From 63dd739691c8c4b3a80b393158709e0876bf6cfa Mon Sep 17 00:00:00 2001 From: wmedrano Date: Thu, 5 Feb 2026 12:29:56 -0800 Subject: [PATCH] Implement lowq for sweep gradient Also handles the concentric radial case --- src/pipeline/lowp.rs | 46 +++++++- src/wide/f32x16_t.rs | 24 ++++ ...ic-radial.png => concentric-radial-hq.png} | Bin .../images/gradients/concentric-radial-lq.png | Bin 0 -> 18930 bytes ...nt-full.png => sweep-gradient-full-hq.png} | Bin .../gradients/sweep-gradient-full-lq.png | Bin 0 -> 10388 bytes ...eep-gradient.png => sweep-gradient-hq.png} | Bin tests/images/gradients/sweep-gradient-lq.png | Bin 0 -> 6455 bytes tests/integration/gradients.rs | 106 +++++++++++++++++- 9 files changed, 166 insertions(+), 10 deletions(-) rename tests/images/gradients/{concentric-radial.png => concentric-radial-hq.png} (100%) create mode 100644 tests/images/gradients/concentric-radial-lq.png rename tests/images/gradients/{sweep-gradient-full.png => sweep-gradient-full-hq.png} (100%) create mode 100644 tests/images/gradients/sweep-gradient-full-lq.png rename tests/images/gradients/{sweep-gradient.png => sweep-gradient-hq.png} (100%) create mode 100644 tests/images/gradients/sweep-gradient-lq.png diff --git a/src/pipeline/lowp.rs b/src/pipeline/lowp.rs index fc1a6c5..f926ea2 100644 --- a/src/pipeline/lowp.rs +++ b/src/pipeline/lowp.rs @@ -126,9 +126,7 @@ pub const STAGES: &[StageFn; super::STAGES_COUNT] = &[ repeat_x1, gradient, evenly_spaced_2_stop_gradient, - // TODO: Can be implemented for lowp as well. The implementation is very similar to its highp - // variant. - null_fn, // XYToUnitAngle + xy_to_unit_angle, xy_to_radius, null_fn, // XYTo2PtConicalFocalOnCircle null_fn, // XYTo2PtConicalWellBehaved @@ -141,7 +139,7 @@ pub const STAGES: &[StageFn; super::STAGES_COUNT] = &[ null_fn, // Alter2PtConicalCompensateFocal null_fn, // Alter2PtConicalUnswap null_fn, // NegateX - null_fn, // ApplyConcentricScaleBias + apply_concentric_scale_bias, null_fn, // GammaExpand2 null_fn, // GammaExpandDestination2 null_fn, // GammaCompress2 @@ -646,6 +644,35 @@ fn evenly_spaced_2_stop_gradient(p: &mut Pipeline) { p.next_stage(); } + +fn xy_to_unit_angle(p: &mut Pipeline) { + let x = join(&p.r, &p.g); + let y = join(&p.b, &p.a); + let (x_abs, y_abs) = (x.abs(), y.abs()); + + let slope = x_abs.min(y_abs) / x_abs.max(y_abs); + let s = slope * slope; + // Use a 7th degree polynomial to approximate atan. + // This was generated using sollya.gforge.inria.fr. + // A float optimized polynomial was generated using the following command. + // P1 = fpminimax((1/(2*Pi))*atan(x),[|1,3,5,7|],[|24...|],[2^(-40),1],relative); + let phi = slope + * (f32x16::splat(0.15912117063999176025390625) + + s * (f32x16::splat(-5.185396969318389892578125e-2) + + s * (f32x16::splat(2.476101927459239959716796875e-2) + + s * (f32x16::splat(-7.0547382347285747528076171875e-3))))); + let phi = x_abs.cmp_lt(y_abs).blend(f32x16::splat(0.25) - phi, phi); + let phi = x + .cmp_lt(f32x16::splat(0.0)) + .blend(f32x16::splat(0.5) - phi, phi); + let phi = y + .cmp_lt(f32x16::splat(0.0)) + .blend(f32x16::splat(1.0) - phi, phi); + let phi = phi.cmp_ne(phi).blend(f32x16::splat(0.0), phi); + split(&phi, &mut p.r, &mut p.g); + p.next_stage(); +} + fn xy_to_radius(p: &mut Pipeline) { let x = join(&p.r, &p.g); let y = join(&p.b, &p.a); @@ -656,6 +683,17 @@ fn xy_to_radius(p: &mut Pipeline) { p.next_stage(); } + +fn apply_concentric_scale_bias(p: &mut Pipeline) { + let ctx = &p.ctx.two_point_conical_gradient; + + let t = join(&p.r, &p.g); + let t = mad(t, f32x16::splat(ctx.p0), f32x16::splat(ctx.p1)); + split(&t, &mut p.r, &mut p.g); + + p.next_stage(); +} + // We are using u16 for index, not u32 as Skia, to simplify the code a bit. // The gradient creation code will not allow that many stops anyway. fn gradient_lookup( diff --git a/src/wide/f32x16_t.rs b/src/wide/f32x16_t.rs index 3cd76a1..6716a35 100644 --- a/src/wide/f32x16_t.rs +++ b/src/wide/f32x16_t.rs @@ -54,6 +54,22 @@ impl f32x16 { ) } + pub fn min(self, rhs: Self) -> Self { + Self(self.0.min(rhs.0), self.1.min(rhs.1)) + } + + pub fn max(self, rhs: Self) -> Self { + Self(self.0.max(rhs.0), self.1.max(rhs.1)) + } + + pub fn cmp_ne(self, rhs: Self) -> Self { + Self(self.0.cmp_ne(rhs.0), self.1.cmp_ne(rhs.1)) + } + + pub fn cmp_lt(self, rhs: Self) -> Self { + Self(self.0.cmp_lt(rhs.0), self.1.cmp_lt(rhs.1)) + } + pub fn cmp_gt(self, rhs: &Self) -> Self { Self(self.0.cmp_gt(rhs.0), self.1.cmp_gt(rhs.1)) } @@ -136,3 +152,11 @@ impl core::ops::Mul for f32x16 { Self(self.0 * rhs.0, self.1 * rhs.1) } } + +impl core::ops::Div for f32x16 { + type Output = Self; + + fn div(self, rhs: Self) -> Self::Output { + Self(self.0 / rhs.0, self.1 / rhs.1) + } +} diff --git a/tests/images/gradients/concentric-radial.png b/tests/images/gradients/concentric-radial-hq.png similarity index 100% rename from tests/images/gradients/concentric-radial.png rename to tests/images/gradients/concentric-radial-hq.png diff --git a/tests/images/gradients/concentric-radial-lq.png b/tests/images/gradients/concentric-radial-lq.png new file mode 100644 index 0000000000000000000000000000000000000000..c9cdf22210a23025b73901cf3a17911a293de115 GIT binary patch literal 18930 zcmV)xK$E|TP)PfV|=rH{u15SG?jzya4iwSKNpfKwj~R8}S0jD_(IUUI2N;D{jOKAg_4E zjd%g%6|cAv4+G@?{LlaQf59u>9etV7o?7GH(yw?d{-6K{GjL<&e*~+3O2DA0ID(yfY#g$fj}gMIziS7nglB#)b}qMFs;Q(f|_4Rxupi z3pDSG7eJnj3Wx!Q41@?4+(;^qM?tc(MKdO8ydhKowd)>ryMz}Spm_o2?ePN0owx;v zK1I)n6$sWy@5rfpO*S_8T~yXMWP1u6641=AFTgw@vVIjv2$*yn^G`1LSc~U@+khhzJI4o|Lw| z#@hjsKP4Xm3LrZo15E`C&SN9lMg>chVK1=!T7c|;LDHPGVP{aF0Aj?HHFG&ySVGqY zO)qWdd)!O;?%@WEo_>y#tSZvikUM?UA1uCHL3EHc4D(31rFy+HYO0Exi3c9jcT zMET^PXklHHOEbS3^Wdy$S~I}p|XpDMVX_r z3Sy(*3Y1?15C_J!(Iy$C^IcTXluzD>D@*JFf#3{t-jwLh_ZkrlU_N0D%Tz%I%?>bR z+inFc(YIt)VW3>7%T@a=K>6_iS%HB-CXaS(q4Fs+g@R%ah_*1w{EItQ*+&J+Beiyu zQP&eY3V0OWJHS-1FpJC%W3mQ@LsC|8pwO=Z%8v#}Pg3d}7z!d~i#;gzfVc&QIj^so zt1828M-^ti)?}8Ug=F7xnJZ=}GEM@_WIsw^;q-50m5zUe{2zs7ygNFAozLfY^Z{oAR6*_GovdRSj;$HDL?_K+mPk?QTFb0E6Ki znt`P0^y#Y zB)fhLK%$%)x9*QiDE*r%;X7bdwpc*XlQi>X7BH+?FaQ3wIKpR5+#>(Oje0g^*<%2W z0;ZYi9w>0IL}rPsGJ%7`+pIuoe1%B2IKEw`jQx4C>)QjQvc^&5R7}<021W}RtKSV`U389|KT9(M|vnjC{B6+xke2 z^DI_awy%bLbPIEBDP}~_WWX@P;5-45RKhH?Sl9qNWL7x?3TL`(K3)dAHu<&y z>08#YMvYz4wa1gd=sgb^*@5B=5Cl053=lnu#$$ad-8l0&ANBuT^K0`PodKqT#buZr zSsRc>yakkK<}W6@m~fflXknA@3X*RJ5N@PRGE|6>HDZx3%BjBb7!ep%M(I4ugzZ4F z0Yo+Edc0uM_n#jL=aF5#Lzn6EoN@Z;44Bcf6+*DP21VNb)NKC3}?7JM~3& z>BwSdlVjYfdEDPma(yd+R7u5j?_Oia8pq7}^Y?RLgerPsi)^$rC{{o$wGmzp&z=c+ zW~j*yP&0c3J`M|mhv4rSFgvhVigw~;u*9H{Zt^PwrBO`hUN?!CAiFMneG!aJ7>t)W zCT-05ev<3k0HlLg!>gpy)a@B-9H9ZL`HoV`fq})y;}#U&H;38@&&NCrUbkZlgob|4 zoX2zbH8HF%eLrRvanQIt;;pdc%3z_!>&%8cmPdYOgfn4%m0n`z`&|ACz#D9GkzGg0 zH7-&AMw07W07U&pEc#VR^)PF61;FFL@KL=hC}=b(J5C2fY0d#GZF7G6*vS!vbt4Dc zG{ihp>~kDN+;4#8+PJ&3%CQ9sGs=)&)47Pk)8Q?**yJdZYsy0@E`AqZ^5p^I;J|sq zs-%h@Vapl;815;QNp`@P-!YnWK8_U>84x+6Rcj-3hcRkXX>bOdIB3Lc9>`e&TMtd_ zG-H?@SlFa9t6av`8f}4cojetgdTilG zQXe(T-8aD^eq~<39Z&>Cvz5;?nr33!^6`jOVw15u&2;Ipx#V(R(#4m2WsrPHfN1fr z%kvsLa8yYZQ@83hc5*5Xb5|*KNb|V|jGjQD(k%nxn6KaApzV3-JX|O4LRxezH|7yl z8942lShedXEp<+}@wa?NgBw_8b>hD}pt$t1WoF_Qlk7SMn}kB6ri6ErD}scJH^Y~( zjQffit}h1=?TsmcBb)K#L{des5m`g!l!GdIj2$o#t*{vUgdH1F(D>+bYB>*-`iLXw zp48f25ZOQfOEyXC9eMSH zl<-b+WsorN6eL_!{CXhyQUHnIID#1;aRv@I>ny2a>UPH(o#oWNV7LGSlYD~E*a+Gd z5F`g&flyP!8u#QDF5eNr0fBm8=1Cf-S6eu4gb0>48g7wcGnG5deFcgX64}f*2;Id% zjI+taouq`b#x4hCkS(vWChjl_4(Q z8t#CR*`k^B;_qhu7vGU(R=(v`Rh@wZm#dTa?cIl3ViJI&GQ{)}3Kq#+nGBoNaAB1d zC@j6Ww$UN%Zef#7Jk$iYlFNNb1j(QIyorEInB*c%a$k4;z4$T!>A`bUaA+oLE@$9y zVC*DSe8%I9H3S4Vfl=9F2MUu@kO85$Ueh?9;qql5P4mFb71H(n*$*w;sl1ASk+F?^ z1&hisWtBZpnhbdCty^CsZU<*8_TEC|tq$iCv!9W0+B zU>2}kH+2yP5Tm{a3XaroLuT1d{)UupY$CgqJ!HwH#YG5g;`I`Rb_NN2F_8RofH(kL z9`W=Q9J~5P1_v{T$t+3Tp0S2zrH&I|L|@^@wbn<*Mhsx_+~kYPttSn7x=ywcgQX== zu_e$1z)-Gt2;0o_iGF1dl=0;GAJ9Br^8sGaAY{8N)5WNTu#R1&o=5HG-TvxNk)W+poZ=Y;gvP2#5#< z9r(DOzs4DGc4CZ|pUgm9jp+iK3YZ;O603B6=`|IgT-f!^hJImbG#l&%olSx_nUbru zA+NYuUq(k&KoaXE6(lVf_j!MS>m*;HnE1~ClE+qgg*;}fM(n^b|8`N)h*n5cMyZnO z7HjCS=q)&I07F2W-<9P`+<_9F2S3YR#UkT*@bE*Hi?psS4@TLt0vP$1L117}V?G)^ zGm4q^0F)uU{)m)fGcRm%UH%U_n?!FSH4#qVisiTno6o$#Fz=)AxBKtz_A=Y06f=l}o+o(taN#r81tNe_GE#_oWb2~#~2dDa8TS!Do4 zswXCwNcM2dj)ElXC9*5B3H7<3D!ITw!c@}*B(MR=fA-=C&u&$abnx^q{G;^mUk3=w znJ~bRZ|^BMG+Q;+-GO6g#uXe@QuT#3Ca}sod2a*5AEb&21qYQeW3L%3Ot*I9BJtDe0Wd?UnOJ*T$qJHF)=ay$_^+^ zOvL!iY{Cz{E1U3P^&q)O4#q(u&!^+1GigSUT*Q;)6tIL;+|kcUq#OM+)Be{0Vnws- z`Tqem<@3g49F^;=($-XN@EjE!UgJ=3U}m4K*KpS8l9l2Y+JNn&0wbn*l_@G1+_HAAL zMrM@=6s~*F955m!a^P2wW;U5}R5D$fiDC=QPqb(Ao$=S-*SjdIkc{4F3~;jmJNi9m1zl4FzInlJR7 z$2MQgMf}tv-}@d+yZRAHQgE^W;IB%pPX)+5X*FW!JLn{xyQ_1EJi7^w>NiwUS%a5h z@sTz9flD=Af#J0h2Sx^kCj`qBRT5Jd${1PgMbHCBlmFli+oWzqpi z=888y)3Sd+yg9~!h1r+D2}rsacPJnk>{rvjgAV$}kHkv*zmQs=3Xm+VMy%2*`h@5^ z2;wv6Jhlp8SLbj;o@yrr9Mx}BNoA~Iaw@P(1qS(k0Hj$!9LJ@B5h$qre=pbQR$y4( z9Maj4RhC z^EgOw!fo{TNa&ln*iHMi1g#Ljo0Q)Vdsrbhc zO;(V`Z!8gH*DQB$B$xXV?#a(U!hJo-I=T@Z4a^`K2S11KPVuz*5w5iRHBhNF+R%Kd z1aOj|!RHnbKLsG#i&FTFj+@fTdUE$2R#mr*RR&aS=$ieS({F&oM)4Xrs-()S(GfhI zOALAiMjWRFw$2EVeXueKfH%A6x;^j8Rc`5bb_8t!%gQP&ct%51=rC)ul;W+)k0>0N zBv;o%P+x*BcPdDRC&?*b23EsGQi>npFPGp){sWLod!xHj>yr)pCoxEq*MqjufV_b( z(h6Xylxr`(%~;KiIw(Ra_aSgZzcCtvGK6^z3|X(>F;q$^kaZh7Q1~zu|E#Y}1$fq^ zDQUxTg~$jMeIjtSYLQ%HNbN<>Q^0iG0LiGlUjj&Y zIQwYiJa%izYz0qIEA48?v((aSq1T%SG=7$0|8Rh4gNTi;mx5qq0xHrRulzm6e zSb2rKLwu2gH|jHRRKMZAWFAOlH_XG{(T^oflbe@7k*@(25Zq)D;%m8EjtAV>yLLf; zlUlM>HjEt$P=*7uF~0dvE*_QPwb)y{f*Xf}}4gU~yUFo`ffm$8fMN)E4~+0xnVu=U~V=NN>Ii82KlA zMM6fyjy5d*vsmPV8DwP-P1nxPfjy`ib7)&>CG!^FK_z1qSZPV+-UCOKRFySUP8G1o zIw9KzY>}Nca;8hB$?EV*i7C0TXJcMKVveJL zWLBhL0G9VZ-(b1%Bl0j*co77c)MAl_i(%(Z>$t-r{X<#g0~tg!S8#_tAU$-X;=qQm zm#o!@Dy`HAcknS>hi3J3!KsRR}jIl5g* zT?B0lN5BwT!*;-kMMn&*GEI446yXjTn?-g!>P;@e{2n(zGOp!uftlTkAQ_3_gFOiZ z(>^Qb`jp5{YH3!BWi9W=f6s~mp~FykKEmfa3@q&|yts-ewP6*yDisIIH}n{6t`tR&d9Z zD~svz?7`t+I0PIHjOaC7PMrZ`2Z{&?3fBc-Wsw>fJ~bd~7z&s@SST@yN-vdNTvKq# zbNH3vvN?1nv{u!qVPH|7+i6@X{0qO`I`dc%|(I1DtEIWjl`3!0>g ztZ|6PSWSDIy+kY|MnK3k^v{;_IlZ!B^sb5xQsJe;^%N|#H^vnxARgr+W`3L@5hTgQ zN7|Bk2X5*Hl3tDtZ=SLyBK&fb9gAoZBv#iiA2>$q z-2lH9z)$BXn_NtC@w=yZNJ#~W%dH8y zIeKUYYd)4AP7} z)Q4!JigF1cXRdCu2Lf%3xxb=xFRcLFcVtrzBGKINYePQ=hi1GmNUGJBOxsE78#JQ^ zJRKB3Ajc-&MEcPPj0zH5K6kVDWYbyN%lFx6E&`Oxr1f#UB#qtKM5R-eTsx3Z?45}Z zrt$kn{5cLY?S7tTQj6EghMieN$2Oj^2wFzV6BHm_gQ^L#E@ftyKftWN8z2e_@9|v@ zQF+-kKm<&Cm_1DAcd!b!4l;y|w2HnXdXg|qeaTkc0!Nfo&X_?0f@jMrFeD`m28j79 zHfYzPUdy>inXVNOmjC{0pV5q^&4Ok}ubC^-Cj^m2%Tz*`Dm2X{*8~ai__zX+n%x2^ zCLY|MCDUI02uN0IJD^s`t0CWmqt->VaOo_m>1p)|4vYz6 zdoi}M2*RzXY!b6t7~XMp=$qKl*SUzNV(Df6&;|A$c!DJbqtTT zNUiChuh&Q$?(ASlUrtB1{d+9p8LhEBvKd=Ks85rOcH91~=?sDPWUU-oQmugEuOBKAj31K}_YkA-@F_0WWwm*zN2i@ii)S|S~o20%Y)@3|<1>nD?djlNT z6Zu0CEOYxN?XEq#0Ami%LkGp@gt4CNkAWh`QjTvdJCB|44oJA8NY^HRHZPa1@w}f6 zT;A$DYa7_hy)-cBy%rD`Sq+-hp`chOym^Mg%LX%8@}tjhiFYu_US63Ig?ONlQoB6e zZlJ6S_BZw{b6W5ocJT-xt~>ubC}*wgM!2+6hKSON;<8(C4B-0PAm!~WrHAGRzy1a= zYGj}cY10y$jAQ*1K{3yz;SMC}T391);SK!pTGs0v?|~m%d2ZiW1R&q**amc6g76E( z`kV9J-9-dIY%@OZeYvc6Nvxf`(gRaJkU%24tW>JH-hG5`=YYNU*s(_s+Xjq1UFeZO z>&l^FX%WzDY-J88GAkAvnKj79i2Xfa)G(hF*kpUm0CG+-xgec~f+R4FnBtAplE#UU zh7R3g5dhC}9-)Jc_nyMz1o1BvMsNj_JL->=S#Ji29~{75UdeLPoR3fLC+2jSmPWdU z3*G~J=sv3VNc%o08FPJV(6d%{j5d6w2XOQymFu!<2ac|Q3as%}LfM3bP5LQF@^@v` z9zddXC4T_TucOzpoJmIX8!U3f={8)br49|iJJZ>2q|qoib(+@INY3S!%zA6Q2_Ty4 zjG?Td^D}dt$tz#C+w?RlR@n(EdrdTGM+9+OY>=GM7C6zVA@oO6eJt z6&x(7;7fu-!KQ6Oi z$!0Z(54N$)dRtR}mj`inAn!e_I0&2U6~|6qarUa1bMSN^fDa7ReZejE*c$U71?Pds z@>zImd`aa3grV~R9Pdln{;gO+BC-i<3b^`_E~B(K_3PKJ8g`R08y1P4a(6EYAer^} zX!2c|1(0fBDzjv5q<1if#+v}*tP#KG`JmJKGx91=b90_E6)CkyYvu|H7zB)oJt7Nr z$O9HBfFm+T|90TeaFFy9x#gxE7Qa!i8CT-hYrJH%ViE^EV;S$|DzkK3dD>29LCI!m z^yT~8eaO=QQU8(U)0*DRCl{B6+M_J;YJOhiRRjOQ%&_gg&s^#0g&Q8&LtZ-+iigT{ zU_)K2lkWpCC86(RpFiMWh6wP^_9Qw%m~n^9B0aDOg>-J0o*)j;%q-#z>~gBqrh-|I)4|O8PG7-&*pWLry>W5dwc0%sVUaj^@ORte(YtYrR&{tn(W*&t;Y$WApWGD%wi1 zJ$$wgc^V+J`QFdw-|!z!>9S~8KQ_cOc?Bot+$+6tecN~F0rQQf^mwoLbX}y?SE_To zHzsrNAVE9NeD1L*$PpPt8)m*|;Z2&wtV5MML1y{%S~SdUME1Y+A#vLf*4?$$XXA}^ zkh+OW3q^H@Ex; z|5=6$z|!+zkZ=^9#NNoOdhynLe)b;PgC@}ZAZb-YrB}-KRa*_wadhbB$? z1}?sNEEa8HXft)_B&s|;buNgtJgHm4_PX2H*>vokGvz^8}(Ig{q?a}y5qeBxp@(6 zTJ0^o{-NIy^5Dev0*4eX`F8Sg;dWmum_l}DvIqTW_RwG!@r+jVbiT}pET<`SOua1Q zJ_G=YBAC}Wr0P**nQYhY{kktG({h}(LxT6kQvf*w1i)jUSPq!>Y}8NoZN1pxg-SqQ znIL7nupUES3X3kU0J2W~4dBqAkPwNzeSI4w-~ZZpWnqXtylnz^_iWc_`{tN5yBPQP zXghW@sz(`ye@FD@=DbN{$< z{bM!yxZJQ6*cf^~!e@J$?;PCbv*xc2ZS9b7G1$3rKcM?*-DaNM&Sdz#&E1^#Oy~Dx z9b`phrnsE0g*z$U7b*NBN2O`X*R2N*q+?`}BQ} z|A@j!`%EjGkICAx+p|UAcMmnWx9n}^sTXhsU^V5sK5f>|+lI2NZ_|$J#DDzWSbd25 zM4zwA?5_11YbHx$CzIATu)`Z)Pd%fLd7=*JVT8_d>rX z9@YNq^{Fh#s~il z^ebNRv*K4X$l1yNMyq~y&cC{Wz$cwQJ~{oP8Y;ed=F^M)$awhN@lCUyTK?HK@mcrn zpLY%bQsb#E6KYr%dPKndDfZSzIR`ly`DIRTF~DQ5I7&Y_&|e}qj~m% z?WUg%7CD=Cdz8;_3Vngk8fVjX)1SFlY1wa*rJ#t^aI$d^Vl}NZT~veDZZf zPKP|JsKyEX^?P+;>?SK13U~zU>&(^iJVB>2EqA`gL4oQeQfx zIt^hrfc|kWw3BD+a;xHbHlAt+w;Ik41b1ZpmitXZ7jZkD**X-P&i8-oLqew$E*$y&i1+M~Ufmd~u*{?F3{Lj(tTK34M|lRA zM^54_x9%5s{^-0lawK{8cv{D4y`gWXve9l|xi?d7O1`Zrvwl8Em|T(Ef6(GT_6FU3 zS~c;yttw^pJIZS@5%jT<_1>@hf-)_~%`E3T;!ObA_4>;}H|dp4+miM0a-qEEA2%p& z9By5NT_$Ta>JcQ>hs2wQ_B%>^gIs34^=+=-D_s5GcSgH|q!$QaErmd3&8Xmw~-mUJZ5+?4Zl#dWSdm zx?R`L?n63j>9DNItZ);AMc_xXh+Gn5kJND>Lqut zZGdH3+^*es3P0Q??|_u8+6^Rp{#_hT0wkx^izH zfN<$#HxPC&$ShIt|U{%OOPdxJ4M zxOx-_0Lu4ht)&1&mXUiik~88-6IfvHcPfkRi-b~yQlq|V z)!jwusmjZtKLH~_dgJyo3krk8W3Mc7fpGDWkN@(6Kr(?4GFRL&j9A$tUMszR0DF0b zL0$nwiCvVy9sg0hWdsYk=hz!`2a+1?iLDI_f>B2d66nmR2OknO>E4H|hOC7Y zq3723GV5aV91LwS>zPF^zHjp)mmegxR9amyX0F(KTzG-R9?_hSYZtGjt+SC=<{2;O z2@&!{PV|<0|B>5B^dCEe?#YF0(BG56%KLgax@80SVys3TwnqK74+%ZFPNJYSsmdvT zVSk=3sat9Mc05T#dylz#5&acBZ8%YCU0{8`$9D>qQ&C#QjzHd@pS;Id&lxo`a1U*O zJDR<`>UO{4bPz)?Z9=xyp%w^r8)09ts0W!AR+|xjyNcWFCs)#Sg|(2>Q*R#|ZTzg? zBZbDH46z=9E&GX`%$nP70eHlXy%r5G;kbA{_hgsFi)a=r-e8d+7?1Bef<&49Di?7* zKbJF4xgpBAgLNn_Wq~&Av0h_mcDc5Q#?E@r0QT}K-g|(p|JnMFmevE?{uz@z8}E^4 z)`;Pb4{4Aq(`Y^<4Jb6~uQCfwX7$8AU@~hp>&?u1w}!v-BAU^Po@E;L01_yEd{ z!4Z8&%+y_iw91}h?>#P=WvHE)bC+ElyL-9Hs}AAE)IeW~imh(r^ZkeJ?+w8|#Cu@& z7+FrO^csCg{=3R7mQPh?@jtQmpZ{GHpnUUZqecgW`;ETj^SSq&;GihA6eO_eZ6ip& zvM0d}IO4fL07sNo7cu7P8i8i6dh#Xg7u4GXuMy0-UUR;8u*fT$wvku0t<0q{nEs1J#u)Tr~L%(9HcLozEHGVk#`ed|3(H0v7{VRoRL(F(pqa{A$B z)5XqjZpc8e14)}8`I^Sv4EYH-oGrN5RbQdf%B~5z{B(0aLf8Y(*~9Kn%siSo-^nXy zoY*#Y@+z`J1Wc6b8gKO&fX|T^|sdR8Q>vr6i0FukbkEm%sXA*+{Omg*q$|ih#d@SRb zE=Z@$;if$Mj!OW?1!9dN77xAdQ8QPqut(dl2SPk9j(G2%kykDF5wLA}66Y-g6d`Tv z&7m~uu}k;b=hJLfEgJfEFtAAM8O~V5b#Kk6>g*pE6fB*dr~VBS%j80z(Zi6~T*M@x{ z#!TDzbm8M2jmjGRXaJ*$nHIl(7(7-%@}DdZ^PKtw$pB}!V*)z(f})Z-6IU0Y$Pc=Q zN9FcoqF4At2?0T(Hl)HBb2^3bWZc*c9Q<89#|jQg4ZIZ@hTuM{K{e)Nrkz=VC=B{c z-s7A-C^YaV{GW&VF%_1PZ_o&A--XpKTB0^*wfJ?10@6V7xG>_u?Zw3kXi{~I=C~%Gi=TzqWsZ$6F7-I-~smV;VkR}OW{(khwif$2NBQ;knhc2X?(!%gN#OcnSR5; zg2D!;r_gw7Z8X z2m9EIG^!m)grTle4{8D=E8M)MX=d3C^h@f1QeJZf_M~#FduslkfWDxN~~p&&yyOvyUEG1yXuQM@1X#KIM&WTF7QaVa-k$`y_Fy#j*gNBy0jqEtBr;6~hgX7?M~ zBR>L;)s(yM(5%(P8gP_Wt1;KELfe4&k*)W*#U8a5!Y}6d81@+PVF1~&$mm)B++Y#S zXlY}e{mNt!-!27DFj?f<5U)3nOL0MJ9lZCUiP^1CmQ&HRpMgaBWdljK#yI9=$u(|- zI2L5!Fr%pSn$;3hLavBAc#77~aj%zg^SPz(nJrvO@m5t%1tT1KUiTYOk~MHSwgbn` zlxu^Rnu83}$!rUL)Nv*5t?Ve(W;786(`wk>*xw|yAX~Jg;Sk1fm3d!ZD*8r)4pfSn?59`;I zRTLH~IXTp&-3|=bHmperJQxRJLSl>v482B8vP9a@vY(|?5@Q{-0o{kfc&_U>s zoqsrCAX-`_m$Jz;<@1KBm&ibw3nSM(7%XIU@5_KV=AvNcgmM|tm#A490GDYF3cbQS zKQ=0rQvlIOD{Ev)HLpPc$82~P+=4@xz_$a&K0&_egJqtza%q(ZBwnNqL=b!9k97}% z_7~V=#D@c9$098>GOexy$S@3kpb8ZX2jEs}#jF-L((Fer&ApkLc2GaD0m&SNJjarB z1IYyRMsks`$>?MM3$jZyR1qiuD#>Q+p&sC)fZ=0|ruYJ%v*chsy^l~yUOJGMb8r<^@P)%?@hW5g#g$Oz47 zdC#jSz;~9UrocnxSHr$aEzN56jUUnNT&8AIId>Z*n%x>H;CayxuH17*N?Y4Zwt);d z1ob9t)LC|MqdR1r@La~g5S#bJxDF1q|nE@A7M!_+(sOV(rDs%1|8!7H$L) zEXpko7=_1upkP|wr(w9(5T3vT$WjUtFdV)nRVWwSs^7q{T&ft~?AKSE)5qPOMepvNIifU8M&<0tOPA{J?4BvBEh> z*ijUa@PQ^@GC>{K#Jq_tdmtZ`JQM{e9)%#+J#<}ZJ6d!37Kf~~khNN+6&d&xFdsSQ>MTALApRVP zSoM2SOPYc_qG*0ZL2?m40tF;Fv$Y3Fx8~?6;6{NZHj--={N?doYs>*CD!o8F3V~PC z9V~n$YN0Tj^!t$|l>1e(`NUFdV+R%5v(DUOLEM(S@BM*K-D_9U9!3Z3n|VH9MMN-pFF zR)ih+d5*y*WU^~Mzi2>F=_T1{W0eS&c?Lon+B_W$&)wk25c5(Piq1h1rIfDQE?R3K zX9584&1Ku_H#`ewj6^AwE1si*W64-0Q@;8RlZ6{;75$P*tIsm#G5!LB+?QJO7D@qe z=SMO~*m{8dO0;e}g9K-0j4-5t=RUFP%N4ROu>ttPCWwf!Qa%&P7q%jUQ8;}~phZDW z15~hZ@(s;|IA~COV<{`sAuCp&4w;<_a+##fZ z^;wTDWv=)=*WfP@D{#_X1?Gr`woNFQ*k5Xsem*`$FDES%y@y$PNG zWkO|o6c&xnDiD@nt1^e%t7ozK`0#D6!c32&0z#)dTl4^iJup;Gov{Y*pQxH>h(l7) zQ@L@dx`M+~$=w0f;<&FowEY6ge3%AR{!MA6@fR7yrPeUN7s4BUBqV_3IrdsNkX69gX#oZHK-dRu zm#Bc4e~l@4J+ETB2T>`t0|o+w#vNHBriHT^hYdK~kY{l0D&?)1@>{+`-y{6Dq?N{B z1;~i_yvUg!QPXbe+R@>U%vKvir&f^gyS4Ty;Bf;F8I}UG_{c!wAuhz-V__3+D0`rg z0A=oBVHL?@1!mDuhOzJIsu0`@OrN{`q z4mRWfYdZJRVy4WcSi9pp5dNO;i1F6}GGdAg@gpE$Q9rT+$+%oIv$X+9GbTaHZYfA` zK3hH>hLQn}#4mAk$ragT)J(KE$c{oyJQbjTK3^_xkC?_>vTU0DN`M(3r*F{*c;6-x z;`0x_71~UTpa@y40t`3tJ+Msn8p;|`Qmtlu1xG8gO2IL~Mln6Sf+G%NSKsltApO|* zCje1D0<$~ssBh2Ofh1PiD@ZQWgzNI88zvrD?nXbGcQDDNY@*&|)=b8pyUHjYTdaMa zGKyA3CXB@DTnsGEEWGas7>$quhWpowWA8yC)FLP#umw-^Dtly%2n@|o>3&;bjVP%w zJq_69{&}6l47tdv2o7Z=xB(6W@+XhAx)=WhAS2|#BYvN&nf45lSZS{y`AR-Ws^3U2vVkN+UV|YN2DOVWDJ(nJVF*r+OQdW;08om=uE*Z#M`{> zL3WKp{e*w_^l$u)4PyX+P?uPN5q-)#ygNhx5dlZ=b2W4B}|ZG5SNNiKPk(Ab2eW@55y z0~Fblc#b9m5t$1!SO6kmNE$K~Ae^zoy}%@^AigW*1QgY$?1ACWeBWn{b2AQWodcZR zA~@XhC^#U1=gbxWtCZRS1B=(- z{de;$SyBN+GmeB?aHRDDICxokIb7I|FaK}jp95q>6VndlPxtAVsR)w)#FNDARs{)# z43{+S5&Sws^Av$i#GCK|h6#E0E!qQxM0$-)&d~sDG6JhGSR}1W>QFjZSr0 zfMdj$0LX|4654=7-;9z|z`(^s-oSXdhmFo1H;T{)d5}mhXA}1(Q!}Jz%KZ0b?i`joTc6>NhYjfWBy-1-^S!Hf6f@L%j9{9RrYbf5O|}Y@ZQ$PwBY7mg6hKVJ3rIBm%kqUbAdx2y!82TgHTsF<;&3*h zX|Bz5&!uJ5djZP9BYTPK@|jgsf`R!J*|QPd*pEJHOMvj6z{C>Vx^{rzzdg$=^54(U zl)-IafC6Y?4LFfhNcEX?I7#I~@*G<0Xz;b-i!q3U1cN8hUv}EnNydfN4A*Srn)(cq z>tdKF{$Z(+p?ktt7vI@Q+I7WOqfQ;Y^m5uwZPBPR# zzc!Q$58u#RP_l!ea0@s&JB zjV}oh4K?m_D2mld_y%@x*)%VI@Fgm_V!cG)D#|ixLIImJ>cjLiZh#YfZ&>Ob z^WPm<7$Tq_!5)qx_ar=Pmy6m1VmA#FC&|vdXGo1-mR~@zsivEh8WDl9l~dqeqs0u@ zMpE(P3~t7C_{di%0zML79v~wWBsAX?9p8k=&Y(&zua`KR=&+2QWY_q~O*{dLdK5MD zb8VJaa#TE}+q38M2R*fwLIee~41e|~VKg3lc?0FOd^d~C0-zh9;B7q)43SM`6fQ5H zS;MzcB~{E+{rlk~&&0O?$Os*~1(Qki&FgO7RdS6Rah$P<0EJX`0jGrBcxRx*)bNC) zu?nx_W?Y+9e3y_m#ta${dbo+4$*l+m{+^fLjsA5|#A$oRh^gC0Sp#4%sXSBleZVo| z+W=%l(}q4?YZ`nB2FW#i_$@YJA0o0#Qo_^RcDC*O+to9#C2wi>XV38jEGTlyO?d3L ziHa?^&yO(&2cCQ`aw^Oxn_ofU)1~2pH-2S|Ghjq%wquPbsdOG=jXeu;gX8Jk>A+Gw*!cV`;siVq`}Ny>@YU*OqT=2 z$7MyJfB=Ow>m~Awe~z>*U;&UOy8(>nl46#syxBy8%J+4Nyp+o*X3jG}=(aK_dH{uI zrF5M~fPukuU!?3$I@XlFMJmHPh+JeRaF~1j3nD=O&e2(V(3>bW_QBHxdMh9n< zE-zQ${eL$}RpVO&WP~?_$|lj9OeQed)o%iYx7y?(jwrvxcNDNNF!-$-4j4VEXxc3e zoLUXR+s=8H#d1J^oc{s}pz=$y-uSD>*a1VAlSgHKBx}U@_5jhi%_g%k(0~p94*M;j z@V2x`DXYxy4Y33HRy&Fe^O^@Y7k*(w1kH%c(v+V$zZhXSNhuVrfEX)N0#gPBK$cwR z!0`!5h7(WUi8veWk1BJpbT~(lT zdogG>^9F>4Rb&qVEF;w5`)Du+4L}xBEax;H_aHf?s}ol+%=zgB4l(-&r)&|;w-pGt z!1%s(jc4OW0z@OqE*{873s9P5o}!uOSN}MxXk(vm8l79_-v+6G;ZJ+e>>9Bw75?>j zgkjFW;Pd)6v$cXEvxS;({=NeSrkcr5jvoz>5!z600YyU0JQo|~aVTSzIj=AaFF&FJ z#wD2_L)giU?=|qwcRx?}Alp=L0R=A`rI{D`c$rN>(SULMcwlJ!cz|fEK$$h}<$b!y z)fAIo$|^jM|5awu?XG})R?m^86|Y;_B0u+@rPPSu0}PE{ z0}zcJQ0Du$h_Dw{LGY}UgN3)^Z(wwG@$G{;^YCJa*szaqERTDT^*m(l0){+44}4LE zaZnVa4&t}uMbW=SN}a{81BgZh%0f|MV>?XZ(vD_i_N8FeduJwRe)u*`8C3s^=Jb6)^6!a>9HJ@!re(dZlh zF+VMjt)2mbKUYxv>{RW0;subC&<3LtEP`doFqTvevh4EU8ohb<5{G@dCt~h3Tnw@) zuLm|=w^2dyl2G^K1&})tS!IOEF#g;nIZEhq%2|fLp9?B3SRQaM@b2+tcChUyK#X|F zr)T2@kSF67V7S2xXaEXud~IF!naCi?JwG9)frBqVd|bQ$^3JG$8G$+{q>3;srvQ3> zU(xr(c*&*DiWfjWA$FkAU{A9yeIEU(rC;%}@s^J46|eX;@nVoyyy8Z@0P>1g+=v%I zUh#?>@dC&zUU4H{0C~kLZo~^9uXx3ccmd=UuecE}fV|=rH{u15SG?jz{9p7%*%)PI R#Pk3F002ovPDHLkV1lPf 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 tp*=8BGC|`LXchm@q=Dl99Y*AZ0Ap