From 2cd7484da96b091a123ba3c09036b2be7df340df Mon Sep 17 00:00:00 2001 From: agazzarini Date: Mon, 23 Sep 2019 18:37:03 -0700 Subject: [PATCH 1/3] [ SEARCH-1865 ] ContentStore Replication ADR --- .../architecture/ContentStore/filesystem.png | Bin 0 -> 84421 bytes .../architecture/ContentStore/replication.md | 161 ++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 search-services/alfresco-search/doc/architecture/ContentStore/filesystem.png create mode 100644 search-services/alfresco-search/doc/architecture/ContentStore/replication.md diff --git a/search-services/alfresco-search/doc/architecture/ContentStore/filesystem.png b/search-services/alfresco-search/doc/architecture/ContentStore/filesystem.png new file mode 100644 index 0000000000000000000000000000000000000000..034842e9fd6ca5b55f39b04c496dd3450dedfbb7 GIT binary patch literal 84421 zcmbTd1yG$^vo?qm+%0HAa0~7pAh^4`yKUUvA-KCc1h?Ss?(XhBn{)Erd;glbQ#C^s zuy?;px|j4?&(r;e$ViDGzEFDkvx; zDkw-KV`pt-YGDWh@-rkp5n4rl5Yu}<;oG-wb$k$c{%a5vQ~C2h;}KZ|P=Ause}ll_ zY%bbRlacKTEej@Z#N@-oy{q|j_a^g0NEHi?MPcn5sKc$>xyQNt`pWbENHXJo8mF@z zG{~&U@1MUSNPK|Qcd;yrKu`gec-uhV zRfDvG4VxxO4GEAP1(07w7QflRK`>M`M%<;KZgOkzYTBZykOi!KPDVFto1%FI3F6`y z@oP#*42J8@UkqNljhBL@Svd9mF`5R1C}fCG3~P;FGj|`>W8-M>GrA#ID7EoE6A!B@ zHIyCdG872#kV%Av`<8(|rg&2|BwnJmGckD%yn&0Lf|x^LgJdbta(;)eAu!O_buxH} zUgOk69`S`YkLrWDQn3xKCRgU-HX7jNh$Dju#W(t`!jm{sppt@d&bng{m)ZaMZc(E% zN?f5Qenx&eC=d|p$ND&E?S*P!Faz>#Ptp6yNx4#9BggE|3ER0#=!3fxLiP% z4SYcy-|i2f?9-EHw{Wpoie_|)&AZrSYijKz64FxnB8|<9&Z|T@bRC6LQ;BLQg0!el z(|UrOyoPO;`i<8KV4+Q*VG-(XOEeS~Dc=)lZd60|gG#TnoS*Fzh>tf+URA!&AracA zC0AUxO*$dz?>gZ010Y;FoOw6|G34hcf6S@LLA?04KnDldyj;HGxl z9#LwS!Ek=vj;X&? zX=e#E4vXoJgM9tunG(g#R9I$)`mFX$@H{T)K@`QxD1BE0A%QiD3diu^BEj3Jew{@9 zrQZsEdUCA`A7pW@azSnF`;HsOpT-NxL^nK;d%dEOhXVa>?t=?7kc0E~LkX>J!wy() z;#0h0Htp7TYL;ju*V}o#|rR9-t0PG z$iYZ-FjSz2x|FKGPr%%|JSRS>b;8&{X+WHAa5Tcri?ISgpE^0edlP+v$^PQ-1DgKF z2r_ODimhO44AD2d5dPR0g>T>}U*!xCYd%r%i^bR(aLW0;MB)ic5$(qy?yy`TAM$Gv zXUf3m=cE+zm_j)>&>;*#V$g035M21wmsL(3~D(X3^FuG4ES4)*)JqM%Na*Xv@Zn`4$ZrdVegpGG6 zZtp(Owu15oX!jCsc|0hCMP!LoeE}e=_olFtXN`Mel@!XNq7ez10cYEW^<=*rNJ)x|qUsyYiG zyG5S-E8rKxFODJ8A?_huLqkJ-L+9O)A+TM@A>3d06q)j#MK3WW{PhJ;GGy}kGZ-^w zN47_nN4TFOjHIsf^CzxMs7#pa;_9I5kSHB6I584nl?~g)0>u1=Fya$S3=|m^d1s4D zAWIBOpcUv!?@D53M`poh7R;_^C}$8$R~3$x3rjhRM2h!|=#M?wMkl&zoz{zvXq$z)THJ zsg_R{*=u9X*UzOFaSA$zotdt#O{U~>i`WZeMXm8ZMG}-4mt*C!s#^!Gk+gYwfWIPp z#JmZ=#yzz`!Gml2N%+-6i6FSb9|o=kf_2vi_QPi~)+c$6SnNUVQ5a>$WXKl9%$T&u zrcQcS2iUgSX4|%1dZ2}dq>45Vs>LbA@yH8Kf0|}5s4s9H88EUka<9ELG9Fz^RZk*I zp`*8E@-oV{?5ZKJDynZZ7OlOh9;q*@Yc&$8v#TAdS+bb5icsTJzb>aLqg&2mp=AL} z9c97S|D?at|EXUgvdL7u{)-mo_l2x+7q+!=;e+B03?d*D0eTCPx5wPQOa{sVAJ;yj~->_eMiMj2v zUE1gDg5y@*_S?iK_D1-|(ndS-e)Qs(enFUQ-Rx39>zW%?JSBuu zYu{u4CN!x4*>1h=p>Bcz^`NlsRN{$X7!>obXF@4Lu*A5zeCSkWk~6O+VFxP*yrigP z!qR0)58wK}7)gyRs<@uiEv#0bZ@p|Q^{qxUgeUejkQR|jNEL|!GO?3XQWlb#SWK;^ zdJR?$`0eCjDM-E;8jHQ>Wr-e>I!ZfbXfQqYp@&g07N%vEa5B3c#h8{%FH9rmp~|7j zI~RHyiBwZ9zM7WRNt$}3fsDD1!Bx;X(=-I__fqY0OWupoNqQx0##fW(2Ay})ZQsL! zLG1b}Cub+CGp-v887dkh7?Byx@00K5?crgXeX8{@EWnk>WN#BRAf`lh+;iQj7(PV{ z3UL-g9z++F&mesnX#ZCK>+P#Y(s{ae%)74epKx%-Sz}mZtrSCU^To14$S%l^(LQ5) zqlPj1lv+4$8=g% zjmL@6+Gb%2p*=#Zi2&NgW^`>zm8IV!ri*=s+F?z-SYjvQLt;F1`_vs5rQMadp76ov-6*+SQMKA6e5ZKAEQKESH~tS;nOtr5biZ zcHTJ$$i>Sz-mx~Un>ihwQ7=B`tEsFuQ5nq_f1XcCS#@nup3AA9TFT&#yRSP(SXovu zR&Qv_kkzh1I*B`TdviNFXT1wLwdUS%$~wzh?2-&R2nxlG4pc?(h_$Uu zU~yw1eCj@nI>O9N2qjh%Q6k94({y*ZQ0c0E+s@f;BV&+qsFyNtb7MH%sh3BSu1`ng z^f;5aNRBgp9V6h}cdXcL?SJgXTA^jqa%ftx8GM||=1qU+n%SG0vst{glW%czv+sY1 z%vE-;NNfBIxE*1hs}Gweu5?}r?yx=H+euAtXl%$>9czC*l6p(`X@NUKIm1|2ZqdHu zJLli+D0@>}Kb&&e(cS14kJ2MtJ>7C>15mrXG`U@(EydLo21=V}u=AK7!kn3U@f^C` z!%c?ytmSmfyf58MUF~*tc)YjIB+ksgioKX!++MMASeL9vx-BmeuD)+*jpaWaAS zW)QVyiG#~wlOBS3AyZ0Q-`N7=tEU6Ggai2$v`((B!{{dw;Jio%NTcIRPZM5>{yCM7 zhtXbi(IfEio$W!G5JZjJhtIz-tIl$QbRJ8{I!6f81)Q4l0ro9QxLlw7Le?dWN(BOB-Nm z5D+c^2k@h%p@S|Fz|z9Xo&&)B^`8cLPt;go$kNd23FE6JC47Xi3i&n1hNUOnmmvZu z3a&G-7|1k3Busp$s-jA<@6VBrgAz5dWj$qlvDOD__7%3N_U+STydBo=`r-atTU%l( z43H9_@}214A(tA#V4zxA-U3fA|4P!pptzoqx`5Asf-FsPolbMC%0+^ye+8Z1#_tG8 zU43;$3Vl*iDc0Qe=)ym+`1KI*KiSGn9?XGjX2SB~3>AU9f z#4(_#H1TKqn&c{u@8D474;O#c%?>L$^&1pM9qcd_Wv7LM4nO4aWAM-wY%|~CSIKWQ zkW!m*in4=J?o7Dg?P3lFT9lf3^LKZfX*Z0cLPriYbpMRGS_fD;I3P1Vi`Pe4tc`Q1 zgm`6u#^%#Fe+0C%gh56W@6dxfQQ3yIsuvfVxlDzOa!`l(!xv~x?pu;z*etR9H@RQv zct6GhjP257hyyK2Fm(5qz50}U^AFrMd5LS^i+}rX+wxu>)Rwn;xgpADc~Hq904h7) zIPOlD@5|9~m`so>TF#oSXM-B5sau7-sQO{FMHD8?s9?Skslu0hYx~Kh>JSW*v-A0y|J-EiCxAV#p@ESYta}L0uW5ARc>!8U-*BC{Vp8S8Sn6hw zaYeEaA&%yr)+}?z8^#^1(}5Sexfte8zh?{6P_p6;$>`5l#2n66*cY;B+@E>7Zm39g z;WA0C+nH5d?jH;9inl(7>3XKbK$#U%!pBH1>+{9TK5&#S*WAvTi=V~m+R#;1N6nc( z0g${>yniuraFRO`r9m*ERQgVcZP9n;Qgf5w8`KZ>QP87oRj7Z1A`@pA)rHY%|BTY`=stOx6ZA)R4bpzq~K_ zE?aqg5^=#Y)yL9VJrPH_05A4%&6ztr%;4FvcSrM#d}}1PM>caf&L|`~BYPi~zG&#! z@8;gZS)KG6kVz{Ky3Zr!&b`;{Epd}R8dFAVE!;lKctUDH_xpt-6){1#(h~{X?a11Y zW}ubfUb1f&LA-o(TKchN&FWT7kb{GR5vFrGt3(&r5>p}52oMaOOipA26ms$)(?sdg zLhR?-$3Rwb_H@`=`c;bmEY z5!01>@{88MZ5*5kR_|R1=kfNq4>+x#|Liz=T-iYY4vlD`kg7rn2SD=Fh^$zZPhXx= zwX`6|GV=W?+&D-=p%bD}bH)UMAOr*5F3@o{S6stY<9fb)wO46UrE%?G%%jtA>Ghy9>w?mWePa6T~Gn(bj`*RcT@{$=yYtrhOjd=3m zD{YmDC@&loL8UjsND#2UgXs5#hvb{(9)AKf5kgNe*9Y0ln@NlbDTXS6Vf*Y+vw}vb z`o??Ov(Z1O?`Ahs8l%ZY+$PZ_7K9z_G;JKNq-WRUY(oNGeDfBlTm33Gw~h(q#%U!r ztDxTPULXAxK%jYD(4wSV2O?4@V}cc;#1DBjqSZ>`%GT&1W8{@ql+8t`bL!5usYxoVQC#O1FlE{KdTj9vB>Uf>lX(z0tN zW*VQ5p@6pc35R%rR0bnN?UbFtWb{>fC3-Q)`))gK{tZ8lKn>-{6n)NG+y6QZn$GjS z)@{^brTO~!$^r8S`X}bjhXo- zsOCH;ez~|CI8ig`j}_Dc<_IQDJ6dl(-#jqzboNI?d#fh|EtOfO*NuCB>ZK80(`~}{ zOCtoQsxih5@6%2@`bg4EL*j~^ww*Ps*_fGrfkwPbh#z}6bDYdro+*Nm@sZhe#E+6_=g|eqh-yp-Mkwm=j+m5^rkF+gt z&NK)dOpMkUewk9Ze%DWV!Ww@zmrI<&Z*ivE1I}^}QnVCyQxLT}ik}o)+@5tmHk?A1 z)&_;Q;cBxZ-Z*8rE1YJFljAgU3MX)_(1V`u6FyD0Inx=B#)$kR&0-4CkVj85?Bjy0 zInV%^?zySzC4-aE2bd8r9OkZDaZBwLYgn?Qb@|Be*L;OT#Q&p@wan@uo}DV%9bC<- zGjm@X?eX|YxW@H7X8#tfvdJNeB|o?LX|~bp+4RF^d7#aQC7=6Csk}+Fd??onF)lox zJW*V4&-T545H#taJ(4nW^XohMX7Q*A37MP28sR@u>^4zz`N-}*p?=!kqSjZx%{N6X z!>mSDEO>blgudt@(fkaRL00v3ugP+D=|>QzHK-zO4~Mt%Fio*i-9?UXEaYuhr@eGV z98`M=X@#;Xpnf&4ODe^IH~SdNqY1KOY_u1Svs9nX-EB5UHXdi2aSqbhaq`=0YFTE5 z$sq6&swUtAYXzR=Ph0E3(ZR;D^`=)uU5wb+G3u;fVx|9A+ML-tKce2eHgDhaa)Zt_p|*FT*IHJ*t53f(2JdQW ziT3S&o%YA!&kLysrZozZ0Dvw55Gr@N9lWCbJYQZ1mDI6^C;kP&+!Y#bCt^H#slg|Y z&o2?rWP}yjS+*!_sW_?{MrjahenSQJmYA5&VzKG6mu)&yM(IkwpnTEtsinay6zwI3 z}iKo|36UT0h3xmb&Jy zQLjAJK)CgcY^nZ_3#faIEhy=z$D|>AuDP?~LcMxsfbyv(bHf?Xg}g{OF#&IP04ij( z3kNhc4|fLW3D^0mWJ#EZ+g50+dsBc5->|^deC1R(-($narScMe+tZV_T08`~1c^{i+@t zO7xt4z4;woJq$zLciVL>r94Uwn{;h1arG|{C=w|Y&;wXV7AZOh~MFIQ~01ca3zx=j+6WS+_;vWw)763n>QEP z>l$D+!veR*>wi36$sW7c->0fipLom`xe*C1o_hk2Vb*n{p0oCVN7^WySz14^- zH0}O=+n)T8XscSk_oeSD{BnZZ-7jLAZe{2nG-3^@26^Fmccy&6dY}Q#VLUY{Fs%UI zM7rDUFpUUspvp(qshI%SgozJRqOT|@6Uo0`Kse0GqV7XXR#7QnZuxYa_WkiXn6c!K2WWi&-M!@@sQ#GkToue1&-Fw>e2#kJu(9apb4G4e^}MXfe%_o((TN zqbbSUuRfgtZp<922}_)_{G38o-m-k##eAe%veA^e?rmQxVpBU}HNyEs zvljRD5AxwLtO&&$AJfFA`>!B=)5NI`_;5DBY=3ejjN+k+*(>}b~fOFR(~e2_6={etS5e=R$e1_jr8cH6(}`L|c` z5Ax}%epwL6C3sUzyrF;JsPAyLlC}U|9SZnb6gs`;55kPNjVyg!%he$2wk3 z&HgRoO=0tyQm2y>K|6Hy!%ckDx~2lMU7nKVBLDC-5gmFw9CkOT=>Z`a}ou)16qYP;siL^KsutbsrUs?;E`(3gEYOj+2$n z?h%oz(=jvIe!uqwn||-WjoQr=)Vq`UdJ88{Joh(VV0jV&7%EpIpu^sH8gX@PrGgg|ZhevY}e+NPkXvJqa z^1iFBExnhkZm^rPX)Iq25>_2L<;ug!~%i17rZGW^^o;z-NM@USUUw_v@ztVcALqrFE{agm;{@P_^@!AS9*f!Sh zsEmNH+CYoZdJpvsgT9eIzpi^KoL7U$=Dc%HU#B&SJDI7-47rpH2Gwfhx`_zzqTura zllEHwhoP&p!40~=n*rGL|JZwc$PMp+?16ntxb63=h1!L6bbM&>C$yWGmDlzy0x3~A zq7yo-7JRtOe@*c)zC+5u4+{z7h0`j^I1jTP?%lR0)wf9`kB4p0wU{$tT7g?G81I>D zb(<7iWy;ZX9W&cm^-}#622M!RfzQhQ=vifPgZ2Ozgg{C%W4hF+ZRhbThrP6L!o(!p zq&xR0{XXZ(b?fWVcb8u4N_EyTQjD$+UTO$jjwq07Bo|tqkB07dsuEtp#7Jt_1_RMw zuz5Y*M^8xKF)uu;Ymv#^@mI%ANPHl^4L|6DgawlhSH!*#tRCv~i3@@Gss3!L;UkF^ z<=r)RzJ*N*q!s`h-hstfp)|QH##Qw=YiJSwm-+xc%rRT@1)srC3D_iBd+3yb$xrXS4_^@Q&t zNii;HYelOrZR|~SXPrB6xv%R&ZKGuqz&%vNR|>IKt>0f|w=35Cc(89SASNNv^NT`0 zIwfW4Uyc!}^;|^m|3AlgSvn$hu+n5-#n0%W3>uZSASMHd2<7|Y^!lhs-D+F`ZFHz| zvuD(-!c8kRPWb+%u1Bl58@1GNSkiL;un0I-1I>q`(um(ZCsS1(y6sDLg**Wji{u*! zUoNyv!7jdH-DRNbJT6dOt2?vG8)K--_rlzAdf~AiAe&$vjR$ruG05Ux3 zG9vJg3m|E<#_bo2fqsTb(?M(jT|vj%*B^Q$0OH_8Gpqn~Y;2guj_g96+X%Wydx-dcjvR)r zTeIm&-`V_Ih55fNta-53Yc|3)!xc_xk}DrYCzn>=_$u32My938mQDOjrMy2buD#&u zB>w3<@rQBW@Bwmh68+&0woYy1aPt0S(U14-GAcrDGZ5FRbEC@-ca}6^2yAWS9(J)Aw z?BgxkO}M;$JMCUZ7bD!X03(3r{bZ53614nv6I1EEd1vXX6-__-0}E`O*~VcPB$p3e z!mpSZ9~d;!9=ZBSM~K$vbxxm(Vm!w$txTl*Ig~@|9z!X!@`V-L(WnG(*LApKS-;jr5X6et+K&XZdQw{m zdf9^$lxP2>yHqX`8I<}BdMgWx19^b70@ym&jlulK75nifAWg<}H<|dc+F8xBLhoJ2 z@*mf19Zq9}#UORbj>~+#);;XBVT~l7Ql+e#=$cp|nT_k|<;js(AOzlUlYb*aWreN5 z&l+ol*S<*MafcSto_m`4?ECcg`u8@IcW!Ubq}t6fth}MVjr+zH@-}@Di7GS%FsSUj zzCo>b5lgSbS*O8ATJ$ZPq-8PhgU-*_Jqhn|ou`a@+HwN@m%hxDy`;UVtKx5a`K(j& zi6fsvWfXA`aV{{$)^{9W5TRAs`O)* z<*7cl_82Fbkz{Kt;V` zZrdD==SC$3P0oPqL@z|E>iHY^s@uKY9G;860hn0a0J9MPWU_CPPLVyR1ln{rW+pXX z#Ab2C5s*PLtK^C=r7`}>W^<%LJMAkNba4}JT8Ir$MLpT(Ng zM{BtuQLg)3b7DifGYucO?s<9jab^SnKlAA_x`{b#9n8jI{tQ+pY9&y2FL%ZAp5Zuv z$JmffOEmL>vlt(thO|y++D&e zTxtzOY__>!A9_65V#E_A85EeJva<*7Of*q58~4)7o9n}>*-65Bi`f}Bv%7O4NlQ7O zNhiPs(&_||+4&uDh_rKf8`ntFT&yLfM&KO#+Fu&kQJ<}m>)RrzOS(SEn4!D>iSV|R zj_BPn%v3a-aZcclvWK!RO<`1d0JR!V`9za3b@A=-sI!!Xzcu8Zpmp}>RqdCN2i?Sw zgijyUM1i+5qc_Q#52aQUWb5-4;@39o_h7gw`fwT483-zdA^dcqetXvJG!a&jsQ+en zW;1Is6$ie}A1FWH>kkgJ7moa)dNN^dcbk6MK+xr4InxNv)>YP(e}7=j*VMt<)A)`^ zcPte+(vxalm?N^0R~swH8k8pm`m)}H_Wjt96%K#+N~>#Nz{~^^kWiWik%)vJ5kW}T zH4$9Ov?6$*a)H>Vg_5=hLL2fsT|7rfKqtlSJmw4mfI@N7gC6V$W(f_VapcT2uEm;tV?&(?(=8pom*tHxjmay`&yZSxmHHw>owGHn#2E>Fs(3 zY$;MFe`iyX*>1T2r)6ik6irM`Z$Y6V4LWD_X59<#frl1kupdHgeV90)g!?`;uCsnU`tV zJIPZUc7f78u|b7fQ=n}VA=h8;-VGT&ucx6=v_vDOPfTH^a&Fr-#@puaNAlhGJiCRr zV(q!U6nx(Z&f(>aZTVJY#y&;wb(Aw6LRqT zLcEAwXt?uwzJ=wb`%U);rzLjg)`AMbyDI@*rzQ&P&6$dt3&|gs9RVK}m{wsfuUbWn z3xd@v=6_il{2+c3I9dw`6JrQo-FQ5(Bpvdk!=hk`hNaNYXm-AtOT}#~*}geChoohU zQN0gG*KJA8yNjcUt(v9mnU?L0$$)rriu7fwRW=moHBUHNE-Ee)>UGCr9VvDAe|#DaboQaxwzZDJc*>o9Eatr?SJH zmyb_aPc$JqjOFD96cj_*Ne%@a7T{kTVEU1E8f0H?U?wIgk~bDt@D)65!W@+3_LS+Y z59yGo21CF7#_f3QYPtm<*Y?)T#3wQ&mS3FJoKXtl)}_S@Nl4PavZ~`{PBydrliR}% zWEYs@QouCWp${QivM}Z)@aLx^Nax^OfqaYvNZnsbL#6>}WOIEr>R(cXCC?kQ5}{4P z4gIg68Q9Kjc|`m_1PG9C{Q_iWEDsEqa{mfu%7GQEEX#WSr9`q2D55)IrY|Ehtp)WK z|5K<=3s|fCesvLeg#JVDFbM$p3*w%dl7GG>ft4!*zaM)zJMI4!M92W`{Zw66@|UwX z{;=P5J$<$5uYedx2{8*$mzw>hW?X@K)~`9w=W)(|o!8!b2Y+`V2kl)6E-IVaXUVv= zr^@|iW%#R8)70(1@{+nS^Q~fs<_3V8ONjs#EZkNP+2%II%{9!#6BIL}`{sDC;Uq;j zpWvRon6%{3rLE-q$2Yg}IPF_n@)Av?v%coP?35jlPf?RPp578$D!OC!q7ur~YU9^O z+)5)VOkb!^b;aQgdC}BxM-}aTY&6s%b2wkxt!unDW8LHp^y`0Vy`-)CQF=D+MNQb> z7-l6WM(J8mpkS`Y`;npL@xfUcpJ!4X>kOWu0*RV={)!rbmO?bU7aKuGXKLLHA{Eyw zTy#t?KUlSZ-Ie0>#e+^?*tu(z_+1PKpDCe~pK7paf5=L6V$&Z@SfCo^-9+~Cr-WQB ztqI3Od21In@-nGgP~sBKc9|Kg7|uxyIQB3$n{aC{!)vAsh^^%jOJs_kYd;ptsVZ=a zINhER|0XvL8K0AvM%qk6o#Oqmm)Y*ZM@!z{j$(MjM5cOBpCd#X`}~V)W_I%&)pLMf zS=s|82dqf0xC5O85<13yGkNqk<1^W~WPhIV@2Y!Uh_#YW7jrA|5doaZ=`Ms|VQ)&2Xzh_!#&@xNV6ky3 zxv@82Ck+-AuLzqsJ>X4>f9iaPqfo{y`oVBm=zdzE#XlV_^iwBUBimOUl7`2TxODv0 z3Crl6`dCiZ7rG-ZTq>Qz#kz2C9|4TcuhVVNd)~mOJey(y>VvGi%qQUW#5G`qZv}}2>*5-z$CSv_{WAyb`Ofm(<1<8|)lzg}bToV%vgRf*kiblFv%>fvf za{4#S!voZ7--^+R@o4Qj;_G2mkvXCTrA#|vZ>5Cvo>qIR$tL@K9Y5Flk+(b{Y=0~yL?_?mBZiFL+wHyw6 z;Qg+2ftbc@|Fc$7hysir-62-$?J=gR$n;~c1wU8a?8)tnsfFgwrV{I);Ju8CkYz_{ zH2tIB>PMENkMir|e&%-lyq5V)d_~8bD?A=sm8_*+G4%%bgDrcrleD9ixN&`Twnh@n zSDa1K#5`{jyTRsZ>@+_jr2LY8cYcZ6nY?gI1DukOT9D*(jg+U+Yq10@OoDzox?l_d zsD-K>RYB##Fu`XrN07>FBb@2WCvoc;%l>0-HimYq4ae!jdX9|@LAt-zB2)3w*mv_i9GPDpspS(MNN$oflJ z%mIH2C|4-Hm_Y3%lE6G7{ zTJrf4{hZEW-gW8cBkFg{6~L&($*ju~{=;+uw9W4^ znvZ~3sxt5(@U3J^00yiffB|dS&eUgHm_$r*q_Gy_4TyZysS@HS-?Wt^gDl)sIOviA zRP+H2&EF^|2D8PU2ESq)4PN6*!W9&}@?VN7w;zKp7lbJ2L89XN*%QxjM)QfIwaB8) zTJXcFj5zj}+2zY=HzNL|l!w`P{_0g)d+Q}1ahK)858QPrjW(>EE)F08aseMcy34r? zB*F1`&X%k6`;lUc)9F#c7ba&Qi=hX$HqLvK>vpa+mO>mAEx~7s+EhSJ&LNL1PZTx= z`CU>1N!`5$ggLN~rKB**v*ng8xzMhDR{{cBDt*{c&E^1^pruhBzVjKi+oikQOvpa;`Wr??>Lce`6KK>|U>@*N#K)X^&fY>+ z^-uv*Yl6Ynq}S;LD%W1|q6dig?S5IyO`|a>k$pPKRaB_^U7#};lPQ-m{09wNv4YM= zhIWkMx1x5+UZ)ufoUGx{IIjbUw8m7v?goZszvkjJ5jfp-d%TK^GwHZlp-KVC4D;nm zhZ{mgqht25!`Ks-1jo2U>k_PbB*nxX@U%|%b$&W3t<-yed!4Po`(F|#n4uE!I1=;s z%Giv|EG78GD?~wMM9(BxgQE5~2M@X(SjlMa4=6)d=>Xt61$h!y0SI*x zMoai%)rUT%j!kOC{2Q~ibqnjPJmG|6vkpNhDou_Q47rWm=9&`>A5Lo)IBA@al~qO{ z;;q2wc@+5u_sttj-u>yhH)$1nAc~l8ijI(QQ*P}6;EeRw^}*gjb!^|sACx5K<)ZQ@ z`?(z0hh|T1f+)!@b1sIdgc| zAS`1;e^w-q#xzn0WPzbVlWX9$L28m}?uZIjPj!<0;_*r%klIkevt@ zG7L8GN-!Zf5xiVcjwtDnh7kVtBB7#^5naHU4am;p@D5kbH3{C!IP7o6_R4H}TB zTKa0RnZ8J3W-`92klF;q;STF(Y>*BNhRR=re&tFx9LNQsY$%#ae7@7^+U3@-x==}$ zhZeRy;%Tfn3i3*|V|L9#=G1y&HllIdOFnMk*(erRDmnxl^|R{QC~r(RWcJrJ z!79NN6pOR(>i)Q;K-y&B1cvDNmVuDK8Ft+i@b#(F2VDJx7VqNso<5MWy_mKTCoNyO z0sA9*eQGdBLD4KnRphWCJC~x78M*-PH>T=W(jV3Lz@)2Lg?7UaDJ?>FCT8MEEHl92Wk%|B7ZC#;Qk+#c-G#bOIrF^N4=WRg@nQi2+PU3ZChh25cr!Qn(1{ zhQ_)wfi6i$NQPM?X+C9q5+lfGB`B&v0j`UNRh5VF*Uyk#xA~$-kI>gKGXZd6k3KUQ z#Su{P?@4FFGwbnE(YLitm$UjMD55M`VJZ{($huudh+AKZ)WH3XZzqA(e}KEW z9=m^f0bT*JfX4;PgWPG%Ux69WOO}?0?EVM*@qeuEi~J>G;7R=PlE{owr?;{?+A#fJ zJ^g?NE^Ua{i~M~BrRW13{w7VZ|4g2>$ncD`ufL6zPrfxLXc*7aa9NtEjzeNgl?!nu zmfCl^V12NT;^CIRm@`w@#aXKk1ZB>^?h2oA%?j@e%fmd|w#^+*G9vR3@mIzUcb8)6 zn9LPYX&;8gWK?X>-#O~2rd%DY3&j@oKh|3rP!m1Hp`-dDu%#lW%`yFh=~7mc5!>9Q zjj`jU5Y3k2#LKv!2N+nHKdx9s=pQ+`qnFCf!`5;&M}T9jmIxe(x!d-o(N#<=tnEZX z%q-{3cH|vOsya80Fa1cY3eNqgdxKL{+>Z#bVIBOC<$vtXX2$+~XT+A*X>Srz49oN@ zCn{Tjw2}}B=k=royiMU<*bubY>Gy_;&U0iCX|u>PQYP(n1ckOSGB{Hn$P1n{%nc zU)z@6nt=iJLT8)C$cz%hM9{WC&46L3`=SI(UJ0MyADEt|ZItDP`fuF3^4IvRtP=ia zLBIu@|9)1VA15ipct7Dw>M5T}*Luwxz-BH>BfA38EAc`QvDx)V92tWzUhFlWoZIOW zZ+o3Kv9l3fC$2QNH_q^tFa9N`@vYK|m#QNG-SdLFhLkpPrug_9w=wh8Sx1?Z?WPF8 zU`tZvS@kqWXAGIE+7_P_9wFwp4Q`*2q;UGIxr6+^qxnp2W&xl12gp}j*I-<`AExUF zALj|X9oM^oL&9Nz*zS*t(pvD>06oXzgtPrK56rI7LjB2CQ-%dq<^3bhPS7Y8L8XUglMOiz}q0Am$ezL%RT2D~!5_nTRr;`{h-_XJggGP}C9JHT-lA z$I!!ySM3hJriK;2#3+SI9{W?J6*p1GjYnR!$dS|xctr^jj)+EL<|TUQ#aiv2P*W_W z^N9|)D1*rErJrXuJ3DLMo+Qv0eb>X$Schb|=FVlEBzhU|#3KW(FxHJM%+!4s(&Gs5 z$xWXtS8yTgV$7F9C?-C5mHM;$d1_~`lLh)Rjiy*Do~Or@XjC*bdcz^~yn+IjY{wf? zur=`W=a^ryVA?rIyG*?U_0i&SM8pdQC4;lY-@<4+?Po>xVj^kj=?<3QU*R8xI2k(9 z91ReBEpI7|AxsPxMPDdu(KwvX@GNA;?<;t@18i#(gvwD604+-6osEw@`bWk4QlmMt7CXmHm60fM^(cY+6ZcXxLP z1SbS{hv4o`aCdhJ8hCMsuQ(^Cr>CcTZqJ?j{i9w=pL%5PwbowsIR7xM)vtDyRqVs) z*H}i*K+2=UcWZj7xXi+5nl!4J_Qiu9KBmH*=iUge2I^&c*q~+m!ECuu1$EMPZyn>_ zbT&xM2(Z@VwWY<;zSl9=vLrj1gL#tVx*$tY6LN z@G@y)yTrd;>K}ACmWhW}9V>9Rq)7O#nM#I_fd zCZjbk7i2crNzTsap_tE-27XxcfjC&<@apFK3Kbtth*NjUHgB_8+2dwY$K!atQP}7o zvQm0C3gzynpTU--9IbG@WNSUD@fFr+HZaX=qX3qWfAx2xb#?I zM*WW{ud1zU?jy3`i}m4ZsDQUndf?P^ZTvSbyQ%*T`!b-3gk~?2rip`UNjkyEwzyW@ zt#eey!y61tdixE<+Fl$^l_a5rE28rQ%-N?R_hGDVMOo=VNXhi?|CsT9lQaO+e&tcu z8pRx>6I3neSxDpxr79B!5v`{U-nYCt?s zIGV0LlIHnW#5gGnJm<(BOLm5f_hK~ev~91VPp8iGN;OhJvHN{}7R{&q47QieE_8{5 zwMEm8CKk0>IMmF}2jVucY>E4X>p!u@{Pp=5&y^3=NF1IaK`uGwhg`C^Wuo01LeC!x zowYJ1OLBXTX9_J3q715J^ZQn==UZ+Z1-#|trOiubD<7_sov^%doGqbW*6&V9>m$-$ z)DF}rAn*5r``;7W=Md!}2ti|gWTqCG(Qgqq&!R|gBDSC^4kLQ7*-1HMDCTx-&b2$0 z=ya=)hs_P~js;Ege{@Pt_Ea=kGviM330lk%Yrs zMd>7ElE%9aY)IE!n*&`#xq(zY%{YW%>d#Vg}a#&J+Wq zw3IT@X}chHw+aL)8h0r9Ha4s}+-fEv|3ig(x1eIu**OwH$7ZoRD<5dyC7>|a@7>y) z*WZA(CqAYlKsg!fGxMDFuB!&^a^>Nx)kJ1g=4FJN30J#aR83W`C#Vx!-Zh@AThD5p zTqhSjMH)8OV&zVB(+HqjsBdXlWO=Ms=s{c^uW0--{};q}WAFMmq1~$KRE$2U(g;e^ z0anUaR0C=IKS8J5+#gmN`PAsJn|v|S``;8D;@=*;N*{|Sl$B|ht z#Kr!%@IU1|x(kfvz+o_!a-m7WOI)gzGb=2A9rf_QLdLVEowY{?fe^M0h!8Y8P2(5#-`Yy;|_23qpxrFE& zMBseohWIiwpCDB!5PqC`#YBpE9>SIBs#jKT=;qOx3a*BkX9!wa8p>)uM2i@{~ z2M*B?8kS+K!DP0RkA*CgY(pU_BR&zQE|3QiRW-YPr`T7edVT&QAi1gnu=XCxSn4!L#RdYk(s zDFZn#!SdL(BD*&dT2fI{2UUd6?1BHseV{*0P)JO{{k24pO;cG%Ke9!Uw<{ugdNuPiRbX^ z2V*)9Fne}D7WrN>-E?$$s_}a3w&>AQ)5|MwYUifin-vY~3WiTB_q}~K0dBtim!Pj% z*aIq=62~?f-P^^Zr`u4nt+RT^qLD<15rh}=#aTuGOdtg$lXxCkRy%g7f!DJp|6GM1 zCV=)IDtxy8P~qzob(e{k$^ThyS{rNmWQ@sSq zMe3uSwV0Z7vi_&891;ejPP1J|KS=>-pNJ15uUY*z8MceAh>A)%wwWpLI^ zoQG6=mEBQYIXZfy7!aF?+^g|qFNw7taDG~v1}!=^s25p%J>P0T1hj;vqY+tUJbzJ~ z!#G{^5|QG#3gx&`1CNj6@z#wN8M_ZzBevf+{_3&5aY;T>^#-q!C1GVcX`&&t`8p|M zV(8;#CPPbk8MG>R=`OrGm+oL6T>SIM-AbN_86YqAn-TzY=ldYcBSLe^Oz}maNZy4= zBvd(6*-i?U1*ujs`RaOV(#%N)F=~rPbq>h0f%0qw*VCCfcbjbR|KM}GBXK9B&<>$m zh08R^0b3K`%yoG{qG#1A>w)__?dJq$pc&$Dqu;FSU-;DG)L-N+05p^%>e2jVuweBv ziZo89(*IDX128Ef6e>q2d)w)%ljeNYZ?HkiFaAaL{>^-;_BTu*^P;L&AaB*0{}Z3c zBzsA2au=Oxf8U2fJ^*OMirZlQ!A%40{t_S27S?GE{RT8*feUjPO)drg1!%|veNeK< zYR=pN&NTXv{`}eRnLE~3-&$BvdEWtV?5;6R4i!+?ub0*EpbjzSyMW(a9O;G0*Ec?c zANi@ryrl0Jbw}E=Tu?O;6IHU2#ALNt-#8s@xe5|2B-_T1l&zZ9>8SfcC+x()g4?VXV z>X6x6t(DX~?%`wwUclW8o>CqamkfSM)e#q3Vdw(ue!YMARz)pqWeWDgU)p+Pntz5H z{1dN<(HF0Y<-%6dbNPLe*1CG6-P{bE=CB%5BDTl5g7?zS1aqfKL8B05-7~w_;o8T1 z!S&B$(2gtdSweSY*l{y_?mRy+y&BQ*o*M|CZ+)IZyFQh!29$L-EZKC`ss*Gj)tB}5 zU0L-7VX^C;H?uCubYH5O%*_m+N&CGJo~-Yql^CE7lsmvqs!=Z}KoV-DIVGH3(s(rv z|Jl%j|KBmR=xt&4m>4zcZ?iC~2ykzk%BSng$5E>_NB_0@d7*x^E8bRo(a~}>Heecb z(q9Q z5al`mAM7gq7?rhv()M|DI$Ekf(OB8a6bP_gahmfg=52|9`pXcbp4mhEE!co~iJZ85 zv}x55)os*r8t>~G#di#efw9!^iX=%F3T@6R<(X#vB=0Ju%06|L`eSA^MbGSdH^W!^ z#5)zf?+jQI7cG!UYpGY*ZG4W|we86@5!^BRCED( zO<=j}nQQVN>~=)*=)yz2PoRbI6P-M}!;z!Z!xJ*PPaTwGLYr?tnb?TXYPQ|X;)%B& zrgfSQ)S#S;RG&}tI*n)R7AuWc7MwrM6i~&Ry7(zlb6Q5q@2_E=;SGoX|BRrPO>$&` z_%Cq6FjqZl8kY+qo9Vj8HEx$7vEDa3BDQu%7xW<-322e#%I#H+N_~@9rmL7f?;?nD z7>j%p1HEAB>rzj67ZZ2O%4}Is*l7$XJ4gF9X8R>-86p<6vw{0;sQ^5a6^(M+&3h(= zOCQ8e#TpON-Zf5k$l*V!8w<7IjYXi;GaEo8!^*;T((~ag*V+h9TCcTZj*tIj#Lv}V zgRlO`AbOb+Z&jZZEQx$RzIK^cLN7a3qA_g|pGVn;?j+ zN3jR?)ZNPCE*{}bs}6Wc{XWqbrC6@6^5Zl$=x-c*gr?8qB{qkxZq8!2yjq6`Xv^O5 zSNg$nJm72~)X0D)%+w`KCk`gL{mrR>kpo(QP(mr{)<5x}P#kBepGgtT1dM5|k>xUF zH;#s$hC5P68<`pu2?$ffHgV3Zg^%579`z_JZ~1(B3v}?E{MZO4M>~~B+rON<&vvX= zdd;`Bqg658g9arW)lgmG55Wl^T=niS1mKaAR3Gl(G*=1+X<_kmh8zt0car?_Qgph4 z7v<?>18q7 z%f=PCs}XNYS9?0`1w0zu-i{chOUQJ{(8!I%jCEPKb&$!4{(|hTzQX&>ok)@LEk8Lu zn7LDicq=$zxei|}5%eL>M~ttM4!;&_>6oh8nlC33IP5mNjo$z&=CMW=K02W}LIjU@ z|JjzpF#M~=vE;F|z=)dFaBQ)>EgH#s8Z7nIh4< zC%1?as^xWBBsQxv@>#ug*XYN+ceEWJ!Y5O=BPJc=gmm6O$YO+Hqa+iAz+BcLr5CJJ z#%_6#nqvvu?{T(9mrWt#lP+*4HC;FjW9wC%o9pjZzKnY<>SDKKO61?7d!`o$A-au8 z{ryfi7s%91ML~6^ZMm;8crgf$1`eY;15#@K;7P?pY=2YTN0zk9$3=%8l*bZXI&nWU z5H`OjV_SFg7oSI0z$)!)59g$3iNxwSmX@?TEWx1C&n}Lhh#~Eoi0K?2clptA?sLmV zn9jtkAE9JHcq=euGhsiB&HDbE!sF*TVi4wWY5JkJQFu?b2$J6P+c4FT>_{WlOd!Al z^DDWzP~r!pIh-xsa#ePvjXJnqthG>Kf0NY+aL+0zAV8>2^v?wP;A)Ql2V6qguro`@ z^=MP35{w>1mhQ1VcN0w4b>91cv@HxaLScd3gOe=F;Iyw%lbwxH4z@n=EmcI)9xX$F z@;p+L+p~|ge{TT_?3vN?LZ`h?cDF2exF@A8RW4a=0{YaSP8useAm;f7-=Xh-U5BU7LJ?!Z+yF}`oc33S}=-;4a4a(%vyJ7%5Ux&z56 zd{tU~;v%Wr+b@XgA(BnqueoP!7yyky8lW-AoyO2x_%uG)7E#ThXN~NVvxlpN-otvZ zR*zyp@%iV}o1varCH6ja#-jVR)>FM@PIl}%rf|8;;%s3*wwqMtEG?ktSj?5TTX8=W zm$!vJ-e0SDB)YyXa;4wy1@Y1dx@UN6ijcvOCz&M+%R~}?aHNwQQL`JKUQG0l*Ng$r z{I;BAjYu^1BW5b?K4!;13tn|2WI3~GG`bv7w-Yq)hm~HE5v%w`X&Yy^7?1o?!!?83 z1#9=N5m{z5#-lLO%^s}f3WNk2r^e;5w5-|T<@P-Nteg9jLB>-@$zhYL8Bk(Qzlehf z?Ml8oz5n!Es;>mu@@19J?|%wkpn%$2XjsYN$MA%iOr#0P({wx@s6p3rpa3G??d1q3 z=?ClnuHs~h1UY&T8;WZ+KB$QN>q*WfTc?^$PKEIyNve)PkT7Tf39t((`*G4eh)}k3 zD_>K~9q>|~5e$U!^vP85a|h_-|DI~WDzB0Q>N^KalLRq;khQYI#qu)uj8S6=ztdic z7~za^{MH8j)fQu#6dEIoze_b%F(J+}_k96oe=5#3&&H&^5` z=aE6qe|W6K1&S?Mt-1qs2rWgDpT`ibyCUXBy0jm!q^#!qoLDG6Td)6wdiGmBy#Jyh z90|Rq?SE)oX4`(KK0qeF0EA5M0l+9bSYNGF*3b4;*suM`8*cJqn zNwW`(^)lqt1Lo(P$gEG~VPi?&GzK#t{~P^1O+$-`R0jliJj#-Bcv`?MbMJZ!uh#n5 zS{NTqVx&n|%yI*Km&P&_v3kFRPzStcBZ?Yd^5LJ{|% zs3$oLSDZ%z^3d96xw+v`$eQq08?EPjsNmlvJzkehJ zKalVR;D%5)55e*O$_ydAW2@{?)AJUNu1(Wtu*09PwDZzL?2@9&>@u$>n^v&(9_n@c zaCv35U`?2@R8NL>vR^fi(YXm0~eiYuWA!B8lWx@#kls9`8%(m?^>$iK2E_)p--^1lE_ z0-u-5&kj=g9_q5*upi`6xa5+0XRYqxNa>3y}L>ou>by+{y(S_TMog zxKR@H{qKzk5~CN2#XGk0Xp+Exy=3Oip1-cfNAfxbVkl0J%N|{S*+TU#HVA$ApMWMb z8$TWX9yDQjmN_1=PyU+rA;8O$h=`8Ig@2eUoqg_HoeyA!0inTM@>=@JJ*5giT9fR! zRzaihpJoIK;3GoPgtF4of$=iM4kT{)C!K%>~G&sJvot@&E- z>{pn;#$TKP0K)+=dbYHZc;IgU72&6T(H9QtWUjRR{=pKMDfFiX%zsNBYV3iKz4QTU z@z-xq<-eW)kXjg@M&wxUfG_;DQ_UOTD61`=MTOtU3(N1o;4j3)>P4iAcQTRQ^&3I~ z0}gltW7zXs4{s#|H2ack)D`;gAKtti!2g!|FGL0J1p)8%s3`yvb|wDmsDCgd0KCxu zg(1PA(iEJ=- PxO7}KNVZRtNa(Sh46{;47w=+aAoyAkE&)CsJ6I&t+vQ{V;mMH zOLCi%llYKE`0>~5rH0lNZVGro3h<_;enreb0G8-DO+aD@kwccL@zEv3@m>zOV z`s#yJr1RH{+;mCR9epPD|REkt)vdR9?UEhI%58~Ae7x)^Fl<-$FHQf08`n@wUg zb9H=baJYEsNg}w`Gs*}eI<=O2%zZG9JDYrTf|Tf6;T=y#M_m1~)-rsb84cj*#AS=L z+SUJFcVRhN^>@09?5CfBH|r66o7achJ$=v%s)dq7hB{n+R^>m|3EyaO&3CtHyy(}5 z%&b(Hpa7KYZ}JP5i9h8RP#^wIeqr=L`&JoLU&2S2%KBdAd-0DovWKq$W$AaQ!cd>` z#U4i0S~0G5W=YSuJU7?QDVAA`F?r!lra69= zjr`b_oV3^u^2YT3EJnWixz>rb_qPJ0R9gKxot?pB7@-BF)g&RMdRqx_PPgS@E%~1J zg5K3^I=8Zwcl@ctC_XPYl^WwS>_-kK;^WP4s#HY%M}L7=|2O^u#Q(`(0DZ`+>-mx^ z(PN0m_4ecC0YFvtv?ffyT8(zG^|<13yZYNLfZiEtm58H}m0pT=<~K?(><&Cl}569Bend zcwH?egW;tHhM=&!nGz zG5U6=gwz7rvRL*5DL?g)%%)0G+V~$bfA=<*$9>B1lv*0|h()04E<#LHzjyI%QqV5V zkAr)$rhWw{&_vUR2D9U#&NjNyo=B&d4Wrq*f?oZzDr9uAU6Pai0mAD%qLhp#_zy$8 zj=$*BA4z7Vn;GV@+8+Ui$YJ?m{lv0PtFtazUUx325&L?bGa-g|r@r4~k4m;MEnNbb zWeViInw?XWbpLP~(2AsFCDwA=iNj{p7e-T`T@miMAGoK8wih*l&O`hh<4eA&gsd*k z{n|A)uOK&|gzc8YsCJ+TP1@72f#H}&pe{OYcR7s)sUltWa$bf`u8~8MgYagW4A5AY zzZ#2d1rHNKNUky^eY#w>Y9N7(R|m2x-@+ucjns4@`>)r7k29Goz?&FJI&y4H6$+ z#}#>#61b)t^;=qc8R44G=SL?yPgcFmQpz^X>RfV}B_#;O%BB7#t-bHmoLpAjD89wS z;7yfu{{N%tAfgqUm6k1HpN7=#tShkX+0JC;`0WRw$#bGI0X??ajE2=*aifd&n`55!nCP+^=eSB;OI5rI%uMr5j8~!YL81XDe)@m-`tk0`noc}~O z3>h768zU*-f!b)eVumm(@b!!Qj6vJme0Otsa@8|o=~SqG&)vysn{<_`mI@F@ye2L@ z2z5~ zI+~wb(e{!hc5(lALJ%ZZBH9dz`fU8XSvt+d;G?z}FttTya$)z)@5K@S6_m{sB zl^QSIT5@@kEAKjXZ>PRZEz(JAryK3;#kkIK9u_B_9qIRHK2xRT;etMQX!~+JV081a z0vJ$kCJ1S1h0kcr5lh&bl}f6K4!x}CIBCDAekp=AvSfH1f55^~%Yfv)Lj{yn$A3XI zYh00KJd+;_-yRvJDUCnx<%r}ZVvyme{99ERfF%N<*t*eHPa3tYUc_6eRYC=px$NGn zvW4I1Hrp{<3 zVl@%|OlR>$0SLNI(1WcLEOp@C`|bc>WnTzd)(nR^w|Bku$}-F6pNIesCfbp5dCWKd z50;zgX_UdRL7Z3}EQ~ysrvu>A*y)Sk(|PZH&2AZ{56;9hqu_Hm(IuF@z%h4&H8)`8 zqa7%#nR8t)ng)t>w;XmgBUie*XKyBRH(~hI&Uxx%SQ%53TqET8gP18q>>4Jzqp|JF z-N&mnhP&o~306v9|3{zBgT51!3*&zOn)f4_rUe7_U?(hYD9(6R8h>FfN{SsR(Jt7n z?$-|dBvGkDa&6+$vg4|0Z@)(=%S|jM`>Tn0OSsX&%jzmNwm}LuatzHYdzmFe6pPRZ z$5HYi^Vg-qy`V%shhNSzrsaWL@wVw}_@n0z%Qod0;pRAtr1REe*7o1%>QA{2T02K9AeDEXygxH4s0lOop!&YXlCrD>;*83 zQ;E{|(wU=mmem%Qis1^j@YtSJ0i6`djoN>BCG07?;C%bRdve{xsYWQ_N6)tIZ$aeP z-phANg(-uLPgk`?32>V(a6R>s_4H8YuPeF%6V~D~Ul*NKf&Xc7i21WO4bDRS0xdWF zrvtdhwQ9ff9e?Jr=<_A+WgjKmpKgGoz=tpN9DL>0*ly%e9ux&0^ypU`Z^7palcmKzXQ7L z7pD-pCfkD)o!R0Wv#N*zAETk=Bmoyf2@%bZo#w1K)jjv+n^RPT2y~wp<0d?HF$WHy zKIyulNUT8*baVL=3OniC69k<=zBG_Gkg70gumQGJX}2pleWg4}!0EzmTmm0tJF3|n zV6AY{Wjs@E1jN#Ri-wUAb#I>+xUfLD(^k~h3)2( z+Ux4-YndvSt9ZkV2lX+|hj@#p6R&co@}BqkGHL2N)J2M)6QNG7&9KBli_|fZ z31|w3hLg~iwMjL;$8HZ1w7f=l6I_^dzdjkbU4-{Uh(wlhq_=c2bH^EdG{OAj9Cl`R zYKi%c&_ZJelW^B-W9tKUd^XAwv1=ULy;^9?Vo@U(hHFCu%XLD3}4GA>$VFSifR%DX8zAJ&pGRfzR0SCrlAc zNsJ1au{~D0w0jiEyLvkb&~O4s{o~S+6kYQ+Y}_Y1Db1Uk9ak&Zo;kUqP{h?N;&^9M z2HXJSfv!s1DG4dUPkyTV)u(oY67Ld~l^E}1>4eNK<9fn;!rH7@hsMuZmm7n8VbU!c zBnt&IMPc8=+nnIkSkKA9rZMgJ3vPXaaF(t@QV1j%SEGF`4c?21n>M{UX^BzQV5g4B zBvTHR>43|-7fo#A%^xx^_;7nc*>dG7Rsb1wUUHN*)aq*^t10}$c;r)}0|eNw=4^){ ziO>jMEH%E=AJW{uK|Snp5Bv;*Ts17=3k$`*bXZuU89(B>IL*x}@p_z)&kjG;SW@Z1 zT#Ywww!)-Sf0s-W%nX99SZ}@C5m8sCNpzO_UcMY@nPeB-Nx*rIAXT^Sx(kU(mtK?I zyStZs8K$BpXSSz4GW%}lynrP+uD_buO$7=gT*mCy?H3p4wodcs4=6}V&FgZt+sNR~ zu)*sKBJW^7`|hGOc-^yI`6L8t@vX^KQ%ioFHIFV@$rET^ta2*G|oLTS0fHQWL1k#pc}R(Qf^cd8bd_ zEsn{T>Gm_KHHNg1RPWyUs}SS55d$dsEBIwC++2f7W>veHH8#W&lZj&K!}!WqgT#=U z()^HPGdyp1;K7LBLVo6tKt}E?Mj4h5Mn(n~N#PWj75hqLxb9#GG2?v&tuc`zYw z+M=3_FPItY3!_a5--rqv69EGXWk{gc5!Kbr98o{z%-ZUe=C422VmwZwH2ruOP-iwJ z3QJUeM)C!D942_(?ACflY3z4JW6J6;(MC|k{h zUEQB5m?)4XYIY(Lpc^qsPx>zWD}sGhcyp+l(RQ7m#cC1waEF@2#r)(}2<_%-P1uwL zTJXA?)ttl+py#48V70V)-7i{wyuZr&_)&^qYcbMvp?D}dw&pddX!xfkw9~%bv5YS= z1wvt%wA0KeJk1|lnfzeVRh)}iBw$?Gz{H@+HR=fyt95z#4@FyV@7!C?1~q}?Ni_to zS=3FZ?dZs|7L2Z$9ia0xSmU*U@=PBKh&pda7#Nt$2S1qr(T(;k3eplBt6RD+8Ysw} z4#me`2Vua7J0Mv)xttErfrmH2l8_o!NW9t%8^=1VWOky~Hz+8a=czleUTrBX;ffrB zM?z8&oU5~1y05!%G~w&XWjqHNK-H#HyU~*evKFtGayvu4bk9!-Oo6`072+LoondKD z8it03-?_ga;suGo?-p}#*Bz@~xc2VmNhZWv#Ppr{2Lzy?qvtvs)T>2@YX3CU9UOPX zXKq6Z_r$FBK8K<6d2)GoLKoLT#)U|nuk{#eAHB;e1uQf{ev)>;2$`o?|Gq8~g&)Xz z7!#+&&bL8kxmXj;9S&w*1vj?2oyhyN@;1Z3*qB_s-a5kh*J5Fu8a~n3l)>6$Uv$M| zviV2VBX!GEM&x9O^X@CC#2Ux?tZ1H}Zy(ddO%2-zzGc4#I`GUZLrOsy7_dGV4l37; zjVO|Lxfp~549G-zZDO;lU>E^?c~$FXe3(4iW#N72t~gAzqGMT$`;o-F`f#y43%r;f ze5qiPeR+t@s3aApM7y}bwI0`cnMUAvJ^Qw&-FB%Xl#sWYD9H1#)3^eCt-AeF@zFm$ z;<3VulIAoWIJxx?OcgE^U>FTrm94$QmhK+^45KabEV11P3}-shm**Eo=s5W~`XhcW z=4*ydZ~%1sCt^4nN6*9zwO4R(aIt%VpFh8^&nH#ZUX6CbX7S1yWOrZS10_%hPS@UM z_#03LCx0s;6d83R8i?UcYNxwacVUEp&+j$J=(J^#L<>>k`ni6v$*6itJI?FP%o`4` za1xcr9YHyeN2gdFMMF2zUg^4Fz)s@IJG(KdNxTjViI33&X1Dkk|=$O@+!z>u$Kj%@nu~-Rm zW%mTYFC*nLhvii@59p77Y~`TpmN~Tq?bTZRltsu$+;!P3b(NA}3fEFMG<72NH+e@u5=KYy~!= zs*MniA3nOdzn{N>^K_gA&wb&BNrc@I!nw+Ha?rUI$ub}!FR#4{wi!5R4J3?3~+m0*Hfn{GCM`~3$m>bAu#C)E)^`Y zFs>wE(l4IO;$i$^^HyCqr)Zr+Ur#%gHK=+v7q}1!ICCM#Cf+&%HVxQeV^<^mwvA9p z@T)YrJ~y6$%&hP-ErH*~#iibBIIN9!q5(n5wu#U3K~6D_hk&@2=5g2ZbD;WcKnu%V=f7@XOd@NS!GZo2eB7}#sY<;Hc+oz zZ@N5CxOMi7%yN)H4B(M)gzQo68#z_Xbj5-oD*PW)89n~11|3Ysl9>%{6syUCXtJ)T zQt#Me!dObUu?p4R3kTlr9Q92JncymWSDJa*7q+LNG!PK`h;uWu~Fw%0)Km zA|TJ|wY(X@j#5}t|LY$}d~cbUs?-k#Eo^unKtE)TQojZ`2?gorOeS2ZUPWD>3J0sv zX!{v`?6?Rwqjz0iqj zOm2rThyK)3Rn|g_TF_aLlnAIL3oGx9V8;+lL;X4!7N3@{+Za7vwG6kHdPqP0+t&?25rza$%6@r9m5|Ok{NTkSfos(Rw7cyS``Hl9z zUb;zVNGZz?hrm-K7B-(NRCV+<(aO^hw)6qXFxIJAQtFYx-7;a2XW39*r(nk;Y(w)p zSiE(&eaPg|a4QR!0z4A~@O^=c%5C>lJ$s%5yY14(#B@X30QFt=?S)E?`(tPcnh~gS z#~G|cdYTi6fy<_H{JCNys*`rK&hsbUcuZhnCtZK?@B8R9pHcOSIc6wSF{)Cs;tq+C zypq|m10$E49eki=RdrpprTrdh&ybar`NZ;d-Q$U~=Q%Sip>$sW!JWS0Ft%{rGt_Bo zUttC0xi~`}@f#|)Kp&EUnIxJr88z;vE+68vm&GFi1%%Maygsp`)qQ&6BPgVPUjZ|Ii z%)hM+oNo>d^scknN8Rls4in6P`Er#0=_DoQm>|7F1&5~42=h58B`T=clf0eb8oSP-@(`EZ_x`&pkJP1T;DqA*Xx!HblHU%gFNap8 zY{X&CdegAk+(C4`>n@882~Z(%MFfx829|0?J}^w~)#^yB&&N{*vbE?pGb%b+27Qr; zC-I+X;~0(IcZ6T_K5iS}KOsfH)|mx#W!x;|35oGW_K|QEri~R>d)ka?K#nbWs4h}K za({gVPk3^E1#m&@6n8{kt642aZ8oEJ7|GQFR^pI1sB+8?1lX^X3ei9Sx+H98n;RObG~* zfjAs&7f3@sjLEd2|GD{J|2<8Tar5}0Cyid?uYHI=89)ky%n@qQ-~AbvmjM~VuEd>u z-JfCjG&UGY3$73?6fD>u!96u_iN+kvD}}1Q~t=wl<|jzY|k;@8bn@3mT+`r%u1Ju zu=iXPOJ4&Jrf6E1MdE|40*hN_WlFt75d|bZDbNns^y0LT+}}D%HR?fpYuni(w$x@Xe>s|(~ywB!N3~qAojRj5wueoF?a&z?JN%a`!)zp-tIig+Mbbn$%x~znn(G` zM)fpQ2IxMzS(|g|1nRJJsg1Fn1FrH$a-tbsQh0O-qFAU8#YWw3xUg4Fp^LUzganWX#Z~Wq`Pw_)(lbR>$ zFC2=m?KP%eZaTRkcJ~s}`FJ^m*@WtzFLY-M=FOX)y@{M5pZ#tH%oaYPp+4z$_jRwI z$9oo8hMTitie;)g{+zkqN3VChwvVIDK9+w9Tdkyy z?fFHh=9&6N!|OnMChDxfCE|Fc^P4u9>3F63-nHEz(=*KTn< zR%Ha53LoC*8e0p?=9s1}GeIy)UcU`~VkTqU0fU4xB3-&5NrkjYfl0?9Qqc)rZ)}3j z^(-g-nvn2iB!!);RmcTUpfWlgD6*JM<_^vSc*a95;#19jp^g>bGMPfS`(q)&|dhgNk~_uWA1@!okJDL=9M6$^k}l1b zaGUib5=YO~2#F6~P{N(_wHfRM1>;sUHnz63i25CO4a;+Exl^BbLod|^9BwO|8MSC~ z_cUkW?c?d2O6+F&0j&kj6pC1j1OPE{fOV#vUV=pjj4;w%R>3qpBJnL}c&?WnSSYiZ zs!6Cass%vSS=s^6v2QEipUxA6;g3xlf^7+K@?i?P_a4jePL-mvVbV{slR48Er^a*V zP|>sYiot$>$K=Np#*~n8Ih=h{@@wTgs((V%rCe(zn+J#d(>27)U0VtFM@kQ zPs}(bY{yO_%x-zS1dBxX_dYbU%!JD{8J{X1%WO6K<2BxBWI$5^AF>RJ|3ceI?L=@T zco2O(UcLOa)6zahl#<TD>1TS~_TVMUxB|FMS0*{gI_y+exe3J?iTFHWD5XaFX z2cB^Z%g{SUo_@aYkX8yj^6}3UlZhLSVT?iwoQ<}W0KAc~nb6gm_Ntj>&Ha#;m3dNG zq66wPjV9{bwmX_~chb3n{%9EcBvk-t6UCKMuUXX5PEX-K@`xI#wrt7N5zp8z(mI}Gmf6ByU^`-0rl8P|uyW-?QY8cxY64edDf z2!0YZm#LnnYRGMJ7ZO+NNfh}vCuE|}eRsjCl5#U6iEpCPr= zk2YW@H_OCLnIbQ$AnO`#IC{qZPzWOU_Q+CBbu2+A6SQyTZx(-WY)Beb2y_%cHJ@|pp zbsY>N=+g|E(r}o5rzD3f0T^vEwMFCwjMK+Vj^I=wbXRBcFzhg5ooZh@U7%}JLiHQC zKD;T|B3diHq#$Whn#K3s2(%lw?hL(c`^0 zJ+~uS9DEpHe5uR%hl4ID$?&8hCgdRnQcA?0*6u(AY1a3#wk4_~l7I`e6~(8{Qo>15 zl!%qv3qpMI&s?7cJn97!=cTsZ+7kv88?+cpN~_sje4XnxoY0?p2mhAnXjGBW)3Fq) zfcl!E)r3(IO?l6MB~w%8Dla1%UFp)_#U8KJwd$kDB=KngY2s=r{zOv?v|NDkcMLf} zv-qFKOw}xAEv4Bug|rm)-IGOB`;JPdp_I_^A_j{~ChsGDwJ3t$ZrKB|EZqrsp>H{I zMS6$)3h+i7tJX&(+Wj+?i6zEW=VODS-&cOGRE-ubtghPIQ-_M3QtR21BO$DwGS*f1 z`LSm2J*d8&;8WRXl4}se(m|JW) z-*K2wH<){jrzKtg2I15#C&9-b!+HeN=Gh_M4865 zUAFn7|D1M`V@qnHIzFq zAN5hVA z;B)a4(}d^sW<%)|@X|{bSr-wvO4Gx%^Edvr&C~W92Z1bz9E~lE!sp@Ji?je9+$h5S zk?b@7C8}=cy+W@MH}=_AR8~4^G^)CF7WgO^(eY^28Ado@9ty+Ba1+f}w+iGVk2W~n zI=S(1{!;b6O0~$>$z8PEZhtvSb+SD|!M|W=F{pw9OOCFiODic+^Y|OZJIzBhl=@i) zKM^vvCs?9({Bqi?8&1F!cdkW9i00S0ET@kN-d-qTO>W+ z?58Vgx6Ri;T)&)&mJ27C+4K+mp(P1h#H&|$E8@Zeihps5G39Z!ViG<7dn!?qn%z(& zY2P9G^2dkeZU|FVPqZE+NYWaiAtnQ73@^Gd9w75f-@S;NR)pb@_Jul`p{Jjm)bFe@ z5cJw{HXI5ULO32zGSRJq>f@rQuszMiVC5B?E755g43!X?Gp{43%;3wLC=pIiE40Gu z791F}SeqbzUL+e1as9ps6;(v`1-U{J7`SvK;%_0jGdh4Eqw=|#=IHJ=GFeMauu3^h z@fY2j#hLtHNXOCT-vT3DgiOwdqn@T>#wIi3!i+Pgv!PfYO%L)SjcdlQD$UW80j0tAzaLHnC`aelD@?eL^H&H-E|dkHIK)02Bhi3CuqO$#;Zqyx<@FpJ2xfa8b<_2>G_( zpaRTGl+{TS_{YwleT!c}g_lI<4~PNzI|_L1`?t03yA*RDnR9=Wipbz~FC^?i$?PHAoTygy2pfxO-#4-9m78cXtcY z2?P)B?$Bs(zGClv?mhRtcklP!&!U^^RjXFb8gq;>=dzRW(+q0$zU792g|(fDm_;TR zu!CuHJ&kZ2doT4`hq6I2o&VhpD3MSo$PXYrlxeBWfzd97K*`?5eaKo2h+o5h4WXpJME==3u00Hm7SqLLsR*3L|80b9+cT?L(NFjW}EqstYYbS zKAVL|S@xIp4Ihy}crWaGws^F-&)r<*J(829_{A?7IxG8*GkP4utZ1MNCeL!J=*Q5| z$2@Qng|ZFypCbJXgLGikTDNPE(8Gx)`?aoJ9WTz>yl$ADyIhb^l88*<5DJb9r zOt3)f!*ZAR734T|*7If>g_u6k?wQ6Y_l3ecWmzZN0^cY}-;&_GL7i^r=CCE6*$ z{i4B^99>90wG<+%%{2UOX%WjNsGJ8YsRjU|>_ZYDNDzuS;muSiYiKM#1SQu1+B6&-T**&n(a3m{yBqh-LG;gNW_duH zWQ*CVOr2Dqul9wKO*FUwAK@%|wT95KGdd|$hF=42|G1s?ut$>rH}urV&O%+)Xd-v3+sb^X`t^@|z- zAmF!$ZLVg^Qb*rTTN3$w9UrxrDiF`%$f3G}*?T0VZqcSy<-2SX-P+p!9i=+;x*XNc z{E@zQ&1Q>{4!9>n(p4{B0Nj^(lj(z8)G;Q&#iA{>R zj30sQag)u^-!`DAOoC zk937GkQYaSS+M+D8kXq%o8DoK$ zlZV4394n%mRq^pvJ`AJ4ZPAhKwvk zjEuRfUo}0c3JVQ{to@_a^(R#fjQ!9-YZ`rXqWE8i9knK;^M@H*)VUWqJ@9fQ-sab@ z-&R_F%|8lL``JgR6&yaRzi%a&k8>T1OHbJK)_4UXJe#G?hg7A_5Ql7arekZ*2$bP7 zn*$_2!!z2;vm^qOMFS%Cr8_*)N30N$U3d?XluneBHWf05&!PLZVTsK1TE@^LKpxkS z;4gI!>$L~2;Zl|Aa*i~RSC1oqga?8o>wijfljo-R%V!Jem=X^)7a|N_T?K-c!VzH0 zVGfm)+gTpGB-rucb5Bj;koc>-ozAAMMI*9XB0!EffRjU{;w_X@b1k+xq13 zyc>QCQ*Kuala!7It$I0n{Auos{d%M)<#{uQDn-Y(vN|BUM0<7I0 zP{DB|Pi1B4*w3D&+_S+KOo*xwYltXJg|=3m#R}#b_)Gyxu)O7 zB_fWVW5^rNQ{qx8um=w=4~DZ}vh#azn7#2^ejMlbVF@sorY3wDDk^{#mV{Z?#Xr^J z3nWztvfbo#9OV((4H|x-^;$>-52l*afJQ&W+XJh#L<6uZc9@fMAT1XwXIn8H0>$If z;2839vt~GR>yq|>C^2B>d?^Q&gV867K2ftzwkogY@}gdHxmeNbCW%BgbpW=6p?sRL zmnF~iBF9}E1A(kpS>mz4jgg}rF~eE?^3Nane7WfHB1KYO`<0FZem~bL;d6C#96)b+ z;gf+|m&njV+C+elFI7BM$`eWTe6qWiWAk*DBzbi>t7$GF(S85(W7icGus$h%YkyS# z8+tlq0l5F-XiMSmL&*R3u_W7h_-eN5(rw-LKi>iTZU46-7#2(n*4jkU_wUkrUEbOQ zTk|A7>mLGv4Pt>-I|vpF4NM2q<%q}v4na-!1^EAA?4s>)1SPZUOZSDK+s-^*A1@O9 zgG|rHlw>6X+dzA{p$U-bD*eTs=JUyB02beB_$pWj`^mqU*)%nTyslXRW07tBXb0T< z{{l|CpT*$Wbem)VLl;n%bPQw1L+i1B1%$DVuE;`v>7EOunzh=mK&xMrOkr*NG^_cn zc6XprM%pXZtn?BYCyfogOLWXWKj_Da7Dp3oF$FzwABKS4sb!96LYR}ce(h=8TK28jmwlLVD)yF!PDOeCan4N%G09Lo7Tds=ZA%`QED12`^ zn%;i%PA3qXR*o@uGnPZICFdLo14Cm>=JJT{BRaby5>r$T1_ng;lO^bO0gvXO1FX(?#OpN~_C)Yax?6u3bmsc$ zy#Bg+BVq4F*-64667(rm4l>0lh=Rb(7krwMQp|ZgK$y!hV`6@w(LbmJt8BJj8T{g5 z8zoDgtv6S0WE-#ceLQ4tzI0(|reZa-v_ym(>Ce3+9B;S`*K17ymT9DjWCVarb65f2 z9f#YUeOz2zE;os=4G{rbMl8KzTFUj*CUG{|l>5_zM~!a$<|XK2wk&e0-ESZ>lzO^@ zDL4Gbk{EgPuk4?V3NHy5UN;^)T#%&4%Z2a70Zk2j>go=57&?N0%!h`G3Q9CE-j{3& z+)XNAN5#W~3+Pav5M5sZ+WOHA`ELq;NR>qXHxN1Gj!K0#Q}+!=T-c=XxO@nN!F1IV0IGD+Xa2)CnVEmn*B z{twXar@OQ^ZSD;AI1PL$C?30<_6IlJ-Dwf6zlKj9yr-URH1GpMu#1|&L{pd<u$k>POLYMXUo(wJpNgB)P239NY&>H;j7wqk_wwSsKvFQu`!7^;+(~g7@gpm~C64+qg zJ;(JPuM}R}(o{&QHfV{+P1`D(J4?Gi)-HSiu8DU)OeZBGI^K(9^$rsL^yw${i$%bJ z1?H6!9p1+e=OY5EYGnqG_s`kioM$hlW2;%59aiv?HNTq*eOY3^g$yXsHH4D`a{Lq!YjkyN-=Zw)5Kip4-oD}vw}0LxH__HxY57)t{Mma-^f9uO zu6cNCFCDZ0`^EaRxqKP`hZCV5$7)fSZl3N>u_-9*n$tGH%Kd;rR$bV@MmW*&s6lJ26TzIPY0SKmZeS%QWVgO;GTgtSH54xzxbZbhJY6q!CKN-&ENC5n zTdc7TQW3vHA!pP7IX~T*SNzrvUie0r;d}(p1XhpSEgP{Mtbwd&Wx8B5F6r8yPfh>? zF|k^H?}hH71G&^rx%d%3SBjG2r>yjZO#Tan2iZVyVBNM{hAd0_OQ+d4P}c|MEVKCy z!B$2vGhrcH@9>~!noPY0Iy}Os>F!C+y2_HwL6!exAb{)~AOL7^P43%~-qi;omN-4cPf* zPgW%787;+&WlRAFLY1`yYT&|3+BREiC$rFw1K#7E7(q7jSl z{>M-~oI*D@u4u&eqRXBbS`9y{E12oQsKQaNszPB(^d|F{3|Ss={)~1)(r!Co=;>Pg zGwDRV*7V{XcH9WkfwT%U1Ey@1#?}fG5r(}u*EMJF^5ZZgb*_aVXmB%|{5xS5W4xpa z(pbY~m^L)hD2!+eR>kbdzU<=l-MpPJB4H>tOK5y?c5hL{J{&g^yF8q@ByMsx#n<-p zbKE9qNhcF(Gw&cS3|tJXgMvkZWRzsOp>~7b=)^;Y(ZFTNNsqojDRk&R_@eh=N|RgP zh_du>y0E}aiXpAnWctdRUe@z$Z^01ttu8W42g5W)J+6+U;FeUCl2DNwPumD}qt@27 zZDR!+xTtkEqE1o#aFyN`pY$2JdO?yL^~D?~{X&ADK%;87v0)LdG{Ain=f{A$;+WRJ zJtJs2;M5FvF%ENpUw#~TIgbeW_?tIDUn^<~1N=KnV&hm$6l6gUx(&6oto>Qnphfo_ z7rCa6lkf@`c)#o*f$G+PLYzPbL+U@Tv_Yw#*He|%e~Q;os7%c;f6Y%m{T{)US(!7* z%(d7=<2p9WxFvuNi!B7=9gHFNJNztE#wYw1@?Ifw|7YfH*v@Ff(9nj4US`y5xUmh& z;3a?qT*H79)rMqj6wgu%Bm+>m*yICzI|-Q7B!E_09SEp0jgi>bqWdj&89Ic7lZ$yt^wuqUR>pOfYCLdf&OuEgF_YyHI{th#)q zOS0qI)biY|2Ld|*zs#FH>5O9M?jK-mF;7Ne#8gBfHF@|B5oK)A(-T9>Of1No7mUp# z#DU^-wjsMPkU{S$jClSh!+m5pvxo+tiIe&of2B{cK#8!&AcSZnCI zkr5G$VRudc*vbsF(tJDG-UT9{|DGQkJN;6ZU@sO1ELTL=BsKNF+1v~UK=Tk4x&8R} zq3Hki@rM^f|DRnv_b!`%eF>-;`48{c-!&uOfRnQ9E6f8A0dULzi|vdSP7p5l@A{73 z<#u=5kXH^R(BLV@5~+B4#Shg6VsBdfX&ZcKEB}MMB!iCWYyTHno4I*87@h8Cx7=>L z#G^Vs-c7L3V3{9O4LIrfyAzYUWC6~y`A$~{D6uE+{Ie{ryqjft;lG zRJX~7DJjd`#iw!RBV4u4*}ENJt^{8LgbQFr%va79cdIA*|EcSU56(NzyF7S-vCEy4 zg4AoNaKGTIf$bmNNGG~{7;$iLKQt?mvwFD-efu_J)E|azbx8Si^Kg4HzVBk?9weL~ zH~9a6gFyfejvF2w9gHRwNbrhxS14hgXm>J}h{@`P$D1AK3k=QCryVmp9eIJlJ1dDz z$k3Q{|3=YPhJ|~eOc{7%-x-U!71_z!9P#3}gEf``r&FRU*wJHsef{0uLX)j7JZbmN zr`0x(H*+bU$_$S}cz^9J_q%Wqp1j=J&b!xEv~WRCFJzx_@iPH2F~U0W-!Qm(12WeJ z$ZW*fKmzr#N|9n16$3-=!w0O4=&33FpFP>x;ouYNq-FeWA#}%20CZJb+6ADi&z-c@ zOPNyK|3J(t0GGQ<+0M(u!!yz5YTaNxt5o@Gqs02+ckv;o-O8ZT{X4j7JyyF5z<6%k zCe8eEKDqynk{ylxUnyCg*6T43!0eCp&6l^p+im_nWn~=+AzC+=0`Td#bwmn2J!<0- zz`BwkP`zs4S>P?j+(Tsy>w@xpmP4{DLPtA@OOA)lq_7&aY`rpd{8O#G8dhjIA`dr~ z7Pj<4#yI`Yw5)9PztOTQLoAX*Um0H+k_I$B-{2yI@JjcFH)HWJy-nOqS=;}5HUrbo zaICtT_8cCi9}Ex6VYG!e+Kk9w+#Sd{(-B|-61GB#^0a;mpLX@KdGn0b$(PySd05{3 zObG?`{4D!D81G+AzmGc6^%7j$o}Zzmeyj1yoYl&B|9JmFMe5e$M=_g9)KN)mDoGc{ zu;qltB)9gWE0gYso~eG426JO}sqgS~{&ZRva%GX$5i;x{#hpfLY65ih4o{mvaP&m7qHGFw6A?N1-p`oFrQOB@i zqh`MTGt{|A5bgw4;VXU`vr1Klvvh7O!lhm}+=D6##Q0)b$K5|>rjKi(hnK!di$*rT zmZHX+T=bIzZ)${o)Ukd%UaC-P^g8kCeeJi~MQOOAhi6fS!V3rLzMt}Z5V|$p+TPZL z&bp4-S=+RppP%2Gt)}eg>^y`Pt!y0fdF@v$Qjh;>N|TuMtnd33DVNuKdyrHtWxbn` z(gQOO1bvVm#()zxR-iNMo%%A-f{^Yemw6&|@VWv&wX251w6qffbk+myU(-=6`P#49 z^)&QA%uF%sGd?JZ<95F|JJ0v|NeLAe^o@#k3gx&+rz9tp1sDU0NeaqXH9ow(&_u6ie|ayYW2?Ix zn2xlBxWha@#x-8xtfF5&RQ2iV!+yvBdfJlx3QvLMhXfGX4HS96PCM&9Wq79hHOGLr ztPoamXDPt}?&$s;%9YPVW3k9JHgcmQcvx$x;nbnP*~WSCERY}v_ghM^6cG^qR^C~z zv%yNq>of}#jnXdDV$tZ^eZxug!=82rPGVIY_p%88+R_^;>JCp@r@{yrm=0#AAK{Et zD7^6SO9&t&IjceXAkAp)+{-}KgfE=Kg6x{)pu2i6ERy;qNNE5ejmea#7XJiZmx-zu z09m$K#E2sx+I>Y0GRrKtyZDh5i0jkzdnw=ZqeF^#l{S!?I9BO zSkE_2sY{SQvp_Wri&fo8J-_o4wNcFQS4V7&5=C9xA2rgRbKygHLr>F0p&#gv^UZR+ zF3AwufDPuSt%@X`LkCP+@a&R*a{M*#PC=dSwh>*HsZe8;65Smgz`en@Q0ke=Tn?{E`AoO_oP5&R;X{UK`24uOf4?_F|2&WyF19DH8jciD1I&2Xr(G-julu#-_H=?r5K7&LkK;ll?R)gX^tRffZLdTpjy zTJcO9p?6BpDc`2()^nuZX_f*eADYmNFkm+%)ek+>{+bE#0bxS>?+zezx|S=zW;-Bw zAzf@Cuwdid8r_d2QPe~?6V)5(kqcrt(8xvmPt`~m_DVklQG*Gi-z6$;9<#LaF>C&a z6fK90BM4$-iirH7MX;M{qAL&I^RezN;MzdR8)`dB1*bd+ZR4GDzhU1XRg2%Ilrc(N zeU$XmhHz(!De5&0s^&E${mgYK zTUk)TV3a=i`Gc)z&Vt7KLNS|%alNnS&G&$o_wMe`tZB*uw1=DF*f3C#3<878USQd47Gs6EF1MYX8mOr|C(38Axf@CEH)0GOlsL z!+|j3b%b&LK8r&U42-CG8HZ0K@V_rp{2m%QtFIs_=C26WnmkT|kM0gM*5+@yDWK586EXO9 z_N@Hrcx`r~`K?&DXcXf((aVgymbHA1XR(0-n4L}3m7rmS-Jyw{e~Hv>KyjoA%m*sH z+pmVtTy0ZFJ6)XR@{*Kyu~@AN?@koWV*DThT>90N!n;VAk&phm&35athFkdxk^=Cp z5l(fGJw=`IY(%NpKkj=ZuWJf!_)+Ya<%G0@O&g4%_2m@WRFt+wkrPd~|0=XV&7%v9 zKl{n@N9_Y`)@S|$F_yL0v%;QIBp`0``Vy=$>bz_{V?xnZOzhOtDhd%wD~%t>+N)@#bT2`(Zvn# z`)q>ng)+h{iI9K^=<1l z??mjFzsZFnpeNCFYgou|a`*fwsnCiDUyrr@?g}45e^*PIFdN6hF!j~0H}C|gvsl+q zBA^uL)5sRq#FROn>TKF}uQ4v+00avCWN^^QK+bfI1a5k}n>zxkl96rju(#52OzaO4 z^W2SC=O1(#h9Ye?6>@;n^%cTFUPSv$LXsT97D=PN#U$Y1bdU31*ADLE8=M&XZ2f^r z;cGcOvtr_0K`!J}YxDG04%Z(b6O4_?t`B24bvHf%GdV-MLlRLXHRe$og%aPIj=mpZ zCu$U&cq8n*4-3q7gIgJU3#LL{(cq_-k5L0+#+$}Mj%F1q78X?bnDLa4uuUrYa@3-t z9ngH%Ro{E=M|KA+rgtdd3zOg&5J+&VGjg_Ny~K{^CpV+rZ5nH1<16`_4pQi|JelP~ zZO%MClK)kEadKFi!H}Hqd4yw1xJyog>230+To{Ujk~Hso&B~9QR_p6EO`lk5R^e0< zxH4#EcbM8a+)-DDepH#k(lAh#W7&mRTxs{~#USX&B0&Ja4Ci$L& zI;*u~RG45*NWo)&wh*6@jcow%0rk!p_yFV2`f_Ip^75K3)~Pf_?`en6o;k+MoeQ~;Ex8~i-H}RlSc9ip0WAJSBXlMG3uFz&lft3Y zXS~cgzfU}~cru zYF=q&HNhxUvQAH{>R&7@u+59S#BgVqWP@c%|D`3phsRUj>e+Ph>p5Tt*J9<)gWrXm zu=c&?!4|uVQmt%>({lLp!TY_hXj^I(zWEPq86U=g*YMyhHGxLS!mp!-9TPu>(2+af zn?g^zZclDG3s>db2L}s$i-T+SMGG0oNw*ZP>w; zUY#hycK-BJ*mOd#^%i~f2fL5Yt(HHuNJ=Z%;@chfU~IxKdXEGH@wFS>g;B%%vMyyy za0)DU4)nfW6L_!qLYMy`9mHlk1jp&RO?(bixAagR&CCa0;X-W+)pmI=bsAspZSjdM z4->_HCJO?Jwj8<|*QqkFu|T`O8~J0{M})arR}G~nd1Y=HL9<|irnh0b2cgU9XndxP z6S8jV+)G43mlCQA0SJ=#otCW1j$A|M?H-T9D@6O&@@w-bC`{jzi2J_&nxK_Jb#Pg& z-zyos9-NxXqAPgday$@hV1Ghr|3ms+v4p^u2l7*sWqjD8V&BP~8Z;RhqHEUu^qRp~ zuY2ZZXU)$0)66BBQ*%|#h8HdEn%x^8G{fh{A z0w>Ay5;1$jslj&djb92jVASVuK7ZxvIl;mM_D!62^q69#T{bza4m!ogZ|%gn+ibGi z(jQoe`?G)vdUC{bsVnguN4`Q&fwkv~IZaoNOADU6`OK(c-HN8hY_Vev+HK}4VpLo% zG)W-gT1+6pmMVqcAN(Eg9hbLCaB7K$EMm5)Qa*}lRyovUG1;VvfEwk{68+$83;Y7) z$kuRGD1rKo=OO$G@@;d8 zwKxT5)K*@3EmzAlXpSJi=1hNciq5wjT)fEhrz3KW2Ro&RQY5TQ*F5eb+Mwamyid9v zY@`>JH>#Mb3w=C;4WaOhF{&83vNYK>hec}opuEM+$Dst8C8E5E1l^BA{ zl*~TxRl%G;1QF&FzjpMr(c9w#j$_%+pK0dWiQ_KCWy8|8&nEchGyY?dm-JNWw?iKP ztZI5Vdm#XG3lw|A=mq;qx~ItwK+*G035I8Y*E*uXHl<7~G3@6{DQIkNiri2hChkQ; z>-i>ZLi()|`{I2c;48+V+of8wtqFaEQNAmA{XZw;}Q6Z&K<7_EGLxYRw z62SP**{~7lX*bw*$zI&tPouLv8EiCsc1+YOm!_Ry7Cl3aA4p6TNMMuOB@a=b&!_-q z^(Uodn>!^uE3DQLd5LiqE3Eye9n%~4!&1LNBULn7My}sP8vTrongrzJ7samomp`P@eZNm)>iYz=Sam8U~#>8eB;qbV%yXAP70?XpD$@j{fqxnL3_T)a8 z`AoWf-t7ssIB|}rMC=p4KMV2lrSfYI6?Ssaa!+ug?tZ9SSt&Q`%mkCF;O30zC0#x_ z{-Stg0@}F~KGgEtW!)|`Y*v#*HCj*37IC-BA1nD7UxL=L%gv4jfk}J|o(gw_D+(Zm z9_oj&@&m8#CG}qBd!e!0s+xGXM6VBiHDQSf)D--#svXi`{!$6jjB4&&d$Mj2ZMW{Y zxci5_H%JDk1Yv_=@-hHx>2x&ROzvtasw6E&??dlwx`)(BPXEjfH6BR%{GMcqeC1A> zY_*YO?3ML#-QtB{>-!NuQ-1y*$LN`@Fh9o>rT@&VFp9e4F-30FJc^hoYwVo;&XT&0 z(F6h^XrxeHKvPmdrWqW?%=fn3?@#xxBjw0O9&P9tN28!KGH$|W6^!Vy%c?44=w@@*Nbv8A{;R(eT4 z#wFoahTexx#9LXZVq_EpE8Sy3VeBO>HClTVKg2mX_Q(z(aj)=?U=tkqzL|*a0>@$x z&^;k&JS)yJMQOIdEVx@lUxuU$RNX?k@raZ3k_6hKBPG0J@$)@-kw804P;b3{uxXhN z;ZDOpVzuzI$}M^JeI8v+lWQ*|#4$;!d?Pb+m(xQQTYhO8dG||aw zm6ExW-A_9996?{y^wCQW$H2#upH-8NyPPdl=>ssWa1(_JDm@b@jHstQ?t3fk)i8f| zm{a?!!(4nUP!&>O>{lBsC&Jgts~e0az&=d1d9DK^oV*?_1jbTNEWy$Zlko9E@O_e9 zMSzZ7tT-$hmWbt0)|X6I%5)GpMeqjP?!KBl0tJ;Jm$yG2cMz9kyc(D~!zZtykq)M& zdCknrnO9jl5+YC8KiEpx4>iKUoM1}N#w>&x+BR-?(c%Ny{YTq<1w4muFlZf`5}lH& zk?`XY$dw6;acm+=Tx(3RLNM`cf(AnVy#rD#R^Bl&sh>oLBbZ-^IVFm^U1TWRuuOD3GWi>Uh zW<Dkg=uOlzM6arkZ&b^$M@XLKAoGbaU4E3uW^3@S(2+^f zPs?&y4LnFX4@&2CC@!MTXEyyTeQpf>!VBEM`W$p@cwA`etmH7U0QumMp?sDip2aJ8 zkbX1Z{V9=%!K*aVnRmRPy7*fBZu9C9bkI;{Jv3iyVyS~ylMAe^5J4wkCh*~j987uN zfNOvTbJxB+N)_gNjX55}M1FPQFrxq;w0p!s_4qG-Lk0k^uRkX#{fpnI1Wq$=D0xTt z4<8Z+@FAf;STkR^lovik7x;dCx8EhlKl}+6yeK2}bl2HW3=i~unZHRENxYhu(=>@Y zY5v2y$O0@(>yOZc*}u4)|N41G0TjdVYL^cw&@@it?M0JW=z70f)<_{>y0>y8q@<)w zLy2Zkh*!ib0U(cNX)swhz{25v^fM1?b=k*xczCc8#~;HL_PKkH=4nAy^z4MOF#eDu z=6U&HZByIeGcG(Y5Vg~A>VPZqrw3|fokgE_0pqP7P%e-@HZWBvc4vWSpwo!J)ddAI(Dr-dx%`xA z`q}nf?dY(SC`Gc?!;VLWq2tE}hBETXy<-y374*X=fOk*JlV9B>HXTOv&&}w0Ql4b} zM@iU~=G8Be>wTfKcSo^b6)uvyy+2AFSNr>h^bP zmuIl+0{6TwTf^Wzo<$c50O$buv9arokr5USAwwP=n|#Ch^lXjYvd)VxZ{9AbwWd!?{(b%f{8s+n;H697w>7*B4UUo(Za&D(oWY_Ra z5U@1(a$~7uX@C`l0MEOYDdda*(4!UVNqc)>$ggT&be~d+_GVi^rQ~6DkF9J=7qDkO zjJY_MmX^lb1G*5pCMOwSV-$8q!IvUhe`)Hiox3uF@oX+@4O?=o0G2QKfUWao&5+}j za6pWAp9$;g>ePle8Q%At7bL4uQ0Tg&iN)M>fX?!qY|pg}BqgC99v`Qzj$A<*RM9^l+n_7Fv%oUw~ohxxy~+j2I~bjgC32 z&haXizm`?BCFA%8Hm|%3t*)*{(O73x8r|P~G4ie5oNex{bc%TXIjJ-=D}4qTU^flQ z8zuTzYqjh{?ZCU2c}M4|-t_&}1{tbwU>#z5`*E2yv!D*e<-deH9mjoT;L);D&*|zx zMJ5i(5^Mi7x5ssJ-}K_~t8jv}&?01AgU2`bhd`o0hm$F%ODi9$3m93U6kIMuA(xTU z(ksE62cnDigBC^+bnFY&X~%~mw0?N^5{;rF)V2Ur!P_hCC3g6Z#hX0y55AXsl3!GO zu<51=rB0^_pfh>XRbm4=ME5Q~V3%ktexCDc%oBF?MJPXR>5+xbLiLvMfLH06ewpv@ z-{m&D4YeZJe6>Tre_s@I+A?I8^_K#t-)7}%s;L#^yqGSxXDX5tizNd4$M@GJ+Iwyk zZ>ZR{u0B2Gi(K)42XwsT0}N5}x)pZ8&`RIq9FNIX&4j|s@NasgRg~S)Twx!&8dvZ>$M)6U~7xa&_ZGN1IKINM`YgR7C8)5qb&r36YZokn^wC zH=qLM+D03)Zc*G`PBMIaamDh0HjD-i`E#T;6SJ zL8?AMot0iuZr*Z1@5F9jgJDFQfubvzFc?K;{}8C^F8hfOYnh&282+J;u}#vCS2q^( z95pVK_oCL$EClPePL^f#mS#ydX{iHgib}>+#Angp=XMfZLvq>O^NjE z+Uq+h*R}nhd1!QzA8mV4<7zD_%0fDMv+eE281UETRrM`(ff*qw@I&aZ@47`;U%#$Z z1D%XO!y^3l+78NS5K4(3BA}SJV{uzc-1{=UdUh@)`t&A`np)I>np+~pJVja6(C^5X z;`;!OZxl$740>?NRipG@z9l;g7U59`6OC*_G*`kI zLf6mKmc7DLM+}=9N8i&dUKf}tElj~FxG6XdByM$i|6c3jMb+b4LX)$3U~G^1%DDe3W|rrM{dEwqU=KxvCKo9y;-IHZ%>ICIE7fIs)k0Ck^} zIL1+y$VH_C76xOcyw&E%d-$3R!%RIU_yDj1@Km9sGgKD6*2FgIkH<5Vj>TqqCN}=V z<5^h$PS^v1dgNAVR1^z3I45DZvQO%P6$xPMY$bv$LsoGhqkbzm-X*#G2d1OVnvPBu zTBSz{cu?2)LSD%VF@>eXSEZp8FLkL!E_DTDREA}kWa!vHa6a2*sSh~WM43B;^232n zAc@=LKyWYmH)-|mA8ED3J)uaSBBTg5{q>YTv9ZL@Fw|J-qkQbW4gCn!RFSx@F`_-` zOmGo}q%`R2C-~@GkA0>DYHUEfq$7rL4F$!b$2!6i`Fb+Bvc>ZAz2NZ=$M#M7Ga0@f}brvNnx#bpD}j_{YLC_Vv>R(U*>81hIvs zLHGqsN-m1-lylBI*Kcs`?GyTb?g9sI^#MtG31 zs;dil-(Z1VjO}`0YNF5ZCPR2$WX;#E`>KDT06#(-HYO&2rD9dD5US_pk-_k}2e1N6 zqt*1gV=*zY)1tSfi%~B)D?gSlmicewKJEa(V)R)htBAjmJufYAJhEr-ct`M0!jSTkFuY|We?eS6ctF+7 zVzd3`WT65x!`RFoYB32w_~!%Aes8Xp*4x{gY9HZBWl?Mh1+ug$GOQZ`Gol1N+Sd*` zqXDdhCKvOOk&#^gAbT@WKEkd_-3?%C5!E&8iM-&EHm9jh;Hp|@|0Fd7&^#E%X5{P_ zv-wz-Ea3FC73Wcwy57rI0a;Fy6g+$qIzRt1xcZb70?=W3fEi_IvRvofJVFFRCuWiR^xs+NFJ#aAHE$LS-6; zuW1&LENU-p%JwLL4B_M~bDIrV#)Uv&1SEsa+)#?Lt9eT5HlrX0|`_P^78 z=luu`y`h1OLfye+mQfev;o;HZyo)i{`LmpE3I7tsx%Rndmhr5q(3xprh0_0r)Ke46 zPccMhU_?1{lZimS_*)UMC;(ZlgTpb4x4gVWi20XC>pg|5xlUW4gLF1DVm)M1TEKoq z&1-a+l>2j-4#6H!H_*+ZPz~uv2pZKhJRH6O+e+=^VK*kl!^Efnqb15LBm`DtNht7Q zH8^^Bme$ZnI{5Sugshcyi6iW?XQZPH7&wHAPnTMqjhg9q_s=$}(MP7HGM9j|zVc}M zElgkTjVk?m?_TRLtq1YRUCg=;>RlzkSF!tQy-@e%)Y|_Igy#?ph<_F=j(xUUYVqF$ z$L71At^f{->a^5C>Z*|`T^y{;4oW1QsQmk#e3OxC8uzrXfKiD4l50x^$gg{H01Qfq z!;L29<hr5xPQ9y9Xgo3()ZDDI7{X^VRH%m8`HUY9`iiG~ zZX`^=`Q5(Dip-CuK>5zxSz#{w2cQh-p_1nHtkhq#f1P( z^H{%$dyCGmZDoDeb4IKTm`wIhxP&HC5v_Yu6R4i=d_kv}s9!tUCnI1aiD9&-fVH8azZ!I8BbZ6Yr$9a|1YWazZ8uwaDm?Jy^XQh^6DA~hGU2M7%r*QP~~J0WmcuMXexKsG*JuXQtA3&d>hJ9<8Q$}kiVw_|?S zO}*z_kUR09E))zRQ6+mJ(P>zMU0WBiMJ-#c>iO3)bNtd$$v(VZ{5>n)UzQ?%p!Egr z#lQUmfOB35gG3h1uW@I}KuM0YyuLXnh-kzy!@L;kAZ7~rM=eCfjNUiV(CA(Zk zrTlPp-2R5$;pIlSc!MRy;@7ow_hL~N#miia>DoY>YxiRa0wB`93Hy_s8W6RrToI@+ zT|r4GfrmOaAW_qi#W+re4`iM<qvoo6E9si0KMmQsrE7VEGO$Paj@9%pYswv}qFDTmZCuGdG^j?5jtebf zF6h&ev%cIdIiIm2(&+=9_Ff=KCiVX8A*+(p$~2zfZ!W%*boqtf472Pc@OSpAf+a#Y z^N0~mbbjF+kvxw*N7&BFlDX;0$kY~1G=JNha#-ciPK7~Q$7X6Bv)-h9kXz8NN8{tw zj(@YZ0XJT?Sg8~_`}mBLK`G-ym7$*ce3s0(StT2(U%x)9 z#$?e!lLpJ6m>N;B9w%Mlj{#Y;AP=Z z2BSz0VvRYO5A33BHi;U0-DyH#!2GBh;wlj7BVx9x^ZY9?bW7HW4l){_OxGQLV9 zPABn)v&n8HWX!kVXTIeHDhl{FxcHMxc6pc&rw(0vx-zat>SRvD?2T$N+zkm!`#3s4 ztN6V4z*p%}$FsobnQCC~aHCkw?EL>|d&{sm)@@rD4Z%Zj41_seIRZOxrkuG*o1CYx_dX#h& zz~+ddk;w;pbeP-M6Z(m@STpqX#&0uKX8i=nhz$+`wwNgEGr4iW=bMMO?qztuUUuHH zVFz5ztfy_I^#%oqov0b$@PD}80zuo6-Y?TCcnc1)5k;ih5k;K#OxE*85>6uKYAPD* zIH$-OYTm27^Q5MVpHD6rBm-};+o3>pH&y#1KEajd00+!VPBbJ>C^JIUa_ZA|&96}m zGB=!WVqg_l*)ImNWo+P@`TO34JUvHao{-j1;~%J0DL4K2aM=c=mpvvGRu ztQ+m$W-RvJoWRYU?T63fgM>-il8Hi&b83(a53XRCm#P7%|MzBLxN>}^CrEdOcmwt` zGRjJDTPC_N7bN`v_+v-o0s!oq^o$W^zT7W2@$`v&dnE3~exk#15kc+0Vq;$d(z_xd zu`iE@=4;`(*WjK5KvPw6k)EFJG4XxU?qBE>;hIBjXt;oi=db-S27n0WKvMbpKffR< z4d?-Kj}M3GmY}Vsv|i+lffl!}>eQ5;b^fN(3P>l3s1goIgnnH4qo;j%TgU?AQf z($j+!Yp+aRvzSx-AC>4n&Wd0&0E^p4Mn*QPT+)}$b~xC!vjUSJ2KX%3HUh~2Llm^e za;(E#uVF_Yr~wxCya(n1y#5Z>E-!)H?+R8_RFpg8YyKO=M9|x*8?=TlMgr3JQY{h5(FIPX#DQ`p8!D*qEPJ_Z@I)mYEA!6 zB~a`z-&$>Si3e^L1@J*7BMIK`MIbzTM&ac2THDLpWTU9eXtA*dv>qchIWDYw4PekG zhmRYA13l$vk-AC}BY=(jM(A0nP&gf)NGTwIz@)D-2_}VScc{%462a0MP+`(Tzfxfn zPXT;%u7!Fhu?8Mun}pK=KBVKr=x@9y=eWTu2aSemrkv&vTRGcfwVwX)nm%5z=?s4A zo;2?>zcK(s+u&CY0zPNc5(jM3dxG@q^Rg_KDU-|El21{-k{gE=>K>ddZ_D)Z(-=Hfo-Yp;{IFa-;H}t4&*aWrLNj;YSuzGqVEj9;M`f z4H=dKL11zVffvcKCt!=)m|L%C1}coJ+uIx?PcJVL*#|_t{Yk^EFq+?MY{fRn?8{mq zzRNacc%RP6k08k~EC)gR-~LtsJhf?dpDK~}aruS^p=xGRE%8^x&F32YKEA%{Q>ZQOfpTnAmAOCEF88Iu6Hi{SSbMzxD+a#ex1Y1k^RF@(eD1w6 z{oB%4$UdK(D2tCQ*Q&zI5k*P1l)`u-^5gni=d!tlFE^-%!MK)#22=W*PTYW{^w;y` z0haRVVuyr8b^EuKxaJxC^a z`&-}&ODv|63mLvB@C~LF7%WBK#Er!AW@V@d8|sQ*S#E1Dh+&vr(r5N?t*voN3?uM30d-Vg*HTi8K}$G#RhDE@3{<6Ksaz}x%>H%Lia0|jk>b8 z9Iv1h6MNR>Yp8Q<;2q!l^XVtW+uGJ9uG!l0r)$HdDO}DQR3tz_9?oh(Izr)f-*}DN z$$(DHvtyoTXqUb6;0FV$@Q*r;EGNFkBbUgN3Lo39y+*9{$>3VVX91 z7pqOcctid9nZSXdfB^CR&3V&+r9uf8Ft=K2AiI2$pyhh<27G*%40B+P?oI069Y!(R z%hcwCT5()gHP#f2e7&s(t`SJ(3l6>?H_qXv_+$R^?hRN3sslif z_Mhl+u+YDx$H!tv>5@0FOjuFDO?LhAC2{KNuDf>PgWCCIJly9nFFT614tItR#Xrbb z(yJ0foqLD)dbT$swJT7|#4k$~Q0f|3ATFs&Of2*$oaFzS61OvfD|=4P-;Fh3#NjSQw&SORK6Q`6(5*3&(bgR>Clx zZtfr1L&&a4-98q+3BSslwg)&YBpW%hELW66KW{72!+8ZIdAs?iEFYN zMm0Z_8oNxKjY8QPhys&5o`b;#nL%bN_z_@C>de|Pv0nq#N6U6ca0*fUi0#c>=-5mOMM&)*#*P%zQGN_@?ZZ5`EH z{17$R1BEl;`5pXm)H-AsNP%-T!I5=aQIA54T22nEADw$=R_L~hhY!>W$6q(7fOgLl zq4N)>d)3_&lx|wD_b5%W?lVH)bR14TbF?hcuisQ(J zn8FElwK(=tiyZUq?GO$;FECN|YMT7b5TA+g@SGgqTAG7ZPI@bd;liAE*sP?}Su7=x0T{+~-P6AE;4M-#(x>#^Z^3zqAvK%g5XM zJ|v|v8$VBq3|%;k8$boP1%tpmwC3zIP9hf$@pr#UO((9w9Dti)CMfDBKiy78*MY1ttyLPl;~V3t-(`q>_5sk_5L68#qDD zhsG28Y!MFiOgeZaDGl}HzQRI<6{i_5*C?mfp#f>{8?5in>*33s`!kn1AIzC?(uO)N z9-FWY?!@DyCfpq|u#!nggQ1Y3Pnh3IyHSVok&EQ5l)G&1kZCk63hVhPAVtR+pBA22 zO^d&ZFiZtk2}IiQoz!;h-O(;D%QrnAH_6vB~ zU!?T*7qoS;AP;8bTWf7Ius6vAAZFTh;w6z@kDx6TgT4BB7nI%`B`s9J;U2F&)>yMZ zMhFaeJaFVcKgm7raRH#4;wDIO23_qu7+@C^m#&T;QrBYWItCMlV%=3rj_o@w(J zPbCv_yp>uCGrn6lSXqVoS#O*+9dv%%LxnC}?+r8oORfg{jI8YRFY}M|I}d^q_5yyXc1qXR0hX~%=_f8ekP2SC?NN4`xI zEc^#P7U{%=zRI{-8Dh*g-{Wz5Sr#~Cs(r#&ZIXA zb?O?h!bd2Azb23t`ELt$>e4Q&$E#=!$pJWdF{Z8!kk1**}(uvQXn16@@=Ai&^Q5Qi`)au`IHh19TUo= zRv=*hUt0|$mjooZd%8XPhz^U5A;Nw!U}o4woOSyCzK)#Xf7=ZtBk^7|3KTp0kB_$;au=;Ahu`W#awiRw|)`oK+ zR!GXGd`(8EXF|+f*v}*YtZr3Y`FJsHx%m)L&96Bi43f=uhP7t&N0r)p$Spg$5Hg7B z?8RH#DXayMu_#f8s&dY^xw=f7bXOJGEwm12ev3V@dq0t><_~(YEst$5{`9Kz0-jhr zY`;!;DFPLuCUgOMD2voN)p)mQ@<=>FNx?Ls#%n+Do{?y5%(aws+xgOX?z^~8zFzqZ zjorY{eToM>&8Ykkn&Xo}s~HVdGlbO|p?R!{<=ExdbUeA9>qH-QJ|Eak zKwR%_f9kg|*1K-K1*+ca5}@SnpF>4Mn`Gv59f916DN@*b-2_a3ZOXX};2{>qfpmzQ z3`A?BsvasTp;*#gW*XvU>lU=aEr|=e2cPgeZe9buMPl>SRzEQCAYwt1GD+RpRsKmO6ng04*YV&n{>5rn7;Zi~-$WYM z64!VjE=!u*egEhPY?F5~*Et$u^J_PSKOUY2xS?HwfMg(VT0;!MgD67K{-!Amzq84T z&|?FJe)V>N1*%ef44tGdMLv5u=3|0cV>Ys95>j?J^_yyMAj{PV0m zGqunXQDwachMec4pT~`x$rgx!0U+S4ps3{u?`08JCW&pbu8`G8%^kTA#YZ%E@oLRepT>fvkDA7?+Tac)fJc@JpUoqP3-a_=^~_% z95DabW(fC=;yvyvzNP>XT}&9AZxu39ODQM;TiC=c^@%uhb^zDPaS_lwF#?oV{X=~W z4g$s|EBBkH#?{s?;2;&bAZ+-ka81S0lkArC3)`LJZh_jlnVvokVjVYmY$c(D9I@If z!2%2&Pc*4#x#|6$&V2k9NwiJ8N28z>VlnM0SkU#%3*69i$!9})RY+~S-e^W+eUq8E z<=cv{xIxtM6CAV{UvKfU3fEM^^pM*@F$Lltj2fO## zd&5KR+w-{)M_GHf!99lr&LjnWFu-sXCH_sD{lj&kZ}jDC&7T}l+|f9g<_(a;Um=? zz3=ECmL}B4U)hQA-gl`c<#wJexIe0GkX%ieDi6%cuKZZM@;flr)I`m9{ zS`5#&^THzRhfabU-H$h6L9&j>VVEQx`Hv6!h^trCmpz&9vDuuY-99+(*`>UI#D@-^0)N^i`5X_*bp(;OQ^KjuKOX&up0wt3OG<=qV0`i8hTPqkdRB^M3 z5_0zT$JMaDxeh{~W~#Jg6JK9VKrh_Nq4n*BsZ1;176>A&ie^`Napo(RJ6{yh1yA=X z5M?cVe{h-jQo*UxKn1Y1jeTk!|H`vdjyBHeUux}EjryQkVK!Yv@Lp9vSVQpwLmhZr zD>vkFc&KE)g-p1vrnLa%2zO(u>c24PRQ`A}=x~?*I|dzzmHRYTv`TA5T%&3(0{>t=fV5jFCN1q_`;>QqmD z#*G|xq!jHzG+B>N8gCJ3LP?s~!UL^s6;aiU>Se9ZlQgr{DtVM;cM_8S@%gX6t_PFq`G{mtFPhsPpI0(e0z zoJ+h5CZeG!QyVzo{z-vIeUWlhK-`5FbhoM$h+9m#aJHf*yC!Va;|J!efDjzuaA;y& zKEp{_u>T|o^%;a&`{_FL+XVGX540X5X-)X8=Bd*-SL=uy9kys-9C+3&#eW0kSM*60 zIkY#oAw)NYvKSbz5`g~>GCvIA055${B1rkTe`%hheSX*Z3B|kn%P86R_SpUj_qQgL z8f_Wy)nq`^-51Yyuvl0f!q|b0ur3c*iTA4TZ~#03pc*~}ubr7G+#d{3ULJ6;2EY6F zV=e(Z+f^!4eTgmRMcgl+r202{TV)iLRx0=by~Hsiy~=Df;4{kQE%FBk z!6sh00_M6dD-5+kQ;HLz)^v{znquIKqM}^%x}oMev&>Z`AI5qKlK|O-vfhm=Dxx)f zdQ10Sad^?cXUriRG5J7$Nwa7{P#A#AZ^%P?>2mN}=>z`Q6-1y#2zG2hJ(d)&EhFkW zxL9Ow+)rGbIzVdgZ*$J1Zqlw=^i;?P5xKHWj9h6-L_d0MyP}VUW{cJm8$s|-I9S>tZ90S2(VW@XxQ)MG9xmS~j$Viklbj6l|AC@>a}m=}#MRb1JgO zJRGVXJ28}pOX*>W(I8gTGq7EeRNN_UMylAAUZ#=NmODQo3wG{%0B+U&vWl~nJd_Xc z>6Ffg#eG8%oiE3fjf=}V4X-`@@SovS$;c@w;}PqvJaV6YAVK;;`@Ha7=!vVGU0P1Q z^Xay{0`-t)fvB0#c=}%D2I%~bub6b=3PL%L-zxrIsjBq?1w%`8!5_8&6S7Vqr zS7S(zUB+?~0`^PKkI{9{zwdjJnphpr{g%rx;gZm@=P@Ts1}_u#!!A&c%52Fb)1`> zT&YGf$73&SODgu_D7m>t>1@6XjFE$nojUkCqqBO}d~C0e<4puhdtS9TUw9Y$*5~U5 zNLBI1?Kw7&x%DbJnB{B_%6}d%CZm$U7B5Q+tM?c@!7f$qKeQx-|*aTfF8vik{hre_T0YFcFQWcgSCli5{ARPWA>_v`J1;&?~Cn1)ImH zFJXv|>lCqhyO#CKsYko=*7`ExG5Pn%>iPdHxn{tVCo>(dkyYn&N&(bW`7$h|5pdC} zB3dA%RLl}`FRR^Vgr>Usaw1#o z&1_o)*(nV1Og}SPg@T12vmJs1dhC9=O>AWJB;_+_D&#BHfAfHE4TK+Sv&khMHy60^ zS@%1Ix6c-ui(eAAx`jbF-_hn7h}6y8a%t<_80UsEwFJ&D`E3hiV$NAVl7AeE-pKn; zjk;sdf4Aju{EuxpLOUt4lKGYY4~#jlsz&18vAD&*R~+amlrWvm-I2Kz`e9F(8uFjM zoXUjL4@%@8g-7#;8Pa+Db2rdaDuG^I-ksYz;0%&f37B?ka#{<$VPIm)J?4RnC*{Fp z$82e7nTnN4GaP9b_^);w4CMe=P03(aG=X4Ti$_HvI7Y#}6PSMLe`TuyVo74O z__6+|>S}>?xA2GEG5AAFPyo9f$?GcDC({JLZLHWn?Hmtq<86P43^5#N=0~;LZW@7g zuJ71?*pBy*r^C$O^ggK#p9l^>M-{O3np{O+?9XBUue}bT!ddCdVOhVA^w&LxFln#k zS9ho~Z5QTH1vOiSzrxf$s462^g^GNLDy$CC%}@DXnPe(@cw zKFr0)a^kB@7yK`5J+Fcxrl$GXlLDGY345ZK$MNLh5Ux9Zfg_=-wPukd> zs4sJDhqKfemX!84TCjTHVVu%HoXT zhbv6n{>@qkRQr6^`+;SA`4MRtN5#!6wbstt#Pv)~-rE+a7n0OBFfGVJ$Ji%ssh1qeuKGo64PL^(8dngVINqVy?^bPT7^ zQ@&tux0Q5lOOdu&vc+=mmU`825@X|IeyZ)f{{gtWqo;JdTqqF5FsL?$d8S&MfZ8z%p%+;S9cuXPDB2q;B_2 zdrqA=v!n0e32u`$y(6^WFgbVUaM%tc2@}_?a8}GSSXiap9S=ktMScO z*scfyq8A8218rHogBm3(vmMxGrk}B<baxxCEI>r>apao+oA{Uo){2H1Zc$LnMf?7EVzsag`#l#jrha|?Z{1(B>up_6vCi> zgbNoyH${oo1D}0lqd$o!=B;rdG^aY^sOAD8v-6Au@l{o-lJ(r39id^jnJw3WZQmvi%nc9hHrI%H-Q*DMFw4u+>Wz?Eryzu~a)Fg;>?+K^QAZ`?c)i($bA za{~jYVxeg7?S~Ud*meS<0_*mPG5<&G2T@VZBO#+`VW&pAv&XovP{QfDvl>`0d;fQ{ z*jixU{lFefGu(F}vhc~Hg12@`B@2PqzLi*fz6tzg&oK2ces^w)c)ox)aasvRP;=AW zEvI2a8^CmS6D}5Zd|^@zcf%o#_6?)6Bp-U*zJ-M>Og7yi{HM4ND!q`^#z}> z-eQFIwJ>O7EFD19`Ls0XST1Px8&E2NFZ@Lrjo*?If{u?v88(?O5VQD$bv`G?G>LbMHnPx zeRDwCs8!P-7J_MF6-qWm;Bl8>FHhFBT|6d83wm`RTTh~A@yUs=R7KWph8-Y{;lA(n z=k{&6>WW^XqB^XAF@GU~ywZjq;7Y{aVHvJRFs*ESA8JoiBWpSBOaVUzI%!ii8qa;M zJa+x*Q*PqS+HUEhTi&Ry#q)v~>=&S{EBWhjK>R{e_{S@f40k^Q0&du~An)XqN-vSM zfN)L>kn*ArTvMy`I|q&d)c^~1u6%u*6+U&porQ#_Qt$(O?Q6g=_=1E4&AXnD5F}%; zGgc}lW#)UFoc6iURGSSFiASj8_md8hAyfwyE`@*Vw!6|tQT>y(T6AfZoT`K?J5ED0 zR;15UQi;CrXb}b;8P5l|D#T`0haQt({O*>|RF(Vkh=OEKdKLKf8)WX&wZZ;^4g_lg zH3_?=*^TYTGX(Q5Pw@$gdkb48W>-G!U&+B)ql^z`J3&Beyesce3cvP(9&e>GjFaRAk0=))gab0 z)uif-5|w`B$YrvGQ5#F`KEc7yVQfpCE~C7ra1elFA<+Tn8D~nopcW#tlbE@2MbM}S z$0qn@OibQ%x|HbJCscw3N`8Zw(GL#O;i-nn}IaIV*=+?+)*a&zza6 z|75X7k2;Rxh&)DyMtX4%eS;~p^27I}$5+nGf~?UFF9BIrg#ZHFFj&kg=(uK35qTZndNR?1F_(<#tt_VQDMAo^+uN(b%r90FkGkx`TI#(V6QSq&LlGQ^3 z1BmK-&3%9r^H9|KI2zXoU#10ztvQ5P9x^`&FdK#6Rode#%L}agg9>%Ng!E9Z9Sdb3 zSeL7LI0E60@h%q9oQoOm$gX5L^t9gu`PHpUUBI@^saUmt# z6TU=b??g1x`wf<$wuLlddE|KY`=s5ptd+zal7*mlQwe(wjqjd?@QVQ%8RVA92aT<9CqytnVEju$_Oxnn$;;0@bz1uoxbQm@Pkyq-wuKx@v;SpMi=myTkI#@)pl z^inL!NFq|j+iYyCLY6ka1)w+H37Y3i7;67oZCpsN#Ji@p+b3!P9g;loW{W)~j-YzK z;5Td7rD1iad@KE2y=PO{;_}Vw?k}Fvf8{sw%oroiTE%x-^o~UQLy*B;W-iDr_wlkw zUa<}#J>l~d%k_K6peROi%+M@=gwyU3zxyYtLx`YPZ|ik26zuoK4IDhari(X_=_- z!~v=_##iGsDGq`H!qgY`qB#R$`aP6@C7KhUH2`sXAMXn_C5G2N*(IM0>uoOPUoy$H zb%t&fSnsn4aw99DeW#o9K{C{}bf|K6-u@?8@Q2|*1{jW=88^Bs87uXan~3}oOn5`p156S-)f=+bpUHSO{A5-xXN=bw4c_|4Fr`EG#8 zvx*-qX4uX^X<#Pdbmz#PbAs=h!+u~*$(vb3z@xqKmyXHV3egYC4j?t)Q@7O78Q))8 z25nETm9OYk-651j&%PD(qf}WdY?2%LtR@tnnNaA(S-}CTkA3^dYGY-+=$m+DF6*L`TY1$sJ>}ah|F3wXe zm%U+b5I=-3RR79sg|Qe(gP(f0H=a6LcN7F!g0&tT)^=+6;wPNScRGIC5dr%Box9+S*X)*PJzDQ^g!CgGtm37IgEWK z2TqW!`N-Ez|G4>@fyrSs{^{H{$|y$wTUabybLl*g?d}AOvxGV!PV`5oB7F@bDetW6 zaSRe7ANVi)1Fs0|GhIUT@r1-gq7vR)k6oEDhNYz?PCG4BXK+g#i~oDCaRJ)FwrGQM2c)*>R_21>=6G*FeeZH~#Nu#7jRJ)$FLFkCG1`FI zo1BAai2k2k#c@YTojq>n?SLsm%-}NQ+dW|BPZi7&j;>R1$FbZzs4~#pq-{&Jf)38!?Ao zP1izgDWVVNBCAQsf1fE7DwfpQ5r1L>D|Mb(#gyv_k@sA*g1G$Xi&t~LdZ5as{^E6RJUP}RT}&s z9}DLaWOHA>##G0R^$?v}@?N}HdOSJqxh?f5nF{m_Z~pPSCg8(>jh4S4uZ?o4vS!#c z?%kK*()62`;)u$*vIbQ2VDfgB(!EPk4?&i$COI-u{rBN*lzv;qGeKce7byDPG_8vc zhT{iS(2yi7_q4h~1l7>|kd0@|18+OAFBLlq^N38Ir|Z`NnV`1v%*&cbzq52sl^;K@ z)=76ZtJ|cudVt)TqQl{yH7EDl@>qdUo`dvvXRGq7F2*M&T8fj&5StC`SUUTD;?%8q zO1Qzrn%%JmNQlRoY4!*^dr-4y=5hzNGk(`qcO#9J5#F$wKG9AIWqb!Wu#SSeU~P3= zK&<6^IM+gWYoRqghr&qk4_ors?G1)+!1W{amHuO%(K%sJ?Ml|F5#)9g{*H4`)Q99p zN}`*v`QoWB$%68y+_Gua{T-efYpob9>w8%@s zs6}t-yP?XP6?SCvt$Q`3>=+z}Erdy~f}eO$5<{y=LveL9DB<#365S&!fb%6lwXd@g zM)?Rg;%x(~WUmOznkWPDUN<3+<#&5$940Q+DRAkR zo0TV(RaI;t$DBtqFZJQsG0bLF>779sqQFS6*Invv$tlTUSJC0{qyyhWi6#W(a zP<;*ZyT|7|yiS#cDTY%Z-tRK_D<_Pa7Z(_LpwhmV|y6}Z4bRXCVy<`L0tXr zs?^EF6WLk68bv|0-}E)^n`^$}^Lo`Dp?hi+Y7G0lTHG!bV09R$YQ1Y15VcVR!(TJ} zZrm#sGdHKsUfsljl0B@+xbF2qFgxT-oS6$%s$W8qw-|X~qqKq&N(Ek69%^p{Ha41L zt3;hAvn1t3Y_B)0>@0i>tUSTaz1rGqtb=r@hM}vvKyGbkIpw|bKB7w+PSqx{3I2|6 zci5&La<(6@zKtliQmn1&e!E7n@FuD~Dmf6Bk1jcOt?o7P(l^ac=kn4kBk||s#bw%h zp$@Wq-2KaCbC+DQ`uZPxnzvON<(6}rTt$5C1R|<{ZG-m_#{IUo2;u>oo*%Tizvy#1 zw6!p_qnqL{7--+3B10#>5}R)FLSe)+q_?$t{(a09dTOi z3hbza!?Rru=58%N8Zc>R?4Gwc7Dx-^=FL`$jM}lj#+G2xB{coofO_c*;Y{TN#aU4I zh5hPGy6{Ywx{HAofydSd*SGf;%@3u*AG!?OF_&(AV4q1RKQD;1pBN07uNHOE#^`xQ zZZF6^lNqb`QyW->V%)mh8e+s@JkaOgB2yLcDCp*A!JJ0EXI5cCG+(X zu!$CY#}1n-v!0Tjxh*d$&pO!vlNY{|-bI6|Yyz^*@w(ZbE9vPIOekWqc+Km$tIIqw zPALUlKra}BC(}z|*d8Y#9LptyYc@hyvW8{h^onC)GbXET5k!ni2@}^g{)8m=%OSq- z{f$C_urgA9#bumF1@93d5U5w^oSQhBU|rw_d_)`4wqPL%Vzta%$i#vmV#(QV*KrLk zl@`d8${@!h!w*AxJ;sHvpQm64nWzXG;e3pqURy_%RcMKAepcy_bNW3>a*Qc zQXXHq_UJpcuP0zKzJOd4FDYD*LiDQoQTKk4L(iU1^k`BP>RTIEf1X2c+(|hQ(Lii*bM})l;r!YN}IPkYPBCtNOeoCW~WQYf1NJH)^)tEs@+aYV!s6^k{!}VE`;k z;feOvfmUE%0RF+JLFp7!5QiKFfT>x%t?OwzpeciruBp1Wn}-~4ED(PQ3yyya^E=Q_4V%B` z7>PNZe<>)~EqvPSx`&$9xs{ROL6eWp_?g%4mFa7r?R8g0?Tl{%~JV!uqRDnSt z)!911DCGrsKT@q#tr|4gKG*crGHC0M zxb$(4i~x4A`d)h;J4^ulup|~0ijQkRZoBgC5%e2#(h{*<_Dm})i)&w@f=Z5gw0!)C zZrXF@sCW`-R8A;0^NV>A%V;|$v_b_@GMyvn50;yVN0vEPfD6AXFlqPPG|Olb&Q zm?ymaH}gWYdOg`jufGUX@IJP!9<})+!y6PjSzhAdyiE(9GPpVle!d5KCcFOv3AnwT zUM$+rzQuU~U2ly%Z~PiF=?1y2D`Wjq)OclCOBJVK?*+U1{o1{9JswA|09TFwgw{r( zR7t|tE7Rpy=I(J0+gpVX`1=S#QKx+;6R{>l)7aAB{l(xd`(1L}6(_KJGutiRAPVDT z@s>k8!8fgrZFvX6p&MuB7cEfOAO=&vcfLkYMw@OF9ATVIW;517Y_!mVWh;sgLi?s9 z9&)thi!VFW!nbl^S<-jsTjs0bfULu)f#K&d;J zsSi|0Fw_Jn=KS=pCrWCwyFaF_Ktu{ZLr?GQtTuAoRhpGuHx9aQSemx8ApP z&t|C+%u4k;mIh%O75v)5%CU+})4-tf(37Z53v%t&p4Lq>mt{ocVflQk>JPKlJtT(i0z77NA7!o-Di2kYo+YhPLkH0MEGC^jLO{je3?urkZebDwLfBS@ypPKs@~^C z|A&_}W2E?M-^A4~TM5{&j31Nrs?fEzP3Boze^xlu)Dt~sIf~LVld`|C`qu3KuHN?6 znhN-w+I^TtU?UW9Ran@gg2$PW+^!qvo{x&d2ebq7s%Z2eHH17y-h;GPj&zn?Q6tB? zXcP1dr5Gc6)zp1SKl#%Wer(Gh6s}O`RF$3xs9h<$@4qq!6A`$r99J-Yg|kqD1b9e> z7YETfJ}@}moLMzLUfUN7D6eKS?0u?1P$>xwb|jSDB@kd{kFC|fiLI3msa4l@jDz>ECuHX?$U>e?kQ@fz<{O?ZquU=x zZ*8@WUpy<(0v_5n4{rOj@_{bj11{X2#-rY7pa;APBVK;@_uIJBuif?m^rJ5JcqiM4E9~SGsQT%WqTR z@&f1#QGSX8|3}`mHZ}Rr&pN=*&Hk`WZNQ7b??mKrfH#PnH--QC`M)0^5J6Eo%HGFW zUcb}c_~|`Q$K@;wfGzX%EuO?-MU;nC&5U|_Y*Gq;ZwdW#oKs-gQl@)k6<}2%z~9UP zd7jPOCt`Cp|Mmd_xw8WBz)SvT4xlY*I7O%6jKW6ox~w9w4g!@^L?*)F#axjXy8TgH zKr8-vWmo$A&oX-!tWw~5>0&i;BhF>Q&5`}E>~V74oh6nb6>tvIIMm87IfScntoa&P zRtRU7+r#Q6@{)OfwgtV=uxxS(xP&#Ak8u0<^C56^Fc&=j1>(y~z9J@y%`O5dHeoIY zD*9bYNbim&3nrxb-EbZqwJgrIf7R$&ny}3J0hhBTV|i|gvm2%P{$l>gJKpHFhqorc z(@LtT_O87Yh}bvZjx!wB6&#Dbf@GBfe~ zWq5yzcB9D7>jOwMg5qkN`um>YmsZ>wE=XrMo9Evn&VIcOC-~yNs?{Kkc?2TQ*cXr> z^7wgaPZlAna9roZqJO=}UVJyrBmyQ|SjVe>eT#7?=z+q{%sN5{LmiOWw|l&r4X%5{X+%}XP&M-eDzG*J5M7j%`o&w1>8hA9M*xX2bN z;7?zAzVEVutw@}%d;mHA%GAv&#VBLAqCnCUI;Z-Ck|~?eDytSxCOOQ7@7F^*0yZ&e zCmEz)+CTcVJdtSkPTzcFrN-m;{4E}}Qd+Q(zT}M4#R+NGJZ>gk_vl z1UnzfH>u?7v)Qb`_6FhJdCVOZy+V|3`?kgUf`keS4dEJzq;|j)W=vz|#-Z*nT10d} z?AKFT*FR{HF8_k|f2KtyWAxvoFgEc:flz%tb!qnT4|6c+A%k-wocXiA(O=QPE7 z`GH#V$BKqrgwkT~uFLe{(2Vdv<1dYsiX*BVV0sOcm%;Mt(AAXxP}dD>>^k%E$FxY+ z71G7Xg1U8M@64^qu}h;(J1kEl_Bp0x)*q^!x3}&T{*#L!s^ru_tEwYN z7j9Vj@nzQxN%Ny6BMY6lB<(4N!_OJ=VU!MLw==!oZ;nj#Z8HH9UBtmcc}sOTM}p2d zs2C{bb27S5n}fPvlc$cxD;&_0Hwp+Y1BPG#FoQpGP;vgWlF|4CYqUT0AT$ zFkO|TLegYK-NfVplXVYQ_$zxJlZ2DLkgj_(JAT~h^zAJXKQR@Hf+THKE$$t{M8xIQ zfK`;;6<0|`=H*1#CF%nf$LGiO{;*-)@FcQ&dZ_Lc$mS4}l}2Q}39q!hdA{^{JR5YY zjQAKVoDw1;*Kv{?T8{RsIu7(yVubCwkGN-vyjj`lii?e9^|^A~+T8!~sgK|dtixdj z_UKL!GlncFG7YT4&myYoSWxli`^5BEjLNz7wfHIOBE>w}*FC#e(+w6wUi!{YP|Ut zH=MR0CYC|p?aoH699I9Flziiz(5U*cQx=V*j^e?lRhC9f2L~Sn-@oV)ftg3sY5(1; z5YSfNJY3@3dz{D?#IE1_+nzHjAp8znseNreR1X&C7L(2Xmx7M!wANyWM)_=-kN|v_ zzJt&MAdVi)feL~%;9N|D zTQbR*&eQ>?58Le&bH5GHO-6oAxJsS$J%Gx&uW^DPE%+5?LSc`OsQmfl_s@2wgoWW% zFkg>!QyMotNe2e{6<4M;>kvRwGffAou4IYft+1_}NX-Wls%$mNIUWTc?k)rf_PC4{ zSrZ&OM=J9KE`N_MY=G!!I&r7!6nZL|$|$hIDz2C1$`4Li^j;{+)~V@o?P^30@is{h zczNt7Gv>%~On~t3WPbY^|HlbbiiND6KGk_huG|yp_!vIqCb2yo}3m@ zh*N@49w0$I08Vo*f4RW_FZdB09CcwB$%KRq+AdX1nwr1qk@@2$U3ou!j3Kn>I3@?< zw0+ve?{&O9R+cb*(FwLqpX@lCD{Qr;_C4%|CYVt*7#jB%A!|ptcu@EAAeEqBis8!x%Nnz zZd|^N*7YTvNr1AFZ=gry3H;(8Jb@<&)3`k(;@jQDJ8-mKVbc5P=Zq7`L&Q*r^Scll z$oZDsDI!65pyRc~m+xD~6E=L?$WaGTTQmBsXcJTMxxDUo3fn)oht7%bDQF&oWI!hK zYxSIyMTC}P+mKop!fV3k3GMQdiEm$!Y0dqJG5h&XY}7x95KhZczA0Hq>Z2!O5}w@Y zNE77>LN3ZUeTbB(qP;x(Xw;BrAblkQ;{R&zJfoWIwna?~Rf^K2BZx@vA|0tpRVmUz zdeP8(2LY*4q(eaIy_Z0wN)rhnO(76UAap|SaDw0W?X!Q}J;vVWo^$URi9}_XC#hGg>Q{lHU8B zC6)?0fLFX1to%eRm|L8>Ls($8?!*$){+8xjZA~WQ*2Bl?MJ^4?YB+cr*@IRFJ_vje z{iK*rN1m!Hjd4ao-+)|@=*JGqnQZ?1}1NA<_cZMRzr!Gf5RY~G>>Y|=*jyom~WhRsMvsVM*AAF62nVJG(E>}ZLTGk||UZS1~FY$qEY z)T%^`D=yuDPHQC5;U$LlOXjG|?mkyXmloH+S|ffpOfJa;I_=}rm3d5VdgtxnrVUD{ z`yjkn+1{tpus`bITFei>iWeWPh0vQ%@!~eYw!SwOe Ly{hxH=-oMPM#|#8Zi1O1 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 literal 0 HcmV?d00001 diff --git a/search-services/alfresco-search/doc/architecture/ContentStore/replication.md b/search-services/alfresco-search/doc/architecture/ContentStore/replication.md new file mode 100644 index 000000000..bc8dda720 --- /dev/null +++ b/search-services/alfresco-search/doc/architecture/ContentStore/replication.md @@ -0,0 +1,161 @@ +## (Solr)ContentStore Replication + +![Completeness Badge](https://img.shields.io/badge/Document_Level-In_Progress-yellow.svg?style=flat-square) + +### Introduction +Solr Index Replication distributes a copy of a master index to one or more slave servers. +The master server is in charge to manage updates to the index while all querying is handled by the slaves. +This division of labor enables Solr to scale to provide adequate responsiveness to queries against large search volumes. + +![Solr Replication](https://lucene.apache.org/solr/guide/6_6/images/index-replication/worddav2b7e14725d898b4104cdd9c502fc77cd.png) + +_(Source: Apache Solr Reference Guide)_ + +SearchServices, being a set of extensions written on top of Apache Solr, leverages this mechanism for replicating the index. +However, there's an external part of data which is managed out of the plain Lucene index: the ContentStore. + +A ContentStore is composed by several files, specifically one for each indexed document; each of them is a SolrInputDocument instance stored on filesystem using a +serialized and compressed form. + +![ContentStore - Filesystem view](filesystem.png) + +The ContentStore is where SearchServices maintains the input data in its original form, before entering in Solr and therefore before +applying any text analysis. This source of data is needed for managing some search-related capabilities like: + +- fingerprinting +- highlighting +- clustering +- stored (i.e. original) field value retrieval at query time + +### How the built-in Solr ReplicationHandler works +The index replication mechanism is provided by org.apache.solr.handler.ReplicationHandler. +The component is quite complex because it contains the logic needed on both sides (master and slave) and therefore plays a different workflow depending on the role of the Solr node: + +- **MASTER**: the node is responsible to manage the index as consequence of deletes, adds, updates. The replication handler doesn't play an active role here; it just takes care about incrementing the index version, other than providing the required endpoints for retrieving the index datafiles +- **SLAVE**: the node maintains a local index version and (when the replication is enabled) periodically polls the master in order to detect index changes that need to be replicated +- **REPEATER**: a node that acts at the same time as a MASTER and SLAVE. It is used as an intermediate node for replicating the index when slaves are on a different datacenter + +The _CommitVersionInfo_, which drives the replication process, is composed by two different values: + +- **index version**: a number indicating the index version; it is timestamp-based and it changes every time an update (i.e. add, delete) is applied to the index +- **generation**: a lucene index is composed by several segments. Each of them has a progressive identification number called "generation". The one with the largest generation is the active one; from a replication perspective, the generation number doesn't actually indicate the "active" segment, but instead the current 'replicateable' one. + +#### Available services +There is only one single endpoint (/replication) provided by the ReplicationHandler. +Then, through a "command" request parameter we can indicate the logical "endpoint" we want to execute. +The available commands are listed in the following table; an additional column reports if the customisation we are going to implement has some impact on it. + +The following table lists the available sharding methods and the associated mnemonic codes (i.e. the value of the "shard_method" attribute we need to configure in solrcore.properties). + +|Command|Description| +|----|-----| +|indexversion|Returns the version (index version + generation) of the latest replicatable index on the specified master or slave.| +|filecontent|Returns the stream reference for a given file. It is used for replicating a file that needs to be synched. | +|filelist|Returns the list of index files associated with a given generation and all configuration files included in the replication | +|backup|An asynchronous call, which will backup data from the latest index commit point.| +|restore|Restores an index snapshot into the current core. | +|status|Backup status| +|restorestatus|Restore status| +|deletebackup|Deletes an index snapshot previously created. | +|fetchindex|Forces the specified slave to fetch a copy of the index from its master.| +|enablepoll|(Slave only) enables the polling on a slave node| +|disablepoll|(Slave only) disables the polling on a slave node| +|enablereplication|(Master only) Enables replication on the master for all its slaves.| +|disablereplication|(Master only) Disables replication on the master for all its slaves.| +|details|Returns the replication status and the current node configuration| +|commits|Gets the commit points for the index.| + +#### Workflow + +As briefly mentioned, the runtime logic of the ReplicationHandler depends on the role of the hosting Solr node. + +##### Master + +When the node is a master, the main responsibilities, from a replication perspective, are:  + * **update the index version and generation**: The index version is the actual trigger of the replication mechanism. The index version is incremented / updated each time a change (or a set of changes) is applied to the index, while the generation follows a similar path but it directly maintained at low level by Lucene.  + * **expose the relevant endpoints** needed and called by the slaves for replicating the data. + +##### Slave + +In the "Slave" mode, other than providing more or less the same endpoints seen above (with a slightly different semantic, indeed), the main difference is the "active" role played by a background thread which, simplifying, performs the following operations:  + * get the latest index version and generation (command=indexversion) from the master and from the slave + * if the versions are the same then no replication happens, otherwise + * a temporary directory which will hold the downloaded data is created (index.) + * the list of files to be replicated is fetched (command=filelist); this includes datafiles and configuration files + * for each file that needs to be replicated retrieve and download the content (command=filecontent) + +Internally, the set of downloaded data files could change, because Solr could decide to download only a part of the index or a full copy. + +### Alfresco Replication Handler Design +The Alfresco ReplicationHandler is, as the name suggests, a customisation of the default Solr ReplicationHandler described above. +The customisation injects some additional logic on both side of the replication mechanism in order to efficiently replicate the content store. + +#### Master +The master maintains, for each core, a versioning history of the owned data which consists of: + +- the underlying Lucene index +- configuration files (if they have to be versioned/replicated) +- content store (if the content store replication is enabled) + +The master replication handler configuration will declare the new ReplicationHandler class in the solrconfig.xml and it will have an additional attribute +which indicates the absolute path of the content store root folder. + +The "version" number associated with a set of changes is incremented after a persistent change (i.e. hard commit) in the Lucene index. +Note this behaviour is already implemented in the default ReplicationHandler, so that means we will inject the additional logic required for the content store as part of such mechanism. +Specifically, we will use the version number (aka indexversion*) also for storing content store changes. + +The content store changes will be stored in a separate Lucene Index, with must respect the following requirements: + +- it must be present only on master nodes +- it must be initialised on-demand, even from scratch, in case of absence +- it must associate the indexversion to a set of content store changes (deletes and adds) +- it must answer efficiently to the following query: given two index versions S and M, where S < M, give me all documents (i.e. content store changes) between S and M, sorted by commit timestamp asc + +The ideal candidate class where this index should be facaded is SolrContentStore. The class, other than dealing with filesystem changes, would also manage the Lucene index by executing RW operations. +The SolrContentStore would execute and collect all changes that will be flushed in a new document of that internal index when the CommitTracker executes a commit. + +The existing endpoints on the master side described in SEARCH-1838 would be slightly changed in the following way: + +|Command|Notes|Impact| +|----|----|----| +|indexversion|Returns the version (index version + generation) of the latest replicatable index on the specified master or slave.|NO| +|filecontent|The command itself won't change. The difference will be in the additional content store stream handler|YES| +|filelist|There will be an additional "content store" section which would list the content store changes that must be synchronized. Specifically, the "deletes" section will be a list of items, while the "upserts" would be a virtual file (something like contentstore://blalbalba) that corresponds on the master side to the optimized stream used for transferring upserts (new adds or updates)   |YES| +|backup| |NO| +|restore| | NO | +|status| | NO| +|restorestatus| |NO| +|deletebackup| |NO| +|fetchindex|We will include also a configurable option where the fetch will include also the content store.  |YES| +|enablepoll| |NO| +|disablepoll| |NO| +|enablereplication| |NO| +|disablereplication| |NO| +|details|We will include some detail about the content store.|NO| +|commits| |NO| + +Commands related with backup/restore are not part of this ticket. As consequence of that, unless we will do that in a subsequent implementation, the content store backup (and restore) will still be a manual process.  +#### Slave + +The slave configuration (from the Alfresco replication perspective) would be exactly the same on slave nodes. +Other than providing the same capabilities of the built-in handler, it will also indicate the absolute path of the content store root folder. + +The workflow on the slave node would follow the existing path:  + * a slave should persist the latest applied content store version somewhere (e.g. a file called .version). If that version doesn't exist then the slave needs to get the whole content store. + * at a scheduled intervals (see the "pollInterval" above) the slave polls the master using the "indexversion" command, in order to get the latest "replicateable" version of the master data + * if the version on the slave is equal to the version on the master then nothing happens + * if the slave version is lesser than the master version, then the replication starts** + * the slave issues a "filelist" commands for retrieving the list of changes (i.e. index changes, configuration files changes and content store changes) + * the slave asks and downloads index files + * the slave asks and downloads configuration files + * the slave downloads and applies the content store adds  + * the slave executes the deletes on the content store + * the content store version number is updated in the slave   + +_* the Solr replication handler actually uses 2 numbers for indicating the version: the first is called "indexversion" and it is mainly responsible for triggering the replication process. The second is the Lucene generation, that is: the number of the last active segment in the lucene index. For our purposes, we can ignore the generation and use only the indexversion._   + ** _if the master version is lesser than the slave version, then something strange happened between the two indexes: the only thing we can do is to replicate the whole content store (the same thing happens with the Lucene index)_ + +### Links + +Spike: https://issues.alfresco.com/jira/browse/SEARCH-1607 +Implementation: https://issues.alfresco.com/jira/browse/SEARCH-1850 From 7d309fd83abfb9be42b1dd5e65c05ecaf07ee887 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Tue, 24 Sep 2019 19:02:02 -0700 Subject: [PATCH 2/3] [ SEARCH-1865 ] 1st review iteration --- .../0008-content-store-replication.md} | 47 ++++++++++++------ .../images}/filesystem.png | Bin 2 files changed, 33 insertions(+), 14 deletions(-) rename search-services/alfresco-search/doc/architecture/{ContentStore/replication.md => decisions/0008-content-store-replication.md} (88%) rename search-services/alfresco-search/doc/architecture/{ContentStore => decisions/images}/filesystem.png (100%) diff --git a/search-services/alfresco-search/doc/architecture/ContentStore/replication.md b/search-services/alfresco-search/doc/architecture/decisions/0008-content-store-replication.md similarity index 88% rename from search-services/alfresco-search/doc/architecture/ContentStore/replication.md rename to search-services/alfresco-search/doc/architecture/decisions/0008-content-store-replication.md index bc8dda720..b4ad1c028 100644 --- a/search-services/alfresco-search/doc/architecture/ContentStore/replication.md +++ b/search-services/alfresco-search/doc/architecture/decisions/0008-content-store-replication.md @@ -1,8 +1,11 @@ -## (Solr)ContentStore Replication +# 1. (Solr)ContentStore Replication -![Completeness Badge](https://img.shields.io/badge/Document_Level-In_Progress-yellow.svg?style=flat-square) +Date: 2019-24-09 -### Introduction +## Status +Accepted + +## Context Solr Index Replication distributes a copy of a master index to one or more slave servers. The master server is in charge to manage updates to the index while all querying is handled by the slaves. This division of labor enables Solr to scale to provide adequate responsiveness to queries against large search volumes. @@ -17,7 +20,7 @@ However, there's an external part of data which is managed out of the plain Luce A ContentStore is composed by several files, specifically one for each indexed document; each of them is a SolrInputDocument instance stored on filesystem using a serialized and compressed form. -![ContentStore - Filesystem view](filesystem.png) +![ContentStore - Filesystem view](images/filesystem.png) The ContentStore is where SearchServices maintains the input data in its original form, before entering in Solr and therefore before applying any text analysis. This source of data is needed for managing some search-related capabilities like: @@ -27,6 +30,14 @@ applying any text analysis. This source of data is needed for managing some sear - clustering - stored (i.e. original) field value retrieval at query time +In a master/slave(s) infrastructure, the ContentStore must be managed on the master and it must be replicated on each slaves. +Unfortunately, the default built-in Solr replication mechanism considers only: + +- the Lucene index datafiles +- the configuration files under the core "conf" folder (e.g. schema.xml. stopwords.txt) + +As consequence of that, if we use the default Solr ReplicationHandler the ContentStore won't be replicated on slaves. + ### How the built-in Solr ReplicationHandler works The index replication mechanism is provided by org.apache.solr.handler.ReplicationHandler. The component is quite complex because it contains the logic needed on both sides (master and slave) and therefore plays a different workflow depending on the role of the Solr node: @@ -86,6 +97,10 @@ In the "Slave" mode, other than providing more or less the same endpoints seen a Internally, the set of downloaded data files could change, because Solr could decide to download only a part of the index or a full copy. +## Decision +The SearchServices replication mechanism needs to include also the ContentStore as part of the synchronization workflow. +In order to do that, the additional behaviour requires a customisation of the workflow provided by the default Solr ReplicationHandler, as explained below. + ### Alfresco Replication Handler Design The Alfresco ReplicationHandler is, as the name suggests, a customisation of the default Solr ReplicationHandler described above. The customisation injects some additional logic on both side of the replication mechanism in order to efficiently replicate the content store. @@ -121,11 +136,11 @@ The existing endpoints on the master side described in SEARCH-1838 would be slig |indexversion|Returns the version (index version + generation) of the latest replicatable index on the specified master or slave.|NO| |filecontent|The command itself won't change. The difference will be in the additional content store stream handler|YES| |filelist|There will be an additional "content store" section which would list the content store changes that must be synchronized. Specifically, the "deletes" section will be a list of items, while the "upserts" would be a virtual file (something like contentstore://blalbalba) that corresponds on the master side to the optimized stream used for transferring upserts (new adds or updates)   |YES| -|backup| |NO| -|restore| | NO | -|status| | NO| -|restorestatus| |NO| -|deletebackup| |NO| +|backup| |NO*| +|restore| | NO* | +|status| | NO*| +|restorestatus| |NO*| +|deletebackup| |NO*| |fetchindex|We will include also a configurable option where the fetch will include also the content store.  |YES| |enablepoll| |NO| |disablepoll| |NO| @@ -134,7 +149,8 @@ The existing endpoints on the master side described in SEARCH-1838 would be slig |details|We will include some detail about the content store.|NO| |commits| |NO| -Commands related with backup/restore are not part of this ticket. As consequence of that, unless we will do that in a subsequent implementation, the content store backup (and restore) will still be a manual process.  +_* Commands related with backup/restore are not part of this ticket. As consequence of that, unless we will do that in a subsequent implementation, the content store backup (and restore) will still be a manual process._  + #### Slave The slave configuration (from the Alfresco replication perspective) would be exactly the same on slave nodes. @@ -155,7 +171,10 @@ The workflow on the slave node would follow the existing path:  _* the Solr replication handler actually uses 2 numbers for indicating the version: the first is called "indexversion" and it is mainly responsible for triggering the replication process. The second is the Lucene generation, that is: the number of the last active segment in the lucene index. For our purposes, we can ignore the generation and use only the indexversion._   ** _if the master version is lesser than the slave version, then something strange happened between the two indexes: the only thing we can do is to replicate the whole content store (the same thing happens with the Lucene index)_ -### Links - -Spike: https://issues.alfresco.com/jira/browse/SEARCH-1607 -Implementation: https://issues.alfresco.com/jira/browse/SEARCH-1850 +## Consequences +The new replication mechanism will be able to properly synchronize, from master to slave(s), the whole logical "index" belonging to +the SearchServices master node. As explained above, that includes: + +- the Lucene index datafiles +- the configuration files under the "conf" folder +- the ContentStore \ No newline at end of file diff --git a/search-services/alfresco-search/doc/architecture/ContentStore/filesystem.png b/search-services/alfresco-search/doc/architecture/decisions/images/filesystem.png similarity index 100% rename from search-services/alfresco-search/doc/architecture/ContentStore/filesystem.png rename to search-services/alfresco-search/doc/architecture/decisions/images/filesystem.png From d5e645d3090c816987ed0fab09db62d233d05c25 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Wed, 25 Sep 2019 07:30:53 -0700 Subject: [PATCH 3/3] [ SEARCH-1865 ] Some side notes about the backup --- .../decisions/0008-content-store-replication.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/search-services/alfresco-search/doc/architecture/decisions/0008-content-store-replication.md b/search-services/alfresco-search/doc/architecture/decisions/0008-content-store-replication.md index b4ad1c028..f4f5db81b 100644 --- a/search-services/alfresco-search/doc/architecture/decisions/0008-content-store-replication.md +++ b/search-services/alfresco-search/doc/architecture/decisions/0008-content-store-replication.md @@ -149,8 +149,10 @@ The existing endpoints on the master side described in SEARCH-1838 would be slig |details|We will include some detail about the content store.|NO| |commits| |NO| -_* Commands related with backup/restore are not part of this ticket. As consequence of that, unless we will do that in a subsequent implementation, the content store backup (and restore) will still be a manual process._  - +The content store is an Alfresco concept and it is currently manually backed up. +In terms of design we would want it to the backup as well; however, the design described in this document is not related with that set of functionalities; +although the backup management consists of a set of services provided by the ReplicationHandler, we believe it's better to create a dedicated issue that will focus on that complex aspect. + #### Slave The slave configuration (from the Alfresco replication perspective) would be exactly the same on slave nodes.