From f55a3a50eda3e91afd9ca56b416625a2a5ae79fc Mon Sep 17 00:00:00 2001 From: Samandar Turgunboyev Date: Thu, 4 Sep 2025 10:06:46 +0500 Subject: [PATCH] added notification --- App.tsx | 204 ++- android/app/build.gradle | 2 + android/app/google-services.json | 12 +- android/app/src/main/AndroidManifest.xml | 3 + android/build.gradle | 1 + assets/bootsplash/shablon.jpg | Bin 0 -> 101065 bytes index.js | 34 +- package-lock.json | 1152 ++++++++++++++++- package.json | 6 + src/api/URL.ts | 3 + src/api/auth/type.ts | 13 +- src/api/exchanges/index.ts | 19 + src/api/reference/index.ts | 26 + src/api/warhouses/index.ts | 16 + src/components/FileDrop.tsx | 71 +- src/components/Navbar.tsx | 15 +- src/components/SplashScreen.tsx | 2 +- src/i18n/locales/ru.json | 2 + src/i18n/locales/uz.json | 2 + src/screens/auth/login/ui/Confirm.tsx | 122 +- src/screens/auth/login/ui/index.tsx | 45 +- src/screens/auth/registeration/lib/form.ts | 1 + src/screens/auth/registeration/ui/Confirm.tsx | 47 +- .../auth/registeration/ui/FirstStep.tsx | 76 +- .../auth/registeration/ui/SecondStep.tsx | 4 +- src/screens/auth/select-auth/SelectAuth.tsx | 22 +- .../auth/select-language/SelectLangPage.tsx | 25 +- src/screens/home/branches/ui/Branches.tsx | 28 +- src/screens/home/branches/ui/ListBranches.tsx | 76 +- .../home/cargoPrices/ui/CargoPrices.tsx | 94 +- src/screens/home/home/ui/Home.tsx | 6 +- src/screens/home/home/ui/Tabs.tsx | 6 +- src/screens/home/home/ui/TabsAuto.tsx | 72 +- src/screens/home/home/ui/TabsAvia.tsx | 78 +- .../passport/myPassport/ui/MyPassport.tsx | 86 +- .../profile/myProfile/ui/ProfilePages.tsx | 29 +- .../notifications/ui/Notifications.tsx | 66 +- .../warehouses/ui/TabsAutoWarehouses.tsx | 44 +- .../warehouses/ui/TabsAviaWarehouses.tsx | 84 +- .../profile/warehouses/ui/Warehouses.tsx | 83 +- src/screens/wallet/payment/ui/Payment.tsx | 8 +- src/screens/wallet/payment/ui/Wallet.tsx | 135 +- src/screens/wallet/payment/ui/style.ts | 4 +- .../wallet/paymentMethod/ui/ModalCard.tsx | 8 +- .../wallet/paymentMethod/ui/ModalPay.tsx | 105 +- .../wallet/paymentMethod/ui/PaymentMethod.tsx | 4 + .../paymentMethod/ui/PaymentProduct.tsx | 34 +- .../successPayment/ui/PaymentQrCode.tsx | 109 +- src/screens/welcome/FirstStep.tsx | 5 +- src/screens/welcome/SecondStep.tsx | 5 +- src/screens/welcome/SelectLangPage.tsx | 27 +- src/screens/welcome/ThirdStep.tsx | 5 +- src/types/firebaseConfig.ts | 14 + src/types/images.d.ts | 5 + 54 files changed, 2502 insertions(+), 643 deletions(-) create mode 100644 assets/bootsplash/shablon.jpg create mode 100644 src/api/exchanges/index.ts create mode 100644 src/api/reference/index.ts create mode 100644 src/api/warhouses/index.ts create mode 100644 src/types/firebaseConfig.ts diff --git a/App.tsx b/App.tsx index 9b09c25..120f0e1 100644 --- a/App.tsx +++ b/App.tsx @@ -2,7 +2,10 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { toastConfig } from 'components/CustomAlertModal'; +import { navigationRef } from 'components/NavigationRef'; +import SplashScreen from 'components/SplashScreen'; import i18n from 'i18n/i18n'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import { I18nextProvider } from 'react-i18next'; @@ -10,33 +13,34 @@ import { Animated, Dimensions, LogBox, + PermissionsAndroid, + Platform, StatusBar, StyleSheet, View, } from 'react-native'; -import { enableScreens } from 'react-native-screens'; import Toast from 'react-native-toast-message'; + +// Screens +import notifee, { AndroidImportance } from '@notifee/react-native'; +import { getApp } from '@react-native-firebase/app'; +import { + getInitialNotification, + getMessaging, + getToken, + onMessage, + onNotificationOpenedApp, +} from '@react-native-firebase/messaging'; +import DeviceInfo from 'react-native-device-info'; import Login from 'screens/auth/login/ui'; +import Confirm from 'screens/auth/login/ui/Confirm'; import Register from 'screens/auth/registeration/ui'; +import SecondStep from 'screens/auth/registeration/ui/SecondStep'; import TermsAndConditions from 'screens/auth/registeration/ui/TermsAndConditions'; import SelectAuth from 'screens/auth/select-auth/SelectAuth'; import Branches from 'screens/home/branches/ui/Branches'; -import CargoPrices from 'screens/home/cargoPrices/ui/CargoPrices'; - -// Ignore specific warnings that might affect performance -LogBox.ignoreLogs([ - 'Non-serializable values were found in the navigation state', - 'ViewPropTypes will be removed', -]); - -enableScreens(); - -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { navigationRef } from 'components/NavigationRef'; -import SplashScreen from 'components/SplashScreen'; -import Confirm from 'screens/auth/login/ui/Confirm'; -import SecondStep from 'screens/auth/registeration/ui/SecondStep'; import ListBranches from 'screens/home/branches/ui/ListBranches'; +import CargoPrices from 'screens/home/cargoPrices/ui/CargoPrices'; import Home from 'screens/home/home/ui/Home'; import RestrictedProduct from 'screens/home/restrictedProduct/ui/RestrictedProduct'; import CreatePassword from 'screens/passport/createPassport/ui/CreatePassword'; @@ -55,13 +59,116 @@ import PaymentMethod from 'screens/wallet/paymentMethod/ui/PaymentMethod'; import PaymentQrCode from 'screens/wallet/successPayment/ui/PaymentQrCode'; import Onboarding from 'screens/welcome/Onboarding'; +LogBox.ignoreLogs([ + 'Non-serializable values were found in the navigation state', + 'ViewPropTypes will be removed', +]); + const Stack = createNativeStackNavigator(); const screenWidth = Dimensions.get('window').width; const queryClient = new QueryClient(); +const saveNotification = async (remoteMessage: any) => { + try { + const stored = await AsyncStorage.getItem('notifications'); + const notifications = stored ? JSON.parse(stored) : []; + + const newNotification = { + id: Date.now(), + title: + remoteMessage.notification?.title || + remoteMessage.data?.title || + 'Yangi bildirishnoma', + message: + remoteMessage.notification?.body || + remoteMessage.data?.body || + 'Matn yo‘q', + sentTime: remoteMessage.sentTime || Date.now(), + }; + + await AsyncStorage.setItem( + 'notifications', + JSON.stringify([newNotification, ...notifications]), + ); + } catch (e) { + console.error('Notification saqlashda xato:', e); + } +}; + +async function onDisplayNotification(remoteMessage: any) { + const channelId = await notifee.createChannel({ + id: 'default', + name: 'Umumiy bildirishnomalar', + sound: 'default', + importance: AndroidImportance.HIGH, + }); + + await notifee.displayNotification({ + title: + remoteMessage.notification?.title || + remoteMessage.data?.title || + 'Yangi xabar', + body: + remoteMessage.notification?.body || + remoteMessage.data?.body || + 'Matn yo‘q', + android: { + channelId, + smallIcon: 'ic_launcher_foreground', + sound: 'default', + pressAction: { + id: 'default', + }, + }, + }); +} + +async function requestNotificationPermission() { + if (Platform.OS === 'android' && Platform.Version >= 33) { + const granted = await PermissionsAndroid.request( + PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS, + ); + console.log('POST_NOTIFICATIONS permission:', granted); + } +} + export default function App() { const [initialRoute, setInitialRoute] = useState(null); const slideAnim = useRef(new Animated.Value(0)).current; + const [isSplashVisible, setIsSplashVisible] = useState(true); + + useEffect(() => { + requestNotificationPermission(); + + const messagingInstance = getMessaging(); + + const unsubscribe = onMessage(messagingInstance, async remoteMessage => { + console.log('Foreground message:', remoteMessage); + await saveNotification(remoteMessage); + await onDisplayNotification(remoteMessage); + }); + + const unsubscribeOpened = onNotificationOpenedApp( + messagingInstance, + remoteMessage => { + console.log('Backgrounddan ochildi:', remoteMessage); + saveNotification(remoteMessage); + }, + ); + + (async () => { + const remoteMessage = await getInitialNotification(messagingInstance); + if (remoteMessage) { + console.log('Killeddan ochildi:', remoteMessage); + saveNotification(remoteMessage); + } + })(); + + return () => { + unsubscribe(); + unsubscribeOpened(); + }; + }, []); useEffect(() => { const initializeApp = async () => { @@ -72,9 +179,7 @@ export default function App() { AsyncStorage.getItem('language'), ]); - if (lang) { - await i18n.changeLanguage(lang); - } + if (lang) await i18n.changeLanguage(lang); const initialRouteName = !seen ? 'Onboarding' @@ -91,8 +196,6 @@ export default function App() { initializeApp(); }, []); - const [isSplashVisible, setIsSplashVisible] = useState(true); - const handleSplashFinish = useMemo( () => () => { Animated.timing(slideAnim, { @@ -111,6 +214,34 @@ export default function App() { }, [], ); + const [firebaseToken, setFirebseToken] = useState<{ + fcmToken: string; + deviceId: string; + deviceName: string; + } | null>(); + const app = getApp(); + const messaging = getMessaging(app); + + const getDeviceData = async () => { + try { + const fcmToken = await getToken(messaging); + return { + fcmToken, + deviceId: await DeviceInfo.getUniqueId(), + deviceName: await DeviceInfo.getDeviceName(), + }; + } catch (e) { + console.log('Xato:', e); + return null; + } + }; + console.log(firebaseToken); + + useEffect(() => { + getDeviceData().then(data => { + setFirebseToken(data); + }); + }, []); if (!initialRoute) return null; @@ -128,13 +259,7 @@ export default function App() { }} initialRouteName={initialRoute} > - + {props => ( )} - - {/* */} @@ -151,32 +274,15 @@ export default function App() { - - - + + - - - diff --git a/android/app/build.gradle b/android/app/build.gradle index 2512b96..f0c82c4 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -165,3 +165,5 @@ dependencies { // Performance dependencies implementation 'androidx.multidex:multidex:2.0.1' } + +apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/android/app/google-services.json b/android/app/google-services.json index 6c89f64..bbc628c 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,13 +1,13 @@ { "project_info": { - "project_number": "628048576398", - "project_id": "cpcargo-77d93", - "storage_bucket": "cpcargo-77d93.firebasestorage.app" + "project_number": "1030089382290", + "project_id": "cpcargo-aee14", + "storage_bucket": "cpcargo-aee14.firebasestorage.app" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:628048576398:android:f93293c00f463267a92edf", + "mobilesdk_app_id": "1:1030089382290:android:668f0669ad4ac3f74dc94b", "android_client_info": { "package_name": "uz.felix.cpost" } @@ -15,7 +15,7 @@ "oauth_client": [], "api_key": [ { - "current_key": "AIzaSyBnFzHK6XAjxzcQAsg0hFbeRcon8ZMDvVw" + "current_key": "AIzaSyBEwWi1TuZBNj2hkFGGIaWZNNDCoiC__lE" } ], "services": { @@ -26,4 +26,4 @@ } ], "configuration_version": "1" -} +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 939e4e9..5301495 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -4,6 +4,9 @@ + + + )`HALLk9yaCe8nJp_Ud?ykWlNRW^qA#aGB zbMEfBdw1`?_j>-Xt*Wc4t*W~Jf4Ar>Av2_*$N2^ksnW45Q%w9K?*Wb}Lt%*?t3?Y7$zh< z!kxH(1UPsEL?q;UFdz}!ukZ&9@Duob0f3GGYlww_1?%URKf(W>a|my`jvU|rQ>F+O zbDrM;MsUHySIi_1b;viCk=r3F8E|c5#E1W@sGW$~FZIXS})z0c)U_jot{r+$?!YN{3(Y>jvUj5)PG6n!(;y-Ba zf?;!>^WNk!k-kU?NMRvlwf{)^{5Ofal=CuKA<~QV)%PPR^$qE#TPWXvrB`8>QDCLQl-bfZhAp}yArdv`B>hg>{WZKDKJ^E;? z4oOnv;^n`MFhl#v1s+H{S$}eJn1r!Cq-mP;&@{&mVwZ8IF}31oF*`h3z-r#b8EY~F zDwMU*E{RRz7}R~FNoyWgg#Yr@YQjCw4r*@Ar-Xzehl$FU*vnh|0R@ z3>Qx&V8{yv!j_l_mNgem(hg=wdT1_(W5e_vfY9dd|K~&k{yx}VKOjE<0hxHW6nbg!XrD63jnXwQn zSaA{gn7EavEcDDra4N)`=nZ?PDR^?}cums%9^zkI@4=>%PZ$8;))U-8HyPm8ZCtEH z?x)WfpW!)AsVykUGSKrplStFyTX@6uB&OigI`hK1yGG~F*6`HG))t*8)pJw$Gg zx)9_B^{qTsr7RMPQ2;IV)k)GdKT%s5aXU z`PyqICvM~&gJzny6@S+q-3hPY0y3*TYcJ>@D0}CGWkUkoXAk5aryN^UPr#IXG?~0R zY>=p=?t2uWKFo1B}U4@T*^&PRd_U68%9)4~i19nlg)0!)nJJ5U2;C`yc| zM5n5R#ozlUBg*&KssWM8Xrw{<4^0CiVpMEt(dtW#WOP=s-N{~j9?vv5-Ii=)uPLON zv)R;3arMZr*5NevFmH&J000P1HlcSDj2|i|Vg!IoY)J79>bxEq$=r@`bv*ni7ne1) zJ)b(5y6EYSp-`@C!K~{}Z;>*&BY9gSCtc5Oo0=Io>ixvE5U4+}NEm57ZW`7NQ&N)Z z?bMZhQ5I4e6SdU^ZwtH@UF2NRKbs6jB-cwPgaJ_zyF=h`6ilgv@gbK|l1uti%U-vk zZR@7IwSCNi8_tSTrx_^rz^vaEkJ%Q-3`FQO zA>Jcg1)F2Hs~shQFP!exbL`{MKsF;JInnzH5@5vc4i>}!aUgnnMFq!( zy+g;~@~GLm`F^K!*<8u+%whk)!a}unweQ8K4sJ%lDoMG%7fQde4$*jwoz}(025tZyqScFv9htmjIxtN5B@_vWv55|Y!gN}Pi(?8HgorL z*Tch@=$dlZTduV#`C#j@h_4v-T159*K_)6TO_I3Cp>KtTt9XEP*|Ej3Akgw04W;v_)I7_1Jg_DzRh zm}L|e$}gRis0u2YFW40@FqA^Danfv9*(A!iRvKR61=z6Qs%SjYl5kKN2!BeYBHq(~ z#}_4sDWC8mzOtq={&Rf^eQ|vew?}SBQxa3Kq6jRb{yX!ljQ`ve)LH{Ta~wIJ4Dfzr z3jknOR#*P$0UQpZA&{XSOKqV>?NM@#N<+C6b+zoqk(A<)+Pqv&nyHJsyEINriFgNI zL#;Ltu_Z~ne3~Idcf$0wG#s0XiD)McRy75Tl*Y6ySgR@ZHnFaSA2Z#a2>CiAAPeXgz6y#$d@Mg^dg^1T=a@ zg3pVq3jiQFZgxxZ?e|WpY*}EcoM4$YkZf7#^!gGLnaj7N&@V2 zAhAf|{l+vn4<)MVT<7Ozrxh~vmuZFz#(L}a&RU$$%4+k|T8}CPAyZ?k3D)z<95kpg z6ykjnp)l_74W$~i1`gvV=Ob;66x(Er8xkO6deE_YCUF!1IJv3UujL=TV}g4Q4C$kTDM(y+8WnRyS!wClA<{6=v??oBy*fKKE~i>9 z4NhuuDkRrh2Urk;Q^JO*2Bd-W)~l+6ttTosYQ~%I08o~J#*AW;fu4rIeZH%t)1tDe zhWTj0?|`JJI>$!($4bGipp`9C-qfoEUhn!H(sE*w-T6j#T332|*6HQ53y(E|+zvjET*UT4c9IcU>j;lLEx z4_)>gh$B7(lZb{<vWxi2r;T=<(4^18`NQ5d)|Y%V-7w_yvRaVLTqy0r`ENIGJJk z@!D{BeOv3>Gm|6oDIIIr9Urbz#8d3sTtAGm$L!lSIl#pHBJ6ZHL*o06?NeSWCB+W` z0myBgEQ)5v>G?h3mY~@sg6*v?!ft5*e61)moLUH~IG%<~Xl#i;ylLq)v)ovW^rKWO4*>XQ1F)n~?v%>i#s`Y?X`F``V*=XY(uB?7N7|2C4oTX%EVF;4mwX*v-$m-|A{BS_yyxB&PYM#@j z*V?+rcBeyYFwPLJt^yZmOJL*fdXanH0nsOMt23`amlBhm`)GfqNpnXKb)ePv^B#@;cp`y7aMgRth#`5=w6H`EADs@_HjpP9FU;Ux7!ZYf&(@Bmv z38qboM13}FHkYAa(=aptnv>qz(L$KsbNpFR(j+bSV3j$r)&wP#UV|caq`6u?mrBBp zHb8~m6HbOkV;zT*7IG&ffZ7mb07%>DlVFaB0bs{A7N`LL{n3<97Y2oEVOvW+d7R!x zW0T4j)E@;W4DS$41$=~y3xG3WtdmE4A6lGD5nzreEe_@?*zXVq0EqY&q+Zt_mMm-? zZ$ui5GPijSC3A6neqk|l>09IR)ga`9D;I}+CTPlQzkioIqiM1`PDsePh;Q!FP}HsU zX0LZ7@hHLU*y+mobdTU*_oL#(?%sC%yvcyKGJ`Ykic40W#?=Gn#og5;hR=3T?Zy4C zN25yQd1P6McYT3{AC^*K&pO?sTvQn~w(O}4YYn<>GDGrM8n2d(*6gm6cfHN-Ce;(M zJjmODXP+CJgAAe{m!Uq2267_-kmbFwo&tdY_-{6n({W(erm& zF!h3fX`E9zOVrc|eNgKJU0x*lBJ8!2Bn&QU(c@PVwqa3MBPgi`MiaIKM(eiqMt{@7lkq3_r&9_0EGpS67ot#)m%N$Pm5%(FNF=MgO|l z5r-VjM5=X47QLJqD3!8venqg}`GtD;IKy&H>u_;&O@QIFMdI>$TG7D%1>;WMn5FrF z`PkfJW@bOCkR)r@T?Y+LO&6iZ<*|Qs4V$GnIT>(Yyr&^F0PmHqns}`8;|EI3osY}< z&U-p5<@$|bM^^yiovQuk&%Jx^^v*wB6V~~@d^v6F`0jDpx;AE}*IygJI>4X2xp^7w zF?8X1Gum*LQIYO=@{Z%HU{dDN?vSH5A0gwGlp>~irF(U72_(HHm)?n+-Bi)suim+_ zAt=Mcbh@Km6{#YEPdzpMJv5Fahl+(`PJEz0nj%!271iA4k?DQ$a8YsihGLY|em{j* z@?YPJo;UxH{&hU6QD37fTwM>cIm7F0X#mWwAm$cKR{^@sevGb-7qbmybb9k!X4^P* zQT(qF2SgB~%%*?jbVyGwqAa%!B&O&g40>x!boi=b4i;7V<`GksR^`uuBJ%XBBG?nr zUEJcK8B7>2UTgQaD_C%Ovob%kFjsW@VmbwV2W-Rm%IVHbuhmrA86GAn5*cIM0E?iPeC`&arjKT&JW&#LaR#ZS{dl zBafdv+sDoeP@9}&q1kX%_HU8@NQM8%soTUP&p(2(s*ipBqY~~<7?m+@SLv738?kZd zJ=V_!z$e%HozRdL%l9^N)T_Hfu z@r%u`1Ws3-9#?h^lqF@6biP2awf|vsl#A84GlS8`a#jkMpXN4}Gu@D&kP&4esf&Qw zX5ePOvvpWF!a!tUo$Od4-+I((U00iNzkA>p!TXam@UOIXjGrvbu01XmFaA*-icP82 z^g3)PY{(zx!iNK>6J{blc1dNQ-3pD#5*}BtoDp7m2?%Z{ekog*p7}-Tck-xSrTXb< zTN*x5wFgHnDI@8=WM+|$?d;fry4N+I^q7Onu&n?uQ`9~PZ%8IMa;Z8mb5?<0pID=? z@_FlvL{H97$7+2Pzo_9CN@FuLCEK1e;ZcuEq3zgp$JIf>!go-_A5IR;&-vpC`y_y9 zQ5n=fw&i*IMK$H^>fYwMcLdM%&ARRyDi-+fo;%YE35~QYmZhY^DgFzsA4Ef{{v`gJ zO9Yth6?E&W)5+COoPkEeI0}oZn8Wqb%pp!(Y%f42;`UD1weg{?s2I)iu-kLl<&Ea|{G}8Z(101|`ta_T+ zBc>3B5Qc(K6}cz0V5EdtWu$m~Q1jCcH=~w@-%a3IQ?$02@*xQU`#4*82V!(T03uIa zqVh&yZ5#q^N-E9P}5n0HP1H@#me z%;Om!Zm@r5$h%Fo%v0yhdk+Mj-Ox15m>7?Ik@c+5sm0~>Ojl|!%vXtV_-JRHMx;;X zRkE<@j-h`mc~Y86=yp+ux$=eHaL1RLFIS~cAH6SqZ?Zv)seXXe}*A{i40UOpC?F>WQhIU3?-bZ46VGhr$>WEW2<|BO87Sb9tR#COaap{{@K5) z{zzZZCDU`#;S|@zYU?73n2MO0CYUBL;*^%(`Hw#xNkkl2KJ-WaN3+-JOxY~~`}d3g z&18h%pAI`vFw@S%GsE_yE=U(tBw%e2WM>Dlu6JI4>?3B+SkPGNuxoFVFdBxgn>s%% z5K`@#Zf>JWSgXf995F}JZ_BNax`@r=c9It9TTmp$>KDlfPLg_J*#q?TtbI5bh7q>W zYp)Xjn5%G{$4T4ecW+@^^51xB9<0A)Wd_}}~L%{C< zzJd}5_L6Ycq2cO5-i2j|nAi(%i{y!2ky_u>Ui}ewko7`_^wf^YD(lCs=Axw!S43;J zCe=E9^IO|HnHyQvJ(1TZb&A`53OeV!>EDtoRtoDuA6DW%rFH@|EONDR<%j z5Srr)M>J|0NU%_WESh0ub?eIm&gLMf;mDODYS#Sa17kd#KT!Xn0|=Uy*6XXlcn3^- zzv?0AED_^c_u?)(cf%lL=mX3X=p3YTRv(fCg**wpf-WGBtvNvfAT`&XhC@763IUwgmw@?;31i~ z`S$_=03uIehvnj$T-fRCUnapR=b1{;jd|Yip|U9;O!IUQ0O32Le+D>`%zE~AY#t}im(rnSD!T{AgFOfP z?u}h}mRXv;Kdc9=rLOwZC%TSN4Tj{4ydMmbsA{pG_5yBYBXKs*?z?`3|6FfEE0*NWGU?i1_))1Ti51a*-Qq*9^)A(*ej*%lD1}=dYhAU0r|lZ zst<&O&%w}XzDxdg%Y{a!o#%MnHMbB@ZJX?KWBPi$MD{w!qzFlx3 zX_o%idi|5rfA+N@C0ub#o)&!S$$teFt%|NTP{uZpY49;Yz|y7>1mHwZ`8%7wpaPHHwl?@Ns z%Y_9)@`aBgXR~AGqffFXWVZbT9R7wsKqbW=<~2)%!dZC*P_2VwR8n5!h#FH;$Y5JO zr=)rk6B^J5qx(M!j~ZSXynJRmKb?NBwDCc?t!CT=d*ILo2bXH-+=jb?{6bo$U%`gtbQjN2~f;e%O!T@dt3$Y?2&Y ziz%jUAXkbT&FtdJF?Dz?dIb^LMrzMLs`^K6|FQ&+b9X2CZ#>%nf;6^#f^7NIs?tuF z`}c1q^Z(fg{Trt6fPcFD{|5UnRVIUj@()NG4L&M`_6snhkid?*5&d7x4A6JJL>ELt4+8k50C~f-k#~oa6t;P zYZEHp?HqoTRCKld+?0`LO31ni#qbN$NW`!^DT@kLdKo$Q7|2j9om_gk@*R*~a_IQB zh%cw}04jr{B_Wai%@*tJ)%;~b^Vs-4(a5vhi0szxJ8$H_4tKH%62SKWthpGp&U5xxJ)}z^V!jyK}2qPdKko|G(Ovzmo+{SM^7yW;5mES>ECU11<&4;nYQ_2afmvT&6;Ns-q0L`Z~A?jPR-{cu{;vSkr-U@ArJ zF8askS?|0 z)tycEO;{bGGw)3lX%qGOtv|(Y6uXa~1q2oRUKA!7u-a@SJv5t7oq*1Fl)HR#b3FT4 z8CWt16<*u@jSc_qfojt9^~+4mC4cxbN47f*ZtZl` zjy9n4%{~2koVkPH5HUOK+q5?%?t2uJ^OrK|D;Wyq;+sUO^9){NRzDme5c;tz{|aPk$~s(tFE!%=t$mVmGos7 z?SiCV{Sm#s14MRiRw|x<{SL6D{f&Z)VUfo_`;y6aK?AB7^#;$@d^|8G(15;hyTVR& zbRSjtH)8F$8;_q*N#FXYlWY=TWh@9s5zl~soh7w)9 zlWV?32U8aU;JN(qR)+J969}I z#bUT%pY@`^J_UwDg8vTK1Wq1*BPah%yv=L8J@D%nw*B+>yZrwyz2ozf`tS5V@ajkk z5r`~Wy%H4K_t<=qb)_+M<@Yz`1)GJNu78+<%rAb*GoQ*%*JYoQ7SYSV zazs41)@9F*$v{-t{VIU}_`@n6!A;33nWV@5J=SBc5b%?6IR8X2>w z!{efYG4uMPuQD#liycl3b29;IrUc3+f-7u7U+6(FysC#k-GjT>Z%_WH8qVDg|M`dsPM}MpDnA!F zL%~HjCKjsAk>$&_Pn4dngw7rG5hI?MxWQubz)tXXhIya1&vpVzZvbVJVI__qj|?S@ zLVnrz9e@-^y_l3NG&D@UW%1zj9%x#TG^#J9+uE^VG{Q744s0UQ!5eV3yaoNHcoRK& zlt{@=WkYmpKr_Rcc7}o@q^O}57$1ixNJ5yW7Aumg+0~KK3)7NPhHExBTNc=zsm4ze zaxNo6tG`uqaK6LG=Y7T_+d}6LHv%tpVSd^he*rimRvp_FvMn0hu*r>?R7T=i2`mlX zKAz7~s;;}fR;zm>Y(K%M`N_3JrBVPXpOMmv%=hKgao;z=ODfxJ*Hak;TG!WNNnLRa z9rO$4@iKG)+N2Z-l?;T+Av(QmA|$?w?9Gz+n=&Q6&d!v5>u(SHkW_r!7->0E6=NdY z15r+STEeJiqDAbET->Mzm$vtHNc^+6t@#D>vX^TGvp`l~ZlizB-i2%A=bMYaU#0(Q z75_*0e6>5Orrh%-1^a62o@|j@xt}X|tDW)k+9&D8{wEjTnxuDmavq!ShTLX+6%$Xk zVxNBz)HaK6vBuzW<`99F^AuR7@+S^>o}A^Hx5%^6AIb$vVZ{Tjap3EDKgXsOH!SO1 zb=#$_@2^HGYOHTZQr4)t@yU_z+3ZuDbgyGz_i=lCU9A2NP;I9^zs_0|Y1td+0#gO6 z97Rs((Y+}_uv%X56Czi+H?zJ-Bto@34y|!=V|go|L8_5){2iSyU=w-gqbBmrKb+%>%1A0IPjcQAnBS=o51OU^7E1XpJ_-p{{S zs?JaHe}#!?<%C+EJyX$=_i)O-9b2lx-kdR+CpD-vQD~NDT?z{VrL|FS5Zaen&KEmI9uLwZ{8L&kq3*n2(I=V zj26u;_G*ts;X@`sOG`b}}xepH`)#vu8ti<6+Ad_i6J` z2Bg2Y&s3yH^~IRKCTe()sI76y0Z@!kf&5Ju1`(-kJB{e81M2-=Wzb9XZUh8Ud5g7V ze+vjQ&a8xJ{?uYY^i?Em+utVKEhJuQhCrl*zTRenBx<5fkY0owIMkVyNs@DIEcO7; z${d|h+4gHCIMmaXSqh%Eue+5Ok%jU;tn5qQwWb##ZPeo%VFQl5YXXDbQNg*RBK@KJ z0X0q*8F#XYStE8ukX9auIQ)Khq>UO2o2Zck4jnO793EF*II(#aVKrc8ktJEXU%Z)M z_AfG2{3JN`KH@G16L1zr+C&PCqM1917M9bCur%sU3nV6ot&;D6i93}dw8UA2_2O~; z>CtV+KAx&b=xs_eaewVeUP$aR*8!^oxWct5H;u>ELe0!HOZaNTy$Py(;2~9%vi#8x zB2)SC-QmoL>>u5Lai9mkab~HIeAF-6On1jLM=$>Vud2SzW&%xWG;SD}e$!Yl;#psJ z6uMk&sI#&mEe@LzG(E|Qy*X#Fw!9EtX>j~?~ z?bz)SihJPI+5}e|xuUDm~zWSA&t6GWMvh{4|CEu;m%SG9Qr-t<}mV5Z- zQ2eMpk9-m;r0PPcbyX6*CG~&|^DVPT@5~E=k6Q zFFbe@{v7dL_CCP+Aqfe0xt@lX9{*IuH-CKWS06)`eWGDsIJ`Y{)5kVM@wort;?nS5 zyZW?FTlnTN{m#W_ef6g(7h?TOK3TM63omgrKW!B8V2MJLw0u+LU|%t?4CTi3$?dJ% zcpkL8-Ye$vvHT^_%IKBOY7e8fL>Fy#JgHVsb&}-VVwypyeGPFL9V)s7?O_+TtH0Wt zt1dsLfrd@_)gG(I=EJ`HSlp-LbA{MkqV>t?6MF_>2Ob`Vvd0IQAD`V%7PD@Z2n;f& zuSQut^bEKR_DPb(0^oBqBWITe9%*xFDYU ztYjl8Zdf{CUS8;mouM^svjo7}=yB}d{fP-(6zm~ z&uEo|Bb~qg9tur9@Y2(POTkM?f4{qwF?Uq(Vs>C;cnkW5ANnS(cS-d{<>Ssv;x-R= z>r2w<%7qsCt(i&)v`2KRhF|hn@Milakwk;UbDC9I>mw@z zsq3mMsJK(83z?b=*aT!}8!@H4vtMrTUlB}DC$5+R8cC1`DP2S|TBxTBNV}?3SOh9< zstqRg9%6-P>2PxTKa(z!M74q4{CN-e#_}l6+EjmX91;)5h^z~)Id*!te9-9jRIO}K zw?qXp-O@O7b=v%_cz1erf%H4TM|O>)uStIW-D1jTFDa9^6{TU6*b^-(`BqvQEfwL} z8W0_Fl~iDQdXf!e2`H7TH-d3}xL|_Fa^lMdw;DJ#R(0h$883l-Z2@G}#F`ybi#%dp5 z`N4|5r|;JdT*hW6Uth|Dw~M)fRzeFk|7V>_pwsZVOWyL}$MxXW7!e6orKY zFR%q{$rmmnl1(+H5p?+kFThH@g4iZ#aco(V3!JawD(_@N)T8SUS!FWMIlGRwJ6e`a zOejEPrM8zfr%~Qy&azq&{X~`(d%{IC;yr zso6t+o|j7w40hb=`y~=q#MLWrM|>kC$XT!MhE8Y-sOHo zKkI$~taTEOP`=PzkoA-;+i0w}`6Vs$R4Vl(44W$2;;hSVkYGgeVc%F*lg!gWo`O*j zB_K}|W9k_1!+H*(wbap6&xg?8<^Lh_*VjlWu+ouMw}y4hO6N!6kLdirvmuWx@KNZ!(5}kIhx9yHnHKgE!O^=lO83i3uOpuw1P>u|KJ5kA| zGPK_7CBB;@A&rfB%qiG}wUnxr6&;@XV)nhnhbc_8vahO(2a9jNAo@@?UCGnv_nkO8 z_16Err1D_Yq1M6eG};tff`@c@vVQ$-x;HdrseCGs%+!UJU7*rerE{lvPRI8f9bjruj@& zk&a-f7d$`GYYX%l)vXlA`C3<;Y5Kle?6Y zRNphCd25YFWtuJ131+Oi*MKHggGP2rX05 z6Me{y&27nsg_>6dRuj3LxW?WA_^3AJL5$Bo`TMk^j-zBD=$2P5Z&udvT^O&Kmd}f8 zr9BA}$gGiz56B{z*b6a<9C*e#8rvL+fo=q}52U+QQ?3v63Et>k0rx7h6V9rod+LB9 zxJm2;L!=3Av%d&RHXa7Ye@36LhCVr1P9sQ~i#weYODhVwIG3MD-%mWKyITE>r<%%H zcj2(keM?+!^&K#UMe)X_G#`yPZE?rxz&FsX$V_sge82L)FP)b>8am}cL! zwKRJcO5FYGh!Mj*`?AZB@{2mAzcThj|a=6!a=XeM~M|I~5S_6e5^vx>mgWuuhll8Vy1q z23FAP-I@^FP_{8tOq^WJyeOV`6>mm5ZFfjVlr3Em=-RH_47%w}0`)FLuAUq^G50%s zmA8$3Vz9?LH~VgGlucwiyM4aIgr^^P<+dN)OZu=lCa`8lLZ0Nu@ zzE-{<3KM|n+}|QwG5A<>yhA=+UQt&1@$JRLL<#00=@ZQ+zRWF^I`2q>QnY~VVn#|5 z8-+lbADUX=4_&OIj;JGRNuj-jE#-LXp`Y~9=%q#_rD5aCK26!npgF0h=*F}4)*8v{x*I7;90RSIg%nltm+{0++u^4=ORYl*4 z&Y@Zy#J0Zqp{FsFPc zblU4;rS7Hdr5-)z4k0@3v{%Y$CM%Lh7Ap{5xXMglMCTG{Uu@s>S$%w1Ic(io-Bc!4 zZ{P0dlY%fdBNTF`^_E)$eh75gXWAFB)gWcUVy%Ufw05wjD_{mn+Jb#dX!;!x6o*Dx z$K{EUbT4&ll)T#|XKZ#OggA-(J~<8HPN%O!54gHNqc$2lg_S2Nk)f3LhP(0RM&3Ol zB2o|Kjk!STysFS48&Y%U+|>&nM_*PxId7gf83q?;0C?EHx1*QIvr6|{D&CeAsY@uU z&$Rp)bhQ$df&!I^5)ZYK=W4}IVGkP2P?e};!-_DFY-@bkkh)LaGCE)spNL?NI?_2X z92ppLX|yD1+c_f<*wqsmz&!^24xmr?TuYco_;ukl?@dg|g?Uh;#cqGry~vnv$@9d( z$M^(BeYmU!J!{pDy0w`EPHvkS>1dlTyFbkhX7{*?bpdSLeHM=ES?YVLIg5f2#O+}v_z+!woG%Iv`uOH zDEcFH`#>f4m0#xJw_^7TMuVffJ>{)l_H>|rT;J!O;{jjh?d~?^Zk$SQN&D@p^pzfCgUty;7+xU^dIt!a_IWdlqfe`M@NvVTaqC^cU z$@-jJ9E}Gi))s3ueK;|3zoOGP!fHpfAuCgEiv0_z+5H*=ikLmmsqUfZ&W%XM_=k@X zLqju8QO43An!yEAz_SrOPb}DI6i$BF|2p(ED3i|>^%cv2!A>7R({S!5lD%*cJ0OL^ zGgZ@x+7CE_%I>evr;~c9uuaqijj{j)nlQ!s{P1YVu75ZagnynO1nb|g!pGo(UGx%A{IzenwJmvaSqG;3c~3?RLa7;yo_#$Z)%(#_J!k@boy zf)}NoR|Afc0nJ=@X+hB#Ti~0P5MDGhpNtN7Sos4*xr`najug4@Y>=PM13J>KkBss^(JAM{}F((umdy$?Co| zglg9yo(KRBHgbk6NFWE5N;H(t_$yG*Jv~*y0C>@R+2_a%VJ>U-f<3h!mPk6>WCv+fbrYZwy;n<0@opl*OaO;@VCM1dfiu zlyRXogi%oGnZ|C`ufFFf#A38jnGD5+&OF$mU<$g^^#rhD|GX;%S9U7p>! zw$V9IdH+=#^A+H+xosQ!#)!R4Prqpe$zKvYBYVLwWi3~`&7!~_EW{TvZZb%`rfUp+Qy+Za+#(7n{uQ$) z9Os1vzID6&5%^ls_p+G*XzRaw0tA;?d_XUk=b`BxxruCUXQzMN+?>S6wzFkG`Sb+8 z633ZXy4b>Y_!_k6Y1lY->G6`1g5txL%p@Fp&2pJ)lOni3ib*MBSkGc|b8N(DKT3pZ zgH%tOBf8ipZ=cNhZg}62!gh2e#TRxV$$fV`!t)K$%L~bYZcvl~`-!6qk$%M08_5}g zk+k?u94>*3pe_;~9=kw%b11cwF?dc_%&Ln&0vh(A6B>)Jl!Th~u+B~)gO4REU_2=; zp;mu*^kLJ9L==yr5~m%?W*A0|o9)t0klD5!ouVKj5S_86gQlkYFoA1=WChVjlW=Su zf&VQ%7Yd70#>k*{mp3#@3}d1S_)~{R}z|GF(Si#6J6$59bmsDP;Et$N0oTd&2mY z$*3EA6dACdk&)<0t~cl>_7^fDnjUPM0yo5GHjSaNmyX%VUpd^E9;ynMn$*$?veJM+ z^?BqL>||C(QD!9Aoix2+CNs!faTltloRcvB$H74km7JyxJ z0oFp~Z$$cqN<#(V6E+$U^5-B#lgZp0Wo!jZ^Jhr=59Gv|W;oU zjqiZCd8AX1=(2h8p<%3qSV@qt9aD_^b>KqSehUN@l4qb}NaOayPQuKkZnP_(Z_ctx zK0MtwnCVot9w(vgm6lT@ii>D;(QoZy&&1>LdDGUly)N|JW|>+a)r+`I$rS%cy$Q3l zQDc8uH@NLm3|EhY}blA$4`pU`R&X>9SyJpTFBEt)0| z#9W!}Dx9>GrkB)(;6SGP0dIawpVPTDc;dwHMVnE!SJ+>F7^E`IArrh{T@aJey*B)aB7#f zlB<&AS|;@(BnZEWO@KZ?hdQ!TM$6!-`g^a)A-_*3CQ$;^i8-Av(f2=PkVfIAhNHf` z=KXb?zG?VE{6C4ayMY4I)oTwNMcHrRl1otuB$R{GVXGi^z zMgA9@v-3(t0Zxmtir77_1x4mc)H=J>`7v$45V8+kk|Mn^;seaSh@Y+P4 zG5PdcW=)r?Rim;G8QRn=pN!9Av-j61P&;r^w2rO=Ax6tG_>%2GSBxqf9AzueAM`;% zDad>;v@=y$foe`ikN3gb1#H+KAN9tcO!OgayW0z2!*1K8-%UMws%|h2xMVx=%nsvQ zXI=7~J4V2vkU9x=+OOXHbWrs{V`{|W0UjkLTR+BR3{g;$poKRF9_R2R4a7Cl$J2O; zEvf|Mo;*owLE5_kb;-bqQ%tqSfId}q%E*#FmZp6|# zA7rc}88e282gu1cbmgUj!vN`i@tTnCJP6jC>?2qTmFe%FfXYzyB?_-Gv~uC--bk7= z+JpR=yQe0{jRJ>W61>b9Aq&3uCK1Xj4auVn@|4r<#$XelsS?79i@XuRt7Y{xgMHkk zw@Z~Fb)Sm7_m4BfowNPR=l-vfvP%!ZT0(@ea~C4$WwsqEoLkYrMST?QXqtShR0*oB zuc~st;|a;!*9w~yrfhw&=MZ6t$>if{X514-8#rscemDA@VzsDqgpvv)AIXOz%k5*T z;gRKWAwo>%nZ!gN@~vFI1FodkgQ~BrPc}cZzm`iOmY4thZX<7w;3864>e9}EP7ngo#lC`(jV=M46@Xwt3L~dQ zL=uP-D6E4NqJ_3dW%Cyk26 zsg}rzI*jm-e#&n2&QmWdc-Bf%;5v>OO#5`0^uBGe+(S%-yJniGYg0V{M{NDe)vr>?HDWIP@w5I=iO6%CcIZ5w;L&@S&-T z^zK@$MtbZTSg>(0=$lh8qd{eTjGhtBwM&s#Gp$g#U^E%H(X=3j?Z{4xBCX; zO+n_;2d^^tkGlr9Q_||1t$?YHD=%r|hEs1%&}Z>Q>h!s6YS_i9T*woJqWi31H&`6+ zZn!sGRx>cgOy0+E=~c}RMp@j@J3)CcY>MURg{Wz4q~zGOY#zK8A#2=Jz}3cUq8;|p zk7SBy1j&ZW4H-l6WIR1<8}4ncI~s(S;$@Pg9Kvm8f-DS?K4m!ebdlRU-l|U}S+ps9 zOEF|S_{cH6b8LsBp3OX9_8#0=Zpz|HA9!4BWO%)~COya$buAv%Y>~CiRv~x$Uai{P z01Aga#Up%$+K8o4+>lSXx@*_W((}0&QF<-uOU}j%+?`&ST&k?BKv%~37+GjX@U4ac zA8nE)s7<SG+N$YE2-mp4U9%oWoIg;$!c}J59_vl#@1~)Z%vN z1=%)?n3$oJdO$psWHKGJtqt@oV+CkrzW7X$N%!`y^%_^V9VYh)co1sN)zkp|Kg_)a zbR9dBAbict3^6k^Gc!}nF*9S#6x)d*W@f%-W_HXBF*7s95Yyhg_suu|oPmFK_Ut*U zZp*Ebx}@8ZN~)5o)X>CLe_{O>2MeEs^rNX$)VjNNUvKi@lPks9Q;EM4T)dqx3^(=Y znj&vyPc{_tl$q0`+nPWJ1ebtUnu7Ya;9PI;Hop^9;O-V1w%OTH$rpXSfnZWd_N|sZ zlWp80p62W`1Mlu%Y$&n4pb%Psi-T^_~t^Zw#@_#TOf)E*H-Ec;x zF_x=!8w$03Z`Q~TPwPeoKg1RV_Qw)Y>=tw5aPh3YYRQxOjAae%j8z1Jsoh0)wQSET zW|7@BNjqn-(8w=F;hU<;Xv1;P)oWCwxw1?1;PwTL70`^4$w|4frE@>140zOEyQ`#jo(Ja#w4awk7f;J!3 z=`3B$$4(DtQ$!1CNr0-}t))U`Uz%M!q*=Ff@tpJgb7Sd85)wN{w%Yu6K!YW3+^(5~ zxp6UzYyq|?X3Y;oOL8)QWCCM>)FB^*?;R#4cm=F&V3Fh@9uDkMBEjD43@wczL{tJd z^5KxoLomcJJZv(Qf!rS^d7ioSy?GUUL4Ulmy}skwR;g!FX8RFWA4534uML^UKoBah z_U6}KXYs5&RmVNq?R+}N=2Cdc%Ag-z@pkECc_Wf?{gjj;S|{e3%3{P-vFs6O*0Rhn z`psJIXlvBg+1bT4Ey^S#w&}k5#SSlesCRh6fp2iqLVU9!m2!C;k7t!jor2gy5te_abv6i_N}4mulNUQ&)vSjAj z=*DmxdDSdB#qr$eagD_(i+mM(nF-@OD}%v_F-Fv4{FHfppY<{*-??rz=9ta+tMr-9 z6%12|4R3M`FjV$re zIv1p|MOT!LyI!^_j3h;7h>o<*w8GeY_#@sl_~Shj{9`@v zk5Kc^qtE$Y%!>A(rKUfmIsV^(|D*_*vit#L7Ml8g^6YvJ=~sWA(?E3f09U=I&&j3b zw7(fcmL_aT9?rO9>Lk6ILm3!4&J0ORBJGp?vqiAzGAWM90dnLc^Y_c$p~B(m2LYBY zsiFO+HKIjqnPtcXY4k(ZX}<8JOFMf!mG9#bg{~V*s~z4F(QIT^Y@*~UamDhG7er%) zw(@LXN*>=0m({5XXr0A@ar6DY(x34L!Cs78N}>*}!Q};<)QgZ<+EpO0^mW&((YHqm`QZJ3AJ8FZY+jy<5>qh5bYqmq@6hksG6so zyD1+CkehcoxS74z<0?cR_iSRnk**-SQroGTn;BytZ{8F$qwQ$eASoq#_pU%2ux!g# z6O1(kD94rSL428BVX31T%d?73#|=-g#vk04K%TmA_Oig$W9MOZz(BBc!0Pt8cfmc3 z^3q2cIGpYO>5)%v%CzePQIZr?Q-2#dTUCG?m4 zYai(|3x20PHMmJZw+Q7lC1uL2turf!e?yNx;Qm3Al;h-^7J4nkl0c0ujn+ZlO-@F= z*Uo~NS!zHoPswh|Bh2i*wk7W}P}>^|Iq{7OZG3NGM~GUodta8^#O}=BCvU`5BPy*m zLGbDaXotrBB%vhx$01X4iy60>F?NI%o%_yGZ?2qUuQO`I>Hc8+u3i=?Ubnx4a*hom5hH{#1&5Q9JF+|DHi_z6=2>t31^+gBgck%WwX=kcWB;X`j)*zEnV z*gnVKunoMhIuNOg)U4IW(N*AFp;`h|)X;z#$WLmv_|r=((@UuXM=RI4oF;vyATyPE z!tva-K!H;Hj1)LAEv$fJx|_d>3SxSE_?>#7rfk zgLe6XFNj~-Evb!1F>>R&jCU5GT|=rs8|gG{=}}yXOg*?%QXSkFKKnyDC@mKe!in+J zh3XuXE}8jAa=%h1g;$~#*8Zse)bs?}j}p|qdB!MqZUg@_x6)|I%%n~e8DJWIi!n+P zddRac-MBn-xV0tSFdh|dJtm-(Ac43tB;lha#pZi29Y$ok*Pmi-E_U!LJk_N&STJHO z-7s-ipO-X=(Ha;&9f~~<3AI7SAz2aW)i07#nlpP$Q@ed`JDj4GCV$*v*x`d;P9DVp z$G3?Wm!bV1&?9Grzz86 zf%ql{8~0Rb{JKpvHs&CI6{7|^LVfo|^|uGV4w};djLHY+j|emKyjb&h5Zk-iPNFaAjqe5U(P)O;jC!$#X z6qC$7a8J7?Ko5`S;pQVGDm3?|xu{@~<0;Z02^4MkCaNjImUY?M_WjMO0lncXP(pW> zUZ#=+s1aCw!oA;U^OExR<;Um&vO?WRP9#SG>$1{FQjV+_6zBHy?Ro<4XxxlR>r^bd zg)&?8RJau%USSHjc4z7Z20QQM(DD^)OuUXo3OTanX;^~!?ruU>coIe$#f5KcO&ZD6 zl!u0KK<iB$hcCn{4ek1>2FmLb;o-M&>WidBB2 zyUimJTIFzT*${LFbEc_a%fVg(-@3k$46QGSNbxcs*+2dG_CYZmaX+q!D--tvd4X*P zHX%!!olc2r->~irF2(m6Y)Jx>7%TFun%yBlGPcs@bI3o&zW?z*5HTkI-T2=UY5cRN z|BE2?UqvDBfOA-ecpD7?9`9d>BQIw8IH8jt9Q~(uR6;D zV*#_?OD|qlL-kMI)Z@K_2VABkb9FaHRDygzU(GoJ)rElQE-Re zs5n#yG1;zh4b7Gd>WCD=Iq=elWMgy}2pv=SRR>ihNMlDu=&2mUd}TsNM$80kBdD0Y6m_fzix^w0mZDdc}S z^E`bASQ@ZHR;0!Ax}sfwWT!B8azbwyUe-BAvD!B)Ppw``Nv99Z1hS6WXCk7Hmt*pZH5G3Hr%2OJC5ZLtuSSe+9_jPo*D znJI+71Bj`3Eg+X__r%#7w)sT8&JxJY```Svv`|p^aWInK49@4torM<(2Rkix%!GOD zlG~_;(y%FfXs6We0&534T9z?V_m&-9Vo@klYtLFh`*i5+F84R!kgTlUMvNW|A2#cK zs@*R@gc2mW|Ff>&_F(w@_ayjs<8&Pq_nH+}$|!1sprRW*kDc2H^?xzoKR*Yn$pWTEm8qWZDzPcOVeBv6*&xh(k;*CL@Iob1 zXa6IbMP!a3MqFoLu|BC~C5P0_Ysw*3J~t!0;NnV{dTE6??ZH{LpP4u|UkNgr*|%a2 zQ!zE|SEqF8E}p#Z=|YUYB6iP{motVXC^`AY3USJV+aZgRm+La2*qII`awqiP@^P`A^#_4(~fkW4%40lStU+LeUaG*OiO30Uq6cAGJiIvAjXArd=>T# zdLp`?e(7#!;|aX^X{2Z=ZsAJMTHhJCC$klL12!%fyT0|;2V;Lkc*B6W5j@X(3Yf0> zQ*uP^R}7@E?>@7Gl%_R>*87zDh2@D!F7Z`rnxk^9vf8wC|4)D{FhfD3vS2s|4;~va5s+FUNGXwpRTY(lUB#G8 zMAV5*ED%cVlXLE0Dv6-;Nrb`P0SHH8UyZQn`??UbiL=SukW~8+G(tWT$3Y5Hql8$f z&39vJijAp_sk6OxN&(X}=F~|Jw8Nb6SFsYU%i`l&0oW^b0saK7H zee#`H=1!X5Bz0Ng?kprfkZ-=EWRymqu-RP{K0FrctfxV0jrVzUaSoUFXEEUXK;+vq zH1Me+Mk{y+NKyHjZ%>WpSQ^=deqA{JT?N}{BsIv&qDmmsj@x2tYTu1$y70|PoK0@^ zDjP@mn})w_i7ywe7PT&-kA-<|Js*sD048;c=2I8MTn6MAdTOSeTw)HGnDpTj(3wI) za{IZHZUha@E8rUsRin{>8(KRMxra3%;tVtTh&RSj`h_U6Icl4tk72`PM-}TTCzOW?aDBGtC)cDT6X7KSKhXS3^bgPDY@E zMYMIl^Xcn%2QE%@uf-dg;f)Ppg#Mj{9Qiif){kVbLh=uLCo&P=`d?!6zta3CH~l*R zi9=Nq^FO!^&2}1sKT)V#($;@p9<|%&a>?LT%q*V#14vvR{u_YwPr$!R@&5scI@OVV zoSVXM6-1TF$5g`%BbE98^XOH*(3|NO1X2yzsD)k}&n$l7Ooji#$m00AFdC}XY9N}6yqOSrU4ff|^3jHTKEpA`Ufpho5c4%!ewzZnr)llf5q$sp;Ajw-=olc11fokS#*l0xPGsz&-vj?5NZ@}H zq$sn*jU1RQr=U(reA+>2g>&^s=PMnSJXonElF((?Ps-Jr!=ZUm1LP%^ciN&~6)Y%N z$x=JeB+{^8@iRT7(T2(3zlubzo2JIqlDvIeG%ZMg#P!L1X{Cts_t7Iy6@|2qO$@d( zG(mnk3#UMSApocOs(!1?mi8E)bOaN{QV&Akeua4M z+D;Y@7}9AJM=Z0j=cm~Zlrm!H<5|OMIA9&B-cua{UwseU$z*nbyux^Bl_BsZEKN{< zB3=VbZp%9H`I;z#=&sqlMp73DG&|vAY?IZq#D5hZmc9D!>99wcbg4m>l{Rv)dr7z+ zJ!AM6ICCMU9GMG?)BeU&o*wo8qJGDglb864Sn_`agv@`1x9?k8D;>8F@}nQqPOfG& z)a_{Wwz*l@FaO^P4%}7Yr>Y4Rf;y@c$f^MZ1Q-+)6f`6h1Oz0+AFBpv5TvZ=sAO!S zs*o5YpPb2AM8tyFRn&}K;xJ8|@+icE<7+uwd%w?YtD6SqCiKnz)rG+T(83@y2earo zi#L+O3tQedI)6Ka|EUA}^iRjXHuw8YrsQ`Amay_(^K*KD(Fo={Ks&hP_$B!r;HrFj z@t{z72q?6R7V{7x^FKgx?i#BY-FdzLr9%&8{CNCU4W&G{)qTEmv2!#RWfvbNHs=N> zELr*q1EiIHb+gR7L_6qD_H62)rR57TWuL5Z2Jg!{)$=#%5O|e zAIiVH==`(VzFyLGD3i`OhqYPSGi$)@VQeb)xF_*7iy@aDvo+ep%{ayH!J5Tq*>9Lz z9kP{$FJVEo*PAU{p{F0}h^@0<{nUH-7?yY{*Ao+;&m~04P2iH@9#^*{>P;hvxoMoZ z!_XDkBIS$n!12~~(F~m3#T%BP`Gj@zc9g;+`w`)vMU}faX;3C>0bd8$7YV9_IFx&a^&%Iaq$*g{ca&|ILXtg;AQ_2}qa&%GML=alpYz%uOxf%mxRX0>g|x0lY5r{nAF z98_Ij%wEVAm%BsXDRP6M_C)hFjI>!5P6)~|xlbc~!k0stwu_k6JH5tP!a?UAt=plG zc!Wt_5+5_x*JDSB78}iy{<|`t$Z}4uG+u>HiN70NSic5PsQ;DijozQa?0pR=?^VBh zlMiSu`SlX_SC!?AID$TAcRcN1P3Vd7?I34yU7C}?bt^h<$~<;M%SZI z4n3W@PQiE%WyTr75B*Ug>vBqjcJqw_jq=fhuCD-$sZTXxy$ICiaL=uO%5FWAC{74= zNFQDL5Cdb+JfHb9bzPH|_^vp#XBwfEk=YdPn1=Okb%E!{oJ_M3r`+-=PzpYpjFkVb zBtgIkT-@f}#RKn|^ z2o6H3p}*T+Uku*DqXW>7SGq5x?lZL%iZqQs2CmZgO%Cy`p$Dbf(SY~_DG{{9x%GfD zo2PZ-3^{j*N$=dLfmonzTc~tfY#^h+bgd3O0+ewDR&b3Le6K#GQ_i|^l`YJ}A8Pmq z81}XIUmij6f6@~CofJf}|B*xs{@~BMe+R>&Q|UwBPX84p2>i*o%6jXCF+*KoSZ^X= zVeaZmGHD6Z8nvoN>r_Mw!A)uy9K2mrpA-x}wD;7_@&+q9f zI@E8{Z$E}hzb~>aUQ0_G^>seMJdrso*=gAmYCzbHISH~%ol6aVhq!HrxVyc(ZKl-b zxLzu+ym;nPI`Ev|wI06Lv^P3cM`wA$)ItDvIqV-UI`t~J$Y!)Jdv-Z-7^q90b1^AkEedn>}9ynS#@I2tr6{N)g|Wvh9e6F5?iXip)Oocn`bR$eXu5yKH4p_ zIa)zHM|<(z_}z1iQv zPNOr|R^`j>3(b+$2Tev1Sv(2de%cCrxb~Q$!Ux9V!cB|U74J$N%a<2aKlb8sFa7os zmUjR~gjAy`u)fYC*27oYcu8f|uk~84Yw2p>tS#FJ?3aWBc?Z0w#2PV$Cxo{`b*U)C z9?-HfapP4(afmV9;uVd}|7#-8&2vm{5K)+VOeg%lg{#JhvvGnG(0cwN^j4#+GuV#> z<4aIc-vE^A>zYkHBpJ2$Z@ZG#d5#}*KC4_2Z^v&gT5Xxf{hHLVy-=E`8y|fauZ=D|7*=^LrFqJFmjoF>GHFqEu zb7}^_8XT7fM2;88mCk)^C6Eq%6r=Hi7ZNx(!yZ_6GOu;Xd$^;muqe++qgSVrPWRYt zL)Zs{YX2fuQV3gDx^}U_%g7Xi2VXYJ(^fLRhAh*0=|oiOnWn=e-tJ`^ki|1*w`Yvq zf$XKQQG9+ON1;c%GR&W)5@P>Bi|N8(TdOP1t5mf;R6P?IdLYfIf=KJQAk%T9w|tH2 zT}{^BR4Q>RK`;t_ukKW+H==O%MqhUwL-k9%4f3aZ1G!f1!pG&CB}9Ecka>Z3fMHyD z)x>A1s;;f`+XtO%Q(KDhOgV?hFMBZ&b!oFdZ{Z^xcXfZna&V-7c?c_wXOOzrxxPH-|#fT{vQTVQqttak=;iJbbrH8)*j-54sXhi~Zl4vk$fAHo0 z0zr&gvlZETphM(FW3ya&c2v9}c!@5ztRz`ILxK6xV9zL3jmsPblGkDFISUaV*bas~ z-w$lkUnpx57*Y%~x`=vVT`_Znp-y1B z&vI;j9NXulQgP{cCMxFPipR_Agu^g21JZzx@m-U}rkHPkgYsmE5o^<5*kvRN1hSkMsGs#FlJf>ZDD zApXz`lYU{{I^WX^UqrlP(=WoSXfErKG1WF62Gy-$AN`$xJ}{sapqInJ$QE;f1Gc0z z*Z#T)`wnm!ig*l<5!_$+T2gqc@Dr|?;^kI}$${C8f&0B}f$oM%U;&8i3+pw$AiNvjVZ-A5FBsR8yM0tVv2Xz?vybj&%y_^KlxF~fd&9RGAt3Dxq z6O-qyHtD6vK6*f@dszJiMEq80_$C+l>3G+%cn|#o!Nv`Ie@E<Pe(vpC*rt9<+oIpMx%Vl21FRtzl1DVjI$K)Q3q+_tC~?#fZSU`#!cu8&xvf++~5I(o;QUF{Bu5Lrzp1RR+ zyPTs3=Ty4w8pl{e5+j>{#{(Av5d(vla)j3%H+-MASVKE`k1u}4KmkO0V5;uA7VXAV zipGP0|2-`AGsHP8^iX`=KXL9KQVj>SG=4@g@9e(G$U5N^AaA(0_eggET9t6^gAma;5T@6t9f^0|B|_U7vTZ}6zEZwc z8OhF=yF*8qP0W>8_dXj6Cu+c&`p1zL9d>rMXr5Y;);f{UB}Zh;Bhkv9hmam$o>fp^ zy&?u&KVd;2c-snrJ#8Wo5rXK(P>0Y3d}CkAqjV3-1m1E^7y)xL5ffX>D9BBYpZ(=m zoK24VI}p#%gZo`w<#fdUh?_xgR5`osf(Khq&b^g@SEdHsByxIuuAdy%aFwA(I`~q9 zyK$-cyMU3=s}(^LdGdKH_rtOclmhIA8`j6Y*HHOmIERr8-KkdpblMPke9-fgz`vAhu%M%P5YyKze#%4HwaN|HVXt zqM^(qk{ywjQDPP;qL?7VwE$!0LiFOLyf=w{DRCUn8>zJ4R`%Jha9cIxs6uF5-$B2uH13-AuOHF^!yG+(`2VVF8 z7Qjh|yL+Qb;T@LuoNL~n)2Bo7^S~TqFN7fFBR2oO)FzuJ)k)%pha&N0Ma=By7bXwO z9o7fmUrJ_!d5QSENHIW^1|F&_AXj<&i%~1PtOFr zc7L_mH3qvsLm@pqrMc*ma30>rhwvTNW_o_srrq08>9riUKZBv3ga1_uwQSAO4yvO{ zmUYkqVA`E<-CWt&JUK;~87aPcG4^ZP-j{HGnepOb zkI(tX4EwMntt{yyvrD7gKbLf~;Zud53*tU#Are_NA$}$mnE5V>6Wn+sACnT?(NfRunUPzeBrY!j@lwdqB#fT*=Dq9aiD(?tr!v#+gIZ%Ot zC!V>3IqnB4~A6A8IPd zds+RGuUFTk#?G6+ywP5*ZVe5@wmQ_*)NW06cE(ZeY}l$BlIo07rKPeoYOqjYwgh5# zU0J6pY!W;!SwnQqQ1Vu|CGXi?G$Q$N8SqZHXCxB#lbm-=V9|YPVQ#XCoBHG$1qfN~ z^Yy;s7u{y@KO#DMzP{e=7lwZ|kx(GfTXuWMq}FBdG@Cy_I=>@cjwl$PSTMY3*PADP zQgnS5w_$0KfW*@rca3b1rTBSLZ**(g_5{JZ_>0P= zy(X#7@NimvOc_z~MvQ4$NB7jFUOf}KaNCeqW zQ#Z-*9MCU9*KJwxgjof51k@}(K|y|z#106vyM+P_g5<-WOjlX`rr^Ngm88tf#0OS8({+K<8|Z9KJt(9zdxl^NZd`d4}f%pa2Hj z9~#731OfS*#I0SzO$+9vB_kel%+=QN0`^fir${wU+dY}Fk6G~Ab;ayPL#H2*bt&=i zhJ!t%p<}>sDV0b%ZgpUYk=;k=9|mJ%YcxOLKc=aZ93$6W&g0pczeRQ5wb0j#h|qb$ zfVn`eet8rPA48R;SCe?;pH5mQ&6a`bBif|rm<@rh_+B?F?YS1QL$XrS3A zzf!Dq204ztL7RNJ-E)C+o<@Bd8lIERLum@k2SC%gOB(Pqz+ChfamAe9Xm%mfz#%Tc zoG%Ngg*s25mJ6*Ica8+p zZXEcz80<~macgn-Ib`labvx;xDtC{;7bxOE9wrJ}wN!v}L4xo}_d6HFxXacS^<-~< zY$Jh2s~Kq{)GfL8RSl(H<4xq`E4c~%$)~5rvVFy5snQ#rBcn+yLT}*lkv-G=Xptd{BI(Z2T^GM!P?zM`dvRl)Q%sHz#DWH#hSd~)Ih*Q zu4Cx%qIB~QzIrG#*=jJ(5aYC6=1;o>icrOr)7JjPa-40oU;%#n=wV(W`z)*Jr?Ok56u@WVSB64B=mvk2pl(Rxcc}ZasSmbY28x%jKrV7f`^$n<%Bi`zEyIu7cq_ z>{|HpJQRiJaNutk1q9G8=Pe22+Ym*dMMqQb>x02aVMIRFwT5o{oq;4UKYkiKS87Av z=_|d?#0203pk5!|e6p4-0toRV5WDEmFY6u!qs7!PrcKO9jVjRH3i-29!BOGH`?;F*xEf2mja zVc%ZP_{ej=X)>iLuPuafll!E*N&x0P1BF8?qU;FH-ENeFq2p5tOe7M|KZZ^%)VXut zm1aSdX+%Yxxr;_?Ys%axZXhQfuDTWDNbuSqTY=c~!&mU&EV3UT{UVa?b+wK<3R;BS zmCMz$7EnGa2}fcNlLKwjok-CZ05U-{d{4A(N>`E>yy8ltNga9!5)pcZ(&=^tA^fo1 z@!6ctpE%;Vy&(@K)rFJ9WkP$0jotx0=ZvMZpJ{nih8j1aujRh!9yv8ZKEo8!ET;0c03VRCK%^bw^yQG8J?THkrru)v~5GH zZ+*&F|LF4I0&hcjBd%wpPWvA9co14H5 zKQK&bN?Gac&h3%Ay9Ef=8eZI?3fzu6$5`VwDB`@R*6U>4!Z+d`M&!s)~^8`l`D?9XKb_DG}{nOm|$eGV%b^ zl<=#J$~LKBNBRypdBN~16H8rd1y+wX__hv$%5(Rl|H#n9I%aocw;Iwpbw{DoFLDA( z0Cav#uKf%G#!)E8VX8jzYn%&__1tj23hl)4R=qp@?Az&C?8UeIs~`#kM^wc8&!ndQ z5lch#RQ<9^_tFn)*2L=&*Xz}9m%Z&B+ute$(;CS$*0dXJPt^8wof__)Ziw90tuEI{ zq>{N#muqIN$2JEvKAe*c0PSYwv-S@0^Up3zoEBv@>E;TF2+3(X zAMN?&vHA_Yo&9O}LsPaK3chn%|%dfN6l&bMJo$Ia+AsPP0u6 zA@#&uXYz}UH-#asQ_`3iq80JW`N*r~pH!|oFBh+mqFGc6L&>Ia>8f;}b}Oy`9p^Sv zrLdv?5X`5Xr?yHH3_AF^GBe+DsAc9G< z9TTmqkO!qEKM#Ew-DA8DnEtlNj+px>MjR7VB$yLQ(uE{x_J(`OxKOMMFhP2g?fdBfU-BA&S*1v9{5 zKA;JMHohjA*fodA{!${>;sx^AyCH0{?g7zx6DPdp%vCG5>q?3jC9;If^5_c9_(rP@ z;B!hfWeFFkeP@|~HX-f`I^Xs+dYZsl$VLjrej_RyWJ>Yb5y?waf;podHG~S(Ho^8q z)Dg+KMXo5AJB8XOLVhv;!q!D|sXn~;Eq*V^9zJav#kAk6esbBzYuuK>??`B59bfC! zSXFH6#`qefy1Ha#R?w}%WpOuMTj5*Lt{zo0B_!`0-u@yfl;ZW^KBvf*KU3%U*GT!ZEFHAwr3*!HGA0 zGJ459Bum@hQE7^eAir)<>)MvO61Lc%5TZXp{-DH}Ip&Xfa{iPRkyO+%#f3S0C>Vk? zOKF8t>ekCGacRNbB;C(Hqhnmq9-uL;>uOT=xd1hl%{0Em8IpPzJ|j2Hk&-4SB(lv4 z>E}bLm4c&9J}$Abt~op=?L(5{ZvKUjBqK^Bq&_j6PYuS>$!7?ONToOY2v>X)*-<}j zB*FDeoPagt!=G2F_ed5cunLx-_vws7=v&Y3ehE<|1V+Q3A$eh#_wjkKNTx40VgT7J@ozQG0HQVlzjVM5t9t-)Ya3=J8wAR7Xu88YE6EZ>a0 zpS+9P8%^Ic=y)bkwvxkl^MS>Uh@(m-D?8*cc^SG}N zO1Gn4wg7>bzHf$QI4ouBF)5Nj^s>$c!kIEY{9E#qEb@b-s<_z;f7|jH<$kPk&_=^f zkbr2LT_%BEd%JJFVQJK&#AVdVwvp_i{Rl%KV@5{87tIydP@1HDYCES~!b*c+9or)u z&oVy$ZB0_n_@(1(#fsw$iK91_N|}0>xu}T?nr)4?2fj`0_jka>x04T=9}?ROKxVuO%nS|#_B)wNOdQ4owPxp)@POjo0F_|XjA|y6 z;u~F8Q^VwUQm#gv2TjQ$&)58FA9aYaA8NI1L`$L47S%=JaTsuC-al=evDV%JXlI`# z=V)dFJO+#30TKApjPzZ3>g~RwN7{ZXbe^#hH?T1iM)D|RR2YrV(gI_Vl2NugpZhqh z(Uk0I8&(5x{FYBV9eHo18Z94^lsPtL%8??(>eopN+`Hd|hwkLP_CH8x+U0N%EC^?M z=i(yXcA?E?6pn;)y497H_2|V%n_;*gG&}6MHR-$Tw~3N!Y>$@ob*DV%((-OT(+3|Z zIKrL;Eegs0;=NH@Ou^K{mKp$?&`0CZp>S7$%0n>6gG3E!%ZHE+<5O^#8d#PKhNTm! z+h*adBtbV(WyDdFV8Vb&7m}^zR+=Y+@5KluF)J7rOXd4q3WyInH7{M3isvIUvZ8|} zb1F0=31AnAI4G*kwt-5Hl^`b-+9KvGOM&e6nZmAZxQqv-TJ@m74!IM)?sh)y`p7*lIGxfD-E~Fq1cFn zi(4R`OoWLo0$Ui`@;;{N|gK7@_(>=28n=D5RWY$w3;4(i#*3yhb?+3NRJDswPiD&+OOr z>blL%vJeds-j&g<;5gaMF+@I$O55UhK1KyLj3u^-aAk716@PUoj2X^dNE*(x=Uj^+ z1jABfODwAkM4J_E_z^VcbdA7`$`%bL!|M-rbD+mt=IP44y*M?w?v{(3U*yuFo-ulYOfj62oM4CR(b%vtw-OevtTB{hn`ijVbAw~N zer=Ycmaub(^v`0*gzo?nLB3pjr-N_&@n!8g@)RkbSSPs<+c=*USuT6vZBOP*GnF3V z1()zm#_Hk!$Maw0S=z~!#NpjZB@6MoiU1oN#F_@7JUec`=}2=1pd)oW zat@VUZ8T7Y(M_XuQ-~um0x`-p+}Ih7MLac`F_@L}>1<#^@08vFSZe)np&r0|DI7PZ zH#`j(IT__~H{g6j){w(fD4`)31bmTny~Gk3o@gWfb_%axUx>bVM0+Cku^=@ZNY6qA zc*;hmNp$JOq93+my};+$2xm}LgxI-S7si*k^ixT^O3v{!guz}khIWgUBMw`;%ugGL zTO#Yu@B|y>84uMxO^deftMg9{X28X)m#R^3_&n8jKntp$JV)IRdBkY=>ih!3;$M8h z)K|sxrJnj@SPHXzAp{*_Rih>1{g-sLxSa6k)Ny6kp=$o&?wYWCWeJdOw~AON0ZCkS zAJ!GoD4q(`J6XI$_R8={a31u3R?S()C<@GQ7~)?4*f7CZvQfq7O_E)2`=DYf2NYjj zUb#>@NZYKJFVo>|(Hh!=P<*7B^MIeL+^$7MEwq#o5v(H!>>6h}Q=qd?@evSJt*Y=Z zQY`)yVH1Z->Q@=?P|U_KN7ECjQ0g+yND+5bt<~V)2wv&tW{gh~(jT`piRYx?s zN3sM88WAblzl5`Ic79Q)V6%7&qh7Ue`A)P1FiPDCq%KGT{si&I(Mp~t^qq6v3*xKf z6Fywf)z%8U;u28B1@1`MGeOhemU`d}F5;?zD2y8p@bkZo+kt|s;+8aX!V)tp)|Z@; zQsIz9KLJ~$*c~zgDQ-F(Zn_9yR(tsw5LzYb)}9*M%Vn3m(5{Eqp>r0^Zkp{&h?9v! z^Hmdq8}Z9Zjuv@kbvoqv9Q>kIFN_Ce8b3L{I@4&`Hgd*`oz3^#?RH&~v|E*Qa71WC zyWrle+JGjo81fy+o5T^+m#m3oeQcWD`85tWOZE4s-xWgIQv;$jbL5QE+vxWbu^Y+a2<1ZUDRvMP9!%u+S3`kDg z1fs1#FPEY(V)wB~zv$1?p388rZG1wc(K62wN)9@CHE`8+h zkB{u`2>xWa7)I~6qRY!jF_kKPbt~GCy>FNJGaQu^qoR^KX_7B@sezV`B#gxr_$@xu zcP>1+f0V68H7<0W=O7Jwpn`yeovwFooKfamaCJ^N%GI%e_-^|Ub_yDRS9s}vvGx{F zaV=4sD8bztXe7A1yIr7hcXxLU8X#EX?hcK+26xv$;~oeS2!s$IINaCw{{Nf#*Q}ZK zX5N~r>N=&`uejMcjHstIud6f~sWf<4XvgF{ zIBGTJH%_g%$_<5)y*V>}wLZ7fnAo+ICe&DTT>(|ed<)WfU$bl&r)j4U7Zz(7$YNMN z0BL`Oy#Fk94U!z}A}Bbu6)on;Gp=6t zJH(WAa1d^z^qZ@Yx4=bFAgU-(RkB`CB$amD7 z4pe7jRLn0B)bHO`ZpztpR7j`B0_(*3AS$`qj2+E ztKy;fHGNZYd~3+fKF{9w`qVMkXM~@n*akTZXDs*SFOQNv0Oj>(t|FTtqwSKSXL z(LgLiuTTeeaVV)2TE%X~yg2{Jni=1H~4#eMTNaak=_H@GKq zpady6q(wz_{Dt?es}Q_76Xlz{i3N3W$?1CFncgGW;3qE3FQes3~(p2al%6`|)7lp@|=DH={X{GA?x_1V~xAUa&9?9kV38$LJ!{t~2~MRB65 zVjYt;w8-y+KPijRibBXwoJ?@r&|x!CjMw!&ktar+-i_`>S7!398hX~D9lhH|!+M>m zY4o_222R&ooKw}aOIEdj?{+(@q2YO|3CjT-E+te|WhQ}2PNSH7HTo7HiL_YbSv+8> zvBSslWi4?AqN}&&f#nF^^y|4NH0o`r6tbtQjN|(tc_Q=fLzjq6T04Y6H-L8B%2r*R}NnhU_Jn`Lu1nS@6f)mclXI_^39GgUCwypuEuc zYl?c{%6t1&GJr+Z89HkCXGiW;8Biv*h`+652`WYPsA5!|;_@mnzNPw|28b}`R6{)E zvEfPI`m)U2&sM*!zie<7t-<>p7JdPaU9c1bIaDBH-TJ+S0ku-WFKS1K$VZ6?K4oTFGkm!ccrX|N3OX1nSkHh+F=n`|d>duRsPkY*5uxH7Laj z9=7FYiO+AH2Y?Fx%GSmU4 zsc!SEP?df4<4kDaqB)(2=KF{kcSv+Fj_j_){K@ZmM~6=Woqrz#pLA=W_>6oMncBH_1R&>NxsO1Zmg-bO_G0<>KP!o}5ewdnEBN98>k;F~Jro zq$C9)INp#h)~zP6?Hyq*6$mjFmk%8 zZngCYGm>WPmK08*rcClk0&lew=a++6oqbzwfvWBfeve*!CH&nfha<%Xx}j&Lg)7Dl zuX}*PZ5R*3g727I^z*wGA?czXeSlcT-Azp^-@UU&`4bxrMp@crZ|7?17&{{S&_U&d z{H?aSJzTcIOtra2*Mu;G&KrBiJ|tAIs3ca@a0@A0TVKH}5aD`7Mm z#zkIfA{M$6m(XKVi~9v6U&bEdQMs{V19@_R%fxXj85pm-FoNX!B)`g`IyxI5&ZbI^ zE!}Foa=7Ip4eV=I-6fCY*_q5eHn{k3KEbpvUL5)}^RAW{y(gHLQ4G5x*ZtIDx>oR9 z^@M2# zh)!Zo-U0iAH~U#=t1-1IOaiV`t3_$4sGdD>rfneP7BW)P1W`- zv90!I`Qq4lWP0uf4=ndIf|@?$F%q;&f9@rnyJ*s?H{ez_Z|U#2#9BkFc+RK1_#Wr` zLHsy3Hg1&pzv|RbuB-VK+__eFPf7Lv`QqPjf6NJH!DZ7z+)KuVg?ptxs6G)f4J&?&k53%ON?rF=`! zt(n%hWyJsRvP&qUb|=1UHJNvD@vD~HWO_sb`m1;>;eIrNx zuVTm&#a1T6GBh-%rneBQ*=(fLT}Tj}bz+e2!`Q^BTKJ+0BY%^#+5NQ2mkx7%otezr zvr5|R4p!m2TTYd$T50ZX2g~+QM)E1JCWde zdd_;WL4q(U>u=(0V*I7e(OUSYN2NM`rqY_>>|_lzUWzXVQ@u)jdcJ#lF+iTl_VWM~ zId&tIe`5czC(1A^mkkUoAuDo@$g8;VVX41X+ZobDbzyL3us+0T>UN*7IxV!U2rl^} zZAQ-AP!(W2f&xjKdiP;Z=QdGLH+IB>9Pr0hyIDZ{cd>cMSM!95^6|!ES$%3;V#?@2hOj|a0cUG7A?cSJ)j4lQvOrD@0}#|-*DG} z2a2yy%7j~4e_wxl@IT>u@^YW|s2K16rQkjJZ&8z{dn5-%|0N{!E38A`P&#krzll?3 zyv4s{-iC(#e8qc6mOqw+0dmp@Q|<=^3$W7&qCmgfG4u01`xK8dfdv#NFXoSBt7Y@3 z3kEIOD&hmx(Vj)z59M!4os;$dDe9J5Yc*H0_B-DiF~ zq&Um}Jif@lN2Yn+MR(fMPdeD-7t=3eN%*aG~8Q@%8QqjdJ>S(+onw zr(1k7i>kMdWbXd>i4?@c@nwba1le6zKS5%oA|?fn463f$`=fDR({-}ESmPN|&Tmj< zvx?29&E;XkMIB&(HP*rH^P5TiQi)KPoEvA4|CyfU8IwBCzjImMTw_;4in9t(*kn_g?Sb z3yFgxeHSnK!}zqFkMmm<1YKpI!+%W#9fC zx^FQr@@3b>(9pDjykU2wAE6yP_Y(9-yu=Ol*6u{`((n zGw3!U!#k2)a{EQ!vC!2@)7R){y&Z&w=@)IW;xH!~KJDJMdjjUousB}`H>kU#+lnVR zAkQITMy{UcJh8zSxGF|xCS;^9rOO$rYYs}3MpI3w-hCZ6ifK+~9>~K-|6J9^^5y%_ z;(vR+2ePGxM&uU`v!kWQ7xOKUH(m@nCp^e4;SkBfcbEKRIMZ`uiE+smz{OT}QDq=xc34%diGbtn*o?@@*jT82ID1fsEkp8>{;*{!cz)r6 z6I0^*@3sfS7ne7IPz=ea;*o_z>uRUpN-OKg8)12FE|ks>YLR<$dHCk{Y*qI~4%vuz zl9_+tvfn1ko~Jto`~KT)2liKO51Xl>F!*DK;*r^vpB2hC`H7a7_Gel8@WEh+!-W!A2wl)B?`qL4&AwV{a!E_RXj0a=6z4hPW=luTb&M0o6GVPF9+Ii#?za0 z(;d@pDnncy8h)KR5*Pa|+J6=i>iH7hXK^PTUXNe0!xQPI>eGB zryl(c=O6IZ`}N@M>TfuY&@Rax%1h+IE8fm~wFek5Pk@@lWekj|`|pLHIQJm3;K?@) z$sH1mYwWt`=(iN}=aIkR`bfUsqXO@dqu*p+hfjhR?hrzcFx*dAO^Vd-qMyU=i#^4Q z|EXgCKdRWGyu`T=uN*kg`x}lr^cm;%-P^t$?9$T9i9#FA70GzFXKt2cFsWdZ)jTs76oV(8)R7H{HsIkPd0kF416O5Qf+AL)>c z_e~5X<~IfHm_Jy{**@kg$ApIaS413InVG|0SvK$i*{G?9UcYT36ksKUHzArB>tQ3k z?jRd^F^-r)Ka`S0{QTR|Fj5qp}gLV~tqV!`Ws#j4Dt znr)4gAso1wHtOIyxg)%!Qg6BAur`|x5tD~HSg4TmC{i8a4LT%YBY%}~O9rvuZuD?a zpnl9yFq+s}x@Q|z->wXH)jfwPO3_1uDI|5?zCu;ZvaNpb1f^FP=s4>sEm4J=PPy{1 z(*=u@0zIJZ6jGvM8Hxa`b9$PT5OW!RaO~O9U$TPb0+=ht_V15n$4CQ1+DK=fvIH;4 z&Z5qDOvmUGv6QJZb&HCGcG{5RLflJF{qO!X|E|~F_qaa&GQJU1tQxVxIcH-QZg@?E zS8m%e6=SyIm~zfFAR8dZpA$TpS!v%@+dSD;##38HKU8Fnl5&krkX!UE-QTKBWx-Bl zZM27+F;^^xF;y(~NS&66HRFyj&#Hg?ULK&km=V6WY1%oA<1@QdkTIl+bqy9p_C!_M zbX0Gi`led_MM5mygOL7>dnjDU$kd;^hkiplUk!H^ie8W&({RL*crE z8?~}vadlMABb7~gJd_-Lnd@5~UO{5V<4f`m!UEbe>h$O83#Qs_slQad@MSr(tgumc zR#j}U(SoxzYdLBJhLaftwk4%ngc!DbFb&zhkX;6+h+T=5cFZM|4VIp6Ki|$Kq6<}A zgx7e{Ka#3eb&cT%PcIoQn;p^Z3xXMUnmTv%KgrM?&qC3rDu&5t8mBJf6Vs-XzP;a~ zS=HW%OP1DK&1|{#*HNn#pb_YzMVGCn*KDF@cMFQGtR-cbP$m5!k-DQQpevfAr#`?A4_r&8aL$~a)`1Cv); zd|-=l%@`lMqtId!i~-G+=(NbxE*nh8`qCr45IY%HlH6yx82v0S4Cfmv?nIh~%yr;X zd%@%mpegb6;`=Z4(ZYA)mtdX)y&+RdEjXFL`Q8t03J!XW5r zd~=4>w&VZQ|%RcM7j;ik6sO zdVPZGjK-31O)5RwJQ9EvQNVr}^T>nofsEVH5@qFZD5rtu1ZtnYS!k3~Y#C|SkljOZ zWG65C{=)W>V#G_aJzFWYDJHMfp6;a}S1}HwD@z;Q+EeTCNi3xD=EJQypxl?{93qMv zSx(!jT|q*gt#F|vZ$%^Hq;k8x^g@DgWbN8^+m5z=6~`!-dY~y6=nvqYrU!y17jN0g z;VB*%y?9s_Cw78J@J%(Mj84Nf(3m%(G@rFehNF#N2t&8?x zq+L3P@-W-0?>qDQeD!G9TJav)<(h-=i}e-NGSm_N8Uc_2l++O;Ei0kOc0A_o3kK)S z!7i$tj2A23?pkGO5EKOovLtPGfL~ptzW)ICNO8nk1wtcA3fKWTe)W>Xj#*5G$$V*mq;=?(=);7O zZ*8`D_!U;=iTSjpl`9H{X;_cZy)K00!|-%Qd!aro3tt8&FA)OtFQOequW4|>MgRPn;rzMkNJ1X{#5yLm~e#PP6| z9+(VLDhCob93AsWg}w;hUihfJkLxG36UWbtIEJ=R93 z$8aT^WI_CC-GMvxY5$D)1DMC`TO@>Gm)F7NE(pgIb+%;r_ezU(k8bFeCB>Zx6Sz_q zarz*a4F`{WV;ih#dkgf&=Rny;{-Vs*I?D!`{U>g9631dhG~Tq0mrC@NL&x|x@82t~ z@fAN&zmbw21);PDNh{xqqwy_t<$B5BPG-sPSKrg1%Y2jApVRluW*ayW<;Y%SkGeV) zC-vEK>lcqa|834-HWKJw{^^PxOHekV_6OhHqGA>iQ*{IeeiaB9Y;~cXCXcyDwqj~Le(Lct-*P@>YzyerJgv2G6dVoU*p$7K zmaoh?X!sc8i+_o)-(!*Cxyh4qOkq`NI4Yiep}!fkCEQrHKP;9JWXfKq8G%g!lC?Bi z96<83xg$l%2<~Ur!_qKR5jP8Ua(dcV3Yi|fE$HFA0ECHA4F!An@gckSoeI*3syeH=gwno94~O?;Kx-+kQ_Vrx<&ab&iY zo51Qxi%rMa)RZh8yv@1w1m5GQELvT&@vFrtt^O3ckO~uKk3ORfOpG+k z$r@?#cO)Vqrl=Uoa{a^`@+XslSvX{AVx3ByzG5GHAz>|Up6wQoOxur!C#^YLF1E;c zI;jB6vRHq?m>PqT!>mRMWAAb8nf&Y~JLCh55)ErnZn><+k20;SucZj>(M=oT#wPu*v$J0=9I zyv!1^%s+xzT+1m2FWh1Z>SD8S+aZ}3GZ8{|FB+tP`TJGvs+1D zc8~wq+DkFF!OHR{!jcT@#-~NeIOrO@xEhs&39~4g>q)fhnAIxD8EIT@ItDqD8xJmX zL=QEZ1-cf-V>l(!fyqB^_(k*FK#jAAG3%Ae2aj@$rfVXY3famD8iKAUen+5%3pMAV zIn`SET4)v?1s6Wz>FyX*=dBwmU;a^$S8cW|1u$BTwdV&VD7om?3@O%Hxry2daJi^X zDOF8XD(F^dn-FSe?l-&&4CKaN5Qfffnkz=R^-w#pUCEcd}Js(+mqkLO$Oezjrv2T-t%kO(k z!yjl#c}RnLMU8uCDhPYv3ENuqzP`jcAxXx28X_7m*1+MHuQHc(dj>lU z&cL-cW5q{Pl1aY4el$$8q;%__)(p36S~la1ky|lEmFyW)zkS1veI7Ye39qv3gtSSm zNoScJDaI7uKC09k-^%49#dv>kcKD9blH>wGI~#O@&2|o^%QlY`_Sf>S3CJ-OSwFA1 zPE{F%V4W35V-=ucWMTl9ndy{t&>@|E795&_KO3&2kUj>c3nAbZUcy#rJj0>8YsM3m z3DQ`g9X)YEHD#papk5jb~7*Rtv=xgtwRxd5P z`75c-8%rF*%m5;h@fgWvUVfN+nj)nY*KmTfF3O96)4E4V(^V0m+|HoJXmGTAzNpA~giqjoe|`F9y$0ERFqAj@B(3Do%&vbKQ_JQNE_Jh?J7}XyN5O zG;iz*oyKQvlSB-1G55Bl-qlSl^UWt^{92S4G@0RXCH66mc@{r@@vCdf^iT%}c%V*Q zhZX;IR;`BJ>4K1^D+{GRM#%^);C;nZogr#@OwT4~R+2jETWJ|{^;iRfjG)$JN0Wh~E7EK29d)*tBR9ScYYFmg_e+`LsEW00UNV9kNsTJ~zl;F4$+CUC;uD|?8GFR*!@g zQCzyAPlZb)F7jT8sJOJ<@KV|fV()V=ZI;L`X%1v;7*NV&m$3GW-;L4h-<_8Q6AxB2 znc@K|6GCD`9a6F2RV5%_H@w4h*jn{deIiX`dhs^@^&3f3NmKDHA-8x*~TyOv8iTq6Ytb$p|EE}q1mQlf}q?IvP2}^5b z*F~js<3d-SC5_iB&Yra1h6kzP`Q9LJqcItzr(o*%m4OH#NFps(D%oL!jz`;a-;0OB zAj7YygA91;ia#}YQ5Tq2(JNj<5{yiNhu(GF`d-vW293#T`VQcxvfel&|E?-?mxS!+ zluh}le~fFb-~lFG2lfNu0<%zJQc#R{zFv}olqZL5P0bF`ikZ2TGogt8RBD}#6Njty zocHsdD$WVs0|U3%5BEGR?W6RrHX*N#U3N)M&I_g$AVX3|r59i6KxEnMZ3O{ZIk%I+ z0OFk+{|*l~y~SMce2gZES`gZ5lzOB`(#$n;H&zNg*D~oGDlPY?AT`O#+fZ-l*!J$9 z!J*Y)%9do5?Mn0nKUq0ZNE0%8A0ggOb#--J*A{Hi7K?Bkm9l7An$A&}1r-_>Wl_H> z;~uwofU%ThsIe7PqZjprhbEJE7=`MBbY?_FO}p&p>L2f!bJDR$CX3}S@*&FM`V8Jz z#J>=9bY60`q&kQSm3mQ-D!yE_$0oNEjuC`~Xy_x3Q74O{(4LTSLug29h^j!#6#6vtbY^rJMii@!=76vdPA{t2-c{y6W% zQ^`|dbaL!P%!L?g($p1==zsAXQ}M7N83XemS!jDVJIO{eTY6nc7Ipj&gH;kudpo-~ zI#O`9yv{@jx;nD6hjepU-3%#y2~YQCQcc6BNI>r30&+Tk?@&cryn{AfNg?zP-f>As z>$xx<%haP(mI@$D?h`*+e&P!4(4ACBh*Bjb%p9JXIc;8v6OaOAf$foW_i-Xq48b!w z8H!$1k&_egoyA7sb;~*^(Fq9>k~SvtH{5U{iB--6rj0P-q>)s&p)Y&M#g2ux{XJIH zF=P5*qL)|tH1D%PWK~VkT9Dy|eM`|q5Xpsod*d#mS3oK`RN)EBnBE28%Db4{mD~sW z{HITl-;v)6N1y5o-jJLmjy(WI1ZZJnO_nOEtsRLV1SJ)HD&4A0_Us-NNXfGuU!?A4Wa>-M1UxkAK z4lnez&p2{n`<-jc-PaskbBPuATpl_L8|u_SOsVg;KJm{ubK^osrfwH{VGtiDP9WvJsy)(x$U0J?3Mp zhHCQ`2tBBjA;r9c{HKodeY4j7Tg`>-P66s^x&2?vM$5qf*^N0mtcoy82lXp~>|YTr zbaHD#PAOjT@3QPBi!lbFX5PlsI9_Ed86uK zNT*P8UgI;EVOsqRwT{y5-VZp`bi&2jhIsQjx)? zUc7$jIMc)$@iMIvMso|MJ+LYr;E2$=-4R6CUY;jip?yN_yd85F125nMA?Z>FjIq=S z(o$#{Mu0W<3in#?LVOIsl%-<{M^$BVaOe6d-v*7|dFIzw0jNEuNU zXay`;DL%3~63m7#d6X(U*%5Wj#3R0tP92BqC&NHW&>}Rg_@W6H8;O><*b1=#_9Nh$ zw)VUW%f6|l&72i=xprP-=4CRxlD&P$Ekz$gYnKdG2S=43V?woLt%UaK0~?7>0X)7w zkdH}vTcr&I}W`2IBH zP)G!S%=mg?2TeV32_jnPu2{8O7$WL<4h*h%qS!ipQYEJl=b(VSU(1Jj{87m^VdFS=s)A2HEJBTHBjq5CTZkK84Gkx%7+%80Rhq-6MwQZ<#*Ji@?@NiK%FN+x z7+g$DD*D`#%tkg?Q(mHt&sM_-MlWCcKQ|{ou0-FEj+#wFzaAmZTE}gUjoX#q1M=edy4Wzz7d2 zWnGuYbcm9XN#yKSr#W@W@FGo=XzzE2yp_3^Iwoepnr#V_|JQUpa&2N5mDd|STnY$! zrEmS9{k6Mgf8#gQ5+~W)uQ?Gs8lDa@X*U{7>OBR69;6p)U}zH79@_mt+x$h}jcylk z09MDRn~Vcu12E||54kx`x6CBb@2SL-CUbaoik8XYePUy>B?~!_wO(~jxDsSs9J253 zEtYyd9VO!V@x7Ve>~wDJS`AX=!4uZO0d8JLw##!4s?$%Fp3~(T;2kp~x75#X8*(oV zUUuBcJlCS4d*aaydzbxXEuEaGl?S?w^(LF!Cl2~fJVUn8HwWEba(z$4=b`S+nR7~q zcR;@jd?8fWu3f!X`epDf$JeUu(~V8>U^07!XA)Y0YNzm;p~Bgz37+j#nCaV*jGHVy z%frgN7Gr!j_Qdr7gi=?cfJxbmHmb(PPHnqhr7>q|ZC}_v+lKw!`~Ih!b7gS>%PSav zC-I3$Gs5iTOT0Bh^ir&5&uQ6?rb6Xg=Z*B5+ms897xlRqu?VhxUe&Nztgd2!LMFZl z8i{8>Xc&>GcMChtw-4?^NpW5uNdT%6Kra}hl5Vyy$Y-5$l!w`?Vo%a93|Q#t;KuIo5=GOywM0)gTgk#nJ2}R2T>BB7-r{!g_ejk(e`nayY#Joo-unfy2a}1PuIr*L z6|EekyHpm!$kF$-_GA!hVH|QYPxhl-ye!nPjTagyn8WyuT1)6!FBUT#DLfxEZNF9% z5vK#wS@-hlA)4h_VNk-*y8G+B+~mfbs)O^9wkJb{0z>W9L`0AwMwfw=aKt5-f@`mZ zw_^TUjESypm z#Q`y`1&`W=+Bl!_O%UR0oVzKD>@9h$$)2EO0O?+zgFpiZ(S-G?k7au?BTqCNSQ zHuKGr4iL=J_0s;@@91tr(D{>4oSSN6SS4rz$jjOyw#LXAN+`Us`eTR?DExyi%y4VT zg=Y=97YClPmE0Ivnbmzbl|tHSK#uyeM+7&m?}UYO&Wsk<`a2Xpb)=FZGt6B~?QM%ZSFTmck=VEhq2-NTruxyQ^wDSR*XzT_x= z)MnKB1c>ARK_#^X-SOo8FbZh|3gG~a~{Z?x<8D3jCzK`=8{+&7rG>l zc&&&Q!HhtV-8{2RJ{(YeK|&uRur|`U7zDo9{==S;D;F_irIRF=+T~VXeYHMV8uX(r zo`wT3mD<>vU4A{rBbM@<<0m+s5#?#vxBvZ8z=u=)0;5y zB?(U;(8JooO z-LeRaw49ikgiA%XUWW9q+aM9Cob)`_S{WLN2^0KaQ)UIoS+Bvp;So>+ZAFmtA6GDW>v^ zI)Ax|Qi8S=Z@YD`&5v6>29KhP8Fd9zmMgQjC5zmBcYSMUwV6 zT$+~|3Hoh!6lsFBZz$7{pgtzdp&d zL|v%e$p^VU$a{MUq5n>!+dX9Qd{&4lXy(YktOHQhLVGV4$IW=T9G zB{1$CU$cuawK7|Ptl`s#CMB34-!)&cr6G{Vs=ev7^Q4Q6AbVg>YPP%R1yckmlVB;J zp8S=j0#5smBAEm)5Z%!;E3p8bzX+ag#td;nLd&RRsv#a#uYYu^Yt=dy1Xto20bdi} zM1juVWLb0$^iW0{cJC7W5IngqO-g!(wpt3k)){mg>6l

N!o)W7mvZk2*6QKqz-6 z_KX$oJh)?X6(qOw zAv0%9fCwdB%L;TnqaL23dllBP8q-jsfBJA{3be_l z8QE>l0o1#6sM=64IX)4k8{*UBA=X#|hMIDushL43MWcFU2KaOaAVvsoBwzXKQ;P}h zHFrG9sh-)o&)8@AuJWZ=0_D3ObdG2H4_=0-rS>#Ql^X34l&bEg+>me8BL;64AIg_q zkm$FT4a}oMP4Y3x&BK>Y*q_RAOjoVtF&9nN8CT1D1J*e=y9u z=b+$q&+1ozolcTIi6iYbyg^LcW3)fMy*O zU#YM7#~6fEuOIqW-PvS?uSnGElPq)zN>!WK97Me8l1`<+q`}gm0i|7OogML|u7YWF z;-se0s)iqY%&QN}2x9g-S~`X_9>b-$4z)c?Tsr(|8`HH?`_kRXtTByxlvZvqUeef0 z(0}!^hDs^L{ZCzV+C;s_S@#6AQ_n$eKEolCpNByU^8evp>0Xc7o+z@Wnk)*_51MFH zXt6q$@bEWt^@rTXA}@Vp$wV5l?lPQ;oxShyo+khk$VfZCzTW=*I0l;05jxJAx_%MXdbB7I~^nxJq!ShCB<9&OhaPY=r0*`wYv&p$xN^a)Zt_P zs*JrS3RV!|Q)Y9Oi^lDbJZAa`Zg-_K!V17j+gdDVWb)B+v6uM`N`paa!L?`vhl8Z) zX|ApM3%K(8zgZ)jSy{WBvyScNm()|7yrnl2K)?H8l>W~u?oJjEx=z*mIo+L zn9^oXO_+oZRWrnk;(jm7_9&H76Ihc8nc}70O^m@W3JdP}JdAii57+`ioz>xE&EGZ8 zGY-{pNk?k+jO7CDckCm*=*tzS^Q;`ef8dQ8gvbb4!+@tsAt#%l(;ccBXl8~RtH5bP zb9DufoX{DPVacb;-D)i-u%w)pu`dxV9(nTwj&TL<;dj&vQN%@37x}zr^_Mf;SIXBJ z>ok-TZoPpb_b6UUjTgzj3hdG`+=6AQGl|V@+KUle;aDGk7o|p7yiex0 z{Df$BcqM70jIN}e?F^4;Otv>hRlCa;;=JUMpnEr~^$QsUE@XXAQ}xr=ei{b0mND`H zVV3SBtM)XX_tRKeLGXa)o01A1`(uTipmqV`#g&s=WjX&K{N^rl1nQB7=p zXoqcIx#5vbUDA9B$5vZYGf3Od zAH3zu=FZr{v<)%j+d{2+hxnxv3EhaJ$crCTt#Hk&Z&UPwBl;lQxL&lKJOZYf)5L^E)Zt1 zv|NN{D+rdzh4t~6Tu%c~T}CN)n83OAjD8`51DTbfX`?$6h!cOqar4(^4IE_H3(s6p zVx{X4Mu8lrZ4Wd3v7bR^vyhG0CfX{Bv<@~u@`4AT6x7|hE6VzBxOccvR}UKBLV3&Y zIP~B>j0;r3_jXDz1oUou-#$g9Uo#(0mr~{xyB*S9YLR&Q84}WQ+!TPYd9zHvUg9cO z$z#+*q>+vo*q+DGcJZiEIS?Bpzlud3MG}yDFwQW85o1A~J;(b6ikorYpnjy$(VAhU z4m&mqOAN*E4xdF1$>EafmlZs&>W--Lm*O4n+66A&kHFW`GhrIN96Bkh} zh&7&2hECZ)^j>2t;dSa*%ccfi$z-%%S#RqFmqwmyR0lP7sKQbI&x1tR4~>0cG$$IO zOwVG^od&KM5>H%16)|I^8M?Hi5PDM1Yh^+KMF_nBQIA3EvuZzH91%n&MMT=O1WbQv zW49ZS7B^y$FdsRfc8OSvVhxRFm>am`y|LIvoAIMcD(tex6r-jUWsCf5QvFEbQ1$;1 z_ZDzfeBJ)=p$~oNmhL*Fpme85h=6p5NEs;I9J*7wLmH(U=|<@Wr9`^H|A6{Dzk2Td zzxVyz_Z=2kNzeBx*0Y6TIYID*duhq;1jy0SeBFXZkjbtfVPV1YDS)g@N0?#VU z#M>eALo^wlzq(Ce$=8SS8gqvA5gG3A9sMG@p*9uV@;mC0iL-gp1lMWr&PRD>xO~Q+ zQ_iSFz2Q@ryQ|bOMyLLzg6_hvOfLA5yYzfEvv{awyOg4`=u3&9w_H-AMW@g*o0*6x z@i|Kdn=IF$AE0$aTD((S`B+7-$xJqh-Wr=P%#4sGWlWng%loJ{(;;RIv378G>6gOr z87;2*Un$;~VicOr?=DaJ*lL!fqV;-}p;9P;T$1l4EQ?ESDnnth zhe@sbj4nn#^%PrXYDt_+yCByQuA#0a=RFePu6U%PqUZYbzMy7>)=W#DW+$PQeXgN` zt9-^TTZJ;MB|ESN(pEWYbt9#WQENo`OQ3vdy|sAA8Z45^m2qS0|7OL|-*}`Capk7O z^*Wf9X|Ld(Du|$s>#wdquF3b)pZrwCaBR%aD&I`E?(gtGlBS@RP`Z-VI)YAtjRVcC zOb$jDwM$)i8K3?jKq4a(2i5zzj5xDhC`9*i=^iQHmq_q~Ot60kgH(ugd<9Nq90xiy zZM<*K#dmfGIcBT8x4ziVw|CW%K-^^JfvaOk*)~echa~cTI(}Lk7@rDjO^R93LRc&* z@5pD3*lg*DBHD^g)bVrT#TJG3$0|}9h zDKEmzYDUck9b+%iydgNKDA&NKcLzG-zG`TiY+dg+wWgAFOja{@K@ysSkm4stD*ZGD zJ&kUXe{+pE5uGS5CA43Z>Ajy2SW!i(d6qu2j8iVtL`Kax)<@UegwpVX_>1PcF(o_0 zAdxSj%(Y>-U51sEhQ3FdZ)D3g4D*OfuaG9&SI)4lc_a>;os2NC7y$D}Hjz38jz|Pg zq_aL(uV;U{R2!syf`Sp762hU3k$SffNB;?uGsP3z@`Lj}l?uE8!d1mESAp!FmDauR zyXwjKeUYu5ce{H@UUuQn;Kp|IAexIiE8wKl8w^v<0AEbtQtQAR^qwjO`jWYlL@DPa zwu%wI%OW2wN;9I?J)NYSpf7=6eTU5u%89Z>>6#6n8A?bAXZ|Ykc@8!WVq!DmJ!=#4 zii1HbYUOvB?@%0Rwf5z79yh33=&AKOTIcDtcMsd?H4t`;MiNp$RoJ}uGoMsm_>cIx z?|y8X*@?=pI-#@Y5c_Jf)R}DIJ-w8752)9g@%0v-S+n)l|I1Xpy?vducXS*fTs~_?D>N> zRte;ZmtL6=;8yUt@_5}FYgOP=HAz`|R+U7*Xlt$QS;_aJ?ZdmlX)gLtwh#72Uizwq zgN>7O`XuVsm+*q08q>*JVT{@4NB~P@P?h2e=INbI;Z&7-Fe@>`q*p@M>bW-24(1&F z2xKt=@JV$^SSG&cW-8?9u42z{0~2_Jhn7*|W$`mqt#7h2Us$9JJ_q3C zc^y+1(q{2g`!$d6B#NN4oKhkzx?+3n{*QxY8b?ug$7pOxrtD~3uT}Z$_Z93XWdBtz zQQENVx)>-dq>kI&6LD;Pc0F7Rbw0FB*ihb1mU09Hmtew}T6<`&$Lyh!H#)Wv7uuA% zAT4zGtU0T^>(kgKtp(zG$9L(p8QhOw5$5doKFwp8P41A!=J_+iH!W;&I^aPjUu4OR zr8JVhVIoh&t9_U>=O>^0#y;Caz^JqimNs(6LhOhKM^rBa#|S!#}BHW3D0TS-1K{Q^ zBtd@a`I9?!r9o0Va@+pfv9{zeTwHm3TZ1~haL);u4pY~Z=jWkFW8$#{nR!M+>L4qE z)tb!SN-cN)ZMnxxj5+Do$ycfgv@JG~q!dmh{Ll>(V+(Z2`(_qL_uSY;QY>dSz8z{_ zr*=_3R>>;!33TL-k0Rl!oWt5HHH-Klf!bAbSop|1H)u5Tf%^9y4uOhK?@bB=?D--? zo|iu5#`e0;9{Smd$;Cds1{)=4P{l)*eQ@ymz38xKhjLvxO>*>=Qwp}9<@Gcr7SSs9|VJv_jh zn~9?o+UAPVib*sLk!Cf0>YZPLOOik)|1=|Un~tyv->S_>`jj8(Lsu8zAN`|z@}WnB z?3IR<`$)3~&Eq`9&+$lrkM11C;nZl#M^>}52J)%3>u*V}#n$wfP`u7$ygx=N69aRm zo0WDk|2MlUSJG(pMVE#jplS0cT}E@gGr9Jwb_Ll>FvXKrIf*k$U{>(V1r4zCslVD2 z&7hRXZThbt`tBuCn(3?d_U?rBAx{+fm-$%&(!s}p7T-x*W@~F7)(DbJ;<%Fh0r6+N z=;sKX2B8UuZ8OE1MSBzS?G0dwr6LZG9*u`SO{gwxH_5J?IeT8;KeVbz85<;bsLZVR z`S2OhJLYnjjk}Y|Y_?&uv-XaUoY-pL9Bc)Z+t{VBJ-)|(`cum+_B4GheKEc6Cw5|{ z6nXF~FA5&q@h=jBrit%)EJsBahOu$2o_B;D1kp0IqFc9fbUMg2`mWm!#|$MeTIm?F z$Y>nMs>&4kmWs_2`8v#&eD>mddfRbbJap3l ztJ;3t4ulsvYpred7B9Gy{Zjf0pW65zf5N?5+4s|UryIE4zO&&433c>$ED4%iU@Z}U zPdzU#5M=ZgrijTqEcU2r&^toPqk(a;VwG!pC=t(W84*(-?GGkU$xq+iQi z=9ygf4eeN=e^t{i@B;)+wuwn|7*`t}4#zCIrZF8!%rGY|46x*2_!973=V_CF5!f`% zZr)K}EyGhg&*_+X3A2xhRpjNQxh~=vB$HqasrBlE6MiSwC=qSphtpN<4@zMeuPR72 za66o*uV&}~19<21ksP5_vlp#QjArstCS`ts@#Q(fZ5?uMoix9m$CA=g-&1+aT9ejD z#m(P4$M9S=@$92PZfWq_Kuq>hvM1 z3O=WVlrh$tYl5^ClhaUf;WMc<>2U&wo`6JdSF=wvM0bJ~GdMz_Xlbl4g#58iHpW}l zR2V#xE{h;9RL-oaKw4KQn5qniV0y+=@`OWG&&oemDRY}X^}eckwovzD9bGFoUxP^2 z$tO~(uGrH`DFN)?vEgxNJugP5Mx`g*lMI0A{a?o2pGVPuj9F|5!)jRHlH>RCCuG$p zzkd4tbBKn4o@LY#yTU#H0)=-n9utVl3sA4#vsJO30GcRlzp-``et;rTWX!*rHkt8#m zQ(iJ#xyw`6q&S)pEVM|PSiQ!UBeiAuILKz}?=)Efua@vC%yKN+{uCR6Fv`k=xCe*}4JCL|3TSzP93F zoj*Vy$8WUn`K=n>y4A&Q`2SAf%>1dGo5w;$qA?d=pR;j&UC$e-JXG)YKUbu+Ul<#1 z&OJG|y|KB3vm_~v__NRryQW>aF`yEkg*eAj8&SjMk;+%!5DO`ITF?r|yF_dYGw zN7=~d9b*Tp&5o^a6SuTK!&INiZJ&6ow3RL1h)PT1N}wbdL)96&I9(~ji-=2T(N+>X zyuDjaI78_tFMy$iaOO1`piJ9DEe{#HGMXAJ(v$IBbh?`#lkwjEZgwTCKT6t{jp-G> ze#IxYQ_Q=eRYrt-1`EjO9GaGH;pVX+CeMm4KMIT11sAG+zqfHEY=R!8cX39xu2e{R zFuTgq^ff0>w_{)ClA5eHJK&ToH!<7%+iGj#9m}obn^~2#ZjhJj7Pra=y6klC)~oNV z;$3dNjCJ(TknGd-MjUEUC-kVVB};HM^(@4W)ziGM1@JC|zJ&}Hf6=NQu_<`)#+=uH zs#slN2C=zA{}MeSwpa85`-B@VulSf4eY{b-q;vV?18d8(CGZ*(E z2Q4Y-36+g=JMS>WtNx2=&)6N?I^mt`xD++;1!Q{f#Gl%KpVPtw&U*e~qNkusrYilI z(N@t|568OHhY?=9a8h<&5&d==zg#_{3wi^b#r?&yEM=Is!mCP<#3CZhE$w9 zVa>W&J8dcZtD;znA%ZNEup_`^hDSN-k_!@ky^6uYXZu4%S{u$5UxHC)Prua6>m{`j z5-?5!c%kQXS*ir(&DmDo5v#gNPTA36{J0MPxsIE8+L+a06!q2yqfFk&ll9%}pl;uD zMVYimMjj7tURm929A&`F@@5Mj0p^=G8|vquIW#mce5HPFdd9z#XlNLJfF9iYe{~o7 zulvpaa32c~Og9dfp+t}QIa#>{NRZoD=lMlcv+yB1)Y^Uqbgs`@NYxqk9J5+3V7X<$ zsFU%V<#Z@{7rf8qeb6@QPv&8NkV;T0(%xA#evhofG=iq43lT7k^0I=BQMn;PN|KU+ ztEI#vinot@U}0`Yx^!b;Q~HE5Hg$m-H7F5`IwonPe`>g|H=IQg^o9*myF%^)TjUq* z2?eqAK}L67uKZiCS0+82>fFD3m+uZw*rYjlC>I3d)k+b&(wcoITP2Q&Kv7VB-rDK7 zLeRZ2ZJ_o-&pdE?PyUqUN=HY@vN)Xf^&Resfr~b{Sleie!z~TqLkbCw4r*{9%zaPv zT=NQf9Wu7SzzqX1^N;O(1(!CC&3 z+`?}k4>Wa}SpeM(e{sWne9H|0ZpgR+Kl1{!8QHxFW}EFS>-)b+ekb(%O~E1^5i70q zpY1G+c!n6 zH{Rv|#Q_M}f8~7}`5E~j{SAQS0+rqUS;&hKX}@hqoKf(WzH(Vm_LRZP$Frq922suQ z?h2Q&XRP~=SO52;7qKVCeex+&U)Q;!c2z#_YS;}A-g7$tYPQtsW^o;yFw}BoVjmMk ztjEhAPV<$5pGM{L_w%mv$?I#dP=;kISVv&dT}JBLoHDbs*`57N(%@{J>=}M$?b?J) zT#AA7N&WZkL|f!Bn*H~>hd47-YtgwdKfsc+9Bot3uR8qf>~WBwruf=)^b10?a8Fqt z=w4ShZ&7YhKLrf+stV=%r|?zQde*|Vs>n}jW`h&lkArNNeDU#9T;b<%mGKF5bxUi# zrgn-*D9Z0qWv-tF$I`jpZxnU`Ovbs;rXglw_ZBHUiaLh)q1Q+1F9btfAT8mWjHQYDxLao9MhQRy$CTXkaF=Ug< zFOjmL(LJ`X$4=dnsnu}+S!jH<0jcB~HFZ`ZSVCEv!!-Y*QE+X2};XH%Ek*RRGr?u(`z z-lhRem1l{U-+!_E!sOXD|1lo`ecVuHD$V?yl=wW&%f0&1A2w}+tLE*&o#LIs!p;7F zZ$lxJ4lsNoz~=K05Ma>{0|5>M4;TRifglG%LjV6z=YOuZQwZ86RMw6G{VS2*qyPfn zV%x+1TtX=CLH}*mpwLRm>j^gA-|gbwdMf(e?eM_$dO!Rp7QFQ5+DB1&X^@C-id`Sy zc)(BGwekzwivai@w8*oGF(S2e{{!4Uz8+k>7y3getje$zC4(u2{6H@A3e+ z2X?(sa{LYco%d(ie~HuZkGa34{xf7q_!sk^oAQ?uZm|Mmg9zPBQ9a*(m9XOB);HjC za#hh~2J}Z6iqiWh9?AKc(f@?yknIhIsXAe({KSfIifU+%%^>7>Nxu-<9}=NxXAs;- zeZmy?57;)RA)!wunvz%o=}hbq_KfSZLQx%TRa-)`?LwDh*g^-`LY^T42O+!{SiCFW zn=X_D+Gj;BHlZs(U$sbLKwCGfCNT51W@=|6C5^R(kSoFiwya<_ zI5}QyhaVuyBRe}Plin7HdfD49wI;Niim}P5rSqxUF{qWZaHE4%jiEh(LBMHuFLoIs zgwsh*twg?$$;Z)A!sg6*nIB(=0a`)MgsjpU1MO)8o3fx;!FlX-pEd>NICK|6eb)MpmWLXhyHbdxrao5hX-#0 zJ!p^!BSZ*OwpXY^kn*R&m$D{jkR@bj3mjW3AoGyGQ~Op7s3Zmi=(YCWuQqiLTG)Ui z00ss*2$709gl5nRWqnilP(AaboD?E?85UyXO})Y-p8mvZ-U1n+#LI)fZ_t2Kfd#;p zZ@#xQAx+4kf|Hg*xcjs!V$oza6I&r)O^oj5_zek*8%M>>=pE8mVMk)+|9UGQy^NV! zJ|xsG5;eIM5 zemis*4l%=P<=Jh;1VPqT^?ej(6RNTgaer0Z-f*1uRB}iN>O;Qh2d3>OHi1FQTBwYA z=uAQcD#F0_Tq}UDog1m+0RaKc7An+U!n=Z5){ZH#f(>1{6`@l7)ziAy+xI&o#CTpt zS|PoCWO~*EQNd5GT>05#zUvPPcQo}i`|%ZnmZ#um6@`h9_dZ?RHophW84i+ki6@ z4kVDrqBs{$62pFUWdx5VJOR8Ai3(;jPgCBxIm}Ga?NF$;0M87FmQ47#!Ihhv@$PRh zouZ$;93)bW$BSZ9p3evb68_M5G9oXqdS`3@Mrx+NTs*iSmOoRtRD_z_LVtkd2_dMJ zP#>i*d{@jULbC!oBY)mQh*jzhn5!#<_aFq?jwR5JadR2jZfk^!+DbG!azrz`%h+1YrYMJ`@5EwyH7FJ*8}c@qeLy1^T&f4aVG9lkp;V@MQCr zql)UgLH#6xGGs6gS`xEigxrGO*zczP%-tUs8oRwB_F+K}*!F&18WDx|krRG0L?iR! zq6E{oBfYkpC-i5*h>B}FDS;Gg*t5X{P8s>DD2S^=1!Q4Y^W$hT;T|~sa41dEW z4Aa|BrqZAlwq`uIY3U8oU9+9Q#%^k1x=}i}L<5Za-(euosv>j{0spTderss>cCJVQde)(Q#WqJ*M~4cGU9 z2ETH5CGkM$R8F@%55+*-S3(VF5dx3?iaoe9?$}3++ef|&%muoB20zlwkKxn03XeH!#72UtP;4ddO5WVZVC($>r znAN}G2&+u?Cm$Mb_P(gw9h&=%?fb(~`AacfLVFy-1PKm}W3okI80AkW(jV&$%d;EL z{KgImjbTIoE##lY-hW$1c5b{uDW z5Y<$@AY%4|hEfYSe}7Jm_;{)?X-_@xLr7-YT= z1QdZ0jBzj|!VQE6762eGps#<5)D9%w5NW!K7s{`&FqqvNu_84=^z%ibPjPz5qZd)& z!ZwB6B=iNLeHpb^Jl`or=jV9i`+o65?XA$9eq&K3ypeIdi8CcPKv-UuYQy2tn{$kzp8m0FwQbL68ardb$V#rO1Im*t{UnLr*}(NCQI#4>%3| z5u@PAsicJktcXf~@e4U({|o!8IlH%62tz^_Hv#gWCGU4(EDZ@cg!5POlW3lLsQ-rl zuJ;%A@6j72AO16!t!(&Fjc^dzAFyLLVF4d7H-gGPm#`~=0rkd!z=I{hpo1ZvKc2X^ zb+MtxK4*6OJ63=eC>de41!{#lUu>*zN9Sa)7;_SkN>-d>_RdYE_#%7pJsi2Y={)n!#djFx_ohao>x=Kj|9yMI|HE<4{#5L0Re8wfT@x{7)|j8%Rc$=`~ihIry{=B8av;DY4-JKDHe@+zACU)V;x8?4|(NX^Os@0bc8tk7;d z{@9=ZaB~j0_^#&^+T+{%t*~raw@PZ)u1*%*Zprwc4jfS0{}%+fw_w4!d9sBJhX@b< z%ew{O-U32J4dpTt6Mv{`=#XLWpZjGCYnC^p3MqG~@(AJd{6SL#Se zPzb$`*w`o(&En#QHkqs@hy`~xM$9s)EcY#;XwR}{X)YE9&JyGKV~`H+%#wAdCG9sJGBTuO8kh6sb~?h6_7py( z*NP(C$$X%qt`eD59{%=VD%DJdZLkoPnlM|#l0#ZQ`5q+E(HB*xvHXjAO`@V7vwp8m zT&s=HwIofx0_<*qq?T;r*VkXL5ryucJ7fyjsS4re;3)7LsKv9XdNWDj`d}_LlFUO> zpLi37NT_~aj7U%lh4}X6&$zBB8pl>V8URa}phlV97^*`1hD4k-AGk>#<4$lMKxcQqe4mRMFl{mlv=Syy$y)wm z?<#>U`Wc>$Bxh^AK}km&`n{8dR8H^Oly9Y3>^X_7KA4YtjhzjiYR}j7AAnU{4P>4u za?95YN;?);<$R2(QCpmH%&R(%k7__I7di^si`yh|R9kHp*h_yr%1<~tmvuL9@a68^ z^#0tMdyEH*vya2Md93}c?IE$@1?d&)FRJq!-K%yf9zsa*=_=MY4aPJ9kz=WPqe%Fy?p3b1N~9GFBQ8Z*0q@7CCsPpY<}ptb^h z5e4*M4rl7PcT`iBz+^W=S2Q#|YKG;L z8UVjA2+8(K!>{Z`+~b%zk9*V%7?wLax6$5mlVP+LGdtA06PgNPEUR{}MmapYWSOV{ zX0;&1ixp;tzQZZNJ?~2YzQJ3vY3+v#bwYPoS^Fy+`ex@Jy-(dd;g^7TYe@i&L15vmGTm%q{t><;1azH^cu{eIdd#mz>0Q5GHLiuJ+U*N4bLUBJ7muT> zT*Fu;#V=-#9sNFTA*@Q3lE|HXrXKczBCZ3Z$)4C#i;sea|4)+(Cc+7+B2pHa$qD5dF3Pxp5(; zCTE}&N4}B-Cb0eo^{^B>^obklE?KzIH>EhtYw3YKJFj|;`E~h%hjpJ6Gb&;-nHASE zA->BJ5D9R8b#0jxu7=bWG{Lt`J{Xg4N$)Ox-G*XYHUHQPb;pX>iaP$@z6^FO-)<%0 z-Q2`LWnq7DjZTS|cOPIXY36k8KV^pcF_%rfY>k*dM~!)VXLi^Zm+CV$n7(F&cSoc{ zBapW2BqidBdCtd?CI)J-%(DlK!EUI@E#C(mqM>VslFgd5LFPV(2A6A$ zC@=&C1t$dssl^iACAi(NB3)>tuEUaN{A218nqkJ{X^f`rM>(hV34hk5cuHT4-y~sP z6X7Sg)AZw@CMLpsSKr*Ze1{hYt2S-xbqR0F;ehPf&*7~($AjOhhhpdr@Z4>g)>baP@tM7raQFn9U^)={sBY%6Mlgb_83Ippnkn0ZXCYw+W1Jg%h;sRK&d zw(+vl&()y;zCv6x;8|*}3w*yMl26!&!kzAN6V2?4iVpZ$q<5(Kiba@CpV=@wDCWlV z#bdj2D@T@RIVwgQ^KVWne0y`D#?e(zbs9&Bc84e-kX!8Dnq##F-dQli4ACR+wpq1! zjO}8^bG1Do4q_Ed_-Ahp+aO69(Bbz?P3(N-Gtk864UYman{wmV^O8|J`36bWo}px4 zlI-055K_Jcm2>vdlA;z&i;B${0NV!MXI&wr+_6k$md%WL+7OP4*CinXjUp;9J3ajC zGDr?}W@oMF3^1L9xw(-QO0`EzwMGZPq$;EqW7q3p09N9afTT+9P#Z>jpUSzDnhZ!j zS2?Xs{Bm^k*H4Lm9#{r{W$$;jTE=*7oy$pT7gi;1E8t`uYWn9~}&FUnAH390U*MxB#gj{Az;MzBL4E!DsaSVA`&!P90 z1k@xtz2IleT;6EnG<65tvQNb>#Njo&AA7?-(3TNxpk~@BDT^+TvN(S8q2PqUvsPi4#8}HzXkcL{bj`kkEv=HTe<5?^4I?_bDBopfcS)+P~ONk&GozmcL8pW1XbP)#oMg23y&_A3TX zlf+9Vsn4)6J1?mKWB7quj|wXGu)K9-2~gz!cIyVr zeb2zigQ9yV)32|<64T*`mkq!EE-w!+$ASOf@&CQwOJMt1`Yhm!UH|WY94XX#;oDaz z*HjnbqFLXCxN{U@Su_gN{>MKmA5Jbr#V>J()<1io>Znp7B?{7# zZ8ZtR{s5(As%x`P9lW_NtvNUsIcVQJD=&6(xs>d zA~$`7j#=BdTrK9E)a8s&BYj0_w{(@3ew8)Q6WP%U6_EDHo9452@MDKkUp^#$|8 zs*2jCM`F7;u8ZCuC7XlB;?$sWq6x1ep)K45R!AS z6}Lw`LRm@QBd~a!sbGKl(}wG`pS`dZ5%9pGz-Z7MP=9#HX)^S+hIOPq&=9d+n|5;T za_;e6c;nnHdu7xhhm@s`aaJ4+Tlm5BaMRqZ7Z@5wLE{M}OPS8a&T-aa4iReTsp}Z_ zKS20F?+T5%$?}P*WYN(dFt+Lyn;U7u*9GQ$1F>8rNxZXAfwgOL+whUT797G2DJyaj z3G73-FE{<}u*+igGui=&I{P^0C4ON}yk2CqZVkF&66w}OBaUYvoc@xPFM2Qh)T&fQmr)-Q&z^Cj16jtKVUT74m&dg6zMaL3&2@Py0y z)DjM8cv=b<)9l5%=DCy4z?HKnAB#Jx(UW?WOB*tya&&ufd||nJaNbY87`prHcq2Wx zgbi&WH+Kc1^O(%5f-D`&-)!PcTf0Ajo+Tx@JA*W81d=<%Yz=idPQBC#OQMR#%GRl; zv@N}UfO2)2TIgDKhmDgO6eu)t%#~V5jHD}K2gJRLBy6&U5OoiVsl+w!1(lD}zR6L9 z-3fvlYUm%bR`q;nyLEg`IdzUbecwAUEZ67jFr}cUESu&+lro7Y{F1?N8+!&xoRmt1vR?% z)~ssFG_j*WFgS^sh_)@dH zANNiCJWWo0eo6l+^-iLfCqkz6-RoUu&=yJh^JT>Jrv=s072e-Mso*_Ng~{v{_~{Wp zHLtxcl|12(o%rU~9B}OJ^8*BN>q;9rNu|6rm^t;ZSO--0?CUGa*GoS@omc;X#j<%l z{_>X^`T+{Q@W2L?=r`<$&`MrV!q;9q)o=k~8Yr*AlVzGdE8mMnJ*sRxR%$N0L|2LD zPU<27)wIgZ;RdxHz$#{&pA9&lx9;}tAd+{Qq?$KKG-kRR=crhl&paHDJl*t_gol*C z0g0tch7Aw$Em=3ad?bc6XHR5>>&as-g7|qP|Kch5wRhkABT2-|91;zACDS(2Zne-6 z?pj16;MR#&r|%q5Qr|La`3@X@*OOxb-yYJWN;dJ3iNw}OUY-}8g7@-~rozgQIk2oC zkg5UBG|54vbOH9YPF`ddEu)$rAhJbBas+8bi^2r{$I%Hh1zJ^fj|Hfkbu1S5Hj9m) zAX(2KwQ&}ARVYzXTyy3YVDzbi`Q2eyR(U}j+O`+mCLcpo^lE4h+LqZAfn}vTt&iz@ zbKDiVa>vzGoG&0-l_+0@ z_!>UFP9?D31a8LwGO9gp6_O;IcQ|p}oemy1r4eV`95@t}L+>85M|Cb8Iw*^_-04Lq zr(s~XXpKtqt&7$^FY#nhCK_D3*eEMkwdc}HZ09xwLA4AhSnG2eX7!|wIa@SAx4ec%(b2=OvlO=zWleGi^xe$O(!+*2Ee@L+@w&{wZ3vq61{ zF%{fv_hd?Q{SBkYIuSRE&m3djrHZ+dKQ%$T5peO#G6KJVl068_#da9*Ev@|sa^V6A zEP~Y_$}KEg+{%l5kXZ9P-+P*BtL7mpm_?sAMSl&qeP7U$4x`fr?C2lOUMu z(ul+;ee9n?H9IPB{I_@=*u3)Gjb?Ng&AF+VnfUITXtEPE^K};3>BuRV+%#1x;E~Up@EK%!b zCwF34;4+Gm5I~1^}NI-Tuub2;2czBP8 zrE?vMu@jmfL>zL#^WuX5c8GdnE28S|paehShsk3fSWA=F43A%gSg*J;e^{p4hI+Lz zYTR}z{gDMxaji$mT3S@}S|*An+*o`A%qAv^6f zLGcHk4fc>0grKghf#Zdni^oPm=fIZ49UiRy{x{2&NW--&+QW}?SzrpG8~007XeVFK zbE<1?WFI%>HD@{jM%Q?Lww>ye5km*^l9PIq+kEoLP@UV@&fy%|#YbbL+JZX=miYmL zJQ{QRPG25ntq>x;h|@y0_3m;$cl7D)>Fx_yWn}DOGGfFt;nE=fiA{TckvAhOKEWb? ztRmWH|B4q0B!5hgB{V5go2a0tc%OSZE?WM8m!UN>uU|y0V#$zrO}z1$OIr1@LRJ7m z9e!rgS-}C%50C=6wU)f9Bs&964IiUvy~T{k)QL)+ThrSUm8N^U$Q4t=jPKnlchXGP zgL!;?jNy3AKNYW!+mC@Y29^TfY&A`rH&tDK1gy#{T;W%wZB%cltY3I|RA9k+?5|4G z6ERE)tIWU>Z1a1;hvOQ(_|1l8^rX)Xy0&WAVs>GY?13%sdm+k(#q-Bp2`=Tz^ES>1 zF|`!C2pugrlW${@XdFWySFw%5la!PAfWAE2(IO7YE;M~*{N~v2Z7nt zF+n|JEQJrKxv zpx(6pv@d0-=8pnp5$k>TD36&Jfpuroxyv|*Dt7|i4bE|#;TJ-oy=jtC)B0(O0@1G! zY~Eo?f%14%rF{I+Uj%c|ec-byL5{`B)<&y-lYAj7ED0&*I@d&o>tRGBw4t$-H>1%- zrqi#e7p1}MJ%lRh-VgZJ3P*{HuCK4XpY{zJ7ank4jDbM%&hrWPTz1SBQ+drj;NcZT zk9<8E&&9o~h4k=(%`R#|;as)yVnteB84+yR&%o!dkKikbE@VDj=5VXo2sRa*Xdjcz zo}~;W&Yq<*He6s3l4Rm5_h{F%Rp_t9<}TY;K4hKOUYk_G9VG&LnMBlmEbH||Kfry9 zfr$?q<-ZSyaJA?YsYLuT2=QH>-JMY{*5|T>1n{2z726N#? z2P#r1u9jh8U2tn&;zM3%+%)wZa(!vQ11CrjdDN^owiP8Z6ivsY=grLcsNn@ez?>2; z4~kdL7xXhjJwf7qD2kR#pAXW2*JIc2kCDN5mZ8TUrBl~PLz&5tmd>Lw#IHDNwF*RV z@WFSq=ub3!^4{KoDJnT%Jy9U0bsT>ul_01515{Z$w=O$=#mQw*_x$7c49?G2;Lr|5 zXB64M-SSyHs?|qjn#kLIs-QasfgNN7VYIT~j*`7C-|qsvNrDS(hIfuq3)Ejbi^JKx zbEm;vZgZkS6}^+>@UeP3K}ko@2#;VJXZcI+@KmFZvD6FFkFe92dJbdl4Nns4=n0$P z=vM`g%J_bO@}*HWTdw5NyO*Q=F(5et!)$j9dn^WDe;qm9GWVhdxQ~= z+%uGlhi2|_rMr;{5%&pD)LSKPI{J~u$kDPwn);{JX1y3P8Y-}(4Z$-x6dY=sz{XP7TB=BgXeI$|#0 z8%Fq9--*lamlf_oUX0auMtU~l3%yn#@}ZB@>r-*hjn_8WX62Ri(tS=|P35;ME=8c9 zE?dS*P|tVgy|)yx)*P0OQh$edLMADCD=7+20fbiT>p&k9KGxX%%*^NGWM%SIZM%h^ z_=6ecKu)1?R-|yni>_j@k~ZYUb})qF?U9MtGk>@HLW7=%#NO|TYn@?}6h~d#y2i$c zdQHwYV>sQwSZwP;B(tDUr&$Dr9B}e2o%1nHzQP1Ak!r{X(HpQgraM&yV`oe=dfiA=?gnvLZ`ZLFKD?H{iVnX)ui-utHC`@*W6GjXatv z_H!u|QTmmcKs^_ekYh$w`6xo5=I#u9$HE8-)&2kuC3IAm7%>z!m27Kmzd;cDxytv* z^VAC8*VNh5h1cqnXR2a<_Gex@Q`#Q0d`ZoBCjtX-Lb%Iat&iviFM9hpQe-$;D*Kg( z%M|yMc-Tnhd6mU>JogiMjAjdyj3P0a3>trX`DrgsFNvK!8H>hnARbsqU(WVW6da%7@@V*CIh98bO?FP)JPI|n=uMv7QP*$VT27AQXMoA zOQ>Z<@|g4~@c|lb-0};E1*&yeYp5OR?e zoI!)>;)eCj76$c46B}cPD&N=Kla4Tz&NcIq&iiE&Mv6P$rPt|61m!qrd12ry=#5JZ zaA8fTj!PWCXOfjYgZG4GYata`k808@`=roFQypP?KFG+Y04Xb&+fiGLYL9~=u*uF2 zd1E=y5Cmh!!(3a&E#A1#D7kl6T2#r^X*%HU&*2LVOqvh zni%_)p*sy4SH4ZGr!|h(bKRD5DNH`LyV=G^oCVS}c_8IM7(d&mZ!F9@?cHAaqZOZC z$H>z94jm9+Xi|HgBvA7po+{y<%XnR@zY<4i`4ETCtDuzhaGsVXYa_jJlI5+0h}1u-Al`+&?hCSaw7JklI2wxDlYNv z+6q{sJ>!f54leoC+Ty&J=)G zH9XAeZ(eHgM1UYig74iIYe7Z`tk4-ANqqhUoiq^|wx?nJMh;XQmPLT4Q=%@Ixo!Ny zxU2&V;##+sTs(Roiw99xQrKha5TMO||8Sl`%DZEg3tcE8*jYv$H!Ab9#b;7D&te}p z2t&Dd935!%WP6zeo_;(14AtB_@Wo@SmwI(c9u|ahHSe{h`ISs!#Y3cY(318bamq?= zISGmL_;V?vF52p#<2dvXkX8+WUat%z4!KuH&e-psQR-}HcF~O2E;!~s@DtrAM z>xiCfeqzg08jkpVh50U(^WYQi$lwde82Fe`#o=w%Tqh=_rAJ##1tlK4?T&PA9^g(K zW)=CGIOiolJX7|jTO@~cwbey!qd|hZy9al7_n<+86)*0z zKq(|xaZdrE|zC zw~3H4PUDa*9^?GfEzUl6Ov84Mn!BcnRkwri+a1|Hr}G#rX{sYoDyeIVp>b9rDLn79BDUXnq?Xqo>kW(W zm)b2_;rboW^035qA=n6r4(R6Y#79<%xJahx0{&s);xFdft~m|9wZ zjKj4!E60doG-V-)Ubnu~Qp~FPd9pZMAo1<>qc*gIar^i_m{xM zI2GP{#!>7iG~J}cPw^;RaBByhnEe?4#*M>oP7i56XRKLf!<_}O>Z>Ey37}k*)GB2# z76a5XZE@G&jH#M1i_cEF8a|&Z=-h+LHin)+{ocil6Pd$2 z2!%+jy^i~P1AKG6`YPjss(^%TmUdRlvaghaz#;>CwB(fRa}NSZg{$c>2~(>j&({ZK z5YfEx6akKYxUOGO9JV@)=KcrZe+W{&UP|#!?1U9KK9Uo?L+Bn z8p&yM!rbdyekE5;&JAcAqM+`hsJb!$L8&qwjjY>7Y$q{H`P(9WLfCkeyV|s2`s{@` z>8FQn*&)y*>FnLN!@;ksZu`o3A#o%e(54C+_5=aJWi`uhV#EeIv2CJmhpkMpi3<;S zq#UK6_^aDKL#{CVqtBelpqRC4%Vlngd;NLpZYjliQaSSIGO1~kvX--2eVO8%j`_3V zoc3o%?>;H;xPJe?>BgwkA4B;bu`6OfqPkgoJ)aBP>y2JJ6jDwDht>PlRXYfZh~PD* zK;TD944-5PR+>XPe|K_#tw1;eS$!S?j0?$iH)*6~2}#s5$R4ahn50zK@Mn;5Nb5}L zi_RIk1g)=z%z6R|my<8hTK49%xC5AtP#$< zE}o^3_eN3(XyMV}aFV@|UahK!-^&|br#pkLz!}~Jg-ye$5SzVYU#4y&sYy_!l+g2n zn22DadM<(=NXv67PDzVOXMEm)-{3|puMqgLZiOy^r%;f3sKAWq8Cx#aIwvj7lPk86 zo(FcPd=sRY87vaZjPbGEcV>|hY{E}36G`{2ta_8p-u&_@}GMmf<(3Jn8c{NY>aXq*a za}?0vZ;Ds89zDo_(jwF>w50c+ip%T-@M9rY{sEv$Z9Mv%?QL8v>GG|uPbMMtG~xYu zG2S5uD^s3nF+p2^-gc66oFLtz0PCMU%9# zRf;s%7J)U*GNs;73aM0M+%`EHhZp4Pt$)toiZ#X)#z+&PPv3dJ0o)3v$#w3y8}_DMvadBi=jrpCtqoDi}_11Nt^K<2Ia zX(QNrp4*ZCJjrcUqv9x$V=9MrmxIdHlLYT3e?#QbocHfX*&(+vFfpqbt|+u59v&Z4 z?-z&_GC8nWqlv%$OlHfs1kAaf>%)JAzhjd1QNoD zd?vJasJ`t*x1>6aIH!pGNRy2q#u)f}OZqK0!J5F&M1A6=_~+6Frko9Xu~Fgfx*g%i zYVr`N=r%H%`L*3$jt()9_{-oIYIP+t82USwPI%ss`l3zK6;aH0*^X*G#|4_!d>&h- z1*9Q(((exh)jCa9uE_9?3c$*-uwYL!t-t`uQ0c0$08NX|{6i7X0cBkj+lfbZZ(E+2 z=h747^45nX7D~`A@Job2b@o?rx-nrj+c(;q7)3!j6K-FE&M5{71}m2?j&uVQvrDDp ztZRrr5lw%ZS{0;4R%abf#_YRdQ`8NI1xV#!WqVICPwR-#npRc>V{3k2_ZTeFI{su9 zT6k_VQ>G_H1O{|}>0Ipo@Fz)*JU+IJc8TQSbu8CTp!ml+?`sZ6w_WoMQFqT@_j4>s z(xa3*ujW4_RercjCTAhgDt%#86=e@tLK{HsUuA;CRxGm}M|^)*tP&{r{Z6o9Q|X{2 zPMKEZ^eh|S0rK0}_0}$QOlzV9Ahti^j3js}-=w-|Mw~3}ri2o1K~lS@Ld^`*2p%%) zl1JF{l@{&mA@l;lH;k|TbOPV@CVL-h%YQMWyWQz!zG8f`F^%;GMSK{|YFxgHxhf## zj=5&U4XZHuNrgXx#>B1VZ=r6)3@_^{R5UQm;#YWH`7$N-^-MZx0)G?>cgCcFO05Z) z-vs)bhHaWCL46J0Tkrcj_`< zDQ210$Qi|S91y9x?FTt*s^?k{J@t`ERvHfyBJ}^8WtOtlMhnQZe=8-*b4d6$Zqb_9 z&e$!$I+$@VSa-qQ9@~>P3k4|Dk6W9GYxC*ge69F4jIz@zx;I))*a|I(5y|>xwVy{q zyvlMbe*=0T-a+B3RZ<~(EmqU;rAq%ntwp2qvFc?q{o6qLGz0MQ;Mel!WCS|OOxkSS zoO^LJ;V`Wu9QjI@bxRj_e)PDj2MNAbWlK_NHo<6+vv2r*#Q8+#=YQ@Sc&c$icE6D8>-7rFn2Y{Mdkn#QVr-xdEw`jXYA zhaKi)ovZSWavsc?>)u9*@O8X%R7HZYz{8jjEhV1E{e(WVO8r3s$AMniiH|p7HM2bi zc`Q?7xoo!_zBz7E?@!w+^Uy()a_uv?5b?_x+uD&H7#?j{lLUW$5$6rz4^>`VCjs#_ z^X4z)kvNWBZ=~FX#@O6jX*f_6^cc)>Kb_hxjo2=yn>fvNRUT!0Oh!5;g>iY%+kCwe zIh&s&reEZVdC;=zvDS!^E{cw2qB4BG4tzJ1`i>LF&s&Qk)kp{=4xxPVT~f4kR{sUJ z1U3mtD{rs~htvv+(2Etek}E`=4A=_aMdOzV@KEOHkv|1?}mL0W$Rm{ox&mvCYAIT!}$KNu#)M_8zIu5>KsXc zY*M zyEjHqW<}W{)!d*oVpB4eRr`dCnW)2(oFsoK6b2gCoE|W^DINI*jJ#g_&6cG);6=$dwcTrVbH{+MK0HJ+$ z`M~6dUU7D}o>HRH;;O(cA^4~~5go|RMk|fm#sIG|`m%h7c?2)XI@ZObVJhM=yyFD; zGSxs~HB~ohwE;n_SCFihb%QPfux*PnjC(hM;zi^z=*VOSRrEVL>%<4m=z-?}e~5I(H!r zF|5PNK0RZ|e!g`|ZlcKVhNK-PkiYJPk|AVwnJ^Q(8MQc0Q5dkE=YN7XCL?sJ780Z` zdcFYq!y#+uk)Mzw zn%=5QjV5}Dc^!W)3nJBK(Ysy>oX~Oh>+Bn8xK4VufhNYLm<$h;&QGLfv_xx@Q==6M zXn%gn!n8IuyvT2+ylk8cP}8?e+AaEglb%`K*vUp5G5vAXz0Q|=HQ~pJra6`->#?>y>>rTI&NxV+N2Gxlj zS9f-H_A)-@zMMKrTsSvwRIhMAMz}1oAg!vo*=CNpIc-I2N9B`4u?LnRKT-R%xh^P3 z7wD2F#*Ua_CKjjdC7bD{M!e7#(>K3W#@6DU3TFKITzL0>OClY`?^q&p!?X_swxopw za^c7b9PH3|bH|*@s;3KO_ao+Ma8?D4B=>5E{4J>E2LYneH+lO+n=PImxD!eUJ=X(l z)tpxoJ`QmstJa`qVv0?^d~D`6y7IhZ83Ahy$N?(X_dQp=wpE9PhOTrX(HM*Bi}?mrJ4c;drN~M~P(1^k zcVJVOxtuf%%XrBTj}HjRdrnub7)pF0*Mb;IJt2#6^EHu^ zlT{>slaPn|qZ{d*Z5>!_>H3(D|J);_$_R}$FnIc^$KsSXKK@n&t%=ut#bDPU-MS{7 zXrtPX#Hx}sP{(0TV3SMLiM-_n$AnO`s90L7D$x<| z>oRzDZNs5?pN)-wnJv7Wd>Q}RAN6Bc@HBE(k4Y8cxevPutt^NjXAwjtcjAw~n!Q%$JFmG3 z;i#$`LB?mT{(sd5IosZLw)s`+#JrSN1*GK%{23V?WNu@};h!Kt%Q^V)4fN?IU{YJn zTeOj{a{2a`v-0cBeBrs(7 zr4Lshi8*v7aU}_lr94U#&L>pxNq;Z3{m@uo%$c{$i4*z<;0_snCp5EfmA9`n6tMM& z?m+|NAAoMg?Woir>*A6^?3F)l#H@u_Z?0TA?@-KNa&Qocv-i-TrsdI3l6T5!5k8dR zi6;cLWA);Q5^cnNC%O*u2L7aa*lXDE5uIyQu8$D-1HbhGdf#4n*a@$`$WBl~s~n0q zW&X+!d5wOqoS&5cjd#ZU7wYm?vfmH-glzoy3qXUTCm~(UKw0em+$Y_(SDMO_FspRLulu$!#A4!g;jFfI48ydjlPPRe*gk4 zrrxI8Z2k9gMn~rudcj@0G%sFm=L@S`u#b>oBx=`Vki8N?62} zXAVd6k}Qu#8HLhOab9JcUTuW-rJ)#`RenF9f*G)ub3P}<>K)RQg6Rh`N|Dcik%0uc zTzkMmjM zq-V6Rmu;dz=MIGg&Q#WNqMtr+dit{+VI{e%?o$@`!diJH;FxzU0|N7itbIhdO}zOT zA~xt=Sk3~RcM`OB+t?R$nj)CQC$sVZYypFANK(m+cQ?xDj>WMS<##~6%#S@`A zsSi6+1IA9cZ=|mL!QQd?W}<@0oA}sL6UyjN8TaOM6Jz?0$M`O zfOzSY(6qrQj&qL;y{3IkbDI94CE3wD&hYjW=Zg#vaaC{MY7tM(ips8_hl}(kh0Qs< zTtUTFzzR=)ctTSw4~J@KTjE+wqge$9G#Y1+*KXJg9n~C^dPiibf+gQ>buJK&y7P=ozo`h@mV># zQ%lK3s`{AqhL%&I7HrNJ`P9W}JzgW_Z&AePa~5!~;U0nDC(ZVV?U0kVT(hh-o&w~? zE80YFEDY#KVvT;80f?W8MNEvSGU&I9izpWMuB2lg$KGqkr+$M~C)MQ0Q2hPVv|E)S zwgQB10&r_+-cXb{x6d*@nWpTpF(O;Uu97|M=N}jo2m+Cyq%fME_ODAZ>CdkIfniz? zd6fcta(xM%L3v~%y_)JS*6@^C7`}Zxs?RlVm4zM1OvGh(HGxcb^Z8svse|YI4`371 z+4|({M3)ngS+I%#3ltU&qv zguMbAX{eErSleE{U==XtM9?FS`>Q7P5L}p^7#pV_E9!0D!}3aVm}1iyKZ1cx%itE% zg>BFop3akBRkpPIeOZa? zkqX+Lo4K$CO>JgQJko^|zOB7rtnRoKlB))i#gP;cDQ?w!b40Bq<{azbH93OrA+tU_ zcR-0%XGxvg=vz~|140II1UZ(|vN&dDwDG#iRUDr7KzredF+hAz>P*Futb!7h|kRc@Me<3SSqB0!OL&D zy=Rv&&<#G$;GJpC8~3-8XvR}7Vxu57IK;?;Q7kqt6#TcVGZ3$v#Jr6r$dHM}CRQ_^ zL%cJl>&D4}j4`8(f156KkkS1e86n{w?3*&%NSQ{8BeH8B(8lskmxai)0LM?*EyP|c zwWWrjyf;CPZF5*_ChxIcL*89vBuk!DiJI{K;!C^H;pJLG(r}B-+b31G=R~zHf2Zx% z{7enDc}YDNolPqKG0{zKznaKkW;S9jxc2-@dY&-P(Xf`f8+E}i^gAQ7P7|j?`&(cM z)##2hX|l_=RHS>7Pa8~pRn(`p)!gm3B33VTeWH3OcC8kPl1u<#uSxF z*gap;ZY4nOZj`t#Ft^Ea^0vY({jsw7XWR+}6}A?)%bY2?UhMwFHG82bK;i;GmlWts1|&+oI;!6?l^|@_}+6JNo~b=Atp}ccaK%$wcgxg>lwj83CF)< z(p zp2pAW)j8m#mNl*Y$%JCB`h6pNe#BvEpOndf#u(+OIq3fZcB|bMl)Mg&p9Drq=s^(z z3!{~D$Z3DfjFPWkx3Bve*R>+Zb94nSz!mIgx5m8C!U89m;&;}_BS=r~I5L0*v%Ftap5)jz>AHeg&x~Qbe+CzgXN5j&1_$xAKYVh+E z6%(IXnuSo_+Z=07^E!`H)7n$+lXGTw5*It>$zQm_K*p`oZ~Jms9*2hRuYS@0HSn?% zmVVNfccejPudPH-28|pcmOrNTDAR<-_r)hrSx*=kQ1fqfksGkpeqDE3(b%J;I|3>( zX|(T1dWvkP)oZRZ5;XRwGO1KKJEblL*K*m@^K(WlW9}Rna4a)H)#g>{ zOV$h*Mzd3y$~INp){WNjDKTw`CZ>-u#>&<>;`UF<9nO5+KY4(eM zpYgRd!T|4P`dn17he@5eFCW~Hxvw4dpN`A%ol6>BOMqUKub^>+ARg1X2iLg=S0XB^ zas0(*kZQDfuj-W`=BDu)96M0eSUk&1*rnZ?T%3Abfhp_8+cRS912B-=@ZN#u$ zW>Ed!T;a;Kujr!Y(g<+cf<9xbv0?0RND8XB|I%oEC0q?HkX>ixTrf3lY%+OL%Bnr` zFwd}Lt{y^7WfSmPomYg+l;dh2SG}R{(uM@_iokiIT-Fc(i?DaeszbVGSwEac)!$Pe zvUJ^^tPW!QrRE1lRMsZRp3cAp&xSRqX*%tQ%@PMZ7;o;f7InuCV}!7xYJN&Wdff%F zak-2a1Bma?uEHOdyh-v)Hl3p%5FUya*2E6I#683gr0Imnl>BL_u z;z({hItw3%C6^=e@`qdsqsrOqF>OAqPoPUf2Lrui{a0F)?{=us)V1w1yC(RFjF;2O z-X>F~k1`{c>|;-rB_qWYWwAE~Ag9N<%?Vl49y5OL1F=DK57<~0&GFV7D70(zOgg*m zE#(b@RJ_?Kv8qg~E1Q53oLoU$s;+K|6Lqj4VY@IbkmwrHX#BdGGPeAi6AizMowZKD zahZJmId&%GBl#anq6kTqH$nfB7VP@|%a_~h>MQBtfdSWe(oDR!p@TGHWTAWiX%x=h zLsM98rMg5O8Lt`AguA$mXkJtr_mGwzSp$B5*=ps;5rUR#Sbdj3-Q4g|!bR1a-y(cr z6>I3ZN+ZHq#h_UM|2zkc|@-nUUwGE z*=Q`O<(V!QyjUz(CcE?WYdV!3qR+eY*}(crN${~l7+Dd#Ko#$O<|Rw_bu1viVc-9m z0XevTwq9g2AT=VeV`~AGyAO{jc>fecL!35tNHQ&W*2f# zF{dgsd(vOvYn`RD=%M%?U&Df8_W!v{ZdRAn9qeMB5y+tM8^odI#d_NO3TSOh4R>D4 zFZ8Cxy?G29euL^ty=F$_V%Yrx1=I#m;ffroH^t9gei_e}6Wp!N+>QbbHM0Ng%YY{d z;ZsQeaBp0(m|-Tz4eHNBdk4gZlaUi27Fd@A!h<1pHnbjzA4Q*Ruwz#S@s!E38f$tC2FQ~ zRf4^%Oe(ANZ{9c4JCZkl2mo13GJIlta;cuxq!WY3zxRq7Cq#7wOPYA6k+YP&k)uz; z5#6Vns`}>r^10Esb0hS>TlH?Uy7bXp$@MBzVJxzUF*Jitt8>)|f#T76k_^5xV=DMf zbf;zRba@v~gsWr%gVC||Do!LhirHow!vIrK&P^!OGni=%PJv|=Bt$MHd6CpgqNKEq zBH(MquYQrJ45Zab!0`63s1>uAr|BmeAYNV=VxJICjR4_odBh-@+CN$Hmj%=+tnk$) z7rf36198uG9nSb9TR{@df$c;p-Cc)*5&XE?jCQSjPZBX0`C>$g4)EDdaQD{FZ$dI4u| zq)d=e^#0g@oirqZvrtg$=^qQFK?v|)CUtH0e`iwH^!)3TC7xhbzwR-p5uaH`1`F;( zXFKvO4LQJI5>RhUeO?jUap}2r#@*{VDLAV>f(~ggjZmtJFt2lX485zOzVeHBJ)(31 z(s|hcgOW6)iByZEUQZOP?@<2$Ofzv1xO3|0LfjVv_^t^*9MPjkA<_zP!_jJ?27a%} znD@u4_A^x=+{b6t*`&o?da{w>fkBwg=W#(f%dV?gW|6UedzURc8v}&fc*$@Adz{Db zdMmA~*`>%b?O(#`H4MVRjX-!6ugSFT_3(JR()(T;$$dc71!;OPmdR+N(JqY=xuoNCdj zdw}+Sq#T&NziWX!y#@Ou5|9K6^P_h9_){TYJrP)tVUHLbi-sEU)O||rwK_utExZ5y zG(PxquBh@e&SxS|pVr2R!91^oQ9b5Z^>02?18;M|(Toz}TR|qJ2_;L-c74(BdWYM> z@j z)eZk+=U*t*2k?L25BWd9Qz>zzebTrAvUS(R7>}bk+iOEPJ#}4GsqdR?Q7eFagrs0ZTv>E_+`luC+l}yJrLKgM#bd?W zO_Pu0fy=`SL1@HLWnXmLzsaqc2b;Onse3uN$zmQVa$D>`)KSBQG~9DLp8O0@7e0VF@wls}SiTmXyMXvm(Wt&$kY6t4CppGhlsU!fZZ1Sw5Wlo_Nb7 znmC?f?4I&!8#U4eDjzxB9Qxghnn z6emk(3{bZ1RYelt+Fmp^ALTQEA~A;oK>@5uqjpgY?$@}^5RK&!(V-s-O;Q&%COeVE8@Vzh zXD8s_Kf_WpZxyh9^{Bv$Cd&YD+|60vSzDydu>E)~*k`o~*gy=M@@5a;il3>Nk) zYNY~VS2ALy+8RQ=1W=H`(X@BXY;p2zrcDL*Zf|mT`a9M%Z6=n)a3n?Ei!KUj{iUWi z|4^Tm7bsZmVsMe@dCyx=Mk$NoF4=3)a(+=ok-{++G)yBJR~JWA7= z`feu#14?x(vgBNdjY8U{uGEbuFs$H%a^{?!1x?jF3|}HPtf?x?%PI5MkIj@O4r0}w z5ln0X5|z|B+#?@4x;e&tT~jFC49?lAH-eO&$$VWvWwZ)|S=$6AU7Ms0SdAfxUB%oc zE{|si!Xz<6DuM(nohY#Yo@CSh{8gHuNAuSOF}MPk8za0@lRK6Hx=zea#7fvfLHy*B zr-Dh6y|VC8>4#iHlNgKmH%Ph-t)jU~N7;PC5Z9n_7!k_;Nq)7nj|`=Soi5Yn+jKS! zIoR2xqr4Dy6vYSeGST51?3boc9TIM0F5Tk3`inXH=^CqtDY_|*w8vj&c}_G ze1-H#bA?n(;7&ZuaY99sH%8#S#m4N0&)b+u*D~0q^yfK~z8$PHGk@6VF7AA(yBV%N z8ZcjxWcL!x?TcH13B!uv@gJ&WJG5G78spReD9LlxiuYrc^A36JQz_uUO`$VX9E3RY z+=(XW_wmxS*h!;$Nrv38MJJAFQ1Vr?$Tya1yF{EViAb6`RSBF?8!`6e6+=tR1Z%_E zMuGAUKDL8G_x3+C4pVXoN)B0a)1-jkY=!0L4Zn-)#Iyg8ZP=}d z;x79x`yPDx|3y>Vf&ktg)?n9Qdn^jo8c;)uC>|Txq)L2%^Z4)1=8#lZ+s*(oH{r^Rwm~i(rbqu;S+h=j4hLuiyqvk(eNxipNW!P*yv6jui zUhbh3g0=D=x$OresRrBVzgpsUa6Ft!@G@nbhJl}J-)`gc{_J!27_6?Oplj~Js1-IA z#bi6&EM+Ver0L!T!<_k9e4@lE(Xje!k^umFB^hV1*`em7b`2>~Ugp!;& zSqF7Xrjf!wWWFi-#2g`w1%~aN@S11<3gmUw25+Ki-vV&1S3HRLGOkC}XvmWxy?Qtp6~Aq3`^9&3t%(Az^(UlVLJ`INOS_cj9839Ga;+iDPVZ&$a%2|}p9!p;chwXaw6{@?Kh1X(#OC;-%XBv|(?Vo|Ht4!fq z#)kXmRrnAf6R@dh)q-&s9NC3@bpcduQBIxH6#Q@jBViK@d|c5*OMGvbRKfd%SwiMc zdTyN`4U5gD{Ex(PnJ0bFhw?e~Rr#51tu!xd$=KMPfcz`%_o4hI8JavPNVa-LCZ-;0 zc?|D^UCt+N94$oT_?A!8^l>u1*2jY!v9Musy?Aw%88n-=mS@Vcl%Zyk2&=~1^2NTO z(Ov?!*~?aaDm`JzGXbG0iAYsR{~}_SExPAKNT=K-TK>M^52mMTZ`Rgg0`#eblCm^l z_RlG+YLiClD)@nE(to%$2Z=G7MwHrPBmrQ4!&l)aF-)! zsT0Fh#)_;h?F!@m2qhp120R_5ugzncb4@#dDthA?LOI9}3~o6@dt_WbPy$mu0^L1P zBgU>v=*9WdJWU~!;|YN~I}G=f0v^ST)ODfyJ~Wq#O8pGSp~!P{R~%yca`I6Rb?7X< zlC3yHv{6N3=R(PMw^2S4gJYd-3!4kv^1-p@wEfjz?#nf+0H%Dc_3^v~+(Spl1BQ#i z-b5M#<2h8#L&VHWPO~dt=%`C5He=A|ekv@AxyG`{Y5}k0r4jmsL1Zq7E{(`q-e1v< zzqGc8PT0?pWX9(Qx$8@!m+92`u8?^{w^35=KisOhv73zJA%TE_P3%0vPz{DL=aPJA zOJ|KKB#)Mu&mRzi_96}tLsG$`Qg@G@p;XHfKd{e!d`iq~8g{D_mxlA!M;^Ul;Xe>e zE>Yd|ASOo2v5U5hn}G5XZ%J3{zDgW#z}5GHR-W*(kkcO|%2I0J#HnEmDnK2cW@>l# zW(Rgp)CKx-XWR7#*e#G8V$4c^IiI$4QZ!kz&jVBmMpuw;Z zC0L1@RG1)|aB7?Q980!X`;*K8z*~nf%;2^%T_-6^GzO0>vH@*@s*&ThU@~9@5!>7* zs(YBhV{L(gwkqMXAjIBs<0ggStmY?&d4FPq=$u9FBR^oexBa%w%h66cao}Ms?w6x@ z#rRxRgUsp`=~s$WeY5H$(U;tM0R*CfW@{JNr97^dn}?jWr1>kqVZ6L?C)!DZG4(%_ z(y-r^5hTHet7nr&}oMAp+xk8b5>?WM?-ltU}W9J(=aMX0#^vR)?y( zXI6rL8BmSpQmQ4UM6z*uqMs0bM;eFvc;g-2tcsbbGR-C!=AvqWBw~m2ej}aOFZK#` z>!MxXT{Fw7lK_gs{llbwN_sG{MH@A4HXr0R{{!%oStkBR+u%hqN zZgCZbTfmONyy0A`>t^!ndB z7W3T?#lDGx;}*Z^ux6rUKb5C$Z%_ z@xdjN7sWHC@l7NQ9n!MB&TH_qJ|1{JZ>c>1y<$nj2k)fv@#57biAOoLAh1}Egry5; zNFrzIiLq;XIXSOyghO~OePsHyAt4XuZ#UbUNv^JyJ(cY8{^B^%d^&1XfssMTE)oR@+uqLUwMgw`-nC~m7Z2z zJ}7^<(|%R5{CWD2hPWp29{@D78P@|>%bvY1!n#N7eM6;Pk3e!=IP*F6^e*;d!l?<& zHum{jA24WswAoIxIFzt^x3aen?8U@J@CPaa^4B1t^}c;RK; z1X7(ZFzams%mYWOze2uIny7-UM*`E#e061&(8Amy44|_!13Xn4VHrk_9AW>T2ytnG z^8u0+@fS8o2WN&rE0QhoG)mG{2o04~N^kBD!!|vq#ZZU|@`qkHOSfAMYA1*JCnxlo8VS9xipWr7$sjTf~L-lL4(jrzcvGtZ}aW^9n{MJs_^ue;*n>f zf<2DXeML(gtV-MUDUQ|3&9sZd>A2AUq~80#%KQFrlz#u8xvE91b&H@ms)pGxeJv&l z$zWlM7aUwEg!*dCGO%&+BAjG;7!Q?O!FrrOMk$dmfXE|;dY*ehdADnJkt^|iG{f<6XyF&l!fA4CwytN>46QSSkUy(3`3lY72}UfK^v{Ty(Z@gUp&5I>TB)!Fj~cU zw@Cb`C8RFT8?z@0YE}k%t;El=-uGbgChqp*TM3ezU2ia%P`T z5rl(#IT@r7(|gRj0>Vlb#fv!+ct^NqJ9sr{b(gT6f2vvlKR3YszU-6PLD|Eo#d7)kdT>6^t`uD0#Ep~tL$$z2s=J2jfjD5VB+hV6ej zO9uAHvF{~2ikE>fz~fA#?A?cy?)oY}VG(Y=#c%y+VCA2j`Ct9i$VpW;Ap6>m)@H7& zsB`ME%IeqI^5q`DY%iIeJaKX0?j72&=}o8BM_q`U)3)u%0loWcfB%t1bg3x@b2q2F z#%;VZp<%P6_trgSpm&UKSbdrzDC{#6+VYGc`UlR#`=tDiSNK9MrhW{6M|dA;7qJXw za*{7bci)VU1(B)N>Hxl@2p>*Oq|Iw`Plyei#BEKmwoHy|W|>sU3u}E>Y+uknCVsIk zU3f|3!wRG3o=aa8-mXzhD!*UbL|)$mD#WnxQu;(?B7yyEr)Y(;1^>$E@P4RvCIX}c zXX&AmKi`4zk~WS1#KPsTn#3xyo{gl%NJe-m)CP!eJYohs91ue6sRAf6UeJ(^Uyevu zrR{0{av*ARB1LHSsj-fZCS&+p)de@Sx~AW(qt~CNj$IrpE1U1UVtToQZG;OB{bXw< z3~T8|rTEhwco{PIC_Z4Pm8RE|NIhwgqQ4mGVVw7_%^~bMoi)BIZZWJ^iT$-}N^+hV z_me9@Lb|r~v?-63>_*Vv(nIkgiYY!vsU|zsZ)nRev(CEC74qXz)l?JPBzgr&VxupA z=!d^eG4PxWkuOBQ{%gF`MiLh)GN+Eh(0)Yu!pw-}JjVlq{brN98<_DvjQh8i)4aCTx3<=zne&Li_B=!7?%vFUmYt-FM%xv|ECbv2NSrpWe%9mHlloDM%ygAj#avR9$Zvuclf#qH?1!g) zO1CFK6;P`3)A`t1)645zN@c&<@zsHzHut3+!TmLSsxnWY?=g>l9WG|EIaqcjk}>^+ zHFrpbFER@9`>yKZ5BTe4-rK$ZKe}H{3zPSz{pu>{;P3QO;-INmF7MjOtt7hCcdMR= zODaqq!kzt}y;1H~m6z8I0{>x{U5A~Tzy8CO&$lL3C;GtE_}^?n3E*zkw>Hm=|{@X$MA z%|9t`oIaMTpGOR{d*!=9KzjQ+6X#LczV9&}r`B@dfPg?SZeQH(KWQrT^pHcKCl=P!{R70QJrV(fSLAG!=XS*}w@B?crcsMV9LLjIw96!JmqtdT z%q1pX0hLvDvnTJ~+gx_)XzSPlj=ck-k!u`d6R=tYrWcH7iS)v{M;4yDYY%2)*HK$U z@!7%IA7`AqvdW4i9oDxCq?T5ib=sZN+mMkq!g9h&b}|KA!l54ArDzRPd=p%^SCH|> zE9GbDgLtW3x%s+&^8&B4m+3=s%_FbK>wHKt^=y6HCu;B zAVGQ)DS}|=y@-G!y@eWj3B5O^BUd^|C_zPfLTBQYyfK$RGSJ8{j}t{L6%UjII*VvLeyFhO7_e-i4{E^9pN23nB$9#4mCkrJarwa31!9{~-_4KTvgCkkjqu1*S>cI%!=9;G91 zmB*L3DDI!BAcHJwaCt2sHKCFk!~uSFm3ej)p4e;XBSxeWfnA)hHGpBJoQz4ndbhxx z2mDQM76@Bnl3eES>Fd&Wz`rb}xW8bkqU~yK6q}*uT9%^Mwt2V36~$+7T7!W{2bZS;46H8nY_7n*>eI zDVB1^s6DEe>r-PEC%sMU7Ejr4eL8)a3q1ujB8T4OJlhtIjSLD4;~kVtcnZ2TaGw{* zI-=t%XWxWY6zy4!cct=BH;S+>Vb6@hV6K?(cN>Je%P|vPwN^%}HS}=83Vx)B19f?I zYks#C_&PHY#5T0{%)&+7_CG!p3^Bi*=(ftqqNz(n$NED${9u_|&T6Iwt$+0Oi%@^YVh?1ovJ9 z-^!#h9|>~^r}+X*=gy3nLQOx0G3>QeA|Q=L1odqwb`7%hp%F-u&$VXFU;C$kcY6m>cSv1+o9N zMQ6Nrxg4JYPh3OPs-|HVp+B=tT9g2wxfYu7w5*31)bZ(hVV*!Hwroul>z&_JiWuhj zsA|{eLn#Eb|6aijduD9$=t}92H7{VnaOzH^N*9cFmH+^B;HWM~XjO6%u>O?6l5Lblj7D$FW#vKY$TI(6j%KS!PUG554cI|q+@{O(8x(!r zJom0#0SeuU_~0qYA|A85SG@R^C{V2Z1?iSk%dmM* zSAl#CE-vLCHA6*0!{5e&G&&5jPLt*`AZjJ%(uhr;=}FYS_OgX{3d#V z&p+vjMrRc4w$Cm%$6369x|EwRZ_9>dxj_7*gd$IkaA$*ME5?u5V#yq76AIkKUuLj* z2)^!+iHg#l*JZtmwyJz%lDXuPr=HVQp0-95?poH_HF)T18$;Dbd0%TXLm7*~7CWX2 zyoETS^2EKk?@uhLjFX69dMT+$$2gVHEiB!S9l5V3Qc;%VJ?ynu_gy{+qx+D<5f?@A zTRT0+iKv+nyjHseEGwg=M3=LycWS51UdD-Vyd=&*H1qC0pGQ*Blr4N_w|bdv+ptf^ zzM{`*z2h1;_6#1IKt0u%?ix1YncGaGRUeV)N5Kyno}j6vSa*llg~8{yr0zOcvw5dC z&Jx%Isz_m*gIIk7ttl{(;n{ z0oGI0f%f+Wh#F4JpF7r<8O?S(xL{QR4+q$wJ4=Oo7WZ#i zT!v21wtnB&msZ9}^Kx>zgh3%HSyF7~O%_nviXIFRUvvi>IT_S?GI&ExpXkXd%#YcP zbQ~j?5e>dRQd}b7W4Y5ATUfz0qd`h(j6O^&g<&YW^-dkE^#*8p2;>YbJP)jk{1{f1 z*vWHY+|#ObjM}gCluFQ1XzaSk@};mus&L~l?(oMapr}IOm6VkLd6v7na|4F&^Ea|a zv=-+EG!Pb*BESv(Y&mM|_VobDdptwL_{ML($8r>wm7d#4Pk;*o+(zl`4LL~xzB;XH zk1|X2?u-*l^65TJy+f{UtiG0~=I0d7K4p`jFMZr|#~oVTXA*VEj6?Swc9kF&!z%C{hqm~*zAy=8AZRsK9S?=4K^uv;lE!$-BjOeWQrx3IIypjYJZ+Du-RA?1Q|8uMt{q{U0?Sbrvp>wXl6C4NbDxkL;)1n zsqv_prc9X;omlqKcMEOMY*%ZIhQz#I;TvN-2N>ORc~Rh-GG?rffd1Qd?nME|*Rjv6 zNG3{cEJhU$*!sEL4@tTgmJaBt(FSG|V{3da4jqn$W~rn%LU`PJZj%+#rb`D#LlzS% zAB>FiebSNz2c{yXK3*R70aKU(XDT$OoubB6c`+MWv&s^|Ra9RB3}kH^(7wzN#cbs| zN=57@vGZd~f^4n_27RFSUL*pIWTB@azwh3D*8lGtPsBrUey9H^d;K3JxO<)h2I8R( z|64cf=b;Cv#UtWTd}EIulY9^x!u3*aX5OZv(&Nd9@9E5UmZ01CtjKo-5;wUg4e6ff zl@cc2h<>gqW=C6)hn2~u=x{f8z|(5a!He*x? zQUtwd54CV2DbBd9}f*yn?-b?EE5OuA_hUvyQGFwsZg8CSlu zsDVYYE0D-e$G52_sHcW+Gm^fI86QfR{;PUg7Kew)xf0FLNBZ3CV4fsU-c z0R$~-4*>Wob+k>a+c9vVraeW$FQk2VFt@Dxn7<`9{FqyzYZiKN3`(qq<1{r(t>)<5 zSh5dagM$$CM;6nQnO5UM#X+!mt2{{|Y}ZNY_AMf>Mk*jgh|H#<5sQ~O z+65a=8G{4V{Tr=@zo8+^?<6cN-i{dF6PfrV#H;renBvdDGugO$Fj}~m!-uwJkQDI7 z*8)1kEpZo`IE0ylW?#_|R)47*?UHL6evygnHRAVf)D^O(&c6Bd>+3Ea&6?AB4W4n1 z-`gUX+K9>8PDoSvsXmOHP3Lk?rAs&i6ccSBKv2RZQymbTU}c%UjU=$9+gdB2U#B9~ z?T%l3ml{H0i$ez)7MsD;12%y-O8FoS;BVbcV_m@0nE46aYhBsLDbHP})T3?A0nhtO zuBG0cpvk-2ZwY?-!@#d$4?FHHFV#?J$+`EXaMu?M*myIgH3Ek3?L$@L-g$oFgjzhw ziG-U8;`8q=7w_I1-ORl*JFi$@%vdZAVKVBVmhf>Cnk!p(xt-O`jk&ccD}_v?^{nW{ z=88-v@PXXR$0eu^Om?^8ws6Y!-P-~sNE+MPSb4P074jbL&rH59fpOo~L)}JP!*!4e zvzBKX$eQ>9!72mmTZ|bBG0hUlmQ8N5rxDj;T*M}r-PQ^+-x{Kx&uiB`u}d}UQW#c! z@!AG}Vp>YUrPp0H5~*N266@0Zl)Ovk@5J28>-Hk_drMIebln0{0@&{(F0Av~)m)&> zw)Z&_KiVrM`Q9YaN=jvOS zlX0|SPAlbNpABLyYVqnTWBHv`TAeV}S?<=}+M>Xd!amLB7of#a)Ic6?tQ{vSbNMDbtn zS|_Q+ocDeBcvuj*{(cMGF;4E_qeCR5Oy!byj{v9s*P-zruxxIvFv)nIMKA9UyBN|J zcYk1wK^y3_D>WT3kujrrox)3`;1d6KJo-BypG7N`-pOO z^arEuhy;QY3rJj+Jvh7~sfuDmUE|Y_e3?UyZ%0ohBvn}$ zj){k^ya@+zCP_D`@CZgOIHfRs#+tauh0Fb5o2F^Jtkc5W$wt|eJDxIpMZoaV4`<#vuF$|Nb)}&aM?a`5oDt|JmwvbG z`jlblT8S~fyN2yDUI6sZ^Xnhfn*H_F`Y4TJ%A(CE6?{vKbmv>T6ayCy3egwKiSaP=-ujEoxq!ltQBcqj|_V`_+|Y2 z_aO(d2kMhTFSU#PU?m9nvC?t=dYVDYsO+e8!K7eu@YqjyJ#C)L;N=D22ith|lZR*h z34EjZ30|=N!VAv*In~NJ+cygzbv?Km<`Si8BenX138B)mU zru%`}=}vYl0S^lU2L9jO`O7-3u!U3Ha`>Y1#D^@@49mVj7{!CHZ~EKc0gCn3oi!bV z6>{Se9xBI!casfxyA?_)$)SIT3V-c(HWVI!6zY=Ku-i6a#tk-v#z)ofG3(HLEP!PI7Q7h-Enc3v^Iw;&ajX zsSB>hf{lO?_L`sq?|>q->(|M$M|N_dIyV z#=$VrnwC^_85?4=T(onlyTVx|l9IZ~J2sAtsqHiz9%xyVU`LEKc_qXejO8X(p+kAH z5iwt?BkzXdHhC+a>L$BNbPd^mlE1syiC91&h%xQDW+c?oxBPav$**^eS!Fzt$W0X zAsLv{`F>4;cuH5pR)8kC`X;Mv%1Pm+N|=G7H!I=Vm=aWPFbdk+3}hyRshK#myK1e zdoZ|bz=JWeBiYV6bzHMF-|~+Yg6r^3!?XWtLiWe-q}gAn3!d$9!HwOI!m}^%S6mB! zH5Ibo^)rqK*PQwvQ|m6wsN-Lgf1-aZ^Ox8c%Woo?GFILd66ntDy=;rDa)1l2aN(SA z>WA { + console.log('Background message:', remoteMessage); + + const channelId = await notifee.createChannel({ + id: 'default', + name: 'Umumiy bildirishnomalar', + sound: 'default', + importance: AndroidImportance.HIGH, + }); + + await notifee.displayNotification({ + title: + remoteMessage.notification?.title || + remoteMessage.data?.title || + 'Yangi xabar', + body: + remoteMessage.notification?.body || + remoteMessage.data?.body || + 'Matn yo‘q', + android: { + channelId, + smallIcon: 'ic_launcher', + sound: 'default', + pressAction: { + id: 'default', + }, + }, + }); +}); + AppRegistry.registerComponent(appName, () => App); diff --git a/package-lock.json b/package-lock.json index bb1014c..b85691c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,15 @@ "version": "0.0.1", "dependencies": { "@hookform/resolvers": "^5.2.0", + "@notifee/react-native": "^9.1.8", "@react-native-async-storage/async-storage": "^2.2.0", "@react-native-clipboard/clipboard": "^1.16.3", "@react-native-community/datetimepicker": "^8.4.2", "@react-native-community/geolocation": "^3.4.0", "@react-native-community/image-editor": "^4.3.0", "@react-native-community/push-notification-ios": "^1.11.0", + "@react-native-firebase/app": "^23.2.0", + "@react-native-firebase/messaging": "^23.2.0", "@react-native-picker/picker": "^2.11.1", "@react-native/new-app-screen": "0.80.1", "@react-navigation/native": "^7.1.17", @@ -36,7 +39,9 @@ "react-native-biometrics": "^3.0.1", "react-native-config": "^1.5.6", "react-native-confirmation-code-field": "^8.0.1", + "react-native-device-info": "^14.0.4", "react-native-dotenv": "^3.4.11", + "react-native-fs": "^2.20.0", "react-native-geolocation-service": "^5.3.1", "react-native-gesture-handler": "^2.28.0", "react-native-gesture-password": "^0.4.0", @@ -59,6 +64,7 @@ "react-native-safe-area-context": "^5.6.0", "react-native-screens": "^4.14.1", "react-native-send-intent": "^1.3.0", + "react-native-share": "^12.2.0", "react-native-skia": "^0.0.1", "react-native-smooth-pincode-input": "^1.0.9", "react-native-splash-screen": "^3.3.0", @@ -2393,6 +2399,827 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@firebase/ai": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-2.1.0.tgz", + "integrity": "sha512-4HvFr4YIzNFh0MowJLahOjJDezYSTjQar0XYVu/sAycoxQ+kBsfXuTPRLVXCYfMR5oNwQgYe4Q2gAOYKKqsOyA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/ai/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/analytics": { + "version": "0.10.18", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.18.tgz", + "integrity": "sha512-iN7IgLvM06iFk8BeFoWqvVpRFW3Z70f+Qe2PfCJ7vPIgLPjHXDE774DhCT5Y2/ZU/ZbXPDPD60x/XPWEoZLNdg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.24", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.24.tgz", + "integrity": "sha512-jE+kJnPG86XSqGQGhXXYt1tpTbCTED8OQJ/PQ90SEw14CuxRxx/H+lFbWA1rlFtFSsTCptAJtgyRBwr/f00vsw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/analytics": "0.10.18", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/analytics/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/app": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.1.tgz", + "integrity": "sha512-jxTrDbxnGoX7cGz7aP9E7v9iKvBbQfZ8Gz4TH3SfrrkcyIojJM3+hJnlbGnGxHrABts844AxRcg00arMZEyA6Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.11.0.tgz", + "integrity": "sha512-XAvALQayUMBJo58U/rxW02IhsesaxxfWVmVkauZvGEz3vOAjMEQnzFlyblqkc2iAaO82uJ2ZVyZv9XzPfxjJ6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.4.0.tgz", + "integrity": "sha512-UfK2Q8RJNjYM/8MFORltZRG9lJj11k0nW84rrffiKvcJxLf1jf6IEjCIkCamykHE73C6BwqhVfhIBs69GXQV0g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check": "0.11.0", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/app-compat": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.5.1.tgz", + "integrity": "sha512-BEy1L6Ufd85ZSP79HDIv0//T9p7d5Bepwy+2mKYkgdXBGKTbFm2e2KxyF1nq4zSQ6RRBxWi0IY0zFVmoBTZlUA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app": "0.14.1", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/app-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/auth-compat": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.6.0.tgz", + "integrity": "sha512-J0lGSxXlG/lYVi45wbpPhcWiWUMXevY4fvLZsN1GHh+po7TZVng+figdHBVhFheaiipU8HZyc7ljw1jNojM2nw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth": "1.11.0", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/auth": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.11.0.tgz", + "integrity": "sha512-5j7+ua93X+IRcJ1oMDTClTo85l7Xe40WSkoJ+shzPrX7OISlVWLdE1mKC57PSD+/LfAbdhJmvKixINBw2ESK6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-compat/node_modules/@react-native-async-storage/async-storage": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.24.0.tgz", + "integrity": "sha512-W4/vbwUOYOjco0x3toB8QCr7EjIP6nE9G7o8PMguvvjYT5Awg09lyV4enACRx4s++PPulBiBSjL0KTFx2u0Z/g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "merge-options": "^3.0.4" + }, + "peerDependencies": { + "react-native": "^0.0.0-0 || >=0.60 <1.0" + } + }, + "node_modules/@firebase/auth-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-types": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.0.tgz", + "integrity": "sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/component/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/data-connect": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.11.tgz", + "integrity": "sha512-G258eLzAD6im9Bsw+Qm1Z+P4x0PGNQ45yeUuuqe5M9B1rn0RJvvsQCRHXgE52Z+n9+WX1OJd/crcuunvOGc7Vw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/data-connect/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/database": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.0.tgz", + "integrity": "sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.0.tgz", + "integrity": "sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/database": "1.1.0", + "@firebase/database-types": "1.0.16", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/database-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/database-types": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.16.tgz", + "integrity": "sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.13.0" + } + }, + "node_modules/@firebase/database/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/firestore": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.9.0.tgz", + "integrity": "sha512-5zl0+/h1GvlCSLt06RMwqFsd7uqRtnNZt4sW99k2rKRd6k/ECObIWlEnvthm2cuOSnUmwZknFqtmd1qyYSLUuQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "@firebase/webchannel-wrapper": "1.0.4", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.4.0.tgz", + "integrity": "sha512-4O7v4VFeSEwAZtLjsaj33YrMHMRjplOIYC2CiYsF6o/MboOhrhe01VrTt8iY9Y5EwjRHuRz4pS6jMBT8LfQYJA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/firestore": "4.9.0", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/firestore/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/functions": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.13.0.tgz", + "integrity": "sha512-2/LH5xIbD8aaLOWSFHAwwAybgSzHIM0dB5oVOL0zZnxFG1LctX2bc1NIAaPk1T+Zo9aVkLKUlB5fTXTkVUQprQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.4.0.tgz", + "integrity": "sha512-VPgtvoGFywWbQqtvgJnVWIDFSHV1WE6Hmyi5EGI+P+56EskiGkmnw6lEqc/MEUfGpPGdvmc4I9XMU81uj766/g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/functions": "0.13.0", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/functions/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/installations": { + "version": "0.6.19", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.19.tgz", + "integrity": "sha512-nGDmiwKLI1lerhwfwSHvMR9RZuIH5/8E3kgUWnVRqqL7kGVSktjLTWEMva7oh5yxQ3zXfIlIwJwMcaM5bK5j8Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.19.tgz", + "integrity": "sha512-khfzIY3EI5LePePo7vT19/VEIH1E3iYsHknI/6ek9T8QCozAZshWT9CjlwOzZrKvTHMeNcbpo/VSOSIWDSjWdQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/installations/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/logger": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.5.0.tgz", + "integrity": "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/logger/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/messaging": { + "version": "0.12.23", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.23.tgz", + "integrity": "sha512-cfuzv47XxqW4HH/OcR5rM+AlQd1xL/VhuaeW/wzMW1LFrsFcTn0GND/hak1vkQc2th8UisBcrkVcQAnOnKwYxg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.23.tgz", + "integrity": "sha512-SN857v/kBUvlQ9X/UjAqBoQ2FEaL1ZozpnmL1ByTe57iXkmnVVFm9KqAsTfmf+OEwWI4kJJe9NObtN/w22lUgg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/messaging": "0.12.23", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/messaging/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/performance": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.9.tgz", + "integrity": "sha512-UzybENl1EdM2I1sjYm74xGt/0JzRnU/0VmfMAKo2LSpHJzaj77FCLZXmYQ4oOuE+Pxtt8Wy2BVJEENiZkaZAzQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.22.tgz", + "integrity": "sha512-xLKxaSAl/FVi10wDX/CHIYEUP13jXUjinL+UaNXT9ByIvxII5Ne5150mx6IgM8G6Q3V+sPiw9C8/kygkyHUVxg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/performance": "0.7.9", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/performance/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/remote-config": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.6.tgz", + "integrity": "sha512-Yelp5xd8hM4NO1G1SuWrIk4h5K42mNwC98eWZ9YLVu6Z0S6hFk1mxotAdCRmH2luH8FASlYgLLq6OQLZ4nbnCA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.19.tgz", + "integrity": "sha512-y7PZAb0l5+5oIgLJr88TNSelxuASGlXyAKj+3pUc4fDuRIdPNBoONMHaIUa9rlffBR5dErmaD2wUBJ7Z1a513Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/remote-config": "0.6.6", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/remote-config/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/storage": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.14.0.tgz", + "integrity": "sha512-xWWbb15o6/pWEw8H01UQ1dC5U3rf8QTAzOChYyCpafV6Xki7KVp3Yaw2nSklUwHEziSWE9KoZJS7iYeyqWnYFA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.4.0.tgz", + "integrity": "sha512-vDzhgGczr1OfcOy285YAPur5pWDEvD67w4thyeCUh6Ys0izN9fNYtA1MJERmNBfqjqu0lg0FM5GLbw0Il21M+g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/storage": "0.14.0", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/storage/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/util": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", + "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/util/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.4.tgz", + "integrity": "sha512-6m8+P+dE/RPl4OPzjTxcTbQ0rGeRyeTvAi9KwIffBVCiAMKrfXfLZaqD1F+m8t4B5/Q5aHsMozOgirkH1F5oMQ==", + "license": "Apache-2.0" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -3028,6 +3855,79 @@ "node": ">= 8" } }, + "node_modules/@notifee/react-native": { + "version": "9.1.8", + "resolved": "https://registry.npmjs.org/@notifee/react-native/-/react-native-9.1.8.tgz", + "integrity": "sha512-Az/dueoPerJsbbjRxu8a558wKY+gONUrfoy3Hs++5OqbeMsR0dYe6P+4oN6twrLFyzAhEA1tEoZRvQTFDRmvQg==", + "license": "Apache-2.0", + "peerDependencies": { + "react-native": "*" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, "node_modules/@react-native-async-storage/async-storage": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.2.0.tgz", @@ -3359,6 +4259,40 @@ "react-native": ">=0.58.4" } }, + "node_modules/@react-native-firebase/app": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/@react-native-firebase/app/-/app-23.2.0.tgz", + "integrity": "sha512-Ol9d0hnr1j2pPXYaWC+0UsQEcIiyVF7XufvyCifnMdnzfhPgrqnFwgqBCZm/jmWfosHIwhMexEuvaUuWtHDxrg==", + "license": "Apache-2.0", + "dependencies": { + "firebase": "12.1.0" + }, + "peerDependencies": { + "expo": ">=47.0.0", + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } + } + }, + "node_modules/@react-native-firebase/messaging": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/@react-native-firebase/messaging/-/messaging-23.2.0.tgz", + "integrity": "sha512-k5pr7VWPvApqLjMEyrBLHtGSb9B7vV/wFkNwRJ36KRurSgwQoMIf5lNiD+8Liw0ROQ01Sfm4YRqHfKkc8xvsqg==", + "license": "Apache-2.0", + "peerDependencies": { + "@react-native-firebase/app": "23.2.0", + "expo": ">=47.0.0" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } + } + }, "node_modules/@react-native-picker/picker": { "version": "2.11.1", "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.11.1.tgz", @@ -5352,6 +6286,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, + "node_modules/base-64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", + "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -7617,6 +8556,18 @@ "reusify": "^1.0.4" } }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -7850,6 +8801,86 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/firebase": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-12.1.0.tgz", + "integrity": "sha512-oZucxvfWKuAW4eHHRqGKzC43fLiPqPwHYBHPRNsnkgonqYaq0VurYgqgBosRlEulW+TWja/5Tpo2FpUU+QrfEQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/ai": "2.1.0", + "@firebase/analytics": "0.10.18", + "@firebase/analytics-compat": "0.2.24", + "@firebase/app": "0.14.1", + "@firebase/app-check": "0.11.0", + "@firebase/app-check-compat": "0.4.0", + "@firebase/app-compat": "0.5.1", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.11.0", + "@firebase/auth-compat": "0.6.0", + "@firebase/data-connect": "0.3.11", + "@firebase/database": "1.1.0", + "@firebase/database-compat": "2.1.0", + "@firebase/firestore": "4.9.0", + "@firebase/firestore-compat": "0.4.0", + "@firebase/functions": "0.13.0", + "@firebase/functions-compat": "0.4.0", + "@firebase/installations": "0.6.19", + "@firebase/installations-compat": "0.2.19", + "@firebase/messaging": "0.12.23", + "@firebase/messaging-compat": "0.2.23", + "@firebase/performance": "0.7.9", + "@firebase/performance-compat": "0.2.22", + "@firebase/remote-config": "0.6.6", + "@firebase/remote-config-compat": "0.2.19", + "@firebase/storage": "0.14.0", + "@firebase/storage-compat": "0.4.0", + "@firebase/util": "1.13.0" + } + }, + "node_modules/firebase/node_modules/@firebase/auth": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.11.0.tgz", + "integrity": "sha512-5j7+ua93X+IRcJ1oMDTClTo85l7Xe40WSkoJ+shzPrX7OISlVWLdE1mKC57PSD+/LfAbdhJmvKixINBw2ESK6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/firebase/node_modules/@react-native-async-storage/async-storage": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.24.0.tgz", + "integrity": "sha512-W4/vbwUOYOjco0x3toB8QCr7EjIP6nE9G7o8PMguvvjYT5Awg09lyV4enACRx4s++PPulBiBSjL0KTFx2u0Z/g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "merge-options": "^3.0.4" + }, + "peerDependencies": { + "react-native": "^0.0.0-0 || >=0.60 <1.0" + } + }, + "node_modules/firebase/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", @@ -8415,6 +9446,12 @@ "node": ">= 0.8" } }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -8500,6 +9537,12 @@ "node": ">=0.10.0" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -10470,6 +11513,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -10649,6 +11698,12 @@ "node": ">=6" } }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -12714,6 +13769,30 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -13067,6 +14146,15 @@ } } }, + "node_modules/react-native-device-info": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/react-native-device-info/-/react-native-device-info-14.0.4.tgz", + "integrity": "sha512-NX0wMAknSDBeFnEnSFQ8kkAcQrFHrG4Cl0mVjoD+0++iaKrOupiGpBXqs8xR0SeJyPC5zpdPl4h/SaBGly6UxA==", + "license": "MIT", + "peerDependencies": { + "react-native": "*" + } + }, "node_modules/react-native-dotenv": { "version": "3.4.11", "resolved": "https://registry.npmjs.org/react-native-dotenv/-/react-native-dotenv-3.4.11.tgz", @@ -13079,6 +14167,25 @@ "@babel/runtime": "^7.20.6" } }, + "node_modules/react-native-fs": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/react-native-fs/-/react-native-fs-2.20.0.tgz", + "integrity": "sha512-VkTBzs7fIDUiy/XajOSNk0XazFE9l+QlMAce7lGuebZcag5CnjszB+u4BdqzwaQOdcYb5wsJIsqq4kxInIRpJQ==", + "license": "MIT", + "dependencies": { + "base-64": "^0.1.0", + "utf8": "^3.0.0" + }, + "peerDependencies": { + "react-native": "*", + "react-native-windows": "*" + }, + "peerDependenciesMeta": { + "react-native-windows": { + "optional": true + } + } + }, "node_modules/react-native-geolocation-service": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/react-native-geolocation-service/-/react-native-geolocation-service-5.3.1.tgz", @@ -13384,6 +14491,15 @@ "react-native": "*" } }, + "node_modules/react-native-share": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/react-native-share/-/react-native-share-12.2.0.tgz", + "integrity": "sha512-f6MB9BsKa9xVvu0DKbxq5jw4IyYHqQeqUlCNkD8eAFoJx6SD31ObPAn7SQ6NG9AOuhCy6aYuSJYJvx25DaoMZQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, "node_modules/react-native-skia": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/react-native-skia/-/react-native-skia-0.0.1.tgz", @@ -14068,7 +15184,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "devOptional": true, "funding": [ { "type": "github", @@ -15315,6 +16430,12 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "license": "MIT" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -15396,12 +16517,41 @@ "defaults": "^1.0.3" } }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/whatwg-fetch": { "version": "3.6.20", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", diff --git a/package.json b/package.json index d084d3f..293e4ed 100644 --- a/package.json +++ b/package.json @@ -14,12 +14,15 @@ }, "dependencies": { "@hookform/resolvers": "^5.2.0", + "@notifee/react-native": "^9.1.8", "@react-native-async-storage/async-storage": "^2.2.0", "@react-native-clipboard/clipboard": "^1.16.3", "@react-native-community/datetimepicker": "^8.4.2", "@react-native-community/geolocation": "^3.4.0", "@react-native-community/image-editor": "^4.3.0", "@react-native-community/push-notification-ios": "^1.11.0", + "@react-native-firebase/app": "^23.2.0", + "@react-native-firebase/messaging": "^23.2.0", "@react-native-picker/picker": "^2.11.1", "@react-native/new-app-screen": "0.80.1", "@react-navigation/native": "^7.1.17", @@ -41,7 +44,9 @@ "react-native-biometrics": "^3.0.1", "react-native-config": "^1.5.6", "react-native-confirmation-code-field": "^8.0.1", + "react-native-device-info": "^14.0.4", "react-native-dotenv": "^3.4.11", + "react-native-fs": "^2.20.0", "react-native-geolocation-service": "^5.3.1", "react-native-gesture-handler": "^2.28.0", "react-native-gesture-password": "^0.4.0", @@ -64,6 +69,7 @@ "react-native-safe-area-context": "^5.6.0", "react-native-screens": "^4.14.1", "react-native-send-intent": "^1.3.0", + "react-native-share": "^12.2.0", "react-native-skia": "^0.0.1", "react-native-smooth-pincode-input": "^1.0.9", "react-native-splash-screen": "^3.3.0", diff --git a/src/api/URL.ts b/src/api/URL.ts index 707dd03..3e5fb6d 100644 --- a/src/api/URL.ts +++ b/src/api/URL.ts @@ -11,3 +11,6 @@ export const RESEND_OTP = '/mobile/auth/resend-otp'; export const CALENDAR = '/mobile/calendar'; export const PACKETS = '/mobile/packets'; export const GET_ME = '/mobile/profile/me'; +export const GET_EXCHANGES = '/exchanges'; +export const GET_WARHOUSES = '/mobile/cargo-reference-book/warehouse-address'; +export const GET_REFERENCE = '/mobile/cargo-reference-book/info'; diff --git a/src/api/auth/type.ts b/src/api/auth/type.ts index ea3541e..ed92735 100644 --- a/src/api/auth/type.ts +++ b/src/api/auth/type.ts @@ -6,12 +6,20 @@ export interface registerPayload { phoneNumber: string; recommend: string; branchId: number; + fcmToken: string; + deviceId: string; + deviceType: string; + deviceName: string; + address: string; } export interface otpPayload { phoneNumber: string; otp: string; otpType: 'LOGIN' | 'RESET_PASSWORD' | 'REGISTRATION'; + fcmToken: string; + deviceId: string; + deviceName: string; } export interface resendPayload { phoneNumber: string; @@ -21,8 +29,11 @@ export interface resendPayload { export interface loginPayload { phoneNumber: string; passportSerial: string; - // passportNumber: string; branchId: number; + fcmToken: string; + deviceId: string; + deviceType: string; + deviceName: string; } export interface getMeData { diff --git a/src/api/exchanges/index.ts b/src/api/exchanges/index.ts new file mode 100644 index 0000000..1b9f057 --- /dev/null +++ b/src/api/exchanges/index.ts @@ -0,0 +1,19 @@ +import axiosInstance from 'api/axios'; +import { GET_EXCHANGES } from 'api/URL'; + +export interface ExchangeType { + code: string; + date: string; + id: number; + nominal: number; + rate: number; +} + +const exchanges_api = { + async getExchanges(): Promise { + const data = await axiosInstance.get(GET_EXCHANGES); + return data.data; + }, +}; + +export default exchanges_api; diff --git a/src/api/reference/index.ts b/src/api/reference/index.ts new file mode 100644 index 0000000..5044f87 --- /dev/null +++ b/src/api/reference/index.ts @@ -0,0 +1,26 @@ +import axiosInstance from 'api/axios'; +import { GET_REFERENCE } from 'api/URL'; + +export interface ReferenceType { + id: number; + title: string; + shortDescription: string; + price: number; + exchange: string; + unit: string; + unitValue: number; +} +const reference_api = { + async getReference(params: { + cargoType: 'AVIA' | 'AUTO'; + }): Promise { + const res = await axiosInstance.get(GET_REFERENCE, { + params: { + cargoType: params.cargoType, + }, + }); + return res.data; + }, +}; + +export default reference_api; diff --git a/src/api/warhouses/index.ts b/src/api/warhouses/index.ts new file mode 100644 index 0000000..63d4629 --- /dev/null +++ b/src/api/warhouses/index.ts @@ -0,0 +1,16 @@ +import axiosInstance from 'api/axios'; +import { GET_WARHOUSES } from 'api/URL'; + +const warhouses_api = { + async getWarhouses(params: { cargoType: 'AUTO' | 'AVIA' }): Promise { + const data = await axiosInstance.get(GET_WARHOUSES, { + params: { + ...params, + }, + }); + + return data.data; + }, +}; + +export default warhouses_api; diff --git a/src/components/FileDrop.tsx b/src/components/FileDrop.tsx index 9fca85e..6deb64b 100644 --- a/src/components/FileDrop.tsx +++ b/src/components/FileDrop.tsx @@ -9,30 +9,37 @@ import { View, } from 'react-native'; import { + Asset, ImagePickerResponse, launchImageLibrary, MediaType, } from 'react-native-image-picker'; import Download from 'svg/Download'; -interface FileData { +export interface FileData { uri: string; name: string; type: string; base64: string; } -interface SingleFileDropProps { +export interface SingleFileDropProps { title: string; onFileSelected?: (file: FileData) => void; + /** + * Ruxsat berilgan MIME tipi (masalan: "image/png" yoki "image/jpeg") + */ + type?: string; } const SingleFileDrop: React.FC = ({ title, onFileSelected, + type = 'image/png', }) => { const [selectedImage, setSelectedImage] = useState(null); const { t } = useTranslation(); + const imagePickerOptions = useMemo( () => ({ mediaType: 'photo' as MediaType, @@ -49,29 +56,27 @@ const SingleFileDrop: React.FC = ({ return; } - if (response.assets && response.assets[0]) { - const asset = response.assets[0]; - if (!asset.uri || !asset.type || !asset.base64) return; + const asset: Asset | undefined = response.assets?.[0]; + if (!asset || !asset.uri || !asset.type || !asset.base64) return; - // faqat PNG fayllarni qabul qilish - if (asset.type !== 'image/png') { - Alert.alert('Xato', 'Faqat PNG fayllarni yuklashingiz mumkin'); - return; - } - - setSelectedImage(asset.uri); - - const fileData: FileData = { - uri: asset.uri, - name: asset.fileName || 'image.png', - type: asset.type, - base64: `data:${asset.type};base64,${asset.base64}`, - }; - - onFileSelected?.(fileData); + // faqat belgilangan tipdagi fayllarni qabul qilish + if (!asset.type.startsWith('image/')) { + Alert.alert('Xato', 'Faqat rasm fayllarni yuklashingiz mumkin'); + return; } + + setSelectedImage(asset.uri); + + const fileData: FileData = { + uri: asset.uri, + name: asset.fileName || `file.${asset.type.split('/')[1]}`, + type: asset.type, + base64: `data:${asset.type};base64,${asset.base64}`, + }; + + onFileSelected?.(fileData); }, - [onFileSelected], + [onFileSelected, type], ); const openGallery = useCallback((): void => { @@ -101,17 +106,8 @@ const SingleFileDrop: React.FC = ({ <> - {selectedImage ? ( - - ) : ( - <> - - {title} - - )} + + {title} @@ -158,11 +154,6 @@ const styles = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', }, - iconText: { - fontSize: 20, - color: '#007bff', - fontWeight: 'bold', - }, sectionTitle: { fontSize: 16, fontWeight: '500', @@ -191,7 +182,6 @@ const styles = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', marginVertical: 16, - position: 'relative', flexDirection: 'row', }, dividerLine: { @@ -203,18 +193,15 @@ const styles = StyleSheet.create({ paddingHorizontal: 12, fontSize: 14, color: '#999', - zIndex: 1, }, innerContainer: { flex: 1, justifyContent: 'space-between', width: '100%', }, - topContent: { alignItems: 'center', }, - bottomContent: { width: '100%', alignItems: 'center', diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index b1daed7..4b1bd53 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -5,7 +5,6 @@ import { Dimensions, Image, Linking, - Platform, StyleSheet, Text, TouchableOpacity, @@ -98,14 +97,12 @@ const Navbar = () => { /> */} - {Platform.OS === 'android' && ( - navigation.navigate('Notifications')} - > - - {/* */} - - )} + navigation.navigate('Notifications')} + > + + {/* */} + diff --git a/src/components/SplashScreen.tsx b/src/components/SplashScreen.tsx index 5f32c4e..3d7abc9 100644 --- a/src/components/SplashScreen.tsx +++ b/src/components/SplashScreen.tsx @@ -193,7 +193,7 @@ const styles = StyleSheet.create({ alignItems: 'center', }, brand: { - fontWeight: '700', + fontWeight: '500', color: '#fff', }, }); diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index 09fc1a3..5f5f531 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -170,6 +170,8 @@ "so‘m": "сум", "Umumiy narx": "Общая цена", "Yopish": "Закрыть", + "Manzilingizni kiriting": "Введите свой адрес", + "Toshkent Shahri, Mirzo Ulug'bek tumani...": "г. Ташкент, Мирзо-Улугбекский район...", "Passportlarim": "Мои паспорта", "Hali pasport qo'shilmagan": "Паспорт еще не добавлен", "Yangi pasport qo'shish uchun tugmani bosing": "Нажмите кнопку, чтобы добавить новый паспорт", diff --git a/src/i18n/locales/uz.json b/src/i18n/locales/uz.json index ebeb7be..1f48be5 100644 --- a/src/i18n/locales/uz.json +++ b/src/i18n/locales/uz.json @@ -16,6 +16,8 @@ "7 ta raqam kerak": "7 ta raqam kerak", "Filialni tanlang": "Filialni tanlang", "Ro'yxatdan o'tish": "Ro'yxatdan o'tish", + "Manzilingizni kiriting": "Manzilingizni kiriting", + "Toshkent Shahri, Mirzo Ulug'bek tumani...": "Toshkent Shahri, Mirzo Ulug'bek tumani...", "Ism": "Ism", "Ismingiz": "Ismingiz", "Familiya": "Familiya", diff --git a/src/screens/auth/login/ui/Confirm.tsx b/src/screens/auth/login/ui/Confirm.tsx index 5f6a45c..fd31210 100644 --- a/src/screens/auth/login/ui/Confirm.tsx +++ b/src/screens/auth/login/ui/Confirm.tsx @@ -1,4 +1,6 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; +import { getApp } from '@react-native-firebase/app'; +import { getMessaging, getToken } from '@react-native-firebase/messaging'; import { useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { useMutation } from '@tanstack/react-query'; @@ -17,9 +19,9 @@ import { TouchableOpacity, View, } from 'react-native'; +import DeviceInfo from 'react-native-device-info'; import { SafeAreaView } from 'react-native-safe-area-context'; import Logo from 'screens/../../assets/bootsplash/logo_512.png'; -import { useModalStore } from 'screens/auth/registeration/lib/modalStore'; import LanguageSelector from 'screens/auth/select-language/SelectLang'; import ArrowLeft from 'svg/ArrowLeft'; import { RootStackParamList } from 'types/types'; @@ -36,27 +38,57 @@ const OTP_LENGTH = 4; const Confirm = () => { const navigation = useNavigation(); const { t } = useTranslation(); + const [firebaseToken, setFirebseToken] = useState<{ + fcmToken: string; + deviceId: string; + deviceName: string; + } | null>(); const [code, setCode] = useState(new Array(OTP_LENGTH).fill('')); const [timer, setTimer] = useState(60); const [errorConfirm, setErrorConfirm] = useState(null); const [canResend, setCanResend] = useState(false); const inputRefs = useRef>([]); const { phoneNumber } = useUserStore(state => state); + + const app = getApp(); + const messaging = getMessaging(app); + + const getDeviceData = async () => { + try { + const fcmToken = await getToken(messaging); + return { + fcmToken, + deviceId: await DeviceInfo.getUniqueId(), + deviceName: await DeviceInfo.getDeviceName(), + }; + } catch (e) { + console.log('Xato:', e); + return null; + } + }; + + useEffect(() => { + getDeviceData().then(data => { + setFirebseToken(data); + }); + }, []); + const { mutate, isPending } = useMutation({ mutationFn: (payload: otpPayload) => authApi.verifyOtp(payload), onSuccess: async res => { await AsyncStorage.setItem('token', res.data.accessToken); navigation.navigate('Home'); setErrorConfirm(null); + console.log(res); }, onError: (err: any) => { - setErrorConfirm(err?.response.data.message); + setErrorConfirm(err?.response?.data?.message || 'Xato yuz berdi'); }, }); const { mutate: resendMutate } = useMutation({ mutationFn: (payload: resendPayload) => authApi.resendOtp(payload), - onSuccess: async res => { + onSuccess: async () => { setTimer(60); setCanResend(false); setCode(new Array(OTP_LENGTH).fill('')); @@ -64,17 +96,14 @@ const Confirm = () => { setErrorConfirm(null); }, onError: (err: any) => { - setErrorConfirm(err?.response.data.message); + setErrorConfirm(err?.response?.data?.message || 'Xato yuz berdi'); }, }); - const openModal = useModalStore(state => state.openModal); useEffect(() => { let interval: NodeJS.Timeout | null = null; if (timer > 0) { - interval = setInterval(() => { - setTimer(prevTimer => prevTimer - 1); - }, 1000); + interval = setInterval(() => setTimer(prev => prev - 1), 1000); } else { setCanResend(true); if (interval) clearInterval(interval); @@ -104,20 +133,21 @@ const Confirm = () => { }; const handleResendCode = () => { - resendMutate({ - phoneNumber: phoneNumber, - otpType: 'LOGIN', - }); + resendMutate({ phoneNumber, otpType: 'LOGIN' }); }; const handleVerifyCode = () => { const enteredCode = code.join(''); - mutate({ - phoneNumber: phoneNumber, - otp: String(enteredCode), - otpType: 'LOGIN', - }); - // navigation.navigate('Home'); + if (firebaseToken) { + mutate({ + phoneNumber, + otp: enteredCode, + otpType: 'LOGIN', + deviceId: firebaseToken.deviceId, + deviceName: firebaseToken.deviceName, + fcmToken: firebaseToken.fcmToken, + }); + } }; return ( @@ -147,15 +177,13 @@ const Confirm = () => { {t('Tasdiqlash kodini kiriting')} {phoneNumber} {t('raqamiga yuborilgan')} {OTP_LENGTH}{' '} - {t('xonali kodni kiriting.')} + {t('xonali kodni kiriting.')}{' '} {code.map((digit, index) => ( { - inputRefs.current[index] = ref; - }} + ref={ref => (inputRefs.current[index] = ref)} style={styles.otpInput} keyboardType="number-pad" maxLength={1} @@ -166,7 +194,7 @@ const Confirm = () => { /> ))} - {errorConfirm !== null && ( + {errorConfirm && ( {errorConfirm} )} @@ -210,10 +238,7 @@ const Confirm = () => { }; const styles = StyleSheet.create({ - safeArea: { - flex: 1, - backgroundColor: '#f8f9fa', - }, + safeArea: { flex: 1, backgroundColor: '#f8f9fa' }, errorText: { color: 'red', fontSize: 14, @@ -221,33 +246,22 @@ const styles = StyleSheet.create({ marginTop: 10, textAlign: 'center', }, - buttonTextDisabled: { - color: 'white', - }, + buttonTextDisabled: { color: 'white' }, langContainer: { width: '100%', marginTop: 10, - display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingHorizontal: 16, }, - headerTitle: { - fontSize: 18, - fontWeight: 'bold', - color: '#333', - }, container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, }, - content: { - width: '100%', - alignItems: 'center', - }, + content: { width: '100%', alignItems: 'center' }, title: { fontSize: 24, fontWeight: 'bold', @@ -280,24 +294,10 @@ const styles = StyleSheet.create({ color: '#333', backgroundColor: '#fff', }, - resendContainer: { - marginBottom: 30, - marginTop: 20, - }, - timerText: { - fontSize: 15, - color: '#999', - }, - resendButton: { - paddingVertical: 10, - paddingHorizontal: 20, - borderRadius: 8, - }, - resendButtonText: { - fontSize: 15, - color: '#007bff', - fontWeight: 'bold', - }, + resendContainer: { marginBottom: 30, marginTop: 20 }, + timerText: { fontSize: 15, color: '#999' }, + resendButton: { paddingVertical: 10, paddingHorizontal: 20, borderRadius: 8 }, + resendButtonText: { fontSize: 15, color: '#007bff', fontWeight: 'bold' }, verifyButton: { backgroundColor: '#007bff', paddingVertical: 15, @@ -311,11 +311,7 @@ const styles = StyleSheet.create({ shadowOpacity: 0.2, shadowRadius: 4, }, - verifyButtonText: { - color: '#fff', - fontSize: 18, - fontWeight: '600', - }, + verifyButtonText: { color: '#fff', fontSize: 18, fontWeight: '600' }, }); export default Confirm; diff --git a/src/screens/auth/login/ui/index.tsx b/src/screens/auth/login/ui/index.tsx index 2987d51..6e2b373 100644 --- a/src/screens/auth/login/ui/index.tsx +++ b/src/screens/auth/login/ui/index.tsx @@ -1,4 +1,6 @@ import { zodResolver } from '@hookform/resolvers/zod'; +import { getApp } from '@react-native-firebase/app'; +import { getMessaging, getToken } from '@react-native-firebase/messaging'; import { useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { useMutation, useQuery } from '@tanstack/react-query'; @@ -6,7 +8,13 @@ import { authApi } from 'api/auth'; import { loginPayload } from 'api/auth/type'; import { Branch, branchApi } from 'api/branch'; import formatPhone from 'helpers/formatPhone'; -import React, { useCallback, useMemo, useRef, useState } from 'react'; +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; import { Controller, useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { @@ -20,6 +28,7 @@ import { TouchableOpacity, View, } from 'react-native'; +import DeviceInfo from 'react-native-device-info'; import { SafeAreaView } from 'react-native-safe-area-context'; import Logo from 'screens/../../assets/bootsplash/logo_512.png'; import { LoginFormType, loginSchema } from 'screens/auth/login/lib/form'; @@ -50,6 +59,36 @@ const Login = () => { queryKey: ['branchList'], queryFn: branchApi.branchList, }); + const [firebaseToken, setFirebseToken] = useState<{ + fcmToken: string; + deviceId: string; + deviceName: string; + deviceType: string; + } | null>(); + + const app = getApp(); + const messaging = getMessaging(app); + + const getDeviceData = async () => { + try { + const fcmToken = await getToken(messaging); + return { + fcmToken, + deviceId: await DeviceInfo.getUniqueId(), + deviceName: await DeviceInfo.getDeviceName(), + deviceType: await DeviceInfo.getDeviceType(), + }; + } catch (e) { + console.log('Xato:', e); + return null; + } + }; + + useEffect(() => { + getDeviceData().then(data => { + setFirebseToken(data); + }); + }, []); const { mutate, isPending } = useMutation({ mutationFn: (payload: loginPayload) => authApi.login(payload), @@ -84,6 +123,10 @@ const Login = () => { passportSerial: `${data.passportSeriya.toUpperCase()}${ data.passportNumber }`, + fcmToken: firebaseToken?.fcmToken || '', + deviceId: firebaseToken?.deviceId || '', + deviceType: firebaseToken?.deviceType || '', + deviceName: firebaseToken?.deviceName || '', }); // navigation.navigate('Login-Confirm'); setUser({ diff --git a/src/screens/auth/registeration/lib/form.ts b/src/screens/auth/registeration/lib/form.ts index f130b15..0c352fb 100644 --- a/src/screens/auth/registeration/lib/form.ts +++ b/src/screens/auth/registeration/lib/form.ts @@ -4,6 +4,7 @@ import { z } from 'zod'; export const FirstStepSchema = z.object({ firstName: z.string().min(3, "Eng kamida 3ta belgi bo'lishi kerak"), lastName: z.string().min(3, "Eng kamida 3ta belgi bo'lishi kerak"), + address: z.string().min(3, "Eng kamida 3ta belgi bo'lishi kerak"), phoneNumber: z.string().min(12, 'Xato raqam kiritildi'), branchId: z.number().min(1, 'Filialni tanlang'), recommend: z.string().min(1, 'Majburiy maydon'), diff --git a/src/screens/auth/registeration/ui/Confirm.tsx b/src/screens/auth/registeration/ui/Confirm.tsx index 5171df3..cb63e6d 100644 --- a/src/screens/auth/registeration/ui/Confirm.tsx +++ b/src/screens/auth/registeration/ui/Confirm.tsx @@ -1,4 +1,6 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; +import { getApp } from '@react-native-firebase/app'; +import { getMessaging, getToken } from '@react-native-firebase/messaging'; import { useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { useMutation } from '@tanstack/react-query'; @@ -17,6 +19,7 @@ import { TouchableOpacity, View, } from 'react-native'; +import DeviceInfo from 'react-native-device-info'; import { SafeAreaView } from 'react-native-safe-area-context'; import Logo from 'screens/../../assets/bootsplash/logo_512.png'; import { useModalStore } from 'screens/auth/registeration/lib/modalStore'; @@ -46,6 +49,34 @@ const Confirm = ({ const [errorConfirm, setErrorConfirm] = useState(null); const inputRefs = useRef>([]); const { phoneNumber } = useUserStore(state => state); + const [firebaseToken, setFirebseToken] = useState<{ + fcmToken: string; + deviceId: string; + deviceName: string; + } | null>(); + + const app = getApp(); + const messaging = getMessaging(app); + + const getDeviceData = async () => { + try { + const fcmToken = await getToken(messaging); + return { + fcmToken, + deviceId: await DeviceInfo.getUniqueId(), + deviceName: await DeviceInfo.getDeviceName(), + }; + } catch (e) { + console.log('Xato:', e); + return null; + } + }; + + useEffect(() => { + getDeviceData().then(data => { + setFirebseToken(data); + }); + }, []); const { mutate, isPending } = useMutation({ mutationFn: (payload: otpPayload) => authApi.verifyOtp(payload), onSuccess: async res => { @@ -54,6 +85,7 @@ const Confirm = ({ setErrorConfirm(null); }, onError: (err: any) => { + console.dir(err); setErrorConfirm(err?.response.data.message); }, }); @@ -116,11 +148,16 @@ const Confirm = ({ const handleVerifyCode = () => { const enteredCode = code.join(''); - mutate({ - phoneNumber: phoneNumber, - otp: String(enteredCode), - otpType: 'REGISTRATION', - }); + if (firebaseToken) { + mutate({ + phoneNumber, + otp: enteredCode, + otpType: 'REGISTRATION', + deviceId: firebaseToken.deviceId, + deviceName: firebaseToken.deviceName, + fcmToken: firebaseToken.fcmToken, + }); + } }; return ( diff --git a/src/screens/auth/registeration/ui/FirstStep.tsx b/src/screens/auth/registeration/ui/FirstStep.tsx index 5131bf1..0082335 100644 --- a/src/screens/auth/registeration/ui/FirstStep.tsx +++ b/src/screens/auth/registeration/ui/FirstStep.tsx @@ -1,6 +1,8 @@ 'use client'; import { zodResolver } from '@hookform/resolvers/zod'; +import { getApp } from '@react-native-firebase/app'; +import { getMessaging, getToken } from '@react-native-firebase/messaging'; import { type RouteProp, useNavigation, @@ -27,6 +29,7 @@ import { TouchableOpacity, View, } from 'react-native'; +import DeviceInfo from 'react-native-device-info'; import { SafeAreaView } from 'react-native-safe-area-context'; import Logo from 'screens/../../assets/bootsplash/logo_512.png'; import { @@ -64,14 +67,43 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => { queryFn: branchApi.branchList, }); + const [firebaseToken, setFirebseToken] = useState<{ + fcmToken: string; + deviceId: string; + deviceName: string; + deviceType: string; + } | null>(); + + const app = getApp(); + const messaging = getMessaging(app); + + const getDeviceData = async () => { + try { + const fcmToken = await getToken(messaging); + return { + fcmToken, + deviceId: await DeviceInfo.getUniqueId(), + deviceName: await DeviceInfo.getDeviceName(), + deviceType: await DeviceInfo.getDeviceType(), + }; + } catch (e) { + console.log('Xato:', e); + return null; + } + }; + + useEffect(() => { + getDeviceData().then(data => { + setFirebseToken(data); + }); + }, []); + const { mutate, isPending } = useMutation({ mutationFn: (payload: registerPayload) => authApi.register(payload), onSuccess: res => { onNext(); }, onError: err => { - console.dir(err); - setError('Xatolik yuz berdi'); }, }); @@ -93,6 +125,7 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => { resolver: zodResolver(FirstStepSchema), defaultValues: { firstName: '', + address: '', lastName: '', recommend: '', }, @@ -104,7 +137,18 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => { lastName: data.lastName, phoneNumber: data.phoneNumber, }); - mutate(data); + mutate({ + firstName: data.firstName, + lastName: data.lastName, + phoneNumber: data.phoneNumber, + recommend: data.recommend, + branchId: data.branchId, + address: data.address, + fcmToken: firebaseToken?.fcmToken || '', + deviceId: firebaseToken?.deviceId || '', + deviceType: firebaseToken?.deviceType || '', + deviceName: firebaseToken?.deviceId || '', + }); }; useEffect(() => { @@ -143,6 +187,7 @@ const FirstStep = ({ onNext }: { onNext: () => void }) => { }).start(); } }; + return ( void }) => { )} /> + ( + + + {t('Manzilingizni kiriting')} + + + {errors.lastName && ( + + {t(errors.lastName.message || '')} + + )} + + )} + /> { const passportNumberRef = useRef(null); const [checkboxAnimation] = useState(new Animated.Value(1)); const [inputValue, setInputValue] = useState(''); + const { firstName, lastName } = useUserStore(state => state); const navigation = useNavigation>(); @@ -111,7 +113,7 @@ const SecondStep = () => { const isoBirthDate = `${y}-${m.padStart(2, '0')}-${d.padStart(2, '0')}`; mutate({ - fullName: data.passportSeriya.toUpperCase(), + fullName: `${firstName} ${lastName}`, birthDate: isoBirthDate, passportSerial: `${data.passportSeriya.toUpperCase()}${ data.passportNumber diff --git a/src/screens/auth/select-auth/SelectAuth.tsx b/src/screens/auth/select-auth/SelectAuth.tsx index a82420c..684df7f 100644 --- a/src/screens/auth/select-auth/SelectAuth.tsx +++ b/src/screens/auth/select-auth/SelectAuth.tsx @@ -24,8 +24,6 @@ const SelectAuth = () => { const navigation = useNavigation(); const { width } = useWindowDimensions(); - const isSmallScreen = width < 360; - return ( @@ -41,20 +39,15 @@ const SelectAuth = () => { style={[ styles.logoImage, { - width: isSmallScreen ? 120 : 250, - height: isSmallScreen ? 120 : 200, - borderRadius: 20000, + width: 180, + height: 180, }, ]} /> - - CPOST - + CPOST - + {t('Ro’yxatdan o’tganmisz')} @@ -110,17 +103,18 @@ const styles = StyleSheet.create({ }, logoWrapper: { alignItems: 'center', - marginBottom: 40, + marginBottom: 20, }, logoImage: { resizeMode: 'stretch', }, logoText: { - fontWeight: '700', + fontWeight: '500', + marginTop: 4, color: '#28A7E8', }, title: { - fontWeight: '600', + fontWeight: '500', textAlign: 'center', color: '#28A7E8', marginBottom: 20, diff --git a/src/screens/auth/select-language/SelectLangPage.tsx b/src/screens/auth/select-language/SelectLangPage.tsx index a2c6f04..d0814c5 100644 --- a/src/screens/auth/select-language/SelectLangPage.tsx +++ b/src/screens/auth/select-language/SelectLangPage.tsx @@ -7,7 +7,6 @@ import { StyleSheet, Text, TouchableOpacity, - useWindowDimensions, View, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; @@ -21,9 +20,6 @@ type NavigationProp = NativeStackNavigationProp; const SelectLangPage = () => { const navigation = useNavigation(); - const { width } = useWindowDimensions(); - - const isSmallScreen = width < 380; const selectLanguage = async (lang: 'uz' | 'ru') => { await changeLanguage(lang); @@ -45,24 +41,17 @@ const SelectLangPage = () => { style={[ styles.logoImage, { - width: isSmallScreen ? 120 : 250, - height: isSmallScreen ? 120 : 200, - borderRadius: 20000, + width: 180, + height: 180, }, ]} /> - - CPOST - + CPOST - + Tilni tanlang{' '} - + (Выберите язык) @@ -118,11 +107,11 @@ const styles = StyleSheet.create({ marginBottom: 8, }, logoText: { - fontWeight: '700', + fontWeight: '500', color: '#28A7E8', }, title: { - fontWeight: '600', + fontWeight: '500', textAlign: 'center', color: '#28A7E8', marginBottom: 24, diff --git a/src/screens/home/branches/ui/Branches.tsx b/src/screens/home/branches/ui/Branches.tsx index cc27266..d5d62da 100644 --- a/src/screens/home/branches/ui/Branches.tsx +++ b/src/screens/home/branches/ui/Branches.tsx @@ -51,11 +51,27 @@ const Branches = (props: BranchesProps) => { navigation.navigate('ListBranches', { branchId: e.id }) } > - - {e.name} - {e.address} + + + {e.name} + {e.address} + + - ))} @@ -89,14 +105,14 @@ const styles = StyleSheet.create({ elevation: 1, }, title: { - fontSize: 18, + fontSize: 16, paddingHorizontal: 5, fontWeight: '600', color: '#000', marginBottom: 6, }, subtitle: { - fontSize: 16, + fontSize: 14, paddingHorizontal: 5, fontWeight: '500', color: '#000000B2', diff --git a/src/screens/home/branches/ui/ListBranches.tsx b/src/screens/home/branches/ui/ListBranches.tsx index 0c0fabc..795fb09 100644 --- a/src/screens/home/branches/ui/ListBranches.tsx +++ b/src/screens/home/branches/ui/ListBranches.tsx @@ -25,46 +25,58 @@ const ListBranches = () => { queryFn: branchApi.branchList, }); + // ✅ ObjectManager orqali markerlarni yuboramiz useEffect(() => { - if (webViewReady && route.params?.branchId) { - const branch = data && data.find(b => b.id === route?.params?.branchId); + if (webViewReady && data && data.length) { + const features = data.map(branch => ({ + type: 'Feature', + id: branch.id, + geometry: { + type: 'Point', + coordinates: [branch.latitude, branch.longitude], + }, + properties: { balloonContent: branch.name }, + })); + + const jsCode = ` + if (window.objectManager) { + map.geoObjects.remove(window.objectManager); + } + window.objectManager = new ymaps.ObjectManager({ clusterize: true }); + window.objectManager.add({ + type: 'FeatureCollection', + features: ${JSON.stringify(features)} + }); + window.objectManager.objects.events.add('click', function (e) { + const id = e.get('objectId'); + window.ReactNativeWebView.postMessage(JSON.stringify({ + type: 'branch_click', + id + })); + }); + map.geoObjects.add(window.objectManager); + true; + `; + webviewRef.current?.injectJavaScript(jsCode); + } + }, [webViewReady, data]); + + // ✅ branchId bilan markerni ochish + useEffect(() => { + if (webViewReady && route.params?.branchId && data) { + const branch = data.find(b => b.id === route.params?.branchId); if (branch) { setSelectedBranch(branch); setModalVisible(true); const jsCode = ` map.setCenter([${branch.latitude}, ${branch.longitude}], 14); - placemark${branch.id}?.balloon.open(); true; `; webviewRef.current?.injectJavaScript(jsCode); } } - }, [webViewReady, route.params]); - - const generatePlacemarks = () => { - if (!data || !data.length) return ''; - return data - .map( - branch => ` - var placemark${branch.id} = new ymaps.Placemark([${branch.latitude}, ${branch.longitude}], { - balloonContent: '${branch.name}' - }, { - iconLayout: 'default#image', - iconImageSize: [30, 30], - iconImageOffset: [-15, -30] - }); - placemark${branch.id}.events.add('click', function () { - window.ReactNativeWebView.postMessage(JSON.stringify({ - type: 'branch_click', - id: ${branch.id} - })); - }); - map.geoObjects.add(placemark${branch.id}); - `, - ) - .join('\n'); - }; + }, [webViewReady, route.params, data]); const html = ` @@ -96,15 +108,12 @@ const ListBranches = () => { zoom: 6, controls: [] }); - - ${generatePlacemarks()} window.ReactNativeWebView.postMessage("map_ready"); }); function zoomIn() { if (map) map.setZoom(map.getZoom() + 1); } - function zoomOut() { if (map) map.setZoom(map.getZoom() - 1); } @@ -143,8 +152,9 @@ const ListBranches = () => { } const parsed = JSON.parse(message); if (parsed.type === 'branch_click') { - const branchItem = - data && data.find((b: Branch) => b.id === parsed.id); + const branchItem = data?.find( + (b: Branch) => b.id === parsed.id, + ); if (branchItem) { setSelectedBranch(branchItem); setModalVisible(true); diff --git a/src/screens/home/cargoPrices/ui/CargoPrices.tsx b/src/screens/home/cargoPrices/ui/CargoPrices.tsx index da401b0..de1665a 100644 --- a/src/screens/home/cargoPrices/ui/CargoPrices.tsx +++ b/src/screens/home/cargoPrices/ui/CargoPrices.tsx @@ -1,5 +1,7 @@ import { useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; +import { useQuery } from '@tanstack/react-query'; +import reference_api from 'api/reference'; import LayoutTwo from 'components/LayoutTwo'; import * as React from 'react'; import { useTranslation } from 'react-i18next'; @@ -16,39 +18,38 @@ interface CargoPricesProps {} const CargoPrices = (props: CargoPricesProps) => { const { t } = useTranslation(); - const [activeTab, setActiveTab] = React.useState<'avia' | 'auto'>('avia'); + const [activeTab, setActiveTab] = React.useState<'AVIA' | 'AUTO'>('AVIA'); const navigation = useNavigation>(); + + const { data, refetch } = useQuery({ + queryKey: ['reference_list'], + queryFn: () => reference_api.getReference({ cargoType: activeTab }), + }); + + React.useEffect(() => { + refetch(); + }, [activeTab]); + return ( - {activeTab === 'avia' && ( + {activeTab === 'AVIA' && ( - - - - {t('Oddiy maxsulotlar')} - - - 9.2$ /1kg - - - - {t('(Katta miqdordagi yuklar kelishuv asosida)')} - - - - - {t('Brend buyumlar')} - - 12.2$ /1kg - - - - {t('(Karobka,dokumentlar bilan birga)')} - - + {data && + data.map(ref => ( + + + {ref.title} + + {ref.price}$/{ref.unitValue} + {ref.unit} + + + {ref.shortDescription} + + ))} @@ -127,34 +128,21 @@ const CargoPrices = (props: CargoPricesProps) => { )} - {activeTab === 'auto' && ( + {activeTab === 'AUTO' && ( - - - 0-30 kg - - 7$ /1kg - - - - - - 30-100kg - - 6.5$ /1kg - - - - - - - 100kg {t('dan boshlab')} - - - 6$ /1kg - - - + {data && + data.map(ref => ( + + + {ref.title} + + {ref.price}$/{ref.unitValue} + {ref.unit} + + + {ref.shortDescription} + + ))} {t( diff --git a/src/screens/home/home/ui/Home.tsx b/src/screens/home/home/ui/Home.tsx index 908a83f..ec472dd 100644 --- a/src/screens/home/home/ui/Home.tsx +++ b/src/screens/home/home/ui/Home.tsx @@ -12,7 +12,7 @@ import TabsAuto from './TabsAuto'; import TabsAvia from './TabsAvia'; const Home = () => { - const [activeTab, setActiveTab] = useState<'avia' | 'auto'>('avia'); + const [activeTab, setActiveTab] = useState<'AVIA' | 'AUTO'>('AVIA'); const [refreshing, setRefreshing] = useState(false); const { width: screenWidth } = useWindowDimensions(); const scale = screenWidth < 360 ? 0.85 : 1; @@ -52,9 +52,9 @@ const Home = () => { ); const activeTabContent = useMemo(() => { - if (activeTab === 'auto') { + if (activeTab === 'AUTO') { return ; - } else if (activeTab === 'avia') { + } else if (activeTab === 'AVIA') { return ; } return null; diff --git a/src/screens/home/home/ui/Tabs.tsx b/src/screens/home/home/ui/Tabs.tsx index 7418e7b..89d99cd 100644 --- a/src/screens/home/home/ui/Tabs.tsx +++ b/src/screens/home/home/ui/Tabs.tsx @@ -8,7 +8,7 @@ import { HomeStyle } from './styled'; interface Props { activeTab: string; - setActiveTab: Dispatch>; + setActiveTab: Dispatch>; } const Tabs = ({ activeTab, setActiveTab }: Props) => { @@ -30,12 +30,12 @@ const Tabs = ({ activeTab, setActiveTab }: Props) => { const tabsData = useMemo( () => [ { - type: 'avia' as const, + type: 'AVIA' as const, label: t('Avia orqali yetkazish'), logo: AviaLogo, }, { - type: 'auto' as const, + type: 'AUTO' as const, label: t('Avto orqali yetkazish'), logo: AutoLogo, }, diff --git a/src/screens/home/home/ui/TabsAuto.tsx b/src/screens/home/home/ui/TabsAuto.tsx index 49a8477..58b5381 100644 --- a/src/screens/home/home/ui/TabsAuto.tsx +++ b/src/screens/home/home/ui/TabsAuto.tsx @@ -1,6 +1,7 @@ import Clipboard from '@react-native-clipboard/clipboard'; import { useQuery } from '@tanstack/react-query'; import { authApi } from 'api/auth'; +import warhouses_api from 'api/warhouses'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { @@ -26,35 +27,9 @@ const TabsAuto = () => { queryFn: authApi.getMe, }); - const addressList = [ - { - id: 1, - title: 'China (Auto)', - postCode: '510440', - addressInfo: [ - `收件人∶吴彦祖AT(${getMe?.autoCargoId})`, - '地址∶广州市白云区龙归街道南村攀龙六巷30号AТ(N209)', - ' 电话: 18023847617', - `1004 ${getMe?.aviaCargoId}`, - ], - }, - // { - // id: 2, - // title: 'Korea (Auto)', - // postCode: '520550', - // addressInfo: [ - // '收件人∶李小龙AT(M312)', - // '地址∶深圳市南山区科技园科发路', - // '18号AT(M312)', - // '电话: 13800008888', - // ], - // }, - ]; - const handleCopy = (info: string[]) => { - if (getMe?.status === 'active') { - const textToCopy = info.join('\n'); - Clipboard.setString(textToCopy); + if (getMe?.status === 'ACTIVE') { + Clipboard.setString(info.join('\n')); Toast.show({ type: 'success', text1: t('Nusxa olingan'), @@ -73,43 +48,54 @@ const TabsAuto = () => { } }; + const { data } = useQuery({ + queryKey: ['warhouses'], + queryFn: () => warhouses_api.getWarhouses({ cargoType: 'AUTO' }), + }); + + const formattedData = + data?.map((item: string | null) => { + if (!item) return ''; + + const withAutoCargo = item.replace('%s', getMe?.autoCargoId || ''); + + const withAviaCargo = withAutoCargo.replace( + '%s', + getMe?.aviaCargoId || '', + ); + + return withAviaCargo; + }) || []; + return ( item.id.toString()} + keyExtractor={(_, index) => index.toString()} pagingEnabled showsHorizontalScrollIndicator={false} - snapToInterval={cardWidth + 10} // +10: marginRight + snapToInterval={cardWidth + 10} decelerationRate="fast" contentContainerStyle={{ paddingHorizontal: (screenWidth - cardWidth) / 2, padding: 10, }} renderItem={({ item, index }) => { - const isLast = index === addressList.length - 1; + const isLast = index === formattedData.length - 1; return ( - {item.title} + China (Auto) - {item.addressInfo.map((line, idx) => ( - - {line} - - ))} + {item} - handleCopy(item.addressInfo)}> + handleCopy([item])}> - - {t('Auto post kodi')}: - {item.postCode} - ); }} diff --git a/src/screens/home/home/ui/TabsAvia.tsx b/src/screens/home/home/ui/TabsAvia.tsx index 5c8a269..5f425fa 100644 --- a/src/screens/home/home/ui/TabsAvia.tsx +++ b/src/screens/home/home/ui/TabsAvia.tsx @@ -1,6 +1,7 @@ import Clipboard from '@react-native-clipboard/clipboard'; import { useQuery } from '@tanstack/react-query'; import { authApi } from 'api/auth'; +import warhouses_api from 'api/warhouses'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { @@ -21,31 +22,6 @@ const TabsAvia = () => { queryFn: authApi.getMe, }); - const addressList = [ - { - id: 1, - title: 'China (Avia)', - postCode: ' 101399', - addressInfo: [ - `收货人: ${getMe?.aviaCargoId}`, - '手机号码: 18335530701', - '北京市顺义区南法信旭辉空港中心C座', - `1004 ${getMe?.aviaCargoId}`, - ], - }, - // { - // id: 2, - // title: 'Korea (Avia)', - // postCode: '510440', - // addressInfo: [ - // '收货人: M312', - // '手机号码: 18335530701', - // '北京市顺义区南法信旭辉空港中心C座', - // '1004 N209', - // ], - // }, - ]; - const { width: screenWidth } = useWindowDimensions(); const scale = screenWidth < 360 ? 0.85 : 1; const cardWidth = screenWidth * 0.95; @@ -53,13 +29,12 @@ const TabsAvia = () => { const { t } = useTranslation(); const handleCopy = (info: string[]) => { - if (getMe?.status === 'active') { - const textToCopy = info.join('\n'); - Clipboard.setString(textToCopy); + if (getMe?.status === 'ACTIVE') { + Clipboard.setString(info.join('\n')); Toast.show({ type: 'success', text1: t('Nusxa olingan'), - text2: t('Avia manzili nusxalandi!'), + text2: t('Avto manzili nusxalandi!'), position: 'top', visibilityTime: 2000, }); @@ -74,43 +49,54 @@ const TabsAvia = () => { } }; + const { data } = useQuery({ + queryKey: ['warhouses'], + queryFn: () => warhouses_api.getWarhouses({ cargoType: 'AVIA' }), + }); + + const formattedData = + data?.map((item: string | null) => { + if (!item) return ''; + + const withAutoCargo = item.replace('%s', getMe?.autoCargoId || ''); + + const withAviaCargo = withAutoCargo.replace( + '%s', + getMe?.aviaCargoId || '', + ); + + return withAviaCargo; + }) || []; + return ( item.id.toString()} + keyExtractor={(_, index) => index.toString()} pagingEnabled showsHorizontalScrollIndicator={false} - snapToInterval={cardWidth + 10} // +10: marginRight + snapToInterval={cardWidth + 10} decelerationRate="fast" contentContainerStyle={{ paddingHorizontal: (screenWidth - cardWidth) / 2, padding: 10, }} renderItem={({ item, index }) => { - const isLast = index === addressList.length - 1; + const isLast = index === formattedData.length - 1; return ( - {item.title} + China (AVIA) - - {item.addressInfo.map((line, idx) => ( - - {line} - - ))} + + {item} - handleCopy(item.addressInfo)}> + handleCopy([item])}> - - {t('Avia post kodi')}: - {item.postCode} - ); }} @@ -139,7 +125,7 @@ const makeStyles = (scale: number, cardWidth: number, screenWidth: number) => alignItems: 'center', }, card: { - height: 220 * scale, + // height: 220 * scale, width: cardWidth, backgroundColor: '#28a8e82c', borderRadius: 12 * scale, diff --git a/src/screens/passport/myPassport/ui/MyPassport.tsx b/src/screens/passport/myPassport/ui/MyPassport.tsx index a450e27..d1563c2 100644 --- a/src/screens/passport/myPassport/ui/MyPassport.tsx +++ b/src/screens/passport/myPassport/ui/MyPassport.tsx @@ -36,12 +36,53 @@ const MyPassport = ({ getMe, myPassport }: Props) => { }); }; + const getStatusMeta = (status?: string) => { + const key = (status || '').toLowerCase(); + switch (key) { + case 'active': + return { label: t('Faol'), bg: '#E6F7EE', fg: '#1F9254' }; + case 'pending': + return { label: t('Kutilmoqda'), bg: '#FFF7E6', fg: '#B26A00' }; + case 'inactive': + case 'blocked': + return { label: t('Faol emas'), bg: '#FDECEF', fg: '#A61D24' }; + default: + return { label: t('Faol emas'), bg: '#EDF2F7', fg: '#A61D24' }; + } + }; + return ( {myPassport && myPassport.map(data => ( - {t('Passport ma’lumotlarim')} + + {t('Passport ma’lumotlarim')} + {getMe?.status && ( + + + {getStatusMeta(getMe.status).label} + + + )} + { {t('Telefon raqami')} @@ -125,25 +168,13 @@ const MyPassport = ({ getMe, myPassport }: Props) => { - - {t('Limit')} - - - {data.availableLimit}$ - + {t('Limit')} + {data.availableLimit}$ @@ -158,6 +189,10 @@ const styles = StyleSheet.create({ alignSelf: 'center', marginTop: 10, }, + statusText: { + fontSize: 13, + fontWeight: '600', + }, card: { backgroundColor: '#FFFFFF', padding: 20, @@ -184,6 +219,19 @@ const styles = StyleSheet.create({ marginBottom: 15, gap: 5, }, + statusBadge: { + alignSelf: 'center', + marginTop: 5, + marginBottom: 10, + paddingHorizontal: 14, + paddingVertical: 4, + borderRadius: 20, + shadowColor: '#000', + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.15, + shadowRadius: 3, + elevation: 3, // Android uchun chiroyli ko‘rinishi + }, infoTitle: { color: '#979797', fontSize: 16, diff --git a/src/screens/profile/myProfile/ui/ProfilePages.tsx b/src/screens/profile/myProfile/ui/ProfilePages.tsx index 8ba5f97..42549d6 100644 --- a/src/screens/profile/myProfile/ui/ProfilePages.tsx +++ b/src/screens/profile/myProfile/ui/ProfilePages.tsx @@ -6,7 +6,6 @@ import { useTranslation } from 'react-i18next'; import { Alert, Linking, - Platform, StyleSheet, Text, TouchableOpacity, @@ -80,21 +79,19 @@ const ProfilePages = (props: componentNameProps) => { - {Platform.OS === 'android' && ( - navigation.navigate('Notifications')} - > - - - {t('Bildirishnomalar')} - - - - )} + navigation.navigate('Notifications')} + > + + + {t('Bildirishnomalar')} + + + { +const Notifications = () => { + const [notifications, setNotifications] = React.useState( + [], + ); const [refreshing, setRefreshing] = React.useState(false); const [modalVisible, setModalVisible] = React.useState(false); const { t } = useTranslation(); @@ -39,13 +41,19 @@ const Notifications = (props: NotificationsProps) => { [refreshing, onRefresh], ); - if (!(fakeNotifications.length > 0)) { - return ( - - - - ); - } + const loadNotifications = async () => { + const stored = await AsyncStorage.getItem('notifications'); + if (stored) { + setNotifications(JSON.parse(stored)); + } + }; + + React.useEffect(() => { + const unsubscribe = loadNotifications(); + return () => { + unsubscribe; + }; + }, []); return ( @@ -53,16 +61,20 @@ const Notifications = (props: NotificationsProps) => { keyboardShouldPersistTaps="handled" refreshControl={refreshControl} > - {fakeNotifications.map(item => ( - openModal(item)} - style={styles.card} - key={item.id} - > - {item.message} - - - ))} + {notifications.length > 0 ? ( + notifications.map(item => ( + openModal(item)} + style={styles.card} + key={item.id} + > + {item.message} + + + )) + ) : ( + + )} { export default Notifications; const styles = StyleSheet.create({ - container: { - flex: 1, - }, - header: { - paddingHorizontal: 20, - paddingTop: 5, - }, - title: { - fontSize: 24, - fontWeight: 'bold', - color: '#333', - }, card: { borderBottomWidth: 1, borderColor: '#D8DADC', diff --git a/src/screens/profile/warehouses/ui/TabsAutoWarehouses.tsx b/src/screens/profile/warehouses/ui/TabsAutoWarehouses.tsx index df131ea..41f2c8c 100644 --- a/src/screens/profile/warehouses/ui/TabsAutoWarehouses.tsx +++ b/src/screens/profile/warehouses/ui/TabsAutoWarehouses.tsx @@ -1,6 +1,7 @@ import Clipboard from '@react-native-clipboard/clipboard'; import { useQuery } from '@tanstack/react-query'; import { authApi } from 'api/auth'; +import warhouses_api from 'api/warhouses'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { @@ -53,9 +54,8 @@ const TabsAutoWarehouses = () => { ]; const handleCopy = (info: string[]) => { - if (getMe?.status === 'active') { - const textToCopy = info.join('\n'); - Clipboard.setString(textToCopy); + if (getMe?.status === 'ACTIVE') { + Clipboard.setString(info.join('\n')); Toast.show({ type: 'success', text1: t('Nusxa olingan'), @@ -74,39 +74,50 @@ const TabsAutoWarehouses = () => { } }; + const { data } = useQuery({ + queryKey: ['warhouses'], + queryFn: () => warhouses_api.getWarhouses({ cargoType: 'AUTO' }), + }); + + const formattedData = + data?.map((item: string | null) => { + if (!item) return ''; + + const withAutoCargo = item.replace('%s', getMe?.autoCargoId || ''); + + const withAviaCargo = withAutoCargo.replace( + '%s', + getMe?.aviaCargoId || '', + ); + + return withAviaCargo; + }) || []; + return ( item.id.toString()} + keyExtractor={(_, index) => index.toString()} pagingEnabled showsHorizontalScrollIndicator={false} snapToInterval={cardWidth + 10} decelerationRate="fast" renderItem={({ item, index }) => { - const isLast = index === addressInfo.length - 1; + const isLast = index === formattedData.length - 1; return ( - {item.title} + China (Auto) - {item.addressInfo.map((line, idx) => ( - - {line} - - ))} + {item} handleCopy(item.addressInfo)}> - - {t('Auto post kodi')}: - {item.postCode} - ); }} @@ -117,7 +128,6 @@ const TabsAutoWarehouses = () => { const makeStyles = (scale: number, cardWidth: number, screenWidth: number) => StyleSheet.create({ card: { - height: '100%', width: cardWidth, backgroundColor: '#28a8e82c', borderRadius: 12 * scale, diff --git a/src/screens/profile/warehouses/ui/TabsAviaWarehouses.tsx b/src/screens/profile/warehouses/ui/TabsAviaWarehouses.tsx index eb863ad..3e1eb56 100644 --- a/src/screens/profile/warehouses/ui/TabsAviaWarehouses.tsx +++ b/src/screens/profile/warehouses/ui/TabsAviaWarehouses.tsx @@ -1,6 +1,7 @@ import Clipboard from '@react-native-clipboard/clipboard'; import { useQuery } from '@tanstack/react-query'; import { authApi } from 'api/auth'; +import warhouses_api from 'api/warhouses'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { @@ -53,13 +54,12 @@ const TabsAviaWarehouses = () => { const { t } = useTranslation(); const handleCopy = (info: string[]) => { - if (getMe?.status === 'active') { - const textToCopy = info.join('\n'); - Clipboard.setString(textToCopy); + if (getMe?.status === 'ACTIVE') { + Clipboard.setString(info.join('\n')); Toast.show({ type: 'success', text1: t('Nusxa olingan'), - text2: t('Avia manzili nusxalandi!'), + text2: t('Avto manzili nusxalandi!'), position: 'top', visibilityTime: 2000, }); @@ -74,39 +74,50 @@ const TabsAviaWarehouses = () => { } }; + const { data } = useQuery({ + queryKey: ['warhouses'], + queryFn: () => warhouses_api.getWarhouses({ cargoType: 'AVIA' }), + }); + + const formattedData = + data?.map((item: string | null) => { + if (!item) return ''; + + const withAutoCargo = item.replace('%s', getMe?.autoCargoId || ''); + + const withAviaCargo = withAutoCargo.replace( + '%s', + getMe?.aviaCargoId || '', + ); + + return withAviaCargo; + }) || []; + return ( item.id.toString()} + keyExtractor={(_, index) => index.toString()} pagingEnabled showsHorizontalScrollIndicator={false} - snapToInterval={cardWidth + 10} // +10: marginRight + snapToInterval={cardWidth + 10} decelerationRate="fast" renderItem={({ item, index }) => { - const isLast = index === addressList.length - 1; + const isLast = index === formattedData.length - 1; return ( - {item.title} + China (Auto) - - {item.addressInfo.map((line, idx) => ( - - {line} - - ))} + + {item} handleCopy(item.addressInfo)}> - - {t('Avia post kodi')}: - {item.postCode} - ); }} @@ -116,26 +127,7 @@ const TabsAviaWarehouses = () => { const makeStyles = (scale: number, cardWidth: number, screenWidth: number) => StyleSheet.create({ - container: { - height: 200, - width: '95%', - backgroundColor: '#28a8e82c', - margin: 'auto', - marginTop: 20, - borderRadius: 12, - padding: 12, - gap: 10, - }, - scrollContainer: { - marginTop: 20, - paddingHorizontal: (screenWidth - cardWidth) / 2, - }, - postCodeWrapper: { - flexDirection: 'row', - alignItems: 'center', - }, card: { - height: 220 * scale, width: cardWidth, backgroundColor: '#28a8e82c', borderRadius: 12 * scale, @@ -144,31 +136,37 @@ const makeStyles = (scale: number, cardWidth: number, screenWidth: number) => }, titleCard: { flexDirection: 'row', - gap: 8, + gap: 8 * scale, alignItems: 'center', }, title: { - fontSize: 20, + fontSize: 20 * scale, fontWeight: '600', color: '#101623CC', }, infoId: { flexDirection: 'row', justifyContent: 'space-between', + marginVertical: 8 * scale, }, infoText: { - fontSize: 16, + fontSize: 16 * scale, color: '#28A7E8', }, + postCodeWrapper: { + flexDirection: 'row', + alignItems: 'center', + }, postCodeText: { - fontSize: 16, + fontSize: 16 * scale, color: '#000000', fontWeight: '500', }, postCode: { - fontSize: 16, + fontSize: 16 * scale, color: '#28A7E8', fontWeight: '400', + marginLeft: 4 * scale, }, }); diff --git a/src/screens/profile/warehouses/ui/Warehouses.tsx b/src/screens/profile/warehouses/ui/Warehouses.tsx index 8c5aeef..7ac4131 100644 --- a/src/screens/profile/warehouses/ui/Warehouses.tsx +++ b/src/screens/profile/warehouses/ui/Warehouses.tsx @@ -1,8 +1,12 @@ +import { useQuery } from '@tanstack/react-query'; +import { authApi } from 'api/auth'; import SingleFileDrop from 'components/FileDrop'; import LayoutTwo from 'components/LayoutTwo'; import * as React from 'react'; import { useTranslation } from 'react-i18next'; import { + ActivityIndicator, + Image, RefreshControl, ScrollView, StyleSheet, @@ -10,14 +14,71 @@ import { TouchableOpacity, View, } from 'react-native'; +import Toast from 'react-native-toast-message'; +import Shablon from 'screens/../../assets/bootsplash/shablon.jpg'; import TabsAutoWarehouses from './TabsAutoWarehouses'; import TabsAviaWarehouses from './TabsAviaWarehouses'; +interface FileData { + uri: string; + name: string; + type: string; + base64: string; +} + interface WarehousesProps {} +const botToken = '7768577881:AAGXGtOl2IiMImrsY6BZmksN9Rjeq2InlTo'; const Warehouses = (props: WarehousesProps) => { const [refreshing, setRefreshing] = React.useState(false); const { t } = useTranslation(); + const [isLoading, setIsLoading] = React.useState(false); + const [backImage, setBackImage] = React.useState(null); + const { data: getMe } = useQuery({ + queryKey: ['getMe'], + queryFn: authApi.getMe, + }); + + const openTelegramWithImage = async () => { + const telegramApiUrl = `https://api.telegram.org/bot${botToken}/sendPhoto`; + + const formData = new FormData(); + formData.append('chat_id', '-1002950892822'); + formData.append('photo', { + uri: backImage?.uri, + type: 'image/jpeg', + name: 'photo.jpg', + }); + formData.append( + 'caption', + `Foydalanuvchi ismi: ${getMe?.fullName} +Telefon nomer: +${getMe?.phone} +Cargo Idsi: ${getMe?.aviaCargoId} + `, + ); + try { + setIsLoading(true); + await fetch(telegramApiUrl, { + method: 'POST', + body: formData, + }); + Toast.show({ + type: 'success', + text1: t("So'rovingiz jo'natilidi. Tez orada siz bilan bog'lanamiz"), + position: 'top', + visibilityTime: 2000, + }); + } catch (error) { + Toast.show({ + type: 'error', + text1: t('Xatolik yuz berdi'), + position: 'top', + visibilityTime: 2000, + }); + } finally { + setIsLoading(false); // 👈 loading tugadi + } + }; const onRefresh = React.useCallback(() => { setRefreshing(true); @@ -72,9 +133,25 @@ const Warehouses = (props: WarehousesProps) => { {t('Skrenshot rasmini yuklang')} - - - {t('Manzilni tekshirish')} + + + + {isLoading ? ( + + ) : ( + {t('Manzilni tekshirish')} + )} diff --git a/src/screens/wallet/payment/ui/Payment.tsx b/src/screens/wallet/payment/ui/Payment.tsx index 9b99ce6..e63a35e 100644 --- a/src/screens/wallet/payment/ui/Payment.tsx +++ b/src/screens/wallet/payment/ui/Payment.tsx @@ -24,9 +24,10 @@ const Payment = ({ packets }: Props) => { const handlePaymentPress = useCallback( (item: any) => { - const isPaid = item.paymentStatus === 'paid'; + const isPaid = + item.paymentStatus === 'PAYED' || item.paymentStatus === 'PENDING'; navigation.navigate(isPaid ? 'PaymentQrCode' : 'PaymentMethod', { - packets: item, // tanlangan itemni to‘liq yuboramiz + packets: item, }); }, [navigation], @@ -49,7 +50,8 @@ const Payment = ({ packets }: Props) => { const renderPaymentCard = useCallback( (item: any) => { - const isPaid = item.paymentStatus === 'paid'; + const isPaid = + item.paymentStatus === 'PAYED' || item.paymentStatus === 'PENDING'; const cardStyle = [ PaymentStyle.card, { borderColor: isPaid ? '#4CAF50' : '#D32F2F', borderWidth: 1.5 }, diff --git a/src/screens/wallet/payment/ui/Wallet.tsx b/src/screens/wallet/payment/ui/Wallet.tsx index ad5bf46..5ee3a74 100644 --- a/src/screens/wallet/payment/ui/Wallet.tsx +++ b/src/screens/wallet/payment/ui/Wallet.tsx @@ -101,23 +101,142 @@ const Wallet = () => { if (isError || isErrorAvia) { return ( - + + + ); } + if (selectedType === 'AUTO' && packets && !(packets?.data.length > 0)) { + return ( + + + + + {t("To'lov")} + + setSelectedType('AVIA')} + > + + AVIA + + + + setSelectedType('AUTO')} + > + + AUTO + + + + + + + + + ); + } if ( - (packets && !(packets?.data.length > 0)) || - (packetsAvia && !(packetsAvia?.data.length > 0)) + selectedType === 'AVIA' && + packetsAvia && + !(packetsAvia?.data.length > 0) ) { return ( - - - {t("To'lov")} + + + + {t("To'lov")} + + setSelectedType('AVIA')} + > + + AVIA + + + + setSelectedType('AUTO')} + > + + AUTO + + + + + - - + ); } diff --git a/src/screens/wallet/payment/ui/style.ts b/src/screens/wallet/payment/ui/style.ts index 78ebf6f..a971ac9 100644 --- a/src/screens/wallet/payment/ui/style.ts +++ b/src/screens/wallet/payment/ui/style.ts @@ -69,14 +69,12 @@ export const PaymentStyle = StyleSheet.create({ zIndex: 10, }, modalBtn: { - position: 'absolute', height: 56, width: '100%', + margin: 'auto', borderRadius: 8, justifyContent: 'center', backgroundColor: '#28A7E8', - bottom: 10, - right: 20, }, btnText: { color: '#fff', diff --git a/src/screens/wallet/paymentMethod/ui/ModalCard.tsx b/src/screens/wallet/paymentMethod/ui/ModalCard.tsx index c39c72b..64bd418 100644 --- a/src/screens/wallet/paymentMethod/ui/ModalCard.tsx +++ b/src/screens/wallet/paymentMethod/ui/ModalCard.tsx @@ -55,12 +55,10 @@ const ModalCard = ({ if (supported) { await Linking.openURL(url); } else { - // Agar app ocholmasa, default brauzerda ochishga urinadi await Linking.openURL(url); } } catch (err) { console.error('Link xatolik:', err); - // Xato bo‘lsa ham brauzer orqali ochishga urinish try { await Linking.openURL(url); } catch (err2) { @@ -74,6 +72,7 @@ const ModalCard = ({ packetsApi.payPackets(id, { payType }), onSuccess: res => { setIsVisible(false); + console.log(res, 'url'); const url = res.data.paymentUrl; openLink(url); }, @@ -120,7 +119,6 @@ const ModalCard = ({ style={[styles.sheet, { transform: [{ translateY: slideAnim }] }]} > - {/* CLICK */} setSelectedId('click')} + onPress={() => { + setPay('CLICK'), setSelectedId('click'); + }} > diff --git a/src/screens/wallet/paymentMethod/ui/ModalPay.tsx b/src/screens/wallet/paymentMethod/ui/ModalPay.tsx index 3ed0a4c..751d107 100644 --- a/src/screens/wallet/paymentMethod/ui/ModalPay.tsx +++ b/src/screens/wallet/paymentMethod/ui/ModalPay.tsx @@ -1,3 +1,5 @@ +import { useMutation } from '@tanstack/react-query'; +import packetsApi from 'api/packets'; import React, { useEffect, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { @@ -26,6 +28,9 @@ interface ModalPayProps { cardModal: boolean; setCardModal: React.Dispatch>; payModal: boolean; + paymentStatus: string; + packId: number; + paymentType: string | null; setPayModal: React.Dispatch>; success: boolean; setSuccess: React.Dispatch>; @@ -35,15 +40,31 @@ const ModalPay = ({ isModalVisible, setModalVisible, selectedId, + paymentType, setSelectedId, + packId, setCardModal, setPayModal, + paymentStatus, }: ModalPayProps) => { const translateY = useRef(new Animated.Value(SCREEN_HEIGHT)).current; const opacity = useRef(new Animated.Value(0)).current; const { bottom } = useSafeAreaInsets(); const [load, setLoad] = React.useState(false); const { t } = useTranslation(); + + const { mutate, isPending } = useMutation({ + mutationFn: ({ id, payType }: { id: number; payType: string }) => + packetsApi.payPackets(id, { payType }), + onSuccess: res => { + console.log(res, 'url'); + setPayModal(true); + }, + onError: err => { + console.dir(err); + }, + }); + useEffect(() => { if (isModalVisible) { Animated.parallel([ @@ -83,7 +104,9 @@ const ModalPay = ({ setLoad(true); setTimeout(() => { - if (selectedId === 'pay') setPayModal(true); + if (selectedId === 'pay') { + mutate({ id: packId, payType: 'CASH' }); + } if (selectedId === 'card') setCardModal(true); setModalVisible(false); @@ -114,7 +137,6 @@ const ModalPay = ({ }, ]} > - {/* CARD OPTION */} - - {/* CASH OPTION */} - setSelectedId('pay')} - > - - - - {t('Naqt pul')} - - - { + setSelectedId('pay'); + }} > - {selectedId === 'pay' && ( - - )} - - - - {/* BUTTON */} + + + + {t('Naqt pul')} + + + + {selectedId === 'pay' && ( + + )} + + + )} { const [success, setSuccess] = React.useState(false); const toggleModal = () => setModalVisible(true); + console.log(packets); React.useEffect(() => { if (payModal) { @@ -39,6 +40,9 @@ const PaymentMethod = () => { { const isSmallScreen = screenWidth < 380; const svgWidth = screenWidth * 0.8; + const { data } = useQuery({ + queryKey: ['exchanges'], + queryFn: () => exchanges_api.getExchanges(), + }); + return ( { : { flexBasis: '48%', alignItems: 'flex-start' }, ]} > - USD - 12.267 UZS + {data && ( + <> + {data[0].code} + {data[0].rate} UZS + + )} { 12.267 UZS/ kg - { > {t('Yetkazish vaqti')} 08.25.2025 - + */} Reys - + {packet.packetName} @@ -133,14 +143,14 @@ const PaymentProduct = ({ packet }: PaymentProductProps) => { }} /> - {fakePayments.map((item: any, index: number) => { + {packet.items.map((item: any, index: number) => { const price = Number(item.price); const weight = Number(item.weight); - // const total = price * weight; + const total = price * weight; // formatlash: 0 decimal, so‘m bilan const formattedPrice = price.toFixed(0); - // const formattedTotal = total.toFixed(0); + const formattedTotal = total.toFixed(0); return ( @@ -160,7 +170,7 @@ const PaymentProduct = ({ packet }: PaymentProductProps) => { - {/* {t('Umumiy narxi')}: {formattedTotal} {t('so‘m')} */} + {t('Umumiy narxi')}: {formattedTotal} {t('so‘m')} diff --git a/src/screens/wallet/successPayment/ui/PaymentQrCode.tsx b/src/screens/wallet/successPayment/ui/PaymentQrCode.tsx index cac1304..5d08287 100644 --- a/src/screens/wallet/successPayment/ui/PaymentQrCode.tsx +++ b/src/screens/wallet/successPayment/ui/PaymentQrCode.tsx @@ -1,3 +1,6 @@ +import { RouteProp, useRoute } from '@react-navigation/native'; +import { useQuery } from '@tanstack/react-query'; +import exchanges_api from 'api/exchanges'; import LayoutTwo from 'components/LayoutTwo'; import * as React from 'react'; import { useTranslation } from 'react-i18next'; @@ -7,21 +10,48 @@ import { ScrollView, StyleSheet, Text, + TouchableOpacity, View, } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; import Svg, { Circle, Path } from 'react-native-svg'; import { PaymentStyle } from 'screens/wallet/payment/ui/style'; +import ModalCard from 'screens/wallet/paymentMethod/ui/ModalCard'; +import ModalPay from 'screens/wallet/paymentMethod/ui/ModalPay'; +import ModalSuccess from 'screens/wallet/paymentMethod/ui/ModalSuccess'; import Plane from 'svg/Plane'; -import { fakeProducts } from '../lib/data'; -interface PaymentQrCodeProps {} - -const PaymentQrCode = (props: PaymentQrCodeProps) => { +const PaymentQrCode = () => { const { t } = useTranslation(); + const [selectedId, setSelectedId] = React.useState<'card' | 'pay' | null>( + null, + ); + const route = useRoute>(); + const packets = route.params?.packets; + const [selectedCard, setSelectedCard] = React.useState< + 'click' | 'payme' | null + >(null); + const { data } = useQuery({ + queryKey: ['exchanges'], + queryFn: () => exchanges_api.getExchanges(), + }); + + const { bottom } = useSafeAreaInsets(); + const [isModalVisible, setModalVisible] = React.useState(false); + const toggleModal = () => setModalVisible(true); + const [cardModal, setCardModal] = React.useState(false); + const [payModal, setPayModal] = React.useState(false); + const [success, setSuccess] = React.useState(false); + const screenWidth = Dimensions.get('window').width; const isSmallScreen = screenWidth < 380; const svgWidth = screenWidth * 0.8; const svgWidthProduct = screenWidth * 1; + + const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encodeURIComponent( + packets.qrCode, + )}`; + return ( { : { flexBasis: '48%', alignItems: 'flex-start' }, ]} > - USD - 12.267 UZS + {data && ( + <> + {data[0].code} + + {data[0].rate} UZS + + + )} { 12.267 UZS/ kg - { {t('Yetkazish vaqti')} - 08.25.2025 - + {} + */} - Avia-CP - 223 + Reys + + {packets.packetName} + { }} /> - {fakeProducts.map((item, index) => ( + {packets.items.map((item: any, index: number) => ( @@ -207,9 +245,7 @@ const PaymentQrCode = (props: PaymentQrCodeProps) => { }} > @@ -262,6 +298,45 @@ const PaymentQrCode = (props: PaymentQrCodeProps) => { + + {cardModal && ( + + )} + {success && ( + + )} + {packets.paymentStatus !== 'PAYED' && ( + + {t("To'lash")} + + )} ); }; diff --git a/src/screens/welcome/FirstStep.tsx b/src/screens/welcome/FirstStep.tsx index 089fe6b..54dce9e 100644 --- a/src/screens/welcome/FirstStep.tsx +++ b/src/screens/welcome/FirstStep.tsx @@ -177,10 +177,11 @@ const styles = StyleSheet.create({ }, title: { color: '#fff', - fontWeight: 'bold', + fontWeight: '500', }, text: { - color: '#fff', + color: '#eeee', + fontWeight: '400', }, nextButtonWrapper: { position: 'absolute', diff --git a/src/screens/welcome/SecondStep.tsx b/src/screens/welcome/SecondStep.tsx index a7a2e08..bd19209 100644 --- a/src/screens/welcome/SecondStep.tsx +++ b/src/screens/welcome/SecondStep.tsx @@ -173,10 +173,11 @@ const styles = StyleSheet.create({ }, title: { color: '#fff', - fontWeight: 'bold', + fontWeight: '500', }, text: { - color: '#fff', + color: '#eeee', + fontWeight: '400', }, nextButtonWrapper: { position: 'absolute', diff --git a/src/screens/welcome/SelectLangPage.tsx b/src/screens/welcome/SelectLangPage.tsx index 593cc2e..074e15f 100644 --- a/src/screens/welcome/SelectLangPage.tsx +++ b/src/screens/welcome/SelectLangPage.tsx @@ -39,22 +39,17 @@ const SelectLangPage = ({ style={[ styles.logoImage, { - width: isSmallScreen ? 120 : 250, - height: isSmallScreen ? 120 : 200, - borderRadius: 20000, + width: 180, + height: 180, }, ]} /> - - CPOST - + CPOST - + Tilni tanlang{' '} - + (Выберите язык) @@ -93,7 +88,7 @@ const styles = StyleSheet.create({ borderRadius: 12, }, scrollContent: { - flexGrow: 1, + flex: 1, justifyContent: 'center', alignItems: 'center', }, @@ -103,21 +98,21 @@ const styles = StyleSheet.create({ }, logoWrapper: { alignItems: 'center', - marginBottom: 30, + marginBottom: 20, }, logoImage: { resizeMode: 'stretch', - marginBottom: 8, }, logoText: { - fontWeight: '700', + fontWeight: '500', + marginTop: 4, color: '#28A7E8', }, title: { - fontWeight: '600', + fontWeight: '500', textAlign: 'center', color: '#28A7E8', - marginBottom: 24, + marginBottom: 20, }, button: { backgroundColor: '#28A7E8', diff --git a/src/screens/welcome/ThirdStep.tsx b/src/screens/welcome/ThirdStep.tsx index 0ba3320..189d6df 100644 --- a/src/screens/welcome/ThirdStep.tsx +++ b/src/screens/welcome/ThirdStep.tsx @@ -174,10 +174,11 @@ const styles = StyleSheet.create({ }, title: { color: '#fff', - fontWeight: 'bold', + fontWeight: '500', }, text: { - color: '#fff', + color: '#eeee', + fontWeight: '400', }, nextButtonWrapper: { position: 'absolute', diff --git a/src/types/firebaseConfig.ts b/src/types/firebaseConfig.ts new file mode 100644 index 0000000..eaca98f --- /dev/null +++ b/src/types/firebaseConfig.ts @@ -0,0 +1,14 @@ +import { initializeApp } from 'firebase/app'; +import { getMessaging } from 'firebase/messaging'; + +const firebaseConfig = { + apiKey: 'AIzaSyBEwWi1TuZBNj2hkFGGIaWZNNDCoiC__lE', + authDomain: 'cpcargo-aee14.firebaseapp.com', + projectId: 'cpcargo-aee14', + storageBucket: 'cpcargo-aee14.firebasestorage.app', + messagingSenderId: '1030089382290', + appId: '1:1030089382290:android:668f0669ad4ac3f74dc94b', +}; + +export const firebaseApp = initializeApp(firebaseConfig); +export const messaging = getMessaging(firebaseApp); diff --git a/src/types/images.d.ts b/src/types/images.d.ts index a66972c..e6a95ed 100644 --- a/src/types/images.d.ts +++ b/src/types/images.d.ts @@ -7,6 +7,11 @@ declare module '*.jpeg' { export default value; } +declare module '*.jpg' { + const value: any; + export default value; +} + declare module '*.lottie' { const value: any; export default value;