From a3018f0bc2d3208b4ebe7721442ea931c18a94c0 Mon Sep 17 00:00:00 2001 From: 0xmDreamy <0xmDreamy@proton.me> Date: Mon, 22 Jul 2024 15:34:45 +0200 Subject: [PATCH] test(reward-distributor): Add simple sucessful test --- .github/workflows/test.yml | 8 +- bun.lockb | Bin 504824 -> 508324 bytes hardhat.config.ts | 26 +- package.json | 67 ++--- scripts/create-gm-task.ts | 12 +- scripts/create-magicape-task.ts | 33 ++- scripts/create-magiccurvelp-task.ts | 44 ++-- scripts/create-magicglp-task.ts | 89 ++++--- scripts/create-magiclvl-task.ts | 37 +-- scripts/create-negative-interests-task.ts | 29 ++- scripts/create-process-locks-task.ts | 9 +- scripts/create-reward-distributor-task.ts | 9 +- scripts/create-spell-staking-task.ts | 77 +++--- scripts/create-stargate-v1-task.ts | 81 +++--- scripts/create-stargate-v2-task.ts | 51 ++-- scripts/create-velodrome-op-usdc-task.ts | 53 ++-- scripts/create-xf33d-task.ts | 33 ++- test/reward-distributor.test.ts | 158 ++++++++++++ test/utils/index.ts | 64 +++++ test/utils/setupAnvil.ts | 36 +++ utils/constants.ts | 6 + utils/crosschainMulticall/index.ts | 24 +- web3-functions/gm/index.ts | 287 +++++++++++----------- web3-functions/spell-swapper/.gitignore | 1 + web3-functions/spell-swapper/index.ts | 199 ++++++++------- web3-functions/stargate-v2/index.ts | 26 +- web3-functions/xf33d/index.ts | 2 - 27 files changed, 916 insertions(+), 545 deletions(-) create mode 100644 test/reward-distributor.test.ts create mode 100644 test/utils/index.ts create mode 100644 test/utils/setupAnvil.ts create mode 100644 web3-functions/spell-swapper/.gitignore diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5dc6e1c..cebc083 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,6 +7,7 @@ env: ARBITRUM_PROVIDER_URL: https://1rpc.io/arb OPTIMISM_PROVIDER_URL: https://endpoints.omniatech.io/v1/op/mainnet/public MAINNET_PROVIDER_URL: https://eth.llamarpc.com + ARBITRUM_RPC_URL: ${{ secrets.ARBITRUM_RPC_URL }} ZEROX_API_KEY: ${{ secrets.ZEROX_API_KEY }} jobs: @@ -14,7 +15,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: foundry-rs/foundry-toolchain@v1 - uses: oven-sh/setup-bun@v2 - - run: bun install + - run: bun install --frozen-lockfile - run: bun run lint:ci - - run: bun run test + - run: bun run typecheck + - run: bun test + - run: bun run run-task diff --git a/bun.lockb b/bun.lockb index af256e036c5827605bf4edd8aa4783e167efd7b4..bc5b5ef7b2eb73b723506fbc5e411502548e4e01 100755 GIT binary patch delta 105335 zcmeFadz_Y2-~NA{QYm5r_dMU{`F;QTy}Djzj&&Ss_gSCy zS?gTqd7YE}J6k?_eXBdp>TpzAo6$QP4LJJC*^Tx+Iep&ZFS6IXH?2igzhQHFx7pBT z#_`9ktrOAb(>bGBC4IMP&a{&&Z}cLO`jJRgj>C%_=9d&*RYK96vH7LtQ{s{7=tono zd#y;M9$4sj26#NYI9?FX%ZWsmQ^$u-DpyC5NG| zs>%xU@^kYekZTySAfA#pHu5XtvGBhI3%sV4{jgk}#=wSPJFo%R96ScB=kPb0mNR|=k*XdB)!Xg- zQZG|-ic8{U#gj|og?X~|@2=cRS1uk;8JAyNQo6+P6X}F@f>_ef&L6w7Wrb7n@n__3 zj=$>44s#>E8ACOaZNaLfR+VoaXDyhjx!}{YiM8xWP?kRc%Hjz*%vT}#%!T+!kcO)U zfwFuq<%G97+|tx~WI(e>g#W5ug*O7n7flIAb}k}apI$YOR%Fgw&20ng92Ue&CluwC zL~?R-<5NmYBFls7T1_jjWDqjz;S+81@shD+`IGY^J6l8|^iZ`KRJ8oX;X;SEJDd(; zVbwU0?yH75%y4+R!{Z$$IsDM95iWb-BAiEzCHvs;Ef^HVbS?=N)b7}NSvwavWd&0-eRW*% z+zHGUVf{w1w|3L!Lp#_yn?U)xkK@CG*3ov&mz`>Tkryv4N*SA9n3GqKGChAvWK56~ zZCd&1nKqRF2Fj3}iCE3&trY8k7eIM(Tuw=8N?CFKBDf6i#lW-#hIO>%&Ic7R-5s7q zzUrAyc19{e1+uBh$!6!O*Judd^_K*i)rQ2JD`B{&p38GIC!2Y#cz+S}31 z4&)66Cxc7!uZlDNNQ9LTFD{8h5*7bA;{P`nCOr4wdE}1+OAJT@sMH7&mS5A|S~ele zx+o`JlA=jUjJOT?a(TiN$2gt`YJ>?-Bu1W?(m#4&5arcxYInx31{1-OGi7|(;l^~k z&;GTK#gqEl;9LV&@GU1_^%9;-7@jcjkA~IgFswJWY}`0q71qfAS~1I+1_ecFNlIZ+ zUOZCHR;bVC1MD1b0aY$9f803fZ@|OVQaoNXvc~1-JqqC$NdgxJFIYc1<2M@ z)xPpV8sV=VJRW%kUYGn=ha{poCpXSibsK8+ zD)1Qc-vu?W$@wLv#mslvFw5TtRll;yaMuum_MOMzirRZY8L$#vSUfH-SB6Y-75x#m z-e6D$|9+9>`{C-is4!m2wKT#7H9t3HT;V^+SNoSyUl*7WAckFB)t`hi{@CCPj8K-x zr^R!1;r}_?F0AFOJi~mGR2R%QT~gr=%3*Org`iU1klM$wgL9r~uVr zK~e4m+K7A|x3kxeD3$(><7>di@Ml1EbR%Ia1IA6x(YPYlz|~I)sDUjA%T8iRF`6J@Jy< zoXI(P@!ZMzWq2g9%oR}DaidW$F0pX>DNDKEVo)W|l{juyfi zP;vPjsQksCJp7Quu_awoW#HJHl6Xq6>6pfypTi{8NSJo)_15IXjZET(C2^y&EogXb ztIEWJO2j#*jc|P=w#h%n``DssaRtEg8?9YWfU-NWgDil{&cybZ&=ZHWm#|Wfbkm*(iY4EIiXf%fo;H+4*zwhHRKbpHTsKStF9ytj37@E8GgET;XRC2 z9(csqOX}J4?3JnQyx_|QXXSi6-xe##FJ$SLl-6~ejU+dps()A`hnGmoz1D$0(Off{ ze?8ke@~R2>xh&bp;VVoqwPDlz?Ud36(i}V*yedAn3xy*24_bYT!^=TU+r1Cj!Q2k2 zeBvp4ms(tWsQxT_ORW^ZwmG{Y+5<$5o_B8pe9%QLC$3Ec8iNR4U|L%JZf9b zD=J92iVeDd#^)XTdIZ96Z6jp0R)S=atVzN~8UxV3%xq?Wms9%X2tI(C(X_ zHRwz7Re#M>>W65Imvq(E7P)wdZ75z+7#`8WXAV@{j4p$?PKKW$aE(}X^yv-P2w$NC z>1lM(2rL>~#A1jt*k6RblrY8u-8`G ziA~%bo%9!#>&*$Jtgt+nqw`7%sNps*+K#WxDb6n}Jr0-gx&LsuBCSZA&KV;pZLU!%Ml zlyQ%Ma%;WU>?k=ta-~IEAGTXr^~TB_F#q^=-W|c(<68~Q{hKY5nBxMty!8lmWbER%ZGPfbzvVmj z&N*?b&s~0a7nXQ7c6ZRZX{*ZF)b^>}0n?j;V<(rz$L1I3CFbalbCB_#T}l5#-ye2u zXX?w^(>@6O(Ce^I6LZp@0y5}0_6kjI;%>Dhx44`qO69*0!pEV{+-iekPtdSg)3If+ z#;8AiWX)syAIAhl#yb7;kL~boqPAxGBiBkt^3_{GydY0c$|jeN4`Xw|r&gZ{HYY#p zf#Bw5Ei0RUW;^}kdQ7ap`s6D>;>E>ob;e1dY8+yo2!5fYb08c}2^>_TQ5sm)ccJS*Cd&GJhJQMv< zQ28ZbXYfL>Etr|)g-g4Q%ir^LBytY=Ixq#C56X})YJ1^P?JuC}6`-r#0bm>Oysh|O zbH|*;C$p~&t>cBROWY@yOb%~%BDxLfii_8gFPAO{RWEU0eXQ?=(Y_Fr>mMgyF*FZU zFke^K>WQf;gDby#Wj!y9-UQ~dEY$E(N81XC+x~bV*R1@)@rj4#BV4)C3B^Ta<0qWG zf@P=%y<=>9yXt%4Dt`d3;7jZhWp25CK)wc2c>xV+`7~%?g~4Q~p=aS5NiLxrXXK?h zdX^uFn1)_>1v{aU9oey9J<5G_oEL6xU7J{aTv2gKJSTU;!p1g#JLQh2+(pNGHkK%l zXDX{sY-$^P3X~yVQbBkhT$bMgYS+BZ#pn~@| z3|BjS;myDpc&yex8!Ia(KJ7FF6=(p;(hp9uymJdL+@5Qp%QFY)P@efKsB$lYGW1#S zXz*@Ob3O}H`ASgb^Ffs#2FlR$z+<)kA352MpfiF-bP}jTLLG;{;5v2iI(Q=ZG^i2G zWJKzy++pIYlF4v&JQh^P9Z$6$Z3D`{(dhE99^M?o)0@coZM|@vr?m~9XxXxV>Q=k2 ze07>FpNPdt?QDBXLD^Yae9pNFiJ_F2>oRXDpUPeqkh%sPN0#Ho(3E)zO3J*pdAJiciwBj-qjqYr5KwW1vQM zH~Ha8p`Hfv^0~JBU7+-YM|#D`SAgB(GM2l7_d8ykYA5(HxLlWLAgl;a7?5~2do|@0 zh-uwyy-uJydQTWCAww-$&CLYU8h=&hhBZ;d*YJcmA zo57P65se1ewQvpC65fUkZ8<{*+Jf8$aN(O+k~qC3o?;~~A5AH*C4P9RUuHd$D4!P} zTQ;6GGu(MD;la@tdXW^3cx?WZE@>1fD=aE5029Z^D7(UOA4|x+$gMS-h&HCfh(A?p+e8k~TuG~&g6Z5G4hhucR=~A?8kBgxj#I zo-aq{IqtCX@b?Uf?-AahK{fCgsOi21)TONi)J1_;4>Y<+;$}VZR=}OP)}RVdewQCr zv<+Nm^-&B^`fb$J!0h94j(UkmN%-lrxb?thP$PRiXntC&$}h*;aVL)c*VByR58+S5elO!306@%n=Da|)<( zO+fkkP?2x|51C15Pksl~#d5X7ywNXS-R1f@*Zy|Tf?6;A1 zcfPf(LC1Gmq#nHNwkKlOef{k6-7PQpaoV!A4=??_?yu8782IUyZPyq5vg!AV(W6^j z@z3C-g?B&jUG(HDvfA(cY)?tkA75DZ#RbhgzdldFI%8f^;9VT^f*|d}On)m{FSJNd z{eEgtJ~-1Gq2Eb&Bn8ti%<$F)t1iq;s#PmEcwt7;`L%*>gERbVYw=YXRlLCaS89+p zg#6mU^dT8ZvD(4vAsNx)+T1S$6@%0L2S{<)sfq^G7skAuLHW?kq~_6J_0SA&c5q;5 zrZ+E08m3{zmg!$p$JVSJcw=JzbFkFV@U`EjCOZ;UR`kqd zZeoIp3)7=lgsDT9ru%o1%Ak0yVC~SD_j$1DqRgbmesJ)j41XlsfU>Y?Sj@XCC?ApO zuSM&I7WS2NT;1T{hzxINkTx>Yn;Ddk%=AAcDtl9a0b|U`gp7>AV}oOUHY^ra&Z5Cf zg7Q(B{$he`fXbWdx?XB|{G067voP@OLz#2XkK zxGWQor(K@u??%;F2*ejsliA9wiPe|J{2UnTnYpVT9>(Yunf?|uObHwji> zkrBOsEud#`h?Z9cX*rqRZ$WuZrk}&|lO41?BIeJ9DY&uf_f+rrpxfw-XcHD{x1h)9 z^yuI)bqFhGg{d_|)4g3mT5hI4wpk>SZR^p>YS;yq5pYMb19S>~doHOVp}uxUYBHod zBq@x!_k&e=nf@_sCYnrUJ3Hq0gK05f%wJh)@l5|E6xE3YYcGoV2VpWDwm&tQ{l+G zt4R$E%l(y9|1j0$&Qs+$oXB`C)6998Nua zIJNt5suLHMK4H1C!>QGWQ@~USXGee z??CHqy*nZn?ZAVQ-T_nV7m!k@g@NfWf%UR%SS-2+)+yYmTD3bIzD)RV*qM~79js-k zRR*hyGW{3P?Cfdz{S>54$@I_Uv5zLHmi7hj(qPq;%;-aC=L9|S(*5^Isb?a2WGs4I z2ln3JPu`)rU_n(6Hh%1bkoPCheOU78V{z=+r=2d8`Y1!-lO z-giNHS!T3r3XU>dp}W^6)iLOS%RVDz<4kMl%(D_vuFdZnm=-HrD-*FC*4Hu|a4<-_ zD$|d5Bn(20Aw{2prG~@)J~(hyX3}Y$f^O3?qEF$r^MW4J(xZDw^$%02T$;j^KbMro z7;e%@Z**1_KN+QeC}x$#ylKIK^33R?U7WL{TS@f@))b{jo3MuZgbiLyYG9aJNGj~k z-$iP0*vi_kQfqhBnvfOGlVSrLoF4t1)P?3y2d{fF)2*Q%6;zLkMIVP&5 zxkx8vV?uE1dEOCFUEV zY_#>>l$iHpaG*Lfn$jb*=Z5aJNt_oPs!ortAjOVA>bJwG^Vxc{LTx4~b`EmiBV}tG zpBe5yXmL{PKh^0;&t(P&t23f|5NuFjY?IGn>32mGohD0T)^MW;%-IGbEt)qgh(J?=XMWQVw z8mwjBGhhTlRc*7jxfe_7Fd&#dJHw9-v>P0&m~E#sYzSrSny!YaJ{!sKn7;<5EspJm zZS{Lt?_dqr`_5btS^Vf4&E+uFNeKSayW!7QoCAYFKqh68tGB;6T; zzj;t3GKwmkqQ=CMvMvk`-jU(2y)Y6PhUl5W#@}sL^L&Eb> z-HU9%)D6~-O-+WdfHYy{A<=*cmy2Wm3uLM7qr#pVkEq$xIM_(?!h^5>qRX=<23!j}qNK!_-%JzKgcM1QwoPFDBJDti6PkdJHeh{vMe6u#w*GQah$( zEzM*|x5EYRhn)+vj(-n!*fhW17`up$)_K713zG?U5Yrs<6-%7x4?K|RkGkB(XmXHs zXUw}PD1R{1e+!K*)gIpb_X6+yR$GW;26vWN3uQOtWeSoKh5QtO=HAX#H_ ztVf6u4#oEd z;a`-S*g7bpyPZceqZ`q>2ONg|Xr8sw21E?Tu2ogbWSzk}f%SsfybocTvZU~&dqzAG zzC%bH-WGR^JY@F@qDM9mi{z(S6LFq_~eEUf(69Rf5ww zlO#>B^Jr^lz~neOAgZRpdc%lD_O=&c|DMQyx;(svM^f|I+$nin;5`!a%V9R^vK~lH zhR9~-f*C(?V!{s!_dzgq5H4|l4$KAXs?=nNoWkbBk)i!0IZ{W#JW{R@tKebjlw$d_ zLw^R7^~_my%x^c@Iyr2?zZ#~l?Cib_v$3pQu4RE`lw@6ubd0@{yxU-^XV<{HFokyQ za0N9gw7pXg|6B-DNha>2RK09DAS80+_b?e9HCaCMU6klt8~#+7Z4&=PA6H(`qoBJA zNw#~&8B-FYW-ImilZ3E2yTBfYX)Lzn=P=b{mE!J`r`nRl?Vi+R2xq&h24Q3^g;@(_ z{I4)YBty9{=4Tb#aA%lzu_?huhE1yT4`CV$!4GRvl9&K(SVJA-f(e@qb53Ti*Tb~d z>*xW7{|ii06sAxC56vRehOAC&y2Rek|k<-q;Vi6rMcn=!XSQgEZhl`dR-N)UXhVh zc2#h2MTWoVDr+d~gF$==lWF#vbjmc&A*Ldo_DE?s_E!7RAnk=re;=A+lfcIroy)B= zxKP5XV0J&zGI+)1*)_NyrUMas_RiGW)0xijf>S^$d?evNsZ`jRJhB^xM_A&muU1*z zsf{8fUxz;PW(8@hGozoP^$jmrv1{ysgSnm)^W!jUrWVaBuzrb}esYD4im)C3LfA0! zI2yc`sw}N|Y$klVUVC_Ty_;HFM2`jhFG!tZTPuk9Eh-N?>9N$>kPJjB+&xt(htp1UASqTo4c$a4orXgHM%TgE%P5gl9k#;rv7V&5h4yf5i%u5{D!7?j zPD(RY+fA|{&?Rdp8zxj1`t#BEw)V6?QB!R$2ClD9WVdo9!Na-*Frte`{@Ow$~mP5hT(w!D_jAy?9#MAL4v z{$n4wJm#0ek`t><>ZO>zPR%W(Lz=&+xC9X$Q@EW|9}c(!%b%busVb zAnlDzKW~=ZMeK@S2~#YE*Qe+|VcdMZksj@Jb0Squs!MR__wKbx;6XC?kcx$=({6EE zQqCL8Udl1g0J(ds~^E)t25QBI%=GVS861gN~T0+mwjzm~DRS~;Q}tTa|CTa|ob0+-kvaIlI`~ zu;GW5!RoYA&d5($NnB34IU)b3q8D? zCN-WP9DFAu+Iv1x7M=&MB&7*p<0y*xPr$UY*upXGtHXJ0$9~g$YD8Gl(0hXE?`HV3 zoEToVqOZbiv-?OX>^b*gTeo{{IMN9l<#d?xxFsO(IhgFT*Mfh-vO~izxX*?@rSSY* zn3e^lf>`toSl@67*T26;ZGSLKErd%hvZlqNePCUJHLs*cr;*~c$RTIBQk3Uu zCwuabFuMw>-;Mcc58DGCYl1D{PM8)w8v@%+%SYJRgNh*>lSs)2Y|k9>?uN;4j1~WE zh1ojZh}7gq?VN@;<4GeQ4OV}g;oTM-_&C#ln=E-KV!RlUzp$qF`op?~?JL@@4-R~i z8U0)(%$j4k96pvfgmU_cR=~K`<$2FqQf%C>cTaxY25V@xKLsZ92wh_5IoJ?&8)W5j zK3$Z!=*aYoV2U|=8oL2@9?UxV4VZ%3vH^?jvJF{u0j!rfbOol78k#7Tbj}mO>d!Nx zg->YXIrKsIWD=tjx&Eb3)|g=L@nF>#nf}jcax9AuTiZXy(-;_Mui}_r0F&idw=U+t z3Dc;;U`;xDNpNs`hM&8{`ppjfewbTOc=5Af)t5Z!e%e-}1D;9_ft?;yQ+)TTA`4Vb3e*7KIyJU`rCvtVh5dzfC6MVE;Mhd%3`{9FxJ`cq+9i7MVJLHW*1 zf8?^7C7y!~2upa^#r%J{JTA=@vFN)9)E95#ejlFZsmSwJu?W4n2M3*-Bq(dkKNtO{0-%J8pWWzE6;D^imo z3JmN0Utx+QdV47~d39n5aJlxcf*tmx|30jrEjW@VRDTJk|Bw;A{4dlF4&9j^T|g>) zdf|UW%0>)d6eXSYVlaJAhJWRYwo`j!_ykP;V;QnbeGS9sKcpv}ye63bV@7ny8aD~i zTS;{b4n36azfLMOVRiI37$>8h-TCfq_1+Bc+Tg(6On=EsiOq+@r}u48{!^yk=4I;{ z&MIqDxm{m9n!8#wd4O&18*Uz8F&Nt!@%}HErjbL(!BoQM;6F0_Q`Xvb9X`2>&WG`6 zPe)Kvs%h6v({*-Nu$SmU*!i|q*7ACobzasrsmZU}9n9WhT>?{w_NMAVm}1l3$uxT{ z;YxPGXf`ao;r8z%)r(U0%JmtnQ`l8CSGDHrtrP6wY!pmkVzfCHFO7!R%SO z-Rssod-5oPX?7UMkXUpvtXDYP$Q#xgqKKW2tVm8f(P^-*L60Hn(Iuq1hc{ijN!cA!m)s6-+jg*xR>#8>3@oj6 zvFI`wb+{MUV-9#;W;FGkNaWJ+1a=oG#RAnZ`)imM0kaHiw%N`m^T+HAgR!h1N{`+} z>YU)vMd|(qQre2CT@g$2-Zcknc^UrM@7j7=$*IYZk+uj&<8?3v0jq;&=LcbD!PwUc zsv+-%5Ak!lCzH^^U^C*x@j2{*km)AnjQ8zY2%|h&2J2}m&gLeLRCvwz50KK(i8JOl zeM=%%bh?@Zle6vRd@(E?#+8pn{xwYX!o29&AJB4m)+<&D-ENJ~!4w{>9oqW=X7?=I zoYek9b1<3l7k_BI7~a_VkHPFFr4{lSY$)}Q32)c#->Ta^Zswu~N%3VnkLOcAN`!~b zqlJ#ylhmWI3qxD*MYQ(EcqaUUVhE|T6S{vLOr_|b9)E_74Dc-;4Q z`^d$L9Bf1n8-iLd8O-B{Ae z-z4v7zJ;f5vA^d_i)CIn9?@+Ld%oRs%utv zpy;i2)uV1JH<02{0yhK)N%f+AyGZ-g^TH)dT(Wh~bj)t2>tMaZlDcp-INEh)vP#%% zU|Q;7N$*B;;0zY?%dQBA2Hr5L#|wa}&id!Mz@@NMSa?;4-UaIw-i6ma#x@jgOVQr2 z@Vy8BX;SWrsw;wHEPQTwGmf<`3fuB;c8o2A-RJ{Y_*gS~N&`xT`*k5H4H;wE>{i3% zwea>d`ZLUKt?l`fi_YkrBp%^a64hOrMZhGQ$3hDgY{7zKD!U?d@TT@8c0HlfNi?Bm*)Dk@WSgkPkQ(sWiHGGCx^ffVLaR}>R!90e5ZSr@uUiT^5WD;^BvBs;0U0W%-D)N`|w~RWP1_F~)_Y6fBf4iTQhAx?Xen z;xSUkcGe=s&lSJSG5ZDDt1$V-UfParZ(C;t6ZDxd&AiQ<KZVn)Fn0cn(xa!OgrSGiOGqiOtUFi1v@=*^_QHCH-7B2Bo|P!6 zwr0Y@posoN%5Gp89TUM@y)QKx;`Xmk83{~dr(y1en|2DTOiA~zA*DGFed0d_Q-?$k z2b~{bns*p6pVpa@;o&l$l#Ma@=nALQ}(9~FuVBVhhzAgDZ6Rt`|@m?xS- zi17Ch9M03!^zCW`h3U(UMQ6am#pAzBO09<``_Xgl;BXX!&V+?mM*mGxZpXxic3c>81-!7QF9#S&ehrjA#<0H&wkaB@Y3opa$V5%SB2s@0~ z=#_384WIh>(_pSc{J$LLjKU}TVLWf+(L-u?8?DxmDKNVbwK1%K*|?S~8uhRj5$od# zFwHKT26O!y%$8IfG|#Y%E&7tw+7O=EaHV*Jlnk<6eJ4F^Kvgp2~2X2H~^eQdc2ron{k#jllRcXAjdN5Je3C^i?SU9PtA z#&Yp=%i!pBQVEzUFDF6KUE_<3eJ=&w7^ zc4*B`>TR1Lj@fd1!sHmcf4m5@7ofFYvQqk3Kikmg1ylEUJueomQeOBNU^ywR8Fa$* zXIS_mX|z*ck0&-gUPzDTlVTNcp32Ag{>OuJZk>WeNC z3om!ylVZ=}Q9#Fji7C@IJr$;S2;Ez2VLvw3;vW7MSBA$OOmg4;c6!)~ho>e(Cdg!y z)qvZf_5*a?*ULfokje{tmREm+$r~KiaQ|fk6D=t3VVFIG>Dm6rFvTDzaqgW?z98XK z?LL>n>}8C4-Xc>zmgTY=(XLv=Xoo>GZ4M=KH&8%QE!l@O%V4?-V+Oc%?tuM!5w^N8 z5q=uqSjX&+cOOjk*gCkV{mn7P&V!D~;2QS$7r-)Y4}|;EFa|&w{u5^JX3x3EMyoyW7mI~< zJxl6vZ23(_Bs{9cJ_e@I+l_Sr%SEkC@N#>uV(|P;!c16Z zu;$D3=o_Tcg9;p(bcGEP9=QzV^)Q$Y0JTk47tYnN@av!Geo|~xyqI@Rj&&f*XF)7F z5f+~AqmP9tP0g32bQc#fUNd%(#$z$qRMg@b(O7e^j6?Sv6y6S}=m(?*sc3k&c5bd0 ze$x>$Z-F^*CA+~ph;}k{Zc5JMFJq~|!yrOD;X7Xsxfm};|jxG7%@Qy8$HzrmaNru=F~dDa9kd?B29+Q4_w zFustSnqL1EQZnC*@Q;*mY&s)6m)FftEbK52Ve$}vw?IhW08?l7ZN=wZNv`cg*?yQV zEX+0E0-ZC_)7JyMzh6Ajbi0O&;`0;Dbm6}yn$^M{lgvRdI(1Uwrgs&o!L)$!TwIbT z6WcI0623uS1siG(oxx6Bw;(ZTUNx_P7MSVR(%ifPvl{gOL9Rj=Pjf}sHwWPwS^HKdtyl;-|I4HlRL2&B&<^+kz_B z&S3{oA7L$ixK9c{Le(RJ!%t0AeeP~1h8ZNng2a&i&Qz-+{0NWYhcy%CmhE#pT8mh+>}e}yW)iXTn#%lxR`D-PE>TnB2l*7GAn z-rz@{H|Rh792Q_Iu+hqYit6A^moGe?pD!H$pJL_zw8H=8@|B_Ga?Mx#XexH{BbR>1 zkMuqK=p)p~e-z;(6zA)M5Pt&o5vm@~??X@i0_sx}_|ghd&^bM?>=Pp$J2 zszNQtg-X_TT&QH!aiM1pE%BPRmQu&be}=V8#Z9bd^?Hme_Ftif)sS+srZK20$LW_T zc-m`Ksq7O)9V&Sezm5YtfvR@4%NNSaF;MlofyzpE*d6rYeLw{^Hw0mQj_lz_SceqH z&+r3Qh7EBd3_mqd9dm{Y8{lXaeuOgM3Qz`cWC-)QqKAfXl@1NyDiW3}1=ZozpxUbd zwcpfmdT{~|ja{|3}9`isOrpc*)UF8mdgVZVXe)aoLty<@>-uqmi=&H2?B zJQI`$&IM&yWhMz()(1Qmya-f-qduc`U&W-s{bI#=cY1Xcc3*VTGguO`YV zZ#(_ZP+6N@J~%OS#=8h=_&ta3y8=QD@?%iW+~)E>bNNE)+a3R}Flu@{=QY&|j(kIL z)%cEIo~b}Kw?2n!^sBQn_P7FjMflW2&Gtd3hiEp@KzJ$n)ycvzm_YUSyVHf@Vdj5> zD(9(@{{~aYKdV-FA_)^=2OV9-ny3alIbA55&UU;eYPqJNb52>Nm|3Qn`47Lc)Kt2w zDiqiM*G5fdIK3un4;<#o4Huf(vvHX=ifmW>zd|)X+Lik=RJWJ7e4+RlQ1vczc)7zX zKz%?R;=;sXRD~Q@aI7mR)CMroaiPjha$G1rS=`iL;prb0;$QoM%8n^6d#bYe2&I=e zE>!tahh+}0bos(M=KI^cR^bt~%E>}it9HC5O1gnx!kb*aP`k#hjti5_nA^RMp+oO< za!pk8fzxZE*5iDq3svqOP@}rf>B3rO+wE>$JmiWkaK#>R#e}N*)FLnGmP#>Z8+_g?$2g=M1wYV;-p*IouFS5zuJD}XL1yufr4nK1E38;@y27cQyJ;%8W75|ZlEkp2h~9@m;b*(wRgU& zUlXNYfF4y?4s`{D$CyKRa#+;B$3kUCuFI~8((_z?98{5fS5BzX_fFt-2UvW4n*pTl2-rpH`&kKoa^ zYA2}=hbms%=~1WGL=8I`T|FEP>Ri|y)B-#ORDN5>&jRbg(?ETM;=QA8FYJq;;auQw z7$^fS0@ctc$45JUspFS9yaJS;#)CTSO?7-4sDYJ(`uu0KVHakoqiZOr5mkXQ;5vsl zxCVq8;cTbh?sTC#y2Ejy+6x@s?R25qod>G?{7Mqad%$Hp0 zP2{*{xZJARC$8A1u2@Z!{hvAg&rpusPQD^!Cn)}nD_;{O?ctZ&+Y9Q57d?s)(}zT8 z|52a{B&)UmCCY$$)K?@N=i1Z%S4$tE2He!~rbnG;g=Pry_(`A|Xypq08Op%cE?-#N zw3zQ4d77)$PIVjH+sEMjL0bRRM8K{t$4(eKQohvU?a;D>dhB9at z`SQdauG}4!i3F&Q?s7QK=`~Re%tsgARjLs^NDXuZe2sJ#>ZY2R6SlOlagEy9zZ?4SnkL zny3aocMW~%a0jRu_`#L0iRyTdEBBMj7e@8RHNQBaCaS`IrwhdoI4-PZ3hr}<{?M&t z*F@P@3wNtpZHG}%y8hKd={~6O)dSUXLr|f0ywjV3^2Pix7;Cfe4C_V$!>YVNLny8Am zp$l(!`9kqKK-Is~=|bs&!@EEo1s(uZuJR!g+W4LX^%1JVQx2Da^1ySTJhQ^-&x2}U zC8&>3u6@z*n%DsSuP*-`Q0;F9&(fj)cM|HLHp5j$)ZtMYJ|Cg22_LX!7vydp5?H!!*d+Qz$A13gDfK1(+8@L zP`p1Vy9YQN=<iBTSM}lhSV#mjTs&|>=IS%uZaiSU+?}UjU|3!-V zr4C9#RV;IOr84;l<%nw>UI(iD4GwPvRqrNH?cWUQBb0uN1heTO9HMsS zLWRbatBK5cD(Rqi2&4})s|5tlC%f7IbZP~{(Y`9eKzUFP%^a)_>U>k#C@*FiP# z2B?ov4QzDymdpRE!%d(*HBsf?cI7v_a_>5P59GhdC;Am4yNV*|3n%=apbXsZ$_vH6 z1l94^pgi`i%NI)j-f^MI|KRu!l_WIspFkD-C#Wg>1ysTPpgwLZlJ*En7iWytmDGGK9j}QhH`D1tm7C@G ztja_J)W~iHRpB;J1#frxLh(CX{+&)2>cQOtP=+mX_>9BnL4AZ8&?}A$<*~}wNXR7{ zL3QvZC_^@Z`UvHr_dpr81yuQuL6!f+>DwIt4Ae)ca$h+vRQaz#wZGHq8DT;NzjFnJ z;(Nhkz~7zzXP9I*Eo56$d$k#z+K+0K{|#y!bttEL`roz-^}j<<{bO8xp&Zl*RQcl^ z9`EvNpnXEx%w-5=e+y6zwsg8syp_X~oi0=dr#QWh(}gO3s>8NU7s}xFpz58j|C5A1 zr@I0|8PE|_1Dzap234U8s8yW-DrEYA^6`bBJ~dJG2RmITKE&ZrP=;JoNkR>ebeIk5 zBUFXa4lf3^J&bkvLeuO)p4Q9$4i|cRD)MKoCa!S)u2W? z6VykjinloaXQ+;Db@@V`4*bn)nx>Gr(^a4AvTLHcd%)>6kuPi(xyNyjxNM=UT?pzz zxzy=G>B}4!imw1=)$>lTiE`IpT)8!%+`QhEtARFBY6ukj(}JO{U;lUCO`?DK{Y=-q zP$SYeaQf6ljksf|T2#6J&+jIkB!4TM_x|Sc6a3Eq$4jU=_MuYibq~f!U;!SP6}he)8@eEzd{{}j=Y?7 z?pQDY+EX?fYd8uK?wzBQGZ%c{#~O#*vqkblBk2;ZINx(vQ5H^k*+6$z#%W*L&pU zq$4jUaZyny9CB!4TfA&%myF~cXlD3Qg-@Tl4nnw3$Z!P^t-OPX6EA4sGF|}_0YF*b!d-BfNK6?GJ z*AHwntK(U(kagxX6?J)D6?|2 zSKq982ceGfHzQ1V7olJ?f^SwyX!agLnX1$?&EG@VAfe(tg!*QqglX@SN_ijQSX2H! zLi;TU+axqJ9kw8Bl`wk?LSyrhgqa^8^!NawiJA2QLh6SI-%Ds}(mq7kCE@-L5t^Ib z66S417_=4PL^FRYLcfm?4oPTX`hSG5U&4})5L%f75*B@oFy>=~)@Jd?2-%+?)c*vb zjT!w3Lh`2wYb3Na{-+2lB@}#$(9W!qFku@)i){!UO#U{6W}hK!l5mD;{u#ms2^F6q zq?nBorhSf(@;O3BQ~o(Z`!5i-N$6}ke1Wi4!t5^)x|ok7%-oL9V>?1uGiy6S>X!)L zONg1YFA;W0xc^IpG_za6ysr=jeT9&2=6{9I?`woZ5_*{aUnA_7u;gomOmjfOq8$ih zb|7S##XAtP|Bg`q?+E9a(SJus-ifeALLcMrL|7@IU?;-)W|f2qyAWFJLg;VucOf*} zjj&0=K+}9T!UhQyyAcMNjS{APgOKtK!eCSW4MO{G5w=MfYC3$2uvNnBZxM!@k0i|e z4xz_)2qVm_?+{YINBCaCD3kU*zjjHu|9gbdX19cSKOhYH0pSue{|AJAdk_vu7-RbH zLD(;0$sUBu%>fCEenc4aBSMZ@{3Am4UWEF45pvDwy$H!aA*_)QH~vrFC~us}5sWvh z05jnqWViSS+4&~_ALtX!TEQgK{GY&NGgVMvHVO(&>wQ3xDHlvJn*~!%ho6CBQ!OYl z9|=lL=U;#_GfQx#*)F)sr0oZ$nK^=Tvs*CTWE}vmHuDA7n7x7u)BhmG?LUZdOAcaO zr8yvB(XR+&enqG@i+@GP{ue_1e<56NM*j;T`4GYy2{Vj;2w|m!f%%zv&-E*e_v86yZU0K*FM<5XKyZu)r)n3L(1=Lj5`jkC@SQ5R#J-)<{@r{A7fc z5(<(L9yhBbOz;s}_y~(lzK_tXF2W`WPnza+5jIGusEe?~Y?Lsq9zsezgl9~7J%sj0 zBW#nf)O0u+VXK7MMvc1xId zEW)5;5&mN4AB)hh0m2~(YfS$J2>T^0X@KyuIUr$CLxeF65!RZ;4H2>%A=Gb#@TwWz z2qC#K!Ws$djo%nyrG$dU2yd8G5+)pn(Be3RjVAv%gl0_;Hc5EPG;e~iK|)0ngiU6n zglWekq#Td%wkbazp?y{ZB;LFJZ}v2%nn+5*D3=Fyw2-z(V>bF4n%8YJ-klYesjf5S>Z;7x{LP1M}oo1DU39S%Xv_jZz@>?M^I~ie< zgl|prlMyyZs5lwnd$Uo(wAKhItr7N^^419LPeIrwVXx_M3c^+ivrj?zhxtgt%r*!; z+92#Rv)Uk}o{I3jgkMbBsR+9y+B4eZO=fcZ>FAsFzrl)EfS73tbHsXm&0_SyzNJ%vuQ>B(yyjA;nBR7hzfqVT**0rgaRVeJa9?7(!>WS;AHcT~iUd znCeu7nP~_+By=^M(-2a-A4q>b9bun@bd!~i(62kf!gPcl zX0L?(5=L}K$TSPOBP{BH5bc4GWrp@Z$j(4mA>lm3zmJMPG7;h#2z|^_2`eQu$wWBc zw|{$*h&IK|eP7=%TaAw(}j zSYU=;hLC+Z!U_qG81Hg~O6#*afBTb zR+!Flgw$~ebK?jvnC%jFN$4{UVU?LP4q@JSgnbhJVzR~~^qYXNa6G~qvsc1?2_q&T zylfUsKvmcyO+-kZgb<&Iu-+_{uu?*kNeFM4oJj~1CL^qu zu+cP}jL@tAp=>h3TV}0<4HDWGAZ#*I3lOFiB5aZHwrO36(7p&^Mj^sxvsuDc30;d2 z-ZRxj2s5W3?2xdX?PVvvuOxrS0Q|B)=JnQq3tw;@6FU{2-C_Dwn*4xT9+fVpN=r2 z9AU57EMcpJuG10zVXCJi%)A<5hlG8m^VJBc*C5Qj8sQhSUBWI2eXc<`VCGzdFs}k( zpM+mcRs}-8YY`S!ARID#CG3|l;#!2?&4OzY7F8ldE0YE$c}ZqirH&p|C@WBO^r)gp zay3G{3L$EiN?0kONi{+plT(c_;W~u%5`5F}I)rA|Ba~f-P|vKDut7rG>k;aksn;V+ zy8&T~gkw$X8xY#hK$vj@LPN7z!d3}gXCO2-)iV%g-iWY6LKD;ZMugOx5a!;9(9~>~ zuuDRpn-H3tIX5B9n~AVb!igqpCPKei2n%N-v@m-m?3XZN7D6ktU>3rnn-QWnBeXU{ zZ$`+z1!0ARHpaUJA^BE>_$>%+%~A;~B{aDep`FRO6=A|`g!K|Sn1-_vn%#y_HXGp# zvsS_e32kpfNHJ4yLzs3u!WIb~P3zkc+TVdN<93A3X0wE?61v`j(8W~WfiQCp!VU>t zP3JiXsdpmGor4fF+a>Ih(C1EsG&AQ;gn0qNJ_+e2D?sRX7sA2-p@-QkVZVeCcOhh& z1$QAVnu`#fi;!i8&PB++8)1cn^Ne>lLb5@K-;L16ES0cQLKA~~-it8Y zRNsp*^FD+f5=NNL_aUU-k1+Q>gi&U@gk2K)+>bEY%()+7-UA5xBwS*$9zf{#Ai}~2 z5XP9j681|N@gTzGX2F99iylIVK7^2ChCYOly#Qf_gk0k-KuCTVA-(`1Zk9?|DWS>3 z2;)u8!w3@|L0B&#-!yy#q1mGdWse|CGHWGlkkIx~gaR}5QG{s=5w=JuGOZUPw0{g? z#zKUtX0wE?61qNyP-3bdLzwwE!VU>#rt{+nsf!TiK8|pe*)Cz1gg%Q9%FUcb2=f*r z?2~Y{$y$ui?+Jv3ixDc!UJ3gpjCcZ}(kyraVbPNa(I*kA&Cn+ivY$d&A>n%CJ%y0G z1R?$u!VI%i!b%BEmLS|@a+V-Wcp727gjuHH(+JI;K`46~;TE%2!UhR#pFx;yrapr( z?OB8^5^guGpG9cD6k*1*2y@J430oy}U5XHx>ZJ%XpF`LoVXo=?975_cgt^Zl7_(i% zE(v{>A(mLberj<8R{y(VipLcbLV3zs9@Z}v*qFJZ(Aga^%n6$p!-M~FU;u)qv` z9wGY$gcTAVG2ROZ$tw}!FCZ*5OC_w7&}1dT<0fY%!h}@_>m@8U4Ojg?w4Dc-O;_Ky z=giE}iNP?8E_xk|-X=1L61_zoGSSQEeT**Z5SE09A%cj6sL@OGD5FG=5~C#~f)Ir7 z{++WnBab}q`+e8-oy$FI?ce&ZUiLnFZD%6{ZA9q*9l~<6L&81@c{d`gFi{&325mw( zDd8KFYZF3&%?M*RA*?d-5>879-Hfo>#B4^GumvGO!deru1)n?V(vKmayLhe2);c8=?RA2nWp$3Hv1E z-HmX_MD0cxvgi*Ve;>_wQc4IH5bqFEZVT8y-2nlADgbfk`4?A_19}yOxMEKj>mGDSH z(;pF@o46klmYzazpV9@0pJ{YT7a*rm)}rVF9 zeZe=4DRaTMwk|*}AWZlPi-ZeU1e%ba5XxOdnDrAvCUaTB4GG~F5i*VXz??`S_yfK>t}>yR}mtA zM#yVcN!TDE@G3%n6LA%xa{|I{2?b3+0z%L=g#HN#h0P8L`y}MOhEUW*T|*dj9pR*e z;wIO1gaS7Z#$HDVG4T>kO9;JzP|C#IK$vh7Awfc@3Au?-?iRwVn+RpiWeGPVgx^9a zZ(?sD%=rc3frN@C>=%SuzalLD1);LJE8&rZroSRoHF3WpEWM53zKsxO8s0`|aR*_o zgzCn12O-&S2$6RX!p$lP8zcn&hEUT){D#o^cZA&%-Z25cBLv+==>I!H9kWBiJ_&j6 zBGfZccM%5tfpAhneUs}CgaY>v#{PlO(8NnPEg|$CLSqwi4`IT6gaipqO~`$Oat{z@ z-A8C{E=#x}A^ZVCOB4G5Va}fj4*K67@?Dic#P2b3Bqm(T};3egrKJg z{huIoGdm>glaTi*LJt%56k*Wc2qz`nMd+UdVUpP)VV{J&NfD-)sH6ykk|CUwFwNvjhEO0m!q{X8u_j)^ zX$hgp5oVg0*I`7Ga5rNQ=-p0AaU;WhNj1At)U}{{V#LW`~4*67r@)SYe{lAq+~7a8klICRcid z0vQm-rbk$1;w7Ax5SjsDwTa1qFd+~jLBd)S5{OVPBf_jeg!SgKgc}mVGa`IvVlyJl z$%ODg!X^`z387XH!s1K_Tg+Vvk0dk=LfB^Ff)JKwMsR0F*kKxGMre@*VXcH+#+3yj zSujFm7KGhqm4pov0)r9unuuV8&RG$5OW1D$vLXa!L+GCs;h@ zvLl?7aKz-wj!+;6!r1Hx@g`ov=^TEkOz9kcb#?8L17Si=gu=u9!cryL3^-{*auQZ9 z7qMsMB=#wDS;7qo;kgjbnAlthb8;g*kZ{g~`Atf+L7J?920>N!oN!TDEFa#l~ zi3maHToPfogybfmBtlRrg#INFQkoqS_DRTF3L&+LDupnpG{Q*klw_EB1|ZQkRTz@gp@%jR~BJb8H7ycvVsf|t$^UJfRM{Htbov>BEnh;d5o(fLb6H-krfg0 znpF}uNC>Qikl#d9Lg-u>VYh^WCZIAxP!)v!l@SV?9TN6Q$Xf-WsEMkAFsLfRNeRVG zuBr$Hsv(T6iV$MrC7hNJS`DF;iK&J#Aq*iwLZ}G|Ln!wa!mKcavgWdc8xq3bLMU%y z-$IyE9pQn5iYBZ&LanzE7FS28Z0<^UB%$fs2vtqo+Xzd;5!^akg_(xo2rX(Ltd&sR zxN0CItBDX<10me3lCVKSU`>RYCZZ-n=UNE6CA?z-Y9R!@gV4VgLLIY1!afOk-$AHn zqTWFmR2$)>g!(2|ZG-}K5XRO?~E<%EYrY58=Lb-Yfv+5!= zHeYSs5kW4?ITueL5jBs{8*Mbr9Nv@>z_5tcSU za5q4RFbx|Zv}lO1RzgSPYKV}m5kh1`gh;bW!UhR}jSxDSh(-vV8zbzN(8UBaMhI$x z(7!Q4H?u>+J_&i7AoMU%O%Mh(MK~#;m&w%>p+GZ)u}u-8OuU5C5<;6H^ffWf5GFK7 zNRZIqgfvGe*8*WybA*BBvVx>ZD31P8WC1Hbv zz|IIuOhjjd&Rr08OIT(Cx*!B~Md;rJVY%5MVV{J&T@hB8sICZux*?pD@QumU4WU4H zgt6TaR+)GSrzM1TM_6rQx+6^Jfsi0!tqJLYP_8G!tR4vK&1DHUB!u@w_|C-kM3~bH z;Q>OuP4@q5>)}TK`%h1|&d?$D{zv07Z+2hEvi0wZT~lT4zH@Nk=U<<${7v_IS@+aA zmE~;S;sbxYHtf&+*MC@gYgVV;#?$^K?-_%*z=#$9y_fy^f z?yUd!gF_QtL2OA}xHj=`{PL2T6R(#jpP@ng?C?JG z&yIKB$sAtqgC~WjKCJd#WZiLtI^F2qd*7+iWs46R?J~DjydLR@q`nq2 zVc(jhm%@hRJbz>VLjSo1SB$DQs(7u)d4-Zr{4{yJwuOe2NnYo7e=5Z^K!iwGqd(B@GI`>0p6NRwfEQ>-2>W`4R55hsyvX5VL*AHfuoI@sgU!21x zLe3HMot&d4pdU`W=_2Qt*&*k+$=o03go%=K((IS>qscV@=ad;N=d_8JbH)@Lh;!D& z$T_$E%s{_Iu9@5GW#CP+{$}K0zhv%V{4etWvntkann%ky1T8l|T9`tb-Z<-TT1(S! z`KDffce$VOmAKx2xL*c8w;#Xbms09--}NPi`*n7$FEPgNYSNk0>t`_d{7ukgzoo1= zJ0|-rPodwV<3AgXY*XJ1nBrH#UA+N6^68Cih+IkOra1qe=jTyJUVG1EU*>n%Q-EQy zepxeq*@hQ|5L^F6zJLEN?`yi&ZfCxZ^}FNSqJx<~!|z?!vGuoS__gwLckE?TKH~Be zHs>6_l}X*bVpZ5&%luNh%%ug?DXB?ZPv5+AO!hdx0q(OO^PeM4#5%tmFPiFToZm<8 z59hs7+4G(%=k(-|B66MQrz1y3ty@pAGrD{$Z(M(8x!;$bP@`7$&7DljMqhX3jmnmC z9Q3r&`eEPr-S>AF`-v3P=tDh4zQ2an^v!V7v|ZI z2(ey{3vW}M_fO z;>c!g&HUqj`P}~PTt088y&5aQ)a7{nwM^e`Z>!Qt@_O>=>~j6I-u0v3Z!Tp&S#pXF zU3&G1q?`kKt$%jPFWF{=beOrXc>xu|DeeDX|3|JAB@TO+r)0mHfZhI8vORn5{ip@6 z@{C!LlPnX)4enopSSb-=5y#Y+`iI9!+6RT+`g~IgT@%5{( z%J2;|x%v^yTHY%A1Xw%$4tX8?DnvS5rKcYoj#30ZC9Iu(TG^#nka6r2!XMRCwQwsY zALm_I3<94dR?~a2RG4&-%xaaarrM^qT4k$cKucq_DrhQ$=XY1FR!u)-FTdWDo6(BZ zZRAX7Ij#0Knwl>N@>)$V(NcmeVm|q;_O6Ya1#KUJ>aO}|3f7yY4%k*`WaCEbcT;(v zh3C`6M$X0&uhjN@np#cGSk-FHY~&mqhg+?MwadxzQ*u*bTUsp_{x4}ZweWjZ%Z>kQ zy_!{GD=X%~zsef6w%VI$pV>jv#%g)d=31?-)%1T%T9L8FNjt0M$FJW+)~CJI3g9no zwFrOuU;SASDk5q?>D^;$u0l}R8tOe`vMUT~Vtqcq)yOXbYGQqy_l)Vc-Be=@#wZ(? zcQ2^M9<7hnij%*m#xm5;`Y4kU@Qyru`dKXmzh0-RQQO~YCGnTF+5oGSLaSi4fmSPx zRs+92gK$;3P)Lhk`TGpDhGp<;8tF64Y8o5qtv1|hydT~tgVjb@tvs3wzecFt5X6E?os~auZmWJx2-tZM&?EJJ~gd2)<&*^R$ImAGtO#N@jJgdINoa2 z&`zlYd?ujr&nFDdplKFNMo=lsKw&FYZ^-4~SWMj43`1PaN`sm$rYAq$! z6-}f2W2-5#9@g#?tJOo(4{z%;*J|(L?~JBdFb~c1POSPIv_{k{_|zJ5DdqV=cO1{l z?v!yu&_L7YGhDTTUKFZ9rI`_D<2J@W*xD_$S`)M(R$GLt=5MO{Yf$O)1+Efo1{y5- zEX7sE%|T;8ALmVbE%2+q_0e1RWY-eZ-})@Kn!0Tweicw}<5O@em?Dqbeoj6mQT(5O}Hv_J7{dRE!M6*npRKQZMSw2`1RIgP1Bud zdNs692PnjWKD#91b_A_vnpS$bpS1TuKM$y-dAHRf@$0pznn8Q4_5uEuXqqj05ugg# z32w{7XTQ}tv=LssjG|EkrFps6t3Ai-)!tzCDtb7*0>$E=-Z z!+EP6w^~m$Rs3x^C#=X7w$C)s6gp|O-uU%X@U?M&v|1GYzG(WKLZhNSeV{*@M*LZ8 z*B5_dYj@6S{m}Gw0uAo-Xj*@K`g3p#QJ+iJZ~*>atajOI1JOEJ?TXa~p&doj=>8dv ziuw$OV^&MB+7Psr3^GQ%&vmN}#lK2#Ba*21Ci2f`7<@`(&4SwqZrtI}-)8&=nwozE z=+zkd+_RdRv^AP$%YCbj#9t3hGvfi83K#?L+PKjVt>Gxd`c`~owb5wHl6hCYztGgw zW8h1xJw;Q3W1(>p@3eYm>8v&bzuv4Kftwyptu+(0q<6&4Xzf0-+WWYf^x8$0a2Duw z$C0=}R-27q8GnGA*=h#=C7MWcH;dKg;J>M6;}dMPkMV0NYMN%X+9&v*fj-%+7Co1P z>mG?SnHA@8{0P53Ijr_6eqY@;;NS?w$Q%2-+z ztF6GVjHOjW28ho*Gv zSi9Bu^;(@6+dmLhcpa=^zK_9eY_;|H^$w}AxOy|H znsoy#WHB3u+sxX1hkudPoHwU#L|be%eyGs;}5i2KdbFV(>&Lwzt#5O*9lDv&H$_J#jkZ?y83CL75CxaL~dG02BE1Y z`(d-yhFH4;Xo{@$VW`y(;=e@%tp&ORr$YY#IcSA>xWlb>2!9IOG9%DD*MEl*|6njI zz}14JjE}$rG<{-hS-VlzE*|Z%)$~$YWqb_gk;xahW3AnB{GVEFytO-_ajGAX zTSDLjE1twZ*=iH5_9NO(GST$=&}ygf@3IA)WVO?1%2?BHGMXxK29&Y1sn+f+e&xGD z{qMXo_Z*@!);yhV4bS6W&*0K5h_wk`z`xNBLcLa3nfwIXtu_ly1Nb7up=q{!Z0#=L z*L(dmTjokr|6hi05H(#sMN|`B0bMXin{Olkj9&|lX3GMrUB$13M%qHFCE(XWBTa*w ze?HehcA8botlf3|(K3{{+#24%zn6^lS&62?+=Q>N(`S{{ZsG5awhi}NG}ZVQ=wa>F zS?yP}o>tpvvIrS6}boBSi2u^wf^|rM?693KHPX~_yE82-rHkV`x7nL7UsCs9-`$- z!HZ3CPgv~{em9zC&`GQPh2Mpy8T6yo9^;>(wO=Ft6ryVUL?YTb+%r~tioXIQU4!wQ zjr=$MidH*s?R0LhYG=ex*6ul4VXIw4Q){UyilAvAM_;jqE=0XnPoJNy=8JX$O{4p& z)%?&-S}nn9{%Aj1?V8oxXru98Chm1yWt;>}(^G@?78(_f_DPDU`6=;N8=1Sup81)8 zcH3&n(KJ1!-LYBKqxr58|A*C5d(xx-CEl}Q8btkwpFa1| zRO&a-bY|0te`xK}qUp>gO;<|lx&Snt*`z(Tanqsc#3t=;H2(RdN1KhNkFWZlW1kHC z`4~}C$PY~k2BOWin%){MEhE}It0hI#w9AC{sZCICgXYjDh(CHmsit2lt7S&h8C5ea zwT&B{1yTK|X%%1%wI8Qxq-m87O|6g>ZI9Igtz9;>y;gHxH=P|#tEWDC^|T6|18s)Y zGFvSt8dp%XKOapiWs(cAqBYEJ4RfRE5=x((XdL?F;ZK;=G)<+kt>BX^g{-*nv~lyI z)nue=w!CTW@}a$LXGGp4LTdg2kDXSH*S|PLqJ97$J ztuUIVu?B4+T(v?Gt7+gBv071`fAuO`eTv!0#n3ugt+>^Sqjj~KRzwbcO7N$f)k3Vs zHi=IUtCh4`Nwg?54enA_D~10seoy;5zj9j|QD-NO_)r2>YHc0sVzMH9DFJ602LoiugB@iKa`q)hglF z2-a+=iL23H8Na5dW=0(}9G@!u(e#v7*T$`iU(-|CyJ#A3)pY+w^HX9&L=`3szh2g> zY1Pa|ehdF}G=21Cl|!HE{88;Rty)^UxACiX(pupvy>R@hoV51Vt_FUcFM`$o9T0JR zYVt=H1^RTfS}nA0XgP89esS69-f&NA7iqQHXuYi62WaZLI%t2}f!Wz=bI9=T_`y6MR;gK$;j=J<6kkv0Su z$EO8w$@@tT(50zjm>zAfJRI9hPeraQ@9b1W>nWMot z&T8x*dS;FWqw{OY?eJ^nNK>Ia*MIFfP|2#{PO_0B@T)M=rdX{5eicmGG+Y&?BYqW3 znqC91Lcfn+Eu#TC+iH>c)iToN;Ntjvz@KQ9LZkL$D|W)KrjhoE)jH#^tK9g^wOSXn zbas3wGiBTr&4s41Gv8|6@av_x8Yc^E-0t}AdB;q&PnT|30 z!mp)OeYhA`8TZDoLZ}OuSS<>_YAkITE{;zh{;0z0)-OF8{oj`Z)mY+kYuFFJ2Aulv zD>Mzb{`i%Ny5<{PWjp}CGLg0l7sqEHf0T*3>szZ0!mm7}t+v`={4+EM)#Ph%mEaKk z8E8T^?>cKZ6#oO7OU<_4YQylW6;${QHtuk%DYK1MEBC9`NKR%+-6r+wq1&1;Gdr-jM>nDLa>LV_k(sn55f;{2o9T;m_~eucOz_q&9Duo(}=M! z6H3!up->jeL3yYE6`>MThAL1Ms=-_EHiSb_C}z$i_y!}xz&ISW>;1kf!=REin^up4a@Db=|1NGB_Er_f4qK<;mFb2k^V5uF4 zXFQYwZGnbD87K?op#oF_?RwUwhqTjK9~yv0ZWhpVDh4_UjiH^!!drw_hj7qFV@0S0 zl|j4SRiT=0wT9s-1BIao6oq0?97;e4q=7deEod_`9i#_sI0ix`YF8P2@%w=rl0Z`E zfZh?_he-GUIzeaXqIU`Z1&`q#EP$Et5zKO(_V zM7Mqpi{T5XfK~>|K?w+f=wkfQPUT6^?&N7W3OhmHc)rH{20p?+3uc2Z#nM6w&^Mb@ zpbJRd`!O&V=D`ApgG+E3uD}7%eW4$K`#z@E4gd1t`Vy%xe)>*#5%xn%cn?}Z8)ygZ zp#yY;_aPEGL09NzZr||F6x|1JU+4$@p%FBOCQuXJf!a_9>Ox^y%g}mGJH+8?ReeHz zpTgfT1#JYHI!b$<-Jm;YUsL;-o85F6>tGH1H8q~=;Hd{yKrf$8fW8cae$XGZS2+;0 z7pc9+VW90s?OAJ&THB1HU<{0f@u2O)4?)|5+6|lr)1e_Wfo9MgT53GMho?2@s!At4 zou{~{@%e@ttb}E-0#?HsSO*(mBW!{#uobq!cF-bdVl0Kp#5Fy475a!WRcOEKN@TFGu_eR=_kE3u_5n2OHo! z(5>Q4uolF2F^&1lQm?+=N^3E8KzK z;19S558xp@N=pC#h37Fmfv4~{JcDv%TnQ?JZirTcLp1e%H~_jKS^#pxK8|(Y^9-DY zZPa)??nEdD!(cc>!$8p8!AMw{#Qgc2e~0M(RQv!OgdafP40Lx-H{`g#;kl2Z`zGa} z0#pRuZ~2*4);-njunTs>KKPdW*T7m>2kSxi(_%sQ(8>e%%{;fsxGfg#xerzy!55xk z{3flR3zCBFhb0GpNJ8OTLp4YSDWDb&pnG9Q@E?VPP@3aCxK}~9wXVTUxCMHp!Fjj< zKf%RhrrBNp?9sa8)DwC^Z|DO9;5}#sHJ~Qcf;vzPLLn8T1~)vRQO?5!I0i={9uC7M z!gc$lGJf6ry$-tTeF65X5f0$d<1ahm6a2c3G6#l$HUM?I#2;Lcn#RZsSs?&YQjt`U z8Xm!8cmjWeZk2fMjL;}|@as;;FYr4BxeF60)WoE$1e5U$g<ri1=E@o(9 z*v;Cfhd#qt@2W!$C<0IYOp1H{U9*478n_zPz*<;90QzP#LN~ISNt=QbS4=3jE=B(!L9Sz+$Kh)gTP2!`q<8{OUjhKf1CMp0ZFJ z?vd~VcmzL!p5ObJ3TY#uHEvs|1<$bEhgO*I)3^(%*kk-{(e zG>ij1A2tal>!Pj^p2pA=T0vV#oVf0m{S4CdEY}h;Sqfi5E^PC`n~)it)*VCGK!}1q z&>r-NmY%-440_^9Pgo^H^XDv_13fl1mD>FbLxHk+j;G<)hkDSCMD&EzS;kFI-2T>I z8238bIXDjrkAy>@2bPY3ZbYpDJ#W++q99ri3+b63J>#UVD^h{54XaOzZ zDzyy5tq!%osc{eVUeFslL1##y#d6}RTSQ-Q?0=)Ozxz_hpYU9QYj7PdfYTxh)3I7b zs8-sN@gZY>&~X!Lt_M)=z;B=jPZpBtRP4IqKMp70GwgNm$#I9^AEy0);dpdzl`zyJ zzSQ&xMhDO%7EVMxTG0d&*LXFprl%(6gKkdiX7pmvy=Es~e+o1}kjG${i|ss}X4-L} z+G#)c1SLNSb8WNr!TpYA+yt9J{V)1~npCZ$=K$1FeuQfmGzaM=g=Vyj#>HI<`v=?y zZRbCRr|>mtM}Ng1Jx-}z@zaR9vJ=n^e=q2rNK*@FOMU@pdtDnA+Mv*APCOO=*?r#r^>*bJY`4Kaa0=Ru zN_1EM_r}u)3c(UuL7UCmGS>#PHjm$gy%eGtZdUlscENF)`vh#U-SR74kcTt^ARo=1 zAG9y*0zY_8rDhSPTeP}c`U!aUgZC29nuPx&5Q7SYRfIyIJzQ`T&J}h_Y#GzNejILZ-KV=N`kiU z6m}gn%P!;U*gJOUe>Iitsx1;{q0lB& zEF>PeihP4sI0o84`Vo%85zs>>^I#@?1ll+14%!!L3+hym~nj;mYh2)?e4Gj|QVrVnsK0JVtWTX~&jz96jm=B+VZqVv(+Hm*)-iPS?{K*A5Av zKOejaxgiha1zj0xgQ6OggpN=dDnSSBPqfF=4(dP%Xjh{I=%QMsFAim(G$@mBcpKh= zQc%qN^_(3I1u1U)VKadxJ^K}wi|+ub;rD^ z6dlO8IkfVKFSYkLZUHiujqpa~n=$^j&<2!w1Vq9x6X|j{kNyPjG>8VRF;ieNjD!g= z7RG=YEXKN{aYunVWgLu$iQw2w!v7&CuEOVl;u@F^v*9C{p=@LE%mlf!Kn?dX%!6DI z2Mgc}SPY-TBKQ)P!O}#2XY=AYe8omWP#hxC1}JN%$2mz%OtEPQy943}@jI#DnZlfznkPvQxMUqC8KL zzb8-u%1Fk_KoJs0-flJNvQfdDaM`Oc3R60&sS4v{ENweDW606vMr%+w2|0-<0VVd& z8YrPlpv)CnE#|~gt0`P9r;4bSKf@JBoS~ZDIcB^?dlFP%IE7HgPGT}vO`HVP)QYS= zbZV=xOOUuloI ziICsg6vWj7cUdWr9xE*YN=%7{z*`Uo)t~~DhjLH`LZLL2g{n|l z&pTGcqi5Ij3|e*2j7jFpA9&93Gk6O3;RalXYoNP#t>I_*2~NRa_z~1vCvkQE;|Q#Q zuVE2<35(%#SQyQp&tN{xgLcpg-XVdOxGg}t=-N%!uDYIK)T1V~K-1glzSEGB6$5Ie;V=w_!Vt&= zBVZ&rVbaFHco+v0U?O}7v*9C{2~$CZpQ8Ssj3*YR!!(!yGLSY4DCLXean$Hzj?3e! zHRgb{@$f1BI9LEN9ILMr+b`i*_FuqKP$ieCW-H(;SZ@8_;I4v|@GY!{?IgGs_ptSE z$K42<(bway16_fAhr0pfYFr(HA7CS4`*E+}?!#65y%6p6(;g0X!)Dk7S`WU*-32n< z0;;w8bSr+j+Y)ICi?QK~qhs0agdO%caU7dgv?n7c6N!o-Lq$^UoF+ZMu?nKFgVuFw zkvNVDew^@Q5D!PKn;hLamS2N7R{eht&lxxkXW=|t0F6?O-Yak!G!`zwMbP+gxQbty z-p0KLf52~W7w*9C@C)1o&8l10mHlt(f5+%o3HDfl!U=Qyo=Ayw#d!jc;V*au58+RE z0DptViD#X#$4?V!(K<-VN|yxO;17P_3ob|j8enT6Iera7-58$%dQK!2+EHrN9{)q! zH#trNsUZ)j6|>=Hg&@cT86gnTX@4UCPZNyN;x@w77Lu0747lk*?h1~7gkbB>f}7c* zu#AwK<6NM$a^Pl%O89f)wxe)Cek^pjdPeC({4H@yXn#vjFsXKWnrSov-G~qas%dRB zJ)2nzLZL8}2JP(ShjZAUg)?v({vh7Fpxv9i5DOo``w$6rpaA3pX?3)}C80Ldfc#Jd z!a@4mu$^WthFcUA7D2%Z;T8nS;MwKVoY!ujblGd>6vtlzszVr51#MGS0Bu`_Ky)a7 zN<%3q3EJ1x{-*XeD}z=r?Q2$nw?GM117)HDZopNcRPcA8CP=RZjxN76Rq`+e?TBkD z8|_n<1IMsE{x(n#)Qr*9SG6<0Ox45LBa>2z;b{GA{l z)Kvc~5hsG0N0A(3r%9dgE`)tgD>#>ax~SFV-%dz;{WuCcjhQRxiPP7>R@&X68$_#C zBVZu(hwT(VCx*WGwHzP9-xI$ET@UMO3EmEUtbMOUdKCW6*y?=I8^7Yq-mdqac=B%o zPFT^Ngtv3h&n6=OHjq02O|Fi02HOfwB4)rR2?g&{B) zMv=egKqXdJsMIfDj^KcH%!kcJka8GOgpTZLlyP*+$54#{YMmuqLz;;jzZNc3Po9yv6+^ui`et67ams2i@qRZ!#`@C&G0?&AIqx`@;Tg=T`* z1hvZB=xPzo^;4V$)$}^u>NHyt|4CeR$ul^JU(bsMLbRT5(KG4kL38yf#N&UA`w;Fy zGcx!S_W|68zu*xlA;rxMPdJ{0t4zm%P26WV{z2g6AzS6)q#fi(|7WrhREWO`)c>cD zKP~vfb2JrBm)NR-ADS2cQiheAt@vQHz-WD(v#Wa;bY^~MR)@gL52a44z?4nrCCj%_?lnMpOJ7Ccs^ljflipy>F0o67bHxk~52xt#_ zP9jMaCcyJZKJ}m$)Px!k4ti#(I_SS56oEXD6S9FW z$Fk$*fZUJ^-UR(ulzi&{y!M~~u4<4Uw=fificl0}tp6=wBYB>Ma{Q&xOC|~n!LRFt z61XaW(v)o|D38)m0m?yH^?w;Wy7n)RE8YS{s0?9H4XQv@a58lg)v@fUi6_hnm#YW1 z>OgIH2NK&TOvfSWeD$J&X~qanJ{%K$-RcC!PwUxEdSXLF1zv?tFd!)Aw?HC)Ysi3SB^nDzXM* zFHphekV#Mc3hxb#(VPqt*Rnrhdi+RnWZM@8z(5!bLtzLEgIeVOVyT>fFqY$SxLT#O zilqmQkrALpNb7>;_*fVNqoEs`mg5-wzMw^HB(BzmQC3qN*~Ng;l#M5Ct!grq!FW&x z4barI%5Wmu0oV`wU^m2q!oR@PwSt!D@A2<|?XV5D!WNhe3SWdf6{bK_jyL0O()^!^ zM+O^lzk?0Xl4BXkcs;CzHP8TUHSV|Y9{v`b~@usV96+s7zB)^leYNiq^(br|{gugD1G_|1O%dh5FYqr9#R#WYzM>_#d1T~lZ zDv(??xk{^3u#RP~gqPXGEyE#eTDj8fjW?@5vwLr#?Am!MymZTG!;ZGv=dZA zjU6X(xhj~}lfAg_;qJjz{BiKHomC2-16p$qssDd~!=QUKM{$q9F_;A7K(}9Dbg$V#n-TIIR|0&#TxaSG~5`QNA89`H4wmLOOr^Tb&F8Ts-0mESK zC}e>gaGm2TkQKk4-qnA_$_RmQ8T}Xd2^>3V7vT~pp8VI~XSfOpaKpN{aBr&r)jZ-M zg4X2+xcA@>=mNLlSGWsrQOMtMe}g-4AN~ZJn2#Q?{+r{c@C20MU+@SXg9@So_+h7f z64d|C@aW(<_}T#7S8+i)P-4k((|{7x)7*NhI|aBQ2}qYsGDr%;D5x@#ra~%?DkZ;K zA{EDKA?n)fx73PU87c1cd9kA;i?d_ zce*cH{g=4evnL8vSU!%GfFkC>RY7v&s_%2+swT2?nmZTAD!A-bnY^HwuWR?&@HT-?gzEUi;4RRT{AHmGD4}Y&RiO%028C6G@=(DZSHhKz!jw+p!q((C z9BPPY{=_l;7J!;&EHp)PZbsI}@0_>)?HpeR8)p&Hxx+al) zKsTh{$L$C|p%;KLFqPw`#G9h~zgh+(5hlZjFdoK1ABX}yvELoKK^N!@onSKYKEUm2 zwQ>}!7k)kW-V??^Ul;)cp&#gmhL-mJ_y<4}-T&W>Fq{MZ4~$_j7>2?S>zAvDF}O}- zjhm4$3P!_NP@-Z2Oav8Lg_@MeuXLt!JPmXLiq?rhqR@7`n(PY#7sKc9F)RYixuqEAAXHpp%hq>nn}f9JjO*Cyeq4mBZq$h^7k;Iw0;_;4Kox2U%dM-{{t}j`|Cixe3c4bZ(O00m z6^?N#{7Ota85;;w4cFnWg*DKH_`T-Z?l6XW%rPf*;`|oPY%--Q+-* z)i&7+x@(z{1>G5g>mX!i0Jqus#oZ8VkJuzE8(-n%q`^39IPiqf-%V7;MT^0`R=vwb+sk5SV(!F zE9M9WyxHz%A=0a28W!fLiRmUM!c;Aa)6;}abEi*Qn&gkivGeqb3#A=4Kiq9SzOUq~-bhNi(>r zR1PItNzbrWax1p9yFEPov&EDzq?jke2$OQ*i=vpGMci3<$)gfA3yZkZC4WR`sqG@n z7PR0>e%`}V6$%v@@k5n4zOE4=#X^deVd9v(Dv8%F^xy6N*_4!orVOF(Crsa>?(pP# zo<18n-Y`4VIM2*EoU9p>a3Vo{Ua?5R^1&@ai56O{ta_?g5|g%=JIM8xDOk*1&(+8b zEaoo7%hZ<3>0vHP9AJtT=V*+HC{8C#G28mNGn$LV-QV%r!jDV1V|XcC*gC3QI)v&! zG4(^-nSE2FFx56=HZsJW)pdCNry=fcE?)grybR4ShbBouX?lFWXhhYYPB)|(O480{ zSvySSQWz}6K+U$l>e(N*PMEvK(@rHcGDsFJds~kCzv=4=VVr8bTr;UjA@~n#Fn3rHcfziRmt_z_-*aJV z!Z7ennaZ>-?GEzIoN9JiocyWGbPhwyl3xH>zI%4Sfi*|;Ovr)gt~lJX=&*sJ+AqakXEbmJ}pc% z2BBT8!H$I3rRg)(eE8B}m<=gY_lI?HGu8}w88X!zQrdACXizR(HlpjDWOP&Cnod5NJy)O+m*^uQmy0qz2HUGSqA@QaMQG>5zkcp`AacQ%C zU*Kl_mjz98bG({6 zNAUi<-jm0sW7j$??Ym~Y=M=#r!pYdA4kJz-6R_T$!Bh-$_plL@c+McJ&6J+*Vo5M9 z<>N^{gGu?8yS$Tl%eUN(c~9q&J?@PDEY}Uq-nYp4ka;4fu_<1iq%W9vspF{4dvEgWOw>)=?C7gUD75Y3oyrlvJ$XjarGB+9Jniet}p(@a!7jy^ZJ zYT&$@hE1Qfuf01%lCr9}P3oZ8BJ(RIKq)>kcRBJ+Tgt3_#~qY4cPVeaUVuzM8)oQYe)G@2t(5+SLvn+gI`qrc$yq6QM1Lho86|BdeQoT|ao13qbhz)$T z5p4Nvn62aMYUNut)NHRuS!@h%Rh&BTKGv9Sl;d>;FePfcJG*{0AJ^t2KGyuUhNHn6)KbzQ&m{+1WiQB$^ZP=^BBT;V$f56z#LY+Os+~13y8#m(R*swM5 zCL5ek!E0AOd`A4}*g11w+P!uZzgmh{hlDL?qEa|x|FyBaqdlo-w7-6g*a2upHgtCm zUQ^M#;Lg}HHOs*^1wW^tx;mwr`;A{C26lpJ*vLCMx;J87_|FCicj9vk$@OT#>sOm8egpRjt#VtVl{lj~J~#`T_)RJlstkV8W=mcHJm{vR(xZkR1( z5*$i(byC@#zH;$8!OP!zX>ico#emC?lufYfL?LuV-7#O&19c{DT=LQ`+Em4$%rh>; zW$@LY@5g1TRlLGWgR;yph4gJvuTal?+lIdk$(Y1UZ9>bwPbp=wHDKzplJk3>zRG^f?t`7=<f1L zWCK0JID^^NfmPBb|GGR)iRPX)-jlzzvnkv#F>T5C)mVv=)dF+0t!EMR#J1&NA#czE z)w2j@FvTM&!0QTZj<#^W`;QQ>o$21vvzR4np?~D1#mtk5EpbEBt=)eV)rQ&D^ekt# z{cO#=xoMD(e4lR^uU5yGkzJw<^|0}u7*`}S!f9o1=a`+XC~0SNp%uBmT1lIDZcb|* zU-pW(Ox{&Dafv)?I5y+{?8@~-V)9x4$IxV&Uxw9-5vkz+=oZCNP0tFcZT!aIN}V~;{(>$*PY?KQ9Wlk4fsv6d)>Ls zYv(z)rLW{YNMp}VP4fNzMvDfAkGw3&>&|)JIIIj+I{nKz&uj6zbDlTkhMClf(!K7S z=QZ%0^VCi{OVp!u`qGp%@431kRScQ&vUIOI8F~|lHmN)R%gNAd@Vb+sH-wX6>(2jj zGW1$_PKHh|*5|C6h0^`8_jH;SDaNmSS-SrmfKLB%D~8g&_AKem!E=`U=l2Zn@3ecHLeR@z19lOV|(@V`~7Zb2>4Ooy=(#O^_>0E;d~qLjCSu=3RA0V;w4>Qhh8)0 zoa8*K+`oJQ@_sk?AItJzQult3(DL>lUwqy-M-qL-@XY^LzhrqU`XcTtSF2if5`BI7 zUwr5KUtBkP%aGI4i~rtH!_1Z*tO~CdfORO*S3&3NQ=(4cWag=^=bL+};P$n>cU&`9 zPT^Z7>EIM}Z;4{%bR9h0oa;%4O~D{7BXh*G)j#A&lO?xZmAKvcsd=LpXO|VGU@yK{ zZ82@+>@~4C!6%88f>>SZbPFs#W8z3pEYA&vi{_#X?qQ&B&|_QgYadfL#Vy^g)@{wu z5>HLh-sJnwFWqThd~e@kB6^cT0d`xo12FjR+SBK%Zsr?|Zr5p>bej2w6kK1J{n)v_ zHh=f#@_)Ul6UEVX6D{X}SsjJA%eeZ`gcTZ^tbLfQBO7{egZQ^7+2l}?FL!&!x@QGG zX6j>D=AA~~yNbW|D=?(|q`dVo;5LX_t0^I>Px9xnpSACI*+q!wMnnmpwvEhu68G)a z$ZY7t-I)H3%Ca<1HuQtmQ2`r;fhaX7(&jlJ#mo@?H@8V^6~O)_P?_hjdq9IGq3$W@(!-w)Vn5r)hlF8_d6Zu z6OU7ys$;WxWG3~awLCY?O9dy#T%8)$u4+yH<#T^~Y3{8=)(td*?tH&neCNW<2XNU7&0tV1% zf11Jr==4Kou$%>E?*QtSV4e_`^>G{TH>aC}caPp(u#)bT*q%+>)|43N4l46zThBAn zBO}7o-`&4H<78i#3`#TJY7nCDDM<_E8JYR~?PKHZ8AAw+lZX{;wE+hBK0hQM~-sHNV$v7$x3B2|1{$=jK42fLg2W^ZSb z4RNpW&EL*!9m41=-_D#K;{GIf3-wVSf0lP-k-}pmJ7jnfn?J!SO zJg3-H5#A0O^L*|6CqaQdZD}ZHrUZ~@09K~$uvJA%#`hJ^-}?~v5%KFpoA zKNfaijW^LF7+5ng(AHYqh;!wu5AV|q18yuRi8!;OJlDnFm_xGLf?ay->aU0&c>7dl z?NebTyQ9VxO?9uDU>x6CADBxMsb?J%H^rSHr)M1W?c}Y%c=wC~=PI5%=P9PAio?w4 zXxeC;Ss(4L7refU_dY|^7Z-d6q0J3Ep#m>eU?BhHi`iTM%JgQGIpyLoFL-{Q-o z@7(_^!LzHx?jPUKyL+!TTW-7Kp7+!30wkmbi^BHkZZ?l}*UkD63$@Gqahs|y{X5MU z#8sQ}rQElNc{7HkENu_dBF0_UyNqT?T2ir-^)%aKsN4*5CdOS#CTT`-=visGfjr8c z!#A+EX^rNav$q*A%3aqtFv@&C%KZU0t18f%o>tG~SJEfev>Q#cE{O7OQ(e8#aBr8} z+1h$a>S@*^=Aa_XH7l?Sea&iS*Ou3;s+ysc)@FIc3?D|?nF z>*+F2q)x%F9eSR`W6kq1EHukZy|E9w1q@RBr?ww{;Q=J?0aLx1{o?3g>xvM4u z1LsbC@Zb^NK|SrlhKgsN7R+Othh=ZHaZM&W%0U6DOr-!*O}q7MwEgv=JDYdDWi}-y zaaHP_d#2qax7#;EwAnD3?^RY)(afdw?o9qnlb5~ZCY+68Pc1$9)MFE_{$x7X6ECw( zrmk~n_Z3{WOq9-+$#kDW0X%U%iFu;e`{(#Dxu?3bs2x4kNL;ku1UQ)x?&&K}J8S2V z0_k=a3ri`dy}ZvDWOfZPt)_9N)00km9H7k3ZCTGHeLU*rcJdpe&Gc!sS%kTO;lJ(o z)3{!PGH>v3MOsq2yQ9V4K7H=8E{+KCe)s&BM*xV*qFZD-dDyAD!L*xBR&jQP4d2zV zdng4Qoh07EHk3KW<>UG=E`)gEMB{SdPYy2 zDIUw{S>rQ%22)p?Lw26KzBI!L30^bKJ5k(cpM>{Vd5AAxo^_kVJ=0y+XqxrrVk~3U z>rd)g0X#_tIqhsp&R|13{X}zTCNnhqL^E#&ZlQ^0fsV^gG)Fnk`u0Tcx;yi6`7-?n z^xCV7g;Jim-FTw$pUE)%+LWEi+0aSop9z%u(3?QAOXruZ=su|C%LM)r!{q$PT{?08 zy+2~k+vF6O<^Lg%c9TuDS$tuiI+H9AmWSUwb-DfF1dyqOe_-rBscjUpzsnd^b zz2TRaA-BzxS*+7Jr|?K72H{(Ge{pMDw-YZ78W6&wJaR$D=Ak<`eeL%$B*vU0s&9i> z({?ta=bDL~&8YbIOEPQdYcIfTgcpaK&BfWA9na11JnS`cX@;q0=&oJA=qm&dq)>^c zgyg0q&2NS6J&Yh_nD@GHjkMAikmw(jV-YT524CEHU{yllnByXrw_jZ2+2$7IU^;0Lf;ZRc_o&D0THkey*9!G=oJ>Khpc zCcguK6#zmW9qv`(!*Og8JfPtWqCy-6#eun2aWo`Ovs~RRj)uqMy>A?KUX5pH9QnpW z2w(q>buAuns>5`80|@_%&a4JO9`TfiU-gaS#YD6Fzn*v{bYhNJT|6+J#7m75G(q~` z0mkUg+niDDNvY>;n2qpoy_7^`2$FS+0BH)yv_6%s+RSqLogozIt!R3Y00MXso0p7B z=*N{%uthXxCA80JB{e$$N@r8%9=Px4D>WKj&Pri1bB5k|ZPtA7A5aZAUshaqkNgj6 zDmM{)ehDx(YK0wVXL^rZ+yG!QV*HF2M!D&Q$g$_#b8n!1HBW+hG-1twLzEkNT~GJ3E^sc$alY-=ItBjux^5 zjBDg-N?8RpRjm=y%$*VIb<=0cML@_x9YK9rP!DkHHS~EE@Jp8KJ0kdCCv78an@pTD z?co`<%6zR@L?pMR6!nhynQ6m3D)qWkWxwNe4N&c{ngg__xJx$(dVp@ zx`t?BmRV~|yKx6Lu6}21>A0T4K&QS!oUo{@$Z^5XPR?ZhkO{-fqd?&#>2fe6ik`25 zLEfgO$sq3pbx%e_h1h*TGO%TA5R$rlC1}VU%R0XrCDm#p?FWRq^G3Ro3=#C$NR`$? z#AmkmT#FD?-+7}@pU11~&pJ|e(L?lg|USxEN;G$(@-jsF? zZ~n=q$pv0YSfPF|0GQuUszpwo>-h@C!re1e?kg*n{5BZ3;Z;hRKCegQVCZ77NGVg4 zP|RS4|DK}p(3NcPMI3~_%oeeWYkXs8iw4_MJ{U!0y(Mxdcp3@`S%7xW?r%$Vx){>i z2w>2?5(xSq$|XrHO3A+~`ByWZ_H7Zw7R-jF1lYyVHhAv-r_q6>!vZDgNsPg88tXx3&;BeBQRmZTNM ztZ)X^liW|B-YHNUqTufoE5(bgj&kj2yOlPiKm&f=4qPC!DvgG}$*mP>VAm?fHa0}mBiW=jzf~^}3 zNz>F9pxKx<+*qB!_RB>@#(#rHjiJG}%m++bqG4DIOulNHY2{hB2>7R5Dhv+0r ze@JbV?x&Ban9pNw6JhAz}YD+(W#oJS~VNL zu*2s>IK)ac?d6%7!$!+z3jgI2QiUI%Egbm z-xNX5qGfG|ywt68rJJ32`P2sC+4O$YX$OsoF6Nm+T^pNqcNbx!m7V)=T|?6WmTC zk6{3Z9GZ6ws}}#<#72XZto-5xRnoQ3k?C=$`ko(!`>6fm`tvci`P+d+9!tQ!n*+kf zXNpKv;}%IF~h0B>YN+LxSYIGNm>g&Fj9&IH@Ug1K52^ zpd6B_bXb`Fh&m4a*ZtWaE0AIL?R0@$Pa=&ilhHhHU9c(`R&emR&@!^!CQDOBrFOeS z`cvSw?r?7t^uBX1?^=EXzr~4{tcm`+6~# z)bbKFzX1N7BL5uZjp5+<`pQl?o}5A+C>Wz!pl7|e-nN6bjA1@hPO1MTs+tW29CwKp z=fI`R0VH#ok$?B8^tjcPDu9$c=U<-K(68B=2CCNdn`X zB8xMa%4K@-oE5d7(Kv$j>?fLd2KA95xS^}~oeBP*GhnPggl7q&-TcOT4h-1bm3te0 znmLEu&H`BiwLi;K{4B_!l(S%MKAl91UVUBY%pU>!95g3u;S?f*t$?7r;`PXLn6CCZ zRXK-MzT$O?!8^uJKZj}XfT{|WJ`e22$^N`%uo_vZS?A$C#?sF7fOt;N@F?aSCj2h| zNiAk47hp-oUqB;gng18^&yvYLKi?6n+izz(*NV=VHIS(aVh_RWtw3ht@Bg6qR zy9i}@4glD}^bUC!-_o1EB8&jl@8Oetw0tP-;8@4pm({ufIkdl2&^_vN5y-~?0%|(F zeVe@|G1u3xGxl9YOMo0F2tKNLw(=A!F43NMp+~^1Gw4c4Pz{1&}L%N?olxbM2_~&&C1XP`^ve znLnVZm*7O&J;3MT0NlD~Sxu9jlM7K2{(w>d;k^c2P;vwhd}LP&kz=0NCq6HX_vvuGqmh76wc}qWdq(P{E=`150mGaUAUlxt5rYa7js}> zm&vmg(CfbgCTFgQNAdS7v@q{y`k3@rFqYF3;i+=_-g|%ZNSZCi!rH*hVj(45Wk;v1 zxG0)NU4x1Kas?*3kZxUviEg`s*hTl0o?d~Dza+=22r|v{#H4LL1uTA8p@-loFHUNV zmIfHMg-iEe>-lVbC8mV+Q4FKim3uB2S|_M|;=Aw#E4~K6p)p9Xrktx-2T~~b7TCZk zWXH(`E$Y(w)a(&#xpF>*--ZnfVg<-x@a^(7*sJJAPPv#t_#^6-iy54zMY)(kF(=6^ zGYrKp=EzG%pE;Dvx)yV2EdfeyIZpM!OT$F2QeV8OYrUq)*AZ@dyrxZf7MTP1{s1mb z&RjkumO^~^3ZR%4!9v~S_o9w5bnN(yBd=cHGqU|pa=8c6(kK&#MOE*B?Zu#x{N>oJ zHEb2&Kwe~Z!$@Y~ekF@$A<;#VbJ`-Bo`t|x{gA$u`wv`A@W1P zCMteX@JAgwzcaTfvbAu#EW(yY4P`~NAYF_u3gB!9-lIxtP>qhsLvDRq0P$C`GsD(l@7BfVePxtrgy{R?EWJjeQ-l*+DXKPlhl|&z( zAU?D1FIJDs11fF!HM{>-fXZ0)8$Hn&%&dq=)#J+3mZt@DdCx2__~?Hz`@xqvyOFFg zAZ$`W#nau+FZQpzJZAQ0v`7~@jRK#6Wr`^cc?Or4M$ve6nTNatJG(i)x!JCPU7A$o zvjFdKZxveD!e;zj{3G3ZrfID1RFNF=z?7cs+gVwwRcw&VH-fWiSYAmXDnGyDk(v!l zC#KWRJggmK=~*7)%L{b6nu4sD3`dP8jC?{~xKf6e)I?1jqDz@Thl82jcGsnFP<9}T!0N5dgS((_|eLeM}7@ISE8YR4e63QzB_}v6HWiTn@ z^#t~+xzzM6CKyTnWuRk8G>W~Y&~r83_E6GWWPq~d0CvA0TekPdwRhy4fao?_n5?bN zFKD@U^~q)%gKrs)==zp4FJjbG$pZ9hkl!~h8Srf%6*4Ox(xvA01)1M>iYfD z8ds74zPPd-E$kxq zvv>~xmH^OLj@=O--Nv9N@Qx?Y!syC3wH-R-?BA?(Tx$Jg+K8^I!ip5A_O>SX4^TrP z2__THc`Fni;s0H1DE=c_#qQq$>@v4i@x*AUhOfu3Y&(C75xv0RfL=Pluq=Z0!im*B zUp{r+2s4wud;siqxDe!L? z$OZr~LB}sE@8h_0!E*_KQTh1z+K*4jn$_mX|1xJLCZNFtHV(HjRvtzY8k#-!4;F@cA+YnO-l0Q$WcY zGS^^ET;T$B)oZADv||41S94pZk>ZGjFV>uCHndiw*z4Q?#Y}RB%4b2%79FCbHA4@C z*ww;y^21HZ6saJB+Co;ztX4*ix`s7H_?b9#{J2SmgXNAuZsYTt#J|ZQVey#Mn-PLCVsmp$-t>PIek&-3*a*92=vFc~) zQckHNPf0xW|NboluXl4U>nREb3(DSVmIr;J?9Gi5%PYU5kfcrp#Y+`Iz1d?PEvW!~ zSVq-skWV~R0YY6vH_)O>uP4N%zR|09&-~YYxVSu7#Il!MOws2!{l^xMv((S@Yef3v zvUAzo)h4BOn;OmH{`I=YsVq6f^ipb;z9uxAq8s}vD9Am zw{D&?dF^6O2hZ;hbfM`Lfock+RRqB&Tt!%s*3?TK8z&e&CS1s@1d+y>wdvz}WD; zE;r5JF=?Zb=zVmHq5YFS0+EWNwP9rtEgDdV%CKKKDKVbf+J&+zBV;RKKrmeBi2+b8 z6wsPs9PLX%R&XxdkZkA|D;Tmwi@~kXgY#Yl9+ zMig(YxG^6m{u>~Sm5H;Eu?joYs(l+%HyfZY#wy*}#!e`;L{Xf?q<~kGA2VlZ3fu`4 zwQ+a4XbU&~Z&sxHh`&+Ag3^%GF$rnqLs;TKYJ6dj!D)-3C3YB-`y#{8?CZyycCef^ zO@(6*n>^e% zf%u0SUWS7m3eo|NpZM6&G@a5wKc%^tU0sJBHExDPq8K7V78jug_^eLx)aU1l97psq zUDVLDV~vauIKio^hdtv&r;#3NEKic6^-4o_cC+7Jv7g%-F0UgkB zw7n8w0MgC5ChD$ke5{$h?(nw8a{CIcNuXEu3j34<=S+cy{`!hIV`6Cu+unidQk7HI zfNjzgLCPTq2#s0_XXQ>w&we;jdM_6~KMhMD3r8?^J>7D|HD7*?ibl1KT03%!n8Y5l zXd?i0i&_a6^!vqXS(){QsEuRru3A+LePoE%kabn`lK6U8RT_%_<5aAwQs2On4^lwAUt89MUh?#lEZ)=Vi{&0)Wjc4H zn>C^M!Yb`>##`A53nGqN+d085CPmOxl(rRzKvoaQ;y3w0EW0+%8e3kl((t8|INc}r zTCndzxhF#u7xC5aw8~zwrlYkKM_mb@T|i*G#$T(R97+1xSW}F_p;p5Laf(9Ohj5@E zwl+Ksry!8obk#bFozJ(m`p{OcNoHJ;)d4>Y#R*VtJ{KI` z*HP;0=Hvc-=4eZsb#eb?Vkq;(EZd4r(Q>L@7m-z8)XK87N#~9A&NRQTLYm1L*Y-1Q zJVg8I!u0qTwd@w8iuIHks&llc9yD$0V442(`I6u|a8RLb!!`6~D|*-NS;2#zMzoXa z0J0uXF1qSo0)ROp(>^g(?>l#6hr!Yj9V829c!$qa4-ft9LBe4*9h@_8>g=I4I2=0z zDOEn0es%`CmW&dXw>fnEUs;v++8Bo_`8!YBVA_Pf`eMHElIAb4^B7W`yy@8=S7DLW zoTsw`?>^Rvd>J<@e2ebx0v#Rj19fmw0(1|%2-dZqXT8vL=Dt#rBIw0iN_9beYTA{u zSO-JR)khb_UJWeqZt(k_u8Om|PB;45RjI0P*i8toN3Bes8H>A|<>G1#uc&7 zAwV!jPHtZBwwFtn3V@JP$f47&5K@Eg0)>g+@Oitc?q%oph;Nx^YJ(PYbagseW9Pn` z52t?JRbMiIq@3NsxS58zL764_s36$shKPGLF4JZT@HQ-Rrd9dXEcGSh>Z;+Q%%Sbn z$_f4Z+$yvLNfZWD6y~l}(Ut2dbl%JFOX}R@Tvk9L;~l9eTs$_c{%G9yA|~j1?rDw5 zBh7!}GvyL00;&P1f%Evj)rNvSlxpnkVyp*3>k>W*!mg==7I;s7n~|4#Om8yxRP4Ox z_ZGR`ZEu5q9)CS_0iU}UTQgRp#R^<$b~tYIyOd|Pb}Biz#j2b zJbf+!o(cC&gN=>n&-HJ~G4Xx*U9_<1bK=>ITebTQLuT6`cHcha>V@5M`#zN71qCS? zha5ABK6zp2tz=tYiPpF8Bh=jgX++2;r+OM7mi+#z+!57!DsM#hQ9p}-LGRvb+(;ki zcg8ubq)y&Yz+wOxMmV25*>!$j`wx!~Ih^2KxoSqy3U6g_k?;E*eXwj4xS`qXOM!$s5O00W6Y~O|R3AXi8o=PBgebfLoc%8}zX24tVK>^3Huima0}R=m{C)8djpC!W zXzwF~gf^FVwVKwh{SVAiJaDNA6zL3Fm{&;r$KU_ZT(gnvyCa?nH+;%}osKqy$K+pm z+OVW)aUKmK1+strJRL~b=jq~8SHs8U^tlntZrN!V0VXGb;5t(Zg3}wsM=UF_t_w)ezn^IN(RH9(4R4AW$Ksm zA17bv$oq4nyyh%wKy=@gjth>j&yMyzC>EEI(1>vwlTQERW{)4mvQwy#k)MO&%6YUf zuT#urAN-o`GB_s?mwR~skIOxPgi)Ln8T(XI^=EecQD1yJ%FS$5lw#0V>TGSg-dL%j>o#1R6S!Va zt+FJz3CmLfnmLS)WZy*5`h){O3zGIMsNTr?!4T{u41QxSS}f4=@l=>!yF+23ewkle zzZ_roH-R5W8cumlpx?{Mq$w8iE!4Ov*3}jxM8D+P%^&qiy_;pc#rE0=3U3N8_5cvf z_Z;jxVcElK@1fasS%{5)E@8sIJ#+tZ$NTox6~>m1lmX;hi}22(ub>v)vqv9jxF}Y(`<83Ca^?Egu4`p`O74Wp{;hP!ci^3cUcNWTjHH&?@v0G>XCg3?~GmR&gR8#>|1x*{yhA^HYr(;ZXB30_>U8%JBWp_OGuYq z<$v3Hz!dLne$%2GU3_>TaP^3h1BNg^P%in@!|A>AyIRX2>up~hJ~oy+wxbFG%+y)xdPtuJdiYQ(*d8}ZIe?!osbjt;$AZbEdH z7;t{XkA8ntPa2(scgB$~G1;!q7i(Xn$@YDNQmQG_PTtMWkN|gX_FK5KSxD+hyqluK zor_)ebPicC{3702sFUQlRP$S%))N+D_N?9Tw;ICW#+eo+r=NS#!MDTo0VBf(Fu_;2 zRO^C^pVz^!+v5X;Uc~MP1)r9A!IT5+Qjt(AfF zu7Zi4P9ImSw-0HfTxdn*Dw^o1b1#!JWPe<-#O>RxT5@)y`O5Z2^G#|vIvHnyartaq z*wTj5yRm~O4;ec)+$DVU$cfaiiizH};B^vUjV~@(Td+W|4x9488)<8+j#b3)|#_x@aK?ab}xKEM0^eZPOUUrnF&d9QV?=e4eN zU9;nXYg-@wq}45*JC2b2e!^|g@@bO_CKiPJ z)?qLFyx*qjDSlSCSvcFz3pcAchKy8pBCr1SY~I`9%Co4TD4sTHLg;yXL;Ov^i1mINiTG|w3%&tgXWkA@h0Wj^e@2~V6=f${I^U?- z)tYdU%|2c_p}e4QQs|+Up%6LFt3ov`u5=oAI@D<|lp4-E9i{krjh+5-vh|-@t(f<= z1AlV*nA7D>Z$LG+Wlr;)4sqHWReR5H+T3Y9r<01y;?rh^LTPSpmF1PBO=b*swpGJV z3(Y&bot<0;Rf{W~c0jd2PV(2(?UGa4-uBw`@}lYL)>pY)sVC+$S|y>-4S1z4EzR$y z_-T0>L#AU#%a@?){fP5T{Em_K;Zi>*(yXE-Rnv5xSX@|KLe=tS7Zhuj+;yhqH=!yk z?{eC~XK|YCl3A$wc5+^6Sz38XK|Wr~B+2F1xQk6!AJr84sk7BDBlfzHX9Z(aF)v0y zbEm!23DY`Xt_t++Y7@TA1&R+g5cq`n#Qg3w^Yrev?++2yWVjDycFh}#YVeOCp7}Gc zVUJLVd8WCYubdynH^IjX3k#-~9aAuI$T{}H0sf47%?kd)<&BB{?rdA^<)vw*`FY(# ztEq;H`8)Bt{CQW*VpMZ-w&PvVR`^u(6m$}*e%kDsv8tENe}{jtUbBiss^2%p_0IpR za}u5M|JB&vw<1ydL~UIyE9Uj?ZF{LhUpvL};-zWo{zUUW&al0iX!aYfGae&qLQO&!#sOD9fyD(msAJ;rhR6J3^ z-&gGS1x_fRJULzx3cbt}(po4hO`BF+F)1FJW7kS((jYrfV^AfSR4{omX+sy{g9T7B zMK;vW#pg{dF43jk@LE8pI&JJU$?3kVP>B6!-r8(C%{mRSJ$^h|p)T1#CR!nL@`?&o zz|f)APcN8MRuYeg2H+bIKkyfYV8 zF$b^dl!)gHQCv7PUJ>d~Hmc_Iw4%J}RA4v-HpHiJCsijTp(?Pbcw)XfNjJ>n@jFoQ zT<80tP4H)B_n%bXkKF4Tzt8$=>4b)_|{eUb5#CgR0Xc!Vm0h5R2AedHnpJlq`Z>JrSX~Z zX=SA)@w`cs3QDFgEwl*=O4Ftk7EcH*DY6;e;CQoXc8IR>E01kov8vcsbGg&$X@$iT z^UC5V^Rg_ooK96U=H!)3VfBRC&9GOWfT}u)Ws#WWiB<9YHx^uZLzOZ-_H=l3+}S$4bm_;CstUVOuYCnT(5$Lpjrt1P|eFIs`$>R z@@eOELTQh5Rd7OHX*|u}b6k_IQL3aX5>>nH8e8SWV@Kj~B=Pt$!Ee*Bbwy%9CFXfz zef)RxeM0futTdpsIIb2RR+DdM38V1kamPly*hI^w4?KvJvsFwiWX_xoYoP zXlH8oN}FLdUOl}5FD)xAESNySkHghL%TRU93(nt1OTqe_1n+6L{5w(dcof(&%%`gN(BLTA`6TtjQs@(#w{Q=dh3 zXL{K9Up4BScj+BASy90>mVRm3&C9H3BbivhrN3JvN0!Kw%WVhFB7JkR8$8N(R{|&0uIg5DJYWah<)|b2Mug5cn74vcdTG!=elhbKs z=q0MH*)|B(wB4}UjzQwC{{UWtpE&rxM>nV-#;ba+r4N^`8hxtq$8z093J~8+ z1sbEp6N=-CpYXWlkHFP4-{F=1yeBBHE`iSe9ZgzSEMI5qJp)yA;y_>N_{nbgPk+j$ zYx1#BWkg^T}=>y+-(^)~;{@fvXZyi!mxaSuR~Kk@9CcxFtz z(75p45Hi6@|y z_>@q8PAKKm=1eS}6z>C2#;c#VHRSQVU|Lxy^c7wMbT_Jwo>(xcR2`h~Up?>taQx}P z3z;qzhc>z4F6K%;H@{@3#}u>)7dP2rGe3+!34aBuY1r#ewsyat$0LYOB|e0zave~0 z=PfVWR&sot8RFyrImowS-c>{#PlCiTaT;D1oX>@t*XKAr2~{`EdBtWt9aSs8dC~gB zrjl5`iRaaWue$CnEGsFV77CTdOJ){Kp2IGz#~6Re35~rgt8Es=e!&T?+gygz_>Mr; zednR-iGotj_3^x-9{!pW+J~F^H7B&r*}uc4NsRGVcukfLT%*c%e$&P$p5E`rp9oJp zz4PE6Jbfizex2m^ZPvP?F;{z}dW@=TTb)o?9-mN9GHHq%qu-Cg%YU^i>3`YxN4oYI zu2*dz*%|ahzaxE`7?ZUmP=)SrYb)`TS~{_0&h)aA8~ll*>z}#HT$9*U}q; zs$mbf>&nqC_`#?u-X5)JOW@Ey?FnfI+5w+_*tVzz+8Y1scXr(k{XP^r8Gk?NltI=H zc2|2DZHK=C-Vr^t&uS~YdhG3=>=0b&{F}s|4u4=D{jU~%@QW>A9ucb0#ps!6M^y2L z|6$K|Z=vn*e-4L(rM()j_%ift^a3;uZH1~L@w(yQsCF)@>%RKf=KCgk8h+b5^#5@L z7_)dG``X*}!a>*Fb(!tL(!$_zC#1)a9(3^q^}|7z_C$4E;<@^^=Hk?&e-{`hck=XwqmpIls$7SEfQe?}7gGp*CH`yn9cu8Fp=EYd(bwRG~I_Et^KDZi)3>{8G}Zz&>Q47EC9-dhB$3Gqj=8 zpW%xC7(EfamWnE$*YM5J7tn@U|7@(RocQcV07|eF)vwa}uf^I1W|%x~S5B>3ZNDR2AKZHq`p>aEfigGXT|iC8|ThjZUvZRls0W zhluW|T9D#~;1`BU1txwUauBbAKXF6&^l7$7SEH)n2XOVUUfvwX+ndnqZNtGj-`v)J zu2rk7P4C!!CI57rJ~0>njaNg?X>aRUR&w?^ni6l5UL7}G2LnD|GRIWTJikrr_7#aG zQo;%{TXI26ITl- zamGm;p>mnJYFFaz*9CZ0EaN=e4`-pO$mwX%-2Qd}7Zw*!*IU#!c*R@Kh#U`4LC2uV zczStZVH&Ud!gytnIJ2GXGE5xOCd?^|&nhU5>!DE^zrf~miqphvx%_zW5;l~$D{LBQ zd!k`hICP3;gdw1{5FQi`-g&Ghfwr8Tc(shj0B(GjmnKeciMLpZ+s9p`*AhRn)W_Q% zNu-|?pHM!9HM5HzRRa?}_(66!lqN8tV0!nSBq*O&TvCK4j**Ml9kkiD9%?t;Mt;?4 ztt;-j$W|}$w)1AZ`Y-X4H}N+3TDYq9`?sO{huQQCoX&FT3Q-MAo>RTMO`AS-O4Y@7 zT>ggA9TjYC(}LgeUI|dY?Z^!WC!yRCwqmcLS{W~(TB2E~Dzce$@Acg5Bfn=z{2t*#mq8~~!`%qgt?lq7_SRNjQmEF25)bQ%U;Q_m zXe*S2YQCx;m2~xlaPXA*J`EIS+64`>ugf{=C1y&ZpC-m_4~#(7^1*(`(_2?enPS_W zIQsi!qjp8}ZR*6^pv`#o+m()AO*$2;8;VX{7djn%xozGMRP*dxRQ=Y+>77$;K6_D` zKX%?N1eCBX36xPcGScCtEvj|dbXqw0b=(g{w!ikGN>`2QNU+Z7a#UOEb*Sd+v?6~@ z`&Rxf?N4cb&Yxa9`Mvr-TvNXNlEW=m&u*}G)1_a`9dOU8r#7@-UH_^4E`MqH)b#A; z;S^3S!F$ytica;bzV38;r?BT&4~Zq!g#GP9Grc;*oI~DWKXqs{seh6`=%UP|g-QOR zi!#G6`dLF`ksnCW)6X87k<`78KWJ!Xc$)9!#FC!F+FjRQG%Pcm?N<+rg-7|`@K|_>pEW#|^h!N{(eTW0UB7yG% zURl?#85i|RaOvceWK#3O>B-KK>$qs-bKKefj-eTmQ<8(wxD4-NLYbtm<5vxfhVSt! zb7S6HFy+A=>%H`3R+th*{G8#@@Wp=Ch?qAY)(aLCne;c$-##KUoa%ccW8r~**2tK5 z7ZayH3Bp00KEf%#ke@R&>NRJKqrt_gWO$OFH7XV^@GJTIDZhGDEa}H%{RX2my%;l7 zS%mzmi=yFc{mRj?q^&9bcB1Mr8&svRpL1J!GDdZwsN87yYQJ(!%zFmb)m}R!>V1Mc z*CwaH_I}pbSR~HMPWP9L&WNlal@6scVp@|sW zSwZ?&37zAojLt~5Ei<(fG_r z3l3!G>N;;Up|fq>8M-Cnfn!cZcHlBqoA5Dy^`$X--n%RoS<^(zbKmY*75$Lyv)e4EY)-U9b`Ml_a?-`oBgZ_F|Q5l zL={O=Cq{B{{Y-YfaPRO5euFWYk)42Ee#)2(uOSP|_4e)Qb!Ge|!!p9FeQ#1Ma%%HX zXq2D*kKV}y*aqzIM_$35rIsXp+uUyu&-Bh`)%Ffb)114_uZ+jMH(<&*1R!jc~`@96%!&i>OF^3jcHs?)cX?Wdi&z2*NW|=KXG;a)G<-795)1)PECX+90{!nLfKS`zi*Ws{8y1Z`jyp^HRpdiLXPfMv;oiyZ?R$l~CUs~y-LIS;^R5DEGh>0W;-2)q z88Pp3n1-m1wuJD>e&vi<R?Yc1P0i#)w zLR@;#^tFC9vH!&PB{pJmBH{G9^x%1Z%AAbIZQ(zT+%DiY0nZ03QYQ@m%n{}X1KraT@&+`XV5dYw`N4Wkt~_f2^W6Cuf8T0`2xn` zyCx&jt&b|9P&pxX1VWpSgz9H9ZUGxeh@FF2pOC%cZ9;56uy(PaKd^>u`DgV1h5K@MJ5rU$LjoMMJe#i<3sGK<`UvnBpL5%SuxoXMIQ zm0HM*!r2rL5wa!!TPcE4x}2A2#dJb8c4H!xl+-_{a*Q=$t9Lyin^`rXp!r^d0k%SQ zgPVUQPK5_|>&OZ@O^V2;gn9;{(^wxF!9*EP$gWZri}xVT4b9AGM3QkloklSMEs9 z;Iyi3FV`DvFQ6I2qh3E8i%{DPJ8227zm68(GlW?1a5dl`?wVx3YD_fT(XYHE7P*AG zB!>?UiOVn4oi=ILh5n$b%y2V5t19M=$PR@@ay|FB@zJDLvi%0Pa`R-R4Fgj2HBoOF zj+#*|Zj?#i4Dq*JG`nuOgV#Dd#;5c+MAx(}3Icj`$J&ddkq8%Y92}kz=|hME7NyQ5#6r-d7!^%= zafHA9j!f?dMIXte7o%h6jk27HBia@4I?gUj3h?TUvRgBQPygM7(}o!=Qty47El9bv zV#iSlRP3UtHy+0pXY-8Qt~i}Ny|)RmhiLrh-s8tuM~5oUru%Wdf;iRf)Jtrq*{&ajJ5o3A7F-4?kM*n8q$guk zg@~yd&QpkUo~9B{2;RLh@BQ(1Oq2Z_KN>#PuY_H6DVs7^1t&Fc2~K%%-c$cy>JM6( z={2~_)(1E}%BEetGM4ni7p6XZM7xV7Vvlj)Mj`s=f zY}L(Aof-8`nqa$|bLVYQZ!AvDrB)o7mrn2-Jdo+_2I>O#irb>$6upQJ>($I^Mr*Zv*!E83gwt#Fmrzc~y6|n#~irj$fjk6iNj8o(4*+Iee$1%=q zZ+-J?kL4Vk;&{5HQ#Rqad(1oDPkkWj{et^#=3P`^tH^lJ-g|MjFEr=>ic>DZGWSln zJaL`obsnxCaSS!5gtfTd!8!22kyP3;+fTLir{}pHPsFMI3>-V(qd4_+kb@U0Ow?HI z?vJxGT77%JbEIT-y!T(?niSdV>`EAkJBK{&gM-1T_k!sdc}pp^MR*;i**!NYSfTnR zvHBy}NW3R-ZY@#&Z*ew1_0E~aHqO>~5>9b;t9k-wdsXY~OXuu5J9E0d&ZeA%({*-+ zt-|R#+y5WqG^ZK`GwhrhiF#^;=izLB@pS3Eg0uTr&Qf-#61#KRUbqCOJd=Zsayd@D zV7KnKowN6W#-)kYYP<*Gx{;E*0wr99(`W_v2=5u(SvY!WWYqhobCmFDdUBa9j@8LK zic4{ve>o=_LiUnW=KHI-GlPfiugm;F>odKc<@PcjS$SbH%dcJ^^VY)7rWD#i4PrCx z*mCk&|%@@{H*6=k-RIlx9hg`0-?^t(l570 zy-#r(J+?R2%z&#BCo0XdB{Xl5S&DB~0dJPaK zq>kp&qNsNtt`{ztl9BgunHs6^X@2GAm^Z4z#@crax8i~mPvkFzSoGv}>^ytx;QBAq zlQEi^!JDB+Zk+A590vAp zI6FIZgGlzPx5Og-uA$Yz;o|{9eS>njvqbjcG6H_ewVX@?Uh{Rj@4X!JZiT2OtbZN@ zU&p2U*<&*zb+6NaGF;(azW3*tSBSqTxRMnYc>%|UeNBcJT3{!GU2W;OOj0qecvhb2 zXKjsn8(N}ZZQ3?Pb9CRN!Q?%ke;LQn{gSqkY96Y)cYQHq?%s$8;&e^ z?zg3W)~m6k$8PW!y_y->M^s-w<%8bI3vE-`U|)`gFZHvw#k>QsK|$#%p--hPFSt!b z=HOy}_O^`3tBFv!o?lrVi}YNi?o&(|p=c0#B*BvYxyT>1Ez@hg*p3d%hkZF0r_o`i z{yFMZ;>HF}%O|=d6k?4KC-=l}?y~gcn?fNLri;24$IP`Z((-2hL4u$CdMv_j=TdmL z@OziQrA|&y#*D;pF!?Mnxfr%tHjj&|LZRVD+(S53hvh(A(yjKKYOC7K=bv5?XPuAZ z;Nsj@xN%3^(A#ReM{%}^YHBav4r_v2Hz1W55*uHr=oMODr<%c1?e+o!beW zPaKnJ7`Ji5Lr=m*-oT9rZdq-Y+1qV!BTZVi%y015%t$pbI2n3B5>nrDXPO@My4-PO z1Ega4I2)I$PF6Gi6WMg`km4I!-!sy#G4`7XEZnHt_R)y173EYMpC^&^qp#{Py=p|+S~ zS6CNpCSHG>TjCVDz&UOR6QbV3ciUIS?64c7-mkd9L7uqC)O&(AB71u$6X=t`-Z}S% zLKj>2OL{U!&7-6_(a3gOcYnv0jL6S~I4JUptLI9)b{JE(;&Pm}CMN$|tX$j>>)3po z-DjIkUXP{M#dP+wb9m!RNE-o@kTcFn_a{zJ>@MCooO+5*Ans0_#w>W|PI~WtfBSox z;U>QKe$2c00ox;XDcy+cXD{Q1@CL3|a2acz4bt1go0(Ol2p-HIBs9dNG!6Hz`(SVs z;vRiIA+?(007r~RaGIyV`!VkjPI)tHiHkmzI4Gu0ibih0vF-AEkKKfHx3!z0x7t3; z+fld>r`a61$eXy4{*F(2C$C9lti_m*%Sj|k+PKEw{!ym)H83Lqyl9U*WWk*U_%%4Slp$k0n(->Nof})7uYJ$JvIT zy7tJ5SQCE;Xx67TlGlJ9_t6y=wZT9h~m+_drd-D);ReCZ;y~_+`gIt4C zLI#y1)IMBxkcsANx5sTSl9EgcaY|`d#A@8oBPr`Vk(j4ico*VSab1_5?4rD2mwg4- z^T=ht{uh_Nu6EobxFa3veT#F8Y-2P$z^~jN^WJ;%w-o8gPbFrFUSQ0}>0)kwS4Sf) zpQh%)`;gI3`-7&$lI4kIe(}(75U1KQS2*%@@+&`$c@x$r4tZ+NgU)dWqsQt!W7}$v z2Iu3nM1nm$e4StYS_6D!nd-t?6GGNvmG)7aio+JOR+}2U9nZ&QG~7!y8OU`>CDU*W!9w zw=tUZ!X|(FSDE2DzV~&^>$dsG4s@&DsaL{Q!?ek9JmFU_A8hs)jp3>GMOz~l!)H7+ z;G!g9RAw_9aQ$)ioy*o2{RW3Jy@y`1E1bK)m}sQcmf&rk4xxl}DGQTHe;00~&4^v$ zYo)S|1wH6bt`|+sKwd}Sh7f0;u0F!4$l&nmwSC!6PWueA0%v=a4KcC@XCJxS{MoMO zdZwzF{BRmS7A9rgjnibYN3!>Enk{w{JacPeI_r@pA7_u#j}jV4Dtq+!2B&FGmrPEt z`${m@G)x|L>*=u93+A#}`$~+on{TTDM!p-U^&b=2kx=8mY#eADl@VzGgdvJ0PhB<1{G2$a{C-H0y%9 zR8q}r!Eb~MUk?ROw_#ItBE62YNopnpMngbew7>q2BllKzjXpRHNU$45uEg=8xw>~U z0lOMGeno!9_3%@2c&-12R)u~MHjR+&a4nt3aLR@%F~2^?sRM(fawPptU89qKnepm` zW06gOOM+Im_)Frxr+1eHI2FoN!L7h)3>h^h_B%LM^?ezU7B!?YJ7)6CNl5FBLa&Y{ zU0-7wM8cWgvrt{fNn#GWB5p+B^z`&s+bgUIUT#(3Iupf?&U=uZIIW4`1(|p9TZv~u zJ?~AzT^Pja$?yr>Ae=p&{eb(eAA0@Gu9vV$&0!R9>IbG8Z)je^orSY&>EAfJ5|n4> zokt!{Sm*^fT^HQ;BhTXOd(H0@g4^vT`nH`StR6P^Qk-k{%h9B@Z<_`U=#1~6XWKF# zOHY2sHs7w1iMSl1jtd^tPTi$52h%)KK`7It#OPl_=a7PVGb%k{xEV6S9e3LaX{Svk z?!w@=5<3ZX3u>rV)qmHf3ZCA)D{&)&IQ93pIIU{h!l^p@y~KS(yZj2A+G5-J4o=me z+DwZs@7rDso-e&iaY{)EOQVrHaAT-P?_>fRFe=MH$Mz&LNadmbMVz{X`_F*hG4x@gD{3aCCu8g|&=ujCCMz|}ZVuFV1}``w z|HNJBr%cN5x_y+WN)^BUxEhyka+cNUZqB_r?A66~3vP4!3H`Q!PTyb;VYt%`X48TX*eM}E%dta z2AmxVt(Z&q+b*SpCqyHwaJ=#7Ec%P%Y`hF@`T^SqOy;+uNvjT+MJG_F?+%#lXgJe& z&FGVtJ`DwriAor1l3g{@^_#0a~2LTR({c(0b z*C1boQ<+RvcIOSaY_p^}3-*vJMU4tyXR=z;O~-tDq;D1yoMEzC(_`NgTw-f*{dc@S zu)*^WCps^(nBWvkzalu!2B&_{5J6SSpyxxZ3h^;$4Uui)mJ>^8JB z6t=x-Ic~AZR-O3AAFlNG2#&NP+AWFHHn@&pl`XMfop9({8{A6p%AnHT!n)y5@o(ew z9oA)dc_ggT)pwr}EVjWh{HqXq>baYcMyP)9%aM=jnL!}*of8k~y8H%$rIO(2bv%MqPd=9ejK+oo%huER#wi}s_J1?kt(o>$qyTxxMQWU~l18t$#_0Hx&PmS)79+5ye`;_Q(px4ib#tTiVvRAZziM?gRLr3jni(O;dMVQ zoVXXT-CgM%S5Jz1FXP-+&V8q0L+iNZvpJ2$1@Ac{4~YjmKLNFsMzR0J8YL>plWXKk zoZW5L66#7SZk-QABVGB|5==|Vn1}W*ARI|M+`%SU&y3yk5x>ac~2Je7+^5GlxB$oZH-`@^f~iCu3aEWVHczVelJ*x-FPSHmkI7)MLwZcVA7M zd*p(?KSao#ZQy-Rq`rRk$P8}GTg<%ZQ*l5x;rr)bX#Z@ zX1mmvBFYF+k!Scqn&ub3ZH)XxD0o2j(px7gq1N7r8{wz$6_LLaI^Qgr!3dmUXDoXt z^Xdwmn`MmVD>yegJh(P*qv^5Z+1_;t3^Y3m*k}li4?3aIsp=T&6V5l4eV8Q=0W=&s zG)0s4ooX6zJB*xhn(C;#Tp=ObOy1T;HsN@bq-Ng{qG5b7qF-A(y3BFDwQxgQvna-G z{xj(0pzE}MmL+P zXGWgG@fCy3z3X;%vmr8zP;hdNyiABagE4H@#ny*L?x6)ZHJJ<<>AP^GpON8(&vIiC zoc_DwR1lrU8Mz#1=OD+&$Y!Ms4w+vPa{DiR)1j-qhO-J!=7l(IoXlI^Mm*NlEE-JT ze)Ah;RL?Qqg-r34{OclhI7!E*Cp$wA`%$k&_i%8q44ayn%n;m>?bP#ec9+oa&G+DJ z9c$?Iu4gAo*DoG0ZVB;a35@0jM_68sHt6Bji`So!@($|jEfNn>F@}*p<9K&NUk*LT zW)(cAcuR1u{kKIUHMrnwEuI%mG)V7C2H=z`$yD`V=fefxH1;+nc+g*U((M{zT&Vwf zxc)(Hf&(>9IoMLS;OvUmiuxI+_Sj=|_nwJ*E3OEqtuDAOvK?o?aowO-t^6YWaeVdX zqKxo0rg}Kz@hU)B2Csm;pK-1@Zc{xoj#P|}nTz8z@3UnS(k}d+Txb zcAa`()cX#nfww1;9{gi1-7M_O@0)O{uOSB;AKSq?A-Ua8`5^cS2z$qVQGkfh;oQBG79ew*Bx$AJ~@^R{D+xk~=x{f_M&KI%< z5Enc%^dzKO!Wn=oadzINevw`m!#}aukP-Qk5X*rZQP6N#${9E!LiwS`P|`CI!i~VP1egu&p1P z9q;-t#c3np8ws2uR^fs!H8rEzfN;942b~yBGnErrF4HcwBND*KW4Qh%r9n8u`--4) zvaf5>v+aSMWTjE>a@=oA`T^&dRKKPt{}#pEXfwoK#+dTlHrzRy%{z|;xFgl^YH%@I zIet0WeW-0Bjp9Z(3#Z~(bo@@_MVw|djx)ufp=Qt&X4dH!*^+o&#`Ebq94~M<7}d$4 z8Npd2i;#vX7=p-R9E*P}Pnv|3yPaDR{^^_6gq@)Sesi?uR-6{U-H{IA?613`!-LSw z-gOBCkFSx9gfdNbD^5oW1>0|ri)+m!Z#mBPp|;Gw<20uB_H%k}Vqeh?GzOJ%)c`GjmI=TN(6adv5H_I{1CD?+>8Iiu}jWT?oY40n!6$qV;R8Xfi*5APG%58)Av zcWG_MD0jU*8Ba(@C)>$J{D`Z;bxYJUQfI8L(O0SZ5YjcltBaJkktQP5Q;e~|MdA#-ExOo$fJ3ZU=>x48FIM?$&`X`*OX6dj-J5RAwf#Kd3 z4VRnBt7zp@z@b4#Rn^f*Qhr!3@UO{8Iyc`msNnW=UA`G4-JWk2NslQo+tEm@Ao0j~ z10m%=w(Rk5<23u|O1^zuba^(xRz>ln-&g@HYwNg_GK}_ zTpRp|Ak`4QEC~0iI6f5oi(>sNS^d+=P!d0_ z`3duL3P19vI&F*UQ(Noc+w-IJ9r)2lD&J9tPi<9xodOzYMUaq(8~uAseM>+1NbB*# zA`RkMJb?~I^^qzgW_j@WpQtLt;02%GlbGyJ3c)H5IQqoMei zANA;de&7|M&j{!vRm(q@;Uks*!s(Z&K2l}KOZ=d#zee?`t?FW4vj?BrstWK*JgCUe zK`i~RfG+qo09I9SP`Xq3Z~(0;nB;tI6{_R-AE_!{&&3Ct>_A=9XHmGBxo}Z9Iryuq zQl^knHEW3KqDJmYsp6YBFAbZei&)OuF3-g3vd%7AsxI%2>M|awgY0-z4m2Ir_SzTK zB zREEc(ni5S=rEAJxP0$XgdY~Jsie;dxSYNaudJ(GpDuxr#N2*{hf2l4b9Ivh7BjM`0 za#R(+236AQ_)8VL1y#kCqAKuCR0Tea@+b7D{&JeC<-Ey(|Bb35o85K)6IJ>bNv}(` zxa+K%@k_$>D%4Z2IsQkgs2wg|s{Gz?`li#rxOk}={x+%}-tFSwb@5X1J>zFUN zTvIjllS}rWROx

Hd?Zk?st2g;QPE$@$tUer6qa=OqyIMrW6>wrVB!fa`*DT>Sq= zbzRh5CzVe})s|j$%-?SgH}0tYa)^r?>hvO1pW0g2WZ%O6e90~B&-yFqy zbn#O8(Wojh#_3q6m!SImkt+Q-mu|dEhgJmJ#AFAgN;t)NseHckQuzYsrSg}fs#u}( zMJ`?{UhKS7>8CrLQRh4hN?Zb|hHH-VwN>aU$7^fYtf&gN&QZ*@E?TNJve0>{>aocA z+N%02cD%OMF)6o(yHse+E_KmTCBGe2cFP=>DtM>!Ql-1gd8zygRM*|(xK#XJrz;(o zD&74WA9csWF2N%%Vy*L!q54R*n{IM^GpdUJ8C6EFp!^9{JAEBh|J0z0f6M7kr|+Qp zyioVpwArt9Mv87-!8tksv=*(6?MqPAF3dr zi0>SbD)@u*QWgB8^HTYroc`>%R5!#3r7OOk)B36npW3SUWXCHKf!eAB`j07V<7|wo zg2$ucO;NS@L{w$BMD?ky;-|oM-Kj2pdzY@ZGV~Rp&MxBrkE)=q?s};zb`GkFMp4bJ zOc(#h%J~0rgyqWcJeNUj6(0zfX1jRlarm*$*H%^N61aL~JSu;w(wR+5-7O{$D-zdV zPL+I$^HN=wkE+-r=chR>M)mnmsuRo-(y3qczv0qUUtX6%P)Du+XbP=DRnUW|DzF;W zr?!ee4A*sQUHZpRWxO8cPiUk5`fpU%Kkwq7uX~y;@C66{NVyl^9&T+;HsMAL84rvu z?H{Q!-%7k%_Zq57zTwhK)wnmEm#Wflqw3Z7P(^*nU%Gyuj8k3r&$|3a78Ur!MM&$K z9VXnmjmkZUm45B?5US+gqU^ZKc=W)9esR$%Q_*3S{X12)>%vJIN=9|;Y>H}Cwn7!( z#`!bQWAHsteWdc|qN+|mRLvO}VXze#;vz0WmCi?ssk5mOU zab7BaJgOmRj_Uf86hAN#_?@bT`v0uyBh`g%oUg6Q_*8fuv*%7ux}V?4N%s%_s?Z!b zi*!og)#X!LHMHq2zNd??t-7w4h!|~cG-rI4sBIv0B4oH>Yd{jd;22}&cyZAp+ zb;xBdzP9SRNpS5)Gf+)|nW*j^SG)9A*JGF!zRrO^QdMXH@#={iUAo$;f^LCJZ*%dr zRo5?tOK*4aQhB3;tpdwXwPd;TccS`8Rq%bzOO@^c=WDC-Sp`?rBm5=*s7oi+ZFRfj zuQ{!F-6fDJ<2RhIt;*<4xF+XcUA$B+e%txls(f}iUR!njdvNIoRx3h#323!^>Mp3Q zD)=*Z!Iv&xsc6`v-Un5MV$PrId_Pn@Js4HKLs8vkLKhRzg}F{gpsL7dR3E9*jdxzE^p`rl3{`;> zP`%zNNA>wnsw7v{XZt4?KpdXVy9XB&zG5M)i@ZYd1JwTN}Z*x%k&n z<-bEM?M&cDR0XKHiU>PRQuFyp#p^gPRYCPpU3aXDPjPyj(}t)jnCg6ER3E7(YejPx z(ZYe&s4{Ge29we08BWujp5?SVssehTs!&g-eVq11^^q!m0IG(ZZ?z(HflDAVOT z4nkFdZ0CnMKMYkyBb*bfz`k8^sN(}_+eqx=a?<1ghu9Sy$HJ|hV5TQ|k>k*aHE zJG~m!1@oL^7lGji7Ng5E?%maz>hn=4h?=`xS4>u^iQZVcp244stmR|ebvQpb6Sn+ zQ(Kk(HJ5&eOZSG;H&OnC-qBxHD}u@Pz61XgRR#CB^iuf`P!;?Usvi5q#Y@ExI4@QD zPo4iXnf_PHzjO)zjcQE4b_u_63I9m7mHzCm`_)~S1XKZa6!|++@0rIb`f@1rk zy1t)_m#UuUqpHq8kDXc{0!LIC4#lh9!(76PosK}2!59}m4pjl;UHoOv=b_qeCOba` z)uJhKej2LJG>`ICR#l_|uA0tw@lq9djq|lt>8^8Js&osSudQm>Lb%c|QUOZ1 z*d>(8-{=zD?Kq^vK3YSub`?(MKu9^r0SwK zQPr#l)dg>(y5JqhcRT+ss*hCZK6GBH^dF%r;A6+7O1Iy6DgOM>7XN*XamU`@;C( zmum_Dbm3)AC!oqOj;aNhJ6?$DBUOe)&P$bky7N-ySK_n`Rm0|@YUp*SJ{1b+!W$g; zBUM2QUA$Dj(&-|{rQ(ZG6}-gxn_Rq9@i#j!C0(mf6#?B9SGWkNGPp~G;uB~tZj%a1;_RUO!#A2qN8Kl(`JJIe5> zt;(lUK&>j>nf(0mm!c-xj0TZF2?z6|k5n0D%kcT1sIDIpr2emZ^h;4kzZ7-!OHsj> zp|m=_=xOxmm!gh- zDeCB#qV(k`y}?dL^%PS3%TUAsS-EiZqH`ALp zDr&NF;gUvo{o0|!x93hdbIf}mj=nNBcjQTDZGHZw%CU7mfB3?4&&zJ#x8J~f=RUIa zGqd)s@O0B|XLzv5|64f4%q0|#nChM3k*4`hK-$}Y`ljG-fNcT`1U$1vVD{U9Jp#v= zj_&|EyaQPB4j{$s7T6`wXBVKMsoVuvxC`)wK&t7v8<4&muwpl$i8&y!Um*KkKvQ$a zyMSfy0)7@~X0qM`415o;_B}ug^S!`ffpPBxPBLrW2dsV{kg^BR(v02%7_|qmNuagy zJ^&O*dWmIL%?aK;6p(EhkzXd?M#c00L?!F%>4+^-c$>06G+<&=xFBb z10O)Hr3TzN)`6=K$Q}8Ju|5LyYfdQt)XMpCP0p@-NxWH5k zY!gWP9FS$^d=8lXIbe^#VAJsnK!+~?OTGYPo81Dt1p0gl7-}lN1T6d#@P$B*>G>}} z`o91x{skCr4hZZQ$o@AV*WB@Mz_Nb>eij&MvJUdsz=MFb2LYqa_X39n#(f1CYu0=P zSp5|s0VbM)LxB84fE@yH)8gCk z$naz{Lo&rwBWByTM5ld6bb*=k9sF`rBbjPC9!3hyd`XenEtzJzevcHJO38GyS2Dx& z`~fL3RgzM3KvHJ<{)m*DJ0vsBLCGwW^%FANtdz_#-%GAAIX@#;nl+NEO!yaMt{IJ( zQNK{RO}|jN3gi6>Nd6U2^ebS#*(k69u(V~;;PACe3z9}I%}+{Mx&ybsv9^Z>jDFk>=0OGS{w^# zek@?_v4Dq6wZJxkv=qP^GbaTwI|Z;u;1SdDI6#Nv085SotTnp@b_w)p2zcC7HUune z2>3!^o$1*KklqNeq7mRJb3kCfKz1r%y}2V5uq+kuv%s?^t1)0;W5C+RfQ{yRfx`mh zngE_RYnlL7Hvyy^57=Zz9}gIHJYbW+i^gjTNNx%!Y6{q5HVSMIXn6wQWm9khApZow z4uP$vMKeJ2W`McP0I!;Afo%e5%>mVBPIJKQ=72o{ubGZ503BKYmb3uuFuMhI3G_J; z@TRFe5wP$?z!w5Frsqk3^pgN9P6E7T4hZZQ$UYgc)7)_~VA;ulp9S7ASuFtrTLRW< zUhg*F3mg_0*9!2SSF!`6{iEfHU|Xu3uLzk95Q#b2P|t3_*vjP zlhpw*umfOi2f+8{dx66O<2nLI}dpK+>-vGoe$`2$S3i zvb7UQ_#Z=@Ns=#(o2hhVD6j;^=kedmJnw6P=fti3v4A9f$!~ll{)(d2q@VS81F+luWKp(SCVAQ#Q zrhNf1lh+rJ+!wG_psz{o2iPD`-Vbn|*&>kN576#BzyLGjJV5jF06PUPFm3t+wh1ig z56Ch#0<-%AdJF&zHuDDnIt&2p6Ua7Q&j;)hSb9ESsM#y9@O;343jjH$>Hq-Fy)2$W|7CYmh*`PqPWLjZ9zV+f%65Wr4>DW=U( zz&3#eLjeW+KXn1KhXQ(B1ej{(Uj*oI5n!J{k?EQP*d?$u2T*MG3M|Y43>XHOVXB4! z(uV;K36z??!vXsRRt*P~n}Y(&h68dh2Fx-mFHX{#<9o>*laq^FVb(~lG~p2>UY$$g z_y`iuHR}XMjQ}(q38*l6BLT@H0b2#;o77Q&4Fct(0N0u=0{No=?M4F@m>Hu1%|`=v z3fy4Yi~(#DSTF`qX=(&!j{)=;3s`LCj|FrX3)m;H#B{v`uuEX+C4igFUV(*|00xW$ zRGF%Afb?;ILju0(J07rKVAXiQQgcvX*?2(ir2u1AUJ4j^DIjtg;0}{>8Q`$MdVxDl zI1jM;GC({Ju)?ep7?lTTIstHx$(sO3o&eY?u+pSX1Z)r}p9r|$Y!S$x2xvD6u*%Gs z1ZX}9uv6e6(0?P^jxt9Z;H7hR%47?l=nF`owa;5?f z3#=D--h>MQtEU3ug@8?FoxrFW@R~GU^yT%6R_Ll z%mf@3STFFN3C{woo(YK00_-vC1V+sQG@T9j(B#bqB+mwH71(Q1=KwYcl+OWtY_F2yLjqr$z7>G|0;?(jhs;5NWfg$jd4TWC%6Wi+ z^8k_gfbUJte86FW^#VVd@HK$d^8xW|06&{`0;8@0G`&_wkFc3=t&SeoLbgJ5^tg^B z8wAR)1Jp5F1oE!~v|9j(m>CNI%@+W63e-1kt_N%rSa3bSGc^LUuLtzF0dS0&e*>Vy z4S;Z}z%GHM3jqzyUV()R0Rt)lsivwDkX{KmB+$h4T?E)Kuxb&YsW~XHY!M)L zF`$`Qxfn2TF(7gypoPh~5pY;wy}(H(yacfNMnHTCpru(SFlq^)=}myvChsOd@=buP z0&Ps{&43L8 zCo}(6K!;la`vlTVS0AuTV5tx2V)hCw^Z^5I19UZ2w*k^`0~`|QZu%|->=#(I6wt#Q z6j-(tkb65IYF6G37j?9MJAgzyLGjPC)ZJ0XqdQFm3JvY!g^;7a+^j2+Y0< z&|?K)u$jLC&|w8&pFpRv#uIViB~UO?_jz(})lC1Bu6K;%BaXp?gv;IP1Yfw3lhKVbEJfcX7@ab}&ssQUp; z9{^lx@*V&rKLFS&kY`d?0X7JfuL4XoTLkh~0opwXh?^M?0-8Sv*eNi@w0Q`yO<=)8 zfC5t^F#91ukJW&wX8vkGht+_60!60l8o(}rrE37iX0O1)HGlyR17?`2hXLsi0}ct4 zn!b+!_6w|f1W;}c3M_jBkozcLmRb2IVBn*G$XdW0ld~3ZSYW-tl_vZcVD(x+{4u~> zvrb^tV}PcQ11e13E z=1IUdfdx+jDou^R>?Z*|o&qd3^Pd8AcnYvjV2SDaG+>v&(x(A8o4o=Hp9TzA52!L# z>jCNO0fz*9)At#`et}ib0G67A0?VEO`fn{3&xqkvYYgYaVFz`=+$jg9@Cg)|q zVS)7m&zta{0jpmI#QzM~WY!6c`ZJ*ER=|rUZz~{qD`2a@7L)o4V1q#UD}a~H7J>X% z0PS7{Y&A1p1vGyZuv6ew(`FlBo4|r?fNE1CFnb%IM>XIzGrt2|=IX0O1)?SKKV0cuRuYk>6E0EYzLGJRhM>=#(|I$)m~{f9-UKxL3*bYO_ZL9&UjSPL_L~2Pxc82) z@%;bz&q*A6ZxTgo*9u}QLF^Tyf*L{W6^fWiD7A@o8MTYlrd3*{Min*FR;xu()uOdp zyDh)x>zwOu!bd-!@9+1|?>zF%b=|M)eeH4I=f3Xb&XS0*Q^L?hgv(~1gkFgVg}+3& zVxqo8$o(b4X$ilWf?pvVmN4Nfgli^ILiAS%!Cxc%YT~{|DE2kN6$v*?&}oD-66T#o zxMeO$m~4ZyZMI4X{~jU7SzUnmnXYGb0df}QAc`(P&SA1s z!q9UF{$`(qUgr=BpGWYRsPhQ9&m)|ckjfPN0pYNO2|pmDF^LkQe?SPnfRN6_T|g*y z0pW^-3?}Fz!WjwkE+S+ymn2NOh!A=SA&ZH>gi!gCUq*BPl3ycTfc%JX^%54Vf5ak( zxg%l0j|gopBjhqGE+aI!jNthRA&&|B3E`oH?Ggfv`wBwBPY97$5b~L=62h+_>wo9mH+_w=DZXrb8 zMyO%7N(jG=kmC+QO%rhkA@v=EgAzhamfsO}N*MY(LLIYDLa*Nu3jcu+YNGx?$o&Vx zX$kdB!Mg~DB}}-B(9k4Gh`x&ud=H_qiMxkT>>k1u2~ADVeS|X-=G{kVZZ1ifbRQw~ z0YaFGe}GW=0m3~AtxU*6gsT!(KSXF_?nqeh5TVT@gtlhIBZLNz5Im0&+L^G&2oEJ} zm(anu|3pZ5j1c)JLPxVzLinEuIsQWEY$Eb!i1*?y-lKo=%;K?1p9OSF)z-)?Yv_C8RlK#sJ{tv zb9ly|rf_pS&|Ko!OmZWH`XNM_ct3>7ehBv@3^5`82v;Sn_D2|M?nqeRkI*Is!f>-9 z1ww-q2p$i@2ovT(cqn1Jgi*$w5+T8Z5SbETjM*w7JS9SoR0uI9A{9dFR0szp#F;Fq z5q3%#ni^re*(ae_YJ|dR5GI(YGzhuVAe@%)wkenv;jn}WX%QxyL}BP=vwnGqgJ*e+qQac4nD$czw~1!0NVDj_@zLXNBm%S=R8 zgw$CP4oXXi~yj%#I%_Rwwav_A~M%ZfNb0bvFjc`xG`z9n0 z!c_^Y^B`8Mt|Mce1cl<-r^Dv#;^(501+^`L|VL>5cw<%2QZ_SFr2n`A& zc#0r=XTpjgJe06q!dc@kijYtQA+jjKd9zhQcu|BL#Sku-h++t-nd0W4gi9t%afF=` zh89P-Z1zd$RUDyk34|*qssuvr5(uXy{9+2eif~xMgjW%+nM4WEuObAOMEKRjl|(33 z65)!38z!g}!WjwkN+H}bmn2Log%DaA;f{$fjZnEX!aWIpn2<6ES0$`2gK*E>k+7f) zLYuM(56p_P2o1_2c!CffnXn*)hZ43+_|v${AtVGLM3zJN+iaB(UJfBgd4DcL{7u*L z{#=HXM>&Y1%a96~?36IH0)oHUC!tpbgu+@RJtis`A$KssX$h%J!HNinB}}M@kj5lR zh^~kbTnQnaiK~QAtP;W%2^maKWrQ;l=2b?>WG+dVR2d<(3PKhWUj?CZ6@+^dvYC*o z2v;Snu8NSu+>x-LDngrT2)WFPY6uOgA$Y1IL8Rcmn2N8gAiI5A;`qn zMW|dC;hu!@CL|Q$s)W^{2*Ku#gax4pZR#OZGArsKG^mH*sgF>_gw;oQC}F#VYR26F zA)!7(WCMg6W~+qo1_(JCBGfby4G~f|L^voR#AIoNuv5a&MhJDxJ_)@VArx+m5Ne_t zBjj$3a9TorQ?LobVF?qOAT%_I5~7ZjNwILMs!}0^zEJ)h!U(m^%^{v_NPRhS1im2t#NPhTv(5(9VRl zM0hA+yMzwL-3lS0rGG}#qm_RnU4}>qZ-qsU)>w2l5v>tYw?;T9A;M&7gRoP=&^8F& z%svUd+8`8u9U;<0y^fIkb%fIrdYXc55e`e3&=#S$Nt6)X79ltsp|6PxM<^DKa799Y z6VwjjjD&gZ5C)n{5+=1n2yKrLW#Zc-RBn%OPr?ur(gESBgw-7ohMGGP7IZ*p^9I6j zv*Hbe25%sEIwFiPVI2`3O4u%8lyP@LNa%5>W7fKAHrz~YfZua2!|z1=#TK8 zNt6)XA0c=E!g>=o0HN3bgewv@nxKIQXC%xUh_KmQk}zo?Lg*lbttNgDLghgS_awY; zLZT3^N?09*u-)8|upkPd&0vHbX2oEH27?hiLl8bP9}Pu#C?Vf4gk7fhFoc952*)Mt zHhG34gujU}W;nv9=7@yULlH_vBkVIHq7imVI4|LVDLw+B*D!?XBM=Un?ckdLvSB6A)|4Qn}u>tm^*S#nucR=PMH;Q63rty zU+xGS>%Yo9C$?D%lRnlzwWm4{>Si%v3;bt#wGGmK%%xB0L4`*4YWFSjYM%s<7By;J-zrZOMQ_TS(xU?S%DuTQ&^$2a-U zgRwt0Gdbt_SM?lj&i_~R#hbsxzq-;+8`0kTKO1BFwl{k=`=9WZA#j0zV9qifd48D4 zdaiir(B9qkEa=Hjrr84jn||jb%xeq%o4IEj3KZkZKJy~~Gk%_{18f#2y;a{==~ZGQ3!`mHl&&szUsp3V#T2YJT5+du!D7R|DI%Q7gzf37Ff zJIO2jiJMw~;-(63d8=@pS3UCI{bKKL-$4~}y8ZTlv}49L|8>4bR)hNem`cjWexCgw zDPu}<)K}`j5B=|^@VtMX6x80Ml;DoJyJ%Fug;&j!PyCCdZFJR_eCaYfV!!pT=S?+j z*NCno`VAc5I)6*ec3;s7e#rX_)!h4Vc>vqna(#wG4&i_6xzgN)f13US+0Q>fLmW!w z_Vx7IH2;|H*nPmiX389u3c0<>sRIT_4jI^QSfp$8jx1mJZ+6=Tt4KSH_Le6@#G3=V zs)yb$OQe5>hHWWtbMY&^*LH2?v;JO>rys8cOy_NGuf_Z&{-3E}FZJey#r$|k8p z5a+E(NBnB!vmMQA-}@KwOy;Gw^ zbZ~(`nAacWsDt#mz|F}N*-zj+?fA1G*L?fX|5cynd)vZ7L}hplQSSthjq`6bQ&9?qDO3H= zPL)43nq0crRo7Q^5%f7R;w0cBkL8cfmW=J zrl!*WzAR`p)lv!OhF7ds&&FllbA6^jKB~DYk{3R=n*OzjG}d9girV{WXtkI?4l7!* zkrnkHKdV`-F`Cj*Glp2LskO_`@k0uu!Zx#70sL#oO-y}n4gujd(G_9;w7_F?;T3f9MS|v1%i8g3zq@qy8+J#%YVrZ(UKJ8MF zzeaCyP)+sG>!mcxOMq&k0oC0`eigrJA}!KtCGm%%>C?k%rSR)jni_aLtyUU;d8_rZ zS{c>9q7{2vu`F6`{QC64RZW5*z18|#JG}-ngVhFDP5qn6Y6GoS0WGuD23ai_O|L$S z(Ws3=qzvA1;I@WCtYIbeniy(;zG*ey^zEu;wV^g{6|_258*c4*xxK3%nm*B1)42LW zneiE+H)yHls)O@B%#qfx2HIEFa1S|RoSG%Gg5-`g5aw^}1K{pVwSW>~E;{_bd+1v9PI1b;Z1X2C40 zHN}5X^N>%x)tccSj9;JGxZeME&4re?Z#6aab~ANJ3sB$cGtX*a_=j0-KCYU-CD4!F z&q7=^YbzLIwZ*tfuQkM3?H#MNA%AcG5axZ0nhe!P>K}cUTEn*ZC*W5Bm*FZ{-KJ*O zXBDnaUhP25uFpDLrNix(uDLg0|q`r)4nb>Oho`s3HX;?^uUVzmMI2cq$baeaYEMO_0S z3b7IHacejTe{-Lq_eFFnOcdxJ!fSM&#Eu{D>*;?+)8{K2cL@GptoF6l-bCwWwbNdW z_8*FP3{j)|8$>GV8U`n4YU4%%5!Z}(HvOa?Wb=JQjlO~J2K(fgrIWv9WWl}#VL2~dTZ z26L?DZ|$a|X)0>o>&<|QI|KUa{I7ZMvEoepde^q*cuF)i*DTPQ-UT;}wTrh}1a4ZZ z&Bm|y*mlKDXSF%_m2o%R^j4dT{~RTa#Lb|$9jP=rgXu-h`ed})eEgb4y!G}|C`lv zqN&H0f|g@_0Hv>>ak!>^2`l}F>pwH}m-w93|Q1O8Puld5Ry;*Bs7O>03lYqv@DA8QS3Si{X| z9niEEyk-rz;MW^XH1BJnsdihT1)9>RW9_!#?@Lq1;)dGv-p9X%`5uQ`&uSmw*V}ty z#^I@NBX7sQl+|oJZbNJMA^v4nYh>+qpslc46EqcOC%kL5=4k5fk6gl&&EymO-H5DD2bg8ye?Xnh!DwJ-1o&@u~gqpWrme@fe0 zgROQ9?Iz(Dc!N(eu8;=L83Lt>G|hcoOZt)uL^Jr_dIV$tv6t)-DnM zLaU9kc3-0D{eUE`R{;yz?)y7!uYmMDKWU`jPu~s~d|5IB+XLbArO&Pz38;hN4 z@+~N1Y2$3%Gx(LUrs;UAeTQEeOMA;|-{XIu@%Fy@e}YZ$EaHcDWWH^+b7-Gfjn&FK zs?Vb>LDLkPZtZ@+uQ#!22F@?MuSi39uWhYIuMRq^K0W#L-T?7^87l=u~P@mOSyo$dU znx@|xGzPfq8uYey>#TMit&i0<*|@)=^|Ns|qp6#Ig8^3CYPB0^C4F&YT<=@)CZbBF z`Me#MiQu{gDulG1xT?TyNWibpr?{%g9awMe_Tnn|cbFs(pM$uv`vY|8rqAbIjrPCG z!6`yN$30{X@8NgeX?oad_tA3sO8w8fX&<1yoR;fH+%K%%L;P+uO|_#|dxT#vAJR-a zX0^xoXXtI4ni_g%t(xmkiD(+NC$07u{)$A_s7nO zSF_+et};%ErfICfeG!cc^BQ|Z&0~o_+Q_NVG>zpRAVFCa76(#h0Kf zolQ^LFV;>EP$<1CXjiS4!J8iaFY%fcGa`1e)8smuN}UN!XT_`d^`>49U77i%v!b+{ zXzIEwXgVuOyKUoUMblYP+8=2Ac;6o}8%>{w&I*?u!+D6;5FgnDbD$Zk{b{wFXbY_N zH<|`>F0_RRx73R zuU=BBPazw*G+H;S6}DO#v>sL~Vl_5TTs^H;)M`O!y{%TvYUR-SqiJv#w_17pdh;&z z=T4^;DGeXdCT(9v< z(^Fb)8@DEYO;2fc(KOy_>Hdr6r^Nb*DohCeMQEBE@a_@|-i(+rJ6R~>$-cA8fD z=Bygm#jn~)(>G_Or+dSyoHTv=m0dmjrw9yC|A!;uxa#xECX!IN(SjPty1u}1wbI*8f9AkDYOUCskjMD- z(FKMK+we;(r3PbPG$r^t{ss6o$Oho5#%=L0wAvtC4qf5=(%P?q7iG0}_;oI+qW&Lj z#rBBmPYtpmxJs}Ce)Xp_@YL#Wps7El=?kaq*iZD%91X_NR%6T2J99J`$D-l5I`d02 zN19Ik-s`_E9BAs)!i}?$Bk-#*(#Bh@D}EJ5nrfuNbi=R0NSk8qy5m>NXn;<$S|on8 zj5IAwIIbT2icvxuwKJ{Q6Tg~9n%*IfA$|?0MOGV#Uo}u4F2+^HgYc`y z>cS;fi^8vTq%Fh6aSi5|Dy(i@?$zl3Asnd25?5HmH}Px0sSj78X}}G|uT0c6t8ta_ zF#O6y+FD#3*KmF*6LnXD)uQn$4{7gNZ3KSr^`Dx29ikE(iC=GARr7AJhNJM`p}Ev- z8?81Pzgj_s-(=&Cv6?d5VzuzgS|eSq0=l)vCvEki<;%TRphAHmy+=k4>`~I3*qbV= zsrp-rW-)qy;5t|j8(<@Bg3Yi6^q#>4m;-ZR9%wh$zyi>Q?NAs7!yy_*z(^PcqoEF^ zs0*P`586`aaA@a86Swy>8E>TMlko|{Q#A&y&SRAmZ=@(vBR&2MkO?w_HdVEWnhml; zPRIqhArAzA_EYo0OXk{*6h%wzCrNFS9t3TT9)iPg1ipX`un{)FW)plfMbW~$@J^#O zr^8GrOQC|GJXC;SsA%GDrU=OM8s1tE0>z;O6oc$$H^DJ_cjIzc3J)mLBXE=A0^EhL z2=t;zy-ZRsoNUdp-b^_b^hV5Bh=Xx39<(E>9nc^s2jw9cDnez@u4e-pxDhngHd_-s z8qGS>Y3bA&t}|0CRg8nz2(Jktpv}ihP#LN~Rj3Blp$3$LqEHNqLkV~lNYci|prGcyss1Z`sW|C(RNU=O6A+1KH&hgtaJVK(TSOM1}Pq*S19LArp{jpaF@ zd%p|d9nd`;eJ#_?h#%l{I0T2`hzYrqqH*X!ylvohXbbJ21H1v9pfhxV2X>m+Z>9`;(^8Yfkkl)RFi{fwn$-LNCznrgk&+ zU4AAjT5bGwpguGNy>wPPmX}~4V?n#sQ5wD4veb^Wb|i;EG-%gxBxrM3yNzQZ7PQMa z9<+%#5wuA-1*XC@XbLT$CA5Mz@H&KpF1K_kr7I#`?X0H)8}yLKYCP}3X4nGT-~;#& zcECsQG362 z(>=4H82*^1{Avc;i~EVbxdPg6`vvsU<{v=&YTaQb%z`;!U;!+GcVGZ$8*DHPfj40& z41?D}J6hVoY6iL-Zw$@!C7~rAT|2jhaA*e?Xx>ZkBj_ym6X=x%bwC?M+Ag07vp}0f z+7#*q5%30dgk#kD1e}CZa0&LnJ~%;ZF2kL#{x^93M0gBmL3=fAU=2;T782k+(2XA5 z*wKBQzd(1KF2fbj%>&&mxCM9Mceo4p;66NnhwvEmeP4SuPa#Yv0PV9ZhZV32-UZ!} z)H}61g04iht+4~vrefgWE`#N;0#<@{BqqUR&_CoI0V81)i~(&#w1Q>yyLPre1npeM zEJc_Bx)kb9rUOBDqvxRMX8t@_2>Mc>ZyKFJ-$FWqb}_YUc@3_^GU6=<-Jj0@86gv7 zhAfa3bgTVKY_&)Gxj+5?6U~2;=3b7wg{IsFy8pTf^yNN~j8cFHQi31cq9(f4{X6^t z_uv6Mh7BY<51Uxf&E^sm{#9_pyBx2D1b7dorU_tC!LyaXZSVnX2i+{*VIJM*^sa6D zk6|Y*|1s==eXt*N+w~xP4u@bHtRY`r8|qq6cUJX9N4u$a;Rf7p9TfIo(jJia!X-1NSOi6`>N8g$p$BMfe0h zg?;cD=xLHIuobq!`=I+_(?R#Zf`R*9-rHQdt)<&oH9^gu1kZ?qwate+&*mS&sMPUIg8i`Vp?c&+sjrf$!jZI19S_q`OVsAu^Sz z`Z&c)F$3@qhS#Aj)P_1x7wSU^2!hm*2Hfy~MmYoD!3j79$KeauLAY+8RKc&?s=BAE z8_&AYtb6mi7q6#M_5iybd?`fGR>&~u4&K`xxPN1ihQ`PNxgi6jq7tbg4cvwM@Bnn{ zL$^9~XG3=~u7mDW`~tsGkQ?w8g_;19U^qm>FS;psn!tzf2p+>((3Y3J2InQyJdhDG z!5<`;omS5Q`bw;?wl}e#Ok!go0Gn)(8Ez9c1#KaIJhYAo3ddRR6RE8>06)KQ< z8MP>+Qb9=1h5H-s4Y&y_pc+(%8c-8zK^>?MO`r^vhgaba>GFtPjCaSVG=Zh<`4#Lp*=Wh>dx2&_)Pb8 z^o-UjGI$r(Kt2p#h60cSoED5FYzXv+0q_Rs(X0E!*P~VEL61{i1U)VF4d}59JrOm9 zN?m~AFbZ_6{ouyr?`jAgNT@%x`G#@P2Ukxx$zK%rGVZr<2Bby65zxa(CqOrf^l*_L zCJKlCpyz;AGltf{2G|7k7;DX;1%!bf&xvWxuQqUzn(9_*P0(#mr`EmE`$9kH2HoKj zO&5r(ZV>~)vHz9Y{s!NJo?iJ8F2i@=w1~oVJcazdO`%$8+v6{Ak-3grP;)(8avgpJ zJyf!kOs8Pe1OG`l1-iGRdpV9f41Y9?fKj01;gDR@;}xBtLmJxOiKxdWT0rs|Z>HJw zNQ54N(9L7rEY{6o-3xZ&MNy!^f=q^j!B!6`bihvyT}uf&MZpun*j5{WyPa0tq5G;k zLH#cVftpm!qy2m})l(ADwo3pB`a?@vM&sfJg}n*4LEG~8;UTOe@dQ`{Q_1{mv<1Xl z2)f}k5#9#fXo{J_FWq$<2jju1&2A#?0jHM#mVn|raVk@5#~(vn$KMlwU+9-iQwy-Q z9^-n4NZKaXhJrQ_G@6r7$LISmdH;Td?JoEXoPzeGK)s+J41glAidN8`@oLaMvG#xq zzyaNGD1j$89Hm6R+HN>Wmz;u+Y}Z_+8}gG-26&mKe+9I6tG(K%@F(bwr|xj-2IPF0 z0SC~-N&7`%6$z`PW-0>OXVn&JB4~^BYfvj_L2_yqLqd+%5|E}anDieIG01Wjv=BVYp41IXtU=_I0kwsU>+=h znJ^2q$I}b6htnQ9KpUtHX=$}|kd4*|f#fZr?HH#89QRl9jd`2WXusuK4t@qjI*RMm z;Q#HQbLPC`{!>%ZR7Ia_(U^ZuyE1%!oputLK>`2UXm;#Q(+W%A4QLFGo{H8;4e7xH z+I-L$xtW^&*T%tZxC6Yx%-aHg;{RWR=l@cm|JjP_|L51_SdK(M~bsB$iP#QTRsR9e@ZF3Rg7 zIhXyDHLt^Q%s+x6&;tKNmS0+W$PAf4u@2xK1>GlD2Wwyj=vG=N=+>!jp)P_kFd8DE z8x(;8kRS3vAo+VQ#j|mc74m{E&vQa<$OYLU2S{_=m+%*cSD+xg427TxRDqhHorJDX z9jZYDbcRmQ2+Bew^7sCwK?huwzBFjtL0b^Yq%PEf5GV(wpd`EsC7?JIgQ6gNWvYbB zfYPc3PJv#-?-Zsg{z?$z7&@6M6YYH{Qe{vkGOP&t2BQROgSYg!PJ9*EseMEIj-4`6 zZ5u#6aPm>5>Z|`{EKz|+kR zf-~)vmXn#{$<|3z=?NVl0B?S3Vr94w6sSmhVJ9R{NG0C|AAy?qWB3&IfTQiU`X^SC zjr>kJa`%H%QRNwbxD6-aH#iH4a22k=HTC~Dcy7TN_!+)} zpWrgwg!Awv`~WxLG<*%e!a2AOzreTfJzRwE-~yZi*((pFt2AV%a24c?`ripufHKmt zGEju%k=5VQgltqWCtUU_jKY+TYO2B{Ph0VwG34km@@P;v2|0-<0VVc)4V1WQrpy&r zE#|~gt0`P9r;4bSKf)z&GL);Px5qKw(W?Znfl~-&>?9^*)x=3qO|8i4L#MV1a|-38 z;S?%)tIDqmIkw*ZcOs|>okX2}QcctnDuh!2_1iYs3K~?&6HK0#Q#iH4^IfHUyakNG zY;UdRr5 zbWo2JW&u6-kOTBoUv9_)rJy9}Y0X#QWe9+RdM@oHJb{o83P65)tOqBGKp}f3K7r+IzeZ6i8OlP zMnZS!2ECxa`oABZfuLv5Bo2Zo7z)E67Br~TQe$8gjD!&o4LM*mj0Go5+Bld1Z^1-( z8z#YAm<{nTP5rOZPlYKk6K244m<7{7+8j_Jo#P4A$Z%X4SFJH0q)mjy_?N*_h~-#) zo!ovk$FhGH)~Hsh)<`>--x>zHo+Fy3ZIhT`?$xfe-G|X*oD3w_XE%s*bdwe zL9WKtQTPHrBJ2?ECEU+(W0b%_aQf*p{0HD;_z1Kf?8n^)vfTx$wfgiE{Bn0E(-am9 z(iKO?vfB%vCbP3~V*W`?89A9Kk|HP(MN;jS;i^dwg9@UsBi3~)kvxvlOCyZcVD4t2+cknHI183lSI17wY@94dVdjT{Set`3!@!;?yer5VA?j5)dH{cfh z1~=gv`~sR)SLKqwH-ZcuqwDycVFvl;~u~EW`^9UZo1Go?O;4b_De}cw|)``FE z@nhT=N7R9b)h-42gCDp-_X?g8mKs+BOeB8F5?SX24yAn-w<;$X(Cz*O15hbK~Z+C@eb^ z;5a`ht$etFP!<16xOx;Nr#}lFt{y|0q(@G)xm6lkgKDSemEth!O@tUwO&g%qhk8&R zibFXFg2M0}_GjQ*_y+W>S`*OoYp=je=nh?>8#II>P)Hd_bc6=@>q22D0d+uzwLx>g zB<`!Au+9{$7;aHWMOblM&3U=fWv`i23V&$`ftpYQs(`jAW3*RU2DFE%z04pe3);)n zo@Pa;23o_Yn>mb|)Isr;R z3BG~rl)fYW&Y(hc0jJAU0r};s*6L2DOBGi&?g4S2?sO{L3xA~gzYr**5^*A^c@)Vp zcAC@)?@8DJTEV&W(?zW=|Mo%h>&IB^G-fWLCr@AbD(#p){OS#=)o2(BL%>;5qws4v zK1zZ5;n$$+YhCa1OxPf6-#?i?5dX*6>U=Q(zv9bYX*u!m$9V4#=!~U=HJAq5MC9KC za^FOAj&%mx4NB-^_yiQ+DTGdDvR9_EQK5!`G96{Lk+>ruTKzv9PaJ{KxGM1&T$NfU zqp|p%5<3~HwX`NAZ_bHm>aKC1mW%{-*;_CkCcspf0&l}4@|!GI{h+g$gh@7F2JUp2 z29B}996L>)^DqlE9?pT{Z^PXR3!xy#3vdnSlpc>;8m6Pq$DIpvAZ8xFW`mkXf?Ovs z8^?J#-h#UdHp08G0oKDxSPaWyDJ+5|@DAuqs4%%=8U7WpP8uY@8qI$txEhp!{A*z< z5vt>EhE1Tg-MKPy#=}|k58-_%1=~Sg_yL3xzXw@PQll(nmAwKehJFBFvqWe3i}(!zruC63YS5x`3qcv zi%<=IfS3#XO5P_|I950O1V4fz{|wha-Es@}Cg>tk*AAKqn!0M0+URN#&Gplq1=aLA z-A;nC_`kwcm;41s@F(h#!)$oQKzGOjnyZgNkBUCTy$5%o4H?|U{R4i72XG&hkmBZo zM;uSaRiT7oDxim+6kgK0ilaXhaN-ByFPrSR41QfFl*Uy7l%{OUgYqZ`m394B5l=AaZx3|s zUkO*#0!63>dK&9BaGuU`GIbKwvFueS`JHgNDr7@w0QDicO{o|wsI*RE&(}|qq| zEz$e&e+qkGH+%xSU1C5Qwu7-{AzwReS7?BwHVbtd4Ll^%_YB6Fg3Yqr&F+FuY}jy#NsEHY~}bYhIzQFksI_h?-hj$|m#M)YQh;>Xqy!I)q@ZqGX)2`Rs8aH)CDQ82Yc-KFl2HawBAIYAf-+ZF zR{U9PnBzKKG<{Q+?!xw|uK#81T)WT3pf-U{gb@5Sp%zqxV9?Y2 zO6WD*8lb<{tp*CK0+pb$J+6u?8-*#IQ#YN|G~=Nax^pwKDSqd? z{cq>^hS)fZkj@>>8L<)iYK|Kx3)iZu^FWMNHw8Ko70?7jEsrwLnMws}juwaOTx2xk zxG3ljsMBq-3*)#245o#yP#N8talWuP*BGjR_51!WrM}6eCPEt`rov@lcvrR8Io9f? z1Qfyf)>8}3jZHhk^>+yh*OyM`i>UtWP+imow=?L5bXVL6IEP*Y#=$hr|5iktN`O{D zJ)u7ZCcy-F3kJbJ7yx~sH}r%a5D8O=*B!T))hbf3{`mVsKNts5FdBx!V9*T>E$u_p z|N09IWqtr*6#ii_5{APFh_-&Yil{i=$hc!*EW|<_jE5nXiMVfr3avs-PUcrSGdPZ! z&M%#SbRLi>wB4>IdzY|Puo4Wc0O`5{)(LAF$Fm_G7J?y6Cz$=Xy6RnE!xeWv%mbZ_ zbX#9(%+>SDZ8?}jfODhhi6V2n6c)h}SZrPC4sD3Hoa1Sr4AqS*an+LAKPZ4-X{x{~ z;CfJn+QNI*9i{$H;9xbZg*DKW2r^m+x?ABGr^ThzT(QpNw=JuQ4zm{L^uT};RGCqV{jB26!(w?t7Ay!yw8iz0hZp%H+|S*qd}(s7;<{==FyKXB9V&Qw2GpfaIkB6W_FSb5{iDnHxr0gv zl`UPC#loDIT~AY{BF>v8OE6BXc{SM6)bt4RWKC1KbWo+zLA0IOsGyHbTo}#)bBUvX z;X^0@pHwLtj@db*`q9kp5L+%c^)j;$1uKs(Rvhm7066Cy%*X)sq(~Q#DT> zzc13v{~W7Y)jWaj89O>w^YnG|zN}j{X~A$BM*ZIZvsGhj{%|IYHYrCBR^kH3{9PS` zt{ABCj@11A*q%v?KkznMS&bZCIaPyNMVm{tanhM3ui=b0F^Iu4h?1UI0bTxxf2%{z z7B*G|RuCJ~r$d?cyT3|NNJD`f>9#fII8g((S%bx+OM0#xcyP%(R)S@*$GFMD?`S#` z_?joT-*@TE-dec7q%$oz4t_wyEachj`(cj<4BAsd5gCi5oSLF!BjkLYkaOq59>3@3 zE?YXdG=<@{DwMjZZ47r;v-}8Ps#4< zxvuTj#%=j|W@Xiy*-5RxVAQJ9%ka*tPDdl|dOMwNphe8Sv?=qro0t`TIBj@gDh29f z3f9BvYuxT6(Pd87Ma*F0J` zDr*PXRI{791pG@2l&|1=)7(*IyP9sSs7u{5CU$6sCR);`Iu zxw(Kra3ls=;xpu`du{2aVTY0oM%j?{^?G+4T(jsqNg?s3R728Ui$N};Ca%bw@3Ugp znkN|y;pKwfh8We*)70-!A@fB;PdUHSh0GINUe*}Yh|prDaU)j53T9uSl-bRkMxOiu zlM8$Q{33SOmp^w+81li}EU}z$v=$h1TyfHw#J!&E=Fdi+{x)Jt?}=cDX&UV*of6aX zE^qSL&C$l5Do)~gns{3Addr!oJULUaUS~0HHzDWgW|y37=2jDuUSiTTWl8Za(0SZ5 zOjJ|Ecg$2dz0B&Sp7Irkm-6-Kcaw@dd9A~wG~VKQPlrb4q@?OX0|A?k;bEc*>$YT1pBP7T~y@_K_cFj#tTaLP$ zON#Yu8a92_zTTefDJyABvPn%fV_IOo(j=-JyUbRO{7#iKgIalV2mVMisBtznyHo1h zmtVhQPn^WQS8je7i%2>X)stR*8qTUv#FP)C8~(XoSggwiTc~HMVl(rzY1pu5o4}UN zhS?gvs7`(lDwx=|6vf8yRm7C{W+qb`hTI0zaX0CCkDgD~mx=kT4ITANQJ*X0KZSdyRA%n$#Ct|^ z>h!{X{%<)v*TQzVJQKr7+jjg5!=4=*$@)5=NO|8X{ZjVDw@aO!I5ufu*b4ZP4Om^( zXICY3cH;Q>1&fpHUO0rGEyc4V!WJ}HDV%}-!dSkcp2|DaUpz#7!_U;};OQ0cW;Nep zJNxq)d5?B1{x0Rz@(ibdqmX< zVjRvre>Zq3S-1Jy~YFS8i$lGf5UJOpz6ibHdN0$XM>FG+?9!Q&G6Mw>Nh@DhI@}sCmCchiG#g8pexm)WzO=j5F2rm9x?m?1JMRayl;`?Zc6GMa!Pj+kYV@c`Tnf%bIBs$%149y`wn0 ziRs4@X_J3Zp5}HJ@A~e|-`d#}5==-hGJZBzvShWq%&Df0x-efEnSmvafT@xJXJ`%q)o{_h&0`l}t9S^hHy>Y5VWlNnyLe_P^5#{}d$ooYCsJxEfz%{=GcU zHgxhbJUe)7vM*{G-!+t-XugvFkH&f?(`2?m-97odL*<{^{9g-hv$X>`@ITim?mKuF zj%SDXvqSrt32Q5CN02S?f3{D+m{9Itvf91V>y;*@uV#MVdjj)bxJ)zg3_ibep=QHC zF5$f=vTW77=S9~k*2t{H`uyiRZ$CLZ<&@S)U&xD2aNfH@oZw0gVtIYh3Cb`>$_T<#M$n8wwEl!+FD#?pZdA>L-3{M9A%PG%i@uE|nFC@V< zj-qrgI_3Ecyr(?1lTH#DIN9j?QmVpdo6M~iG&`wuFFF_c5~yj8lfw(og+7B9oeO;- zoC^a7|I4}1XW=~;I=z^Qi&ou>{Qc0Gj2qLwy(Ou1|2Y7i{^d5z;D0$u`f~7|B%l9^ z;k&pC{Ljwv-cRGQ;Mps!fXlX5&vbwDM)oY<=xdiPfW4Zt-#7mA+k{E|X7UAHUxZ#T zT&QZnv0q%a z4)^5C{a?Rl{U5HDeYqF#_TImDP<7q`&T5d9xAzO@Gri$_XYwvR_Pd>}sQ1fy`G6}8 zeRo;&)JW@BG1Z8)bZgntm38^+XBJ1(Q&}5%|4%~f*qQGi%bzjt%XT&59_P#EBnIws z=2|r0rfQpfBXF9SFr0w)#L`W&-i`a_C^LIy=u7j2Hx74+Ym)YQ zcK2&FbT2cwY@E3`3c`!bce1AQ#`vFIFf?B z%8Sh@QF*g_Bv<{_O}bGWg_@djnwue`5F40%qiDiUTbOgBn53RC-<^*X;pJK%Pr2@( zcZ_>i-nJ&wXjXs|80bdgZ*LYGS!HVBrWkPNL#_2aA*xTBr}4|Wym`q@i1*$@S=Z$- z(`hu9Lbt1((4?sv}Cd$4Q}$yD^+ zhb>@A$^2ClH1;2J&g!EO1K(=xi{%=(C*g3t!Jj7;Yes9cWel15l7BAmfUk+CwQ$40 zpbz@p?6#D6oYGVso6Q*0cr2~uy-{91V1~^mq;t*sDb_E(m1OR#L|_d{&wb?BW@YxT z%=5*8?6&lz_jPOI7sDy5vN<2h)kBDB9z!h}n=JKG<_T!ZA2BJ~o|e52_&xb*mbduY z32?n`mdLKF>5QFwfJxNRDD!I!eb>@diNz^w-j1b+tIe)hS|X;S?|aX+5eLT~EM8rA zIcx{b>u7GrdU98M4~v({EFv`9og+JPPV;lifbTM{qlD;NMye98#O677`)jSezL0CY z4?K?Xk*1R`?y!!mAIyo%Hr9lrL8ilb3kMWU8{3DNhwlHczA+SRwzNJ4b;oo}qM=KMHMT=qpaYWZeYH-;A} z`I?`5Mkh0Pyr;F_s!rzcc+UrZ8#Z!yUBbTSLx@+=BCKz%g-mKBaI`RatouG#;& z(G_BvPGBUzVEcuQ3!Ne3yZCzJt*6_U{+T<+09zW$`A!!zHe1Tv?l7~gVal8-D)aQI zIZ0yNpu0AK`gS(?CUU27QH1F?kug`-L}kXTBAc1sh6wQM?n^oK4ly{S2gxs@A(j3lvQ?Aa=H#teQP18xf_i6W+d9mZD$ zGhKGIvC|6Pd}HG98{g*9786#o<1RS{?%w7sj^FV}vwRNqOlKmDCwl?!IC$8@SAn-Z zvx}XrcJ{2dnBFS7O`XZKQ93hxvZrZ4_1?a_1W{|wyM`6b(+fL0l4_U>lgXoqc_j1J zrqmRAYgHd#?GwY-ooaY@*%j}O5ZiBTF!uFbEVldfrstg>ZWJRStveL<_r7NI6i<`D z(fxewvUK9EIthPgTti&7X*qV&`{Ke3%PgGg zDKC=~I`l4>-1?pB$?vylpb4DDm|H#2RGj8%;&#zQqO?PFB*E@#B-WYXRy$eHW_A;_@$v{i=o!HhMG5C zWir@1=L2VY`ukn(Zhn|aD|ut&2{glfr_O^%uWujQxk(f?*1V=BOZu9Uvq;3(N4edD zOy^moeKXo@dDoM}%$()P=l3YuY{Dk+X0)&WDmVJ#X1T?Aqf_|CHFJUv_;D8fM+fAL zr{PEt42@obEOO`II>Q5=hCzBwEf zGjShrbDjd0Hem=#qo0O&B@?s2lheaV|JgxrVh(X9qPA)JIkB6W8^j6dFvd5{YNkK? z)`Jgb_4n4=yUz7C1?Q5eb2I)4hMLkd&+n}E-CxCDvCYG>m)h)`M|PBh0z9F$*&fKh zk4@N*=6dq^=35?fdoEX%zPV@e&+~Zv7LGO1^Et;@O+_=y_jz)qV45WLl812ic)hjs z=F`-j*JPSc2Ych?vB@-X4sB`OwoH`HmdTVf6u=wTo0vCx)91&B`4KC%qqiE#i&l1l zQ+{tdd;7}U&Ut)^>Sh%SOL?cg*xz?Aq?uz)0L}~c*`2N6x#LWWg|t~uvjjsw@AiBS zb*fJYoIB1pEbr_KKQwso9oE6ILB6kwK2xzsI(`u2Yd|+$VDLo|6HL6gJTIn*eYs!ePq7lEUk6F3MQ!e0z3#4~+6fw8R z!|$fQ*{iv!eH%NG-DOOT#bjS)qHiX6zW+0{|CZx?Ir1*dr0$*1x|Y(kHp><>D1H7^ z-YM=&Gq=-{=J&fdg*w|bo)4rJ>ssWRQ8nwbbl&YjE&i@rgy6;=ot7cngg18n zniMkFG+o9*ycz@AHa2w6!8O-E?fZ3-!D&KRbz_%zYa6_O*Czj@kd$UIQT z`1Cbl%NZ8`e$8bK{p=N%jquN5h*`Fr(_fd_-aiG4O~^jOj5=`OS6%A!un3iiBScqo zZLfzM`l865fk`2&W}BN7A^3AFUcutvS83DbPxVRRB#Uc=6e8r;el4pX*jlY$Qb-0< zZ3R;-TM6IE{7AFZFYo;#bMB-Cip6x$3hL**KFbsEbe?a?Tl>Y<`kv4J-j5+?4qctJ zG`mSD_}qNo72fpy$G?BlE$cb&$gQCB_Z>p?Y*FI455gaR-8La9B&|ue(z_-vshzTP zD({(SiZSh1GBlPNGh-!nTW5UJt>w>eWj@~^Jx_aZQN%?h4`C6Ki)2@vOq2co<(oAL z;k2%a*u$J%$%RE@lW7&H4>!eEF@$F>Fwv_#SGj_Vc-MO&hvS@%$^~v){`poqP|I!z;#?3%yq$f`?E2F-ud>}SDNGAYZ_N46O}+4 zt}|v@0;|bj40W<=ktRbXzp<^keWD^UiCkQ|?@jQO3mlC_b}V{aJNQPrM@RS;5X2al z$*iR&<9oF3!lkCzd!9vpXP26i>p1>tsmZ(r_vTXb@I89rd7V>N7wmX6X6A>KyuFFv zLWw?HW;US)?p@}q>4~m)qrdMReaiPNQ4smrbj{;+o@Rk*m-`BSbMx+kzq)SK(=72` zk-Ka{&UJ7=b}Z9Vf%iLQ%U*9{kqJuBcLS<`*}9$r^fX7;GrD}29wzq&&VSiW`3;P} z^()Miqm(qgiTj)deDem6C!ozr-<+A$=knc5wR+BBY_R&4<_1|G<38@mR^8Xo!!c8? z>2`iOE_mRqN|@P;!tsQt$d}*8t|t1q z=Oy^gBDS?{F9yDgtkLqcdCCRfe^>QHQt$0dFn{exHafWfFnTM;&nDpK$j%_LgC(F+ zCtrL1GUltgbxudHwWzOAL9}~m(~>}X;-tWP$mZ0RblU+4P@^}*Di_qNJV@yn#r z?IA={v*?fpL-%i7^B^hY)H+j|at6+_Q|j3Kp$&L|)B&w#T@`-x2UWSDAsQiK*dpeNBalpQoOAm6-NxpiSHK`+zg^v(3t_id`SDj6B%vYsIYd zZ;onE<>Fjb)7#-Zv#D7aSZ9lG;Ye9<{>aJY{$R3r7ifmubFs#su>tnpHHeAE`dVUiVvAxlA!3a!ihwm15EYFmioIY% z>?M}(x8=A);mwyna@_6g?Ci9iot<5cB3ibU_8kCIiy$Ivu*SE`3$u=S@jZ+X2IVV< zqW_^?lGf6s{JWNaH03FuRw)GiAr|KpjYtipy$w0Ac<{olYSkRHSTS9MA+nQf<01HR z*%A(UFe|HPKSYyoJ=0FDN|h~Pvd@axPsavpSFGG>FiSgp#EeLg+#SpEmK-mM7{`#5cRYEi}-XV5*# zeOGeY1HI9cwWngM__6g-E*{z2Xz(6rK*2WQm1y_ir(GA`wSxM}t@VR#v>Fg4TOPS} z1iM~tqoO@9Fby?H!#aeWa~O{AyPb{$1{pcBN@t^eeXu>AB8&vh$yDXGNJX zkHY1iN}al$EcRkRfzPfYL}t3p`f4vq8q434ijAcPZWr6fl)ZfWC`y3QPwoN9EnVX; z%7y$4!_aT(*rVUuLBp}fmOti*(j&irD?QSZeWu2-?5S}lfvK5nyJ=D;h5~uZGU28$ z-JDFY&7T(LVVmUVg@8v?En~~0+lQDWc9&4vtR}6S(4=)8d4Vct8Q|QIXqiPTQRJ+n zdV;lU{LV$KTK5_&XCia7oPQ|r)2h1BeFpdDPXTxGaBS|zrC9@wE|fD*E4Id3>a-tR zGG#qB-;RbVE3QjgnW89HGeh?Xx0$%&RkY8_MTkkDnE_1yqE!qq^oM6d{6r|TT$M&nM?kQU5Jev`C>0L3 zk04|8ER%|kAd)xRCnoOq@?Q7NsuXiRaV|3*T3A3D;pw{V7uVXpYLx|kVH;C7T6i4d z3B*?`d`$>x7Ik*i+qOniY)!+CV)OAO0GPM_*|yrq>NCFI2>^s;jHwA|u|Z40^-JCn z&wW^?lW72KwH2kKYv4oxu*|fj_Mun6PhHr4o|!ppbUs>`&wRDv(zI^_f@h*d9#p*A zM;6DxQk(rEsPaBL`^CgcXDlU%lP{;H8@1YB z(vTcr=tVPt!PLHW!+?!Vd2-}~p-aqPV^^EVtQEYUM2|{mBD_xPiyu0;sm6ktHgj0>(k&>;R*6Q4a0tNf?A)3^$8$-Tlhdm z+Rhote||n}CX(Jv7*KgLblAiIz3AF$oFeu|a)cR^_UOXO1=F{rO8tQo97o={7~q$a z)IJxh7QYQ*uR+>XTnIr4^Tu4t&V{CjeIO4n>U-F6c;547+E!9)Fuc$>J7@eE2p}r}nOHbv21A5wrk(+f z2Xko!#u2*{t!g5j#IL$Cj7IwRGEBp>l7S-ORTkg`iMgGkie?**6m{8ToRb-?fk#8w9FC|XHYdEoV@8+h0uPcVicYGqTp^nHy9Jq~X;#{2p) zhjcV=$yKng6RGl%7>0M_iz_?ANX8j)^NX@H#`P+ z%jjB|PdOJb8B=bs`zN}55cp~01T%xjN3uoC9TlYm^5J5dT@(g2dhn+0^RBlX#qtH5 z{buDz1|xT((-;F+WwyR%73ldI7s!JBM8OwP&nQA2T7D6SPEdrs7s2VjWQxZ-Y^-m; zh|Qh3@8Rc{)#%YhAakY4mv~a2g*-I;5_mm^=3K&5W)uh=S`?A#tjVg6bB9E>9%3p# z6wtm);K0uXlz$0pKE8J^;IY=20(dAMUpdmj0-&Eo1qGS}HPTeAFTeq4um9_2Y&YCv>- zvfM1RlSW=QYL}D&#a~5SdGdzHcus5`f23%BcNc&mE68N<i94(A%VTtuxG5TuxnY?Aw51u3^rxGzcI1q+25Wx~}5=wtL6+9c09`_7<%Mrht=x za0Mpaj-ST%NUzLPRZiqNTG#}(&HdgveZ;;c#ujJ#@IYhd!U&4EjdLsjnO$`M_V*Dx z-Wvy)NVTss*M6ItUWZdT0YEnZZr{7Kp84*HCX_tCO~U~ZQ2&mgwb*9uwLs-M(lQ20 zI-tcJeNQ~JIuzAu;do=q7)r+=folQ47}j&4U&}hlYr7k%I4N6t#IGHYtyUy`Oipj^ zki`wK(ydTrx1T#lYVY~RvuHyypgo1%04u+w|J;DSEiI&ZfDe2Q_{tcoFlDyoxpT^J zwdxjrvBEFY@5=b{hrSc{uUw5{?eX}9dBcTw=@J_&^`3BD1z+EKb@i`p4j2oI3^NNG z>V1nHma?j#TGZ$^Of>W+Ow@*w3t^&TZz7UeeV;bmgo=-&D>o5xE`BH`ZT~J}L1ERd zf}^~uXdhaFFl>v4UB2@O-2PNd3Cksh3BRXtbSx75Y!KD%mzTrmt~6~28SIo86xh*% zTUZtX$of8h;slmzQO|rt@1LOQ5&1lT0Si(^-vn@N>1`f&FobmbHt2s|NcuaVKbAV) z0sUp19J4$z)Vho#Fh~rXL2q|9blDmXYgPdRPR~f@$hQaQ*57 zaJ>vPlD{0AorWz79LSH(78=Pk?N_ekP?`00*)mnNqsNa*xTHS#hB6*;(Q>sA2-QDH zf&UA=CZy=f_9aXsO_4}Wa`#f29il~j?kz<W zXxgcKc}j+sA+GZK$d*s1X<)9}K!aqxDWqihAr&<*#*%4Zyu@ijbO{nuBP>y1=0XH7 z*j@$ZY@$9TKwQECvkn(D+4GP|Paj-M(LNkH�<#bmei0ei&@Slw=d4r0X!Djr)R4 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 { ] satisfies Partial[]; for (const config of configs) { - const task = await automate.prepareBatchExecTask( - config, - {}, - "0x48c18844530c96AaCf24568fa7F912846aAc12B9", - ); + const { tx } = await automate.prepareBatchExecTask(config, {}, DEVOPS_SAFE); console.log(config.name); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data; - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-magicape-task.ts b/scripts/create-magicape-task.ts index fe60dfa..b89ec84 100644 --- a/scripts/create-magicape-task.ts +++ b/scripts/create-magicape-task.ts @@ -1,5 +1,8 @@ -import { AutomateSDK } from "@gelatonetwork/automate-sdk"; +import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; + +const TEN_MINUTES_MILLIS = 10 * 60 * 1000; const { ethers, w3f } = hre; @@ -18,20 +21,24 @@ const main = async () => { { console.log("Creating Task"); - const task = await automate.createBatchExecTask({ - name: "MagicAPE", - web3FunctionHash: cid, - web3FunctionArgs: { - execAddress: "0x598330D0F504297f53799e37CfF80ed564eB3525", - intervalInSeconds: 604800, + const { tx } = await automate.prepareBatchExecTask( + { + name: "MagicAPE", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: TEN_MINUTES_MILLIS, + }, + web3FunctionArgs: { + execAddress: "0x598330D0F504297f53799e37CfF80ed564eB3525", + intervalInSeconds: 604800, + }, }, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-magiccurvelp-task.ts b/scripts/create-magiccurvelp-task.ts index edac30d..6a87d81 100644 --- a/scripts/create-magiccurvelp-task.ts +++ b/scripts/create-magiccurvelp-task.ts @@ -1,5 +1,8 @@ -import { AutomateSDK } from "@gelatonetwork/automate-sdk"; +import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; + +const TEN_MINUTES_MILLIS = 10 * 60 * 1000; const { ethers, w3f } = hre; @@ -18,25 +21,30 @@ const main = async () => { { console.log("Creating Kava MagicCurveLP MIM/USDT Task"); - const task = await automate.createBatchExecTask({ - name: "", - web3FunctionHash: cid, - web3FunctionArgs: { - execAddress: "", - vaultAddress: "", - swapRewardToTokenAddress: "0x919c1c267bc06a7039e03fcc2ef738525769109c", // USDT - curveLensAddress: "0x5552b631e2ad801faa129aacf4b701071cc9d1f7", - minRequiredLpAmount: "100000000000000000000", // 100 lp min - intervalInSeconds: 86400, - swapRewardsSlippageBips: 100, // wKAVA -> USDT 1% slippage + const { tx } = await automate.prepareBatchExecTask( + { + name: "", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: TEN_MINUTES_MILLIS, + }, + web3FunctionArgs: { + execAddress: "", + vaultAddress: "", + swapRewardToTokenAddress: + "0x919c1c267bc06a7039e03fcc2ef738525769109c", // USDT + curveLensAddress: "0x5552b631e2ad801faa129aacf4b701071cc9d1f7", + minRequiredLpAmount: "100000000000000000000", // 100 lp min + intervalInSeconds: 86400, + swapRewardsSlippageBips: 100, // wKAVA -> USDT 1% slippage + }, }, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-magicglp-task.ts b/scripts/create-magicglp-task.ts index 09829f8..d430a34 100644 --- a/scripts/create-magicglp-task.ts +++ b/scripts/create-magicglp-task.ts @@ -1,5 +1,8 @@ -import { AutomateSDK } from "@gelatonetwork/automate-sdk"; +import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; + +const ONE_MINUTE_MILLIS = 60 * 1000; const { ethers, w3f } = hre; @@ -18,54 +21,62 @@ const main = async () => { { console.log("Creating Arbitrum Task"); - const task = await automate.createBatchExecTask({ - name: "Arbitrum: MagicGLP", - web3FunctionHash: cid, - web3FunctionArgs: { - execAddress: "0xc99A4863173Ef52CCB7EA05440da0e37bA39c139", - lensAddress: "0xe121904194eb69e5b589b58edcbc5b74069787c3", - rewardToken: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", - rewardTokenChainlinkAddress: - "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", - magicGlpOracleAddress: "0x4ED0935ecC03D7FcEfb059e279BCD910a02F284C", - maxApyInBips: 10000, - mintGlpSlippageInBips: 100, - intervalInSeconds: 3600, + const { tx } = await automate.prepareBatchExecTask( + { + name: "Arbitrum: MagicGLP", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: { + execAddress: "0xc99A4863173Ef52CCB7EA05440da0e37bA39c139", + lensAddress: "0xe121904194eb69e5b589b58edcbc5b74069787c3", + rewardToken: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + rewardTokenChainlinkAddress: + "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", + magicGlpOracleAddress: "0x4ED0935ecC03D7FcEfb059e279BCD910a02F284C", + maxApyInBips: 10000, + mintGlpSlippageInBips: 100, + intervalInSeconds: 3600, + }, }, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } { console.log("Creating Avalanche Task"); - const task = await automate.createBatchExecTask({ - name: "Avalanche: MagicGLP", - web3FunctionHash: cid, - web3FunctionArgs: { - execAddress: "0x05b3b96dF07B4630373aE7506e51777b547335b0", - lensAddress: "0x1589dEFC3Abb8ac5D0e86c19Fb940874Ea788c69", - rewardToken: "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", - rewardTokenChainlinkAddress: - "0x0A77230d17318075983913bC2145DB16C7366156", - magicGlpOracleAddress: "0x3Cc89EA432c36c8F96731765997722192202459D", - maxApyInBips: 10000, - mintGlpSlippageInBips: 100, - intervalInSeconds: 604800, + const { tx } = await automate.prepareBatchExecTask( + { + name: "Avalanche: MagicGLP", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: { + execAddress: "0x05b3b96dF07B4630373aE7506e51777b547335b0", + lensAddress: "0x1589dEFC3Abb8ac5D0e86c19Fb940874Ea788c69", + rewardToken: "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", + rewardTokenChainlinkAddress: + "0x0A77230d17318075983913bC2145DB16C7366156", + magicGlpOracleAddress: "0x3Cc89EA432c36c8F96731765997722192202459D", + maxApyInBips: 10000, + mintGlpSlippageInBips: 100, + intervalInSeconds: 604800, + }, }, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-magiclvl-task.ts b/scripts/create-magiclvl-task.ts index a143690..e9a7943 100644 --- a/scripts/create-magiclvl-task.ts +++ b/scripts/create-magiclvl-task.ts @@ -1,5 +1,8 @@ -import { AutomateSDK } from "@gelatonetwork/automate-sdk"; +import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; + +const ONE_MINUTE_MILLIS = 60 * 1000; const { ethers, w3f } = hre; @@ -32,22 +35,26 @@ const main = async () => { ]; for (const config of configs) { - const task = await automate.createBatchExecTask({ - name: config.name, - web3FunctionHash: cid, - web3FunctionArgs: { - vaultOracle: config.vaultOracle, - maxApyInBips: 5000, - intervalInSeconds: 86400, + const { tx } = await automate.prepareBatchExecTask( + { + name: config.name, + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: { + vaultOracle: config.vaultOracle, + maxApyInBips: 5000, + intervalInSeconds: 86400, + }, }, - }); - console.log(config.name); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(config.name); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-negative-interests-task.ts b/scripts/create-negative-interests-task.ts index 01cf09d..fe677ca 100644 --- a/scripts/create-negative-interests-task.ts +++ b/scripts/create-negative-interests-task.ts @@ -1,5 +1,8 @@ -import { AutomateSDK } from "@gelatonetwork/automate-sdk"; +import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; + +const ONE_MINUTE_MILLIS = 60 * 1000; const { ethers, w3f } = hre; @@ -67,17 +70,21 @@ const main = async () => { for (const config of configs) { console.log(`Creating ${config.name} Task`); - const task = await automate.createBatchExecTask({ - name: config.name, - web3FunctionHash: cid, - web3FunctionArgs: config.web3FunctionArgs, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + const { tx } = await automate.prepareBatchExecTask( + { + name: config.name, + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: config.web3FunctionArgs, + }, + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-process-locks-task.ts b/scripts/create-process-locks-task.ts index b1c86e9..1c887a9 100644 --- a/scripts/create-process-locks-task.ts +++ b/scripts/create-process-locks-task.ts @@ -4,6 +4,7 @@ import { TriggerType, } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; const { ethers, w3f } = hre; @@ -55,13 +56,13 @@ const main = async () => { for (const deployment of deployments) { console.log(`Preparing ${deployment.name}...`); - const task = await automate.prepareBatchExecTask( + const { tx } = await automate.prepareBatchExecTask( deployment, {}, - "0x48c18844530c96AaCf24568fa7F912846aAc12B9", + DEVOPS_SAFE, ); - console.log(`to: ${task.tx.to}`); - console.log(task.tx.data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-reward-distributor-task.ts b/scripts/create-reward-distributor-task.ts index 223ce51..2adb932 100644 --- a/scripts/create-reward-distributor-task.ts +++ b/scripts/create-reward-distributor-task.ts @@ -1,5 +1,6 @@ import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; const { ethers, w3f } = hre; @@ -18,7 +19,7 @@ const main = async () => { const cid = await rewardDistributor.deploy(); console.log(`Web3Function IPFS CID: ${cid}`); - const task = await automate.prepareBatchExecTask( + const { tx } = await automate.prepareBatchExecTask( { name: "Reward Distributor", web3FunctionHash: cid, @@ -39,10 +40,10 @@ const main = async () => { }, }, {}, - "0x48c18844530c96AaCf24568fa7F912846aAc12B9", + DEVOPS_SAFE, ); - console.log(`to: ${task.tx.to}`); - console.log(task.tx.data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); }; diff --git a/scripts/create-spell-staking-task.ts b/scripts/create-spell-staking-task.ts index e484ae3..c5f9ff7 100644 --- a/scripts/create-spell-staking-task.ts +++ b/scripts/create-spell-staking-task.ts @@ -1,5 +1,8 @@ -import { AutomateSDK } from "@gelatonetwork/automate-sdk"; +import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; + +const ONE_MINUTE_MILLIS = 60 * 1000; const { ethers, w3f } = hre; @@ -18,25 +21,29 @@ const main = async () => { { console.log("Creating Mainnet Task"); - const task = await automate.createBatchExecTask({ - name: "SpellStaking: Withdraw & Distribute", - web3FunctionHash: cid, - web3FunctionArgs: { - // not used on mainnet - bridgingMinMIMAmount: "0", + const { tx } = await automate.prepareBatchExecTask( + { + name: "SpellStaking: Withdraw & Distribute", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: { + // not used on mainnet + bridgingMinMIMAmount: "0", - // parameters - treasuryPercentage: 50, - intervalInSeconds: 201600, // 3x a week - distributionMinMIMAmount: "100000000000000000000", + // parameters + treasuryPercentage: 50, + intervalInSeconds: 201600, // 3x a week + distributionMinMIMAmount: "100000000000000000000", + }, }, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + "0x48c18844530c96AaCf24568fa7F912846aAc12B9", ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } @@ -45,28 +52,32 @@ const main = async () => { for (const chainId of ALTCHAIN_IDS) { console.log(`Creating ChainId ${chainId} Task`); - const { taskId, tx } = await automate.createBatchExecTask({ - name: "SpellStaking: Withdraw & Bridge", - web3FunctionHash: cid, - web3FunctionArgs: { - // not used on altchain - treasuryPercentage: 0, - distributionMinMIMAmount: "0", + const { tx } = await automate.prepareBatchExecTask( + { + name: "SpellStaking: Withdraw & Bridge", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: { + // not used on altchain + treasuryPercentage: 0, + distributionMinMIMAmount: "0", - // parameters - bridgingMinMIMAmount: "50000000000000000000", // 50 MIM require to bridge - intervalInSeconds: 201600, // 3x a week + // parameters + bridgingMinMIMAmount: "50000000000000000000", // 50 MIM require to bridge + intervalInSeconds: 201600, // 3x a week + }, }, - }); + {}, + DEVOPS_SAFE, + ); //await automate.cancelTask(taskId); console.log(`to: ${tx.to}`); - const data = tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", - ); - console.log(data); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-stargate-v1-task.ts b/scripts/create-stargate-v1-task.ts index e7ecdf6..3de6244 100644 --- a/scripts/create-stargate-v1-task.ts +++ b/scripts/create-stargate-v1-task.ts @@ -1,5 +1,8 @@ -import { AutomateSDK } from "@gelatonetwork/automate-sdk"; +import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; + +const ONE_MINUTE_MILLIS = 60 * 1000; const { ethers, w3f } = hre; @@ -18,50 +21,58 @@ const main = async () => { { console.log("Creating Mainnet Stargate-USDC Task"); - const task = await automate.createBatchExecTask({ - name: "", - web3FunctionHash: cid, - web3FunctionArgs: { - execAddress: "0x8439Ac976aC597C71C0512D8a53697a39E8F9773", - degenBoxAddress: "0xd96f48665a1410C0cd669A88898ecA36B9Fc2cce", - lpAddress: "0x38EA452219524Bb87e18dE1C24D3bB59510BD783", - stgAddress: "0xAf5191B0De278C7286d6C7CC6ab6BB8A73bA2Cd6", - gelatoProxyAddress: "0x4D0c7842cD6a04f8EDB39883Db7817160DA159C3", - intervalInSeconds: 86400, - swapToLpSlippageBips: 50, + const { tx } = await automate.prepareBatchExecTask( + { + name: "", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: { + execAddress: "0x8439Ac976aC597C71C0512D8a53697a39E8F9773", + degenBoxAddress: "0xd96f48665a1410C0cd669A88898ecA36B9Fc2cce", + lpAddress: "0x38EA452219524Bb87e18dE1C24D3bB59510BD783", + stgAddress: "0xAf5191B0De278C7286d6C7CC6ab6BB8A73bA2Cd6", + gelatoProxyAddress: "0x4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + intervalInSeconds: 86400, + swapToLpSlippageBips: 50, + }, }, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } { console.log("Creating Mainnet Stargate-USDT Task"); - const task = await automate.createBatchExecTask({ - name: "", - web3FunctionHash: cid, - web3FunctionArgs: { - execAddress: "0x86130Dac04869a8201c7077270C10f3AFaba1c82", - degenBoxAddress: "0xd96f48665a1410C0cd669A88898ecA36B9Fc2cce", - lpAddress: "0x38EA452219524Bb87e18dE1C24D3bB59510BD783", - stgAddress: "0xAf5191B0De278C7286d6C7CC6ab6BB8A73bA2Cd6", - gelatoProxyAddress: "0x4D0c7842cD6a04f8EDB39883Db7817160DA159C3", - intervalInSeconds: 86400, - swapToLpSlippageBips: 50, + const { tx } = await automate.prepareBatchExecTask( + { + name: "", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: { + execAddress: "0x86130Dac04869a8201c7077270C10f3AFaba1c82", + degenBoxAddress: "0xd96f48665a1410C0cd669A88898ecA36B9Fc2cce", + lpAddress: "0x38EA452219524Bb87e18dE1C24D3bB59510BD783", + stgAddress: "0xAf5191B0De278C7286d6C7CC6ab6BB8A73bA2Cd6", + gelatoProxyAddress: "0x4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + intervalInSeconds: 86400, + swapToLpSlippageBips: 50, + }, }, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-stargate-v2-task.ts b/scripts/create-stargate-v2-task.ts index 3b6fe82..8d0c506 100644 --- a/scripts/create-stargate-v2-task.ts +++ b/scripts/create-stargate-v2-task.ts @@ -1,5 +1,8 @@ -import { AutomateSDK } from "@gelatonetwork/automate-sdk"; +import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; + +const ONE_MINUTE_MILLIS = 60 * 1000; const { ethers, w3f } = hre; @@ -18,29 +21,33 @@ const main = async () => { { console.log("Creating Arbitrum->Kava Stargate-USDT Task"); - const task = await automate.createBatchExecTask({ - name: "", - web3FunctionHash: cid, - web3FunctionArgs: { - execAddress: "0x30D525cbB79D2baaE7637eA748631a6360Ce7c16", - degenBoxAddress: "0x630FC1758De85C566Bdec1D75A894794E1819d7E", - lpAddress: "0xAad094F6A75A14417d39f04E690fC216f080A41a", - rewardAddress: "0xc86c7C0eFbd6A49B35E8714C5f59D99De09A225b", - underlyingAddress: "0x919C1c267BC06a7039e03fcc2eF738525769109c", - strategyExecutorAddress: "0x84C9Bb8B81037C642f2Eb6486a9bdfF526CdEbe0", - gelatoProxyAddress: "0x4D0c7842cD6a04f8EDB39883Db7817160DA159C3", - minRewardAmount: "10000000000000000000", - intervalInSeconds: 86400, - swapSlippageBips: 50, - targetChainId: 2222, + const { tx } = await automate.prepareBatchExecTask( + { + name: "", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: { + execAddress: "0x30D525cbB79D2baaE7637eA748631a6360Ce7c16", + degenBoxAddress: "0x630FC1758De85C566Bdec1D75A894794E1819d7E", + lpAddress: "0xAad094F6A75A14417d39f04E690fC216f080A41a", + rewardAddress: "0xc86c7C0eFbd6A49B35E8714C5f59D99De09A225b", + underlyingAddress: "0x919C1c267BC06a7039e03fcc2eF738525769109c", + strategyExecutorAddress: "0x84C9Bb8B81037C642f2Eb6486a9bdfF526CdEbe0", + gelatoProxyAddress: "0x4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + minRewardAmount: "10000000000000000000", + intervalInSeconds: 86400, + swapSlippageBips: 50, + targetChainId: 2222, + }, }, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-velodrome-op-usdc-task.ts b/scripts/create-velodrome-op-usdc-task.ts index 3dedbfb..50a51a5 100644 --- a/scripts/create-velodrome-op-usdc-task.ts +++ b/scripts/create-velodrome-op-usdc-task.ts @@ -1,5 +1,8 @@ -import { AutomateSDK } from "@gelatonetwork/automate-sdk"; +import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; + +const ONE_MINUTE_MILLIS = 60 * 1000; const { ethers, w3f } = hre; @@ -18,30 +21,34 @@ const main = async () => { { console.log("Creating Task"); - const task = await automate.createBatchExecTask({ - name: "Velodrome vOP/USDC", - web3FunctionHash: cid, - web3FunctionArgs: { - execAddress: "0x7E05363E225c1c8096b1cd233B59457104B84908", - intervalInSeconds: 604800, - strategy: "0xa3372cd2178c52fdcb1f6e4c4e93014b4db3b20d", - strategyLens: "0x8BEE5Db2315Df7868295c531B36BaA53439cf528", - wrapper: "0x6eb1709e0b562097bf1cc48bc6a378446c297c04", - pair: "0x47029bc8f5cbe3b464004e87ef9c9419a48018cd", - router: "0xa132DAB612dB5cB9fC9Ac426A0Cc215A3423F9c9", - factory: "0x25CbdDb98b35ab1FF77413456B31EC81A6B6B746", - wrapperRewardQuoteSlippageBips: 100, - strategyRewardQuoteSlippageBips: 100, - maxBentoBoxAmountIncreaseInBips: 1, - maxBentoBoxChangeAmountInBips: 1000, + const { tx } = await automate.prepareBatchExecTask( + { + name: "Velodrome vOP/USDC", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: { + execAddress: "0x7E05363E225c1c8096b1cd233B59457104B84908", + intervalInSeconds: 604800, + strategy: "0xa3372cd2178c52fdcb1f6e4c4e93014b4db3b20d", + strategyLens: "0x8BEE5Db2315Df7868295c531B36BaA53439cf528", + wrapper: "0x6eb1709e0b562097bf1cc48bc6a378446c297c04", + pair: "0x47029bc8f5cbe3b464004e87ef9c9419a48018cd", + router: "0xa132DAB612dB5cB9fC9Ac426A0Cc215A3423F9c9", + factory: "0x25CbdDb98b35ab1FF77413456B31EC81A6B6B746", + wrapperRewardQuoteSlippageBips: 100, + strategyRewardQuoteSlippageBips: 100, + maxBentoBoxAmountIncreaseInBips: 1, + maxBentoBoxChangeAmountInBips: 1000, + }, }, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/scripts/create-xf33d-task.ts b/scripts/create-xf33d-task.ts index 8366e45..da6e252 100644 --- a/scripts/create-xf33d-task.ts +++ b/scripts/create-xf33d-task.ts @@ -1,5 +1,8 @@ -import { AutomateSDK } from "@gelatonetwork/automate-sdk"; +import { AutomateSDK, TriggerType } from "@gelatonetwork/automate-sdk"; import hre from "hardhat"; +import { DEVOPS_SAFE } from "../utils/constants"; + +const ONE_MINUTE_MILLIS = 60 * 1000; const { ethers, w3f } = hre; @@ -18,20 +21,24 @@ const main = async () => { { console.log("Creating Arbitrum USDT -> KAVA Task"); - const task = await automate.createBatchExecTask({ - name: "", - web3FunctionHash: cid, - web3FunctionArgs: { - destinationChain: 177, - chainlinkOracle: "0x3f3f5dF88dC9F13eac63DF89EC16ef6e7E25DdE7", + const { tx } = await automate.prepareBatchExecTask( + { + name: "", + web3FunctionHash: cid, + trigger: { + type: TriggerType.TIME, + interval: ONE_MINUTE_MILLIS, + }, + web3FunctionArgs: { + destinationChain: 177, + chainlinkOracle: "0x3f3f5dF88dC9F13eac63DF89EC16ef6e7E25DdE7", + }, }, - }); - console.log(`to: ${task.tx.to}`); - const data = task.tx.data.replace( - "9a688cc56f5f4fc75eaf8fdf18f43260ae43647c", - "4D0c7842cD6a04f8EDB39883Db7817160DA159C3", + {}, + DEVOPS_SAFE, ); - console.log(data); + console.log(`to: ${tx.to}`); + console.log(tx.data); console.log("------------------"); console.log(); } diff --git a/test/reward-distributor.test.ts b/test/reward-distributor.test.ts new file mode 100644 index 0000000..970ae67 --- /dev/null +++ b/test/reward-distributor.test.ts @@ -0,0 +1,158 @@ +import { + afterAll, + afterEach, + beforeAll, + describe, + expect, + setDefaultTimeout, + test, +} from "bun:test"; +import path from "node:path"; +import type { JsonRpcProvider } from "@ethersproject/providers"; +import type { Anvil } from "@viem/anvil"; +import type { Merge } from "type-fest"; +import { + type Address, + type Hex, + type PublicClient, + type TestClient, + encodeFunctionData, + parseAbi, +} from "viem"; +import { ARBITRUM_OPS_SAFE, ARBITRUM_SPELL } from "../utils/constants"; +import { runWeb3Function } from "./utils"; +import { setupAnvil } from "./utils/setupAnvil"; + +const w3fName = "reward-distributor"; +const w3fRootDir = path.join("web3-functions"); +const w3fPath = path.join(w3fRootDir, w3fName, "index.ts"); + +setDefaultTimeout(60_000); +describe("Reward Distributor Web3 Function test", () => { + let anvil: Anvil; + let provider: JsonRpcProvider; + let testClient: Omit, "mode">; + let snapshotId: Hex; + + beforeAll(async () => { + ({ anvil, provider, testClient, snapshotId } = await setupAnvil({ + forkUrl: process.env.ARBITRUM_RPC_URL, + forkBlockNumber: 234134609n, + })); + }); + + afterAll(async () => { + await anvil.stop(); + }); + + afterEach(async () => { + await testClient.revert({ id: snapshotId }); + }); + + const run = async () => + runWeb3Function( + w3fPath, + { + gelatoArgs: { + chainId: (await provider.getNetwork()).chainId, + gasPrice: (await provider.getGasPrice()).toString(), + }, + userArgs: { + multiRewardDistributorAddress: + "0xbF5DC3f598AFA173135160CDFce6BFeE45c912eF", + multiRewardStakingAddresses: [ + "0x280c64c4C4869CF2A6762EaDD4701360C1B11F97", + "0xc30911b52b5752447aB08615973e434c801CD652", + ], + epochBasedDistributorAddress: + "0x111AbF466654c166Ee4AC15d6A29a3e0625533db", + epochBasedStakingAddresses: [], + }, + secrets: {}, + storage: {}, + }, + [provider], + ); + + test("canExec: true - Multiple distributions", async () => { + const { result } = await run(); + + expect(result).toEqual({ + canExec: true, + callData: [ + { + data: "0x63453ae1000000000000000000000000280c64c4c4869cf2a6762eadd4701360c1b11f97", + to: "0xbF5DC3f598AFA173135160CDFce6BFeE45c912eF", + }, + { + data: "0x63453ae1000000000000000000000000c30911b52b5752447ab08615973e434c801cd652", + to: "0xbF5DC3f598AFA173135160CDFce6BFeE45c912eF", + }, + ], + }); + }); + test("canExec: true - Single distributions", async () => { + const execAddress = + "0x280c64c4C4869CF2A6762EaDD4701360C1B11F97" as const satisfies Address; + await testClient.sendUnsignedTransaction({ + from: ARBITRUM_OPS_SAFE, + to: "0xbF5DC3f598AFA173135160CDFce6BFeE45c912eF", + data: encodeFunctionData({ + abi: parseAbi(["function distribute(address) external"]), + functionName: "distribute", + args: [execAddress], + }), + gasPrice: 0n, + }); + + const { result } = await run(); + + expect(result).toEqual({ + canExec: true, + callData: [ + { + data: "0x63453ae1000000000000000000000000c30911b52b5752447ab08615973e434c801cd652", + to: "0xbF5DC3f598AFA173135160CDFce6BFeE45c912eF", + }, + ], + }); + }); + test("canExec: false - No distributions to execute", async () => { + // Increase approval + await testClient.setStorageAt({ + address: ARBITRUM_SPELL, + index: + "0xe291b9f68327d6549fd70e333daad56b6cdb38ac27f870dafc9c5d1dcd54d5a5", + value: + "0x0000000000000000000000000000000000000000002116545850052128000000", + }); + + const execAddresses = [ + "0x280c64c4C4869CF2A6762EaDD4701360C1B11F97", + "0xc30911b52b5752447ab08615973e434c801cd652", + ] as const satisfies Array

; + + await Promise.all( + execAddresses.map( + async (execAddress) => + await testClient.sendUnsignedTransaction({ + from: ARBITRUM_OPS_SAFE, + to: "0xbF5DC3f598AFA173135160CDFce6BFeE45c912eF", + data: encodeFunctionData({ + abi: parseAbi(["function distribute(address) external"]), + functionName: "distribute", + args: [execAddress], + }), + gasPrice: 0n, + }), + ), + ); + + const { result } = await run(); + + expect(result).toEqual({ + canExec: false, + message: "No distributions to execute", + }); + }); +}); diff --git a/test/utils/index.ts b/test/utils/index.ts new file mode 100644 index 0000000..15cbb36 --- /dev/null +++ b/test/utils/index.ts @@ -0,0 +1,64 @@ +import type { JsonRpcProvider } from "@ethersproject/providers"; +import type { + MultiChainProviderConfig, + Web3FunctionContextData, + Web3FunctionRunnerOptions, +} from "@gelatonetwork/web3-functions-sdk"; +import { Web3FunctionBuilder } from "@gelatonetwork/web3-functions-sdk/builder"; +import { Web3FunctionRunner } from "@gelatonetwork/web3-functions-sdk/runtime"; + +export const MAX_RPC_LIMIT = 50; +export const MAX_DOWNLOAD_LIMIT = 10 * 1024 * 1024; +export const MAX_UPLOAD_LIMIT = 5 * 1024 * 1024; +export const MAX_REQUEST_LIMIT = 100; +export const MAX_STORAGE_LIMIT = 1 * 1024 * 1024; + +export const runWeb3Function = async ( + web3FunctionPath: string, + context: Web3FunctionContextData<"onRun">, + providers: JsonRpcProvider[], +) => { + const buildRes = await Web3FunctionBuilder.build(web3FunctionPath, { + debug: false, + }); + + if (!buildRes.success) { + throw new Error(`Fail to build web3Function: ${buildRes.error}`); + } + + const options: Web3FunctionRunnerOptions = { + runtime: "thread", + showLogs: true, + memory: buildRes.schema.memory, + downloadLimit: MAX_DOWNLOAD_LIMIT, + uploadLimit: MAX_UPLOAD_LIMIT, + requestLimit: MAX_REQUEST_LIMIT, + rpcLimit: MAX_RPC_LIMIT, + timeout: buildRes.schema.timeout * 1000, + storageLimit: MAX_STORAGE_LIMIT, + }; + const script = buildRes.filePath; + + const multiChainProviderConfig: MultiChainProviderConfig = {}; + + for (const provider of providers) { + const chainId = (await provider.getNetwork()).chainId; + + multiChainProviderConfig[chainId] = provider; + } + + const runner = new Web3FunctionRunner(false); + const res = await runner.run("onRun", { + script, + context, + options, + version: buildRes.schema.web3FunctionVersion, + multiChainProviderConfig, + }); + + if (!res.success) { + throw new Error(`Fail to run web3 function: ${res.error.message}`); + } + + return res; +}; diff --git a/test/utils/setupAnvil.ts b/test/utils/setupAnvil.ts new file mode 100644 index 0000000..4b0ff46 --- /dev/null +++ b/test/utils/setupAnvil.ts @@ -0,0 +1,36 @@ +import { JsonRpcProvider } from "@ethersproject/providers"; +import { type CreateAnvilOptions, createAnvil } from "@viem/anvil"; +import * as R from "remeda"; +import { http, type Chain, createTestClient, publicActions } from "viem"; + +const defaultCreateAnvilOptions: CreateAnvilOptions = { + blockBaseFeePerGas: 0n, + gasPrice: 0n, +}; + +export async function setupAnvil( + createAnvilOptions: CreateAnvilOptions = defaultCreateAnvilOptions, +) { + const anvil = createAnvil( + R.merge(defaultCreateAnvilOptions, createAnvilOptions), + ); + + await anvil.start(); + + const anvilEndpoint = `http://${anvil.host}:${anvil.port}`; + const provider = new JsonRpcProvider(anvilEndpoint); + const testClient = createTestClient({ + chain: { + contracts: { + multicall3: { + address: "0xcA11bde05977b3631167028862bE2a173976CA11", + }, + }, + } as unknown as Chain, + transport: http(`http://${anvil.host}:${anvil.port}`), + mode: "anvil", + }).extend(publicActions); + const snapshotId = await testClient.snapshot(); + + return { anvil, anvilEndpoint, provider, testClient, snapshotId }; +} diff --git a/utils/constants.ts b/utils/constants.ts index 584e0c4..c84192d 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -1 +1,7 @@ +import type { Address } from "viem"; + export const DEVOPS_SAFE = "0x48c18844530c96AaCf24568fa7F912846aAc12B9"; +export const ARBITRUM_SPELL = + "0x3e6648c5a70a150a88bce65f4ad4d506fe15d2af" as const satisfies Address; +export const ARBITRUM_OPS_SAFE = + "0xA71A021EF66B03E45E0d85590432DFCfa1b7174C" as const satisfies Address; diff --git a/utils/crosschainMulticall/index.ts b/utils/crosschainMulticall/index.ts index a828596..88b4cc5 100644 --- a/utils/crosschainMulticall/index.ts +++ b/utils/crosschainMulticall/index.ts @@ -1,8 +1,8 @@ import { Interface } from "@ethersproject/abi"; import type { StaticJsonRpcProvider } from "@ethersproject/providers"; import type { - Web3FunctionResult, Web3FunctionResultCallData, + Web3FunctionResultV2, } from "@gelatonetwork/web3-functions-sdk"; import { Contract, ethers } from "ethers"; import endpointAbi from "./endpointAbi"; @@ -17,26 +17,24 @@ export const wrap = async ( localProvider: StaticJsonRpcProvider, remoteProvider: StaticJsonRpcProvider, lzChainId: number, - web3FunctionResult: Web3FunctionResult, -): Promise => { - const calls = web3FunctionResult.callData.map( - (callData: Web3FunctionResultCallData) => ({ - to: callData.to, - value: callData.value || "0", - data: callData.data, - }), - ); + callData: Web3FunctionResultCallData[], +): Promise => { + const calls = callData.map((callData: Web3FunctionResultCallData) => ({ + to: callData.to, + value: callData.value || "0", + data: callData.data, + })); const payload = ethers.utils.defaultAbiCoder.encode( [ - { + ethers.utils.ParamType.fromObject({ type: "tuple[]", components: [ { name: "to", type: "address" }, { name: "value", type: "uint256" }, { name: "data", type: "bytes" }, ], - }, + }), ], [calls], ); @@ -77,7 +75,7 @@ export const wrap = async ( )[0]; return { - canExec: web3FunctionResult.canExec, + canExec: true, callData: [ { to: LZ_MULTICALL_SENDER_RECEIVER_ADDRESS, diff --git a/web3-functions/gm/index.ts b/web3-functions/gm/index.ts index 4210c09..6b221d8 100644 --- a/web3-functions/gm/index.ts +++ b/web3-functions/gm/index.ts @@ -50,155 +50,160 @@ type GmUserArgs = { strategyToken: Address; }; -Web3Function.onRun(async (context: Web3FunctionContext) => { - try { - const { - userArgs, - gelatoArgs: { chainId }, - multiChainProvider, - } = context; - const { - execAddress, - zeroExApiEndpoint, - gmApiEndpoint, - maxSwapSlippageBips, - maxDepositSlippageBips, - rewardToken, - marketInputToken, - dataStoreAddress, - gmReaderAddress, - stakingAddress, - strategyToken, - } = userArgs as GmUserArgs; - - const client = createJsonRpcPublicClient(multiChainProvider.default()); - - const [balance, earned, rewards, callbackGasLimit] = await Promise.all([ - client.readContract({ - abi: ERC20_ABI, - address: rewardToken, - functionName: "balanceOf", - args: [execAddress], - }), - client.readContract({ - abi: MULTI_STAKING_ABI, - address: stakingAddress, - functionName: "earned", - args: [execAddress, rewardToken], - }), - client.readContract({ - abi: MULTI_STAKING_ABI, - address: stakingAddress, - functionName: "rewards", - args: [execAddress, rewardToken], - }), - client.readContract({ - abi: HARVESTER_ABI, - address: execAddress, - functionName: "callbackGasLimit", - }), - ]); - const pendingRewardTokens = balance + earned - rewards; - if (pendingRewardTokens === 0n) { - return { canExec: false, message: "No rewards to harvest" }; - } +Web3Function.onRun( + async ({ + userArgs, + gelatoArgs: { chainId }, + multiChainProvider, + secrets, + }: Web3FunctionContext) => { + try { + const { + execAddress, + zeroExApiEndpoint, + gmApiEndpoint, + maxSwapSlippageBips, + maxDepositSlippageBips, + rewardToken, + marketInputToken, + dataStoreAddress, + gmReaderAddress, + stakingAddress, + strategyToken, + } = userArgs as GmUserArgs; - const depositRewardToken = - rewardToken.toLowerCase() === marketInputToken.toLowerCase(); - - let depositAmountIn: bigint; - let swapData: Address; - if (depositRewardToken) { - // Already market market input token --- deposit pending rewards - depositAmountIn = pendingRewardTokens; - swapData = "0x"; - } else { - // Swap to market input token and deposit output - const [quote, marketInputTokenBalance] = await Promise.all([ - context.secrets.get("ZEROX_API_KEY").then((apiKey) => { - if (apiKey === undefined) { - throw Error("ZEROX_API_KEY not set in secrets"); - } - return zeroExQuote({ - endpoint: zeroExApiEndpoint, - apiKey, - buyToken: marketInputToken, - sellToken: rewardToken, - sellAmount: pendingRewardTokens, - slippagePercentage: maxSwapSlippageBips / Number(BIPS), - }); - }), + const client = createJsonRpcPublicClient(multiChainProvider.default()); + + const [balance, earned, rewards, callbackGasLimit] = await Promise.all([ client.readContract({ abi: ERC20_ABI, - address: marketInputToken, + address: rewardToken, functionName: "balanceOf", args: [execAddress], }), + client.readContract({ + abi: MULTI_STAKING_ABI, + address: stakingAddress, + functionName: "earned", + args: [execAddress, rewardToken], + }), + client.readContract({ + abi: MULTI_STAKING_ABI, + address: stakingAddress, + functionName: "rewards", + args: [execAddress, rewardToken], + }), + client.readContract({ + abi: HARVESTER_ABI, + address: execAddress, + functionName: "callbackGasLimit", + }), ]); - - const minimumBuyAmount = - (BigInt(quote.buyAmount) * (BIPS - BigInt(maxSwapSlippageBips))) / BIPS; - - depositAmountIn = minimumBuyAmount + marketInputTokenBalance; - swapData = quote.data; - } - - const [depositAmountOut, executionFee] = await Promise.all([ - getDepositAmountOut({ - longTokenAmount: depositRewardToken ? depositAmountIn : 0n, - shortTokenAmount: depositRewardToken ? 0n : depositAmountIn, - endpoint: gmApiEndpoint, - client, - readerAddress: gmReaderAddress, - marketAddress: strategyToken, - dataStoreAddress, - }), - Promise.all([ - getDepositSingleTokenGasLimit({ client, dataStoreAddress }), - getSingleSwapGasLimit({ client, dataStoreAddress }), - client.getGasPrice(), - ]).then(([depositSingleTokenGasLimit, singleSwapGasLimit, gasPrice]) => - getExecutionFee({ + const pendingRewardTokens = balance + earned - rewards; + if (pendingRewardTokens === 0n) { + return { canExec: false, message: "No rewards to harvest" }; + } + + const depositRewardToken = + rewardToken.toLowerCase() === marketInputToken.toLowerCase(); + + let depositAmountIn: bigint; + let swapData: Address; + if (depositRewardToken) { + // Already market market input token --- deposit pending rewards + depositAmountIn = pendingRewardTokens; + swapData = "0x"; + } else { + // Swap to market input token and deposit output + const [quote, marketInputTokenBalance] = await Promise.all([ + secrets.get("ZEROX_API_KEY").then((apiKey) => { + if (apiKey === undefined) { + throw Error("ZEROX_API_KEY not set in secrets"); + } + return zeroExQuote({ + endpoint: zeroExApiEndpoint, + apiKey, + buyToken: marketInputToken, + sellToken: rewardToken, + sellAmount: pendingRewardTokens, + slippagePercentage: maxSwapSlippageBips / Number(BIPS), + }); + }), + client.readContract({ + abi: ERC20_ABI, + address: marketInputToken, + functionName: "balanceOf", + args: [execAddress], + }), + ]); + + const minimumBuyAmount = + (BigInt(quote.buyAmount) * (BIPS - BigInt(maxSwapSlippageBips))) / + BIPS; + + depositAmountIn = minimumBuyAmount + marketInputTokenBalance; + swapData = quote.data; + } + + const [depositAmountOut, executionFee] = await Promise.all([ + getDepositAmountOut({ + longTokenAmount: depositRewardToken ? depositAmountIn : 0n, + shortTokenAmount: depositRewardToken ? 0n : depositAmountIn, + endpoint: gmApiEndpoint, client, + readerAddress: gmReaderAddress, + marketAddress: strategyToken, dataStoreAddress, - gasLimit: - callbackGasLimit + depositSingleTokenGasLimit + singleSwapGasLimit, - gasPrice, }), - ), - ]); - - const mimimumDepositAmountOut = - (depositAmountOut * (BIPS - BigInt(maxDepositSlippageBips))) / BIPS; - - const callData: Web3FunctionResultCallData = { - to: execAddress, - data: encodeFunctionData({ - abi: HARVESTER_ABI, - functionName: "run", - args: [ - rewardToken, - marketInputToken, - mimimumDepositAmountOut, - executionFee, - swapData, - MAX_BENTOBOX_AMOUNT_INCREASE_IN_BIPS, - MAX_BENTOBOX_CHANGE_AMOUNT_IN_BIPS, - ], - }), - value: executionFee.toString(), - }; - - SimulationUrlBuilder.log2(GELATO_PROXY, chainId, [callData]); - - return { canExec: true, callData: [callData] }; - } catch (error) { - let errorMessage: string; - if (error instanceof Error) { - errorMessage = error.message; - } else { - errorMessage = "Unknown error"; + Promise.all([ + getDepositSingleTokenGasLimit({ client, dataStoreAddress }), + getSingleSwapGasLimit({ client, dataStoreAddress }), + client.getGasPrice(), + ]).then(([depositSingleTokenGasLimit, singleSwapGasLimit, gasPrice]) => + getExecutionFee({ + client, + dataStoreAddress, + gasLimit: + callbackGasLimit + + depositSingleTokenGasLimit + + singleSwapGasLimit, + gasPrice, + }), + ), + ]); + + const mimimumDepositAmountOut = + (depositAmountOut * (BIPS - BigInt(maxDepositSlippageBips))) / BIPS; + + const callData: Web3FunctionResultCallData = { + to: execAddress, + data: encodeFunctionData({ + abi: HARVESTER_ABI, + functionName: "run", + args: [ + rewardToken, + marketInputToken, + mimimumDepositAmountOut, + executionFee, + swapData, + MAX_BENTOBOX_AMOUNT_INCREASE_IN_BIPS, + MAX_BENTOBOX_CHANGE_AMOUNT_IN_BIPS, + ], + }), + value: executionFee.toString(), + }; + + SimulationUrlBuilder.log2(GELATO_PROXY, chainId, [callData]); + + return { canExec: true, callData: [callData] }; + } catch (error) { + let errorMessage: string; + if (error instanceof Error) { + errorMessage = error.message; + } else { + errorMessage = "Unknown error"; + } + return { canExec: false, message: errorMessage }; } - return { canExec: false, message: errorMessage }; - } -}); + }, +); diff --git a/web3-functions/spell-swapper/.gitignore b/web3-functions/spell-swapper/.gitignore new file mode 100644 index 0000000..042f8c6 --- /dev/null +++ b/web3-functions/spell-swapper/.gitignore @@ -0,0 +1 @@ +userArgs.json diff --git a/web3-functions/spell-swapper/index.ts b/web3-functions/spell-swapper/index.ts index 084f8eb..ed62e9c 100644 --- a/web3-functions/spell-swapper/index.ts +++ b/web3-functions/spell-swapper/index.ts @@ -2,8 +2,16 @@ import { Web3Function, type Web3FunctionContext, } from "@gelatonetwork/web3-functions-sdk"; -import { BigNumber, Contract, utils } from "ethers"; +import * as R from "remeda"; +import { + encodeFunctionData, + erc20Abi, + formatEther, + parseAbi, + parseEther, +} from "viem"; import type { Hex } from "../../utils/types"; +import { createJsonRpcPublicClient } from "../../utils/viem"; import { type QuoteResponse, zeroExQuote } from "../../utils/zeroEx"; const BIPS = 10_000; @@ -11,11 +19,9 @@ const BIPS = 10_000; const MIM_ADDRESS = "0x99D8a9C45b2ecA8864373A26D1459e3Dff1e17F3"; const SPELL_ADDRESS = "0x090185f2135308BaD17527004364eBcC2D37e5F6"; -const TOKEN_ABI = [ - "function balanceOf(address) external view returns(uint256)", -]; - -const SWAPPER_ABI = ["function swapMimForSpell1Inch(address,bytes) external"]; +const SWAPPER_ABI = parseAbi([ + "function swapMimForSpell1Inch(address,bytes) external", +]); type SpellSwapperUserArgs = { execAddress: Hex; @@ -27,97 +33,104 @@ type SpellSwapperUserArgs = { sellFrequencySeconds: number; }; -Web3Function.onRun(async (context: Web3FunctionContext) => { - const { userArgs, storage, multiChainProvider } = context; - - const provider = multiChainProvider.default(); +Web3Function.onRun( + async ({ + userArgs, + storage, + multiChainProvider, + secrets, + }: Web3FunctionContext) => { + const { + execAddress, + zeroExApiBaseUrl, + minimumInputAmount, + maximumInputAmount, + minimumOutputAmount, + maximumSwapSlippageBips, + sellFrequencySeconds, + } = userArgs as SpellSwapperUserArgs; + + const client = createJsonRpcPublicClient(multiChainProvider.default()); + + // Retrieve last run timestamp and 0x api key + const [lastTimestamp, zeroxApiKey] = await Promise.all([ + storage + .get("lastTimestamp") + .then((timestamp) => Number.parseInt(timestamp ?? "0")), + secrets.get("ZEROX_API_KEY"), + ]); + + const timestamp = Math.floor(Date.now() / 1000); + + if (timestamp < lastTimestamp + sellFrequencySeconds) { + // Update storage to persist your current state (values must be cast to string) + return { canExec: false, message: "Time not elapsed" }; + } - // Retrieve Last oracle update time - const { - execAddress, - zeroExApiBaseUrl, - minimumInputAmount, - maximumInputAmount, - minimumOutputAmount, - maximumSwapSlippageBips, - sellFrequencySeconds, - } = userArgs as SpellSwapperUserArgs; + if (zeroxApiKey === undefined) { + return { + canExec: false, + message: "ZEROX_API_KEY not set in secrets", + }; + } - if (minimumInputAmount > maximumInputAmount) { - return { - canExec: false, - message: - "Bad userArgs: minimumInputAmount is greater than maximumInputAmount", - }; - } + let sellAmount: bigint; + try { + const mimBalance = await client.readContract({ + abi: erc20Abi, + address: MIM_ADDRESS, + functionName: "balanceOf", + args: [execAddress], + }); + if (mimBalance < parseEther(minimumInputAmount)) { + return { canExec: false, message: "Not enough MIM" }; + } + // Minimum of mimBalance and maximumInputAmount + sellAmount = R.firstBy( + [mimBalance, parseEther(maximumInputAmount)], + R.identity(), + ); + } catch (err) { + return { canExec: false, message: "Rpc call failed" }; + } - const lastTimestampStr = (await storage.get("lastTimestamp")) ?? "0"; - const lastTimestamp = Number.parseInt(lastTimestampStr); + let quote: QuoteResponse; + try { + quote = await zeroExQuote({ + endpoint: zeroExApiBaseUrl, + apiKey: zeroxApiKey, + buyToken: SPELL_ADDRESS, + sellToken: MIM_ADDRESS, + sellAmount, + slippagePercentage: maximumSwapSlippageBips / BIPS, + }); + } catch (err) { + return { canExec: false, message: `Quote Error: ${err}` }; + } + const buyAmount = BigInt(quote.buyAmount); - const apiKey = await context.secrets.get("ZEROX_API_KEY"); - if (!apiKey) { - return { canExec: false, message: "ZEROX_API_KEY not set in secrets" }; - } + console.log( + `Swap ${formatEther(sellAmount)} MIM to ${formatEther(buyAmount)} SPELL`, + ); - const timestamp = Math.floor(Date.now() / 1000); + if (buyAmount < BigInt(minimumOutputAmount)) { + return { canExec: false, message: "Not enough SPELL received" }; + } - if (timestamp < lastTimestamp + sellFrequencySeconds) { - // Update storage to persist your current state (values must be cast to string) - return { canExec: false, message: "Time not elapsed" }; - } + await storage.set("lastTimestamp", timestamp.toString()); - let sellAmount: BigNumber; - try { - const mimContract = new Contract(MIM_ADDRESS, TOKEN_ABI, provider); - const mimBalance: BigNumber = await mimContract.balanceOf(execAddress); - if (mimBalance.lt(utils.parseEther(minimumInputAmount))) { - return { canExec: false, message: "Not enough MIM" }; - } - sellAmount = mimBalance.lte(utils.parseEther(maximumInputAmount)) - ? mimBalance - : utils.parseEther(maximumInputAmount); - } catch (err) { - return { canExec: false, message: "Rpc call failed" }; - } - - let quote: QuoteResponse; - try { - quote = await zeroExQuote({ - endpoint: zeroExApiBaseUrl, - apiKey, - buyToken: SPELL_ADDRESS, - sellToken: MIM_ADDRESS, - sellAmount: BigInt(sellAmount.toString()), - slippagePercentage: maximumSwapSlippageBips / BIPS, - }); - } catch (err) { - return { canExec: false, message: `Quote Error: ${err}` }; - } - - console.log( - `Swap ${utils.formatEther(sellAmount)} MIM to ${utils.formatEther(quote.buyAmount)} SPELL`, - ); - - if ( - BigNumber.from(quote.buyAmount).lt(utils.parseEther(minimumOutputAmount)) - ) { - return { canExec: false, message: "Not enough SPELL received" }; - } - - const swapper = new Contract(execAddress, SWAPPER_ABI, provider); - - await storage.set("lastTimestamp", timestamp.toString()); - - return { - canExec: true, - callData: [ - { - to: execAddress, - data: swapper.interface.encodeFunctionData("swapMimForSpell1Inch", [ - quote.to, - quote.data, - ]), - }, - ], - }; -}); + return { + canExec: true, + callData: [ + { + to: execAddress, + data: encodeFunctionData({ + abi: SWAPPER_ABI, + functionName: "swapMimForSpell1Inch", + args: [quote.to, quote.data], + }), + }, + ], + }; + }, +); diff --git a/web3-functions/stargate-v2/index.ts b/web3-functions/stargate-v2/index.ts index 1bdaa4f..8f1afb9 100644 --- a/web3-functions/stargate-v2/index.ts +++ b/web3-functions/stargate-v2/index.ts @@ -6,7 +6,7 @@ import type { StaticJsonRpcProvider } from "@ethersproject/providers"; import { Web3Function, type Web3FunctionContext, - type Web3FunctionResult, + type Web3FunctionResultV2, } from "@gelatonetwork/web3-functions-sdk"; import ky, { type KyInstance } from "ky"; import { wrap } from "../../utils/crosschainMulticall"; @@ -76,21 +76,25 @@ Web3Function.onRun(async (context: Web3FunctionContext) => { provider, targetChainProvider, LZ_CHAIN_IDS[targetChainId], - result, + result.callData, ); } await storage.set("lastTimestamp", timestamp.toString()); - console.log( - `cast send --private-key=$PRIVATE_KEY --rpc-url=https://kava-mainnet-archival.gateway.pokt.network/v1/lb/3b9d1dd7 --legacy ${result.callData[0].to} ${result.callData[0].data}`, - ); + if (result.canExec) { + console.log( + `cast send --private-key=$PRIVATE_KEY --rpc-url=https://kava-mainnet-archival.gateway.pokt.network/v1/lb/3b9d1dd7 --legacy ${result.callData[0].to} ${result.callData[0].data}`, + ); + } } - SimulationUrlBuilder.log2( - gelatoProxyAddress, - gelatoArgs.chainId, - result.callData, - ); + if (result.canExec) { + SimulationUrlBuilder.log2( + gelatoProxyAddress, + gelatoArgs.chainId, + result.callData, + ); + } return result; }); @@ -100,7 +104,7 @@ const run = async ( chainId: number, provider: StaticJsonRpcProvider, context: Web3FunctionContext, -): Promise => { +): Promise => { const { userArgs } = context; const execAddress = userArgs.execAddress as string; const degenBoxAddress = userArgs.degenBoxAddress as string; diff --git a/web3-functions/xf33d/index.ts b/web3-functions/xf33d/index.ts index 354d35c..2b079f6 100644 --- a/web3-functions/xf33d/index.ts +++ b/web3-functions/xf33d/index.ts @@ -6,8 +6,6 @@ import { BigNumber, Contract } from "ethers"; import { Interface } from "ethers/lib/utils"; import { SimulationUrlBuilder } from "../../utils/tenderly"; -const BIPS = 10_000; - // using create3, same address on all chains const XF33D_ORACLE_ADDRESS = "0x518d6B079884Ca6Ff12c398F68Ac31516813b1A5"; const GELATO_PROXY = "0x4D0c7842cD6a04f8EDB39883Db7817160DA159C3";