From 324bcf5f8ff84546d7881286d932ec4e12f64366 Mon Sep 17 00:00:00 2001 From: John Wiggins Date: Wed, 3 Mar 2021 12:53:34 +0100 Subject: [PATCH 1/2] Document GraphicsContext state --- docs/source/index.rst | 1 + docs/source/kiva/compiled_path_ex.py | 4 +- docs/source/kiva/images/state_ex.png | Bin 0 -> 49223 bytes docs/source/kiva/state.rst | 83 +++++++++++++++++++++++++++ docs/source/kiva/state_ex.py | 31 ++++++++++ 5 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 docs/source/kiva/images/state_ex.png create mode 100644 docs/source/kiva/state.rst create mode 100644 docs/source/kiva/state_ex.py diff --git a/docs/source/index.rst b/docs/source/index.rst index 5f2e6ad88..6113098c1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -17,6 +17,7 @@ Enable Documentation kiva/quickref.rst kiva/fonts.rst kiva/compiled_path.rst + kiva/state.rst credits.rst diff --git a/docs/source/kiva/compiled_path_ex.py b/docs/source/kiva/compiled_path_ex.py index 59aa6a095..e90558b27 100644 --- a/docs/source/kiva/compiled_path_ex.py +++ b/docs/source/kiva/compiled_path_ex.py @@ -1,5 +1,5 @@ from math import pi -from kiva.agg import GraphicsContextArray as GraphicsContext +from kiva.image import GraphicsContext gc = GraphicsContext((600, 600)) @@ -17,4 +17,4 @@ gc.add_path(path) gc.fill_path() -gc.save("example.png") +gc.save("compiled_path_ex.png") diff --git a/docs/source/kiva/images/state_ex.png b/docs/source/kiva/images/state_ex.png new file mode 100644 index 0000000000000000000000000000000000000000..5d325dd5f9dbd5b015a0511e636f9d9903bc62b7 GIT binary patch literal 49223 zcmd>l(jC$r!!T#h z`&;XLIe)_W;94&B?7g4o&g;7FXD1lyYmyK?AjH7HAko%RdxC+1WrF@kfCv1g>t)^o z21Yljwwm&@z=Hk7fC3BuR><+#+s3KA%SE@Nzg<}v+PokzSQ!_ShB{_%(`hgkD+=q0 znmTpozpuT|6A84$*+Hc|?CkZOSBq}KQz3G2hzfb{=>FS6#j}p1y?gfMBbl@PmjT;v z&yeB8aki#8xa=@;6#@{WRW&vn`hVJzSvC|Z1ne*v1D6T<5A3!YAX@Z~wDOFi)PW1+ zlrR6k{>fXmX-skzjy~zX2|uFK`sC#Za@Fbfym~qGYGXK>DP!K%Mpf3cPp^`z#9I>& zH@a0vv%z39{qNFj_OszwTGQ5^cwFZ9MC$J#bbCq!><;QpYFb*EqWZ77gM4r?1io9{ z@F%}1Y#;?pZmb5FUi;1ieEzdrGZ1@145ffd z=Ho^;=WUMcE@KrfyHcDawC}*bczZa|UIdBj)T4c;(wj_}LaCzl@a$&g>s!oNOzV%y z{t_@S32<54XnXnoRkbR?&R03%cz*)z5&Pe^H#cyV<|FTVA)fAIwkkQQeD~tW(_b|h zef_d(DwGeoW^&Zp)hGrRWc6YZmjEMSS$NEi>s{_Rjz>k zt&R!p6ufJ<@5dj$Y6VaGbHodq%dvnS*J({rX_ZX;|DLDv>!^cJ7t!;Fr%`d|3KF@> z_*$iTo1)&zU?Z9noM4C!L%t~gb`ex_F}{Dw%&YGUeOI>U--lbcUc$&R(9x;&(`4x^ zpk*tqZr5!4oSyp#DVB;lcl8=cjgt~l$t3^pJy`OwTmlNnxb!3Y@GJl1(CsI`P{{CW zw;T~Q4K1HCvUbL6e!7t^T@V`Y~e(K2CtqG&QpB}8g9$W6+ZqnR*1WI`Ezc-!A9OOYa=nA%p z#Lra1^`;N{*Pg-$hnj^VPgXo4996q`*c0M`XduvjGCYQ)VOhkgXq9iE<_dr$uCby> z)-o^H;om}nSO6!0>>+nd`<#pH%W3Iqs^}yKvtO+d=M*9Mw{IA7p&%?h?)QHLc{`6- zhY&w4$v-u*58ATsch3qI_xw775~PKTZXo{e;w4Z+!rg6!1zR5->r`(?UGL9W=~;f$ zS;U@NA1U7s)?xS2!I;uk|2T=srKxcr7ihSho+5Y+X0zJmQ>HNn3}^j#Qp%*EObEOD!-8M(R-sFE~i*S9-)TRL4mWP}@wZ^tCCB5-i$E87UoA-JtT5H&f z?i5+@lrygd5zK_TA@Lf~iw%XS*rDqMfi{*e>Pmcc*tN{xaoi2zcWqT*TOw`G|C1$< z)bs_ENWMX0!#qE&Gb+Oq%5;{dh*7*q8OsJr5JHy{aF3}hY0u;>-uBI3>lQwNuQmDu z1nNUA=WwI@6^~D2aET2>gB4j$F@itVa~8L+Y7C=V_#C*K^1r(yfoof=TUI&BfM?UC zil}L8FzcK9-6rGRB!B6pQ2J!~X}B6SA>cJ$|M-J{rmt}7BWnF0?Iol81l4P%)i3uist zY!w0O?FJ0RAj)pLav>`!anA95&^qp~JPAg+j=0fNUj`i=A&kCbdnR`FhV4hY4c8l< zGGjA`ZFnxN>J-V&xWw3hwscFRefe{WkwiH~(0E@WR%mkEWw+nHqeIxgJuTGi*Mhx3 z3QE0moTPpR+QBr|?@OJ_Dlca2k9b~S*nAOOTMR(OPfx=mie6G+3CN!?2G+dP_r-lE zC?<@00^>YQ z-9Ru{h2d=lSdpkYz+iM-Cg3e5QqHBIZK(H3_lSwv+Vom^JA&1#wI$4l2fSOqpOA9E zRJ;(cJFOaa&%?p=%i@z=oCn2--MIS8Zd>qB(Mp7f9Psz`mTSXK_dXRvMOVL$moZZ142xp3cMyuph7NvkIDz8?KDTC_rbK z*--&DBk~|k^W49BI*6F$K*Rsy14S6Kiro*z-=OuqG2fzMAWc>h`YDom#d1(csTMkE zp-4jYq5FjZP9_R=SD+Js^-KTlA?Om5#-dG_=Da;s)+qP-EXa{~ zAD)lc@@+A=D+@%>^fFF%>2T)3~q%m7srr91XdB$)>&Gtci@nigU6HpA>v1H{ ztxdC0%dllVj9R_emL40sT?pu*(&nJ2U@rxL5zHYdi2UGyOu2#)G>n{_;vfI*$J{jM zgP~-*szFS4G;n&#RVicG&$3=_|M1kjUl9VBf3s)Q~PCunEfx z;mzY3=l(SMm!cFD=bG4{s~sXiY_f?D+L?O18O7gZjapu33kt2R<$ zcqmZ?LO__z&gYbkkVq-?;qLXH!L}4f2f`3^`>hXpF@9zxv z7A3E?AmHMXz)m4z(yoZEE~nKCS=BDqG#<6*e+CUL!}xHbvJK>2zB=*>DYCAw*Lk-& zIc=8@4a-qsMe=T3Xa02!up-|hA9}cj3Wsb58@kBEj9Z2J!#D{c{~0gJ1WN(+MC<1( zPQXs9${^a+_<`TQjr{!Xm?asTHxvIS;UkjyA?51aXWgdv~j<;!BF4L1C`6z^Ni*V#iI;HkAUy9WD^kX23LSbXuJ;%q2=a=_X9#YNu5|JXrtecy3 z<=-v|31S)_EyoQ~m3`hlllI%$F4!{A>x>x~I2ii%xPx;K>>pIaEpWFkRj}>aY>hk7 z*3YkJcOZi|m4PhS=J^MB+7j?I+1o;QRn5UZk#|mgKJbEqmlBV{SP0d_O%8K&17sT; z|25Q)54eN_CTuzGEw0^7FfG%0$-b1K?6Mm(+ps?Ksk#G4-pb)c zv8yX2rb)sB(ORHS6&zBW>MVbvX8AiJQxFy7V9ckELO&SO>RiSkFj(46D{u>Vi;~zOFjft%d zomz};*Gc)xVnh1%rnpYWC}oOqxBg?M|9tj-9h`REWsikJ2M!Bktcn>MfWZ zl2h`FLtB_*b5)^hmGZ8PjgTu#f-k+T_+k=oAUA{p?hA9S34}k5ZogFY9N$o+CZ-RS z;P9)@9t3xsd|woKn;I7?tY{6(&(}3Fy%9aWX;6?=z;l+6$MA;bn8i$hu+{oLbLot|&O!XCpD*=VGyma-I7Wib!@N&Gg*!JZXv%W7) zqP*MuCDC!<`DbYgKgPBR`+ZaIYUAfgvi_D?oQb5xi-~_B%ed?BP^801oO}TX=%JjU z`y8mh!~wMDZNKq-cqN}7N|i;hgpc z+diqahpku<-@m&`^E`feMy#Q6sUgjwqSE(fC>@o8F!Z@9w{>ybpAfdWm6EdG|K@7L zx@D{?RN#kT*)FgU#bR%)YZYz8q@cvjviX3~9>yTh{_TyrUBd&Xf|EyXe|>}}r`Er8 zWm*&^B_`@hj~(p>QR-LlMNv>tvSj|$$XY;1pLPWYm;@jHjgu9*jII(nn>Uw{G9k?d z_~+Ui__{nKY-T$n=P5l<4--gr>YsF*8Ak@mV^&rP52P}am9<>UkH#q2fB3ldhCJzc z!B*R%q+bAp0%*S=s#yGso7}Ryo<%g8?;(J(FHaud`U3G!ms4~@WzsB8tbE&ioMzqU z^u;Tm-|z$H`kNU|2^N*I7|Lqul8G!YeMJnV8lm3H1Grik@((!ym?Bvq6s7|D_pf$K z9_qG_K^%KBgsY~NcLEl3utW-GAy0#NM`s_LB184%Xj!1-earXKzdYf@YBqAU_8qLZ zxy5Vpki9Ree}M&_q1CZw1)Zm@DfvW#W{*z9fuWANqO%E ze;PvsURxEX)0YE*{_KS{UPk;LWj>99LP9g_y9jZ9e(kzE)VqQ1=~GWl5e^j&O=Bpn z4)l`R2Oh|H?Q>}G3E6Pjk&a>R$}mdl?M*4z4tRY}VpYeF_O%RgG1G>DwMi<=F7MFmV!JK0_Yr7k_S;uiT|cDHdKIOpq&s zh3vdU>D=<3XDBrjx#hraXVO}!rz;q5JeLV%tcJ7vMG z2df?nm)n_P11}jxWvfJ4s+gPX^qikJ5NJ>{JaLh&tb+6eg3Q|#SRLVkw10~cLV=W~ zL(LL!gseuFFCPGDP?cPCTdZLiiWSjQVKEG?L)Y|IWMMEcz&D>5s`fcWo2Zy~j~lKD zmY&>jNJv=p1>N`ezcaBST?ai>vDHw9%KuyW-mE*j~&&ZwwGmfO!|&iuU6jKE$Bwws$FO&`mu zVg2Hfve-e^twbLnK^y{%KNK{WU*3DkX?Wg9xP=|vJ4IaB9+nn+b)_|JN$`%%(fY{4 z`uTzNJ`>S(W=W$0aJ0H~nU-|xcJe$=K%ocyn>VEwZeXxgg6>TD^&qsb>MfAf$-N zK8zlYB+9$}lj0>j+I{?;s6Nflw>{4`-S=RG9rBzLTm*QqOkbchEcNUzAz`L;ibPYS zYzRme!zaC+L$92+?T-WZDU##U>Fwxwr4E(;*4?L|QA5tA%+zWp{q3COue(d*(HZA& z7Np+VdP8-3TJk`K#L!R|L?b4Zs>(+17v( za!<1Pop~b6J%QIo=e;&s=~tVqni4kvp_4W8E=s3X0(j0V(1^!OIUMzO z2#*?5z6e84&zj)hgUVz5CxmJE7dZxHK<1_2pX_xXVL7vl)dL}Y}@NPyg4^U z-u0o?AAl?1D0%5RD;5Lj6Po6wwrVfIGPqZ_oYEHuW!W<%(546E2HuuksA1q9E4$eX z+PRTHc?atds%%F#K0v?0!dN+hIlFCi!6YB~;{d<|Sb?8VE`z%}bU;@)jEsoLvVk-% z9R~K4$NvCLw?XdZ}sHe?-<9a$Y4hm+s$JuvbBn zrXDrkewn%3NcvAIy&?bL!~FB-H{YV=MI>3vVkwu{s!hYMRiMeQr$`;f{*a)_3HjD^ z7hrOzs?|tA^Q>g&8>DpQJN}D8bH91ka&n`@v!K;okLZeKD#gVo)#dC*Xtb{8evqxD z`^Gna&o6&s9`OuNS;h{&m47)i0z?J(U%!}$h841ZVp#-jQXSW``2CZcC_N%TE4;MK zx1@d#+SnA47Qf|h4-*kp4qu(hwoYEp&9W$04-oG~U)kJ5;q5@aFy9(j#&4eO+1{^8 zt(xa0`3Ld|-^J)__3G-rDX%@8a&|`&Rotkmh8URzvr{MD5olhr3Je3l;*p=f0$yAn zeNM>Mc5!4*4k}iw`g@)uQ(>&WbO))3jUk6{MqAk1Qtx)0p!AMDO49$E^F)ZnHA`rs&%X+Xlh)A_G;6dn1D>~c%^I1 z(g)OdfrYlv=!mS8K%HjGo}^#-V9Tk?AG7Cz|9<-$rN(!39m{U*vxdu-=}ncH&LlOzGTF(pm6pU+OXr{!$(j2X*2;&8Jge1CbZ)(j&$1T>JLj z7=3)-animS`IcN;t0^KA#4B+1Mytu$`I-s9eONZ*_WR1sr6B{YUoK65%{ry?{2&^3 zrOJ$dxi8MDU5lZ#J-NEsnrl>1t6EbjiI>3zSzeG3AX~uQE`oY@eQ!MqYJvC?^omPr zh=`$wDgAZT)xjIv#R&9+~e z@9YMN3HyzW%%pXFM^@4pt@Sa<;8U#x3S)v76!3*2_c_1H~BShB2Gr zFh)SzF@6qcto?S6Dq207NfsATCTFfPOd1_$qpV(l@@T7FtH!~lFL$5|&{~AC9^lX3 zT$|2Uoy*?MV<|$|Ul-Xwe;6LeZ5}%a=+JnM4YH;jh|hfE8AP!)564DU2ostEV>HE1 z(&=RshuanB0x&Kz<|5ZJv__eZo@r`Y$M%S@{C2$#Wg#Z+h@i9XSnd3GT*~YL@Un;e zkXUB9@RZ5Pnu4k+Y^Cf*Lb1qSN7tVm&p9iILE6T_xh&m_qStxzQB8m;Sph_nK9TOv5?9Na*xC3B48Z zrpRDD6WZFDE7hxnk@_VlzDX6APu=E4_vsf_^~3uOPC!m95FtjhPU$ggi~WJ$&sH=S zxTmO>0@tmWW)dlA`$@pkPod_5^uovGQoib6xH zOx8m#Reif``2=8W)7mrYqGcPa%nT7Hy2Y_4uEo&-J^~Nxc7x9xTb7dR?i+q2QwsE& z1_yHi*$I^GiIXcDgZows+NNd*42kgUzYE=QcZR7j0O)z(oBI_fPX*rwqVRW_3rKpY z*7K^Jp(tH#+p*JmrWwKP)Lmjq)!G*DBk|Ec+nXOXe75LtoU3` zXIOR?Yy(}h-FaPziztU;g|dfBub;5p{H7~e^ril3t$;%?)eR`+GdZCRkWpP_nw?t0NZ7gFPTeflu;p^x82K$G!|L02 zB|-mahM?!Z#}a18M2YOk-dq`LPvj!<2Fs#pNLz)2Z1Pz6*U>9OW{Ra8GWdA#9^02)96p_#6k$A|#k6j?myeON;N@GjNB zgr|Q0y+Jfs252`TwuQ%Xwd4;CYkAQYi2G`06L!q9qxg+tH1`S?3en(**?$L#*t+Q> zw`?J@QM|oM%lN^LxFnNVo;o?_JU&Nwl4z)Cf@n?O`0tIbJ!=tXN=zIb7@$Kvc=RYY za_kCjLB}T_+x+k4lCdTKEV*j{1*NNiNz*?w>`|9#iKh^KXsDue5sJsJeKhL8fGpNg zy!Cp$IO_Ek1$w9SMk^JuYiX7sWp}D=6Tz!R+Khbj4V+s+c2~bfH`R?Iu*+AP*|rOo zf}pJ#_6%o^OIeEz9iI&T6YE>$?Md4OF_z8NDY^dPSsLy@1|x~o9jI2D^}|!kwde`zy11X8Si;vH+tqLlt**P(4YC_liG*I$)lFOJ*B$OQvbcO^ShOF$NjQ1 ze|9$J701U1)4LG|WMoRsX9Cjq$Y(=W_LGxrNa%9x<+7*pT?0Sn(%f><=5iNFa-O-T z*3mEOeKM5CNS*o}5KS;O@Dp2P@L_Sz-H);5h$P{AEQeq=jb;vNPs*H)>hO+iY zxM0v4;LKZ+Q)1Gl;bL!L!q+*vcvoEJvU(f64xyO0X@%H(o`=|b1f89^J7u~hL8~GT zQVUob|KMZ~Uv%ut10LqyzWD}GAXx5o8>-V)1PUBwKWmfC(`?RzR-0Ey@syVU78H#C@usp+R$rIqb3D^y$!Z!**k^cT|ae4nkg(WR*Vd16Q zoF9>-XBV!HV|a2oaj}M;eRounWvoz3={TabP;_xT8`x0dX~U|=lOqBOdXb*He=$qad)W|Ygf5IlWaK@ z3&c|uZtfkTNe|o9(5k)XV0%misHodhg38Ul*d|GDr$ToxmSOwvnl+>=H#80EwO}IT z1Zvua7MMyYm3Wk0s9^Cb!5(r-B8_H>zLzKiCvYgJ^7$VC;3&?r+=uP_py^Wz9e6Z; zC`0&zu8Z<)gAgNdj(DichZD$>I4Ids7Aiao#t2OIL6H#@I2IbVJ!O_N=nA)L^Hr5T zC0~PpUKy|wwg3^jRqoREPL0KG{m3nCS*KfZ5$~lo2}CdZdcbjkyWO(>{_b)JFAEDm zGhnrtMwRzTlgQLDnJp3f;siT2*tL{9nS}<}GAotC)aXCc_jPTJ?B8|x8{V&t0f{Am z^T)fb`r+f~JH&#krHu6w_DqHpC%xe*P(aejMQz5*KpkV1dNZ{3>748nEB0Ykibi_7 z3ek5fMRTHdAO~wWD4&j0wF$XiV6Zo!GuKMT;Vyo4-!NUgL>TxP{?81^5iNRWbu;SW zBxI_&JS}lPemNaEJ3qYy8J^qbGk~p0>M;T-h|ih9;l6%Tu#GOPi%8n{*7rj6Mt9$? zWV7!OkgWo(;MiMR=)VjC&8!aeW*9>USz=c#^y z@Wjq01Q*{3kNSoY`5ve8Sk=gdYY!y6Nn!dMenwT#t-67wV+WjRq2#9Q!r6PihfEC# zW$}9;TMh^*s0o)HSlk7C;fvK*#g&BFXX)R9_$MW;x`VnlyXGl@>}()P^hJp` zq!tHSV^W+x3A5*p(|>r-$QTYh8+iinl@lZHiO-}0PP@P;0Boy0MeU_uRr^S`hy1kY zPxw|o8rfzXB<1p6f5_%*fN^)N`I0}og|6MRD+&uhkhVLW^iPS=cmI{$m32t?a+fL$ zzyp`UWIHu*ww@VJ!-mDFT#?|YMwdj8nMq9aew7qAit<4k*^S_pSJ9#D-2)5H4(gtW zO!T=qHKi{f8Hn##{~nG9bPopurqNbsnT{q6i(B@_BhLRi0_;XqMCZ}_9--0{?j=6k zRR%`(wjIjRGeHP~V&&s~r3KpiIG?6|^FF<<%Xd4Q1F%{WuoRjLMuhFz++Aue-_H`t z$})PRwRDU7zgZ?KZx#db^CUbDLOZC+>lJRd0e8!z-K_#pX7W>5_#gs}JMZ8(6qJPj zp;7pgl(2pKVSaqgqkA00RK>X4WG`4^<5z{U`X7HO!Vi&rMVP#BO(OUfn z3lJ}WN%jUHg|SmS6B3Sl^66ZzYYxvrW!i3{mHwD5259GR3+&gIsdEW+os*y8{cVO0 z1$6NGDhmm6veE^5pRN^A$LjaRui z0k*z=2rL|hR96uyO$e|gwZ$G(%n|@j(KT~#6n$|nTdv12sizkYSb2M5y@JB?9O#Rd zTL1G_Q^bie#orkmxuN9)F#R*RE;9-(m8b?Y(Rq1o79a3JPV^9Hat{u&dMOF)2@quJ zpp?M0Gh#4$|K*`B6p$Xg4nu^ZFu4?U>hJ7M{{1QsJh^5Sb!CkCV;?bMuTi`zc;|XY zHw(FVVY1L>g0D@f_U0qs3RSd_D&2x&05vDakD&u!e7C`V`#|SONp;~8FvU6L9GpdO zh)cp&m8hQ;MGZ7G#1YP3J)o-gYk+cC-G}kVJp+f2uIqO#?yT%|?l$yU`2o zOP?H%*nKj1hI%}tCiZ~0$E?TvY^=A>$GWzmg(T4BmL0GbroilHTtd^g={#zkZA(Wj zX&0sc)qAZcE&%o!yuC{Wf)9Jzk+X_QvIy^Fuy#Wpl94kmuW%q@;R|}aj1mjQJ0#id zERR0k-2tEL@b<_KRJ-G-ehirLJ1B6cHb_Ad*Nw_!y&I(78qyNu&B#@Hvjrdgn;eGc zd)dmXp_bWG5JoC~$pBx^mmtyE-~!S%=tmcGKjqv$fESUHy%aIuo0~As$lxGkMRU($ zxSQV9$}LjsQI<^@1`#Xir~<>Ocpzt#J5lkt7)p7SuLNHNkom_GVQT84m<0H zeVFr9-IE+;#uh2=)zsW|2(SdV zSux@_^C+q_6;pOG^|!!oZnPCqG{sa(UOD|MF(;*g$_^ARgsA}27SD3;eDq@@G9$$9bZT853@@aV+MQH3%K*#(z z30DSV3_gONFv5 zeNF)QNY~nfcu0^xJ%_G-mQCmO;sBj(+6t(a&lOTc-%95>ssO5xYBC@OpJ?MgdB$Ib zOl=Pp@?&T#17c5YG4?RxVyZIxPdcIV4L7A4-C@*mGBE5iKSW}#B#lhM$4cThm&{Ax zcUUc{9So;P`WV8~`EbI4gDdP%WqOXsz$-CD+Gxj1LmsWw_4URHExHCeTC*fO0y<3hC!qI3JO{Bbl~)45fiKpU4SwShF?itqdukqY z(APjs`qR@ug?h*(9a_LaHo!3yQ6q4fRe<83fBg^aIMtSa=y`4!g}X9-2VWr?_rH(6 ze!TOyZOV0k(HGSZ(L5T+`U=@VWb}h=aGZZ%TX(HaK23dJD;Z|q&61On-#t7I_KT`C z)2eNWJqz8dJH&HM(65o3F|Sj-`axvVdPNJg?V&3wk6Gf8sXCSWzT(J=iC7jJLaiH| zy_OGT>p%q)l_TteB@x}TX7!$@Tbpke44hHHdy)oG80GvY`O%r}LHrV9tWnN;`evjS(OLTS!RMYT zV-qyT4aGwA_PM~*YQJmb0_v-pl)P)ciKw(~MV zuLoBi6S!oQ9FKv4qcY^VX0`Y8=BHK5QZVO6u77hU3DW5sa9+o=x0&fylFD}7Wn8|C zE-@q=+sYW2+v@uBy|d};Joc3Cl+^d-3YF0x>yTb45YQG?G(EMn$V1@{;Z&xto7Wqx zS+B#pb*ISs*0z@D62aV}*2!l6HOt;)d&(81;y|VZ{{DOf<53ETH+$~h9lHkhnUwTY z2SBfPktcGuCL+MSP%+eZN@VezhQ78Hr)Vkl(c*e^ps9@E!j;@7R2O4Zu$dKUZr0=a zoI>%P3Ew*0Ms@_1*1EQF;b4UFhkuVPEW_pWhg+ltcu3=t2ajiu3j>`_21*_nzUhDZ z`4h~7?MhD3gCTD80~$pY?G(r+n-3yWhjD$LJ$wkj>KlTatD_AIx}W0m7zip9-EX96 z95WjKEY^NmT^I>N)k7YeJ$R2gnjgPM2*wMyM*02#_39CZOPMm|ha{e{R1kY(zWVKi zdqJpDM8Mdn7+WX;G?7}ex|3pIycdntt10;=_akBOc>KLPp>)ObnFob7 zS{4A2dCq#h++{jX%Tr&jQb)#OT2hbEkNZWKrWxP|w&-)C^ z+*zZyVw&07S7}9_m=0ZWvS$0hQ-D-?Y}(3dxme(foA)UE9d)mtoAuT5wc12;I{T>g zl!D^W+O#d|xApO_>$-aCk3|XKt_|JO48hS$xvqVS@32Sbv~=Kx#{k~lx44um;v7{j z0t*9V80uhsPa62Z!!gvPoMn3XUSNgEz?zPDCLHVIkrivs#|fbPd}0m8`-y+w+gi+F z`YubSzN4BkZVNRK6yAC&v7sYVL=0lHHjd=i_52>x`a=2F6&$DkPqjNeiV4YQ^)5`H z>>y0bO~UnEPd6%KhcryHJ4_nf8fZc$dwzfQSH#9R>{Pof&gc^xVv7ur`B3Y&fw78a zUUSVI1ZM}!k@rvOdXa}2>FaBN0I?7bkuYE(s2m_OZ3h-2n`0gG<7>Z*P%*{Y{=RPC zsvt1UxFaRR>G1IcqsOEn=sE9;YlHm*E4ka`Fd%*U zpApvE#N;F@u_iJ+KdqO%Q&W-=Fu=X-nb{B3#&P1OeJs&BA}HcR%m);bhXV zV(VH%zbtMLGEtGvIb-hGee+MT#R`bt58J&yC}v>Z_6A^LO=Df8H&;+%4Q1`XrVo#! z{2f+~&|BU6bAd_aO(_Sk?MP?Dpv;)m;&Bi?{8A>6N2LxrBrFv7 z?)}x=P`(JSj zh6UQ4v!GMUw@{d}*x3A520bjmzo>s~Oq7bt)O-W^RYqB9_>mW#&nAsW3oL(hc9JbX z==~jt*Ri{wO@HbXGBqUxn+O0n>_^b+)Fx`0$|(-|G0hWt%m-7=D_>{=Y&u_3k=sOz z(47w!8CKqoxNUI0*`XA`PAiQ#cjw zUsn#@+%63};RP3?#Ms_fst}C`K=_|ukpIT= zjqU8w@R&LNCN?zkw$!Pm*aU2p{TpOFe;RJ0fT!;pBTq54SN z(}QdT-UcQj1JAWXGl(`mJ$ZJ+91vW%BYLSO%0a2E@SQ~(n`!9t6JuPr&uVLF&NG|j zlCe&EAkG}6%anJefGVmsuZSno^q8qGQ?f^_J$K@pU&Ptnlz4#BLqiRbvab{(Dg{N} zqP0Tp%-NOVDs6NZVvj8zRpv+Nh2rZ)i?n~U^b8dhpN<5C`Mjf9@BtQ>tFC*e;(GB-l#goIJ%;|4y zGBB#d@gE^~Uu^goLhvuYH2hqh_Yh&JcIBIKtn(Ac^}8gDg6isH%eI3xsp1=YXp;|^ ztEFQjWHvuQZ+zxwj2U|N?Y{FpvK3pp%}>H6#+lMOadTk&y~|zd*qoE7YcZO`6&NF~ zrarnD2?(cJDS^SS>zFljQ`fo|FaiAz5GbPVzIBJ;8w?B&MXePrE1k_I*_zvdC*Jsh zXo;*19T}#7R2r6j0uHgR0zI>+TI`dnM43gs%|s=_U`@t@d9Y|#Vdv3huWkkLItw6}&QWL%#2Nq56GikiC@bJuH1L zgp9jykGm)t9*;2^<^_}*6CO*tQ4#Gt$9OSAFn=%1-);cSVgNbzVRjGK3iw;>FICK| zahe~A>Fht_?bI9uKe{~y=6ZFr-*t{A?H9ySGo6;Y?ZQ?l8Rt3&yRDnQ)v$rX!OzY1 z&*!}TR&htq_L|<6(rl^&r<3v;NbIHKxyG4sQDlla>J_C^M@&_NiKbu3JK~Gak^p z>R&Aj?P-WWenA*j@~U@MvT%f-&&iW}yvO2u_3RNqr0S#(FIy)Z_j`BerplQZOq2fn z%lq@`72BpRz`R#~?)sMv&&E)k5mele)?owl5DDi8B`s%|yoaG|y%d=yI{7>%cr)^C zesw-Y(3e|WwjbKH#-*p?;EhXe?`e zzErlm7IDpOw=PmI|6{~(5BT=w!IxRNb~^XlZzZz4z>Le=duhP=w}gg>ETuuFU4qx- zWHgBAN@x0=Pc6Z0FxaZ|3;hD+&f5xs$cHgH1-bq#z_AVInXi5OtHybg`;zM^F;ale z0~9|HVJXMXtoAjH7EwCi&;BxB?|~ECK`bDm{JhxpnVXph%j`FS4n0KeRHkG`4pbI4 zK;l5J1LF1&hfu=hT{@3;2eJz+0V=k+F%c#mfdC&IC6r;}Hui^Xcz6kxh(88qKbi6y z8=E%c^6^&o!rKP6fT-|m&dKO=wOUOjtx8e4uRK@`&;@59?aN1j?On{RnHIr>lujMh zbm%7QYbFt?>yy6Yg;)T}s?E3r{qNHvKotS*rAbVL-6_zudIzL}_Zkd%OYken; zb~vce=5Hr0lld&L?ea^kPm^Mt^hOSk&4NX3O>g>Vb)rnMXwC+tIg!L!{68luT?aCK z6Q=z2i>U^4(rkz1VYGTgVgm_RVS2O||ALvCnXeGw#+lh9U~%A3?JQ1C{)UhPpezBk z{S@};1&{H`y2F0xN(qi+j&SNYKMUNV*_gJ|4!yVFq zK(m~{HC`b-CTz7%`H5REx<LNADs#KRL>U~veDszfL`{V!E53COK0coCHlF9#BDbZJKtS6^HFv}w2iff;$nrl!Z z_##ev48p$$kP@yX)|$hT9HpDtyf9O(x);3sYF!en$dBRY3<&AwaWs-)KoA2?`DFZD zHJz=K`Hgx^85ZXj1stF5d(ArUi!4sdESAloA$&o(T%_?TK1Pfo@a>d3py6~Uq|%0c zS3G}r8~sqX&*}P;(Vr4CQ#}OJ4^8k6l>lwrR`Ev1s>oA|_=gv!6sdf7`&LA$f_PtW z+HfnIs?)7=$Bu!04vcmb@@CQabd3%N1E<$}fWnWttfqB+LeG-lq=&iP^w0b=o&j;; z9FZRvpsvo5Gph@jJT~E3I{NY8vCng$CXe0~etQ1riI2K*R(cwPh8}a?H&X8+IN$b9 z*g`z=vKPL3{@nxg>|y%ae)1Qi(oafNwHKUW#7MxG(v5x_{r3XyL`^Pp_21QvbAU8V z1>*yX8_l4YIiB3NQ1e=CBOTlS*xxV{Jw{4l!L&r14M-~!m#+%~Hwl#2hg*tE3| zt+`P;wf&)@qmLm}bX!(hKWJ9LtCRv2GqDVNY}+?4n@Q71mlM8yKpu1dV${78j1)tk zr|SXi{K?oD|7)`7ONKtc%E|}39IoZm53vtd(NQgasV>Tah0*zODWX$}Ka0kY5IyI( z0JDyihyHwE~94z(Fc8bq1h;=Y7-jZ5!315&76Dz79yZZgbz*yx?mbaW{&I4f1LQ}Np$<(7l>ov z{##3S*Gw;idbLmx&ab(L@$W2j(Q5bcUB74jegVkWVRhAUQCb2eJbK3etb+4}8EsFz zF*n^%1D`L|=$Inw!_veve_&{iPe-=)^=8J#kCBt!_MguBhf?Lmm4Jo8TjLrI{oV>7 z1HI1tqT4WCI+}PjvSgDzIIZ46Nr1cXvMoNt9u^dbDM~telx-wdoAz>dqsf#kUTXV3hzf0 zX7o#U-)9ps+^E5@Y)1WyrtC*5ET(l*}XAoUjnzqvR}ydsn6k+Tk51Q33mYKrd{6r}*& zW>%_w%rgO#vct_=5;&N3!z|U7LjTBjPgy%k%8mupLfoa_Mryh?zBipgwYBdH{G1FJ z7mt$cW3p)$eEC>$46Ei|m252ruMK-?uf7m{dDy>t1MS&an^qlT?ewJ;etd^Fkcj8@ zt4lxtS1wxAlXWoS#C`N^>_-=Ilr+-b%LmolB!LAzb{&DIg`o|;)Qqx z%n*UXHk3Oa$wJ1rdX{CCT!y@rYxZCBeT-l^m z9BxvyuYpfdF~8vdVeKuWs%qD;Q91-kDN&RXq(K@4N$HRfkPr|Nkd*F5x;EEE0vWQle--IT5bnz15JeX!K*L4>Yw;#J6rZv`EFpZ zd5VmLRxY8g@=>*GYo|S^_?`c{unYfsq~WwkpDnMSqQGOC)E)(Qg2=fH9qn)JE|RSfR-1yWHW=d>o7EOJg3-uvgrUv2a3dZ!z;uvU{jY}axnv| z3%eB@a$Vrb%EB^w21tr4$K-(hc%j0la?g^81mZ?yt9l%oMS}hIl#TjGQ_tz&&ZE5S zuHm9tBA60kpt{*W%!^+YgTC>7W%jJDKk$CUi@_TE7ef_>T@+I>h0ujbEpaqd^xxZV z@JF!SJOG@jtJy_+1&X0n?bRPJ;^gyd!WBuWW$Pv^*g6OpMctyGiYoD$ASoEkd_@S4 zL7(MkrEUU~bg4-cMV(E2^yuN}IP4K@mcX#>*`2epVpnkU8V9V~Bc69H<*l1~&dA$# z!UBwo!Mo$Xgl;SP*2~6@$l9+8J>8q|tu0j1d@b!j`vJwwA7}>_ts8HIkWz-c*z3M( zCq*-Kg&L{n$(O?tC*sFPHoY&D$|lz_l3cLQ%`3wjdG%%>9^hquwMyNIP;<%Ehg`*5 z=Q3pDazg$ypw7N1+y8n-3d5rM<#Qk=>yCXgTyxpV!+IFltJd8uCSbb>THV;qbGw zt0%+bt_6Zc8m+)gmN234eN|eo$l*ncH}FC_>W%C?94l(}tESKOeXkz~ zI9ps$;3nxv)TRYFER4-t?Ni_(VDIV4mkpJoZ>+ywhQ9KW)X=$ey?mu;&0#*?n=oBT zF9>Eb!Tp>3RziJig6tboRT-4;msNk;U-w67g-zPYt0Ic{tq$LCKBE$kFJ-Frp$`_@ zyWLAwHnR%{@|#rfsI!RX>Rmord)Ye4>QahH4nSst>4PrUyPG@X6Aab*;ybUAp*j30 zcOd9j6z+7n=<_W~*CI6Np`MdIWv1!hsxUsI^%tggT>crBq}UW(D!IBNSnT$k zPq-molmnX_*>QQ>-=96$?pZKHoX5Mb6VIQ8aM50)pl+6}LBm1PIv&XO!g)xR8uX*5 zKw9l7E`YYi5+fY~taBwhb7}9749A-bRPB7~Fm5rQT_;*ve9EYlO0dpt-?DbKa8deG z-L-@D-_^2s^BP4Zd{4taK61I+CnHK5LU@wMh&@uWWK3RhEUKm#)l+~n#1$MZJlcs2q3BWUxTW-G zPfLw=NflphotW746~;f>yx5JJ*;P=zQ@QvOC@^Mue+Dh~{`wm>0v5*0U%XjEAB~rL zT>mM!^@B<&(+Z!C@WUc;zS^gu(&D@w<~Qa0^8;sU141=U1_r@{6|e7ictxVPT!pWT z7tVNeUgAW0WTOPL7X>WL6pvVfm8jL9z8ZPnJH9gT(b})ea^60r-MBdk$C~D0vfmv` zVs&v1e_BNrhSOPAep1aF2KH?8)j#>Kd}#j3s=yOF(&gQyk-#4slSe}SL%Mupf^!9{ z@F)iq2q4)Ih)Kqhl9o9hfM4%ei@o;1dKR7y{&V#PJPcH-^@^4Gu-=qnAYTBR?334D zS@y(mc=wgMBZ|d6AHOxh5MUTT^W|=Dv6{>q4(o#JHAl!8iO8p>M}Fm0Tpx(Mz}bn;)Yqj^%ZR`6opSW7 zwrh1UHIzo15UMIUXQa*VD#Kh9LVv*FXqMb|neJqM~-*qxIl(8bs_( zyZPGNT*xXsIX@y@Xj!XhS<`b-+m+*8(iKY^K7*g;S9H7Hy=d}csOm&-Sunn5rR8(2 z6HG4BWt9};^P5-?uV1cf9K0!4`t3n8X1Xa6obPXbC8cG#B%^<9#Yq>Tfz$wWZ+;YJ zHfRInKc*&pQsO|CQ&#yl;YhY6(`iTJL+IXaaHh4nS1ag4jZdLOL?Pk7D~E#hBB&={3O{u6@b^B7eXv@sZhiyl!@r zERk2@wr=XzTsiS~Kv@d0GcP|+rC)i}lt z;Um6V&fHoe2IYS96%?R3%KyV$_Jws?aA#QuaD`8I`nLaB7@wM6C|&Cb5inRW_J9?{ z@Tk`+?8z623G2ihXIy;5M)V41z`G~)0wg%31+`5-D*=h1ILdYea)MS{zCpjr!`J1iig2o=T_>7XJerV5=+hA=b66>T`|-1` z@UeH7=rZUT+a&x#r^E!ma=yy*gP88+*YS`tuD&a|mq~qDtv#>U7dpR1rziE^seP{a zs%a=bC9p4@$&!Jxs{f{q=yg;KfS*>;uVKEVqKsg<*$h9A8LumQOq3jNOIo@7GHWq} zj@8wdga!jQSKTyIeem^2md6VNPYV4AH*XO}`A7cUSgb-HnJ{p{$I_X&{JwuI$Wu*p z#UvD-KtPzZigY5GOf=+Jo-q1fQDaq4Ndj^`0J|W%K$<(H84flOC!$~_41D|OO~lWQ!VZRz zhG2VJk!%aNE;J8gCfuH6&Moe4&Ct%_=3T$esA$mHSZUcHC2`Xju6MIkBl)gLHFz=$c|#iS+JNVZ*Z2XmaID6^rD> z2sgvh;2A($wo{H%+s>ht=ztQw{z9;UW&sOj@s^yk*sfinyMLx7b;)r_r3>%;dSK{g|m+GQ!8)NmCb zpY%fcW&G>@`5M0pED4Bwp$4$^)sw?nOi$qZ1NoK#U`InBYxU zYbD{-v-LbYA$0kv^|RU4@}k0w9W@~3f$Yqk$66SFy-Jp2PVLE$HCdyYdE7@l;g zGZVWReDiieB8_a{b`GvXn<#HHSL*d`ho+kHTM4u=>4mH@BpHZ>t<|2$G{&s|yZQX4 zMHWa+d7^%0@iQ;5s53Gl?5KTN3-&2LEIJ0W-jnmpeS^56czkdiqQNO3ip>cX}c$oAgmCw30rvKCsVa7w5>BvgXiOJ7l7F5}Ivej7|rV`>ZWXK!}>?%KEjx?v>=(`&R>iV%eD zA|cX9-Y7$FY;tVy8IXl=Q($4I{Khv6A9S|{r0kFehmfDEu&{ptCG-9}S7<7;bsZ*C zf)U`W9LXDb|45tS$W0eC)#MdnzxAXkVaXR)MTV!iJ32rbTtmHF%TBs%QSasE8t-V; z?Ud?+8yMurIB!@|*Pofi9CRNL?5tY)MA@V>fL=P-o8bXKbV9!zpQhN~T-i_(IdQRF zmV&i_hTL%V7#HxukKV6PDiVSpTh>;3FTfwGXPQLeScKkVFZ@lnrM~fDqnOqj6A0Bf zT|y%1{Yl8|=t8%9**o>xr9&86eKL-1s<22JI5eO-Sw*(2$nPN(D^I$gcGdX9etg9w zKsDl}B^(VcJ2rreNlj@D-ocdUYivUSk4USpF?G&{x;P0CES;pL4;i^)ROajBP-FRn ze3e4BBcJ)x6$8*!xnkL2HZkP8K3X-a)r9C4kB``rMNH9Xbw4A}H?=6BV$xGH+d_b= zl$e=wO8$e&U89}vgAMuS4XDN&(Pd>Nj*(mC zi;N>rnzN?P#@1Z8f zycj{7Zo6g1q6Is53E&S<^29tY;S&%o03blb-KR#}{jlH@qvU8$44Ca-e6PS@q1X{q zDnhVd^)rqPYB!RyC4mNAl>G(H6Kz{vAh3J6NY#lbWQ`Lzfo^SFIEirwReC1bz+KXt zp)bByVT9SzQ)J>oJtZpaWTx&4F&uYh_Y{*ce_O7U**bun)ImDzfc_1I+x$ALIW*Va zdOeS%a5FvpUGS8B8K!n?(*gN+Afjoc$0}{p?j$lrcMyeB0$+G;zfkwWw`0c!$W;}r zYhpk65Go^pe2^2_9@CJ>4CYuVys0&&>#iP&3^`K2job*KKUl#M`Xiw**1}4H%x9Dq z@)vii$i0qorxrg)2>!M5k_L0$V2&B=RJXntT6cJxHElby80{BR?Ngq@IE(*#rdC?R z54!nOl@<+WoOf_n2+__)I+Qa0=dhC+t~Pye;L6#6E#f*)IAaWn6k}Nz0K9(;?+Aq{$^o0S^gX3Yvm~W}LSHB4(Hli%uCx{cjJs zMP+D2fC9-J$6!f0q2Q3Re{I;0mQ?8_doT9G+sMVXS7`yk0ubq z`5P0KoQ?Up(}zUrD0l8K%QY4GL9i+jV#F*eA@f@nYfS2XO!E{?t4KeRNlHU9a+_U{ z3^6hzDY4*a{=ue2mU%ua>8zbr@t9gjrd>JFx`ojT4SFBr`+H8RMlZT%x~E2^nP_K% z2*-$+wlFCI7_m&lTNkW(5CP-VudEZo5L{=AHCAU2eW1L3bG2?MGBkR*Q{6H(O}<$& z`nFQ>z1|F7Xa~`-!%56p^~FUrTJ*neBO2ez8;PXCuhu*cUZw5hu<||p@U|rKfLD-ApIJH$#Ja0l>jFDXZdf$<;i{ADwGI1;k{p=`2 z4^qp%DCkjxwHiP|ozyGeK1PS3U>VJQI)eP?I(@_o7CJEJmHa$#? z#Q0(J1Tbf@A%gFLlm70K{~Qhpf(;}r>Jn8tW^n}T{KXT8y;myv;XuF?J;A^A~T;+p?D90b3pp@?dK0e;edXv6)oG4#Y}vv=}sDLp0B?!(^AlYuocLIZyc z2UK7o?s~Pvw0-*5MT{b;@vs6n8>mpwa7ax*rUetZ$mX|(eB$gOpVs%J6b=jmqocV- z#oZ*En13Hi0-~sK%P+9{hQIp~=Ox$bi}>OuzqlCv)t6G~y#MuIKrDT!+&{PVL!Y(< zBDp?_5o}42dH(;JevSw}h9BVoFW~>zj}W&BddDj?2n73y-hVyrWNP@ftW7Yvc*1pC z^JT4xT7D}cF#p2OBFnx-d#a+_WiOR)w;SI8d7deEhe$5q*yjKf$r}VKq&ILlA-^iJ zo5++}KAB{LWB&U2MU3;o#kO@Wy^?L*x3=%Z`CWVru_84nNL63M{X_*`D^|U1@ij)i z|0Pu`NU}48vH41vr2&Mh1WX5f$kQB zjfJTeP>U0h!ME~%T9zVHYW10QB-;P6QeUu1bCOla=fx{B185tLhlg501Oq9(5N?n7 zl}{p{Sl{2hq%(hk|Nr|72CzFfc@brg^ku$8umCuf4}Nld{#t?;KtQxYRH}hTP4^2i zeT3J8XA^W%VAumuK(K=rCyx~cG(jYZW$OQMhp8MRhJ@nth{*UTd>9UUxdMUMOx9mH zy{sP^2zK}eQhb$a4=Zq5A|pW|gnkQBksL@ZlhjASPza-?^KT>8p`r7yvmUH@o%r0K z1-OV?h>XWSa1!PFPNSmHF`S^$-HglSzW|5+I}hy8zIJjcX-FxDwSfQymOVTV%!tVd z%w)b7RFZEqaqWDB<)Yg$LpyxM_R?o;>*XUKFYAlJAPZz7q6kPo{F`td(;}RY`QKWT z*LPGR0%ix4+N#T1`itUc`!Yl#-Oz*^@ED1d&izOO^bv94Kr8_( z;O*s5+8cMN>8KFJJ_gp(ztpf#(1A@uM8{6f$k1JK4w$k*IkuB=-B1^*oXwQ$jf!<0 zxbJGugX5#rr4W7SB_P3IXknp}R~cQB{RQR#U-9(UD$jxy{|Y%CN!47*LbE^1SV}n4$^gY)|O}@L_#CHCjtqFv~?N5hzK;+ zpfVg@8%%O@PM#{$WMP(umI%O!k}MkzDclUu6{)~KuE`Y6!Y3w(VL|*7&0htU2R<$| z2s=EYOUx$vq@-DGthkUh$Nkd`)KQof3LC#_U^j1vtAHT*Ld#l7iK*#+|8IJkgq(tZ zO)t@tPdxx^200yK{j|(`_3O05^q600VY7I~fL?v>Y;%v(BuPA|!Ea9t_5I}Q(PaaP z25!;9Mlb)Ura!+BJbIws;&@6mt4jk`nlOa*5#)PlX>OEj=mIH4;MR^jZ*1{80{I3|ee1=`tBl@ZLF8IST=OPjRcRph}x|$`No{=n%7rPN8!s$)sRWC@B*j??)vs$ zMo<|5G+(jT6ZW{oqHacRC>KWhNfN@C*N7_; zF)qw&PcArZV7DOGk_aI1YcR_D)0{H?OIrT6j>UX8IafhHP;4lDCe{O@#`0qeL%Sa( z^D2hoykctuGzNmt#_AoFM%VOQ>x7TE04N8Y!2{Sz;py!BV}if&t5hFmm_f*{Nj$J? zi1_z@(KucIW!hUlF+K#~@sd2;BFJ+2l)ry^t>-U_4!H@#MhJAv;9aDM@h!;SNj@3| zfiVZ%ZMbaTyVqZDeWLZxzY2A??d?M40?3G4mrKwc^!_{OU`Z{fjT?VScNy5Oe#8F7 z_51Ji?azP^_!=9wm;A|^)fW3v1WP5T8K7Q=EWkt_cegv!)lRtyOQoprA#ldB)iczcOc_a3v8Xhy!ssl~(m!;ZB2!`^vf?@KmhtNS}q=qrEo14i7$ZS_7Pj z(enMuS*-_=B^}$&#n=gen!{8HYh(fc)*t%cSZ(BE`W7YLKPcUQr!jciU0wowPX1Rc znIStQ$*Urc^#?96hNA$Q8CYRKzySOg>>)5cDJUm=9bZA=6&m?qM$_OTOb$m95e9LG zW9ZPVS76y_B$87tIT#Re4s!~r#0DItnQrAtrHWNu1j>%6clvt32i};I!KU`1lm28P z9uo!T-I?LY`}f>HNC&vZBTd7{(`<3w^2YCUVI6_GguDW!Xd$;838d%m5YlsdOR)nx zT)ux`)kXxYn%>|AJK5&jaX(}=8;5UL)N@kGuz>o2oDzW(<+-KB{l&09Cbf&cXyYO( zmQsdh^)_>iRquD~-9AY~#D^!tKVtH0B&rdct)L|Uev2_SF+*`C5a_t<4d~g>$$=3~ zm!0$%meu#CrT0%pw42P%MP9^D37qPxjNT29<2HL2#oQIH@~rvQiSGZLuJ4^_*tPzH zg@f1_frVcqQ!FMCM~6&1GAI(DcYf-aB%o({_-1#xC8;xdF$<`5GeoMM)#bPReD9M|q3OzIo}@$;~27%?{W+-#!R5H>sFW+-D%}B(*yj;naHsfO~*s7|L{6zhRLFJCvdvjnOYs-(+M;5h)c|M$JZT!lmY1cEC^p z*^~45yF?qA6h})1C+NL6Bad$;{>lQ4>O;=Vicgvv#=~6eRRb#^O*0AM%JI)-e7Fp5 z$qYH|08n?-hUt;>MB2$sXak6j53<4t#JEmU@}u#gOlfFQWSc)-G@yBhUpHHU@%57{ z1n2?5dS_cGNA@gU(efa625w+IKxtIG2@8dk)TB96k<6LcEC2N|O>*J=o0E1`=o*== zORwe-NE=^SzjZjLxXkMOCHw4^t!GG_`nQ}IOEcnMskkQ!!)i&Iv zqi$vw+BpI&3}fV$Dy2c3=tJ~mXkqZz?q;5GvCHsw%34kR^gB(5JQ>ikk#k%Hp0B5-{ac*n70`ntcCq)lvacB;{pnDC zD*}}JM{_&yX?t<1{OAK*espZZNw*1WAl(Z57IPXPZ?WC5b=K++S*Q=x2QrzM zh9Y5y{vXub_xDLT=zMGKuSqOt_@AE8(M`8)?^%h@zX2FMI*XQ{!|8U;B6N+X5??TM z-@GzxsdsU>E(io5l1g5o;_4v_B3k781?3|*Eqst1!2Pm^4hBC-4J0xa6X&pi1AGP& zm|rl?)e{Kp#C7jC$E!-uSIqwiRNy>$kd8>T|2XP}WZG@Vw08coav$%&eJ7EQZ%EY)@-r6s!Aq=|X2Xm((py6@qv4{^r|duIa@Wi4eUgR7lOUcL(5y8qIp?k zA#cZ^ja$4_$jUgC%`>ma zou#;WW+S|q!cwDKnRrMg4mHOsuCS#*T_ae{}`D~>?@cL z3nx1LLjffRv=qB#3yYTOrj2@tA4`GW$^VVVZS5P)#NWPxXa%^qD32my^AiGfh9fJe2z}pAECug_8b}-;Ho80><^M>{! zf^7Y_W93k+_5bczfjPS{;l4<(v%5{%13xV!F)r)o;Cqk^7`F@-A&~T^n?((M>y#Bw zC8)^N0VXTP&g|J>$!nN!fSY2=p#Kb$+oSxWi z`v1V(=`UDZ-H*F`NiI3~XI-|HpVWE>_2;x7YX)9p5;4(iCw#|RG#NSDek8Mxd0$f6lWFB3Vx5IdwLR~|7|2GE<&nI>`U%9 zaY(_5f}mDadtN;9w4P6C@0cGVmKM&uRJKD;c7As-Nl(d(ySBqukE;JWJ2+?2&FS_t zlF*2D;_UQ<8K0q!^K0rK8Hu55%!TdWBdRqzF_&h2j~qFN;Erhfg7qJ8CeU_aYX!E< zavlFPe1nV7_REN(!atyvh-*F(%l~K<&$^IJkq(tFKEK^NC&MgV>M3y56=;h+r4Y)+_>3 zF7sht40oMzvsK*nHZz)UAIyq*Oqu)o_$eRx#O*mSY;@k#7rvo>Q=pW0du+YXQT3w;H?S$5bc-u@wLrvaUc2{xi=$@kc^}#G}9Xd3QP18s{NezNLCrj<0T% zt7R&jJtmU)RlWmokL?S>(U1*ZECao(yO{_~!=V4M-7>eCa=h_R2P()_8Y{%u?ZuoO z;fdpQZC-2>DZ?@7kD8^Vc+~0K)p&O6DnJEvtfVZ!A|WgaFn_1V-l%PKUCP3T{S=6 zU6=JkwLGjKX>urGq0%a!+oZmk$|cx*UPQkeM8pykXRmZqKh=%mVL}8NOPmXnObReJAshwC=%Juj*+&UMedKcu0PApY0r}~O zRQ)ldpaJU&HWR3)!-l&h)fOWA^kV{%_y#FlhNC&i1r`b;o!IbTeK0x#^WX`i{yVq3 zPcQ4#5Twpq&pT|r^&C0jbzMdyB9z4#Z-58@93TECwf0~0-ob5MT?d(gR zg34Xr7x7FLL=LJ7n& zf^7{05l|?S5Z#c2QFrpq9bjM|3`JD5y5S!-lsQp%Y>Y&8m_)wsF+lQ%%}jKcWlOOM ze+Xea8K^I$6=@w8e?Dj!_HqeTa{>SU)s!)zGP0q{H7w~j?pA4KEhNoT9m~eHM|C8W zK?h^Tc8^T%MLasv3!oE*jTGQ;h#M5s%O=Vl$hVZPMkwj73PO`x(A|@`_zc0X0iObcTlNMBm+;uAB*E_Sbz=F$%R5v` z);fC5gT3{s28?&~^mW~){1v&Vx4NR=ODo)!yp1^8H{j8Ca@aPS>1}|6&8>f3r<`>x zwJIeh@5r9wGs=i{uIhI*jXg#U8T4=73`{>n_-ey0HiENa{&L6gw=7K1j)O#v&Tb4MB+pa>tQ>H4Vu*hfoH{$poMMtok(_``U|3Y?_f%m#n-@GV) z8I&|~Rn!+w8^J$b4&dq2nVzq_el@bcCP0#}nE)$e92Za1h;RQ6P=NbFeZEpj4Xkj# z8!JSl98af!)-;;g6ah&taQ^cHZrW2-P3LRhy)5W+2zE2(?j6e(-YAMUvq=@+Zw!`Z z4}G%2QvFmi=rJq2n=w%VPMq!6P0od{0eri^TQ(3Jq8wWkY_oTg6FsPY&S^EnfQ;ZP z7hr+CCW8afRYpv4BpAX-#ju9Mv=3JT0|Zqt28<_o$|%Z){h5xoF9Efgg*@Zc;sUCjjsZa z;UDMb!XM+N4|q1Tpg;hoabz)Qy9DA+z60a_UMiUN`M0|i>{+~T^=UWpIDI0)+0k~G zoi8%O^(!)!vHc((n#VIA<@Bjmd)7&wH<>5D^}Q?RidO8^dYtI$5?Jcx%h>0}esS{G zP1QD|!mFb!dw!7GldP#f1A@|G^WblWa3LhCISK_z1%O%T3+Gj8NT3jwV;%HvR zp{FtO$e}rBNQPhPWlN@V>~m-I%r$p(;2wLa-BGAfTcKk_yl@Z-GRU(L2m}aERyO|A z%4R5vGkH&nO;)%7mG|r*fu?(nWDtk33vgakt1+so2+Z%d?tO<4r4m{%OdzAgQl6)j zE5RM60_rNpYI`y*;V1b*wU2PPq0PgHmj}U~97rOch~^6HSQ`@W2E4}h@ER$TX6U2( zHn)PKIp*HgXeEP98XOG2#i0V`<-=lV>4-|7UHF~|MeHdA%FJB1QHre$J}eCI?%2`1 zf1_B(4EL8IinKQLL#b|gmUNzXO^x28Vv`2rmq<9lIxDsKH0-0rqF7 zGKoJwSdXKr#V>NuMYyvQ9=3ClqRX&27r7CKxG{ko<(+SBPj{B?60=dE9G$*6#F|B@-97AZ(Ebatm}p!Gg>j@3ih`A*Xaf3(07R zeoV1uiuQfQ7Boa)x!*nfH7Ry8J(%pKBRdWy&LR;fNXuLSH#j3YSzri z@qUy8(uXd^yXqKIJqT9+PncsD%)lVUbzJ(1aLeSF`~`@)<_)V?ldF-)NR>H{M@zVPPSbM!SI`;NrKh&(2qzF*RxcX_4O&9^urNI;Io=gM zYRpJ`6go%)4~KfO+|aS}2bBPZ5cQmE0SzUdQ%mhD4B^%0Em#sLkMDx8&p*6pMQ||6 z;rXrQ8&i~}S6svaa4fm+6oy2UKEmBp1w4u>%0%q8v8s7Tlu4RswtS zj=-RB47%D)$a*eLBgFm6{L@R5^Ezy5HJYTPJ5oEZ?wjp ztuD`v46L&-aouXhdh9e>hmIFvLUCp2_}H$N4lJb)dsgO5YwYTDJ~l7&sK;KW2N9L0 zQ6pYp`FAjDv)C&_ukaGP6J=<;EDe5M&!#2fQb+K>Kzz6f1#~mu=Ao}mzyU^1>vN>2 zowqV$(#{zguD*SW0t!K_x8A3}-hwn2K4@;%$mUe0bt&g-xM`SD-=0@8ytOmyKqiL} zXGgu{IzAbr>YK{Sb8W|4IBF=Go{<+;{4oQ7_5Nd}aOl+8DK@1B5Y~t;DH@fSfyx{*!`T{^cV7iXO zRKt`&W(-D+;T&_unh*|zJ995;#uiAKKPwdtQn7xG$W!8<)I$UcR%&p=?gP|!UE?ZZ z3oFTgv*&;yjErwVJ^4~?B0PUuc9G$fKGe*Lyog*a^e~m9E9kZ1&R5*K5$Z2W*k1FB zP@0&j1Q`ywmjn2$S+S_w;xmpa_E<~_B&wOop~ci5sB~w?6St!BH7B`$q?>trXJC#F z-kHT7$T@6e>G91fy{bwxCtpl$jLOzsg9T_^->5(x-VHsG5Y#eE-*st1+_K2_A2?GR z?>+RHn}2hZ7X(*gCz7dIZQXxyDNi}x@+msT`I3vy9IO_wF^C;0#qQAmrF&(vhcjP* zPF>*hmE6M@Ap634wiKyqh=(79k=>s*sMaJ38x5flMeYc$}aMgzECN z$`4;~T)6_|=&-?jINLcmb9*}YrH0NYqyR>sXGIDHtXv;XbV1m5oDC6~M==l)unnoC~MMz=h=ipvb1}WL^(S5H_io(#Zki z`yax|K!w#F_GGYH7}lHL2cr+QwHLXA%Wj9s))H1j+FiedG-pwU%K@Q*=8~FMnXEpk zA=BtxLBJI~gb)y3WgCZwS3aP_Wx#NF6y)C@<%0D*a(vslBp-@10TBgU=4)LcXCfrL zf8NmoP&~;}=cAW1!8pGD~<+Atr)3{ei|A^V8Lq16d9eJ=7_ZDu=}1JC%Ct+z6*r=fMPbx zZPd-X1g~X{EWw0(Yd>E$4@4=T%x|9M0^SArq@UiCBGLqY3Xv0Xxp@KFenMscp&{jt z$|=h@-F7YbMpkK;&x-+ESc?+75xqkXewuBksh_XjgK4?_b?2x5aSZsm1iwHU3Rb)Y z7-ah}eWzG#o)EajRNnnoES2hfF3~YkjP{NSGk#41Ty~G*{<`X^jFp@CR$#3LP7#4^ z`Vr&yKR4%Ez%vv zOSx;}=rAwYy9@WhImEBdPonR;GKLx1rU{fNyuyV=Q1gOM*PaDjmCiDh*|Nv~7jH=O z=Al>4qF=Aoy=g6HRG_@!#HC+jnz{Aax)}qtcqTn&n1F(3VK0i9SX+2s+s~q!CnR-D6d?(-+ zOs~>{7#&X2GzoZ%4lr)}LidkFZ&pn_L9($(!0krMe@@j)l;e%O)vMG?KM+6g`T3Q( zce-#t@36NP*69H%scJ_O1OpMWyjdKRoY|!k3b-Ux@32GP`{RX#oyH#rY%uWgpMN=` zpB)K-Ck~gq7z%rZuSIK#YYEchPsH2mX2tU9m&(jyHHWvo8cXF=x|Me%;q1i16s4O%F3}u| z+5AnWbtl&y8v^-sQJDeyfd}x$!l!t7l>MU4XjKMhow={J&lg3(j&LD^EDU0W`dTXR z3Jg4-_#;jjqkKfIj?i&Jt`a}M)c<=$i*5uW*bAy3;@E@dI&w1!1U?8`!w8{=%F&ss za*pArcN-Ry^v8&N)uget^5o{RS?w=q})oiG4o)TBRpSmX@_$G1l#b9OKXv4_Da$781Noeo7|xP6~p*YdPKY>aTf4P$o^+??zJz^b&;}o@tLR4aXyF$*LqDwQ*G6M^1cD6EfpP zkAh?)bbsu$!^w7~@1cZTp_1z_2F&JfOcE_?Jck&<$U2|$ajS!Z=rBNnBxjN}V;eN; z13W2&7eQoBKqcPchi0F$K!@X{%&T|?XXn&uN5?x&G)JC(Go4XSQ#f3zvQ>OZvb9KG zOp5y6^4hem+u3+;BOna#`g(DCV|x7FwFI~5)naEBat{3Cn`FCE$jTYfZIAMDuZ}%+ zZsJA?4RSMiNo2s=CH@4j>{RRQS#wButLxe1VpyJ@%TezW!=*RJOIKWuT~RbY;={X~ zZC~ViVdLu`v0R*`cno~CvFIQOGri@E!zOe@jKDyp2zMξS8C0i5 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 literal 0 HcmV?d00001 diff --git a/docs/source/kiva/state.rst b/docs/source/kiva/state.rst new file mode 100644 index 000000000..b17f1b03d --- /dev/null +++ b/docs/source/kiva/state.rst @@ -0,0 +1,83 @@ +Kiva State +========== +Kiva is a "stateful" drawing API. What this means is that the graphics context +has a collection of state which affect the results of its drawing actions. +Furthermore, Kiva enables this state to be managed with a stack such that state +can be "pushed" onto the stack before making some temporary changes and then +"popped" off the stack to restore the state to a version which no longer +includes those changes. + +State Components +---------------- +Here is a list of all the pieces of state tracked by a Kiva graphics context, +along with the methods which operate on them: + +* Affine transformation (:py:meth:`translate_ctm`, :py:meth:`rotate_ctm`, + :py:meth:`scale_ctm`, :py:meth:`concat_ctm`, :py:meth:`set_ctm`, + :py:meth:`get_ctm`) +* Fill color (:py:meth:`set_fill_color`, :py:meth:`get_fill_color`, + :py:meth:`linear_gradient`, :py:meth:`radial_gradient`) +* Stroke color (:py:meth:`set_stroke_color`, :py:meth:`get_stroke_color`) +* Line width (:py:meth:`set_line_width`) +* Line join style (:py:meth:`set_line_join`) +* Line cap style (:py:meth:`set_line_cap`) +* Line dashing (:py:meth:`set_line_dash`) +* Global transparency (:py:meth:`set_alpha`, :py:meth:`get_alpha`) +* Anti-aliasing (:py:meth:`set_antialias`, :py:meth:`get_antialias`) +* Miter limit (:py:meth:`set_miter_limit`) +* Flatness (:py:meth:`set_flatness`) +* Image interpolation (:py:meth:`set_image_interpolation`, :py:meth:`get_image_interpolation`) + +State Stack Management +---------------------- +Graphics context instances have two methods for saving and restoring the state, +:py:meth:`save_state` ("push") and :py:meth:`restore_state` ("pop"). That said, +it isn't recommended practice to call the methods directly. Instead, you can +treat the graphics context object as a +`context manager `_ +and use the ``with`` keyword to create a block of code where the graphics state +is temporarily modified. Using the context manager approach provides safety from +"temporary" modifications becoming permanent if an uncaught exception is raised +while drawing. + +Example +------- +.. image:: images/state_ex.png + :width: 300 + :height: 300 + +First, the whole example: + +.. literalinclude:: state_ex.py + :linenos: + +The first part sets up the default graphics state. Here, that includes a scale +of 2 in X and Y, a translation of (150, 150) which is affected by the +preceeding scale transformation, and some line properties: stroke color, width, +join, and cap: + +.. literalinclude:: state_ex.py + :lines: 7-13 + :linenos: + :lineno-match: + +Then in a loop, we draw twice (the two :py:meth:`stroke_path` calls). The first +draw uses a ``with`` block to temporarily modify the drawing state. It adds more +affine transformations: a rotate and a translate. It also changes some line +properties: stroke color, width, and cap. A rectangle is then added to the +current path and stroked. + +.. literalinclude:: state_ex.py + :lines: 18-25 + :linenos: + :lineno-match: + +After leaving the ``with`` block, the state is now restored to its default. A +line is drawn from some point 20 units away from the origin -- which was +displaced by the default scale and translate -- to a point which is next to the +rectangle that was drawn a few lines above. + +.. literalinclude:: state_ex.py + :lines: 27-29 + :linenos: + :lineno-match: diff --git a/docs/source/kiva/state_ex.py b/docs/source/kiva/state_ex.py new file mode 100644 index 000000000..218e3fad6 --- /dev/null +++ b/docs/source/kiva/state_ex.py @@ -0,0 +1,31 @@ +import math +from kiva import CAP_ROUND, CAP_SQUARE, JOIN_ROUND +from kiva.image import GraphicsContext + +gc = GraphicsContext((600, 600)) + +gc.scale_ctm(2, 2) +gc.translate_ctm(150, 150) + +gc.set_stroke_color((0.66, 0.88, 0.66)) +gc.set_line_width(7.0) +gc.set_line_join(JOIN_ROUND) +gc.set_line_cap(CAP_SQUARE) + +for i in range(0, 12): + r = 100 + theta = i*2*math.pi / 12.0 + with gc: + gc.rotate_ctm(theta) + gc.translate_ctm(105, 0) + gc.set_stroke_color((1 - (i / 12), math.fmod(i / 6, 1), i / 12)) + gc.set_line_width(10.0) + gc.set_line_cap(CAP_ROUND) + gc.rect(0, 0, 25, 25) + gc.stroke_path() + + gc.move_to(20 * math.cos(theta), 20 * math.sin(theta)) + gc.line_to(r * math.cos(theta), r * math.sin(theta)) + gc.stroke_path() + +gc.save("state_ex.png") From e85be534489fefb7ae5fc6baea124092b8ec6f3c Mon Sep 17 00:00:00 2001 From: John Wiggins Date: Wed, 3 Mar 2021 17:48:34 +0100 Subject: [PATCH 2/2] PR feedback --- docs/source/kiva/state.rst | 26 +++++++++++++++++++------- docs/source/kiva/state_ex.py | 10 ++++++---- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/docs/source/kiva/state.rst b/docs/source/kiva/state.rst index b17f1b03d..96f3898d6 100644 --- a/docs/source/kiva/state.rst +++ b/docs/source/kiva/state.rst @@ -1,7 +1,7 @@ Kiva State ========== Kiva is a "stateful" drawing API. What this means is that the graphics context -has a collection of state which affect the results of its drawing actions. +has a collection of state which affects the results of its drawing actions. Furthermore, Kiva enables this state to be managed with a stack such that state can be "pushed" onto the stack before making some temporary changes and then "popped" off the stack to restore the state to a version which no longer @@ -15,6 +15,8 @@ along with the methods which operate on them: * Affine transformation (:py:meth:`translate_ctm`, :py:meth:`rotate_ctm`, :py:meth:`scale_ctm`, :py:meth:`concat_ctm`, :py:meth:`set_ctm`, :py:meth:`get_ctm`) +* Clipping (:py:meth:`clip_to_rect`, :py:meth:`clip_to_rects`, :py:meth:`clip`, + :py:meth:`even_odd_clip`) * Fill color (:py:meth:`set_fill_color`, :py:meth:`get_fill_color`, :py:meth:`linear_gradient`, :py:meth:`radial_gradient`) * Stroke color (:py:meth:`set_stroke_color`, :py:meth:`get_stroke_color`) @@ -40,6 +42,15 @@ is temporarily modified. Using the context manager approach provides safety from "temporary" modifications becoming permanent if an uncaught exception is raised while drawing. +In Enable and Chaco, it is frequently the case that a graphics context instance +will be passed into a method for the purpose of some drawing. Because it is not +reasonable to push the responsibility of state management "up" the call stack, +the onus is on the code making state modifications to do them safely so that +other changes don't leak into other code. + +**Well behaved code should take care to only modify graphics state inside a** +``with`` **block**. + Example ------- .. image:: images/state_ex.png @@ -68,16 +79,17 @@ properties: stroke color, width, and cap. A rectangle is then added to the current path and stroked. .. literalinclude:: state_ex.py - :lines: 18-25 + :lines: 17-24 :linenos: :lineno-match: -After leaving the ``with`` block, the state is now restored to its default. A -line is drawn from some point 20 units away from the origin -- which was -displaced by the default scale and translate -- to a point which is next to the -rectangle that was drawn a few lines above. +After leaving the first ``with`` block, the state is now restored to its +default. A new ``with`` block is entered and the current transformation matrix +is modified with the same rotation as the first drawing block, but a +*different* translation is applied. The line properties are unchanged +and so use the defaults set at the top. .. literalinclude:: state_ex.py - :lines: 27-29 + :lines: 26-31 :linenos: :lineno-match: diff --git a/docs/source/kiva/state_ex.py b/docs/source/kiva/state_ex.py index 218e3fad6..73ac5e22c 100644 --- a/docs/source/kiva/state_ex.py +++ b/docs/source/kiva/state_ex.py @@ -13,7 +13,6 @@ gc.set_line_cap(CAP_SQUARE) for i in range(0, 12): - r = 100 theta = i*2*math.pi / 12.0 with gc: gc.rotate_ctm(theta) @@ -24,8 +23,11 @@ gc.rect(0, 0, 25, 25) gc.stroke_path() - gc.move_to(20 * math.cos(theta), 20 * math.sin(theta)) - gc.line_to(r * math.cos(theta), r * math.sin(theta)) - gc.stroke_path() + with gc: + gc.rotate_ctm(theta) + gc.translate_ctm(20, 0) + gc.move_to(0, 0) + gc.line_to(80, 0) + gc.stroke_path() gc.save("state_ex.png")