From f1808e35b3148b98ff612e3f06c81f5b82c9ad37 Mon Sep 17 00:00:00 2001 From: hknsh Date: Fri, 1 Nov 2024 20:57:42 +0000 Subject: [PATCH] feat: added load and smoke test --- .swcrc | 1 + bun.lockb | Bin 503232 -> 505056 bytes package.json | 8 +- src/app.module.ts | 12 +- src/kweeks/kweeks.service.ts | 2 + src/main.ts | 9 +- src/services/s3/s3.service.ts | 6 - src/users/models/user.model.ts | 4 +- src/users/repository/users.repository.ts | 44 ++++++- src/users/users.service.ts | 11 +- test/generators/user.generator.ts | 23 ++++ test/load-test.spec.ts | 146 +++++++++++++++++++++++ 12 files changed, 239 insertions(+), 27 deletions(-) create mode 100644 test/generators/user.generator.ts create mode 100644 test/load-test.spec.ts diff --git a/.swcrc b/.swcrc index 3e08dc1..24f65fd 100644 --- a/.swcrc +++ b/.swcrc @@ -1,6 +1,7 @@ { "$schema": "https://json.schemastore.org/swcrc", "sourceMaps": true, + "exclude": ["test/*"], "jsc": { "target": "esnext", "parser": { diff --git a/bun.lockb b/bun.lockb index 598674e8b2e6acebf85abe71392d7efe26c872f7..f203488baae3eaed1a2389821e09b2c6b28b12ed 100755 GIT binary patch delta 94010 zcmeFaeSFU4|NnoUr=9FIR#pi`l89=BuxV_r!qn1SL8a0q zm2{=3x2_dxl}b_R@~x;;lHy(JcYnN&Acw<$K!EaKab~e@jA{I zUij#w&vu=(;H)<1hCb|f>iD`J9^CiINeiAI@>+E0!!1)%E;(tzox>I2aiLH}{f}(PIwg9dQ zJ_Xf)SV4+U9+zKyExHOAmphr%p->0hPWjt_vgAn)^GlK^OfDP~>U^@TxH!L{IA?q) z6o};e9=$$gReni88UMXyp~~nf{!O*c${yLmjVq{n>z-=M%Lc{A6z7c1#YHwa{iv3< zJ)=Rz7vvUC$Zb!B#H*Sg{iL{tZ3eZn=4)`8HCGO(@&1fjG(L1RXnwMv9oMWPzKxA7 zaK;}AS6TSV*c^%;bh<6A4=CHEff|If9i9p*{RvkKC++jQe{$COTxdl%3_eO8k|&3nKPM;m%?pJj_(?>CR0eZoaBb@*5};@jHV zLYlSnCq~Z-&-Ir?n^p8U$F>Z2$y3W?qq~|+nnm}5a>vrr{Bf!+@q^Y z*SE7Ra0#diZUB|OJ@LZg+?;XAMUy7PI`YQ3HvMI3wj(1!d0B38aba&{AA zflxs}V^{>rbO%YGo)v@Q#knPglc(o~{^((s^q)aF%~zl%8ben&V@fEL+RHjyY-L?S zh3e^P&NBH^@@YPufh+$nw5CEm%PAh4m(ODSkKQ&S(#JN)z}0{aa8>k-!%=;$smD7$ z98`nH7LQFnhnaO9`NU^}%Gb4@EPvOpif`8V%?s_o-S3){Q&K)H_i;(JeL&)b0JhTAuwnt&Cl_gRg4&H zJ*;e6?i9uMhime82i4tk92QMrs!U4_wH;*ZfEN`OP7XDJ%REaWHvOIcG| z*u=Spf>dzl9NUmqpfWT9RY6@)_F6c`t_0VBn$Z_AXlh8ww47-)wWJ4J>Br?31;cQ; zOE(o%2UtYapU`v~c67*ZRri?uK?G&mUZ5a-d+2R#v$5d*O}YtH>vVWr5xD=)VNRyGFJ&^IYp6)uIV+*itNJz*DL zRHnlxXNWrrY(;G^w-x+Jf>X#arf^1y4t-z1o5EiLPX>2Uuque{GArTD;dg>Zfpfs1 zL!i=)0A;bBpc*`pbyVf|2T$auvMv!i_TF6?3bg>wm}L{*0xDx`8h8}A1708epN8NI z(zPM}MNkb|4ayhYpyO=6&y!Cb!g-Qo4y~Y{6AiAed}#d@vE-K z{;KFkC&al5CY6`uPR3#K3yX8d<(Gt(`qm-~!Fr^h$b|xl^W<#Ew1{7v5&Q zKXz1)J$b}Vb*U7fo+N=X{hLc&5ASeZ4ayhB78Xv*#{%PXN~YzHFAsftXDHMX{bBG} z@LzXX3%m;|{TCqRomjbnfLfX}G3a1u?%meZrFZ-7>$j?SkNon{=Rpm5EctD4wJX-1 zo~|9&p=$(Yg6eoNsNxsgZ}mB#cyTTZ5uZHbwK|S+xa9%64!&WrqB3Xt^!!2+7UfS7 zg!-E2M)e;K}8dw}Gpnb-?4nz37^KAA{1_>AR9wi>za(VGBNW>4kZs_K zhi%7RCw-FErxysQ#m{4TSuVDRJpz{nmVt7aYag*Ke;ri%Fe4^Q{1UeO(N%UNR?`W^ ze~c~*#awPByg7UksF9xf81bhPm{wkto6ICgdE9192GwKjUCHCdgueB|$26>n?Tnw0 zP0i{2q)l}esOsK9m%UyF)s1s$htf@>x?{kP;KDaR#mCa+5+8IscXENoEVe=YZQZY^ zjIGok3ziR#aqLqe)j*8Ng z?3evpk3Fd(cJjN1f%cF;ebuh}>p`uS4>`OE)P_{cEMg*m53)x2Ql^NT3_)f>Zt=BU9IuAU0*}JA4IM{0 za;^HitnXLvw7ygYD&K?O*ptBuSI>mpDHXw^Sl91u&l{3J1)lqZ<;_6(`dP#u4eAOY zXL3oXnd8TRDma6D8p4S@6pW>Zap*_EckH&7ZTpig=QvQ7dIh~XxNtA_ms6DIOrD&N ziAwg`(_0Rxp;$#ijp0D>RB+TjYl&0gXT$&a&K|bj1b zaL|xPX`#k&LNrJiTQDk1X^;wx-7}3KUJV};tRA7z$F*$(a;B6Q9p-MR zV;eH9KqqJ&If`?p<@$FtPN?{Us$|TMol*Xb4+s8y1zbja4wMa&6T*S**LY)K$>_7+XOL zP(99m*%~{GcvUdzSUY;LMS2)qmb(B{fsY<%d)&jN&ud^CIvA9t`hhBE{PDK@k)X#M ztQ@2OI4+mdKE@eaCe4A&@PmhTUMwG*>Sm->H-ZJ@i~J#;<$R4Z$-*!6Af9{8=+R(}A~%2KhL@k2M_r=!bNV&7x@i6CEEL4h*q zU7&jW_xs^k1*0*S;{Ug+`Pdgau`Bu5*BWX_Ma{eU*vTYzt(8|=GKt69P}rGp4`I!| z25qfxwlva!8+jYWLpB)q)SP$<-EXB5hS>W z3YB3osDf^E{Q6Yu?FC>n^lO~{|Ll+)J0<_*=QL|rv81bQ*SDZ1pKkp5CZgy9xa{#w zy7dfQYtxd@gu-Ci4fXD3?Nk?3e>Z{Z#wt*oZaYx<_jI=dc9KhHdf58@l@ZieQF$)` zEgEltGW6h{w!+wj!q8r};O^*}tTC4=D%FJ?1BtGDv4X#$9C^rx4xb0*+K>0P^{fB` zyQ2r|_Gk1^9`Jr2n=rO}zYbTAo&>e)#;!_YS0qf~f4dpUEt{4+C8r?w!hW^^_k*fv z7Z_|r#B1WeMSZgLOXuTZnv72qP(_0;uno8uREAecr~*#UvJEWKwFRHp;YdvmBe_O5&Y!y1O#Z3AU6{*5^9L8pC?7PF*WSv1HG&i)^$+yoMVDp^< zs^ObJnS7nY$DAGy>U95ewjD}by-$!K_HExSi`9Yl3Q@gDc$} zQ0e+zVyk75DjvrpeoJ)K6WiaK*z~n3j~(uRNIR-V+WN~ux#AR1>0<*>z?Vn*;vg4Y z^;~$VP1hZi-D2g&wt?qI+wRA@w=$LV~qSsvor*XF-S8W2SoS4B5z~uljLpTG_e>H%! z(D}4R3C;wyh%K8C4xJA6$+HdN_Ar_Ir6Rr&DjYL06!Ot!i3Oxng^X5^zrjSidd7j$ zf6lj-`U9@j7+U3rTQ;otr)zlqV(W?% z^QYz0$I#DH!@<+kHc-oENr`RNtE5*ofB(AiMbhakvl`S)co5XcyywcluhhC;>}$)L z;TW!>^7iR=Dpi46uV;XoyK84y%dPEykXxwbAXIjl zZO}eY_L~CAr50SSk?qC93yIXD=dQ38xCc}L^FUql6ocy7aECoXExXB}PN@yAcw%^~ zPmVhIhtr-*y8Xsp!~fWM%Fn+}Yp~?C`S;{q6gs$leP*xgTVM9#jZdU@+!=nNb;@0d z@lQO`XX)wz*AIVUL$CVL_^)n1VN~6tYv1t1*33sE-exWz+fi(Szi@Pl7pY~RF>8s1 z+xuQtM)*QMGb~d;K$_ z{o+HRp?)GI+)Zdu5c-ACfFRTtx4+1*&h8Qy1e9zip$mh^PFT=}W)r#~(B3{2YQn%< zEss!d#fI1U-hhnoZ+<4fll>}wm-!p{{jl#1%n1MLXY#whU&Ze`{Ehtn*!KoyL>e9C z_ZyTR9`08S%81Tml=}Mf2d0I$``+M;@FjjGzqj~RgEJy0)b}?HP7javy^AxV%kYe=p zSURkZzi>c`_Xw=L;{1h!Q=*@V`SVAoMUTN}dn@GS66!$;J5&$&nZq)|pZZn9GQ1>? z2j>wJ^0Nn|g!6rGct-dhKXZ77*NL@4d5D>n>TevL5q$(D!_OL?7Tp~SMb13l?>9U> znvb`gA4EM#sE0b(_&PjOTQ$xQ!c{_SEWszo&lz!AB%!fCZ$!E`95=p*L~(MW=!3An z%Iy6_s26%IKWTW1*NGiaZHf5V!%{p0yHLz5EDWdm-lz;Og;|jrE5<8?bqm<$fhplN z{zg*lMU#o+{3J|vHn%ZiQ57Ga=2u;s;jKgKjfNQ~rpB|Hs{XKS>J5g;!r@>V$$Ri0=tg3vHJxU>#r#AkBFK))rRBPa2rw{Q>I>3mWJ3Zf?t^;mpz5 zuyccan}?)?pYyB6Wq3!QVoPRVakleevK;kfrG&5cGjlV%XVFw!(0OL$Mzm%vLZOam zb!D+=9xUBY9G>RgPsr6UFeTF9RDaWWM)g!HQYg*68Ri;K$KHXdV|9YDY|_#iCGd4G zAEv_aYnBxJFfYUV08NI9`g9@Epq0NVFFicL_wqBMx3F6Y56_49Y;9o?OH9;qiV|VMchd zzp*gGdxe<3HXUA551+N3s-6#nS-(^dZv2ZeF+YN-cebyM&yEe1d~XQM&Ph$-8(}IX z63oB#Fxi1AJci}WrL1K(w}au@vO9gG&0}G5iNL#~OJQC7tO04>mkOar13z!awsZl^ zj^j)i(OSADq{cy*mjlwGJA#m$wkdT7)%)3(rp6QMOzOIUL*5LN{b|`5v<0RH4b4SY2Gy`Nc; z5j~l_7x{_()4U==@^xk;Uiu_VmDmn_2jh>}h?MZ@epO|LH<`u5)*{0#hmH5Mu1xce zqUVE1OJgZ#DQt9*lU3C_sXHf^fNeH7!c`gGRusF}DD_D_tl=1DIzP(acvVJtmG51h z;Wh0^`Q)^#`PDF2cR@<{d4D4*;%K~P3l76sMh)!ji<|dQ2a?RK%$YZyHP;q3K_x z#zSPwVBd(Iz=G1tPh_s<6H?vGRh;?(=|L7b{I@VU4Wombq-NUQPy##mWWQ=|hPM*U zrk5=%4$i_f)zkiL$dwWA`r@vxFXN0`wSe znH|@8Fz42!d>ba)5;rg<`iGdGm6sMC=2tDr@RnZ^3XM3_w>W~bTyXOD`oLUIsecYk zmJ6B9$1}-bU2LiJsP;&kG8k9y0~iZEkA$0X>atOG%d>1XOs%m?(;k>g!Iqb&#$OsU zvsQ$$Fd2|VgibsFV2~{vupcF(^I^GIiV2# zL={QQsr&uRJ2JeV(Ns3;%Y4?CF}Assy&yFnf{E-{N8`p)RNw<62x-i$58Muuo!o%{ zrs4t*i#8gEj|X}B5>i9#GH?w{K5BdZj8efE6;8F^_?gQxyl%PH0C+K*74KGaM$r?) zBZM^8_;ddh4jh?xXLwV`$LyapEj1n@2MvbU`xAC9jA}1U@j6ei2^rFvDc)_c9>j&T zP)C1(bqlKKlo!*r&XvK`RL(3Hr|`&Ib#I2Z6HRrn+`W?;mrtR=A$vF>`5MN<5ATA> zF80W^6{ai{L!n1aw1v_vW?m1N8p-g|*DJ)-5N%-hXLwH)#e6-9g?4Hzsn+ZZVXRx~ zD}~+xQ-1<8di(#1!znKOLVf zD5#|UWwEqZ5n>9^UiuOK!q0pp!@J;eS8>qOI9RTq^>A9myTVUcmF}fqVZGjVaWTvm zpmlIREL(}a%$e3_z2GsV95%+!dL%9S5uq+YBN|@mn&V9(X9_B*Q}bkAAqHko(J|(Dbanfu736XX`~X8Q@N({*pNIwN}TY~4mt zeDqI3BZJV0IlNErCqCOHjzCTz)w@QfRV(HY(yR^kq-Zs4u=Mb`e&*8|(d(`a@q)h6 zeMv}8$V#4<5^Xb=S)x5HI+D<(L7D#`#0WgmC9WzIDh#A62nEGOHy_fv&5LEYlTblW z_(|87=KNKnnLT?l56NDPxpsLl(JVI)wHR>ZUnUO8} z&D6LXxia^&o=)>_Bs4shD7p(~tx~$c6%&1xP@kYL3wi0*&w8#)908l^146bb=icNr z?>0glv~0EEulfSI|PvUs6%uNa3?r(f4!`tjq)DBM1$1b+B4AZii4S;nceX#FDZ-R9&Sq0%P zJfkPPoE{ms#P9cVy0?6Z-GO)%V~P9@);Y+-{Ef7{)lYaOJz8`t$1y+gm9)rxxBBxC zwj*RnXuaUJP>2;FxRg6C^w%dB{S5T$SKoa7-I;|S`#-+iIPUgPC{wwjg9xPsp&MhG zx0R6Q8fQqXa?w&o9j2W>H6Ehr5F9U~WA9)UwFf0a*8R2E?1gpktFK6loOY)_@3nNV z{$02U*{~kAEQfK-#TynbOz|2lV-mpF+Sm#v!cr^@g2I z9MD;28UP0nLZ80dqmnXt~{O zab=G517PigO7!$J8`c))1dqs?;(HF=5#OlVLLF?Ob#x! z&%pY@g6qR*+)5d_dPtggAt4!z{xeCghiS@UzE@Jbjj&!YJ7p6evCBZ6pr04QG@XKN zFS6hff8KlP-usAdBsupSx5{SVOAvV}EQJgSel|C}kUl|f4sVf!NBvD((!E}f#)cw^ zv8#mj4ARRyFT+N|tUtDR%=)7}TUNk$CK-?x{>9JyAj9kNxNSwS?nEjd_cwiz9$ELe zpRhIE``N`|X1t~S6V`W`4|v`*Scl;Jww#bUj=yu0`rQ-$ywT}i&nIp3m{^Q@1x#JF zuC)%PakkAn2$L0IO!z*ltw-3nDww(zZ?d`Gi4zN+{M$Zd-P=x(=`fW*GnvFsz*LvL zciRK&0Am~$q=ujN`+b}qnfSCn@8fiDY{v<7W-ZQ~MMyQey-%L@==Y-hCN!RX(k%JJBtP^0IA@5ZS2 zazZ6R?DvG&DA78;pxP9=hLCOF*MX)|QeTXvt00sgYL>D032EkYP~r}Mdg~ahzojXWf2{ZWeU%=K ze~pdN&-yAYI-bzbAoSd!(D56X#DO;XQ0OH>g97dNjj_-~LIVQrAB1>_ro4KabZ{o* z4JDLDYj|!cOo{lL{C>OAz1I!i9TN+A%Lr+j1k=ac0n_S6`iJ>u;Z4g}Nti<8 z-}L8wm+mb=Y)cZBHTH^)u(JZD3&LMvXZl&g(!3ULS>to}J3l2d=PiHJ?sV^&w`0pc zmXC%u2P<<$ns+WCwSifgmlC;hv%l&4^ze_q_d`ZB;~kl7{@}Fet%T^*4PD|1bR)H0 zAv?VrV+%K@M5e#%_xmy3dmeEFNg^hxKa2Ex);PBKN$>dyd(yqf5Hm<}V(_H=BTOxb z*IbRHZ}B(nNsrvL#ZUMtJ@V-mzaMbo`~JM2(!Gn{w<|J_eh;UH-}e*trhCVI5S#Z} zD~7{5sq$duSOAk3!b(%TO|Tv?yXn{4YTF()n`h8Wm~3z3Zi6YGWm{Yv+bGL$(zaNA zI=&5oWs;J({FLZjFg%MddcX6%UoyOzAKG2Wj_-%CRMKL*QK{jN{7t{4M+Sf7C;XZo zx&I@-->>Q6-G0@t8D7tiV~g{`@3<%3?kDU|k7jSjNPgn}H1AGA>LNbCKyHEY-7uyr)B{VTeG4eC(*tp<#Dc)J1+p)9k zN|?4o%U=CAcGMTK>7jh1VWVOxqtC(8{H)xx@Bu&b_l!u#Fa3GHr+Z(1X}{rb8k`$S z{~7Znoey4sr3aSM)|IfsjZ|=y>IdsgTvJ`+d2hjn!C2?nQ(Avz4|2>zw$Fty9pqSp zNck14Yb;-+!`FVopXrg(ul;_1rh6}cZM)VWNLhEM-Dqvg+U(*9Ey$NmDYIdHVx@Sm z!+MIDh1vMfH$0@nf*mM2W4G2k?&~8XzBm2CVJ7eQ_F*9sd}*N<_&FP0nHIg^2YHRY zn_EnXl@9GkLfoNn+u!y_>ot5EI-PGrVcpF9xNw&^LR^-R_5dNi2PbW>J$7}a$9#!1 z9hM$^FA+y*bddJ^pJFxKLuh!Q9V9d^$baiz>-U^-*v{XBan(C4Et>FiuohES9--br z+D8k!PF_5#JoSHPS~xidPo}%>p&dcAD2AU*k5k(4D7r^jXcH+2M=*9fV5{ctZOVTx)j#kWYy!VjD&FT zh{(eoCRhrSSuqyI-wV4C7Mv8k?))8!UNDTsLOuu9*H7d^Y#Sk&+xEM0J)4S)d`cJz z>p`3~_X?OBT3WONCJP0(uwH}2@Lw+N4TYUcoP83x3DzEFpRrzn9rCtll)pI9*{?25 z^U?_&(!CF0f7zlfe;q?^ln}IPE=+@2%OvG;CWoc_)#KB=`t@VOnoZl!haD;*x&X!l zC}+a0g#MaWrzY8!+O~~?9kR0b0PN75i+%y??pOcWCH@%egUkuMbw124Od6(lVd^*r zV=GBKwx-ur!Uhr-41MI?V@*Oc-0tM#YPvuH%r-8mBsCtQ5wmTJG^knF6|nPTg+*V3 zT^Jn38XR9ERkRewcFh&hvxMA;aH8A?JJhpC+lFRSbDA=vVc30hr^ozzV25lGsny8L zJ0+YRxxSIvB>bq6NoYZyHjQobdAi|ilIbwps?ChRR@jiBjbdk?5Hn3ShRTO&(XjL2 zdDvgm^AFfL#3lI)DKneDP@*YsXX0%zw-4}^%jYopOoQOL>y#$e&p6pJ7e>O=WBV9x zVDeTjq{gRsufb&5;H%z9gQjLvE9Pvkrr}UKzj{Ynw3HCLDW~d{gj5Q%=7tpSYsZ*h zoW##K$#^hI+)841O65%Y-#45g-1PeNab;&);BG~{_6v~Mmx1q zySP*HCKJ+n%ah9QoZVn5KX~!P`xi_r6z`AW<(*Em49m0m6vKGAV^o^=Dxr&lR_OG1 zd~54_T=3D)!7z;hBh2~UhpD`v1aF&Tw)6&V4sBsrcM?n~?bpz&Ve&7|>2IgTLsTTk zdm5E;x;24y%gbRlp_@2X#!)`tJq~>%4Y{BdS=b0 zbcbn6uyF<^bFtI%ofJgtvYjurl4HAtyd@iEs}u8Ks=z*zybIF^+al|pWvjEL^ntkw z$Tth7@wS`y)3Cqt{Qy%J>iG-#^6zZh6kEXv#~4(;U%3IMY{AR9(N|&J^_1wfYHQa@ z9DyCa9Hym!ZH&X@GqA3Kd;dzPBRZ3GGp{PNJJbXw=@l@Za+m}!5YptuE=+=i_L`Df zHZLHg@d1Os55DAO5~(YCLx{j26Qt0K=0vBc9Uaq zJ(dGa5hNX1k=0;@#%ysp5b@9!iz@?mSL0BESwTaNj004 zb8)I2Z%z)FX)7$pBqnlU-`ULT#+p^wIUE{g=6B=FTupGO4YoY@P;e%}i>>u3qPi*b2l-5XsLl^UkCEQQgA9l|Qq7acVq7 zk6?@ng*NGKM}sYy`8p7$4GshI0QewGDPi2^g?j`C4ty(fkzHEKDnlJ>V^aX;~wVOUOMiyC7+i zOFqx$!;kURkubHv_G#H6rZs2>Oon2ep-;)Z?Q~|N{|*?5Ymce=bV>mmkAC7tOcWC>akq~ z?|^A}!Fu%gJ(ya@8lq*rpB;WX(?-G6E6!}Cyjx{EWvB5znCr%msqyFAT&yB&rv)&L z4ka>Hn_=4YY`Yp>U|V8GbqvhaP0B}MDv}kye@gU67*9Pfb&1ciW(Wo-S_EtBS5FOO zEyJNj3wf$XRaOl5Vrtxlv?lo0WCS7GZ?)t;m~sS14PLH_ZN}<%)BcCXh?VS8*t!0E zZt3n;D9D2cL_dbHo$`gkF&EiJ*iML3S&d&>zWS;$$IqXrxdU8z!+o3MK6H`FA96N5z@mF zo-i-P`x&P7-m;E^tl8)VzE}!VFR*`UYIu<8H3>j>lFL*HZ9)P(C zLASq!*)iC>LoZZW)7$MkA0}6}XY%`CH6}Am?r2X~&4vVn$6w(XLa2Rkn!K5i7ITdA zQi@m1-#i->l%+lPRhT(0h7ydj^o6fFv8|# z8N$hWIfj>F%PSoVTqwE**2$kgFU|X2Axgkj07QlqyoZJ7Ma3U@LDgOw*H; z1GoeqW#)}$#BLsCr#{xI=I#xqe)6Qj*}D#ZJ5GIJ4On3Q9C%&`M2_lJ!m4#tFe7sky#6RG7GJNfMHGaAO^<`(5v zLfT4kbu9lbOxB|f+^#nr8*@+k=S_6Xo}V6sS?Ax(E87t3xvXfBR^!aPTnte(&bkK1 zqUhIPx@feXpPFmeC|lT7FjdQX%~uRBG&WNWWPRCxnCR$YX-*&(~pB5XJcvlMKw0uF*4h<44<_fecD(~82em1` za&e@jlqOSbeb$vPg4stS?MZjR4lN1Z`!Jc7i90GazR;QjqPkXFr${d85emD`Ld!Og&@^Mm!CseIt0jh!()Q zn#5u*QpX?$8)f9yVl!_l8DB59PG*PaJDb-DsjYT^kDg}Ti}i!9 zXTh}I6323VIZTVUEnx!;*P(>?(wM`_wR^+<8t!LdnWlOo!#&-0gSpQ!Bo+3TBRvY! z7Gqnw52gzgTTki?jAE*%QUW1u6zW3kQcZZlv-l4o^%@4!0 zLfFT(`j>GghS>whY?xNNdM2qQcT_MtRpKtU?!g-i)Z7o|9AYm|{4fnRj-)LbmS(D( zbH@JYig0L{4R)BxxY%G7!E77+kYIlsY;)zIU>U(ItF9+_eh`e*uP_OhhtI9Rg0f=p zsfovjy@T1QY_+IciB)}5*S!d+{RlxK72w&t!4Sk89kXbpCf7M-~m-&(Wio^8|Uj_9M z%CLN^9i-!%>frOAFrF0expap^)wd=17YA%0DENKCwN2KQ;f9<$L!s^bsM(+Lqfbqg z{&}EURQfOYkzIE>U8r{N<|ks-QEYQ1+ry9WCw}y)iD9$j%5bv^mA;=JB|E^6J~dJL zzXJ8}sQBObQ8@=)x|-;r)mEavp`nrK0?Je z1La1ixcC-MZwcxnRIpVTuTbDLC$tvfBUG@B<26wgoPjP(cJYTpMV;m1g=$bc$A!v& zPK66}bP+XC2~wP16E*N%oi0?m3{X-xrymX#)!oGl)u0LxbxKI^y z?g~Ca1vyg%AEAProC4$|6ntu8oSt!}5}}GXAq2=?9(-z|;@OvjkFb^*c@;~F6gI!0 ze0ILzb2wDgOc#GRtV8^4;?oL0J?eC!8vG2XeCt5vd)~#@ zMCmU!AwqF4IegjSD-zAVtHY-S%iC*C-XNLJ;ZPlZ%f$;7eA{uM`nSdD?>qg!Kx-i- zRGtr9MxlaR9T%!YAA&N#Kb`)6g3A9D`DD0Vpo;iL%bPymxQN|S`P4-9>?ibk;2#bX zC`}g8KTfPH$EfuG1yykamrkf)L)l-;RZ|xsRDmZsE>r_rI4%@#?fCxs4n{TKcMn=b@4*+bjvG(fP@T}peCvTJ*MN$@7Sze(M#mR`%I|~fz~X>2{ z0LY)v3a38|$^wr%{c(r-KX>FC&w?7-7oGmH(>H-Cw_3XV?=6==|8$8ee&69opep{@ z@y|hhgwnro_$8=Q#CI-Us0w~?_!Fq8pB?`dRKtG*D-`&X0DnSZa;e}5r~;x6<3XjX z=lIc}(kD57oa4tkYy_&D#*Uu|@+Wi>zchVYJN@)ptk5!1TLfVzP!*l)Fx~0BK#k=E z;8EakP!(JP)&<8qJ^|E6sPYOxN&0V=RPHp#XE?m97WP-fl?ZCtTo-X2DE&rIV|fdx z`F}U4A$kC84Zh{@SCBuUfALG{!(97_kJpok1>VvJoPO`rWOaoOxA5dd?5y+p= zAbu&sa1n=!AM3bK6^(QJzd<#0g3H%3kATK1!N694h`G*#_mGd^~S--2@eJ)oq0{L&(D5L7{bN^}@D`>y9% zO*Bj)sy6~EMQs)OKcLdpaq&V`m+1K6P}Lso;)U9mGC?`mMNzkyU5ubKm+(tdbsVU* zWeTVYrhzJGI;e~@K{a$1s1d#1@dcpL-vVmUyVvmtK^br*sC$G3y>fzLrU^H|{DQ5pW}GVE{}c7dw++aTk= zqx9YA%J-v-|4*p&KPjE&p8{&>UYD^ZD&an-3)S)ipep*^>Hi5;?m^NiX)T%4q4YR- zF#i>h5OoO-hiXV2;#F~iODB}q9|J1>I8Y621j@Ucg8B%hH+Q@SR_I^I3$=9_I)W-l z|AL$vlv4;C22cf`ilCmf2IVPdxr9Q+ zpY5=%(}ikad#9h{u!D=QiE3D9bTy<4sCv4&bloZlsKVZ0WAIW?3CDoSIKlCWpguxX zJlS!f(ib{?s?%$t%Aeu%nkcD44bVq;Jh%u{hTA~({C0;+L4Aa(@Gek2x!37J=?^$A zRQyAr8oUyePdo*x+^0c46|q2o4N%@7LJfEaRL1ulz7Hzn2cSN}M&J*iD%$IGq2^>A z)%G`(MeCufoWvl0hz%%j0|X^F!6i7+VG~ddISEt`n}e#bC8&>3&eRT+gQp73%v-_@ z&Gom0<13V>2b%CaP@kHp#`H#4nf*ZV^BrCQs_qLxZTv$)eS}Is0#y2uj_0^|q53jj z|AwqS1pa@h1e4HZ?Wv#&Dt1`na2lwF&j9riszK$B3l)C_sQfdX{ukQ%4-;W~bgj#9 zI8?*ty9yS#3KqKbLREaTXK^)xz6_CTp>K?6}M27b<$0X zBT(gk>U5#ff2Qv@byVH$BK}{ZD)^pqRrIg?()9lmlpf48VFlwOAq*;k=Xio0w~$bW z{RW_V(AdSF;P6CHAEC-=;GZ@{Ko~YnZwoi{lx94g&8Di-YMFvX=8O79G+oO2zfCAg)9KoHRdR6!YzcLSBNhvPj# zeT34_b9!&53uT8ar(fuFp~}s6`T&Om6Wr1=5J3eF2KD(rLG|cjmrtlA;}TFyPma@t z!D8z8_!!DV^pOxOrl5LI?DU$bib~Msa#y(c!=XBICGkqH^2KL4ewD+kL47I|(4M*2 z2{lnByUpoB6?i+S^XWsN;vaGPDo`Jx(mm?<;ZXUWu<;eKz`vmic#;G%;WMrvp?dNU zhtD~^CMx~~rwf(;RZtafbohpgx5)S_phxu&U4&2#_{edg3it%n5Pb=%q8%!$Z$AxOh_m0=ZqfPZ4?h51&7cEqFEet9)42susJWdM+pPHz2QFIk?v`e4l(h0S; zGys+Ecu?Iq(Q*FaYWo^SQw08mTJuX8&U6Wq9iF8~K0?`}o#Qo84L!%{{|S}9lS|jB zuA78^3B>+e0&9U(mqDmtPkyPPeVi^-12RDwyuZ_h>iIkj)l+>A32+rW7*v5n zKou|)jGBVG*!NZbSg1b#4XVTAT`?0t6+g-47pnNljtf=o6vu_yJ*GPjT8q^Xi2k<( zhvgD8+)peVLmk`)i}3m1@r?gDp?Y#LKSGYiY&+X8$6$o?uQ~XM$RRUylHggO(T0wIr65_kvENwylHggO`{`k8XbAlhzIr~ZyM>1BX?P&SC4dH zI@}vZI#^5BCC8CBjqHW)kvENwylHgUH;gn{^eU2W{g1q9bmUE=BX1fVdDAGkl4__s ze?Gz^ZyL!MN8U6FUOAE}j=X7v5stiRq*np>9C_2|$eTv?aqP&OM#0{BJP^8Zx zJo2WId*$fJn?^_8G;(j!9PW)HeH(n_O`~A#&>Khm6Ho<*_KJaRI+&$fAC-rFj z=4bD(zu>7G{x~{eUv%P|BfdQAtRJ7<-Rj+(yHme-zyEQo#&3N1rrLRDFFyX{k~I%b zF8n5?Ws`5Nf27{mb?$ud*yqFMj){?m6_q<~8e99uRxf1L+4RT#@APc4rv1y0K0Er? zm6OV9H9c@}LGOCA#`b$jiZFn!n3q64SDIOtO@D8r#Y zj@CZ_u-$#TtKP&dxbKrqGv4gg?#7F{x7_;MyT=~e>CLz1E_(Z!aTzVTzV<_lD@)s+ zQ*gz`qQ?6!o&5RqA#41eXG~o9Rqa>KIIeiv^)nv){Jp^@Yf_|<8C(%LKm4i5o){To z;wMKE&FYB=pPTR`gf$X!Cn0=k9+Qw)fY4wv!VZ%&8KKb>g!K}>Hc15t8zht#AnY

HtXgLMpTQhYELhB-gEfRK{=7k7bCCn*A_`z(JFn20K$0CG1W>yhGYB9nN342Yu zsR%nIESie2&wMUnaS6hC#R$Keg~bScry=Z^RuU_O_y_)3KHW+F5+3uhwqtw7i(p|Rk&p?hmc`bT!#=pA0hF2gzje8 z^$2Sutdr2wc=HkRZa^rQk8qw@E1}Vi2u*K5=wtG4K-eImT0*92d?P~H0)&}2BAjnF zN@%?hA$b8pmMLF=uvNl#3H?o*g$Q$RLYTi0A=_+|km@6Jy$NBUsk#Yar-a=S2Aj@4 z!s43|mih=o%q|Ii7a?Tbj4;eBxfx-6%5RBO+q3=ToSq~yCF-smq*e~IrgxgH!LkP&Fq2A46Da${$16Dq*{XRi@432y>r6 znEyD!V`iI#)F%@JCp=%;XnNd$i`h}l2E1pJ(UrUO_HKcga3|oV+M#4G? zFB@+yLf$h71#1!3o3#=eJ&Vxv8HCqN{xb+0Bveb-Xc|9@Q1%amna?7;ZZ=A2y$&Jy z9|+Z^{2vHgC2W`QmT9vNVeWGX^VcD4HrphmK9A7#IfQpj)pH0tCG3{4#dLliVetzH zOP@#h!0eLH_eF%P7ZA3YB`+ZCmvB(RM<(+{gyk#iBn6(lby^7FuJ;K)}e?7tm3DpvInZ~ao zl)Z*9^Hqdz%|;2WHy|XxhOpa|zlN|?!gdKim^K>_=59oozX4&7*(M=%6GGRG2zyP{ zMueRbc1zf2I&VT){5rzYO$fi5T@w1ffspk&!U417b%gyA4odjVWWIs0yc%KU8wdx@ z0SQCjL>O6(@TXZ(jS&A9LgJe`Z`3lw-_&_S$~qJT?=6z#y^T=t7DCjlmC$H2LesYq z>X`hu5jIGumf)Gjn-R+1L72H2p|05|q4m26$?qT}n(}uLwo2G8;b_z5U4*&sAw5^tnyU8@c1qYSp@HeV1!3{~2urshG&H*;^!)%K>wSdAX36^q`z0Kd zaH7fl0Acx7gq0s4G&Kh#4Bdt>aw|eJvtlbk{D%mM+Yp+YVcQVaNLVMKh4DT_$omMP z;6sF#X03!qA0ssV2;nr7{}I9l3DpwXn8qI?lx;_t`7y#7W}}4GpCBY}M@Tm1+Yz=( z*e>C0)8-R|xt}7;{{*3(*(M?NGlZ_6BAjEYK1J9mVYh^irt@bAi$6zL`WZrs*(IUx z7YJFOBXl-PK1bLu;h=;xllcY0@-Goqeu2={9FQ>dp9mwrM945JzC?)Mfspu5gzje8 zKM~eQSSO*U@pd5OeT7i41K~WgRzjn%5t@F5(8uI|g|I>ltnUzpnI+#L?3Zv*!X+kiH^TDo5mxR-7-< zp~O_}L)a-{w}evD`4@!6zalLC1!0ESC86(rgsfi?%FU8r5%xLi}$CiT^^FWrqC=VU2`!60SDhZwPt6BNY6GFvqNw(C8pS z)87%UHTl0IY>-ebp~^Hqh*0(i!pwsR*O`qHTK|cV{0G8(Q~n3SRteiB+-TbT85y!@ zZY|95Cw!sV1~;kUT8WFg*5dfFsHzsm5Zw)3WIBi8izB388b&Z?mxR8x5V9f&OU#l8 z!hQ({CER8*YauL;Ls(f0VW~MFVQ3U#WE{esWaXdnqhcGi9;UTk8LhA&CWDjAbDfbYz zO4u%8m1&cJFt;wk`~-x@%r*(B^$@z&MR>wg)kWATVYh_UrgJ@n#fb<@>mfXCc1h@a z6hc-a!dkN=5n;cCgA$%KnMWZkKN?}>Q3&hI0SQCvBaA#6;d!&-XoUDAgv9y?FPdTX z5!OgpC*ft|B_ZS;gHVu!u->ed(CAo%rpF+>X7Z0g*dU==!ba2hScJ0U5M~~W@VeP3 zp>+d<voTqJ@U};UwqXeWpv*gZvLUi2VeZqa^sk~HAI4%2zm-LUe z#x6xRn^_bae#dMRyldJW54>lp1Y6AKg7;15hQJ4Ap-VHv&F1O9UU8J%W!- zW@BKxStj_z91w6jasmyHZ$eL2pFmHz9XSzUjfC725x5>*dl@3k!A>6CCq7t!0m{Hxy=zeo{Yfl z$jJz)ry%T*!0kwLgq;!=HAmofM8e`022z^gQ*e8M8kroL1CEV8nf!h%Y z%UdE0J{5u6ky8V?^rbcZL)=S`aq&30@38k$OxE+yDb~-}KHVE8~v_WWn2ErBz+>V@%uvNmG(-F8G zkudj6gpOw*a657aLTWO?4hh_joQbeg!lE+~xE+zO_$-9;k`cHaNk-^V@u zuwTM`XCZJqB4K%3gu!PcG&Rf4Mi|--A=(z9naOU85Z@kQwS?v-+zw%lgxq!rEzDyQ z^3FkM&>o?s$!U+!r~|@!38$H)a}YL2C_M+Ejd@W*Sx1DH9T3hiQ#&BE?u4*KLb7Sz z5n-!@IUNzsHk&2PO+o0`389^t)d?Xr6=8>jb4T>-Hr+cT?3Zv~XM{AfN5b+ngu&+`bT!M)MHt!zA)1DeVY1T@;=3ZOmeAdV zyCAHQklO{Jr+G|5UOGYp?F{FcoURCsG7#2F=wp)75jIFDO-INyFG?uuhR`wt;e0bS z1EFv2A_v8(kwd`m}I8*Luh>g!WIbyruq2@TP4gnAED4}mM}L9q2mPzQ_ZXk5K=Eh*nyB$ zqW4|hC$7z zl^bqcoBhl{8gR@@JK7ZQJLRKi%=QcUKOehhQBkR>%A%sh{i$fTgc+vu zg$R8wLRfksLb=%`VZVf|{s@!a50aj5iRW(O`svfe6={wGuW+XgUa?%H$71D7zS;TEcav z@nD43Ll9;TMwo9lO4uqP`C^0{P5H$LbB7{qm$1;Z8G?{H3}OBd1mA3vuv0?Up$Lmi z)lh`R!x45%FsAb`gua&`EFFfh#O#u=UqaS!gxk!L;Rwq|ARLsi)MQ?QFmxos%1aRL zGzTQak3twZ0%4h1F#=(Ygv5~u_n2WL5%MlYSSR5=q z!sK6yP?m#GE#V>4cr-%mF$gn9BdjzVC2Wigdt6fKnCEyaSi#VPLAQk?r;d(S2bB=mXTdq4Ny zKi;%IX7-vjGi%oP+H+>(>`*hr*{Pn0^OLI77H5}QAWoEeDb8+HtDS2%+y1S4+POZn z(J2=6a$PpHR4um@a*r-osYIUSrUd4ePOi^{oaDPS#-#(1bGLTs?yj#2U zm)wo;C|meezd^21t||U*W?a({>DrvrPg{|ofX#@TWvFYQEqH6Kp{}FcOv!KA)cQfL z-x#6A#<(VSoEb$_iPFr~2vO1FTpQb4&fFR>-nG2D!8dLyd>#1?L(&+&aT1cWW3O&q zL+RB=_HCV_Tm$TmCdasfLsU@5i0Pb3%&(8@9JEl4XF)8;ua=GE${3RRWREsA(W-NY zfR4S)-<`HQ$Bhi?>TcJswj%Q+vq;NqJ!gn~}>J+%%HV zB7^__D%Zq5$uipHMhQcLjx9R1K@b;%CW(jG4Mw!@ky1oV&azU(ZIVN^TlQ+j@JG>ozyX%<5z)2`DpxQacfOOnr!wdwPRawcqKQ%i+r<`$-JdNTvN^ zWViDtxU)C0xp-{t(ckr!Eye2Ari@!~Q%kaD1=xplP?vVQwsbt=XRWC|=y$Q9-xM7? z^zI;qnaD?WjBGC(i5so3lM3JOdduFcpUQK$+ z2e4_HJdV&byQaze^0AsG*CItKb&tsWdN(xPaJ;BfjonUIsC@LMMX=yag3tD!a zpeHn`4pDO+P4m)xj9MRVjZLTd zc50dvzmG`3Uq(%nTO#H5T=~m{E5Vt-2u;hP`7%QrscC*DEy8FVqckzAX7q#cFcl^R z%mz(@vx4?O{&GSPC1nF0guq{*j+-5SM}tDuXj%@Qi)gI|Ynnf_y4F1|A)1&IVj6wY zLhc8aMw1K3g*eidLZR`$OK$K|Cs;)D<$?A})4tHOywFY&QIeFawH z%+JF%O)Rcy0np}aS_w@n0BxnFmDIFAXunFI;;)pZ1>u*2b@CUkX~Fm%(4-fXh9=b% z5yC&eXsOF;#)8leX<9i=llkOVO)IZyVbJnvS_MsG%5ony(1- znu+wSFjY09+;dz@GuF_IMWNN!w3?bGA0hfu(`rGJk`xE^HLVUb{+I9CxirwU`Z{h& zXmVw${56oDhDn{20&=IF^wWl#F&zIYO>3lSrJ-4O_I;&kWuSelwa^%v^p>(<95m_U zEue`O$_X@|T%RuamM4GX{!|>7Hkw!g|0peCTTQD7ZM3GfgC-@e1nS|JzYdyK8Gi%( zG8S~gl}xGt8Bt{{Fs@n0tqSDcX35{Bi)O5bf2WAgUsp}5j(;+K`Lix%uYrG#rghhR zHK9oy`Rk!+weU|eC>(s&wAwsR)3jc43AspE2h7sM-kPy4&+|c6&_~ni;a>pcuP-#w zf?V9Q5D4Elny)_oML_=gX<7sPOM&q9*R+OG{#6jLr?qrq z{;V$B7{6S%Bm+sL=4*mqF5Qy9A)3|{zqgJ%6q*R#3>e?n5&aL>jLq?%qaVuvAw#EV zrUf{!`?d_7LTd?j=}ctg6ro!I>+a-lHD7CJ)`ibwHLVS_Xr10TXvTGmZ6TH+K^ZhA zK;(ayc0ex8lR;yOjx57(fX;ZTrgebkp=sYilhSnrsWol7=IaD4t)?kW>n!c>zHZgu zYoe(BjP52gG_5PNlbSYD)4D;E+fZc?nx$#o@n3@`f3r2M2mbq-CXH4!*c0r6R!Hi9 zt|s<^cu+IW)3n~uel-|rjGER5n%o;JBiI5>>x+M=j=NCPzJ@kI(-vvkH_#?)+G3$e z{r3ZzAL^Jls@244;YT5v36`;vTw@lLp;;*4;%QbBfwAwnZ^*I8$ovE>=S)U}3 zyd&Of^{>*ABO%Jyx=P}%*0dq`t@HY8ph+DM1q-Q?(zxq1Z5aM((8}O$&~b<3pRQ>e zHQxwm%A`en__D!Bh~I0*&6;r(v;O^42iTL;9m%k`YlMyde zRK(wIXyTm=CHmg(f57ubS_B{N*%X#9>XG0a3b&43kGRZ6@=aXpdk->9d+5mW%?I($ z240$WT+`-2lk{XXjn=fe_~l|c897gwvz&v~`*$NhVu>blH)(Pc`3G{L-7Gr#;iO zZTM*`5iZh&{?f$l_=`v?{Qa$IKjJ?FqzgUQv>o{6BW2Qs{?W9Z_%}k6zZaVJ6aMX* z?H~xmuq+7j(CYsp;vOtp-FAF`q#+NPg=tgLL z6l5Rtb_6cMl@Ejn-+s_u(_A&}fYe2G>RlR-nhX8+?LPry^~4E&{%>~ZsLbQA9_a2wnKcfma%cSp-T(qgmdPWj}H z>ED4|a=jPGW!c-ndLZ_SKxTNcQHV_<1VkiJO%J-ID?XAiSww#gv}cd2TxXz z4T#wx2k-|uL2e*shxO{{9=G&arx0x__zp}1(}4otgKxoDca?On+p&n!)KwW!7L)_! zK?NY+zL5qbtyfy6G(>55($KtVX<}&b1y1k;G39f3$$^Y$azg$+u<o71Ji~u8n ztc>Mzde7v>!N2hQ1A0Pa*Wn_Y4B7Rx25mrF&=v)V8}Js~f>ACRjs_>dNpKp7-QqVOHyv*VTY;D@wgWL$EC36^BCr@N z0ZYL$upEf#Lhgg^BNOj8c>00+fW2TJ*bfeXgWzW% zHju;M2xviiEkP^L8ngkoQOq5157d+2mWhGH4%~n{NCXmtPzKO2PzV$T@ob6?yJej%tBiSI0g#o%60i&`2P?oTAPYxX0LsE(BNzy}f@YvOXaeMp z)vs}7_t_7W=D7@z+oiE;M7XrU(+GS88Urz5Tme@>Ri5SA>U2QN7#Vm^;z{PatNFBtR@1kH7^`3W!xh ztQe=jF|Zr-0}=iC=OW{bm@e*udq7MUJwY!}0&EBSfLJIFflXjD5Uax&AeM%SK&%Uc zKo>IX33`FvK(6G-2*ju$#(}z^9%z`D`fr5iDHtGL4=q~;sCy?c> zEPG{r{f_#|P5oa7vd`KBWdAJNWm)$f0J8m+?d~BUTU^=E{seXbF%T>U%fNClj&#NY z`MPW{CPn}~W%0^~brvK5w3$o)f{3WQYzjcOn`PeQ42(*XIj(R1(uyaMll9lCrPNxr`{6Uc|4{!n9%y5)=*OfnH5 z5)1)D!7vaEi+tEhz9rQfcmdfV%jS0q$;}5%K{L=Cd=2F5bn;QLyp%Z~xCw57o#;wF zEG!=xmJbxmp7k}!u`h{mIfdsi*aKsKAe+)nU^CbXmVl*TB;b9qOKs2_{t(=PAT!7a zT0!eV#mHUz1wjx900n^TH}itF2-zNV1WzPi8BAZ`DUD|RK@K3Fa7qunfe(<6T!nxF zAQ5N1eL%x;w=W7z-AzyUls$Ym~aFsz!-24tt|oF zz#$6v6M5~EF>4?mF-~$s!lec%3wl5=gj*C8)6X4Hnb-rbQ}Rr>SwL&TE~6DO*X@SB z7wiY}y~kTXzCd{ml!sOcR0dT+C@26TGVxCq-~-Zw$CThKrHTe(Pk4i7j)Rm8A$yD~ ze8F0P1V(VT7neE+P+JQj8c0fJ z{=VK9)NJ*O;~wcITQqcgc0E}gh${Z@F2oF+*G(3 zU>0*sGLQ(k12^CRuD}j3zu+N3+^0aEUjRwtE%*og4W0wB(uiLmJg?>Tm^{1!FTooi z0TNN{KH?YQBvTPC39j%b#;t-Y_98jzl>*4>O9Ygyp=>E-9uOOoOh{5VY$7gcfY?W5 z3n^R4G_o|52$^6IW0V-8q$yu*QQ42m{4I%BB24zF;))R2wLb^0s9#1v**eN% zLY{Nu&q-X_tLDZ31%9FX;YwAgnz!5%M@WM>46;Iz&82WiWAWp;sKf#?ipWw#-aLf> z*?{`NBP(55+*+$$sWVxww8Fg$WaKFZEa^+(FA1dXWQkMSPDha990E~b7idC2V^9q= z0u4a}_2iaY`usKV)&^BTEl>kg230|IPzfw1iP4~<3cu}EfTQ0%Zo8$=RE`ko#lwLt zCB}nspgi=lb~X5-TPC&twws5&oLx=0CTL8)5surjuZ)W63dgO^HN8vnn`F<=R!IKi$%0ltO(R zSM~tXPRgkT58OO+e4K21qO=2T!6+~ij8I1(xaG|F4c<;bW|NM%GTeO)`hq?x^+UF6 z5+slPzyQ!63e?|a;exN~qt;MriN*glHjnFZzo$z+~(MH5TFVz3lQ2}Ia+U@ce!R)N*v5Mfe! zNmw+q4QvIQ!4F^~*aWtKAAyAJ0NZ4OlK_dd8%V$&5CwJtQSVPc!ejGExP%G)(X7a;9K zRD2v91&6_};D~mQ;YNcn(h=T)#La|X1fgw3xa5T(iAy4);@SjM1(onu#4QHC0C~Y_ zcnaaZ$IXD74?Ouf_8A-qma2-gZlCcPA31GQ*q1^$} zc5eX@qg8kCx|D#?c51xS-CC&RrJ;HH_ZwkG43G%smd zi3yV$7WF2=p9ENZ{`hs9)J?;TBh5^jkTPfjKrS}H!HA&vieA7Xi^v_t_a3^od{$5 zAstAV#kB@JDV_ATPDHR0kjPn}`DwaXZ?fah0VKX?GIqNkLbwO%NSLG{9Wf7(UT$iS z`nLilbBQe7T}oxCSHeH;=~4notRM&h((!^oAh3F~WK;l%mI6S2AnKRiEj>a8ZZFyM zeymdI>JmxJL=`|Veo06oi{w(5p*)LFB4iQ#g@KgNYD+>d3N3cwWLOe`ML?^75i+QS zYsMJXjlmw+fY=Pj7_>iF_R1QcT zOGzamNu&a*m)%};g^9`1gs1y0TEpIr0ze~g4F`eK)Uuma5e&FDWynNj{uoI zL^4Upnl41;b$PA>M2HSN=LV9n#1o-K*haw8PDA`s`Ubd?X?-C1NW8@OMXNGBMTkm8 z;xBoS(paUIX+si|$P&>inY7*ynUJ}(iRPd&kO4*-vkc)fMl|EODQE)pc>f`+1vI9k zhz}8D?3Y9&f^iHIwCcEjHszG^^5%5Qn@3HpGsK)SB zs9qYhJZ}X*0x`Xb4KD}S!}D&i3;YCjf*l|V902>lJ`iC&i2Exz3J!yV`dKph1^>_B z5Rhk!c0@lP({3)pB+;BeI@W32Q=l*YPT&x@qMtA0UXuF1i01-056*!%xaW9dT2Gief5D zjwdm21$SV$1#Sa7&(Cn*gTKH#@D@A;_rPQD5Znb1z zaYb`!v^xZUTKrz1oDct`2j0LRGVgiGzpw$4tt3{%CR zeF0<?`51N76LI-7m2w4WS zA@kC>;b08@Qn*)%CrwV$knrWQDgA=XtddE9JlBG`Ca3|bgKEH%zAAoMn#kZ>9)A^i z1{FX>P#Hw&a4GFkP#;`5x@W!s>#yiM(CC%dlKFQ#MWYWp3x#diXg#mJcud> z5~)9KAJ7-{17Cx0fRt_sylvo-h5lShS9)jmC1i^It)4*>0-{DRLlfXnU0gMHs!Ehj|l#>G^@XHIWk+`G4w;&Z51IB}K zz!RaT;7$fo<#K#UglsKREdmRHlu9K1i@*iAv%xGd1Iz?6K1tn5l}NV}Ua2li8*}gr zP2$W0^TB$s3=5#akbsq71y~N&fwf=_SPdk6m3BAcZU9m>Tfipp1IUCh zn{lPbYz4bP6xaoR0z1JD@FUm`ewTAE{GASTSHoRjx(nh7WJAAllBd^^NVjHQN@f0zU6qCSSck;aO zRW++uhdnSLI3Og}9!RCY^iNAc+VAkmR_5LA*lJTFa;OYpqC%37=u8v^e^yoDW zY|}j=!$X>^6$Jz$c5skOZgtp|k_W5zIKD;UO9@}`b9?`p?Xh5(AyKfXu#&3g=J4^Y zqZ4{Q;kVp(kInwuZfhD65LSo`+o&NhaE0tF;gc5%QWtCIzHQ#uIoAPSSU`}ZG)*0c zA#@E4elV2CUud8E`RGkBP*sxCF+xO!@`H0#Dj)g0mV`)U6?D0vGCD|GUe_gu;eNI$ z$9na6oiT>txvB+&+(g~k;qdlNP4mVs8~IDpoE>-MTiH2=F}Ip0DHVnxH4KmMbuCn8 z!sQ^lEsT1Wxvi2q<#2>}*M}hm43Bc|N{B&EAd-uAwfim7hC>?xBjh zJF5B0EG6~YI6C{Wm;RaZ!%c}LyrdE2(x7x`YS`{lvH7>1K- zG7MbMwF<{6tDto7y&4;yZSbiXePZ}L-PD!D4)4%BbWKsb)A!}r8zHIA#&F0y%5WF? zsKLc)DJySI9~07;E8-AB252V?XEwH$ z5RR{$ea}KHKetr#FW24hXH2Yo>aDPw&S&_{gsfzBCT5nOk;xR=wpJZYN+-IcY{|&$ zp7O=8m?S2IpPVRP-c+Q=m(8l_Dj2x&lLb z82+fcq{na9dZn@3bhyhuDjWuTA}`fArNi6q?WOvrbObwd(~2dpEy-GZ{ZkFzG13Pl zJ=W4Dr@D~Rk%4>OV#hXUTg#?${Aja1SMNO>K4I@^m~LLDm=v3Zeyf3(n*3m z60$nC#GZ8088v z851In<*W6H8?@;#oFO!bp;!d|Sv`;}&a1;2aULl@+KHX3tcrP3T%$qyWT?O(Aido+ zOY(_9->h6@x21Zcs1E8hB1f^;xb8H_JZ-UdgNF?SD3{ z_3&YLg8@CWM^zE&X>Jd*n6vzW!*@3iZdSF2bOf`DtR*VFHnL&VL&xk(4{{kHK>^f{ zDX_QQkyYJJ?>OdLH=CJBP|3wP1`bP|!N?>ypa^Swb;29@uc&)C&d2c4rz4~C%{o`K zo;O{Dyv*j5U1jlc1lyBkSC5Z7yj5o(x=Jlo>kJw*2B%-R_>rnknM3XLp{kp!Gd`%Q zu1b=DZhl3lJGS+A8+M*MblGl`8Iak>#fu{w(tbxJ%00K*qK(UR8IY`n8k+%;^5-%| zUwdK4eZOA$M0A-PX)TF!tKAtG0Gs4Cdr#sqWfEOpw6HiFk~$n+)Uyl-VN{!sZw7`S z>7BWrTzb?i{o}3h$q)zMD)l72d%8^Yn(XjMPux|z!#?}FQzAm9@-=yGM)Ai9a~ z=6t5wgVV3}?;kX9l-d6g%;kXEApOYbP9gRz`KM=cRK-!%GtnGtsv(&i?R*aem@u~iJ9-Dq9V}>;;SF}1G;K-*6WOmf!($4XIju5pivm=8&bC5cnnS{*d>TMgXB7EI_ zv?J8+S*XI&YD|_7+B17cI`trnBP0G~evWEVo<@GiVI*CRO9jvS8M6AJOj)g-P^q#) zxS(=pC7n~M2~WP4Xr7|saUJugpE`3MO~IQYumb#5XPKX-*n zhp<&tEwbU%28n>s&iHJ1$ZlwwZA>PY+=JDYnRt`n)>{4>Dx<&P{!PFL`A@0jSbS{U8<@dvNNqVDT>X5I7Po*cp=!2 zYucqCVtPs`ABgJ}IXARF9nJ??+T-6m424AUKq6%I%LebD-!ks@5+Qb!ZN{ z)G9THNOmh|f;u5d-B9<$d8CS_clS}5{2dv5FVPC6xwY((y?Ci)sS1;9P(TsMzL2Wp z@5pOwsUrLxetgPdfj?1)s2w=Yx24SH+rL!aKST1@O-3xOoFw7uvA@GRtb4dQs3a=c z`P(0}>}qWk%V@?Cgm{pn|KaT0qpsW@_(@#fggI`i9yyWXFEv)2cWOyaT0~)G`&jaA{fU{LBrFREo}c~jb~jWcwfH9u!&ql^ql>~GaX_(FHWAYHmq&@*SV z9`4OykQE3@7(|FnZaeaPQ6giBD)Y3k49q%hJ8zPtG!y>FeJFpo9rbin(jKc)=SGG` zDz7+gRk8p}q715^kbYDx1~cp#gY++IjgXqEpK~L=k#<^@Dvu-chtBmxbz>@VzOH2I zbwKj>#WU5|=4Rw4J0F*%mDS)ptW$g|t6lkN4!PBaJS16MJ&`FWcK$xTiekx-fB1o; zLAZZZ7^&!yw15i9%ety4*SH$;%);^gkwO|;IC-<>@?M)5SO&`!PT%}R9XI*z5WP|wFrr&j=-uVYQK;uqfQpSO48 zXB5ns6q!*Ds6A3&#?V*IcYiH&v?;Kx#O|9TS`LDbjg@FUTs0{GpW#%qJL{^|1sKW# z)#U<)7V`%ZSW#67WCIsc&(z}n(Wj3!`YW2=Iap6H;c6XxzBOQwzIdbh!xbmzUd1Mf znvLyAV|9%bxNbNoi1fy(D&johVp~T@=!mDq|Dg8^ltVtUbF=-7h<<$uoG@s>|Qmeut3^&CZ>q+M7!-8wd2TUVJ9ru~) z5<=P^@6XfPN)*q+9yK8Fu37*C&3Z?OBX5$oBqZydvg(mgSs)Zd#qD`HC=E4P-*ypa zF2BnwYf(cLE`7PWm*hXT9Hh04Ac`nynpzV^LQ7Q?d>uX(!^5^2zSQu2Y#)dT*~Io* zQkws|$oS*pufjv=3+>g4zRar2Ls3x? zn7v4*#nA2}tMnb>k`@(Fd>UJIbupAOw1puJ47dN7k|(8ioy0K=$5d*{;2Dn~s(6^A z8+V?@Dq})yeoT;Fg;1s^t8*C@Cp}*>|Hq83Y`z#IFi_~3QbsO1zzwBfb|!0Kw%xxE zj++x?^LTDB8>XqE$9H5)vk6t3v8&Lvq~q3_i$J(tCadFx=_RFA#v;V3scPYL zn5OF>$*nK1dv&>2C9Ul_Z}Oy`mJ%YZzwNM%&2M_l?UvT&-qzIYr?u}*h%dbHs8*-H zMm;EkkXuxuFUb74Dk@GN)eXmYcso;*e;@94?!eB119S-~`vmpV7sR@#eiQcLDp^sU z?y4L`iFJ`!G8~)__bRo%{|Z?|%AkY(pQ~O)si2R|WgfOI9nD^GOr0ko=cjG8MDefy z+0?srQXa*aES#Ox+TnEYFtuk9Iag6vhda_{31eyO(yEhLVMVWJ+V492@^R@)VMa(_ zHMtnf!_>Og)W>4@SeHi@j>`BjS1YwMhVN%}8NSfFF!;mpr0C4(Vh%oU@*yFQ&b;R# zq-M6?eG#ZXgMEeUa7oC%ISu zR>t}XHa?8u%cb_zgD*@?wz8?Ff=WQ?qK=Ow zo8~3R=3Am;D2Oc8=D_i(S)+?-fZ5f^Iz*K! z&63UZvuK!Dnl4aL?JG?m&aDjfXyHvsE%^*iAFkS;{H2v;H8Z*v;Bz@^Jv>)K$`M)T ztc&O^k*+&u0n0>SC=a#BxqdG%p7Byk9t#? z__0gx!#XH)BT|dWpdhwVLm{6O%x8L4M|&%}E|gaDr@V1n-}Le9#A53~E5K?FmZG(e zj7Iu_MYkrC7+Qn3UNX+Vnvmmen+`r3bf05(=}3qSAi+J?Y^(Nq!s(b0UDHO>sAgNJ zCQ2vL#JuWatf%QJZ%r%AYQU;d4b*l+^=MB>F14m6%}Yl%o}>`r9Uxv&t!fz^gx3%s z8fo0z;vEny&BUWc-P3hfj;)svzAs`7pL%qRU9BN1OI<|%blfz@Kr6owg)oL!-&Q@DhAnR$gR54HZ^fSG&iq>c$c6n1)W_gxZ9ZeS0ZYHS zsra_*ZN?fsspi_rd&eb?iKWY}XEn1}_N=4S;3CW&k$?Ez!s3uNgyq?_5B(ninU0T;h+zz3O8&{5xYAW7D%^FcPzhhxNah&-Y zXV5+S^qaGe(zmSz%{sNADeWs-9Tw-Y8sCi>FYWm0&1e7x)gGQKE$Klz-cel(sl&7e zTPfR2M><)^#JkjTk7q%Z@T%z3rBIwjjwR%0mom0E3l?jl)e8`F<-zv^{(oCvn62XD zO>L({-8dO=c@}qZP*OS79oOX~*~71aloe@rTNjrd^)Rt0+vrMqiH2?&F(r zqB%P*IeMr35x!UxdkkfcYUf*dlDTKNza?oJTa_+YFsv@tM0H!JSMhQCN$f?*hruY` z{>A2`BmMHDeq^=*-~Xxn1S|hD`u_JZ@xMD5#ra$-aK)UslW1Kx|mD$778+N7XR- zI`m?tc0kRMr)cGu)O^8Um~}&(qo$kohq|}s)oZbF`F-MxIf(d4mCDkaIcJnA(%TUd z+^J2!zL+&!-rdgn*FU|zW*FVluv?e;-ZWkOJbqF8nl5iITJOb`$6$xkG_VG!_q`kr z`|IyjSCVwP&oDQW-nZWcRGHZ4AZZmgEtqL%sD-_;Sx!@D$kcq%>*M<~#vj@6ri|F? zJv>i8Ud=Kh7==8qiuXYa)n}ROsUmC3l<}~Sn`pN=pyW^Mw`isTrmual|~g09TAAGdua!$P#qa-)`e&MnDi&2A8#(CB>VYDZ0N( z!FIF|Z<|rOOVk|IxG!%dkIhk&`l5f+92c6fvGAeJC8EfZGUIwZ-H_IH35o~#nkG0* zI6*0S#ZvZbUXzuXtD1k!#=Q1i)&FZpq`m1p^@e9>`+25SsKc+3FWsv&s$sMvqaE~| zrvks>CCVT;#GLv4sl!8Obm-c`;4nlkGuLbYzx}p&U;Wi7+5KB>aO^xaSmGYj0%cjg z=Uru2ah*|chzashn)1JgJ#Ts2 zNZojkb$Z_PelXmFL29VsjnNV1y&mL)p`h7>NuppsM_cirx#K@po9-m07`3Pci_>(gO3cp0boN3;^aPQsoDi6ACSV9=%XGFpaPF9 zQ^^NXhBM2Q|3FTF#9J*!#cf)yRu6)6_i{CX7-5H(o2uUHdVjH3hSysR*^T@z5JDG= z+_1>6&eno_7FP`6#+3VPxw;^^San~e~WL9s{x zZ(&Ww4u@e#Mj2A{srdZ*`3(JxQqp!lJ=5o5v&^;KTlDJHy<5-TtKM%*H-FIWWFEG9 z>v%g)D(i8@9DO0I;@Xv~2IMfu2~1Ni7x z$f)je;wkh~4r??^c$_P&iVR^)-lVz=arji|vB4Y;cAaTEI7`JoFHFlfR^(4kHO9P@ z`1q6}A?oN5ho61l2K9IdP2(hq@(wui^!DYimW-MaW;8^jXtPT?bVxi4Kku$Z&=!=b6}{Pij#v*LHyX^GZt}KBD@~X zTy88jz0~7H4mZr-1xCd7VWeuYB6SC!>sM| zpIEfRF*p3bvuLMx3vv0+ZQ9y86x*zsusK_jHVxX|+9G9HA3kHwwl>ZQ+i5Ke)qiB7 z)hl4biew3I7{TJ&F=CrQEw;GA8rIL)mcLkvvuts3agSahivyxV0<*Vbz*!jhfVl>RyhCm%hr>z-GYZveS4AY;s{OEFM$+Zd% zSu>c)nrXxs6F=k^+r(x{6{jFM}KIlG1j zY;|#_&i_$T2@pgZ$_gMAw?*r3+cSO={LUmukcpodrk7fn^#y#%DsQb2VE#_dMdawL!LMF3% zzS2?9UTdGqw+a)*_5Et?D$Ybd+^LcVL3zGTY_Dayr!R8ogm zvwUS|VC)*L-^Y2_IA3l2Jyq{vu)R^W)^b!P@j+9F6-B0XukG`6p8Up#^R;Y0od;F* zH54%z4%xB)ad))JHf8zI7>-H@RZY9QmjmV&2i0t0?gz6E%o#JxyR&LXmP|3sQx2+V zIKo!JA*Y_YR1Zr&v{$v!F&qbU$fj9Qzg@VwXl6{v<%25ITB_v@9I|IS{N?ncCr=M; zmi9xT%+lDi9#)-UbdEV}%G|tCt7KWn)Z=FzhHBX|&OfZ?ujTA^ljG_kocch%m&&-# zkx6Tm~w)42Q9yGP@JpCxKoa10~CFeK}5h6#?p3mJ?Zd}=WZH*9q zh!^B?{s5;eEcLe zS~cCkc5*x%UT~y5`R3`Sm($i8!eV&|bXgd!R+GAOl@@wgn+KE2{_(0I9Gv`l~ofl4+Ewb^&4xLAagls0J{LTQ$soltPoJ^X$k-8dlSgn_6 zW`(B9SkPtSNwdkHo?r5A_|-R!b%6rqJl)%kbXxCI%KHa$%yUXr{ed=MS=vTpX_Jol z$7ug|CB7P+goyIfNOD|qN*()w+B8fb8H}GWaAd)E6E)lGjHqPl)GgQBUiEj?bu;x>?{~BQIu-wJbdOUPc3~se8!*rP{i_49#<4{uV{-Fhk~n%LO8w@5M0=$k>=Ryec(cL^t0k-0%SiQzne79*y_JKxR!zS@@AMmi9IH%@rab&R{I<9taq5P9C zs7qVX*!m0R(Yi&AroEoOk52^Sxxs zpDxg+$E$LkzBTeTta6Pmt4VN#C7kl%%Upv&nUfw1J72G9DqicOOCwJ$m6gi}X_sA5 zf!jYT?Y=9j`8LXROql{ly%weg};#;|vt$nw`$iwK#&(xZ2jK-ck%X+^|FR~nZ2rA$x=i-Y*Hrr-=~Q%;*_6@V=bEay2b;^U zKRPn`4!&lZoeoS&HnHTFw^LFf(nc9c9xB%z46);2kP*FjyXe*fM|I3D?MX~nK`tu@ z5wqu}mzmB@ik!PGt?hd#sfBV)b>4yA_i2u&JuD&I9waap_pcuBrJuFvRhD zV={53y>2$i2Gu8w%l~xB0m-C@Vfo*8O-;Il(3!5Q`HvjlY0JSW9boRlG=10o)FB-c z%yqt}?#SZ1nGg|YLB~Rye}38jJ!!~fO(%Y*Cj0ZsW9Lp*8>WfWIqZg6DivDo$}fde z%!ZkfJdmGuPQ0O#|Ag$b;gCsnP?}=FTefzVU!CgYez>7Z!4dZLO>>@nJEu@YzB&as z(rr!PKM>bR-0zp>dGOE8w)bK}vfWY>h-+VeOD+G2<&0Su)+8rCpX9eiK6YJdEv?KN z^Uokt>Dy)zw`EORbnuGZU&g4Z+HG}Z7roB>-JiX|ZB_F&*|ff`0-}i6orqG2(HZ}0 z#f9X?d|~Q$;B8gvH#o=KRw?hnIUP>XZ{gP~7Jt>RYeY;Ii*Bp+q-9@!Tjje9=Po$K zw0UH*Taw?3T#?0*t~09N;|82ZZ>#2T`d)xjnnf$M>|LJ|iD$%cK2WKCr&GOyAq@=Y zN1d`A+P9=s41>oV6}g+t;;VMEBWl5|%+$@@j_S^ocg-O`TbGy3Muu0G!>(F3OW`Z7 zsbja0@k9I4Do#&K(NsFmn^kj-t|&ixD#Tj>X2ooGRpe1(SbDHZ$?^Xzdnsi}VtNqs zUdI6=lY9|2&xpxFjcam@Qrc_WRb64Ux45fzouy2@h#&`q|EW6hQPA~l?PDU0y{mS@ z>0Aj%7C64EoO4&j^D|Pxq35OGd+IS9VfF8sT4=g5Rn~`DzBYe*RanIBNk|Tf+ojL3 z^fP+&H&T}cP>8yxO6()8hedZC9Sx4)g8XjlIw6wp!~2oX9m}W}V+%r-!^GVj(0PU*1={CH0YTNa}ZU)!s9|-?IrZ9IFY* zNl0{?zvfT5`|OPoV#s{zzDl{DxbJk_%b|ZgewjM^qZp3t4~)yABDZ&WmaX*n+sm4% z%8eFv9;n8|wNtUxAL6cipeFI`tXkA;e3du9zjCSZm3l@DG(BWn;{!o2)z){v-%Nq8`udH>znAadWsD_T;m;^cClt3RvEsVL4f$xzqz?b= z$oLsW#YrgbQ5lI}%FCX{_|RhuPqPtKEfqxuJp*`rmlLsaJEXX?vCtWQ5GqAUWN{;iV#3JU^F z5I3IZQXhr?+w+Bg;s39OUpbtxe9oqSo3q-WopmCM?iqE_D7-Ol#46FhN&ImRv7c4t zqmB%p8KFNKXVpg7Z4=bdqb!>A$5L zQoFD z<|I>SDx1w%uDISQRBf@#9hu?fH_`>!TK%mWpJ0gchr^dFmUZ_!|2*X&8ytEvnQBv$ zPOw0nZBzSkS+g7KC6ANXT_WtN{7E)ZA20TZ&44f4#WWA6KXjz!9BCmJQx^LiS5@;o zKcT;JlA7zJUL&6t(|*iN1)f6Z+4HE%r|3Y|bR4&etaVRg$Mn-MTg#slC(Px~geF}& zxD~rrLX>2#V)RPG-p--gpQZ%nD$h#Ye2l$0^ij?;oK-e{-k-o~E7UFD`D4OhK)5(HTUkhNU*ZldaeL^CY^(;EH3Zz>h7q!R==cBpbD))ybsaIkAq~+}& zaO)MO8uuGDV5VrX>Y|zH4zaTPmvv*pinEq~my)R67g;~vQ!PXQy|!__Oky+EH0O6! zS#*6u`^Kn1eka57B1uxU{*V7)ZD$oJLsE60HsPG(YBTH-vyy(j{ZQKj$Bh(?ReCC$ zs(KEN{7G%bvZz(}!8Kcqo_z=olrCyFx7rEp0al-5o62_m7-@thoJ+jzI5>oxBADHr zBH>#Xo6!}cZ#G%=qQ{RLjcPZ_Y_{uQY2U-oJA%V*WH6Tn<@U8|bu{NQIqpxN5J`_F zvl*+%Z^rii$@BiJ@r3B^to5LKb2_(R7b-i;1x$$v4*~O%n+>stcl6Ei)6Q{r)#$mb zEY0nL8hL?sLNDG)Iv-ZFAB~SH>%{~clioGxMqs~iTb;YeX^DuGD)0&^>Nf4Hwa;8t zZ<{>ua_RYB%g_FF&BVW7v9=-3(J5`lrXpR{5qBFnbdbaUo0m+ue$uj?&RO$%Ya{dfQGDNO;f77DIcbBo55hWGIvKwzt z{-EWLbf~4b`=(Yko$en7!4K1bC9RI;oR!*aa(x#a4e;o2zf6pdwLVnGKbZ@)!qwbA z9o4Oh{V>2Ly!o>>ec963jCJnvZfAF#=#e6evn8Ew&VBfF{=Cc{y6hSr69(?PM&JD>~XDX zh`+cWHO2qH(D+fWwXerca}z^BxR(mR_WGg9FrY-r{#9RBV>_aba>Gf23y;cP$|(i` zZ6~mLrnOl554Qb!igniWvKhzIYOFc&^@HDhLQ$4X2^clod#U@9hgOZsbjPr_6uE;f zR@eK7I%0@fc*il*UN@a8A!{&eh-s3}W*D|}jQDv;RF>n?-}MzXA9WACc>7GV*R~I< z#aqifXIrw6t=hg>XHSgWzQ#OcYRoVHX@jwL@M@^6L*v%GrBN$8d+YS7{C!qBmIn0H z>U)K@B}S2~^Paxy`9+DHW}}ml?TNa2-{IqGE&M)NdU?n+V_c4BZgRZC(y)3IqfM$Z z<>m{@79XVn5 zHEsa%aVBhn4f0i`p0IW(lbVN+~GmSrlM!FQ`U8w9je}```P<<^Jr)^4Wkl` zwS#eu(I*!T8HBXz(Gw2k=_N+Wr;hdsUFF3>#Js>r_9m;JvI_Rgq^>-rd$-G^20lZr z-MQdY-d9bWQK9`)-<2|J>Xk#kOlmzGzQf>H~(v)8HMXU+%S^9IZqzr1d+k$|ByorR7VmT*oDNx~Bu z9&a5zX-483(j(=yFr(y;e(Jtt7B?yTlFaIh=V!V;Dt;Y>+mrzjxdxMrr2 z&P#kLQO3X;U+0+@dScx>T|yQqoR}T=58{PnS4;mvo-t?Cxqlp0x$Z3I3&wG#o5n97 zugjq(;W~@cyOWEqd*|w3WNeOVB%~{LzQ4Nk0%2D8o3*iQ%!4-mEpjme85>hHvBh7d zc}ZGzooeta_8t>dvzP1?>!~5Han7qf-tOEq^olmPNUb5nd4kH8mDT;$jp|)2wp)yU zti7a>Y|N>SND{FkIlp0bE~0(Wc4e=rIh&g1O`{f%=Td=i`&Q%*m5=Ku7TI~rOCnY*3|(bYps=V-l5-n1E~GF(DbvUi9WUeDZqRf={d zX*}TUU@j%nim0JV!r*KSgN!LXOCOGO>D5$>rkbH^km~)8<~uILtedEP%fI?%5It|OPQ8H9rA*s;Hp=MH@&OQ5m?Avw|W0JZ+i1d}2k0STY?YZLz zlA;~RpQ-$hQnJqsn>Ns0zee}57b-Mu{f8&#r@u(ZV57A{YU3uLXC4UPCJ#9z&RK= z%yTf_VJ!}tuUwu~s@`N}@{+^!0TwtCI2J>Qc`U}O2;Kxv#t@Rg$rwU78FL@u{`F*x zD(vcBP=?#Cu5c%CpC##aQVU#J=ws>F38TGgadpnSIy`D!y>SS? zJh%IzMD^3X-c&TCGRF10I%LSKE9z;UORu$5?ABhDRBMTAPgY6|PDC!5N}2s8MUM$( zGF%(?0#3cn2r8xCh#ckNke72WR$mxCG_>$&&4E_dl~RGE;rlBb(!&az{`PtQ#Has& zLpDMzGxYGLGqWsqn))PM9T5=}pN>gM^c`8?RCiY03O5&b3TUkC8D=IiJ&79X$*1E3#p1m&8ZmX?Bj9;k!%kNUVCuO7> zrN$(653yJ0hCv>kODmh=r=A-0?8MTmBEBxzoyzKIQgpYqitQv82tJLJ=bQtX7t6^joK9HPVI{BG7Mn2v@sQc{Sj>sVdSzb{MBa~+f_iDBV zsznO;X4Eiq9^L0|)WyN2o9didm>U=ThWzW*ZTv7qE@;!g4z>SPOI1xte@R?hWyy$} zwYG}nIrP&(U2d^M9G8IFrUXf<4BY?(Ck`aOBMJfuop|*0SqK1Bg zUm8bb^xpSR3#MY*Y3Pc+`fF`fGnIQ)`?$htu5jMwGBH`lP2W;wQQ|`T|1o}kXBgD9 zlvG&&(_O#+V}{*X-kuO{eoTuTzsxsV*{K|r+FeoCddP3oj27)e zPF+2yVSP|dZS!!iX=jlb?L|%K6B(K6sS>FfeRA_@50PeZy~QhM9B$MKxjF4AwI51| zwB}V~7mOU5;-A*KM1+*7r*;!po%V3&H@D`4EF90JCR1uWWg3e6vC0qESCi6^e;c(T zjeE7QJN3=g(8bo1e`q<_jU5zwA35mg^6Bw58Kk97p4C_RJV`or1J&P?tb7}&wVu@C z$6q@zuhd3Rm+TE}#+9#;y>|4w5!wH(dEdE&R8p@!>0sdvRA5^7JW1-qC@+&ns#aW& z?EExEW2T_}af)+eTK8j4&qikZNcUaC5#o|_lZw``@ zfj95OSuSg`PTMD{Fb%Bw*6Uc?S9@S1RXZJJAJIsS#0}l0<@lpj%GJY;wcMm{vP9C# zUzs)gGDX(SUZv(gw%bZ*ioSj~RJy;lvbz>+fK`}WRFHQ!;k*`RpA5KrysWqx5eq$dX@ zeR3~P`Lu3!TXraEp-fK)xbDbNcjBcVo1bJC#jI%$=N%?Sz`_ z!>AF}T&?y&!By1(ANOj`A6l5&jf(jG&DHQmte{bWv9>hLq*e7>N9QgWMf$?)vb@Rs z%e)X6rPYy*d6u;*2hiSTpaIu!X*SQZ#rIvkR;BbX7^OC-No+FQc`GzT=3Rv0Hx8@?ta3#8T&ax2&!F`p#zuDr(tU z4RK~`sEFaB5t{5V}ModbpCXrxMHqTR-`t(G6y)BKG7;bVWjPg$qQ`iP=g2AfIkRH+PIoZ-!1I&MvrQP|l9RN83LAHWUe_Tte=hdj(x)@q z$AtXVLFLOrE~Y#_wvMW~JbHCh{j)H1Xff5nEbbYck2;#ATGyk}v4Doh){%-VYB#1sGqb%kf+j9D4 zWH#m%)>5alp`htqRpRWp<~agyRX02H+=}w5dv@~a!tf%c*qYyUNvh-fo+62E^DWe( z>?}g#?aW-x!&jB~n7E7|1J8PFc)Ku6mYAIMk`}bNhe}S%(I*wG8qya_JNFPz*6wo- z_%F*d=Ew~xyx9i+=%FS^i~9=>IiPvu?ZeOoMeg>F;qd6G_U2%xvY8Ghd4Kxrj2~Jk z4}bEmq;mT+BkF4ZUy~M0hEyN-wyow*4qCbZXe6|PgDj_D0;bS4Kz%aB#gKqs-!Wg$ zeaADeKRv!KO? zOkNeF@l-I4{{>G@3uwv*G`I|GJyldqpQi~-%3rIdztIF%wr$lAl@qF`D`)|IB3=Wj zrJw#Z&VHiI%mf-R03Qv^pbM2*b4$$h;5WaE2pQ*^>3JZ%Q9u=-WN5Fuk|XPu+jlP45Izcc!ldQO~BI1W_NRzXVagr*rDC z$uqIJP1n+4vlFTahSW|i7N%zyEBO8akKd`%VUsgb0v^x8F7D>MsF{D3H3T+hjM0wQo@6I0EU+grtSU zaJ6hXBnadK$1)r0XIou=amaU>9*_@GU%7LeM&OwbH!OjCP#Nau6n?JgkY&FIRNjKq za?zsIu6n^x`3-l=g&kd_PbLBR;8Ia(f>_t~y7uhC~)&B&Xan4FQSo12)In4Vg+UEPqaW2!ugn7*z)3SZZ3 zdf+cMWqHtnOh7phr3>n)8|js#S2=)1i&Kj-r!}xENFlh1Ihj?dK;79YZr^Z>ZI|=jYs9 zo5{!f8b0@a!&_Rm_LFcEFCN+`();1XbDEb_kA^~LhC-!ZR11a90JnmTzz4vF;EfLR!9@5#@N_WQVItT7 z9tG=z-^7JN^}t==so?VtSA%uoOC4SVo)QX`luoyS(vc2(fpti@ux2P!8!RfEnmdj* zUxbcST9}_!rKi^lg-!scfl7B0SOeThB*D^xIg<-X9=bUa z3Y`eQ3ak~nI8@q@TGaA8z>~mo5~+Yzq*B3)(N(~6jz?*o2Y&*t3a<3`gzJ@DODg4> zos&C0hZ1rNv*%=kV=0oT((_NYrA*H%%1N4%T|8xK_DnUuCXqyyreX}0+6Gjq)i9Q7 zoti%(tB?YJM3-4UarhRfZaf8I?~>Br=)4k~NnbP|AEFXh`ijFR9F7BJr@^2q7(-$; z;5krwPF7*k#Hm@62Ex_->rb-{JHTkFVY?l6#|zZpg<$Pa2^A7h0Y%w)(~IfZ6x>A> zJPE2Hv4RwzG$FTO9J&gakUf>u6oT6+e>G5+Jc#=Va|@FuP0b${I^_)8fP&n-f~<+5 zP#}_T8~TZqRr(A8W%$>Yg-Sne?B5#KvVY21Ho6t4dOru%q4SzpKCU2Zd^Rp}4_x{_ zQ0+-=YUA^=3npc^4Tau!<-F?GsaCH=tFx{7z5`{hj?L_NKSe5y4;>AfAMf|C)~Mvu z<~BCN89$|kZ4(lFCMesT3aZo^4*zuNe+Fxy=TFNn%FW9T<>lt(j!&96 z?QS>7cb#XQ;dfB!CS;GBIZ5uFM+bG?LWG)kl^>4Q^B!zzn{k)lINGYgxiA^%8#mIA zx3-1+*4m#OZ5bZ#mqis>4?B#x zM}3#>tPZxoB2X3Nf=XYDcws?y)`X<#Qzpeaa{q-k{oqvFkrYr~mR(SgUyxLiJtwx% zG;;|)=x8&%2FkS8c5*$;$(lL^3&bYkUng3uA+d!jws1`#zgFhOG=z~T9eI&mdH(^{ zEkPLG*;dpGl<9U6p`P^t#S5|v^QX?r4pnrqOZpq2oMAI4$7bmAXHUc7x>{$8t*k{< zsGdfgWpbzGhIIXdRw(}tutW}$RWLp$m&Mq0w-J?~dR_pk0ry;DD_Y{PLxweVXUE%v zYVi1i@k!@1vnG;Hd>E((*6(R~HBc+aFFmaOS&z_=z`5QgA+i z7DJgf-}i7??GuY9mA*wl0FZiPlvXgVJ*uST$t} zsH!(OK9MCOcUmYk27YAz81LsVui2<%fh%or#Fm;$$F-JTIo)=6O1>@qJ$QZeJWy-w zQ!^|-tH7?2!(IB<;R(cFPd*u}IVirPFcdls>{4XYcSf(PHMJT|)KF(ofGS=%GZbn9 zwt=%4l%57^h>j=2>EIc&?IE!`sDl5A&hA}0#1>fk6XmI)t3Xva2VLdfS#0b1z{U5P zqr)d>h~hk3QO(P31-r>`CK<-%&o0!VZxcKbUJjlCzUT^w?J^7CjnOXyPXNb)L5Dy! zBpH;&8iHzYH`Y;=e-3z>*3{2w0OyX!Zuw!S)WZJDLb38-g#h)~OVUu!cIz}1sOaP_1=TS_f( z`E_=36c!asn@Qg1Nv9#W5mdTfU^B3d%U{FsugI@-TfnoyFRsV_8k@Tj)bkRDqe1nc z_9EM(G`O7UY)}={0dbzvUnkoJ9=OSlbp@yjzP-_QDCHKLzA32uucFJh9(3{7--!KH z(PSrlM1iVcN^xQKR2(KZzaV=;ZeeJSZ!IzvJf8Tm4lf1OfeG2uX3S(Fr@=KuNuY+V zx0_WDF0l=~3#^Gg?lzmQu%xJi< z?QjpMg4&Q?zA?QZw=ge@?W{0+R`#@_!r0NK-7@Rkv6Fc0#v*oTD>;J#)Y5}t+w;f& zZd;a8ZuJ&mZQ{r0=TFI{hZD03i*hFxhj!c%3N=N)6+9XI_)goyjiAzR1!c*HK{YgM zGQHuNw%l5B1V}!A=!uO>o}>)<;R;a08p|^euC~S66l=>2bXj>ksLl@qRmZFqR-Xcj z7i6>8a9v8gR=}`XAdAfMxXVaSe2C^T;7#EDu`UVXqe^o0l2LDrx(WK>V@1J&{s zjDoBf+pqoxSNwIL+++D_+k?+QrQgTs$s!+u;;%exM}@%)_>1VWRLs4Wz#GHog7r%X z-0-MPP*glUI|+yHzs6>~1XRzpPbEzl7m7MPJ3DD&Zb4yD-W1N&)45d~Yx5tV95ry@ zTAMEeRD-@omnADfb!^b%Hr+@XP@)<1GlKAQPzhoQ`;b69Cwpq1hBLN5{dL)ot=h5G zIkx!47QMJU+rT3iKMfUYT1n92zb=BY#qWQ*xc%pA8ur&r`Og=ve_gZA!a^F`DbHJ< z$m8ssms?mgxiEiPd&a-0Flk!;gzQl4KsX!CBmKcGc02f}gn*X$Ee;<7wNd#FF9+4Y z@eX@~GTjBBy#Gw_6!26~V|+X)pDB9LR?zVkTi%nPcI10NR~*ng8z8IUv|pbB@O7fIx;(Z-1MyRQ$kzbu&(kn80es~-4ANE#@g}Ao3`Fn zJFIWsPQ2RP^(~9BrRrI@>=IkD+QQ|cUy&c5E~$Ea!QnDEDg23LmEgM9Z9DII$2MdU zC_`=7X*-_qu5D0J*7U4#Q?o<2x(3e&HF>7E2IaqJ%b5tOLoq&*_~7x!Y$}rBdLpRe zG?#H+g{?5VaD3L(tO?mga1}fjl*I>u>TxsDYb0uc>S_HC?6MID%3_azGWh=YZF%i0 zZ8@*N&(gB-Ac02Ur!+(jDEiP2`Db8r_|NEaourTL(4Pvb!aqNLFRU-!11jH(`|OG01y|3c>}e&zE!xoiw&!g~Ad?RI#_|rJ zoIQj1+Mpf{WKAs$b#VMVuoikI`80%+xmg%b4;!MN0RQuAYuTRP+j3fh>ez?qjll)$4c-b~A3Ph}|5Ye-F8C7I47>}J zJ{@cgrh{$3hM+3`<4bFaT_psRa1E%8H-b&U8K8RJ+wm3jun~L_C||f7R0B6T)5e}f z@GxY25qnQ3;$@lUpa&)&vKGm8`KmKSb3`@{@C91e#1iBLGO{Ay73v;gHY>m%X7aP{D7XHD>U(5D#HyEiUutE2rIsd?3G zI=3v8-b}SBFZPsa7V&D{xL}Q7xA`S%8;~`vI4`Sce9mm1)#y~P@;KX&qP*!-@dQpI z1zANr9n79HJ$rl+#-rnE&@WW1h9ty?1K+*P8FCk>{$ApR14G9;)DA8mKMM>_8z&Qx z&wWwD_ACllPYzI^EWfd)ZD97CT&fL)9(5JOEHzc<8T9MXWtr@}+#=S%;wv5hxRxqn zgE%1^EH}4;s&5Zi6SplbBY{lxhD-P?s05EVY=5GSzZ~cCM_3*7UD|D)?DY7M$G3HZ%)Vc~77VS34{` z!&-7Ls9B!{Y6vEI`SwZ3J7@UUpWd+Kdg@cY183R}_Tf0AdV&XFQ*w*uxp)qLIr$R` z_0&1&5UW`*Ld98m!DQLi#I|R8?u4R(?Cg*_ThR8ffvVn|&`FJyd&XN*`r6rc=-or! zs%NxsHnoO{J;RMX4Bpqw>YJO}hQ=O`#~zDc*TU+tcNq!i*oM78c{1FSpgL@y5%*$R zcCamqRSNN&s_cw`G^LWswdx63Qt*st=VEESuh56jmkR{|E7?zY?Nd_7CDMal*FSNA|@HiNF zFsO=logWUJ0ZwRV9VHXgl>5cu1H`K#TR=_8$J<*6S__vW^}oQDvyyrgzYwgcd#O?a z%2<$WJ$E432tM2CRp;IH%9(!ZQ-HQrmk8kBKYE-kNq@!)x4p4JSkNI_*)D|w2 zyxGaRf}Um5sL-VRV3`e_mu^kl9;p29U1Z0s8eCnU+u7FlG5M&k zr1W|MS|uI>W$V-~wnE+k&QgVG7u$lHp`Sv0%!Q`U)Uzc{KHV4bbxQd_Q0VzhCP%!Vbs$RfGfP`i`0Vc*cm)_^C1VNm`1b%-@+E)T+T3$hDN z&9u{O+Q0tV~va9b_wQ~@_Ap_=HbC$^zQZ2Gv;gTwsaXh%Lz3bd1s0p*H= zK&6ijfbM$rwxAcf>S;IHrfUYuZn1J>@Ag)VvE7d?`xUgmA?fZNYv)*AcHTs7ft|8~ z@=8i47AE0s1zBYzP{qFzA-l!yKrSBV2Iw8@5pOtyWQ?~Jt#K99nqXZu0;-&t!9Ie^ z0b+)52B80H0CVa*TBCKW*Tit>9PoQk4d78>5)YcD^ZF-$++FP?lVoYkOP=|KxG%CjzTqSGUwJn^T=7GtYPEd3Yg!Kp2F_=&wP z<=Jd-3Y*{#OET-qJF1Fn0gt3j=!i3PTy(@C$2|N7E#3h8ua83W3~ zgQjz8(^y^UD(G8eoiXrnZ>q6cY-o$eNeOM!prQKqXj+6x!hWy52ym#feGO0pn6u#;ePUI z9exkg?Aq*bz~0`u_bs~mmeaoJ-Q&%s4PSkKZQ0o`pRl&H{oZi=mL6SiY<}71o7d(f z-&JeviQP_&u5I4)(TMj@#NH^@@b`>O_9|hmDKSngT+7ewlOAs2m-R`H-V){9?3edR zjs8d|D+mobj`vhSXl+&Kr0Sv2s6fjnG(w^9D}H9*^k~y~y%-%u33CYz3PL*w4G2PK zG5z}mp~9-r3xqBWv^to}hQ<);9cT|$g?_CHUCelQ_eb^X=w}W{55Mb|@jKqH;P*g3 zVPJarIzN-&Z~0~XKF6=%cd?%^C_TL1&m5E<`LUM2Y*1Rby`3a;TQdiq3Mxd>i7+YrFm!KYH1{_?(Z3p>@9>bdrKq!p25k{r^Niq zv8mDhgt{x_U4)BvsT!iI{IbmS@RNQ;X1ez^G2Ms>`O60+hr9Zj!_&i8`enn@y*ivf zl!ut%$uh-=^yosgbiaIfYIJKX6sdlyzifC~v@1^4D~P(8P#5(rVImHwEt_HuU|3G3nmxXtHuOUzuyLT!=+gO}MXL zL5ihl-O(Z@YhpMh9;V{M{&JHN&l)RRLnv^LUokd4`Z`)a**V=KP|ct}wh(F+OLskDYrPf}n_1|gc{>~5CV4&!h6>ES{@VS2iEClMJo8O!H(70ftq4oqE-nB`|MH662c9p8p!p18Qcorl4Q#u;GC#Cesw^VC9;rP>=#w^wz@E@_3oS`xF+K$j|zFN<5}h^+98zrLe$fz2^v7 z_t1L#hhxloit9)pDTC^9tMD2>VQzZ#E3}TL{P=K3zie*0_h>3_Q%Pc1kdvrE8N%|) zXir$0UpX>0yudHJGTr+et|l1LQ}ur_@erpCiYCWoVbMQOTs3Co79MK-${HqkGqmVJZE7DTZj;ge>K%m1l8i8h=-?+@ogTj4&%8R_JJ5yliLuN0=!>iB zo|YV5<|kZ}?tO%&`9i(Smow-JS!5v=`l)^eDegiW5u{lDa!NeJc8SJBJFr@|)R23V z2-$8?OyuiseuHb%yfawO>;PeJZ#hg!Se95__rtVaR8vh}-%DbP-=3Mt-Wr%}8f+ZV zpT+!915&-NWKiYISp51bm{M6=zXX#F7$qF#D~e~o1QJoYr>jl z(>I=*>`j363vw^dPWB#$DJ5;2nCu;Z@t@j_t-JKHEoDt&En5Jy-PYJ}%(_0^JBMY& zwVo{>Vw+4iqYuIQ1ry_+gqT@wVA}SvjiI?Tz5u2|?eg~W;W!r7>X%jx(EMbt2kg9{ zX}D~7rk}Zpoes^FJTf`5_fmiNBF=n$V-?_a;c_4kzw78%z-rTdcEOU= zXkS7d1K+-ZkQO*BOtUsA1x)K@N<2jUIxbiU+VqbNw9fRoFeS7L@&hoX3J%-OT2STGfCBBbuyJ?BN3x(~yKk)h5sX3xptlxi^C0nc7Q$oY(J zieU0MJ8PQ_i+L(O<`p`|>Q9SmX4=y2oazB%TFGy(N{M$Q&NRM+9SCNpo18y!xMg-= zvtc${7EOE*#x7hMXO>T=iDJR#)6TCbOZTp3B^YVDLt{RI$#lUDfOjSluB*h2g~@bm zVlSk`LprL^z+LvZgu$qKkBzb$XAQqGEDRc6Em|G zgEW{7h|kf7t6)q6va!@ee}wh+69;JnEh|s=X0f!|LDkZ;5~fzOH_uA;T4sepc$2DN zM$Plf?nw9EKvUUx%cA7y$>V5lu>a2|gn2Zytc4%J*iKjrlgGys~*?}sO+13E|bkrY~5-cqX32CVD z=f26@9G2ak?)9EnWq-=P9VQQ@G)^14VHd(^()}s%lWamplx1-iOb*Z7y&>eWba#;IzpK&)GcP%C7n3R zEQYBkfdRd@563axE-bL#62x&Bs92fqeStQhDt(8-s(MIY0<&@0DEc*Qh@Utu)yph8 zq8#sjnB6wAxTE>L$Y1tATD03thF^)Js|n=n=;4NLe!5b)gb+XrbLTlr#32&j)2)(Hxe2Y)K%-USlUs9 zm;*A~+~n{kzwF_3ui52Q^|Q8>z_R`Fhf*W|xZEH9NSc>$h4uWvVqPK47NDE(w_*L2 z*lRM^I;|JXk3q0;e)+?x(I*IX3>xtRp`bZl_baPLYfN(VHdvRSBfAK>abScem4rgf z1UHJW!iL0Hv~ej$3d+BW5QnOVQ@uv>j?8@(Ofx+=FGk;lb@D4Wbd0~sx_lseJz#Pa zW)Cyv23SAK*zMnk*=2>jKicBzP^dtS)Q+<*J@UuZ{_u5adTg^UJz8>&o<$|zpBmjw zXjBkNo*xSJ4MNuv$_heX5Xx4_8+&bRg;wD!VS}ZI>-uHu)1wow3KjaJp6FPOz$Jn71EHX5@8X+mGp$t@!emEl`jc-Cg@*d& z>r=hSgoX$Da_(gz)++sOiS=MPAzSobLb*XD{TIj5Jx0j3rS7fLDmQhEC&1at))ao; zPk1)n`xWg1TMH(;(U<4zp~DA+)LHAsr~fUsZ0lq<5~gzOva=F~nU#l726}Kp_L?jS zg*pdJd9q=tuoL~|cO-i+!A7eD(|8~o@NL%l*hF+s2J1u|3oBms2u$r`3mT9d{Q=g+ zBcp*LVknxAVm=@`|)L-^uns?JuyPeoOs<&VrNFSUVA~nnW z;ak$8L&`W-`J=X^Ms6tccO$%jkS?M5tYx7PQ#*LXc1q~*)eHSx^c&ax?Z&%%452P$;XFw9F8Dj+2eX^_9+*rPoE4)z%2~03Lyu3$ zda~Ay3RpWoac*j))*b%tt!dsbcQD{&vya-w+{xsDapGH??EMZK3}c&Oaqo9mY)i$$Mw~r=eFM{^w;RoQ%k5W9*o)2nDww>|p0nP9+1VZ33Egcspxkt2L}*A*9)}07=RFuFs9ARyK1}VfN0J>dYlPG8wW*jHKKCIonI!PY z=mRhw!f+q`1EJJFXVQB~D{NWZg|mNO3p?zQue&(tQ@)0O*PaEDcPHO2&(=LXmyr3}skAHg&f!81Fr)dN+A9Gx7Q|A4>yt+dGd5BLq< zPV-KF&<>0}>0RO&zD3tAhhCd`vU4npGP%}r3PK~5L;SaA&i(K=BzpOIN`xIRx z%wt9-V$%BHm{OSBc^(?Nd3{5n`Jq-6>B6n-rmJLTsso-XX-cO{m4w zF>NU!o8wnPc|j=?HU%3i>0Yf0wS7jLnd)6as4yrc{#k8*()tqWAB65AWZM^hF4lqp zglxJpLTrPiB_gzA4(uB_5rb96yuYiyi!H^y|Mpke0hku#oeTFzR5chD*9{h^G z8*%3=cBR3|@vLUAR(T2cdoy5KX@U(Qx*5i!N*@0IsSr9IjF)zLO`Bw8S!(o(Sjc;d zkfum5b-X`eTIoptP_mc0-7=ODrcdd1f7$*tZ!KbLlCbAc{y79|1 zQ@u`vWP9%D7bQpTeBIyuO`7-48?lW5!$%vu87$Hzsoo$$Y6CMeCpoh8O@H^dY2g}v z!gstm+98uw4o;0ePRPDi`GJrosa-7ly%l47-b#+#@|HjR`!uftaU@A1CaWJS_S@Dv zw*2{T`wf0b^Ik-{8lz$ia8~;XwPH{<0s_ zyy-jba?EYrL&=dhcKQu|O7mL28=Li7DT-hhsP8=lOyMT;5Rs! z7M=0|X7Upcrg|F*sgJk;WBDztd!TozjCqhw{8z%pN{@a>XjqWqf)8UpNx{*@Fz%K} zQR|~nXmXHZHX*Hmw0M8Am+`S3JRIX@xQR0lYMz+rfVS{Zc3|#1QyCDSmBA0%?q(L|>a`Wd)hKJL0;OP6f|Aqw*dZLTJ){4h-_{gmNW_Tpb z9B#<%n}c!J-Pklck=o3oOmSH<+`dxUrdLjIG# z!=Zz;qX}tU#a_IVxdoPHDyxS(RwFbvNSpmVHJHR|XoQ9bTD>2*{q++|I>r-_zXx+6 z`VEYyEt#p&CO>KwR#jIK>K;_JRUy&_H?-jsOj-4Cdi2(xv>+?tUP7g&ym~k_lJm0} z9#7YI{u~O;HlyOhsnOoQu!|{}Zcg{Y9iuIN4Ta{}s0RpMV-h`5wLHN7V%5b2$6579 zg42RJvJUcUbm7EE1L<@^wQNp&{t@J;-Y? z)q*cEzZ&vq2U_uiP0}0fn0-ut2TY5F-H(2Rsc)1{JK9tW2k*YErG3XpxiZ_PUo~t;t~zbD`sGuV@qRQ#!&lPdK!3w^jse2c!R! zk|S%5Gt27Y3tywQ4j$E?UcJg%tQP}d?WV~VG9V(3El`;SK=@h4s|Ci!ym;nt{(}>-0WC% z`}~?Vl^5(hvtf4sQrrtLH?*)nVKNXV;Y`x%`0x>qT>#VUwl^UU!P>%tyRGPlu+Ap& z1e}yVdg$OM&Pw%$5jxzZ?_r0{(38KVkPC4SfsTLTPT;Ng z!|dWD6YYoDZCv|Cvy+bWx@E9|u_7b;PcjY8!0RqN`A84A4t98b*ag#&*#@3|%8{kr z2J00oExHGGX>b;6RriQg(VJm>+{II$orK(waGJi)*dHcfs z{w7$JK_ZFu%(AoCzV54Mb_;*5XBspi&&B+Ghdh`&%=z2`!ECEowY(o-LxVPo^+<@> zW;vF+8m3jln!5sacz)Jz5DuMBTpfSUHObx-nC3jkyJB`dnA;5aZsm8F2BvOsr0RH@ zbu`X(dTjwykL?Zl8kpRbBmbmiZx2kCrKfyM)9Q4yyBTwK^y%SH8^7}N)acEG*iAW9 zzf4G_Fl}y1_QHuVD{@Hoy1_Idc*MXIco^mmGR)TliVN=6+cgY_l1Rm5@ROr?Fm~JQ z)X46JX81YO+Ncqe%rBqIw+4i?0tE+nZ!JtU+vEIxvEZh&*%>jNryt(6uuE+!Y#eHA zSA$^9@P@&9+c>=OUYIO^-_A^_2I2062Qy91j4fY!hBXYvPE5ydBIFi8maS)CY7EN^ zMO8n`4nnZxc_UylCY2I*Crpc@T`J#$DIa?`LsF-ST?%#o%?D7i3bGcagqxUUt#GGz zszeUzan+iJ{nG|@iuP-&R`F!byOxj^TZZ@$hc=i>4?ZOEPC45S2Oops;{6=M>})+Z z!uT9ybgK6;p?>7S3>^DfH?xk%b3PXKe3%A+JXfZ~Lo~WU0p5>}@y4%!FQlrrFM2#5 zri5%}us2|`2AevqIJt!_k#jw)KTPLn>yk@gHl^IP0;YA?#x*%7<_gL;4yJY3ejRo% zOluQ1y^1XsrhIl}8l8J&TSmaNAK17xFj?Wki8yx?mP1QGo6tkQ7=-`xaXtb&9%prL#!C^L7vqM#I zJi#GW-FP@y`@(Q&kX6SY4z4FSz^Yy<)6fPp3HA4;R`1egvCfnb_)CNkL~0&N~>CJxE1c3W_EX{{I2QY z;4!~FFg*p+X_^th5hE8_%d`7pz78<$W%gn3Eik2oWhY0!fZ3VRsv656Popwk@-@>$}vE?)C zyJy%Q+x6}mm{t<3M~|O`sde_I>7OvoXS?=x?O}Vx^8)&~1g7;!yA7{CVYVO3zfXzp zX|u6duxk#4X?X0Cy&k3$hHcm(nB5YzsAcr3s+?u{Hke&{^$qR2FjZ%l`UbtNG3+o6 zf!WPeOWd_EEqEcbJj^l%Qz^j#JX)gC;pW856{O^%-4 zPxWX^9YRQ_H~X?|2~2Ae2X+P_vA->yMVht^h1st%Hxbe>(t{tlnW$pSylCeEN~I4` z<`L5A61TXX1sA3z-m=pMTD#E;9CHNBTA!hhEE#B)Wir3tMQuqA9Empvod#J~4DLp~ zMKCu#==Tno8->p~s0_BYw`18CX6=O)qBp?otR^7847@EG9TE&2f2+}nP}|@Pbs3># zQec=DlD%R41=%2&HTy#_J6rVHW-n|Uakj#q!>Wb^_q+zCJp)rclI(4U$>Vt!!GW}C zX3SYNKr>;jhzl*r3bSv+s)j%EMW)$3ngzY%a2Z!_a0MZ?pC_d_Q4$-5t>=CBVC*LAe@9mWxZTnkei9>&Z# zcT9}QAlWdDDyM!*SqsyMlaDhTME&KQfsNab4F}(4z?dolx3!}LheI(@?lcB!(Z<-k-g>o)Hb?wep5?X@Rx3Vrf&VW*Q@KD@=X29f^fl;EjD9%rO zv12>|)nuLbH<(>|wHx)!vjy0=QkdqnU6!AQ$r8jJN{;>xvxk@TY1R#C0xiE9=6rzV zauZCGh!Gu~5)YBH*p0t^zBS${{_+QsBeU|&?imd78dPTnhV?U;b_shEQE&PYX7%2K zX^9E8%1GB4ra>Xg!OR)Bmr0z>;}}8%O?g2$JqeMeAJp$(VOm&; zV_|MuXqRa_eg!Z*h7uklWc^c~{2i=nl)dbtaPS_(dd9;rb%W{7LGKe-x*0VU5145; z6PxNzm>!Q<_6e-Yo4le~v6-=)W#Ac@9ZKET9XC71)b>mNh22)gG+RG}9roTKbL^^M z&G{s3bj*NW%VN90aS!uzN;Qa`Bo7mkd$3ee@lP=85S-ql7M5x%&*Wr1 z|MGAs(*{2zIM@cyzkC5+=|20zjZ_|YX4 zFBIVtiWiA+36*a)Kho#$qf01WEW-7FV~Oq2Dted*QH2_l4`}pWhAr;N%|zc~oh*Q5%JRaq_PsTt`Ed zet@5dDKEu%9>F+ie?dvroPIP^RMf=_>%dP1)w=qiq7oc75aALk{&Y}I(@1|*uedW@ z#F-*oLIuxq*hFaZ?x($qK3j1PRbF$r@EoTf4Hb2+ix;Z?mW~URzqP}*PCpVA-;TeD z2ZBHqYE&;je3Ks z_)<^>aSsz*LInpno!f+90m_ufB~%5Y96u5zah?q>p~@c{ESCx(DB}c|K&Xm2aRrx9 zK~7o0B~*~}RDhh3g6l|Bc^or>iZ~zy$le}YF&wObTEey*TtZdMW*J;Zq9iuTph9-P z;5r(H&FZVe^~}>(hvQ4ClWHDmRpvFI8nwXj8(bMe1#fixNL1Tya{7^|#c!$8{|#FI zQUawde+FGq&pLe0;bw_kLIt09{Aj3hUNl+r!)FD9@S001RB*fFLiO=2r@!s={|+k4 zJ1(D4!JUqSB|%@`Ly!&jxQPD_sxP0CPqzCUR1sgea)i>qbo@wE$G+7d98chP5(ukP zn!MlyPwRdlv1N2qyq zj^jc#I0;m`Q7v7BP%SziREA_wQ62Q_zd#jmp^F!ar#dbSo9)-JkElNV%e>t0go;7& zD-;dR1^F)|I|%1Fyc$&eHJ}a=H#)uuRQ_8)HFt^QOI>^!$bX^R`K9=~BDk0`+~X45 z>k`}tN?!%4zpI`8h{H9YJYfTp}>~rx#Rq(aLZ$U+U@Ayxk8h*gxKSBNr{lPDl`zNUU5!qjXD8H1!bNqNv z8BTD#j^iggtP853Qys4l@?YpQerd8cb$T;U7D{q>J{WkA!;(}N(HYcO_5e=+hk~kL z7+4b=@Aw2zmrw;y1|{Y3O9jtxyvX5fr(X`LVe_57!0IKT8wqGEeNeOfPEccXFW4M> z&EZcV|Al_#m(u?M2BvhV+ND`v%peetB*{Xcgoh($a$Z?^H znd!Jt#msSdIjE7m*71d)uA||J=w-yKyk(#ayIj_iaJS1S6u-yey`Z92>epXT=~g-Y z-=P}(5b2bDwM#FQ{%AFG_haFc%tMcb<26r0Yn9McKIV?Y>!32wdYA7=l)e#N26$1~ zz%4GFQ2Zsw{~f9v{V&7hQQKX5&>j~gD8U<`3VhQgI2tPI9TzWDzIPq&0+qkQ#S0bx zKB#_w=;A+e_;EGrSBpMF&?S^he+5eVmS39Ozk(|0phSnN=r_lO;=en7Buf7$dJv_` zbj8qQ-4s5pL{;klucqs0sH!~|FVvoMF(~iq2`Ya-kpDu1`K4Jn8q~Ux11f$RsB)%* z$~PNSlP-@k2!VS$;d)RR^iMu%LA%58dqElTeoz@7bo^n5Yn;9gRC&)i{vxOfUj?;} zya%fMN>H;ndK`nGKoY8q-5ykeRDPWeW;s3ytOYLu)w3%>$_QNzs$tiHx{ijryEHCd zsB-Rg{NBL+M+&is{{?E)SCC(LA1KqWbmjdOOa3bSCtL-uas~c7l<6NOT|Mw+mtLp_ zZL_>22q^r9i`W6Gg0~#L4a&stI{qFgA9x?sbuG;u54GA+Is<@iQ#bJrO{&)l>H~~}(^)IQ(yX(1xLg}YDek9gLKgXqS1*)7jpc>TH zr5CDgDUJ&j-=VtOoi21js!JeLf{u<06XBVlDj4B(;VE$agKygYbn~SK-Q?nrMD={J z(+?x|m$uYJ2$k@5P!0GysGi^D;)QC!-JmRVzvHVMKIrsELFHcq>N*;#oVBO8jO$!N zVZeRMHjksLREMXm;h#iN;k4M0cFf`!URy4P!&&f zT&N7WPM_lRBk?#h_i0W&iYa!{LcK@08C3mCKpEmThX&LoRPoC|wfhdI3#Bi2T&VaJ zpqh6-C=YlPRJm(3qPhrFVO>Hm!PS7*KxKU0;hUf`?f`WO>x271RkYvfLQTZ5YWoYy ze#fD!oa&w%(dr1wTN_k@Q(S_&4o?Nukour{cp9h*8-cona-DNQxpP~G9bEj;P~~*2 zMuIqV$S@LW&_z&{+Z7b==CC`c`ZGXn_ya&)LZu%9D*aH$N4R*Q`ZLz?qoLxn^-r|Q z;!{Ydf~Gpmb2trDgJ*!cgldrfjY?fY#m@qjf40;A6I6%h#YSSD%XlQJVb{3|u6GsO z;L-_I@lB2&4b?-Rcr|zls0QBV&^W!UBLQ7yE@GMELS?w!@uOkHtS)nR5OZ<@BSW;vaDF{|Tx;50PFT@TeCu1DA#C1W#kuBFYV)bcG!aRoPQ6{%9zpK0~}J zc@9+i&7dmV;&2|O%8hgps6rL=y5mA6d=pfGI~;%8;Z9H$RDimKO1B%-LG=r# z|JUdy^naZ|#r|tSs$ee#tL*RjrG?-iDE&8y4#j_W@o_kgU7F0{2OBMYM9*#uXt{(dUDztDVF4E?y}80#Kvg!SM@0Cwi;#3!ZB&wo3ba~b+7hi>PA6*jElR2O=6gz&o<5xJG3+fVT=e*VNBT*Jx z;&h?PyA9MKYXzwIl};~NML?HO2_JC$XsC>Jqk2JCcPsQkM?4N)bidOmXT!r-Ok$4(F`!6%Lj z)sVf8ABi&Mujs1qfQvsGs=VJ^y5B+ZLyrHUd}h>3;o8Ab;7_O&k7Y&4YHE3Ls0F4r zT-BWjsy}rdKh!oKS7n- z)}!d}dlsl-vt4$fnlsUHp{mPqT&S&Oy5s)?bcUf2ee0ng zT}R^ox1Rx-wsXTL=>gKQuYY6&uESpeF*X|QV_*LSb_u=;(rh^P^$$jiuYZnx{ljrdk3x=p{liBy7(&zH*w;T*p9SgGjO%~G zb@)8?_0NY`P?k9M^^d*=(yiUGuYV4I^@BOM7FTBx)=Q&fU;ki)V_*Lq`}&8sC0Z(u zef`6$Vj1Gt*FVR;{=p5n^mULt;@H)+oR9(Ru^&x`aj3#LYDnV$)TD^2HVk)b9f4`IbL zgpbVk681_MoR6@_EYC++It?K@9pO{ce>y@&KEgT)pPBFsgaZ?;ten>7+vUXDX#tQFGV=n?2xckLi>3Lb#Sc&2+dLVZl`hVUvUw##?|e>^g+J1qkPwjS}J)AS5nC zNHVz#5jIHJE}@l4xE>*AA;R425!#q-66#-%kaPpW`KI^=gsl=PCA2p!ZbX=K1Hz&k z5t2=XgyuIQbXtVa!7N;auuH;z38|*TO$ZAXA(Y>Q(8=tRka813pPLcVP1(%|dnFu_ z(Ao631!3vU2&->FxY!(&kZ}vbsKp4~%&Nr*2PD+G72y(-c`L%o#R!`u^e~=}Fzi-@ zJRhN#*(f32M@ak|LLZa+H-rrmwoB-15|$w3{0(955`_L{n}qsH5Rz^~7-))bL)a>z zQo>-x(s3U?Fi$|K?xbRBaHexLbh4;cZ35HYLz2QGMVKFEB}tL zNkXpi?uZNxPc~VCDQ2T!s;P4)kY{oQ)68Z;zDc+Xm~LhWW|(b)0@HXoP-uz;MP`R! zrfG3EmCRXAC5!H+lG&z0Li4*3I^Ba%Y!=>wuuH;z374A=_aZE~2ci64gt=y)gp_*` z`m8`GF=Z!6AHvcV2&?ZyxY`_)kZ~WvsQVG-n^pHC9FS0JCBk(kb0xyc z`w=!tSZKUe2*Xw)+_W^_r61GdY*(5xOkn;e-+y@aBn{5*6 zKZua@5Q1-tA41qFp;E#U(_%HkoQDt=twu1WLPGP^2%R2AC^HKmM%X1`zl7UOher?= zJd9BO2tv8pCn4n#gg%cV+-b@lMc6Chkc8!?#~OsCk0PvIgK&>IC?R7F!l=g(R+v?f zAsmoUYc0b4CUY&q%Eu5kNmymP#}S6DMaX*`;X$)eLj28zgL(@Q6ux z0wHG|!rUhi)|hP)>OX;yv>sutDPE7TRYIkNb*9AzggNUG7HvRSZz?1--+<6*Bf>_r za3jJl3Hv2HWjZ{GuwWxX`I88n%svSzPex8Kmp&Eg8GhE3J%zCMNm3koiWHkokEaoq zK83LQX@nQdK?xa8BaGUFu*Iy}gm6GYt!EHkHkr>LtlWgKNy0YcJ&Q2x8HBuN5neSL zCB#3AkoX+Jc9Z)Y!UhT3CA?u0HY4ObhcI_D!Va@dLjBDMNzWs^ZHk{q*ean?!cNoT z1%x@zBP@CW;XP9!q4^64onAz!FbiKq*d<}Vg!fH{EeH!)yXo*I!h$yt z%HPy^BVxXMQ|FC0QTpuAc_U($?a+Bc${`fa8$I44)6yLXtKUM1GY2JPyoE68ZG@;< z^)|u*3ANrqsBSXfL0I`V!X^ox@pd8%dj}zJCqhlLQ9}Gqgv56dYMI=35jIHJE}^zb zcn=}xU4*&sA=EM3B-DQoA!!%F$)7AuOsusAno9G_OGDv>PG8 zEZmK-OTvB$rA))y{5ITK^(7`PH3}Kgq{Ss15htClfe1=f|IYKA1PeRJ)2z|alNH=9)AncWJ zNJ3}RV=uzeFA!GmMYz};l#sC(Vbnf^Zf4a!gaZ<4eTi_1$@~&w5_%Z#D}-TR zBIJFA(93L;5dRfI;@1d$OzzhR8zgL((AOmFN67gaVeWo}{$`tm`uh=*zCjphioZeF zDxp%sVAJATggM_JEczBoz&(B}|Bi77jTuvfw%3G+;kKMmu*;Q+#tT5%jemSo0ZjX$BApbL!`jvKmUSRA$p!*4Jf;fBBZ!xj;QMJ6|butCCh z2{)UBIE0)C!rVB7#b%p?`f&(J)ewABTn%BXgh~lZOp7SOoN5S*q6o%RNN65K=yV)H znOS%o!Y&E>CERX0R7Y5F971_@gmSY_LP~XnKJf^5nzDF=y%G*dSZ;cF2utG;R(lBd zn1d2BJcLm-5LTE~H4qL+s8ti;ev?@fVPy@3O%hfa?|6h^H4*ZTM|jX|ln{SBLZa-q z+T_+k*dSrMghx!m2?#m05aynMu*PhYQ2zvkq}m8;O>u36tr99FtTQc6M3_?>VbO^Q z>rI7(<|iU_s)Ml6EUbgDOTvB$PnixUAuOnaP<|4^CbLgM%1H=)PDXgvl%0&QSHd9) zn@x{X5SE^du=*5)7tBEk8K)qOs*AA2tg4G}Ktiok5neW#ry{JZi?B(;HsjSp7mzKC&@=(z4KpJFA*VjVP6<0q;|6glxhkkGUV0uMHtAmp5duu}pLHku;TZ-OwtDFP2RBy5$?{%iyu zY@CfSrzyf`5_quD459hi2uqqF@L)s2E(zV5Bk*9OIl_Ww2tOl44#k-+E#f$6G)Gy{ z0_D#*^MjPVQU;$xCLU~@L#CxI5TfTI@L=Oygp6|#)=7w(@OcOaBxIk5z=I75E6+u! zn}ooFjUGg~6?U_-(N2~Are@L;1ALQYGBof3Gk(HfzCD}?#2 z5qPj6VXK7pZ4h{{(FS2oYlP1v@L;1YLi08VOWGnNm^~79N$7Sy!f9sl`3MWzBK#~N z(R6Nyka9l4igpN%%=Z%ZN*LT8p|M%s9${%agy;nbXPN#NAY`;hSSO*W2`3{QkdU2> z(9Eonu<`xeKX72z`p$)-&wgytO)mUKesVD?DZC81jy zLaJGuhOnR$!p{;qna=45DQO5R(h<_l_Y(F>7<>^zXS4hwgr(^S(as1LoBo{x3B636t_blLBh2iI(8p|+ut7r8 zZU}wNjBW@yT@iLl=x-W#N2uQoVSaanfo6ws5Sm|t zup|Q^)9jJ3OG39E2qVnm9taCE5Pp_0%5?6DkkSKTMNfn==6eZyB@FI`kY$$lLRi`p zA=(>Zyy@Q?A)^<Dlgt_kD|;i4KZJa8UxcLo2s2D^e}ww|5Go}Unic~Pwn|tu0AZ%7kT9n| zLZ^WUv(3VR2+ao|?3Yk%It)VCC82x}!sTY4garc;`V2;xYsv;AqzpnhB%#Fg7=o}@ z!s;Oi^UOgBO9vy28j5hWSv3?PV+ca6VF>e0<}ic<5;jS=&UnF5V<W@IEl;E2dqY$=A zSTqV@iK&nln z2$d4nnie^6L&J}od4hGOLhyuXlMAdj3k4g@9>GS_VKVTfSuA+U?3)~yAHH+_jO*jR z2>bo|S2L|=$Hj-cn?8AQ4|-SeQ33zXM(Ju3o)-6et^AXMzdH-&=kG?e^?Qh81Iht^0^I&S^q;Bg= zpBFdKw4NLHPV~4QDrU`Q+GD;ep@<;e6mw!}TtAf)J$(Rw1#dcUiOW}pYU^9ii(`tv zIVSi=`AR#7y4Y%4a*k82&NmA(GM8{>AzsgS#ZUfRZ~+fyRpN7q;07X_CCE9}#KlLid5lJ@miOYSB1YaG7a#fj`SlZTk82r; z&fcz8s#`&>@5+f>{JKhQ>+F0dIc_0QZL_hmTx{I}RZbvFv?e)C>x8vGsY zQHu+MPMMGAW7=BlN3D#z=eUF;OM5yY9F+Vrc#;aa-#qt7T>Pm``M2fyW4oZn$yrmf z_31>@)7O9aNZh578b3kQoY_sx1&_sD7}up~c>PB=#{D1m-U7O+Bl`c%z2pXm009#2 z4Fvai0u-0x?ocdH+})Glu5B6Itw6Eju5EECEyW9^P_%e~BJZ=$nL~u6?eG29|G(Z^ z@1OR|%-OTY_RQ>=*=O#Y{dOt9)}ot}M4QsxdU{)uZSIcf8ss5`Q3gZmZf$$_k@ULr zDW#N>XJ)f4YVS*u&tYq1qvX^-r&0eD?YneuEzBvJZC$&c>ZYFF#w^)f+;ozv(_nNI zQrKs8+*;~zk~DUEv7V~t_ema_9ah!(KFM!(-vKJmkt8)!cyo!lRMI~{ zmD!vmiy^+bM-bo8K@>uf_Q9=PjwZQ$JH^zsawy!*&2O)&^sRfzD7Sa-%|9VNOtKdV9EIvP!rv~n0U-qOC- zL^(4WrWya%G`VQNx*Oz;rpbjPk@E9N{@!YuJX&{-SU-r7`w2#AzW16>F1LCp3CJI% zHEuVT8+p!YqD_cA%M~1QtB?HIHBD~ESgmPEG)?ZuD<~!B&t22xW`RPQ=Fl{e)F9$g z4mS^I5}W}<4bcgv){G*)p_-OP)8s~!tUAH8(4;x!hJ;+2mQM4@jgZ!@qUklC+$)ws z+JHYVO_R&mQkt|Vw@f;67Kr|uF|(#QB@(#_*;~_G_%lff`18>;xkXTJSe3slxDqUF zK2+0OnlBr)NKNxKXtci{MB_$2+^m{0JN_SN2dQ8-Xc8v}Xba>oCj=2vPS8#W{1wu1 zbK!4qP`LC%({l41qNVDuX?dX4jMBGQ1ZZMjh^aI!P}A~3lUq}yF9kv4f4BVLsZKCV z^A&*hOw+2QU?MolcHY5ve=YuYE8765IjrWMz; zKxl{b_$;AmLD1xuC;2O>X~Fp4Lz7WZ3L4E6CEqf3JD?fMXvR=z2Q{s%rpeGeq-o_e zEgV`NO)IZyMW9vE9kT*7>G4HD6-}$8`HDfSDrd#zud-&8dvL31#%h|eIJD}TR$bHN zu8`WARs))JIKJNGR!7rnLF0e3AakGC=M;lX2QW)5_vs zrfCf|tsFG#PPayyRvy|&ErrI=WVBQOqoK(dZw^hQ@F^&*`C93?Q57K?UpK&&`?RGn zmB27v!q%Er8QO47YXePcTm{s{FMn+{ttx)0fan6bUt7|v21I*`F6f|X)$wz&uPOhI znpgwk7AZb|a`(1Gt_iG*u{Eofiim%lEWRvZ5$gW_h~*DZ1Dfa#jnP4m^|d8Vdy zm+P8^u^yNQasau_TWIycd?0^4p-GJ!fCWJKdTYLh_!k2ClivVJ+(uvt5Wc>e))@av zAb=Xxnrq!=Xv3TLbGJ-BFsa4K#iGuW_%r z1M&^uJSjNPMA*U12<~XjO>h6BTVWN7MS^A0mBBd79QA+5}CTuW19I`9Ko|wg8%ON7g_doSJc=W*h{qEHu$-i!@Cx<*A}+ zi#2TsG`UYz{+4LkQ2Y%wO|GIBX+?s+wD^~48kLWdPcF$v<=mEQVl@6aTKp@ZNv9bG z=0YonD|gllZ8(?$tvv2(9d`u&shTEt*9+fBFiq3eYQ9m>rW-Vhuue0MhBy{t1>6mq zaSZ-(nzm8X#zHFxP5z8~?{UY0^3XoT-K6=(~dK)xzb z6?dy<6ip_yYPj1pZ8H8{_~mcArcJ>gEY;+12Q=|c1&2iD{0YB!rvaAY#@}wuCz>%T zQWN)T#xEd7YuY|d`x07RXrdAKYuZ=%>uJ6NI>8yx%0d&3cu4ap{N*&?VNDbDDJ^P08-n*8EX{(jN4mG~>b*B18zG|BjDP*Kw^ zYra*`tUEEUXxeIMp76g1@6af8l-ov#euz*;!XKLPTl|w4PQ!5TXxb+Ha@*{1+`G^u zlg&Ve>?qv(nr{n!895VhA86WE{L-f;<37~1ZTQ3Gt26TVrzUR4e-_9PdZcMP@P9)A zWe7diw4M0ZL6g5Hnzjr77R~n*niOz17zRy7)pO0a2ftKUM%4>zKHkd%n|L=FR)4`L z?YR&5LX#f=f7DfO zBXoIorKtB4?9-WUVMf^lFxmha*D?L(a2e@wVqEYBKHwe&m+Ov_ z1JP{q0kk*Z9S{{OOYtFKD2N0yoc|>35qJ!q0olmN#zi(N5$>1^TH}!|R3jk!wWi=R z&1LBYQDJgn}?o1QZ2wC8%8cSsl~_As`flfuf)o_yiOOC4g8c(g3-GwJm55I)XOf zH}E@%?C%y$@ zk(dMKf_Y#*SO6A+MPM-y3x!+`+#U1+y+I$jmAEe+`FP0&un~LohCgWzHIcNb|g5MGNE$|1Z#q-}(^bL3?Lqe=LHed$<=*~b8 z1cHHl65N0cwHT zK#U7wOAyukrUkQ;LE$Wb1T~Hs$hjXLBNFZPLISx*Mli(CM z4bFmd;0JIN$k&0yX0RQM1@is1x%4~v;M*(k95jM1pTd)`(TxL@sAOeXdso3z4eSFh z0(?PMkPXPk2xSc*bH2>y&w$L~FMxdb&=bg~Z{@3uzkmziBDe&ufU7{3b+X=*^&-1n zw+TQtxU!+0BFbVKm=3-IGk^lJNgNHv0{OsUdt5P_v<067`8Z)gPzcCvbYtjMW5IYZ z0my!05|F)tEM#QiG9AbwL>3)0fGo?SWF0QcZdpFh2MfVsuoNr<%fU+UHIVh;H$c_| z13_od3^WH#fjb3}b)sxe`+?FtmjQCSuoyF1g8HBVXb3P|M7dpL5L^NkA;`VOo~Sj@|7VmXovx0JJ<>a zfL_GeD=W@rJS+z*h&UKmuGJ8uuLC3n$v|?D61*hrHTWC60rKUaN8mAd0>mP654@s~ zVhIt;$8qq8Bp-tVpcHw8gQ6fv=J;Tc2jm4}?QjPU-~p0?WFR>ZtA|)QQi0S!tQ$#y zSTyc{pMiXDM~oR_yf^`V06Rc$&@^fcLqKe=!IY2lDBl zIh3#=s0-?WGC;Q3vV~p%R)aM_KGL%UECmY4*MO!1`6iZp8nGgf4}S#!JN~PP-H(xy z1LOp`fGld?i|tRA)h|IF+F!n=D%&gBTFX{?C)fpc16lUTZdi7|vfDifHiIo-J(vp? zfQ4Wj>5K>Rsn7rr1Z0aY-x8H=`2p}3WjILw#wzqz+#BE~kk8rf20MX#>UJC04rK2> z1ju$>Y&OwAw%_GIc~AkA1U*PYR?lJh!-4FmQv%sVrvb8a&H%hX)L z5)1(S<(Z+_8py5QjX@L86f^@@=zy}FZU*F@bSIFVv@ggCWCtxf=Ir1tyepB;U$_rQ zx3%0YdI`@?2)n^vAitYk309GyaWy~fngqzVuw(};UlDsooU-tg1EoQ6AYW3*1#*MT zzz1XjE|3Xi1Zjcndase*5&BiXhC13=QuWZ)> zJ&7RS6b}L}kOj1Y)}9uUi`V^u{A4vB$PZ+znH#jCkgdVz;352n5#)2+61aXK8<3Cs zq?7N@q{ov1$ajwlgZ#h-nnP;=exO!jk(op0bHOOk4Ri->3GWCxftn;L-%Of?UyLwv zoo#O*U*h(Fo(p#pJa-B24+elivc|fJIOVmW*eB#IUMHAZgBw6zhP{X9BH|X?$2a&Z z;12-{@Gk_5z!IvnVyamVr?oyEl;30Sd zgCikhbe^5MDn zNI=X?VphsQqLP*ZGlA4rDkfH6`R=wzPcRd{d0;-6EbT85JAuxi3&;(`G$f{=_Mip@ zsIChk5^yK8oVZqjti&X7p-b&M;!3*0BeZQYruiEn#xVX;l;|50T*@z0l{nKqd)kKeh)s-175Kl83ywC2(ccBdZ^=BNPX>w+_AFo-|#9tN5>g%Rn-^0c0Wc zJGcd87Wz#;3(b0#v?bjfR6tf&vSE_V(*tOC)PuY1F7M;L2kwGY1ii*hiJOHe$#BK4 zk_6a+8?b@*@Vo@d`WzVqbXzEL)2_3(sEwf0Ww`JkP;PAORBb zt@cadBvUDz16LxuPLU8WYXY)IwA$|0LU*$Acusr9p` zSeCQGAQmODB#A{SGZ5>NY+D?XA&_0B?3*ML*^SEXQ(P%bcJ0rBD*`V9WJ6d8SDy3W z&r95k`19fa1i#R;<9e&1_uW%QiS6hZ$N@?Aj1nw;AUn@Rd6sb`3PM&FvPcaCvaiez zk1Swi(P}MXrQu`+(gyb~5T#NKSVb?1zXXs5lvPVIRf^AJ)kK8O+Zyu_0kuI5PzzKBH9>Vy2~+{qKt-^WB*ubIRnG_R0k#Ti5vll=BSZ%JNFXbONnj!< z5527VNjS?X$3yqLIE5d&J8`Puq^>~tX!vCPR8IAL=$_djnO9Pi2u)X2yg>5*6!cg7 zZ@6cO64DSNcq0NKOU6Q5i@ORKiSaxbzi6YOK*EJ@0+4u8RiO#5#E~$eTUoB*S<;rc z7LTr^%6ZG(r>&K#WFk!CfFxkiWBVn6*w2aig>Men3XFoNBY(Q*O=p$!Lo{W3Mn zTgfqYi$zi*p;-<6Q6p#emAb``+LLI~lgg&p{iN{Hc3h-@$kXfq|ee z=m6wAXnWi|ss=1ko$+=89d%G|+z$97w#SU?C6jl*Dpoq0s`;CwI{%md@WSTF`y%ro$R34~`Nm;fYmtB{lM z%eMCm+^JxScK@Q_GWSg9c^b$AM#1+LZe`rrGLJ}!X8{F70nY?;fMhaPyCR9jU=dgX zqy|#hHDEPZ1y+Ku!4blw_L8nhW;56XHiGqF9oPWA1zV%|M*_D2VUz%gv>OP057-5E z0uk>HAmOq3BwWIT9zUblX$fCfmN}h(NFxhwl=PU6;t>KRZ;Ss&{QBIm;T+&u+Pf8D zCvm?62Z02N`STF|!$A6pi1;`-3Vs0JgCp8KhI;~pkdE+T9f@*t@*pLV&Q%ad;*yAn zxEAy(0{oxi76U~}nKoXV&lY%SwB|$NH{f+-Mcm>X?Z(g_uL_NTJAKU|XfF$<^_<`gk>Tlpz za1C4rm%s%eS^WgWo_r2h8eN4lAGA^9wYG+T09(GpQIn!I?B z{gZ4EMMSc{_5|{7K=$1!feez=xT%2b$3?`FfwZl}O%KH6-wMccCNLVmA8s~a6-o+} z2e_coWux4D@JPwz^^9yVBv6>ewG^JzP6k_N60{N^vYRioteP&?r|kH10EsV>jNR{t z5$;Jk5+-TLK+Kzj_LpI9iO&j@%q6l6cd1qE@c1KLDjQ!&`=gXl@CNFH#xmLSKtp2?XGmge0;QT-q|2XDO5vG8}&xkQ!QjN$5qP z#jc#FB`I)}lrVM;OKHZ+xUoeoI;=bpT_l}JYAMZD7Pky24L$*}Yiy-ur6Uq84oZNM zfC6#Mi$wAOVYd8|P&puNEH$;lDnOHrLBh$x0 z5PQ7Vg)Y;F6igDbrV9~y9cZS-Y%JX0#yuu@};z`&r z(3Z4D;f?_QRA40TI)-AupXT7v{r`xH)lUdvgPxt3Wd70=+57#`AR`uX(QF%48{%?XUP{QcX|X z)WA6VkPMGIcu(N(;5Tp+yaRuNzriE$8oUAz!EJCK+y%G59qcEmKn{={_dx_V~pTExeL=Tl{jML=K&54{t~!Xh$mf6(va|FvO)cX%&eM8fIQcLxjLu@s)8!ODt%>n zhDVfhIsBEtr=UEj04jpLI$Uad0@Q<6A4vbN18Rd>Ab|W0)gcUZK|>&KpP>!4eb>_&K35L=3Jpb#lW z83}ggK}0!_NPTg8fS#Za=mmNMsogL#Zw-$u^k+enQwv{!fk5I70R4gR%Cp#N2IGo< z5Riie({ZI>k+?(U7{w4gcOeL-;hzfj;h%y#8B74}D7BK3J|l20t^zZ_m*6WP`bpYWnnZ@3 z@Je%8(wK=~XcA{Om;+XW#X#r_!6NOK!VV*!C<#~wmVzZ<75Eyg1S^1qFW2rjxNCqk z%?7XztOfF_U_Gvkn2lg3*a5bKZD1?d0ycw9V5NTTl&qkK`qsnIUsXuz$Yg7%K1=HG zv2{>=lR84e@vQiaH27{b2$q2*Ky`y{iY-}Ay3PJvX{vk!( zPOFwMgj|5Z6Nb%4MkTvbE_VbB;V=X2{bY@-H$C8I5jKealUBh3EHP2EW5 z2zI`QmYxJ=ct)2EX}*L(*I z;r>CAk{H-Ab4I86e9OwbXM?|zsAd*lsTwIrdy6hZ#mIbBDn`GkBMgE5q5h$6htx0_ zxXx(~j_WFXBG%!n=KX!I)Y5DwpJZ{zrcS4Dc!$Y5D#_}H6nQ)CEVQaiOiJkxlN9f_ z8w>x~w&l5d_&O7aL&MN&FK)bxyw^vPQUg%cL$R$48Ppz3OSN=FT61Co#q z(d=}tldtk*Eld*RjRf3UsO+hbr6~4PFr4~vo7cd-3nO3%H5vM-?!qt}hSV?&IJA7h zw(a>3OY!`Rim<1s-KiX#on;uMQo|0fhD5uU-dss%5yCv6CZ$GH&0z3?;o;b^my=cM zIo#bwuL+^3Zavg~7;GceCE=6RrF5_ZFAKd~_rrt5F?`>sv}qhZ;j(bc1jFF_tskWt z@pUW)Syf5M>j`CZM*cXfZ%ovONmPq84sWM}5hPM}IbTiqJtXbVF&w^X8i~uTL7o&s zrW6-^KW*$Vb!2hNu61 zSxm?eYF%2=z72yP4B6e&F1%KM!;Kh*q$&aiZj=(|ANb6K!V=FZ@zR;a|A+dS0^kyw zYMuCt#W6@IgBP%u-tzS%9KRuly1tDh|uR2}j*@EAVkU$A>sS_f} zZZJr{c+qXfaIX~0bHYHoOV>-UZ0Q^|=)JYlk;Q9xyRL=~s7grN-oIC07nc=%oe_7A-zx7UUx1k)u zgzv1{3xoZJmzwJ3@U}noQqM9tf?e)(d`Wmq%835EYw;3>F=Ft$nViAs6CH6Y5%1f$ zHEw7o#>7Rsy);Apo23p8Ejr98(xb;xftxyHP1xbm2fy0#o-$BWl!x2HOzL8o>zhRy8tHUF*J@ zhlAhM`{Kt|Da=Bk0o(%BFc@ql)EsflhO$*wr{t-D+AU4cn$$&`=b9V6e)Q>Sy(C|= z20gez4~8fhq=VE-^*YnAbD6xPA}He`EIL#j7;KAGXW`odpXiyWcFS@eob)0|Oh-DZ z9!pMFHG}u$*#mb+%vdHu4mRpx^d}#$9B2p@DA7s$QcVdOuxg3j_9XKRA4h#>;!-yI zk(QxV!GEopSs?E2>iHYxZ>e%;p*QbSO~e_mCS`$GQ7s6@8K?I1WWVZCm$Nv6ZLL*W zCrWv|(^TvG(-(iij-2z2YLnmdWML-lt$=Gb3lRSR=FGP^EA}dHAr0!60*{+aC2+QaIvgPVU7mr+nK_)56bWDfrEi~t1@dn-u3u79lXI;vv=4W*T+i&Gmo`)RX z>TXs?7H6ScW=;)S-GBdjYQzg8Aw%UXQQ5Ll_B$|0UvqC9T>pf}Dw)g}Wm37~s$MpP zAE3r$bJTEsTp}qDGnU(p?zS@4E+j@69t-1I%Ui@1ruS`EwP7{)DJDf6;` z3D51wVt*Z|>gFa5v(I{Sp9zNO;>ciaVEMJv0&j$%HR@UWrWKx~;IDGMs%j2ja z75OC(MKF@C;mi|m>c=jrcJ^IY`LqZ?_tq_H|6h(w?ucTInv|EiY*i~LjBTyD#FKM7 z`bC63u~Xs9U(8-$bxO*9NTtmOyLKw7<}V#Ss#!iqO~$PFZRS9+Kne1r?y~ zMb-W-$OJ+I6;*(tncyUD=*;6K%&xJwXWmQqqpG5n>6F1?{zcp_mry4Q&{Ur*-;)lX z83i3#n5dlv(F|5dM^%eQ=RS0;jK)t7wrO)B?^85C-Ge$~no}bRqUN?EH<=Y%_smtY zOva!S0Cz3K}SLEZG2nMk=<59Wh+Eso0T!wZgU=GSbgyFtkkgUDeMV5+w(abR8z{*R4pQLyJobRk6a%6CsgOD za%T4$vA*r80>x@=H%b_Y5Zo@P$078K5{0RL26f^!{vP6QtR@sj((TmV!nA!aRVUct zrMmk&9L`}C%|hmAmZi&_g?Y0XX))2U30A57$xOi@bA8jGr>>SgJzBvas};)FSe1n# zPHIy{-%+GU7G^Eo9a z@@bq8Juy~s)eC=W^OZ^$K*mc{L2-(yPXnl%!R4c-2QaFw(R^Gzkm>Aabsa|g?^V>B z0G2;5s;CknbQO0M5J;%E>W<8u|0#cGFDfV+_}BwS~ zrlA6v%@(TCp;XLJ#)Z_VP)By>f;y(O0#=mTcWYGZp)fN)N*{Bn{laWI>RG5G)c#jJ zRUiyqn^H9oGX%am433=YFi*}j4a{D2XzaO@O`o0iLAugDMoNXlY32ej$mssP=EJYg z&cBY)6Y(2+ts*KSob-;Xb;8%avDs0Rl^oiB`jML(DH1wB5<0Ga3r9_S3xo88%}>`q z`f_KcCoqJXdgOo#Dng0Qs%kjS8=7yB&#lrS$z4t1)3c@7|D2CCL;hLo^9K~Q6*m$x zSGwxkB98WSaA#2xO8S|(PV85D`k+#;YP*|DYx<2_c2x@o&1X4gJ=B(>44BO7j4+&3 z_aveCRs=6wsgizduKfegs%*vJOQ(tza}-SeOEbMFQ(cA1Dy0|_F3-zH8K)`xwU7Gg z+Pi|XayHbbTOIW$e9rjx4KG_OqIeRehbmZtgode-pE!Iv#xI7aZ7O`};5&<1E|4+`|2FVS0fy-u04s(Nz%!ZM{XM8|v`MkU*}g zX9-7kb-6h6Z=6~s%FF!xMG3_BkV1+&o%&+g!X3UzhSS=?{@8zHV*XpCvrlC#$zt$U zE3=L)l)iX;&)7MebjOE1LWk6twWr8$DJHJ9+w_oe>!NCuVo3O^Ii*Ob zpgM)qv4@s;^4kq>X6$;enwRYi?**k*h7lq|qTPs%t!{bF@9t&0PDpwvAGh^WLfB74 zCm>s${#ezyG_{zfMwKS>GwN{}=ByK?9ocNP)dL~5RN2eG&`}i^XB$^0Gb~%SH|6{M zSoe#EcZCi%q=Ly2+pAh44BKE31#qcs#xm;%eJ!h3(KR%HkwuN##p!)g<`P~ge!$wU5c-tSFcgW-F z#)mPyNz|fN@TOA_BuYLtY@)-DX!mAyT+Y}?h`OP6VT_|#_+KW8?h%Bpps%3gyw zQ&mt4oVhBf0?uybJBe7gh$R-VoZmGoACY8fXBt!#EIU1SRR;!JR@GUYB5KhhoXTo} zJhf6Amf;Liwoh@!s@)WTDb@A`&LQ=fC;R1YDpd!X?pZfgYB5chO6{*nXg<|*F-}=^ zMq)Np)B53bRvW6~3{VlZamK4NU2x{9VU2NitF#?)E~>Ii9GQKC-QINP^&bVkacg)>N{DqESMt3{y8tV^kjXK>1_kgkf6{{Fc{&_pA*583Fto>A|mk~$-uSUJ_E zD)BTi0ZvOCs(Lj_IZiq2ew2oetOcx}l5)2rO{t5it6)gjO4Mq0E4kSDe`sK{h1BVm)M$ZfUMsNz#x0W0&gdi|R{ENlQeAID zDzOqaTQz~&_^3xs9ic|B$)j`8mC_Q9U4JWG-KEsrx{gq*18ZsPV(4~HoG2?&I+*T{ zAm+_UQ9nj5W}h?qfLZ9FDs_XHU=Q_K%#*X{FmoZ0 zKH|Xcw}1Iu7NeS|0Ztc~YGY|MMGAT?!)!&fcs>Ik$l)(TPUx;Q;r&2K_+<7z>z z(PH<<5Q|0E)l>@VNu`*`W{A-ZoQZ2~os&+xy4o-^M&5>c_@Kn%NLBYiXSqJ6X<+Qs z+H0pBn3yc4WpyXfQV8p*1{udl=1{^vv$`8l;qt4jAZhN&S; zt+Er;@wzHH%xnZ#{FRcY=ow?Fl;FyWPgcZQKiOk1fIeRN*y5~Wj8&2@L!xUHKHm^~ zMWUx!y~NOKi~lb#D$F4qe^vT_g=S1%iLJy;p?$PykLikWhh#ccvKu}Af{N&m6Fbbu z{&KQf-=9%oOi=Bexu=@@fcslgq_?t)$yQEUCUQ=eYdCZtXOL!S)cGf8iy z-_rZIHv;bzhmbDepht`B$6L_d8N6YT6NBE46qKM#CQJr$OXCP4yg1?u&W# zAun&!L~ZpRSzsWiU|44wi`Olxq%efeHrGJK)|M~tX`eX7ZnHzdoE>eZU?!BsV2(j4x^p_0sA9{?Pwf3;h94WHGqn;ZoSF^imko@q@we}3t~Mr+bw%C&k@&-p4+;%?Ff z@>{v&?$)v!p?wj`=g9U^oMVv`~}Z$3|7m_@EFB+P+H?p;3-@_O%PtTsZC97pSb!xIZjV zrzPgE3(P*<>EfrScGQ^RBBr)xTb!m_U1D}2rt7msruzTP`TdpwVejr5#WmiFbX%kr zMw@vh8|J9)N?a(2zQ-`q>b%Uf^S$oyv)@DK5%WEYVN17i@3&0tfs?O!W8GsjIgAF} zxLlitKIT#T3OxmKzc64xIN85N}p+{kc$ivUV-{#xx;T zdj4y_Y`2{CWGTIXnIihrIet-M8|Ko0qZ-G-_zP2KZQeSjN*H5xsl&=-#W( z>i63+EgbqsN>5w&wVdE5m7};Ba4&~fUb|}b;M}H;2tyI@yOdFAw!{;SeQqg)Z_?Eo z?Fh-72)o)_oc-?>4mgE<%wcJ=#C4pXa*T0=M0~937%+z5C#*NM!=9hoMfz3l`_eQ` zW6U*fml3^T9fgc}M-cyLBOzj~cO^9x`<3--*BFM$eNs+E{Bzq^zFszFmb}Q5_dux1 zm+RFdIHZwNjAhDjsFGuO#b0TInm876oegUFSVm;!Z&jLc1ou*9$I*A{eXE*{Bi;I& z%x>rv_$cjy&ZTq2q)X?S3de`ebA=L!wS32wPLWwR^^}=Xzx=(mNnMq+64YXbI)A=N zr612QecH;D&&?*~e7XdN$#FM1l!`GsQM>au<7xf)yD4M6SwyN|M_q>jyK}9D@Fi?_ z7K^uGclL25Y;%^k<>r>l+m=ENoj`)dt}CN@^tHp?G&;+R<70$46E-eO9!u4GiE0>^ zeVhp!mL;nss_YE-(y8XFa16t;VLj#PKiZTtxfkUi_y2aYa`wspBeSxX+B?-xx-ufg&j>omKLinuTI`f$}j}#;e^e{7z{e0xK_V7 zwfP6LP)r5m8i-;W?c#_!t`RMsw8``qq zosia#qtvb5nvm*_V`4J~&VRD9#nufU-uGxJC-CYnZa4nd_jmuIV-qv0{a@KwFO0A! zJXpcJoS?-k_6o!>d}UO%SF&Kxy;t|cI2Nvilx|!;!vvN|MnODFvDsz+f81A%_bUH1 z;vpYMr5Cc87V8m<>12nr8KYX~i~-ZfMH`EHBP6~0W&?*n{b2B9 zE&u6_l81NA{cVTAV4TPd)FF{mzCE5TO%`iEz*)^Qht!)5tnzDXj-(}1UmL%)M4*m~ zk*U=o6}XYDZ67#%N!_Pp3VV3cfhph!G=B}%pPi7Lo40;?Cr7!&5Em9W?U0Hjt}}?! zEOOpxLGI{61xK}Q?Fk2_5aP{K8#bc2Q>kO(WKzDH5Z2)t-;!bYVe>Fm-aE%mjL1-9 zy!>W}bGGbOs}mx7`U`i*s+`kTo`?x)b6C|Ru4^zHa#rMVm72|0r7ArlhU1IFs&+Du zj1H1nb6Cw4=EE>^9yhvc&G1yid)F8n!+hO6&zCcvS+Uyocr1GfiWDJ)R|-) z)iw(56JFvdzng|{;N#7|Tq?aQ(memgArQAEgh-KFRcVtl$G8S^6j}@eY$A6YRen1; z#y@hCBh=OZq}hZW{@nCu-OxVyVbjOP&C~uF)tyZaU*{OuM4mVA@5r*x@9i0*Eikgl zk8!eZc7(WohQY8yw6O0w_h&LW!Yvz1w%)&;R6RCRrRQ*ngyuh;TP|~{A#(nMz9hT0 z)M^Pygy%hFmiXu59YT}#d?8jdIe|U%^2Ub0$Qf)z^305Ph z2#Gg4rOLoz?|e!%-GVWr|0y+Do~@s21O@Ta2u@=A*higGmnE%A8_c@$sb18`{`h9>is`?c?3vMs!Es?uUlAg^-4$&g zOsjC=brV83o+qsks~q2vmh0YW(-1PbdDo8aC4MU<8QeaTTZM4rv|%)}2*zCNSYLvek43|B0KtcTo!&#Idex58QFy`3KbXj7aWgIn}= z8fouYvuBPhea>0+^beJcni%#0Z67gz>%eQBQx`dJz5^TDq;tx(LyB`w)!sqo@9BJU zkj(mJDJSmafL?H*n`t}nwvRcf=EG^<_LJ&yicCN5#0+%A6z1lm?(N`*ory7oT75aZ z-FdSGA`WCfTxq7ybIPsFmfZ=Fp4++Pmt%YWc=>xH#86`0&#P{X1FI*fc{?4x;q@<= z29l8JZ3gY1w-8%gB`DIfTj7e;{9f^hh$F!@lao-8)T^jlp9|`dBsA=TO0f$`aP+>^ zE{C^Q{BG-MyLUl#+U4-GGbXO?MpmmYnP;Mo^`5k(Yn|lpjGtQtiGA$oCAE(<><=!f z$i2uY$z{_Ln6psh8b7sdG%<$LTW#2jE?x(N)U!{jLPMsm+umM&T^DSe1P!}lRv=TL zPtVt%b{=mO+%PZpxvH8`4ExbbGxnhjud1m$g(qI9#PiSd=bnkvMz z^Zhk*Y_}*GKH#yd!8)V(hQ%h6YPpBJQ>y@K;VS&AX+$0}Vg97LZ?f%-;j={cpUdzM zd77D7tw8nvXR`hfF)hH1$K%(hdKR zH%js|17^Ww>eN0*NT=m6h{3L8`_rEf8Ph2j45IkZEe8n^%ju?9SuakFp1;k@wh>A? zC?|16>7?)s4-7~#;xZ?DgUwUiS9F{wJ+rEv7Jf2ae!N8zvZcCmL)HGC8WjCab$L!FZwaRikNJz!_glBSVJ|IEn`+MiI^Wkf&E)0{7~HP$&>=O= zj4>~}Z6QP^w4v!s1aH~eMSh{GlRI%!mAS%bn)bV?yxz_$5>=>P0B5udpo`>BI1a*5 z@|G!~Z1e2DhNj$h(F=!#!1`Pg->tor+;K6PZy32vY0kK<{13yq zqCFaQ+>hfLO+qYFI z=~*vsE6;lrC8^5x1LMkD1${^P3;dy~lfEmV)-p$&RRW!k+W4KLrYqkaQ?2Ig`l{vV zvQ=BeWN*rebN+EVAq-5qqQR_wqDAEjA}Q&}nKIm}o^NdB{RSsz=(+#oj+!q$O4s>A zjjG;J_n|wR5K~r}_c{$8o&1yV1x8HPWn52V)Y0DYj_Prl$_<85W}d~b&TXH6X;ZtH z(oVXgy8QshGB|i)7~T1=Eup2Jlp7P1)S){wo>7MCchxRo?0MIeN{dx#b3F9x?`1F+ zmC{bUs~*7-z5$NBB$c8-lV<5o6y9!d1j&5;3n6kKxl^)|9hcm7bTUGMLs@;kyQ@ka zA#T=t#+5YDjhl{WxXrftUQFtx31Qg~{mr;Jm-f}`DKC$Zr~FW($2~QXxUPk8Na}a< z)!n~v;M2)59N*nj`y}-Ta1?~Y`QyyiC02e}FD7;G`)1s0Vb31DN|)=;n2=KURhpxu z-W85q#N9o9R@Nau?J(@p%J{hv{s*!`i@tzP7eUm{;cR$Z~b!|*Y)(7e;aqWd3%s7El?173rj$8SGT6hvS z=#Dxq^hOU$SRL zmURu~Ogyumtb!6KdHmdUu4?^p&Wy(9*QK;d72nls8d;z$g& zJY;ED`t!7G9vO`a=Y6OAeqt~mRmFaCw2wdix#BM}j2@JreouU+x^2!(t}oab$nqq0 z?!6@{oC#=a^flvkzd5wMlPrDjrY8OD$Sk9$`mYpNFPHf8k2K5`@n2G|^iU5kAycbD zx|`}%i8W)}2j5ZSFUP94wP?`GBAbu8{yU{K7kDw^iMtxpiK=H;9389-|7G2#1!t|k zUM5o$f1?c@s_-?k(@QFTN*p1NIg_g)*AR2Om6cgGS7>sZapYjj;GuW2{g8?S;MTH~ zu27q<5T2i&CkxjkcZ$?l>UKv~f4cKlBCeQ3+VqI59Wi$95kgSC(yjFX$ddSaO$82c zWXx`CWD_*b7(cGlMG)0|QpS@pd3iZP_?b{EiIE`<$tCGb0O79dij+bPt1 zsZQb*PGp-N6l|=&uQ)O~SlZ~ZZr`3#`Q1R~<^o&Qy@4_68zhw+d5m#P&v&W#rAvmS zjGe00G2*E~^^j;*o5ve1)?!>YuGM^M&u@;J_F1Xb>DvfI_fJ>n1Li_^+q5Cq$}Q|K zKabNb5x1{>7pCGaPgTCZX-TuYE6RwG0h=s4ENh_06PG3Dxa5B* zf0(Co<-piwsW@vUh?P*_EncK>6>lmE(r?KLf6tEh%f|@76cOeqb4R5*{XuhErL$7i z+pO@!C#{m{Y{njXW%r+Vp6Qv|PckrvX7zNc#2wm#9?}8lrE_yjQ$x_DOuaa>wbF4=h~d;K+(ntYoJ(*Lwj^a zmF97bu8G%&WXkUMIM&Rr^R*VDACig8q|!fOYPW`*?wZcmnM~D{W5JWxy*??m%dC+o zxs>XgCk~$vi@=ZClOG&lsgbG3+)Q~X&!_y-#+=hUrco!af6mRb zKl6#Hfi@!O4O&(yXktbW_JuVuIB!T{BMkyIgaA zHEi_^%P6HSbRTR=x??45u{-|UQ9r&a`_Oh~itTKHs$?z?A6Mcw$!b|ts=pWxO|zJd zeDg}3?>j#5HS9))(bBD(QY}YVfb5wa`pD}1$@Y7KuJBr8Ktnt3;p`GdH3tu(l6}G2&aLPp6ss5Fp zS~t(*gfqxI>S|N#UO9%jBDh*qCZg1tUN(I+@mD#!E87Yz_}^qz)nC)0wq#Yc|Hj>$ zRYmjcI!+8R>3uq|-0YqEKb4zvSjEYqUd^emuyI9XGfU~~dK)!u)oocFO45j|Q#NJ) zo5fm$pQ+Ei7Yv>?X=VLj&A|wXo0OHey|N?;YeLxl}V;ws%wB z@xEk7Zd1C+-%nf6s?T-V56T43YpR2UNKsded(bvdM7~Od$Yvb5pU$nWl7zFH(~R5T z$NRYkb@yxnhiPBuHj9Gq*<=N(8a7_iZc#0H3Xh}*r69qkwz-!o{YVCVtoJbO^Wv}Dd@8nf)pgMD6FOU?=wk%!Aef1pE zkf(=)@c(-Ww|+I0UzO-w?ECY5wb3KkmB1Be`qHB@`DfTXyu*A7m`dlx%-O3tEGnB^ z%1ce?a0!%1TQE#nI1?~&=v~lOHO%G_;%d$NZdv^QT(jbedsD85lD1xTayQ#)$^CzH zH=8ba;&-#@H=;RI9Xm}GpgP+K~WHBg7sVsP-iB@J{FsAE`gR#HAi5p@;=k zN_Vtxkp`w2rB}IQ(Qdt4h*?w1X>6b><4!X!4>l{Y_u$IUe%N@CMMDAOEeLlT2dl~M z9^T;x;gFH+o4Q+_m6Hd37Q^wcasMIpRopYYfd9)u4R!2QNf@L-Hj_0s? zMQn!k`unPfif%aE$&S$VI;gv2?ZqTG{vgoZ6Sr-yc$V%^ebtX2gXX`@0S_f?WiMb$Mq zy*)wOMiF@t6I?DyIFnOU33E79NV|ST zpGl{A{~al_JxZ&rnvjAKc&3Efmx6wqprOlnNxi0|sqkO*-kW{ksc*!PuJz02k}6F~ z`j1WJP3a-G4tMC5}<4c*HCFHNW&DPmgCY5ev>d$3_ z$fQ%fP@Zp>_^)t? zikk10x>uSpqvbbAyeSkBJSIfO-IW`c1FAm{3?oGAZTHe@t;Ee-+T8f1^?BeQHnUMt zojMIsh!D{gFV|ciIXtZBSVHvd^;K#0hPcl4aL6ncaBlpILCMZtfJ3g8Wi??AGH2r1 zn+$sNg`Y2DRxvQiq(0NSM94WGEuNue%{JWmW_7yKp-bEAENDZYa_V?$#PdAAIVI+M zeD%-XnICP1Lu>fF%B#7=QXI z{W>el+b;47K-c}KT9DSGV9o-SO%W{o%IxTA>fBV%=dO#k+luOt)#^c7`e4j2MoW0o zGxaYs z%Bm_)I*;nE;(W|k3Y_nFhHY<;pBhFCJ>!qBrY5I@)3drdfSb_FE=L$>ylvH$XL{7@ z{_1A#*?T5y`e0!ic{!{Fmq4@X*>1FIp5DX9nZTMwGh|ZJ(tCtBS3fb8&!a;_d(1t5 zT+R)M(TaJsmAaPRqlPU+70v)(R86xCWBcCSdnK}*>{+A?j2`n|VD)7Nk9c>evA~m? z()4da?H6mS`5Bo!9@bX(#fFuvj;iiOPy2X^kh|k3fSXqx6%B`Z>LR0B>*bLZJN*eS z51(*V$Lve))5?E6p;~XbiBI>3C4`9JqfZ}r|0Famdsw5OsKoVklq;i0_3(r;H1wF; z$+~8$GqzM)lB~#~zl`&Oh6T?oe05$7+{>7t-erR=L)wksfBI#jcD;(IPcqTU`uLd| znaQKJEKuhgvd}?+Fpw zRVp*-=dZ6O;;J5*J@}=q`M^R|EzeA*yfC?#*`xYLBHz$ZHS;F_hN`c(M-A7hhBh}@ zCtvw|+PAGE-2w*eyjPwbsXI#qWKXPVzQVZ+tuoBri!)^2VvZ3dn-`i2o%8 zEen$Fe^Nze@i=LJ)mYU;c;WUYW*HvksGVWVtCa^0+0bYCNcqPb53P&i3f`Wwi8?Lq zVBUJ|N^p;Dv_qyQDys{Dc5b5T;)X5Nd0%LgX3dC`tvBiW@+f6sQ?tchrOvTAW0{4I z?6zE*V&1L$Z~Jr~-Z3WiMLyM^niv-?|$u5dMR==6*0Y_NNW~RFGNuRz;{hVpf zAqbgR5JY!EG9lYlseXRR zn1g5js_FMKWjrfef4Kva`h~VoW#9-)KvsGoah|xIWcu>;;0^~Gf4R(V+XqF|`W7`Q ztA|g=H#|xg`Mk-&1M|}^bl7dTp=5-TK*QQ`G2Z&tu+M6xe$7VD|IACh z&W5r`pczDg(hN&mnT0R9&hJgO9~Oid;x{y>c_g(udh3WEEm|@{y^|BF*!s8v-CG4_ zM^l=2O56X6Q0=laiJC@QXW}<@2dNX>LG3Kx+LXuY?2Q+{9`!y~Ov`#JTMk-QzadDt zPa74j+(y;T!MtPt+|)i>zs~c=q%#MOn;#rNPr5C?q2{BZU8&)a6;tD`pBKG#JBV3N zzx8p8tIKDHziMob$xL51N!5EyAJVc`fC-FNJpp0s+LaTr#2K50%_}9NOjb+|i~;NAVcg+qn%ly!QAk+`y1pBdE@);pnZS7Q%+YDLOe7;AX)~1Rm1=JW zSrY2;VHux3X{S;ZqzKj8seQSq@Z)yoApZT>kT2^;Y>@LsdR8gfUOmg@FY-p7*k`NgMFV42gIeDC0UXlnZYTV^Hxr4fzn@r|wj%&|XW=o#N zTg>a4!z#|&4ysTdinX_cs+b4uqv>jT9(4Vzj%uw0TFfgusvCJcHYIQgu{5Rp^->%1 zGJ_|0D$5UMiK4;Zg=ih}-Q>X0K~=Ea|o+sk^^5Bx&fAXPs2de4>;)n*wRP zb>O`x86Gl~AUR_+dJ-b7(4*LbbAxluHL7clxNM!(T;e+Y;SiCPSnhUa{q2g=%#O&A zbepD5<)h^L%bCagmUQaZci_9ve2v77*|3K4&Chh)tW09pZKK%M7iOC5l;0!N&RT6@ ze&kuEt2!sHd9=Y>`4vE}tWrx9U{0tk7vIZwBDxn~TAIZmm#(-sYUZ2kWt*}kMB@bbD3oWsOdC#ReKmd!sVVlM+@#+02`L?VWq5GW5Cd5yX@E&u!9+ zgDcAY{R{DQH<(X|i;&}QABHU|cDGMV$c`RrazV6(`6~_4RhLN$J@dREdPesM=U)+K ziLP#0owiNgWebU~hn!iW1bVMEJ^1!An_}JA1^$(`-IDjUx-wSci5JeUt`$OJh5MLF zW7ySuZEO8l%oS7mQhk&^ZDEzuUaOC4T{xzD+s(H6(B19X`>J>Fhllhvw`b=|miR2w ziBbn*Qmjab%mpP=wEXqfMTcQFH3wVHeyX}ZgDs?=S)rrnCnlX4GI)&v;`F<)| zIO=JR@CK_-t-GFC?3sK!NoE9Vgth6XPQq!G+vPjJY`H%@FQ{_^q9skev@be9xdQ%C zk9ZGMwc)Vm7^pf0u&`P%P;CofA`Tp6F2z0>r0z=!`+1fb{P$NOop0t$Vi)^^agDFr z`9aDr5UD(XLnha>Pt}ZUrA{r3;cy>pZb?fQ{yJHwi&_7S32_Zp-6U=(9Ae$ry{2+$ zSEHf}VmN9LBE53Q?6%&OzU*``CZxk)wTrkZ8W;2srQ){DUtJCKD97~8!Ye}l<-=i> zmS3A#V#)a>Dk#V!o9!D_N1Uyyr#So7G;xlp4dVQ)&fwUuf2y7Yd6bH(SI>MEG_q*e zaod12?_Mi&$mjfd{QgBthxBjVv73LV-kjXraPd-}^R};&%`}fYFFwE7bHk6W$ZR~z zIGuKB`)t?Tab5*@&cO47)ydNL?E3rPC3%)z!R@+7zwdM@dH+7W3wP`Od0V%Ujlfcp|ufNhiL)i+>BSUzWg-Dki zQ!_>G5AMA9|5+DMKnN%>z5T$_6B`ZB%>nYkZMaMC=BWrkzYLI6exhsBpThxx%Xk?fsp)Y^Q>H+Q=WXCo-#}#ncda49|Jsa~ ztlcfrQCyx}0gATh8}U<{Zf|+}94HU+(^j3I!QKh`0*eb0le2;H?;RH8s64v2{S#0g z)GO($`N5rcCF2Ij2~y}W_d*YnKHjdG-etm8G@aX&&0~9vDcfqs?IPxE9aFbYJj*s) zczWzvHq-68583j&w_nI%|Ef1_9Xt1So;mFN65JYV*+H&iFj&hzUH=G+0>`2`IV(WN Leotp?V4eT~;KEP! diff --git a/package.json b/package.json index 29a56aa..1a8dfd0 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "docker": "docker compose --env-file docker.env up -d", "docker:build": "docker build -t api . && docker compose up -d", "docker:db": "docker compose -f docker-compose.db.yml up -d", - "lint": "npx @biomejs/biome check --write .", + "lint": "npx @biomejs/biome check . --apply", "migrate:deploy": "prisma migrate deploy", "migrate:dev": "prisma migrate dev", "migrate:dev:create": "prisma migrate dev --create-only", @@ -25,7 +25,8 @@ "test:cov": "jest --coverage", "test:e2e": "jest --config ./test/jest-e2e.json", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:watch": "jest --watch" + "test:watch": "jest --watch", + "test:load": "k6 run ./test/load-test.spec.ts --compatibility-mode=experimental_enhanced" }, "dependencies": { "@aws-sdk/client-s3": "^3.670.0", @@ -44,6 +45,7 @@ "@nestjs/throttler": "6.2.1", "@prisma/client": "^5.20.0", "argon2": "^0.41.1", + "cache-manager": "^6.1.2", "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "file-type": "16.5.4", @@ -66,6 +68,7 @@ "@biomejs/biome": "1.5.3", "@commitlint/cli": "^18.6.1", "@commitlint/config-conventional": "^18.6.3", + "@faker-js/faker": "^9.1.0", "@nestjs/cli": "^10.4.5", "@nestjs/schematics": "^10.1.4", "@nestjs/testing": "^10.4.4", @@ -73,6 +76,7 @@ "@swc/core": "1.7.25", "@swc/jest": "^0.2.36", "@types/jest": "^29.5.13", + "@types/k6": "^0.54.1", "@types/node": "^20.16.11", "@types/passport-jwt": "^4.0.1", "@types/passport-local": "^1.0.38", diff --git a/src/app.module.ts b/src/app.module.ts index 9b81055..8945cb2 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,7 +1,7 @@ import { FastifyMulterModule } from "@nest-lab/fastify-multer"; import { ThrottlerStorageRedisService } from "@nest-lab/throttler-storage-redis"; import { Module } from "@nestjs/common"; -import { ConfigModule, ConfigService } from "@nestjs/config"; +import { ConfigModule } from "@nestjs/config"; import { APP_GUARD, APP_PIPE } from "@nestjs/core"; import { ThrottlerGuard, ThrottlerModule, seconds } from "@nestjs/throttler"; import { S3Module } from "nestjs-s3"; @@ -16,7 +16,15 @@ import { UserModule } from "./users/users.module"; @Module({ imports: [ ThrottlerModule.forRoot({ - throttlers: [{ limit: 10, ttl: seconds(60) }], + throttlers: [ + { + limit: 10, + ttl: seconds(60), + skipIf: () => { + return Configuration.NODE_ENV() === "dev" ? true : false; + }, + }, + ], storage: new ThrottlerStorageRedisService(Configuration.REDIS_URL()), errorMessage: "Too many requests", }), diff --git a/src/kweeks/kweeks.service.ts b/src/kweeks/kweeks.service.ts index 947e256..e9bdb1e 100644 --- a/src/kweeks/kweeks.service.ts +++ b/src/kweeks/kweeks.service.ts @@ -31,6 +31,8 @@ export class KweeksService { await this.kweekRepository.addAttachments(id, attachments); + console.log(id); + return await this.kweekRepository.findOne(id, false); } diff --git a/src/main.ts b/src/main.ts index 5258f5a..5ff5ab0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,5 @@ import helmet from "@fastify/helmet"; +import { VersioningType } from "@nestjs/common"; import { NestFactory } from "@nestjs/core"; import { FastifyAdapter, @@ -12,12 +13,9 @@ import { Configuration } from "./configuration"; /* --- Present --- - TODO: Add a authorization system. TODO: Send e-mails to the user when something happens to his account. TODO: Create the chat system. -> Initialize the websocket system first. - TODO: Create a TOS. - TODO: Fix Docker Image. */ async function bootstrap() { @@ -26,6 +24,11 @@ async function bootstrap() { new FastifyAdapter({ logger: true }), ); + app.enableVersioning({ + type: VersioningType.URI, + defaultVersion: "1", + }); + patchNestJsSwagger(); app.enableCors(); diff --git a/src/services/s3/s3.service.ts b/src/services/s3/s3.service.ts index d70f561..4026981 100644 --- a/src/services/s3/s3.service.ts +++ b/src/services/s3/s3.service.ts @@ -16,12 +16,6 @@ export class S3Service { constructor(@InjectS3() private readonly s3: S3) {} - /* - TODO: Remove single image upload since we can use the multiple one. - TODO: Find a way to automatically get the image complete URL. - -> iirc, S3 api has a function for that. - */ - /** * Returns the image url if the upload was successful. */ diff --git a/src/users/models/user.model.ts b/src/users/models/user.model.ts index 13c3e23..497a3b7 100644 --- a/src/users/models/user.model.ts +++ b/src/users/models/user.model.ts @@ -10,11 +10,9 @@ export const UserSchema = z password: z.password(), kweeks: z.array(z.object({})).optional(), profileImage: z.string().url().optional(), - likedKweeks: z.array(z.object({})).optional(), - likedComments: z.array(z.object({})).optional(), followers: z.number(), following: z.number(), - kweeksComments: z.array(z.object({})).optional(), + comments: z.array(z.object({})).optional(), createdAt: z.date(), }) .required(); diff --git a/src/users/repository/users.repository.ts b/src/users/repository/users.repository.ts index fa4b75e..535c8f4 100644 --- a/src/users/repository/users.repository.ts +++ b/src/users/repository/users.repository.ts @@ -1,4 +1,5 @@ import { Injectable } from "@nestjs/common"; +import { jsonArrayFrom, jsonBuildObject } from "kysely/helpers/postgres"; import { Database } from "src/services/kysely/kysely.service"; import { v4 as uuid } from "uuid"; import { UserModel } from "../models/user.model"; @@ -33,7 +34,48 @@ export class UsersRepository { async findByUsername(username: string): Promise { const user = await this.database .selectFrom("User") - .select(["id", "displayName", "username", "createdAt"]) + .select((eq) => [ + "id", + "displayName", + "username", + "createdAt", + jsonBuildObject({ + followers: eq + .selectFrom("Follows") + .whereRef("followerId", "=", "User.id") + .select(eq.fn.countAll().as("followers")), + following: eq + .selectFrom("Follows") + .whereRef("followingId", "=", "User.id") + .select(eq.fn.countAll().as("following")), + kweeks: eq + .selectFrom("Kweek") + .whereRef("authorId", "=", "User.id") + .select(eq.fn.countAll().as("kweeks")), + }).as("count"), + jsonArrayFrom( + eq + .selectFrom("Kweek") + .select((qb) => [ + "id", + "content", + "attachments", + "createdAt", + "updatedAt", + jsonBuildObject({ + likes: qb + .selectFrom("KweekLike") + .whereRef("kweekId", "=", "Kweek.id") + .select(eq.fn.countAll().as("likes")), + comments: qb + .selectFrom("Comments") + .whereRef("kweekId", "=", "Kweek.id") + .select(eq.fn.countAll().as("comments")), + }).as("count"), + ]) + .whereRef("authorId", "=", "User.id"), + ).as("kweeks"), + ]) .where("username", "=", username) .executeTakeFirst(); diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 08efde3..e0d31d6 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -28,16 +28,7 @@ export class UserService { throw new NotFoundException("User not found"); } - const followers = await this.userRepository.countFollowers(user.id); - const following = await this.userRepository.countFollowing(user.id); - const kweeks = await this.userRepository.getUserKweeks(user.id); - - return { - ...user, - followers, - following, - kweeks, - }; + return user; } async create({ diff --git a/test/generators/user.generator.ts b/test/generators/user.generator.ts new file mode 100644 index 0000000..3a5cedc --- /dev/null +++ b/test/generators/user.generator.ts @@ -0,0 +1,23 @@ +// unfortunately k6 runtime only recognizes modules like this +import { faker } from "../../node_modules/@faker-js/faker/dist/index.cjs"; + +const usedUsernames = new Set(); + +export function generateUser() { + let username: string; + + do { + const uniqueId = `${faker.number.int({ min: 5, max: 10000 })}_${Math.floor( + Math.random() * 10000, + )}`; + username = `user_${uniqueId}`; + } while (usedUsernames.has(username)); + + usedUsernames.add(username); + + return { + username, + email: faker.internet.email().toLowerCase(), + password: "S@omeSt!0ongPa22sword", + }; +} diff --git a/test/load-test.spec.ts b/test/load-test.spec.ts new file mode 100644 index 0000000..6a0b79f --- /dev/null +++ b/test/load-test.spec.ts @@ -0,0 +1,146 @@ +// Ignore this error since k6 uses another runtime that's able to fetch this import. +import { FormData } from "https://jslib.k6.io/formdata/0.0.2/index.js"; +import { check, sleep } from "k6"; +import http from "k6/http"; +import { Options } from "k6/options"; +// @ts-ignore +import { generateUser } from "./generators/user.generator.ts"; + +// biome-ignore lint/style/useConst: it's like that on the wiki +export let options: Options = { + scenarios: { + smoke_test: { + executor: "constant-vus", + exec: "smoke_test", + vus: 20, + duration: "5s", + env: { NODE_ENV: "dev" }, + }, + load_test: { + executor: "ramping-vus", + exec: "load_test", + startTime: "5s", + stages: [ + { target: 15, duration: "30s" }, + { target: 15, duration: "1m" }, + { target: 30, duration: "1m30s" }, + { target: 55, duration: "2m" }, + { target: 0, duration: "10s" }, + ], + env: { NODE_ENV: "dev" }, + }, + }, + thresholds: { + "http_req_duration{scenario:smoke_test}": ["p(95)<50"], // smoke_test: 95% of the requests must be under 50ms + "http_req_failed{scenario:smoke_test}": ["rate<0.01"], // smoke_test: Less than 1% acceptable errors + "http_req_duration{scenario:load_test}": ["p(95)<90"], // load_test: 95% of the requests must be under 90ms + "http_req_failed{scenario:load_test}": ["rate<0.01"], // load_test: less than 1% acceptable errors + }, +}; + +const BASE_URL = "http://localhost:8080/v1"; + +export function smoke_test() { + const index_req = http.get("http://localhost:8080/"); + check(index_req, { + "Response successful": (r) => r.status === 200, + }); + + sleep(1); +} + +export function load_test() { + executeUserFlow(); +} + +function executeUserFlow() { + const user = generateUser(); + + // Create user + const createUser = http.post(`${BASE_URL}/users`, JSON.stringify(user), { + headers: { "Content-Type": "application/json" }, + }); + + check(createUser, { + "User created successfully": (r) => r.status === 201, + }); + + if (createUser.status !== 201) return; + + sleep(1); + + // Auth user + const authPayload = { username: user.username, password: user.password }; + const authUser = http.post(`${BASE_URL}/auth`, JSON.stringify(authPayload), { + headers: { "Content-Type": "application/json" }, + }); + + check(authUser, { + "User authenticated successfully": (r) => r.status === 200, + }); + + const authToken = authUser.json("token"); + if (!authToken) return; + + const headers = { + Authorization: `Bearer ${authToken}`, + }; + + sleep(1); + + // Create post + const fd = new FormData(); + fd.append("content", "Example post k6"); + fd.append("attachments", ""); + const createPost = http.post(`${BASE_URL}/kweeks`, fd.body(), { + headers: { + "Content-Type": `multipart/form-data; boundary=${fd.boundary}`, + ...headers, + }, + }); + + check(createPost, { + "Post created successfully": (r) => r.status === 201, + }); + + const postId = createPost.json("id"); + if (!postId) return; + + sleep(1); + + // Like post + const likePost = http.post(`${BASE_URL}/kweeks/${postId}/like`, null, { + headers, + }); + check(likePost, { + "Post liked successfully": (r) => r.status === 201, + }); + + sleep(1); + + // Get user info + const userInfo = http.get(`${BASE_URL}/users/${user.username}`, { headers }); + check(userInfo, { + "User profile loaded successfully": (r) => r.status === 200, + }); + + sleep(1); + + // Delete post + const deletePost = http.del(`${BASE_URL}/kweeks/${postId}`, null, { + headers, + }); + check(deletePost, { + "Post deleted successfully": (r) => r.status === 200, + }); + + sleep(1); + + // Delete user + const deleteUser = http.del(`${BASE_URL}/users`, null, { headers }); + check(deleteUser, { + "User deleted successfully": (r) => r.status === 200, + }); + + sleep(1); +}