From 11620cd1de1a2c2b2ec643a92f19beed06ffdb4e Mon Sep 17 00:00:00 2001 From: fedorovv Date: Wed, 7 Feb 2024 11:45:48 +0700 Subject: [PATCH] Update performance section --- main.tex | 1 + src/figures/test_redpic_performance_1.png | Bin 0 -> 38966 bytes src/figures/test_redpic_performance_2.png | Bin 0 -> 37094 bytes src/texts/abbreviations.tex | 1 + src/texts/redpic_performance.tex | 35 +++++++++++ src/texts/redpic_test_performance.tex | 67 ++++++++++++++++++++++ 6 files changed, 104 insertions(+) create mode 100644 src/figures/test_redpic_performance_1.png create mode 100644 src/figures/test_redpic_performance_2.png create mode 100644 src/texts/redpic_test_performance.tex diff --git a/main.tex b/main.tex index a6be17d..eaea403 100644 --- a/main.tex +++ b/main.tex @@ -76,5 +76,6 @@ \input{src/texts/kenv_listing} \input{src/texts/kenv_gui} \input{src/texts/redpic_dockerfile} +\input{src/texts/redpic_test_performance} \end{document} \ No newline at end of file diff --git a/src/figures/test_redpic_performance_1.png b/src/figures/test_redpic_performance_1.png new file mode 100644 index 0000000000000000000000000000000000000000..c94be8f296e796e14bed969ce82dbbc80001394d GIT binary patch literal 38966 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%0AhFaI0pccl|0je8<^1)*cl*0x=jgW zbOJ77v#Hmqp?IiFmY7E-vAvYxWx({TQ40f-0%SU7)EiG>h5ntl02aXQEO8O%M((AkQ5#9LhL z_KU*u%~VlVQ_9Ry7ko+-K*Y6J_SfJ4bw52kgriq&&^b*gP7k2=7@>d zPcfha5zfkDmRaRcuzqs3@(#uRS!5gx(P9X$kp^r(Of+&iK#}HXrmz}7(?U>A1xB`; z9!7SQ97eybKmoEKyWyaWjP#z>eX`V&rRmX3XWvE7LcptA`VL}vi{U-*&;;<3%xt2H z@s61Q#PDeCM)!d_;cDOUW~4F>?_uU1wun*@cq9cOm?;>xDmmb-2m<5asNO|XFhNp0 z!Z8)fAi9FKc9jvlRn=jHPeY>*S&N&Ydz!OeZ+{u5A$sN+7&~Ib!Q;qV8B%f5Z_$Q~ zMoc!~nizJS(=ONt<+MSN&F>h@p?O2xp);PYfd2Vp@b zn0mQt+*Ps;XI;g9iufu-%b_H!gtnTU6}+^a-SU1kQrP(b7^GKqVlM$gnyOfQ32ile z?rZ2B0tiE9RuFiVtmp*ZN*mDx#lChs7?o&Zco4dlk8Pz?u>99zdO7^Lu~`F;u*q{` z_71~!qOe0=?B73xAvVtI5d1q?DQ|N7Hk-PZA2?K3R?wZ@`Q zFS^~#E3*V@yzhY;-nS+R8A`zRO~$wkC<6e1O%8$gkbXbF1STR)W54}K0q8nn3I0~% zn~JEZycrssz7+l7(_3bQs79tx1QH4T-;vHE^br7|*kmM2--1wbpiMWB!w;#0bD-tE z>I~{}tdKc?B!isxnXP}5=)Y^Zxh9tIPNiLZXgWGF7k~bH(nKvMAGB3jC@=aKt>Q}$ zVt@PepG=yVFq2aOuDtCp{cOYP_H7$eNZUXiu$!kB@POxGAexRwUWJ^C06oFYi=CEh zH*?u18z=bkhnfz^smNu8V)I6$8eGoCy^hg(a4DJ)HS@ujvG13E1zmVIgHk>PS|Qg3 zL#S=?;h!1`!AVJqQ6L>ZbNLn|asX+Nh|r!8znjqv>1$>6jDx-l_TjMqFZ&1ntf{hr z45xd|GT`(f<8Yw+heh$?U&3wc-XLXgGZf)55SYtp8z=(Qbad`@b&wSRD9iHeS*U+I zFDn)#b61sT>*sYswq1R_wx1fH;lNuG0^dJBt7X8E+o$$ly@(n?LeDbWKYg@cF;yjz z3WO(t2$5{#|Kdd};A^1b&GYmdl+FITbC%+q^UKd&C^Q%1hnQ^tiwZe8IiijeAV7|^ z1p&H%bSxnYgi=|6R-LaB6pr*t5;$UAuYnw7 zM8rvlT@2kzs1pE>u^qZQ0Gx}fp6{lC^M(p!ECs>U#O(OMrT_uiMo1DYdO`yi&|b6L zSQzeka|9zW`2Xb*4mrbOCAe}sd-KZ!iRGG$NL{~Aw-133SJOL`cxg(##Lk0_FXt?XPC zR~525c;TS>v*~;Ki6_0V%E?)=uOUT^POuV3aK&k`-L7GolXsiK_#11IU!(0wA4mg?$r5z}l^qg%Ro%(~LoC zk};gl0`yQH?<0mIrY{*3HrheP4X>c5mS?8;eg3im9-T)7UKTn&=4wC_2l)wm;>*e0 zxn`h2c6z|Ds86pSoeY>r6jsq1f}wP&(=E@LIf|H%z#&_?vCY>$TFssm4-caNAvVs@ z4?IJpiPcqF`I;5!{772vM}o3C@@+7YC~%$328DS1Ot>#*!%VC|=6~hSh;2jdZ~WlY z9{}rrlMpftFV1jSv`k$^?m2j|=%G1iTcr~wCJQ|uXcigE9(g$Fq>m=}uEj;Tsu}tfPXeu#bFx&QJ9^-41 zk@In_Kib6DhJ=LPOJQ z)oad>byfW$9Gm)Wffi`?MR+5T=ddM5zlW`MrWO7#j$zep@F_+~zzIkNTqi=Fv!;4% zt|6fbJkL@YyhQpvHr1 z(=PMMxpwk7BCt1%h1|Lr7oCb{Z~`vF4izYFvp{-{(2F+ZTNKBwPz$QG_sBa3X~Q%4 zdr-qYR4=>ky}MR%ycLp*p$VQs+vbiVtx#R#N511_0ay$^>!1hNJ~GY#4xl;+_y7X? zqsINakwE}`M7kTe8uSAwhpvJL|35rKj470jhJw$=v*7*mXeksDA$mJhH0%HI%ZH@l zed+vQ_&@QqwR_$7f~41c{5JnoD;!qMUMHrp7xU3 zRWcp<(NNbf3mrgI$1P%Lt6?=911SNfHdH@}F&J$1sq{K0m!^^ZwqkB2zhRuq78$ZD zTj-_IP7GIGlC53)QtLgY-(26{`HP#|ADus9<0#_qLG>59gbm`;H9ZQ0yiBUnviz zg2EIFq6*@GJObh=@}Y3(tlanE>&RBSeu4rlEDCn3^iT-2Jvwu@;b$etC75qF_JU!2 zZ>0ba5WK3ZK#VaQ>|`{^T9zB1FHr)(*IL|QoZ<_Vw*;s~mEH}#7Y*&Z@K3tKEN&Q^ zX_F>7WMvh51$Y#U@bUb~wS?2J+F9{XN;JJo0XS=hz5W0Z+fUn5ig_xQ4mODB1S}^6 zBN>tgENDKY9=vZnH}9#w4@~u&q2Oz`SGYey^i}0lnSfT9;sh9bJ39!dK~L_8KUo_n zttO%j?tmsh65ztANqHr%7OoaNX`L9xpROI$VpL@30Gu6OQf~M0b1I7qV)DEJ9#YjJ zyc%&R#N>&@5u6|ba_cxRV)2KfX2f;$^^i^x9ifpQgk2?297ZcSP%&u+oXZd8oO~3q7R4 z%+@v7{7E)mAovRUg*TejJY~R0oT77t zj2#F+$_}doja&)}7jk+8$XM+A2GS|I zK5cbU4Iwn{m~~hi0?IJbh~m0XZ^zSDc?Yx(LsNjj zsC2z-pWSp{N(}0QJVg{5eB3tVkbg3R{-wH)=6Tqdq-#8PfM1a?&Ek^T@JYqYE(NF- z=iw-=k%Qq62DRENr)PlW4daBq9o!tXsWlM!NrMFvQf9K)|E<1&SS1 zJOLUp2tXBi{#p+M^edYjpv9mtr2=z;u(Ho+}(2+hsCN_0)khA zbDJ7q%vM43PPK4+@kjhPr&KbUUbP8knK}3+B;^<_4^Q{sI}bvx%W`TLl1&I%g9Zrl z9Vo3FiZr79fAUblS_axhW83$(b}%QH4X@e$N4jcG1H=o>eMVIjqnt;~t|dKGR({d` z{YjNoX^M5ZZed-9wZZGx5AF|?Y7K`q&o$odwT^4>&@U~{G+%use65!I`q-3r{m;*` zynaUrpO7`}#7eQtJdY&2SkHfP!L3rCrAcIPS*+4wL$oPka5HAonf*jdy9q<%g?Z>N+Jld?|<6@**WJkcY~;7vV~aVB6@wUdRJn;?o* z_?|=SgXoU9{0v4~0m_%Gl24>qcL)f#k2=a0zVP);IZl4y*vZqg{^1`bf7#gb>&{c0 z!+deBiCmE6ev_ivt&w~5xcd&~;IodU{kDC^2kzoE7TP!^+*oL74#hpUZ}b!t%8X10 zTYmnoc#@b`EG{9(PU!COU0B!5ALtfKr7qwv0_g9z$+tFe$y4YKCvDBjdLE@6c=dw+TLL1Xj^S8P`pj1doSzU zWQN(~#BfuAd}6Vgy^KTNVKL|Es`k{@JE>GLwwUqt;Z(S%W?EX-HDz@QKTiMb@fC*j z#)X73{>4KI3<5o?F)U}#F5UUjbgy{8xK{rR56_$=VOL7W9G6b})PSnO$|3GI_3^X; zM6YzuU45v2!7t5^+o0J%WZv;EwG%b(1T%C_8u|6(UTQkwkGS<4=Bc|O5pxWBld*2x z{j#Yuv8|yWtmSLRRBSxFAk>jh1W+zVPZfg9gb>(qQp`k~=0Rh+OFPb%+K z|8Hx}%Jz|TIfTX`r(#LG!lefI+$-DG+*FCrp0$6#;Lml0W?DFi6EkTedSY!nXGN{` zL+cxu>;4ZPni%Ep>haK@pquH5t3H@*cvjeqUdTesSWQ=*Tf~BD=mhRr_CeO?Y&sPK zbl8iZIC(J3bV(A)>qF6d(fw`;0`>e_!l%MMuotfs`PMsxhr8|b%?x}AapV5TsUdF7 z;ICu-OoPkk<;#pZ|JNUz?lIeIsJ&XRtjIO|aLj3~SSBVlBTMk*sr>T+bhJY9B#QiA zM{iw8;LWWO>p4GqBqJ`D0j(O7U~Otefj5PBh406x?y`Rvh|eH9C0Vw7>ze$n^8JXC zc)G~C-wjV{&-}@8l&${RvnHT@(Rr@#F^I2ROH?V|RwEBNNTa}-8s9ARR?@gc-AYp? z@K?|&wr6Zwfu}_*w|pnNw}v!IclF@@ie4{L=2Je-6=@x4noduD^wH3MbXiMRJKMEU zoJR8`&s=QX&%T)oj}svyTKsPOrZO%cU072jQk#WDlcju!B|R~X96Ua^;~mV}C%(Qr zV~yWNeY0_1f*xNS`-FEYY$T4GI1fMJJ8~o;OL%-tq5aIOZ~{*CW-9I&YCDP4JQzA| zoy#x1eajwql`E8Q{)y5mb>`vZ;tF~5#uqY=#ycB}b8{NW4Gp*%tD%jVm~OWX=E78cv=y=)10$kegEOj07Apc8AZEnCLePujpxN5Q%S^aK4R7ByFy67E!fje&)ve zqSdTII*o(j5?& z`JY-P_Gj7UnQwfc+s9X6er1F74+i(m){ViNpUxG{#j6x!noop8C*O4ct z7bsZBWC+;@e)lHnZRZ&IC;hfJyhJ8L%%{W0c(g2P(7ZIuy2tzeamC5cw3GS;<6WL! z%S*Tm_xd_+b&-GG;g8f^KgVnHb*3jXEF`gc-fQ98|$A& znmlndqhn*npP!j*Y@BZQ}$BZgi4+$L#t2V@Gq}M`Yp@+c#y89Y5j?M@P32n^eHH-EQ#2ji1iI)jr zG~FZh!0y=0=>K#JS!^hv#^BW34Dxj}HX5M>ExyRefB3|m9e#|Vn&V^jnWI~$GX zmcxp?FrFuw!U#@#6YW_@nT30{>}_=@%@Ru`(&*&V=!DbUAJcqjXL=CBbRmtLE2-SZ ze7$3~@s8R98yA(YZUMf>^2^MLheGGY{7cI z?w)72dn0sh#xE^MwB9!Dtslc(J62Eq=kTz-$UC(+5slPco##h!zq`i#4DMxlSQqx? z24`EfPeG;av!vDo4)X^B}vif1Xq|`9OF&idBYf!52D3= zkDUW#SSt4S9`!l4Dc(8Pl(*R&LwL!GKdbV>4zalNc7C(<_WZ8H!aa3vjNzWU;T`Ex z53Sj}cqdRSZ@t|+PG2yokm0{J$TPe0bGh5wS>f}uC5Lfx3JQYavAGirua3vmVwak0 z`ipz-2E~70zedvD)lm)Ik-E72qPr{k367c)sD^D8D-awEA`r0eztqsqMVhpOu!JRmxnZuHL|omycbq4%k&-y7RC_6ejB=q@rtz{)+%cN*G zoE**jj=Bv99FT*9UwV|1C#(WT;?nFRJiUrNNK7oI#_!fa$8Ku!;K6U`nNpx#0o+it z{EwA~uihP`+BwKXJGuDCinrFGb1{!axs9A8Jn67Ny`h;3%aup84?{StjbFx;(+X)G zc)xbxN+Q3e*?}(3{57GwmSa`|-&$JUU3)jk#wtx;XkJ*veJmo24A+@Od&JwU>qq`p zY5a#4=a}F=nY5VB)~By&L@X?YLU(z#*cjltD?_;SJE=`^8t3wMSbn)5PoM9Vin!Vx zn8#2Xy!&g=xsJuMEhFQ*NSO9Moz=*VQtQO+0q1SYaRsdysoprZ@$g6Y;whze$bFgi z{ZC!|RQ14PAhNYci!tDgZ5dgnt%Hx0>*TJ;`pIWO+p`q~3BTz@nqxa&FK;_YrmxusmuGLxRlZo+V&g3@b`E-(!JZ6KYvJPJ^eN69l5-RZDom=2@ z{aH8aS8@5obl-k|L9Y|lBl=zE1@Se7N_y)yq2ex{-2#y~iG_=fmkZLzOSgLk>qNJn zH!AMZ9Ed0L@~%8rSc0uSC^A){?MoP81?-rm z`=fesMspRv(_rV~Yg2G4MxXqw1 zY{Hf{HZmF-G;?Lkx6>_Ws0)ugqwYV_nt&tgve&xu`0xnd2hK$=3hMsl%Is9zum;Vu zO6?u);p%gbm!=&qHIDH!x2&+t-Bu~S|4J^aON?$Btej4!jEV|nZeAXb!y5(m6Yzg7 zc%7$-YyL;`o+WH~)3RNLDn^ z=}&ODeBCc~&KS!s^|H*$0hz?lS(}Z^w+7;OEqD26ZQgxb6Vf7L*@;>j%IYUh=@Z_3 zvvtX(Oqh9!GkHm!WavvHW)!2~d|>oWtSjv)@%%d3$mmU}@vqH=&I3StUKn^ZZv<7^ zbLY=jgBicC=LX+j3^~mSVp;wY^G9^)wd?_OMYY)kI`;OZR-nT~-23-=At)zQxcG zY0!P-4?l%+p|Tk+faOZtp~+KmcV2qUuBJUXjQP_XXS+@*u0$gw{nWwSt$yb?Z}6Y^vVzl({}WpE|D%iKU0mKJlR!EKTR!kz zg5YgbRBKBMrdzH!UA;(z^C z-sR7Ke~b0;p%ee}M)*%CBTn&mM;yOAy8OCe#gD)@K`+6n5m5H652oyx# zryqZbjVv6%l7b?_>*LGN7_|CFj2O>!WcuhgAfpgQDm;hwr#i1Mn9h>7#}`=joNc$r zcLiUv7Q_v|KwCFnV7p7JtB04C%9M8lsQ(KvP-=mVauAaPa!%>1Am>Q|T>F!8o?EHs zI5{cT2Oedef;JLnR#u72!KHWS9dDv2Qg2?7~|k zo!XyQ9l`vr4`F%z1^^OAA{E$SQaGNG z|IYH-O(!8Eqf%5&MZcYBIta1_sV=Td(ai z4&mY&dU`Rwfq~T8+SZRUFGzT3!EaWZ*07-qx1HDq%Nr-@cgLqlimK6IZCiH^4V)(CVaW+o;K^kT^W0_*=OZv>05a2Mrr)Zh-0MgA|! zu#k|)FsQl}?!`Vq&$00kmtm@K1W=iBb8|DZu_wm0B^lgkTe782656ltbtwnvXUX2X$Kvkc zq4)4+J1ML)GC(>NVOKdpT@`JM06Gy$Z*Ol{H<#}gSY7q>lnkO1G0qFh%38}o=gLbV z+W~PpDNj1khjVn%^kqHDC`kvukdm2+Vz~>C)~rTHM~h1DN?-aBE8!35EG8~4Qc#DR zn+xh1Vsn##R@$eIcz^zLn?+q+o#gm&7uBqkEX(iZK}!PS;&jj(x=?5E=g%jgxS?I! zZ5cl+=^KqaCilhKlih{3j6}y7th7O@K;cdbK6xYbP8iX*_` zQcxfRah2f6$QK~!nqg2G3!}}!$9EiVUI%vQof_wRHBMNNPeD!QN~+pfZtegPOJdR_ zh6Igt=qU1RX2z;fAnY6ZZ$d&sQI2VQ#8G-tD&VtexTSVYheSnLertU7imJW6or#aH znKI91ULTx0u(fxMp~EHa&z}dk6u^&!Zi_z}7wgYoBWa40VgwnZI%o}S&AX}~FaJb7 zF}I-y7S^lqaP6@fP(sN#vYU~?4X*(+@RPEwAh7dP1w-4aK%|11g@y6Q&^kFq#ag)T zj+U008${PM0H(`zZ;sBd>34~lutfGx@O0n?^d+tR7RFH)QR(~S$$>>^%}v7GR7icCgoGTS>CW-;(tu@->+kh@2|Y|9H1mVT zp?=-nTIs!hUG43@u(lWB{{G0afhsUbrbc70UsxLwjccv+^2z}^7wiKgH$g!`E#p5w zVz@qh`0xc@xwbW4_J+K?-%UBWoDAFYS!*n|?W6Z69s#EI0dyhEgtq zmIij!+V-0S5Y*1v+uMHu^q};^hdEjxH5UBM#2B&!*GT?wx>Xdod^_<(#PT>PyKr~W z!+2jmKT3;yod8BDeRp^V{CT&%HhThN#Q+C6&9yhSJcy)6K|{k1qjXbIkvcIkQNvmn zx)g&|SKZj&CXKnx0m@S>Q&UqJ#?bKo3$Vew!R~>G6D6D!ld0De^uOqTJV4IqzVMhW zDJMr+d~-DHEOcQv%h$O89iq{zcl>|@jeD+Sns<15nhTWBYV(>UxxiV;GzKL-4sdSS z;E*aBetsrn?dqtnETe~-w5%*?z77uv%}85Vq$O%mJ}H)u&GM-J5}nU>;u^_%fc4*# z-R;s3qyIO49X1da%soJW_A}g)mi9P_JWBgWSq8U*0+D3!Ka2d+AUx*^9hX~v{+tO*_y7r_ zn9nd6{t^1v!=TtWt8$m<>HC^huwz$%x>wR(kbao?&Ye3r=(qhF`jzJBfN+rycmzeM zrjYNaKrYj$%IQEN*oD49L0?gj^68VH``+d_$QqP78~y(Bf`o+R%AGspp4+{HzoEZs zu9cYEk_p;+q$hc$Ar6Hk;{x+}ym#e$20C9Jx*@>FG59 z!pwFUzl}CQCp4d8Ie-4!Z~+ul#*ttCfnjWV+LHEsiT&6SlmZ0`DL4aX?2GAu2K)4z zN$wX=$)bf3A9P=?UNq<{&HA+x#{9Y4dWgTk}Ya#YKE}HT|w$nSw-au_&)bQ zh>QH%W%oWf%oY|Gs~Pt`5OqVXv*p@9mSC7`oe6Epx13;Ah9+1>A z0=8xMC-V~znq!Y*PF=D(#eO^5Ot>O7^)N6}MG-F;tSyvVi-w8l#9hhf%a)I!-teD3 zeKLf{gh?mDe5tDwbK2S5+ysRzoKEIfkO<0ln$~D~bAb?KE6vQ!jjCapyw~CfFZ-4U z92pDi>#`0G7vW&^1hJx##0dQZh7}6dK%cGu{{4oNQ~rIE)QpTK6@I5Nm3%Njfg~@#Z4}9_%`t zk6@WI{1TzV_=iuQs6e;riiHIyC?!1xWUE+v63knx*(+VfGiOL4EHE)O6>A>=m+yV6 z*&Pjy=O8PeE<0WSQh~h&^rjY;8u{Yiy~Ds;!3pP*vI`>+pOo}f<<$9b`99Di-53p1 za;<^N)$uwCWLf;Hs;(S7bZ8h_me*E2CRBzyf?Db2PqWb9J2)!JKhA5976OJ-{Dzp( zB}*^D6I4i_-sW*L=fleSQj^u^EVG-H->#6pu_>6 zT&(>V1;wg3-r&%{#soL08g$YEi;6CTOG|g=l2sLmA&T{{p)ZBL^B3$#Zwg+z^c!SZ zPYIa#sy9K~Z}2a2EIK$reC-~naJ~V-Mw2K2$IINjNg{CZ;zK}GA3S)_5SFc0ffX%0 zCh{7f#n)9xfQpKq_S##Hd)TGtqFt~L$L$5vA9STIKN_2xWnp*0@o~QgK=6m-TS=Z) zSKV6j^%Z}kaM?jg4eW02bnQt4>D#xDK{PcF(Ikbk@NW`Wd&R${(GxK_8Bw q58+S9!2!0H_@MazZ60Aqs&9r=+V^^g1Qg3LayM>Ef4pY+W%rpAV+QGv>fp8D2$MwLupd)%<=G^+>yV2Rn0Yaw$H^? z&7`}2$%erf@6aLEQ?-7HU6l&zGSr7^op@(MvIze;eq5&3Pm_~NU5&cR?`?*rOM5%! z5UJs{<1*A^-&!6iZg!wdY&D~n zk7ScqO=l0(d&ma=Tgy!lh5R?_sjmY3MP$R5E9}TOOzyo!{+N8>!Y%X{=;_mtuce0_ zQ$s#iyYbbC_7BC=Pmfd_?29?gbg;9svd-EgUkPAi2+y-<=XxzVAc1Jf%+*zlj3IUgmD`4IZOrP{3!mL`m+9Xdq$oF2(&DmCuyiMWtiah>^V@}0M$R0SDQ-oAZUU0qG$ z6~DXd8Tss)R-v_CKt;5(Zr4gwWTdpJs%lC_HdxQ;{#&kqPoKn3@M>RIR#pzE&=6!` zKXb<4z^@CSWv+Nx^LH$ecdDyu6&Im7nU%MgB;_Ky2aDMX9}2s;#XpWP-^Gqbk!W_lj=wbfUHgN@?F{uy1+Qi>U5;66Vq(2ZpA)UkrzIkr@-5TW zT=%tUjD-@sh^ly6vrXhQ=-YO#fkO zWk{>;^GJQeq zyiT#{v?R?B7Bul*>-2aRO~1dropj@7ykyyAEd52(7FhO1$-?{1ak_T3G_$1(7c80GM(ZLdeYbVQZPqN(^gMR5HL~?3x<6RfuTK3C9er}` zrKH#8XajFiu=M@4>Gt=!#gXu^$4L>A?)lA`m<;vY_C%$%`M#Ko&EixKb!^I_&fl$D zT&ibr*j=i(sSrT?NXVbTG}vd#mxJf~O7mfp=XL6P*nQ(Iy!B3*$+Yn`#!*>YTRZns z&g$xF;zX+Qn+6R7ui9rSlJcd_b0R~JsOUuP+3waqX6NVU598-FW%OEY1*^U>6Knt@ zelvgfrcQEaw#H+jtUiqXqFKj#dXM?y`{@Q7u(;UvVqzyBf*V<0SqXg;6CbYvE`l=nkKpTR zT2%Wk+s=(|NSVZ}rAnJ(>5cYM-CNC`gW+x$TK6?tcWdXLy?&bAW8pEA*mBq1h$UFg zr;(A>`W|z&t+FhQaLj9#$G%N<<(_$ZP}Y@NapRy+w&@UbeWEAtW8I=JugLuw>MsYzqkHfuO^g+?ki zWAXW_2lGYW=}`XiQx`8j1LuAl7DeB4Nv8Xw6=@}Mir^f})J7r`uxJe(csTB%az~j zU|xUaly!4+d#_je;?>3b>XRS*F<%SJe^m2bO&Rp8rI_F<7cp3>DaLw=ii)yd<~PO1 z#9Xp^Ddxh*t&uevK&$^2PQmw==lwrg_1ISt(o(-EL^eTz`JKxy^WQfHe43d(W^a#g zFkW^%=TA(*=N|j!jZ)|d-bpw(xi6%TRM+uW>`K46>;&%GG`;^FTc;S|M7!x;kF{k0 zR!rkasT@D>(8{?Nt0VjEZNboUn{7pwy7I%s7G~r zMzxnX&7@&6PB4i%^QQc}v@yvcSx*D*Ry$eOWW%4$JUE&L=$-hN7FVR)ubGn3tFtL#OW zd0iM$lah+c{Ab#6tDcW0OT)FZ`OT6t6PZ5oYZd!*Ha;UM(fWxF6HV_mbNzy;INC~G z77`sUWm@VC#K^HpD<~-BP86BnFfwE8 za@6V$(?ws4J5S}3yVjIW#=!dHfx!uplb~Z=9Kf#lqNT|0?kUX^N-8S+7AKG0`Szkp z$)nIIKK({G*L-UEM!yF?{Mh8)ov8>qIn!6_a@)}Flx_K9HEGNn+P>=YId1j$U8ZD; zFL*dlSPS=;c-^fDB)i*{W7Olx3!afv{qyy=46unfVr}txbw1u}$6{{AiNBiq@$RBY z19kbqzQgs>yARUXOrlJZ9S9Alc=cLwN8WP zN?(G)B7B-a2pxO^wRtdw#qF8we8Vby*t(3)qDV9;4hg>U;oeuuCW#GQ1lE+fuZh5h ze0jlyM6bkg2;BWpqwv6JzsG_}<7=S;vsOQ533povjb7JfO}tK7C8+rGQaJ^9L9NHv5AOA#f+Pmf2J4U*MFQsuP8!*f_u_3+vKjRVZrZq$Z`6j=7X$ z-Ph5au642Ko#p#LE}eZ8l^RdASp{((i5uu3QSUmY#&yBGjSbL5Mc)c+M%Ss7Xs%Cj z%LR6g2!4W7^!<%k;pg~)^gA4UrL%b?=?ErS`gSGdw1mg{XpBucr@Q!rE&-S;t^QTJ zv;6!K;FO;cP>4S%C=g^2viN*lma*z{FxA)QX5zOl3;k?tY)`;1|2{!yZiKyk`xdXu zIW4^Y6gPmob~iE%U0(kq6{0HEyQfBqaxyqoGt_x4+Oagw^z0CqV_jk9#7)2w`JQneTNCpwJR?nqRW@mjaw0a66Z8P%h#>TM^o%(kND}9rblLZ_n zTWl+ifL)`sH>HBrgkFFTP}LGB%XgL^hp9|x{fjEq?E;4}f8_qEI_PMwT}fEW)a z?&P`h%ZSMW0g_C_`{)-W!k>~8n{`SYIp4*(a{(Bd1vIe>xV7Juw{*UQ`;6@4(eD?V zlbz?fXY;=Cg)xbJ>=I3qjW9jf+js{bB6}#5ujJ463=LX|it=)wgPnl_tDYA>f2y6} z)BQ60D}Smjg%m87s9)xe#CK$8q-^VZZH-08+EyQhG$H7$(ra7T>^TM0jU^j>E-Wmb zi-&%sDj`!YuqC|wv z3%QYCs5B+zy(7#M!}O^x?^o4GTltNn*Sc=YGSy-+8JpmG@L($w!Alu$uTIHKAn^cT zq}6&cvMoZmvkV8kHcTMVL10{*gvSX9DbGz?WvM+!NCsr#%!z=$w2uGS6n+7KE>kJ;P;n}IkL$*o7i{jUDCp|lQQ z!RX1ALx=-`%*1SrCwrNI+fkK-`dX*RqCsfas#`8z!GOuiiaa zvORsv$1>hw+d{5?n__YXmMsES@x0fzBf044AE_$wO=HmpO%U(3%G`yJmE?jVz4R!B%t6o}>i)HDU+Ap&upzO-bB1PO-51qn(p;l$Q+5bXHgy>VvPna!sFbi#}v zdkE~c-K`4K|AjI08k>I!+TJrYT?S`NE8)G;C_L3$d=cCVDPXIyScj&e2&w&3931Z^ zW5IP$d)PdLwfX_jeZAK~1pt$*yZdGEsHQ{J0qon_k_WpE{caOX({KP*b0O3aEJAi2 zJt>r!V%F!m)~*3L1-X!A$LJ#}<+qSo96NdG{pWao@G>;lPuqUu?UBkhZ5$jg&uyT= z<|!zUs)s0WF$4%l1k%J`E3mCudc>CIbBa-zfRZwVT=w+wy!?E56_o+c9|6e)loeL6 zZCqz_>o<2-n&su?jbQ4jkmMrJd+b}Zjhz#g4G=_#gtDC6DazpIQy)%sHS9L~>|cc7 zF!(~pI^n86(I@E=_2N|~FX(6Gg@87>u z7Pe;Um%T<(g&vy%Z@axRcd$^|H76uh_k=7PaVlW1SFK61KQeW4 zxLgK(i7&XXnps!uIm6DBigTalgdz_nvGa|95&pMm{)xB#jauGbg~~zEXD2wO zVaS#MNL=DP*8m=`*(6%;#@_atqGv<~L_#F%$|{-WVs@Woz3ezy32+;6m~?_>f9%W^ z8U)X{!6p%fs4z89A+W!51x!L`dcJSeM?0+^(%+^R>aLjS3x~a?`tVJuM<7 zjh1P{Ey&J*S5$w%QGsQf-Rd41h;Ntk_Lj^pTW0{QJ20z#rIz`h>Kn!?>jck3=Q+c^ z%dV5GMT34h+}$NsCjQ|7cudm!PH#Q|aE48&mY)2EfTcuh`)LVNGhuOdE6duqD8)B5{FK`Dl*TRcK;xjtjn3+GxTW+UzLv2gzkEA0>o_H-Ln0m zRJB>Y^VV&}DxM_*>TLzyF%7Y?u}`?4UW$&U?XBT~n&hYgJQ#m#t0jYWbgU}=;Mhdm zNoN_F8YNDJbDW$=O)Vc_G+tX~>hw(~fF~W^ltOdN;)(;KNd-v|)Q3qf{s3EN_b>{s5Sg>U(*f=aA!s!~iFq$yB*;9f0*f4>rSI16X| zJ*7)+)^v4THpH2tNMzd5-rhMG2Hujfo)==B)VpXfJOmheHgUs`jyNd(`W`|q`n4E=j>v7Kv?RO()c0EO>@)B=q3T70Fv*D$DccEApeS!G_ zmJ-LKg>jlDXx+cyRYrDTytkiv=3tXpP1adw+&pPk#$yDmbp^a<&!_1K_qrRu!dda@ z?1RZ3VLAiH zVhLxJ;3#h4f^9N}!?G+)@L@Ij+QC)+L!AZ*PL@S$9XT1nEa(!azxJ5>U?^Pi=+WEu zZ0ETg?vUS~Gw75vZm*HnMe7mCGSgd#+TrGoxf^XjUU5L~F-Iso!00Tr^!wvG*`M$u zq{xGV15GA_PP&8p|ivW5|R16=jrmWp*w$i)?zps z_o=DA`_VXei)$GMjjxR~s4GyrstV;fa;`40gk_gAkV}cf7;kXjzQI>~_yv!z*G7O* zO?B4UeblbW7Q+FwgRkzN;^Z`2Q&b`=P29YXE(6w=UD2@ep`mA^knI=Np^iHkbgLv= z7!FnrZl~{U1f8@#Qu-QOgBlBC*DOI>u*1&LGp*5&dkvb8uIF_fZwr*qUly5sYde!} z@%wX{aH3A7y(QuTOX5y_aA24S-1{ZQc{AvH+QDqX8Q`R?;hx83)_S^VbJ);xB;0n; z7kLlddvl#-2-x2<+FBlboo<4fiJJRV0ssbvZc~H%F?nv2?g~BiWi0rV~6z zN5MkAGe>JJf%$Ee(}}l>2Jtm>@yR8qvr4#TL$H$Q22zu``TB5n*@@Y4VRO}-(s-^H zxR=ED-lO3w<)MpUJZjYwsIC0L2({L*t{}-oJjJhHEeQm=b~511aQlL@N$DltozyFh zudikpsH*<+`QyFai^rH5!)(gwy9;3RPuHPuUz@&`>7Aio6~A9F#K47NM&E_{9kVxG zzbBPNJCvEM)=2%)R|&Z$wO?ek5_~(!FuM%=ZwZbrvpY-aTkd7l$RIL(u4ptehZ|dt zvwJMPFgYAVz`g1f*L|=Q;REhSvh~>WKtk8cNuYes88Q@DrupAr|MU9brOMi&@d>p zW+EUaPXMXe# z_8>jHN+`su%`Wj4_ErPte<@^n0w|FC)sK!MH8M!6betCL~{=y@eJAn3ZfpQ*ro_WyTx(<`|r}LV`^b!o(A4rN%(NIzO zTHFl?2oOKmU4axk@cZ|h|`1GpImSrf^dqK=kPN_z8)orY53OP;lMd-6h#3Q8Yz>X^=wQzo|-u?aZ~- zle}A3aKEqQaEW7ZONIukvd-AKsrZPON7W2Gmk1$ceXmpa__EXV;&3Q`+ea&%@uoM5 zP?<ND;@=)@T@1 zU2Hxql{Mg`@kqbyFUA0LTAls%4EB)v zd(GPqqAZ{~jKHQRz}M8X_~_2Abu8c)?Z@)UD=D!H2|4AD0De2a60OM7{{QpJ&NS2j zKA*&p5;GONEcZGoq7n5zd0^pX*O(1LbHnN(xfm4E7CUroXe0`udJ1JKIaAZKc(4?n zOSQB-T6wVUV9%#mak&PwW>qPrKj%;mOhF-)rt8}|I=cQ)C|6brl^8JBw zFM4rT0WtmL26=1H+dp`0`#5$0>^x6@_>gxLJtsP?&u?^+Eg<#+J z+sleYQ>ljH?vAWvC*AwhctZcL!tSBLIFEVO^XH#}2Y3<_qX<-kE0k11C8Yq%0_7HU zh=AzHt5@=HY^ESRhr;EN8H6y4RN$3jao-61BrY<=CbBboF1v!+8Poj&JPy^_n_c58 zklEau?aGC!pL51Ufkk@=RCF>wDL#W=z%?E)G#IPW1~TVrvC^Br(c%+4}goH&P^r(+XP?2uq|jZUgxy~5QP zjRDfDzwX3kN?u5QE=iyw{;E*p@k6)##xjAp|}&3FqqBi>JDA@ zmvIK*>RRip5gxdbZ)&?xW~7m{j1zKjwRkL4No*V*31SI+<4jV>9L0|du~+Tw->R_u zdBfj8Mg071h}v)9Kv=x4y*V#t*3Sq4wv+*L829Z%rr#g#%#+qdNRq701Zh9!!d2$E z?q_J!xJ?j_tTYE%BcX=|2eG2^Ewg-CydR$69h@(%$+|)F6%DXaNiO}qxp)1S?nYd7 zcZW$CLMuW zA|!~MW&(90xNwlZ`zio{LK^{Qkv|@bo`uD8L%-feUb3vPIY!&%1;32yDg z3>&EbjYhG$xOEBxmZoLeWh$j5_iozQxx>FdC87u%@b>S>9O}@4`556=+GH{Q;4rWE z(W6z_=H{>z0=P9&)h=h`D>_97R5_#Dy`r^q;tDQ@=8JbEOw`gCDI$9!wZ!M3&J=(h`)Xbp}jzNjqU zsa6sW&~1a3}B_e`wJ)=Kx?%?2cU z-Kk4)!{113H4I%f`Sw;%tZ2PEhg+2gmol7uB~GvJO|Pm7u<7~pe?C9RH#@FtFE3EO zbVFpZ(st(d?-b*3ruW_saO73%lh*EpOGz^Y{APA;Js%!rXaFj1&PDX}Dw_|$u*46|Ww`yT8zE$@lorvE_M!SL_iPsM3gls<_2etsVhN~&! z?o>Z4w_JmObSvY;%~-RHc;_&5p6zuJQq@r!L?b=c{t_FMJ@9tj&`Y~huPzlOlrvLvTj3 z-(NTwESd3Jnrv;sV!&@q{~n2x=TU!|QQzgs4zlfaveMHS6WnWZx(tx9cpaXa`na7w zjBY$N6VEl8UfXK|h{AI4ad)ZMMC+98&O zeMIrzBw}-iDJ1S?#B<>iN4uGoW~0$BhP#ynEd}NTy* zEtcdrkysCN*OH)CGVTr+u0Ggfxp%Mf<#{8GGc>p_f8QP?K;ztE4OB;q*5qPvZ+CWV z6qcp+T&xFQtRtju@-e7K;5@76BjLHjD`-iy(SOoesO?29u;xIX1TnjxgGy$K-AG-m zeFGAtT+1LP5TKnN(j>s1;Zh+pacp94lmGrdl{4#K&#sfn+CfdO}MmsH$!i{YUUN?*Y!;%3`b`3Qw@>-pOd-YeP8VJtIM=p?rCY z&AMnPFcE`=BKs4_&*C8uqkc1xsUu8ujIMHbYsDO42^XFLIJCC5ZXKDOeSilAMIg5M zH?lJXJ1Ts-oYL<7Tb{YZ{$j#%{QKd$u%q7BnWV}e78IO2uW6bRJXVaIR@jzM`SV6n zD@j(08o+9wt#1aJxyFRRBk8v;1+jR)1U9Jkz1Bs@D(j!HUK5$ksoCtT*e9$cq}8o# zmOA+UobyhIBnJma5Ktj2-Im#Q)kirVtm`8h3S4d@?q;9sER8s?PaiCw70u?|)%;X+ zNv~x0bER*5kX|GPN+le&R` z_WzRh%v`E4k7E4~`HXa?OwYu>_G!MDKkQ z#wn-V!^*>$>y{p*5TCZEGho@D!Q^dL{x4BYMyFm1FxjtPm;73K{`~pNEwYn}AIx_C zYZb<4<_e8^iwwn$r18m4*4@y{J^f-FTXJq{L+tEFrHC6zy2vv(heJQ@t@q4=jId`f z7L=9v;EwL#f%b6=5=+gzd-AQKz^R{sOa!zg>T-Q>O1kYb)Co(s4jrQd4jl?Ps^*_R zleB}**)zi_c9UH$#Tm1c@Mf1;|}vH{wU3$EdQLCv4I#-`%xOo#1E zCd_({4)vg1jXwJXR2 zl7%tSI}539p^!DbdT(c7F~aAHv2n|^Mg|oA<;Tz>Vlv5EJxfc4k3jjd!ek3;uX{2s zflv)#5ImBXXBh8gxVZ?fzX2C%XvPf={JuV87g6U>vSMG}4aEZ%qspPXN4=e|8E1oXH_*O;5F0 zJMS=G$vHX$4_-!3TVxnCg-Eui3MVqMm{JuP#4Fn0&f$*yT^k%5|8;*T{@~H*sG&v$ zgAkOBu$pL;iVA(tLnk6YXW%1IU`cBss+xit!aPVOsp`bkw-`^lpTm$6JSIkB?;CLs8K0r+mXMEGvbE^v!-=c|ok|^jYVP(f~ z$mDyRE55#$P*>x^QoVoQUh*^!U0#4fXwhn$p}42WY^e>*3YSQv|4h6+*-4?E^{9s2 zpF10@$%%s;QQe<|L9_MbHOaHHzoy?!qgB>qRjr~w_$tKd20Sm$=Bps1;2!!p@wUi; z=a(iZSdmpJV6)K8#FZ<{5@7!0t!d-iIetz~urQ9hP&+MkaLk{Wcm%TPOICm(LI_cN zS!uB0PrM<9yzZ%N_1mjP8f>*h=!W_@lMpmGSD2vAtFxCJjxKhAlGOeY4LzDLn^H3E zLP!fZU*L>|nE`g^AG8_5iyOKfMVp{HX_=0mREbbMzyB1%R@(`$4W?uClwk`+1kM8z zu=O-i?9*m?`uOAzVtf0+uDe6kq_9Sy)X*TN@bsJuq;YnmepB{0%ozY?R3^T;B@qY%fVrw12NdlC2G$Y|n; z`1qSfMyKD!QVxY(gi{k@gP1tkV)TWMVgIMY(;bat`#YpoYtNjYpfh;Axq1gU8N=R+ z1M$~_M+=$LxzO{3At)|xDRr?uGr%lyn$c}^!6=#ya}+n0;pmsa@;hP+$L`iq2kJdm zGeI{Aw&+*>(8nIXr6RklX_0D@sEsjQB~DPU0nX2kXm#>99H@4*yn(F_qzK9`_dBcP z=brSUz;0$zCxc|t(hR z51X!bISiVYr-!(1^pUYnx5_4X?+Ii)#iD*#l_tlOY;}sNV0&$jlp_|B8r3yJB!$D` z2a*RYR0NGT3O|rz{hg%@_lD8i9_&@QRv%8&;D?id^BdIl>e=Mldw6_BcqPtcU~?S1 zS)0pxZLppt0mBUl8hk321zpxy&_+Np55hnG&&-n$pKz%}$hE&?_ZzVwod`8Obe|2k zU^J?lrE0QDtC?IL>4mF#;XeNUGabrwRj$L=)9!E}Z-V9$)Ux2DkdPIvi~r^_gexuEaA2x-xX+!ZQgY0W7nl>AxdHP@Rze?Y{PP=s%`+A0f8t*Eb7Vtv5&;>85_Tmd zmmML~mDfQt?2xN4!%*65Js$-gXu=wIGvHokYeH&h>K!XW*r9b6Hmh)Sn84kQ3do2B zm@gbAmw+NBn^g?%b6ronKd|dP6hJY|TCiE6bQ|Xl@eSR@r_T=q3z?n{p2yq+-Tmhc zmyC-h6AeB4oNQaJ!a+^H2M8W&`yogM0{S0>+gBDHqdvi-d22Qnz}9)&!7B`x9>_ta zGufI%97@a2=iF2sKq|WQnF`upk{}(@b!x`|ov$_?eHs{hi&it+zMm{UmA=G8z6z?I ze+FL>x?6V)6!u?$>Uep{iUErC2rh#{F7+D+&|I!GaAz-q?CTQD47SWqAu(KpiGIQh~e_?;*$$le$JA zgK33%Ae2h|VL4IGif+B z0XS5GW|}QfEKLDl2x@v(5I9LGy%yxW{7$FP`WT(S!>yHxALU*o!CTADtmJp^G&Xl^6oKXf*q@{r%?G5%Bkj$cuK4GuWhM}63Uq_eL@FxW1qfm|Aosg=s_I`GjuyjX0MCJTa zy$guf5Uvpv@vq<{p3qxSgYGC$=g5F$ezK>KA2P&LP{@E89Y92ikS8Ep!-F;uZqSyY zYR|`F^Ux_13hjMyz68Y9b~K3pIaaYx60Oe=CL8w9YXf|{yx7^Z`0c=P;!OgDnL9$o zp_~jta=cy;!m)t@C`p#W-oat2Bl9E_84O#CL9BzMkI1$KvdE${ODS8wjPAVgbrUao z2s1s@;nEe}Iri*~-XbVBF5i9o{PDEJ)=6iO%IBYj1_Be{Yjh;uK^xMi^=`{Ct=C|J zVz=4zAgz;A`p~X|-KtKW3dPurxci9lcxH%jBh7^S?2y6z^xVdsuiYeil3*uDS2o>=nTyL|92#7-OFCdO!_|U*ZPlJ>xi;Hb{m#P{)*)ja+w=a}{))R!S8WhZKpVg((FDvj(1s_0- zLve2y+BXuQsFJcT4ojyg>?7IhdRL%)K@zH;Fl<25XW!}Pca%BXNjccq0L={Kl@<~M z1&_JuEeRz+H@C$JshZ-6KzQYx=h!iR*tl|Rs)-Q=1qC5kE!enfsCwbRf-kKRpS>2F{COj z6r8EQbrf!oP1JnlsL{HQSScsUJh}qfyPz5O&gv#;LC28}6p%iTslSBn`JP^gL~`dC zgW$uZ5x}Nubyu8__D86`;pITT7`fE0?L5d}5j}!NDttdm(1j1uV5D9e76yoe`b-0L zn&jTcAr5D#DzXE^bicjni-l1A2{g02 z(6e*%)rA1y#_@ANF6goj#3-iWT|AL5$zT<6g53yWARTx)>rYEJvOX;>$S5!ru`OXq-pN}3_`WE$e!b7&j6qz)%ToBAE!?4KtEo?Q(5M(i87%;jetPj zWxn^-9TkZWy&>={k{^E_UmT0B!v5^a1&GCYBFZ(uqW_cI_0vxi>%mbY+SbpX$@uM{ z`wrEZ3;67Nl8}%zM^+y& zcTJ+U%U=Ogadt$R_c+3@VJ8Dm0&8#9O$|C(z+klm$cdr^x?8~AQNVlCsLT8vVs;kf zfTwqVLqUJ*V5ii9C_vU)Qsmp%^{i6z^1TzzzX<1xIgmk~T_D6t?MgCxp< zAdW=4MGke13E!$Z);mYJrF_`1f`seh6SaJ;qYs)X3q zgC4~KfFYltt8o{E$cXwJnxLX-4LqNMWEF(pw^-`?`JpShj71r zB@jF~%iUNYs;F7ryN^=Hp?rRKBai^NgeKP5@Qf_K08*pEzQOe#pj=fkXxh|X4SC68 z&EI(m8-@(=glc1%y7aw8w1zFGM7Ag4_0*h@BvUm?*i~S6n|n5wxYykhU_4f#LE;t& zY3-qx;lll<*kx~X*deMOdu#vJ6-KH>J@;4Hk* z1+5b5?G1`L4Fj?u7G{XL*m5`tKq)|1Xldi)3ILe1@V{cZ&%yj!y7otbIR@o`wFpo8 zh3A~N)@C{*6#2`ZM@Vk}2{#ZR2?e5;M_e874!8P+V5?cd(K`w$guFZiM+*xiIFdIw zvS6VxEf93o6HRZR$29?vOLA%|0BsF>q-n<`96>v)0|(XH2S3Wj8AL{(AltwTp2^O} zX4~h~Y1fX?Sc29txNN`zz@8%HObw-yFr_&L5rHF^odpWv-anj$BC&9^xgH|Pl}*1m z^omPE_cQ{{iz`5IF{T;|6{~ge4My<;aW+s~a-=Uuao#Fhsyhh^e^F?3XNi%BhL%4g zqakuyFj#>^C~b`lE#b&amcKta2r%T^RbE|60d=6F$lmG?tpc;-NY81I5lkEtXeL-> zJslx6SV=I1RwY%P)Kaf}a9uJcqF}xW`A@JQtjJzs4gbl2uIKf6THOU zTDFe~xWh5s5U~AM9&PFe*ALl_gjYdzIw0X@=Pjfq3Ir@ZBVYv+XvgDVXHV%`fz|=8 z=wWchmuSMJf#36Vvu*q-)QO~R)9-KkPQxxSg~$v2#m}G_^%>HOtSc?;horZdmmKkr zH1vI+KY!b9^X#BADp>)Odc_HheIEMXvWmwUD5<{v6awe1W&w%A%)x+jmjEO`5Q3BQ z^sYt0y%x=J5@dJ4@3vh}0_|;%F(IS<5s*Z}qN~!QfWj3V(zntRFzrnDUAxU@AHTj` zW*_mcK9$I7_0)nFQk;h_4$0{_oRGP-9hA~T&=pxY$e{)R(Ew|dU6<9$fB(gvs zjskeLt02ug1QK%oP>I4NA{y8^V$cf(A{Njyw;akUIt`BB+#mKe^rOG~Gy_G-?!=>1 zpcs);3J9ix>>v4i0+%TGi}RL4(!lW34cL>;mbpMNwk=iRleCcQqT!9ljEH`U{?oqA z$IL|pK^G)JF{y`EJ=0HW?fE3~9H_NahmqH8tkHB&T`pDyp+wc5mG$ z-nam!KdhnemV$J^LbZM*;%^KMaL(LP!HKLL*M#RJ(+-*bbvDX^?My8KSti10U8qb) z7C5DlsI{6EBu>Ly;~Va}x=t|3Df-tl`(H0?iKMPk*wc94DFY#PTu zK$n8WtS_vHBDf+NCfiw>7TwwsUEC7qc%`zU#1Pd&V?n1 zcOv7}!~FA{D+J5Wwmtocl{C&`r}M1qxQS^i?FFMd9etfW0oL#a18tM3i-YSPLtU-7X>^FXtdAQ7%%<#eE)#rs^xV+*SzJH|* z@=LsD@iFp9BOlUS`a@aF4#J*2sAhlU7+u4Y++Dne+`U4biU--N2z2CcL2D;;Qrs!r zeEmNuTX!u!+Wfb&RaSmt`WydHYD}c>;TsWrumR2~+l;L=tHa$B)pyz!+;k6Pp#v!n z9velMt$MSKx<8fd$`ygbk)+vPUPD=Q;e_C4gH38#NwG@%C4<%YeP zbN_#dr2gYL_U$QO)@zp|qc!5Mk$+9R>L1}c_d$V2Ic5oc2`&S;%_q1iH1vv79sPak zaA?i)AqR$Oz3VOoG`K25#QC;c0#aX-#lb3>2*7f1sS%-GsWZETgjbM7|Ly-v;L83g z<8~6|*8UEgb2n!LDZgN{R{ngHZc4{*1LPw_@GwHuL;v18P$qlAe;om|Lrg_(Dw&N1 z>A?%o8@JD7ohstv{zuSy^3n^7)^$S1_ZPpx&&xHGv zFy)cn6?cuJE84c96?F@2ZPs1DiRf3~!|e%B9;1G<0-bAA!PiBg242Gj{`k;;i7zA7 zyp4?mEa2J~mxL!>Fy0lHD4UC|QiBt(_SeJpTj zR4Tmp=%l>G!BhzS9BWrcKflN!ulmKhj0U=h0?CYaU0ooR`+zXYpi+qt2CCm}I;e>u7$2Xv*ag*FD{Pz34s+UPT$bBC5jYDAj-M$9D@I*oyZcq$Il zG4cZR8GK4E(`L8zA5G-rCP380cvQNrH}-cf)he9!#SjZq6gsKhGA1 zK2PRCIn@S?wKcG;nsfzQdr1EhV0cs>*#M4Oz{fj>Yps$1k}!E1l-6r#w)p=9{( zO~-k6N29JWIn@-T6q0>_t7|LJLBMu2b1sX;>8 zFjC%1wwNCdHTp`~nN_ZT!&LHhKPxgNB!xy}j6DUsEEMXD6?7~IFx z(FTKg-~5)oJZ<@C1#GWs6mn+LN#Je@11X^N$(aln2Lb3OV-adil}6AAALZj^&lcZDmdOc8z0*nlybdJ`Ai_P9Q1>RmRZkpgjNb)%WgW-$MlGIJC&B z+Rg6o4E4Drz~Y&fL*YzyY&ly`K63bH;Xrju!awazky!NlKD)FW0kbuo(i4xx$Z-e} z8;2}mZNkpH|HeR2iPKQ4EcC=8V9y=#WYqVeB^lxMlVpJkMb2eA!t*AJsA?W5^Qb9t zYRS~Gy=Wk>>WU8Yv^B}7gGWv!2qpF-s}b99D*sDG+Ikv%m^@<05K=-yNL8)*92c0w z*yV?igGWs~|B1@9IdFSzXebD3l*yWiu!XbEYm5EZ$rE7k0|F2o{QP zh5(%iw)9bC0RrHD0nqY53Gp&_QE)aJr#JEvB(47`BbCQBbg*tgyTrdK{740)illm^ zBa6&=E%f?euftICGi0x+oj@ij4ejHLjlzFZ_>m0_$k*ZSHHo5$IK$m9XP`|5*&RjXWNK zTQGQ?oAOM)iNIYlaw;nC;JOp!It@s+G=?=;<=Z-bHvm64>e5F8K`MEf5*pbci(zyf z^hFwSLYoJG1BHIPz@?G;6}TzjcB!)!V6-~;328#Es6no?1M+XAUBkcx_*q@Z$fMTS z}P`L_ttUo}mjlr9*IPflUS!hCTFM?YKxaKUMvYFon3TdFcYO|VjsAvQU zGiv1s=+r@OdVmZ-#5&2x7m~|*xa_3~G^0l<;a_r)e}z_4SHjF>jg3#Uc&*+}>Ew}b zbB6+z)ZXFJc@mf2yC2i0vhm^o|oqw4imjofVJt2zLUQk~N!X+Dbltl?2B60#Gzk~yG z-h0;-RLsR7eia=FyVyIV5~&6%Ot?m1ASGJ5{xPTrt}ivk^7cF zcwGc_c912I(dybBg3DzFznqB}h0axw*1eXAUx7;_LE=dJquAj-q{&mD#(=)a^wn&c zNVPID=3~%qlBrXZSs17n&X%4CWdtaKJMP{+F1RHYak0Au#+V$$p#53!QQsb=wH~Ea~ofjL)grA>3=hf5G~}Jqrb+M z^3MmPo-3rQ%jEssnclmYHV)i|#KP#Ee;7t>vl)#Uj^exLr2)s#F>@piIH5? znpISZ#Ohyvn{{LR24Q_pOL(D&@M!mmtVm_MT)cFcRte26VUmmrs2!lSv~e#o|1C7+ z+{j84Shy|Dq;=1>oY{baKy#Qd_XUR;b{3r1FF3YMWrOvOhA468W?~!{eM0qpi1H;L zJ3DdpY(jtF`>A7ETTnH7WK+V~`bZ`)VV1D!R&oLq|Ak$I7SqP^`gyKw)^lNR{Q{G6 z?Uob@sRL3w5i;8JR`qnLFly&)*}7}TM`#f&k7_PD!g~{VF}2q`I@_$;-<>Dh0 z_(dXMNG&j~_vWwP_J%@UMVwfv)Tk<%qD5ojfql2egV;8p#3@==OZPpIVzw?K1;X;% zW);=KRmk>c4z+w zC8h3i|Ne1%wnzI&za1TU!-t|c%BCGgt=A92%Opc!P!3(qW<#r-3+p7tEHjQY?eV zQ}I|8G@W#t@9depPhU0k4Y^JcmNb>%(xrTMUUd{6Jh0GDm8?zA?6SpmZpRzkgt~Dp z9%~H!<)^Hm`RsnROZ2GeBtN=RT;bem;Kvl$vPQaa+@6r0fL-X#cvIk+tA~CW5%|*- z;>{MF7@zumDU(?#43Z|^y7(s1?B5pyX>LtT_4sl3@Of^pYK(obmB+(}6KBN%?J^oo zkCi?3!kZ=6gq?4<86m9)Kt0(AH%gFLIju_<4uMC-ttqp*1Woa$U&0X=U4BDI#BYDlku&HGxC)Mx@+(DNIW1k; z!ggew&dCht;@NuV5qXNv_WXv-gAkM1{Yuo4!fEnvyCB2H$3$X6lbTuK18_62$lhCu zCeJ!gE1NbS8~F_5BuPAUtV`eaeaA__NtNI0{D*Vsr^rYu_O}S}*dZI78FJTIiYm3i zdTIY?VnJ+h5)u>yJv|!wgv_YHoqV|GxDmyT8{WDvU}8-0!c$aa%Q+5!;W}de$5`^&SS!I~lsYNbU&f8PrFajELWrK_QL&-~sQH1UBGQ z^gKJUQmG6&*u3fwO=(b`=PjeLcL26G=EFF$^9&_KTi5XtLf(v6Lec^~i=Ii}BU>Xb z37FHE11%9EMm**3Ke=DM=qf<4{B@&f`oh9|1zI1-=xDJ?iyxlttt2;?xb~^`9#Zy8 zO|fTMLvSMOhzDgVFeHoglw6sPuI#T^VQ)QDCVlTxEet|c+td;HcGg^zchcl!23+ju zPLu1o))05gOx$gVya2^~CpluF#l@@+Yia-P*atqu5`_?zD6V{?TIfumR&=jg!u2hp z)zzig=dikox!B%nT)D<*lt_oAUf#^?O!CsRi?}S2VTh%+NGp?@0_NNgg-e|{6mm6*cbcU3a;~wJTt9f{( zY(%}L;1KoQ%keR)M^Gq119f5O@KAR*9ZYI7aYuPC*cB1U8+;D#fi^P4-w476PCpIg z-~$s3!BOV_>MiFVqw)G0eTAgEP6%v`q9wWpq?fL2L-LYc4emg+dryDBy=CS70EV=m zByQ)15t)^{O&P8DSf|*P7pb~pjX6kJ{yKFjK3Ny{{4w9emnIpi=8m_i?~l|Z~#mqNpp?K0{DuzAYp||CJsR=QO8oRtK~ZrEtz#& zq%n;g<+h|KIwy4;0A-jH720Q^zxo6`%btBCZ!ctCJQo!S+ovW`1oLjkB_z~p8Fwy#Majsx z>SrxY7qy04a%xy5tr(sEW(h7D`DCEHdE4_ey|Hw(x*?+HliFa-TWou0dYE- zBJhG~`d_+IEX_XYIMA#u{2`T2j) zOp!^~2>d+uH?tR&>?&`Vn^zG%UxZ@Keq?c@8^-9L_PpZPuN&YAo)Rkuv5iA1jEEma z(7GTE6Sg}<=u{%VibL}vL^qW!q^&=I=tgs^?cXn53rTNtT;v2thDLHZbWqSF`Z)Gx zy#A_5)CYiwNeLxGWD5r%IUzSVRyN<2XW15rj?D3Nd-fDHfLQd(AaaXsbxS8}!z?GX z(h6~_AuAI`iWNr)R%_)w?0xsZq4Dy$NjxC3FS&n9m3%dWEDO>vZTBxff9e3!=+A6o zVzQYKzV`6&xPP08{eNd%0av2Z_$s{lzbYA5dTpWJ8xJg-H|v>0Z0ypHLbOs09n14X z{w?GU+3JeH?cYoVv?}w}9@27afHKT|Hh@_f+LA**k}hW3Zm}h_#p_N~!z~xuObUWT z`SBmUa+j$aXd`hYSj)Eq(+Ew(z;nzZXa%q_2wbV{sdPZ=TB?dy8L=G?n23bLECIWK zR{iUj^my=yRQ(D`@Wkk$2FnEe9V_&KaRW5kiCU%3lXRKIS~mX!@U~;+mAVfUubkGhaxdy%VV^9!>y5{Thv*zYp=p05cUHq?@ zTZ6Ans4XEBfR=;`H9`y>NA*L#zIKjg7Kz*4%GK=uJy=71QDJHINyKSK0)au)FR;u6 zoWr_gm;jJl!cWSJu~=_vg6?GQmqCl>^cv7>(TKHVS4Uk+ z$Yj^d$ae7EYievetd2X|+WtWBM^n+qaS0)`-`U=~Uf99NMy^e~Jfd+xI3hI!@$7r&mIK54klhd}_y|NXSe1pr9U{CY7 zN@D&k*i{z+F@96IJpL|5T8|GOs}nvTBnUDHw`@RM?3vVGryvA3{@m9B`Y81@0yPy8 z_*&Bz-fgOa=5JfGp>sf($PHe~=$-R~1s8Sl1_iPCHENedLx;3i@Qb_P0uxRmiE^Fw zf|+BEw%aN`vpXT_0TDW;iW8UJU%G7F&^O<10l4n&1dfZR5FD#@BI`(@Ikcx}Rs-q7 z!l)2Ndw}c2TlALj$f<{6c~iV0Y6elf6xDmx7{$^5QJQFkU=gYi4JA;ANiwai-MW&u z4X`3agqpAEe%KRI zzpc)O19d%i6&}Rf;Gn^t&?cG{J&%RF)RPkx?^!h*^wE+5w*v9tdO8 z^C%WX1Bq;u$SDHVH1LvA>7Y1=DkLp8b&9T70Lmnb9o;L0{LknUTi)2$==2FD`(%Yyz_7DTi{ik2bzL_2kH{XKL(a z6Psp6DbWIpA%$l?5=CRFz=|)|LnNt|n66E}nS85ujETuRIO1q`I&a)q!W7El&{kNs z+8x7u`?xb$pGwiYz?$3Gu~m34YV6|EJ8&k`wa9>o-Fxxv_9H|FC7=2SSEXrz48+=M zZyo==rxr95FbL|bH~Mn2P5H`9F!XROyG0n38tkVqrN-Y17?c7N06(%^Qp`; z1Lc{BvJ?J%M$&zPk71{EotW)4Bn)S_D!n|AegRqbeIh(RVKr+$)WmH%4IxO=(TI)A zDbNrJqDtLTpFg}Z5{UP*$g=^OM~j(AYyvkSPVy7^c2s=n=njT0f19Oqjgf>vR)+XS zHbVb^Ml~n*9^ zp}5QYgmyuc=BEx|;@i|cmsB^dO0bSpk~cV759sx_F-PB2v5ijg*|~Am6gIpMn(&K~ zcL7AJQnNq#(_N@^C5Je6AE<~ORANel)0R<6Jv9wd8CrON18jsDTugW)3i-E1us!(7 z_lZmXrg0uQ0o?3{apl^J7or{xHHf*@OK_5`o~p@ ze3e#(($b_OC!!+< zQ;YD&;j6Th6YyntwP@3)yho;vsXhx(aobtVe-aE0q6!mO1?xbxgE7CM(!8=*J zl+7^qXpKCgk`O3mAdDRGZ(dZ%I4_T~$Re(-bX3_r($G@OPpDQnF@WoRK)-0WdGpV? z=HZR{3a$PdJT0L>#03dk>4&aU@(ZJdJF7eLwrj-IOEPNZwXRHS6?l_TdM#hJQikfP z3+`VX&DPX`wS~X~Y@l=l;YAS-kq2$oy z@=n&&zrV85<7|I2(pF}7+}er>T8@R-&k0ws@lt(FX(U$#T4Qade)WyIjCPQ-{;A^! z{CvV3_S8>kD_4r2cHYqdDO^G!Jred+*bGH6=q7^+2X7 z`Px#;HNn*D=guqb$UKXuQmJ*_E4hEmgGYBC^;c!QlEqR)0`yhby-TLCVvSbk2wCN7 ztmrNLl#(Pf+TPntSXGYyn1wLf?6NFW^@wyU7dmvSj=SSt-lq0gwt6>t%F1iE<6K)q zoSgG4@l5`5Hg7Q?z`4!xiU4i6BW2+$Y8aLiL%?jJ$NV?W_-mK#?W8C#H@VqAFf|PH z>t^6Lq~5C%|Mb;oC4|xa#+fdTfN4$Z#VcbJM|H}2XQ>0Pb?t1(v#48t3!iBytH)fr z=9Z{!==j_$LXZRO}qvDFo6QQs$& zriOc${dV;Bl35nDpv%c)x+T5EIFGv>2VP)ui8Fw;3HxXtpI%F~B99u)pf);_7qeon zpm2|2mc^()U`F{#B6&rI)N>trNzsEj6%<~Lu68*JP=%EN+F+tl6^CGDk@1Pi4M0c8 zq|Mh?-=$%CmU`BC58w7)YKKsViIVlh!<}}QvgDn)uBbmDW4C0!*(}vHkUi5U&6&Mp zvTvRWP^N$wQxjb(Mab4Qj zZr;g*FDb_k=66M}(Re5SxcFdc_6+xBnEC5J=!(BvhVNGK*D+9GDqot@oD*RQ`lYqA zpj07PEqCQlisdu$Pgg%Ze@9a}Nyvl;8cxgDZw>+3Xyrr^?;qbIJr53^I$+a8Q7<91 z@UI=}C)Q#0tfQXm@=+f9;f|{!?H>L*Y*Nt&JzO7`-TJ$Wlk@i#&qwDK?px=wLRVWV z$+$mkrz%QzpOw+{3F2S}^7^>LfKR{UpSSw!4C!YbN48<+N7GT%VLH;~GPaD`YHNvb z>1cZhhNQ?@|9DJee#UD(In=+M$16Y>Z^-Gi0c+_jol%a%o%3f);X2xUNK<@>ZGhJ#v$Tz^K4Sk*B}WVHbBk$r zOhstbeCUdKUQ>q{(Tk*PS`<^^iUkfMDSB6if4GF(yU8dgua^>(ZSM2)0OU#mCa@;lZ@X5-iT3Gv++T(r630A0xwdhl6#Ot}! zqD$UiQ-l0ItN1-MxP5*1=($Ca?YiB76KFMnv#i-pFKtZ`&#_&RWM~N8~RaEp)=i4x%{3m6a^J<{1=H&2XWj8!;+6zGn@-#jzZ>I`9(A zt=hqsH1g4QgiMtZ32bH&m}20@bHkHqrTw+T;@Z=LHQh@Tm*h2l4fEtOSfrv0_1zwi zMZF0c%CHMe-LpBwP{V)~G3n$4R3Rt2*R2;<=y<#)8Z&gW%3R(!K~ARft4y?qIYQS> z{;#TX);o*c+D3Zpa;?`bo@r|?Deo=#cBt^3AJ+L=brE(odrLMJi;zGt()hkC8iMJM z4RM8&sXt0xDkqiMIjS)DX`3?KXoS3gxtb53jLOQxvoXi%4;4qOmn2?iUv*q9vej)E zE6jf3xn1U*hZEV@p+flv`L3$`GuTTxxVRx+yOB!ZvS?HKc1k)+=2Xl;EHxTmU!ywo z?2G%dAEYhfwS_0fefdi~4hr_;3@HqW=s&fUF`xo$IyT`I3) zr_OunF_YMHVs27;`Z0pEL|_4SiH&4s)p9+9ZsdH|J@qs%jlz+U>+*_}8SGrgyg8Ji z0TO$GiBO)Z*Af#g6*f!*- z@_Bx~XE|v{3RrbvbcU6XqeI3UqHjV5~%q3se`r&JxG#D60TN zAUrZvFdS|Hwvv$eOV4GGk=$CLU-TTgx0N?H|87Ybf44VmdFvyQTf4_c1$_z!$faYZ z%WX~${FL6|YWObO@$aehkCq2s6*!JzsOJ%KRGib(d#HF^)65XP*G>oREYvfn}BWx(p9 zR7OS8UmXCd(IQoV#N56X9S7x4O;#O8qAgdB2Dm#d`gm_iex`Fe$W@V~D1T7!^d_qa z&o8efGJj7nimi_?XN8sobJixGKM9!@=~yXMd6}D^Y4T(GFxk^L^7_AL z_I_R~drhLf@*_LmAYSL*1uiy?l#1}{`fTH#X{y@V?2op*zVoc~+7lG`&xb5(ilGb# zkTWp}EAG0luP;&0Bt)B8H8fl)$IRb+Sl=RH86d*=*o40?Q;677+3~B}Ja6l)FfLnDowv!o?0nSdsV`mNrpPT5hA)!JmbRrhTK3cB z2z7ge_LsaouV5ZEWy7SpBEJz|+~S_UL6Y1?RGZr4xb`ML=ham(FkmIr4V+3Lps>>Y zYSnE0zlpkaHH%w_*m>tsM-_j&U1qTN?k2)ihKb;$I%EDjE z*;y~Uo4JG3ifZQs>?p^xuQF+8NGTkW&s`3Dy6TA;KvJuh10ObbM^{~cwQdtJXv;VB zm6&|P8g<)ThK+Swjo;P3>%18g6+sp^wjAu>ePw9z&>`fMCKvq%d}f0}5VBp(=!ALW zQOqeTZ<_=)7b<@mDf!2A+euAxnwnC+FRTo%UM+tGI^=8C6Re;4Dqj7FnLC)*;n-z7 zSihJpp{O|uA%NPH5REH0#T7RFjfg+ROiq2J?A6xkfl;M?SAUVzFUt{SV-fnywKlck z4il`3$q_Fv2FtR<4&|Tn&=I(Bo`l-}AU8wqqQmy>5v5}T(b_8_tzzr@zsD(_Z#AXQ zJi0wy{?j!*1*te+d1(@s?1jwjz8{{*o&Wi(cy^HPV5qRTY}*vC@rjfP&x0REbtd+E zeqJ@t?cYulm}SVDtM}%?I!9rq_mYBfd!Cs=XpD;Of0~dCbP!MHZb!;gr5JOJOoS)^ zhAmD4Mtn#*syLZzT`wc-c8!`pV>IhSi*jbZUl4Qj zr%+AW@5jy-9J=@^Tw&_Xyp>1fQO7uc;gN}V4~=i~{ID1t+~B#C+#Hrskkb`DSQ~da zu!})nKq$NQkJ`5%Y~NW&)hWdE8C~6U^P|&*|An{OklLX5x-^zQnsV}PDhR8DEO+T_ zvo<03NFsY^4>1ymw|t?G$K%3AX***6eNsY#+LBG{d)X_tntxSR(~A=wf`TYSECbqZ zc6xF_p5!d0?tHY$&Bs3q>Uq9|mR2)QOs8`Syo8Nfb!ir07~gZaW5>Dp3tuLexQVPu1e>Ejs+n#Wd|c|7XbzqE4Q1 z@-D?%MVTAblT^ud;k7m$r=V@Dr1l@!PT%`U{Zvt2HS4?np*<-Dr?q|J_BOW5#QNRw zvVXnHr?Pp^H?Q`~BYEucN1uOIW?-T5i)HJj4)kSd5N6=@duqEUaAbPo0;R-UH%;L$=Xt@d+RQa`7ziR?RZ`|13CE5-Pyid~;a!+nx z{HhSx-l-Pf;Nwrey}LcFsMX4v^giX9P1jD&L1qj|Z+T|HbxHm^NUD5`bQRa;hW2*m z&Aq6mZBaXR>wH<&nG2lno04~j(ola-xTF~*xhyV!PG|jyra#SxkNGNTt@zcQ*{^A% z|1dI~so1?sX1wV3(`~ay&I?rEsUnlY^~;T0bYjfwts{i17fWJer7^0m5$xvPQqSqL zp0`$%$+mAICc$So++DqQ9REYo@Mupm@#ou%TeyfnC-&YY{sGB~Y|JL&PpSWZK32UF zb7Z$tol>BhrX~iCoZq=~Ck6-v|M~NWhMAdpXt;;FA#>oKo*>^$+G3367s^$0$szTg z$gf)l`KuClCzr>Rm+J)vL%YA{1@YwDw$9GZLi(hMy;^rp{n=m9zFF5<0P@m+#IrBf zA&pYh)s4bDxEY}SxI{%oV;m|qkhRHa1yM*sjMU^&S=#4G&7%ANxQ2UeV8}l<6zM8*kx1y$!G6>VBYTbAL@b zZ<3(ZA>H_rf%_hU2WL`UHm*bAaZG`fcmj{UU9`lX3%;kxHhw;IiTL|F(c9FBAA62$ zQh(}-f>R^p4di5Hk8*P>LK|r3OmGG#qmXrD)UB=*bX|*ec*`K6DcNs~Sv@9PoSgE{ zo;~~g+hchLNPfz`&*JR`qh6r-xP{72SE80 zeBwUJfp^6&F3@XGgGy$k)ae&dQLmu@Bho*^<@_Z|Op`ZM5vokK1>Z7zP5`ruCyhRb z=47OuE3J;?($L{faIVaMyn2k0>LD*)q(I_Eq+iEG=lTxmq^zulpVozCQ=hpD+~%#_ zFdgj}2gk=8}}=VIVuEn6Gl%(p*+UT1;kY!0BJ9Zn;y2AF{t>NwO; zc_CVIw2>Hp*_>-~5l!;>k%Q|C4-%7-I$(67fME{M1`iqin2OG{hezU=e{^xMrS<3glqNJvNl)Fy~;2Ut~1Ffu~lYH{j!0c1(sz{h-DQqoRLJ)xwc zD)jTC;E&g=G{=;%X6&=S-{K!g%ru;-cUqzqN3YWebJYsl+qDMmetp_w5~)WPfGMh& zjvoG)S)v^Sjx8}RqQLkIL&uw2nX2y`Kjz;*P3w(0WF`Q%6DPb}9fGybhaz=W5RTx;idyZskCfuh;F(AsA!C8(K@eVSfJQ)p1Xo z?Cfl(fx7)k#vsWx1KT>d9E}?8DQFKzFM@^H#s?|i%vljV#a#y_Ed$ewidyUHXF0^h ze-fkll3t~zer9U}d$Ddr=gzL}+q1#u6BWd^%NrUpO_G8NK(ga_SLfgr$S7xFpvRzF zz4H3|k009)u1%1;(kA@*`}Z}}j|-eewcfzjN1c|d@T$cTPse~udL}HM5pL@gMkOge zafq@T?d9>59>4@yE*>6m?=o_EU{1hNZO8E;F>zXLt?;aXqZ;~g56{WT&0RZOiCd%D zyEh&$P*f2A5+bda(GORhE*p2hXkFNm0)aDCN5_1S82OV1{HsOu&t&qA!bb%rG{4qX z3{+55Y-(uenHF^#{w{}hy5#ETx;i!NO4Xpy(4>+Q(b2B5j+9~@K4GCuJyq2pkktwI zYh+^bBaKB6N#oA_Cx3ah1bdK0W0LGqm_oc6Vtluns_J21J+cT)*G#kNE?=s-=n=QD z;0*qyA|Y4IUyt|w;56+G0;en}D7d(C?}$9c7mI>-e#h9+U1VKUKZBf{idpUU?b5H# zSFVI<69Aw4mqzMJdVF}15#UqBs(cVE1IC3Jrk0Y+~I zKtCTcTch0-`h`F3{qY8e)t|N%+C*b)N;1$fW?&>RU?d$g@RnsDl?N8p7t!4(bKOK@ zn+OVW5>5rI8fSxQr4d-LS33%AT5#0!Zw{;c9vn<7DiUt^Q58z0Z>~eJ5Av`vV4t_R ziY`!KYdMvV;Shl;5d8f4s}_AvUD#vN$o=JYe`iy%imrcBz&e3mmx`R+eN4Mfz$_k; zue-Xpj9nsofz!?#}zK>&#Ivgvv;tqPAaLbS)k&CoEe{-s13^eGk_J&X0%<_^IF;6@@NG%H7) zxFsZX-Ir!AOH1Fy(8?4-YA%gMRZA-s6oE7dePM^F;&u7?`_Dr1i}TnqCA`)d?uQ@V zzaM%PVf`IiBO--fN-8RW038kFzJ_vJy|zGcebLm^OiBslUUa*XK_bs7o74vq?k*hS6XS=fQvl(r(fcm@WB$Z)7H zrD7tq-{Z%Q=Hzqd$X-B(8?p$Bc(Jz#bVw6+dt~OY=7gwS zpEofSik+R^&YJAS+Um0Y#Gpi%=em1hVxoMXXn#1(kopPRSPadab`~#yC`MX(dY=AD zA3fdPz5Tf-sn*00mT2hdS;Iba)Vzd91~(sHAu(Ut*vVStM_AZCLLJFm?ABNw%*z9M z-TFMuOg#-16+;YF&B4}OJZ9oL(t1Mi{P`@mvEphhUpkywTwEOQm3o0=$Lc(mJG!;h z)kCm@{eLS}5QA=-fqLo4GPw8Ez7lj|dvhqpUxyti!1`bmPy`OTwv$r}~k%gdK9&m~E%)}-``_P5K#P^eJS9m~R`QHM93%@{dMxYtb*i58#XK$O3e z1ptr4FIJc^40m{pm9-MS;`gs#S6~UhN)ozRj3V|4nB!iBH#`amT>jFMYjikFS1TwW zb^Vi9pgm-XDN*!wzd`&djIb`LK}bMYdQ5DZd@M0OFl6W+cmvbpQ&k<7X3UnGGChpo zY3OKajeu0khu4c<#c-pykUg=)(P=KQ(vA=?3ltO(SZGYwujsNaUoi48`a9CI}Mi8J_s{zlbRerme z%?x{&;rO*XhK7cXuap^Ad&s34FxI$dWds`Vg0O_jVaKHr3##ksy+j@Hbzh(1muRW( z;$_F4x1>pHD^c8;EolhKIAH{t1J2=~g!7x!vkwl>x~gBg6a&M1^yEnuc*4f-iHcE^ ziHf0I{QRoe07R$>h#-7t4YvmqhJeLm$04lK#oTiU!6!v#=j5E69sV)sH%~^g(9Mcy z-b>-ejRc3JVW1(yh3(>C-e1MV9lG!BZ3R zaFd9KZfb5e$F#W;Oe|JYS5E{k)U-9r;AAehM;G=eg8T-|#&(c9cMcQM)dLeCJg1|s zuKqK2(;XICx}ohPBrH*Gwc3|2Kf_e%c>VRImcRs{D3=>c5mdu7s3N8X;*(7t5=Ml^ z=IuW?T`*I4W6s~MBd4-hTUm6)oMvSHeDX`ph2@Eu=cSXk238i~183$d)^%b30~4Mw ziD7A#T|rzD1o%<#)G2e^D11T?n~|}xUeh#m|5TA7{Bn9Dcys6yk8X(?{8S5mt+BQB zd<^ba4$1JAMpW~Obx1~Dt(U1OwcPfV*nIMXU0a1529!dAgNMKhv>Q`uYHSp~`#HL> z3XeOCyZKyGQyjMhaTQ{!dC6!&$L#_HLK=jNhA>b_P*6NXEn&{hAk4fp8Q_`T+S;c;E>SL%|+`g6KX!d zcg{fghsZi{rwDx{{Vx)1F-`ZnPoF-erAomIv6+Fv1}V*`uVK~wmrYHRn=^FNh*90H zurm3G?tyGo#^L$X5c`gnDLy@237WLQH^*}IdV71dz!0NUAvyiDpI?pS&YhB8AI9L9 zFEe0jqmR!b_)aY;(EkR*;I3g(H4*!%lCoG&gG|;e|MH1mxu8H1jHeY^>>@ zOh!&OJUlEJFn#NZ4sYnv{CH;f%773TA75z4XfvE~hUq%QGJa%Vua4}Yp`&~CW~@Zf zrhJj(pSwV!%X0L?$B(JFX;%!{#@vX6@Nfp@DA8Fz52QbH$XmZbkCce<@~u0ySXtK> zrQSb$xJ~)RNjV}w#|jePiAOY@AL}IYSiV+$gn`6{kpN-?XNj;0PYz0D;3#n;*a7qv z?&cW;H4+fB5^o;~+n@IQzqDTp^YYXXSGzFA-yEC1jwuWQc;ZB4gu356NJ!S*P-;1S ziHO1t3}T50(dfpFWJDpZn4}_L+w(SarL89D2pX39XuJ>sYQE>XN4`yWSCTP2FJh-3 z*bPJ}f*Z*=_;B%^On$$$9pAqA;4R!LP!>5=RF*lS`=;J0tz+7a!%bf3H0)YQbu z!=qfW+&M0Q5PEQso=-2G@QHEU>&WOh4<9~*yKZyBz)Kh{d1N2Ic|1vWzt?dRv?xIx zqM|NbP!ZqK4$+*Lq)j9X40aDFNbaoPMNT~oWk{+S0TL2@{;_{m8Ls@MBFYT^sdhp9 e_!UvKcbhy#5y)XH;VV literal 0 HcmV?d00001 diff --git a/src/texts/abbreviations.tex b/src/texts/abbreviations.tex index 09916df..37073c2 100644 --- a/src/texts/abbreviations.tex +++ b/src/texts/abbreviations.tex @@ -6,6 +6,7 @@ \item GUI "--- graphical user interface (графический интерфейс пользователя) \item ОДУ "--- обыкновенное дифференциальное уравнение \item ЭВМ "--- электронная вычислительная машина + \item ПК "--- персональный компьютер \item ОС "--- операционная система \item ПО "--- программное обеспечение \item ООП "--- объектно ориентированное программирование diff --git a/src/texts/redpic_performance.tex b/src/texts/redpic_performance.tex index f4877fe..f25a8a2 100644 --- a/src/texts/redpic_performance.tex +++ b/src/texts/redpic_performance.tex @@ -23,6 +23,41 @@ \subsubsection{Параллелизм на GPU} Это позволяет выполнять параллельные операции над большими объемами данных с высокой производительностью. Задача разбивается на блоки и потоки, что позволяет эффективно использовать ресурсы GPU. +\subsection{Анализ производительности в разных режимах работы} +Проанализируем производительность ПО для разного количества частиц на примере его одной из самых затратных по количеству элементарных операций функции \lstinline{sum_field_particles} (см. листинг~\ref{lst:sum_field_particles}), которая нужна для расчета эффекта пространственного заряда. +Вычислительная сложность данной функции $O(N^2)$, где $N$ "--- это количество частиц. +Подробное описание теста и код приведен в приложении~\ref{lst:appendix_test_performance_redpic}. + +\begin{lstlisting}[language=python, caption={Функция для расчета эффекта пространственного заряда}, label={lst:sum_field_particles}] +def sum_field_particles( + x: np.array, y: np.array, z: np.array, z_start: float, z_stop: float, Fx: np.array, Fy: np.array, Fz: np.array +) -> None: + for i in range(int(len(x))): # pylint: disable=E1133 + if z_start <= z[i] <= z_stop: + for j in range(int(len(x))): + if z_start <= z[j] <= z_stop and i != j: + Fx[i] += (x[i] - x[j]) / ((x[j] - x[i]) ** 2 + (y[j] - y[i]) ** 2 + (z[j] - z[i]) ** 2) ** (3 / 2) + Fy[i] += (y[i] - y[j]) / ((x[j] - x[i]) ** 2 + (y[j] - y[i]) ** 2 + (z[j] - z[i]) ** 2) ** (3 / 2) + Fz[i] += (z[i] - z[j]) / ((x[j] - x[i]) ** 2 + (y[j] - y[i]) ** 2 + (z[j] - z[i]) ** 2) ** (3 / 2) +\end{lstlisting} + +На рисунке~\ref{fig:test_performance_redpic} представлены графики, показывающие зависимость времени выполнения функции от количества частиц для трех различных режимов: без JIT-оптимизации, с JIT-оптимизацией и с JIT-оптимизацией с параллелизмом. +Есть значительное улучшение производительности при использовании JIT и дополнительное ускорение при включении параллелизма для больших наборов данных. +Для тестирования использовался ПК с процессором \lstinline{Intel(R) Xeon(R) E-2288G CPU @ 3.70GHz} (8~ядер). + +\begin{figure}[!h] + \centering + \begin{minipage}[h]{0.49\linewidth} + \center{\includegraphics[width=1\textwidth]{test_redpic_performance_1}} + \end{minipage} + \hfill + \begin{minipage}[h]{0.49\linewidth} + \center{\includegraphics[width=1\textwidth]{test_redpic_performance_2}} + \end{minipage} + \caption{Зависимость времени выполнения функции \lstinline{sum_field_particles} от количества частиц для трех различных режимов} + \label{fig:test_performance_redpic} +\end{figure} + Использование JIT-компиляции и параллельных вычислений с помощью библиотеки Numba позволяет значительно повысить производительность программ на Python. Это делает возможным решение вычислительно сложных задач без использования суперкомпьютеров. diff --git a/src/texts/redpic_test_performance.tex b/src/texts/redpic_test_performance.tex new file mode 100644 index 0000000..0ea044c --- /dev/null +++ b/src/texts/redpic_test_performance.tex @@ -0,0 +1,67 @@ +\Appendix +\begin{center} +Тест производительности функции для расчета эффекта пространственного заряда в разных режимах работы REDPIC +\end{center} + +\begin{lstlisting}[language=python, caption={Тест производительности функции для расчета эффекта пространственного заряда в разных режимах работы REDPIC}, label={lst:appendix_test_performance_redpic}] +import numpy as np +from numba import njit, prange +import matplotlib.pyplot as plt +import time + +def sum_field_particles( + x: np.array, y: np.array, z: np.array, z_start: float, z_stop: float, Fx: np.array, Fy: np.array, Fz: np.array +) -> None: + for i in range(int(len(x))): # pylint: disable=E1133 + if z_start <= z[i] <= z_stop: + for j in range(int(len(x))): + if z_start <= z[j] <= z_stop and i != j: + Fx[i] += (x[i] - x[j]) / ((x[j] - x[i]) ** 2 + (y[j] - y[i]) ** 2 + (z[j] - z[i]) ** 2) ** (3 / 2) + Fy[i] += (y[i] - y[j]) / ((x[j] - x[i]) ** 2 + (y[j] - y[i]) ** 2 + (z[j] - z[i]) ** 2) ** (3 / 2) + Fz[i] += (z[i] - z[j]) / ((x[j] - x[i]) ** 2 + (y[j] - y[i]) ** 2 + (z[j] - z[i]) ** 2) ** (3 / 2) + + +def sum_field_particles_parallel_cpu( + x: np.array, y: np.array, z: np.array, z_start: float, z_stop: float, Fx: np.array, Fy: np.array, Fz: np.array +) -> None: + for i in prange(int(len(x))): # pylint: disable=E1133 + if z_start <= z[i] <= z_stop: + for j in range(int(len(x))): + if z_start <= z[j] <= z_stop and i != j: + Fx[i] += (x[i] - x[j]) / ((x[j] - x[i]) ** 2 + (y[j] - y[i]) ** 2 + (z[j] - z[i]) ** 2) ** (3 / 2) + Fy[i] += (y[i] - y[j]) / ((x[j] - x[i]) ** 2 + (y[j] - y[i]) ** 2 + (z[j] - z[i]) ** 2) ** (3 / 2) + Fz[i] += (z[i] - z[j]) / ((x[j] - x[i]) ** 2 + (y[j] - y[i]) ** 2 + (z[j] - z[i]) ** 2) ** (3 / 2) + + +jit_sum_field_particles = njit(sum_field_particles) +cpu_parallel_jit_sum_field_particles = njit(parallel=True)(sum_field_particles_parallel_cpu) + +def measure_time(func, *args): + start_time = time.time() + func(*args) + return time.time() - start_time + +particle_counts = [2**i for i in range(13)] +times_no_jit = [] +times_jit = [] +times_cpu_parallel_jit = [] + +for N in particle_counts: + x, y, z = np.random.rand(N), np.random.rand(N), np.random.rand(N) + Fx, Fy, Fz = np.zeros(N), np.zeros(N), np.zeros(N) + z_start, z_stop = 0.0, 1.0 + + times_no_jit.append(measure_time(sum_field_particles, x, y, z, z_start, z_stop, Fx, Fy, Fz)) + times_jit.append(measure_time(jit_sum_field_particles, x, y, z, z_start, z_stop, Fx, Fy, Fz)) + times_cpu_parallel_jit.append(measure_time(cpu_parallel_jit_sum_field_particles, x, y, z, z_start, z_stop, Fx, Fy, Fz)) + +plt.figure(figsize=(10, 6)) +plt.plot(particle_counts, times_no_jit, label='without JIT', marker='o') +plt.plot(particle_counts, times_jit, label='with JIT', marker='s') +plt.plot(particle_counts, times_cpu_parallel_jit, label='with parallel CPU', marker='^') +plt.xlabel('Particles, $N$') +plt.ylabel('Time, $t$ [s]') +plt.legend() +plt.grid(True) +plt.show() +\end{lstlisting}