From 7a2acebc28d960fc9a496c7179f13cf7b86d6cc8 Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Fri, 18 Dec 2020 19:56:04 +0200 Subject: [PATCH] Layout: enforce box limits, reject <0 chartArea (#8193) * Skip chartArea boxes when chartArea <= 0 * Legend: limit to maxWidth/maxHeight * Layout: enforce box limits, reject <0 chartArea * Update legend fixtures --- src/core/core.controller.js | 8 ++++++++ src/core/core.layouts.js | 6 +++--- src/plugins/plugin.legend.js | 16 +++++++++++----- .../title/left-center-center.png | Bin 3467 -> 3451 bytes .../plugin.legend/title/left-end-end.png | Bin 3005 -> 2991 bytes .../title/right-center-center.png | Bin 3369 -> 3337 bytes .../plugin.legend/title/right-end-end.png | Bin 2856 -> 2804 bytes .../plugin.legend/title/right-start-start.png | Bin 3339 -> 3274 bytes 8 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/core/core.controller.js b/src/core/core.controller.js index 8fa07ec85..ee0e9df94 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -510,8 +510,16 @@ class Chart { layouts.update(me, me.width, me.height); + const area = me.chartArea; + const noArea = area.width <= 0 || area.height <= 0; + me._layers = []; each(me.boxes, (box) => { + if (noArea && box.position === 'chartArea') { + // Skip drawing and configuring chartArea boxes when chartArea is zero or negative + return; + } + // configure is called twice, once in core.scale.update and once here. // Here the boxes are fully updated and at their final positions. if (box.configure) { diff --git a/src/core/core.layouts.js b/src/core/core.layouts.js index ce60695c8..1e7005fe2 100644 --- a/src/core/core.layouts.js +++ b/src/core/core.layouts.js @@ -92,7 +92,7 @@ function updateDims(chartArea, params, layout) { // this layout was already counted for, lets first reduce old size chartArea[layout.pos] -= layout.size; } - layout.size = layout.horizontal ? box.height : box.width; + layout.size = layout.horizontal ? Math.min(layout.height, box.height) : Math.min(layout.width, box.width); chartArea[layout.pos] += layout.size; if (box.getPadding) { @@ -103,8 +103,8 @@ function updateDims(chartArea, params, layout) { maxPadding.right = Math.max(maxPadding.right, boxPadding.right); } - const newWidth = params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right'); - const newHeight = params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom'); + const newWidth = Math.max(0, params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right')); + const newHeight = Math.max(0, params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom')); if (newWidth !== chartArea.w || newHeight !== chartArea.h) { chartArea.w = newWidth; diff --git a/src/plugins/plugin.legend.js b/src/plugins/plugin.legend.js index 3fbed828c..467aa1fbe 100644 --- a/src/plugins/plugin.legend.js +++ b/src/plugins/plugin.legend.js @@ -5,7 +5,7 @@ import {drawPoint} from '../helpers/helpers.canvas'; import { callback as call, valueOrDefault, toFont, isObject, toPadding, getRtlAdapter, overrideTextDirection, restoreTextDirection, - INFINITY + clipArea, unclipArea } from '../helpers/index'; import {_toLeftRightCenter, _alignStartEnd} from '../helpers/helpers.extras'; /** @@ -145,8 +145,8 @@ export class Legend extends Element { width = me._fitCols(titleHeight, fontSize, boxWidth, itemHeight) + 10; } - me.width = Math.min(width, options.maxWidth || INFINITY); - me.height = Math.min(height, options.maxHeight || INFINITY); + me.width = Math.min(width, options.maxWidth || me.maxWidth); + me.height = Math.min(height, options.maxHeight || me.maxHeight); } /** @@ -221,8 +221,14 @@ export class Legend extends Element { } draw() { - if (this.options.display) { - this._draw(); + const me = this; + if (me.options.display) { + const ctx = me.ctx; + clipArea(ctx, me); + + me._draw(); + + unclipArea(ctx); } } diff --git a/test/fixtures/plugin.legend/title/left-center-center.png b/test/fixtures/plugin.legend/title/left-center-center.png index 7ffd400944999943943f914c134114498ae3109e..cbcdb6593d35b1f36d6e00aa42bb2a960072a24a 100644 GIT binary patch literal 3451 zc-rk(`!`hm8vo92(>4azEGKW{`DfA~j~9>(80xNNicVeOx|8JLv9R%?348aVukTedmn56_HD zrCfuSD%5rT`Ud|LS!uI%+{{8g_nb|9gr2d=2M5LV)g~54J6g}{syQ6JFcf7?sV%Wu z%5Q(07oPp`J=@l-ey;r0-Ll9v?1>8Mz+CLOEn6I&!b|{guTp8aja9-{0G$PUAjHxD z0~(31K9Ol)9KagNG?3aDatc8~G=NfNP|!4FW(|{p4InhZWNdh9wI+mMniv)YA-wP( zm*ojCPoBoxOn?V1W1SKK#8`uYdkaEEer!?K(>(){E*3(g#2VS7YJ}dpGy5j{o){X^^Tj;_ z;*t8#&hhaNQ8GxD;e696Fvj}(`-h$u?U{xPyp5$Ulg(=F$-zu<1s4l zeACs{ToW@RT$uavAbi*fHlebg7Fp_$xxlx4kB)*i)qTIixqYnW`=PH5s!z`uLCgo) zm#wI9p$d&vD-q3n6zV_Y_XJW5|0~eY8o2v$)NTLAr(Eh{MY2blO&dX1mwr>KW=4)#h^w=6;&^Yh zcdCZfSwNzw-)VBj|M9ux`r6un=<#kH_WZbLSsfdxT+y@;$5UC$oEm(3u6ucD@lfC6 zC_zUD20rxYSev@zPQvDdO2SOBTi8jwb}FCcs6l#oWxXZfl~pRs+wA6)h*{xvR|eA*Z9Lt zX(Mg97J}~X?AYGlApU{eb)l)a^TUb?7dkyH_Q#Zce=XZ^=Hn}8FzTCiVFtx>t54=j zrjHa~x{=`++;T5YVQ{o9H$wa)+^;USx_p1_-nVxHlEI&#Js^22dK(9oHe$pzPMRE9ID5^8vk^*K3WP5NdXH+a7^ySeLc4-rB~apkNTG72 zf|eLdngK@LYbL#ZgZ!iz(>{aK)whN~dZz{KnH_LAorqVJhtyq0Se4sOq)LevA7AfZ z7whNBz51}S(s1=OsbJmhR*ft&Qy){eIKh8+FL0#e_pK4j;uyb*qpDD8@UbfT0o;+d z`2FjlX<@ThU?8QZ^5k`#dlYLZH%;(y;AMdpJD5aSv|3ejHEM|Js5j^fUS8Xj;hd)R zjZ|<%y=_a*PlTn#?}z5c-<$q((%ZUt^Jfgqq!ATN_C4=)-)AxEcjC!gPU{6)*B#F?2H}Hh` zlNPi~kp^}R4Y!l;?*N4E_OwZzzZ(gVg8L;<f_O~;99%_oY@+>wF>slu~i|Dl8dGuSSlsdhNic8`26&}QLY1kGEH{POmW zP^DmU@&qntDdy(p#W{8hFw zwQP+vH8n#=?`3ZKo`Ay%{K2Rc*?5^r`hg4kRc}rLd9*c0Id!F*S^TVy0ELb8(?=l_ z3ijfK(`pTk%ua2&7f(ReUAgZYhy*q0$gyJ?`T1I~XXc$l^8bL0VdiA7)#tIXt5cnf zwzjqh2O2L-Ed*NI*t~ANC!Om+PD-KOkYxznKt>6qKq9TRTTvA~al<{wR9|$Q*WT{& zvzN`{kLPqMz;BS^YT!hqO>iRD&A#^LGzLk@%;N2(pdJS-gI!?hl literal 3467 zc-rk(YdBSD8-CZa(sFE>$RV^b|~~c4ichWnj8|JsDx~?lO{RDAU5Xhy5`6H`+k4l)sJ

ss&g-p~8K_x;?@yHZ%5 zE=uxR@&EuOH&=!?00{W<;Ii-)z`eW+e)o1`IBequeasI|J~6wb_9f5DYW!JSw)57@ zZp@SmDVFBR-po`B-@c;{6qzPMW3EYWlb|bEA?YrQ!8C6?p=BL;p)M&s_j`JG(}l>~ z*5UWBbFJnYZ%qa@TiyTbO7pei$$f*RFQ;Q(j@_6X9PM25PzfbC?&lwWlqf1AIF7RA zXg%2g zfLT~tT4osb<>uxF^w)7^_d2olaS6AVMx`X5txXh7VMZRntH9Q+!vFT}7OzU};hBrW zkF2QCgnlowCk*2*7L`SaLwUR%5Fx{k+1%lNUHS3M-0&MGuwor%YLI>o>=#$BoE&!DqK3zQ7_{a94xMT^T+W_{+}N{xED;M#ilNsJ2E&K zXGC4Npm%t7I@-HPDBSdAu-S;K;-`Csr-)13XjuwHrKQo5_pL?s0aveHt^dP*8eQZ# z^?I^q)-G0RT;!RbVdi_SuFx&Bu&Bu8&c05g)=QfeO1U`(&1~KZT;c!`mfusbn1~qX z&d)dISlv7_ImA$nj*hmB=(a77ovjG(x~qanZkX6Q>&a!Sh*H(eB)v8KdiP|G!Ya+R z`#Qe$y&kj)Bn50f){sDHB8e|&1om;BL5{yv&(3o7v(|sY6Kg550OOW(tb@?-*A?5% z11r7_u8uj?(ea(8hDJJE`;#kvw|KJY?;elrNYaM~_VCAvcg=z)on;Zi^77Aov5dy> z%%P#KQ$s`h*B>0rZp>T1b%Tw~&Ua1uTuGe@#=3kaG}~5AVnlI94@E`Qoz$@jZ7$d- zj*}@FKiI<)FJc|Vlyz;hM_%2JyMM*M%u`ECiy#Y@)`X~~lKauR46O*6U2a(&o1myt z^UQBKu(hFD)Z(F9%5l-^U}rwrh7n}j=zp}an}!s)`PMxeXKV%tLub)b2bw>M)BLNq z{kNb!*a$yaYS6j1?YDUs#+*$>2hSyA?8irY2TelLNiD=<@u`uWy%Sz4a>3#VT;v!& zPTztxsE{>`H94OS*h_yNHK0z5ra}l~7huJZ@Qd12Xe+81htq(*Yr+x_6=Poz%#d8K zGm>s)TuQ~!cj?PYDS(&e0%oJ_7yDIbZ*gFFd`8%`5kAQod z|K?O&Sc|LLn&rpqPK#%CMNiMIdpkAScQfWQ*RSfQ(kp?LOOS0yUgZ)#S&k+j{uDf? z&zhp&7)cOu6a>sRu~;CTY&c`~S(9u`dFJ2$*m&+Pih}H@GD-ZB4YgYxX%%wn$T)AWiHubKR~hk;K}c%r9;z7U(IfC zqV0l0=#Lsu`gc&eGsu(IjyyUp8*d6>KoRPTWLG-E*ta;fH9o{MqnpM;;<*@mVq4FM z&3x}f&x3?z!~tD$fqzY)ywmvrB->W)Zq!g19fS@lA*#EwGz(Gm%UrV^ONYEw(QBB6 zg#|5ZRq)vtFMQq)47gfKG|4SKIqOaJdYE9{{;u@v!S@?3IPoRY&to_DJ~zc!^)EPr zhXluvnj98Ck<@1jtE+?VM2OAR%>zh~K$SR@pKfQqQ%doiEAFL~yhu3WkDo>F!sX&Vp& zsep~=27RydTB-2P9Uor0TI5w_Oh@kYjDnpTp1u9}~HFI{szXsBu@Z zNJ?0oG%P%xVgPF*X``A3;?ebHwC(`mYCzF92o-RW%m*mTh3SB|!zMo%x~Yg@EvG=+ zDQ^Nj2wS_2UyBLW2Ag|yp=u%p8@kBTCrTcPMsZTdWPu(V-Wp0W)$$#`!hD7K|AZN_ ZM|bQuzxv>)Km5r8Zks$A*BseL{{~_FMlS#W diff --git a/test/fixtures/plugin.legend/title/left-end-end.png b/test/fixtures/plugin.legend/title/left-end-end.png index a60610ab5009b914322f7745dbb64813861715e3..85c33c674ac20545afad44d57fca101e94432fec 100644 GIT binary patch literal 2991 zc-rk&`#+Rv8-M2UXr3W?W++QJjBR8SHd-1Ck8vnx$yp9<%9+CJ(8xSP%iAi+YsqQG zw#ep?M18QC=|GCGyi{VdpHgTHk@J{&ANvoy|3E+7pZoK@uJ3)__w~KLKirqxU5_Zp zsmTEVpx|)S)&l?tz}AAd;oFJ$nlk_(pX6X`?U@oZJI)CA3Q+6%ymO%V$3K!N2cBGI zk|8TIedRkQ8D1sGPCIjQ=B{*QHIIl>-|A92nK3SLzt_P2`)_EQjOHHib-s3T?qHF# z{R_*zEM80BhJ5!@yans_iqzsGZ?Uz{eIXM7Pm;F(R6aHVYvsWx34xt40L+d{gkY5T z6?_F>!B_APXi^afg~I64g9-`?r~4~jtf`xuaD+W>z#aL>^(2z=cUXJ!+=yrH9{R#@ zvz$OnsiTO{9Ps^-{!)|-u1Ypp>tCjikKT(3a7hpaZH)bv*=ZmRgrK}+>-vU3&<>th zU-~pX*;6$A_v38oVkui>y7{O_MJ@vv)xY*zk&_mS;OyqsufaIqtYg7o1iqc+u~qo% z8;^R}I#}}DUsX5Vcq32gXD3kq`?2F=4=xE+3jz%F`pePfNli^n-h<@1pcm)T(*Ef9 z+|TFuFjvPXhnFnV#n&57wB~nQ*eLX_^Sx#gJ9fQ~XT=+72nRx|N%e$~v z>qFQjv7cL#-mI=3{7GJAaARd|==m>tL-?bI%FUAp@0@xHSB#1L*NhODis6y!m$!po zDpGIpW~h%Pn;S#_+2;m_s5-t!CMh^!=Ch>8FnA^#S!AbMly!5hTbG&^#z>*TlF1bK zEUr}IyRIwibj+*PyXweQjVk?sdzItu$?e2EmQDR_uPwO-ezlqY{O;-WaIH_o%Z5Pd ziY3-*z?O(p&5}hYM%$C){O_J|X=6*%&C%)kc@L+;VdQ zIB$uKnMYpGr)U9S_?@5~<>nlrY@Rv#$)+L{gxurLkK_s{Bt$?Vw3&f4B`qv}=x!2J zcoYK);elbYZZSY8DC4$#+h_|yjkZ`rF8U0DE8c&pQ|Hhq;o2C#vOv=IWHIqyOYG_b z$q&-doESY(y&%x;odta>Z{^`Q%%h}BxE{A8;x!w9_TngaQ-@MwA z=(dr+%L;U!ED+4fIRoP=eX5Jv1GT`<;_nA;=P98F zZ)IeZe=FvpY0RkS_ab5H8MSt4`R|tZF&0pt_|%$+ZJAj}$8uB*tDil4rn9Js_S&NpAEA;l;DZ&>UAUX` zVXyni`Tba_3@D}HJ;i?*S!@t+WxDCEQJ*qULvZRxh7;q6TRW&E@Hp3=J`I(?f~OoO zx7X|BRasmiK#>4#D*y=F!yCJp6(j-}&V0tV4#B^(0&H8<0jLC*LZ?8y`~Q$u6{B^n V4Pq6aQ}B;C;9%!!+rSLT_#e#;I!yoo literal 3005 zc-rk&dpMM7AAaUF@s7U9J2_Rz#HN@s+OMTy)JquTv>MSmq(#H$bBGF&nF;x1lN{Ss zOl5{vl8C~X(O!sgTG`53a?Ck$SYqFH|M>pf>)QYO4-~$v*?Y=2$B;6K1%_RIib*lmCvoIVz8Jb?%MTBZL~K z0ecwkS18uM?DP|&Xl_J`QSy)_-Y+dCDI|P zlJ97p{+IlPB2NCKWJ$O&+PN_~(RH*z4uWHM>nU6aiP7Ys8elg{*26)tYW1%qGEn;h zzJM>_3-}X^T?1!WESAjn(Y7{+AQxgv>cq4Xw=eA{P~k+cY>q*THU+OPPNjUfb2PsC z*s610t0*}VL@2z{&B#ED@UtH$UN5};CBD>0l9AHhBV2sOkP#VvV)+t0{SrsJK9Jie zI5*+NZ;aXN^j;BrgB?BJ`blsq{C86m1l`FmO&oz2EWpc`FH7R()O8zd?d>zeR!945 zsq4bog&D#?bC$vQ+`IbWkCWZy)WVY`XQunif?U3Frc#FOcn18P>gqYd&{4aF$f&5Q zs<~DXSJ`yAbG&xAPsGmAb+1UPj#^2{*zcP0s_0ZsOSW;=i6ReoH|HRiVGrw7|0FcX z+PzBl(X7G6-VJ+OTYl(h3%@+5Uob4m%zNVhTHsn9$k${fA!z9BQpXrPOy(b4`s(fC zRQF3sCRGxT)Y{J_pPuOxj{ka(fp7EF-v65_4!XIAGdQ=NXP?s;kIb{Hjc<(+3r61i z@Ouagf{tTz$iPrT>Uh@^|KU(TIq|?!ZYSL`OFzKcC~W$i9C=BryZZXN-MSD$*%tn;VK#zngG8DoE$zrTwk{$~NTt%K1Z9+ZWi?vZBd>k9!}&+SMcO%PX3E=Gw}9 zJg7jjjLXbSerk1S{CQ6^uyGUJ?|l? z7No7;=yYM*YZsC^O^(I4?GQ4EU!6AlHXuX~Zwm7c)tx#UUX+lKkTRGczo-5F@x1oB zYbt8vEInaJq1rCQ6e#PuS$cVS4HK)AYi4JIyF_eu#2QMKx{!OnjD|qF@D9n8B$?&+ zzZEP@c9tBZ(M~?!S1rc@((M%IF4AYcXSO_`J0q~?>5Z$JQp!sJ=4le2G;_DYyEr+Q z%x^{lsi{m#>n#+=$EBQIv zcaRhQQ7NTDACJ7a0&w2)ao5OgbR6WH{Y;Vcw+vSYn*G{y{+SDjYXLJ!oO_VL);M#- zHyc&M9nuM&U%>?K*3Yku-sbzZo;xc4@$3M1QIgKG!`fgN!SsY)RK=CO-hqRHnFFsH zS#K8!v0KHdd+gggI+$H0EPKOCzn`<}KgwA=<|{Krf_HNwm!|pWCtjs9@H*?phKAN) z>U?YCb_7!f_lo>CI1kq)Z8Mvvt?$G&7ZQ}-zF#1!)TC}*(wOoLOIZ~0=JAKkv3KNrSGT2WyF*dc( z)FLG*Sases@nu_@PO!4$QX)YO!lWe_A7oS`^B%q=c1K1ip# z`K)s}VSIQ9VtSGCM@^NWXL5%Klv9X|lW4yLOb%tfGJIZtx$S-vqDOGIcU0ycx@CIu3GSD1chx?vI8R=F`Lk#h_>|nM_utvD4^B* z1=%9`njEdgdFR*p=dnpyE_mu*J@MDzR%So`q&X{vc?5Ps@Io5EEgW?5+T{=jaLhYH e^nc2T+2BB$iEfm`^Fi!e4y?@W%pRJ0Uj74xz&f=6 diff --git a/test/fixtures/plugin.legend/title/right-center-center.png b/test/fixtures/plugin.legend/title/right-center-center.png index 9900784a4b3cfbc976d0f5b5ca5d88a835848378..794aea86cdfd9941eef8584df3207a1281b00c26 100644 GIT binary patch literal 3337 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 diff --git a/test/fixtures/plugin.legend/title/right-end-end.png b/test/fixtures/plugin.legend/title/right-end-end.png index ec2acbf131253de7d8b46207d4d24f7d509239b4..97a0c8489c8d70d744b5fe6c0956dfc7e40e3c86 100644 GIT binary patch literal 2804 zc-rljX;4#H7RT>s!&AUqg0K^BE+W@HKIIK&nKSsG+9FU}}N zx^cQ$f}=>3LBR!Z8W)6+MD@1>$tBP2lJ~rC5aAJw{0*I78ssh)pJnM8u}~V-KYE*eoeZS~qXbGtw_>1a zEH@88uL0bIptOfsFAZqm8;n*AAcW6wf{|zq6fvaXvS}|L9K-=`G>lLq8ply8u1BNp z!@=oxV^avOfsoVMR4h?>%>o1VIJOgl(H*Q51SPb-Hu>7*Ym@)WCVE?UI+N>Zvjy({ zDzz6~qCxP2JKm9pUDCGx7VmqIApKe2)TuVQHtI&FTYfk=9+h)g?!xs0EYT^O&8}J7 z!tcjb&gkncXWT2PPZLkh%H7TJjv!yc-mn5moSTqLFDYk|)T(8*@|oLwzN)WFWQ0Jq zC!xGO{~~5*XFm)#=N!}O>gt+%p;9_1ZizUViymm9}+S6J0iEU8nfu_MK)HG(rQL* z=M|ezN7F#!cfszJD-2=n6xPTL42WwPaYLp zXndUD$StQ5pFj4sxAPg3^;Ah%DnCX(C>(oP=7Wf*RHjiY30Nve-E|{qF7lj`H8;RZ zY#gx=vtfTTJl`^?=$N!hBGUNt-9ug{r)2KEwMRpG>yj-Y+eg`}jDrMg2(HGew&tAG z?YYK`wmeg3mHZ?S267f>k1~_r?duh0rv2sK_kXI(oR4Q_%(9uMmK>qS3<~Z|j&(}$ z_DParq-EExT?h0xxh(YU2JbiNe@M+Rs`-VOo0Lx8E-NcLBCU!%GS*gzh{r#hMz}!L zn&(OZct%21m)-l8gkuQ-Sac%dLUDAwzheWpm87aQY!n!*H-X^wCgJ=av6Za1R!KNY zAz`89-SPJpC=gVjFk)he7KxwMlb$UW;&d1hFPt}#1#O+;A82E7rvG65xl|oXA7jmk z>ZFD|H2N+(o3)+G@}o;i?X#AJ1qYUuA9KN*;7f<&c5#^y#X(8)r>X-va651!FQ&198?nO824@IV^YKixs9 zRW?Sf$Q8SxoxWDkHK&t9%xhEeGyhxdWITPn*kk1>4_kSP-+=p8{N$kekRXAj?;`RS zX`oT}$8*iai+l}3;#$V%0MyzS2NVs`Pf83365qD&?$F*}V}qF4iz$(n^`NPJUG{#& z$pX)u|5TVd*&~soq08ARDFtAi9W+$1Pp})V7}R{Is&um*J>HaWY?H}Coap#@{DG$Y z*s4Zm0cNQw`@6e`)cS{^l`<2j)bCzgn(RcUobkpq8RaVCG~+3dRqn z*Ag}$UR`L}^1}rzwp3>y82ILvr+<)Oj-j=<=Ub#^_V5YbfW?1DhRu7^UzU;*P`UJ| zwjdjQ1cq?&#fx-@gh6Wwr#hnUKx=Dj+tgHz546$2VO6&+2?v&1zInq2x}@)P!t0u= zk4B_xii?YB`1Lz46t;OJn8A@sEA8h(t0|Kh5fazmV-l>PT^j{N^Dm#Oi?^Xj6 z@P3%xf88WF7bQcw%lb0XU5_Lsy^@22ww^hQ$!N+54@+KCLCshzdrx^LdJ_m=(dq9P zG_iyIJ&0Ux5mKh>E+|17Odgg9ncpMSaWCQvG;2PZf;f>pIYm^l(OGj02vMdfSD&;5 zeZJL3Scpb7=sjj?mxQ>#&>enz#;&PH+l8kgZ#~cyG literal 2856 zc-rk&`BxKJ8huq1P=K_Fs1Y3&#SXHgj0l3HWRbB!$f0RmpaV04AdBe+Srjl85OEp6 zQA}i&)?tW(3Zg`aK$J#Bkj2QZ0kmn>kPu{(K&JG}UopoY-g(=-?|k3=?)lEUK=*Rj z*4(HG0MOq5H&-73An;|NYQz)}%{vBwrgXpSUf%?U_s*10*5Q`gt6-RN`tsL{4Hjm}XAn74W85!0JnZ2Ru{PoDVKa7%4< z@Xvw!u3TNB%_PCmwJm?NC>K`>XJT7ha%?;<8X%?4V4>Prm zl0dB#;u#Q;MYZ0!b7#zG`)~TGw{PDTi&m<=r}OGr$xD1h_IY+fKH70h95*-h-rw&& zW4XWbLRif+Bf34iqM{R%k08q6S_Ihi<7V5QLGr|H)t$N53Z%f zMAu!j(AIpDQop-f@K+(qZ7Z~3il3M?b1cjvy2?y;F~#QT zs|~2Q?97Egdv+R0SQXX(>Jr83bUNv^cg)Ljf*_X-xxl=n6%NHKXfx9O7b#1zP!W%A zpD&5GBexz*Lhew@NwD3oA6%vg}Yr3b<2P*Vw2d zJB%-Ag3F#bxKd)3=m^2*?*o87bQkvHl8Q$m$Q@%0bY{JT$zfRldibJ?L*^9%$d|T7 z%e80^jI`_f`|m3{4I}jB^X4S>97@6xBcpWLMq-p#41ZO>aiXfiwy zv+HxE&RI?iW9J{nW}ERe{cDogG~s}U$?F@I3dODLH;ToN>7d5iHli#?SO(68GlETq zMN$VEOMY-~(ECMuE7N&3Z<nN{bE`^1K@DW5A*1PH3{l* zNYPlZvxboF|24sv)WM5b?+n)|A3$d*m?9EJF7IKDH4tu2fPQZyT4e8xw->FPsWO*n zfgf8yED3#vr>Cdu<|pc;cGvYTn_mA4QDh*;?rSc)Xz>2rAwJJ&!be(w{Ag(UP$gWEVWAj zV%N2Vk5h@lk3etV(@P_+;j2~1SgC5|bj?@Iz8ty~MZpXtGOt`>MBh%BD#4C(4(mtI zqNrz8Sy&^n_%L*6BOIk;h*xR!JHhLS#l`fa$I*ueaL`AMTta<42kW)ZVN+Tq&-;iU OFxclS%^G+_sxV2C! zX^PUxttn+r!YH|%gyI~en1~X&B$skKukZQc`~4%@Ywfl7TF^J#0p<9i8b{Ky>J4loS?ZcILdwDP@W*c_ z?@iG{8Jg{_oEBbq8qXzbn7v*L*9Kr$^PkKHgM7hXQQ zc}G>|3+D8pXZ`n`_9hfadhBHUrnPx<^JPIjDRvQ4HBu?3G0R-v zqlm4_%CSw@amDJUS;Kep3zNOx*4k11`equ?-OvwB;bYP*r9K;6QoqH>t*D(GYL~|% z9bY&TXZCR{V9t%8FT8ni+N5=7p;}$MgD{ZafMVm#Ae?k}t&F5ieeP15_|W{p z5@YArRg*rtVP!BEWzyiEmJz{EtkehkE!P3mvYOJ5QrwC`l`NGTR!HWj5Kt^do(AB4 z1tREgO3Bo35#es;tK}F%ZwMB?=@f+^8&^@lMuYbN%`j$w3_9H-g;571jJjB|#G7L0 z=zJdDK^K9k~%+Qw=1&xfgF5%zf{%7MA0^OXx+|7lkzSQsn1S8G6ELunCc zsm>h2NH32I?UFBrg@$?y>BqQ>iRYSmQPYONLRZ=Rc;;$iQX@q0qWY?$!exPHS@F61taZ6UTRua0W%Yc4pk#t2ym-2?jh!m`ZQ+K z)^}G%Y4ub_3FzFB-506!uwiw`tmvV|i*@ibISJ0%q3Sb)aXidABy6->TcBo|^6uRM zn9)gUb1~-k%1Ha_QcnytUiy@tIPl_%+Wh?dU!b7bB+DZ=Z{NRAI?B00Zyx<->{Au3 zz5N0;VPxd1Kn9k!m%*y7?zsKq(2(Hz_3P>y8VM!7RUWKGd2CReIk=Cct_23|Ku=~& z+ujK;`@EpRm6ar;D93jX{M+xaOnpQL9RfP<#ev%=DCF1MaYo+1>5PTO`k!C?lrCsB zvD0Ge`sM_lU7CFi?L$p%CK7BPbRxrJ2AqoMf5{-;&ajhF1d7Hs66F2f>uH zYwyNq6U6I+n_3V2indWDd-(pc17qm>rCn%_lK)oW5q@upLU#AWwLs5e?{5i-?cjK~ z9l0``-@8Z_7YsF@J@p9G&uBqza|?O=%XsBo=F@Cp+OiHrGCMumH{Mq#Iyv~NLww@U z;imOicA1X<^DPnsptC7beYCqma57W+^|a*EUj_0QIZWNZo{igHsq&A$xU9NN?dPOi zr_|b;+b^P6VVRELzX#c-@GUjMAJlLqFM(wSg`)wCJ&Tj9gSy8Qg|XW8np&!N<*|#V zzK$#wi^?uFYRa+G`p|S$A85X1XFo=kZu91}uH^pFX1yr8sP7w!eJV7cUog=J&K>+h zk^8@PIqAauYyrrka{~+amtVkneN<#~YAx)oD$dv@az&04rFSHj!Vo4xtY=_c_=p*D z0b}gK^|R|swi;g%r(H2#qD=I2#(m2B)=mX1q@nH5&#C>rEPN>Dmq~3t>)OGo;m#9%waI&{qN7f)Vu1g} z!F$;GO)9_4ImL{7VS3a0f}Df6n1m%ICEq)*fvn!EPY0<;;tC9Zyqbn|!-Atw=s;sa zYd)*)?;@{5T@QbqLpdUcV>euvh_^dRUa8W4j%9BIvA(#=H zs|ewekQ_+-ieW|!a4tAwwUojDHZJFN@R%qdrC1Psl{~#nhNCvhnj*Fr9;eQmc&B4{a J_&=O8{{RWIuVw%M literal 3339 zc-rk(=U0Tiv`t<<=6)q`E+N9y>uvzSGLK0SNKzwU54cP z@Wm-brvsFZ7%&Q1N#qwfW42g$GqhXYn5aefXtoCBe~3Pint!KFT952F+$QA3%ID%- zA8(q{^pdd35S1$f^bmiqqFsW1m6|sLi46Y!u`yW;2GfYl*gD5Xqfqcu8bh~V)CY!q z`&6PIb+B)<%9AnADOq+v(GHu!zY~_mYBXp2D18|4=E}u5>^;PUpleEe7}(C%zod1%628ros(xFoDK!iLPO#!xasoT=Z{eq<2 zSa!|AXReas<-_fd6rgol{NBt(EnU!rduP(4QDCI#BMyA7<>h$7H%VN1BvtjTR#cX} z#DfnG)^TqnitVmWme~%K-jJ5ny_@kV8MiOR^uY{tNTR*v!S2dO z#kyHv0sQW+pWS={c0w&H(~OCU@$~jS*A&Th!Elwqd#7wy+$QA3qrl*2g>9Z!w*Q(E zYiTmj9-(Brm-zP15Z#{Q-sssHKU{eWjnKO2DV*C2OEX7qegW)_nSX6}wl1h*WG&@A za+`$ZFL(chor@dDdV*C2K2E{fkrIbfrOa80e1;mYOF(r`-gnBxi|%H=?wfbFVo7zN znNLSvbop#Q4Iuhy8gu4MR}#?r-^kBWct^Z0GSHo}HCPTBAPFF(`GfVU8k5dMk~a5f zH8H%ElPC2Vb0!gPb%Yt^OP8goUq81jR7rOnP3b z5#s_weaW5>i_6(vXRl8?)d&0E{Zd=;bD%(v|A_as<>~s$c!OmFvWSCt=~#9F z$T|ECitu;^{-TN6X5V{ znp0f|FGc7o9K{FA(-nVBF*OayKJwO4bHPzR!W~tFGmwX51Vn+1P=bTl{A)PO{#SdS zV$ETmc}u=M(oh`>f?b|(&M4Y0(U}i-A?mWV5WS^<6gJ4uEy5DtkQ<@&;-?Wib+ z=x!B0J-@#;!7pcVszr3<6x7eI89^ib*w8hKexRamz=WKVlF~XHU;W5^;@!z6#?Ey8 z4!K#WXA;M>g&V|Dv#rR6;<>Xl5;)zK4D!gJd^R -- 2.47.2