From c6eee0934f9a744479a4e4c67ef4cc55dbeab371 Mon Sep 17 00:00:00 2001 From: Tyler Arehart Date: Mon, 19 Nov 2018 21:23:34 -0800 Subject: [PATCH 01/24] Upgrading gradle to version 4.10.2 to support Java 11. --- gradle/wrapper/gradle-wrapper.jar | Bin 54227 -> 56177 bytes gradle/wrapper/gradle-wrapper.properties | 3 +-- gradlew | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 51288f9c2f05faf8d42e1a751a387ca7923882c3..29953ea141f55e3b8fc691d31b5ca8816d89fa87 100644 GIT binary patch literal 56177 zcmagFV{~WVwk?_pE4FRhwr$(CRk3Z`c2coz+fFL^#m=jD_df5v|GoR1_hGCxKaAPt z?5)i;2YO!$(jcHHKtMl#0s#RD{xu*V;Q#dm0)qVemK9YIq?MEtqXz*}_=jUJ`nb5z zUkCNS_ILXK>nJNICn+YXtU@O%b}u_MDI-lwHxDaKOEoh!+oZ&>#JqQWH$^)pIW0R) zElKkO>LS!6^{7~jvK^hY^r+ZqY@j9c3=``N6W|1J`tiT5`FENBXLF!`$M#O<|Hr=m zzdq3a_Az%dG_f)LA6=3E>FVxe=-^=L^nXkt;*h0g0|Nr0hXMkk{m)Z`?Co8gUH;CO zHMF!-b}@8vF?FIdwlQ>ej#1NgUlc?5LYq`G68Sj-$su4QLEuKmR+5|=T>6WUWDgWe zxE!*C;%NhMOo?hz$E$blz1#Poh2GazA4f~>{M`DT`i=e#G$*Bc4?Fwhs9KG=iTU1_ znfp#3-rpN&56JH)Q82UMm6+B@cJwQOmm^!avj=B5n8}b6-%orx(1!3RBhL~LO~Q_) z08-2}(`c{;%({toq#^5eD&g&LhE&rdu6Xo6?HW)dn#nW17y(4VDNRo}2Tz*KZeOJ=Gqg{aO>;;JnlqFiMVA+byk#lYskJf)bJ=Q) z8Z9b3bI9$rE-t9r5=Uhh={6sj%B;jj)M&G`lVH9Y*O*|2Qx{g3u&tETV~m)LwKEm7 zT}U%CvR7RA&X0<;L?i24Vi<+zU^$IbDbi|324Qk)pPH={pEwumUun5Zs*asDRPM8b z5ubzmua81PTymsv=oD9C!wsc%ZNy20pg(ci)Tela^>YG-p}A()CDp}KyJLp7^&ZEd z**kfem_(nl!mG9(IbD|-i?9@BbLa{R>y-AA+MIlrS7eH44qYo%1exzFTa1p>+K&yc z<5=g{WTI8(vJWa!Sw-MdwH~r;vJRyX}8pFLp7fEWHIe2J+N;mJkW0t*{qs_wO51nKyo;a zyP|YZy5it}{-S^*v_4Sp4{INs`_%Apd&OFg^iaJ;-~2_VAN?f}sM9mX+cSn-j1HMPHM$PPC&s>99#34a9HUk3;Bwf6BZG%oLAS*cq*)yqNs=7}gqn^ZKvuW^kN+x2qym zM_7hv4BiTDMj#<>Ax_0g^rmq=`4NbKlG1@CWh%_u&rx`9Xrlr0lDw zf}|C`$ey5IS3?w^Y#iZ!*#khIx8Vm+0msFN>$B~cD~;%#iqV|mP#EHY@t_VV77_@I zK@x`ixdjvu=j^jTc%;iiW`jIptKpX09b9LV{(vPu1o0LcG)50H{Wg{1_)cPq9rH+d zP?lSPp;sh%n^>~=&T533yPxuXFcTNvT&eGl9NSt8qTD5{5Z`zt1|RV%1_>;odK2QV zT=PT^2>(9iMtVP==YMXX#=dxN{~Z>=I$ob}1m(es=ae^3`m5f}C~_YbB#3c1Bw&3lLRp(V)^ZestV)Xe{Yk3^ijWw@xM16StLG)O zvCxht23Raf)|5^E3Mjt+b+*U7O%RM$fX*bu|H5E{V^?l_z6bJ8jH^y2J@9{nu)yCK z$MXM!QNhXH!&A`J#lqCi#nRZ&#s1&1CPi7-9!U^|7bJPu)Y4J4enraGTDP)ssm_9d z4Aj_2NG8b&d9jRA#$ehl3??X9-{c^vXH5**{}=y+2ShoNl-71whx;GS=a~*?bN{cm zCy+j0p4J4h{?MSnkQ5ZV4UJ(fs7p#3tmo7i*sWH?FmuDj0o>4|CIYAj=g@ZbEmMgl z6J-XPr67r}Ke$)WkD)hVD2|tn{e!x-z)koN$iH!2AUD0#&3&3g8mHKMr%iUusrnOd>R?l~q-#lr2Ki zb)XkR$bT5#or!s~fN5(K@`VL)5=CrQDiLQE;KrxvC78a+BXkAL$!KCJ3m1g%n4o4Z z@+*qk1bK{*U#?bZ$>8-Syw@3dG~GF=)-`%bU56v^)3b7`EW+tkkrSA?osI4}*~X?i zWO^kL8*xM{x-Ix}u=$wq8=Nl5bzHhAT)N&dg{HA$_n!ys67s~R1r7)(4i^ZB@P9sF z|N4Y-G$9R8Rz1J`EL)hhVuCdsX)!cl)`ZIXF>D+$NazAcg3$y)N1g~`ibIxbdAOtE zb2!M7*~GEENaTc+x#hOFY_n0y3`1mnNGu&QTmNh~%X$^tdi_4%ZjQk{_O^$=mcm|! z%xAxO*?qsc`IPrL?xgPmHAvEdG5A>rJ{Lo;-uQf3`5I~EC(PPgq2@n1Wc}lV&2O~t z1{|U92JH6zB?#yX!M`}Ojw+L1Z8{Is0pe?^ZxzOe_ZQcPCXnEVCy;+Yugc`E!nA(I z%O%hk_^!(IZso}h@Qe3{Fwl3nztZ$&ipk?FSr2Mo@18#FM^=PCyaDZ35%7gPt-%35 z$P4|4J8DnNH{_l_z@JQPY07;`(!M-{9j2=y__fxmbp59aaV4d)Y=@N(iUgGm0K!28 zMp;Ig3KkNy9z>t5BvQWtMY82$c}}d6;1`IJ^~At0(2|*C(NG#SWoa2rs|hBM8+HW(P5TMki>=KRlE+dThLZkdG387dOSY2X zWHr}5+)x`9lO#fSD1v&fL&wqU@b&THBot8Z?V;E4ZA$y42=95pP3iW)%$=UW_xC3; zB6t^^vl~v5csW5=aiZLZt9JLP*ph4~Q*l96@9!R8?{~a#m)tdNxFzQaeCgYIBA1+o+4UMmZoUO9z?Owi@Z=9VeCI6_ z7DV)=*v<&VRY|hWLdn^Ps=+L2+#Yg9#5mHcf*s8xp4nbrtT-=ju6wO976JQ(L+r=)?sfT?!(-}k!y?)>5c}?GB-zU zS*r8)PVsD;^aVhf^57tq(S%&9a;}F}^{ir}y0W|0G_=U9#W6y2FV}8NTpXJX*ivt{ zwQLhX0sSB8J?bmh(eUKq#AVmTO{VudFZpsIn-|i-8WlsexQ<;@WNn)OF=UpDJ7BI= z%-95NYqOY#)S?LIW-+rfw84@6Me}ya4*ltE*R^fy&W7?rEggZBxN@BR6=0!WH%4x0 zXg7=Ws|9Em`0pAt8k0cyQlr+>htn8GYs)+o>)IIf)p+yR`>lvz>5xFt(ep7>no4?4 zA%SUJ=L2D=;wq*f8WFl|&57Apa1;cT?b?bfJc8h&vkBvm%#ypP{=`6RL#Tf-dCq`;$!eR%>29EqpIkV*9 zEZl_>P3&}hY7)~q6UYw?*cBCsuPi$TU zRe}A|5nl7L_#e`8W0Hcpd~NWjAaV#3ngl$CoE3dz!= z?$3`dPgn5I+Q8 z@Bk>MqB7;kQqnDK=buPc+DsEDP-S;8#I(_z!*u&%_%nqI3+srxxsf9-Qg6%$l$Rtl zK2Wn-OtsBE5<1d}1Hl!l-r8eqD+{%b5$jfxQZw`2%)f+_^HMfbWyW4@j!^9M({>e; zeqCfR5b?^xh7MhHfmDvoXm8Wq;Jl2RU;jY*+a&o*H02$`#5HsG9#HOR4{g9 z#2mgNt%ep|IWrmctj=e%3xV&o^@8%OrR6io()6^sr!nQ3WIyQ3)0Mn}w}p^&t*V0G z03mUjJXbSCUG!o#-x*;_v>N8n-`yh1%Dp(1P)vz$^`oevMVh?u3}mgh}Qr(jhy;-09o$EB6jjWR!2F&xz^66M!F z-g}JBWLcw=j&Vb>xW#PQ3vICRT_UZ@wllScxk@ZQe&h-y)4B5kUJptVO%U-Ff3Hka zEyLldFsaM5E5`k>m}||+u`11;)tG@FL6TGzoF`A{R}?RZ@Ba!AS(tqAf{a_wtnlv>p|+&EEs(x%d4eq*RQ;Pq;) za9*J(n&C2dmFcNXb`WJi&XPu>t+m)Qp}c;$^35-Fj6soilnd4=b;ZePF27IdjE6PZ zvx{|&5tApKU2=ItX*ilhDx-a2SqQVjcV40Yn})Kaz$=$+3ZK~XXtrzTlKbR7C9)?2 zJ<^|JKX!eG231Oo=94kd1jC49mqE6G0x!-Qd}UkEm)API zKEemM1b4u_4LRq9IGE3e8XJq0@;%BCr|;BYW_`3R2H86QfSzzDg8eA>L)|?UEAc$< zaHY&MN|V#{!8}cryR+ygu!HI#$^;fxT|rmDE0zx|;V!ER3yW@09`p#zt}4S?Eoqx8 zk3FxI12)>eTd+c0%38kZdNwB`{bXeqO;vNI>F-l3O%-{`<3pNVdCdwqYsvso!Fw($ z`@$1&U=XH|%FFs>nq#e0tnS_jHVZLaEmnK#Ci==~Q!%Vr?{K0b$dSu(S!2VjZ}316b_I5Uk*L!8cJd>6W67+#0>-1P0i{eI%`C(_FkwRC zm}5eHEb0v^w3Wkqv#biSHXBG4yPC=^E!@hV8J5*JYf73=BqO!Ps#sP0fx~&C9PMN= z+V%$50uI|KE4^LCUXI74-qw$aRG&3kN-aOzVpRS1AX(Ua;Ewy>SlDn@lV(<^W?t-x z%K2iVK+;lG_~XF&Glk7w4<=Z!@-qDLc7)$q!>H^AU{s6e7krRmr!AZLf?8~$rRuP) zc$@c*PhIA^Lsu;uR{^x2)9nvsm}-67I`+iFZkhfNASUD>*LqxD=sAtpn{zY0xMxFp z4@USzYjMULeKc1lBe*8vxJDGNiSTtq_b#zd+Vzdc%$~+xf0;s|LR{F$YKe7YJVR$U}jKOo6=D+|6vnryopFbmNXEo-~I z*nm(LHmEGwkB%h%tXF4r|5h2p%VnRLx5rRsFpPR|e)*)C`WG-Iz94xsO&>1k8g6W? zG6#40`>I=B^scgmt_6!uU}=b3HgE@Jhj-X3jP!w-y>81ZD*~9C6ZRN4vlAFJQwK&l zP9&CP4%l-eN@0>Ihb_UWtp2kcPnh+L(fFJfQLc0`qqFbCkzr`8y2%{@RNrQbx*;tj zKtW!BWJFR$9(9^!Y%I%@3p?0zX#;(G?}sRkL{U>2rH4Wc{3{0@MV+vEaFcD18KIy% z7OyQTp?-N_)i%g+O#h(eLt_3ZDo)2l4PwjVS#=FzUNVvW{kFijz-@Y9-66fQL=xoc zXfLAC8<-!nnpM87K#eT;D^sW^HL5kS))Qj`kxT`%OewTXS(FT^X~VlkkZJJ?3*R8J zR>c>6)9K+9lg_a7!#<`KC$oEk-!~2N)@V}eq4O2xP)~N-lc}vH8qSe7tmQ3p@$pPde;Xk30uHYJ+VXeA@=yordN?7_ zpGsTlLlI{(qgtjOIlbx8DI{Nczj!*I>_-3ahzG;Kt&~8G_4G8qqF6IDn&g+zo>^L< z@zeVTB`{B9S*@M2_7@_(iHTQMCdC3zDi3_pE2!Lsg`K)$SiZj2X>=b2U#h^?x0j$Y zYuRf9vtRT~dxvF2Onn>?FfYPan1uc&eKyfBOK(|g7}E)t7}?{4GI%_KoO#8;_{N6! zDAqx7%0J`PG@O{(_)9yAFF!7l zWy1|Utdlc)^&J3OKhPI+S|Fc3R7vMVdN?PgoiQzo200oGpcy;TjSQ^e$a}Kh&C~xm zsG!Pqpqt5T`1`X$yas7{1hk?-r(Um>%&@?P2#NMETeQYhvk~nZW#BApGOLS2hdH)d zn!sf)7DotO?tRXBE#UpfKk-s}6%TfS0|7#>Rgk z%Np7ln*SH#6tzufY<0|UT+M}zJ1)1ap_cE@;QZp)+e-;k24 z3lZG_EA?tM$Eg|x3CK3!k`T7!*0}{fh8#=t^2EJ>TTo`6!CUm(HFUl7fFIB9Zlt4a z!4=|s-ZSn!@6Yc&+r1w*?*2fxKX>Hz2(vBwgE*>E=`A?Y1W-;{d2$4B%$NFAI?v5e zmYT{blxWeHn2J(0Vbz%FDz9~baqE#)R2TMG24xMZjCLcPfc1mR?5H4L%GnMR7ua{B zCu=nN(vV)5dJ_B80WBCy`tJ#YH6GyltGBSQvsN#q0;6XU1&60$&PC$0r}FUdr@1I+ zINcU{Ow6t4Qzmyk=A6u*z_!A*$^hBXJeKQ96bnF2qD$46hN!?1C|io|<_u@g16@Wd z(Fg?1=p8)dkWz<^ml6Tj5gO$hpB1N5msV!#PB5pfwCOBu`cv__=7kQq*r#Tc7E@6z zdr}5qs*slXK39`Yn%?=rslQgOTH0x?@z|h%fI5Y7kQ{X00BcL#8Jae4Dc9M zR%ySU5qODGnM;n#&up^M+PIddhxizA9@V%@0QQMY#1n z%{E8NS=?1?d((9Bk_ZC|{^(juH!;Mih{pTo&tu<^$Twk1aF;#W$;gxw!3g-zy(iiM z^+8nFS<9DJfk4+}(_Nza@Ukw}!*svpqJ)Nkh^sd%oHva}7+y)|5_aZ=JOZ6jnoYHQ zE2$FAnQ2mILoK*+6&(O9=%_tfQCYO%#(4t_5xP~W%Yw7Y4wcK|Ynd#YB3`rxli+9(uIQcRuQW_2EFA@J_ae$<%!EbI9c5htL`8>3Myy)@^=J)4p@nB2*&sWCOmwH zwYi;-9HOboaw0ov-WBk89LqGY!{)>8KxU1g%%wMq9h@Aie^42!f9`?o32T4;!dly? z(N?67=yo%jNp;oIVu7;esQ$wG=Vr+`rqPB&RLzr@@v`H-KK6wTa=8b<;$yE1lQGy?A1;JX|2hSzg9`a{;-5oh|=bFSzv&b zst=xa%|xW;id+~(8Fj7hS5BPVD(@(`3t@HUu))Q{0ZrqE2Jg zm6Gv~A*$A7Q#MU25zXD)iEUbLML1b++l4fJvP^PYOSK~^;n$EzdTE(zW3F1OpKztF zharBT_Ym7Y%lt#=p2&$3gs=g4xkM8A%Cbm*xR)9BnI}5=Oxp4GEF*bjFF^87xkP4L z;StW)zkX!yzz5^Q4HfEicKi{8elkFQx|0TH5Mtzsln>TN2*5Nypl(7sj_UxoN|KSyOP0g{L+vTbHlOyIEJ@ zjfku4x;`_FLga2P{FJLrgpIt;A-ukDuPsuW4#ApWE7|&i85Frv()~gOM`v`YVsF0c zx|J0}YRtNo7DIl>N&+%c(o1^C?%>Zf5<-<(yVcj~p88d;@=(jtox_$Af#v4%=g4oD ziv4MKh%Uf}NHP$SqF6mZj>}_HfC-@2>S~<3qOIu*R^%7;`VGN{ay@0(xmKM^5g9H4 zaq4>^38z|jszHqa)d>j#7Ccxz$*DGEG9PtB(d31?a;2$u>bY`CigPsg$zpDTW?zKg z+Ye-wtTjYHi#Hs`5$aDA=5Gl4J>p1Xs3PJZWWgax9~(h;G{hDip2I=+bW1ng3BrMC za72TsJR+;*0fSYuVnHsA;BnH5x8yc5Z=Bno0CUc14%hAC=b4*&iEzgAB!L= z`hhC!k&WLZPFYJY4X1pELFsAnJ!}Y@cW6I~)S53UOve!$ECM^q8ZE{e{o}hoflqqy z1*ubPGaeqs1&92?_Z|pDIR*gw{Tf^KJV)G*JLdzktzF;w@W<(X2;}XY0Mlzs8J?$L z$HVp2*+(o8?*n6cqx3_k6 z_&05@yeYRSfWQk)=oa0v#3BHNBBd>{fP`)#O^*^0_#?tW5jf!vCBp<2W+WCTEYeSv z9x0#bu>tB9M0W%_p^S7&BHa{2hfNL5eUUq4dFsGvgW}38M#j+AdeC5Q0pg^g zVzX3vrRi^YI(~*BW_Jv^o?2;5SRY4UiQy4mO}td`T?9Cn>K+dHL)+V&T+H2e9cz36 z3w!e<82_a0Abraxx8?L{a%&###&w=O83@y6xz0Yz{8$Wp? zpRHDDFRKHe+@^Y7*&@z$+aA;ksdi7xdV}c(i1><3F00dIA(v8LW(^O*HX)5kc#IRw zqF;w9l3uQK5us~@YEWk+?*7*(7!*}^OBGk+&H=rcQ31wWiI7@}vU8P`@-3x85BGy25yPLiFcZ9Ix z&g>o*aIM5;Y#3A-9~8-WmTezK5V~98kP{j^ZZ|WDa{ZX{nzq*qy3?Lw?|D4hN>kzB|OT6-b>reho-)KPiAg^M6 z^V7T^-LL<$VK9OM_AsP21hWykSObS?gk4L=NQ@Wevk9nXUWk~lu4S>zqFX4H{cWCE z8{eF=%>j8Xll5o2)cdA;Gx}>chr}9ZPv2kT=8x~q=B4i_@+{8-#jh5lsK}aj>0zxd zIl8*E$!(}Vii%YIB_2V6>|Ove`W+f~dqsd+*K|~yHvkUoMukz^XnLgcXunf+E9#k| zU0yT>#IG*W)+6ue)vv=xfDT{9k$;BDL!duM&qpGVui6NbuaKa`h?7i(W~4YUu2O@t zV=FEUMaC0QAIZg2c%Yb_WFI$vZ0z*fj-GdWkVMt>lDy@w)qhCE7c^Vx0i34{@bnQJ zMhB3B>8stMqGsKyqUsN>cE5xczm}r!D&5+?zTtYl6!U!4nmiPv?E)Pe$l(A@E1T7dD)Px*$)#pB(Mccz%i%RKcuskizkH& zM^+m#S#sK2?f8;gH5BaXCfyI z=Mo5s;fHbBh@$hNB(!H7;BeU>q)!Z^jaCks!;!d2W7 zv{8hf2+z&R2zAS%9Tu1(dKX~*{rOT|yjLsg6Bx_1@bTy#0{R-?J}i!IObk@Tql*9w zzz?AV8Z)xiNz}%2zKEIZ6UoVuri+AT8vVZBot|VA=8|~z-!4-N@}@Bfq$~F4`^LO) z?K#tKQ7_DzB_Z%wfZ*v)GUASW0eOy}aw!V^?FkG?fcp7dg4lvM$f-%IEnIAQEx7dJ zjeQdmuCCRe*a?o*QD#kfEAsvNYaVL>s2?e^Vg|OK!_F0B;_5TuXF?H0Pn&9-qO85; zmDYsjdxHi?{3_Il0sibc3V2IAP74l2a#&X0f6EdwEb_ zCHuQC@Q$(2$$0W&FuxtPzZJ`{zM{%lcw)>^c&ZZe3{GU#x8ZmhC${E>XcP+}<0zKn z`!He406MT}e^f*=$WZoCHO>xt?AE)A6xB*54a+>4&{!W0*`Q93ibK&4*}N2!PdjOa z8?@WRHjyEXqa(1=JSuglKreLS>x>SiHMYiH7)EW4L&&HyJUh+>opC2p&vz)-)hLZx z$xgyMGH)3R3o|Ptu(n3@oM8uX^(hq+q=`-aC1BlQp2I$eKj1tJuqDUh( zDkDsZ^23iaH3;bn7U>k)AD&%$u4G55$I=scldY;vFs+SJmR6mE&8&=C%8}PL3Pz1e zQ8C!gVj0PV2ym8>BOJZh9EPGH7B0X&x$=hK?E>1-@+vYaj!Grfw5!*_$pLHotuVn@tVzDd6inT? zVRbufqa&mdvhz=1^!A^mshoYUOn2TjV3fhuz*2mdNqBX{nUrI%6StBzCpt&mPbl5F zvw_Cj$en(bhzY^UOim8~W)nxy)zWKuy$oSS;qRzt zGB#g+Xbic&C4Zo0-$ZvuXA7-ka&rf8*Kn)MO$ggardqZ=0LyU3(T};RwH9seBsgBc z$6-BI}BN*-yID>S62)&!|-r4rDIfw zn19#SN$JA4xngbeGE4txEV5qszS(EnvzvVfh08c;IO5>d^UpU#m~24P{^7AVO7JAS zXZ6RdAp5-_yL;j@AlsMp8N&HVwHV>9DfH4c81xmzCzVZ3fXAQ+=RnI0B<;YfHZuqa zH|&*09Aj{ZsDVS+5jB{XEkd)PR5JO&0q`JK;9>!6T7%b14rbcBtNiw}OPI9h?u#%^ z{#w3(2+S5shq7N4smmX#Ns_ayWl5jP^7M^2hVn&gl1y>C@BvQ$Ah*^_cgzF=iG z39Lr1x6KpDuS0W9tH%r}N=vnOgCk^E`0I|6X8%H)E5a1{r;Ooi{4RF@DssCC6!o~J zDpXb3^$sNds;bMqm6n#cJ8M2#j7A_?^(fYr0QA$GrTQV$n;9;Qkh~$WT|e1Yq}o;h zEk_Ww1Kf4%%?R!{!c91CSJ*2fr<8xHF)(7!_%EKZ*$KsDg&ALtP>P19z99^whu6ms z^F(P(PMjgfp#lXpZt(?04@z5J{`JHow@|N~KFN{8WLok3u$zxk=`cv$?EaF;?XU6*mT&GJ_`>Ma3MgI?U07^UN9N3Fe37d_Q@ z-K2Z>R)Wso&W%+APtaorr8H4bEP6FH4p7!F)=w=jfs{I20h3Vck4N=Y(~XC1-kIAd zy5x^LnlUYu)zXH(P}oXq?U#Bgp{4bf<(9x%vx;I>b+jS0&jtaYZ?(5Pfi=RUF`r58 zPQbIAX=tIC=*W@cR#+`*i)vPR-|p^(ORBp*UB+Ei6;0-CF@No`$y^MQ8{I(2`CNzye&0=Q^qYjw%}y zZk$+l#(MVftcugPvORxL+@7k(4XzR~ti3!@toSymCaI5}vo}ri9vdMZa)_TzEsCB^ zLAkET9Z0E*!fv>)%Z#tIxUhYw%QRE2;98~{O{W%9rXI<-_{I=y%%qwb%iNi=+!>Qf zK(HtaA|ze7afz`txb*_lkb0u$(ijK97^%;axfg0J0#7NIs61X5HEQ=zq4Zv>VMu>$ z2~v10H$A`~ZB}6dK%@F2UgC9sMoSgd@q}!<7mY~z+C3H5tBW}xeKN&KIXP_?N=ed~ zFv^}TDs}$Eb(JDOQ;H7ZUNrivfKib({Ix|*X$AZawRj(j{g<^=Frb3--rEyv z6xZd8uQqr-K=@KuDrN*E`gfQ`mxKf_5w*!nJcKf(S=suW%7rFjx+s2> zi#9ouh%>Rl2Ch+}ie_3lybm-tkHbTSJILVkcjl~h@Q}u~N~u`668%(zQ9>9i7C#5$ zx{s(#H|$tR^Isy#9Q9XsY<1MHT-F7OyLQJdGEvzDtP8S6C2h^jU=C=>>*UM{Ijd1dNe~wr z+2V*%W+RpfrPRjc)E0!+gT^{TN*3CN1C}}95a1F4XwxwLS9A^ttvzq%M4HJ+$y?4I z`yKD+?Z?h%Uf%Z`@?6k*M1Nf&Cz(V^NgBygk_J*oqqX3`NcK^Lkg7rqVHhw@z>zv- z%X}I!;8!nQ^_RTCBos2Bl+SVD9Fa##0@yip*+{E)wPQxv$$hRA!c&QWLoLFG2$U zYDR(@dUI1w4`Zyv?%zhHwZ){BfpG(vq}!Y;6q(jI@xnbko7P(N3{;tEgWTp9X{GP3 z8Eh9fNgec!7)M?OE!e8wyw>Gtn}5IO|5~^)!F(*STx1KCRz?o>7RZbDJd>Dg##z!; zo}rG4d{6=c-pIFA4k|&90#~oqAIhkOeb6poAgkn^-%j66XICvZs}RA0IXj6u*rG#zR07|(JUt8bvX^$La@O#!;a) ziCtKmEDwgAp}1=mhU`6(nvaz%KG1c@?X8FbZK*QU*6mn${cWs15OGLA-803ZO-?=7 zah4u9yUPx8iI^Q~Bc7;DSaf@k0S@+p?!2(*$4}3v|?Nx~swkjwTmia)C!dVfht zzo1E-1vmsM(nC);|(Kp4yaPusRKec@I0b0J(n9k*tg>E zC-M)?LH%OLASR6}G-`?oyQ%KJ3(+KfS;-Rndh?ku8frhoZdKm<$0bj0e4I_lCX`7S#zIYBZ*s)i1dsNx5wX6~IDx z(Oz=(Bo4-fnzObxxiw~v`H}FuI<4v9nlM*7QryonD7aNenD4Iivwde7(TYd34Y|)E zZ;|i*$m}OZEsYWN9Xn+cJ?tl$HcJt&tK#m5)0pE@XV}gwcJV80^2W;>rR>%lUXzzrnFRHk2?0nQST``j1g;Rr}E@4Bo##q3%WJ3kW9`oLwIq zA0vY(vUKK{!(xz~Aai`k?GLCg(L^>jk7c19wzM!kci)KXbo`HMF5|jVUqOh5zPHx~ z7u)Wv`L*($bdq$~K@z$=!D+{HF@qBwO~Iv@@Nxw?Fyp2O5_#Ys8J$}5^H>J%`@CS{ zt-hYIu7NOhv0I=tr-?4EH2w4i=#_UUmFjs z%A-veHM(n~V=b%q0^_6lN0yt~Pi!0-4-LyFFewUhvZI$BFGs7)rVm2-{L|9h^f~Z)eyKyr z7?*u`rR)t7ZJ=8!I1#4|5kHXDmljgsWr(i6WPJ0eCg9K=mNGR7`F@<9Y)ptr=d(G2 zyFZ6ui;z7lu4{L3aCARB69KtaMekNz59bzEC8)@)F`W`q&hnF!@hlaZlivmQh~9 z8R-`kyDt3>Is4#t4`YaCAl(Y_9rDyTs1KYE_5gKHl-~>Ih(L@+s?${L`>}yrDEr-q zaZJ6`3Uhb_efWr)4dESDe#xM2C-gvCth%+_s@(-6U(RvIlv?Ex6v_UD{5h)9b*>N7 zzip!Gp<%x}c#!@x5`?mLYygtk7JG(HNpnAPnU%2^Gmjs75I>IS^yb*`pyeYn!J7D^ z_Z#@1;rrh7(T48tPjx2LKtKflO``Iz@cr-po+gBW$}#TuxAUQHEQAn2AEUg92@)F; z3M`=n3n&Q;h^mjIUSbe7;14c|RaJ{dweE`QJlDm5psETI1Mo@!_NG-@iUZ5tf+VTP5naWV2+Jq7qEv=`|Y`Kg-zESx3Ez zQ)3pq8v?(5LV8cnz-rlKv&6J}4*g7EdUU6RwAv#hOEPPngAzg>(I@$3kIb+#Z%^>q zC6ClJv0EE@{7Gk%QkBdOEd0}w2A}A(xKmF(szcN4$yDCezH)ILk`wx*R!dqa012KxWj{K;{m4IE$*u6C-i^Xn@6TimgZXs~mpQrA%YziFDYm9%33^x>MsMr{K`bk4 zmTYOFO0uD{fWnFuXf{4lKEGfjCSAEiBcUh~-RK~vwagYh%d^zqS*rgiNnc4TX!3<4FL7tr3;DA>RcYrMt3 z7h~TlyR(x;>v|5s1e#?b~H|Pqc=q};~YvHmKp(4Zk9bYF9IcEMmW{Q;%denJT?l4 z70{bSJ{{dIb)jJC54M+j%am#jwFugdb8V~47)xgJ;{uA!=Zs?&88BQVhSI&P+}(>q_==| z7JnM15Q4kwb~Px<@LEs%cxdZlH`{A~E3?IKpfJGR2rv7%N}=c)V?JJ@W7AH|AkZUh zvi2w)>RY)$6mkHQRo9L;PYl3PPg~?S(CX$-5+P!2B}GqIGEw- z3&}?!>|j7^Vh!EMc2U!gsDhS&8#Pq)SlamRXJ#FxX`caWHH_RW3%~WsoF&WECP$2g z3vaHqsO>V7k2xZwX3!-T2cj>VPidn8C|_4c?CyU;gpnaO(?YGO=a)9=Sc(n>Zb)C_ z>8fRKP6=d9Wg?&2G&5nNVU7Xk_8F-TmDrM6uNLZNK!U|gEn(vb`sw~_Q7LRLhitWE zJ{DBl&v1l}uTVoMM*y8$1{W*UIP`Ju*BeYbo`gJO3-K_tZ&4g%BSpS&lGf9 zD<3|fTK@&&<9U(QZ?zOW4zHKQXw`?v;uSZJ3ZIAji)F;jrOD;GeX1VSR+>@*5?@>z zVUfy2G!UmbDU$F&S&~3{;e=EUs{9uU^x(oT)!;)yX4Es>NE-7X%5^brZcL7_$KhIv zr5CGYP6|tw9`3$Cz3Myl8 znbJvOI4#W@<>Cyg>1I0>WiZtflPr-GM&DAaVv>AI;InpOh-5usQbSpOmTKY9e3EKR z;Hno1gPK2lJj!r+UKn9Zp#3yQStL5eP+`n?y*fm?v zA84*u&xPM4%6OaA%lsEMxp<}G&L4b#3zXfT`Q&U=2$xO!&?4X~_EUw`E}jd$70B`D z%VO!*-NSxZ=hz=*vGi#2+0DPI?Nr{|cA-Xm?8(IBQT5razQXk&(-b@ZJgwDKQH#!m zNC}wPd|`LEdw{jkq}>P?kLv_l`1H;`3Ypo z<=~^h)h>9lcSp#~`+8{d*nkO{Q57=hcqST+<>@KCkjsY4-m!~JrSs!7e3YBf5+gie z@3YxN5s{0Nw97uJlOQ$kM!sMpu6~+PJ9*Ym^Ru?p*)mlo*nLP}tQcyY@^-0%KE==U z9_PrE;U|ZK{=rZX`6#d#514_!C+5->pSvmgNS}EpK($i?)6CZ!Huf)`&x;5Z1A(&Q z@DlP6YDZ(sbd(>nxM#=4mhsQA4E;<+v`Q%cvx`xmNiP4h>WvTUPJ22uWaL49LZe&$ zu1$oP!=mMt@SLsRR9nk&V1bN$rN33*%D|rhd|xC)oT5}P_9ccwLRy4*EnFy#-VG|7&>jsJ2#RpDz#r@68GuOAE*sQSmL#Re$ z8y$k2M}GP&w8RPob)Z+eZez0hGJ6;ig$hoS`OMO5oKKR#YtoGWNpHT|{A-<2v@r9k zdHaj`SnX5h4E^0M=!*2hM>m9i#hdJD+AEofPeP$bAN9B`?Qin)0|4sWhwTizniPlA$1E6xG?)-y`KbWVB#R7|wk*IeoeRw}# zv0XV|5pzw9*e0TCxIsLcdLNFOYX4Y^gpD&=N$!;WMK)%4;Wh80b>{oPy}ot6_RYmF zZFlk2_X|kWVuVY)O#Vf9iHpmhr1G2no4g{P?=gJ_UpU}HpD|jo+qJb=ynu~|cc+v- z;x`}SwQprny~&aqm;cD>#RsRo_#Tf(pEw{Z8_{2^g#CKVen}EUK}tsX@2GvX6kFB{ zz@BgZBarBKocTk%rxxP`3yE^XTF~#~>G?6S_kr*M-OA&x38`~(+>=FcD7CF1Zzp~R z`rhZwkz2j21wH7{BU2yzTYRZMGS+cNw5Qs<(MJzN+PcO{SFY&&dRNlj2{vylsOs_+ zxNOcD(t>RX?HVbjT||`Df>@!92R)`K$w3^9!FYA7Zh8->KU!x)e?ztv$;IVrH@|W@fd8 z7BiE@%*;%u*_qv$`FHN(BD$hGqB^>w>&yBw^JV6HC=#GpjX!WQ(zeKjLwM3%)TCMT z#xyLTD8e|^YTKwg=Vv1|?|13o6!&U$_A}W2wWMcD^#DSn@g(5GbsHO6W$I9JNSxoCmsH}pFn8j_Wxk~5^ zVhEXZ+s@i0YjOeagPLSQYoxR{i2biszj7RW*S<_0j2Dw-Ef7qqLN%~y`ZAHIINOP} zvmaSn7x|DlC&W$UxkMbbJ&xpGD97rRFi#}3H61(AYVcPN9YUF0n72Zo#a#jfh`6TX z7!Pw#0~N0S?BC*wDZ0l04tmB!J145jwS;Pci*%m~ID_r&x0H;>J>$x}okimL!WLb^ z%m!KzacfeEw#alud8ZbsYF& z1@a|GCQHDAcQ3iM5LfSbz{fwQEh%&k<8f6$Q`yJ~Y7aO&6=u1}-*Gqw6$crh2cZ*X zMJE4cPZcdI%GQ>e=U|%r7EWn5pWBsM{|l8thH#qb@2{EkxwMBgjvOdH_IVX`Hh3}l zHcZa5HIB;>NekQX)ukMQJ`DTqS}jZ#j|$iH=Y_~kA^2?d%gm$PmPGuA)POynhUyaK zegRG1n2fzKfWg9@a>C@^5M)xpFSicmIRz7$?!Cq3uh(hTvD(>sag!Yf5*aMvtv=^^ zleZUVg$1$=zDs9p6Q1CAH&);!jkC-ZJ{fW`hE2o0x^4F_jcyr4#!ggqbcMo}icm`y zQ_77P#ZDAzmQz~g1=4DW!t7IZa}Z7thh#dEqn7+`5Lf8=4OAj_>AZ3IGQlz5loU2V zh|Ok)*^>O^ITIz*6(a6LT46*2Z8qn|UEzXV(Cl(`t!NL2^RU)JQ5CwNXU<%q`gjnv zF8YRI{0Qs{HiYEeK^2%=T5HFvrq^)R3Z~s+&dp-ZNpWu25qg9QUYwJZRjYFp(D>*A=`$9U_~N!BjcnQhdaf0Wf4k~Wb-yz6v=9i4rRTbdv0 zO)%vr@`J~@XKn3Cmo;jazVHe{VYoA-^m4ZO7VwZ~TARsMO7PY(!ck&QGkAgY9Q9RJ zLr}6J8cX!W%WFefwo9}P-hOjJJd>||gfOKNQ$xEbxDL$!N<$66h}w{A$tdnEEUq5; zQB17>Yh#_2o^GIeLQ`D^c**S1E;}*EAjaUHZAmh>Q~WW`RrCigz!CK>NF|IY`w>Yt zHl!vK+Cf`LljiFI=u=(p3$f!)&jk0aE{~>@e!_NZAc2Omti-mkw)JiJbz_^F-VP%u zQ&y+sQ5}T;hcIKT?jPxfEv!MA!t{oa;sV+#hIQ7_qx8Lz5Sulr_iep}MwMTaYYHyE z;th6PF7kKkE$1mPSGQC0?W9DiI&FS zPw(Wqb7k(snDvn6ol!D7!#GhJjH2M&gJc}C(-vuZ?+cGXPm&H#hftWUx3POg66a6n zfN##yl=25{SXg!9w>RJsk>cLGe2X4*AU?QPz|qi6XRQfR&>EZ1ay72<=1iIAao!gl z=iXCdaqY-04x%}=Y(<*>tlU_^(VrHIH)W}5({50@Pf_Emkvmy1_vz}FN4%!arFz{@ zGv%Z<%-w_KloV$v=!Z~|Z<%S|Y2a7~>BkxgdN}R+5+GE`KL1&xvnC1ZF`O&)@+-)Gcq!xuuB9S0X>R-t2pteqfiBX18=s!G>_Y z1xdnN_B)8}I9o<`n6y`b6?TV^e{iJi5!y5A8#Yc0miLEe zI33k{;HS8^<|IEkcVzjj#3rzLtPbmdq8r6_xeOf+1flw@2u{ z7ph8+9FzeiT#-P8tS?i#BdQ^$h{Ww*F=6X>5d^;jC>JrKa`a2vZCP4F`(r%|qT)+p z8I(A**}QO~>w_{AcjCG6S2(!)!0Q0koYHOqp0J7jIN>?pqxj+UPbG(ZzH%R7XM90` zj$jS22XlLiS_ef1-*ioM!Q*00STA}&18-3EN|(Q&<%b4;8@@tEm^uU}c!LZu9o`^A zX?d0=!n9~@Op+U(i2*`#N{3pe!XtMPb%k4>*#6S)3<-sC5x+);@IFHe;)vLac7gVb+ zVy%FX+y_#;fY94b0?IYZkO^Ow#D_#PU~5k6IsF|@9#PExC0GDbVu*%(SN5nu45KYs zKy!crklZl|C;1xq4#gk_`Nhg`S}5lC++i0e&GcafLxzk_hVLkBG5d2y{94=Z+|x=1 z%axSnz&LR0GB_NUJ02Lc;Ywvu?Q4ScA)Ezcg)!G2B1)N>;~wK=y{3lDg{gpiV|7Qn z#pOEzcxTd{r1`A7Q=fO{Wkuq(Nu{edMD>fb`0?+_%wU!>D5zX;AqW)-;3!Ex0vhNX zU(=77+{)#g(yr-uoy1;VzA7=eqw-JnGPqHOS9eh-G-@b?^PL|t*sa0#ONj?=tb;`? zl3AWgQ;F`_s;d-UQw4ap81^{HPK`38^=*#j0=$C|aKZrRIa{?amtPS#3sAyjQNNE= zMb?g$oC)nJIPC#jz%sw{QK8};07-+BdV^4n4PcL?xNe2Unx(ja7Qv=z_StA;h(t@` z(NNC7C@e%oWn=;U?G`?^0-gqzf+ur;K~}LsU5XJOUlJ1+>uC@)ch>nl zTSAKzE;N|>ob6G}%w)1smx;CC>fI+tlBydTE74*M`xWyfEVkhU0|-YvvQ@BS*=1*E z51c1H+!>B81O@#;EpxFY;eQ!72d*%yDa90owz9bww$P3P!PL8B1NB1>hZm6;z}(0;}OlhLJezvWPX0@NORT*jtJ!^cR@vI;g*o2t`ZiJwUsBg)gff zZE|OPnxbToa;liDWvy7?*;dfZj1DP^FbC{!haAw0nvpCY1``va4NgJN+5Q4oFCb0h zt^a99;!%c9Qzhh3JiTHZ?tWHR5Wz2sk&=FEtvf)LAVL}ekqCQE?nH=)#wWLp>@1CT zsg*%F!$+?0Z2>!V;;{xXE<^&RS}z%8PcOkF{p!LGufDBPhMPC^ zG$q{wZ z#Ja4}W6245crq5zje}Y@*c9{lc@AzpQqmGuXJ~LY$*{`hg&Gf3P11|WiFee_O|b}! zVRY5AG_P@)S3`T7$B`vU`zoGU;5|1#4QY$XU%4+;XJ0S*Gf z^`C83$;j1G*u}-n&e+z>nM}^X#K>0cbBxQ`${65k4P9l~vmH4wj!dK9Ds-qvw$pf(6VOiY2 zE?B}k{2zUxzM&EhG6jZ^@X=))R&lRCJ#H4rUE-D}<&<(5y_%LK&nIcv={%BK0e!`un#9Tp#Xwr-Fflcti3K={AE}6#+kt{Qie|AZ6 z6*&nr;n(wh^uhJE3@XxoOU#BJE&q;S)ux&^y%En`f>||6x$_bSMn;dC71xBhpU~E{ z5f2v|P{1Cv^jl+$^NJs3E!XibZM8w%4kl>uy8yA#xpwUfn$HvbVs|_LMy>AUN(Ar4 z6ZtLFzwcQpxj;zF&-MnRPYxT3{|`I(dzBso9p=4TUAQ4of#Wd3q@H-0Gz8C6U2uxl#VXmC}x+B`>D)ffK;%ZXO>H zPVvNavG%b4+j~NPJ?rVff87JMOM5lOQOltlI~`eXFb2A)9UhlOiw3q{Ke>OF<`kMl zD=jNgN&(C4hl51!cB-wzNNv$JDl%R#CFx^wJ8zI;*wqhcfv8FGOLzgs8B8@F<^2`p z%)SN|zLITOn%{T>nk3;{6-GYt$(;vrEOutbF+({n^elu<|244j+ z86+n$mOkc15>j*V=xfd1B$*G_jnCJcV9-J8EZ4((lhmZiNJw`_M7fwG&8pHy-Ke_I zrkS&<(%!(i9Q}xb&7WPk`{_kfquVmahoIG>3~7f7S+RSV+E92f8X9;%>e3J=Cr>x0 z&~#wS|C19#Hq^JQmKY}+yCL3daSWFY*=wp%?jSI5|8X-huuF_swuyAM*laABQv<nM&9OUnkdus9i3(4|D}`eMP1@}Y5Bb1U(z#8*%%$T>s4~qFx5>;H zHo2s5PKg@JpAq1ZZ4ryNp{ihW>z)*VLmyu=cWSVjU!#O$Av&KhM`<{OsHeT4W^L$D z{FjnPLb}b$BGoEeF$aDxO-llzmVFo67b$7hXg_8Tqtl11I(W(^t~3EMSd=YsUc-tL zeLEb+dK9(xLL!m2ow1)kliqtx)H+c?rCAXtFh}k)h<{do_@=OvP_jjD3nLJIHX;cA zVfvn9=>eu_t@R0_vlV-GJm~znRBf*`LeMt24Wb(uH5ag1#POrx5gcU1N=^GbQA zX9vONEw_HE$REtCE;n>zdhek^PUnZ};@#Hm_lec6sYLgf#WB9v_nsZ5KeZMY7auW5 z_kJ*q9eK)**B@+THL8Vch#NR9ncS;4qP#j6})Vi(T4b#5_y$z z7?C9%S=An`M&>9nt=_&CMr#bKi5!PK%Oi^X!xk~)OE$*!pzhBbDl|3c_cJ?Jt|od% zuYTxQifMN~M*;jbwvtdar!}ipi6*ul!tJ)0=`QptvVjiLWO?Ld6ii1euZ#(56TeW0VKXYA zO;JSEAuLdOhiOC(zo^YHO>63rTdS-vZ#(9539=q3ZSysm;qjs%@UoRNo1fD+cYOcer$pT%eNH6nAI) zF#HH}KZtL)Sp+0rH3lrc-tc*6T!UfgJ4jfcO4jby`$s!NkCaEoshYG5Jo6~Z904c_ zN@%e>N*~A}l2(TI*J0P&&ek!u&;b12$=W|DWJ0HN04;s(4eX5ydQQ`7)_VOrV%JU| zAsp{6!;B$uFYtT>M{r;b#P62;8PhsNPB~ zDoO@&p=doKv4mZP-D#zF_D~qc8PYJQJ|xuo%cr(3q7)B2GZMPwDGIJ&zZi;fUEyQ^ zlcs~)j^o>q<<~(~Ioj!$ZboT%dYqkYXq&vL*WDjLt_ESAA*A_+)v9X4Z~1?D*Gu@I zNYE?q&aC%8EUc1@Gw-PszuMQ!Erq`S#kHQj5KwM@PRZ4NlK(ROXVva0&c~E!#qtJ0ujV8(>y;aKR3G#1Mf43 zs*c3YkGCB~5XCJWkhOHBOJ@*-bm(s=s<7LjkA==WAdsxiSCN_HG*VRQs+ZOv^y!x- z2C;A|nMuaXAm|6=uTAFdv78xK6bw>VseGo>i1Y#EWJOx3B56}m<5I*`T}qD9x%_qM z>9{{znOJ%GMVUDWcqR9C$0bwpMbQjd+S2r_HA|s-X~_nZcDoQ?DCv38rI(hSCE_ZV zbvPUoTrAj=%zqNQ7P^-Fp>bqVgI}m6*^!WlyGKv+92^oWZlrs7 zLP%PeYC`}14V}Z>{6=9~EdATJEHiIgFI)OD3;bRds~f#P3rA87s!!-^uI1br2CapZ z`1v@|yHda{pTH)AkuX@Swr8a=g6N?>VNRM z7dRL!$B(sDymlKemGkMDPE2d*y(`$P4}_OZoiG2^U!|m)OKnsrH$J?=XL-5>htARqAgN!n1k0v0x4yHek#IorCFRo7^?-1;kV#W$fYQ!QZ- zomxY^(n$ZyZEU3bRd(Qmx=%pGu6}>mQ28S?VS|^mSzr&Wfbtc!fa(?ZZ>1~p-zrz^ zzm3k-e4;KOo(bR9U`{KmT>prvOF+)a;9Ml_ou|vL{IM=Wwe`oeC6zehu8qmGfVHua z1Y$@hbgk2??zN>r8?u<}nJOl7GDqOU+A)^>wkuZ=$Y+0?aq+`izt9p#hof!8mlE^O zf~Gi`+8)>#I!~O!_k0@}6j5)Cw87lr9N9gq4%B4BC9m4se#V(Ln8hzIpyRB}YGS^g zuNz)bukTc4-C-cH9TGtxvp~CV=`XTDd&4S2E=a~QX zH34ta32)bdsH=6WJ#2@#8V6}tbI48DGdKfUvU_^LA8y+nb4GUQkR}LPxm+CNd1|r_ z1{{kl@@K!{B?`H_fqa2bMp=P_xGQl3^UVQO)zE&*>6|fd0-ij2&(}+rzuIf z5BCVJgPeH`_W2=)_-9p+r-e~Ku;noOyq)`Rpluve)JTNOUH0EkxO#^Pz8g7A>2|Gu zo_MJ?scrYD45&6ToEltGJj8>3)|>Uy;dJZ@3c-Eg_+sB9D&U1|zG;L97$k}{!5VLm zZTG>$Pkz}N1Z_+lLxbHRQ6so1{TgU- zNgLZjHZh}%$P)p3^Gekk&O5Tieo9&&cDwA6`Vp6H4v$08e1lb0n7X`!_x6ZQd5Ncr z-1or8K7tmVoT%EEwQD=~7Pr?K#Q{0Fu|sSC$>>4Wb1Msgv(Z1Z(3m7U zMO0y=!H*S-W8oYSQ1PnB#xO?}$Q)^p(#SI7QlV{J=a2?GYE5VN`98&>h?oe*R}ep{ zozpe2vsQT@R#sltkEM-?rp}MoSIFEzNh`e`A6Ph1sa~lqf`_P8wdR(|ad7+8L@kAF z;vhFm@833@Jipi6uq3Pp_bF!`={6RZ)_q3e&#G#EWcSA-dg~O=vK_0rWH@i|&I%f1 zoygC}jg8DWcewP#zZ&O+CV8OUQ)Dm2p4Bjk$?oZgE_%JhAOFZW({kXYL>TpT;Lzz_ zI|FZMvT5ZIj4~Y)tmhAPt~%q0DYhX1((N?ZWM}JC*I_>20dJ=5-SmxUPm+W65rj^`Sjpw$s`^3 zE*(gDcZAiVe8og}D*eTK{{60Jzb!|N-s5|xL@(8VWewvmO-}3iw=6G!_s9I7pXH&* zrdXkqzmYytJaFoVEQefFHzj&&L-8Ck-zIBhH1+A6Dx7TbAE^RAhyx%HXL5skx89S4{#ET7{&c zmPoAZzn~8EGBAIa)Vb6MJ!#GZi5MYbm5C>b(F_nXi)XRA1togzy^M087T#tVYDd`x z;*c=}(IpnMfRND&nI{v8vJ54n?8f4lN`3K^%b)}oat1TifJuxO&ZZTXv5pUhub0Va z0wwYURnZ6}Gm9@r5z`F%e3zeTCje1FB69h@e{T5iwyiaFBF^|31@L?}B2xY5NZ=o~ zE$(4v0{AEMu;!Eh>^}AfO&zIZILKE}6cHN{5EEVqDy8a~1SAO{o{UWYu(Q(T`PAts5V>@5aLwuP6?A4V6(t8AZ*csoO|B$?XQ9mzToari6>M0&(#_q-@sf0G2g@us?RlnK?i5>!_})FfdEnul&4?fFyZ!m znCK()B;nqc9yH<3(+;1HNFSx>BO2|cmH9_>Fz+Q=1y^syP5ZMgbdJd#BU7(9as%Ha z^HX%VEDCVvM$S*Chwpb+?xd6lMjE*fvLWo&C>YLzd&w85R^HGrZ7(kpVPCu?l0Gs1 z>hIk~pj+7mBThy96}uG6s>OMG6mD=@i)9C}#fhwl)Jyp^xn=OVCWhssK}rg8=eT@_ z#MM-!#b3{H*Xr$FEUim5yRH+?cP*`J{c|f&rbWvFlCDFuH4#)*;lNUt$}#2XSF&9v zrQcdn7C`A`pBI)gGu9`(w@al@TAb`ex0c_we6RkY{rql>Q9pi>PGM8b2KT7qFnaxV5b zmoEvhO^tU`ABvOe!>+KynhALJ%$E>t)0)=h(O|==6SCC1QdZFZD5R7X(TTm*Q7_hO z7=l`B@tJOngSoFD`AxA6D{dmf-hq?o<*Jej1-3o?L1`s6?+mT&LguymtaBrJyuUnZ z?rVkLYMuzew?h6~WR}&&rjgWu%Ol0zRpK~!e`c9{nSB|I6c>-U%w~d<3Pru2oslnD z!7N9~Pvko?^+^eupC}q1Sey*kNzo2lD|DB`-Rbj%!6@17B|U@DbT%ss`OK13)V3c zBwneSClO9vQ^N*Z%RXYO`Wr~pe)sPVHe|_LFY!-A<-IfJFyW4DQ`-%WQ$+9`xjvG( zpQ|w~wLPi9e&l?tir%<7e!wa+NTIeV($?_M8K9Ok9K|eg(1Gw$>)_r!@~1mMWch?I zlu47XEEFQ?B*b6E2Mn(`k^R%I5MNchehcs$@A>Qon=44fmd(0d!g;b+#n@O=a#iwYWb+LEvPA@*#Kw4&DzJnYfh;LQnC6!87g zdeW^0s%^91PAO0q`>$Mb==p<41NxthJ-IB>>x%WSPot3rFI* zMf_9_Wl1cS$EV%`sC?Jhn@_2EIcHtJ_h7LBu5E^=&na;`bMz8S&E_6(zjFs3RZeiQ zuRTJN2!tO#0FHtOBj@_b2Se=SHmzr0Tt=WHWsm zPs9+a0tP&xdv8i{VnZqpkkTa`J-)KLAX(5g`{CFP0HkK9R?;p};94=j88#urqEf@h zNp86`#tPiH=peJZ1GkQ~j!|~G>DtG7jQ3c|>9GN9;LJVY1=w~3+AxFB$^Eo!vtkY< z^lHsv3=oH=6dYkZUJB8!gnGuu>Mpma_%KKAHQD%Qw+A~YE zE7L`H=rT?lQtq`I0KgG}wsC>BEIza!{njtF{Q`O>%)n&}o3jSMpQUFP%j1UC+HN<| z%(W?wu*JQbLVt+3ZDuiiDA#YyF+Ybg*l!h`SyN{^k0hQeu)8@TkKFQCrJXjud)K0> zE{25F{XD-Q59a5JYP&@17qn_&5_&P?3hqsnwKyDL`c}1=5ZJU0UskWz3a|b_9B++G zN)j91j2Rf7HbdQc&*p52&{LV;l9GveK^#X>?Yyoup(pf4w|r>&$=OG@Y_VMwA6hl! zIwQFIwy79_k(kp+&XQW7iS%nnfT|GF1~u@KPe&}8SiTJ;%RF2cz}~XJ6NDb<=rK#j zVHko2=aA8x+I!P%vZ!O9)e9UMJ0?eeR#JpbX0d512u#wxBlv;hf62v?LqwumZ%wcg zHVp25KY-e>DBPKKKy-JtDgj!RZ(S-1&dd=Xfl&QQQBJ6^qysCBFAbkG_9f#dv+)s1 z-L3APDR&JQ*PJ&s9> zB@&43RN*^1zQA-|GKN~I4qBYTZiMEPc`j3U596%W1rSO;yzSV-svR6&RH9>mD7B=u z8}eph-j#vh0v4B6McTDb$}TryMb+$sTV5 zi}_AlY6U+=R!x+it_{Fws^cQRi&m1^#pnUclQP{S=|M!jX6e!UuBpP(5qVg`=VuE5 zSpDtgx;0OGi1AVvVZScV;hZR4>PKLNj0j~Daguy8P6p8aJ#Wk2&=#n`iu={^&Cuoy z-OsacXUkkO&0G=_vb3pgg0D+_3b#{KW7s4b3?1@R)oPF<|d zG_ke%UusA5tAf>hpXrV2XKnZ|oQZ$?y0G!zbdF41MIG$yJ~1FUD|@rgG{@}|75Z;9 zC`IibDim;0C(9(jCO=WZUxP;=Hp0PKO>Q?1=4@jTW27?wUSwYJ5=htt-^akbm08Acywa z?nLL@sHAx-9N~vRRHk5`7W$g&)+fS=7KXruHCEE+=h`IRE~j?$(+$Nuv|ud;8rc|h zjdgESU_~0ZjvT}PN$$DBE25Xd!H!-qq-$f;-@rXwG-;l9#g7}!%cbSj%7`g-jyxA_ z0$^z@B zu8A=6hEd*PVO0if!FvNKOXTxHr=b0u@#o{$PVZQee5{z+S>bCizS`MmieM)ykX4gZhRpUGL6F zOkE$%^Gm`Lbd9qfXKCCp+^1dWmdg-NcoY+kwC`Rb+&@P{ix_T1_FL9HZn=tICT|&< z$H{Fd^@RXGa-_mGD1nN-V{GI0VrHfZ-iIa5NBVY7d=2t7+GO%A8@~x-5WU&2kH3_D zqk`_7tUqx{tWQlZ-v4d6|80u@L?!?4Mp>n?rirVL^s#1|6k-NPhJuub9zPdcC}t;X zlSfrFHxP;_4{1f~)}Y-ZvKZ5b3;!(mc+UO%q3O5S6&}Cuz2Hp2pO&BT6t;!bgS)$a zV_9(B5LMlN&4d5ZT`tN%!FUkZm!{_`EP1t|i5H*9W6l-hV^L zx!qJXeRAxC%aOh`>VU)L$Lc!pX&4TJA|Y^ok|g zGfQh;Rq}&N2EcF_JpyGSyGxM67#h+Ah=vdzPjUHZ_san!2g91j89&82?co8PbaI{{V*nJH-6oY-Z7TN1S54VidmMQ1IuCPAZY34*eyYOy*dkm= zWBmKt^*?yxjMko^(;OB+>mxwSTDg_&Nl3kTd_i5(x1YIH)T#2#9z=oU?&C~X&VJh* zC&dao)x@Os%2go&Td7bn6)YQM?7DCgOVd$hW<_kcf^{WhDRMGkvZ{&qjlF;(tv{(W z7$>A%gQ_qOYF&LitAX_s zomK?d5dU)Ok%o9z@e`X9dtYzo3)In;lfq*F;iGLslrQFTj^L#bFN^{P8Tk8zAsf z#keSh$;y9iM*Sqr_l1wz=EFXba$=NjYTWp-_yIAkN(S$eb$CC-PN#PoowN+o!DMey z#1(8Z4#=6dGYIRbLJMW+NVx09_`a_oo2N5P6Z`Tkkoz#_$XUhstzb@kZOA5N-Y!&% zw`TU0oGR(@E?u*=*M7z>?Wu^u7Z1R*c26GLw>%x<^sLJa@s8Z>F+cnGE%Ai`xC$d^wpgSo<>ze4WIAUE6Lvdxh;telK?xt9P)*x!)dTu6T=j*xL zkiLe*hoAV9l5hLoLxsK<7T_|lg=&wrp z*p>*BX3Uskrs5!gzfdod;X7^vSzcbzyR-0=!S>ltmUOBo(|z6E{s8j`iup7Rq~vE7 zRnWHm0f!Stlaf!zjvNbv9ylRrAYS{z{=tAs9k;ZNLce>*n4SX8jOywN_%rLNaG}t~ z3h7z*K+BU_xjdJ`t2JLTP$_d_le(Q74H##t9LWR}SnS@N19=Bkcl~6^qYRq5j{F_{(HdqNhjv^v)WoRlgkB#D!dh)d)H`V7AzDMv^$;{C4^ z(Dq~@#uN*gj+&HwR7MHYDiPnX`kXeGWIfJ9eqj8bvQ2arlrH)hxXo0QSh5|MBTKeE zn5cG-Uw&+L!y!~bvoll=Czr{~1HZ_c!tHx2zp8bUQBFMx795^CHcZ}?I3aiRZ8Jt@ z_{Hn+8>RJw9-4C{0#Rp|wR+54)ebE0`@9tpTE5X1Xwi_`zv5^+*X5_|WJ80m%iU#! zT$4bGhj}sl7l<6Z0^tq*6CTg}-@Q72iy{Bz{wn^9sb^_OyU%K%z3+0RnnaOdp-_&A zQpL(UuCU2T_aYTHVh0pT!zd})&LdL+6U;(qJd1Bq<=yFVF^WpMKADb6Dj1$ITTdnr zkEq|WD~GPtoLj?PH)h*5-p)HVd?zkG0du&3gDZJxTqlEp5F{V2jX(sCDo9KxX{~aP zv9JUY9(aVBC`pL{5iA~t(Polf=)9)gCaTKHT4&*1Q6EEeIM(pMN8<=dWxi^di<509 z(Sc7PN2z!hPuWQ`IF#i9hKhwb)9IO*-DGnF8Ot9ttlIN585zN6DTZM(vZCYWiK?k( z7OX+Nw@PZPs(N$ve{RS5vNXIEVz8|9x=3v*9zwT!STp~?Qmg(NmI|Nik%c~5QgbqB zYEC2?PcR%9L%(TgZ6eC+%rKl7BV#Sj;Ak`*nMxvU=@)1JNif^6T!`Pdk1J#2sVZBR znwpA)HPg__PDhM$6HM5|rkcgs*u9Po^PZrmgIYu~Cg$X1z*^GJDa@6o5`#TI*T1|3 zznkgm;}!R_d3@?ilQRYNV-;l9{Kma&PfC-Er}SYZ{KO0|#PQyAu1iHR9Xr5GZ+xX1 z$YVe3p(Ocvf+RYOR}K zqi8EWh=!!)B@I*IE%9u;V<-m1N_NcrdL8g z?a`g{d?N z(w+7w)4f1)n_7Zi9{9NXYDO>am#{o);@PlG(P+lnkeTc2M^U1R`+n3=5-SaTeBM0) z%kNRG@}o6-%AToQ(590ntVT?F6@U)=&6Isy2)}N*L1f4m5LPgamROcTYv*(iPyZ7c z#oWFCg`-d6eUw=UClhNO#vmqk7d}WW7zq;B057V=1_yWz^`sQ|iCPKK-*76K4e|ht!@`_yeX!1BAATkU7xFeYV z1PZo?&s`Us8+@fNYnk8(bz&7v_8NI9_DcEqlA8O-SC!D9g9; ze)c@z0tWx5DPDXxE&%#5N?4|>b4aw8>yRvSSEiX0?vLOiRHB=2|NhsXiZGo^5&B@< zeI31A+X0#Tx|c~iFv?`0v!=blr=KbwgLb78Gt8U_OIAAE2z9eNK&!s5F3F0>=8W!r zKT;oYg44jC_`bW%@*i!jZbKwGRx%8gdl9{Hbb1jDI`x3IjAJZW5Ei6(S>l@9E&B&0 zB3*=O@#A7@kk#)a|5-MdEKD-rCeGj6t~5#M&W2oS;K0izF)(Eg#omlB(Rx#OB)aoT z#GwXoK_5A|4xhFvu3CMq($#~xb8~18q6z}|Mk(d{j*7ZYQanRcz1UwW+(Xbs<`luO zHb8f`LI0u?3T)Otb_0X6$!xt|`V&k)`37wFO)&S%>7x!C60RXywvpkR*hEEuATHLB zx@Mc;`Zkyu+td&XI? zbu%d4p@UVsAW5iTL@C%3XR+Bptl=TbDEL_lvW3tV3l)rQ*yEL9_5{2}*ri^pn2SG} zR+-zw0QeD)q(v=8w55$|>$m^`e=SRmAT^m5fBNae&*Lv;slWJ>PpPj@Hs}8)xC)6D z{+kM@_=jba4xHOwYq(92K^_%!WFTeunUd}dMB?$5o(Bjbd2zGrme0Pwz*zf#={HE= zk-#G(=Qp%0W&TPr?xACqCk52iu;mm2Y}17p~)Pp;4!j)g8pxkGAfftTfDxEj~L%JS-YlQ79DmS zN^OP@{~`ohPv?81{MqY#@>z!a4@vL8_|AX)S7Gx{=taWH*~L{AVEm8Me{X*6*Emr? zRYrPOpr*5hLko^{?~9y*>xc*tZ&YiM%KMfA@nN^p#E|?c8W35t>GBAcZmA?4{UPUr zmeY-OaEd_%oDz|Gb=lAS!M&m9W`6(rdUJ;x06jy(gJfSoPLhvmgsi*@_=ffX5ej3s65C6K;Qq$m8<98QKQ&(2=PnxU-p zy1o$8j9+3oDY6_(6~00AZvJDQX{iOaWATzEh(B-7G*n?ii^k5}^sObC8mWZ$GqLO` zFQk3dGhc3LgXh1}46U4`@|u=PV=ro6Gk-U&3KzERYKq8iQ&`M{ z66z)|kDF*;2!t0`h2%3jtiMmCM!^ZbbEazf%%%b%rN^OWL#s=lwAd}0e;=qX?usTA z9(Zn-UmlKH6$@~yBkPop@gA+{^6&}OC$4EF1IHAN{w%|uvsCbY>|1Y3+n*y}m=gfM_MD2y2ybg5Ee#G4-0q!EQiw8pk8 zajMzrRw<+V4n|~tR*qNe&{ACV!QlqG+Tu_laOhYoqD#AJ;#RB7epfO@XP3?5L=4w| zHUPUmS;`H7X9qE!R2UvMsm6A;@=1O#5XSU1sWSQI@4a zZGFgOeXx}tmJs?=@*}5@_Cw*EWqjMYiP;ArX6+xYip?F}`38=k++5@zfoItr7BvNp zF4AQz;o;d5e2Pd(OFTD+j|Q|942$uF+L(@u_{M20MhtWi8oj``eZXbdJ;tUMbs@T5 z2y5LW6wZ&jO#>UCoMKMSy6g6DP)D&BF@YE9UtKg?xrubeFm**3WxIPdoUuJm6|>fa+?m%l%uRVj9gvr3LL<9h zzwJCHAAzE&-HEze3O~GobD}0Q8+EwwOWusWqu$p8zx0Xc)rsjG`nO_2#mkonxKUW8 zdT^tvODb;w?|v&f4=o3rG4P^EMVhblocIjZ`>hvC`9QX&{`gG;d5Q(*;i-d2Xpw&Q z(C@{o(K1N_^R@FKtK=F!$oRG`ANJ|~1L!u@kE-(fHSnoz^B9DTIMV%qFHDsLJLx;a z{kiDL9o$beEYbKDFhRicb1(FhJbGP|=3Wa8j344(w4YiN#2MMp;ozg{ZV|3@nlHrC zW^uW#Wd@qdwly%Kn#Y-3@(E1S1%~fg$8y?v55Ejv(DaH8Mi2lDLbwD&5!bxl1li;o z(LdPNVw+uqJe!`sO+I-1;BEVZO!%Dz_O@S66!?*QN}cGHJ0w6VOK24*rD{2LcnT6} z?;~uSqXzkQdoCHMAs~sk5Ds?W8B0!Ldi>wV}UtY5jdD4LGbGekgSgCxr;tWYlL{X}jf-~Z+7*=_Z1Km-EIkFnc0w}d*@k;T?0~RO(X-cMt?gUsdi*&sn>-7~!6{jts1NIoIy~YrX86%dgI}?$~|o75S{0+o3V$9hED;=AC2cw%Uuz zn%c_kE}cfHoSWej)Zc!aoh-n&ZK3_#(~$eJS8R2BuOn~A=IX3_35k7z6YhpHcdy?T zKih&CDm+TZQ+|d2B7GxKmyr)L^LpH%>r{7P+NA>@T2c_uw_wh}K= z{~#_+Nj<<2q>=ewjhBlt2DB&B#;NNHLLb&fj9u06uW|Ud5K!YyMi_OJ%*>q>C92EM z;>IlY(CJs-@UI?NF>1~-TU(XGwu|5~DS1{Lf9-8?OV3s@sIuccBOP*vKf>i@a+@$VGIzJD@${J?%^ zbWR$Kh@|3gAi3o+$wOkin1d7AoX>tYxR^ft5(7R*bJfR)v>mbg6-;nitLx>KfB0b0 z^R~_tVhPem2#B0P>L0Ca+st1MG&OmIKG0GA=mB{yop&crMUe&u{f>E@M9R(+e8Ni% z*kG=uijDODHo=eQsQfCP4ijs#+ve{s^Ck58tsW-rT2IDABK( zeZdFd?BB}%F6P((0YEmP3v&Vnlj%yt>UUG<0=6c-yY4qn()-Z5_dBePVW5rSoXDv6 zv8I!H;5&?F&m}_q9}C63GW9WD8U(lJ|8ioI7FNCX;8Vp}8QfcR?|g8Q>Enk2oF z%&lWU`bbvMjQq9e!|U7LrSj=juRk{#iT|GsM%2i~OxoVX%-+Sy^;6eO^>gme-r_S3 zb~O5Iyma_Si+Yi&yu<7#aChR<4D%Ji3O83tM<(wnUtt6^PYoRjhFS$ys_g$z_7+fi zC0Q3J1h?Ss?(QDk-3jjQuEE{i-Q6L$JA~kF!GaT9-`9W7yzXXt`pv7g?&7i*wd+#% zRNYfm=j`pVNwQiy*i_M^bg6a^-)2XN1Tm228%TlQ(5#}Y2#Ex7J~7qh&TQN9^zalC z1H^Vo0E6t>kUAp;eRo}NlV8|xjI4spihPIp{qy&vUN)h8%} zz?D7T5Tc;y#e*q4HO2E?Jtj9&@8CVOJCW6!pyTmRco8Kv0Xe@6$Aa0@irX*O@&*?;0Xf=JVLq>VInqATRQrg0KFw6m) zYg7;|g=VSrv)PxGi8one{g1!M%v@sL?hdjIV?Y@vbPGfEogW)9_IE1kkDEfOO9HE> zYwdcQW>QETgH6=aL}R#kOEDiOF+E%)Fg#=%8_Y}-im<;Z@9{>u{=gWSNna4S1xp!i zAp$Z{_|iqq(#N5J$R*J%UzJ5r*LjUrR#bPJU>Hs&SnMxaTLXxHH(F*_2V~o8hA|nc zp3>%Gs8VfFxr5*6ZDUmI(nJcX0m( zYBNX@GlF#qx-^JPA^N33M@fAMI*Z(nd!S}V)@;#^^kg&FUafSD$R=LIXP^A9zF-U( zH$4Wx4}3%f0^fE3yj8TPNFT;nA0(Zw3*4 zrB&9mN&Yb5^O_1&=JFLH13`qCvwlv+Q_`9U>}z+ZaViQ51E_P&%67bG!@m8FJg-oA z(H`d$B-%*g$70WK@hf+v7$rs^YtUhvm zHNWOcwjm+ukW6e!ptxSP#z>z}0xX0Yz%+@Algwn)EqKbBhT=UeQ#cuNu`WYx%-Bnl zt29^>_UO?mZfPJheZdvvf?K5wkq2;ys>AL{1du4}apz}9PKeB>gLKFs8-Lt6Bk{L$ z6_P1=jn$8sIE!1$aC+3U=C6J{O}hRGCFHD#Mp>QK-1+@Uwp=uSp5GOs!tv3$z4&y3 z{EkQOEa__=H|_`ig#*(ZW0Wi69Q?y&zvXY_2!~9&feRWFNHTC%-zzibWhC+w#U@hI zPn2l0y1fm)%pjF&8K(9JAIvA3Rgav1vQg+`Gs4PJC1TCRjP9AgS>CotwJrypkL;^-V)FCwm@eg^K46Nze^kOIrx>Xm8;V1!@~5 zjePDRBu#2!$$GR&S@dX{ss-0edeZ{El>0Y0=SODhhkB;oX$+_ui6vV77$DHsXMPfE zpR*zx19U6vU42UUQy!XKeNK4v%ToprR+MHPX5+y|OJ~`bF`8_&k6Do)wI~fqtGDKL z{2q{jPaA2Ru{ZfTn&gIx)Cmg^tC&`5m5aL?rH34}hzcMS{Dx+q5~oU3J{zXzfQ~<( z?vtESZ-7w3vlkP#kfY<$ZR{|F~eYQaL!%@WRn^)=9Suhl8TN zY)-M#liNT`Tnt;$%w(1( zg}2^JS8f-j6fSZtO&|A5Gw6M zYKO*RxVR%@k##Du;j)qW1$B2tW+d5e%ZiNjk+~9>xOq3Pbf*7D8PDDd&M9 z{!%^(kHTc$I_nSki$=X~yO&{Vq0%Nb4HI))Tv@YL8z`rpSTGZ5f&_?C*bE^|NvfX3 zwMCad0|fcQ`mPfyF!t6C%~Ym3r?Se{+nAksT#IeQYvRYvw7-mxkF^GUjR#v(Fh8Jr zTnQ4)2a?$yLPQB1#DMN6M^NVv&PPNE$q*$7$`C_<;SDb$IjIQ4L_m1M7!}bdpV_h~lgB{l{?ze1J5!l0w-9X3U zGyVmIb>DbJScwTXf=NEc-JS0U+GF7EKz<#3I)kF(Jx)UwuESdYv3k?^F;{QYK(j_* z;Le43=8!W~vmPBsWDrleZqHsB`lL4#S-mw|pYQ2VnS7rKVF!7K3tGhMCss1ANZ0nU zwoV>GTsCu8lS_IU<>BWi2ILHb;)FaX5dqz}t>FN2dc{E6-B)bGb_nMLt(z~EV^Bs= zzW8EIrp^ij$lM_t>IEE&+E%bQl0vl{xQV1~0Zg(GqH?nwQ-%$wjU2jL*jfnIR(K+l z+rFvcKjtjLmwaD+YVNR18KQj~A*&|TsN58f?N z`sBJk#VpbL3`tzVbfI_ekY8p*s6phlB-CGkhdUCw=pot+$OIls^wlm-E)yp{;YHQ{ zvOn$l)r#42pH>%Ie~Pjoe#jk!1actbgIwzI}$(lrU6Co)9xQL(kItc^-ug$3N+ zN)toZeqHnQ(ill$2%O4%yV~Y1LUIV#M`5&emYxdJwM}HOB1(RpS}(zpFc=NJ*nq0z z)Jzl-ea6fF%bWXhv}Ne7YPtg2fMEJL#9LbfE;mTtdt!+AFU!-vZNJkH0I@(B28pvLecY{H*DArFRNkf%@R`Pa}@rm?Qm zZlL8~M%iA^0(N482GD(g_!BSJnkRszhLXunIa>~%rwmsBVQVko3=ycfP$*6$3exc` zRdX3!im3{wq@+o^sZqOV0sB^-$;3OUh8P~(qW?EyPRz80IZ54jFgA+9}W-3;&y@QUu8Qnb3`fPU#*+ymcX zqURlh7>E(hjLDVwT-mLb4{!7;te)HK;$drFN%uKLHbuLbg&+i%WY4j#~h|Vxt1INLW8So(L_McXXgO7AHCm2>eK`_a_wgl+^ zMCpgZ%Bo%K$Nm1|XS-Sqtu%Gh!SHo6Jgb}iE*?>$2Eadh8obE?;t(Mgun@J&I3 zf$2cf`-~vn#gk`p^&#{;hvUtgRhBktk9~HNoIsR(L^wB@LWC_5V)}=fBL}Ro}t*KOD{~mH*p@^f^;qsG_zZ znn3sJWi+zt(UXit*ZmSoD9e(j;lFv-%tifK%7%L;XNUeG0-ptuHU76ChapF)-ndDW zFkO!`&V#mTM~~^Y(`nsJUmywt)?khymcv#;wOuS;0Qp$#Z0vAhI3*kvG?fXe3Ckmf86&t4znPfK40DOkk2q9Y>{k6doM4N=0G z@nYkzu9$cx0o%P-$f)4PlhsOfP?$?rE#<*(LlrXNu!$#FwyLcRMduKx8gxQGN24uQ z7RKn%yEK>g==N^l#+e2*6S$)VT7!D1m^;%BwG(Jxn=N9=*Fa$V<(sd=yZ3|0TCjrZ zsiiCGSS~XOCq#tM){+X7mllexaghdMP}^4`=vsGnjc;f3n_p7T-N=7L`KdOq=9^Sz zTn#8{gU%`{i+zy5HD#$Tl!;Mf^tgGDpSUTzGH(1$W2UlkUJxtqD;ghak ztEOJQZkWo2dC(iD0DmK^=CEd(%5VG`lk9EJO{J3Ii$0Ir3Uk8-iV^(6nKu$i<`Di9r@K zFQ!;FXBGi`FBD|75XU1tFz*`bYRQEMc1qG@Y5 zVvZ@gH(q(_QzV1JO`P#2f_umu-yH4HD69&ecgz5v!RM|D@9Pa!3yXL^8N#t*Zl?&b zuOhm4TvaN8LwIH4$VPM2Tmdjfj>@8$ulxr|2)I^wizpB1V}|JnjP(s9Ok!xGhqiwm z3e4s^PrZPlPz4wY?ElN!>-VAXev2UK--BRbMu82ZX3R^#ehfO2=@UXY`W^~>E;c`Y4<6|DZq~W?QzYtE)dOD zkUxtF%5{VozKQV!Wh_HYZYUUL1XD5!$sk{tF(&ngSK*=ZNLEZPq3N&Y8L!|%JT+%b z;-scI%&^MR8Mf@$o@?HQCmMyAelx#@(; ztyb4)HG&W91!+`qTB_%@4L5f*Cz)9L*kC<%1Kq7#@mw8KI4RiM7FHB;)gGuJKgjW7 zxKT?n4Jd?ciIyc1750xn;*Tz0nVGNst; zRbA|!Qy@zaJb;pCFgVf_mU_|3OMd(o5$o6n;h7UNgVJi7b8=(Pg~3WRmp*$vT9r8aMf`?_kijY9*qyhS?hiFHQmAhqx4k zWTMe7LXER#MdLvO*OUhM5~2F3*}Q_IUHXAPl!1CEYy`E0EEEo({YH=)>83LYe87)r zxkYx6J*Eh4r(H@H3Ykd;yIL6NvOaNkg)YQ!Ao>n7Jo!=HHlR9F>U}JLK0>o;VbU1F zjSoBkSsMg>ke%s0iz6{^rf7fCccC^S)F~`6otj~ndP6RZuHi7?f=ov2))KFmw4|wo zKi0{q1G0-V{{Vj(dO}3+H!WmcHQOq1OfpXs^}*d(f=<4Y#2k7ql*Zcu+AZ?r-KfZh zx!NxU#JCmzCvVo@pHBUk&4?sL?caE_cpEetj>v{c=Eb|M=1>YkD|R9ZA=%_LAvMJ> z^K280mSmSE#!d?F(VscJsjhng@%%{VRv!e222OY~xm~AuQ#{Ys_@BE$>>}m(n3gWK z4f=&9`^kiE8W9b3_L%3NJB9m;|k zUY9SQ0b_4C<$S0gLHJfUt#9bsb*-epuUg281#OJc#j*nO8Ulf+rvHsmv%I#g)_@UZ zA6u@t+-Se15m7})tPc_%;M**jPb~6TtjKV%hrr&X)Rrlb;~iz+Q=KZ7GiQQu>jO)T zc$6~Z(04%xf1fKFKl^lTHu55(Ww4aa4=rSkH(E7=?4sXIgTsy7_H%}ofFz=>@eY1U z7aHe>V*JeuS`7tVB-BM6Y-=N1qEh9Sb9jZiRGq~y(s3_lM1E2yvYiw6%b%$XXmSND zZYjx~au4{Wyc8*UzYyIQhoSYu?6MGw)`@S=2L)%H^LZG=HL5;&!u7@O3TB(wp+0q+qbWt(23#?l3&o1 zdu)^dCgS(B6leE^YS)++mSC*+R?77Tl(TwZdpiYkMz<*piGX(~65AxVH>ir2dH4 zw!4eGy*tK=6W}CKV6qad6P!YA&$_h0&g zCdw1q=PKJc`EAprZSd~;!o5J>Qzd_uE_ZPLB(0ds0}nCsyIg7>zItBRcMgg1Fv{7q z_%0m}M{gtR_@vy1VGhB*RIX3oQ~7{aQ_5bLXeG`QUI~kH6G&tAC17KHS!DYOs(}@e zjZ^1@34@$gL>r_jto3H@gN^8%L!;?2UV)u|L7MBk#OKV|L!MFxN7H|u(mGM_5p?*8 zpe~)nbB)n5x(n`2l^E7SW%GS-1PVAo7BQ9SW8Qg|6FTuxNvtBHqN)?$g0xP-R|!8W zX&HQhW&VulO{VowAzAQzgAPsvRCi8b!b?(yFr9%LzR{&q_LdS=}sc%(-pEdt>W z`Q(=fEI0z`M?D~qeEY%h z%M|A(CwGf(SLYj~9%2R8W87@sxR8*JkU~hf*j4JH-k4=P43;Do8fN@)vtyNSeN?d7f@_Ht)J~b(8)&nLa!yS6wtuvge+wlA38{lW$mYA|j@a zO+xlW(qgSL%%aKdybn}^ZVJuuMw?)*9mztFA9?sma6BLS32e*p!iOrzcUospllr(l zLsW@rTs^N;;G|$fFLy+P zQ@)8@UQ9V)`f<6HE-w);J%yLot%V^850q`D3`0W2E1`#Q`w+krMzhG!{}j8+CFunu z#e<5d86DvQDRGKsBSz9<7s4X@Bbgz%J&`%We2rL!6b>beg>6|4gNEt=`D#6a_F9udtCDAgC| zxg}dx+7r~enD`(xecQC#)^=YIuAe!c0jYMi&p)76BQn}mY1YB-7|<@aq;nBqU(~ zohC}+GxO*aO3n#t4h>#jd?BywPK$lU9vPFDVt=@~qbQuKhD}{y!W+zA%_n zRyKgcE&l(-tW<0)|KVt>Q$X`bTscPqxp5f~6#Q9Zu8N*PgS#zBahO zJ)Lp`xv!}r^tbwdly>??MLto;ptM6!qld+;pcS=)6`*z7S|Y|cjNm)4UVl~{1{Cnv z)9mcJyt7xYW0IxkA8 zwU&O6-Yg(?*+-bHe^1dctyH;7E^gG@C}SHZAct>iCHqb1GR-;oqF$+R=c~w=MNwl} zd(1;|Q3N_Cm`#=ABFYm1#%*>w$@d=Qr?%6MMtmFhV#7C5Qy9`r(BcDE%&)FFDJfb7 zir=kc=44FSC{C6Vw>|woBNy*OGwWMuv?G_`z!^Fo z;o+>ZdH2{gRB|Pe4CsX0j_c#(R*GYqlH|qX)A`Hw-4N8%a&_ zRT2d`|4<_nrg|zKT|@ES`7}E;wAPldMw1uL4Rgwn;nV(y!pc+Pt9{6OPh9nCKl)fE zl?xpABa#bv{LFH)IUSPS{5K-9A?{p_LL7S$!Bx^G7sM5@#7wV|Qb@F0Wc%BS>O$e9 zB(Cof#Zkt?@I5Zk$~V2k)5?w(DuZ^U-#CM30K|shyQU11F1d;ICrrol z6P_7Fc2a||(B4uTIAm0Gh++aUGBmW{seRw&UXPFpwH6@(0Vz=Z2Wjo!F2a8Iyt6di z^%Ccs-m)gHWV*bp{D2B*5RpbDfd~cFL4?61fCBW?2M8a;!GqH{m=SlPrL-;b7K*?u zEzMcyEsjNj3YMs~MN$+-cFd?Ic-CR2+u}j1O5s$#@P~MM#DRKH6jMuni=T>o7{E?l8wu zw*{w?1xx83{0~A~n!#sP1YEsY&rzNcgl~nRQ%RgU;E)DUJ~RK)*?ACjm9MQn_DhKDok6 zvF6(5V$|ZsGm6kshJ~^>Wt1VhFitFY!Xh3?XyM_9gYlvV@@L}!EbZ+Cvc0URVypPc zVyif6?|K#UzF)0liC?UKNi=9$F%F=8(yM|DIX$eGCqQd3^slQ}-R%``WyFIE{+uG> z(gcz3=SE^N;?n!W*e|t{2&bXHPLIbeYCT7s;rq7ifhB5WH%|vM&N8kG+9GH^Blijh z{D8I4O6zWssRj(RsBzi`Aw?;){=M((#5~y4v^>F@<{o5fHx-g~l|>Y|rl5<8BZYcWt+fh+75CVbu5enxhdg;B zS8uzR^?19KPi)^m@aEX-Xkls><`b9u(!vjYSQTW;I@Cshh1iV%t&abG^Wm;uJfiCQ zKo$_<-rT`ELLBtNtYxI0o+g;5}Z<-WB!e^q9=7I@Z$hA?}Ge1+_0ZljRpD2ub4x14Mz zs7Ucar1@!l0-|Inr6`w7SahQ)8VqQJOGT!OSVFam+PtvKaYH{a>oG$`3y zMAJ%f@crm8;m;>#Ov{-XMY^7I8`aY!oXkuz-73AQipx#2XCxh3$dJxF9p~rK3ahQi?VPCCNpUK2z1|1{~C=jNsdCcTxe&jfy znt}=LFkqw81hQfG1W>h*HB$a0cs!;;7-FeND(S0Zg{h~A^|Pd|JNignb+El_m__!fl2 z+Qw*S$5TPf&5|o`e&)}J&&5L|e%}Qz7H62tuNO0047f6u>LP-m;Vi|uj6G@jQE^pE zs+;gc`@mH?One2m(?J@N*!T*;K~PHjQ0x_vq=|N~EO4bd1Y8rb!UnI-;27$xy7?sR zey1?cV&Oet0hoR>`7Z=2HnkmW~*tApcum_s%BG zL$t$I!c`*aW)eB?1o9`Y8=s}7ufvcbp1 zubAR>eS(8}qlihCh7CeFgkq>KjA$_CO-KS&tOy1&D|HdB#^pLDa6eLYII1|W^%^3fZmmW+cU%|O@fZhQHglOrY=~QiDD-A{L(!joMUy?i{di-Wt%SbW;usj$Zw~C=kWj*P8Pxo1jB;w z?hT2c^q$5xJ#WiHHom=Wt45b`{O9oFWS4o7dKpbGzyj9KlYedl;Jw^q#TsRn!yZUo$%Vf7B9h4YgHnTY9M-UJZk?{K6;Cm;FVxW{htB)QqiR?#>r-XUN-w1j26pdz zXWR&lUJRIwjXnm9MiTP0K6$$`_-~_m#(225n}3IP&ZMr-FtNCpF{e;ZKQ-e!-f$0F zrEn?pi1q;C5(>lCFwQCZSb(9+6YqhNVx;2jR)K5EJ6qCqG$%;-c{`EaDCG05HJ9|! zmk#k(LL^zdEpeGNmIB$M0}GXJ4nECG<7i8C8xyeE3uc7{-a_)H2|3v}KZ*Ur8_Wa9 zor#E^{6w!7W-WDWRI#DGq3aoVrLkf?{9?w$bq^APuNED+7jWRnx{I4CO5WCJ$lzz7 zHnLnwM1O31N8AAK!N!EMe_b!>7Bs`cZ_z#X%D8Yi6b||2oOh0!<b_~5R!$;2kxcsIITT^RU^G~Pi_}lxBBYK07*XZ|rS1TJ z(vpT}U!Vhh2s)6hUe5BLdlX{4$%OYEc$@wFT^ToS-9N>m)nd3`@kFusikCNrb)~j< zLdT88w&;%iN{%2qLgIc!?sw#z+9?7#ZVhQgj@WMlzt-d6@r2ShY>v0w0V`6w!z>@v zPSaBJLldlq?gIUU>qZmf|kw*@C@A4IGmWgF}&U99xR~zeB_**D8O)qcgXP2 zV@u+V$ut~6#_@9o?f>b?&{0QiXUjx~)=?z-|3h@J%bqw7Lzrd0w$w!WT z2q(7WIs4h)CX)9{952RVq53ep(`bL@t?OxNJ?=Xt@zHJ&N(byV@RpI)i$7&mzNfHaRwbVn9q9~{9 zE<`zqXl+D6&&!owK6tN}@_g~?rZ=Zk>0P(*@CYd3Y9UZ-tNe+u|DEbp(FJuOHH~O8 zP@I|6!K2^0?fblEK1@VeL}5jS`nlkxo(Cn768>^za5XbCRXbzDjyWzNRd%)r*lH8T zv~X&;=$rwr>W)M6F=7w+$pGr1FtSabXmLN;(7FjvIISC=+7850IQ}lxb9f@Y9`)4(v? z!S}$knJ+s0`b!vwKe=w7nD5Hw1s2Sz_b&9rDb1adpk*0p`S|~GknJ1S*X-i1bxzzh zbRz_ob>t{u=%;YR53Z<$mz0LXe=-|-W#M5$GJ!O02#*COIx7f$Y6xA5!0R{+jg?%n zv9oCq%qC7%(cO@D?^ro4zeRC_UJFT`1IyN6-3T{w(TNp8HaXDix5hK+c|sj#5c?*7 z)Pp#rLiVjxQ(swxo$lo4OKBy2dC5h`r|$d11PS3D%##ZDa7#>5Y`34-m|&8dlRTFa zkt7FNGW&f}!t&_bUqOc@4u&XDeg(qM^feW_rG5SiHH~~z*4`LM@@QkiM{#|_=&I9O zaV>pSnU#i|sbI>BdZrV8gXK2aa}2(rNA0vaOuzYa=-3!78~1Uffqfbw`}Kb7vgTVAvYk_m!c|woPx# z;oQ(i_jORr9?CTjnmTc5F|NcIKQOL49@)mXdXpzuN;}*KoLFpKq9SoplDj4xt7@Hu zRnp89#SH~T6<5T&Da5`|9Sgj^u|!>!njWVgYqFZ1zlF%R>WNfq;fEqjl>d-TWr4si zs`y(iStaPun&V&W9HQ<_BN=N@VIK|8c_SC8vn2+9Hbs6yAa@8u@yQpav^PLAG=-ZX z>S| z)1UD@yv2xpBl*QmOs7BQhfD|cIRasV_#;8`u60mEYuZw^0e6Zge{{D#4))p$Uq=8w zQ#8LIqL1)bturpfbBk!!xuS@Tt95VQfeRWzl$T_CRnUzJ(n@5P9QH_`!hl&F%Uw2$$5xrg|YA zAosxu7#3bR#C%EMK#k#&!LD5T*(U<44bA!HHPYV27@tg5jX)6p z>Ciag6<4-9GJlimunzNDg>_>XX=7Ka%pR9-uC6Y0MY(qB8S+h5?uk=&&7~6Y738hV z-j?(=g1k!JhSDc$(<~yHf$z3x(NvW4ZM@QGrJ&{^ddk^m=f{PkTtLePkwez+_qS-5+mGxLRRa|BEPyr-P zFB_TBc1Tu^Di@A;CFSM@}5c4wSMEw4G-a+7F*HY$+#?UTn zn)I$BNL75_P*bFGgjn(6b4!N4sVNAuo);3_Bcz!e2{yvyfVOypHm z7h7+0Q%0}IwAdq=vu|+;Sr5CF+~Wu?#kPDByvr6h&~{U1Cx=6_8;oakt=iN27Cwg* zF1!%!=a>7+oQ|oq^DAQ4&$Xm|qY3Fh=*<=x`26KNg^tz7UoE;Q3r-AA4jN(_&h>oZ z22V}8Lo%~YYMe7#qhD?^@rPf*Z`td+!;brxHz$1PpFXc~wkEw;7j|d89Ei7QcHDoq zJ$rkXwcbE;2J-^gA~pnUc9H$(Hu3+RH5mOXIsG@zz<(Vvs~zj&sA2k;&`;D$L(0?n zksXok)ze6QBUu5WO!_tu2n0}XBAGu7%%Vx4<2G_d6S9=~T%~#LDpR#s?iQ9l2P%1a zE92{P_qqEfN8a}VEXUErWyv@MynCYKVB(4Iz&q#8!R5{U{Ina0Ba~lc#vcqdCz9w( zkOhgo%Af&?zUgJA8&A!Sl7ccfH~rk!Y^!Pj`enRZN97JP6(6<;E?WLln3}}}r9crpBED>xpqWg3=UtWLP&^z{^p_ahC7Rw7tz3 z#oRE2>Atgt5NCPdD7rDSGNsz}d?C?aJl4O*%?BZwo5^TOi$Mury3lHIaJ{Ydl|jtQ zW-e(fG7UiI*JW-Ab5dSlvd|cU(l{W6BD*Xq+nve?-abtU8Kq7ssYMbo-zONfJcx*IkSvFubJA6=28~V^^CZY%cW9YEg#0diCV% zB%99)q36QH)1m5?l3G)EBl{y`VQyPy@ZbXxs+iYx%*G~fTrzG#Gv6;7OL@V%RF!Ap zLAk7CMTWzaN^60LKvAoTCHSaIn{FI)HRxn(SW~5fWXh{8U2LCZ6?b$E=fDnenci&r zC1_1**l5%V=`n;fwaI5F=9H3T2OW|PdY+sQ`%7EG3U*GbXk9vL(?1^!W>^QQS-&1B ztyi9*?Q4|aN+3@LH$;exFStpl#Hgo5G7@W`FK{!fdQ7M@FzFz(KT%VQ-}@}(`+B}i zU&FsVljVocSa(nUoDKH&n!PZmSdc%uKdM|>Bl?2tK}Cu32L@nwz3~6lnf@r! zM}L2~(GB$)W5;TGg*JU$iXqN-c+JXXj_SZX1f?YHw-0>}(q|4QcEODFRp7e>FaLP- z;w4G>YHuC4>P84<|CjasMtO#liCo^ zY0hJ5iYOr{NgbclRCT*cfpb#4DVupU+s_a1gH9%D-amPx3;7@vEJaD2_(gTPVZv{t z4%{>Q;zxhqApxmZh!A58q|*9?j@KV@FJ=@U+Rq`{p|BIPWgq+snVqN$;{O3>80wQG zK3TZGQX*?tR+fTf31tg$qila}I3wyV71L1e8L?5sD^Y@xe^#_h=M1fyN^ zN8)cDSm_n7k;zAT{;;LgORSu@NCr_T{eqE@m$Z!=i46W9hZ}{04>{&{xo{8yrYB8f z&#BI`w1u!6F1FmvMn>m8iC@q-+Nq1%eC+eo5n@@c^~Cfnj)(Kyt6p)a=y z;Q~%c9@P;65}#?~e@buO&}@*wDoe7Y1FtK_;bdt3vc3gJ&pr7=Em0G@Z9}elWz+~= z14WFybXGKEz%T#YQ0LOs^USHgr>K4ho!dOc9!XxqEgs( z_T?66y$W0I6}Nri8{_&n%=n^B;&M+gZC{!2K4{5BY@-Rv+iHOar1k71n_-+DBy`*% z3r;9uF^ED-L<-lLL9!ny<8BMa^>R!wfg--vXT{PI>_OUYDnQ^5mEC{i-WXlSDj-;=LKdg zesdllPgSy-wnyTZbJf{Wag0hCkI44)osR$e#Q^-p!%qR#tP-7 z_rOGa?0RZn0!uwbd8#s&=!f@ zROV>B9%OFObFdYv=r{!myU8WFC3b95T(L&Olx@D3QZ@|i%Ab-uRbuH@;Y#{)phjJ` zaE=m?B!u8SP@S@Bwe4`4X(=rag=GO6D=4s8PTFiTHVg?gm-pYFpzrD^h=C^6tk3po zSI2E@X|qiiTsFFK66$Aa!$Yu47%Fo4rOEdnH2bfG*MA5UOO?fZnw@T@n!mvKg@s0v zH}i&lPMMf=BcnqIzbY3Kd=^RV^5Hz$yl8t&frec-C^xY(`g@NiII2%VS4E$8`Fy9f zR-P|~6h8)>^jGn7IxdlKQ5>hE4x04xMjsVcfR}gp5_brRET2MsL{1uVyyH|Kbp5Fe zlxM}bX-9@hub=KgT5$|c1J!2-Z9~uVPZ7eJGQY%SNP)xqiOgU3 z+ifY+PuCOD=v*DDn?sUkfuHg{@=A9{wNC`RjKW++>4ZPR%6{a{N|+3izHZdT2IAw` z_=kls__3-{xFmH!7-TC7Lobqy3;?eXxy@RPVK50-PM4e<1iLw~`&;tCeeERN`4y{5 zXIG%zOE%aEWKAfy)t5Yo%_H)F)X z*237(>3^X^&We|k>-&TfGz|tS?8PtNpMTN=nvUVTORNw{olk;sC&Zo1XdMCz0`(@T zMn?CW4DK#UIpdP>F3s6dCg1s&0BjCvG(kmvO6v57Q2( zVh%|crSI2B6Ok9dqmeG7gQ9V$LUhAQ_d5A+7DBlwh(dV$Rss!tCFi4Vq0n)wtCqr@ zu1t<~sHE;%=W(Gon~LGoRW>fLR6B7a3)ajT@ECnZEaCckeLqIoaRg+!LTJ`)aws#H zp7CR0%3tdjPi3T8Cq_=4@&;s22tk7>H6T0U!W5&G02f3cdqIseYQ=0{YyPwcr}Y+^ z)jgE_ke)3v9(HK)Aw5lm8mjccmAvfcofJ3pGzaf*@AMfk_i_H`JAJRa_opS)J8IIb z_;JbpPbk6DOBL2l%?lRuB5SOI$npb0=&@+%iuCeFKIwR~aU{rOvw|CvYW^_zJt0Ws z<_Kj10~(pkzoy?NGut|RJGy{-fUQyp;G>AFQ1UbaCqG!B=86#bj`5I9Lm90+#(ruZ z9~RGDF~!@EUPlb~%X5~5OPksYYato_oXkOQ;Y2!_jTrumT>LZ4u!6M0RH z5EESc?CTu1ScFR(yAn}2@&{IIV*_Yg@6lGV+?j=^7$;Gg5RYcgSbz8C`eq+>PYOy$ zJ83<3W4c;UDODP{du4UE(fsh6?nDz|Fy&kzkq?Dpxi|yz!)hpgyTFpx)n-2RRYUkJ zoC2p7ZdFY)wQyClj{Ro06L6+;Y56t?9M8k7Wvkk`bfSJJbMf7dwGf;)TMFYJ!lv?f z>ao(Okdqvr=s#tvm_kWX?Hks8G)AR%3>c$k?1G*LJtMIz?z(RL!q%OaM(;!mHc6Au zU1kRONtdq)UCw8DqWSiYT^9bWUk#w21O!+L|DU@0zxezC0U!U&<-hly!5@fLjA+b1NfS2V+BHb33O$s{%;TQcX=v|Dv9hk)*9>ondDA#{2;gkpcl}`P7z# z2B`VlW64Vae?a-|?oa3dEBoDMjsUu1pKiY;Q9^rk3tE! z{eP>;2*^r^iYO`5$%wv3_^rmj8wLa|{;6aE?thah_@^2G{-HmW-hb8jm$1P;Ww3A6od` zUwaSd?kAm}2Y?v^T)&ZI|526!=Kc?Gfaf)JFm`m52B^Io+x%OA;ypa2M`3>lpew^* zf6s;Z1AY|qZ{YzH+*Zzx04^C(b1P#3Lqk9dGWs_9rvI&htlLpg4?u?p13LUSMZiDG z0>R%lAm*SCP)}6>Fjb1%S{qB-+FCl>{e9PvZ4aY80Bo)U&=G(bvOkp!fUW#Z*ZdBx z1~5E;QtNNF_xHGuI~e=r0JK%WMf4|BAfPq6zr~gKx7GbU9``Cak1xQw*b(024blHS zo{giEzLnK~v*BOHH&%3jX~l>d2#DY>&ldzp@%x+q8^8ec8{XeP-9eLe z{$J28rT!L8+Sc^HzU@GBexQ25pjQQWVH|$}%aZ+DFnNG>i-4n}v9$p}F_%Qz)==L{ z7+|mt<_6Ax@Vvh_+V^tze>7Ai|Nq^}-*>}%o!>t&fzO6ZBt23g4r?*WLL8)z|!gQsH?I_!|Jg%KoqXrnK`% z*#H3k$!LFz{d`~fz3$E*mEkP@qw>F{PyV|*_#XbfmdYRSsaF3L{(o6Yyl?2e;=vyc zeYXFPhW_;Y|3&}cJ^Xv>{y*R^9sUXaowxiR_B~_$AFv8e{{;KzZHV`n?^%ogz|8ab zC(PdyGydDm_?{p5|Ec8cRTBuJD7=ktkw-{nV;#0k5o;S?!9D>&LLkM0AP6Feg`f{0 zDQpB`k<`JrvB<<-J;OKd%+1!z`DQP}{M_XnsTQvW)#kKd4xjO+0(FK~P*t8f?34gT zNeb{dG5{jMk|Z%xPNd?)Kr$uFk;z0bG4oFYGnNlV6q8Vd`WhQhkz5p#m^vZSc48n^ z)8XlE1_e=c^$WG1no(|j8Tc`PgwP}{$Z2MV1V$=SXvP)gXKtqW)?5PUcJu&?e*#h! zqs>gH(jDQk$9cz8;-w$cc*dE1}qLepfsBCXA@(bAJ66ft0aCq$Wrcq)WXX{0nm+#w=uBj1o9rLyA i;x|p)^~-yfPOPa3(|vBayXKzd_WEY_lIM<*>kEH?T**n)L|d4_rKbms*8e?2n)Ki&=O?<4J<%>V7R{?iBg zUq0qeh9)+q|G%!t|L*GUWa!{v>h%8_vhfuLJO%*-l>FD9;-818|MyT)4^v}T7kei< zV;e(f=M?n_Z{$_P@0tV}PfeKL81;-1K%hd2jPC7;DA>wd?+UcoR*R#W($?M))u>gd zdn}ehUd3m+8_k40@?K-j2J`KZyalp1AAH~OemS09)oMlsj}Ip=JKY&CS%B#&?VkHQ zbp0RoxZiO54G4JffN7@lTM-EP35bJi7)bfM8EqjCYYcnn{VS&2QEn5KJxt6fN4jA5 z35`f+Sduq7yq)PG@7FzVPY-Jv0EQW7A|u)@XZ43(l=9JiPNOEX-?M91MKSb8LB7*ix_1 zP;pX`ce%>4<(cfvymJ}t(%d{Q0z=8R1bQv29j?-2sm$ONs(@PIGdy@9R%Ta=*YdEA z&d3ZtFAJZsYhJ)vf*)knsFyO}Y=592S4#xG?1vm(x|kp{tuD2chGmvsN`Pzy^ zUV@_Yn2NIb#=1!#ZV!rb;}EdSGKZGG!tBKgC=%PM#u0uc?HGxKOZ9pZ7_T|A*1#Qy zf$Rm!>2sH}rRl&DRAmM3N>s80GU*RYMpwv5BW)XS&*^g<%=05?3M^7)<&I1!aW`0s z&|9LT!iow_V9V%qPOf<7C7X$)ABMd05mgn;wfKiF_Pq*?msg;KGz$4;ER)t4nxfpQ z>NJFiAO81*#gMz>5y%b5ZK(1yt)P-Kre5KQC3YH?naRFiq=b zJGw+CtdguK-J8U(x~Pj8^~>uka;Ov~%`0$5NxZck$uYX(d75Q@4yqjY9dl38H@E9W2#wa*RJ8+Fq#c%!`8 zF?p_di`A_*fY_}yp!i7Tkv@$(lKu;SFRYmSf^wOzrJS-o78?qR;M;FFvyw!qlC@@U zjOGrCIjd*tv02Jqu9Kx`kDN_RazI{F##4p9_>71}duTTOg+3*QxxW8&f8T&T>SwHa-%rxr1sm0msfK|vl&OQI zX&*rkG-JX~)q&mH7lf~Zy}Z}7U|~=(6%wDv zXggVP{CTshNqV&AXub;T_43>o*E6$B1-0epUkaVp40X1y$=!96kgUo zQAWHAQ4ln6PPLTKRtm|vB90=hFW>%6&a3Vxd&+4)-RLEH+7&*$N#o@kG-=jl9>#1{ zmA_w6RaTULUkhTUPuuirdzrP-E*H7VLpxQbZ1nM0jU1g9WR`IdH%?agZbu88eAX!D zmmH#^1wp!tnHJ!>H+UD~o#?l=TaYt97?r-!bgjq6OdAYtzBP>2kC7H6i5oHEphkp zXwA+ySm+72eNV~9feSko<*D;cffr6e&cy%;qNZSI2spGwz0q^o0ocX!Xj{Q3F_FFy zb;xtD7*4?WLK3%$cb>s{W9Q&3(PD@F(i%LS6uG@nCDEj-8k$@3;>2k48067l8*}^f zDK1+;{IRWcX9VNm7Upz%V#NEjq}`_K^*p)Vza)4Z!DS(t4nSte6V)4t{4zL9S!Rt( zG{n^ISmKsVo2QDFceIUfS|WN{o_BbkcY09LPkC0>vo5ZtVTJ0qcQ!3~XP=nGv1 zJo-kS`382}lM(yeA}-?&GjM11ZN}hk3NG%6OLm!3viy4Se)z*zljGWqNMTRT z;|}+51hU6pvm>GAzY!k9b#*Qp!4uUd{BHHM=>z7(TUQ&61wgNHQl)lHtm$Tv{V8?< zk}YmbB)h;VK~-h)&*iAh&3CrB-vGbFBvrq;kS955Nc(!x4d&^0{<$rOYwALrDOsQ4 zW9hcssstO*k44cLQ%oj=Xj9q|<70?iI9T0cS6YjjP+BYXQepHl8|&Ti8B#65lL2A6H|t*f&z#g5Xapa^l!(# z{3O494S#6RU}ob3Jn||E zC_hOlR0p5`1g7@8F13LjC$1vO%+&M*gnInCca^I=)t1-j*Sz;lm3mi<95Fr|0BFc+ zu7#3Ed?%B~Ue(h6*BMLO%@xB;6k8MgnjgMWjopLNBA9B0ynXzYzi2B4s?*J`Z6}M9 z`z+Ety}W&Vn)+KW)ql|+_RkE4d_;T&aHIwh$qd6>IR;n7%`5{W&?Roh16J=vX;Sz(L_>M=+Ys zq^-2;)!L)YO}{_rzt7a@)sp)32M`bz91sxMKhIRb(8WT~+1b?A$j0=4K%d&1KK5VG zM<=1BS#3*W%xxfHDuYZ2T)91JD|?Vi-HHU3Og$negw~995uVc6)mWhJ)ggOB&AZU~ z;+wRRur(+D;Qd|Ry1T9`ogYs2CU`ULoyq=?b2F9I_Wd<`@eSet_Z_{@6D^!vJEqVt z7M(~r1dExgu9$o!tEoXH#W-y6TTZhWy|CWY%}8N?!c8UQ{2+>vnqAL)pG@)nixQ8l3#ZDiH- zOAKW<`aqk}2YVOsgkJn^o1&MTTwm?Z7nNVZ!KSmh7M)yntYx|-(mIs}Tx+Ef#=Eeb zJ9eLf!`0Kz#>vad)zZ+)?`guu&dSx$k&oM1Q_$x<)K7U9#kDG4GatB$p>pq5WZX$- z+bQkIXhgxm#Ln+Iq9S7Cy@D8Adlo&0bgaHEnN4(v-8hvgE=x3sj3_QM^-ND`E*D2f z4Iz`_sKU){3q9S;{>cO(!Duz;Y3V>sB$$VB=phfv*F;pxRVz!1i{0*%QQ}ZK7ARHbULmBp8A7 zz93B7-OS_TvFL!)V<3|WKIDk{_$C$Gpw}Sl&YiUR!TvO4y;-YbzS-gk4rR>KFm}GQ z(y0jd8o`kZO}4_uCe0pGLAzRy6L%bc)KC-;ODa9{Yw9EW>F00Sp=p|Fb9e~NQ=P`B zC!*duS%7J&u3)s-SO#I-pRb^G3l)C}q=_KtlE@yr-(=Lj`miy-Az_O=REB;!DvnTN zk=+WzuHH6>mN8TjMp^0|_N20YLb$W={LE4B#2oP$p*e=t9*Pq^A%CUB9JhGQs200( zhV4T*OKUIM`{b^3Xt<+B?OS08(%d=UIwYp@E81^+&57K#eg*w1-RZiVpAJkC=VrCOt1UIT|y#IB$V5l}&G8kO{eaZFLGx3RoJ&N;4O9yunGUqu?ea z_(0(#OeEfb*Vg)R}!1*oms#bJAGG83BAD4+Q+e;y0;RhEa~F zz`Oo_z!J)KI)+4vzOeSt1mYkFe~D1AC&ZuJlB8ZY14)uVQUWpt%(YK?-imDdvIW)V zRfLI>P%DVp;?PA_5xP*fg4*Bu^H^|KM6F7~Kh?ER!vNwOE@2!hj?JMnQTrdAW6x)! zFK1p03IGKY^f7g%?fq*BSY7TX2QP&EbQ6jo4k+)%X3L5vc zBgoN{WOq|@unntspvNN5q`cUiO$=zt{SNkTy)J;pf8r@$(il*!`~7x?@Y+~G>*n=) zOt^zka-hG2j|*o5^BkI2ePjqWjvNycLpt5jBDy$f4bZ&vTS|W08a~$$$HtK(P_@p8 zMUUu?UUT1Fa_^fo7g>yK@y-M_sE#1BGpaSmh3BY-tK<}L=50V1>P|u{*fT7yL9RD% za;^U1y<;Kt&T{dD>E)ZssbT7R>Ro$ff_p}?@(ZTg`{ZFNUj&X*n&bB+ub zq)0d%*cs3S34)l8068Ko@q8d;1PK@jgqshQOc2Q6-z+H zuPims#_D_e+utKms(L7Wt2x0o!w2`NyC1Z>_E%p=yZCiLYmpC*HUjFTD@EG0@>Xl; z;$Xa3UV!idY2D{4WqokC@;~{7k5xzUT5wfI;h|+z4l1~DBMmU}V}?co!o46N9BNe0 zDe;atV+Pq`p$GL2g&;#xdAflKR2&Wfj1gwlTZN@PYYIya%6gjBly&E7;;c>AYIA>a z@#lO2-Roe_1)23y=JfMB-bqXw)bg2jxp{WnzS(AJrTm39v109e?kErRK^uE&eT3(g3KwitamUX%r=36jqIb}JtYaiXHS`+tt!u3-IgyIxh2=i!{PiU ziqcdkUO^Rtvovc=tj8HeMGMkbTq$kRq8G)N^)~Cdvy(;*i!M`wXNVS4Fc2VD<8$zn zvXs3mw`%va+$rukKI0F?fHJ01Tk5D9*{1GmEDpj4z7$KB^@mO0_x7xG8+Lx0IRqyz zm27+_T=9*OevoYpwS>f`eMTl{LyFZYqUGv8_yQoP6ME$)Z;yA3lf*2m*yiUvi(#uf z1;-wx@s7ARy%wQ~djP3Us92T<6aCTY08l35F3~rW@xs znO_V+$s1G;i=QBEw1vU3Pwk}i{3#nP>~+JmQW|4q(Pt8clH$ynV2|s1=N#aLJ-&Wz zS2UV#f?iy?BhFm8W6(4iv~GSHV^NXyko0FBm}Rcrg{kU}nVx+G#`@!mHJpHyeqPKr z6Lgrdr^rU7D#=j(%P zZ|R{u#_gd#2JjFX^5)tZ`w61jvtP`x1qgLI5q4`4#CapsWEhp1ESm%l$mnGpL}T+| z?@wZ5@hJuvXD{AH#L6?4?la@&8AnTMk;H+}wz06RNj^X;ZwuB7si%=< z9lJM)rS=>{;H#5lp=D(=n(k5}s5D6G>Bm1% z&25b2t5a2TTv;n8-Fpr!v`+I`w|y7B3>^u0nue5~^_Wj1wrQ)-Q{lX7w%LTLapV}S zU}NSrz$z1N7!KELA^`=x@CI}k?Cp3e+bR>gqs{FQrlJMm(rzflHaaJErBK6;Un&*o zH63;rpuq`y`-PhKB30SJ#oBo+q?##C--15`GXw<&iTO3N-?|szKyHO}5!NTPF%2u0 zmHwP{wF&^k`4!WVVGV8n=aBM5Z_@{{(DMnN!rJZ?_-Ge=P#dHHVpXj6BHxeS%7RQZ z5;1Zg@2h}-gOZtugHqU(XE*BOw#HJSWIx*1at zRrG=z+kI=U#BiDXcaYY~o@1WMB|UH8m?VuAep2nWY@x&2tkj;XN(pgME;mT(R%;^N zjPg%R-0mgo>D{8sXwPeCo4nzPuhh=>sCHglSrKvvajw*GSpq}{{cl#mebopG^vLAA zj^Jf|{X7*fEi-Jpe9;mo5bN{nL(fGVge-dF8Ue0cf&mB=B<1|1TRRMi;XYY)+8Je6 z)|y$Pr8=f}|Gi8F#A>t_tDn>=HZa$+R_58Ntusu@2Is4c*i`s&Ov~aKz)5xBW)nto zHe0i2-#|aF*kXsT+5^IFNf%zBYF>ZXzUC^W&C5k~Im9Hr%A4Gwy8-Mk2l#(8j_49a z+7)`}R12t))N8XC#916}iuKwGx+@ThYtWOO?D zFTB$Pyvq-=m#?4yUaVOWSj9I3{}m=cfq*#vIRX7!u|^_eZ)|8IV(IMSWNGB;Vrg&p zFV0>`TN+ys6LOpaue7UiNVcXV$m-QIYJ`mi2d> zN*=@RX=EOenr3$$(wpB_CAIABy)kR~B?22(#`W;uA0{H&-*Wy&8rL83?QX|_zrLmQShDC*nAJ$v8q7U*1(xBK1(s;q##37*2IvNSh zwr=LR#R|?jr6hQdK(?fo^jC?eiF;+s1TB)E_FBT*H)&U{lIz3qbtKQ2HY+B%ep7+n z_ytKe!a7?!kSGrXf&p(ojv44{`cs3Thr55=<*1gV$VLP|dskx$GL&l5#61gJ^+VqN z9lx@G1&;#?massD3C#waJrev|_Q@qTPP-4ixHhrEBevY5SFq5d8Q4qo1sobpScc-% zlIapW4WVEJwW*mg4cc2!OmwO-agkj!o}pVvG$tjGyP_80MsjiUD8o|l1)goh9L zS`Q>&2k7Nq1h4u!?d#QW4*DljC&<4?!i!gRKm1=YOW?0q#PZLP@IU+niGq{8ho_*c zi-oD3i>0yQ|0*}iS9VB(D7>J_Bc_&)s`V>Uw$>q)G_RKpcNod+9FgK(P z%wk(;FCf9Dit(O)wTUp7%@pjrN-(0z@I2k{h& z4~F7+(KryqTkF$=|I@hh${li3@!mq=>Z}!_Wp_`D>c@#H29zqaM;mpxa;5b0y;dYU z=>8MxjZ5&o-fuq)iJdJT?fk*|EhMk7g%2fGat8fS80}&QYkaDB+Yeim^_98)?{BZ&SKW{kHEC(riD; zhlrcGqj$)(j!z6}4Epde;Noe%4KH~04;znvE3$&p$l+!b_DaXNtv|Yg>(s(wBAM=? zkd)yySesZSr_g#ctWx5@Hu7K!dX1|%JHv>WYg{?5tVAJ4Z16Gc8;#GIH|jI1bvK4FrXAHDcrx5L zkM{>n8}B?MRqQ8SYnMVh8@B)V05kEL+D-f$T)cmkQigvHFlA3?7gO86(e+nObg?vb zmN2yYt402cA&ODcR@PQU`C^mgAjFyIVUf@-ZVA>_qL(0Tra~b>1tEnf(K{#1CJPI7 zJ{Xq-wtsrp(#J7B53+}w;h0%UWB48I`yyVkD@Sy=GGWsAykYI@ebv&}vMTrW{t?Fy z+#PQ3dpc75ixU5w;cUoNhC2OjfH=nfE#E**j!3DiV9yrZ8S2>AVz3xpk&{lMfnr1! zUxh}}qZ)D2qYRN+Bjq4<>#!8vnr~~gOR1ZD#*E=)8=%sI;kT;5+0HOSUygZGV4cfcL~k zev9V}!;^)ZwQgHl%TqF4kftMTOW}HGHhPR5xupqM=m`xsqSV@km=wJ2rWRMtX2F`> z=zJTRZ4~m@9CK5qWZN{#26CtJ87c=pMX|L;0VZ)t*iWd%YU5&|2d&JD?$B}L(~Z=C zJ{WAqMa{B3A{mB;8Df7ELof2$GTb4iGw1C^cT9;UxoTBTfXkcvO zAL3X$>sZnx{uI6mO*>g(&kc|m(P6r#R2enAp)@+qr!%A%Mr^|~3V=8JAN-S|BVh8% zC>`65(EwORVnZvr6|?9wb7$X!^xpK87Jye^cy5^r4@FvKdpJ6nR@_U*GLz(W2|=w9 zsLrlp6l7p+nTnQJcNI}!F_iGAU7ey+;5A@4t+CYD=8SZvc0yU!EM_Ux4q7L@)pqiF zTkhP`^n$lm`$qTJNp*zmS~5YY0bH5Pq(TBf4Bi?Eg9EOK`chD}HVQ{Cb{w9c z|4SDYAApRScfgFA2MCO$zb*Myr{WW15B5WTM+t;BB~3$swj{>Z4yBHI^ONmD!4ufz zV$vBZo6{}jIYq?dfRdUxXxv4{NE~GO#VCJ5g@jcnkiK=Z=~i!yD&2z{WLbddhqZ}< zk*3_nO6z5o&)3uCSNipDK-!K+=HZZrS$v&r!`XV2>22aze$56|K1qv=%B~?qTL%7w zGQXFp78SBN|D9=T&Q#?-$y?|$QCdrt{F#{$h{goO2Un8rEXu0;4fqhaWg*@tFeBqP+0OptF|;X6xeNL61nagmA#cXZQGqZ#*UV zO?`Jx#RHURffxb=V_`7{85DJBdV{hg_S%G(YOaP@+0%nQ#63ds@CSv3|9lcAvx+^7 zg^4>^?5(!_blsvw?fV$V^C}8cScRJxd8}wX#?itkWDRRg@NMSDoGAbR<$%m5fM%n4 z1Yf9hf{kwbxx<-nd~&+*58loncHnr8^7_HI5?q%B@nRd%Wx$F=`Eq+GY z(j4pfcwnwGU`-Q(zw5lpAkCmiBRAmww;b{T)-QV&)AN4N|M&GRrwZeB>2EF12LJ!f z@Y^}N7~0s7F#b1a%K6J2pr~W|$v-nqngt+eIcQtVi>=YXLKi4N20}sF3a1HR3xOHC zHgeniAY;C`q)DrM3TQRYuuSg_CvAw9-c#rxH=zCXxEx%!J%G$O`g*f(n z&gR_pNqh0x<=*A={MfDQ{b7Lp)e571+YW=Dyf4gz!6Y*tFHaQp>j!fLn4A>_S%Qcl z+Ty(lse{z5=Ynrk!K+?{(!jXzHy^Z zBQpLNIoF+}k5s5Uxr5+vp5#H(s}53LnnBX55QseKZ8Hxa@eumRm$anNS7WF-D^J-z zHI%M7OxKv(L#Xc{6|cp5>0sm*B_KMXWvjZ{o!TW*Zh-1zD7CDEc^J=m@4 zUC-W2IZE*bPdOZ}1KiBlbjE3Feqt*5441XE7;c-Ba*}bV$wU`f%rp&3VNM(;4AG`Y zhmEqsI%4|K2GCpNGAiU+;;ns=^=K~jupEa{{2Ny-ZqT-XsL9@3+$X8af%k9EME7DT zdL_NPOp^kh+bmbBH44fSBvY|XHcOZ`X5oh&rFkx+ZDY7cS7!D}IW+|D>J#b;&DP7C zlJ5<+mdp=yJCiyCZU;L1R1!1IA@z=sce|i!{9G>6W7362#;Q{czmcL<-ze0~gZP2B z$dioNJY1tMFo~{uW4n>bEJLYBt(CTLENJik@lCsoBR-S&MLO+~RTrMPx(kecyPQ8I z`eSaG*F$i)+>U**F9vC`f<8gLnZjqUWOynXn^Hx8P$%iqb7P}C1jpKLZPgs3ytT&M zO?bo6U477Z7w>#A{RkS<{!--p3wKO(l*6sbFte+7#-4wWKa&+No{Aq}5AMvd{AvN{ zuO+ei`;DRME}vL^^N!$6T$SyWhH_)9-Ie>DvAdCZyMar3yfz!9^l}nZWGhcIi`&*7 zxe{!J*)rP@)j;g)1*DYv=RkiJ_+jaECX~u^OjvXHv)OEUGTI z5%xHYFBW9u!w0hrT@UIHhwIc2>nvLqCs%W9^O)Wu$yv-78n(g5!RM__FQyUbL8+!d zx2$|y{ZX!sR&w3RPG%bvahWHlMCV}2xW~RAO*d)=PH|awjnKinvJZD_E)?te6>Bs`87e+# zcT=hsbqYzg=jtQJR#{G>h${J2Oh^zT$LJbxZ?oz zdCb~Js#N#7J%y2ps_s7uSQSRgqSd=PqA#M=1p*NaJ`G-QZMtx@UHSoNJ;4?x@T>Ej zTYR0@L~`_)=F>jeffiI+BO8!+d|~cODqYGdr&R}VRH}~VuTDAb@}hNyzF-v=r&qNR zT-BUgya?S#Z#)RnBenZEk?66!_m6ZT?C}`kZD1W?f=Z6pq$0}D$&s@K<_8P@dUc+$ zs(05^Rf8U%cSogY?3S5f7Q>3}_U+Nl?=_qRb27Nh?(GSlIN{)q#?EU~I=kEnk-Bhe zgv-7-)|}78vT|2Mc}^w^B%Ue+VWs1RCx>`qaJq&myTv2B4fx;v2wx$FEqFhd$n>O` zJTzeU^DFldU4g@v9xznt59+-j<9<|U3^ToZ0>LxNC8uWHG2|V*l54X33NnH7R0gPM z@kWThsu?Qbl4J@WstaC?QDop59=188%fvE`QhD8!T^Y0Lh2D%}>{E~`N{x0sClrhc zh5pb_sAo^DD7?8xdW>DppX%D@Ks@b(9}9W|+rjV78vdCMb?dJ>GRyM%LI3YL@y1Il z?dC7$U;c~vY5y7X3)$Pd{ACji9b^qH?UY>%om~DG@N2p+sv&%#Or{cxpqT^zlz<@| zo-tCEvXr!dYKH{N7BGfjEkGIRbpvZmo?s%`M(=!qzuiddO-0X2RrY${@So=w;#O}& zvUkYLc1~OG%it#d{`2`_4x~3A&m`obJ!&{5tr71aI7&b_p)pK~nU-)cnFxcQYN|7! z+S`ph3{_Sf)K0eF8BB?}t&!p&JlgeJqP^qiAB`jj>hPELj!hrWJbL$E3Z~V>)P(3@ zfU)jqVG4;g1O$#E%uHVLe)O0cD1;=lSjba3%OBcw=&Kp7vbw7gNKzS^s`{$5F}v0x z^E-1=AV!pnR3uQTnTwhSfhBf!Ow^7$ELVxLX{4&m3$0e`Q<Vw37*ldO`jX2H?M?}WZW16~7e3r1*O?D#={<(WU@*&&8Z>oH)j1BH zB%EvM?N_q&o`0szW@V-vCm*ymTP>|i6%+FnDep5Aq$^B`y9Q`}PB}DF%1{3u={{Bw zZ>cUaF{lZtV-CU?EDV5)fpglR`8#UQB4iVlZibeE-TP!7L=jt31C8-Q?RZdtAYtEv2e z_^XD%EZy70yKZH0usn)SK-#O+fUu8j zz;=6SPkSiD{5aBWG&)G%j z=GWkI>em+7sEVaH?T2XSBrpTt>Q64PQtbkt6xSiWGFLpa(miCGSqZ*P*_tclLfca9+#UIs42wtVx zv*e~MD@-;dAbr*MklPxeIg~q#GQ>HBR?5QhBY|#|y^;bCrJ_Qz0-J|TuyeSxwlQ@J z=5GwXd2e~}AbFn6cqQ7u+ydRcMNkKgxm*mQR|15$;*6WAYJo-(OLFj-$Rr}E`N=sW zoa_b0>s1*Tq0sc+R0B=`eW1nVPbFz+A_>oo>)>oJt5*0=%iAHupM+c|en z1?0MdH!=h`2;oQ*uViOC?!+`-Az$J;H|#JF9+zOVMckosT4BFGfI*xPk{*xvBMf!= zA=D5DY(XZ&hl=`6#WbRF^T-&F2quiN9EFhjaixT_ZQ_U`0FT;YB-Z4o->O2>wz#%lGz(!3Mwd@goQ6zrP+(!k7vS>EY!Wltd3_a|U4&wQ~a?fHTP?#?E{q z2^`Cv57~a@Qaftgta9lPRbFza&z3gO8zG?Yw^p( ztmyBGx%}6N|9R#7KXlx`$_d|S*}n}#2qC)`tXkA=^uM52Lvsi49SG@o1Z{+EASER$ zd$OS6_X>vpa$-Ekym(VSbuR!&0^z}a3?m_*R`#?>-wIO0&X$^aHIxgfEpWqD=8o20 zmUD`%Dq0M(;1JhHYH}!A&kGS<=`nx*s%Rh~CkC<37_=Q}c?oW;)jg8~A2rEYwbGUaC^6rW{vlW+!}y<| zpGDCpt*}TMP4T(8&NrNS4^;kNU+=Jc2=Yl1duAYM4%C60dJ=r+;=K`ljPXCT1zv>Dvcqy zIifqtMuQ8MT5xseaa|3Zj*5z6#kLeXTWg)mMi5wSa|#r$ax3svMpS5Z&pKia&u9}A zu`j1 z5=G(SLOf^(kVlX?OhcpJpZ4$OIz=FDGt?1QwUG_g^sml6XO2xtcr2#D~XL-K!qyMNX28jwCH ztG-{k&0Wk`KM2tfXx8f2Mj>#i0c$u1^$GC?4Rp;CCIf5HYQ&azR_46S(7){#I%^kk zY`4iQvAb*+*er2RENoZx5)j7hF5*9W>)2!ujxC%Y`4-6Db~cys7DA8J4R*T${yjJT zQ~s}Wal3!?fVfAJ137Z71~orJaB@?Jn16)*iUkKvyQPD@Vao?J2EOcRg5HccJ9+3W ze3syRO$d;GX$?VR?U);|)?!!;e8B#t+>^)f6NkcFeTMtR?-)6Kw))9$B|-BB%Z_d{ z$gJL~V`nj6d3y8rqqura2qNi!7JR{oyZVgutKYHz_(IcPOh}CCOA_j(bMLL)$6g4w zpV$}W{OrN$B@MHm+~;c5+D0Me{Bd=w|I>pBnYO%qEKbABFc}*rxWU&V=1^O z9Pf8DJT(fTlbJxJwv4b?8KKf`J~e8g8|>65ifZZ9AO~-@GU_2?vmhb@0%p#g-mudj zz316PhKTE&8F>@-^k12IKTAI1t`&GVUHhHT@Fj9^-CG10a-Yj=@1Ni!zj#wy$*X7b z>{1k>s4sN)G06A7ycYRX;cshgg9v7tnTnRB%=&@rUg|yCQp)7^0=_zNWYgxYfP0NR z*N)eEY?I00F~eo=YF>RQ<38xVxQ>a3&68WNOMhiT>EzFq^$ZX7*s3df?8G?f?j{2P z_MS~ysmq!^voZA6A-TzGC~KBXC^s=7qhY62E1d=G&nBB)TT}L0?@XBGSWUU%EjuwT zS7v@++k>Lu8Z^pQp_xa;2w`JMjg{8&=lZU}V|=N3kvD#3Z9--`Gtg~)%(#@HczTu)Tz0vtTeu_4V3!u5{)}$6XdbmA>R1suiJ>%W#Z81vcnO-k{Tvk>> zjxG1HkZa>-H~CZQc}P3;e6-$WcQ#w9!m_>gcRR>AxZ7m(6?(=N;bxv|_{k_0*J|#J zg0}lz^kZpFIJ#xa!9tB}R>HWmNg`jecUx@xpVTZ#=}K2sm7{tMk}X|Pj6_Bv@{1}C zl?)7(pNE>$ml8+JsrGSchV8Yz>{d6`29uR0tIo+D1CE|44lx|49w646=TZ!ZJHa_Q ziAR>Aj*3)pRn+1szxF*wHWm&&mb1dPmS{pqv%9kzOhWbcq1qsZ)7N9Y(IO*J+;U>vu59(lgYef z8ssn0HI!$T6P#=yMbPN+d;U@%RHNxE5jI4n5ul|U6n2ZlSEU>zUb6G#&shic!|Tdj&~hqoIHy@j?I|fZXeG zIAXrM5^R1$3Bh${({5>EL26d6!9$#S9q%dU)adGO`>mHq2M1TmGe%01rzCPzteMRU z@c3~_2I;(yrXkVjUg9|pyRUx5ZM8nuM$emzn5k~LMXreH@G$mmIHlMTZCn(iGRZI` z8r(Q`(S}U5dJ3Lwbe54&cCk1$Ysj*vlBz4vNo#q--Tvx|7OtE3WV8!v zeY+KFN(bhth|xCss>}_J5s{f@o3Raz-qVKdSxHwyPs^x36(REq!mz! z8>!Z^IkwM^wdcS=wq@S#!`3?fMy(#ri6JUNz3sKWCFt&yex@5y>N~K@IlJZ6V3X73 z8>N1#biY;WZW3ePGIk+dI&{n`?n|wXdo?FzB@CJ~Q2{&};R!Dzma1u$bpW5`fVYu#3hOwiUJpy#w<-6WCV;0lnqY<` zXe}#q*?ZB}?9tf~_uV&sR<~q$z6Pc}&2L$ccTDawu10Qrgux0J6YR!$HhTCa&m}ydNF6WaC z(R7akrkk)xuBOE^w6IF^1D?`h z(I}cD=;}fGJyWR>s&1SDGCvXX>cjD<%S!KGxM_1b{gt_Mrp+Yu z#;%ExL(m$`IFP9It>kk%h>$b}xDB>f^F)ES@8N3wp%VE467mjDn`yk3iT#7NPn z;5IVXR#qO!VswVez^gpJT;=ySZjV7)b;MXOcRB+ua;;fcSb0sZ*tB9=+Wl(Jp6rV+ z%jOYw)cRw{mrHv#Pa{ubE;6CkzSiXN)XQwaFT=s=1meJ;Ep9po^?`BY_TTZEzB)=$NKpL@3;vGsq>S9c4QZqYBHcEZ9c<>K401) z{BCu6SN8Mj@a7o2`!IsZhj7F}UDd#z6oww)tT=KZF;2gf7|E{GA=4gog$vzo+J5l| zf(Ns=C8!f>?TI4NZcCQkE%ZfabmtJnYw!bVZFi?70MrM~A>L7aJbXGBGQAj=Qiw^E zpe$p9c`A|x*R7Un1U_|uOXJ4{fnQiZOT0I{pL)q_;j-fOy>dD>O8-H!! zHh9-ic+@%UYil30Fz8eKYZ&<7PYFP)+fg%$INZ~Rp0=KZ^MAt`rPAX5C!8>}F!~WAs2h5!?)MOufMx$>Gd$oq&H?KceyVD4IAZsdNrjjVD{j$W$F|6ax5 zN>6Rf&XNfqlREmW@#r>LNuyL2TgbSTwwyEIsEFn!je*WPUPFf1rNke&#e9PZxv`p0 z@y4i+i7*L>6CjeLCr>PpU`SXZDiBe+ks#3)%E4)_9VXrSGn`oOOFQj_d+5IxoI!y2 z!#H`()_iZg3WpX;rBe!m{EjW8N;0lbSC@1u+Bd9I3M}kSZU!XT0my$;Gv3Lq0gCg` zMnLf)Ne1Cf%+_Eq8(hof{glQAgCG3gdEg(m_?ftWw}D?$0s#^Hb6F+%-`eQEswz!L zAC;pPesbmv?hG9QFd>W;#0V33ZY%^?$@n#d_<9V4J2K}aoea{Q4q>DVHGDO#E3s|c z5nL-v)D*CoNZaj}R<){{mX_9)=a%Q5-jbWY*8Sb#ZpI`@2SV28^Ri>ldGVcn!>ehBY z>QA>YA6-JJlp(Ev?N+UWctERTSKg4{%AYODd$%J;cI?9C62BeF*>DJCRSvX#ISnLP zo;>eYCQF$RWZ;eQm<0_c#)@0I5O2^WVrRe>IrO{e{3Ph7X0H%mU3?q$2)R0i4=OTa zg=|B*-HLd#h>$!3I5w90s;$*ddr?7!D*A9SHI(RJIqN^n<66Lzw ztW}D5p*6!&%ZDeep*6KpEt)uYWJRV=va?*0C9{|XFjJRJs|X?XlC7(FdOS6gZQ>12 z`EuxHM~kpFEY-9_&cadx43>yDbzTq{HS-cBpS06zHY1<(O;?m`ipX;5d-(ftAI;nPe)j?!(-7}v&!zmP%Bj7i@~jBdR+ z7K05s2=oX;Td&Rt^(o`(QELO9opv~)>5UK}@Xa4uVwJXMKtfy8ti`f%%yqCRn@?e3 zoeUpKP2-efKVUUNb`%wV=1^XjO!_5eSkE5wTeob^fep<-w9+tNHtStJO|V}>;+Xd~ z(G=RB9iYXyln^u6p$R-mjxAO?M&r%3>xqki{bU_T%3*uUrVuhJW#%n#Cy^aGuhWF4 z0SSi{OUtb{F)ichp%^NnTuEvcP+u*?Fijs=&Aq%tDL=8%4zaMl3439cHl6@g76&P< zFfP_Itpkbqe;9kmC|$Z_UAtDI=uV?m2{xMj_2Ff|G(rG=7gi|!L z*F28JDpjJmUD54UP_$C>kim#}`@v(r94s=S%@DUHq24wY%Y)+mu;DQ@8Src(exhbB zTLJ^97|N;R3)2WoRr=FP_K0Lxyk6+fO-A+8!!b@0Zj%npngK&htPT)$OLSxNbJ?@#jkI$U-a8{Zodq^Qq_FCZ?oCd@`2N5Ml~;!gwHJyIJ8y;|D0q^g_0Z zF_|22Z6TM>UFy-uS|gZ^2%MX&&kF2*CGFF+^z}lA8c<7jD`s~> zgBD*CO{dFmEoo|+_MeLTPnXeB@?zUgW~c&n_Hm2fH4a-ia}`=oZBp{_qz!W5mF&)f zD?eq^7W0tiIQ4DB=QOAr%47l;7k36Ejc!25YM+(vEM&Iw^l2pn$8Hr}TwNLp#A&#U zt&Q!=GbeHS%S+uC7^Mr3j@=VCi*?JH`TZ$BB7RlPDt==EmS*`%oM60V3WHA&5+AP{ z^}Hldil_l2r{*3gFN)5PH!E+Q-`x|dk9Z(`1b913ZehIgM|F3xYI*QqZv2${(20{4-r86b*@b|Yl4{5v$pXz!Ti^ID=MY4)AWz zAiu;8@b0iEzXG=U)v6Ui%idAHln(y9;LPV#HAYKx9c5FzJ0@X{CjnO0!Qw@XjRjI0Rl20snZEc<;5<59i;9_`w(RQ{yd3R?Gg=lRiS+bSxE z3$oR#$VXDlW7$SGW?GV1C_-ax5qH!c-ww~e5JGe)_6kyHoNo(U6qT0XJeZ|*>QM%p zDaKTUQ|thATUvz#DH>{>jm>xpqnh_)d~BWi{Bz!TN~}Dy!Qt{DMOHG?_*4syl(nuF z&4oDj#!yB2TaF2iV?VTGRV8QlN~UGB-3|R<{b7JJ?elxAr~Mq5jUZlY7Ht**SHEY! zN!eI>ntTOmk($D1dZ&9HO(t}kh9({>E|iEV-di%oc3=rwHwihBwPklAcuyjE!FuTT zH6qv8iGzpv$MQ?+TjJ>6*(vLW?ZBKv1fKe)5Czc;`bDiB@4fS?`3i4;L~f^bg{Rg7 zg+sj5B?;2t0evnQEtX+KM4R`ku~<*2ywdFXzSu=ZLFRF_rEEWuxMZ>$W{db^KBF%l z&oW`%)Yloo#I?FhoFv=$43REEi|Xtf^jcrk(2a3%CwEIS0{_|)uCXDl)@`J)P^+Fl zxCZ(p_ecMeww^pd=4qoEcaQ?@E;&o#`~hh9WHNt;xhCUUOdlE^(vZ{WU;zedlg^u( zqr$bgZVhm>r&Z#ei{Gbn2HaELLcvb%JWK5TD+zY`MOzL^alkkO zn?xKP6B=tA&tkEJauJivDDl`FyCa~O!k=|HYm15ZU?NMsmQ0|uy$-Pqa^@g+qbd7? z+#J8@w?$`MvW&Fzw%UNbUrSVZdge_KB03|;EwK0nt&RPw&82K2_vDOB0P%QpZx!=L z$1qGt^^oJoT8=MyT$$y|+cj82>+|zQYkK`O^EcOwE0IY`-LcK+EPv2awTtIUvPVP6 zll`1Pw8f=Vcc_A^iUc_{_d4WYS09l?jow1<7_;K(UE#ccT%g@J!;rh(WN7k=xgQ82 zn^BEti_yWvd87;`s$!ECw%^jfjF!XBJqxi0V@=Bt;jMD0VdRZCaT=va)|UX=nodWe zQ@EPVCLfOpKc)}&Kc04>v1$50FYJ-FUl!=x5tc54sG1b zarK3?bUa`vT@3!T7ubTAwxNQ1^=nB)QTA72=2y%r+!YlWQ3u5t6KFxKQ<-rp3);W4 z=2&81XLP74sGiXgOOQ03Svnz=gP1mG#dv(sv*y?k{3BF2)t% z@n~?Mt>%AMmJi34OXnMV23d@oyS++~wy44&HmAug*?|OgOyOf~6U%0bH&Ft42s<6| zef)H#J@l!7G5&xoFp~Nf?XAYaUvH6naNZ;Uxj>m!_(|w9{WRXe>_dnH^&0jbUd1U` zyl@C|2Wl4eWHSm!333N^d`~0rv-Qws<>KgLNC%D*NQu!ZX@MExA`reUl5|>y-w;d7 z4Pm0_f;pNtDA#2=bsp9+;DmeD9LRZ=Wd0|p^PI60MNTo0nfzKnrrb4RMJJfZX#Sl! z#D?TktZu?&$^&OBo`_(--U84)enARV_hNPqIc!8p^2jc#W0f^NLjY{0iZW`OGD85U)sx&296;^J zYn%v=`dMk+qFia+nWL&yI^msw3YC@Q7Ck+?lagu3bs$0Co_3269gh$zAiS3f|EU$S z1#rG)HslNEO=)l=0Uj4E=GLnN@|)3ubvE8*GM25!C+dUMXh^(CK~?}mw3O{SL9HAs z&$#;5kLni#X#JbeOq;#pC`49Mv9bI5qm;>74t6%32jbB`)i2_?l4TQl>=aV3D zTh-W)6V&P3(sE}e&xfd#g_;P9e+0HQkFi4%VXqZ(K7MhDktu@k2#MDIqO|+0h-^K% zK6$!MqUtq9u8@40fwS1{$cT8#$m%9k(O+rHxP*c2~*$8Fxv{UX9Ywb~C85>i@M zk#Ba0nN%O65puFgzcMegyhEhfvMuUg5|`4kip1fp;uAd zc>%h|uxG{vn&;-Xe40BYurSBUbGBym`M}qv7sDb}Y%u5<)c866r?hhM3lIe?v3CM? z-v4v)$7&sj`%lE)K$rR4VA~(CHHce}02v)2gJ{P;)jlw-_~>TFwwr@ZW~qGh@Yba~ z5_SBOEzQY3VswI&@p{+sW};_Ymw$Qo1wD#lO!)}&)$;I#ZuVbgHU-&EYqB;t?lV#~ z+S?2ycmLAZi6U|u$uEGB^K|^FKLilycv-APy z;8xC@wOQLoDQYvO=!NT>;5T86;=--8ms|Z%k)a+cz1`q|rIW~n2B_=5p9r%LJNkgV zei5tIGY`@y$bR!h2z`&J))ArS214qILUGPQ{GM!1fQ*)l>aPu9(jnR9yS#^h8#m3P z<_J3eC8@b@jNwR=ue)+M8e9H3U*$@`E)IW=lP9xs)rxK8Ea|~Y%!B3DlAs@v3A;}8 zN3qsSfdWtdn310$=YE193}~0fnrIO8q)vcQ9ssywHWB<4bOf=P>}if2?0F=|!Rf0u zJ>Z1)r-cPeR*?$0F}c)H?P`?_QhIcT>QO7mZUzaIF3W z$Y>l+;Dl)U6=>iDPv8Wur0)}4124bog^Aod!s}Hwm6#cA?E>r`YuSaXX=TfxvEaD_ zgXC+PR3a($#3 zl#aI)Smp8atcp@QK>EKVzG5L`F}aOZs)$KlXUmv+2qFi*Ahd^QA2Zi?yL$L1cUP4V zuU8I&-z><6y)i1iqEvG3`0l%GoZ7);V<*36wiHct;LgO#Zu-Vcf_Z|qC^&wG^9hZ> zNle;Y24`k&tji9GTpoh_S`O9TNZp$}jNfoKP2&2EGN~V(&aj;MXdfZKL0xuWN9(;f z*~TH}I5}0x4bu4Ii|>D?*8YU*o#lNaDJjvvum5{$P4pi~$A7XG|0=WmuhIoDFQg@m zFTNP>+ZXN_7?A)1@NEzkbny^rF`PBu9-#IR0tk-%KGawz5l)7*g;*zI>($xR25Hwh zr?`g14R(kVsq{;ytB%=@r{}J=dTPnwn`*x8lg+2j5AUnD&Y}1(_h$xx^nO$nF1tTr z6KH@j)|A(yUCG_}d$>N_l7Txk2O!%;dpwmZ2H%vZhtxsf z%G9V@)}w=w+qa_ON=gR6l#S>Kx=0Uh30k<%hZ69jORo3iTYRK?I8dVZ`Y3t*qRXDq zd8>Aj+yr~bP`o4tSh-7g=bj_*vJ;uJ@AmE>JMsCt$lybryml^>0MJrcd zUftMHzIUzXBf7P-(XoLO?D+)a^!Nx4+!}R4c5f#o8xizYX~fL1N+`EzLaLCIRTFft zwh9l967$Cuy1~W8xxw^BsfGLvjEf7jZu+1;2Sj*aEkCrRQAkf;`ydAQYXMol!xf z%Z3NDK)#p#CnR+#my%f>jkau5oNnS!t?#MBWnsYB z5wRkx$U{R!d%0V$fZZjKvN$FMQ)UEuCB-hfhnAkb%Ad)8w^fI3;)SS!{MuMvA_L)} zO6s%;Ue&P)XEd33z`N=+v>7dq+{ZN&_9tWUoXSabdB?1Kf<*OKoNJ=NdGG+iW<_P_J?PD%u_tzY=6a)P#Y zo-jXs`6!>`gZTF7q{>pE8Z~7jozM0#Kf}7rpSeDB2?DuTG6tDg)S4xG_*mYdzEIT; zcRFR%lMNYk*rWSg?u-acPKhdhOpb`dObuMjhJU4AG?|Bax3VmzNnqHk%op^((V?{h zG~y1c))y60+ZcJh(rmD*fYyI#mM0El$)(Thm0b{qurbAG zN!pRALLr|ZK`0|nbiy1P@Umzp9A%cLr9_r54gE=&6GADi6h089mKTayn;?_E*Ezez z^fH?)qc+nV%adRMj8ZFwgeLCoEoxpwniP%#$hCSe+}j{X1iFD>N*F-Mz>|nsY$_x= zVKl7F)<22BnZ~@A3!c7?z+)U>u~cZ0Zc=D|6>BKcKie-+DvY!`FR1T~xMkYdDxLRIdX;7(F9Qu%_vdwsFXDLmtkCrZHu^u8E zEfN_k$83-LDIHcaC(Ki2=>AAf7onA&O1fbMC;ir+xI`RjEhn5$${G^c9_44%m(~pY zhsq$n9q-R9#1Rc?oJYMCTy2WG1HHYW-%^fit9eCbdA95x4Xd^{-4iz4q23Iaw&)SL zWC!itECbI%8n*OMWPmflLY>!vlpQl?n#`?1B^7yF;NWnQs*xn~%(}x`BZZHO_79jD4X(dJJ7Vd7rM?-RrYq1gMn`3(zu?v0#_S0 zSYsAF`ow`;yvVJl(nd%B9&^p&NL1pE$|T3S&YqohmNUH47bR!IX_LmX$W}9~R#K#L zZpRBdOq+u(XbU!|nkE`rtvw=?G)qdvdy|Ve(E(f+~}uqxfZ?hwo}-RMq|3 zkeHA`ku^A|#nH(H|F%t20L9d9d83Fcvv>_X{vxYPH^j9GttuOjG+W0h00{PZ%V4xK;At7Sy%w#OB}Shxq(M2%ky#eh3D!Y8koB3ca}5{eD%0;?(Dd zyJx9_GuOaj>D~gmprgNYs*mNLgV8`GUW2`VH1he+LN{R8r2;2QUjL?0im9t>Ay*?d zM+5PO!2nJRCzD^O07elEFP4)|7{H(&$srw%FP!+y@!2ExbEvOqG3q0xwNUZ5=tE9| z1CuPO@w3!BAXbsaXAWHG6ZisNl-k~#lA)&s$; zMZv1Ul3tcA*7ldapFl+q$m%t2hFP-%OS>Vo8p6;Dbu?@AX1jb2b`!nW=IJ%vL;q0s zgAjfp0lJ09i!oFa1=?`hdBi$97K4QC$7N;H9w*w!F4G>hX#O58^E^esw$|xMU zfPUco9Un17p&7-`*7f4y*oRF}4f0-DNLDPzwGLmB&i_Gtyorf6p8}L-FUElav??D6 z+iFy7J&zcSVv~nh(-pNMQhG~r4%t3GQLa#D>GYX3F;+F1aZcIz0a({eGM2Y6P+p5N zsR#6B4b2SFi=oB%Tl(d^)p2>jXyqpHvaT(gt31EUmX` zXAnZmK8i67hz7%|3r&)Q-mdUU{v2Ird73Y@ob)=vv5K)0srj{nraZ2*WqrYj#2DZs z00x26*8-Z+8J0e@YUhF{PgZidcC{m}Tl@MHTwG75 zr`!cG726xraXfFf@R!tn=6M4-L8P(NS1Pocxh~eoMz1#QlQr$rEd_LpIR=T89z9>Q z&FGH8r2|5{1>)Jj*S~=!flEC$w7$#5<-Y|*|BIOD??_kK(bz%E*4kLg*4EP5?(bkX zQc+VD^BYhi605!Vpin{H*kqvzthu6bp*+_=Ru-xRjt?Pg6bMm8+h(M0^{(1MY+*4w z#CtEw!qcZfHSFIu(lX)N>3BFke#OW43s9}M%ujxN#4T@|B1=4k0$fi=MC&;eUZe(p zr^PP@pab4RUPQr6x>piH5;|V<_3>4JQg?Nv%C_)+RzPMd$z?9vDah`0nVp4stfpLJ z(owptb(DT1lIq*LMPyB&NqTz3>YL5gVrA)jg7jH9>~;k%Jwfp@H=C>$J;mnoWs%bZ zvt~k)L=;G+U$I#RuTNkFqoR4U8~0J7S5dsX&~M|U!UPGA+LvoAuu!5d@wSO{Oln&f zAK)@Kx1G(qjoQnkIa_!)uOgVDN0PnMq(wDZYh=*hYOGke7Vc*hX&xH^a-8)hGS@)4ZVawHSMC<> zI$xc14^{3K4F`SaiVfy`-6i&Vos!%UC3jh|bA#EZm*|PHM1Xk}L4exjO@i2AGvY>v zpJ^X+-0Uq8WHwPnPrVsh#{*!`pS2f^emUehKS;gtD(`{w5fWw|hcbX}-W$Im>Vy1U zT!l}N$}SWak31vBGz$cUrl+eJLq4KM#U2Gltc>SN!A*?Q%Z%F?FRNj6&)nyod`x%w z;pY*^A6o+28Q`BB!ztAJ462^86i6rxO{fy$0v#*lTl6BIr=0?DF_;nzwNn9g)~?Gky8ig8wgO`p>PH zkgbi0xv8^*{(p0HBIB)Pkp$p}zSfQw{dxU-^YREU2r_cEnIPbl8I++>#Jq&6?2?EM zqSm!pZWPT48Eyjcy5Wp7Iy7@C*816)>Y47cKQ6T1-lnE>0S>RpgC$c&^jO2OBcLzs z`GzLA*`8Y5yC(!O!_B#krXQ{OuFqB2YP5s(YwXQ_F~ST%MpRBb6hjAYzJ{G>LKl`4 z8**Cbi?bBdJasVn0|n)7D&2Kw=&D({M5E8@p6{6re<2t)xW3{BlY~gV4BCQT4G(zYT2rdn96eZvT`4k*;my* z%HO#3AT=de_gaHoq-}4Ps~oYNdUH^$^{5T5Pb!q3nWHS;qpkWzaHR#8eLa?mh_=O< z3a=oP{xRJl`n9DHrGzKLCpvk>Bb;c~ToNKQcj4i=2$g>IOQ~^N{Sy-g1$stD*M_#5 z<+M$6;`Q*dJd({B#($UzI^!3?C)EuLa?Fz4ZqayT&<~iOo9qwSx`|bsy1OE0)2mSQ zKR$y26hdx7kq4eHa_PWzkvoaKIPQV;GP2LnV0OTP zf6>41YD&ZuKr`k8w^V|PkK#KPq+S6jz~jeD#8g1nK~LJ3!FasGa6`1kdl&HylQHn%dOaWFPCHn(&7muIpJbHRS2 zkpZSVR0Ya*-xHwKm(|p^0cFlZ#H2MBD2{@EY(9@JdSbCj^cZ1jMd?wkSVRaZobxP- z=^>1?^0y+h9n{m@TV)#SZN;l>|7ZXOn^_5eP22PmTU&fvVZs|3_XzsZmVaiG#-+Nv zT@@*72KV{5SN(pw|I_;88~E^#_8R|eondHY{y%zQ{Pks`GbZP8-%cUpTk7<0pvS*% z7qYds{$|}sncEo4={tNcU&OL@e>nxkZ_JjB>EA0@qT+=N(l=ab4z4MoQF}C*Jk3ve zmByH2mn>uu6N%^t5;W)+%!OK#m23LOz;XUF@Moeh{!BmEb#8=f5tZN?@U!F5CYR$S z&(Y*R7O@{CyDRurISHhOMX>_vL5>tkvnj!a`UEgA#^z`&>? zEsZ>%v6`^1>5C@EYc`Il`rVenO-FI{25m0Qqx72RJWJ^m)(pfJIzseDOIE5CSASdr zzLKuk1zm1W*H?BsY4*rd!CfzW1-9g1xQxlY4qAJwIk>@rFElK(wi?oSZP|OvxSEvj zG-xhajl$X1;R1BoBguZG7J=(73#{#AFS&=mMxaW51QZEY?^(JH0|YIh&ARhum!3|-4 z7#l?mZJ<+X=2l^dK?RMpQJ8(TCL{FBnWd*Z1S7>z6Bc!rGJBnn>p*b|J^1yC#pRiY z%Q&9F$K)~glfx!I9p?mA@G`iEi)-B&{mikY@acZky^Urabmqb}hYZEMsPu4ZFNpi2 z8Tw-pT{>Ym4v^O{P zpvABswskwrFFlipjA@!4XM(>kBJKCRO|EZqY_IkDiN45gYpS_vigfub!#Jg8e?e;; z`o<-X)=x|}^T62GfAI}}nYb<-?`;0JiBo|6Kbp9J$+y(|Z##GV+r%pqt!3xF6@FiT zu+EM_vB*QFp#1ou5_0oG805XcM}(1_LfaW!EpZmASX_VJ5It*q5rj(Qh5oeya{npM zuZ#6#koK73cv|1$INEev%kJv@0FWCD14Ws`tV=l|6IW#@Cx~>1Aw^Y6P^MAYncNZ>ejld;X(x9?QtQ4XrYRFn;B#cG7d~VQIP_G|dg$Jy=ImZ>9B+XefgO%P zN+kIfmVeUYuZyh{fk443V6+=Ob*~mdV9vY|SeR_>Z6qONfp%9b0G#qa^Y@7%sATmR;HLx7FlT@|CKRp!3tj*{es!RvV8>?>D) zxAM9Aq_RZ3M?3qZOnhhX~&Jg326FbIcWSjJa zZ%ng^6NeVZPco2WCmBj;=-4H5%&CF{xan>XOiAXvltQ1J-yCLL{~{Os%jO9^Ml|BS zU3%)bWbofu_y6YB|F-jgCf-#v9sdFwB%qJg{zQcC-@(QAHAGrR1xzTA1OLM>=35{x zl=HJzSyU-jOZ{;6t>Xi#{l4;`5UxS7w_x1qwO`2emF!h$^_QrM(Mp|UQGDoR)-n;SnsE~ag!WegIEuu zG!ziwjhZ|y^^0L9=pZV{bE6*28L|^4--_&kFC(#EM23?T5g+tKG%DXePEt>rX89%B zQGQ4nWwT$zY^o+Wl%T_`Tx?*8__)}GQ)&aVKz&$*t;rVNN9Hale_>!O&XjoqMuNKv zUxUdq?~qEGj_FK+I2~yis491SD`Jt)`E=Gr;(M{aRsjnf>Yr^*Dx}RcR zw`5{juDQ=Lta#`<8==cqIHhv1 zm%~m}lB<@&c*U-Z?zkGKCthk+n@1E6q%H`eL945I?X+_ToR-N*O;R@It*2nyR0+bI z_Gxe-WN7fxlDseaf?tjyrxg`Aj6o-m3 z2_Y&ZHUX?-Ol5wOK74#m0o2%HQbil4%iUd@|JEycoS(5?ezRqMr!@S;*3(^fhTQ?s z=4h3pG$ie-i~6rY5=8fyTLOz;qFjVpbjDeNqufGk>xvD00>pPri#!4iMX~i%A>z#r zb|5&2xCU5(&HZ2Tb`x^%Um&;#y5 z290*%aA=yK*zK#-5AM{%bXB{Q=MYFydf?_+8EleU!vvHn~`v z&L0=GmNAaub?EuPTMDra%@mcYfS|H#Y@hFLI=SL{63qaf%_Sz3h6J8Z{ zOR1PDxhGGxSq^>elf~eU5t#aOu`40{7CBA)IYQi7P z@>3((I=!n*PIV{RdlfoQj^ygKw1$1uOZ$!m^<&G=IJ+yCoyJya6Qpe6uD#?ZkR!NL ztPk)Vkxd;{BaBV+09p7XJt~9C{j`@JE5X{-)4yB{VlZ&^v#Jpe)jzcdIkd>!5A9;R z1nEFVtKA_6?804+v;Z@PKAqWIBVf z-2=qlqG5#7A?MrHs-FrEe=YyP(|As`K0R`{+mFlLKTKVpKpnxkj+1|g!;4?21yq)JSytE_(8My$9eLgJN}Od;ZT>o1^~}T2@;o$`rt)_sb+1eS)4Vbt_*AlvIgD|94|)Js z>!41HC*@?IF_fv*MC`E$}VkZO!Bo?B3;XtH=?}J`}I<` z7~2F~8~xJtP8r779u_1pvlMnEz1m5aad<%_>S;_4I8=q7)MBdV_t zbkqo=a_!$>i-j5pzxz=~C+L+Yl8^s@>IFvNEx1E>5qc*|5PU;t>*Zx1(GiNe{FP1Z zP`dTsd-8u+tFCc$(YKWze_#LBX7S%*kbiD1|A`9;j1c$>7xMGVtWg8X<)AghQfNvJ z8Te-pQollmZ!n^wR;wNF9Uq>_=GliE;4pkJxR7wbv6W5JwsmDn&9L;E zg!ZN71erO`nlsT=+&7?E5JUCsw0mPAfxsl7ur{%zf*K`UaAEhzJrRLF#8snyBGD-d zhu|buP+U87uW%=isNhRX{FDR8%k&sz3oyb96x}oXHS!(ifhN`K-*(*@R$5cV-?-`` zp#Q*C|KGp$@38Cd5C4WsIT`*xE&2lO_)u9s2G zN#8(Ga9pr;(0QrSYzBi-nWr`AAA~1hp-zg#W{i6-!L2(P;nV?>^#l2IOY^I}0?W>k z0R5fEkzutB`%Lf+#`Wpy^+p9jHo`1oKk}gowP1k~cREA?wzzMO>{H9>3U7YvC|4|J zpH~I>{GkZ+L<=lW0>F)aB5MdFC-nm&M_jZ>qGzSfNZrV0k7&tU0DjT?T~fx-q!iq1XkWeCR< zfkmOf9kW+udSo5#)(h@1T9_AS%w+V@cu{?FX~Gr~k6zmIaDExf`Z5k{UgNO_roTbzro=wfX=9UD50wOIcAG$@x zAJvana4Ln5Q;#R3k4cuKp4UkdkQPCs5O1Oaqp&H1bwf)II`|$ILpaF^gSmgN1{nBA zEJQv+py5Y1D49E76-?@?m1g-Rl=krl(pbL`+`r_-Bm^L4qjOBRS$g6`>aY$PY*If*51a zir%@`IJF0*@fMoXJ(d7W%lbJMdTarhmim(lqU6Putn>lye>yKRU@>Tn?=dy~D{=6j zWBR`jVWhmYWFJ4g_uS&(e03Sw6d^ODNVPPDm^?BdB*f;QlU6Hnwz`dkPgb~30H1_r z>0ID=LA0by_xh`E%GuG=8CEyXB#skK24V)WB2*Pj?iN(BRnL0@#ZDJ`)e8H80E8!w zth)hVH6#LO^jLroW@>4RKa(Gpcy7uF3)%Vt1e}DLQG*g8I;cIi+aqF@r+!f&9dmlY zx~#%U7X!~xygX|<0}DjqYD@hYP62CYRpwwY^3OF@6oXI&v*T`0vU^bbE(`98OofC4 z&K+6C##c0wmKhHSt*t7xfU%3o^y+|1AE@35mtB96fF@R5s%p0YTn{jgPP#Gyd^d`|I6~{M3PPk1n zu<+VMgnZ00VbGdFH=)pBOf*oBL>txMPW)q~NU@w=B(E&3saR>8uONR<$kt|c3`VRp z0oHYl7>XLX`5yz4aaFi zlxDPOQi-ajSPLSZ0qj`5H*@TF3NB?P5w3;7 zjaY^rJVl7a!tqzKHciFLh(Dfm!OQ47z1eA5tW0z2bCOJI?n?9!uqH&lfiY$)Pjnh^ zse9YQx?3q;8>Z-~dW0EXX^GuZg>oU>MU@{tO?G!INWF0^ZvaScf(4GE+V^{ctcxcJg%qFZ-{Xvgb%8-A#kRY5^T%?|Wr5Z$F%Vg)!+gKt<%|&iT8TQWNu0Ueo^;TWxnrSGXOXs z9gGa$+^MO%Ea#Pem2rc_s?I5$h<8^{{a&VRclriG2~r)*^P&OF^O6BG3KshE=aMA= zU}HS6Q&{H_0%0_EkJFq6(r+fnndsO}aOE8O3zK%Y7}TdvGWRFN>~M!J7-&{}9Q_de zk68qxpzIn!eU0=huIAqb9qG;>MQemZP~i)0Bc=oGP?F7P^`M`~ zL6S3{9WI_7?rraYf*-Ke+azwZEsuUnqKZ3Y4g!kXY!d}{rRP)JCgva<=_OJ-q|bUW zKO*kI0B1jpTgR)HUZ@M!9jN!x2yUDV&E4KJ@Y=u5|4UixUyf_vV1aDsdr`3Y&L;Ey zr{nsUh2fu3t+I`!&3FII|0Uq-P##nG>+pnUgjk=E9~}NBFob*r9(*U4FodwMP#IYx zuugA@SaI*zC@4)TLHAl$OAIBN6784o*Y@C2ZzL95YfU>(DkOp+iT%#u=H=Q`MyL1X z#Qw+CpDTcUdrbl8JxEUa8G-T)`uN`cfu00E^KoH&mM}|bhn2l7+yQK%cLdk5);3Z= z=u@Dz#SP=|tPU%Ph-PP@Dm%V6~u~{Bd5{+Nf;&Sdcl^j-Q}B-WjzV0-gh=ix|CQGO=N2s1)Ui zvqhJ@hv`YQI{V1Yjg#7n=l*)jo)&RpK(gmYO?R`unh#Q=K9VzN66_FDvbKzmH@$Uq z93mye|L`cVWv=AZ7%B#xRi3VG#>IFtW}5$z4Ku`>-89d!S&LxM*&}io-K=wBFknOP zzCPt+u5owSw5@C4p^(x^q0leF5YhNCH@27&ra66;n)gv^$bqyQN$D{|Hr^g)L#%X< zUn(e&9HtK~Qk%0&ikja%K>su~*F(R6yaq5oho59EYV^9piWa8NykWrQ;P z%Epsc_edr1@gs7u@y9|f6@xHdFYK#YPz*9muChYI@Y6iWErM8{H*@Vr1Jw+zRHv>X zSWH7LPe8*tZtvEvy3klkgPQBpg0~H4cRZFg!lRiBe^hzC`{bbP=FTL$No`aOJ_PhyaFc znsAxhKIBkCR139t!^vG{W%p2SL<1`md!CB-f6Ge;7B--nA_4#mepiJ5|L3Luo<0A} zORGb3OS`R;v6I50S5^yfUyZ_uk;Oy1IDS)Liql^<49?)I8~WOidk^f+c<2+dJp+ ztnOG`J-fMTblrS^Zb1@e4wpTgg?;sTdH>0aH*!>s`9YKXDT8;mpR34up*LF^s=kMv z>13|WiE+NT(x;QU$oy!Ykv_zEbfVN9B=f>8xEITba#O-RdF01UyU(=Gq_Ibs344u> z7rkK49X+>PJx7dtwa0Yu1pFd}945}G-52kzMNMQnVj319^>D*%HZte!)ilWD1W6yh zj~FTGTxRfSpW1M63o#r9`Jx2rPr1XT$XhQg+i2s0o89NQub6YAm5J)uIC$rzF?z?M zlVcw#Gv<~n)7UN+f@;|=TzoeGDe2rQXM%dyg1L0+R7lJsU)EXJYB zi+1cqP#v@R6H_-s^vta=`i#XU=8_VjWp&6>_)5}ioxE$w!mCt96@1TG3%}!GH_Z1Q z5L5SXk91`TG*iPp|DN^5tzPZOA@k2Q3TJxz!q7w>#QRKM{XiwJP5g*Uq`y?ZQ3ZH# zrJ43{#6Si5T#9n$jUMqjdNgRCwR3Eg43otmk$mJI2I(p$!^JSWamXRRn{64Y^bm?I zoy<-fuDNE(zO}wsZGBINMvO@HnZag^Kg_TKy933kXL^)&=&(#E3t)x}Ax);1`PLSY zo~722n)05^MfL&a4VWB!=#c|hZB2sJuuSWKpkoz_V)LVzOU+EizN^|M^P@50+{0t& z-M=E8EEzIuEgn`;$}yXm=NIX=>RMecRu7Vy>0eZBm|WA8wQuxFC@mV*+saka?afeh zhM6f1sM;#HMhulOojX<_($)v{G?yb>f7bRLq}GR@XA>~3s~9t>H8Ubwms^CV(GZlE zaUfSnoLd{yTdj=JY5`_}n2;l{DC4bLHxiEz^kdZkv1IMgjUzXyWy+VYD0TWGlfz-H z*7?U$vNZ5w_S36nGe`?klqF@MMWkv9p;BLJBSVAjNv3F#6rQE5JIA6*vO+atwsJOU z%rpvu%Tp0en3!c^z>Hq?=WuP}24E`k>f1J%3VVr5R0l{9((!r5jLcC;rW__(VOtH% zTFHm`NT%`I4O`+qL-fE}0c4K3vT2U^_TwHV7syxolGgR@gfb=cLijLDV9a99ff~a# zyH(mjF@j#|{GJXY-czN%%IWkCFhQE=T@@2-8bgNV=rJFzX$Vnz6Ii5^f-$v0vR_K= zU;z8WX|1CQh2*ZoalgpK#zV?f*2)zhd$11^To9L_&SABx@9ucZ4+{7jF&4QT25x_^ zAxQ z2Xtm4ri37eEclAwiwpXfCTVHb0z=oCNsYO4F*HuAL30dy%^sK2L-Bi@PfcR*2u&r# z*52C0$aQInLz#lBKPtG{N&81m#F{M5Sm_bg72|6YsOpTnQ5dL{hu!|TG&Y6F4#FTd zNKJ$^t5D!EPCfky3LiBxl+1J`j_+HaFP=PBqC7QmtVao#PUmtYox6|A705vb;h(%r z1)@3{8+8n-caWQjGpglR+b8)ou24pe&f6z25NL~Vd?6@k8{zabUA_+@DjK6dPXQg> z32noATA+0Rbh}3?U>zEwM)x3Re+op3iC-{V+Xg4>?U*J4;5L4Iq8h4WlnvW>EJhd#C`w{z0 zL)|-a@C~{%sd~<>t0(*54CWJi3m{`GipJk|A1K5>4AP%(itW43jDor26jhyV551&h z+3jU_;sA837Yw>Hu}kmT`u(TB?GYD%8HuD}Aw<|fqA}>!2w31Tt^d`b5P&rc-5jH2 zaKE{GXl>X;qOsT*GrP1(`dI#q*!*^1-u-fqIu>-Jm>|=mGn~)Jw&x44{}tN*SJ_uU zRkd|((~WdD(jna--7TF;hop3OH%NDPcXue=NQb0!H~;ay-d8Wz_kQ=^W1MjgL)Y`H zy;ttJ=6t3gcZUP!Jt43DakuNhD%~Ux1aDV_scX+_IaIwFHYBT-tB3NMj%t&3#D<2RwFoMXZw;VowBD2SQ>?4 zBEuFOjLh!XUPu(IJMrh#J`usd>1#&tulr<87WKwt8)sKH)CLvu13TT2tq*rAch^EY zsu|{2x33|5?rxl*63bf7K|m;#HECesUK5$H_hE&xxXbUfdl8eCih$17B@&@FYvHk% zDEP6P(z$%=WyIJkmQB6N<&{&xD(1M#cBhQO>&5m1J|&(Y}fGe`U0Qwa$Q*M zw3To`R$6fsT7zkm2PNR$V~|=D{6k4KUyR^I8xL&zfD2Z!FG+S;tuNiAdYN42w~N9< z2Fsp_FgQ3`aqfK5ZMaE!u*3S1Wt55jnWr2JWj`9mcw@Dx!qzI0ml(9EgAeU~mANeE+%`A+iP^7s zhk53vFCy`vo5I(>O#%>NoR*t|_F@L)LXqCu0J6r=jP8KyExRLX!=gnWcFB_UMTSq) zIG!@ENc=}mw3Qn?!z<;+R?&@53;Oawf@;nD%jEX9iJ7YC{1aM)stg0BPc72SDdWQj z>x+x3voos1Ss@b2>~ZTaNp>ddDmrywpN0+=PErl^1rjjTT4#rF`)v4TssqsB>Q$RJ zwK~FROA!gmt(KF@2qj3VCmG3SUDdxh1u;?ES1u;C<~5yzXyH1g=c&hd^WuvyElJ`k z5qvT1mA`;1C|^KR7(iw|^DnW|XwmWmcsXN0vk7&HLvB%j{>mB`;$FsDI5c7(%#+_C z0}87&(P)+SGGRU|s%+$fKT0Fv1^nq(B5O9iogrBvWArMLQ3;l9zlwRe9h6nb-7G!9 z!T=xdP~3WgcOr(w8RlbWC8{>e39bjPlR*TUr>KM)R>B{RdXl++D z)4#G&g(cq)LnTb;_Ik?~liDGmfbDeo&V*Vi)t||VIR~@{kEzx8Bn1vgZsa=(r5cw_MGN$z*5BBh1DzmZZ;1t<39~ zCqNqlVr1(6M<5l&+0eFW$n<@N(TIet%{xSabD{{7@eD@qQ?m;`41SK79KgrEPz)|r z*{!DvQ?dwFdc`9Uq5BARTXj&r`qX`n+2~vNjqrRF6vu&glkGx*U*Svj*S&0kJZ;YG zc#+vF1$hNEPZtv@K_`N+-s%1WhpTb+JVDnt&hB}ZW7pWSek+rLM)>RG_i0_wJj^GE zn^%)LWNMs^Yfvj8YwP%&-w?wfb5}suDS4P{`@UUWjxi(d19#dA%k5r$r8~^5E^cKt zK%y{&D&3mBzus&UD5dSpf~_b}q~(+xZ{mS|Q*q(aLfQ05v~Zsu&8rD_DuA*)9pqTC zH$)XA3%lHG;piayGp^7O=GvyTnBx3+GxRb`Qq~mm$2+RqLYPoP^pU;HF9O`n0V7fN zreUK;-!eG@3dW8kEij74fU(jRRtraHKcmGc@d}+)Qr}0r4Ht|vsqI0>IR|ep`ad+f zew`W=HKw%vB(B27;NhExkQD*ge*-7>oifVMKLa?mj~d1iZ4dC&e}C zD|tBApiNO8vTSDryULH$OML{B2OQCl$ag$q6&Cv4D!cEmm&Idtt(`$yMI+4^^Z1#% z)BIksrb3t~?0h>X*~Jwc;q^mn95XFWy5P64$WoCgpPbB?%%fRG?gDnZHq+5AY=I{lC$srho`453`HGxDM4l%-s+6^-)$Xj?nvAxV%ypsK1*HSZQ`ANR0SR;`!&yhrPm4vLI_)vG#%>?*dyeQp+-d>~GrJ&A zur;DOqIe8zP4b7OnYJ6M-i?^GQ26IyM;+?%O8G@87Cb!$3e0zDt8hfcXYC(niT$_Yb@RiO4%6j zl(Ka_6lT(NRF`jA)DbsxDGT8g!__&i?YKwgyB3$P zK;%dYBFRUF0lhB@6ED#GMQn8%3Kqo#MQ?e=@ ziH5B%;y3TV(rQ*$l|x|JtLJQkRNX_R)k1XSzL`)y z_aY;D+k7ZdXeEoz;~8T0saIVyI^U|;g-=-2{sQVXYoM&fOEMe$_sqUPUR71 zm*afYT?c|OxWn7=5^~XRG<6pc7U$tJ<9~|)R3*Aw4;^V9V4y!s{`ngyd0a!$lJH>= z!gv{9l#6|sC{Z!Fe8}}(VQparZ4^*i-^SFkB)=ki^w)*xvxVyIh&N(1ljDMG-Ox#5 zti$eXKzDua>Wd_~Ms#*Fkf_%=8&^5Oid4<9+J}6|z{{|3xOCIZAS=A%#6v!!-!$LKKAEwsH%sr z1uSNn6qPZ#WKN7I&TEQ@AcB2OzYcJpKbDZV1(u+P;tFduln3czWG#hpX|T-$jBA1} zX!AVASKj?bW7?(n4L+BRc1`F9c9`kD_Pq0>S*`eI!p6J-mk>2L!|dyMBxs8K}P>ke70P zQl!2O0&vJ!4N+E(KOc@%XwAHigA@cC(?a4Gu>D>Mje{laF;-=lN~n2fF9~FUmMQIu ztc#f}*{4gVTW+`8mGn{`BSU*YX2psi-n;GOv(%%-Hk-SV!``Pf4`4p7<=9Gahq4S( zqHGjBWGO5n)ll)%QzvaRZCq{5JXvu}1U-Q+B&^xh0yuC7hI2pqHdQaWwLvM{da3pH zt_2qoSEW8@SDsK81G8>7#x^g@(@*vKt~e_?T}S>WJbjCAy^b~@Tkhq$BCfC533v%N zF!4Vg>tWedbX`MxkUKe1gr=Wf>0m{y8cE%q!Q6vfNnVo{J1KUR1JY5;l>oB6Zh5}P z*$VWH@%<9-muX&ZvS%+VV1v7aWPDJ)A2oxd5kh`GquOPBP}$eV%(QHjaO*y7Z`(|k z>=D4%SkAw?H&}7YEu@8%EQu&2^vtCaIT~mwCWSuOq;SRTVzJ}p75Lbt~)`taaQ#D$TTW#P{ zt&{Zd^^&UsZq}y;BAE@_AzaQ*BW9SWP#3D!r!#0$6Y1DoISY_Ag3w(;wogD*RI+Wem#H)9RbU?y7GjutCrHVB)Jy-(!8bSY@%}zU7OSC z%V)QD(7F`wK$Sm-@3LX0Y<)X5R%bVcxy(@Mgl~w-BnO)r3aDDBtIb|Cy55VpXG%d0WHM`FWRRcI1wIjM9%!sa7*T;^!tXC`V*B%RWX0eq+6u1I=zKT4lNSi=PE&&6&mu z$DWO;!+)9HGi^xh3|cPcsL-iFb8mjH)U^UOr5jtcioA@}a0z;8>J?5}7mk}Z4Q@3& zxW^A7J!nFBo`*r_=GC;`%4p0yHE%+jZ-zNpFlkA5EP}VMp=x(-hUVy81k-9s!=0J@ z@~|MkI9@w`5zBu}ox9DGtJGgR6^ch>Dae;4$|+)}G7ip&4dccDrMo@9qmz{V<SE4rlTd+GwX154>%e!JXIz``MoXyfG!3l69-dGXmw-(bh71p8H3njf>(3zeaa)80Ol z5*Y%~(+KESmMOhS$Z$~^wfRi-a|8H@vi!)hF&FujYAO8jj_9rHB@RAzZI?svw((fRyOZ85Y=QiSWU$x9kG>S3Jl$j{3>uSh^ct@cPF~<&zA|o&q@Xq6Jp?z$#LpN80Va-9SxjK^$ zEZdm6dm@obL+G+Yg$RUIeW{&S(kfQzfmR38+Ts_pZmx+Of1KtB z`Gj=zhUW2*qa|d~BjtmALRA*()jJf6UjFC@eDF0UZT}}9s^0#nGoKFIam;JAMF@H5 zB2ikXO6e++7rHf-g^iqwTCAYfhWrTxCpCvByNqgutBBL}#~G?}Ixy?}ew1TAFbY-y zDmrjs@20*%`sc6FzuqHN%6y`1=mwdD8e_j)wo{_BANc&4=ngI#+BCPzE=h7G7i#KoRQk z!-z!3cta<*>z;%^8AXCZHYuhMKA7I}BommLW{&@tK=!6k31&Hj=MyuwN`=-UxqLY6&UWh4aJ5H%B%hoPt!U z%rZSCDHWa_^69V(HQ;z$#_BJaAaw}GTTvE8iLfBF4x6TML__Qw*%XL_Q9xL540K^E z-99ylW{l6=Mc9f+2RPSpM0z{bRn@txx=>KsSV_HOGk8@2CaFvVf32wM_$e#+qWzD4 z05`tR(7$y{`lShfobLZ8R!qd?gN?0%o$il+{^QWHSNYqUNjbzv84ai$UfI@9F@~nN%X#$Qb_?_KRW}{x(Z)~WxA!G ze)^l)W4RxxHf?3d6)l5f^leesSQq%21`c)biK6zWn4a{B>JRSXtcq=PFg%M|{&hX? z6&T2rvfmljDF;WwO@!uAiZIe)z`&@5vEO2{zX(`AH$!} zgBD|~nQw7Jqm=G){*tU7v+_BrrDT&BYf`ROvqf`ad*2C*^=36L3|CeY3*U`nsfs*b zLO>G3V7jf<90lVz5*Y5A(dk-hcZgc=nlr|xWGI~voR|6tLm-yh-~d$&Re3@0r&` zjHy=3m4gZuDU=8>H4c5<%v3MMLXa54b~D9Jobh6Wl1xx`H&U#;gi_7s$*fSU10<~I zWo9d{MN0}lSKLUVda^@Zp1cb6{E-4&+8&zra0~mzqsm?vIlnN*!=}a#PlxO4*JFV; z-M!m5!{1ovr6-rA6=D2ecca1iIjlX3xnRtjm~U~`1#(`3X~*$He&Q4Z$hJp>c=nF# z6JvFwH4TeActSV^l6j}E-h#+pQ}1bBd)?kVrXK?`w7iJQBO0(DZ>WZ}PFy(XY{rF& z5!+i)VLiZYSl{;C=TQFwTT^WSHb*^}n&CF?#RaV?%GTJ~h||+Zu|omU09_xEeU7dr zrC@xY^R9R3gtX_XnD!!)x5n>i9gC{Nq2OZ}2IXx!0(W#DfQ*#+IiIt@Swj6x|T}r$Vz6_#J3Xhj zCGejfC1pPZG-m3Wj^ltA7A<`+y>E=f!))%@^VXlB_tgOh%{NuS4LFeegnb(|ZG~42 zLnc#PmQ2Q$pmveaKf65BFe)7A$*fY}m|Sf}SKoc<7_N55@x(|oAfP~nZ|VpZ&5hk9 z?o>9;$TQCDhQyot6*G)2FuLF0J>>t!`2i$)Co2vb;XMnsD%xL4qTeaWUm6ji-Dg z^3k3z&k-uuF?3*tDC;fK-F|lY7}W|9#Y+*6mo<|h+-15`+XUUUk;PaaXwlk<+&!1| zNb0Kgh@yEz-Xd}dAYi!>_$!dF?I2Ac-FsgaYFQ^Rdz%(2W~X2G7Yg8`;7!NRPxn*e zpA>(yjec5>zW7M92AR(ly`l4AEE2bui~&vEQ3T0EC5GfobSG@p&VhO>l8obJn;Zeo z>8B-TLsu+YBf-8m6x2B9tI^(|1(gW;_j>VtH!s4z)OB(Y#6CTXW7crANcadaNc1E9 z)_3M_qu@tGfyx&T92K-jk%fT?p-QFx@Fg;(N%lAc4u6s{$HI^eGHKieN^5Z|br_WQ z#Ilh_AIArRG$bT5$NX}0!IR?Lm_odAn4!sd%s>+XSvb)|PVYCs8YMpgX+!J}VQfoSt)wFz3y;@#`E&_szN`iVvYJu_xJ4a>rGYyNwp#^3!#=?}6bLK(dDq z`c5--w%G%zg&}*}gA9pN zr!et3BXv8ro-Q)>gSN4jXMs^@%1r%06CR4hp;T8BY&dtQoI8G9VyLj$*_R6B^CB{r zHc3*w6H>xN#Y_^fK6qMq-6p&Cg^@%#)J`i-9cyQJ*q*;dg!seZQ? zB)_r0wgruiT%uYE?LHsb|Kdm{#-&TQ6AQFN=DPRUFzoV@(4WMXd7?tIOx~KE&*S{? zFsLRJ%s@}lNVspkPL2Bd((J7q@<&M}fOC3SS56^pmQM_UEu->Dq=8BS)M2rGqp9SM zDW_FVQ9MkNSZRq$_^z^_`UFSRmyBZ&YFpdECa=djnu1t$K(-0i_vhouGvL$3jguDn zQH1z7Y;o_&o2%@=xpd+r=3Bb!*;`xn(erCaOTS(jiB?qkYOV%IgAhQ~Vd363!V3X{ zJDnkG(OB+w{2Qaolw=?Dzs%M&iUTc733T#vXU7%Ilbu&NOc3hm&1DbeVt$oUlS`k?%IBtF8KFy#u;Ser3^VVkZh5^ZSpqc_^Ux5_A) zf{%mn>+IF|YqS87a&Jm0>I9&h2Nq?6dy!6ZhWyp~Ydle>rOSRw*a z%VZOm(%)3?}Yna4K(Dfaw?;>1mvUM;};KqWn~~IN27kU ztyIKL$~*il$#(QX^~3E@qy}VaDIPbKFfItanT(NJ@E9QgOjq+#rn zcUE;+El%WPK6Buc>WV=OsAF}q?(_qS}1nrFl;F(h7>pEHk@Q=)*LhGwW;K-Bnc3XRZPh}ghV6J@erVWH2sc=%D(J8 z-V)9Ru$FxPK}2%%I+W;hwG!<6@G;6))Uh+F+#NZ>@9v(mIh#KLv&tZ1%Y6KhqL z4Pe{*TH9}qv@0LBIHZpFGIVVNQ@GkQeZ{*kUEwc`;T?8h{OZCGbVnbeRZ)pUx9;BJ z3#Uycp3QBY0{lg6O(&GdKYu(#^qAqXKY?_eJsi<8`WnUYqdk6Ce`+}qKXCXu=Bii( zl5iLFXPA}4ksR4|afuXM*JuG(Z)IN@kEWNG)XzJDxEv%q!f|NvMx}WAW8EZfDR%ZL zs4^dnl32*N(ZP%=AtL~}cqT+}8DDlOqz_Hzs77LKf0~pM2;AvE0W*P}MWU%0xduzm z?cv`?a`omS<~MJAOdd!<+h@Fm6i~e|kz$AGN)^TJ=UfDBLopw^!dxRsxdWPWq~9me zkzEGA6zAUD+>>qt2XzBmP?#lJs(oRS{;84)za`jM-wx0S-No)OoMKr8`4(>~14#CB z%UjP?6Go6~l3zgkWEn8IFJ0aop06pCT-`RIaiw3HJiw7^+iTyWW%>Gr8w+wavk7gh z=bw3Wk1XsYN*;x-XqFJ)bcaVz5H zS;AEUwrv7vR+czxols#JX%>D4juIJP+srd)Ri~v0&ioCc2?natg2S zI7_*syFNTvr*NC2%mZ_2SC$fN8x#!BCKe=xv^nwk>pSNg0cgAe!0z@60tkrv@4MSy z_O(CWIi*c(Yyj#zf9!JkKN$TIKbRV;B|G^JAXGBS+En^YKZCH15#wVkpy0W9LP;=9jAC-lAdZJncn>u=OORVrzLy9D%C`vT(jQ%Fn?>a98Nv0(As@ z7BNIshDsFa{3Z=;Dho3Q`K}8&F>6(|-NVurIByVMygY>UnZR?>XAdVTdVN}_1z)7T zpC&9SOGT=*VOeiCVK(a_Dqpo3e~(6&q^TH!QzmUO*huS7Uti4F{*n$WI?kBi%#P32 z^K$mVmvn~K8k1_Aab;Sj(E(u+o6sPLET%b2pw`GHSzgl!sQawVe|ahYE3L@RaA->` zCRzAKSB8bE%VoIxXk-YZbC03=rC>MVn^V?u{$6N!Sj@?aKpgCmwHANUP*MJpo5#yQ zouYVjrlHGaK7XkzdwMB+J$CnOJ%5`9!6LR}Eroa;!zv!S(7jsS@;umhqNQOhlUvVT zA{7%=86OgGA`T)>EaHRLCPdC;r~5#eu5097cRBt8xcc~HqYjwwjxwtd*u{;q+c;#R zz+|IUMP^Mx!N+oeioU|y3AM2}!hC(>VYW^IAMVY>{>|E05@bX$SQd*g@yW{y57e)a z^W%|ugDn250~}VXPeA0Pu{nsJFzE3;Eg_)$NE1GU)(P^mZDLyTZG_=YHlSvpbMx@Y zhmSti%f=q=!|LuA2TZyO62yZ@>kxY`5)D?YRDf1I)ah%pDa|cb3~F!W+JeVu3#*MX ziL!uV2^q7K8YA7HQ0su5VkmbBPcWSeQC&U@wi6sj-`WFMU0eadVE<|a2pAYzelYkS zW*2h>6cto=iz+MYYGX0@*t$6}A3kj;{$f5vSfohgAoGu`bM?}ylhgXMU(AX;GI=wf zx<+bz;tDS{jBazEvU#&6Z5;HV$SOLm^WGi~HjeUaH;$&cTs~eLS<(UJSikL48%oVG z)E2?C!NtNtMmL~YRR@x67&!?_ps^`|nuEt;ROXn0s2H(U=!1A2%Md6Xo)U^!$9{@i zk9B)+bm464uR~*`9;?{<#-UifNOM|2ty)gDgjlFvx64)y|Nuqg=mngb`D(Ea%*Ddvg{wh6v8nOM1w(0>hI zQmrwLDNp^h2zmj@qNEfiQS?ruN&b_qdR|MR!!_9p_vs?2UC#UQdL}&Xpsz0$!IQQS zq!n5rEI9B@W2ja_tufZ-5UB&eLKWw>^?To_*_)fgLMWwq|>MZy|(Qz;|` z;^H25NWnIurE~{+>$D772M{?CWA$z|!_=LC_s7Eo&*=m@iWjWnx9KKah1$+K8Ye`A zz53*MSU?JnK~JXYHi*c}*-@orGR54j?e=CSDg9Ak(jX@h{S(z1vBiimS>HF5Nw`j* z`=NMzV}s-kE^sOdV%@~GqU|Ww2=+0nEAX}Wz3y1HV#rp+4}hganf8D_GaKDd*1dCA z+bREBWzdE7GY==5VEnf?2v<&@!=@`PO!wk$#ZX5DA*l4xh7B9$ zWG06{s<^@lSEgSm~_)dz&@_8#e!9%|zA446r-P;j5DmdOEx^n%OtE9VG9Hj~4A z?Vw%{KRR^T{mv(*VK>M0`AOX{EkObe0Z*-dNPV0q& zqOElZg_yDxJm==U?p{Y&wq$ir%d@0(!lzT|Ho{q1K zi152%8-yF^FVe+dyGlQ>Mc)(rbrq#WGxmlAtfI|;pi;(vvx@$)nEtYM#wx5>PROA? z%21-h+H@=`GNZ8J(zEWlGGR)SBqcAqGg6kR7pF}n)Ov|wHBb~ z>Kr32vFF*v*ABfayQR2&?IN-Cj_@8OliOT2#n5)k&v&s>F0aAvkgix z9zkP?FDxYrS#ZS;qHWvO`$Tmhvn=wfQvSq(Zt4pTN6Xf?VP7;$Kp2^ynyC~B`1f$9oL3bI@H<$RmqA$D#z;Knis}40jlY@Wq^F}4J)uZfxODnqHyrV_UWX+n#92@vz^ZvG zd7!XfYDmMnIPGT}X9~}0TK8bBfVHe7UeKdEx~$lQ=iVTi(u#&}>@ zd|fiGFQ+u|>nUpbIZHZoS_X1HPuNDiRlETf>Ikasm=W)>rNE@nqP(RN%cSyX|uFRh!e%g5~mg|0vxG5bDWL z2jUhyrs;TPhTgcRKWS|OXPi=!nS6h6xRSpY?e4(4WTLoq-gjf4EtYgK3&r}Kr@712 zmvQ84DH+wR-*>%6OjEq0C;$(bFcLdT1)H$D1eN6st8#HA=0*Q|8gv}R5z4FE8T?;n_rgHik@ca)VLfg0q0D+C_mZgx+#_dGl?$KZT3=fDe6Xx zbHjf+IM@v%BSxDD>0WRa7OH>wVYx)}eT@oFl_`HAR~Gik)u4)t5JxOg?kpx^+_$@% z-smRZ#U~&v|4V~zBz}dUstdZJVZQk-0@C^>zq!0OeQgWprZcdG7A#BC7UFmkgkJg} zvXy0eK5I^I!wuFnn!_zQ+TgwxPV?YTx*-;AWP_1K8j5Lc4_8=sn>4*Cp+)a@q^rfm zzifw2!d&=(-Klf!Z;Wkto7&09Bj6*lj?SY7uL&*LtTUgeZ=#O)wgK!(>P0_PDJa!| zf>>0#F{l;JhMbM?sZanfk%;xXd@HYnOW>wUBy}^FlcS}kI36E{%+!}78eeQS(}>Dy z+XP$&Um?*UI%iCqxTZe}c8D?z^+#@QBy6G#oQb2}pej3&k<`psU?aU*Cdm_s=4uec zC;w19u=;9zkT}5Qt4SdqaaveldyZ77*@w(yyj$XjSM+mxHy2Fi@AB26DP#hMqdz7q z)3dP1uSr*NN5@>mF)cyZ!t@os3qNJxesNNr0Beq~r_Y2+AOM{Gm4`57ig4*2ux#Yb zGaZY%jtZLuKwmEcyomgN^mTp*oew|ML4TP|OO*hspz?@3^#F|y`%1J-_f<$;q$X4t zmVta2WCjxWq$%c3kNN|3jQZxS!Of(H3ug%f2RoEk>CZ1&Q-Q9&& zjt#D5T^VLgcBZVPpj@Sf)2OnJ(|H4OpGvKpyZlHW2nz=6u^1z?Z{xn1wQLc~QQs}* zx3nFw=grkLZYTO`yf|Q7NDq2^-}GrkS^Cu1BTxr3k?PmqpYJ@yV+D`5o3b8f|ac0f@31z;N~X4PFOyWcrjnw zt1uEt^h9S=xQ-8sN!G2x#kHcn)Ub&MZ%<=3iv{7-`nVcK=jgXUdqy{?xSP8tpPzW9 zK78J?--WBS7=)rJ+?Yf6I2g;b`^D_4AT{khH*S9DIL@1V2P3fV54~Qt>aTc&v*e5; z{Ee%&2dI&VC0Na+j(o88sfk703C3mlX$#^`X%NDO340A01S;V+3;g$mGag7-hp=($=W@K+<^NYUG7Cn6iXe_~P6I_wg7Z z~A z_lJ2sYFGl40o70TmMOcoPTib(uj{Zz334{pJJ6fHp(6Lr7CSF0QHYUg?|max!!fWc z1%tRG8m+h5;@7mryCsy<$CF!#Rk&efm^ntB1>q%OpAL>~?|dHb+e{Bxf=B?mtIS-2gXD+K;1@2e-^mvI)Mg0$~G+&(DuS+A}^2-fKV)^L+=2n6qd+SO2+1JmagmK@aR}KSOWC1V{vHfGK{IH1pvFHLUC04%*o5d>q zN43@6Vs>1f6Vp=R7+eSr$I`%)5DqCt7afB>k?2GZYnWzNeZsyceGOqP4mEt|L5@c}xHNR0Uy+lx6_2l0px95LsJ7H7aWT z4pm!Rb>r9$S{ND!S)0k$95ZgsoRQ?ijT=OzKEWQG8(Q~-Lvk4C(oG3oLJn5J9LwCk3a;4Fn@+S-2_u*S#UiiGJqgkR%O!~Ixt6DTCqgBc^pIKPUGAReW zFjgXnzZJ99(8S~vlRZE( z$<$O?tJFDMXF9|yj8LJGbz`|RO8YE0726$VZK2DqXsnMG99r?kwQZ#uHLBAz*%65T zP8qhHg?Jic{Z8;pyiP}7gX`?AyYEqltaovEuZ~FEW4C9WbI5hV|Bt!)%u+#L($^wOO_@bGx0}p%NX(WiJ68D5{&3MW(zCIQ9Vp z_BlUXm$3IEijD>H)Zqq8=cAI}xlbL4t|=QzA+iQOf#niCC2x8~bTDFHFw+a0bKT}* zA;j(DIv+d}0*1jrF_sF}8PSAGA0Xd&4i)hbQ?d#zzIeuwrW@*-zoWZB5|n7pxm0~@ zOYljcMND>7Gs`G0jfo;ZN(C3ev-F*b6e7o2u6VRB+%=|O&-)q}oe@>rkt*N};RKQ{ z+%G5tch@FE*WYOH$2j?&q!cKtK7PTdA&wyqli;nAzvVAf?cI5HA|5$#9>)zBAqs$P z>2Kz(Kjm|Nu^m2hIf_;ML-Y?6HiWt^(7beI3}G|dcHwoRfEd)cu|N^hL=WIlZr1!= zJe***N7qUg9rJh(!D~f=VrMuo z-e~NVfD;Fv6COC8u)kyPg{GQ8;MQqAochv{mH)K=x04v1@?qgYQwL~qHrIu{H1#f} zJLrN>qlccEQ^$UKoLzgijV2CS)id~FI$x>|ubks%<@N1WxV8m8$Q#Zz3|-Vdr628( z3B@WGYm%}q;lG6IZ|qC7vq;n$v>B>L%~Bm?nrptqsyE;u@D~dq#hs|C3-m4%pLqXj znulf}4B+3g>aFu$yJM(x1(E@^b?0L&RtcrwHx92l3KM;LZMRCNw@qzqW0n0@#k-to zqygS#`|nIxvpz%G5>S zzD1M0=EfioUhEj0qeDi+D4(nh2|M1JE76461{1 z800%_>Kd|sU{&GZ{Uu4UB%17zQu(y3I}zoV%{Q=75g37Ks1h%Y{oYvn&MiZo98JPd z>+?H7mrT09EKtPUmZ74wOkJ+%XqJ`r%~Ejm4ER_)5(Ul9O1_QR&zsc8n|DqA^}R25 zZ#AE@e_CaHukyS4r)QHj!c(^jDqxZZs5$@<06ssY_W`nZ|17(|`K#DIFbFCrAXgw1 z6i^Ys-vfa1Uk!VJBi4@#5$J&b`%h_MMSfaw84-Xu=3k4ktJ(Q~{~yYL&-WVrdF6P0 zSMd68F=>7oaS>q!#aGfIzanHjBL>(Jeq7&)Qvkm$KN$Um^LYt?_41bz9f058OZ*Vu z|0gOygu##NJJq+p7W|RJ;BU?1!G?>0X;q z?*Nu@>=%DHE&K_Yl?_bcFc*T(0W zWqtz6>HY6KGtW`Jm-^ltzh8jS_~ZJ%nA`zSerfXWVzkc-KTiSkXYm{_D*e9|{$)q` zmv^r}44!}QLf`N4c><1~1n@@xg5dAzIG*3Z^K1t{34l%iiQrd1(dU@YwYGm^&RYHx z=8vcHuavj{#`#P!`6s8}hkwEOo4M-y$CTt=djQ9NPog+IsOgy&)2JeBkB8`=(&F2 zPa+MszY+aX{~!J8pVb7PlRcMP`$?AQ`G1rBel$Oii~Wfy6!U*$lKfMY?DOhB53u=3 zWtjXos^@!`U!L9n(e}@SK7P`0r2dWO7uX+7^1nks{&qjl{MdgIjb{9f=s)QH%d7o4 z@^jzdpUBgIeb4jJ_dS!>ugJe|=;wY(KQT*-|AzVZ$MO$eO3!Qm-2dYzQ+e6HVEPAd zkmpR#PlS+Hz47-s$#aX@Pm;Cvzmfbo!T-{$|BpH3xfSFm iyjj Date: Tue, 20 Nov 2018 20:07:24 -0800 Subject: [PATCH 02/24] Renaming batch files to be consistent with python, and pausing at the end. --- README.md | 4 ++-- run-framework-gui.bat => run-gui.bat | 2 ++ run-framework.bat => run.bat | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) rename run-framework-gui.bat => run-gui.bat (97%) rename run-framework.bat => run.bat (97%) diff --git a/README.md b/README.md index dfff600..05f8b47 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,13 @@ https://youtu.be/mPfYqKe_KRs 1. Make sure you've installed Python 3.6.5 or newer. Here's [Python 3.7 64 bit](https://www.python.org/ftp/python/3.7.0/python-3.7.0-amd64.exe). Some older versions like 3.6.0 will not work. During installation: - Select "Add Python to PATH" - Make sure pip is included in the installation -1. Make sure you've installed the Java 8 JDK or newer. Here's the [Java 10 JDK](http://www.oracle.com/technetwork/java/javase/downloads/jdk10-downloads-4416644.html). +1. Make sure you've installed the Java 8 JDK or newer. Here's the [Java 8 JDK](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html). 1. Make sure you've [set the JAVA_HOME environment variable](https://javatutorial.net/set-java-home-windows-10). 1. Download this repository 1. Open Rocket League 1. Double click on run-bot.bat and leave it running. It's supposed to stay open and it's OK if it says something like "75%". -1. Double click on run-framework-gui.bat +1. Double click on run-gui.bat 1. Click the 'Run' button - Bot behavior is controlled by `src/main/java/rlbotexample/SampleBot.java` diff --git a/run-framework-gui.bat b/run-gui.bat similarity index 97% rename from run-framework-gui.bat rename to run-gui.bat index 77e207d..a1c00d9 100644 --- a/run-framework-gui.bat +++ b/run-gui.bat @@ -7,3 +7,5 @@ cd /D "%~dp0" call ./RefreshEnv.cmd python run.py gui + +pause diff --git a/run-framework.bat b/run.bat similarity index 97% rename from run-framework.bat rename to run.bat index 047f068..b3318d9 100644 --- a/run-framework.bat +++ b/run.bat @@ -7,3 +7,5 @@ cd /D "%~dp0" call ./RefreshEnv.cmd python run.py + +pause From b7b47b2338fddb6f035131a04752dc5d30622132 Mon Sep 17 00:00:00 2001 From: IamEld3st Date: Wed, 21 Nov 2018 08:22:18 +0000 Subject: [PATCH 03/24] Add python version check and if python is even present on PATH. --- run-gui.bat | 17 +++++++++++++++++ run.bat | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/run-gui.bat b/run-gui.bat index a1c00d9..700dc28 100644 --- a/run-gui.bat +++ b/run-gui.bat @@ -6,6 +6,23 @@ cd /D "%~dp0" @rem Make sure the environment variables are up-to-date. This is useful if the user installed python a moment ago. call ./RefreshEnv.cmd +python -V >nul 2>&1 && ( + for /f "delims=" %%a in ('python -V') do @set pythonVer=%%a + (echo %pythonVer% | findstr /i "3.6. 3.7." >nul) && ( + goto continue + ) || ( + echo It appears that version of the installed Python is not supported. + echo Please install version 3.6.5! + goto end + ) +) || ( + echo Python was not found! + echo If you recently installed Python reinstall it and check the "Add to PATH" during the installation. + goto end +) +:continue + python run.py gui +:end pause diff --git a/run.bat b/run.bat index b3318d9..9995643 100644 --- a/run.bat +++ b/run.bat @@ -6,6 +6,23 @@ cd /D "%~dp0" @rem Make sure the environment variables are up-to-date. This is useful if the user installed python a moment ago. call ./RefreshEnv.cmd +python -V >nul 2>&1 && ( + for /f "delims=" %%a in ('python -V') do @set pythonVer=%%a + (echo %pythonVer% | findstr /i "3.6. 3.7." >nul) && ( + goto continue + ) || ( + echo It appears that version of the installed Python is not supported. + echo Please install version 3.6.5! + goto end + ) +) || ( + echo Python was not found! + echo If you recently installed Python reinstall it and check the "Add to PATH" during the installation. + goto end +) +:continue + python run.py +:end pause From 481acbbe2da8210b2ae21bdd9134f9f3a9f710d2 Mon Sep 17 00:00:00 2001 From: Tyler Date: Wed, 21 Nov 2018 10:55:58 -0800 Subject: [PATCH 04/24] Revert "Add python version check and if python is even present on PATH." (#8) This reverts commit b7b47b2338fddb6f035131a04752dc5d30622132. --- run-gui.bat | 17 ----------------- run.bat | 17 ----------------- 2 files changed, 34 deletions(-) diff --git a/run-gui.bat b/run-gui.bat index 700dc28..a1c00d9 100644 --- a/run-gui.bat +++ b/run-gui.bat @@ -6,23 +6,6 @@ cd /D "%~dp0" @rem Make sure the environment variables are up-to-date. This is useful if the user installed python a moment ago. call ./RefreshEnv.cmd -python -V >nul 2>&1 && ( - for /f "delims=" %%a in ('python -V') do @set pythonVer=%%a - (echo %pythonVer% | findstr /i "3.6. 3.7." >nul) && ( - goto continue - ) || ( - echo It appears that version of the installed Python is not supported. - echo Please install version 3.6.5! - goto end - ) -) || ( - echo Python was not found! - echo If you recently installed Python reinstall it and check the "Add to PATH" during the installation. - goto end -) -:continue - python run.py gui -:end pause diff --git a/run.bat b/run.bat index 9995643..b3318d9 100644 --- a/run.bat +++ b/run.bat @@ -6,23 +6,6 @@ cd /D "%~dp0" @rem Make sure the environment variables are up-to-date. This is useful if the user installed python a moment ago. call ./RefreshEnv.cmd -python -V >nul 2>&1 && ( - for /f "delims=" %%a in ('python -V') do @set pythonVer=%%a - (echo %pythonVer% | findstr /i "3.6. 3.7." >nul) && ( - goto continue - ) || ( - echo It appears that version of the installed Python is not supported. - echo Please install version 3.6.5! - goto end - ) -) || ( - echo Python was not found! - echo If you recently installed Python reinstall it and check the "Add to PATH" during the installation. - goto end -) -:continue - python run.py -:end pause From fcdb653f15c05e57058dba861c72d5d3505e43a4 Mon Sep 17 00:00:00 2001 From: Tyler Arehart Date: Tue, 13 Nov 2018 03:51:22 -0800 Subject: [PATCH 05/24] Adding a DropshotTileManager. --- src/main/java/rlbotexample/SampleBot.java | 14 ++++- .../rlbotexample/dropshot/DropshotTile.java | 32 +++++++++++ .../dropshot/DropshotTileManager.java | 57 +++++++++++++++++++ .../dropshot/DropshotTileState.java | 8 +++ 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 src/main/java/rlbotexample/dropshot/DropshotTile.java create mode 100644 src/main/java/rlbotexample/dropshot/DropshotTileManager.java create mode 100644 src/main/java/rlbotexample/dropshot/DropshotTileState.java diff --git a/src/main/java/rlbotexample/SampleBot.java b/src/main/java/rlbotexample/SampleBot.java index c927534..cc7103d 100644 --- a/src/main/java/rlbotexample/SampleBot.java +++ b/src/main/java/rlbotexample/SampleBot.java @@ -8,6 +8,9 @@ import rlbot.manager.BotLoopRenderer; import rlbot.render.Renderer; import rlbotexample.boost.BoostManager; +import rlbotexample.dropshot.DropshotTile; +import rlbotexample.dropshot.DropshotTileManager; +import rlbotexample.dropshot.DropshotTileState; import rlbotexample.input.CarData; import rlbotexample.input.DataPacket; import rlbotexample.output.ControlsOutput; @@ -71,6 +74,14 @@ private void drawDebugLines(DataPacket input, CarData myCar, boolean goLeft) { myCar.position.plus(myCar.orientation.noseVector.scaled(300))); renderer.drawString3d(goLeft ? "left" : "right", Color.WHITE, myCar.position, 2, 2); + + for (DropshotTile tile: DropshotTileManager.getTiles()) { + if (tile.getState() == DropshotTileState.DAMAGED) { + renderer.drawCenteredRectangle3d(Color.YELLOW, tile.getLocation(), 4, 4, true); + } else if (tile.getState() == DropshotTileState.DESTROYED) { + renderer.drawCenteredRectangle3d(Color.RED, tile.getLocation(), 4, 4, true); + } + } } @@ -91,8 +102,9 @@ public ControllerState processInput(GameTickPacket packet) { return new ControlsOutput(); } - // Update the boost manager with the latest data + // Update the boost manager and tile manager with the latest data BoostManager.loadGameTickPacket(packet); + DropshotTileManager.loadGameTickPacket(packet); // Translate the raw packet data (which is in an unpleasant format) into our custom DataPacket class. // The DataPacket might not include everything from GameTickPacket, so improve it if you need to! diff --git a/src/main/java/rlbotexample/dropshot/DropshotTile.java b/src/main/java/rlbotexample/dropshot/DropshotTile.java new file mode 100644 index 0000000..378a035 --- /dev/null +++ b/src/main/java/rlbotexample/dropshot/DropshotTile.java @@ -0,0 +1,32 @@ +package rlbotexample.dropshot; + + +import rlbotexample.vector.Vector3; + +/** + * Representation of one of the floor tiles in dropshot mode. + * + * This class is here for your convenience, it is NOT part of the framework. You can change it as much + * as you want, or delete it. + */ +public class DropshotTile { + + private final Vector3 location; + private DropshotTileState state; + + public DropshotTile(Vector3 location) { + this.location = location; + } + + public void setState(DropshotTileState state) { + this.state = state; + } + + public Vector3 getLocation() { + return location; + } + + public DropshotTileState getState() { + return state; + } +} diff --git a/src/main/java/rlbotexample/dropshot/DropshotTileManager.java b/src/main/java/rlbotexample/dropshot/DropshotTileManager.java new file mode 100644 index 0000000..d4659c5 --- /dev/null +++ b/src/main/java/rlbotexample/dropshot/DropshotTileManager.java @@ -0,0 +1,57 @@ +package rlbotexample.dropshot; + +import rlbot.cppinterop.RLBotDll; +import rlbot.flat.FieldInfo; +import rlbot.flat.GameTickPacket; +import rlbotexample.vector.Vector3; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Information about where dropshot tiles are located in the arena and what state they have. + * + * This class is here for your convenience, it is NOT part of the framework. You can change it as much + * as you want, or delete it. + */ +public class DropshotTileManager { + + private static final ArrayList tiles = new ArrayList<>(); + + public static List getTiles() { + return tiles; + } + + private static void loadFieldInfo(FieldInfo fieldInfo) { + + synchronized (tiles) { + + tiles.clear(); + + for (int i = 0; i < fieldInfo.goalsLength(); i++) { + rlbot.flat.GoalInfo goalInfo = fieldInfo.goals(i); + tiles.add(new DropshotTile(new Vector3(goalInfo.location()))); + } + } + } + + public static void loadGameTickPacket(GameTickPacket packet) { + + if (packet.tileInformationLength() > tiles.size()) { + try { + loadFieldInfo(RLBotDll.getFieldInfo()); + } catch (IOException e) { + e.printStackTrace(); + return; + } + } + + for (int i = 0; i < packet.tileInformationLength(); i++) { + rlbot.flat.DropshotTile tile = packet.tileInformation(i); + DropshotTile existingTile = tiles.get(i); + existingTile.setState(DropshotTileState.values()[tile.tileState()]); + } + } + +} diff --git a/src/main/java/rlbotexample/dropshot/DropshotTileState.java b/src/main/java/rlbotexample/dropshot/DropshotTileState.java new file mode 100644 index 0000000..b2dba3f --- /dev/null +++ b/src/main/java/rlbotexample/dropshot/DropshotTileState.java @@ -0,0 +1,8 @@ +package rlbotexample.dropshot; + +public enum DropshotTileState { + UNKNOWN, + FRESH, + DAMAGED, + DESTROYED +} From 3967ab3a805cd12cd7ca3b365b1127b541726781 Mon Sep 17 00:00:00 2001 From: NicEastvillage Date: Fri, 23 Nov 2018 23:51:22 +0100 Subject: [PATCH 06/24] Added function to convert vector2 to tile. --- rlbot.cfg | 4 +- .../rlbotexample/dropshot/DropshotTile.java | 10 +++ .../dropshot/DropshotTileManager.java | 47 +++++++++++++- src/main/java/rlbotexample/dropshot/Hex.java | 61 +++++++++++++++++++ .../java/rlbotexample/vector/Vector3.java | 3 +- 5 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 src/main/java/rlbotexample/dropshot/Hex.java diff --git a/rlbot.cfg b/rlbot.cfg index 80411c4..37e9322 100644 --- a/rlbot.cfg +++ b/rlbot.cfg @@ -7,8 +7,8 @@ [Match Configuration] # Number of bots/players which will be spawned. We support up to max 10. num_participants = 2 -game_mode = Soccer -game_map = Mannfield +game_mode = Dropshot +game_map = DropShot_Core707 [Mutator Configuration] # Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. diff --git a/src/main/java/rlbotexample/dropshot/DropshotTile.java b/src/main/java/rlbotexample/dropshot/DropshotTile.java index 378a035..28fda76 100644 --- a/src/main/java/rlbotexample/dropshot/DropshotTile.java +++ b/src/main/java/rlbotexample/dropshot/DropshotTile.java @@ -11,11 +11,17 @@ */ public class DropshotTile { + public static final double TILE_WIDTH = 768; + public static final double TILE_SIZE = 443.405; + public static final double TILE_HEIGHT = 886.81; + private final Vector3 location; + private final int teamIndex; private DropshotTileState state; public DropshotTile(Vector3 location) { this.location = location; + this.teamIndex = location.y < 0 ? 0 : 1; } public void setState(DropshotTileState state) { @@ -29,4 +35,8 @@ public Vector3 getLocation() { public DropshotTileState getState() { return state; } + + public int getTeamIndex() { + return teamIndex; + } } diff --git a/src/main/java/rlbotexample/dropshot/DropshotTileManager.java b/src/main/java/rlbotexample/dropshot/DropshotTileManager.java index d4659c5..a7e7837 100644 --- a/src/main/java/rlbotexample/dropshot/DropshotTileManager.java +++ b/src/main/java/rlbotexample/dropshot/DropshotTileManager.java @@ -3,14 +3,20 @@ import rlbot.cppinterop.RLBotDll; import rlbot.flat.FieldInfo; import rlbot.flat.GameTickPacket; +import rlbotexample.vector.Vector2; import rlbotexample.vector.Vector3; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import static rlbotexample.dropshot.DropshotTile.TILE_HEIGHT; +import static rlbotexample.dropshot.DropshotTile.TILE_WIDTH; + /** - * Information about where dropshot tiles are located in the arena and what state they have. + * Information about where dropshot tiles are located in the arena and what state they have. Can also convert a + * vector2 point to a tile. * * This class is here for your convenience, it is NOT part of the framework. You can change it as much * as you want, or delete it. @@ -18,6 +24,8 @@ public class DropshotTileManager { private static final ArrayList tiles = new ArrayList<>(); + private static final HashMap blueTileMap = new HashMap<>(); + private static final HashMap orangeTileMap = new HashMap<>(); public static List getTiles() { return tiles; @@ -31,7 +39,16 @@ private static void loadFieldInfo(FieldInfo fieldInfo) { for (int i = 0; i < fieldInfo.goalsLength(); i++) { rlbot.flat.GoalInfo goalInfo = fieldInfo.goals(i); - tiles.add(new DropshotTile(new Vector3(goalInfo.location()))); + Vector3 location = new Vector3(goalInfo.location()); + DropshotTile tile = new DropshotTile(location); + tiles.add(new DropshotTile(location)); + + Hex hex = pointToHex(location.flatten()); + if (location.y < 0) { + blueTileMap.put(hex, tile); + } else { + orangeTileMap.put(hex, tile); + } } } } @@ -54,4 +71,30 @@ public static void loadGameTickPacket(GameTickPacket packet) { } } + /** + * Returns the DropshotTile under the point, or null of none is. + */ + public static DropshotTile pointToTile(Vector2 point) { + Hex hex = pointToHex(point); + if (point.y < 0) return blueTileMap.get(hex); + else return orangeTileMap.get(hex); + } + + /** + * Converts a point to a hex. + */ + private static Hex pointToHex(Vector2 point) { + + // Apply offset + if (point.y < 0) { + point = point.plus(new Vector2(0, 128)); + } else { + point = point.plus(new Vector2(0, -128)); + } + + // Calculate q and r component + double q = point.x / TILE_WIDTH - point.y * 2 / (3 * TILE_HEIGHT); + double r = point.y * 4 / (3 * TILE_HEIGHT); + return Hex.fromRounding(q, r); + } } diff --git a/src/main/java/rlbotexample/dropshot/Hex.java b/src/main/java/rlbotexample/dropshot/Hex.java new file mode 100644 index 0000000..e21f544 --- /dev/null +++ b/src/main/java/rlbotexample/dropshot/Hex.java @@ -0,0 +1,61 @@ +package rlbotexample.dropshot; + +import java.util.Objects; + +/** + * This class is used to convert a 2d point to a hex grid. Look here for more information: + * https://www.redblobgames.com/grids/hexagons/ + * + * This class is here for your convenience, it is NOT part of the framework. You can add to it as much + * as you want, or delete it. + */ +public class Hex { + + // For a hex the following must always be true: q + r + s == 0 + public final int q, r, s; + + public Hex(int q, int r) { + this.q = q; + this.r = r; + this.s = -q - r; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Hex that = (Hex) o; + return q == that.q && + r == that.r; + } + + @Override + public int hashCode() { + return Objects.hash(q, r); + } + + /** + * Construct a Hex from rounding two floating point q and r coordinates. + */ + public static Hex fromRounding(double fq, double fr) { + double fs = -fq - fr; + + int rx = (int)Math.round(fq); + int ry = (int)Math.round(fr); + int rz = (int)Math.round(fs); + + // Find how much each component was rounded + double x_diff = Math.abs(rx - fq); + double y_diff = Math.abs(ry - fr); + double z_diff = Math.abs(rz - fs); + + // We reset the component with the largest change back to what the constraint rx + ry + rz = 0 requires + if (x_diff > y_diff && x_diff > z_diff) { + rx = -ry - rz; + } else if (y_diff > z_diff) { + ry = -rx - rz; + } + + return new Hex(rx, ry); + } +} diff --git a/src/main/java/rlbotexample/vector/Vector3.java b/src/main/java/rlbotexample/vector/Vector3.java index fe7905e..b359c52 100644 --- a/src/main/java/rlbotexample/vector/Vector3.java +++ b/src/main/java/rlbotexample/vector/Vector3.java @@ -3,8 +3,7 @@ import com.google.flatbuffers.FlatBufferBuilder; /** - * Utility for reading a network port out of a config file. We're expecting a file that has only one line - * that's just a number. + * A simple 3d vector class with the most essential operations. * * This class is here for your convenience, it is NOT part of the framework. You can add to it as much * as you want, or delete it. From b697d966db7f80a1da5947405c9e987ac4b54aff Mon Sep 17 00:00:00 2001 From: NicEastvillage Date: Sun, 25 Nov 2018 10:20:34 +0100 Subject: [PATCH 07/24] Added some comments, changed back to soccer, and other small changes. --- rlbot.cfg | 4 ++-- src/main/java/rlbotexample/SampleBot.java | 4 ++++ .../java/rlbotexample/dropshot/DropshotTile.java | 14 +++++++------- .../rlbotexample/dropshot/DropshotTileManager.java | 4 ++-- src/main/java/rlbotexample/dropshot/Hex.java | 2 +- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/rlbot.cfg b/rlbot.cfg index 37e9322..80411c4 100644 --- a/rlbot.cfg +++ b/rlbot.cfg @@ -7,8 +7,8 @@ [Match Configuration] # Number of bots/players which will be spawned. We support up to max 10. num_participants = 2 -game_mode = Dropshot -game_map = DropShot_Core707 +game_mode = Soccer +game_map = Mannfield [Mutator Configuration] # Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. diff --git a/src/main/java/rlbotexample/SampleBot.java b/src/main/java/rlbotexample/SampleBot.java index cc7103d..b4a116f 100644 --- a/src/main/java/rlbotexample/SampleBot.java +++ b/src/main/java/rlbotexample/SampleBot.java @@ -82,6 +82,10 @@ private void drawDebugLines(DataPacket input, CarData myCar, boolean goLeft) { renderer.drawCenteredRectangle3d(Color.RED, tile.getLocation(), 4, 4, true); } } + + // Draw a rectangle on the tile that the car is on + DropshotTile tile = DropshotTileManager.pointToTile(myCar.position.flatten()); + if (tile != null) renderer.drawCenteredRectangle3d(Color.green, tile.getLocation(), 8, 8, false); } diff --git a/src/main/java/rlbotexample/dropshot/DropshotTile.java b/src/main/java/rlbotexample/dropshot/DropshotTile.java index 28fda76..06c639a 100644 --- a/src/main/java/rlbotexample/dropshot/DropshotTile.java +++ b/src/main/java/rlbotexample/dropshot/DropshotTile.java @@ -11,17 +11,17 @@ */ public class DropshotTile { - public static final double TILE_WIDTH = 768; - public static final double TILE_SIZE = 443.405; - public static final double TILE_HEIGHT = 886.81; + public static final double TILE_SIZE = 443.405; // side length and length from center to side + public static final double TILE_WIDTH = 768; // length from side to opposite side + public static final double TILE_HEIGHT = 886.81; // length from corner to opposite corner private final Vector3 location; - private final int teamIndex; + private final int team; private DropshotTileState state; public DropshotTile(Vector3 location) { this.location = location; - this.teamIndex = location.y < 0 ? 0 : 1; + this.team = location.y < 0 ? 0 : 1; } public void setState(DropshotTileState state) { @@ -36,7 +36,7 @@ public DropshotTileState getState() { return state; } - public int getTeamIndex() { - return teamIndex; + public int getTeam() { + return team; } } diff --git a/src/main/java/rlbotexample/dropshot/DropshotTileManager.java b/src/main/java/rlbotexample/dropshot/DropshotTileManager.java index a7e7837..fcd82dd 100644 --- a/src/main/java/rlbotexample/dropshot/DropshotTileManager.java +++ b/src/main/java/rlbotexample/dropshot/DropshotTileManager.java @@ -16,7 +16,7 @@ /** * Information about where dropshot tiles are located in the arena and what state they have. Can also convert a - * vector2 point to a tile. + * vector2 point to a tile, which is useful for checking the state of the tile where the ball lands. * * This class is here for your convenience, it is NOT part of the framework. You can change it as much * as you want, or delete it. @@ -72,7 +72,7 @@ public static void loadGameTickPacket(GameTickPacket packet) { } /** - * Returns the DropshotTile under the point, or null of none is. + * Returns the tile under the point, or null if none is. */ public static DropshotTile pointToTile(Vector2 point) { Hex hex = pointToHex(point); diff --git a/src/main/java/rlbotexample/dropshot/Hex.java b/src/main/java/rlbotexample/dropshot/Hex.java index e21f544..eef320e 100644 --- a/src/main/java/rlbotexample/dropshot/Hex.java +++ b/src/main/java/rlbotexample/dropshot/Hex.java @@ -3,7 +3,7 @@ import java.util.Objects; /** - * This class is used to convert a 2d point to a hex grid. Look here for more information: + * This class is used to convert a 2d point to a hex grid in the DropshotTileManager. Look here for more information: * https://www.redblobgames.com/grids/hexagons/ * * This class is here for your convenience, it is NOT part of the framework. You can add to it as much From 5beed8eba11e4b3b91c0302347c630e4e6fb0cde Mon Sep 17 00:00:00 2001 From: NicEastvillage Date: Tue, 27 Nov 2018 22:13:20 +0100 Subject: [PATCH 08/24] Added details section in the bot config file. --- src/main/python/javaExample.cfg | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/python/javaExample.cfg b/src/main/python/javaExample.cfg index 2737dd0..d85a9f3 100644 --- a/src/main/python/javaExample.cfg +++ b/src/main/python/javaExample.cfg @@ -10,3 +10,21 @@ name = MyJavaExample [Bot Parameters] java_executable_path = ../RLBotJavaExample/bin/RLBotJavaExample.bat + +[Details] +# These values are optional but useful metadata for helper programs +# Name of the bot's creator/developer +developer = The RLBot community + +# Short description of the bot +description = This is a multi-line description + of the official java example bot + +# Fun fact about the bot +fun_fact = + +# Link to github repository +github = https://github.com/RLBot/RLBotJavaExample + +# Programming language +language = java \ No newline at end of file From a04b6f94a3ff6c5986ae7f0c0a2b8041f5c9b3a7 Mon Sep 17 00:00:00 2001 From: RLMarvin <35970829+RLMarvin@users.noreply.github.com> Date: Mon, 7 Jan 2019 17:36:23 +0000 Subject: [PATCH 09/24] Change default appearance. (#11) --- src/main/python/javaExampleAppearance.cfg | 62 ++++++++++++++--------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/src/main/python/javaExampleAppearance.cfg b/src/main/python/javaExampleAppearance.cfg index 5cdf0a4..468bbe3 100644 --- a/src/main/python/javaExampleAppearance.cfg +++ b/src/main/python/javaExampleAppearance.cfg @@ -1,33 +1,49 @@ [Bot Loadout] -# Name that will be displayed in game -name = JavaExample -team_color_id = 27 -custom_color_id = 75 +team_color_id = 60 +custom_color_id = 0 car_id = 23 -decal_id = 307 -wheels_id = 1656 -boost_id = 0 -antenna_id = 287 +decal_id = 0 +wheels_id = 1565 +boost_id = 35 +antenna_id = 0 hat_id = 0 -paint_finish_id = 1978 -custom_finish_id = 1978 +paint_finish_id = 1681 +custom_finish_id = 1681 engine_audio_id = 0 -trails_id = 0 -goal_explosion_id = 1971 +trails_id = 3220 +goal_explosion_id = 3018 [Bot Loadout Orange] -# Name that will be displayed in game -name = JavaExample -team_color_id = 1 -custom_color_id = 1 +team_color_id = 3 +custom_color_id = 0 car_id = 23 decal_id = 0 -wheels_id = 818 -boost_id = 0 -antenna_id = 287 +wheels_id = 1565 +boost_id = 35 +antenna_id = 0 hat_id = 0 -paint_finish_id = 266 -custom_finish_id = 266 +paint_finish_id = 1681 +custom_finish_id = 1681 engine_audio_id = 0 -trails_id = 0 -goal_explosion_id = 1971 \ No newline at end of file +trails_id = 3220 +goal_explosion_id = 3018 + +[Bot Paint Blue] +car_paint_id = 12 +decal_paint_id = 0 +wheels_paint_id = 7 +boost_paint_id = 7 +antenna_paint_id = 0 +hat_paint_id = 0 +trails_paint_id = 2 +goal_explosion_paint_id = 0 + +[Bot Paint Orange] +car_paint_id = 12 +decal_paint_id = 0 +wheels_paint_id = 14 +boost_paint_id = 14 +antenna_paint_id = 0 +hat_paint_id = 0 +trails_paint_id = 14 +goal_explosion_paint_id = 0 From bd30980440fbb904a720d64b2e63fa734f486e99 Mon Sep 17 00:00:00 2001 From: Tyler Date: Sat, 23 Feb 2019 23:37:46 -0800 Subject: [PATCH 10/24] Making the generated batch file set user.dir so relative path lookups work. (#12) --- build.gradle | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b4ccb9f..7863d80 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,15 @@ mainClassName = 'rlbotexample.JavaExample' // This directory will be created and the interface dll copied into it at runtime. // The end result is that the interface dll will be available for loading. def dllDirectory = 'build/dll' -applicationDefaultJvmArgs = ["-Djna.library.path=" + dllDirectory] + +applicationDefaultJvmArgs = ["-Djna.library.path=" + dllDirectory, "-Duser.dir=MY_WORKING_DIR"] + +// https://www.mkyong.com/gradle/gradle-application-plugin-app_home-in-applicationdefaultjvmargs/ +startScripts { + doLast { + windowsScript.text = windowsScript.text.replace('MY_WORKING_DIR', "%~dp0.") + } +} dependencies { // Fetch the framework jar file From 00cdfbf4feeb14d90cc1845ac59d908a7b5c384f Mon Sep 17 00:00:00 2001 From: Tyler Date: Tue, 11 Jun 2019 19:37:06 -0700 Subject: [PATCH 11/24] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 05f8b47..e7c2910 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,6 @@ https://youtu.be/mPfYqKe_KRs 1. Make sure you've installed the Java 8 JDK or newer. Here's the [Java 8 JDK](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html). 1. Make sure you've [set the JAVA_HOME environment variable](https://javatutorial.net/set-java-home-windows-10). 1. Download this repository -1. Open Rocket League 1. Double click on run-bot.bat and leave it running. It's supposed to stay open and it's OK if it says something like "75%". 1. Double click on run-gui.bat From 007f4c13898637289c50134bcca51056b18e6027 Mon Sep 17 00:00:00 2001 From: Tyler Arehart Date: Tue, 11 Jun 2019 09:42:54 -0700 Subject: [PATCH 12/24] Switching to socket-based python interop, and adding a nice icon. --- build.gradle | 22 ++++--- src/main/java/rlbotexample/JavaExample.java | 56 +++++++++++------- .../rlbotexample/SamplePythonInterface.java | 8 +-- .../java/rlbotexample/util/PortReader.java | 23 +++---- src/main/python/javaExample.py | 15 ++--- src/main/python/port.cfg | Bin 8 -> 0 bytes src/main/resources/icon.png | Bin 0 -> 18448 bytes 7 files changed, 65 insertions(+), 59 deletions(-) delete mode 100644 src/main/python/port.cfg create mode 100644 src/main/resources/icon.png diff --git a/build.gradle b/build.gradle index 7863d80..0124827 100644 --- a/build.gradle +++ b/build.gradle @@ -15,15 +15,7 @@ mainClassName = 'rlbotexample.JavaExample' // This directory will be created and the interface dll copied into it at runtime. // The end result is that the interface dll will be available for loading. def dllDirectory = 'build/dll' - -applicationDefaultJvmArgs = ["-Djna.library.path=" + dllDirectory, "-Duser.dir=MY_WORKING_DIR"] - -// https://www.mkyong.com/gradle/gradle-application-plugin-app_home-in-applicationdefaultjvmargs/ -startScripts { - doLast { - windowsScript.text = windowsScript.text.replace('MY_WORKING_DIR', "%~dp0.") - } -} +applicationDefaultJvmArgs = ["-Djna.library.path=" + dllDirectory] dependencies { // Fetch the framework jar file @@ -86,7 +78,13 @@ distZip { exclude '__pycache__' } } - into (applicationName + '/bin') { - from fileTree('port.cfg') +} + +// This is the same as distZip, but not zipped. Handy for testing your tournament submission more rapidly. +installDist { + into ('../python') { + from fileTree('src/main/python') { + exclude '__pycache__' + } } -} \ No newline at end of file +} diff --git a/src/main/java/rlbotexample/JavaExample.java b/src/main/java/rlbotexample/JavaExample.java index 3b910ab..c188933 100644 --- a/src/main/java/rlbotexample/JavaExample.java +++ b/src/main/java/rlbotexample/JavaExample.java @@ -1,15 +1,15 @@ package rlbotexample; import rlbot.manager.BotManager; -import rlbot.pyinterop.PythonInterface; -import rlbot.pyinterop.PythonServer; import rlbotexample.util.PortReader; import javax.swing.*; import javax.swing.border.EmptyBorder; +import java.awt.*; import java.awt.event.ActionListener; -import java.util.OptionalInt; +import java.net.URL; import java.util.Set; +import java.util.stream.Collectors; /** * See JavaAgent.py for usage instructions. @@ -18,41 +18,57 @@ */ public class JavaExample { + private static final Integer DEFAULT_PORT = 17357; + public static void main(String[] args) { BotManager botManager = new BotManager(); - PythonInterface pythonInterface = new SamplePythonInterface(botManager); - Integer port = PortReader.readPortFromFile("port.cfg"); - PythonServer pythonServer = new PythonServer(pythonInterface, port); - pythonServer.start(); + Integer port = PortReader.readPortFromArgs(args).orElseGet(() -> { + System.out.println("Could not read port from args, using default!"); + return DEFAULT_PORT; + }); + + SamplePythonInterface pythonInterface = new SamplePythonInterface(port, botManager); + new Thread(pythonInterface::start).start(); JFrame frame = new JFrame("Java Bot"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel(); panel.setBorder(new EmptyBorder(10, 10, 10, 10)); - panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); - panel.add(new JLabel("Listening on port " + port)); - panel.add(new JLabel("I'm the thing controlling the Java bot, keep me open :)")); + BorderLayout borderLayout = new BorderLayout(); + panel.setLayout(borderLayout); + JPanel dataPanel = new JPanel(); + dataPanel.setLayout(new BoxLayout(dataPanel, BoxLayout.Y_AXIS)); + dataPanel.setBorder(new EmptyBorder(0, 10, 0, 0)); + dataPanel.add(new JLabel("Listening on port " + port), BorderLayout.CENTER); + dataPanel.add(new JLabel("I'm the thing controlling the Java bot, keep me open :)"), BorderLayout.CENTER); JLabel botsRunning = new JLabel("Bots running: "); - panel.add(botsRunning); + dataPanel.add(botsRunning, BorderLayout.CENTER); + panel.add(dataPanel, BorderLayout.CENTER); frame.add(panel); + URL url = JavaExample.class.getClassLoader().getResource("icon.png"); + Image image = Toolkit.getDefaultToolkit().createImage(url); + panel.add(new JLabel(new ImageIcon(image)), BorderLayout.WEST); + frame.setIconImage(image); + frame.pack(); frame.setVisible(true); ActionListener myListener = e -> { Set runningBotIndices = botManager.getRunningBotIndices(); - OptionalInt maxIndex = runningBotIndices.stream().mapToInt(k -> k).max(); - String botsStr = "None"; - if (maxIndex.isPresent()) { - StringBuilder botsStrBuilder = new StringBuilder(); - for (int i = 0; i <= maxIndex.getAsInt(); i++) { - botsStrBuilder.append(runningBotIndices.contains(i) ? "☑ " : "☐ "); - } - botsStr = botsStrBuilder.toString(); + + String botsStr; + if (runningBotIndices.isEmpty()) { + botsStr = "None"; + } else { + botsStr = runningBotIndices.stream() + .sorted() + .map(i -> "#" + i) + .collect(Collectors.joining(", ")); } - botsRunning.setText("Bots running: " + botsStr); + botsRunning.setText("Bots indices running: " + botsStr); }; new Timer(1000, myListener).start(); diff --git a/src/main/java/rlbotexample/SamplePythonInterface.java b/src/main/java/rlbotexample/SamplePythonInterface.java index e6812ca..829aa93 100644 --- a/src/main/java/rlbotexample/SamplePythonInterface.java +++ b/src/main/java/rlbotexample/SamplePythonInterface.java @@ -2,12 +2,12 @@ import rlbot.Bot; import rlbot.manager.BotManager; -import rlbot.pyinterop.DefaultPythonInterface; +import rlbot.pyinterop.SocketServer; -public class SamplePythonInterface extends DefaultPythonInterface { +public class SamplePythonInterface extends SocketServer { - public SamplePythonInterface(BotManager botManager) { - super(botManager); + public SamplePythonInterface(int port, BotManager botManager) { + super(port, botManager); } protected Bot initBot(int index, String botType, int team) { diff --git a/src/main/java/rlbotexample/util/PortReader.java b/src/main/java/rlbotexample/util/PortReader.java index 892b662..3664bdd 100644 --- a/src/main/java/rlbotexample/util/PortReader.java +++ b/src/main/java/rlbotexample/util/PortReader.java @@ -1,28 +1,23 @@ package rlbotexample.util; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Optional; -import java.util.stream.Stream; /** - * Utility for reading a network port out of a config file. We're expecting a file that has only one line - * that's just a number. + * Utility for reading a network port out of a command line arguments. * * This class is here for your convenience, it is NOT part of the framework. You can add to it as much * as you want, or delete it. */ public class PortReader { - public static Integer readPortFromFile(String s) { - Path path = Paths.get(s); - try (Stream lines = Files.lines(path)) { - Optional firstLine = lines.findFirst(); - return firstLine.map(Integer::parseInt).orElseThrow(() -> new RuntimeException("Port config file was empty!")); - } catch (final IOException e) { - throw new RuntimeException("Failed to read port file! Tried to find it at " + path.toAbsolutePath().toString()); + public static Optional readPortFromArgs(String[] args) { + if (args.length == 0) { + return Optional.empty(); + } + try { + return Optional.of(Integer.parseInt(args[0])); + } catch (NumberFormatException e) { + return Optional.empty(); } } } diff --git a/src/main/python/javaExample.py b/src/main/python/javaExample.py index dad0097..faf3765 100644 --- a/src/main/python/javaExample.py +++ b/src/main/python/javaExample.py @@ -1,18 +1,15 @@ -import os - from rlbot.agents.base_agent import BOT_CONFIG_AGENT_HEADER -from rlbot.agents.base_java_agent import BaseJavaAgent +from rlbot.agents.executable_with_socket_agent import ExecutableWithSocketAgent from rlbot.parsing.custom_config import ConfigHeader, ConfigObject -class JavaExample(BaseJavaAgent): - def get_port_file_path(self): - # Look for a port.cfg file in the same directory as THIS python file. - return os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__), 'port.cfg')) +class JavaExample(ExecutableWithSocketAgent): + def get_port(self) -> int: + return 17357 def load_config(self, config_header: ConfigHeader): - self.java_executable_path = config_header.getpath('java_executable_path') - self.logger.info("Java executable is configured as {}".format(self.java_executable_path)) + self.executable_path = config_header.getpath('java_executable_path') + self.logger.info("Java executable is configured as {}".format(self.executable_path)) @staticmethod def create_agent_configurations(config: ConfigObject): diff --git a/src/main/python/port.cfg b/src/main/python/port.cfg deleted file mode 100644 index 1256cfb1817cf7effe298709bcf1c94f4cf727fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 PcmXpsH#Rlr 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 Date: Sun, 30 Jun 2019 13:01:50 -0700 Subject: [PATCH 13/24] Updating ControlsOutput to include useItem (for rumble). --- .../java/rlbotexample/output/ControlsOutput.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/rlbotexample/output/ControlsOutput.java b/src/main/java/rlbotexample/output/ControlsOutput.java index b544024..ace5d65 100644 --- a/src/main/java/rlbotexample/output/ControlsOutput.java +++ b/src/main/java/rlbotexample/output/ControlsOutput.java @@ -28,6 +28,7 @@ public class ControlsOutput implements ControllerState { private boolean jumpDepressed; private boolean boostDepressed; private boolean slideDepressed; + private boolean useItemDepressed; public ControlsOutput() { } @@ -72,6 +73,11 @@ public ControlsOutput withSlide(boolean slideDepressed) { return this; } + public ControlsOutput withUseItem(boolean useItemDepressed) { + this.useItemDepressed = useItemDepressed; + return this; + } + public ControlsOutput withJump() { this.jumpDepressed = true; return this; @@ -87,6 +93,11 @@ public ControlsOutput withSlide() { return this; } + public ControlsOutput withUseItem() { + this.useItemDepressed = true; + return this; + } + private float clamp(float value) { return Math.max(-1, Math.min(1, value)); } @@ -130,4 +141,9 @@ public boolean holdBoost() { public boolean holdHandbrake() { return slideDepressed; } + + @Override + public boolean holdUseItem() { + return useItemDepressed; + } } From 82f97803f86746b027adca2b4fbb6879ec7f9c3e Mon Sep 17 00:00:00 2001 From: NicEastvillage Date: Thu, 4 Jul 2019 12:06:15 +0200 Subject: [PATCH 14/24] Fixed comment --- src/main/java/rlbotexample/dropshot/DropshotTile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/rlbotexample/dropshot/DropshotTile.java b/src/main/java/rlbotexample/dropshot/DropshotTile.java index 06c639a..a81f553 100644 --- a/src/main/java/rlbotexample/dropshot/DropshotTile.java +++ b/src/main/java/rlbotexample/dropshot/DropshotTile.java @@ -11,7 +11,7 @@ */ public class DropshotTile { - public static final double TILE_SIZE = 443.405; // side length and length from center to side + public static final double TILE_SIZE = 443.405; // side length and length from center to corner public static final double TILE_WIDTH = 768; // length from side to opposite side public static final double TILE_HEIGHT = 886.81; // length from corner to opposite corner From 6776eeccd06cb922401d3054421145032b4cb59e Mon Sep 17 00:00:00 2001 From: Tyler Arehart Date: Sat, 24 Aug 2019 09:13:23 -0700 Subject: [PATCH 15/24] Adding a ball prediction helper, and removing dropshot code since we lost support. --- src/main/java/rlbotexample/SampleBot.java | 23 ++-- .../rlbotexample/dropshot/DropshotTile.java | 42 -------- .../dropshot/DropshotTileManager.java | 100 ------------------ .../dropshot/DropshotTileState.java | 8 -- src/main/java/rlbotexample/dropshot/Hex.java | 61 ----------- .../prediction/BallPredictionHelper.java | 30 ++++++ 6 files changed, 39 insertions(+), 225 deletions(-) delete mode 100644 src/main/java/rlbotexample/dropshot/DropshotTile.java delete mode 100644 src/main/java/rlbotexample/dropshot/DropshotTileManager.java delete mode 100644 src/main/java/rlbotexample/dropshot/DropshotTileState.java delete mode 100644 src/main/java/rlbotexample/dropshot/Hex.java create mode 100644 src/main/java/rlbotexample/prediction/BallPredictionHelper.java diff --git a/src/main/java/rlbotexample/SampleBot.java b/src/main/java/rlbotexample/SampleBot.java index b4a116f..1639980 100644 --- a/src/main/java/rlbotexample/SampleBot.java +++ b/src/main/java/rlbotexample/SampleBot.java @@ -3,17 +3,17 @@ import rlbot.Bot; import rlbot.ControllerState; import rlbot.cppinterop.RLBotDll; +import rlbot.cppinterop.RLBotInterfaceException; +import rlbot.flat.BallPrediction; import rlbot.flat.GameTickPacket; import rlbot.flat.QuickChatSelection; import rlbot.manager.BotLoopRenderer; import rlbot.render.Renderer; import rlbotexample.boost.BoostManager; -import rlbotexample.dropshot.DropshotTile; -import rlbotexample.dropshot.DropshotTileManager; -import rlbotexample.dropshot.DropshotTileState; import rlbotexample.input.CarData; import rlbotexample.input.DataPacket; import rlbotexample.output.ControlsOutput; +import rlbotexample.prediction.BallPredictionHelper; import rlbotexample.vector.Vector2; import java.awt.*; @@ -75,17 +75,13 @@ private void drawDebugLines(DataPacket input, CarData myCar, boolean goLeft) { renderer.drawString3d(goLeft ? "left" : "right", Color.WHITE, myCar.position, 2, 2); - for (DropshotTile tile: DropshotTileManager.getTiles()) { - if (tile.getState() == DropshotTileState.DAMAGED) { - renderer.drawCenteredRectangle3d(Color.YELLOW, tile.getLocation(), 4, 4, true); - } else if (tile.getState() == DropshotTileState.DESTROYED) { - renderer.drawCenteredRectangle3d(Color.RED, tile.getLocation(), 4, 4, true); - } + try { + // Draw 3 seconds of ball prediction + BallPrediction ballPrediction = RLBotDll.getBallPrediction(); + BallPredictionHelper.drawTillMoment(ballPrediction, myCar.elapsedSeconds + 3, Color.CYAN, renderer); + } catch (RLBotInterfaceException e) { + e.printStackTrace(); } - - // Draw a rectangle on the tile that the car is on - DropshotTile tile = DropshotTileManager.pointToTile(myCar.position.flatten()); - if (tile != null) renderer.drawCenteredRectangle3d(Color.green, tile.getLocation(), 8, 8, false); } @@ -108,7 +104,6 @@ public ControllerState processInput(GameTickPacket packet) { // Update the boost manager and tile manager with the latest data BoostManager.loadGameTickPacket(packet); - DropshotTileManager.loadGameTickPacket(packet); // Translate the raw packet data (which is in an unpleasant format) into our custom DataPacket class. // The DataPacket might not include everything from GameTickPacket, so improve it if you need to! diff --git a/src/main/java/rlbotexample/dropshot/DropshotTile.java b/src/main/java/rlbotexample/dropshot/DropshotTile.java deleted file mode 100644 index a81f553..0000000 --- a/src/main/java/rlbotexample/dropshot/DropshotTile.java +++ /dev/null @@ -1,42 +0,0 @@ -package rlbotexample.dropshot; - - -import rlbotexample.vector.Vector3; - -/** - * Representation of one of the floor tiles in dropshot mode. - * - * This class is here for your convenience, it is NOT part of the framework. You can change it as much - * as you want, or delete it. - */ -public class DropshotTile { - - public static final double TILE_SIZE = 443.405; // side length and length from center to corner - public static final double TILE_WIDTH = 768; // length from side to opposite side - public static final double TILE_HEIGHT = 886.81; // length from corner to opposite corner - - private final Vector3 location; - private final int team; - private DropshotTileState state; - - public DropshotTile(Vector3 location) { - this.location = location; - this.team = location.y < 0 ? 0 : 1; - } - - public void setState(DropshotTileState state) { - this.state = state; - } - - public Vector3 getLocation() { - return location; - } - - public DropshotTileState getState() { - return state; - } - - public int getTeam() { - return team; - } -} diff --git a/src/main/java/rlbotexample/dropshot/DropshotTileManager.java b/src/main/java/rlbotexample/dropshot/DropshotTileManager.java deleted file mode 100644 index fcd82dd..0000000 --- a/src/main/java/rlbotexample/dropshot/DropshotTileManager.java +++ /dev/null @@ -1,100 +0,0 @@ -package rlbotexample.dropshot; - -import rlbot.cppinterop.RLBotDll; -import rlbot.flat.FieldInfo; -import rlbot.flat.GameTickPacket; -import rlbotexample.vector.Vector2; -import rlbotexample.vector.Vector3; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import static rlbotexample.dropshot.DropshotTile.TILE_HEIGHT; -import static rlbotexample.dropshot.DropshotTile.TILE_WIDTH; - -/** - * Information about where dropshot tiles are located in the arena and what state they have. Can also convert a - * vector2 point to a tile, which is useful for checking the state of the tile where the ball lands. - * - * This class is here for your convenience, it is NOT part of the framework. You can change it as much - * as you want, or delete it. - */ -public class DropshotTileManager { - - private static final ArrayList tiles = new ArrayList<>(); - private static final HashMap blueTileMap = new HashMap<>(); - private static final HashMap orangeTileMap = new HashMap<>(); - - public static List getTiles() { - return tiles; - } - - private static void loadFieldInfo(FieldInfo fieldInfo) { - - synchronized (tiles) { - - tiles.clear(); - - for (int i = 0; i < fieldInfo.goalsLength(); i++) { - rlbot.flat.GoalInfo goalInfo = fieldInfo.goals(i); - Vector3 location = new Vector3(goalInfo.location()); - DropshotTile tile = new DropshotTile(location); - tiles.add(new DropshotTile(location)); - - Hex hex = pointToHex(location.flatten()); - if (location.y < 0) { - blueTileMap.put(hex, tile); - } else { - orangeTileMap.put(hex, tile); - } - } - } - } - - public static void loadGameTickPacket(GameTickPacket packet) { - - if (packet.tileInformationLength() > tiles.size()) { - try { - loadFieldInfo(RLBotDll.getFieldInfo()); - } catch (IOException e) { - e.printStackTrace(); - return; - } - } - - for (int i = 0; i < packet.tileInformationLength(); i++) { - rlbot.flat.DropshotTile tile = packet.tileInformation(i); - DropshotTile existingTile = tiles.get(i); - existingTile.setState(DropshotTileState.values()[tile.tileState()]); - } - } - - /** - * Returns the tile under the point, or null if none is. - */ - public static DropshotTile pointToTile(Vector2 point) { - Hex hex = pointToHex(point); - if (point.y < 0) return blueTileMap.get(hex); - else return orangeTileMap.get(hex); - } - - /** - * Converts a point to a hex. - */ - private static Hex pointToHex(Vector2 point) { - - // Apply offset - if (point.y < 0) { - point = point.plus(new Vector2(0, 128)); - } else { - point = point.plus(new Vector2(0, -128)); - } - - // Calculate q and r component - double q = point.x / TILE_WIDTH - point.y * 2 / (3 * TILE_HEIGHT); - double r = point.y * 4 / (3 * TILE_HEIGHT); - return Hex.fromRounding(q, r); - } -} diff --git a/src/main/java/rlbotexample/dropshot/DropshotTileState.java b/src/main/java/rlbotexample/dropshot/DropshotTileState.java deleted file mode 100644 index b2dba3f..0000000 --- a/src/main/java/rlbotexample/dropshot/DropshotTileState.java +++ /dev/null @@ -1,8 +0,0 @@ -package rlbotexample.dropshot; - -public enum DropshotTileState { - UNKNOWN, - FRESH, - DAMAGED, - DESTROYED -} diff --git a/src/main/java/rlbotexample/dropshot/Hex.java b/src/main/java/rlbotexample/dropshot/Hex.java deleted file mode 100644 index eef320e..0000000 --- a/src/main/java/rlbotexample/dropshot/Hex.java +++ /dev/null @@ -1,61 +0,0 @@ -package rlbotexample.dropshot; - -import java.util.Objects; - -/** - * This class is used to convert a 2d point to a hex grid in the DropshotTileManager. Look here for more information: - * https://www.redblobgames.com/grids/hexagons/ - * - * This class is here for your convenience, it is NOT part of the framework. You can add to it as much - * as you want, or delete it. - */ -public class Hex { - - // For a hex the following must always be true: q + r + s == 0 - public final int q, r, s; - - public Hex(int q, int r) { - this.q = q; - this.r = r; - this.s = -q - r; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Hex that = (Hex) o; - return q == that.q && - r == that.r; - } - - @Override - public int hashCode() { - return Objects.hash(q, r); - } - - /** - * Construct a Hex from rounding two floating point q and r coordinates. - */ - public static Hex fromRounding(double fq, double fr) { - double fs = -fq - fr; - - int rx = (int)Math.round(fq); - int ry = (int)Math.round(fr); - int rz = (int)Math.round(fs); - - // Find how much each component was rounded - double x_diff = Math.abs(rx - fq); - double y_diff = Math.abs(ry - fr); - double z_diff = Math.abs(rz - fs); - - // We reset the component with the largest change back to what the constraint rx + ry + rz = 0 requires - if (x_diff > y_diff && x_diff > z_diff) { - rx = -ry - rz; - } else if (y_diff > z_diff) { - ry = -rx - rz; - } - - return new Hex(rx, ry); - } -} diff --git a/src/main/java/rlbotexample/prediction/BallPredictionHelper.java b/src/main/java/rlbotexample/prediction/BallPredictionHelper.java new file mode 100644 index 0000000..77b56c7 --- /dev/null +++ b/src/main/java/rlbotexample/prediction/BallPredictionHelper.java @@ -0,0 +1,30 @@ +package rlbotexample.prediction; + +import rlbot.flat.BallPrediction; +import rlbot.flat.PredictionSlice; +import rlbot.render.Renderer; +import rlbotexample.vector.Vector3; + +import java.awt.*; + +/** + * This class can help you get started with ball prediction. Feel free to change it as much as you want, + * this is part of your bot, not part of the framework! + */ +public class BallPredictionHelper { + + public static void drawTillMoment(BallPrediction ballPrediction, float gameSeconds, Color color, Renderer renderer) { + Vector3 previousLocation = null; + for (int i = 0; i < ballPrediction.slicesLength(); i += 4) { + PredictionSlice slice = ballPrediction.slices(i); + if (slice.gameSeconds() > gameSeconds) { + break; + } + Vector3 location = new Vector3(slice.physics().location()); + if (previousLocation != null) { + renderer.drawLine3d(color, previousLocation, location); + } + previousLocation = location; + } + } +} From 98babb46a5534433e512b5f6f07f934b43b58452 Mon Sep 17 00:00:00 2001 From: Tyler Arehart Date: Tue, 27 Aug 2019 10:26:15 -0700 Subject: [PATCH 16/24] Getting rid of unused port.cfg file. --- port.cfg | Bin 8 -> 0 bytes src/main/python/README_Tournament.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 port.cfg diff --git a/port.cfg b/port.cfg deleted file mode 100644 index 1256cfb1817cf7effe298709bcf1c94f4cf727fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 PcmXpsH#Rlr Date: Sun, 6 Oct 2019 22:39:37 +0100 Subject: [PATCH 17/24] Add a BallTouch class (#16) --- src/main/java/rlbotexample/SampleBot.java | 8 ++++- .../java/rlbotexample/input/DataPacket.java | 2 ++ .../input/{ => ball}/BallData.java | 6 +++- .../rlbotexample/input/ball/BallTouch.java | 29 +++++++++++++++++++ .../rlbotexample/input/{ => car}/CarData.java | 2 +- .../input/{ => car}/CarOrientation.java | 2 +- 6 files changed, 45 insertions(+), 4 deletions(-) rename src/main/java/rlbotexample/input/{ => ball}/BallData.java (70%) create mode 100644 src/main/java/rlbotexample/input/ball/BallTouch.java rename src/main/java/rlbotexample/input/{ => car}/CarData.java (98%) rename src/main/java/rlbotexample/input/{ => car}/CarOrientation.java (98%) diff --git a/src/main/java/rlbotexample/SampleBot.java b/src/main/java/rlbotexample/SampleBot.java index 1639980..80c5e3d 100644 --- a/src/main/java/rlbotexample/SampleBot.java +++ b/src/main/java/rlbotexample/SampleBot.java @@ -10,8 +10,8 @@ import rlbot.manager.BotLoopRenderer; import rlbot.render.Renderer; import rlbotexample.boost.BoostManager; -import rlbotexample.input.CarData; import rlbotexample.input.DataPacket; +import rlbotexample.input.car.CarData; import rlbotexample.output.ControlsOutput; import rlbotexample.prediction.BallPredictionHelper; import rlbotexample.vector.Vector2; @@ -75,6 +75,12 @@ private void drawDebugLines(DataPacket input, CarData myCar, boolean goLeft) { renderer.drawString3d(goLeft ? "left" : "right", Color.WHITE, myCar.position, 2, 2); + if(input.ball.hasBeenTouched) { + float lastTouchTime = myCar.elapsedSeconds - input.ball.latestTouch.gameSeconds; + Color touchColor = input.ball.latestTouch.team == 0 ? Color.BLUE : Color.ORANGE; + renderer.drawString3d((int)lastTouchTime + "s", touchColor, input.ball.position, 2, 2); + } + try { // Draw 3 seconds of ball prediction BallPrediction ballPrediction = RLBotDll.getBallPrediction(); diff --git a/src/main/java/rlbotexample/input/DataPacket.java b/src/main/java/rlbotexample/input/DataPacket.java index 7001897..a61b69c 100644 --- a/src/main/java/rlbotexample/input/DataPacket.java +++ b/src/main/java/rlbotexample/input/DataPacket.java @@ -1,6 +1,8 @@ package rlbotexample.input; import rlbot.flat.GameTickPacket; +import rlbotexample.input.ball.BallData; +import rlbotexample.input.car.CarData; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/rlbotexample/input/BallData.java b/src/main/java/rlbotexample/input/ball/BallData.java similarity index 70% rename from src/main/java/rlbotexample/input/BallData.java rename to src/main/java/rlbotexample/input/ball/BallData.java index c7f042f..8dffab4 100644 --- a/src/main/java/rlbotexample/input/BallData.java +++ b/src/main/java/rlbotexample/input/ball/BallData.java @@ -1,4 +1,4 @@ -package rlbotexample.input; +package rlbotexample.input.ball; import rlbot.flat.BallInfo; @@ -14,10 +14,14 @@ public class BallData { public final Vector3 position; public final Vector3 velocity; public final Vector3 spin; + public final BallTouch latestTouch; + public final boolean hasBeenTouched; public BallData(final BallInfo ball) { this.position = new Vector3(ball.physics().location()); this.velocity = new Vector3(ball.physics().velocity()); this.spin = new Vector3(ball.physics().angularVelocity()); + this.hasBeenTouched = ball.latestTouch() != null; + this.latestTouch = this.hasBeenTouched ? new BallTouch(ball.latestTouch()) : null; } } diff --git a/src/main/java/rlbotexample/input/ball/BallTouch.java b/src/main/java/rlbotexample/input/ball/BallTouch.java new file mode 100644 index 0000000..d0af1bb --- /dev/null +++ b/src/main/java/rlbotexample/input/ball/BallTouch.java @@ -0,0 +1,29 @@ +package rlbotexample.input.ball; + + +import rlbot.flat.Touch; +import rlbotexample.vector.Vector3; + +/** + * Basic information about the ball's latest touch. + * + * This class is here for your convenience, it is NOT part of the framework. You can change it as much + * as you want, or delete it. + */ +public class BallTouch { + public final Vector3 position; + public final Vector3 normal; + public final String playerName; + public final float gameSeconds; + public final int playerIndex; + public final int team; + + public BallTouch(final Touch touch) { + this.position = new Vector3(touch.location()); + this.normal = new Vector3(touch.normal()); + this.playerName = touch.playerName(); + this.gameSeconds = touch.gameSeconds(); + this.playerIndex = touch.playerIndex(); + this.team = touch.team(); + } +} diff --git a/src/main/java/rlbotexample/input/CarData.java b/src/main/java/rlbotexample/input/car/CarData.java similarity index 98% rename from src/main/java/rlbotexample/input/CarData.java rename to src/main/java/rlbotexample/input/car/CarData.java index 87fbfa9..1023e73 100644 --- a/src/main/java/rlbotexample/input/CarData.java +++ b/src/main/java/rlbotexample/input/car/CarData.java @@ -1,4 +1,4 @@ -package rlbotexample.input; +package rlbotexample.input.car; import rlbotexample.vector.Vector3; diff --git a/src/main/java/rlbotexample/input/CarOrientation.java b/src/main/java/rlbotexample/input/car/CarOrientation.java similarity index 98% rename from src/main/java/rlbotexample/input/CarOrientation.java rename to src/main/java/rlbotexample/input/car/CarOrientation.java index 84a0fa3..68370ec 100644 --- a/src/main/java/rlbotexample/input/CarOrientation.java +++ b/src/main/java/rlbotexample/input/car/CarOrientation.java @@ -1,4 +1,4 @@ -package rlbotexample.input; +package rlbotexample.input.car; import rlbot.flat.PlayerInfo; From 23c698fb1a2ab4c7b0c43299dc939378bc6c30e7 Mon Sep 17 00:00:00 2001 From: Antoine Tran <31257370+Tran-Antoine@users.noreply.github.com> Date: Tue, 19 Nov 2019 21:27:35 +0100 Subject: [PATCH 18/24] Minor improvements (#17) Minor changes, such as: - Usage of primitives instead of wrappers - Generified type declarations + added missing @Override annotations - Added method displayWindow --- src/main/java/rlbotexample/JavaExample.java | 8 ++++++-- src/main/java/rlbotexample/SampleBot.java | 1 + src/main/java/rlbotexample/SamplePythonInterface.java | 1 + src/main/java/rlbotexample/boost/BoostManager.java | 11 ++++++----- src/main/java/rlbotexample/output/ControlsOutput.java | 2 +- src/main/java/rlbotexample/vector/Vector2.java | 5 +++++ src/main/java/rlbotexample/vector/Vector3.java | 5 +++++ 7 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/main/java/rlbotexample/JavaExample.java b/src/main/java/rlbotexample/JavaExample.java index c188933..d3d7230 100644 --- a/src/main/java/rlbotexample/JavaExample.java +++ b/src/main/java/rlbotexample/JavaExample.java @@ -18,12 +18,12 @@ */ public class JavaExample { - private static final Integer DEFAULT_PORT = 17357; + private static final int DEFAULT_PORT = 17357; public static void main(String[] args) { BotManager botManager = new BotManager(); - Integer port = PortReader.readPortFromArgs(args).orElseGet(() -> { + int port = PortReader.readPortFromArgs(args).orElseGet(() -> { System.out.println("Could not read port from args, using default!"); return DEFAULT_PORT; }); @@ -31,6 +31,10 @@ public static void main(String[] args) { SamplePythonInterface pythonInterface = new SamplePythonInterface(port, botManager); new Thread(pythonInterface::start).start(); + displayWindow(botManager, port); + } + + private static void displayWindow(BotManager botManager, int port) { JFrame frame = new JFrame("Java Bot"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); diff --git a/src/main/java/rlbotexample/SampleBot.java b/src/main/java/rlbotexample/SampleBot.java index 80c5e3d..0a82f17 100644 --- a/src/main/java/rlbotexample/SampleBot.java +++ b/src/main/java/rlbotexample/SampleBot.java @@ -121,6 +121,7 @@ public ControllerState processInput(GameTickPacket packet) { return controlsOutput; } + @Override public void retire() { System.out.println("Retiring sample bot " + playerIndex); } diff --git a/src/main/java/rlbotexample/SamplePythonInterface.java b/src/main/java/rlbotexample/SamplePythonInterface.java index 829aa93..aa679bc 100644 --- a/src/main/java/rlbotexample/SamplePythonInterface.java +++ b/src/main/java/rlbotexample/SamplePythonInterface.java @@ -10,6 +10,7 @@ public SamplePythonInterface(int port, BotManager botManager) { super(port, botManager); } + @Override protected Bot initBot(int index, String botType, int team) { return new SampleBot(index); } diff --git a/src/main/java/rlbotexample/boost/BoostManager.java b/src/main/java/rlbotexample/boost/BoostManager.java index a9fa1bf..b93d7a6 100644 --- a/src/main/java/rlbotexample/boost/BoostManager.java +++ b/src/main/java/rlbotexample/boost/BoostManager.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.List; /** * Information about where boost pads are located on the field and what status they have. @@ -17,15 +18,15 @@ */ public class BoostManager { - private static final ArrayList orderedBoosts = new ArrayList<>(); - private static final ArrayList fullBoosts = new ArrayList<>(); - private static final ArrayList smallBoosts = new ArrayList<>(); + private static final List orderedBoosts = new ArrayList<>(); + private static final List fullBoosts = new ArrayList<>(); + private static final List smallBoosts = new ArrayList<>(); - public static ArrayList getFullBoosts() { + public static List getFullBoosts() { return fullBoosts; } - public static ArrayList getSmallBoosts() { + public static List getSmallBoosts() { return smallBoosts; } diff --git a/src/main/java/rlbotexample/output/ControlsOutput.java b/src/main/java/rlbotexample/output/ControlsOutput.java index ace5d65..9cdbd2b 100644 --- a/src/main/java/rlbotexample/output/ControlsOutput.java +++ b/src/main/java/rlbotexample/output/ControlsOutput.java @@ -146,4 +146,4 @@ public boolean holdHandbrake() { public boolean holdUseItem() { return useItemDepressed; } -} +} \ No newline at end of file diff --git a/src/main/java/rlbotexample/vector/Vector2.java b/src/main/java/rlbotexample/vector/Vector2.java index 2197505..dad1633 100644 --- a/src/main/java/rlbotexample/vector/Vector2.java +++ b/src/main/java/rlbotexample/vector/Vector2.java @@ -98,4 +98,9 @@ public double correctionAngle(Vector2 ideal) { public static double angle(Vector2 a, Vector2 b) { return Math.abs(a.correctionAngle(b)); } + + @Override + public String toString() { + return String.format("(%s, %s)", x, y); + } } diff --git a/src/main/java/rlbotexample/vector/Vector3.java b/src/main/java/rlbotexample/vector/Vector3.java index b359c52..506ab21 100644 --- a/src/main/java/rlbotexample/vector/Vector3.java +++ b/src/main/java/rlbotexample/vector/Vector3.java @@ -99,4 +99,9 @@ public Vector3 crossProduct(Vector3 v) { double tz = x * v.y - y * v.x; return new Vector3(tx, ty, tz); } + + @Override + public String toString() { + return String.format("(%s, %s, %s)", x, y, z); + } } From f12ed427db7f84122561f9041a10dfd788622333 Mon Sep 17 00:00:00 2001 From: Tyler Arehart Date: Sat, 30 Nov 2019 02:24:11 -0800 Subject: [PATCH 19/24] Updating run.py to avoid https://github.com/RLBot/RLBot/issues/462. --- run.py | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/run.py b/run.py index 89b5a0e..60af312 100644 --- a/run.py +++ b/run.py @@ -1,36 +1,46 @@ +import sys + # https://stackoverflow.com/a/51704613 try: from pip import main as pipmain except ImportError: from pip._internal import main as pipmain +# More pip changes breaking us. +main_fn = pipmain +if hasattr(pipmain, 'main'): + main_fn = pipmain.main + +DEFAULT_LOGGER = 'rlbot' -# https://stackoverflow.com/a/24773951 -def install_and_import(package): - import importlib +if __name__ == '__main__': try: - importlib.import_module(package) - except ImportError: - pipmain(['install', package]) - finally: - globals()[package] = importlib.import_module(package) + from rlbot.utils import public_utils, logging_utils + logger = logging_utils.get_logger(DEFAULT_LOGGER) + if not public_utils.have_internet(): + logger.log(logging_utils.logging_level, + 'Skipping upgrade check for now since it looks like you have no internet') + elif public_utils.is_safe_to_upgrade(): + main_fn(['install', '-r', 'requirements.txt', '--upgrade', '--upgrade-strategy=eager']) -if __name__ == '__main__': - install_and_import('rlbot') - from rlbot.utils import public_utils + # https://stackoverflow.com/a/44401013 + rlbots = [module for module in sys.modules if module.startswith('rlbot')] + for rlbot_module in rlbots: + sys.modules.pop(rlbot_module) - if public_utils.is_safe_to_upgrade(): - pipmain(['install', '-r', 'requirements.txt', '--upgrade', '--upgrade-strategy=eager']) + except ImportError: + main_fn(['install', '-r', 'requirements.txt', '--upgrade', '--upgrade-strategy=eager']) try: - import sys if len(sys.argv) > 1 and sys.argv[1] == 'gui': from rlbot.gui.qt_root import RLBotQTGui + RLBotQTGui.main() else: from rlbot import runner + runner.main() except Exception as e: print("Encountered exception: ", e) From c5a016a2e829eca6da9727c566d46e7ab7f2009c Mon Sep 17 00:00:00 2001 From: Viliam Vadocz Date: Mon, 20 Jan 2020 11:47:13 +0100 Subject: [PATCH 20/24] Updated outdated comment --- rlbot.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rlbot.cfg b/rlbot.cfg index 80411c4..930f607 100644 --- a/rlbot.cfg +++ b/rlbot.cfg @@ -5,7 +5,7 @@ # Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. [Match Configuration] -# Number of bots/players which will be spawned. We support up to max 10. +# Number of bots/players which will be spawned. We support up to max 64. num_participants = 2 game_mode = Soccer game_map = Mannfield From 3a47339772324f34bb01fb90992b57bfa8763c37 Mon Sep 17 00:00:00 2001 From: Tyler Arehart Date: Mon, 23 Mar 2020 20:02:47 -0700 Subject: [PATCH 21/24] Upgrading to RLBot Java framework 2.0 and cleaning some obsolete gradle tasks. --- build.gradle | 40 ++-------------------------------------- run-bot.bat | 6 ------ 2 files changed, 2 insertions(+), 44 deletions(-) diff --git a/build.gradle b/build.gradle index 0124827..8f55dc7 100644 --- a/build.gradle +++ b/build.gradle @@ -19,54 +19,18 @@ applicationDefaultJvmArgs = ["-Djna.library.path=" + dllDirectory] dependencies { // Fetch the framework jar file - compile 'org.rlbot.commons:framework:1.+' + compile 'org.rlbot.commons:framework:2.+' // This is makes it easy to find the dll when running in intellij, where JVM args don't get passed from gradle. runtime files(dllDirectory) } -task checkPipUpgradeSafety { - doLast { - new ByteArrayOutputStream().withStream { os -> - def exitValue = exec { - commandLine "python", "-c", "from rlbot.utils import public_utils; print(public_utils.is_safe_to_upgrade());" - standardOutput = os - ignoreExitValue = true - }.exitValue - - // If the exit value is nonzero, the command probably failed because rlbot is not installed at all. - ext.isSafe = exitValue != 0 || os.toString().trim() == "True" - } - } -} - - -// Uses pip (the python package manager) to install all the python packages needed for this bot, as defined -// in requirements.txt. -task pipInstallRequirements { - dependsOn 'checkPipUpgradeSafety' - - doLast { - if (checkPipUpgradeSafety.isSafe) { - exec { - commandLine "python", "-m", "pip", "install", "-r", "requirements.txt", "--upgrade" - } - } else { - println 'Skipping upgrade attempt because files are in use.' - } - } -} task createDllDirectory { mkdir dllDirectory } -// Installs or updates RLBot. Empty task for now. It still does stuff because it "dependsOn" tasks that do things. -task updateRLBot { - dependsOn 'pipInstallRequirements' - dependsOn 'createDllDirectory' -} -updateRLBot.dependsOn pipInstallRequirements +run.dependsOn createDllDirectory applicationDistribution.exclude(dllDirectory) diff --git a/run-bot.bat b/run-bot.bat index 4508712..fd7a00b 100644 --- a/run-bot.bat +++ b/run-bot.bat @@ -1,12 +1,6 @@ @rem Change the working directory to the location of this file so that relative paths will work cd /D "%~dp0" -@rem Make sure the environment variables are up-to-date. This is useful if the user installed python a moment ago. -call ./RefreshEnv.cmd - -@rem Install or update rlbot and related python packages. -call ./gradlew.bat --no-daemon updateRLBot - @rem Start running the bot. call ./gradlew.bat --no-daemon run From 9b4c363dff8bc0b130f82b914c76adbed7c56a3b Mon Sep 17 00:00:00 2001 From: Tyler Date: Sun, 17 May 2020 18:33:26 -0700 Subject: [PATCH 22/24] Setting enable_rendering and enable_state_setting to true --- rlbot.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rlbot.cfg b/rlbot.cfg index 930f607..7944055 100644 --- a/rlbot.cfg +++ b/rlbot.cfg @@ -5,10 +5,13 @@ # Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. [Match Configuration] +# Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. # Number of bots/players which will be spawned. We support up to max 64. num_participants = 2 game_mode = Soccer game_map = Mannfield +enable_rendering = True +enable_state_setting = True [Mutator Configuration] # Visit https://github.com/RLBot/RLBot/wiki/Config-File-Documentation to see what you can put here. From cb4db9648293b028861dc10596bc376786d08010 Mon Sep 17 00:00:00 2001 From: Tyler Arehart Date: Sun, 12 Jul 2020 15:09:57 -0700 Subject: [PATCH 23/24] Removing references to legacy GUI. --- README.md | 12 +++++------- run-gui.bat | 11 ----------- run.py | 27 ++++++--------------------- 3 files changed, 11 insertions(+), 39 deletions(-) delete mode 100644 run-gui.bat diff --git a/README.md b/README.md index e7c2910..d354da3 100644 --- a/README.md +++ b/README.md @@ -3,23 +3,21 @@ An example bot implemented in Java ## Video Guide -https://youtu.be/mPfYqKe_KRs +https://youtu.be/mPfYqKe_KRs (slightly outdated because it uses the old GUI) ## Usage Instructions: -1. Make sure you've installed Python 3.6.5 or newer. Here's [Python 3.7 64 bit](https://www.python.org/ftp/python/3.7.0/python-3.7.0-amd64.exe). Some older versions like 3.6.0 will not work. During installation: - - Select "Add Python to PATH" - - Make sure pip is included in the installation 1. Make sure you've installed the Java 8 JDK or newer. Here's the [Java 8 JDK](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html). 1. Make sure you've [set the JAVA_HOME environment variable](https://javatutorial.net/set-java-home-windows-10). 1. Download this repository 1. Double click on run-bot.bat and leave it running. It's supposed to stay open and it's OK if it says something like "75%". -1. Double click on run-gui.bat -1. Click the 'Run' button + - Alternatively you can launch the bot from inside an IDE +1. Get RLBotGUI (see https://youtu.be/lPkID_IH88U for instructions). +1. Use Add -> Load folder in RLBotGUI on the current directory. This bot should appear in the list. +1. In RLBotGUI, put the bot on a team and start the match. - Bot behavior is controlled by `src/main/java/rlbotexample/SampleBot.java` -- Bot appearance is controlled by `src/main/python/javaExampleAppearance.cfg` See the [wiki](https://github.com/RLBot/RLBotJavaExample/wiki) for tips to improve your programming experience. diff --git a/run-gui.bat b/run-gui.bat deleted file mode 100644 index a1c00d9..0000000 --- a/run-gui.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo off - -@rem Change the working directory to the location of this file so that relative paths will work -cd /D "%~dp0" - -@rem Make sure the environment variables are up-to-date. This is useful if the user installed python a moment ago. -call ./RefreshEnv.cmd - -python run.py gui - -pause diff --git a/run.py b/run.py index 60af312..23ea98a 100644 --- a/run.py +++ b/run.py @@ -1,16 +1,6 @@ +import subprocess import sys -# https://stackoverflow.com/a/51704613 -try: - from pip import main as pipmain -except ImportError: - from pip._internal import main as pipmain - -# More pip changes breaking us. -main_fn = pipmain -if hasattr(pipmain, 'main'): - main_fn = pipmain.main - DEFAULT_LOGGER = 'rlbot' if __name__ == '__main__': @@ -23,7 +13,8 @@ logger.log(logging_utils.logging_level, 'Skipping upgrade check for now since it looks like you have no internet') elif public_utils.is_safe_to_upgrade(): - main_fn(['install', '-r', 'requirements.txt', '--upgrade', '--upgrade-strategy=eager']) + subprocess.call([sys.executable, "-m", "pip", "install", '-r', 'requirements.txt']) + subprocess.call([sys.executable, "-m", "pip", "install", 'rlbot', '--upgrade']) # https://stackoverflow.com/a/44401013 rlbots = [module for module in sys.modules if module.startswith('rlbot')] @@ -31,17 +22,11 @@ sys.modules.pop(rlbot_module) except ImportError: - main_fn(['install', '-r', 'requirements.txt', '--upgrade', '--upgrade-strategy=eager']) + subprocess.call([sys.executable, "-m", "pip", "install", '-r', 'requirements.txt', '--upgrade', '--upgrade-strategy=eager']) try: - if len(sys.argv) > 1 and sys.argv[1] == 'gui': - from rlbot.gui.qt_root import RLBotQTGui - - RLBotQTGui.main() - else: - from rlbot import runner - - runner.main() + from rlbot import runner + runner.main() except Exception as e: print("Encountered exception: ", e) print("Press enter to close.") From ffed34b232f5349fb81dd05c66fd63839ce8f5cd Mon Sep 17 00:00:00 2001 From: Tyler Arehart Date: Sun, 17 Oct 2021 17:45:14 -0700 Subject: [PATCH 24/24] Switching from jcenter to mavenCentral. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8f55dc7..e4bda5e 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ apply plugin: 'application' sourceCompatibility = 1.8 repositories { - jcenter() + mavenCentral() } mainClassName = 'rlbotexample.JavaExample'