From ee7e928cfe821e2a283a05afa47f0ac2c8b83d40 Mon Sep 17 00:00:00 2001 From: stockiNail Date: Fri, 28 Apr 2023 00:25:13 +0200 Subject: [PATCH] Enable applying of gradients and pattern on line segments (#11217) * Enable applying of gradients and pattern on line segments * add test case * improve replacer --- src/helpers/helpers.segment.js | 16 ++++++++- .../controller.line/segments/gradient.js | 34 ++++++++++++++++++ .../controller.line/segments/gradient.png | Bin 0 -> 16971 bytes 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/controller.line/segments/gradient.js create mode 100644 test/fixtures/controller.line/segments/gradient.png diff --git a/src/helpers/helpers.segment.js b/src/helpers/helpers.segment.js index 0c6dbfd0c..50ea8da5b 100644 --- a/src/helpers/helpers.segment.js +++ b/src/helpers/helpers.segment.js @@ -1,5 +1,6 @@ import {_angleBetween, _angleDiff, _isBetween, _normalizeAngle} from './helpers.math.js'; import {createContext} from './helpers.options.js'; +import {isPatternOrGradient} from './helpers.color.js'; /** * @typedef { import('../elements/element.line.js').default } LineElement @@ -346,5 +347,18 @@ function readStyle(options) { } function styleChanged(style, prevStyle) { - return prevStyle && JSON.stringify(style) !== JSON.stringify(prevStyle); + if (!prevStyle) { + return false; + } + const cache = []; + const replacer = function(key, value) { + if (!isPatternOrGradient(value)) { + return value; + } + if (!cache.includes(value)) { + cache.push(value); + } + return cache.indexOf(value); + }; + return JSON.stringify(style, replacer) !== JSON.stringify(prevStyle, replacer); } diff --git a/test/fixtures/controller.line/segments/gradient.js b/test/fixtures/controller.line/segments/gradient.js new file mode 100644 index 000000000..8a09503e9 --- /dev/null +++ b/test/fixtures/controller.line/segments/gradient.js @@ -0,0 +1,34 @@ +const getGradient = (context) => { + const {chart, p0, p1} = context; + const ctx = chart.ctx; + const {x: x0} = p0.getProps(['x'], true); + const {x: x1} = p1.getProps(['x'], true); + const gradient = ctx.createLinearGradient(x0, 0, x1, 0); + gradient.addColorStop(0, p0.options.backgroundColor); + gradient.addColorStop(1, p1.options.backgroundColor); + return gradient; +}; + +module.exports = { + config: { + type: 'line', + data: { + datasets: [{ + data: [{x: 0, y: 0}, {x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 3}, {x: 4, y: 4}, {x: 5, y: 5}, {x: 6, y: 6}], + pointBackgroundColor: ['red', 'yellow', 'green', 'green', 'blue', 'pink', 'blue'], + pointBorderWidth: 0, + pointRadius: 10, + borderWidth: 5, + segment: { + borderColor: getGradient, + } + }] + }, + options: { + scales: { + x: {type: 'linear', display: false}, + y: {display: false} + } + } + } +}; diff --git a/test/fixtures/controller.line/segments/gradient.png b/test/fixtures/controller.line/segments/gradient.png new file mode 100644 index 0000000000000000000000000000000000000000..74bdef261206944cdaa9754d46f3c2d334dcdc02 GIT binary patch literal 16971 zc-mdO2{@Gd`#(N2*~?P4vRBq9ibE(fDp|_XN-0AdEmFuR%VXM{s1!woMiG??5m{$S z5^8KMWEuOAWtg$dnDIRS_cPPy^ZEY%=eo{yuB)E8-}m~uU-x@CH$2=NWo6W4Fc^%i zv(vWS7z_@B{wpN`{xco^eIEP=8?xJR3+4@7V+4cI!8mWT-y7~T-i5!Zv9D}yit*yn zV?R=RjZ=hP^7Aie0%O)zMiBQKSB}=}6qRZr#I z{Y|=-4~;)M&AC{TRKMZq{r0h(!Q39&i)Oz$DGUbPPzv}wl6~7)NIZkk>-dg49h(UkkizN#Rka2OjjUzeCu?rY+T3npQZS*%Ww0W_L%GwfXC|A(_ zi58-S$yEq8!3kA4t@y>C&v-r@tZIZ=lQ>`@((k)*eoHyho*m_c^$053Xe;_wSvuVN z7xF94ZI&bx6Q^q}EBfOZ8E$N%&+}n5`Ttjh$4TtuYH>nkbKjWgkM`=)jAP<-{`0%Q zWxmUNQ=d9`FGank@Z2fpc#N`ru$st=zxD5Q-R*p+?7i@MfWAS}*TF&VubrB><{b%7 zp@oW>1O%qMPVubJ^2X*#ed!gg^2&jh2t6wGOBQdghOW(zr1-Xvve#!EAKWM>3=sK( zOj`8Ft|C*bo#v{VCw3=WFEqM8iS8!8mwKQJoyO;3ey(tMb4}zp94;r*v3ZzK{Z+Er z@1QOsAhM<#s`xM^;iI^66%pb_xWx2C5zGbgV6pxNyd@tM1S}IadEuU)u0l|IM zyZ#1h-Q@2P$L25o)fV^H@{A`0ucZw2;r4QP;|oLH9?V`XJGXyD{^`Rd3(TMGVF}W= z51v7)x9XkDc1gmE)B4u;Nr_fnqr4HCwJ*Y}-D3&jYvG!5L{JI!ZI7eoPST;y@FC1z zwe4=#MbZR7TC0ghcKg%?xW5+eF6EYIJtDz{ub*Nb;N1lOF@_C2-uckWafhp9{xobOBd zYpA|&9ezibnQK=;I~-f{716z5Uom%hbHYN7?FS%oOZ{Jw;bpXIKqSA4o8S0-8MTj& z-xu6d{Z1G1!J6$B<*!!~?HWh^X(+LJ>kc^KHHUP=y_%c)PbZHfbOJ*Mn$=QP9*885zu{~<=4-nf`-b4+EGE_8S^@d0VYJ^4rQeXE1uJy{nFk>)$n4I znxBmSv3gfR-8_q5&b!sgOW=P{jB!|9&k`vgemzDH+4ab-n2w*B-G|rf=5cd_ej;s9 zS-TQu$|C|qPy%b5 za=gX{N?B7?+G~qC%I$BVdw>G9k%@glNgrp0J}|1osWK|wwb%Z?a^`@X=(@{-+-RO0 zGWhH?Z(+gD{iyjpJm7G1rApx1Q*5gkI<|& z{>tjE&^|7C_5rUisfuTURM#oS=xScOwG-Zi^&ML!@>Le?z7@-n-_FgAHXjx2N!h6S znG*FQ4P;-}u@yauWTu%=6fEP#cCTbhLt#wfSN5DsJfz5yyyXTY4YS&wF@>SoA#pX4;h?w;TVpg-wS}6;oexJnz&{ zx&_t0@neNMEyBg~Z>rUbx`i8X*ihk7;!L3dhNp!*O#EJAz~hKzkg8MUgl)lO^<=Xx zNR=r+N}Ua|)d+kS>vH*Pt*3V|6F-4>$0V6pje-SGg$sL9!nHq@YdV2Acpck2=`B>wZSkS8;mNfehm7Pva zthN~2$0IeZ{;6eR9f+f`gm zVbGZ3COrR#?G=_=`UW6%Whel6i~rUJU>@SVSYc>pXA+-Xs(Kc_fa!1z|n#W z)B&B2iDO{V9%P-ckS-Zd@+K+`H&0e?4N4X4?4Dtgkl2UI@b!HSl&Y3EdA^C_w*6R> z%+KqE8opKmb=P_%2$?#A?6T{?dpw#yHV_%fJ4Hg>d~kE*$xVOVY!$|GkgUIc@?~%k zv}1nI2I6Ps%}teSx(hw6A@X#3qV7*t0Uyd);SR0Y|Y@owvb>!O5O zbFM$L{BDB;FCF>54BydZ%IH9JJOmT9UD0Fsz|R^n4vq>`VM7i`r=@6j-P&%aaRPkY zJX^)HLH6EAiDyjgVl$-)qu0%3w+r!cZ%>2!#CF(Mu#ehzm>Shndjj@ zr_OY1=U`L6eHabHOopF@X!-op8I-~GfAF)}ov>BV!h^_p;fYV3W%JHe1xyI12 zAjH8@5?Fjhpe4lo^SF{c#;uksCP-FLK?(KStZB*Iw|mDjO`@+1KqhCEFt^k{TS)yk z?Og(cAl3GHI5>oI{t1Ps21^S!(4bC7UtHNA6l^IgNV97p0zL;VG~Mll9_ zx4sVf^k5gp;*?>lsCqAoPxw$ZkDoQ$Y0iJi7_))&POeEr_Lv!AhBQwKgq4=D9ye!4 z)f`Xw==aC}Cy&`7C>!XB89-k7?!s)^@h>7Im`#R2uahcr^5$0U1O62a6g`Na-$-E$ zrXz)yw__(wR>DFGNjM5xcZ7Hnz{RRMck2%Pz76%bL?o>l^moNLQP(=NzX!h6(fq;Q zZ0ExFbmZ6z$_@*ezK~8{qo%G*Oz8{mN@1>N14%hAY#)sW6$<1lTY`(Bp^x0oj!m;f zT{|UAe87|l0^ThKz3*+_yphe4Eoy2Clhp{xo(%2tVd|x? zbuTr@@eckSf-v2oh{?h6fTBFVp$1JjZu7!@<(0C(l$_Rwm|I+eT4T4q)+u zgu>vmb*1N9@Kbwz+S36!y>JRrs)&4$Oo9)r?=>xyh9pl$4vmM5jZ=^57-EvI_KW&S zjksVEPa2&5u*wmx&>p7XV+YfrseSkyljy;^ ziGwA~0aeIl;`=YoAzmF7cA-<0u+g(2+H`kpQ>{Wg-4?qY_RwSb~jUhduh+)%2bc*{r$)n#UssbYe2g5Q0L#bv1M zcZ)+?ym!yUO!=<&QDz!f*U6;)`kAcs-oz9a_Hm5QghIIe=1j40>E;5pe+|ag5(5KE!jJyz2;rgfWbyRHCZ3$0lon$ zXoXvX3MaeAdXt};71_dlZ=hT*!&zaTE3b=uzIq>*vHnTMO4Qs4@w3Eob)LOtr%d*Q zprIBabLwWpwzGr0!i_L$DhiKK7ED0~Ga|hm<>+r0suPb3(Z_5RusI9gJaOEWz&LmN$Y!EY#Wn42m&g_a4d@GCSpC&Rf z5|XjmXcoBwf@{jGw?*nqkh-Htpd&lzNau-;ZP=#khRxg2)mGw&(ZN<~;VGsw>Om}9 z_?N!GXbFl=R=Nk>gCxWW#viw>MkDiWaU`#~%W%0^b<?r9`BV;6SyNN|?Ynl|TnzgQX5= z$q~Dr?<%OKbd9^`apdodk^AsT0xN}wKh`;8^B-wDq8&6{<$XbfY0J-m_sV6N1JJaX z&Wa^YaG)jzh`OaQj`reHD%{99pCZjHgFH@&G}K)?bzF=8OXK=)H+QUu`dS0@o8QL3 zWk`O)_@q^PE57w-@}A|#oQIv@@mpt`gJoih9q-Jdt0^yzj2`qED2bQnizVgp?(_Mv zcI|TJ69QvP#-|ZOjO7#hKd714QI^%%JtHsa9sRZhIhIasSXPo$6ExXIebVgx>Hxs( zi&Ljj7Z-wp8LzhU3ooMMDKpyP;!oTqT>7oLndy+H1V)_Txyl)jBB!$0o5Q85f&Ocf zpzPO8Co4)Ig=059T2wi)iT3X=#_q;gnCcgy0PU44WR`xz*ZqcpIjYxvyxpAhH9xB| zplkB{SO2V;A>PDgL?3;FwjYcAfNR5kloz$Iy{|hai^lt8Hx_a}Wq{F!dDCPj6Qex2 zQ3<61g){?JSG!_+nuj4XQ{j!t5nlZ=fi0#eY z@bQ*L2A`=2OXwnYw-jY!>>N_7R>cs4gtJHSN5$D$QnHK5{?~wl~F-D zAeHH6t9f&$wrN~Q#%1J?b2xRtMW3NaCQGp-{c{Rf5+;Oi0iElT z`Xw8{BMzf9H(mQ|plcVe{75mii`NkwwGOI3imXc@`_J6M^&HqDAfYL89LK7>h*xt; zs)ha5HwRTT5TE)gQQg@=2lnO$trI8AWT!0!F=~52i%^|#Je$$GfB5OtW0>a#dG8Le z707<%F1RDK*eFYtCqsuG;4-WWGW5_$x!_ob-fIWOP6Q-Tj<^FfL1x_uY@+jfZ^=EF zP~*qb5`ep-P;y6Ijtx+v9M05)4=J#sKc_?Pv9&k4vN66EXnRJS|7wnuiLu#hZGcXk`s5vX_ONGvr!{1^V=I4g4589sLn308I@ z@s<9QjO5#(zj@vn+_CUcr!_o@5*dqUCXwHA|F~-LNhV|OLjTvf_L`pS6x!R{R{({x7K+1+4 zSts1K(?8eyPV%n&g)<)+03D)QNU;OdN9XVf*_dJf&XIpW*Vrc9)_Kx;&X)xD118@N z&$cm2&ETjPdl2<=Yp4pD$T_YYT>41)A~P+X2?orgj_1z?($@5FPne^NxUT zWBGEzN}TZHX&Smm?6te+U2DSA53>PmFd^C^0%<~@L|jlXlbW?I_M40c#!Mfra|tP6 zz=weM?*_9^@U^>m@?lP}tkj;IM+9usi*qe200w2!+JPWV(7Tt%m*&1g#;Sa#J8jvHX`&gb8d+l@K1CH*w&jzs$Q zgjKR{>ue!!CO(=)ap!i>o#31IegocfDs%9Y2+Z6Z6P}Ve)#n-<{YncN&HDHQefMfg zX2ZuCm%nt6!DZNa({BR*rx}7e$8joCYn4ca^-$~`WX1_4N)P=C8NchP%XsKhgcLIpR<~M1|STP&D{BX853E>f+ zUFx+u0OneqFMU@B7%%QN579j^Mb?*!0AKv6a|b_5t*pNmjg(ijD9B7N(Fx8q3_kM% z@cMo6!FGUAK8Pu)i?Zwux`u}wW#IQ8r8g>(>j6ToF&MlGRMI3z79+Rf=0kP`TN&G^ z=Ggll$I8Uqm$t?NdhY4VBOwM4A`PumoxW(}ZYgA70=6v=5Cc7V53QpNrtbeB-aL&G$OvmDA%}b@Jb0#A)?c(}35?gohBB18x_7 z#XWxK3bHeBX=WwB-tAZ)?5m}zJ6<0ES@x~x5SVp;>(X>-mJad7>+}IaJW!=>$B=!b z^Oxj%_D&q||L=$pFLR8fOFGeP)xN^m6x&tSO2%uCP-I=TD5%9q;eYT2Pon< z-rBz+`s~aC6T|-o25O*YMXe*W+&d5r#MXNOt8r4_O($E%oknJ-gtT(k{Go?}(I6R5 z^hibtGwLy<24Z{$3<`D{Yt*S6`F$1q5~yU^t;=3i!OD|i1_7G5c%Zk*P)*)aLdIzT zNgQd&+ffnD*5;Rwd&xV)hZox}+yxCy90($kQ>tzcNbE^i$YBYpw*?nyReel{AV;U1 z2sdog$YhJPm_qnd!t{l#MOODdli)pdc-dtrILg1r4!?3s;wskD~u|a z0!roje8dp9S!LtG@vOU1ZT_c%AYqG4t|j$`QTw zBzQb-&Fj}*pgN9txW$42TV*5vV%C+63XVKF3-u#MK5ExN)%JaCS2P#4CCizt>=zO@q#)4>_|(@v zLn#B}YY5Pq574?nIfCz=Jb#NNXpn{&fIMplT=IAZyng>t+F}4YrsrmVf4z$D=*;OH zX{`FgR2nUh2lNQP;ZQ*@@V%_O!Z$!ya-=H4*0zv=dn1|n$3lXk!!wUj2)~RG$822$ zirdJy4jPDWhYM{5?dedlD?7;l*vXkk04{%ueLD`kvW5K1?#4aYI1&uEsX=uqif~l~ z=p)LBAulID(uSI5PfL-{E(Udb)(~I*y-|x_4oK8y&5cz5LuP9o1%CR;UypX=#jG_X5A2VcGgH zwe?+;PqPkB2y9it%JxvfS__{KVXN))eN~hYH4%k@wI5Y?e7Gv!c{7UFStxOGa_Fw3Le6{ zi|>Ca_hK9Zvk6N=Li5dTAk4*;ehq`m1s>97O{Oq-vGo)TH!=a))*drJE!*HvAShv$ z;6SUqO&eutg0V7!Nl6A?zDTh}hPK^IEBDHB7@^~AgX zxeIWvH{FTq z-ju{$&HKe{d>8>3W7Ftl>qRk3!*jj6vqI0Y_3>T;^R7oCR8CbZAXJsB<^wJpQ>){)^3xo`GPiT;mUl~+d4T8G1IV*jw z3UKuK$p9PNYsL4IC$e-*?8f>zE8wtNqTqDlLf}V+rzgmeGFnTIC18j}>rWM}AX~~* z@J?9wva-gbs*l9t6Cw50J5s&Z099IO&1b|8>P-$^b9(WbqYeEC3jRgxKopqJ0ik)^nAOY;Yi zwyV^-2t>F}NT0)wOL}0P+;go5#C{r{8<}z9_j*)y_PQ4rGPu$)uAth_Mt?qv{B!;4 zj+JJ>JG5{>Y5#zNPv}gt;!Q0A^TD6ArQ~a%09E?>YNd20canE76Z8eoo`jCk8DZRr z+XKkXZP77=1>m+B^$>Bfd4M?3hTfo4x2REVwfX|kSFET#1rW4dY;#~fNcbyPwzet+ z+y`JD`H>Nxj!fGkI=k{UM;9kTxkp@%+M+=c_Klyq=SJQ+ot>|?s}18B>kFdJC)pzZ zT)WbsV+L3eZIg=t40?}ECh4c|%5{3YwMBxHA$S5`bO5=5mLX;7RYE^dTupVE+Ep+g zbX$AxgzMI)4b;hM9y>;*^ zb)*(f+6>1_LzJ#QI<#l1w@m7*5dmvvpoHIw!8)_jZ-@FOEL1y1U&@9`>5N!iNJ0j; z7Br&(=ZpY-oI03J@$9W9{}dp{enNK)J67_7HaS^f$UH#RhD!QUq^3Q4Dh+p^(4Jip z#NN}rplS}sYr=N?>$UKL=E~`cYe40-OVnJq`@TkZH?`d1npeoS4>~_{bdh(Tug0(R zAcJs-|C@#*(`72=cI%dG1_nK}g^YgYM0D~k%MW+6lqnO6U zoH4#Df8?-h_!#xnrj1%;34q}ihRZF)$u8n?wQz~24bz>9_+&DXEo`Fm-78B2vVa3u zS8vHwcuw&3j7ao3JhIc$pl9pC`DY>L%m5`u5%;d&lU-7;41Eh1o~au@J|4++82@v^ zf!SvP*pmXV?z-6J6FMF*Xlq!ocF>pD!EGO1QoqzG5PS=PEvYliKT_XU=cne40?KHB zl!tMm7I8r@l|%cB;e$|d@(r5gCBq!mHOnqOKV0e6T)I&fEW8aYypo);LTc|CkK@>$ znM}LyFI+lmQL+6%thzi_mXIL<==JxQdZVSo$-s`1KIb3>L$L>9Uz`94_yZ3rq`+2F<^xhcJwv?t)_$4;t zQ~Vfd55ZO454}+fYiekRN|RS$WiZ#paEBGZ-@EJ9{NDHU2+E3WO^I$3Aw1jY4x8|V z1US^stVvRA2ms`R#v8^C!qD$Ecm8F-S!|_E&!a=mOr{i+ZHp> z=nI^#hR%hA!F&HxDu#9*n7UmI=c=s3v-)R4(PFY2h)n3Jo1srbfKK#l_vBVKSpdzm z9j?ymfRTI&82?c@KV!b?fpIiu0B@y?2gLUW__O_-{s6I;Kygq1x`zsco`=8*jkWFw_x77MUl!$}}Uz7Kq7tQZW)$n*U``ayU4by`187uqfk5*%HR zZ2!brbD0j0B&>t8Xhj%5p3Zg#>*+gODF%+Xi4sd3*#=0z@I2TJz10GKw`Hf>HNraJ zD;;!04*2Dug6^ZXRoFx*{<6cKrNbp4denY*R<088)Qh@O^u`bH@FTKylsk~LS=yp& zTZS$0LDvnv&F%Lvbs3%)9*H7CJ~4TlIrB*9i=u z=Df=J`SJ>|+(p~lAflg9cv`1x@%%0@c>DEh+d;Ol!4Dfc&L1NJJ)>?|ENsj01bC)#_fmbF)GKG8mTS|Y?BhUIviQxRRWY=u;FstW zJF)nVpj`XtrGGKFrx;%a9Y7S={+oat^rY?5vVbz{SfG=fZuDgg?l3w_x#*76o&s`y z2sWx=#SR((FO=PB?x_dyyq^@j1(3@s;9<_uZHq^Nhkw0jCrS$oe3IEUaycUfY4tL=~s40K!%RVR2^7UtCaOC>kjQfd5R5YtI8* zT@S)_Tm0SxNUwp$N%TxsABbOaJzDCHfWOrL(hUqQWU=UU$J>~|4hkF&0Ce>`(A0yn z*8l8f5F6=T8L~hU0Z5XNxTe2P7gVHFVk}I1%C>b&?0U+l=mL$ho_#dv2PgRvuwdQ>In5_<7IKtC&p( zfPM7q#Wk88KOSd!dX9b29RHJG{P;>Wx}Qx4$QEi@w08W#x7n1ld%w@e|NikUj$U(8 zcy9--w>4>+!#n?B!LW_xVxXHXp^v2a{d zx>s1H!A{)Rc8w7f4}3roO|ATMV9^1Iw!)a!!(s|;_W+P&50p+MiQ6@4TBjelJM67& zE5nXO??RkIN6zY}yKv10aqxuj;cm#rZE@XW5W{ zo%u-g_&SRpp%Z=1e@uri^rT6nw-$xt{n0>N-eJ#sx9Z#B!QIs6=2wXBHz)Y?VhPnP z7;-n-E25=dN%jb4j(lV|vjnZd9~q=hUY@~n;okC{ZCIMwb1(u?!AM$J*BJhS;>zWa z`&iw_KN82uJ;K`x_t2O=*^k~gx=L02$;&CGGwupb%VG@By9y5$(UyCa&_;hLYl@kV z3K~dA7&Ax_o_)_DlDyt)0SR{&Pm0BmJ>qGj6jeo--46RaI@lkC*it4P*?HF{vAE> z&L59jAom4@k1_g}Zutcu&j=KX>y2%azy0bM9kW#ioxB7CK@`WbaKTpLR2dMY2^z{U zK_Rv2nibwuU$D8jnljD-I%jcJ06;x?DvO>dtpj5l!RtWJH}$yP9lb&GxzU4?(QJAC zF~C^vqI3E|%|#Ov6`bSidszkT@Nv{lx=2|j zjfbMn50Jt8t;W8s=;ptDFiARt`p(c&P-g%pjtFy&VMCl$(IHUogV;l!oVC1!v81Zv zY9j9qbP9}ht80jpZP4M~9vd_x>e0(AieZRYvcUYC$xLB8Y&psRGrJOW{;o9Cr7b*X2-nLm7mnV_tSKOHNsH zCu`EvWGeL)dah4lw^8+@+=Ta9M5igQOXKvQ)Jdz&9gIXIJc5`yIX9xdlY82ga1z+A zGbx6$-_P56GW|-cDfokbtfH9OPE-35@v9}!3nN#7vIZaDUox%;AbrK=>Sc$If81iFKG1IzDtz8vi z<(<8a+KhpmNZcKFZpR><8oT<+y45iR3QB;K0-ciu?%<0P3;r&0=7~__b+Il7@O#jx zrVS^51*O;uZk5cfot-uXiWmqg8`GhL?P7<)Cw3^r=*}k#KxEN7x))#{XEnoUq;V&A zwC-F+DtaCdR5X*aqrMJ6H?%ImFFq4Fsbk|10K3i0B|_1|>W%s!%2QasIy`zyF*|Hd z-E^i<8bXiBxrP}LXwISYm8O<5g|TnI5n%m2>S&6^8V0Z9D!!vPVSv$#CHz8>H3y~f zq2ZnHy?1g`;g^hK5VH5i?iyAwlhHifx)yYxo_3U;Tb}AN71f+2Zv~ZaO5#S$X(+-6 zRlU^E1H8S4fU~STq3CwJj?sRV`p`AHJ_=S$1&9^2B@5jF*2za({I_|}OEaddHEN~o zbZGw@mMLRFJKLo~iTW)adN!1{1Wkur40-@&)jDCyQdWesfAKo{p>j@RJzAT$#Zu1- zAC~~F_r|;**|UUY^xIt!3}ejGyR^ehJ;IgIcpv_ymU#h|=KZ zpAmg|EF(2>a}sQaJf+ALZW^gob%tjo$c5~_3`aa zQ|g;$gLZ8@xdwHiHR{54)6nC>*21RaiGBWs3-K$Ex-Ul2{mS}+wO8vCQ0&qISyrUO zC9#Zc@-^WT6M}|SI+RJ(B!Rbr^CR>%h6O0`4C{i81$rcHCE#Tew}Ca^&20H60%R`e99B;yavAG6S5#JC6=I;1iQr%SMp3hei2=| z9RdXTf#Rud%GxABEfZ!&9}v5z2s^=?mmFK+T~7zlepHkr>RAowmXGxyw2;Mu)J9Bo zk$ptO)t%zQ`f9N{5E24)MM}c0-vT<>XW3Zk1z8@Hz|brq7$d``obmotDHpA@>PHZG7qD&ZG&wJ z`;4d;&a!{dl-+CozTZkS0XjB+nVeG^v6_#CT}|`C>qF>+|KZo7+Es2Es>3&Vc*jlK zIyag|wKUL2{=0qv`~xcA1oPMcnYv0n-$JS4 zF!Xt*v^sZT(peg!`@U7k!Mmc9Qh2Lga9o#hC$F)tu2HyvCGe-2BZfTy=-ruggnJtb zLyz<1oYAQo&<7>-^kdscdF7K#BNA-e$+J3c)+#4l8Ql+leB{0XdLJZ;2~CS-i0X(V zZxwyxzdttEw#ps8RBrcwlyZ;HjH~s-K%J8IKYkhVGF2M^1DHANZ88 z;?^d#d1(^+gZO;Fs^PCk5q()7;pHEl{0fYCOjKKKBGr`(O1iLve;Yrxl}(JkcV1VR zMEzoyh!}38zn$aWG!73 ztz+bFC9rbI1>s3%7qY*UP8nbf6u5N!eWEq&fW2dYw9E4~zRjDWS{rNZ7rm*<7{R5R zVgv?*u~DCaOVAT$hBs(M^Mq$nLbHF!gra5xm!)>~1_|0g-%JwZYVJyt75-cqm%bJw za5UGReOSpUk>}qLc&~RlDRSowF5LvA7#_}VbOw6GMs*JrKr_`h%!N-YiX1XR#0ifD z{(x%;Z=C8P#W&r53scA=iI5|Mq2@Yy585J06N12Wq`Z^&%OZK>TAb((u+1LKKphko zOC1sBK^@g$Yf`pQ?suc68#o&A;%7O?5-=blb7Nnp(2})^0a2(MrVOHT{O3C?sk8g= z-b@HIv9;0<7VNqJH!uqW4LpV3((|7u8Y$&?fNf^YQMl4sG{Ax!EU`|1m#*RrNfT%3+OJllr>$W2kG!`oH;civ^DtfDByCBLxbYwS}6?N?QQS^HLPy z$3@kY*Bs<#Ev&A#`jD_?W?aFko1%(o&t7an)plgFdYUqK2z{NZ)E0p4X#`9>^)M6B zsDqNOTsbX#W)$k_dlX#~pzeuZyda~yKCNBSN+{vY5t&tw!85F$kH)pR{BVtX>#)pmuc0wvZ$ye3@L zTL2||UVhj?h{qX(XQ(s5f=P)0)M5u1G(SR;@VE2&9tVK09-+RHgLaS2zUQzyFqu@L zBflv<&-x3r0M2fqb9kyXE6clY zM0)b!wxrMtI?j5QD`ZMt@!8?8XZg>>?@u%7f;>aOO&bv7e^&-P+OuoJNnHHh9CUF?PR74D9zBNK7L6TSca#bkb3HPOLb+h(L@joT+{5rrdU z*pXkNye{-*)ll#W5i3!6z9q&Jv(GSC?(hH8K%b^d6Ybs$SHFg7z~uht!I4za&W!q7 zF;y2FiLz%_Ec)gk5=+GW2oyI-4@n$1{PLG$N?9Drc$9#3PDu}a*BkZh;(v^hc?Dbh zCgQJ1i*)@dtznFLH8Yrk#i#c76BsUKpN=9wYtke{4$G*Oi79aA-OVUmQ#|_)8gJ~L o>iGE~B62#mSwvR}5#liZklhpWH099u81Rp?gWI+@TYNA7f8ZD