hexbin/0000755000176200001440000000000013616044062011531 5ustar liggesusershexbin/NAMESPACE0000644000176200001440000000432413171627113012753 0ustar liggesusersuseDynLib(hexbin) import(methods) import(grid) ## too many things from grid import(lattice) ## too many things from lattice importFrom(graphics, plot, polygon) importFrom(grDevices, col2rgb, gray, grey, hsv, rgb, rgb2hsv, xy.coords) importFrom(stats, coef, density, IQR, loess, loess.control, median, predict, update) importFrom(utils, modifyList, str) ## Generics and functions defined in this package export( "erode", "erode.hexbin", "getHMedian", ## document those; the method aliases are there: ## "getFig", "getMargins", "getPlt", "getXscale", "getYscale", "gplot.hexbin", "grid.hexagons", "grid.hexlegend", "hboxplot", "hcell2xy", "hexbin", "hexcoords", "hexList", "hexpolygon", "hexViewport", "hexVP.abline", "plotMAhex", "hexVP.loess", "hexMA.loess", "hsmooth", "list2hexList", "pushHexport", "smooth.hexbin", "hdiffplot", # but not all the helpers in ./R/hdiffplot.R ## Stuff in hexutils "hcell2xyInt", "hgridcent", "hexGraphPaper", "hexTapply", "optShape", "inout.hex", ## color stuff "BTC", "BTY", "LinGray", "LinOCS", "heat.ob", "magent","plinrain", ## Lattice stuff: ## high-level functions "hexbinplot", "hexplom", ## panel functions "panel.hexbinplot", "panel.hexplom", "panel.hexboxplot", "panel.hexgrid","panel.hexloess", ## utilities "hexlegendGrob") ## S3 methods for lattice-type functions S3method("hexbinplot", "formula") S3method("hexplom", "formula") S3method("hexplom", "matrix") S3method("hexplom", "data.frame") exportClasses("hexbin", "erodebin", "smoothbin", "hexVP", # could/should we keep this 'private' (?) : "integer or NULL", "hexbinList" ) exportMethods( "erode", ## undocumented: "getFig", "getMargins", "getPlt", "getXscale", "getYscale", "hsmooth", "plot", "summary", "show", "coerce" ) hexbin/ChangeLog0000644000176200001440000000424113171627113013304 0ustar liggesusers2009-08-09 Nicholas Lewin-Koh * R/grid.hexagons.R removed break statements, switch fails. Cow lattice and centroid can ramp colors. Bug submitted by Ricardo DeLemos" * man/hexVP-class.Rd Shape slot was not documented 2009-02-26 Nicholas Lewin-Koh * R/grid.hexagons.R fixed bad if construct * R/hexbin.s4.R changed xlab and ylab signatures in class hexbin from character to vector, patch submitted by Don Armstrong 2008-04-28 Martin Maechler * DESCRIPTION (Version): 1.13.4 * man/*.Rd: fixes to several man pages; note that gplot.hexbin() now is *deprecated* ! 2008-03-18 Patrick Aboyoun * man/panel.hexboxplot, man/panel.hexgrid, man/panel.hexloess: Added more information to man files. * R/hexbinplot.R (panel.hexboxplot): removed unused singles argument. 2008-03-12 Patrick Aboyoun * R/hexViewport.R (hexVP.abline): Fixed the handling of non-model objects as input. 2008-02-28 Patrick Aboyoun * R/hexPlotMA.R (plotMAhex): Require users to specify status explicitly rather than as the component MA$genes$Status * R/hexPlotMA.R (plotMAhex): Replaced support of Biobase class exprSet with ExpressionSet 2006-09-28 Martin Maechler * NAMESPACE: add full list of colorspace dependencies 2005-07-26 Martin Maechler * R/hexViewport.R (smartBnds): some rationalization * R/hexViewport.R (rname): dito 2005-07-19 Martin Maechler * DESCRIPTION (Version): 1.3.1 (not to confuse with the previous one). * man/gplot.hexbin.Rd: fix typo and usage for S4method * R/hexPlotMA.R (hexMA.loess): add argument 'n' * R/hexViewport.R (hexVP.loess): add argument 'n'; other "white space cosmetic" in file 2005-10-21 Nicholas Lewin-Koh * added Deepayan Sarkar's hexbinplot.R function for lattice hexbin plots * Added my Hexplom function based on Deepayan's code 2005-10-27 Nicholas Lewin-Koh * Added more panel functions, for hexboxplots and hdiffplots. hexbin/data/0000755000176200001440000000000013171627113012442 5ustar liggesusershexbin/data/NHANES.rda0000644000176200001440000047543613171627113014131 0ustar liggesusers;,IvW\pfZ2.,_o9R34v8zeѢ!ʢEk=Z}ZE!:+5Gʪʬ/ͬȈsNW8O^jVY/~[~ǿ'/|ۻV5&{w^1mylǾ?5>0 90w S=K;7ߜ:\qÿ->JwܝWԴ;\O33f:c˦KL)r29gѕbN8e,Ωcvʸ_>?uc=ٲs9i=o\\0M:1pkǧTspn4:wLnT>CKS;_v3Fs˔qZc|??5k>5o9ssxgX~ ޘb=S{l_Su,eǦTs_>7ƌԺ~ngڽKٜ!?_\𛎁c#yDZ]O9OץlSΩ8=GL9_L1˵`:)ejq ?Rҥt۹}vTv%5\g9WN%NǧysCuͫ9tO~)>u钼8MsڹN?5|s޵K1UxM|WjȻ׆町S_%|ה9׎E:\9ׄrv-nMy| Z/W7r?t)Z5=TZ,MO_z.\S}}ϗ E\=Rckt7s+tY.vZڒ)1)}\kg]-?q(3X.1;wǴI}5rڼ>/~[~?_ӟ|?yO~?eZ}.ǟ;KإKF@cۿL4c`>vc2UsҬ7.S7^nnk ٜץKk\sf<^ؽ%cO{N{5e oj?ZssRl%wYמ3NK*_~/Vqω3O 4ٟ 1h57-uzq._j6N]YRi zc<5.m7_.5_X>i|r< oߵST٘zεOiO~_K 63mt]]'Flڼ:s>RbNKx.K/zMޘߏ4[yv.wu|{.lz 4=5M%. ͧb %9w[wxmI\o]TEwcqX_tʺؒֈ>7aiSRa]F%|N%%646M;""K›] wskNåz)p\ uX-M[X/7k"wi{h_㔟n^< N0oo?\.? {-wa^LÔ =p<yl3z<Csj;hzO a7#Ṧ^ތ[1 'G?g̷ A/R?+#/C8y| \ЃqPso:x'I }hVצּ>|{CΩWKRB'}Xi>K=Tt_<;o}D%I)Cj~?A'tϸ]?_Z_.pp )>aI}~n^+ibJ~i'Ѕvq[d3~ivr>O#aI= D>s> }koAߒG/RvxWϯ@ڮ7qi|W~fY?Wr[葢!v~_'Ёz?;_3=`ONCnз -BOsZR߯diƑO BO8~ƍۛ!<ԣ}z){;rƒ\J{?R}Cyܴo=Vv)ϡ#픾<>c?shGwW,sz{[zߚR"MJ| 7i>}_?YJi;^}i8=;p=R}AWO#7#q6#+z^x tuJ8ῲ >oE׼@k? _>+/WgZ|WQooͰ_oۮ0k q)e_pBGo{@;zyzx<>>v>B?:e;oJ~v >/cWwܥoSCſ!7!q(߉gCWrm9L G#o;s_t Kya;[wk$c+J}ƻ]+,L =ϲ(x;|J'jG?7zW3^姬]~^n^Hsyc:JvjCm/~ 񶟆^\W~T,=Y w|zW|US +s3v/?7Cxv.}+I¿Ǵ~{kW/u?6Cji.^o= ݡkz5,ߡ缞b儏S_r߁罚gop u|qOxz92[<|3:pz5޶sZ Fn"G>j➛a{A?N_s|vk|C?Z KA=߂.t_βvQ;ha|nXn_Y?Ag2ncǽ+ƭo_x#x˟S.p>s3.%gz;У!{ UgO3^_B/T<0ϡ9jA;_:κy>; _"G?x=|nvz6ZIuISuհ=>(8!:1C\ b<_ʽ՜'g;yB|G){eo7C|=_B|?_/;~W*~-/=.ubZ,k}{yzozدuZET}5Ͱwxr+~|;~>=˟Ke|~>=s~^hx>OA?*o/zN޳?[~7qyHё_~~Vz_:|?C_DZl//㋌izS}[~z 瑠=[k8og|;^}TgއO=t(yܴa=={RY=u/=#tq;s_ya{enyoq;|xsq7})^Q5[ rLS)};/^C><_^u^4핿y|oy?yug'>;;&9N.x :{Pyz_{UmG+?<ϡwë^8N8K[W~u_+>t)N//{QRq6{vx?e)?޵.>Lo _?ٯqܳy<po}ީ}e{u}RIcǮ؎;;?л;paֺ/=v x/WElK;ؔο>ӏy==VUyO{;o[{}_meo{WD~1?q:$}㐵&֫aYys8r`;fOxHϔ&|G<˳3x;x?gC/Ǔ|QЏާLF oebs_/}7Cx{َӏ뼚W|2z5cyKJC+R@g "<'uJljY߇N>BG'؟qʗ_ ۩LN5T>R9O'x_>GN,?CȟکuW~~G;ctۏډ :ܕ=;Տ!}ng=~{|v5|u Ys_};5<;z>/rh냊Оڭ8~J)-WnWT=o-{{cZ?z~~9.S~;~K=Doq]Sz=Ny>۔߳<~uJW~zw/3wΗKsUv |^yZpg'.≼:Z=>{j?z!o ;xVq=_cǿI;yoYgywKd.ǃ-_;=~MɇUxc#އ[tH=ox w˱ƒ^Q;>Cu>3+uw5z>' a>7qη9~}tI?s)m?ˮqo 5J|cxr_nGlǩ_Rzu'oCy)xtܗR:ݴy~$a8|NfXJ}W>>QAY{a{_~ZW{x:>޻g{w~9}z5!)=^uC8}'sR'o_#gΧ/S]Y^ODZ2<ya׫a|P;7@/;swVw9%wo8^؍{w9iXPϥ:}TrFpgG*=oY~ ::|Y;^W὿sYSz@^GC?*Axk3,gίG%e;GR߿v=a7?ϲ穿νi<; )ws~cf·*s*>y^5z~[l)UqgBobާR9C8%ճ23y?bo{KjPTl[{[>nMJ7jGa8ydv+Mj'B} w|:5v~9.RX.xgsۃ:g"|eBM9ay8ԾДh'v-{ށ;ϻw|ʧZ\|3 x|N yyIO?޴',9RZ?~?8kM~yzX7r+ۮߝ76{/of8 ?aԏٕO8QQ+_a3||N|c{FRzfUa}_tx9zwO_uLw/>ϜxVp :'Ԯ{SR9'Σj}y<v\}ˤ]O}·7Mewg:{}Cw=ǟ-we7nǯNs;*͇>w귾״(Y/9$_=){,xs^ϯ8qyD;M>G#xc^q6q~]? ϫ|ބ3*WYwPi9!{5S=G9i<۴νz:x^쎋؎OK\<^C_Hw]W|Jſryn{}Z=#7?{c;Hi!p}~O^Y3su~>?;=y>ک8ڷe?n|J|y/GVW/_'/y}*O^o^͓y~;"zHz!y\x`?FrO;GW;7γ<㥟V~%T]sk}~sϳ;q#k9?2zsor8sΰswO|zۿi8=L8gq7v 6vWyO>73>:Y!|.m}[y!)}*Lﳶ_WfXcqӬzD~َ'r'ψow{]XOz]~syLIZ;ߵS!;lp8fo}|~Ѝ~w\fck<8\g_}shߣ|y;6C8jt>~'o<>w,>7ϽsO;y SwgSzq:3la'.t;,V~m}zv#7;w˝sW~|.Ù<;ɛa{YnUwΟS?|o>__8鼖&NE;~I{;q4捶W7Z?:/J?Λ9_O+T[x[X}ǿ }{wgsha={'0?Y^~7y?LJgν>!qUAp|q^ױs̿o~GoO$կ)}~Ak[8u.=_?S~zWcI١/ί>]=DZ>)mwʏ wVv=Vl*C8 e~w}:}nOy/{>Y߼V˽~w^ovs7g>:|IǻNNYYPOp9A{l߼/rRoc烈fn}/%:Za}k{o}8kMp?c/+?&e}o\{ݲS2u'zx|losj&g<wCٛ{~U?ɝTxn~{fX__m)q\S>ӝ~*NT>E9}./-γxnJC)}skhy߫!~umnؿq\N'\իu=^}30Oˑ;_tt^wcvSsqZLuބz_8<}vi?Χ'Gp?t>wQtz瑽u7ϫ!!|s獭Os7j;.ysͧi?CJ;e}gO9%xx}yz=Jy^d\塚%~_ 4j}"xVf3シ6W>^OJ[:.sy{٥u˗YG}ycNqHr~C^OÏ:Np.>A;|@{c6-}W^;g}Z}M_?sm5;[^:e u\v^窭= KGˎRCxw{uޚxz?PҎl=}>bsNN}a5ʯ^u>j؟!}|z:Nqa81eS9_)oRz>DWq{_76~Gf3,=/L=*5%tb=o:'__Qw{,%!!/^v~uw>8.|j{ϗ>V}~g9F^_c4;\^m ynO9v-7oKޗ}ާE?^fޚ2+UX?s|X{5?^/W}Y,]ǡ~ mwx?t=q^\'/߬۾z^yϥNs{{>P=x^gڻλ'X +Rz3 WGc}·NMxy=4!Ou娷iȽׁ/{^/*.K)yѝPRo-|fYs:^8 ;kӜ'c;>e<uJO^Ϗ^/qϢr;z묌}xwò)}7{->{;߸+wo~}i:6>vGێ| ;齟F|/8׫!?1 =owyoBWO.x㾎Ϧc; <}#Xq>B;>#8zq#o7?=>rGM[q=N}΢|e\gX 9,w_P=l'^'|Jw:~pFx\;9a5N<ǭ5]]Am{}\޹s^{w^[n*)yS~ρw4'{Px_={un<6G>_|y89n};,yot 9^u Ǖovwϛ׫)-=^ӹΙ˽Ľ=xfXqTʚoЏ Kso{SOvb߉+wGOLW߭v^Nš6~O;azn侗wu^GA^c Ϸ_0]+*>=}eg6Cւz}j=p7;y‡z\M:广yWσ?ޯzeHyMWG8E;_:kν#{#׽z=N˹i'3+?vz5xvrYy^ozp7ӎTP9Dzxwx~u:|x?:޵ū}a:ku'>7ˎzǝ}.y;ގ?8O~띛a==yTmzB'{}=އo=X ,Yyg9}x[7Rz~g98?>o{@9*jA.\u3ݼ?\x|\y u'}I :oy^߀_!x]֫a}vޔy?m^_yc>/DZ踈*k8U;siN6vϲa*T{=<|ZM ?|]S)|i3l|)[ʾwo|ߎKHzNj)yZ}{߻){?ܿwӳwWw>UU~oӸ:[}Ր4xSc德2[cNvkݷkmp[1^^}kLl]nleYiU---nv۸dcӒw?֖ _ {-3-YnѧoO_zO}Bm޴ٕ[cͣ0İ6]ɦulYnZ&mϬS=[d۳4Ѹ/jCpm_clײ%cgz{5.{yk̷i4F7덛ig|ZJ_ӽgK>[vų9-5-7,=ޱ.[Ӈ^ؘ--jٌNn飞q[[߸o렞LuO/ֽa~_m?mtpO[}oLw{G[}zm3/e.٧Z:}l;`j6)ճA-lg=`K-ù֘l?Sļ> -ѾsMseϰy4il3Ӟ]lm>?.lm{6i]lmҶhɼmlۖݖygզMWKwXNyz:%c2m;aybKFikzikǽ--;m:[wwWu5eK?ۮ5vo n@OZ>0[z-}7c_';=F-goz2ز-ccqheך?=}߻m'Zc`=o뉖\غn?ij#zrc+-xl8{Mnw-ۓ]m^1,==-0iۣmKߖlZӭzy~fZl۷e[ng^ }lgfk:e[`nc7-Zg+cL1 =,旞n%_:' -?;]9XgmZ;=5MO=Zxpiѯ5F3?-YOk?nܼgs[:m-K-}-=e<{cޚ#tFqms[t^H-=j_׾a}K}}=x<۸za۰oM}cF}ԣmGZ{2my㡖x쓹no0}mXzzƾ5=\-XZsOy=-lkmlZ<߲9cdb~EOӺ7-;O&[|nm[|ҁ-ݢ>u ϾO^J˾d-~1o{g=b҃}ۣA z짌ˡv{8m߳-$7ζ-݊l{~6-!^=ezzl[|>﫽wV4:$k-XѢGo,[kwz[cGY% -`}g[sVlmY84v>jSK7'=}V?7l㸏Zx7?1soNYo^iڶ|,˥!m}ٲՒQB~oQmUl_kLZ|ۼHW=۴7̭nUOݖ,6=\iВcO[`o=W-0>-zde؂g_O!zehqkp,Ƿ=hqw9û* !?t9ұnuKVT=[ Cϡg}̞mi?h]5›t`[m6=١G}}ٶТc?Zx֕5[|o<{1}k{1m1n>~?V^_xT}4oQtо~#s|v.߶s}sm}-oN8o/jO/ЊgOo0n:z1vs{ov-;O>Z39$۽hOnZ2qomy%87fc^ۖ3ik[nSGoLoǿ%[1}m_ݞ~81s3_!8ϴtXָ}tݧZrԪߋvt!yۧ7i}}i5f~O&[ynM}[cGk^ ool[nml/FeϭZ@K=nu6ánVkwz%-xZcO`'aXwƭ!7k7&c>z1^={Ohw'qx}L-湞[{~dK. ÷O7t>;gikzƻb_g<6-v^0x}d~?⅞n!_nN+nq}٘}vq~g>Ѩ'[&wڶӭq~oגV_z56UO[7w ^[wce-Ӳ7mz7nhnzHŨz|s}moHb>l6-C>_Ϗ4룥[П'z3泖niѻwtvݖ\y/.ٓ-L?۳m->LxhvH쓿ksl_1s1}j瘶<[g}CbXXnjݧͥt==}Z=lR!g-ncޓuچ5Ug_|:gO{m}cjӂCcks{X\ǯoN=b=c^Ѡ%dGyԡy~O[Ӄz=jq.eh_[[lӦNϮG⼽y؃o?%6wHbk{}l?ĪNiw݇Y;ncV-J}z>lu7ءC_P^ǶDZ폽ΥשkoKӹ|4u.sSM5S{)8k=5_[P;s+S]sۥ\=3u;^O3K՛:՞jo.}|w\=15~S]Ssc?u0?ySkX;rNm\Xy>=v*{Kũc+gsqJ΅R=?|ۮ굮SSS?\vhj_w:Un旹MS_S}]z\zt9Sw*;0|ӱkכ&KKgmpsS?wku~ͩtNw^}ޙއX=27<Ƕ{>}۹X{߱Ucʟz^6jT}m:]_{z~=wj;K kq׵u}M5:qjs?cۙK̥\ױcߟԼq.X~K?/5O}T<ɹS`j{k}έO]cc:߱7{ Tu.]ڎO=OO~Z7~^slKr|p*~Ω~pKѡkn{5|?W?KS.MuډST~gn>:/4>S٣sS35uNXy*|߱+OǎåKwݺ5xyƵ\ztNkn=4|*tk¥m.еt,cƹ:;/^ۿ\t6'8xLscssm]S۽s1ӱwl;qkM\zj{)}.y|Scӱ6U|sjy[z|uvOߥ)~]}:wux+?K]?] ũץq:c\xM}./usxo.w*=8εs+sO澦յ:v.NOYuun^׊;.u~6W\v)k]cNq/5k'约#/}M'\O=KKs}nrKTO'8w:]<ظȩ_꽩?kqkip]MTr8ݽTP{νo.Y|w\^O΃ ǩRu\cǩԵ8ϥc`8T׹qͱǥ~˹zhqi2W<ɩK۱]M.}]kan;8ךL.u+oF8˹qڱvG?v.});uxıES\3^ڹsߩc*{8W\?gj~4.8M58VߞOOġ.Sɱ_Z*\K֡>Zޥ|jylSǻN#. ס;Tqcj4{ϱRsZtYri{wi9~ӮKTϭ/*w?zZc9֏;\~q>6^rm*<.߯ew'ݵZzv.e>~)~8ןKk:S5ݕqZL޹T~α퇞ϝKKOt{{*?_[~~~ձ{~zj/vsϩcṔ^=u77^?s=7u.4ݺ58?{lֿ]>v~yl;c;޹ץϩ/EMݕRp.}4US7S] Nmn{qv~\޵={]ov-eZqk['>??:~95|Tqc۟گvqo;ߩskmk]򋦾t/V\<ko*/}ypmx ]X{ױ?CzJS=:֛sߛ ޻^rC\xZR=kw~_o*=M\Vumy s ߹OE5 ߡߧ~wi{<{Rze~Zp]k{l|p)c{c¡~ǎX8c۟Jn. ϡwn;c^7s;USvmPkn|R:7>kjǶ{Cxqj\s:N>~K̭ƶۻ.-S{躴9]߱pw)]צr{_ޗ}9wum84z:kc:׻?ޱM=~Ƕsl{c9TPc9c۽/UΩg:\~kw_.6wcۙK;{;7}Nk*|jgit?ߩc-\kipzޗ}9%snS3~䚺}4y/%ֻ/r%׵6~;co}*.ϩ] Ωx,ܮcx]ksWR|XNTxwX~~nKKmu=_o+2>oKuW]KccR|r.|77?|\|݃gl{}mr:U/˷wK_CO-colavշ>/ Vr][ͥt]׆lum87um8T \SݻNs,c;c;K?wcwss5^,Rƾt=07\\O%KTp,Kmvcu*]|l{9S]͡z?sǩwc%?c9N??4R!xk.?7=/TޡUԸ׿{MEc*cOSnk{ylSc`.q*?+scᝪK}._Sw)-pTki7Ͻw.o*8k*y6_NGk,Lߗ}\oK}y_ޗS\Wl^=3s*: g;S}m9Kש\O}o*=q*][oޗPSc;^wjq,߫?\t>sZr55,/k }f\?Z*n~on: Ϲxcۛޱ΅wjץj.~4u[v55_;nSs8>+sS?Oc,\Jw \pR=wǖ?۩\}xL5Ǝ/?~.\=Vz>:/VuWw-t}y[/ry%׵Xzu{_Kkñ4xPMkk{5S:?]ݩ|=8ӡzsj}vn?KxKk̅R軴vw/rY%\]\uz/C]7}y^ɵPFk}_ޗ}y_ޗwusSS=Uڝ/7ul{Pc8Cc/߮pܗwumxk)ܕw*߃$x>0Gtɟn88|<ΌU'x|^q!_ C|~Ѓq|Sq^0x|'_,%pA<OJϸ/Wѿ|$|$4p>K{Y}~x3^/ϳ:N 료giE1/Bc7_Їz5 ?>@/4^iiI{"iQ{iCOO7|yiڃ rC}Rz9|8>8#l{qȧßOi=>  |*|:`G~oQ0bG/^~?xzy;ǧ.> ߃ϓ }zPnћߠ/Гyϡ_9E^F7أge=\4!/ п˳2|w AQ2pC_aЗq_G˞CÌKєO"G_<"ɓ^wqz!ݡC5?sѫ ?|0Y G/> /C}>bsƋc7r:|H{y<"/ѡ7vq|v^O{a襗pb0^aYJ-㌼_z?x0OcމG|O#`oKƁW/ة)S}o3_>=t{/+#qދg񯆎){#Cײiz9{BO<||= e<@׌;ٓz_`W<^K.3NЏ\@y}~-53Ra x }wѻп3 ?};r'COC }<ʯEc|<}J'8q rN?s0h﯆|:o߳/R%rxaB~|{0"|? e'Cq@|: Ǐ)c_~ߞze]>{>F=Ů7F_e3 *cGs_9~ͳ7vC`~GџOCwEx?&Tq3]B<FA|i~B_~/5@N8+= O/ _Ў<{gCOR/_> At̳k3?/b+>sS) 1x5_~s3]v*]O?g]^f> G7~!t4xc'+. y^!*>= Oě~U_.a't/8[@Џy9ϱL?9[5x420 Wq<!Ndg]z#e|X/0pH=xOi ^2ie<2qƋZoH=[ ,|\GG~G䭰Uz/ԺWu`Y+~ IyE^>*>znbL| ;Uq4"qw/dh߈>Ժz8>8Y7xN\Ԍ'zZG Wاj~7ï&RٴcW |?_<|> _A'e'tf~||OO*^ ̫+?;#Q∥'UUb?@O'r0x> ۭxri80D_'_R/t@ϣoOBg8'Rocj9 T<4:P7By87v|Y_a}ա< ?G*2pNX/~7&t*~ ?b7i;2>}^ij]=p}?qb\*+9f]y"yx?C;@ vxF7 M;Yb7_رơiyQ~#^yyE~|7J~ȯ"?*=sA5Q{yno zq3 \5/HI?-=W1'yu}^~i%zA?_yZ q!K/XOd>_I|Z`WG'CU<$bj˴G ~9 }ȳ~$dg_O'{ =g>C8F'xgߕ|Ydyi?:xG1XDj卥?| }Goa_+!^y oE}#n]G_W^GUq/xBN7 Wxi?푟2UOCOχz }wd\YxP.J_f\`ߙa> _LkS`;^j?f~EY#;q+/|qAA/xbOik_;I??2?D/z>y3ɫb=y!"d}ס5 =~_A?Fbo*>v.#ׁrVӁk#k_$/1xoQsk.WmO$>|<Zii.v{><~^gYq(}*Nݥ}hā/='шy/Y/Nnz/~|~ ~`+; >~/;~ yaǡSͧЇ?0ԫ_2(\e/䟱'=  3zr'>ғ8W[SyOc^?Ty?y|1&/Bo'#_ֿg\Gbk5pb'0.#o_G'x}3yw;k^׈[O*2Ǯ8)xG`e?o/i/x^' վ>\|j/𰎀Ћ<{W|㏡Oޯ Bob3??k'Eg#gYݼ|8~G' e]Wv|v~[rEO=|k_7j~uґqkuc]yHwr_סI\T\"te;Z_A/wgQy*q͸'z} ~^O>*t7(/?_o_O{f|E~C7-$S-0PoA*_!᧐xz(/7w`? yv,GG)!Wr=_7ӹ| yF3*!>nz+2{Ƹy$ȫ9u ڏ0?u᠟[p\'/Cwz5]?3~+!~u |zɧy? /U~Pi8KB}7'y^#^1>KoƳ~/ ̿9g8wP8G8g\f]y?ҟ7hA'-{r﫭}u0OEV>6b8ׇy܇_z d_O'J/z*i7:w% eg"e2n< Ժ&rϡ7vTDgSC;|ހGxt ~uy J;}|ЗxaSŧfu!~xڅOC^ E~!~;y*yGܥ7g٩Wqތ NnoެӳYdEykŃ'"ɾ1v \+3G}y j_r4WA7~U|nTe\XOkf/'PDy)S`>F9y=C f]C=Xp7V~VV+&ZgC/ׁOgޣ?WkT+GnXǴ_ߨs::[qz=G ?jw.+ʸ־W{o@:WU1~sg|u~e^M~W9=o wF/qʫEoǡ70%5?H:}>|1JRwt=,łQ5T SyIv}g_Qd|xrR>;jGwa'J.CműC?? |>v?8OGG!>?v<3Zfv_:~Cd廦>I7/ *?ya~ʳN=m{j*g=y<?y({z_ㄟ+_? pOȼT܊*:W&W6K.|;Ae|98FWOק=GTW>>8kwEO/O>!]+#WWO ~3p~d~Qys4Vʯ }cãW ?m{5_z>2r}*1O9P/q7C<GAڣ(`?j597 \_Ny 3Gs>t!^Y^s|Cf*9?|/urq)'p[NK_=N\52/#c) v@:G`u^}RWn|^X%OyNγ='x+!^uƷkd*~6v-t%]矇ڴ璖ȯJ/0O3uoF؉uzēK3X!΂~u7K+3CܓXS ߩg}"sn|X^Z Iп/)kve *"87te3N\eɏs>\?~C: #Gu>F-}C ;U'C9#^Sؑگz]:~ |Zy! ԺNUxe뜹[^ӡxeWz@k؇xCrq|,p;Gaa?7):%%?A~t%NƵ`X. 腼}c1k,} <_= ʟCcScI :&xcϟ1)ˏp?"oac[%b>7G9G$yuNr=L7=ϸ?=jlc_m/fzW峄/p2zy)U^A/ T<y#k}5xԺ[A<:<Q]gGwg8wC:oS :_~~ugƭAM; G僧=ռ"ezLv 5ߋWZ2K@zuN^9tw1^nPګ}5ċ=%<+wC;ިЮaGּW[I}/"@~d_a_"ǧ1=+ kn0󉒋<'>VV9|>e}\W2_:VCM+|ǵ9^=uNeکMZ< ykSRyAwkW(K˰ |:8_.9^WqAr]Х]ơaG9yǸ/u.!x>q\N·r؏S2_#}y^?釼=ġj>G_r~3u_".ۚ>/~D0>.7 aw'pF<>彊D:?z{ _r^Tun_q>AϺ'G ~?]y?_Uf컬sӠCa,vЏ߉GI_og#_8'q7M~0S~ )=8 tccK?E?3O𓊾?{|[*4>>?=tCi/'j?S'}> S~ԏyv*>0 =3*/"|^,tETzv^|w׹./H}u\е2~#|v> U^G䎸#ECFN{}$bk_rƕ G*^<δG>q?~9niÔw r }k~by^yO1ƾT>0WGqbZOK뜕)p?^n;yCگy@/;ܥ=~ !Zs+q芿Aԯ򅏸/x.JM'|y΍/pfO`rV߳P~?/zs :C?#I` G7yj?|Az7_37s+";xAoƟxX~CGF~r '}]~f<ڿ?:<0C7 _3^?ůF 7Kz!ǡ;yD7p F>xVx^{U]O*o235O.E_o73>~}-g}Q7K9(8=y>3.>7Bcg}W׆8_ngAGCo+N8笻SscW_د-E;K}|q2_|.|qq|} ԏ\/7#ӵΔq7v{wuއ}ڸҮ-*FHD8|H<3CҲ˨e[ MwZeYiVh*@Z (xQ@EA߉~\:׹udgzY{ɟ_؇J7Ӿ}i: [>SS, =vÏ37_FT p칆]?2~yJ) l~=tq<2|Nވ 8;Z;=Nif\(::>G~?Z}!ߑw*~/zro[Ao|SO[v)u|C3 Ϳ6淩 Ih@ɋ}z=:7~rK=Ed\7=pk^x՞/| 427#̣$Oiߐ1w%}B)g?|=i)*xwګ/߻WÕ|| ݛo&pCx KsC[vSҧ$~Ye'G#_?+sds럮Rw6ޮ7g}x!h^aOK#a5 4g~ yktNbO _DJ޾Wݧ__+L^I|{_7|W)8V?aOW/j/!c./J39?ہs |]3yO?s/5i#9:hnӼlWC$YB:9JOWdNیŕoxO? j>cҏu|<o7_d|('oongzyCX6zoZY5^+7s#лxN~8~tt\ursO9PGW_o׮&_Bgi~'+I{7̣87~oǩW?5:{7_ou2pi~k|$ߍRjߒ?o󵄮~ |\o~̋__|v ~Iޗ|%72|<;`'p[ {>1r3諒7Cǥ=A9y/r4 ~y<.2/ uT޳W&C|o}E;GC7'_duϝ~"۸? ?V?7h.{?'%|q?8xxYa_2^:Lx='Ǭ?z%tcnqv>uy(Y#ߍߡcv<:~$c<|N H=oO?:΋`eͻy˳Ҽp{>$ugG:q;7YvI# =Wx3~gƙ;}DO;b93ϞwIHW{,6s|7x=ρ.ݣ7[k].ΩtvUyȇ#.=F+p4yotuc>ֱ= <0>r:gO_4eAo i |_ikW_}c|ȯ#MwyysE7A2Ư;Y[g{yd_msgy<\,?+6Pc/4wѡ)cx|I{Nb3>v87"O.iD4=~苔'Np~;ϸnN?R|m}sLnΑ6.(ݥWbw~&o]"~Os'ā޸_}8_nR?^c\E.=7z?MKy#͗yG}xC|4>-Ů W]"gn$~'g?9L7: ;pN,?d^b3=zN4ܼZg׸/1xy^}nxez_}_]#y}̇fGXwt:xTdW~W sv'xk#tlOu_}|{wi&xj<3ݴ8ڑ#A!\Co/&=OK/ܛyq Wyuȏ3r _e{W >!_ݷ4ΌNg!ǞqId<[r\{]U.(WJNxȗwV?Z|~Czwͻo/>U]%O4o`O;l{|K}ȉƃe_\C-7~A <{n"Ż g:a ~;iqKwK?|3pA_BgޛS_d݇(>=e\mmO&pw|7^yg]eݪ^聼 ڟ}oF.jDۃ<-3?rd]|]xghIWg\_|_H'ydtL>#^788]:k -ռ_;iMϋ~/UcC}N[5t Ӥ}+.i%6ϟKIyWw%z=>E6<+w|Ȯ;^${믏^9}_{$GU~tCM,=];5#a$2#x ?H;g=_Bҧppuyƫ̗^пͧGIk0\Ȍ!W׺wow4fڡ?ޏN^zwqFI_udХL]]ˌy6?Oqp_RaX3>8zʸyAw?/8ݟ3v$>!̟_Q/vWwOs9g빝׸?c?S#?q:2ϞS?#4/Yg߃ϏD\yIo_C_}h}d^|[꽿_2~mH!r~=xqSE>OazxHO+x<5|Ǿv*Wm_x{~-Glǽ͗4Gqtq>s9#q~H\Y^G_=k߆.;ACR/ \KJr<+w!(N]f#ؿMԮu{{ǰ8BM?wH?{nqoQf[v:WoM_]wGt87n8u2oEO7pjx -gpqoi̋N>r?v^YvPo\}6O_Lq4:>[|^/v {:z*Y?vWuܗN3Ny0z7o1KS|-m\~W0w)=>3^z|o]>vO)qj5uy^? ޛ2 ֍ /K8ܟ"1o_>A[/{WڷjKoWOoޣ>;mdG~?#4?c;ԫ >˴ %Ƴsut5KH}1} |z-"wWƇ;Cu8_ߐ#k9px{w>D&igSgUؗ3?&YCG빲'v+;ø9a!?%/}B_zOl~{AEHW@ٻU~֌|ϯW{>j_}-W딍HY{77~.ዞxz~o|f_s+ph F?uEG.,y5o.W~!w}Ml>T8wi ~&|x3Ϗ>='nvہsn|˞i|Fnԣy vuS{|O{E+CStsc.6'_%wk^ctn2 |\|ʼry2ϼOyq?ޑJI?NIqc4~<ԼeRNGG*p~M#/}؏yg&^#q5`gNGσ]O6z^-=߸ɝ}B~-pne7ҧ{;x/p6ȼޑWXԏyѸkN? ;P ﹤9)H4/ ~ OD>w3ot_?py{"ﹷqߒq\q nK)O >@+9.ɣ tK|/3?#y̳a ޭ_3_]Nߋ}ہ#O`ӾYq6㮽o.|] 's=ZG߆2鑟3šu)9{B~}w]e~`{}r<}^N#G=x2TVwG8د(}G~]߾=.bNiT~2ʇ̧f|ͣz+Cgs : ޝ};g޳8yv?H?boݏ ]ا[;ipϡ'#q5DEBe^[*M;=π^9~gŞ/?r[w;vG)gx67*L=_ݍH쎿O\|2Oĭg~F^ 7; ]u73o/~OiUq<*ȏ֧:g;ίsu 6ȿq~=^7?9APO韇^YeY[?z#}yYwГx= =3''zOɼjIwwpop^i>9z/TV]_ϴ~KiߐA60߁O/ݿ8>;gx8oqocUSNӸ_k 1Y g)3;8'άx͋{>z{G|Kϭ%?y |g/qd>f}.^z4xICyydiKk̇|z;?tTSqN_88 ?7y) ZztyWxg^H~A|e齃yFv3#~2yC<p+< Ѕ~*}884z_[Dz!`Ϸθ?;zO+Bo{K=4oW]Y/usz;|~Ȍ{FB+g؍>ٱ\W|_9<_Oͅjg1y,)9wXGy{`r= -a~@_WT??VBOáGqo,qۺ pymO<|/7/t;̃]qF-u8ygK_i|{~'rH{vu~|#_>C}ռ7kq4_zCGƅzoSjo?2^Co[qYG4v6 ecW*s(3>!{'#i~Y/W82 ~qp{6o5빊|)Q$]KRc'z~ȇ{!Eϛ_J)|oث|_|2C￑c_|+|7_C7Oq]%~}oa_;H}/{]~Oޤ}̼+Љg_K&w{"3846NyO_u,E۸D݋~~G3>hi#Gz`v1{R;j|s7 esoKO[VzZq+v^8nSzW2Wϋi3W|r޿Lr~2Bڿv^2>Kiv΍5~8KyZ3y>RrWJ(yޱ]px!qʴ>/xy!gݴ3ʹwܦ4Lug{{v+e|R]M;RW9sy=*evq2?/nn]:z-=𼍯2;+7NO?7'_"/љy/]yF?]ʻW|rt_/eG~ϼ'gR}ޚ:O~^89pgΞ?{>r^o+xp=;~g^/fw#Ϸ/fw.y CN^Ə.81oyn<{~3#QqS}:B 7&wk~xki/#zy~Hr&/O\ޑk??CWN3/?r=96xWyD?Hl>/vw~, ]:/} 7`_WL֙[;=GJ_v8 r:Wf~w2/xgϢ;v+:/|t98_<4pb|G*WG/9ws=]N/֞C~'x:e!7~y@״?W{Y(?v_yz eLc;|; {7g֕/dϮ'ԃ7zqKn8f?9E| +~V>uD^__go}zDW/>_:% AUg97C3߳dwx*gt=WߐxSp~"_?t}n;wƏr'헏g53ݗCG8u?rr+{/yfg?J A{i\:8;{pO/7]9~pu]u$~?Ae=Bn+C$&k^o|4ջƛo =_#gCz'Zou~Kg?'݁#w=qςi>Nf~p'Cy&jW'xχG..H{]Okv p?:w]>~Jx{ ^C՟:~ugw7.|B_J{Ky3x.ߟ~7t8n+#)xԏ_iHkGiqQh=>v!B %!'n~&|8?St( >$_[?9Nn߃nM9x#l#w>\6Avg~#_ \͗<ƣ_cGo;:i!B/|n3::kq g#|ɝ㞤)Ɓ;|l)36]Fݷp}Q|_7^yq'7Qy8̻ }7o{x?OB;qv~yR<[[\<YgQ G?79[y-{^+?GGk__K]>΃p-8/?+oƅwq(iy^kG5CLJyWrN~O6|V9:tSx#S>7)?tK:]z.W|9_jޜy/Jvy_>J4lK޳W=v|H =,xR 7:<sgOM7]jv?W;|лy|p9;L/>|۸z q)Ө?L;|8gCkM/x]hSyzy/%>~<>};p~wvOtvY]#/~3{ɔ9~=`|HNtQvK|~'.ȃ[_عN7W<]97? O7't ~YKe>{\-{<ΎF83v(ƃ=\7:?SwکFqf|O|n?xM;]P}r] BwJ=Zw~{L}q{3>l|>;߷qWH졎#97ίsjg}G#\{Gqg|ֻiDϐS^:#.#^\//=WߛW7ɉYMH;{zj| x}nWxU|?άF䏸]{r]g.qRw]Կo^Pn3G//sor4yC 3.ԏo]y^9U)ix|*GɧǯQ}k?՟=/<5yGD?i O^om=|_1rZ ^юyg\yN=z= !Q]S?c5/ t腞Orq&\Q/<u7D6(g$}8Ʊt9/p?z/Ncx G:nDk8xtݸqT.cB{= WNG9;~1k/ƃngpW5.= ʞ>V=i~Dܺ|gP+C.Cy ,}tni7WD|2}I9{_lo{]tGrqk5?CO{{ [~?çz#^IU7.# -8vDN=~ܫtw|~S<o!w={~?Uڱ?[=r ~4_y{Ǻ@w$/ZgqDL?Ƌ^Е+I=~/|霼K;{f||W/_5qG}(|6.|DPkEI8K|п}!t87xɼ{?5 9^(y)BN;j"/ tyb>? #wW7]c_\%/;rm><ԞCm>O{kW.GG?iQy7H!L `y|/~t݆>ϐKak|6pumԷI7> =f|sƓy0[u>>/_3ϞC?]~=9:_|WFV/̼vG^Vy{8@qowxo7qI?~$1pil#kǧ9ik<_ wRAo\Vڵy(90R;3nx~6΁oOc{6^|q]s533IoGgrM|M#7/A/~gïLgR;y'C^Ԯ6+;הl>|O~ |vo4.|}s?~ƿy`x>~r:ϼG4|G7'9rv-~q#͏uo|eA/ͫ{XuiӞoN60%SyO5_|{kT{(GJ?6;6Eiȭ3pYhzg73鹕o|0~{(C5pmrxR>?Յ'An'ld]ܬyNU9vg~Ɖt?&6l'tb|{'OS\ UYR8q|NMz>+_=#/]~ƙGOLw$'k{ey%<kN|}Ryn\]+vv{(x9-83Gy~KJ8~W{@)Ѽ= ?pj>t3q$Se~(wδ?iz<zy_9h96OWE|ޗg~";8CwGpJWj[t΍3+3ћ7 όCIOQ;у~L>MG?aM?Ox\)kqSjn 7ylgv|8_ ^ ݋y](G7WIgˁ|<>i{}"N;Rǧ>9.)2Nbډ)~2~6=1p\ ?_ڃׂ_W Ɨ Orə|9>G^",1kGNW2~r\x./|y{|>~0혿_Jy9]FOt|5|3^y9\>`?|5/;G@/Apwz#W;+n|13 n /uq;'I#x|`W?~%I3)}wloسG{+b<cB({~<%кaU+i^?BgGá{v;6QkSٸegͮG}Ď_կyfׁ;7;Km+)zǣ<ѱԝaG'%ebJr>xL? ?sse扞 2.]AǕOg{:5"Sx,|y[w_t5|Apzב3ciOE'9cyQ}~,'6oF(=?λOϼ ~iJNH[a\o;?˷yg!;um !oY?Et8OwBοYGk?WރxɁyٕimpJ?tfo c>y%'o!^3h%aOv@7%O{g=}g\u";?wэu"uxGt8޳)o7wH|mW;̟}qzӎuc?A|}*W?r2嫁ڏkf=ZzG :D[z}z<'<9y];>'Y_Sxׁ7g>k39/B.㞯wWvZ6~Co?igW)9HoW~<(7Eo/r#\^}}ib|b^k^J=߃7:OtHnw`GзqGD?+O~Jt^:Dʍy4me)^?S_y%/Lno)kq5aC3x?@#r;_gy~[q:ApWց٧/~:qLynH}xώ⇻'y)^?ؕ]|a>]W3tUNig~! >'"/o {O~qKtI ^=ux|/zE?|Cq1{vcc_C,ߔg>!q84|p4 Ë}W|6)կ|{z_<}zEg;|!!ß^|nl?ȼx?gvOi޷D7}S)w I'|@S)|v_<~/[f~oIO闟Yv}!477~r E~5?B?Tϔ8ټYh u>,zx:+9q[%D?O&ci|ڸ"r |댃w%KG;i3FN?ʹKN\~o3Ni>3;z}FCO~߸M!%{^#O?Ή4!ߓWH?*~# 0_p"W/.'򊞮'O vxB?|x!z\?G^~ӣ/;Hohb7g脾o7}n\}8]8;6:C/e<ߋy.Rک~W;Ʒ=JU:ܢoKs=LR 8oǟ8?zš_97ۑy>zRku/{3pe'{#<+q]1 \79.xJE{w>ߓ-:O@X\{,1'9J/Zes%{Ci#CU:\asYcoe~ ɳq{<߸w3:'ț~L=v÷ug}Ǟqxo!)]8o<O.? *طIr.A^qyoѝ_z~ri{ƏZڭ?? W71ƃJy-_b} 7.xWVbzOwe5 /W_rz^dݯユ|9|%DO<'lv7zqߨ,{>pƏgksOi?$kiiƃ9Qt% %t_[c~ ڸ| H >݇'of|gɑåԳsNaW=o~_n=r-rȫo>x=@ >_G<#8X9 'wBGo5wg~`깇Գ.; <7^,bG>S'߻—'o~j5s{_2/[k[{=A>~fAҟsčM) zt`uH9/>|u%5ߞ^i7&{=Cao7g/ ?Ӯ86F}q(O?:gl7W ~/+q1tϫ'ߑi!U=*S^Wp+^v!zv*9r\}>Ňn97#<\sڻ9n]xgȾ=אeXwt)gx&o}?pj<GÏ?c W*[N^!|R)^ɽ3ތёѫuƱg\x;k[GK byF/;z }O>×W><i<>{WE7Cv-L9^z9߿q~|>ώk_?#G|ԓO{LB7)e}s<%ħ#9g9OOiyS=O>7z~ə92J{?{ySfܷCGE>wN9q;i 0|M6=5^}0>YỴֿB#{ܬ;4'$?Qs7Ot=t(Eۺsu8B&I{v"}xeԗ=g)z_l~Kvzkm}ÜywS~iKkGp{~}yejg{h$7_p㸚$eQKY?~pk(r'U)k{tzIK(rk\pSOO ^+?n}Oѻ{a=?[k=Rc~/z^GY_~]~ٽ&oL4. =gyɓG>< >kMCG}.NOۏo*/_ž/r~u=E}@gk]_;ָGCDgN9z➿}_ {ͺM;cW#Orz qSG>Y~/:Jټx?Cx̸Mt~?V~e><`^I{-ɇͯey;~֏0ysG O78po+r'{OM?Ks~67xSO/Gߥ>Ϟbh^w}OF(>J3ٓ_޳s3G<9%|{{$z~ke7rSo~?eϯ/3/Qc1{g?NC\6<3w@GygG<8y8մy]ɋ)㽨|_lG Yl>0㶎bksc7=rH{|ظ"/ȿc]gίRv \ɁʍynyOo v[6oKLoS0?gmڿ?{*e~=?]̛^u+=9O ޛg r3GOwh}%C=}kk9g~߱KQ9<7Ny|9+|^AA]χ~wqyO.{S[#v#z{z]o)=/K~4J}e?y6>le ]6oeܞvQr}SUx{'*}TgZWXgwAƕ=__JA7|DG]=LY\g ^}=wӇ&ޞkO}ߑO]~`&O)Kioyz-<2j=k . Kys"5z>=/G]eEY;W{e)>||7NG&? 35>|Uyg\~a_7#{ W~K֑>Y^A/{4%WyFOyO \m͓T}L2ﵧ^#_^ccG~D3Myv?ߠ'z_ߟу~j<_γv멽w\g[ϙgyGo_gۇYd\LO_z?垗&2_-|D^UͿLGzIiBm_yÓs~|>1>EqVP붴q)ms3Ǐ?R̘7xΧg~x|~ƹyV럞j\]K5/k#IO~j_;{S}|/z<<{{Bw~|Ͼ@ugצ?o>s~zk‡M}p"|F3o?)o{t烼wks{~M9c \ӻg޳>}i?/i~tfvyȿKc+k=ON^P;b<qHG7r9kG=͇.{(/sKWͮt'R_A/w{Roq=o n/y8>=?!;>={7/C'/ Kt Ko? ?wGQYfG|߅D>7SH^ySf?^bSvVn[]=^"go>홙W<^9tu]ow#/>9ǧ W{vO\1/ߙ񰯭е~/l)ůw?=_zPzs܃\3IS}sԯ~:̳GF7^֫jhھq=}7ҥ}G/KA)k̷q ~Ay>9@p'OC{^l̷ag40\#ޛ '鏝K#_2ύp'߭/x~Tz+^{^^ ߚ⯑s_]l~}4~}Bnm>YO 2ϼSy/E㩿"ޑvE'Zӫs~ܺ<i%5u:G`Oys~dr^q8̓<7.<ȽH53B}bg}j݈/Q{6Ɠzd~dn(4>l^O.6'iMfzbm|)oR)#o.c_ĺy?_<}ݽ7jOcmkdww3(]y_^pPރajM6v;j 9߱噋7r %u4HO\Dbϸ6=b?~ޣ~[irrxX5p?O/:{Տ;cyO?>;zw?rƙʗw5X:Gi;v!Eoz[J~O8wq_W)ۋww!y6k o+{]+z3o'8K]ޣD>84-MgyC.vҮ]=|"O;'듔q\\ƥGGlt|KI+|M~7a5ӯy4NkIsm)7 \_YW67^8\zO^ >ە+7{qq9cܞ~Li|ss<{yxEVuĿvgތw}Oww~NC{vk2/}oơx|gѼ}vqG7-{юPq^ޒ=_CnqB5xSzJn*:2~r RϜZ{t}qorvߗx$%Y?"|M}CGN{Q9xO['G=v߾q)/ 6|!z!+~>??%}~p4>A/l~y쌣6tgv;yX{vk7?[x t}| ~q~R9p=?o B'5G`}ObyZ{G|>OŤ>m~h֑^EgD঴k^O=~.+ڸfyفo|vC'rǸ?7)ŃY779UW5o =?1?cy&O5? :Fgn6{W;ѼAw8~jsg~H7rٕOonMㆧ|~/~4|vڭ_hQiqS)7^4]xyݮ3zǯR/@Tsw Y?)W7 N;7JpO}H~_|s CpM{>l$y|B3_:Ji]W#goUXߓ=lx/H> ?Ưiyo#OۺGy۸ȏ=/:+1_ \*_8_M=qt_4o?$y(ɭTig ybK_O5+^ƣ^ʯ<?'ߙNo>ϕ?ޞoIaP-Xt¿gq)ꑼg?:xegA<7%;%y7>3'L?2{6K w~pKI^{a߭VyiXv?xib]7I!%;d5/ |_ z{f|>j[3rٛbh_[SOX4oon}Qs'6o>]`%'{yk~ⴏk\yŮ oؓ?O!9>_tN?5w| ƕzˁ.zn\K{7gv3ؼ7:,qx#wQ5AϻorMϕ9y_|Xgp{mFne1s6q?xclr37o);QA׽|_t||m}9vYm`w}0v|mc_?X;{FyOkx^FN4.Gьzk㯼;?{-wiFt9Ǥs; \{}@yF~uI=i|qzyUJx]#ǗOHi]Ot_"_z(ϗF>s?Aoo~yj 73ow9֫g7ٳWJv2|l>UJ>xWAN Ỵƹk/>{NWI|x;h7q#oy/ ߔz׼$y~zb^SO^yKaKMq/2t|kKy~j7e]O~"w[zvA?Z'nsjo}vVkh~oz[{YRt9@_։='z٣Gn29SʯGiaߍTyy뗞"O?jWdn]7,(?s`yf<C/zn||?yR;ntӸs*yOïqz߼k/ފ/s\ROaX7Oeoߡhg\E?TwuyL;r+Ѵ0obyg/zɯjiQ{~A~@ks׵g{I7]:w} 7><阮߯Ns;~\xc7Y?C;?D~ x+q#=j|DGSy*3naG qo?zj^&py1F> s^/Sɝߛ׿ ?m ϞS3CEL=zJ=/t|}ޓc+{nx6~|g|{^>oezIQ#8V@H+K#MZKMH^&<~3ʘz& _2fI2 {~Ի[A OzT.V[ZUH;Y{SB8ߤO7k.vO{9v)_ѸsOߍN{>>6?sUt8{j;/d ~?wA{Ji{'O =RrejJZ}=!N.Mڵk}oL9?yLyc/e{'S]\_ꁧ߂>W{Otޓg]݇wy}ˍC?d {yy3x;=o7ظCk /;?US@'wK\=_ ~w" = W")fp{O/^m9~h /?Q{Ol@2_̻ƃO#r-C3nϣ RBgșЇ9 %O܃C>wonRj\=ydwwLo?~^)qA~fb%8%N"׸=jo__?1呓O}_O_SGS떔}7;+;)csI{A%^uw1xyQƝduI3]'$m|~}>RύNoRؤ=&m|;vH 9x|GG}f>K΅ziyX#xbMt߬|^o~7H;#@!OUN 㤎d)t\O+>l"X^C.(r)>tߡw+~lqE~ȣƏj>Uw OH1~}]i<H.#~784>ڏ\gow}DnbOW>wǼ{~P>DB)"z}-z. n+~gκg!b<zBxv\{weމ)_c\SA ޻@?[8z~& Ns ]|G_4N~^RqcޠnA^gzW=x|B nǢ6%^TWs]޿ 7O_BNU?I9^*bWPya_ >-?v2½]|]]/B/)Znѻy zz]~*ߐ?/v<KWث֛e~/F9{)?*t)y}*e?/7"ߜ#IDOCOܻߙݡww;+~=K÷/o\,{Qggv~%{qZo:e>?Ji {m{ 9i9|1AE~r><՞O =3zV$ 3%_P9 ̸|OnO}?:Nf]_3ߥ申z{n+ g5vj?;~\Y/\Ko|=ッ|=^oDz :N*)yOr=|'`qw~'$ORhE7![-о E4){,߁sSV|}C{zDR-N o~{+zSzsDn2)ǾXϛt}W^?g}wR?oT NkYtr~ޏ^Ň뽣'boýAqOA ~Bϰ.AOJ}Ǎ!Ϙ}}}5ϻzzTz()b@ƹݯ{]i +ߔC"}oZ|NIFW1r|&O<݄΀ݷJ{Ѓ4xh[?S͋Y78 | pSu7G|^h ߎ,2շ{X{Cc_A.ԏ v/n<_:a{S!/5n=.iQ7?-^||ϋ\7_D|Zr&yd'>oTw >zQ%얾!g75^XWv-yx?oy8H^`9^J.<'ba_g][G t8Nߑ)'P|¼_rxY_^Q~o;~9qeޯb'Ct'2з,M_Awɳv>WG}^oAy08/z}w ~c=; =n_~a]U)wC'ɣokt߅D~sc"*9їєg>zNq%$7~\=W+_/>w?D)=xOW/ ;_i諟N|SNFnߜc_=y\NN9On|[E?OWzDCo?y߭[8 }UDszA{*7x{彯-rM_{؇ۼg=rl<ϝބ_ӏmxJtIAƋ<™qt#|؞r ?~z^AMG+grc%rLQ9|ϠOcsk1CrǾi $/cy87^?/( M_xnL^'ImqgOgM/Uo$oyq9ެ?6_wӅ孷dzI$eW7ɁOF;ۉ.ԫJPpLv,gi~Ni +ӱlr֗詟<.?'9bybP:xi}U{fm>Ӽw4?y? sͦwOhޭ›]E3{ޞ-6ukk?cy;лjhoNӹbZz7țnk Oi?K.{ |U mo~y|~/1M>U?[~kѯ~r3rQ3OMߔ+^>k{~ͫSո-׬6ew$<=|qOu8مG/0}m|7[x#?h牏,/y>qsCyuMO'yc_d9Auh ދ>o~jdo1n˙&:]u߰S5ӽO|ȥ}7\k֣и&?rh j{7f'MO:s_߹DP>4^:x<\=Kq[ӓ6lMjS\gˍɎqyww{uch?c~6+:ؾۃ[Yڧ?ڙcG5_; JQ]-[?KdOx &DcZ'/sg6`.[xw[oXN dsf.>9G\\N7t,9}IO~tNύ~"ünƃNJv2g}\§&mqg:>~S$xi} Ƕ!z@M~֦/DwSܒ %JggƟxMc>~AoANOި/~1:h =}\i>tqx ;lqG>$.g$K/lp0n֗%>ٝﴯp}Ǐ'=?nfj[ ^/^dOS< ~6ߌ &֥=a<<1L9^gֳ4o0՞CAMrpnit[rx'~$Wq?Eutn>R\B~&w%lML3_x0MGpn%[|]?T ? G?tɏ 㾉i_}:x'kGzcw䗜kӹImL)uǷz ?q:5Nϧle98eoɞ;o3|b4]L4$&ysQ.jK=ϴ?9~{Ƶѡ\F7{_q;SdN)>I=EBɏm&&`Mpn)n3Npɿn~97m4(?) '7L ovoKxk<1o [l<MS\;ӝ/][_Mvo~,|22k>Fx?DxMc{vzeQ ? ,ܿǽ ԟO0mLzoߍ~Rkwth}?L\'8&4';`\[ 3H灏'lZ^l'a?m{p]ÛN,]LtjNq㶮_ѕG9❓nOizb߅/lI5/cD[#q~m=' ץ5/g?9i<ӹ9 Oϱ4/ lorOx]777_ܦWKrntpɏ7уrLZqmm ﶫ?~g^eZwm~[5=soqj~~W3Kr~Z[mtt?h x_])0><ƨo:̯k2 c_\ƿ 7?0KƁ1)&vXqcaR;ϛP'=ripZ?]j?s~K2CG>:r:5mMqW<͋_O)k4 nd`^Ӻ߈Һ}ZN~i?w|~ [>{G?yKii{ݽ[{~^zg6h޶8ƤexڡO{?wHH)g![lv渟+:~;wuN.~%"z_qH/rΌ7 _;,_|B?~?smv^Utg]3lzG=㷽%Lt3ﶏ37޷4.xzΪE|p0>~~4ޏc צǕ|~u{cK~ʝWFl:hLfi.o>Η񳻼 ܝ'cGoC׶|un0cG+VnoflqbO]5AN<Ro=X6nCv :o)fl>LGfwom~iO>n=izOx|y6lЄq}>U>M/t =xnf'ߌvƳI,?L~^OAs䟚6N_d:@;lל7sg!?3?k{tϪi/ֿa_;й~Bqs96rbkl ~I&r#LOig<ԟAMe;tz|zv϶4&'p;Uo}?~\G^ovsj~M ivv䀯)`)e_~nGھ ϖc3_:.݇*? ,G,=g`|EO~mXy{-&؇?Aؾ ݏw&yyij>;4#>xO׾E?]ljNH,oHrsܟ.9'8=^ϏgՎe1M;5^1?6״:i_} LrlqCtg?2mWpLr|~|ҹߒr@{2=o͞]zkMzf/G1O0i;~7>UO~m#97?nq6dGA_X\:4osZny1ųl˛NG/șis9^&:qZlJ{H@qzg[䧙Lr{3~nY`ilKaJӧ׭}|/^/ǖӾaܗ޽hxi&9~}D>9z1vF]/0CzOxRa6 _/oޟU'x|'>)iۧ4NvzuZLq4n~ǵS^fzvuoK㰞? 8'?<ظ?4/96981W1yѥs].yF󴭟͟\`;{Ϳ1}i_bZϏt1ޟyWݸӆy7]?i>^&'8毻 &O}|uC0zXLpv?;\~/zTt9gOö (쿡ݯc{WrAk_{_5&kd{xkNcElAxoko;ۥ{6a)iI׉^G~6M{??sjݬcדWCa+'8ɯ1Xz5-M,8u^?re9'OEϗm_?&ǔsfp|or7s?Zm߃z?Mkc0 Zn7>wgM|pOW{S4ե8=ߴI0ѹb"|rip\Mr_Fo3ͯL96ɕɿqzc;2DgzA^?'u[ݍ4O:E>:QkW~He8|~n{MSut6z_a-~/KL7tD9Kc? a>D}cc$=S<Bt>{̇<=L5\c?ӾgmC[?v;_|Rztm%8|v7N0Nr}Z/Lqb֣Ӿ>G?wEG]N2ťLֶ:x<죞~~addol넁m;`)u´1&y%x'vSdZNGC}Ѡ4>oÏמ-Btӻ)7o'Ds-AMq+:x5}LfOoi'9a{k0xKo]8f'[YLxdg_P!#Ldž0̧y|b?uᆿ8)陉&9QDO0y[MqӾǶ;٣-Njf ~r;g}AXy8&&[tɾk׉^S#y;f<]0Ӽ_[<}K9Kqu߭_>m5=tԓ a7:>geB~ /uOrt;?H׃qN.S;cW7bo2~w<=P~7|&:zS&WK\a|SҸ>S+2죋睅M.'Oa˚ϕtqaz~Nb3Зxӽ0۶8K>ݻ;ş~JPoovS&?CMW$G?y~{~ԟ|`;~ϴgxߥ{>R;oo֡||Nv;մttj=3ūL/d?L$7c8K擉.yؓ:юm3ȣ֏S\ҶN5.xC'ˉ7?ߴ=Sii5{C_hÁ.Ƹ>Ӌh rc'Gaw^u+{\Z@/1]nx5HnOx1p}tI !zQ7.E1߉uFwjg#7فk|ݯ7#>'ӹoLmރONv$-5eKi>63^ G?gjw?Ҿߖ/᫟,?w:ayq~_~'}6ٟaڝ uvoڟ4>&~&t~#ÓD8'_\ү7~RIiGItyI/??acƛv|8ˁ+\Txy~ϣ;yҧ ?~+Bo5 b)Bo|= <3#ढ़|Ͼ4rQү&/)xb~or/ׯTjG=_}!Gg?ϿJ ɿ~q;r@rxg~X_BG;FB_ӯ]|#yzv; NjORbڭ7x3o7W?yO7^K}G>2:3I'Y{+mEa2Kwy">GoOz|~o=G~7$pZn3N?;O#K+ KY/tyh9}=r+>} ؟w#ߙwt~< xF2=6SBvvK x!C΍A_[ ]2G)3__QRQ۴'_Vܭn=|`z~k`ڃR p~;+#K:2+KIӧ+$xg9yw ףS|$2>$2NlGJoՓ^rj_?xj K$a#tNo^^SrR/TNg\ |>H_RiƉO8呗ro5Im[M]&_GK|G.K9[톤r9<`>o{v?)qW,ŋ辒HI9uM| HP9迯)ۇ"g凤1|g^ t~#I}9|' -םKת"Oȍkkz7i##r:GP|@=}o׏wk{-?#)E;q߮_ ~Cc1}md=_;:W>^㆟>C{)_:>2|]z>r߭?'Ͼ|1WSMSyBny T~4|oZ]FF^!g_ <'7xL59|7NƏI׿j>|9iq0#\G|}:K}zͳdi|MտI979xkq>8W4v}15w gq2_[5ꏾR>= ؗeN)|x_+r/ȹ?%Xc?5nmDn䱃T3+R攲g_B 3|3͞z1屻4~|NGq4i_w՟]]/;Ϸs}(XS$~'GO^Ol>/7Gz:>?ַa~|. xk9d{vuyHoɣQվAׄo2]ַ/ݞ껤~R'ݑR?:n g =g|ȫ]`Gqտ+/ve?D⸦5;zRI~KpCL)8~Ic+&ܟRC"iH}䱧+/a5" 9(rqJu^v$Kr @t<xw-|)g޸|GO/=)O| I> Oyޟ%=)qY ")v/v N?֏8k''+Bn3w't>.=d\_y^i^F=IƍZo_cXG$+v SFRz/+nOk|Hʓ r;?xANO}\b߅} xzqakWCW "Л0_K#qk ھg^|'85_ŸG. tƾe|mxO;􋼁Oa/@O3N7Oƛ$/빠GH ]#CF'I||R樯SH^wt.ߙ  wEޱO8|}մ;i:+{v~z~$)WixrsJGnk^Q;]/c+I3|qЭυ;T\W#<9y7]"iwk{?8p}+?~yB:HkxSA/ic3߯)e: ۼ]DɃw◠9]=A;j&~ZWIh^7@=q\?sŇ~FvDgmbR~7}S?_H@?GoWCo9ry<>G^?v$B+:~S3n~]Ey_{ח5Ӏ7faB5QMy#B7~kvyuϧ]p~>'~Uvf{8m@s{J#>qr;?Hyv@lxET_$/奴}g{?M=s<7'|CNX[>vxMٿ~y!xк3ߧ=gI?W}v=Xy#S%N5|)|Z` ToʷːMʸ ?/#~z=ulcúڣu.{=OcGAKݣHOg_y۟>A:SysV{I[`P<%Mlw#8'8qm"_g}\75)y'7;{[}>|r_f|)׸=aX ]uD꽨ZyD^|N}E^{~\'Sm\`@(=yF/OɳS{ K~H;!| 7NDO=6ȯKWcկra'~#wo>g=<|9p2ޫS ?Z:L;7ɳ_}&7tEq2[gsqIe:ΪPi|qsJ Iӹ'f>y;ri)mWBTDn0Iqk}痻H}ƞ&E_8/xANgRJhWc^#|ggZy#ox^Co<>灿[i:e_;z 8J7y5rq@O/uk-|eg,8? r{Xǃ՞SIg_Kck[4n=߉ðnBzoF8U;{2}:u/@ߍ7JGW+|)qi>s I\=O+<+oqIF^^'~?C9]{+{ cvlosXw}g^cǿurq%sG?c*0N~.'J{ݱ/iR]{zMSRP8|o-Xq"0G{tZ-z/qOo}6o#ypۯL }^+t~-^9g{p6ڟ8|_QG~ ϻQWk=ӀcЯը+&ʩ>M} ==7<>wuC;~q{+^𨿾r|Os=Q}\mB򾯭+}^R8;$;Ɠ'ubF.|38ooo>z5|>vRO~o<:ݞ?v̿Q{w.~[O< /'~'x# FtqOzߑ?}xeǎOL@/'*GJ=#z󢜣ߓGq"G_=krzrfspn$A>zsJmߋ ޠ'==w{I{Bʽbs\C?+}Y}! Igz>pܚX)stߤ '#<h'{@ʱr:3θcJ|:{?Vڱ~鹚 x.?|{RNҞ3^NO?lpW9G'OzCV}Hy煴~ynI?B[ߣIZ{juRƥqAH/}UГ{|Σ{{m|n-8}%c^l~~/iU9(nC~.zhßߩ=;\JF4&V;|/s~qެ^H>.~b=,,]Jy֧'VxW=}7!),̇5AO>þJ~ITy'ot'M)"?{gO b|^nU >'7 {>0ߑ{=yS>:{|G~Դs~}vvgb?p!YQ/i7{)R=,zls>{Ӿ#o_*SV/mzn&큇kq#W=Ӹ[;.(_C^׿v> *v3zU߿Sܠky;NC> +wU':y4K7{9 =u6.&੟2){G.vvoYR'O7y/$yӒv'M)"g: ޾sg~oH㘒~j>;/[a;bݱڒg z?CҞOHy'5}#?{ vac<|].|{rݷޟb={}cvg'3+`Xa]s~\0|JzqGげBĻ&|M{ Ozq),>?rXÿ>=Sxa|ƣ7T9.*z_MRx\?nQzOHgLy/`g?ɥS8jz~=+~tV=gqn3m?{9q,| g~ qR3{ڮͭfo#96s%E/xi/B. WݷH9w/ 1p g|c|}3d}݋>H}vSWy!)z#q1o q =_z;r 8z.?wnȽcL /}/'/ڏN)L^=k^} ~M)=zo`vJO97)%SȻvqz4/)tB̯Ewzzqm3]q>]z>/=ϑ/v^')Bn﹝||9:?3WxkxF?MSՕgq1M;K8t^S[@nznS?ym=7L78ƍ~:iRkݭ3.)6>zGG^#k_~Y_I}g~oB#W9yvE=Z?6t=D|̓w?[˝ԯ]-zo7w`˪߯?ty$7CLJn{>xޫ;}~5.~[LXr}w cK~}彟]=OJeoO}oN7i/k{ڗ\Dbc0'cwXN|EcAb'=M>WAyɳg_ R֏'C83 3}פn~|㸎V~Ӧ^kʟC;e/%)~d~1)"M{ou밎723RO{!7~jM{-yCxz.QFy ){uqwkfg{FkțoO*)t},o8˥r+"/]S^ F{#~H W K}+)5ŗlqfpR8ԃ^Ty{C}gb?yh g3.Ke]>t3{% :+J9u,C ?wmAk<؅~n򍻸[Dž2N}cOgOx~ ri>ʡgώl|HR\$hy3~ʧc3|*NL긁?Zǿc^Q~G]_zz\&z<'}) mZ ~þCA{{M|㘎kg=<|κ }oI=I .yN.붮zW_3or70sHYOo|bEuɳLrߞzK??lo^ǽizCPs ^}_=Lic/{Fa}s;Hn_ϟQ9q!i8qo5Y#Xw?JQn Lʁ'')_v 71~ac|Yp_ F~1\NCy6n~^q\/mz?}RK}-zSW^c]}Yg\IF_IgYWiOFQ~RO?vηnO)qGL`׼r|?=?yX8l<@ <70y5HGo܁ק,ߧqQs\Cw=~u\5"YL:?q}vI9M9sIY3/>abG㬏knaN'7븎d}@N{O—bۗЙ1oqܮϛZe~}Ω087 {Oqf&+\OU/kW)sJ![ʣ|?8ػS)ře.?ۏu!W=wo;̗U=ojg1d|r?Jha)ԾZ%7*S>J_'2 cyT^ |x9y|w2S#zھߋ=܇* 8뵟G*}uOճߑ v!:W6^8_v ޿|G|Kp߫Ӱs,]v_5wnM{s=f܌Sq w?7{OIR ^{n7wL{ݏM)x ρqތ3CRz${nKcgw̸(G?c]\=w+U^^<싔.}_\;߱|q2/ȁk9{VO:'vRk[zg}q:Nv*mSZ;p0-ߑ{˵'Sp|ܺЭ{>6L}vѻ^VN픴sK|BOt}|::߱࿞C}H89y\o)e?|>U}{W<> \^^LʼJ)]ew>> juv[5>X*IZqgOS=IŻܬ_gH=R]8LSt]&pk>a-?zOY?cw`}>G={W6pQN/?ݯw~?4~E> a?xz/ c\ɳ{@+;S?߻_q3&{?AOCgC@.#6wQ?p ``cr3G @?K1)|xL?Wyv6:[ w_9)T.Auﴗ|S?}z~v _co.o|B}Nv5>ޟqhݏw "^J}+)v󈞃W/Gz}>::}}ǁzG+<F˯礟N׸4թϺqG|#?=Ywt˞?A[a3nvlםG<@oկ|}K93X7!<{|*V.:~ |MSp\q_WּxܞRˡʫ%a/G_Nڻ[zDUO]z2 a7|}Ǣw'r@[ma4a}aF'g8Suc#6-)xrܤ}~”c_O[]qGWkӴ{͓I5LSݔsu<~w~_qg=+z?CB\WW>I9 ?tθ'r zbq؟Yge_Or谶4Zqݓ{AP/p!ggN!ű57r|/R\/wW=CgWLnq6=\RyոSs>|>.}_A"Bދw%]H=QXc' ︯o#HoI{]Q߇K _R?s?K)E=bݭ.Iy'xDϼn~}ƉIS7LJIt:ٰ׸ke<wzC5_{=)x"弯{ FQ{|0^:N~#Y߆_ا+qu_j}T|`ZPgݛO)sc'8GW#| #M#șq?O DI}og|CIܜ}}g䒯^7^%)x?WyvDWv;ܭ6帎}0?9%S<+}V}/^SSwnN黩F{3p۩O_Zi?N)mׂ7~I{oqgy?I׀/Riͽo{IymJiTSAA/I8J}n{7|ޝ?NʽvN g|kk{p8_n{y/:ηR}>?|eZ~|m8)wNCk<ϭ〞'|Cziɥgہ #>ya;i./_)go"ݽ1-H?xE@oENTާ}Ɲ)_K+~w? GO~+> #oa^KzBPyo_<qD~.\+/WG.A/W{a3c]y~pq2޻]9g]vzݮ깔?YotzrC =:^Iy~OS_tY8wk9ګy|~78sAzz]OIC9[wk;u-]f?Ҟyy#~RmN“zY_>;ʁCßkI~ǻܬ`C?OnW8􏾪۵ [s]'Ry]7̸@]=;o?7-~-C>uŸﻁ ^ᅟя鶮tz_k.|M>?1\ = ig?ȃ۵~_Dok#}4x@_r~+Nz"?f=&}-@2Wyzy+?Z=~-p"-p:O 㳾>xouW1P_:|y]zCFBFxi7"OkO"?SO~>Vw!r^[׻v Q9'r Ôz Iױ_k'knWYgvvGiIY5z?N?]??A;{tѳ#=irF+pg[TyzHSKʧM[kgfqm/w^>Z6pǎ@/؏w1X{!#G~U= Of>v ir8SVe^O=:R3svE ? ؟쟢w~ٿz[|w'XNk]#XwoAz*OSe@9> v#}9?aWWחi~G೼+ǻq2|/wܩ"W z~C d]n}{M}R91nGC~8VwxC㪟;g3GM/276^o~7?}Y{vGaSm|$ =yﴷU?'e WR[ Щ zq祿;vMJi~¾D Sj:6xi+|#Ocaúx9Q7(@imqǴ<3v~l.>~nY_Sux)Wruiľ~t>z?6wzN>s/X}?SmC.~ }cO09m /פiy3vor_b)e? C\/eް:i;y3m|hh[}Hޯviq?2 /N.^ pmy_J_>07wq]; Y ۵ ?Ǔz_'7͸ă+8 xYAkfT鏟^x#o}r(p_?wʋ o?r~֔>/[=?pg)g?~;[1y~}x, ^ȳ%ߨ}{ک[=wᾧ|ܹvuDi/_=8w_ꣵ\b}6v# <+r: y}gGZ>t^PB>e>xv}V{i~<v—r_;Y_inu,vsv"2껃_oq\L|_}zywT>k俍5~rFj\vxSqڙ+3v}1/~tY<]|}ێg`+J)o|j']rdȿeߥp6^<۞h-~x];{>wrSLa g|>z^=pOm|q(q7o9]&Sl:Lƕ>׸ϿI칍{>3sbNoiN=\X_5ύrq\k-|tkϿ}M7zr,㮝8I]q:A7OyvdGv3<^ئN^2B)_}2Tx`s+u޷ޞ4s^W1Ky~N3^tQ<<{k {ƙu: PɌ׺zWY+/vJ~f>:qMZR.)pw߆q-G#ه|i絛þc_c'C_ڭ侵Zxz [|YץNቜI/e\خzGQt||[_=E}+GQ?h>7nStqwbuy_XOdǁ}}_/a9?Ɲ~WhxݙzVly_~`A\HŷK5@g)Gߣ_o?OCxםܘ/~y~G<؟NCwk݁qOlik^,4~ _ݳq'y[H;=~$m_j=7ߞM}}5?8+Yus|kI{; nlG>>I~px;+c>OK叧x`?5>&e YAg|Z;݌뭓3q^xcO^h׺Jk3Rk/z"G#^Cx_wk<^8~kO9H. d_ϡlҾyH2Es/y̯NyN73OǮϓu+pwS!izZm8vx7+Gw8:e@>ωϡ79C?s'OzS1ԯ2oa['#p\L[x; '_<ɸ/89y$NC1Y~oK;=wBL> ~u|ݗZ˳zdݿ31xJjx*qt <|_;u\G2t>fAy^i/G5>_|_ƙ~j_iW۝tni+?ۮ|Gk9|O^׾=ƓcgJ'n+GI91ΞgOGk?NCK^c^uxeJqMfCgs{~|+uHEggr OBnJo kJ=7xg^w>sM?~Nuz^vVS?؄7_sgX'O~+;G.c߃ug ͣ4{yW^MGky.N(}vpc?i_Џ{vsܦ^7>ƕ+튫mԯt?|ώj|x7j7{o n~38?U؟sx'kON->˸}{qiqs9)!fshmO/sw}v#-ҫDG >ߟ=ؼp{f埃NwO|aO4X` >x~ 7߭~ً'yϓ9{> ͸f\}cݼO {to]ctlzkg|1cQ@o:<wr{>K}_~7*u?ow<ǺjGq:Iw3 >zNYʸ_(AG]U7~R{~ ?<sxkc5<+\阯M+8{ڟo8zyȗsg< _o=~6Zs1z~.7ܼ3u^N?^8OKik' <ݯI}Y7hʡ/<{zo7F##I(nco1o_k[r혟x'OCYxpSO|Cڥ6v2=Ǵk}4NݠCG}Io_vmow{<:j>dH/o\⮺N3S~w}:uQqOӟ<#WO7X{.;8Ob~g?O;[yL]ojtG7cwSzj>CxO~?6zV 7hŇyEWފwv_Rnu>-=7f}xxkI{=^>9^=Ɨ6?\JiކSg9hsig_$I{/y~OEog K|X\z=K|p<πe?>m;{.3ƝQzV||vC>yW~]: Yhuh/g~r~gp-̣gi筁:͛鏽ռۃ>O.w{u\c~4%/ãC:Y/<8})7)Mq'<˿[Oн?#4qp]ym<3>|]G>?z '8'OR^vƙy7y6u(iFu>Z^ϥv}u/yl؝IxexgrAsgnj}>+Gq4 4`CݯJ;yyOBqʡs~ЙqqbYgvw8f+w9w1_OwΏ8|o^|oky|ӧ{~w_mv'Vz8R?Ovc#ׯ<Oz9z]wJa<:~qVAxY#ǟ 8f^ 66lS.tm]8KGIɃO_xŏX9CghFf.kd}cg_M?8(y>"ޫvf>F|ByۼN>M8۽kaơݔÿ{ ~yzduqȋ3GhOs^J?Fvyssk97li~)xGyo>ytr{k6Ns8ןz ?j?}Y>_#|=m۟sLoS~ƭOlގ7g'+wMh,k +ow~q}ypwנM /w?|R8?]pWept_*rlڟOy?v|xdkMN^D]3ɯOoO)W0~u~ǟwʱ7ڏ}_<#yHng >v5}l|s7i#y/=Vqϼ|zx!=N7]gƇsnC9{gW;ֽySgry|%OəUowx9I{Y~/ qnv{&kwg>4>]I;Y Gpw~}-.52/=Y;q{ֿ~ztw:o\aڕoޤG'a (5r#聽tm'=W/>b|xOt/|-x/,snJ=PrS?y{Sk_^ssQo$?wq|P%/햿{|n7_{Ny{7y<>)g?i/ppK]ǁYO=읜W?]ާg؁/oe_;{䝔?yOGYP}yk}~i/:?+}򏚿Ǻ}2x)_zy^|μh\ <8iv}k Gq{}c<+Rܷ>/3'w0]Y^syy!?j/j>\ :~{Q/7?N,`ϒz#7Sk]Ywqr"pWg"5oހFiqֽ~}y9~?Zsq[yGZ$w^YO/{9M?_F7|>i+\zʷ!WS ;5O=W{n3>r@'Pf^1Nj|wOWON/gZϙGg}'99:k(яQoEwm>q=~S_7W f^Qy~'E ޛ_Z/WySNW8w QA~V}vx^Wwhn7!>8oxzo.ؾ {yZ^oz7_~cY۵Ji|2t)E}nzςzyV \}q6N= ~H <>=vh=Kk\z_AwzVBڅـ%i?7?Z>ƿA#i7ҏ&>io]>{φog;Zf|^<Տ N̸2 ߝѣwxGN :ޫȻQ}c27/JgO>wgɿ+~ynl2W%+w{t!x[>o=qj}\s7rSiG7oSvt:R\ъGf̸ Fvɇ[o߸AcO9|L8O ^OG7z8!''N3m)ÿqj/{{myz<|e/SEg{WߦոڌUH{G8Ǽ̳p7摿m浺wx׼4~ /[}?ZZzݷ1zjy2?bck~oc>yԙM+hA/9ԯ߆|/x><^.pE/g?yռ6D{yK? n=zؓ=WY*p߾zQ؛Ӵy!;z<;k Vk㿻~ ^혿鏪+M=b{!}s)g_yҿz:OvM1[>mn_鮝ݫ<Y_ϵOvz 8'`?ڴJ^Jڧ_sz0~\/~|<ɳk^g=oy?MFRnokYsrw}7oOgXy54K( O^?k}]t߭G{J^5ϟ_~>L?v/'+~ã78 9w|߹IOzc_+ަ_ɳż׸ K}錻 {O*f܌=OF>[;~KWG rO=}>qgi^5Yڵ.øc}Cy_=~x>m3{Xguq 9[ȸ'7ki35'+~~G< y2N|)]~Oo>4$ߛ98orW;͛8.D'v*:M 'zS}=ziʟ[Fވ=u='z_ȃu̫q~g7t#{OwƗglW>/8ry'RGYρv_^zjQp\h%Oć޳js󃄾/}:<"|fs|=TO8))|vTRy^ y,fmqś~;^zqq;]˃W/r{6UaU=w¾0Q;2No^ |kO^觍KKhxz{x\yz=]銇KyF]\kq>ɕ+Og'zc3ys~v39Կ=ywz< ,;޴t ܕ[^vT4?[+7no?K}z{J~.|~|x+J˒q?|Nʣ'~xG4Woׂ׼0zlRUA[ϳ[yiL}ʏ;_X~~W=d{6N-'_ԯrqGgsnv?~8٩>͎S~Axʞ+qM=toT{3ߧk;g$qƑz |zz<;?W{ސs ݞ|=Z}*>/[s8C{4r1wƅCq'ѧxn;gwX}tɏ}lIi~׸ԯ=y+{xrkS>8zn!ZY~ =^-z9[Njt8yN{&ָ7tsyϥyލ|;anߡ|V\ƽs)g{{ZNwOzMqR>s>Ӟ8o_lz3=s{ʋ[}D^=HǣG;)N~.vL}.o? ^;W(S_9ʿO_Ŀ{{{{eO7g(C4ɓ<8Oݳ=yr~oI}nW?;1pGk{W#{~`֛qg^ߑz ]?K_M{?x=)G/Cꝧ+<ͯ>7oqyzn6鹻bἯ'nݟr =zB?>m}{~5Ѹ '<<V|MͣvӞ3׫t7?_]O[{?5~<'y?=űk' ][ĺG5vOn`'Oy8Os[?Wćg??~gލJ=W|HyV/?Sym;}qi?ywovO~w}6hیj~mڝ~7voz罐ʹih qzDJR޼7?8hct} ڡߤW}<__knG3<~a<[z|>vHrj^<w}u૝ϴk?Ѻ}n}Gy/ޝWԮt)GnzRn3z_Cxٞp|o}_: ~jToݵ\o]t{2.󑾿/S_>nqi׎{Zvmp=~5x1埅܏Z'ƥ|:D7jJuog׳cAǏՌIr<=\ _+~9\H+'~%g{ew73ˡ ܯߵz2χ?_K'zs?>p]_Oޟ=|+}'y|.?y!~'q=:yfCrXhڵ~/fCۻvnccoRZ~/CyCOYm%b~q>~_}&tMz0 KG~_:wtn// noy~G@y>B3N~kχ :/dr*~K^x}O|!_\ <_SG|?xo5_8M=舾eX7Ox>AgO8^b~/_п+c+Ky''ϡ>xҿu9|џ{.WBn=LO?i[K+OvDOϥ5|#C:3kAwI=z΋H}6O~W{=|s^~Jo @O֮dSܾ~ًo>ٸ3x!oj:dO .g/SS{㕎<;' ?qg?oy&\g}|&<o<3=r_߃GW?XK8襏x?FO'+z^f{˺ ]y$蕕sfב;&?Og2>[ ?;:|4ѯ唿#_zy+?p[>LӃ#iu.y^<=zڣǼ[^W~_oV/S6ۺJ?_Nǭߔȍ̀bWmO{/v L}_ \O<}\;:%sS8إ1p=|1?= |^O*. _+ov{|,ѳzeeC[v'#Y'Wõ{9["r|++__'?ѻu~ |"߫׬ӓ~y+W??rqx&W/;ȳ|\dOo7>rO.Gޙ:OŽzWʡ[Y_[~~-a_Wg #:‡軟 tr:zÕOZw 9K7^q|_B<)AѳE/Mr~ݔߌvͯ}gƇӥ_xO̻} ;|$Jo̘'|ٺ :{C<+wso ?c] c_ⅼL,~DK Eѳ$ЏY=*nn>A; ^geߵr }o'9Py)2?3+. 6oǼ^\ |2vuߓ]A4O>>\;(pv/xg?{\~g< v{5~{\f&^;]17oӮu` _FXǭϡWᅵ[Xc`syuW>n&Gj7߳oC2 %,_ X5L{_wrx>;!"q ̃vg~Hd[c{td$W?~}=C^?M}^a\GIE'q/ԯ8oGߴGOgsf~7o^fXƺ7}ɕyGvpFμY@Kf =yߤ穽ޯ/^w7qgD2|e^O?p}#{շS]Ş{os'עߴ."%tY7w*?ˋc^à7]8W7Wvg~}v-3/Ů_[|>9y{l[yOt|"ave^?d>u7;W??vO3Y/[r ;]t/M>ŏuUȇY#9Yg[Ǯ^]}~JkӔ_ݿwFS_Gܤwt o ÿ fgta/_M n_}/WuàG=z kv>Gǭ0OuniγOKgqX~_ UOg7қc=A'_::gwJFzP/qE!e7w>zi''ZO|?m2gwNlu@;g4e|Ч+#Yo~iq}k ~n<}מ]댜eoz9*A6cy~T/B<}_&؏C?˯NNkvuD>Dҧ;'/ǴOXJqBa˺vnż˚ƛo>q?"ٌC:媷kaW4.%탇ݸ!/ї_~ HOz }=}v"z1n>/[x <o+~BG|  ѷ8Y+Q|q+o̸x3qwОf?g|z1βG&3^>NA?loyc_X>}@+9yg]G_<181y^Muez_-ܼ}_ԏx<.SqC wy9?|3GOlBG/u}ݿ!|8أYo&ߝ0/r2_ ?'/zouulv?B?'e^ ?Ok^Iԫqk]hփ}[uc=| ^:^Hp|B\ }X~KoWz?|B}&F#p3Zz!sd'y4(o?jR޺O%^u8<.uz+7ɱW8yM?F?[t1#>-K|ε<z2C/z>Q]t|6Nʸ~nW~9}~sWrZ|WȤuG ӳkz6|۹ G c^syx̻{?pЃwۮ2/c_pYg2~;: >7 ymvŌ x^et_>gʉ'c+kݯO3ݰsf>\-}eghYOog~:MigxŴޓE؟soew_W Cqf7O}~-]tt)߭|9jso<֨/c:M U}<?~3ϯ ~3_# _-ߴg= 77/v;~2'kp '|vxcqͫw<2?79~q~zG_!u[uNM~g-=?g5 7~5=‡98~̼>ťXgo?:&o<gn ϗo1(}|';|B*q/9&k0z6SK~C/,zEK/d;J9ñIj/8wyWr>0>+oyoV/Cfuqλxc ;Ҏyp~y~ǰ^?AAO=93tl~Ыx Lzu ?nn|ґq#^ߠ;q RǗ |h jO2.vR?xCzL㳿%1_}OYO}Sw|X+`_y]?|C+n_ ?A|j}7CEz <ПW'xϠKsDuu`I5FDޝfXl?Ygy죒~e=Q>3qyX?7}}rչZvq\eaƋξov;G,q3wڿxUaЭѫvųw`v^;9xa~ɣg=qEFगeexg/}xyͺybpQNov:lTys;I}:5O~M>_#:'7|5oUʓ#_ sHEr_ _Yw|@%?})߅>9uɎGħм)o'YWw->/??/D_cGs@#]N_7L'N_Njklc'5CNMh>աn;%z4=%?q|e"}ʟ%ޟ?RJ|s7xcr;^Rvd޻y"'/mxs z㊳_&}]~D:?[7r9}Y; YW/#_O/دl>yOɳi3SyC/v}%n~wP?w57Ҿj> yXr-X5~+7ᇅWFNәg.?0=?Cc9k/5>'Boo/OLNXͻlAuu_Ӹ?9oIn>7/?}y=߅Էb|_^%f|m7OM_ CB)Gu|%㒟;~/B?hst_ɼ N:hۏ;zOy5M&<['s\9Ms*N_DqN?io7/ +ocG'_aw7}ֹv|3 Ao /#Oؼ]>:t2kmM_FY1.'"ߛ/'ASObO~9i~aYiTOR_>bҞw~s7&{#'wo&x{5]GŦ?îooث][֕#v,^A|~¢SWv7d޿h=տgo ϲ>1ܷg]t 旰g(pn3"_gbEu{oԁ??m?ub}m~s*[kk}B?'Vs2G1o|- uD?eqO~`  Qy~Q86{AD7~y-鰫IvG~rP|6h!K+=;3" /N.ٿ'W.{7{*^4K{ξ;qV?37~oڍ'5OQַ+A~Js42lgo˟< zɟ!s[?ݳe|=O^rR;}\tsi߸Џ(O0Jf}z40?eYGT;ϼ{zyU-wzq)O<>xY= cfr@{~' JNN6ygԺC~7027`flf|z/ѼNu?wc!3xl|Ig~׃c=5q_y/s*:wi]qW7E\xu[n_d4&l/u#7G/N{o)]|Ah?v777Oz=\$gQa>z?LwߍwRO#jv~os4^l Fr<3?BGN{ijw͗/}~f}ޫ`|~Q>)vVR}gGAi~:cf]֩}vtݼk_ y?|wߎc_yg~; >}o^|G'շv嚯)|giz_wz;ؾ&Fn[c _B~O ]<9 } h' ~8ty Yq8;齩+\{})kOyvޠ7'GkUIo?|??9=]]W}?y&=c݊ץ^5~<Ɵ3~2r\g|w1?9|G?++l>_ZKKs:{.ܞ]?'<=|Wz|/t?#XxOi/ώql޳ʡi||th֍q8KQ|ov~G's_W"W9Z?kA?fsOf\=/%&%Ofdk~\;T3=qS">v*ݽ~~gUx웛gíȫ}b[Y{xb'dު{-8^BAii/B'ﴃz//|z`אo<xn^{p7Eڷkeuw g__V{`?=a><9| w ҏ#s˺wo)7{>80z+k˟d?jG/|h+ =7?nU\3}799^̸*Zd?TzOX_gqxPSc_y8߂><&[^e~)xƏkWYWΣ;hRhi뽪18(G\ o7"}i{z?o>v'k_-lϤǹ~l:{`3 yw5:L_O{| Ddrŗ/>㴏şߵn Q>+>':{`١2HOwVGwv]O8{'^ͼ󗘿m=K^gԧwygm=˽?jO2.w୾~ޓj}x$/NƧ3|\AKcWˁpo繷+gΫ {.oʣ~YűN{>$\_U|23]DN>}^]ϴ_}۾;9wob=yϾ/~}ȓG;xg_,YfRu߄Oa/?3?zx޴G⟪^rt_#ϔo'ݟS{ާ7s*1y_v{"yc^|ϲ/~2e< |gA3Ƌ<эy&+Qk6Wӷ+`;ׂѕ}#pgotc~{WoG<|9x _&G6*c=<_ n~wkݼi%x轾$>nޠ+~#.*oWz5߭}@Gq?y>>'xw_|*_o'Ίq _3<9iyڬ/_Y{BwG5nA_~Yg_ԼM}3~N;{+=~%G*"]}xp=I~ApEڥ_@B[/{I^LOO@7I?c': oF=~Vz3}}] l|wrm!]_\_7%w~2O^[ͼS)gp1tm]Iz8#{8k>|gv=+O o?wEv>`מu߬kzq섃=/ON?a_/֏7x]^zn(%]=}s|[|O?K@o^zb7O!s6}څqǪn~vw|8~sMrR|F6^wYlzn ?m_~X>_dO C?)C/?|~g_RyR1y3יǧ?/\<: Oī5o!wz/x Q^r?__yz_=\yO?͗]|N ~v|;.O=G#zL{_y^=%{FAwxWtO|ϓܢg??z|</  <S_~.7͐Ã/ԿzŇ|ǿ{]þ09-2yL^K2.5S˺/zn~Ȟ'MqЃ9J?米F=~[߯[+zzLyr|Owo=_5:zԧ5O0ua}5 nI>87{~'9ʔcg G3zq Dع}=ռ7>ϞFyڟikv~ ~ֿ.+vu?LϚ#!xM2n8/1R>h9}~yCvzI^1Ġ#3w-Aq9siϏ|߰ϟn^</3Ͻ_%x'Mh7n|;Y/ͯ?3f%ޣ6Bz?'z${;JrMN|Ϙ+CҮyoOōgؕۯExo^/!sON = >W$3}y>4r1pM}?=n;W#zG@᏿#:;i<Od|C7p-~i ߳W=g ·ѧg~#<艽o`}ًZq=K?'-Gě+_Nl)siOU*yoOq>3FQه3.-X+|A_s^yRçxthw[gžh+^|oi/~޸\O~~7=t)>Oo:h~qil=ӏizw_&f/ʋv%'9';M`k`}ޮ9;G,p>in>{~#r~g#nDyz5yM_bW;_`]ң/=VӼo͑ߍ_;魯|w%7ODwƿ;()q3z#E߽w<{o{A硝;?'_fw9{?8G{\.||ނ_ƁC_MD-~>5vt$g˽Ao"1 !y; ɴ+.9 z;ϑ6fЗW?O?aY8הv#K96dڡ7O]ѽ<1iu޻;=` fK+ ֓{o1s2r(y7]!|_% >L~o|X߶>S>7Aq>yBg][缿2N'Cd7fƬtj 4d=tߴ>82vtshLy1[\?{]⁓"kgH}j?¯w2J !4o\mKķn/~/_>A'm}k>oOK j,LJGhR/w#.[G޿/+ :p<ޅr2擾 /l~w~~b_۔; 9ò3_W>Bϡ?>JNGUo?_睇?ޟwv<'z7}i s?:_׸ώ_~#cWGBA^g\ҳO]{M𼇤/`9rڵW/~|YϹ{Qꉓukç3t\=I?og|7-#pзռ~{>uK^LK#i?/|?j!/A8z\Фq3p.̓gdK=D\WϫgRnԛg~[iza}Oo?A7 x.6.yO8/=noiޑtބr~ZKdw7Nçh]G?`}ȩ,/O?ryQֻ8Z''n/ =)^!y^);..uW?^y~, M s<+3:FA3nzby5_iG}~J0r }_e{Zz Jy~u~An\|K4otܾ3oi}{$xş7ѩ~d~{^-sAYO{PGƧ ~p9{wrJy?~ʼU|GWs+z @mNy9A _<[F5Ϡ+=oqg۞dzO8?^Yg3/K:?;=<'rzOXG+֣~?+.?ϧs{|Q^>E|2|_?Ad7>6M;z0|)/>i!p'J}{sn>o;o_ ūWweodjܳS߀^OF3{R 9 ROnj>MM{2;ϼ|87:u~nOK;[KٍNϛ;RN ?Xn?!\w8iۼC_!ҿ<3n_^D_wWp}l)ZƇ2>0>^vonX^ֳy◲?7zo>Wt8cDu^"!)EM:v47t(R@ DH= 9~>G ^˘6Y_U'ee̕yzsc#DupkOG)>ɇ_KOo>^ztuGoR<ҼQ077?Px?|ϕO*%gzp_Yɋu׿]O|ɷV>OsOz~^T|5%\|m(~}>h__\w=/}]_U|h~@˪>+y\wC.h?[*5~k4./ͨn{뎟:f{ݿ ||WG~Քoj'z<*zCzrKtܩP{Cy(H剪"ywrq*?o]]>Aߝ.Oh;^iMgw*_y|>C|OVh^RU:C?i_%N*}{+?~ʿ~ϓ ^GWW;|ר?~z^_x}^ͫiK;s<^1GqC~}W|8kTqwR=߬|zCZ+~~yCGFT>4o﫟*ϯpOϯv'q3_ch\S-W{oϭzVzu+睮_G~~yw{'|_7WߩtyUrzb\uP8Z]ꝗA+wxtywY-qזw?WSwz*V Gx<麌')s@yӼ5N4[x5?~_sx߫l>Y=uS>5>{r"?y'wy.};'z+(?<ʧ\/캕5^|U9S8bϫ|S9^-*_w}^j筋/㑮c~僷/^<Gy*]={KʧsG!ˮ;WCTɻ2JWcnuuOg{Wt9zgΏ>w #o'܈o_?yv¸ut}:W~Z>u2n^b=_v_U/^wv^゙{ GMïy+Onh.)j,*^k=v>cO+ʿxwT=O7OGq{zM-^?~qxgxwzwOˇ?פv}|^\K/^e;xiAS [e~E'xū˭~Tzv92>wzݿo[_͉SoN;8煅}ﯞ9VUy%O/W}sO]ߝ?}_W(>=|QT9k߼zj_#q74.W,~'>.QZyGk[,+=j>ORuX?}~ޣSr⇮Gҫs|:ʁ{!~}>>`ϧ뽥_CZ߯],ݗ~^D~Rx7>8͸z^||_7*nOu_?sa/}i[~jE|.>xnﯞ.ozg@ëRj|kY`13O}՟2V:ݏy3ꏷ>~ Gx{;%u}mg ~y_X~n'}Nk&w<}7uY+?yQ^Pqu/ѫx~^U59?Ϟ}ϽQz=s_tq`gϿu]]<=?u}3o~r_zK.qljzίi?\tRvq5xx}^[g8:}>lK~]V[9ynwzNoo81GP·7b=??jOzouU>_r'_ܟ7?⚯_e[㩯R#yb!ݿqT=m~'~X>->|G皧r%{^;vx~Y{^\y񌻼e}׿C[?KTUR9z;R}~L9e?~e>W?>_O{Ƴ GuKCK˷eǍ^>X։ܨQ\޺>_G޿}F>W]n}{Kj?U_Q8zΥR:(=_]O9ă;<>Բֱ~/}%y|^F8|1^)Ү?uXABu|Z7oXvt_ͻ-wZ|}.w|jסr.'BuJW?i[/17Ny˿^ve>\>(v齥{VK:,{}gK_u)}s}xQ/T9e/_?Ow? ǮcS|տ#^kxmׯt-ܲ[_W>I^O,Yg_웩p<᪜[ʲ+ݔO(N__m8ߧ^_r)J']ʹ3˾r*;oK^|u+]_7~^|U?پ-}v9|R:~cu|5_^y?~]Y}=ߏyw췤x+}.g~{}}n,oݯ7z:_=uJ+Ϸ7tOϓ[><˳'?C[X=Qso֩>,}ZxVc3˷>/ߟz;J⵬W>R|*:+>}f%e]-|ޝoz^?slsm@f/X-qP>>j}gw/ċ>gu(]>ϻzTy|/ث~_k>/I~u[}'*yFW?|>o79߾_s9s/vTYIe%_֧[x7uz}X9u.}l&]}W\n>^[˃myit_՗eMR_?Ƿqtqe]qhKǥ?z:7ޟÚ/}d^[;^Ϳ'8Xz/x|XKW>s}-|tz:Tܗze_&ʍ?ǟUzje_=WϽ u{_||[=Ny+9hJ^<|e~Wsc^+xw8,qps__~{_ntkK'KǞTT/m~#xǞOX瞉U˪̣}ݮnGJO )%姕gi|BwxT>k<Wwdz:\P{}'Q:)X:G9~r]Gc ^gp\t[}5߫s}:?y:ϧ>Rz*eަ9-~}^T.۫#ڗ?qOU^~||v c_g}}ko~-~,>N2Oo\_nX~χvGOR?F{?z(yɞ>6t?ʸuW3^9_27_yݯ_'q=)=ţ,ԽG;=>*W ߟܹL{]{m7VNןw}>Zhһ꡵Vn~ˣ~\kk)OƗޟyN]^UV/]w.]~o^V=t]O<N7_tp(_);~v>]e棥S^yо/xe[K__w7z%o]zʙWp+oNz~Y|~'ןϣW~S>u9_RV=y~6g~{1sخg7{?d \I_۟[W;^_O/^n-~*T|[8^W |J?\˽evK7|m J_ʏ{qgO\X: wVr]uvx*/+/?1nv:ޯYxt^_dcy]gv}ʯWzqusj}n74/u*JZ9Il=vdןןӗ~W=Py07Džz}ܨ%㜏U>su;g//j~~)?oǗ|o~.󟊗]2cu{|3js\k羃?ޢ}d<ρ|}J[g)\G]>W9',o|-8qS]·|~5.v/y;^ʓso'|!2N8tqǛV|=kxQ^>t>o׭.V:qpT*'7_7Ǐ<\7}_ヾZCEfʽD-;cWvV;ǹ_xzw^[?V|{[ʻ~Ǐ-]{Posv{d=);~i+>s׼/?t~ӝߪ?G,\PxõQ:~ǩ~/T}kFHҮ/;?P~~U(_s|O?,]o<_o^T?~?Gg>W9q[˯>UV^{J7e?ݿuzvz˾aJG+O?YZ}^NA/勾o}Wie帧#Ke^Qm19Ǐ<AfoV:UNW珕ߴ}\=5y&wځ*N7ONjz>T=˖O}^+oYp:rx{J_V}}fU}ׅ(s ϟ8WqO6^cVVo{>>9w3_/6~:.?JsW]^@!|ߍeVS8܉y8;ש8±x\*߷9߫~W>/G+,[oqXsΊˊ}\}ٿNx*W=e#K硕+W|Y]ՇO-|>o/n<;>+ݞ[q#}O[x>.GƏ7v<;}m~Yzg{~w;csO~oϳfrE_WU}˛Ѷ8DϳXz&ߟ*?>gY|_^OO(?8jq|K_Ky=3^.{]~3\Q(~ evtp{Jq]Nߧ;~VoV{~͇or}Ϸ5/Oz7_u<}?xrn>?>/_+߾}uEqx5~?#~Gߧqm^e|ZpoV}{?ۻ? V|׳83?:ߧY߯,V?/ }'<=?}?4/}y`hYhןeqHɛqfT^uO]?ߩޯ^/}|Gzpz\}͋\N}]R?x{.})tYxϻ}_dz~CsO}s:޷9[`x㝎^}œ?玹{}z}˽|GMy9ʾF{㓏#}]w(?UϽ_<'ʓ?_OpuJG+>/7.㿖_X>*:kNWquxzv鶌{i߷}=U?ƸYI*=3ޯqoXK>9}{>AvnOt^p{g +~V8e^_}xiT< 離\t9K=}H}->o+J'O`oU/o]^UNʏϿ-sr=?f~E~~)iig^ǫ˽wG oy7ᵯWC3S}[~y}]Fnt?Tz{/-]Ogu~Wg>?:s{{2jy?oT\RzZx>G1~E>~\Ox^Y>Jw;GʥO]֓),<Gߏ?I{-}y<>/G{{uLq2j墟ۡ:y.,Z/>^螏7wr~z~V_|/nt/˟r㷽uٯ#?4uV}}>_oӽ<׸`ozݐvۿC s_|_<J N1ߧԞcOK;k>Qw=iW1^qڷ}V[{->_(^O7ϙ},?Z}qyGVz V/:Z{.¸)>AvW{>㜚^,.x{׼)X5v̟㮽9~L/QGi_ǥ[w}NzuE=eGxQ~ѯ֍/Y}\~|>}zJ|Gv}}l~IJ߃kYZ/G?qܟ~ϻydˣϭg)hw>OeÊJGS<#<_A]tgYa='ΫWe\g3,~_pkz9?u{j轕W||] -{˻9Py^ϔgk._>ߵTZ~Y}㜗eݣq%}3[z9S|}-/M-\[i\պP#eg}=~?:,(ejyri ^~ݟGV=v~!-Ps |_y|O㇇ގyz/C}?К>o~R~mW:T\5~Ω]U9?^6x[ʵWP9= ןcW{[˼nߺ;}*߿@^s|oӿꫯBOK{o囗,?~#˟e_RqʷR-ߝW*:C?YӟS:wƲ~˫(}}?1ܻ_~}}ϟr/ϱߟeg]W~WbC/r(^_V޿z8,<wZp/s.ݳ]ó~ȧeYX{}Xz.;w 3^}e|WuCzU*},^=_By齷\X9//߶B==|Nu:|KOs'}=W]f_\ֳY|>(ݭ8w]ߟ޿~/Z >_qp7_?j٫,?|'q]_oM{*_ߏ'}6_/<~-랕JoU~[:=esٗU_яµpU=`e;\o/<>x~fxٗԾƇ幑?o<:f}~rfj{V/||cw|}yz}-;=?gi><ݾ_$>6|?xz7f짢x[~˲ʅ?XtJw_v캗c)|sV<ګ}w|^ɲ.qX~Az>e<ʱ;9/_SC>oz~/ʯߧ-륕#vޞxSpji?gɮ]Wܯ~_pzYkpգSKﭼf87?^;_^.ڟt~Qܟ_qן+jx/s=~_|۞U}_`>[6->[CI^+MK*kZv{p ʍ-׽|e7R뾿|1ݓq7Kh,]}}+ПwGj4,^>GqN+{K'ǯYz:oKx-ϯ?9N}ϟg׳}|X|I+>~SP?rk̳YGq/s!;y&;} co7䜶zޛ:,eeo ^ɗ}s֮Uţ/Ѷg4_zx:ʏT}?w?@:YƷTܟ`C|<? zyLy:YX3^b}aXχ>\gcGC~6/S=m;9B_8?}<9w8?/ωtҡs8|~n±p}|,uxje^Izwtv?ŽfoOt>ޤx~q-뭭|-W.|Oͫra|z$ݎZyy=re_Wa7ίo wjg|xO~7t}},_z\ǹgy^sMKyW>&oNϯ疎>þ{V93|?O>??~}>x}>x}>x}>x}>x}>x}>x}֎>x}>x}>x}>x}>x}>x}>x}>x}>x}>x}>x}>;?ڿ;~ww~?_o߿Ư?ǿOq?OO~ɟ۟͟?wwWQo~_gO/?|{O?_?_?O/rgſl{c$~|?Jlc8u;/GW_muaDFtaDFtaDFvadFvadFvaTQFuaTQFuaTu[u[u[u[u[w{w{w{w{w{qtGqtGqtGqtGqtGqvgqvgqvgqvgqvgquWquWquWquWquǗ_Ο3Ϝ?k},ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װj|e?w߅7>>>>> 7n @p 7n"Dp&M7n!Bp -[n!Bp7! nwCpw#wG;pw{ @=p{ D'=pO{"D½p/{! ^BzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW* * * * * * * * * * * * * * * * * * * * * * * * * *J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J * * * * * * * * * * * * * * * * * * * * * * * * *j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6jvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN.................................................~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO =^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/6i8]E @訲7rh~)F[8?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?||{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷O~v??,hexbin/man/0000755000176200001440000000000013616020657012310 5ustar liggesusershexbin/man/pushHexport.Rd0000644000176200001440000000161013171627113015122 0ustar liggesusers\name{pushHexport} \alias{pushHexport} \title{Push a Hexagon Viewport ("hexVP")} \description{ Push a Hexagon Viewport (\code{"hexVP"}, see \link{hexVP-class}) on to the tree of (grid) viewports, calling \code{\link[grid:viewports]{pushViewport}}. } \usage{ pushHexport(hvp, clip = "off") } \arguments{ \item{hvp}{a hexagon viewport, i.e., an object of class \code{"hexVP"}, see \link{hexVP-class}, typically produced by \code{\link{hexViewport}(..)}.} \item{clip}{which viewport to push, either 'on' or 'off' are the allowed arguments, see details.} } \seealso{the underlying \code{\link[grid:viewports]{pushViewport}} from the \pkg{grid} package. } \details{ A hexagon viewport (\code{"hexVP"}) object has slots for two replicate viewports one with clipping turned on and one with clipping off. This allows toggling the clipping option. } %\examples{ %} \keyword{dplot} hexbin/man/plotMAhex.Rd0000644000176200001440000001456113171627113014503 0ustar liggesusers\name{plotMAhex} \alias{plotMAhex} \title{MA-plot using hexagon bins} \description{ Creates an MA-plot using hexagons with color/glyph coding for control spots. } \usage{ plotMAhex(MA, array = 1, xlab = "A", ylab = "M", main = colnames(MA)[array], xlim = NULL, ylim = NULL, status = NULL, values, pch, col, cex, nbin = 40, zero.weights = FALSE, style = "colorscale", legend = 1.2, lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 2, maxcnt = NULL, trans = NULL, inv = NULL, colorcut = NULL, border = NULL, density = NULL, pen = NULL, colramp = function(n) { LinGray(n, beg = 90, end = 15) }, newpage = TRUE, type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"), verbose = getOption("verbose")) } \arguments{ \item{MA}{an \code{RGList}, \code{MAList} or \code{MArrayLM} object, or any list with components \code{M} containing log-ratios and \code{A} containing average intensities. Alternatively a \code{matrix}, \code{Affybatch} or \code{ExpressionSet} object.} \item{array}{integer giving the array to be plotted. Corresponds to columns of \code{M} and \code{A}.} \item{xlab, ylab, main}{character strings giving label for x-axis, y-axis or main tile of the plot.} \item{xlim, ylim}{numeric vectors of length 2 giving limits for x-axis (or y-axis respectively), defaulting to min and max of the data.} \item{status}{character vector giving the control status of each spot on the array, of same length as the number of rows of \code{MA$M}. If omitted, all points are plotted in the default color, symbol and size.} \item{values}{character vector giving values of \code{status} to be highlighted on the plot. Defaults to unique values of \code{status}. Ignored if there is no \code{status} vector.} \item{pch}{vector or list of plotting characters. Default to integer code 16. Ignored is there is no \code{status} vector.} \item{col}{numeric or character vector of colors, of the same length as \code{values}. Defaults to \code{1:length(values)}. Ignored if there is no \code{status} vector.} \item{cex}{numeric vector of plot symbol expansions, of the the same length as \code{values}. Defaults to 0.2 for the most common status value and 1 for the others. Ignored if there is no \code{status} vector.} \item{nbin}{ Number of bins } %% << FIXME \item{zero.weights}{logical, should spots with zero or negative weights be plotted?} \item{style}{string specifying the style of hexagon plot, see \code{\link{grid.hexagons}} for the possibilities.} \item{legend}{numeric width of the legend in inches of \code{FALSE}. In the latter case, or when \code{0}, no legend is not produced.} \item{lcex}{characters expansion size for the text in the legend.} \item{minarea}{fraction of cell area for the lowest count.} \item{maxarea}{fraction of the cell area for the largest count.} \item{mincnt}{cells with fewer counts are ignored.} \item{maxcnt}{cells with more counts are ignored.} \item{trans}{\code{\link{function}} specifying a transformation for the counts such as \code{sqrt}.} \item{inv}{the inverse transformation of \code{trans}.} \item{colorcut}{vector of values covering [0, 1] that determine hexagon color class boundaries and hexagon legend size boundaries. Alternatively, an integer (\code{<= maxcnt}) specifying the \emph{number} of equispaced colorcut values in [0,1].} \item{border, density, pen}{color for polygon borders and filling of each hexagon drawn, passed to \code{\link{grid.hexagons}}.} \item{colramp}{function accepting an integer \code{n} as an argument and returning n colors.} \item{newpage}{should a new page start?} \item{type, xaxt, yaxt}{strings to be used (when set to \code{"n"}) for suppressing the plotting of hexagon symbols, or the x- or y-axis, respectively.} \item{verbose}{logical indicating if some diagnostic output should happen.} } \details{ An MA-plot is a plot of log-intensity ratios (M-values) versus log-intensity averages (A-values). If \code{MA} is an \code{RGList} or \code{MAList} then this function produces an ordinary within-array MA-plot. If \code{MA} is an \code{MArrayLM} object, then the plot is an fitted model MA-plot in which the estimated coefficient is on the y-axis and the average A-value is on the x-axis. If \code{MA} is a \code{matrix} or \code{ExpressionSet} object, then this function produces a between-array MA-plot. In this case the A-values in the plot are the average log-intensities across the arrays and the M-values are the deviations of the log-intensities for the specified array from the average. If there are more than five arrays, then the average is computed robustly using medians. With five or fewer arrays, it is computed by means. The \code{status} vector is intended to specify the control status of each spot, for example "gene", "ratio control", "house keeping gene", "buffer" and so on. The vector is usually computed using the function \code{\link[limma]{controlStatus}} from package \pkg{limma} and a spot-types file. However the function may be used to highlight any subset of spots. The arguments \code{values}, \code{pch}, \code{col} and \code{cex} can be included as attributes to \code{status} instead of being passed as arguments to \code{plotMA}. See \code{\link[graphics]{points}} for possible values for \code{pch}, \code{col} and \code{cex}. } \value{ A plot is created on the current graphics device. and a list with the following items is returned invisibly: \item{plot.vp}{the \code{\link{hexViewport}} constructed and used.} \item{legend.vp}{if a legend has been produced, its \code{\link[grid]{viewport}}.} \item{hbin}{a \code{hexbin} object built with A as the x coordinate and M as the y coordinate.} } \references{See \url{http://www.statsci.org/micrarra/refs/maplots.html}} \author{Nicholas Lewin-Koh, adapted from code by Gordon Smyth} \seealso{\code{\link[limma:plotma]{plotMA}} from package \pkg{limma}, and \code{\link{gplot.hexbin}}. } \examples{ if(require(marray)){ %% for the data only --> data(swirl, package="marray") data(swirl) hb <- plotMAhex(swirl[,1],newpage=FALSE, main = "M vs A plot with hexagons", legend=0) hexVP.abline(hb$plot.vp,h=0,col=gray(.6)) hexMA.loess(hb) } } \keyword{hplot} hexbin/man/colramp.Rd0000644000176200001440000000332513171627113014233 0ustar liggesusers\name{ColorRamps} \title{Color Ramps on Perceptually Linear Scales} \alias{ColorRamps} \alias{LinGray} \alias{BTC} \alias{BTY} \alias{LinOCS} \alias{heat.ob} \alias{magent} \alias{plinrain} \description{ Functions for returning colors on perceptually linear scales, where steps correspond to \sQuote{just detectable differences}. } \usage{ LinGray (n, beg=1, end=92) BTC (n, beg=1, end=256) LinOCS (n, beg=1, end=256) heat.ob (n, beg=1, end=256) magent (n, beg=1, end=256) plinrain(n, beg=1, end=256) } \arguments{ \item{n}{number of colors to return from the ramp} \item{beg}{begining of ramp, integer from 1-255} \item{end}{end of ramp, integer from 1-255} } \value{ returns an array of colors } \details{ Several precalulated color ramps, that are on a perceptually linear color scale. A perceptually linear color scale is a scale where each jump corresponds to a \dQuote{just detectable difference} in color and the scale is percieved as linear by the human eye (emprically determined). When using the ramps, if \code{beg} is less than \code{end} the ramp will be reversed. } \references{ Haim Levkowitz (1997) \emph{Color Theory and Modeling for Computer Graphics, Visualization, and Multimedia Applications}. Kluwer Academic Publishers, Boston/London/Dordrecht. \url{http://www.cs.uml.edu/~haim/ColorCenter/} } \seealso{ \code{\link[grDevices:palettes]{rainbow}}, \code{\link[grDevices:palettes]{terrain.colors}}, \code{\link[grDevices]{rgb}}, \code{\link[grDevices]{hsv}} } \examples{ h <- hexbin(rnorm(10000),rnorm(10000)) plot(h, colramp= BTY) ## looks better if you shave the tails: plot(h, colramp= function(n){LinOCS(n,beg=15,end=225)}) } \author{Nicholas Lewin-Koh} \keyword{color} hexbin/man/hexVP.abline.Rd0000644000176200001440000000303613171627113015060 0ustar liggesusers\name{hexVP.abline} \alias{hexVP.abline} \title{Add a Straight Line to a HexPlot} \description{ This function adds one or more straight lines through the current plot; it is the hexbin version of \code{\link[graphics]{abline}()}. } \usage{ hexVP.abline(hvp, a = NULL, b = NULL, h = numeric(0), v = numeric(0), col = "black", lty = 1, lwd = 2, \dots) } \arguments{ \item{hvp}{A hexViewport object that is currently on the active device} \item{a,b}{the intercept and slope or if \code{b} is \code{NULL}, an \code{lm} object or a vector of length 2 with \code{c(intercept,slope)}} \item{h}{the y-value for a horizontal line.} \item{v}{the x-value for a vertical line.} \item{col, lty, lwd}{line color, type and width.} \item{\dots}{further graphical parameters.} } \details{ The first form specifies the line in intercept/slope form (alternatively \code{a} can be specified on its own and is taken to contain the slope and intercept in vector form). The \code{h=} and \code{v=} forms draw horizontal and vertical lines at the specified coordinates. The \code{coef} form specifies the line by a vector containing the slope and intercept. \code{lm} is a regression object which contains \code{reg$coef}. If it is of length 1 then the value is taken to be the slope of a line through the origin, otherwise, the first 2 values are taken to be the intercept and slope. } \author{Nicholas Lewin-Koh} \seealso{\code{\link{gplot.hexbin}}, \code{\link{hexViewport}}, \code{\link{hexMA.loess}} } \keyword{aplot} hexbin/man/smooth.hexbin.Rd0000644000176200001440000000611413171627113015362 0ustar liggesusers\name{smooth.hexbin} \alias{smooth.hexbin} \alias{smoothbin-class} \title{Hexagon Bin Smoothing} \description{ Given a \code{"hexbin"} (hexagon bin) object, compute a discrete kernel smoother that covers seven cells, namely a center cell and its six neighbors. With two iterations the kernel effectively covers 1+6+12=19 cells. } \usage{ smooth.hexbin(bin, wts=c(48,4,1)) } \arguments{ \item{bin}{object of class \code{"hexbin"}, typically resulting from \code{\link{hexbin}()} or \code{\link{erode,hexbin-method}}.} \item{wts}{numeric vector of length 3 for relative weights of the center, the six neighbor cells, and twelve second neighbors.} } \value{ an object of class \code{"smoothbin"}, extending class \code{"hexbin"}, see \code{\link{hexbin}}. The object includes the additional slot \code{wts}. } \references{see \code{\link{grid.hexagons}} and \code{\link{hexbin}}.} \details{ This discrete kernel smoother uses the center cell, immediate neighbors and second neighbors to smooth the counts. The counts for each resulting cell is a linear combination of previous cell counts and weights. The weights are \tabular{ll}{ 1 center cell, \tab weight = wts[1]\cr 6 immediate neighbors\tab weight = wts[2]\cr 12 second neighbors \tab weight =wts[3]\cr } If a cell, its immediate and second neighbors all have a value of \code{max(cnt)}, the new maximum count would be \code{max(cnt)*sum(wts)}. It is possible for the counts to overflow. The domain for cells with positive counts increases. The hexbin slots \code{xbins}, \code{xbnds}, \code{ybnds}, and \code{dimen} all reflect this increase. Note that usually \code{dimen[2] = xbins+1}. The intent was to provide a fast, iterated, immediate neighbor smoother. However, the current hexbin plotting routines only support shifting even numbered rows to the right. Future work can (1) add a shift indicator to hexbin objects that indicates left or right shifting.\cr (2) generalize plot.hexbin() and hexagons()\cr (3) provide an iterated kernel.\cr With \code{wts[3]=0}, the smoother only uses the immediate neighbors. With a shift indicator the domain could increase by 2 rows (one bottom and on top) and 2 columns (one left and one right). However the current implementation increases the domain by 4 rows and 4 columns, thus reducing plotting resolution. } \seealso{ \code{\link{hexbin}}, \code{\link{erode.hexbin}}, %MISSING \code{\link{hthin}}, \code{\link{hcell2xy}},% \code{\link{hcell}}, \code{\link{gplot.hexbin}}, \code{\link{hboxplot}}, %\code{\link{hdiffplot}}, \code{\link{hmatplot}}, \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}. } \examples{ x <- rnorm(10000) y <- rnorm(10000) bin <- hexbin(x,y) # show the smooth counts in gray level smbin <- smooth.hexbin(bin) plot(smbin, main = "smooth.hexbin(.)") # Compare the smooth and the origin smbin1 <- smbin smbin1@count <- as.integer(ceiling(smbin@count/sum(smbin@wts))) plot(smbin1) smbin2 <- smooth.hexbin(bin,wts=c(1,0,0)) # expand the domain for comparability plot(smbin2) } \keyword{misc} hexbin/man/hexViewport.Rd0000644000176200001440000000355513171627113015127 0ustar liggesusers\name{hexViewport} \alias{hexViewport} \title{Compute a Grid Viewport for Hexagon / Hexbin Graphics} \description{ Builds a \code{grid} viewport for hexagon or \code{\link{hexbin}} graphics. This builds on the concepts of the \pkg{grid} package, see \code{\link[grid]{viewport}}. } \usage{% see ../R/hexViewport.R hexViewport(x, offset = unit(0,"inches"), mar = NULL, xbnds = NULL, ybnds = NULL, newpage = FALSE, clip = "off", vp.name = NULL) } \arguments{ \item{x}{a \code{\link{hexbin}} object.} \item{offset}{a \code{\link[grid]{unit}} object.} \item{mar}{margins as \code{\link[grid]{unit}}s, of length 4 or 1.} \item{xbnds, ybnds}{bounds for x- and y- plotting range; these default to the corresponding slots of \code{x}.} \item{newpage}{logical indicating if a new graphics page should be openend, i.e., \code{\link[grid]{grid.newpage}()}.} \item{clip}{simply passed to \code{\link[grid]{viewport}()}.} \item{vp.name}{name of viewport; defaults to random name.} } \value{ an S4 object of class \code{"hexVP"}, see \link{hexVP-class} for more, with its main slot \code{hexVp} a \code{\link[grid]{viewport}} for grid graphics. } \seealso{\code{\link[grid]{viewport}} and the main \emph{\dQuote{handlers}} \code{\link{pushHexport}} and \code{\link[grid:viewports]{popViewport}}; further \code{\link{gplot.hexbin}} and \code{\link{hboxplot}} which build on \code{hexViewport}. } \examples{ set.seed(131) x <- rnorm(7777) y <- rt (7777, df=3) ## lower resolution binning and overplotting with counts bin <- hexbin(x,y,xbins=25) P <- plot(bin) xy <- hcell2xy(bin) pushHexport(P$plot.vp) i <- bin@count <= 3 library("grid") grid.text(as.character(bin@count[i]), xy$x[i], xy$y[i], default.units = "native") grid.points(x[1:20],y[1:20]) # to show some points rather than counts popViewport() } \keyword{hplot}% ? \keyword{aplot} hexbin/man/erode.hexbin.Rd0000644000176200001440000000522113171627113015145 0ustar liggesusers\name{erode.hexbin} \alias{erode} \alias{erode.hexbin} \alias{erode,hexbin-method} \alias{erodebin-class} \title{Erosion of a Hexagon Count Image} \description{ This erosion algorithm removes counts from hexagon cells at a rate proportional to the cells' exposed surface area. When a cell becomes empty, algorithm removes the emptied cell and notes the removal order. Cell removal increases the exposure of any neighboring cells. The last cell removed is a type of bivariate median. } \usage{ erode(hbin, cdfcut = 0.5) erode.hexbin(hbin, cdfcut = 0.5) } \arguments{ \item{hbin}{an object of class \code{\link{hexbin}}.} \item{cdfcut}{number in (0,1) indicating the confidence level for the limits.} } \value{ An \code{"erodebin"} object (with all the slots from \code{hbin}) and additionally with high count cells and a component \code{erode} that gives the erosion order. } \details{ The algorithm extracts high count cells with containing a given fraction (cdfcut) of the total counts. The algorithm extracts all cells if cdfcut=0. The algorithm performs gray-level erosion on the extracted cells. Each erosion cycle removes counts from cells. The counts removed for each cell are a multiple of the cell's exposed-face count. The algorithm choses the multiple so at least one cell will be empty or have a count deficit on each erosion cycle. The erode vector contain an erosion number for each cell. The value of erode is 6*erosion\_cycle\_ at\_ cell\_ removal - cell\_deficit\_at\_removal Cells with low values are eroded first. The cell with the highest erosion number is a candidate bivariate median. A few ties in erode are common. } \seealso{ \code{\link{hexbin}}, \code{\link{smooth.hexbin}}, \code{\link{hcell2xy}}, %%FIXME\code{\link{hcell}}, %% \code{\link{hboxplot}}, \code{\link{hdiffplot}}, %% \code{\link{hmatplot}}, \code{\link{gplot.hexbin}}, \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}} } \examples{ set.seed(153) x <- rnorm(10000) y <- rnorm(10000) bin <- hexbin(x,y) smbin <- smooth.hexbin(bin) erodebin <- erode.hexbin(smbin, cdfcut=.5) plot(erodebin) ## bivariate boxplot hboxplot(erodebin, main = "hboxplot(erodebin)") %% MM: This looks wrong -- both the graphic and the logic in "par" here : # show erosion order plot(bin,style= "lat", minarea=1, maxarea=1, legend=FALSE, border=gray(.7)) %% FIXME: {compare with example in "hexbin0"} grid.hexagons(erodebin,style= "lat", minarea=1, maxarea=1,pen="green") xy <- hcell2xy(erodebin) library("grid") grid.text(lab = as.character(erodebin@erode), xy$x, xy$y, gp = gpar(col="white", cex=0.65)) } \keyword{hplot} hexbin/man/hboxplot.Rd0000644000176200001440000000660213171627113014436 0ustar liggesusers\name{hboxplot} \alias{hboxplot} \title{2-D Generalization of Boxplot} \description{ If \code{bin} is an \emph{eroded} \code{\link{hexbin}} object, i.e., an \code{erodebin} object, \code{hboxplot()} plots the high counts cells selected by \code{\link{erode}()}. By default, the high counts cells contain 50 percent of the counts so analagous to the interquartile \dQuote{range}. The function distinguishes the last cells eroded using color. These cells correspond to one definition of the bivariate median. %% FIXME ^^ (bad style, content +- ok) } \usage{ hboxplot(bin, xbnds = NULL, ybnds = NULL, density, border = c(0, grey(0.7)), pen = c(2, 3), unzoom = 1.1, clip ="off", reshape = FALSE, xlab = NULL, ylab = NULL, main = "") } \arguments{ \item{bin}{an object of class \code{\link{hexbin}}.} \item{xbnds,ybnds}{global x- and y-axis plotting limits for multiple plots.} \item{density, border}{arguments for \code{\link{polygon}()} each of length two, the first for the median, the second for the other cells.} \item{pen}{colors (\dQuote{pen numbers}) for \code{polygon()}.} \item{unzoom}{plot limit expansion factor when \code{xbnds} is missing.} \item{clip}{either 'on' or 'off' are the allowed arguments, when on everything is clipped to the plotting region.} \item{reshape}{logical value to reshape the plot although \code{xbnds} and \code{ybnds} are present.} \item{xlab, ylab, main}{x- and y- axis labels and main title} } \value{ invisibly, the \code{\link{hexViewport}()} used internally. Used to add to the plot afterwards. } \references{ see in \code{\link{grid.hexagons}}.} \details{ The \code{density}, \code{border}, and \code{pen} arguments correspond to the \code{\link{polygon}} function calls for plotting two types of cells. The cell types, pen numbers and suggested colors are\cr \tabular{lll}{ TYPE \tab PEN \tab COLOR \cr cells of bin \tab 2 \tab light gray \cr last eroded cells of bin (median cells)\tab 1 \tab black \cr } The erode components of the hexbin objects must be present for the medians cells to plot. When \code{xbnds} is missing or \code{reshape} is true, the plot changes graphics parameters and resets them. When \code{xbnds} is missing the function also zooms in based on the available data to provide increased resolution. The zoom used the hexagon cell centers. The unzoom argument backs off a bit so the whole hexagon will fit in the plot. \code{Hboxplot()} is used as a stand alone function, for producing separate legends .....%%FIXME for \code{\link{hmatplot}()} and for panels in %% \code{\link{hmatplot}()}. } \seealso{ \code{\link{hexbin}}, \code{\link{erode}}, %\code{\link{smooth.hexbin}}, \code{\link{hcell2xy}},% \code{\link{hcell}}, \code{\link{gplot.hexbin}}, % \code{\link{hmatplot}}, \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}} } \examples{ \dontshow{set.seed(753)} ## boxplot of smoothed counts x <- rnorm(10000) y <- rnorm(10000) bin <- hexbin(x,y) erodebin <- erode(smooth.hexbin(bin)) hboxplot(erodebin) hboxplot(erodebin, density = c(32,7), border = c(2,4)) hp <- hboxplot(erodebin, density = c(-1,17), main = "hboxplot(erode*(smooth*(.)))") pushHexport(hp) library("grid") grid.points(x[1:10], y[1:10])# just non-sense to show the principle popViewport() } \keyword{hplot} hexbin/man/hexMA.loess.Rd0000644000176200001440000000234213171627113014722 0ustar liggesusers\name{hexMA.loess} \alias{hexVP.loess} \alias{hexMA.loess} \title{Add Loess Fit to Hexplot } \description{ Fit a loess line using the hexagon centers of mass as the x and y coordinates and the cell counts as weights. } \usage{ hexMA.loess(pMA, span = 0.4, col = "red", n = 200) hexVP.loess(hbin, hvp = NULL, span = 0.4, col = "red", n = 200) } \arguments{ \item{hbin}{an object of class \code{hexbin}, see \code{\link{hexbin}}.} \item{hvp}{A \code{hexViewport} object.} \item{pMA}{the list returned by \code{\link{plotMAhex}}.} \item{span}{the parameter alpha which controls the degree of smoothing.} \item{col}{line color for the loess fit.} \item{n}{number of points at which the fit should be evaluated.} } \value{ Returns invisibly the object associated with the loess fit. } \author{Nicholas Lewin-Koh } \seealso{ \code{\link{hexVP.abline}}, \code{\link{plotMAhex}}, \code{\link{gplot.hexbin}}, \code{\link{hexViewport}}; \code{\link{loess}} } \examples{ if(require(marray)){ data(swirl) %% the following had 'newpage = FALSE, ' -- why ?? hb <- plotMAhex(swirl[,1], main = "M vs A plot with hexagons", legend=0) hexVP.abline(hb$plot, h=0, col= gray(.6)) hexMA.loess(hb) } } \keyword{aplot} hexbin/man/list2hexList.Rd0000644000176200001440000000066513171627113015200 0ustar liggesusers\name{list2hexList} \alias{list2hexList} \title{Convert list to hexList} \description{ Converts a list of hexbin objects with same xbnds, ybnds, shape and xbins to a \code{\link{hexList}} object. } \usage{ list2hexList(binlst) } \arguments{ \item{binlst}{A list of hexbin objects} } \value{ a \code{\link{hexList}} object } \author{Nicholas Lewin-Koh} \seealso{\code{\link{hexList}},\code{\link{hdiffplot}} } \keyword{misc} hexbin/man/hexbinplot.Rd0000644000176200001440000002153413171627113014754 0ustar liggesusers\name{hexbinplot} \alias{hexbinplot} \alias{hexbinplot.formula} \alias{panel.hexbinplot} \alias{prepanel.hexbinplot} \alias{hexlegendGrob} \title{Trellis Hexbin Displays} \description{ Display of hexagonally binned data, as implemented in the \code{hexbin} packge, under the Trellis framework, with associated utilities. \code{hexbinplot} is the high level generic function, with the \code{"formula"} method doing the actual work. \code{prepanel.hexbinplot} and \code{panel.hexbinplot} are associated prepanel and panel functions. \code{hexlegendGrob} produces a suitable legend. } \usage{ hexbinplot(x, data, \dots) \method{hexbinplot}{formula}(x, data = NULL, prepanel = prepanel.hexbinplot, panel = panel.hexbinplot, groups = NULL, aspect = "xy", trans = NULL, inv = NULL, colorkey = TRUE, \dots, maxcnt, legend = NULL, legend.width = TRUE, subset) prepanel.hexbinplot(x, y, type = character(0), \dots) panel.hexbinplot(x, y, ..., groups = NULL) hexlegendGrob(legend = 1.2, inner = legend / 5, cex.labels = 1, cex.title = 1.2, style = "colorscale", minarea = 0.05, maxarea = 0.8, mincnt = 1, maxcnt, trans = NULL, inv = NULL, colorcut = seq(0, 1, length = 17), density = NULL, border = NULL, pen = NULL, colramp = function(n) { LinGray(n,beg = 90,end = 15) }, \dots, vp = NULL, draw = FALSE) } \arguments{ \item{x}{ For \code{hexbinplot}, the object on which method dispatch is carried out. For the \code{"formula"} methods, a formula describing the form of conditioning plot. Formulas that are valid for \code{xyplot} are acceptable. In \code{panel.hexbinplot}, the x variable. } \item{y}{ In \code{panel.hexbinplot}, the y variable. } \item{data}{For the \code{formula} method, a data frame containing values for any variables in the formula, as well as \code{groups} and \code{subset} if applicable (using \code{groups} currently causes an error with the default panel function). By default, the environment where the function was called from is used. } \item{minarea, maxarea, mincnt, maxcnt, trans, inv, colorcut, density, border, pen, colramp, style}{ see \code{\link[hexbin:gplot.hexbin]{gplot.hexbin}} } \item{prepanel, panel, aspect}{ See \code{\link[lattice]{xyplot}}. \code{aspect="fill"} is not allowed. The current default of \code{"xy"} may not always be the best choice, often \code{aspect=1} will be more reasonable. } \item{colorkey}{logical, whether a legend should be drawn. Currently a legend can be drawn only on the right. } \item{legend.width, legend}{ width of the legend in inches when \code{style} is \code{"nested.lattice"} or \code{"nested.centroids"}. The name \code{legend.width} is used to avoid conflict with the standard trellis argument \code{legend}. It is possible to specify additional legends using the \code{legend} or \code{key} arguments as long as they do not conflict with the hexbin legend (i.e., are not on the right). } \item{inner}{ Inner radius in inches of hexagons in the legend when \code{style} is \code{"nested.lattice"} or \code{"nested.centroids"}. } \item{cex.labels, cex.title}{ in the legend, multiplier for numeric labels and text annotation respectively } \item{type}{ character vector controlling additional augmentation of the display. A \code{"g"} in \code{type} adds a reference grid, \code{"r"} adds a regression line (y on x), \code{"smooth"} adds a loess smooth } \item{draw}{ logical, whether to draw the legend grob. Useful when \code{hexlegendGrob} is used separately } \item{vp}{ grid viewport to draw the legend in } \item{\dots}{ extra arguments, passed on as appropriate. Arguments to \code{\link[hexbin:gplot.hexbin]{gplot.hexbin}}, \code{\link[lattice]{xyplot}}, \code{panel.hexbinplot} and \code{hexlegendGrob} can be supplied to the high level \code{hexbinplot} call. \code{panel.hexbinplot} calls one of two (unexported) low-level functions depending on whether \code{groups} is supplied (although specifying \code{groups} currently leads to an error). Arguments of the appropriate function can be supplied; some important ones are \describe{ \item{\code{xbins}:}{ number of hexagons covering x values. The number of y-bins depends on this, the aspect ratio, and \code{xbnds} and \code{ybnds}} \item{\code{xbnds, ybnds}:}{ Numeric vector specifying range of values that should be covered by the binning. In a multi-panel display, it is not necessarily a good idea to use the same bounds (which along with \code{xbins} and the aspect ratio determine the size of the hexagons) for all panels. For example, when data is concentrated in small subregions of different panels, more detail will be shown by using smaller hexagons covering those regions. To control this, \code{xbnds} and \code{ybnds} can also be character strings \code{"panel"} or \code{"data"} (which are not very good names and may be changed in future). In the first case, the bounds are taken to be the limits of the panel, in the second case, the limits of the data (packet) in that panel. Note that all panels will have the same limits (enough to cover all the data) by default if \code{relation="free"} in the standard trellis argument \code{scales}, but not otherwise.} } } \item{groups}{ in \code{hexbinplot}, a grouping variable that is evaluated in \code{data}, and passed on to the panel function. } \item{subset}{ an expression that is evaluated in evaluated in \code{data} to produce a logical vector that is used to subset the data before being used in the plot. } } \details{ The panel function \code{panel.hexbinplot} creates a hexbin object from data supplied to it and plots it using \code{\link[hexbin:grid.hexagons]{grid.hexagons}}. To make panels comparable, all panels have the same \code{maxcnt} value, by default the maximum count over all panels. This default value can be calculated only if the aspect ratio is known, and so \code{aspect="fill"} is not allowed. The default choice of aspect ratio is different from the choice in \code{hexbin} (namely, \code{1}), which may sometimes give better results for multi-panel displays. \code{xbnds} and \code{ybnds} can be numeric range vectors as in \code{hexbin}, but they can also be character strings specifying whether all panels should have the same bins. If they are not, then bins in different panels could be of different sizes, in which case \code{style="lattice"} and \code{style="centroids"} should be interpreted carefully. The dimensions of the legend and the size of the hexagons therein are given in absolute units (inches) by \code{legend.width} and \code{inner} only when \code{style} is \code{"nested.lattice"} or \code{"nested.centroids"}. For other styles, the dimensions of the legend are determined relative to the plot. Specifically, the height of the legend is the same as the height of the plot (the panel and strip regions combined), and the width is the minimum required to fit the legend in the display. This is different in some ways from the \code{hexbin} implementation. In particular, the size of the hexagons in the legend are completely unrelated to the sizes in the panels, which is pretty much unavoidable because the sizes need not be the same across panels if \code{xbnds} or \code{ybnds} is \code{"data"}. The size of the hexagons encode information when \code{style} is \code{"lattice"} or \code{"centroids"}, consequently a warning is issued when a legend is drawn with wither of these styles. } \value{ \code{hexbinplot} produces an object of class \code{"trellis"}. The \code{update} method can be used to update components of the object and the \code{print} method (usually called by default) will plot it on an appropriate plotting device. \code{hexlegendGrob} produces a \code{"grob"} (grid object). } \author{ Deepayan Sarkar \email{deepayan.sarkar@r-project.org}} \seealso{ \code{\link{hexbin}}, \code{\link[lattice]{xyplot}} } \examples{ mixdata <- data.frame(x = c(rnorm(5000),rnorm(5000,4,1.5)), y = c(rnorm(5000),rnorm(5000,2,3)), a = gl(2, 5000)) hexbinplot(y ~ x, mixdata, aspect = 1, trans = sqrt, inv = function(x) x^2) hexbinplot(y ~ x | a, mixdata) hexbinplot(y ~ x | a, mixdata, style = "lattice", xbnds = "data", ybnds = "data") hexbinplot(y ~ x | a, mixdata, style = "nested.centroids") hexbinplot(y ~ x | a, mixdata, style = "nested.centroids", border = FALSE, type = c("g", "smooth")) } \keyword{dplot} hexbin/man/hdiffplot.Rd0000644000176200001440000001241313171627113014553 0ustar liggesusers\name{hdiffplot} \alias{hdiffplot} \title{Plot of Domain and Median Differences of Two "hexbin" Objects} \description{ Let \code{bin1} and \code{bin2} represent two \code{\link{hexbin}} objects with scaling, plot shapes, and bin sizes. This plot distinguishes cells unique to \code{bin1}, cells in common, and cells unique to \code{bin2} using color. When the erode components are present, color also distinguishes the two erosion medians. An arrow shows the vector from the median of \code{bin1} to the median of \code{bin2}. } \usage{ hdiffplot(bin1, bin2 = NULL, xbnds, ybnds, focus = NULL,% if(is.null(bin2)) 1:length(bin1) else c(1, 2), col.control = list(medhex = "white", med.bord = "black", focus = NULL, focus.border = NULL, back.col = "grey"), arrows = TRUE, size = unit(0.1, "inches"), lwd = 2, eps = 1e-6, unzoom = 1.08, clip="off", xlab = "", ylab = "", main = deparse(mycall), \dots) } \arguments{ \item{bin1, bin2}{two objects of class \code{\link{hexbin}}.} \item{xbnds,ybnds}{global x- and y-axis plotting limits. Used primarily for multiple comparison plots.} %%%------- FIXME -------- \item{focus}{a vector of integers specifying which hexbin objects should be treated as focal. Excluded hexbins are treated as background.} \item{col.control}{a list for detailed color control.}%% <<< FIXME \item{arrows}{a logical indicating wheter or not to draw arrows between the focal hexbin objects median cells.} %not yet \item{density}{fill arguments to polygon} %not yet \item{pen}{pen numbers for polgyon} \item{border}{border arguments to polygon} \item{size}{arrow type size in inches.} \item{eps}{distance criteria for distinct medians} \item{unzoom}{plot limit expansion factor when xbnds is missing} \item{clip}{either 'on' or 'off' are the allowed arguments, when on everything is clipped to the plotting region.} \item{lwd}{Line width for arrows, ignored when \code{arrows=FALSE} or when bins have no erosion component} \item{xlab}{label for x-axis} \item{ylab}{label for y-axis} \item{main}{main title for the plot; automatically constructed by default.} \item{\dots}{...............} } % \value{ % ((currently unspecified --- proposals are welcome))%% FIXME % } \details{ The hexbin objects for comparison, \code{bin1} and \code{bin2}, must have the same plotting limits and cell size. The plot produces a comparison overlay of the cells in the two objects. If external global scaling is not supplied, the algorithm determines plotting limits to increase resolution. For example, the objects may be the result of the \code{\link{erode.hexbin}()} and include only high count cells containing 50 of the counts. The density, border, and pen arguments correspond to the polygon function calls for plotting six types of cells. The cell types are respectively: \tabular{l}{ unique cells of bin1,\cr joint cells,\cr unique cells of bin2,\cr median cell of bin1,\cr median cell of bin2,\cr median cell if identical.\cr } The \code{erode} components of the hexbin objects must be present for the medians to plot. The algorithm select a single cell for the median if there are algorithmic ties. %% FIXME: no 'pen' argument anymore .. (?) The \code{pen} numbers for types of cells start at Pen 2. Pen 1 is presumed black. The suggested six additional colors are light blue, light gray, light red, blue, red, and black. Carr (1991) shows an example for black and white printing. That plot changes the six colors to light gray, dark gray, white, black, black, and black. It changes the 4th, 5th, and 6th argument of border to TRUE. It also changes 4th, 5th and 6th argument of density to 0. In other words cells in common do not show and medians cells appear as outlines. When \code{xbnds} is missing, the plot changes graphics parameters and resets them. The function also zooms in based on the available data to provide increased resolution. } \references{ see in \code{\link{grid.hexagons}}.}%>> ./hexagons.Rd \seealso{ \code{\link{hexbin}}, \code{\link{smooth.hexbin}}, \code{\link{erode.hexbin}}, % MISSING: hthin, \code{\link{hcell2xy}}, % \code{\link{hcell}}, \code{\link{gplot.hexbin}}, \code{\link{hboxplot}}, % \code{\link{hmatplot}}, \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}. } \examples{ ## Comparison of two bivariate boxplots x1 <- rnorm(10000) y1 <- rnorm(10000) x2 <- rnorm(10000,mean=.5) y2 <- rnorm(10000,mean=.5) xbnds <- range(x1,x2) ybnds <- range(y1,y2) bin1 <- hexbin(x1,y1,xbnds=xbnds,ybnds=ybnds) bin2 <- hexbin(x2,y2,xbnds=xbnds,ybnds=ybnds) erodebin1 <- erode.hexbin(smooth.hexbin(bin1)) erodebin2 <- erode.hexbin(smooth.hexbin(bin2)) hdiffplot(erodebin1,erodebin2) ## Compare *three* of them: -------------------- x3 <- rnorm(10000,mean=-1) y3 <- rnorm(10000,mean=-.5) xbnds <- range(x1,x2,x3) ybnds <- range(y1,y2,y3) bin1 <- hexbin(x1,y1,xbnds=xbnds,ybnds=ybnds) bin2 <- hexbin(x2,y2,xbnds=xbnds,ybnds=ybnds) bin3 <- hexbin(x3,y3,xbnds=xbnds,ybnds=ybnds) erodebin1 <- erode.hexbin(smooth.hexbin(bin1)) erodebin2 <- erode.hexbin(smooth.hexbin(bin2)) erodebin3 <- erode.hexbin(smooth.hexbin(bin3)) bnlst <- list(b1=erodebin1, b2=erodebin2, b3=erodebin3) hdiffplot(bnlst) } \keyword{hplot} hexbin/man/hexplom.Rd0000644000176200001440000000570413171627113014255 0ustar liggesusers\name{hexplom} \title{Hexbin Plot Matrices} \alias{hexplom} \alias{hexplom.formula} \alias{hexplom.data.frame} \alias{hexplom.matrix} \alias{panel.hexplom} \usage{ hexplom(x, data, \dots) \method{hexplom}{formula}(x, data = NULL, \dots) \method{hexplom}{data.frame}(x, data = NULL, \dots, groups = NULL, subset = TRUE) \method{hexplom}{matrix}(x, data = NULL, \dots, groups = NULL, subset = TRUE) panel.hexplom(\dots) } \description{ \code{hexplom} draws Conditional Hexbin Plot Matrices. It is similar to \code{splom}, expect that the default display is different. Specifically, the default display is created using \code{panel.hexplom}, which is an alias for \code{panel.hexbinplot}. } \arguments{ \item{x}{ The object on which method dispatch is carried out. For the \code{"formula"} method, a formula describing the structure of the plot, which should be of the form \code{~ x | g1 * g2 * \dots}, where \code{x} is a data frame or matrix. Each of \code{g1, g2, \dots} must be either factors or shingles. The conditioning variables \code{g1, g2, \dots} may be omitted. For the \code{data.frame} and \code{matrix} methods, a data frame or matrix as appropriate. } \item{data}{ For the \code{formula} method, an optional data frame in which variables in the formula (as well as \code{groups} and \code{subset}, if any) are to be evaluated. By default, the environment where the function was called from is used. } \item{groups, subset, \dots}{ see \code{\link[lattice]{splom}}. The non-standard evaluation of \code{groups} and \code{subset} only applies in the \code{formula} method. Apart from arguments that apply to \code{splom} (many of which are only documented in \code{\link[lattice]{xyplot}}), additional arguments meant for \code{panel.hexplom} (which is an alias for \code{\link{panel.hexbinplot}}) may also be supplied. Such arguments may include ones that control details of the hexbin calculations, documented in \code{\link{gplot.hexbin}}} } \value{ An object of class \code{"trellis"}. The \code{\link[lattice:update.trellis]{update}} method can be used to update components of the object and the \code{\link[lattice:print.trellis]{print}} method (usually called by default) will plot it on an appropriate plotting device. } \seealso{ \code{\link[lattice]{splom}}, \code{\link[lattice]{xyplot}}, \code{\link[hexbin]{hexbinplot}}, \code{\link[lattice]{Lattice}}, \code{\link[lattice]{panel.pairs}} } \author{ Deepayan Sarkar \email{Deepayan.Sarkar@R-project.org}, Nicholas Lewin-Koh \email{nikko@hailmail.net}} \examples{ ## Simple hexplom data(NHANES) hexplom(~NHANES[,7:14], xbins=15) ## With colors and conditioning hexplom(~NHANES[,9:13] | Sex, data = NHANES, xbins = 15, colramp = magent) ## With custom panel function hexplom(NHANES[,9:13], xbins = 20,colramp = BTY, upper.panel = panel.hexboxplot) } \keyword{hplot} hexbin/man/gplot.hexbin.Rd0000644000176200001440000001346213616020657015206 0ustar liggesusers\name{gplot.hexbin} \alias{gplot.hexbin} \alias{plot,hexbin,missing-method} \title{Plotting Hexagon Cells with a Legend} \description{ Plots Hexagons visualizing the counts in an hexbin object. Different styles are availables. Provides a legend indicating the count representations. } \usage{ %% In future: No longer export gplot.hexbin() ! gplot.hexbin(x, style = "colorscale", legend = 1.2, lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 1, maxcnt = max(x@count), trans = NULL, inv = NULL, colorcut = seq(0, 1, length = min(17, maxcnt)), border = NULL, density = NULL, pen = NULL, colramp = function(n) LinGray(n,beg = 90,end = 15), xlab = "", ylab = "", main = "", newpage = TRUE, type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"), clip = "on", verbose = getOption("verbose")) %% FIXME: This is the S4 plot method for 'hexbin' %% currently also exported "standalone" - for testing,debugging.. %% we'd really don't want to repeat the argument list; use \synopsis{.} ? \S4method{plot}{hexbin,missing}(x, style = "colorscale", legend = 1.2, lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 1, maxcnt = max(x@count), trans = NULL, inv = NULL, colorcut = seq(0, 1, length = min(17, maxcnt)), border = NULL, density = NULL, pen = NULL, colramp = function(n) LinGray(n,beg = 90,end = 15), xlab = "", ylab = "", main = "", newpage = TRUE, type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"), clip = "on", verbose = getOption("verbose")) } \arguments{ \item{x}{an object of class \code{\link{hexbin}}.} % \item{y}{(required by the S4 method for \code{\link{plot}} but unused % here; must be missing)} \item{style}{string specifying the style of hexagon plot, see \code{\link{grid.hexagons}} for the possibilities.} \item{legend}{numeric width of the legend in inches of \code{FALSE}. In the latter case, or when \code{0}, no legend is not produced.} \item{lcex}{characters expansion size for the text in the legend} \item{minarea}{fraction of cell area for the lowest count} \item{maxarea}{fraction of the cell area for the largest count} \item{mincnt}{cells with fewer counts are ignored.} \item{maxcnt}{cells with more counts are ignored.} \item{trans}{\code{\link{function}} specifying a transformation for the counts such as \code{sqrt}.} % FIXME: use better description of these in hexagons() -- or use same % ---- help page ?! \item{inv}{the inverse transformation of \code{trans}.} \item{colorcut}{vector of values covering [0, 1] that determine hexagon color class boundaries and hexagon legend size boundaries. Alternatively, an integer (\code{<= maxcnt}) specifying the \emph{number} of equispaced colorcut values in [0,1].} \item{border, density, pen}{color for polygon borders and filling of each hexagon drawn, passed to \code{\link{grid.hexagons}}.} \item{colramp}{function accepting an integer \code{n} as an argument and returning n colors.} \item{xlab, ylab}{x- and y-axis label.} \item{main}{main title.} \item{newpage}{should a new page start?.} \item{type, xaxt, yaxt}{strings to be used (when set to \code{"n"}) for suppressing the plotting of hexagon symbols, or the x- or y-axis, respectively.} \item{clip}{either 'on' or 'off' are the allowed arguments, when on everything is clipped to the plotting region.} \item{verbose}{logical indicating if some diagnostic output should happen.} } \details{ This is the (S4) \code{\link{plot}} method for \code{\link{hexbin}} (and \code{erodebin}) objects (\link{erodebin-class}). To use the standalone function \code{gplot.hexbin()} is \bold{\emph{deprecated}}. For \code{style}, \code{minarea} etc, see the \bold{Details} section of \code{\link{grid.hexagons}}'s help page. The legend functionality is somewhat preliminary. Later versions may include refinements and handle extreme cases (small and large) for cell size and counts. All arguments of \code{gplot.hexbin} can also be used for the S4 \code{\link{plot}} method. } \value{ invisibly, a list with components \item{plot.vp}{the \code{\link{hexViewport}} constructed and used.} \item{legend.vp}{if a legend has been produced, its \code{\link[grid]{viewport}}.} } \references{ see in \code{\link{grid.hexagons}}.} \author{ Dan Carr \email{dcarr@voxel.galaxy.gmu.edu}, ported by Nicholas Lewin-Koh \email{kohnicho@comp.nus.edu.sg} and Martin Maechler. } \seealso{\code{\link{hexbin}}, \code{\link{hexViewport}}, \code{\link{smooth.hexbin}}, \code{\link{erode.hexbin}}, \code{\link{hcell2xy}}, \code{\link{hboxplot}}, \code{\link{hdiffplot}}. %%, \code{\link{hmatplot}}. } \examples{ ## 1) simple binning of spherical normal: x <- rnorm(10000) y <- rnorm(10000) bin <- hexbin(x,y) ## Plot method for hexbin ! ## ---- ------ -------- plot(bin) # nested lattice plot(bin, style= "nested.lattice") # controlling the colorscheme plot(bin, colramp=BTY, colorcut=c(0,.1,.2,.3,.4,.6,1)) ## 2) A mixture distribution x <- c(rnorm(5000),rnorm(5000,4,1.5)) y <- c(rnorm(5000),rnorm(5000,2,3)) bin <- hexbin(x,y) pens <- cbind(c("#ECE2F0","#A6BDDB","#1C9099"), c("#FFF7BC","#FEC44F","#D95F0E")) plot(bin, style = "nested.lattice", pen=pens) # now really crazy plot(bin, style = "nested.lattice", pen=pens,border=2,density=35) # lower resolution binning and overplotting with counts bin <- hexbin(x,y,xbins=25) P <- plot(bin, style="lattice", legend=FALSE, minarea=1, maxarea=1, border="white") ## %% FIXME! library("grid") pushHexport(P$plot.vp) xy <- hcell2xy(bin) # to show points rather than counts : grid.points(x,y,pch=18,gp=gpar(cex=.3,col="green")) grid.text(as.character(bin@count), xy$x,xy$y, gp=gpar(cex=0.3, col="red"),default.units="native") popViewport() # Be creative, have fun! } \keyword{hplot} hexbin/man/hexpolygon.Rd0000644000176200001440000000537013171627113014774 0ustar liggesusers\name{hexpolygon} \alias{hexpolygon} \alias{hexcoords} \title{Hexagon Coordinates and Polygon Drawing} \description{ Simple \sQuote{low-level} function for computing and drawing hexagons. Can be used for \sQuote{grid} (package \pkg{grid}) or \sQuote{traditional} (package \pkg{graphics}) graphics. } \usage{ hexcoords(dx, dy = NULL, n = 1, sep = NULL) hexpolygon(x, y, hexC = hexcoords(dx, dy, n = 1), dx, dy = NULL, fill = 1, border = 0, hUnit = "native", ...) } \arguments{ \item{dx,dy}{horizontal and vertical width of the hexagon(s).} \item{n}{number of hexagon \dQuote{repeats}.} \item{sep}{separator value to be put between coordinates of different hexagons. The default, \code{NULL} doesn't use a separator.} \item{x,y}{numeric vectors of the same length specifying the hexagon \emph{centers} around which to draw.} \item{hexC}{a list as returned from \code{hexcoords()}. Its component \code{no.sep} determines if grid or traditional graphics are used. The default (via default of \code{hexcoords}) is now to use grid graphics.} \item{fill,border}{passed to \code{\link[grid]{grid.polygon}} (for \pkg{grid}).} \item{hUnit}{string or \code{NULL} determining in which units (x,y) values are.} \item{\dots}{further arguments passed to \code{\link{polygon}} (for \pkg{graphics}).} } \value{ \code{hexcoords()} returns a list with components \item{x,y}{numeric vectors of length \eqn{n \times 6}{n * 6} (or \eqn{n \times 7}{n * 7} if \code{sep} is not NULL) specifying the hexagon polygon coordinates (with \code{sep} appended to each 6-tuple).} \item{no.sep}{a logical indicating if \code{sep} was \code{NULL}.} \code{hexpolygon} returns what its last \code{\link[grid]{grid.polygon}(.)} or \code{\link{polygon}(.)} call returns. } \author{Martin Maechler, originally.} \seealso{\code{\link{grid.hexagons}} which builds on these.} \examples{ str(hexcoords(1, sep = NA)) # multiple of (6 + 1) str(hexcoords(1, sep = NULL))# no separator -> multiple of 6 \dontshow{ stopifnot(3 * (6+1) == sapply(hexcoords(2, n = 3, sep = NA)[1:2], length), 6 == sapply(hexcoords(1)[1:2], length)) set.seed(1001) } ## hexpolygon()s: x <- runif(20, -2, 2) y <- x + rnorm(20) ## 1) traditional 'graphics' plot(x,y, asp = 1, "plot() + hexpolygon()") hexpolygon(x,y, dx = 0.1, density = 25, col = 2, lwd = 1.5) ## 2) "grid" : addBit <- function(bnds, f = 0.05) bnds + c(-f, f) * diff(bnds) sc <- addBit(rxy <- range(x,y))# same extents (cheating asp=1) library("grid") grid.newpage() pushViewport(plotViewport(.1+c(4,4,2,1), xscale = sc, yscale = sc)) grid.rect() grid.xaxis() grid.yaxis() grid.points(x,y) hexpolygon(x,y, hexcoords(dx = 0.1, sep=NULL), border = "blue", fill=NA) popViewport() } \keyword{dplot} \keyword{aplot} hexbin/man/old-classes.Rd0000644000176200001440000000127713171627113015013 0ustar liggesusers\name{old-classes} \title{Class "unit" and "viewport" as S4 classes} % \docType{class} \alias{unit-class} \alias{viewport-class} % \description{Package "hexbin" now uses S4 classes throughout and hence needs to \code{\link[methods]{setOldClass}} both \code{"unit"} and \code{"viewport"} (which are S3 classes from the \pkg{grid} package), in order to be able to use those in slots of its own classes. } \section{Objects from the Class}{A virtual Class: No objects may be created from it.} \section{Extends}{ Class \code{"oldClass"}, directly. } \section{Methods}{ No methods defined with class "unit" in the signature. } % \seealso{ % add link to grid ?? % } \keyword{classes} hexbin/man/hexGraphPaper.Rd0000644000176200001440000000465213171627113015340 0ustar liggesusers\name{hexGraphPaper} \alias{hexGraphPaper} \alias{hgridcent} \title{Create a Hexgon Grid} \description{ Creates a hexagon grid that can be added to a plot created with grid graphics. } \usage{ hexGraphPaper(hb, xbnds = NULL, ybnds = NULL, xbins = 30, shape = 1, add = TRUE, fill.edges = 1, fill = 0, border = 1) hgridcent(xbins, xbnds, ybnds, shape, edge.add = 0) } \arguments{ \item{hb}{a object of class \code{"hexbin"}, typically produced by \code{\link{hexbin}(*)}.} \item{xbnds, ybnds}{horizontal and vertical limits of the binning region in x or y units respectively; must be numeric vector of length 2.} \item{xbins}{the number of bins partitioning the range of xbnds.} \item{shape}{the \emph{shape} = yheight/xwidth of the plotting regions.} \item{add}{a logical value indicating whether or not to add the grid to the current plot.} \item{fill.edges}{integer number of hexagons to add around the border} \item{fill}{the fill color for the hexagons} \item{border}{the color of the border of the hexagons} \item{edge.add}{offset (typically \code{fill.edges} above) used in \code{hgridcent}.} } \details{ If a hexbin object is given then the parameters xbins and shape are ignored. Different bounds can still be specified. The \code{fill.edges} parameter should be an integer. \code{fill.edges} takes the current grid and adds a layer of hexagons around the grid for each level of fill. So for example if \code{fill.edges= 2} than the dimensions of the grid would be \code{(i,j)+4}. \code{hgridcent()} is the utility function computing the resulting list (see section \dQuote{Value}). \strong{WARNING! If using a hexVP be sure to set clip to "on", otherwise the hexagon grid will bleed over the plot edges.} } \value{ Invisibly returns a list with th following components \item{x}{The x coordinates of the grid} \item{y}{the y coordinates of the grid} \item{dimen}{a vector of length 2 gining the rows and columns of the grid} \item{dx}{the horizontal diameter of the hexagons} \item{dy}{the vertical diameter of the hexagons} } \author{Nicholas Lewin-Koh} \seealso{\code{\link{hcell2xy}}, \code{\link{hexpolygon}}, \code{\link{grid.hexagons}}} \examples{ x <- rnorm(10000) y <- rnorm(10000,x,x) hbin <- hexbin(x,y) hvp <- plot(hbin,type="n") pushHexport(hvp$plot,clip="on") hexGraphPaper(hbin,border=grey(.8)) grid.hexagons(hbin) } \keyword{aplot} \keyword{dplot} hexbin/man/hsmooth-methods.Rd0000644000176200001440000000146413171627113015722 0ustar liggesusers\name{hsmooth-methods} \docType{methods}% + generic -- still use this doctype ? \alias{hsmooth}% generic \alias{hsmooth-methods} \alias{hsmooth,hexbin-method} \title{Hexagon Bin Smoothing: Generic hsmooth() and Methods} \description{ Methods for the generic function \code{hsmooth} in package \pkg{hexbin}: There is currently only the one for \code{\link{hexbin}} objects. } \usage{ \S4method{hsmooth}{hexbin}(bin, wts) } \arguments{ \item{bin}{a \code{\link{hexbin}} object, or an extension such as \code{\link{erodebin-class}}.} \item{wts}{weights vector, see \code{\link{smooth.hexbin}}} } \section{Methods}{ \describe{ \item{bin = "hexbin"}{is just the \code{\link{smooth.hexbin}} function (for back compatibility); see its documentation, also for examples.} } } \keyword{methods} hexbin/man/grid.hexlegend.Rd0000644000176200001440000000605713171627113015472 0ustar liggesusers\name{grid.hexlegend} \alias{grid.hexlegend} \title{Add a Legend to a Hexbin Plot} \description{ Plots the legend for the \code{plot} method of \code{\link{hexbin}}. Provides a legend indicating the count representations. } \usage{ grid.hexlegend(legend, ysize, lcex, inner, style = , minarea = 0.05, maxarea = 0.8, mincnt = 1, maxcnt, trans = NULL, inv = NULL, colorcut, density = NULL, border = NULL, pen = NULL, colramp = function(n) { LinGray(n,beg = 90,end = 15) }, leg.unit = "native") } \arguments{ \item{legend}{positive number giving width of the legend in inches.} \item{ysize}{height of legend in inches} \item{lcex}{the characters expansion size for the text in the legend, see \code{\link{par}(cex=)}.} \item{inner}{the inner diameter of a hexagon in inches.} \item{style}{the hexagon style; see \code{\link{grid.hexagons}}.} \item{minarea, maxarea}{fraction of the cell area for the lowest and largest count, respectively.} \item{mincnt, maxcnt}{minimum and maximum count accepted in \code{plot}.} \item{trans}{a transformation function for the counts such as \code{\link{sqrt}}.} \item{inv}{the inverse transformation function.} \item{colorcut}{numeric vector of values covering [0, 1] the determine hexagon color classes boundaries and hexagon legend size boundaries.} \item{border}{argument for \code{\link{polygon}()}. Draw the border for each hexagon.} \item{density}{argument for \code{\link{polygon}()} filling. A \code{0} causes the polygon not to be filled.} \item{pen}{color argument used for \code{\link{polygon}(col = .)}. Determines the color with which the polygon will be filled.} \item{colramp}{function accepting an integer \code{n} as an argument and returning n colors.} \item{leg.unit}{unit to use}%FIXME } \details{ The \code{plot} method for \code{\link{hexbin}} objects calls this function to produce a legend by setting the graphics parameters, so \code{hex.legend} itself is not a standalone function. The legend function is \bold{preliminary}. Later version will include refinements and handle extreme cases (small and large) for cell size and counts. See the \bold{Details} section of \code{\link{grid.hexagons}}'s help page. } \value{ This function does not return any value. } \references{ see in \code{\link{grid.hexagons}}.} \author{ Dan Carr ported by Nicholas Lewin-Koh } \seealso{\code{\link{hexbin}}, \code{\link{grid.hexagons}}, % FIXME \code{\link{smooth.hexbin}}, \code{\link{erode.hexbin}}, % \code{\link{hcell}}, \code{\link{hcell2xy}}, \code{\link{gplot.hexbin}},% \code{\link{hboxplot}},% \code{\link{hdiffplot}}, % \code{\link{hmatplot}} } \examples{ ## Not a stand alone function; typically only called from plot.hexbin() %% Hence we should not run it here! %% FIXME: Improve hex.legend() such that it *can* be added to plots !!! \dontrun{ grid.hexlegend(legend = 2, ysize = 1,lcex=8,inner=0.2, maxcnt = 100, colorcut = c(0.5,0.5)) } } \keyword{aplot} hexbin/man/grid.hexagons.Rd0000644000176200001440000002045013171627113015334 0ustar liggesusers\name{grid.hexagons} \alias{grid.hexagons} \title{Add Hexagon Cells to Plot} \description{ Plots cells in an hexbin object. The function distinquishes among counts using 5 different styles. This function is the hexagon plotting engine from the \code{plot} method for \code{\link{hexbin}} objects. } \usage{ grid.hexagons(dat, style = c("colorscale", "centroids", "lattice", "nested.lattice", "nested.centroids", "constant.col"), use.count=TRUE, cell.at=NULL, minarea = 0.05, maxarea = 0.8, check.erosion = TRUE, mincnt = 1, maxcnt = max(dat@count), trans = NULL, colorcut = seq(0, 1, length = 17), density = NULL, border = NULL, pen = NULL, colramp = function(n){ LinGray(n,beg = 90, end = 15) }, def.unit= "native", verbose = getOption("verbose")) } \arguments{ \item{dat}{an object of class \code{hexbin}, see \code{\link{hexbin}}.} \item{style}{character string specifying the type of plotting; must be (a unique abbrevation) of the values given in \sQuote{Usage} above.} \item{use.count}{logical specifying if counts should be used.} \item{cell.at}{numeric vector to be plotted instead of counts, must besame length as the number of cells.} \item{minarea}{numeric, the fraction of cell area for the lowest count.} \item{maxarea}{the fraction of the cell area for the largest count.} \item{check.erosion}{logical indicating only eroded points should be used for \code{"erodebin"} objects; simply passed to \code{\link{hcell2xy}}, see its documentation.} \item{mincnt}{numeric; cells with counts smaller than \code{mincnt} are not shown.} \item{maxcnt}{cells with counts larger than this are not shown.} \item{trans}{a transformation function (or \code{NULL}) for the counts, e.g., \code{\link{sqrt}}.} \item{colorcut}{a vector of values covering [0, 1] which determine hexagon color class boundaries or hexagon size boundaries -- for \code{style = "colorscale"} only.} \item{density}{\code{\link[grid]{grid.polygon}} argument for shading. 0 causes the polygon not to be filled. \emph{This is not implemented (for \code{\link[grid]{grid.polygon}}) yet}.} \item{border}{\code{\link[grid]{grid.polygon}()} argument. Draw the border for each hexagon.} \item{pen}{colors for \code{\link[grid]{grid.polygon}()}. Determines the color with which the polygon will be filled.} \item{colramp}{function of an integer argument \code{n} returning n colors. \code{n} is determined }%% how? FIXME \item{def.unit}{default \code{\link[grid]{unit}} to be used.}% FIXME \item{verbose}{logical indicating if some diagnostic output should happen.} } \section{SIDE EFFECTS}{Adds hexagons to the plot.} \details{ The six plotting styles have the following effect: \describe{ \item{\code{style="lattice"} or \code{"centroids"}:}{ Plots the hexagons in different sizes based on counts. The \code{"lattice"} version centers the hexagons at the cell centers whereas \code{"centroids"} moves the hexagon centers close to the center of mass for the cells. In all cases the hexagons will not plot outside the cell unless \code{maxarea > 1}. Counts are rescaled into the interval [0,1] and colorcuts determine the class boundaries for sizes and counts. The pen argument for this style should be a single color or a vector of colors of \code{length(bin@count)}.} \item{\code{style="colorscale"}:}{ Counts are rescaled into the interval [0,1] and colorcuts determines the class boundaries for the color classes. For this style, the function passed as \code{colramp} is used to define the n colors for the n+1 color cuts. The pen argument is ignored. %% S-plus: In motif color options try polygon: black 16 white See \code{\link{LinGray}} for the default \code{colramp} and alternative \dQuote{color ramp} functions. } \item{\code{style="constant.col"}:}{ This is an even simpler alternative to \code{"colorscale"}, using constant colors (determined \code{pen} optionally). } \item{\code{style="nested.lattice"} and \code{"nested.centroids"}:}{ Counts are partitioned into classes by power of 10. The encoding nests hexagon size within powers of 10 color contours. If the pen argument is used it should be a matrix of colors with 2 columns and either \code{ceiling(log10(max(bin@count)))} or \code{length(bin@count)} rows. The default uses the \R color palatte so that pens numbers 2-11 determine colors for completely filled cell Pen 2 is the color for 1's, Pen 3 is the color for 10's, etc. Pens numbers 12-21 determine the color of the foreground hexagons. The hexagon size shows the relative count for the power of 10. Different color schemes give different effects including 3-D illusions %% S-plus : %% One motif color option for the first 4 powers is black \#BBB \#36F %% \#0E3 \#F206 \#FFF4 \#FFF %% %% A second option is for the first 5 power is black \#FFF \#08F \#192 %% \#F11 \#FF04 \#000 \#999 \#5CF \#AFA \#FAAF \#000 } } \emph{Hexagon size encoding \code{minarea} and \code{maxarea}} determine the area of the smallest and largest hexagons plotted. Both are expressed fractions of the bin cell size. Typical values might be .04 and 1. When both values are 1, all plotted hexagons are bin cell size, if \code{maxarea} is greater than 1 than hexagons will overlap. This is sometimes interesting with the lattice and centroid styles. \emph{Count scaling} \code{relcnt <- (trans(cnt)-trans(mincnt)) / (trans(maxcnt)-trans(mincnt))} \cr \code{area <- minarea + relcnt*maxarea} By default the transformation \code{trans()} is the identity function. The legend routine requires the transformation inverse for some options. \emph{Count windowing \code{mincnt} and \code{maxcnt}} Only routine only plots cells with cnts in [mincnts, maxcnts] } \references{ Carr, D. B. (1991) Looking at Large Data Sets Using Binned Data Plots, pp. 7--39 in \emph{Computing and Graphics in Statistics}; Eds. A. Buja and P. Tukey, Springer-Verlag, New York. } \author{ Dan Carr ; ported and extended by Nicholas Lewin-Koh \email{nikko@hailmail.net}. } \seealso{\code{\link{hexbin}}, \code{\link{smooth.hexbin}}, \code{\link{erode.hexbin}}, \code{\link{hcell2xy}},% \code{\link{hcell}}, \code{\link{gplot.hexbin}}, \code{\link{hboxplot}}, \code{\link{hdiffplot}}, \code{\link{grid.hexlegend}}% \code{\link{hmatplot}} } \examples{ set.seed(506) x <- rnorm(10000) y <- rnorm(10000) # bin the points bin <- hexbin(x,y) # Typical approach uses plot( ) which controls the plot shape : plot(bin, main = "Bivariate rnorm(10000)") ## but we can have more manual control: # A mixture distribution x <- c(rnorm(5000),rnorm(5000,4,1.5)) y <- c(rnorm(5000),rnorm(5000,2,3)) hb2 <- hexbin(x,y) # Show color control and overplotting of hexagons ## 1) setup coordinate system: P <- plot(hb2, type="n", main = "Bivariate mixture (10000)")# asp=1 ## 2) add hexagons (in the proper viewport): pushHexport(P$plot.vp) grid.hexagons(hb2, style= "lattice", border = gray(.1), pen = gray(.6), minarea = .1, maxarea = 1.5) library("grid") popViewport() ## How to treat 'singletons' specially: P <- plot(hb2, type="n", main = "Bivariate mixture (10000)")# asp=1 pushHexport(P$plot.vp) grid.hexagons(hb2, style= "nested.centroids", mincnt = 2)# not the single ones grid.hexagons(hb2, style= "centroids", maxcnt = 1, maxarea=0.04)# single points popViewport() %% FIXME --- this would mix grid- and traditional-graphics %% ----- would need grid-graphics for 'gpclib' -- aaargs... % # And if we had all the information... % if(require(gpclib)){ % h1 <- chull(x[1:5000], y[1:5000]) % h2 <- chull(x[5001:10000], y[5001:10000]) % h2 <- h2+5000 % h1 <- as(cbind(x[1:5000],y [1:5000])[h1, ], "gpc.poly") % h2 <- as(cbind(x,y)[h2, ], "gpc.poly") % plot(hb2, type="n", main = "Bivariate mixture (10000)")# asp=1 % % plot(h1,poly.args = list(col ="#CCEBC5"),add = TRUE) % plot(h2,poly.args = list(col ="#FBB4AE"),add = TRUE) % plot(intersect(h1, h2), poly.args = list(col = 2), add = TRUE) % grid.hexagons(hb2, style= "centroids", border = gray(.1), pen = gray(.6), % minarea = .1, maxarea = 1.5) % } } \keyword{aplot} hexbin/man/hexbin.Rd0000644000176200001440000000776613171627113014070 0ustar liggesusers\name{hexbin} \title{Bivariate Binning into Hexagon Cells} \alias{hexbin} \alias{hexbin-class} \alias{integer or NULL-class} \alias{show,hexbin-method} \alias{summary,hexbin-method} \description{ Creates a \code{"hexbin"} object. Basic components are a cell id and a count of points falling in each occupied cell. Basic methods are \code{\link[methods]{show}()}, \code{plot()} %(\link{plot.hexbin}) and \code{\link{summary}()}, but also \code{\link{erode}}. % .. \code{\link{smooth.hexbin}} } \usage{ hexbin(x, y, xbins = 30, shape = 1, xbnds = range(x), ybnds = range(y), xlab = NULL, ylab = NULL, IDs = FALSE) } \arguments{ \item{x, y}{vectors giving the coordinates of the bivariate data points to be binned. Alternatively a single plotting structure can be specified: see \code{\link[grDevices]{xy.coords}}. \code{\link{NA}}'s are allowed and silently omitted.} \item{xbins}{the number of bins partitioning the range of xbnds.} \item{shape}{the \emph{shape} = yheight/xwidth of the plotting regions.} \item{xbnds, ybnds}{horizontal and vertical limits of the binning region in x or y units respectively; must be numeric vector of length 2.} \item{xlab, ylab}{optional character strings used as labels for \code{x} and \code{y}. If \code{NULL}, sensible defaults are used.} \item{IDs}{logical indicating if the individual cell \dQuote{IDs} should be returned, see also below.} } \value{ an S4 object of class \code{"hexbin"}. It has the following slots: \item{cell}{vector of cell ids that can be mapped into the (x,y) bin centers in data units.} \item{count}{vector of counts in the cells.} \item{xcm}{The x center of mass (average of x values) for the cell.} \item{ycm}{The y center of mass (average of y values) for the cell.} \item{xbins}{ number of hexagons across the x axis. hexagon inner diameter =diff(xbnds)/xbins in x units} \item{shape}{plot shape which is yheight(inches) / xwidth(inches)} \item{xbnds}{x coordinate bounds for binning and plotting} \item{ybnds}{y coordinate bounds for binning and plotting} \item{dimen}{The i and j limits of cnt treated as a matrix cnt[i,j]} \item{n}{number of (non NA) (x,y) points, i.e., \code{sum(* @count)}.} \item{ncells}{number of cells, i.e., \code{length(* @count)}, etc} \item{call}{the function call.} \item{xlab, ylab}{character strings to be used as axis labels.} \item{cID}{of class, \code{"integer or NULL"}, only if \code{IDs} was true, an integer vector of length \code{n} where \code{cID[i]} is the cell number of the i-th original point \code{(x[i], y[i])}. Consequently, the \code{cell} and \code{count} slots are the same as the \code{\link{names}} and entries of \code{table(cID)}, see the example.} } \seealso{ \code{\link{hcell2xy}}%, \code{\link{hcell}}, % FIXME \code{\link{gplot.hexbin}},% \code{\link{hboxplot}}, % \code{\link{hdiffplot}}, \code{\link{hmatplot}}, \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}. } \references{ Carr, D. B. et al. (1987) Scatterplot Matrix Techniques for Large \eqn{N}. \emph{JASA} \bold{83}, 398, 424--436. } \details{ Returns counts for non-empty cells only. The plot shape must be maintained for hexagons to appear with equal sides. Some calculations are in single precision. Note that when plotting a \code{hexbin} object, the \pkg{grid} package is used. You must use its graphics (or those from package \pkg{lattice} if you know how) to add to such plots. } \examples{ set.seed(101) x <- rnorm(10000) y <- rnorm(10000) (bin <- hexbin(x, y)) ## or plot(hexbin(x, y + x*(x+1)/4), main = "(X, X(X+1)/4 + Y) where X,Y ~ rnorm(10000)") ## Using plot method for hexbin objects: plot(bin, style = "nested.lattice") hbi <- hexbin(y ~ x, xbins = 80, IDs= TRUE) str(hbi) tI <- table(hbi@cID) stopifnot(names(tI) == hbi@cell, tI == hbi@count) ## NA's now work too: x[runif(6, 0, length(x))] <- NA y[runif(7, 0, length(y))] <- NA hbN <- hexbin(x,y) summary(hbN) } \keyword{dplot} hexbin/man/hexList.Rd0000644000176200001440000000305213171627113014213 0ustar liggesusers\name{hexList} \alias{hexList} \alias{hexbinList-class} \alias{coerce,list,hexbinList-method} \title{Conditional Bivariate Binning into Hexagon Cells } \description{ Creates a list of \code{\link{hexbin}} objects. Basic components are a cell id and a count of points falling in each occupied cell. Basic methods are \code{\link[methods]{show}()}, \code{plot()} %(\link{plot.hexbin}) and \code{\link{summary}()}, but also \code{\link{erode}}. % .. \code{\link{smooth.hexbin}} } \usage{ hexList(x, y = NULL, given = NULL, xbins = 30, shape = 1, xbnds = NULL, ybnds = NULL, xlab = NULL, ylab = NULL) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{x}{ x coordinate to be binned } \item{y}{ y coordinate to be binned } \item{given}{ ..} \item{xbins}{ number of bins partitioning the range of xbnds} \item{shape}{ the \emph{shape} = yheight/xwidth of the plotting regions } \item{xbnds}{ horizontal limits of binning } \item{ybnds}{ vertical limits of binning } \item{xlab}{ character strings used as labels for \code{x} } \item{ylab}{ character strings used as labels for \code{y}} } \details{ There is also a \code{\link[methods:as]{coerce}} method to produce \code{hexbinList} objects from \code{\link{list}}s. %% i.e., \code{as(list(....), "hexbinList")} should work } \value{ If it is a LIST, use \item{comp1 }{Description of 'comp1'} \item{comp2 }{Description of 'comp2'} ... } \author{Nicholas Lewin-Koh} \seealso{\code{\link{hexbin}}, \code{\link{hdiffplot}} } \keyword{dplot} \keyword{misc} hexbin/man/hexVP-class.Rd0000644000176200001440000000607313171627113014736 0ustar liggesusers\name{hexVP-class} \docType{class} \alias{hexVP-class} \alias{getFig,hexVP-method} \alias{getMargins,hexVP-method} \alias{getPlt,hexVP-method} \alias{getXscale,hexVP-method} \alias{getYscale,hexVP-method} \title{Formal class "hexVP" of a Hexagon Viewport} \description{ Hexagon Viewports are \dQuote{value-added} grid viewports (see \code{\link[grid]{viewport}}) where the extra slots contain scaling and \dQuote{embedding} information. A hexViewport is created my taking the available area in the cuurent viewport on the graphics device and maximizing the amount of area with a fied aspect ratio. The default when the shape parameter is 1, is a 1:1 aspect ratio in terms of the size of the viewport, not the scale of the x and y axis. The plotting area is centered within the existing margins and the maximum size determined. Extra area is then allocated to the margins. This viewport is replicated twice, once with clipping set to "on" and once with clipping "off". This feature can be used for toggling clipping on and off while editing the plot. } \section{Objects from the Class}{ Objects are typically created by calls to \code{\link{hexViewport}()} or by low level calls of the form \code{new("hexVP", ...)}. } \section{Slots}{ \describe{ \item{\code{hexVp.off}:}{Object of class \code{"viewport"} with clipping set to off, see \code{\link[grid]{viewport}}.} \item{\code{hexVp.on}:}{Object of class \code{"viewport"}, with the same dimensions and parameters as hexVp.off, but with clipping set to on, see \code{\link[grid]{viewport}}.} \item{\code{hp.name}:}{The name of the viewport for searching a vptree}. \item{\code{mar}:}{\code{\link[grid]{unit}} vector of four margins (typically in \code{"lines"}).} \item{\code{fig}:}{\code{\link[grid]{unit}} vector of two figure sizes (typically in \code{"npc"}).} \item{\code{plt}:}{\code{\link[grid]{unit}} vector of two figure sizes (typically in \code{"npc"}).} %% MM {FIXME?}: Is n't this simply ``xlim'' - then call it so! %% NL, yes it is, but xscale and yscale is the parameters used by %% grid. \item{\code{shape}:}{The shape parameter from the plotted \code{\link[hexbin]{hexbin}} object.} \item{\code{xscale}:}{numeric of length two specifying x-range.} \item{\code{yscale}:}{numeric of length two specifying y-range.} } } \section{Methods}{ These are methods accessing the slots of corresponding name. \describe{ \item{getFig}{\code{signature(hvp = "hexVP")}: ... } \item{getMargins}{\code{signature(hvp = "hexVP")}: ... } \item{getPlt}{\code{signature(hvp = "hexVP")}: ... } \item{getXscale}{\code{signature(hvp = "hexVP")}: ... } \item{getYscale}{\code{signature(hvp = "hexVP")}: ... } } } \author{ Nicholas Lewin-Koh \email{kohnicho@comp.nus.edu.sg}. } \seealso{ The constructor function \code{\link{hexViewport}}. \code{\link{hexbin}}, and its S4 plotting method, \code{\link{gplot.hexbin}}. } \examples{ library("grid") example(hexViewport, echo=FALSE) ## continued: str(P$plot.vp) } \keyword{classes} hexbin/man/getHMedian.Rd0000644000176200001440000000134513171627113014603 0ustar liggesusers\name{getHMedian} \alias{getHMedian} \alias{getHMedian,erodebin-method} \title{Get coordiantes of the median cell after the erode operation} \description{ A method for a eroded hexbin object to extract the coordinates of the median cell. The median is simply the cell with the highest erosion number or the last cell to be eroded. } \usage{ getHMedian(ebin) } \arguments{ \item{ebin}{result of \code{\link{erode.hexbin}()}.} } \section{Methods}{ \describe{ \item{ebin = "erodebin"}{...} } } \seealso{\code{\link{erode.hexbin}} } \examples{ set.seed(153) x <- rnorm(10000) y <- rnorm(10000) bin <- hexbin(x,y) smbin <- smooth.hexbin(bin) erodebin <- erode.hexbin(smbin, cdfcut=.5) getHMedian(erodebin) } \keyword{methods} hexbin/man/panel.hexgrid.Rd0000644000176200001440000000107313171627113015324 0ustar liggesusers\name{panel.hexgrid} \alias{panel.hexgrid} \title{Hexagonal grid for a lattice plot} \description{ A panel function to add a hexagonal grid to a lattice plot. } \usage{ panel.hexgrid(h, border = grey(0.85)) } \arguments{ \item{h}{an object of class \code{hexbin}.} \item{border}{a color for the hexagon border colors} } \value{ There is no return value from this function. The results are plotted on the current active device. } \author{Nicholas Lewin-Koh \email{nikko@hailmail.net}} \seealso{\code{\link{hexbinplot}}, \code{\link{hexGraphPaper}}} \keyword{hplot} hexbin/man/hcell2xyInt.Rd0000644000176200001440000000254413171627113015005 0ustar liggesusers\name{hcell2xyInt} \alias{hcell2xyInt} %- Also NEED an '\alias' for EACH other topic documented here. \title{Change cell ids to 2d integer coordinate system} \description{ Transforms the cell representation of a a lattice into a 2d integer coordinate system. } \usage{ hcell2xyInt(hbin, xbins=NULL, xbnds=NULL, ybnds=NULL, shape=NULL) } \arguments{ \item{hbin}{a object of class \code{"hexbin"}, typically produced by \code{\link{hexbin}(*)}.} \item{xbins}{the number of bins partitioning the range of xbnds.} \item{xbnds, ybnds}{horizontal and vertical limits of the binning region in x or y units respectively; must be numeric vector of length 2.} \item{shape}{the \emph{shape} = yheight/xwidth of the plotting regions.} } \details{ Takes a grid defined by either the hexbin parameters or dimen in a hexbin object and translates the cell ids for the grid into 2d integer coordinates. } \value{ An integer matrix with two columns, i and j representing the integer xy coordinates of the hexagon grid. \item{i}{Integer coordiante of the rows, increases from bottom to top} \item{j}{Integer coordiante of the columns, increases from left to right} } \author{Nicholas Lewin-Koh } \seealso{\code{\link{hcell2xy}}} \examples{ x<-rnorm(10000) y<-rnorm(10000) hbin<-hexbin(x,y) ijInt<-hcell2xyInt(hbin) } \keyword{dplot} \keyword{misc} hexbin/man/panel.hexloess.Rd0000644000176200001440000000277613171627113015537 0ustar liggesusers\name{panel.hexloess} \alias{panel.hexloess} \title{Loess line for hexbin lattice plot} \description{ A panel function to add a loess line to a hexbin lattice plot. This function contravened CRAN policy and is no longer available. } \usage{ panel.hexloess(bin, w = NULL, span = 2/3, degree = 1, family = c("symmetric", "gaussian"), evaluation = 50, lwd = add.line$lwd, lty = add.line$lty, col, col.line = add.line$col, \dots) } \arguments{ \item{bin}{an object of class \code{hexbin}.} \item{w}{optional counts for object \code{bin}.} \item{span}{smoothness parameter for \code{loess}.} \item{degree}{degree of local polynomial used.} \item{family}{if \code{"gaussian"} fitting is by least-squares, and if \code{"symmetric"} a re-descending M-estimator is used.} \item{evaluation}{number of points at which to evaluate the smooth curve.} \item{lwd}{line weight graphical parameter.} \item{lty}{line type graphical parameter.} \item{col}{same as \code{col.line}.} \item{col.line}{line color graphical parameter.} \item{\dots}{optional arguments to \code{\link[stats]{loess.control}}.} } \value{ There is no return value from this function. The results are plotted on the current active device. } \author{Nicholas Lewin-Koh \email{nikko@hailmail.net}} \seealso{ \code{\link{hexbinplot}}, \code{\link{panel.hexgrid}}, \code{\link{loess.smooth}}, \code{\link{loess.control}}, \code{\link[lattice:panel.functions]{panel.loess}} } \keyword{hplot} hexbin/man/hexTapply.Rd0000644000176200001440000000371013171627113014552 0ustar liggesusers\name{hexTapply} \alias{hexTapply} \title{Apply function to data from each hexagon bin.} \description{ A wrapper for tapply except that it operates with each hexagon bin being the category. The function operates on the data associated on the points from each bin. } \usage{ hexTapply(hbin, dat, FUN = sum, ..., simplify=TRUE) } \arguments{ \item{hbin}{a object of class \code{"hexbin"}, typically produced by \code{\link{hexbin}(*)}.} \item{dat}{A vector of data the same length as \code{hbin@cID}} \item{FUN}{the function to be applied. In the case of functions like \code{+}, \code{\%*\%}, etc., the function name must be quoted. If \code{FUN} is \code{NULL}, tapply returns a vector which can be used to subscript the multi-way array \code{tapply} normally produces.} \item{\dots}{optional arguments to \code{FUN}.} \item{simplify}{If \code{FALSE}, \code{tapply} always returns an array of mode \code{"list"}. If \code{TRUE} (the default), then if \code{FUN} always returns a scalar, \code{tapply} returns an array with the mode of the scalar.} } \details{ This function is a wrapper for tapply, except that the cell id is always the categorical variable. This function is specifically good for adding variables to the cAtt slot of a hexbin object or for plotting a third variable in a hexagon plot. See below for examples. } \value{ Returns a vector of the result of 'FUN' as in \code{\link{tapply}}. See \code{\link{tapply}} for detailed description of output. } \author{Nicholas Lewin-Koh} \seealso{ \code{\link{tapply}},\code{\link{hexbin}} } \examples{ data(NHANES) hbin<-hexbin(log(NHANES$Diet.Iron+1),log(NHANES$BMI),xbins=25,IDs=TRUE) hvp<-plot(hbin) mtrans<-hexTapply(hbin,NHANES$Transferin,median,na.rm=TRUE) pushHexport(hvp$plot.vp) grid.hexagons(hbin,style='lattice',pen=0,border='red',use.count=FALSE, cell.at=mtrans) } \keyword{dplot} \keyword{utilities}% at least one, from doc/KEYWORDS hexbin/man/panel.hexboxplot.Rd0000644000176200001440000000401313171627113016063 0ustar liggesusers\name{panel.hexboxplot} \alias{panel.hexboxplot} \title{Boxplot for hexbin lattice plot} \description{ A panel function to add a boxplot to a hexbin lattice plot. } \usage{ panel.hexboxplot(x, y, xbins = 30, xbnds = c("data", "panel"), ybnds = c("data", "panel"), .prelim = FALSE, .cpl = current.panel.limits(), .xlim = .cpl$xlim, .ylim = .cpl$ylim, .aspect.ratio, type = character(0), cdfcut = 0.25, shadow = 0.05, ..., check.erosion = TRUE) } \arguments{ \item{x, y}{numeric vector or factor.} \item{xbins}{the number of bins partitioning the range of xbnds.} \item{xbnds, ybnds}{horizontal and vertical limits of the binning region in x or y units respectively; must be numeric vector of length 2.} \item{.prelim, .cpl, .xlim, .ylim, .aspect.ratio}{for internal use.} \item{type}{character vector controlling additional augmentation of the display. A \code{"g"} in \code{type} adds a reference grid, an \code{"hg"} adds a hexagonal grid.} \item{cdfcut}{number in (0,1) indicating the confidence level for the erosion limits. See \code{\link{erode.hexbin}} for more information.} \item{shadow}{number in (0,1) indicating the confidence level for the erosion limits of a boxplot shadow. See \code{\link{erode.hexbin}} for more information.} \item{\dots}{potential further arguments passed on.} \item{check.erosion}{logical indicating only eroded points should be used for \code{"erodebin"} objects; simply passed to \code{\link{hcell2xy}}, see its documentation.} } \value{ There is no return value from this function. The results are plotted on the current active device. } \author{Nicholas Lewin-Koh \email{nikko@hailmail.net}} \seealso{\code{\link{hexbinplot}}, \code{\link{panel.hexgrid}}, \code{\link[lattice]{panel.bwplot}} } \examples{ mixdata <- data.frame(x = c(rnorm(5000),rnorm(5000,4,1.5)), y = rep(1:2, 5000)) hexbinplot(y ~ x, mixdata, panel = panel.hexboxplot) } \keyword{hplot} hexbin/man/inout.hex.Rd0000644000176200001440000000132013171627113014510 0ustar liggesusers\name{inout.hex} \alias{inout.hex} \title{Check points for inclusion} \description{ Check which points are in hexagons with \code{count} <= mincnt. } \usage{ inout.hex(hbin, mincnt) } \arguments{ \item{hbin}{an object of class \code{\link{hexbin}}.} \item{mincnt}{Cutoff, id's for counts less than mincnt are returned} } \details{ Check which points are in hexagons with \code{count} <= mincnt and returns the row ids for those points. One can use the ids to plot low ount hexagons as points instead. } \value{ A vector with the row ids of points which fall in hexagons with \code{count} less than or equal to mincnt } \author{Nicholas Lewin-Koh} \seealso{\code{\link{plotMAhex}}} \keyword{misc} hexbin/man/optShape.Rd0000644000176200001440000000317013171627113014357 0ustar liggesusers\name{optShape} \alias{optShape} %- Also NEED an '\alias' for EACH other topic documented here. \title{Optimal Shape Parameter for Hexbin Viewport} \description{ Takes a viewport or a given height and width and returns the shape parameter that will fill the specified plotting region with the appropriately shaped hexagons. If margins are specified the margins are subtracted from height and width before the shape parameter is specified. } \usage{ optShape(vp, height = NULL, width = NULL, mar = NULL) } \arguments{ \item{vp}{a \code{viewport} object, optional see details} \item{height}{the height of the plotting region, can be numeric or units} \item{width}{The width of the plotting region, can be numeric or units} \item{mar}{A four element numeric or units vector describing the margins in the order \code{c(bottom, left, top, right)}} } \value{ a scalar numeric value specifiyng \code{shape}. } \author{Nicholas Lewin-Koh} \section{Warning}{If a viewport is given as an argument it should already be pushed on the graphics device or it will have null units and a meaningless shape parameter will be returned. } \seealso{\code{\link{hexViewport}}, \code{\link{hexVP-class}}, \code{\link{hexbin}}} \examples{ x <- rgamma(10000,.9) m <- as.logical(rbinom(10000,1,.17)) x[m] <- -x[m] y <- rnorm(x,abs(x)) library("grid") vp <- plotViewport(xscale= range(x)+c(-.5,.5), yscale= range(y)+c(-.5,.5), default.units = "native") grid.newpage() pushViewport(vp) grid.rect() shape <- optShape(vp) shape hb <- hexbin(x,y,xbins=40,shape=shape) grid.hexagons(hb,colramp=BTY) } \keyword{dplot} hexbin/man/hcell2xy.Rd0000644000176200001440000000361013171627113014325 0ustar liggesusers\name{hcell2xy} \alias{hcell2xy} \alias{hcell2xy,hexbin-method} \title{Compute X and Y Coordinates for Hexagon Cells} \description{ Computes x and y coordinates from hexagon cell id's. } \usage{ hcell2xy(hbin, check.erosion = TRUE) } \arguments{ \item{hbin}{a object of class \code{"hexbin"}, typically produced by \code{\link{hexbin}(*)}.} \item{check.erosion}{logical indicating if only the eroded points should be returned in the case where \code{hbin} inherits from \code{"erodebin"} (see \code{\link{erodebin-class}}); is \code{TRUE} by default.} } \value{ A list with two components of the same length as \code{bin$cell}, \item{x}{} \item{y}{} } %%FIXME \references{see in \code{\link{hcell}}.} \details{ The hexbin object \code{hbin} contains all the needed information. The purpose of this function is to reduce storage. The cost is additional calculation. } \seealso{%%FIXME \code{\link{hcell}}, \code{\link{hray}}, \code{\link{hexbin}}. } \examples{ x <- rnorm(10000) y <- rnorm(10000) plot(x,y, pch=".") hbin <- hexbin(x,y) str(xys <- hcell2xy(hbin)) points(xys, cex=1.5, col=2) ; title("hcell2xy( hexbin(..) )", col.main=2) %% __________ FIXME ________ \dontshow{ ## Temporal trends with confidence bounds plotted on a map: ## Illustration only pending access to user functions ## mtapply() # like tapply but for matrices ## sens.season.slope() # computes sen's seasonal slope ## This part does not work and commented out #hbin <- hcell(dat$x,dat$y) # x and y are in map projection units #newdat < dat[,c('month','year','value')] # extract columns #stats <- mtapply(newdat,bin$cell,sens.season.slope,season=12) #plot(mymap,type='l') # map boundaries in map projection units #xy <- hcell2xy(hbin) # x and y coordinates for hexagon cell centers #hray(xy$x, xy$y,val=stat[,1],lower= stat[,2],upper=stat[,3]) } } \keyword{manip} hexbin/man/NHANES.Rd0000644000176200001440000000365413171627113013557 0ustar liggesusers\name{NHANES} \alias{NHANES} \docType{data} \title{NHANES Data : National Health and Nutrition Examination Survey} \usage{data(NHANES)} \description{ This is a somewhat large interesting dataset, a data frame of 15 variables (columns) on 9575 persons (rows). } \format{ This data frame contains the following columns: \describe{ \item{Cancer.Incidence}{binary factor with levels \code{No} and \code{Yes}.} \item{Cancer.Death}{binary factor with levels \code{No} and \code{Yes}.} \item{Age}{numeric vector giving age of the person in years.} \item{Smoke}{a factor with levels \code{Current}, \code{Past}, \code{Nonsmoker}, and \code{Unknown}.} \item{Ed}{numeric vector of \eqn{\{0,1\}} codes giving the education level.} \item{Race}{numeric vector of \eqn{\{0,1\}} codes giving the person's race.%% FIXME : 0 = ? 1 = ? } \item{Weight}{numeric vector giving the weight in kilograms} \item{BMI}{numeric vector giving Body Mass Index, i.e., \code{Weight/Height^2} where Height is in meters, and missings (61\% !) are coded as \code{0} originally.}%% rather FIXME? \item{Diet.Iron}{numeric giving Dietary iron.} \item{Albumin}{numeric giving albumin level in g/l.} \item{Serum.Iron}{numeric giving Serum iron in \eqn{\mu}{u}g/l.} \item{TIBC}{numeric giving Total Iron Binding Capacity in \eqn{\mu}{u}g/l.} \item{Transferin}{numeric giving Transferin Saturation which is just \code{100*serum.iron/TIBC}.} \item{Hemoglobin}{numeric giving Hemoglobin level.} \item{Sex}{a factor with levels \code{F} (female) and \code{M} (male).} } } \examples{ data(NHANES) summary(NHANES) ## Missing Data overview : nNA <- sapply(NHANES, function(x)sum(is.na(x))) cbind(nNA[nNA > 0]) # Which are just these 6 : \dontrun{ Diet.Iron 141 Albumin 252 Serum.Iron 1008 TIBC 853 Transferin 1019 Hemoglobin 759 }%dont } \keyword{datasets} hexbin/TODO0000644000176200001440000000176013171627113012225 0ustar liggesusers-------------- Aug 10, 2014 o get rid of functions in lattice.R, which were copied from lattice -------------- o The new 3D plots -- should rather make the new functions "internal" and choosable with *arguments* from given functions ! o hexbin *class* {as mentioned by man/hexbin.Rd } -- done o find the references (on paper) and read ! --> "References" in ./Biocore-notes ftp://www.galaxy.gmu.edu/pub/faculty/dcarr/eda/bin2d/ ftp://www.galaxy.gmu.edu/pub/faculty/dcarr/software/bin2d.rev/ o example(hmatplot) is still doing many pages instead of one ------------ March 5, 2005 o Implement conversions between different hexagon coordinate systems o Smoothing on a hexagonal basis using tensor products + smoothing histograms + smoothing the intensity of a Poisson process o Family of hex apply functions o Hbin list class and constructors --- o Use standard convertColor() function more and and try to get rid of dependency on 'colorspace' hexbin/DESCRIPTION0000644000176200001440000000175413616044062013246 0ustar liggesusersPackage: hexbin Version: 1.28.1 Title: Hexagonal Binning Routines Author: Dan Carr , ported by Nicholas Lewin-Koh and Martin Maechler , contains copies of lattice functions written by Deepayan Sarkar Maintainer: Edzer Pebesma Depends: R (>= 2.0.1), methods Imports: lattice, grid, graphics, grDevices, stats, utils Suggests: marray, affy, Biobase, limma, knitr Description: Binning and plotting functions for hexagonal bins. Collate: lattice.R BTC.R BTY.R grid.hexagons.R grid.hexlegend.R hbox.R hdiffplot.R hexbinList.R hexbinplot.R hexbin.s4.R hexpanel.R hexplom.R hexPlotMA.R hexutil.R hexViewport.R HO.R LINGRAY.R LOCS.R MAG.R RB.R smoothHexbin.R License: GPL-2 VignetteBuilder: knitr NeedsCompilation: yes URL: http://github.com/edzer/hexbin Packaged: 2020-02-03 13:36:39 UTC; edzer Repository: CRAN Date/Publication: 2020-02-03 16:20:02 UTC hexbin/build/0000755000176200001440000000000013616020747012634 5ustar liggesusershexbin/build/vignette.rds0000644000176200001440000000041413616020747015172 0ustar liggesusersj0F)}>Ab &Ld zv4s|r4cFI˯e5dŌ'19myJKBsB3b=6oP**̗ {dw/C]B KL$;J- aGW⾄ 6k =nQgu\p<]bVAg|@%%~t $p*5ϘĻ }Ob:2p@6=r6ꭂ&lZךuSQ70hexbin/tests/0000755000176200001440000000000013466540747012711 5ustar liggesusershexbin/tests/viewp-ex.R0000644000176200001440000000107213171627113014562 0ustar liggesuserslibrary(hexbin) ## a variation on Nicholas' post to bioconductor & example(hexViewport) set.seed(545) x <- rnorm(2^15) y <- 3*x - .2*x^2 + rnorm(2^15) hbin <- hexbin(x,y) ## hp <- hexViewport(hbin, newpage = TRUE) pushHexport(hp) library("grid") grid.rect() grid.xaxis() grid.yaxis() grid.hexagons(hbin, style = "centroid") hloess <- loess(y ~ x, data = hcell2xy(hbin), weights = hbin @ count) xx <- seq(hbin@xbnds[1], hbin@xbnds[2], length = 500) grid.lines(xx, predict(hloess, xx), gp = gpar(col = 'red', lwd = 2), default.units = "native") popViewport() hexbin/tests/hray.R0000644000176200001440000000110113171627113013752 0ustar liggesuserslibrary(hexbin) set.seed(572) x <- rnorm(100) y <- rnorm(100) val <- rnorm(100) inc <- abs(rnorm(100,sd = .3)) loB <- val-inc hiB <- val+inc if(exists("hray", mode="function")) { # 'real soon now' ## no confidence bounds plot(x,y,type = 'n') hray(x,y,val) ## confidence bounds plot(x,y,type = 'n') hray(x,y,val, lo = loB, hi = hiB) ## clockwise orientation plot(x,y,type = 'n') hray(x,y,val, loB, hiB, clockwise = TRUE) ## no tics and small filled dots plot(x,y,type = 'n') hray(x,y,val, loB, hiB, ticlength = FALSE, dotside = 20, dotlength = .025, dotden = -1) } hexbin/tests/viewp-ex.Rout.save0000644000176200001440000000243313171627113016251 0ustar liggesusers R version 3.1.1 (2014-07-10) -- "Sock it to Me" Copyright (C) 2014 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(hexbin) > > ## a variation on Nicholas' post to bioconductor & example(hexViewport) > set.seed(545) > x <- rnorm(2^15) > y <- 3*x - .2*x^2 + rnorm(2^15) > hbin <- hexbin(x,y) > > ## > hp <- hexViewport(hbin, newpage = TRUE) > pushHexport(hp) > library("grid") > grid.rect() > grid.xaxis() > grid.yaxis() > grid.hexagons(hbin, style = "centroid") > hloess <- loess(y ~ x, data = hcell2xy(hbin), weights = hbin @ count) > xx <- seq(hbin@xbnds[1], hbin@xbnds[2], length = 500) > grid.lines(xx, predict(hloess, xx), + gp = gpar(col = 'red', lwd = 2), default.units = "native") > popViewport() > > proc.time() user system elapsed 0.368 0.020 0.379 hexbin/tests/hdiffplot.R0000644000176200001440000000160413171627113014776 0ustar liggesuserslibrary(hexbin) if(R.version$major != "1" || as.numeric(R.version$minor) >= 7) RNGversion("1.6") set.seed(213) x1 <- rnorm(10000) y1 <- rnorm(10000) x2 <- rnorm(10000,mean = .3) y2 <- rnorm(10000,mean = .3) rx <- range(x1,x2) ry <- range(y1,y2) str(bin1 <- hexbin(x1,y1, xbnds = rx, ybnds = ry)) str(bin2 <- hexbin(x2,y2, xbnds = rx, ybnds = ry)) str(erode(bin1)) str(smbin1 <- smooth.hexbin(bin1)) (smbin2 <- smooth.hexbin(bin2)) str(erodebin1 <- erode.hexbin(smbin1)) (erodebin2 <- erode.hexbin(smbin2)) if(FALSE)## does not work -- what funny stuff is hdiffplot() doing??? par(mfrow = c(2,1)) if(exists("hdiffplot", mode="function")) { ## not yet in new hexbin hdiffplot(bin1,bin2, main = "Original N(0,*) Random bins") hdiffplot(smbin1,smbin2, main = "smooth.hexbin() smoothed bins") plot.new() hdiffplot(erodebin1,erodebin2, main = "erode.hexbin()d smoothed bins") }# not yet hexbin/tests/hray.Rout.save0000644000176200001440000000246613171627113015456 0ustar liggesusers R version 3.1.1 (2014-07-10) -- "Sock it to Me" Copyright (C) 2014 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(hexbin) > > set.seed(572) > > x <- rnorm(100) > y <- rnorm(100) > val <- rnorm(100) > inc <- abs(rnorm(100,sd = .3)) > loB <- val-inc > hiB <- val+inc > > if(exists("hray", mode="function")) { # 'real soon now' + + ## no confidence bounds + plot(x,y,type = 'n') + hray(x,y,val) + + ## confidence bounds + plot(x,y,type = 'n') + hray(x,y,val, lo = loB, hi = hiB) + + ## clockwise orientation + plot(x,y,type = 'n') + hray(x,y,val, loB, hiB, clockwise = TRUE) + + ## no tics and small filled dots + plot(x,y,type = 'n') + hray(x,y,val, loB, hiB, ticlength = FALSE, + dotside = 20, dotlength = .025, dotden = -1) + + } > > proc.time() user system elapsed 0.252 0.012 0.258 hexbin/tests/hdiffplot.Rout.save0000644000176200001440000001313213466540766016501 0ustar liggesusers R version 3.6.0 (2019-04-26) -- "Planting of a Tree" Copyright (C) 2019 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(hexbin) > > if(R.version$major != "1" || as.numeric(R.version$minor) >= 7) + RNGversion("1.6") Warning messages: 1: In RNGkind("Marsaglia-Multicarry", "Buggy Kinderman-Ramage", "Rounding") : buggy version of Kinderman-Ramage generator used 2: In RNGkind("Marsaglia-Multicarry", "Buggy Kinderman-Ramage", "Rounding") : non-uniform 'Rounding' sampler used > set.seed(213) > x1 <- rnorm(10000) > y1 <- rnorm(10000) > > x2 <- rnorm(10000,mean = .3) > y2 <- rnorm(10000,mean = .3) > > rx <- range(x1,x2) > ry <- range(y1,y2) > > str(bin1 <- hexbin(x1,y1, xbnds = rx, ybnds = ry)) Formal class 'hexbin' [package "hexbin"] with 16 slots ..@ cell : int [1:535] 16 20 48 70 74 75 76 80 99 101 ... ..@ count : int [1:535] 1 1 1 1 1 1 1 1 1 1 ... ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ... ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ... ..@ xbins : num 30 ..@ shape : num 1 ..@ xbnds : num [1:2] -3.8 4.3 ..@ ybnds : num [1:2] -3.71 4.17 ..@ dimen : num [1:2] 36 31 ..@ n : int 10000 ..@ ncells: int 535 ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry) ..@ xlab : chr "x1" ..@ ylab : chr "y1" ..@ cID : NULL ..@ cAtt : int(0) > str(bin2 <- hexbin(x2,y2, xbnds = rx, ybnds = ry)) Formal class 'hexbin' [package "hexbin"] with 16 slots ..@ cell : int [1:545] 41 51 75 76 104 107 110 114 136 138 ... ..@ count : int [1:545] 1 1 1 1 1 2 1 1 2 1 ... ..@ xcm : num [1:545] -1.141 1.445 -0.493 -0.324 -0.995 ... ..@ ycm : num [1:545] -3.42 -3.45 -3.24 -3.35 -2.9 ... ..@ xbins : num 30 ..@ shape : num 1 ..@ xbnds : num [1:2] -3.8 4.3 ..@ ybnds : num [1:2] -3.71 4.17 ..@ dimen : num [1:2] 36 31 ..@ n : int 10000 ..@ ncells: int 545 ..@ call : language hexbin(x = x2, y = y2, xbnds = rx, ybnds = ry) ..@ xlab : chr "x2" ..@ ylab : chr "y2" ..@ cID : NULL ..@ cAtt : int(0) > > str(erode(bin1)) Formal class 'erodebin' [package "hexbin"] with 19 slots ..@ eroded: logi [1:535] FALSE FALSE FALSE FALSE FALSE FALSE ... ..@ cdfcut: num 0.5 ..@ erode : int [1:71] 12 35 34 57 52 4 30 101 138 150 ... ..@ cell : int [1:535] 16 20 48 70 74 75 76 80 99 101 ... ..@ count : int [1:535] 1 1 1 1 1 1 1 1 1 1 ... ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ... ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ... ..@ xbins : num 30 ..@ shape : num 1 ..@ xbnds : num [1:2] -3.8 4.3 ..@ ybnds : num [1:2] -3.71 4.17 ..@ dimen : num [1:2] 36 31 ..@ n : int 10000 ..@ ncells: int 535 ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry) ..@ xlab : chr "x1" ..@ ylab : chr "y1" ..@ cID : NULL ..@ cAtt : int(0) > > str(smbin1 <- smooth.hexbin(bin1)) Formal class 'smoothbin' [package "hexbin"] with 17 slots ..@ wts : num [1:3] 48 4 1 ..@ cell : int [1:906] 17 18 19 21 22 23 51 52 53 54 ... ..@ count : int [1:906] 1 1 1 1 1 1 1 4 5 2 ... ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ... ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ... ..@ xbins : num 34 ..@ shape : num 1 ..@ xbnds : num [1:2] -4.34 4.84 ..@ ybnds : num [1:2] -4.23 4.7 ..@ dimen : num [1:2] 40 35 ..@ n : int 10000 ..@ ncells: int 535 ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry) ..@ xlab : chr "x1" ..@ ylab : chr "y1" ..@ cID : NULL ..@ cAtt : int(0) > (smbin2 <- smooth.hexbin(bin2)) 'hexbin' object from call: hexbin(x = x2, y = y2, xbnds = rx, ybnds = ry) n = 10000 points in nc = 545 hexagon cells in grid dimensions 40 by 35 > > str(erodebin1 <- erode.hexbin(smbin1)) Formal class 'erodebin' [package "hexbin"] with 19 slots ..@ eroded: logi [1:906] FALSE FALSE FALSE FALSE FALSE FALSE ... ..@ cdfcut: num 0.5 ..@ erode : int [1:73] 11 35 95 100 117 88 6 39 167 232 ... ..@ cell : int [1:906] 17 18 19 21 22 23 51 52 53 54 ... ..@ count : int [1:906] 1 1 1 1 1 1 1 4 5 2 ... ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ... ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ... ..@ xbins : num 34 ..@ shape : num 1 ..@ xbnds : num [1:2] -4.34 4.84 ..@ ybnds : num [1:2] -4.23 4.7 ..@ dimen : num [1:2] 40 35 ..@ n : int 10000 ..@ ncells: int 535 ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry) ..@ xlab : chr "x1" ..@ ylab : chr "y1" ..@ cID : NULL ..@ cAtt : int(0) > (erodebin2 <- erode.hexbin(smbin2)) 'hexbin' object from call: hexbin(x = x2, y = y2, xbnds = rx, ybnds = ry) n = 10000 points in nc = 545 hexagon cells in grid dimensions 40 by 35 > > if(FALSE)## does not work -- what funny stuff is hdiffplot() doing??? + par(mfrow = c(2,1)) > > if(exists("hdiffplot", mode="function")) { ## not yet in new hexbin + hdiffplot(bin1,bin2, main = "Original N(0,*) Random bins") + + hdiffplot(smbin1,smbin2, main = "smooth.hexbin() smoothed bins") + + plot.new() + hdiffplot(erodebin1,erodebin2, main = "erode.hexbin()d smoothed bins") + }# not yet > > proc.time() user system elapsed 0.340 0.015 0.347 hexbin/tests/large.R0000644000176200001440000000136213171627113014112 0ustar liggesuserslibrary(hexbin) if(FALSE) { ## the following is still quite a bit from working/useful : ## what should that do? set a palette? rgb <- matrix(c( 15,15,15, 0, 0, 0, 1, 9,15, 9,15, 9, 15, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 2, 7, 0, 7, 1, 8, 1, 1, 15, 2, 2, 11, 1, 1, 8, 1, 1, 5, 1, 1, 5, 1, 1, 15,15,15), ncol = 3, byrow = TRUE) ##ps.options(rasters=600,color=rgb/15,background=2) ##ps.options(color=rgb/15,background=2) postscript("large.ps",width = 10,height = 7.5) plot.hexbin(ans.25mil, style = "nest", lcex = .9) }## FALSE, i.e. nothing done hexbin/tests/large.Rout.save0000644000176200001440000000276713171627113015611 0ustar liggesusers R version 3.1.1 (2014-07-10) -- "Sock it to Me" Copyright (C) 2014 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(hexbin) > > if(FALSE) { ## the following is still quite a bit from working/useful : + + ## what should that do? set a palette? + rgb <- matrix(c( + 15,15,15, + + 0, 0, 0, + 1, 9,15, + 9,15, 9, + 15, 9, 9, + + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + + 9, 9, 9, + 0, 2, 7, + 0, 7, 1, + 8, 1, 1, + + 15, 2, 2, + 11, 1, 1, + 8, 1, 1, + 5, 1, 1, + 5, 1, 1, + 15,15,15), ncol = 3, byrow = TRUE) + + ##ps.options(rasters=600,color=rgb/15,background=2) + ##ps.options(color=rgb/15,background=2) + postscript("large.ps",width = 10,height = 7.5) + + plot.hexbin(ans.25mil, style = "nest", lcex = .9) + + }## FALSE, i.e. nothing done > > proc.time() user system elapsed 0.240 0.032 0.265 hexbin/src/0000755000176200001440000000000013616020747012324 5ustar liggesusershexbin/src/reg.c0000644000176200001440000000134313227156347013252 0ustar liggesusers#include #include extern void F77_NAME(hbin )(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); extern void F77_NAME(herode)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); extern void F77_NAME(hsm )(void *, void *, void *, void *, void *, void *, void *); static const R_FortranMethodDef FortranEntries[] = { {"hbin", (DL_FUNC) &F77_NAME(hbin), 13}, {"herode", (DL_FUNC) &F77_NAME(herode), 10}, {"hsm", (DL_FUNC) &F77_NAME(hsm), 7}, {NULL, NULL, 0} }; void R_init_myLib(DllInfo *info) { R_registerRoutines(info, NULL, NULL, FortranEntries, NULL); R_useDynamicSymbols(info, FALSE); R_forceSymbols(info, TRUE); } hexbin/src/herode.f0000644000176200001440000001304113171627113013734 0ustar liggesusersC File: herode.f C Version date: Jan 4, 1994 C Programmer: Daniel B. Carr C C The vector erode returns the gray-level erosion order for hexagon cells. C The erosion cycle is: C cycle = (erode-1)/6 + 1 C Many cells may be eroded in the same cycle C A tie break is the cell count deficit at erosion time: C deficit=erode - 6*cycle C The last eroded cell might be considered a bivariate median C C The algorithm: C Repeat until no cells are left in the list. C Process list C Reduce the cell counts by the a multiple of exposed sides C If a cell count is zero or less after an erosion cycle C let order=order + 6 C report erode = order + cell count (count is <= 0) C remove the cell from consideration C update exposed side counts for existing neighbor cells C if exposed sides was zero, temporarily store id's C else C compress list C endif C Add temporarily stored id's to list C End Repeat subroutine herode(cell,cnt,n,bdim, * erode,ncnt,ncell,sides,neib,exist) C C implicit none integer cell(*), cnt(*) ! cell id and count integer n, bdim(2) ! number of cells and 2-D array bounds integer erode(*) ! erosion status integer ncell(*),ncnt(*) ! extracted id's and expanded counts integer sides(*) ! number of exposed sides integer neib(6,*) ! pointers to the neighbors logical exist(0:*) ! cell existence integer nrow, ncol, Lmax ! dimensions integer inc1(6), inc2(6) ! increments to get neighbors integer i, icell, j, k, L ! subscripts integer nc, nnc, nb, ninc, r, c !more subscripts integer loop, order, maxcnt C_______Zero cell ordering numbers________________________________ order=0 C_______Load the increment arrays and constants nrow = bdim(1) ncol = bdim(2) Lmax = nrow * ncol nnc = n C______Load increment arrays to neigbors______________ C C order=right, up left, down left, up right, left, down right inc1(1)= 1 inc1(2)= ncol-1 inc1(3)= -ncol-1 inc1(4)= ncol inc1(5)=-1 inc1(6)= -ncol inc2(1)= 1 inc2(2)= ncol inc2(3)= -ncol inc2(4)= ncol+1 inc2(5)=-1 inc2(6)= -ncol+1 c_______load working arrays_______________________________________________ do i=0,Lmax exist(i)=.false. enddo maxcnt=0 do i=1,n icell=cell(i) ncnt(icell)=cnt(i) exist(icell)=.true. maxcnt=max(maxcnt,cnt(i)) enddo C_______Store pointers to cell neighbors_________________________ C C A pointer of 0 means the neigbor in out of bounds C Also find the max count C Speed: Can avoid adding 1's to r and c C but this code is easier to follow do i=1,n L=cell(i) k = L -1 r=k/ncol+1 c=mod(k,ncol)+1 if(mod(r,2).eq.1)then do j = 1,6 neib(j,L) = L + inc1(j) enddo if (c .eq. 1) then neib(2,L) = 0 neib(3,L) = 0 neib(5,L) = 0 else if (c .eq. ncol) then neib(1,L) = 0 endif if (r .eq. 1) then neib(3,L) = 0 neib(6,L) = 0 else if(r.eq.nrow)then neib(2,L) = 0 neib(4,L) =0 endif else do j= 1,6 neib(j,L) = L + inc2(j) enddo if (c .eq. 1) then neib(5,L) = 0 else if (c .eq. ncol) then neib(1,L) = 0 neib(4,L) = 0 neib(6,L) = 0 endif if (r .eq. nrow) then neib(2,L) = 0 neib(4,L) = 0 endif endif enddo C_______Count exposed sides for cells in the contour_________________ do i=1,n icell=cell(i) sides(icell)=0 do j=1,6 if(.not. exist( neib(j,icell) ) )then sides(icell)=sides(icell)+ 1 endif enddo enddo C________Grab surface cells___________________________________________ nc=0 do i=1,n if(sides(cell(i)).gt.0)then nc=nc+1 ncell(nc)=cell(i) endif enddo n=nc !n is now the number of exposed, non-empty cells C_______The outer loop________________________________________________ C C temporary indices C nc: index for cells remaining on the list C ninc: index for newly exposed cells added to back of list do while(n.gt.0) C Subtract exposed-side counts from the surface cell counts C until at least one cell is empty. loop=maxcnt do i=1,n icell=ncell(i) loop=min( (ncnt(icell)-1)/sides(icell) , loop) enddo loop=loop+1 !all loop values are 1 too small C update the counts, rank and remove eroded cells nc=0 order=order+6 ninc=n do i=1,n icell=ncell(i) ncnt(icell)=ncnt(icell)-sides(icell)*loop if(ncnt(icell).le.0)then C Remove the empty cell and store it's order exist(icell)=.false. erode(icell)=order+ncnt(icell) C Update the neighbors of the empty cell do j=1,6 nb=neib(j,icell) if(exist(nb))then C Store cells for addition to surface list if(sides(nb).eq.0)then ninc=ninc+1 ncell(ninc)=nb endif C Update sides for the neighbors sides(nb)=sides(nb)+1 endif enddo else C Save remaining cells nc=nc+1 ncell(nc)=ncell(i) endif enddo C Add new surface cells if any do i=n+1,ninc,1 nc=nc+1 ncell(nc)=ncell(i) enddo n=nc enddo C_______compress result___________________________________________ do i=1,nnc erode(i)=erode(cell(i)) enddo n=nnc return end hexbin/src/hsm.f0000644000176200001440000000360613171627113013263 0ustar liggesusersC File: hsm.f C Programmer: Daniel B. Carr C Version Date: January 3, 1994 C C This program is an hexagon cell smoother. It smooths into C neighboring cells and hence expands. C The kernal is a crude integer kernel. C The boundary hexagons get weight 1, the center hexagon C gets weight, wt, which by default is set to six. C C subroutine hsm(cell,cnt,n,nmax,sm,ncol,wt) implicit none integer n, nmax, ncol integer cell(*), cnt(*), sm(*), wt(*) integer ind, ind1(6), ind2(12),ind3(6), ind4(12), loc integer row, cnt1, cnt2, wta, wtb, wtc integer i, j C__________Constants___________________________________________ ind1(1)=-1 ind1(2)=ncol-1 ind1(3)=ncol ind1(4)=+1 ind1(5)=-ncol ind1(6)=-ncol-1 ind2(1)=-2 ind2(2)=ncol-2 ind2(3)=2*ncol-1 ind2(4)=2*ncol ind2(5)=2*ncol+1 ind2(6)=ncol+1 ind2(7)=2 ind2(8)=-ncol+1 ind2(9)=-2*ncol+1 ind2(10)=-2*ncol ind2(11)=-2*ncol-1 ind2(12)=-ncol-2 ind3(1)=-1 ind3(2)=ncol ind3(3)=ncol+1 ind3(4)=+1 ind3(5)=-ncol+1 ind3(6)=-ncol ind4(1)=-2 ind4(2)=ncol-1 ind4(3)=2*ncol-1 ind4(4)=2*ncol ind4(5)=2*ncol+1 ind4(6)=ncol+2 ind4(7)=2 ind4(8)=-ncol+2 ind4(9)=-2*ncol+1 ind4(10)=-2*ncol ind4(11)=-2*ncol-1 ind4(12)=-ncol-1 wta = wt(1) wtb = wt(2) wtc = wt(3) C_________Smoothing_____________________________________ do i=1,n sm(cell(i))=wta*cnt(i) enddo do i=1,n loc=cell(i) row=(loc-1)/ncol + 1 cnt1=wtb*cnt(i) cnt2=wtc*cnt(i) if(mod(row,2).eq.1)then do j=1,6 ind=loc+ind1(j) sm(ind)=sm(ind)+cnt1 enddo do j=1,12 ind=loc+ind2(j) sm(ind)=sm(ind)+cnt2 enddo else do j=1,6 ind=loc+ind3(j) sm(ind)=sm(ind)+cnt1 enddo do j=1,12 ind=loc+ind4(j) sm(ind)=sm(ind)+cnt2 enddo endif enddo n=0 do i=1,nmax if(sm(i).gt.0)then n=n+1 cell(n)=i cnt(n)=sm(i) endif enddo return end hexbin/src/hcell.f0000644000176200001440000000251513171627113013561 0ustar liggesusers subroutine hcell(x,y,cell,n,size,shape,rx,ry,bnd) C Copyright 1991 C Version Date: September 16, 1994 C Programmer: Dan Carr C Indexing: Left to right, bottom to top C bnd(1) rows, bnd(2) columns C Output: cell ids for none empty cells, revised bnd(1) c implicit none integer n, cell(1), bnd(2) double precision x(1), y(1), rx(2), ry(2), size, shape integer i, i1, i2, iinc integer j1, j2, jinc integer L, lat, celmax double precision c1, c2, con1, con2, dist1 double precision sx, sy, xmin, ymin, xr, yr C_______Constants for scaling the data_____________________________ xmin = rx(1) ymin = ry(1) xr = rx(2)-xmin yr = ry(2)-ymin c1 = size/xr c2 = size*shape/(yr*sqrt(3.)) jinc= bnd(2) lat=jinc+1 iinc= 2*jinc con1=.25 con2=1./3. celmax=0 C_______Binning loop________________________________________ do i=1,n sx = c1 * (x(i) - xmin) sy = c2 * (y(i) - ymin) j1 = sx+.5 i1 = sy+.5 dist1=(sx-j1)**2 + 3.*(sy-i1)**2 if(dist1.lt.con1)then L=i1*iinc+j1+1 elseif(dist1.gt.con2)then L=int(sy)*iinc + int(sx)+lat else j2 = sx i2 = sy if( dist1.le.(sx-j2-.5)**2 + 3. * (sy - i2 -.5)**2) then L=i1*iinc+j1+1 else L=i2*iinc+j2+lat endif endif cell(i)=L celmax = max(celmax,L) enddo bnd(1)=(celmax-1)/bnd(2)+1 return end hexbin/src/hbin.f0000644000176200001440000000365313171627113013416 0ustar liggesusers subroutine hbin(x,y,cell,cnt,xcm,ycm, size, shape, * rx,ry, bnd, n, cellid) C Copyright 1991 C Version Date: September 16, 1994 C Programmer: Dan Carr C Indexing: Left to right, bottom to top C bnd(1) rows, bnd(2) columns C Output: cell ids for non empty cells, revised bnd(1) c optionally also return cellid(1:n) c Copyright (2004) Nicholas Lewin-Koh and Martin Maechler implicit none integer n, nc, cell(*), cnt(*), bnd(2), cellid(*) c cellid(*): length 1 or n double precision x(n), y(n), xcm(*),ycm(*), rx(2),ry(2), size double precision shape integer i, i1, i2, iinc integer j1, j2, jinc integer L, lmax, lat double precision c1, c2, con1, con2, dist1 double precision sx, sy, xmin, ymin, xr, yr logical keepID keepID = (cellid(1) .eq. 0) C_______Constants for scaling the data_____________________________ xmin = rx(1) ymin = ry(1) xr = rx(2)-xmin yr = ry(2)-ymin c1 = size/xr c2 = size*shape/(yr*sqrt(3.)) jinc= bnd(2) lat=jinc+1 iinc= 2*jinc lmax=bnd(1)*bnd(2) con1=.25 con2=1.0/3.0 C_______Binning loop________________________________________ do i=1,n sx = c1 * (x(i) - xmin) sy = c2 * (y(i) - ymin) j1 = sx+.5 i1 = sy+.5 dist1=(sx-j1)**2 + 3.*(sy-i1)**2 if(dist1 .lt. con1) then L=i1*iinc + j1+1 elseif(dist1 .gt. con2) then L=int(sy)*iinc + int(sx)+lat else j2 = sx i2 = sy if(dist1 .le. (sx-j2 -.5)**2 + 3.*(sy-i2 -.5)**2) then L=i1*iinc+ j1+1 else L=i2*iinc+ j2+lat endif endif cnt(L)=cnt(L)+1 if (keepID) cellid(i)=L xcm(L)=xcm(L)+ (x(i)-xcm(L))/cnt(L) ycm(L)=ycm(L)+ (y(i)-ycm(L))/cnt(L) enddo C_______Compression of output________________________________________ nc=0 do L=1,lmax if(cnt(L) .gt. 0) then nc=nc+1 cell(nc)=L cnt(nc)=cnt(L) xcm(nc)=xcm(L) ycm(nc)=ycm(L) endif enddo n=nc bnd(1)=(cell(nc)-1)/bnd(2)+1 return end hexbin/vignettes/0000755000176200001440000000000013616020747013545 5ustar liggesusershexbin/vignettes/hexagon_binning.Rnw0000644000176200001440000005225413562352573017407 0ustar liggesusers%% Emacs: use Rnw-mode if available, else noweb %% NOTE -- ONLY EDIT THE .Rnw FILE ! %\VignetteIndexEntry{Hexagon Binning} %\VignetteDepends{hexbin, grid, marray} %\VignetteKeywords{Over plotting, Large data set, Visualization} %\VignettePackage{hexbin} \documentclass[]{article} \usepackage[authoryear,round]{natbib} \usepackage{amsmath} \usepackage{hyperref} \author{Nicholas Lewin-Koh\footnote{with minor assistance by Martin M\"achler}} \begin{document} \title{Hexagon Binning: an Overview} \maketitle{} \section{Overview} Hexagon binning is a form of bivariate histogram useful for visualizing the structure in datasets with large $n$. The underlying concept of hexagon binning is extremely simple; \begin{enumerate} \item the $xy$ plane over the set (range($x$), range($y$)) is tessellated by a regular grid of hexagons. \item the number of points falling in each hexagon are counted and stored in a data structure \item the hexagons with count $ > 0$ are plotted using a color ramp or varying the radius of the hexagon in proportion to the counts. \end{enumerate} The underlying algorithm is extremely fast and effective for displaying the structure of datasets with $n \ge 10^6$. If the size of the grid and the cuts in the color ramp are chosen in a clever fashion than the structure inherent in the data should emerge in the binned plots. The same caveats apply to hexagon binning as apply to histograms and care should be exercised in choosing the binning parameters. The hexbin package is a set of function for creating, manipulating and plotting hexagon bins. The package extends the basic hexagon binning ideas with several functions for doing bivariate smoothing, finding an approximate bivariate median, and looking at the difference between two sets of bins on the same scale. The basic functions can be incorporated into many types of plots. This package is based on the original package for S-PLUS by Dan Carr at George Mason University and is mostly the fruit of his graphical genius and intuition. \section{Theory and Algorithm} Why hexagons? There are many reasons for using hexagons, at least over squares. Hexagons have symmetry of nearest neighbors which is lacking in square bins. Hexagons are the maximum number of sides a polygon can have for a regular tesselation of the plane, so in terms of packing a hexagon is 13\% more efficient for covering the plane than squares. This property translates into better sampling efficiency at least for elliptical shapes. Lastly hexagons are visually less biased for displaying densities than other regular tesselations. For instance with squares our eyes are drawn to the horizontal and vertical lines of the grid. The following figure adapted from \cite{carretal} shows this effectively. \begin{figure}[h] \centering <>= library("grid") library("hexbin") x <- rnorm(1000) y <- rnorm(1000) ##-- Hexagon Bins: -- hbin <- hexbin(x,y, xbins = 25) grid.newpage() pushViewport(viewport(layout=grid.layout(1, 2))) pushViewport(viewport(layout.pos.col=1,layout.pos.row=1)) plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE) popViewport() ##-- Manual "square" binning: -- ## grid rx <- range(x); bx <- seq(rx[1],rx[2], length=29) ry <- range(y); by <- seq(ry[1],ry[2], length=29) ## midpoints mx <- (bx[-1]+bx[-29])/2 my <- (by[-1]+by[-29])/2 gg <- as.matrix(expand.grid(mx,my))# dim = (28^2, 2) zz <- unname(table(cut(x, b = bx), cut(y, b = by)))# 28 x 28 ind <- zz > 0 if(FALSE) ## ASCII image: symnum(unname(ind)) sq.size <- zz[ind]^(1/3) / max(zz) ## if we used base graphics: ## symbols(gg[ind,], squares = sq.size, inches = FALSE, fg = 2, bg = 2) pushViewport(viewport(layout.pos.col=2, layout.pos.row=1)) vp <- plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE, type="n") pushHexport(vp$plot, clip="on") grid.rect(x= gg[ind,1], y=gg[ind,2], width = sq.size, height= sq.size, default.units = "native", gp = gpar(col="black",fill="black")) popViewport() @ \caption[bivariate: squares and hexagons]{A bivariate point set binned into squares and hexagons. Bins are scaled approximately equal, and the size of the glyph is proportional to the count in that bin.} \label{fig:compHexSq} \end{figure} We can see in Figure~\ref{fig:compHexSq} that when the data are plotted as squares centered on a regular lattice our eye is drawn to the regular lines which are parallel to the underlying grid. Hexagons tend to break up the lines. How does does the hexagon binning algorithm work? \begin{enumerate} \item Squash $Y$ by $\sqrt{3}$ \item Create a dual lattice \item Bin each point into pair of near neighbor rectangles \item Pick closest of the rectangle centers (adjusting for $\sqrt{3}$) \end{enumerate} << nearNeighbor, echo=FALSE, results=hide >>= x <- -2:2 sq <- expand.grid(list(x = x, y = c(-1,0,1))) fc.sq <- rbind(sq,sq+.5) # face centered squares fc.sq$y <- sqrt(3)*fc.sq$y # stretch y by the sqrt(3) nr <- length(fc.sq$x)/2 @ \begin{figure}[h] \centering <>= par(mfrow = c(3,1)) par(mai = c(.1667,0.2680,0.1667,0.2680)) ##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) points(-.25,.15, col = 2, pch = 16, cex = .5) par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) px <- c(-1,-2,-2,-1)+1 py <- sqrt(3)*(c(0,0,-1,-1)+1) polygon(px, py, density = 0, col = 5) polygon(px+.5, py-sqrt(3)/2, density = 0) points(-.25, .15, col = 2, pch = 16, cex = .5) par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) px <- c(-1,-2,-2,-1) + 1 py <- sqrt(3)*(c(0,0,-1,-1) + 1) polygon(px, py, density = 0, col = 5) polygon(px+.5, py-sqrt(3)/2, density = 0) px <- c(-.5,-.5,0,.5, .5, 0) py <- c(-.5, .5,1,.5,-.5,-1) /sqrt(3) polygon(px, py, col = gray(.5), density = 0) polygon(px-.5, py+sqrt(3)/2, density = 0, col = 4) points(-.25, .15, col = 2, pch = 16, cex = .5) plot.new() arrows(-.25, .15, 0, 0, angle = 10, length = .05) @ \caption[Near Neighbor Rectangles]{} \label{fig:binalg} \end{figure} Figure~\ref{fig:binalg} shows graphically how the algorithm works. In the first panel we see the the dual lattice laid out in black and blue points. The red point is an arbitrary point to be binned. The second panel shows the near neigbor rectangles for each lattice around the point to be binned, the intersection of the rectangles contains the point. The last panel shows the simple test for locating the point in the hexagon, the closest of the two corners which are not intersections is the center of the hexagon to which the point should be allocated. The binning can be calculated in one pass through the data, and is clearly $O(n)$ with a small constant. Storage is vastly reduced compared to the original data. \section{Basic Hexagon Binning Functions} Using the basic hexagon binning functions are not much more involved than using the basic plotting functions. The following little example shows the basic features of the basic plot and binning functions. We start by loading the package and generating a toy example data set. << basic, fig=TRUE, results=hide >>= x <- rnorm(20000) y <- rnorm(20000) hbin <- hexbin(x,y, xbins = 40) plot(hbin) @ There are two things to note here. The first is that the function \texttt{gplot.hexbin} is defined as a \texttt{plot} method for the S4 class \texttt{hexbin}. The second is that the default color scheme for the hexplot is a gray scale. However, there is an argument to plot, \texttt{colramp}, that allows the use of any function that excepts an argument \texttt{n} and returns $n$ colors. Several functions are supplied that provide alternative color-ramps to R's built in color ramp functions, see \texttt{help(ColorRamps)}. << showcol, fig=TRUE, width=7, height=4, echo=FALSE, results=hide >>= #nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE), # widths = rep(1,4), heights=rep(1,2)) grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) vpin <- c(convertWidth (unit(1,"npc"),"inches"), convertHeight(unit(1,"npc"),"inches")) shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai) x <- rnorm(20000) y <- rnorm(20000) hbin <- hexbin(x,y, xbins = 40, shape = shape) #grid.newpage() pushViewport(viewport(layout = grid.layout(1, 3))) pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE, colramp = terrain.colors) popViewport() pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE, colramp = BTY) popViewport() @ The figure shows three examples of using hexagons in a plot for large $n$ with different color schemes. Upper left: the default gray scale, upper right: the R base \texttt{terrain.colors()}, and lower middle: \texttt{BTY()}, a blue to yellow color ramp supplied with hexbin on a perceptually linear scale. The hexbin package supplies a plotting method for the hexbin data structure. The plotting method \texttt{gplot.hexbin} accepts all the parameters for the hexagon function and supplies a legend as well, for easy interpretation of the plot. Figure~2 shows a hex binned plot with a legend. A function \texttt{grid.hexlegend} is supplied for creating user specified hexagon legends. \section{Extended Hexagon Functions} So far we have looked at the basic hexagon plot. The hexbin package supplies several extensions to the basic hexbin, and the associated hexplot. The extensions discussed in this section will be smoothing hexbin objects using the hsmooth function, approximating a bivariate median with hexagons and a version of a bivariate boxplot, and using eroded hexbin objects to look at the overlap of two bivariate populations. \subsection{Smoothing with \texttt{hsmooth}} At this point the hexbin package only provides a single option for smoothing using a discrete kernel. Several improvements are in development including an apply function over neighborhoods and spline functions using a hexagonal basis or tensor products. The apply function should facilitate constructing more sophisticated kernel smoothers. The hexagon splines will provide an alternative to smoothing on a square grid and allow interpolation of hexagons to finer grids. The current implementation uses the center cell, immediate neighbors and second neighbors to smooth the counts. The counts for each resulting cell is a linear combination of the counts in the defined neighborhood, including the center cell and weights. The counts are blurred over the the domain, and the domain increases because of shifting. Generally the dimension of the occupied cells of the lattice increases by one, sometimes two. Some examples of using the hsmooth function are given below. Notice in the plots that the first plot is with no smoothing, weights are \texttt{c(1,0,0)} meaning that only the center cell is used with identity weights. The second plot shows a first order kernel using weights \texttt{c(24,12,0)}, while the third plot uses weights for first and second order neighbors specified as \texttt{c(48,24,12)}. The code segment generating these plots rescales the smoothed counts so that they are on the original scale. << showsmth, fig=TRUE, width=8, height=4, echo=FALSE, results=hide >>= #nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE), # widths = rep(1,4), heights=rep(1,2)) x <- rnorm(10000) y <- rnorm(10000) grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) vpin <- c(convertWidth (unit(1,"npc"), "inches"), convertHeight(unit(1,"npc"), "inches")) shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai) hbin <- hexbin(x,y, xbins = 30,shape = shape) hsmbin1 <- hsmooth(hbin, c( 1, 0,0)) hsmbin2 <- hsmooth(hbin, c(24,12,0)) hsmbin2@count <- as.integer(ceiling(hsmbin2@count/sum(hsmbin2@wts))) hsmbin3 <- hsmooth(hbin,c(48,24,12)) hsmbin3@count <- as.integer(ceiling(hsmbin3@count/sum(hsmbin3@wts))) pushViewport(viewport(layout = grid.layout(1, 3))) pushViewport(viewport(layout.pos.col = 1, layout.pos.row = 1)) plot(hsmbin1, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) plot(hsmbin2, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1)) plot(hsmbin3, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() @ \subsection{Bin Erosion and the \texttt{hboxplot}} The next tool to introduce, gray level erosion, extends the idea of the boxplot. The idea is to extract cells in a way that the most exposed cells are removed first, ie cells with fewer neighbors, but cells with lower counts are removed preferentially to cells with higher counts. The algorithm works as follows: Mark the high count cells containing a given fraction, cdfcut, of the total counts. Mark all the cells if cdfcut is zero. The algorithm then performs gray-level erosion on the marked cells. Each erosion cycle removes counts from cells. The counts removed from each cell are a multiple of the cell's exposed-face count. The algorithm chooses the multiple so at least one cell will be empty or have a count deficit on each erosion cycle. The erode vector contains an erosion number for each cell. The value of erode is \begin{center} $6\times$(The erosion cycle at cell removal) $ - $ (The cell deficit at removal) \end{center} The cell with the highest erosion number is a candidate bivariate median. A few ties in the erosion order are common. The notion of an ordering to the median is nice because it allows us to create a version of a bivariate box plot built on hexagons. The following example comes from a portion of the ''National Health and Nutrition Examination Survey'' included in \texttt{hexbin} as the sample data set NHANES. The data consist of 9575 persons and mesures various clinical factors. Here in Figure~\ref{hbox} we show the levels of transferin, a measure of iron binding against hemoglobin for all \begin{figure}[h] \centering << echo=FALSE, results=hide >>= data(NHANES) #grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) #vpin <- c(convertWidth (unit(1,"npc"), "inches"), # convertHeight(unit(1,"npc"), "inches")) vpin <- c(unit(6,"inches"),unit(4, "inches")) shape <- optShape(height = vpin[2], width = vpin[1], mar = mai) @ << hbox, fig=TRUE, width=6, height=4, echo=FALSE, results=hide >>= hb <- hexbin(NHANES$Transferin, NHANES$Hemoglobin, shape = shape) hbhp <- hboxplot(erode(hb,cdfcut = .05),unzoom = 1.3) pushHexport(hbhp,clip = 'on') hexGraphPaper(hb,fill.edges = 3) popViewport() @ \caption{Hexagon "boxplots" showing the top 95 percent of the data for males and females. The red hexagons are an estimate of the bivariate median.} \label{hbox} \end{figure} Note that we have added ``hexagon graph paper'' to the plot. This can be done for any hexbin plot, using the command \texttt{hexGraphPaper()} where the main argument is the hexbin object. \subsection{Comparing Distributions and the \texttt{hdiffplot}} With univariate data, if there are multiple groups, one often uses a density estimate to overlay densities, and compare two or more distributions. The hdiffplot is the bivariate analog. The idea behind the hdiff plot is to plot one or more bin objects representing multiple groups to compare the distributions. The following example uses the National Health data supplied in the hexbin package, (\texttt{NHANES}). Below we show a comparison of males and females, the bivariate relationship is transferin, which is a derived measure of the ability of blood to bind oxygen, vs the level of hemoglobin. Note that in the call to \texttt{hdiffplot} we erode the bins to calculate the bivariate medians, and only display the upper 75\% of the data. \begin{figure}[h] \centering << hdiff, fig=TRUE, width=6, height=4, echo=FALSE, results=hide >>= #grid.newpage() shape <- optShape(height = vpin[2],width = vpin[1],mar = mai) xbnds <- range(NHANES$Transferin,na.rm = TRUE) ybnds <- range(NHANES$Hemoglobin,na.rm = TRUE) hbF <- hexbin(NHANES$Transferin[NHANES$Sex == "F"], NHANES$Hemoglobin[NHANES$Sex == "F"], xbnds = xbnds, ybnds = ybnds, shape = shape) hbM <- hexbin(NHANES$Transferin[NHANES$Sex == "M"], NHANES$Hemoglobin[NHANES$Sex == "M"], xbnds = xbnds, ybnds = ybnds, shape = shape) #plot.new() hdiffplot(erode(hbF,cdfcut = .25),erode(hbM,cdfcut = .25),unzoom = 1.3) @ \caption{A difference plot of transferin vs hemoglobin for males and females.} \label{hdiffplot} \end{figure} \subsection{Plotting a Third Concomitant Variable} In many cases, such as with spatial data, one may want to plot the levels of a third variable in each hexagon. The grid.hexagons function has a pair of arguments, \texttt{use.count} and \texttt{cell.at}. If \texttt{use.count = FALSE} and \texttt{cell.at} is a numeric vector of the same length as \texttt{hexbin@count} then the attribute vector will be used instead of the counts. \texttt{hexTapply} will summarize values for each hexagon according to the supplied function and return the table in the right order to use as an attribute vector. Another alternative is to set the \texttt{cAtt} slot of the hexbin object and grid.hexagons will automatically plot the attribute if \texttt{use.count = FALSE} and \texttt{cell.at = NULL}. Here is an example using spatial data. Often cartographers use graduated symbols to display varying numerical quantities across a region. \section{Example: cDNA Chip Normalization} This example is taken from the marray package, which supplies methods and classes for the normalization and diagnostic plots of cDNA microarrays. In this example the goal is not to make any comments about the normalization methodology, but rather to show how the diagnostic plots can be enhanced using hexagon binning due to the large number of points ($n = 8,448$ cDNA probes per chip). We look at the diagnostic plot $M$ vs $A$, where $M$ is the log--ratio, $M = \log <- 2 \frac{R}{G}$ and $A$ is the overall intensity, $A = \log <- 2\sqrt{RG}$. Figure~3 shows the plot using points and on the right hexagons. The hexagon binned plot shows that most of the pairs are well below zero, and that the overall shape is more like a comet with most of the mass at the bottom of the curve, rather than a thick bar of points curving below the line. << marray1, fig=TRUE, results=hide >>= ### Need to redo this part. if (require("marray")) { data(swirl, package = "marray") ## use swirl dataset hb1 <- hexbin(maA(swirl[,1]), maM(swirl[,1]), xbins = 40) grid.newpage() pushViewport(viewport(layout = grid.layout(1, 2))) pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1)) nb <- plot(hb1, type = 'n', xlab = 'A', ylab = 'M', main = "M vs A plot with points", legend = 0, newpage = FALSE) pushHexport(nb$plot.vp) grid.points(maA(swirl[,1]), maM(swirl[,1]),pch = 16,gp = gpar(cex = .4)) popViewport() nb$hbin <- hb1 hexVP.abline(nb$plot.vp,h = 0,col = gray(.6)) hexMA.loess(nb) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) hb <- plotMAhex(swirl[,1], newpage = FALSE, main = "M vs A plot with hexagons", legend = 0) hexVP.abline(hb$plot.vp,h = 0,col = gray(.6)) hexMA.loess(hb) popViewport() } else { plot(1) } @ \section{Manipulating Hexbins} The underlying functions for hexbin have been rewritten and now depend on the grid graphics system. The support unit for all hexagon plots is the hexViewport. The function \texttt{hexViewport()} takes a hexbin object as input and creates a viewport scaled to the current device or viewport so that the aspect ratio is scaled appropriately for the hexagons. Unlike in the base graphic functions where the aspect ratio is maintained by shifting the range of the axes, here the extra space is shifted into the margins. Currently hexViewport returns a hexViewport object that has information on the margins and its own pushViewport method. In the next example we will 1st show how to manipulate an existing plot using grid commands and second show how to create a custom plotting function using \texttt{hexViewport} and grid. \subsection{Adding to an existing plot} Adding to an existing plot requires the use of grid functions. For instance, in the following code, << addto, fig=TRUE, echo=TRUE, results=verbatim >>= if (require("marray")) { hplt <- plot(hb1, style = 'centroid', border = gray(.65)) pushHexport(hplt$plot.vp) ll.fit <- loess(hb1@ycm ~ hb1@xcm, weights = hb1@count, span = .4) pseq <- seq(hb1@xbnds[1]+1, hb1@xbnds[2]-1, length = 100) grid.lines(pseq, predict(ll.fit,pseq), gp = gpar(col = 2), default.units = "native") } else { plot(1) } @ we have to use \texttt{grid.lines()}, as opposed to \texttt{lines()}. \bibliography{references} \end{document} hexbin/vignettes/references.bib0000644000176200001440000000057713562345033016353 0ustar liggesusers@article{carretal, author = {Daniel B. Carr and Anthony R. Olsen and Denis White}, title = {Hexagon Mosaic Maps for Display of Univariate and Bivariate Geographical Data}, journal = {Cartography and Geographic Information Systems}, volume = {19}, number = {4}, pages = {228-236}, year = {1992}, publisher = {Taylor & Francis}, doi = {10.1559/152304092783721231} } hexbin/R/0000755000176200001440000000000013616020546011733 5ustar liggesusershexbin/R/LINGRAY.R0000644000176200001440000000461713171627113013172 0ustar liggesusersLinGray <- function(n,beg = 1,end = 92) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(0,0,0), c(0,0,0), c(1,1,1), c(1,1,1), c(2,2,2), c(3,3,3), c(4,4,4), c(5,5,5), c(6,6,6), c(7,7,7), c(8,8,8), c(9,9,9), c(10,10,10), c(11,11,11), c(12,12,12), c(13,13,13), c(14,14,14), c(15,15,15), c(16,16,16), c(17,17,17), c(18,18,18), c(19,19,19), c(20,20,20), c(21,21,21), c(22,22,22), c(23,23,23), c(24,24,24), c(25,25,25), c(26,26,26), c(27,27,27), c(28,28,28), c(29,29,29), c(30,30,30), c(32,32,32), c(34,34,34), c(35,35,35), c(37,37,37), c(39,39,39), c(41,41,41), c(43,43,43), c(45,45,45), c(46,46,46), c(47,47,47), c(49,49,49), c(51,51,51), c(52,52,52), c(54,54,54), c(56,56,56), c(59,59,59), c(61,61,61), c(64,64,64), c(67,67,67), c(69,69,69), c(72,72,72), c(75,75,75), c(76,76,76), c(78,78,78), c(81,81,81), c(84,84,84), c(87,87,87), c(91,91,91), c(94,94,94), c(97,97,97), c(101,101,101), c(104,104,104), c(107,107,107), c(108,108,108), c(112,112,112), c(116,116,116), c(120,120,120), c(124,124,124), c(128,128,128), c(132,132,132), c(136,136,136), c(141,141,141), c(145,145,145), c(147,147,147), c(150,150,150), c(154,154,154), c(159,159,159), c(164,164,164), c(169,169,169), c(174,174,174), c(179,179,179), c(185,185,185), c(190,190,190), c(195,195,195), c(201,201,201), c(207,207,207), c(212,212,212), c(216,216,216), c(218,218,218), c(224,224,224), c(226,226,226), c(230,230,230), c(237,237,237), c(243,243,243), c(245,245,245), c(252,252,252), c(255,255,255), c(255,255,255))[round(seq(beg,end,length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/smoothHexbin.R0000644000176200001440000000253113227156510014525 0ustar liggesuserssetClass("smoothbin", representation("hexbin", wts="numeric")) setGeneric("hsmooth", function(bin, wts) standardGeneric("hsmooth")) smooth.hexbin <- function(bin, wts = c(48, 4, 1)) { if(!is(bin,"hexbin")) stop("first argument must be a hexbin object") cell <- bin@cell - 1 n <- as.integer(length(cell)) cnt <- bin@count xbins <- bin@xbins bdim <- bin@dimen row <- bdim[1] col <- bdim[2] ncol <- col + 4 nrow <- row + 4 nmax <- ncol * nrow sm <- rep.int(0:0, nmax) nr <- cell %/% col + 2 nc <- cell %% col + 3 pad <- rep.int(0:0, nmax - n) cell <- c(nr * ncol + nc, pad) cnt <- c(cnt, pad) ans <- .Fortran("hsm", cell = as.integer(cell), cnt = as.integer(cnt), n = n, nmax = as.integer(nmax), sm = as.integer(sm), ncol = as.integer(ncol), wts = as.integer(wts))[c("cell","cnt","n")] n <- ans$n length(ans$cell) <- length(ans$cnt) <- n bin@xbins <- xbins + 4 bin@xbnds <- addBit(bin@xbnds, f = 2/xbins) bin@ybnds <- addBit(bin@ybnds, f = 2/xbins) bin@dimen <- c(nrow, ncol) bin@cell <- ans$cell bin@count <- ans$cnt new("smoothbin", bin, wts=wts) } setMethod("hsmooth", "hexbin", smooth.hexbin) hexbin/R/grid.hexlegend.R0000644000176200001440000001375313171627113014755 0ustar liggesusersgrid.hexlegend <- function(legend, ysize, lcex, inner, style = "colorscale", minarea = 0.05, maxarea = 0.8, mincnt = 1, maxcnt, trans = NULL, inv = NULL, colorcut, density = NULL, border = NULL, pen = NULL, colramp = function(n) { LinGray(n,beg = 90,end = 15) }, leg.unit="native") { ## the formal arg matching should happen style <- match.arg(style, eval(formals(grid.hexagons)[["style"]])) if (style %in% c("centroids", "lattice", "colorscale")) { ## _______________tranformations_______________________ if(is.null(trans)) { sc <- maxcnt - mincnt bnds <- round(mincnt + sc * colorcut) } else { if(!is.function(trans) && !is.function(inv)) stop("'trans' and 'inv' must both be functions if 'trans' is not NULL") con <- trans(mincnt) sc <- trans(maxcnt) - con bnds <- round(inv(con + sc * colorcut)) } } if(style == "colorscale") { ## use own 'inner' n <- length(bnds) spacing <- ysize/(n + 3) inner <- min(legend/3.5, (sqrt(3) * spacing)/2) } dx <- inner/2 dy <- dx/sqrt(3) hexC <- hexcoords(dx, dy, n = 1,sep=NULL) ## _______________Plotting______________________________ switch(style, "colorscale" = { midx <- legend/3 textx <- (2 * legend)/3 tx <- hexC$x + midx pen <- colramp(n) for(i in seq(length = n-1)) { grid.polygon(tx,hexC$y + i * spacing, default.units=leg.unit,id=NULL,id.lengths=6, gp=gpar(fill = pen[i], col = border)) grid.text(as.character(bnds[i]), textx, (i - 0.5) * spacing, default.units=leg.unit, gp=gpar(cex = lcex)) } grid.text(as.character(bnds[n]), textx, (n - 0.5) * spacing, default.units=leg.unit, gp=gpar(cex = lcex)) grid.text("Counts", legend/2, (n + 1.5) * spacing, default.units=leg.unit, gp=gpar(cex = 1.7 * lcex)) }, "centroids" = , "lattice" = { ## NL Solved hex overlap problem on legend ## Need to tackle too many categories radius <- sqrt(minarea + (maxarea - minarea) * colorcut) n <- length(radius) shift <- c(0, 2*dy*radius) shift <- shift[1:n] + shift[2:(n+1)] #labht <- max(strheight(as.character(bnds), cex = lcex)) labht <- convertY(unit(get.gpar(names = "fontsize")[[1]]*lcex, "points"),"native",valueOnly = TRUE) shift <- pmax(labht, shift) six <- rep.int(6:6, n) xmid <- legend/3 inc <- ysize/(n+3) if(inc > max(shift)) y <- inc * 1:n else { y <- cumsum(shift) extra.slop <- (n * inc) - y[n] # FIXME? y[n] == sum(shift) shift[-1] <- shift[-1] + extra.slop/(n-1) y <- cumsum(shift) ## (y+(1/n)*extra.slop)-y[1] ## delta <- max(log(shift))-min(log(shift)) ## fudge <- extra.slop*(diff(log(shift))/delta) ## y<- c(y[1], y[-1]+ fudge ) } textx <- rep.int((2 * legend)/3, n) ## ____________________plotting______________________ if(is.null(pen)) pen <- 1 if(is.null(border)) border <- pen grid.polygon(x = rep.int(hexC$x,n)* rep.int(radius, six) + rep.int(xmid, 6 * n), y = rep.int(hexC$y,n)* rep.int(radius, six) + rep.int(y, six), default.units=leg.unit, id=NULL, id.lengths=rep.int(6,n), gp=gpar(fill = pen, col = border)) grid.text(as.character(bnds), textx, y, default.units=leg.unit, gp=gpar(cex = lcex)) grid.text("Counts", legend/2, (n + 2) * inc, default.units=leg.unit, gp=gpar(cex =1.7 * lcex)) }, "nested.lattice" = , "nested.centroids" = { ## _____________x scaling_____________________________ numb <- cut(floor(legend/inner), breaks = c(-1, 0, 2,4)) ## Note: In old code ## top breaks=c(-1,0,2,4,8), numb<- 5 and size=1:9 if(is.na(numb)) numb <- 4 switch(numb, {warning("not enough space for legend"); return()}, size <- 5, size <- c(1, 5, 9), size <- c(1, 3, 5, 7, 9)) xmax <- length(size) radius <- sqrt(minarea + (maxarea - minarea) * (size - 1)/9) txt <- as.character(size) ##___________________y scaling_____________________ lab <- c("Ones", "Tens", "Hundreds", "Thousands", "10 Thousands", "100 Thousands", "Millions", "10 Millions", "100 Millions", "Billions") power <- floor(log10(maxcnt)) + 1 yinc <- 16 * dy if(ysize/power < yinc) {warning("Not enough height for legend"); return()} xmid <- legend/10 x <- inner * (1:xmax - (1 + xmax)/2) + xmid n <- length(x) tx <- rep.int(hexC$x, n) ty <- rep.int(hexC$y, n) six <- rep.int(6:6, n) y <- rep.int(3 * dy - yinc, xmax) ## ____________________plotting______________________ if(is.null(pen)) { pen <- 1:power +1 pen <- cbind(pen, pen +10) } if(is.null(border)) border <- FALSE for(i in 1:power) { y <- y + yinc hexpolygon(x, y, hexC, col = pen[i,1], border = border) grid.polygon(x= tx * rep.int(radius, six) + rep.int(x, six), y= ty * rep.int(radius, six) + rep.int(y, six), default.units=leg.unit, id=NULL, id.lengths=rep(6,n), gp=gpar(fill = pen[i,2], col = border)) grid.text(txt, x, y - 4.5 * dy, default.units=leg.unit, gp=gpar(cex = lcex)) ##adj= 0.5, cex = lcex) grid.text(lab[i], xmid, y[1] + 4.5 * dy, default.units=leg.unit, gp=gpar(cex = 1.7*lcex)) ##adj= 0.5, cex = 1.7*lcex) } })## switch(style = *) }## hex.legend() hexbin/R/hexutil.R0000644000176200001440000000721213171627113013541 0ustar liggesusershcell2xyInt <- function(hbin, xbins=NULL, xbnds=NULL, ybnds=NULL, shape=NULL) { if(missing(hbin) && (is.null(xbnds) || is.null(ybnds))) stop("Need a hexbin object or boundaries to make lattice") if(missing(hbin) && (is.null(xbins) || is.null(shape))) stop("Need xbins and shape to make a lattice") if(!missing(hbin)) { xbins <- hbin@xbins shape <- hbin@shape xbnds <- if(is.null(xbnds)) hbin@xbnds else xbnds ybnds <- if(is.null(ybnds)) hbin@ybnds else ybnds dimen <- hbin@dimen } if(missing(hbin)) { jmax <- floor(xbins + 1.5001) imax <- 2 * floor((xbins *shape)/sqrt(3) + 1.5001) dimen <- c(imax, jmax) } cell <- 1:(dimen[1]*dimen[2])-1 i <- cell %/% dimen[2] j <- cell %% dimen[2] list(i=i+1, j=j+1) } hgridcent <- function(xbins, xbnds, ybnds, shape, edge.add=0) { ## auxiliary for hexGraphPaper(): jmax <- floor(xbins + 1.5001) c1 <- 2 * floor((xbins *shape)/sqrt(3) + 1.5001) imax <- (jmax*c1 -1)/jmax + 1 dimen <- c(imax, jmax) c3 <- diff(xbnds)/xbins c4 <- (diff(ybnds) * sqrt(3))/(2 * shape * xbins) if(edge.add > 0) { xbnds <- xbnds + 1.5*c(-edge.add*c3, edge.add*c3) ybnds <- ybnds + c(-edge.add*c4, edge.add*c4) dimen <- dimen + rep.int(2*edge.add, 2) } jmax <- dimen[2] cell <- 1:(dimen[1]*dimen[2]) i <- cell %/% jmax j <- cell %% jmax y <- c4 * i + ybnds[1] x <- c3 * ifelse(i %% 2 == 0, j, j + 0.5) + xbnds[1] list(x = x, y = y, dimen = dimen, dx=c3, dy=c4) } hexGraphPaper <- function(hb, xbnds=NULL, ybnds=NULL, xbins=30, shape=1, add=TRUE, fill.edges=1, fill=0, border=1) { if(missing(hb) && (is.null(xbnds) || is.null(ybnds))) stop("Need a hexbin object or boundaries to make lattice") if(!missing(hb)) { xbins <- hb@xbins shape <- hb@shape xbnds <- if(is.null(xbnds)) hb@xbnds else xbnds ybnds <- if(is.null(ybnds)) hb@ybnds else ybnds dimen <- hb@dimen } xy <- hgridcent(xbins, xbnds, ybnds, shape, edge.add=fill.edges) if(add){ sx <- xbins/diff(xbnds) sy <- (xbins * shape)/diff(ybnds) inner <- 0.5 outer <- (2 * inner)/sqrt(3) dx <- inner/sx dy <- outer/(2 * sy) if(add){ hexC <- hexcoords(dx, dy, sep=NULL) hexpolygon (xy$x, xy$y, hexC, dx, dy, fill = fill, border = border, hUnit = "native") } } invisible(xy) } hexTapply <- function(hbin,dat,FUN=sum,...,simplify=TRUE) { if(is.null(hbin@cID)) stop("Must have cell ID's to do this operation \n please re-bin data using IDs = TRUE") if((length(dat)> 0) && (length(dat) != length(hbin@cID))) stop("Length of IDs does not match the length of the data") tapply(dat,hbin@cID,FUN,...,simplify=simplify) } optShape <- function(vp, height=NULL, width=NULL, mar=NULL) { if(missing(vp) && (is.null(height) || is.null(width))) stop("Need a viewport object or height and width of the plotting region.") if(!missing(vp)) { if("hexVP" %in% class(vp)) { height <- vp@plt[2] width <- vp@plt[1] } else if("viewport"%in%class(vp)) { #height <- convertHeight(unit(1,"npc"),"inches") #width <- convertWidth (unit(1,"npc"),"inches") height <- convertUnit(vp$height,"inches") width <- convertUnit(vp$width,"inches") } else stop("need valid viewport or hexViewport") } if(!is.null(mar)){ height <- height - mar[1] - mar[3] width <- width - mar[2] - mar[4] } shape <- as.numeric(height)/as.numeric(width) shape } inout.hex <- function(hbin,mincnt) { if(is.null(hbin@cID)) stop("bin object must have a cID slot, \n try re-binning with ID = TRUE") tI <- table(hbin@cID) which(hbin@cID%in%(names(tI)[tI 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c( 0, 0, 0), c( 45, 0, 36), c( 56, 0, 46), c( 60, 0, 49), c( 67, 0, 54), c( 70, 0, 59), c( 71, 0, 61), c( 75, 0, 68), c( 74, 0, 73), c( 74, 0, 77), c( 73, 0, 81), c( 71, 0, 87), c( 69, 1, 90), c( 68, 2, 94), c( 66, 3, 97), c( 63, 6,102), c( 61, 7,106), c( 58, 10,109), c( 56, 12,113), c( 53, 15,116), c( 48, 18,119), c( 47, 20,121), c( 44, 23,124), c( 41, 27,128), c( 40, 28,129), c( 37, 32,132), c( 34, 36,134), c( 29, 43,137), c( 25, 52,138), c( 24, 57,139), c( 24, 62,141), c( 24, 64,142), c( 23, 65,142), c( 23, 69,143), c( 23, 71,142), c( 23, 71,142), c( 23, 73,142), c( 23, 75,142), c( 23, 75,142), c( 23, 78,142), c( 23, 80,142), c( 23, 80,142), c( 23, 82,141), c( 23, 85,141), c( 23, 85,141), c( 23, 87,140), c( 23, 87,140), c( 24, 90,140), c( 24, 90,140), c( 24, 93,139), c( 24, 93,139), c( 24, 93,139), c( 24, 93,139), c( 24, 97,139), c( 24, 97,139), c( 25,101,138), c( 25,101,138), c( 25,104,137), c( 25,104,137), c( 25,104,137), c( 26,108,137), c( 26,108,137), c( 27,111,136), c( 27,111,136), c( 27,111,136), c( 27,115,135), c( 27,115,135), c( 28,118,134), c( 28,118,134), c( 29,122,133), c( 29,122,133), c( 29,122,133), c( 29,122,133), c( 29,125,132), c( 29,125,132), c( 30,128,131), c( 30,128,131), c( 31,131,130), c( 31,131,130), c( 31,131,130), c( 32,134,128), c( 32,134,128), c( 33,137,127), c( 33,137,127), c( 33,137,127), c( 34,140,125), c( 34,140,125), c( 35,142,123), c( 35,142,123), c( 36,145,121), c( 36,145,121), c( 36,145,121), c( 37,147,118), c( 37,147,118), c( 38,150,116), c( 38,150,116), c( 40,152,113), c( 40,152,113), c( 41,154,111), c( 41,154,111), c( 42,156,108), c( 42,156,108), c( 43,158,106), c( 43,158,106), c( 43,158,106), c( 45,160,104), c( 45,160,104), c( 46,162,101), c( 46,162,101), c( 48,164, 99), c( 48,164, 99), c( 50,166, 97), c( 50,166, 97), c( 51,168, 95), c( 53,170, 93), c( 53,170, 93), c( 53,170, 93), c( 55,172, 91), c( 55,172, 91), c( 57,174, 88), c( 57,174, 88), c( 59,175, 86), c( 62,177, 84), c( 64,178, 82), c( 64,178, 82), c( 67,180, 80), c( 67,180, 80), c( 69,181, 79), c( 72,183, 77), c( 72,183, 77), c( 72,183, 77), c( 75,184, 76), c( 77,186, 74), c( 80,187, 73), c( 83,189, 72), c( 87,190, 72), c( 91,191, 71), c( 95,192, 70), c( 99,193, 70), c(103,194, 70), c(107,195, 70), c(111,196, 70), c(111,196, 70), c(115,196, 70), c(119,197, 70), c(123,197, 70), c(130,198, 71), c(133,199, 71), c(137,199, 72), c(140,199, 72), c(143,199, 73), c(143,199, 73), c(147,199, 73), c(150,199, 74), c(153,199, 74), c(156,199, 75), c(160,200, 76), c(167,200, 78), c(170,200, 79), c(173,200, 79), c(173,200, 79), c(177,200, 80), c(180,200, 81), c(183,199, 82), c(186,199, 82), c(190,199, 83), c(196,199, 85), c(199,198, 85), c(199,198, 85), c(203,198, 86), c(206,197, 87), c(212,197, 89), c(215,196, 90), c(218,195, 91), c(224,194, 94), c(224,194, 94), c(230,193, 96), c(233,192, 98), c(236,190,100), c(238,189,104), c(240,188,106), c(240,188,106), c(242,187,110), c(244,185,114), c(245,184,116), c(247,183,120), c(248,182,123), c(248,182,123), c(250,181,125), c(251,180,128), c(252,180,130), c(253,180,133), c(253,180,133), c(254,180,134), c(254,179,138), c(255,179,142), c(255,179,145), c(255,179,145), c(255,179,152), c(255,180,161), c(255,180,164), c(255,180,167), c(255,180,167), c(255,181,169), c(255,181,170), c(255,182,173), c(255,183,176), c(255,183,176), c(255,184,179), c(255,185,179), c(255,185,182), c(255,186,182), c(255,186,182), c(255,187,185), c(255,188,185), c(255,189,188), c(255,189,188), c(255,190,188), c(255,191,191), c(255,192,191), c(255,194,194), c(255,194,194), c(255,197,197), c(255,198,198), c(255,200,200), c(255,201,201), c(255,201,201), c(255,202,202), c(255,203,203), c(255,205,205), c(255,206,206), c(255,206,206), c(255,208,208), c(255,209,209), c(255,211,211), c(255,215,215), c(255,216,216), c(255,216,216), c(255,218,218), c(255,219,219), c(255,221,221), c(255,223,223), c(255,226,226), c(255,228,228), c(255,230,230), c(255,230,230), c(255,232,232), c(255,235,235), c(255,237,237), c(255,240,240), c(255,243,243), c(255,246,246), c(255,249,249), c(255,251,251), c(255,253,253), c(255,255,255))[ round(seq(beg,end, length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/lattice.R0000644000176200001440000006742313171627113013516 0ustar liggesusers# the functions in this file are verbatim copies from those in package # lattice, http://cran.r-project.org/src/contrib/lattice_0.20-29.tar.gz # copied on Aug 8, 2014, by Edzer Pebesma. # reason for copying is that hexbin 1.26-3 generates # the following NOTE on CRAN: # # checking dependencies in R code ... NOTE # Unexported objects imported by ':::' calls: # lattice:::cond.orders lattice:::construct.scales # lattice:::cupdate lattice:::limits.and.aspect # lattice:::trellis.skeleton # See the note in ?::: about the use of this operator. # See the information on DESCRIPTION files in the chapter Creating R # packages of the Writing R Extensions manual. # the files in lattice carry the following copyright notice: ### Copyright (C) 2001-2006 Deepayan Sarkar ### Copyright (C) 2001-2005 Saikat DebRoy ### ### This file is part of the lattice package for R. ### It is made available under the terms of the GNU General Public ### License, version 2, or at your option, any later version, ### incorporated herein by reference. ### ### This program is distributed in the hope that it will be ### useful, but WITHOUT ANY WARRANTY; without even the implied ### warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ### PURPOSE. See the GNU General Public License for more ### details. ### ### You should have received a copy of the GNU General Public ### License along with this program; if not, write to the Free ### Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, ### MA 02110-1301, USA construct.legend <- function(legend = NULL, key = NULL, fun = "draw.key") { if (is.null(legend) && is.null(key)) return(NULL) if (is.null(legend)) legend <- list() if (!is.null(key)) { space <- key$space x <- y <- corner <- NULL if (is.null(space)) { if (any(c("x", "y", "corner") %in% names(key))) { stopifnot(is.null(x) || (length(x) == 1 && x >= 0 && x <= 1)) stopifnot(is.null(y) || (length(y) == 1 && y >= 0 && y <= 1)) stopifnot(is.null(corner) || (length(corner) == 2 && all(corner %in% c(0, 1)))) space <- "inside" x <- key$x y <- key$y corner <- key$corner ## check for valid values } else space <- "top" } if (space != "inside" && space %in% names(legend)) stop(gettextf("component '%s' duplicated in key and legend", space)) key.legend <- list(fun = fun, args = list(key = key, draw = FALSE)) key.legend$x <- x key.legend$y <- y key.legend$corner <- corner legend <- c(list(key.legend), legend) names(legend)[1] <- space } legend } extend.limits <- function(lim, length = 1, axs = "r", prop = if (axs == "i") 0 else lattice.getOption("axis.padding")$numeric) { ## if (!is.numeric(lim)) NA if (all(is.na(lim))) NA_real_ # or lim? else if (is.character(lim) ) { c(1, length(lim)) + c(-1, 1) * if (axs == "i") 0.5 else lattice.getOption("axis.padding")$factor } else if (length(lim) == 2) { if (lim[1] > lim[2]) { ccall <- match.call() ccall$lim <- rev(lim) ans <- eval.parent(ccall) return (rev(ans)) } if (!missing(length) && !missing(prop)) stop("'length' and 'prop' cannot both be specified") if (length <= 0) stop("'length' must be positive") if (!missing(length)) { prop <- (as.numeric(length) - as.numeric(diff(lim))) / (2 * as.numeric(diff(lim))) } if (lim[1]==lim[2]) lim + 0.5 * c(-length,length) else { d <- diff(as.numeric(lim)) lim + prop * d * c(-1,1) } } else { print(lim) stop("improper length of 'lim'") } } limitsFromLimitlist <- function(have.lim, lim, relation, limitlist, used.at, numlimitlist, axs, npackets) ## have.lim: logical, whether xlim/ylim was explicitly specified ## lim: the specified limit if have.lim = TRUE ## relation: same/free/sliced ## limitlist: list of limits from prepanel calculations, one for each panel ## numlimitlist: (optional) numeric locations for factors (lim ## will be levels including unused ones) ## axs: "r", "i" etc, passed on to extend.limits ## return value depends on relation. (See limits.and.aspect below, ## where this is used, for partial enlightenment.) { if (relation == "same") { ## The problem here is that we need to figure out the overall ## limit required from the limits of each panel. This could be ## a problem for two reasons. First, some panels could have no ## data in them, in which case the corresponding limits would ## be NA. Secondly, the limits could be either numeric or ## character vectors (the latter for factors). When relation = ## same, the type should be same across panels. When numeric, ## we just take range, leaving out NAs. But what about ## factors? Is it OK to assume that all the non-NA vectors ## would be exactly the same ? They should be, since levels(x) ## would not change even if not all levels are ## represented. So, I'm just taking unique of all the vectors ## concatenated, excluding NA's ## Additional complication: Need to preserve class of limits, ## to be used later in tick location/label calculation. Not a ## problem in other cases, but here unlist-ing loses the ## class. #if (!have.lim) ## always calculate the limits from prepanel first: ## should check that all classes are the same. How ? What ## about NA's ? Arrgh! ## to handle NA's, how about: all.na <- unlist(lapply(limitlist, function(x) all(is.na(x)))) class.lim <- ## retain non-NA limitlists only lapply(limitlist[!all.na], class) ## class.lim is a list now, may be length 0 limits <- unlist(limitlist) ## loses the class attribute ## if (length(limits) > 0) if (sum(!is.na(limits)) > 0) { if (is.character(limits)) { limits <- unique(limits[!is.na(limits)]) slicelen <- diff(extend.limits(limits, axs = axs)) } else ## if (is.numeric(limits)) # or dates etc { limits <- extend.limits(range(as.numeric(limits), finite = TRUE), axs = axs) slicelen <- diff(range(limits, finite = TRUE)) } ## hopefully put back appropriate class of limits: ## FIXME: date changes may have messed this up if (length(class.lim) > 0) class(limits) <- if (all(class.lim[[1]] == "integer")) "numeric" else class.lim[[1]] ## (have to handle "integer" specially, since variable ## specifications like 1:10 are rather common, and ## class() <- "integer" would turn the limits into ## integers) } else { limits <- c(0,1) slicelen <- 1 } if (have.lim) { if (is.list(lim)) stop("limits cannot be a list when relation = same") old.limits <- limits limits <- lim ## lim overrides prepanel except NAs if (!is.character(limits) && !is.character(old.limits)) { limits[is.na(limits)] <- old.limits[is.na(limits)] } slicelen <- ## this no longer works for dates (R 2.6) ## if (is.numeric(lim)) diff(range(lim)) ## else length(lim) + 2 if (is.character(limits)) length(limits) + 2 else diff(range(as.numeric(limits))) } ans <- list(limits = limits, slicelen = slicelen) } else if (relation == "sliced") { if (have.lim) { if (is.list(lim)) { limits <- rep(lim, length.out = npackets) } else warning("Explicitly specified limits ignored") } slicelen <- limitlist for (i in seq_along(limitlist)) { slicelen[[i]] <- ## if (is.numeric(limitlist[[i]])) if (!is.character(limitlist[[i]])) { if (any(is.finite(limitlist[[i]]))) ## range unnecessary, but... diff(range(as.numeric(limitlist[[i]]), finite = TRUE)) else NA_real_ } else if (!any(is.na(numlimitlist[[i]]))) diff(range(as.numeric(numlimitlist[[i]]))) else NA_real_ } slicelen <- (if (axs == "i") 1 else 1 + 2 * lattice.getOption("axis.padding")$numeric) * max(unlist(slicelen), na.rm = TRUE) for (i in seq_along(limitlist)) { if (is.numeric(limitlist[[i]])) limitlist[[i]] <- extend.limits(limitlist[[i]], length = slicelen) } for (i in seq_along(numlimitlist)) { if (!all(is.na(numlimitlist[[i]]))) numlimitlist[[i]] <- extend.limits(as.numeric(numlimitlist[[i]]), length = slicelen) } ans <- list(limits = limitlist, used.at = used.at, numlimitlist = numlimitlist, slicelen = slicelen) } else if (relation == "free") { if (have.lim) { ## This is the only situation where limits can be a list ## (doesn't make sense when relation="same", ignored when ## relation="sliced"). Even if limits is not a list (but ## is specified), it will be treated as a list, and ## repeated as necessary (see further comments below). if (!is.list(lim)) lim <- list(lim) ## There's a subtle consideration here. It is possible ## for some panels to have nothing in them (or only NA's). ## Such panels usually have their prepanel functions ## return NA. When 'limits' is specified as a list, this ## will be interpreted as the limit specification for the ## non-empty panels only (this is an arbitrary choice, but ## it usually makes more sense, even though it's less ## general than the other choice). ## which ones are non-NA? id <- which(sapply(limitlist, function(x) !all(is.na(x)))) ## replace these with the limits supplied, except if the ## supplied limits are NULL, in which case retain limits ## calculated by prepanel. old.limitlist <- limitlist limitlist[id] <- lim which.null <- sapply(limitlist, is.null) limitlist[which.null] <- old.limitlist[which.null] ## lim overrides prepanel except NAs for (i in seq_along(limitlist)) { if (!is.character(limitlist[[i]]) && !is.character(old.limitlist[[i]])) { isna <- is.na(limitlist[[i]]) limitlist[[i]][isna] <- old.limitlist[[i]][isna] } } } for (i in seq_along(limitlist)) { if (!all(is.na(limitlist[[i]])) && !is.character(limitlist[[i]])) limitlist[[i]] <- ## preserves class extend.limits(limitlist[[i]], axs = axs) ## o.w., keep it as it is } slicelen <- numeric(length(limitlist)) for (i in seq_along(limitlist)) slicelen[i] <- if (!is.character(limitlist[[i]])) diff(range(as.numeric(limitlist[[i]]))) else if (!any(is.na(numlimitlist[[i]]))) diff(range(numlimitlist[[i]])) else NA_real_ ans <- list(limits = limitlist, used.at = used.at, numlimitlist = numlimitlist, slicelen = slicelen) } ans } complete_names <- function(x, template, allow.invalid = FALSE) { pid <- pmatch(names(x), names(template), duplicates.ok = TRUE) if (allow.invalid) { x <- x[!is.na(pid)] pid <- pid[!is.na(pid)] } else { if (any(is.na(pid))) warning("Invalid or ambiguous component names: ", paste(names(x)[which(is.na(pid))], collapse = ", ") ) } if (any(duplicated(pid))) stop("Multiple matches to component name") names(x) <- names(template)[pid] x } getFunctionOrName <- function(FUN) ## Try lattice namespace first? Does that happen automatically? { if (is.function(FUN)) FUN else if (is.character(FUN)) get(FUN) else eval(FUN) } trellis.skeleton <- function(formula = NULL, cond, aspect = default.args$aspect, # argument in xyplot as.table = default.args$as.table, between = default.args$between, key = NULL, legend = NULL, page = default.args$page, main = default.args$main, sub = default.args$sub, par.strip.text = default.args$par.strip.text, layout = default.args$layout, skip = default.args$skip, strip = default.args$strip.default, # argument in xyplot strip.left = FALSE, xlab.default = NULL, ylab.default = NULL, xlab = NULL, # argument in xyplot ylab = NULL, # argument in xyplot xlab.top = NULL, ylab.right = NULL, panel, # argument in xyplot xscale.components = default.args$xscale.components, yscale.components = default.args$yscale.components, axis = default.args$axis, subscripts = TRUE, # ignored, for reasons given above index.cond = NULL, perm.cond = NULL, ..., par.settings = NULL, plot.args = NULL, lattice.options = NULL) { default.args <- lattice.getOption("default.args") if (is.null(skip)) skip <- FALSE foo <- list(formula = formula, as.table = as.table, aspect.fill = (aspect == "fill"), ## key = key, legend = construct.legend(legend = legend, key = key), panel = panel, page = page, layout = layout, skip = skip, strip = if (is.logical(strip) && strip) "strip.default" else strip, strip.left = if (is.logical(strip.left) && strip.left) strip.custom(horizontal = FALSE) else strip.left, xscale.components = xscale.components, yscale.components = yscale.components, axis = axis, xlab = xlab, ylab = ylab, xlab.default = xlab.default, ylab.default = ylab.default, xlab.top = xlab.top, ylab.right = ylab.right, main = main, sub = sub, x.between = 0, y.between = 0, par.settings = par.settings, plot.args = plot.args, lattice.options = lattice.options, par.strip.text = par.strip.text, index.cond = index.cond, perm.cond = perm.cond) if (!is.null(between$x)) foo$x.between <- between$x if (!is.null(between$y)) foo$y.between <- between$y foo$condlevels <- lapply(cond, levels) list(foo = foo, dots = list(...)) } cond.orders <- function(foo, ...) ## function to determine order of panels within a cond. variable ## foo: trellis object-to-be ## calculate actual values for index.cond and perm.cond. ## index.cond can be a function, in which case it would be used to ## determing order of levels within conditioning variables ## Question: should these be determined at run-time? Wouldn't be ## impossible, but has the disadvantage that looking at the ## trellis object will be totally uninformative in the default ## case (when both would be NULL). In a sense, this is fine, since ## having index.cond be a function is similar to having a prepanel ## function. After all, the results depend only on the panel ## contents, and those cannot be changed via update. { ## the following to be used for changing order of conditioning ## variables and indexing their levels. The object foo already has ## components index.cond and perm.cond as whatever was passed to ## the original function call. If these are NULL, suitable ## defaults need to be computed. If foo$index.cond is a function, ## index.cond has to be computed appropriately. index.cond <- vector(mode = "list", length = length(foo$condlevels)) for (i in seq_along(foo$condlevels)) index.cond[[i]] <- seq_along(foo$condlevels[[i]]) perm.cond <- seq_len(length(foo$condlevels)) if (!is.null(foo$perm.cond)) { if (all(sort(foo$perm.cond) == perm.cond)) perm.cond <- foo$perm.cond else stop("Invalid value of perm.cond") } if (!is.null(foo$index.cond)) { if (is.list(foo$index.cond) && length(foo$index.cond) == length(index.cond)) { for (i in seq_along(foo$condlevels)) index.cond[[i]] <- index.cond[[i]][foo$index.cond[[i]]] } else if (is.function(foo$index.cond)) { FUN <- foo$index.cond nplots <- length(foo$panel.args) panel.order <- numeric(nplots) for (count in seq_len(nplots)) { if (is.list(foo$panel.args[[count]])) { pargs <- c(foo$panel.args.common, foo$panel.args[[count]], list(...)) prenames <- names(formals(FUN)) if (!("..." %in% prenames)) pargs <- pargs[intersect(names(pargs), prenames)] panel.order[count] <- do.call("FUN", pargs) } else ## this happens for empty panels { is.na(panel.order) <- count # panel.order[count] <- NA } } dim(panel.order) <- sapply(foo$condlevels, length) for (i in seq_along(foo$condlevels)) index.cond[[i]] <- order(apply(panel.order, i, mean, na.rm = TRUE)) } else stop("Invalid value of index.cond") } list(index.cond = index.cond, perm.cond = perm.cond) } construct.scales <- function(draw = TRUE, axs = "r", tck = 1, tick.number = 5, at = FALSE, labels = FALSE, log = FALSE, alternating = TRUE, relation = "same", abbreviate = FALSE, minlength = 4, limits = NULL, format = NULL, equispaced.log = TRUE, lty = FALSE, lwd = FALSE, cex = FALSE, rot = FALSE, col = FALSE, col.line = col, alpha = FALSE, alpha.line = alpha, font = FALSE, fontfamily = FALSE, fontface = FALSE, lineheight = FALSE, ..., ## NOTE: ... is currently ignored x = NULL, y = NULL) { ## top-level values x.scales <- y.scales <- list(draw = draw, axs = axs, tck = tck, tick.number = tick.number, at = at, labels = labels, log = log, alternating = alternating, relation = relation, abbreviate = abbreviate, minlength = minlength, limits = limits, format = format, equispaced.log = equispaced.log, lty = lty, lwd = lwd, cex = cex, rot = rot, col = col, col.line = col.line, alpha = alpha, alpha.line = alpha.line, font = font, fontfamily = fontfamily, fontface = fontface, lineheight = lineheight) ## override by component-specific values if (!is.null(x)) { if (is.character(x)) x <- list(relation = x) x <- complete_names(x, x.scales) x.scales[names(x)] <- x } if (!is.null(y)) { if (is.character(y)) y <- list(relation = y) y <- complete_names(y, y.scales) y.scales[names(y)] <- y } if (is.logical(x.scales$alternating)) x.scales$alternating <- if (x.scales$alternating) c(1,2) else 1 if (is.logical(y.scales$alternating)) y.scales$alternating <- if (y.scales$alternating) c(1,2) else 1 for (nm in c("tck", "cex", "rot")) { x.scales[[nm]] <- rep(x.scales[[nm]], length.out = 2) y.scales[[nm]] <- rep(y.scales[[nm]], length.out = 2) } if (x.scales$relation == "same" && (is.list(x.scales$at) || is.list(x.scales$labels))) stop("the 'at' and 'labels' components of 'scales' may not be lists when 'relation = \"same\"'") if (y.scales$relation == "same" && (is.list(y.scales$at) || is.list(y.scales$labels))) stop("the 'at' and 'labels' components of 'scales' may not be lists when 'relation = \"same\"'") list(x.scales = x.scales, y.scales = y.scales) } cupdate <- function(index, maxim) { ## This unexported function is used to handle arbitrary number of ## conditioning variables : every time it is called, it increments ## the "current" level of the conditioning variables suitably, ## i.e., it tries to increment the level of the 1st conditining ## variable (the one which varies fastest along panel order) and ## if it happens to be at its maximum (last) value, it sets it to ## the first value AND increments the "current" level of the 2nd ## (next) conditioning variable recursively. if(length(index)!=length(maxim)||length(maxim)<=0) stop("Inappropriate arguments") index[1] <- index[1] + 1 if (index[1] > maxim[1] && length(maxim) > 1) c(1, cupdate(index[-1], maxim[-1])) else index } limits.and.aspect <- function(prepanel.default, prepanel = NULL, have.xlim = FALSE, xlim = NULL, have.ylim = FALSE, ylim = NULL, x.relation, y.relation, panel.args.common = list(), panel.args = list(), aspect, banking = lattice.getOption("banking"), npackets = length(panel.args), x.axs = "r", y.axs = "r", ...) ## extra arguments for prepanel (for qqmathline) { prepanel.default.function <- getFunctionOrName(prepanel.default) prepanel <- getFunctionOrName(prepanel) if (npackets<1) stop("need at least one panel") x.limits <- vector("list", npackets) y.limits <- vector("list", npackets) x.used.at <- vector("list", npackets) y.used.at <- vector("list", npackets) x.num.limit <- vector("list", npackets) y.num.limit <- vector("list", npackets) dxdy <- vector("list", npackets) for (count in seq_len(npackets)) { if (is.list(panel.args[[count]])) { pargs <- c(panel.args.common, panel.args[[count]], list(...)) tem <- do.call("prepanel.default.function", pargs) if (is.function(prepanel)) ## results will 'overwrite' defaults { prenames <- names(formals(prepanel)) if (!("..." %in% prenames)) pargs <- pargs[intersect(names(pargs), prenames)] pretem <- do.call("prepanel", pargs) ## prepanel() over-rides defaults except NAs - e.g. ylim = c(0, NA) if (!is.null(pretem$xlim) && !is.character(pretem$xlim)) if (any(isna <- is.na(pretem$xlim))) pretem$xlim[isna] <- tem$xlim[isna] if (!is.null(pretem$ylim) && !is.character(pretem$ylim)) if (any(isna <- is.na(pretem$ylim))) pretem$ylim[isna] <- tem$ylim[isna] tem <- updateList(tem, pretem) ## tem[names(pretem)] <- pretem } x.limits[[count]] <- tem$xlim y.limits[[count]] <- tem$ylim x.used.at[[count]] <- if (is.null(tem$xat)) NA else tem$xat y.used.at[[count]] <- if (is.null(tem$yat)) NA else tem$yat x.num.limit[[count]] <- if (is.null(tem$xat)) NA else range(tem$xat) y.num.limit[[count]] <- if (is.null(tem$yat)) NA else range(tem$yat) dxdy[[count]] <- list(dx = tem$dx, dy = tem$dy) } else ## this happens for empty panels { x.limits[[count]] <- c(NA_real_, NA_real_) y.limits[[count]] <- c(NA_real_, NA_real_) x.used.at[[count]] <- NA_real_ y.used.at[[count]] <- NA_real_ x.num.limit[[count]] <- NA_real_ y.num.limit[[count]] <- NA_real_ dxdy[[count]] <- list(dx = NA_real_, dy = NA_real_) } } ## Some explanation might be helpful here. The for loop above ## creates a list of xlims/ylims. Each of these might be either ## numeric (when x/y is numeric, shingle or POSIXt etc), or levels ## of a factor (that's how prepanel.default.functions are set ## up). However, at this point, all x.limits[[i]] must be of the ## same type. Returned limits must be in accordance with this ## type. The only exception is when relation = "free", in which ## case they may be different. This could happen if [xy]lim or ## limits is supplied as a list in the high level function. x.limits <- limitsFromLimitlist(have.lim = have.xlim, lim = xlim, relation = x.relation, limitlist = x.limits, used.at = x.used.at, numlimitlist = x.num.limit, axs = x.axs, npackets = npackets) y.limits <- limitsFromLimitlist(have.lim = have.ylim, lim = ylim, relation = y.relation, limitlist = y.limits, used.at = y.used.at, numlimitlist = y.num.limit, axs = y.axs, npackets = npackets) if (is.character(aspect)) { if (aspect == "xy") { aspect <- median(sapply(dxdy, banking) * y.limits$slicelen / x.limits$slicelen, na.rm = TRUE) ### old aspect calculation ## aspect <- median(unlist(lapply(dxdy, banking)), ## na.rm = TRUE) * y.limits$slicelen / ## x.limits$slicelen ## if (y.relation == "free" || x.relation == "free") ## warning("'aspect=xy' when 'relation=free' is not sensible") } else if (aspect == "iso") { aspect <- median(y.limits$slicelen / x.limits$slicelen, na.rm = TRUE) if (y.relation == "free" || x.relation == "free") warning("'aspect=\"iso\"' approximate since 'relation=\"free\"'") } else aspect <- 1 } list(x.limits = x.limits$limits, y.limits = y.limits$limits, x.used.at = x.limits$used.at, y.used.at = y.limits$used.at, x.num.limit = x.limits$numlimitlist, y.num.limit = y.limits$numlimitlist, aspect.ratio = aspect, prepanel.default = prepanel.default, prepanel = prepanel) } hexbin/R/hexbin.s4.R0000644000176200001440000002700713562344315013671 0ustar liggesusers## namespace *internal* function: addBit <- function(bnds, f = 0.05) bnds + c(-f, f) * diff(bnds) hexbin <- function(x, y = NULL, xbins = 30, shape = 1, xbnds = range(x), ybnds = range(y), xlab = NULL, ylab = NULL, IDs = FALSE) { call <- match.call() ## (x,y, xlab, ylab) dealing xl <- if (!missing(x)) deparse(substitute(x)) yl <- if (!missing(y)) deparse(substitute(y)) xy <- xy.coords(x, y, xl, yl) ch0 <- function(u) if(is.null(u)) "" else u xlab <- if (is.null(xlab)) ch0(xy$xlab) else xlab ylab <- if (is.null(ylab)) ch0(xy$ylab) else ylab if(! (is.character(xlab) || is.expression(xlab))) stop("xlab must be a character or expression") if(! (is.character(ylab) || is.expression(ylab))) stop("ylab must be a character or expression") x <- xy$x y <- xy$y n <- length(x) na <- is.na(x) | is.na(y) has.na <- any(na) if (has.na) { ok <- !na x <- x[ok] y <- y[ok] n0 <- n na.pos <- which(na) n <- length(x) } if(diff(xbnds) <= 0) stop("xbnds[1] < xbnds[2] is not fulfilled") if(!missing(xbnds) && any(sign(xbnds - range(x)) == c(1,-1))) stop("'xbnds' must encompass range(x)") if(diff(ybnds) <= 0) stop("ybnds[1] < ybnds[2] is not fulfilled") if(!missing(ybnds) && any(sign(ybnds - range(y)) == c(1,-1))) stop("'ybnds' must encompass range(y)") jmax <- floor(xbins + 1.5001) #imax <- 2 * floor((xbins * shape)/sqrt(3) + 1.5001) c1 <- 2 * floor((xbins *shape)/sqrt(3) + 1.5001) imax <- trunc((jmax*c1 -1)/jmax + 1) lmax <- jmax * imax ans <- .Fortran("hbin", x = as.double(x), y = as.double(y), cell = integer(lmax), cnt = integer(lmax), xcm = double(lmax), ycm = double(lmax), xbins = as.double(xbins), shape = as.double(shape), xbnds = as.double(xbnds), ybnds = as.double(ybnds), dim = as.integer(c(imax, jmax)), n = as.integer(n), cID = if(IDs) integer(n) else as.integer(-1))[-(1:2)] ## cut off extraneous stuff if(!IDs) ans$cID <- NULL if(IDs && has.na) { ok <- as.integer(ok) ok[!na] <- ans$cID ok[na] <- NA ans$cID <- ok } nc <- ans$n length(ans$cell) <- nc length(ans$cnt) <- nc length(ans$xcm) <- nc length(ans$ycm) <- nc if(sum(ans$cnt) != n) warning("Lost counts in binning") new("hexbin", cell = ans$cell, count = ans$cnt, xcm = ans$xcm, ycm = ans$ycm, xbins = ans$xbins, shape = ans$shape, xbnds = ans$xbnds , ybnds = ans$ybnds, dimen = c(imax, jmax), n = n, ncells = ans$n, call = call, xlab = xlab, ylab = ylab, cID = ans$cID, cAtt = integer(0)) #dimen = ans$dim }## hexbin setClassUnion("integer or NULL",# < virtual class, used in 'cID' slot members = c("integer","NULL")) ## MM: I've learned that we should think twice before defining such ## "or NULL" classes: ## setClassUnion("vector or NULL",# < virtual class, used in 'cAtt' slot ## members = c("vector","NULL")) setClass("hexbin", representation(cell = "integer", count = "numeric",##count = "integer", xcm = "numeric", ycm = "numeric", xbins = "numeric", shape = "numeric", xbnds = "numeric", ybnds = "numeric", dimen = "numeric", n = "integer", ncells = "integer", call = "call", xlab = "vector", ylab = "vector", #xlab = "character", ylab = "character", cID = "integer or NULL", cAtt = "vector")## "or NULL" ) #setIs("hexbin", function(hbin) class(hbin)=="hexbin") ## FIXME: add 'validity checking method! setGeneric("hcell2xy", function(hbin, check.erosion = TRUE) standardGeneric("hcell2xy")) setMethod("hcell2xy", "hexbin", function(hbin, check.erosion = TRUE) { xbins <- hbin@xbins xbnds <- hbin@xbnds c3 <- diff(xbnds)/xbins ybnds <- hbin@ybnds c4 <- (diff(ybnds) * sqrt(3))/(2 * hbin@shape * xbins) jmax <- hbin@dimen[2] cell <- hbin@cell - 1 i <- cell %/% jmax j <- cell %% jmax y <- c4 * i + ybnds[1] x <- c3 * ifelse(i %% 2 == 0, j, j + 0.5) + xbnds[1] if(check.erosion && inherits(hbin,"erodebin")) list(x = x[hbin@eroded], y = y[hbin@eroded]) else list(x = x, y = y) }) setGeneric("getHexDxy", function(hbin) standardGeneric("getHexDxy")) setMethod("getHexDxy", "hexbin", function(hbin){ sx <- hbin@xbins/diff(hbin@xbnds) sy <- (hbin@xbins * hbin@shape)/diff(hbin@ybnds) list(dx=.5/sx, dy=(1/sqrt(3))/(2*sy)) }) setClass("erodebin", representation("hexbin", eroded = "logical", cdfcut = "numeric", erode = "integer")) setGeneric("erode", function(hbin, cdfcut = 0.5) standardGeneric("erode")) ## currently define the 'hexbin' method (also) as standalone function: erode.hexbin <- function(hbin, cdfcut = 0.5) { if(!is(hbin,"hexbin")) stop("first argument must be a hexbin object") #bin.att <- attributes(hbin) cell <- hbin@cell cnt <- hbin@count tmp <- sort(cnt) cdf <- cumsum(tmp)/sum(cnt) good <- cdfcut <= cdf if(!any(good)) return("no cells selected") crit <- min(tmp[good]) good <- crit <= cnt cell <- cell[good] cnt <- cnt[good] #hbin@cell <- cell #hbin@count <- cnt n <- length(cell) bdim <- hbin@dimen L <- bdim[1] * bdim[2] ans <- .Fortran("herode", cell = as.integer(cell), cnt = as.integer(cnt), n = n, bdim = as.integer(bdim), erode = integer(L), ncnt = integer(L), ncell = integer(L), sides = integer(L), neib = integer(6 * L), exist = logical(L + 1)) $ erode length(ans) <- n ehbin <- new("erodebin", hbin, cdfcut = cdfcut, eroded = good, erode = ans) #hbin@erode <- ans #class(hbin) <- c(class(hbin),"erodebin") ehbin } setMethod("erode", "hexbin", erode.hexbin) setGeneric("getHMedian", function(ebin) standardGeneric("getHMedian")) setMethod("getHMedian", "erodebin", function(ebin) { xy <- hcell2xy(ebin) stopifnot(1 == length(med <- which.max(ebin@erode))) med.x <- xy$x[med] med.y <- xy$y[med] list(x = med.x, y = med.y) }) ## Still define the 'hexbin' plot method (also) as standalone function: ## This is deprecated! gplot.hexbin <- function(x, style = "colorscale", legend = 1.2, lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 1, maxcnt = max(x@count), trans = NULL, inv = NULL, colorcut = seq(0, 1, length = min(17, maxcnt)), border = NULL, density = NULL, pen = NULL, colramp = function(n) LinGray(n, beg = 90, end = 15), xlab = NULL, ylab = NULL, main = "", newpage = TRUE, type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"), clip="on", verbose = getOption("verbose")) { if(!is(x,"hexbin")) stop("first argument must be a hexbin object") if(minarea < 0) stop("Minimum area must be non-negative") if(maxarea > 1) warning("Maximum area should be <= 1 this leads to overlapping hexagons") if(minarea > maxarea) stop("Minarea must be <= maxarea") if (length(colorcut) > 1) { # a sequence 0,...,1 if(colorcut[1] != 0) stop("Colorcut lower boundary must be 0") if(colorcut[length(colorcut)] != 1) stop("Colorcut upper boundary must be 1") } else { colorcut <- if(colorcut > 1) seq(0, 1, length = min(c(17, colorcut, maxcnt))) else 1 } if(is.logical(legend)) { if(legend) stop("Give the legend width") else legend <- 0 } else stopifnot(is.numeric(legend) && length(legend) == 1) type <- match.arg(type) xaxt <- match.arg(xaxt) yaxt <- match.arg(yaxt) ## ----- plotting starts ------------------------ if (newpage) grid.newpage() hv.ob <- hexViewport(x, xbnds=x@xbnds, ybnds=x@ybnds, offset = unit(legend,"inches")) pushViewport(hv.ob@hexVp.off) grid.rect() if(xaxt != "n") grid.xaxis() if(yaxt != "n") grid.yaxis() ## xlab, ylab, main : if(is.null(xlab)) xlab <- x@xlab if(is.null(ylab)) ylab <- x@ylab if(nchar(xlab) > 0) grid.text(xlab, y = unit(-2, "lines"), gp = gpar(fontsize = 16)) if(nchar(ylab) > 0) grid.text(ylab, x = unit(-2, "lines"), gp = gpar(fontsize = 16), rot = 90) if(nchar(main) > 0) grid.text(main, y = unit(1, "npc") + unit(1.5, "lines"), gp = gpar(fontsize = 18)) if(type != "n") { if(clip == "on") { upViewport() pushViewport(hv.ob@hexVp.on) } grid.hexagons(x, style = style, minarea = minarea, maxarea = maxarea, mincnt = mincnt, maxcnt = maxcnt, check.erosion = FALSE, trans = trans, colorcut = colorcut, density = density, border = border, pen = pen, colramp = colramp, verbose = verbose) } upViewport()# plot #popViewport()# fig ## ----- Legend ------------------------ if(legend > 0) { if(!is.null(trans) && is.null(inv)) stop("Must supply the inverse transformation") if(verbose) cat("plot.hexbin( legend > 0): ... hex.legend()\n") inner <- getPlt(hv.ob, ret.unit = "inches", numeric = TRUE)[1]/x@xbins ##inner <- as.numeric(convertUnit(hv.ob@plt[1],"inches"))/x@xbins ##outer <- (inner * sqrt(3))/2 ##switch(style, ## lattice = , ## centroids = { ## if(length(colorcut) * outer > ysize - 1) { ## warning("Colorcut is being shortened") ## colorcut <- seq(0, 1, ## max(1, floor((ysize - 1)/outer))) ## } ## } ## ) ysize <- getPlt(hv.ob, ret.unit = "inches", numeric = TRUE)[2] #as.numeric(convertUnit(hv.ob@plt[2],"inches")) legVp <- viewport(x = unit(1,"npc") - convertX(unit(legend,"inches"), "npc"), #y = convertY(unit(mai[1],"inches"),"npc"), y = hv.ob@mar[1], #height = unit(1,"npc") - #convertY(unit(mai[3]+mai[1],"inches"),"npc"), height = unit(1,"npc")-(hv.ob@mar[1]+ hv.ob@mar[3]), width = convertUnit(unit(legend,"inches"),"npc"), default.units = "native", just = c("left","bottom"), xscale = c(0, legend), yscale = c(0, ysize)) if(type != "n") { pushViewport(legVp) grid.hexlegend(legend, ysize = ysize, lcex = lcex, inner = inner, style = style, minarea = minarea, maxarea = maxarea, mincnt = mincnt, maxcnt = maxcnt, trans = trans, inv = inv, colorcut = colorcut, density = density, border = border, pen = pen, colramp = colramp) upViewport() } } invisible(list(plot.vp = hv.ob, legend.vp = if(legend) legVp)) } ## gplot.hexbin() setMethod("plot", signature(x = "hexbin", y = "missing"), gplot.hexbin) setMethod("show", "hexbin", function(object) { cat("'hexbin' object from call:", deparse(object@call), "\n") dm <- object@dimen cat("n =", object@n, " points in nc =", object@ncells, " hexagon cells in grid dimensions ", dm[1], "by", dm[2],"\n") invisible(object) }) setMethod("summary", "hexbin", function(object, ...) { show(object, ...) print(summary(data.frame(cell = object@cell, count = object@count, xcm = object@xcm, ycm = object@ycm), ...)) if(!is.null(object@cID)) { cat("IDs: "); str(object@cID) } }) if(FALSE) { ##-- todo -- #setMethod("identify" identify.hexbin <- function(x, labels = x$cnt, offset = 0, ...) { if(length(labels) != x$n) stop("labels not the same length as number of cells") ##NL: Should this be a warning? ## -> typically default method: identify(hcell2xy(x), labels = labels, offset = offset, ...) } }#not yet hexbin/R/hdiffplot.R0000644000176200001440000003121513171627113014036 0ustar liggesusers ### FIXME: Need to check for bin erosion ### or fix hcell2xy so that it checks for bin erosion. ### --- Fixed hcell2xy, probably should do the same to other accessor functions ### NL get.xrange <- function(xy.lst, xbnds) { range(unlist(lapply(xy.lst, function(xy, bnd) xy$x[(xy$x < max(bnd)) & (xy$x > min(bnd))], xbnds))) } get.yrange <- function(xy.lst, ybnds) { range(unlist(lapply(xy.lst, function(xy, bnd) xy$y[(xy$y < max(bnd)) & (xy$y > min(bnd))], ybnds))) } make.bnds <- function(binlst, xy.lst, xbnds = NULL, ybnds = NULL) { if(inherits(binlst,"hexbinList")) binlst <- binlst@hbins if(is.null(xbnds)) xbnds <- binlst[[1]]@xbnds if(is.null(ybnds)) ybnds <- binlst[[1]]@ybnds nxbnds <- get.xrange(xy.lst, xbnds) nybnds <- get.yrange(xy.lst, ybnds) list(xbnds = xbnds, ybnds = ybnds, nxbnds = nxbnds, nybnds = nybnds) } all.intersect <- function(binlist) { ## This will not work if all the grids are not the same ## Will have to rethink this if we move to non-aligned ## hexagon bins. NL if(inherits(binlist,"hexbinList")) binlist <- binlist@hbins ans <- matrix(FALSE, nrow = binlist[[1]]@dimen[1]*binlist[[1]]@dimen[2], ncol = length(binlist)) for(i in 1:length(binlist)) { if(is(binlist[[i]], "erodebin")) ans[binlist[[i]]@cell[binlist[[i]]@eroded], i] <- TRUE else ans[binlist[[i]]@cell, i] <- TRUE } ans } ## colordist <- function() { ## } ## MM: FIXME : `` get(where) '' is a kludge! # EJP: outcomment, seems obsolete? #mixcolors <- function (alpha, color1, where = class(color1)) #{ # alpha <- as.numeric(alpha) # c1 <- coords(as(color1, where)) # na <- length(alpha) # n1 <- nrow(c1) # if(na == 1) # alpha <- rep(alpha, n1) # stopifnot(sum(alpha) == 1) # get(where)(t(apply(c1, 2, function(cols, alpha) alpha%*%cols, alpha))) # #} mixcolors2 <- function (colors, alpha, where="hsv") { # colors: an n x 3 matrix of colors # alpha: an n x 1 vector of color mixing coefficents # sum(alpha)==1 should be a restriction? # where: the color space to mix in (not implemented yet) # The reurn value is a single hex color forming the mixture # This function is purely linear mixing, nolinear mixing # would be quite interesting since the colorspaces are not really # linear, ie mixing alonga manifold in LUV space. alpha <- as.numeric(alpha) na <- length(alpha) n1 <- nrow(colors) if (n1 < 2) { warning("need more than two colors to mix") colors } if(na == 1) alpha <- rep(alpha, n1) stopifnot(abs(sum(alpha)-1) <= 0.01) #colors <- convertColor(colors,from="sRGB",to="Lab",scale.in=1) mix <- t(apply(colors, 2, function(cols, alpha) alpha%*%cols, alpha)) #convertColor(mix,from="hsv",to="hex",scale.out=1,clip=TRUE) hsv(mix[1],mix[2],mix[3]) } hdiffplot <- function(bin1, bin2 = NULL, xbnds = NULL, ybnds = NULL, focus = NULL, col.control = list(medhex = "white", med.bord = "black", focus = NULL, focus.border = NULL, back.col = "grey"), arrows = TRUE, size = unit(0.1, "inches"), lwd = 2, eps = 1e-6, unzoom = 1.08, clip ="off", xlab = "", ylab = "", main = deparse(mycall), ...) { ## Arguments: ## bin1 : hexagon bin object or a list of bin objects ## bin2 : hexagon bin object or NULL ## bin objects must have the same plotting bounds and shape ## border : plot the border of the hexagon, use TRUE for ## hexagon graph paper ## Having all the same parameters ensures that all hexbin ## objects have the same hexagon grid, and there will be no ## problems intersecting them. When we have a suitable solution to ## the hexagon interpolation/intersection problem this will be relaxed. fixx <- xbnds fixy <- ybnds if(!inherits(bin1,"hexbinList")){ if(is.null(bin2) & is.list(bin1)) { bin1 <- as(bin1,"hexbinList") } else if(is.null(bin2) & (!is.list(bin1))) stop(" need at least 2 hex bin objects, or a hexbinList") else { if(bin1@shape != bin2@shape) stop("bin objects must have same shape parameter") if(all(bin1@xbnds == bin2@xbnds) & all(bin1@ybnds == bin2@ybnds)) equal.bounds <- TRUE else stop("Bin objects need the same xbnds and ybnds") if(bin1@xbins != bin2@xbins) stop("Bin objects need the same number of bins") nhb <- 2 ## Need to make a binlist class, then can do as(bin1, bin2, "binlist") ## or something similar (NL) bin1 <- list(bin1 = bin1, bin2 = bin2) bin1 <- as(bin1,"hexbinList") } } mycall <- sys.call() if(length(mycall) >= 4) { mycall[4] <- as.call(quote(.....())) if(length(mycall) > 4) mycall <- mycall[1:4] } if(is.null(focus)) focus <- 1:bin1@n ##_______________ Collect computing constants______________ tmph.xy <- lapply(bin1@hbins, hcell2xy, check.erosion = TRUE) ## Check for erode bins eroded <- unlist(lapply(bin1@hbins, is, "erodebin")) shape <- bin1@Shape xbins <- bin1@Xbins bnds <- make.bnds(bin1@hbins, tmph.xy, xbnds = fixx, ybnds = fixy) ratiox <- diff(bnds$nxbnds)/diff(bnds$xbnds) ratioy <- diff(bnds$nybnds)/diff(bnds$ybnds) ratio <- max(ratioy, ratiox) nxbnds <- mean(bnds$nxbnds) + c(-1, 1)*(unzoom * ratio * diff(bnds$xbnds))/2 nybnds <- mean(bnds$nybnds) + c(-1, 1)*(unzoom * ratio * diff(bnds$ybnds))/2 ##__________________ Construct plot region___________________ hvp <- hexViewport(bin1@hbins[[1]], xbnds = nxbnds, ybnds = nybnds, newpage = TRUE) pushHexport(hvp) grid.rect() grid.xaxis() grid.yaxis() if(nchar(xlab) > 0) grid.text(xlab, y = unit(-2, "lines"), gp = gpar(fontsize = 16)) if(nchar(ylab) > 0) grid.text(ylab, x = unit(-2, "lines"), gp = gpar(fontsize = 16), rot = 90) if(sum(nchar(main)) > 0) grid.text(main, y = unit(1, "npc") + unit(1.5, "lines"), gp = gpar(fontsize = 18)) if(clip=='on'){ popViewport() pushHexport(hvp,clip="on") } ##__________________ Construct hexagon___________________ dx <- (0.5 * diff(bin1@Xbnds))/xbins dy <- (0.5 * diff(bin1@Ybnds))/(xbins * shape * sqrt(3)) hexC <- hexcoords(dx = dx, dy = dy) ##__________________ Set up intersections and colors___________________ if(length(focus) < bin1@n) { bin1@hbins <- c(bin1@hbins[focus], bin1@hbins[-focus]) bin1@Bnames <- c(bin1@Bnames[focus], bin1@Bnames[-focus]) } cell.stat <- all.intersect(bin1@hbins) cell.stat.n <- apply(cell.stat, 1, sum) i.depth <- max(cell.stat.n) ### I will do this as a recursive function once I get ### The colors worked out! In fact for more than three ### bin objects there is no other way to do this but recursively!!! ### NL. -- Well this solution is like recursion :) diff.cols <- vector(mode = "list", length = i.depth) levcells <- which(cell.stat.n == 1) whichbin <- apply(cell.stat[levcells, ], 1, which) ## Set all the focal colors for the unique bin cells ## if not specified make them equally spaced on the color wheel ## with high saturation and set the background bins to gray nfcol <- length(focus) nhb <- bin1@n nbcol <- nhb-nfcol fills <- if(is.null(col.control$focus)) { if(nbcol > 0) matrix(c(seq(0, 360, length = nfcol+1)[1:nfcol]/360, rep(0, nbcol), rep(1, nfcol), rep(0, nbcol),rep(1, nfcol), rep(.9, nbcol)), ncol = 3) ## V = c(rep(1, nfcol), seq(.9, .1, length=nbcol)) else #matrix(c(seq(0, 360, length = nhb+1), s=1, v=1)[1:nfcol] matrix(c(seq(0, 360, length = nhb+1)/360, rep(1,nhb+1), rep(1,nhb+1)), ncol = 3)[1:nhb,] } else { foc.col <- t(rgb2hsv(col2rgb(col.control$focus))) if(nbcol > 0) { bcol <- matrix(c(rep(0, 2*nbcol), rep(.9, nbcol)), ncol = 3) rbind(foc.col, bcol) } else foc.col } colnames(fills) <- c("h","s","v") diff.cols[[1]] <- list(fill = fills, border = gray(.8)) ##_______________ Full Cell Plotting for Unique Bin1 Cells_________________ if(length(levcells) > 0) { for(i in unique(whichbin)) { pcells <- if(eroded[i]) bin1@hbins[[i]]@cell[bin1@hbins[[i]]@eroded] else bin1@hbins[[i]]@cell pcells <- which(pcells %in% levcells[whichbin == i]) pfill <- diff.cols[[1]]$fill[i,] pfill <- hsv(pfill[1],pfill[2],pfill[3]) hexpolygon(x = tmph.xy[[i]]$x[pcells], y = tmph.xy[[i]]$y[pcells], hexC, border = diff.cols[[1]]$border , fill = pfill) } } ## Now do the intersections. All intersections are convex ## combinations of the colors of the overlapping unique bins in ## the CIEluv colorspace. so if the binlist is of length 2 and ## the focal hbins are "blue" and "yellow" respectively the ## intersection would be green. First I need to get this to work ## and then I can think about how to override this with an option ## in color.control. -NL if(i.depth > 1) { for(dl in 2:(i.depth)) { levcells <- which(cell.stat.n == dl) if(length(levcells) == 0) next whichbin <- apply(cell.stat[levcells, ], 1, function(x) paste(which(x), sep = "", collapse = ":")) inter.nm <- unique(whichbin) #fills <- matrix(0, length(inter.nm), 3) fills <- rep(hsv(1), length(inter.nm)) i <- 1 for(bn in inter.nm) { who <- as.integer(unlist(strsplit(bn, ":"))) fills[i] <- mixcolors2(diff.cols[[1]]$fill[who,], 1/length(who),where = "LUV") i <- i+1 } #fills <- LUV(fills) diff.cols[[dl]] <- list(fill = fills, border = gray((i.depth-dl)/i.depth)) ##____Full Cell Plotting for Intersecting Cells at Intersection Depth i____ i <- 1 for(ints in inter.nm) { bin.i <- as.integer(unlist(strsplit(ints, ":"))[1]) pcells <- if(eroded[bin.i]) bin1@hbins[[bin.i]]@cell[bin1@hbins[[bin.i]]@eroded] else bin1@hbins[[bin.i]]@cell pcells <- which(pcells %in% levcells[whichbin == ints]) hexpolygon(x = tmph.xy[[bin.i]]$x[pcells], y = tmph.xy[[bin.i]]$y[pcells], hexC, border = diff.cols[[dl]]$border , fill = diff.cols[[dl]]$fill[i] ) i <- i+1 } } } ##_____________________________Plot Median Cells___________________________ ## With all these colors floating around I think it would be worth ## porting the 3d hexagon stuff to grid. Then it would be easier ## to distinguish the medians because they would stand out like ## little volcanoes :) NL if(any(eroded)) { hmeds <- matrix(unlist(lapply(bin1@hbins[eroded], function(x) unlist(getHMedian(x)))), ncol = 2, byrow = TRUE) hexpolygon(x = hmeds[, 1], y = hmeds[, 2], hexC, border = col.control$med.b, fill = col.control$medhex) if(arrows) { for(i in focus) { for(j in focus[focus < i]) { if(abs(hmeds[i, 1] - hmeds[j, 1]) + abs(hmeds[i, 2] - hmeds[j, 2]) > eps) grid.lines(c(hmeds[i, 1],hmeds[j, 1]), c(hmeds[i, 2], hmeds[j, 2]), default.units = "native", arrow=arrow(length=size)) #grid.arrows(c(hmeds[i, 1], hmeds[j, 1]), # c(hmeds[i, 2], hmeds[j, 2]), # default.units = "native", # length = size, gp = gpar(lwd = lwd)) } } } } ##________________Clean Up_______________________________________________ popViewport() invisible(hvp) } ## hdiffplot() hexbin/R/hbox.R0000644000176200001440000000517013171627113013020 0ustar liggesusershboxplot <- function(bin, xbnds = NULL, ybnds = NULL, density, border = c(0,grey(.7)), pen = c(2, 3), unzoom = 1.1, clip="off", reshape = FALSE, xlab = NULL, ylab = NULL, main = "") { ##_______________ Collect computing constants______________ if(!is(bin,"hexbin")) stop("first argument must be a hexbin object") h.xy <- hcell2xy(bin,check.erosion=TRUE) ##___zoom in scaling with expanding to avoid hexagons outside plot frame___ if(is(bin,"erodebin")) { h.xy$x <- h.xy$x h.xy$y <- h.xy$y nxbnds <- if(is.null(xbnds)) range(h.xy$x) else xbnds nybnds <- if(is.null(ybnds)) range(h.xy$y) else ybnds ratiox <- diff(nxbnds)/diff(bin@xbnds) ratioy <- diff(nybnds)/diff(bin@ybnds) ratio <- max(ratioy, ratiox) nxbnds <- mean(nxbnds) + c(-1,1)*(unzoom * ratio * diff(bin@xbnds))/2 nybnds <- mean(nybnds) + c(-1,1)*(unzoom * ratio * diff(bin@ybnds))/2 } else { nxbnds <- if(is.null(xbnds)) bin@xbnds else xbnds nybnds <- if(is.null(ybnds)) bin@ybnds else ybnds } margins <- unit(0.1 + c(5,4,4,3),"lines") plot.vp <- hexViewport(bin, xbnds = nxbnds, ybnds = nybnds, mar=margins, newpage = TRUE) pushHexport(plot.vp) grid.rect() grid.xaxis() grid.yaxis() ## xlab, ylab, main : if(is.null(xlab)) xlab <- bin@xlab if(is.null(ylab)) ylab <- bin@ylab if(nchar(xlab) > 0) grid.text(xlab, y = unit(-2, "lines"), gp= gpar(fontsize= 16)) if(nchar(ylab) > 0) grid.text(ylab, x = unit(-2, "lines"), gp= gpar(fontsize= 16), rot = 90) if(nchar(main) > 0) grid.text(main, y = unit(1, "npc") + unit(1.5, "lines"), gp = gpar(fontsize = 18)) if(clip=="on") { popViewport() pushHexport(plot.vp, clip="on") } cnt <- if(is(bin,"erodebin")) bin@count[bin@eroded] else bin@count xbins <- bin@xbins shape <- bin@shape xnew <- h.xy$x ynew <- h.xy$y ##__________________ Construct a hexagon___________________ dx <- (0.5 * diff(bin@xbnds))/xbins dy <- (0.5 * diff(bin@ybnds))/(xbins * shape * sqrt(3)) hexC <- hexcoords(dx, dy, sep = NULL) ##_______________ Full Cell Plotting_____________________ hexpolygon(xnew, ynew, hexC, density = density, fill = pen[2], border = border[2]) ##______________Plotting median___________________________ if(!is(bin,"erodebin")) { ## No warning here, allow non-erode above! warning("No erode component") } else { med <- which.max(bin@erode) xnew <- xnew[med] ynew <- ynew[med] hexpolygon(xnew, ynew, hexC, density = density, fill = pen[1], border = border[1]) } popViewport() invisible(plot.vp) }# hboxplot() hexbin/R/MAG.R0000644000176200001440000001437213171627113012470 0ustar liggesusersmagent <- function(n, beg = 1, end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(0, 0, 0), c( 40, 0, 0), c( 56, 0, 4), c( 61, 0, 9), c( 64, 0, 12), c( 66, 0, 14), c( 69, 0, 17), c( 73, 0, 20), c( 74, 0, 22), c( 78, 0, 25), c( 79, 0, 27), c( 83, 0, 30), c( 85, 0, 31), c( 86, 0, 33), c( 90, 0, 36), c( 91, 0, 38), c( 93, 0, 39), c( 95, 0, 41), c( 96, 0, 43), c(100, 0, 46), c(102, 0, 47), c(103, 0, 49), c(105, 0, 51), c(107, 0, 52), c(108, 0, 54), c(110, 0, 55), c(112, 0, 57), c(112, 0, 57), c(113, 0, 58), c(115, 0, 60), c(117, 0, 62), c(119, 0, 63), c(120, 0, 65), c(122, 0, 66), c(124, 0, 68), c(125, 0, 70), c(127, 0, 71), c(129, 0, 73), c(129, 0, 73), c(130, 0, 74), c(132, 0, 76), c(134, 0, 78), c(136, 0, 79), c(137, 0, 81), c(139, 0, 82), c(141, 0, 84), c(142, 0, 86), c(144, 0, 87), c(146, 0, 89), c(147, 0, 90), c(149, 0, 92), c(151, 0, 94), c(151, 0, 94), c(153, 0, 95), c(154, 0, 97), c(156, 0, 98), c(158, 0,100), c(159, 0,102), c(161, 0,103), c(163, 0,105), c(164, 0,106), c(166, 0,108), c(168, 0,109), c(170, 0,111), c(171, 0,113), c(173, 0,114), c(175, 0,116), c(176, 0,117), c(178, 0,119), c(180, 0,121), c(180, 0,121), c(181, 0,122), c(183, 0,124), c(185, 0,125), c(187, 0,127), c(188, 0,129), c(190, 0,130), c(192, 0,132), c(193, 0,133), c(195, 0,135), c(197, 0,137), c(198, 0,138), c(200, 0,140), c(202, 0,141), c(204, 0,143), c(204, 0,143), c(205, 0,145), c(207, 0,146), c(209, 0,148), c(210, 0,149), c(212, 0,151), c(214, 0,153), c(215, 0,154), c(217, 0,156), c(219, 0,157), c(221, 0,159), c(222, 0,160), c(222, 0,160), c(224, 0,162), c(226, 0,164), c(227, 0,165), c(229, 0,167), c(231, 0,168), c(232, 0,170), c(234, 0,172), c(236, 0,173), c(238, 0,175), c(238, 0,175), c(239, 0,176), c(241, 0,178), c(243, 0,180), c(244, 0,181), c(246, 0,183), c(248, 2,184), c(249, 4,186), c(249, 4,186), c(249, 4,186), c(251, 6,188), c(251, 6,188), c(253, 9,189), c(253, 9,189), c(255, 11,191), c(255, 11,191), c(255, 13,192), c(255, 13,192), c(255, 13,192), c(255, 16,194), c(255, 18,196), c(255, 20,197), c(255, 20,197), c(255, 23,199), c(255, 25,200), c(255, 27,202), c(255, 30,204), c(255, 32,205), c(255, 34,207), c(255, 37,208), c(255, 37,208), c(255, 39,210), c(255, 41,211), c(255, 44,213), c(255, 46,215), c(255, 48,216), c(255, 51,218), c(255, 53,219), c(255, 53,219), c(255, 55,221), c(255, 57,223), c(255, 60,224), c(255, 62,226), c(255, 64,227), c(255, 67,229), c(255, 67,229), c(255, 69,231), c(255, 71,232), c(255, 74,234), c(255, 76,235), c(255, 78,237), c(255, 81,239), c(255, 81,239), c(255, 83,240), c(255, 85,242), c(255, 88,243), c(255, 90,245), c(255, 92,247), c(255, 95,248), c(255, 95,248), c(255, 97,250), c(255, 99,251), c(255,102,253), c(255,104,255), c(255,106,255), c(255,106,255), c(255,108,255), c(255,111,255), c(255,113,255), c(255,115,255), c(255,115,255), c(255,118,255), c(255,120,255), c(255,122,255), c(255,122,255), c(255,125,255), c(255,127,255), c(255,129,255), c(255,129,255), c(255,132,255), c(255,134,255), c(255,136,255), c(255,136,255), c(255,139,255), c(255,141,255), c(255,143,255), c(255,143,255), c(255,146,255), c(255,148,255), c(255,150,255), c(255,150,255), c(255,153,255), c(255,155,255), c(255,155,255), c(255,157,255), c(255,159,255), c(255,159,255), c(255,162,255), c(255,164,255), c(255,164,255), c(255,166,255), c(255,169,255), c(255,171,255), c(255,171,255), c(255,173,255), c(255,176,255), c(255,176,255), c(255,178,255), c(255,180,255), c(255,180,255), c(255,183,255), c(255,185,255), c(255,185,255), c(255,187,255), c(255,190,255), c(255,190,255), c(255,192,255), c(255,194,255), c(255,197,255), c(255,197,255), c(255,199,255), c(255,201,255), c(255,204,255), c(255,204,255), c(255,206,255), c(255,208,255), c(255,210,255), c(255,210,255), c(255,213,255), c(255,215,255), c(255,217,255), c(255,217,255), c(255,220,255), c(255,222,255), c(255,224,255), c(255,227,255), c(255,229,255), c(255,229,255), c(255,231,255), c(255,234,255), c(255,236,255), c(255,238,255), c(255,241,255), c(255,243,255), c(255,243,255), c(255,245,255), c(255,248,255), c(255,250,255), c(255,255,255)) [ round(seq(beg,end,length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/hexbinplot.R0000644000176200001440000007317513171627113014246 0ustar liggesusers## lattice version of gplot.hexbin ## There are two major problems. (1) For comparability across panels, ## we want the same mincnt and maxcnt in all panels. However, a ## suitable default can really only be determined at printing time, ## since it would depend on the physical dimensions of the panel. (2) ## there is no proper way to communicate the mincnt and maxcnt to the ## legend. ## Tentative solution: the counts can be calculated once enough things ## are known, namely the aspect ratio, xbins and [xy]bnds. An ## important question then is whether [xy]bnds should be [xy]lim or ## range([xy]). Both should be allowed, since [xy]lim makes them ## comparable, range([xy]) potentially shows more detail. For ## relation != "same", both are more or less similar. An important ## observation is that with range([xy]), 'shape = aspect ratio of ## panel' does not guarantee symmetric hexagons, so shape has to be ## different for each panel. ## Only feasible approach I can think of is to produce the trellis ## object first (with known aspect, so aspect="fill" is absolutely ## no-no), then analyze the limits and relevant panel arguments to get ## 'maxcnt' (essentially doing a dry run of the panel calculations). ## This needs undocumented knowledge of the trellis object, which is ## kinda not good, but at least it gets the job done. Once we know ## maxcnt, we can also set up a suitable legend function. ## Unfortunately, this has the potential to screw up update calls that ## modify certain things. Is there any way to capture those? Maybe ## make a new class that inherits from "trellis". For now, we'll ## pretend that the problem doesn't exist. ## tool borrowed from lattice updateList <- function (x, val) { if (is.null(x)) x <- list() modifyList(x, val) } prepanel.hexbinplot <- function(x, y, type = character(0),...) { if('tmd'%in%type){ tmp <- x x <- (y + x)/sqrt(2) y <- (y - tmp)/sqrt(2) } ans <- list(xlim = range(x, finite = TRUE), ylim = range(y, finite = TRUE), dx = IQR(x,na.rm=TRUE), dy = IQR(y,na.rm=TRUE)) } panel.hexbinplot <- function(x, y, ..., groups = NULL) { if (is.null(groups)) panel.hexbin(x, y, ...) else panel.hexpose(x, y, ..., groups = groups) } panel.hexbin <- function(x, y, xbins = 30, xbnds = c("data", "panel"), # was: xbnds = c("panel", "data"), ybnds = c("data", "panel"), # was: ybnds = c("panel", "data"), ## special args .prelim = FALSE, .cpl = current.panel.limits(), .xlim = .cpl$xlim, .ylim = .cpl$ylim, .aspect.ratio = 1, # default useful with splom(, panel = panel.hexbin) type = character(0), ..., check.erosion = FALSE) { if ("tmd" %in% type) { tmp <- x x <- (y + x)/sqrt(2) y <- (y - tmp)/sqrt(2) } if (is.character(xbnds)) xbnds <- switch(match.arg(xbnds), panel = .xlim, data = range(x, finite = TRUE)) if (is.character(ybnds)) ybnds <- switch(match.arg(ybnds), panel = .ylim, data = range(y, finite = TRUE)) shape <- .aspect.ratio * (diff(ybnds) / diff(.ylim)) / (diff(xbnds) / diff(.xlim)) if (!missing(check.erosion)) warning("explicit 'check.erosion' specification ignored") h <- hexbin(x = x, y = y, xbins = xbins, shape = shape, xbnds = xbnds, ybnds = ybnds) if (.prelim) return(max(h@count)) ## have to do this because grid.hexagons croaks with unrecognized ## arguments: args <- list(dat = h, check.erosion = FALSE, ...) keep <- names(args) %in% names(formals(grid.hexagons)) if ('g' %in% type) panel.grid(h = -1, v = -1) if ('hg' %in% type) panel.hexgrid(h) do.call("grid.hexagons", args[keep]) if ("r" %in% type) panel.lmline(x, y, ...) if ("smooth" %in% type) panel.hexloess(h,...) invisible() } panel.hexboxplot <- function(x, y, xbins = 30, xbnds = c("data", "panel"), # was: xbnds = c("panel", "data"), ybnds = c("data", "panel"), # was: ybnds = c("panel", "data"), ## special args .prelim = FALSE, .cpl = current.panel.limits(), .xlim = .cpl$xlim, .ylim = .cpl$ylim, .aspect.ratio = 1, type = character(0), cdfcut=.25, shadow=.05, ..., check.erosion = TRUE) { if (is.character(xbnds)) xbnds <- switch(match.arg(xbnds), panel = .xlim, data = range(x, finite = TRUE)) if (is.character(ybnds)) ybnds <- switch(match.arg(ybnds), panel = .ylim, data = range(y, finite = TRUE)) shape <- .aspect.ratio * (diff(ybnds) / diff(.ylim)) / (diff(xbnds) / diff(.xlim)) if (!missing(check.erosion)) warning("explicit 'check.erosion' specification ignored") h <-hexbin(x = x, y = y, xbins = xbins, shape = shape, xbnds = xbnds, ybnds = ybnds,IDs=TRUE) if (.prelim) return(max(h@count)) ## have to do this because grid.hexagons croaks with unrecognized ## arguments: args <- list(dat = h, check.erosion = FALSE, ...) keep <- names(args) %in% names(formals(grid.hexagons)) if ('hg' %in% type) panel.hexgrid(h) if ('g' %in% type) panel.grid(h = -1, v = -1) if(shadow) { eh <- erode(h,cdfcut=shadow) h.xy <- hcell2xy(eh,check.erosion=TRUE) dx <- (0.5 * diff(eh@xbnds))/eh@xbins dy <- (0.5 * diff(eh@ybnds))/(eh@xbins * h@shape * sqrt(3)) hexC <- hexcoords(dx, dy, sep = NULL) hexpolygon(h.xy$x,h.xy$y, hexC, density = density, fill = NA, border = gray(.75)) } eh <- erode(h,cdfcut=cdfcut) h.xy <- hcell2xy(eh,check.erosion=TRUE) dx <- (0.5 * diff(eh@xbnds))/eh@xbins dy <- (0.5 * diff(eh@ybnds))/(eh@xbins * h@shape * sqrt(3)) hexC <- hexcoords(dx, dy, sep = NULL) hexpolygon(h.xy$x,h.xy$y, hexC, density = density, fill = "green", border = gray(.75)) med <- which.max(eh@erode) xnew <- h.xy$x[med] ynew <- h.xy$y[med] hexpolygon(xnew, ynew, hexC, density = density, fill = "red", border =gray(.25)) invisible() } panel.hexpose <- function(x, y, groups, subscripts, xbins = 30, xbnds = c("data", "panel"), # was: xbnds = c("panel", "data"), ybnds = c("data", "panel"), # was: ybnds = c("panel", "data"), ## special args .prelim = FALSE, .cpl = current.panel.limits(), .xlim = .cpl$xlim, .ylim = .cpl$ylim, .aspect.ratio = 1, #erode Args cdfcut=.05, #hdiff Args hexpose.focus=c(1,2), hexpose.focus.colors=c("yellow","blue"), hexpose.focus.border=c("cyan","orange"), hexpose.median.color="red", hexpose.median.border="black", arrows = TRUE, size = unit(0.1, "inches"), arrow.lwd = 2, eps = 1e-6, type = character(0), ..., check.erosion = TRUE) { if (is.character(xbnds)) xbnds <- switch(match.arg(xbnds), panel = .xlim, data = range(x, finite = TRUE)) if (is.character(ybnds)) ybnds <- switch(match.arg(ybnds), panel = .ylim, data = range(y, finite = TRUE)) shape <- .aspect.ratio * (diff(ybnds) / diff(.ylim)) / (diff(xbnds) / diff(.xlim)) if (is.numeric(groups)) groups <- as.character(groups[subscripts]) else groups <- groups[subscripts] binL <- hexList(x, y, given=groups, xbins=xbins, shape=shape, xbnds=xbnds, ybnds=ybnds) if ('hs' %in% type) lapply(binL@hbins,smooth.hexbin) binL@hbins <- lapply(binL@hbins,erode,cdfcut=cdfcut) if ('hg' %in% type) panel.hexgrid(binL@hbins[[1]]) ## ??? if ('g' %in% type) panel.grid(h = -1, v = -1) eroded <- unlist(lapply(binL@hbins, is, "erodebin")) tmph.xy <- lapply(binL@hbins, hcell2xy, check.erosion = TRUE) ##__________________ Construct hexagon___________________ dx <- (0.5 * diff(binL@Xbnds))/xbins dy <- (0.5 * diff(binL@Ybnds))/(xbins * binL@Shape * sqrt(3)) hexC <- hexcoords(dx = dx, dy = dy) ##__________________ Set up intersections and colors___________________ ## Reorder so that the focus bin objects are at the top of the list if(length(hexpose.focus) < binL@n) { binL@hbins <- c(binL@hbins[hexpose.focus], binL@hbins[-hexpose.focus]) binL@Bnames <- c(binL@Bnames[hexpose.focus], binL@Bnames[-hexpose.focus]) } cell.stat <- all.intersect(binL@hbins) cell.stat.n <- apply(cell.stat, 1, sum) i.depth <- max(cell.stat.n) diff.cols <- vector(mode = "list", length = i.depth) levcells <- which(cell.stat.n == 1) whichbin <- apply(cell.stat[levcells, ], 1, which) ## Set all the focal colors for the unique bin cells ## if not specified make them equally spaced on the color wheel ## with high saturation and set the background bins to gray nfcol <- length(hexpose.focus) nhb <- binL@n nbcol <- nhb-nfcol fills <- if(is.null(hexpose.focus.colors)) { if(nbcol > 0) hsv(h = c(seq(0, 1, length = nfcol+1)[1:nfcol],rep(0, nbcol)), s = c(rep(1, nfcol), rep(0, nbcol)), ## V = c(rep(1, nfcol), seq(.9, .1, length=nbcol)) v = c(rep(1, nfcol), rep(.9, nbcol))) else hsv(h=seq(0, 1, length = nhb+1))[1:nfcol] } else { foc.col <- t(col2rgb(hexpose.focus.colors))/255 if(nbcol > 0) { bcol <- t(col2rgb(rep(grey(.6),nbcol)))/255 rbind(foc.col, bcol) } else foc.col } diff.cols[[1]] <- list(fill = fills, border = gray(.8)) ##_______________ Full Cell Plotting for Unique BinL Cells_________________ if(length(levcells) > 0) { for(i in unique(whichbin)) { pcells <- if(eroded[i]) binL@hbins[[i]]@cell[binL@hbins[[i]]@eroded] else binL@hbins[[i]]@cell pcells <- which(pcells %in% levcells[whichbin == i]) hexpolygon(x = tmph.xy[[i]]$x[pcells], y = tmph.xy[[i]]$y[pcells], hexC, border = hexpose.focus.border[i] , fill = hexpose.focus.colors[i] ) } } ## Now do the intersections. All intersections are convex ## combinations of the colors of the overlapping unique bins in ## the CIEluv colorspace. so if the binlist is of length 2 and ## the focal hbins are "blue" and "yellow" respectively the ## intersection would be green. First I need to get this to work ## and then I can think about how to override this with an option ## in color.control. -NL if(i.depth > 1) { for(dl in 2:(i.depth)) { levcells <- which(cell.stat.n == dl) if(length(levcells) == 0) next whichbin <- apply(cell.stat[levcells, ], 1, function(x)paste(which(x), sep = "", collapse = ":")) inter.nm <- unique(whichbin) fills <- matrix(0, length(inter.nm), 3) i <- 1 for(bn in inter.nm) { who <- as.integer(unlist(strsplit(bn, ":"))) ## FIXME (DS): this doesn't work fills[i, ] <- mixcolors2(1/length(who), diff.cols[[1]]$fill[who,]) i <- i+1 } fills <- rgb(fills[,1],fills[,2],fills[,3]) diff.cols[[dl]] <- list(fill = fills, border = gray((i.depth-dl)/i.depth)) ##____Full Cell Plotting for Intersecting Cells at Intersection Depth i____ i <- 1 for(ints in inter.nm) { bin.i <- as.integer(unlist(strsplit(ints, ":"))[1]) pcells <- if(eroded[bin.i]) binL@hbins[[bin.i]]@cell[binL@hbins[[bin.i]]@eroded] else binL@hbins[[bin.i]]@cell pcells <- which(pcells %in% levcells[whichbin == ints]) hexpolygon(x = tmph.xy[[bin.i]]$x[pcells], y = tmph.xy[[bin.i]]$y[pcells], hexC, border = diff.cols[[dl]]$border , fill = diff.cols[[dl]]$fill[i] ) i <- i+1 } } } if(any(eroded)) { hmeds <- matrix(unlist(lapply(binL@hbins[eroded], function(x)unlist(getHMedian(x)))), ncol = 2, byrow = TRUE) hexpolygon(x = hmeds[, 1], y = hmeds[, 2], hexC, border = hexpose.median.border, fill = hexpose.median.color) if(arrows) { for(i in hexpose.focus) { for(j in hexpose.focus[hexpose.focus < i]) { if(abs(hmeds[i, 1] - hmeds[j, 1]) + abs(hmeds[i, 2] - hmeds[j, 2]) > eps) grid.arrows(c(hmeds[i, 1], hmeds[j, 1]), c(hmeds[i, 2], hmeds[j, 2]), default.units = "native", length = size, gp = gpar(lwd = arrow.lwd)) } } } } invisible() } hexbinplot <- function(x, data, ...) UseMethod("hexbinplot") hexbinplot.formula <- function(x, data = NULL, prepanel = prepanel.hexbinplot, panel = panel.hexbinplot, groups = NULL, aspect = "xy", trans = NULL, inv = NULL, colorkey = TRUE, ..., maxcnt, legend = NULL, legend.width = TRUE, subset = TRUE) { ocall <- sys.call(sys.parent()) ocall[[1]] <- quote(hexbinplot) ccall <- match.call() if (is.logical(legend.width)) legend.width <- 1.2 * as.numeric(legend.width) if (is.character(aspect) && aspect == "fill") stop("aspect = 'fill' not permitted") if (!is.null(trans) && is.null(inv)) stop("Must supply the inverse transformation 'inv'") ccall$data <- data ccall$prepanel <- prepanel ccall$panel <- panel ccall$aspect <- aspect ccall$trans <- trans ccall$inv <- inv ccall$legend <- legend ccall[[1]] <- quote(lattice::xyplot) ans <- eval(ccall, parent.frame()) ## panel needs to know aspect ratio to calculate shape ans <- update(ans, .aspect.ratio = ans$aspect.ratio) ## also need maxcnt, o.w. can't draw legend, panels not comparable ## either if (missing(maxcnt)) maxcnt <- max(mapply(panel.hexbinplot, ## note: not 'panel' x = lapply(ans$panel.args, "[[", "x"), y = lapply(ans$panel.args, "[[", "y"), .xlim = if (is.list(ans$x.limits)) ans$x.limits else rep(list(ans$x.limits), length(ans$panel.args)), .ylim = if (is.list(ans$y.limits)) ans$y.limits else rep(list(ans$y.limits), length(ans$panel.args)), MoreArgs = c(ans$panel.args.common, list(.prelim = TRUE, .cpl = NA)))) ans <- update(ans, maxcnt = maxcnt) if (colorkey) ans <- update(ans, legend = updateList(ans$legend, list(right = list(fun = hexlegendGrob, args = list(maxcnt = maxcnt, trans = trans, inv = inv, legend = legend.width, ...))))) ans$call <- ocall ans } old.hexbinplot.formula <- function(x, data = parent.frame(), prepanel = prepanel.hexbinplot, panel = if (is.null(groups)) panel.hexbinplot else panel.hexpose, groups=NULL, aspect = "xy", trans = NULL, inv = NULL, colorkey = TRUE, ..., maxcnt, legend = NULL, legend.width = TRUE) { if (is.logical(legend.width)) legend.width <- 1.2 * as.numeric(legend.width) if (is.character(aspect) && aspect == "fill") stop("aspect = 'fill' not permitted") if (!is.null(trans) && is.null(inv)) stop("Must supply the inverse transformation 'inv'") groups <- eval(substitute(groups), data, parent.frame()) ## There must be a better way to handle this, ugh. ans <- if(is.null(groups)) { xyplot(x, data = data, prepanel = prepanel, panel = panel, aspect = aspect, trans = trans, inv = inv, legend = legend, ...) } else { xyplot(x, data = data, prepanel = prepanel, panel = panel, groups=groups, aspect = aspect, trans = trans, inv = inv, legend = legend, ...) } ## panel needs to know aspect ratio to calculate shape ans <- update(ans, .aspect.ratio = ans$aspect.ratio) ## also need maxcnt, o.w. can't draw legend, panels not comparable ## either if (missing(maxcnt)) maxcnt <- max(mapply(panel.hexbinplot, ## note: not 'panel' x = lapply(ans$panel.args, "[[", "x"), y = lapply(ans$panel.args, "[[", "y"), .xlim = if (is.list(ans$x.limits)) ans$x.limits else rep(list(ans$x.limits), length(ans$panel.args)), .ylim = if (is.list(ans$y.limits)) ans$y.limits else rep(list(ans$y.limits), length(ans$panel.args)), MoreArgs = c(ans$panel.args.common, list(.prelim = TRUE, .cpl = NA)))) ans <- update(ans, maxcnt = maxcnt) if (colorkey) ans <- update(ans, legend = updateList(ans$legend, list(right = list(fun = hexlegendGrob, args = list(maxcnt = maxcnt, trans = trans, inv = inv, legend = legend.width, ...))))) ans } ## want a grob instead of actual plotting hexlegendGrob <- function(legend = 1.2, inner = legend / 5, cex.labels = 1, cex.title = 1.2, style = "colorscale", minarea = 0.05, maxarea = 0.8, mincnt = 1, maxcnt, trans = NULL, inv = NULL, colorcut = seq(0, 1, length = 17), density = NULL, border = NULL, pen = NULL, colramp = function(n) { LinGray(n,beg = 90,end = 15) }, ..., vp = NULL, draw = FALSE) { ## the formal arg matching should happen style <- match.arg(style, eval(formals(grid.hexagons)[["style"]])) if (style %in% c("centroids", "lattice", "colorscale")) { ## _______________tranformations_______________________ if(is.null(trans)) { sc <- maxcnt - mincnt bnds <- round(mincnt + sc * colorcut) } else { if(!is.function(trans) && !is.function(inv)) stop("'trans' and 'inv' must both be functions if 'trans' is not NULL") con <- trans(mincnt) sc <- trans(maxcnt) - con bnds <- round(inv(con + sc * colorcut)) } } ## grob ans <- switch(style, "colorscale" = { n <- length(bnds) pen <- colramp(n-1) ## rectangles instead of polygons ## pol <- ## rectGrob(x = 0.5, y = 1:(n-1)/n, ## height = 1/n, ## default.units = "npc", ## gp = gpar(fill = pen, col = border)) hexxy <- hexcoords(dx = 1, n = 1)[c("x", "y")] maxxy <- max(abs(unlist(hexxy))) hexxy <- lapply(hexxy, function(x) 0.5 * x/ maxxy) pol <- polygonGrob(x = 0.5 + rep(hexxy$x, n-1), y = (rep(1:(n-1), each = 6) + hexxy$y) / n, id.lengths = rep(6, n-1), gp = gpar(fill = pen, col = border), default.units = "npc") txt <- textGrob(as.character(bnds), x = 0.5, y = (0:(n-1) + 0.5) / n, gp = gpar(cex = cex.labels), default.units = "npc") ttl <- textGrob("Counts", gp = gpar(cex = cex.title)) key.layout <- grid.layout(nrow = 2, ncol = 2, heights = unit(c(1.5, 1), c("grobheight", "grobheight"), data = list(ttl, txt)), widths = unit(c(1/n, 1), c("grobheight", "grobwidth"), data = list(pol, txt)), respect = TRUE) key.gf <- frameGrob(layout = key.layout, vp = vp) key.gf <- placeGrob(key.gf, ttl, row = 1, col = 1:2) key.gf <- placeGrob(key.gf, pol, row = 2, col = 1) key.gf <- placeGrob(key.gf, txt, row = 2, col = 2) key.gf }, "centroids" = , "lattice" = { warning("legend shows relative sizes") ## Note: it may not be impossible to get absolute ## sizes. The bigger problem is that when ## [xy]bnds="data", the sizes (for the same count) may ## not be the same across panels. IMO, that's a more ## useful feature than getting the absolute sizes ## right. radius <- sqrt(minarea + (maxarea - minarea) * colorcut) n <- length(radius) if(is.null(pen)) pen <- 1 if(is.null(border)) border <- pen hexxy <- hexcoords(dx = 1, n = 1)[c("x", "y")] maxxy <- max(abs(unlist(hexxy))) hexxy <- lapply(hexxy, function(x) 0.5 * x/ maxxy) pol <- polygonGrob(x = 0.5 + rep(radius, each = 6) * rep(hexxy$x, n), y = (rep(0.5 + 1:n, each = 6) + rep(radius, each = 6) * hexxy$y - 1) / n, id.lengths = rep(6, n), gp = gpar(fill = pen, col = border), default.units = "npc") txt <- textGrob(as.character(bnds), x = 0.5, y = (1:n - 0.5) / n, gp = gpar(cex = cex.labels), default.units = "npc") ttl <- textGrob("Counts", gp = gpar(cex = cex.title)) key.layout <- grid.layout(nrow = 2, ncol = 2, heights = unit(c(1.5, 1), c("grobheight", "grobheight"), data = list(ttl, txt)), widths = unit(c(1/n, 1), c("grobheight", "grobwidth"), data = list(pol, txt)), respect = TRUE) key.gf <- frameGrob(layout = key.layout, vp = vp) key.gf <- placeGrob(key.gf, ttl, row = 1, col = 1:2) key.gf <- placeGrob(key.gf, pol, row = 2, col = 1) key.gf <- placeGrob(key.gf, txt, row = 2, col = 2) key.gf }, "nested.lattice" = , "nested.centroids" = { dx <- inner/2 dy <- dx/sqrt(3) hexC <- hexcoords(dx, dy, n = 1, sep = NULL) ## _____________x scaling_____________________________ numb <- cut(floor(legend/inner), breaks = c(-1, 0, 2,4)) ## Note: In old code ## top breaks=c(-1,0,2,4,8), numb<- 5 and size=1:9 if (is.na(numb)) numb <- 4 switch(numb, { warning("not enough space for legend") return(textGrob("")) }, size <- 5, size <- c(1, 5, 9), size <- c(1, 3, 5, 7, 9)) xmax <- length(size) radius <- sqrt(minarea + (maxarea - minarea) * (size - 1)/9) txt <- as.character(size) ##___________________y scaling_____________________ lab <- c("Ones", "Tens", "Hundreds", "Thousands", "10 Thousands", "100 Thousands", "Millions", "10 Millions", "100 Millions", "Billions") power <- floor(log10(maxcnt)) + 1 yinc <- 16 * dy ysize <- yinc * power xmid <- 0 x <- inner * (1:xmax - (1 + xmax)/2) + xmid n <- length(x) tx <- rep.int(hexC$x, n) ty <- rep.int(hexC$y, n) six <- rep.int(6:6, n) ## y <- rep.int(3 * dy - yinc, xmax) y <- rep.int(3 * dy - 0.75 * yinc, xmax) if (is.null(pen)) { pen <- 1:power +1 pen <- cbind(pen, pen +10) } if (is.null(border)) border <- TRUE key.layout <- grid.layout(nrow = 1, ncol = 1, heights = unit(ysize, "inches"), widths = unit(legend, "inches"), respect = TRUE) key.gf <- frameGrob(layout = key.layout, vp = vp) ## for debugging ## key.gf <- ## placeGrob(key.gf, rectGrob(gp = gpar(fill = "transparent"))) n6 <- rep.int(6, n) for(i in 1:power) { y <- y + yinc key.gf <- placeGrob(key.gf, polygonGrob(x = unit(legend / 2 + rep.int(hexC$x, n) + rep.int(x, n6), "inches"), y = unit(rep.int(hexC$y, n) + rep.int(y, n6), "inches"), id.lengths = n6, gp = gpar(col = pen[i, 1], fill = if (border) 1 else pen[i, 1])), row = 1, col = 1) key.gf <- placeGrob(key.gf, polygonGrob(x = legend / 2 + tx * rep.int(radius, six) + rep.int(x, six), y = ty * rep.int(radius, six) + rep.int(y, six), default.units = "inches", id=NULL, id.lengths=rep(6,n), gp = gpar(fill = pen[i,2], col = border)), row = 1, col = 1) key.gf <- placeGrob(key.gf, textGrob(txt, x = legend / 2 + x, y = y - 4.5 * dy, default.units = "inches", gp = gpar(cex = cex.labels)), row = 1, col = 1) key.gf <- placeGrob(key.gf, textGrob(lab[i], x = legend / 2 + xmid, y = y[1] + 4.5 * dy, default.units = "inches", gp = gpar(cex = 1.3 * cex.title)), row = 1, col = 1) } key.gf }) if (draw) { grid.draw(ans) invisible(ans) } else ans } hexbin/R/grid.hexagons.R0000644000176200001440000003221713171627113014622 0ustar liggesusers hexcoords <- function(dx, dy = NULL, n = 1, sep = NULL) { stopifnot(length(dx) == 1) if(is.null(dy)) dy <- dx/sqrt(3) if(is.null(sep)) list(x = rep.int(c(dx, dx, 0, -dx, -dx, 0), n), y = rep.int(c(dy,-dy, -2*dy, -dy, dy, 2*dy), n), no.sep = TRUE) else list(x = rep.int(c(dx, dx, 0, -dx, -dx, 0, sep), n), y = rep.int(c(dy,-dy, -2*dy, -dy, dy, 2*dy, sep), n), no.sep = FALSE) } hexpolygon <- function(x, y, hexC = hexcoords(dx, dy, n = 1), dx, dy=NULL, fill = 1, border = 0, hUnit = "native", ...) { ## Purpose: draw hexagon [grid.]polygon()'s around (x[i], y[i])_i ## Author: Martin Maechler, Jul 2004; Nicholas for grid n <- length(x) stopifnot(length(y) == n) stopifnot(is.list(hexC) && is.numeric(hexC$x) && is.numeric(hexC$y)) if(hexC$no.sep) { n6 <- rep.int(6:6, n) if(!is.null(hUnit)) { grid.polygon(x = unit(rep.int(hexC$x, n) + rep.int(x, n6),hUnit), y = unit(rep.int(hexC$y, n) + rep.int(y, n6),hUnit), id.lengths = n6, gp = gpar(col= border, fill= fill)) } else { grid.polygon(x = rep.int(hexC$x, n) + rep.int(x, n6), y = rep.int(hexC$y, n) + rep.int(y, n6), id.lengths = n6, gp = gpar(col= border, fill= fill)) } } else{ ## traditional graphics polygons: must be closed explicitly (+ 1 pt) n7 <- rep.int(7:7, n) polygon(x = rep.int(hexC$x, n) + rep.int(x, n7), y = rep.int(hexC$y, n) + rep.int(y, n7), ...) } } grid.hexagons <- function(dat, style = c("colorscale", "centroids", "lattice", "nested.lattice", "nested.centroids", "constant.col"), use.count=TRUE, cell.at=NULL, minarea = 0.05, maxarea = 0.8, check.erosion = TRUE, mincnt = 1, maxcnt = max(dat@count), trans = NULL, colorcut = seq(0, 1, length = 17), density = NULL, border = NULL, pen = NULL, colramp = function(n){ LinGray(n,beg = 90, end = 15) }, def.unit = "native", verbose = getOption("verbose")) { ## Warning: presumes the plot has the right shape and scales ## See plot.hexbin() ## Arguments: ## dat = hexbin object ## style = type of plotting ## 'centroids' = symbol area is a function of the count, ## approximate location near cell center of ## mass without overplotting ## 'lattice' = symbol area is a function of the count, ## plot at lattice points ## 'colorscale' = gray scale plot, ## color number determined by ## transformation and colorcut, ## area = full hexagons. ## 'nested.lattice'= plots two hexagons ## background hexagon ## area=full size ## color number by count in powers of 10 starting at pen 2 ## foreground hexagon ## area by log10(cnt)-floor(log10(cnt)) ## color number by count in powers of 10 starting at pen 12 ## 'nested.centroids' = like nested.lattice ## but counts < 10 are plotted ## ## minarea = minimum symbol area as fraction of the binning cell ## maxarea = maximum symbol area as fraction of the binning cell ## mincnt = minimum count accepted in plot ## maxcnt = maximum count accepted in plot ## trans = a transformation scaling counts into [0,1] to be applied ## to the counts for options 'centroids','lattice','colorscale': ## default=(cnt-mincnt)/(maxcnt-mincnt) ## colorcut= breaks for translating values between 0 and 1 into ## color classes. Default= seq(0,1,17), ## density = for hexagon graph paper ## border plot the border of the hexagon, use TRUE for ## hexagon graph paper ## Symbol size encoding: ## Area= minarea + scaled.count*(maxarea-minarea) ## When maxarea==1 and scaled.count==1, the hexagon cell ## is completely filled. ## ## If small hexagons are hard to see increase minarea. ## For gray scale encoding ## Uses the counts scaled into [0,1] ## Default gray cutpoints seq(0,1,17) yields 16 color classes ## The color number for the first class starts at 2. ## motif coding: black 15 white puts the first of the ## color class above the background black ## The function subtracts 1.e-6 from the lower cutpoint to include ## the boundary ## For nested scaling see the code ## Count scaling alternatives ## ## log 10 and Poisson transformations ## trans <- function(cnt) log10(cnt) ## min inv <- function(y) 10^y ## ## trans <- function(cnt) sqrt(4*cnt+2) ## inv <- function(y) (y^2-2)/4 ## Perceptual considerations. ## Visual response to relative symbol area is not linear and varies from ## person to person. A fractional power transformation ## to make the interpretation nearly linear for more people ## might be considered. With areas bounded between minarea ## and 1 the situation is complicated. ## ## The local background influences color interpretation. ## Having defined color breaks to focus attention on ## specific countours can help. ## ## Plotting the symbols near the center of mass is not only more accurate, ## it helps to reduce the visual dominance of the lattice structure. Of ## course higher resolution binning reduces the possible distance between ## the center of mass for a bin and the bin center. When symbols ## nearly fill their bin, the plot appears to vibrate. This can be ## partially controlled by reducing maxarea or by reducing ## contrast. ##____________________Initial checks_______________________ if(!is(dat,"hexbin")) stop("first argument must be a hexbin object") style <- match.arg(style) # so user can abbreviate if(minarea <= 0) stop("hexagons cannot have a zero area, change minarea") if(maxarea > 1) warning("maxarea > 1, hexagons may overplot") ##_______________ Collect computing constants______________ if(use.count){ cnt <- dat@count } else{ cnt <- cell.at if(is.null(cnt)){ if(is.null(dat@cAtt)) stop("Cell attribute cAtt is null") else cnt <- dat@cAtt } } xbins <- dat@xbins shape <- dat@shape tmp <- hcell2xy(dat, check.erosion = check.erosion) good <- mincnt <= cnt & cnt <= maxcnt xnew <- tmp$x[good] ynew <- tmp$y[good] cnt <- cnt[good] sx <- xbins/diff(dat@xbnds) sy <- (xbins * shape)/diff(dat@ybnds) ##___________Transform Counts to Radius_____________________ switch(style, "centroids" = , "lattice" = , "constant.col" =, "colorscale" = { if(is.null(trans)) { if( min(cnt,na.rm=TRUE)< 0){ pcnt<- cnt + min(cnt) rcnt <- { if(maxcnt == mincnt) rep.int(1, length(cnt)) else (pcnt - mincnt)/(maxcnt - mincnt) } } else rcnt <- { if(maxcnt == mincnt) rep.int(1, length(cnt)) else (cnt - mincnt)/(maxcnt - mincnt) } } else { rcnt <- (trans(cnt) - trans(mincnt)) / (trans(maxcnt) - trans(mincnt)) if(any(is.na(rcnt))) stop("bad count transformation") } area <- minarea + rcnt * (maxarea - minarea) }, "nested.lattice" = , "nested.centroids" = { diffarea <- maxarea - minarea step <- 10^floor(log10(cnt)) f <- (cnt/step - 1)/9 area <- minarea + f * diffarea area <- pmax(area, minarea) } ) area <- pmin(area, maxarea) radius <- sqrt(area) ##______________Set Colors_____________________________ switch(style, "centroids" = , "constant.col" = , "lattice" = { if(length(pen)!= length(cnt)){ if(is.null(pen)) pen <- rep.int(1, length(cnt)) ##else if(length(pen)== length(cnt)) break else if(length(pen)== 1) pen <- rep.int(pen,length(cnt)) else stop("'pen' has wrong length") } }, "nested.lattice" = , "nested.centroids" = { if(!is.null(pen) && length(dim(pen)) == 2) { dp <- dim(pen) lgMcnt <- ceiling(log10(max(cnt))) if(dp[1] != length(cnt) && dp[1] != lgMcnt ) { stop ("pen is not of right dimension") } if( dp[1] == lgMcnt ) { ind <- ceiling(log10(dat@count)) ## DS: 'dat' was 'bin' (??) ind[ind == 0] <- 1 pen <- pen[ind,] } ##else break } else { pen <- floor(log10(cnt)) + 2 pen <- cbind(pen, pen+10) } }, "colorscale" = { ## MM: Following is quite different from bin2d's nc <- length(colorcut) if(colorcut[1] > colorcut[nc]){ colorcut[1] <- colorcut[1] + 1e-06 colorcut[nc] <- colorcut[nc] - 1e-06 } else { colorcut[1] <- colorcut[1] - 1e-06 colorcut[nc] <- colorcut[nc] + 1e-06 } colgrp <- cut(rcnt, colorcut,labels = FALSE) if(any(is.na(colgrp))) colgrp <- ifelse(is.na(colgrp),0,colgrp) ##NL: colramp must be a function accepting an integer n ## and returning n colors clrs <- colramp(length(colorcut) - 1) pen <- clrs[colgrp] } ) ##__________________ Construct a hexagon___________________ ## The inner and outer radius for hexagon in the scaled plot inner <- 0.5 outer <- (2 * inner)/sqrt(3) ## Now construct a point up hexagon symbol in data units dx <- inner/sx dy <- outer/(2 * sy) rad <- sqrt(dx^2 + dy^2) hexC <- hexcoords(dx, dy, sep=NULL) ##_______________ Full Cell Plotting_____________________ switch(style, "constant.col" = , "colorscale" = { hexpolygon(xnew, ynew, hexC, density = density, fill = pen, border = if(!is.null(border)) border else pen) ## and that's been all for these styles return(invisible(paste("done", sQuote(style)))) }, "nested.lattice" = , "nested.centroids" = { hexpolygon(xnew, ynew, hexC, density = density, fill = if (is.null(border) || border) 1 else pen[,1], border = pen[,1]) } ) ##__________________ Symbol Center adjustments_______________ if(style == "centroids" || style == "nested.centroids") { xcm <- dat@xcm[good] ycm <- dat@ycm[good] ## Store 12 angles around a circle and the replicate the first ## The actual length for these vectors is determined by using ## factor use below k <- sqrt(3)/2 cosx <- c(1, k, .5, 0, -.5, -k, -1, -k, -.5, 0, .5, k, 1)/sx siny <- c(0, .5, k, 1, k, .5, 0, -.5, -k, -1, -k, -.5, 0)/sy ## Compute distances for differences after scaling into ## [0,size] x [0,aspect*size] ## Then there are size hexagons on the x axis dx <- sx * (xcm - xnew) dy <- sy * (ycm - ynew) dlen <- sqrt(dx^2 + dy^2) ## Find the closest approximating direction of the 12 vectors above cost <- ifelse(dlen > 0, dx/dlen, 0) tk <- (6 * acos(cost))/pi tk <- round(ifelse(dy < 0, 12 - tk, tk)) + 1 ## Select the available length for the approximating vector hrad <- ifelse(tk %% 2 == 1, inner, outer) ## Rad is either an inner or outer approximating radius. ## If dlen + hrad*radius <= hrad, move the center dlen units. ## Else move as much of dlen as possible without overplotting. fr <- pmin(hrad * (1 - radius), dlen) # Compute the symbol centers ## fr is the distance for the plot [0,xbins] x [0,aspect*xbins] ## cosx and siny give the x and y components of this distance ## in data units xnew <- xnew + fr * cosx[tk] ynew <- ynew + fr * siny[tk] } ## ________________Sized Hexagon Plotting__________________ ## scale the symbol by radius and add to the new center n <- length(radius) if(verbose) cat('length = ',length(pen),"\n", 'pen = ', pen+1,"\n") ##switch(style, ## centroids = , ## lattice = {if(is.null(pen))pen <- rep.int(1, n) ## else pen <- rep.int(pen, n)}, ## nested.lattice = , ## nested.centroids ={ ## if( ## pen[,2] <- pen[,1] + 10 ## } ) ## grid.polygon() closes automatically: now '6' where we had '7': n6 <- rep.int(6:6, n) pltx <- rep.int(hexC$x, n) * rep.int(radius, n6) + rep.int(xnew, n6) plty <- rep.int(hexC$y, n) * rep.int(radius, n6) + rep.int(ynew, n6) switch(style, "centroids" = , "lattice" = { grid.polygon(pltx, plty, default.units=def.unit, id=NULL, ## density = density, id.lengths= n6, gp=gpar(fill = pen, col = border)) }, "nested.lattice" = , "nested.centroids" = { grid.polygon(pltx, plty, default.units=def.unit, id=NULL, id.lengths= n6, gp=gpar(fill = pen[,2], ## density = density, col=if(!is.null(border)) border else pen[,2])) }) } if(FALSE){ ## considering 'hexagons' object setMethod("hexagons", signature(dat="hexbin"), grid.hexagons) erode.hexagons <- function(ebin,pen="black",border="red"){ print("Blank for now") } } hexbin/R/BTY.R0000644000176200001440000001420613171627113012516 0ustar liggesusersBTY <- function(n, beg = 1, end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(7,7,254), c(23,23,252), c(30,30,250), c(36,36,248), c(40,40,247), c(44,44,245), c(47,47,243), c(50,50,242), c(52,52,240), c(55,55,239), c(57,57,238), c(59,59,236), c(61,61,235), c(63,63,234), c(65,65,233), c(66,66,231), c(68,68,230), c(69,69,229), c(71,71,228), c(72,72,227), c(74,74,226), c(75,75,225), c(76,76,225), c(78,78,224), c(79,79,223), c(80,80,222), c(81,81,221), c(82,82,221), c(84,84,220), c(85,85,219), c(86,86,218), c(87,87,218), c(88,88,217), c(89,89,216), c(90,90,216), c(91,91,215), c(92,92,214), c(93,93,214), c(94,94,213), c(95,95,213), c(96,96,212), c(97,97,212), c(98,98,211), c(98,98,210), c(99,99,210), c(100,100,209), c(101,101,209), c(102,102,208), c(103,103,208), c(104,104,208), c(105,105,207), c(105,105,207), c(106,106,206), c(107,107,206), c(108,108,205), c(109,109,205), c(110,110,204), c(110,110,204), c(111,111,204), c(112,112,203), c(113,113,203), c(114,114,202), c(114,114,202), c(115,115,202), c(116,116,201), c(117,117,201), c(118,118,200), c(118,118,200), c(119,119,200), c(120,120,199), c(121,121,199), c(121,121,199), c(122,122,198), c(123,123,198), c(124,124,198), c(124,124,197), c(125,125,197), c(126,126,197), c(127,127,196), c(128,128,196), c(128,128,195), c(129,129,195), c(130,130,195), c(130,130,194), c(131,131,194), c(132,132,194), c(133,133,193), c(133,133,193), c(134,134,193), c(135,135,192), c(136,136,192), c(136,136,192), c(137,137,191), c(138,138,191), c(139,139,191), c(139,139,190), c(140,140,190), c(141,141,190), c(142,142,189), c(142,142,189), c(143,143,189), c(144,144,188), c(144,144,188), c(145,145,188), c(146,146,187), c(147,147,187), c(147,147,187), c(148,148,186), c(149,149,186), c(149,149,186), c(150,150,185), c(151,151,185), c(152,152,185), c(152,152,184), c(153,153,184), c(154,154,184), c(154,154,183), c(155,155,183), c(156,156,182), c(157,157,182), c(157,157,182), c(158,158,181), c(159,159,181), c(159,159,181), c(160,160,180), c(161,161,180), c(162,162,180), c(162,162,179), c(163,163,179), c(164,164,178), c(164,164,178), c(165,165,178), c(166,166,177), c(167,167,177), c(167,167,176), c(168,168,176), c(169,169,176), c(169,169,175), c(170,170,175), c(171,171,174), c(172,172,174), c(172,172,173), c(173,173,173), c(174,174,173), c(174,174,172), c(175,175,172), c(176,176,171), c(177,177,171), c(177,177,170), c(178,178,170), c(179,179,169), c(179,179,169), c(180,180,168), c(181,181,168), c(181,181,167), c(182,182,167), c(183,183,166), c(184,184,166), c(184,184,165), c(185,185,165), c(186,186,164), c(186,186,164), c(187,187,163), c(188,188,163), c(189,189,162), c(189,189,162), c(190,190,161), c(191,191,161), c(191,191,160), c(192,192,159), c(193,193,159), c(194,194,158), c(194,194,158), c(195,195,157), c(196,196,157), c(196,196,156), c(197,197,155), c(198,198,155), c(199,199,154), c(199,199,153), c(200,200,153), c(201,201,152), c(201,201,151), c(202,202,151), c(203,203,150), c(204,204,149), c(204,204,149), c(205,205,148), c(206,206,147), c(206,206,146), c(207,207,146), c(208,208,145), c(209,209,144), c(209,209,143), c(210,210,143), c(211,211,142), c(211,211,141), c(212,212,140), c(213,213,139), c(214,214,138), c(214,214,138), c(215,215,137), c(216,216,136), c(216,216,135), c(217,217,134), c(218,218,133), c(219,219,132), c(219,219,131), c(220,220,130), c(221,221,129), c(221,221,128), c(222,222,127), c(223,223,126), c(224,224,125), c(224,224,124), c(225,225,123), c(226,226,122), c(226,226,121), c(227,227,119), c(228,228,118), c(229,229,117), c(229,229,116), c(230,230,114), c(231,231,113), c(232,232,112), c(232,232,110), c(233,233,109), c(234,234,107), c(234,234,106), c(235,235,104), c(236,236,103), c(237,237,101), c(237,237,100), c(238,238,98), c(239,239,96), c(239,239,94), c(240,240,92), c(241,241,91), c(242,242,89), c(242,242,86), c(243,243,84), c(244,244,82), c(245,245,80), c(245,245,77), c(246,246,74), c(247,247,72), c(247,247,69), c(248,248,65), c(249,249,62), c(250,250,58), c(250,250,54), c(251,251,49), c(252,252,44), c(253,253,37), c(253,253,28), c(254,254,13))[ round(seq(beg,end, length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/BTC.R0000644000176200001440000001367113171627113012475 0ustar liggesusersBTC <- function(n, beg = 1, end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(0,0,0), c(0,0,40), c(0,4,56), c(0,9,61), c(0,12,64), c(0,14,66), c(0,17,69), c(0,20,73), c(0,22,74), c(0,25,78), c(0,27,79), c(0,30,83), c(0,31,85), c(0,33,86), c(0,36,90), c(0,38,91), c(0,39,93), c(0,41,95), c(0,43,96), c(0,46,100), c(0,47,102), c(0,49,103), c(0,51,105), c(0,52,107), c(0,54,108), c(0,55,110), c(0,57,112), c(0,57,112), c(0,58,113), c(0,60,115), c(0,62,117), c(0,63,119), c(0,65,120), c(0,66,122), c(0,68,124), c(0,70,125), c(0,71,127), c(0,73,129), c(0,73,129), c(0,74,130), c(0,76,132), c(0,78,134), c(0,79,136), c(0,81,137), c(0,82,139), c(0,84,141), c(0,86,142), c(0,87,144), c(0,89,146), c(0,90,147), c(0,92,149), c(0,94,151), c(0,94,151), c(0,95,153), c(0,97,154), c(0,98,156), c(0,100,158), c(0,102,159), c(0,103,161), c(0,105,163), c(0,106,164), c(0,108,166), c(0,109,168), c(0,111,170), c(0,113,171), c(0,114,173), c(0,116,175), c(0,117,176), c(0,119,178), c(0,121,180), c(0,121,180), c(0,122,181), c(0,124,183), c(0,125,185), c(0,127,187), c(0,129,188), c(0,130,190), c(0,132,192), c(0,133,193), c(0,135,195), c(0,137,197), c(0,138,198), c(0,140,200), c(0,141,202), c(0,143,204), c(0,143,204), c(0,145,205), c(0,146,207), c(0,148,209), c(0,149,210), c(0,151,212), c(0,153,214), c(0,154,215), c(0,156,217), c(0,157,219), c(0,159,221), c(0,160,222), c(0,160,222), c(0,162,224), c(0,164,226), c(0,165,227), c(0,167,229), c(0,168,231), c(0,170,232), c(0,172,234), c(0,173,236), c(0,175,238), c(0,175,238), c(0,176,239), c(0,178,241), c(0,180,243), c(0,181,244), c(0,183,246), c(2,184,248), c(4,186,249), c(4,186,249), c(4,186,249), c(6,188,251), c(6,188,251), c(9,189,253), c(9,189,253), c( 11,191,255), c( 11,191,255), c( 13,192,255), c( 13,192,255), c( 13,192,255), c( 16,194,255), c( 18,196,255), c( 20,197,255), c( 20,197,255), c( 23,199,255), c( 25,200,255), c( 27,202,255), c( 30,204,255), c( 32,205,255), c( 34,207,255), c( 37,208,255), c( 37,208,255), c( 39,210,255), c( 41,211,255), c( 44,213,255), c( 46,215,255), c( 48,216,255), c( 51,218,255), c( 53,219,255), c( 53,219,255), c( 55,221,255), c( 57,223,255), c( 60,224,255), c( 62,226,255), c( 64,227,255), c( 67,229,255), c( 67,229,255), c( 69,231,255), c( 71,232,255), c( 74,234,255), c( 76,235,255), c( 78,237,255), c( 81,239,255), c( 81,239,255), c( 83,240,255), c( 85,242,255), c( 88,243,255), c( 90,245,255), c( 92,247,255), c( 95,248,255), c( 95,248,255), c( 97,250,255), c( 99,251,255), c(102,253,255), c(104,255,255), c(106,255,255), c(106,255,255), c(108,255,255), c(111,255,255), c(113,255,255), c(115,255,255), c(115,255,255), c(118,255,255), c(120,255,255), c(122,255,255), c(122,255,255), c(125,255,255), c(127,255,255), c(129,255,255), c(129,255,255), c(132,255,255), c(134,255,255), c(136,255,255), c(136,255,255), c(139,255,255), c(141,255,255), c(143,255,255), c(143,255,255), c(146,255,255), c(148,255,255), c(150,255,255), c(150,255,255), c(153,255,255), c(155,255,255), c(155,255,255), c(157,255,255), c(159,255,255), c(159,255,255), c(162,255,255), c(164,255,255), c(164,255,255), c(166,255,255), c(169,255,255), c(171,255,255), c(171,255,255), c(173,255,255), c(176,255,255), c(176,255,255), c(178,255,255), c(180,255,255), c(180,255,255), c(183,255,255), c(185,255,255), c(185,255,255), c(187,255,255), c(190,255,255), c(190,255,255), c(192,255,255), c(194,255,255), c(197,255,255), c(197,255,255), c(199,255,255), c(201,255,255), c(204,255,255), c(204,255,255), c(206,255,255), c(208,255,255), c(210,255,255), c(210,255,255), c(213,255,255), c(215,255,255), c(217,255,255), c(217,255,255), c(220,255,255), c(222,255,255), c(224,255,255), c(227,255,255), c(229,255,255), c(229,255,255), c(231,255,255), c(234,255,255), c(236,255,255), c(238,255,255), c(241,255,255), c(243,255,255), c(243,255,255), c(245,255,255), c(248,255,255), c(250,255,255), c(255,255,255))[ round(seq(beg,end, length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/hexViewport.R0000644000176200001440000002210513562344315014405 0ustar liggesusersif ("simpleUnit" %in% class(unit(1, "mm"))) { setOldClass(c("unit", "unit_v2")) setOldClass(c("simpleUnit", "unit", "unit_v2")) } else { setOldClass("unit") } setOldClass("viewport") smartBnds <- function(hbin, eps=.05) { hxy <- hcell2xy(hbin) xr <- range(hxy$x) yr <- range(hxy$y) dx <- diff(xr) dy <- diff(yr) lambda <- function(a) pmax(log(a), 1) epsx <- c(-1,1)*(dx*eps/lambda(dx)) epsy <- c(-1,1)*(dy*eps/lambda(dy)) sx <- hbin@xbins/diff(hbin@xbnds) sy <- (hbin@xbins * hbin@shape)/diff(hbin@ybnds) inner <- 0.5 outer <- 1/sqrt(3) dx <- inner/sx dy <- outer/sy #xb <- dx/(hbin@xbins+1) #yb <- dy/((1/sqrt(3))*(hbin@xbins+1)*hbin@shape) list(xr = xr+ c(-dx,dx)+ epsx, yr = yr+ c(-dy,dy)+ epsy) } rname <- function(n, chars = letters) { ## random name with n characters paste(sample(chars, size = n, replace = TRUE), collapse="") } setClass("hexVP", representation(hexVp.on = "viewport", hexVp.off = "viewport", mar = "unit", fig = "unit", plt = "unit", xscale = "numeric", yscale = "numeric",shape="numeric", hp.name="character") ) hexViewport <- function(x, offset = unit(0,"inches"), mar = NULL, xbnds = NULL, ybnds = NULL, newpage = FALSE, clip ="off", vp.name=NULL) { if(!is(x,"hexbin")) stop("first argument must be a hexbin object.") stopifnot(is.unit(offset)) hvp <- new("hexVP") if (newpage) grid.newpage() if(is.null(mar)) { mar <- unit(0.1 + c(5,4,4,2),"lines") } else { if(!is.unit(mar)) stop("'mar' must be specified in unit()s") if(length(mar) == 1) mar <- rep(mar, 4) else if(length(mar) != 4) stop("'mar' must have length 1 or 4") } ## in both cases mai <- as.numeric(convertUnit(mar, "inches")) vpin <- c(convertWidth (unit(1,"npc"),"inches"), convertHeight(unit(1,"npc"),"inches")) fig <- c(as.numeric(convertUnit(unit(vpin[1],"inches") - offset,"inches")), as.numeric(vpin[2])) pin <- c(fig[1]-mai[2]-mai[4], fig[2]-mai[1]-mai[3]) xsize <- pin[1] ysize <- pin[2] ## The point is to optimize the placement ## and plotting area of the plotting window with ## the constraint that the margins are preserved ## to within some epsilon. This is going to get even ## harder for cases where the complex layouts are ## being constructed. NL -- I think it is fixed now (NL --3/22/2005) ## Now find the maximum rectangle in fig that ## has the correct aspect ratio and does not spill over epsilon into ## the margins, i.e. ysize/xsize - aspect.ratio < eps and ## xsize < fig[1], ysize < fig[2] if(x@shape * xsize <= ysize) { ##center <- (ysize - x@shape * xsize)/2 center <- (ysize - x@shape * xsize)/2 mai[1] <- mai[1] + center mai[3] <- mai[3] + center ysize <- x@shape * xsize } else { center <- (xsize - ysize/x@shape)/2 mai[2] <- mai[2] + center mai[4] <- mai[4] + center xsize <- ysize/x@shape } ##fig <- c(pin[1]+mai[2]+ mai[4],fig[2]) pin <- c(xsize,ysize) mar <- c(convertUnit(unit(mai[1],"inches"),"lines"), convertUnit(unit(mai[2],"inches"),"lines"), convertUnit(unit(mai[3],"inches"),"lines"), convertUnit(unit(mai[4],"inches"),"lines")) ##pin <- c(fig[1]-(mai[2] + mai[4]), ## fig[2]-(mai[1] + mai[3])) margins <- rep(as.numeric(mar), length.out = 4) wd <- convertUnit(unit(pin[1],"inches"),"npc") ## (unit(sum(margins[c(2, 4)]), "lines") + ## convertUnit(unit(legend,"inches"),"lines")) ## Oy, mi stupido! This is the problem, need to get the bounds right ## here. Fixed, do we need to guard against others stupidity and put some ## checks on xbnds and ybnds? (NL,4/1/2005) if(is.null(vp.name)) vp.name <- rname(5) xyb <- smartBnds(x) hvp@xscale <- xs <- if(is.null(xbnds)) xyb$xr else xbnds hvp@yscale <- ys <- if(is.null(ybnds)) xyb$yr else ybnds ht <- unit(1, "npc") - unit(sum(margins[c(1,3)]), "lines") hvp@hexVp.off <- viewport(x = unit(margins[2], "lines"), y = unit(margins[1], "lines"), width = wd, height = ht, xscale = xs, yscale = ys, just = c("left", "bottom"), default.units = "native", clip = "off", name = paste(vp.name,".off",sep="")) hvp@hexVp.on <- viewport(x = unit(margins[2], "lines"), y = unit(margins[1], "lines"), width = wd, height = ht, xscale = xs, yscale = ys, just = c("left", "bottom"), default.units = "native", clip = "on", name = paste(vp.name,".on",sep="")) hvp@mar <- unit(mar,"lines") hvp@fig <- convertUnit(unit(fig,"inches"),"npc") hvp@plt <- convertUnit(unit(pin,"inches"),"npc") hvp@shape <- x@shape ##hvp@leg <-convertUnit(offset,"npc") hvp } ## Potentially: ## setGeneric("grid:::pushViewport") ## setMethod("pushViewport", signature(x="hexVP"), ## function(hvp) { pushViewport(hvp@hexVp) }) pushHexport <- function(hvp, clip="off") { if(!is(hvp, "hexVP")) stop("1st argument must be 'hexVP' object") pushViewport(if(clip=="on") hvp@hexVp.on else hvp@hexVp.off) } ## maybe in the future ## setMethod("push",signature("hexVP"), pushHexport) setGeneric("getMargins", function(x, ret.unit = "npc", numeric = FALSE) standardGeneric("getMargins")) setMethod("getMargins", "hexVP", function(x, ret.unit = "npc", numeric = FALSE){ mar <- convertUnit(x@mar,ret.unit) if(numeric) as.numeric(mar) else mar }) setGeneric("getPlt", function(x, ret.unit = "npc", numeric = FALSE) standardGeneric("getPlt")) setMethod("getPlt", "hexVP", function(x, ret.unit = "npc", numeric = FALSE){ plt <- convertUnit(x@plt,ret.unit) if(numeric) as.numeric(plt) else plt }) setGeneric("getFig", function(x, ret.unit = "npc", numeric = FALSE) standardGeneric("getFig")) setMethod("getFig", "hexVP", function(x, ret.unit = "npc", numeric = FALSE){ fig <- convertUnit(x@fig,ret.unit) if(numeric) as.numeric(fig) else fig }) ## MM doesn't think it's ok to "pollute" the generic-space ## just for basic slot accessors : ## setGeneric("getXscale", function(x)standardGeneric("getXscale")) ## setMethod("getXscale", "hexVP", function(x){ x@xscale }) ## setGeneric("getYscale", function(x)standardGeneric("getYscale")) ## setMethod("getYscale", "hexVP", function(x){ x@yscale }) hexVP.abline <- function(hvp, a = NULL, b = NULL, h = numeric(0), v = numeric(0), col = 'black', lty = 1, lwd = 2, ...) { pushHexport(hvp, clip = 'on') col.line <- col if (!is.null(a)) { if (inherits(a, "lm")) { coeff <- coef(a) } else if (!is.null(tryCatch(coef(a), error = function(e) NULL))) coeff <- coef(a) else coeff <- c(a, b) if (length(coeff) == 1) coeff <- c(0, coeff) if (coeff[2] == 0) h <- c(h, coeff[1]) else if (!any(is.null(coeff))) { xx <- current.viewport()$xscale yy <- current.viewport()$yscale x <- numeric(0) y <- numeric(0) ll <- function(i, j, k, l) (yy[j] - coeff[1] - coeff[2] * xx[i]) * (yy[l] - coeff[1] - coeff[2] * xx[k]) if (ll(1, 1, 2, 1) <= 0) { y <- c(y, yy[1]) x <- c(x, (yy[1] - coeff[1])/coeff[2]) } if (ll(2, 1, 2, 2) <= 0) { x <- c(x, xx[2]) y <- c(y, coeff[1] + coeff[2] * xx[2]) } if (ll(2, 2, 1, 2) <= 0) { y <- c(y, yy[2]) x <- c(x, (yy[2] - coeff[1])/coeff[2]) } if (ll(1, 2, 1, 1) <= 0) { x <- c(x, xx[1]) y <- c(y, coeff[1] + coeff[2] * xx[1]) } if (length(x) > 0) grid.lines(x = x, y = y, default.units = "native", gp = gpar(col = col.line, lty = lty, lwd = lwd)) } } h <- as.numeric(h) v <- as.numeric(v) for (i in seq(along = h)) grid.lines(y = rep(h[i], 2), default.units = "native", gp = gpar(col = col.line, lty = lty, lwd = lwd)) for (i in seq(along = v)) grid.lines(x = rep(v[i], 2), default.units = "native", gp = gpar(col = col.line, lty = lty, lwd = lwd)) popViewport() } hexVP.loess <- function(hbin, hvp = NULL, span = 0.4, col = 'red', n = 200) { fit <- loess(hbin@ycm ~ hbin@xcm, weights = hbin@count, span = span) if(!is.null(hvp)) { pushHexport(hvp, clip = 'on') # grid.lines(seq(0,16, length = n), # predict(fit,seq(0,16, length = n)), # gp = gpar(col = col), default.units = 'native') grid.lines(seq(hbin@xbnds[1], hbin@xbnds[2], length = n), predict(fit,seq(hbin@xbnds[1], hbin@xbnds[2], length = n)), gp = gpar(col = col), default.units = 'native') popViewport() } invisible(fit) } hexbin/R/hexbinList.R0000644000176200001440000000627013171627113014173 0ustar liggesusershexList <- function(x,y=NULL,given=NULL,xbins=30,shape=1, xbnds = NULL, ybnds = NULL, xlab = NULL, ylab = NULL) { xl <- if (!missing(x)) deparse(substitute(x)) yl <- if (!missing(y)) deparse(substitute(y)) xy <- xy.coords(x, y, xl, yl) if(length(given)!=length(xy$x) | is.null(given)) stop("Given is is different length from x and y") if(is.factor(given)) given <- as.character(given) clss <- unique(given) if(is.null(xbnds)) xbnds <- range(xy$x) if(is.null(ybnds)) ybnds <- range(xy$y) hbins <- vector(mode = "list",length=length(clss)) i <- 1 for(g in clss){ hbins[[i]] <- hexbin(xy$x[given==g],xy$y[given==g], xbins=xbins,shape=shape,xbnds=xbnds,ybnds=ybnds) i <- i+1 } mx <- max(unlist(lapply(hbins,function(h)max(h@count)))) mn <- min(unlist(lapply(hbins,function(h)min(h@count)))) hl <- new("hexbinList",n=length(hbins),hbins=hbins, Xbnds=xbnds, Ybnds=ybnds, Xbins=integer(xbins), Shape=shape, Bnames=clss, CntBnds=c(mn,mx)) hl } setClass("hexbinList", representation(n="integer", hbins="vector", Xbnds="numeric", Ybnds="numeric", Xbins="numeric", Shape="numeric", Bnames="character", CntBnds="numeric") ) bnds.check <- function(binlst, xb = TRUE, yb = TRUE) { xb <- if(xb) { b <- binlst[[1]]@xbnds all(unlist(lapply(binlst, function(x, bnd) all(x@xbnds == bnd), b))) } else TRUE yb <- if(yb) { b <- binlst[[1]]@ybnds all(unlist(lapply(binlst, function(y, bnd) all(y@ybnds == bnd), b))) } else TRUE xb & yb } xbins.check <- function(binlst) { xb <- binlst[[1]]@xbins all(unlist(lapply(binlst, function(y, xbin)all(y@xbins == xbin), xb))) } shape.check <- function(binlst) { xs <- binlst[[1]]@shape all(unlist(lapply(binlst, function(y, xsh)all(y@shape == xsh), xs))) } list2hexList <- function(binlst) { if(length(binlst) < 2) stop(" need at least 2 hex bin objects") if(!all(unlist(lapply(binlst, is, "hexbin")))) stop("All Elements of list must be hexbin objects") if(!bnds.check(binlst)) stop("All bin objects in list need the same xbnds and ybnds") if(!xbins.check(binlst)) stop("All bin objects in list need the same number of bins") if(!shape.check(binlst)) stop("All bin objects in list need the same shape parameter") mx <- max(unlist(lapply(binlst,function(h)max(h@count)))) mn <- min(unlist(lapply(binlst,function(h)min(h@count)))) xbins <- binlst[[1]]@xbins xbnds <- binlst[[1]]@xbnds ybnds <- binlst[[1]]@ybnds shape <- binlst[[1]]@shape hl <- new("hexbinList",n=length(binlst),hbins=binlst, Xbnds=xbnds, Ybnds=ybnds, Xbins=xbins, Shape=shape, Bnames=names(binlst), CntBnds=c(mn,mx)) hl } setAs("list","hexbinList",function(from)list2hexList(from)) #setMethod("[", "hexbinList", function(hbl,i,...) #{ # if( length(list(...)) > 0 ) # stop("extra subscripts cannot be handled") # if(missing(i)) hbl # hbl@hbins[i] #}) ##setMethod("[[", "hexbinList", function(hbl) ##{ ##}) hexbin/R/hexPlotMA.R0000644000176200001440000001654313171627113013727 0ustar liggesusersplotMAhex <- function (MA, array = 1, xlab = "A", ylab = "M", main = colnames(MA)[array], xlim = NULL, ylim = NULL, status = NULL, values, pch, col, cex, nbin=40, zero.weights = FALSE, style = "colorscale", legend = 1.2, lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 2, maxcnt = NULL, trans = NULL, inv = NULL, colorcut = NULL, border = NULL, density = NULL, pen = NULL, colramp = function(n){ LinGray(n,beg = 90,end = 15) }, newpage = TRUE, type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"), verbose = getOption("verbose")) { if (!requireNamespace("marray", quietly = TRUE)) stop("cannot process objects without package marray") if (!requireNamespace("limma", quietly = TRUE)) stop("cannot process objects without package limma") if(is.null(main))main <- "" switch(class(MA),marrayRaw={ x <- marray::maA(MA[,array]) y <- marray::maM(MA[,array]) w <- marray::maW(MA[,array]) },RGList = { MA <- limma::MA.RG(MA[, array]) array <- 1 x <- MA$A y <- MA$M w <- MA$w }, MAList = { x <- as.matrix(MA$A)[, array] y <- as.matrix(MA$M)[, array] if (is.null(MA$weights)) w <- NULL else w <- as.matrix(MA$weights)[, array] }, list = { if (is.null(MA$A) || is.null(MA$M)) stop("No data to plot") x <- as.matrix(MA$A)[, array] y <- as.matrix(MA$M)[, array] if (is.null(MA$weights)) w <- NULL else w <- as.matrix(MA$weights)[, array] }, MArrayLM = { x <- MA$Amean y <- as.matrix(MA$coefficients)[, array] if (is.null(MA$weights)) w <- NULL else w <- as.matrix(MA$weights)[, array] }, matrix = { narrays <- ncol(MA) if (narrays < 2) stop("Need at least two arrays") if (narrays > 5) x <- apply(MA, 1, median, na.rm = TRUE) else x <- rowMeans(MA, na.rm = TRUE) y <- MA[, array] - x w <- NULL }, ExpressionSet = { if (!requireNamespace("Biobase", quietly = TRUE)) stop("cannot process ExpressionSet objects without package Biobase") narrays <- ncol(Biobase::exprs(MA)) if (narrays < 2) stop("Need at least two arrays") if (narrays > 5) x <- apply(Biobase::exprs(MA), 1, median, na.rm = TRUE) else x <- rowMeans(Biobase::exprs(MA), na.rm = TRUE) y <- Biobase::exprs(MA)[, array] - x w <- NULL if (missing(main)) main <- colnames(Biobase::exprs(MA))[array] }, AffyBatch = { if (!requireNamespace("Biobase", quietly = TRUE) || !requireNamespace("affy", quietly = TRUE)) stop("cannot process AffyBatch objects without package Biobase and affy") narrays <- ncol(Biobase::exprs(MA)) if (narrays < 2) stop("Need at least two arrays") if (narrays > 5) x <- apply(log2(Biobase::exprs(MA)), 1, median, na.rm = TRUE) else x <- rowMeans(log2(Biobase::exprs(MA)), na.rm = TRUE) y <- log2(Biobase::exprs(MA)[, array]) - x w <- NULL if (missing(main)) main <- colnames(Biobase::exprs(MA))[array] }, stop("MA is invalid object")) if (!is.null(w) && !zero.weights) { i <- is.na(w) | (w <= 0) y[i] <- NA } if (is.null(xlim)) xlim <- range(x, na.rm = TRUE) if (is.null(ylim)) ylim <- range(y, na.rm = TRUE) hbin <- hexbin(x,y,xbins=nbin,xbnds=xlim,ybnds=ylim, IDs = TRUE) hp <- plot(hbin, legend=legend, xlab = xlab, ylab = ylab, main = main, type='n', newpage=newpage) ## plot the hexagons pushHexport(hp$plot.vp) if(is.null(maxcnt)) maxcnt <- max(hbin@count) if(is.null(colorcut)) colorcut<-seq(0, 1, length = min(17, maxcnt)) grid.hexagons(hbin, style=style, minarea = minarea, maxarea = maxarea, mincnt = mincnt, maxcnt= maxcnt, trans = trans, colorcut = colorcut, density = density, border = border, pen = pen, colramp = colramp) if (is.null(status) || all(is.na(status))) { if (missing(pch)) pch <- 16 if (missing(cex)) cex <- 0.3 if (missing(col)) { clrs <- colramp(length(colorcut)-1) col <- clrs[1] } pp <- inout.hex(hbin,mincnt) grid.points(x[pp], y[pp], pch = pch[[1]], gp=gpar(cex = cex[1], col=col, fill=col)) } else { if (missing(values)) { if (is.null(attr(status, "values"))) values <- names(sort(table(status), decreasing = TRUE)) else values <- attr(status, "values") } sel <- !(status %in% values) nonhi <- any(sel) if (nonhi) grid.points(x[sel], y[sel], pch = 16, gp=gpar(cex = 0.3)) nvalues <- length(values) if (missing(pch)) { if (is.null(attr(status, "pch"))) pch <- rep(16, nvalues) else pch <- attr(status, "pch") } if (missing(cex)) { if (is.null(attr(status, "cex"))) { cex <- rep(1, nvalues) if (!nonhi) cex[1] <- 0.3 } else cex <- attr(status, "cex") } if (missing(col)) { if (is.null(attr(status, "col"))) { col <- nonhi + 1:nvalues } else col <- attr(status, "col") } pch <- rep(pch, length = nvalues) col <- rep(col, length = nvalues) cex <- rep(cex, length = nvalues) for (i in 1:nvalues) { sel <- status == values[i] grid.points(x[sel], y[sel], pch = pch[[i]], gp=gpar(cex = cex[i], col = col[i])) } } popViewport() if (legend > 0) { inner <- getPlt(hp$plot.vp, ret.unit="inches", numeric=TRUE)[1] inner <- inner/hbin@xbins ysize <- getPlt(hp$plot.vp, ret.unit="inches", numeric=TRUE)[2] pushViewport(hp$legend.vp) grid.hexlegend(legend, ysize=ysize, lcex = lcex, inner = inner, style= style, minarea= minarea, maxarea= maxarea, mincnt= mincnt, maxcnt= maxcnt, trans=trans, inv=inv, colorcut = colorcut, density = density, border = border, pen = pen, colramp = colramp) #if (is.list(pch)) # legend(x = xlim[1], y = ylim[2], legend = values, # fill = col, col = col, cex = 0.9) #else legend(x = xlim[1], y = ylim[2], legend = values, # pch = pch, , col = col, cex = 0.9) popViewport() } invisible(list(hbin = hbin, plot.vp = hp$plot.vp, legend.vp = hp$legend.vp)) } hexMA.loess <- function(pMA, span = .4, col = 'red', n = 200) { fit <- hexVP.loess(pMA$hbin, pMA$plot.vp, span = span, col = col, n = n) invisible(fit) } hexbin/R/HO.R0000644000176200001440000001362113171627113012366 0ustar liggesusersheat.ob <- function(n,beg = 1,end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(0, 0, 0), c(35, 0, 0), c(52, 0, 0), c(60, 0, 0), c(63, 1, 0), c(64, 2, 0), c(68, 5, 0), c(69, 6, 0), c(72, 8, 0), c(74,10, 0), c(77,12, 0), c(78,14, 0), c(81,16, 0), c(83,17, 0), c(85,19, 0), c(86,20, 0), c(89,22, 0), c(91,24, 0), c(92,25, 0), c(94,26, 0), c(95,28, 0), c(98,30, 0), c(100,31, 0), c(102,33, 0), c(103,34, 0), c(105,35, 0), c(106,36, 0), c(108,38, 0), c(109,39, 0), c(111,40, 0), c(112,42, 0), c(114,43, 0), c(115,44, 0), c(117,45, 0), c(119,47, 0), c(119,47, 0), c(120,48, 0), c(122,49, 0), c(123,51, 0), c(125,52, 0), c(125,52, 0), c(126,53, 0), c(128,54, 0), c(129,56, 0), c(129,56, 0), c(131,57, 0), c(132,58, 0), c(134,59, 0), c(134,59, 0), c(136,61, 0), c(137,62, 0), c(137,62, 0), c(139,63, 0), c(139,63, 0), c(140,65, 0), c(142,66, 0), c(142,66, 0), c(143,67, 0), c(143,67, 0), c(145,68, 0), c(145,68, 0), c(146,70, 0), c(146,70, 0), c(148,71, 0), c(148,71, 0), c(149,72, 0), c(149,72, 0), c(151,73, 0), c(151,73, 0), c(153,75, 0), c(153,75, 0), c(154,76, 0), c(154,76, 0), c(154,76, 0), c(156,77, 0), c(156,77, 0), c(157,79, 0), c(157,79, 0), c(159,80, 0), c(159,80, 0), c(159,80, 0), c(160,81, 0), c(160,81, 0), c(162,82, 0), c(162,82, 0), c(163,84, 0), c(163,84, 0), c(165,85, 0), c(165,85, 0), c(166,86, 0), c(166,86, 0), c(166,86, 0), c(168,87, 0), c(168,87, 0), c(170,89, 0), c(170,89, 0), c(171,90, 0), c(171,90, 0), c(173,91, 0), c(173,91, 0), c(174,93, 0), c(174,93, 0), c(176,94, 0), c(176,94, 0), c(177,95, 0), c(177,95, 0), c(179,96, 0), c(179,96, 0), c(180,98, 0), c(182,99, 0), c(182,99, 0), c(183,100, 0), c(183,100, 0), c(185,102, 0), c(185,102, 0), c(187,103, 0), c(187,103, 0), c(188,104, 0), c(188,104, 0), c(190,105, 0), c(191,107, 0), c(191,107, 0), c(193,108, 0), c(193,108, 0), c(194,109, 0), c(196,110, 0), c(196,110, 0), c(197,112, 0), c(197,112, 0), c(199,113, 0), c(200,114, 0), c(200,114, 0), c(202,116, 0), c(202,116, 0), c(204,117, 0), c(205,118, 0), c(205,118, 0), c(207,119, 0), c(208,121, 0), c(208,121, 0), c(210,122, 0), c(211,123, 0), c(211,123, 0), c(213,124, 0), c(214,126, 0), c(214,126, 0), c(216,127, 0), c(217,128, 0), c(217,128, 0), c(219,130, 0), c(221,131, 0), c(221,131, 0), c(222,132, 0), c(224,133, 0), c(224,133, 0), c(225,135, 0), c(227,136, 0), c(227,136, 0), c(228,137, 0), c(230,138, 0), c(230,138, 0), c(231,140, 0), c(233,141, 0), c(233,141, 0), c(234,142, 0), c(236,144, 0), c(236,144, 0), c(238,145, 0), c(239,146, 0), c(241,147, 0), c(241,147, 0), c(242,149, 0), c(244,150, 0), c(244,150, 0), c(245,151, 0), c(247,153, 0), c(247,153, 0), c(248,154, 0), c(250,155, 0), c(251,156, 0), c(251,156, 0), c(253,158, 0), c(255,159, 0), c(255,159, 0), c(255,160, 0), c(255,161, 0), c(255,163, 0), c(255,163, 0), c(255,164, 0), c(255,165, 0), c(255,167, 0), c(255,167, 0), c(255,168, 0), c(255,169, 0), c(255,169, 0), c(255,170, 0), c(255,172, 0), c(255,173, 0), c(255,173, 0), c(255,174, 0), c(255,175, 0), c(255,177, 0), c(255,178, 0), c(255,179, 0), c(255,181, 0), c(255,181, 0), c(255,182, 0), c(255,183, 0), c(255,184, 0), c(255,187, 7), c(255,188,10), c(255,189,14), c(255,191,18), c(255,192,21), c(255,193,25), c(255,195,29), c(255,197,36), c(255,198,40), c(255,200,43), c(255,202,51), c(255,204,54), c(255,206,61), c(255,207,65), c(255,210,72), c(255,211,76), c(255,214,83), c(255,216,91), c(255,219,98), c(255,221,105), c(255,223,109), c(255,225,116), c(255,228,123), c(255,232,134), c(255,234,142), c(255,237,149), c(255,239,156), c(255,240,160), c(255,243,167), c(255,246,174), c(255,248,182), c(255,249,185), c(255,252,193), c(255,253,196), c(255,255,204), c(255,255,207), c(255,255,211), c(255,255,218), c(255,255,222), c(255,255,225), c(255,255,229), c(255,255,233), c(255,255,236), c(255,255,240), c(255,255,244), c(255,255,247), c(255,255,255))[ round(seq(beg,end,length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/LOCS.R0000644000176200001440000001306313171627113012620 0ustar liggesusersLinOCS <- function(n,beg = 1,end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(0,0,0), c(0,0,0), c(0,0,0), c(1,0,0), c(2,0,0), c(2,0,0), c(3,0,0), c(3,0,0), c(4,0,0), c(5,0,0), c(5,0,0), c(6,0,0), c(7,0,0), c(7,0,0), c(8,0,0), c(9,0,0), c(9,0,0), c(10,0,0), c(11,0,0), c(12,0,0), c(13,0,0), c(14,0,0), c(15,0,0), c(16,0,0), c(17,0,0), c(18,0,0), c(19,0,0), c(20,0,0), c(21,0,0), c(22,0,0), c(23,0,0), c(25,0,0), c(26,0,0), c(27,0,0), c(28,0,0), c(30,0,0), c(31,0,0), c(33,0,0), c(34,0,0), c(35,0,0), c(37,0,0), c(39,0,0), c(40,0,0), c(43,0,0), c(45,0,0), c(46,0,0), c(49,0,0), c(51,0,0), c(53,0,0), c(54,0,0), c(56,0,0), c(58,0,0), c(60,0,0), c(62,0,0), c(64,0,0), c(67,0,0), c(69,0,0), c(71,0,0), c(74,0,0), c(76,0,0), c(80,0,0), c(81,0,0), c(84,0,0), c(86,0,0), c(89,0,0), c(92,0,0), c(94,0,0), c(97,0,0), c(100,0,0), c(103,0,0), c(106,0,0), c(109,0,0), c(112,0,0), c(115,0,0), c(117,0,0), c(122,0,0), c(126,0,0), c(128,0,0), c(131,0,0), c(135,0,0), c(135,0,0), c(135,1,0), c(135,2,0), c(135,3,0), c(135,4,0), c(135,6,0), c(135,6,0), c(135,8,0), c(135,9,0), c(135,10,0), c(135,11,0), c(135,13,0), c(135,13,0), c(135,15,0), c(135,17,0), c(135,17,0), c(135,19,0), c(135,21,0), c(135,22,0), c(135,23,0), c(135,25,0), c(135,26,0), c(135,27,0), c(135,29,0), c(135,31,0), c(135,32,0), c(135,33,0), c(135,35,0), c(135,36,0), c(135,38,0), c(135,40,0), c(135,42,0), c(135,44,0), c(135,46,0), c(135,47,0), c(135,49,0), c(135,51,0), c(135,52,0), c(135,54,0), c(135,56,0), c(135,57,0), c(135,59,0), c(135,62,0), c(135,63,0), c(135,65,0), c(135,67,0), c(135,69,0), c(135,72,0), c(135,73,0), c(135,76,0), c(135,78,0), c(135,80,0), c(135,82,0), c(135,84,0), c(135,87,0), c(135,88,0), c(135,90,0), c(135,93,0), c(135,95,0), c(135,98,0), c(135,101,0), c(135,103,0), c(135,106,0), c(135,107,0), c(135,110,0), c(135,113,0), c(135,115,0), c(135,118,0), c(135,121,0), c(135,124,0), c(135,127,0), c(135,129,0), c(135,133,0), c(135,135,0), c(135,138,0), c(135,141,0), c(135,144,0), c(135,148,0), c(135,150,0), c(135,155,0), c(135,157,0), c(135,160,0), c(135,163,0), c(135,166,0), c(135,170,0), c(135,174,0), c(135,177,0), c(135,180,0), c(135,184,0), c(135,188,0), c(135,192,0), c(135,195,0), c(135,200,0), c(135,203,0), c(135,205,0), c(135,210,0), c(135,214,0), c(135,218,0), c(135,222,0), c(135,226,0), c(135,231,0), c(135,236,0), c(135,239,0), c(135,244,0), c(135,249,0), c(135,254,0), c(135,255,1), c(135,255,5), c(135,255,10), c(135,255,15), c(135,255,20), c(135,255,23), c(135,255,28), c(135,255,33), c(135,255,38), c(135,255,43), c(135,255,45), c(135,255,49), c(135,255,54), c(135,255,59), c(135,255,65), c(135,255,70), c(135,255,74), c(135,255,80), c(135,255,84), c(135,255,90), c(135,255,95), c(135,255,98), c(135,255,104), c(135,255,110), c(135,255,116), c(135,255,120), c(135,255,125), c(135,255,131), c(135,255,137), c(135,255,144), c(135,255,149), c(135,255,154), c(135,255,158), c(135,255,165), c(135,255,172), c(135,255,179), c(135,255,186), c(135,255,191), c(135,255,198), c(135,255,203), c(135,255,211), c(135,255,216), c(135,255,224), c(135,255,232), c(135,255,240), c(135,255,248), c(135,255,254), c(135,255,255), c(140,255,255), c(146,255,255), c(153,255,255), c(156,255,255), c(161,255,255), c(168,255,255), c(172,255,255), c(177,255,255), c(182,255,255), c(189,255,255), c(192,255,255), c(199,255,255), c(204,255,255), c(210,255,255), c(215,255,255), c(220,255,255), c(225,255,255), c(232,255,255), c(236,255,255), c(240,255,255), c(248,255,255), c(255,255,255))[ round(seq(beg,end,length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/hexplom.R0000644000176200001440000002617013171627113013537 0ustar liggesuserspanel.hexplom <- function(...) panel.hexbinplot(...) hexplom <- function(x, data, ...) { UseMethod("hexplom") } hexplom.data.frame <- function (x, data = NULL, ..., groups = NULL, subset = TRUE) { ocall <- sys.call(sys.parent()) ocall[[1]] <- quote(hexplom) ccall <- match.call() if (!is.null(ccall$data)) warning("explicit 'data' specification ignored") ccall$data <- list(x = x, groups = groups, subset = subset) ccall$x <- ~x ccall$groups <- groups ccall$subset <- subset ccall[[1]] <- quote(hexbin::hexplom) ans <- eval.parent(ccall) ans$call <- ocall ans } hexplom.matrix <- function (x, data = NULL, ..., groups = NULL, subset = TRUE) { ocall <- sys.call(sys.parent()) ocall[[1]] <- quote(hexplom) ccall <- match.call() if (!is.null(ccall$data)) warning("explicit 'data' specification ignored") ccall$data <- list(x = x, groups = groups, subset = subset) ccall$x <- ~x ccall$groups <- groups ccall$subset <- subset ccall[[1]] <- quote(hexbin::hexplom) ans <- eval.parent(ccall) ans$call <- ocall ans } hexplom.formula <- function(x, data = NULL, ...) { ocall <- sys.call(sys.parent()) ocall[[1]] <- quote(hexplom) ccall <- match.call() ccall[[1]] <- quote(lattice::splom) if (is.null(ccall$panel)) ccall$panel <- panel.hexplom ans <- eval.parent(ccall) ans$call <- ocall ans } old.hexplom.formula <- function(x, data = parent.frame(), auto.key = FALSE, aspect = 1, between = list(x = 0.5, y = 0.5), #panel = if (is.null(groups)) "panel.hexplom" #else "panel.superpose", panel = panel.hexplom, prepanel = NULL, scales = list(), strip = TRUE, groups = NULL, xlab = "Scatter Plot Matrix", xlim, ylab = NULL, ylim, superpanel = "panel.pairs", pscales = 5, varnames, drop.unused.levels = lattice.getOption("drop.unused.levels"), ..., default.scales = list(draw = FALSE, relation = "same", axs = "i"), subset = TRUE) { ## dots <- eval(substitute(list(...)), data, parent.frame()) dots <- list(...) #groups <- eval(substitute(groups), data, parent.frame()) if(!is.null(groups))stop("groups not implemented yet") subset <- eval(substitute(subset), data, parent.frame()) ## Step 1: Evaluate x, y, etc. and do some preprocessing ## right.name <- deparse(substitute(formula)) ## formula <- eval(substitute(formula), data, parent.frame()) form <- ## if (inherits(formula, "formula")) latticeParseFormula(x, data, subset = subset, groups = groups, multiple = FALSE, outer = FALSE, subscripts = TRUE, drop = drop.unused.levels) ## else { ## if (is.matrix(formula)) { ## list(left = NULL, ## right = as.data.frame(formula)[subset,], ## condition = NULL, ## left.name = "", ## right.name = right.name, ## groups = groups, ## subscr = seq(length = nrow(formula))[subset]) ## } ## else if (is.data.frame(formula)) { ## list(left = NULL, ## right = formula[subset,], ## condition = NULL, ## left.name = "", ## right.name = right.name, ## groups = groups, ## subscr = seq(length = nrow(formula))[subset]) ## } ## else stop("invalid formula") ## } ## We need to be careful with subscripts here. It HAS to be there, ## and it's to be used to index x, y, z (and not only groups, ## unlike in xyplot etc). This means we have to subset groups as ## well, which is about the only use for the subscripts calculated ## in latticeParseFormula, after which subscripts is regenerated ## as a straight sequence indexing the variables if (!is.null(form$groups)) groups <- form$groups[form$subscr] subscr <- seq(length = nrow(form$right)) if (!is.function(panel)) panel <- eval(panel) if (!is.function(strip)) strip <- eval(strip) prepanel <- if (is.function(prepanel)) prepanel else if (is.character(prepanel)) get(prepanel) else eval(prepanel) cond <- form$condition number.of.cond <- length(cond) x <- as.data.frame(form$right) if (number.of.cond == 0) { strip <- FALSE cond <- list(as.factor(rep(1, nrow(x)))) number.of.cond <- 1 } if (!missing(varnames)) colnames(x) <- eval(substitute(varnames), data, parent.frame()) ## create a skeleton trellis object with the ## less complicated components: #foo <- do.call(lattice:::trellis.skeleton, foo <- do.call(trellis.skeleton, c(list(cond = cond, aspect = aspect, between = between, panel = superpanel, strip = strip, xlab = xlab, ylab = ylab, xlab.default = "Scatter Plot Matrix"), dots)) dots <- foo$dots # arguments not processed by trellis.skeleton foo <- foo$foo foo$call <- match.call() ## Step 2: Compute scales.common (leaving out limits for now) ## FIXME: It is not very clear exactly what effect scales is ## supposed to have. Not much in Trellis (probably), but there are ## certain components which are definitely relevant, and certain ## others (like log) which can be used in innovative ## ways. However, I'm postponing all that to later, if at all if (!is.list(scales)) scales <- list() ## some defaults for scales # if (is.null(scales$draw)) scales$draw <- FALSE # if (is.null(scales$relation)) scales$relation <- "same" # if (is.null(scales$axs)) scales$axs <- "i" scales <- updateList(default.scales, scales) foo <- c(foo, #do.call(lattice:::construct.scales, scales)) do.call(construct.scales, scales)) ## Step 3: Decide if limits were specified in call: have.xlim <- !missing(xlim) if (!is.null(foo$x.scales$limit)) { have.xlim <- TRUE xlim <- foo$x.scales$limit } have.ylim <- !missing(ylim) if (!is.null(foo$y.scales$limit)) { have.ylim <- TRUE ylim <- foo$y.scales$limit } ## Step 4: Decide if log scales are being used (has to be NO): have.xlog <- !is.logical(foo$x.scales$log) || foo$x.scales$log have.ylog <- !is.logical(foo$y.scales$log) || foo$y.scales$log ## immaterial, since scales has no effect. # if (have.xlog) { # xlog <- foo$x.scales$log # xbase <- # if (is.logical(xlog)) 10 # else if (is.numeric(xlog)) xlog # else if (xlog == "e") exp(1) # # x <- log(x, xbase) # if (have.xlim) xlim <- log(xlim, xbase) # } # if (have.ylog) { # ylog <- foo$y.scales$log # ybase <- # if (is.logical(ylog)) 10 # else if (is.numeric(ylog)) ylog # else if (ylog == "e") exp(1) # # y <- log(y, ybase) # if (have.ylim) ylim <- log(ylim, ybase) # } ## Step 5: Process cond cond.max.level <- unlist(lapply(cond, nlevels)) ## id.na used only to see if any plotting is needed. Not used ## subsequently, unlike other functions id.na <- FALSE for (j in 1:ncol(x)) id.na <- id.na | is.na(x[,j]) for (var in cond) id.na <- id.na | is.na(var) if (!any(!id.na)) stop("nothing to draw") ## Nothing simpler ? ## Step 6: Evaluate layout, panel.args.common and panel.args foo$panel.args.common <- c(list(z = x, panel = panel, panel.subscripts = TRUE, groups = groups, # xscales = foo$x.scales, yscales =foo$y.scales, .aspect.ratio=aspect, pscales = pscales), dots) nplots <- prod(cond.max.level) if (nplots != prod(sapply(foo$condlevels, length))) stop("mismatch") foo$panel.args <- vector(mode = "list", length = nplots) cond.current.level <- rep(1, number.of.cond) for (panel.number in seq(length = nplots)) { ##id <- !id.na WHY ? for(i in 1:number.of.cond) { var <- cond[[i]] id <- if (is.shingle(var)) ((var >= levels(var)[[cond.current.level[i]]][1]) & (var <= levels(var)[[cond.current.level[i]]][2])) else (as.numeric(var) == cond.current.level[i]) } foo$panel.args[[panel.number]] <- list(subscripts = subscr[id]) cond.current.level <- #lattice:::cupdate(cond.current.level, cond.max.level) cupdate(cond.current.level, cond.max.level) } #more.comp <- c(lattice:::limits.and.aspect( more.comp <- c(limits.and.aspect( lattice::prepanel.default.splom, prepanel = prepanel, have.xlim = have.xlim, xlim = xlim, have.ylim = have.ylim, ylim = ylim, x.relation = foo$x.scales$relation, y.relation = foo$y.scales$relation, panel.args.common = foo$panel.args.common, panel.args = foo$panel.args, aspect = aspect, nplots = nplots, x.axs = foo$x.scales$axs, y.axs = foo$y.scales$axs), #lattice::: cond.orders(foo)) cond.orders(foo)) foo[names(more.comp)] <- more.comp if (is.null(foo$legend) && !is.null(groups) && (is.list(auto.key) || (is.logical(auto.key) && auto.key))) { foo$legend <- list(list(fun = "drawSimpleKey", args = updateList(list(text = levels(as.factor(groups)), points = TRUE, rectangles = FALSE, lines = FALSE), if (is.list(auto.key)) auto.key else list()))) foo$legend[[1]]$x <- foo$legend[[1]]$args$x foo$legend[[1]]$y <- foo$legend[[1]]$args$y foo$legend[[1]]$corner <- foo$legend[[1]]$args$corner names(foo$legend) <- if (any(c("x", "y", "corner") %in% names(foo$legend[[1]]$args))) "inside" else "top" if (!is.null(foo$legend[[1]]$args$space)) names(foo$legend) <- foo$legend[[1]]$args$space } class(foo) <- "trellis" foo } hexbin/R/hexpanel.R0000644000176200001440000000267513171627113013673 0ustar liggesuserspanel.hexloess <- function(bin, w=NULL, span = 2/3, degree = 1, family = c("symmetric", "gaussian"), evaluation = 50, lwd = add.line$lwd, lty = add.line$lty, col, col.line = add.line$col, ...) { stop("panel.hexloess is no longer available") add.line <- trellis.par.get("add.line") ## x <- bin@xcm ## y <- bin@ycm ## if(is.null(w))w <- bin@count ## control <- loess.control(...) ## notna <- !(is.na(x) | is.na(y)) ## new.x <- seq(min(x[notna]), max(x[notna]), length = evaluation) ## family <- match.arg(family) ## iterations <- if (family == "gaussian") 1 else control$iterations ## fit <- stats:::simpleLoess(y, x, w, span, degree, FALSE, FALSE, ## normalize = FALSE, "none", "interpolate", ## control$cell, iterations, control$trace.hat) ## kd <- fit$kd ## z <- .C("loess_ifit", as.integer(kd$parameter), as.integer(kd$a), ## as.double(kd$xi), as.double(kd$vert), as.double(kd$vval), ## as.integer(evaluation), as.double(x), fit = double(evaluation), ## PACKAGE = "stats")$fit ## if (length(x) > 0) { ## if (!missing(col) && missing(col.line)) { ## col.line <- col ## } ## add.line <- trellis.par.get("add.line") ## panel.lines(new.x, z, col = col.line, lty = lty, lwd = lwd) ## } } panel.hexgrid <- function(h, border=grey(.85)) { hexGraphPaper(h,border=border) } hexbin/MD50000644000176200001440000000755313616044062012053 0ustar liggesusersb8c6e7f6b0230cdf61f0976d387c7a44 *ChangeLog 8fc9eaa3bc6bdaeee7a251d78fb4d866 *DESCRIPTION 9129a733a21f780d50b1c3bb85da0047 *NAMESPACE 98a77d0235bb074f09aa7675358b8650 *R/BTC.R b8083617bec9ef2a20bf2fb31d1f50cb *R/BTY.R def8a3ae791d6214f8093069780971a3 *R/HO.R e54503901b17f4b00ab192bef093ff18 *R/LINGRAY.R 9220834650597d3f9a3c2f5a38fb2fc6 *R/LOCS.R 47006284b4bc42824409e49cd3ebb6e7 *R/MAG.R c25363a22b3f824d1f25997179b74434 *R/RB.R 97262cc9f616661bf71e4686225f6c17 *R/grid.hexagons.R cd88d10aa75a6666b296efff0ac1f355 *R/grid.hexlegend.R 503b110bf985d5c12a0d514c333dc81e *R/hbox.R ad4a901fb8fc48deb4f76ad3d797ecd9 *R/hdiffplot.R d53fcb4dabb71c0154e881648c6b13da *R/hexPlotMA.R 0001d85574371fa9a3c90af1672987fa *R/hexViewport.R 7a92115dc09afb29331421e3c4eeddcf *R/hexbin.s4.R 5d66d35fa92d45957684ee3375513e28 *R/hexbinList.R ae5724baa7c3661621ed0018287fc6ca *R/hexbinplot.R 53e8c6ea014e06b21e56b8e447a0dad5 *R/hexpanel.R 249d47000fdc8b641cf6ed2ee6f640bb *R/hexplom.R 0b7181a5ae4cbc780f46041886fc80e8 *R/hexutil.R acf4489ea175f01eb1659a420183e155 *R/lattice.R 887f080dcb908bb6b6491acb52cddc68 *R/smoothHexbin.R 53e586900ba0c452c12ec7aed3d20295 *TODO a08ac6eda08bcc5791debab3b3a9c716 *build/vignette.rds cfa9343134507d8eaf7386167ea1243d *data/NHANES.rda e857b573460b9eba00bdb571dfccfb23 *inst/doc/hexagon_binning.R 0f5af19e815f37b968733e524435daee *inst/doc/hexagon_binning.Rnw 59bccfec0efeb5d068f0005854ce6f2d *inst/doc/hexagon_binning.pdf 3b3cb098160c79abc4d739397d315ff3 *man/NHANES.Rd bfc5169b22c653bb5912e9c3e92f3207 *man/colramp.Rd 94a1639600897389f489b6b836362d82 *man/erode.hexbin.Rd 47a11326b5056014da626fe8c3c5b8e8 *man/getHMedian.Rd af748a6a41f4a7c7cb0265b75f645d06 *man/gplot.hexbin.Rd 4f14ff188dcc89ced1434511b0da5dc0 *man/grid.hexagons.Rd 6e12f30832b4d71515a91bb8c448049d *man/grid.hexlegend.Rd 5f2695c8af33d84b154a61e3463859e9 *man/hboxplot.Rd eb4f91c7c9c4482122d7c9ee209e93b6 *man/hcell2xy.Rd 9a215a3b0ff1077d865688a5d9a40921 *man/hcell2xyInt.Rd 29e7649124c53711586904d9c556f53e *man/hdiffplot.Rd f49d784dfab4e373b90f6399c511235f *man/hexGraphPaper.Rd cbc932856dc584b571a425fe4b7ec414 *man/hexList.Rd e674cd78f6a724d5613ddc81c6983b10 *man/hexMA.loess.Rd 15c9da95418b954cc0feeec69eff71cb *man/hexTapply.Rd 18c065f4f0c331f17604d467cf00b305 *man/hexVP-class.Rd 9c7707d15c10f959d35a0714dc65b667 *man/hexVP.abline.Rd 1f4b3a61121669b0bccb6fdc4e5cd836 *man/hexViewport.Rd 92c69549ef7b876c66bd362e17216c44 *man/hexbin.Rd 1d1b19028ce04fe352f1195993b8802f *man/hexbinplot.Rd 37d121666c32d6396a680761b201162d *man/hexplom.Rd 13241d553371e3923f6647b3a7deea77 *man/hexpolygon.Rd 85e71d3e73900af44b7e88ead81c033c *man/hsmooth-methods.Rd 7ea0b41a11cca81d2093012166c35101 *man/inout.hex.Rd fe9d76fede0a6c4727a6efb5c2e3c861 *man/list2hexList.Rd 087875e158137bd1494533ffc2078ebd *man/old-classes.Rd 6ed5394a980386786a41eaffd7dd5c8a *man/optShape.Rd 9f23953a55209099110283ec98343438 *man/panel.hexboxplot.Rd 3d36abbaab3ec18876e2288151da11f1 *man/panel.hexgrid.Rd d62970352d19f6785e76d6c68f3ba79e *man/panel.hexloess.Rd 9da0d7245fb3f734cc0f07cb4f2aa123 *man/plotMAhex.Rd fc017f52b40dc804a41ea45305c840d8 *man/pushHexport.Rd febf2f7e1ad56316da2058e260732d7a *man/smooth.hexbin.Rd 886e2efe62994815b8acfcc78c7ad81b *src/hbin.f 470ef863da306fb9d0955b3cdb0b2ce0 *src/hcell.f f8fb4b9ec5a1dbc174102d40377ce885 *src/herode.f 719cbe239d3f98da12bd7f489ab6c197 *src/hsm.f 9738cce32f70c2d27417252a78d5b14d *src/reg.c ddcf0653ed6863dd0260e1f58349356a *tests/hdiffplot.R 07c2792a31643ea08be36a8133f95ed6 *tests/hdiffplot.Rout.save efe67770786c28cc2bfceef357376f7a *tests/hray.R 24021c6251d46ad71065e3705e04479d *tests/hray.Rout.save 6dca74e0501c54cede56d657a1c0c632 *tests/large.R 98321f01b4ed346aa059aec1aa3c637a *tests/large.Rout.save f94ffad94528308a3483bf6f4088fa70 *tests/viewp-ex.R 53478aa4cafb6fb935b12b7c982a667d *tests/viewp-ex.Rout.save 0f5af19e815f37b968733e524435daee *vignettes/hexagon_binning.Rnw e95a649be2460892a58230b0bc7c78c2 *vignettes/references.bib hexbin/inst/0000755000176200001440000000000013616020747012512 5ustar liggesusershexbin/inst/doc/0000755000176200001440000000000013616020747013257 5ustar liggesusershexbin/inst/doc/hexagon_binning.pdf0000644000176200001440000164647713616020747017140 0ustar liggesusers%PDF-1.5 % 49 0 obj << /Length 2269 /Filter /FlateDecode >> stream xڍX[~?G2梑T%MٹW?(v%=uH#@s=L[S4U; jmd[Я;(w;;/ _Es[eG,O{̌ɛ8 y]T1rp8~{=eӊL,vvVMUy]|\-tE6AWf|&8j!M[Pүھ:mHYU^L^ё܂TGɛ`Ě!%(eIV1662vfCk^eڳRh/-@|ۯ=ּB;{TL>*ޏ)o@3/Pd̘)oV߶_+^fE >tެ Lbcm4PM2!{V@ 6%Nzn:Kx&X_8ybT JbɈQ"b: y+9ZX#bBda|C2vט+rL{QrP)ń"ބ5T#ba.BejLC#Cyb4k3Ȼ:'WQP]Y~:/y`"]Ũkij:!X61A͉l` ޔW$ xEA;Lve!^(X ONUIK/ KunC*TY9:m.޶.vGEDw#P%|Pp7EG`'0EA,#*jp_?;W !ڞ &phbVQA|h/:^[Id0dcxK)VxCivi78](:YIuc3vtbAZuSd| J~@#]/!ajzmdJ 82'0* 8 cJІLX!`D^U'N2CLӮ*n@]i.ԯ4I'K|Ej(/{)' =@_|g2FR[pw%n-c>CR\ KiPQhCJ2Z(C*htC mԦ}=fZ ţȥ[~X?={pVo212Zb0F»lHю5KGSD7=Wq '#X<Oמn7 1vZ}{زyl.+D.X"^XX|Aw@ڟ) %xB5`}Oj.>DvmxO{"*qC$o&T5ߗ%ϗ M1{^ʢ:e~{ׁ䅇Q_WOc})eۤ^ofK=La_8nマi 8OBwL qb^Ɗ*:]h}ZZ~OHJ> stream xڥYɎS,K1d`` JbKPb)uOER  Gߗ}QT-ǧ8Lˣ]K<|^ u߬λxsdΫ"&qS | 7A"-W+ ݬְZks ~&O~E5/K::q2bkj-m#\q?h^%@Lc$Ҷ1O:zǓ#BTe.Bz:ڡ f{AFZvi,KHlakeSHFt88o)0_8 #2 .7BE%~ov{EYQJaaE?>^zIގ3c鳁ȦFC<Og&|[IP{׫i^1 O7(]W rxT/ M#&@X>1{JDc˱ۖF=&eHl #5FB'݇%Y %I-o6*. hIU됢NRE] $AF|0@:Ld WEW!ɳ4C_E.*~=+8:ޥ+5g-jVd ͣuډ ·vlV]"9 RcOjb((Oˡf@uDV&cYAԤTHJia0dnx#gTcϱHKħ/!RW蕶"cm:]QJ§l b9 .?:p[LA g[ K~R$V6K-hD:*Ps|}7w΂oeoη$u&R+d'<솆ⱥ`&K%B<ŽhM?1 /K`>I!Vm \xiU7nJ\ w}\ǖnPi#p1ޔJRSί0]:oEx^Pþ.~JrrjCF=,`Bɬ D2"3nYʛeDVY ܙaC7U4>rM-4j5 Y*Rr/4} W52l4;ewa3-p:\F₪ y$ *= "2#JTMDե˃\91[2"9}LwaZ̎؜Mca?)3e̎Q6uxՑJy&:#$jn.\v ςBim9r:Og%%=f>o1w#H[G"(NQ?ʪٶ WKر\d<@p EYy}H- FOEI@/0DBEvNDu9=`!㙐78`.^U.: а\gi&4V^ǧO.|3dz짖/|8 uC&}4oPnD\܄bRq;k}e:*'=Ȅ@ ~g I`0B.j]_ޮP@eT]lE RuXʧ)pS"-{kWЪc |W?/ 47 endstream endobj 66 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpWchdiG/Rbuild4f762e64ec7e/hexbin/vignettes/hexagon_binning-comphexsq.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 80 0 R /BBox [0 0 504 288] /Resources << /ProcSet [ /PDF /Text ] /Font << /F2 81 0 R>> /ExtGState << >>/ColorSpace << /sRGB 82 0 R >>>> /Length 11782 /Filter /FlateDecode >> stream x]ˮ-INCi%1:-A }Z}>ֶÎÎWc_~xǏm#azl(?(^=ڣ8G _C?ĥgNLV`9LI7nˢn~ß>~o( exlxyoMǷ?~7ivJͦ;ﳨ{J}Gޤ"ʳ l:5;Zs7cvF$ aRٝ 풌;`dzx׭<选nu:r:k{-z{9vΞ{{^y{OKZy__vsz=M*mJ$g%]+V>~O`lmiYv>61QiYgUXJT™6X̟?~Ѥ]إ&}c aA5i=ds?B6d_RnRlcNPBAms!{}Q=d9dh!gT'jT' f=ۜpӢc9OP3՝Y-$TP 6LTB ${BCK]t9WKp*6${iU{ɾPj+2e7u -3O8} =o ˈ|۠Z9{G zl[{5zՠۘS,ZS};쩾ZLݶȷ1|ӂRs<=a7j!ۘGMԗ=Ĕ9ɶq- #vh9i*g[b>qkVVe5m01]6 SO!{dAs6Sڌ6ST =:륥n4`^S&&5m0wA*{Υg@l’O w&=xW=3Q lc3L#d2e){t5N5H`v6mV}&D32}ز{NxnBRd`!-8SF^(8{@ٳڝRu>6<z)RAU]PD[ai\cq] #=BgA[=` 5ofF=,yRZL3AV`<6 0T`=ȁ4$sf8O,o ǖ65s6k.3!SuCJۃPs+O?Lܙ3!)/|U23L:#ObsS^el=`0l!ѷ5?4z& ĔPYEjwzݓiFw%併LF7rG{%y^ {=сYGC Ĕ`^@h0'!сaFxgODZ(.jkD>ە1y1&qYs W Oe֯d\G錪+Ӂ5}O|Q%~Z"dP&o=]{~Ё5}O d Ĭg8lG; @h nmKUG%b]6qʂejO[L 0 C Ӯ_IYu6Z"f-E='sDf-?jiZC\1%L+_IwyS]Üjdka3ǜHd*"nP)(+ wp=)}SWKT@H's"b".] \l)ozXwkԚy: !{Nw}V{с5}H/2<2/2?0aEW8eTNHǢڍSIiI4&2L:IkePo#4;]D7:khhYj a׍^;۞CQzPK034 Nv O,N `bhL  |'Ǿ%OxJx[ 7-ľe!=aİ lt` a;+1ۈݓqmđ?F|k$wv 31MagZ"f-Z__D%x^Gx^xAwle ι@!aH{a\tpCÜeQd/ىwXllN2W=DpVU*Դ\ScZMe] dvWa'?B8aXO/TCqt* f&DR08o2{%^H#= x d>-Q5Qz 4OiL@Ѐp%b %,gz4jj?o2xb| g|V'Ǩ:.Yl~xBB%ڴWmTe\~(xS<\e8uO@VߜN#JM=^bA<e aΧ4SV]x7:05?4t3L/] :pJ]A1;b"?b&|< f :0}<ˌ)aۧ~pKx𴐏ZhEc&D ռ@{Ldvٗ&; Uasm{j`bVk@(T[#تd.=VTy̗o`ǀYwܹd3#pJd.q DZSIyd:K~advTbAڒ, bqo~2hН@cjqHH5S"`Xh' y;iy;̙b"ٱRe?m!S5m0XzFJ/e2{rٺT@˾n|xU4N# ڱxxUk9RV|q&5R$Ϋhspɩ)ǷÌfpXA4$s|Ӂ/8䟦n`1=zbd>7(G*F%Sg}IDCb w :X2tf|a/D6|59_(#cFCD2TKZB<)k@<t`j k]ayvVDw.^x-u"F9CVuœV1B-ָըӖ^%Ӂa5߭91I llzɃJ:Ԡ"dnk>CChg{?ˊXj`nz61 c1 g~=}Ǽ~PЁQ2UPVZA:gFnQNjîkC^bqMЁYG 8=njvi?]ARWDu qu4zH?2!">2Bu$Y,8PO}An\ ~J}}q9n7:0/u;o-M̖D\-}聀DfK?]~ 썈뼷b?(*[w$57xovC4\ӻi850+ Cܗf*㳖Y 4.t :1k^K6khmX_Ƙo%jmL̗՟ǘM)AS!.f^cM骩vT@ṀTeXGwڹt[{r* snf!xpqs,P@A.n 7C\'vNSo.tÖ>m69>4N\c\ǝbA7lj豋vZK|!⺎k8wьf6fh6W#;[!Y#'.1߄6 rn%Mf7]6 S[aZ$.$;FzFh2P"̌3o s<{9rKdxrgaf)ؗ{ڧqCݰ9P.G ǁ}:a?xZnóKmZxk\ezݣȟIY-[3Wt`K \mĩƮo)ǃo|N5ݰں4$-4wYji3ޒ膽Zͼ G[,ݰ ]:2{o iF2?Xp[D"Nz}9%VLTWo v7-}{\K`, ]z[6[g;A7ad_%`5\VAS^h@4= 1 Es8H*aIM&DjE.ێfl@&sȶ-W*} 0E}%T@\$sx1wD:_:G{f:^qEL45lus(O|1@<"&2ň 2`GM!&b#pG.Kh]_-_bDnaA|kgຏL7lb)3/QˀgA7e*C]uQÜ`A[;XtyQZi[?3vͤjEzϧ#fA?ز=GuSo(5_"Jk9Xy]~da/SpzԘ'NS 8s8=tg];14$c"4n[\7 o]}7y+Y s |S5fXyO,i1 c1FIt`Oc2^{7[ʀӓ!OG 3=F?xbuaщ8zTn۽dEلH[ d4pM *ZX4-ZT@^sv;>XLDt~/ik >1QhMp:k֢<b1鷫j[^bJ@LE4?i}\ƾSЁվ $nnYb;N 㾪-M̖DL--r_#C;^KĬD^Kx:%G-͘ #b"/ác 2te=:j읷q s!v@|c"/N5B?p#D۞A' 3#BL#1S-8LjMyDLeՍx˘e 1yDLe@tbQ]W :k>)FmY|L+PΪ ے%3ާ=3-Ln֏q4r`#eU["s=F w(7:ɜۍ[ŊۍAF8 Φ-yrI|D]wt9Gj5D]dc?k3%b.%ezS-?j.bJ@!\dv5YM ~BtzꦱJ_)Qo"꺰TTseS<,*23XDeAfp3vQb{c^ټo2?Av41bq@c'с4Rx fg\;{/O{g^K.:΂Z% Z"f- &Z¹W9cDr8b'#83@ ψ0&yN3|r 2f\8p]zBx^b޹{ЁYGvuiC1%;w n@}]_w>ftbE$]qA5:05?49%b|g%0t`8pzrЁOP~^ xKܰ֩y mtoY o7!ݩ)Nt`68oUe fG˥7z 2Xt)X$B|FG)|.x !eܞFGQ7@(bJ4i}ȟZZיkq/:pI`[;;ǻ"?m3 ;x?4ثa!pI'kBǙCk\eh}qf`oz%Mx?4ا|{ڊ3O'rO[_|G<ʔ1""3WSu`ЉD9UK/YՊ18"ez* [幟>緿ݏƼ=?>N~ۿ?|?N {эs+o??~R!gJ@zk]tAoN:` M _ۿ%~||} M_?3IRU^e$r6S\z@njk]?Q҃8s4c3ǩO!vp氜J~TC*|o@b.|wϨnCwv &tCo0D9U>'cޗF_JYM ~ԁftIR+SÊ>~O֎p+=cU3t0O?|4[1ZĞm&/f>ui3"ؚ&]z;8\k~h-StG %ʰY4璆|ikÚ&Ono/i(6s _h\;ؑpvXDh^ZꓲOd]ġC+*FwD;&Z#Λ ]⾽7b/}wn5ΐL׻3$)%C2Wa(l^X˔%&".rћm+u"nʺ==뺚g}H2ݥAn_um5ʼz-4v3~[ { o`l6+=/=eNKp>d6x:ўkHZe׹W?_~i2|q/[yd Ҟ%3dˢpvXm{AW">$bd!{ԺАq3?~k"Feo.*D!ڤ&bCŤۻ ˔gDf8>&+IdMKr`lKYh]WS./wI=.qpc^9ËyE8k"Na&b^Yvxfz[_g+kɩcYC :'SbXf#{MOwb1un[8r1u^{/C7Y1;ӑ+&X{C|yaAc&UuDK𭨵Xe9V]!]*z{d*x2%).SrfĮ6xDXND!^%_eG{uhk"ʥ(+k"Ze-N {hv)K˔lK{3Vbdk"&׵N1+y½&“Za5/=f{jMd-bkA.llۈmŭX%D5+'7=wco-!Zݾ!Nҥۿ#vt{GNgeMv[iEtK;&:͌˹uzJ!DvID'ڷi75r| @ۏ endstream endobj 84 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 90 0 obj << /Length 1229 /Filter /FlateDecode >> stream xڵrD *mU!@jƌ) EVlld9 pRr/۷<.S֥&X=Zy&26 V.#M>,uXwo_lWl;6|ȻAfW…vw^1 U&Eq8gƿ9QM[j>>!߳cIA9ɓhh=} )Gвl\;4Yx&N:Gx!/s װY3/T5Z{[x)'Z]'dpD,/^ (3IP/c2{yYaP-FŖE+uo.lVc8<>ډSIX15\6lx?y5#[!lePtD=JHKQDm-+|2I!R9Sx- O[f.yL^B^KքR@ԩƳTLM.Zre iEmEq9NbX | =#pᵕ{`7ZS3_Nj{Ot"Tcn{+QYZh /&*5IP/TjhK N.>WӌFDWKvʴ *XO*1.~(>1ˍ&`C-~M8FkJKNۖ03HM*s0 i['|87-2U5-(F:5ߗ/gDL[6NXUA>Ԣ͞17hh-?9BTz3);?je˕oDc3Xdd4Y\lQ筲Ezv^B(3,≫$kyfhII7ʌ5.4ϦRA)N4UP@1l&ַ\Y`Ѭi<抣$N`q7^(ޭ$"F)4T%ʧ3a9U8yzǁ4a6 })cͩKFv#QnQêΦ5}&w;͐SZ'N7 B%iO^cuA=s̅R'`ڍ3zWL giɃ/@wRچ0 ʔQ$> /ExtGState << >>/ColorSpace << /sRGB 96 0 R >>>> /Length 17784 /Filter /FlateDecode >> stream xA,IrW>/~xΗ/~l:k^|w(1?Է/o^y /ݯ~Wא_ٟu>+Gz~;8n_;}^{__o{/dvz<O˿q燞[?^.^/ omxy?oort ۷÷WVscXnos_ߞha q}yu]ޮRPcޯ >V_޶Oך~\cq)}E_1f|/:|^^/=^c8@Oc̰,7qx?/a1ovq< k\g _nϷP)3_{H˾ѡtx!zu^P5F'ԋѡ=øĸJOJ1|'߶8p^'5 88R/Ǿӡ=*vG9Pzy3]o3]R+!?_Ou[y]5 uh'ԋC}c/up%^pu@ W*&5 $}_~'R/uol0>/y\p9!1CzA?;y?|9x~3}zƘlp:1J/ՍƘakZ/Ⱍqp(8cpUc ҋCQq;Ԫ PBw*8؝+lv1J/+yߙwá PBrw@ G`Ժ5.aut1fwƼMBz1Ctp%^p/JH=z|0~o5-Už!׶xGjA0Qs}5Pj3{b&!Pv{Vӂ@ Wuüg=!P`;ԸgwݼkNBš`wŸkR 㾞IH8} PBš`ݸ/R>Ky BcrRNNyg;(!Pwv;{@ JH:;9=F0ۡ=XrmԋCPc:T PB֤vX!w Ǿ%@[!]^Nỳ{\GOkeqXQ`+lA;8\{1vdl1Ptz[b} %=VXl}1V#8W(šVvS^F0EOFp)V PBѷCF૓^IZaNzMI(z:`5NzX+`kG-zkl툵%PPkE;̵## 8kK(ݩrq;ꗫ$=?q;] O ^^<Կصָ&QR/3500ۡPkR;kX(!PkR;kX(!$:5*0#ԋCev@ cUrR/굃JRkգ\s4AH8Ԫ *JH8Ԫ *JH=6Njܿ_uZVH3WTP4?mVSoj5ԓ)ꚫ(!Pٱ%1r}ԋC`wAԫZ0\ߍ`R/^߱R/^߱Rk\s}7AH8|C{сd1 PCF|?Pz:|}Y~kXk/Gkx_!~U?S{zN5.ӡv;`FO=@ EO3p& PBыC30`g`M?A8XO(кާif/юjD/4?.w뛢 ZF z*X=Xj5絀f= Bџ;@c=V`AՈiO*J%8ToʾjLBџXуV#z֋f= BџcѯV#z֋ ֏EJ(zqf? B[nzq_q1f^kPts3R(ۡ~=ulLGk^⭈mwO1ٵ~pXg| ξxe|}'Pc;X?f(!Poqvzqc6zqc6zuX*fǚ Bš:v5: PBš:v5: PBautkvF0ñwuMcktAP/VօFJH{ߖIzufv٥g:Ԧ5:ڠj_]g;X]j(!갺N:.4T#= XMZs/:T̎5;Zj' :v5: PBOP:hVٯn4hG5ԟ<76u)VC\ lԫ0{ō`R/[ыR/[ыRkw[FZnR/_O n'PBX¶6 ǺۚУ5|Nj|{ s[R_5!?0L#Uࢸ&.>#z\v8X]~(šv]|vF0EOtp.> PBѷá >hDZY/:v&#:|8X Pt@%gzttM3;LF;=E%=Љ:܃@ E/Չ̳s7A(s3t.>jD ꮽh.?i7Mw0;'$=Љ:܃@ E/]춳7A(SWPwנn;jDz1:调@ E/]7춳7QY/k8Xx(mG7J(zqfݸ B/^ٺv=^qp{Xs9ޮtC~}^^w q^=-* s[7o>!uĜwmݼwjK̹{^ps>0^o%^VNgJH8TGJH8TGJH=)տfzv~> PBšv~> PB֫'3oMcdj?yn*4AP4ۇA.43Sd0Q reVh9@ `9!rD(!'9!sюj' r<'xH%^V. #@ `9!rD(!P~;X s ̜9hG5ԟF rB䈠jW2DXZ r-T9`R/!2Ed PBšL5zuX)3d1AH83v3 0rWIH8lE5KIԫc8q^N0աV;!‴K_΂@ WJ[0W3#ԋ,QE %g5HgAP/"mL_Ό`RH[,h^$(8XJH:T*j2E ^t`'Q(!}&FXJZ f7Ϣh*A5LTvTC 4"qVC=i:A'*O\IԫC%v*$ԟ:mWj?v2k2z9@cI-\j5˵K_΂@ ?:vj2zi "RHHfI.h^$vI- B "R/HfpI.zud3e3AH8 Z$ PB%+UyqKC$ G1|śxnjrO;[Z,#w`v!S, W0sH'PBC"ROcO*2KdjW(M33KfP/gY"RYȳR(!箶>M3Pf%j?wBVAeJAP '5MvTCsh,7E Zz 'rS PBGfUF;^iT,h#S2Vd PBա2U;̌!LX@ d*8XƊ JH:{t1f)1S$C>=n?#vO5.Pp'߮qK4zmgfܓ\$zFk a%7:$I!Pɭ,E %W%7$IhG5+͑\[XZ r+%HzAk`%7$IhG5K\$ PB[XZ '~%7$IhG5ԏss 4"VCHFܚƒ\$jW~'EUfLF;乩4"VC!h_KL9,ư^=s$Eqύ箘ǘ}=Zd앖{3]OI'v8AcI;xj5gH0v&q'PBi#]^簕Ac9uj5?"Y7LڙčvT#z9+Yƒv$jD/4"R8h,GjZFJ)if*n ́KڃV=?HpI<PZOgkU f&LF;d KڑăVܾ^g]I5h,iGZFBs \4_i3if$nџz:Y'mOIՈi:-Lϙ@ E/ KϑV=E%HA?Ftn31FND9h#q$ PBџ^:-7LϙvT#z֋ Kđ@ EO$`8X"J(z9vfLF;=EZHA2,=G%};TܒU~-֯Wh k[-2o+Wܖ>-rX^aӓt\-șsR7W4eJ=%H|ԫJtI2 Bšc;XJH=eJI2юjWٯcXZ Js mUrlK4V^Jt0ӣ BO* 6HAP4GJMc0cj57I3d&MP?h$ѕƒd$͠j?NUrlK4V^i.~_ 6if̤iO^7ƒd$͠j?w 9Ɠ'ͤj' #f̤9 &!hHMcI2fj5K0d&M#ԟ[ƒd$͠j4?+96%HAP@$LJvTCx _)i,uF* Zz2+eHAkǟJf&LF;^ꭔ:#R/2Rg PBaL:ԙ!POdOh1uCt3fq;p315`+v?SeT˿U.& jսbf>g>DOM8X|J(v8串i̬Yiѳ^M8X|J(zH~ ˟OV=El)3s {$!WȧAՈ^hMX|Zy!af̜F0E/H:ȐL3h?I+C2edΠjD4?!ff̜F;S?<4)#sV#zٚSY4_YmXZ]ȐM33efNՈuyh<z>MZFMfJ(SΛ4hџwȧAՈgfiPΐL3hѳ^B8XNJ(zH 43Sf4QY/r!,'F %{IjeHXZY/2d;L ˔9@ EOz6LPⰾLc&t;8 =`8rs(a}w5 #g2oTK8^ ^^K}_&O{nr~j549?hveqq< ֏zוIc<{j543ƲydjZgkqy; ֟=+_vjZWn۞ǓVi$=xfq<մ}8i,GvZBSZfa%e:!t8+U7HAP/VRLΙ`R>4#VCpXʎZ r+)a&LF0zdJMc9uj5NKΑV^i޶;$jU~;\hfn񦱔)s=h,>@j5ԟ;7`@ ?:׃r~VCB3s~z9pAԋr=,>@(!Pf}#ԋC=o1C=oz5CP*w;fvxzُXO{F:>v+b3KǯRO17j|srsc pgj]{V^t\-ܽ3QNdQ-cCMQOc;)/4s"1vTC} >EcVC}5{Ƚ #kǿ4{AP/b Ak{7ao04=Dj5+͑k=Dj5ԟ<7kh{F;~gP{ ؛Z@c{7Z Js`{ M3rohG5ԏss4=Dj5ԏs}} HZsTK4ܧ}I;g%@cZ 7/4s"1vTCu%@cZ Js[McZ 齆v{7as]`5bo"h^5bo"z{F;\"CMVCs} >EcVC\ ؗhOF0K)b#zuX߰CAwZrdR/NI(!t蝏r)yrݎEq۟s3l-]"vl3jK̹}O[Z>raO:pMc Z Jwf'~j5ԟ<74{AP4ǿ4{AP4vj_4s"1vTC[k_il"1V^i;~k_il"1V^i}0Q rGv؛%~{A =Dj5+@{F;~nA54=Dj5˵P` JH:=:=C0AH#;kO4G{IP? #=j?IĞ@A!VC9ob!hϭ #=PnA~B7VCNMc Z :5f=ބюj?דbil!&V4?hO PB%f'~юjzkl?!@ ?hO PBaa'~ B%oW=z杉2o`rOx\DI1eȰ|o3 ̨avT#z9 6h ́L43f5Qy- grg PB%#k^葿Pٱif̬i ͑eX4%#kV#z9oWȥAՈc;,Yޣj=i,KF ZFBs$VveȚAՈ^i+3f̥F;=L8X\J(vX%=k&^*̇'$oAX>ZY/2^;̗^) 4"V#z֋q@ E/afnF0E,f݂V=EcA?{vk2FBs$UenAՈgY "^*f݌`bpl-PⰞӡ2$};T{ =Z>:Z^j?&tmCa8TjK\Ȃ@ W0ST,'PBpgXZ JsIJXMc+Yj5+͑+fLoF;^it-hʬ"RyifDfH~\ii,Ez ZAٺXX:Z Js'if:fo7HoAP?T4"VCwRifThU +'Ȥj? G"$L Vi,MF ZsǦ4i3hOJ3юj?% 6HAPB*mKbV\wKh3z HAk zXJZ RoR:̔)!P,F %^*HAԫJt)5S Bo@c̀oLCv|;ЋC{;Ԙ;pH%=ox}/oe(GGTt-[wg墘s=w c!=wC;nh?|h?F0Egn~@V#z9oГfюjDϳ'J(zȿ^4cO h ͑on~@?0QSjD`?4?AՈ^hh?F; @cZo7Aj5dh?F;S?b hџ{?h|V}tosO`LB#=s{9hG5?uVs;h,GZF:M3s||ՈܹAnAՈܹAeZFBs7I33 F 2 p{A03  =Ix;`ƞB зCgr{=p1u$Gxj鷆-.Es=3NIG8Tl˞M@ W0dM'PBp{XZ Rov<y3zof̛F;^L#CRߕ 2bdȠjz+a̅F0zؕr_ jW٨r^X\Z r+afzF0znMcY.^j5ԟ<ݚƲ\dj_y3e~3AH=[(!髲ifˬZ >nMcY.^j5ԟ"5ezAP/B1:|!VR䱦|-h1cMc,[j5ٯE2 ^*7YA=$i,sE& Zz2fLfzq"R/ܶ45fꛄԋC-vq0Rc>ۡRfgz:I0p0siIH=iv=x}/pz*O17z8qa 1箈g<<=wۚӮa7W4Qs~d[oY7p+šm;̬Y逼 ˯o@ ExeۦY7юjDzW`5m(逼 ˯o@ E/Aaf̬F0E/ّ]y4_#V#z֋ ˤY@ E/IؕAff̬F;IؕWAc5mj5GeȬAz$ʠM33ifVՈG^ȷAՈi:WϷIk@43fѳ^dP8X&J(SΠM33ifVՈ^h$NUX~|ZϝUX~|Z@ZC^m_3F2W`5m(逼 ˯o@ E/Aaf̬F0EOdP8X&J(z: !c&ʙY{ Pc02ofI(vu|X8Z?3Q-Yf32L)eP fbDezq@B%HTAԫCv)(S Bp,UB%HTAP/"RP PBաRO;)!zF?#kKAV^idXX Z ' RO)hG5ԟ<7HH*hDꁃHIAԫC%v& BOH2d'hI=!U^h kVz^2LIG8 KEfnz ҋ,[D%^`y!D(!Pf^h2Og4"OVCs| 'V^iM3EfPB)APB)AP/Zv9$s BY<[xH%۹ifɜZ R/r,DN %^%`"G(!Pf^AUqFe XZ R/D;l!NG2c8^og20AH8Ӈu @ C=;x:z:^mflPt@_ s%=胃@ E/ի]5A(v8W4FZY/Z8X}p(}2ڦ}nF;4GZϝ8zjDܠngl7M}Ika;}-hύ>8hѳ^p>7 PBыC0{m`$`etЋCu0;<`$`etA<8X}u=sůpٓeOz=Қ{`Mv<¸J/u4R/u4Rh1AH8TDJH8TW֥DJH:K.!t8vVW4֥DZ Js|oiK.&hWAydgbzqn#z:{wm$R{&ۘzqC"zuXf Bš:v!: PBšve=N(zqCzۡPA;XD(!vPma8٣LBšNg;Ըg߃kd5n]ve]; qG}mn:`Bt֣ЋCu0; ``BtA:8XD(š:vBvF0EOtp!: PB<lՏ Pt [gcpXW`lAZWa };Z:J(zqu:(u:J(z:`]^j]m:lPtv3N!WI(z:`ՃJ:c8@OW;`:< EOZ_jN"װ}9׷}G Vc:,px0W\a`^֊A[Ab %l: J\1a  l:,IdK0\&aaIt5*ְ P$s5aaIt5*ְ P֋CIkaI5Ik$W&֨XÂ@ [?k85*0#WbVXal 1^Vңf@5'1^֚D[b %l:i:nuPP߻K8I {Q$ߙqt5*װgn5t[b %=bV\ac8@Op$V PB+l&PP+F;$W#p{m1üۡw'qw=V G' 0 c=p?J(vX}Z_+`*y_20^>vߍr(!P; `q_2Pzql;}7AԋCgq_%^kntјauq;a0XyZWcoxWcu}V?z]F;`՜WcPzq{Zp(:{Zk!P+l;`jMoZyp(8 cq5c8^jk1CP+2C_׳_IԋC1j'j$1J/ƘS; 5Cac̰xPz<ߎ׻}z>qn>׹v=<^c8^pn5C}9JyYր~t<^v>f_cۡ*<^Ep=á5:> ]~u4- =C}㏱?q}.w|6HMiv7 F"gXwF_z귏:K7y/ÿvm{SoO/o/ ^kMeoxڷ׿nʺm s|y_~|7? ؓ/e{[Ʒ>/v~Oay<:N8^zꯟ&ӯPe8^ʃ?ŸZYOCzzrCelrg-Z޿oH۾Ӗl`?_O*7g-wcSk_Wή?Xfl`5^7g-7?%?ϏZ6?gM6q~ko}ln|E>/[?{ؾ 8_K5NK-=}S>/(Oe}ϰ'|ug_ާ^}!˳yOeKEkxw5;x?*|5Sk]cK_>zT׉i-?kc?=eIkySgk^OKc[~c7mNJ1{پ 3p zR|}kk#KbIq^~׷5}|=wt1Þ_g endstream endobj 98 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 101 0 obj << /Length 2230 /Filter /FlateDecode >> stream xڍXKϯQov[vnɎ.;H=)zߧ_A4$FяV)2.Jr&իϗ$7y"z)%d/g繍[IYb%Jk}zܨu2_*sՏ^F_60xDo_Z~O9_3}wSO3m?ؾK[f~Tt,MS:^$\RjBF<#6IVШJ j#ӱCw6` ;]횋pU^7uH[]yu ILR( HH*Igv}v/PA=d*c~*/빮p !5N<̔@6$K-0Rx5g%&IqWL╔p]8q!YT3/Rڵp 1Hŏ#ރ;}EEQg{EnwK9L蜎gzÖd =82gz"$$0P! /;V( Di@F(​w6t 3Sht6"ӉL+n6]<đppFkbNST%I6 qßAD<_t% RTJEq`7S׈E?#E6໢l|Ff Mq;5"f߰p< XeA}oY.'~f Wz&$j3I-駯ؒ<}fD:lN8 .|)F0j8/Ei!+Bn0͹kƁWW/8YOL).bA(!XpS{ܪcVzぽ,"nҭ%'"pS/2;Y BLziGx6Ĺ!uw~z!!n TNeU7_Ռ= e/P0frE-ҝ&epz q "3˔| ]bz_VYz:H[9>n>Z]sZhO3Kuq IUCPIX˝:O0rVvʷb' 7.mZ 3׹`>ۼ{ڙh$adֺãy :Gh[}7j8JrsS'U\_;2PrT~zeB;GL͑:gF d|?w; 8D29̤ٕ++ka;P9͝h hQIv .LZkrEdWYẉ#{o& lҔh.twB0E2oӼQ⨇qL4w."LT)\T#TުL"_mI,V|AS/?L@ endstream endobj 87 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpWchdiG/Rbuild4f762e64ec7e/hexbin/vignettes/hexagon_binning-showcol.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 104 0 R /BBox [0 0 504 288] /Resources << /ProcSet [ /PDF /Text ] /Font << /F2 105 0 R>> /ExtGState << >>/ColorSpace << /sRGB 106 0 R >>>> /Length 89319 /Filter /FlateDecode >> stream xM,mYbF %@ ,F}FY0373o u?a~yddfUu^?/ß_7Oݿo˟{?_oO~z?oO,uϱ|z]Gyzc5G?XOa?6ʟ>?>۟WQ?گקg_i}K_^>j{_CixyciߞmuXҎʗiyrct'x~ҏ׾/_b$sӟw﷗?c=?>>Էc:)ߪ??}xo7ԷyfcB)o(~SX/_O*|{ݗ=(Mjtv.Fǎ]k ]|myy}lS_nWˏ^r{W^_|vķz{?6zOX!O?w6.y~Ϲ]z۫},J?~,Ǜ~cC Gow6ϗ4sX=^'mx>ϧ7U xzP>UBU(U'e~f֏ϗ9v)v|QUʟǮ;+TRU 5˚v>DiqԫXg1F<_O䫏j9z,Yb@NcW?>STC<_7ƒ~mS͎KֆXosz~+}tX=^'zT=>z'k4RNNJ<FJU=vV < }+TRU_^ޟ^UK6u5qy8>_9x5qcx- >p&&l <%JS?w~#}r+᥸رzNʟW˳+{7u;Vz(Uek>CuǎJ{TX⵼/ f`~x},&}QGj⩍7wK>S@%_㾨ǒ!]3Ϗ|_9}uTV<ӏ=e Kk?NԎwbOٸ$ڏS?Xat>nP_ާ㾢jb}_팯g]X!v7_! G*_z+uX=^'ϽNU^ytmEGr>-zJŊU²\;fOƕ>5FlK[J_l\#ǥq.;Gjb>vc÷zxz;VIqgռj+Tr=+Vjw_N#T=zUh4RNfոώF#T=hV뻮h4R*/fkjj@#ǥqeՈ/ԫ>S5b}|LT;>53UkVTXY_ƾXՇIٸFlypjK|z/O/ovX!ǞR~x]kĪ} Gw1wiT;UŪH9U{ƝbiT[({w juK:#oq#AtF.Ǫqcv4)U7<_Hiuiݽ%JSljiݽqj7$ՎӺ{Ugjur>9*V_4~Sj^uMǧ +TrWƵXiv4)qj\ufGrƕXWiv4)U=;=DGGj"ܬOU1#/fՎk{]R>m>z}"ק*Fرzr=VeY[ _رBCe7NJ/=>ֱcŲ=nG,7qeKá,V|G~8Tz6Dzqӫbt*qGbٸ?ս+XCe[ n^pɠnsTM (|5T8n"mJ(~*~,rWIŏ{-jIŏ=jIcɗo¸dCŏR/?2?c9pz߾ax\?zph3K?EMi,YnFTziܩX:o\uW˛%,ziܭX:o^ugNE wTzXp׍3Ҹ!tY}Z/"K=nשҸ-t%Z}Z+}umLB@9mL %ܤ> ς7"3`nHn0kUi/'7;`M,$}LY58a[ Gj_/l˿ybzo8 2䫑-X<( js[Eek5⩍}sM8;׈#Lm,jkOm쬬moùs6VԮ\#[Y;ވspxjcsek{'5⩍ݕs:;׈6Wݶ\#Vmm(hFlձz{Igzu8b Mn{lZFsfK(ٴ>/l toMӘڹJmnh}ϕy>5+ncفzxIVOWY!v⽓&+Ʊq~]Ͻ(׎zgm,jwFQ,Y⩍msoPkĪmk/НkS6dFZgm,j&_pOmXN:;׈U.{rEg8h/X;F{\#O 59m)Ja59ҙo)JasaDX;}I\#Vm o>;/r bIGK,i@!v,Mtȭ&v7MӘهM:턚֧1sCDrE5-Z hAmմ>ʤcRtPa5: uZndm{&pBOz2v(<"pB[P:`2KLBӏǿo Wr_͚gx8hX;W{\_{iȑYQ _<װ[Hެ(}/X3rSkW>!_uo'ثgz˲{ҍ)O&h5O3z>Kwm_N8zfyO&}eMӌ٧"MO3z;N^j{"{x'uH/V8:^ pIKmN8z@奖ZN8zfǟ7vfDZfӇ3x/(J|۩ s_(}6bm.pq[m3NN:;V;%Նb_ΪsIlaX;=U;\Om(.OU;;S"Gzv\E3Hl3vvQٹ$0;ާQuv.~-"GPE3H|}{Hv[ c9wKzg3%]ۗ5O3z9+=CkiFg&}eMӌ⹡'#MyO3'Sh5;Cz G!=pMdm{&p[|_\Bp`WRޟ˷O^Rv]jcW\..F4f]>\\wvOm3N..;׈6kOkWkSƌӧ5 cUgjӘvrqٹFڧ<9ҧKʘa3#kOkWkSƌӧ5 ڙUg7g@y1kNbFrg׆$]veI5+%t]ە5Ocz9C: Mo!vOMv rO֧1I4餶*ژs!vZMpNNj;&pB[8'uH'V8;ZNk8,t:` KB[X[9:@?n,֬m'8@xJ5#ܷSI@N_خ:;׈UFk5 # 5VgԆdsxjvvٹFg4H(}H$GyrM38N<$GvE3B3J\g8hFY;i;\#߿s/Jt[gs- vZ0|.H߃k|/*۳6bg~U4_mZIp4xnmE^w{iLے‹֧1|hoܴ>鯽S̢I=v4N_&MӘ^4~{&pB_IS|yEӘ~{uZݏ>/m>o(?FB_ƵoY;s{\6ĪM[wgԆ]ftspxj.vٹF~Tۇ0v=5bӄ]GM3Xrv_ziɑrQ #aY;q\#O$X`r#n\>È㌃HSһ.++'iNbK3y_Ѥ^i}ﳗh oܴ>/SI/r4,;]w8/}VgEvߢiLϊ&MӘ⹁M֧1] v&pBO~\BxifVU=Z;` O?񍺎cЏw_-q<<\~wD>ӽM%kCڴ]mwvOmUN޶:;׈U]%GE3xf]etmsf<79ҽ-Ja]ErmsxjÂv:ٹF/IѤi}_;7t)wiL?:DuHǸe8m3Q4lZ6/:c܎ Ӂ1.GoUkv:[RuZnϚv{7kU=k%-?9ʕR>jjWKb}'N/N:;S7Hծ(}m]tnCNn;iF9ФNi}_ӹrz֧йMtrA;nl:; ppc!voM쌛=|nEiFoCy%5 94+,ژf>W|Ϫn iFog˶pU퓾CcO|{;_o,K_N˗@~aVm,T:;׈69kOo_kĪMcwgԆ1g⫳sX/|+gcWgԆ1g⫳s cgq0H.(}ljcNg&0b_~{iɑ~Q #9Coԗwq?Y}۴ꐞ{{&pB_E{{iLo7C M"M˓/Zv-qѤ?i}_E^~{iLo4ghoߴ>ʤwW7~:ЏC:?0Vۓk[֪pth'4x_q;t\>^;P9j-w[ΙKֆXOS[rm'1È*[rm'\>È/#}qFliɑvQ #t}4鯝:`Ѥ#ގhc_<7pIGs4&vMӘ~>'tꐎx;&pB_SISyEӘ"+lӘ~>~y:` O1O㧜8:u0߀xŹ|vķǿgtūsXiQt\#ڰ=suv)G Lt홋gqH:HWܞ(}_;HWܞ(}  r噛gsQ#]q{F||2#tFl',39A.Ja59k/Ja~5{p$B0s".t۱7bKuѤ{i}_<7pI}4)[M֧1{:iʽ/wh}ӋF\ґoNhK{hґo޴>/}uѤ{i}_<7pI}47s?[kvtݽ֤~L~ϮXW&pB[|XW&pBOקo5+us<Οb(׎6" kgSkĪ}sCLCgqxրJNgXELY2fqHFUȔ(}Q39u5kQ:W0bq0vJٹFl3FBLC2fqH?4Y(};%92 uV*JaCLCgqܯ߃k@: UTjNbėΈrH2휔9/}n{D9h礦iLUM栝֧1ϲrh2Դ>鯽S=rҢiLiOQFMf61s$L;S5OcKBI4vjZQQA;'5~:;p vKB_rJVɤX4y!NbMxX'ĴV-֪gGNhIS@7aɁ㝗2qx^^O=ȑIsJ%.8'PEe\#O92]t(Jaė592tN)Jaq" z#H產F|}AL!G4E3X]IrJwvیD:0q3]t5b q.:{0b}2a GfNE3X(YD7w4SۜgrX2)$Ѭ>mZ}uHA8/}EiL%/t;4OcKr}Ҕ_`4&NMӘ;E/t;4Oc@4vhZFs"DbiL0ERJ֧1ј"!SNMvH4Xgrۼ4gg&pBO+X5+_R>qفzu[K|>vgㄩk[ ugxj#vNo15 >`6h՞*W2 .T;\\Om8֮yTȑSMQ #6ӿ&-jgq~/cP!GN5E3xs,I:;׈}pTҔ>ÈrdR>È@ڙ/:}TgF`>sxj#"v&ٹFr( B7w4S[}xxOO=w>_E~{iLo—C Mo54oZ)O鯝TXc4754AvFiZsGcP ;4:ϱ֪)j$4u8~Vo:` M&pBӫ}%~YQ,ۣ6jWNםkS3tʤ%jS<pX;N\#VmԮSi;;׈6B kg鄓kĪ}92t)Jaq" #3L'F<3t©5bpTӔ>È ڙK:dx"[!#3L'F/83"rd4T>ÈϪȑ٨SQ #t>)BVs#tFDik$IL/%&uV8/}"DikiLo"1C& Mw_&&TZ k4(1&NXEӘhΤ $&d i}ϵvjj'4u@QL:; 5Q!M%Ocz9[RCIg'iL?gF2$Nhzdtv?~FoEMU;L'! #)e,t1׎_ijsWGZYKԦxj#ްvBxDţX6S3t5⩍xڙv: UgjJ3BdT)}ljJBdԹ(}3t5b+rd2T>ÈgFδY:;׈m Q*750bq0ްvBٹFl3H(7ȴY(};# 92t*Jayyj &:g  s:5aKX2Ԭ>ETrv j'4u@QL9;5ҝEF4rv jZFs9R i*h}r"A"Ո&SNAMӘ^$LD;15Oc2!NLMH5)g&pB=jHS)gEӘ~eQL9;5:i:` v Zb:NhߤRY'P|فzpntZݚMWƳ{˴Yg8#{d},ԮDy5ȸDm6"kgUkĪ}x n#WgF,F(ԮDUy;;׈mP:o%e0b8ȑ髳YQ #sڙ:oUg{_øEL_͊gqH5[U٬)}_:fȤ9.)c_;fȤ9(}q3}u65bDrC"GfE3XO(yVv_z'DYjg$ILo";Cf M~&];5Ocz9ӎYܵsY4(gre֧1sÜ%];mLc2!ZMNYjg&pB_rgYܵsY4yءZ Mo^x~&];mLczOkU专_: ɩC&6Q:dɯ ӁI*٭'x5;P|$}.#խd#o:;e]٫(MFa<2qOmӉ:;׈US4pTDԔ>Èڙc:Tgxo] #3O'Fl矢#3O'Fl'rB92t"*Ja`pA1rsf<{_)(}ό.9SNuvی'2 92t)Ja3#b kgSk>9Ɠ1tӠ>Ţ_vgKWh2|Ӵ>m^duL3K8xADdgiL龨 B$+,Zv d~i}_CmDYggiL?W&:d~ 6Mf֧1%lC:+ -ZFswDh禦iL?s:d.ڹ 9H2NhVn3?dz'f5+D, Mo#i (> DZV'Ϸޟhxа<^+ҶnZuv.L: szG@#GJsM3H<hy\v.k4qd^4W>{g&kg9N?GNsE3H'Qٮ_S _;sl/)c|w֎'́g9Nd##s`Ģ$x>(̌(g`B$H' SH|0II&˝<4'}Мxy$ɡdg4wķGL;6O3HC)tԦiFmaMЕRO3a,w, w8tȴd8&&ɡdg4yt82-4N8zħWB\N8zp鐩n"{v&ylh2 9>$n:ɜ*x 1 GonL$תTz|ĵ:@?>ur {ksWTe9)ڈc鬳[B.Y⩍ڙ:Ugj_WđXQ #6 q *50bq0bv&cٹFl3x2EL\NJgs>5"b#W籢F|| b#W籢Fl'~ *50b}:A"G&cE38N5D,rdÈڙ:cUgFbEs D0'2 X2Ԭ>ETrv j'4ϲRh2Դ>ēVd)i}'DӢiLo4dzi}_JKU4 Ӓ:dz |h2i$ִ>g^&+v"pB[tZ<+3z& "Y&Nb oݟ#e#~﨏<\%^)k%%.Q⩍ڙ:)UgFaBsxj#аvN?ٹF )]MwvZD!GN?I38NHqdS>ÈrdS>ÈDFC!GN?E38NIrTӔ>ÈڙY:dx" #3K'F|\#А#MF㶙|d,I(}5P)FgDBI4'1U I4vjZFs&"!&NTMӘi?%M&֧1i*1Dh}_۔Di'iLO"!&NTMӘAM֧1ќIHStW4͔HSIl%EӘhFdj۩hc_<7ogԝ1s_<7Ȍ 3(hkU8~t:cЫ}M_-q2rWkGy1BԮZ9;;׈6)kgR[kSє3v5⩍hڙT;VgF4eLcsX/!9*VmJaq)92v-JaqwőIslQ #&kglZk5&92}v6-Jah JcgqxʉhJLcgOɑIslQ #&kglZk>4&92{v2-Ja k<HΥ c)L;6bz?383_w &SNMӘ?'24Rh2uTڴ>y%&SNMӘ^4JPIr%ES(9&NMӘެ(L;i6Ocz;Hp&pBۼ'2 Ӡh2ش>/9EAT:\q4vnEpǦiL?:dۉ AkU̺3g~RYʄ\>^;g驳U6.Q⩍ڙ:[UgF\bLOsXPQ\#VS:/%e0b8ۀDy(}ϹFbLDsf<<:/0b8W8QRS #v&"92u^Jʘaq%92u^*Ja92=u*Ja~>N?$GVE3X?(yRv۔g"$JI>,R4tPMf֧1Ӝ PddYi}_+'rU֧1ќyT$dnڹhc_ŕDi窦iLo4G&3`MӘAMf֧1%ߧLEX+-ZsgNRM;WA: 'C榝 MogsCdls?uZ<%xXw<Nh逿\\th'4u8rtZtMZ>сOsZj}L?yG|v7uW?ǟ\Q,YbRoV)欝9S|uvOmsΜ):;׈69kgN_kĪ}wHɑQ #6C g8Y;sz\#)92w/Jaq/ ē#3}'FK ē#3}'F||0ă2}%Fl"82w/Jaq)/92w/Ja`0g⫳sg<;0bq(x'NL}TKߛg1Ӝy\4w~oZ>o|{4+[2sLNhK9elT^|4tWMfɛ֧1\xr+;7Oc!sM䷔E9ziLo4 HT^|4όw&o'4u@nV;g7: 7C蝳 M?j١RJV:` DJ_X|;yu.̇Z?^eȔ(}QK3yu.%F|bJSsI(L^˒2ff{ODJSg8TI:k%e sH)G|GZE3Hbqd\V>q>~GG&eE3Hg~dV9} !|[$ag;5O387'dž&oMӌ~hǦC泝ߚ G.<&g+-ZfNs d>hcr7V&oMӌޮl&p_scCl緦iF4gݑDSlEӌ>tU7zpiM3@42=t:~áxt3y?O˗bxȞıveNVǣ7)@yRuvOm 0#SKgF'~~  X:4aK׈X2<Ӭ>o""&3MӘ^4'ye&pB?ODye癦iLgDB>!M啕gOcKh2<Ӵ>_h6;4Oc2O!3Mdg&pB=L4\[$rϼL@ꐉh'&pB[$ uDS8l:` v&KBӏGTy_-;t9~zQG|v7ڈ*ɥsMuvOmDҹ:;׈6 kgr\SkĪͨڕ\*tgj_y:EL.k2f̈ڙF:Tgx"Q!~#HgF<3"Rv&ٹFl3DrTҔ>È!#K皤FO=*ҹ(}r92t)Ja~>N82t)Jaq sKŚ)F$'}!$34I",;4OcKdi}g/M曝֧1ќyoS"S&3`EӘhś*ִ>E'dꀵ*|C*=q.JsSLl\>^;f{ȑXQ #6߿ `È爫#s^F,5ɮ:;׈mngq}kɮ(}3uZ5b4rdV>ÈOȑiZQ #t>IZg٫;/]RlW4y!SMtT>M楝֧1VFZNhz/di}_CyDhgiL(&3HMӘޮu\sO8/9)TYg4yM!2M\K4X[ϵtk@?7ԁkUdĥz'i8 xkG|~4Dy:;׈6b kg TkĪ}*1"#Q祢F,ԮS;;׈mOȑ)3PR #6Okȑ)3PQ #v!b 92t*Ja#ְv@ٹFl3HH5ਔS)}Q3t5bD"@!G@E3"֐#SNgF<Q3t5bL@NH疊5SIN/d'Is;ph2Ӵ>E<ovi'4k]yF4oviZ3/ ;TYg8/3|O4*ψ&?MӘhΡ|O4r}DYhgiLW*J֧1ќ&sUEӘ.`nwiL?&1ud&OųgZ<Ә~TY!rΑZcK/]8x%_?mX>^;<QY&C.Aqx‡@Fgފg@gޚgqȘd|(}!3su"5b﨑#YFl'92uz+Jaq/QY^S #zDx#GfNzE38N92u+Ja=rdTX>È|/ȑ3aQ #t>҉av&{;6bKeAd6ٱi};͉l,(̆;;6Ocz$P4#wlZQdʆ+;.'4u@S{;6腧{ɼ`4y!3xM͔DngiL?2C岕TM沝֧ۚ1%$LM;UeZ4ЋAovN<^+~d:CB= >ͩ6x ٹ$G`SosIlڙ:UgxjsG#GeJlM3H<V9SXv.T;sV\;wȜ)(}m#,vfNVٹ$O?#GeJVM3H'#,#S'$x>$Ng9Nđ٩UQ jgTKb9A: UXjNB 9uCIh'$IFph2 Դ>q"gh2 Դ>ܜGLB;)5O3kw $TjZj4veLX;mL3z9ЎD54vkZfCD52aN8knjh2aִ>m^$*u"p{#%MLM;UAWoh25T'm:~ӳ逧io$u3u4V1u3u8wxt8^:,'Gʛ~̗>oܮ).m{cڕ:eB)f9S\uvOm3Μ):;׈U3L3rdNW>Èo2]%F,8L׉:;׈mȑ_Q #X;3]'\#f9S\uv;v䨜V))};:0b8#sZFg+O:0b8-ő^Q #q"!\1L}QvKfg13&r;5OcKce7dYi}g|CYngiL/1v|"pB_ Dl緦iL3&zMӘRvMf֧1] nYng&pBۼh*\h}ϼnYngyynYng&pB[7wÈ-rdTV>Èš❤*huo'Oy$SNYILI4vjZD&d)i};鿸94vjZsU25CҾ$LQ;emLcK;Rh2Eմ>M֧1\x>(L\;5Oc2ءRJY Mo="3̗ӘESt;5: éCf6Q2:dۙ W> w#Pڙ^:TgF\aL/msxj#v6ٹFWKeFl'$ 92t*Ja 92t*Jab92uf*Jaq_GLE38N D&pT|Ք>È/F&rd|U>ÈĿDLPgqÈڙ:]Ugj+xKLDCKg1Ӝ&LC;-5OcKחҏh2 Դ>/}ꔔDi'iLiPR"M%Ocz?7'r h29dմ>LARM&֧1%W$LN;Y5OcJ4v kZsweRbJN+Y-'4{$x_)kiLo"UCš Mo!SNaMxXĝo_,qb^_Q,[>Cʉ"GDm6!kgNYkS፵3u%kCW~S*50b8{ȑY^R #69:0bq0vNoٹFl3x"@FgފgqQ[S #L@Fgޒ2fӿHgފg:0b}Gx#GfNzE3XJn(I^v۔gRH2픗974vkZD6d)i}_O(&SNyMӘڹaj#MOcK{Rh2W1/JmS^4:d2ɭ ܓh2ִ>LBj#MOcKWM4v+ژ h2Dش>dRc;e"ZoCfTfO&8@:0N} [<߲6cjWLȟem,Qb%k{\K>SG&ΏE3H82!v~,JA`CJ} sI3י(}mF<י:;>*L} gfDtcLrsI<PYe\;=ő鬳[Q 92uv+JA}E#GnE3H'~: C :518'O,vkVeNs'ND n'iFUbM&֧Oh2״>/SLlޢiFmRbM&֧5?t'L{; 6O3kEN4vlZfCĦvk'5FJp+-Zf6/S:d*۩ pkU\sa޲ J٦(J|[~6 kgs<:Q,QbڙW:Tgj#tvfN(ٹ$ڧ2 8*TiJAb8W:$e p0vN3ٹ$O0C6|2f88~fȑ٦OQ _<3lɧ(}7qdS>· @:TiNBkgD)F$jvIҜdW Rh2Ӵ>}zbDfiF4g#Rh2Ӵ>FɄ*$p %dRIhc_=LDIe'iFgiC2}tN8zD`2M&d֧˴>V:YN8z>v:) w@PL;4;O֪XpÈ8ڙ:;eFbLGs߉d8DLGgqFLGgs>u :T嬦F,!t);׈/k!rd:T>ÈtA"GNE3x5kg:Tk6d,FӧxJ$E;7%iNbK3 d.ڹi}_D(&sMMӘ^46Ygg&pBۼg i*,h}ϼ+e"B_WDe盦iLɳ(&7MӘ>2:d&ٙ Ӂ*gvFɡL3K4yA!3,M ꐙdgMgz뀄v̢:@|W-#+xkGyg jsW<h(MFaL;sxj#ްvBٹF<YX;L\#VmFԮS;;׈Uw#NgFl'& 92t*Ja 92t*Ja#v&7ٹF|\3ހNeFl82t*JaqY92t*Ja92un*Ja`a:sXUPKgnhHid|H c'&pBx"/!}&N+MӘEPL;4=W4FVZY>g^& uȄH8/(D c'iLo4g~C4FvZiZv>!N+Mv>HSidEӘgRM&l֧1}&u䲓M8':` vvJBO>aUNZ88Dbx툿N? +t%jS<ZX;3L'\#-NuvP਼Si)}? 8ȼi()c_;8ȼi(}3t©5b!#NF,Ԯ S ;;׈mOZȑNR #6a:0ka:0b}D!GNCE3XJ7(iPv۔X$SNMI{$LP;a5OcKWh2Aմ>/ DikiL?W%;TZ k8m3yJ4v+ژ6/:d s%&d i}_r9JWɴX4vnHSikEӘڹaMƊ61\>YhgLcZϙkU4X~:/ ׬=[a=O2A yU8ޙ xk%׏?D3t%kbڙF:Tgxj3Rv%ٹ$ڧ "92at(JAb3at%x1G&E3H'V!~#Hg$vF*4 p0Rv&ٹ$O?%"G&E3Hl3"&vٹ$ Euv.]t^<Ѡ>ƨJbɴD,Q:M&֧{ҁh2-4Ѵ>诞$ dɣi};TZXib8JdG4y!NM)&NMӌiddZii}v"a선5;@o~wtk%-PxbXʗ.62kwng]Kb YWgxj,vyrٹ$0~rv.6 0kn\K}/҉#p$v- pԢvyrٹ$&GvI3H8#p$x>`ɑ޹uQ ;ljcM‹gx8Qsdǔ'\7\H5oW9}V8_uH'r8ܬ: prIwo4yf١r G*7+tmL3k;h oܴ>wM:픛֧s+t)7O3߻kus߿}{N3zЇCۋ Go֪b'$w8ٟX%&p[ni߬3 ˕s O8#}tFl'Gq&GvE3X4ì޸suvی8G.Ja=e70bq vzvٹF|\ #q;F<3vvٹF3y09o.Ja␳Ev턻ת~탻'BX4鉷gnZ6/|:> IO=s4yk١| MiM탛֧1V4snZ |hnܴ>/ZѤ>i}ϕI_s^Nhz_sn'4t\~E+skv^}8ί:bx?>쬝>]vuv60j7./yKֆxjvv9Fڧ2 .9.Jaq"; #q;F<5bo*nFlR_9'e0b8`ɑ޸sQ #0k7n\k~8s.Jaėε\3@EnNb"cVtag3{hAoݴ>/}En{iL:Mƛ֧1wN4̗s_>鯝:qѤ3νhc_-E|;iL?ZkuHx8: <5im/7h}ϼtn{"B[|+X5moq<\>^;iWt홫sXiQ\qy\#V ?1.t홋gqp԰HWܞ(}_;H(}_;H(}ljҀeG9M38NoXfrn]>ÈA_Wgs Ltg 39?.Jaė·|5@goPrtۅ7bgZ4鲷 oZjѤ.i}ӋFNY9ogNh@冗[^Nhk/ݯh oܴ>/ErʢI缝u4vU&]vMӘ⹁M›֧1\tP.{Ep.{&pB[4:` OBO/NY:qفz'ꀵ*ŗ M?Fvozoq\% .=7^|v#gq0k0K70b8aɑ^|R #68׷/Jaqɑ]Q #ȓ#}}F||]})F,rUO]|vO:[8muH罝y8/}E{;iLoiC:̛ M?١r Mo!vEpy;&pB[\uH׻]q8:N 3\Ҕ]x4yr!]vE_X_~f\DZV8֪pNhzu9l>rNZ6Eī]Kb m~ŒԦF嶻sIlaY;=r;\OSA {Wgg<=9+.JAb8=8+nJAkF{ K튋gx8h^Y;l;\' +9ɶ-JAb8piێA}Q_{Œx{fYF &MӌXY4飷nZfC#߬飷n'{<6is/Oh}ۼꐞ{{&p{xluHϽ=y8<:ޞ pYGoN8z@Wr w:5;@o~&n*GVnk%yjjGK}{YqjGV>q{Yq?kV>vaX;=W;\' L8s#kJAk9M9s#KʘAb8HՎ(}/2r?kV>AڑUgڵ'v\eȚӧٖIƒ4'1C: G!]vMMpAꐮh&p_;\rM֧+I4頶*ژfv!vXMzDnkiFo;LuǚǓ逵*I:4;INU{Zá~׼8~X!cݿڴU;b\#Vm3...$MԆb^̪sxjlvzvfٹFڧ<29{3+Jaq{6-p*g֔>È/-rjgV>ÈAmUgxgrőޫYQ #vaȑΫ}YQ #t>Ү]YtNĒlfYL/1uH[8/}D^n{iLJwMz֧1kލ4[>鯽StVIXBE\^l:` KB[㛺逵*8uh'4t;drM.'4u;TtM6:O֪ntIqߔm&<|xͣX>^;⏻yԆdtU?@X6Īo'QK}\6SӍW5 F۫VgjrHھ(}ljodaUɑε}mQ #'j-ڝkė5'9ҍWMʘa3#'kmZkSa5 SVgjxFlT=}}=L#'#6Ocz>NmNhK%8Ѥ۾i}_;q)_|ߢiL?g֬t;$4uSt-6:Cz-jOz3v("pB[8'uH'qفqK~nN{?/׎A dr%YqOmNWҞ:;׈6khRkSv=5 [Tgjr (Pޢ)}v=5 [Tg߅Z#FF<3Xvv!ٹF(=H7w4S_(Ēc;fYLo4}hҍlҴ>/]_rI7J4N}&v+MӘ~Kv(7"pB_;t*I粝M4yT!v6LDZVCbY!v6Zjol M+v/mbx툿~Rv9mDm6,khQkĪ}riR>Èw9HҾ(}_:*(R)}_:5H()c5kr05K@]jNb"Q7d3uGQ,4#",4OczC҇lNh@COYNhk'}h҇lR1m^|'X;턒Fl'Nh@gtwB::@Y1|ZWDyXߗ_G퇱s^G˩[بvrA:K>^alvvAٹ(03Hgs,CN.:;VUsQνw\{=sݼ:;^AOܯ{7E~lS;wޟsQl|Y SNޠ>Ƃ}>|Ǵg\c_6ܧ>޴>1c_O} PؗC{o'sCSO#Í&7O#c= Pzpvto~݇zG!>k<~0ebx_﷠k Gw>Xb8p;gQ #7CԮv\# Y;9spxjc3d{5⩍͐so읳:;׈66Cνw\#Vmn(޻]mFlձzt{'IgzJrڻ[8v+uknMt&Nش>/ev.Zs[C^{w+ 4un{ݭ h֪xZa܎cO#cOUᑡC8iuCA^w 9#~6Oި%^a5⩍X64\#ڰBuvOml묝|{\#Y;wٹFzQvާpoM#wӋgqىF<:k޻uvrスnhgU?ݽ/ί:@owC{m'4tn{ݭOفzX{wZW~qj>/?:d>j}Ry)ڸvއ.UkĪͤ\~\wMw\#ڸQv޷VkS7{Qߩsxjy/;Uuv<(wQuo'UG>Qu`ҙ:ྦy&pB[|uZ>ZӁf@ >?]<.iQ,?˝kݢ%y⒵!ڸ=v-^RkĪjݢ%ٹF<fD=%\6SaOtޫsxjyO{uv>(ޟwsG3'W?LoxkU{Ѿ$ }/i'4|_-q<SׯIsc~ֹdmU1ԮO\}sxjcogm,OzpxjcL~dmU[D}dتWs3YzzpxϯޟIá۫R:4>WǞ{<uOV[WV`]\:Vs:x}^55:p qOkv:V|WtP׬PjVo%jSjK':z:` ~ P{1CrǷV8g=k%~BYo:\:~ـz_x=+XǏ:@?pwן<3p : }wfg( >.tƒw}s5bxw?(y(_ X< ~XK:ލuF|_8Ihuvu׵gDZ~GXqoM_׬|Kspߧ֪pܿ>::@og鸧~m8*}G|xğ1_AZ8֏כU֪w+ecO؁kV=+dMmBr @ 6,y!4 i+2dֽ8WTWEtu7kÿ_?_?룖~[o?~?ۗ~v:y߱o_򏯇{y^˿m?{N<k?^@_KKN߿שjM;kMŏos(5?7`Ԛe955=kǗ _߱8)<oϿˏ|Z~ g{B?o^]zy}dzg)Y^sG8hk?_'cmm?78ײ]v`S6^˟Zkۿ>O5?׶kY=??2^sG~qYZ?ޟ-Dx{yZK<ۮ}{3|Σײ]}4k\z{3Σk۟Ϫ6۾zVgۯמeou|kR_#qx<⣶]~u m^ճk.1zζzUkۏBԶ/lQ~mײ}ö?_8m_vg=_W¯e= ?A[&|=w ~kgl{9kuѶe?N:ݙ\#m_ mʢmF^vgۏӣi۵gc\WR+F^sG]mײ}]k.l3z~kYKdH^sGٟ过}-um@^vWm_K=WfQG}gubmRϾ΢r׈Wm_~vr׺΢zZKm_\mq$\)A^Km϶ mײ]vEm yj(Z^ϕo>y]LV-Kmm{_k9Kbnm#ZWԣl%ƶ]~vlm%_׼u ԶqőPKm_Ϸ}/:YtoޠyPۮ:Ͷ3Fm7kGp/{%ƶ_Գ_r׈gu߯ cmw&׈׶W <^Km϶kuD*0G«(̣xBfvQfGp/K<ţmײͣ?`1}kms$,gp۾xmێxu,gp۾xmێxu,gp۾xmێxu,gpx]|oۏ1}]ӴkmU<1}m{m+o9kuԶ3BkuӶ9 ϶mײAm,m۾Գ_l5b3:ֲdzz}m;řn9kij:y\t\#ֶ_xk:>щ{qVtJ0br3oIQv3 #ƾNڶ# 5bl:)jv3r׈gumy,rveouҶ<g c׉K۶X3FB{Ug^*O#|lyeouPjv5bl:(m;F^1}ڶq/gpX۾w8*W0bry^Hᯫ۔aij`׶؏Wzm_blkR+6^u5bl "Գm/gpx};[zG0ߟ7Xkz*}_ok_7_FϣRmWƯe?:EkĶܥ۩,Nt`Ư|_K=g8x{~ܧm 0mKY<%_/mNgq[6~q;GlYLbn4q?ҶĶ+ hײe Lbu'e 0m׉LZ5$x-t2Km%_Kc͠Ο2in?$7:ϩq <*?iwOr_y8NӛH0wC>+gty]0~f,Ư qجErW^A\|A]ld6mIN6 g^Or\^ϿuknKNgy߳._yoyֿ??ȋZj:xz8UY~Ϋ& !ЗvX鸌 ë%ֽz8ԅY~ 'Pz8ԕY~+& !ЗvX긔 C]꼖/#uq_b H=,Z|z8%W~ K& !vXո ýr]HEּ.Zzܸ0וT4~e+4/y޴}Sh5;雖@?G9ǡ׽yQ׺Z׍A8Z[xGë2Zˡpx} ^5 H=u~}r_ZqpWuպZrxkBy$u _S H=*5wqkh;kj\sárkj^s7 C]CԼnB/{ o^7-V~& !~ousrg޾y$u]_': H=Z'qz8TC^ЏC_Ma]]$&j-惼;!pM@BPk9;áyC&LN8tx~; jJx?mx~Z; "H=z-~z8T~uͫ_ߵCǡq By]F];+zr1o]MW׼nBy${չMq ZNWS95C]MW׼nBy$u5_] H8մ5A@BPWS95C]MW׼nB}ymr(8}v赶w^}q%}ε.3A?; r]}=^k9 !& !pD O 6 ~z[ CC Zˁ'3r(=*s3HfM@BpD4W2lZNV^<$4{x^3П};46}@?vg>ПA{D9(sҦ4H̔jrM)xi9 gWӬ,Y-h9 sdvgjá)CLN=*^M@BPN2 nB?vuojM'I3,YӠ֟{.B(9xˬ H8z8=ނejZگ^&m6-=筜&m6 Go٨shf)2yz|ǿr#{֥oVM)55||Z3{ ZCen9xό H8tn# Cen9xόz9|vhJt[z~Ϻ3kzڻrr(=*oM@Bǡn;8Hʻxr1o]9x| H==xG^43oZN=歼+Ͽ7 ΰ2md !p +ϴy7 CR9xN H=;9rhp忡1á$^'D@y+~M@BP^lB=z}`rAs'Wo-4wK{x>i9 gnarAs#?ww@?r}`c}Ӭ} h9 3ogv9xό H֙]43oZN=.7 ?;tfg@v|4+GZNٱ]@4 ;lZN=͍nQ]@4 ;lZN & !p|/6 lz[_vh=hC) H=m%w$L~=}9x| \k9^meYY9trI篳ƢYz4ЃNN-ՙ7-47@gnxόi9 Menxόi9 g3wӬ =h9 S+s3xfEk@?r\{z{AUݛ@y+GsuM@BώMru4ϼ:s"0BPX3KoBv-ՙ7-[9Z43woZNپ4+WGZNپ-ՙMY^-ՙ7-~^':s& !gWܢ }r~g4G6Yquo>=y,<^vh=xy Rxrgyxi9 g{shdOش}S_4'lZN=inz߿izn3'h4#CPw6 C݉C M@Bq__2Zˡu6C+&{;T;lSkhYeڴzxtli@o5jl肖@}scUC7lt֦~n]r-mý_K4²mZN=&%oVټ6 Ǽof5h^Ai͝QMJ4ެy-ZziդD*צ4ЃN&%oVټ6-4_{C}D4ެymZNپ&4YE ZNkhYeZ6 gGq7)xi9 gnRfkrRդD*צ4П]{u5ja҂@ou[XEk@Cu[XMir7)9x H=ꮋj-fsBRowY-]rgjrn!pLrnNk9uK꾖6 G3&R?ݗRdn?^o_g]D]&7/ESzѨIM@B1vUiO-lwww:@;]hdٴÿTx^i9 sdvww:cރo42u@?v/c;mhdٴz7GD$˦4cWǐw$c; :FӬ$h9 3o9xȞ H٫{hGdشs[xȞi9 g =crϮfAi?Kuo@oc;GvMi'͟7#~erMx?i9 sF>D B>hj-lS> ڑ-e$^ﴵֵwAwxA~}lq{PV=Ǧ~z_7^P_< GjxrX/W Cp_ߦ-ft=1{& pq=rpp' G?'wƻ_vEkӌ4wƻ_vMiFOwƻ_vMiFo^84GnZN3z]W/#ӌ4wr]rhSf\6I:N=W@84)snZN3zC쑛y97-YR4SF ZN3#x~hmџo짛ӌt\}shf?ݴfxT97 Gyo{PR4SF ZN3+uȡNs4ޯ^8GnW~ 7 Go{Fxni91ou=90H8z:|\E`\$^*=_S=.UR'+Z_?%TiՅ+ Cu9xʮ H=PvM@BPGޅ+mB>r.]iz9R}fuJAio wJ@;,#Bٕ6-~3r~gz{#iu?@; LӬ~'h9 ;KvM@BPEYlBr=ez8TwЏCvX}!DWAx_>i9 2dG$޿#74OlZN9h/dش}iV_>cw xi9 gɡ{hdOٴ}SC4ClZNᾩ",i6-47Uio-~hg&& !pC6lXN=+C H893"u)~sx֯C8C>9x ̖ H8tcjՠayӺZjLr kz8Tc7lXЏCvX(ZSz9/lM֦4wZU x+ִi9 Ղ([& !;݂D([Ӧ4ϼla5hBA@B1V-H4ފ5-Zz}or1ou29xG H=˗Y-:\rAsU{֦~~w29xG H=\Mi͍~M4mZNپ4E7 ZNپ'~ M}.& !F&s6-V'wpП}5h႖@?v'wpyo{@; he۴P7x˾i9 g[Ӭ>}/h9 sdv'wpCu29xG HY&s6-V'wpsf{Aiyj[F C5D9xcFܣC5D9xcF H=!c6ʺk-ҏ{E@X ~=ǾE뻎ru;՘ *=Pz8Tc7lX螟hAeڴ[P;V)H=K՘D *֦4ЃhAeڴz՘D *֦4X$oEٚ6 Ǽ߬kՊ5-~$oEٚ6 7ZU x+ִi9 Zek$^voͻlM@?v jՊ5 ?;[QMiǼlM'& !')وƛN6Mi?;{v7lB@ve4Ek ZNUhAeڴ92[QM@B1D *֦4ПenL krIs[xMV4ϱJ޶mBjWrmlz8Tlc޵z-AAkm}1BRZ޿> ޿~{ixAztۣ=bb^_|\M@яɿ74nZN3zW~ 7-=~u=90H8ý_]ohe7\6IsWJ74nZN3zܿ84nZN3zH {bMiFofAiFoƧ94)s.ZfNC2;4?7WO7-龹x~i9MuSѬ]6h9wLn:4U.ZfF4T{7-龹zx޻i9Sc{mMiFPTF WO0wU7e7-=8x~ H8z:\rSf$=aA@FxF蝳ע)=CAYs:룻 qO}vh=fQfu)_VcK zׯC=^8Z ~}qJ?a5l9náZe$^Z`6x˖i9 Ӑ_6Mi߭V$޹XM4mZN=htjm-orM6x˖i9 jm-orIsTkk-hTkly@?nbrfmz8Tlc}]VMi'͍~TiVۊ6ݘ *& !gnL kr Wc7lX@IVMi_6jf܂@^ƛY6MiI719x3 HYv&oq6-VklyЏC-C{ CG:!ܣ7zf6x˖=Rkє ޣD|5vy5$v`Z7uWz-eZCu*9xz8Tw`áz7e$}](& !rIMzS4ЃoU֦pTOU@;-zh7eڴzѡޔjruݧV$R}D](Ңi?ݓD){զ4s<Ղ~R^;VvMi'[efW'X6-͟wTM:Vt4ПݿD},ڢi7?YK4DzmZN=ik@v%c6-JiVzn/x˾hmMu5xwni9 uƻ[vMi?sD=/{4Гw&E:atƠ4П훾(ogi?7HE 5lZl8Z[>[;uUZtϺOLa[|?)ّ7 :pt !p+ّ7 Cu^9xΎ H=;pvM@Bp^mu^xΎi9 s:oӬ9h9 СyrX+{7 ?cE6{4ЃF+ّ7-47~o:oӬ9h9 wT4ށ#oZNc6{& !v,yK+{7-4ߟfW*{7-X4F ZNgu7_ӡ^wrmyK+{7-4:4knZNjjvM@BϮ'MfuAi?w7w첛@?{f?$[QMx~i9 g9hf?ݴ}}iV~9C;evM@BPqPkm8[BX $;_6BZ]vX},7Bۡp%c6 C/9x˾ H=S;VvM@Bp>guY+:XrAs Lxhmgww`cރ;lrAsZ;VvMi'͍O8Vjձ-hnuw`֦pTk@Ow]E},ڦ4ϫ;ce$}TM:Vt4թD+;آi?;tw`@o4TlrݿD},ڦ4Ѓ'75cׂ@v%cM=hƻ[vMi?7D-ݦ4П%jnrlV$տ},"0BGwvI=z[w,Pkm3ۣB*Zk ~G3H=>oCaz9ֵvexA<\~ϺWR~qV|wۡ׽ionáʡg{OJ?a C~9>& !p/ '$^ { =MiwxE{ @?{{;} !; =Mi͝K{ =Mi͝w@={¦4z@4Ai9 ŢY{ Ai'Ԣ =MiWm~9>& !]j{¦4cr}M@Bf-Q_4>@Oi9 g}Micg$<]^4oZN5|Ӭn?h9 9,7-~r}~\4׳oZN=E>4.GBr}~z8T?󛀄áڳMg>J/zT9h][ЯMm_o<׺GGZۏ祐K-{dN:_6MiF?4[\M@jb,& G룢Y-.Z^rcjb,"0sof6-=iFĆƛY6MiFO;=jbC,ۦ4}?hV3fFs\Mlhes[6-orcjmC-.[ަ47?^V狵s9|ߞVV ǡz8Tw`á:ce$թ+;& !p$M٫6 ý_iVNJzܿ84ޱmZNᾩN%X6-4}ҡlr$M٫6 >Pt !أwKuxʮi9 F=h eWڴzR}D](Ҧ4ГoEUwJ@vtiՅ+-47YG4ޅ+mZNjPvM@Bm?}D](Ҧ4ГF#Bٕ6-ݧiVz=ߡޔjr#Bٕ6 C9x H={CSkeiy]j[Ƃáڕme$q} G:\~GTkz>h>r.]i!p#Bٕ6 Cu9xʮ H=PvM@BptGiVdYF=֪ψMMiǼQ%;& !7@MMi'͍OViՅ+-47TuxʮhmmܾK&Bٕ6-owJ@OSG4ޅ+mZNoTiՅ+-/G4ޅ+-ZT$xo^i9 vmѡޔjrAs3ՓD){զ4ЃN爵47E ZN_{h7eZ6 g;hce۴z}k@oXMi͝_4E ZN=iv쁋֦~eՓCwxPzj]?ewhijz>KPVC7lt@O?vl@/99x H=vorώn~M`4Š4Ѓ7l@o*7-~n~r&Mqz{糨DM04ГF4 FS ZNnsrvoz}?xi9 qڜhe۴}SmN4mZN a5htA@BώnhƖnr1o.9x ˖ Hٙ[heK۴z[MJެymBy5jVѼ@v&%oVټ6-,u7l^@?B#9x[6 HYv$oK٦6-~EC B.hj-˦6UwxESz{}nj-e_ZGr.]iz{WWwJ@o4~zRӬ*h9 mU֦~Irޔjc{h7eڴz[=IޛWmBve47E ZNU{h7eZ6 kC){զ4ПTlriw*xi9 Ѡ5cׂ@o~hjn>=49e#LO'Zˍ6O=~uj-f?Z_ooֺ{O;kz>ϟv5nij4'͍D=/{4u=prAsVk-^4jrnz{?xi9 ׉{^Mi'͟gNqr?YiV'z\u@x'θi9 grrmN/cMi?7E14Г7 fAi?{Muw좛@og?-E]34Ѓhfoݴvw좛ЏCvX1ezуrr1ou@9x'θ HY(7-V쁛ПeuMz^4Пn]-;֢)D7_;Rv&ǯ?p8oh lyҜppr車BݷCz.=Pw{ }Repqvqpt8xF H8q74nZN3z[ME Wkoq{[\MiFy&6̲m޿94̲mZN3zHZDY44?7ĆƛY6Ekӌhn|.jbC,ۦ4ǑYjme${ծVMiFo4(ն- wˡml47jWCm+ئ4w?{mlrC 7lnӌZM4E ZN3ziWkoqM3zѪly?Lkچ[\MiFy6m䰚Y4 mhvWof֢)=C-:p-=9?=~ҏC;B H8z꫏{So|]au膫}jCu=9xn H=_vM@Bp;Vw솛@ߔ#7-~~vX=1zdz{ncBxOi9 z'f$/& !أ84nZN'M5~ @ORxni9 ǡ=rrIsWO{bMi}ح^(#7-^4'F ZNپ^(#7-޽P4GnZN=hߣ#7-~/& !gzM_tà4П=rrϲTBxOi9 s,t/쑛3y )97-~^'fw񯜷p^(#7 Mq;t:!r-xu9H?3=YuT|_7G.h;=2H={bE`áz'f$/& !p&s6 78E_tà4ϼ}."0B1]Pxni9 e7$zprgo\ !/{֦4uhe۴}SM4mZN=drnz2E:Zt4П;ZvEk@vdv'wp@Oۿ:4ѲmZN-;& !gWdM:Zt4Пedn4Ѓ78;ZvMiMx˾i9 sdv'wpsMFҧ~(o(BjrƘ2 >G[jrƘrz>?w,Etƴ~=g\r.]iz8TwJá eW$^GwD](Ҧ4ЃίVOj՛W-ltOU@oS;VvMi qhce۴zHݿD},ڦ4П_MX4Ѓ{ݿD},ڦ4_7"XMik/9x˾ H=S;VvM@BGo4TM:Vt4lrώTlr^ݿD},ڦ4П]OXMi͝vYiVziPտD},ڦ4П_>}mrMu5xwni9 s~%c6 7euY-]rgjrnz8TWwvá_ʡgG'~ng\Bߡ-w,x_χq]wa}wQZCM9x~z8TlOCpHx;i9 Ӡ 6j@;ڠhf{\6 s,tÓ7lc;w1_6MiIrhe#ܴzhf5hAi}sƗp4П_6Mi'͍E04ϫ۠f{$UmiV;z!aEk@vdvl@v6(o7-pTl@v64F{ ZNٕ۠hf{\6 s'o|7 ?]D/43|jAx;i9 g `Ӭv1h9 ghIf\6 sdv4CX^-ޝJ<^r~f IfӬ_Z?w9Ts7lY=^k9\z8}vuoj6Mۡp'VlӌhU-S4:nZN3zjr&Mspoˊf5hAiFy9d6M@s-;4$inZN3z[mP=n/& GhVFfFs1V7lӌiMW7lӌhn|۳ڠhf{ܴfMAx;i9+fhAiFO;6(o7-QmP4=nZN3WxAx;i9ORE04?ul=-a(o47-a(o47-=0& lAx;i91o7vX/apt{rYs:ٶіM]wZ?gjGR><^v(=P6M@ӡZd$8j5xʆi9Is,׍iVfx ("0s;wRP6MiFOwRMiFϽ_HޖMmiՎfhSAiF4޶REkӌtT;lSӌhn-oK٦6-龩v$oK٦6-v4-E ZN3}H4ޖM-Zf􇯩nGmjrѓNv$oK٦6-=ίx (& 'xf5hHAiFx#o@ِM3zn1rVgpntj< irsj1rVgppD b&["037Λ;sxppV8Z[}3$=>CuV9lu/quuZ;u۪x_χy*尺_túW8náe7$/& !rֺƻ_vMiǼ}.& !V$-;& !ݹGYL4ѲmZN=h4o>}or;ZvM@B1PiVGzFxGi9 :he۴9g{WM@B9{vC+{٦4Пg5]˂@{WMi?{te@N&h6-zҝL4ѲmZN=htdM:Zt4Пo>}orRD}.ަ4zprIsxOi9 s^'F B~8ZlTz8T7láfS$?/?(M٫6 ýXJ4ޱmZN۝VNJ$թ+;"0BGtTlrAspWP4ޱmZN=h|he_۴9SXПTl4Ѓ/Tw`@_JޱmBytTlrIsnVuY+:Xr^ݩD+;آi?{tw`@?Gf$9xo^ H=3ՓD){զ4ϼ}auJA@BϮ}D](Ңi?<}D](Ҧ4cW?á:d${747@?v?C9xܣC 9xvGk9~dp}Bw~=?aڡ׽&&ZCPIޠamBjLr kz8T lMáZek$^'ߝjPѰ@;C$oPٰ6-pTc7lX@?B 9x+ִ Hޯ$oPٰ6-4T4AE ZN=hىT6Mi?7ծDm+ئ4ϑٍIޠamBjArViqfD Bj+rfzwX5x&i9 ڊd$F4t mZNmV{v$mE4^lZN=inܻf#o:ل6-{d$pW7lB@5jEњ@?{[ek$߻CeN=.j-e/Z'Y[ezYVzF)];V{z8T lMáZek$^GwD *֦4Г_ݘf5hXAi?7ݘD *֢ic[ek$&`5&xʆi9 Zek$޹U-iV+z1ՂD([Ӣi?7ՂD([Ӧ4ЃN$oPٰ6-~nLr kz{piVۊ6ches[6 gB71x3i9 gnm-or&&of6 ǼwUkk-~&&ofBƛY6Mi?GD-.[ަ4jm-orMY-.Z^rN%XiCClyN1ABR<7թﭕ":XK{z/_ΗeC.=[MM@ӡd$8k:Lf5h2AiFyJ6M@sxS&i9IsZxֳi9Is糖bD&[Ϧ4DZͤVS&$==%o*d6-=筶!oN6 GOjrdpܣwl xvi96fh'AiF!oN6-yۆh}d;ٴfhdٴfxtېl'?v3iT-=!oN6 Gx!oN6-]چh}d;ٴf}קz[ƒCv(=SdeoʑZ?PނLN8z:TL뛀Co9xϴ H8z:TL뛀C'vX ;xptD-Oؙ~N~ph}=^'aA@1-Xcᄣubj-=9$'R陵+}?ߊL~=G@<8F;GsunOZM2xd4ЃڕE<34ЋF9Z3woByxόi9 Ӡ*s3xfMi9V$lwݛ@y+rfM@B1E:s4crYzql++GB-ՙ7-V6gқП;GsuMiǼY9& !gMrd4ПmEY94ƢYzrrLgcxV,i9 sdv6gқЏCgvXY9tz9fZ=Пՙk] xz7_~=|wi<& !pD-Oؙx=^k9~:%J͑^ꮔ,O͙M=h4JԢ |r+%SsM@B9;E9S4Ѓ7Dv$4Ѓh󛀄ЏCvXy=|z8lPk9qdcpB+rZ[=q~jJ!Z z4jSWK(E6$ZgY{ R~ !r+ՋS~Ek@OD)?[4J-`rMzxi9 *7J@~x#ưhmAsx#ưi9 jFarM5x#ưi9 s~T+G BJr~!ggN~r1o%u9xrd H=*{&M@Bǡw;4i=H=*Qv&E`áR<5g$|I8& !gWNɢԜzrgNRs !p~gj[[nqp8lB??|Kѿ-ԯ~=[rPb& 9V.^xۡt.7 Gvd ^:l-ڙ7-=筼,ϙ7 Go޿g ϙ7-=isMiFo:/7ϑӌpt^כӌGfg`9x&̼ H8z{Tg̛ӌ4wFex~|i9Mvd4?7EY;4?3& P9\3oaL^u;iٷgi-ӜE_ۯ/|X+E ~N'OkM3z>xi9+ZM@s;iҙh}=|ߟoqętqL+E\Tvh=*s[M@BP9M2mB/{rh@Pz+k;hZY`rm׵~, H(9pk}fM@BOgشFӿf Ai޿r<dn$׷&ǡE-ۡ_yżvMkgԼ" п=OEM ͺ:^uӴ4wߛ_IJi9 ѕS~%+& !WvXWҸ C]9WҼ.#u唃_IJ H=)vz8P~u̫& !WvXWǸz C]W".#u_ H٨c^=7-lWC1@?{pxqE BxyE\F=^M^wYz/Zëá«aqC]8lB?}~^.~U;ϬZkYחC N8to^az8TzLá??)|3?cjC ЏCa$Pk9'uW H=^F~=߳.U/W߾~>9k2_~VZC|nB?ڡ*yVpBP9+&_QպZz_1$~ !pWE`á^!rWL6 C"9Z[%"zr(8;kmz6 C9Ժ=6BzOG9;zr(8߾>~`)SڳlGXÕơPʡ/z.=<"u^z-á:;:5[E_k9yd?z.=8y%;CG+q kp5Y?+z.=QȡFo^JO>8} m:6 GÕ=_L+~yo/=km|Ei-á.9іGZCǡQruo<n֏CkmGsZˡpXcŏFۡP3C{ 9yqq!Vxey֯CvK~X=^k9~-%w'uCPWá rpeq$~juXR=^vh=*Zk |ЏC_/OYBiPSZj-%wۡpW~<~5yr(8hˣяwۡpK~Ѹ H=#Zk uEC]qxPq裫іGZ#_~"U"5kz>?%Rj-p/^pBǡC{ MP]su;~zڏ<S^G8~*Őutk-á9[H;ѬǯJ:=Q&ݷӊP׏yoW;~zu;?x$_ ??=}pyM^\*ނr?kn1oryqC;w;knߴ0ӏC,2ЏCBqz8ݾ``j-|/>ZˡK_g߷ϸ:i}d^x_χا>(ӧ~>w;?C<|_o0/? 4Z>C{ }ԙkÿ_?_?#g9{c>_۷/?oߞ/o_xzۗz߾?zۏk(]͎#d78CiGUZsA4Ad/s;辱1lyd0ŒAf~=.5ǿ׶O~ W<׍'<Ǎ~>5ϕo</W3>.c>'1ZS>kMœkMyŵfgJߟ=^__O)ԓx?~z~ç8y>p~,?'yy>zk8=/g ?=O#S<G?N7υ_j~@ߏTz"~\?x2^z|]@ks̛|=w'>WuZϓ:%kzmmy2ֶk~{^_Kj۵g?am?C^ۮe=`g?Z'JG׳ei۵g|mqzǶk.lvRoޣos%m_G:ukY?b<̣?ɵԳ?[m6Զ/lm\1 yZK<ۮ㻷]~6Gk3>ζ:h׫z%m_/TmUm}cϋlZٿf_/wͣR۾ij5~4W¯e= _ *Σum_K=Ygf\#m ]K=:Eh\#m_ m2Guѣײ]ǏgӶkGY/{%>^_q!zvm|=wį[k:{۵g_W!.$zZK<e=ާ.]g#=z-_wZtۮcۯ 5۾z+̶H^Kmc׉Q۾zuն3F<۾r]~vrӺ΢zZKm_?\m~q$\)A^Km϶ mײ]vEmB}~(Z^ϕwzۯlLIO۾~ڶqɟslA|ӠOimNqqӫmp͠Nk2\?$7:Ouq& ^pSIN>:mOr3s O>͠Σ2jv?$A4Y9s;qZ߬E=Y}V"`Y$AyeZ[5-K'F~k'fZk p$٘1uo\_pz~^ϬKw4W}ޯoC{ ]et |5<^vh=,JU|z8eY~& !pq赶A C]꼐{RкZ2y%$ui_R H8ֵ:A@BPg9:/C]W뼚oB/y$u_W H]B4ޠ4Ѓ΅+k^yMᾩˮh2Mi?7u_i9 sd^sz-0E]k9puoẏ2ZCj-nkaz\1*~}r_Z[q-ѯZˡݹz[kv^sz85T~Mk& !pkM@BPP955árkj^s7 ú57H=*5wz9ku_i9 ro^7 Ǽ%_4~4ϼ} muMknz8uQ~& !pkڗM@BPWxΫBy$~MvuoA^ߝz8Z~& !pM@BP<ȡH&'ԟoB-^jz֟ҿl_2AlB?}nu'ۡpW_k-árk^}7 ú7H];+z4c޺y$u5_] H=蝫s]MEW׼nZNWvXW׸ C]MW׼.#u5_] H=j*wz8T~uͫ& !WvXW׸ C]MW׼.#u_W_Pz8}9Z[;N8~~dž_.3п.C;[(ZCP@2AlBJr bz8{r ~z[Evh=*s3HfM@BpD4W2lZN=|"+g6 ǼwΕOf3Ai?eD&Ϧ4,#6}6 C9x^< HϷhߞB}z[Psn֏#I2x 8ԺZTWI|<=jz>ϋ,?#9,3ynBJrdsz8T'LЏC'vX2gz8T'LUSh߯5W{V4n3nZNޯ4+O~7-篿}ޭL@o:6J‘@v,O͙7-pTJL՛@o*%SsMi?;v'L@4+GZZNOhֿĵeǞCPyW3oBʻrxz9ϕwfAiy;oM@B1;xr1o]9x| H=*3mfM@Bǡ3l;L7H=*sjM@BqTɹKE95s4cʚrtWAgMxli9 g{fӬ4h9 ggΚtrMRxNi9 rhC'a$~W_?i-s'^ˡtr8xn\ H8z8TbՂwfs[Ekӌ^kgR8Z[rOkk-3 _ ?'nLZ7_%?=IIái9 3ogvX>2~3hJ/[ƢYzrAswfeAi͝Z9Z43w/ZzHE<34П7E<34ܢ }rAs'Vn#-~!:s"0Bo-ՙ7-VݛПmE:s4ϼaA@BPX3K/#L9Z43woZNϷshP/{G^3oBr }z8Tݛ^.4+WGZN=h$Ѣ\{rMhxܽi9 zhxܽi9 ;GsuMi?7feAi'͍L[[43oZNᾩ|.7-_߯~Mo7-pTg@4DOZNپ/6-5չ_4'lZNٕshdOشI >& !gM}d4П=arM~xȞi9 ١oj-7 Zsdkm4az8ԝ9ԺwDBߏ^5g>mCsmVM=N9x[6z9zMv7l^@n]-mrM54xcFi9 ӱ5jl肖@?Gf.9x ˖߭K4²mZN=&%oVټ6 ǼoD*צ4ГF®&4YE ZN=hM&%oVټM=intjRfkrA]߯j67l^@oIƛU6Mi?{Mujլy-(&%oVټM+hYeڴßT5)xi9 gמn]-mrMY-,ZZrrH.x ˖hmMJެymB"Zk ]M4ݲmZN=歮&n6 -X7nu;uK꾖6 G3&.K)yn?^nκƻLvo^ZQ/cg#~er~wY]&NrAs Uww:@#=ً6-~.r.]gz{1.]grg#I !N۪>"'_6-4wMx?i9 1#;& !7Tu xNi9 3ovX="zFWWxȞi9 g =crD="{Ʀ4П]7{DMi?Iuoh#g-ltw$@;hdٴ}S}D4OlZNѺIM@B~j^ˍm,۔OHޖM-#~ɡ·;qzr(޾GTtu+޾?Amqk}=vonx_4¾;ǯu;qm9ptz8xO H8z:\p'f$=7n~NԉfuAiFO;mzC/ᢵiFOwƻ_vMiFo^84GnZN3zl {bMiFo47z!E:etΠ4'ب~w;evEkӌ=1{& mw;evMiFxdV97-Y}S4F? ZN3}S}shf?]6O7gMiFIuqNspv!;evMiFx))s-=~q=rpuqppܣwƻ_vMiFywo(~ 7 GOo!e$=a{@ͽTz8sdž?.G^d<^Ĺv#Bٕ6 >Pt !p#Bٕ6 Cu9xʮ H=PvM@Bp.huxʮi9 ;Ѭ.])h9 s_h eWڴ9MM@B1~T}F4olZN=hn$3~grgwGiY Cu9xgN H=w{HM@BP]B-{lBr}bWAY}!Drgraznߑ '6-@4OlZNᾩ~  '6-]iVнC4ClZNᾩ!!S6-pTGw4@}76-~hga?A@Bp݁ZerBp}^qj-\oM@B̺?@\z9J<^pʡZfK$~1jPٰiC5&9xʆ H=1T6M@BP-Hފ5mB/eMZQ4ЃN$oEٚMnArViz{nAVir1o59x& H=sgZPӬV)h9 z\EkT6Ek@}s.[+x6i9 hes۴}SM4mZNNjf܂ПN[\Ek@yY6M@ByѫƛY6Mi? u7ln@;XӬf-h9 s,tlcC5&9xʆ HY$oPٰ6-464ޠamZN=~5&9xʆ H8tcjՠa7hp}lj-wGai-G՘yʆz~=?}<9Z[`CˆJ?ݘa5hX}WMnáAe$՘ *& !rwڕhme۴z(ծDm+ئ4AE ByVMiǼ՘ *& !Nv%o[6-Vc7lXc;SӬ +h9 N1T6Mi~WwT6Mi'͍>XI4ޠamZNOڕhme۴ytcjՠa C5&9xʆ HٙhAeڴzo[$oPٰ6-F;$oPٰ6-,tjն-~nWrmlz8Tc7lXci`՘D *֦4cjLr kq;Lނ5lXZCh5lX8Z[~c8\Qr/C}Noʍ& !x?W-Gz֯CvX-:\SZCu29xGz9k`D}.ަ4cdrnz{7_wp@; [Ӭ>}/h9 ;ZvE`c; he۴zGD}.ަ4zprMwY/ar&sByo>}or1ou29xG HϷ:he۴;Y;.H=O4-Zzo4o>}orϮBD}.ަ4o>}orNE Bdrn!ghe۴z[LѲmBy\MiǼuGMHQ:! VcFܣC5D9xcF H=!c6ʺk-ҏCE@X ~=Ǿ'sꮣJ?ݘa5lXnáAe$^GD *֦4cjArViz{7qTcjՠa-4T6Mi͝SI4ޠamZN ݂([& !uVirgnAZQ !N$oEٚ6-V lMc?~V[QMiǼՂ([& !gsY(ZSrgn6rMhznܫf#o:ل6-F4t mZNٕ[hekڴn7Y *Vr$oEٚ6 Ǽ7lX@1T6MiDm+ئ4ϱVۊ6$ծm+"0BPJ޶{J'Zk qz.ףWKkG=.T}GL\E`74nZN3zW~ 7-=_vM@zY/arѓo)xnhm{C/4'͝fw¡=rrџ쑛ӌ4w>xuHѬN3h9F':xιhmџo짛ӌt\}shf?ݴfC]54WǴhVW.fNCء^w4?7W{7-uzx޻i9w첛CM94H8Uthf]697gM@2;& pq=rp[ Wj|WhJy8D9ft]8k-'Lmr(8}?qtкz Z{umg8<^r~j|WԺZjmr-oz9kD-.[ަ4ЃNC'o|7-{Ze$޹XiVzD-.[ަ4jm-orAsD-.[ަ4ЃF&oq6-47NY-.Z^rUML̲mBjWrmlo+x6i9 s'ڕhme۴ݘa5hXA@B^ݘD *֦4Г}jL kry}thme۴z^#nfӡfmrK7Y,[ruML̲mB[\MiǼ-.[& !pCN=蝞YiV˖=Ri=IAhǯe|ߟˡɡֵp.ǡ;U;,H=S;VvE`áz7e$}](& !ru$M٫6-4hVo^}=I4ޛW-ZziՓD){զ4ГM٫6-~^'}](& !N4 EW ZN$M٫M=h~^~;VvMi'4_hce۴zhթD+;ئ4ПݿfkAi'ͿߦXEk@{>}mrݿD},ڦ4П] XMi'ͿdY},ZrMw5xwnhmAsVWwv@׉{^MiLw쌛@o ֧lt#mP-곲Pk9\\w^xPz4ܺ f]/l Z`98;& !p+ّ7 :pt !p+ّ7 Cu^9xΎ HN94ށ#oZN=hn\;pvMi'ofuAic{f$lw콛@;hgG޴zܹW[W4ށ#oZN=h6ё@?GfX9x޻ H=-zhfݴzj[V G< Ɨ;֯CZumǢFJ_r>}m!p%c6 Cu*9x H5TlrAs ̦Y+:Xrgww`ǼwRE+;ئ4ЃohX6-4w>ZJ4ޱmZN=iumձ-ltk֦4w]E},ڦ4ϫ;ce$޸[J4ޱmZN=in|7:UӬ,h9 gTl4Г'cS;VvMi?;wk@Oӭ%c6-iVzIwv֦pTWwv@ƻ[vMi}/9x˾ H=XM@BGx6n{3o߱C CCCw$_7ˡaq?$^ɡ/k:\̺R߾?8kz>|]3rкпsw:;yZpr#'ZC~9>& !н>Az8TlB/36-4g)lZN=~~9>& !;M3@;D{ @O{ =Mi?7h=|OarAsg)lZN=hR7z SZNj 6 ǼwE{ @y 6 ?VlZN=w57z 'ZN+{h}|`rX./7 ?;vw@v./7-WwfuAicg$,u?@thgߴzrnq~GBr}~!p,oٶk-ҏCv赶-~<^k9|G ZK-o^_뤣] ohe#\6臦[8x˖ H8z:\Mles$=>:4mZN3z[MLEs x3hmѓN{x3i9Isg^Mlhes۴fonix3i9Is\ML4Es ZN3zܿ=4-Zfon|kjmC-.[ަ4'͍Vo|7-龹xFi9_SD_4 474.ZfTo|7 Gx74nZN3z;߾=4nZN3z.hVFf8ፃ7lGC 7lӌ4w_6MiFϽq>}aáVߜt8x˾VkKwb[џ/6f[|=G}q>}O8ZT:Vt !pN%X6 Cu*9x H='{SM@Bp+ww`@E:Vt4ПTlrIsw`@?Gf$9xo^ H=PvM@BG$>MPt4ГFϬ#Bٕ6-4wTuxʮi9 77>S\G4ޅ+mZNqSG4ޅ+mZN=h|ﳺOӬ.])h9 #Bٕ6 7cuxʮi9 ƻPvMi?buwJ@W47E ZN}](& !p>#76 ohj-7lc> ڕme$~]j[Ƃẟ7-X_̾УKUy. eW>9|PݧV$}]("0BPGޅ+mB>r.]iz9QwJ@?vio ǼwZxhm1ou9xgN H= С~grAs#uwJ@;OӬ.])h9 7ƻPvEk@}sC](Ҧ4Ѓo#Bٕ6-47zfuxʮi9 g?>MPt4П'{SEk@ϳoU@;'{SMi'͍U=I4ޛWmZNO{RӬ*h9 g;hce[6 ,ノXMi?7տD},ڦ4ЃwWƻ[vMiͽ[m?)y7-~ek^.z`n֏Cg-,[@_χyɽjhM[44ЃϷۜhe۴zѨ]M@B1 l@x,T7l@}V4 FS ZN=hph5fܴ92`6M@B1ϢV7l@; h fSܴahA@B9~vorIsN[9xi9 ڜhe۴z -& !g~7Y-]rgn]r-m3m.x ˖i9 Ye$޿?'oVټ6-MiV|MJ4ެymZN ݎm)& !g ۑh-eڴz[Gހ!mB.\.T݅nϼ-q}Mk9~="/+Eϧkz>kձ C$9xo^z9!թD+;ئ4cIrޔjz{pP4ޛWmZN=h47E ZN=h|޲zh7eZ6 s,tOUc;zh7eڴz[Gޅ+mBytIMzS4sws'{SEk@?{ eW${>.]irIsUOU@oS47E ZN ݓ){"0BώIޔjr1o$9xo^ Hٕ{h7eڴnY)zUrIsU֦,uw`@NS;VvMi94DzmZNᾩq>=49^;[nhj-> Pkm6r(8꯵.E>i;kz>_zUWkݲyԺiZ;#׉{^Mi?7D=/{4ЃNk^'y7-^4j[t !=prAs'V쁛@;;(7-47Ju@x'θi9 iM:atƠ4П/cMi羹ꋢrrMEx~i9 9Fh?fܴTw˦Y]3hryU[ƻfvMiKx/޺i9 s%n)E7 CE9x~ H=]ȦY1ergrNqdP4 3nZN=^'y7 ?ˎD=/{4Пn]MZX4Z7MgW'z );ԏ&ǯ?>~]ơ~׋- GO.8]Em[ʡkk=uQ}WQ[r$=68=.#=7n~5ƫ 7lӌ^me$=ahyA@s~x˖hmsޫ7lnG7lnӌ4w>{5fmrjbY,[rѓݳ 7ln֦=jWm+& mwv54޶mZN3zx6i9m Ym+XrѓNwx6hm͍Wo[6-9x3i9ϯچ[\MiFo-jmY-.Z^rVme[F8ôVmhe۴fjm-.[& p5qfmpܣNhV3QwEsESz[wơʁ2q;BѓCz.=zp]q$=c_^oߏJzۡe7J?auA@BP]OnB/84nZN=hSrh'fܴzr=rz{nc¦Y=1zdrgr=rz8Tדw솛cFxni9 {ƻ_vMiT(-484GnZN=hӡ=rron^(#7-^(#7-lt/lG-޽P4GnZN='Q쑛@?gzrpgw=xni9 g{{aӬ=2h9 gY{h'fܴ9{bM@B1ߐ:4)snZN۽VOY;p^(#B뛎nwfSuBǡz-|{G[=Rk9|ߟ?.EiyuT|ߟ7G.'f$~#áz'f\F=_vM@BPMmB/opw솛@?vk ǼwAE/ᢵiǼ/& !}zpr1o79x˾ H=[E\4ЃonsMᾩ&s6-~drnz{[C-;ܦ4П5h႖@vdv'wp֦4xGi9 sdv'wpП];ZvMi?ɚfupAi羹 Ρn4ЃΦhe۴92;ZvM@B1oeMFҧVC7lЏC7vX1?|s1& !hk}wK]ۘ֯CvWV$}](& !p#Bٕ6 ѝ>xʮi9 q$M٫6-ltOj՛W-ltw`@ qhce۴zb/x˾i9 he_۴zwjǢ-?߈c6-~ίݿ},& !pN%X6 S;VvMi'M:Vt4ПmݩD+;ئ4ПXMi?tk@Ohe_۴ziPտfkAi?!ݿD},ڦ4jnrKDzmBye۴Z;.H=[vE`á_ʡgG'~n׳Pw.[P=w,x_χq[w3i]㵖Cǡf;4H= aGZCpHx;i9 . aMi͝vYmiV;9_6E`s߸Y O4nZN=h%ɡƗprAsD/4seӬ0h9 g?nxƗp4ЃjvqrUmP=nByojvqrAsCfhAi?;2 aEk@v6(o7-pTl@v6(o7-miV;9tÓ7l?]D/4ЃN6(o7-,!wl@o9ƛd6Mi#{];=Лqz4^~u~>XkGO IfӬ_Z?珣9d6.=>e;`M5Pq8=C3[4'C;4:nZN3zjr&Mspo47-=IF ݲCM240& P On{o|7-=i4jxM_4 47mhe#ܴfsڠhf{ܴfMAx;i9+E04ԍVl=-QmP4=nZN3WxAx;i9ORE04?ulӌ0usl$i-a(o47-=0& lAx;i99o5<9xF H8z8v赶Κ G϶UPm)uqՎahSuo.=P6E`C9xֳ H8qYP6MiFO;heCڴfxa5hHA@s;E#o@ِM3z}gqh-eڴfՎm)& 9߭SH4ޖMmZN3zѶ5jKѦӌpt;lS֦=i-oK٦6-龩v$oK٦6-龩v$oK٦6-v4-E ZN3T#x[6hmѓNv$oK٦6-=ίx (& 'xD (Ҧ4?viՀ!-=~9xֳpNg#o@ِ6-=#o5z6 GOj1rVgpt#o5z6 G3'^[;ԝyPz:\+uj-> GOnbPkm~;6 G?.EBn~\{^qW8Zz_t !p'~ 7 Z~ 7-V{áe$~hႀgvӲD-;ܦ4ЃN&s6-{:e$iD-;ܦ4Ѓ7E:Zt4ПdnrX%]6 Ǽ e@J%]6-G{vY+zYr^'ݳD+{٦4П;ZvMi?t'wp@}s㻘D-;ܦ4ПoM\4П\Mi?7D/4Ѓ=rrӽPGnB?u?Ot:!p)oTBjr&Muz8T7lУQTzE?ѱy|?/?(M٫6 w;VvMiǼթ+;& !НVNJ${NGN%XM=h ;VvMi͝ϜVk@c:ce$lwjձ-{ݩD+;آiߝJޱmBytTlrAsqu*xi9 gTM:Vt4ПNS;VvEk@?Gf$9xo^ H=t'{SMiǼ}](& !g>MPt4Пe>.]i4>#76 Cu9xgN H==:4olZN=>#76 3M m=mG?Zˡ>'+܇+t߭|?ɡrjxPqAE BjLr kz8T lMáZek$^'ߝoPٰ6-47ݘf5hXAi?7ݘD *֦4ϱ-Hފ5mB1T6MiB:4ޠamZN=i߳kՠa-ltlc@?Gf7&9xʆ H=[QM@BPFt mB?Vah7A@BqTblDM'Ц4cj+rfs7x&i9 ڊd$miV{vzilDM'Ц4f#o:ل6 ?lDM'Ц4jAVirgw jՊ5 ï(PނeN=.j-e/ZG}=Q̺U5J~=(e߽kՊ5^JjArVi!p$oEٚ6 ѝ3xʆi9 Z1T6Mi?7ݘf5hXAic[ekZF=MjL kr1o 9x+ִ H=qWZhekڴz1ՂfhMAi?7݂D([Ӣi羹81T6Mi#Ae$elc@v,tk̢-X&&ofM9[he۴92Y6M@B1YM4mZNMV3$,t7ln֦,ukly@o[\Mi?7D-.[ަ4ϑٝVNJZz8Խ19Zlq~#z[,?ޠzTJZ?ߏ/eCu;b&[& PDTl~j&Mfrcn&J4 974TlZN3zܹV-F4jlZN3z77ZQxֳi9y,T37l2wf5h2AiFymGM@ӡچ}d;$Mچh}d;ٴf?jdrm4jNӌlZN3}SD4TlZN3zNmGM@^uƛJ6MiFymjN?ul'ӌ4wB xvi9뮏j-dZ>O"+g~<^GU#xE3;P[3/#=*}xM@ӡҷ}=^'y?& p݁Zk l,8pp;ruoy! J$\xֽhz>os^9Z43w{Z4͝OUg蛖@;)2wӬ =h9 QݛcInh3& P9\3oaL^u;Y+bi֯ZM@яĢYi-\rѓC.ߢiFL2mI{Di-ܦ4?=*ZMiFO9Jk悖ӌpt'L~֦=NgrinpGf3xZ4i9O~3xZ4i9;qJ`ЂC(9xԵpt%OU6 Gx.%OU6-ԉK42mZN3zN\X$ ~3xZ4hms=qPzOu.=O"C6 GzT-X̼u;iz﷟4v+ՓO_~=[|td)i9 sdvj"? ?D(ӢiǼ(& !g?N,Ykr1o!9x> H8tiy" ?;:3OfEk@y+sLM@BPEc2lBvvn9@?RkmI,BJFrIj!pd$OJ})=^k9~{y~xZ{{нB}w?_?*8I.8pᕌI)T/_k8JFpIjPz:\bV4ۼk;ZY`PzΕumu,Fz{]қg$k}fMi?rh<dnشFz+8Է(ǡ>Pb^zb53Nkj^s_~=_S{Cy|k4&@WҼnZNht唃_IJ H=)vq+g;+i\iár+i^iBry$u5_ H=j(:sq+\;+^\ápr+^^Bv6ꫡhWMi?;P4~u̫4cN~+& !WvXW" ëIáֽ. xۡpxu{8Z[xuw8lB]8Z[x5& !WO\ п?wu}9Z[`áj-Tw& !V$ !& !pD O 6 C]^{Zý[YAiOsAMi9@ 27lBr\aqt;v\WnкZy$u_W_Pq-ص5ZCǡx?.C-\u|?R:W*g~ԺZ:?Wy>$ՈPkmg:7ƹ3H=Wȡֽ;Svh8t&o^̘g6ۡIandR(:;Z_ ogIy%;~fӺZ:+y$uW H8֫> 뼣u;* H=U.Yaz8ԫ\ϳ& !pWUgM@BǡU;`<8!pM@Bz4B̺~Vɳֿf|YAvh=5(Mkvz8TVCUЏCBabYۡpWM@BP9+&_QЏCBab$ bz8T+CjQr,k-áaCur$~:Cir$j[wۡߑmݙϿg,E}JglGXÕơPʡ/z.=<"u^z-á:;:ȡҋJO<2~^z=ydM@:W H8z8kP5Y?+ZC5 9t-k>_Cp݇/!Dzn++<^?>L+~yֿ/=ןoơ_Z>amy4u;~%^k amq4u;unCKN8txU+Vz u?u._xw;`<޵ná_9 ZˡGW;-uk-á.9іG"0BPW9Z[+ꊣk-ҏC]<x~P Re+^z֯C, *Pkm{1B?nz[n*xۡ~!9ԺZwCpIyKZϡ~27O*zmwPkmGB$mނ !qk\)r/YA_b~*Őutk-á9[H;ѬǯJ:>.<[iE[<^_cl=׺ZZk <'ЏC]W=?=}*^XJ2UCSgPqk?~B?zh^n>xpuqpEaz8\qpqz<^7z ^|/>ZCξ4ӊO^/z֯CyӏC'A\3x_χv!PB$@xۡvuoϝ_Iyz9/ endstream endobj 108 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 114 0 obj << /Length 2495 /Filter /FlateDecode >> stream xڅˎ6_ak,RcolO2@ߒԲ@lWSO,ndX*>m>~.e\f&[lv8ϊEXlGeuv::^_54Ͽ,W&'-<:N~}\9#n@ bN #Edz*I u##kN!TaY(x xθm3M.&b4.tJo9,oxy\|<*v c~@Y`* 2Uh"ٍE: t}B!ה&z56G8t-&+]'$Q?Jh(xx~8X$ڃӄ\U=1sW3Y od5<}:xR8BoM]RQT'gr*=/,86;B;O2PN|]) ]oy1*ܶ!D6,g;`PI&ch5 dMˉjtp&UoX 7va\uVx_^$ VLĩ!?^`Q_**Odw4-'0YI|C^vRcrVa'-\\;neTaW+y @~Sq.(*J/rFHd!qjREI,wFYs؊"^I$gqv#}/5:`|sfqB2 , 7yxDVw[<.w^Ԝ']Rq:IrJeS{׋aY&,4mN+->-= R'b䚰J- iLl4X3Q _~9Hg7|{.6M-#g8}LSRi2G{rF<7境K6! v+$ ܧcBA^zQ56/2ĤxWR]bj,ԜaDJ.m$H)z!6ȿ崴`rABߠtNgM_5ּ Mj(.\@* ;DΉ23M^R;iQLJKHF UX"*-*A#$1,w"p"k.`p)7h؈NshTy/I/OJD UjRե ]%P]4X7űu4!λJkLTg,_e4N4H A{)HI(l.4;~NCF'Kz:vrlp;F .d'qdI%{|q4ev&,"bW8F&3DC9i O#9g?4@AF:_sᙣcpX5y8n<Xh9?{=}ד87 kJjǛ`ӼFN9i%n,3IP?JAhĬJ#GWJ%\IƷ]opOa>`کsoL:67f&̍G}@\t`I3Hc6mi9mِ`:x'F0*p2`p[39.3^&bRлdβ 89A_ƚTrXqLi.㰐3eC|C!Yqg%Wtת4eZt`KtWK%R1޼Mۣ9+}?6qavҍ@ ;ǍY/vZxcɯ[OrۗɌw43^|pC(!iÓz</ {6C)^M0YD6FD $dp~h"tp(4ȜDSfA;nʽv[p4ilm᫕>O.p}7+RTw;Eŕܼ`%3|r5_U'%3KmURJCµ9F> /ExtGState << >>/ColorSpace << /sRGB 118 0 R >>>> /Length 55427 /Filter /FlateDecode >> stream xn$MRZ L2 $n@mf$-^~~c_=oJ ?ωp7L_O/ޮ/o/o/?<ӯ~}>^??_.z__xG /ye^/W߯o[Cq}k x} c_835^Xr^?^_~~?Scoc/??6؝ׯ7~"?5\u_Ͽ_^}Ը1׷Kx~}װ_|=:~7}~o=|Nc/w{DZ_r׺:KK‿<׏Ǜu_X^z^yӗKx{//yܼc߿_?1|+^]ew?s0^~|«kx[[~cG>Ks=c~__/uSSq\)_8a\k{#(&Ni ̳abP}k,DZ->cs0^b+_a{okw&^<>4~R|sZHw-'>F9qH9ǰg^Nu7ԫǰ>Ę{ݧ5qqԫǰ^{]ZIU^9z8_O}̺՜uϊ)e͚wQL86~BPaLb̽.{\;veIep王%׎^YZ\-װoWj1^b=Kj2ZsDžsҮϧW0qt5w 菇ü0w!_@}{z9W}ߗq\)ﯷ1뼛N[rF1k(k\c汸G^Qλw<5︗NUS1yjq/ٝ&;n{Kziepsi2Zs/Us0^ƪ^;Oͽ9w1yjq/ٝ&;n{KzŮVsackI[.}-a׎Q㪼bC׎>mwQOw>$>ꌄ=>2NrL磾H(CgMCRlb)?TOIzvs~h?rs>S҈2eSWdy^ʽҲONE3{-e7П;7鳒F|2e7}ީ*L/^K!VNE3{-e7ПZg%.eFn?wng]˄vt}_ 邪tE/qU}WDY!9u&!p.*ĸ*|=+䓯z=U!c7ql~OrԟMØ;=wب{*\R\-Gier>,9SR%c؝{FR\-˿ghmw٧q3O:]/qKH[oe(-4;}x/c^h }ӏTOܿ O?R4ӟQZv= QpO$ԊP~$iğ1Zv}*LD H=*o GPB37$Fn͉YE㢡kr3~0]% !]!]LVWcH} \ޟ}zu)_]uleѱ'eİ8Oc&'21}d%&ϟOe( _%{(19 4ԉ((h5Yv|2}ee/+f !JnZ܄)$Yݴ՛i'qϢê׸*+ޗ~a}IWt$~Z1i34Zv}*LR H=*G 3TBqUCv;MZu+pG[r3<>WezqUH}a{z|[Nw}a^qlo?s;k=:]LaHsOսJer>88ğ{UJbp?NOսNCϝ01Wd-dž;ӝwJbrlxpT kÇ[@OgYfzXJn͎Ϛ4a-4?CYfzXJn/UaRJ@BϝI#|ѲOCfRB;4'q@BЬ |S;Hy֢=Ўn?-w+- [4VZvs^8iw6Zv}_Ǯ㪰99U+x58ÊUJPH#sO_U*)hrL_U(Cɱ[ ubZ]x?7.HݱNI뛦\eU.]خ=ϼ-Y42ͅ-i7ht*֟*ӁtXݴBʪ0]P% aO^*F\Pe7?6,2݅*-i=i6Rw:ТҲ֟ۛʁ&8RsFnZn.Z4ӑcUZvzpE3;Ve7]O|Bsb݅8+M 1bָ݅*,=*3嬐!g|\8++y}N˪]ǖw'9/+NW+Ę;k=:]Lc09^2JsxƜOŽ*%{(1964+/5j$l6|mТ}ЎnZ?V _>h/uߪ8-xMF@֟[Evtz? n5݋*-i=z"b\3-۝GtYAܬ]# aY!kUnzFۯǸ*,}WH3F׷Ƕd}a .sap80?jq&0瞞PT&Wq6|\O(Q)C cJHcsO.P*qpu.OLrdmLpN'ƳptE3;@e7Ѓfnш3hz|_f4|4 [ ];׍-6t,@O /htsWqʤi.h ֚tE3]Pe7ПZˁtX@3MqX@ܤ-Hݱ*-4ςfWwJn?NMq愍@S릉qV}{P?T0z<]?8ŏ%-~J0lv=]zrLicnqqrØ;=wX{:iR\-:IϖjqͽT7spx99V=)G-Fu'JbpNՑ %{h18vzQ~\Adpᮋemw^͆?Nw]4mWZv=I#nܸѲO]宋fmwJn;]tƕ@Jw4͍-=hv7.A]tƕ@jO*w4͍-;Ͽhv7.OrE3ݶqe7П|]tƕ@oFmsFn/zJ^b\OB۳cpsx[G|:-\+Ę;v=}Yyp޹?Ҕ'==ιVW.UbhnqJJisiKer=n|#srL/N[(Cɱ-pNZrdۥk.eOIIXϏ ~L.[iMI<\s҈6mMSN*LgYaG:pLgYiMO^鄋f:cwJnZn('49-i=tUa]wJ@֏jû-v +-i؛6rۤknhMI릙nݰҲ֟&nf]wJnZܤMq憍ݴ4'tvtzܵ㚁޽$l=+ow1C|'*( [v_;ouѧql?ϋ'9pZ\%aswKersιV-Ug-[)Cɱv't'ɰ1]ztd%&ϟЦNա %{(Dsenr5t>Zn4QVZvz<ע-osFnZ?FZ ]4};WZvTݹҲ֓fwosFnZܤ3/ l|μhSw'rI#NݜѲ֟}˙tvtzpE3;ye7'7|™t䕖ݴ{O ܹn*L\ Hsoʇ_s_;Wk&prLoY(CNczcuBZ 'xcqJZ _f897V,41:gd-EIub]$I\$AÞAiv)k6B~74k ~B4kVZv='M3]fe7П;7邓F\fe7ПZt@l .5+-ԞW.8ik6Zv}!ltП 4)(ۀ,;-rVLY |6>LV43ySZv=ߧf^/o8I#2ѲI9ŇNi 箛dE33g8e7П;7ɒF2e8e7ПZg*hvt=hv>LV43ySZv=qF2e8e7П!+svt)Rhf󼧴z|hf󼧴S[HgVf$s2kV`cKo~Ϲϋ*1^]W]PcQiD=z`ePeï-p++{4ϴt@O 77i [6Zv=hv~n#oL7nYi ~4 [VZv&o҈6lsTߢnݲЎn窷M3ݰee7П&asFn/rUa:\wB0?It@~åVZ* ?&8\sFn~wWqUGw= G]!5.VWPB_׳|=p=_qlƈcnq2Zs=Ϲ[W/?+as՟Ker><9W.~ş+%{h18~N՟ %{h18\Pc1bϕ]$; ]${7Is^hvos&v҈6ons&vL\hG7ГfCᵋfzoJn/UaiJ@Byn|%s҈6mSi碙~ҲO埋fiJn瞷=i{77Zv}_韫УϋfzoJn~?g淍Уhݛ z^*L\ H}U_+~. _jc[|.{z{uR\-۫jq͝f>o/_+=w{z{uR\-|۫Jbp+%{h186~ |rLoRZ Ocz{uBZ V>9W/8BWׯlj$2={~ee/liwϯsSzOoh ީE3={~e7П<7fJn睽{Fe7My0={~!sEMx=ҲOFK|=sLicnε2ZsιVw.;Lt==:nL[2pO-[)C̽8V=)G-3[ݹP翻'vrL\(COr.]] %/++{4o+-4;3{҈7o)O^Gw$gWݗ+ նlhw/7Zv|vL\hG7П[g˕@onFn+3sU^ڽ BO坋fziJn;4KVZvs9iK6Zvs>hv_a,Lu8_O7g9B2ZsY̹wTg)(R)C,&,=E/Y %{hbsc<#6p"]$@_4tУ'/i S4Zv=hN<.U sB:ʢҲOݫ(f:LwJn?wnQ&8LsFn?wݤ,0݁*-4$eLTi ql>FܨUe7П;7>fQwJn5eU.1+k4Wi$.hktW)U!9C~~WqVH}Ug+ ό| C|5DZ-~nK|s7U:]qcaFsMչJerNs7{3L7ՍNC0902Z7xXRPc}[ u.m@ +|eL>TY vKʢ>}ҲI5ig5Zv=ߩ?)O_Y4gUZv=寧ʟhtzQ.W&LFn?wnWCvt|eL>Ti ES^1+w4oi$xE3{K@G7C@*L>T H}WH;4B *ĸ*{wtYAܩ-*zB%'$_c-c=~I=Yyps/KZsOU*Ę{YҚ{:TR\%,irCUT&Wㆃ_8CU* TrEdzStvz|byѦԽҲ֓fg֖-]ݴ~gˋ6]vtIt?$lk!eL~TiMoxƪ <֦M3={Le7g3v!c* [ BF@fBJnZ~ oTVg`'ӝVw%K|]c[,g5tW꽤2Z\sՈÜ;53 ˓?c=I %{h18Q?ꎄ=( })(ۀdDž)|)+{hʽTf( G;O½$s;Fn͎W S43RZvk!NLHi rEI#.\ѲLSqg$Su.]ҲϝtPI#ѲϝtPE3;.@B:0;.% !w;M3ݗ3e7w鶲/sgF@BQa=g 1 &!]!3V zدǸ**ïR!_9z5DZ-^./|sT9kc|/aMkupKsOU*5!URjZUPcerLU(C*X4C E3={Le7 oTBϫmgL1@OX4CTZv+3=cLSi I#<ѲLXt$V 7* U!9pjR#yV#(ƫ9&ŧuGP;ac$PBZ O'Dݔ-ePK#OZ|УB0'% !]!=NVcH=ޱ hqOsOҲO凒F'e7П{Gvts~h?rOd<扌ПZaU8 wIYOV1;:ró;Ex)·O!$QLgÜ;Ę{{zuR\%cϹK*q}KqWwbXKL;:vW6gd%ni{Z T+$l}W[cHAl1Zvz<9h;ЎnZ;FU;0J@֟=cA|QZvg?wv#e7ݥ*w#% aQ!aUq0v3ߍjB +uWfո*,=v>_}|]8ŏw/OWǹ0Nq]k]LkZhPcXjʨ}W"+a달v5 GX/\?|}QB T&$+}>uH}U{k@5 @Pz4~_qф~< 1KBB$pUq?RRgW9^럭a9;ߠIީ8ԗrYߧZ|g+%~YaG+¼K.R d ;YaY!ެ W]1 ~_^tr-_qp/o=q|ٺN8 e9vjկ8+,pdHTqUU$,JUJ@ҳZBsqu2 K ˃u ٲ8+,=*,tyD]U\[?U~sX#1S\sǺS8u%;_^q(}W%)"V!z=_JY!9C^qY!z=Y!]ay]!9eB^zB1.%ٻ6Y&_:i.#BU!޹l]aQa%뭓WRZw#)q1>Qhjo_>y{y{_ߟ鹺_s}z>6^/x]k~/1:NkدUC?u=^_~}tx7_iޞw/ӯc~~~czDZu?>;b>o9{}Cw>\_rK]g?cq`xX_%e寯TǍ,ɿi:X\N?r\?o'^]ߞ乘<60~[*5]yD3a~y>+^]wC|_wxa}N[*Ĝ8^8/>OЯabνހ{nIepssC- sװUdW*q}yx4*k_Gn=2xëkxYi6ď#ٮcXGߟ=TW9s0~Ffers ׿R\%낯owTW{zXޜ;qk\%fǽewTW9jqoٝ'Ub7S=-2J̹Ts{Y\%u7zoٝwy~u c[|}f5jqoٝ';n{[ziepsyR\-fǽewTWkbnγj1^7S=-Fb̽n{[vIepsyR\-fʹ罥wVW1kXscEzpQo'K_]z*6{ܷvWKep5Z\-F}kwLcu㾵Z*Ř{ݨ5ojq͝7j-V\-F}kwTW1Qkq]-;nԜ{޷zWkepsճ2ZoG=Xml\-=,`=krWp[~?ǚ`+TW9cMC*Ę{-5\t*1>{ bHeps@=[12Js"s˚ +UW9cMcT\%"s5V scǚ`+TW1Zj&芡Ub},=XlŐ*1~~,s>+FĘry>嫹װ=LR\%z#ߺj4VǶc3nzj$;{7ieps덭F2ZSsV# ccH*5w.017Yeps덭FR\-kzcTW{X`rjb̽{7j1^ L=ssFW# c=\%m\-_{5qzn }yz~0Stu=^]=_*5G=TW{Xts =V!kѭl+TW{Xts b̽ݚ{BKepsEkR\-sэe *Ř{-5XmW1Ztk -b̽ݚ{BKepE7kZ\-kѭl+TW1Ztk -;ݜ{BkepsEkR\-痘{5s?Z{-gu} ǶzIbAnTW{9w hJ cYcﰝeV&W1,jw";6{heps͢{,2ZfQsv cYcﰝE*5wn1Xeps͢{,R\-ka;TW{,rw΢b̽6{j1^E=Y2ZsfsϽCw cYcﰝeV&W1,jw"b{ hxk c96=yG m-cۊa\Q/0?lwd+5_[FO?`8J=?v L?vc8J=?6L?6f8JϽDw-NRӏ6)NRӏ)NRcDjzTd˱d+G0Wl'[Vb'[nb{'[9PzV1`$V1`&$VjNv~4iqzLl.~l6IqzL/~7Iq$_mvcAR)lǐ Jn~d6}УB0!УB0% !x6]zoch oz0{!УBx0{% !^*LoG H}WH/ۘ1B e6}У]!5ݙI=rK x}z'sW_ׯ/?n{TXn+LJaYa0ݓ+% aYa0ݓ+% aQ!RUdH\Y5tZĔݴ.gr'$l=*[ ] [3sΪir'w90;1% aBIݕRW$g债tDg债tDGp@UA9&# aϭ閚f'wWJnZOk-5tOݴg?RUdHzVXn+LJ HzVXn+LJ HzTT=2[ =AzVXn+LJ HzT|;Ս㞁$l=vcK޺3o_Wx?׿|廒3oF@BQ!XUzT?V?s$+ ̿ GXUaz.dB0 {2XLMi o zg߄vt= ?V?s$~>s V4˹SZv}єw 9 GnUaz9zJ@BQ![U^ν-+3g$]Pޭhs'OA݊fz9zJnsgh Mz¢=Ўn?yn?7@IǪ0M% !]!cV?i~H=* OTB 7wBsNB{Lͱ|1>%<<3 X GpUa:VwB0GpUa:VwJ@BQ!jU5+c5Gk$*zfZ4ӱUZv=h6h٢ݯҲC X G;~4lLwWi 7jUzןg+>74n:-hVnNI=* ݺUB ft~ПF&[sFn?B-n*-YnhuҡfqhУBΪ0]T% !8;:jLVi o:Ԭ zTZcuG+zTZcuG$+C X GBs3OB{Kz})r(N\x迟O8VsF@BQ!jUzTZcuG$+C X {7jLVhG7УpUaPwJ@B3pI#ѲAxáthvt=i~Gt~@%=E;Nt~@ܔ uꔝ@_4|tП:咋ffwJn~fq攍ПtvtUoL'NYi }fq攍Пڅ%tvt=hN<.U+-g?\rU].9+k6Wm$%WU+ GpUafwJ@BB \v?_G4Ʃ|{u|%~*uwx]>y-߮$l=+,d$l=*ӯ - [ w= l=+,d$l=+,d$l}WK8KFnZ~w=( [~7t ݴ4;a9ohMFrXNidI7t ݴiҽgu>6W7t &w0ݼ}% aYa0ݼ}% a]AދFܼ}e7?w{o+-iu0~L@iMq-{  [nK4ͻWZvz"4{2PZvzpUA%# aYa90'!gt GpUA%# aYk5=z}BY{=mǪ$l=C ҋm];z|}̴Rfzt#zTRfzt$"T^<( VK7F@BQ!JUӍzTRfzt$*쥟H+I#ҍѲL+UaO7B0G;'JFi I?VFҋe7Гf#DZ)^<z< TZ)^<(-L+UaO7J@Bc3?oyoLhztRfzt$"T^<( @$K,F@BynH E3'@j5R43xbQZvJHztc2TH< NZ hf"Ģz1*DE H=HpVFҋe7wVL/nУB0Ӌ% !]!> 9F4 GtQa#OJ@BQ3*|I H}Wk\r\30yB#Dzߖ,?IBq<"5> 3y~RB GwCYA'# !y*|I!y*|I H}UWf#OJn~3eGУߝ|yhf>zlCE3'e7Гf#_EJG@|yhf>zo/U$}X:1"mT><( [ L8 >JINݴ4;%FDhG7'NzQ43}x:QZvz|-FHtb 6fO'B;i'Q43}x:QZvz<(-i\+h4}h:qZvsFDiM뛦FUӉi#+Htb$lkFDhG7?JU(><(-iXv6F҇e7?T2)T<vJ&E3'e7'#L*dݴwm& IŒɤ*̤IF HzVdRfR$$l=*d2 T, [ LL*dgH&Ua&O2J@֣B~>r\30kyVGJ[>[c|%v*Hd$l=+D 3 yVAzVSf$l}W8YS,YIiMI"$d!JFnZO,٧hf򬤴e)<+)-i=ivTd,dYhMFS43 yVRZvzd>E3g%e7'a=ύ-?JBݴi*ToE3g%e7?WIBݴ^[٧hf򬤴|HeYȳҲ֓f3dhM뱢eN 37yAzVTfn\$l=*dN ,W [ M`"'U% M5z@_4bL5z&$nH+K,YGiMISd,cYhMI"2uݴ~ld.E3ge7'N4e48-i}T 3x~ߍyhf>ZT.H|EiM'GFe7kFڊ#I#Ѳ֟ۗ+'_ݴ452uݴG4e,-i=i?ke<X3Te<( [ ]d:F@ֳBd0g!g3^]!5ӘIzVX?ub\3OU% a +{>~XCq^}z=_fk%i_UqͰУ+8g+ "VZ=* GHUaVOJ@B^&D4p--͔ZfjT$"VZ=* 2ߞmseݹz?U!rpUs98+H.l$"W=7+ GUabJ@BBf۬ Yײ#Şvt=\f.ܬ$nE3sfe7ЃgI#rѲAssҲAssҲA#'bFn?A\43{nVZv=hvru࢙sҲIvh.S2s {n?yn"3О@Df.=c+-h*gŖHfbJnv\Yi {6I98i$[n6Zv=oG.=7+-g\43{nVZv)X9i$C[6Zv}ߵŞ`B~wR~d梙3ҲYA2el# !* [!* [ H=*Df 3C{VB#ܿPx;_ߟ϶$\KF@ֳJ]a&\OB0[ +vp=+ [ +vp=+ [ RVKF@w3?k43zVZvzRjWSw'Z4Z--ilifjT+֓fSҲ֓fjhMIvVhG7'N_)ifjTlifjTfԪiM&gWIԓdWӧi*Hi$l7>_iif)֟3M6L>ݴ~۟AKKFnZn443]zM&fKOJnZOdtSiM9LE#IԒѲ֓fꦙIԓҲcEf$l=*D D- [i*-=xaTGi FRe7Ѓħ\E3Se7Гf#E)j<(-h*DM5zУB$0'I0 GH&Ua&O2J@BO]ALf&O2Jn#X4T,-4I'I̤IFi \y?*T<(-O-I*d@jǪdR43xQZv=hN|rU43xQZv)S)&i$X1Zv=hN|rU43x f 3xQB2dI5z#Q\R(<ԓu|ߪfL$l=+fL$l=*Dƨ 9, [ +ct9<( [|43sx&QZvz*Ha$l=IE+743vtz}M3s e74?OEFr e7'N*Zif!֓f瓫fJnZO2FDiMƿHh>MfYƳҲ7M摮0% a]GFe74f呦ЎnZn <43x~QZvs}摢|bhMNR|EhG7'43x~QZvzܵ1I?2cd$FnZOϕf/JnZy+|E HzTϑB~3 i#t|e&CltO<( G/F@BQ!HU BQ!2FU3pSҲAͼ#I#ѲAO|Ei I[Gf/Jn'Fڊ<4O,-4?yhf>zW䑢ҲA("/Nn/Uaf$`B 1IyfɌQ43sx&QZv2FHLbzމ%2FDi VE33ge7s?Ydah E33ge7]*D H)S#i$sX&1Zv}*9C!w7 6I@f 9, GI]!9HMz&!~o_WqͰ~S`WPBT)~[3sUzRUS)&+Hc$"Tj<( GH&Ua&O2J@BVd4T,-4;+I̤IFhG7Ѓf'wE2)T<(-4+IHR$c23mT>< dHE3Ӈe7Ѓf'KE(><(-4;Y*IhR$z)hfԣz^7?wbfO=Jn?uWII5z@_4LL*d`BUj#D2)T<(-+F҉d4T,-VɤhfR$#ObfO=Jn+3IUIœzC"$K=Fn~3TT<( GH&Ua&O2J@BB& IŒzTdRfR$$< 1<+MBt"_y$3R? SVbIH=*D2 3xA=*D2 3xQB 6LNW,i#i$}X:1Zv=hvTӉҲAHE3Ӈe7Г.IHR$cz|ɤhfR$z|c0I̤IFi LF&e7M0ӇI0 ?u+mLN@OLE3Ӈe7ПO*$$K2Fn'ϿɤhfR$S+Z%IœҲO=LF%e7Пڗ+L*d@)hfԣ^2dI*dУB$0'!УB$0'% !]!IVbIH=*D2 3xA=*D2 3xQB;ry:[1LLDn #,g [ +7t#aZYif6젴fܐ4#4g8-i}d 3xvP~\ ?wffJnZ,P4 ,;-i=~0!?Jo=(-i<}ш߷<`8ٻ`iwI$7ݴg?}UoyHzVX+Ly@ HzVX+Ly@ HzT_[0>ӹF=( [i/<> c|'#UA# !*Ly@!*Ly@ H=* {PB_|2R4--M^w$$E3={|e7Ѓf'gO@g?}xU}zy‡ە@>h/w߮z޺*L^\ H|x҈/7n7uU^۽SIy뢙^۽ҲOÓF|ve7Пʇە@OfrJn+3}xV_nH=* ӗoA=* ӗoWB҇gۍУB0}v!Уd+|C,<LBClgd~_q<tyeT=( 8KF@BQ!~UߓzT_d$*oh o:0'!УB0ݼ}% !8${҈7o7{Unݾ BN ^4ͻWZv=i6InݾҲ苦{TP7n H=*# ӡWB-^4ͻWZv}<+C7o$‘W eWݕ+ ?Nqʍ@j)]4u+ q᲋fnwJnk!]vU].;+6Wn$eWݕ+ GpUanwJ@BB \zT]vW$z6^k+ơw\u0z~,Q!||U}zT_w߯$+  GUazB0GUazJ@BQ!yU^ݽp3_oh o0}~% !޼*L^^ H=N4-Mo^Ww/$$E3{ye7My^]zTo^Ww/? &!~*L\ H=*߮ ?WBogύУB0s% !wّkUphDPU,Ne x 0:oN@Bסv;X|$Aws#BPy{4g>wBw !H' ?J#=:\ۯ' LF I8ӳpt8ix4gzvq p:h:$\=N^MǙC%q8Hz:x3~5FqgnVVKI렉7y^i'.&LNݬ4WIK8ӳr7_Nspt8ix4gzv' LN@{urKґY=[y4Ig6!\3hΤJ`8spt}h:ls' LN@ut Hz8TKǑI8ӳpt8ix4gzvc k׭lky_ _^ͮmá8hvl$~:eȶA@BPYu4f5!UAkf[' !p:]3: _Ϊ`5mz8TͣWЏõt]Yuh4fuZogv6H=*̫N@BPr4cfuB gx C3s4f^U%?AhU' !?FhUnYi,F Z{MgաiAs!v͹~Ukd !p:]3: Ceq H:tVmˮmá8hvlkB=*f̶N@BW*#}|o]iEd*Kms=W42S9 Ceq̔ H:tFjLá28hfLeB=*IN@BסsO;X$~.HC)3n~+#fTN@BPg4eNrB?{s$ !p32'9 Ceql H:t>i+gá28hɌbB=*GN@B]e %hw9A3Hf#BPc4dFqB$3uA" Ceq  H=qY)*SBQ׷|y]n5r2jASN ' Pf4d rjRN Pf4d rjASN ' I,D TAK&' ZҫT34r29-wz\l'nVル442])fK3ii4=erAS+' i,=E #h$JK)ӕpp"] WOJK)ӕpt42]9 WNK`)Upt42]AS+' +*ÒI3*gpP3itF s=fT̰ šf8fB8zq4:r9 GOI`3*fXpP3itF 3!8LQ9ÜCOv $n$'pt8pW3L Gϓg^(r!~^ׯCxfT̰ !px5C88pTBPSot tB=`L !p7:sJ: CMq)S H8+>%á8)J=jꍃNN@BPSot tB=`L !p7:sJ: CMq)S H:k1%á8)$8s+!Sl 9}1lJ?p3u6Ab q(=jbN0F á&8 $51A'HN' !0|IB$'z8 9aЯCOv &H=<= 3u|?H=<=7!uy; C8u=+pBQB>q)TsWxHOAy*8 W,o$\=γ|Y(p<y>Tp;ǡsh V;Jz:g:>O=wz,{ǩ$\=γ|Ypt8ug} N@T_0>]4 3j_9xǻz8ww' !Џvs<ރЯCq^8T?؟u;~Uq^:8 wFu{?ɻe` $ϳ¡{^PBס=?S ɨ\n[1H8/a/Ϳ{~Dq"G=Oۗ߿| x{ܽ# uߟ ߟ?x{{6sˏCyksO'y]z\?y~_wU?8ŏ/o|?z_pG|俽񷿿;n{5A~?#qhq߽~r._F k*޿='*5aFq(Q4g=* wv ύ??;|{^|*ur+<ȹ鶸:oϡuo]ܗI?/|U930z{~\x~\~{R|P|i_勇qR~ooϻ}>g\+ڟ rn|qa6gpx~{<+,4۟mWZkkf cgݵe7k3V=]\έߟy6gpxNm#{3Vg֖Qsk<,\+޿Kvdчɯ\>.bηp֮˹໶9k\]\?<_g:k\-gB ssr&ĉa1֮C3O w׈9fm9PgrkC`֖3!N s׈w>jm;gpkC`֖3!N qssr&ĉa1>-gB 9 qb|~`z._]u'd][΄81\+޵LÝb}Y[΄81ԙ\+LÜb}Y[΄81\+޵LÝb}Y[΄81\+LÜYZ;1\+LÜb}Y[΄81\+޵Oؙrn,N#Z1Γsz~ꏟ7q}{?=Z`jm;o4 gpkf֖&N#qcsridZ1>̬-MF <_oS2N:Z1~~`>5Y۝bUz{FI?E?>OZ9wm9'5gpk][8E\#`Sԝ5b:wm9'Ugrk][8E\#گqזs2NQs׈9gm='ugpk][8E\#گqזs2NQs׈w:{m;' gpk][8E\#گqזs2NQs׈9gm='ugpk][8Eՙ\#ڿrگ˽5N8kXǷfs|-k3FǯgIςRuY?x8gnuakZ1>b֖Eɵb}Ŭ-#&9kX Y[fGLs׊w, c3,fm1Y\+gX2;b3Vkװuvdqgpka1kɢZ1>b֖ŜYEm&K8kX Y[fGLqc3,fm1Y\+gX2;b3Vkװuvdqgpka1kbZ1>b֖Ŝ]]o͉SKVϝDS3s~>[g2bj3Vk u.rgpkA4k\eZ1>h֖S˜]Qsɧ;kX Y[RL-u&׊D̥Z c3fmK1\+޵k:|j3V e.2gpkA4k\eZֶ݃dS+b}Ѭ-s)9kX Y[RL-s׊wD%Z c3fmK1ԙ\+g2bj3Vk u.rgpk| ]\9Mc" ׊1ΐy1?E|vŏaTEאeD4gpx׮!kZ1>Cn֖Qɵb}ܬ-3/&9kX Y[f^LDs׊wr< c3fmy1\+g2b"3VkאuDtgpk!7k̋Z1>Cn֖ќY\m3&b8kX Y[f^LDqc3fmy1\+g2b"3VkאuDtgpk!7k̋hZ1>Cn֖ќ]\3';kXvs9kcRǴc^C1eexq3簼̽fNQs3vy}>ݜl_hd,xX^`G3'ۨy@nNQ򯱇e ƐTsa,|X^&aI3'ۨe2 cT9FutsZ@,/#1mԲk by13͜l5gy66Ül_lid,X^c O3'ۨNHnNQ򯡈eHUsa,X^dLQ3'ۨJnNQeZ,Usa,Xu `ǨVQ_u]m}7sZFyMߟ/iZ\<<`?QF^1áf8LΙmB=j N@BPxt2vB=s !py<:s~; Cq# H8\2g7MA@!>:sBs=qQ^>}' 3F@&@ á8hȼ$~:E A@BP)`4djpB  u, "; CŁqx H=*&LN@B?q2}=+0dFQB ,_eKQ. &u{?*ՌLAN@BPf4d rBjRN !pT3r29 CqД) H:tiK9áR8hdB8\0FQ&&n~+ՌLAN@BסSM;Xʉ$jASN ' !pT3r29 I*œMz8TRM.lá8hrd$ϝ YSMXʉ N5)'S!pT3r29 _N5`)'RPz8TM9@CqД) H=*ՌLAN@B뻵׽YJ=2L}9*ry]ncg2+7YF ár8hʜ$~:7YA@BPi4Ge2!AsT,' !p42g9 k)2VXL M9*sz8TnQ.ۯGkgMc+2Yr7~;cfdF á28hL$~&cg.dI@BPk4se&S%lh> oeq̕ H={%AVkg߂~yl4e~sBc,u<" Cq| H=*oN@BסX;X>$?OZ$afBTBDy}`&ďo>_i _+KI| 0pt8o4fBt`$ p:h̄$\:\wFbInVVKI| 0y^wFbInVķ3!: WJ|` 0bpt8o4fBt'&LN@կC'v 1 Hz:29 Wķ43!:-wzR8X$\={%ķ43!fI| 0pp7#! WOA`&D#$u Hz:ķ3!: WJ|` 0bptx?ii:0fUDLK/13{e~^ׯC8)2fd !pL913Bʔ33uL1# CeqЌz8TN͍+Џõ\rh4cfuZz\I?hՠn{38h $)A3ffP' !GIܣ_X Οy4!p9G3: ɟyjz8TͣW@ <94G3:-w3hhvl {wlˣWá8hͼ$^Yuh4fuZogv6H=*f̶N@BPYu4fuBUkd !p:]3BơgLJ?OL?>?~N_C5q H=)6lN@BסB;Xsf$AC6 #BPMa9dpBC4 !p0YB?ךG5iAsytSm,~n `!EzJ04Y8-w=itmB4$8WyGieD Z},tmB@CqЖ- H8L(oBá8hsfJg4iJm ۂ['4"hoMi C!r7Ma9dpB^hZ*ZFnvmBáZ8h$~Uh!A@BPbed 1!*A[F' !p}8=G _' C_ oOr' !h)=too[S&<~?~|QfڔI6lRN@4uЦM Hz8T3kJѤiFM)pt8h)erՌR4 Z:hi)erZfi;'ۑpwƚR4nVO+M4ѦMhe7 M4ѦMiՓBӪf4ڔI9-wzy~SCc*ZWr7Z:h$\=NZmUٺ_nQ[WpAݢF[U.nVՍkieCsZfNn\Cc ,Zr7w*wZm`ЌVv{3h[6Isv64֢-wz}}1H=F á8h̾$~A@BZ74/z8h̾$h̾ '5A@+ h̾ ohf_tZz|} H8L+á:8hJgtюiy\hF;^v@nuMkxֹ?nhetZ[Sw:h } H:tká8h̾$A`E' !pOVk~of_tB^F`En͕>YiF_ Zz\F`E@O }h̾ ' N@O#|ܪhʻMc1er7Ѓc|rhC=3{r7ҽrgfuBޟZ4I&-wGtСNio=kvN@vwЦN5hoAF;ivV@kNYV4_-w=hC5n5z8T_oЯCv6H=N@BP}ufuBWk !p:_BfWm/?~j)}ZW ޿8h$\=MlN@ád;X$\=MlF Cqv HuNM6hAݬ69.}NMlNݬ4iɡviՓJ;64.}-wz\&FeOnV/4MlNݬ4W`ɦv3h +S_Mɡvhe7mr]ft~!7FoI@84Q*fFc6JnV/ԅ[ qh1ftZfr_c4ʠnVoLCm(YY; qh1ftZf4Ħ2hՓC2ۧr7ljmr]ft&e Pmr]f4!\=MlN@ӡ8h$\=MhA@ӡJzvjߟAOlou?o369.}: WOj2ۧpp6.} WOj2ۧpt8Q: Wwޝk>Y=ijC2ۧr7'͕vZmrh]ftZfNM6hAݬ4Wiɡvhe7 hIsvm>Y=i>|+k>Y=Nn2ۧpt69.}: W/MKoIݬޣmh &FeOnV̜64.}-wz'rɡvhe77kMlNݬ^64.}-w8QMlNݬ69.}: Wn`2gpt69.}: WOj2ۧpp6.} WOj2ۧM>3n+}ֻ~gỳ2ۧz8Tm>ЯCvv3H=MlF á8h$~;;4.}-w=hjC2ۧn͕vZmrh]ftZz\h&FeOn'ͅOVlk>4WiɡviAsnC2ۧr7ЃJ;64.}-w=i_gChܥ&Mhe7sfSuB?&ۥ$ !~MlJ ]h <.tjC2ۧr7:M6hA@kMm>694.}:-wT4ͳiFS Z=CMlN@B+]hͦ n`M4jz8TmT@C5q&M H=y6lN@Bסg;X$-篯[MW?u&Mz8TmTá8hͦ$~y5hA@BPsfSuB?l7ϡ&Miw&e !vZmrh]ftZz694.}:-w=hjMc2gr7ЃJ;694.}z\i&FeOnͅvmrh]ftZz>N⦱*6hA@gHqv H=MlN@Byuߟ6Y4.}&-wɡviIs+Wm>wnMc2gr7ߚ'&FeO@kNm>4rɦv3hoiCM4n͍w}Fh6UniM4uD {'-M H=>;=oQ: G*E˳9ׯۯq- Hz:Tkmq򜀄Cv-/Hz:Tkmq@WZ`-icZ\ lyF+Y=ijmC-.[r7'ͅحmhesZf5hyAݬ4WZ`-iՓ»چF[\ҳ; _n`-=Z|z8T+m❀áZ8hK$~hA@BP|g7!~4ҳ;-wv;Xf$ܫi6lF+4_m̝4_m̝4k̃4W{5iIsWm̝4Wl54ҳ;-w=h4ҳ;-wL+ok⃀áZ8hKoB=lN@BP|gwBZz !p8{z:CNУW?:@Nj~Д#8 _`A@BPu|z8T} _'pB㠯N@Bס{;:Aq:Bun~8 ~o|iux hAsCN@G} _'pZz 󦱾}>ho%C}=n/N@'Zqо} H:t?o烀á8h_>$Azy' !GB}=!h=? @)mksտ. lN@á8X$\=N{^mٶim:۶pp<֦m WOӈAr6h#կÝ ,lNݬF<֐A W^hCmՓJ>xi!gvZfBssK 9r7'͕OF<4֐A-wz\hCFr6hnVOkѠY\hζmDڦm; Wݞ۴$ v{^mٶVw{nKm:۶r7SgFtmnVOkѶYyiMgvZf&6miՓgtnV/v{^mٶY=i`iyg3wZf8_i5hA@4upt8M{yg3wi6lN@á8Xf$\={u'zqfms=;A@BP=xgo6!ՃA{qf' !p<ڋ7; _`8zsz8TمЏÝ/N@A@/N@/N@A@_ٛVv=h4ڋ7;-w=i.igovZz\iՃzqn'ͅ_yhCgvZ=3vN@Bazp9x/ޜ$֣mzh/ h/ <3/WhGoZ[dzh/l9k/4ڋ7;-w2=iGoZ[mzh/lAs=^iD<ڋ7; _`8zsz8Tٛáz8h/$ms:\n3{㠍/z8Tm|ЯC7v0H=ፃ6lF áZ8h˖$~ Cc-.Z^r7Ѓ{_mqVv=hG|iesZzxwhesZz\X ޗF[\ǝ39Bjm-.[z8Tkmq򜀄ЯCv-/H=lyN@B;C-.[r7~5hnA@B66lnN@66lnN@OX3 K/6lnF+4ufiAsgVmfܜ4]jmMc-.Z^r7ҭmesBjm-.[[ڊ[n'ͅXmhesZz>/K-.[r7KhyA@kLkmqVv=gwF[\z:hBc} H{~>}-i{dvZcהVw{_K},r74Dz9-wz9/Cc},Zr7Ix=ƥ>}iߛݿFX5nV/tcׂY_wI`)zUpt8=i7e2!\=NOZM٫Cuq.])Huho^esvJN@sW>K](r7'͕fwXߣ4څ+9-wz\iv,vJNݬ4>Zgh EW ZfB=hʮdY[}fdq޽}ixIZfgFMݬ^h.gFMnV >4o8-w{k~'hߛ=gFMnVowYBٕY=it}ƺPtnV4}APv%' p:hʮ$\=uJA@g' Bt%#w]pt݉ eWrӱg](w=.:hʮ$~uJA@BPg eWrB>](u>o kmhʮ oq~ H={ui74WZ~he7ГB[>34o8-w=h+X}fhdqZz}w>4o-w>Oό?N@BPedqBw:JxgN QF;Kvn=${['􎦱=%ho;F{H@k&N!S~ %Et !wF{H@V!Sáz8hɞ$~w)A@BPcdOqB=${uwơg6lBJ=z.#lER{7}= ڥk9 Cuq.] H:twjRѵá8hʮeB=;vZN@BסS;X$~ns64ڥkz췺8hʮ$ՇAQ'' !GCMc(Sr7ЃJ۫>44ڏ?9-wqA;Ov"' !8Mc':Qr7ЃB>44ڏ?ON@BoӇn8㠝';(!]ӇFQ'n~㌃vDN@Bomq:Otn5 vDN@~wqΓ H={ݥ(hwqA;Ov"' !p3y9 _8`':Qz8T<ى@CuqΓ H=㌃vDN@B7|>?yտX? !qA;Ov"#BPgd'rB8㠝';uy CuqΓ H=㌃vDN@Bס{K;X$~nC64y9-w=[gd'rB[zL !G-C=&{n~9N@B+zhɞ "`$KzB24c8-w{{hɞ C3xIB"$z8T&]:!4u.A@kL&]Vv=h.4-C=&{r7cH;X7$EAIv#BP]ddwqB"$u.M Cuqn H=v.N@BwU|=D7qs}nGx`q8X7$\=NY&]"$pp.2M WOEAIv#tun Hz8T&]}#Z{:]didwqZf"$pp~17 W{J{:]didwqZf}#p~X7}#p::hȎ$\:tgh1~47(f}#pt8aCdp9ڝahCDZfANgX1Y= ";pp0!c WOA;Dv ' p::hȎ$\=3uA@tup̾߾w?Z\noݏuz8Tߙϝá8h|$~:oA@BPy{4g>wB;u# CeqL H=*CfN@BR4#-w38hmB=*CfN@Bq^ F3ufnnvnԑá28h$A3ufn' !0<'{NB99s[C:3r7~;A@B+9rhNm99su\#G CqМ9z8T.əár8hN$~:A@B +>xr-G?ߒ:b3: Cq) H:tjmKráR8h͔kB=*LN@BסSk;X$ZASl\#BPu4fuBJ4q+6HA@:b3: C%qd H:tmK\á8h2jB=*&LN@Bah9x2$DAi&W%PBPr4mfuBJi3Өz&CA@BPf4d2!oAN!' !p|3w29 _7`y'Pz8T;á8h<$~:ߴCA@BPf4d2!oAN!' !0AH' 0AH' !,DZ BJi$ӊ!p1F28 Cq4i H:thK#Vá8hɴ$>AH' !0AH' !p1F28 _N`i$Jz8TM#VcNW6x C|gm%,~ABf #BP`4+dpBY!ul"K CeqЬY H=*fN@BסA;XV,$ ABf #BP`4+dpB? g$ !pl02K(BY!z8T6 %ЯCgvY"H=*fN@BP`4+dpB Bd !pl02K8 CeqЬY H:t6h %á8hV,aB=߿}4"&e>_iC9靀Ù렓<'pp=6c WO3A'yNz#LuI Hz:ɽ:s; W`<&}pt8{twgrNN@կCOvI> Hz:ɽ:s; WO3A'yNz' P{lǤgrNF Ù렓<'pp=6c WO3A'yNz#u9sX'}_á8؜9$\=Ϋ P:BNz%\=O:|p"0s=?::u|?H=<=7!uy; 9w?áq=%PBP8z8y>z$~zǡy;z8y>zoB=λP׳'TN%'__?Qi\n((yv: CgcN@Bar$ !ppl̳ H:3Ϩʈná!Ϙ|F9 _~=c$ }3 H=^*C] |sV CoMM?!5v?$uޏy?BAǼЯC1>k+^Wƿalq/ WOu]$\:/?: endstream endobj 120 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 125 0 obj << /Length 3366 /Filter /FlateDecode >> stream xڵێ}(P2$Rvn\nf|y` 'ZY^ SrM]=?Mt.н2Nh@L[dޚ^Yb9r$Mk$ 3k`U91;m[Z@ vqFXpǵ)/uӊ׹gH*b<_~~?ZN&79xTZ6HNӚU5 bAg-&ً dၔ&8.7 9Gii${ R%QFB5UZ}YW;%Ġ _XmŰ20D*F*BTUl bH&ܳ+nMM`d8Vb=V*$'˚' lAƎ !.!2g ̲ه]0ky0H:1&1{6I Uzڏ*"Srtǿ}$yd<vLŭ #DX61.,b''.R") s/7O>^PUVm)cI+>?d1)IIoPH0EEm($aqvct)~kT2T zO:!'+Z"2紾5-@@Ƿ˕J ܚ0h*1(mu#~3k'4[M. =0%weܓUŵJ *Nﰌ? m96&cbEU/4-,Nn{=޴(ĺZG9"$8KC#DR OcX v2j,_J 7ܜΓ<զ@F#O0_.zty)Pv90g餵4l## }+BةA?N2gWCtP& [ۤ}\S0&qi=vO;X|:$8`GCz(EkJ1$S+\:{)sE\݃ uy#CDqdzX45L%ΕcQ{)Zi)yA=`fR 좁2@Qކd78lw2+8"fN.%=j~WQNU҃QbXiv-U{r:5a23.eilæR7j@<&t2g)(K6s (o)](7ͼ6 =G<4q5t,@4%!Npk6bƎьޯZL+>T'X .[^yfHgYdj>ʞ0BxG;w*ɭDҖl:>uXSVOXQ9sa'R#)'YUhk-k \XS:8> stream xX[@~W4a{5d1bL$ ,lDZ){;o Zq#>t9so'ӑ! =3&m{>lט̌׏l9-[FrIwO|wQ"?lyɈsmһ7Lc@) ݼz~Z.S\FwMG16B* ^ʽo񄎄ѽ~Ũo a~-R Qe#*MNm]1!rp(džv.EQ "h`Kþ/ݠ aNrjmIj>1*8A|]j 5c[iA6|WէRZ`B#rb =UGOňH$ioZlbX]Z4v:0u#?&q)eF/$Kbpea]!34u UyGi,|Xcmkc =2|rƳ?K uŻf,w K|R+/+pt?nT(faf3X]DwMUksmF6Ӻ=)fBpo}ini *hq  /sA`#tXJ ɾٕy22ak(LPGf1}"fUiА-$aIbhPK |KMX?rkd-cy\ :xk|aKǧnM(s]^Hle3猝I73 endstream endobj 137 0 obj << /Length 1381 /Filter /FlateDecode >> stream xڍێ6=_V^FJ}KHnHvv?s!(}|eTyV,JZeuXN戺к[gغlE[R?fNœ7%KOypԙgN"?"pes'U"R2<2tÔe5[2#cR D@ϩ tؙWYB3ˮ'moYJbuf's\ݞ_Q.ȟa+J3C:)s?IӺn=`uTD*0> "jWK^C<K@xUb#z!8oBB3r~$:+XgpsSHr"z-zǿߴ x۸k1$c~.1q7 m\2ƀhM7uɭ KGoxB17z0vq]z/,^lh8e ڼe:ԸfoW,"x qWR49NOJ]Q^dLErDW?apzPk͓IvwT u9dTB9uxx="B̌>'c-kr,~b,k88%h^Z9^&`Ԉstx_֋k endstream endobj 128 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpWchdiG/Rbuild4f762e64ec7e/hexbin/vignettes/hexagon_binning-marray1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 139 0 R /BBox [0 0 432 432] /Resources << /ProcSet [ /PDF /Text ] /Font << /F1 140 0 R/F2 141 0 R>> /ExtGState << >>/ColorSpace << /sRGB 142 0 R >>>> /Length 67144 /Filter /FlateDecode >> stream xer) d= HC,cOFUXR}.מ{5g̈b??owͿ/UJ?o?(?o8_}Qתv:~5}_Ɵ|7ޟ?ƿCކ6?o_ /y8?d?_ke|b+pu3 W:_{g?ulţӿ1,ր75k_|>ԟ?{Z돿i_}{w}(Jƌgp= ͺſbz_$#kZ.uX_׮u?x{ƟWw*q?.]om3>9]h' }?__-[~?oyoZ{#/"v$y_y/5lW_Vu]N>}8νپv;?ŝߕ|[wzWk#O_?G+>uhUxeO[N?.{۷Œy ~[knf=]fGO-eэ#}X3m3[@ʞ-Yu+}yz+p@OoOc[|xTo~ym~?c?^k{qsk2XM}5re=>}~,&=_lNݤỬ7(+6B%f7oJ֡Vg݋2ⷳ/}f~׬J2#KJmi͒%7^a.q>y\ކ*{.l!]5M&߽ >3؍_GUD6V|uY5=^/l:F!I^{2UtC[G#Uu`o sV ܢ#[Ww(Mԇkhɝ_[5!\脫l&{{/^'ͺ(:Y}>D/PPQùg <=[Ya QMU606e-wv<8[ٜ֩e3|N{f ]r޺z∛k6߃5棯8m-~H,POUwvxm5?SKxhoNq[tS v> @;O1F2v߶뗓j~.];@p^/GUƙ5ǡxYU@CW[o [$:k3URT5cɞ Oݦ~yuv 494xzݣ%_c͠~^",ks/,i^M2|C==[jn:Lpz^>q3%ۺU`oڣ;!j,۬O_Gzl@Dž#C%dj{KwPuC+w~G]ܚvKoAÚ]bϭƗ͌m@G.'v[@#rQTjRއ^[?]u`!x?lꌕ,pDy8&jGt-hlٱޝKP6Af]n[W|sCmE:z9uoC $ob扪O :}o^ OG# UD%;$+^HktFnIFRwЃ<ةbUDp_ן:B;VsFo#P4 _>}z0?6P~t(~hރ{ $84`P0.†t׀ȗowB'sٗOĩ*۔.bҏצa1¹I1-MOttqmSiahz8{PU6s= :! DE A!)Q 2l ܬZpa[*1GEhBӐ6[S2tW*n?TD@:!fv4/wyB4թjt0pQx8oMFeQPQ^ч :`RqA? )Mˆʇͱё)Bx NIlo(mbn.EC,aH6Tt]o:8ܻ*z[3k:Pg!+.sb `78IVm/+MLU@] 'm.>StF1Y-i=/hX-ZhSN%P1$+L{tw֥_<\Au=Z Qӱ涛䉚`,'JZ+Z$M2&vxA1DwM'a6I>l|Y]m hQz⁣Tl7hahրI &#C>57{1+"Fu-'K:ovT |UK ,jsVDI!Hj]Zeķ3|b!c W!38+ Z48!bԦQb h|q#%[u mx-T([DvëL|OcuE7aanZrr݆٩U@O.8̽~ђ!Z)p49yfLG\NUUG74O^#tw@p0cٲ5iBOنo>UstA Y#y|gns]naJ0|U4)Ԛ,5woآ폷$E3&LE~6KB]l 2_Fwp$]:b{7& .?k$ucՂ⮹4G};&bh/uEEFzC9S@T7"{3BÙnyәjRuVT `UUJ^VE*7bg^D^XX2Ƥ짗#0MeWtRA^URfRELݷIsUREJTu)7&A]n)~wA&A@GVU"Q{L%wsI)(i"Yd,ܓx6M 5ߦ^s\79ュ5Y Apn4~jrhS|kqԨWVZG4za&?DDĠ/lpˢY$@&&TR#w7c&%K~cEmttjK-^]>{(^ (Sب6iVsq3>uob!!4.-1Ct/ F8mm]R\u^V?#:)G1IrDPEWc]dEk 2];MgJMH2,jـMDٯsEWt`af!5n<ڡ|&HYMԲ&* NÚDk`ר2Kr:s,Wϴ"B>߸W ^W]$vi”Ap~#**t67!Ӿ+h~&zGAGNCqGÌ:_ znmx^l[ b2*Θ*%f8AHU7UF,݇Q9PwOp-[_AeC. nalfՆ s,*QfrֵL8チ=[a5&6ŠV=AE~>Jώ"`C۸d;bE)roG*ʥ\}1͌?t($= EȴIqElrVmT+}aLC/uELjk׻/ٙj1PE1{+3(+ wO(z5Ua>wL3̪s-wW/43rjp8K1IXĵxYַ,!6J'٪UNiUfU΅H64ۻMTUD1Hsp92y<J2)l\Lff҇_hCм Cnh>mG{[Bht@Do+qc|0c 8AHQ&FP 1x_6+_ * nY5ED^D\e^N#M=c͙V4ydEA¢!m ma"f}U'&H܄RH DU\*'<2YDFo@S¶vhM@"H9@m61a `): .vȌ*Ł[êɜ\2ݘ+sO0 qa'4U `YH?BJX6̂Hg|WtЈ!Cl{VJE{ gW1UCYM*}W=/e3FA.Q??p3DvgS%C dG2ڸ?,Ҧ@K"\kJ6)C.bV1cLOZèU%ms&l^P&Nh}"3C~CNвM(m1V ?lSikU]!%\0Ėģ\(aiQ|t̖oOS7" |z;Vn U?v=)BƌdwȬfvm|(wydl݈͡׆j.ZChRPbWo+[䶧d:?jJ6`¯]&gQ?sN2MI IOMo1w#l/ڏ4ŏWTqm*'ʣV2Yr,2b3E9ߴ^G9Jb Em 5931IU4 *YGn4" -?B{cW,fHjYlKeNI3CR9pc0TwP)Lʨ}'zkBYeuoTjt@f)Jb@3?I@8Jh"Lb|pP8Xd:&*:@:#;@{4j&`ajLDE ψ%, B;4eꐹpKPi, s-ݫ픣7Q8ܐ,ewQd +,51s4Q IF\O[1bmA_064@zMw51~7-dN[uctU1U^ 1K l7 J,s4?#H%Jb *xVJw?Ym·qFC`}ϔYA8n& 6#,l)M4Ofnq>PMlH 1Cm9+1ehә7.Pطɤ0D$1(XKfa`r" wm_bt\a\%1S18:Gu3d#< ͒KdH8UMĩD 2&i˽ԯE(&\xB跗%*1|$hA bO*K&kKϭO_o *XE]eOώi˙Oz'TĠsUڭbPnX\bs¤`[>6WĊ)ܪZ  xIw~n5\ة"sJX̞oa XXӱ";6,}r r +)1b kKϾ"X'ޣCR*Ӫ!?j Vȫ%,o.1.R}w1΍EE@6[u1`ae}̆AFv2ȏdbhIJ5eTq%}K.]]V '܈P `X!3`< yäT~HCM{٧mCHDL.sLBwpkClc~;“> Z&D0']F[7RH:4tMmhorERARW۫!.=գBquܛȜ0^wQD8c@Ӧ7f3]!(,^j1.T]Řug &!&FyLLa)E@Gd˸sXq2 \RYa]Pr~Z`a,A b5p nr7j6Р~|PeT '2B=OB8C 7nMe1VԩCqnd>Ig{X!#˴O8򍫌˺MU@'IRM3hmZ6p>N$L6+6S2DḀ ?ly @*a|* -IN@jlfuJ@.lѵ!ؚ8̈/AsEzD'LǓ{~HσDޑCh4jl&m]|ͳ{m,:%:ez&1I nܫ ȪACʇМ9˨)C|/kNl>i_fR7gnΧ&OXҵ.d֩opjPzUW۾Q5[E<ϮAE% )2GBDyӅw*] YC%WA##lo Ey>ţ] 8CcSoN\{j\w[aȧ-#|dk|{uFh*,{S*oFȻd>6kip޳0lvRdIEJ$Wb$?iV?yIʧ]wfW1F2Vȟ!³nTQ[V04;^,(QA36OQ ~9&k!7%`uFtIۚOUPso<l˅&Na}!dfw$2L3Bh*0R GӃ1k=LYțtՋZBKӭkB s}#du8xpa'7|"U-qՐ ߣ8[ܫ -n t|V`/!-td*|MG+C`])5TdOU3BjwGz?z_(*[H5_k'ao [Uv2 ҧ]˲^8.<,:T {#bؒTp(9|੡wxW]߆VS:c~-5Jp?QUSxXno4ֶ[̓'B?$$4$oH#w8rzEk=A=F*S%5[T,ћϦH_5j zҢIa%"Foa&#욏uZb0/ -{=yepp#.\Eon }khnmÎYG,hh:ftpac{/y>sazVQ@R96Z=~^(d=!ƿaΣ5zdӘFaQ![ϝ (;,ϗ9`*fO_Mmat"wnF0~kj)%=a>ElZ?N $2hJDa{w]=}h vG L(uӁ#bњF!n>jD}ۭe^v9TcjS G1_z’~#gϷ,y&SFUN̤ rȘ&')@HoD oJ:;%LEфxV6a}֟/YxTuG"*"LmtQ<Ofl2#J3(jJO=mT`['pIjazz,Cfґhjx;߂Ct 'gx\ֽ=ЖgTȘa&4t/)6h<ΈX}JXn+t{=p6B;bf[,V ϩfe@ofM|hНF&#q3.WAӂGn3‬=DNr@m#N@0Fݿ;%:%`h;x Bm 3VL)st^k_3*-|q0; TX2L5Q-qmt-otI,ºPN^Qu=P;?ʟƉZ ~^730M_2hpdn}zecD/ M|gHUv1~`غ8Iиc}!l$0fL:ºzߧ7Pngƅ!Θq0VdH!Lƞ{rAn0+NMBk `g\dٲLC2cÜ,mc."SІk:Up*isJգcdA9Fxnnv%4l[d""Ρ$KDY6̈]f@)bCZbmI 3d ˧ }Y;SXQٛ[Yxʟ $(:_pA&D kQfۨQ>f[ [ >twQ)cIDGv2$Ɇ8t@?Te˦wU%`wUe?*6| Qdg`Ee}OwAc]䪪+ h,wU{My&y|@'7V]s!XbvU?ٕ&lEzNU.}RF !-֩gv>G=F-('6!TSyB!4Xqv$E6V譲 di5A^h~REu#"m>qȲ:! Ϳ*/}a[ysBvFT?/%2xHŢCWGR6TAh߆lXl`h0b)0W9e!r>aBؒ 6._rDPk=!IeէO؇ma^G:HlUY3b̥KB{9z:ޏ+{nto쀬& Rfnuߖ-xYm eU :ci6E^Xwr,@;m)(/i˫ d _gZHoIFek  ٦$-pjS :F*zy%ԁ֩8CCJ͏.3Zȕn1Q( <өK@1y0)uձ- >S'_&כۏ)4`SΨ8I@ N {LKSYq13( ǃsV6AreF5Eo;@=кuA/>O *.hS-#ԭ{cd"^P5׭ e lx.C[!(#2 b?0AF!@ xch[^(`.툈{ۯ! L>̺ j2)0.NsHj}4E|0j\v˸6*K(/<œ9 r~sx 5'@Gq`/4a4LĮ]|pp8c;e=+]Xdq4lZ݉y:`ȪMQ B giTF!މoL>hPVhYH#zp8}ojE Z4m곎@Ӏ{H@dh4Tu^9YI5A/?yhBݺB2ư*Ø_BE1'Îv1'GyU9߲`NC}mƙa= cL™E[;hȅHFcE%_Jڔ&PML\I:b!c,2Z׻2< Da7`BLLd/MpY϶m]G-L5H@W" c| ɠ;ir+CYt'pB5eע_)bʖ2JanbCsO]88A}yxT (䧯%EoN R|e'{gtyiwrw3MgCk`}ݻPV4Y3=`5{_Wbh GbGuew@j¡LQhk,blEͣ羺I &K{6K$b8Mk]TXh[΃ 4 "z؆Rh)NPS3MmJ|4t.qiw0`af`*Ӽ3k?Ա@qY-=+̆ɂ6hGpVŊuL,["ײ< &U eI} KPh,&" Muc,a}Kdoˤ)e|@ 09J"3&-JC4&|wњvZFk4!^S&J9f6y94mq~#b7^SX#*G}v =$.hTUx6Gѧ],oGj9S4&Ȱ̾\SxF96hg4.f 3>Zod0t2ڧgAuT;lG&ʰWj"[T19Ň1>}pMufz5/uyC 1ZaMzlgyk\-q5ʖ 4rw.RQެ nTJ)heRQ6@ۜɺE@S1a!fa!GP>Y؀.xw5e j-3eɔH%*)#:Rc1 ӎ(-ؗ?ύ#@Rh<3[ (((PM\: |awLfE~{;Fokl QIe4c54}TA&hKg\guM boդnRpB7@iIn]}i<}∶ZoHZyy(akĠ.ywtң59鬕<2~ SdžD0RƆ T<t+HCT)D3V^T=v uZMxFۦTՃc3GZ}& .f0zŢo75hOSټd:Gt4g)NfU3xB2!r37tsA3hI =]CvoBΈ7uL5 rM# jPxph9F0]R ɵ0Ud]ncQiY#2ֳƲ0[{\8::4K2S̏xr_$6aTL*&ve̺i/qj@ @,3Y&h3MB t0R. xGaCGallueK%cd a[TN 411NNK%H8TEܶ weRa|`U(Tum8u.k&wOGӸZ%`^bmCCMnd>m' !S`Et,SB#_SzHatpC]=$c2ٴٰCf&Y5MaQ -2]{%`UY"M9OM5E190I$ F0#nPEWgf}0Zcɸ ]j`R{ᘍ6ZoFs@2dPzp`rH {:S1o(g&sOmœ"scGyumb"G">S@x]G8Qvpe iJ {3\r:Y-3Ba[B]aDO,!VMo蹝7 cY:R:QI vjya-6g9#Θt'呉۩7evSgѭ65]0V)bΠC칎S!O0ݎvAmT=柤hbBuKsL"uqyO=\Mo KUSQ)4v +oЖcخ>l8ӼG@Hݺs npDtc ܒ澦P6Ul(Dl ('piw]ߚ$~dm dX d.4„)@,ɒ kᩉbݍhS`e 2 5 yHp& 6cGS,EC@#,{5@cN]H@[2+;yV0WV4r g@tYؗ[/"&n75J qP9S ׮L/*g;JJAf  N6tqDf`vTdXǮ % h]* 'o+XP=|;&'= ^$f|{^#3S0jA`mԮvaLڣ!> Rל b aJ@s@Z[@kEnYE j(%6=J;셫;`6`&Y#sǞ{m6u= ǃ2BokwD_~Ol8'0*=.y$rM͋USΊEa>KGԀ 7gx{STW%hY{ ; 6TpKFp4_n13MHOW?%+ZLAUTmE}oC*^}QM kMGle7$%^mQn/ͦyuU3:rhj,#ly`%Y0A6)^8;sa"w+):;Y3'4#<7+UӜ{쎟f,M@d 8 Z/Ĕ L?cwD["@BHt2PI>Q<ӕ5^l0 4+=*3Ps(^\P^x5# ;m"NE VxB)kFĴW3t۞ zd tffwUHW'Rz) 2 R[CSGy0UAwoZmow!uC{xu9l&JJZLlL/}2L W?& {aQK'hB% xrz췓>КMFqOBFC}@50ʲ #%sICԃ5,MPc& v3ǶiMQ[E!- E6 hI5 jcO61*IfeKVʌq4hfx$jCuXxL  ¦'$͢{(k&GYsۈ{MtCk?ܒ}|Am mQ3gmIi>39ՌLFZ3}1"5 6Xp/"rYe޴`ĚiiB[:RfB} NXcɘs1V;r^>Н~;ܨ=LKyoG0LE?wdѻV"]V Ċ2[l[:sBCU5Yq.s@h1ͼ"Th]$:&HBȡb;u)JvFx!4V"XU:Lr-Σݦ; fTf ujZHhq2q+ݧp@>)iEPENvD-ϗ&pVwKs8ך 6h#h S> " $4~\/M0=`y^7iF)>8Ʌ]lTԐmچb={yTZOn/<*dca@sQͳ*kduM ƭiI4Y/ 6P|ecPH+)΂_~0O׌>OxVc2u2H5gNj(U!}]ZfF;.,,ym_\ LQMFێ MH ɲYMUDzJ:1)~XUِ,sobi:'ܜ&k"- lj3eaotCh htP- K8d?9̴>,t_&'\#.SPf8>R^./YW-k&yf}Ex0sgTN '<ҔIfs/]V