From 36d85e4b414710769455df50f3d88cbcc215bdee Mon Sep 17 00:00:00 2001 From: mutouyun Date: Sun, 30 Jun 2019 12:02:12 +0800 Subject: [PATCH] modify test cases of mem; sync_pool_alloc => async_pool_alloc, synchronized => async_wrapper; statical => static_wrapper; optimize ipc::mem::allocator; use std::hardware_destructive_interference_size for cache_line_size (TBD); simplified codes. --- performance.xlsx | Bin 33093 -> 49768 bytes src/circ/elem_def.h | 4 --- src/ipc.cpp | 0 src/memory/alloc.h | 47 ++++++++++--------------- src/memory/detail.h | 14 ++------ src/memory/resource.h | 10 ++---- src/memory/wrapper.h | 80 +++++++++++++++++------------------------- src/platform/detail.h | 10 ++++++ src/pool_alloc.cpp | 6 ++-- src/prod_cons.h | 10 +++--- test/test_circ.cpp | 2 +- test/test_mem.cpp | 28 ++++++++------- 12 files changed, 91 insertions(+), 120 deletions(-) mode change 100755 => 100644 src/ipc.cpp mode change 100755 => 100644 src/memory/resource.h diff --git a/performance.xlsx b/performance.xlsx index d1881212fe23a28d67f05d7f8bc15d114e648858..997d170a1272ccd7fbc1f02db3d73f464bdf9024 100644 GIT binary patch delta 28418 zcmYJaV|ZY}vbG)Dwr$%J+nLyQGBH+c+n$M&iETR*+qN;$JA0q=o$p_-?yLXRs;8d2 zs)vHWPC~$Ol;yx7FhHO{U_d}XNI@ptoXGIOKtMWC>Tt-wfDA*&H5QcKZR$&YasS*1 z>lU{~hzDbUs73ZtC;*>$kgSd|f4#qDd#FT1xf{%dV!nZXKwDB z%St+HGid}{^IP=PPpCrvdv}eG)}95VQVNXa{#W55;OE+F&2Id#{dLT0+BGz81r-gQ zZsCL4*7eQ6(CEOf-GO-fU$LD)uNC^> z1}k=NFlN*I(QkaWD?fYRxL>#4M5tRa4^I-q2dw0E(!_ds+^zf(I)?md1;ml}$tKui zoilpNfd1YqNxU6aVC|_(?gnRI`Z1$d`tF6-M^yUx|Gvz{;#n{B;$dSb;ti=E{%1Sl z>E-XUeIut!Z@Vw6@t4U;+lQPH#Z<5(x_6B6vA4Vtg;!_JtSJKjvMCt(G`W3fZEoE| z%OVdB)2+4bdTgFH9K|?x^-pVCg({Wq;!JRihzL6_Yde~XIP8|MhHr9 zxL~r`h0A{da{!eb4~qq8=>7{B4FCMbFO*k7ifP0M7)&k1@@(bhCT8hWXM{TGy-C*e ziZfu_nM7}#sNEfPr7r&dmH*gR=xXDleqn`0+a*y7hTG2UcTQBs@dV6AJ8?FnSxVFa ztBk}n*~6slkNJhk*JpVi6^+{0==Rm4R2kI43#tWA>A&ji zjeSvrHr)`m!VduLB>UFs-NaM`p;0;>6G&(X=vB%A>C7EVz#Q4< z6t9HFKSAD-PC`;vmNTlp931w+?83#9g-{iN0lP7@kh5np?=IHwd1D&ftbB4aYr z1U!*GVJ+~lrMZSNG8!lu*VW23XF9?(k~GXlVA^cLK^0~8M+pbxvb|(fwjBZqi zGCarT1P1WBGL+vQt7$gk*Smia-yaeZ_;t0-(R8W7UsbsbZn=J!;wQ-A9xo6-#3e@M z-dlb=vD?fhboZT-B)|ExFX>~0dpI4IW!PU%DQKLt0Y;w%?+Q0|m(|U+Zk?8fGo>}%G`7vRHa;fziXY4P%1LwO96z)Q|Hj4B z^E9iq{5*3nfaY{@g79&#wQdodCu-|HZCZ<4z0(^Z@cd?Zz%4bPvb~(Sz%BM7d}iWC z)Bm^P4+A>cVi&~^NbChd-3J-ixylorUi1{*hUT-{b|Bda786dk{Fm|He~D8Hyg?6| z1{CN_nz9*WK?u1H?GFCa<(%}XJkIAs8`{;p4$V@B7Or4tS}yGMmX&hF^}8f}wwQwB zo^{gVjrU=XklbyHmZqKnqJ1rUx(UwUSxM`eB%+DE{TT@}M*4R(6EoM$imjrOS%(N& zIghGQ=0I?Yx-J2Sxln;z`tXRTE1oHRa1DUmE}?z&nj6!@S&(HNm8*i{afCPMk1+P? zXur*&9~QxoZyi0yl<<>_=GPfK2*}qLILLo=BpCq{ z4vF^OUl|Ds1Vk4H1Ox{pdDj;cU}N&Mx69F9k1OUu@iVmk0=*@=A&lS?Jev^b7faOS z_wo7#ds-j^0_vB&`1zJb8gLnAol)lK95*p?cvoKZ_iXzXtd?Jfmdp(HNm9XZ)R@f&ca$SRPt)t9;4G zDIOn-rU+I-^74wa@zfP+*HEGQ)1CQ4s11U2H?NqZK^OkqB`)^eNqYZ4C_aB$Mzck7 z`~YLIw}7D1nobX=r2RQTZI6J37p`EA(ROWyMBSrK zKX#zw8smISkM3#Cu(`n@5WWUF;V|*~@dVE8RNUI~;Q!SyX>^n}=1Pa`#3JDzhj!G( z$c9raY%TvVT+%WAsMfx{@&zaAc-6(c@{hY>d(+3Qom{|0hN6z!}V7;wn;eD7*}8YA`Q zTLcc6dnix$>%w-9dsT_WHO9T<)Q@nSRu)075HhH&V3TwFef0lBVC_&FO!NZ<4Y=zWitk>Ie`4BJu zdDO`4`HrIW+e$+mxO3m*Obcge7hFk)*p_`54%0B&#?0xx=N!_yVsB;b7P-=aNgyVX z4&U%VIpwf^YT*5?0i{Q>)&LmjinZB53jO{He<9d>fL{3Bvt2<-w{pkP1Iw5F{Mua#)i2Z2pKpjQ-z~e{I;mqGs0N-9g zc@z{jy}SYIixr0n-zN#E{e1K?PgO4! zAdXOuPyxr4aN#N2MAcALuWa)4q;bLnNO9-%X8Ga_etR%yu)zp!I|!wFoe~*RhoPcJ zY}c}zRp{d~MG~aqpgHYMta2q9bmwd4Gl>3?Pw`g0_n-exo^YP2!BpdGCHT$?VAJ{LfCKCBKEj-}`yrV#h>L)Dn7mfP_T&Tf zUOO-Nx)9sW6co`l{hk|DY9lEUnjc3HnA%iGhhkS&Tbg7(WpeiQYb4t(J52oq{xFXEgTiEJ!gb z@N-GIAVO$g7AjLyyq!TB&r>RlR|qM=q9gV@q6ER9-?XKdg*5)bzKcMK&6*LCiTV_n zsiG=%z#WNF07J}?`Nv>bBWrYe9v92=qPgT8uExJ3Wkb84Y58Qe*9WqEXfNaBZAAV*1*w%LO^>F=AARvdm7K@DZ16Ax7Y zNk{xB&8<0AO1fAFd4%Pcf1EMZLoy@XtRvn_{Np{?>4O>(0Y>(~1kDm64Cj10O zP9>$F8CPJUW-%VMX+LgI^k3Fe^G9JVH(VZ8EEMts4=SiUl(3L0elzXF8I9Y}A==_V zI<{Zm5O|&-RUqrb&vVi+U-U4I$6!evwj9xe>y&;mjn}ggwMU#u^oe__%NrV?$F&xK zuP!0l=hxYHVMZK{15Xz`;B18L@Q^zBNj+=$4Jl-qbmshOYUpaY#GkH;j4tWU z_Aen8H0I<4Mthb*gRd#Jmv*{}&iWGSa1Z$M$q&Pl0$-RCi0}PW3yCg_IBzY7>3;Kt z8|i=G-;;aKq}IpVzgl`9zy7144KhemP;mS|r4$pvK|rYClSwc!fr+?vE{sj=QDK-3 z+lSvJ(qSbeMDc+jw8}XDYxe8yuK<{w7O3ZYVjk0bb z6zb8uB=UT&lDUB;*P{)zMHN~&48508(xN0z%xti(cI`G=7rt1D*i4KP5udq2%fn>i zJH>0WI*t; z>f&r7l9!#TJ4z}qc`Q^1#-`nr*2L0x+NQ7y#``Q_FBT&s)0ck(2OC5eb+|@h`EOfW z@FsWM$}Q$HbFb*^m;5iHw4F?6-W|kjwviYI2x>64d>RFMHEB${v4jghaD-ofp)S#f zU~$~KO-dc7jhu-6VYuSL`dn;QP`CT+C!T&;W;n21?M%;#5E*@ZmG~Ilz3+U)pW6K_ zatvq$V8f?Se*nJSf&;9^-4SFQuMOZlJkG|I7jG~pnR<5CqO1xwe-$N&>1SBuu=1!eZhcjkX?ySU> zslB1O*y4#Hm$vcu*`9ZMwng7QdDC!~6Dd)SYaDqY8xD60z%L2Ysvh@bJsr+Usm;=O zPdFZYTYu`kHx@0Y-I^_WQ-dI6f>Awuu&-exTAHN5HqBoEJ{AcwxU_n4I{uRBRcFe9;#xCY&YCl}89V}h{ zQ{**j$~mmFplo8F5JKsg{aN|@hCZTswjymq^4XiVZZ0Ah!>CTCk>s*h<&#hZeM0Jz zl2<~`F9N;{8uS~LBw!DLSc*M9eqN|!LiM{EDf%>DnCTjnGS)4R@dOaZip*T00A51I zKt*fWXlhr+F&*@Ly{1an+a&KEld9@9QE%2*gquh;L;Gz45gS+Kg*Gj15|Xk`Po<)M z!NtDA!JNVvO1#sk!gRrTJ&1A}Zf#w`6Or6%g2JkjWUN?I?ndlS^Uomn?tUJ1GzEwa zr(aO4lJ)^>2RH=#g3|yIF#J2HS%XYKG*UB!HOs*{Zw1bJh;PNF>4TpTrj#!ze& z%iCd%_n-^h`Nv*sQA{mwNM(p$ZUT;2kHz^8Vn)&F0P~5nC;)uH%2c2EGz*U0=r=&6 z=U+9|Ylcs_5(Y5CM!!~vKuxNplIYWJEP7~o63&d1|4HJFOaNj>y<~>6@I>=#k|Uap zYCFSoeUe|{1xq(~;RQz;(jBH71Z2uzMg(y*3?F5!d2NoVg)7hkf{&r=?R(?ZX^O}S7!ocDtQUctVc&q*cezpQag zcss*Zf9Q>xK@!Z{rkLtmZ-aGoTY9?z@E2L#T5)cH`i5%l?E^yc+|Mb6RYLD&f&1%R zM9MQi+%(*}d->ZyO0Cy~il$@{(X-ld7~ZaHx{SsK~nRlI@A4scydmP#^>FlwvZ1Y|sYd*X8NDbZ8 zzWFb_NRE*uZh$hVhk(<(!Demw7u8Id$*r0sz^2VQ3r4^-v=4Og+u&E6sY!ZMq*URL zt`#DYQ5QQ4T~XEKlsW3v#j7U_pX@#&(!g02tRT|1-|=xJRt$5seFs6KRGE zfE{1dOsa2?HKh1SkPhPZidKkiG;?j4Dy?Y0&c}Z+(6g)tnPk*~nF`t41~fw(8dryz zgQIb>caveaRtRyHku+)?rYuy4NT;r#tJR1^RRp7SA9$GvR+!5yD%Z=}Rj0d@ZrCs_ zRJ5_R;f5zqdG2G!9(&r~Z{7}f?+Y*40bv(VS!%5`vMH+HO^d@Kl5niTIVNUwQ@Piu zPrSXp#j-^Q!pBHHMD^tp_k4Z6oAVSA$J}HYver=Ur=_vBDybcBSni=vrqk4 zk_A>8&U2zRp~&k9ObNjgH9hWVW6Hg7%QT7?zUB z1I5MPQ~R5LC}Wp{k9`dbIB^PXMMG~idkWmRd+t0XLT^Pvzin@H-}IiMBKscS zJbSy^d9L4!qI5pL_HOS6E=v);P!m0*Lp#KKqJ&&e1mEC(5?uSTtnG@e~ zBX<(rlK38dz1K}c?_0jO3J^uu7EwP#7Yp5y2;3I*2;9UEfxBIk)bb_&4~ckxq>ssf z1_2o+Oa}Nc0oMN{;|pzF$8||8f9Bs`fs}We(t8S>Fo_*(gxJw*k*KA9C+iUeGJ43o zlasS)st-NaneY;_T!d|_CN0*8D^$lWN0V*7$NkIOj&dfOro-?$Q}!MgD_AvbS=fu- z4qp$uE*R@r*k$9Wg_wEk{F9g0GoQCp=XPoKDCjK!=lE|(aXO)iqbJD-Z?4Q6yI{G& zk;Y-n$!Z$0LQ4TmIXF$vn}!{^F-G1Q`s1H9Yv11CsmQjT*aprK5)`QX(MiDuydlsw#yZC zUTI~ZX$d@^tN5Xs$gHv4C8sn+qabeUFIzTaL~j+CDs44{ll_549>pzMUB@pX&<;*L z7wrVGi-o4khGh}{P345}MqA~2maK@~$Y>fMO=aLSh-q<}Jmj0Gvj($7? zBwB4UANxf=!A)<96hov2#QeY+igC-U!rLx~=B;dWaVw6wDqRXG(*hCOWfP_7Q&Ht0<J5E4S|yE>FU{ z*@+%BjeCW$;;}~yu^H)EvpgtNDYadskFKw9Ojt?6!;*xtfI@q|s6-IfwiU>VAN z$w={l)5!~F3u(Gq1-)cp22xeqgHuIpdmImKODOy0VdVEA8}#@{jI`9p1N%P94_Y|j ze9+2tP;jaAF!^g~d*2!4lgQoSU60{}w`U(x@w#l@NB|DXuLpVGd9DW-A~_{0Qu;RH zM_MEmc#I%sg*=ST?DCGTT=VV6Or-uX#q1@@=6%sD@o)!q-zI$jEMXiNVUbTEek(QW z0_{rlCJ#?!A<||S1#D6>nOLd)cIeJB|1r%ppf7Umk2`y;CD*SZ+f|6HDVNLT{g&jc4OcnQdE6}1RTwUUpYTURWpkI{FM>DlE%H-gHJq%YBg|#z zH$(tjL0K3zq#fAD6>k~IEKrbDQNuc0RaEaE*j`-inpD1=#!FxJT)0PTYZRtsyDnyi z_z^Gvdqz{(gq~fpU^QiV;eZN``QX&%Wz*&-GrAm(^+ZW?nCj3UQ7<=}KNQXFHo9}Z z9s>-LLmNb)RQ`cL#Q8?4HfDssPlEH*;tPIrcBVh~a$D8eT3JZqHRyt_c`0qn?X9l<$)L(8 zjlb(?YQt|uS+|F@CXLypq0|g%USKC6`Xhuf!qj@Qz0(iqhVlDXQ_x?3<1EYhytheU zEEq@Yz^g4NPD#1|nY#3Qh8{OZ z`AIkPGpaBjRFJBhoYi`>eYcLnsF}dIQIf7iXNapEfItl&o;edBaScZgE54!%($pe}~M-eRjOqx_f$Y z%#$0pVKmDNZD1=)_p8Fh$|z1~oH<%u6HI*Tghc>|cm6PdkyY>L&}Sm)>B+TkTVrq~ zQ6}I%X!$q+e&aSY^4L~An*r-A0baX*^a9c4uGneAzs4$ex6S{<<-@GjfcvYbrsR9+ z&P-|9-}}J{*ZM5X)Yc)e`oX4gAugOg>^wQET$5jS6?oOGDQxFOdvqU!6Ek#o4ck2R zjM9{ai-2^;uCV;c<=s?Ep;eOl!$cky!P3Itfw4ckY~<^Jzu+74fAL3*>>r2*JsB2I zxCXdsh?aj6e)V4oPevAl26SE5xv>1VGe4oz=359=It@7zb+eoK`J2#{a-IquQD9}N zM1w#@b!AJx{E(SSXjbJjf8}mYX(Drh-Vp5Q-Q>a>`gPDp-bQGv&DvP=rP<@Pj$0Y1 zXa9WN?>N`C!$XwPh=ZxVncLVOet){C1UkpDRfAbXv~-V3K0IR5m&8s%n-MCiGgPb`aptp z%(>||zeCg-R8smBL6}VhgDXS9D)@dia~Qf)$vx1foNjs^pf5ecDDIxTYdPf3H7v2d zFRxiIv$)KOE=POPu@{Mxr;JR!X2!+5NNVtjmhxd#z{zY9!aVUh&b^pnzqZCD=m2xC4W z7Oe}C{b<>iNQjolHSXiBqv<9`#!;W}`HqK~m&dn%_Wph(AN*+Y6Z!21o?jPyRxJJnPIXrg=Ic155b?`hv5b%6ye)- z^`Yab3Iz7(+x5XTut*TQIHBv>f8ah=kS;%uV^ll^CHABY1Ooe)F={ZyyN?wT$WNXl z1W7V}OL-=cKNX=n3eeD;#hY|Q3euVSu58B&0{xN6dCmloD!v5~Qud4bB+D*fKv}9; zN=XAyYx~+wD8KfT{kLssATct+Mcmb#_DU1lj9bv3XTA>aG<+&j@%bz6>2`L81o1jS zMKJ6~r__al0c1b?>?GB0K{4)5^kqFg4No>5O@=8$HDo;wg%52fT!SfJei=(_tvvpY zs0}&p$j)B5`E4lB=j4HE;Ruf1qUxw;#?N#>^23lnbh4&4Cpr^2)SqHf<cXyCt2hu;94btM~zG@96T-+qMIKG zEeZx*zAK`@9ZXO;IJqG-VsNJ(a}MxUu3?V|ExuVR?6!mq#E#iBfPN%enIe)JLD~|8 zufI0p0O1eMAPj3pSB$*NRq>+-3&=yu%bBj|#tdg&07w7b&TeZ2DKt0^I~Fp($_Ya6 z1^%O@%kp#=8{&HUxX;JGfh=~iv*iIeg>rOC{R()NN~{h{%}Wl!SbQOaCj0FO1i|&c@mI7~ zs6sH((Tx+(D7CxLz;4vw>3lN;fh(>L8{k+R=0I5$$*0)A@Q9}9MxO-}SiegHi``jP?)FqvBXkS!3`eyMdLszsN>4h>z{~@ z8#CBL-EqDfEPSZ0=tx(|O%v2^_m^iO%b`2Xa%dK%agu0<^i(r}79IkFQP5W08V?3S znNaG{MWT>pP!wf-{h1n=@3%USl7LMnwr8u0z>pe(!@)xte^DBZjhCKR_%pG7G8sPl^y9l6Jns8ywxoK z?)ENXzGJsodmK6`s}un=4+sQwr(mx&V-qn!iS3=11C_hsn?SqlVVNC>U^lA!%)^5p ze}lR8PrS_KU(bwSvjs$7YbU}JtIYZ@T)k{}Zx@(FhD(8ca(}C6eG?r1G%!4Iyuf={ z{k;BNsboS?(-oudatd}&9m8o*y&z&qE_l<4vn||*E5Yox!jcA*7upd{l+OQ;zEe0a zw7RC4_&)gsz`S@Me5snWj!yW@pnX26{pl=^cp}dQIhIf}6k)oV%{lk%7Hyg~DMV_+ zpo|&aBB2(B9oe*uy<+pNs_t3qT$$6_hUu;<`Tlc>MU&z!riw_^HV z%YT7SthU6_1Zl~jd)dz4Dq7~QpqIY={{PgSM0b4p^O;CbTBSaNCfi_sF<1eN2fFt^ z-dtLZ2jBy+XSK#9v@)@nb7pq%lWklxf4+oky)qb@ zG7;nDphIUY048ZOn@uTGb^=(hS?b?Ct4KK~8F6cWhiG-_CoGO!A`J(RSr%m=08R zVX%C=ZS7cugemV$DkvxBRmzyw-zKaSjXF=oeQ6~!2OOtJEVJ85B!)c^&rYgq?^Y>O zLza8#Oq)W~biFhzWjg!co#$hAS`qbJROVE#9-20zwR-t=*%QL=<9t_Aaw6KYi>;W0 zPUIkWO83WjetU;b6j@On#G$#89zdTp?>iX!h2YDdf*r@pa&--D&V6)}{qyEUa~35; zHfM^F-J1}qc-h*CP=1~T323-j zHlX<2;~{tyQ)XLVI1ER8twed!v4!qcN7|A9G}o=g&1YW=qol8mQ8 zvgQd3Zjix+aJL(3(06ITkDo2z&BHMMO$v`w*^%_dF!YUz;p^Cmco3=;cy{dd18Fpy z1HU!?S|xW$8VshHZx_BRGTK9S0oM0@DhNJZ3y3^-4nJsEr2lw(?S$6l=b-cG_#$`8 z|Jc4xjEB}U$L~Bf1Sn(qxieL=Q*Xa_U!mI zX*1Ax(Fi|j2PQp9`QR$tHY1vf;)KDz)CubWZd5B2gK5Kp|J5JW@2reEIJ0AKLKe&a|GOfhX_C0P=%4|nP^Qr{lSu*!1Ln<|Tn?!fkv>fm3_ zvuUDoRxlzG>YPqEDz$ph^OzjcE@Q&Fgk#nH=sRuYTP)emBpUE#z~ z-kc!1hUw|vX~8>ROIebx+9Kokx{hNcOP8xSG`>p^;pZ;2i^ zmNK~NK_RLq0V%WKD*FjPSU>-`<+W8H422^eK~Sh1v)Gv#8?wP(>sUGolM<`<)iSS_ z;jim7kW6?u(cL;<0bq0;(_)x)NEE?09;UX!C!Du;sDI@-eP)$vz|D)!t%>i#TS@DZ2Mt3Cb)?5n(1Ww z_w2GDR|NY3jbS~8_MD3_5fTy~v&3Ey=TzisX3MUO!7-oaMRR6#*NCu6gwP4i@ag#N zcpv_v!{oIGlw#U0SKD2U8 zO?2C~Wd2Mxro#MhSE<>q9wJ#!hNMBu=AZH>=n>2e{ZoEsqJLbT;6H}`pXUG9&^I{p z*Lza`jO=W(=5J7=z8yRjdO##2jpUSO0kM)>UH#e$hL@1$YH*+L;?Ngdf#`L0V(Rr^ z@_qbhrkWPC=q#G*e^e4!?o$w*sL*EK0DN1s%xVT8ZDhr*g0ZiVT%X_OdwlOJGO+On z2koQbE4%DJtrP9uo9lTrgwLPdM&6Gvy-h}E>%5TWMomBI^_etd@dw5VM z!bZx)6{n}Gt|zB98kjFZSo*Q}g+GllNI?MG33|{`!`du)@6B5z^#F^>G42YH6FK!z8^&FR*!S#Y zEVcm}iuj^`5aS`pb$U8(1lNnk8ubKbw92!g(I!!#z1|?Z@j6u^6_75+hPY z7}$U?=UUA7zF?+27V~2B2Q`UxV@unYzWJrXXhkGY(p{C_bB2dnl29GP3C8bmteAU|HjOB)lalrykSDEa<7i3| zx7V9IEL^bI@9>rZ4L1F<5R-1^v){+>vu`~+W*w1yw1ma1kQQ#h*1i+g#nF;E?mE$&YIiXy2Woit4 z_dnBZ`9YAv05fV)Zh6TTl?D#rloVn^7o+fkh~QaRryvzLr|2RS+6KH~IL#W_WEU+1#HfM_JUr`(?IA$mB!PVk^*>^#y4UIGXk^2 zU~9K9rjYNW(U$|9il(oEFs9q%Xv2?n(;|D6-9Kmkw0*S)1$>!{7IXpzXf>+Oh<>fZ zwi_wHNJsF?i1DG6S(2U_#CRJ)WJ?)WQz9o2y_$T_oiR4~hI)PP&_?mn{MW1jj2f{> zFmB9h9eRKSVV`1*jlB1d7@mX;=n86wGTlFD@i<9CZa`A-U2a}kGjO9~c&UF`;~vUh zA)v{CL1WdufMjh;Sq(sDb_+v-9o1mWAssMmr5XyifV}LLT-I<6m$S063c~w{u1D5z zeuf&48&CzOi><&l#1Mh_+?1OYLAwdGscBCWy$>7bgFVac&dVASHB_uFr~^sW*bHLn z)b2ncv$bl(2>LKdrEF$vfXLJT2+Qh}FpqNa;QVlCnj5E)J^?1`x;51#Rzz{1H}>T1 z+}v7A4zI#^W1>R&PgOAFH?XuY_xJFeor7_H*!yZdB@FVvG>~D?$;!k0P^CNhIqD_7 zN%MBVhb*s|@opN910}}+DQ~NrAYL+S%`&Lg#Y;iCh1+cBLxr1jkNrvyp9783MSJd zO+ThN-@nrHiv>r7SwjO^CYqC>YpbuJ4XwhfJ@mAP~tM?EB^CONyn}X`w+o z6A|_l>_7JP^Z`XqFCd_N6OT}ScXiGBl#V9{n4~Y3y#WI?q>(DEPaN*$KV2D!Shzf! z7QmBZFMz<~v6s)F0h;VO_Yv)%VHM9+d2tPRaD_<)#e;u#rbVM}hn_*ncJf)@Z6kNt zn78v8yte$SUOK`uT+PsS>h~^r55PR$CkO92Z4|KJ-9|$hjLn{)cwbd`u6m*$(sy0A zA=A#OdtguE5e&6dtJH4(gYVf#|Ka;Ijo8*9`Tyhhr6u%MmH*-QSpVhs6}xmFf{FQ# z2hT&v3vMK#nqQ=sVPC%s#tvzI{KNNp4@NWaT<1C;fk#%ZnTeM@_j#ZA{~3z^j?=zp)N`iTGAiRb*EPQ0A!J{MZIqsAwAdg^)_O*e5xBD!w9ny&2( zk12Kd1_@dcPA~+bNHa(I`?I~kKd;Y0ZdtF(-*DSUCi5*Q|LM`9eD{6;Abk-03Hafx0&@wyea1cz#}a+pL)uk%2^8 znb?^17BjQ!cv40}QwNwIdczNm?lh6v+AHAo$bFG z>%kgwQR|lY&8~0tgr;W3slMJ?xVI&@vI~7R-Yn4}Mx=zeO~4dMW6l~8Vt*Tvp31rm z&#$ic>7M)0rvML11>a>#{9CPFdvQ9;D0lyi&Ta%vT8Z17d)d8Nr-(PF7F*agw1Z4r z4bsv^S0c-{Io!8zXfZ8>QfTaF*!*?SL>Jom#3q3oV5pze(r0e1|;x@maKg5rXw{ z0ga#nfy${MVaWNnzjSXv@sQ8?K*C_@ZQYIK)M5=;a6h~z*;8dNlse&sP$tVv^vL0B zfpw+*)*VPKARnuzcz8$Gghh-zhH%CpIwZ)n?%oemNpZlX$0SaoyuukVz{(?&ol_B) z!6BG8Ta(#qQ$fiuNUbWq*(7mOO4zg=2)lmiUe_HEtRSgvVo3;b*w!17(Sd(cOrnyR z>Hk#WwqazDQPlg{^!vI*`+}$`y@k^m>qXQ>y$*1KYbllKX;hgfkTy`ElaFBe9=FWa zIyMidv=o(U`qm-?vXmj;FUk?i3|*M50EL|%DBLRlUY<`WiXl(c^E?-$MU88WY`FiY zf{9q`B_HbCpZ)C~>eJkv6Q&gVbZ5`Ro0liP|7Jrj*oiOJpIZgXOw+h+Gc;zFis3pi zD++jeErYhPIDjepczG>oJ~qS~k^lXs6qq&5+byEZPxFEeYO_NNVk7*CEy5TmUW!fG zaG_QJ^{9+ja!b#mP!yZ*T^qnL6Zx%o&9unQm;pYSMu^KEfB&6AK{!&sJ9!8NR!JlV zt0SOa;ayG4E7~*=T_O_SLBpBjrG*EJuMi-n?$fL|C=1jfNTw+0W*k#Nbo;mOzcW0N zSO!@;8@a(DAmLy8Z#717eVO)rcW1D+u*T_P!t6AUPVj4>4(Eo+C-WANSi$rqa>ra| z@7HMhT{5%m3HmtDb7N78v43-DX*P}oe&}KsG^nedDc;TPAHLdmt2=4N_z?6A4B2pz zztp_XT0#~yVP2Zk1uij$y@`TILC-Pf=3N6Ij;t??aNRAW@eWS2eBsg1Cp5 zBw7Yt{X}d0YT|tt3a)Q+580*%s2BQF0YP19NiGQ6IL!N3LbQt)XN`|z(oHw_Pm%R7 zIvvlR1t!(mh~OA7+rcM7Hg>!8328q^HBE*F9#^y%Qf=Om@wB_RalShUEoXxkuu2B$ z6;+9fJQrvGp#^vxCP2sXvDC6Cn{Lkh5Hh zjg4<1M#>}=vJ2bcU?05#4DDgdc8+JK3D&>L&OlWTg*jMex1eJh+g!V!NsoUS7d#eL z*>gakO0P-S$Z&lPyDz^4OTw0^a$1x`7N$a8O87hI{F{`^xOeC_c6~6bJjb4lIiG0B zl|;=)NXH4z9+-31YQ98_5*X8W_|yIA0!p8VjbkMF@I4xKsM+JO$yz^T{UJ#2st1C zFn(DM+TAfPxo0>99EH>0^%Y`>Ga|R&+qcyjdF+&^2;--g87$0elllO)es?80wt6BQ{5m8({oJ$eoW?g zC0=8%@;JkIR^`KTBDT%l@Un~@ysFhByfycGKePhVHW+>s7S)(U&yP-{I*sDm$tNu6 z>$R=U{Ez>?b^ycs-`Zgw2L%*3ee9uc{Wpw?g!rGgbN?N&Hghrd_|J4T^ZzdX`;J~AA+B&`Fsg|eAeU-kP)f8Lp-E`Q(dZ(fehwl9<&;!jc}H#i5{XxdN-`lID}tRP z0j;kK|27?dZ;^L;cw1B6BuCXA)dI>Ak5EvT2HbVpEQ7xMr3_}8ZO?1uE%%xLa~k4v zBJh9zy>ZyT?H)N>65M=$$OdA*?dYq2Z8e5BM|g{9d+5+7@y)vp!&VU6j9#C+DGp&^ zsUy~i;#zk2uh|A@vhW>*BVxG@O2y<~#&~W0S{)r1)(W`3Y?Y!;q^X}m8%8Lpffz#A z5`fi4MR@8OsxN+4vVVf*VV`rk=1A&JeggMecoRtx`If@?t&Np^iv zCJEv^o){!@uX@7M-F)BCt2(;3yBAX<9Wn@*4t+J)&D&e8u&}?)uSRmA^~X|uVVSki zGBBrHa~hoz+_20P5-u`?VhkUaZ)w?N)IfBi`8LARuS+#pM`r$WihN_vOP^k@RQbkz z2|(Pd_`ax&CL3R(IWp1>vP$-TP0{&+K_1+Dw2oA<3&-2Qq<6Gwb3s9Ki>}!rfQZR0 z_2a$Tft5^1&#V9N!ayYg_&%Vf*y9$=yh!(~ME^06x``>~j(>aT)~FA1@LeAWO<*Ngto#vPTvE! z>*65(?(qWBr79G`HW8!GAJlBCV}QcX73N?^k}+&xMxAKBH|cd8Jg~jd(hq%tcnj)I zoHz5)u;2PrXH}-2O_M$&!vUc#^5CtvPSA>B4#RlBd5^;HIJjjL zdg*Hq{ILe-b36q24;!rY0{>oVq^HT6NS zUcHo<>5bldedzfdOiKN!jqB}6=*V-JNUK1YV$UOoI;S4KxA%thR}MpRrfZuNz!dub z_4SouarNBV4DPOjx41h)ad(&E?pEB(;O;|lEiT2OP^35oiWYY*r4))4DfSKYJ*Urk z&bhw%F_WES?X|LV&AyYYl{;Z-oMSde`XhcX$YKKGnQ4S{EKpx74l>hhzNw8skWHlO zc-A+0IV8#2-wZoRiLF+c(sFjqc=qTDyGq$r4zJ+RcTq}$M~m{*i`CJmi1WRYGS~i^ zgVK^}JYHFdGv|yNhEQbozKWYeBbWwLL)41`JF~4zP%9pO>Wv-P=RJkxdZx@cP=Di@ zMNWvI-*#1ip9;-ad?~9qg~_F*su#ms1Y4KN!Z4l=3p;OVN>;u*wcD_Zd$m}bV(sw; zE~k>kW@aOujKiNq0=x6kA!fFBsM#1>6-fpmV-c{TTJ7Xs2lfPCqmmFte!g+?3vDlK z59B?WB(_h(eEus43>;odP1#UXs_P%fTXpE&5g7V(WjYG9TT$1@sW8QK*r)^ER^Z`B!lon|94V+a+<#*){37x{&_uR=(B@ z@QI)T&$zR4N1@s|*`$`2z%f_oYCNYH7lUq67PXUC_ym^$emOQHD$&wgfMI;zdu+>F z@k-pChjzv{r_GEjE6$K!_Sfg#CYTdjCSt}|U-_s&b-j3QbN=vCG6~Mfdm-Wq3%zT- zVI9pAw`g}?*3_Oibbgxwl@ecwRUNAk;Ak}TBmj0zGxspx)Ne|Zf6e%ab0FX$%G*d1 z&n`{|sSctBfG>C>W+bGrz9bbJU>)WNz1pkiN1evM|1dF2wZh-Z)$Xcdn#+ALJ)=4l zc!`pzgnC$A-Qp1vdz?es63vV{|u=tbWkbKgQnb?GCp6_(ZgW@~_Ty87z zaXse4c68b2^wNTFZp&VX!ygJc8ZULXm_1_}-0@?-J_gGS=M^N+ z!K4=%a9iM?{dw6$sQw!_wF7zmXn3L&xoKsr7yZV>s=dQ(Hwis*vBHH&mb5uPbWl~g z^Cn}9TxUiXEg~BRsqUk2;QQ365$7QGvZ5obEhMH~Wl)Q- z5~GS@M#LN-;ADNQUfkw2Hq#G?eeaLVQm}_)iRBAc4A(Y@*zqoJK(C(9^i`r7H|VaGA=UeLsdt7-+Pr4!*t|Em>5W z=7T$&At>Lf%nCc2TF@M>SRwZ6Fdeu^6U-R~XA0U@kY%)v@6i&S0#STpK{GYMP*##_ z)ULEJK+#~Bn6RFNbj4Dz5Xb$vCqu-S;!Q&X)d#l*FUlFxkHD#S0I>MO4GH@b zBNyMktu97A%3LN`#-=n?FhXP`lDtNy?F7Bw%|;C2TX&*tsVEy6rR02HSi5#%&)q<^ zhrL*;Ed9QMoe17sYojHByB>`!ZIuTsl{SwB?^c!mqd*slx!WdxAU!t_EYg)kVHhwr zDlrfhe9`H5vYxwcY8fBtPkKu)SvhitX#uXSyQggTBO-X<{jrn`bu3L-q#u3gKE<(! zeTjBv{^(bl$ool&9rvB968y8YqOdFYi)v(bM31`sB*3+)wNaK+gI2l7!V* zHl2yJ=q$xK)mVH|)WDp#Sq>XmdzQTH6&-!Jx?2j3iM%o{g(8u$!k>9-E2mH;85@}@ zCZS%X`T6f3S=RbJgCq`23Mf~P(a5bo_{ADBWToPtO%I0*WGxx0QL@w!>s_wbG(ujX z5I(Lk0r(oL73!b-O3>tMc`N{Gpude51{6r|fKNcm|KB@4`0xWM>mCYFUX!vM*e}ZD zLigL5+fE}Y&qsEmH%Tq)GicCO^s7ugboIsVC>qTh@p~M6M>5#jJw7%R35*Q9wbaAe z!*o~Ydf^H;;Z3gOu9NB^;tGEKdW!TzLQ)iA6h{pG5h~i{@NlB2(D=|btgEkP5gAyJ zDlEoT#Fa>6ZadIq2hEUrvmU7VEt}Jr8l^U1jUDs>X_H_-vP<-v19c5S(0xb{>YJwA ziNwqa>qf328zqYv6&&&pxvW=DV{rP=+>fC3J-!Lf0!s7DLLCcE33&p6Adm@KqH z=H`rN)d_2{KRSJ@-g zW1TkO=D<6M_W8a3&h(F@kGkWQyy`IS3U= zvy$s7AV7ew-mou5xE_pRH6)I@!Cm&H_c#p%h)&0EUq;AQDZIw0EaEI2zw5_{l+S8a zN%$T;Y6sYw(&f+~B%-DMEnUJp9<@p^;vO|1Cg@>PjA^}VOKYG!&`2`ATcSqzGV5FT zS$&MMg>ZdkDSCli2?|2_lmF!fvvjNg{k-C+6&jvc~h zei?%_s~;TpHUkB3jIrZVblDqP>KmF)WKHilkKf|-U;DDJTnzeI+R6^DVb@WEIJmyc z{C34J4ZIYf5jmnm7<+pJ-q=sSJ$U;t{42F-k;7+!xQK5}G^W zW_OxdBE}}LaI1f#?^6+?hyX?w62M@mKWb-*i3m&^=-hF1S&O|>pY!*l2=6@O5kixN zuC?i11i~GPk{)bhWRS*@>UTLEvlF_l>7hk*#(sNtFi@C(4qcTxSDE-C?)3sBh;?^% z$u}ZylS_EWrWLW!w9rGC>vZh{XW%$0Tfh5Vv982AE`ZmP^Xh>&c^CXWS%UED-X@v$ zWSZ*yi|5+}OiK+k?m~XxpnQYMj3j9Knaa28VGj8Og9?QFZqncTbO~e{wa}zu5zh-) z7bu7#$$R7|ux`K`=XASzt`t84tAdPw(DgEG&bLvRveq2jLc32Pt0r3lr33CAOTGF4 z;a5q*Rjei2P9!N{b~UTaHJKZXul~!moG;`*gj7Kn?OYZZxXAf;Z(<$}b8f2j@TYruc16mZEe0l!ZX4AuvVIYT$bo6hfnyNp)A? z!Fco6(!=2$QWD0`F?nq_Dr0oJ!fHv(#Ns%q)riv6NGiPwP~t>e$Aw=?>2)|^51FE5 zNjBDpzaFOPaLDhu59?63N?LP#=jB-89c)u8#(cuzDr<^vQyJ9>caG3Ssu*4fySK}# zwVt~AjeZ_5SN+|yywD64R~Mm?5e3uz0{q&U_=mToM-Hjht`d1$a=j8>n)KM?w^;pfLc5Nber3k}75giuj!O7Kuk{7u9IxtAx6 z%=S{?k7*;-`i`N6t=X9lUA}3+#M;>%cZm8bqtjZxoqhSM>GLmaRc0<)xJ{B|tVfRO zaqQzrAi&4`&GiwI8nBNqksj09TIv=pEnfl)fK5SN6oJi!S>@1IM7G(gUM(`G0#~M< ze`7~*$kl&znXa$!U~E6&=WJ;k^IeNvec?tVV`baeU4V+tS;`10OEB#??~Sf0Jkd6h zOL%14S8d)b3kIvNv;5(6BhZD@>DX78CB5ZIDIW(1`id=?#2xLE;fV**eNrQJu&n?JDs4~F6rcy#7b zHs+04OGixT>7-{U6d?@3%hv_z;=j>V9KEH$5=qe|B(Vt@+mRm}sljPk!$&^bc5ZwO z(MX`VfNlvp!X|0UTh`8npK99&`{;U1r+K%IFr&k+NIiZ(~py}(sr2n;Wp^0%{<)^C_6+9SxzZdm1UZTfmU zqwn5x=2>*jK2Lv~jOJC8EiyXhScwYzp3r<3J*>oZ0^~iDqxxkyjNdDvzfHo*wBKE& z#Zf`xT~<)U(y-plK)Ztp{!yj#osxRKw*U+Hd+gX&yP`(ilZR%ejk2wW>S(A2QfR;9 zmKEy5gCB=~T}&m#ucg18x?ohu5~_RNEa`3i-Bc$*r(sq@D0@@M7}d(PBs$QQPpjUp znqFr&6@XvCQwYPWZ|@HqSAIABVa1};5}7Z~KOVzO$3ikxgmLr)yzh?Q79N#X$|-+& zwB%d2KE5W8j}+Rk$d~Wr&Rj$~e>KOuCXbC|MogYX#B+9gPj!K%jK=@PuZt+c_)MUc zW{D;GEzM-wBK)At7awl+xLz6&bN9|U+=L0Bn)#F2Kt3lV-M zB3_n6?%3y4vG&|!Brh3TDvmOQR%?qtA^qy(t%NV zYMpN#9Nmk~1~W7z#|d$cw%@oM6~xa?Fci=?z{(7OWk9MS`0h*%mri`+GC^*KFcqd< zuJ?ICF%ibCP6MrMx5AF}-91j*ddM3p`SZ+QBw8m(om2s2l~?yvAY?~Yt&=U|)=-gk z!qh7hMB3}!ROB%R!XNjz6P#lv8?%HlsKmapKk6M8E50ix2Sh6m0jboegLU-p88t-EAYF+EU!28`{s=%Dzp6(DT5mu= zOW#^N`rhfU`s=+Wi{U&j*`fo%QNHcq*t@{WOB4BEqPU+A5|Eu&vMCL4!F5 z{|b=+%cZjc)(Sos8s*?#4#PbxI(oCC5sdq(dX(8(Ra6v_Mf27CYOOVQV`k3>(x?J9 zR098*CYM-U3Pqyb>El_((U&DB%+TrPTX!LU z=yWqOIXj3mr()|HCN|zx4Qo}nc^1)oH91YMqI^Rn2Ia7kq5v$;=z@P4t zuRfCYZm$%?n127H9d4sGo4As%xI_(}_8}F(fr;k)ke(pqP$@s^IbVQ_CmmWi-pp>%B#S>m545TCv8Pbg>k9|<$Neq zo+>{=<-y2EKijdImo}cB;Tq1TcREm{#Hfa$hazSC6H*cy3hhbPn1lPpZgdbX*T-LR zGz|8=!?=frG42M2*5@;OezbUb@O=XuX@n6y)!IVYem+S&>L15ytgPJEkc{Yak@qtZ zS;kX%rVI7UjG9TzewmR@-$pr&Z6rv4W$`VsNe-3^Y@lf0$2Z)DC#Q4`S{d5Ibm_bdt6%R73YlTE|MLrUrfyc?_B$*^5H+%Wy`K6Q*LzSqA%J2V% zN@9*tZDwdhgNBAuQ8EI16|=il$C=x}r!3I|l?T9Is096mO3)KjV)DJQ&@qH^{i*Q$ zht>}W&M{baTL$62Ua!1Edb1|EDFIVFdXZ`)RFnIOZ8*DAh?&c&$~>A$Apx?w1YSpE zh+b8ez?J3Qra4#Nt^?$BCAHq}4xKt3cb42te z{t2t*9H-6v*-_iZnwUk+tLamx;;_1+UB`Oh93fk!yJPCaM69o?!T5UmfV}}}Ma=s} z!mC%tL@AI>!XPu31ZXdS&2EjmsD>CzDz8eb4UI{w8m{kPy4z{ijF0UG#b7Rsx!70 z{T@uDx;$THc62$W`q5(t)8u(iEdT`^I3vf1TV+}e7r+5tcO2dQ=>3t-1W9!c45yb{ zf`sQ-r#{BE^5f7^u)V8#BoR=}PVCW`cfHEQUYwsgz8rdUx?v*x+a9^7`}HeRnJyDW zPl4Z<&N)A+KF(rOfrBjZUE5`S@_nm5o}qbv>qYjV_yqfr!csUZc{a`wqsP)+#w!t& zv`cg}i6BAPF%w!X%iX~E+(42;56nosEWFd5X3{E2glzC}Y1{;fVr&68*b;%=l2X4a ziRpM9F6a?l*W9__$7A6@vJ4DaWNN8qQ%%-8m~JF z(e)Zx&Gs0lNLSL{xeZCuP0T!+6`F7B*E`OzxAw^X`!4gJAGXP*5EqB>3c(&n7gGS- z$aT?rcA+HpV);D#Dvp@bL)tJ4Jw+{L#AiVsI-I%wRK(dJYFbOsO=7I(KCQb&?UI>! zCz(G}+pJ@mFt$=!v7WtS;1%||dhI!GeSP)p?gjyEu7kQ6aiK==%5*nlvhi=8i(uf5 zRIsN0Xi>PU9e23Lxv?L28n_voY^5N64s&jF^yB{{Ql z$b6mTFJYCHj&HnnQo`hbz2$lT1+Zo6$Asd0FrXR}B{W+iIm< z63D!21Oa4$Wwcqap@6~Aic4`KV<<3&Y=mSd+fbngj;^mU zTzLjh_SIID<872(ObxVPC5@_gaX)cG2%{U@MzLQE0vV$~My83pDqp9ih|`PIx(PB0 z3N`oQ1j%!Ga3PHhX1+<$%G_q#Cogo@f4aNaD{NWOnA#W9+NgtjE3(5rukHUprj7BU zOV8yO1Xrf29|?Wu zOVqesvAd0W?;=@siBfyoGt($ox-N49_HQn;gt}-gBXgbFR#YQ-BcX!1&QW)98q~rS9FYLT2K@w03I?=}_1ILpLPl`8TY}(8}b1`bF8muwn*poH{aq&5!hpu>w`BcsV%$R+r0cLk$ zc1TiOpDl>Mbkpfv#UjGH@3LV;^YDIB-E1vtNcxx|%^V^1S;&JRXOg%eFSN+ci63+oD<@)ghAr# z9_o8D@2`e}BrEdUAEbqJ^RZi%iklfF#T zY{jpaRwVEm8;_UTl6uL*c-@QlNIn&yxCyAFTm!SQL8<&q4(yULVlQkx$y}-5sceuS zoS$LlXDFrQ4cQTG1tH?SGBuI?^4VX~0O}|Ur6@GW&gwl|DZ$;|hqR#7v*DG&C{k<6 zbX!llf}{D*DKe$e$eS~kS1b z%C^#zZUp4(c4k+hqq63lTBG$si%BiBb`O*Gn77Ye6vM{9zvfu`!Sk&}%zQRLzvhuQ z{Zbb92MQBp8^5Xt)Af$SQetPtWC!@J3)Batbo9qu8BlY23*+ zlz(l*`x5s!Z{!u2txJS;698TzVz;8NlG8cB7vlNM#l~!LfHnE(K&+AUj*(c)Fo{1R zz;2WmA5h^_@)nG*&p_RmDvE{3$sn-l7a!Hh4IYTZ2b@|xWU@+MGmj2e5VdXYC$fgj z8s3I8T4!-FenPK0u@9qX_|_}L^e>_{O;QrhEdlzY>`W8~sI*C@5qO9OIu-#0rije|>+bofik!vDj1B6yWS~ zRp%lxdH-5qW5NQtv3z5SbEMyAht~EuE952P+baK&!N@>%2Gf`61vPxgD}vY!sSsg= z<*J1%vW=l-9YHyxb#ZS3+$x`F57kLyTJb&g{!P`Wcmx%z?IQ_Ozv$qceXBAdidPlP!ii3 zX`+o(^G<&8uk*sn2 z>}6k4QBdk9iaf+9Y^26x<>G`YZiCa{Do)6ZJH)rXeB#6qxI@K{Z3O4qG7!FS7ss)XF%P3pYVvW3p9wlRxtNPeo6tQQti<*!ga|N9Lq;Y-3b z2i*3;H;mInNv0na8RW1i^E~mk3%6JARFqbescpaUp!rbJEHP!^Hi6+Wj>o}Xqij2- zUkT~3JHuq|=Bw=6>OD`_?`r5cbABmoiX!>21giH*HJPOr=$4x8f5N@zmkf~nv-lc|L&-T9VAd8DKz-GQX`5r?%DMe@x}A;1kVw<<}YPj zf)#coN?!M?7`98LZT!3Za32sf4@1Knuvp8t1?I=VjhgGSiK@fk&vI@S;V1*S->nGt zM}o}74;16s#jC2gGM4$WADS91>Gfb64_UAQjjPPiFE2VWKw~E(G!7a`aFuuz8pFg3 z3(29U{KEmx=4R#S-jO_k+RK3+`7`9Fn%nzTy7H)8BAkvG5wUL#qOHv(6>nd?5{E~a z$}UR^3;2lDpl=dsY{=lUR~=z!P4x-*(z9jCMaYpJ4V!FAXF*UA=-gk&HdHj5=NGph zwLIP^hd&BjBEHjLu_~c;bnHXPSlv?QkHXgR5qu{Aewrx&L`HwSP+<`dflfby#e^senTO7?6b?u(EbBQBb_Vvml0o!NTBj zU+?I8m4saynyA@4Bi_T0keeS!PCcN*G%M`p1)?y#c zDo0I&*!uu8PQ$ae-3e=)DDfq(_`LB&-ptJhEn0`xqq}clPnuZ(%wwlv13?DfZjSci zli>FD2NzLWE2k5S*=+s`2(>*S{C3v{=~Ek@9E|^JV<(j5UVU1UUnZ9VG1R#I2oP69 zW8GrK!kzU#-CQYu90(xICvTN8WQg zUAc`JQ4uos9pwt@Oe0)vMs=RgCB;Ni_1p;0G3aA{ak*iZqR()uX2jj`;B9s}VL_aj z_zB8N3E^*-SMMTkRG1xNDVd$u7NC3Xp+WiZzn-gTJ=y%Up!$ zXAR>KV0f(#*H<6_9=yCCHUlR|mbQjs{?iGKV@%ipl=_+0-V6YgBe~Jll??zktH9P5 zkeP+uQtMY}cgcSNF{(;%T9j-WZFJc$#CMP367?gDOHqi!9!j29i2NVK#I1)N=+UPE2IDd{uO zZJ|nxIc$3Q7WoRp@?Z_%+=@2%jgHUJ%Wvd~tyyi>fWKS>S&2i*TUoA^1D zPN^C~-&u9oXLi6bm%r<=o)qG0;V|h+W2V$PZOO5wg@%02z9B3bxx8sx8{r~MN4zaF zg1oT`aewJw*Df_DYtnp2@#=0Q7jE+)X-K+$MXa0au*5{d1pB33S5Fh&8O8!{TCFf; z_yx_;hxT+?ddMwEb(vxY0Uq4$at#6K5nx7ZdVQjWb_@$Vv~yq}LqRmqx1G72^AE_F zLZ29ZxGIn}2JLlFjp0kBVXeakKJ{nvnsm`Osd3m0kd#u=0V3DKzH^jfv~_9K+t3hH z0{##@>v4X5etK^AOl%;kBz}4M0l!6`qlmd>R%B4H)5>AgySS#;v`ehmv7c#^x5okA4+97f26xeTx@D(|M+~T2 zv3?f*x*Le(3jqn`!fQ0aa4DviO1N>$a`F~A-R3gN)}XJ&bd| z0&NP>-*P0w5lzRFt;@bW(-^Y{mS}3rTsMdO9IR)?No$+d*53`M9b`zY|KZPxI8e+G z`b@JHzQTII@;*hfiPfQ*hgF3=9529&aN_YD3aJXhZj|%T1)x-i?Ww3hpQ2@Bg(o`z z?BOXXxx7hvQB0+)9)LEyO6Zu9((ie5QF^E&h##Od-u5xaUA}9j>cvv9=kzz&5)^S9 zTj#JDD7&{#)fG^BoSRkGi3k513?}R7XlxFDDk<8;9FJ)yJP|^QS1LcklHa;o9Qk^P zIU5Qld4F?#%(Y7s=?cgFFkg^O7)u>2cmnGzvet;C8Ny`x+#G+h0_yV&` zJ_g)DQSAoCJRj+=C>G@@{K9#Z%6dhWaMTGYs&`s09{Wv94USpQr!e_lSwFK{11jJm z%5g*cOlmM!FgCv9<2L)Q)_PntT)CDus$J5TIdx{*cX@2*>OD2p4I&(o6h7CKL1B-) z@8}U_B>|HSO=q+`5TYlok!7UL_3&*?H2WtPCeindEt9Qh<8snmFY>>5a8l>NSmoc` znxw8nG561b8~|8WC{gqOKH3Sw;G+)Eg82DRko`Tr2L=WUD){%~iv+p#p(gu#!U+rv z@NX$J1wn;0`LK}v&*MJ+Sz`?S@$e7mU9ot!s6gT{C#Q3{&Ky;z(C`i|M6KP zfpqv%lKq=#`frUaa)^L09b`Qa2l-JW&W3{6__bEJQZwkBT)#NDr8v?CFHgXaEWD`y(c50XZQdgsAypKQ#*57ScmZ1i|#f=K6P-`QPUuX7_&woj>*=+uzXL ze`{rPd=j&O(t&%pvp@atK}Fc`J>36U;O^n;XvGIf2D1@J`~0)O;+5koH}^*oe73)F zP5;*7>H9xq9+mMwX=w`jXTg&e{wFQr;r}f7qvcTqpY5;b_upEeOi7Q_=KpL9=t;|R z{67nxw1A$pRHyv2;E$F^5qz@$xoH0PF+)kzA<#bu6WQaCei@oS34QTB|7SUjb3UZY zj}-dvF$o}nocRG^V+tSz^t2G$0BneqKM=OG5Mt`j3GoR4!ZyE!CW#CzZ_=|zW){`ao4#n4;wLXx4_AHwr$(CZ5t=^Jm2@8bE?iiyLa`fy{o!= z^}2rRy07~<0Cd0)1WQ2%6buar0tgBS2#6R+?JumsAutfoK5PvZ2?!u@?DrZYlGqdY zD4jqNHXnI&r2PYS=!3R zNE!m79QaNY%mW>?ZD+>CDw><8$EEW!%9sR>QEjru+$AsI*&~SfjiV zwErg(Z1tDCm6M|h)5PkKtJ(4F)m1#sC`?AH#^Sa zai8_uhJvL|YZ{2!!cSUUh52+Q2%t^)Ga^Q+{AoEOGB5#9Z9SLh_3Bg3plh)7WOzN( zE!7*668mmk?xeq5tvE=Ah|f#7q6{KNZ}zYq@p>~;_n-!g@dPrM{`bJ${|r>)xf{33 z6W^NsAmilkFG8-a$P~ly6UE33?iT5rXNi?q9Vvsj7`N`mGZ^E|WB3A&pVmaH`vpc0 z3ggS4kaYJw30gtw%3vsg0p&_^GX0E59k8FljIL=e=*TNh3?%2OXNXWE^;By=h*`Yv zw{WRjbu|`c7(i`<+^;5vT%Onvc0o}edT5HnP{2G;t*>~%Z71#~K%stJR1o+{fTNx&{7zeUaJD*%R^ULM0suRkV>7GO7CVH7Aq|ka zi~x+Ea+j&_3@|a9ZO^m`6{n8X=3@3b&@Vye;Da@3Ru|E-7wv6JQ+As@dtDBw8Wg4G zKZw#&6LV_~vq2SPjUBM@$k-dC$69uI74#d>!Y?AR5+6angh3)>FXd<`nUJf{R;fSB zFXdwsBuzJRkpKu`5t+M6wmVHe7HMT_lI!q$oG`^%UkSULF(A^5(oZ2I5!cDdvbmI} z%rzx4C*72X29`@o&`y+8<)}GYzw$caFG9g`nxvT%Fr$qX$mtKZZc+~!6^5^) zOUnSaEpE>>D%nseaPGrKD9?Z!j!80!7M?kZABrfC*wv1N6=P=Ru@D=5(o$lC|9g2j%OB zd@4764{`yDT<*Lt>FVm7TVRKk%aTQ33dIhv8x%nxg<*zWv2bi|s+N`oFVCl`%i-G8 z&dVRoZis?ke$k;;TwpOpBt~9*Kg#xPTqOl9Mp?9=qKsi8CaCrfIBK=?REP7zPR9O@}_?y5oG6c z9pHuIPx^Ogt!Uy}XI#lILG)fsZnNDZ(4>8gT>$toIw0-W=5GjEmZ2ma1_c<*A*8CV z>U-Mual*3%h%it9f8G$vw=Q0y>X;8a)d=Y~|JW=v0MT#O13wSD{kTMfGf*`*Jr1)Y zJTJOt&16&ml~0|D!;UjalYmP$gT_HSfQ%RMbhGVN!_Dl#)$;w}{m0rtQLS9?Mcs|{ z48WdlC05CorY&^d-#siENfF2|lft^{1D=>woZz(P%d_(QSFs9&M`6*l6u&vv&y-5_ z)wp6Rbs>m3{J?89@`zSdXhs zM6IzSbz%`fjVG zh@^wpG0K8Ql?Wmj_M{E@*zvZnK6sP5N3-cFi$C=IB97(=$HXOuY&R8jCLCzy`lY=C z>L#BiM7?rC;{$8FG!x_n7-mMi1&S%njTfe=isi|XVTCj|GQ5!(c(Qx779dK5>4^SaiN!&*Etv4hfFzB6+ubZ0$9a zm+sdjj*Vp*wY}o>`_l`8htTy#3x*t9?TUvh%dUx@^4gc#1;)V|unQel>SJuh9D)O8 ztFwjg5mM;W>cr@>CE;QV;T2*!vWEy{yNZL6c4mPf;$KbRtWt0Ma}}k4U8EZjzq6jQJpxj8gR$di7!U^Xc=h)P$ zQ|ob1ri9H&LbVWjSrB@d>;kIiZ$OUg!sqJI8{fF*mub%xqU#p&E)XuGA`y-oa%{mjV?F;-$k z;f46b$CI35SlC0^gUumGu=DX{yvF429r5|*)aa01PWi$2Auo}|J;jnF6S~>ye)n|M)$Ppb65X_^2w^n#5SM~c zgzB?$Id#_~uV_8VHwPw zm$j^2VnEjc#9TkPfYQzU&f2IJ3>xO1l_}`BxvpnfXb6~cdL4}$JLgl#~URK+6wY?uQRE=7+i0kmz7X$hc z7;}DUO|Ca2TsSc!AK-9Ex|I*0ZPH=e#sm=S%TY(^`M8Vx$hj&)o#=0Xn`SVW&Q5i? zf5-D^)LA6&G(9NnQNf|&{2}QF(ck(z&=WeiET&&*XK0dzgk{N-46%yEX~0~jO-9iV*-Hvw>pi_%rUVLr$3ARLTn@zBS3pTKaq!y9tx`c z$O_`fZgb};E!Bw0ag68^4LF*xB)3Fn5=>hfkyAbbgWHO-afK`^V3ELXnJ5#cg>)H@ z@>;}sRjR8BV+R7cR`4KxcEZ5E%jruGnSfeE(c-QQvOe~_CJ{{E$d9~I+yh_>9j}f@ zYUGc|MQ@^bdG~G;F6%m?=yfuMsNP6cpoJ=#?x*FwT)ZXjGO4@W7 z@Q$xnT6A#Ghhv2O{;<|&8^66EI$@4}%>^>0K2?$KuP<4~M=DN(zbxY(uXW?~a=06L z=Srb=Kb5U5mJbLxf9}SEy9ZQWn-7>@30bp}&%39z7-kxWo+T7#w4|$bW6Ob)Iy)<) z=0cuQ?{d{p2%A8AW0@Nfl+Q<%N0htKD7EYCDs93P*pP>AHm6f}v8JN7nf3tj&!gu6 zA*P<$`R*sHfsN-cu%O`4tAiNaX+v!~5Ld-&XwO~sv&BF9WbsNeYykEu8@wxx#nzL{ zO2ytTcRrTU=l7qkAUAW)nR&@6Meq}Ury5P7$n}`aw!30$EVe}mjc}D+A0T2?gCTdw z8Wm-J3|GwVc^`OMppXeMJ>$M5-?Hw7`8tbjjrozm?y^YsW|B>X6<%vY*G}KG=xQu#63pLWrs{5lb=z=(MHKzFkg{F zzmrK%O-s)x2Y4sEnGF*-4I_IP9wRioriCM`5nx@ih@0%qNjlJEueNiWjpT-< ziDPj+p~drXkA0=MKtGq$5j9N6P@&c7|FB{9N8r53K!Z1$%>@KR9mCAi#^DEmz{eao zA;FxFpD0}KRUv{y{$M(`z1ew!0so-^2+Y|o-qx3)1Type9t9Ai8OIRARToh5W5Q%Z z4CnEF_(^6na*z8nK!N!t4I<^pht@)Vkxa(j&)4!X2WVyjFm6PuB!LAcyH^lye0!&Q z9f7JvzJ_Ju0OQe5rJT?y_^(5Hc!iqvNz^6e zTTc{`O|v9q41N)-bUTHi;ZVj*zujVSnarjd<5O0)@o>L(FpCG_vw{QNYpY&(@@l2h zlcAk7Qb7fWS-!gA7|g=u$k6HuP5pZ;4Tl;~piQ>Vw>xbGt+VhFYrC@*$4L2uiFo>} zI4~s`0c4L*=P0mjSE+rAC`t&mKENUmmM2*T%POtsCBRF;2K3LeTE?>4A9TG=(31Y( z6j+~AZdg@Fo`%n^ngdd&RJRW>-5;X__wi?f1tqUa(^)_$WYrF)%0htFNj}q{`(|uF z?%jAcx9EJV0yTZk0h{C3;xugTnQU>wOb={CM2n35buL;XGu!L*Vj~U+n39X4mQrM4 z${I&XHVLHaDS{6(Q@vbvJZYu%S}%}q$JHZ#qx#PV)z8Ql=Ra&X&Sb-WI=*IUTn8J4 zRkcLhc_6MEuzUG2dUb8^u@4t4zHMv(dS6csUzIn`&imVs$7f*(yBp9d=e{1nx8l8P z=Pldn&cVJJ;IAZN)r}7VBY`F5SJXBLzSb|E^V4{&NUNb5nJ$mW1K2@~DhyMDx>y3Y zsKF-&JMo2J{KqtB%VM6X*AvDv;^Hd_7N~qiyd!rEKk=2ps!kjvxG%UPK!P0r0YSop zLb>uunQl|**T?W-Z|T)L&a5AWy@|*hOapsPVBEfzDhqY2|NT1=vn!!wtLIHg6=?Xv z3)x0$#eLzA{N`k#DOmQk`a_n9p2Kb3H^hdd|C$}~ zSY1f*5n0&rKf7S!F$zxVlCx<*>b?q)fa_$+zJ-0P6Dgji7(M>86DD4(1SuXRf2OW4 z7YP^uF2cHq0t*C0&jJL5^NtDw88p7jXGRJf7~RA@K^RjNqB^DIX7Oalo!kbltq;WRntajxw*WBxkQpS!GW> z`U5Uav`ZW!DIq)A8VsXH2d{t!)8{JypVw%Rzb>1;z|_{5vpvhZ>UmJt#^;Ca65+w) z+hql1DX@md)$br%)rJ*x-rc4W$)Vo`dd z)b0*EG_;#n^?v1fxogsgy*b<%sg{?m4mY}GsdodO8rRPe7S+OK#w!4aYgYp7Sr`YF zpg%h4wvraA44gPM=qmZUD#tF~*LZlJex^)fLayy3CB7^;)X=#e$o%zbQIxCy7=NK8 z^etFBJ0j=xb$v6?ZeNGHnqN@<9h|pzww?V&8y=1S>aH-+^@naVTuha>j}snp^J{DL zwhhudNTwIyJpXzra{UFc=5eFfI~3R~10)iDQ6^T|qGK^#^M2M;W&$=a+rXbu$I0xl zY3W8?oB7^(H0VD1fdJ!xMGifFbz6?U^{H_EO*V(gSrW z(FMR0;D`QFFs^1sfduNgXxtQ_z5*ax%=sJ&3~u%wU0?K9f*9*8wc*qH|)Vm zT86!X<2P~`aSm)xHpal44I4n~RsyLRZECD6-WX(1tHjs{IUGyZb?rls)ac!)%a6#L zTEiA$15a#CZUpf3!CSe7MLY&EwDPQZFdtlGZe#rJMMxyk_}&ZJD!BaWW7lHK z$2}}wH<&6Vb^glc-J%;^=z^||u*V)S(KE!}i_a(3EH&LVHnIW!Jb|=0dsC9~HRKrr zR~t_ue6k+8H}v@u`e!HBi&*YfMLSS2!Ips-Z%ixKk{N&moL?7qvQFBw+z(Af>_^B? zFJF)}9@$|T?EBzwUb3%N_xDkfQ8Ui8q~_&D#7m-MR;GWjRxK${J;A9`EYL7O8r(q! zv`EzBWNsPK@*EXh-a;-KW3XTXX}0ZYHm#;SaQhg-Mr9IH2{!(~&82^R`?b8Z=H9OB z@JU$&wg}+F0=260$ntDLT+p1KHbDeL7LA*!O7Gt^VhsT4dtXD`1@=vC~}1j zsVOmw`+l+xS58_W>Wm3EdC$Qr2Z9}|^x(?4(?(^;;3dM8W(e*Dnrf($~G(Gb#X&*aUbmz5r8#4S<&;^P_cMk3p+)zGz$fi(*dWL zcJFnVXmnIXkJ0VJSc55aqE@F36*a6^^+(;kpZ$5!a89~V=STq>uK{z!=pF0TzMPqh zfW4YZ`rmmi7yb+H2F2#YYF6ZSXzB#zu7sZrj-5a1ih|w_yh=$=!Zj8!5JywRcLfYMvS&4U6HRo6Kvb5Z->c4D)>L6ChRtw~fTJ~ROoY^D!2qD2=cJAZlqfPr&(gULn5fS% zU}#hT5-Lm=RP(@FaJg(2L85_4U0@kMchV?hSq20M9 z%*W=j#>lkkzb}g}jG2`Bu;XYl+3>b$)gv^2n4G$gL6QsGh+rrT7DgJzNI?b^Y2hQW z#~0xvE&fb)79{KAbv7jVLnU%L=eXGldp*Z>L*PIeRUwnc1uf8kC*c{54Jg;qslMs% zslc_c8=QF5D}>AJDHWrFj$USgaHZzRWpReu*((8`BC)G2grgdmYVpF`mRm_H(8_Tj zbgl&{g7z1A@4Fmtaba$bA9N0PtL7)SOOdpKkMG28Dh9vLO{MBy#r`>-JIo5Fba$dA zEy4|Xq$~MW-xB!4)NH506+j%w17&q6I>izr1iJ5#PIkw|PHsnOtFo9G6yf7Eeag8b ztd-GC0DgZLm6a?TmpSB)x$6S~YHOe?F*hEXLx*UVEfhUnAttxueyJ3C<5XlLT|U-N z)vYuffn1I4q_Yd(L18*0EJ1h3KFcp~#jYiYZ9%RLgz8URZFR*=1BexGz@Tj?CYCUA z9!k&%m<><^qf?)G}BqZ8sDz)%>S5#rhWrlHRta&tK&wjwrA(-Zp;)^7SR zx=}r|*MmDML45Nm8r45}5w88`lqiMCCJC1r<)LuWO_d}$0K06kz9MW45m6inMPL=E zDI)B1Y!Z*1{d7>rgS{{qlCJKVy%D&3q7?S0GPCylWkHGT3@Y@x?b&Ha^-tvPTtKQ$ z&Q<=nnA6u09%jGI zVh9nI0_EGP}N-V>* zrd-_-7RdnY-D=YiJpX|2q)uEDmL!Sl_ec%R9ZiC;MQ1j+GZ2Lee?%qZ|7a{eba#)P zw+rVaxT})cY+r0dQbD#>g#&FjZ|pye9NmNJhrr+r&}!cpa}7?hPvXMN@>TYeH#CAs zwVHwEG*V#(_6x0TP`mFjkxIpi6$-z54t=TB*Zg&o34QLg13q<|0xc9AlL3>6Aix|x zt<1v(dh?O{D838g~m}d z*aZbCfR%LjS^`8}3L=mLH;&2|%dJmtO)cFJ9Hu?hw@f6HiaA`t&KVKJ+s&=2uistH2BF)U)}FtyiVusDocogUfsFoTIEzW2)7 zhqRW80K5N$m$G#i{TC!hFfv_}4Cf@0eBe49$3f%jWYWSkp%ZZL-P7B|Y*sRsbyZ@w z$J+~6x}n?Vq`>yNjH7BG3;IwzebX0Y-L$4CFrbv5Ur_4XIMc)XS0DM0w{2u@=@U^~a8SwZ&nph5$Y=DU7IED}#K!dFfN22Ll7GF@6QB`m z%BB}iv2rhybn6=E6Ltn>@~^S>w+-mbN63F%vtIMb%BU?kaXkRMUF`u%&zUhHY9Wka zMV}b3Un?t3TfB4>2Qc>T8@VW+*#TivTo39>jqx**2{h|O_M=*|hQE8<{K z5fV6z(ZGe+XQjQ$fIfi1;Y%$jrU*%=Fv45=88ljcGyXNj#6uq0#{`bCoea>uqHSt zfw)O?_Ef4Z44jy-QW~q+q_;+Lno@&1zuw&4T4Wpgb(&;2%LUTOZzralln&h(Q>N4 zuc|YKazIx_=>aOS^ZUYiPLNU~F+VAg|D^Fis(off#{~ED@QNYK#UoSG&K7 zMSNM$&0s8WAD$$Giqk51Da}unQvhY--k8Ek=sgMS!zvTOd#s2Qsh4RMe#s%7;y8|Fe zw@Q?@Wf{kTW1*umdt5a(hj7~>f1$wLrnNRO4a8HVmnN71Qv;~i`fBIzkX0A&W<*AV z)LxG$B8J4d`g4N05`@p3JeT|1^;jYf(Qnau)vnDBZJ{#ednoCJQs>eUb01g_Bs214 z(Y<7m{u>fS12w9rIu$1*x$K<^UAR+rUmvxe`I;IeX``)3Z=Cv&SE`H#L8 zf7cEIEo}R)gI=r6>|?<8gbw7Z^T?ulC7xNG^6&#RnXtGi_c}+%MS|%Y)x`R~x%aw= zdMoh_SkDrTiUL7zHP*1b{ne|TcbFD57K7uHx*fnuu__Rjw9VB$R@Mc~aA%$lfnWev zWEpL2AA=rE1q#W~$Lr+a*_@EkOEu`eUCtcB^auLDK1STXdp1dq0MkA0sldgK^2uk* z-x$Fh*|bBFU1f$((r=j4SrkIC1X8M@rW^QO$mc|ec?w3beW+U;G0q*upYG2zWTgEy z^G`rH=c{NtElBmCZ;_#nOVkLNioMc*SQR}8r3@v>vgQxsi#*bTw4cW34lbZ6z2 zuBw4bSA)ntq*~|84D$_T)Eq4hOq;KNC@(SA(j$ZlJ>6^R+Zsa zDr6>4Q+{&Ub$0vwHeW>4%3?F1UzDZ(PeI|-V|w3CwbiTbS>NSacv<-vtQv7 z6zj42;MT&y1kHBSTRH}%ja)DVIh2r>D^Io?=@wJoLX0VEjx4eR(Ja0_VUgm{8YW=c z3nb81YdIoYW=q5vdcuwBMdGA=o$?ceduf8kRHWb~L`xU3OOrN&sWpImbBhf;_2TLQ zHu?f&f3Tj|QO%~Rc_=0Ql>-0NCw%QT_fS}mgt!VRc#{8qfzRIy6o3&Rbmj-``@0Rp z6z^4a@aoT1RGFIid!sm>KZQAT-yi_<(eTHP<`CRD>a7-A$?CG2rgd5#48vw`W&g)K zB=wo68meeaH+70!*W*s*sRkCavl1Vi z$U3}8T0xbRitQsK+$q1Ghr`+~xK6d~#}%%JaK2*jOb?j2X)YQhYC$zH$0uNVOal=Z zq@xx zA;o4;#U+j2Tb@V){L;f@k9E7`d?9uC^)^w^=HhM!zZ}SnFO1>i^V7?V7(u6f-?_k{ zU+_)O=yR*mHssp@;{*Mghyj#Z0)lG@+j^eEbSERHzu?mu_@* zy^iTUI(a=1ZRo!fMc&rS&%rCDEgoM^9*eiBqgJ%OjPz{CnucIq20Gn*1c#}=8q7m; z$}|^M%zt>5dNV5sSY;e`LVi17ke>)&hP@$WMa#jTQWi{zJi67(t!x4?c(e#B3tzNu zk38Qp`}GA1^e^)jzp4p?pt;$%!Tqhl`2W%1`0FMNz`5rCCAm!hzvO1ff7h=5PsuHK z|CZc*$`#q<`V4;O7$~1MpvRjX?cA?C1KyqdL2dbjAU1Y!zj;x{efLkOP z>x+ky!#&Wb6*Kf7fedr!guL7_3*f)c_^lJ zZ{-r2fKu`I-)rgU<-ZN=$HG(`s*+$~!8XF-{r_;<-c+rH88Nwr6a9tN(ASK@ z%N7(jd#R3SPP5V`jq(nIN^9?K{1n9K-owPq4_L0NV7)A+)GH=Z`LMbc0rfQjlN-LB zZ9XQr`S3$_*(cCoK9sJdc9p1O();B-PwHwK{7$D=Qnc`L0bzvgb$32w7W?Iu>roH= z3?j5&b|g+uM4#V~sVPp1pDZI5@3HsE%jtRHb<{8YNnl+Ta3390L2&FJl!;Do!JLY# z0box>KII+XVEkFz?+i0Pt}8Dy9bxJhTiRX@H3R=Q%uVP#Nb4`fBd7f3{L#jMRo!a*e>%@e*sy@umd3JY>ZA0Kg&vVy^FKd2{r1kj~dx=KMv9T@C@{Bt~?Z zdsb#|{pZIeDx8#PMnCIhu2+DlHMuau$Sx&LO>}-5X|$k0Ki-KUp?g9G*nW?oW)qq~ z`m4X^IO1KfJ6g2HO}%ounN%Vn*{zU%0~eZy5Xw^pGd`Nd2d;H)luATs)!vYOrWZSbspOitih-%yR4O?x48$+~qoe;xUhc7?Qq8{lNs?vPKh#cac zipN?yKd=})`an5kSfd#hS`|QmG7~JRM+g=HfI*pRbjAQKR*mPg`;dhY)|pf==bbCZ z216*HGgJ&UkL2J8_lc)~d~2;@2_R5lk}2%L!n3KPxGt2!i;6Xmr?}6x=Dr}lGU#k5 zh8oEV&U>^6l4Sfn%_9UMR5CF7U3a3y77fQBBE3!%h@hgQ6enO@GQM7hL7>o0eHG$9 zw6@N`@x<<4#Zo}jsv6YGJnSxzAksNo?3ek)X(*1@BXqU|){geTI1^2911M#H9JsZV z3Mh2LeY6W)N=_8m{XmvLW4tBMWHvqnUuY7%Wh(>5_>0s7K4z2M|~#THRpO=B9&>1l8AFoaLJCZn1JFn$NR_Wp6D##;4Eu zPI$1r2Hv=;+PlKv-zUd`kX9UDXM+)6+ctrOx!&TlXu%(ev5cZ+K@hCpURt0u)_a0C zkTPDk`VK&~y5Ng0D#&2Q0pcRZGNi?(TPmtjoK<54bBkA;pVAga0oFfk+k7+6Znf+^ z=qVd{*{ovg>F`=$N-K(C+@6XotRKmC*aR&sxY3e<6Q> zg&jyIdsA{?e{FLk>Zp?JF465`(F(yHvo}^p1_m@fVxRvU)>bt-onW^dYHXysIi)L? z_DXK^!L6)Q5sOzo0bEs7ux)Gksk_>d3$0XmJK$5w%#%Z81BDRzsxqcIob8FtDF2qs zauH#jgg@o><#yQGMqiH}->|jv5YNA%7N-EkO7Rs=hePXKv=}5s|vboRD)6L`P9>#6sbS{$yPaAD!= z{2k)TikEkFdkb4h_0kpVtpqmYtES8~=Ps+SGOFKP#}lXRep-f>kg?INffasCoO|2- z*6S<6KqblL1285f2mioU;LUBq2IicU1c#txPH@KyDcl+gZSYwqXN?08RWaZF5USjlS0PMa1NG%iB%%*LfaB*2@r!x z^mk!Gfyx7}|PVC^e_?lHksit{JDyvM!Rvy!;H2X0jZ zOIWq+WMjZ!LrgSbpU~LVi9$cd!_#?0e^eeJsFDgf0Ss{n5-H}I3S;Zg>Fk(H(*3Y` z_R74x#J__hqH^E4k<<+{=Y#_4ep~eismW5DgtWi;3Ah#Xlu)%rG7xWen|lIka;ha4N?NI0F5;tmBzro*=rjicDUg#!4YUF0g^ zYtvni-Nzc>sT}v(I)f+fdNA1z&e;l`<|7n3ZAdZH!x621A*UYP zul3iU*0u?|6iT0b_geSmT$@F-Ps)O~kLI{PAf8MY`l9UDeHkF8$1zsK0zgV^ zYw=3*ZUxtMzL5R=PMDG5i^h=K z{G`}5KmpfdxOVDhfJI^81;N$AgKM9Eit;PPfb=H{?ek9HgbEcx8}b%#Y2?J}_ueNg zP&nHrdYC(=4Ahc^tEC-{>YZ6!1LPn|h?`|}%-z&&*EA<1=d`TFZRl@<7Y^XIuk3h( zc<>XAIauRouNF#niv2AZ%6POIM{LwLtSnw4U13nK!|qu+5K%|7E>*Q5-0-EX0@Q$U zLG{_8nfj_4RFQ@$Z2<2|Cea*8W?D$E(Maw?nbIa$U@-{U>Jnfdl*Q@g0vgCYGkgP0 zFL`i9&uC0#a#ME9>=H86XDwbf`WwIyPh}fHaCH;zF)$UvQ=!pcGj7tDyE?!&TgKRY zEfedzlzYjpuhc-pmTrTvOM=F8nM}ecL3?bVoY`S;`1yiUk&2yF{h9sfbs%HG=Z9Oq z@4|{hg&Xv+j%w0)tMpM4KuedSD{X4RROzn^JfZDytLY98@27?f{Zb)sa?LNtfp2x~ z=L@CV^bb9IZ{HWzBl@?U^;>gQePP(@SxRT5q+%pi088qv7r`ER_CH&9RQ(kqpcZ0O z4K|UpvfSG#OWtmk)$wdJq2Yq)D#ZDj^1EF~_Q-=fhL?RExb zu-z&3t+o2t=T@*S9)sqTGk`(S0Iw^_%dB)kXd(W6-f;#ofhTYY;VdVJ-%@gecggqT zG8&zac-9R)uLB`MR)YSK+rdzs`Eh!)5#u|_;jO5q)C7;}>NyAGjGe5sYF{{x)uzuIW1Xz7Hzcnr?6+({}i^wP%Z`p(ox-2mB7e)7A5agXqfsY#XHV_f0$EV|k*N zoq0dN@!UOLvV2;N21+##*q^d74#J7Wwm0ob{*) zFSI5j1p!IbetG+?usqg#b;_U!eYQg{OAhHYVV&^I=pKa9H&H0K5{a;w1;zRxbj|2y zkLLQ>t0-EOQhFtp;>cXtN1hapjxwA31In)bbpt(bhK@V$&NoJVgIT6!htltJCz=y7 z)KxVyV7<-LqQ;@f?=^M^uFlC;VXArHL8YdON;xUlg1QG~fHa8EGoZA^uI{ZJOzv@~ z2aHw)0V=9P6B<|y?S;cyZ(IA2%EztNIf4H)t-!Pq)MYY%=j)G<;J0ZcTi;_}4qrevzT?Adi5V0ek;K*$S}T z8XtptZ_ojnMQFZvX6X)90t8-h#{HnBxRpkWINQ_^lu!8GI~(d#-f+h2xZcz4Xbc=7 z%4{f0cS>OW5ewRWKz6{%%A#y_<7=|wDUS-=Kn)SQgo3Wgna;BSLp=jG-J8UT06BG9 zYT_YS-j}nW?vQt$Y}LTTLBGZ+U4LWxg+7J9bhvh7it2j1J{M#S0-*CnlajXe-G@5} z@Pn$BgVO(V?zFj4G}z&!-9b1?UgZ`y;&~JUx_duj&s>ODauD6<;5N<*UB{#V^)J%{4g~)@Gv} z_}kqYy-ww=5@lY+5|X$IZep0(h1PtK4hJ{p5pu!}HgyIZ=Ol}O^^lea)%?fhWqenM zkKR+^O}o(+YdoF#Af~xIGLBoMQ)gB)zNeAzBWT*-DBa%f{W{ z@mXQYg>Sup`Td;po}A;Ke}gIa4~0xq1E+*y&zRqghW0PR8z0>QUdN$Y0agbfngN4Z zB)qke`(`u@ym%S`Ji!0$gowqEJR}d7YF~m!ppGyYxm2+)0_F8uY_@o=^#S(9X|FmeD12tGc&S|9OJaG z7yCvKI)2Z3m*Fpo-cHx(lYYdH%-{LRbk==) zx5lrF>@c0bxJHU}7#WSMyiy{kib?!@OR3CYOda27qia zm>5v4MKTC)*PF43Wx_~YH!Sm2-&V*sjL|apkY|+vu|AfgTiTj8_-|HYasj$c6#=vh zK`3p+XyP7C9j1D90gkdKaAvNn>=iu|(>7fg>l{Ie%$G}uZUxUaIh5{Vl!|0qHJ)NE z+^AsMgw}v(X-!wO2w7*O(?{^<9KY^bKXzlW-?~oG1E!-?TlR>wDNuBp`)3&|&BLL~ z7K&DFA~#Xv4|DJLrcxoo0=%Agv_ey!tpmw|vP`0#-j(xcyTV*&D<&$V{w+?dC&*7l z$NLpe@k>j$PX^j_#@_j*58o`7thqBom)9C(vIk%?+3f3&4jLi4>3~y5)vv~5-K*KJ zAD)7ho(Pv0V=nkD!8t~R5Nm(9DTz9~I-=EtL4Lp)OpY=YY zBqZRY`eTKqnZ4}+*1;Rv-%ubbE>X7iEU!XxJ|tq+4k@xRODIWF$5TKMnzn*`mVCyR z3?(7A*-B%U00SXfA)OuNLx@v0ItGg~loBhzf_FKU@>FYKTI$~4+(*HxErT7O%~6z; z709?$Aj2`6J1-aLp|AKNsL~{7bp^R!A{kKM$bX7fk^xU*f!8>0BJ7sdTM<&4fe)T% zJg=wGBzbYc8PaDM(YVGT=xCR?dZz^@MicW|PYaNX zpIk4GhXDUD$8xb;%iR?$8Y#+VgdyTsU0$J5JQ7Fimr5o8ZDOMq?_rcu9K*=)ELUVg z5Dw_wS60A+G-nm08$SW_$AK~OiLT!IW4G`Oxkmz4{{S^yeuHS|p4@-K#Hid>OPK#r z-0>+-Dbb+)W|!ZK>^M%#_DOEn-w&{O%Cs8#0sM?^(DibTAEOWE@iGu0-FK1rzT-y= zHMSKqfxwk8eMi89u@3{j!9H+GM~@Hq-LQpZU;U8^B{#wU?ToOcDLN?gHmdd%Hp;9G zSsToqW#Rir?Q+T!Uv7XrawDZzM%B--r%YCJv!pjE$Br{f($-rvQyOd(dIM_18DL#P zm*j1&41O1XOhVkernaS8n7-iRDI68tHon{L@_;}EQtJCg(!;n&I8drp2!;aob{mH; z>3x$f9Tc;3!Ot#Lh`>H=)VhbYHXO-a#|UZUJ#T>ckVA59ft1mi$d=*ozb0V{*C`BkhJKJiK2TkCls! zUdcCJj&!^|3;hC8y0<=|W#{ckO1cIml{G$LcrUNsg1X=6=0M2>RiHqQIol|bF*1;M z#RsM9H;hO_3#H*_GHq?MqgM#C898MDP}(@&owaV9<#7>{lRvyN0I1&D?}CQCY|5(3 z=oxmZR}TBUK`E~H=z{HW9F9C?6U;PWa;J7+CyGMWRn%ox27RL&-#G*)pH3z33B;f1 zZr+BHVLW>AAD_|WJUOEtf44gj{A?tCJaIFhz_3~&?%9|T3ld#m+K~UjXSzu%g9<@p zEGR*32+wH_^3cz00qiaU31wVWMmNvT4LnteHcv0v@;K9E%&>%5uNCI4sco^qFi}hC z?rEI?_3bCol!k?S!hE9}8LkF!qdSs*) z^%h(S_Y-c!$NWSe$GPRk{x`Z=$^3$=#2=)edx$HB6vop7Oq_=sk-}f&eWM#G)`N}i zo7${`h@*f-<~O8}T!xS+k zqF|2#%k{p|E#BK%Qf+webhGx8+<_(r#}f9Uo&`mTI; zqDc-@_&Wrox0zAYSc>ue&JKaYP82IlbqCz{8{HT!lI^mqULUp;d%B-|M<@G)jPbBLzrp!;JLbY{ci^ioa}edmcX2-4w?V|Yo+0q_->^M zR6Scx{cb)-sxvO92L@=a=2{+LsluWMtCiQox-O+ymvc9oAkO^GDo7%TaRZfahnM7q zh!>?@=`CqWd6DSqN~z&oVP&@>{;{XqQy8CavR%&*sf~H=@NjVrJBC87PJM=tW(^yf zG3<}{3;B;v2!xV220ePYI2_Ald}WTJg>Wrt!EKGAq=k;7zA8YxuViTno^xNq-Fw{7 ze_NUov2QX4KB^AmYpMRebx%gU%!bH-sx!zSQcY5Mlu%qE%PVkYMcg0VixwtV+pjYU zqKO&PD?O}04dc+5mc|4X>Qf8pD7&?QE+JGZ48x4h{GLhXkfY)v#6&>V5247QB21i% zth~}j@^v{VKoP*dxxu^s<^JkP!+9c7fjCsLx9k-+*Xir`F*s?kO=Os5XEH6^T8u%x z%hNr_WH-gQjlemE0~E|LSB7IR7#mi9oBsXL!^yll}1D5!#9E`ezYBONy zRi!;gvG3=jTL)Il01UW~W)@lV9nHjpQbXGkc4$IR%O|tn=cOeV7L=$q*VNNLXfM#gbz^S@-?Oat zrJ#~=*Urvxq#Ibi#g{ZCy;9IyHz!TG`&lWc(-$N6Glf{)J+gPvecr8Dhk z$sWHM2>xHw*bfXk$m|;>FQCAKQcpzcCOR`GxvxF=a{^6{-wOxAppA8%DvL*H$R zP|YEV*n2v;V4LV<`#n-jOC=_^?^2)azg>#ys^nzXU1~D$y>POSAx?w=%j70A?@|M< zy_aIjP@DX5i7LqTlOODrVro&JEW2EKviLp|rUe?4FD??FoU%`9awbsWdQC8Q&VH%M z?+!>Y?biZx3s!SY);=fzT&FL^bY6S%!^MhVqw0X%`#L}sij#Nm6Och)tdDTXd)>*Y zd$qtGFt?n1V5hna`a&dx+H|YQHapd1P-jUI(hLlb9D#GD4orTYlh)VS>?%p8)_Mc|f; using u2_t = ipc::uint_t<32>; diff --git a/src/ipc.cpp b/src/ipc.cpp old mode 100755 new mode 100644 diff --git a/src/memory/alloc.h b/src/memory/alloc.h index ace13a5..e055744 100644 --- a/src/memory/alloc.h +++ b/src/memory/alloc.h @@ -2,9 +2,6 @@ #include #include -#include -#include -#include #include #include "def.h" @@ -31,10 +28,6 @@ public: static void free(void* p, std::size_t /*size*/) { free(p); } - - static std::size_t size_of(void* /*p*/) { - return 0; - } }; //////////////////////////////////////////////////////////////// @@ -54,8 +47,8 @@ public: void free(void* /*p*/) {} void free(void* /*p*/, std::size_t) {} - constexpr std::size_t size_of(void* /*p*/) const { - return 0; + void swap(scope_alloc_base & rhs) { + std::swap(this->list_, rhs.list_); } }; @@ -64,6 +57,7 @@ public: template class scope_alloc : public detail::scope_alloc_base { public: + using base_t = detail::scope_alloc_base; using alloc_policy = AllocP; private: @@ -80,7 +74,7 @@ public: public: void swap(scope_alloc& rhs) { std::swap(this->alloc_, rhs.alloc_); - std::swap(this->list_ , rhs.list_); + base_t::swap(rhs); } void clear() { @@ -106,6 +100,14 @@ public: namespace detail { +template +struct fixed_expand_policy { + static std::size_t next(std::size_t & e) { + static constexpr std::size_t basic_size = (ipc::detail::max)(BlockSize, static_cast(2048)); + return basic_size * (e *= 2); + } +}; + class fixed_alloc_base { protected: std::size_t init_expand_; @@ -113,7 +115,7 @@ protected: void init(std::size_t init_expand) { init_expand_ = init_expand; - cursor_ = nullptr; + cursor_ = nullptr; } static void** node_p(void* node) { @@ -127,7 +129,7 @@ protected: public: void swap(fixed_alloc_base& rhs) { std::swap(this->init_expand_, rhs.init_expand_); - std::swap(this->cursor_ , rhs.cursor_ ); + std::swap(this->cursor_ , rhs.cursor_); } void free(void* p) { @@ -143,7 +145,7 @@ public: } // namespace detail -template > +template class ExpandP = detail::fixed_expand_policy, typename AllocP = scope_alloc<>> class fixed_alloc : public detail::fixed_alloc_base { public: using base_t = detail::fixed_alloc_base; @@ -160,9 +162,9 @@ private: if (this->cursor_ != nullptr) { return this->cursor_; } - auto p = this->node_p(this->cursor_ = alloc_.alloc(block_size)); - auto size = alloc_.size_of(p); - if (size > 0) for (std::size_t i = 0; i < (size / block_size) - 1; ++i) + auto size = ExpandP::next(this->init_expand_); + auto p = this->node_p(this->cursor_ = alloc_.alloc(size)); + for (std::size_t i = 0; i < (size / block_size) - 1; ++i) p = this->node_p((*p) = reinterpret_cast(p) + block_size); (*p) = nullptr; return this->cursor_; @@ -187,10 +189,6 @@ public: this->init(this->init_expand_); } - constexpr std::size_t size_of(void* /*p*/) const { - return block_size; - } - void* alloc() { void* p = try_expand(); this->cursor_ = this->next(p); @@ -202,14 +200,5 @@ public: } }; -//////////////////////////////////////////////////////////////// -/// page memory allocation -//////////////////////////////////////////////////////////////// - -using page_alloc = fixed_alloc<4096>; - -template -using page_fixed_alloc = fixed_alloc; - } // namespace mem } // namespace ipc diff --git a/src/memory/detail.h b/src/memory/detail.h index 90748e1..a654f6b 100644 --- a/src/memory/detail.h +++ b/src/memory/detail.h @@ -13,14 +13,6 @@ enum : std::size_t { base_size = sizeof(void*) }; -template class FixedAlloc> -struct fixed { - static auto& pool() { - static FixedAlloc pool; - return pool; - } -}; - #if __cplusplus >= 201703L constexpr std::size_t classify(std::size_t size) { constexpr std::size_t mapping[] = { @@ -51,18 +43,18 @@ inline std::size_t classify(std::size_t size) { template