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 zcmeHK`#V(q7XR+urfm!}Lf&%Q2&F=C9=D94kV{5LDKbS#r3Td*jo1^RW zMRj@;%4MQ53NfYhxaU#{xoa5a?4I+>d;WxTp7t+$J$tXU_FC(+*5|wSMRzwxInrtp z06@-Z`!){%AVP!yDoxyc!wL=)&+VMH*?O_}kKXoANaCo}e_;0<{=zHVl=O#tTKbBc zdauec=XL99eUoIRP1f?#a|OIutLQKtL#0o43hOG2&5pJ-UeH#tI~vz_+R~^h-(oSl z`TecX%+DV=)+RMG#c%EvhOg#~meP7=B1fz_;xkFC7=U!HCHJL)(rX^+5D#GHa;!HKz$`V|-K_w6u#C!b1(3P?omMRzv_ro>_dixlx*w<` zu87Iv!or>3E#5>G%5gJg3jAGBY^eOJ92~80YzVU_2b?Ag5?5}VcU%fM7d>#BEzKuw zrKivh;UBZ3H_38xPM)5g!eEgPN7VLgPmiRHjna)G4Qw$LsI&UqzOk;S`udD)aYv7M zu;!~{bo3*P3KC_w6IwZjcz1Vq--|>Q{jRy$Sv|&rBkcu6Vm-egS%W`&W*f0Mf7&CT z$Fm>)_U-i>y>}c9&39W!$S0kgs7)EpyuN(K9lf+`&b)z7ni1UPTH@h_z9>zbsC3VK zw}y=My90%JPQtFPjUA6e(t_XqabfSUb-jwLx-ByjB~tA3!&{^81}#cVf|>TxWnrl&cz`J;l7Dbchy5BB#AG_f}@LRo#voi)T>tW_) z3mTHEL}yn?L{py!be{`4{EhVgE70Idr2Wb1BHt&coT?*5+NGtX!k!+ZxA~0gK7Spa zAY;|)xjJ=7m;#;Mv?LaVM=Z>in3|bM#yKG1oTT}-m9VW%w?0`tEz2ax+0ik6q_e^^ zSgS{QN^4l-z0YFXmlhWebv-#P zY-z#4rw%R4&8~#eKtoI!G?nKPa*~+)vgcVUunxfr?;(N}3S{}4TpZ$Y3xWfD15L@0 zHH^|zbTcq!GJuU$R>=|A1Gpu?Nf*u3!9kh09r@*h- zHqdjHl68zHNfc=6XdWmIcqMB4vgLmsMYNy%* zImNcXSM`hIA6}#Y54bc#=t`=>2A!j%so}ZP*Q~f3;DkkgB+lP+NORd>_2w<~D+ES#_F47n4V|?v z>EkntFKeV9QB|$ol(?pFW8L{#{9k;-1_9x72RTU5aqi>(y%j!gmw81d8U$=0j@;UQwnBw83BbaD0!5Qns9; zA;uG?fI<7}F^}J1A1UUfSMOxSoj#D-YKFLH`W;Rs5nbgbb&nZR?y?gtUqO$KuJNso z^l|20eN zmte+*i;DVrg@rPZQpnvbeMN3DEbxlFB^hThqzom}y+WSL;Na`)n@B!j0igEglrgQpD+$q@2l;ULN_=#Xw=n$E(E)~(186g%Dj!!AXydiF zNteNKBcra}3<9XeY?9c-70sEK$~_br)Ng5*2Pm?LPAQ^%vtng z4Qm5+b@kw(`{^6!VhDFaUoa#^HC$qme-Ole)sq`T9cs){OkVC{5tOXI^N1` zYHE6Tpe}BF-rv&7>TTnF>6>=cge3Y6S>}KXNXv&QWbzuDW#wl^Z@6Y{))gJ+H#fWe zoMn^f<5{f~9?NTx&SGeX=1!6s!_l^;3c`RsECMBzQkh%97_F} zwUm3gCs(A!RCC#`qUeYv0TRc+7|twz(SM~MBLEFO<*Y)*aZ3ovNlrgceL(C|?G2aQ zv~t`4RG`DdkP%{GJM%Et6D=TCw&CsTP{@ja`F8OaC3u(+EImked}29c>aVxF@XO7w f+Wdd^O)o<;_k>}n)D8pUrwTaPyKTE?$2|XU>!?hl literal 3467 zcmeHKYdBSD8-CZa(sFE>D1(!FUeS>8$r(<4@U7s8r?Oc0b2_-nL=N^8PC@Ld3jU*s=Vg#@TNIgbSeIpv$C{AfpR0xWT4ov-`j9?;VQnVVudgw8Ze1NhSex2@rESd2E zn1!XKWrjgtUS3{6e*;%`uLD~TmvDP&R7&!h`b5zbX6Oby3vFB~{cr7l;#s9NJab|A zffY5H(CVsql@gP zUQgD|+Qv$aiaiQ4Ont956uD#;6&E|*-q&gP?4r9u88=tImCaj;OY9)Rin|IH6A|Ow z`T6Ets~blqhZw5S(b1L>-8L1mvz6gpcT^C`bz>VxUAY_;QL37$q_>XW=$gz?FxObO zuj5?~I=d&4I@v7RCeF>VECO%NLXx^lZ& zVCA>LH8H0;I=<6TS5Jp)e{|XJCQml~-NTU`NqR70_kWyt*D83_Sso#*sQAnm%cu{} z92)96H8iw;!@Ruyj}P_^8i%Hnnuy!tQzJWjCp=Z;g2fTI$Uc0W zz7=ayA?p}xb3Yx}Ed6;@pE@m?3L%V~fE7c+FK$<%t*mAoP6K+*2}|5mjC?^bLvpRb zQ0mRNn2MvxE7dzv1OV-E9-S&bt!$;=V-I?*77TS)oA&M=<@ndeR)=@r%^kz6{7vQk zb>V1OYhhNB!cyjx^d2pt`p9I{nN|K7i!^)pk*2>h1%3oamx5#)@Y9dUxCk~KITQ06 zi@ue|;SfmZ_3dqI97IVV=q~S6zMhtcT2LuF{#IF;0g~it*snq51`3}j;&%v9hJmYO zw6FeC|KnwQ!o%Hczf(j)OWjYeae_a0bao2M%YAKQrf9?6)tR5i-sywL-cvlo;a(mU2(kOw0KrW^!V)hw^O5iH)1|>{i=T|yBt`x1lfklK_IaT&B_AO3%$A@@ibkkT!JQrh6Z0i}Z zp6{LLxtFk#7F^qO-hnTXejdBA_qhqiYJ9;F z+$T5&)a0=Ek)$zGSW^>pJ3?%>)GUAmNq#$JOA;wlS>6*QR?jxC>iTOtyQK|p0x$=#UGUKc$IOjfO0byq1TlC%kk zfmFe~)n_l)wmWBn?!iPQqV2l{FQi<%>>G*6qC|D3!Ak7vpiRRHENnkYbWV&n+3>A4%2$qYfQ%o!VX6-@ofs z>Gux2S@Xcaz&-uG3GTZ114r891s2l=RHJwN!i5Vn1xP^ELHCPpxfwC**uK8m(9Lk- z+sy+D(Y@Hy0B~W!xe1Ym>NKRT_xe$6dS)h*ue2HDuMRoZ_WU^vP4F?6i>KpXc8wZ! zm58K-#Yuyr<0<;k6G@xY)DgF?H=_*)2xonYzEP-vlVkxvSx!tlyd5@ZgP~iB3Dyb< zw4L%I(1Wlov-W#pjJ3hWEV@WFk%G;b$ipW}9*IVAQrmceE*rLBrI~64_FrMX=H~xX bHzS+T9sA9$+&k(IFIm84iwEPXJ^Se2Vf;of 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 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 T69(qw7YER-94#v>ykh?bPmSyO literal 3369 zcmeHKYdBPE8-CZaj5UsH8bu{7!j>GSkWqaaj53n*q3zVPOQM5A2}#z798w`4_U>S4 zY-+bnlRo1Vvvp9h30o10atdYYvon>(UhRM1zwhVwU03VRdarA}*YiBE!K zZL6B{GGzdO8poOK1pq`YA%IfIS5QpFUI0|39Jakre8`(iJ2TECXtxxL`c=)gp9!~0 z`$>?`wDP>K=;^|tjYR}8itJaHX*!u34tzYnJh}wa%5r{~R_l3kueoL|=4Gk6zrSp7 z@8{dLKdorf8B3Z=IMFnII3hxPxczhD<&HVql{1NBZ8JVp8^_B9Rb8pz@l6M#8fYSqDO!t2xS@( zKquXO3S)sbfauU!;Ow39SQH0)0eqH#0r$47+rkU$vG{Ag4J)OV(!up2-&iQ7Ma&pp=M%K0AZY`wQP$Et4OrBkEzsS_< z7e{umJ-xkGRqg#fueH#k_1VAn)4(bU)QY^vBzcD0M&1tA_ZhNl(zcz7oqF={-f1lw zF)F>P1}C6+&`eYEf?a*8_OZ{$Z9Qd6j}5CZj4MRH^#Zy9hc!fJw09h z{cFyD=Ux!r{c|)WXL9JV|1u;6G+Tdu)pBlhw6(CSw^!CP4z|=U+&{CttFu!tU42E~ zRqt|_z`zR!2J3v)b(jR`(x%su!7*0+J8^aOqXM(QJuPQf?6iY+$YY20%_*(7hZE=C z{?2&w{C1$gWUFCxsQkt|15{uSAVKb`U{XDx6KWId zk1b0lP?)RyUrPkx4>x5z5awDfh%@FbZ$0U>OZ9nu$N|OksQk78s_UX$DgDlyI2v{H z&O<1Es<)zZ9q%TXG}T(IA8FSlqY>};#unyqDCA1Z6}pMkZh1Ab6V3otfj#vhP1}Uf z(0`vUQctGmX6mPaY(+=ga8j6tFJyN;$TP>KcaTyomduTJ!6wqBH(=9%pD@I1>Zx#{ z^h5l%>-HwchIw^yVaWqD>UnJucx_7;vY`P+wJ8 zpOIjfW7pPmx}h&jG>>Y&otkn4X=l`w+|tMx@$W}C)u*F+edF6N+I9^LTnwc*{#ay5 z_}tI8%hJbggC(Xr@VS{6g<2LN&Php0A9{X3`4!Q_HCJgFA;8SctgENTkR(v9zcA$C zbYB&X72)l&IqmB&Zgv_GHv4_5RXC@WOI?+uJ~Y|$ON>mq>-&ayk?GFHAiv6>OmO0? zbw`Xdw*r`o7X~%pG$CCj5;+wp^DDi4`SNsAp?UD5L{LC4TTe$G!8hbuyy4xC=GW$A z=9XmSqp96fht1Y~;%rk-kW;y?Tt&{4%LK=GV*y4aNn=8=^6D5y@MvYXaK$=Z@@ z25S$Guko2y@{rC($tI}mg>lI)8-A3^azeF9kC+%gPf;chn;OJ8{w}j26n=>E#bW>V z;>{LiUYvlyK+Ca<&<@>yL{zcxrBG09jFa7odE?I?-kk3)cW=EJ+KLfr)GL&3B#$N` zXC68)d*>AxxQ2v6fn``b4!W;wjb4HptRmiDAcnWwS1XDc0e@f$JOjlW`#SY&<7RZj zz*<+_`r0DrEr1k_g4f;Ut!+PAj>_J>y1Dp#4 z^e)zhG#P$6i(nd!>zI?#THr8kTh!wKY>n?N6p$1*YioMCM0 zlE!+DV65kC+YnPEZ*Xx<*KOe7f#L{Betn0?VRCZP zi(oUL2aQ-zfM2M*+0?|+gyl^h-!DU`J}zEm2^ zx_r`}Rm_^Lhv)wMGjs+Dsyo6laxKb9vf(Bs)?3-w`2U^uQ-UXi#28{Y4m)-HhV$L=zF=Mg-6OfCLSo0;6G!6uL;5*oJ#Gpp1V%sb zQFMY7o(%)vFNTdsGelqOfgnf7#frDrl_5Imgfg{_VVHDAgnFD`8bKw^7h6>mf=GA7 zO5ga4g9L#Pu0AD;AV@>TzjMj=Yh;)~Q*dIjNK^KBxcwT&AjP;SgQt)4NnJ`VY4-f6cqIY)aA z8Ewf_tLTgNki?kR5f#N0V|*JTF4C9~BWBKP|KI=jkDh;?=X!o0&vo6`{k!jn7wGS! zr?Wu^0HC+m*Ygkn5P5_Eszq+02_=66K&NJ}r+aW}_*DNMc5pg;UctdqvgdmCmQ&qy zyr@g#6@kxs(CSsgi67tp zlAKuh%06+=Sgi;TW#pQ)eW{hZTzQ$Hx0Z#{sD2S!9jaw0Ef6J8D!K&&^`qH20O|s8 zJ%ZAnWV|t?fp0Kc0e}!b!x=^*G*HBdhRZ&A`QRW1a3f%Z8d^7wQgJ;Rbw3Wywiug1 za5;pW)uv+c%A1xLaKN#h5RC3%B_SxG_4SdjaD8Rh|K*(MZP~e-TrV0dard{$-RKex zf*0KJ)*S4rw#~PAZ&jT1XMHp0iinEvJ8f>cN5IMOtYdN)?moa0o!P$0HDl|M$1$Zd z`g+T0m4!7a;>lULy9M4F;7d3dl_2qR6OvC$%9#YUYFVv(={BFM>TMUTMWBk)P|luz z5wo+iABGyTqP5!F+vi@Zl#YsfB2N0E2b?*cDr!Tiw{KEE9RKsw5Aq*~~LbPS7(31@|UlomRYio}d_R z+_h`hA^nXm3%#~rY@_~%>H?K%UMK?K zC8_Y$nceS5rCve+77>rQP@J3|?=ayukrLk&G6D?On?mq<(T8Vl5Lxv`8<|dfvI&Qk)7S;)RQ*vVbkq{6ozw&Zj@vd@fQ)(MMS`qH3uT z4~=-l&SY)lvi8v>MGhIu!n{Mv%BgJ76L|Gl%q}hyqBtsPe)J-B`luCt-gtDn$19=^ z+`TGQ$94@d7{$RUL8u_I(dk+&wSa+_73Xp6Y&r+`(XGkb2Ts>osWiMbn2y5BMrb;?GG z6@$j^Xs50bw9n~e5%bzq{M`SxUNWA#UhJ__%EMMl@jGzuin$+F9~H#0^j$=LA`LYB z@p!g{c#*GRMBGgKd;qoa#Q{ZwH1|S7f~0SAM@Mk?uTcTa%*CXz(i%|TvM%!=;%teh z&wsp}JlQFcqruCWNlAHNojo*|w_jijmkek=QI)#cjhw8{HQt`iLY(RNMZ8K=9=)oL znTJ_v%Kq-|A+`BoaHY+}8TI?uS0~%h>D_o;ii~mtah~xMNXuB#B7-Mn{{-cy_|%Wm#OvVe+Fkj#O|4)J8U{4*2@6BE zE(Ejvf^v+w5XlY*Oa2+HI0vALV)}C)0Z=Ld1W#Z18;*Zy!2c)-xpQ~57Pr_++-(IL z5^paxZvNpC7FDFPAM}57&(kkJFvrkZ-199`K6~sGuix^&kYV%Q^fyK12&h~-Rhy9w zJ^~}S;K~)cW88p^gi{t;eW1wZblkBxYck(pvkK(0bZ5QiR0xb(#ihXjg;-(fpeTL`+mN|J`Ir61)#) z_uV!P%tpzO?y|m&RM+DP32)`#u$^btVj`L}%)=5_mr&Ez$i^ryMLquTb)CM}0aJU} z&x6S3<|DUs-35h6t?83OA@h5LI_^b$fo3g6k`QO|E9V^gkd4k-U_gj6&A9rcB=X(&eC2 znu*+Y9mfexn-F1*5~{c=hIK?S!;ct^?9D}^IdB_7wFy| z+M0Tr008ZMe{=H%03u8XplZYr7|lBdfTnbx+aA9JhUDGuFuz2@XVdjXf~K0dHI~0~ zUC2n#E~~W__9;K*lGeF9l2g~$t=02Ae#B(UnkJX1{mk1u^sxEOP4@lw0wz!VYoxWd zI^^e|y;rU-(Pon1=-SplT9u0{1v9a2tvPm{7mX0o`R~g&+gA^v#&i_ZAfZ$YG&E8S zAh-iUQZz`IOy=%^gOh+A3?n3`q)xIiFu;tj0|;3ibP_=^^=~fU82cue|GWEQPPMhO zvlIO(M~n8?RAmUAG)O`x=yNPm<24ijKaQR7w|U)=s$Q=v3FWshf8P#j-hLNhlmKUd zx}-&4aXl-@o+*CYA_!?_3M7-A4eckCcC2P!Xw)jTz!?_^h0ROAfsne+ZT?d`h<7DuOsGDv4mCe9>E#kCd`8-`^ejb-i0 zwYHk*zH1TMmSAb0xPEYiCGKB$|9n>%xni! zY?;2=h>FY3TnO69P9q7cq6S`GqS%~HC%y8Cc~MR{$YsN>FfVC^L-7vYh;;l#%2F&; z#G_m1OX3~KZ3mK&JJfO#?C|S*x9Zcg;nMB+NDG&{G%w|5=ri4XT@LEN=#76&+v@l)9*9+}xko@bJ=q(;EY z#Z2(kM$Xw<6zlBa;o;~ZA)D3)@{%28q5K_?zDA%R?k+brB;?uZI4pyXqI|X%3 zO**ne_<|<5?1h6XB{qpp5PbeV0O&&x;Q%hFcytuGV~T;UtQRmjEDJynpLcV}yaE9E z(Kczh743$R4#R+ey+x;CguZ;kFMRB&ghf`JCabx*_ z*~nnbj?a}kXF08m?SGhBY{b(HuSsIlgoB=DuL`Xdid)&Q6^kFzL5;0_L|Klo44eyR zgqV$pq>ePm&v{GB#Cmo$99Fa?ywL=zhPkli?(jxyf zF50$rYo}{}((x^jqFExBb?J;f0l5Y<4j{UW==@{W7x(2Y00Ts{SrTGw?#^fwQO7 z==)kMZyo*`R*r0Zd|W;*Dv{4g2E>%)1T}ippk>)MIG;x5?L@*DXylnp!`=N$VgU2X zj&gpqf=Xb=)kXc$hYv0xNgK|CerApbkAr8a=wOdV9@--7({MY8qFSlGr^uVA&1hhm zCfj`@1}>%ar5e*sA($6q?Vl#RNixRW8z%RVcvk`RW+$aIyb$L@wc5RBTAW-SA$h19 z=;DZ;_L~m*1;b(WM-6`?0#@2~^cblZc=kVMmrC-}ej-vbQm5iStc-O!-2EB=s7)ja*xDrYu(EoNuWRW(w`e{f*IDrO*P)i&indR^4Mg5TC3 z7yU;Zk0fXt-+JQPRwxwap`Si>m5S$8PV_w}4y-xZEC4gob5;oH7xVHN0Eb(@pGOyL zNl>q2ipGM2Erj&^ubX*69lD71&2XLb0CbjuDI#Iy@^036BcbL5==XM_J?fkB@urnC zRpt_{@M8zrY}8oL`+D9ZIM_#(imzx6G5U~Q%D)#$GqS*gOIFD&V)kn= zJjU#pN)z%?5>A06x($e$3lND!BhNDQix;KDlh86Y7N)DG_i?FdxlXzvaBZjh)h}Y3 z{M6XkSX^znK*;HaLA@z^dV0EUexgq5aNXdt`Sq_5MFw*0zNV9-rwy#eKm4gq<0JzN zE`{5|V*-__4PJ!qWUGuH*WPTuLBM5qdq7*h;{hs_`q}xRbSZP@S(FO;#y!~B8_B(f zrFIKI?7G(Qk5r=YqtKgo^wNlH_-Yk0R;pS#UGtT*FN>~4Q7{9EyiqPOp>HKbmEgcR zhYcWTQPk6_EUbwz-VYztgQIke@hXi0XLuc9TueW59DTSS2mRE@CDhMrs9yUVHlCIu13?0Z2Q|(G=Bicqe%$gjEaq2>; zq$x@}r$!F5D@-Maolxu@DJG&s4#}aM_VVr@-uI7a{j#3xdhT^U-}PDF?|oe>!Ohia zxq_ww0ATqxru|L;Abbe{R2IMagxo$1fa3XW_FHy``+k0F=fAs4vu@nFa-udjPM0Jy zSGaMDDB5YSVj1U`87J&W;OO5*qho||tInJgmQ#)$taT(Ud$fUVBuia$Mo2l39{%v{ zWa$(wv@zN6$k?Uf;qsh0IoN67VMNLFbnz*RODOsI8){(WY)YktvI#y`J#9(}Jr#w&sH^5+lgO8a=Rx;$P%@)hf# zI=+nD9iEb+Vr_~xo!w$kx?oNpdfI=_X>US-q{mLie_ES2H(wdllVTS!RV$TpnzGFG zJ&M?>tQ^~f9apSwnl*kmzcAVBW33(4uWzOS-3|TF96l!9Qs%qCCG}g3+={x%p;z)) zq~mjE;*1x^0_NNZ`ofzRr%hUS7OK_9I|u{$jVLzW0>VjmM}9vMi5P5Ksu~UeRaI3l z+S;C^g7gi#N->NgcrEa)I=!bVnER>ycN^Zq9BWj@pUY!&jFFc-zv@WZ)aNd>i4QFw zEHQR|{Ug#xH>?uoqD&h6(=sCXiIrNe-+CQDt*a^hD8;Q9)W}k~VTELV3IWAZ^mvWsB4;5|9pr#7Ga-Pq8yk@I$yoO4VZRyf`zf7(mDeI8%m2n z%XH=tM*4%e&@TBhSZJuXkbacAn0T&*7d34NEVPxMt=q*p4k88THd_Sb()A82gG)Q& z`a4h}u*%INA<_GUGeBKiJ6X-tw|0JZx?tp0k++(b)$y5$M2DJ@Ed;pD8Ltp?M}3>J zY3sYIqqKUeqXcyB$nJ|&df2c!WL8vR@q8WpR8E3ZJNW1fVH|I>4hb9W))uIlro4N% zA7*rt+FgwKy)x3i`qUExO_x5UCk{NnqBcK2{}(7|G0F1C&GY(KO2-3k(3|_e8T-~m zYj3|mO&A&ZDv*JtuPR~HHg{ae$Dtv?_3PKwH8c`R{AxT{i}Ki@ICId8q^<=9?Lbdv zO#9vmZ~MHU!Ijk{qbSFBJDb^USz&#urNu*9+r|9o9a^e0G?s2=Ob^%kCc^VeS^J~Q4aob>2YUbWcfo%t<5 zqFh&}N%Ci6elk`_%TZFp77R4(S15$|@d%2=OKB!B4Tnr~;agH#({LvcZSx%{au7^8 zyY_B;HbJ~DxVdfruV_0}vWFiaJ1~a6Us{FcCy%n|bNfXUE3DKJ{P#h&DSS(f@CP+q$y;EVLE&fsW6$Cw>!9v2MPaOVgQk}1U3u)H zsh=Z@#iFvyjGA-ov_3Rn)d!ky+1U?~rMG!=T32%KNQ+*SUDWpt#lBUV&n}qg1LqEY zp~(H;eL3mE{A>ZpqH_Za_dU3PbG=_=b80Q@qbknWCUQlN5v6w|mckGwLTq4QT==jV zasgxP!t=B1OST$c5y!3=FHt7?J7d7#IcGvIjSrx-N5s7_yhEM{b~J`|??jH{N-_g) zy6}I~YfZyG@8Qd1@nI_YCeD(nI}(K9KAZN`YK`069=>4+uKu-qc7@Rr^ekX>tVYz) zgrCtQ`#6M{*ijzfS?G1oV4rSU5A4$K+Uw(>prQ)~AMtu?6FMHA z3QbB%s>QMP&W!hoqGrQjVS`EIjr^Usp_wZd@R-!)v#uSO8ty#NSC_oECOYc$DhBvp zAAE+L-=y-(oKwuWH>NkOFUUE7he=pcQu4j?8p!Is`ecxbB(A{lk5}86Zdh;x3LR)l zXv=5S|6SyLu&d(NIg}%EIC{f%3AC-PtxuJ#*~X3RD2vt)E!X;5uWxJ+?KDY0^-PTUp|hE7yxR8(T?`DoQORfU!*X!EBLq?)Kvhl1V4Lc zY$6f~VjT>1(twp<1bd<~2tn=`Aigu&D#2qBoTX<+q2Oatk9-KV!9$_6D^CuwhhRo* zt|Ej-Lb5;cD~1^{z`5Xz)lv!r*tne6!F!^BlwyI95fq$V`%(tJ0U*j__joJ@KvFY@ z(+q|R1=!pCNem`Z0QnYk1$quY{D+7iBz}0}M>>AYiT|IN5*{Q2TNcN~(EIRz6tK;~ L)xP*YoHPFb3A3+e literal 3339 zcmeHK_gB+d7JvB?AQ0&Yi=ZH=pwt;ydL+vd%2@{xrAmo_6dMw7$WRkeq!&kaU?>TY zrKp4^OASPkCRJ3bK!l-5?~xFgFY^cN&-(-KoOj+mx4w7p=iYN(oUOHmkl-mn0DzE{ zrI{T72$)0w6d!!J5{i8QI5A*l_K)jC_vLY$*rW*g_Vra`qup9(w)V56yvNR#4(G&t zzD~Y3P0M+nWcvQlPR&Whs>0!ITSts{UUv*{W@Wz$&PrGNOyA1-RzohwxF;whjNVx{ zyZN0vi}}w=L!Im7>h|72uWxVNEIWtJLX#oh$bI&DL1))Dc-`LEzxHrNQN!~^dGW6) z%rc0&opD-I_QKx5@JnT|;fxM86ymi5;q0}uD-#S^i)6VH7!B1%n-F{IY z81n5?iGI|k)n?{@VSe?-Iah&y^N4-G4Lb=ngsdjFCP=rht!W|fRo#B? z>=ihG&0hD)HV7)*qvijyIg5*min@i#>{DmSkQO&+Wre(zA|yuGZd>V%nyKx@p$hNL zXY(u8&H4)9cX$2l<`ZxbYFU|POiYZYxA(cGNUjTps|?;dWxL`wAuk>U20tro^SrYC z*OXXGlY#aKCELBkw|9o<_7wL<&(`?i%3ElJ)mx<)8tQ079BSSg)!v=}aVP zbB|UN!&^CdQlBwr65&=ym{GoTS(^IwbIU@NbjJaOC*&b_SIT`9(6|YpBQk=35JHQB zMx-AxE-=)W>ajJwG}_k$&fY&3iSAoWM5mJuCI(YST-PwIEa^y zWfy>)!{0DYXh{j+Z^3e|@@akh1U)_fp&)Q!;5@_(UHFh4jr{@9UoVhxU$9cWwq+py zsT?x?1SwtBu`Nq4fXJ8HB1p3+fpyk4X1eAV7UFOTQmrFZzSCdof{>(O|EtFQNA45vPBt-i zrt5de%}PC!IHoP!AeJHr3DTNvMK%=Aou!e$>9!=N=E#UpDO*mU8wcBh7!Ze=l~NmvAtdWJUt1<<}$;A_(Z1ah#81I2?Dw@i6%RpM@-w!SlKrVlL=V Q_>%*yaMosYQ~aYp0Y95KoB#j-