From b0d5b4ae9391eb3f52fcf418d118bacbb3a19fee Mon Sep 17 00:00:00 2001 From: cecille Date: Mon, 28 Oct 2024 11:25:15 -0400 Subject: [PATCH 01/13] Update coding style guide - removed most of the motivation sections as it was somewhat repetitive and made the doc quite verbose - removed the drawing because it doesn't match the SDK implementation in reality - removed C discussion - I don't think we have any - added python versions. Didn't add the other languages because I dont' know but other folks can easily add a follow up - added sections on + formatters + anonymous namespaces for internal stuff in cpp files + singletons + std containers to heap allocation sections + CopySpanToMutableSpan + std::optional + python section - removed the code samples from heap allocation because it implies that people show re-implement these things when the preference is to use the provided support classes - removed the version table - we have git history. --- .../coding/CODING_STYLE_GUIDE-figure1.png | Bin 97045 -> 0 bytes docs/style/coding/CODING_STYLE_GUIDE.adoc | 716 ++---------------- 2 files changed, 66 insertions(+), 650 deletions(-) delete mode 100644 docs/style/coding/CODING_STYLE_GUIDE-figure1.png diff --git a/docs/style/coding/CODING_STYLE_GUIDE-figure1.png b/docs/style/coding/CODING_STYLE_GUIDE-figure1.png deleted file mode 100644 index d8603de93c6067f6e2dc1026d72d4c66a642561f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97045 zcmeFZX*|?#_%>XTv7`}Eq=~YxWh)uWi0ow>Yp7&5BwJ(6S}NHIVNi^*WtTNlw(Kev7NJTLC&#r=8SJoBRFJ2TgQF2{MC=Osw}mI5^;6XlU3N2rw)$de;VatQ6m{R@@U9@>+!)k(@C4cjWDr%7MjO%7xr<<_*k z5fqF%&Bwr}sKo7i{2jq2qgOUL@*M_o->SzqU-lFqzqWy1hTKPg!o^dUI-ckhzxTGR zNmI@&pLZGB+L_*docLHswITL_d3fv{{IsLDkfZt3*Jdl zgeQtqz3=b&#R^-z(yw@&$IZ__Da`t(B^Z9?p6Z)x9cxQN17BZX`SkLF^l+j5$gpi+ z{<~Y-agy%E^rt*>i1Rq;t%2mC{Qc$ON)D&TEj}a=Tye`A@ve!fseaVnqM4c5#@^D_ zR7-rzm*8_PVV4vZ*1vzh-&O7HZCEp!Yuvu!JpZk)e!Cfu>k=)!bSWouv z7Fx0;`%7KA^a-5C6tfbB`veK(WLAF;&YxQ=t@o`-_}!mB#>BLXSQ>a?WW+T|NhPZlN5m!ZJom@oW$JSll~pPsCq_R8u$7l`m``zu0MHfo{ z%xmo~l20Qb&C&ds9GBOw-$BZ9)lBsMj{^zLK89%Ad3NejmSX$bQIszG6Mx^FOxcfW z&gz8R0qum*r2f$u2-O*Z!jKLTa(OSWD$h3&kZ_tMhq5Xgd=73tnYG>l@vp2gskHh1 zn0i)V-jd&S>JHL3O#mC4Li(gU1ia~&X<^u0`XeQf~$eiHnPijk$I)+)0)54k1}*Yj+|Y!i&mkdy@>MQ63jn>~-33-pgQOeYKUj_pX*5c72>aD^1>)wCTf?I4;}V0BWz?fO@Riw+mt4V77k-vgigaRkK0 z(0JMomGw9+51&W3KZ$}U&sns-(MK6NIOO$}yV_Sy`0R`QyIB*6I}=I&HD?zc~cExmyqH2cYdz?yCn6iXw2*ht@K+(DR+Mn zCey$>9j-UxjyH3gPoF;BJHU2~?8I4hQEJ(esL06PX1AB&_@*Z1F0kC~vr6PKm$xT< ziY*>I&{hhlsDQigr*T1d1|kQc7o-NgUeO-kdU+?8gyLAx@pX}Qk*8T%d|JlFb}ozk zX7*rWo4PRns!!%EaiSZ9!4HmVw{D#Tdwg)zMA4KJgl;SjSo9a8Y$Ci$)S^h03BXqv zvQynrJjCf3@VZ@+!JhwNB@)2W8XQWW~+A)Y?14M`waEanB3$H74?QYj~ z2Y%s#8WdXIwVCj~H!?q-Br`e8BfPC>?1$%Knj-rc4b zU}?!@!79N@7jybCVrUFyAXtf^QhS=(Im1}Y)N?nffc+2u7#RZQCi)@pSy&z@8(E~2 z^_&k6)txrdq1!@;kXd}LNj5bd(hBpOgu*}2GNt$Iqz|nJlB`Y{#-)8+$hw>BoQSI2 zA%0+sg17hGZt2tMjEIf3GH*)^hATdStAEc;66ntS*m!Im9!f*LjAj|bm|Cqu*Enhp;+bkdsOhZQf zb4{UDSJvGKxrgC3l2adjNT$h;N#5*4WC~j*Es2Thb$1`f3;xx0MM^Ygg3F`v+J2uV zySVa$s1qO9XKR~Fi|!<}w&TP{fM74UIEU-rpW8^cCR@}hnH7)Hn*@kxeoq;~e&0>9 zKc~}<-LO9g{axAijKH18t$SMB9hMDeCEW_Mbu4)ZnBw-wE@~&%wbV|{OH56*C5_xw z5xMx+USb`8PCF=2vR_vwMAhZq`Oujt>P+D|W7c<)z%%eIRzJ$Q{ENNYn+JYN=_uus zQ7@IGX7Zz<-DapRsdcT*#gXc2qhq(XL%G^TD5Jc~J0C{P&F9Pc8=oOy_L8km&b`2} zU)-%^h%1AuAD0b*NiMj`jjNmHN^PIJ_7G!~b44TgRM=mX$tDNG+8VBw?5Z?y=f!Z5 zFWRW>nT;bGO55dKAuO8&ohJ@fMZV>6PMKLm z2R+JTzt*RCx5w2a+-&QX=$gAM(2N5mMbkK2mie^)P$=WSL+=0LiC!~_d$Y7**#NB6~|ENqmYWWv?y1NldXIt# ztmw-7(7Ga-uQ`lPd1TVo3{9D!5K1p6ZoHkGV>?%f^RUov|Ud>qLEG-3?%Ki;~-~ zFV`546k0_Xu_AcySe7qc_1tn2wjYLXSCsAk82hxbS7t;p4QxLyjd7-G2~9;w`Sq<* z#KLajkYp|sw=#2pv~k{pM%r?tW%=Cf@E8&@V<9geFx#7#8bzU8 z7v;qJ%f(`OfN0^>k;m5-2k=>Xd9}l7Y(^z2WU7hqK1vED2>ZKayj4m0_AHwH1#K6;dO;-Qw+;2LwKt7LU%phnj%HPMIk;>r{3 zG;HVA;5m?I;poqCqBaYQaraYkOeNYG5hwPZA1|@Za5t_bmYy=2?z*KHT*5IEKp4)7?+Z+ zFRaSQV&zkW?U1g;&ZmgS-m*(+7qGH-8$wx;YP2>Hkhoe*ok0jP;D!i6rfoJ&?&pnM zr1b7`E|50ZJd^9UZ|7KAYzT~rb=%AHpe2ut7Oi#-jU3F9(ibOOD5%Cyei7aSRD(NGqGjOkk-SsTATjU>S`$6x(-jGBrtti=;r5AWMYcDuchTe$8-E<-f050>bcu3(7?u52GJtx2M~Qzqr-Lx!AF_(L9f!*#c5xWS z{kH*!&HwT~#CE?Uy@LV&3#1Mn{~PY$5e)S|f>KL$z|^d^ojiZNVk9yJKx^ua!SfO> zBH4x|UeX;7jqEWMBQ$N9>tPfmWLXN#yr?aa2>uveMzw+_>{lA;@x5?kI6f{3<@+YwUZ$JOUmjCp8uq}V~`_IUK+W%S7 zVQ~AWA7Ya~?+?!IppSq0{DYbP_ip|f=Kp-Q|E=aPFZp+c2Lu1J1OLg`e?$M@ob8c+ z7JV?6e^z+#{NFVGSgHS8v;Fso4u<~!r}obd{Esq<>iY|;2%Kx$2Ry~Yw!a!a$*7M^K<%*)td(PJSMA7eBF+Scj7vWzSHUroMz`O@0d z@YGh$>%IbuO9w`d*ryDvo56i^NfgljMHc4MUt>)L%iCl72!uxyh!b?wl2c<(FNjsT zZ;HKO;0Il18I^z2*3r2Lz0U>JmQ2kXtn%Cj-R1!{*m0ua)ITcehe@6&DlCjlgit7p ztf7;xIrxINam7TC==OI>N7kbtfFds@$T+U-<~?4yKY?JT4K}TR73;oSiC2AnIoTk~ zq#A~%fuJ#7u&y*U2@4OE?}ws(IDOKWz`*q1eUV1;*Z`owzd`@tGQrU zVkZx)L%<%GnZ*tc4my6>EOVa!*M#{7GBuz^suHZIz%0vLm+fvPT>o4cK-%c1ev!Gf z`d>y6L7g0KN2Gt*I67X7SZR*(kW3(UCu=}p&;kPY|9X}2oT#Y{pi%=n)~eqsFr(>0 zj8l?qh{QO554K(8)C6Jy1P9DL&#A`74KoG)=W?jeiM=U^OpqN2gXG;75kvKBqhfEK zVP|J23I++XM~-R4u-Nur68xFV=i}_}L6lL92fj}nyvMD)FpZ14j@2eo%On-^JO@sKh28D`tCr zvp8dt`d`7Hd8S;k`NkIkQX~O27=&L|sRm=^mKw{!%1)eqaYj(=!-o$lSp zkvnA|rQWD-c~vYg?uu!kq~Qxx)2ZzU{D4^_Im7Fc#%Wa9Xu1j907aVLmL z7-{=O&KaTLLsLK$)=fOJ%ZJXAAu=5m>|sGP@@R^>pae*Vi86McEa!9NF6clUEk#vA}SBQKb{Ps-fC4 zusW%ZvqBG^Wni(`Vib@e^R2a6AbP5X?c+_&&6%ip3D+DjIFUpA<4F-BDx$bm@1L=T z(bg|VG=o9f5m&6n%l}^6)MEm1^JXB(uSqJv0QY<9UvaU-u2#?rCj|AF?P}}0w!c~< z>PgpWHX2Gw%7uz;^y*Zf6;+(FFZ@|0{H(NBMPpM_zDkI->g{;3mYfP2fv^9r!8$04 zSGV7a5+{3B)H+go8-JFJ|)BDZnfnI|8WA#JzdLEK$Wy z2UPcqH5KuYh^N5<)x(9oV+w=t^*s9{*LA9}nXHo51|IR%`bciAP>6$~2#{ynt~!9q zbYHNmM6*DFNz$H7wj%1Y=l=kZ$G#A=U0muBa^8v{(gL)^iL;kKeod4d02FtT0kf3H zS)y^H*)s0+f{cy31I_tYU=TMlc}UgXhC*eptzRV%q2s)DuxQ}UF1=dr?9}{M z`z&RtC$xPqH@(WL{`dvN8`@w%-NrXYaO$d=v^%Hq*V$*>R5K(VD@edP^ng!@Dt9>M zvy0LEhUPIj&24QZDq`00wAuOv=B&`~-K!Y;k*bZ=^J2EIhoXTZM+=$&#rA`@mo5QL zk5R%UE8+Pi?lcDhL?HZG2>hDk)JvoA?rfHn`9BBD_5t2*O$7{S-n+qDFhJL*&Iu7% zHZu83GpKICW>%9f-#Z4}GJ!={xGOR$s&9@7Uq23fU~!aKgI{m6Uy%*o`c1F;1*lqm z$7|?ye#jw_-mZA)2m-0k;Truw#x5SD2fz-6T4Luuu8Th;+y%beg^2_VMUV;6@+PT< ztM@3h)87n*Xk6eeupg1)wY)>8?m3L$wK?2{Bf;7*knjEC53?cS24Y5czXRWAfKni8 zs9uqE)a-C&`R*I%n>rLafZ9RDUL|&ZxAl$qhT}KwHvmDzS#_l;k@wCqO(1M1Yk-?v z=>29^4d>$Gy1Y8o@+WL!iJkPhKmH}yD9-%;@$a$RPapU-wpF1J0wXF!08s*ZE6@cAuOh<2?xm0W(~jei zXF?$>hBytavuyP|yuA9jQ-?ig07Y%he$bQ<)&o*DEt9}Msfpwl6tr|_Xk|v{YK6Zu z#lXmkM@_OW(QYySz~}AjXgh5|Qm}^;K51;&`kG&|^b~)^DG#n5g?PMr4H!O?l;mF{ zV@R?b2#_Ff%=D14fyl2opNj_;I5WUEzdD`1l_PP&DmqTAUK(ar>=YSU(KBk)9?kgC?BIA8c{amTd9%u~jwQ`&$tA}S^e_k@q3*_ekz z)zqT~zq0K7hgHB`+=7)N8LXeL23?sztR-`cU#H4Vh!FvGNO(zeRaKeFL`m@=U@o!<3V|GI=byw6h+aPFVDtWXsuq8 z6Z_@nhDKIwfs|ABq2*wM-Weg`glaou{Hf41?r02I5CF? zs{-_54cB@B$L<#%&&FOhYdX!_qzdBrj7N({%<%6<8WUB)&2D*7H43r3(P5Q*OSX1bfh`jTfDOr8Zc}VONID%Q0KJhatH?4 zir~HFuDK|d^!7Io)sPSI^afU}mX8A9SV<>u(Qqx*B&ng+5Ep#ZU1}zg21>F66G5wY zHM(eFrY?vsGlw^Jaj3k+=pHGWMgq;!hn=MCVeW_`%$IGs&8+H}JkgGVFxk81=9Kt> zrJB6`y^q|Jh@aL}*59T_(##)a71LDrFx0lyDKi6kXGGIH1xWeTw)gmkv$AR zm3er0Y*Xc~PMhF+uBl58#r^^{UhmcbS6IyAfMM5N7oM4;Jp=%XJZPF>77bp0O9=vt z6afP;UcXp&=||1rl`xQS93lEc@IeJohXj!O3XZOE!pHFGKWbgqHbx~^`5crVJOOZo zXI#hk9l=iRUi_hCx^j?H~IZqogP?$yDaDdto6C@ zbcS*hury&1rg9Rp6WFqx3`(Zyr7d84vqM!y(e1@3!|h=tDwN?~6a{c}M7@w{Y9I+{ z{n{EUT+gAq#VC>|3+v`*{Fd)b#lZKTAY)-xB&}okY{Z(%AWp;ahiDbZCR&25sXmJJ zizGDg1mk^R+);`!5VZD7L6}Aot~*l>id>1E@TsbIONz^J0HsrowQA#sF${4qc?Smv zWQo&f;6QK9suMcv;UhJ;g$bvbE*47ZK} z`TpLVFnRy1-aN zdx^1rDbE%GZ#V50yoo$R%UQM{n|WLD&41bzZKmyu#Cw;9K{^7Wvj<8YOcNq_fzhR= zTSw#9uMva#>G}1`w!N1n_-{04&*i@Wsjq&d?IEBD1vsZuGq}O;XHGGO)*dL*giqY1 zK*0l`TSt({=3yw|W6$J2-1H_AXGB|LW1bq_EShFt&J@%vm=h)%*WikwaKKmuQWInN z?|t=hvhDkxQjdS!9i`X)Je^+51V!6*x3zoOnowu|2wNav&|FI=K948sVXB4K2S@0W zuPqrZ(LMig<*{c#vgKz`n+aYkF_85`%Rr2*x?$IwtDNU`&c$t;sH>|xdxF5*W%dgQ zB;RGh0pKm-6`0w*1#*3M5!c$ML%)K=8Csvqi~jkJ`f2~~54hYuE5aV2Wo4aKQMuHW zugX0Mqkz}|!^n6{)_ni`0yVniE?OqMgmbFoz5h=d|a96O& z$w{P|j3_^6=T99?5HKzl9*TeZ7A&asdBim@3en>OsfxGO-JvFM&sA1G%1*&X+ zqY%o&I_PMzZP&ae>3v~j-fC&FzFLsDFB6E5XRqA%Uv$K)~6`Yam~lvy@!Laf^*D6W+VXzV8)@Nm>^W{1N_BWW-rl>Bpja#e$I_VW>?I znqN8HUMzbX#`hz9+jiM2oIWJ*JC^gvnp;yveelMHX+=_h{l$^_j@_GXvWVQtQ-Zew zl@1D0ClHYuIywxcLChds-o+4U*=^Qy96(W7Sp+?Ws^K&HPjX7fC`c(tqJG#|X{s5L zU;h@N0aJ`qO}O5(bR$aMt=a&04OJy1kBR@wRzPnrX*GiP1zr0s(K54L`6k$SNF@ZC1aFR!2t`pD|r}A z)X*D;3y8n3K1sktmE;Z?SDcf9mE!q=FilTo?c;eayxQ7uhA%i13tF7mefL>a^Yp{Sb@2T&y4bXHbbfo_yu83>x$N z7?NpWh0V8j2~}NtM%9qGj0uF~o`Z3voAW4o^kDKqBvHV2fE9Irx?~w42R3)oXKE`w zJ^gCXJEj)^b-6n>3vZ3&rrBBY+z@IeVV{q(x**1(E$G`>2-Uq_+7h$#!sJ)DTV*n< z)R=lad}eBhQ<87YwIqR>3+gn|m00nED&XQs)zh~~`!yog0p8`Jw!xdEB$FOC2S67U z_c0T_kxZvdFdgz+_Wafk04fm>T2T;X7V^HlrU8PvN;rtQ*gN|bj6$4+8c8Zm_}j31 zWK3FiXyt%3J5a&{3Lw6pyv>5`A3ZO~eS5Q!)JSmEt7<`IZrY8)JA?C>YX4J<-Aj#r zA|q9igVSzphI1(VYWY;~ui>g`5QSMKa{bU%71^u{Omqz?5j@a$7U+w~RTqA#E^8P~QdL{W(3v>=e%J;4Xmr{+c_ z^+o=k*Eqt*&!8@8zI#W6al%KXDr#+WGklxVv*d#nMOd_SclQ%J=f^NkPJ;lW+>K2E z{w?-1!d*B)c8bHT5-NO~(DXr60pCcnE4&~8zE=rS>H*(2P-2gy6X%5LfQ0|_^Gi_TvPm;cU|b&(u9yOP z0mR5~AD2^w)e0aK;aA~CV@6WF?mYtKRgn<~aeTY~q>mhtjRN79aRw15|Pb z$l5cDJI$y!-8v9tAjwEjfLN0lg`7kf8z<6Jf|D2t4BD!Qa+!x@4c;nV{Zcn?^ z!#_HfAsM^v$8PNn5>;8`CH%FJ*>fWlt0wk>ZyYBeRAVe>zPdgRACpC1C=!jn0h2ou zhg0wR2?O*MD037fumq}zS}VU2$owu7EaTj_PNE2Md&6X7)EBk#rhTGO@J06JU&gZg zYzGh-14z1eDlz?R%G8s0uyux#G~N3$yF@FlBGT<+)N*Q9DG=0VE$FYVLa3Si;m?xc z>bWEdM_o(}wH|eo+*|qn*+of{KO%@oIuePKsJjOF4#4dfzcCpAf-MAg%jZ4_4K~Ub zqwfTp^Joe+knpEI7CU{zW1x^wE0Nql$eDgRG?inc|M|}T2+wkH1vvo|?>aD32+d^L zAz)(cO?E3AHeg+xzJ(2&c0?I@a<;)wvFCVM&SKdhU~0>00YT!D$?u;_ktPCkb}8!9{=bOp&|DNRekgeS5GZ&W!`;p)hMsuH^o zH%pHBxkOuUd< z4BgwT$O%MoOs~WsqqlrH*90P&lbZRs6#BjN>5`vz?vkhdtivFCo~TVb`^g}GyCwTn z*Glny4ltu5-M3*}VW^H2c_gRXZg*cls6&kh;aDFEc*I40<%A$)?Uj4Aq@WU)hWA8a z_rP;{URxqacLB9ok3_22KZ!((njva2rKP>MEZV!7CqT&k4Y(H8wy?M>M*#^T+_kp!8ZqgvLX zkY)5{W$l^lIl${=t1}i~kiY(Wi%ejOG+Z?V1ym*HZ?Wj zf)_!yz4va$%?U(SRTqv+b5%`=L`|2R=VZ85(eZWG$K5ghym``#5fC@J9Q1u-YJyCr zfbII?xGp#%Nma5z0|j*Zpu15{-hDTNb?XC@2YhQ9zh#{7X0>dW7i7}8kH$YJV#D9o?nJ0XBtZGX#{7pJJ5(zRs~FIyW6gRoy&EF7zC{x;cfJ zpRwLA(&#N?TOWI*i&86%+*_CU@igtq+i>_p%eh*5tFUu4bHxHjH#%DAC`5;%8U66F zOO>rIJMKh@p*e@fc$XS+Z(=o47sS|0{^Wbq^$Yxc!g=t_4j}7Sj0O|mAbga(MNgj7 zFLR&I(u|tGq6bQ~>s~FctvPLXU9e_8>tt}tlLy*e!0u7b^gx*pJ1zfqz;q=cnz>{1 z>YX^t&jH$zhmJ{ZvIY?O3;Mz(wh66Irl+R|ew70^%E@G~X{_{>$fNYNgF^QB#~{K# ze~^3R@dH^?L-8~@O^akCDisBOecLdU&+=I!#M)o{;i$~ONG(c>-dCr;eOZjZMc+^q zX;j^X6Kc2S&X7VKq!!{z;qB4`fS)R|m|laH(i%iF{e2_-afnj45EMN92lOzP=E4-1cCzwRI9_o900`Wf4{ZkbFeK(=Cxw)Y0RrmNu z69)&tGQ5q17}%}6I=iTn$y(ZTx^V6LjN5_=!`yR4?`>I)8Kc%)+jpIhcStY#y<;Wr z9?MOFj8bH4=&u{^K$Zy11?-jHuNz6grUBrnM!Re3{^cbj$C^<_(W(@IWo!KHgAc%O zBg4NU&sn~N7@;va;AbYn!orJrJ$fq&71dpFE~g7w9|$%0IUA=8^9M{Iu8z161ro4c z>HLHVaaDFhQzYS(3iie%$(OB-nCy@ zY+hUz6D;#@^g|501d*3$Kj5{$Fh;=Way_c_^cZmWs4Cgj8S#pDAL#mZl?d2EA+6AV#g`z501P*W4y=^pIgxE4iCQXWS7fgf*)&mMOcZzISjyzLjCu{`HD4aj@NFD% zYE5G3HK4J1u>{QR{tp&&>uE0TvZIsg@L84K5sJ@R$$GTUl?550F_4gLfB%V3jp}@q zpL1pN>Q#o>A-CMO(RJm6t(!Y$!=^6otT{g_b*kYFn@gz!RF(Dfzsk|MB{9oIkt>2k zx5)yvhVtukYK%gi`I4l)!Ks`K3Z&(U65qbj@=Yh#IQSrOA|l{hlAIhCdAQkT5xxxHyCln^qaM z35Vo9T`cEX^uzhvj;xmB9W$4I8BNNTab5@{4Tapge0Ic(U2$s57=LFk;P8;&^Z5Pn zF1~6%{MDMuL7A9mf6x}bb;H62Fh@Y7CJB3am9~9C@s@{VF4HCD(15F?Lx38+GwCy7 zSW4=AYI(V^s@nP_BMecE50-~nGS%qcCg*?H;>lPozdrD5Gm zkqkW=KD&2spd{V1)HbzBM1R<9xBErw8vBC4*nY7fYc9x(TaVsae#E=H(m$PAwT)#O zeefDy`k9ktc*X0RJdAuDp>FnRXlMIya-&8~>1y#h&b#0;jrsSwpyFwtJ#KubML!4y z)l!mk7WP^fKy+Q4WvE6M^-vMiEC3#~`>ci*{op#NU5SW@Fl`=;8l*md{WO|pyoaGM zL=J>cuR1r=@)}9h^h3E+8PFK1;|iB-@v*y_CWI=<#ZS-uB|Ip$m6pA>B`L08!S{hL zbKN(kmnfbV7DCT)z&4F<#|nPHukQ0Kewsbu=y4wuwz7y5@=I=Cl}DsZNZx)zoIA*- z`%jTB9}uZVu1Zl%UlZ(Kf&DB~7p>3GO2?tPb}aF+MrI>GVH-(A6<)G^WovK}7Z#>N z)7${HdsX0O&~)TVCSC!a&JQw>v7Mcrj>TuroT=ZH$exS(A;m$=t8`rr&%XEl*F%e? zD39%Q<_GRdZe=kIS3~Y6m3e2rN3~Qgit;D)vhx!npY}i8cD9^txVYy`oZbZD2cW z{_wvex9bbD>%}Evcu04fyX$p*TrscN=TP+{IxcAKk#A7fz}y;)DjpCrFzf zLH&F-kP&E=!oPc43DmNSu5b;@BQ+@W7KaO?(aN7q>I}6e$c&g!gljLMM{%kBCHD3q z*Gatd_psSil7L?#+y&oGXHj_n{Bdsr@n*uuU+?EnDU%D(15ze@3KT2! zH!*pGDlD;_E(UGH+q59+EA&=_r4HsG80aac2Up2v6@NQ^Ml=RV->rS?T{X|VOR{K_ zmIjQ=N;UJ|Y!!yW%#)Tn8$FV5*6hgCWYr|g(?rtf8z;3a*FZvXF)DYvzW5?mL>b7p zKFw^wtEtt@5IA|veF5LZfZR;@!+L{CvhHgdQAd(D?@hHP#D`Amews|m;q0=eBFY#j z8Yt}do!Y~%UvS}prhpqB&80n};;BFh8X6j&^#%YM9AIJ2TW`qUT&_2OVY$sgRX;#c zPw2_E>{Q5bPn&-+Rekv`kxfaWL?tTitft;`B&zA)YPcddns~{%xhxD4WQamIz6JjS z`zDHr03{5&ywL8;S7w?hR}4`1Krs_iwy^k}Ie>sVsSTiR9I1wHZ(CTfEkFMk-mKj& zq0J&*^=lUJ)w%S(U)Cx4Lx-|RZA?BdH@6ZR-A)4-ilD@BCE%q<6E3t_Q+4Qm^Z(K) z-u1|7VVoPfW~4LelXfqoUxt^@(vZk)qy?=Tp%9&HaeM54b1p1a7~vmd$%`2R&^6fn zb+c3{n_6($Wb6&GI=rcwq;j)NwGSIYWC)b&R`~BlfIBqHl9uCL+B3v5^tixx+$YL% zjL#rK96f>a83FkcH9NbU-HbHs?=iRm$h+Gwd*9EBDu_CbU+x0P?Bz$189W#1=RUC> z23Zd-^GX*@6GbArIM{f*mt}g+AnLCl=GMYxVc562yuAKNu}G5l03-8QxHPX*gR6zA z@nYF?Wp*!IQfrPsMK|-Iplx?+U05ZWFQY7x9Hb}R#(E%gt9c-$ z9T^F+J~{iPKzYMi%sA$%-Qa5)GzQ%J>b(AKZaFzh-dF5oRxUi0y!)Ecs?II_Vq5*u z@jFS&g*fWkbhDYVFN}xt(!2@dLc^{*VbySjH_KZS*JnCD?TsfqClJF{jk?IpRCL&dey`Lv z{prMPWRdZO<*F&cDR{hTdq(o|Zy9{a+e(33aSth|5}!RCEuuxvcZuz2|q z%i55@v+3oyExsOXnva14;#dv8yBNr5gQ6MM4)snCV3p$UDluEeD<`m{UKbOS!xMc8 zQ7-icQ5PJizTWGXeL3l)b0!o{K9YlDy84X{Abqd&5A+PQ;EfylC9`jdB*n2KFg~^ zb+6IU{C-W>R9c_3a8jAsl*IWmV>IE?84-7hHQv!M^)==8-1xyYDnY5{?k9hK zH@w6tZTV%e;IpcMTf4`27@hf4wGJ(5SlyMy^m^63UBNht7s{%`Uz6flO{*-fZ&pk# zn$Mou-3&NWw1d~%&&kLHp?@#Y>JsdByRuPbONTt@3}06G2~oYSRh#&!z)aesAj9^K zsp$I?sqvNZdR@_P@z)$c;CPal$JjfdR(k@6p7db`A>s6RTT z9BSKG<#xpKgYfRBZ1y%y5HEPS7)9r2-cCtoQ+BL%Ci*`Y}gq(b%h)E1r94e4lYfRUA)Gg0uTN(Z0SEC< z*T?eZs)3ya3+c@Mjc%>mu@cJ_T^un0A}C|K8@>uscW<)BeX(9w6B&%v_dFR+7Jhc+ z4r&bC*)Bdhwd}Q7jzeAl!o!ZAK6@Kj3ljE_G0zKtdyabF!yv+6FG{B^2u%okHEm6$ z%(4n@$h~$M@cQ}bf&ptf+jYQmXuZ1m@~j3bKBs(=iYV{H)vuNblg+6)B0=D`l3v;P z{3~a`$bt2}>YYi!fu^UA8%csMi7LLiYHwV$=$0FI>%C=13Yk8x zV`QJ@8$o7uZ{1+Ibo``5+R#RNl2`v7@7?vOz;kxb;^CoZI~<>GI<`BbbT!XI(U^Ly z?TEKzh0omzkO41nPH@v6SuT`I_p+anczZ?QUh)V()4*6QAN^#_j5>U2*H*}B!DaHR zSVGxuQd5*tG`TMp!NMGj&|g7W`(q!Og|qvz)S6CAT&NycNSR8%QOzrK4wU0*li}f4 zz{Hdy(-gX$%4rSQyH-LWMDD|EL6qMiU0{cr6&k4uL2;eQhPPXAb8FGf-N0Z?V4~H;|}_nwgba$&_MHR^#c;5SD;3-) zq%-Ps;}K`>gnGGr|6aL&BV3L~PVLHQAme^QqQlCPHVA?xH(q~OEFQ3~*mWP-HZGby zkrxRGXPCBOIiuzq$43~gfm{%g{#gSBKd>>`j#K+F4%VfPTlG*Y0SUD9H}LkKo-@f$ ztt*U7)sOK5`AE`GYo^6@vdvh$wk61T@~v&-(w^a64UiDg^=s`;Y-;zwb#R&HAhV|z zd23OXt&WD?%f-AG2fwwHx0vAYgXQ)T_U`+oYvK(RYl0@F+x2V;q=@c*k{X*7z4TeC z3%?qUKh3S)O}7tcK1J$KrG6pumC^Q&no3DpK3rWWqagRX#F^Qz3!?ZtrqfFGH(=l| zFMMj14{-v--@roLj|>iIqUVM_@z2w&4!bWWIL1qT0=dFiU{b!w!>}a?wdNirJ?y;) zIB;n$Ts`Dy1&D1QotF;vBARvc64~aVpeo_inlMOT zJapw6UR_G%Qr>=;@ZGs;@%iE~if47`yvx9)Do+85ahM>wxsB)_O=Ngw!r#Kh+uTk%}`y0qd;a$j;86Y^;p8c! zuGOo+$khzhmCA86k%K&IRqQ91%I0%Q*Wv1#8Ho@k6>FaKHr-_5{JDnQL~_vov;^IG zHSZUelRn1F&Uhn>oXQOY#}Us>WUxJwjjOL>I??_6w^f;>bT_xsS@G*%wle1XVTBqG zj3#_u6?ntv-KQ>$BjSBIx(bhnV07VSP%|T4u&BVY z@W&H7vP1QLTPYqBzUKDZZ>`?r{HQwjf4u999|;okDRuS=WAx}MX;Ikr{C20asKja{ zL!v`5)o>YM{&Bq|z9Lros<2Mtb3@IHD-J_5_VI~HcU46;+BY}4OsC^_woS6S@|Hwr z(yrd9mYVuv2(!%IUQNiRic`cpXM8c)`F^Ij+D9(n`?Dwg z0-*yUn8fDXh(Ve#sI~+7!Pf0Wznrqr=Y+dKw~uk2cxEf|~ z9@$~9p7%I*ae%j@YhA&UaMuVvY>Ag5$*~#u;I55?&{7-aGTjv_H@;`L)z7!OIC(qn z0_tbwufBqPJJ^VOprzbOyKru-uiCpQ3F*BkMhVZv+4aVG)fZxmE$N&doN3JuUm3lx zaawi^p6y;wO}?_Sf0j;32qyK-8*9~<=Etb>bfrCcK8jP)hbc1aB?D^s8Hd$b$2JB> z{aggcYJQ@5x9;?7_h{6WP3e^s^g`^_uXODDN+KzG>uX7>V}iV2U8zc94VQl=|LWy@ z8qbg|5tnSTR~0lV^rqzNuiy_mI7IS@sANk^#96vvPgVGj2OnZRM>rx@-$}?;+gy*^ z6E7KHXG|5JqGO1{ZjGwtG8G^|6hh}51<89>*5Icn&zDYo1UyoT0D*sbYO2UT$ugTpj zgGQgEE^IdX)sL^-%>6lG;Uzx$B7%gSN?CwxSfs~k=Fx}P;!)P{JhtEfn?zC1+!nEz z4cOf@_|CSQ5=n4SvPqn|kf50=+v?-eEv-wc_z?N4FtU+HG0H(_6IGUt^~$(FUmXH0YF3eg?hcpz4CaPK7Cl1IP)sLQTir00{%c)tp-xBt8K=giHW&CcM5}bV3BC0@)z8RrytkPBS39&K=QTuARqY1X)>dcIiu>H2%Q*mgl+_c$|wB)O( zCIPZ#c){e(^2Nt`tDo-VUhrM1tGQ$x zRU7(#`W1JJK*h{%KT}$U5bJ6_@9XNsl#c0s+tt1uv__DhgQITzts$wV*NQa_TixWV z9~wt;{})+b9T(NN^*uukJ%o}nfQX{BGz^V^grG>LA|)*~fOIOYbcb|FHw+<&bR#*0 zl*G_Iyhnfc-sgGm^UwToK4-7lXYajwt?zarRumPq|G8Gm7H@f_U`ujjmt52C++6+O za7u%}vaDs{y?MuSL09|0qQ|K7E->`l_sbvid3({%{kr|SR&c4mWc(X-?9a^UqQm2D z-*T$9eYw;$*J`J{r}YrN-eT6IjHS)E;ho@J4K=+R)Fbdnq65*3bj0X6{hGi&pL-!J;k{$gpRit9 z=)xh#0_Czg*FWBR)&(pH$-Vr`1KEb@VD`XItl(-kI{s&v-pXMQ8H5=d? z)5l7O+`rRVvXu4{566sCV7jtcy#ZYFp1k*yk%$dI6jMBciWzbPU}wZd#n zbONtDn=gBPjk`$ z*Ekyw^NTcW&wDXercoz#z_hY#V*2{PEg_}25-*wSPMAEoC}{?rV~#H7rEcc_a7EuQ zf;b2eL#TeZu;V1tE8pg~R#`S5Do>{Eb3k_(XSG=8G;J;B8q`+8vm@pLy$3yNy8k^9 zVcFM~!u#1gsZ}=vh2Z~0Bls>>x8l4;YSDrqn@gMYV*?yWuTMzEZQK);A!xo1X=Ba? z`mXYr7pm?axeI;2v|DU#A^3JlLQZY`-Z7wgUHzSzUY(sSfEIP=oh>^wtG?0%z&Vf{ zq;uD!{P8@8vi7t-Up{jKioBop1-zoArTw<>F8t|3XmXtmCEIzb@b8eky&eg>+OqQ? zk=C}kt6yl|Z1BqP$$G!G{Nn3I=iS#@Hid>v@S}d~Jg;?=gUlzzwSGSqJPloH&Ighs z!b9Zw@7poBg!OJaTLEB#E6gK6iD+1@U*CcxX1~>Zh%YM1?O6iN;R%r(cK6TEO*<8d z!rs-J&Q_;-l--(YH@(gqcT`{ob44e-jyIIt$;zTYTm7>P6QwYp!9+_O$E&!-m&)AdKQvjA+2E}?O^MxenKSRo+!xM)?moC)+Y#TnmROf3>HoVn2z zOBJZX*s_T4Lb*t;?_QnVi(Sbv&3!#sb<3AOykIreHxU1Tk?E;*pyTgSNN02fZ&ek%oarA zrdtHYAM{Uu=)d?vTFMcXT|pSA(~HeoaL+t~k4^?=87ZFOwGsjNZVAQ`fC z=qZ%hV9#~R%}6EJFqb;SWXlcOWWUj!hY9QCobZQat3{Xi=w5RJGuU~x` z_73iuQ|g~_{oWvn+o(1>XBl}L~vMaSM41@uxqz^oKipdwp5N$3>lWQziaC2H(jjKrgSwwa)G zKun6*>2QrYX{=mQgVWt+qVk)F@{>o>FJAy%A2^3=^i{=nKIcgJ6qQz|#x6UJgThOj z%ZY#qSpICBjRaz`&i2zf;Bk8b@=kMJEum(>aIx*sQGXvD*5mVL$f5W^dMM#%MVgoQ zX*1Bd5E7Z+744%x7}~y;-?#gL4ay%p=R$yIJBAo_Waq>*xNqk#mW$@il$n-!o%f`Q zO^ViDYyu5xWf;emwzBmx;ZYg~O&&V6PYgxb`%w)4;lMvT@|1~`ERQ2V{cf!`)IG%Y1r(w>ncYun& zjVfZb#;De>g~|5-bVAGidfT$cPkP+@K0~Lyf-w(kdkiMHC?sae>GgL78T5PEA3&=m z+qU0L33T(@IbX3B93grMBZPqZ8WFPegXd8>aHF|HBalUgHm3Z7{Y~mVQCZr%c zOTi4qU``eXiu2QjZd?&T?iXm;wZ$8Q^n(LbL;}Xd$aCq`yeB=Re{GpD8T(Qwg)ihL zn#>(7zu`{0a})9NW%IBNyOCXF%U8)?zuGT-xCMMJ#;B?;;~0|`<2ZR9VA_n6eS&LQ zWnfo__K<-Q$ufa95$C9fT*hxPhviKgMzH4d$&|G?O3wlNKEi?8%8cYGHHK%2aN&cu zPc}}c@T&6OM7qCSBs}~PlMoFdK&=K*8=XY~#n5dlQA6G*ReN~1@c{e^_-`K@508tR z8oT)mo&(es`BVJVy;ee2XTrFAWtt6@3JUSG9T%sSIJT2b7tIM%O_{PUqXVB$)%YB) zsRkcFV{dIW%>CTb4pX)Tps&>b7PI-!0UIU+bMA+DXSc<{cc&X3-O?WU>OL`4TxKmA z*d5(1=TT*@`A%l}ZYWSC`r?~klPXq61cUhf7;(yINR7fhW{1|xN1NI*c@6{_MIeJu z`9H7?Cv{C&eYujfU;He!e&DI4tBFs6XV+Hr4Cs)&>dkxoz2>^;(~R7yilUi285hpm zrt-+P?tsW*3RebdH;%nz!7{xk0bNl|Wsk5wU>Q#CU(Rbt7B;Gm76O^p5fmf)C*_&7 zJn=L3TR`>rio-V|^FB;QGQ`!ZcdqV|Xl-QOJn3UjIRH4AD(ux&;)C%t*WFiLYqdD+ zZ=Lc<12+9Ej62cRGd{(vNj~M$&8r>WaOt@=WTrrQ7y2lD(H1uE9`cZFkWbldHE9%E zEw>qtIE-L0|DCm$3`uVq@m?5eY3{n(`-$zC07Nrkw{&1Q7G6q8O zWMcp?9+K5{1i%Dz8^boXzkbFStzvgXQ9Skel^|&pfQ*1>Qf}zf7vcI$gmy_Go&-?%XvaCYPa~jrp>v3$O-Asl^t(RnUMyA{K(r`b zv9P8ov30W3y>!pSQM34P{WPO(U0M|YVdIxi_V9yS3cE9bQQd()KR#M#Z|oMEu9oAV z8Qpezj0Ki6YSn@6t3xX#In_TWV5Em#p>N3jXr(&t~V>+Dd%^pUt>a(mY`TlHRV(*Udz33$JVAZYA?^ ze`^D_D2uv(DC0U(mr5!7*j@5!`_17&dvf`+O9#xVhY$ zw;k2A%msb<(B;kzMJJ&^E;T-G&DcMH0EO((mojDMAC}Ti;>Mq_&;jtO zd2E4uvaD+}b)Qs(f|%*tnE>M=)Te-usrhGSBmk%f!2p1+n&BI*cFF$qEHmYKRF*b! z0GXf5{hI7ZK}Dswo0t$OSaK$jL+ z-^7TX1C0#y$sQC7HtHP;JzR7nWWaoFmlIU!SUk84pQ+hvl|p3H-7_B&eh)AK@+#`u zcR1@TR_`tvy>ex^sBwRD>Rk0^>Uga+&6vM9BgNK;?Z&Ic1J-Qr32RUn0&vowv<%lUL(xPDiXeK4{_4>2@2BkN3)(meuy+lhbMTyyfqGS$*Y` zJUd&yx|ehC!<@9K*`X$r9vzK$8&-!~)(U_R5HKDG5oIYkU)m)u8zim(yCu~0lm;n zNVjiy{G|d?z)B9rPYRSk85|%NiPZ>!}pfJYCW^M#ouwp9!jxt^2HaSpN6&M*JVXaM&IVAkz@3(kRo?RLNMn?-Y zRp;I5M8(7{Y9Uwt>nAP527Gc4payNE4`N$+f5jJFTMm{B2&2K_chf6<=%<&$^Y%Q*v^@<<+keIIW(~ zudB#Ls|#OUkye?n-w=5%h?w_Q2_^Pqw9GbF-z0emslYW)K8jS|EUNUTAFm-cZqQC& zB zzY02!8uKY|>+Gu3CQVM`wh89a3}y^W4!qJcxOGIKB|l56$SU_+;73CzNb^ zIXTXz`sYl>#y|+uS~NeE8K)~P#|j6#bwmMGu9eO^YKN$a3}jk^R(8JEL*@z7SmMTe z>K}4oIXfQVpCR7htm{qJI!W=mlQ=fNXdsi;V|0yw&-zHD_@^0SLK?`uTxb=HMYmSY&x*3r-+V?4Oo#d1SHudu%1u`JJierSdr89Y6wQbs1@5 zDNV-)vhNe_1u~Yx9W3H&)L64;%5Q9H2j8$WyF~1y0tw5as*%RFFTra=O%|wk+~&$fj;oo3q`CfManPKL2l-$L$p(F7_pN6!KDQU`*)vHhx$iIW8t4)B(4(xY5HL1Kegj|48r@DRua&bhkpM5g2!v@j+?tf<@J zkYEVg1J{>G_i$Pe{xc|yz?XCqPHD%F@Z}z4r&Jg|(h)lN$f&Y;{yYvTPJX$ffHX~ zHNEYEgdb@-o8#s@)ibJ{oZA($mhuMLE9?2yVh?gDbbQ^~<5!<{y9gyGO~=KvzL%P< zI~RLX7nHp%d=R?*q-w?Elh3mA=hJrZOkA2=`bat5&U~EteP`Cav;Cv_L4$+^+oeTG z^Reb>ZzUc(rJHcBw5NqQRL?R(vj&o6!)skNju#ToA2NtiprYrglt@eRlX&N?yhqt% zb$B$s2@dz+S}u{#tNPJ}?}u*h9}N-B8hF&9lk#YdFNO?+ z3*#T7W|D{=Y|M^x_jaCrk`!;{<9rHJF(~m&fU9k`WV%iHvG9{r#_RhGO_jI6!^?`^V9x1_ z$dO4yO;7GfjPJ=WvquG}A86E#;oK|yBUsThjk{vSQi06@Sns&riq}0&=SFJ7wu%Ksia9W;=GJQ} zq-8kJ6GraG-8w=O3$T%v&GDa%kIJqcF4#&{VCKzZzow`kcqukTy%`H4T4%t5-gPa> zE*vqmdaGh_A$VR)$o=T5q4Sv+|3thNOER3jS%aSd0+w8$hDH82q2-(VlRR+C( z1-okGuGD4|)v)BC#Um-Q6rr@WuG7aevjtAhZZj24Tdde89RacmSXNI)r6w|zKP_ff zUP~0gsns5gT*RvNEwUd4@wN`7eXOJV+#ZJl$3H4jp)2bisZK15eNIt^0@a!w4JJMt zGi|y)O~Y^{4W^4Z4e;9rL7uux^Glu>PLzdF;5}Ee3)Cx%u40d9&TeQC8%r$^D#+xY z%5$4BLXeS>Nilk#F_X~nNVQ|X50*Y9gp(nd&{8NrB=(;@>B519Ho)PE{iM0>6??;7 z1*H6v7vf3-MES8m2jj=f#QXBDnIH7UMt_`@v*ojO=5f!}b_5(!52=rGNhW`-X<^@ z)Mz*LH{?cODF?1Wz8}PtwMNDZ%8IapB=K?J1J_RboCfk%h#|` z8qz{IU|u%sedHOj+)JtuXA`v`G?Yk@f8MQDEp*}WLdQbXVR-Sr1Bwuh8c$+mo7p0U1|SCY9OkspS=v6{3Zm}|uj|Nc-(=ztxlw%*XTRNlh+ z!Mz~;n%X1me6fz zb;B#~3F#TA>zxITXZzxi+3+}zTTY~WOGKj``$6{kNO`fKl&5{~)yHSBsLFa48C6s} zH+5B^$zC15V1087wH#??zYI4WLY7@r+ot*EvlXgW@6sX{OIjqP3GpZ3p&r zd#7JD&qc(6px}(Bj5_tP`+FUQgQw@8FvmGw71~>3a5m#chs5UB66`+t0W&l%u0k_S zS7}C6LaC&8*jvm~1GbRZzn;WVs=!{^7c{pLye;>=C!t2{lrvF5Sw5qhSBvt)QMrXs zw@0;S7gkNgheTdiL8oI36BFG%qPc(*%{O^i$(t+}?>MW*q`{w53MJs$SE-F

O&Yyy?-2UyF~L0T@s}p8j{8CUxKE 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

0b4k*%t2i5m}&tBiPESu ze;F)sj>!f=RJ%`PdA8}L#q-g@p@;X^DMhQ@8btvLp!036B&n>QjOy=pc^copaZE!7 z7)QM4hUrO(5z5o;9h>}E6zG1PW{nLqsCP(rWl+jN`@7%Ltxr5*WG~_Sn`2ylCp3oF zJf=%j_(m<}kE|{ufpQRtR9Q>PQ3nd*P?u|j6s!yhL&3pAiQv}BO5FE&w~*Uh-aU^A zTB&8or_SAcvA;wOkwso?*X_ESkid|#(jhF~V+lnyS2ef!mOOkRbFNb#wS6zo_y%R? zR`}rfpujUaxNebNEl4rYjC|YOzx53QoQR{?^%{l*4ZSufp_f#PAPF{DO1HKJ9G_2q zj+s#`vE(kbcyfS`HP?T)Pp=sZpRc~`P}GG(!&hHSLh^F;T4`>-#+p;#*97~kuZbxW z$kNx-E8e>Rrorv@7PPen->5%WV#Pan zT0wuAulwoQMb_;p^x%O7;`YlL8}JYog>ZwXvuJ!Ksl->trXtSqaTFi8LxcFqoLuId@~4`1MaQ21a+ zm`v*d8g!S%-GYo$aZAmKuW_Vg+URBTgSKZV>4kV6LY~0O=B@>Pp{rtU#mZX!zyTo53zk8?SsRB==J@bO$PUn_mu)nL^#RQnBsZV3{oNKWS$ zDy6qo@)`R}X8W==TF^Y=@kIl*`~BnWlItZGKqQ~+W>x#+>qSpzteG{AmDC%(R8M9F z%$)XP66mxTC>>0;#Bru`*6EPG1d7Mj@rMvon>aw%b#0t5iC&W}x1ym$qI^ul-`WHa z4xCYdGoU@IDm4Gae3{d*(|y;?bw6bPG59?m$X{yR`r;kMt`iaq22I?bO1PEDO>2~? z1}^Kr#@nNe%y{*1?az)nT9A+d>d_DZdLEoKRa7R6cvTDIYvnjYG=L?riIMug^ zM9guYc@psy9GJ{?;1KcTi$rI{JCv^B%Pn3g5Rr@>p<^OLm`K8XPr;{ro_;943y2ZN zd({wZUu3<{J2VVWq4W&>_SY8<}Eel&v?b6o_UR9MXRrV zP-fLGNiW5-5fY`U5}95WH&b_?=457CyS7s|ErG1OPkuIOsG*VfL{cvot zX>v)r!Wb*pMpwZ|zprO{ZWUJD%@&d?DnZer-)A0P9&)cn)cbwC)TyeB# zTC?N+_2ZzAP=?@_R%s{R?$J3*(;0ea49Z_G1afoXEwb|nrojH z3x&=A(|pnwCS?%L=7VSD{b!*cNpmMffu(x+%#n~&6?n+9x0+RLefsQ=&166ilS*wT z${b~MlKm<>JZ0XGZH@Lf93J4MMbqAW5kgsu#74-NnCk+W@ZemKul$7w)$f`boA#@y zSpL4|)6#21-Gnn(M}U+-qGJe>3);0(K? zv#>zWVyW?6@y8)i>8t*Ldjes`tJFCX`his40vX7Cexa=Vw|nO!*KC3&h5ITt5h&>o zKg1@#3jg|PQm9&Mzn?Ral`+BrF#o5fkxyv9*k8YmR}vvN60M&w?#_iz+^*h{w}ihV zR2cbK-CEQ_op+Qup4Pc>u=GvfqdO?d|K{|X@Zx;q-NkW8@nN?}|CNFby-L;R`InyD zPj_V(car4W?ilN`AkZ16#T)B;31i$nS_SV6=I^s_G*uR^rk%$Z9X8)`J6IG{_X|(% z`cut-l_u_%{48C>?#jD;Sv-FzJ##vHqMEI=t>~~LcIu&*o9}*q1zkIKbArwboO+AR zv~HKH0lf^-XDwq+z!{ZZPN^>Cd3H_mH$;}Z1n#;unIL=TKxDhxgv!kY7s`bH97g4) zBM7eep20g7{&+>y1S`yk!wUsR9SovD8N7W1Rf}Y4sjzr%lXwG^^nvC+WVm*l0jnHK z*^z7u3&vy~1Utp*Bl>y|YwFcmf8X7&HvWgWS5gc-TG4oLJ-|@l+pF|*^g9v}AAcHk z%#21>G;xA%N%0(vg7Ke(J{JGvZP<>DFN4I2L_kMESjn5efOmJuKCuu%D zszLY4)EzfolgHUth$zbV{hDI{Z=~7dR6HP6FGK-HCTwpT_TEZsiFtgGQ#j6FOiJF; z!jnFk8*x7>kc(feH%%*#So3s}-()$6ap?Kx$WCnQgXqXK35SVeMxRE-hD+1$?8iF? z+?P*V*oqt)9QWGka8=~e4wYTiWy&O3*Kl7vw@TkkZ+TfQmVm{#J{FG18GL9Loah~~ z{H|8#7AsI}T(UWYKFlk{5RH$5LanO4KRcdPEbfqGj*?^9JF}}6wZYH5v@3E%cFD9^ zD$P|U->v1yG+0y*)T&@Bdd_`#&`AqhPtwl=q0y zHXPa~V$MKT$a}g8cI#;CeXWuFc3xWGh?K)WV)3+4cg3)Y)+}oH;W(A}wd8)bQhn>A zxi0cyp6#wRPnrZzT{oB#%=km;!E?ub#Kk5$yBOIa8O4=TauvfbURFi7=tSA5Vb^Yn z%lDRohulTNEVk{dB?kjnO4b4I)OnYm$gRd}Y=Q2zdkrHON8qFR-Aw_~M8wI}!$(>Kbz6;{wg@bI6dx}J-*rE;|AW|B3 z%{b#fwZvFNzrQonR0M+gj>Ycw2s;o0+cl_}LpQ+qfnxYnYnUeloHbqBH zX#%-$?h~oY{p`8sF<5D2w*T_W(igRb_LU|%1$PJKVv0AlB7hpNaIquuAJ{sX3Ajkm zy857zVY-&tujZvff6O z&dMa;$S1=l=PiNQ-JYbm0j&g#d=Wx8G+=k2gZe z)Fa02L?;qRHDsXr%}@T$`pA=$@J(5;H{YGgSuFGEb-HUfP-1PX=<%6L^WeVDlLx1s zK)tY#rMZl@ru|-Z-6lGn_Rl2i-(U@Vbj)!ln13koy9y{rM{}^TC#mq|M7;mpG|Z7x zp7U5TE29_$0X6|ak7G`pP1{YQpEMnHvX`z0ENO-$OiylKBqK(_fcp3ux0-v<0ipb# za{N7SHs+`e33<;(`n{ujKsi3{jF)giGX5+TxJ-_F9|AB{)?7gz~+OucP zd_Oa;In^rJdyz2$z&n3#S8gVqg!@GJ@x*Aj=PbS=i`mkS!>i#kiP6YuZ+5+G`(C4EhcBO`MagA0cB|g zeBUA796N$VEs2HIB1x$Gz7UrKaew%Z)Cj52NMen4#6lxbk75Q8${rmV0z&kn;big^ z<(vUJZ3Qa3o#om+E6pE_>7;gzc1^7UX}f9*RjTe(7uLh*|OT7>{YNWg^0}J~s{( zD6uz8*esskOSA0h=cQd6b9X~7jMZq=!zSJSdi~`;-gz~=pow_<*75PQAy?Ub>_3BY zF>2=XF}#nft{M|;L)HVf)3jn70VzHq?SkfwGR=+%QyoQ;z;z?}8j^@zh5Bv7$lR!a zUi=aFj^LMkX9GJ7c*taFPi`^I9i5Q>MUL6HrMCzqV6=hDRmeXQ2uuBBCa|-t{;XG}#gvkDOg7Ksqy=TD-V&h3ceZ}=tP;eN z%&7IR+q_7U1yq*Bamj^%^10TuLdYz0->jKbiBHTFEFD+23oV{`DY>UG(OsRX952z%Citz5#`c_lz-=E*E zoZ)^PIQzER;q-*wG-$n#h0?1(&IjvKN@pnowGFO+sFEvPgmtP zXa5oayU&M2d)eMc>5#g9T3u4=MHf>$PM{l(k@Q?utt;kaUwA6LA~M7^*n;+LamQ4> z=>$WuZ$WT8*VY0UnSJrd`5w8d@~-7Ucq=8(0pXr_sIX{`LU6-hN&w+mW$s-t&&XyJ zqIlc!)0Eq$|17pkj?%P`^6;ya@Q};H5gXvLxA^b9$R7F_pgl&ZM>`Yz!bK?)+*QjL z3f6FYB;%Z_^viZA&&$E4X96&%o7*@qn2)r)aMPOj-NHXQ5S2TCl|mhP=ASGj5pGH6 zbxLd+>J3+r!I0MmDe$zbq{v+d^84BLC_f`yf~S6t1zeYX@oy^DEeVGPziM@r(t)b#H|Sj1d#XDULPaNgxl zdni7q!6bRN?_5FwyLZ_&V%}WJOTI%l97%qTpY0@SM6KhMEWAGutcPQ1JQTB-2xB7|t%B6+4g3|*lw z7WT7-uy!=&Nh405cy)(Zb9~Juykj8d<@a*A15XGQy;JxfH`$C7tU*`U2_AZYB}0*-YVrj4ha_LqfJb9b0QE*|BIc##fAn+Fi2VoOQK>^vzy z$EyauY7jd`Ocw!si^!c*24{yYmsr|)RbHp zzqP2c9Sh0A^X2WnWY-)Vl8`mJbY`~oVA_+R5li=MW==>81SHzzn<6RMm(3>2W&ls- zHD|aYBA5!XndcqKHX|AHg%JIu`7@u6^O{aWq#L6mpVG89{bDFhglC%s1$bwMbtRV8 zDF;{KO|Yk*V8dY^@7? zbaG!km@HhwG<;#>_ifWius5^1o{-Sp2h04e%+K^z_8dR$E1$4>LJ-!x5- z_k~nKp(P1e&Q*387;Pt!4eeOY3Y5ZqbFWvVb;qls0I;I6)8f0&#*I*kQ!Qp?_P+0K z#X~bS8D!}+0v0(U-jEYam|B)`&Whz%Xf=fgty+6LauBOV=9WHh z>L)bxr_gA)Xztv3YzpQI3Y)F@mVI%YH#)!MIm`Up!&!!_6*!`>7n9Xj#?j*wEa}*a zMY5iKf>O8DW+4=V)1kTUvdCHUj?E-xvvP&!2p20Vtn5;_KxFT=^ND3V(P&zF$`~cy z=8G&DQcZ+}$8Z@0mMB(&kW?2fu-rS~9*-uMJIYcBZrr}{FoD7+^>_oxnDR)<$RNFYPYRDM>$=h z8!ED$d8<=lc0E2^xSbUsm%mNWdtdlLxDhY}K_szmMelVdox?g`*R1L0>xl#JDUjG+ za2!$knLUGw9!GwSYRi|h% z<&TV!yHQ@b5luYZfv6c-=H$w>KAr2QJyLm|XAKfY0M_z3VS1=biIjQp@$Bxc1rTfK z+kNa_oUuq#H0lPx7Vc7yU!2Sv$5cx>AtlmO@C#>n$Jec4riE7XU8hzFDhPvlLg0oA zvEZ^-kfUDI7VVO~tVkNVm-PiBFn2m_xM^oVc64m}=|MYNjiKml@Z~;j@9od$+U#!I@hiq!)gID()CVgZl0z&AY0(b>Pt|A?c zQEWpZ^fk6_@6uGn-0LH#N#TT_q6u?8Q6!^P{JB!&4}Um-w=uq2MhyTHAupOloul_3 zHb1$;Ee@uI{GJ|?<`%q*nlq}|@r9H)P$-YgmZ)strBGO|cdfCQuRS7T_*`vM!0rm- zCNB5FQ$lUYweyRqd<9>qztdv)zQbN#KLBj9`cTFCr(|A@c}!kS`?eMD+PQj;rc6%z zngQ01-2jD?o@aeA0x%p_XBXr5D(qooms)$bg~0lA!kZFE>9Sc@P675vrtMqzs;&6G zpFPsDM(;~LB{Dgm2|>dhH}09dSY32i|KNxG0L^=9w#0h|QTsoy*HE{m} z?U)2ZRjX@`(s*AhK*r|tGYoT>>P6PY#(vHKX7FVI6or zt+xf@RpLTHLZr?CzaQM*{Ahf9cAB+rqgPbhSaA1Dn0N?3Te@!6{sdA$4?6Ow{-PQX z(%}|z1f-a&B=5B;pp~GlF>={Qv;yk&Ne7V04ri38Oyi8BTKdheV3_9M0h>#L#ZC5s z_3awP_a}7^T@edY!sy~iK=$wr)#0?168-}m6H%PD&8%nBuWS^B0$uxyf)XW!H}{|X zreDuz@o!F#Nxo2!@kwnS8n_ldQDs1)Nr`7%_oKv5X;D|64RuhfMnITx;gt{3FeEys z)H7YU)X(ze4&i=-12ZnzuaSyVdlXK3)v>3~9}c~WZ1@C?67hvN;X&uUb}%2FFjS!t zIWjtT?=-6^U^3Leyi00H%xi*DP#P^NA)R*u0axtxyOSYMTf-;zPW_EbUwhbLYmM0i zsTL^>MmVC0{&tlZPzH`y0qC?y>S&qNZDtzp4^zAKIeG4c_bHt0Mu$Ub&|s;BzmpNd zmU0G(8Dc})lu*iNfY<}?h~S1W&1eYfHsapdbv>xK$M^SBn_!*6kn1bym&A zbj#o47aBZ^9On0!sa$P-gi8JSEYgI(DD$DU*yHA7n8rGd!Om?KV2sI(ehG&IQtNaw z>!$Rd5xp9(er$Ay+fh)I9TrOVG0crQRW$xe~+%@Uz93ccixKr$$;zBq#oL8{M>t)q}kgbppTSzjW{ zu=p`Zv=}=#ap^CD#&E>gLrjmh6IR-Oinff@)dZrI5~mM*Pw~2#;G~oo_C5z6$bd~Z zP+!Ae)EO=1lUNs34;FUYAcz5k_#5j2EkYKf;ta9bJWtZ?yoKoSv+Ta3OOXnkgtEYjt=`pS|{bR7lqQ>Q>M&lvRY<}xRE6QnRIW5OoQ zrLd~huR{lop!WIqGCl^zv%-KgD@jwkd#oXD{MS+HH_9VbGR zeDM?)TQ`Vs72qvO=6-jF`1n@IBrsa0b5tDP{GOpcowvTDL}2veNMAvAuPF=wQY8N* zdU31^tbUpa)`Tozw?8ThN4_$_W~GFKb$-7hdBwKP_k12*4pqO5|qB#GiE!ah*1D-1J**1aXJh zhkBscPIG|Fau$Kmx}VZjS+L*V@%~4M;Z6&8$A|EA6PXjee5cdaGLL268Z~8n@)96D z*r1@0J3eHt!NkaL4`YQqYLFRh9=T6-$B8ho5kGE?{>RskvXt{uG!{fZ{r(DNdX96^ z%JzFv-p_-(3&==k=6C;S8NP=A>vvPW;Y8PiLy>f?hTQH`c7}kP4XA#$*@lhJk{A)M z-n?EVUxJkPnES$-ymQ^hso@9<#H(3}QHgJ5!nGpFfUlK07~(L6lmK>A7eR48Y^2D2 zkiQ({FVhlD+@jD*0v8wh%Zh~4%;8~mnTCpB9^F)6L5V_$e@hK6=mJ>J{|d1HHwcX@ zf^Thmvlvexk{I;)cybR`g#8?X7Q(l~w$3Ho$J0raNDBoHj6fqXHrJ!Db0t^17R+Tt zU*150Ci({LKFQULN+n9ZF`)v-$N?D#{2lC5Z!E!gmU@v!h^EDd1T|6JxYHEZy)z#q zk>#<~SkPHROYMEC613|8dk}W#DVU>$Mm88SJ17Jfr}`wu>C&PC_yd?Q0eToi4P5{u zB-+&fryNK!gbn*C;m6=f3=jd^I+C1lAL`$Y9_FTi0-cI0en3eU7_H6Gfu0pbq4U~zK$t$&hs&9(>h3c6Q{r4uwmG@B zgJ4KnV{}mm9}^eMAdS`1ARQ`w=kQnIHj&@|O9g6Y&<4ilRnVh18K+=C0Ev}!5}sN% zLN_hy-=OdY&EiW-{nEJ}cpF<^y))?5Ra2dE@(#!`4yACHTas=6P`iLHPn-FeVYKM?oD2LSLEAyaWvocOxlcqtjK+neBLP7^ zVFg$komy!A79I!&!_f7`iPG8Xtc8;$rWly19v}@H4bQ>>ncok7SDREH0S-)>X}asc zn?RjlWVaUrj32I(nsNKPd0iz)blqq7SvX##99juta5fnA2#rfzlv3q+N(>tVAsCFe zYkR2Ue~N}AFKQP+JnAWKM{k7xFTv_xPp0!d-gv;LDc zfuOmJE5h>N{=jAoWA5^jk88oeqC`fQ5>**qo*8p<0Q@ldka;x~H-7Lo{=tUZaFXOFI55yN6A{^rN!#q<*Vk;|73M8{RPT?X>mrHCB&n zuAJ$g<07wh`KUcAf*fYQp zPL4j`4R2UsRAp=%}-=!lmfp zCppbSY|S?OrzwD9GAejM>?Axq*q!$g%qA%20 zu07}|SPquMDbipAkRt8i$zZ0nAuv=_8UQ*zd)t>SHhNygQCR*P`>1Zd-l+x9kLz~^ zGyTsNu6pTQX6?tRoVNiG`<;Bk|3d!BMTYkz6$ z%^h$xRad3=zUddsdE5KTes<+wm*yD*1MWGtt&|SK!gHw-;GEHVwG7!Tbm)8F!M8fS zYI*llD+S2BSnJu`!5~#Y5alnB0sOd|n!BPd|H3T(pWwwO?!WK*7sc^!^x_}$3Vik- zNBeu>|0N**#}WTQi+qy$*Gc|`fcz(U@~`{kpFGK5BISP(Cja+P|1sSE!A<~(ML8Ja z-_4%-IK}*V@Y3Z|0!bKUYUi>zu?rhAX^_sq5i8m;7iisrQW14Y(vrOScdaTAq%?`O|a zx=ver2TE4^6K>n7oPw@*lk0EXTtL>_aVY2oV@FjOFG0EGQ_*oasC$n$pT%+Sy=2e7znnkf{xkJ)wSRG#p25`TX5NNbP) zw74?h_3vx{uiOBu-cnHYh{}xiM*&h&2Q+8^`Dw+6SFUz)8L}Fl?{Y$TxVb4%;+AfE z*Z*zJc6>c{$zMNuw0eJhIB-!SAFyqI{|Y+$4{Q8yQ_ulmM!t&_cuR1Imtx77_a=vO^2y+S+l3T^IYC zhAFR7hM}Q`$LT54BBz#x6@a?8uCxLCYMHKT{>STAGOjO(0w0{se49Tkyv^RNUNHm$ zDYh6fr%q`3w8?-H{AiJqNH*~9YxU7iC}NZYgK@I|F3WU z$fH=>+U!_HLn>F2cHCv(N5~9E=^``g;#Ja`*!GOpE1RRoJ!S;=sEkzC1I0u#cQ4zo z`}2;=eJX0&A*pSk>b1Piq==23UCx(LRVwOVg9upBJ%q|r!nLDFv?It}k?ANzAmjFa z4ov;}S95z+Og1Z8Fv7knGk6V+t{`-sQx;lyMt8dCtqlT^!n-s`Mo%XDWJWY*gz6ND z#>S<+PUi95Pik{E<}dZ~n%dW*3w2euPYTKRMZ_(dFEeB#+h4mmB#m^#)F246Sqo-s(7!1@QvU z(J)*&?<^7$+ach20WK_d#03bS5x*}q94Pw%?7Znx=fW!1q=z)u`cBb_(&$Ufm{Y=f zu+`U4>i=4d|1k=@HgHX==?PG<<|al+CDqHVi^c$Y(v3D6$4cZWzuzytVfG{M2lJc(8xx@f@;qKY*V8;7oKS+&!ra z6B$^f-feC4Bq-k+5#7o$Upjx)7)dmE3VQl9UU|)#s#>`CN!t9jrb+BtzRG= zT~zc`x08Fh6$KKfRpMf;)@UnOZ^W-r;Z3t>Ha%vtK8JkpVEAXzYMf2Hn%7o|>@?3* z=fXUHHvu~bA6G8d^~;_!m%iuE-p;D_Yxq3%mr*=L22c_wwusPPfh_CJE`ztz=+CWl*5P1G&Ktw+A6{_|fO+-SHx$cE!usJR|J` zn5*?~pu73fZM3_Vkut*3j?k=4Q6&0pCdEU|QOuP!=ayO*NORV-@y$oUx95;e!~!7r zGwc3>*0;LEvw1y>=cDEqJM+on>~&zU1M9Ga_XS_bRaMe-Zdq!-kiAK`n_h$W|>I=~{kuOmukq40v8x|vn z{a)I-+lzOSM3T8n)M2)nVHS)%MmtxtKs-WHEf|w1iD-KD!+pAt_vEv1sYp*X4*ewo z5YhZu(nKFqu^j!oya3Vhqm0B^7|}TM;|9D>Jxsjspe)eVE9S|5ND5INQFUE4nyA!s$#uzaNl?2D{U7(CO*ddQ zF!D1N9A7cCFrFM&?h>7^mLUaagFPAj7~yKLs}8;pcWk}LF~n6)e}eumK6&&@(_>AFy2q(qWLx#;czu?HVD#P@+VU^XmdKphx4KH(4#ZDbPAK1ZN^kQ`){v1 zS09qu_-*C#OhY&9E*D|??QYAVKnYCsK~XDWSjhw^W^A0w8;g7WiNX@Pjo*hfphG=k z3&DtZnhWj0M1YLjOd&03PU1ccHdm3{tqMYRVgnfsXW>mUy72M;Fbn_k)hBVFTp5jL z2`;R)wWdK-l7y0E>B=d;uPX&hqe_L&QZ~8HS$%GC=tOFwf1|L5QOr z?6eidmWmb7Xy}{?eU1CtrYVTZ8(V`TO!P_Q#fO`-K2U%NJJ*P<)fAxqI~>NsHbh`} z22omsybgj~kbpo?WjvdHn;#H->C5{_MvQun?Lu}vAR)~qE`GUDe$x={D*|O>UuqFp zbe5p@jKCD@NrN~^$JL5WwxgW_bpVpnzOw1na4(`sKQ(VCWY^^4)N2VB4r~4q%`X1! zDF!mmi#(CG18Rsa0FfwMgQ`VUFzDDTrM&9i7L?`(^oR>DZ{U{$uzSo=hEO1k<{*NG zkHVMc6bHg*)p1m?^-t0&cz>u;7I#`E7$()sL#*{jz}mWcRjNs5Se85$V|(7Wi1=ej zuCWS+!bY0N@7=TTgY@}au}#8a^j(K?IUMmw!5i>_^a2{gVmX^$u9s_x3y`#D`<42e z&ai^Tfwpt`ed^OCeS;SN6z_}AAEPqWT^IE~GV6<9`uuF(U2Gk!wcgMfhrf71qn!4O zUhQ?)gA0rKcp)Idlp|pJG%(9kdWa=uD3lJb*uz!Txh}SfK0FoSN45O*+2`RCNS=ce z8nj25Ol@|Tpn}`t-ud29YWmVlkq1zy@k$U7l1ipwIxw^Oi0<&+(2tVACk?bDhXl8* zytP2|k*bWLN8WfF0 zSKGsc*uHTNSOl(wr*Q=L=Nh76AoN`n(HWc8eq3+FEBmX_iGzf#;5g6gM2_)&b&4|g z8=_XC;#_b8>5uqu6NMNt$2Q3;M1^OG+C6}Cae5%0f#6tdo!MN~ zkOsoZcF?INCiJXs3Y5#n-cICdXW9x@FezenMXUjs4E`e|0f-U$sfFh-QOtZRUw18v z%KDIRxwQms-5T>Ez?@9` zLIUd@m<6mE`xU$c;p%f%PMa}ZF{ojHb%^0GNC%7E8(yW$u<~}dJy6_~5he^UI7K1* z2suA0TqlwPs`y%2kKhN;?AzY!s`0-IV7PvJ3mPyOOXRrlM)qyApIoGBa;mdod}z#g4Lzee0l?$FY7 z{JClPak`+q2#d9mE8ydmHP%PmMlkYacsHe~ z2uqnIcan&YEZ|`HUtmJ}wzggq4G|s25_gAJcoXm}ZcC)v5@4&KVf!RY$WmXt^U*{j zWuz^2Y~9JqDG&uee_cpegEcbv+6s;HD-ft$hf(B$2M(Wpv~C6WC1{TzK9*a3B~YHSS!2nD7HGdmsdm_%X9uu(QAL4ug->54DX>Fx$;E2<^iKyjK}8 zSNbzCH@trF^e1WAUVa0Zocf~0*3NCSZ=Z#}L_eUu&s0dm4uB3DR!kf8wUv8rcC6OK z=N-^YOe>M_hB-^GHX6q_m$O^cKzB)co*TSjqYOdIy(1Tv_owcx!j<{aixS)`bn@w0 zR`gVR--Y|-cVzRQ2EV*HwVL3ApWQ5b9}LDh1L|+t1#`l*bSbM!Lg>lvlZ=9N4Bhyn zvDCAjQ`#trFFAc+xTp`Y0*Qlo_7{j%P{}9g_0p*EyW6xJo-Dn-5 zK$WW^1BzG#n5}1D9ohl;{Lwg&Z61wuatnHdIW zkUup7%UX}`Pdwqv-@)so3TmK#J{qJd#$eVT6+BDIK%xaOn{PA9_P50l{Gob(Of-FkA0RwF zaL6}6Kfxfn*l)+~ig15@k{DPi_#V{pbR4PY4`Bw_X-+rsI3Nx2lcvSb^kE5dtuEcO z?vw1rcmo$m42jcv9Z<2TWGr99WZQxj`MO1dh)Nu&_~a^x$@vUzS)2|C-OdI(9ncVK% z3vQ3v{X@O53C^{G^s6JBibp_On>9>%5licX97pHwKfnPIa;>*3MK9fM-=RrxiJpyJ=lUWO?em9dEL+uQR9{c?rC);|tO8X!)&RpIa>YFs0j6uyr1PWV*+pR1t^0Fz3--~r^U+IwlMxCK zmZryeVqRrW@4+pOE$IqW1q{2?LFvYyLoCH%nq%Pm^s1l@H1c%?vXb{H#fv$F7{F2{ zx^bs-+=spnv(Dw|sLwLP12N}58*XppBHye66jtbnh9NBGu=xQHH3*ybjQIX6HC#Le z38UPV6HZe)q9b#(#cQEo4)fq9M8!3V-5v0Dou`7&J6+Kdg2fM%8f^HjH7i#$@CiHt zDzS^$3aJ1hyaK@eIF0=YvX8xp`}y4yID#_ZXHf1~#@Uve#JXwM3|zQ~X1w3@6&U?q zIxSI$rx*tNL5pCBP2U>_Pzz9IuBS@^ywAoEwENnZ605G{*#xNqjN#)DzbpApntOeM6lbFy+zt%f>&$HyjP!R7uBmnu>lw6K@*c&kf1p8jh=^e~ z4uvFlI#@D&3-gTtd??>1L!$bSAli_q7OS+rpFpy}24!5l|B!~q{e_@7pYO ztOF9}5^RO?bn-A9154*G!i6uWWH-)-?x2^OKd)Hf-(Ij}H90P8OleN|Ty3E5Oj5{) zy_|n(bRt6Pq25=d>3G%07()h0n`VKp7Zs0{dfUwM=gH1o zhiB7Y1VRYS2J!$lh`wA~)xPWA^!sJ6r(2tpSU!X2(N&M5vTN;kd3o~i`os2=H&~dy zQv_^bDY9jcdP&^VstG6~?8==)U)2GJdU#sNUodD|)C_v8DW=c1%L9YeaeYVAxi_WA zowa4THpEM+!>pys$m>I_6t!m(ZhPcJ|B=;Ds$ON+aS9P?F_4sgwfBX&wnMIVU5{ic z&O_4bbq@`on0rb8kwagmTbZr^80FO$wvWC0X_K_Jtjxdo4Hgt+vfS=f*f9310?i44 z66jfzbfUP);}4AQBjooN6<=_is3~yw^%4yvi75y}9}HDfrD%qiw#>#=+)i@f#4`V_ z>JOfdQ=<5WO@du&Zna9kW=HUT-<-HdfxJMZcjJS&Bo^L9bmaDUkuBJ=pX*7)(UHxK zBNR*DA2B}2#3{0#A$a>^6LDz=6SGg*&9*IK8tyzy47#EEBs-`M6|htgc9{DeSrg?? zt@{)n##>PNb?Vcj-4(hA1(l>RuNHogo}&nHYhqF?2FW}wR8;T=6I^_NU`IR(;eQ=B zXnJB`BnC~3Z1E#1-&P*v`PJ~%@1_9ONI#E8lp$cjB34sbZduqPK$raeSq#O*5z>z< za@|PNYac(E&sOhey_8P=<8Is*5oVf$KM%1Qz~Gz=PLYytxF65< z1Rx9P+lu`BosAhi2IM0&a!;d?qvv0=8mHS9%AAcY*0D31Jxt`*?L6bkW|uLMkq%bY zNU~!>{Rl_xjJaK6Ce_%ITs1AdGq@R*zCYcfxxPXQ>h!HEJ<8$L7d)+?6E&=Xr%Ul? zGLhZi!wCxAD+7naYVC073h=v>O6eJjWf|HeGm~)JqXR2;uQr5D@J%MopeBBCB`KjrP3oDabH1U?;&Sc%jAlq1 z-;ZY}5Bu{My;=rka)wJp%?sSKr_7^{9tyZs-3=4_g-iGF?61WlFY)?LfNy6ac??s_y7$AFnvSyr~3goA={Eb?YeQe3_QV!<9ZiM@no3L8?N6=;jtG_kXHcG|s-3k^z5b zT5<0Lf6jfFm(>o&g3nT46GsP}wxtt6Ff6uz5c>VZUQU+JU!)cVDP*{tm@V6#Wxo4y zc!&L=y2JY#6X zMA>;vZs}0(B05_|KE(($yI)9}b(v$xc!8?99*;fVYQtjSbIv}{vcz|_gLje*w2BZg zb)#8JUC^x9f#xEcVpJ476K`R^K;@mi*Hh-jXh!J z8fcB|$mjv079JU|aOB&RG;S|!q?wQEj897A>1|N4%g&Aq)czNA8yo-!`b5x!2_At6e{%vMc z)dm63q@m@APS!`*q;&tCO;pm$9hpum?fq`_61HV0C;A%cldh^D_(L|y9Gm#~%-4)0 zu67n}V0XIT5s58`5%4;-t>6nI`k^Jn;aq?3MW{3o^a^uB5;x=awn1LM)^XVmO^E8d zl0I&ui`|S|dCgS9+)z(FBpi$M^ZPO@bO^M=(ElM2X0Xo_e&u0o9}6b==!x1nwpHEl zC!>8~XhJ#Js5$lib^9j|R>FyQ?{<#yzN+>z5U8+NW+%&BsHNoyE@S#ar!^&x8YIqSXVkOBw zCC|cLUWc=T;(}GcZetU3TR{i$a8X(3&D8+gv*Zoa$4jHUL3IZJNYU};(nRS@?}yQZ zY*S#Yq7T^`10N^#R$G_$v5SsM0U=%R>>sv-WGg*W7_G81zjtxss0jJD^8WQ;PW#$F zBH*rhVTW22FE2Y-_p4@hv}H5rS(&mW*tSK9n*3d9Qt>HW_c4N9NB z!8a-MB>KJ)!S{O4*w9X!4f{jOzfkM^8Dd)gS37#fqZVnlF3X)9 z6?G5ZSQErj>Xy*sNzrOvj?0A0ooL&m#Ht85g1Eaqyd_e>k>-W6H&ip(LQ}XG-U|AYhwPHO8*jGd4UK0H4K%#SF^^>b?1K_oB&-n-isD2$$9cwMMNV8E?`J0F zxu4IG1qM2l+d9{ZkIBz}nA-fhgP7uCLPSarHGPDG@dM;$U%VlE&@S>8wu)8ST;KlC zlKG3n{deBk04ibiaIx!}SG>|zefa^|AOiVDri1xdaq!u0DWX8B66^Wjg!A1c0Mf4{ zp}LrGW)}7itae1=(gInzS6!>f2j2_PnP$9I49C{GlF*Pr!YY7gTpc4X@(CNE5bJ)o z2kVKAUm2s5m+_6=o1k$B-*dRCYvFYG8b4sXRTf!@2D4l7i@1^Enpj_$GE5>SdPrNVt?$TPiAuZtT8QcC z_E#D|fhuR$7Er+9^~H@{lvAMgsyiD2EPdCeYD(la|I_y*45jn=?D}ltu0x`I2mBW^ z%)Nqkl#%8|?TRS_KR6Dr=#UAGoka^@$(yGo%`lY{Su_R@^xH#Hc2*D_Z2;f1la;(N z)y1=u(3IEZ7zBhD@IBX4$_%c9_60xSQTj`jKH=`o31jt86F0(muv4`aR|S}frVnUE z676KXaXWK#5^=&MPaPG?iRUB8+g;W50~v| zFF3BL_;sCyMITrAbX-%?A_*66Yu@GeOIy=+@W)=>_aDzN%JG@r2Mt=s+Gplp^p#c1 zdIgQdC?hY9x2nnDs!t3so1T%mY$VC4=X${3ArA z@-Jp)m}fE^oP72Us0y{-l&tw!0V{2^>!%7=cX9CM9)KenN83`2t!k$2F`P?t^>9+~ z3&B+-48@=UdOs6n-M04zG|gzP`|I9?#f3hl5h2vYgQpG{UXjqWixzli=XjL#YhE|< z9q@QM-C(djc>>gcRvn6K0&!}j&G#ug5*XiJ}%>?>(&Sz^OePrBIK;J3+| zgGWO}xFn@8>-I+sw{Je`eg}G2+y$y5G7H+n3W`3cCe#Elfw|&itnY;aCjT8yktIOC zC$R7RG`p?oNIObdcMgIKZFuXDb5V~p7 zB+sDskDlwatE?ubZ(DoSP8iSM0S1%P9c|Y0LZdoHcX^6bUTtK5qF~4QTC5xb)5x@y z)cF}4>wL6utz_CgmH{oww$0@cFtrYZ_zKo@%~V@B8L1z7VKLMltrPS<<9`JIdBck4 zK|+30-%QYdwEJ;I!d4ri+AxP~&3ZyXl()6F&UW`X0lPywgKvkA!o^>_TnENtPQvQF@@j!WIzv+eQUN8*!x*i z%?bB-`zRThaKK^Az~r3yU9MUhsH^MD?oLsBbF=X%uUqfhNb~K-hF7*#>P6LetFjOb zqdi&xFO~7hi$vRgD6NH^{9xH)uk%`zIN$%U9ij8SVOjW3`!%PD>2HhYg5>IJW#I&Y z5Y2f=OsS9^iKyri$)i0lVzpXW%}ckTq7B?a0+=0+v`VuJ_n|6<;{2%vEiPqn`7di! z6x->eK*;F%w@MxRTrp9hv-{b*9++0d~GWIVqL|GW-@r8&L0Sb}c+R$d}SJ!=}Ck0SzNMfz+aDEtBeHoLxMEGGu;VEIdC0{X&`Gsr&gD8s zh~v#t&e=%utwN(X&28WJMMJuk$r((}>l2pm;~SryC*c+a(<%(D2h0SIMd_9@qvNku zNa==_I@dJZ*e3K{VEHj=1hL7W#WRx#_Y_=%tm(EZC(+f0xPd`M zi-h&c7SFS}r?#~|fXK-ZO8Sa1^KQFfQX=VCav;WTP|V$OrQj_Z?Yo6kA~%#(ZB zXbHp$L=P$5AN=+}WLy-qyrtQHvJne)@wCS;hRo$%A>+eS0pq*8z(D zfM4?#1UJ3{i&~h@dw|`H%-f#zs8ju+tzA2H64uUhgvEH>FLamone8aWmOs$G^u7su z%za)S+7r7bN{zhqbjiDd5N;LY@3rv=hVT{U#_7aV0j$d$n{N-&4U=ycq0< zZJ@%s({lB;#Q2r19@2NJ93d`U?VH|>u^2Eb2G~6Ue+ch?rY^jlJlych%2;19yfI)4g&T9pBuiPgcnU^{r>OWhIYdo-TkN+2 zo0~SLp<15qm~%scS%i;I??v2wv;WF}zklM|GUV-tCUV?zaJ5+(nK6;iLL4sD5{nKP z>LWvAT^j{uehk>}eBTAZK#5(7yKkb41y2oYPF_tt<+kN{kh<IRM8 z212NbxT^ealvUGm9&r)+o}Wc6tY`gUSa%;@lE~r4LSN#H&0!qHf-+;hdxMYRfRrnr z2mmH!eH_^IlB0zEA8qdOZXTcGf3)Op6O8cPC##T9u?m{`)fUrzNNTZca1C_2F4LW_JrKXv2(pP@JBRaD(TPNCHg$@)CvDu z{ncU-;@GZOZ2csOZWCiscw{%}gIRnS5jl|~mr8U$|2qGja~E$hjqZPc_~%+hfE@i^ z=D->&wtFWQ^^T$`Em}4YHsc8TpN6p)Sc*%mH~_gpnEvy+F9wZ-4~`TJz`?-k^H255 z7qg7Q9uKwiTj6@tUYz2iwbE*O{{OM|)=^PK-~YGdfW#n3!+>C*BHaw7l!AnyfHX*h zGz`tqN{K;8i*$Fx45@T?4Bar)(C}RJ`|01G&suk}Saa_^H%{EM_j$edJ~2i6ev*p$ z-H6NL{tfge2IYUY3x89}a0?s6pfLivBuPIg5`AOP*|&KjB2x~_n11yhXGC%a`v>03`5T6$2j-X7`MNdM z)vmyEZBmd}(apG5KVwAnZN5yATeWbCAAHgnk8^XKl1}J_t=@=A;ecdw(n@@9T08b& z)vOL@Db2g6cCPS~J)y+5Q^#r<-HH<^r1#F>1x7i;3L z@u4QBIWx=!V(}*i$=?u-%Az#?m4&3)8_E37+5o0m{7dd!q+p35D#w`(ea0!}yX55z z+>%S8g`z3X+Lbh!)WH54DDyP0AghpKL^_N{SS6CML06aW3W zf%YrgJxvv&FMg(7=COK*KlANS%>nAdW~ft7*BuQP7|_pGv0-wj={?_;Vc(Z8eiHGV z2$+8Pb@v}H6V$>)0#SjZv%wG9_qDOjp=U z0@*HIfhsS5zx#I7g#8sG#N+Ad2C0fd5a`E9J|=Np;C8m0$Zs+G%&dnfxOK_z`|;L* z9_ZT4|F;eJ?Rv*`1%&)#`z7`Vp#JYY|JS?#Gge^y-ItdFf2Pa8m*ZdO{<^*dP#j?G z{@LIlmOtCyYySpd>wi_s->d!WjDH;azh?kV`JdZAAH&=Q#^sH9alTw_wmYcANG!%; zX|mo|Kmyr1mQS3w2WnF}()E;3Z)@4N{L(ES0trhl$Gf^X-|5@kZI{kh*_x>2-7b{d zxE=ZB(lYT>A#!GH)uT>p4oRU5wFkn#V`ir<%dJMYJr=yswaY5)5sX(eK<#>_tW z%g%OPD|Kvq&Ld49j`pR2D^ENezj_?$UY%S`h@Yb*Cd+Nlrt?Q|z+&jiWww}g^eU^5 zZG^*Qh1FT)vU^6j*@kWRp`yg$klNKGgN^rcoS6f#vWJC6A)acgN~OU|>f@U{;c3wM#}_JZPFOF-4m$mF5(uh#Ro zEv957tqv&>1E+mk?UxfR*Xspt>q1fU&CbjG_B}#% zm+yVzJGUo}D4lz@-fNa{f*;u09(amg96Zq6So2hKb=MQc>~=?3Wx*o5CeaUPzVp1g z;0GNqUi2}H#%`Hh{o7docif$-KqIm&ztBY;W-AA5ps2t%D!ixaXW;CP0`+ix@exup z()!UXXCvTA^3s8bYI9R-a{`tozIO^Q$pK5P;6C>}A=||C73;ytzE5_E9xMmv@;Eo5 z%I=-#p@f-Vpte`HrfJOVr8-KAx7i5b}rmGk?=Vs#IvBQ)jRjnYVa}4XI^O# zka**p(T?a@pP0aLu^xsW=dWMFFs{nER=rjebN!h0hJGY&`~qF6{@DL(P6tG7CJUc; zv#lHZvF-$foqlgbeW)A-!E&F4(?)dssyu++dG||GV!%>dDiky%?0z-Ro5+9&y=9Emd$Dr8DM*2HKjOpZ>x-IA+efbUTJ4sn{>%IN%R zj3R!{dX4(z^dIbcB^A1SSuwAKm}HtCSQ*EqZSy%vtR79SAIKQ%l}zA|e3`*NP42{z zXpp0waYByb3-0%`p0WF^f0D>DcDgE>hGJTh?D;dO(Y&3*UcYa7?BAs4tI>i?wpXm4 zmJ&y|UMQL|TKa?7lSexT=;5Qt5@oIAi5sMauXWW}lg`}E=q|F(UakDzpLOvpsIhe; z;T!6^Xv1)YUuc&ZE0)XQL^7gdGIMscF@X&jXgje}Y-U3*3|s=3<7J*OM3f1T+DPte zGHl)6nek-QLNjvxmQB)GW>2GaNfNLxoZYJtTV{nwyLD}Z5! z{Q$)4^T-gG2|#)}=iwYb(h) z5aehQeIEVBfUA1pTVS!o6%)GTon$M$!-Vb&FEoK6F=aeSp`C|9vW->o|> zs1=nJDgJfiH8;t$uWel6?~;1=&817lyUxPj_p-62#2oO_pPY9&(KT6COHioXDN3D` z*f+c&R3~^C+a^GsRitDsn)=)Z?Hj~j=%0TDrN;)thzpP8aC|avd@VmG#B+)tQ=U+R zAK^`QUTg~LX>@FAA;k^joka@qCJR%;8syya$5*;SO>P0%qRdaw2y4j!$+S=rIMzz_ zp!^ViQV@u*%;JXSvtDAz`(-yt9EXpcEp#RWzGcgJl4;)&zRoFzIV2`M)n*qkNav`m zh{OieVspJ_@Rv@VSG35HNw7q&3tBUSmeV%2-sR)#UL5b0YFt+K&^9g-_lRxYM0x;F#^EggdFZe3S8^yhx{Jg=@nLWBp-#u;!@XeG;3Z$`63Q z(%D46@6)I=Z)T~oo6Wf3rmI-FRAtP{y0@_yEU(&n#tN4W8iSVB_t?pszKKE8Z8*AZ zxk1jpt^7}ti>WBIFFrGg+P*lQ4IiS+swVvbcI0Rf{T!C=QaR{GX9`>nC%Ucp1WMN; z!nt3DN9Rt5-B-07QbyX6Df4W)goGj0R4gyu{%c~;6OtEJK}FS`74Wt^40fMQ770W% zzAXiQV=}X|1Ru=zwWur9>xJEq!7(2ZCc5cOW9^J5L;Q>ZUY(u~G2p@|fxSZs^^cMt z)=tlIj`T~vGu^qFN`m|}o>D1b14sE@XlXaDoqakK)aUf_A|&Z@yTyh+<>@Bod^hoQ z1MnN%J{e~qi)>4wg~Vn)(X5G>1q?era}C#sO)CwU;|;lJ1sqlS!y0c92o{Os{x1;{ zExH9hOJ~upv~zZS&^{{^WnTV1UO>glA28d$YvAr@s#*szMWYc@pyfKkr+o4$n&Q1C zx&&hEnE`;&IAxu4qaIrmyhZZESXU*F_be&7JL$H%4L1dWws{^e(^HD*{5#ki*7&s6 zwIv2%SljQCKPpB1tr#fQjR$RS1fbdXhVR<5E=K?PXKq}9Wu%(F4*1+Zdr-Qa$) zlQaUWa|y}HF^)>Q%+h^9DLu(X6WxBeZxzy1fAathsm7BI;nbMP{gV1@g4ok)>u0Ls zLQ zIEO!va%$0i3{E|_d7l-55$!&L7z~4^`kOQYBZKAH#l@USt*kzv_iBuwOmBW*!~dq0 zw5j7*+%7WNvMzvHP#9X}eIXK&{2PhvqSgGucjK|q>79#!E1*fWrU!;}iG&SvKP%?> zO$dMqG(oc4!0#*AvvTI>4NZ!LfN#Z0XcCB@tt}SxSUY9+l7fqLJN2SSBvtT@^ug2T zeO1~3v4rR4dw}TIq+SYm{h_{CeCRjOs<0u)i?+z+pC8)lr>Wm_w_PL(;2`e>$1^|z zq8X8Mo3GpW1-6S9XY9f^act8#07VqptE$ZIrjJ#Znie`6<;BK%71hOaQYI$%UNm$e z8p@QzH>P@F8E32)`@XzqNNC{Xzm`_C*`z5o10zx_h;<)&I z>8-nz`Pv$Zdrg3VrbU1Q-z?9|ok0k(pg(B&A%iu}M$;NSKoBe4>D$IcZ(m{%ICRs| zpJYRW%H5=|0B?`mx^LiH_nXg++n}gJ(^<`eyU1)R_ldS{6qcA`mmb0L9{U^?@FlXc z$yU|V@ARgG^_`;NF1>=a8G=;M6!TvLp}r>W*e8ScsX`)irlxS2J>`ORsdEL_T+=9#e8n{UyVdbAQ`lV2pt{}iR4^td@H zOy;#LU-H`GZ?fhJvW;{QaWelEmO}_4R!cJaO9^TPbYxd`*Zj_XtG0jt;iCB`2 zue=-n%popvPxg;1GP((8I}KSFE>CB^9CE?{U(Tw7j4#;(lfAWUtck>g6^F(68PHTa zU#XO0ni8n1lyAnuR~x^n)Koe?Q>E`l`fkCU;1ivi6)QFeURVl=+BCkqM4yR%|m5c{Xx0(_z(r{xzK2~mp z{w7$Hdf5V>vP&P7kw*mKQi3Im`pS0| znstFhM~|T?NKI`wVpDmX{_k_Stx=YYcB=F#2OPkth~S?x5Yy7Hxf%tK@&q>#+>I0x zH*AvqkJ!;$??g6II)`@&09SXyQ$tdQ=QK#Ku9!h?p_+ohgWKd*0AO_cV7?Fe=&&3m z&L~+@jKYHBrepb%j{Q3O!2v^Dnh@hm+itc4eqYAfr%b(kVlM;9{6`ftcN>5p*uvx* zmUYmThsJU5Pe){D(@MpPg}243S`T@`!m-AZg}~J^Ya}1t>@I3Ivg%wYV;=R)pB~!g zLmaF3u$yjH80*g4y~dm#3x0B+0&5iNT9ZLhPNDMy*tfqe($9A0)6vqN*xN;35qBDS zJoI-k?h^gQE?*?_x)}mP>-ODM$5m``Zq{68y9$>*0R6g26TUU)1;7o`!YpiPXPuh~ zV=1v9AENJh#7@!Oy(6iu(zy7<$aR_ruQAI-;=jNQx$8q@FtkQm-3!)8E9=s7SMoGv zCHy*n93+mqPhpsIOVX!HAquVrBsci!3(`A9=7q0a&mXa#-f&6pL3UK#$?1M<1Zom< zt`Nz*!wohM;I*Y&Gkinr;D>Y7BsNBNBp%%={N@{@7_nSL{%dDo)f&YYg7|Uqh{=kJ z`R6eisaYZ7dzIkp>du8z1LLMM^kX|)l`j7dt8Z1W>eF_Y~KUQQ=wzIi74)))rr;5B{xy*#M^O;v@MNuQKE^Ybl(450R)JgT* z;pJRPjl2x~8VAVkJ-H%b3mt&1IudExt6bP@<-7-=@BSHqAU@0igUd(!iX?#)joT=1 zIv4k^F+L}{y`h32`5{@6qkhc=Zd07tHct2rz@Ru1VNT(PrTEi)H^$cd*v6u}mcJxt z9JjR~{?WM~-$^$K6o9iVph>sx9tfmc@pU#5*=XL2>!|};p~#J&NtXy{*<5$O*RnFs z_ja@huw2oVD}WZ#F{;j_!n zFEMbbUNPs#xl=;Qmv#6{ki=?xfsHTRYs*2%egj~n_&nDP5$=vmlNk%dT;WoLac%B>tM}1aHa9_&%}x-xU8t1;k3&sJ zwKBW$t)b|~>Mgzr=fv@&uX^|QfRD|RLkD)GnNO+i=3{J9tI<%C;wR8#lVY#aQ=V`) zE>1{VCJ>pc?~&ZA_iWgM6|5ZXJHgaD-(~p*UE7oc6`YjWBiF1vll&H^LhwO~dFRVF z9U4NOI?aiD+84;bROZUmKdT^rXyV;5DMkC0+n-EzHNr8b(b@pf;_#08-W|SXE>d31 z>Vk^SYD}mYgCz zd9DVHA?zocaF9NzA^3LM6vGvF)omdpHapGEbF3XCkeE-0g)z({FJ@1iZOgR_CWJ)T1#LlFJ-<%*IDZaj#a(aWH0Q(1?ODBH86Z~Z zETb7mk|pqh5`L%$m~5-f?^~THu27pHdEHE2$7{JPsz{rV2bH)K^u;XnuECGL{qF4(6BpqXGcj`8EzfPU8h+z1 zX&6P`NSF9bDz0uGx<+BPRJ|pX=^#T_+9Y2SkWBkP>sSMM4gtnNf4fU3&E?!US*$%wgtWq*d0b^SjjbOOjH&J$@G)g(`vya85!;l8( zm{(b_5036y86X>#EjMw4#^9$4GcR=iIOpX`b!(YSXgiJD@89B5t}bFvPIgPu+d??- z=@+sXjw?;S$*@X`Gl`qtJv6KD@T*p=ANpC%KHWGn(I);*EcSi=#qvX%JPH$qWC3Xr zRI15radMYemwW7F`q|4_ikiYaUCz!8E4RY$`z0>3Gr!R(Wp%idKQaw0s#r&4=w!Ew znZLkwBJ!H^Kv?G~sOetEEsrmz3zHkOvGWX` zq4R}<#oX@`RNr&5hi?0)#c>?3Kh^Tr&^Cy_7_2a`U|ZR5ByAjeGR*qzpe}{TQF6jX zDEKhwu^d|(KJtNuaavvl;uePS(hJ3~?Q4ToZ_k68rkerj)6PcX(s&vD^8SQIm zN4gDnMn=f*`lQMFwsgwUa$h!wd!z`=n zvI^4|J+kCW2*>P+Ytx@a6x(_McWK8wNE!Mp0YyGe9lww{gcc{@5DxL8< zl_M%*jPB~8-wRR!Sb5;5fo4tWGjRZ2_lvjpVd~OJH3-Bf!ljL;5O4Y%k|R(ULR*j` z15ErS30CO@`l^E6jcw->fag9>xRT)ksA3EE4Bg$<@z1haHh0*Xr(vdNMsABLuzQ8M znENQ+Zr>2(T5Y)5%yU{a5Nx{nv3=sOg$AYxrwKkBWef}o)D^8>0ctBRtjel4HyAdb zCuMlAM7PpheCA;c%zX6+$A1Y1zs)J@{}nYq!EzcZ{p2M!m`>k`amAdIM6wOS#pybx zvhanhY2pz+i>iVK05NK(NvH<3u{3`od@=js^FWU9#YyY9(C4xNu6JkjoNZ#oJPrYd z=C=96t)uT@b|;SPB;0!u4qRb*GaYHZYP5WsV{}KUhC{+g;T&q0yWU|7W)Z_8^+4(_ zRD8`X1>$E$soFd&l#Jx?4Qw&afpCEu zJh~-W3}UY+34O$^#qQ^%-?Jd{O_%Az@FNAV1Aodk#4XR_ADS5l8TZ_y%yBBzJ z>IQSxgaYk~d`T8^&)Rqs(cB%%Olqu0;aFho@Y#ZUsrALN1{^LQcNJIOv~zsu#_%WQ z-dPtBl@l^FJ5apF$LEkaA%a7;i%kZgMXxALF|WCUz%N2yYiKxbdA&Yut8)EjCc9LA z^V+7|)`1~Z-{G?@micBt?oa~=LD}^$`aPnV8$y|2O~=5($b(0q=rlA-6vDslgBvQY z2)~mB-}tWpAh^r#F6He$PLo>0E)qfF&22lvjmYK??*$dD07A7&)1Io9!qiX|=E^P* zc6`iYyX0lJG$F$v|JJ;2@kn66orZHc?UU;xEIo!?UR;oS0WR-x5A^7xjI_En>FImM{jI0AzX-;Q8Tv@CIgZ(>qVzsc9mvSDvh zp|vZeMEp9jK`NeeSz|BXG|PAo1O2Zj_4!cp)vY3Ap{0Zv1?CK+W>3A|(F>TV#-7fL zu;vs#;@ZCVW8@OgXxGAIita2wYYr)>X^#%VG$)m{4$Hb2BXA-Uob8C1vQLNjjmR(= z)!C=86`R(QK2^)cN1`w;Pg>?;Qac0XE`OU3rNsWuzU~>Lt#y%U)!Jk_o&>e8!d4zR zeOljXO;rlwK1=PVKHKO5E{|9P)rN_`=~V_)2g@GW{YOL^Jw~=oP<9g6S2lXI;_D#R zGlxXC2>_WV7?G(hE#r~=Jf=NY>LTj3$ZfRe$3em~5M$j`k=%w3>_=#`E89Kd<2>(u%MurPHIty|VP zxwd0gmF?5_Se`n#7^)UgEC)Na{y@ygbLwB1gbEW(}u) zb8bgMg%8+^9=UrhMfW7GM+<3S5CGVc>!E;(5d5O^V-fczYZqqYqn5bt97Gtr@l*m~ zeZ>(=-$zN`^ng|TamzCG`^gx~x(EQdH>l76n<#dROpxpbipTD(1PHesRbNh%eJZD< zE=VYL(~<*fr=Ga(i-1vut!vt}ZV?aKW;4{jjeV9Q$9e^EhXBxEkMh_7d3bDb9vBYx z>%}h2j+>w5qIVerNc18ARyRo4JF$4Q79@PweB*|D%X4Wdbta|bdYk<}H7`ckLE`V# z)8EtPyyYh&SHpa{O3=0E4ag%LJ@uX~_8WE(HI0-2){KrJ%a|F#@~M+R$6A<8l9G^v zldpYaea3o8$0U~UjO~O@ff$;(>NrKUAg!i=H^K$EJVqP4GfV9l=HRwv(RH@CRU|Ai zsiBQlkv(JId7qPa(s1#5oHq>9%OAEO>>XsEScE8;r2t;M-S0bjA7P_xX`wZl8bS4- z%D&=QlPUd8(C8;sq1a*|M39Z1O==1DgWlV(#Rg^RPXsw;L5^M?muGQ3Qy)vI8%x|i zJOi%8CL_77)Ww~&CVZ(oN5zE?GLFf`>>rufOZwp6-zon;orU|Y0yt}!L)feeXN5ie zn}CMw0?|oNE(=0&30-r?_&@o1u7zFz#{&F)dl#BQ+M3t$^y)Hp?TjwN!=;UQrza@Y zkcJk^mU)cphiyfNE z71CW?ijnWFS+n|taV^1Z@NCje{j33&)qIgYb$?qq)E+AOyisQ zfoSUypiY#$MQnZZYH_x=EO;$0;yb*MGoehF6Ufs<`DM)vI%xZ5+E~xCBIh(-(n0xW z>2z-y@G+X8uB6$=anBamuaurPmh~wFCkHff4s2SMUU#k^A}uCYG`q7S3++d4dQT{X zP@Kxoul@)(s5GE{7n@p(Pr9NeSHsOw-|ZvhhTRVGMkT9Efgv;ntG5*?BC z)J*FhtgkVE?{MM9Fch5~wLoBY%r^W~AmUv6$ZqHa4!v$lUU)1OFxghxJIj))45uz3NFGntlTraf|*O9 zHz_GK{4!bXi;}Oa)x`9W*1Zkrj_J3BvlJdE zDV1F*b|UXdScVVVSzoRu<0aPlP0W}sFb?|Kp<33AJWH<1*Uj8d?<~ZL$N4?h;G8s( z2A-j+#7}=fDXlR#X)QZgKQOmf^WE};QD8Iz0ol%-@I&i^bFI2cG8wlcVxh`9bq+n- z0@rV!*-{!-4J>yp`pb-I}BTG+Mk>}M@nwb3O>&S0x*7?EpmL2Y) z@AYAb^1dUPJcJ_nfoIi@jP=c=h_WddYkuAHIV|VH36nhTu!%@;eZX@Mef1=QDKpON zw_nsfXCcRZ^=so8jR@6T7L7-nkdsPk zh>97BvDZ@4_VFqzG`3_#=BGzQlm5m@;}GC^tweyM=7q^aG4(;E+XQ`l}Ze)0o+lehYAW-wx@~3D%Osr@6Qw7Z;nt@pv^w_IAF1 z5$$U;Nyg8Z>?UMT(m$(!(>5>PV;b+zI|AIp3du9~Z&#poNPOMVy@fc;8weqWt{=F{ zlFYZcNIbcq1=fYQB-eK#r+TwyK%N>Ew|w&LC?f9eH2VAWjj1ya>34@uzF0Q?#VEd$ zL110m;gCj;r!QYtofTZEcS>^5?SFoueRydF`?(c4EPlCw;)#Mbj4~ywub>0t+E1Qr zMw)qJiuP1cyYcs3bBoIs9VKiFBTT;c01J~4wRW}hE-$srP z+W^zAV#NoLd7m_Vv~+hW8I#q{s>0H%XC7d})NBkdm)+N{^(WBe!!SF>ygK%=2VMRw zi=WcD@c7kc<0)Z^ae`QoohR@$HZ@n=EUq7z%HgQEg#_?aZ8N&pE$-TaM=I$ zf+qWDW%NX@>{jL6FbICF#s1}_lp(s^$+6x|d~z>dLQFf2smpCcpjh19?Iq^-1$aiE z70}1Lw}qwr__mTcZ+C#t5TY5rn85aR7|^ck!O&Zkvnl5ro|~c0GDF z$(dLWJPnuhy(PGsRcRNfBf=_0{Cam3A272`9!85qv^i((Gk@!8RJ?My5?vQX!jr^5 zmAF)iLV$8eKZWZGXVCeckO4!`i)666n4V__MF#jRZP>lEez~N} zt&|avf(VQGpWNaj`^=@k9@)6ANg@u+TBI?}{`K7PLynlXpQ!}DB(fxLkeENkvSK|x z6^)#wtkz51KmHP#19kT1TXt3qEb!7-{gJ9H*#{tU$L71R+$2z!|4NUZs0?GL7oEzg zF@b=S*11BTWLnap0bRJK)uE{toxFM6{_;u;<7M8&j)%4W;cgyi-;^F8l%8)Vi{AJ@ z5z4<*CqQ&2z6`*@AD(^+*wCNr(J9;}oc|E5T&q;R0zVc1QMdk50+x`$4?`%z&Tko1r;xV`j2X&Z#He)WLnUqGKW5 zA* z;0!`zM{P+9Mu<^!86j==Kp1V14j%B7>X{7qSXSQSe{>sU;xxoU6A7 z3K{l|DcjN9j#t0tbYp*wQqotlIbH>hUyV;m5(tX65DaxQ;Dn-zN4#wpFK=DTcmDGR z?6i?MN>V7c`lJj4w+5H|xnXteKq2VqxaJK8fkZB7axEsrgNLF#eDUGf&a{$Yo#x%;LGc-t$* zxCAvx0BAs*@XJ{1{=PvqfQBHGYH%0|-=* zqH&5$2Di{14OauY1xihSP?#a2uKE?W7)ckBmR168;=r_TP=oPJ>F?cPcl1Bv!Mg=x zHw-H11c-p%E47u`Z0LbHF)!|||KY>{m%Tv$r;*%;eV;PzZIl3{h0Q>iGNod{*&62~ z>zU%{N$ye;vE{S{RzR-_C4SkgT@_v__<4v56mKyWplzLiN1IJ_uBUE{3<>b7F z$JtlTu}IF!E4@=7<{>aGDS64@HQGt~UH76J4mu1G&7_Y7)G1cCaPvgUG}8yOMzP4t z@AUB5w8Zxs1M6qrj`dwE)+vU)PL2o}N3LhOF5&lnhZ(yi&GhmRP&fW<55R?oBt7`ggMn`R28F!n z=+?dF#!W)8c#^%BNAqbQQ1xbhJwPy`*sUju*XX$|_&?|I50`qFQHCl1InheJm%7hq zGdQ0LQa50A<9-kAgFkweVMlpEV!E>r|1(~^tcHX&H*Y}@n^9M4|Inr!FHL$~g~)ji z0RGXN+E1XG4H86P@dK`zSiT|46j8w4bPg9ji*RaTWn^lN_T~Jq&Ilk_LsK^J;#02tCK&?(!1 zNf~mMo%Jod8^;E1*WUhD)!^lhPQ}2M0~-yNQgz~!*D`!T0RBHad>tLWBYy<=_o5dB zfuUYFuFiPuT$nkQ#ntT0)LxySypD7L{mIJqm36d3Hq*2tpi;SDy4q#Ba@CJ#x+?9y zIMTh=r)<}LPuE$WVVWLPw0YlPcADg|ZBb!X^D*z6x0ex3rAVL%%S}EUAuS}H}8+g9`K~x4n*sc{N*Rqo9@$s*E$E z?`ie3*8-xe(YdIItKN~T#_(*p3D@HW;g0mAG#S#S1 z@WY?BwJk=r-q% z_=CldIr#=LzgQ#r6ylRT_kNptGyv@s(5GmOORV)3Yjp@DS@5+xXZ)3)@a>c?o0l3Y z`#kt_XUdIe@*ooW2b?cifH)iEA9DE3QEYW%Hbwu_dA~u-NA<$_euaL%K2Dk?zbb^` ze6je!U-SCkzRx)=H{AC=|2ZaVHHg~#zsIUSj>PLS{@Gss^<@W!w(HyY-_Jb|VdZ+) zzmELp*!cHu{(rrQl!E^?wEBxZELdaR0a$GdLUkpwN$9yK0EFvkqtte``SD^6LbM%k z$*lDHDa_TsQ76b5nG!=kM;rRgKW#A$NUKAi15lsI$qLzL2ZCA(Gn8GE!{So(3n_*1@QvfLlgac7IFu8dinIB*_ z!ZPfQ`I9r|Z$(K1QA~b4QS#SVznS-uK7?}DtLX8Z+Slk9zQ5RHN6$MWpEkZcrOil6 z?u#gImh1VGzbr0@Ix6WK+>3C(n8(}KKJw7tcJIwss)SlRG>XM&;Aycq=4GDJI! z{1-IZOS{>>qvJ($h*E1(*+b25V}*Jnt+I^|fO8og)87wBUv*xns%rg_ z^vOG!<#3(xy{WZnjTM|xdt2%7;KhE=^g#j|aa-{MMjAv)mwt&4YkiYxlIa~0`Jh|H zCq7L~@Nv9_{VidEB?`*VaC_tXS>hI(BFiQTmL*mXkIH~Dfr!F;|SPS4~GXQYG1R;aoUhxWSn&P~Dw+NrqA@ZAnMi-Pl()pE%ZHPDccii*xk@BTx{}(z9?zhZ1 zy|Z-=@);es=QV(6BUo1CL6>O7NSU{8H#l^KXPIFtdU`=W20VdaDA~P&mp$L^pZFKTZ4-p+UHsF&RI#rYwde9 z$oH?cW=>`w$xtiGmq0WZjGJN-`r-Y$BSP=fV+z=AZ{d(7YJ1Exq!DLz)T4-}4TNFJ zXsG4T%N(#sppVSzmUTDYFg4-bLIGm2J;UU>y%>&IacA$ek)7~c3q?~V#%YxvGwjrO z4vP&`AGUE}DiJMH%*W~PpDI?2k~sPZzlwpe(}>QC!vV;sO6Caeah@svJKP$8T|U|t zFz@e^NmFgNt(ff(9pE~;F9}l0bL?~LmC5DAT)ZxRHe9^I;d2j*0>}UeEn)gbMZD8u zBi|t}ZQ=bgt&Z=Co#oX2`iRGdj}uru=#E^K^FA^J6}^+Vy^{RC9E*ZePdK=2kGYv^CUCDXa@zczetp34 z4^~Y^QN_a}OYuRxS`yY%b$^`urquWE2pLm9<#C};R(pSgsJb;y=<_E2N>CoFP0ZbUq7|q0ByGxBwz*sH)DQ&xMuqBn;uxBZiP4Hf`RC27aNg2x4R|Ud&b8eDOWUTS7N2u}H$1>SLo~ z%rMoTFXnXh4?{&`5pI!Q%ZdJHhUI{ZabLS;ZpZORmF#IV4qZtA86Y_=ybsad!<)VV#gP^eOMFWN7f_LLIQVu=){`+H>T7eV4Y&6 zKP1x?YeVYOj}0lD})vjYkHq@zn zd}7bHo-m|v($kWCd~W?de~|wAU1l*th=E8^Nt(B(D4xgt24XudF5WiMUQ`5_l<@Rh z^+n>I*z*Hvc}m;>)u2f}LqX3XA?dySA!m&kZ{^b`2xv6LP?LNurDF!d4U#!=R(@u^ zhDQDL1L1_3jUc&(&K3>=Ide$XD9mmaKQ#683$)&k2zV&ueP1JdN)R7P0Dw2wSclLQ z^7!Q$F5bP@dg|w5p*?$kR=>y&wHFxr>1&Oa*$Q*oG;^ZVsNTqgy=jah@@M?y!PDS= z+N7}(xnQvVv`YFwbuE6Ojdf#R9`DulV|}8&+t2uzu9*+AC8n&bor0yv>a-Db!5`*E z0yZb3Q0%KpH>`b!eDqC;48ivlH%V?GPPRITicfFW!=vO;uxyQ5A=c`6TI8wXF7KS5 zKwg|+xXp6AvCTCTYjH4Wo>AQG-p?jj3EySXye~yC*)>LH&3UvdDzUM~w5dRcIqzxc z-#Qc{&yHBqPm;?*G?;m5`BcQH$vR1p--s21XbNm}^s*;Ao9f~6*X%e=@(cAH7IrVd zljFdh@3iiCf5?fTAKfm%Ck$XQ4Y>nE*fZDS21nd42-I#NV<+ASnl5&Xib^)9v!l*3 z-+!Ol9Ck51M=n4H`S5rsVZLVXIszpS_s4@`#o(GiA$640nNtM_l;U{?%mYrYFp&qW z`Jgv)4IlhCzl4=_i0ofS@1%$7Lt0)y|hQ= z5alyM$Zl*a#imbG+|8pl+7koT6si^Ujg^}ca?C{XKqJx-QkU6xb03ooQA1ix&kSvj zCvzG{Wg}$NgCenUpSL#w7z|^%kG&@4-44#4; z&F12ZNdX;9wuiM$i(LyfW9!n#(0`B{PTC3{_(Ll?beRm*8Mj`feHmyg5zw*t^wu#u zb4~$ABbh!5&CH&^?o|?<+FIQCTO7F$pj9#OtoOcM4+m> zy=0qVNzmhMEQ#mHm$jO3Yw-Sk^}e-{FxX{!JG?pq@Bl?`nTYWrxQ>dSpnZL1Gk1AY z!%kq>bP8aK>p-!ca1i169ZgCBs(t@jBbi_3(xwbDuo}<^4d?tdKjQCh=-LHcy!~_H zpvlIu%il`lljde90Bg{uP8aiA-UOyTa&|qW?4&MD=bs8R$%nw%>F_G|t&*3Id9UpP zgY1wNg9XU)#Sn=V_5&8)GnzW%BZM%lsAh#4{{Zfq;E|6-zQMT9oOv5$JYt}yBDe%E zdN4&fJ}zSi*0%&AOBOM=a24SMF$+IQSF#PhjxKw^b^nTBIooUkYw|}%ju62mt#%RH z*lw^{jl`=L*j6N;G-bJZ!rU|4Mjvme3Jf#5l>zUwFJl)L489Ih_B62C zv03t(y1QokfxNxQ$W|<7ZJ!ebgARCrwP6BBFLzpe4~;I&x*<(}QtZa0n%IKlMGY&P z6{tt|d}7(^nizeZn4_p17!vdOt@<2KvtG~AZ}UXyA&Q_OX~kApB58l-$b zfh$y&XL^0(THvIHTPBF5y9lW24tNaomeZ*TIm_-S;pi$;_E}(H5TMHgC!}`i4>*x-jUurgc79p&`T)KiTl&$0{pHn5Pz{I8oc=A zNbnT3Cww4T)=Sn(h9rOe`$Sqb|h7H>rCOg7trcIaVa+L0>>=N z%a%uO)^yZ&?ds}F9pSL)Kd6PmM5ZyGp;w)@hi|jwP3+7U_2-%gpAiqG_dZy6|b@? zi=&iv_qOZA>l(oz1Sq?Qq@4Oy^bJOTh`<}Pz}-sVKI6)bqgMTlXMmfczXHR;A%)Y0 zH`5}NuPHEH{dlkDv{CZS`ja?8ODI}u+&ml329IjvaH-FWML5&TCL?~;kqq* z_YsR}8GSb}d$NePIJmXZ9)HcyP=u=^*0ytiuew>E(>WH^~mO zKSJBc1RD@*6e_5TRou5^EyCZ#?m%4z5$ z!*dv@K_SMBo6ikL;LxSru;U#ZDZgfZfh%Z79=57;ZSW=(t-CJ(d5Qqh!XODTys?{RRF4?lP`2 zyYQ~8l9+kY0EK#f)gk^9YN+v3IO0Z!S>D!dPldHE?A*b3Z)GFxIunQA9~UivTYG+x z%6Q!Nj1v|b@(25uMGVnGrViH>fuL;Ua0BwW5?^OT#NnVQPip7^#OAK$ywSq`j*7l_ zQY~-{HOwILK+-6^uZWO%Q!>XVgv48e0t$;M+Wy3Y1L1d`%kDBu?;9ixN?!H3b#Gxo z6S$`7TdhCXtS>S0rKC)ZbQg79+o`{BG_gj0=Uf!_`F{K%A@mG0e}kU-+;=C0dJsxC zsalr&A=Yv%-%ZaHpb7M)SD=;B*;6X5x|BlqiF<>vmU%zacy0aWrX?E=*?3?hNEZEi zI&jY(GCq>cX3zH>WRAX@@@t=PVfy7{FR9cdt&vj_#hXBiLr420&jAGj+V=3e6PyFn zzUt8**`hQo^$6nLv2j|j;nPO(UJJ`}aT)G~34Ow^na-vLZSq6!2!&2pJ=jGA|zi61HEgH9GQ8pxm%v;Wl{y>WLxA??+meFx< z>7F@U{YRDNd*-XmHx0c4^QMjpJ+S8n`9IlVEI>)I_>y5Eq0<05ZtnnHt24>-vq`$= z9&WX_BDGS70M}of27B1AmhjAqXqPbs$1=$1-9J2k43~wY@56Dt4=0GVuS+Vhiti%A&zLEhK;TFs>|9l3!j@zzpu&LdE8mAQUnA_pA0<_ciE}nnU>Hfg9Zt@&pyBQ zAQK<@Rl-qsbUP^e*E(l=Ypuqe3+NsVw86m3<>|NgeNhL=1YN(nk`vPSpFR6K^%(%c z#1KJY7$yebqB^0g(R_{4fun~2hQot+SlG__@NM1${!I)af|vun`@-?3r&qoG@A9YL zz|9i>yIfUoam8c*UaqPEnkD*Q<^NIr|Ch>Z^ zQ04>bKl19Y)Vg{-TO`a)j{7;X*4}9sCVNHo>eqKp?D%|Pk>I;hJblj0UwOp-d(5uh zwZFm0DzQY@mVcUh`TcYBT}MdbuMLBgl|}^`MJxmJ*sJ7cDnaVE+e3ssIXRD{G6~pQ?25Z(k=8AqTj#jgdBDsTcFdMG>7rOFFn>RB zzVmCO1%vfQUx;$KVWV#wF~k8#AYELxlN0rh^j(b}@*w71uV!DWqs;%zpJaCTIIzY$ zb^Q?mp})#2j95SLWbkyNM+y;beS$S>rr13+?n90152>yMydM}~vnOy_YN+~k;7fqz z{(b`fVMXl+_5=UhxBu)4|MBhLYW`OG_x=B_^s3_js{B8i0%-VuQY04uWGJ$H`WPEG z8wI{A!<+s%CapLnnC8x%+mB;aMt_CuX&Fq+{(_l99tKAr8x(%K?S0fDCc5gLsuz># zhzNE)&}%;J{OE;AUE6J12Xe!&hms-xAc3LJ(jT8E&G5c1S*d><$9wLsSYb6$blLeq zusP=L%hM~c@Z6p7c-Evd`b3INx6b1vgll`-b#Lk1cA)9@#r*1JeVx;sWbkDY)oN3^ zO3bCE;&+`A7PC#Fw6 zM6aYY7m1wl{9$JCZf+WHj^|2&%E26ck2|WjBg0?mw*z(%{*bqRg`M0Wihz{nY!ZZ#3lVLq*x$N351@Brr z$s0eYA|SmU9Rlyg=($YCyh*kwDGuQ(rc%39gh%wu$t`lOwLi}__#MviM<7s714$)+ zFk#64HF5v^mGdRN!E1UbgbDn+0@r>qTStCM=l<`N_xBw;9qG!B(%)x#|M#N*M>hZe zBcqTZzF^=UqG&y(d3Mun*o3!-WmOZ>Qk1W2hBSMjxNodugkd(F0mzem@s&}!Qs>o1 z630%UQIB;Ka)TK1mMyG(@PncDwL-0L%`WNOFs&PPYBV{Y?=;RuUSsg$0WzI`!OUNy zse2_IbgbUgESkX$tJrORIN|E%zad$!$a{`)mS{rmIV=oI2MNgxWrz0d$2%dxGP?CV zV3}FNXvt@Fbq+wN1_tp*UQ1vbLHIr3r&ci^YN?Gow!E&nqm9J9=X9%p3pBkeZwJ;- zvP3E=sw~V2I2;aMI00HqUvk`Yv+$0ep2dqpdfSgNc^VE&XLp*ARz#5BO;1(KjibAR znRp%Ff*;$xsA%y|eo70cr1g46^ROo>e6)_!QIkCGC6)USG4yL>)`!g^!;uGUo6<%6 zZe?A9nFO#3`@Jg03QA6@K&8hmjROvc)u2^ENbgt4+X7hWPyW^JkJ`619CkMb08&J4 zXCkN#wxeT|I3A5R&N-m>#41mQ$p7d$e}w%80fZuXijB&hqhtR#)8w%SgErl)T5r`# zA#kzr@xhqEVz&#{WYxz@&{NYrzNoZz&oa0jSj>_flKVRAj=wcbqQrmDkh zrEgV$fsC1RH*V~_BWO~*6F)PfXxdu0UesL|0G2u5kD_|8{ppvxJ45p7`&P3mQb!abO5L#0X94Uaps9<)#RYT$Pld+ssL9VZtis&7J|N zj{a*x8<6vvkdC$UJ>#V^TI0^JQ9(;A>9u0pu&!HYK%=u~c2AoiVM1PZGWVk9byWK6 zj;=;wkP-S-%H{R%@SIQDI@O)giMhtRhndC`VRIbnz}}^gVUe)P?A8%~oMGiUYGpJu zR?FL^>6g*mjvTrMt<%rQbDcicmAV~ORvtT%P58a59XUb;HnAVZi!Z7RK8a7NT6H~P ze`i`10z2N_y+bU;58Jt4i=Vt|dz2}Dbt7ud2CPWY)OORjV(ffk#nchw_6k&+#nKxM}=M|o|lMvL65`Xkr!p=mvy7BTu( z?RSVb?z0KhCQS!C9?$eXZrki>Re&dz?QqyTYDHc%U=EgS#Ufgrme#LXa)03p~ zTG|EBc$Asp2o`!fboWG5Yxw$}x1`r3QLHGGELI$45EX=a-MPQnr@XRN=&-Th_#)30 zlYO?o=UllvFS^^sCsPeu4rGW6VV+{{>}E5V&bs-8#i-*M(|D@k9@JqOBdoA%@x%`tPYX4Cdf8dv*;=2e3k@fhWG7`c z>x>TN`)p0txc@Dya_M3?#}&Z>`=9L3jPUNU*9#^w^mtlD4lqmCAOn2dWn=M<$jpDca>%XEZ` z=5?ks*L_OX#s7s_WafR`Jx4ES)aGa!zr3+xLpU&&=bd~PZs?WK$0)qHcK@R%ILtOq zt^BA|dMMYpcNFS?Zh2q6{uxdJv6(s>;MpUmO(Q~Yd)Kh*sNIVam#qF`l2kkYaKg!< z(8GIEC(rfoGzQB|vL4Mm*WRix|5$Upf!f{OtL?TPhxTI!oh?P;s#Rj6dYNX0hTIoY z*N!2>-K1egv-9D@y%DFfDcii(j0$y9{*oOD$`5oX(RjoTV!)?fap^W~+E5dllQek9h?fj|*jtPN?r!q=ZVz)`zlP1|3C6&64d+vqErp0tmoqe>Dxjug_j}mHZ3b%Xh%NpBx zmeq0X8q^5Chx4oN3Uv`Xt8zw*a}2Rgs9Eit#fg}k?*so$)dLhw0s8m1c7k1t1x9VE zx{*5-GHe2KV3V1Tj|AUSPkx@OSia2#8~0=S;f`vuAP)Tysm5v+A1sqcB7??%{`8SK zJf}NkHKD&wv^<7hz>}TF%Jb)J8R8d?OJe9J=eDJ;)nIRfW^@~aOnX_>Ey3wyp0v75 z+jVxGr@S#Ln)Ocs0;DA?72Y24@t*}T!YcP{lTX+(4^>w3b_9FRRLi4R6RO+G6u9;B zP`}AxIPBtfZ*n!3!WUQKb~s>#%xxup=gad8^NCX3f@-M4kQ@o2Cv{aG0k%3UFf@c+ z0$crf@#nK@H^jvH*JEbm{x{Un5}VUA>t({e*%)K>aF$A=1e-@0qPFjH=$M~tOYmKk zo#PO>S-(esLGDiuj&*I{K-T!~b%tTDLHnIX1Hf7)9v887g6|c$;|mM3TbM7nWkrx1 z)F_jVuv9^t=iKoH>80J%rx{jK*B7HSg}sjEmj%71hg!o=UKQCXc{^%6kUH$juWuj7 zFYDT{)-ySajTN+4(b0B=fAMhH+2Z0EhX)Zcb7fD%J`7#ER`xohwdPI9 zcC4U{k!Ac1ss2p{aE(7$MH9bkWn9FR;nMuqI7*Q@W!YP!g_WLZ>~$*x?qY?rwTaiU zYPqd8h7f8v+}OP$Cuo{D;ANyAX);H(R7FBU!`fWl5jX%Gzmu9d-gpw^sTUjIf3om0 z)Id+%IyxO`KRa3kUrs>llc1T6tzbo<;?0_Fg?`dFXxDXsk4{BOxjB zgWk~PscN!}?NgNx6OyxBj`E&rlV>G4lTv+~A3%Tst;nD{yZ><_fL~&Do!hMYfc!eo z*QyFNnyod<(Sw$I*6i?Ee)01IuR7rVF<__ay%?2+URFtnSjvCb^s#*AQ||a>CElg3 zdc*$z zn3lc5KIu>#+3%C{2i;EndlZJh@4y;n5%{-1PFw36q`gzP&#Zv$5dlC0G4LuVtmahS z;C}t*PK3v;{C3V=fA39`2lQK9@Jv@S*EXpFW(x~(9K)Mqww7Tw4V83K-z>zD^tI5% zU+s{E=Gpobac6wjM)3;1t?)A=H^SYxXr7Yy2y8XEE%rTc2z!0_qwhQhQ=3gwmFAVC{X$zm6$(~LOdo;rV&@+PZ*ZHCQt|uUG1(meQ}|` z2PH~ZzIlxOslf*_6z|ZtQ#!f#mV3w1FKr*&9X}R*PWB8BB5yqWE-lpB{8p4^?Je$R znPRsKwa=>|`X&oq=0-*$CDHWUgbDdUs#{4(4Im!4*!_0}A^KyF6>lc55=0i8IFD*>Y;KUpN zfM~*|%{?+)$fNuCm_#!rjtQYW(E^qzx`S!mCELw=ZEDO4(a!*P0w0I zii}ZUsAqs{^xi^y9Ev)V&(Nu{Xu3I62=!&wXz%yzr)C4I$Yh)8 ze>^$G^;BeR<9o(L(xbN;BnXK3cSLIpTPItDNeuC$hzy-kdYBJ5Ot>7rPWT;SW7500 z*a(W2llv0_&pW33p2O`nmrS(FEGz6UGfXM#7vZ19Ptn-**+>1oZvgpf zNnctQ-#xSYE#eWaHwE~nK2o!yfWJn>9ZZkVQM3mCu2 z_b<%=qX^b<2Q<@!>@O%4ytDRX{^E&=hn1N&)7 zEXlv_5W^6(em#-)g?$N|aJONc`%iHE2jW$8i67Q;t5J=2RVWA3_j7A)x)L+sp$prw&~ZSVN- zOA)3IfUPANo)cqXNiDr@4raFYPzrNDjz4tjL4K%xZamcrh;p5SiNM|Ik^IHZ@YzTE zKJeLsg+HG*XjQxwv)Q zZ2b=rL5Q12575@ku88xzfMK?k((n(m{lWS+x@njO>1jM40R&;*%XzWR@3_TG4rmWR zJo{Qtx0aBSS4@XKD_GXaBwAS^y2pm+In1WWiiTlX1A5bBA~dl?KHq`+i&u5^hb!e- zuq6a)XditrNFI0BoN4}ZHWi1^6L`cS#;`55RM4|ITkx$lLN&}?Lj+0`=Zy6=nXJ+@ zIsU>S=QQz%^)`-8@ClNY+&^i*RH zT5~tKu)V+Hm)#uH)aDw^+TM45%WV$XC1|gx$h>WZeKFx_9MwHNt{ISP!Nc4l9JRWx zA62VV=34Vfa!zhZm*4)8onOcYfytps4ndI(;UJ>vyL<9xU0E-gj4K9OrL`tTiGCK! z{+0{hS_Za--$=(MP7aTNx2X1zh`DR@WeOPqgq;QBt%_KiyJ@V+QT-9*9fxP`q!4-e z(Ty^$L(X?XCYeCk293WV%z%@q3P>Dtsa+~oUEa{^aoXC z@!hC#ow|Bc`~j>?bfo<~YU!cYW$W#Uiuzpgh}Uqtl@_RWm1neeU7;naYd3cu$k$`N zyVHuhWaifLB}33;le_3>R880-tr%m2?H=x&)fuXuA zF-NjUo!6jtW#IhEw`wk-LsvUOgwf3{2#4A&M}q1;mjNkC#Pib;P>;5Zxj$+Ra_P5na! ze9ikZdtA@T{0oMP*m<<@G=)T^brc(*hhMuXlDLp*Hxo8JwTu}~*x`kmv$uhX5PrjH z{BB$}&017=(2_MuekP81&Q>L5V01@3`T9;6eqhdyn4a1kt|GmM>uL#EuuaTy{0y93 zDi#q$Ucy!Gsbe(^(?2>6(zqh%=>z+h zKbY0it{? z1qZ?~*=^V;o!w0M+;+Q)14g#5xt>G{2XCqowBHF*6+==*d(P#AE_rU|OXGi5hQJX6 z*Z6l+WPeFB$>EZ^VG3X2h0RSxH-K_75$9Di_?qkXtMt5A6KXDAnSv8CN6w*FLo@$8+}AEIIRUsLD>c(Lkg~7MIpgKYvWOc zEDh$F==eWM%id*`36i~^=x&b)jZI16iXyNAn0NF1{H=G_^ntz9aZP?jf}ZKrO&%Ne zSeXI$ETTPD(0Y|FE?;Ax0ESp5^k#3?bP_@x;iOs5J4%UF6#{6FHVq-)-d*cHgAuq& zo-X#4^vv+=>iy8|C>-q?Yd>-S#sss?J23uCUdGq=qF&X%i*+^pK1Vd{!ggZ#QU?G4 zKaM3^08?J$(FS+)3qE1GInZup#I;w`FKv~pQ=0=6DQK}oY*HBEm1c13{4UrVd zW1^1?JMqhQ%9HX*!5LtfY!w2pD)h7q3vjSAKB5`B9 z)l*n6nwCXronm=4nli*g7FwD#@br@}82P)3MDU zp7eAh4R#9jR1J^T~ylAG<#{1r{SYgoc+iwsG#BvFw6@wbe?|vWaW^yYNi1 z@A%LMfm<>0U2W$htz?kbR4i%884)Eg9IFQykXm&fp&=Bmn`M1YhRTxh#b*kRn*_Fl z2LQYYKL<~Eu%8|Fm1t~7y{+o_#l0Nbccx}R2%&(^vXP30RBYa7qMJ}%YB^9FFq>q6 z7hLWu(pUaGx3;#L`pN5nIeYalCt(vv!t7=v6i)%)4MC(;j)Rt^Wl<$HntS-&pG9*_ zLzXhz$MhKnM{1YoU7<2-Z)1d42&{jA02t<06plIv0{1(qda6$)@23w~mIgIGIAT7_ z@q1v&&M0VsJPik<8leOuT_CW-?^B)&tV_jxj`wvAH>9fn4wG2eD$5s(6$JHPH<^aJ$1P z`k*NR%~L{A{-I6UQRR$Z`_XKiGJ93sfC|O{Z3%$J;L2@&x79lLdrvd0N&^m5&HkL0J9YK4F)X!iR&>pMuybs2s{$k+=jU&>E-%F&?uslhIQya;X&K8vo%#Y zgdc)@inCMqE0{YIXKEKtO$nBTSvHz41RR>AbLEp`c%ktxrmJ*v)Ytp!(5YK(o;PyL zYsYaP71hcWi+nk-O1^nD#H$bpdNCn`!3X<%cWZERcc&`Vlu!S$mmNU1(_D+T<*D*E zT4L8m-Fm|LT`1u7BhPR2DaYW<6o@{PCfeqyjU9;{;MV`d1Qz|g?az7TG{u1y7t~X| z5cyOdHyjIz^Ww^uhorCUZIHv1wQB5;WZL^5YszcN_H_moePeS4XYnFOF*r%J#y*l%W=rhVxQI&TO%~uZU_) zF4kyKmjsxfh?6-v<93_)GIQTk0oqh#>JCyl>D;*XkbiXS{8sL&{c_d0odL#M%)lT| zx3cg53WB#o*P&Gv0R1n|{lCHHNL4aQK@fl-|6c%cmMA>GZaj+rJ9U0Ix9@G+z z+irz!(8Q#u&%HhKd2mJRzI7Od#2+kswO>9v34QPELLdRA>y!9V1|aICSBScUZF*b!c7=L)gWT&zWR2^d{@&41 z{g;{ED9%1+0+Q<$U#JfE_ONUKG`ids$EPr;81MMnbGb8SUFKwW>9Tp~(%W-&s&da* zxvC)9V213GWVpss$f@oemOX8-H(BN~nLg5{(U%}xGOL^00N8*m8Lpa7X+;VDftgii zqpWn=4YDxz!oAzEv{gwj4Am=)3Bp0-5|-8D(;eWCc01J*91b6c@cts|53jKG|AN^8 z*!>D*{{y)H8^r#v$NrAtf8pW(0j5v9j3HB^uX}e~HFqxnG{}`JAHaQ+SN@+y$iDq6 zjDzdrx2&Ahk2FG*q&IO`&uos>nw^JOYPVj!P6PN7U_T5(4j|-j0ceU57Mdkl;+!~i zE<7aALFMMAFsHn!IN;m=JSW>V@^wpRY%+Y$a#B%@r(}!CXj*fmU%~}3xBIjpwbXfv zv%v?0;DDt7m$>|?`5VxB&5$_v=lr**upS#B?zIoY0$XMVx9ZU1yWAx8hq!)X+kaSj~rY4D@_}W+%9Yb`i z@RyWtH_+?e4)#DiK4n!MZl08Bb-m}L{0&QNG}{{{zpByqU&(>o$<^IubzFDP z)7e00Uwxgi?Kr@F_qm$^qle<$S%G}7v5&RbXlESQRW*o;4h@_@keQh$yu*l zwFmz(n=`A?H&WJxd_IbZp(&vFS}4t2qxW%Ti88akxQ`lS=#I~hDg6)KEg$lIWOc>BkvcE%E*Lg!z~u6*YI9;fkwkW}te9Hs1g z9#)?r*zE#>r1(EggA}}PA|%CG$!0cU^nPMiVGIIQeg1|Q3}*s*<7D$WiYrdvdGxqXksTPkBP2Y|?^bW$>j?pVem>1UmJf zlG2vqSFb_g+r8T%$2tjc&lS}Zp$nblbf3crs0kBujlx=~m;O(fwgEIBr8+~8C7zQb ztg=tYE3b5Ig9_R`F6r9}XQ8qtJ$kxcR3p4W?fUJhitBNQ;$X^1u%PRNToZ_In$2!z zcCw|bmg5U$yQT&DB;`r>M_822;=7}_2E{z_1aGPS^!Wvi`YQx@1-BKFU30RV(5O4` z%%ppB%Jr-p2X?;^xv-Vy^Y#MI<@55bmD@1P3{i=Ow|{V);2yHfXR}jnIPzCDui0HV z!X2%@H3^!;+YJ}I!SiAqRzBwU&<{*+Z0Q#l&EuJGF};Q9M5q!#D9wLM6T$SDws%Lz z{rZ#(s~1x_*B(LVv4gYbmV2+fAHvbMRpq5-v@0qmp!@efx}BRZ`UAfc$~QOaz@@St z>qu0A%U+3@7qNa|qCBVB6iC`Nq>`1SmnM@h4DZO6;*&qhlkz5PflfP}F(#(qyd&5zz~Kj1>YGsfRC$g(SJLC0ZOoH4S= z#EK3uj5)a@GvZoO?o$PN5gCyk7=pmlCNBxn`|AK6`yP%k%h@DFRRG!QlJq4_etGTH zZL5(!V#M`%j}-ao>THATkvwmP1!z!@D@yk8Y_euHgQgYxc<>bQXNhX4(6`WEn2&Pz znP~6cZ&KrUs?>1ko)&k0FRR6F-;0{9dmfpYUq=o_>mTCuj!?b_de{hdEN7pAtfHll zUU@Z{;C#TcalO>Syja#>I;nun`5fU^j-rZ=lc|qVkDz^c2jLn_{7J?7l5Q98_arp? zz{|hsCc~Ma=GejIrFUOQ!{$!Xq*jTDN*F=}8$Iigb& z{a~C|T@T=B26&30Vsh%JZM-}8?a|`w(SB?e7d&lJh@kQ!EDKpRrT%j`~bYPIr zh3Ctkm$}w=V0KUYpvtW3o;jvNs7durgjqLY$R3;R7j;il7CY9x=OIqO#@Pg-bI$6M zS3(%F<0VNda-u7xwCj7U`@nt90~wY}2j&ciWxg8Zr`@HV7H++4FLB6rm-gy&r9!bz zns2K$s*w*4zR1{SXr^g^f%xsKU7&~$Cfg^7=U!oX`DjU6^-Tddimoh7mO`qIjwDRq z3kQU6GET@Yi<#Mv-?rj_ddY`Jv@W7m_}xBH<*c@Y$hWq5UFu;& z_xd+>e$9%7IS!z7bBx6u8OAJAJ{VrB?a@+bd=Brgo$YRM9N5djy)%eg&@dYV%}rde zbHNX$OGG&0QdTUQnkYn%axgDaw?256>mKbKK8<2xe=N zKKqrN(jeJ8;&7Z}gyS2SHv*r4+B^Y4Ki-;!PjKTs_da|X`3tIM59peIb}p4BkQp0) z3#Gj~e^BcDxT5+G+^;j4Zu25RKJkajmf`up2IzoEd2xd6u6MSP!c)|RXrWgpiT%KJ zKH%QGq2Ki7Y?4k+L4+8I1A?&?N063X>5|+t40^F{{+ci8yg{P8&$&eB?H|IB;daNK zj7@5#Lc7M6kU;Qz5Izf6i~Ta1LbhS9CnpM|cHxjR@w$LDN*}pTP1vhOF5I(FM_sAC z?`R)9HrVr88XVlGHa(yP+%#7HPrnilsE8m}{r=bqSlx1Tz9Rd_s4-!HkxqX;)Re1{ z!f~Qlsqq0nB0&Cu^VGewEJGd?*1sBfdH$9pI4?5wIiVeeVq%4x4d94czC$*{^Es<^ zpIC__K2H`NLCMJa0f~#VA%*R2Ow2}5q%^+ik#d1Tw*U+9-7P7#IUmQQ2=6A)_8e{! z+Zx5ehXK6LU(j3PKy?(BR8KWYP2ET!pLDG5-(f*$ToZeBQK!_s&)*||>x1t-U=2LJ zFDx`QZI`b4Rmn3E1_q>DJPOEV_&}Uk#@A^Lx3x2`WV<4aI&2?37CRX`oFzH z#s=9g+4V*>zs?6OJ_7>T$>D~91X|v*N;gviX?-L|W$m;`QMW3F#$@io)U^-@_52ap zYjT;qS%G^yd`q21lXwB$>+7_72M>(c@wbo-*H4B-6;~J-h#-R$P;@*hIYHXdlNxy* zkD_g9sdduB!#}Ech4k=jb(5a_coAAI&82Lo^_*+N)>FC161doq>+Uq#CwcB;z_}hH zw{eBXwK1BayeDfF+3V-lV^>N>j1&OSgIPWgCh57V1PSual3Ae+b>VN@X_iwM(|t8SbX3vldzZ|7Zes9`Wfr0hR$PD|JE z);l+=?8dS`<-p8F0|LV`kEGj-cXnZvV-G{QTM8sI;xZ~Sv#37+&f~v?=EIY8JPL8Xd zafNX*xSLI$a-MD#F9--2HsON7yD<0Gzs`~!6)^$GzfKzkeVq-#DGB2e!^Mz<*NC0c z`Z$-RLB-~&Q9!U(o8;sm%w#$ag8)n;$Umk^uXOL@KekJjPyjeL*JzpNL&5B1s|4{# zPCeB)grCt0IBrH~V{KcISNpCp@R|tRt{smuFlVzoCz7a~X9clmDt_^rG8T|e|84>a z(!+?#!)kvkf0oC5EDc3S_n*2WHa#R^VrJHw#d%C-)-HvOpeM!ErJ?7WIrV8)N40=L z{y&YwE5pa+DV%cKZbw3E{bp@mB?FwrW=e`4Zg{ElOBfJ}tp9CtT`f9Q63APtG=jUY zTe+D84rDWL?>mDayyBs-eoNBZAjoSJ4#8ENbsZ8+uzj~x_AZ!?6pv@|bji6B{DaUgGV(0WXU6;aL`q)JV0_@BQa zR*7CRdgr>@jYx>h5<^vs%gVLvaE53Kj^9KYqXE&6sV3my5U*IeY8C+`(cVqS|7Ii` zQyW_TFq-QUp@d=KLp=yHhq!2FMdx7}_-wt1C*6>ZFGNIVcr}X7kkCd@P3$LYR;>H( zZrZaFRg)&rUCsuO*?I|Xjx{F1TECz)TMmS4kirqpQ?1@R{H6 z$Ml41LT4@?P=}-Cf&`Be3VaS?YtJth=qi^ZIsCvcp2pR)y_u9F&ODd!$8B4CjeFsh z>G)BrEf^kedTU)m=9SDt4QU_n%bU*8Hb^u6l+Goau}#k(=em4Ag{2vNo$Cr_MKeW( zk~O1hH(gc}^DyXCx5UN8qhuBhIrJJXMt%%tr!JcIc ztlwj(1~h_&#YfpgH=re(H;fOJ?|<%`;nhC$S`~B%R>I&||Bk%*MB8>^>fv@>Uz&&< zTy|0YjlDw6Gb&q?hA+gMTDPx1GUXM{H7&cwevL%Yk7?I9JrJ>iz`Nv^HBwh8AZQxf?nuES&8T#gx2a)F&)MoJ_mU1x5<|@-@SE}t z0i`WZ%p+}@K9R_2nD^$5y&IuPWyF7#)lNJNPM+@aogYI>w+Xc-+KJAxhe;yVHr?R_ z6xYU@v&Ix}y1@ON<3lH#jhw$c&dr?NuOL6Z32lgZ_depwy()o6G2{M zJ|yg#)BAi^_MmLga$w|oBd8>(DCXVcw6bY&yju*%QRHLa9S%kv>f@|^0r7XGm=nSJ z4XM~DJ72lU6ZS279ObOdL?P3);y*qsJ;=TTr2Q7zQLhzo=tHX6k^Awi9c2=z1Qp#_ z?8vNgorVtLLCp(3Tsijm;iDXcy4u6%oJuM?f=4PNOH$9sC^oFWIpk6}s4a3<63V~Q zKYD8wT`BvU`i?npq~yv27UPfh@g&FBJ(4XA*xhYd6_j=g_qcg^4^*f+l?{7;La{n* z88WrkAN35#Y$?uw!Y9T{hy2p;z?y#doJ#(;9VB;b zA;5XR4NDe7s$W=UTUNe*7m`3~X4ET)zbQ1Ha~P(;A1!)({8uVd+L{I9O`nkRqVA1?qUw(7UE{=8PY zhSHs9r}{fx2?iunFNeukR=bTZCAU7+To9z2PkJ{C*l?&*^72%qPQZMq0H3G2L>MXZ-c!85TDfc7KNohoYj}hNY?slbxRzGgL zi2MPyMn6j6dRrRgYegO3d*V68@mC+d8+_$NUfoArd9MF4Nw56dfamP$CB{NntgJE7 zhl+fXEXZoy(asJTsKs`5>Ze}_INk@m0P8I1rj$g3?E_WWhVg?ZwBe{>tLgR%Q`^I{ z?~3}PWDhm|c*U;Y5#;HY9(A+PmzqiOB1h;b#lQbxLie0?{l-dpj((-r{q-9S zM4;vQZ9fqn37!m%?Lvlx#N>+H^bpk4SproyC;&o~t-%`j@}*w$!|}I&HbM))qj`0_ z?XHr=zPZv?!wMlEnZY!C5DlzwSDCCy>&6{RIou26tKn^-cX|yMJ33!3ZKpDpL=|%= zKBG8Go|-VTGu!UbG=s>n=^7ep^j^Araf*ar`x*@&1> zijbM{jlNWYPzth-IR-tqh|?g7!E7#<7`KDKHW7VEQ=?+<@QLBG%Yb|fMk)RrFDd5R zd;ttM^UM#{nD4{xhJO5*GMjw09REl4S=Sqo4Kbnb!zTOp!>R0_TnKahd}C&L>I+IE z#YjzhojhH37GyLNYqxV*he_3^ zZq~@64uzU;^Q=4Dj|yxgn53I9pCi26w9{Da@>Q$&y^{(8Hix+%9v`S-M{G5#@s7?!AUUEp68E~$bon=emu#FH*o@{I_{Swb_&V^ILz5cnnR7~ZbuBR>k$mSrqRUUScqpXuR*ugG`HvS zk_u&h?3!x>p%!XF+x9va_I>V9i?>^rlh#$5&f7n&CTVm5*RCR)81vEL1R(sy_0o`c zPmf5m%Po~v(_{!0MUFMM)18;eK4f_d@n;NN;%SPUE@M-jWxUMndjbbpEIhWVwQx^t zvR#<(zGbRjS*W5hUfEKB_mBDFA38GUOXhP&Eye1xdP*$r z)2X}s&r)@5J!&`$Ym}*v`ioektmd^6>X;ud4^Rb3o$+rSO?_BgI>|E9O&b#7x5h!? zUeYCMall9u-y=MvW_A}_YFK3sm+@IrPMVw{qqf^LP&ECDYkQh6+gFtHu$8zInP8Y5TSlG-{oc4uRw@0-)&yDPn8saCz!P46_p0&TnD zo-;ujv}{!6pW$OfNAM{oLwVu5FoaUJisZMzcP3mew~4~gA7m@>A~Kv0yT0_}wxJG5 zs_q$D4LUo#RTBwlVdMWLz7jN=WJC6&ycwBCeHee_R?u47LR&s(fRE>{eoM zd2&{BOYQIuWrcSKN%-xO#wjmT{h80st+0Sq!U~sMiu0axG4PSx%qDKx48tX>t@4n5 zES~?z_ya$Qrt=8qjph?&QXjE0>UwwXu}9rV$MfHGgIS}yxh+o2KgYzWuA?Q$F&fYY zXl)!Gc`ZeodS6E)Xo}f6-`Q89xxSA~*J6p>b=Xp!X2bI0)at%@eZ8B`edeX3oShoy zkNA0oGSt@0S(ek`@BJdV4$XXO%o*ep=d`~ux_J{Y!3oE0)fg6U0ggfJ3i1mzz?U`B zTve(2ko?PJ9}V&gv$J!h)BCYPy?-Ly`zbw8daK_~i0f_)w}Aj@m~ zz&BKTicPJYc2ol#yF zT^Hy*!#y%ajrCaS)ChOf(AeQc;Q9!KS;_*jixq^+tnI^SCRBS=c8%q>xUc#5=NFL@ zLABGpi}D3Qh#QOYb~zT3%j77c91Y%u=Ux6-BZkI%VYd*YXdR^YIc~Tm4i#lLD}=~F zgHKE?-(J{SZac_>1-M}W^*T;ivMy0<61NSPM4bbFLz(nM;Ut1$O*J(LNIr3@(Vj|) zziKhv{Ng|M)m^ZJqfQ0%1hdFU+N62O&y5u`i$T!J{OQ zXlKs2zoLwfk11#(g{gfHGGu0vm7|gcr4aW1^3-6KSi@z(Kk(lxv5Ambpgsta7&OD3 zuj5LvNekPbV5zT)MV{1JeGRNq@SOYHLhC9DOUGJhQU^GASrZh2G6h2yhaht2spD$+1*lV5(44xyyU4Um?eZb*(*#@uV0_q z#erTgOnKS1uCDs5y;tsOxgdsdDTpi8+Rhh2cV1H0mmqVkoDuiH4ju zDM^lDbBN8UVHR>ejPETC(UXez)}aYK;X(6k-7ct`~}pa!WAu!Q~hYK3O9M@b23L z4#nG$Fu{OnfDgz2!3(!U`}rf+-@vNfEduWo`N)oJUl2IC_l-cJlyD2m%N#@gI3Hbq zY1|GEr6W?2EK$3!)~?+Z1M`IqlLRTCT#HI>Lp?wWZ}6{)_cAvzh$08hre$}kmj`~F zxAtW-RQ0uxpbBXAoaH}ifArv|r=fH(NKpZz3J`SY2Lc;V6)T{Lh@hSd@Vir`zwIYy zClXh?(I0g*QyB2oT$_=mUw#H-N;uO9L6(Q($wu27BPLr({r`BFQe&n!&fWV?vB8fM zb^p*CE%s5yfZ#Hlu5pGkc7{ISco%=pm5^o!#!84D&hEYFI#@Jbv$`sd@Fim+>xX?u ztpqvc<~Fs{^e|Tm$R<^ixy-o$II7CH956My#w020sk=7!|$jhNZtUT3f{ii+R(FAc_b|!xG^D5KhPQ z*-F9{Qt!FKe@z0+H`#zm3EkjX#JHE~r1xdQ2vV!rQGE@>R67hi#^B5c}3z;q<}?Iwba)uKd?fD_@G)n{i7GVSHF0byT8P*R2VX^&mcAQjwXbICDoj2#{;wsXq4% z^Rf?K_rCRlkAq13SfAQL)ip!JRjC}gmh>=}1$yH*0zlv~B9{>gvn7%%RHC0h*X~y0 zLD0S@`w8@m_ztk#@+dkSd}bTvMJ)uj4#CQbi8*o94Auc$4gnI`qzi&p1M4}S4lH@o zgAo_8R?~SI!aGu>NXjVDu=_VD^!c+am9gzqFjTu1(j|j53X`(jPB9$YP>DtRK?2?# zG^B?~SxamMYo^-E0Z?4o?=SD685I+9-XFS@y@Y|Cj?Apy>+_4`lS;AN{Nl96zR1}Z z`IS~xfUa=2P4@7`*A!vWAmBwtL9g9Hvfl>>i6vV`O6KHND}s+#g$ID3G(^}0!d)H| zCogbO9PxTVDe37%jHpYPIw+|Sxd8dA8w)h8Vn~h=|6Ex+rKzzqg-MmO6T-ihv>X1M zAG-ci)3cULANri%D78bnmt= z^k<*4K-Q?IbS^Q?MZy*10jOSl-JUbex9s*OKB(wq0-omFi+wAjzzp$CnR^jbLr0_O zjW=GBwb%;JHNG~TH0Mw23iUmU78NE=T$--@Xk_P6nle_-s9cZ%vNVX8A++LI=7Uy0 zi{aL+qpZi<{TB8G+D^I9lDNF0u*XtX{29NR+t(9eWzg!notm=Se0tpPw_Rm{09SH$}*l~9`Q4yL)u(ODpuaL%@# zh~gFYHbbE7%vO<5pALu+JqyCzJzgO)ofB!FL#Uq}mIH+1ce#Bwu5`N}nEC6(45bIC=@@k}6l2V?uTN<{pK;_;+S?y!hkgHX@gj|}76iblLu zrr41?7QxTgH}nLYdA@7cCgYag2)a>%^fBG9;1+qDVW&&oCFIZ*YP*_z)R=>SM0y0T zDdOUp6`q5Hq#-s&s(zR$61<{rwdE?Mz;J~JOBe|EQuis?IAGkYT|o*x_eC-z1Vw9( zww0`z)e3L&y52qWg`CX2hUW^~*rLC?PrtHcm)lV^(-5P$iC#5tr+{ikurT%pP(MPwg>#_UXfB77+x?J~bP@_Qd zT%6M_U4fI!&PcUB_60nL=KwK$ns;@O3EYO(s zr8)Qk0oC={OF75TSmss)%~Wz*GCH)gFq@Ko7-gf*E1hhi z{IUJvetEF`&!Rf^a`|oH!wPTKa(avPlWMVDhEbiBZEw=&{8Dwh?P05l8Z&(xV=Z0$ zYRvup{QC9Ur;e5UEtgQYEMPQBdb@19Ocn za&nkvcR$u3FxDmfrl{J@H9oTfpPu010bP+b+sBOpHP+Hb<(p?JXC;^Cgd`RWwZ~O8 zC^Pp5Ete-3Kd;3S|8i;F11TTbi{f~wSfuc}R)Sk*fe}h3<=DlS@4dBXf!n}r&o}pU zu z^YHOH+Z%SFMMIDO;~@PqY-&T}-p>&IiO1WiIqaJWk6}7idA>vW$^o12=7A7W1)9o2 z0i_g1+)JA2%5o~ebq0?009(@CY?Iigs_jUNpBMVn?nB!n4NrFGpR{VO{^K~H6i@Zr zkm@V3lS^9b)MkB+?8lv1!}GHaL0a37etvt4W<2qi^l_&})&~4*e=@Co&r%MQ00pN| zKUnsYq>iZ6tMs$IZ)Om-YulPZ#=9x|<~=%|JbwjN(Vac9sty4v2aR<$>pwy6`?0|~ zol0xnI|H`pZfx!m6UTrNo@bDjaU1*Zg3uzCTe+vYbHHuQG|$myS#KPO zRU@R2uV8oLBLegq;p&T=L+0K^>gd}BZRvSM3I(+mpw~xjM{mh-^}u@kNdu zw_4^o7acRdJ7zTh^S5|e5(fxLoU1c#+P$3esK1*xk$zxv-dIfabvgmShwE(A%>pOq5O2>Mc}Lhruc5XR)|501n>?P|jPsH#v)2 zgIc6rr_6#%@;xuUizV63M4rTRkkQ69BgE6kSg52fxyY@f1T!ThMc3NLozux%laDcw zCCw}`ICYc+%9WQV{`O;(%GtfJ5C>zdCSJZ@aB4R9--`DK8+=*o7k-YDfB63}(w@y1 z^{HizH3eDv3w+(_@Thzha=tx8HPxSPB!doA9wS^86=IctIaB*QNB((w**DR!$HY1za-_f8g6n%gj$WN-fZ z-#>JALfg7_>*kf_uoMl;Nn9~OvTIXa)a4TkDy@raRI!+dkXR0Y^e`Ky=$FrmY!EA& z63m=q7UmBTX)>-dg@*642KE-Yf4k;bF#_f1sH1T0RM{c1DhRj~PAG;Jex*Z}znWaH zlW`Ex{!?WjWa~2Y`?X})ghF+ijoOu|{5#1&f)n4@fR-n&bgI;Fto~|MG%oZ2^Yk8p z_V1Y;>5$}uUsC|Ltp}>(oa4!i7pZY(9=S1XHO>3D!E<{_ZIW3>-hma}2n@J-zgg`N zvnBy%1p~Oe^*;}ChkmbG%5)9Rr38@3DRx6`5f719S>OKK+4h&r7M+17or+e}4SU7! z@O;33g)+jyRoL>Ju^8@v?nf5$c<{w^@C(Ffc@?B|i=BBoko>w(LU5>R_>%9Ry!h%; z{KoJP1jkWt?%B1eE41b@&5;$ C{-s&~ diff --git a/docs/style/coding/CODING_STYLE_GUIDE.adoc b/docs/style/coding/CODING_STYLE_GUIDE.adoc index d6436523d657a6..eed9579daebab7 100644 --- a/docs/style/coding/CODING_STYLE_GUIDE.adoc +++ b/docs/style/coding/CODING_STYLE_GUIDE.adoc @@ -1,174 +1,32 @@ -[.text-center] -= Project Connected Home over IP Software -:listing-caption: *Listing* -:toc: macro -:toclevels: 7 -:sectnumlevels: 7 -:sectanchors: -:sectlinks: - -:plusplus: ++ - -:sectnums!: - -== Best Practices, Coding Conventions, and Style += Coding Style Guide [.text-center] -_Revision 5_ + -_2020-09-22_ - -[.text-center] -*Status:* [red]*Approved* / [red]*Active* - -toc::[] - -== Typographic and Syntactic Conventions - -The following syntactic conventions are used throughout this document: - -_shall_:: - -is used to indicate a mandatory rule or guideline that must be adhered -to without exception to claim compliance with this specification. - -_should_:: - -is used to indicate a rule or guideline that serves as a strong -preference to suggested practice and is to be followed in the absence of -a compelling reason to do otherwise. - -_may_:: - -is used to indicate a rule or guideline that serves as a reference to -suggested practice. - -== Introduction +_Revision 6_ + +_2024-10-28_ -There are likely as many unique combinations of software engineering and -development standards, conventions, and practices as there organizations -that do such work. This document pulls together those that Project -Connected Home over IP believes best for our organization, its efforts, -and products that consume those efforts, with a particular emphasis on -embedded systems with C or C{plusplus} language development and runtime -environments. +This guide provides a small set of code guidelines used in the SDK. This guide reflects the currently accepted style practices for the SDK and is subject to change. -This document and requirements should be considered canonical for all -Project Connected Home over IP shared infrastructure software, including -both RTOS-based and non-RTOS-based projects on both tightly- and -loosely-constrained system platforms. +The SDK was seeded from multiple different projects and contains contributions from many different companies and the SDK code therefore uses several different coding styles throughout the code base. Stylistically, code should attempt to conform to the dominant style of the code being modified, while also adhering to the guidelines below. -The document is broadly categorized at the highest level into: +== Language standard -* Best Practices and Conventions -* Format and Style +Code in the SDK conforms to the following standards. Changes to the C++ standard happen infrequently and there has been only one change from C{plusplus}14 to C{plusplus}17 over the course of the SDK lifetime. Changes to the Python version happen more frequently. -And, within conventions, further sub-categorized into those that apply -to: - -* Tightly-constrained -* Loosely-constrained - -system platforms. Applicability to tightly-constrained systems also -generally applies to shared infrastructure software that is used on both -tightly- and loosely-constrained systems. - -link:#id.jzphr1iiku89[Figure 1 below] attempts to illustrate both -qualitative and quantitative applicability of these guidelines to -Project Connected Home over IP software. - -Generally, product-specific applications have the greatest flexibility -and latitude in applying these guidelines to their software. Whereas, -shared infrastructure bears the least flexibility and bears the greatest -adherence to these guidelines. - -image:CODING_STYLE_GUIDE-figure1.png[Figure 1. Graphical summary of the -qualitative and quantitative applicability to Project CHIP software.] - -[[id.jzphr1iiku89]] - -[.text-center] -*Figure 1.* Graphical summary of the qualitative and quantitative -applicability to Project CHIP software. - -:sectnums: - -== Standards - -Project CHIP embedded software development adopts the minimum C and C{plusplus} -standards listed in Table 2.1 below. - -[[t.4d8bfeef046f29261fc72f1a903d6d10a909957a]][[t.2]] - -[cols=3,options="header"] +[cols=2,options="header"] |=== -|Language |Minimum Standard |Aliases - -|C|ISO9899:1999|ISO C99, C99 -|C{plusplus}|ISO14882:2014|ISO C{plusplus}14, C{plusplus}14 +|Language | Version +|C{plusplus}| C{plusplus}17 +|Python | 3.10 |=== -[.text-center] -*Table 2.1.* C and C{plusplus} language minimum standards adopted by Project CHIP -software. -Product-specific software may elect to use later standards to the extent -their software is not broadly shared inside or outside Project CHIP. - -=== C - -Project CHIP embedded software development uses and enforces the -ISO9899:1999 (aka ISO C99, C99) C language standard as the minimum. - -Wherever possible, particularly in non-product-specific, -shared-infrastructure software, toolchain-specific (e.g GCC/GNU) -extensions or the use of later standards shall be avoided or shall be -leveraged through toolchain-compatibility preprocessor macros. - -==== Motivation and Rationale - -At the time of this writing, the C99 standard has been out for over 20 -years. Project CHIP and both the new and contributed source code that -comprise it have only existed for the last seven to eight of those -20-plus years. - -This is beyond more than adequate time for this standard to be pervasive -throughout any toolchain vendor’s C compiler and saves team members from -worrying about ISO9899:1990 (aka ISO C90, C90) portability issues that -have long-since been solved by C99. - -=== C{plusplus} - -Project CHIP embedded software development uses the ISO14882:2014 (aka -ISO C{plusplus}14) language standard as a baseline for source code -compatibility. Conformance with other standards, for example, ISO14882:1998 -(aka ISO C{plusplus}98), may be additionally required in cases where wider -portability is necessary, but in all cases, ISO C{plusplus}14 is the baseline -requirement. - -Wherever possible, particularly in non-product-specific, -shared-infrastructure software, toolchain-specific (e.g GCC/GNU) -extensions or the use of later standards shall be avoided or shall be -leveraged through toolchain-compatibility preprocessor macros. - -==== Motivation and Rationale - -CHIP strives to use the latest C++ functionality as long as existing compilers -support such standards. - -C{plusplus}14 is considered pervasive enough to be used. As compilers start -supporting standards such as C{plusplus}17, C{plusplus}20 and beyond, -CHIP may follow suit. - -== Conventions and Best Practices +Product-specific software may elect to use later standards in their own work. +== Coding Guidelines === Common -The following sections summarize those best practices that are -independent of particular nuances of either the C or C{plusplus} languages. - ==== When in Rome -The most important convention and practice in the Project CHIP embedded -software is "_When in Rome..._", per the quote below. +The most important convention and practice in the Matter SDK repo is "_When in Rome..._", per the quote below. [quote, St. Ambrose] ____ @@ -176,23 +34,8 @@ If you should be in Rome, live in the Roman manner; if you should be elsewhere, live as they do there. ____ -===== Motivation and Rationale - -At this stage in the work group’s and the team’s life cycle, it is rare -the project or subsystem that is entirely new and built from scratch. -More often than not, development will involve extending, enhancing, and -fixing existing code in existing projects. - -When in this situation, it is mandatory you observe how things are done -in this context and do the best that you can to follow the prevailing -conventions present. Not doing so can lead to readability and -maintenance problems down the line and will likely earn you the -disapprobation of the code’s _owner_ or other team members. - -Your extensions or fixes to existing code should be *indistinguishable*, -stylistically, from the original code such that the only way to -ascertain ownership and responsibility is to use the source code control -system’s change attribution (aka _blame_) feature. +Your extensions or fixes to existing code should match the prevailing +of the original code. If you find the conventions so foreign or otherwise confusing, it may be best to let whoever owns the file make the necessary changes or seek the @@ -200,522 +43,95 @@ counsel of others in the group to find out what the right thing to do is. Never just start changing code wholesale for personal reasons without consulting others first. -==== Language-independent - -===== Commenting Out or Disabling Code +==== Commenting Out or Disabling Code Unused code shall not be disabled by commenting it out with C- or C{plusplus}-style comments or with preprocessor `#if 0 ... #endif` semantics. -====== Motivation and Rationale +==== Auto-formatters -Code should either be actively maintained and "in" the source base for a -purpose or removed entirely. Code that is disabled in this way is -generally sloppy and does not convey a sense of certainty and direction -in the code. +We use the following auto-formatters on code: +[options="header"] +|=== +|Language | Formatter | Style File +|C{plusplus}| clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) +|ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) +|java | google-java-format | N/A +|Python | pep8, isort | [.restyled.yaml] (https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml) (command line) +|YAML | prettier | None +|JSON | prettier | None +|markdown | prettier | None +|=== -Anyone who is interested in the history of a particular source code file -should use the source code control system to browse it. -Code that is debug- or test-only should be moved to a conditionally -compiled test source file or conditionalized with an appropriate -`WITH_DEBUG`, `WANT_DEBUG`, `WITH_TESTS`, `WANT_TESTS`, or some similar such -preprocessor mnemonic that can be asserted from the build system. +All pull requests run formatting checks using these tools before merge is allowed. Generated code is not run through restyle. + +=== C{plusplus} -===== Use C _stdint.h_ or C{plusplus} _cstdint_ for Plain Old Data Types +==== Use C{plusplus} _cstdint_ for Plain Old Data Types -Standard, scalar data types defined in _stdint.h_ \(C) or _cstdint_ (C{plusplus}) +Standard, scalar data types defined in _cstdint_ should be used for basic signed and unsigned integer types, especially when size and serialization to non-volatile storage or across a network is concerned. Examples of these are: `uint8_t`, `int8_t`, etc. -====== Motivation and Rationale - -These types have been effectively standardized since C99 and should be -available on every platform and provide more neutral portability than -OS-specific types such as `u8`, `UInt8`, etc. Moreover, because these are -pervasive, you do not need to spend any time and energy as a developer -and engineer creating more such types on your own—the compiler vendors -have already done the hard work for you. - -Additionally, using traditional scalar types such as `char`, `int`, `short`, or -`long` have portability issues where data width is concerned because these -types are either signed- or sized-differently on different processor -architectures and and ABIs for those architectures. For example, a char is signed -on some architectures and unsigned on others and a long is 32-bits on some -architectures and 64-bits on others. - -==== Language-dependent - -===== C{plusplus} - -====== Avoid `using namespace` Statements in Headers +==== Avoid `using namespace` Statements in Headers By doing this, you are effectively forcing every other module that includes the header to also be using the namespace. This causes namespace pollution and generally defeats the purposes of namespaces. Fully-qualified symbols should be used instead. -=== Tightly-constrained Systems and Shared Infrastructure - -Applicability to tightly-constrained systems also generally applies to -shared infrastructure software that is used on both tightly- and -loosely-constrained systems. +==== Classes / objects not exposed in a header should be in an anonymous namespace -==== Avoid Heap-based Resource Allocation +If a cpp class defines a class or instantiates a static object, it should be enclosed in an anonymous namespace. +``` +namespace { + // CPP internal defines go here +} // namespace +``` -Heap-based resource allocation should be avoided. +==== Singleton use +The decision to use a singleton class should be considered with care. Do not default to using a singleton for ease of writing code. -===== Motivation and Rationale +If the class truly should be a singleton (ex. if it is controlling access to a hardware resource) +- The standard function name for accessing an SDK singleton is GetInstance(). +- Singleton classes should delete copy and move constructors -As emphasized throughout this document, the software produced by Project -CHIP is consumed both inside and outside Project CHIP, across a variety -of platforms. The capabilities of these platforms are broad, spanning -soft real-time, deeply-embedded systems based on RTOSes that -may cover life safety and/or physical security applications to richer, -softly-embedded systems based on non-RTOS platforms such as Darwin or -Linux. While the latter are apt to have fully-functional heaps, the -former explicitly may not. +==== Avoid Heap-based Resource Allocation and auto-resizing std containers -Consequently, when planning new or extending existing Project CHIP code, -consider the platforms to which the code is targeted. If the platforms -include those deeply-embedded platforms absent functioning heaps, then -heap-based resource allocation is absolutely forbidden. If not, -consideration should be made to the cost / benefit trade-offs of -heap-based allocation and, if possible, it should be avoided using one -of the recommended techniques below. +Heap-based resource allocation should be avoided. This includes any container element in std that automatically re-sizes itself at runtime (ex. vector, string etc.) as these re-size operations are often large and can lead to memory exhaustion and fragmentation on embedded systems. ===== Alternatives In either case, recommended resource allocation alternatives are: -* In Place Allocation and Initialization -* Pool-based Allocators -* Platform-defined and -assigned Allocators - -The interfaces in https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/CHIPMem.h[_src/lib/support/CHIPMem.h_] provide support for -the latter two alternatives. +* In-place allocation and initialization +* Pool-based allocators +* Platform-defined and -assigned allocators -====== Use In Place Allocation and Initialization +[CHIPMem.h](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/CHIPMem.h) provides support for platform defined allocators. -Regardless of whether the source code and runtime are C or C{plusplus}, the -first step is creating storage for the object being allocated and -initialized. For simple -https://en.wikipedia.org/wiki/Passive_data_structure[plain-old-data -(POD)] data structures, this can be done by just allocating the -structure at an appropriate scope. Alternatively, _raw_ storage can be -allocated and then cast. However, great care must be taken with the -latter approach to ensure that natural machine alignments and language -strict-aliasing rules are observed. With the simple data structure -declaration, the compiler does this on your behalf. With the raw -approach, you must do this. +[Pool.h] (https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/Pool.h) is the Matter SDK pool allocator implementation. -Once the storage has been allocated, then use symmetric initializers and -deinitializers such as those, for example, for `pthread_attr_t`. An -example is shown in the listing below. +==== Prefer CopySpanToMutableSpan over memcpy when using spans -[source,C,caption='',title='{listing-caption} *{counter:refnum}*. Using in place allocation and initialization in C or C{plusplus}.'] ----- -#include -#include +See [Span.h](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/Span.h) -... +==== Prefer std::optional to CHIP implementation in newer code -// Preprocessor Definitions +The Matter SDK Optional.h was implemented when the Matter SDK was C++14, but newer code can use std::optional, which offers some benefits over the Matter SDK implementation (ex. std::optional is trivially destructible if the underlying type is also trivially destructible) -// Allocate the structure using "raw" storage. -#if defined(__cplusplus) && (__cplusplus >= 201103L) -#include +=== Python -#define chipDEFINE_ALIGNED_VAR(name, size, align_type) \ - typename std::aligned_storage::type name; +==== Type hints +Use type hints on function definitions for public APIs. -#else -#define chipDEFINE_ALIGNED_VAR(name, size, align_type) \ - align_type name[(((size) + (sizeof (align_type) - 1)) / sizeof (align_type))] +==== Docstrings +Docstrings should be included for all public APIs. -#endif // defined(__cplusplus) && (__cplusplus >= 201103L) - -// Forward Declarations - -extern void * foobar_entry(void *aArgument); - -// Global Variables - -#if USE_STRUCT_STORAGE -// Allocate the structure directly. -static pthread_attr_t sThreadAttributes; - -#elif USE_RAW_STORAGE -static chipDEFINE_ALIGNED_VAR(sThreadAttributes, sizeof (pthread_attr_t), uint64_t); - -#endif // USE_STRUCT_STORAGE - -int foobar() -{ - int retval; - int status; - pthread_t thread; - pthread_attr_t * attrs = (pthread_attr_t *)&sThreadAttributes; - - // Now "construct" or initialize the storage. - retval = pthread_attr_init(attrs); - - if (retval == 0) - { - retval = pthread_create(&thread, attrs, foobar_entry, NULL); - - if (retval == 0) - { - status = pthread_join(thread, NULL); - - if (status != 0) - { - retval = status; - } - - status = pthread_attr_destroy(attrs); - - if (status != 0) - { - retval = status; - } - } - } - - return (retval); -} ----- - -For non-scalar types and objects such as C{plusplus} classes, this gets slightly -trickier since C{plusplus} constructors and destructors must be accounted for -and invoked. Fortunately, C{plusplus} has placement new which handles this. -The listing below modifies the listing above using C{plusplus} placement new -to ensure the class is properly constructed before initialization and -destructed after deinitialization. - -[source,C++,caption='',title='{listing-caption} *{counter:refnum}*. Using C{plusplus} placement new for in place allocation and initialization.'] ----- -#include - -#include -#include - -... - -// Preprocessor Definitions - -// Allocate the structure using "raw" storage. - -#if defined(__cplusplus) && (__cplusplus >= 201103L) -#include - -#define chipDEFINE_ALIGNED_VAR(name, size, align_type) \ - typename std::aligned_storage::type name; - -#else -#define chipDEFINE_ALIGNED_VAR(name, size, align_type) \ - align_type name[(((size) + (sizeof (align_type) - 1)) / sizeof (align_type))] - -#endif // defined(__cplusplus) && (__cplusplus >= 201103L) - -// Type Declarations - -class ThreadAttributes -{ -public: - ThreadAttributes() {}; - ~ThreadAttributes() {}; - - operator pthread_attr_t *() { return &mAttributes; } - -private: - pthread_attr_t mAttributes; -}; - -// Forward Declarations - -extern void * foobar_entry(void *aArgument); - -// Global Variables - -static chipDEFINE_ALIGNED_VAR(sThreadAttributes, sizeof (ThreadAttributes), uint64_t); - -int foobar() -{ - int retval = -1; - int status; - pthread_t thread; - ThreadAttributes * ta; - pthread_attr_t * attrs; - - ta = new (&sThreadAttributes) ThreadAttributes; - - if (ta != NULL) - { - attrs = static_cast(*ta); - - // Now "construct" or initialize the storage. - retval = pthread_attr_init(attrs); - - if (retval == 0) - { - retval = pthread_create(&thread, attrs, foobar_entry, NULL); - - if (retval == 0) - { - status = pthread_join(thread, NULL); - - if (status != 0) - { - retval = status; - } - - status = pthread_attr_destroy(attrs); - - if (status != 0) - { - retval = status; - } - } - } - - ta->~ThreadAttributes(); - } - - return retval; -} ----- - -====== Use Pool-based Allocators - -In place allocation allows the successful allocation, initialization, -deinitialization, and deallocation of a single object allocated from -preallocated storage. However, if the desire exists for a fixed, -configurable pool of objects where 0 to `n` of such objects can be -allocated at any one time, a pool allocator for that specific object -type must be created. - -As shown in the listing below, a pool allocator for a `Foo` class of -`CHIP_FOO_COUNT` objects is effected, assuming the existence of another -helper class, StaticAllocatorBitmap, which uses a bitmap to track the -storage of objects from a static array of storage. - -[source,C++,caption='',title='{listing-caption} *{counter:refnum}*. Using pool-based allocators.'] ----- - -#include - -// Preprocessor Definitions - -// Allocate the structure using "raw" storage. - -#if defined(__cplusplus) && (__cplusplus >= 201103L) -#include - -#define chipDEFINE_ALIGNED_VAR(name, size, align_type) \ - typename std::aligned_storage::type name; - -#else -#define chipDEFINE_ALIGNED_VAR(name, size, align_type) \ - align_type name[(((size) + (sizeof (align_type) - 1)) / sizeof (align_type))] - -#endif // defined(__cplusplus) && (__cplusplus >= 201103L) - -// Type Definitions - -class Foo -{ -public: - Foo(); - Foo(const Foo &inFoo); - ~Foo(); -}; - -// Global Variables - -static chipDEFINE_ALIGNED_VAR(sFooAllocatorBuffer, sizeof (StaticAllocatorBitmap), uint32_t); -static StaticAllocatorBitmap *sFooAllocator; - -static void CreateFooAllocator(void *inStorage, - const StaticAllocatorBitmap::size_type &inStorageSize, - const StaticAllocatorBitmap::size_type &inElementCount, - StaticAllocatorBitmap::InitializeFunction inInitialize, - StaticAllocatorBitmap::DestroyFunction inDestroy) -{ - sFooAllocator = new (sFooAllocatorBuffer) - StaticAllocatorBitmap(inStorage, - inStorageSize, - inElementCount, - inInitialize, - inDestroy); -} - -static StaticAllocatorBitmap &GetFooAllocator() -{ - return *sFooAllocator; -} - -static void *FooInitialize(AllocatorBase &inAllocator, void *inObject) -{ - memset(inObject, 0, sizeof(Foo)); - - return inObject; -} - -static void FooDestroy(AllocatorBase &inAllocator, void *inObject) -{ - return; -} - -int Init() -{ - static const size_t sFooCount = CHIP_FOO_COUNT; - static chipAllocatorStaticBitmapStorageDefine(sFooStorage, Foo, sFooCount, uint32_t, sizeof (void *)); - int retval = 0; - - CreateFooAllocator(sFooStorage, - sizeof (sFooStorage), - sFooCount, - FooInitialize, - FooDestroy); - - return retval; -} - -Foo * FooAllocate() -{ - Foo *foo; - - foo = static_cast(GetFooAllocator().allocate()); - - return foo; -} - -void FooDeallocate(Foo *inFoo) -{ - GetFooAllocator().deallocate(inFoo); -} ----- - -====== Use Platform-defined and -assigned Allocators - -This is a variation on both in place allocation and pool-based -allocation in that it completely delegates resource allocation to the -system integrator and the platform on which the particular software -subsystem is running. - -The advantage of this approach is that it allows the platform to decide -how resource allocation will be handled and allows the package to scale -independently of platform resource allocation. - -The package may define default implementations for a few types of -platform allocation strategies, such as heap-based allocators and -pool-based allocators. - -There are a range of granularities for achieving this type of -delegation, depending on the desired size of the API surface, as shown -in the listings below. - -[source,C++,caption='',title='{listing-caption} *{counter:refnum}*. Using a common allocator method pattern with unique allocators per object, accessed from a unique singleton access per allocator.'] ----- - -chipPlatformInitFooAllocator(); -chipPlatformInitBarAllocator(); -… -foo = chipPlatformGetFooAllocator().allocate(); -… -chipPlatformGetFooAllocator().deallocate(foo); -… -bar = chipPlatformGetBarAllocator().allocate(); -… -chipPlatformGetBarAllocator().deallocate(bar); ----- - -[source,C++,caption='',title='{listing-caption} *{counter:refnum}*. Using a common allocator method pattern with unique allocators per object, accessed from a common singleton access with type per allocator.'] ----- -chipPlatformInitAllocator(CHIP_FOO_T); -chipPlatformInitAllocator(CHIP_BAR_T); -… -foo = chipPlatformGetAllocator(CHIP_FOO_T).allocate(); -… -chipPlatformGetAllocator(CHIP_FOO_T).deallocate(foo); -… -bar = chipPlatformGetAllocator(CHIP_BAR_T).allocate(); -… -chipPlatformGetAllocator(CHIP_BAR_T).deallocate(bar); ----- - -[source,C,caption='',title='{listing-caption} *{counter:refnum}*. Using unique allocators per object.'] ----- -chipPlatformInitFooAllocator(); -chipPlatformInitBarAllocator(); -… -foo = chipPlatformFooAllocate(); -… -chipPlatformFooDeallocate(foo); -… -bar = chipPlatformBarAllocate(); -… -chipPlatformBarDeallocate(bar); ----- - -[source,C,caption='',title='{listing-caption} *{counter:refnum}*. Using a common allocator pattern with unique allocators per object, accessed from a common interface with type per allocator.'] ----- - -chipPlatformInitAllocator(CHIP_FOO_T); -chipPlatformInitAllocator(CHIP_BAR_T); -… -foo = chipPlatformAllocate(CHIP_FOO_T); -… -chipPlatformDeallocate(CHIP_FOO_T, foo); -… -bar = chipPlatformAllocate(CHIP_BAR_T); -… -chipPlatformBarDeallocate(CHIP_BAR_T, bar); ----- - -:sectnums!: - -== Recommended Reading - -While the following references and reading are not part of the formal -best practices, coding conventions, and style cannon, they are -informative and useful guides for improving the style and quality of the -code you write: - -. Jet Propulsion Laboratory. -http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_C.pdf[JPL -Institutional Coding Standard for the C Programming Language.] Version -1.0. March 3, 2009. -. Jet Propulsion Laboratory. -http://pixelscommander.com/wp-content/uploads/2014/12/P10.pdf[The -Power of Ten – Rules for Developing Safety Critical Code]. December -2014. -. Meyers, Scott. Effective C{plusplus}: 55 Specific Ways to Improve Your -Programs and Designs. Third Edition. 2005. -. Meyers, Scott. More Effective C{plusplus}: 35 New Ways to Improve Your -Programs and Designs. 1996. -. Meyers. Scott. https://www.artima.com/shop/effective_cpp_in_an_embedded_environment[Effective C{plusplus} in an Embedded Environment]. 2015. -. Motor Industry Software Reliability Association. Guidelines for the -Use of the C Language in Critical Systems. March 2013. -. Motor Industry Software Reliability Association. Guidelines for the -Use of the C{plusplus} Language in Critical Systems. June 2008. - -== Revision History - -[cols="^1,^1,<2,<3",options="header"] -|=== -|Revision |Date |Modified By |Description -|5 |2020-09-22 |Grant Erickson |Added Tightly-constrained Systems and Shared Infrastructure > Avoid Heap-based Resource Allocation -|4 |2020-09-15 |Grant Erickson |Added Common > Language-dependent > Avoid `using namespace` Statements in Headers -|3 |2020-09-01 |Grant Erickson |Added Common > Language-independent > Use C _stdint.h_ or C{plusplus} _cstdint_ for Plain Old Data Types -|2 |2020-07-09 |Grant Erickson |Added Common > Language-independent > Commenting Out or Disabling Code -|1 |2020-07-08 |Grant Erickson |Initial revision. -|=== - -[.text-center] -_Project Connect Home over IP Public Information_ +==== mypy +The current python code does not yet pass mypy checks, but we are working towards this goal. The more compliant new code is to mypy, the better. From 5bd8597d35544b30c55bf4f3f21fcc59e3d1b6a8 Mon Sep 17 00:00:00 2001 From: cecille Date: Mon, 28 Oct 2024 16:56:09 -0400 Subject: [PATCH 02/13] Move coding style into main style dir --- docs/style/{coding => }/CODING_STYLE_GUIDE.adoc | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/style/{coding => }/CODING_STYLE_GUIDE.adoc (100%) diff --git a/docs/style/coding/CODING_STYLE_GUIDE.adoc b/docs/style/CODING_STYLE_GUIDE.adoc similarity index 100% rename from docs/style/coding/CODING_STYLE_GUIDE.adoc rename to docs/style/CODING_STYLE_GUIDE.adoc From f5774958439ff4839f50328275266f065242bef2 Mon Sep 17 00:00:00 2001 From: cecille Date: Mon, 28 Oct 2024 16:59:27 -0400 Subject: [PATCH 03/13] Use md since that's why the doc wasn't included --- docs/style/CODING_STYLE_GUIDE.adoc | 137 ------------------------ docs/style/CODING_STYLE_GUIDE.md | 163 +++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 137 deletions(-) delete mode 100644 docs/style/CODING_STYLE_GUIDE.adoc create mode 100644 docs/style/CODING_STYLE_GUIDE.md diff --git a/docs/style/CODING_STYLE_GUIDE.adoc b/docs/style/CODING_STYLE_GUIDE.adoc deleted file mode 100644 index eed9579daebab7..00000000000000 --- a/docs/style/CODING_STYLE_GUIDE.adoc +++ /dev/null @@ -1,137 +0,0 @@ -= Coding Style Guide - -[.text-center] -_Revision 6_ + -_2024-10-28_ - -This guide provides a small set of code guidelines used in the SDK. This guide reflects the currently accepted style practices for the SDK and is subject to change. - -The SDK was seeded from multiple different projects and contains contributions from many different companies and the SDK code therefore uses several different coding styles throughout the code base. Stylistically, code should attempt to conform to the dominant style of the code being modified, while also adhering to the guidelines below. - -== Language standard - -Code in the SDK conforms to the following standards. Changes to the C++ standard happen infrequently and there has been only one change from C{plusplus}14 to C{plusplus}17 over the course of the SDK lifetime. Changes to the Python version happen more frequently. - -[cols=2,options="header"] -|=== -|Language | Version -|C{plusplus}| C{plusplus}17 -|Python | 3.10 -|=== - -Product-specific software may elect to use later standards in their own work. - -== Coding Guidelines -=== Common - -==== When in Rome - -The most important convention and practice in the Matter SDK repo is "_When in Rome..._", per the quote below. - -[quote, St. Ambrose] -____ -If you should be in Rome, live in the Roman manner; if you should be -elsewhere, live as they do there. -____ - -Your extensions or fixes to existing code should match the prevailing -of the original code. - -If you find the conventions so foreign or otherwise confusing, it may be -best to let whoever owns the file make the necessary changes or seek the -counsel of others in the group to find out what the right thing to do -is. Never just start changing code wholesale for personal reasons -without consulting others first. - -==== Commenting Out or Disabling Code - -Unused code shall not be disabled by commenting it out with C- or -C{plusplus}-style comments or with preprocessor `#if 0 ... #endif` semantics. - -==== Auto-formatters - -We use the following auto-formatters on code: -[options="header"] -|=== -|Language | Formatter | Style File -|C{plusplus}| clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) -|ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) -|java | google-java-format | N/A -|Python | pep8, isort | [.restyled.yaml] (https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml) (command line) -|YAML | prettier | None -|JSON | prettier | None -|markdown | prettier | None -|=== - - -All pull requests run formatting checks using these tools before merge is allowed. Generated code is not run through restyle. - -=== C{plusplus} - -==== Use C{plusplus} _cstdint_ for Plain Old Data Types - -Standard, scalar data types defined in _cstdint_ -should be used for basic signed and unsigned integer types, especially -when size and serialization to non-volatile storage or across a network -is concerned. - -Examples of these are: `uint8_t`, `int8_t`, etc. - -==== Avoid `using namespace` Statements in Headers - -By doing this, you are effectively forcing every other module that -includes the header to also be using the namespace. This causes -namespace pollution and generally defeats the purposes of namespaces. -Fully-qualified symbols should be used instead. - -==== Classes / objects not exposed in a header should be in an anonymous namespace - -If a cpp class defines a class or instantiates a static object, it should be enclosed in an anonymous namespace. -``` -namespace { - // CPP internal defines go here -} // namespace -``` - -==== Singleton use -The decision to use a singleton class should be considered with care. Do not default to using a singleton for ease of writing code. - -If the class truly should be a singleton (ex. if it is controlling access to a hardware resource) -- The standard function name for accessing an SDK singleton is GetInstance(). -- Singleton classes should delete copy and move constructors - -==== Avoid Heap-based Resource Allocation and auto-resizing std containers - -Heap-based resource allocation should be avoided. This includes any container element in std that automatically re-sizes itself at runtime (ex. vector, string etc.) as these re-size operations are often large and can lead to memory exhaustion and fragmentation on embedded systems. - -===== Alternatives - -In either case, recommended resource allocation alternatives are: - -* In-place allocation and initialization -* Pool-based allocators -* Platform-defined and -assigned allocators - -[CHIPMem.h](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/CHIPMem.h) provides support for platform defined allocators. - -[Pool.h] (https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/Pool.h) is the Matter SDK pool allocator implementation. - -==== Prefer CopySpanToMutableSpan over memcpy when using spans - -See [Span.h](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/Span.h) - -==== Prefer std::optional to CHIP implementation in newer code - -The Matter SDK Optional.h was implemented when the Matter SDK was C++14, but newer code can use std::optional, which offers some benefits over the Matter SDK implementation (ex. std::optional is trivially destructible if the underlying type is also trivially destructible) - - -=== Python - -==== Type hints -Use type hints on function definitions for public APIs. - -==== Docstrings -Docstrings should be included for all public APIs. - -==== mypy -The current python code does not yet pass mypy checks, but we are working towards this goal. The more compliant new code is to mypy, the better. diff --git a/docs/style/CODING_STYLE_GUIDE.md b/docs/style/CODING_STYLE_GUIDE.md new file mode 100644 index 00000000000000..16cff1afe678db --- /dev/null +++ b/docs/style/CODING_STYLE_GUIDE.md @@ -0,0 +1,163 @@ +# Coding Style Guide + +_Revision 6_ _2024-10-28_ + +This guide provides a small set of code guidelines used in the SDK. This guide +reflects the currently accepted style practices for the SDK and is subject to +change. + +The SDK was seeded from multiple different projects and contains contributions +from many different companies and the SDK code therefore uses several different +coding styles throughout the code base. Stylistically, code should attempt to +conform to the dominant style of the code being modified, while also adhering to +the guidelines below. + +## Language standard + +Code in the SDK conforms to the following standards. Changes to the C++ standard +happen infrequently and there has been only one change from C++14 to C++17 over +the course of the SDK lifetime. Changes to the Python version happen more +frequently. + +| Language | Version | +| -------- | ------- | +| C++ | C++17 | +| Python | 3.10 | + +Product-specific software may elect to use later standards in their own work. + +## Coding Guidelines + +### Common + +#### When in Rome + +The most important convention and practice in the Matter SDK repo is "_When in +Rome..._", per the quote below. + +[quote, St. Ambrose] + +--- + +If you should be in Rome, live in the Roman manner; if you should be elsewhere, +live as they do there. + +--- + +Your extensions or fixes to existing code should match the prevailing of the +original code. + +If you find the conventions so foreign or otherwise confusing, it may be best to +let whoever owns the file make the necessary changes or seek the counsel of +others in the group to find out what the right thing to do is. Never just start +changing code wholesale for personal reasons without consulting others first. + +#### Commenting Out or Disabling Code + +Unused code shall not be disabled by commenting it out with C- or C++-style +comments or with preprocessor `#if 0 ... #endif` semantics. + +#### Auto-formatters + +We use the following auto-formatters on code: + +| Language | Formatter | Style File | +| ---------- | ------------------ | ------------------------------------------------------------------------------------------------------------ | +| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| java | google-java-format | N/A | +| Python | pep8, isort | [.restyled.yaml] (https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml) (command line) | +| YAML | prettier | None | +| JSON | prettier | None | +| markdown | prettier | None | + +All pull requests run formatting checks using these tools before merge is +allowed. Generated code is not run through restyle. + +### C++ + +#### Use C++ _cstdint_ for Plain Old Data Types + +Standard, scalar data types defined in _cstdint_ should be used for basic signed +and unsigned integer types, especially when size and serialization to +non-volatile storage or across a network is concerned. + +Examples of these are: `uint8_t`, `int8_t`, etc. + +#### Avoid `using namespace` Statements in Headers + +By doing this, you are effectively forcing every other module that includes the +header to also be using the namespace. This causes namespace pollution and +generally defeats the purposes of namespaces. Fully-qualified symbols should be +used instead. + +#### Classes / objects not exposed in a header should be in an anonymous namespace + +If a cpp class defines a class or instantiates a static object, it should be +enclosed in an anonymous namespace. + +``` +namespace { + // CPP internal defines go here +} // namespace +``` + +#### Singleton use + +The decision to use a singleton class should be considered with care. Do not +default to using a singleton for ease of writing code. + +If the class truly should be a singleton (ex. if it is controlling access to a +hardware resource) + +- The standard function name for accessing an SDK singleton is GetInstance(). +- Singleton classes should delete copy and move constructors + +#### Avoid Heap-based Resource Allocation and auto-resizing std containers + +Heap-based resource allocation should be avoided. This includes any container +element in std that automatically re-sizes itself at runtime (ex. vector, string +etc.) as these re-size operations are often large and can lead to memory +exhaustion and fragmentation on embedded systems. + +##### Alternatives + +In either case, recommended resource allocation alternatives are: + +- In-place allocation and initialization +- Pool-based allocators +- Platform-defined and -assigned allocators + +[CHIPMem.h](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/CHIPMem.h) +provides support for platform defined allocators. + +[Pool.h] +(https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/Pool.h) +is the Matter SDK pool allocator implementation. + +#### Prefer CopySpanToMutableSpan over memcpy when using spans + +See +[Span.h](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/Span.h) + +#### Prefer std::optional to CHIP implementation in newer code + +The Matter SDK Optional.h was implemented when the Matter SDK was C++14, but +newer code can use std::optional, which offers some benefits over the Matter SDK +implementation (ex. std::optional is trivially destructible if the underlying +type is also trivially destructible) + +### Python + +#### Type hints + +Use type hints on function definitions for public APIs. + +#### Docstrings + +Docstrings should be included for all public APIs. + +#### mypy + +The current python code does not yet pass mypy checks, but we are working +towards this goal. The more compliant new code is to mypy, the better. From 504fcf2b1b9d039c5d0a74029463b9e577742e7b Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 28 Oct 2024 21:17:05 +0000 Subject: [PATCH 04/13] Restyled by prettier-markdown --- docs/style/CODING_STYLE_GUIDE.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/style/CODING_STYLE_GUIDE.md b/docs/style/CODING_STYLE_GUIDE.md index 16cff1afe678db..58c26f386a3aa1 100644 --- a/docs/style/CODING_STYLE_GUIDE.md +++ b/docs/style/CODING_STYLE_GUIDE.md @@ -61,15 +61,15 @@ comments or with preprocessor `#if 0 ... #endif` semantics. We use the following auto-formatters on code: -| Language | Formatter | Style File | -| ---------- | ------------------ | ------------------------------------------------------------------------------------------------------------ | -| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | -| ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | -| java | google-java-format | N/A | -| Python | pep8, isort | [.restyled.yaml] (https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml) (command line) | -| YAML | prettier | None | -| JSON | prettier | None | -| markdown | prettier | None | +| Language | Formatter | Style File | +| ---------- | ------------------ | ----------------------------------------------------------------------------------------------------------- | +| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| java | google-java-format | N/A | +| Python | pep8, isort | [.restyled.yaml](https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml) (command line) | +| YAML | prettier | None | +| JSON | prettier | None | +| markdown | prettier | None | All pull requests run formatting checks using these tools before merge is allowed. Generated code is not run through restyle. @@ -131,8 +131,7 @@ In either case, recommended resource allocation alternatives are: [CHIPMem.h](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/CHIPMem.h) provides support for platform defined allocators. -[Pool.h] -(https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/Pool.h) +[Pool.h](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/Pool.h) is the Matter SDK pool allocator implementation. #### Prefer CopySpanToMutableSpan over memcpy when using spans From 6e49e9fcc2311c994117c9dda19b2a61e706b7ae Mon Sep 17 00:00:00 2001 From: cecille Date: Mon, 28 Oct 2024 17:22:16 -0400 Subject: [PATCH 05/13] add new words to wordlist --- .github/.wordlist.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index a5dee8881fec76..59638c45243bce 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -41,6 +41,9 @@ AFL AIDL algs alloc +allocator +allocators +Ambrose Ameba amebad amebaiot @@ -317,6 +320,7 @@ cryptographic CSA csg csrrequest +cstdint csu csv ctl @@ -440,6 +444,7 @@ DNSStubListener docbuild Dockerfile Dockerfiles +docstrings Don'ts DoorLock DoorState @@ -565,6 +570,8 @@ FlowMeasurement FluorideConcentrationMeasurement focusable forkpty +formatter +formatters FOTA FreeRTOS FreeRTOSConfig @@ -731,6 +738,7 @@ IPython ISCAN isHexString isLowerCase +isort isUpperCase itemName iterable @@ -878,6 +886,7 @@ MediaPlayback MediaTek MEI mem +memcpy memdf MemMonitoring menuconfig @@ -933,6 +942,7 @@ mv MX mydir MyPASSWORD +mypy MySSID NAMESERVER NAMESPACE From a7325c531f683d6c7ce5684e8d3fbba8cce22731 Mon Sep 17 00:00:00 2001 From: cecille Date: Tue, 29 Oct 2024 15:44:37 -0400 Subject: [PATCH 06/13] Add clarification about heap allocation --- docs/style/CODING_STYLE_GUIDE.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/style/CODING_STYLE_GUIDE.md b/docs/style/CODING_STYLE_GUIDE.md index 58c26f386a3aa1..4b4bc83e01a07a 100644 --- a/docs/style/CODING_STYLE_GUIDE.md +++ b/docs/style/CODING_STYLE_GUIDE.md @@ -115,11 +115,15 @@ hardware resource) #### Avoid Heap-based Resource Allocation and auto-resizing std containers -Heap-based resource allocation should be avoided. This includes any container +Heap-based resource allocation should be avoided in the core SDK for common code +that may run on constrained embedded devices. This includes any container element in std that automatically re-sizes itself at runtime (ex. vector, string etc.) as these re-size operations are often large and can lead to memory exhaustion and fragmentation on embedded systems. +Heap-based allocation is allowed for controller code and is at the discretion of +platform vendors for platform-specific code. + ##### Alternatives In either case, recommended resource allocation alternatives are: From 8a6b0b6ad769c0d652222ece43ae300d0aaed706 Mon Sep 17 00:00:00 2001 From: cecille Date: Tue, 29 Oct 2024 15:51:44 -0400 Subject: [PATCH 07/13] Add clarification about code removal --- docs/style/CODING_STYLE_GUIDE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/style/CODING_STYLE_GUIDE.md b/docs/style/CODING_STYLE_GUIDE.md index 4b4bc83e01a07a..a4e679f70ff5cb 100644 --- a/docs/style/CODING_STYLE_GUIDE.md +++ b/docs/style/CODING_STYLE_GUIDE.md @@ -55,7 +55,8 @@ changing code wholesale for personal reasons without consulting others first. #### Commenting Out or Disabling Code Unused code shall not be disabled by commenting it out with C- or C++-style -comments or with preprocessor `#if 0 ... #endif` semantics. +comments or with preprocessor `#if 0 ... #endif` semantics. Unused code should +be removed. #### Auto-formatters From 585534fecd4ca6465d462a3cfd1d38a101c59586 Mon Sep 17 00:00:00 2001 From: cecille Date: Tue, 29 Oct 2024 15:52:01 -0400 Subject: [PATCH 08/13] add isort ref to formatter table --- docs/style/CODING_STYLE_GUIDE.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/style/CODING_STYLE_GUIDE.md b/docs/style/CODING_STYLE_GUIDE.md index a4e679f70ff5cb..95129bdd28ca6a 100644 --- a/docs/style/CODING_STYLE_GUIDE.md +++ b/docs/style/CODING_STYLE_GUIDE.md @@ -62,15 +62,15 @@ be removed. We use the following auto-formatters on code: -| Language | Formatter | Style File | -| ---------- | ------------------ | ----------------------------------------------------------------------------------------------------------- | -| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | -| ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | -| java | google-java-format | N/A | -| Python | pep8, isort | [.restyled.yaml](https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml) (command line) | -| YAML | prettier | None | -| JSON | prettier | None | -| markdown | prettier | None | +| Language | Formatter | Style File | +| ---------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| java | google-java-format | N/A | +| Python | pep8, isort | [.restyled.yaml](https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml) (command line),[isort](https://github.com/project-chip/connectedhomeip/blob/master/.isort.cfg) | +| YAML | prettier | None | +| JSON | prettier | None | +| markdown | prettier | None | All pull requests run formatting checks using these tools before merge is allowed. Generated code is not run through restyle. From 850870c1c07625ea2620c8f07b492379feb0bc13 Mon Sep 17 00:00:00 2001 From: cecille Date: Wed, 30 Oct 2024 10:04:24 -0400 Subject: [PATCH 09/13] add ruff --- docs/style/CODING_STYLE_GUIDE.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/style/CODING_STYLE_GUIDE.md b/docs/style/CODING_STYLE_GUIDE.md index 95129bdd28ca6a..877a91315ef82a 100644 --- a/docs/style/CODING_STYLE_GUIDE.md +++ b/docs/style/CODING_STYLE_GUIDE.md @@ -62,15 +62,15 @@ be removed. We use the following auto-formatters on code: -| Language | Formatter | Style File | -| ---------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | -| ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | -| java | google-java-format | N/A | -| Python | pep8, isort | [.restyled.yaml](https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml) (command line),[isort](https://github.com/project-chip/connectedhomeip/blob/master/.isort.cfg) | -| YAML | prettier | None | -| JSON | prettier | None | -| markdown | prettier | None | +| Language | Formatter | Style File | +| ---------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| java | google-java-format | N/A | +| Python | pep8, isort, ruff | [.restyled.yaml](https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml) (command line),[isort](https://github.com/project-chip/connectedhomeip/blob/master/.isort.cfg) [ruff](https://github.com/project-chip/connectedhomeip/blob/master/ruff.toml) | +| YAML | prettier | None | +| JSON | prettier | None | +| markdown | prettier | None | All pull requests run formatting checks using these tools before merge is allowed. Generated code is not run through restyle. From 8e0a796ed3e449fb29039a89546cb21b87d3a802 Mon Sep 17 00:00:00 2001 From: cecille Date: Wed, 30 Oct 2024 10:14:00 -0400 Subject: [PATCH 10/13] use links --- docs/style/CODING_STYLE_GUIDE.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/docs/style/CODING_STYLE_GUIDE.md b/docs/style/CODING_STYLE_GUIDE.md index 877a91315ef82a..130824b9ac33c4 100644 --- a/docs/style/CODING_STYLE_GUIDE.md +++ b/docs/style/CODING_STYLE_GUIDE.md @@ -62,15 +62,22 @@ be removed. We use the following auto-formatters on code: -| Language | Formatter | Style File | -| ---------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | -| ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | -| java | google-java-format | N/A | -| Python | pep8, isort, ruff | [.restyled.yaml](https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml) (command line),[isort](https://github.com/project-chip/connectedhomeip/blob/master/.isort.cfg) [ruff](https://github.com/project-chip/connectedhomeip/blob/master/ruff.toml) | -| YAML | prettier | None | -| JSON | prettier | None | -| markdown | prettier | None | +| Language | Formatter | Style File | +| ---------- | ------------------ | ------------------------------------------------------------------------------------------ | +| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| java | google-java-format | N/A | +| Python | pep8, isort, ruff | [.restyled.yaml][restyle_link] (command line), [isort][isort_link], [ruff][ruff_link] | +| YAML | prettier | None | +| JSON | prettier | None | +| markdown | prettier | None | + +[restyle_link]: + https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml +[isort_link]: + https://github.com/project-chip/connectedhomeip/blob/master/.isort.cfg +[ruff_link]: + https://github.com/project-chip/connectedhomeip/blob/master/ruff.toml All pull requests run formatting checks using these tools before merge is allowed. Generated code is not run through restyle. From 77e530e3907c5ae91917697d4296f185e23f17bf Mon Sep 17 00:00:00 2001 From: C Freeman Date: Thu, 14 Nov 2024 13:15:15 -0500 Subject: [PATCH 11/13] Apply suggestions from code review Co-authored-by: Boris Zbarsky --- docs/style/CODING_STYLE_GUIDE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/style/CODING_STYLE_GUIDE.md b/docs/style/CODING_STYLE_GUIDE.md index 130824b9ac33c4..088c9a97a92ebd 100644 --- a/docs/style/CODING_STYLE_GUIDE.md +++ b/docs/style/CODING_STYLE_GUIDE.md @@ -44,7 +44,7 @@ live as they do there. --- -Your extensions or fixes to existing code should match the prevailing of the +Your extensions or fixes to existing code should match the prevailing style of the original code. If you find the conventions so foreign or otherwise confusing, it may be best to @@ -65,7 +65,7 @@ We use the following auto-formatters on code: | Language | Formatter | Style File | | ---------- | ------------------ | ------------------------------------------------------------------------------------------ | | C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | -| ObjectiveC | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| Objective-C | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | | java | google-java-format | N/A | | Python | pep8, isort, ruff | [.restyled.yaml][restyle_link] (command line), [isort][isort_link], [ruff][ruff_link] | | YAML | prettier | None | @@ -92,7 +92,7 @@ non-volatile storage or across a network is concerned. Examples of these are: `uint8_t`, `int8_t`, etc. -#### Avoid `using namespace` Statements in Headers +#### Avoid top-level `using namespace` Statements in Headers By doing this, you are effectively forcing every other module that includes the header to also be using the namespace. This causes namespace pollution and From a3d63d7d739879d1227d619207a52a6f3377209f Mon Sep 17 00:00:00 2001 From: cecille Date: Thu, 14 Nov 2024 13:16:57 -0500 Subject: [PATCH 12/13] address review comments --- docs/style/CODING_STYLE_GUIDE.md | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/docs/style/CODING_STYLE_GUIDE.md b/docs/style/CODING_STYLE_GUIDE.md index 088c9a97a92ebd..bba6ef4ffadbf5 100644 --- a/docs/style/CODING_STYLE_GUIDE.md +++ b/docs/style/CODING_STYLE_GUIDE.md @@ -15,9 +15,7 @@ the guidelines below. ## Language standard Code in the SDK conforms to the following standards. Changes to the C++ standard -happen infrequently and there has been only one change from C++14 to C++17 over -the course of the SDK lifetime. Changes to the Python version happen more -frequently. +happen relatively infrequently. Changes to the Python version are more frequent. | Language | Version | | -------- | ------- | @@ -44,8 +42,8 @@ live as they do there. --- -Your extensions or fixes to existing code should match the prevailing style of the -original code. +Your extensions or fixes to existing code should match the prevailing style of +the original code. If you find the conventions so foreign or otherwise confusing, it may be best to let whoever owns the file make the necessary changes or seek the counsel of @@ -62,15 +60,15 @@ be removed. We use the following auto-formatters on code: -| Language | Formatter | Style File | -| ---------- | ------------------ | ------------------------------------------------------------------------------------------ | -| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | +| Language | Formatter | Style File | +| ----------- | ------------------ | ------------------------------------------------------------------------------------------ | +| C++ | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | | Objective-C | clang-format | [.clang-format](https://github.com/project-chip/connectedhomeip/blob/master/.clang-format) | -| java | google-java-format | N/A | -| Python | pep8, isort, ruff | [.restyled.yaml][restyle_link] (command line), [isort][isort_link], [ruff][ruff_link] | -| YAML | prettier | None | -| JSON | prettier | None | -| markdown | prettier | None | +| java | google-java-format | N/A | +| Python | pep8, isort, ruff | [.restyled.yaml][restyle_link] (command line), [isort][isort_link], [ruff][ruff_link] | +| YAML | prettier | None | +| JSON | prettier | None | +| markdown | prettier | None | [restyle_link]: https://github.com/project-chip/connectedhomeip/blob/master/.restyled.yaml @@ -96,8 +94,8 @@ Examples of these are: `uint8_t`, `int8_t`, etc. By doing this, you are effectively forcing every other module that includes the header to also be using the namespace. This causes namespace pollution and -generally defeats the purposes of namespaces. Fully-qualified symbols should be -used instead. +generally defeats the purposes of namespaces. Fully-qualified symbols or +namespace blocks should be used instead. #### Classes / objects not exposed in a header should be in an anonymous namespace From 2a4cfe551db3de10f9f83e8b177421a71d3ffc4c Mon Sep 17 00:00:00 2001 From: cecille Date: Thu, 14 Nov 2024 13:19:15 -0500 Subject: [PATCH 13/13] Add link suffix toml to wordlist --- .github/.wordlist.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 59638c45243bce..c43d780c0f2a60 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -1452,6 +1452,7 @@ toJson tokenization tokenized tokenizer +toml toolchain toolchains topologies