registry/0000755000175100001440000000000013210742516012141 5ustar hornikusersregistry/inst/0000755000175100001440000000000013210552315013112 5ustar hornikusersregistry/inst/doc/0000755000175100001440000000000013210552315013657 5ustar hornikusersregistry/inst/doc/registry.pdf0000755000175100001440000046320513210552314016236 0ustar hornikusers%PDF-1.5 % 34 0 obj << /Length 3305 /Filter /FlateDecode >> stream xڝZ[s~Ќ`[dNL=qT.$)`g;g-7م?GW,LZS”EgvQ&.>'nyfnL=[?a=`[^9K~~wXqFϓqo~,LL-MڔH%*>- 1KSii7XUEZvH>zx~. Lf-tf4K|ץJt ܕBAft6uyK11nr8vGG]zXђ̀Y+}y/گaw-O/M4i4igd YtSI{{&-mχ?2{X#?Q%ڝTlshߎ7.4o5@ eM2&+*ZU|erq%{ ]FJLeq[X k&E#:ѷ8OԙH)@Ѐ6Y:ُxf%r˂\!wfMfy #}%>?"ù_Z/: 7 iEмVy?aE5W7%mէӀ<ÛyUQȮà$Ui+7+^&'vȯeĭL+DLjK9ctΠЩOdlX8clS&%Bi6ّi#hVdm󖕹`HD {nowDP# 5zl2S2ʞ(g8> :"[lxѶț٣bNJ/.d#pF;{O4qIOx~y7EMQ@ҽS|IU´ k4`Sh+5 `{nFjˢ۠!v1qW bT&ZJv 4.j#z4aNwEoc!AҪ1Sܡm; Eeܽq`L?#~~ mQ\f8\FJGq'(W,0+;ibU#M\wO'䠉#/#9JQ&dܑ׍"M$0?Ggw(5t; M|Ә$˩˶4ᎄ;Am|Ÿ{/i, ьߑH޲NуkӃFSOkLqjYfҙzB g74NfLF;| |°`n.yI˞k5ٰĻi䗍lwBɹ87Dj!:EvLB+p sY 3agh+C,ҵPk1e?6'G,wXUðW W5߫zY0Xlͅz_`{,GU 3^.-U'wCE㉗fDkWA['T ~Ls\^RƜxӏnܦu;;5nӨyϞz=\[S<3K~-R蓻Ӻמ9t]~˟U7lXdMR5oe6|H6* bXy>5K=; tf\ٴ4,%8Bn4sM~SČ^V1 mFk9M'E럮ϥդu]o% endstream endobj 57 0 obj << /Length 2462 /Filter /FlateDecode >> stream xZHE@pdGcinhu >Zy'633;Uؙݯzwu|*7~cA6٠4bnw5lJ ܺg '#c4k1qϾ=-͟QDeN^߸#`<-V5 ``c `I o. M'.1Y]FIQ8TWTQ:<;N$$L@&])#j(m @T˫Qjb]ZՀ\x_<{ u̘[9Q,X*K73YS %^wȚfa39t8a1Z"f*ؼ^^Oֱֈu(qVP;6OA^_ׂhh^!Ȕ+0nXDtݚ rKT.&]wj ͐$V⋂ٱdTdE~XÓk*tdm1ti0i'qdgh[B#aqNIUi]3Ș*J]:ixU[O̺&"`7wH;٢k`McLio[ii NnN z>|\*gꝪ#&5򚋡5d=hgImeoYk$}IPh:|<i. fXi'ȚfF`Z?Gya?r_ƿWb",Ǚ_˛Ϟ7_b\t._.48=rΉ뱬գϻMu4;gkPy|۰OcȎ NϏaț8 mF@g 9.1"͂2ޛ1E'ٱ0:*J>LVFMtoUZT_F62t\5zn{v1V^?GhL Ѹpg EIx㞿|KC?uwT_d8t+ܡMʂAs~9b7L@nv!é-i-us5g1n9 g#R񡰭 2!Q+ ChG'~gH|0Nuy8QHC>`T,}ɓT;o jJ5Bs@!iR[|긠32.Y`^Pr9jĠMs_E`IJUohH^dB=a4Y~ 2c ) 4y~=zDa *,F^S;QJ1He.ecIsbV)!j;"Bd&L f7KpR R Up7  L{Y΅҈o נg8VdP{PJhσ#.Z'>~!x SƼ/e )w8#͡xj^3joQ!J-K2ճgTsT J=ROjvE:N/M ^aZ1{jRT#h"*gWkbjTP̛ S[NoZ$˓tu-y_/G+_R$kw!8v{9ܱIN_L̾|M8dž _(_t R}Mk+^QWFEQւoo^N6 endstream endobj 63 0 obj << /Length 1565 /Filter /FlateDecode >> stream xYmo6_kac", YvMiQbٖlJɑ-'@=#GN^lǡF^􆞰0荦R$r=nد,)z^aFP[o m_AO*3|">_JlJoW 0l:ήag,k9MPS ۋ"k ߣGa<'"PU99BM2:nVBK+KMm m3PV+IA#eǶ t`迕$Rr?L;mpG>h{EC%6T/Aڐ`P[EZ@ #' V_js&M3vR,X& x{}Jg4eU(V08B+lUdz;[P7I )RS~Ic ^hE%fصC713vCiŵbg, Fg{/xKt ]{f!4 &@]/]kj ITzEjFC`$}-Ik\ ιgN؞$ ,2&ShKG z_ $dn  $Q⌼[0tedQC9.I + %!UӺ˖U],h k/=jӿ5lᄷ0hI5- wO.Zw0΋%?p N|uPچJmZ/{o _ygGn #G6oS1(3mtL䐰CIBd>IEQ'הD9<-ȪtK8cgLi0Z̝ep|GЬ&淍NlGG+|О8x"4 U2}֮gn#U}@.8{a`>U4 cv(x(}ށŻ̖p`9\F6vXZQTBNFwX endstream endobj 67 0 obj << /Length 1848 /Filter /FlateDecode >> stream xY[F~WD+x|M/Hl% +UEț8Ne}\f<IOxۑ7ǿϦ_(u؏GHxb4׋t>vVg{>y+k8%8r}4M#]ڦ,ah熡a˜ؚ3a'Cn]A@J>7LB:ds%OO%[ 5WҬ@q[mn[.;67ghlZlp˒XǾpIH,ih&O&i%/ׅ\ %$d՚d* d"#x:ӎAFa/;wIXU)d:Xg߁cFy"45(8)ȁX?a5m2|DW/亍Ẓb pLCHSϘCY'>Pѝ֦ <ώvH6hAJLpkhQ#_W;󤗨?;g|֎,V/B_qL/𨧇Kob]Mx -czێ7rC'0`VfOE~dpĔ Fu83φ7 )-E8ǐΰ }M %QDߢ?奱.Ia{0[z_H}Ox 8Q4K!ƬZoP96@&' %}VbpR FMfYw(Ke">2nhZ(`(,kڏ&cggamH-na)іYU[[`JG3]]aw$QZn]jSŮQԪ&'Hb,+Όʷ ciwjgRlK91L{}H軑_yM$}]'=s01gII}P4 -Àa*|a+b$~ 0̎z +Qd]'!8[1 ahET% FCxٕ,;`PZDTЦPm9E "xVbTXJY8֪Nn ^GO}\f8$^baCNg[]ۗZPN=dI7sio^b.Xein0J/y\@{ql(w* 5 'mgr)Hm ~:P1# EOۀ;9 6Z2+v>ҟT{~.k~)z@ 2h[4iU3=S$O+}n{jJ9 t=4qD+CAH'nf抵xOGsW]Jw|ROeI߭ 1 tku(紌1n4r[J'n6t넊?eǘ2I6)R04UIFIx P"Mw//Rꪺlog5V^ݰ<O7z7\n=/ku]hSRiT чE endstream endobj 72 0 obj << /Length 1704 /Filter /FlateDecode >> stream xYmo6_a c*RDu݀fKV$)VXj^$QoNd>Ȣ#yw<>F7Gzq(b{Ht>zL/I?:ٚk0? '2rr[(Kg5Ug w:0Ӧl^sSI=%٣6Mv}E?% 9g^'T)L2pWJ:e7Y&^zw= V]30e813>GL %g95jעn )adΊ\p\emࢋ{5ٖF&+ H pIe9lH\ o<]b1H->]{80r{iw6 ;sWH}82pNSުʼrN>2 ՛9ɝ᭰^R>@d? ՞&~Y϶ ~hʘJ0q䬡D ;쨲&tZଳJϸ5&IJX:/ +:P7uZϘ@T\_9D5H\ 413AݴSTiC6Ev%'nRBp`JkbUaE%KGxھ8C7*| Q80!Y! 8L}eZᚚn|_;RA9@. eo:!= ?S?roRԔq;aF23 rbd{QhmqF?tz?r=i'HIs@[dz/\J.:k[+ xZ!|Rzo-VĄD2$XډPԼ 9 t/->;S6|spk=֬ſ.ZA9XA~< CqၚT\ԯ;-ILH$ك_爺b6`LK}c3[df] .yh9]`h+kV ΍7MV1sKV}roZ^X2+V8 Q`(+Lz򷒮􂝈na#J>oP (3'i?3h9 2mo-toۺ)AM{&f^z9efSG6J endstream endobj 78 0 obj << /Length 810 /Filter /FlateDecode >> stream xڕMS0 ZV (C$0qwWBdKj+YHh&5WY)Ņ5lzžgzˬ^ӣjӳEzV҂%/ >:x^(k/+r`[bY|v?_mq&ƁS:;!-Es~a>a0 40~GCfy|O6mlg(3>5}~Fu}2#$S4;Bf\ (:fˍp&1! Nk.[#kɵpM#QjσƱѶJoӘ1u 2)zdoy%**w<DX=&vAB$R?NVG(k2 ^VBW1Q:lo}Ye8eL'}N͟hE !RL ҽ}Pp]ݒ!3'hv7;F'ӃZ7 endstream endobj 82 0 obj << /Length 104 /Filter /FlateDecode >> stream x313T0P04W0#S#CB.)T&9ɓK?\K(̥PRTʥ`ȥm``P73`v(PՓ+ L5* endstream endobj 95 0 obj << /Length1 1597 /Length2 8672 /Length3 0 /Length 9713 /Filter /FlateDecode >> stream xڍP-иC ݡin\$C@=8݂wMxdf{UgmYgs> 4ZV0K, HHr@ /'ȃ qse`B`PH-ܞlnOq*0(@ <@a.Bi @]1`N.0X܂$.bf v|dЂ `7`usspt儹؈Q@VB`_\ Nn-ry:e us]4 z:vo?o !P+MX;q@!`BLln@ v@\鵽80?usX?5X~0|\-<7wϿ0Vlbd[.0>i{e$/+?KWV]BGώIJ¼>|<@7i{Ө[@*_ Pk@j?{%濆\'Ղz) $mq+InO{ZI,@j!B\e!^`+uOi=c(X 8= p}.2PXXxc<]z ~D+pqBanO)0m dF|.忑KH)o$)_e/ p9| _\]*v<1{ >1{A..Oo:?,0 ˜^UTHPzrlL2l饲p̹|uAMfr%߉!|)>Og5)Q,^s|ɷ}*g۾?}u>: xvyU|Z §i#F'8h!2sō wj {Z1 p'vgmvrzrC2*KqF>Ņ+"Y惻tiߨp+ҷg{]tAF&j4b9rbg?騴ؾvg , 3&+F^&*-ĵsΣH&ogǡ K% G+b  u.Z<Ȃp. ^Zb+x./ l<wyG73SƦጔAk8 %ƷQu~H)]7pw?Wf hh:Kq&%0e9t|:ra2A[_ gs<%j') :=%g'_P6lڛPZ-:/YOư* cTb&X7DܛPuO<fh(A)fPT/f泥& \5c\桧O+6 džn$evͼvvb:J%I)9c)5֛PΖyǨ1m! c"[j1TH8UϹÏrXBj2tp8KueH|{ķia/:WSLhvbɼ{iw߂hp]8 |l:sE*.wrRFq0 rH?룋W/T}Cwkv=| m:=a~x^-l4# sd_5K: e@!tg]X>A.@Uey4k׊=.GbbR)LkM(6}h]LGd`o!a3@ʯL9iy@7Vo0˽8LV<5uE/}GN>a%!\r)US۷ ޛ;BɌI˵ֈ$7P6`cErc-K1V-~&@Wy.r<2FZ)OnEeí<Y"'\sB!yAD?"_;}]])*rEªV˯+~ØlOdI[-/qSJ5w !4G|2X_+,J\=RQ9f3ż]|t{oGÍ ؗJ[z.5+QZz@(A2-[.kN21݄ݲN N?zE= ?PeP0I嚫R|k8./9'Xk-)|/^zx]0Yο MӾVXL.|-?>`r=*?&ӕs_{ єFR"mQ|CzG$kʑ!%}RqWE˗(rY^OWszq$䘏֥kD.D'y=LtãN^tdZ&FS\r#̺om/MQ/]g:-?M".us/H-vJM7vܪbmU1~M/p:/Ў*޺̧W Mǭ24 r{o= Qu9cT? ZG}c]ނ~Uč'\g5%iZYjG^뻴6 H$Ղ:ߩ^ϔr$>K#>O8Z{F)5Ñ-yl#b h%,Hs06;GbCgY] u 7 FI g}$)ZF#,El; [/IGKt LumN~,,57/p[ANgTEez-e 夻t!c.̻UP+VԭU 4bܻhAm[Ҏ{ n,vވcNhJInLD=S)&T j?BMb-yu߮֙>ƴ>  i'Qxd'K3q&yG8e+v71Q}Oަ"*p 5 )u/)&459t%o7 ^r_,\L%;iO}97͌0%#!*,:A|"OVTUz :o~雷ZMa85EU&fB|cE-#)mIP ;XalKwG@WYrNXpTFR25f.vᵶ0EQ[4u<Zt%/6{{ďVx5,E;|KOp@.ݍ9,'NKXQ@$sdm'5y+BQSG$(f.|+)!^jÖQ*z@.ҹm32胬Uwyc*t8zc ;$ VC)6o1jtF4Qޯ5liY2 0Y*'‰$L(Px~o)pHj} eRBI9R}~0A%~SLk.V&Cc7Ho-Hs2.[h xb^\4o:os Ok,/G .ͽ[%gマvig'ۥdGFJ_tuu\;.̶%; WS9P&-(V[,5HT:16hӳD +׋YڈZ-=on}%`3E6P۰fimsGG0 V -P(caE .iwIuٯ74}XGv q 2/F1i9C)m$-w'jyOxm4('  =(]ҴUe[tG#HÕA;aʒob9hW3"W-(R<]>%WSaf洶ۗG?HZQ~zG|p$8Y2N:O%2cIsэr _~Fl^JˁXǾ}TYU8~7]mↄXŝ_1xkK}SX{wE0|mܱ|pO{y6_qG  WE$y8I$-6i)&L9f<烨Y-[g<䝜fIVL*":B÷:9U@R;2L&)1wOٝ)x:Lĩd Ge Dg*DT׈έ<*Q@,pѮfOJk|m)Sf$jF$›F<%j Ev'w5ߗ#ﳑt[mfce_XXq)~f c%zW̶%ѓYk$fi=q\fr솳{FaߐQa&ԏb]S?*`V"v܊@0?>1M2ϛ9Yb%i*XRNJɻJ2۬5:??cUR}pmݘ5GOڴ{!۫~ ল֬&y5GrԮhŀҦ?f>B MY.LIVyR?oQgW lSH+8&9wF`$Ee!h~WPzW fh2gI')ٕ5!5 7>J,&<irXq6_Yn5HlP5fūR"q>g[oM(w $’0n٨B4L{tn[I0ڼݏaɲ(Ǚ8;l=`0@j(?p[hvfј&(q,045[<. >]:71pjcs PR6XyW Yn24"0&z~p.xU:z}QB[^} Ÿa-ydSqNvpҩAP%z*vJbVA%+978/Sa8kڲ;FHK󲶽Aa6yU=^yBxSSƥ&\-~e DnhȞɈ>-R_z)#7ȷѝܴJ^#D¾N ’ -5v<>*w4e(ަ$Dw]FY`xz c\1>iD8gwWkغ2 ~>!TpmKٷ4浤ǹѱ hBWma%1>B8n=^r!&h85SekY Ut[v[|A0ֈOhuuA.tHbg _W;WCtSuwⰥ$8HqDžI#o⛊$TKm9GxУL+e})y)s@3zֆAWz*Q0x Kc߸1t8elL/D3,Y4X,vHZѺiiXlMꂴp~S~Xa c$iޙjDG˽^ӹrwB)=J$-^5==' Wi(%-ZYF˽ 52.2Ey< :$m{i"NXä$W2P]6'bhj vƢaF)iaĕвVMڧ&m\W4Fzns 4ksu@bqt:*Zs1aJ*V\!׵w|]lkTT¿86 Awk_&AȂ:ϳzO1pGvFX|Oc-C}'U3gr{{.i%м.&e-ƨh"eԍ*gĢMOęi J}8~.1eꏉ䐬iVBVd /oLPW67_swQ.v,ank7 =c2c/A?p@tj~WV7 C٠;^=Zrr{-i*w NI^Ѩk7#qf}Jܺ,@cC[e4 ɇSUkv6jzHN#(ɬo4eHV UHH)ʶ&=m״B:DzۦsSADk:clې^ڬ[WnN/tVssT8 9R⪔[gfH̷typ$Gp%d'6V:Ɗ,2RF/|졐x͢eu*\&/AD&?nIQ;/bMRVB/G=F$#-e&s64@1U  I4K[\J; %8=e(l!\J}"3W FL:Cs}XgIg-:)nDuz59Ru _ ~iՔA3|qFZPÅUu WsߛŒ4w<Ǣ jג WQpU/g,5HPH{e\\Eb̪v* nb}d~%y$u KFYNEū-7n|d&eUWiKSHd% O;fopIޮ1zxITF~.-1%'ݯt >1?_qr嵲/ܥ[$hё_ޔ֨Ӫg gRaC%VFuJ/paKӀ2B9zzÅ!*g<[Jt/M MUr!bM(PQM$l~?~X?3Hy6g/PqNfF(琜& >xus:''Qp> c QE?& g<<Hwam%gyPJT?9\ 'e94ySN |Vd 1U-u zAք1<5%ӓʀb_e{6:WBMɸ%*1XKD󸬶u6:ZvL_M(Z؀1aQd^@t:iȶ2Oʞ͵qf^tT+Jg7xgYp6v4mQٜ L'48ΧO}7u K\B%IvܩR_yt\ _ix]k 2NItX#)॔0\ Y*2{u;9)6(ڛG/<,>1*V?|EO4 {K *v񜹙Jj=W*ډ [Zu(ۺّ3"e=Wy-|WԲS\gS{F=tP/M_NW.:Jav Yˎ`N(Xoέ8Ir!. ̡XAC}UDOw<ڥG9INӒ))nou Ek~(y{-">;XpK&js6Yyڙ?!q,Bp{? 5ɄЗ f!% 59Xydo!$T%M_k0ߵ .NY C?v;fV3JuxpoIS#-.q%Ͻi J]/Q' y&|ګ%!Vœ+5hzZfַMo:~369 $_?)h g~K-n }.ubP X9 J1s3̼@QY)k1[r/^evv36 |NU׫8AJ眕UFJI :Xgs1{+F:ӐˆHNS䏓̚Ђvۭ! ؜ , '}7W:5|&=se($<Ю~DQ@ƤO%6~NGs/\J!+ endstream endobj 97 0 obj << /Length1 1729 /Length2 10075 /Length3 0 /Length 11173 /Filter /FlateDecode >> stream xڍP. wwJR\;x  /ŋSܭw"Ŋå{vw2y]cf7Cٹ9D2үy\\\\< :g[ z */ $:?CJ.n^K?0,b P(CAN 20[+< ``p  @(@l{hh[@@IA͍ha{+p8[@N +eWk +ӟ m{< l! ӓ ^S ta. +ss,!s[ObO`D?nfisiK(ɰJii{w;?/+ w :U4:fRb.э,G+wCGze\+P<]i{[):nA 1B! K ՟tSl!P`uY<=NOCz:N)}e< @z??-Aw~r<5oT)['py#!?Iz7~ 8-F{p _oVOe@@C*B+1ShA?u>rqZfY`O?^Ld>7mo!l5B}cÆ~ 3%c؅Tb_'ӹdNWI6'V40:@c S>c ݷcJU%X0~mٺuOY:$y_',+y9rvvҌ,YnaqG?ɸYΆ^@wVc(jΛ}qQ8>:`?M(~~2Gqx/Qcփ?<2v-$M6%1Vfu6\g- Aci"JP: ݟ%KT탿 Iٌao .5DǾر,S,=yeNxD'+{W?!=cpMX`lJ,ELoF<FDVCD.^g`qaWÚVx~WMkthU_C&IoPms2iRJשjFeFkXۣpu|oL؅!Zol lY奋՗^ύ&>uH? =uYl^s# ACiƞ^0FdXDJ\DΔ/f !0Ư0V?y $!Bd"XgAE{,džt-cߐ ҩ-H*cBB}~mc^dq݃U0aӈ}Q痆Kq33oR$w+8,dSz o37d#~oKw8"HZ<zx)hpb1'(T0ٮz _>!=Y򤎲Iy$r̃Ͼ:.yGUDq%4|A[HwۺQ^6ɓXlvV tcX"#6mIAQc6j.{&D>eZB,SenUy~ TbNErHVެ\Z0ێEjhp-J5wP&a-Ki|EHM41Geґ++]DNLHژ,nΖ~rB e 8CEbJmuϬAFoUyI~e*wg - azˢOgla#a^=/@kfBYM (5#f1ָRu.2ڦ5'ltjc.3_xU;g_aU̲[J -7+6W׼9C<=D-+zgrY|^!<8wњ H5 vV E cscz]*ǧi.JKE lRchn촬|Uy )/@,rΈ}J-z0̩srN ,cX%~&%{a=Y9<+ ݬOpJGJFvԔJd6dv´j3Ö#2WA 8,NR3{`g4Q u_(?S3ʬ2Xg,`m6Y[^ zle?q*nxccK,ȸX [JvVBj|5;_,Tt EJ\B6K臫]E4bU!AT`I Ã!E5_瞁F-$H%8Sa|ۻĪ7ISp3n~ ~hjv33r^X`pΰJ#3n "K^<x-ƴ1v^qi,zDeEV7UurY'Mꛎ /ۀֺ32=25ѷ'8~ AVO)gVO37Owi_})Ǟ K 2*U26QZpk(.Ů^rfiN[3XgjTs4yU/)7|.r|+H(}9`ϾMTn? HqtZj WdLcz2eH9'2pfF~xhݾR9K+@8Na׵.YL[deWD }oM8}؛KChormY2B.*Jt/6:ZK)* c28sR2/՘nr5#jMbh_#5vzv #%W^iJvfLʚN+7ҏ&߾.t,@G9xn/%$<3B["ƥ#3) V!X|Kht{i]_seY_Ik׵Uy@ZR=Txo7 vKSl_&gp7F7/2<,K)|֨*9٩uL{D8 epn t~5a}8.qi̕#X\ XWȜ@*mMpSh{Uq\/tyu7oP^̬ ]XtYG9rsƅ-<#NWJCW5s†o>,$2#i}H|w"kr[YzܵzGlAa\@=e0`M 6VfQF0KǢ) փp"t{yӱT s+jY 3OZBjOz},1CԻ⭵Z#ys=}*6tw$÷Փ!y2D&62_=p(GS9UqS=J'|O [SCC3etY܃oϨ!|Izpvzpq eo  ' J߳ :'99C,ˆ#Pu߱]Z  fDYZ~kEag4^6t(-J8Ӓj[\ήêvhʟ5gŞ7kN0`r.{YqުW s :mMV\뙮(e5nE)⩦AimCO*WqĻ45jgk|T-sK QΟOf_)FA-[ڻUv$VN[1_g!YjH-`1;!$%:,EK)uU:dGU2xVa\zYCp-3060/MeH๧-rr؋|mbJ|fSm8ykmK ܞ J'_xY(km-b#'N&dKc(YaFNJ(Yq-@6}KՐUƦיiem?53,ʕ~|QL\ >:<LDm݇vhٍ_{`Y` ߫늼Iرb0\tqkix9[a{Q`j/ɺ I]; 5YLkV͔V-:Rzߜ#d-ZiЦX\~ -x$L-QYp:F\ w[7+<&W؞ wZpTvN}t^5 |*?lL3mm5#C Ūby'S =,1/k" .Evy+}/mCqF)]XY蝗;5^Vqxv0&xo|mеraM*w 6J8:Ihj]`WDE ?4?-4\װCrkW5a\2Z&D7x[Q4N nDsV\@+se8uCs_}YVo~K}(ń(};bBN)WD9|cd GEsOwh;9;۾S$˭4s;ʐFN\Ύ\ZetTk)x[MsT!36/sU5zR4X`<˛ĪNŃQx>8uy7ݘ6 +)?Y6 MЖ(> 9k>kuNZ2$ ڮΛ'&zRvE Cvvc^X,}a]v*Y/KJ<'b4)Jwoc3$/gBԚ7& *~TQ I1L;PI+ob煆咞v GB˥o ~LꝠi@H)ܯaj{뉊ln~׻~3]#GN;^q O5 V.VY!;9pݜNf"X6rauL?ؑe9tzy:U{Ե4+k_j`U FR`bx[ Vj7`t`eua7J=HMNi_a G,QP>gf~w#$Y.laET Jk20V/DZWEmݑƈ.KCzU QS|anיEQ#$&WqJl3GZ߈w uhEwŦkmґ˔@ |zf(!yC|G>D^t(FaPf |O^AV!L 'R:GOJJ=^]j|݋R?=MUs5 #XX)(%GW7xnx-y>,),ͤ+qmjscpU36KŻU=Q "X]o DyOptǴq Õ5pg@C iqaE'*c?N8pǶg10wN=@_::X +Ђ}If @KېsK `*U㧚х?p8ӌQ] ݈IK%(=!;z? s8V~aL tKEPehdA28:~?{v٭qNcȥ`[9$u3ADф4O$׳e'zQdz[qpXgݿޞ?+jaTJ5W226ch?&\yP1*~~%dюd&JNSrLPh.LB2"n[G+.^/krnbH*{tf2K&nQeX#([3G4 593/%)v7$RuyF^/TNM8|JJԅw۽bKi܂`Ld۽$~鈱*fILTwZ:>@:@zᨺQNtyl4۝ 9qix_Mmj-V_ tfi~TqhNz"i꥽Yʫgtw zGtc1iF$sSlDCz~~S&F+>5QċEL9 E.x'qb/pMEڿxFiVywĂ$dC/X,IlHY@ 61e0b7(}LUMA5oDF"bȢ̨K(Ds4ݩ%1gyeᔸ1Io blQņTg>W· V/Hܷ&Xmk~ Ƽtn9w}T*vp*`_-BȌ!sX^1\LSAWpM &!X޶3w L`WZN=6µwbthe qIK Si:tȠqB$4`%Qbx< 8TtU ۆgFV:(41eGPUCz.*{OY YeWM?!HO1>Sp;rcYMo2QS,۳iD|eؘf{trYrT寰1L1ػ zd{<Ęar`Pqch9RA,hF#|r,7}n\v??\h-mW;X0)%EpFL`UbؼORY$r&!=GrZ94;pOG7~loh{}aCܵCrx4"ЌLIM&te1H۝56['LYܜڀ bF &hҪI:fp#d,@*Q zKDŽm[x¨[jrQā10],x >4OBZuu ▧.(HCƦZ:Udnތ3oE>r$~N1Gr:Dfjږ ESjP==UYzj>G$; ]@(1̄Wy_xi(ݟrTv9In(W=˰?QH#xf⬰Y_\  r,(q{,{֛/K=XB}ZhiDkghs_yX1Y5rOe* ݙL4[8\' F(FM.c9US|EDrA} KBxw&,iRS!wNq|f^{-!~Apw/qk=耙xN̬Sg/AqxL>'"aDيzYno;:UJץ8ciVyPpd <׳ ڴ ]Ҩᐅ,CGN: ./DIa?[`3~"M4[ =̵do]Oؒ,P?ۆ2`pSusuEx/[ėd#;X,,[ TnW)( 5"ϝ4l 5'xfw/:1}9Pn< 3/Ї]r{=n12nZ)7Ci|Y<+y}xЧ%K:-}\L~ƕuFo >=A2#E@nRʼ}HrRϼܪfy:雼t**/*yn;\>Dۈ]z'˺KkUk3n4xq1+9T`V}G\"^DpAaKu%1Η p+g^ҭ.:kRh35 ;Qm&X1{BZyA. 2#EDH)>5Tz/c%4uR('Eqƿ-|q-"_c wʿظ HR ?n endstream endobj 99 0 obj << /Length1 2435 /Length2 20696 /Length3 0 /Length 22097 /Filter /FlateDecode >> stream xڌPݶ- wwwq\[p n!;>U[T5ߘ2(HTM Ff^ 3BBle@ h&3vyd\m,lN^.^ff+33;Čݬ{B-|Mi,<<\NV %--@ _..LLvΌNhV.3 h`(jVU]܍7) 2:ނT@?r ?tzEdi[r..c_ƶonV&ogn VoyΦNV.ΌV[Afvv@3_Y9Mdm@ "\AV@iMDe@333zZ2E[o{[@+s?ogc7  `!fow2 |鿭=eRS֐QDD= Vf_K4JV4Oom] ࿹߶z̦o?,ϫ߆[joKvߎj9@3+Wv1~; Yhdbj϶#WZJV]+/2y:VowHq_G`d67fy;f@wys0wBk&D No`LbI?$~#6oO7z'œ)Fo)FoT~x;I7zyCƿ[t-Ǜmd#agKbgY2YL ouH ފ0 )~Koݛ-A龵Mf|?[lo#3sv[qys/[1odoOh],JoY;]*tfr=7rGW{1V7)Ͽyq:hg{ 폾s8[ζΖ;bcorq6,?[fl֛.ɽ1y _א0\~(?@aaޔ/غ6Z;Θ4Ŏf* S lMUFӍpP78"aslXKr'8ɝV Co} jB?j@6qtFQøsW4:[)T:Y/ EIO\RB8Z3ԙiWb8:(Bou^+jΝxx:#"28sŅ) hUV*ƞ$@0~턚FLC'REVH 6 ~JۍFu "ԷW Scp?mhJPVW>A wZqK݈%tRQNM4&[qw>f37t Gh3wsAA &S ,č2BsŻ>P)gJ+J<79 ٥%{v*"=yO4*[c9I"FEBzyn7oD 5*E7Ըs?ugw:+I GBn7!;Vq#kATx,zr/*\=?/V؃W/џ] )m%"cw ̰}Q_佪]:Xɏ-ro M>iq$s[_.?GG4 -Ԥ׎GD`٘1?I J2V 0_g72c*jW1C:O>q&eOyH*۶M"DcéjЏyV H8-T1*Jl$ 5ޭLȠV1B/֊ʌɸQxsr hLLt>2dEbT#1\5ck2X "⤑o& sGWӺ!˳՜ൊt!<#KClDÑhݤKn%~v.wR`|iM>N,l_E`ITNNx;Q9뵴+JU~z5g^#,f.q\Mջ@8e;}!eLTҖe\5DE#9,m.#"Վ@DD!Kê e6} ܶidJEFŬu+6nYl=u!RY;\Ըh[j[ʮEҟ?m<+Tx65  l͢A(^q]p{rY^xJ# J:"%xȥ^(-ol9=dc$/ewF qBVl(w4'v(;d/xX_\MEz f#x2^x4oVf"93γ'ҙ\J Nb#+}i$De|t\zxڛ+╣ XنɒgDH',Fܮt'[ &)[r< SkHx짬,^=4<Mfy|upB$ K+ftDjeyu)5"-Qϙ5` @ 8Y2o}쥼<i-(7i#ҹ^2YT(D r}K9aL^ws]yil;$[ۭϑN3O8VӢ=BbѠ@b#yRJ%+;z. )FJH"kbQ6f SggD=VjQ 3|yPU o -\1Upt*iGNO}ڎ@yy0+1 pu˗gӲA?Q>SQC^Xw~M-xʱe"hS,w7Si9ͬ1 AI2r؈pB{9?& T+zJԯ-ؤv~bU-7y?mʭ-'\a8 8'av_^t iZJn1M6q?0&7Й xyo֊xUe^ ʹ@l 7'Y`k@wǵ#-䩪{ Vqok/2{POF|!pR"fh~/Sߒ$,&6)݆t.KXڱ)OV.Vzg&ȓ ,ezܣ }M*<v4VxnC7őr*"*"ƶ=igrZ=Y<ňn@Wd]޷Kjxr(FI?X=L#uuE o'6<) ܡ" JL6\60 Y2"8. [=6t-W5!|Hܷ_7Mڐy__xGd|ͻ%Sc- ӣ[850X ֒#Dt@UY_{k(KV/c?1nq0@p;r‹ET _Ǘ8:V&,8dK}>]OGRasP|F|Y_5JXibwR׻sU $t d\nF{x:ObߴP1]@daDZ* -r%ʈre6NӋ1@^I[T>T$6vd$5>]F̞!1)<-g,'@d]UU6)|Ud{_/4^Fy[Ҧ`BRm'P@77F@D ޖFM)[ߥq0g4f)Itrɸ &sE[%*'ag4՟}n{ g(GH:N#^F "j.6erQj`KQD-8Uq [Tw %Tf1.gL3=qkJd47^2bh FXiB%m^CS{==|䝘#^z*0`o0oyhixpTLtr`cCK3]:}xKͮENbHu!P1PBqCz/$oyWPVHE|'ז(O ͦ6Ju6;L;li[B9)g&g7*;FtQխn֑['b\<$Yo}v Uw ,E.Lg_֣F6?հT >8횗ZX> L5KqBmK;9  ir-^h<=BvB; ፉZ4#U)\$C:d(Ǥl1.-jѝ #WMX|b(A1Hw#@P'4uk5RNzDq^bݱQt:c{},/m\ ?Bc.}7X|”9hd|^4[5f41"}dL)kB8zzoH1?bǧuT6m EF)LFд}L 7I9y*k`TWLmw}ȹTGk'xgb,{Rm^,Fc]$r&{0XkZm˷xzkҢ3U)b_mPxp"5?>Qɇ:tMfl,N-EAo`&/ /^o rD*U2۠ YS41%oɻ%&8Xù'Nx0mh6Om3!9;tr'$(0J"j/fF&;x%Nq^aUVkiZ-5ga͛%-c翩ABO2}uı&DnT^37glmSz .//F18]QAY#‚%Pg8ӂo><i>B }YC+=]G=wʦ>-a9PrV ِV&]U&.d&\!͘43=8_t)`BʔDVնݽeؼ'h2hsa~R[/*%YC_ܙ %lZ;Zh Z`ƴq21"O @Gb=go\铆>\%`EQ` EjeIx2qRQʩA"^Br qhpq3Un)Gii0HCZ[5wkE-q&278X wRj2SP0'R'P+:cJq015ii:Ё z*^ۖRA+]Xay"krvj7Of-ː9oQΘYOxP0ށz5}s7vo_լNh(Cj!qS,DiȬQ|P.# lj0 Iް]BFקf)|{Z+,ϡO#%fétI>G]-cդf|J:޽1H}Jr]nD%ϞLZQ) l}?qSّ">?be*p&Bg/\8D;UP&IpMy˼yX2TA!?9ބXDYǀ}Q#hHǏTCj9} ŧ`Dm1"אqL7I+X/$1}2{[&FƓ]^`J4d?`Ru 0~2bh.@w~gb 3K0ҿ^f*I}L*/o4 mm22[j@/8n ?ѱ:l´"eSj'Cw~)zM\d{WJbeu<,@pg Oq2"v4xS|k@ 7rp}t-c|5o`MmȆ1<0@|HU{?:X~P׿ 7W/wH?կ zf@Lz5I"r/!R{1>^G悄U"^Ka_ Qn =5Y4gI4؜DrV)kLm>r&lg3*-];t6ѾۅB&M.햔\uB4oG 8$c瓹;3~pdj}T ܼbh X,e2 4}(apd).$->uPC+by7g +),̐O0h=+ MbޛuҬS--eZFB F6u:frK#Gz/3Ǟ}$>&ZO}BU ۄLqpLrrtm Cw|i*m\zNF;Kgb ^Ekvk R,LMOg8%l@A_IT׆VFNL',S4@x?z^e7X1_9,:qF>.s5Im _8 m- ]Fv2 3͉:uP_%A(U|!XWySJ+Cx35#%Z%wS,];<je:k5uRBVQ4khmUS-6 Kuݳ@O5n>6J:ܚ"Pqv:ɗlÏ(G0?HM\[?G71_lXJ8/fR9y&[麲SJWV}jh (ar}Q:^gRe^SyuӟnoCHz,O0x+Hsן:Xɼ^l%lKͦJtGo1M Sf'Iq69IuL"JjߥkdGko%3;C$Ye4=]eTNl;gZ5e /C㜭~aRw[nAtk؈wqL!/3(MC,">$m|ψw\7qR<T{JQvqf4bϤ,8G-N?CC~bq>(fs-gVG9gTZԨLafcbXl"';|ASĪl?J7i!Xa e7zj!-n bFW3._(1Zx]6#`;`^/sƖ/,5b4Y(mɅPJ'Fb- VѦX&BfNQ b4r:Uc,~68&t&w3eX_kq[~>^uY$GH"j<`rZS/8aɱ!Q687^y[%%{O%~v^ --e7ݝ2BFqD}݄!Z*CBqC^> ![}!u G|̣aI`K>f5-6uhH~W(&$5@V (&@T8_9qT^*OYXi:^jiXM)8E8}}R\aM?~.|נ@bikF(s>J4Tc3_t 0鮌C}k]L{[AÚ,gDuܭJ aÍ׽^_4 ƺvDcu9N MԂq 0Ic?l7=CjntYưVwAMRɂs|<6=e1 i"i [qG\#SyRzyk tz՛ψ-e ϟ@*v!a K f,_S ]rᘍ`&$w<cӳ|9B7őďqN {<u)! pLG˅J+sVψYyVRi 6h ^#]?,\慌6Mq)# 6jW)-y x@E{uJ8gp!Xa:k;pkOOAWl{`sR; Ջ)C)roF4[/fG.0W@t%Nڴ;pƝ, PuvTuJ=#2GXBᆕJOԇYШ;eB.ML$N8ۇ.H1c=DX&NfdAX7 _qV%mk<Xm '9?wٜNa */;f:ad61,ɔU?Z+R@s%gs%^0N1閐~3)t]|Kǁ M0igs2u:(lYAC,^9Jdn٪+QH5oȱG-fggG:^kJ&}j]T.f6cZ|Dcg@ jh(!^"@`#SjBcrDH2v´V{;MF@<:Г&8Zl]&d=6|*fK)yNV&%A׵v)|H{Ul/aaE)aQJ]ad^4A4P4yGzshUi'~B>olӶ_nTs&Q콾\=7X=NZmE% EsO``DXH0""_5d[ ]*p@AmHveH*uR89 \gU8)- ﲛ2*Duws;u <n@tXUNW>ܽhw%; {tXtGb@y\rWRܙINf1_N%hm+kI2mJӨNgv;ÆUjSq>X[HRy$/,qq@9TuTƒ iJ?,:瀐d%ue5zxa@Lr3}`#*nKU|֏r5J Ϸ<9Kgl_o(TOөfAp2r:tWt!gOpiUgu;0˖Z r5u_A40  ΍5So6ԜLا[`hyF6jM'X{F{0`Yy%N^MzTؒv \uXLi .srn,\^LF%ĥ:85Xi5_'"׊ﳧQ4oj\սLSԨd˶[c8:W+yB;xeDi@|)U5.C4Ag'/dyFA/;,/ƅ--]B<=R&/^oY34 mKn=t:IonǠ};T}R\\/0\K*{;C#BT\6*QGcCL'ҧ {Wԗq#,'~!nH0΁sԂܦG: øޕ}مB >Q;`mbtVKtp2Bvna$V^m4u_ir/' 3'Xsu3G]L4s;NXp>fw~ 3+dk~]{[fZ 0rHwboudؖ Qꞙ  ,_U0Ӿ(Oi+;eWOTOnLOS&/3"}#A+VKjQg_b.L~[̰m"&eo/N+րfI)tHQ4D2 v[a@f!e keAZMB%Z` _vsN@cSWu7'[0 ].VG!`~*@}zv'A$dwG$ )L[w¹k"fzɑxod>^[} ;/O|gݹ#sE~܅PGm~Uuqx~,A YvWU7fT = -5edRcXyU49hݺ-Y,h9~ 2+[RRU O1UY5] `Cd2ĘQ.l&`~#]<DV|mhL`gՎ%mǍb; H[*&W'a9V\I~wl V5I=MB'5Fw;?'0"*M𮱀TC2bc1ZgRӁj^3n +lsF#)dif8K1lm!$q&܆IAhtr_aUh=7|J{lx*м=KWCHHwj7PVӭrn&72bc Dm_|%G@\r<\ t珑Hυ&O[LUz‹ 35[x~&ַ0%v߹T +/ۏNTa6 F <)1?BTE;b+!dtGӤx\'K 8\1pxlf~~Ӧؾ9P#ي"XDĀQ\4P z~ؓehJ؜.f&&_E[=Gb )TErEP^دy9^.:KVPpEh.r"b`} L&PGM~]$ uV꧍wt)B*JleN%)K^ߝ҉$(Kʧ5<NS,p9Qrޫ2$Ki:Z72&^:rE0.`mngDyl7~&g_{ <{tF$YU"dBʯf=< *? :#wCS4wcNG]M1H$*Tk'Opxi2j@Xjk8=}^Z&xwkߘGڷ44Hp|~PҕN(϶H :Ub4#U 6ScgOq-c nNIFjj43, <)aS3_1|8j|6G]*跂?>KN̄A@Fm]94ȗ7䰶 f9hDcu&i].SnӜMj> ͑9G҆M4َt!R=Cw%3=W'-]][Ut_M\#|~tE,YÇjh֟0DHp=Č[ c:d)Ȃ52«[$M\"lX]HN{3ᔐUU<4Za^H' ˺꽒PqcϷWdԏi\QK8_;#N}"CzώڰӠN_>O&39l=*?R,Z.; ]G#1>x?\f#KSe/т{!Bhtm'c7-b'ʥd\`W\JfkaR&W51|)1g\ӽ_u>A\NqLS8F~i{[Mm܎OK4&gI*:iVD4SLUp75,F%S,sN"Xf*&g1;Ԓ!v͛F%%Ԓ"+c6|RG8PI/s={>*{(!JҽJYd"E)ES RV4͕i汬#I;ݐN4W@qY7T'k~G|U 3?DQ/1@w k_tydWoK ##,ƕNԳE< u?KO={kRx5ÿT_os:liZ&V|Pw|_F% ~d}4~2ZJ5d d FOCTȎ-<\17anTY6KMY7n L4Q~2wWO0*tR*3{4geDዲuO;!, gC eS\ԘML/G=-=W|(ߑmߗH\b;c'9$Ne8(Upk`)Tg+H,[rem`ֳ2.N,˜>/.xE/ź(Z6}|u+S 4XBXmXkx*/YPH#*|u`830+TQTzF:[V D. C?pDS Ѝr,=5Q27Hm;t(b'S LZvSʜ+rJCVU”0qGw_-̛Y ;Yo"-[^E6Ju;N;ᲵMk!B9n里yZ% _gl`7S$^JTNgS ADE52 ^v5ѳ[dM%}sjst>KGqGf>]ţ&حOqi A9#PFf4{hev(!$ddHWu $R1*!{7  ![Uʹ_2I)7^0 t-5籗ȔA#m&ߋ ]Ua oo,Hm^2eL}NX0J o=rÃM ͡~ VrsY"MXB+DY%1a[Ʈsɱ1unCCV &6TSt!dKGLW)Y@>k^됂9(6PS,-&o9+3l]'I2]UMm||d&bЍqavq&dyM˞n6JqA*P2 s(#6H2rkK4⽧vj([pwR1I<4&_87ƒqz LTPBW |ǵpfh4`Ct#=]8 &#UмFa@PtxĴvs_vNjD#wBwm8rs4Ϋ|>ݩAUBkq \93ߑ,tⳌss$77:r3 <Ņ_OڪfS>"U]c@"G ){ _c992\6_jK=~VN `ڛngM)|.c[ykPFq\_m]; ep4""Z&{.lyڅd/3.Kmfh̺okEiT٤KHV'$I -LJ[K /mߓ_ *i5SQ)"ӛ02[KՇ[۬NDw1{k,.$$dYq{d<\z F1”(a5E SGSʷbD`72H˓C#XETAZ(8N!c.=T)&Vr L,ֿ@d|m)c[9?iStq[zCUu4C7m C m-B>n{ W; 1N%LP &W A7GMظbd!xSZY.eueZH4/C%yRUݒlv_|9`T-tֆO_VܼV +7F^69yWu#z=4KGBPC[ZMh&?a-ps&'[>cL~ȡ?Kǩ[ :䤦PD6Jhi0|;qFo-2 ln eZ/W)#%6S|cYV`q 2InXC,~)M +ˮ-鱮r$qӽ^Pt1:}dBŭ)H5L2&yw=@UVm\jgkU鯫edvM9q rvTߖ02; FvXI&)]CmZ.xm|&D$()lӲ&P"9!$pZK_MTu(T$oʳ+1DPs}j?^(E{DbV yI<E}뜐`8@Fܥ.[tr#!z'=#CoWl;}ً8jO`)PntkRٌؕR>Ǚd|Ҧ biW /iy}2=@yg Ъ<r輗>Pk@A4LwgJFI=}{49Ӊl3s釾co,<.侾#xc]P]6hsb EK0^8X2?!9S7B`x_n`APNCc/tTns;8{ot1 endstream endobj 101 0 obj << /Length1 1583 /Length2 8326 /Length3 0 /Length 9375 /Filter /FlateDecode >> stream xڍT. )^K(.ŋ! Z(PHqR@"9s[Y+7lF:=NYH ukxxxx_f,FC ]l @& PsxBbb<<>a1l ,Fy w}8?,֬^QQa?N h]AN'Z!=5_)X$]]b\@'.Nv\@w w-θ`?z0[W x0@ C<ShA?8w'CZ[Ü@jC@m% .WOWj@0h@r @I9_X#pW.0wܿ_YM =A#E Z)? t`.߯ |er<(aqHE5  AH|އUya7xh` C`Q!oHX7}@myܠ nVx٠=" ]@J0nWؿw=TO7'ff@<aQp`[g:G]l(,S$wkZSr٩^gӸ}OFCQ{y>6kfn[UD 2{<,"LfQ7Rb jw,agF=gΎ 9y$q D&9GST wb%lhߕB}z#ek9?QȤ:x,)1'nN9'F%v?r F  fYFZiÌI2Lcwk*8Gu7{i=әH3PLY)#1 ϫ EP&|lɸf6nb.J<+=hWj:}[7a\fw!J!ȵNaY#]<~OwgnpKU== 7]9s8B4-ڕȍ sN6c+]bT z\֜p>L ^_h^G1$\˖S"AR T/DR&\Ue=F hu!Qv"| 8\#]"N"iOg~XZ^W̜wjָXZ]lg 1]o,f&N>0(Z+.L' Mgb-5~΍Jk<+]Ǘpu0G)I2X?p.?y $R.lF qǎt$}=by)3;ED2,P"zdpFS6ߎTy2řĪ8zOw_C!iMgh8*Y%c Ss~ ȐrjŪdZbǩIO3nB_ 1R_tdibzgӋ/$;i͢Xy F"b-\8frW6Ҡ5`섋kZ ''b4Kyg8{AϪtΈ0G[g#΅_BΑ0 t8;;I⩽+Uܘ4_ɂ:δGx5mJ\Sx>3dy7VU}D/62K`{~_)" 5> vϊⶪҺ?`|RV^m`v)BQܩx/6* fU'ז*1-d)mg^/] ].6rrDF#Iz`v^U |/eC͍`Xk (aUE+ѧRZ̡݌!b}RPOr|Q[?gK3Zc/5̎R:je9w$8HqI  / *[{vA%O;%AOvFu^{*luvyMO:_pf%M, ccQP yc -J߫vEM4o,1 OJ*wSm&ش1qk o(V mT/Y)F4OGXZ4c1gu~NԆtlʓWP%"XBy/1W-(yJ#TZt&(2?6R֫yM\9~QV<i+ro"rwl!i_2݊?QtZ@ ĪK-Ѕ. 2)G/UѤ_뮍٤4K]t/yS}6:[ ISs(%|P=Nhj=*3ʁr5juȍ]gw'-4p22Q1Ҙq!A3`aʹ*o)k/7Kjr~":FATt\`w,ϜyO m[޽P4!@ZZpTts+q1b;ї$U#p"|c|ϼ׃ɧC ])'L(MOfq qZ.0VWja|F[=S%dLgG7M ,Ħa%/Ca|x+me(ԃ(O=5U;-:+Ml>ƙukQCiu_jk;F)%*}ei Nt)_Ը`䄷M Nӭ-I%n]RNPst3~1GiM?YX!ɉ鑝Ŵt(h;to{@R~_wڢH| fЗ^}+iN{cdś4/ ROō:nغQ]rP40( %-4vlK'ѫTJWYܩ \O0̘_=7 %&e[E7':6B&7M uJm)c{#T;|p0 L&]rnp=hrp`Ee-S"C)c{O,D(QK jTBpe#5D#H5.] 4d-̽WT.;Aޒ} Hn$jBi?>6,;n֓1^\OWH.[vuALĴ?'UKD+VMynݚ3'-QfN/_lgx(I؅C|%+ǔMf%KRԭk~7a6rn-,CLe56z1<ĻbVtLz>qmuu0jMQx/<H]@51*P,PSaH@mPlrqYԛJ1K=]x\Z_~&8nyZuScq=ŶMѴOO)b{]lmJdr>ɕC^C LC7>-eo@Ѐ\jI)=}l8/[ Ϧ }=6K(r]v,sB;FeX2o#I5ӲBt*k,>w̙Y8G$X$K%je,tATUhV\{%\@5#_GP~񪍕c|a/ƅBf{A0\\Q}LA<0)%Fyp] FfU׼^z).MYÁ- ?l^~MKN8Ш$Xhavr5qȲ'yӵ鲐ч~}NS2XaVD&ȴH7҉a*yT._WQBX&EB{!JLwDշ[:uqڮq6!_ gsCid"^7mܣ;3"f)eE ɈɞO0Ϸ ~\;%ޠ5n@DtkH[ƪ-M*asfCwڥ3VCwg #~D⇅1I<=חo{tX> ئBs y>4MArTg0Jż7X@K_Ht1=GS ߸|'5uo9-Tּ{upVfZ 9e/ܣOQ(x$5tφDm!q n9Zi*q"@ssWk`%cOiP=3]|<4ũu̞GozoEyɏtJM }nL-&`] ] I[ȽT+;ٕ$fp+9bX):|-yl5Z6Zn:IQ?c%]Y>v`g_ݑ0/MǦLh6zvhI }i w'_s ߐLIc yȔe~n= :%29d4݅&Bӆ!ܣ DZse׵+ ˒d?"gGCwXf ^;mjנ-{xhi ^9"yZGe7,Pq.'?);=yrP9&;ȏRXP ;JpǣY9%cըgIFhNzOZM6чޭv?@Y;?-ƚNt ,M)hϩ:04i8e7'Sh$\OL:Cgeo;rb)1j1=%ruQYd >lt;euP $FϦnٜ|XNGoiymg9}Yu"%YZV̤PsI30>)nZZa3^jcI0}b+yW/r"Mb֦X[%i?exm\_OpۢA" kh8\PPB`hX.v >k4kfOڜUSivdiMlscᬬ3YԪ\X$1 L]o9G}uQ*USQ .)\UБ0=6,!sƐ\z1SC0iο|&)㵈9ij b2<B \Ŕgzy-Zl][1z3+wF5`ln=~/Ύ#Tkڰ}s'Eއ6mx$t. aCݓJeG|PWe3āX/W91BzD)ohE6+l⃉ m4?"5}WESoڪ_ ek3k!;ImkC"JׁXߺ>W$أft^ ׭w^E+?ahjH T+Ǩ:C?n(&z̠~:JZ̀W`,A(c/ܵPȯ& emim \o%?5I!;R\uz&fl%VzpC3 L$t =Śq8N^Y8gB ֧k&oG#>"(u8C]>'jSԏ)gA]_pW]ȠW9<4 ÈR.h9WY{K1ɹSjYI!'WՊWcgHK]V)*m|)t(Y-x0˘R։h;Pk`N<ܘDҍ*}bW%i̦:Tuo1Ӊo|˔OL!@ӒV[W/#ͯ!=y ;}H|)wne2\1u9xBn1UR O3Q٨M埂XX6rBu^;85GlЩguUiUE?LQLQv5M'/ۊg2vp,UZ B?'7_V͞ѧ Kq{`lc nށd&s׏Ѳ|O~Tq ~Ԓ<QjyQ Pͽ46?o|m`+,:R_,5{Wӓ؂ZO?a^p99A{Qa}yϢgL^&F07T]g5%g Uy;O+/p,`(KUlr+ošѝ՚SUI Wm{^[Ә) yJ⾽#LS`O+_+@BV^zCWÂwX͛Ym8рP*E;S6e:-h -NJLk&z׎`^di0;3b[a\,a2 bN! Y˧TTˌGxB NCAJQ(Ip8%f]D.khHLIHbƗG֤I# _^Fv-LקMAbNUK|͛}\P4mi5b~EqW_B B9ECx ѿ`%t]_3Fhb~\"?o endstream endobj 103 0 obj << /Length1 1597 /Length2 8938 /Length3 0 /Length 9979 /Filter /FlateDecode >> stream xڍP-;:Xpwwwwon! !wBB;3{UڲYTӼVdXe `7fv6;/F ˌBtqA tؤ^!`#+`cO E e( `+ $dc<,L. Ks0@FKs&t/ :![77'VVOOOsGW=f ] rEWlʃ!?} zs@^D q#6n6˗/g',7oA2 ^4e7T*@w3qcʀVj 7K?]9@5+`fgcfYڿ/|Y~4b{8y..(l/B XYK{k 6x N߈7#_2_hm_**ȿ _%_/R?_twqyCx@/%"R0Ԯ>VēyRxf_7w٥1&;xZUZ=DdW83R`q>)E,)3TE:ފw} G@:lD/+N Ib epw~0SIDgB'c[TufS(=$q6'"Rۅ5M,gG;1;A `E-均)er0T{_f d;-c_km;$^V?Fފ܆k.^q}fڱh"LuBMʕ[}x-;r3}),g'@1+xX&X\g02J' zU&JoiDLt+Q΂.Iz^#)&Eg,-4o9(~zLd|L=Gn~J׭4$t|=,G<:K SW!{qp[޺4lo5% Ǚ+g'N*鏿ȤǗ/͜fTtSHJ0x@$}aveq4~x5R'1N@3R2lAGάs1?70Wnxb֜NFR'HSu?$HdTEPQ/׵̲4k,~I\>L,=̳TW_oc(d7OIFD%~L=[oʷ4m3I6xT"Zҵ#[WS\kw ,CLZL-m_;M(y$?+ֆt#": cVw0ݽCގ d"-%;铱D ^\fp C9g( fS ʨDmX XZ9M۳E?\PWu}4K.ΰ|IX7&\0 \ b'*ulE͈ne?m荌ʅcY5/ǮZC)VQ-b|NP Vw<4[=Q:@[ɍgco70BK[{®|\u`v+رyiЯ=Xg7$F-+NU ܕ6> A6rՑStAqs+a,rB[HĘQ|R K oeUiO`> oa=~?DFl%8E R"Ėfڏ\>Kбs pZl^kG컵Yodn}N1z[ĐCѽe;;=gE"l+^:VQZE[oÌ>qVO_U\*tIoRXr1oVxQn3j\Vf ܧ7vLQԠ}7ݾ.qbz17*ڕa4+Ial jiˆE6 PwÞII O@z@=K 6\I ih{і=H4*vi2\+Wx(^ >:8 26aQR]@W(,:Yn;1%3ZO"v){D `Ye@#͈ʞܦ3ɝw0;6)JIc h7yxg_hc+nv?K5i&O$+GivU*fn~{_E4@v|XRZEI˖f36[`U}ۿs59!l1he]b'֔A1 <%toΛ5W@fS't “sF+[{Cn؈~HrY Lë <ºoanX8֨a#^93t vRw!/?]aIc#.P/-:{ BF6jU-GMX h]64Wc(~VТ&W}p'\K-;OӄQ U>1H 3MrEmqr_Hpu&x6 '8=G1y45k$1oɶ]I2dg;yP+grb"U5A5´_,0X֯t^!n.l&:E9X-PeR 0 Ƴ}Wo UQ'ߪ< C th*x#`]1~e&A jImA{P)kH3!)H I}J,wsVE]eT|;\!d(,nSM/ӯ\"T:i6=1+ނ٠u05Zasc܄^/,vp?4d]`]6&TM[%"{{MUk0&vH%0ePϣFe֞TD?%3m6\@Ћl0P|Ǵ!D: Z(q@XmmIq5N--NMkUfY?fw[%p.s_3O>X!/YՖyQeC|sB V֗KVk޾XۈÆKuZu}tS/bI9'H[ MI\R]?t<^Ȍ+YUm.;+RFj۠ޖJ4޴ʊjz:WmW _a|!;>9F"/M~Dd*kȄ<`ȧ0,TDH6f|q)"Qu), Om}W|;;c2 =/f^8g5(0g/T,ܥy~I*0E)گa'[xr3`ུ*,B[gmhyֱ/f8v>:77nI<D-+Z\iG]d H6}R @ &iRNvׁʫ>jm[me[<]z}ʒ<:S.+?@P̫ɁMY'%JmKS=uVhuqx/RUFjkI^0xH!M8e(4ts?q&8LT J[%(v,MNY^;^=1'vi2-`65AD[ nAJL[Xh!}uKApaho>?~kVbPϬ©&.>fO<<`ӁӾ!F'DGŽ-$/*!syvxyק"Uuh%X$fN7 tCt[?gcM ?w7Pp']>f!xoroÕ˙,"6/ 2j2~ &>{I5:{Z9vTUP){?'|"A9HXuiX~0rR c:$U3#J1I1ӂ/[Q,g7n}Lc3ofkro~0 ĵ`}dV˭v0Sp4jNP*-_Z8&! EW3T&Fv=R4*u0B寡ec§/|F)EG XMN7J;߰(Q [+꙯&rsfGȂ ^1WE7ɗu;66?pK%9=EN{ȭq~~z=qX4`8 f)?yW̉GG Gg ^(CV?ǤvڃGmr/zOu֞L )rP߈0^K0,U:+1(z'Et'EXLըQ)CWE<>6䅹I#U4&w&( 4Bƥ֯Ď]'$)>z^p'=~%?CO 4x25`,čt4:˪J0ݨûL ig<.ʔpA_ņ(.2jheQRT(vX%{a֮ ‘ERL/4s3pU+7!%;*_Dtc=:JtB eY8cv󤶴*A jbf5҈ >G3-GX{`obz6v;HdL1XLLev5ҽ>n-DC)2H@$%2LYS ȝp<)~"QZ6}R &4GwCw9ga9F_oߞS?rĈDjY6Sp ![Q'48bl\J7fY}?.4FHl%+c+?rUM-5'Z(~g٤_ v`u w%#l;<ұ8[q0zkh,}yYQ! ].ht"#'z7:=REbv儁G7[W.{jv0&Y?[%@gȤR$>_Ba65OrRf߈j{$* HIb^]ׇ8b:Ÿ"+LoÔyDjwbk*l$h6g,rӲfCްX[Qj_ ׏I> oW<[EJPt1 UGdؿӷh B:gG o?E)ec%GlGȹMh_?tP+͑O # ?zX8~ʇ%>:\8@emhZ?"VKz;W7Q %\U l=!^fDcN@l;/؀jt|;j8֡Yȏv"MYn㚘KީHsZN;۩phaV7}n'$L_qQJ+6_UV.I^}4a:@X4~nڀML=搎<+JvgH ՑWjVK0%jyU8,ۋvꜱ44GM>`j!hXd<Ѽp1 OW+ﵙY)ѵ~tH|N(biB)*ѽKg # ܍& n㦄ڇ|RɉnWb6[J2Xmp޲;ʰ&20a d((v0?Rҽ S]]ŚZYKWb#, E27*{LhsVf-ۏF krF b΄KFr!݇z»J^5,&ˤ2) Tpr1Na ãG–iˉuXV9jXl1oC> =+|.1CjhTZj2s{/;FM$hK9lYMIܢYZ3Eq2h$"gq5\# cRƑLLI-}Ժ5a†Y)V0x/rCg6+[-{a1P06بxvR*p]l'صs0Sѹ_ۺRg./+l~~ %~͈2.,0ֆtDV_Тw-Hugb«R~7?Ŭ%i6> I4=)WYZW4)'>&$ٟ)[&)Y4㾺D07lG ̭YC=:O?9x,m`|@pN9yw"j +{ 6su!|$+~ h԰,ŋ5c+yU_{밋D2C9j Z$3M@{hBr]$z\2ʇ[d5s5C`+94+Nseb$ed:4vl}HBo&“k#Q}JU|uFL:6PBƨm#G )a)&;L|i-UIBM+$ `$5YpNx֛CVyT=7EZ, 0z!FzYȗƙ,ua3L9 w&C=K{Gu)Sh3C\IHٸg"ڱS@݈U|=+KhqW䰽.e?r7ǃSvRD%E z.1P8˔ MC:X YbC yzʣOв&((n.ZS6 $G2Y:U RH߰ L`n0ɏ㙟E'ǖ,vCs\&4"mV|ד*nVdǷd MwynP4bmĎRhۉ.{]m̫ 1&fm]lVI?L~}Yso}79ZDh)EmqOrXimiANףӔ,;ͣ}xN\leH͸odVHnlFLʀ UN,T,H+Y䑿I*2[!Vaիɀ~!B,,)m8-LwyVG{r? U'`$c3HOBz݀v>up>XIx9Y^Cqd`P[d]fi\ۤMy {Wcم)+T7흌ETsBŚ!@iAٟ4t!fh 2 *l=fki ɏDYF Fm2h2N,*{ *p}VDb8 A3!9uzQ#2EpZ}9'yW#|A,kۡk:TCc 3.GxI"b?b6StmtԴT͠*U< *v.PmJjRfbSˎoYWJꡐ|N,IwwR(4ZS|8#1g~ ӧMCףHP^{hBLp:z1%q~ \z.<:bNu;a] endstream endobj 105 0 obj << /Length1 2611 /Length2 16983 /Length3 0 /Length 18491 /Filter /FlateDecode >> stream xڌeT\;w)݃܂Kpנ% <]UFQUs\Pi2[́2 'wfv6;ZGDtu9 FhIMAN;'GW _C@P9ݐ%A>6H 2wZ9mfM-(lݝXYXX@"L/[w .b8$j*M+8ZNN@W8>@S^ tXo&`ga?޿lr69:9:YlU%wow&oC37lWfquTfjfJ4FK;YJNnHuZ;;`+['KߥXz8j;ٺxc!Ylll|6h8Rs9l$?73O o"$vv;hm,ZSj 0d!;9991YuU)`xyKffD*d/Q?@=/ <@ݟy7bf\7y9x88eA_l#^ex).-VZz8_x-ĝMhfnaט-vN@5t]_'nKFvY9nx8~z5V';0`rE}<VߢUJAV/UA\V?̩9 >?̩95 Nkt p@!I"c9wE Td_.y5פ'69K3|J8G奪,*΍2UȪM,7ߢ31)9 g,!CQ1Yߪ,#\oj&qdJ_44Ie%ǨyJ:gpgem&n,%i}U5^7|LJT[G8M_ ̥A*5ۢr8[v#7xq@R絞%ALՕάro*%.zic_q9lBC z0u&YH= ?Woȫ]ǫY.=Wl(p46g`H |M:Miח _Y-d&-w7!iݗ۠G67/g=Q>*}پiݞRh/cv2d cVd CiB\޶cǤ6/{7Jo8SǼ6)]ɤ'g _|PJ[`+2 !}"^4{59o6y؊4`,zT?3[]Km-m'''iFi >yn 2s%>CgE% _eUs#G,.4Ө%V6w3vLT3ul"?2A'hL ޭ8 ! _6 6-oNi?M+6 hG_Yh_eTRVU/8>!XCjg"}56WI?&dnӀ녺'iߜB)LA܄+u9)L !䛟U4.$cv]u?1F 7D/Io)Dè#-JZnʉ9\9"TyV 4dIAp\ 7)L uE\̿t}TŔUBd6z\+ 9(N#ӱlMZਜ਼0W)fKpnս)~`yXӝɲgÞ ֣6y y$%[[-#fk$vp}nķ3Im}M*{GՁ+$]哿7-3 :V\o/1)$ ǰ#4d9n词L6 Dcf6oM\hͫKzeRWLrP%G]rܩV2 <έkeD"[,[5``ŷVszX0g쎜Q-dMɋ˙f;_~zm9+,mR%:;b0`p%ҷH[dRڭ,Ej!нw3½&Kک?{Cͼ}7ÚjЋPzࠅu# +ʘ%bܝ=e1,\q@ q2]ZQy6= ϧԜ4>B<(HWRE4/Wy86i˵b әzфoP ȇ+uYEJuVˑFbm3pʺq&I\Hfgưg{Ĉ@E}e/#I齏]f*ԼaxU:~/N0":}Rڻ7I"D{+ :YɋdloQ& =1f4< Ks׶VCD+Hߪ6GW/a´@SsC>Y!9}CCx?bge(u4'-?dyw" '!k]yevy4oȯP2.[D:̅K~q玏NzqAI؎WɌV ܳoqyɥt zd'u(9-v/pb,Yx{{ds x\\^ ibGP: pin܉ͣ1eJ Faqۅ >p5 +ʮRDfE՞V4&ii!E~jlYEj Q%d؂oeOXQE%ǰNFB@EFv$3wHGL g})iĜthtцM>N!]8d:rsw-;cx[N ի+VPǽA]+6/9dNN 1@wiu2a8b?jZů8jf#͋٭r z.$80'C ^}ÎǼ- |,sJIpqT`KT*9̨Kf l =JڱSgRD& ]S']%717dKHBtUV(?l􁇥 # mb' W]Pn <^D{~F z.Wj8^G.?Hr|q^) tX%`"Df RM|T"MMV.s8`}xTzO6G\~~Hvd6h;@Ha$RTwwȪZO&mB1|r,_eSl KjrxGX&7,mJ SLKD~S1w<Ԙ^Cƽ_EZ9OçY$br`0vM9qM[P}7I!ח@}՝3d3|nGh-Mҍ( \WTc^5F^CrL% g#_ w+yu|br^3@Vu~DT?=SzwQH(xі▌P'g}?nk3P&< ) 굁hcR葋B1x&ҁo$~…}*Ot@5 bt)f#DI,h'A.K]M3D hSIKmNSLݡ,sʇCx|;nd[5;) ix0̵̂4?FA+M{"_qwm/==:*4Rƈ<ìT=aڍ$w=m+qOR$D dČ~4zzayUDZ l#N9{oQ02Č叼U`uf)zb}>G4R~PfrE2#hR; r5^ ] N]54I"\PGΩoT'S0Kv$s(dKE[:L}o\8:dG^,hwSO|4'gۯ¸K%41eS`* 髸Hgħ7"sW;H|P猜M\ ~P՚LHnCS:(w5KS*ʹɬ,}|r>ra\,z+{c%)A@Ȯ0Tq;`m,GωwSr/U4F/a&>iL&-C>XnԇB\YʰqK lWe\J%ڲЗ@mʝ ]\1B-r@Hi2jҶZ۠1Q>Q僧%Z}}. J ̀Wl);y)5 ߎfa=lS%.[8&c V/\=˅ር7:|Os#^IҥEyPuԄ-u}c>%"QsƘ[yo%g@Řƍ*c?0ƛꤙ5Fa6zvXjeA3pu?Gȃ6#c{pSa&qL[4xU'|?d%"*?tl(cݑ}SA/Jh#J7u"&vnQ(2ix֭J,D?,Re9|7R=4mru"&ŗQ%%(v]43&㚋ǘ%˾%niK3^M{դ퉥o~߸c6P~Yaaw:>Wcu"|zN' I%HM~= ؝gԅ]KQPodTRΫY \/.!;ө3DZvSgFu:My^/y,iY.T+)"^c(A}Xv[+U.o3=y/ D{3:E¨9WCɍ9z3V$F"Gx2X\J:Kf<7J$i;l1?'^PU0Sf::aD3UFzR t J\D(1 0F_OU>>d76i#n:e/Tޓ6aKj*~?q_O?}Tqgz/Y3%dtfsY>!?4g4B\~^ HV0㘯wG^8,5OŒLķ12{1¿ll+cr(䡼RM)>P+Bԓ5߮嬁Xg9++lqr>^$8XNd!hK 2縠m?_N¥RH.9 X,ՌD?eo&wXH,C*U*(O*iwZJ&#q_0 Z oqd|oq+0*ZiqVafD:qW@';~V;U -JA^dݳl"djBٗ2Ba#,!{L`%F Cgc陹' 5kc#fn9 6(EvN~!| sU7/>}V@ mI%y*qVA(Y{]:?XUaFm# +޸3. gN}hȬa)8=)dQ?Kzțs3ny!tByOЦ3!6N'8 dCV<#B7dOl+"ӫy Z!0{VHalه(8!q9򳗵fE=P_RƔ!*E",z-=Rv.LZ/i+#7":a)m/U,#i jv[d_@} Nb 05;8Y|ܒϒD% 8T/r~fgt&ؚ$?U!A^|`Q AA_ jWɎj*娳ʤ+~!-,OwQp2q^=^|l䑁K%z'[BjXbR^~!'ӐhU0gAM1At4A )$KE ^Ĥrzygsrb]m5YZmυF?~~ 6/怕4.(g)606EIqw=XVV|dma `ԃQAH9 NA]\oܹaõHDBT`ir.Ѷ>֗-[dF搵iF,SבKT Z50C8aܲ;T<*fFoPgG?f%u;QhqP-zdU#j4eFl%TsHTNJEmCEcà.7Tl qL*h/cU[qӡ؅F}}'(LpME3ZS8xʴG>F?^}ڒCùa"r9")|ܣE"'%ѓe }`[ʰna4@; EPMoZ8T59tr%8P[2/l.˽[@ܛL!V\o~qB?F6oTк_ȡҗcEWl".='%TY<[/d-c}^G:_ȓc-JCM.e~%,#w;Nn^R[͜oWDngԾ  ? 2.:vPގUa y==ۉĥ9}SˎjO`nkįfhĜčjFәchaZ D#3Zܛ%9T}Sɨ-%j3vPSiFհDU&w6"r8u:quí 2F=St41+se%6ڬi6)Yln#DAq]떒<.&[2\zg3;Y[k֓u9?mSg\ScSt˺>dh_=tVjtP~&moOw(CYj]&98~C9] &~b;`bpYl3ކ&\&B =Hw*u3pI"BХ#Uӧ4A; OUx)\ rmKWm%8n!Z}y:5/p(}J=5nN tCs"- 5=JүԂ&ؠTzȅgğMV&/kM:ݧEVx(3:4?pCyÌ](?"}e^$ٮ[\~[" $U]a,f7燏k/+3pWr Љ+ԛp9C4P#PHҏWp,Bp)ޚ=.sUgt UpϊU^dYN<jFY>0g0t^xɺ9ƽdl?w$֌%yJRΰi ^?+ *T1O57Jx @{.§y*<yعL6r!;>: gLp0b_[Q%HI>\>eP?F;$r3:t\+Z Wںkh'Zre .׹{?I(4@bL]&V h=']&OK#{ɩeY\ThQN(KQ{JF%*K զv:zZnh6|jVCF Wg=cmFO=N~1*_O5Y+sMmb{4f΀Wz /yfL\lӮɑ&#tYw(ױ ~r,dC"n!<Fo^yr^ lI'iC J' ~(z@RhADa &\gWZirF:BK/Û}AK҈ulR)‰ZX6 oJܫUNN~ u9Q>v )7ڡ_n Nl>S`ͽ֣MT[%vIs0m1k{4-fkJBaʊ 2/ٝ(h?s3(@0SY]<K=G 3> F`n; A ~9II>l5+7 gT uω1ņ!*|R \fz۳_E[ ȟY(1h %,sZ,k[7{¨^,ZEx1N9ZG'G߉WW.Cg3iy'Wj,I1;gδkhMYU*U2x_]~t fK3 B^ ^R`<1Vxy(&aew{f2MktB+dkَ'nu%DbF,_Q&7[ Q"JѸv1Ykڵ $kGNql6T^llqLꘄB֢>ٙup!ԨCٯAgw!Vubf-t PG 2JW#5q1cKҞGc\X܏VkɈ|i<,.}J'ph[AHB:o+ȭ!06g*y_L߻avYVt~I̦"#$XnYd4eZR !Nu426qw:fA97yJvMBJ>~^czZ!ɘ;:Ƿ/4)D 8ʈA\QQ!,PSc aȴCx_"9|34{ɫ!cRFf\j)(tgBL6OAwdRCWB 4~p'Ė>-ͩ+Sꓖ,'U2<ш |%e)(V%얄 -eJf>p,Vݑ=0sg@B !0O ;L.bqwD:XeMcLrnDG?r,;W|q@W>ܥ&sغgt<ą"kVJv# ? ߱eju0Jbl^2uIOs"g<͚4c|M@'7^d.y {G.޼R¯D1ʁ\ZBgs~R\kڻy=<3#-= J UI)IDu P1y!rY$_1*ߪA;l L uQ)#_XD@r'sq⥣>Mֹ[/u}6 X{+Zm#Q_֓Ed9Pvۯz zga*Nll go >tWQgIyU/9wd܌F3HT/>fQ pgiu?0f=2v0[/2J*>EWsHL[r5D᝜:{K &%J$xpH4JY=rFGg4 %}5?ZBˏ*d~>ŝ❟{d-5SfP̣P6J> !i&I*zv4?6QOZ::#h?l<"yj2 ~F!;S#OJ #ܼIv9j@,Gڔ(cUyO0mN<>QWSޝvǜ X2y*`Pj~&\xKOֻ>4Ѵ cgga_ZpjX0$A+/YD=簮q(M H-Y8L٩LKlǒ%˄gyL$L3 6 ЈGa{͜0\9bm_F10WHCa]^DĪZF ^hu/8vpeiwHi]Sx{pW@+.jfi'kvw}ꦍ^ >QmVIqIw ,\\aܠ‘*Wp~(yS_F'ah_n(~ϡWX55{p-U/\)=2Ӻg}ӫrZe齔,s Mep//r$htOk0fm{(8GP}e#U-Za/HzXa\Km"%7!9潭z*#'1t?S1sHjE/-Yw(iP}@TpRr|XGjgöR/EG+(UƀDx Xy+P%t{MQvGrSc͒6.ebnKʽ!!׽) N۸0GrD4)O #< b>[ zڡL|XO(FjϠ'b[ +n=To LA8jc֝4l04G_U;i+kx/ǝ/]F+E]-uW5}ȹ"{\pv%B9\;|.N<'IWѴs،# "iH{+W2)Zm,j6 ' I5ϔBY)*5gwޞ^MMu 82y{+[rYXCgEU#}ش3&IpRXMku9:6$H8P_<i!nd!Bn ru_̒iE"l_sr2Z-zM|M#SJ<<.WŗN7 S6oL)2!H%o6Y3?=~@XG9^BW0,L>ު ?N{D䉘A Em7il^ m$c@*7Y('F-asU+CZ;5Gɘ+g.=jk2ʧ*KAޡ\1YѭBLhAzDtwص]8tB+;`r\+$.\?G.OP hv 1de2CyȀҎ>{[LJS5 +];2K6Ճc37H[P]NW|EO.-gYT7됬ļ6'u^OgvG0Cff0O]y\Tլf۫i ҷ" YM,!;rw&ĎCkk, ]GqǢT|g M;vߞ ؅4=mSW耪&0#"jM.`޺8@^`]]L%NUԅ_7جNGt)gLCXE :;0yck d6~JіoN|!+"{kAryB-its =9k/&bZڃ{):ZVbpd?08Bvs٠k; O`:iV:=/^6Lvo!5*MpR>hgA vZ,T> 'n,t~*WR雂;ĵ+wjץ)nqynudZ.pqu +WJ)z͎"^4L4-ŐR Ticlj8ZYMj/)%pӔT_}5D ^ӿ~fO?t fPe*o+ Z~gYPa__-d \)R(N*QbtpRP< Gu84Gq[۹`o)YŸ<,Iъ2~4Kc]M# L 8h">P{!C SlbNvm!j2EԮvAJZ03k! mգYՅ|ۘVau-ѡ}모цR* 'pHH; oV&?j G˗QOiGo\P){o.U>ˣrXcXgR uSnIL ܬb躄OǺQ_6&k"< :wi~Sĕğ`> stream xڍwT6R HK7 tw03 ] !-4()%!ݍ}[us]ZD%m(aH.^n @ ~nItma҇!p d `Ma @$7&ȁ=67 A8Lpo7=ߏ5+**;vA0@ 8V;:pk(H'7 wd؀R AC$w񃝡NuGފ@ ~+C )W buwo|+iӿ E(@ 6P_|ˮKiNPDz\ nex@ܒ rYm~ɌOPq@\|yohMcGކp7_w*h2#ۭ~_mͿϿ xAq&ա-gUT\˟0[z"_s}U?q)'Hќ, b92 KVA,qvAhlvS&hQ[$L\ wV\"VE7g脀. +ݺmDǸhdJGfꮫ5w*Cqd۷ޞ|Jp" be(H2(2'c](1G[iuiexE}gmF_CE)"W`|d}hF/jN~0(.5IҪSPbE,f촗oC!vv5!}Yw_,a!o.oqهW؁G[U,JLقdOhBS+B>1| 3^iAK c݇'EB/=${&Q%:(wDq"F4g]L21~by*WH 4:t8|-0B ja)-9'Vuj:0 @{<=- mE ݖJ6rJeCޖ7FcsC;۫MAU-gi@1 ELCӳВe # '%EIP?I{pC2bo7j9>B ]MbeFtsWc ?mO9uJКoD^):4$Fչݣ 9x)&UTǾi1 טmJrHƑH)z!%_B 2~Xrz]Z^|.̣8*oX!YI:4DF:ɢ85鵣v]E+ %r$s۱s(e3C$vol6 Gkч AI9*4Gv;?+$GvoK-$Y-^ayr+!@Yg)ǡ%,gAt\ZM~™ԴzgvQI0l72ʎ_9 LQ`gYS7޴Fwt~n0#7W&DX%/KRTH#P71v,3V\hj$\ۺd`8 XdM:$w*@^EWk'銳#], jL|1܋3iwcݹ7^݈n/Hn>}0Xy'A `?->P*t.WtPD:xX-dL.Z{|J Dr^x@ݻ@Pg ]h9sēSIa/ Id?A9[IP >=~fMk0#(3uVHw BGfo`3ZHڼ)͝۝R*c9kG{?LFOokw-qaKP_з fVd=џoK#3df½̭ eԜC ۂ.pjRUpY˻LXkP~+h;+ӱð<wE&\ǫ8{X͍pNX]ꛃW .s Ke6@FqO 5YH aQCs;N)v x8aN˕SdCЭuop,a2jL@GR+=_v7e2t=3h18P .Q̛dݲ:#cAN([ߦVV=>EN]ZyZL.dk*ƭٗ d:ep9xBr;֋p3V? O&-& |ga0$_/cY##Loz#< a~ɠ?IUD|GֱrwE "Y[7@f|,Lz2͜ߪP dΞ^hBOhggs$t8@6\AubTWj<,Ue_޴ͻ#p_ɂjͥ־3N*C&F:9Տދ:D-XW`/q.R.+DWzJR̾i}.zv:~P/F !-rMN *,P~ ߞ jV_ Yçb4%7h|}Z^O/=+ʊ٫O9XӕnegM^Э2KYTruÛ`T;e U"o6o)cSh4&l&"7%"a wã:mL*yloIkew͚XU@fù))o,].` gmc;uM) _0v! KҜ%G Z\ݯ7GJL|pu+!y]>KR,IyCUrUMӐm3[˲cV-CRJ V>Ԋ Dy>mtU >CH:\wX}s-#5{(^c+)RE;}two$P$$Zڶ膔E0Zq? 2⦓L8uRI1mg21oL)˴R|îrC+`2?,KDIlK-9.hq,ܩ}fjs˨{sS<*{۟:#AZ؏DrZ+nt$% 0Pe+4M+?qbdJѦhi#IXԹ> &CP8vI!Cu3\CVݷ.У&%B]ϓ'>‚^ &sFt':z\͵srKO̺o(J|m=I!Jt.e6 n"V'Gq*OR{8O`̚AYrVD0EW1lL'KVT,IJDlεQNx3etr 8z ;I9kyW++mC\+iy63b6 = ]졯{xlPǽ l+Kz|,G^c ԟ2.j8$hF$\8! d)/de[ o r! mp Ű\2PfŸ4,*8F|Y_WmdL|;+fVll]Wcb$*F/jdZ%̄j,*eHFoTl֙.6ƃ<@;zB~tPV A>/zMY@i.[>wW/ҳ+QȾ: 3𨟿$r bj`Dz0Tq_~0=T$r ޳7 }?@Li eb % :{&22JG{j:&_Q:>/` 5uP]̰q>`}ì֊*Hm#PjV;?M2/&~N6fXHJctFCMʻ,n(ZRD^H3_hI(NY3sa^=nq0FphOLZIL&5Rpv]3S+7a/~Mg%S?Q]);"J^(SJȺT0V HH}<ϗ4Mg@Z/:.{,n5ܘU ?4\0Pb{2# G::6 >[dbAN;zv#&]zU>ص> '^ HDJ~F`7 Ҫ!gC?ʏ׺B7ǭFLZ Go`2*NZ[*&O4J_3֢pؖp]cF+ ajƼcuXameđMAl]5v]2I?T6WTa!+kY7lH "|~1-fv֫̀.b9(&#> stream xڍtTS[׭("]JRz &!$$ AD( (# H RIxod֚=ag5CTPH,/$T20A A>Hn:؍a ){S`Z($PE$ PH Ov@->: s+߯@N(,..;( $P u9]uB((W N),-qrCaexnP< Ԇ8`: \ X7r8"0U+^uiu0_`Ϳ{( @@3u r_F5`>8yb10v(h G TrWA-@WA~yb ** (wW@^>. AO51=?.ki rsK0zw俪?y::s?'q]W"B]IP_Ղ!\;\AiD av,/74GrAy Ů}|p"J=n~L@X` ^+=χDaRW( ם * u`zm2 &FQPJu]9Pʬ-H1堉`YƮ'Nw<]>w˦wkmK ]'M0F;}h\NŽѳ@fՌz5sM0됔9.6\>~z3̒4cjf~=qPF{d{f]{[^FKH;I=Q+]q(*uYx|/y:͠& IKKMq{ޒTk)]Ķ<ᴰ# m17o},Wu16 c'T{p%!bkˇ؜ym]fƈ֎.C]h,C@BczAE!U!(z g2žeCk8Mhr-k.\IvxG|=O'A3d Fy"ݫy *r\ލPwG/mbIːS!%fF6׶<s`e'(9c)Gk8tҲR~6$.Ӗ6'"-p#ƶ]6j}oE96I`Σ7HZB83%+Gr kΗ_Uc_3lyEaOВ @vy ck/tD~1<(y}X%#Vv?szҬT6^SwY&sxᕓI4)! R{̚ܣCkk.-xboD TH'hw ~A}Z M>`L25QYq1(Mq7mRoxrxs;=C3X5+p*kffgGGLw9.٨{~lW+X+t̄@$4'B =4DNsX pkk;Ӓ]I;ܫtY6aLiy8/~~~Kr{ZD]Xx*Z#!3fHrMb!_]vL׀KW-5-DNUfF^@i"UFJz0#V'AfK&||x#=/~R S?^.fJW~|؁I̽sq"{vԍ4tX's8aC86&rK*]H`&>Aoy3^eA$!2hK}y== -.5`&!yc8R>u'y__,[$$RD;_sCfe2nXzm6A'Azx˖%%I$O?jz4oí? izX6ỹcy/x?u `WH`IcmyN [i#Z{jLX"sJ@ i~YhIƥ1ՒOE7< Le!V@]ɾ蘺_KC%ߋ-sҢ<"dV5̂Ɯ\ >b<=3K*| Clsm?/N a1E85S5y5!MP:XѳzkЌsE:Y\Gy؛bݖzZ\7զ{xu ᣇe79^w3]HRnq6ݎ>b[O૎*nPps7T3I|(iil&qO5:[2,i`(UX{G&E)?KGi$ 1{ fj7k=yWLbtxLnކT/>WrJ}o[I}zXGy`U6-(3"[=yYr/@>膳y]oීȹK"yQÒqݽ}[aU7o#duTT~ҧ,'GEnPm;WtpH>|csmе~x OK#*ód[sKٞjm{POwPϭIkJo?I+.MYy6#H^!]CՐuBd\wp|4q姇Uԡ΀rӽS7ܩ`c29[0&`TF@>@nXip\TydgBuu_2$G=3ᲀ z>ҨX(02mڑz<`2hRb+Qgu3B; GR*&M"~HcU7B}N'DGeGE9܁+{P*h:^ Jzv/Qfa5_l|)t_9}(W:Rſy&zkťyS3e֌WhB)H{ުeS9vMY҉Z[ÉJ0iu]tTe=UUD#/j>Y%xG-lZz*89Pܻ'eҼ )tr` (aI*}VeĖ6 vOA{C̷,!H⍲]SV5-Y謔򷋏2yюK:=rBΟy:[.டD3CxF+sH<uDLEzڎ_gyҟ(oRxQN 96vpF~$^,{^8vcY"d=uaգ'yW},ɢwjB3bz\qm}W[w&7\D(N^*Ry3t}ͿX~n]@Mӗ M$Yp-c+$%'qNw*vLgb1Fb0KmiSzj%A.yO傇vl8%SZdc%pbyMkyW~d"LhzO!al|J}u6VD\L>Jʆ'DVqB #"i7jn~hl 'tQÅxTvpX79COm8N;RDm"B"O5і1OD^ЧI;sM>Q }OVSn1ox(O{˪_VRz@X<CDz(E2i%+2; bߊE=I ikV"H|y+"R+pY:MhvJI67b[LʃkTazo5QQ N eأ߾)dI. 03Q xǗDE>5R]'mNHt]: 1S[܂T-ʍV^B7QL㻖m3 ,ߦOz~H,i>WK]9{3>x,;hJafC5;Ɛ#'s8^v*p8Rۃ_ld?dBG A 8lqf&Pmo?Wu9; 9zO؜,W$Vj.z9T. Ul *ȅ\hGcO u/چwſ>!EBJ\J嘳a@>[Z_]|^ySsKqW|<9Pw>] gœ[MFGDj}/} (#4yi#F[ri\AU~oʃkpeyj'#[%<ݯ!fg> bsVuKfx9v_W`Y;޴ `+|n;|{m癮hݗ<Ϙsk? 7.vGrbyWJ79keۦ"ntvuYko!Fs(e-_S!zv%{t疍dU;n-Z(+{*K q,oxb0zG)MBYӠΓ0Cɍ~iTѢm:M+ȡgDs- ߃bRN{|!\Lqeo{ }N6439SW-8i?\B)or͢9cオy璃Vm%)|e\IN;ܶ㍇cFotZ[4PAݵb򽎋\KG!an cw*2L힢nJUHh~ 3>Z endstream endobj 111 0 obj << /Length1 1790 /Length2 12805 /Length3 0 /Length 13933 /Filter /FlateDecode >> stream xڍP ={\kBBB)ZXqww/⮗-}7sdyz=6X)VQprpprr@gYH-/2K苡3@z- @ b P(8=]\}!vЗNNNn H S@WWK@ {_BXC@PO1/~we|d2a.Ύy@Ey-m%ֿ[RJ`pqq^<o KuW W/\^& `gM88A/?.(+ttS zB_@e>U[CĄAؤ(`bWC'U= ѧzG{`+#iU"d.e뼿W$\]ZwTV% %'B\@Yˆ? CreE"ZXrfi|$9FC/s'U6 襁9nf ߒՌwG+iwTx]%\@jhNߣQ}[L?YC9+_[42n3(fl+eNO혪h ի-Ly_orfi^-})IX*հhf/f%EEiD7EGӢs90iG%ki>8 dT]~ K!DiHfhUʿ+B q(S[ l7Z'|E![{68њ>4 ւʢ9-"evY#܎N1WuE00F֕nԟ4tL|߱8,K |&U=^ѣ_|◘#'I(7M~>m +5Ͳ=}=r5U>~>S>"5">/۽WœzyEb',yF,l4mw-jih `eXNJZ3^maeq}i35%/S_!٤ls)iy0|Bq!8 0oQqXM {~~v'jE$4:X>፤A 8'h_R {bYhrɤ-)dM0C:I3@Ek^BT߮faT@q!ofxlwόrrsBʟ.Xg:.0Y5B)5lT&$Gm*ꮓ "NքnׯH2L ۢbSNQ!~9j|P_c`Mqi~`~ϡg֢ZX/GNr:&HsCd0,[xܡ`;jdw뚍rXn'8[}0rKLB<;b@>be.ٕ9v~%C>1p6O=uj iLvu{j{I7?$KD\xM7"ʭX4% Gy <oT-dsO(Y ӹ~jƅtY "Р9`ϻ#cwQ&YVdr?ޠJNv<&ae.Ծn}K~N]m[h#VP5~d@fyd4/f# z.|ʚ}Wω@Ӆ;WږC%t$Yf&~YˌkD̘2ձl[{k267k1Śh[B:P{qc=(S?:jےoOkDϯMua(뻒>bO ڏ-]|xơxl_k(t-:-8D (j{TA#7ۣf8p9Ǫ,VĐII^kՔ!ec"N`(zǤ͜dF\ KNM+{Ǻ 3H7(z) Q f^w4j(i_QJ|Mv8Wգ%G/k?=jGHL9N8`7;T&VػxQe`L:ā5 C"HorVѧ+^;lW f@F('9U<2|l-lERm& H`]twF>a'd/2!FU 6 &1ҽ󲷣e`nr E,]P*m5Ln9QԴUHjspx+B9EMt%:E$̉kWO6…UAT?Aڔ/TzCzTF s6@_UU'0|z 0hnų NNEm)]{dQ|lV4RDb[߬{3Y:>ΓϛW_E||wt"s|=jq7 Yc`Or[ Ѵ `̂Z*[Τ09 s7 =%5Bp dC7*\~8djEQ V<(@nkNתDY&R"Iv) !T,m9_ŵ&) $Q$4y=Vviޅu8hq"S?WXq Ӗqi>:s?n`w1r&FXJJչLj66(hΖNl'TFꭟv,`%e:Qox7S$G 7H%lscB}>juDaܴwh(qPo@>ڭтM,6羦6 fjX UZfFc⑐NtwOV *U@d;q:NCKpVk8)54S(Y\B*I}L˷\nXL2KU$oͦ`qŰfAKj2'? TN듉MTOJR6R#${-j5}m.BIA3tVldge<|)&2 x~ OؕY&lqL$hdFj%j^ jӕ>:Gg½œl6[!f:ؾ7LYo&aRG5R"9-ww"qM({adE.) B<v1qx؁o^C[zdk7  a`EvO9 bVݙEX)uoM_=to}?n4;N{t*Igȴp*{ dlY}r4-u2W}p_ gi{BLxyњAwqPyV:tXXwsaRķzt" 6#p[r| ]FrɬA ޣOJw×ӏ b\lK]6y?~X ~QK a`S^ ڳ}9br~/SRV`r!4[ghgcL{1FҼ'> $yj lbWX)OOu(smX̰?~fI&2GcݳƇ-wUSu#,Rc+g{\HN #=<K"oR#<̷(i=}#-+>BJr,9 ^ÝIDB{.es$McKhj2d[TI/bb!4D%QQX%;!)ԴnDeʴ2cJAR֠౻pA#H y]mtLX3{,*#o[)d-ζ kE}VV T,Eb6[u63VI FK-Z-y0ws4d@-3Z_ *'e Q1ĩ}M$Փ]R*!B,-V++R}+ -F:V!w;Up(B,ڑG[ T~{ , i 59W]HVxC$:S.KEDVn1ցxmXghE,hok/ FS?HGĽB,vS) 6Q6t"\,>\JfbC* <IPi9hfhLFCB0- ivc2+ꭨF3>:c{{岽*}Ȃg˵ Y; M+VyoV~c,8EˣiƤBńRC"V.$ӗ/&B`Ǥc7ZGs0&LLJn Kׇ?-/n C3I;y`; jdPY+LL\WVlYD!WtN_.Rd@[w,ĈXRt"&eBࢡHfl'oSz|U2#jh0]ml^'t$bG~Ô{"f5lʶA. 6L"e)x:a.]]MFeյH\];D*MghFܦ& hkd2RRR iX9B?KY+*o%2dö(IAxATjUē VOř42&LH>C(P!)޶ZX%@t*PMfRɑY- T*VJTx"Zx|F޹k|"6:T77g}Yݴ,NHc$<Rga^C9# P.0"*zL/k:# u'W:gsTe?fV}^]zӄSlsSu3!SBve;UmLUiq:8\|JOz]=58EyE_\ʸrʠ hn9A6y<9ܺK&:t@jƙ _95 ŃQK γ-\99şz\lsl+b^H *OH纯^2FKJH]#`JtZP-` ?7\NKs إ ZW EiΖQ`> hI7@W|3.;-,Kȕ%t38F~ʰu;-Ћ7_hbZ~Tyq/Zӻbu(1gsLeWMsg,HoivGc!"$~̎WgT="#rH?w([Q.Y:7h1Ndb n9DZ-zmmCC&JSyˣd%A`̪ʹ*>;Jd# 7d@Jbזw }Aw%V3(@ݔ9xbq.َ߬ȟ'ܺKzY!!CmzWZb%=bS e=66Q6RN7,w0]bqiK-'gi29L}tEk4Or ^ieA?ˆI;׋ywݜwt56{# \~˂Jyr i_yvG {U_6ք♪F2yGd&:xhMdGe~ao23u㞸TE7sQC#g?kk SZ vXhz*I9!jI*4L,$2u/V{2ۄp〫"C+዆GRlX>ʘ\%,riϊuYnhac9#r:M?bOoYHy%D%]`{ϮJS@OCn溔׃A{vZ9L]|{*!*œcByWW&UѳKt=5o,p[om bwXE#[Eb ~}p'e k"NfGf!1=J:w 8(?clu Qg.:o$OΚEFwo+4iKS d=7 :=aC1.\FY}#BjRa^tpjv37sA<׿vOHζ`[żӥhѐ9m.{87Y7j[dun)9ZԆpxh7j?VqK=ܯ/g7J<ǦwFP²$#=9 #%7-Ȉ KS6 y;cNI Vc iB&N4t-aV;j]ެb'ՈwԽYYn߱~^U5/凶1xDZCSJ$@? ->3\L:6)C .YML ~-bdFtߛV9Wd 4T#ƜƹBf0D T׎pA$A7htE۫Ըb3+)6/6v>ˆ^.oIoK=8U*Ðzr--=v\mS> ']ДG&r)ѮMcR.n ?؂1IfV~̫.|E@WUr-K=K̫[؆)l%RU H8.{GCZ+kJe2"EqST h@{FR"E?nwvDdje\jn (nOw(*ʁpgAK=2}9{M=ƍJIWa{^_N r%~x;;Pid g؈DTFDI>^RF_u0 `΂ϭ\y8Z>)e56za⫧$CI5e::Fv-U`Jº޵/ XpmJ_HT2:Yr F]émJx3`CQ6!4 KRӣ62ޕ6[PJ t{}s_G$y|8S %/y!%IIڶ.ŧ+d37{h|~CLO$!;x\/fCUV/`^0jML6lF:F4["%K]-č͙fjGaLF*@|h C8̞ՙ˴I'@B9'H{^~@t1Zp~I^x2wspWg/$Vdc@-Ffje&厷{* Vf+.? k `uEp u} u tA"8Tr2_ j;L89+)-΍?C`6v<[@ݪ_e v~'wqΙީ)y"4rtVCK,L>ZƏ߶VtΘ6s⊾ǃ1"B׮{NVk$N6vp1%aWcE(<NXA;B5횘;Xao-fUUIz ] >~z<ȲnZ H =C77@)WJw$vwFTF7AqY1,Elۼ_\XzS#d1U6$<ɘg1 Yh(43XI9n'!7-% ï4x`"3mLqi]=ߵ@~R$/ 3ja|ȍ+gT,xNzߨoXѠ6sa!z~/$40(<9Hg :(jaA_c&_;\',u=9r:htGl_aY8.|%X}GO̕R*\Ift=w:F΋m"|y*&X3I72r&Ph|菌p&oыexDHd?dDбС֌R,sKgk.o~& ZԦ#&% 0 endstream endobj 113 0 obj << /Length1 2519 /Length2 17780 /Length3 0 /Length 19253 /Filter /FlateDecode >> stream xڌP n@qww-^$@pw/VݽKqbŭCq 'kW9g2]MUԙL@Ll̬ E 6V++3++;-t$*-= +& t *:ll6n~6~VV;++@w+3"3@D%lea ߯ZS:1;)tف=mV W1A+h savpcxXZ@. gw௔J@;?1#Q4,\Pw0w:`)foreʎ +GOqllG/CV+MM^Vs+[@YZӕ7Khl&`CT@pblbeW,YLdW|V SpݽXi_i9h[9d%~,@.VVV^v 4dˁ#o&_dp~>sp ?+s:|d/BbcYL@VH `p<cxm~b))e-R). a0sp8x|'?4e| \t[gb5U_V_F$fk7??|?usx6?2r\YW x-l-'LY=8XuXY\6<@_Rf-;7 BbO; f Ͽl V;8#Rn._ no`x,xE<߈"m*F`ئҿlE7bFA7iF`ڿ8jqc9g_0_vltfcg |sKG`/[7u7Nο(vvk*X~N  Qמ<@?t50r_l?E,~̷)w*Xz9ZӬPձ\ۿV7\?2y,]qmكW>J+;o6ؘ#nrCߦT?DY9:py\Af&S!BsG!KGaF\ƿ],0 wxࣘGz8{p>~6p1upl&{/`@WAUAq?3Ȯ_<#d`*by_'F;)4KNBW|+2ҏ#E{#L縭 >=I(Amf4ޗcơ7$L{|m {xT =e<*VCvUj呟+1hF,*0ə'sez@u>ws;7J&wGo=a{JݥP AOYIb.+3X),>8_G#K b#}1"Lrkɠp]3{̍iÔ6"6j0'?E8{Y>S'{]_*АS213?P$csG0@|G?B,tyZ0+Ae7ۧks6!k6~!D5VnIG͂5ѯɘwdk{1G_(UN}_C}.Ξ΍Ԣ[%YgǕxqΒHusy>jW ')仌y 7TݮN}o#EM"?3"[M^@Q }dI P1+?"(.WsKq9>C%ds=ƜYZiPUV6ug<}TVixØt3c,ND҇wmlɮRSAZ EQg  DRrRrKB ɟ,<{ 8YJZ9zD+xfH"Z73.Ir{StA1W#RZm=F0! B&qДy<]qF}jRYnK˜3ƤM)ճ4pvoigQi06U|"9dDm0]|cvL%λz Vy/)h:NWWT䫇a#gă|; ee0pT[2Dd/I/IƯ04ƛp(q"@?>bvM$^ c..hH7h`*un+#5{fXNa5OH|Bh %N& {< 1aoK=qzq/?Gf2-5۶13YsbL}w PN;BTRwr mZ pΌԟ~+k}x?֌v qBz#F4XI F ɭϤAI3 aLtTRE sh ]ڋN)uZcd2vAnKK:^q\q ymj9~;kx+FP+w%7%nS6/nzd]S#`\a}@MJMTX+sROm,:^TQY |6<5Ȟ烔vYhdaE^PlozL䳑onab๾%jKT{g& >F7,%OP?" (pxNj#F !Zy6~Y3v^v'AE=9Ê#[n3DDeS?R7 AKyјff`6'^ `ZZF"$]3-?Rye6 s4TUSOOaU†ޞ>Y5-m7U4V%~M-R x(qZ[Q|{?WQoа+]\ $ M?wd>qO|ߚ G3$10qߝj5Uds0 *r#ոzNz [Ղgߊ==\yO$uTγ1wqxVdeϨګ>n81YsO60^Lf]dXm&͟fMmTLB|Gb-/&ޑ&AnReDTv’ Q|H-טYC.3 cUIF=軁.COńbv^vu@=i4ݢP.^/QY5'HŗwQD`Y _O_.uQ$Jp@,NŤyQ}Z.Fl.CԫKN̹i;ZAwIua-7==coJwz;W4?dʮBԹ".@g}=0pp~x)(sܬ9 #dv:4ź2ozձ4E]3z}[Sq&#a8P]nFC$zY6>^lt3]tI#Sر-2d]qA4{9@ ̛irnw| vΰ< X2TaWr/i+-d k=U 6uu?J%Qܷ&S∘-gna%p8xΦfN\M!'[ XB )bIfe2C.Ts,İ U""Sf"_o-][m$FJs_qKM{0E.p<6ھJUsPjr@%@Ѽ7<M*FA$w kĕ`K(xCh"10/蓂Μ2  1?eTSOSBi;$%E,$ c븢QI6i*uj+ϖ<29hW-* ^[;|K`ś+E\)dTAp3 HfK"9ZL{+pi)ajdguqY9+%AsZ-o E'ČλG w P%gqqP]zHM-~kkd⮄ˆoΙ.Y5{PB߼FQ əJ(11e_e fcQgA|[lJ! PV*mo7aTힹo*bdhå0谆,1y~(?ƩLp< ()^p%cGRCvv+G1DZA_ 3μ jv+#TDT$2mIqپx&e!6/ WŻY&=%i@,=Vby7W}1 jNoD0/*i d¯X-hX Gm5X$sז(z+S3HG#ER@VJx L7ڡO~\SlZ9 3ُ(M~ DyZ[G-oj]QdΎ!!/1N!oQLOg. 8K08Oa-'Ε<-MB&GelG̟F<r?[m^&<q:<]7 NHm9c4pb@`JпmNhm:Jxb6=/YʹGǬ8Ʌv]zɔ;&? /xKL}Y5q>lmbzC?kheӱwp: v6L0%)5x(B2b5XSBh7z)Ng?P3· Ƙ)dt:\׳Z 38J},-?HIy(3cT/k^s,zV:{%'Cu,*9N\ Jg,_a{ȱ }>ֲ@kU _LsYh@hE-:%(km@45-zҦ;lPjh$@ؿc{~T2ZI+an?cN<9vfir7_~H 5="+- D)NVѥH!`wM_NGo*/f#7OgJ}1R=GJGR̵(*qD>,b;5wkZfz m8ĜxٝTe_*uW3R0/ѩrcso ,LNYۃR@FMa#TdVhtq'.@NNBo~X^{B9SG,jb1ފ78.ɨ޼:W֍5rh3يF6 ?4aOoEAq ecy1r}o."Kl%\ O,p0@Ru":{'߸eL~{$ȐuT6/q8O%8]o[e=]HfTo0n'輦bB[&SZ`CC5#3NUmCɯ 2TVvy3wcKSgELye):٠+' gU([z_v泻;j~H{_<~ꏍ .DeD6E901Xoky/ݔᭋ;^'`4ݶXpJƼ|o,WI->Y~OX 'ap'i9y)yq -ph/!|I +u,pZs"vk1J>Qԙ^>Su2o7qt+[~4LPg(Q>0qv,ZSA3!2= $ƥӯt"Qg<{@ieaǥIN8sȁ~2α=19sJ_tSpAKm3T~;aSg[C8gg1~hc:e.Hym1ڒ)xdG" 8טy m;0SO<*Dp;8t9N(})lަ9.ɿqkKVn^c'.OZ1|'V'%*h~gk}83J5܉!BYrnp݃!m =bm%Y K768y}>̧w]+-hxOSsNlLMV)yQE:a.KHVMF>6^B OB+MoM QƋ9bjp!eWFE VsVcdg{5 g;NcYpMΒMF:)EU:MIc2{@sf7VAjwt1zIY3:򿤭,*J#k! ϖf PrN**~6bT7 j?,AߔkI")ܱ\LT]MGjqoHPa *D-)tH

K6,Ӌ]BUFAlTY54kxcQtޣ.^y;OSH8z[bB #(@c2hWwVGj1yaw1hGF, |hcQJr_ `lMmBb\eZWb, anTR/TQFVrgjEh"h0.-|Lʵܖ!~m"Qe.A|iO'R@8UqyJR/_W'fBiL>CI!8zw.ƥ)tNMu{Kr$:P9uceّ"s{ϨFu%\6[u$<5'P?9p$m!Qme䧽"f\#n(% Wޏ Ri1a{'%{OSU2bN;1fx(FeY8&Zԉ5#뗩62[M]W[VtΝ鳃NEQ;KVrBʍx XxQon`&}PA"A7ǂyӠ孷4њ;qК"zr8;6]m Ȫ2AFr4M`y*}ڟ8I<=85d.#@&7lۗ鑛C@kd_aC!.܌4KmJC6Op+iCIoAf}֐\;0ʁ.Oͧ ^cmDžqvӛCo2y9Lω’-<7Ol{ݠrT%. uоx 5_vEӐ {I,Vxw[eu }9d0v-$?# p{j)”5B+]ͤ:er6 \mbKY#Lۍ&u呿YO-=a ȡ#Hz6KZ7w8Zl,ݵ9t]Ƞ!% \4) sb z Y ޏvVW2j9lbد #%>% "UϴU}BO6)oEη>Ŭ2"'@]m_VZ}L&%6q}+ $HsU*߫253?Yԥs714u$2KǓn/ qU$Un~Y<(/,nz+TWEJ=$qb\ ]' ub2q"_ {^dC\I bDؐJg-0"NTtV48rŒz MK^FCb?p>e,FNk{u+<",H4E#,zoފV+՜j񵂣٣.{bDlK ːfYlķ)h>6l #YN<3G(U*X>j_FL"+6 2&on/\?ePɼ|]zXMҹpna88\Q[\S%]( X.=ŴOS "mFIcfΔ)'юv бfg;$>S~qUk邔Ei%7=X.2RV%q.X+QiOtˈ0r\CU*^ISB B>84j*&1Q# 6-|Bn`iWc5Qm.Q'neeX .'W)tD^-R꛺U/hFG6]w LHphػI!!{p+O<^ 6wrz}6;w*݌M"} {Y0CyF?K)6~;D|ǷA$l-Qdk*US B7qR}vrx>(<'F0|tZe54 8!ǶVL)Ϊ|]ztKɸcX jk˪'gaOE.2}2Q3yӎتV̔F_:b8V+ AP7kY*m- }7=?͕֊OtQ.@nܝ36_@f2II'Gj֦Qg~30UD\YV2%8=a5X1R(L/O|SqZbk/X§U& ̂ρiUlj2ZJm쬎-O}U 2ݳcB5~΍ >ʐ[fi LƬam{dkfH n%nrfmxP@qLnUްlmи"iU#jPM{ttuȣa6)mn/1P;M9E! ;}Y3:C1lOBK5 :mL Ց#A;3 ÿƠ[OA}t䶛8>&:^$|".tfL,҂`mUT-"KWS_`2 hEH̹gU:n`E ɳ ̺)jVKEgʡ9-9.C1_V^JD(L}#c q㵡&e PL/?4UJ'C~: \JDeIqRH7KKeJ6[;*壡hx͕Dg S.ޟ64!9&q7TXG$tl v_pԋ: \78&"{oҥ*>'74x%*K`QTh~ocLEWFJ#j`R9 X+Eَ9txz, uTQ7vnswk,4%&#8b|Ek:8wis+skbZ$dKj?W76եջ>eed}IH{6r.JۭXA_,ߏk'6`\itTQs|cfW+{$HQ 8?:g]PtCY2Z`'P,]$ k}/M år5Gn]OVR,il=l#4X(:$RgreKWoBc-lGWenyFxw9Ez rCg^FvBL<C7w!:]dw 䯭bܰK TFjz.h_4%,j?5N8Cg yUIośVS r/ȕCX-ਖ਼iD:.ŗ1swM`z? ynp}[ %)y̻5=}Uݚ%gJM S↪q^AdĎyM[ 8s]~aBaR1nn>@H).ӵKO_19 z#Ukaǝ2;tg8x=6+e%vN\ 臵: |~lRgGX,e”Өᛢ{OP\QE Y6ǟ!~Y,ķsV^`]quI#ZL) Q]T*F7hfm|1Ol唏8<0"l{&7.? D#Nta!^y,DfOf͝풞ы' 1h\ Q&2ۻ\ yI7Ct+f͜ԿmG#:z8Z~t;i HS}mŌȞVd5V 㭈![#AF6840q=\8S\ +RW C0=_$sW3&b!TOn3YX,nOnf]'- Yi|n<'ʪc6З##Mò2,Jn8Z(Q * lĄ s<}6^_;v,.bxJoqȜ/5P?" xN"ƞ"|쨭CDk m~Uǔ0{9"c)k^5`fYmȬDn1sۂA?@IZ`68$^-MF@t 5SRA[ .r}Giξh- TnR,؂EdI#]%twj&OE& ^4k'UsLԣX>BˤnQl뷻G aoƐP2{ m'zBNȨfy -s"#F`PFy~]c >c`hi2W5 r k*#B4К_Sȴ4E2' ֈ=UErhv}~Pο] v̩6@g8yG|\׫79鱦1f6W[HSV:&vzh#LQ+v&2eζ"w?*C:O>_Vaz??Tɥ,B]tCI=93=t#1>bxX'Kx1= 3l+zbU=2VD;]j%aDR:i?{3u˦bԡ5IBΣ؄9X8h>Pm!4^\"MHrY]? g i3{ԋMD@,7=ad΢$/uŶDk1zÅ6ISRo_:CI^E l(y@t[ f9>k`UK,y,V؍4p&.c~G7]Y6_$pF#\Y ]6Cu6XMckwY[Ï| i`KatX.+PT{;}|BY|=h]Vt, E;&g5檎~aV0h~匨J967+{kݓ>w' Pi V+ˀq>U\EOwfXBkLcN܃kAa*p2(j`n9;xs.DQ"V?> ; y9°ݴg/Hؖ0q@Ӄ_??$˪1WV{;I{s"p" Ji[e.}"V뜩8jq豍p%>1c,Qv $_:>^x7SeTklCdjL]2/Zl.#H#Z ;K@*2,q3!6lggΞyrT>_(G=}Okھ2=5|޾܏\i^i, @[54Hɠ:GjX-9" z;:2PuH0GaNOcf!)H驖(܂Mi]6,UhuyR@hHe?s%3Qj:cƜXj0>kyFPkOFzA { _[.% 5k>+/8 J`J՚ U!d>?JϨFэW\vyC,K̔YIy5x''o͠a e?h E6bFE3}[if)gaf7lBMHY^@1c%mр@S.:$_Bi7'!?${\oWâS(%!)cVqIh '颤C+{ gTMB/kD86pIB0mnI*Mߋ M7)Vm܂OJ9XJGJV9t}tIZ!@t~ 3tRI=&eVg|w܊@I\B쐘 wS$[o#J1p.yj1*j0 9<)EtE^G< 浾ݥP#` )[#xRV)ab1ja Ei w\"0tbzWKA K#vBUsQGˇ@%iњNJ< *7 [m9qeH E>g;I&Hx˘+Xvkߠp˝ar)~[$ho؛BWN0ܧyb(0Wq45 ~G'o*f/F-M 0 Z\e5RRO+ŷJWpVY)8|IL?N5OpWa5c@U) _}VvtKJON.kᆬ|+¡[X5 +yiB%lZپ endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 896 /Length 14626 /Filter /FlateDecode >> stream x|y<;sA04 % a'°0 0 aH`H$GGq0$p8$ C! ,8BCAX! x0(S A! 4Bc04CU$ ÀHHAM"0 t,@D0Fr`䁀h$C3(рDc`Ƣ Cx h<ÁhNAӉX p0; xa` hI`Pbh $`&XC#x"p Lt #1D @,DH$`Lǂk0ţ w0 ,<!{qX 80@_(:< ,@+9ddth@3pG:MLUSntHqPI6dц ك(  WqtpDBЇ6Jh04x HJuS@9N%\9SGL)krqq.$?\ƩШ~(*8UY֣^EC+Ŗ% !k_N%4sQNڸɮ3ɥqO+==n.ߵTpGӦؖ/'Ht#6$7#lwgZw,lMwр;| tl'δjtZxvе|KJJ '^dy<):(g£ފY_I^ѮwM8mQ혼-~ 绻*<PwG^[[̌IA~rHgIIqRш '!1;G=uD"bnW>؉Kz5yn&# / ܶ/+VmusgsPwEACR'u/^ih:RFdeucI?"\:J:__YNzpw^,|L3l~ekKJ"`q 24%WkfjŌ%]'Vs\+dEb"B1۪/e;:W5hQ;HYD,vշ}YQJJ$qSԲOGM o)BaCV/1rKBH p_Styut+Ƽ3bm+Dq:usn;rt"}T:Mm[ՓqQdQŪre1EC¹7>J?lU= !:I )v|1Z2yekc^y&69jn[rϦVT]Xĥgu˺ث6t2"o5OؔU y?2N|(N5Pd{j˧ŜV=2Ϟ>a|VҧO-ʭV*æS> "^os*j`/d|L7j{M[ͦ6̚Yd׺ ߗ+gx~1GkIz f9Pg E]ˡtbgXByXT8ckkk}}= k2oϳ7o7>4J٬uxq5==$ m.*O>GRxݮp]Ғ8B14\lfVkU-::AN"9tt{_iNO|63m7#%y,1,v:-{L#J+zTQHe_g͞ųn!W25NzƲiO⹍;&{]Zaѱ&,ڠ˒Bad0ݩ민]<}zM%sxœr2Fec甎l>V t#Ik:=[2\0kc72x<;=yypLA}csy䉈HݜYɾ6_"[m^llУJl>ۓ#іD)X'vbm_J%Zu퇲%RXޑa 3Dy7/ϡįKQLi׵ AiyJ|qb+fzHECSSY'DfBC0@ജPanaC7|uCqGKf_M)Ps a.JW˹CH07]z;tUҺsuz>HS|ժ/DleZW,s/mW$3%$˪c*wxZRW=v>wNK .Sݕ)̓-5Nm[B|]]y¾?^}ĝ1N+ Q% GҾnfUSΊ}gj#Nw(7^8RVY’DCk,Ni ԟ1q\`qOid螔OF8uyoE̱IΘX-:p:F7 'Ԯhx\|D܅txKON8nY["stQۦ LI{19]n8ibI8%rga8lF?=? {7\Yxɭҡ!r{e6H/껣k31 ]*Gx |E"S<1e3;ḦwchNd 4 500SLL>|~MhoEUy/H[Tn( gYO3hr:yMV^\51*мv,s?TOD PVu ؇BcwnѬHS[Iuf;j;M! [: guC2of:z`8|]BTxб镪5vRjܙFyeym)ZiHK6= <&u\pɑ'ې'ޑwB8ZHR3'h j5!EiNu,8:#z-g*OHjGt[!^ҥM-^wyAS]P7Ro30tI 'ʜ[G jt}jV8H3J2q.j|3裥n]Ӌ%'n=+b-]nZ?>XdGrN ވ.7ħ/WAUx(G)xJr]AsI"kW.tz"ƺ;7Pr2P>~|=c-e["o(2JIh+;D*[GGHK?Qprx R_̻2 X.E3$ÔG %N XĉuXL{"U^伨A]6/ 5Ry*lcj^*'GxorW!_.a'fZ͛Q͏<,_Zasr='B\Uu Y =#2\PAˏQ$ t8:AqpE܍ є͆[$nW֧xܫu ftO'j!uO/0B_^IAn;1bY G6LP$Rzfv3Cu=YuGuV>8E^&Fv<d ]IB۹Vc+#]V= M߽'g]qF{zEDd(JU\|tϕ6\>{qlef4؃ƻ :zllY'@ir8k]+Ag1 aG}.GO)'vnT0UaGzt;|ªK LK4e$S/u7>c2.A)s/[OX%74Q2qw}w[· g1'.-t^2ԥۡ 9]>-ܣ±35|L(.15G'TafU[$ #W+,m@}5"oT62m"mA2vx7g_ѥd{T~ӊϦӠ5!EmU +m[r^w]7u޵.ZwvN ^xtj:}څ%Vb'fIkq\V:]gf[_2Y-EK|QTP p:M;\+Jk(L֮ctz?q{Oyyt*_r;ifۤe2aPO(r:ۜ .}ZǮo?Fm]}::%; orV`E%ԏ_H0{cSTYZj<<~G,nS Uc癉IbQG)i]83s3]E^$~m=>ľ0yφsuZixv[@)Qm766õزM/f?,<۰qcCSE>M+54Sq5g?8<:_Y+Ǐ-^mwޱ>:{~y"3#{v6l1M/xv{MrDe`6]I\SZ;mg}h7_|$i/~^QFδ( )!iovv,_7Ƈk~i̾͞AWg-xHiiF> ;i 8ь;]t"N QdS|P<[^qe%M!d7oz R'uWϤ^^^THϟx"`\;˷Ԏ55ܠtکɛ>8phrvMĉD_m?n t#XK;շ9tW[joelS!Csw!'zEtQ ǻY0lL}\@?(Ay|mDyRU[:ͅŮ q6K86DpqssϬ\Ci우\X&Ԇ/*t %ffr="Zw$&Aʋ ߿?,<~Uk`(iEE5s ]Sׯ_7󲼴-iޙJx6['oT+Z-:pKM-+9jN%~X(#Up:V6'x :yvuyJ!<>!Th|&doaCx7~CY-I&5Qs8 ˛R #2[n8{v%">~ iq[Gɋ{/,N;5=xC#R偞%_ /j[U?pv~MY1JHSOP6 yfɘwͱR}c?켽$I`TԧӃyX9ܪHn=c|hPL T{S,Y-FOtw"k"$\OX񦔹g#3߉g/HHw,[ yROd[8trSCfEOFzxP5b(jԑWlPV{+/h| ڨvqmX+d}sنhgҬݸsΘ^wbQpʤsky?sJ(MvU O7'\q[Am[WSȸ0P九/ϱ N)#QMJjdnÉ=MM'g\Ekm4=<<OeMcj458ly^%MBFEHGjppp]Um Žl'e 3^-Θwd)G.tJU(I dd*80 l99Mz]~=VaAP :*|'¹7$tLNxYg|ɫ[DR5sP_B?0{@׳g, kfwJWTȖi:e֔uG\WxeeTI+V.]|oeӚiX8QfÁ]n{Hf:iԘE]/Oz%b/z52O"8$Bn.>val&OVUKUe߽u줳(5''4>fO\NRiت&?޾vB;m=#ke|Y'ΩarH}ǧ)\: ,-˽IƉ{$g+`/՜xͺdJJgu޼ `8~?f=+yS9t7EEZ_NIYͽO/1e2 s-yP{ܹ{])<b^n4bNd#,bVkT=S]=33SWW=G!]jRH~=+0!\uOjj4qk VR OH[jBMTk+M xlJkwO|O}l}\*uzkg6~C"lmNVaz/Ys&$O%b"bQɍvʓ: v3[:<?yz8R@'\w㜡xKD$*߀[scpT3綫efaNlcB~@iGz.h"Of[}4c4m+:jNl\R¦WIB9Ueo9uoZcIMrkJ@AH]pN6c5UAY`N_lJK։Z{[}jvS+UHm!Ұ\-S_|E/K:hr~zٴ9MןL$/ߤѪ0^^__rYYYx_c >wxtԍB-@cʵ^OBn }xXfV,9T-ܑoQ/^ /ڄ VoVT \' 9[kǮQ݂1kSR'<[uHYzHRZY$!u.OFp)oSz1@(*E"W4[XlYnnqS+ U#zDEO|7{Rύ ѫ^}<64 ē~WbL嶻xvڰ݅p 4m?Gy?.CECMC=ش o\{w⹎MӍM`g`U=_gZr E( `Py/"-rWW?L}[|z6,"کA v 7#|UYn"HQ Q]?j#뢠Ϧ4sz m#^/E2Oܯv%I/,0;"M}LE_˓'&׻F'}Q|7ٜluH)Y-VK:8(}rKF(y!^WS4ּK2HݵLRb9 k2~܌&**)65Dք{}Nָ*RB_Dֲ3]EW>Px  q[*uKcB=cUfjʠ3mNQb{y)j`2-a0a˩XY'` n<\V?>qb5LCF /ySS %NDGo IQ=w b1{64F5Yc^u2- &=ܮ]KxW$ vRfv{ @l A*ܻgjY7g=sw[=8x3i75zEjMbC8MOrL[2VNnvL0.ӐEvǚ5R,:vMKї*&#x} &}emxxcc5t=;em#ϕnk4/.I-rtpv9SWBuq%:{ڑGZ"ꬻYx?Y=[%ᐧ1gKJJYL̮)VbyߙBn{gs:YQʥq-yݲ-4~$EyX.giႩQJew(]%bWF< NN~Rs2JXVj]nBaJ;r'*qe}kEdbM0SPXA}SG7,+Wd׭9uA5I37Ԏ _1p(|S^4ҋ{,3և S]'wX=)*7\|;֤.A?ӥ'wj^4ϕWx.=/.$P+PQ4/y.?Tgo*lSȚxwZp"~:׃U)\ &F#)nRHqJdDVn0]#H|9g?W'`$Hn0=2ZƆLtgb(, ӅC7p}06ɞRm0"\LxRM}ƈ&H3$7D 0H)ќst! A `ʻQqSHA`~h@1>9~AiMgk89s(T[2!W'9 fᤠ)@a08)<RX,@-#,EeZGڕCnqQE6 !~ pOȆ¢h< 쇀nGc"0 輝!,""epF n8 `9H,()4],Z _@B!"Rc4XbK}F&s5x<$,OBh8FG Bc@Rg4,A?B3+=hH4P[/*ce<ÄQq &@1Az@hFA Jr'r)6ցVRaA)2,wJJwaqWc<P1G?^/;b^_W|,6yTIyAO4Θ`́Ή!HFg79AFm`_'_ ?ԟ`R!љG#;e8r:j0PL<4Y۾1Jd̹sCb>iN$=Bh _fi M\|1w E(XyG I5w -M%]h` 2Y ^J1e"DFׅ h" O@З#`OGMj'2dcѯ3FБ9BD02c0x+2zb(Fb$Khx5FlLXh,)͘bD;&#eCי3hErWC"o'X"Ad0| 3cP !0 ȹ߰ЌB qkLq0%a/C2"h@ՌQP̀0&&@sD2zh uh07{`_ 8d3,v ` ?¤FeFgn.sA#x!5 Ņ$!|nNpg`GW`I7G`H9n.d;:2H[ÓB'Z00qgLr ȔF ip ^P}d*{:&Ia"8S)W1]L#3#aH}/Hjd;z)i0Do43jP0_z#~ ZU…-d<T*1GAo E*9XOC_g+P4>nHBtEP?꺃+>ViV10,Tk3s Xpk*ɆXH t ЙL6 `慅ܖ|]dO mBrV5o?C_w!h!C}M.oef `C?-y=P<>#"z$o":yuQ*> endobj 120 0 obj << /Type /ObjStm /N 4 /First 30 /Length 199 /Filter /FlateDecode >> stream xmK 0{M7ն|$= %6nVx1;9]Tz ܀-djju3,&h ~$0ѹ6/c¢6\.1t>̋dϋUM6lU)+idVdJ\ktAq֒_쳱o˻ZfT } [ endstream endobj 125 0 obj << /Type /XRef /Index [0 126] /Size 126 /W [1 3 1] /Root 123 0 R /Info 124 0 R /ID [<06E9E4BE1CA45CFA28048383CB40BCCE> <06E9E4BE1CA45CFA28048383CB40BCCE>] /Length 303 /Filter /FlateDecode >> stream x%2CQ3sLAD")YHcc JyUDƋ |SE:"N  J PJ@TC BCtF8c8=؇#؅ShhAF`Wq'헝I.oܦA腰z ЧAN`! taB%lgS0 30 s0 K XQVUVIUJk*?V몡~ oMDŽՖնד B&O6M?WlSmʺԹwi)& endstream endobj startxref 156758 %%EOF registry/inst/doc/registry.R0000644000175100001440000001551013210552315015654 0ustar hornikusers### R code from vignette source 'registry.Rnw' ### Encoding: UTF-8 ################################################### ### code chunk number 1: registry.Rnw:56-58 ################################################### options(width = 80) library("registry") ################################################### ### code chunk number 2: registry.Rnw:122-125 ################################################### library(registry) R <- registry() print(R) ################################################### ### code chunk number 3: registry.Rnw:141-142 ################################################### checkAge <- function(x) stopifnot(is.na(x) || x > 0 && x < 100) ################################################### ### code chunk number 4: registry.Rnw:147-148 ################################################### checkPhone <- function(x) stopifnot(!is.na(x$mobile) || !is.na(x$home)) ################################################### ### code chunk number 5: registry.Rnw:153-155 ################################################### R <- registry(registry_class = "Addressbook", entry_class = "Address", validity_FUN = checkPhone) ################################################### ### code chunk number 6: registry.Rnw:158-164 ################################################### print.Addressbook <- function(x, ...) { writeLines(sprintf("An address book with %i entries.\n", length(x))) invisible(x) } print(R) ################################################### ### code chunk number 7: registry.Rnw:170-172 ################################################### R$set_field("last", type = "character", is_key = TRUE, index_FUN = match_partial_ignorecase) R$set_field("first", type = "character", is_key = TRUE, index_FUN = match_partial_ignorecase) ################################################### ### code chunk number 8: registry.Rnw:175-176 ################################################### R$set_field("address", type = "character") ################################################### ### code chunk number 9: registry.Rnw:181-183 ################################################### R$set_field("mobile", type = "character") R$set_field("home", type = "character") ################################################### ### code chunk number 10: registry.Rnw:187-188 ################################################### R$set_field("age", type = "integer", validity_FUN = checkAge) ################################################### ### code chunk number 11: registry.Rnw:192-195 ################################################### R$set_field("type", type = "character", alternatives = c("Business", "Private"), default = "Business") ################################################### ### code chunk number 12: registry.Rnw:198-199 ################################################### R$get_field("type") ################################################### ### code chunk number 13: registry.Rnw:206-210 ################################################### R$set_entry(last = "Smith", first = "Mary", address = "Vienna", home = "734 43 34", type = "Private", age = 44L) R$set_entry(last = "Smith", first = "Peter", address = "New York", mobile = "878 78 87") ################################################### ### code chunk number 14: registry.Rnw:213-215 ################################################### R$set_entry("Myers", "John", "Washington", "52 32 34", "898 89 99", 33L, "Business") ################################################### ### code chunk number 15: registry.Rnw:218-223 ################################################### TRY <- function(expr) tryCatch(expr, error = print) TRY(R$set_entry(last = "Smith", first = "Mary")) TRY(R$set_entry(last = "Miller", first = "Henry")) TRY(R$set_entry(last = "Miller", first = "Henry", age = 12.5)) TRY(R$set_entry(last = "Miller", first = "Henry", age = 999L)) ################################################### ### code chunk number 16: registry.Rnw:226-227 ################################################### R$get_entry(last = "Smith", first = "mar") ################################################### ### code chunk number 17: registry.Rnw:231-234 ################################################### print.Address <- function(x) with(x, writeLines(sprintf("%s %s, %s; home: %s, mobile: %s; age: %i (%s)", first, last, address, home, mobile, age, type))) R$get_entry(last = "Smith", first = "mar") ################################################### ### code chunk number 18: registry.Rnw:241-242 ################################################### R[["Myers"]] ################################################### ### code chunk number 19: registry.Rnw:246-248 ################################################### R$set_entry(last = "Frears", first = c("Joe", "Jonathan"), address = "Washington", home = "721 42 34") ################################################### ### code chunk number 20: registry.Rnw:251-252 ################################################### identical(R[["Frears", "Jonathan"]], R[["Frears", "Joe"]]) ################################################### ### code chunk number 21: registry.Rnw:258-259 ################################################### R$get_entries("Smith") ################################################### ### code chunk number 22: registry.Rnw:262-263 ################################################### R$grep_entries("Priv") ################################################### ### code chunk number 23: registry.Rnw:266-268 (eval = FALSE) ################################################### ## R$get_entries() ## R[] ################################################### ### code chunk number 24: registry.Rnw:271-272 ################################################### summary(R) ################################################### ### code chunk number 25: registry.Rnw:276-279 ################################################### R[["Smith", "Peter"]] R$modify_entry(last = "Smith", first = "Peter", age = 22L) R[["Smith", "Peter"]] ################################################### ### code chunk number 26: registry.Rnw:282-284 ################################################### R$delete_entry(last = "Smith", first = "Peter") R[["Smith", "Peter"]] ################################################### ### code chunk number 27: registry.Rnw:294-299 ################################################### R$seal_entries() TRY(R$delete_entry("Smith", "Mary")) R$set_entry(last = "Slater", first = "Christian", address = "Boston", mobile = "766 23 88") R[["Slater"]] ################################################### ### code chunk number 28: registry.Rnw:302-307 ################################################### R$get_permissions() R$restrict_permissions(delete_entries = FALSE) TRY(R$delete_entry("Slater")) R$modify_entry(last = "Slater", first = "Christian", age = 44L) R[["Slater"]] registry/inst/doc/registry.Rnw0000755000175100001440000002600411714440422016226 0ustar hornikusers\documentclass[a4paper]{article} \usepackage[round,longnamesfirst]{natbib} \usepackage{graphicx,keyval,thumbpdf,a4wide,makeidx,color,colordvi} \usepackage{amsfonts,hyperref} \usepackage[utf8]{inputenc} \DeclareUnicodeCharacter{201C}{"} \DeclareUnicodeCharacter{201D}{"} \newcommand\R{\textsf{R}} \newcommand{\pkg}[1]{{\normalfont\fontseries{b}\selectfont #1}} \newcommand{\sQuote}[1]{`{#1}'} \newcommand{\dQuote}[1]{``{#1}''} \newcommand{\file}[1]{\sQuote{\textsf{#1}}} \newcommand{\data}[1]{\texttt{#1}} \newcommand{\var}[1]{\textit{#1}} \newcommand{\class}[1]{\textsf{#1}} \newcommand{\proglang}[1]{\textsf{#1}} %% \code without `-' ligatures \def\nohyphenation{\hyphenchar\font=-1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font=`-} {\catcode`\-=\active% \global\def\code{\bgroup% \catcode`\-=\active \let-\codedash% \Rd@code}} \def\codedash{-\discretionary{}{}{}} \def\Rd@code#1{\texttt{\nohyphenation#1}\egroup} \newcommand{\codefun}[1]{\code{#1()}} \newcommand{\codefunind}[1]{\codefun{#1}\index{\texttt{#1}}} \newcommand{\codeind}[1]{\code{#1}\index{\texttt{#1}}} \SweaveOpts{strip.white=true} \definecolor{Blue}{rgb}{0,0,0.8} \definecolor{Red}{rgb}{0.7,0,0} \date{2009-02-17} \title{A Generic Registry Infrastructure for \R} \author{David Meyer} %\VignetteIndexEntry{Registry} %\VignetteDepends{registry} %\VignetteKeywords{registry} %\VignettePackage{registry} \makeindex{} \sloppy{} \begin{document} \maketitle % \begin{abstract} % This document introduces a generic registry infrastructure for \R, % provided by the \pkg{registry} package. % \end{abstract} <>= options(width = 80) library("registry") @ % \section{Introduction} \label{sec:introduction} More and more, \R~packages are offering dynamic functionality, allowing users to extend a \dQuote{repository} of initial features or data. For example, the \pkg{proxy} package \citep{registry:meyer+buchta:2008} provides an enhanced \codefun{dist} function for computing dissimilarity matrices, allowing to choose among several proximity measures stored in a registry. Each entry is composed of a small workhorse function and some meta data including, e.g., a character vector of aliases, literature references, the formula in plain text, a function to coerce between similarity and distance, and a type categorization (binary, metric, etc.). Users can add new proximity measures to the registry at run-time and immediately use them without recreating the package, specifying one of the aliases defined in the meta data. Similarly, the \pkg{relations} \citep{registry:hornik+meyer:2008} and \pkg{CLUE} \citep{registry:hornik:2005,registry:hornik:2007} packages use simple registries internally to link some meta data to available functions, used by the high-level consensus ranking and cluster ensemble functions, respectively. Such a registry, whether exposed to the user or not, is conceptually a small in-memory data base where entries with a common field structure are stored and retrieved and whose fields can be of mixed type. At first sight, a data frame seems to be the data structure of choice for an appropriate implementation. Unfortunately, data frames are inconvenient to use with factors, functions, or other recursive types such as lists due to automatic coercions taking place behind the scenes. In fact, a simpler, record-like structure such as a list with named components (\dQuote{fields}) appears more practical. Also, features known from \dQuote{real} data bases such as compound keys, validity checking of new entries, and use of access rights are not available by default and need to be \dQuote{reinvented} every time they are needed. The \pkg{registry} package provides a simple mechanism for defining and manipulating user-extensible registry objects. A typical use case in the context of an \R~package could include the following steps: \begin{enumerate} \item Create one or more registry objects inside the package's namespace. \item Insert entries to the registry. \item Possibly, \dQuote{seal} the entries and set access rights. \item Possibly, export the registry object to the user level. \item Browse and retrieve entries from the registry. \end{enumerate} In the following, we explain these steps in more detail: first, how a registry can be set up; second, how entries can be added, modified and retrieved; and third, how a registry can be sealed and restricted through the definition of access rights. \section{Creating Registries} A registry basically is a container (implemented in \R~as an environment), along with some access functions. A new object of class \code{registry} can simply be created using the \codefun{registry} function: <<>>= library(registry) R <- registry() print(R) @ Optional parameters include the specification of an (additional) class for the created registry object and the individual entries, as well as the specification of some validity function checking new entries to be added to the registry. In the following, we will use the example of a simple address book, whose entries include first and last name, address, age, home/cell phone number, and a business/private classification. Last and first name build the search key. Age is an optional integer in the range of 1 and 99. Additionally, at least one phone number should be added to the registry. We start by creating two simple validity functions. The first one, to be specified at field level later on, checks a given age: <<>>= checkAge <- function(x) stopifnot(is.na(x) || x > 0 && x < 100) @ The second one, specified at registry level, checks whether a given registry entry (list of named components) contains at least one phone number: <<>>= checkPhone <- function(x) stopifnot(!is.na(x$mobile) || !is.na(x$home)) @ Next, we create a registry of class \code{Addressbook} (inheriting from \code{registry}), containing entries of class \code{Address} and using the above validity function. <<>>= R <- registry(registry_class = "Addressbook", entry_class = "Address", validity_FUN = checkPhone) @ The additional class for the registry allows, e.g., user-defined printing: <<>>= print.Addressbook <- function(x, ...) { writeLines(sprintf("An address book with %i entries.\n", length(x))) invisible(x) } print(R) @ At this stage, we are ready to set up the field information. First and last names are mandatory character fields, uniquely identifying an entry (key fields). Lookups should work with partial completion, ignoring case: <<>>= R$set_field("last", type = "character", is_key = TRUE, index_FUN = match_partial_ignorecase) R$set_field("first", type = "character", is_key = TRUE, index_FUN = match_partial_ignorecase) @ The address is also character, but optional: <<>>= R$set_field("address", type = "character") @ At least one phone number (character) is required. This can be achieved by making them optional, and using the validity function specified at the registry level to check whether one of them is empty: <<>>= R$set_field("mobile", type = "character") R$set_field("home", type = "character") @ The age field is an optional integer with a defined range, checked by the field-level validity function: <<>>= R$set_field("age", type = "integer", validity_FUN = checkAge) @ Finally, the business/private category is defined by specifying the possible alternatives (\code{Business} is set as default): <<>>= R$set_field("type", type = "character", alternatives = c("Business", "Private"), default = "Business") @ The setup for a field can be retrieved using \codefun{get\_field}: <<>>= R$get_field("type") @ \codefun{get\_fields} returns the complete list. \section{Using Registries} We now can start adding entries to the registry: <<>>= R$set_entry(last = "Smith", first = "Mary", address = "Vienna", home = "734 43 34", type = "Private", age = 44L) R$set_entry(last = "Smith", first = "Peter", address = "New York", mobile = "878 78 87") @ If all field values are specified, the field names can be omitted: <<>>= R$set_entry("Myers", "John", "Washington", "52 32 34", "898 89 99", 33L, "Business") @ Duplicate or invalid entries are not accepted: <<>>= TRY <- function(expr) tryCatch(expr, error = print) TRY(R$set_entry(last = "Smith", first = "Mary")) TRY(R$set_entry(last = "Miller", first = "Henry")) TRY(R$set_entry(last = "Miller", first = "Henry", age = 12.5)) TRY(R$set_entry(last = "Miller", first = "Henry", age = 999L)) @ A single entry can be retrieved using \codefun{get\_entry}: <<>>= R$get_entry(last = "Smith", first = "mar") @ Since returned entries inherit from \code{Address}, we can provide a user-defined print method: <<>>= print.Address <- function(x) with(x, writeLines(sprintf("%s %s, %s; home: %s, mobile: %s; age: %i (%s)", first, last, address, home, mobile, age, type))) R$get_entry(last = "Smith", first = "mar") @ Note that even though the first name of Mary Smith is incompletely specified and in lower case, the lookup is still successful because of the partial matching indexing function. The \code{[[} operator can be used as an alternative to \codefun{get\_entry}: <<>>= R[["Myers"]] @ For Myers, the last name uniquely identifies the entry, so the first name can be omitted. Key values can have alternative values: <<>>= R$set_entry(last = "Frears", first = c("Joe", "Jonathan"), address = "Washington", home = "721 42 34") @ Either of them can be used for retrieval: <<>>= identical(R[["Frears", "Jonathan"]], R[["Frears", "Joe"]]) @ Unsuccessful lookups result in a return of \code{NULL}. Multiple entries can be retrieved using the \codefun{get\_entries} accessing function. They are returned in a list whose component names are generated from the key values: <<>>= R$get_entries("Smith") @ Full-text search in all information is provided by \codefun{grep\_entries}: <<>>= R$grep_entries("Priv") @ A list of all entries can be obtained using either of: <>= R$get_entries() R[] @ The summary method for registry objects returns a data frame: <<>>= summary(R) @ Entries can also be modified using \codefun{modify\_entry}, specifying key and new field values: <<>>= R[["Smith", "Peter"]] R$modify_entry(last = "Smith", first = "Peter", age = 22L) R[["Smith", "Peter"]] @ Finally, entries can be removed using \codefun{delete\_entry}: <<>>= R$delete_entry(last = "Smith", first = "Peter") R[["Smith", "Peter"]] @ \section{Sealing Registries and Setting Access Rights} Occasionally, developers might want to protect a registry that ships with some package to prevent accidental deletions or alterations. For this, \pkg{registry} offers two mechanisms: first, a registry object can be \dQuote{sealed} to prevent modifications of \emph{existing} data: <<>>= R$seal_entries() TRY(R$delete_entry("Smith", "Mary")) R$set_entry(last = "Slater", first = "Christian", address = "Boston", mobile = "766 23 88") R[["Slater"]] @ Second, the access permissions for registries can be restricted: <<>>= R$get_permissions() R$restrict_permissions(delete_entries = FALSE) TRY(R$delete_entry("Slater")) R$modify_entry(last = "Slater", first = "Christian", age = 44L) R[["Slater"]] @ \bibliographystyle{abbrvnat} \bibliography{registry} \end{document} registry/tests/0000755000175100001440000000000012216131422013274 5ustar hornikusersregistry/tests/registry.R0000755000175100001440000000004310722651722015301 0ustar hornikuserslibrary(registry) demo("registry") registry/NAMESPACE0000655000175100001440000000051712546776062013403 0ustar hornikusersimportFrom("utils", "formatUL") export("registry") exportPattern("match_.*") S3method("[", "registry") S3method("[[", "registry") S3method("length", "registry") S3method("as.data.frame", "registry") S3method("print", "registry") S3method("summary", "registry") S3method("print", "registry_field") S3method("print", "registry_entry") registry/demo/0000755000175100001440000000000012216131422013056 5ustar hornikusersregistry/demo/registry.R0000755000175100001440000000366611120570556015077 0ustar hornikusers########################## ### registry test instances library(registry) .my_check_fun <- function(x) if (x$Z == 999 && x$New2 == 999) stop("No evil allowed!") ## create registry R <- registry(entry_class = "simple.list", validity_FUN = .my_check_fun) R ## set fields R$set_field("names", type = "character", is_key = TRUE) R$set_field("X", type = TRUE, is_mandatory = TRUE) R$set_field("Y", type = "character") R$set_field("Z", default = 123) R$get_fields() ## add entries R$set_entry(names = c("test", "bar"), X = TRUE, Y = "bla") R$set_entry(names = "test2", X = FALSE, Y = "foo", Z = 99) R$set_entry(names = "test3", X = FALSE, Y = "bar", Z = "chars") R$get_entry("test") R[["test2"]] R[["test3"]] R[["bar"]] ## add new field R$set_field("New") R$get_field("New") ## change entries R$modify_entry(names = "test", New = 123) R$modify_entry(names = "test2", New = "test") ## field check function (checks for strict positive values) R$set_field("New2", type = "numeric", validity_FUN = function(x) stopifnot(x > 0)) R$set_entry(names = "test5", X = TRUE, New2 = 2) ## add field with fixed alternatives R$set_field("New3", type = "character", alternatives = c("A", "B")) R$get_field("New") R$set_entry(names = "test6", X = TRUE, New3 = "A") ## print/summary = as.data.frame R summary(R) ## seal entries R$seal_entries() R$set_field("New4") R$set_entry(names = "test7", X = TRUE, Y = "bla") R$delete_entry("test7") R$modify_entry(names = "test", New4 = "test") ## error cases: TRY <- function(...) stopifnot(inherits(try(..., silent = TRUE), "try-error")) TRY(R$set_field("bla", type = "character", default = 123)) TRY(R$set_entry("err1", Y = "bla")) TRY(R$set_entry("err2", X = "bla")) TRY(R$set_entry("err3", X = TRUE, New2 = -2)) TRY(R$set_entry("err4", X = TRUE, Z = 999, New2 = 999)) TRY(R$set_entry("err5", X = TRUE, New3 = "C")) TRY(R$modify_entry("Bla", "New", 123)) TRY(R$modify_entry("X", "Bla", 123)) TRY(R$modify_entry("test","X",TRUE)) registry/demo/00Index0000755000175100001440000000005010722651124014214 0ustar hornikusersregistry Demo for the registry package registry/R/0000755000175100001440000000000013210551451012336 5ustar hornikusersregistry/R/utils.R0000755000175100001440000000011210722635434013627 0ustar hornikusers## This should be in base R! .FUNCall <- function(f) function(...) f(...) registry/R/converters.R0000755000175100001440000000102711233064514014660 0ustar hornikusersas.data.frame.registry <- function(x, ...) { .one_line <- function(entry) { entry <- lapply(.labels(entry), function(i) i[[1]]) data.frame(unclass(entry), ...) } ret <- do.call(rbind, lapply(x$get_entries(), .one_line)) row.names(ret) <- NULL ret } .labels <- function(x) { ## transform function entries x[sapply(x, inherits, "function")] <- "<>" ## transform objects obj <- sapply(x, is.object) x[obj] <- paste("<<", sapply(x, class)[obj], ">>", sep = "") x } registry/R/registry.R0000655000175100001440000003661213210551451014343 0ustar hornikusers################################### ### generic registry infrastructure ### IDEA: use lexical scope with nested functions to create an ### S3-"object" that exposes the data structure only through accessor functions. ## creating function registry <- function(entry_class = NULL, registry_class = NULL, validity_FUN = NULL, stop_if_missing = FALSE) { ### ATTRIBUTES ## repository DATA <- META <- list() ## permissions PERMISSIONS <- c(set_entries = TRUE, modify_entries = TRUE, delete_entries = TRUE, set_fields = TRUE) SEALED_FIELDS <- SEALED_ENTRIES <- character(0) ### METHODS (PRIVATE) ## helper functions .field_exists <- function(name) name %in% .get_field_names() .make_field <- function(type = NA, alternatives = NA, default = NA, is_mandatory = FALSE, is_modifiable = TRUE, is_key = FALSE, validity_FUN = NULL, index_FUN = match_ignorecase, index_FUN_args = NULL ) structure(list(type = type, alternatives = alternatives, default = default, is_mandatory = is_mandatory, is_modifiable = is_modifiable, is_key = is_key, validity_FUN = validity_FUN, index_FUN = index_FUN, index_FUN_args = index_FUN_args ), class = "registry_field") .make_entry <- function(l) { ## get index fields index_fields <- .get_index_fields() ## sort l <- l[c(index_fields, setdiff(.get_field_names(), index_fields))] ## return object (possibly inheriting from entry_class) structure(l, class = c(entry_class, "registry_entry")) } .get_index_fields <- function() names(META)[sapply(META, function(i) i$is_key)] .get_mandatory_fields <- function() names(META)[sapply(META, function(i) i$is_mandatory)] .get_field_defaults <- function() lapply(META, function(i) i$default) .get_entry_indices <- function(key, stop_missing = stop_if_missing, FUN = NULL, ARGS = NULL) { ## get index fields index_fields <- .get_index_fields() l <- length(key) n <- names(key) if (l != length(index_fields)) index_fields <- if (is.null(n)) index_fields[1:l] else intersect(n, index_fields) ## returns the index of the first match index <- seq_along(DATA) for (index_field in seq_along(index_fields)) { if (length(index) < 1) break if (is.null(FUN)) { FUN <- .get_field(index_fields[index_field])$index_FUN ARGS <- .get_field(index_fields[index_field])$index_FUN_args } index <- index[sapply(DATA[index], function(i) do.call(FUN, c(list(key[[index_field]], i[[ index_fields[index_field] ]]), ARGS)) )] } ## nothing found if (length(index) < 1) { if (stop_missing) stop("Entry not in registry.", call. = FALSE) else return(NULL) } ## return index } .get_first_entry_index <- function(key, stop_missing = stop_if_missing) .get_entry_indices(key, stop_missing)[1] .check_value <- function(field_name, field, value) { ## Note we do not check NA entries because this may by set automatically if (is.object(value) || !is.function(value) && !is.na(value[1])) { ## check class / list of alternatives, if any if (!any(is.na(field$type))) { ## check class if (!inherits(value, field$type)) { stop(paste("Field", dQuote(field_name), "does not inherit from:", paste(field$type, collapse = ", ")), call. = FALSE) } ## check list of alternatives if (!any(is.na(field$alternatives))) { if(!any(unlist(lapply(field$alternatives, identical, value)))) stop(paste("Possible values for", dQuote(field_name), "are:", paste(field$alternatives, collapse = ", ")), call. = FALSE) } } ## apply validity function, if any if (!is.null(field$validity_FUN)) do.call(field$validity_FUN, list(value)) } } .check_for_unknown_fields <- function(n) { ## check for fields not in repository missing <- !.field_exists(n) if (any(missing)) stop(paste("Field(s) not in repository:", paste(n[missing], collapse = ", ")), call. = FALSE) } ### METHODS (PUBLIC) ## field accessors .get_field <- function(name) { if (!.field_exists(name)) stop(paste("Field", dQuote(name), "not in registry."), call. = FALSE) META[[name]] } .get_fields <- function() META .get_field_names <- function() names(META) .set_field <- function(name, type = NA, alternatives = NA, default = NA, is_mandatory = NULL, is_modifiable = TRUE, is_key = FALSE, validity_FUN = NULL, index_FUN = match_ignorecase, ... ) { ## check permissions if (!PERMISSIONS["set_fields"]) stop("Setting of fields not allowed.", call. = FALSE) ## check for double entries if (.field_exists(name)) stop(paste("Field", dQuote(name), "already in registry."), call. = FALSE) ## possibly, infer type from argment if (!is.na(type) && !(is.character(type))) type <- class(type) ## check mandatory fields if (is.null(is_mandatory)) is_mandatory <- is_key if (is_mandatory && !is.na(default)) stop("Mandatory fields should have no default.", call. = FALSE) if (is_key && !is_mandatory) stop("Key fields must be mandatory.", call. = FALSE) ## create field entry field <- .make_field(type = type, alternatives = alternatives, default = default, is_mandatory = is_mandatory, is_modifiable = is_modifiable, is_key = is_key, validity_FUN = validity_FUN, index_FUN = index_FUN, index_FUN_args = list(...) ) ## check validity of default .check_value("default", field, default) ## check validity of alternatives if (!any(is.na(alternatives))) for (i in alternatives) .check_value("alternatives", field, i) ## add field to meta data META <<- c(META, list(field)) names(META)[length(META)] <<- name ## add (missing) fields to data entries DATA <<- lapply(DATA, `[[<-`, name, default) } .has_entry <- function(key) length(.get_entry_indices(key)) > 0 .n_of_entries <- function() length(DATA) ## entry accessors .set_entry <- function(...) { ## check permissions if (!PERMISSIONS["set_entries"]) stop("Setting of entries not allowed.", call. = FALSE) ## parameter handling l <- list(...) n <- names(l) index_fields <- .get_index_fields() fields <- .get_field_names() if (is.null(n)) { if (length(l) == length(fields)) { n <- fields names(l) <- n } else stop("Need either named arguments, or complete entry.") } .check_for_unknown_fields(n) ## check if there is at least one index field if (length(index_fields) < 1) stop("Need at least one index field before adding entries.", call. = FALSE) ## check for mandatory fields mandatory_fields <- .get_mandatory_fields() missing_mandatory_fields <- !mandatory_fields %in% n if (any(missing_mandatory_fields)) stop(paste("The following fields are mandatory, but missing:", paste(mandatory_fields[missing_mandatory_fields], collapse = ", ")), call. = FALSE) ## check for double entries if (length(.get_entry_indices(l[index_fields], stop_missing = FALSE, FUN = match_exact)) > 0) stop(paste("Entry already in registry."), call. = FALSE) ## check defaults and set values, if needed field_defaults <- .get_field_defaults() default_fields <- names(field_defaults) missing_fields <- setdiff(default_fields, n) l[missing_fields] <- field_defaults[missing_fields] ## check field types, and apply field check function, if any. for (f in n) .check_value(f, .get_field(f), l[[f]]) ## apply entry check function if (!is.null(validity_FUN)) do.call(validity_FUN, list(l)) ## add entry entry <- list(.make_entry(l)) names(entry) <- paste(lapply(entry[[1]][seq_along(index_fields)], `[[`, 1), collapse = "_") DATA <<- c(DATA, entry) } .get_entries <- function(...) { key <- list(...) if (length(key) > 0) { ind <- .get_entry_indices(key) if (length(ind) > 0) DATA[ind] else NULL } else DATA } .grep_entries <- function(pattern, ...) { pattern_in_entry <- function(x) any(sapply(x, function(i) is.character(i) && length(grep(pattern, i, ...) > 0))) ind <- sapply(DATA, pattern_in_entry) if (any(ind)) DATA[ind] else NULL } .get_first_entry <- function(...) .get_entries(...)[[1]] .get_entry_names <- function() { if (length(DATA) < 1) character(0) else names(DATA) } .delete_entry <- function(...) { key <- list(...) ## check permissions if (!PERMISSIONS["delete_entries"]) stop("Deletion of entries not allowed.", call. = FALSE) ## fetch entry index (this also checks if the entry exists) entry_index <- .get_entry_indices(key) ## check if it is unique if (length(entry_index) != 1) stop("Key specification must be unique.", call. = FALSE) ## check sealed entries if (entry_index %in% SEALED_ENTRIES) stop(paste("Deletion of entry not allowed."), call. = FALSE) ## delete it DATA[entry_index] <<- NULL } .modify_entry <- function(...) { ## check permissions if (!PERMISSIONS["modify_entries"]) stop("Modifying of entries not allowed.", call. = FALSE) ## parameter handling l <- list(...) n <- names(l) .check_for_unknown_fields(n) ## determine entry key key <- l[.get_index_fields()] ## fetch entry index (this also checks if the entry exists) entry_index <- .get_entry_indices(key, FUN=match_exact) ## check if it is unique if (length(entry_index) != 1) stop("Key specification must be unique!", call. = FALSE) ## fetch entry entry <- DATA[[entry_index]] for(field in setdiff(n, .get_index_fields())) { ## check if field is modifiable field_entry <- .get_field(field) if (!field_entry$is_modifiable) stop(paste("Field", dQuote(field), "is not modifiable."), call. = FALSE) ## check if entry and field are sealed if ((entry_index %in% SEALED_ENTRIES) && (field %in% SEALED_FIELDS)) stop(paste("Modification of field", dQuote(field), "in this entry not allowed."), call. = FALSE) ## check new value value <- l[[field]] .check_value(field, field_entry, value) ## modify entry locally entry[[field]] <- value } ## apply entry check function if (!is.null(validity_FUN)) do.call(validity_FUN, list(entry)) ## modify entry in registry DATA[entry_index] <<- list(entry) } ## get all entries for one field .get_field_entries <- function(field, unlist = TRUE) { if (!.field_exists(field)) stop(paste("Field", dQuote(field), "not in registry."), call. = FALSE) ret <- lapply(DATA, `[[`, field) if (unlist) unlist(ret) else ret } ## permission getters/setters .get_permissions <- function() PERMISSIONS .restrict_permissions <- function(set_entries = TRUE, modify_entries = TRUE, delete_entries = TRUE, set_fields = TRUE) { PERMISSIONS["set_entries"] <<- PERMISSIONS["set_entries"] && set_entries PERMISSIONS["modify_entries"] <<- PERMISSIONS["modify_entries"] && modify_entries PERMISSIONS["delete_entries"] <<- PERMISSIONS["delete_entries"] && delete_entries PERMISSIONS["set_fields"] <<- PERMISSIONS["set_fields"] && set_fields } .seal_entries <- function() { SEALED_ENTRIES <<- seq_along(DATA) SEALED_FIELDS <<- .get_field_names() } .get_sealed_field_names <- function() SEALED_FIELDS ### CONSTRUCTOR ## return class structure(list(get_field = .FUNCall(.get_field), get_fields = .FUNCall(.get_fields), get_field_names = .FUNCall(.get_field_names), set_field = .FUNCall(.set_field), has_entry = .FUNCall(.has_entry), get_entry = .FUNCall(.get_first_entry), get_entries = .FUNCall(.get_entries), get_entry_names = .FUNCall(.get_entry_names), grep_entries = .FUNCall(.grep_entries), set_entry = .FUNCall(.set_entry), modify_entry = .FUNCall(.modify_entry), delete_entry = .FUNCall(.delete_entry), n_of_entries = .FUNCall(.n_of_entries), get_field_entries = .FUNCall(.get_field_entries), get_permissions = .FUNCall(.get_permissions), restrict_permissions = .FUNCall(.restrict_permissions), seal_entries = .FUNCall(.seal_entries), get_sealed_field_names = .FUNCall(.get_sealed_field_names) ), class = c(registry_class, "registry")) } registry/R/accessors.R0000755000175100001440000000044211120513560014446 0ustar hornikusers"[[.registry" <- function(x, ...) { if (missing(..1)) x$get_entry() else x$get_entry(...) } "[.registry" <- function(x, ...) { if (missing(..1)) x$get_entries() else x$get_entries(...) } length.registry <- function(x) x$n_of_entries() registry/R/printsummary.R0000755000175100001440000000135111233064404015236 0ustar hornikusersprint.registry <- function(x, ...) { l <- x$n_of_entries() if (l < 1) writeLines(gettext("An object of class 'registry' with no entry.")) else if (l == 1) writeLines(gettext("An object of class 'registry' with one entry.")) else writeLines(gettextf("An object of class 'registry' with %d entries.", l)) invisible(x) } print.registry_field <- function(x, ...) ## remove index function { writeLines(formatUL(x[-7], label = names(x[-7]), ...)) invisible(x) } print.registry_entry <- function(x, ...) { x <- lapply(.labels(x), paste, collapse = ", ") writeLines(formatUL(x, label = names(x))) invisible(x) } summary.registry <- function(object, ...) as.data.frame(object, ...) registry/R/matchfuns.R0000755000175100001440000000074111146536310014461 0ustar hornikusers## user-specifiable lookup-functions match_ignorecase <- function(lookup, entry, ...) tolower(lookup) %in% tolower(entry) match_exact <- function(lookup, entry, ...) lookup %in% entry match_partial <- function(lookup, entry, ...) !is.na(pmatch(lookup, entry, ...)) match_partial_ignorecase <- function(lookup, entry, ...) !is.na(pmatch(tolower(lookup), tolower(entry), ...)) match_regexp <- function(lookup, entry, ...) length(grep(lookup, entry, ...)) > 0 registry/vignettes/0000755000175100001440000000000013210552315014145 5ustar hornikusersregistry/vignettes/abbrvnat.bst0000755000175100001440000006360511714440422016475 0ustar hornikusers%% File: `abbrvnat.bst' %% A modification of `abbrv.bst' for use with natbib package %% %% Copyright 1993-2005 Patrick W Daly %% Max-Planck-Institut f\"ur Sonnensystemforschung %% Max-Planck-Str. 2 %% D-37191 Katlenburg-Lindau %% Germany %% E-mail: daly@mps.mpg.de %% %% This program can be redistributed and/or modified under the terms %% of the LaTeX Project Public License Distributed from CTAN %% archives in directory macros/latex/base/lppl.txt; either %% version 1 of the License, or any later version. %% % Version and source file information: % \ProvidesFile{natbst.mbs}[2005/01/07 1.8 (PWD)] % % BibTeX `plainnat' family % version 0.99b for BibTeX versions 0.99a or later, % for LaTeX versions 2.09 and 2e. % % For use with the `natbib.sty' package; emulates the corresponding % member of the `plain' family, but with author-year citations. % % With version 6.0 of `natbib.sty', it may also be used for numerical % citations, while retaining the commands \citeauthor, \citefullauthor, % and \citeyear to print the corresponding information. % % For version 7.0 of `natbib.sty', the KEY field replaces missing % authors/editors, and the date is left blank in \bibitem. % % Includes field EID for the sequence/citation number of electronic journals % which is used instead of page numbers. % % Includes fields ISBN and ISSN. % % Includes field URL for Internet addresses. % % Includes field DOI for Digital Object Idenfifiers. % % Works best with the url.sty package of Donald Arseneau. % % Works with identical authors and year are further sorted by % citation key, to preserve any natural sequence. % ENTRY { address author booktitle chapter doi eid edition editor howpublished institution isbn issn journal key month note number organization pages publisher school series title type url volume year } {} { label extra.label sort.label short.list } INTEGERS { output.state before.all mid.sentence after.sentence after.block } FUNCTION {init.state.consts} { #0 'before.all := #1 'mid.sentence := #2 'after.sentence := #3 'after.block := } STRINGS { s t } FUNCTION {output.nonnull} { 's := output.state mid.sentence = { ", " * write$ } { output.state after.block = { add.period$ write$ newline$ "\newblock " write$ } { output.state before.all = 'write$ { add.period$ " " * write$ } if$ } if$ mid.sentence 'output.state := } if$ s } FUNCTION {output} { duplicate$ empty$ 'pop$ 'output.nonnull if$ } FUNCTION {output.check} { 't := duplicate$ empty$ { pop$ "empty " t * " in " * cite$ * warning$ } 'output.nonnull if$ } FUNCTION {fin.entry} { add.period$ write$ newline$ } FUNCTION {new.block} { output.state before.all = 'skip$ { after.block 'output.state := } if$ } FUNCTION {new.sentence} { output.state after.block = 'skip$ { output.state before.all = 'skip$ { after.sentence 'output.state := } if$ } if$ } FUNCTION {not} { { #0 } { #1 } if$ } FUNCTION {and} { 'skip$ { pop$ #0 } if$ } FUNCTION {or} { { pop$ #1 } 'skip$ if$ } FUNCTION {new.block.checka} { empty$ 'skip$ 'new.block if$ } FUNCTION {new.block.checkb} { empty$ swap$ empty$ and 'skip$ 'new.block if$ } FUNCTION {new.sentence.checka} { empty$ 'skip$ 'new.sentence if$ } FUNCTION {new.sentence.checkb} { empty$ swap$ empty$ and 'skip$ 'new.sentence if$ } FUNCTION {field.or.null} { duplicate$ empty$ { pop$ "" } 'skip$ if$ } FUNCTION {emphasize} { duplicate$ empty$ { pop$ "" } { "\emph{" swap$ * "}" * } if$ } INTEGERS { nameptr namesleft numnames } FUNCTION {format.names} { 's := #1 'nameptr := s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't := nameptr #1 > { namesleft #1 > { ", " * t * } { numnames #2 > { "," * } 'skip$ if$ t "others" = { " et~al." * } { " and " * t * } if$ } if$ } 't if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } FUNCTION {format.key} { empty$ { key field.or.null } { "" } if$ } FUNCTION {format.authors} { author empty$ { "" } { author format.names } if$ } FUNCTION {format.editors} { editor empty$ { "" } { editor format.names editor num.names$ #1 > { ", editors" * } { ", editor" * } if$ } if$ } FUNCTION {format.isbn} { isbn empty$ { "" } { new.block "ISBN " isbn * } if$ } FUNCTION {format.issn} { issn empty$ { "" } { new.block "ISSN " issn * } if$ } FUNCTION {format.url} { url empty$ { "" } { new.block "URL \url{" url * "}" * } if$ } FUNCTION {format.doi} { doi empty$ { "" } { new.block "\doi{" doi * "}" * } if$ } FUNCTION {format.title} { title empty$ { "" } { title "t" change.case$ } if$ } FUNCTION {format.full.names} {'s := #1 'nameptr := s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{vv~}{ll}" format.name$ 't := nameptr #1 > { namesleft #1 > { ", " * t * } { numnames #2 > { "," * } 'skip$ if$ t "others" = { " et~al." * } { " and " * t * } if$ } if$ } 't if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } FUNCTION {author.editor.full} { author empty$ { editor empty$ { "" } { editor format.full.names } if$ } { author format.full.names } if$ } FUNCTION {author.full} { author empty$ { "" } { author format.full.names } if$ } FUNCTION {editor.full} { editor empty$ { "" } { editor format.full.names } if$ } FUNCTION {make.full.names} { type$ "book" = type$ "inbook" = or 'author.editor.full { type$ "proceedings" = 'editor.full 'author.full if$ } if$ } FUNCTION {output.bibitem} { newline$ "\bibitem[" write$ label write$ ")" make.full.names duplicate$ short.list = { pop$ } { * } if$ "]{" * write$ cite$ write$ "}" write$ newline$ "" before.all 'output.state := } FUNCTION {n.dashify} { 't := "" { t empty$ not } { t #1 #1 substring$ "-" = { t #1 #2 substring$ "--" = not { "--" * t #2 global.max$ substring$ 't := } { { t #1 #1 substring$ "-" = } { "-" * t #2 global.max$ substring$ 't := } while$ } if$ } { t #1 #1 substring$ * t #2 global.max$ substring$ 't := } if$ } while$ } FUNCTION {format.date} { year duplicate$ empty$ { "empty year in " cite$ * warning$ pop$ "" } 'skip$ if$ month empty$ 'skip$ { month " " * swap$ * } if$ extra.label * } FUNCTION {format.btitle} { title emphasize } FUNCTION {tie.or.space.connect} { duplicate$ text.length$ #3 < { "~" } { " " } if$ swap$ * * } FUNCTION {either.or.check} { empty$ 'pop$ { "can't use both " swap$ * " fields in " * cite$ * warning$ } if$ } FUNCTION {format.bvolume} { volume empty$ { "" } { "volume" volume tie.or.space.connect series empty$ 'skip$ { " of " * series emphasize * } if$ "volume and number" number either.or.check } if$ } FUNCTION {format.number.series} { volume empty$ { number empty$ { series field.or.null } { output.state mid.sentence = { "number" } { "Number" } if$ number tie.or.space.connect series empty$ { "there's a number but no series in " cite$ * warning$ } { " in " * series * } if$ } if$ } { "" } if$ } FUNCTION {format.edition} { edition empty$ { "" } { output.state mid.sentence = { edition "l" change.case$ " edition" * } { edition "t" change.case$ " edition" * } if$ } if$ } INTEGERS { multiresult } FUNCTION {multi.page.check} { 't := #0 'multiresult := { multiresult not t empty$ not and } { t #1 #1 substring$ duplicate$ "-" = swap$ duplicate$ "," = swap$ "+" = or or { #1 'multiresult := } { t #2 global.max$ substring$ 't := } if$ } while$ multiresult } FUNCTION {format.pages} { pages empty$ { "" } { pages multi.page.check { "pages" pages n.dashify tie.or.space.connect } { "page" pages tie.or.space.connect } if$ } if$ } FUNCTION {format.eid} { eid empty$ { "" } { "art." eid tie.or.space.connect } if$ } FUNCTION {format.vol.num.pages} { volume field.or.null number empty$ 'skip$ { "\penalty0 (" number * ")" * * volume empty$ { "there's a number but no volume in " cite$ * warning$ } 'skip$ if$ } if$ pages empty$ 'skip$ { duplicate$ empty$ { pop$ format.pages } { ":\penalty0 " * pages n.dashify * } if$ } if$ } FUNCTION {format.vol.num.eid} { volume field.or.null number empty$ 'skip$ { "\penalty0 (" number * ")" * * volume empty$ { "there's a number but no volume in " cite$ * warning$ } 'skip$ if$ } if$ eid empty$ 'skip$ { duplicate$ empty$ { pop$ format.eid } { ":\penalty0 " * eid * } if$ } if$ } FUNCTION {format.chapter.pages} { chapter empty$ 'format.pages { type empty$ { "chapter" } { type "l" change.case$ } if$ chapter tie.or.space.connect pages empty$ 'skip$ { ", " * format.pages * } if$ } if$ } FUNCTION {format.in.ed.booktitle} { booktitle empty$ { "" } { editor empty$ { "In " booktitle emphasize * } { "In " format.editors * ", " * booktitle emphasize * } if$ } if$ } FUNCTION {empty.misc.check} { author empty$ title empty$ howpublished empty$ month empty$ year empty$ note empty$ and and and and and key empty$ not and { "all relevant fields are empty in " cite$ * warning$ } 'skip$ if$ } FUNCTION {format.thesis.type} { type empty$ 'skip$ { pop$ type "t" change.case$ } if$ } FUNCTION {format.tr.number} { type empty$ { "Technical Report" } 'type if$ number empty$ { "t" change.case$ } { number tie.or.space.connect } if$ } FUNCTION {format.article.crossref} { key empty$ { journal empty$ { "need key or journal for " cite$ * " to crossref " * crossref * warning$ "" } { "In \emph{" journal * "}" * } if$ } { "In " key * } if$ " \citep{" * crossref * "}" * } FUNCTION {format.book.crossref} { volume empty$ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ "In " } { "Volume" volume tie.or.space.connect " of " * } if$ editor empty$ editor field.or.null author field.or.null = or { key empty$ { series empty$ { "need editor, key, or series for " cite$ * " to crossref " * crossref * warning$ "" * } { "\emph{" * series * "}" * } if$ } { key * } if$ } 'skip$ if$ ", \citet{" * crossref * "}" * } FUNCTION {format.incoll.inproc.crossref} { editor empty$ editor field.or.null author field.or.null = or { key empty$ { booktitle empty$ { "need editor, key, or booktitle for " cite$ * " to crossref " * crossref * warning$ "" } { "In \emph{" booktitle * "}" * } if$ } { "In " key * } if$ } { "In " } if$ " \citet{" * crossref * "}" * } FUNCTION {article} { output.bibitem format.authors "author" output.check author format.key output new.block format.title "title" output.check new.block crossref missing$ { journal emphasize "journal" output.check eid empty$ { format.vol.num.pages output } { format.vol.num.eid output } if$ format.date "year" output.check } { format.article.crossref output.nonnull eid empty$ { format.pages output } { format.eid output } if$ } if$ format.issn output format.doi output format.url output new.block note output fin.entry } FUNCTION {book} { output.bibitem author empty$ { format.editors "author and editor" output.check editor format.key output } { format.authors output.nonnull crossref missing$ { "author and editor" editor either.or.check } 'skip$ if$ } if$ new.block format.btitle "title" output.check crossref missing$ { format.bvolume output new.block format.number.series output new.sentence publisher "publisher" output.check address output } { new.block format.book.crossref output.nonnull } if$ format.edition output format.date "year" output.check format.isbn output format.doi output format.url output new.block note output fin.entry } FUNCTION {booklet} { output.bibitem format.authors output author format.key output new.block format.title "title" output.check howpublished address new.block.checkb howpublished output address output format.date output format.isbn output format.doi output format.url output new.block note output fin.entry } FUNCTION {inbook} { output.bibitem author empty$ { format.editors "author and editor" output.check editor format.key output } { format.authors output.nonnull crossref missing$ { "author and editor" editor either.or.check } 'skip$ if$ } if$ new.block format.btitle "title" output.check crossref missing$ { format.bvolume output format.chapter.pages "chapter and pages" output.check new.block format.number.series output new.sentence publisher "publisher" output.check address output } { format.chapter.pages "chapter and pages" output.check new.block format.book.crossref output.nonnull } if$ format.edition output format.date "year" output.check format.isbn output format.doi output format.url output new.block note output fin.entry } FUNCTION {incollection} { output.bibitem format.authors "author" output.check author format.key output new.block format.title "title" output.check new.block crossref missing$ { format.in.ed.booktitle "booktitle" output.check format.bvolume output format.number.series output format.chapter.pages output new.sentence publisher "publisher" output.check address output format.edition output format.date "year" output.check } { format.incoll.inproc.crossref output.nonnull format.chapter.pages output } if$ format.isbn output format.doi output format.url output new.block note output fin.entry } FUNCTION {inproceedings} { output.bibitem format.authors "author" output.check author format.key output new.block format.title "title" output.check new.block crossref missing$ { format.in.ed.booktitle "booktitle" output.check format.bvolume output format.number.series output format.pages output address empty$ { organization publisher new.sentence.checkb organization output publisher output format.date "year" output.check } { address output.nonnull format.date "year" output.check new.sentence organization output publisher output } if$ } { format.incoll.inproc.crossref output.nonnull format.pages output } if$ format.isbn output format.doi output format.url output new.block note output fin.entry } FUNCTION {conference} { inproceedings } FUNCTION {manual} { output.bibitem format.authors output author format.key output new.block format.btitle "title" output.check organization address new.block.checkb organization output address output format.edition output format.date output format.url output new.block note output fin.entry } FUNCTION {mastersthesis} { output.bibitem format.authors "author" output.check author format.key output new.block format.title "title" output.check new.block "Master's thesis" format.thesis.type output.nonnull school "school" output.check address output format.date "year" output.check format.url output new.block note output fin.entry } FUNCTION {misc} { output.bibitem format.authors output author format.key output title howpublished new.block.checkb format.title output howpublished new.block.checka howpublished output format.date output format.issn output format.url output new.block note output fin.entry empty.misc.check } FUNCTION {phdthesis} { output.bibitem format.authors "author" output.check author format.key output new.block format.btitle "title" output.check new.block "PhD thesis" format.thesis.type output.nonnull school "school" output.check address output format.date "year" output.check format.url output new.block note output fin.entry } FUNCTION {proceedings} { output.bibitem format.editors output editor format.key output new.block format.btitle "title" output.check format.bvolume output format.number.series output address output format.date "year" output.check new.sentence organization output publisher output format.isbn output format.doi output format.url output new.block note output fin.entry } FUNCTION {techreport} { output.bibitem format.authors "author" output.check author format.key output new.block format.title "title" output.check new.block format.tr.number output.nonnull institution "institution" output.check address output format.date "year" output.check format.url output new.block note output fin.entry } FUNCTION {unpublished} { output.bibitem format.authors "author" output.check author format.key output new.block format.title "title" output.check format.url output new.block note "note" output.check format.date output fin.entry } FUNCTION {default.type} { misc } MACRO {jan} {"Jan."} MACRO {feb} {"Feb."} MACRO {mar} {"Mar."} MACRO {apr} {"Apr."} MACRO {may} {"May"} MACRO {jun} {"June"} MACRO {jul} {"July"} MACRO {aug} {"Aug."} MACRO {sep} {"Sept."} MACRO {oct} {"Oct."} MACRO {nov} {"Nov."} MACRO {dec} {"Dec."} MACRO {acmcs} {"ACM Comput. Surv."} MACRO {acta} {"Acta Inf."} MACRO {cacm} {"Commun. ACM"} MACRO {ibmjrd} {"IBM J. Res. Dev."} MACRO {ibmsj} {"IBM Syst.~J."} MACRO {ieeese} {"IEEE Trans. Softw. Eng."} MACRO {ieeetc} {"IEEE Trans. Comput."} MACRO {ieeetcad} {"IEEE Trans. Comput.-Aided Design Integrated Circuits"} MACRO {ipl} {"Inf. Process. Lett."} MACRO {jacm} {"J.~ACM"} MACRO {jcss} {"J.~Comput. Syst. Sci."} MACRO {scp} {"Sci. Comput. Programming"} MACRO {sicomp} {"SIAM J. Comput."} MACRO {tocs} {"ACM Trans. Comput. Syst."} MACRO {tods} {"ACM Trans. Database Syst."} MACRO {tog} {"ACM Trans. Gr."} MACRO {toms} {"ACM Trans. Math. Softw."} MACRO {toois} {"ACM Trans. Office Inf. Syst."} MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."} MACRO {tcs} {"Theoretical Comput. Sci."} READ FUNCTION {sortify} { purify$ "l" change.case$ } INTEGERS { len } FUNCTION {chop.word} { 's := 'len := s #1 len substring$ = { s len #1 + global.max$ substring$ } 's if$ } FUNCTION {format.lab.names} { 's := s #1 "{vv~}{ll}" format.name$ s num.names$ duplicate$ #2 > { pop$ " et~al." * } { #2 < 'skip$ { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = { " et~al." * } { " and " * s #2 "{vv~}{ll}" format.name$ * } if$ } if$ } if$ } FUNCTION {author.key.label} { author empty$ { key empty$ { cite$ #1 #3 substring$ } 'key if$ } { author format.lab.names } if$ } FUNCTION {author.editor.key.label} { author empty$ { editor empty$ { key empty$ { cite$ #1 #3 substring$ } 'key if$ } { editor format.lab.names } if$ } { author format.lab.names } if$ } FUNCTION {author.key.organization.label} { author empty$ { key empty$ { organization empty$ { cite$ #1 #3 substring$ } { "The " #4 organization chop.word #3 text.prefix$ } if$ } 'key if$ } { author format.lab.names } if$ } FUNCTION {editor.key.organization.label} { editor empty$ { key empty$ { organization empty$ { cite$ #1 #3 substring$ } { "The " #4 organization chop.word #3 text.prefix$ } if$ } 'key if$ } { editor format.lab.names } if$ } FUNCTION {calc.short.authors} { type$ "book" = type$ "inbook" = or 'author.editor.key.label { type$ "proceedings" = 'editor.key.organization.label { type$ "manual" = 'author.key.organization.label 'author.key.label if$ } if$ } if$ 'short.list := } FUNCTION {calc.label} { calc.short.authors short.list "(" * year duplicate$ empty$ short.list key field.or.null = or { pop$ "" } 'skip$ if$ * 'label := } FUNCTION {sort.format.names} { 's := #1 'nameptr := "" s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := nameptr #1 > { " " * namesleft #1 = t "others" = and { "zzzzz" * } { numnames #2 > nameptr #2 = and { "zz" * year field.or.null * " " * } 'skip$ if$ t sortify * } if$ } { t sortify * } if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } FUNCTION {sort.format.title} { 't := "A " #2 "An " #3 "The " #4 t chop.word chop.word chop.word sortify #1 global.max$ substring$ } FUNCTION {author.sort} { author empty$ { key empty$ { "to sort, need author or key in " cite$ * warning$ "" } { key sortify } if$ } { author sort.format.names } if$ } FUNCTION {author.editor.sort} { author empty$ { editor empty$ { key empty$ { "to sort, need author, editor, or key in " cite$ * warning$ "" } { key sortify } if$ } { editor sort.format.names } if$ } { author sort.format.names } if$ } FUNCTION {author.organization.sort} { author empty$ { organization empty$ { key empty$ { "to sort, need author, organization, or key in " cite$ * warning$ "" } { key sortify } if$ } { "The " #4 organization chop.word sortify } if$ } { author sort.format.names } if$ } FUNCTION {editor.organization.sort} { editor empty$ { organization empty$ { key empty$ { "to sort, need editor, organization, or key in " cite$ * warning$ "" } { key sortify } if$ } { "The " #4 organization chop.word sortify } if$ } { editor sort.format.names } if$ } FUNCTION {presort} { calc.label label sortify " " * type$ "book" = type$ "inbook" = or 'author.editor.sort { type$ "proceedings" = 'editor.organization.sort { type$ "manual" = 'author.organization.sort 'author.sort if$ } if$ } if$ " " * cite$ * #1 entry.max$ substring$ 'sort.label := sort.label * #1 entry.max$ substring$ 'sort.key$ := } ITERATE {presort} SORT STRINGS { longest.label last.label next.extra } INTEGERS { longest.label.width last.extra.num number.label } FUNCTION {initialize.longest.label} { "" 'longest.label := #0 int.to.chr$ 'last.label := "" 'next.extra := #0 'longest.label.width := #0 'last.extra.num := #0 'number.label := } FUNCTION {forward.pass} { last.label label = { last.extra.num #1 + 'last.extra.num := last.extra.num int.to.chr$ 'extra.label := } { "a" chr.to.int$ 'last.extra.num := "" 'extra.label := label 'last.label := } if$ number.label #1 + 'number.label := } FUNCTION {reverse.pass} { next.extra "b" = { "a" 'extra.label := } 'skip$ if$ extra.label 'next.extra := extra.label duplicate$ empty$ 'skip$ { "{\natexlab{" swap$ * "}}" * } if$ 'extra.label := label extra.label * 'label := } EXECUTE {initialize.longest.label} ITERATE {forward.pass} REVERSE {reverse.pass} FUNCTION {bib.sort.order} { sort.label 'sort.key$ := } ITERATE {bib.sort.order} SORT FUNCTION {begin.bib} { preamble$ empty$ 'skip$ { preamble$ write$ newline$ } if$ "\begin{thebibliography}{" number.label int.to.str$ * "}" * write$ newline$ "\providecommand{\natexlab}[1]{#1}" write$ newline$ "\providecommand{\url}[1]{\texttt{#1}}" write$ newline$ "\expandafter\ifx\csname urlstyle\endcsname\relax" write$ newline$ " \providecommand{\doi}[1]{doi: #1}\else" write$ newline$ " \providecommand{\doi}{doi: \begingroup \urlstyle{rm}\Url}\fi" write$ newline$ } EXECUTE {begin.bib} EXECUTE {init.state.consts} ITERATE {call.type$} FUNCTION {end.bib} { newline$ "\end{thebibliography}" write$ newline$ } EXECUTE {end.bib} registry/vignettes/registry.bib0000755000175100001440000000174211714440422016504 0ustar hornikusers@Manual{registry:meyer+buchta:2008, title = {proxy: Distance and Similarity Measures}, author = {David Meyer and Christian Buchta}, year = 2008, note = {R package version 0.4-1} } @Manual{registry:hornik:2007, title = {clue: Cluster ensembles}, author = {Kurt Hornik}, year = 2007, note = {R package version 0.3-20.}, url = {http://CRAN.R-project.org/} } @Article{registry:hornik:2005, title = {A {CLUE} for {CLUster Ensembles}}, author = {Kurt Hornik}, year = 2005, journal = {Journal of Statistical Software}, volume = 14, number = 12, url = {http://www.jstatsoft.org/v14/i12/}, month = {September} } @Manual{registry:hornik+meyer:2008, title = {relations: Data Structures and Algorithms for Relations}, author = {Kurt Hornik and David Meyer}, year = 2008, note = {R package version 0.5} } registry/vignettes/registry.Rnw0000755000175100001440000002600411714440422016514 0ustar hornikusers\documentclass[a4paper]{article} \usepackage[round,longnamesfirst]{natbib} \usepackage{graphicx,keyval,thumbpdf,a4wide,makeidx,color,colordvi} \usepackage{amsfonts,hyperref} \usepackage[utf8]{inputenc} \DeclareUnicodeCharacter{201C}{"} \DeclareUnicodeCharacter{201D}{"} \newcommand\R{\textsf{R}} \newcommand{\pkg}[1]{{\normalfont\fontseries{b}\selectfont #1}} \newcommand{\sQuote}[1]{`{#1}'} \newcommand{\dQuote}[1]{``{#1}''} \newcommand{\file}[1]{\sQuote{\textsf{#1}}} \newcommand{\data}[1]{\texttt{#1}} \newcommand{\var}[1]{\textit{#1}} \newcommand{\class}[1]{\textsf{#1}} \newcommand{\proglang}[1]{\textsf{#1}} %% \code without `-' ligatures \def\nohyphenation{\hyphenchar\font=-1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font=`-} {\catcode`\-=\active% \global\def\code{\bgroup% \catcode`\-=\active \let-\codedash% \Rd@code}} \def\codedash{-\discretionary{}{}{}} \def\Rd@code#1{\texttt{\nohyphenation#1}\egroup} \newcommand{\codefun}[1]{\code{#1()}} \newcommand{\codefunind}[1]{\codefun{#1}\index{\texttt{#1}}} \newcommand{\codeind}[1]{\code{#1}\index{\texttt{#1}}} \SweaveOpts{strip.white=true} \definecolor{Blue}{rgb}{0,0,0.8} \definecolor{Red}{rgb}{0.7,0,0} \date{2009-02-17} \title{A Generic Registry Infrastructure for \R} \author{David Meyer} %\VignetteIndexEntry{Registry} %\VignetteDepends{registry} %\VignetteKeywords{registry} %\VignettePackage{registry} \makeindex{} \sloppy{} \begin{document} \maketitle % \begin{abstract} % This document introduces a generic registry infrastructure for \R, % provided by the \pkg{registry} package. % \end{abstract} <>= options(width = 80) library("registry") @ % \section{Introduction} \label{sec:introduction} More and more, \R~packages are offering dynamic functionality, allowing users to extend a \dQuote{repository} of initial features or data. For example, the \pkg{proxy} package \citep{registry:meyer+buchta:2008} provides an enhanced \codefun{dist} function for computing dissimilarity matrices, allowing to choose among several proximity measures stored in a registry. Each entry is composed of a small workhorse function and some meta data including, e.g., a character vector of aliases, literature references, the formula in plain text, a function to coerce between similarity and distance, and a type categorization (binary, metric, etc.). Users can add new proximity measures to the registry at run-time and immediately use them without recreating the package, specifying one of the aliases defined in the meta data. Similarly, the \pkg{relations} \citep{registry:hornik+meyer:2008} and \pkg{CLUE} \citep{registry:hornik:2005,registry:hornik:2007} packages use simple registries internally to link some meta data to available functions, used by the high-level consensus ranking and cluster ensemble functions, respectively. Such a registry, whether exposed to the user or not, is conceptually a small in-memory data base where entries with a common field structure are stored and retrieved and whose fields can be of mixed type. At first sight, a data frame seems to be the data structure of choice for an appropriate implementation. Unfortunately, data frames are inconvenient to use with factors, functions, or other recursive types such as lists due to automatic coercions taking place behind the scenes. In fact, a simpler, record-like structure such as a list with named components (\dQuote{fields}) appears more practical. Also, features known from \dQuote{real} data bases such as compound keys, validity checking of new entries, and use of access rights are not available by default and need to be \dQuote{reinvented} every time they are needed. The \pkg{registry} package provides a simple mechanism for defining and manipulating user-extensible registry objects. A typical use case in the context of an \R~package could include the following steps: \begin{enumerate} \item Create one or more registry objects inside the package's namespace. \item Insert entries to the registry. \item Possibly, \dQuote{seal} the entries and set access rights. \item Possibly, export the registry object to the user level. \item Browse and retrieve entries from the registry. \end{enumerate} In the following, we explain these steps in more detail: first, how a registry can be set up; second, how entries can be added, modified and retrieved; and third, how a registry can be sealed and restricted through the definition of access rights. \section{Creating Registries} A registry basically is a container (implemented in \R~as an environment), along with some access functions. A new object of class \code{registry} can simply be created using the \codefun{registry} function: <<>>= library(registry) R <- registry() print(R) @ Optional parameters include the specification of an (additional) class for the created registry object and the individual entries, as well as the specification of some validity function checking new entries to be added to the registry. In the following, we will use the example of a simple address book, whose entries include first and last name, address, age, home/cell phone number, and a business/private classification. Last and first name build the search key. Age is an optional integer in the range of 1 and 99. Additionally, at least one phone number should be added to the registry. We start by creating two simple validity functions. The first one, to be specified at field level later on, checks a given age: <<>>= checkAge <- function(x) stopifnot(is.na(x) || x > 0 && x < 100) @ The second one, specified at registry level, checks whether a given registry entry (list of named components) contains at least one phone number: <<>>= checkPhone <- function(x) stopifnot(!is.na(x$mobile) || !is.na(x$home)) @ Next, we create a registry of class \code{Addressbook} (inheriting from \code{registry}), containing entries of class \code{Address} and using the above validity function. <<>>= R <- registry(registry_class = "Addressbook", entry_class = "Address", validity_FUN = checkPhone) @ The additional class for the registry allows, e.g., user-defined printing: <<>>= print.Addressbook <- function(x, ...) { writeLines(sprintf("An address book with %i entries.\n", length(x))) invisible(x) } print(R) @ At this stage, we are ready to set up the field information. First and last names are mandatory character fields, uniquely identifying an entry (key fields). Lookups should work with partial completion, ignoring case: <<>>= R$set_field("last", type = "character", is_key = TRUE, index_FUN = match_partial_ignorecase) R$set_field("first", type = "character", is_key = TRUE, index_FUN = match_partial_ignorecase) @ The address is also character, but optional: <<>>= R$set_field("address", type = "character") @ At least one phone number (character) is required. This can be achieved by making them optional, and using the validity function specified at the registry level to check whether one of them is empty: <<>>= R$set_field("mobile", type = "character") R$set_field("home", type = "character") @ The age field is an optional integer with a defined range, checked by the field-level validity function: <<>>= R$set_field("age", type = "integer", validity_FUN = checkAge) @ Finally, the business/private category is defined by specifying the possible alternatives (\code{Business} is set as default): <<>>= R$set_field("type", type = "character", alternatives = c("Business", "Private"), default = "Business") @ The setup for a field can be retrieved using \codefun{get\_field}: <<>>= R$get_field("type") @ \codefun{get\_fields} returns the complete list. \section{Using Registries} We now can start adding entries to the registry: <<>>= R$set_entry(last = "Smith", first = "Mary", address = "Vienna", home = "734 43 34", type = "Private", age = 44L) R$set_entry(last = "Smith", first = "Peter", address = "New York", mobile = "878 78 87") @ If all field values are specified, the field names can be omitted: <<>>= R$set_entry("Myers", "John", "Washington", "52 32 34", "898 89 99", 33L, "Business") @ Duplicate or invalid entries are not accepted: <<>>= TRY <- function(expr) tryCatch(expr, error = print) TRY(R$set_entry(last = "Smith", first = "Mary")) TRY(R$set_entry(last = "Miller", first = "Henry")) TRY(R$set_entry(last = "Miller", first = "Henry", age = 12.5)) TRY(R$set_entry(last = "Miller", first = "Henry", age = 999L)) @ A single entry can be retrieved using \codefun{get\_entry}: <<>>= R$get_entry(last = "Smith", first = "mar") @ Since returned entries inherit from \code{Address}, we can provide a user-defined print method: <<>>= print.Address <- function(x) with(x, writeLines(sprintf("%s %s, %s; home: %s, mobile: %s; age: %i (%s)", first, last, address, home, mobile, age, type))) R$get_entry(last = "Smith", first = "mar") @ Note that even though the first name of Mary Smith is incompletely specified and in lower case, the lookup is still successful because of the partial matching indexing function. The \code{[[} operator can be used as an alternative to \codefun{get\_entry}: <<>>= R[["Myers"]] @ For Myers, the last name uniquely identifies the entry, so the first name can be omitted. Key values can have alternative values: <<>>= R$set_entry(last = "Frears", first = c("Joe", "Jonathan"), address = "Washington", home = "721 42 34") @ Either of them can be used for retrieval: <<>>= identical(R[["Frears", "Jonathan"]], R[["Frears", "Joe"]]) @ Unsuccessful lookups result in a return of \code{NULL}. Multiple entries can be retrieved using the \codefun{get\_entries} accessing function. They are returned in a list whose component names are generated from the key values: <<>>= R$get_entries("Smith") @ Full-text search in all information is provided by \codefun{grep\_entries}: <<>>= R$grep_entries("Priv") @ A list of all entries can be obtained using either of: <>= R$get_entries() R[] @ The summary method for registry objects returns a data frame: <<>>= summary(R) @ Entries can also be modified using \codefun{modify\_entry}, specifying key and new field values: <<>>= R[["Smith", "Peter"]] R$modify_entry(last = "Smith", first = "Peter", age = 22L) R[["Smith", "Peter"]] @ Finally, entries can be removed using \codefun{delete\_entry}: <<>>= R$delete_entry(last = "Smith", first = "Peter") R[["Smith", "Peter"]] @ \section{Sealing Registries and Setting Access Rights} Occasionally, developers might want to protect a registry that ships with some package to prevent accidental deletions or alterations. For this, \pkg{registry} offers two mechanisms: first, a registry object can be \dQuote{sealed} to prevent modifications of \emph{existing} data: <<>>= R$seal_entries() TRY(R$delete_entry("Smith", "Mary")) R$set_entry(last = "Slater", first = "Christian", address = "Boston", mobile = "766 23 88") R[["Slater"]] @ Second, the access permissions for registries can be restricted: <<>>= R$get_permissions() R$restrict_permissions(delete_entries = FALSE) TRY(R$delete_entry("Slater")) R$modify_entry(last = "Slater", first = "Christian", age = 44L) R[["Slater"]] @ \bibliographystyle{abbrvnat} \bibliography{registry} \end{document} registry/MD50000644000175100001440000000205013210742516012446 0ustar hornikuserse4c26559421b36f9684fe4b4cf1151e3 *DESCRIPTION 5d602abc58c4875294dc11f72158774d *NAMESPACE b3074b376232f3c1fd80571ba446996f *R/accessors.R bb342556b9b96cfa5283fce894700b0d *R/converters.R bc616cbb85bd434ba34d927e64f630be *R/matchfuns.R 880b67c5a7ad7d534dbafe347219223b *R/printsummary.R ad2139eed220df72ad5ec741b92e5791 *R/registry.R 21bb06f605604d73919a8d3cb816f44c *R/utils.R bf34aeaa284a479836ad611a74dcc434 *build/vignette.rds 8eb52e1e2fe74ae94a8aa3113511b94f *demo/00Index aef06553ca79a1d87d69ae93ea9ffcd8 *demo/registry.R 7d44eb1b5a93ff5de790427a3b8c2301 *inst/doc/registry.R 03889df16f04b2e9156693baf5e9e694 *inst/doc/registry.Rnw ac1c382da5eb124075565a02c1ce6d95 *inst/doc/registry.pdf d75af01cf06a4c33ade70aea44df055d *man/matchfuns.Rd 3ba25d05aadad18ae969da1ed416f2b6 *man/registry.Rd 5648e6108e71120477b77b0150624873 *man/regobj.Rd 2c77c272d1d8f1c5bb781bb9ec6edf44 *tests/registry.R ee1b5ad6f2633c9d108cc96775448248 *vignettes/abbrvnat.bst 03889df16f04b2e9156693baf5e9e694 *vignettes/registry.Rnw a2cad786f79804c8744a9e008c1651c0 *vignettes/registry.bib registry/build/0000755000175100001440000000000013210552315013234 5ustar hornikusersregistry/build/vignette.rds0000644000175100001440000000030313210552315015567 0ustar hornikusersb```b`faf`b2 1# ')JM,.) +GS&Dž0h0X",LHyh]R RR@3?wjey~ 5lP5,n90wd9.nP&c0GgQ~Oh9JI,IK+^registry/DESCRIPTION0000655000175100001440000000064313210742516013654 0ustar hornikusersPackage: registry Type: Package Title: Infrastructure for R Package Registries Version: 0.5 Author: David Meyer Maintainer: David Meyer Description: Provides a generic infrastructure for creating and using registries. Depends: R (>= 2.6.0) Imports: utils License: GPL-2 NeedsCompilation: no Packaged: 2017-12-02 16:29:01 UTC; meyer Repository: CRAN Date/Publication: 2017-12-03 09:35:10 UTC registry/man/0000755000175100001440000000000013210552315012710 5ustar hornikusersregistry/man/regobj.Rd0000755000175100001440000001400612216131432014451 0ustar hornikusers\name{regobj} \alias{regobj} \alias{summary.registry} \alias{print.registry} \alias{[.registry} \alias{[[.registry} %- Also NEED an '\alias' for EACH other topic documented here. \title{Registry object} \description{ Registry object. } \usage{ \special{regobj$get_field(name)} \special{regobj$get_fields()} \special{regobj$get_field_names()} \special{regobj$set_field(name, type = NA, alternatives = NA, default = NA, is_mandatory = FALSE, is_modifiable = TRUE, is_key = FALSE, validity_FUN = NULL, index_FUN = match_ignorecase, \dots)} \special{regobj$has_entry(key)} \special{regobj$get_entry(\dots)} \special{regobj$get_entries(\dots)} \special{regobj$grep_entries(pattern, \dots)} \special{regobj$get_entry_names()} \special{regobj$set_entry(\dots)} \special{regobj$modify_entry(\dots)} \special{regobj$delete_entry(\dots)} \special{regobj$n_of_entries(name)} \special{regobj$get_field_entries(field, unlist = TRUE)} \special{regobj$get_permissions()} \special{regobj$restrict_permissions(set_entries = TRUE, modify_entries = TRUE, delete_entries = TRUE, set_fields = TRUE)} \special{regobj$seal_entries()} \special{regobj$get_sealed_field_names()} \method{print}{registry}(x, \dots) \method{summary}{registry}(object, \dots) \method{[[}{registry}(x, \dots) \method{[}{registry}(x, \dots) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{name}{character string representing the name of an entry (case-insensitive).} \item{pattern}{regular expression to be matched to all fields of class \code{"character"} in all entries.} \item{type}{character vector specifying accepted classes for this field. If \code{NA} (default), any class will be accepted. If \code{type} is not a character vector, the class will be inferred from the argument given.} \item{alternatives}{vector of alternatives accepted for this field.} \item{default}{optional default value for the field.} \item{is_mandatory}{logical specifying whether new entries are required to have a value for this field.} \item{is_modifiable}{logical specifying whether entries can be changed with respect to that field.} \item{is_key}{logical indicating whether the field is (part of) an index.} \item{validity_FUN}{optional function or character string with the name of a function that checks the validity of a field entry. Such a function gets the value to be investigated as argument, and should stop with an error message if the value is not correct.} \item{index_FUN}{vectorized predicate function matching an index value to a vector (of existing field entries). See \link{matchfuns}.} \item{x, object}{a registry object.} \item{\dots}{for \code{regobj$set_entry} and \code{regobj$modify_entry}: named list of fields to be modified in or added to the registry, including the index field(s) (see details). For \code{grep_entries}: additional parameters passed to \code{\link[base]{grep}}. For \code{set_field}: additional parameters passed to the specified match function. For \code{get_entry}, \code{get_entries} and the indexing functions: key values for the entry (entries) to be looked up.} } \details{ \code{regobj} represents a registry object returned by \code{\link{registry}} whose elements can be processed using the following accessor functions: \code{get_field_names()} returns a character vector with all field names. \code{get_field()} returns the information for a specific field as a list with components named as described above. \code{get_fields()} returns a list with all field entries. \code{set_field()} is used to create new fields in the repository (the default value will be set in all entries). \code{get_entry_names()} returns a character vector with (the first alias of) all entries. \code{entry_exists()} is a predicate checking if an entry with the specified alias exists in the registry. \code{get_entry()} returns the first specified entry if at least one exists (and, by default, gives an error if it does not). \code{get_entries()} is used to query more than one entry matching the index (named argument list) exactly. \code{grep_entries()} returns those entries where the regular expression in \code{pattern} matches \emph{any} character field in an entry. By default, all values are returned. \code{delete_entry} removes an existing entry from the registry. \code{set_entry}, \code{delete_entry} and \code{modify_entry} require a named list of arguments used as field entries. At least the index fields are required. \code{set_entry} will check for all other mandatory fields. If specified in the field meta data, each field entry and the entry as a whole is checked for validity. Note that it is possible to specify a vector of values for an index field, treated as alternative keys for this entry. It is possible to \emph{restrict} permissions (for setting, getting, deleting and modifying entries) using \code{restrict_permissions}. Further, a user can \emph{seal} the current registry state (fields, entries) so that \emph{existing} structure and information becomes immutable. Additional fields and entries can be changed according to the permissions set. Permissions and sealing are useful for exported registry objects to control the users' capabilities of modifying/extending them. } \author{David Meyer \email{David.Meyer@R-project.org}} \seealso{\code{\link{dist}}, \link{matchfuns}} \examples{ regobj <- registry() regobj$set_field("X", type = TRUE) regobj$set_field("Y", type = "character") regobj$set_field("index", type = "character", is_key = TRUE, index_FUN = match_partial_ignorecase) regobj$set_field("index2", type = "integer", is_key = TRUE) regobj$set_entry(X = TRUE, Y = "bla", index = "test", index2 = 1L) regobj$set_entry(X = FALSE, Y = "foo", index = c("test", "bar"), index2 = 2L) regobj$get_entries("test") regobj[["test", 1]] regobj["test"] regobj[["test"]] } \keyword{data}% __ONLY ONE__ keyword per line registry/man/matchfuns.Rd0000755000175100001440000000342611146532506015205 0ustar hornikusers\name{matchfuns} \alias{matchfuns} \alias{match_ignorecase} \alias{match_exact} \alias{match_partial} \alias{match_partial_ignorecase} \alias{match_regexp} \title{Matching functions} \description{ Functions used for lookups of search keys. } \usage{ match_ignorecase(lookup, entry, \dots) match_exact(lookup, entry, \dots) match_partial(lookup, entry, \dots) match_partial_ignorecase(lookup, entry, \dots) match_regexp(lookup, entry, \dots) } \arguments{ \item{lookup}{Search value to look up (for some key field).} \item{entry}{Vector of key values where \code{lookup} is sought.} \item{\dots}{For \code{match_ignorecase} and \code{match_exact}: currently not used. For \code{match_partial} and \code{match_partial_ignorecase}: additional arguments passed to \code{\link[base]{pmatch}}. For \code{match_regexp}: additional arguments passed to \code{\link[base]{grep}}.} } \details{ These are matching functions to be specified for key fields, controlling how search values are looked up in the registry. } \author{David Meyer \email{David.Meyer@R-project.org}} \seealso{\code{\link{regobj}}} \examples{ ## use exact matching R <- registry(stop_if_missing = FALSE) R$set_field("Key", type = "character", is_key = TRUE, index_FUN = match_exact) R$set_field("Value", type = "numeric") R$set_entry("the key", 1) R[["the key"]] R[["the"]] ## use partial matching R <- registry() R$set_field("Key", type = "character", is_key = TRUE, index_FUN = match_partial) R$set_field("Value", type = "numeric") R$set_entry("the key", 1) R[["the"]] ## use regular expressions R <- registry() R$set_field("Key", type = "character", is_key = TRUE, index_FUN = match_regexp) R$set_field("Value", type = "numeric") R$set_entry("the key", 1) R$set_entry("key", 2) R[["k.*"]] R["k.*"] } \keyword{data}registry/man/registry.Rd0000755000175100001440000000341611144570374015067 0ustar hornikusers\name{registry} \alias{registry} \title{Registry creator} \description{ Function to create a registry object. } \usage{ registry(entry_class = NULL, registry_class = NULL, validity_FUN = NULL, stop_if_missing = FALSE) } \arguments{ \item{entry_class}{character string indicating a class the returned registry object will additionally inherit from (optional). Used for dispatching user-specified print and summary methods.} \item{registry_class}{character string indicating a class the registry entries will additionally inherit from (optional). Used for dispatching user-specified print and summary methods.} \item{validity_FUN}{a function accepting a new registry entry as argument for checking its validity and possibly aborting with an error message. The entry will be provided by the calling function as a list with named components (fields).} \item{stop_if_missing}{logical indicating whether the registry lookup functions should abort or just return \code{NULL} in case of no match.} } \details{ This is a generating function that will return a registry object whose components are accessor functions for the contained data. These are documented separately (\code{\link{regobj}}). } \author{David Meyer \email{David.Meyer@R-project.org}} \seealso{\code{\link{regobj}}} \examples{ R <- registry() R$set_field("X", type = TRUE) R$set_field("Y", type = "character") R$set_field("index", type = "character", is_key = TRUE, index_FUN = match_partial_ignorecase) R$set_field("index2", type = "integer", is_key = TRUE) R$set_entry(X = TRUE, Y = "bla", index = "test", index2 = 1L) R$set_entry(X = FALSE, Y = "foo", index = c("test", "bar"), index2 = 2L) R$get_entries("test") R[["test", 1]] R["test"] R[["test"]] } \keyword{data}