fontforge-extras-0.3/0000755000175000017500000000000011254624430014220 5ustar kestaskestasfontforge-extras-0.3/Encodings.ps.gz0000644000175000017500000002101711017461124017111 0ustar kestaskestasw>Encodings.ps]K{8]~EmfYi^KtRcY-C*JJdDZ ٗ \E~fz-mU}VbE/חiYtIdīz4aWEyV/:Z؄ex.eU?(}SWEIjry s)MlGŚcJ ׅȮ7|y&wW~_JhQ(>ϋ4&J\/| r dtd E.fl<^m4:ִ$om\k[|Հn@-]n*eM{]&lUE\R#u"Vҋq`F]bDm5Mo~3ߙT߹S^OV_l9=]οUw^G~Uwh!^sD9EgGKuY rݵo6]VZZZ475 кrGP+U]fIѷ@xaG64s;b*OL9~)+dz%YN,~x]oH7&7ʙR[7༓w.}X;vHHv9,ոL7_H&5FC1 RRrD\JTԸSk9eڔmɖ/4J[7܉}})5neiM@qG;L){콿ҧDŽc\`MEP-Has9q.y%﹗wWR#Y "^K"^##Zc~-7^x]rΗq~ >BcG%{ F'C+,2ɛH˛PXzR&EdRD!#Q^K{=]y#YvBWN2l4)]?Vd]}׶Joy /\Y N/D?7.CP$t^U`41M]e0FE2D1񳩫VemUU*FgeUVzH1e͔U"IR'O*mT>)}RnDj:)ttIu:m|qm] f H b+<6'w٧jb#̘o".q+nꪝ;Z&Mifq>-peThr=7r}K6鍗Q]^Mp4ol_~F:D km.\?u'6mp{ W%d$WIjȩ-#wliid i&Ҵ #HcQ$mY,]nw7i2lP9A۶w~|ٛ!apS|ak3ow@M//M25ulMqA+e;pj>ʼnԻ<2:u!G sjStgÜsz{s}sN-P XĤrUQ-KWmSv$yoMF854BE%}f .ΘzO>Fi^kt_lMv9ԟM~>ˡ)z0:gɫd]T#ƔaOP*:ܷ͘jLgh;+4g7Eaϐò1c I6>Q,צ2S;2Y';}c ~qDWIZ1X]Phe6G튡k?'5Ek}ze}s%.hn8id/nWߑ+c˷A &ѦMCl!M !9.x. U1`dc}l& qN;Ӫن#ԅԁyS2Z ɷŪ$1HŒyuft|GfDn"36D! Q}` Q{ďf;)* d'8r\x<(ȻxzNjiKjOӁ[V]kArXi-1Z2{<ȏ}p4x6p'sճw%BnQW^{aHߢPVZXK!\u~%5޻IԻ`2\rFH9A >r5F\nE*JDWVݨK_\nxBpfQ jc:(c9ug39Te]OF TDv=hTfd>S;@ݒ~maZm`KtGV _@xAV˸39:2 -@"u+< >,"Fvb-cAJ2?EW,VbU[:B2yM"nXWúհf]ڗnV1Uyh=]2/ c>-{u@::{P0{mg,Hѧ2TƀP]k@u !5$= uF!?TR#*D#wD;xߴ} kx_*ֶzٽ9|OVռ{ kc߂ݍ`dmHג-=z`zplTz!DRJXze "#7Lu]{$׶n;. Uw " '3xbpG-tx2kxˆp7!܏M_|KE>m,DʳI6ʇ(c6qҋQ+R;g9HSHgZp1/Wyދ'yrmnKgeDе"6oRn¿"eM{\, 'y#荐oBhSٱECYy|e&gڨ+\֜u&:@3a&v Q{yi"t\qn"'mYyvKB|j }cbzw&V[uea-(\baɷg ' ~&:*ljI % iMpM斘lʠMB g: ԲZU`;ĸUC$J$q4`lRH.4D>w$G{( ic4OזvݭwY;ɧ'tE{3|=|" vu'(zCÉ+{l%1YA#;.5r(R|!.A:N #\|!P3Z8-  P=k׻|8v !@LϷ٫h 'fgǧNK?OP'7ǐ fDœM K{Ml)˒`4J+nf//UfKzm}nJ4oy66~)*H~sN,JԙC2oN.oU),y<78Oһ>jTW_&]7w/SM./}E3 !ȳھ(sCp%.ʉq-cQWQz)aqŒ$pb840 >zI&O9{埠 ^k\lËմ-l@ I cB[^}'(=@!HǗJp82 dw |f};۩H1$}H)ke6h73H3[}Cɦč)s0>kE(1^FK3=&۾niLHe6 anM7B/@|]r_'%eM95/Stz$G0&ꅮig%fI0ۼ+iVE_b`_w>+9k'65_'hԍ;zvQ~cd3|I"5x_@) qŽO5 6/-dt\V +f*]&XqUt:ɒəh#Fyr^ܑy[CL]%~kɈۍKpܘh||# _~Q6BGG ittBG ittgj#`/RP&^ Fh((r3맱T;B!+.u~hMfThV.4 2IqhO}ܽ_ 5&"sɔb-_U<͔R>o{<#s+YA=" 2?&%BH=H}HHCH#HcHHSH3HsHg"uھӍJpvg8;pvg8tR38 38 38 38mFg8.pv ]gwrΰٴ@Ig!pg!pg}g}gh8{p=g8<gorg͖U'fuaV zubU[E,vw$ګTG| PHZN]~CO 5!ϐڱgUA :_ C0X5Huاs;]b=D. fhkiٌBJj(eHl+G0l7nءN.!=$HLTo@To@:7NH2A.A BC46 Z$b,N|`qZR|yg "H)rL(:=ҕY5GͳdZ$K$:(Ҩ(x! Q|Dtq<~=l|  ݹeg}(|nhC)G{t|}yK[~S03pN%go^D: KmsR'-xɖ\I?1f^rۚ0b!*(+Æϝ@j\ܣ~ ~N}G\W7!LV5H}yECt1bˇt{_iϵ.tC;xUawlw٧QBo_̌.}?Ez(C&^*kȝT4P..xwc6€5۰I+v/TՐY%):É{vvZ_yQmb*@S 奰غCQ30Lf>~pY&\Lߘy:R`0 V ssF#`9t&I5cD21n\R*J1F*6_McJiEvkad)inSЭ#1| oi2G98H/z囗HsZFU oWatXU8X{!lZވưº̍(oa*#:W -MJC s#^4v/0!t'BJ bWwH):]"Y=`c<3u0+gm[ќM/+j &j/hD(EphXhŖf}X90(a=;!>\&rĹ #6*> HS~E"1H6P.Ʀ[m`曩ہh100w|Rő @#X(6JBP'C9 EBqQZE®HDMqQ`-FөB:9F7Ȫ.8@;=a5{V e]tgiN{ lAW1z.Q\M2(1q& +$au8~;=?oH ؘ9{Oypk8I&i3yOR8g*5׫(M&uaR jԉI=,ΆI=,ΆI=,'ˤWԬM@ u!zFƐ&fD t#@G:t#@G:PY t c@:1t c@:1Nh@': Nt@': NtT:)Nt S@:)Nt S@g3 @g:t3 @g:t.@:9ts@:9ts@@ @~tgzgzgzgzgzggE*%z-t@:T&]35=rDlFSRg i)J^Zк.Ea8mbEIIi 7??|<>wX;qk[R,-fontforge-extras-0.3/cidmaps.tgz0000644000175000017500000114571211224612714016400 0ustar kestaskestasGԽ.Ifu亊}1z: W#`MC>V* 3 V(af><ӟ???Xߟu_ﯵr|N"=~GUy&_)I|r\I 3 jޚ?I=?u~ђh<ɒt$FV᠌jֳfG?X?AU>A}0љ+1s>YA⯬io̒kNY!r@$ſYL7MJ93r9 /G~Oq@L,_T!hM Js OY`?e}vQ(:/KΦr&%=/?*O_ˎ]WI~K.|;$$>s/Gted/2J͞RGVPjT̓_PYMRdV*|;qD9r_ΛoN̹%'{NP,/3˸5q%KտZ͜ko=߲_79P+{2g%Q٧$LC\Id;۲)m:+/no$fu$_+HY4JL\1M˺/k˺4O"i a\=w}WߕA[,ARA! =k/zOD.V?z"ȾI;u&uړp^IdOYdz/\2=L5Da^I0R^dr Fw%A}|e}f[(7cF mɢPO6e} %BOʑK)) =Q*uo*ub:<:99rf̉˹瑑#z0Ӯiחdݿ,vӠ@Э֚0֔ ư<[n-` J q J;&%9&%<;_|'Iɹ/BNvʙ8)5Ŗ1\ssAy 33r"ϗ~/98_R,JGН)^ȿR9M\ٕwvZksE%rI0%<`eϹ$<`3#^f^^\YUwdU݅'̥ܭ'dʙOʙOٝ3WTΊ=WTg\^DI"7Ι+*'L~+*lSsYFaJqvI)5K"K"K ?eWv3WԸ&gݖ+j\Ow$W`\U΍s>'=jڊ\UIH"jʖ$\UISq;t=tK}v+]_h) Δ%6]b-k\bKɯؿ 2]HLRӅri_ ɔOfNvi"))La-'yvdot1XH)%L=jJ3'/ZdbJQ" @s:z%^O2tu}fW%8]]oN?Pד+ KIP{&A_Is VW)?KY]},5 尺V΅`uյjZ);=Kf]Q`ݦm Kb& 򫒣5rEӀSmy Ϋ/*8;@" VV ׀RYY)& ,YYf rEsf^j,^odJ*\U,:57fEE\#reesUq&ׁT`䪚#Z䪚iΔ#W֜9/#WVNl|As]% vy|{jxDAuNw;Hʍ $pUٲ`a$ wUվ/g_Da\U$_UPǃ*rE5$@r{ %@`wVK {# q%ޒK})H%OŊ:D#Ŋ:R%[#ŊJ)=b5;[ӛIj¼XM%:Mv*ɂT'Jj]Բ+Ϫ$$ęD^P؂ZԋԨe߮jYjYjYjYj%,y@rE垑 `|I| Sp! n!(EN\Qt)Ò ӒzLgc E.0)e.rIysΌQܚ\s vvgI{c9ȏv,@|*J @~z A~}A~i_]i_c4-?[䇄 x b~6 @}A:^$֗4/(%qNFGYRpa'ű}{{C)R'բd*\]ƃu-d]8C35g(BJt]NEx,4mNzWk3OWRUyp^{[y#mଽ6pq~eVxò9r;\8uGc @~o=8{qWo=_`3#k{ow {x/4Scf?kqgԊӸp^.QGdzǏ\89Wp(@ 8-|.r@{ K/p,y j 07|18P Cu({@?JER.(xNRr 'Uʟr|\<|N)Q"GLX`WvͣRXة+gtLWiRr(RgiLҞ2Ȭ%sNW9]mteSNi7Őik8/2Jd"9dn1'sm+$gjdn vv AHH3dɃR*!qOf\CԴ!qH́=ٝzҟ {4$I~`A {qBDmHܫ.7p+ReYJĽjĽ!zm!q/D {={5$y+-=Vmj婋qpcEhWOsHŶjVk eR)c%ſژ$ib*WJ㩴3$~J۟ߦ4I4#a4#Naؽ~ Ͼ#EkiBRH»<-k~ҔO6KSڶJ7%+ms5mӦ}<86++m3ksABJڬ} @S|x"i)I6C9lHͧ0)=#}[>t z) `ojtuXwqV!\[`{H$<ՑsLBkE00IQ$HGAwz{ghχ=Y8;Ϩ){0hV z0ɉZ"})Epbω"$frb@1IS> X\ԇsid-H >h@x}2 dhΌ ⥖-.򝗬۱O Y~5}?iΚYQ=,bMh5}e,Ymy@ؗm/k~AY(Kά[y pyh8UyvBiq PY{MCjRjZ. EIn5h΁%K EXϲ "WE/)rM֠hO8Mu|F9)q 1ڸR5Ԋ& (WvR*鯁Eg@$?<6p(~ NǷ K-nXv@Q>B[:ڢ}/uE#`H!R:t֯-EjQNwwHQG=4Rk:H`آ2z¦%3z|ʃMx M|<.XA(E QJ~Ah H69i*%%4BkP^6>}bG:rmY91%Ermei oˁgZk@=?̨LS1Ծӷ.)49vPM͞Ծ_65 HȦN_MI'MM $Bn<@oEoL@P.oDYSf"7V'H 7(tyX2<%Ctȃ/3xa;<ޜWBf`+1B&v1Sm"O[L>95)Zh" !T1G^2Q-NEPTIJeг@k8e#R-ォ={zV<º'<QuJqCϾtl9z(Tu.QUzUVqU7g]dՃoAh{z=U/^U/* ׇ*0/3LWX}/DGSz$QV_ \jAVR(+>aV&8Ou#jTԍ(ܫG< 2v0W)+2@&5k++G IӤGd+Ko]^jL^> ~_ p!;Y.*LVo^ovJV"{e tBR/@q͇l>Zn%ECI @6z x+QGo'k֘__<~~ikL[|>9}@r>}/ɃyXZ0`3@J1@=;k:2`,Q2r]oPvFuj ^k`bYȃ%+`oڅ}/ꆆ}D~&ߡa?a?*Z-<Ѱ_ 6h 4l,YR6R 6,)xa/h7^{NNγ\nr"t@A]аwφWѩߡS;\xIY괾Ԝ$Y:NN6tpѩAd R~<"=YD{l"yyk"\:篝R~Pȝ$C .:(Pv\PVE|NM/$˶qW^l|VҎby`}$;&-RD'uԤ5Qd݋(2|E"+gЧK|O_uעȸ \Dufa:h"}^Geň$k-B>inG&kYd@>Q]">RhpΪK&7TfM*M6og=ԥ-k"Roh}:#ѣOgziٌ}pR>h\tI.(zB>]ѧTfIoV}C=5|G_-Gʎ ,uk HzʊKs*uN`ti/$Y^@qIO ?i$YzB3ۊWٟwť"|.XP_d|ܮ- :'@kQ_PӕY g8a7E!>m+էm֧iUNy2W^>Ǣԧo|A|<- [)[~\4)+ZЧ&jѧ+1!Dx}{rYBէJAPfYRhX> ˧]Fzaka6:g'P=ڨG[CF/Gw=z =z4JAѣ͓@eo*} F 0a}ѡÞBwt :/:t?05y:tX_tpeC}G{~C ;< tpС0Kn Q WC_qBo ①C_ŕmӐ%Њrރ.\-ˆ?JU&HU~RԡNEΊ&ㆂUD@QfgȊUzKF+8|FаՏ^,.YM?6':Xg[y^M?6X8䁆}V,=azi þc4Z|pY- fA,@îƤBVs( YR>Lx vEs`΂'Y {9qJ%a|+='|A0gv,%txp:5c;7,a@PQ@hD>(yPl:r} kRa/)}hM|,gyCe/v%fAAaMֳ[,?),?aM,9Y9K Xt20gU<#\XbC <liysϨiŚҥ,,ZEӢ 1Fv9K&T+PjسV xGZsAU`aAo z,?y\Nl7 z]0gII?] sI59ů?Nc͂;<:K nj?W)x k;K nS3}[YWsĴtw?#? Qoc:fƴйc9P :w9y XtLlΰpgvF} DFnowvMpg9vdpgGwψMb> v\Xu"=JpFN1UG5U6J=1}p=) س> =-eoA`j"u=Ko 'V&V&!Ĉ qur"NfQX\:Y/F:wyXacaT xu:2Fb!qyu!Q"dQpX!imyb8q{W8*aȄ[umVe},Ϻ5W7>+y?QWYW֟8ϼx;әddaEgܱ*=K6x3f.(y5pgC Y _1 qۛbƋv;듵k<x;g;Ĥp;/ghIa|!&}hS{65Цi>xhSlp365F4=>"ag{*jM k3gس%Ğ=bKg+MUB8; i=;i<4)icpg {Ze.8C{4{ Il84F#R1XCn 6.k-:^TB;|Ґ@B[Zpad;Hc Ka:6'g4<;V'ˆwQ6 696B ОӐoC{ZX\OO {SRAQ* i'{8X;2 X{HbOo%E]$P`W)*v#5K nUhڱDp-*@ءP5Kօ ,Ia몖 YBC U `&s XTCN(l]1G6c)"bU b@@3P%uA (Z bE V%b)~XAo:.K eȾLoV 2x\RpNKNL,*rxK!Yx9˒i%,:0gc(, tfl,WF|liWlD7r'hY>woC,)aOb,&ByO?aO Ph{Z~ia?aO <В=i>n= -JZGi'voPh'e'$ZJ]hc F:ܙ- т[Y(fqi7'8̒ -܎6gHAc6 sgFDǨWjƯ^Au"Th|R-oEMu`( NFYx5,<( E߮}d>ºosF_i{w*h9:78jd3tjd~<a0:7jt32Tv<tnnW#F8Itn4j~wv6/9RK[mæiWywXMWŦ`F8ûWŦK6eYťᝫ<'6K[ť!TqigjpU\(KXGF8Hb . zvdYv=a!xh`wpvCI{ܱ=F7#|Vai|f؎4ì b҈r^ŤI#F_f~#$]xбWhh<<`R/tÔH$<} `6UhI1x*xA m񣝬_YThIY<z61+xQgG$F}{m _`GE^@&B(=kDOId^JtQPG_ nU0iu8+; 5JaNLF6CF6F6_k~ad3O #y^l ay`͆{ w7Q@WF5H0GjEЯYeTH,KSh'{ 6#3/Я3,p_:>)x0~F;΂q6I%2bF,#F; hgk<(>~L=ǰŢE8Ģ] 祕Ԯ;Y,;Y>*4eUn*ȢU;ۨe}*e5C#Iv)ynk"GUqh=WšaC{M>ú~£0 l+J)@a?ѭmXi[n}pU-EKApG U1t\LE7uFn ݺ"}G MThA -X8+`ђ|lgx+X\ih縂Eo}`u_Ha`5E#~gv#IE#NFD*X{*A []>K/~-,[_xVߨ^h`:> -^X0XQ`:ڽŪ*X 1Tϰ1&*b ‚׍Žɠ[SujTbwdL- | ~j^mnt{M8~-z?;ؔjn`'3o;Kw69ŝ{33Tqg/}\Y` wM* Rwƭ*,8;@w΂^B;wv2ŝ;lNv:NYqg؀؅ŝ7@W\ gC98L{Q£L(('ʯ8&D#*onM l;d9=D&INw ݺ[;JY[jTؓ;M pqX9~o>cFh̳:a}9cÐtp1 i;zZ)6o6WfɒѫJ7oA`͒:Z Z/xX_Z K7 } aF.40#rr ; x,7,WiI`d5ӱA>Ktꓹ,NdfRbﳦ(y,FNGdnC vQnv:<{Q f.)`w}N ,̈ \ō< ,lf3cOOm63PYR>n,[V0gv9 pY:`DAsu9wX;l`9+ģ4þ,QXOK< miGam/(kxd%|GAZQ£ z(Zc3lyv)l/qt)l_-З"zs5B< l99[*ֹg`smRO-d"{sS{0)" Mq-(K< 6f 4VR;Olw>/_)1XEV ,u2Я5[ܼ`7f*X|ƸpH^يO<. igS\Ӌ YR!v lpfƚlig>g}&a1#=l$V5)x%br[ ռv&`fL=:1*8,eY'b] )(ΜasX&8ά_pfI"(:6q+8N ,)ꢏ Yr>Co[>-283{+HcSN3yXBaȶx%#Ƭs1` Ƭ3/@4(3Ǡ<(̕,)|{3fv> &; Y7a7Zz̋<Ƞ߾M̙]/5K};|c-&=0/{`^N(70fl#Y>vv3| YGl̒8Nά!3.z=L'.RӮ=g'B7&cݷt8cb_cs;,zBn7stvJa=EmR :v:v=-<}M>,u~ꌎOE tnK=l'5@GعGܔu3QA&ag_Ha4pf<.Z64 ?Mg67pfZa?['~nb?#c1$m~aV6/v>K;KM~B&Shwں IOk}|}:е/V;yN6Mw{gLL YR>xkK=Dk`&Iس|S]_g{67س9lhA̅,mg;Ϟvb?#"dw6%EXzJWֺxP(yӊw@ {3+;h&Z1Ziswz5_gggBa+Vw pgu+nԔWL{%يKbRN0pgA\,}.->ƺwk7zY>Oе{9سhgmCn`ςl YǷ-,ړSYꖾ]{W=KqD&!z{e`RWmn@5gA\VXQ+# = ,@6gIQسgd<36VԷ9uvP{mO}^ԷYE}U ,Wtz~g{-(; /nSԹй;:kl=wmg6{6з=%Ͷ龎mSlfl?KSBFhъ=t߭oӋ\e۴F} %P¬0hK9 j-e:0h P3fٿͶ m ml`f,HZf$+o3fam aldnf$go3ۦY-ѵ;}-){yRT~ɻVջЇ-l ښ]{.t퉮SѵE<lq?[ sԹ6,)JE^ϖRamRѵOBVOmK}5̲:k;[G;[_;3lZc|QWcͰ ʤaƧ̮y2DIʾ1&45̧If>|$jiևF:]]9욃=욣iЮ ̮9І̮9!-u4k43k3Z̚NkfTF1f8Ьi̚-f <3klfּs6RO Ԟ7RH5Rk^ͬɽ}jȆf|V̪ILfV͗¬ vY5_dfS3k {xC~̬rYk̚j^(O2x(Qs pe664Pf/Be(Nl#|e=ڋ Pe¬E (ﰁ2KghLRb{2_L@.5y`(Al鵁2g@nkF] J5lvŦ$԰ՠrsYANFV|#"s6#0ܭl FijA>l2x(B0Y|ok:l9eq3B7&1šY6A 7l^ fټe"53l蓮ac1lCͰa]07hdskf$r3&6?Nb3l~f?̰IfMr(73l*Uw5kֲY6̲!e}:zt6dn͒PhBgŭFfq6"ӺYطYU#f+ԥf7Ekfs\Rj|{)^#uR^[sj4gIџMmѪtd;Zupv=Xazz(ijF)r8Q&lzO`͂ Yjr@^hye͒ ҋyg= ݖƬkDh`ѥOtKf각7 P YIlWz ]o{]x.}byoyKSc>C?dMc~Ph`R}_(=º lj`օ4l=zc?G?`{ /g4-faoi 1l^̓uf^Mn`7jj4ɼ=>¼Z6̫If^l^́b^Mr5j!fg^MbR4jWHgͼȡ~Ѱo6!6[y5̫ݼ1 1Ϋ9픽y5/뇆}9{|aB 7;\ H=~8ZHroF>f|fC?Qovݹ$ެ3xmH^n|36㛵DzІ8oFf|3265jd|37kRӠ^(bM!{ E39|͸cҌo6k`!6ruBuKA#b&쾇օf'f N{㛝ؼov5Y;3_69՚qȐՖ~P`0fk_ YPK/4#f3c5Y ޛow~e/o3#E3 @`.Yb<3r.7)y,5ggD3B1*~xf&i6+r>K㙝"_إgvgv2;1NKxf%㙝QlA3;9gvb37ىxf7{n{ |3n<3" 4㙽H3#C3pc㙽3o<33`<337TF3q,3Mze{8E|gY#}Nl}3g9ZSZ^C,΍nLT"rr8wӺ1FP2x87E%#:C-dk \;^|/Eˑ8⃾B_ EY7;nq 8x32#vfž"7k(cqdqbvfBddqlR]Ys6!7gxsA5#ZkF.l<~:RnXɿŚ"_:/űtf XsPȰkB!2b@wfW~U?e.֌}c)KZxpWoYj]G=ęo3_iƙogZ*7Όqf/ugF3U:8-)kCdl%e)ȯƙWGMř1̈QřF)XWIřM?uqf eXz ,7ř3>OaudyVwvrqfENǯ(9E7<+t]J ߎXbno drb0ufLNf.֌S]X3,]1X3$.֌x]|&z Y7{ xTB."9>ZN,,]8a9E,6z+^~ ,%Bnf%@cohyXgq>q*:]VbΈŜ_9#csF. ,dsFĊ.Xo]뻘3bHv1gO3Sv1g#l CFȻ]]Ѹ{Sn(^xAʮ,eNa^lQQtj)F'rM Y<3&97'(29;(&Q.)D^e6AįXgHO, ͆Hg4 i;?im)ݍpFl|gK|Ӛ\(gĐN*IeNꃽL3fti>='δy+w-gRuI=9Y3rwMSl'4nM"l%aM,df${l7捎aULnm,'3+ o;Num`1{mh32Xdu3l~ψ0g_s:WNgu#amHs?D4Y_pr>?(N_99/qrr5O_`#l"l.jF~nT3ut ũJ2ZQ.c3b,jFnTסtj3*V,F5{<8AuqӪ7dT%EhةTA1þCH"`;XEl55ßRAVf(XE,<`͒ͮr2̗9/k|qrs2\5Co/ެl{ƛn{H͸ś͈mͰŚTf7X9+LXhZĚ&U3{V"q33×ř_>pfAPR3+cr D8 73hSW||[$VqW<8bXќ:8pfIQs)b̂ IMj 2 ,&Km#*`-c|nx︋1{xxFgs ;oxt)j`D6ݽ>ln"::izؿ58[d Β (df"zmkA-bwfQ># ,e;A3~=<(om5sv {[,f-3"n^mA-hf deZ׆pF"'pqwgk"ul]p\)ȝ7Z5|"0.EX 7t3ju3j?Qsa+}oFMV5fhfԼ؛ͨpLIg~F8ψtPY+"9Z`OgYR$'RzRp  l.gs9Kȳof<lo`-9kYJpgmKh)c-eCی; Ѩkg:,&BuܟΒ5X:R5.ac4AyY;To(?,@Iug,]PXM~>eȺuDz'-TYR &#`~: 1D:#ruF.l2cDoF!luvO.'L3?Qg]D7K)}!/cOeqPg$/x@%EXۋuoGQ|BW#0R_tkru3j3v53j-fԼ|nF.ntr7чnnZ Y7 sft7(y(H x7A3jevby 3;4;4;4;ƹM>=9/6:)pϛFCrRy˯ἥ8(svST[Pgj.qrtPgYRy9G>q~so͹= Y; Ag, Z"Uu:N4l;:[7,)C7{h3c63dfV N Pgjn(Yg/Y~^ׁ%YJf<8ˆ)XX,>0Vfl$|Ȥ"δA8X #s_QL$F[lBᷞG@)ͪInVMSwj"LQ(gH ;6 J ~Yo3Wwr`3"fx(ga"D8Bm!ԯC "piY~}n-c~}A-rufLR_m%c?% ΒbNcx@^F&`q+ټٯp }{YRp{ݑ@@+:7!]_:u{_Qg3r!Y ςۧYև~Y3ܼqv#gmkjP pFnŚy֍nFnt3Kﵑԥlvf0ٽP 9fv/8, HD6v!b[㚾Ǘy6?Ng*]Yy&"FѬȳ1yv-!0"ψ+E81B#賈<[-kct16v]ZF7S4ٽu q))ֲ͔(l!쳮޶f_u_rRmiPgIѷ>xuvӬbɃ5l63Gd8(5ͽ, _4k: }#ZRE..t䴛eyMqN٨3pUH]Yc'qh<3QuΞ||mF6,HFt.p>_Lfs3g_H\uZn+.#cF6_7@7z8KꆪF @>|8f"Rfc (RX|q/Cxx<=rxzݬ6 # e6- __' ו=v@?q>'׶稠_Z_{S2Hhf}]9 ^.JA0~F>Od~}Τ\;x/vX|%vX|Kn\R/)ZQ^gh[^ yH'aͲ`W('}E|jW}E|,_7W6q  [5j8CkIs1[ͤ_3iE Ԑ|vA1R2;fZlĜf$s0o6Mda6ے歙4y7BK=) Ǽ5#p_}ll`φ4%5̦ݔ͏.nob#CͰCrx [8~wM\,'= 7]YNk8D6f$0&Y5#j=%_wٷEϾt%gs$Xc ؓPǶÇHr _Ƭi6FwЯ0@QtH(C&{ A1,g؅"QkE }!Z|⋚rnVH {6B(v溶׶numw`m׶k;18GEFo,xt?h傇/yuYrmp jf9<wG4P\dRݷT̸2 P*&sec*oPf* T,Q#uc^2 %c]7 \(kRQ~}MiЯ=@arbc2l0-'*)w8AHb;oQg^^-~=mr g뤦ݗrv Pfc95g.=6xϳ;hgwJ8=@%E81@%E_'eֹiĦE@)8V,)2)HqOIPf3Y'eu)=TC 6o!Q4[ 5Hy4 H-&QiҬ  } l]c4( [Ve2HS &AqVp9KRAgӡ,,G`Ά$3: ~`Y4ANlc9U6*sԄ<s67 9lRg'YaE ofqk9G`͙l8 g>> E=9X9s9ܾ9ŝ);^2ĝ݌Q6~~ƍav¾jvrQ+7gs~]\jMiZIgWV5+\Yg;Kswl旸3P"cgD4O~=gͬmgY''湽vl87̬0&Ň557&RZbwmUs #-aUGᵤ;V#-4‚mسQ g=b❥G]Flg6QNԦ VREπOA=Y@ /(y܃π{AɃwyP>!|+gd^,3{?|üϒ[b g4,ˇ'5Q DYBaYke; N,9yM_C|yl?X 3 >3z]mڗ tPS*FԿ),ԃ'ONjp5=@ PgVsR9']7@%*zg9?jIâBA "<(x0Aaϐ;4l gC(gC}Y] A{Ovqв3kEcth=dZaE&F=hZҟpآGbmT7o<"@gԊ(w99>)>5G}oO"rlYvBdTb;>(. mcBK E66@ nPhxӕ4NTa͉cM" slcs!Ś_cs5k^k7c_F2:55̯yR,:HaM׼96o,\t1&aMrCsl$0^mMr1 slȤؼѷ̱y3c~<8y6ݧ̳yJ\i@3 $ZJyyAW⧦Z *4GCwED?DU&hHȀDk ^>=5DuN:-Qh# ۳{ /E ђ;H)m~| mD-B@FhIx'2y6W]xëБ̳yVGJ}Z^{h:3mFFq6FˊF#F!`CVN)4[ yA!PhHА!Y2h4PLC4'hPB_ iLh UaF hY?h/.:2p=$IhA-X ~Hz-5[!oh/nkƻMa »Ma g1~ @#J04@s46ߢ!YvM5hH[hm!!Fk@%<.u<@m q~ jh{eQF:QXhܧ@x@Lf]Λ3 9Ή<u9@UhY ܐΛsސs ɼ9aɼ9̛kɼ9?S*9h`-ZkM8sc%]H(0V*H9+DD& ѺHNܩ-e_D$E,:,sa.z+߅G!߅3Ek@3)"c։~2DpF[윢ш&=DrhmT4tkEpFh7Qhhr,š~Zmr$hbgA3h]4ZRù-Q4MhhrVkh-ʃ`Zʙá1#rtRKDmx]B8Bh/awޱɑ=9j~9{YmnhG m콡m<^/C]:6@3 phАHd~1ȧ1ġC$>qhd= gCRQ &2[qi] ZRC۸xY‚6,mHK8-* F ZRJ?(v 0hE3LP'qphPhF;18ͨ884n(h~оE!jC}CCCϨ Ҹ'Xz6X᩹z|ZD+ƴRph 60lο?So϶Wg?Rh^RK6'ҟͮg;^hۓ Z~K]жmhԪKl81.", 75Z|f^RMs];J`- ea$3"Fl1Xb&ز_[ JwJEc>Cr- rOe+1`WCc1巴[ % _*zPlYJ[T}ͿPuȗHGD:B`Rzd"/- d ,V񨕚r]lY``˲z{ghf5_H[|Y 5Mpc~򠟇_UF ŽɷC |5b̈0ŘqKi1p zͻߚ]Gf׳'Ws_vfpWُ3꯾jCyڳ33uW PXJG^/ Yz+JН'B\㦸24) |+#W6/K l"+#WF)l+C;ЁeSRĕq~+>4cSv<9V\La;G|d`>jڠ>)Ku>j{UuYE{Z.>j1Gȁ+HWɭ2%P1cP1%uCMEʒd4)S\qU,PD3!([i-'<ŖǢz gw<,Nlز;{̦2rYOqeDjnğ3B&4@LUGO HM4#4Y~1*11A?WN eߠhWˀAqۚ?w zI!U=UO52USwv 릧z;Ϫlpz+KНI\W6K MpeԄGFwNpe3\98u e pe)Ḅ<aɃ_ѝ\&X(yP31RmEwBНSޙ|Q+peI=Pxi[KM^ȱQ16dQpe \ WT&uMRS?peAhLxߡO?k$LxX5s<5gM?h>xS _)m͇<Ħ|l|i͇jǾc]?Vm 3<У̣G uͽi͇=<[AXϤ}E)XȃXh5`˒[z K-NhBeI /C)ߌٌD#l(J w["-(ChI {"DG. gz: Nl(j> ʦ:l(〃º`KW'e]AD٬ Wj.][,;tǖ4i$3L#m ^Kú2i$3{k #*>33Ov"3f)+D2c才Č#ilp43f^C 9׌dpf$4c&q3=͘y9vľg̛یb=~1;/ӌ܈f̼mA6cd=?ίX #cXؿ'8X?ֳVepdIQc;¬gi<@ ҍ@ۍ@sh|CeUcRv`~X͔ ͡\kMLsh*7C-V3%chJX͔\ͣIiMn9OhruG6)x ]GϘG2ͣYuTN6&7fy4,E(yrfky4-j>`MdhVl4fe}G2̣oMxhb)b5c.M7S {X/{iV4VidOs OsOsͧI.i>M2Li]sOs,Zn#<$4&44Z2ͧ9н̧I֒i>́eh6fK3oO"4cD,MQ"r8 4Y ',hhlF4;K&NJD3L#qg 4iD3Uqd8O8"7]GD.qd/҆82EOqḍ(Qhȸ6ͣcGFF)L;4H*T*#5ӈfڣhڈf?@F4!L~+F4S3~F4;:`m͌rhfĒF3#4[d p,{#E$)Y YJ6.lD3Pӈf{X-YiF4"hˆf $~MhƒV1lJ?fyǜ7ǜ7~ Kԟ%v6Ŏ/Y~uf)vSXX̺vc 1fGZ;ֱZ.Wx 37hb5kɃj%aCb1,( C o s{cXC:2s1d1dHqCI3kc>)x`!2!K1dJ H) Cbc!m1dDb&2=b7L1dz ŐCHb{<<>%3Z`2ּ2"O1ddbȈ5ŐbNV2N1dDDbNf[X֙2"L1d's^ Cvj77QA CFnI|Ȱ:ő|Ȉ[7őel##CGF)dGFlIN^ItAOd&Qe'Ӟd_gg=*#UF)'LXT c+'*1EU֕uAu#TYJ+m*Kg+'fdPe])TY'U֕A3j:?9Y|&U։1;A%E5AߔQl?g k +s*K K2ƂM)[ST7Qeb:DЄц2-,"(QiuUNTQeD*o,L/:2m-~ʮ(,*STb2":MQe둨zIaEU)[ST) " &".ȲYVO߃g2OeU-Sd){SdYeYVGe9"D,D%ge䊙":{Ȳnbq"Oe/SdҌ2΍,CY/X~2\˸2eaQeaeST@.%YRE D)K,S YeKȲX ] 92%regi!G6]l.L[tYDkOtYq-Psj=+~ZSe2P-52IM __ e?e5ZojeZ{x'-U~ E]~A~BGhwՎ-ǮvM Q~-:h!6jk)lsm65!6ræ:ěaf5|\F1Ԛ=M્æ֬Im䎔6rSulj~F-yPlj} [ߗljM-(mٖrA9wJt|Ž\F T?"Ј"вcc'.̿Q-ȧ 6vTcWj sJ ! s;vr~- ;vJa>MccwZa><,c'σ"NQsiy.6fF\DiOjP6ry4O{9YPmQlI7@%A@sB{حs#m'E/hg_*OC۸sB۸m66 ,™m<3FxPd5@y]K'5yDM Y2@|u> Pggާa{o|RPg_YYz@ (2=/xΒP ΂eaMEtWI8[Wq;_jmP?K5LOwS_(3QY/Ռ{6qÅ{y@&Ž<Ԑ{ՇW}|ԕ{@!a{N5<;"ٟԕ}LA}5cb=fxlq[=d%9kdT6[p fL`6#y;v5^cq։ H1]ꬃd#[u^S ԰ {W/U+HIOf6bg@=;/'6uF/(xP?Pg큂}ꬓE:@<Pg% 5 3fH͚hf$ۀ"s-2&:̔ƍf.ڶ x { dH,*u6;.]3;n/vqbQI¨fèf W¨f`èfJF5;9Oj]8 0iC8geL8gR+^3999c1ǍsV?ka339HZ9q{;8gdK q2s0sZ1sVHB99g猻aHg 猛ab3a3a3|a>Im c3lׯϰ#kla3Y m,qH{8#b,!Ǘr~kwv Ay"e;mq8g 8g\6YَX <,X9 ֆqk8g8gd8gqvSc3gRXPbZ ~-aAO6)|7gZqvq b5`gZ1Έ38 qvV4]߬6roh -uM,kX/;?X_c`=ON=Y 3lCf$Nnam"j͚~>cM`_, {EZQs^ h<me% n"XnC ` ubbʃLy/9fY<<)~e] = 21A6ȣ{x۔e\PljZkv`40a?a?l?ָfZMWѸB a7=?M-ifiR`SE:C@36(w) }V1X4IACnѸ0VP@Fƥ,(x mr8M1͒>k}<&K'P)N3bO3b׌9LWM&+$PYlXrnI[0i)0@`f郦Za''QIK:c''/uIKR:3K!>; 4Ia'LU ahaMÇ6g;|!HGav58h0f6p.aXwڣуES,ZRm fA,3,P4B=yZ )x4P*3mr'3%O6rxyGゝt XחźrGK_Y%x(u}٫k2 xIN51<ڼ_?}<~:  s: |F !3@1PgL.(B":<^uYR|+屢=,;EoodWsqW=a^M\FE2qS_Vɞ,n RRsrhCTo< h4>cm f άmp,J ͂,n{}{mb&H+kaNMn95Kam?x@DXۢr@fIBֶ#f!Ym@%ES %OyPqSn-_*ͩ~f-s_π6 r%,,;Og]/@* f üĨj[$̫) li3"Ҏlim_gl"BPxZ~?(yL(x:<*xsRZ ނ,(- RMrq۵@3J&H9u ~u'ǫXS<^[c{IMQJ5U mU~~ ÒQx ]XΒj;3Ax'^#>@Zx@|~^? c4'&|g4ZM=RYz8[Ķ_ y9|O<_@-9 ٺ_믓ZInD~/&E rX:5"fW~z.ᑲ]zl^i^oz]>MzWuQ2X}@u{8` /7A_o<>Stӫy7Avz=^7zh/{› /ezhxQ_0x4;h>Mm-i)^/.ibO3`(-gyFR(<+NX[,'<9g=fνBc:̻Y mTۏB/  F@ jBY^hmC a '"<6A(49C<&JFh(xt)x8rqjBd^Ś7e/W_$kYޢY95/$.e>oX/4̧ue]|W>DTY$2{srK[g\|̥"Ks^K˘g/g1ψ yrJ=)uC'jʺymeUe -zƺ&2{R" EԴڎJW̺&~FP(X±-h+1,co>i|j1<V4ְ4Յ̧y4߃G=x0̧y0ͧy WoS˜95V95-_34%ʐ}jjE%sFQ0O= >j 34|qC{D˿yx70H4:AᕰT.,Ph፽z7@o8a f_g)xV>qHk8سe쳅f m9}B' <dZY2<Ph=³.Ҽ (=+Cgd:b%BW<+@N"{y ԼB7ot8y yӼ߼ ،D6%u'%[ h[ ټ.׼>Y4ZR7V}3Zߌ4%v%7%-Zc$v|gs Jwy[c<˿!48ȳI|l=s<#w25ƚ4@%E]4|+#]F@⽹, ڋ"`0ǂuMte4b-#=7AWqXۏm$GψI!EFLrDęb^VȰdk}ko  42hew6AoAmq iѽ ¾ѽ ҽ xuovoptoL)nRr6ZY6cӽ BͻA@@7Rڽ nֽ nܽ ïڽ .ȅ,@EC6q*y4mv@E ¨8[ bog,A%)x?8n V3`P~<:V,gl<8@\<8A2&3Pݰ{9,Ԉ@UV_*Za)A&h>vrS-g٧|qRw}`H:΀BɃa'o讠΂, Yxf: 0 V(xt cbB~NDPg*z: 2,Pg1A>) ,[ȃ y0B"V>Â:үC6goy(WF>Xa0Cq.h3IM9h0Bs@a¶:K~{'Y l 0S@n (D?[J\0@ga'm ?K<,Qr?Vq"m!@-bH-fK (yПWx+6vcf <Y}lgS&'=EȅF@-Afo 2ψ~6n , kFvee9-+|/k|Fe3-Pf deԂw?W_f\X̞Ine3ϓﺺTDKww=L/&(N#gTv3|;;K/F>cߑMx8kG?c-7ˎ~f[g9 ֎|f͍|.#{ l2YF>hfF?#_>5~FӶ~6y~6W~6~~y!گϋkG?syqct,gĐYF?2Yp,8q~Fe3",e,8~Vip2YpJgyF? t L=g;Zψ/~vr|?G ?sg#9j35:3F?;F?;ߓ|y,4ى|il3b.][]ϋg—CLMgNF?S3Fg{|g~1ַvP#F>7|q.GmX`mh 63E͏mhY6F6JCg46qFsi<1|cn2fAK1si{siMgA6f6q)simKS0̣l.5h6dMh6{0hR9i.e_Bk6ꙺQϚsB'QSw4g3Yn3".# _g2|c3/#oO0|lY7?F>[X|Ii `uIa4fF>[;#-F>[| muI8}G ֒#-F>[K c3n/#[F>[(F>[`|auJ߇9/#]j#]̦%^Xg<4/:>!gXgξ_dx&uam0ًmXg]:du5c;%P>H}ղ(38g/q>|9#2@l3WgsF>e 8gD㜁W[9SG1ه^`3S㜩L,ޖ鰌utr v~%1@$Hx%6˒r$n@YJ8/$!q%dHAoK[Bnȏ%7 侕d EL x]&uLl+ +饐??2}k!S Őa2> g?</~Ӫx5d"I]!n眒x*M⪸-̛&gYqV܇$'Oz$ܶ㹭/sBkvf vcp:}.w<%w<ծrOq{6w|merߥL8$CV^Nq6kMywvKc\&awԍ$bж_3nv0kc~z@/.Ӂ\m۪k߳C$ܮ.'f=; ~[-3mm~nUzgpC=msyq,ƲWضԶVl.?1vX a۬Yq#W22[a0k, ,vyl2xspx$nȆsCqH­rrI­Ip+ af\݈).)`m7m֐=npyXf l|7nCy76!| \#x 8caٯUNry HFz[.OC-ޖб]{zo)W)HcJ|};1vW=v:x`طYoܷɟU2ϸ|k7BBrDo\Q$.OOx9fΐ=Dw|?N~ޱEVSbc(.{2S`+<@p)zs}:ރ]-@8 X=V.s_.WnԬFۏIʭJURu%&V$ᦘW&)«CQ((PUxdVx"V/8i<5ijib?m] "W\0F+e?B4.[_.݊iհK^G<`%zcmߠrS- <g)GCƸǶ'BťVg嶸ot4r_n 0%#-YC̭j7=v]a]o& 5 5nF;= 7w˭/m\wV`sWpkb{T2{掺@}psΎ7mw9N 7o 8w\3̛7"kE4F b OH΍K顊cܹ\scQm7bg2 \Vvap$>{A&ٶA0$ D"F 3CmXt[5]|!'"|M7CҶbJp@Iw9 Jw:JwV Kw~K8h?㲸\6F< MG>HB.w'=k?ũx< Pįk}u3.Rm0u۸q/ս:xUK U]^5'㦟!l:,Lo+rg|L5nt3_'FC8v1{n- 8<cw cL{|a?T}M(Mp>dQt` Ƕ'& &=,XFj:±u2IڿGb$mY`%m)@F-[o[82=@ciɪ?.}R\1٣txp2̧thf/ أ!] )pSHlW{b7=l r.r2 hƹ[.}-%n#-UuN6-r+7ICa}~f,,ޝx6IO zwj34x'HY#§ڄ|oSIwB­;En6^/ۚ1x[!1NE]awrr]:g cv5ye8o׬iq| hFK~j5(`TϕbXOqfG>>?C}.\c}sp0w pS`7@7 nGn+G>%o Iړ#{o4,S7Zާ@ixyfD}ߍ2s7fާhмĨyDm;#{Y]i]k^׽#ufv=M9X0<&w=Vz(Sx[W&x=wlSI^<4<[1kU2kuO;#x|D#c_\ qQ.K!&n9 5Zr~1Ɇ- G`܇F]K`I- Ѝz |#^%uL8&]W,8qlATOm-Fӡ9 c>g09@I{X<֑tMee  31ɭkMOOI bzBTe 'R IWF/]l a,(,-9 nϼ 4ʒ0ŒX}ͩ-O,)76+l=iz\-[滾 `Òm?Uޞz[\JSom0x$n${]X1;ڟ1f9ɤ=_XPR KkT"U HX=@`PgĞޔӻ{i 1wpSޗ3O3W&Ln)ܔ䦷&T&T⦞ݩe8셨Ehi^Ӳ=-J\;63DY EtQG(5!;R^PU oO1?\fJZxf&Y%HY<3ޣ /R(7)1W) .oDl7|j0N6c xzF%|ĆqzV'hSâBrqC_҆wb3IK`øx?rcø cø]Fn#H__* dF|ݼ 'O= 8=(e^+Qu1gD (F|k{ܸW,>묍a( ˳d&&Off_)mIڍ7qꀔ6mkHi;\@J5=-pV}ŵr4kUJVEzuT{kEtuv]+Z.ekhn5Gk:_Vhkx&l͉µrx-]EGk)ؒŭrx'{8q}*OEy ?8p@Jˡ>{T. Wĥrm֩K`ץr9TxOeܰ.ˑRåOqr\6K%./ؚ]ץrD "R9]*p.XT<8w]*1TbR9Hks)BTܻ0A,01%bԒTthuL'^ =`^/`:M:X"цBڇR^X}dB^wNù¹[;E/>@HW~\J"gsEi%sFù䄊.\.\y+1~+wTs%Ưs%卤sE;\q3#gU5Ε[\9ZTFk1%8W;~FEԋsE*,Xv8;(V!lv lh'WIYx6犳B|kyځv-?;N'[gڒrVhځvq;Ѯi>5yG&h'"h]"6*oxK| 3o*g2H]M:{ux?go\[=M<{:FU)&w-Zi1'x"^@mu4DžAb߳b_1VE( -ZWIW"Ϣ> NxQRY/Z"uǦ%A*e=(J?EGUjzP)%;7آ2[A5x`"OSCvtā v@{d(Y(*BwzR) zRkLOʰ^=) DYOʰ+2EN^em(uY/WC֋5.!S% )=, Nk-A~A~G bCl7+g3{fS'{eTCT+}Ӓ?Q/7K ͹g7Z4A(8*>`D㍅ uAG?[c[cĭ7^@ dj̊^5f%zo̊N5fEE5f%>1+]Y,PYQiii6OwqQyF >tEnB/lb pU1;IEWqh%6PuW ( ]"QnEۮˡ}93_ޟ  wwww)ws0$bv0M\<,j7s vT11)l6檎m:w04xcOeC|(63?M|h;1?hóz0#^5w/КDS5j>M||gP7_e%ofs@MtÚblagExe"fXEf'LDV(74*U6)9v%i{j? #SX09v{ԋ#l9vѣYX5rO49u:ʌ:Kk=ZbB1t/-FD?Tf.Z=}܅V%METrn@E݌dJ5s&uɬoܽ]M!ey_ܙ/+]ې ]Ml8nv'3HFfxZMe7Cz^&|>Pf|x;^Lf5-t5Wi |*]EA5^]~>a (ڒ*:m"ڟa]S0 SB%h[^<f3t&~b6[hM $3+t蘦~4)ɶA񪏚ؔІ6e79tlfH+LtW&_.+^ChTChܚDؚ9R)plQ&LN jD׉0zĻمV@DۅV a;Q Up^FןQ#wQK1v nֻZآn#jxJkѢFÝ,j(ҚM85bq9ZgkkE[{-jދ0y."G9ڵZrEvq(g&hMѮ&r9]}"G9ڽ]DvW9Ǻ8Ev*]Ѯ*r{]CT9:= DN 30i15ɥp5bV#ztx*؆b{[H]@=qDE)~HaԻsW詞afjwѣOmvC驁ԧVS&>w:@89/=&.vdKybsR7Uu U}ǻ#rU?MWh7_#q:gSVĜկh &thM{&59U vLʾP\w^ҹR2,\ww'wvMlKw%eqv9*츋츳Vqx9Y,(HH3?bmP\2#A@d 7uΎ 7Q- 6m1I)(bMmuv[Az!Z=zx{0HGIq 9n 8{^"cjMaΜ kD nH󉑣nNA$x ȯ{WݜpI9bۀ@~AnA}Z Ԩ!PIԨ$j`$jTwe5j`V5j`TfQq3I(٢)b:푄uN1ieSbq%ޱGdv399a% Hur% Hu& HO7gvsş5t#y H%K]K9j594& ;ǙjkNR5Tu-T5t[q)HBz)HBz)HBzÐ$ YvRzHBFx Fq͞a0(& ]/86lg>׵8nkۚ07kFQ4Jgh#CWbuT2:Ooc 멃!O6 Kyhhͫ=U 6:o7`h C؆94tt="qzю=Cx:.ikCV:hښ sh"`NuGp @$hC]v4N iGMѦP]r4|)GTLRjKR;! qIKX228F]Pr>*rٔ.يl%=ޅ=^I6Y}x&P/t'KiQ-0) ]ؚzlx~1*GcP2c5 f*P-ǨIQNewlDw̮ggU^W3o R*qUŊC-bŁarmSl=dۣ"b=dS2KyCǘyS|(bVB1ODr'3KLU.v2Wyyl(%V #by%ӕ7K+vmɬSϴsQ3&ƌOT۟j~+3>Ќ]°8ti2~y]i 5S4T%Lz)ѥ4JDWqXDgtS]nO Z6R Ţa* ~ @ti.IFNߎRӚ'-5O&6Of6"SWͫͫUqo.,Fw J7(uf JfzG9j\9ze%TU\h]o6ia^Lx>0UtNyhF5EJ<Lz>'z5k|{>&>-/Ӟ/:3>V7F5T06g,(t aϪg p=͂~*NdtÒC2qT&sv&C?̆~ƈqÆqņņqiМw|w|:($ӢK̋.A21mf0W=s?ؒr&!`zG hpJ&HW6!umw7]^dt__ sw..E; }տoW;UĦ5z$Y>VҦUkmX(b E}n^}Z>Ǟcuc7}TMZKkMW}*]}[E/5V<$bTlEʯFb~(tv:@SHjVx3LU dA/ 8()AIjx -Ҡ@WA nIS5^Aէ)Տi@;T]dVuiKL~Y]dju SG]/xS˵̱~#,Ǣi-j@٢KͰduuyO%KP?N~Z?c~ԛL.D/mqzwotpd=`uc9׍W[Wh~'3l6lѢ}lړ\ Z#ib Bw\B존졗2$О=QzNjMٓ@zvS$K JqBDQչ:hE{ܠYhԟ Q(6mt~TZbPݕ#x, =:^Tg~[yhkEƶS]E\C:&qn4d)N:J3ќݝ!sodWEr-3,8vl9AY)s5|յ'3\"9*3<"9K"9eK"9ov7HCHU$c7|՛I$X!35"9)_)b9<㋠iF$@$F"Q᫱@6./? O$,I$ǵ i KiJ$ӜUI$筙P${HNsV%U;)]ryϨ( c4CV)riR$7hNhNS]%ќ%N9o%ќ&ќLs(ш4=p"#x} HGA$|I$|I$\$sm"¹!Yi$3N^ќ/h[М/VAsVS5fМa]Ed ʛ!%~Bk7\"<$gXAr.Aw3iZX 9 &kkծ)DآH6| 2F%2FΑZ$or"Z%7 fQB}gS_jAf]c%3|$,/lzg8e yŁf˫dbAq.N"jvE0!_ɹQ/Rnב5LArӼdD!k k!k< kdhmwi-9bd/h݌/1bh݌ʴn&')G3#ŻQ$pL9&p63-?3ǻQ93$PuhI` Mc3!i t̠:~ s3VϠ::o-_G~ (Q=@~No[RVęQVֈ)VV EY# J6KY#5 bޕ5Jߥ˻wy:2:ۜAwN;gНإKDeJր!n9͠;W>J"@s2^fНS^ sٓ;tD3:3iD*"dSv sAv"L?Ֆ;.,)1"3yŌ#w\H/AuNqT*:d sJAu]A0}9w9+妼+2G ;ܔF=AvL5_@/VQ@u?Uw]`8tqŻd)7NyCYչ.cf6e{ռ|{ǓT4KAչh{kˎy5a: hybĤzm|;d1f4PНuvP ; ޷?2=N@v ;d2Uw!جwFK;AOy[F[m[`ݧY.)s2&,gpbwIc@8YOYO#'*zKy`d^Պ0d\ʳğW% ^YN .j8O0 ߔ # L$,teu*gi,tS,tyPGxnGΑ?+4ozFxmOQ9Meo).E\V3*e5$3^ e,t󙶄pn1\ם!Q3!Qjۣ".*o}`h?(^Ig8[!V\R^]ɰ2%dXD2̝LTLTKLoD*(7 . ^ 1 )6'g#AOEx +Fp,Sj4b,1U I [Ep^MR)SDy)BbK X\MR,r4\y"8owHZyyZ"8i,&'(ڰhkvGoƜ,3aҵy3E{îZ#[p8EG>ga a-l2\7?^!<18;lf(+ĘUT Y|2dɓg,\cp6-9K0ي9m?Aŋ 0gK9W1h8&Ȁ9( iN!#2:TJςT68@]rJڜ9Qr<:rԀRY$ wct{RJIPJJZ爧(%*J9s(&{IH*5 " ,:G΢b"x ,*1YI)r+ sJs^9 ћgћK^U"'M3xeћ.ތ_y+z\y3 iY '޼J끡x` x` ,Қ(Ou>W7IэݨU9)D$C:Ò&tΐtw+h":u4Y'<@3 d3΍ U@*hv9]*܀9ٓ » xTO(l1JQ6j78,f78,6*@qX$(t g/j9湘5R9E7eB@G+@NsNg댱1mZ08,g6 {bP*zVs1d:eL[ H<=O1"Ċ@(1GպGAh1 H]a@=TS2}+HL??C(c{PF8eZ˃G+*S/Al[7^ݢ2Mv\jQL'L,$yke|jcQ- R{ 74ͦ7m[5Oxӎ` xFɁs-dľxf7"WY@mv#3U<-}" 6{6 jk^h CU&f"̩9MxYgn[9/QaѼS8G ,Y"ogqYub(MvVy;CYIYg\Cn y;h=i˧@y;vJğ4c9 Sը! W5DhC7F= V5{sLI; +DsĻ\s4>4Ut ݮs*&WX O d|, QY2i Ds͎ΏX'cihQ7%a+ J40M*0KR45mL":guۼbhՔ}~Df8۟'Oɟ>7'?O?||?>}Οi>Og~ڧ3?sO9??}Οϟϟϟ>Og~Ƨ3?s|g|\>3>}.>Og~>gg~>gg~>gg~3?s؟'Z?O>}?O>}:?O|<y?ɿO>}nɧ-}|>>>>>>}nI>?}O?}O?}OOg~ҧ3?sO'??}ɟ>Og~3?O?3?O?S3?{%dXyE1un=x3q@qP7gyēw'^_Y +{:O5f9pLUggV # `ցTPճ tˠz֙CͲ4K|H Y Hm[(K@LXEy,YJSd&3^ϲcD+V{k:%+Y5xxa*ƒpX\_sgAI6H܄EĈ1USϞow+6 #H:*$ɐ $yk$LTI$3 @ɌMzLXŝD>tZki s[0UA$36pOD21ULTA$S[p]o3nÃW{6캭 9,:mMhu@ Fj@ WOCYWd NH$/Fc+O'IHoOxGNS%Xs-d"rs ؘTdUk3?99j*Ej'([ *z\En'En'LEn' ("C,vFPtd5N`0+_<7R`;onjw2yGU<%G+QuYq:M[ց}Nݒ9 \reVG N.Kd1N΢D.nG,n5r#pڈÂ1*M}%Af`K#F:`Ш]?Ґ}wtttioLOl}-ƚ؟//szlqX-QD\AQߤnR(5 ;V?WlK$O36 l XGqR͓l0`a8y.ĤtdG_ ɫm[8`UwZ=5 `]T UĚU@<'iM*VdC}w2l  g˴SΧ?OzƻfǒJX~|3eIQHwrd͉ϑS,ohMHe1hsMO-xS8KOUGms@vZ]@[zxu-<<e0u0Qy>^GHJWCz{ ]/H xY\gP沊3e.Yp`mzsZX{U8r*X)'8I|C -z0akD>8yQ\-va{нe/ȭEQ|xQEh/^Py>G+G:K$\];H">G1, U`1|R }2M8c;|"E2qnCsRK$ *-& KԛwhycvFYWaQ#C%aQe?" ?)&PC# jK̂I@xLZL:-ґC؄Hz+k`czBDx CSxH690BۥS]ps8v[8;lU%,O kuqȧٱ SոT=b_~ٻ`ȩבRe)PՐ@ 7EzhO3x74T~.bi1r *O )CZL;4gcx(jtW䣊U.kv,-=dR:\Y4JR)AH"HaZ/Gq-p\3dNQiPQ F*87-`'UHְjΖSaz4XoCmhe( :3JT-wx@EU}]Xd]EV8@HV>TUq '=kj(%o+dRT R TA1Ij[0TEq}`J*CQɊ UʎCTY,Z4USlmTIfQ*Z!aERX@atgBUq)*Ⱥ3>pM5 [UJrca9jӪlʪc&Vj=Mg7Z 8V5BZj ɻSVʰbX5hC-&&ojV4[ Yϭ<m uk޴!lWԮaFZZ $Ui̧637.b $V}KgxhSnU.4Wj^Y-u)ja1՞:3V$`֌2!FC{ȹV9czJTDi$PX+6MSn|(j5uib[8gv;9d5h iClar@KT0` Vb19} chmjmXX`c.u4R)lYSF| ^q njJ1jҸ*j!Ք2rVK),873d?@NPM̺U(EvtH=ZA[B~`MnHb63MսB1ypdf@`_ثFuS[^̌hc)hXpEL_vk]SaݿQ M^X['#}j@cM;SwlK32J;bz*:v 6R/DŽ(Ćܦ}oKY4k2^A*TBenY|pd{vUnӆ^Σ;n vc*RoMơJf۴ntu/慈^>)t=n.#`ݳ6B+ٵ0-Ҷ%]ʚU?ܰ~X`zBe`ijn0ąD6`56V̹!ɭuEfC#XryRb&4 o7KMm>,cf-OQV"tEo{ʶ%]fc(E"o͵S:o*Cؽۺz+M g٣f,):( gpKj*vI!eCHuyݎ݃4xvGNDIJ(ݕxBc%xNro(gmDM1Gly[)m   (wk2l(aΌZ̒W H$.YkTPW$C[V;x%" N*7u;̟*}FG#Z˨@QF7mhQ4.ͻv" յx(-{ 8JF1~gX 'p;o9O*jf emLĬ|ajT#{[ve6sE S n^g?(_uIm(j Jp 2%:ҡ L[;M;Α[ 3uؤ`G+܉nG,9*(ѭϋ%'T$ ,R nCG;Aslx.by56MxnnT}k#v~,۲% M @鳮sO*.**]/2 ok!ӰOIAXcJ0m6 1M`)Žblm?J W=&a m m1%(*6(춟~m`KTPw˂%d$Yi }]Q <5ߎ[ck"<` ..aY-ۆP8ǪXt~Do n9l~1-qnhjqd6Op;E"u{B{`pԫ7ll` IUn<6 +RujӬ.v{ -b*u3[XlH)S\M\VFB?ksJbKN݇~5u:P=2޶U 6WkOk۽*~#G神mc8_w%kW.Yʱ,t[%`nw-TA.9ҟ(m0nD>^mˣv{^@l`m4 㾊Mz@ݶ!V W[叧|8* ʵxϫ۵| e]SgF)cU)ӺJ#ZM*ogu;T^n8jZפҴ#Zq8>7Mp;ޘ( nG|M mk1ը7=vZ`* 9& vMeTTѼNWX-p+_GH'R8>&u@jWSBFiW~}]ٮ+S4 [`j 62aV@ SNy`jcGttx}X I4kF*.D d>RU[XEBK-"WdU(dUf~h #o|G6n@*6FX>r$T#lK@gò+>Xή(v:p4./r̰ ݧ2Ze#o !>9>K,vPb`'Y- HDŽ j].L,xvmG z5рg/K>j;Wqi0O2KuN+8T&?j9 LvK!['Vx9{lͣj4A)k2 H5W!3&( e7DDƖyGXo [@e@Ǝ_C[+D>O,9\*X!\gD{<ԆbD8`c*(BN 6W캄0 1gM('C4ZO J>S I .,v-fq lVO[Ž@-1@a: aJu`h {$)m akV`:wn|)k"f40?ؾכּU$\ aZ,9*i ytzNsQ7{ѴUl$`ka81vU 1LB\%~8):_1Q˦K^^7z}(oK-@GVjn̓ks}.k`6 ̵Dr=xQYJr{ \ [WѮ5Дu&B34/<>܀j愮Z7 k!;9Tv֢%5ҾV`u˴Gam:;Db4C|+}a]GHA3} uܱ.𼚍դ(ꒉ]Y fc?/`szu]VIZҩ`W%'_ Wkx5vj]lVIƛGOO$S~/{EmAvڦЭH39M5'zd$QAMk2iCQm@X]m`>Mjђ̤(:e!PXLͪӀ)C\VO6Q j5YMɣmAMn7S3ju]#H~?E[suA[EkfRFӉƥ2tAM l1b#KCl GޜzBp$hU׼$kU75\u)qq.(QcWqL<tdIdB0]K\ z#^^ ?N"\:ь㦙nU+`]U&@AMnYE*hF7f>260=fHzjٟIDލ,|M"щVЦ9mZVpo }@@iϰ?8$i@=t)Vӂ[6UZ̬'xQSn&^Xe׃OQ grJTZ6]~EmwZwUtc"AiUU'ܪ"aܪ) ɭjVŔEٵ]486 KmA{OV̱IOk^F86o ׾}D$53jk2tl4k 2] ;.'5C܊԰MU-(AxRX1"u&˸}PJMY}ei>ءr\K-:@ݎOVxEYycg g֤\ E'"{Ye5(J\c?Xs-A~v5 Ռd\-_STm+Z%g͸V1S@֟Ap"Ox]Y &hk%U}ng5?]+geb KlO̅!E:7#dFzo~N-Em)@dE?JhMp-33^tش7iW0M&f Lϭ*/Nl#*Wc$ϵNWi-r g5LYrр|>zŰ ;?h*{4sɑwDΞ1lj@;kڢsi#EY~/Q.X霂ZʁՀN`#DºC/0ĘI].sB9K"sEY(gk%5@g, @kccY,&)UمL VlR dV JnY}S2qvpg^CP#gjv&aII @6X\ 80dx\/9DCz(6k;G?NbC/<. vd>1^L ^ҪhAx0g6yˆ…Ͻyf}6-84Y:n;6%$d0֤$6/u5?"B8`YRxj9 VZ3M1H'"R]:USs>&G)ig9.j,2ns2C0w|Bry7GHij^{*+^<02_H5 i$ < gFLOP)|Mnw,[Dɹs𬷇xziY/DͦhQv2Mx'~ERi9jYE#%L&;1-8:Oe!sbqdbns=5ƺ;rV7Ϟ aOn`9krVy@X,z,c쾂PzʠJ 2C!Q*TC@s8-=Y$h2 +j3WYI"AZP~vI^ >)czHӺȫl'j7KJ5eɤiOr:q2Aglkv6rHմӖe$ ?P>c@3OE[ߴ%(f ײ!_pʨڄpJB8ZL&qWN:w!BN< W_ƒHF5 -4  54MPg |B >n`-{x 3tqxs>zUaS-S-_ԛ g+Ir%Iuk6k2I,xVqnqк)#TGȌ::GqF *$fшf!)Ijډs}!駓6Bm]9|dMC)mcӀmrmS_kzz>\R-z|BKlan !3EUΧ󕅳əQϵm-G2f&ڻ Jhh#~ٰHZG(]@ItH 3_A8[п+iʡ:m@ P t N)pEAR,JH3%G]tۈUfC lCʎ#>1Gʌ~EѨGJ\CWaۣfSߵ*8=z4p뎍I@ P]_ĻEe-6֐Be7^EYh ĉM<>q0@#[Zcx{TF:c ÜS=h݄=I1I9fD.SѢԣZO50O| b\ԤI]7 B]i_zO=`^$06,?S5,x KM8_eTkJ)%ݢ L iߣmXJSv8ҥX4OK݃k&j1ZHX=[vE:@eј8N14y+A:,NQvӍuke;&,iUo@I$CEx!H\k-?DF cw ]zRЃ u+;N-~zQa R|.iރtt4QKfz[iw9:*/|"waMr5/j*^][ΈJ[A)o rwG! ?-՚'ИY&|dV{-&3FbkQEyEmv='^f:BJƺwШ>/i.@r(wѨq]BO@ШiIeUeD1Klj7M::ԥk%ܯi2O(5jy[~l(Z׃qWMLցҤ`ԟ ᐙ @Saؽ,*~Gl1í45u2=o9 G\$7@ ^xjZO}М"@Nٚk/SנA]u(S3Nc|ə /&P{ oD ^WTN<{ORǃ9뢉+~c; zw~'Z6;N`Qq FwT;I, v4]fSt͟D=M9`635>f_b6pN5XPu6+@5}xwQ$/ [_S.G"hra16"?Qy4ٟ>ؿ#H!g w3;F c#}ƑHq8ҟG#}Ǒ?Hq8w3G#}Ǒ?Hq8w3G#Ǒ?q? ;G|Ƒ(q8g;G|Ƒ(q8g;G~Qvw3G|Q?(q8w3G~Q?q8w3G~l8g;G}Qhq8g;G}Ѿq8g;G9q8g;Gѿq8g;Gc|ѿq8g;c|ѿq8g;c|1㘟q8g;c~1㘟q8;c~1㘟q8g8%Wj:aE^N@3ܮ$0 6LS]}9ϯVyb{D ]]Ioψ2ʮ.yct˜;ޕq'ޅ+P 3<KYbjx0nG)Bgs&w`فU[, .s|Qlfxzlra3p`h!X`&g3 l@yx"w Wt(0_ t{B@*#PB2.#Pu xB"k'hĚ h ʫ3O fץ]zVQfC&ݮVw*pg:@j=x[(x-q}{8 di*;qYګN@ 7#QՄ.~V8KJLz wEßb=uFqd)Wc֋GVp8^.[L}hPd浑XM׉ Ow|=bv@1枖F:A#-4Py ) 3ۼSz2l`q 힦N<r%1Q+HKt"V Ե>=B_GԫUӘ$팥(v7`߽ ȯ;M%}MoD9ǗʙLo0 56>"acjG&bՆ| DSrVA034y?V=ay:#DHK&f.` LE HR &ؤFl8 j 'Mh&u2oX7`}xV,vL.$x $ 4!7ݰdrNXںQkDoa3x3*%]9fxKC.I+)1f.\ vUS7N@AI.jʬ>\"ivSh@EԖb*ՌkH*Wd' hjQ9ĒF:J` 4(P'РMMd;Tdq96┄!E6M%BAq33ȷqyEƠdPS-N?!8)xlZ> X@F#~:/!KuzEekl@5 Z{8 DflX%&|Is&/v:mr` :hChXeD+I}щ9G,,#" YZ;S B !- S𱃈+ o g5NH ڠI?6AD4hfvAQ$͉36hGчÞ%8c/@Di<^@DА!}V!}WOWkr bTUuDAAud#!squyv[+E~,!0) Tp p<M%hv[.h8 Zқ.6e̒9q lj$CMr  <=|5iK~KOi2تt52[F&'[GIDdهAs;RrlsiW,?]hKWD# F$`>OVKS5faCqkA0e0aF?>H9J-"k@8H*꧑31DX@tDw]`DA'^,fG'/o(1OYJ̤D=4/ fb&b&zO>ls]0ciɓ؊K<%"3'؇>qSNA\*t%Eqdjߑ=4z<]-$+UIS eUDh b%UNeb b= H7R *q*9aǴmQ HCC4]p - bpjdH",GAŌE<=`Ş 3tg-zƔ@ btl|0g ymbܪܡF Ɣpdd;]ÿSԣ ΆO,FOL֫z[ä]i<1 L&"i1:nqHHdlTهK[>o1{6|ɲo9)= 9n$2,ZOqޞMEEGҵtcD^7F)Ae/$M|/{3dgȗgȗݮ{[ ŲelNf}ٯ[̫vUxPMPQ< }tg-^E6㹁`j*-.B{)Nd )8L|"P97 p-K\-A+ȖNAo3A{İuLӢy^$U?53 HF'>yʟX87hWlQQ bg LTpψjK pY73dtE2 ?#:I3cf8S! ?ߌ-{IQ1Kk*[u(;_Ӗp%ClI!v"ϯWkmݱu&R]cxr,&$\?$ap-r$,W#O3Va-U:kEf[,ҦkOݘOIYmfnF#% U<]"Ht޾<%2UHC}Er-lp}5GXg&D 8>'3N&GYC"FWDD% ofթ.nt-rtxMţ{mqnJrCkY9#Uԭ+e| w>G;[CQ;DokAΝN ̷J2yIT==SP?mk!=Վh1;E6͙Jǐ骐}`}]S"X'J'AIQ`}F!w6B3paJ@n!]#&nHkoiͅ ww[,kϒ5MU5a-<& |wzjehYdfehR4:Z6 hѲπL_0@nf) |ulR}0;Wtoq)`HEM%w^CL;nQe/C\Rzxzkl @[oOqwv!Q^-a靻^,BGu.a?|7Ww .7y˹GJC5@=`w9N'MH G yZ8ҿS:b9a\Չ7gH$/;v)4(@y<[#^03S@w"@";[we3Vsp-EPnyQ:(A%w0)랙RרYJ"(yS-ey\Ҟ G/l!z_H}?vw+גޥxgO R)J ޑ xa- m}i(]OB dIV]G۬ wXv;?RQ&u nz֋$n=Ρ./Axx[… l7pw8A֫ #&hRss bN߀w>ګ`| 'k RF'mHܝ@K@ BY)8v}}^Eek`)H>ܘHeXzse-n!,ѰBh  [S00NY%z $5ш8mpQЕO:PS5k_jiX(.y` qKS_|W"!ESCMFWajɨP׿yc*yqŻWY8@UZ 7/uktpqlny/KQ_':VpF9Z_UQ˚6 oU+t"Yֿwp ڶzp=_p-!gK|Pq@-f=f8Y\nV45ZuxUR†CEkRGѲE>jxP?ѢD{iM5ђD;hK5Mj&^mi|)䰆"hd0و/_ 3ȼC`0\ tpqDi6ׂAWmd1t)W^ZJ*Z˸Ҷ"Q*miuߔz-cIm$iOQ3. M@2k3_ ᧬4ӌ? 8c5j%F{(.9KYG:ʚEͺeSJD.-=!sdHx `dh KZI(k>q3JP*{]4KCcAjzB}m(5 IH[O'twY5u46>/X YEiؽ -DvC=K=zqxc x#7aJ23nlrWpv6fBȢjØ(tllf)o&z3U;`PhSe En8Dž-p$DqtEiʬ@io>4y3 _yn`AB󛦵E҆q6S Άf7L7uVy,~Q &yM)ٷ/:0j0'ZM*y㭣gX".zP.<61+ڍM n|HZkZÈdofFkFkBgeniY E eA+ҧ'V e3TfO8%[8*Q [N BwR7]=xj 3-nx2c2 'c% sJ<4ᘳc#3 &z2}-k36>b_J nluz_j@GR'-%ƀ!K ]NI#ێl7=D1k!K1&޲JlDe34h˺Af%r{[=|==@wCm>XfDX4R VВ’\@4͒(k>{ mϯ(:W;J:'+1y v _%晻\vNco'v)[ d6=DN) sj.h;bhPּ8Lj+Lʶi pgakN3trG6d7)$40 $.p$r{!(>REb64033]9Qn9[>=SW\+ؼ8v-KQՎnZL͌|Eߚ f _}&hf67bDH{u }?1~uwMr%o_ zb$DEi}YY]r7"o(ZYBἪK(__@W: }!o@fB"&z&|oVR tb1݉#Xx Yϙ>o>S?}Bz Rv$ F W+}u1"HM|蟔&Ol0fj FfKXސu/XBA!$ol\7xKXMPJ4^?2@hhŦ@^obpW 3QD୳%ujJ`z~nc۔ڐ e)Asʄ25 w|4 3[brvV(#i$5n$KF8Ů%!`WK|݈2GSǏ B}Ys{"i#u>vf03i y5#jGg|klULJbzEJ#RqDu Ή[__W/=Gs?8w9'5H aDzBz%$n!"n;|F:-UyZ |! <`sԄ:pd Ŀ[> d-B3Cq ;c- "Dݦr n>70ތBt4.ɑaX {X b{:/;Rqm]IڊA>DՋ[IHRD^Gd x[D(OM$$DP6as PyO r{DP"wϸ &By}-S`o@n?~s;3Hgıao, f6nSpKg;d>M.SlGn#ך9B#:2&!e]i#ILզ/hCjtN%"fuE@Txl}.0<#?g2C瑠8!1D 3."q>_[ HA"9d5jDF lW"TON 25~gW/I>j df2m:i md3ue|rTQ%#6@Aq,3%t;hZq 4f) A':K$Uo{?rLnpYָk #wxo$v]cW/CLsA nX9 UP &`s?|Qp1.k ҫ d¦MX0ri ?(튡 m>dM)M$JW0O}OF$τOP` Ϋ`AOz҃\֤T`B*ꇞ0Y &[3<hV01"Mzʢ]UK#?T(yD r7"OW?)kѶ>cjo?#농x7DhIנ ϰG:][Dp^=ȄD1Hb-+nDd̒ 9vFRsą >z+ /,dW(a@s:G+`G d9BI8]|jf_i*ZW<[[FD~~3g- ԚI~b|r{6JLƒO\:'hUyAbZcNwv>bq`sk$c ӜPaM;DauIªg-Zvq=R}Av^>ַ @Q3R ܊R@ܺL`ja'"!bJAzZ$_Xjg`&XBJ"Ā}^g02&w#̛'&.r@ު ֐+>Qo >$>6K/~5ioKf#5\ \2X}*cWgzpٯ}` 7u$./04=3'#~#[;yYRK 4(<|s ,\J``p r:Rd#zM3p K`Ƶq= (BXwXXm8JyM-sR$sFzߨ/k{5?J/L ,9X8#p/m'cCn'YC qX8H4)fc,+bIB$/5ωJ23_K6NL3p2Ltb|yydK |^aD'_}Cڤm< ,}>/fk0d&z>_ˎ,aO؏/:C>af}~1p+p'wuTsI <ܺJf,?J|k>lRjRRN #SzQ濾ߙ^< =EíJ_skf znM9%lK$Nupj7<\јh!K%p\ <ܨFxx%2Y5j53(L 0evmZy1]Ԭp$$L.xm n2`|O>s eׂ[* wx%qk_'pW{<4x!;<\+aM&>x6]u[l}4L KCk}Nv[\jn<̌wb[j~p[%ze -xí5Nq N9:{}]۱'p}s>x\ < <\#`nX>s&f}QKcNw)X4J F  xMJ%7%9n?7ns$pAXx8 Lwx4 n/f^eJ-{vWK YG<\&<ܒ-9¤824}W Mzm/Րi5r%p _G$-Fiu| <uv8xVng]oQW]ϐ&Ho\νv8}0݇IU%pa=j/ n:C;8x0ȧ`Jj:p}c^ن9/xU6$H x8Q.z_fhӧ>p6'NLp;"lcJec%Nxi {{{ւ_9Ք-!S{'7xIVW씄onDW%pxuXѥ Kp&X?\5K/N_V4} 4JuZE OdAq֌~5A>rwL?*Ƌ ˭ nau$xpkS׊W`Zbcχy1N}]#ގ&W6,")ʬao'83M|*Ʊ}py̒xx8NLpK W}g^9_EzBGbPJ`7M{}n-7Zp힌hz&Z~K#+I<\EƱ*C7x/(U"s,q〇3V׮ZepkQ#dWõqXG/*:_-j̮ >מX%)k7wn:p3AnXpM?|v<~_+np2Tp* <\%gFƤ:W`NjT9>x~9< Vpi>/vx nݖzK޲>vz^:sh?e 1m-9vM}>|wſrKN5p2}nkƕ,[B۱K[Z #x5 c/v#x78sm%dQnXp}w!HU=xFP#[o>iw@wԈ/}~[0rG뚠ڵS;%>኷xo48K2sF6Íg;fVPpIʛGqPBWc۸%%i?ǒz@nuں(c~{)[3>(a`倇k1rn';-6bW>>q,p;/ƫHI<ܱq JM{ܞU#֬1ES|rkyux 5ϡ%LMrS 7Jz3b8Ñcr{pE}FnkMrC'pe=pxFLpgf {-yCHyGvW9]kI7gjs<\#cUjrJ?pŏ)܃~Ky.؍{<ׇT n1-ݔwr=@?܈xњv8g|_pAW*#9ȬNښ6; [j6];CWn,a ψnVqp nɄ}~be },q׾p_8wpG'pI<x +S \LC{NŬycγw-,\#*"lד=H@Y' |o=W?%%dbI&Qb- _,*W|XFxvrKa;Xz2`ᖬ)'{K_pUg%ph  7%t(` ,~¦ FdX8"M#t_%f}X8 pD 7@%JiY W Jӻʼn'bXEiYg s=sGQ&pkSݍ`(n ]DKoC}).%Kcb•o1O 7GSl;;T7`jA WIm02֑^ ? ;,= ups[.=e~ƛ>n>W ,\A#n ukɽ DŽ{,$VfG 72>n>n>)^i/(^ʾ՞7}jyR2ǒI {-SaIY,ܾV ̬xᨙ}ݓ7mp]Y^ dvZpm c­u3tsX2X )[z.&,ak3q p>iMlI=z}N n4ԒqRZY^2zSb$ GG I H,9cc#_fy.{Ucgsn,/!(!Kȡ}f_S#dllM[}MO烚-,\!.W%,yPf`%S-69H 7]b]C/0jOfc6 l;=7ro|}|j͵}Ntj^8G}lϯS` 7pb()X¼;r s 7{~Wl>Śg`yo_7OEfg짿arýkOD/Vp5%S9u2XB \ȻlZ ~>F<½;%pſf]WAeps,Unufgǿb>3^A2gp,\!I IIwF-U6*c7g9 GDޓs}.7=,\/θ\2%|jh@,\+7p}a=7 ׫v;_}~%qsk˝"?*kfpY,>,nsub3X5= 2?[c6yfoNlpRepepݬ9,7eΕ  k؁2X/P wq4epqS˷Ŷ- 䴡}iT,\0[g$GęX|O;q\6jt,7\zw-+,\6iޔ spY,\ua-ױ+lp$3rõk,`^wF.nr/|5|$vg"jNbdC6bሒ`V̆j` zYxDkH7rÝH ,\]%_mX;JIn<Up@‰ǜ~dN[ ]dzCd$Oq{ۃ3<["NI㗓T;#B?'8'}j(pEyHn?s,(ɣR*1^bϫkcg`oI\-Y>A>IU`^`A̓5lpּϹ?׍9pwޛ![_\~ nbIΨFCn/uXA$o F9)P 9!'n{lkEfԝWO`*> 9$ `ZD Aepk+c_pW)D3X#2XIN ?MrrZZ:`*L,ZM''.s~r™t-+oI,ܸaYF_ļi;@ ׈~`Wu <7XIf䜽ϑ_•gPFMp}pumJ mW)O.!-fioZA/wm&{6\'im7vAȬqY'8;10? =2kg?Mp11gW]m(? W9=䅋] .2{Gnz?W2of'>;Uד=4 3 f ^2{sZ,agWr9񨍒%r$kppd n v0V4QȒV+K 38Pn׶{ƶ3Cy#)#)%ΫĈ@7vT_ӷeG,qfdvXu28 kz@^89Bړm7?mW#9s#Kr#Rcru*g;(!_YWoWQc{`Ql(ɩ(kJ>85wm7,C1*|ܺ]9 flesU App`fENiz nɒ元#\Ss&ppu88 38Q&=eI928%mXqH2qpjQO\;Zf>î>Hw- tBĻbd!~>7=կ .\! UeZ<G79Ys]-Eq?U[_Fjppߜ3\u .Vy=ؐ䅃A'Wef,FUqpj눸ϯd ndpphG,/f [f9'37882gpprgppU齙(aB# \%Z7K5)382d25/#R  nm`7Y຾qp>|**g8qp7[ >2g65/NM>gnvyܵچ|D5KWZ)7Si9cS,y+-D^8y^,igs38Y%Kb]Ǯ;;u!BUD2ď(xL7Z8;A>c]ȹ88<89lr+E8枰jk%mO";eSc7#[y9@o׺<;g2.՛qN2-{wN 1rdT u(7hav4sqpp 5qp_"|-샃R9ḭ Q5M' kf Eq/&d7s 9E8q}gȯsk&n8oW, 8KjC{lQz;ׅƍ~7?J <}l;ƾ9͊ Na|ޝ5τua76qp8-\=qZ+w.z;9ZT(F hk )zπr,w?k(~_ΉZ'"+"_[; \\I񜱽[Mƅ8}ׯ|Ys-8}5bpp1'r .-k`}fq³7qp!pp{` /+D@)^{w8_צЗZ~?*z8W\8V+q*.ܴ.wX E7 7XunG~s*XMXyߕ_P,\vcw9X8b6.r n 4`nΕeR9U`ႻPp͸p},\pnZƅ9`6Xqᮏ58R#G 7/Af 7<˕1Om9EN,\lc^m?s-pbO gz }m_B'n[1s>'Un ¥󍰵#VŗY=V,Za%>юĵsY/2W`[Bgpπ_,!ikgg 6's~o3eQ[[;cU `&$͸p+ ,\q3'X (\X_թ 9&WB1.g pp3>W`.熷<F]M_3p e{h[v&p];0Xܝ鍻s05pe3p/,a5wÖ5C,əN,+q&7`6f\+Nތ bpX-~=no˘іagxhO2Ի> Nsj'9e0.,|, :X<+Ki{.A{^8i],.Fe| W,^yRG-­O yFΉl9p>?}0x_ wsZޞ.g5ܯe2^\%+,f&aq|ሡ܍ ך5㡽iLވj'1 {5^upg\83e ]w3nGE3+12_lOg|#+9XA QzϺr kpusąT`:m7O[eȾ97N,c%[e>g\k?^7OͺfsPb/(|Sƅy#yJ'/nݬb@½_(mRpqZc`dLtpc湻Ppi~{k~F'O ҇ٓ}oy_M|'9#0s=OeV Mm?\g(c‘vp  o)3),k;'^i9'e V\.Qggw6&*~1clN.,ݕ72_1yu=kaڧo }yN`#̑壛Sӯ?hmbNwh`_W7e)ǐ99gጳ [߾[`vg笢`f/# `7Gf nCb±_scsbbGÜ笱b%Ywc¹;ٛ1,[QRc؏- ts͑Ei+S;?#sƗHOd cP d 7ׇw`&:X%jx*`L8}T%ގ,zsp}(ƄSW 7@uṕdKH/\D(f}8ur64?f.Z8o{!Dྫྷi3umcƃӖ%/?*Lߕg4z>m}9U42vH8Fn<4;qpƃ#^ʣw52s7290ϒ>fSN:̿[w=ig7C-;r4sY#]ŧ~k^lxq258 bhNj[x~Y{ Q{XoWlcV8Qح٠Чy)>ez+12[Ĺ:z4o.ʯ>ͿM}W0y+̏_Ng7%V2NO;>}͏JLn<8w&b<82#e\ޒ>9?O(25\!3k1` Q-$|7?xpxW\»2+8OqJ` cu"v0pIQW;2􇁳|;gVsC woJ40~ .0px=3w^L_Q-,EKf%̕~a g%Lǂ뜣+7*N)W s,-[$b \t \ICr/gv]֥9wA`E؊u2|t0pIP ÍԠ+7k+O˒ow1p \R9,΃XH#Ӯ n{͍R<[R_G͍q&\֠Vߥ A@ ܨd>ƃ8jG1I`s;dH`:q:?FU9h4Z}/n#AYvEʌ ̍z 8*`C]1kc]#q qag?؅ nmn7_K9GfYǾzBs n_}lĜ̍zp%@g77=xp60pFrF=8%K`}ŽR_笽ו} v7-ov,谹{{ U;H&T=ZABkH.+z5oɐt)n3"ے/O|m(}mAG/pK ʄH=N໒b&Yqk+?M8n(Z$o~/ݜf;+r@70#}?w?__֙O7# _v\h gw"XNiR-˨'Dd^ݺz8A%[i gFZfSᅢ\DZS@KuRmѽT۞wzћ7؉&6S1򻵒q]Am">f#㍈Fn66 zj+}TF լYEA%,Pc=#oO?)o?)"y[o)RW ؼ@ïjtgT˲ e !WRmg;D%AP*y~?aĶ3gb|.yi/9'cVѪ Pj=>G]K QjGj;Èmun4R -ޜPWRԈ >@ež0^5@#`% ~\f5m<-1HuH{>G~o3 mWkSÛc![r*'g̥"R+`O m}-R`PajuB wcM Ř>DD,XROp\RFeGp78j9v@6=35&T0fXc~(?hߌzAf70n:@fo=o*5Z0rӦ.SMKGg>zoR|J[gf1<|>&ef1$!`\?@%Ż>mGFh#*FMТ VCѢAھkHe;7p*Gڲ57[M^%bSC.A՛h,MYXL/#uSL Ӎ]lMyzIǏ Mzf3t?,㖜lUO4h 5Pgm1@- h C4{h4 hD2 m 4bA%E> mG6Px~DKjCO[K;++*,k~9#xe^z>'ƂV\Rܹof y"]568yas>~w48"`F, EH3b㯑vI]N70kj ,}4Nf!=tjHj kr cuViskΌ1׈4=:sc7"aZX3gxc*1De`̒hZFe ڿNdb9*l1|>u9]gPmQb80fýwtʈm84J! +03yz}+Ө5hfDÑ3^yN(l=FyߌaQW#rδ}f{/m #0,2g *=dYW5$qqK_isՈFlm#C~EjA Pd uZo&ENFTk0vVc3N4.hQVPdrE}MX8YtSETP1|>؟/ 3+0aD5QdXQGETl`"}Ûg,CA? Ћzh/d40A6&;1_[ѳ`Ԉv4*O0h|.(>*f%2AF̮aVf/EM =6@ c?p E sQdMjLQ2vTd[cnyA b&řlZY0hY _c z,is̒Y&(I/({!߯eo5|0cEF:9|xY~d=7I@ RL-"fc;0kȱGG2$J(BB|c۰?.Q2|>dRљYvoe+)vmcJ 9҆D~8IWc/<ȱԣkY&:tCEA orleyW!N0SMvx# IE_9+D_jg j3j9kӴ; ff%9Ik':*zz8_,dFOӺ&j 5Dr)RcALbKzD8|F-5` ^9@e+ n1Z@Ec7rZc5r1Z B+1Bh ~Z?[̆L=6.#NNF3  26&P` li mˇaFtf&lolqSY1/5N xY DO5f1 cq=J.1<7$'!0_븥41_/z&Pt0fP P֡y@!?MsN3x/"/} }؝{z` 0~ |8xI ! 㘞< +ۣ'&s~h 땔O}B>'{c}0v_3U/}me9*>"~q%v0Y,1>h Q s9 <;V]ܟ'ི,%$k;B5WF09)oq<9Dz3s.V$ytEed/'uN zk~5@΄Y]9ù,_ &؝FyV>-e9Xì3k/{(,}n+Am/֞Uc}C>ke/gi#eo3rDw2Yex #=XH||OW55 rya5Ō\@me]ޣCZ f$5 ښj[F.{X"Y\^R𒈭gۂH*kcVslèQѴZXzYH|fCO\ƫg4gF3x>H%;;0wت~~}L+i}t(3mؚ?hFnF-ɩ5-Xk>m!=,3qs5r)Z.3^lߴ0h Rz,#>GHìcSؾ#@ȄK>/0{'qb5_nNV6g1V6補VFA թ{C֥},3`&XaN"F3wUXrm]>m]#O_E]3unf د+>n6i|bۺu3تb.gطȱ1~]?)p*0R}>^S$+ks}͵o8x7L~žuHϬ?2p&w]3l׌^~iDfxe-Z@sz <}>^FE7!~w&=ܠsb =1fv=2Lcy`㫁Jꂢ~@>rWY˾G۬ i>KnBKr'ug$fem/5=`]C7lJ ^j#lJ ^jf$/5q6>|'Φ`IC˼1gp_A1OR3Hʨ2f\pi֫m <ٹ˜ʨP)#HI| 6xF+}3f1>x#3X~Χ` p6]qOۓ9nm<e7iH\YH%{aoJ"gӅNb<23HT#O^Ӭ{+}Eyޚb6 F ##jRM1H,> ?(gO(O|"Gm$H|g>R܈"CoZ}Q|6;(tQxOQ)E?E um>ب uibkH>kبOlԵA 2}5zG/sQ׀2zk("}NQj^b.D2ƌL_"{pk F?!FݜeZEGgqQ7ٛΏ73٤qy|Ѝ`= t# Ef}^YidD.uF8,3cٓyBVOt>mhhB#>ǎZ"4jPDAB;x i=cc +:pM"҇P,| =&1iΗQ"7iH(^r$4:4d(H( iNoMίH@B;(`4g7,_|CibltgTݜ5㺹,M;^kP~|'q49%zk#{))FfNm,Ei?9qNu++-8wDˊulSʸъɯ 4k }qk 2NpM$RVCs5 %4%.90kdhGc1RVi̬N#ehDʚd.`&b4B5R~sQF~=okz946֗ݾ{['_9m*O$kHpTS2 yk0;+8ѽA5-MSTT" P-C>Ycc}nz3;ȦTy"ٔT@-$!\_1X@0-3'5g|/1j 7,7L{xȌ n-1'[[ Y ђEi.HOLգb`! ޜ:No ).[LLHI%+f|0+Ҵ.Xt5~$vH2$vȝHDb+RR?($ANJADi+e R 4RpQ2ҕ^)?JcAqXwB1RNro+%<,<-f阴-`tWYY"sD)fؖCY:8Y:N,?)@6"n` t[:O[a&cZ[:o-7uUOb#]w[ )GX' 'Y𦘥͹mW6=++1̮üz~2ӣ"JIEЎW\b"_$U6F[>.k~ji`&q>fz80c%pmP rD 63Hk)aHoCFF:{i+h%!hD۞F"9YA;EXU oiGBkt MSzNe۷"sD d/9X'BbZDsFb2&ud `bV'WX-0^)E5e}pME\c=\S<5)Ȩ1cئAImJ" ئ `b}[MM6k]8lShm0f67Fn#3O~ByvypMykJYɲ޲okq `Xg8wi 70Mh``ZP:aV~!$8XO34'N=$8X3&xU )ˤ̻FzqnjZc4v60MIі!#B8ɓؔGgn)Q8:[FV0:^bW>SpC:]f1VRƨػ=b;H/ )<{5 )G`xb]$MRҘxĜGwq0i4%$O4q3Hlyg~Gi=$M(I io+oNˈgbe9m g!J/C)^D@61ߓ}88Gܟ&7kvc?eOl{ԏK5(v}BS:f;U$,KQH߹qE+ǠO4*"8moqVѨ8E024*w%j|>~F]|4*QR,K` 3g,j9̴|i/Un(vV|y2"ad Ƣd .>Fd_rEK0of$$3af~ڌAC,Ѯ.x XETi#g- ygIcYZѺC ViYa qGld];d6MFKUzm>^ޜx'0"c>acm8Fa }+٘s c}!a\h)K 'QԗB˼i 9WΑb;hYksX`}Za"j®F+r=JaaLVw͛W?ZWn$ZD0jQR]MR'ss2 #5)XD68*N?}"aDF4yiՈ&=aƌh2F,dF,"7tYd> #Rs6#F,AP'Ar`"b8=YFy #n"rF-ʃ?}+(XZi<)vh#q#G/XD0bQ2GjaĢX%ȝلQrlԢT샷FF- 8E i¨ED Qb+},ZM(Pl>.F=YD!F- F-!F-5㱌>n"ŗ" ZuF-!cor&Q 'rdP89E·^ 'xOlntP8IY>"t7lfhE9Zq}>Q q߱}6[iO6@d}ĉ{@q &7}8֜y寴 a<9nP8IP'Ț q:CY>zCZpF @aẦ'=)a{H_[ fkJ#nfm-(_W7Na<-/d~ qM Ŭof )*R̤'rR#$\'r2wf87Cz_w1Jd i =$Hʴ\޼K4-r@z 9WN4}@~e ėlxOT fÇ.+bs~|[3RX8;i4C-<D빥̆Gˇ[(n  :;F((쮠t:a< F0 B'a '1h?h(9j>ЀA$5h&CbهolH:gsÝ &':5&')zƆ|!#^?$p9~ q98nI9|os[ڇx9ssM|l!<LϘ]cY s=_mveЭ֯N98+8ѫЫw٭A,"EFWCfBy~#b玌z'klYz') Pnj\^ 6Sc #dtN a~iK9'S`xYvB 0;lnH#=s؞.@h/P\\?o`v6'fgK`v6*fg%Դ܁e9o@Z+s'(#szԉA6\va!%f lՅh%jfOryw̓g˓ٲ=Qۆ8 ;.M*!vIԸ ({`?¥ɃGY_(_qp&ug1#*Q&>gdNC$,ި <@ )ta#.WC#3lz,LXJC(,sfGTރ w)&P>G\] a&5\I-dKQ R ">p_=rb>lVӢR.4@Kr>(^Z(ycBv6sX9m@.|Kudms$+!1cA S3dZvXEyĦ -H !Dl_s.܄ 1Y^+~C.oWH$ HSܾ:IihR5` "m [8{mH̟e1ZrN4Q])VHqԺUؓ<[Ndi5,F!,![C7M0mEʿ>;O=lg\m}4≘s7ȖA{rJQ,N2hI//?Z4i=bTW0*VH>AjQ!HU*kcbuO9*#D81@^~E9P U*%70/n֖`lƪ||1*I>:?;WW)PGWc0飻[+t@>01ď"p_$:W0xu?yKlz;%вk.ޜx*EPV82ɾ|-}[A%qs/F`xͯ)p7xj5y7;u1W% uxoM( #.O:.(QJ-Dox@\ Ri-]=3e^2. ЯX} 6)a*/#`?oʡP8bW_!mǻal}pJ)9_= z;i!_= S2laT&o 5/}tC2ftyNYr WuMj|p>?&R\BϰDm@io1a g_s$HTV=$0~iwQCjTȎ\8YA Eth-sLի QӺVeets\CwKB '0|+]8? yHqy_a_F/,ΐu¢*soK|ReTBb۳-\9E9C,`Q1*v.שގ*,*ʠ Jn(e]̉9FzR9 EMwv}MEy3t 7s'ШMu^rZ `W= 鯞ϙ]QB˘ ! Pt~y+k Bc(n-Q[@zCCJAܙ`ElW}x>2z{PN1s@g hz4-ˀbX'EwP$ޠW>9A.b&YFs3@i ΨL4|>>/;k}hPu:/5gm^k r\~.uB,Q3"PV"]Ho_5Z7sB/!Rc A-C}`,R:? 9o2(< R#@E_+y\_' ⊏袖%7:z1ob!R 0)ӫ ?(2D(нWy_ME+Ҡe \Z=sp`/{-!-O;%zA>m ߃".}|{y7 XB@,RKeZHsJ)fCyvP,7JM엑" -RT궖q;*l/asyc6"h^dQ͵}ET+KՇ phc@ *hCQ͗ *O|"yP+; mD_c;C[ qP7ZamI6 j`Nob@G`ڗoc0?8G rNL c0z`o{16)LȫJ #p9v(a@/[1Մ~ %̮W0Y=ϑP벌-`x9 .2 X<;zp 9FT-/}YmMAP8/ eأYTUŅj=숀ȱe))8kU-犰GZL>.\w9'f9# G*b?4F]r-aN=OUog5fBM]NTsZqWǥ%jy2L ǝ2|ɫЫzġb zXs @bmz5q$]@bzE(l9ΜXڀ^2߃aN&v8f\ZKm]ݓ8KJ9sW +zsv]aо^2 Ր#*Q~3N0-P~Hs~*Z^xn{2+:5P-/-NֆVh tU9@>,#=̳9wZC>/9kq>\+Tt Ae3j`N`kޘSV&C,~b)Uzs~s{;IIBN$Ib2I\pa+袬TH!<%9EιZ&D%*[L,H[dmwpxK;Lb+b&P̚aE ZFΧ5sIc^L9w9*4cxmQeNݔo˰!#eaҏraw7np>'Wg?vlKrx nXaPa`iDcӻ"){ܫC̆ɜY#LRGe,?rMNR%.Ϻ |":_Rܥ?+▁b6,/<pZD58; b/yR6˰b4YFå>D˜I$LVw?NYrPJ;3^n l'`ʨtzb-.wkU|oZL~,dZoκ!h$p^7FRωFƊdº-q2lLXLzU`)<\<ax89[gy.5AZmG=N.{5NN#˽k_EoGÅwa!-<g]Ř̟x8MB%ˤug-p,p^;­o=me¥;2~,pYRgn%Ż"#3# ," wc w`K~;# 0}[>Xe5X{Tz W<^dyEHni0y=NbL^G(e:m׭ nnEj6#5Ou&˥ [{)ʹ.`/uqQuLj܎gg88X>R؟¼}:oٗfLis3lp2÷DBƻex}qBPnpס1l' 21ya/}2>:bc!3d|6ރv 2 ;5xf|QC<l}`koyFguߨΙ+${"#^> !`k'@$ @$vbfc6Hb7R}pw>&3|NXy􇢏`˧^nf\xNo"xw4陓8YjYܤz#g R~P8 e}@oWۗ>LHۏeZ9:XdVL CM(NȔȷ\v|ۮ 6V m9 :v A52O>&y77yv[>aa`XMwaTXCoܠ}z"baqE4ü/7h/ȷ| 7n/ȷ/0A4wZ"|2|,_ ACE}|#6 i|ȷWI"!I>-vt6 !IE]lo,3Px&A@zvA N tρy˭#qh< 47ȷ-j|?R KU87pmoD[jj: Ҟ0$I O%۾e \ ߒF7wVjxS~+Bl7I\3N]BQo7R}mQozG,Ag(7zcܜ){^fB?yg7#" F0mP: Û#?voַA F-B ܻEkP0frZtO '60P-m[1fAm`Û8L@67i 60-⍄8uB1* /Eϑm@¬O.YF 9m>Nx[.XCLw9RS},㦟}{Jq3p+HOیyf'$ܮ4}MP"i}4}?Z1Mb>vJӇ^Xi/c4}iyzf[J"in e9kAlCaxO F†->i0R oo9Dx[$ !\6Cc }~KNs\#d햿Ђ X*;T%>MqwE 겇ϯe T>[`YzݾF+xl{aeAA/;h_k9p> @oQY ˋvպM뗛pk7,/'ڍQ:le35&*$zoC :|vXVBvBlC%  w:Ȼn"1 v̉H駛sK7߱9`ͷ&2YȄqllt9oqEqEa"1H7L"eD}\ HʹAwSA/z뛛D0 :j73>?閔q۶mmۖ=yWmnmp#b-9IvN  ;s`@B)W;22nmtIa;ǣamnmPYlJ} zbW#4ۖ2wvOԱkCQGwnN mok;sĵȱ0^D\P2>arO>/`Epmʄ"8m \[ĩý;ĉв`ĵz>6S?|ʰZE2͑Wރ5_\[s^ʱNnC5ѐb'MC/s%N93>/G?PhvJށsNc'`aX {0C5V>0mlPknic:tC5FC5?zA>$0;+x& ܷ۠x67xNGT,> 1 o *_5 <[R4' n/ R9gDHӋX Bwf=ڀf]sSʮ-).%g !wŲuNX0#۝s ;N5,K.}L@5XVde_S`69xdaM1e6-bnbnlfa\l`nxlaOe CD&=; '{ެ$$q%ɠU*mN8s4mcU6 HmAA mX}O}IY İmVi^ω-ú-)Ma ܉\Im_Lqh&|ehfo[v낗ĵ`!0H-~ma3Bf qů-V/Ϻܩ+1y*xUx(cnC۰̎ 23xti kq 547Io8#ʏtCºAaA3vc0)OL)_6 >0۔_ɔ_ek'ZR@__# RdZ/\oZAW}M+H-~퇴_[|*a __kyp-e ¦2Ʒů= r 'H"|l~'2}L˺~-A3eX y-XL+hvQ~0l2&sޭ%Z6ҏoG'ekh6>CvsC=ھ'jMJОj_+Rwƾ C0@kFlaQV(k[[M ~-[_䜐ZVk .~Fν-F4-~w민3~sTmc.~]]%mkٿr导-'ߏ8pJaA|ܾ`ײlC <[4cNi&Ue7Xnxmc}QLEm֥.EMEӗWMGe2a ٦#$6[|7kj@˧K͘p5P [oI 72$vf~Zeb=a`"m.}oFU c0d7[8صo(ރS2&;**'B^lzfR/ }->\) 껌 ]K lkصAm,7ڰՁ|nev8qzZx_ӈ^1Wυ]BQMTmOoiQisL2>.vhXn#ag`rW¦bGZws68a.}N+G_4:ks w|vm4b״d]:9ܦ+v2g2`Zk3; KTM3éQhKIl#5, v%;O[HKʶ'i r'Fo Jl=2W2<*n8|nJqDAvHǷj|Ohfrt84?KJd'$=5W6Mw'37w4k${4?hIt=\lA*yZUB[j9 G: I8"NKq@T=N$jHqlUqi ﹷaxbƣB:::+-$üfava=6fc.IVim086(&VcOdl?_p&S{,a/Fg uA{ !?qQ}c*!綤/_eQ{"HpC_e55{:]Wy7_DUNt~C2vK:>UQBΣU m a:  !))x ~֏tsxpJa&/vddl ͙jV[p44iDӐudd23sӑd=h,aW:G Ic݉2tyk'Ż HRc]uNjby}jɴbi-GyoKl6i>L_+Nm*,A\??Int*'WIYMx,F$1tſ\g'Gkuo׫G}Z=UB[b+B=K|+|BVjn||L.ǓZ6 *aj+:K|ؤ¬IJ^>D$@d3sKFPk |Q;$}]yTT1e\+nf+L*m,KJ;W-װ$Y%4m*ёÖK~S?V?dV >qnJ^խq }2>nwnGg*4TKE7( ^5OK-s Ip HN]#YX{bmPzw@C7\Df 5JR1KnKzv?TN7˒^%tqw6ӍFt^e qe8HIj:T 啱QYbaq 82 9:[d&d@j\&s%|{+ˡZYǪvd7vj91E(0}k\CA„pxonh\%iY_PY5㪚4R9S(q@֋ɇ_8`!zri"#*C&|L%~q_,{!I2n|ܢCrE, 'UUY m*eq*aStso%NTDj' jVsշdSNF9W>/gmn:tTBH{JF=GLBTBTʢ3EOzS3JՈl4KhmϘ5(4d/ҟKͳs*{fЃJ!+ERW2z|I T$GT 4&@SR=-AZȪ 4u(n$KlninpQI8ŵms[%fVq$g&jtB㦱QcML6MSH>m =$/ZQ\x ݓq#I/Ol ( M 6My#If}}du ٫ Sͭo.#zzc4U>*F WIgU)`Q6DU9F44 )xwe9vV\9d ŝh*nv,6}ÔAsհə (ܭ3EMڐ  loծ coc\byWyate&@Y﫛{w u,~ Kݤ- nFWA\NDHziVALJ"W{[zADRU+?$+!-]S*i`tIF׸%A=ؾ+?ft*(5'sNT$Y]{ԏJw}лG4лBzJ<A'<#෵MwU=7]Gy8NQ$JQ>!j9iG%$AW=ē|th'YUj|h*$œU.*Yj7JJhC.y-+*uqϚ)(<';y,g]܍GլZ6vַ(ZRcT8vݶlâj4opY?MgF@r%K}DzCg쁨zc؃{ bڴuAے^%|a텴{vL`V?2 nYet0_t$=9F#|; `C#|WMXx,_Uc;&Jvvz5 ώz͌ ȤЃCabqib084k yŦc)_ձʡgmH<{:Q/(6NzVdٖq(!˱ 2<2%$ϹCq?}w5-֔_wG\:$LpF8{{LKȨFb:`?jJn|r?n|~dMGy3N`'cg`Zq3\j8Y 8e]תʝNXŐ~&$g0ٯ]{sp˓%`߼B)Ac$[WKY3;z_j!Y3y6%լɆB =3dӑj ')ՀH8 צH7!PTHGY2ϹbiX@2%窩1c8Řxfג=ψYt"C4BLt2sZ(yG]\ B!xuf sڊ] $;Y3őfEJWe04*G{U&ii2zz`7?)Gpp;ZrX975bd U0k5PA,NL7Ț@[M$?ڬفͮw&(jx!&znvus49| G(Xm՜k;+!?؇`5+J!£QZjWFAM(%crԵQOpML Z{?VV1.yÐU X* [8sH_,*' Iްʳzin_Q%}|xgjbgyT>ɳ$`wL;ֲ<ӲIZ |yo?Ao8 Q3)[>4K[5<,Ǻ9YX*oh[Y^,ULܱr"f=Pԋ|34b޼,,!#Rzʒa |9B9j{~F{W qQs%dg)ut\RVF!8V7jq*K,[ݳYY2fo@Vt{ݲn٧Y&q2نj(nRҪZ?<QKZt*dةV]4YlrSjΡ$˷G2/L&[v'Li?ɨ*&BXRaZcVJ’f ɠIv(4Cj5_o^3^C\qH4Ik˙eW; ԇyo&8 $Hdmetܷ]G׷JY"%o]++*[n9 $z:&٪Ssv:xF_X(NJBL>6N-jʟǚ%7 g OǍ(nqiNb B%DhDFM'S;LsbBUB0m6NB ŒPӢG~28qՒtQc9.tI[53Bp#!dlkUqHVF0viNbe oRFS#vg)Oe:B]KW%zY0~,?%@@OF,pY[ܨH/lI(A(EhD|O Y$M4O%>eӽ&eB8XUn? %ɿj}̬Z,?իm6SR\1\1Z,~yOhk)vVI%׊S$kxƲ~m`ׄFK Ikj`|9H_@gHOQXOBFQ%4!X˩VyjH}#^fT.G$>V86T(A䱤޵ڑ43IUʝޚlD㖍hi,K)U]+pu+Վ>$q9u҉uP:Xw{ͫW֓VY('pbQ@p$jvjIDĹذ YƆndErzexu{2*ZfE5 s/MCkdI*a4;EoṶU>ˊzj(}UFq4Ƌ-ɣJW ml(u7UNac-oNͦ:s?52<|qU>EnjQמf-Mդ? ~9i~*g2qh'd&ɋy*@yvvO+( b7(>"?uc;'YT$8ON Ī" 1i!I}G "(KT-W-vv sEvbMNdGl'Q 8Oi&6J$Q8:Lp$<4nOkY |l6LnM$<,U%pfD~",&%P,K[2bRIL\$R!-ɳJVv97U|c}qZFf;7Sj˛'43ܡȭbeGu9KYm0*{Y{ć% Z\.Do$ӱ饖d5jDIM"ء:c߱tG *4<.k@@O=BM;!W<S״I2K' X-KyG9 ddˌzw|[QFB{/jo,ajф$}jG,A{`6u#;1j'Yxc ^{#&yV9%Ke ӷ RZ |;IGUvߞ>og3U!|S"Wnd$/ɿM*INYg0Ej׹;xe^>OOpbI=]rx}ZZ0S3xLBS/Z0=' 8{vbNҷю3ukҙiHٞUBLFZۓ%lUBvXNTˆa<ɟd ԖFI\HIܞdl|HO+v= U·U Bo,sPsc52b%iz960ݳ}ҫ=8}|ycl{ZʨZ&:oT-X)6U4v:lU6TgŎX+kx%2{ý=Zr9JVVP{7Iٷ\~USOJ6GLJ`H:XHhw% Bü`~U«$9)5C_0'yK2~i vjUcm>ن ݰORB*5a@Œb:I; u knv7cQrj^nG-[޶WliƦ=9kCš&l"1d$\~HG3'`U] z5s"fHD[+S};M>g#rOd}g>Ang5zf0ً$CLrs4kNk $ idՄgpQVJZ4b̮NrI*geu4KwX[#Ny1i?ԩD')Y@JH۶̥Zg;!7ֳ_,=+ѠqŮD]Q>>峻1͊))ML=)}} xv8W"OYOd5T4O\B!&C*dd i$MۭɦWW$+uEҚldךHMM3>@'$Yxx|EW.W38r::ڤp3n*$:$lUBMg(ꮥgg(J03hvTkj3/\h|{<܌۬ ;V7B`XZI ɸ:(ji2f/*TP\>w+0͘تqc: 8_JWU3S/$-W/sWNMG%K<72cWM|bfm!e;$o[fĆ[Z!ĦY^UUыK7I$kԲ+yc~sIK!>ܤDr73ri[jA5ݻ 3XӜ0d!AͿˏ#^*\G9zP_Z-Օ+Q벥2܋-ٳhN%LHWjs\OҚ)m)ý8{I~SPRvI AԸt0,Srϓ%jIeNrʕO8r3uk\$H^KlEs^WԢ5NXNqTv ߸™S-,|&KnKߋŧM`񍛜,9-a0X}1vb5J삙:ٵ7.uq%Hv'K|yF=JB'KlK.sW9 H$hX.|#Q8+ytvm{\m ;@g_5uMK#G8Ua\̩=d/ .Ԧ]% |*ܙ$u$K~UB k,E"Yb;Ml V:ewY[)"t P놤yJ!zݵiއu b޼ mB$9%[H[$HҶ`PNbyHp䖤BLAB\Fd,"YdmIδd $bb5Jx\.tz#P8vBGVJjFögCR'z鵺?iޟ5?k׼?"IjEO׼FO^:%X )$uJ%KPVENdגj$oC lInIoW˓IC{yʸ'5`I$a`n7w5 /yuҼ' <_ zA[~OҡRB"%[qw$aCU+P$c5*f5)3*!3z"bF2+L( >IKl5fⅹo-/?,^ar)amrTamlĎÖ;7s-HlIܻ%̓箏M8]۵mQ0vmyɒe8}~`.6M:y vmgz V>ngv*jb{%Ԡseҥ %0Ԯ~8ek֪m5U >K.K XW0SGV1ah,q*j'z{fRD h~dN}/=z(toHI먚IQ5;`&8 WH֏jy@u:`~d@IrV #e3ڽgmW^6r(ս0ۮe޾FZfkؗ?ds >w$HXF(G29>&Y2\`s+L_d_՟|83Qs <%XcJZ&(vҰΜKC?d_n 2u0hϒfb!I:ԳD6u15_-(Nfw}:$iGUn6ҫ&[l׸LiLl*q%yV #gk\oEdKIև=C/n\k.]5|o|M]X۹rl`y^5n襴Ew_X+ϒǒz7քKI+[w})ee? V);'}qe@}|G$JVӸ}]8x$Y-egՔ3Y#4sIm@qzI__k#*1Ig,Y/.FzW of3&U>c%j7$*!A2j{2vҰg jU֚{c1[O\#vr%| ޵K׵ޭ~pzjnsf4 h39rBwss_{a6T[yܪ]/skzO;5J$잎$_ EVlv~+6ҡ^6}\+8GhzHcC ő݋ZI-`,ZBqLzw7^VNB,a\]Mwݫwhu7cP]&U8o%D3Nx S_$g6ή1Z=FL?Ƕؾ>I;5 RF0^#֤nIŬ.'uqv[-쪝S^ݻVTҷA>Ƀ=uK&{8Dկrj~q׵^NUXNI</%#¤zuϯV;,-JQCxw$ 7/>$"|bϒd1ddQU0I;+%S^/I:}jy~}Lϯc;,qxHVֆ|8Զ&%~Z׉h[^zz-%S$Yud7k}=֮fj*a"/O,4~X9?/yL]IV[~ԅ[Lݺk~ݺ ?vsj#dԕWȘNשd5nW%E2z%UO֠_dנ_d>2zIZͰ$`gM׏ %֪ygTx,LSsdXQljQ%9˦@ôz QqzΔʖ:f#d5REujXCOFxAnɚ_;LƗdMbYb-)>+KD)z; =cF`: U I=ËsAv$aڽQxrQQ2-iU˜Qw6V  VEzڀ®7 7=W%ӃP5Yی!>~A 1AidYR$?uXa-+WCQqgG0O720Y򳤆=[2IyHIKT"t@CQ<͒0*8(:v]J(<$HyIȰ[ kɟZU*YbC:DB35VEJ[T5ظ2f ;K}0&7I:CȁA=I>yUySTf 8 ?3@gS:p^*~yPBNߟ5ۼ{hq twE~+#W%`d[+(TCQdÜ{wKҎ|aNF)'N5{`%GY%Q!W%?KZ"YgIghT& %MS^/&e~ɒz`io\_@iQM~Go%IjjA|-n;̷7ʊ=0IF&,q`1}&GEu!%ƪl}ox!6ZӦ4u?ѢBq\t{[sn5$oMȨX.rB9 <5.r{sroT쁭9K*a*.0B+ɡ(k2 n(8BDSgiDeߑu<|IV'Y&zY8_)6[(D%v=q9Nr/,Ƶ) ,aV1妟Uj8KlTT;g)~C_QSsÞ]A aQOBWQOHBגU%$]>>InIuF#!_I# KJlU0ȣZfXPWRPhY2G2"$$8{f SW=IBoTKAeuxLԨm-KAWFw+ gZhW&yIV]dWfU0_5]96K^KF0hF$W%JT*KX~Ntf0ȱQ% DiYxIV'f8o&+8w0hV6NrqPђY e8* |H8*|De$% U7pG2LGʍ)q^  #2Xfok8m gլ/8@&!d?| INIIs|-m%D0* d8*%678f8ʤI J%5VYT7%N(.#( K[T17\ Ig e' RB;:o G!{ q70`eH#a?H@: 3>ڳڃ fo;9{$t=2Ô}l[foT8JP_qHb|} d(v˯n_V?$yYd]]֕-k $D{JᖓȮɳ*gAG~P9 R<9{9! S`:KȇZE}W uu,Ժ1$樶`8cj6' ଈu,}+IpVbQJN ա,HԺj{&(y-ItS"|AFr2K%/Ci:lPv8WˁY F:KAMpyxjֱo~&=Omq8ۯ|8 aI$o)N}"Or6N}x!S=7neAۚ i%Sp|:j~_kz̪Fd#`ԷojeH} buL*fICBl`0+_ RZ*"Zl*xDőͲ,G}'_eYdYnqjG^Qّ':Ķj ǜÒ&jZʐf]gٛ'<YUf)N*,$dG8.Q >{8R=%aIu #/FvmvYZƩڔ~ woV`z'6o qÔ~IUp+d:R"T8R=AbFksBbOסC~Ow$Pylu>k\rbzj( yߨJo]:Y!m[ųlē8_ԍK$cKd2..sV L(Jv.M`U1ެ\Svo,l޼UG <5olSs9fEڐ(x$$p%()vڱ@ gr 8H$l%9G3+L|a8DHrHQ*Z/p8F_`Obt#dႧ;YCjQ˅3!?φpʊfeM!k(QRZx_Pb=rS+ 8)IMQVKA-+ cQӁJr=~RIzo#Vũ43dc =5D_neS?Ls1KlR XLPc ِu'a&kISc~*-m>$G\YC[% $Ca>*])7JlVJ|>"gI 8BhuK62\xj^YzPYb6_tp_ jڋAy"`(/v~UeUVay3K]] >zp3+6TL뉣1eڧ~eXŋINIXҗf%}/<2a pQQcʭ[ióE2M_=0/:SuA IڧvP|-q1g/X;;u(:" ˳q r \ΒyzP/&z~ ѳŅv^ 5 `YA-ʸ*Kr $: ʉ'&;f1FgZ^E#|Q9ܒ~as4gIQx( }JQ&.*F,bE,IV=GX0bP6F!=֬KJ8eʽ'5Gu4ieYI Y=(d%X҃M>I+V&t+ "7/ɒ< )̑%;n@䗩 ^%ɠmg3Khcu?䶤W Mz&k#Iؠ"y,ٖT죧TNEzK2GZ=YjװݩK9zKvwK*<(JZ.]%1']d~EloEꀫW)x!I:ĕ4OQ/$/S%y@>Knii(F%U0F*'InY^v$ P~%JhVݎI.I_2c_`_:E}0dMҎ`^U]|~CeAY1pd~_82^}>/¢p׀/¢wPe=^lڸ/3E b,âbSXsh/0/E~Fy`WSN' _>gshͩryB/nNY"nHB{|]*)V`t@sd/*a*a;ddoUq%%JxyԾŭ<kqeU#Y]Ú |lJZu;ȹc a싛\?mW-7_{Qち̔:bqoP2wbV;d ÷Há.`>#dxKoboq U o8$I_gdne]8drl:q΁dh*#L zK2GbZ{q%t[u%@.*`uNI yM`*q_-S%d2^~CNk٫-U/1B$9pq5GՔq~d%2*9zdYQ^cتth20"(,ɜiP!ir矃nY% *yjR~Y%ުֻMnRb(aCY:jgcUE,y-Q5f \KWɤĚ(W:/Ik5Bu-dZتS rIV[b`q5%5e(X\$r=׺rIn?_%Y/dU!L0*"R2I]U\u(8U*3.jl>fCuuw=XATt. Vo$ e$+g&S-ž&(nqq wƎ~D i:ߪx#˂, Kj}o"|qY+T#Y,Z|V}nRmG =R?^dCKؑ,y-0/=Ò}%&Al|=jC?UfT}h ޿,Ͳ+) p3q粷Ly :EȢc 32NCNdiS=qՎn ͚%^ rȋ>IXI>1OxM0AA$38L2t픛;R\6z0Rަ 5qZѻ\z>CbAYvBX#ڣBɧ涓j.m8\>68xrl̓b[mqP& 텵9`*N!9zmT[4[yRԝ2Hyy_'/6OS[P=5vNs'^J"0%p^Jw~ -̚>l{jn7VB>`綘OqG }ʮ#317|jYۋqM v JHm7vVgLn%Sp{6]I -c:c8%ǎ;/vFoZ 6|jJpꩆ oC8)x,,%l,$^ z7WS{!\dvGĹ1Ssdn$SSW6uO]ϡxk6uCޞrGo=0zvGa# xV`e= D{i$*bI RC[v̩|v/ݱ wǟ+J@A͝NۥV>o'HMӉD4vQ> 77|:Rr~ddL~&a#:R8q_2gb{$iמ, 7]jZ,67|j6y> ,77|0R,C;$"N $( σ|JLI rs3D,EUT5Oe{ȧ9ܻcsљH1?T)sIrɄV̇Wtk=OS1Ix,ZH%w#uk>d.Z[3`Ȝ).cSv۽vo/ @vsHڻr5Z/깷XW+44M^rHnzO-UyID܈yUܛ)mëZ=@p2;ejc {nj]n,w莔);/ƁwtO KQ]{Tj^ʧ`m#Rv ]unW*b^sj `+8Ʋ 9gò&g*Ӌgs;S?d= v</@}.om|ƒ4\TR潚%˝֎Ƹp2{me+o%"ެXݙhݛ\o[;xuJJ|6Y93ݻ1ֶ@ ؟߇̴- q6M:xaX:bֶ[/Dm:vcv{ʼ/9YWKp rך~_H/HL^v[ut}uD $=옵yS (\78l?lr?evez!n%?Zp䔄SYK۷VR0%/sPz H1?;3M}?4jK6h[#Lo9q^8g3Q8P/[N*A6K+V!SÌ8~u- ~M٥ D \8r Ln?5CL Ay8m-K#[3ċtkKa& Hszsn혘@b4E' f>}B"f6vЮ|(Kw?`e~m+ٯsfxmmcu K˹ֶ/0ecrس4=0͚ݸdX+۫+۫ R lQK]mWYYp2KEH1fj{VYSqCέm_ZǍ<!OߑAb rVWmmmV,}ɹod[ooHP!{dTY"F 86%HzcMYý:9|i:/%v1I<̖U0?V'ggS)zP (>R5=~n,e>足>R);?-Sۋ|dӻNAwX^NZ`݃ ^y rAܙp] w&K/'kΗP&>HcQes/S#ʱ>N44Ϳ8Z4ϗs/Dk_8J^Z;tfX(~ %R(kBYܧObxq-~;67SNU@roTŽ\iY[7|/olK[y[ח7^kWw$)۽V:7*|2RjOFu[QABYe1/r7*|if;elfC ~n3}(ďdֻzlm;- O 9F {|[A:pUɆ|`e5m›CG1A:L"wkcc| 2"چ&;)d[}Kʶ/,KL xz/IWg Iw~~12v -,lDQLW"/Wbc!,$s[ro I{XSq™ΎJrhvRlӹG4ʕe/o`/~/~y+H—kY,o_}d8.eA5-K ,KcB&/UF ~12c&q, cclCZ8XF[8N)d}h谅߂ÌHX],Cf >Rl=L)56B}28XInx9|ܟmv)V _孫D~$s c ^K@zX!YeAtd݇fI'Ǡ?yx+߲);/QYP_)oє0O$u@ɯ[\2rb L;R.Ve?S|:Ty;.[ɴ|3f, i=6# "AnFrBs7ѿ w> eABu$Cj;B!3B^Jg&;)TjeI+=R SՒ T^ɺ?5ȱS.CLMn~LM˂$뻟]Bw*;[$nAɃǸicQb2$L=-1Ģ3iTi& 0{їxI-.}ݡBmAc{|{%!N1vc8Ή9/TL=0唛_dW9,k%YYE  )OSd)Cr+StN;/Ի+BfΒ j Lv0ǒ+$%w&CxAHa'H(oS 3nzY#0c{5%1an1!)/AnF:_ kWL_eO|EÊ3ʴ©fZSv n/nAb e/(J_;?Hsw0v2]P s p"$}TɺRb1`IN͔SB NuxanS`X9,{L`Ï{\82NJ3CrP+c=6oIyߤl nSȫWɝJUq>SrUh+XBt-M O1?jowSv^tn֑ـ(aAeL09$!3B.(FJ}(I j1BK&HG)n̘PZUd)W/mwu"HJtvӁPm=Ac%Խ`qՔ:3OrӦe*q*[SC{q`qrw3Os` l Iu?G'=h/2L!(g9-Ά?0촄; 9CyfRh[b"$\|}k,FABW|2QA2ᗌ~^N?)Y! bAFwW)h{ts~)~>LR,w;sh2h|ۋ"\o~9N![yA!KtA&LKewT AZK`4wx߬:1lR8#ł>rQvkI>0oxJ20,?Ȼ|?RCKRNJ Xu5k q`?Hf'#~9%m)G_n5 oG=p@^bјkgDkh}{vw5eǔUV8X__9XBxY%Z7îp*3}]P 4|S`Oᚻ d))?sdIuC5 dǬeH96>!9qᲦږ B)*ZG NiLS:Kr>3Ĕ C7騅?dP̀Qg& 6CGbO\uZ"0Le) Ys@j5̏G$HFLF0uJAL7V )eO6LU /.rv2ݼa& @$e%m䋅#myҠM#HzYb"@$ydgdڑif%AIڸ  CV݆i4i3'cy֑͇yg}ߡɯvK^ w(A:ʤ@m3[;y E ȝ-ywݘ@#a eV:i79eqoKZ+a O+b(nt  i;cg 9iCb$d"OڑmGNợxw>Db Y{Ti;钝?гbj&+ #@ۋ wXCđsJb1/.SbGHH@s4ƒy:dr|Np\0?)5vŦؐ{$ܯ4H#t  o'b58[n>ݰnmggm&n. @R#CAȹI^ӃyS\)f @ugp&fz8͖=gMB}aӁnǘP`tMOU MO69&MO5 ߒ4z:=i8|{m8L`#ůP/üў>>&X4۽5|߶h|:k|wh|*JC]P6, y{mD4И0m) k9v (TpXG Th{pt.7B$YiF8RdzF||[cSِ&=M.RH!/}od˜G |Jfȷd4jʄrNf6%mi/6RT511,VcIپߡ^i `o]X/6I`/^N}Kh_X,[gIm&)4Zð71<LZ^NbDHQqp)fUs2= Gwz {g$wcfܙ{% SnZ@@bE_/M祂8IdKBd(h,V'P{ríȼSbX~b'?o ~HvmpW(% -uGINݬoWz'->\үvK{{ ky; |Ŋ$ fz cv֞$p瞚DK*`ȷs0iy/9˛xb &ޑ5:vν ~Xπ`vf"~\.3=dݖB}496Ok7 y)z6pۓFyc&oGϡzpnyp:COUBb #YpزT,{ugoL P޴&tu0ù|aP)RmVi9_1*%kO(s=~p)7wb)p_[ xhY[ ZL$p] ,`]䘵r LȺShAVrE@5zE>rrDt*&+y?lAA|9L |A8bȝW=zxa=up8A%Cw ){m/4귦I7f30w5"N.oQm5v;V>n^?,ɺ]bBkα9ԹieʶC!@%_fCNjYၙ _oo7SNɿSʙ]nJ~)y_J)Rw~)eup~lw~yp~{~}p}>o>o>o>oˏoˏ2?/?/?/???wۏۏ_q??ܷ}q??ܷ}q??}q??}q>}q͏__Ǐ~_Ǐ~cI~_҇Ir>܏Kp?/>Kp?/q>q>q~O׏~O׏~׏~Jmk :Ґ B␿k\%C>J9 D.Brrֈ]-orV]/os։]1o%sV]3oEs֊]5o¿z|[.w᜿"W[0w霿#[2w5#W[4wU#[6wu#S.r:KG.v*:G.z::G.~J: H.Z:KH8g_="2 #BK$R%b&r9=]YoAߥu^V:/Kwq5建ˢ]^eU|yYW+,,%v^Vuz|yY[,.ev^V:;/w|W[`w|[bw5|W[d\/[2SΔs]\sׯ碻~w]_=.3Ϻ[y8ۯ{\|ozܙ b YMrU_ԂWIYhLiҖ ),f6¥"ҽL##eT2ʝ )w8z =#V"ԥnGM%$9WH_G$i:Z58V~Jv%,$΍(0FMZA}F :D_#HڧsP IJHZl>GOG>Co|z+~D;2O?p!]U2#9/}MDZp8jOYԥDfȵ0«܉6ƏUM_͙w"!Fjw"g6rk͎6rkk&7]#|5Ѱc߯6W|OnyA+zClcwBV7^4«[)v}#ĵz[tJB.t. {l޻~}{|{~{}Ocݿi>_ݿOc_ʮWvۗ߾]/e׿}+_o_ʮ;o'o׿]~߿]/u׿__WwǗ?]]q?Nv߮8'__ڮv痿?]/m~k__ڮ<_'?߮:_'___wח뿾u믍sn/}_ܿ}߿'Ym?/i7oO_Ʈ7vӗ럾]o瓿]|7?ߟ_?>qV[Vo|G :/-KKړv_RITwR$T.Is'*'vId/I/ܷO' [jp .ɽ_ =( \K| {(r3LV/Dp?wKu\d%}>,}O^L+պ}ouYv;7]dC}.Pߓ{(F}ɥ~}YtG1fٿw?sK4]W-ik]vYivYi^eY4+}޺{$Ǚ/%n]|~gr\{ 6%_vKrI|zIu,j۰_' Vӹ:k}p֏q9KڍS/oUdgV5Km_/Oz~ s3.]v~m&څKl'n>6a>y]4vѰJ _._Ï˸ߺ~I~~#}0q>}p.a}ĸp`.f6^~q\и/i:.#}qqds>_ߺ9Ql~cu꼎^:7".ܯẎ׺׺=&.:A&]_&~uWw0cv/w_ݿ}}|~}??B+?iO;ӮϛӮϛӮ}>wv;ӮiW+}/+m>ot:eﻉ.a//st FxPG \ft &G+^8.SE=Vr['Jtg3RJd]F%2eB|(ȱ#䑷_"e|m0> ֻ-xE}pw{'yq4R>z)v/nG'Zݟ`bC_n1n%к1OaR̰PBvh2iFJ/y*@t^o5=y,ʉJ" 㗹\pUsAL>eJ<!.G?D:5 r1"4pE NoD{ yHYnnqa}TƩ,គhvOD 'D} "jރV*E #Na ?\F(a~|x0O(ss1Gg44^ Q q9ނB+)kGSn4;AtrEΈJ0 ?+ urMC%Hȧ(5t$ { #AD<;оR<=?9}&U=+f_:YهF2ymJ. Oӡwطs0|~oyPo;GP+!>E<72;4ԸŬEl$zCi6m@{t};=ٍܑW1/6:EnPIgN\{bc7c8l~ornHo[eds]OZsvJi~*Z}J=*ڪeC23t }w9"y(;@GjF?9viza! ,zaz`ՠ2h(t^G7<-5BMHĢ诨=a2>@1 p?*Q59_7ԁa ƒѭ sFB#};OC>p8uis|s<ߟ>Eq􃏸 ]n'Y%<;& :!x^2s"Gp}4@w'C, sA'on 2n8.zE%ꁏJ5 8M/cC{!텗NеC*}s23XHxoVBB;N:ܡAy(kE[%r=U9Ic5"k+Hb\1C~z˴^I*z(`y8OBrMBc ϱ)rnhP䘹g 9ؕ-{2V'wۏA88<8:ME_Isc~̌CEk$MP!{Qg5-ÀiMA#lJC*L}O?xz\ 9~,52W@(F=BΫYK czX󊯑Dp RK睵4rҐ4(G 9n!cC"ccQM[X89=PX 3f 9 1~-r[r2ŞAΉ% Q Q!3T%\|81wquFW=C r>Tё}Ñ3yYr!|/a킲ԗObf,Ӭi9!,TvMZ'L%6OSj2m* . f!xbL 9̿1ccP; =mB o]"s;!9/zChsExr ?$`=V+xNFx _;Fd'm!)ygh~j0Sː=Ng9ՅOnnX-.Է4$#mOሻ"zr=t@E=7!H\rd+(K;hAAy̘ԣ!r>7"4/qLX/ߋx8fccYMF``9QC[%Ca+^2I AO%dؔ2\H0ե_0uV4Q9XiZ' 3zLFYiZN hI_d4TCKЬ.\,o ҃n83W18F3ش \ͅ^TOͬ哕3(|ZixLԨ0h]L2p=h?f<GCgp<2X9)w`\pex,:A`&VSN{Xͅ\q7Oݺ1 Y5Ֆ_jw$)\?+xNQƳ "}^жeܴ󗼰r~6z5-j)t pNIؚIPOrU['N*n6"4j@iY6}E4aΫTR:s ov?M]I 9oTgƼs%8^-&>p솜RPuO)]E"d~V̠ƜQwKs :;w~kSQL\%y&n-H`,G/ñˡ˰{sF-}=G, k9Sw7-!\\gq3rth64E78TIĎ6po>q2\Cݛ3!͜ K4 epߍs^KN[ zVyK#)v2bO@wo>؛3q97]t斆?nnç k!_ #|&Tg)zB%P=yl&)ٍr 3 c87d AFǮ0S-ĻqO10#B-k ';ĬO!HB_',>!za>' +3<򉃞v`䤧D/t. .%t18Dkp2r3/{=~`?(L5@3d+F;!H|jV|DqԞY 4DzFٟ/X˵[q W 6f}/4dS?=ȹP3pXvvnq4Du cKSdvIQ Ᏽ0r^4'Iĉ|ird4ƚѻҦUÊ3rlTq39onŬȬTEMy$ 6-G3 Hb܃2ؗrPЭ3qO+?: v W8y ؘ9XwMSr6n~1/8G2 ,&^G;~}A.wo#˅zΜ3]٧v]iɴh7;bSC |1XB>qB>ȓ2.}Jߐ3r^iе~&(\Mco̵؛KQw;GSP:oeς)3 fߐ-|O5C]yJaWR8Պg]VЧ,3j,oaB߅>MJVCε =L>ƀ|,ՒxP_oxx|}xG[q F6'\5uQ@(ttQFRαx.Ekݱ ]CΉԞ<^W8iO+vNZ\k|i{zboNxǨb.AZT?ߣ?\|{M/{O]޻6zW[󮼱7'nc'zs\'^8qONbg ;@yl+~`ɜM\u[bb_OD/X 2cG F~Bk'o~fϜG`1Uy̮|Ξ^40nY Y˹y64ng0cٛ Ϛ ,<; _FG5ju=|^;wXKh!QLyZaŕaP1O \Ǿ7? zHwX| eG&٫ ^C tM[>cWO85V3﹞FXQ|܌_||G|e=+mǎY_eŮCrdZPm9l cɂ0lk%2oPP;+,e_CFaQtZsf@›z1C4/O9O3d1r^.@̻Fb "Cr?2ZC7ZC?x~tc2 r7#z{N qn62aGĕy`hKpʹ;Db!_ތKv>mGCaȥpDqp976i,lH(*?7r>= nhr 2Yf ov,nH*m1yaƮ0YƘ7DtoǕ/ w l29mOHOahۧQF]*b\s2vw(#wX$0ʧϧi}>g^|@s")FKw:eeNrNd1,2h/wm ŖsUry9؟]b[2j yfV7rZYϝO 9 Br>ۧ`ËD:bK1=+n vFZ8qrNLpp*-z} \|l^U-Mc3(8tyZXz[tG18;oD7TȺ%4ppy3l48AuP#>B&288f{],w?ݺ_LM~-8gn-ӨGbn'zU9$΅҈~Fϱ?:{^j#f&)8fUppu=eWXƻv\}:jnd>>ꫜ ?'=8\NiC\h Bi!Ex1[Wb۪/k[q?r08zn"u_6Iiƫ|%88qLcEtͲΩr .Qrc?ގ+eqpG[ƕܳ0P/; .fBc=O!~11KZ4,{gB12 8>:;+;8v91I})vsAη驾 /_/sF%8apƢ\i廙kՔ|*3 '=^q^ө_c0;88#ӈ~2h9qpofd+ j!?7\7|88Y+'۱[;Z8y3o)9Kpp\q7Ax1:ń.Ź8.58`==c^N\(|˹(]nq†kpP&R`'kE؟Ċ !bN5\k8֓_?f]Y{xWtv\-\338hI7ppA]TGχvѡs@ow.T~䱀)yI7D ׉)n  O,ܝ,\h#b½i1_%[yB Nt2X n fǪY4D"  78_]mI.,\4,R`{9?WʖjιUհd3:M5p;|nӐUH֝@c `;,\}{{ZRboPܽz]BΊ ǮrcpqsRUfpiogG*io tn`և9'2 n;N 7@վ =9|pI }).oh 7rO d j"g`` 7H`7^D.`dC1#X2s로3k_P`&n .4}jF}|#[dyM,\_L`gaw }ȀbV3]s02:X\ .fezEr2/ýh-FN\\2X …~۹xMV!pvcX n epOQ`nyO'n pS񤖞)G{SpMݧ!c .G{ ;) wc 7pLnh 7șs57/p,ܨOت6Kxvn91`Bk&?况V+& fBp]] ,,3X&! Mse,\?uVvp`ƍ`B wB,\F}Baz}h1Hd.z(`V,\a4 [K\M8WZFͱ9I.w?Y$X6YQLpe ^XyG/ k1\jjP 9gcY,8 n& pc+ #6}~Vy#.Oގ(n_`ƽ xM1pg  D ^򛞥[+X1µ\-L\qVXÅZb{8&rޱ/pg)8NGb\pd =piWlu(dP<\ΦMg&1Ƕ{KxXakm2p B nzhc g pͰe .R`™Åp}d.jH+<ǙYr<n$<o\Ez;kxEh&p&E=\J"i5gih; O;J؟s5k pno&ѵ3éKj伣;`~^<\.9e3v8xpj{vp yx~j=_p ah;X?X< .:\}БE;KyƷ=ՖY<qoCiά^ ]@OuN=0M+ x_í;}a.d{0Ӏ8DÉw0Á뻧Ž_ÅSYCS <=-:4??W<\0۪f.Pb&nP̻/^u};&x>Y'F x8<ܼ[ZF>X55pMDxM ss/}Z{( p]m<\7ÍpnX <{ 5) 'ث1õ<\GX3Ӏw v8p-x`l<\p{G !pkAkCp1 q؟hKfO̞nio<Å\4aBxȏs5gp=M"dpw }0_-h꛽xgYܯ1b_W{x8gp1VA: iȹ:+xB7[4KK]CoM~AYWndb4 }RyAK}\ 9rӿă)Z w^|[~7 =rSoqP o-8e=GW.4lKG3XڋdL[hPr7.f`8`=?2e4QpϽ{ gs J;\s,<\2ý6N}LMs7\?ߥD}.\9)7[#K, R#PEioh*.Mܫ+Z"Iy~z9//`C H"} oqc~ Rm :.s˴K[9| *B%y6|#<\쥤wc/i Kw(0H|_(N.+BOWOp#KV?wJ~^t@=D79)bKW9 xq?vxhI=P7pҕ$Ҵ17.33x8Up5z;`׎/}!S.spjO[MQ~>~ክ f+ZK1;~0?pd 8WjY<\K֨~Pr5[$?XCΗҕAcvGb2e ʻ2 >n<ܲFnOb[z5(l'qWp]Xi¦+pwfDpP)Ѻˬ(УnP wXslE<\<>Ŷ$Z7cE}ڦwBeX4މypg(Dtp<ܸVw/{I-sd8&~ x΢_8lEp(ẹo7ꆜ㡠[(ZyO9SGo!{?*J>RYÍ}ޮ~5)W̉Ԃ[bJx8`x%|év8GHk`oW(AiqL<\L_PW-d޴T5pE<ܡDy6/˻޾ۊsǛPo#gp# ՘õ<\cZ)4b+PP7 e-r>Аé+_R}y/\G:e3j7^ 7:5kxWf x?"3ݙ'h29cow%gp2o:qZ/J~{.U@S#異 'gfU>eiiBu=<܈%J[r_+sN x n<\^{;3~nT;\=s$<\*Ɍlp}<}}ӧç26}r<[9'Ep)s5۞})o~/~wRy"d l!2#NfBdh9¦LzRG[A2爇[GטÁ,VF R(VoO LˬeV~ 'ΜbwUPF1=U;UG_kxl*ڛo_ >g xCJI% 0<(h`r-#PݥЯ~~ WyB[J-p4CoGÍB&;45Dp~ԃkJWspx5zr@ ގ߲±Y +cWpm~^pA. Íi/{Es^݀1/;ϧy~<_%Qq#7[õ2A#l~*{!pcv`~s"x R=?O ÅпfoL<ꠅ8?L׸oP +Yxj.袾oMb~/JozkW]õQ \U"gp@C7&O(sJy7A13v8t$p<=}ϳTgEJs/iO)fp1_PRKYX(vwZKΎ<\\ +E<\ECnY7<\`bϷt'|Kw(W&s㺈n\cm_b=g7#KqyB}=l ϻ?[}xt7L`z5EoX_sHp[?1H?bx8vTB)z;8nɀO)]{sJ{9ʊxHd=_6n3s0<\h>|4t8_pe >Ђ /:u[R<{?phiAs}í6"M+x8n}50p{[OKžXV.f Ƌqn6V+p R.Y6n"ߋxd~7e ǩe_aYNr~> {EpV+}q] Dķ/sAgx 8V&}q2_ x,+xo8n}B{~n/nj7XYÅ2"ԵW)8 x¯[/zK\͑8;<#7b ?acaќ[ ֓tl}Ih]Qro%nV,wƊX8p,23Ķ3> 68Z[,\~A܄CP) ,\'T2Nibm] 4Ѡo8Φ W,X .f[+;١M}mSt,\K)pN,\ǂ~;3Xع,5-kxJQ,\]ꁌVס?i??}KFvMnXޜ]&X)z78ȅ;O`:wN*ctx'[X:y)X 2LnA6uێ 㙳 }L3:{~o8<#( ,zkXN9X s8é] [Xб޵F}ˣza  . VF)kG枝7ܰȼb­OCA`p ,\hw TEHoμnс[_ Xe%1X X\%Fc7/,p/{P,sX5ApS.pL(b>Nc  X )hS_2) `BS_Pa)>,[ ۜr%c Sµ'}F{'XnP0#o,ܣC1'B|Ū%rB9g$,N*r>n vD;gj:'X4c0;Gp1RgjO@if9W6 7PMw`&X"{,\=]lλ kya֛ZbdO1 wc./Jc-U?"gof~pCϿppز=h'q<pp󎔀 ݍ\,3xvD9qpÖy) a+tG:e6>Vaqp38˙:k{`2Xˋ_!OKܧ-y-EߎLdy88<qpI+Hni/)kyBu\ ;8uwwgl`7P׾S$hq ҏ 3h O'&- ΟeoPl1sL|jڞ} SFm7*cjU[#Ʒ"ߪ/DP;&mIB4_NE]V}|\YOpKM"?#h wMQ7_G/9#89E}ݍ5ne62b'/4tsU^P7WWePo`.+{s=p9POQERE7sXPNϰyִѭpݨ^+^f9A:sðzk!AaU-~Sѯ&m9iVN [<)RwȟY(Dj$G*'g܄FB}:䌵F5jrAXTb-1;hUoX߰BTbkPό!-Ů7(Y[b醇* NUo6F@łSVЩjD -~we5%VϢYy@(喘AŷZE%GdDE RsQAEf6%6gcx`=clh9M[9MFN转?'i'Fx4s|߾GosG{gk5<[#wibJ}p/`U<[><5~ Ε8([ŷVb\;>i^'W7JwJCz)@{з[^ˎFkGcv˖m2vcawƋ!Ro!UsM92)-#؈'QűM{ z{UU͎|$UnfEJz'6r-nDsVc1l-V@4)?*VXvSl)!Tsm!f@Qhz}A!/  [+(Ғqc OAU [A5<"VmjtFw,ئ{{`Uh!`^jپh-`FbNݱM7ErO7VnXLj{kfO_mZmIעu1"Iįj2/9qM^kZOũTpd[h>L+H3_4x^љЖO)cTlWHk ;xA+r~qo*[KQ^ʊ?7n7T ~՗߲]kZkݘPd~ElW{Sҧ> dٛx}`q?+صGd{sZkJb7iC0m<Ӧ"#3VPpk >P!4 2}(n7O'e,ӌo!Eĭ [ny}5Apk Hipl7U?neΔh:S(qvУ"UWgZFz_q=q Hg2h'4<^`Rū8򷣑2[j4RTr78a7F#s5魛Fno)29S=gXYLezJԂ8xz_dzK]ѩ%Dn :5|VgFzSEqi67 6 ҽ}7/mLnΰ-Y1ԓç"ҨhŠ:n/#2ԍSfXpcs nU[H+(^)BquQ-#P[k MfG eH#@_@O~dړffc=ieLˠR}J6HUD`Bteɱdزɥ2nWeb˒Ib[Ъ5"T}%ƃ>ֈ*P9jQhlYQ*ززE`:8 ,([꼶%JKƌP,uKᷔnDk.20k>@Wc⥧-#z5( >Uu@Qa. lY$lYH][j2WÃAW_*3"ት.{%*ŐdOuOup(S-c2) ʷ$E2%a5hE` Z[-v[ XSֹ3x2χE;6}R;0'DIjW-cX7@^7@{Oֳ-m3\IΎ$9OKC?wٓ.o'`*xiHsoNOVrxxN1_w~h'L_ʎ]j-e~v8'(<#8 ~ PdŞB\3ZU׎Wd.YqFKHqF%Ԍ3Z7(ʈo%+|2BSn7sG ?Dw@ i6Ǧ_O?,4m)mm5M(baǪLZnoٮ4 r1nxn I ~&>xneܩ[66e:?\j͋8^E9ij_5N~8mizq .(V}t}w}Sj6=P͟6fA7.MjDjT㤦S%D<Ē,qb5d_ j/}:y%Tޫ5LUx=h&9NG;}j|{ݦO<;o(-8Sk?ܘOl7? ^!'l7G&,6P4-\7Gr= \ㇸĉ:y!1;%;c=cK4cA-(uCӢP봨>8 *4=M\f<>nPs}3hGr~'#}R:?{(yO?¸DO)`E9iOߒ!=-5hAEQ乿yy}OFmKAQA'O~kO*s>XmH xyX:V~; ,Z,(?+x~(u@QʻR t}=3fKo9l(F)1JҼ˕({ٶ2`eo6yF|mz 8glL_& i ,(Gƹ?KAn5'^Mi (~R;a#y[ŞDk\# j+rǝ>bi3Oc8\?X@O8r`gXuN J{=2”iPN ێ3{ YPlAd|oJL)3(n"xChƍ,(F2-֬? [GI(WiO2f,|J`:q"Xya3fUܘ-o F3f(g͘6crMuj!}ӹ#U|]!dDi5}iT}'1C_Ȝ1C_k }uRƒ `w4YWjR>Y|Ki5g YyGQ$>Ҹmun6f0ͻt3rBkOrb,W}'1Z>̙SӨkXΉ`G~C_@H{/yf|Yu|7f1zd)H[`k9k`:Z&,r/ڍM-񷽏î~Krƈ8~F>4v Lj }33[Wܹ͘k;f(3ʎT74 楪ocY<%g* Y|}6ckֹ{ԪO#NX]3^ҷ۞78'=Z::Q[RŧԁQ?x$d:7xM,w(|F7ļkG; 2k7bFm;. IE);;f9#xk8hc ˀ+dx]2/`m1^(ћ Y'qoֹՠ(o/2ΞY7S VW hAFfPn.6rn}4ѸQ@E[kLKz?kA\mAe~A@F;,@xl gh ڸ1AmU]Z6n3o 6Z~l7ɧ gS|tz kl FrxJSC fQ_4@.>Ucqכq=d͹XWN| M̾?ӧޑ&gg⇣;=MhɱS4r5> hsmp^66 o! {`A fhLP5/c⯄<&ofPh#c6Fģ_4n$q.ӌ/(_>EEF􋆗-(o $̥D LKDxj]o)tZPh8 ȴ-((Z#Q[hQ -(J7 ROMe HyKP؁ARZw6 z"Ђ)c-i5~"AMӌf|P|/5h "rk5hshK6K ߣWOyZ#պ"ׅKhWuEAE"]i]h_ FeirWf|jk orY H&v6@EhqbI0>h} r͹^6@ O@@ =@ K@ |k5V/en鯓j;!ձL7,L]*A <@Ÿ 3(ђo{%*6mE6P6(ZCy> fPh{=GX   }Mq L6@ OT@ZPs/F;|-e%bFǢL䙛;ͨxk;j'-%BHDiԌɝlpke e2i GAXTb#YD`2)/5 #o ˛AE]vY=,k7b3/=վao#ˏX;ȲA$z,;Ȳ֮g xe:TFԹl ffs@ zڈġ ;v༧8tgx'EA N=:vAՍҐw M_8.Ed v;x#v#@e~Q9m7b9:hkS7Z绑?2R w{%2f.q68RO)h ziIm|kP|5A+ul_(x 3A nEd[>)u[6q㳝92_&R|0+k5|ܘ=S77@E#p_k{ݐÖ@z Սy&HvTO6غq8E^NO:x %\7''8G^D9]VOBMΙ:=lu!xB 1+L#E~GC<9.!b{A!#~W60dq؛ -؛ ؛1B iQnu0d3h |'{tR+%.ѐF.vZE+L>|x]1=B`_]VEpcA&1a:IV z*Pu hff76Iby-e.s!`&Q :ر(&B;6368ۍMǺnM8ucmk.(=0c!Ϝul⭮xu0cu\! gu0cį\q6 0cӭflf4M0crXP %˘َe{ԃg1nmN}:~looPSl ~,P(y[^?69]"gCŏqfDž-#?d>|2~KK2^> Hc[QU? 2e`70f}IQݧQFRqP>5 vl6k|7v`&w\I;GHҎ^A`&z5G仳;6Mn2ucr|'`&'n\;69`&'nS;6ۛ/eP_-|7Gq3In|f|ƺf|fwAz&ر '4WH\drU]YH'رəYeU;69a`)w X|(1@)2+G;krc_3n|~lr M<\v,~SxBՑMupcy#@fw"ۜcupcdn7ߚVupcHXPO(`u2fG4ff̤ EZܪx?s769wV"jk&;I/ BIVo@7&^ݸqyS76nlh`?nl⡮|Fi7gdXP|s# PVhO`%76399S(Iݐn\Mujvj_Pĸ܅&dR769Ezc\Mvje=8TsW f,~+(G1|A&̾ȟXP|lO cjNԜd;(ʨl-ӞBBN"2XMyt0cJ\ jIQh dfl׏"E NY'#W=EWt\ ܗ`"-ˠ/ ؔqmMzkbSiMSuciNSE_Yؼ#łm"܃*.< w{7>D/(4~&q3SԍyG;7~1V7|kLv ϼO(ؼ͏2lid9` 9sF7F1Xc+69WX<ͻ<;4bF/㟑 |NV,4`F/9#o-Ś}gό0~惽3k&'B CUwѓ_s˴(^lZDpł" Ƈa/69惾/69mł:(e5lΔh/6mG72XM;^&l:ə%^P f,( v(䴱 >z4vb1e 2v4lq3Rbӓ7bi=iMnub[A |i c J3=`粠ȥ+gMnubXEYƘ91n^1i\6-A'v$cA2 r,(2D2\6#oG='#;&&ac< XPQdDz'~9s/Vpd!xȂ,(ߣ qpd4pd4F rGB;pds.S8E_y{_K6C-3bU6A;ӢUx DY<ȗ{2]4:h 1Ӎyh|BU(6lⵯ,E|exSY2nlw=`mU6AMN&:#.CQ~U\V-TYP(@j@Mό@e.2gccrh}d-Y6UAM"uccG edGaY\!eF߇O)-Eh &q;Ȳ(y>ԂXDiueh<8 bD 8ȲIT,:Lo)eq,p\ c|)Ȳ2XAMR/ k݈vXX߿lzlrEq{4-k-Xx4o%[7G|%[7[[+88ٕ82tpd _~"*[J|<}C?3XXxc@h(6K6Xj3*Enlg4Ney D ".5DwRRi۔ V`c 2@csXPM9q72'c |g;TV[@ERP v(XPǭ |uc+B!+BFd2'JF$fQ?EDN=`V2lFw)ʸeXF=`Ȗ'E`Ȃ2>Ec1⥧D`Ȗ'BF\C-"t0d0dH J f5̟XVvՖ{J8 N#UDcD9IW|Rkhye[Jhgp@ju0dA72_Pz&lq! ^EaK].KD.K~CE%E#-CubV&M3*a %fV.CcE4蔆| "NPsm0~}\"of \!yx7(`";i/(Qr͝#%-%!#5Vc[i ck| c!r]m#|:rYmA{C(uoňն%r0em%r]vlq"UH|\g[x cxXⷔa/!C`b?Frvla3`w.ne!mg5^\cFlwBސkn pcADnd=;yd{.nle9m,jol7GMn,f4N(ꁵ{\)P\[l z!ݾA\w{Ʒa[0c1Wv(ʈ{[F`b|AQf,Ek@QFXPQb6-,F/U}"XPaRF4-+b +2E XXױVlul,(rFy2E{ ױ冢{"ӣɐUb cXPpdzXPLzz?e.>Eʏd a`b^4TŸLe ce Lǖ2&s 7mE2@LiOg\)cy!<9yLg/)wbFZ#SiB2!SA3?n ~,T%n5(FS`Ȃ2 5 l+$)|z8Xc UA5[ZE+qy' 3s=X/la'|- p`(8XP 9"VYS p`ܦ`ݠ^ bNw5Oy3[2 %x I|lf[Yi|ꊕy>g=l=- =`Q1H\dFl=j(ʠ-_ 0`Ad}u@Q7g[D`] FR >mde /k>p`F /[Y} 4ⶳҀ4@V[5e/ /[fEn_i gN z[`"+lq{c[`kō,4 ZRq4ם\Xs_rf}=}JOxa}=̙2P-l ~0` +JEPo)U XP\sE,+7TOkqKaZ4kq (4s_ _0~E^h؆د %!o^<_9wrA˄s JGf?@|-?:0@h` OeLz[|bpzWF?5gS(y0\/ Aj{,&6ݔVodCG \(76?Fi_Ā>To[2zhh)|A!F3 cƠ Jn6A{rA#nHi֠CTŖ{$'xp;Wczi9Oso77)Iˤ2m/)}>ǿI֙} Oҙ}%8gj3_RǙ:.Lu_ꨟTN~LM~K8S%uu^7RKf>S/uLmuKͳnRy-]6ϺKYt<.u[gҥn[mJmֳi]RϺ%ENԓl'gW[~I=zN-r;S%lr9_)VRP~u[ån(_[=^Kzhgr&R5.ɿV5dkYvWvd+'kYk@3y\oxpX[39@;p-РB1b' ,.erl{Ae( TBy eyrl۝\XO\/dTqrC3E&Gg?'2-ySvP(jCFE[Q=UA-PBuF<7fA2&Jc;ɕ oNlS]hNѓk6)izA%(J Uȫ9W-%:(_ɻy##y7ȻQr#ot웛y3Gp<<1g Ey&x7NK3H~}S/z3˨_lˠ7v~Éïp;<ԫ~r6z:Sfq~xڇe Ƒ1$bXmu 57EEEd19 *@71y *x@EjedBEѰPQ &֋y"; WZ&ViILďu(˕?lq7(ߡ/cYKi)/0sK+iQغQ]Px2mBQbpT*m߸5ݸ263AaoDX?.e'ўE{T7T-6{JPQÅ. SBw{1@ޭ@^Hj$-E)*<bL{+nzƀkKXu{nzܗ]fvb32Onz/|LnzQMK_cP7HW!ҵle-H{Bdnw(R)=hAP0 t%C$'kH>mp_(M\Aj,D껕ë|LD3r w]N%δ^LWiW7bAHgM.GU*uXY!S:StzHuVzDubg.|r8u~&5X,Y"5aFW2.vӾ2.V|b(g.rrUp;kt|FSr֨jtBr>rZ:rڢFWVe3QpLkgd肀g.j\/XWk'qޮUg*W3x3bmgFߣ9// 8ċtY e5@^YtENY e5]Y e5]Y e5JUWuh vV/Y{3z]t;+vy.4rV-_ gݮé>>u1 ĩA̫qB:ļ1JĩE̫qFzļ]NEbYzՍκ]TtKSe"ļhT'EH>1/D:yQ(ҩQ̋FNb^TtSSuhT+EH^1/zE:yQ,ҩY̋fNb^Tt[S"żhT/EH~1U=vQ0ҩa̋Nc^TtcSɘ%#ZƼhT3EH1/zF:yQ4ҩi̋NUc~kS٘e#ƼhT7EH1'ħ1'ħ1/G:UyQ9ҩs̋ΑNc^tjs^#g.jG:y;ҩx̋Nc^4tzS#Ǽ(>EaM0 Xtj WsP3WbsS Bpө\!+7NM M*rSBpө\!Ft#Wn:+7 N MJrS'Bpө\!Jt%Wn:+7zO ͧ^rS/Bp\!K|%Wn>+7zO ͧ^rS/Bp\!K|%Wn>+7zO ͧ^rES/p\Kֿpu8Nͧ^FS/u󩗬K|%Wn>uK\K|%]7g.zI>+7zɺ%K|%Wo>uK򩗬^Od]|%뢗S/Y$zWY^Od]|%뢗S/Y$zɺ%KE/ɧ^.zI>uK򩗬^Od]|%k\ og.zI>uK򩗬^Od]|%뢗S/Y$zɺ%KE/ɧ^.zI>uK򩗬y*u%KE/ɧ^.zI>uK򩗬^Od]|%뢗S/Y$zɺ%KE/ɧ^dzS/Y$zɺ%E/_d.zI%vKW/Y^zɺ]KwIgn_dnW{vKE/)nY^Rng.zIu%vY^Rng.z ]^RYr5u%%u%%u%%u%%u%%u%%u%%u%%u%%u%%usnnnnFE/uKoD]Qj ?9%7.zI^#ꢗ߈%7.zI^#ꢗ߈%7.zI~5u%7.zI^#ꢗ߈%7.zI^#|^#ꢗ߈"#|g.zIgݮ||rrrz>z@zBᢁp}&_EE)*_TE)*_Tra2m E)΋ Rٝ;/*H)g.*H)g.*H)g.*H)g.*Hg.*H*+]TUW Zm;S/u*+]TUW ܯtQAW_颂rE)E)E)E)E)E)E)E)E)E)Ugݮ*H?vUAY Ϻ]U~nWu Ugݮ*8vUAY 2κ]UqnWdu Ugݮ*8vUAY r*骂} r*ȩܧ r*骂} r.*H9tQAʩܧ RN>]T~Tr 9tŁj|AN5>] PSOW,ȩt RO+]Tz*]Aκ] ҕSJWDȩt+$Tr*] 9z*]TGt ROzJJi=z*]颂SJJW TE.*H=tQAt ~]T좂gHqvQLڏ^~]좗SL`%TE/i:.zI;utKک^N(]vF/dW]n;b@eTJ!)B|}˝R';s?wVNsK\Rh_zF+6ڗ^Ѿ%%.Wlt,qIbcKK\RXzF+6:^ѱ%%.Wlt,qIbcKK\RXzF+6:^ѱ%%.Wlt,qIbcKK\RXzF+6:^ѱ%%.Wlt+6:^ѱ%%.Wlt,qIbcKK\RXzF+6:^ѱ%%.Wlt,qIbcKK\RXzF+6:^ѱ%%.Wlt,qIbc}5rF+6:^ѱ%%.x_,XR-qIbcK..y,qIbcK.yն%.XcgXR-qI"cK.&y,qE$3%.Wt,q.35.֡֡ԥm]m]m]zlE^J Pxg%W+YI+lwzEqɝ%W\J6Px%(z k=^ʵK\RXrk=>{=^rK\RxKʽ/qI%.)z%^{=^rK\RxKʵK\R\rk=>\%Z%.)z|.qIsKʵK\R\rk=>\J*Q\rk=>\%Z%.)z|.qIsKʵK\R\rk=>C1z2dk=>\%Z%.)z|.qId\ʱQ\rk=^8ʵlZ%.)z|.qI㕸\Qx(zvk=>\%ZWr+GsKʵK\Rx)z2k=^@ʵ< Z%.)sK7+eH`}ld` k}nBꈿ;bmv#uմJXհqyw<whM8~q\;b؍+,c== ߘk_bmKc)=}RgI9Z&QE;zX>XҼVLUksƆׄ8#rXw`˻`K;4Zq&tB;V~_בKx΋  EX*fkK;b4#׷=I E "#z.  EK\Ƭ?[O$cI?8~˒s\1+n?mIx$%IKբ,W$^-גxKբ,WOΥ?OΥ?OΥ?OΥ?OΥ?OΥ?OΥ?OΥ?OΥ?OΥ?բ?բ?բ?բ?բ?բ?OҟEeӢgiQYs,9~ZT?-*K?OҟEeqhqhqhqhyhyhӢiQ]s.9ZT?-KΟե?Oҟ:|')ǒӢ:īEXsIi?xKբ,W^ZԶ%EOXZ~'KOڹ$%EmӢ֖ğ???EK^ҟբ-W<-y\-ZiQ_iQ_iQ_iQ_iQ_iQ_iQ_iQ_iQ_iQ_Zyhjҟբ?5;+K/]K?^,t-Xy-X}lR@ciX{>^TKkF,ZZր-1C.g->Tg->yXo=>/g->eޕoײcI̹$<%K_翖ğK5e$_ےӢiѿ__ʒx Eײv-KOZv ۮe_\-t-ZzZvҵ%E^Zvtݵ{kuײeK]ےӢ/y- jײxv-iײewqAZvtݵ.3];/'tӢ,]w-Y?KוgӢ,Zҵgk}KV?K/][,tEYzҵU{+{kKV綾K/][vm^صU{kuWxuWxuV뮭K][/]ơl%l?[}O$#c_˜ }ҵ+_VbeAi#^*.'bY mww$!Z\;%,l?i?ğH`_ ? ҟW$'ؗWI'ۚ Kܑҟ-;8ec~G{WK33Z;<8eW3ZWmğ}'^GwxpDko?2Q/-?ؗğQ7%E\Z4ʒӢhiXZh,-Z4?-K~ƒ}YOx/;F'ؗj|_^,?Kʟ1sI?\ZjKtϫJ3Yv%ff,F@c Wd[cNBY\H}2LQGfo@OJCI%)xOGdUH)vi) ]D:P9IQ_*Ӕ@baQCP*_퓕ƧH~PVGa\?_qGu]G]vG]&FvGu]Gu]ݕ&~8hǼ1hǼ1hǼ۱28;?]yh⇻+ 3fm{4LQr0m~WwQV?دXOb甿~8?ѻ?pq~wG_Zw?~~ޅtX?QGλV:Z<?ѻݻ{޽{r7wݻ-/wˏ?Z^-tnrY(7ݎ?Hf'W\kuQzתQzx꬘16$^11Q۾ ڊl _(O͕%4ť')mfh<4b^{\1LSXocG~pY]??jUhZc040 f\/7wGzZ|k5ST=ĒioKn'A{pV8c-;옎y-Jۄn0P4dpp؝IhŇ_t{R/RNQǡ׋rƃ5Q;-q;ccG/Oz#fL݃:]5X#v 1j~?BWҿyOyVy^h!Z˚>;}aIҒNkq5+༎Ԓk{ޱ+!༎֒k{ޱk{ޱk{޹k{IR-k{޹k{޹wk{޹w\] uk{}ñ.k{ıR.k{ıx.k{ıRn!]λ0ϻ+uTnJq|%}iu`]C5n.~w Jg㔕^p^wI/kU:Kn}%}m~wUF}%}m~}%}m~w.ro.~h䃑~\{-k{JA8˽yZIgN+ [qJF86tQJH84p{_roVbY]JM8˽)[ gd+=,l%(ޑ,~l}4⮯fc,wrGKYJX8c>-w{{rY8z.SJ_8_fu,w|厯֗Uj;Z_UrW뛪Yj3厯XJi8_f㫕p;Z_wrWۮYj}5_fU,w|厯]k;Zg,w|rW+,w|-厯֗eJz8_uX(k|u"}m_+y"}m_ y"}m_+ ⼎ܼw]k{5w](k{5k|Uk|Uk|u&}_uXsMۻWׁa~wCäup5wۻW- k{k|uQwۻW= k{k|uQۻWM k{k|uQۻW] k{k|uQۻWm k{ϻk|uQۻW} k{ϻk|uQۻW k{5LH_[EgBrw.Jk|uњ]㫋ڄn_]&w{8!}moۻW k{5NH_[EwBvw.k|uў]㫋n_]'mw{@!}moۻW k{5PH_EB~w.Jk|uѢw]㫋w|:zW+w|2;zW+w|;zW+w|2je펯VNje펯V^je펯Vnje펯V~je펯q;Z?3vWWj劜펯Vj勜펯Vj89_&g$@+}_ܑw|GڿAϙw|rI' N_{W+$;}m_w|rK/ J_vW+$P;}m_<w|rM7 N_{W+$G5jw|NrN_{W+$w|OF5jw|rPr^N_{W+%5jw|rQrvN_{W+%'w|rRrN_{W+/% w|rSr'}eXVJk{jeVJk{jeVJk{jeV`w|uzW+%']~W+%G}MۻWV.K&eMۻWVFK)k{jeVfK,k{jek|jeDÝVjĝVKG\k|jĝVKJk{jŝVHۻWVK_\k|j\ƝVLNgk{jŒk|jÌk|jČk|jŌk|jƌk|jnjk|jȌk|jɌk|jʌk|jˌk|ǰk|j͌k|jΌk|jόk|jЌk|jьk|jҌk|jӌk|jԌk|jՌk| u<ϩy5?4_2qmk[0O!9jU}8sB^mYX^ⶡYHbZԴwj}c hǚoeAN o Y6vMf &@ZUU.R-Ó~Qq$b#o w⤑b;}jzя;BOm8?^`Oԝ鏵qy֔SqA 9 L\oNzNIM8z̷mGyt"|fLsf6st%n9bk<6iOZ"W-YtحQ N[s WĐ%-1kmQϧCoNSƈ~|>4y\ϙt;ohvtׄC ڜ0?eJ!0#m[84ƨiukϦ7~8ׇWH9:ҵ_̶?̚u7f&`BpT30 z<f=Xj3N;#R;{*u^TJtuH=חq 05\ɱwb2'hf./d;yr^V[lN]}02grpe7C9fS|@iދv\󀘩BjZ=~eU>V7!DAʖCs]sc"EyAx$'f Opa)QpŖx61 _j8v/l\š>€(|G]Qi:[`3F#O^h-}X- ~xD{^z_xWMͯ7 7Kկ".Sn Q>پ7|{nbEdjpL[.x ±pgDnϲn5gQ>O/8bK,5D:1o Ќ+g FM}ϝ4 "f`ˏf7X: 5J1& V*̦~׎;cټ@yu̮t\c)1l97دA ̲ksv6lmt:8gq=㴀=-lx=Rr26S fь؅O[([`/x ǹ z| "*D!'nU"ׁg6U-ő}-YX̢AS"Z$%<(Ҟ>Ai^ymV7[֜%j=o8Z 9EԚS5|hf r+"%R~!4&|O3/xy-%b6 |h:!"PD^+Lba̚hk蹾eFQR3IH |> u@0ٻ_iFi9>r/́\|-(q7ս~> = H|iϬ ixyw}e/)DuZ(Wr+^=6|+_B]xw`fĴf43|{%j;fj^g|̗WAB_Ќ>OԒD))D)ŨzX@3]?.ݐKG-;OI/ǁ aY ⻿Lar-_FuoHs4))B=TpP8ׯNuBf^Ki&E dߗ39ȗ03t3+g*0Av 9tnC6  _YIvöܶm{Ii ts8;" SZciF$tm[=|82~ ѓÈ܎>G$B( Gh(S`yAvd7%.E0d8kYp4IkIXY*b4p׏˾&%_O.ϠSj⾭  Jf^Ga!BmgjNp[(#פFD̚QR՛p-fŴV$Z-y[T[ѮĤw[17߼AfFiͽ(4 7m/Fбk(:@ۚ"֌1m͝,o*LNhWڶ^򶎙Ei >ĵaZp8֝3Ԇicaf|QLp-_2܌@-ƙ?FI#ׄ>E E(i8⠇mDI#kȠ0m b|l-bcQz(|[܄6_7d(*sô\Dgy1[^WlL͒S >cBCڦoZnBx'f6KEjQЋ@z~HPO ԧ6לrikDδ@bD_=5|õ1J7܄4Rlz=>xY\=]yݞٵ8Ϭ«t7 4#|ӌ^{r$^Y ߣA^&$^9p Θly[i6LۆxI Z l/.?_^3̏&tPiQQ mf{%Pdi*N/H0ۭԗeYĺ$.|3h#s>.@|=c8O怓wD}wG$>(,۷33ҾOpߑ6ZhL Y@W28o&Ѿn2:׷Gu>9ng'KYV/YR8Hr$Iӻ#jI(ŕfRyq{e(<}[ ^=/B2/Bj"toym)_gt?m2( %e,|w%zȞo*zH?͚?!Qd'Y*gldǫ0߮^dKh'Mo[a5e䡏ݕi)QR%pa͂i?adKcZ}2"ۧqdd_hHz|q0$}%|9'Okou<0+Ld1( m-/%   Ԓf;=BϘ/1$_\(^{W } 4ô0s*ڞ LkhAlt7/†CZ^@I-ovn _{1LڲM Rcaդ$(3^DoQR?6*a~4.0@3^)*OrTVoѭAivt´:|&}xdc_XC{_%7(x` v+2f&Lۅxf]b D4iP L*|gD k/xi+$ufj0r K1,.:qKܲ/9_+xe/߬B3/ Lm(az N}djd6N錄k6LK"Vx Q>]~8Å4@X AL8H;+xi$LI|H&V|a |8O :0^ŧE~?9p8+؄0Tq/R*+Va4/Bѿ8 F35J¤£KsdoQ|T0"f#ݒ@~l̗ E/iV̦<3iI(nZ6-ƚ]7+ccU$":Ќ,?0B o1}X~a4QQq9Di G9૰0i Qi("ܱʎGQmҞJǐҾVb:(<ڃy-ŐBnя G}|pU)c/p0Yhd7 BQ # @y[T^paZ_ԉi]A7g~##6FDA7ƨu7F ~cGfoD0dkoDc*))CaaLTn3kv^VrbMJ&߈~c:r=L+6&FDVf~#"LvM7"x 璺6NVΔnr|t\cS4*X9,׮ hJUpFaz[͊iiQ1*# kaqT{ ¹0Ac*GCJ4Uuk T)9>j: =GT5#yz bڵhͬqmuq3 G1uOHQ:~Ϋ4(KWGZki8瞩Q4ߒI<ϚDIi$:U@TU'kqn8#S=8v$^_.!(rvw; Gnކx;@d>DV>L{8Dxlx2JdQ qDkGɂqsr:u|tH+H!rt|޶GɧݞQrjt|$9plNV`i87/Mq~1(b ("9[b80`80ps{df=g0t &sssJ}B<0_Qo*g"g. 3sv=T;N1m"YXS+jFqZp 옙Y{Fp ;);py\95V9 Jʺ=Nf1{@9 ŁŁ ׵÷@"%cT y O;1rT|FzќO"0tU9d5g<{ӻqOC0 fpӤOdFs>JiNa0aR/*aa+p/'!ќ/`4̢w> ƻh0޺201#c0}87_H*f4;(-{ N3LG㝽x;miN#WaZ 1V9?0´n?/+<}X0m&ayA o:[$[mlP>X0V7 Vs~u34| 9b8 T]¸ [Ұ/m'[ǰ<=Gk`F4l_>0U;_.rwPT=&ZFըedP}./CV짣Z5Ċl[]-1m(}ޙzu>,gjM\|__QFgyA eQƌdMb)Tar;(Ip+iy'[lGfGT9@*V@sQCE(z,B[Uܸ8.>"#x=c0> ׹Lo03buy/F|@vW> i q9̧&U=F䛩ՎeG/țG(* YjiR3Qii֬R[d>$mҲ_d!yۍ5kԤ!9̼zRϟG,:\]!9L)MwʇMʇH5)܄19J (Q3S=iFà4w?|PvC >(G}ӤPZKӶٴ'mŤ4DLj^@i-(Jt CHYLd6%|c;if厍>ZJk m+t643;mpZC,_r_zPWMIW0bi^/9f,_r4/9%|Ӫ=W^1wm|-M}$Ba'My'0 Iy;Lus{Y>'o*cV>'y rdG^@ԌfI7u8+79̒%}.K|JrSrg))yS)yS]|?W-%?ҏ2߱>xSn8L56vls[ʗxmf3۾m7絯揾1;j9xIx`7Ev>8Ƀo9lt΍a.dS69[ P9xN# 3s0@屧ļ/;iz0/(zQIc}l,R 2hJYY;>*6Q|;w;}EkAHvV{%30"Y%XzxXK{ XḰ)= ubKAū?=񷗂3xR=-T}{IC#ٽ,92@k9Du \L̷&9@-S" vC-S9)NM]'O ә N.Ux5 \ɇr) dyY^8S`W)מ:"ry]5ra~n qDan_+Hek \^-g׿kl~\{3_)8I@5ih\kW@y@˵o@˵o;8_Tr<-׾/{8_6rk@n K>i}wꈖۏ4YN͎h?W:VG}PslhuPGN"X3- ES| ·]ɺ+%/ߓZ(PJ0%&qne*rN׶LG9ZNCtM_ ńӵ[ZHt-Nt'/&t=p:4-t]8]#TNY pƮ .2LFO7xӍQxhʄՍ剾ݼB-QSDymɧ{> M.B]';:.T lN>tuaZqҎIVw+׳]f f}{6#665+hNz[cиӀ徇aA+/yr%]m{tvi# ͖c 44ᜐ |U]ݞD?- ;O0o 'S<E' _PtvG{|&hRAx hg`1͙͑#yY h| h|҅ WB<=܅ڝLF44BOs)O ]ttESMyZ3@]]=mx{1xzXxRv5x:SaAP՜H"v]]AoX:x ahp4e@yA#.றbuwmЁ]Du.N.]trB6"d"wtJ̜Ⱥ{33k%sV- .* `S0v* i>gf]BV^ǴQlH^u:;:h#{& nx8^~S.7"@榃fc2y.m9*;-MHU|_Û>lo-[e[x݀Ǜ<^ry\VoPլ,txyefb] xHxx}ox2ZH5_>cHM>RK^xgw1ye}4XXIa5(VI.&;3`(<\=1v1yO.&W^c]i?<yϚYiH'Ӥ +Sgme8Z3 rrVG܊r+z˭ 3Xnb)bGԐ[у]nEtp{aohK67˯X^Y]Me@&k`$X,96,Vw(,33AɻÏԬ!i2t@{j'G2rɰXȰXsH bT= вOǽ]PA|9(X mdl%YգÛ^[N݋"t*'b ng6[l70 LZڔvkkQxkѣ` -2;Z 0wz$ZYZ5|(uOvAQ'c d O1,QI;1ff'$|ĺDE|ȴ8r8s, 1y]g`ܼca1|.1Nui=AJF7w,Fj+G#w/BD+#Gbad1I{ʨەdq>2| ?f6_%YFȒ,OҴnp ՎEGG gPcYӯT^ŇKT e:z?b2R->|R-H<)I*C)ݢ|U]Ň[ΈJR.>yAyshBi\|SrȖrEŧB|*ӈOjA!ǧODžGfho Rpoib\-{c..줆oM8?x·Xs,·x/7Ž˚GMؗr-^(:tawamLQq| T¿?f@sTC[&C]# \ɴH CܱL`f7K=nՉ||K c};`a9n&Ƚ,,Ұ0ViL.{mLG|:L` b {D?94})kb[m/9]ɾx v^"j@z>{i=7Dq-yAr+"؄/dO-sfKlZ~7M%kYSil+4Ǚo)S(0D~@^"gkf?s XQa# -@^jR^*u 2_Jsym!.CC\+H7͈wd S ƵIy݂om |kOMi} 1o5o)>aVM6\|mdNx;9M^d4יY m*[6iBNzBDvW`[̾ą/L#\eb[>$٣VlW1m3d4 ژ`k^ l :B ]TkS!CvH$QT]T|}>fVDWX=zro)Ŕ-U. 5?k}ZZ5l2 ^PևS,zĞlެ0tyG`Ыx}(yNkĬ>%ft?,fo.Y.!gJK-.JszCӏa Th2F-o¹rZ{?A՗ѱVPm//?mP=_񩉱2r,>%\ |GŊԗCOsz)clmq~Cp =^!ZlT7 Ni::2`AOSuHSxS>ʩ[xih!; خ˂Sol NMԷ/].JqJ_Ч>=.Uxd9[o{uiRa,>u>`0͑a(;̥jfHb-l j7C ӌHb3Y|Cm_Pz(wNiaVqllL97,)0yDUmD!uc9yDXqH츕Lb6n<|ϼV" ucP7B!u4)m/E_Lq˂!̎>6P!t{{1M%x$1&(-s_%c?4z|?ݫ?~ӴhRڴSL>ݧ]td*l^ـ9D3"SzH`e "N% NcCk8r8=μnQE fkRd)q2`<nݓiۏlvO0ils\Y\i*l?>&ۺm~e' HLi?0c^͓+iwi?ec1ƯzHnSiR԰tHneVK M)[ ]/ Y-)?C{m.83{ܴK)MIE l` |C҄WQK@NO8NjK+,<@〜Ф8;bZإ4iVR>y-OM[9U1~2Et4L/FV'?嵛!im0i`ZS8h"&E9vv_YOY_vClzM{u5y'`u_]y.+S)×om|oo'GSyۓ|f$߼Si/0v9̌6=2gKęx[J*2T=˒qd?3'ŧJ]b="| y竅5.ý@io9n{Х]4L3UlڔmUyL3>=G?✺?sHH%ҫ% nKq!vL#="WS!y00l=[y0힕Ǩhk?.`([\(Ga\Av5%0ߚ ԏ59y]bތLa_o~Hm}@LôD V@Lx[5">-fC 4L[sxǁ&mKir K\lg{t@K .59]̧m$/oÍ̗I4FY$}JJ#)-+ҽ]8Q*.YY*Y% K#zdiyTF򨖆/ydpOW!?ŕr.A~P՗(sJCyv%`) T}ρ7I-0iƴ+951  ٬T| Dd"s ?R2xbڟ߀ >|Z^iP ? oܕ0 0wha}e2@'M`. $iƕeK|iy-v7vM0<7Ci~Lv'´||h'A3'|&~^ytczAqza!ƴ~*`Lk(<|i1nc| :۱zzΘ SiR7hL~<(rs,4qLj("[=Rt3B0.n{h= 3Bg*fE; `a:ymLsך},#k?{4D4xa*^*4LWW"M!OƏi fZĞ` ̴H?@v_ @])ȴL2=ڑςOYi0@if ( pp\xKyg8_ Х]qv,Õnɗ7H(ya[d*1x/x\^:=(!/M(6MǔC:Eॱc|j*D159iE ZQioXԽu/iR# n/)vbu/J`L˩o^rH2(.}ᾨ}+j_d$;0g V^ !Sd5+ffa%8s:<%0ӱ;ʀ=''^@Nôs:vQ0tւt7/ã~5{9.8&d:mq=@4)k1 o@d #)Q^#%:et< IQI\h #݀5(\Guf0\Gu:E[bi\) iQu`NGrffJQixBtTgtxt72'pGa(0@l:[-a~LG5g: 0Q}14LUWe:ڞ*bckd*'³ihr*ZT+`e23WUߪhNϜ)oh*3!73U̪`9`+S)镩TJrɬUEs =ijDJ6lD9mUќ'hN9`LG;9~vi IMᜒRZk)5 Kҡ]: b/Ŷ,On'/ 3/,0Ҹzy_j8_5)Pg3~"gwy@_MHq1u:OKbDq:@ixqxhpZe#18#{@ ~  Vm ԭ9#'2`NxejLxg(30"vil^Oe'ӣIO CtV``ʹQ'jiBJi txc<"a:T'rp6_v<Y0ߚ|'jM:Q71>jp0> ・mƙ#c)e#??b)ӣK7@;ЧaZ|:D+"H.h'l P02iΜxң@=S5ߚmzR:yRMyKspCz x9yh~jIg5R=5MC@Iu\ Q QGn@$5HA1 DO (810qCNjKyjOgSvA|]b`v38ԡZLۋG2 jGRмGӴ|%q:<01Pu=C<zGA:4)O%D쭚~T*i(w50]Q X9H1oBl̷F@StJCd"Wf Ya )dJ \a RÓu)deJ Sf&unYw$u>p~6_QI{>at)&u xBQg""N9pԙsϮ'$÷!B}p5S ys uj^GI`Pg*%ٝC.P뙙5) h*WB uӓ#)؁BK .v{e]P]Fn#,K.Cf{f*)'vv-NɻybGrN5L>DdKT|Xc<|*ٵx8INufpaZg Oqё憓f‹͋)8ՙ܇Sl:Ch8ը%W$r_jy#GJq2"Ĺ@{ d@[ d{^2!:>Aב9wVx?i<3FyvPn#MJyX6TS)+r)p^:+<[}5(N;gW<^=7JK”-L*wxwRM?f$bp jGpl~9켪`>M'0 dj֑BX_- Ѽʁٔ*MB0(|}7,1l@0(|{#a:C- c- />HY Y`zgC]DKzTT~ߞ@;4L /ZU;ӧRB "R(i´Z7'Ժs,h$KSR?`MZǖhjsh@Q략*{+'HT5a{=mpL혶 R]t c[Naz 樄80y=؁|*w ^1AV9'I0A၄3Y2#Jʑr+z1NC=Sc4AV)'*}Z=%7{U9tѤ4NU `&0-&%yy%5ApU Jc0Vqi-w TTΚ`Ni-ohMkwZK*̻#bN_r'w 촖(VN߁'ST65!;, Zu1Nb'Za Tf X}IiϼҜx@O i OômՏMLxZ<~0Oôm8-Q4I[U[oj y NoimŻq͠im#>hY&$"$.Et>}l8>},Ѳ ?kNMvf !|h*ghڳ/>sLL{NEסJh*Ԕд,ڙ=>>Okϐ"y6ݐ_:SOOLG>  iQ~cdu#Pve:32,ԏ{i{^ [˘\7S.S&H:mH:yliOooL}T4L S-d.S&Sy+LꙜbOM8|Pb)2r)HTɗy)(=2}VOL_xGRf ʴDLjS"SϮNLENLߙC ȴ01U{c iUsa3]Lìp7 fZ=t62@Ȕ"/iLAT|n 2;] MN&{F||ߜyKxisPhyBSSW^"8&/mҴOХm=BSվUhBSϠK4_9=8~L]#[&湒 4̼#C0s6ͳi6$;C#orVg^$uE@B -P@=KP?2"f|="?3 .F i,~7 L۩aOx S$ :4! 3UMS - ]ڊ d_)^^y{o*^TD*^0K#9_KH |[F OHQdrm(29@-o4m@O+ȑtg@L4+mf.ـE6ll@/~`J[? ZR=^ӄ/gmm횐(m J4lLȧiB% os/ " Mə9M2&(NФa(&mBJTdXKO*y8;d\bH 4K|?;C2`O]>8xrv1>e*F`I[V`I+xg #M r3^9TLM {^ o<2m 5=`nqE0∜D0i?]B@9lgR|59O;M*[UUV\z<)<)qu6$W7us4'TOO=&:3ў3@ip/ 1,z9p/ץ75Ͽ"ߌi0dMGIhxk8ֳGfqop-;g!a6Yoa3?[ˮ[T]ߞU?.ڿ#𛯉t6O{[A&\ćzfBR:bDPe ":6](0&ƘDݴQtQ`83U33SvP`P`&С*AŇL4C;C2)2twy< } "2p=z,D24E:3MemB%ڝ𓎌, C-q.\g =iR'/6# .BO = BKTLi| ,4L C s<@>G|ϑ(i .7p s<|#s0}f8 '|dK^ X%uOg0-,}x[|HS|T뮋@?9f4rsmLfTU&}):TU&cfQt 4LӐ>poa @;,NCtx3#Jr;3h[ו#W>ڨg>h!8O˻mULSqd`>G s|\U@|Ց&iv@la>6J{m.!+sp_WbPC sH8A}N!59?) s?!&_|?yI'0ϡ9$C{0Ak7號z͈E#ou0mu<-G͕EPa OIg'~)N N\1''D+kp1>b%Eg1)k߆xVcJ )iߙ_U(5~1FߩY]wVsYO+;=V7'@jaSg~zӮղ+>y6$ДN¤4A}kA:f2)Д| g_gٳ?ojʌ5v?3/4C=;`W7TB9ϑ6""?8~O#+~cXoLWV"?39};Aę.…1bZ,&8Ӛf8As?XYlI=o-`#wY3ldTJ&%EHII3SAbNT_L\ϗ f*bLq/MY3|+6B-Pֆ3^YI|`|M1ᵇ&0n3$c%g-{Gֵ$cqZapfn6G6`iY| akyQ?@kލLf8 P^M۠>NNoVq#R.V#%X #+v*0/(ll(냣;gtc}HcnPd`GO-8gMDm^S(0S=x۰k\JW 4t<- l Cos1G2Y(+Ү \L3V\ ǰhƾq3j: yb~4 <5+_͖M~ՙt,/O7ė|uT ,f>qouԬuHzw ))q͎-0XQ` 4HIa0gvM ˱%pAїФ J䵔*Y޼n*`Vo"mc.y[ڜk5V)ɖ󣩶IIT[=S)id*%1 v0afЇEP6NApIiLe$@#iJeoWi5\>LAtLY)cm785]vu37+XP`A¶׭@yr|(ډXr}%7kk07c(]@bԙB{t .LJʧtmv-*L'QLLQv: Z4Ŀ-+Ѐ~o3 OB0<` [tB) u?,Sc= rAUqO 0AN }@&Ysa?ܧ)iRa$:^u. ?9Ц2yj 9% >'~"MU3]SMlw`y?$w!Tj;/ {lj y?tB(IiҾ9zC ~?5! 8cQ#M`:rs!$k8]`9̚ҹ l;&? i͙gv/̎,٧IP<=`InW]${Ofx9,^ "Kkg23.Kk9^]ќ"ً>L${qd/9L^FMI3$HLطiҮVssĤzkQ91!,@|&}-2SKd@Lx0)uN${5.^Ą/9ʘm09qrzIz? ]oB[HpFaVN:_0ySo8Fa4u T&{{~4+xo+pǞB9;]P:B$<y%^ׇC y}8ׇ` (<̯&}ߚQ/wY2duO=[;ߝ-q8d;\YWSPΚ?Rj>W aZ1>֦xǮ+uI)R^fWxfJˌ(m0#@c]rD4D޻re$@eG(*̞>֓f^!äP3S)if8;oXZ5X 0qJݻM(J;wCrTy ljZq"c2rp:ļ9jogyQMXQ~mTJzy~>LJg֢f'>E}xydSW맓ZwHה?4)7{UYw <̼#RLwR+= MPjT2u7 y GUa{MU ļ~K%}ī:n::DU![չwbC[;@wf*%^^k5Pn!wH)#_;\kd ypofm8aL97<=Dh8vx; 3vzphrPoH+Aq7MVja|xFxy }n݆!dn'`-Lv;0ZwnLLGfdh"F6?%镩,&'ls: L=6a2!䄭.g$Mp -h-e@=|#rW;LM(ȁG([yspzj>`?|5rnc>cdm ;̢Gn甼79a= F' B83L_InO yz- ]fRqwnO tݞ~,GFM4rq 3>1` zĽ-`0m7e?rڃnw{w{49\n3_ [ml!sϛuPPa浔 n434 (01Lw|Lܬn9DiELLSY4)Hw{1wo9E0Y_g8e*iLO4e*} }F^ZPw }y%n_~nw4{<'O'!Ol!QCx#DA64?Z; k^@ipӃ#/47ӃF7[s~0w=4`]OƻM0wμx SxSx_%/ػ .tPl9p}k9lii(`3wzN⫕T+wmSx!TWSx?@OuN_/%od)wMe4{NwRT)zT)޷ :"=$?NEs p}J?z;Rf [v )o$=}9?33df0ϱ6iIi N ny;j𾷞#S 9P;O^Ki̗Ҿv'Dp'//9 g>{ΖWܩ T~ݰ̼YvHj >lþB)4 /<& $+5NW~`0lHŜ03k6k0F 7h&% :3MJU-8*Lx7G014B)0ypNE M9?2,y&|" y40)e{cL=;޳P؝SDT'&|W?@aG,wKfό(Z wѲ&zX=GX`JW^KoKi xgU73$nf]pU7-e9@Pl4}d죚0GML̓>ψ>Ddy Րp!opQ;%\Z&L axmIZLx1)-Tn%O/hYMyQsw^x9Iv2#=o+c| 0J\ W1wEmPTܧxuQFFO *8Wm8Ww^@a拣xiBqXUkB_ݬ=4)ϙMPa)*Seٸwfh@M( 3LUGP?\$\ǁ t/0mSZDlv1bI:rJ$bUNDl;ߏ0Z5Dl 1.W̘0o.c86<ï8! :L Ĺpñ7naf*d"4 Z̾J]Cز1s|s<7tKkRd%L̚%&u=T0prK>ñ(B;8&ׁ7{aMSJiP p<>t0)坩ҡd*%}2Oi)v8[9|IӥQa4r>ôіr(}hpxj@IIƭ6&%ҁBDm^Sh/P2(q> b*m' Q\f@!w(!&bΎ^Paz-ŧ qMd 2>SSQĴŸ;spupȍ"Q@ zG͖?Qcutl4tڧJLJt|m7l@DLZMe G@~;@ ? "zg} A XI#M7V8jx}5dW=8(0Z(c *BVPsjN"\@у niCf6﷿h9ʦ h%SF[A3a?Rc!ʱb)WMJiR^ہ,&%9l({mX1)a_MJ 5h'P!j8r ph>i6l?n6E#M,;ՀS h?Հyɻ0/ '$ާF<pN4记 ôL>(bRl?^( 1ٻaZ&|nAiLD!piBg*<{B5UxLQ~C‘;yj)Ԕv1s?MwN\ P#ɗ/E~(7E~(w%|Rzr07M%'`~3Up<@ ջĄJ80z% Ӓvt`#wGaP0J(&&%4)(Tp䞾|10RK0L>%زr,7@ (av^A0L+<JiLE W@ 㕩8p0o6?8{ Ӓ]f_02Z8rhaX ^!_A;>&hj;0ð5{X̼򱙷P[D`Ҕ ~/@ #>F7U7Uǿy7%}Zi,)0= l-p0NJfv'{AaMd5}7LqkZT<'^Sb<u@6Ƴp_c aZv[SO}CR>6u Լ@p6$ߖtxnȝ}B4!O3~B8e8鐂)|4} p xbB8HSB).7S)@5oN%n" . aiW1ܱ@gb .뛱Eѕ{.]9p׮OWܰ+zpz;̬j }*n֕wс5&M aRk#3|T0RlR&*fR Tp+af*%, >7ϊNxFINTPcY`6>Cߕ҄o'ۙ Nw0"D r?`̔?[^KiT{5hR0-NΔϷL ))S^r MϹrt6f^KIs}rA,cHWY*3N š0, {#yo# 2Uqu-ac â/F偝9Xg8;;uo#mP9Y9f|y4)-ga3xvvVi/_;}&;}+2O^)3l]%|}w+ _vC8 _>+ _vL 2>22>']LLĆ"p\{j^R^#LLSs |8dz}HׇXGHCܜ'>x&|`<զ ѥkki]%i]BffR>\R>RR>R&Z`uH4Gc\nHs}H{t 0^Z:| pzde)]TJWcR>u"R&T@Jח[&)]_#t} p/wR\t}Ir)뫦 MSJח^ `7ȊRwr}?(^J׷/g~]A[H)#S)`^:׷QS*WاT>U|)sJfƜ0GBܟ^GIN[LE{Ku}=%l kJS:ꔬeڋ>%kZJz嵔DtJygtʤ2E&]S&ռfĔyLtʤjw1a`# iIE&U+g^j{Cj)V,_kKm>LaI5KuZk5kTJzϏ_i=eSZ) /1 kߠ=p=_?_o\mjn_k6wO_~!q"k׌Dt:`ߓ6<\]BnQDǯ݌οLߜq됙͌9QoB uBɃܩ_lߒKbXlĶ a=_/iRc _F -V#]1q2rcEvF)H~.C$5~;ϢSytbO:3Xi0H yۡd~M#Ơ~#W$6F=Ѫߨ(9_-FB6Dn(U9^\LHI1]f!):$A%gF+)3#ps+˾1~NΤHƌ"TKČ4HŒҶ(OH&H-$rKeK$^Fɵ 8YLzh|7e%2sʸ|˪ʶ\`ȴ4wpz=A{5 tka; 5 ǘ>ZeFFerʓ.j&"濰=yqZUmT(q_;LlT S%R*I`5wӣ$;sXŠ@-H?-'Wɓ{@J~Q TbJ,zҬ=:e甏>BS67L8y?Ԓ~Kͤb-Z$? %ZfrQ.%gPFK䠌u WRI΀K"&qܒR^I Z>Ieڽ0,C+pK ӻtIxHCB&7>$%XSV-]ad~2Ar( $% /feD­DGQ8e}^Gd|0pwPX[29^`főO-3n1ʤfd7U`)e/1B/#1{aJH-#6J@+#qۛ;VJ٤p-gl0HE#ٶ*+3H-"Ċ,*TJJEY1qʓHT$K"ldH$@WHC(+#gW@IrBe/!|*8 eU+{-i lIjȮNJC ΐf$}{JrRܗ_{(}ˣI^Uԅu솴{,] +pa] O}aD]3 )+r}( È;r* AVv` IX GV@=B9A>:pA ʾ_љ$X!"FxXT;+~J`Mx?xwÈ3RO0+D</j1:@V`r_]^*ߛ @ԯ|rz ZЖ:@nV/Za_hi)w!l4+ ~'x@V6f1SR U_PUE[@ˆh(<*u5#fV AP)vq5c SQ4c~"[v' rJ)pS;0o9BUNAL+^CE\=FqX7 %+bG7zn>֕)nh#F))T||Lj9?s bw|<8,Fڎ<Ҏgʎ5ȸ:Ty,#ߔw+uKgDڨ8b=@ #֡AI*91Zt|{v)' ct:XF1RW H۠Tm|Z4 J`=+)4QA)ӄG9q*7"-p+5uJF(Pl:Sh5 SF)D4 S8`=>W0 >):.#װZ=Y]|ahO/",k)y3NKŗKŗ f>J'ϗX|<3f(,"YEm]X~MyEĬqz;%_J⊯._~_~>("jX_aS:78y/kf'dDDLLẏw 'nᕴDCϞZjb5zOȟADtR+.ɕW$4VM@"Z]晝BѿQi+>ɑ9ĜzTbN*1PB *Ed&P)TAD ,EK 7#A wؐ!ltBX\\z;KoGkzH!wԑAChR4}r~?2sltbezb_v4LQ4|.(iX*L2ǂRo aK!Cק۱<N!90or "S= /|*e _F#lfYYJ@0gC0)ϑ>R6Hu=$R#"aWdOa 2lR:%:\ 0VvZ ~9)5@* l31|Wi2rm3ȁLiϓenq>!QtK]AN' n*!{+?,1`H1ARKݷD-A~k، \j~7)r 4Ȼ `UdyI(ť$  =Jfb[[.e]=̮#$e֫ @rev2Io3י"uewR]~F.EЪK?NY 5JRȔEq)o~=]j}}J}hHE?"ÏQ<%&(b)͇O#TQ}mD}\>Wj&Q/hQ^ Oj w 졯礮]Y+[Y4礮^H=FT UDz`rVo=v)7UG)Mckb~E>SC'%XqRA~_mqUCovmD,m%gy=Þ'cNcu)4`mah`V/Bbx":3Go)'JV<)H35#9~2ġ}'V;*߉.o^hW 7wWvXDjۉW.y7gvI ;ன`'[;~ O:*O:A։V.ҨV%Y%>B:A:λV_))ytHRn_c !ԄUyLIXTUwLAXdǨ*,2 ѻ0oJaQgUF4"an *XHV; "&8DTUb,,uam[:) "ou;@Ujxms%T"r[1Vyh~:RCSL I<Ê1G>HN]f@B܃Ymq 8lK-eg&@=<`ofeY 2*̜=afIQfՀCXϼ3Ry5d3ʕ̭1={99S-gJtogU<3J`^ BWC Ti{Qh4A-64+j¢$vUVZ]XȬITZMjjK4袢ժ52OR_>DSzVIJvt;pZX)@X)&u+U+N]=܋)VL^-U[l2R$= bIO[̌Rx%E6Y*RX*xX)Ko2{JT#o)#jl[HmVK>-VNu~Maߪ7!T!ox f!ż,Rҋ1g22222V#@PO,(L)KQ" 35R N9 "+9OF[Ԛ$w*7:䞵W\[SѓKajړ9H$)S$CXrHvb͓iD| q3ԩIK>,Xߔ-7"k+.l%A2Dp$dr)$MIHIHHI㷺C[bxB꬧0؅TYG)EOA1wyH& H&u?Hdj3NiOFRUN$K퉷:SknLvNeYNUeMPT]2%=Ul^G{j3@3jLfN5YO WO%3;š?lT\n(5O A3Blɐ2񧳉~!`bv!5SJ BSt6YHy$UUɍNG Gfӓ,CJ{8]IO1pghgv2L<]24u9Wqj=̩|b*ރoH{4RT$TC݃jh**jHbjuu``B a9_ "5Db3+e` =_5"/4Cj5!9@ x)x(ҘyJJp>,Z`4)+)# !,&/h(B0 A3L ^f84CS4CaQ{37 eo \CMDXk FvXݫYf /Č}՛QBRŨ=RĨIQ{QS] !&f[fT(50KgmoGCSl0ë͛f}¡ ¡ɭy(i3ДOH;C{C !,'3N~(@)Oގֳ7;na+sCM::A:4;@:cCr7#;5!|'-c) ҡIQ:vhݠX?! R(,mypH< SooX@);,9r"-䍩̵#vC?&kN7)d8>0>x$‚' ۇ=9h3?(>">-iLG|2j؇!H6TT$"> + Ss 4P}Lڇ5DD5sdA?(PXHD|""3TW4N7QED|04F>mV/Hii_džKL"OSȤven}}̭O7%B&u؟`_<#9!Ai&*GۗX׳jߔ&/qe`%A Vq_Q×u#o7熈/;r S'd7ox w¢4V[Z͑L- :C×$aM,f΀QjoW[SD7!A {%0a K"0ayGǢdw7ցLo覚hpOќ\NѣZN>~ԏhrLCL{k^cdBE{6 mt3k|Got^R`n4nMA@X\06xo3D&@ok[T*׀p谶o!iA&,ޯ6.0tW9TJaϩY(Y{= @ C,EuqomJ4Bhl:*tH fС WJ4?h>2xBEHWCv3` e"Y5tŅaBsfiݒ13w(4f*; n)A+7@ 4CW4CX`>vgEE噰LkXy1E='c|n̕g Y@_%Csw@4D쿔ϼ:y0@4DQ'#3:,*͌Q{TCXG>of[2 aQ>h1 lA\=@5t([PoI3TQ*CRLXRGTC?y?7E/P1(ńWǃoQߠfL)dLCX_ tXoņ 7z̹+G_dg)Aqv>X0!01UC?LW4Cy!oFpCȢLWLZ 01;`DDP77m@ ^Qi1h'N-i_rBpt5~~ 0] /?ߴyFeh Nu]:xl;sL! :,/]@Bߴ9&2HFY݋.]iz "FPS~ G~φq7yAnХcѕOT[:T0E|*"NM{7ypt;ʴtd=P+z*sH|2K7Fav}Upg6"ք,Y?y>g"7p/N$%@>$- "&12AY* FL.d(Ff1Hi%6DD='%n4u~N\.'dtpPW< 19I # /v0 ̥%it(eWtfՁUgGG 0y(1+VN>sN PʳL^/NbLpbdOR|,̞QhΔj֏ &x"y.nBQZ/no0"GT[{)*eIw6(%!gTvLd$ ȄI:5e2dB$HQ8кFtƞSB}C$DŽI9nih^$GQ9I_N|4h IT98|##IBLq0kYT\Գhk R/rs<>cy jWA1B7G1"5ydc75ƠB1IA3_f)% =Δl@ n#cD&W> 4N_ C8G8E=8ipE% +p47Z o~q4-IQcDŽ90!{ul?I>z|B䀳=09i[r}4ȁ &= r`Bu%r90h!&< r(HDG T(u"> y5TԳڰvdLXC0!O E)HKiMG]Viv 0i-GD ` ׂ(hpθn֍)2AQJ9ÍDLsATV @QE* @_f| ~Pڪ1L#"68 Ԃ#hϙyf E$,A摚d` z⦚'dd^RKPT~şmX8޾~g LHz/P`51=+A%AGR&y^(߇l⛻J[["Ԏʻ9Mp#C|4XI*= V(-SR2^{7z~ǷYXX ==(*m|Avg_ ?6 &Rl=}? r` &dRPHEHo@ ^~Ij\I-!^hs]M EcY= 5YPjESzڒ T3ng֙D˷VJEV`38;S;{ΜfA L%[ b<[]PKE5ԍB*5ȁ-:=n9EqNN-@Q/BU5Q“%5M ^V=)q@Α8 "Cp sz24x> 5XɋPQG8=o#3^?'0KmFk|TTڑ &,T BALƻjPn0+-B x%BA %]"(zV÷P( Jj_F9۳}}C LRb/Pzj%eT' M`$QKҞ{QkzґgFm:z.9=3&Hړ"iP>W &E-!0@Q'jonSfQ(J=IF vSRǣQ+ ;P'q6؁ i`&UU v($yO7W;`J1P$xObIɯisz oFOy{P`HMM˾;ayV$ע0>jE]+x0ruYu@(F@QxbNt@=>2.]GdL2A{dw0]m| L> orue+>dj| %52"TvٕɷQq 9yQ G N9eA4 =Ղh|)F Qr`}AԳ<BQ‹DH$~Bcj=AR`QIS*")UF' XH>+TUcٟ<05;gR', -ꕓy/%%%|/5>&Uc/J;8dݟ,5~&TQߐ/x_%ƝF6n: 7vzV/[8PUE} d~ſՎ M`U5'DUc韷>,hb$( j|AR| OE_' Uc/JCړ =砱Oȩ‘DYOXYhq/;VOS`JX'U%!/+bl0W-6?N-6~Zl/)5}n(VWd'A=ҒE;HVQ_gH[ߕ5z[JR̗Ȯ&u0%@Q ة+?DVQy*YYt|V1> Z,O,%0R7 `̍?!og(G 2g%Z_R6c0.q&W "7/ P_m 6oƿAQ DŽ}Boz̹so3Yo.؀} \۾5خ\ .=+Fٌ6scu0Zpo+n%GvDL!ZB`n+؀lI<L[|*' ni  IdU  σH|ٓ$VlL-Oj9 `3y8*j(Jي̒G&EzgC'XV|X?X?I>v`B9Xy6jX?RvzE,<``dC뜉ֿx9jl[c_O=3úx=jEi]X9yVQV91߳%mIS/AZ5O5?M 'kjEm]`/ #;鰬KƪxBj B/w/~}[ v8.7V/XQ-Gx[Ye/~ZM4z.M Fl,KڲD _bo,Kҿj, /xO}:_C_|Uc_b66%\Uc_[z>uh6m7zZ5V%l`Z5kbo,k/[G;%dc'!?_l)9m W k⪱tf5_T)waFa/J7Pa.a/Ja?a?Cm7$RvFg oР9y<㖀}Y>Xb';='Գ䎧AQydΫ`puP2M ?P( j|D EY j`Av5b>l pj<5Q_<+Yj_ҚWcb-4%p$g1|jE)'ۭ/[dl7 .`Xr"[K*Y Y 56V! ~%\,8mP$ߤmPv^`5^ `킔~ ;A=A#֞dk(%[Bt5R:(J+]@vhKdj͉K䮖G5,>ABQZD*JDhzu~jF<ycOlK<ˡP"[$ذDE9X15\C0A1!Y}NCva4 &d2 PB"PoxgT%(&B=C),BRX٬Gbu3UHj3‹x:BQkE}F|.aVvǃ|Pς-.CQB:E +9 C4,^:D̫!\Th(J^;4Ci_I9Pr*:4CQZd nB(ʯ'^" k$- rZXu5ՃZP URu"AQ!g]JF/JaԉPԉJ)0@b aEiXR=Q:‚<,>:$nC",$B`(kX0)'cm= >:@XC4[ o(PsڞUag",>2OK=8}P}Pڐ~:EC TJ_P'PSu$2)8Kȳ v ~ԳI1#=C,κEq.Y_SL0E)Xa jߡ!V2LAQjd9N9"ljUx&Gzqa ֑'# }&B@` wu:DC@eSE'Y8^EY^# Y+X0U}O$w<fA(%[2X|#DS##.afF5ǤePa TUQ{(u;MsRfMPTR%6.Xb6yY: D& %}cOEn5 DPJ_{ԡ j+ Y`:dAQ}7٘SJSQ).YN ԳTT2{:K|b`D(J 3)**ɁhV`DuX ,Ȩ'4)#C%G XQEiPPRS (J$8,by aTXuX5E(JLPR׀C? ^5^4;>i&Ғ  `ԎϦt$acԳfVF2:/ӳpV 8Cm/_a0LƧE%GճEoKTg/*G`'|,:{ Pԉhd_֋jVʞ}K-8ZYU󠨤 u$5n=V{wYHZfC3Y2b:KLgg 7u6JqGn/hf򝞕' wig8 Ɏ>]ɏ;Y XיA Όg-MΦ&$IPFSv 1{ /Q:jYKf/:~EO(c~A }wOӯp²ү7wzGվ2:X+ _;prS`T/;E)Q}}˨Al /:|QJi>ɫ4}RŒq%*Zg_J}~c .~nsu>_Ԏ{< `_J}~A'u4_<>e׳әFE/ 秢Ҳ֊gG7xr;/ȥΆYn/~A)ȑzJ, bD66~ggmA*v#{ilݍ%.[g/*z_W)I ROt.:A=HJ :~QIxI n~~ghEPXUP]4+TQr`:%_ 7ԅ*~Q$?Ύ_ e6c/JIee֯Z_G3b_<>uw:Qd/ٺ;: ib,r~}ggIhm]p -2~QqD'(JEr_],6~A9;rW_x_dLd&cE)ᣨͿk oMr3>v<u7=rtE#GNr}_L.-6ٓ׳[cx2lEJ[&8QI?q ;KL_EYt?$龒2{vFKԳοD= /^:;Q7mAt~Pm'_ԍRn>Wk/Fe4Ng/JIOQE@^v ֥Pde_oX Z~a/(+@QՋQ;_7I\)*A E"֬$ex$ C٠CԳ|(ވ2WHn6^H|% {gI Peʻ&y/>`Pnv7fv7PwPS%Y (J+F KO4=maKNIfR -**Қ6տ,!cI%֥6b-|Ķjhh뿍+aŮ>|je=|{j=|E@n/zloqe{۞c<7Q[~-?י_osJu7i=6}zloEQi26D0( qcEǦy$BuX?41kHI=u{e/;h%vϮmrI^?VW"twkb~c}azl0E=w{)EX빁c=&1&XZʚ xf=zD^{^|hgrSGsXEPJz2k%;iי[@cabc|.ޟUi|䥨(\KfQgQK~>RS.: S3wO8NQrg`?yGlgEkVa?B.j O:}(WO^: STm],-? 3̙Y]4D",øb/*yFٳzy(J-%c+@g_S zVcFPOءRTfnGÍf)`?E4xw5ڤq?XOF,ϦTg[/xv%;[VMdOTTJ9%5ۡ,;.0 vY5XOH)ZQGิy e;HBSn4XOx=ק6"%"xԳցdv/]P'S#z\> n/;p{i#HSŽ(u0XOR[ƿhk>xG,$NE%_)'UEk_RϾs`XOh8#k&pWViCjsVEC2yW]+58}kw9׿v6Ԡtj_S:pOon_d pT#]rϔHIC܃E}Ǭ S5J-_I$&^ǖg _˨|Q sH vQoN2>jksk]_B- U[~Fnvz<ϾoB\ذSpk{x"x'ֈ5{f3N=4_b}BVܙ׳FkOr R.㶙ݞ/JrUn=|ͽZ=%2TbnJ;iok_Xf>'4`.Jj1\`>',`>;7WQ[#i^,E`7W]ZH 6ܙ?+*hn+xhn}7حO)}f]lZf5جϖK7l'o[#{u=+%)mk,'p+mkė`yyzNN;'`.Kc&FzoDcnOoO]ԍztA7a>Oz4f%  7™V ׈? WQ38qi#zH!l٥AfvSi$z˳2Fqød>ClEHOKȖ}B g~4x/ WR`>yNlSܴ{QF"o?EO?سY)]3;/J>حOquvTJp^/J[#\X6~V(z@!4M>SfXޤRXFU*JXOFnSL] Wgn׳(e&&Čبu& 7ы!k[赯,L޳&~B e`,Al`N;p]I{g|GrKy?'_?sf$X'LgygU??ZJY5&}» e`ݮg[Db??y >ظx6}Ns[EuT/jIge{l˳r!7up4^|||Ê2oҟ02Ýs=weN` ?ylg-uԒ sٽU-(9դ? ZVX 3P?a+x +)`?y৘h# 2~{׳Rd?}=3}÷#9$]eMzRW{QJ]YKXOȖ}4Xeg)l+r#r)n`?y$ @NsTU,4X[ RTz(&E*>>'Eg!KuQ5 p ju˹{+ԍ›}d>XO^rRctܳj0)#'dʈ}3r}^Z$ |:p(aC ~O(͘E,'O9EOJۼ 7O(ÍeP(Í ;z'㚟2˹;^F8;#wLJ㧈dDdӗ,Vx=kv׳63/r03#wJ ٓyzƗĦ\uWn&CȋȾx5vS\э?1ʧ8f]񓟝\_FUm%Yyy>P7j2,mEy" vߝRe ,m6x׳D}**<n3c,ƒE {Fmt **܌e 4} | VJFgenwtz;Wp*  14؏O~m E3>Pl+}dH+}TOXR~2JD&>_ލL"ײIx5c\sp|9eqiȅ[|z~lrQ8D6ĸ?_r®|Ҿur=Ef.`Mgܴ!krQogI>_N_D/Js +K SȳR:#fFloE%7>b)~_b)~c)~Tb)~O"f׳fňmm]ZPԬ}6|6 s6y#$|׳gKg ؑ[G,YA#O',[𧴔#؁?ͷGlndiK9bPm2?Czd~+ؑXG|͟MOR~#ϩGZ8mSmE'=SL_߿uZjxc >mCηV'_?׿8+=w_ϳRՄ?jQJ^=Tg~€hK&_B܁ET ,B|_AEE\oՔ1G|>lo!#v -$Zο14@53ki(x|/ˋ{%p__\k%^opvu>!v !庿EE !J/ĎrP?隧M/rc!0,^Q_;vx (bg( V>Jy7h;;`wAIasݴs0Ntn5i\=STKRiv d6GXr&խKo=1*mys_!/n*[?qkW - GCY3Dѡ"1ds0 A/"vsx8 i9f" *S,|^) 3ӫı"sl,W883M8`t5BRJ!P9d9V3Ǫ:5n{suS>9l)zrR`OqɩPrBo9j7vF{LtfO5}$ygP0z²[/iZ60(W.4WSJZmcX̽mU(M@@ x8b;߯"iVQ霵bQ+~#]`Roc)?/3Wj }՟8־unjӇ&yYM-2Wٳjf)Ƀ8eSXt~ynEmPqfz}r{OV˽ǣ&1!Zkr3YT_N04_rZx _3(B%R}jYimWQ.+'Ԏwwag-{;UW\q2r(?򻥤&e,v4sk +Z#&}mӱA\Q}|~9hU88k0B=o*7`EQA6zuQϾF~r*Ѵ\oT:*q)O|]YbtudQWOWZ7^(/3y yXyH.*G~{Nx'*%]򴔴zVۦ,gRsޓ+ǩ=~m;6"42[.O)GvhKʑvZJ~ޥnm''V@)-vT)пHI[x1%UѼG E{?]f-*&n9kx1wQXwQ6]+mWw=g[|^}ۯʨ3_&Ngi>H(|N3oO|V8=|{d@-Jt#-a65ۍJt<_ԑ_RF2Oaɱ|QI*\hEN*\>DDÞ Wi7Jٍ]Tm$ JKy/]$/8~.2C~rѹn^jwב z|,[~IIkg#KD%Zӵ֍ca݇g|{ݕqQ8PerIR7'[m蝑A# 'EygdԔ众r,+5%/+xo;}4&N<3q{noe!%ny=_ %:)y7K`tQ/TXO#'!$Uэ[嗉Q X$7ϜL?oLo„=o  VeHG_݀M3'13ORZ@ʯJJk~~ΤQRj7p'G󵐄7qt~r J?]!,|ԸHJ?? * 6OD'y$M\33_ke |zJrs=(j1:}q̾No:}⹁N+20}=J ۸+J+\G cgq VI2B&ާ1Sک2._%@zge-9I:Wg}ѓYMNy秚ϴ黤G>\,*y_7L_o\{]4k둳va_r鲨-ϻgg\^nqOs )9Ў{MPzN{eNb/Ϸ7I~z&c-YL}qlqvqi^Ԟ_{ȍ[m7!QJy%V:j%Rҁ@z[Vs%n`՗#MˁZ}qb^Tx*7g^W[ԛcz;;8gYNN0qU=\~gzCyTt[tmΨFGT=I&\G]oΣcՠ A\k+'k˵YB0/%P(I8›,8ks(Uo7sˑ|q? u | GisTu̸2(%7[FJ܍o܀Fg 2H@x ԫ(yIAH \o܁]sVT~Z{~X!}OK76n^.*୯6gkCbP]@Mcuvuⴭ(E?i4ݎáiaXQ~dۏYu|Ff].$N.GJuQd/a50酪﷚fvD9gyKvo]"E:M)6AHr6LpPr\%uΥ7[7.gkHS- rpp9*n9+8 Co ~%a# sjxq]TxXc]ɑ][zX,d( f\m{]Fs k'IHOFgP__K!zF& (͑~ 7/B}i[rs+P`OQOn8g8P}NV @%P~.*j&@%_@*&WQJ _<\Uڒ6]K8զ4[)5QU{YT|]KYP//++}& p7'{p;@='Oe>'LO͗;+ |g9Rܚ#(ՇɃf;~⿳Y@ns~sgQ%FYon8wVEhYv>+fQ[ޡp@pcy><'}JUrQڥK\; fl7+Ҳ,@E[ǭkvje`ɿYvh%gɿGjTkɽPEpw7qVde2F-'573jWt#sv$Pԉ} - ipH;v*ip; 'hipTz_PD o;=FsK$mHmG`=IHXFzd ֭a,αZ=Ƒ2aC #c,q(J "Goܜ%Ш;= wdP&G#lb7ڡܤI@b@U7d.42lB;{{yڝ>,E%V&{#z=s\Px'oӤIj5(uO0,<v _])7G{eˣU()sՓԑ)7n& 50zcYo&Aq'#i.0SF7ݞ*;4>CUnT]U4@QRgdRf]`;)q,jQf<wefT,{ܟ{nlR{ka `/JJ‘ypg/JDGOJuLYͿ\kՓNJjܨiߜJE F݋,ugKovɝx{a1{=닒b;}Q*7O'iE%͑_poTwzVtF7h;->_ׅ-wyRDAY/YoUXwVSe{n,{9iHЪ;7W;-͝ OQI+.\Cn_K>YQRxrOЮfR׌_G>%v?cee;}QjM'Ztv_o?;Gh;-n_Ϸg &fLn|gsFb,9B+Z~QR Kㆍ {E6{+ uMee;jW6mtg/jv8v6{Jj?ʝ}$)zǁ}3k i7khQfgqsXR1΂n{t8Mc]O+{}Wkj;{ŭ+UML3gma,l&}Zk/NQ`]9Ϥ]LoE_oe_Z2×9?fg.6L_KȮǝ>k촗`/J <~,*|sw ߸Ap Cx/qwguJ&| ]Qq?rF`wd dgo 4h[Xp8 ȣ*)O*Nnw@Q PQ7x `‹5؁ۭq b.A ܟ[{G>CN%asvw6vA 6sԛl}ϔ8/rE,_q` ^ԍUN擨q4WT~|ieZ((J Zń2lr(z=%_5)M׋cz/Tlz*iNGzKsݵځwj×#ֵ#!qΡ>q$q{ZiI ^4G›i56A'jZ~؇Lx ^˷Hܞ&q,hE$έҟMPT~;}dBQt̢zoi/v/J| t +@#c!k ֠|p /PԍMvj NfҺ[ 3W3'&ZN^ne58Yg3TʵpO? *()ɘ[ZE\]K؋ǜKPtMIRR2NW/ͮrqbk;n+ /jNWTx-7CQJzoՊbk0 f2"_l5Xw ]mx x)(7F|u6CQ8dEpg)W_;|$CQڗl V3V/7^ۊ~dxW ޡ($giCrӆ䌵<7>J@ֆ(_ <Ë X5Vv 'ۋͮ<Ĥn }v_un-ËŮ<uk { :Kpb+j& +i— 5H0s ρI bCk/6PԎ Gr RRR)X ҡA: kE%51Hb9kE)#Eڡj$ЧEx0/7 /bjpEMԉ"^ r&sg8x(5^^YE?$ċAB=C,4(zV]rU5 SX1 s !FvB.  10 _x:1PwKAJ6%aV=a&_J.%A1l<1_*\7H|Xk_VZds=oj1k%mX#錾WתCKhZ㉪z 63+-(]š7u^zQfO> UIW}7k1Δt'.%EiӚР7? zc:m1UinT~avM c٠8ÚqpNF[8#0KH gVq_Kvڟn 4F͗ñ]IWm_8vT|]S 6xoRr=o!Ɵ+Te{btm7(9&mU@q5q=/%Θ*zB,SCZŸ{~>w8x1i( RJkPYaaRfN`RD_4G¥y'D NM)oԮgTHaT|x(HӼ'(0*+zkV#h|R҄sYkT2n|R E3FoPft 8oRTM?j'yUk=`]~y`]6?cXwY9wY'MPWεAg8 ,E=,LɥOoHɘYLsMH8cNཧj6>oVe1jP33s zx9c98mN?K@Ź刜FP5'/ k0 f|GDɹOET%絽F ~:WZy j\5X#7;D!XV\xo3v6a)ٟd;Jyg\nt17Z+X--9Ey)(q*|sT$/gRp9J0Bs>%;FGTUے5¯-ƇFfwSKyR^tα5r~Y:b\=S Umu aufXXхu֓ [%a}%}ן6OT+̎ǨBF7Znh䭶b!ok3܏7KLyɒvt+:Ǥu@鷙RVXh(4Ϝfohj!y5H[i r3:g :{ Us; ZW=*Nl$tugB6S$;QҨ]+%x{/䎼IKjD Ns3 5򎜛i]<7cSxq35ؠC%_tAOl=}u(? ]~>g KH*y4X#:,12J'/V h>|}ǺA'.me=oyWc2 @<5>]y!ȆZ7> Jh.XZ8l0CgsnЍ|34Bo%znhb74.2PYvsvXdv脰C;T=sy(\.~hm ~h5ΑH_#~hQԡߔS>Rr^;E壷JVg8n6X#'5D? fpzZO49oDJ=JW֣̮ ҕ~wF}PΕ_K>l0ECSTS˒ґ+9?xro5آR>@qePZFiT[ #czYId/U36ȹme=O#㏜39f$NU}̿yN4,-(S`w$/uC=̧IZk{ T~I&ӌvTkZs4%ϙt֜_Ok_|{C1@1]boLKɴo^(sDWtfdC3&,a,s0O=0wʜ0eBFNuƝ-9_i_o eVC438s'DOJ1t7'Ǖ~#B6Cy6IieޕX;denO:cF t<\P8OiM&s&4Y;߰?2vOG#!!J. :4Zh$]W!J(ϕwλF~j:R5c|PfChYFi-^j#څOK7.`j(Ws^:p# 9/y8ؔ%WQڢSPn؝}õu+e_ґs!YK|<:x $Dg ukqpQEK^zs~)_ygՙL흯?q PU$_9ԁU?ZrXPUUuyn7j>|v'!GN7;tUCWTٛO\iUc|Vٛ7%%5EVbvc^+}ί ;#:{JQ*doL:KIG·oX%(S%j=g;_4/%rÑuG6;Yeŏ׆Um># HhrxwX"Ò=-n o5|“-wpN:w;V~5+{8Oil_~tGO[(ؔ0eUY0eݞS6Ord;r(^93Q5JԜv(u|e eIwl}[9qX_673?|t+3/vuI1[plϤ{Z8J3[|u8өk_ÚbtX3Y=C96hAq3CMs:ܟ^;8|cK=>(hiPUˌ$XjvvҡЎa.B;FJJs $ZAg?myWpI-4qFXm>i:+v'e=^vi SsPwR?S AO+⿫écGW~u3n/Ђ;iFUP|Vmfg_J_6V2a̻^XϛvmaJը܎qu~qEg.xA_ grhGھ|g| vv@Ru8޳c 6y-l%oIwP01GGK{5sfso\t8YDwkBn0֭2;_V 6>O,9g !ѾZn ?Gehz$^rvM[]y7R|m΍V?Dzpo;-{½ގJ Vj( wrԜo󴗃}[¾eov`Jϐ7};w91þ./;,ط޾K[8[gj\2ۑu)JY :[DC3}\[ c#\f(5Gs mHH{^n鱣Yaj+|dLZϯ}ѯ397K m4طҠd'R8o-l=Hk|$mF[gB &U; m;}]%+pdmo(t#S_Szgo &[M¿if[u# 6ZZ?K߬oi݇+grUJ?=oשk; #6 턺#WB;&-83z.G\\L-wjݒuYWΕN7co,#sg7o%tɟs*!];y Aupm5|vTf(wFk Q}`oE#\'&/%7vWӏϝM0;dqo3{}7NJʒܮmُʻ|]v~[UſN^g}V:<'伧 0%Nv'у{b=gޑ%oy^Gh46Wow6oTҏWB')a͕os:9wFvv{j=hv]+iEoA¿gPOF#䀋I7_#og}HfWt6zZ|lu@ %]l*FoLF^hߎ=kjJsb/uv1TzFuطڴV;U ](!=m@vطCaVۓ8oU7 \ۼι k =طüOd}K "9ogWӕ9cV};Ho5Jg-CþI[7ڕZ~&]ط™1-Dơ:ۄvo+`67cC{m,e/RlZ]aþU9F+[ t ~Nbfol,dr^iބ};oG`ߎoH ęmI•Z>pJr`N{o&`֢¾oƎQkZi6d2ط\0ݛpoۤ8 uf?i?po5pi[_b'ߏ3ZަV=M-;r?ý-_:[KZI-po*tiJUL3wFPFrT_t2½P_;^5wnB7Dpo8jý+8 HporήpoՏ*+wU];Gfåџՙ3fޮpGυ{=wO [ێrn i 6mD{;Epo8ZY+d+VgEpoLs*cF![ 䌽O,m0o ި9G~'LRړg׃y{#&Fy+E{ձüoaޮN0oÙnZοM-}>|>:9`J̯{ekd<Wg#x{ӿ}3兇|3zﶛw{ҹїwygߗvb7|?vW=~iSz::Kۀw]xttM͝˄VPct̅Sf-wj3*x$߯ 9PmZ݁k[o>#Azz%qY*=nj #x=6=ݎo9OMW-fڇg8g#UрpUp'z~:pJ:(Wa46EnKnk{P.ᶞE2U!{r,⴪v1 Ym3 ƥ '"+-p;.k..XyՈTe ɗڀp[ureKK:]s r@-^/[~f%oj &LسrQ &m1 Y'.AZ!|,.8[+\=%$+"p~ ; ܖ­tym`@l^!N7[ 'jwQnp~fXJ;J b ; nn#߀pnK v 8 NOLcݓg;M@-[ h9=[ Yrow@-^cbnv|Zun2yA= ],pnX,N.# m͍0Md5÷,}Wj$ GnDzv@#-dKS|ߡxR!AKمKnY'ZnkNEvn;kOV ܜA oV~) g_.eVJ=Bs<@+-$;'fR񼣏hvxd<6J8#ap;s6;ۀp;-$sn|i "zZIurXNA}Rxx+9Irm)_>i*iG{MvHqZ jϯv~{(/n{8yn< Cv wۄ2n.u@Np;p,Qf7j)m,icnzF>Q(U"%vns 6; ­FzXEAd:7x6{>=mW'T۳Avx n%QDS'M< vF4&!Nȫѳ[9!j-hn^sҖY%"μjl826"׆e\%BYQ䃾EspS;M/U߀[n;ht)cd<[_}!܆LᑼP4<h%hĒ\vvO(;ۜ//@!J_S#B$δAb8zv w~4A=fXFN/-̻WQ#3c(n#ˆ'dnW_k nG nG'n|7# ­*3\|6!ܦ­7uьnWJDJƻm~yZKc׉v@ ʈŬ)hNuGn#6G*ޮPmBϖwtW x|U|C#uEye_`Lj)rGz b@=%p n'h" 'Fnʸi "7zT ۹n6+(2+np[b} sK tbjvEGNԗaGIw]QaTLIkd=7'ᶥZ.Gpw 1Ō Yg~u+:z3ؑh9iGq& V3Yw;z3xx;"|f35GXyO_ |뎜6?4iO^Z~uo|эxxҗA=/nJs28paGf#9Yp*\XRfsq(k=v'9ݍn|趓v=; Vcmd@xnYP캎 km=B:BfdHƇh]n;-xqbtsmrn-ǻ jIg^k%w7tid@-Qt~m m5nR8Kt[ 㐣tJ92NGm/rtkmq9/ ݶ6G% xR{%yuVτ8u{S趱1N=mGVxw{|ٛ[J;Z;lNQJR꼨 jGx {A=6N ߗpr@J:~ғ FfqGٛ}7?A}~rn"yn+'3gpZm=I6…NBpd*-e!+ktʜFg+\vnk/ⷍ xngNR } _鳖A89pOzmĻD-ƕ_B̯P}~0 㛎fp[x?Pn1 8ݲ[-z([[f<2sfn ko>~3nM4ʭW]q܌Ғ2c嶾$k y|9ar;_#Pnc9/mX#܎G ڶs<;(IΡ܎.Pn}熴ۊxr;E Pn'X/F(۱vPnn3xw0(sLޜ&[P':5N71G [ihJ|]]|<0(7̉znr;|JkPnm 1#,ܠvsk r+.GΛxwn;ؒ.ޫGkt+JK])c등.ҭVuzw/{s:"̙zN]ej;`Z-BuqƊִF<8t+m)yBPW 7Wn5B:is i?ڝ]`+^k#SZmB$9?w@ V69uEgw vdv|[z~V{Яan3;hm!xZzI΃v{'vpWv;NHv2ݠG6ݎchwfLhtvƊ vƎ%BL h_sXv>3vݪ}7?RKg?s5J^Ι_y5Ļۛn׾5 wjIγwחrjVQxÏ|ZI J#VxK<Μފ/0j޶ZMZ%NsV$cPoO#gwy)Y{9ztv3j#7=˻ͻ% ݾ ٕ%^O%M|w9 )QF>z|A]{F3:ގ#wV5P빝V8koxWrRAίt6Y_҇ :W-zyoZkmvޛRv@ފzH,?ӗA}?N5?DroGPoآ919]ljzݒRo Ygzk7n-&ok,zvv(~x1P6Z &'[~8 VPoGɹ[XkЭMvWH[}9ۻ#ȷ_GPoZ 5wPos#xn}-8 Żb[) \doyOuq_΍w8on&;I[oX\mQ,?b- 2mxzT VC[КIoY֢jYk9`!Eɛ[:CwGnGwq+FD :hzj]Pu'=rK+:szr$o69o%C8Ci [/ fn*snߡrs2T8(K"\FY?NVsoe-7BUK&op%GF;|LMN֖_svr;?84OoA _pAD٧Yxd7 n:swl{Gvm?J7= Y i]8)jWkykW7U=C# e $yppo\xxܴ gr.w>>I[WԬyk7l \uєGa&KGv~VOҚ=e2Ctj ͈EŜD=`OrǞ(*֡=Vco"W}mҮ~3ka-3^0p"#uǣ \`k:Ds}0p7;7ZQc+כ6 "}Lyy;樷/'0p7fq}^!HJtu,^ޢ WZ諯OFD%Y`EǞ[h` /Y-p6%= FoB'u|7[OYܾ-G ^zlxyZn0pkNew/oBG?~˛+k0p],.;7m \k0 !6C9}C<=(gt[웻G{`bZ{ʯxm-l:por,bC{'H>9 oz9ZҸ=Gas/T+^f.nϗMlmsC0_8xh;gF#ɧvu`[2#(i\y[tv]0o+I$&̛hb;`N^\{G0$bV盖CkX͌OJW(g7y«ǂQN?zu;¼A`0o'lv\ife~rٓū۷0oӟ}$c˯t:R]ȹCIѾ~ݨ[ס6T<럨x*(g+x\Jxio`#g_>`N{(h+:c¼NrN&m+*xYyGweN4'B8Œ vPXgO4gbi=^`Fxǥgz.vLQmF$ٯüM>'k{ fg3:[v#k/9QM[*Xjzڳ'm}KTӷ9'^I0x2x{r̛y;DʯKGD`wnYys-'궥Ƀy+ jp.V=ÙfUy[-ܸ&αzGη[1oM3xMe-txw-陹y{ Z`ަ=FB۟9h<0o v2uī۾{+b=%0oe0{ƛ^e'xugWYW(: 初ƫ/Glr66ad3*" K^yvFOܹPiʙʯk&=rn|0o7)-W6f{tGMnQkmw(^V(gF{ī۝wMS8rW71D5PμGE}+{{?fVImlpok=,6 ?\DYf(aRfnu{cFdf{cB"o[G=PUKa%x_.09{9Ǒ*f=ڻ '9099mIQze6yg9xo$Gpo1/-ECX"XJk\ ^vtss2۱GRuu'ilߨbF5uFJWCv|V=zɻ؄;.QM߯P0vuc(ݦ½Jx{ذ'1Gw{+`CGl؀{;<X9[wvީ99>џe{;@S{uPV8=n@v5nmƻfD9}{;^S)wn&Y 5ӫozzRG0+m{3ӺٟY2^Dz. m/ fe1ԉjzL$[*sxxsc툇6 E>f\VAe|$iITӑq@'y?yG51#IK[9{[ oy|^bԱ=R3^Ԝ|˨Hyq{Os[*e')j/o]ecr{:~М/o//onqV+~(:܁ߖ`CӥΜ^Lg8sW, v#2lC2vrܛڝ_s~=WP9ܛ8Gpo y7Tb=g-\xs6zmu%Fwa/oTƓ/on6{(뇹=^޾у7.sל%|V˛-Ǚv&W~g"1j %BFo?ަ;ZG=ۂ>tsv{;y{["po%k=j=ɯl.ܛۂGpo_: {sE/q*K%ZRir:Vt#J Y8uK .vy+btx{ov<'֞oo'霗TfBD5}>9{[wrs4jQ'^|>CEO93QMiy9oJ[چJTӚfpoj"BWKD^e{۞ v*ђ c'[Jo63B䈗](U9C(:.(U_oo̻錷6 w݄yyڏ_~|I9>j½F|6| 9o_hyg/L3eDp} #{o½-=?wq 7&ehv_ݴPFG,CtZvP]-Ғ3ݔ*vyuWxʈ7Ldm(n&XKjkh-wkj¼q={}+|Ν^|8CSnKeNގ8P_'q2ގ<ޖ񦺡om覬3Mnhx{=sۛooW63>Gdk|==y3`埤svUZ m~9ޛپZ~^ ^.)Q%}HD{K[%r1i{;Ɯpomx|ی`>c|P摔FLwp7HDޖ3~_Y|Z._>]Ik<|xa#3 %93\ ޿ZmL wK{:!ކ;sWG "+TCIBWL(G3C"krPDJzɑȇD8ݧsgejW8k_I|;ct}~[3N[|J`o>K+?$SX˯/eNL%[ F|h0#Az`;WP8sO\Y;3طɻwԎ!ڞw;#w%o9k?3ȹU3N9qg&;sƟ#0<3NŎ_PUR7%hT eooQp=y}ځQ GB=Z"`j(/݂;:qJ(@iIZ/7T(3[*3od&^wt&©3^Ghɯ;7|D޻go; 3s?.n^B  wp[@ޙ-_yg v\ n~[֭s*;t Y?mdwh?:z,[ n$JT#6yWGcޑ;mJ_3kՅMXLA'J_i?{3`of;/./X8,~բ**wV&˅];#-K>x wG/8GW*Lݬ`V 0 7 ΍nrC}o~5J, A KG0pzU3N+p2{|I`D=UvZϛn+.<.d\%©3_Z7-)p4.,\ڠʉյs 7 p.ɡĹG63ycw({R,܋ w:熮d8HNVLFJ~|]8'ZY>XIM#j.̰F:ia9=l秽FW]nD8]foX8QF c7=hoVX81JVf7чf:m_=B>o7JMo Ԍ7/:y]X̟`fZzGfrn(zy=#Yv9b;7vGڍ(;B)\J;­s={G(xF9jDoWn._ǎkCXIP& 4.Njp*BLS'3K}YfXJT4yO3,Ǔ(|{`GdGѩ @sz',f)Xs2`jŃp>) X8Q .,w@(w*%%{zk~]<'G0yc&X85fps`;g2$/X8> Y{v^3۝ 2"f`4ˑh+r90$3t9k%r6@?#Y/&cD>Rj39 21_XIkn\pzljO#~򱩭Hnp?۟ZYк&b܄[˯p'].,|&)@;9o}&<|,[z\=>}8_#Gr$=g"舜Ea\Fc<~}̝GMGMͬp<l7MBGR"> 7qe7Kpp_388n38ӧJgvnz|UL88nQs#t|  ņjOnJ;ut, D7}D7}F-ZcmY'ry8?3MafD7+ ~ʽ=-{ig(>ݚ 7 =sc^_*㓼ż.>ҽΆfXΧ}_w#sO3鄃[| uB]1Y\7e掹;pptwz&w88&5muS_{6sZpp|M8 :j˘_rIsw>yop9E+:O3Npq7s$N% H[-7g53c=$ǘ_g1{ޑ#g%~ ~=88S&9P">J۲{7piHpp_Le.9?b7αoc%%38ߠfm7'܈;[cjƅ>]R>]b2'/QNSQҬLIW:Y__o)7Z:#mJ!fppǕcfR:2;Kj|z$i')քW NtW88Qi_ot;clVr҃rfJӜITf4%i4p8HP]˕`&Z?̬vZ!&|vD9?o!崓aŦtܚn]b87ń]g˼WR99Y-\͟Qg>5>故_aepp#gpp6!e=U&I2\Eg$kO^J:ϕ|5vGe=_Kg`\vǙ_ VzvاVvpp9MZϼsϠʞVIԾ=CVYQ"3{jKqWofqeAw#&B HG6ڙHA5} N +J 32DӴ6 6HP_3N1{[I`V{ .URWvXsQN7(&W?D>Q(?~'.Ν+Wos]|$]|H(9]~oAx f9UoHrn m#goarg3ev<-v3yO/{DY7 ,4}7C4PY[%_ ߳|[doy~b[#E_o}*CўƜfgO>.x+5q}E)]u%+Buq#NkPOPj5{ۣZh=r߼fj[y'WkS;w9{)u6E9{J/]W~>0s57V n3v+~XVoq=S"[k=o/5w&" }c >#P~uz(i>ξ;sIjiߛ=v]OZVo9qo ?T P/wP?YtL]KO=o_x]x;=?oǟ?nxk5ovy﯍u?uuGmnmSͿw]}\x?|ow]})nW?eXoau;m]w=O_׭nxoO\k}o^/ϋEy~?//F^@<8~^l_̟Eyş?~^)OIJywIwI[y=%m?.iiwIO{lK~cSҟ=?%iOIcSҟ=%?.iiwIO{Kڣ.ii=hKڣ.ii=ڟGSҟhJOIڣ)O{?%i=K:~ڣ.i=K:~ڣ.i=JOIc|K?,JOIc)O{%=~c.?q.?q.6=~]=%=~]rǟ?1g|?%i?1=ΟK:c.i=ΟK:c.i=ΟXK:c)O{?%i?=֟Sҟ8/}6Nl]X ;7bIS¸s2-wa^RWXkC(kjF?L6U@4{۽Cwz5E)XνWQ[ygPȢgƩ4~Ur&}` `wظ Yս_<UyDZxlnn%W_f^wEu?b]_Sp8pUb᎒ƦacgL^Ei٫;Hb(jCfɢr'/[ QwP_;9FyZ/Ō p?\|9 LEw&u1!'Rߚ~zYmשe/a4qﮄ-JX;Z[Qқ 1Az4ty^T;P52֯ʯ˝h99{_)ꨅ¯f]xo<v4D0׿NOZ/F9~}{?PjG P z'H}Q Rpue< P_'Hn}:lI=fm;{U%RmύjRH{ޏ9)`{[r;=9k=}<8U%eˁg#%Qtge(/*e;7|cq^ɹW=WKK| PT=$ݑ X35g]mYo#|nOhڥ(OO_K[ϴ5R^OTR/fJ:MxVTJ~*G3%Y) B\DJԍТߞ}),AQ=Uf:<=w܍@B\<]QmtqZ.'ՙ?F)uQ#36KpTThɷq5Ӓ |xw>'\-5gC}QRʬ6J{6_ii=Jπ =~7.V^Z' $Rԑg0<w*J 2mG5ܥk_.k 7&7Kȟ71ˣcmyӾoY*&%r+_tHnx^P|z}ߨymj| +/ɥ{2i:& jG=2 wo;{_7*GƷǷF#7MF:MӾZ.W)+{Fٻm^ۆzf"!S<o7yMk}#WU۾_H;q&iMFdQ>&#׍kl<+6&lxc}%ڎWﺶo.eɵHgK[卜+9K[*4-|:OL5"tX;k֤KşIK=]02/솑4Vn\E~Ǔ{5*r}H٭o|d6G@$O}?|ojq *r${-MBn2_{Z:ro;s4{ &܏Fqg||Li2VYy7=SoS=g|ynKPמs<tv|E ;=mڟIN !9~H L}ؽyˠ~}~Tʎ87c3Q~DF2VH< .pN1x9[ĩcy^i+:e=`ղ[4!0{ĹeP_qt_! <:n9fG&ݷu r/Q>t!;VH2淡՛;o;>!4|r|`;Gޤ&ռ5L:Z\+*73Mrnyeii^-r}=ӫeZa y]U5s}ϝ\Maorm} ̫eAg^n#Bby ]R3?[v4-lϐ*3#?8O_J+M @B:4_g4_x^Y9%,Qg uj^0[E9Bh!f/˻E 7H5 UM7۳UGN؛-^@4jG,Hn!M*9U jE*uxEAtP#~!թ1A[ |ۀ$"nBq^YAf#pU}DUaF\ܽ<, 9 qYZWpJd-,b% >H ab+*.i |=3XDi|^!yR,BV#n\dJJⴹjQ6ѵw4 q%$n!"ԸH0B~Wp7&Yl X9OJ?[Yxot 2$=bGǑF҃Ô \#PА\6i/zp JK #;H炷 iPGjsK*9diT+.!4JSTN#Mq9S8Uw>W/jCh]\2FLH?\hA*o)f]FH:R/!rrҥKgP},}(QbO :gF:FvuWA*uGO%9R,,elvuR%K|]xVTxKyx4JX#璧{")dTr:h<[ދ.Hr14 > d qMiTDNէcCGH6=$kZthtSi&~H6=+ZCâ "CP 7tvR)eop:z=QYC7CZ؇tڅ HaKmB@ ~l5핗ؐ҄MC&)p<֐>0t>}x.jI:Nҏ$!jt.L~ \Q,sAR:ǘ ]:3{Hgt>bAjx;Y%ϯT ?H^i+X-+ؾv EpYlp#|]B ]:]AH̞,{\:?!]zV7/HsY=mB&B I8Kͭ.[s[LGTsN>&<1$ut!2tz:ä(Z t y1]W%I & I*!QZ,n2H7)!)1 {8P$gQNln}Sļ˭SUu&#5o4T!Z@~t#džTbvt£JY%K${`60s~Tfnk^ 'UKRu?/^IAHtu҄W[v_IYMYmd7և6Y'M1[<_{8jBNM$ d XO&-\  <%|-bl@.wHU\cQ&28N" oIL2Qՠa6KB3 sH(.!U. 2a/$~d8*c$%Sqaʑ>pīxrwioҵ/! 'H$O24k: :%E#^'xRJ.n{_m]2#@8Y̐_![rW%-寐2/qvR.&FcK rtYV9 upy4L-TX[_eZmH@jvR̖\V$, 驪33A€2)VJdhGī›#$!҅N;N;ƾ R=ے%Mq҅lېN.[]IZd͓P6Oy&Rܳ kU= 'bJdAF 2JbL!*ѵ%XaLCdv#D$4 t &MwbбT#͘a*ǒ#Uoҁҽ^§:n:R!g aڹhN27P.K# u#TRHt{$aCӄG ӏa;Kukt<D fH|oto{$MYG20}K/}ua/$9r>|vUu4!Gw>Pk*)n/SFVNW`oٍG(sl;%rmoESV#q@/9Y,cAF~jg! oQꌙr U*FLAi84x_B9I2+ ~"B{8a 1B]G4e2FKv:A: SFv:YfT8i$TKP?d"Vem SH6RAc+:pe_QT=Ɛ4GLq :5 A~E&j6ąZ3 gve`bQ2\V2  Mj4p$nY@R;CDtcx$ rCiTp[1Az&iU;D+4Ɇ?P/!@~EV~yA2 qXb{39B\Cyg|m|@fҋΐyecIۖ=LFs۸at G2݌R]$Hɠ=]x{~J1 ?$*Ro, :>"]RŚYƆ7ipčOy/p8FۏN͗q[-s S[- &B-Uz? ݃h/ rU.2Ծht  t)BrIx8 9ՑcL"iMXyY8HoxY<Ӱd)={mQպX2lYd[2d<28WW7MەK^B8._, w- D9B( *`1f=X,1tUp 03k4W"9.<߲ Rurvb6|2W0ş B\1!#d7BoC#)!ʀPpٍnIӠN2!MV4I-Lm.,+Ad,ۗBT@dDiT{sҕ; 2T42D- U4va R%[-pP-VmKVKi\2OvXM?!2,),MXecRlZW d Qߕ3FH9B(jT!N-˔pKSx Di+&"5ECUj;"^)_A.K+$:VkQE,ڵ*]sYe5{3]%'ܤڕN=ninnpw]5mCQxCaCV,䋞eCZ0)dBkc`kC`[R5|ЏS=:z><"#M@k26W%B*B։i D&5ǓeMwׯ7RQ5_ufN+$>Q|[0/M%EU6bMhkiz݂1n6&.lKQ% ;؃w7MoARlVۑG{PO2|1B\vaeETtpiUɥ iBZ]sLTg@ƹi1aHP|L)5J3ҴRH DxHMs }a_|b)!yp1NM)+@ıN5MClfgtMSvEYA5\L.]:`tIgoU=lҽU z 2!PD9׊%k&TSQ[J0ru c 钙˲ފEi4 ̋MxbH.l|d)DL d"]:kv׼ެu䉦X?’&ok^x lDE,DU{k`n Y6#zQN@n-W;1.Q_XmYHBv`os'-S Ц\+:Az'Đ06n0#ݥpjЕ?ReHyP|_tXCw%"bޗ{1Pó{H*8$6#ʊNe]3ɧs@čW!Lr|IlPCWt;QpNb'0u2CN K9pC& d3AB\558 KЄѱn$%gY{w^u;A/x=D4ޑŪ^dV|j+yV6ޱ!LSmOzB_K%Yq]9EJ) n Iۏr>VY2He.nu~pu/AV SE( Y ih4 u8DuJ BrE?p REJnp RBI39c,j˝JNʫr+Zy>""YalH$*<[f`Ն< D_uVSLV~8QU*6v!U21zTNqQuUQ./2 ʗ ?\d+lUG&Y1G[s*q u;O%_T谺rI8(Tۋ %kXB^my^6A_ xsz9U_W[i*t;Vnt&NYH72@TKK>JMhUHdeѡJ=UU옪J<@z0߻*ҭ~%LUzָH/H QEY1/[KK4U{O[+T a{bLB?d2B,U⹄I jwfozuxJ e2!9jj0CWg_{>tkp9꺐jBR-{v>*d$0UlEw7@'[W^nY6U4xqd QKSzxR:a+mi~/peprhrڄ>hR47lBg6lY-5{ iXi4j%r~LC>L?t7Q2ijV6N Ҡ&6kxQ(Ѝxp¯AJ:Rݑ 6iỴ4M*'J[L YeI㒡SWo(W#S[L=97]Tr5qdꗳpj0&ځP RE9pJ>95}܊}T7_MH1@h p!t.)gZYoW-Z,+*i'<7Aqe/ WrbMJfm6[^6 Wo4]2224jW#{yZjUC#F@hw{u(A! Q, ܃9]jo$< O(FBm}5v|l4v6Dƿ`xMyduF؝ JAu&6CbN8n)NxFyd:E&KӕKpSIjlSCn{=Y ?l32gzB<AQpݑZ;~(]ԽVas]62NWuGޕJԗ_%w_|$FCcH#qCV#Q}W4lN|W '/!,mc@`jx,HWwIO#$ \;kK&0? DZAh@wG.\Erz`q9yd|90= D,=r:Ԧ:q)9҃__Hl Q\"I!h PC ۀ4n oUcHtbi:n!h 9A~@uC@Cn$Sbٱ8xELFHdt.TXEO*1v c;V.;S (Jc'‘}RdRyw" Yd'; 2.EA: bPv|GA#Ei]y( raҦ 2Q"r-blV%ێVHaF˓QaYa dԏGmr?b@.r*ꓸA!Z8A xvOHIQ0Q/7dOKиI R5d |tNTgqEL$Y>u #N_ݺqc \Q Ib,;2+׹;s꾴Y}}i׳\8:wdN@Jg1&1#DC841q$[g,('/5V* nJM/;WꊪhB>ȯH)һm;GWݶ!GWݎ:/^!h('DKH$)6[w D̶ DIO5o&4tT@n~ҺKGM?FtfFA76Pp@Kc t~FKq΃"\*hTL.Ni^V UVE?2S#EN ;vH_*]-(AU~Ű=-;djIx~ b|!6su{Ip}= @MhEm58IBʲVȦۯ2"Bzj?YDٮC~ȦB_F#IZ1+TE3=MjrGd)E$=_g45rNl@_w 4RRG-٤XA=t"mvO0p U|U_}tHQ7_!/x#8 ?S]ooyWE_,]O<ы^D/[xw<;O'zy{MWBl拷7j^7j|㷑/A|``2ⵃ7~},oR[^*7WJUR{U^*7WJUR{U^%+7WJUx{U4^e+7WJUx{U4^+7WJU|{U4^+7WJU|{U4^%,7W KU|{U4^e,^u,^,^,^,^,^,^,^,^,^-?o~7WIϛ߫Ujy{Z~^-?o~ʖ7WiUrz{^-7WyUrz{^.7WUrz{^U.7WUr~{V8].Uu<=Wo鹪]~+PU[zzJsV"\%/7WUry{U\^e/7WUr}{U\߿߿?M. fontforge-extras-0.3/showttf.c0000644000175000017500000065316311254363111016074 0ustar kestaskestas#if 0 #include "../inc/basics.h" #else #include #include #include typedef unsigned int uint32; typedef int int32; typedef short int16; typedef signed char int8; typedef unsigned short uint16; typedef unsigned char uint8; #define true 1 #define false 0 #endif #include static int verbose = false; static int max_lig_nest = 10000; static int just_headers = false; struct dup { int glyph; int enc; struct dup *prev; }; struct features { int feature; int nsettings; struct settings { uint16 setting; int16 nameid; char *name; } *settings; int featureflags; char *name; int nameIndex; }; struct ttfinfo { int emsize; /* ascent + descent? from the head table */ int ascent, descent; /* from the hhea table */ /* not the usWinAscent from the OS/2 table */ int width_cnt; /* from the hhea table, in the hmtx table */ int glyph_cnt; /* from maxp table */ unsigned int index_to_loc_is_long:1; /* in head table */ /* Mac fonts platform=0/1, platform specific enc id, roman=0, english is lang code 0 */ /* iso platform=2, platform specific enc id, latin1=0/2, no language */ /* microsoft platform=3, platform specific enc id, 1, english is lang code 0x??09 */ char *copyright; /* from the name table, nameid=0 */ char *familyname; /* nameid=1 */ char *fullname; /* nameid=4 */ char *version; /* nameid=5 */ char *fontname; /* postscript font name, nameid=6 */ double italicAngle; /* from post table */ int upos, uwidth; /* underline pos, width from post table */ int ttccnt; /* if a ttc file, number of fonts */ int *ttcoffsets; /* Offsets to font headers */ int numtables; /* BASE */ int base_start; int base_length; /* CFF */ int cff_start; int cff_length; /* cmap */ int encoding_start; /* Offset from sof to start of encoding table */ /* cvt */ int cvt_start; int cvt_length; /* glyf */ int glyph_start; /* Offset from sof to start of glyph table */ /* bdat */ /* EBDT */ int bitmapdata_start; /* Offset to start of bitmap data */ /* bloc */ /* EBLT */ int bitmaploc_start; /* Offset to start of bitmap locator data */ int bitmaploc_length; /* EBSC */ int bitmapscale_start; /* Offset to start of bitmap scaling data */ /* feat */ int feat_start; /* fdsc */ int fdsc_start; /* gasp */ int gasp_start; /* GDEF */ int gdef_start; /* OpenType glyph definitions */ /* GPOS */ int gpos_start; /* OpenType glyph positioning, kerning etc. */ /* GSUB */ int gsub_start; /* OpenType glyph substitution, ligatures etc. */ /* hdmx */ int hdmx_start; /* head */ int head_start; /* hhea */ int hhea_start; /* hmtx */ int hmetrics_start; /* JSFT */ int JSTF_start; /* kern */ int kern_start; int lcar_start; /* loca */ int glyphlocations_start; /* there are glyph_cnt of these, from maxp tab */ int loca_length; /* actually glypn_cnt is wrong. Use the table length (divided by size) instead */ /* MATH */ int math_start; /* maxp */ int maxp_start; /* maximum number of glyphs */ int maxp_length; /* mort */ int mort_start; /* Apple metamorph tab, ligs, etc. */ int mort_length; /* morx */ int morx_start; /* Apple extended metamorph tab, ligs, etc. */ int morx_length; /* name */ int copyright_start; /* copyright and fontname */ int opbd_start; /* post */ int postscript_start; /* names for the glyphs, italic angle, etc. */ int postscript_len; /* names for the glyphs, italic angle, etc. */ /* OS/2 */ int os2_start; int os2_len; /* fvar */ int fvar_start; int fvar_length; /* gvar */ int gvar_start; int gvar_length; int fpgm_start; int fpgm_length; int prep_start; int prep_length; int prop_start; /* head */ int fftm_start; unsigned int *glyph_unicode; char **glyph_names; struct dup *dups; struct features *features; uint16 *morx_classes; int fvar_axiscount; }; static int getushort(FILE *ttf) { int ch1 = getc(ttf); int ch2 = getc(ttf); if ( ch2==EOF ) return( EOF ); return( (ch1<<8)|ch2 ); } static int32 getlong(FILE *ttf) { int ch1 = getc(ttf); int ch2 = getc(ttf); int ch3 = getc(ttf); int ch4 = getc(ttf); if ( ch4==EOF ) return( EOF ); return( (ch1<<24)|(ch2<<16)|(ch3<<8)|ch4 ); } static int32 get3byte(FILE *ttf) { int ch1 = getc(ttf); int ch2 = getc(ttf); int ch3 = getc(ttf); if ( ch3==EOF ) return( EOF ); return( (ch1<<16)|(ch2<<8)|ch3 ); } static int32 getoffset(FILE *ttf, int offsize) { int ch1, ch2, ch3, ch4; ch1 = getc(ttf); if ( offsize==1 ) return( ch1 ); ch2 = getc(ttf); if ( offsize==2 ) { if ( ch2==EOF ) return( EOF ); return( (ch1<<8)|ch2); } ch3 = getc(ttf); if ( offsize==3 ) { if ( ch3==EOF ) return( EOF ); return( (ch1<<16)|(ch2<<8)|ch3 ); } ch4 = getc(ttf); if ( ch4==EOF ) return( EOF ); return( (ch1<<24)|(ch2<<16)|(ch3<<8)|ch4 ); } static double getfixed(FILE *ttf) { int32 val = getlong(ttf); int mant = val&0xffff; /* This oddity may be needed to deal with the first 16 bits being signed */ /* and the low-order bits unsigned */ return( (double) (val>>16) + (mant/65536.0) ); } static double long2fixed(int32 val) { int mant = val&0xffff; /* This oddity may be needed to deal with the first 16 bits being signed */ /* and the low-order bits unsigned */ return( (double) (val>>16) + (mant/65536.0) ); } #if 0 static double get2dot14(FILE *ttf) { int32 val = getushort(ttf); int mant = val&0x3fff; /* This oddity may be needed to deal with the first 2 bits being signed */ /* and the low-order bits unsigned */ return( (double) ((val<<16)>>(16+14)) + (mant/16384.0) ); } #endif static int32 filecheck(FILE *file, int start, int len) { uint32 sum = 0, chunk; fseek(file,start,SEEK_SET); if ( len!=-1 ) len=(len+3)>>2; while ( len==-1 || --len>=0 ) { chunk = getlong(file); if ( feof(file)) break; sum += chunk; } return( sum ); } #define CHR(ch1,ch2,ch3,ch4) (((ch1)<<24)|((ch2)<<16)|((ch3)<<8)|(ch4)) static int readcff(FILE *ttf,FILE *util, struct ttfinfo *info); static int readttfheader(FILE *ttf, FILE *util, struct ttfinfo *info) { int i; int tag, checksum, offset, length, sr, es, rs, cs; uint32 v; int e_sr, e_es, e_rs; double version; v = getlong(ttf); if ( v==CHR('t','t','c','f')) { v = getlong(ttf); info->ttccnt = getlong(ttf); printf( "This is a TrueType Font Collection file (version=%x), with %d fonts\n", v, info->ttccnt ); info->ttcoffsets = calloc(info->ttccnt,sizeof(int)); for ( i = 0; ittccnt; ++i ) { info->ttcoffsets[i] = getlong(ttf); printf( " Offset to font %d header: %d\n", i, info->ttcoffsets[i]); } return(true); } version = long2fixed(v); info->numtables = getushort(ttf); sr = getushort(ttf), es = getushort(ttf), rs = getushort(ttf); if ( v==CHR('O','T','T','O')) printf( "version='OTTO', " ); else if ( v==CHR('t','r','u','e')) printf( "version='true', " ); else if ( v==CHR('S','p','l','i')) { fprintf(stderr, "This looks like one of fontforge's spline font databases, and not a truetype font.\n" ); exit ( 1 ); } else if ( v==CHR('%','!','P','S')) { fprintf(stderr, "This looks like a postscript (pfa) file, and not a truetype font.\n" ); exit ( 1 ); } else if ( v>=0x80000000 && info->numtables==0 ) { fprintf(stderr, "This looks like a postscript (pfb) file, and not a truetype font.\n" ); exit ( 1 ); } else if ( (v>>24)==1 && ((v>>16)&0xff)==0 && ((v>>8)&0xff)==4 ) { fprintf( stderr, "This looks like a bare CFF file. Proceding under that assumption.\n"); info->cff_start = 0; fseek(ttf,0,SEEK_END); info->cff_length = ftell(ttf); rewind(ttf); readcff(ttf,util,info); exit(0); } else if ( v==CHR('t','y','p','1')) { printf( "version='typ1', " ); /* This is apple's embedding of a type1 font in a truetype file. I don't know how to parse it. I'd like a copy to look at if you don't mind sending me one... gww@silcom.com */ } else printf( "version=%g, ", version ); printf( "numtables=%d, searchRange=%d entrySel=%d rangeshift=%d\n", info->numtables, sr, es, rs); e_sr = (info->numtables<8?4:info->numtables<16?8:info->numtables<32?16:info->numtables<64?32:64)*16; e_es = (info->numtables<8?2:info->numtables<16?3:info->numtables<32?4:info->numtables<64?5:6); e_rs = info->numtables*16-e_sr; if ( e_sr!=sr || e_es!=es || e_rs!=rs ) printf( "!!!! Unexpected values for binsearch header. Based on the number of tables I\n!!!!! expect searchRange=%d (not %d), entrySel=%d (not %d) rangeShift=%d (not %d)\n", e_sr, sr, e_es, es, e_rs, rs ); /* The one example I have of a ttc file has the file checksum set to: 0xdcd07d3e */ /* I don't know if that's magic or not (docs don't say), but it vaguely follows */ /* the same pattern as 0xb1b0afba so it might be */ /* All the fonts used the same head table so one difficulty was eased */ printf( "File Checksum =%x (should be 0xb1b0afba), diff=%x\n", filecheck(util,0,-1), 0xb1b0afba-filecheck(util,0,-1)); for ( i=0; inumtables; ++i ) { tag = getlong(ttf); checksum = getlong(ttf); offset = getlong(ttf); length = getlong(ttf); cs = filecheck(util,offset,length); printf( "%c%c%c%c checksum=%08x actual=%08x diff=%x offset=%d len=%d\n", tag>>24, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff, checksum, cs, checksum^cs, offset, length ); switch ( tag ) { case CHR('B','A','S','E'): info->base_start = offset; info->base_length = length; break; case CHR('C','F','F',' '): info->cff_start = offset; info->cff_length = length; break; case CHR('c','m','a','p'): info->encoding_start = offset; break; case CHR('c','v','t',' '): info->cvt_start = offset; info->cvt_length = length; break; case CHR('F','F','T','M'): info->fftm_start = offset; break; case CHR('f','p','g','m'): info->fpgm_start = offset; info->fpgm_length = length; break; case CHR('f','v','a','r'): info->fvar_start = offset; info->fvar_length = length; break; case CHR('f','e','a','t'): info->feat_start = offset; break; case CHR('f','d','s','c'): info->fdsc_start = offset; break; case CHR('g','a','s','p'): info->gasp_start = offset; break; case CHR('g','l','y','f'): info->glyph_start = offset; break; case CHR('G','D','E','F'): info->gdef_start = offset; break; case CHR('G','P','O','S'): info->gpos_start = offset; break; case CHR('G','S','U','B'): info->gsub_start = offset; break; case CHR('g','v','a','r'): info->gvar_start = offset; info->gvar_length = length; break; case CHR('m','o','r','t'): info->mort_start = offset; info->mort_length = length; break; case CHR('m','o','r','x'): info->morx_start = offset; info->morx_length = length; break; case CHR('b','d','a','t'): case CHR('E','B','D','T'): info->bitmapdata_start = offset; break; case CHR('b','l','o','c'): case CHR('E','B','L','C'): info->bitmaploc_start = offset; info->bitmaploc_length = length; break; case CHR('E','B','S','C'): /* Apple uses the same as MS on this one */ info->bitmapscale_start = offset; break; case CHR('h','d','m','x'): info->hdmx_start = offset; break; case CHR('b','h','e','d'): /* Fonts with bitmaps but no outlines get bhea */ case CHR('h','e','a','d'): info->head_start = offset; if ( length!=54 ) fprintf( stderr, "> ! Unexpected length for head table, was %d expected 54 ! <\n", length ); break; case CHR('h','h','e','a'): info->hhea_start = offset; if ( length!=36 ) fprintf( stderr, "> ! Unexpected length for hhea table, was %d expected 36 ! <\n", length ); break; case CHR('h','m','t','x'): info->hmetrics_start = offset; break; case CHR('k','e','r','n'): info->kern_start = offset; break; case CHR('J','S','T','F'): info->JSTF_start = offset; break; case CHR('l','o','c','a'): info->glyphlocations_start = offset; info->loca_length = length; info->glyph_cnt = length/2-1; break; case CHR('M','A','T','H'): info->math_start = offset; break; case CHR('m','a','x','p'): info->maxp_start = offset; if ( length!=32 && length!=6 ) fprintf( stderr, "> ! Unexpected length for maxp table, was %d expected 32 ! <\n", length ); info->maxp_length = length; break; case CHR('n','a','m','e'): info->copyright_start = offset; break; case CHR('o','p','b','d'): info->opbd_start = offset; break; case CHR('p','o','s','t'): info->postscript_start = offset; info->postscript_len = length; break; case CHR('O','S','/','2'): info->os2_start = offset; info->os2_len = length; if ( length!=78 && length!=86 && length!=96 ) fprintf( stderr, "> ! Unexpected length for OS/2 table, was %d expected either 78 or 86 ! <\n", length ); break; case CHR('p','r','e','p'): info->prep_start = offset; info->prep_length = length; break; case CHR('p','r','o','p'): info->prop_start = offset; break; } } if ( (info->encoding_start!=0 && info->glyph_start==0 && info->head_start!=0 && info->hhea_start!=0 && info->hmetrics_start!=0 && info->glyphlocations_start == 0 && info->maxp_start!=0 && info->copyright_start!=0 && info->postscript_start!=0 && info->os2_start!=0 ) && info->cff_start!=0 ) { fprintf( stderr, "Required tables: glyf and loca have been replaced by CFF => OpenType\n" ); } else if ( info->encoding_start==0 || info->glyph_start==0 || info->head_start==0 || info->hhea_start==0 || info->hmetrics_start==0 || info->glyphlocations_start == 0 || info->maxp_start==0 || info->copyright_start==0 || info->postscript_start==0 || info->os2_start==0 ) { fprintf( stderr, "Required table(s) missing: " ); if ( info->encoding_start==0 ) fprintf(stderr,"cmap "); if ( info->glyph_start==0 ) fprintf(stderr,"glyf "); if ( info->head_start==0 ) fprintf(stderr,"head "); if ( info->hhea_start==0 ) fprintf(stderr,"hhea "); if ( info->hmetrics_start==0 ) fprintf(stderr,"hmtx "); if ( info->glyphlocations_start==0 ) fprintf(stderr,"loca "); if ( info->maxp_start==0 ) fprintf(stderr,"maxp "); if ( info->copyright_start==0 ) fprintf(stderr,"name "); if ( info->postscript_start==0 ) fprintf(stderr,"post "); if ( info->os2_start==0 ) fprintf(stderr,"OS/2"); fprintf(stderr,"\n"); } return( true ); } static time_t readdate(FILE *ttf) { int date[4], date1970[4], year[2]; int i; /* Dates in sfnt files are seconds since 1904. I adjust to unix time */ /* seconds since 1970 by figuring out how many seconds were in between */ date[3] = getushort(ttf); date[2] = getushort(ttf); date[1] = getushort(ttf); date[0] = getushort(ttf); memset(date1970,0,sizeof(date1970)); year[0] = (60*60*24*365L)&0xffff; year[1] = (60*60*24*365L)>>16; for ( i=1904; i<1970; ++i ) { date1970[0] += year[0]; date1970[1] += year[1]; if ( (i&3)==0 && (i%100!=0 || i%400==0)) date1970[0] += 24*60*60L; /* Leap year */ date1970[1] += (date1970[0]>>16); date1970[0] &= 0xffff; date1970[2] += date1970[1]>>16; date1970[1] &= 0xffff; date1970[3] += date1970[2]>>16; date1970[2] &= 0xffff; } for ( i=0; i<3; ++i ) { date[i] -= date1970[i]; date[i+1] += date[i]>>16; date[i] &= 0xffff; } date[3] -= date1970[3]; return( (date[1]<<16) | date[0] ); } static void readttfFFTM(FILE *ttf, FILE *util, struct ttfinfo *info) { time_t unix_date; struct tm *tm; static const char *months[] = { "Jan", "Feb", "March", "April", "May", "June", "July", "August", "Sept", "Oct", "Nov", "Dec", NULL }; fseek(ttf,info->fftm_start,SEEK_SET); printf( "\n\nCreated by FontForge " ); if ( getlong(ttf)!=0x00000001 ) { fprintf( stderr, "Unknown version for 'FFTM' table\n" ); } else { unix_date = readdate(ttf); tm = localtime(&unix_date); printf( "%d:%02d %02d-%s-%d\n", tm->tm_hour, tm->tm_min, tm->tm_mday, months[tm->tm_mon], tm->tm_year+1900 ); unix_date = readdate(ttf); printf( "\tFont created: %s", ctime(&unix_date)); unix_date = readdate(ttf); printf( "\tFont modified: %s", ctime(&unix_date)); } printf( "\n" ); } static void readttfhead(FILE *ttf, FILE *util, struct ttfinfo *info) { int mn, flags, fd; time_t unix_date; fseek(ttf,info->head_start,SEEK_SET); printf( "\nHEAD table (at %d)\n", info->head_start ); printf( "\tVersion=%g\n", getfixed(ttf)); printf( "\tfontRevision=%g\n", getfixed(ttf)); printf( "\tchecksumAdj=%x\n", getlong(ttf)); mn = getlong(ttf); printf( "\tmagicNumber=%x (0x5f0f3cf5, diff=%x)\n", mn, mn-0x5f0f3cf5); printf( "\tflags=%x ", flags=getushort(ttf)); if ( flags&1 ) printf( "baseline_at_0 " ); if ( flags&2 ) printf( "lsb_at_0 " ); if ( flags&4 ) printf( "instrs_depend_on_size " ); if ( flags&8 ) printf( "ppem_to_int " ); if ( flags&16 ) printf( "instr_set_width " ); printf( "\n" ); printf( "\tunitsPerEm=%d\n", getushort(ttf)); printf( "\tcreate[0]=%x\n", getlong(ttf)); printf( "\t create[1]=%x\n", getlong(ttf)); fseek(ttf,-8,SEEK_CUR); unix_date = readdate(ttf); printf( "\tFile created: %s", ctime(&unix_date)); printf( "\tmodtime[0]=%x\n", getlong(ttf)); printf( "\t modtime[1]=%x\n", getlong(ttf)); fseek(ttf,-8,SEEK_CUR); unix_date = readdate(ttf); printf( "\tFile modified: %s", ctime(&unix_date)); printf( "\txmin=%d\n", (short) getushort(ttf)); printf( "\tymin=%d\n", (short) getushort(ttf)); printf( "\txmax=%d\n", (short) getushort(ttf)); printf( "\tymax=%d\n", (short) getushort(ttf)); printf( "\tmacstyle=%x\n", getushort(ttf)); printf( "\tlowestppem=%d\n", getushort(ttf)); printf( "\tfontdirhint=%d ", fd = getushort(ttf)); switch ( fd ) { case 0: printf("mixed directional glyphs\n" ); break; case 1: printf("strongly left to right glyphs\n" ); break; case 2: printf("left to right and neutrals\n" ); break; case -1: printf("strongly right to left glyphs\n" ); break; case -2: printf("right to left and neutrals\n" ); break; default: printf("???\n" ); break; } printf( "\tloca_is_32=%d\n", info->index_to_loc_is_long = getushort(ttf)); if ( info->index_to_loc_is_long ) info->glyph_cnt = info->loca_length/4-1; printf( "\tglyphdataformat=%d\n", getushort(ttf)); } static void readttfhhead(FILE *ttf, FILE *util, struct ttfinfo *info) { fseek(ttf,info->hhea_start,SEEK_SET); printf( "\nHHEAD table (at %d)\n", info->hhea_start ); printf( "\tVersion=%g\n", getfixed(ttf)); printf( "\tascender=%d\n", (short) getushort(ttf)); printf( "\tdescender=%d\n", (short) getushort(ttf)); printf( "\tlinegap=%d\n", (short) getushort(ttf)); printf( "\tadvanceWidthMax=%d\n", getushort(ttf)); printf( "\tminlsb=%d\n", (short) getushort(ttf)); printf( "\tminrsb=%d\n", (short) getushort(ttf)); printf( "\tmaxextent=%d\n", (short) getushort(ttf)); printf( "\tcaretsloperise=%d\n", (short) getushort(ttf)); printf( "\tcaretsloperun=%d\n", (short) getushort(ttf)); printf( "\tmbz=%d\n", (short) getushort(ttf)); printf( "\tmbz=%d\n", (short) getushort(ttf)); printf( "\tmbz=%d\n", (short) getushort(ttf)); printf( "\tmbz=%d\n", (short) getushort(ttf)); printf( "\tmbz=%d\n", (short) getushort(ttf)); printf( "\tmetricdataformat=%d\n", (short) getushort(ttf)); printf( "\tnumberOfHMetrics=%d\n", getushort(ttf)); } static char *getttfname(FILE *util, struct ttfinfo *info, int nameid) { int nrec, taboff, stroff, strlen, platform; int i,j,id; fseek(util,info->copyright_start,SEEK_SET); /* format */ getushort(util); nrec=getushort(util); taboff=getushort(util); for ( i=0; icopyright_start+taboff+stroff,SEEK_SET); for ( j=0; jcopyright_start,SEEK_SET); printf( "\nNAME table (at %d)\n", info->copyright_start ); printf( "\tformat=%d\n", getushort(ttf)); printf( "\tnrecords=%d\n", nrec=getushort(ttf)); printf( "\ttaboff=%d\n", taboff=getushort(ttf)); for ( i=0; icopyright_start+taboff+stroff,SEEK_SET); for ( j=0; j=0x80 && ch<0xa0 ) { printf("<%2X>", ch ); } else putchar(ch); } putchar('\n'); } } static void readttfmaxp(FILE *ttf, FILE *util, struct ttfinfo *info) { int ng; fseek(ttf,info->maxp_start,SEEK_SET); printf( "\nMAXP table (at %d)\n", info->maxp_start ); printf( "\tVersion=%g\n", getfixed(ttf)); printf( "\t numGlyphs=%d\n", ng = getushort(ttf)); info->glyph_cnt = ng; /* Open type doesn't have a loca table */ if ( info->maxp_length==6 ) /* Open Type */ return; printf( "\t maxPoints=%d\n", getushort(ttf)); printf( "\t maxContours=%d\n", getushort(ttf)); printf( "\t maxCompositPoints=%d\n", getushort(ttf)); printf( "\t maxCompositContours=%d\n", getushort(ttf)); printf( "\t maxZones=%d\n", getushort(ttf)); printf( "\t maxTwilightPoints=%d\n", getushort(ttf)); printf( "\t maxStorage=%d\n", getushort(ttf)); printf( "\t maxFunctionDefs=%d\n", getushort(ttf)); printf( "\t maxInstructionDefs=%d\n", getushort(ttf)); printf( "\t maxStackElements=%d\n", getushort(ttf)); printf( "\t maxSizeOfInstructions=%d\n", getushort(ttf)); printf( "\t maxComponentElements=%d\n", getushort(ttf)); printf( "\t maxComponentDepth=%d\n", getushort(ttf)); } static void readttfcvt(FILE *ttf, FILE *util, struct ttfinfo *info) { int i; if ( info->cvt_start==0 ) return; fseek(ttf,info->cvt_start,SEEK_SET); printf( "\nCVT table (at %d, len=%d)\n", info->cvt_start, info->cvt_length ); for ( i=0; icvt_length/2; ++i ) printf( " CVT[%d] = %d\n", i, (short) getushort(ttf)); } static void readttfos2(FILE *ttf, FILE *util, struct ttfinfo *info) { int i, val; static char *weights[] = { "Unspecified", "Thin", "Extra-Light", "Light", "Normal", "Medium", "Semi-Bold", "Bold", "Extra-Bold", "Black", "???" }; static char *widths[] = { "Unspecified", "Ultra-Condensed", "Extra-Condensed", "Condensed", "Semi-Condensed", "Medium", "Semi-Expanded", "Expanded", "Extra-Expanded", "Ultra-Expanded", "???" }; static char *class[16] = { "No classification", "Old Style Serifs", "Transitional Serifs", "Modern Serifs", "Clarendon Serifs", "Slab Serifs", "???", "Freeform Serifs", "Sans Serif", "Ornamentals", "Scripts", "???", "Symbolic", "???", "???", "???" }; static char *subclass0[16] = { "", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "Misc" }; static char *subclass1[16] = { "", "ibm rounded", "garalde", "venetian", "modified venetian", "dutch modern", "dutch traditional", "contemporary", "caligraphic", "???", "???", "???", "???", "???", "???", "Misc" }; static char *subclass2[16] = { "", "direct line", "script", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "Misc" }; static char *subclass3[16] = { "", "italian", "script", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "Misc" }; static char *subclass4[16] = { "", "clarendon", "modern", "traditional", "newspaper", "stub", "monotone", "typewriter", "???", "???", "???", "???", "???", "???", "???", "Misc" }; static char *subclass5[16] = { "", "monotone", "humanist", "geometric", "swiss", "typewriter", "???", "???", "???", "???", "???", "???", "???", "???", "???", "Misc" }; static char *subclass7[16] = { "", "modern", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "Misc" }; static char *subclass8[16] = { "", "ibm neogrotesque", "humanist", "low-x rounded", "high-x rounded", "neo-grotesque", "modified neo-grotesque", "???", "???", "typewriter", "matrix", "???", "???", "???", "???", "Misc" }; static char *subclass9[16] = { "", "engraver", "black letter", "decorative", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "Misc" }; static char *subclass10[16] = { "", "???", "uncial", "brush joined", "formal joined", "monotone joined", "calligraphic", "brush unjoined", "formal unjoined", "monotone unjoined", "???", "???", "???", "???", "???", "Misc" }; static char *subclass12[16] = { "", "???", "???", "mixed serif", "???", "???", "old style serif", "neo-grotesque sans", "???", "???", "???", "???", "???", "???", "???", "Misc" }; static char **subclasses[16] = { subclass0, subclass1, subclass2, subclass3, subclass4, subclass5, subclass0, subclass7, subclass8, subclass9, subclass10, subclass0, subclass12, subclass0, subclass0, subclass0 }; static char *panose0[] = { "Any", "No Fit", "Text & Display", "Script", "Decorative", "Pictoral" }; static char *panose1[] = { "Any", "No Fit", "Cove", "Obtuse Cove", "Square Cove", "Obtuse Square Cove", "Square", "Thin", "Bone", "Exaggerated", "Triangle", "Normal Sans", "Obtuse Sans", "Perp Sans", "Flared", "Rounded" }; static char *panose2[] = { "Any", "No Fit", "Very Light", "Light", "Thin", "Book", "Medium", "Demi", "Bold", "Heavy", "Black", "Nord" }; static char *panose3[] = { "Any", "No Fit", "Old Style", "Modern", "Even Width", "Expanded", "Condensed", "Very Expanded", "Very Condensed", "Monospaced" }; static char *panose4[] = { "Any", "No Fit", "None", "Very Low", "Low", "Medium Low", "Medium", "Medium High", "High", "Very High" }; static char *panose5[] = { "Any", "No Fit", "Gradual/Diagonal", "Gradual/Transitional", "Gradual/Vertical", "Gradual/Horizontal", "Rapid/Vertical", "Rapid/Horizontal", "Instant/Vertical" }; static char *panose6[] = { "Any", "No Fit", "Straight Arms/Horizontal", "Straight Arms/Wedge", "Straight Arms/Vertical", "Straight Arms/Single Serif", "Straight Arms/Double Serif", "Non-Straight Arms/Horizontal", "Non-Straight Arms/Wedge", "Non-Straight Arms/Vertical", "Non-Straight Arms/Single Serif", "Non-Straight Arms/Double Serif" }; static char *panose7[] = { "Any", "No Fit", "Normal/Contact", "Normal/Weighted", "Normal/Boxed", "Normal/Flattened", "Normal/Rounded", "Normal/Off-Center", "Normal/Square", "Oblique/Contact", "Oblique/Weighted", "Oblique/Boxed", "Oblique/Flattened", "Oblique/Rounded", "Oblique/Off-Center", "Oblique/Square" }; static char *panose8[] = { "Any", "No Fit", "Standard/Trimmed", "Standard/Pointed", "Standard/Serifed", "High/Trimmed", "High/Pointed", "High/Serifed", "Constant/Trimmed", "Constant/Pointed", "Constant/Serifed", "Low/Trimmed", "Low/Pointed", "Low/Serifed" }; static char *panose9[] = { "Any", "No Fit", "Constant/Small", "Constant/Standard", "Constant/Large", "Ducking/Small", "Ducking/Standard", "Ducking/Large" }; static struct { char *name; char **choices; int cnt; } panose[10] = { { "Family", panose0, sizeof(panose0) }, { "Serif Type", panose1, sizeof(panose1) }, { "Weight", panose2, sizeof(panose2) }, { "Proportion", panose3, sizeof(panose3) }, { "Contrast", panose4, sizeof(panose4) }, { "Stroke Variation", panose5, sizeof(panose5) }, { "Arm Style", panose6, sizeof(panose6) }, { "Letterform", panose7, sizeof(panose7) }, { "Midline", panose8, sizeof(panose8) }, { "X-Height", panose9, sizeof(panose9) } }; fseek(ttf,info->os2_start,SEEK_SET); printf( "\nOS/2 table (at %d for %d bytes)\n", info->os2_start, info->os2_len ); printf( "\tVersion=%d\n", getushort(ttf)); printf( "\t avgWidth=%d\n", (short)getushort(ttf)); printf( "\t weightClass=%d ", val = getushort(ttf)); if ( val>=0 && val<=999 ) printf( "%s\n", weights[val/100] ); else printf( "???\n"); printf( "\t widthClass=%d ", val = getushort(ttf)); if ( val>=0 && val<=9 ) printf( "%s\n", widths[val] ); else printf( "???\n"); printf( "\t fstype=0x%x ", val = (short) getushort(ttf)); if ( val&0x8 ) printf( "Editable embedding\n"); else if ( val&0x4 ) printf( "Preview & Print embedding\n"); else if ( val&0x2 ) printf( "Restricted license embedding\n"); else printf( "\n"); printf( "\t ySubscript XSize=%d\n", (short) getushort(ttf)); printf( "\t ySubscript YSize=%d\n", (short) getushort(ttf)); printf( "\t ySubscript XOffset=%d\n", (short) getushort(ttf)); printf( "\t ySubscript YOffset=%d\n", (short) getushort(ttf)); printf( "\t ySupscript XSize=%d\n", (short) getushort(ttf)); printf( "\t ySupscript YSize=%d\n", (short) getushort(ttf)); printf( "\t ySupscript XOffset=%d\n", (short) getushort(ttf)); printf( "\t ySupscript YOffset=%d\n", (short) getushort(ttf)); printf( "\t yStrikeoutSize=%d\n", (short) getushort(ttf)); printf( "\t yStrikeoutPos=%d\n", (short) getushort(ttf)); printf( "\t sFamilyClass=%04x ", val = getushort(ttf)); if ( (val>>8)>=0 && (val>>8)<16 ) { printf( "%s ", class[val>>8]); if ( (val&0xff)<16 ) printf( "%s\n", subclasses[val>>8][val&0xff]); else printf( "???\n" ); } else printf ( "??? ???\n" ); printf( "\t Panose\n" ); for ( i=0; i<10; ++i ) { printf( "\t\t%s: %02x ", panose[i].name, val= getc(ttf)); if ( val>0 && valos2_len==78 ) { printf( "\t (no CodePageRange)\n" ); } else { printf( "\t CodePageRange=%08x ", getlong(ttf)); printf( "%08x\n", getlong(ttf)); if ( info->os2_len==96 ) { /* Open type additions */ printf( "\txHeight=%d\n", (short) getushort(ttf)); printf( "\tCapHeight=%d\n", (short) getushort(ttf)); printf( "\tDefaultChar=%d\n", getushort(ttf)); /* 0, or space I guess */ printf( "\tBreakChar=%d\n", getushort(ttf)); /* space */ printf( "\tMaxContext=%d\n", getushort(ttf)); /* Maximum look-ahead needed for processing. kerning=>2. 3letter ligature=>3, 4letter=>4 */ } } } const unsigned short unicode_from_mac[] = { 0x0000, 0x00d0, 0x00f0, 0x0141, 0x0142, 0x0160, 0x0161, 0x00dd, 0x00fd, 0x0009, 0x000a, 0x00de, 0x00fe, 0x000d, 0x017d, 0x017e, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x00bd, 0x00bc, 0x00b9, 0x00be, 0x00b3, 0x00b2, 0x00a6, 0x00ad, 0x00d7, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x2126, 0x00e6, 0x00f8, 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, 0x00ff, 0x0178, 0x2044, 0x00a4, 0x2039, 0x203a, 0xfb01, 0xfb02, 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, 0xf8ff, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7 }; static const char *standardnames[258] = { ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", "thorn", "minus", "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", "ccaron", "dcroat" }; /* Standard names for cff */ const char *cffnames[] = { ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold", NULL }; static const int nStdStrings = sizeof(cffnames)/sizeof(cffnames[0])-1; static const char *instrs[] = { "SVTCA[y-axis]", "SVTCA[x-axis]", "SPVTCA[y-axis]", "SPVTCA[x-axis]", "SFVTCA[y-axis]", "SFVTCA[x-axis]", "SPVTL[parallel]", "SPVTL[orthog]", "SFVTL[parallel]", "SFVTL[orthog]", "SPVFS", "SFVFS", "GPV", "GFV", "SFVTPV", "ISECT", "SRP0", "SRP1", "SRP2", "SZP0", "SZP1", "SZP2", "SZPS", "SLOOP", "RTG", "RTHG", "SMD", "ELSE", "JMPR", "SCVTCI", "SSWCI", "SSW", "DUP", "POP", "CLEAR", "SWAP", "DEPTH", "CINDEX", "MINDEX", "ALIGNPTS", "Unknown28", "UTP", "LOOPCALL", "CALL", "FDEF", "ENDF", "MDAP[no round]", "MDAP[round]", "IUP[y]", "IUP[x]", "SHP[rp2]", "SHP[rp1]", "SHC[rp2]", "SHC[rp1]", "SHZ[rp2]", "SHZ[rp1]", "SHPIX", "IP", "MSIRP[no set rp0]", "MSIRP[set rp0]", "ALIGNRP", "RTDG", "MIAP[no round]", "MIAP[round]", "NPUSHB", "NPUSHW", "WS", "RS", "WCVTP", "RCVT", "GC[cur]", "GC[orig]", "SCFS", "MD[grid]", "MD[orig]", "MPPEM", "MPS", "FLIPON", "FLIPOFF", "DEBUG", "LT", "LTEQ", "GT", "GTEQ", "EQ", "NEQ", "ODD", "EVEN", "IF", "EIF", "AND", "OR", "NOT", "DELTAP1", "SDB", "SDS", "ADD", "SUB", "DIV", "MUL", "ABS", "NEG", "FLOOR", "CEILING", "ROUND[Grey]", "ROUND[Black]", "ROUND[White]", "ROUND[Undef4]", "NROUND[Grey]", "NROUND[Black]", "NROUND[White]", "NROUND[Undef4]", "WCVTF", "DELTAP2", "DELTAP3", "DELTAC1", "DELTAC2", "DELTAC3", "SROUND", "S45ROUND", "JROT", "JROF", "ROFF", "Unknown7B", "RUTG", "RDTG", "SANGW", "AA", "FLIPPT", "FLIPRGON", "FLIPRGOFF", "Unknown83", "Unknown84", "SCANCTRL", "SDPVTL0", "SDPVTL1", "GETINFO", "IDEF", "ROLL", "MAX", "MIN", "SCANTYPE", "INSTCTRL", "Unknown8F", "Unknown90", "Unknown91", "Unknown92", "Unknown93", "Unknown94", "Unknown95", "Unknown96", "Unknown97", "Unknown98", "Unknown99", "Unknown9A", "Unknown9B", "Unknown9C", "Unknown9D", "Unknown9E", "Unknown9F", "UnknownA0", "UnknownA1", "UnknownA2", "UnknownA3", "UnknownA4", "UnknownA5", "UnknownA6", "UnknownA7", "UnknownA8", "UnknownA9", "UnknownAA", "UnknownAB", "UnknownAC", "UnknownAD", "UnknownAE", "UnknownAF", "PUSHB [1]", "PUSHB [2]", "PUSHB [3]", "PUSHB [4]", "PUSHB [5]", "PUSHB [6]", "PUSHB [7]", "PUSHB [8]", "PUSHW [1]", "PUSHW [2]", "PUSHW [3]", "PUSHW [4]", "PUSHW [5]", "PUSHW [6]", "PUSHW [7]", "PUSHW [8]", "MDRP[grey]", "MDRP[black]", "MDRP[white]", "MDRP03", "MDRP[round, grey]", "MDRP[round, black]", "MDRP[round, white]", "MDRP07", "MDRP[minimum, grey]", "MDRP[minimum, black]", "MDRP[minimum, white]", "MDRP0b", "MDRP[minimum, round, grey]", "MDRP[minimum, round, black]", "MDRP[minimum, round, white]", "MDRP0f", "MDRP[rp0, grey]", "MDRP[rp0, black]", "MDRP[rp0, white]", "MDRP13", "MDRP[rp0, round, grey]", "MDRP[rp0, round, black]", "MDRP[rp0, round, white]", "MDRP17", "MDRP[rp0, minimum, grey]", "MDRP[rp0, minimum, black]", "MDRP[rp0, minimum, white]", "MDRP1b", "MDRP[rp0, minimum, round, grey]", "MDRP[rp0, minimum, round, black]", "MDRP[rp0, minimum, round, white]", "MDRP1f", "MIRP[grey]", "MIRP[black]", "MIRP[white]", "MIRP03", "MIRP[round, grey]", "MIRP[round, black]", "MIRP[round, white]", "MIRP07", "MIRP[minimum, grey]", "MIRP[minimum, black]", "MIRP[minimum, white]", "MIRP0b", "MIRP[minimum, round, grey]", "MIRP[minimum, round, black]", "MIRP[minimum, round, white]", "MIRP0f", "MIRP[rp0, grey]", "MIRP[rp0, black]", "MIRP[rp0, white]", "MIRP13", "MIRP[rp0, round, grey]", "MIRP[rp0, round, black]", "MIRP[rp0, round, white]", "MIRP17", "MIRP[rp0, minimum, grey]", "MIRP[rp0, minimum, black]", "MIRP[rp0, minimum, white]", "MIRP1b", "MIRP[rp0, minimum, round, grey]", "MIRP[rp0, minimum, round, black]", "MIRP[rp0, minimum, round, white]", "MIRP1f" }; static struct dup *makedup(int glyph, int uni, struct dup *prev) { struct dup *d = calloc(1,sizeof(struct dup)); d->glyph = glyph; d->enc = uni; d->prev = prev; return( d ); } static void readttfencodings(FILE *ttf,FILE *util, struct ttfinfo *info) { int i,j; int nencs, version; int enc = 0; int platform, specific; int offset, encoff; int format, len; uint16 table[256]; int segCount; unsigned short *endchars, *startchars, *delta, *rangeOffset, *glyphs; int index; struct dup *dup; int vs_map = -1; fseek(ttf,info->encoding_start,SEEK_SET); printf( "\nEncoding (cmap) table (at %d)\n", info->encoding_start ); version = getushort(ttf); nencs = getushort(ttf); if ( version!=0 && nencs==0 ) nencs = version; /* Sometimes they are backwards */ for ( i=0; iglyph_unicode = calloc(info->glyph_cnt,sizeof(unsigned int)); fseek(ttf,info->encoding_start+encoff,SEEK_SET); format = getushort(ttf); if ( format!=12 && format!=10 && format!=8 ) { len = getushort(ttf); printf( " Format=%d len=%d Language=%x\n", format, len, getushort(ttf) ); } else { /* padding */ getushort(ttf); len = getlong(ttf); printf( " Format=%d len=%d Language=%x\n", format, len, getlong(ttf) ); } if ( format==0 ) { printf( " Table: " ); for ( i=0; iglyph_cnt && iglyph_unicode[table[i]] = i; } else if ( format==4 ) { segCount = getushort(ttf)/2; /* searchRange = */ getushort(ttf); /* entrySelector = */ getushort(ttf); /* rangeShift = */ getushort(ttf); endchars = malloc(segCount*sizeof(unsigned short)); for ( i=0; i=info->glyph_cnt ) printf( "!!! Glyph index out of bounds! %d\n", (unsigned short) (j+delta[i]) ); else if ( info->glyph_unicode[(unsigned short) (j+delta[i])] ) info->dups = makedup((unsigned short) (j+delta[i]),j,info->dups); else info->glyph_unicode[(unsigned short) (j+delta[i])] = j; } } else if ( rangeOffset[i]!=0xffff ) { /* It isn't explicitly mentioned by a rangeOffset of 0xffff*/ /* means no glyph */ for ( j=startchars[i]; j<=endchars[i]; ++j ) { index = glyphs[ (i-segCount+rangeOffset[i]/2) + j-startchars[i] ]; if ( index!=0 ) { index = (unsigned short) (index+delta[i]); if ( index>=info->glyph_cnt || index<0 ) printf( "!!! Glyph index out of bounds! %d\n", index ); else if ( info->glyph_unicode[index]!=0 ) info->dups = makedup(index,j,info->dups); else info->glyph_unicode[index] = j; } } } } free(glyphs); free(rangeOffset); free(delta); free(startchars); free(endchars); } else if ( format==6 ) { /* Apple's unicode format */ /* Well, the docs say it's for 2byte encodings, but Apple actually*/ /* uses it for 1 byte encodings which don't fit into the require-*/ /* ments for a format 0 sub-table. See Zapfino.dfont */ int first, count; first = getushort(ttf); count = getushort(ttf); for ( i=0; iglyph_unicode[getushort(ttf)] = first+i; } else if ( format==2 ) { int max_sub_head_key = 0, cnt, last; struct subhead { uint16 first, cnt, delta, rangeoff; } *subheads; for ( i=0; i<256; ++i ) { table[i] = getushort(ttf)/8; /* Sub-header keys */ if ( table[i]>max_sub_head_key ) max_sub_head_key = table[i]; /* The entry is a byte pointer, I want a pointer in units of struct subheader */ } subheads = malloc((max_sub_head_key+1)*sizeof(struct subhead)); for ( i=0; i<=max_sub_head_key; ++i ) { subheads[i].first = getushort(ttf); subheads[i].cnt = getushort(ttf); subheads[i].delta = getushort(ttf); subheads[i].rangeoff = (getushort(ttf)- (max_sub_head_key-i)*sizeof(struct subhead)- sizeof(short))/sizeof(short); } cnt = (len-(ftell(ttf)-(info->encoding_start+encoff)))/sizeof(short); /* The count is the number of glyph indexes to read. it is the */ /* length of the entire subtable minus that bit we've read so far */ glyphs = malloc(cnt*sizeof(short)); for ( i=0; i=subheads[0].first+subheads[0].cnt || subheads[0].rangeoff+(i-subheads[0].first)>=cnt ) index = 0; else if ( (index = glyphs[subheads[0].rangeoff+(i-subheads[0].first)])!= 0 ) index = (uint32) (index+subheads[0].delta); /* I assume the single byte codes are just ascii or latin1*/ if ( index!=0 && indexglyph_cnt ) { if ( info->glyph_unicode[index]==0 ) info->glyph_unicode[index] = i; else info->dups = makedup(index,i,info->dups); } } else { int k = table[i]; for ( j=0; j=cnt ) index = 0; else if ( (index = glyphs[subheads[k].rangeoff+j])!= 0 ) index = (uint16) (index+subheads[k].delta); if ( index!=0 && indexglyph_cnt ) { enc = (i<<8)|(j+subheads[k].first); if ( info->glyph_unicode[index]==0 ) info->glyph_unicode[index] = enc; else info->dups = makedup(index,enc,info->dups); } } if ( last==-1 ) last = i; } } free(subheads); free(glyphs); } else if ( format==12 ) { uint32 ngroups, start, end, startglyph; ngroups = getlong(ttf); for ( j=0; jglyph_unicode[startglyph+i-start] = i; } } } else if ( format==8 ) { fprintf(stderr,"I don't support mixed 16/32 bit characters (no unicode surogates), format=%d", format); } else if ( format==10 ) { fprintf(stderr,"I don't support 32 bit characters format=%d", format); } else { fprintf(stderr,"Eh? Unknown encoding format=%d", format); } } if ( info->glyph_unicode!=NULL ) { for ( i=0; iglyph_cnt && (format!=0 || i<256); ++i ) printf( " Glyph %d -> U+%04X\n", i, info->glyph_unicode[i]); for ( i=0; iglyph_cnt; ++i ) if ( info->glyph_unicode[i]!=0 ) { for ( j=i+1; jglyph_cnt; ++j ) if ( info->glyph_unicode[i]==info->glyph_unicode[j] ) printf( "!!!Two glyphs %d and %d have the same encoding U+%04X", i, j, info->glyph_unicode[i]); } if ( info->dups!=NULL ) { printf("Some glyphs have multiple encodings:\n" ); for ( dup = info->dups; dup!=NULL ; dup=dup->prev ) printf( " Glyph %d -> U+%04X (primary=U+%04X)\n", dup->glyph, dup->enc, info->glyph_unicode[dup->glyph] ); } } else printf( "Could not understand encoding table\n" ); if ( vs_map!=-1 ) { struct vs_data { int vs; uint32 defoff, nondefoff; } *vs_data; int cnt, rcnt; fseek(ttf,info->encoding_start+vs_map,SEEK_SET); if ( getushort(ttf)!=14 ) { fprintf( stderr, "A unicode variation subtable (platform=0,specific=5) must have format=14\n" ); return; } len = getlong(ttf); cnt = getlong(ttf); printf( " Format=14 len=%d\n numVarSelRec=%d\n", len, cnt ); vs_data = malloc( cnt*sizeof(struct vs_data)); for ( i=0; iencoding_start+vs_map+vs_data[i].defoff,SEEK_SET); rcnt = getlong(ttf); printf( " Default glyphs\n %d ranges\n", rcnt ); for ( j=0; jencoding_start+vs_map+vs_data[i].nondefoff,SEEK_SET); rcnt = getlong(ttf); printf( " non Default glyphs\n %d mappings\n", rcnt ); for ( j=0; j GID %d\n", uni, vs_data[i].vs, getushort(ttf)); } } } } } static void readttfpost(FILE *ttf, FILE *util, struct ttfinfo *info) { int i,j,ind, extras; int format, gc, len; uint16 *indexes, *glyphs; char **names, *name; fseek(ttf,info->postscript_start,SEEK_SET); printf( "\npost table (at %d)\n", info->postscript_start ); printf( "\t format=%08x\n", format = getlong(ttf)); printf( "\t italicAngle=%g\n", getfixed(ttf)); printf( "\t underlinePos=%d\n", (short) getushort(ttf)); printf( "\t underlineWidth=%d\n", getushort(ttf)); printf( "\t fixedpitch=%d\n", getlong(ttf)); printf( "\t mem1=%d\n", getlong(ttf)); printf( "\t mem2=%d\n", getlong(ttf)); printf( "\t mem3=%d\n", getlong(ttf)); printf( "\t mem4=%d\n", getlong(ttf)); if ( format==0x00030000 ) { /* Used in Open Type, seems only to contain the above stuff */ /* (no names, they're in the cff section) */ } else if ( format==0x00020000 ) { gc = getushort(ttf); if ( gc!=info->glyph_cnt ) fprintf( stderr, "!!!! Post table glyph count does not match that in 'maxp'\n" ); indexes = calloc(65536,sizeof(uint16)); glyphs = calloc(gc,sizeof(uint16)); names = calloc(gcglyph_cnt?info->glyph_cnt:gc,sizeof(char *)); /* the index table is backwards from the way I want to use it */ extras = 0; for ( i=0; i=258 ) ++extras; indexes[ind] = i; glyphs[i] = ind; } for ( i=258; i<258+extras; ++i ) { if ( indexes[i]==0 ) break; len = getc(ttf); name = malloc(len+1); for ( j=0; j \"", i, glyphs[i] ); if ( names[i]!=NULL ) printf( "%s", names[i]); else if ( glyphs[i]<258 ) { printf( "%s", standardnames[glyphs[i]]); names[i] = strdup(standardnames[glyphs[i]]); } else printf( "Gleep!!!!! %d", glyphs[i]); if ( info->glyph_unicode!=NULL ) printf("\"\t U+%04X\n", info->glyph_unicode[i]); else printf( "\"\n" ); } free(indexes); free(glyphs); #if 1 info->glyph_names = names; #else for ( i=0; iglyph_unicode!=NULL ) { if ( info->glyph_names==NULL ) info->glyph_names = calloc(info->glyph_cnt,sizeof(char *)); for ( i=0; iglyph_cnt ; ++i ) { if ( info->glyph_names[i]!=NULL ) /* Keep it */; else if ( info->glyph_unicode[i]!=0 && info->glyph_unicode[i]!=0xffff ) { char buffer[40]; sprintf(buffer,">U+%04X<", info->glyph_unicode[i]); info->glyph_names[i] = strdup(buffer); } } } } static void showlangsys(FILE *ttf,int script_start, uint16 ls_off, uint32 ls_name ) { int i,cnt; if ( ls_name==0 ) printf( "\t Language System table for default language\n" ); else printf( "\t Language System table for '%c%c%c%c'\n", (ls_name>>24)&0xff, (ls_name>>16)&0xff, (ls_name>>8)&0xff, ls_name&0xff); fseek(ttf,script_start+ls_off,SEEK_SET); printf( "\t LookupOrder=%d\n", getushort(ttf)); printf( "\t Required Feature Index=%d\n", (short) getushort(ttf)); printf( "\t Feature Count=%d\n", cnt = getushort(ttf)); for ( i=0; i>24)&0xff, (script_table_names[i]>>16)&0xff, (script_table_names[i]>>8)&0xff, script_table_names[i]&0xff, script_table_offsets[i]); } printf( "\t--\n" ); for ( i=0; i>24)&0xff, (script_table_names[i]>>16)&0xff, (script_table_names[i]>>8)&0xff, script_table_names[i]&0xff); printf( "\t default language offset=%d\n", dlo=getushort(ttf)); printf( "\t language systems count=%d\n", ls_cnt = getushort(ttf)); ls_names = malloc(ls_cnt*sizeof(uint32)); ls_offsets = malloc(ls_cnt*sizeof(uint16)); for ( j=0; j>24)&0xff, (ls_names[j]>>16)&0xff, (ls_names[j]>>8)&0xff, ls_names[j]&0xff, ls_offsets[j]); } if ( dlo!=0 ) showlangsys(ttf,script_start+script_table_offsets[i],dlo,0); for ( j=0; j>24)&0xff, (feature_record_names[i]>>16)&0xff, (feature_record_names[i]>>8)&0xff, feature_record_names[i]&0xff, feature_record_offsets[i]); } printf( "\t--\n" ); for ( i=0; i>24)&0xff, (feature_record_names[i]>>16)&0xff, (feature_record_names[i]>>8)&0xff, feature_record_names[i]&0xff); printf( "\t Feature Parameters Offset=%d\n", getushort(ttf)); printf( "\t Lookup Count = %d\n", lu_cnt = getushort(ttf)); if ( i+1feature_record_offsets[i+1] ) printf( "!!!! Bad lookup count. More lookups than there is space for!!!!\n" ); lu_offsets = malloc(lu_cnt*sizeof(uint16)); for ( j=0; j= max ) { max = ind+end-start+2; glyphs = realloc(glyphs,max*sizeof(uint16)); } for ( j=start; j<=end; ++j ) glyphs[j-start+ind] = j; if ( end-start+1+ind>cnt ) { glyphs[end-start+1+ind] = 0xffff; cnt = end-start+1+ind; } } } if ( specified_cnt>=0 && cnt!=specified_cnt ) fprintf(stderr, "! > Bad coverage table: Calculated Count(%d) does not match specified (%d)\n", cnt, specified_cnt ); return( glyphs ); } static uint16 *getClassDefTable(FILE *ttf, int classdef_offset, int cnt) { int format, i, j; uint16 start, glyphcnt, rangecnt, end, class; uint16 *glist=NULL; fseek(ttf, classdef_offset, SEEK_SET); glist = malloc(cnt*sizeof(uint16)); for ( i=0; icnt ) { fprintf( stderr, "Bad class def table. start=%d cnt=%d, max glyph=%d\n", start, glyphcnt, cnt ); glyphcnt = cnt-start; } for ( i=0; iend || end>=cnt ) fprintf( stderr, "Bad class def table. Glyph range %d-%d out of range [0,%d)\n", start, end, cnt ); class = getushort(ttf); for ( j=start; j<=end; ++j ) glist[j] = class; } } return glist; } static void readvaluerecord(int vf,FILE *ttf,char *label) { printf( "\t\t %s: ", label ); if ( vf&1 ) printf( "XPlacement: %d ", (short) getushort(ttf)); if ( vf&2 ) printf( "YPlacement: %d ", (short) getushort(ttf)); if ( vf&4 ) printf( "XAdvance: %d ", (short) getushort(ttf)); if ( vf&8 ) printf( "YAdvance: %d ", (short) getushort(ttf)); if ( vf&0x10 ) printf( "XPlacementDevOff: %d ", getushort(ttf)); if ( vf&0x20 ) printf( "YPlacementDevOff: %d ", getushort(ttf)); if ( vf&0x40 ) printf( "XAdvanceDevOff: %d ", getushort(ttf)); if ( vf&0x80 ) printf( "YAdvanceDevOff: %d ", getushort(ttf)); printf( "\n" ); } static void PrintGlyphs(uint16 *glyphs, struct ttfinfo *info) { if ( glyphs==NULL ) printf( "\n" ); else if ( info->glyph_names!=NULL ) { int i; printf( " " ); for ( i=0; glyphs[i]!=0xffff; ++i ) { printf( "%s ", info->glyph_names[glyphs[i]]); } printf("\n" ); } } static void gposPairSubTable(FILE *ttf, int which, int stoffset, struct ttfinfo *info) { int coverage, cnt, i, subformat, vf1, vf2, j, pair_cnt; uint16 *glyphs; uint16 *ps_offsets; printf( "\t Pair Sub Table[%d]\n", which ); printf( "\t SubFormat=%d\n", subformat = getushort(ttf)); printf( "\t Coverage Offset=%d\n", coverage = getushort(ttf)); printf( "\t ValueFormat1=0x%x ", vf1 = getushort(ttf)); printf( "%s%s%s%s%s%s%s%s\n", (vf1&1) ? "XPlacement|":"", (vf1&2) ? "YPlacement|":"", (vf1&4) ? "XAdvance|":"", (vf1&8) ? "YAdvance|":"", (vf1&0x10) ? "XDevPlacement|":"", (vf1&0x20) ? "YDevPlacement|":"", (vf1&0x40) ? "XDevAdvance|":"", (vf1&0x80) ? "YDevAdvance|":"" ); printf( "\t ValueFormat2=0x%x ", vf2 = getushort(ttf)); printf( "%s%s%s%s%s%s%s%s\n", (vf2&1) ? "XPlacement|":"", (vf2&2) ? "YPlacement|":"", (vf2&4) ? "XAdvance|":"", (vf2&8) ? "YAdvance|":"", (vf2&0x10) ? "XDevPlacement|":"", (vf2&0x20) ? "YDevPlacement|":"", (vf2&0x40) ? "XDevAdvance|":"", (vf2&0x80) ? "YDevAdvance|":"" ); if ( subformat==1 ) { printf( "\t PairSetCnt=%d\n", cnt = getushort(ttf)); ps_offsets = calloc(cnt,sizeof(short)); for ( i=0; i %d (%s)\n", glyphs[i], glyphs[i]>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names==NULL? "" : info->glyph_names[glyphs[i]], glyph2, glyph2>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[glyph2]); readvaluerecord(vf1,ttf,"First"); readvaluerecord(vf2,ttf,"Second"); } } free(ps_offsets); } else if ( subformat==2 ) { printf( "\t Class based kerning (not displayed)\n" ); PrintGlyphs( showCoverageTable(ttf,stoffset+coverage,-1),info); } else { printf( "\t !!! unknown sub-table format !!!!\n" ); } } static void ShowAttach(FILE *ttf) { int format = getushort(ttf); int x = getushort(ttf); int y = getushort(ttf); if ( format==1 ) printf( "Attach at (%d,%d)\n", x, y ); else if ( format==2 ) printf( "Attach at (%d,%d pt=%d)\n", x, y, getushort(ttf) ); else if ( format==3 ) { printf( "Attach at (%d,%d XDeviceOff=%d", x, y, getushort(ttf) ); printf( " YDeviceOff=%d)\n", getushort(ttf) ); } else printf( "Unknown attachment format %d\n", format ); } static void gposMarkToBaseSubTable(FILE *ttf, int which, int stoffset, struct ttfinfo *info, int m2b) { int mcoverage, bcoverage, classcnt, markoff, baseoff; uint16 *mglyphs, *bglyphs; int i, j; uint16 *offsets; uint32 pos; printf( m2b ? "\t Mark To Base Sub Table[%d]\n" : "\t Mark To Mark Sub Table[%d]\n", which ); printf( "\t SubFormat=%d\n", getushort(ttf)); printf( "\t Mark Coverage Offset=%d\n", mcoverage = getushort(ttf)); printf( "\t Base Coverage Offset=%d\n", bcoverage = getushort(ttf)); printf( "\t Class Count=%d\n", classcnt = getushort(ttf)); printf( "\t Mark Offset=%d\n", markoff = getushort(ttf)); printf( "\t Base Offset=%d\n", baseoff = getushort(ttf)); printf( "\t Mark Glyphs\n" ); mglyphs = showCoverageTable(ttf,stoffset+mcoverage, -1); /* Class cnt is not the count of marks */ printf( "\t Base Glyphs\n" ); bglyphs = showCoverageTable(ttf,stoffset+bcoverage, -1); fseek(ttf,stoffset+baseoff,SEEK_SET); printf( "\t Base Glyph Count=%d\n", getushort(ttf)); offsets = malloc(classcnt*sizeof(uint16)); for ( i=0; bglyphs[i]!=0xffff; ++i ) { printf( "\t\tBase Glyph %d (%s)\n", bglyphs[i], bglyphs[i]>=info->glyph_cnt ? "!!! Bad glyph !!!" : info->glyph_names == NULL ? "" : info->glyph_names[bglyphs[i]]); for ( j=0; j=info->glyph_cnt ? "!!! Bad glyph !!!" : info->glyph_names == NULL ? "" : info->glyph_names[mglyphs[i]]); printf( "\t\t\tClass=%d ", getushort(ttf)); offsets[0] = getushort(ttf); pos = ftell(ttf); if ( offsets[0]!=0 ) { printf( "Offset=%d ", offsets[0]); fseek(ttf,stoffset+markoff+offsets[0],SEEK_SET); ShowAttach(ttf); } fseek(ttf,pos,SEEK_SET); } free(offsets); free(mglyphs); free(bglyphs); } static void gsubSingleSubTable(FILE *ttf, int which, int stoffset, struct ttfinfo *info) { int coverage, cnt, i, type; uint16 *glyphs; printf( "\t Single Sub Table[%d] (varient forms)\n", which ); printf( "\t Type=%d\n", type = getushort(ttf)); printf( "\t Coverage Offset=%d\n", coverage = getushort(ttf)); if ( type==1 ) { uint16 delta = getushort(ttf); printf( "\t Delta=%d\n", delta); glyphs = showCoverageTable(ttf,stoffset+coverage, -1); printf( "\t Which means ...\n" ); for ( i=0; glyphs[i]!=0xffff; ++i ) printf( "\t\tGlyph %d (%s) -> %d (%s)\n", glyphs[i], glyphs[i]>=info->glyph_cnt ? "!!! Bad glyph !!!" : info->glyph_names == NULL ? "" : info->glyph_names[glyphs[i]], (uint16) (glyphs[i]+delta), (uint16) (glyphs[i]+delta)>=info->glyph_cnt ? "!!! Bad glyph !!!" : info->glyph_names == NULL ? "" : info->glyph_names[(uint16) (glyphs[i]+delta)]); } else { int here; printf( "\t Count=%d\n", cnt = getushort(ttf)); here = ftell(ttf); glyphs = showCoverageTable(ttf,stoffset+coverage, cnt); fseek(ttf,here,SEEK_SET); for ( i=0; i %d (%s)\n", glyphs[i], glyphs[i]>=info->glyph_cnt ? "!!! Bad glyph !!!" : info->glyph_names == NULL ? "" : info->glyph_names[glyphs[i]], val, val >= info->glyph_cnt ? "!!! Bad glyph !!!" : info->glyph_names == NULL ? "" : info->glyph_names[val]); } } } static void gsubMultipleSubTable(FILE *ttf, int which, int stoffset, struct ttfinfo *info) { int coverage, cnt, i, j, glyph_cnt; uint16 *seq_offsets; uint16 *glyphs; printf( "\t Multiple Sub Table[%d] (ligature decomposition)\n", which ); printf( "\t Type=%d\n", getushort(ttf)); printf( "\t Coverage Offset=%d\n", coverage = getushort(ttf)); printf( "\t Count=%d\n", cnt = getushort(ttf)); seq_offsets = malloc(cnt*sizeof(uint16)); for ( i=0; i=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[glyphs[i]]); printf( "\t Count=%d\n", glyph_cnt = getushort(ttf)); printf( "\t Glyph %d (%s) -> ", glyphs[i], glyphs[i]>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[glyphs[i]] ); for ( j=0; j=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[de]); } putchar('\n'); } free(seq_offsets); } static void gsubAlternateSubTable(FILE *ttf, int which, int stoffset, struct ttfinfo *info) { int coverage, cnt, i, j, glyph_cnt; uint16 *seq_offsets; uint16 *glyphs; printf( "\t Alternate Sub Table[%d] (varient forms)\n", which ); printf( "\t Type=%d\n", getushort(ttf)); printf( "\t Coverage Offset=%d\n", coverage = getushort(ttf)); printf( "\t Count=%d\n", cnt = getushort(ttf)); seq_offsets = malloc(cnt*sizeof(uint16)); for ( i=0; i=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[glyphs[i]]); printf( "\t Count=%d\n", glyph_cnt = getushort(ttf)); printf( "\t Glyph %d (%s) -> ", glyphs[i], glyphs[i]>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[glyphs[i]] ); for ( j=0; j=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[de]); } putchar('\n'); } free(seq_offsets); } static void gsubLigatureSubTable(FILE *ttf, int which, int stoffset, struct ttfinfo *info) { int coverage, cnt, i, j, k, lig_cnt, cc, gl; uint16 *ls_offsets, *lig_offsets; uint16 *glyphs; printf( "\t Ligature Sub Table[%d]\n", which ); printf( "\t Type=%d\n", getushort(ttf)); printf( "\t Coverage Offset=%d\n", coverage = getushort(ttf)); printf( "\t Lig Set Count=%d\n", cnt = getushort(ttf)); ls_offsets = malloc(cnt*sizeof(uint16)); for ( i=0; i=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[glyphs[i]]); printf( "\t Count=%d\n", lig_cnt = getushort(ttf)); lig_offsets = malloc(lig_cnt*sizeof(uint16)); for ( j=0; j=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[gl], glyphs[i], glyphs[i]>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[glyphs[i]]); cc = getushort(ttf); for ( k=1; k=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names == NULL ? "" : info->glyph_names[gl]); } putchar('\n'); } free(lig_offsets); } free(ls_offsets); free(glyphs); } static void gsubContextSubTable(FILE *ttf, int which, int stoffset, struct ttfinfo *info) { } static void gsubChainingContextSubTable(FILE *ttf, int which, int stoffset, struct ttfinfo *info) { } static void showgpossublookup(FILE *ttf,int base, int lkoffset, struct ttfinfo *info, int gpos ) { int lu_type, flags, cnt, j, st, is_exten_lu; uint16 *st_offsets; fseek(ttf,base+lkoffset,SEEK_SET); lu_type = getushort(ttf); flags = getushort(ttf); cnt = getushort(ttf); if ( gpos ) { printf( "\t Type=%d %s\n", lu_type, lu_type==1?"Single adjustment": lu_type==2?"Pair adjustment": lu_type==3?"Cursive attachment": lu_type==4?"MarkToBase attachment": lu_type==5?"MarkToLigature attachment": lu_type==6?"MarkToMark attachment": lu_type==7?"Context positioning": lu_type==8?"Chained Context positioning": lu_type==9?"Extension positioning": "Reserved"); is_exten_lu = lu_type==9; } else { printf( "\t Type=%d %s\n", lu_type, lu_type==1?"Single": lu_type==2?"Multiple": lu_type==3?"Alternate": lu_type==4?"Ligature": lu_type==5?"Context": lu_type==6?"Chaining Context": lu_type==7?"Extension": lu_type==8?"Reverse chaining": "Reserved"); is_exten_lu = lu_type==7; } printf( "\t Flags=0x%x %s|%s|%s|%s\n", flags, (flags&0x1)?"RightToLeft":"LeftToRight", (flags&0x2)?"IgnoreBaseGlyphs":"", (flags&0x4)?"IgnoreLigatures":"", (flags&0x8)?"IgnoreCombiningMarks":""); printf( "\t Sub Table Count=%d\n", cnt); st_offsets = malloc(cnt*sizeof(uint16)); for ( j=0; jgsub_start,SEEK_SET); printf( "\nGSUB table (at %d) (Glyph substitution)\n", info->gsub_start ); printf( "\t version=%g\n", getfixed(ttf)); printf( "\t Script List Offset=%d\n", slo = getushort(ttf)); printf( "\t Feature List Offset=%d\n", flo = getushort(ttf)); printf( "\t Lookup List Offset=%d\n", llo = getushort(ttf)); showscriptlist(ttf,info->gsub_start+slo ); showfeaturelist(ttf,info->gsub_start+flo ); showgpossublookups(ttf,info->gsub_start+llo,info,false ); } static void readttfgpos(FILE *ttf, FILE *util, struct ttfinfo *info) { int slo, flo, llo; fseek(ttf,info->gpos_start,SEEK_SET); printf( "\nGPOS table (at %d) (Glyph positioning)\n", info->gpos_start ); printf( "\t version=%g\n", getfixed(ttf)); printf( "\t Script List Offset=%d\n", slo = getushort(ttf)); printf( "\t Feature List Offset=%d\n", flo = getushort(ttf)); printf( "\t Lookup List Offset=%d\n", llo = getushort(ttf)); showscriptlist(ttf,info->gpos_start+slo ); showfeaturelist(ttf,info->gpos_start+flo ); showgpossublookups(ttf,info->gpos_start+llo,info,true ); } static void gdefshowglyphclassdef(FILE *ttf,int offset,struct ttfinfo *info) { uint16 *glist=NULL; int i; static const char * const classes[] = { "Unspecified", "Base", "Ligature", "Mark", "Component" }; const int max_class = sizeof(classes)/sizeof(classes[0]); printf( " Glyph Class Definitions\n" ); glist = getClassDefTable(ttf,offset,info->glyph_cnt); for ( i=0; iglyph_cnt; ++i ) if ( glist[i]>0 && glist[i]=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names!=NULL ? info->glyph_names[i] : "", classes[glist[i]]); } free(glist); } static void gdefshowligcaretlist(FILE *ttf,int offset,struct ttfinfo *info) { int coverage, cnt, i, j, cc, format; uint16 *lc_offsets, *glyphs, *offsets; uint32 caret_base; fseek(ttf,offset,SEEK_SET); printf( " Ligature Caret List\n" ); printf( "\t Coverage Offset=%d\n", coverage = getushort(ttf)); printf( "\t Ligature Count=%d\n", cnt = getushort(ttf)); lc_offsets = malloc(cnt*sizeof(uint16)); for ( i=0; i=info->glyph_cnt ? "!!! Bad Glyph !!!" : info->glyph_names==NULL ? "" : info->glyph_names[glyphs[i]]); caret_base = ftell(ttf); printf("\t Count = %d\n", cc = getushort(ttf)); offsets = malloc(cc*sizeof(uint16)); for ( j=0; jgdef_start,SEEK_SET); printf( "\nGDEF table (at %d) (Glyph definitions)\n", info->gdef_start ); printf( "\t version=%g\n", getfixed(ttf)); printf( "\t Glyph class Def Offset=%d\n", gco = getushort(ttf)); printf( "\t Attach List Offset=%d\n", alo = getushort(ttf)); printf( "\t Ligature Caret List Offset=%d\n", lco = getushort(ttf)); printf( "\t Mark Attach Class Def Offset=%d\n", maco = getushort(ttf)); if ( gco!=0 ) gdefshowglyphclassdef(ttf,info->gdef_start+gco,info); if ( lco!=0 ) gdefshowligcaretlist(ttf,info->gdef_start+lco,info); } static void readttfkern_context(FILE *ttf, FILE *util, struct ttfinfo *info, int stab_len); static void readttfkern(FILE *ttf, FILE *util, struct ttfinfo *info) { int version, ntables; int header_size, len, coverage, i, j; uint32 begin; int left, right, array, n; fseek(ttf,info->kern_start,SEEK_SET); printf( "\nkern table (at %d)\n", info->kern_start ); version = getushort(ttf); if ( version!=0 ) { fseek(ttf,info->kern_start,SEEK_SET); version = getlong(ttf); ntables = getlong(ttf); printf( "\t version=%g (Apple format)\n\t num_tables=%d\n", ((double) version)/65536., ntables); header_size = 8; } else { ntables = getushort(ttf); printf( "\t version=%d (Old style)\n\t num_tables=%d\n", version, ntables); header_size = 6; } for ( i=0; i>8 )); if ( (coverage>>8)==0 ) { /* Kern pairs */ int n = getushort(ttf); int sr = getushort(ttf); int es = getushort(ttf); int rs = getushort(ttf); printf( "\t npairs=%d searchRange=%d entrySelector=%d rangeShift=%d\n", n, sr, es, rs ); for ( i=0; iglyph_names!=NULL && leftglyph_cnt && rightglyph_cnt ) { printf( "\t\t%s %s %d\n", info->glyph_names[left], info->glyph_names[right], val ); } else { printf( "\t\t%d %d %d\n", left, right, val ); } } } fseek(ttf,begin+header_size,SEEK_SET); } else { len = getlong(ttf); coverage = getushort(ttf); printf( "\t len=%d coverage=%x %s%s%s sub table format=%d\n", len, coverage, ( coverage&0x8000 ) ? "Vertical": "Horizontal", ( coverage&0x4000 ) ? " cross-stream" : "", ( coverage&0x2000 ) ? " kern-variation" : "", ( coverage&0xff )); printf( "\t tuple index=%d\n", getushort(ttf)); switch ( (coverage&0xff) ) { case 1: readttfkern_context(ttf,util, info, len-6); break; case 2: printf( "\t row Width=%d\n", getushort(ttf)); printf( "\t left class offset=%d\n", left =getushort(ttf)); printf( "\t right class offset=%d\n", right = getushort(ttf)); printf( "\t array offset=%d\n", array = getushort(ttf)); fseek(ttf,begin+left,SEEK_SET); printf( "\t left class table\n" ); printf( "\t first Glyph=%d\n", getushort(ttf) ); printf( "\t number of glyphs=%d\n", n = getushort(ttf) ); printf( "\t " ); for ( j=0; jfdsc_start,SEEK_SET); printf( "\nfdsc table (at %d) (font description)\n", info->fdsc_start ); printf( "\t version=%g\n", getfixed(ttf)); n = getushort(ttf); printf( "\t number of descriptions=%d\n", n); for ( i=0; i>24, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff, tag==CHR('w','g','h','t')? "Weight" : tag==CHR('w','d','t','h')? "Width" : tag==CHR('s','l','n','t')? "Slant" : tag==CHR('o','p','s','z')? "Optical Size" : tag==CHR('n','a','l','f')? "Non-alphabetic" : "Unknown", lval ); switch ( tag ) { case CHR('w','g','h','t'): case CHR('w','d','t','h'): case CHR('s','l','n','t'): case CHR('o','p','s','z'): default: printf( "%g\n", val ); break; case CHR('n','a','l','f'): printf( lval==0 ? "Alphabetic\n" : lval==1 ? "Dingbats\n" : lval==2 ? "Pi characters\n" : lval==3 ? "Fleurons\n" : lval==4 ? "Decorative borders\n" : lval==5 ? "International symbols\n" : lval==6 ? "Math symbols\n" : "Unknown" ); break; } } } static void readttffeatures(FILE *ttf, FILE *util, struct ttfinfo *info) { int n, i, j, nameid; uint32 setting_offset; fseek(ttf,info->feat_start,SEEK_SET); printf( "\nfeat table (at %d) (feature names)\n", info->feat_start ); printf( "\t version=%g\n", getfixed(ttf)); n = getushort(ttf); printf( "\t number of features=%d\n", n); printf( "\t must be zero: %x\n", getushort(ttf)); printf( "\t must be zero: %x\n", getlong(ttf)); info->features = calloc(n+1,sizeof(struct features)); info->features[n].feature = -1; for ( i=0; ifeatures[i].feature = getushort(ttf); info->features[i].nsettings = getushort(ttf); info->features[i].settings = calloc(info->features[i].nsettings,sizeof(struct settings)); setting_offset = getlong(ttf); info->features[i].featureflags = getushort(ttf); nameid = getushort(ttf); info->features[i].name = getttfname(util,info,nameid); printf( "\t Feature %d\n", i ); printf( "\t Feature Id %d\n", info->features[i].feature ); printf( "\t number Settings %d\n", info->features[i].nsettings ); printf( "\t setting offset %ld\n", setting_offset ); printf( "\t feature flags %d ", info->features[i].featureflags ); if ( !(info->features[i].featureflags&0x8000) ) printf( "Non-Exclusive settings\n" ); else if ( !(info->features[i].featureflags&0x4000) ) printf( "Exclusive Settings, Default=0\n" ); else printf( "Exclusive Settings, Default=%d\n", info->features[i].featureflags&0xff); printf( "\t name index %d (%s)\n", nameid, info->features[i].name==NULL?"Not found":info->features[i].name ); fseek(util,info->feat_start+setting_offset,SEEK_SET); for ( j=0; jfeatures[i].nsettings; ++j ) { info->features[i].settings[j].setting = getushort(util); info->features[i].settings[j].nameid = getushort(util); } for ( j=0; jfeatures[i].nsettings; ++j ) info->features[i].settings[j].name = getttfname(util,info,info->features[i].settings[j].nameid); for ( j=0; jfeatures[i].nsettings; ++j ) printf( "\t Setting %d nameid=%d name=%s\n", info->features[i].settings[j].setting, info->features[i].settings[j].nameid, info->features[i].settings[j].name==NULL ? "Not found" : info->features[i].settings[j].name ); } } static char *getfeaturename(struct ttfinfo *info, int type) { int k; char *name; name = NULL; if ( info->features!=NULL ) { for ( k=0; info->features[k].feature!=-1 && info->features[k].feature!=type; ++k ); name = info->features[k].name; /* will be null at end of list */ } if ( name!=NULL ) return( name ); /* This list is taken from http://developer.apple.com/fonts/Registry/index.html*/ return( type==0 ? "All typographic features" : type==1 ? "Ligature" : type==2 ? "Cursive connection" : type==3 ? "Letter case" : type==4 ? "Vertical substitution" : type==5 ? "Linguistic rearrangement" : type==6 ? "Number spacing" : type==7 ? "apple, reserved" : type==8 ? "Smart swashes" : type==9 ? "Diacritics" : type==10 ? "Vertical Position" : type==11 ? "Fractions" : type==13 ? "Overlapping characters" : type==14 ? "Typographic extras" : type==15 ? "Mathematical extras" : type==16 ? "Ornament sets" : type==17 ? "Character alternatives" : type==18 ? "Design complexity" : type==19 ? "Style options" : type==20 ? "Character shape" : type==21 ? "Number case" : type==22 ? "Text/Letter spacing" : type==23 ? "Transliteration" : type==24 ? "Annotation" : type==25 ? "Kana Spacing" : type==26 ? "Ideographic Spacing" : type==27 ? "?Accented leters (undocumented)?" : type==103 ? "CJK Roman spacing" : /* Compatability (depreciated) ... */ type==100 ? "(adobe) Character Spacing" : type==101 ? "(adobe) Kana Spacing" : type==102 ? "(adobe) Kanji Spacing" : type==104 ? "(adobe) Square Ligatures" : /* End */ type==16000 ? "?Decompose Unicode (undocumented)?" : type==16001 ? "?Combining character (undocumented)?" : "Unknown feature type" ); } static char *getsettingname(struct ttfinfo *info, int type, int setting) { int k,l; char *name; name = NULL; if ( info->features!=NULL ) { for ( k=0; info->features[k].feature!=-1 && info->features[k].feature!=type; ++k ); if ( info->features[k].feature!=-1 ) { /*name = info->features[k].name; /* will be null at end of list */ for ( l=0 ; lfeatures[k].nsettings && info->features[k].settings[l].setting!=setting; ++l ); if ( lfeatures[k].nsettings ) name = info->features[k].settings[l].name; } } if ( name ) return( name ); /* These lists are taken from http://developer.apple.com/fonts/Registry/index.html*/ /* the numeric values are at the bottom of the page */ else switch ( type ) { case 0: return( setting==0 ? "On" : setting==1 ? "Off" : "Unknown" ); break; case 1: /* Ligatures */ return( setting==0 ? "Required ligatures On" : setting==1 ? "Required ligatures Off" : setting==2 ? "Common Ligatures On" : setting==3 ? "Common Ligatures Off" : setting==4 ? "Rare Ligatures On" : setting==5 ? "Rare Ligatures Off" : setting==6 ? "Logos On" : setting==7 ? "Logos Off" : setting==8 ? "Rebus pictures On" : setting==9 ? "Rebus pictures Off" : setting==10 ? "Dipthong ligatures On" : setting==11 ? "Dipthong ligatures Off" : setting==12 ? "Squared ligatures On" : setting==13 ? "Squared ligatures Off" : setting==14 ? "Squared ligatures, abbreviated On" : setting==15 ? "Squared ligatures, abbreviated Off" : "Unknown" ); break; case 2: /* cursive */ return( setting==0 ? "Unconnected" : setting==1 ? "Partially connected" : setting==2 ? "Cursive" : "Unknown" ); break; case 3: /* Letter case */ return( setting==0 ? "Upper & Lower case" : setting==1 ? "All Caps" : setting==2 ? "All Lower Case" : setting==3 ? "Small Caps" : setting==4 ? "Initial Caps" : setting==5 ? "Initial Caps & Small Caps" : "Unknown" ); break; case 4: /* Vertical Substitution */ return( setting==0 ? "On" : setting==1 ? "Off" : "Unknown" ); break; case 5: /* Linguistic Rearrangement */ return( setting==0 ? "On" : setting==1 ? "Off" : "Unknown" ); break; case 6: /* Number spacing */ return( setting==0 ? "On" : setting==1 ? "Off" : "Unknown" ); break; case 8: /* Smart swash */ return( setting==0 ? "Initial swashes On" : setting==1 ? "Initial swashes Off" : setting==2 ? "Final swashes On" : setting==3 ? "Final swashes Off" : setting==4 ? "line initial swashes On" : setting==5 ? "line initial swashes Off" : setting==6 ? "line final swashes On" : setting==7 ? "line final swashes Off" : setting==8 ? "non-final swashes On" : setting==9 ? "non-final swashes Off" : "Unknown" ); break; case 9: /* diacritics */ return( setting==0 ? "show Diacritics" : setting==1 ? "hide Diacritics" : setting==2 ? "decompose Diacritics" : "Unknown" ); break; case 10: /* vertical positioning */ return( setting==0 ? "normal position" : setting==1 ? "superiors" : setting==2 ? "inferiors" : setting==3 ? "ordinals" : "Unknown" ); break; case 11: /* fractions */ return( setting==0 ? "no fractions" : setting==1 ? "vertical fractions" : setting==2 ? "diagonal fractions" : "Unknown" ); break; case 13: /* overlapping chars */ return( setting==0 ? "prevent Overlap On" : setting==1 ? "prevent Overlap Off" : "Unknown" ); break; case 14: /* typographic extras */ return( setting==0 ? "hyphens to Em dashes On" : setting==1 ? "hyphens to Em dashes Off" : setting==2 ? "hyphens to En dashes On" : setting==3 ? "hyphens to En dashes Off" : setting==4 ? "unslashed Zero On" : setting==5 ? "unslashed Zero Off" : setting==6 ? "form Interrobang On" : setting==7 ? "form Interrobang Off" : setting==8 ? "smart Quotes On" : setting==9 ? "smart Quotes Off" : setting==10 ? "periods to ellipsis On" : setting==11 ? "periods to ellipsis Off" : "Unknown" ); break; case 15: /* mathmatical extras */ return( setting==0 ? "hyphen to minus On" : setting==1 ? "hyphen to minus Off" : setting==2 ? "asterisk to multiply On" : setting==3 ? "asterisk to multiply Off" : setting==4 ? "slash to divide On" : setting==5 ? "slash to divide Off" : setting==6 ? "inequality ligatures On" : setting==7 ? "inequality ligatures Off" : setting==8 ? "exponents On" : setting==9 ? "exponents Off" : "Unknown" ); break; case 16: /* ornament sets */ return( setting==0 ? "no ornaments" : setting==1 ? "dingbats" : setting==2 ? "pi Characters" : setting==3 ? "fleurons" : setting==4 ? "decorative borders" : setting==5 ? "international symbols" : setting==6 ? "math symbols" : "Unknown" ); break; case 17: /* character alternates */ return( setting==0 ? "no alternates" : "Unknown" ); break; case 18: /* design complexity */ return( setting==0 ? "design level 1" : setting==1 ? "design level 2" : setting==2 ? "design level 3" : setting==3 ? "design level 4" : setting==4 ? "design level 5" : "Unknown" ); break; case 19: /* style options */ return( setting==0 ? "no style options" : setting==1 ? "display text" : setting==2 ? "engraved text" : setting==3 ? "illuminated Caps" : setting==4 ? "titling caps" : setting==5 ? "tall caps" : "Unknown" ); break; case 20: /* character shape */ return( setting==0 ? "traditional characters" : setting==1 ? "simplified characters" : setting==2 ? "jis1978 characters" : setting==3 ? "jis1983 characters" : setting==4 ? "jis1990 characters" : setting==5 ? "traditional alt 1" : setting==6 ? "traditional alt 2" : setting==7 ? "traditional alt 3" : setting==8 ? "traditional alt 4" : setting==9 ? "traditional alt 5" : setting==10 ? "expert characters" : "Unknown" ); break; case 21: /* number case */ return( setting==0 ? "lower case numbers" : setting==1 ? "upper case numbers" : "Unknown" ); break; case 22: /* text spacing */ return( setting==0 ? "proportional" : setting==1 ? "monospace" : setting==2 ? "halfwidth" : setting==3 ? "normally spaced" : "Unknown" ); break; case 23: /* transliteration */ return( setting==0 ? "no transliteration" : setting==1 ? "hanja to hangul" : setting==2 ? "hiragana to katakana" : setting==3 ? "katakana to hiragana" : setting==4 ? "kana to Romanization" : setting==5 ? "romanization to Hiragana" : setting==6 ? "romanization to Katakana" : setting==7 ? "hanja to hangul alt 1" : setting==8 ? "hanja to hangul alt 2" : setting==9 ? "hanja to hangul alt 3" : setting==10 ? "expert characters" : "Unknown" ); break; case 24: /* anotation */ return( setting==0 ? "no annotation" : setting==1 ? "box annotation" : setting==2 ? "rounded box annotation" : setting==3 ? "circle annotation" : setting==4 ? "inverted circle annotation" : setting==5 ? "parenthesis Annotation" : setting==6 ? "period annotation" : setting==7 ? "roman numeral annotation" : setting==8 ? "diamond annotation" : "Unknown" ); break; case 25: /* kana spacing */ return( setting==0 ? "full width kana" : setting==1 ? "proportional kana" : /* Proportional Japanese glyphs */ "Unknown" ); break; case 26: /* ideograph spacing */ return( setting==0 ? "full width ideograph" : setting==1 ? "proportional ideograph" : "Unknown" ); break; case 27: /* Accented letters (determined empirically) */ return( setting==0 ? "On" : setting==1 ? "Off" : "Unknown" ); break; case 103: /* CJK Spacing */ return( setting==0 ? "halfwidth CJK Roman" : /* No change */ setting==1 ? "proportional CJK Roman" : setting==2 ? "default CJK Roman" : /* Ideal metrics */ setting==3 ? "fullwidth CJK Roman" : "Unknown" ); break; case 16000: /* Decomposed Unicode (determined empirically) */ return( setting==0 ? "Compose" : setting==1 ? "Off" : "Unknown" ); break; case 16001: /* Combining character (determined empirically) */ return( setting==0 ? "Combine" : setting==1 ? "Off" : "Unknown" ); break; default: return( setting==0 ? "Unknown (?On?)" : setting==1 ? "Unknown (?Off?)" : "Unknown" ); break; } return( "Unknown" ); } static int showbinsearchheader(FILE *ttf) { int size, cnt; printf( "\t Binary search header\n" ); printf( "\t Entry size=%d\n", size = getushort(ttf)); printf( "\t Number of entries=%d\n", cnt = getushort(ttf)); printf( "\t Search range=%d\n", getushort(ttf)); printf( "\t Log2(nUnits)=%d\n", getushort(ttf)); printf( "\t Range Shift=%d\n", getushort(ttf)); return( cnt ); } static void show_applelookuptable(FILE *ttf,struct ttfinfo *info,void (*show)(FILE *,struct ttfinfo *)) { int i, j; int format; int first, last, cnt, glyph, data_offset; uint32 here; uint32 base = ftell(ttf); printf( "\t Lookup table format=%d ", format = getushort(ttf)); switch ( format ) { case 0: printf( "Simple array\n" ); for ( i=0; iglyph_cnt; ++i ) { printf( "Glyph %d (%s)=", i, i>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names!=NULL ? info->glyph_names[i]: "" ); show( ttf,info ); } break; case 2: printf( "Segment Single\n" ); cnt = showbinsearchheader(ttf); for ( i=0; iglyph_names!=NULL ? info->glyph_names[first]: "", last, last>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names!=NULL ? info->glyph_names[last]: "" ); show( ttf,info ); } break; case 4: printf( "Segment Array\n" ); cnt = showbinsearchheader(ttf); for ( i=0; iglyph_names!=NULL ? info->glyph_names[j]: "" ); show( ttf,info ); } fseek(ttf,here,SEEK_SET); } break; case 6: printf( "Single table\n" ); cnt = showbinsearchheader(ttf); for ( i=0; iglyph_names!=NULL ? info->glyph_names[glyph]: "" ); show( ttf,info ); } break; case 8: printf( "Trimmed array\n" ); first = getushort(ttf); cnt = getushort(ttf); for ( i=0; iglyph_names!=NULL ? info->glyph_names[i+first]: "" ); show( ttf,info ); } break; default: printf( "Unknown format for lookup table %d\n", format ); } } /* some class codes are predefined: 0 => End of text 1 => out of bounds (anything outside the glyph range in the class header, and possibly some glyphs within 2 => deleted glyph (0xffff => a glyph has been deleted, should not be in array) 3 => End of line 4 - nclasses-1 => user defined */ struct classes { }; struct statetable { uint32 state_start; int nclasses; int nstates; int nentries; int state_offset; int entry_size; /* size of individual entry */ int entry_extras; /* Number of extra glyph offsets */ int first_glyph; /* that's classifyable */ int nglyphs; uint8 *classes; uint8 *state_table; /* state_table[nstates][nclasses], each entry is an */ /* index into the following array */ uint16 *state_table2; /* morx version. States are have 2 byte entries */ uint16 *classes2; uint8 *transitions; uint32 extra_offsets[3]; int len; /* Size of the entire subtable */ }; static void show_statetable(struct statetable *st, struct ttfinfo *info, FILE *ttf, void (*entry_print)(uint8 *entry,struct statetable *st,struct ttfinfo *info,FILE *ttf)) { int i, j; uint8 *pt; printf( "\t State table\n" ); printf( "\t num classes = %d\n", st->nclasses ); printf( "\t num states = %d (derived)\n", st->nstates ); printf( "\t num entries = %d (derived)\n", st->nentries ); printf( "\t entry size = %d (derived)\n", st->entry_size ); printf( "\t first classified glyph = %d (%s), glyph_cnt=%d\n", st->first_glyph, st->first_glyph>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names!=NULL?info->glyph_names[st->first_glyph]:"", st->nglyphs); if ( info->glyph_names!=NULL ) { for ( i=0; inglyphs; ++i ) printf( "\t Glyph %4d -> Class %d (%s)\n", st->first_glyph+i, st->classes[i], st->first_glyph+i>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names[st->first_glyph+i]); } else { for ( i=0; inglyphs; ++i ) printf( "\t Glyph %4d -> Class %d\n", st->first_glyph+i, st->classes[i] ); } /* Mapping from state x class => transition entry */ printf( "Classes: " ); for ( j=0; jnclasses; ++j ) printf( "%4d", j ); printf( "\n" ); for ( i=0; instates; ++i ) { printf( "State %2d: ", i ); for ( j=0; jnclasses; ++j ) printf( "%4d", st->state_table[i*st->nclasses+j]); printf( "\n" ); } /* Transition entries */ for ( i=0; inentries; ++i ) { pt = st->transitions + i*st->entry_size; printf( "\t Transition Entry %d\n", i ); printf( "\t New State %d\n", (((pt[0]<<8)|pt[1])-st->state_offset)/st->nclasses ); if ( entry_print!=NULL ) entry_print(pt,st,info,ttf); else { printf( "\t Flags %04x\n", (pt[2]<<8)|pt[3] ); for ( j=0; jentry_extras; ++j ) printf( "\t GlyphOffset[%d] = %d\n", j, (pt[2*j+4]<<8)|pt[2*j+5]); } } printf( "\n" ); } static void show_statetablex(struct statetable *st, struct ttfinfo *info, FILE *ttf, void (*entry_print)(uint8 *entry,struct statetable *st,struct ttfinfo *info,FILE *ttf)) { int i, j; uint8 *pt; printf( "\t State table\n" ); printf( "\t num classes = %d\n", st->nclasses ); printf( "\t num states = %d (derived)\n", st->nstates ); printf( "\t num entries = %d (derived)\n", st->nentries ); printf( "\t entry size = %d (derived)\n", st->entry_size ); for ( i=0; iglyph_cnt ; ++i ) if ( st->classes2[i]!=1 ) { if ( info->glyph_names!=NULL ) { printf( "\t Glyph %4d -> Class %d (%s)\n", i, st->classes2[i], i>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names[i]); } else { printf( "\t Glyph %4d -> Class %d\n", i, st->classes2[i] ); } } /* Mapping from state x class => transition entry */ printf( "Classes: " ); for ( j=0; jnclasses; ++j ) printf( "%4d", j ); printf( "\n" ); for ( i=0; instates; ++i ) { printf( "State %2d: ", i ); for ( j=0; jnclasses; ++j ) printf( "%4d", st->state_table2[i*st->nclasses+j]); printf( "\n" ); } /* Transition entries */ for ( i=0; inentries; ++i ) { pt = st->transitions + i*st->entry_size; printf( "\t Transition Entry %d\n", i ); printf( "\t New State %d\n", ((pt[0]<<8)|pt[1]) ); if ( entry_print!=NULL ) entry_print(pt,st,info,ttf); else { printf( "\t Flags %04x\n", (pt[2]<<8)|pt[3] ); for ( j=0; jentry_extras; ++j ) printf( "\t GlyphOffset[%d] = %d\n", j, (pt[2*j+4]<<8)|pt[2*j+5]); } } printf( "\n" ); } static void readttf_applelookup(FILE *ttf,struct ttfinfo *info, void (*apply_values)(struct ttfinfo *info, int gfirst, int glast,FILE *ttf), void (*apply_value)(struct ttfinfo *info, int gfirst, int glast,FILE *ttf), void (*apply_default)(struct ttfinfo *info, int gfirst, int glast,void *def), void *def) { int format, i, first, last, data_off, cnt, prev; uint32 here; uint32 base = ftell(ttf); switch ( format = getushort(ttf)) { case 0: /* Simple array */ apply_values(info,0,info->glyph_cnt-1,ttf); break; case 2: /* Segment Single */ /* Entry size */ getushort(ttf); cnt = getushort(ttf); /* search range */ getushort(ttf); /* log2(cnt) */ getushort(ttf); /* range shift */ getushort(ttf); prev = 0; for ( i=0; iglyph_cnt-1,def); } apply_values(info,first,first+cnt-1,ttf); break; default: fprintf( stderr, "Invalid lookup table format. %d\n", format ); break; } } static void mortclass_apply_values(struct ttfinfo *info, int gfirst, int glast,FILE *ttf) { int i; for ( i=gfirst; i<=glast; ++i ) info->morx_classes[i] = getushort(ttf); } static void mortclass_apply_value(struct ttfinfo *info, int gfirst, int glast,FILE *ttf) { uint16 class; int i; class = getushort(ttf); for ( i=gfirst; i<=glast; ++i ) info->morx_classes[i] = class; } static struct statetable *read_statetable(FILE *ttf, int ent_extras, int ismorx, struct ttfinfo *info) { struct statetable *st = calloc(1,sizeof(struct statetable)); uint32 here = ftell(ttf); int nclasses, class_off, state_off, entry_off; int state_max, ent_max, old_state_max, old_ent_max; int i, j, ent, new_state, ent_size; st->state_start = here; if ( ismorx ) { nclasses = getlong(ttf); class_off = getlong(ttf); state_off = getlong(ttf); entry_off = getlong(ttf); st->extra_offsets[0] = getlong(ttf); st->extra_offsets[1] = getlong(ttf); st->extra_offsets[2] = getlong(ttf); } else { nclasses = getushort(ttf); /* Number of bytes per state in state subtable, equal to number of classes */ class_off = getushort(ttf); state_off = getushort(ttf); entry_off = getushort(ttf); st->extra_offsets[0] = getushort(ttf); st->extra_offsets[1] = getushort(ttf); st->extra_offsets[2] = getushort(ttf); } st->nclasses = nclasses; st->state_offset = state_off; /* parse class subtable */ fseek(ttf,here+class_off,SEEK_SET); if ( ismorx ) { st->classes2 = info->morx_classes = malloc(info->glyph_cnt*sizeof(uint16)); for ( i=0; iglyph_cnt; ++i ) st->classes2[i] = 1; /* Out of bounds */ readttf_applelookup(ttf,info, mortclass_apply_values,mortclass_apply_value,NULL,NULL); } else { st->first_glyph = getushort(ttf); st->nglyphs = getushort(ttf); st->classes = malloc(st->nglyphs); fread(st->classes,1,st->nglyphs,ttf); } /* The size of an entry is variable. There are 2 uint16 fields at the begin-*/ /* ning of all entries. There may be some number of shorts following these*/ /* used for indexing special tables. */ ent_size = 4 + 2*ent_extras; st->entry_size = ent_size; st->entry_extras = ent_extras; /* Apple does not provide a way of figuring out the size of either of the */ /* state or entry tables, so we must parse both as we go and try to work */ /* out the maximum values... */ /* There are always at least 2 states defined. Parse them and find what */ /* is the biggest entry they use, then parse those entries and find what */ /* is the biggest state they use, and then repeat until we don't find any*/ /* more states or entries */ old_state_max = 0; old_ent_max = 0; state_max = 2; ent_max = 0; while ( old_state_max!=state_max ) { i = old_state_max*nclasses; fseek(ttf,here+state_off+(ismorx?i*sizeof(uint16):i),SEEK_SET); old_state_max = state_max; for ( ; i ent_max ) ent_max = ent+1; } if ( ent_max==old_ent_max ) /* Nothing more */ break; if ( ent_max>1000 ) { fprintf( stderr, "It looks to me as though there's a morx sub-table with more than 1000\n transitions. Which makes me think there's probably an error\n" ); return( NULL ); } fseek(ttf,here+entry_off+old_ent_max*ent_size,SEEK_SET); i = old_ent_max; old_ent_max = ent_max; for ( ; istate_max ) state_max = new_state+1; } if ( state_max>1000 ) { fprintf( stderr, "It looks to me as though there's a morx sub-table with more than 1000\n states. Which makes me think there's probably an error\n" ); return( NULL ); } } st->nstates = state_max; st->nentries = ent_max; fseek(ttf,here+state_off,SEEK_SET); /* an array of arrays of state transitions, each represented by one byte */ /* which is an index into the Entry subtable, which comes next. */ /* One dimension is the number of states, and the other the */ /* number of classes (classes vary faster than states) */ /* The first two states are predefined, 0 is start of text, 1 start of line*/ if ( ismorx ) { st->state_table2 = malloc(st->nstates*st->nclasses*sizeof(uint16)); for ( i=0; instates*st->nclasses; ++i ) st->state_table2[i] = getushort(ttf); } else { st->state_table = malloc(st->nstates*st->nclasses); fread(st->state_table,1,st->nstates*st->nclasses,ttf); } /* parse the entry subtable */ fseek(ttf,here+entry_off,SEEK_SET); st->transitions = malloc(st->nentries*st->entry_size); fread(st->transitions,1,st->nentries*st->entry_size,ttf); return( st ); } static void free_statetable(struct statetable *st) { if ( st==NULL ) return; free( st->state_table ); free( st->state_table2 ); free( st->transitions ); free( st->classes ); free( st->classes2 ); free( st ); } static void show_contextkerndata(uint8 *entry,struct statetable *st,struct ttfinfo *info, FILE *ttf) { int flags = (entry[2]<<8)|entry[3]; int offset = flags&0x3fff; int i, k; printf( "\t Flags %04x ", flags ); if ( flags&0x8000 ) printf( "Add to Kern Stack | "); if ( flags&0x4000 ) printf( "Don't Advance Glyph" ); else printf( "Advance Glyph" ); printf( ", ValueOffset = %d\n", offset ); if ( offset!=0 ) { printf( "Offset=%d, len=%d\n", offset, st->len ); fseek(ttf,offset+st->state_start,SEEK_SET); printf( "Kerns: " ); for ( i=0; i<8; ++i ) { printf( "%d ", (k = (short) getushort(ttf)) & ~1 ); if ( k&1 ) /* list is terminated by an odd number */ break; } printf( "\n" ); } } static void readttfkern_context(FILE *ttf, FILE *util, struct ttfinfo *info, int stab_len) { struct statetable *st; st = read_statetable(ttf,0,false,info); st->len = stab_len; show_statetable(st, info, ttf, show_contextkerndata); free_statetable(st); } static void show_indicflags(uint8 *entry,struct statetable *st,struct ttfinfo *info,FILE *ttf) { int flags = (entry[2]<<8)|entry[3]; printf( "\t Flags %04x ", flags ); if ( flags&0x8000 ) printf( "Mark First | "); if ( flags&0x2000 ) printf( "Mark Last | " ); if ( flags&0x4000 ) printf( "Don't Advance Glyph " ); else printf( "Advance Glyph " ); switch( flags&0xf ) { case 0 : printf( "No action\n" ); break; case 1 : printf( "Ax => xA\n" ); break; case 2 : printf( "xD => Dx\n" ); break; case 3 : printf( "AxD => DxA\n" ); break; case 4 : printf( "ABx => xAB\n" ); break; case 5 : printf( "ABx => xBA\n" ); break; case 6 : printf( "xCD => CDx\n" ); break; case 7 : printf( "xCD => DCx\n" ); break; case 8 : printf( "AxCD => CDxA\n" ); break; case 9 : printf( "AxCD => DCxA\n" ); break; case 10 : printf( "ABxD => DxAB\n" ); break; case 11 : printf( "ABxD => DxBA\n" ); break; case 12 : printf( "ABxCD => CDxAB\n" ); break; case 13 : printf( "ABxCD => CDxBA\n" ); break; case 14 : printf( "ABxCD => DCxAB\n" ); break; case 15 : printf( "ABxCD => DCxBA\n" ); break; } } static void readttfmort_indic(FILE *ttf, FILE *util, struct ttfinfo *info, int stab_len) { struct statetable *st; st = read_statetable(ttf,0,false,info); show_statetable(st, info, ttf, show_indicflags); free_statetable(st); } static void readttfmorx_indic(FILE *ttf, FILE *util, struct ttfinfo *info, int stab_len) { struct statetable *st; st = read_statetable(ttf,2,true,info); show_statetablex(st, info, ttf, show_indicflags); free_statetable(st); } static void show_contextflags(uint8 *entry,struct statetable *st,struct ttfinfo *info, FILE *ttf) { int flags = (entry[2]<<8)|entry[3]; /* the docs say this is unsigned, but that appears not to be the case */ int mark_offset = (int16) ((entry[4]<<8)|entry[5]); int cur_offset = (int16) ((entry[6]<<8)|entry[7]); int i, sub; printf( "\t Flags %04x ", flags ); if ( flags&0x8000 ) printf( "Set Mark | "); if ( flags&0x4000 ) printf( "Don't Advance Glyph\n" ); else printf( "Advance Glyph\n" ); /* I hope this is right, docs leave much to the imagination */ /* (apple does not document the "per-glyph substitution table" used by the */ /* contextual glyph substitution sub-table. */ /* My initial assumption is that there is essentially an big array with one */ /* entry for every glyph indicating what glyph it will be replaced with */ /* Since not all glyphs would be valid the tables are probably trimmed and */ /* the offsets proporting to point to it actually point to garbarge until */ /* adjusted by the appropriate glyph indeces */ /* user will need to look at the table carefully to try and guess what is */ /* meaningful and what isn't */ if ( mark_offset!=0 || cur_offset!=0 ) { printf( "!!!! Caveat !!!! I am printing out entries that look as though they might\n" ); printf( "!!!! be meaningful, but that is no guarantee. Examine them carefully to\n" ); printf( "!!!! find those sections which are actually used.\n" ); } printf( "\t Offset to substitution table for marked glyph: %d\n", mark_offset ); if ( mark_offset!=0 ) { fseek(ttf,2*(mark_offset+st->first_glyph)+st->state_start,SEEK_SET); for ( i=0; inglyphs; ++i ) { sub = getushort(ttf); if ( sub==0 || (sub>=info->glyph_cnt && sub!=0xffff) ) continue; printf( "\t Glyph %d ", st->first_glyph+i ); if ( st->first_glyph+i>=info->glyph_cnt ) printf( "!!! Bad Glyph !!! " ); else if ( info->glyph_names!=NULL ) printf( "%s ", info->glyph_names[st->first_glyph+i]); if ( sub==0xffff ) printf( "-> Deleted" ); else { printf( "-> Glyph %d ", sub ); if ( sub>=info->glyph_cnt ) printf( "!!! Bad Glyph !!! " ); else if ( info->glyph_names!=NULL ) printf( "%s", info->glyph_names[sub]); } putchar('\n'); } } printf( "\t Offset to substitution table for current glyph: %d\n", cur_offset ); if ( cur_offset!=0 ) { fseek(ttf,2*(cur_offset+st->first_glyph)+st->state_start,SEEK_SET); for ( i=0; inglyphs; ++i ) { sub = getushort(ttf); if ( sub==0 || (sub>=info->glyph_cnt && sub!=0xffff) ) continue; printf( "\t Glyph %d ", st->first_glyph+i ); if ( st->first_glyph+i>=info->glyph_cnt ) printf( "!!! Bad Glyph !!! " ); else if ( info->glyph_names!=NULL ) printf( "%s ", info->glyph_names[st->first_glyph+i]); if ( sub==0xffff ) printf( "-> Deleted" ); else { printf( "-> Glyph %d ", sub ); if ( sub>=info->glyph_cnt ) printf( "!!! Bad Glyph !!! " ); else if ( info->glyph_names!=NULL ) printf( "%s", info->glyph_names[sub]); } putchar('\n'); } } } static void readttfmort_context(FILE *ttf, FILE *util, struct ttfinfo *info, int stab_len) { struct statetable *st; st = read_statetable(ttf,2,false,info); show_statetable(st, info, ttf, show_contextflags); free_statetable(st); } static void mort_noncontextualsubs_glyph( FILE *ttf, struct ttfinfo *info ) { int gnum = getushort(ttf); printf( " Glyph %d (%s)\n", gnum, gnum>=info->glyph_cnt ? "!!!! Bad Glyph !!!!" : info->glyph_names!=NULL ? info->glyph_names[gnum]: "" ); } static void show_contextflagsx(uint8 *entry,struct statetable *st,struct ttfinfo *info, FILE *ttf) { int flags = (entry[2]<<8)|entry[3]; int mark_index = ((entry[4]<<8)|entry[5]); int cur_index = ((entry[6]<<8)|entry[7]); printf( "\t Flags %04x ", flags ); if ( flags&0x8000 ) printf( "Set Mark | "); if ( flags&0x4000 ) printf( "Don't Advance Glyph\n" ); else printf( "Advance Glyph\n" ); printf( "\t Index to substitution table for marked glyph: %d\n", mark_index ); if ( mark_index!=0xffff ) { fseek(ttf,st->state_start+st->extra_offsets[0]+4*mark_index,SEEK_SET); fseek(ttf,st->state_start+st->extra_offsets[0]+getlong(ttf),SEEK_SET); show_applelookuptable(ttf,info, mort_noncontextualsubs_glyph); } printf( "\t Offset to substitution table for current glyph: %d\n", cur_index ); if ( cur_index!=0xffff ) { fseek(ttf,st->state_start+st->extra_offsets[0]+4*cur_index,SEEK_SET); fseek(ttf,st->state_start+st->extra_offsets[0]+getlong(ttf),SEEK_SET); show_applelookuptable(ttf,info, mort_noncontextualsubs_glyph); } } static void readttfmorx_context(FILE *ttf, FILE *util, struct ttfinfo *info, int stab_len) { struct statetable *st; st = read_statetable(ttf,2,true,info); show_statetablex(st, info, ttf, show_contextflagsx); free_statetable(st); } static void show_ligflags(uint8 *entry,struct statetable *st,struct ttfinfo *info, FILE *ttf) { int flags = (entry[2]<<8)|entry[3]; uint32 val; printf( "\t Flags %04x ", flags ); if ( flags&0x8000 ) printf( "Set Component | "); if ( flags&0x4000 ) printf( "Don't Advance Glyph " ); else printf( "Advance Glyph " ); printf( "Offset=%d\n", flags&0x3fff ); if ( (flags&0x3fff)==0 ) return; fseek(ttf,st->state_start+(flags&0x3fff),SEEK_SET); do { val = getlong(ttf); printf( "\t lig action %08x %s offset=%d\n", val, (val&0x80000000)?"last (& store)": (val&0x40000000)?"store": "delete", (((int32)val)<<2)>>2 ); /* Sign extend */ /* I think we take 2 * (glyph_id-st->first_glyph + offset) + state_start */ /* we get the ?ushort? at this file address and we add it to an */ /* accumulated total. When we finally get to a store (or last) */ /* we take this accumulated total and ?look it up in the ligature */ /* table? to get a glyph index which is the ligature itself. */ /* Maybe. */ } while ( !(val&0x80000000) ); } static void readttfmort_lig(FILE *ttf, FILE *util, struct ttfinfo *info, int stab_len) { struct statetable *st; st = read_statetable(ttf,0,false,info); show_statetable(st, info, ttf, show_ligflags); free_statetable(st); } static void show_ligxflags(uint8 *entry,struct statetable *st,struct ttfinfo *info, FILE *ttf) { int flags = (entry[2]<<8)|entry[3]; int index = (entry[4]<<8)|entry[5]; uint32 val; printf( "\t Flags %04x ", flags ); if ( flags&0x8000 ) printf( "Set Component | "); if ( flags&0x2000 ) printf( "Perform | "); if ( flags&0x4000 ) printf( "Don't Advance Glyph " ); else printf( "Advance Glyph " ); if ( flags&0x2000 ) printf( "Index=%d\n", index ); else printf( "\n"); if ( (flags&0x2000)==0 ) return; fseek(ttf,st->state_start+st->extra_offsets[0]+4*index,SEEK_SET); do { val = getlong(ttf); printf( "\t lig action %08x %s offset=%d\n", val, (val&0x80000000)?"last (& store)": (val&0x40000000)?"store": "delete", (((int32)val)<<2)>>2 ); /* Sign extend */ /* I think we take 2 * (glyph_id-st->first_glyph + offset) + state_start */ /* we get the ?ushort? at this file address and we add it to an */ /* accumulated total. When we finally get to a store (or last) */ /* we take this accumulated total and ?look it up in the ligature */ /* table? to get a glyph index which is the ligature itself. */ /* Maybe. */ } while ( !(val&0x80000000) ); } static void readttfmorx_lig(FILE *ttf, FILE *util, struct ttfinfo *info, int stab_len) { struct statetable *st; st = read_statetable(ttf,1,true,info); show_statetablex(st, info, ttf, show_ligxflags); free_statetable(st); } static int32 memlong(uint8 *data,int offset) { int ch1 = data[offset], ch2 = data[offset+1], ch3 = data[offset+2], ch4 = data[offset+3]; return( (ch1<<24)|(ch2<<16)|(ch3<<8)|ch4 ); } static int memushort(uint8 *data,int offset) { int ch1 = data[offset], ch2 = data[offset+1]; return( (ch1<<8)|ch2 ); } #define MAX_LIG_COMP 16 struct statemachine { uint8 *data; int length; uint32 nClasses; uint32 classOffset, stateOffset, entryOffset, ligActOff, compOff, ligOff; uint16 *classes; uint16 lig_comp_classes[MAX_LIG_COMP]; uint16 lig_comp_glyphs[MAX_LIG_COMP]; int lcp; uint8 *states_in_use; int smax; struct ttfinfo *info; int cnt; }; static void mort_figure_ligatures(struct statemachine *sm, int lcp, int off, int32 lig_offset) { uint32 lig; int i, j, lig_glyph; if ( lcp<0 || off+3>sm->length ) return; lig = memlong(sm->data,off); off += sizeof(long); for ( i=0; iinfo->glyph_cnt; ++i ) if ( sm->classes[i]==sm->lig_comp_classes[lcp] ) { sm->lig_comp_glyphs[lcp] = i; lig_offset += memushort(sm->data,2*( ((((int32) lig)<<2)>>2) + i ) ); if ( lig&0xc0000000 ) { if ( lig_offset+1 > sm->length ) { fprintf( stderr, "Invalid ligature offset\n" ); break; } lig_glyph = memushort(sm->data,lig_offset); if ( lig_glyph>=sm->info->glyph_cnt ) { fprintf(stderr, "Attempt to make a ligature for glyph %d out of ", lig_glyph ); for ( j=lcp; jlcp; ++j ) fprintf(stderr,"%d ",sm->lig_comp_glyphs[j]); fprintf(stderr,"\n"); } else { printf( "\t\tGlyph %d (%s) is a ligature of:\n", lig_glyph, lig_glyph>=sm->info->glyph_cnt ? "!!!! Bad Glyph !!!!" : sm->info->glyph_names!=NULL ? sm->info->glyph_names[lig_glyph] : "" ); for ( j=lcp; jlcp; ++j ) printf( "\t\t\t%d (%s)\n", sm->lig_comp_glyphs[j], sm->lig_comp_glyphs[j]>=sm->info->glyph_cnt ? "!!!! Bad Glyph !!!!" : sm->info->glyph_names!=NULL ? sm->info->glyph_names[sm->lig_comp_glyphs[j]] : "" ); } } else mort_figure_ligatures(sm,lcp-1,off,lig_offset); lig_offset -= memushort(sm->data,2*( ((((int32) lig)<<2)>>2) + i ) ); } } static void follow_mort_state(struct statemachine *sm,int offset,int class) { int state = (offset-sm->stateOffset)/sm->nClasses; int class_top, class_bottom; if ( state<0 || state>=sm->smax || sm->states_in_use[state] || sm->lcp>=MAX_LIG_COMP ) return; ++ sm->cnt; if ( sm->cnt>=max_lig_nest ) { if ( sm->cnt==max_lig_nest ) fprintf( stderr, "ligature state machine too complex, giving up\n" ); return; } sm->states_in_use[state] = true; if ( class==-1 ) { class_bottom = 0; class_top = sm->nClasses; } else { class_bottom = class; class_top = class+1; } for ( class=class_bottom; classdata[offset+class]; int newState = memushort(sm->data,sm->entryOffset+4*ent); int flags = memushort(sm->data,sm->entryOffset+4*ent+2); if (( state!=0 && sm->data[sm->stateOffset+class] == ent ) || /* If we have the same entry as state 0, then presumably we are ignoring the components read so far and starting over with a new lig */ (state>1 && sm->data[sm->stateOffset+sm->nClasses+class]==ent )) /* Similarly for state 1 */ continue; if ( flags&0x8000 ) /* Set component */ sm->lig_comp_classes[sm->lcp++] = class; if ( flags&0x3fff ) { mort_figure_ligatures(sm, sm->lcp-1, flags & 0x3fff, 0); } else if ( flags&0x8000 ) follow_mort_state(sm,newState,(flags&0x4000)?class:-1); if ( flags&0x8000 ) --sm->lcp; } sm->states_in_use[state] = false; } static void morx_figure_ligatures(struct statemachine *sm, int lcp, int ligindex, int32 lig_offset) { uint32 lig; int i, j, lig_glyph; if ( lcp<0 || sm->ligActOff+4*ligindex+3>sm->length ) return; lig = memlong(sm->data,sm->ligActOff+4*ligindex); ++ligindex; for ( i=0; iinfo->glyph_cnt; ++i ) if ( sm->classes[i]==sm->lig_comp_classes[lcp] ) { sm->lig_comp_glyphs[lcp] = i; lig_offset += memushort(sm->data,sm->compOff + 2*( ((((int32) lig)<<2)>>2) + i ) ); if ( lig&0xc0000000 ) { if ( sm->ligOff+2*lig_offset+1 > sm->length ) { fprintf( stderr, "Invalid ligature offset\n" ); break; } lig_glyph = memushort(sm->data,sm->ligOff+2*lig_offset); if ( lig_glyph>=sm->info->glyph_cnt ) { fprintf(stderr, "Attempt to make a ligature for glyph %d out of " ); for ( j=lcp; jlcp; ++j ) fprintf(stderr,"%d ",sm->lig_comp_glyphs[j]); fprintf(stderr,"\n"); } else { printf( "\t\tGlyph %d (%s) is a ligature of:\n", lig_glyph, lig_glyph>=sm->info->glyph_cnt ? "!!!! Bad Glyph !!!!" : sm->info->glyph_names!=NULL ? sm->info->glyph_names[lig_glyph] : "" ); for ( j=lcp; jlcp; ++j ) printf( "\t\t\t%d (%s)\n", sm->lig_comp_glyphs[j], sm->lig_comp_glyphs[j]>=sm->info->glyph_cnt ? "!!!! Bad Glyph !!!!" : sm->info->glyph_names!=NULL ? sm->info->glyph_names[sm->lig_comp_glyphs[j]] : "" ); } } else morx_figure_ligatures(sm,lcp-1,ligindex,lig_offset); lig_offset -= memushort(sm->data,sm->compOff + 2*( ((((int32) lig)<<2)>>2) + i ) ); } } static void follow_morx_state(struct statemachine *sm,int state,int class) { int class_top, class_bottom; if ( state<0 || state>=sm->smax || sm->states_in_use[state] || sm->lcp>=MAX_LIG_COMP ) return; ++ sm->cnt; if ( sm->cnt>=max_lig_nest ) { if ( sm->cnt==max_lig_nest ) fprintf( stderr, "ligature state machine too complex, giving up\n" ); return; } sm->states_in_use[state] = true; if ( class==-1 ) { class_bottom = 0; class_top = sm->nClasses; } else { class_bottom = class; class_top = class+1; } for ( class=class_bottom; classdata, sm->stateOffset + 2*(state*sm->nClasses+class) ); int newState = memushort(sm->data,sm->entryOffset+6*ent); int flags = memushort(sm->data,sm->entryOffset+6*ent+2); int ligindex = memushort(sm->data,sm->entryOffset+6*ent+4); /* If we have the same entry as state 0, then presumably we are */ /* ignoring the components read so far and starting over with a new */ /* lig (similarly for state 1) */ if (( state!=0 && memushort(sm->data, sm->stateOffset + 2*class) == ent ) || (state>1 && memushort(sm->data, sm->stateOffset + 2*(sm->nClasses+class))==ent )) continue; if ( flags&0x8000 ) /* Set component */ sm->lig_comp_classes[sm->lcp++] = class; if ( flags&0x2000 ) { morx_figure_ligatures(sm, sm->lcp-1, ligindex, 0); } else if ( flags&0x8000 ) follow_morx_state(sm,newState,(flags&0x4000)?class:-1); if ( flags&0x8000 ) --sm->lcp; } sm->states_in_use[state] = false; } static void readttf_mortx_lig(FILE *ttf,struct ttfinfo *info,int ismorx,uint32 base,uint32 length) { uint32 here; struct statemachine sm; int first, cnt, i; memset(&sm,0,sizeof(sm)); sm.info = info; here = ftell(ttf); length -= here-base; sm.data = malloc(length); sm.length = length; if ( fread(sm.data,1,length,ttf)!=length ) { free(sm.data); fprintf( stderr, "Bad mort/morx ligature table. Not long enough\n"); return; } fseek(ttf,here,SEEK_SET); if ( ismorx ) { sm.nClasses = memlong(sm.data,0); sm.classOffset = memlong(sm.data,sizeof(long)); sm.stateOffset = memlong(sm.data,2*sizeof(long)); sm.entryOffset = memlong(sm.data,3*sizeof(long)); sm.ligActOff = memlong(sm.data,4*sizeof(long)); sm.compOff = memlong(sm.data,5*sizeof(long)); sm.ligOff = memlong(sm.data,6*sizeof(long)); fseek(ttf,here+sm.classOffset,SEEK_SET); sm.classes = info->morx_classes = malloc(info->glyph_cnt*sizeof(uint16)); for ( i=0; iglyph_cnt; ++i ) sm.classes[i] = 1; /* Out of bounds */ readttf_applelookup(ttf,info, mortclass_apply_values,mortclass_apply_value,NULL,NULL); sm.smax = length/(2*sm.nClasses); sm.states_in_use = calloc(sm.smax,sizeof(uint8)); follow_morx_state(&sm,0,-1); } else { sm.nClasses = memushort(sm.data,0); sm.classOffset = memushort(sm.data,sizeof(uint16)); sm.stateOffset = memushort(sm.data,2*sizeof(uint16)); sm.entryOffset = memushort(sm.data,3*sizeof(uint16)); sm.ligActOff = memushort(sm.data,4*sizeof(uint16)); sm.compOff = memushort(sm.data,5*sizeof(uint16)); sm.ligOff = memushort(sm.data,6*sizeof(uint16)); sm.classes = malloc(info->glyph_cnt*sizeof(uint16)); for ( i=0; iglyph_cnt; ++i ) sm.classes[i] = 1; /* Out of bounds */ first = memushort(sm.data,sm.classOffset); cnt = memushort(sm.data,sm.classOffset+sizeof(uint16)); for ( i=0; imorx_start!=0 ) { fseek(ttf,info->morx_start,SEEK_SET); printf( "\nmorx table (at %d) (Glyph metamorphosis extended)\n", info->morx_start ); ismorx = true; } else { fseek(ttf,info->mort_start,SEEK_SET); printf( "\nmort table (at %d) (Glyph metamorphosis)\n", info->mort_start ); } printf( "\t version=%g\n", getfixed(ttf)); n = getlong(ttf); printf( "\t number of chains=%d\n", n); for ( i=0; i>2)<<2; fseek(ttf,chain_start+len,SEEK_SET); } } static void showagproperties( uint16 props ) { printf( "%04x=", props ); if ( props&0x8000 ) printf( "Floater|" ); if ( props&0x4000 ) printf( "HangLeft|" ); if ( props&0x2000 ) printf( "HangRight|" ); if ( props&0x1000 ) printf( "Mirror += %d|", (((int32) props)<<20)>>28 ); if ( props&0x0080 ) printf( "AttachRight|" ); switch (props&0x1f ) { case 0: printf( "Strong L2R" ); break; case 1: printf( "Strong Hebrew" ); break; case 2: printf( "Strong Arabic" ); break; case 3: printf( "Euro Digit" ); break; case 4: printf( "Euro Num Sep" ); break; case 5: printf( "Euro Num Term" ); break; case 6: printf( "Arabic Digit" ); break; case 7: printf( "Common Num Sep" ); break; case 8: printf( "Block Sep" ); break; case 9: printf( "Segment Sep" ); break; case 10: printf( "White Space" ); break; case 11: printf( "Other Neutral" ); break; default: printf( "Undocumented Unicode 3 direction %d", props&0x1f ); break; } putchar('\n'); } static void prop_show( FILE *ttf, struct ttfinfo *info ) { showagproperties( getushort(ttf)); } static void readttfappleprop(FILE *ttf, FILE *util, struct ttfinfo *info) { fseek(ttf,info->prop_start,SEEK_SET); printf( "\nprop table (at %d) (Glyph properties)\n", info->prop_start ); printf( "\t version=%g\n", getfixed(ttf)); printf( "\t has lookup data=%d\n", getushort(ttf)); printf( "\t default properties=" ); showagproperties( getushort(ttf)); show_applelookuptable(ttf,info,prop_show); } static void lcar_show( FILE *ttf, struct ttfinfo *info ) { uint32 here; int cnt,i,off; off = getushort(ttf); here = ftell(ttf); fseek(ttf, info->lcar_start+off,SEEK_SET ); printf( " caret cnt=%d\n", cnt = getushort(ttf)); for ( i=0; ilcar_start,SEEK_SET); printf( "\nlcar table (at %d) (Ligature carets)\n", info->lcar_start ); printf( "\t version=%g\n", getfixed(ttf)); printf( "\t data are points=%d\n", getushort(ttf)); show_applelookuptable(ttf,info,lcar_show); } static void opbd_show( FILE *ttf, struct ttfinfo *info ) { uint32 here; int off; off = getushort(ttf); here = ftell(ttf); fseek(ttf, info->opbd_start+off,SEEK_SET ); printf( " optical left=%d\n", (short) getushort(ttf)); printf( " optical top=%d\n", (short) getushort(ttf)); printf( " optical right=%d\n", (short) getushort(ttf)); printf( " optical bottom=%d\n", (short) getushort(ttf)); fseek(ttf,here,SEEK_SET); } static void readttfappleopbd(FILE *ttf, FILE *util, struct ttfinfo *info) { fseek(ttf,info->opbd_start,SEEK_SET); printf( "\nopbd table (at %d) (Optical Bounds)\n", info->opbd_start ); printf( "\t version=%g\n", getfixed(ttf)); printf( "\t data are points=%d\n", getushort(ttf)); show_applelookuptable(ttf,info,opbd_show); } static void readttfapplefvar(FILE *ttf, FILE *util, struct ttfinfo *info) { int dataoff, countsizepairs, axiscount, instancecount, instancesize, nameid; uint32 tag; char *name; int i,j; fseek(ttf,info->fvar_start,SEEK_SET); printf( "\nfvar table (at %d) (Font Variations)\n", info->fvar_start ); printf( "\t version=%g\n", getfixed(ttf)); printf( "\t offset to data=%d\n", dataoff = getushort(ttf)); printf( "\t # size pairs=%d\n", countsizepairs = getushort(ttf)); printf( "\t Axis count=%d\n", axiscount = getushort(ttf)); info->fvar_axiscount = axiscount; printf( "\t Axis size=%d\n", getushort(ttf)); printf( "\t Instance count=%d\n", instancecount = getushort(ttf)); printf( "\t Instance size=%d\n", instancesize = getushort(ttf)); for ( i=0; i>24, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff); printf( "\t minValue=%g\n", getfixed(ttf)); printf( "\t defaultValue=%g\n", getfixed(ttf)); printf( "\t maxValue=%g\n", getfixed(ttf)); printf( "\t flags=%x\n", getushort(ttf)); nameid = getushort(ttf); name = getttfname(util,info,nameid); printf( "\t nameid=%d (%s)\n", nameid, name==NULL ? "Not Found" : name ); } for ( i=0; igvar_start,SEEK_SET); printf( "\ngvar table (at %d) (Glyph Variations)\n", info->gvar_start ); printf( "\t version=%g\n", getfixed(ttf)); printf( "\t Axis count=%d\n", axiscount = getushort(ttf)); if ( axiscount!=info->fvar_axiscount ) fprintf( stderr, "The axis count in the gvar table differs from that in the fvar table.\n 'gvar' axes=%d, 'fvar' axes=%d\n", axiscount, info->fvar_axiscount ); printf( "\t global coord count=%d\n", gcc = getushort(ttf)); printf( "\t offset to coord=%d\n", offset2Coord = getlong(ttf)); printf( "\t glyph count=%d\n", glyphCount = getushort(ttf)); printf( "\t flags=%x\n", flags = getushort(ttf)); printf( "\t offset to data=%x\n", offset2Data = getlong(ttf)); offsets = malloc(glyphCount*sizeof(uint32)); if ( flags&1 ) { for ( i=0; igvar_start; } else { for ( i=0; igvar_start; } for ( i=0; iglyph_names!=NULL? info->glyph_names[i]: "" ); tupleCount = getushort(ttf); offset = getushort(ttf); printf( "\t Tuple count=%x, (count=%d) tuples %sshare points\n", tupleCount, tupleCount&0xfff, (tupleCount&0x8000)? "" : "do not " ); printf( "\t Offset=%d\n", offset ); for ( j=0; j<(tupleCount&0xfff); ++j ) { printf( "\t Tuple %d\n", j ); printf( "\t Size %d\n", getushort(ttf) ); index = getushort(ttf); printf( "\t Index %d%s%s%s\n", index&0xfff, index&0x8000 ? ", Embedded tuple" : "", index&0x4000 ? ", Intermediate tuple" : "", index&0x2000 ? ", Private points" : "" ); if ( index&0x8000 ) { printf( "\t Coords[%g", ((short) getushort(ttf))/16384.0 ); for ( k=1; kgvar_start+offset2Coord+(index&0xfff)*axiscount*2,SEEK_SET); printf( "\t Global Coords[%g", ((short) getushort(ttf))/16384.0 ); for ( k=1; kgasp_start,SEEK_SET); printf( "\ngasp table (at %d) (grid fitting and scan conversion table)\n", info->gasp_start ); printf( "\t version=%d\n", getushort(ttf)); printf( "\t Number of gasp entries=%d\n", n = getushort(ttf)); for ( i=0; i= %d and <%d:\t", last, ppem ); else printf( "\t All sizes >= %d: \t", last ); last = ppem; if ( flags==0 ) printf( "Nothing (No gridfitting, no anti-aliasing)\n" ); else if ( flags==1 ) printf( "Grid Fit (no anti-aliasing)\n" ); else if ( flags==2 ) printf( "Anti-alias (no grid fitting)\n" ); else printf( "Both Grid Fitting and Anti-Aliasing\n" ); } } #if 0 static void readtablebytes(FILE *ttf, int start, int len, char *string) { int i; if ( start==0 ) return; fseek(ttf,start,SEEK_SET); printf( "\n%s table (at %d for %d bytes)\n\t", string, start, len ); for ( i=0; i=0xb0 && ch<=0xb7 ) { /* PUSHBn */ n = (ch-0xb0)+1; for ( j=0; j=0xb8 && ch<=0xbf ) { n = (ch-0xb8)+1; for ( j=0; j>4); pt = addnibble(pt,ch&0xf); } while ( pt[-1]!='\0' ); *dval = strtod(buffer,NULL); return( 2 ); } else if ( ch>=32 && ch<=246 ) { *_ival = ch-139; return( 1 ); } else if ( ch>=247 && ch<=250 ) { *_ival = ((ch-247)<<8) + getc(ttf)+108; return( 1 ); } else if ( ch>=251 && ch<=254 ) { *_ival = -((ch-251)<<8) - getc(ttf)-108; return( 1 ); } else if ( ch==28 ) { ival = getc(ttf)<<8; *_ival = (short) (ival | getc(ttf)); return( 1 ); } else if ( ch==29 ) { ival = getc(ttf)<<24; ival = ival | getc(ttf)<<16; ival = ival | getc(ttf)<<8; *_ival = (int) (ival | getc(ttf)); return( 1 ); } printf( "Unexpected value in dictionary %d\n", ch ); *_ival = 0; return( 0 ); } struct pschars { int cnt, next; char **keys; uint8 **values; int *lens; int bias; }; struct topdicts { int32 cff_start; char *fontname; /* From Name Index */ int version; int notice; /* SID */ int copyright; /* SID */ int fullname; /* SID */ int familyname; /* SID */ int weight; /* SID */ int isfixedpitch; double italicangle; double underlinepos; double underlinewidth; int painttype; int charstringtype; double fontmatrix[6]; int uniqueid; double fontbb[4]; double strokewidth; int xuid[20]; int charsetoff; /* from start of file */ int encodingoff; /* from start of file */ int charstringsoff; /* from start of file */ int private_size; int private_offset; /* from start of file */ int synthetic_base; /* font index */ int postscript_code; /* SID */ /* synthetic fonts only */ int basefontname; /* SID */ int basefontblend[16]; /* delta */ /* CID fonts only (what we expect to get) */ int ros_registry; /* SID */ int ros_ordering; /* SID */ int ros_supplement; int cidfontversion; int cidfontrevision; int cidfonttype; int cidcount; int uidbase; int fdarrayoff; /* from start of file */ int fdselectoff; /* from start of file */ int sid_fontname; /* SID */ /* Private stuff */ double bluevalues[14]; double otherblues[10]; double familyblues[14]; double familyotherblues[10]; double bluescale; double blueshift; double bluefuzz; int stdhw; int stdvw; double stemsnaph[10]; double stemsnapv[10]; int forcebold; int languagegroup; double expansionfactor; int initialRandomSeed; int subrsoff; /* from start of this private table */ int defaultwidthx; int nominalwidthx; struct pschars glyphs; struct pschars local_subrs; uint16 *charset; }; static void ShowCharString(uint8 *str,int len,int type) { int v; int val; /* most things are the same about type1 and type2 strings. Type2 just has */ /* extra operators (and gets rid of seac). The 5 byte number sequence is */ /* different though... */ do { if ( (v = *str++)>=32 ) { if ( v<=246) { val = v - 139; } else if ( v<=250 ) { val = (v-247)*256 + *str++ + 108; --len; } else if ( v<=254 ) { val = -(v-251)*256 - *str++ - 108; --len; } else { val = (*str<<24) | (str[1]<<16) | (str[2]<<8) | str[3]; str += 4; len -= 4; } if ( v==0xff && type==2 ) printf( "%g ", val/65536. ); else printf( "%d ", val ); } else if ( v==28 ) { val = (short) ((str[0]<<8) | str[1]); str += 2; len -= 2; printf( "%d ", val ); } else if ( v==12 ) { v = *str++; --len; switch ( v ) { case 3: printf( "and " ); break; case 4: printf( "or " ); break; case 5: printf( "not " ); break; case 9: printf( "abs " ); break; case 10: printf( "add " ); break; case 11: printf( "sub " ); break; case 12: printf( "div " ); break; case 14: printf( "neg " ); break; case 15: printf( "eq " ); break; case 18: printf( "drop " ); break; case 20: printf( "put " ); break; case 21: printf( "get " ); break; case 22: printf( "ifelse " ); break; case 23: printf( "random " ); break; case 24: printf( "mul " ); break; case 26: printf( "sqrt " ); break; case 27: printf( "dup " ); break; case 28: printf( "exch " ); break; case 29: printf( "index " ); break; case 30: printf( "roll " ); break; case 34: printf( "hflex " ); break; case 35: printf( "flex " ); break; case 36: printf( "hflex1 " ); break; case 37: printf( "flex1 " ); break; /* Type 1 codes */ case 0: printf( "dotsection " ); break; case 1: printf( "vstem3 " ); break; case 2: printf( "hstem3 " ); break; case 6: printf( "seac " ); break; case 7: printf( "sbw " ); break; case 16: printf( "callothersubr " ); break; case 17: printf( "pop " ); break; case 33: printf( "setcurrentpoint " ); break; /* End obselete codes */ default: printf( "???-12-%d-??? ", v ); break; } } else switch ( v ) { case 1: printf( "hstem " ); break; case 3: printf( "vstem " ); break; case 4: printf( "vmoveto " ); break; case 5: printf( "rlineto " ); break; case 6: printf( "hlineto " ); break; case 7: printf( "vlineto " ); break; case 8: printf( "rrcurveto " ); break; case 10: printf( "callsubr " ); break; case 11: printf( "return " ); break; case 14: printf( "endchar " ); break; case 18: printf( "hstemhm " ); break; case 19: printf( "hintmask " ); break; case 20: printf( "cntrmask " ); break; case 21: printf( "rmoveto " ); break; case 22: printf( "hmoveto " ); break; case 23: printf( "vstemhm " ); break; case 24: printf( "rcurveline " ); break; case 25: printf( "rlinecurve " ); break; case 26: printf( "vvcurveto " ); break; case 27: printf( "hhcurveto " ); break; case 29: printf( "callgsubr " ); break; case 30: printf( "vhcurveto " ); break; case 31: printf( "hvcurveto " ); break; /* Type 1 codes */ case 9: printf( "closepath " ); break; case 13: printf( "hsbw " ); break; /* End obselete codes */ default: printf( "???-%d-??? ", v ); } --len; if ( v==19 || v==20 ) { /* I need to skip as many bits (rounded into bytes) as there are */ /* hints. But figuring out the hint count is impossible in a subr */ /* and difficult in a glyph that calls subrs */ /* .... So we pretend the hintmask fits into one byte */ printf( "0x%02x ", *str++ ); --len; } } while ( len>0 ); printf( "\n" ); } static void readcffsubrs(FILE *ttf,struct topdicts *dict,struct pschars *subs, int type, char *label) { uint16 count = getushort(ttf); int offsize; uint32 *offsets; int i,j; static char *text[] = { "char strings", "subrs", NULL }; uint8 *temp; printf( "\nThere are %d %s in the index associated with %s\n", count, text[type], label ); memset(subs,'\0',sizeof(struct pschars)); if ( count==0 ) return; subs->cnt = count; /*subs->lens = malloc(count*sizeof(int));*/ /*subs->values = malloc(count*sizeof(uint8 *));*/ subs->bias = dict->charstringtype==1 ? 0 : count<1240 ? 107 : count<33900 ? 1131 : 32768; if ( type==1 ) printf( " Bias = %d\n", subs->bias ); offsets = malloc((count+1)*sizeof(uint32)); offsize = getc(ttf); printf( " Subr Index Offset Size: %d\n Offsets: ", offsize ); for ( i=0; i<=count; ++i ) { offsets[i] = getoffset(ttf,offsize); if ( i==0 && offsets[0]!=1 ) fprintf( stderr, "!!! Initial offset must be 1 in %s in %s\n", text[type], label); else if ( i!=0 && offsets[i]lens[i] = offsets[i+1]-offsets[i];*/ /*subs->values[i] = malloc(offsets[i+1]-offsets[i]+1);*/ temp = malloc(offsets[i+1]-offsets[i]+1); for ( j=0; jcharstringtype); free(temp); } free(offsets); } static struct topdicts *readcfftopdict(FILE *ttf, char *fontname, int len) { struct topdicts *td = calloc(1,sizeof(struct topdicts)); long base = ftell(ttf); int ival, oval, sp, ret, i; double stack[50]; td->fontname = fontname; td->underlinepos = -100; td->underlinewidth = 50; td->charstringtype = 2; td->fontmatrix[0] = td->fontmatrix[3] = .001; td->cidcount = 8720; td->notice = td->copyright = td->fullname = td->familyname = td->weight = -1; td->postscript_code = td->basefontname = -1; td->synthetic_base = -1; td->ros_registry = td->ros_ordering = td->fdarrayoff = td->fdselectoff = -1; td->sid_fontname = -1; if ( fontname!=NULL ) printf( " Top Dict for %s\n", fontname ); while ( ftell(ttf)version = stack[sp-1]; break; case 1: printf( " notice\n" ); td->notice = stack[sp-1]; break; case (12<<8)+0: printf( " copyright\n" ); td->copyright = stack[sp-1]; break; case 2: printf( " fullname\n" ); td->fullname = stack[sp-1]; break; case 3: printf( " familyname\n" ); td->familyname = stack[sp-1]; break; case 4: printf( " weight\n" ); td->weight = stack[sp-1]; break; case (12<<8)+1: printf( " isfixedpitch\n" ); td->isfixedpitch = stack[sp-1]; break; case (12<<8)+2: printf( " italicangle\n" ); td->italicangle = stack[sp-1]; break; case (12<<8)+3: printf( " underlinepos\n" ); td->underlinepos = stack[sp-1]; break; case (12<<8)+4: printf( " underlinewidth\n" ); td->underlinewidth = stack[sp-1]; break; case (12<<8)+5: printf( " painttype\n" ); td->painttype = stack[sp-1]; break; case (12<<8)+6: printf( " charstringtype\n" ); td->charstringtype = stack[sp-1]; break; case (12<<8)+7: printf( " fontmatrix\n" ); memcpy(td->fontmatrix,stack,(sp>=6?6:sp)*sizeof(double)); break; case 13: printf( " uniqueid\n" ); td->uniqueid = stack[sp-1]; break; case 5: printf( " fontbb\n" ); memcpy(td->fontbb,stack,(sp>=4?4:sp)*sizeof(double)); break; case (12<<8)+8: printf( " strokewidth\n" ); td->strokewidth = stack[sp-1]; break; case 14: printf( " xuid\n" ); for ( i=0; ixuid[i] = stack[i]; break; case 15: printf( " charsetoff\n" ); td->charsetoff = stack[sp-1]; break; case 16: printf( " encodingoff\n" ); td->encodingoff = stack[sp-1]; break; case 17: printf( " charstringsoff\n" ); td->charstringsoff = stack[sp-1]; break; case 18: printf( " private\n" ); td->private_size = stack[0]; td->private_offset = stack[1]; break; case (12<<8)+20: printf( " synthetic_base\n" ); td->synthetic_base = stack[sp-1]; break; case (12<<8)+21: printf( " postscript_code\n" ); td->postscript_code = stack[sp-1]; break; case (12<<8)+22: printf( " basefontname\n" ); td->basefontname = stack[sp-1]; break; case (12<<8)+23: printf( " basefontblend\n" ); for ( i=0; ibasefontblend[i] = stack[i]; break; case (12<<8)+30: printf( " ROS\n" ); td->ros_registry = stack[0]; td->ros_ordering = stack[1]; td->ros_supplement = stack[2]; break; case (12<<8)+31: printf( " CIDFontVersion\n" ); td->cidfontversion = stack[sp-1]; break; case (12<<8)+32: printf( " CIDFontRevision\n" ); td->cidfontrevision = stack[sp-1]; break; case (12<<8)+33: printf( " CIDFontType\n" ); td->cidfonttype = stack[sp-1]; break; case (12<<8)+34: printf( " CIDCount\n" ); td->cidcount = stack[sp-1]; break; case (12<<8)+35: printf( " UIDBase\n" ); td->uidbase = stack[sp-1]; break; case (12<<8)+36: printf( " FDArray Off\n" ); td->fdarrayoff = stack[sp-1]; break; case (12<<8)+37: printf( " FDSelect Off\n" ); td->fdselectoff = stack[sp-1]; break; case (12<<8)+38: printf( " Fontname\n" ); td->sid_fontname = stack[sp-1]; break; default: fprintf(stderr,"Unknown operator in %s: %x\n", fontname, oval ); break; } } return( td ); } static void dumpsid(char *label, int sid, char **strings, int smax ) { if ( sid==-1 ) return; if ( sid> Bad SID (max=%d) <<\n", label, sid, smax ); } static char *getsid(int sid, char **strings,int smax ) { if ( sid==-1 ) return(NULL); if ( sid> Bad SID <<")); } static void readcffprivate(FILE *ttf, struct topdicts *td, char **strings, int smax) { int ival, oval, sp, ret, i; double stack[50]; int32 end = td->cff_start+td->private_offset+td->private_size; char *name; fseek(ttf,td->cff_start+td->private_offset,SEEK_SET); td->subrsoff = -1; td->expansionfactor = .06; td->bluefuzz = 1; td->blueshift = 7; td->bluescale = .039625; name = td->fontname?td->fontname: td->sid_fontname?getsid(td->sid_fontname,strings,smax):""; printf( "\n Private Dict for %s\n", name ); while ( ftell(ttf)bluevalues[i] = stack[i]; if ( i!=0 ) td->bluevalues[i] += td->bluevalues[i-1]; } break; case 7: printf( " OtherBlues\n" ); for ( i=0; iotherblues[i] = stack[i]; if ( i!=0 ) td->otherblues[i] += td->otherblues[i-1]; } break; case 8: printf( " FamilyBlues\n" ); for ( i=0; ifamilyblues[i] = stack[i]; if ( i!=0 ) td->familyblues[i] += td->familyblues[i-1]; } break; case 9: printf( " FamilyOtherBlues\n" ); for ( i=0; ifamilyotherblues[i] = stack[i]; if ( i!=0 ) td->familyotherblues[i] += td->familyotherblues[i-1]; } break; case (12<<8)+9: printf( " BlueScale\n" ); td->bluescale = stack[sp-1]; break; case (12<<8)+10: printf( " BlueShift\n" ); td->blueshift = stack[sp-1]; break; case (12<<8)+11: printf( " BlueFuzz\n" ); td->bluefuzz = stack[sp-1]; break; case 10: printf( " StdHW\n" ); td->stdhw = stack[sp-1]; break; case 11: printf( " StdVW\n" ); td->stdvw = stack[sp-1]; break; case (12<<8)+12: printf( " StemSnapH\n" ); for ( i=0; istemsnaph[i] = stack[i]; if ( i!=0 ) td->stemsnaph[i] += td->stemsnaph[i-1]; } break; case (12<<8)+13: printf( " StemSnapV\n" ); for ( i=0; istemsnapv[i] = stack[i]; if ( i!=0 ) td->stemsnapv[i] += td->stemsnapv[i-1]; } break; case (12<<8)+14: printf( " ForceBold\n" ); td->forcebold = stack[sp-1]; break; case (12<<8)+17: printf( " LanguageGroup\n" ); td->languagegroup = stack[sp-1]; break; case (12<<8)+18: printf( " ExpansionFactor\n" ); td->expansionfactor = stack[sp-1]; break; case (12<<8)+19: printf( " InitialRandomSeed\n" ); td->initialRandomSeed = stack[sp-1]; break; case 19: printf( " Subrs\n" ); td->subrsoff = stack[sp-1]; break; case 20: printf( " DefaultWidthX\n" ); td->defaultwidthx = stack[sp-1]; break; case 21: printf( " NominalWidthX\n" ); td->nominalwidthx = stack[sp-1]; break; default: fprintf(stderr,"Unknown operator in %s: %x\n", td->fontname, oval ); break; } } if ( td->subrsoff!=-1 ) { fseek(ttf,td->cff_start+td->private_offset+td->subrsoff,SEEK_SET); readcffsubrs(ttf,td,&td->local_subrs, 1, name ); } } static struct topdicts **readcfftopdicts(FILE *ttf, char **fontnames, int cff_start) { uint16 count = getushort(ttf); int offsize; uint32 *offsets; struct topdicts **dicts; int i; if ( fontnames!=NULL ) printf( "There %s %d top dictionar%s in this cff\n", count==1?"is":"are",count, count==1?"y":"ies" ); else printf( "There %s %d subdictionary dictionar%s in this font\n", count==1?"is":"are",count, count==1?"y":"ies" ); if ( count==0 ) return( NULL ); offsets = malloc((count+1)*sizeof(uint32)); offsize = getc(ttf); printf( " %s Dict Index Offset Size: %d\n Offsets: ", fontnames!=NULL?"Top":"Sub", offsize ); for ( i=0; i<=count; ++i ) { offsets[i] = getoffset(ttf,offsize); if ( i==0 && offsets[0]!=1 ) fprintf(stderr, "!! Initial offset must be one in Top Dict Index\n" ); printf( "%d ", offsets[i]); } putchar('\n'); dicts = malloc((count+1)*sizeof(struct topdicts *)); for ( i=0; icff_start = cff_start; } dicts[i] = NULL; free(offsets); return( dicts ); } static void showdict(struct topdicts *dict, char **strings, int smax) { int i, j; if ( dict->sid_fontname==-1 ) printf( "\nDump of top dictionary for %s\n", dict->fontname); else dumpsid("\nDump of sub dictionary ", dict->sid_fontname, strings, smax ); dumpsid(" Version=", dict->version, strings, smax ); dumpsid(" Notice=", dict->notice, strings, smax ); dumpsid(" copyright=", dict->copyright, strings, smax ); dumpsid(" fullname=", dict->fullname, strings, smax ); dumpsid(" familyname=", dict->familyname, strings, smax ); dumpsid(" weight=", dict->weight, strings, smax ); printf( " fixedpitch=%d\n", dict->isfixedpitch); printf( " ItalicAngle=%g\n", dict->italicangle); printf( " underlinepos=%g\n", dict->underlinepos); printf( " underlinewidth=%g\n", dict->underlinewidth); printf( " painttype=%d\n", dict->painttype); printf( " charstringtype=%d\n", dict->charstringtype); printf( " fontmatrix=[%g %g %g %g %g %g]\n", dict->fontmatrix[0], dict->fontmatrix[1], dict->fontmatrix[2], dict->fontmatrix[3], dict->fontmatrix[4], dict->fontmatrix[5]); printf( " uniqueid=%d\n", dict->uniqueid); printf( " fontbb=[%g %g %g %g]\n", dict->fontbb[0], dict->fontbb[1], dict->fontbb[2], dict->fontbb[3]); printf( " strokewidth=%g\n", dict->strokewidth); for ( i=19; i>=0; --i ) if ( dict->xuid[i]!=0 ) break; if ( i>=0 ) { printf( " XUID=[" ); for ( j=0; j<=i; ++j ) printf("%d ", dict->xuid[j]); printf("]\n"); } printf( " charsetoff=%d\n", dict->charsetoff); printf( " encodingoff=%d\n", dict->encodingoff); printf( " charstringsoff=%d\n", dict->charstringsoff); printf( " private size=%d off=%d\n", dict->private_size, dict->private_offset); if ( dict->synthetic_base!=-1 ) printf( " synthetic_base=%d\n", dict->synthetic_base ); dumpsid(" postscript_code=", dict->postscript_code, strings, smax ); dumpsid(" basefontname=", dict->basefontname, strings, smax ); for ( i=15; i>=0; --i ) if ( dict->basefontblend[i]!=0 ) break; if ( i>=0 ) { printf( " basefontblend=[" ); for ( j=0; j<=i; ++j ) printf("%d ", dict->basefontblend[i]); printf("]\n"); } if ( dict->ros_registry!=-1 ) { dumpsid(" ros (Registry)=", dict->ros_registry, strings, smax ); dumpsid(" (Ordering)=", dict->ros_ordering, strings, smax ); printf(" (Supplement)=%d\n", dict->ros_supplement ); printf( " cidfontversion=%d\n", dict->cidfontversion); printf( " cidfontrevision=%d\n", dict->cidfontrevision); printf( " cidfonttype=%d\n", dict->cidfonttype); printf( " cidcount=%d\n", dict->cidcount); printf( " uidbase=%d\n", dict->uidbase); printf( " FDArray off=%d\n", dict->fdarrayoff ); } if ( dict->fdselectoff!=-1 ) printf( " FDSelect off=%d\n", dict->fdselectoff ); printf( "\n" ); } /* The real encoding is done in the cmap ttf table, not sure why we bother here */ static void readcffenc(FILE *ttf,struct topdicts *dict,char **strings,int smax) { int format, cnt, i; if ( dict->encodingoff==0 ) { printf( "\nAdobe Standard Encoding\n" ); return; } else if ( dict->encodingoff==1 ) { printf( "\nExpert Encoding\n" ); return; } fseek(ttf,dict->cff_start+dict->encodingoff,SEEK_SET); format = getc(ttf); printf( "\nCFF Encoding format=%x\n", format ); if ( (format&0x7f)==0 ) { cnt = getc(ttf); printf( " Enc cnt=%d\n Enc: ", cnt ); for ( i=0; i ", i, getc(ttf)); dumpsid("",getushort(ttf),strings, smax); } } } static void readcffset(FILE *ttf,struct topdicts *dict,char **strings,int smax, struct ttfinfo *info) { int len = dict->glyphs.cnt; int i; int format, cnt, j, first; if ( dict->charsetoff==0 ) { /* ISO Adobe charset */ printf( "\nISOAdobe charset\n" ); dict->charset = malloc(len*sizeof(uint16)); for ( i=0; icharset[i] = i; } else if ( dict->charsetoff==1 ) { printf( "\nExpert charset\n" ); /* Expert charset */ dict->charset = malloc((len<162?162:len)*sizeof(uint16)); dict->charset[0] = 0; /* .notdef */ dict->charset[1] = 1; for ( i=2; icharset[i] = i+227; dict->charset[12] = 13; dict->charset[13] = 14; dict->charset[14] = 15; dict->charset[15] = 99; for ( i=16; icharset[i] = i+223; dict->charset[25] = 27; dict->charset[26] = 28; for ( i=27; icharset[i] = i+222; dict->charset[44] = 109; dict->charset[45] = 110; for ( i=46; icharset[i] = i+221; dict->charset[96] = 158; dict->charset[97] = 155; dict->charset[98] = 163; for ( i=99; icharset[i] = i+220; dict->charset[107] = 150; dict->charset[108] = 164; dict->charset[109] = 169; for ( i=110; icharset[i] = i+217; } else if ( dict->charsetoff==2 ) { printf( "\nExpert subset charset\n" ); /* Expert subset charset */ dict->charset = malloc((len<130?130:len)*sizeof(uint16)); dict->charset[0] = 0; /* .notdef */ dict->charset[1] = 1; for ( i=2; icharset[i] = i+227; dict->charset[12] = 13; dict->charset[13] = 14; dict->charset[14] = 15; dict->charset[15] = 99; for ( i=16; icharset[i] = i+223; dict->charset[25] = 27; dict->charset[26] = 28; for ( i=27; icharset[i] = i+222; dict->charset[44] = 109; dict->charset[45] = 110; for ( i=46; icharset[i] = i+221; dict->charset[51] = 300; dict->charset[52] = 301; dict->charset[53] = 302; dict->charset[54] = 305; dict->charset[55] = 314; dict->charset[56] = 315; dict->charset[57] = 158; dict->charset[58] = 155; dict->charset[59] = 163; for ( i=60; icharset[i] = i+260; dict->charset[67] = 150; dict->charset[68] = 164; dict->charset[69] = 169; for ( i=110; icharset[i] = i+217; } else { dict->charset = malloc(len*sizeof(uint16)); dict->charset[0] = 0; /* .notdef */ fseek(ttf,dict->cff_start+dict->charsetoff,SEEK_SET); format = getc(ttf); printf( "\nCharset format=%d\n", format ); if ( format==0 ) { for ( i=1; icharset[i] = getushort(ttf); } else if ( format==1 ) { for ( i = 1; icharset[i++] = getushort(ttf); cnt = getc(ttf); for ( j=0; jcharset[i++] = ++first; } } else if ( format==2 ) { for ( i = 1; icharset[i++] = getushort(ttf); cnt = getushort(ttf); for ( j=0; jcharset[i++] = ++first; } } } while ( icharset[i++] = 0; printf( " Which means...\n" ); if ( dict->ros_registry==-1 ) { info->glyph_names = calloc(len,sizeof(char *)); for ( i=0; icharset[i], strings, smax); info->glyph_names[i] = getsid(dict->charset[i], strings,smax); } } else for ( i=0; i CID %d\n", i, dict->charset[i]); } static int readcff(FILE *ttf,FILE *util, struct ttfinfo *info) { int offsize; int hdrsize; char **fontnames; char **strings; struct topdicts **dicts, **subdicts; int i, j, smax; struct pschars gsubs; fseek(ttf,info->cff_start,SEEK_SET); printf( "\nPostscript CFF table (at %d for %d bytes)\n", info->cff_start, info->cff_length); printf( "\tMajor Version: %d\n", getc(ttf)); printf( "\tMinor Version: %d\n", getc(ttf)); printf( "\tTable Header size: %d\n", hdrsize = getc(ttf)); printf( "\tOffset size: %d\n", offsize = getc(ttf)); /* Er is this ever used? */ if ( hdrsize!=4 ) fseek(ttf,info->cff_start+hdrsize,SEEK_SET); fontnames = readcfffontnames(ttf,0); dicts = readcfftopdicts(ttf,fontnames,info->cff_start); /* String index is just the same as fontname index */ strings = readcfffontnames(ttf,1); for ( smax=0; strings[smax]!=NULL; ++smax ); for ( i=0; fontnames[i]!=NULL; ++i ) showdict(dicts[i],strings,smax); readcffsubrs(ttf,dicts[0],&gsubs, 1, "Global" ); for ( i=0; fontnames[i]!=NULL; ++i ) { if ( dicts[i]->charstringsoff!=-1 ) { fseek(ttf,info->cff_start+dicts[i]->charstringsoff,SEEK_SET); readcffsubrs(ttf,dicts[i],&dicts[i]->glyphs, 0, fontnames[i]); } if ( dicts[i]->private_offset!=-1 ) readcffprivate(ttf,dicts[i],strings,smax); if ( dicts[i]->charsetoff!=-1 ) readcffset(ttf,dicts[i],strings,smax,info); if ( dicts[i]->ros_registry==-1 ) readcffenc(ttf,dicts[i],strings,smax); if ( dicts[i]->fdarrayoff!=-1 ) { fseek(ttf,info->cff_start+dicts[i]->fdarrayoff,SEEK_SET); subdicts = readcfftopdicts(ttf,NULL,info->cff_start); for ( j=0; subdicts[j]!=NULL; ++j ) { showdict(subdicts[j],strings,smax); if ( subdicts[j]->private_offset!=-1 ) readcffprivate(ttf,subdicts[j],strings,smax); } } } return( 1 ); } static void readttfBigGlyphMetrics(FILE *ttf,char *indent) { printf( "%sBitmap rows=%d\n", indent, getc(ttf)); printf( "%sBitmap columns=%d\n", indent, getc(ttf)); printf( "%shoriBearingX=%d\n", indent, (signed char) getc(ttf)); printf( "%shoriBearingY=%d\n", indent, (signed char) getc(ttf)); printf( "%shoriAdvance=%d\n", indent, getc(ttf)); printf( "%svertBearingX=%d\n", indent, (signed char) getc(ttf)); printf( "%svertBearingY=%d\n", indent, (signed char) getc(ttf)); printf( "%svertAdvance=%d\n", indent, getc(ttf)); } static void ShowGlyph(FILE *ttf,long offset,long len,int imageFormat, struct ttfinfo *info) { int h,w,sbX,sbY,advance; int i,j,k,ch; long here; if ( imageFormat!=1 && imageFormat!=2 ) return; here = ftell(ttf); fseek(ttf,info->bitmapdata_start+offset,SEEK_SET); h = getc(ttf); w = getc(ttf); sbX = (signed char) getc(ttf); sbY = (signed char) getc(ttf); advance = getc(ttf); printf( "\t\theight=%d width=%d sbX=%d sbY=%d advance=%d %s aligned\n", h,w,sbX,sbY,advance,imageFormat==1?"Byte":"Bit"); len -= 5; if ( imageFormat==1 ) { /* Byte aligned data */ for ( i=0; i>k)) putchar('*'); else putchar('.'); } } putchar('\n'); } } else { k=8; for ( i=0; i=8 ) { ch = getc(ttf); --len; k=0; } if ( ch&(0x80>>k)) putchar('*'); else putchar('.'); } putchar('\n'); } } if ( len!=0 ) printf("!!!\tLength field wrong. %d left\n", len ); fseek(ttf,here,SEEK_SET); } static void readttfIndexSubTab(FILE *ttf,long offset, int first, int last, struct ttfinfo *info) { int i, indexFormat, imageFormat, bdatOff; long curstart, nextstart; fseek(ttf,offset,SEEK_SET); printf( "\t index Format=%d ", indexFormat=getushort(ttf)); if ( indexFormat==1 || indexFormat==3 ) printf( "Proportional\n" ); else if ( indexFormat==2 ) printf( "Monospace\n" ); else printf( "Unknown\n" ); printf( "\t image Format=%d\n", imageFormat=getushort(ttf)); printf( "\t Offset in bitmap data table=%d\n", bdatOff=getlong(ttf)); if ( indexFormat==1 || indexFormat==3 ) { curstart = (indexFormat==1?getlong(ttf):getushort(ttf)); for ( i=first; i<=last; ++i ) { nextstart = (indexFormat==1?getlong(ttf):getushort(ttf)); if ( info->glyph_names==NULL ) printf( "\t Glyph %d starts at %5d length=%d\n", i, curstart, nextstart-curstart ); else if ( iglyph_cnt && info->glyph_names[i]!=NULL ) printf( "\t Glyph %d (%10s) starts at %5d length=%d\n", i, info->glyph_names[i], curstart, nextstart-curstart ); else printf( "\t Glyph %d ( ) starts at %5d length=%d\n", i, curstart, nextstart-curstart ); ShowGlyph(ttf,bdatOff+curstart,nextstart-curstart,imageFormat,info); curstart = nextstart; } } else if ( indexFormat==2 ) { printf( "\t Bitmap Image Size=%d\n", getlong(ttf)); printf( "\t big Metrics for any glyph\n" ); readttfBigGlyphMetrics(ttf,"\t "); } } static void readttfIndexSizeSubTab(FILE *ttf,long offset, long size, long num, struct ttfinfo *info) { int i, first, last; long here, moreoff; fseek(ttf,offset,SEEK_SET); for ( i=0; ibitmapscale_start,SEEK_SET); printf( "\nBitmap scaling data (at %d)\n", info->bitmapscale_start); printf( "\tVersion: 0x%08x\n", getlong(ttf)); printf( "\tnum Sizes: %d\n", cnt = getlong(ttf)); for ( i=0; ibitmaploc_start,SEEK_SET); printf( "\nBitmap location data (at %d for %d bytes)\n", info->bitmaploc_start, info->bitmaploc_length); printf( "\tVersion: 0x%08\n", getlong(ttf)); printf( "\tnumStrikes: %d\n", cnt = getlong(ttf)); for ( i=0; ibitmaploc_start+offset,size,num,info); fseek(ttf,here,SEEK_SET); } return( 1 ); } static int readttfhdmx(FILE *ttf,FILE *util, struct ttfinfo *info) { int cnt,size,i; int gid; int pos; fseek(ttf,info->hdmx_start,SEEK_SET); printf( "\nHorizontal device metrics (at %d)\n", info->hdmx_start); printf( "\tVersion: 0x%08\n", getushort(ttf)); printf( "\tnum Records: %d\n", cnt = getushort(ttf)); printf( "\trecord Size: %d\n", size = getlong(ttf)); pos = ftell(ttf); for ( i=0; iglyph_cnt; ++gid ) { if ( info->glyph_names!=NULL && info->glyph_names[gid]!=NULL ) printf("\t\t%s:\t%d\n", info->glyph_names[gid], getc(ttf)); } } return( 1 ); } static void PrintDeviceTable(FILE *ttf, uint32 start) { uint32 here = ftell(ttf); int first, last, type; signed char *corrections; int i,b,c, w; int any; fseek(ttf,start,SEEK_SET); first = getushort(ttf); last = getushort(ttf); type = getushort(ttf); if ( type!=1 && type!=2 && type!=3 ) fprintf( stderr, "! > Bad device table type: %d (must be 1,2, or 3)\n", type ); if ( first>last ) fprintf( stderr, "! > Bad device table first>last (first=%d last=%d)\n", first, last ); else { c = last-first+1; corrections = malloc(c); if ( type==1 ) { for ( i=0; i>14; } } else if ( type==2 ) { for ( i=0; i>12; } } else { for ( i=0; i Unexpected end of file!\n" ); return; } } static void readttfmathICTA(FILE *ttf,uint32 start, struct ttfinfo *info, int is_ic) { int coverage, cnt, i; uint16 *glyphs; uint32 here; fseek(ttf,start,SEEK_SET); if ( is_ic ) printf( "\n MATH Italics Correction sub-table (at %d)\n", start); else printf( "\n MATH Top Accent Attachment sub-table (at %d)\n", start); printf( "\t Coverage Offset=%d\n", coverage = getushort(ttf)); printf( "\t Count=%d\n", cnt = getushort(ttf)); if ( feof(ttf) ) { fprintf( stderr, "!> Unexpected end of file!\n" ); return; } here = ftell(ttf); glyphs = showCoverageTable(ttf,start+coverage,cnt); fseek(ttf,here,SEEK_SET); for ( i=0; i=info->glyph_cnt ? "!!! Bad Glyph !!!" : info->glyph_names==NULL ? "" : info->glyph_names[glyphs[i]], glyphs[i]); PrintMathValueRecord(ttf,start); printf( "\n"); } free(glyphs); printf( "\n"); } static void PrintMathKernTable(FILE *ttf,uint32 start, struct ttfinfo *info) { int cnt, i; uint32 here = ftell(ttf); fseek(ttf,start,SEEK_SET); cnt = getushort(ttf); for ( i=0; i Unexpected end of file!\n" ); return; } here = ftell(ttf); glyphs = showCoverageTable(ttf,start+coverage,cnt); fseek(ttf,here,SEEK_SET); for ( i=0; i=info->glyph_cnt ? "!!! Bad Glyph !!!" : info->glyph_names==NULL ? "" : info->glyph_names[glyphs[i]], glyphs[i]); for ( j=0; j<4; ++j ) { int offset = getushort(ttf); if ( offset!=0 ) { printf( "\t\t %s\n", cornernames[j]); PrintMathKernTable(ttf,start+offset,info); } } } free(glyphs); printf( "\n"); } static void readttfmathGlyphInfo(FILE *ttf,uint32 start, struct ttfinfo *info) { uint32 ic, ta, es, mk; fseek(ttf,start,SEEK_SET); printf( "\n MATH Glyph Info sub-table (at %d)\n", start); printf( "\tOffset to Italic Correction: %d\n", ic = getushort(ttf)); printf( "\tOffset to Top Accent: %d\n", ta = getushort(ttf)); printf( "\tOffset to Extended Shape: %d\n", es = getushort(ttf)); printf( "\tOffset to Math Kern: %d\n", mk = getushort(ttf)); if ( feof(ttf) ) { fprintf( stderr, "!> Unexpected end of file!\n" ); return; } if ( ic!=0 ) readttfmathICTA(ttf,start+ic,info,1); if ( ta!=0 ) readttfmathICTA(ttf,start+ta,info,0); if ( es!=0 ) { printf( "\n MATH Extended Shape sub-table (at %d)\n", start+es); free( showCoverageTable(ttf,start+es,-1)); } if ( mk!=0 ) readttfmathKern(ttf,start+mk,info); } static void PrintMathGlyphConstruction(FILE *ttf,uint32 start, struct ttfinfo *info) { uint32 here = ftell(ttf); int offset, variant_cnt, part_cnt; int i; fseek(ttf,start,SEEK_SET); printf( "\t\t Glyph Assembly Offset=%d\n", offset = getushort(ttf)); printf( "\t\t Variant Count=%d\n", variant_cnt = getushort(ttf)); if ( feof(ttf) ) { fprintf( stderr, "!> Unexpected end of file!\n" ); return; } if ( variant_cnt!=0 ) { printf("\t\t Variants: " ); for ( i=0; i=info->glyph_cnt ? "!!! Bad Glyph !!!" : info->glyph_names==NULL ? "" : info->glyph_names[gid], adv); } printf( "\n" ); } if ( offset!=0 ) { fseek(ttf,start+offset,SEEK_SET); printf( "\t\t Glyph Assembly Italic Correction: " ); PrintMathValueRecord(ttf,start+offset); printf( "\n\t\t Part Count=%d\n", part_cnt = getushort(ttf)); for ( i=0; i=info->glyph_cnt ? "!!! Bad Glyph !!!" : info->glyph_names==NULL ? "" : info->glyph_names[gid]); printf( " start=%d", getushort(ttf)); printf( " end=%d", getushort(ttf)); printf( " full=%d", getushort(ttf)); flags = getushort(ttf); printf( " flags=%04x(%s%s)\n", flags, (flags&1)?"Extender":"Required", (flags&0xfffe)?",Unknown flags!!!!":""); } } fseek(ttf,here,SEEK_SET); } static void readttfmathVariants(FILE *ttf,uint32 start, struct ttfinfo *info) { int vcoverage, vcnt, hcoverage, hcnt, i, offset; uint16 *vglyphs=NULL, *hglyphs=NULL; uint32 here; fseek(ttf,start,SEEK_SET); printf( "\n MATH Variants sub-table (at %d)\n", start); printf( "\t MinConnectorOverlap=%d\n", getushort(ttf)); printf( "\t VCoverage Offset=%d\n", vcoverage = getushort(ttf)); printf( "\t HCoverage Offset=%d\n", hcoverage = getushort(ttf)); printf( "\t VCount=%d\n", vcnt = getushort(ttf)); printf( "\t HCount=%d\n", hcnt = getushort(ttf)); if ( feof(ttf) ) { fprintf( stderr, "!> Unexpected end of file!\n" ); return; } here = ftell(ttf); if ( vcoverage!=0 ) vglyphs = showCoverageTable(ttf,start+vcoverage,vcnt); else { vglyphs = NULL; if ( vcnt!=0 ) fprintf( stderr, "! > Bad coverage table: Offset=NUL, but cnt=%d\n", vcnt ); } if ( hcoverage!=0 ) hglyphs = showCoverageTable(ttf,start+hcoverage,hcnt); else { hglyphs = NULL; if ( hcnt!=0 ) fprintf( stderr, "! > Bad coverage table: Offset=NUL, but cnt=%d\n", hcnt ); } fseek(ttf,here,SEEK_SET); for ( i=0; i=info->glyph_cnt ? "!!! Bad Glyph !!!" : info->glyph_names==NULL ? "" : info->glyph_names[vglyphs[i]], vglyphs[i]); offset = getushort(ttf); PrintMathGlyphConstruction(ttf,start+offset,info); } free(vglyphs); for ( i=0; i=info->glyph_cnt ? "!!! Bad Glyph !!!" : info->glyph_names==NULL ? "" : info->glyph_names[hglyphs[i]], hglyphs[i]); offset = getushort(ttf); PrintMathGlyphConstruction(ttf,start+offset,info); } free(hglyphs); printf( "\n"); } static int readttfmath(FILE *ttf,FILE *util, struct ttfinfo *info) { int version; uint32 constants, glyphinfo, variants; fseek(ttf,info->math_start,SEEK_SET); printf( "\nMATH table (at %d)\n", info->math_start); printf( "\tVersion: 0x%08x\n", version = getlong(ttf)); if ( version!=0x00010000 ) fprintf( stderr, "!> Bad version number for math table.\n" ); printf( "\tOffset to Constants: %d\n", constants = getushort(ttf)); printf( "\tOffset to GlyphInfo: %d\n", glyphinfo = getushort(ttf)); printf( "\tOffset to Variants: %d\n", variants = getushort(ttf)); if ( feof(ttf) ) { fprintf( stderr, "!> Unexpected end of file!\n" ); return( 0 ); } if ( constants!=0 ) readttfmathConstants(ttf,info->math_start+constants,info); else fprintf( stderr, "!> NUL Offset not expected for math constant table.\n" ); if ( glyphinfo!=0 ) readttfmathGlyphInfo(ttf,info->math_start+glyphinfo,info); else fprintf( stderr, "!> NUL Offset not expected for math Glyph Info table.\n" ); if ( variants!=0 ) readttfmathVariants(ttf,info->math_start+variants,info); else fprintf( stderr, "!> NUL Offset not expected for math Variants table.\n" ); return( 1 ); } static void readttfbaseminmax(FILE *ttf,uint32 offset,struct ttfinfo *info, uint32 script_tag,uint32 lang_tag) { int min, max; int j,feat_cnt; fseek(ttf,offset,SEEK_SET); min = (short) getushort(ttf); max = (short) getushort(ttf); if ( lang_tag == 0 ) printf( "\t min extent=%d max extent=%d for script '%c%c%c%c'\n", min, max, script_tag>>24, script_tag>>16, script_tag>>8, script_tag ); else printf( "\t min extent=%d max extent=%d for language '%c%c%c%c' in script '%c%c%c%c'\n", min, max, lang_tag>>24, lang_tag>>16, lang_tag>>8, lang_tag, script_tag>>24, script_tag>>16, script_tag>>8, script_tag ); feat_cnt = getushort(ttf); for ( j=0; j>24, feat_tag>>16, feat_tag>>8, feat_tag, script_tag>>24, script_tag>>16, script_tag>>8, script_tag ); else printf( "\t min extent=%d max extent=%d in feature '%c%c%c%c' of language '%c%c%c%c' in script '%c%c%c%c'\n", min, max, feat_tag>>24, feat_tag>>16, feat_tag>>8, feat_tag, lang_tag>>24, lang_tag>>16, lang_tag>>8, lang_tag, script_tag>>24, script_tag>>16, script_tag>>8, script_tag ); } } struct tagoff { uint32 tag; uint32 offset; }; static int readttfbase(FILE *ttf,FILE *util, struct ttfinfo *info) { int version; uint32 axes[2]; uint32 basetags, basescripts; int basetagcnt, basescriptcnt; uint32 *tags; struct tagoff *bs; int axis,i,j; fseek(ttf,info->base_start,SEEK_SET); printf( "\nBASE table (at %d)\n", info->base_start); printf( "\tVersion: 0x%08x\n", version = getlong(ttf)); if ( version!=0x00010000 ) fprintf( stderr, "!> Bad version number for BASE table.\n" ); axes[0] = getushort(ttf); /* Horizontal */ axes[1] = getushort(ttf); /* Vertical */ for ( axis=0; axis<2; ++axis ) { if ( axes[axis]==0 ) { printf("\tNO %s axis data\n", axis==0 ? "Horizontal": "Vertical" ); continue; } printf("\t%s axis data\n", axis==0 ? "Horizontal": "Vertical" ); fseek(ttf,info->base_start+axes[axis],SEEK_SET); basetags = getushort(ttf); basescripts = getushort(ttf); if ( basetags==0 ) { printf("\t NO %s base tags data\n", axis==0 ? "Horizontal": "Vertical" ); basetagcnt = 0; tags = NULL; } else { fseek(ttf,info->base_start+axes[axis]+basetags,SEEK_SET); basetagcnt = getushort(ttf); tags = calloc(basetagcnt,sizeof(uint32)); for ( i=0; i>24, tags[i]>>16, tags[i]>>8, tags[i]); } if ( basescripts==0 ) printf("\t NO %s base script data\n", axis==0 ? "Horizontal": "Vertical" ); else { fseek(ttf,info->base_start+axes[axis]+basescripts,SEEK_SET); basescriptcnt = getushort(ttf); bs = calloc(basescriptcnt,sizeof(struct tagoff)); for ( i=0; ibase_start+axes[axis]+basescripts; } for ( i=0; i>24, bs[i].tag>>16, bs[i].tag>>8, bs[i].tag ); fseek(ttf,bs[i].offset,SEEK_SET); basevalues = getushort(ttf); defminmax = getushort(ttf); langsyscnt = getushort(ttf); ls = calloc(langsyscnt,sizeof(struct tagoff)); for ( j=0; j>24, bs[i].tag>>16, bs[i].tag>>8, bs[i].tag ); else { int defbl, coordcnt; int *coords; fseek( ttf,bs[i].offset+basevalues,SEEK_SET); defbl = getushort(ttf); coordcnt = getushort(ttf); printf("\t The default baseline for '%c%c%c%c' script is '%c%c%c%c'\n", bs[i].tag>>24, bs[i].tag>>16, bs[i].tag>>8, bs[i].tag, tags[defbl]>>24, tags[defbl]>>16, tags[defbl]>>8, tags[defbl]); if ( coordcnt!=basetagcnt ) fprintf( stderr, "!!!!! Coord count (%d) for '%c%c%c%c' script does not match base tag count (%d) in 'BASE' table\n", coordcnt, bs[i].tag>>24, bs[i].tag>>16, bs[i].tag>>8, bs[i].tag, basetagcnt ); coords = calloc(coordcnt,sizeof(int)); for ( j=0; j>24, tags[j]>>16, tags[j]>>8, tags[j], bs[i].tag>>24, bs[i].tag>>16, bs[i].tag>>8, bs[i].tag, coord ); } else if ( format==2 ) { gid = getushort(ttf); pt = getushort(ttf); printf("\t Baseline '%c%c%c%c' in script '%c%c%c%c' is at %d, modified by point %d in glyph %d\n", tags[j]>>24, tags[j]>>16, tags[j]>>8, tags[j], bs[i].tag>>24, bs[i].tag>>16, bs[i].tag>>8, bs[i].tag, coord, pt, gid ); } else { printf("\t Baseline '%c%c%c%c' in script '%c%c%c%c' is at %d\n", tags[j]>>24, tags[j]>>16, tags[j]>>8, tags[j], bs[i].tag>>24, bs[i].tag>>16, bs[i].tag>>8, bs[i].tag, coord ); if ( format!=1 ) fprintf( stderr, "!!!!! Bad Base Coord format (%d) for '%c%c%c%c' in '%c%c%c%c' script in 'BASE' table\n", format, tags[j]>>24, tags[j]>>16, tags[j]>>8, tags[j], bs[i].tag>>24, bs[i].tag>>16, bs[i].tag>>8, bs[i].tag ); } } free(coords); } if ( defminmax==0 ) printf("\t No %s min/max extents for '%c%c%c%c' script\n", axis==0 ? "Horizontal": "Vertical", bs[i].tag>>24, bs[i].tag>>16, bs[i].tag>>8, bs[i].tag ); else readttfbaseminmax(ttf,bs[i].offset+defminmax,info,bs[i].tag,0); if ( langsyscnt==0 ) printf("\t No %s min/max extents for specific langs in '%c%c%c%c' script\n", axis==0 ? "Horizontal": "Vertical", bs[i].tag>>24, bs[i].tag>>16, bs[i].tag>>8, bs[i].tag ); else for ( j=0; j>24, stag>>16, stag>>8, stag, ltag>>24, ltag>>16, ltag>>8, ltag ); pcnt = getushort(ttf); offsets = malloc(pcnt*sizeof(int)); for ( j=0; jJSTF_start,SEEK_SET); printf( "\nJSTF table (at %d)\n", info->JSTF_start); printf( "\tVersion: 0x%08x\n", version = getlong(ttf)); if ( version!=0x00010000 ) fprintf( stderr, "!> Bad version number for BASE table.\n" ); cnt = getushort(ttf); /* Script count */ printf( "\t %d scripts\n", cnt ); scripts = malloc(cnt*sizeof(struct tagoff)); for ( i=0; i>24, scripts[i].tag>>16, scripts[i].tag>>8, scripts[i].tag ); if ( scripts[i].offset==0 ) { printf("\t Nothing for this script\n" ); continue; } fseek(ttf,info->JSTF_start+scripts[i].offset,SEEK_SET); extenderOff = getushort(ttf); defOff = getushort(ttf); lcnt = getushort(ttf); if ( lcnt>lmax ) langs = realloc(langs,(lmax = lcnt+20)*sizeof(struct tagoff)); for ( j=0; jJSTF_start+scripts[i].offset+extenderOff,SEEK_SET); gcnt = getushort(ttf); printf( "\t %d extension glyph%s.\n", gcnt, gcnt==1?"":"s" ); for ( j=0; j=info->glyph_cnt ? "!!! Bad glyph !!!" : info->glyph_names == NULL ? "" : info->glyph_names[gid]); } } if ( defOff==0 ) printf( "\t No default just language system table\n" ); else readttfjustlangsys(ttf,info->JSTF_start+scripts[i].offset+defOff, scripts[i].tag, CHR('d','f','l','t'),info); printf( "\t %d langsys table%s.\n", lcnt, lcnt==1?"":"s" ); for ( j=0; jJSTF_start+scripts[i].offset+langs[j].offset, scripts[i].tag, langs[j].tag,info); } } free( langs ); free( scripts ); } static void readit(FILE *ttf, FILE *util) { struct ttfinfo info; int i; memset(&info,'\0',sizeof(info)); readttfheader(ttf,util,&info); if ( info.ttccnt!=0 ) { for ( i=0; i TTC font %d\n", i ); fseek(ttf,info.ttcoffsets[i],SEEK_SET); readit(ttf,util); } return; } if ( just_headers ) return; if ( info.fftm_start!=0 ) readttfFFTM(ttf,util,&info); if ( info.head_start!=0 ) readttfhead(ttf,util,&info); if ( info.hhea_start!=0 ) readttfhhead(ttf,util,&info); if ( info.copyright_start!=0 ) readttfname(ttf,util,&info); if ( info.os2_start!=0 ) readttfos2(ttf,util,&info); if ( info.maxp_start!=0 ) readttfmaxp(ttf,util,&info); if ( info.gasp_start!=0 ) readttfgasp(ttf,util,&info); if ( info.encoding_start!=0 ) readttfencodings(ttf,util,&info); if ( info.postscript_len!= 0 ) readttfpost(ttf,util,&info); if ( info.cvt_length!=0 ) readttfcvt(ttf,util,&info); if ( info.cff_start!=0 ) readcff(ttf,util,&info); if ( info.gsub_start!=0 ) readttfgsub(ttf,util,&info); if ( info.gpos_start!=0 ) readttfgpos(ttf,util,&info); if ( info.kern_start!=0 ) readttfkern(ttf,util,&info); if ( info.gdef_start!=0 ) readttfgdef(ttf,util,&info); if ( info.base_start!=0 ) readttfbase(ttf,util,&info); if ( info.JSTF_start!=0 ) readttfjstf(ttf,util,&info); if ( info.bitmaploc_start!=0 && info.bitmapdata_start!=0 ) readttfbitmaps(ttf,util,&info); if ( info.bitmapscale_start!=0 ) readttfbitmapscale(ttf,util,&info); if ( info.prep_length!=0 ) readtableinstr(ttf,info.prep_start,info.prep_length,"prep"); if ( info.fpgm_length!=0 ) readtableinstr(ttf,info.fpgm_start,info.fpgm_length,"fpgm"); if ( info.fdsc_start!=0 ) readttffontdescription(ttf,util,&info); if ( info.feat_start!=0 ) readttffeatures(ttf,util,&info); if ( info.mort_start!=0 || info.morx_start!=0 ) readttfmetamorph(ttf,util,&info); if ( info.prop_start!=0 ) readttfappleprop(ttf,util,&info); if ( info.lcar_start!=0 ) readttfapplelcar(ttf,util,&info); if ( info.opbd_start!=0 ) readttfappleopbd(ttf,util,&info); if ( info.fvar_start!=0 ) readttfapplefvar(ttf,util,&info); if ( info.gvar_start!=0 ) readttfapplegvar(ttf,util,&info); if ( info.hdmx_start!=0 ) readttfhdmx(ttf,util,&info); if ( info.math_start!=0 ) readttfmath(ttf,util,&info); if ( info.glyphlocations_start!=0 ) { int i, pos; fseek(ttf,info.glyphlocations_start,SEEK_SET); if ( info.index_to_loc_is_long ) { for ( i=0; 4*i