ࡱ>  ^_`aFk-o1R䰹mE JFIFddDuckydXICC_PROFILEHADBEmntrRGB XYZ acspMSFTnone-ADBE cprtLdescHkwtptbkptrTRCgTRCbTRCrXYZ gXYZ bXYZ4textCopyright (c) 1999 Adobe Systems Incorporated. All Rights Reserved.descAdobe RGB (1998)XYZ QXYZ curv3curv3curv3XYZ OXYZ 4,XYZ &1/&Adobed gmXX D  ! 10A"P@2#`B$p34%5C !1AQ"2aqBR# br360@P႒CS$5cs4D҃Tԕ`dt%puEU !134AQa 0q"P`2@BRbr#pႲCSs$T!1AQaq 0P@`p G_~E)?7=||_ !/-go.|IS.M?vw=/E>ony_O?=_7_/ϛ_N_?#>;ϕ?G]7 W_{7}?so's{?3#>?~o>ߝӖqyΏ/>9`kw6?/?2sN1:qTLpLAB2\S:]uِ͋Qe ,4+$$BHQ% *0$.5A@2TɭHu3_&8Hț.Zk.5dKfl:,5"ֳS[(Y&dִōetH#&H"DcQr ֔ƊIX 2DA`I5&Ib.EeˬMMkld &ME|ևXDZVRH2/=8@@I HcHc! Z2B0&LEb&Ml6Rˁf5oU\L3NƖ3ODǦk;*HҊvnOI̺qB"u)l0$؉JR#AJ"Eĩ"u%d@DtM\WVe-d#5rqH8ϧCr:Ɖ9aTIT*-a"a1$1F$ $ĭcVDk+GV,d +̹bbٲ*X&Ht f~}k "CɊͮ݊C$ 1X`1$H)H ("#AYBlW 7-N1l˖'23qdeckUskֱz]%묹 *vmRYUJB b RH@:(F(c "UPH`0` %u\Ge2㜹#c+,2ם5i亠tk-&bঃYX@[IPIY `5 @2B F!$H2@2PS2%E$"FX䋌y%b; ^=4ƾbnf[ ycE/rc_dFD # g-"$@j0`H`Hb$1+&H cEYgy 7#X\"-29RiDeDϮQ;hN8akYQ"2 #Pc@ MI5H*PCcDj0CJ) 6]C$gU'h.o$1(L %bWd,KzlZqˎbCeD R1uI!HRBv@4k0"-+3cQ (dm& #d ԣ9=b,V Y0b U2$Wd.!Y϶\yo?LV ( HdHD11:tcjv{ƶi`k.YUzefc؋b!d1+9m 2 $s[8\8]cIրD a "I`H!D0"&l35Lk;=1iIQIi&1+=uc L%dՀdwnuM^IJځhw\a%h !0TB@01DJ0*D㬝"BQV $D(DT2Ua"c%=Nʾh,;5;ƨJOXk?Sѥ2#ȓ*!d:Db"L Eخ:3+gNI=uLy c0aR"d S$LHcz^/V:|egз|;\z5iaČrM' RdI 3vֺzf:{'㷝9돼KBp穱X*K " @YI jSDYS9.zw?CvsVprrcD*z5<;/c5kSЈNt%@'@@o3ζ'=sOCMzz<|65H! !@HD!,DV i ufzfiwZ٦LgJ %`H@ZgZca5\aFo_Y}xnP! !! )2#Lb9}0SgLg]}z~C>gsMwqӗ9 $uc#V4X#T AX J ֶd7_cuU As5󾜴7(D(0 R1*@HddQϾ5v׭j^ֽw͹vw'Xmfn IqX1 CΒkUfV2V,*^*ɲ+&ǯC$D! PV4! C$Q z2wáWsw6m*6g~@[sWNvKpj-uƕ0$ J *uvm3%nca.@L5$jDP CSJ %N%L08_"}8n}sr:s{ӞB˩p:^jMz67祹R΅-2H@!Z/5e1_8dgtz\ӎYQ 1 (*P*ԡ04R8zq92zpk>:ptuqb}Mѩ27˰ܱzZTiuhsuĈ%C3շs:QzЛ)m]ypNֽ3=8DAC`@1 Ss:r=c3Y+/5w|Ƶ3)~1`e/>ӖkMnnZ{ۢ7\srzz<lw17YnsVlq^wxٸEHcl淎j"aS((`! B! bpj4~.yUwoM.Lҝ3|rH^_m;]KMϦx~]v}#wUrwz-cQsZ((/^kk0l6k<\434~razq.y~R Bh(%ƂH#k>έ}=~`nުqZͺ]>뫖W?EǑtui})3ӇdosG7AeKp8;eGm:wSz3sX@/?<8 +5 H`_ffRANˆ`Q@5V b SY4Y׷YxלyqvKYO]r>zprqS&~+2yrzlћ~_WKӗoqQo1qR˟XoynmeX5]r \_U# ) 1QS [_:O;s70gS>yG^c=MFVkWN۹ӟ7>3yq[.79v9v}G1} =qMlFd燬0F VPi~e, ЍZ`5 h5L=y.}s]Zx_ے\DfΡ5^wfӦ<qb돢Ӄte)%ǣ<ֺ]eFzMs橿:t2WU3M%fEeդV)! Z Tߟу_kLlkN =or[6=ڟ?3cͤ3:xѝӆV{ܬi2N_oKкؚ6+Q+:gnQ!5kif$̛K c $!CDzsl)]fp%˦˯uyΚ[%23O`s~{^;;96|޼vU2%Tm屿W{}-LfcyV\\䵎X*#\D  Q*$I*GsuFw8KOǿ!\f7޿]^.Ƴ_Ͽz D}O{q kFt+?j{go>O7Zgܹ=r.*/T/,\In6;ŖdzvR7L".|Yc ky巋V5 pj :{>ٲ7.UeˎEVq47<͓YfU&)@:B B ů8ԕSO{u{p˔=+MgJ^Ͻǒuygf% \4VAg2 e^y&:޵9vtϜuᴚ=; urwRiy}c Ț9MsQM&1a AD {/.~sӌ#ي~g|uL|c["3ִ7nknssmbϚ0%K+5=<^}o+9><ҋ0u]8GbG֚8KFװ_X(>Ȭ֦@BvsY[7zgWsuc{ϯc~WJ.|Zʗ\rR[eyw.Y嵎= nK>Mmo\cUϷglzs-pucϝz%zi fx3;(}9sw;y}/nwX\賾:볽U΃Y%ͳ4ZΦY$$V =;MggP'k|zC<+}><ΜtZΙGZt-4jIó˥׬\d藆ˎ=[/>Iv%:Zftrxoϟ8. }E1c/_!CQ|> }E1c/_!~CQ|>}C 1ȃ?!~DQ|> }E1c/_!CQ|> }E1c/_!CQ|> }E1c/?!CQ|> }E1c/_!CQ|> }E1c/_!CQ|> }E1c/_!CQ|> }E1c/_!CQ|> }E1c/_!CQ|> }E1c/_!쯆@@J aBBB'`и!]0B%\h{Ex(Pك? |c  ưr  HA&30TX傅rP`  {m(PTFaBCP#[dp7 0@aB"] (.-)M͉ !a5SFz$z2ty;z7V"ȨV!+7i3i=B(ͦe$*GƧo0Al܀fQfn"fdu8sDzX74# F9/P6 3=LG$8d{ҲGh |`5)Po@h SڲV FD&#Ɏ'~dNRts6@ep7 Yw0BO6!o7*zwO7 &kZnc5$vcRm 'pZ=FY0Dr4Zwj ~_J#A'!ɭvw+ sqֵ8 =8  (Qj)cLf=#Z1yZ8s{7*)s^ ܌{Pj'fUkX7(cȣj"wHT<`N@NF24Ap˥MꊛIc\)=!X8#tpAHG\(YTqMB752n8 lj8"[#^J\]KR3j^p4 'I'0{sq8 (PB ) CP5l!8Q Frj1j4c^e#Pz)f//z֓f1Ő*cx $`76sW48A9c1h|a>cѤF6C T%4 ZR|zde!C!$ OPQ CX504A< (QHy<,Wdlx@Gp0ό'Fu@M.DgžSpaU&M48T41qHt>n)8ʡnM)$i$MiUtrNB|!bvƠcHA ipPB j aLJ& N9`6RSJ(otpi9> #{G\ld%RQAubADBjpR=| jwY4e.MyKLch6 S=&3a@B#ul j aFjBAB q] J  c83qˈ Ȣz&iA'+=53\t8fכ蝑T | 7#rR#ZaB;PPF(PB .+. +P)piI#0&)ձT5DbsǴʭ=Xf 8$m0m59|HIs<  (Q…  \WSB|#3maDɖ( jf2CIcA ںܫHI[1QNr[#"i:c[#^`] (PB(S (PV҅ S۲#҂>SV52;8|8+]zIf KMtqM;Pg ) 5(n4" ]TIpsqљ# PaS|G<U7Jڸ,$n]|=j(P4DҖU >(M,$' 8;?udn-Qkv9& f pP/rE9=Dkx}$l-D6Y#ZZL@ BB .x j ($z"l-7:G,馆nPkmg@f+EMͭ=B (PP/[MDnGa>;xu/)X$HL㞉,{T.kBqPB\;8tnӾ*LP;l3mfrxdtUU B (PB(\L(\)A攍s^.trHk.61E ĸ=Fx(q[ʗTS5+4Tm pQB \cc{Zht=qeg+8ɮWV[Ua%Dq@ڪjq B  . .҅Qwyȵ5GW,NO[XN״̐rX_n zTUtԌkդOtk4p,ۍQ}uj/W'6񼅕nW8F.罛dd)(KyΕU,ԇZKښftlFXQศ (PBB=sOJ5 ZQNqXSK"9[!%RBPBiv(PB6.7UuPPSXbOSEY5DSIOC$ovYp,DF⑯Wྒ){}%`*lUbV T=i;k(P(PBnM8qFW8EETPYz{5d\n 5 AB B (PJ(PqP*z-*ZvUԱQLqWBʙOZC&?}%cA:M({rqPBPiQ%,.k)bٞYg9S2e$\zrM7Sϸn!AS (\. BB .* 8۞[:l(H!':Wq0q3 8M#HRc8}T力YdRKoQNDV R&(P(R t}L6ik8٢[u1}zlš;B쯊 .&tZI_w8‚)7B9ӼңQ9OW3k#.w(!(Ȋbr*Blr[9Fȩ#zWQ9˨kk1j1EU$ iYQSRSTT49[W{k{H' t˜1AWw8. iBʅ j 84ՎU 0)gMZiVE'!ikU"8M8W4ť |g5s:p˭4UcOlʨuC4<$[}I3b{" gTNvӕ]tT bU6z`[I\ʖ UCPvW epP)e=BÉ}s'xиfF,gn$c!(k՜r`P:mAszUNuQmhA f^E47#oh7to"oϮ,R1JՖqSxb~+(dNEcWlen^_u-7E55zY#)An9]O/B4wB#z<4nR~Nmt# (\H(\T(\T(PB )bBPBGu0g KE%UvIi սΑBȊC thb2$?s2+WWN){d*ژ6)H}AX_p)PuchiU$_VW!TZC⒚Xx:/|ڢ*JbcR 69 3:cJZJ=\S6hK;59I!%WqHV[q*bsal񙔄ʦ{рp626W\&jTT*:\Q Pۥsqe8m'N)%]2]i=2\l'St=?fS^PtPӉw:`7CYQRUtc BB . .pɭ`d yHZ'־{#= (+7N+QƏ͂&yatQls .'oI){)F+\*mx/*ʖx*S{e\GC,&_mOkꩌ3u40QSBa>-'] 7&1YKS7UXÚ]tRdžB[\g BR5x嗆mdoR  DWR7Oq#]!AӴl#iN+D魬m5]XOd*+"u3#(9&aTkh Kݢ.SAܥm $mU5ȭz+^i*\YAECLΠeDGO=eE-²7-'oȜ8!g颚NE=m7/1A_ Lҵ8ljieSvԈTbiٛsra{n),WJ1ǫj)CLx.… Pkk)6TsA!De,-* GPt3ms"-lǧ[rytӿkʰ੦FC5=b&No㥆z(Ɯmtp6xbJ#fS-p-I5@jz' uU{P8≣:Hz-FfO"W>K2e vSL+NP W+bfQۄQbd9cp}KU7Z=Rk9m.! WKM KUP)T#Wo,:r' uL*ͮwdYZ4#,rDu5]k)a])?WJB ktѵxӵT=8Fv<Wݭqڵ:h⧒8F(5=('?{W,+=TqqNިc&'R lJɩUW}ZME/ygA-uU<ͣTVMoHQYk$O;uɱR9WE;7RM¨"kN-;M(=YRTQ<]OW_{PZ1C%yJr<9ISPGa=:bG\%v"Ӳ8.7b1KlTQoJ?S"cvz*'SuP14TW{<9u{mU\_YO%J oOQ-LVd]sOEm2zB䘮vo5Φ)I$숪CQ+1[}3=TIC=HrT>FE]WG s`iKlyhIvYU;{=`*Z3ʦ1ňSk*t5@a͉Lws[1.c\w%%01.c\w$w:qw{7qί(WL2{>xs[1ͮ݇6kt "wrNru~jޢﷹW{x ws>qvR^sP]c:][MՂm)uOSwS+NJks NꞧϨ:#'߯?wjwoUqad]C!=NaCyskC|6.is9sK0]A~'wOS`}OԎJC::zyzJ;UC7Q5is9s[ks9??m5ϸ$)j*WQ ]=qM[]^Tqm,յpQ'qH'S_;JGӓ<1GLUUog|DSO#9ciU1hnDb)c=l#:"|')nnknۍkj)3 c.8E18nޥavTK#OO(bk U.d5% uuE=aj}MM[o)U[44O晕QUTs|eYPڧUQ_Up2H4p٧dUX:kZ&1s$t:Jx%33))M&ס&F*6j}=<|QJښVJjXf<"2Tޜ6 {KL}-4:zwkM GH------pZpZpZpZpZpZpZpZ?hhhhh;;9wwwws@?hhh9wwwww<(PO}ԄR@C-2"=@@wn?D&_FLK / ࿍=cyb~Am M<|w|CP5 Tfѿ11>x'~r{'੅=vg_Ѥb{0@=f3I˼"ļ,(]|5 ,KoPm?+1JQYX]x:&æݝUQO/4u rCBu{UV[kovz+kj΂KS_ -V+ tv][iͦAǎksQ>t4v{}wcMSԷ* j(0e$I\eFK,R) CYWN3] e]3JyUN*tK;.R7!md zy(k5 fꊠʳ6k\+=akr\" º6+es5̹c1F;;gucvQ1F;;gucvwQ1F;;gucvwQ1F;;gucvwQ1F;;gucvwQ1F;;gucvwQ1F;;gucvwQ1F;;gucvQ1F;;gucvwQ1F;;gucvwQ1F;;gucvwQ1F;;gucvwQ1F;;gu~X @]Sl~B 鷗鼿/[x@/߁I/[…/mid2M/_eAɻH.X  L_B,K . "AY #L _m0_'H(R{$aǁ F3~ Qb[k=ĿXŲ]Xd PdqFc= 2_2HH0[–Ov(F3,7`n¡PvLI #ǿ!hMr 7` -5Aޥ2H=*ǿ {qE4#vy&i?x"\ Lx'3 pX SL&%B?*W:mog)9fDta5x(|Ɠ}_X$)v* [XQ҂M2)P\Wa Dmk4.<.a1Z⤔(og7c2jt:qX݆GC6لg>S9EKMoD7Ҁfm/?2:3QRO0qy Rj!Q%&锏h<>%&ɔWʢJ#kԪ_1KGŤl6'o BF n53v eEzRt<)XA0rKdv aaJM 68f( 2QU 韁0[$>WDBQ2$*$lj\L3~RIi?7_ r4`KFDZFL<'o(E"n ,J&$j'/`لWD(3g qۀZV~fTKX0" E1=1F3kEvXujM&FQ J nALQH Trhg.þ7.˙&鑥1ix ҋobEg鏋ҡID64⥱${UI5FԤ|Q_h1(b!M(=#+¢$$ғݦ~^6B TTDO!a#nic{,8xNV#$g"|aMQ LD$ -签]P<EQEIi4D%ĔLISS[ibw 4e\n** S !B"ƭMRteo%.3$jÆ[Z֚VRZi8c"r "&I5($lyVMp_̱x5RI%Ԍ*nimx8%8EKVjaar/a16Er/7mQG M3fxɆR-DEqLԽZqv9ԤF_rQ 0"BJjJJQl`чT7ŀEL%R6l#FU&4; 䱌lflGkX7k6 Z"% ([ adu)q6N,8F5˃"dCkD]3#gҳiOŅ#&XTU%E2c5i!ne'~zGKPPTH3,F(ޏL Lhip:qQDY}b4@q5d?kn|^jItX…*aHdC) QGcw 4D(׷XA,B8dd1H$<؜1s 96j YFJ!^cy=P((2)xiׅle¶2z𭌽xV^;c/^ׅleö2[z𭌽xV^+c/^ ׅle¶2[z𭌽xV^+c/^ ׅle¶2[z𭌽xV^;c/^ׇle¶2[z팽xV^+c/^ׇleö2[z𭌽xV^+c/^ ׅle¶2[z𭌽xV^+c/^ ׅle¶2[z𭌽xV^+c/^ ׇle¶2[z팽xV^;c/^ ׅle¶2[z𭌽xV^+c/^ׇle¶2[z𭌽xv^+c/^ ׅle¶2[z팽xV^+c/^ ׅle¶2[zw)9?Cw٠d?YCDމ?Dgt'C?M_TfEn"sީ;x~p7hvE}_Lwtfw]x7 >v3Wzxx (fw?KK}:L?˻v]x~ݖfnw;o}(?CNx0pxbC; {4n$ӗvvw>a0.}ݗhevprmPޛ4va]ZC~-,=/3^ ;.Z6qݥCp@{|{Ct8Kݧv7h# a?Ґy;%<3KPffhoaoiwvv1y4<Ѹ.RZBt43e-ckܾbT ھ¥U)bT0`1l^Rnm֦q)u)*A#HXּ-b-R_s.aqVy}w4BvqAY,~q˘PPn˛5}rʥnlYf[ 'VJm\poj_U6kF1\]5'of͕$MIJЂ@QlڴN%lPf2VwN7rۭZ)!ڬ9~QdҔncrvԅdX[żȱ#3COÿ=Yុ;)2kT"jRTa]̭ƷvYⴇ)#i;a̭cƶ}9]oo2tgi 6ɺw]wAZ5G$[փ[n [nG+vys8Zmy]XxWht:ykN-4 yu2[,e^I#>!3? 8Ar&&yʀ*포sT*byw/b'Qf*D"5^N]~}YZy E7 iXfZG*l^hͫ{9M giXEGlnդ)Who)6Ve׾Xs59-x}iNߤ%n6nRʹb@<'LZzSdn4'-dgZϦx5Zn;S )y#Iu)kڔ_c$6#^d._:\N+5zpf~ԸS /GsY#tʮ U4?:(RepR4y}:CۭG.uedwIJӖvH9)w16m.@/5źӉm%`?}m ˆP2SY+"V9%fg?j/P~N #^l~ZZ{6T'a2PZ9i@n>n}i_mˮ (50}*p donm?Xl KW\{n]XȹRefdK2LsfKXL7ba̮QJ`$`dpA"ws+o<17<6׬29>5ڏ7.rS/oyhrX)o.*}^M(ys77#]e6ܫ_2Up9  Mrםswx=՛c,SS7qEgS96?]ذ]ҹ(W5qp㟽[m%F61Vm}f.KՎQxYo,ZV\~r NX-sW~%mI32 prQeun}h|c|P#V]M(S[-7%wgd.lJq͓.\3(7vlX8ݯ\=o}aHPvsh]1Ôfy2sY{.U90mhJ+ݶyvv!wۭ:H4"W2t?s{umH[JmMҬ^Y"Bmqo&ܶ e(?X8޳Ud|n˚S"90eF^\6XZ\ eTvS!X7Wo^y!4H.:*IBayZZq -?ͨeZ\Wٽ?*pU>mżݱue: [f|4L3({>imaRm(c=nf{L֚9%;Ys.gt7%u\\ԧTbsvOu7WISʭuhI2fUOb#DF93jզat^>K!I}xKvp=߳;rO܏(=#J>;r?μ(?$J>>;rOμ(?#J>:Oμ(?$J>>;r?μ(?$J>;r?܏(=#J>|;r?܏(=#J>|;r?܏(?#J>|;r?μ(?#J>;r?܏(?#J>;r?܏(=#J>|;r?μ(?#J>>:Oμ(=#J>|;r?܏(?$J>|>:Oܓ(?$J>>:Oμ(?#J>>;r?μ(?$J>|;r?܏(?#J>>;r?܏(=$J>>;rO܏(=#J>;r?μ(?$J>>;r?܏(?$J>>;r?ܓ(=$J>|;r?܏(?$J>>:Oμ(?$J>Twq4}tD>ϧi}rtweT{ }>ö =>z;}_wsF4F]}e^ö1F&)Fǹ1g8=Daa1gӺg_a쇇˹N1 >_qތc0{-1a vEgDJG1c0G1Do{}Dcܮ18wkX?rSc'z 1{ J+>WsƎw)4A{!}vzQOg<z#IOs9Grя: Ltƈ&7]wG;zWbdb{GW~(apF``OܘD‡TN0N#1Q1#>4D)JD=z>/z1=cVaJČc{_kݬb?kǸ''){ъʊ%z;z#\n0Rc}o*pe03utς$w0ߊF>"5='K:#r8=8aDh$A"T(d5@#Tj>TF1#ܢOr4F}q썠:lQB;}%NsdO\a,10FR%q^.}Goch&;Ѻ;=W+c^9e]  4}mS NrR%ݝDGJ,Gdctħhe@6N=hjqJpOn>DRDAdP'c+9v#w kAYpD|#(9=2w+8_cnX!"}>cf'Sd']Pk3ӣ+O*Q1dp)ɜ4Te4 NP0=qD<޸ޗOhju ]3LRyX|X l2$t J2 q=yTrcת(xd cj;=xFI9ut JNEH<;`}7|}N4O'? Fr$%O63)>фON&* f}b}0tDQV pVOG:`"jJqbbGxTW Hvބ|OBvQ{eNtS"mГa)Pe*Gjrb eیP'N 1@!Bg%2 bI $uh!>S RzF] 4Ei`aOn1Ida=1j@k+)R4U8FE13.}Xj&(iƙu{#:slPϤ@0ͬKzZG'HIh@0@ϿuBѧ S؞Gf,O3xeQ|` U"ލyzO_TcXPr]xw;) Oz9zO;ʔ*@։=JTkT:kCW*w H"U덝Q(4TX VH bA|h`Ū0ލ{)*:{GN1?zD`4 4o( :`7* t%:`:F 0^敁|0g>=1Dcg)Fһ)/ZgwGaQ]'*?KcLUH^,bZ0e1ot;\a)MpgJ a;SLǣ'n1;g82hH4f큜cYr6GP1ff= "7g];%QQ =0L&{4x' 3HN֑Z+3a VE cJ^O(q ta(5 n:@@dLǿR4Lg*Btal~~ "`TFߕ?61w{B%L.CBz![N<;у'}XD#swDΓ)Ky{u@QV b {yfReꁵ{*>TOxEGMbDGhfAXw.aֲ ӢVЙHLdl0pV$^JL8(lj#4#2\^M\6ʄCOU6kΟ(F"߄ ɗz Ԡd;)}qM}_FeUtƠ]WX9cTy׮!~ F"6V+ߊQYbz5≓ ('Ԓ CRȗH={OctcYv鍥tNjP:5B2M}TZpve;F0fzg#M%w䥤uJ6{LkFUK pN9mN}` t9pԥξH43Gwۮ=O^PʾAGM!'k:tR)y I#4L)͈޸NdgO𯒞]]F G7]0IEO~ 7w,5 D§Uv e`eHP+T>DPveGh}e>*`@uԔ >+9I>X?* (OD+ۢW %vB=q{ N7Tu({Ex#xwxFc|F/~%2z1jcs/ǯ߂ ,'8NCGPbSgJ-"Tf) -^x3׬^% `F**TQ w5uFRKY+Hn#&8:U6h/.㳕DtV6֠6Lee4 (ލGW RmJ|Fꌰ܎GDs+Bgʄm7tF3|bdqw]7=DɜVὄ˨\ߦ$N02]pQ-ʛ]B=#xE ISfdRzULMꘝDeT`$W+StENLySʄs =!Є< )LYj Q'$vC~1"»? !]{u{F=nU:Lf0,uUp,`]NɚrF2kh#)SX\kXWp =tK*I<(%:AS9tJ]Q>"N2kq<=rΈI1Qh.dX Pеw#;$hd LAC6AΜb@)Sl =|фcIF"fKI뜠IV^ Wab٘wOQ# R rV'Ȑ=#y1Ǧf55Ϻh7qwR0. 'utFp)BNN7J L=A uLA>^# )*\NIH*0JgR"k ;=_DhNut(e#BhH쉣&kSRcGJ_24bNIh Sz{GބPgZlNP:AT̰k!P`OD)E$P;}VS#;hJtz*cN9ghbpTe*fJ2 2âX˘H7p5A2lҚiYT':>Pļ1Ve{՝:_h+3MZ#z_ {U(eeހYK8ӠSSU|΅WD!+ QWf+'P1>g3dn[•FɯT'JсT(( bgQc#F =r?+GQfǠt{Ѭkʡg pLH%1gP4VR0da؝3.hdvU(~\r'VQ>Q1) ykOWS0VD%2T-FS\नP6jTf4$lעo_ ө:jt٦ J6L.RVKU{kqq&s(ЙtB(WߊGDƏ1xa*]DvOz'(:Hh8*e۪%b6=ċD|A i⸀˨aXEfZ(+Ka# >4ނ,h8u)'(O[LNr :=̮*~l8>=##VAĥ]QXۨt 0iF㎱vG"O3(65Q'IDvҔr*~PE>~6V&uށ5&T+ZliPA=A~:EBDfd֓L7Q4٪#"!3Brd݄q{['͢g >n\2gL9fRYLVJ6i$$N$B8$f{W͘&7Q:sS$TI)|&RJ,k߉*]@Ju1c4a Tx{19pqϓJwTg=@ 5k$~c(3LH y^JU(ZqVJ')?nh"Jc;bZk'DI:xSVst4ڷP*6T20P'BONqEJJ*NPdSXU3l\ ,imJOdsHHe檂U.Fw&S)ʻIQP)\(H#IB@>m,Hx_]{5C˷h7Nf!8xj}"IOc\P_ErQyO'DLVRqNL$%:%&ue!>Rթ:Ps(e:e#xb4:VA"9Z>@`,Ϊ:d| O\d)"rE>j`5z 2@LƟOpUS p WhN[ l3(k@Nl6#`-)&bim5p&gR5~(lT*FYS@ $O@lƟjɡSH5 I4tS{)UbiZ X:vbPGTg* 2}ĀFutdr0AV_ pJu1*)ңXw|PeFgD'O6z5{M@ k_lOu=OlL>M^mNBf`IL&Ddce!N)Y.A01'6 ;bYaȩ9`;m}CSMXa!t*%'DD`p08<=F’q֜n ֥ z~,с#=gY>JRi>F;"^KUo+(է&Z}2˼g |%AJ}:Jmq2'2ø>0Gx?LĚJ3"MVL) x%Yti84a (2&lF1sw`@&vc{,LcU3*JWF@a ՌRm3\ 1*썥-J/83>zT jB7>!)n;ՇP#= 4 I57RvR>Q COJӐ8 򈞩*Քh3\䔭:&8l4= S 4*NΤӿ8):(ۻF'ׄn۸_GdX W8+U?UNAJ??tc2)JҜh40B2yQDDXX4.yY;Fc,AUe_F@4ʄwD0iG{=qQ6T2"h>%GȫpʒqI\^)`dZH VЌ*Lʎ4U )͹JLdwq9.Rp1CV I)9H섷qpfԗ$)MPT3L-╬eqQixC8VgM'.~^.7ץ`~pn&z[~̃kMHQ\}>|~ gNZ|jQ㌩MH-+dH)uR-+(GKPwYkl.JTGB@Y!9gV6T)P'm@dU1;=~bv}*BIiA2ޕEqN]0.jr1~rF!+(˳$)E ˔T`I&{FAJӈ"yINi)#321eX FIlg&f&J@}AE8~ 2+̠T%D/N[d8%9nq..Fa$4& M]M9f[5:R=?[?څ2s9VQu w>Ci= qLɜ&GDl;kQ9|'N•U)̉i=t>ۉ͐|}Xi9\'d)8*rA R.BR5Bp tʱ_m'Pޟpx=Б (y: :LsdIb'*=\/@i8%) UZ8uJ6P8ga:I|OTr0ȕUFc:ҁ0'2Iv?8BYF{tMA:TW/Ymdt̗Hs4&=aSL)WR|15Lϻ֔%@KdK7h?%\wԏ)TPNby 'htE )Ս'* ^%*iqN *Z2).ϔNyOm9' 5BSej;9 ƙ0Ph[dQؚAZ˫P*L6Ѡ#)kfl g %+BG4㊲Clf*treC0ʹ&fm m ڰA!e)M&4*\6 :R*}U|i2GlsZ1R.DវE75hLgC4b*0VP&LZ2N/+񘤒+U;t̑QU8e*pHc۩85Eҥ%5wsQOGW#`))߈ю4'2jۇq"PSv?5O#QVjBF>=VfՋKg>i,%DM\GGU!70%B:b~ևdTꙬ9ox Bi.+zۺ40aݳITΑG3,ɡOPU8Ȳ̦&eCSiI#,@LHjeM o:Vjny)8&6PS.Ht%>9GqK&h>ǹw>=M?:{I3&()$O֓G;154 'z[nQjC6U\vie*uQP0m' ϩyEgn#u _&rMHFAOq ZՕ@L408HL sgKa*U-r*g"CCy, i*=0 6Ei КE3=&2缫P?W[+ZʔfOiLa+IN==t)>8c[$!DN6JѳSya@@58@HNP-mLHC1h0uq 1pT-B@8%#pLр~U&i öZ>Ny±n0 |b ~?{)0TAhfᩑz`u㣿:|xbBZaףPmb$lΗUϒ eimµNl Jԑ OSՠE;aq RfYR+z h; 51%H~IଉPʅPO3ʫ˙P']"ѺΗTw:JlIcG5 J\tDLƾC%+`&"zSQ o0JjCY"uی9J*4\2s,(S*@ #k;]]JL:Liф8(I)f΢1:=Ԧ2NaI22 -?_B(@Fd9Jcm@f*<1jmNC E@I*Dm5x͌]:toڸmN" ROܩ5쒄 UmZ˺ -'kso9  <0[J qMU::\8jɮAypjHz"HUNF̘gFI0҉t!23dO4T3k!`V'A )K‰T&ݭp3MZzTJv2J J'I /a Rf3iT:<jjdu2)jP!MJu1JSZQȬ 3$,&PAT2Jpp=aMS5\"KXjLJIKii v||S$Z?py6O_Rqi'BkQrdfMO;y:ΨZ  Fv2RT]wa8$[f/8vFAshOL gPkL@k=e)xϐtU=299ڜ;)32rBVucQ9$$i>vO? ڐ;6h8p'J4NJnvR=*F(&_~8w*6T A$ևRF{o7! Go\4O8CJQ@g1uK'w8u-D%eGy2jPjs  i$%IPȵ|$0i$PU3IKPyqhү5ĬpYI2bG;AE@}.컉R7n ?Ix|οŸweR/ChKBT@ NV?.~e@Qy{hF PRόҤ)$Йl&OS76S_!:OI5WFk$)O2f,Hy7{.qY< Pu s6d2{g$|9@-)ARP2$ji/ega|5 VR+Hi%[P!႒j'0KN q6MPir`-lZu%J"'F:t 1TfN`![%' *̕Y)7脇V/lP={(}'K?'6JiO ubL 2P)=pC\DJʹ6V=d3QKi5HS9;^׏z?xv*`.J:I:2)Z@-TR{(?pyDn=#-砞xFwxm唒&NP7aU!?!hQ:'=(Nv-Y2m*lahIt צ2 a>8S0#((-U.+JP\H-9% J*Q3$uq]~Kn4fT.?w,ԢOpcZ~]D]|uV=ggDl*mךVP FUkKjI;C9&~e{JSRJLCT!2m+yM/d HiGN1`V30&U;Pd6Tmk$Le%`D?rReMa.]gO6wdž-`3 s&,Xq)93x ech|tGHAmsQtx\! -=UpYV|Qd3VZvVdPݖ)2TfVR`XzIFm`FāUNʚ\ -?^iׄ) Ԫq)+&@;Hğs\%n3ff{1 -4]%CpnHDMKzG'k+F2[ 6}eyŴKVF[ty{_I䎨!9gzh8ɴ **s]_s_ O~8;ꬹ%6W\d[,'-;nt H@ ʥM)2rT-?/.9}Q h wSE?5 x"oZtdiFxB]?BdftEeu.kVRcm"BR~ i}hH)!9(uf Z䒬]6r&36ۤ':f'C8qVl[2$R$-*&xH ]>]N\GeK ZI6# Mk% *u͐Tm)F ;mРx+)ᝬ*H&\S ܬeeBF֧ؑUvҷ~1,)U*Q'Y'B AVpg.txTQ X9 :(+; %J:gaQsJm=mR W)m[EZf*t{Dh^*մҨP:NT`pJlj(>>Ymi(UJT%gUVs.jU,)p[Sp_wD©ҥE orc[4~jšW(Dop]Y?:q;*QB5^ם> zɷ'E0RC XJR3%ԝ~ oJrT{茮hY(:ej*}k HΉ3q)Džԩ5HWP=0)3i9bf@z&YY\,TyPA4)Uk%ܬ#uюgՠ`)"єl*0JY@3Q˖JU*>L[`u,~~C|uGJFSof¤#^e=1^;Ѵʓ?\c։I"٣!*ZbLܦ\V{v"|rs*r V$LɇHV!Sik| vz*̄rDE3W\{|=Ppἓ=k?T| Fiyiu/aHs՚ .koKp78`^goB2 ':|xrY$+P e$W|ީ,W A6:NPVL Ku[J,IRS2%R*l+wxBz BDl< m>23QH%LoϕT7KU;pLvJvJt`zks UiֈS zDͥjXZSQtI&P8eziSHL8|WP(}N`HbAKHPmq[J厘À@#9w!u^6IP4L=i7)IF*k R\ޝ5d LAVUi&S3HKDΈ!~PKp,G!=13}DaOJyyj$ mm[hZ 8a=qƒ_ILӒG1 +ZBC(8ìlT8Vf@ [ZW3b5z͊ڔZfJ(- ʂ$QMr!JR Q'@Yr xr) \طojGIYMn&{bMiz䃎#Hak(R9bxv\UPQLpAyòn\mk-vi.D.ݕa7Dʓ0^[w(Pʔ馝qMPmo}2xt@WTi iI450㶪|NTNy=-6EêF)@ (]ɝQp^di+;螃XCI,3gi!*fI{#NllNW-&} o,%m%N~nd:ӭڀP̘N0"{9\"ceaLi0N۟I*LG‡uey֥ Jf,bi*=2vA:.+R3NJ<]g y94)ޘi14ǦnNU0i'^0ʒO2qTPA>:% ʣ'==R%)4'0E ~L$+.ؚU:~(îGF"f=F }QQؾYB-3ʁptQꃄ=8ҽz%TRe3JRR+"uCs !n+!W U[\pLCPAIVJ.-iėq#nS2TUN@%8(Sjns2ޖtyj0- O:ySj2;ʖ#=Fj>*Ur8ZOWi B_ERqS\-J1.q-AyDXa\3@neqKt`;t۱Hl2OZLmrEf<-yDRrfo\1;j3`6B|;d->Rs?jpuTOxR5QߤS$&93K[ƹFYڏ[($6zˏ\d%Au܃zTjHh8r&@Vrdj]1wj۽Kjz$LnC3@(QRDf"p:N}fin ZI"dx"N7n pGxG~d3hB3]󇖜O2-38IEZzَ*;di+RuC!$%ZeխSL8 MqPux*S+T,866Z<(m@S"ReJ@& +>ؙD JR@`u S4zg#Ǧ3{'$֬kf ʒ4jܜ$+)i2ZW+839033!0Kv/'d2JJSv7V{2d!@mnh ;5,[>[b TgB_,lܨPJ|חתqJQ\W dgN\TC-א;!tljS({Zd4Y[O.G;QR~jU~biBUW`0nl&~HȆ@$tbǤ笚:KS 3޾F-#Ҿ4>BL'/N (%[8 p-!iu qmWG*4 낖Г Ar :|)Reyfߊ | l>ӝ"v6w} >t Ǥx'0LCmk5f:A,Hd-&C`u(HWvUN<֋3H-M*HD0ә$ע*%+tÇ ۴0JU9_{n}\geu%ܡ#7~-Bk Hɜ+pfZCs^ee H5STiTFf;Tw]qϔ/OI@g$J,Wc@&y:{}Pw|j4&XW@ҡRiLikg݌Q:e(I@)JxuT'QUk*zƘQmRHˠ8eNlU*J0Oi߃2i'BcAm:iqZYBEí^$hvgro],*104CZ# BYOpy`q8 Ÿ԰fR2^nx H*W|y'3>ݝspLAi(3[x}0 )XMI'4N2A=Hʓߌ0U-󏆑4S5H-uŃ;Jb|A5 :c-G6v̕-*5+d-Drc?vL ] >PϕR9u0F[:11j} lv3e9%$l Fc!SI -$ZnmJsNRz;pY8fQ3_c?Ff6R 6=9==1fۣ推DMcD Wl!;#)IyLW!kS%x'o_rdPA9ԵG^bte'ִJdӦ5jRU Wr8ݠ(38H FRD-Ak-@X>Ji q24eY7(Q>y%@ISM356Л,52YH.]'O-|rĆ줣`&PsQyu;\UR Ɏe339pm-Y3/fYj&&U1#]r -5@#`e`*i BA0g. Z21ZV%)X37##˅=pyBKl(X3TSos{sMLمٛt->2VPJk"xYx:Df~8sS`Md03$IehJ4NAKfCwЅsW\[@aLL#t_ìly>N.3mpk.ǥDĘivqԙ]\#+Fn@.L"h”JOΎ+ [|!4Ȟ8KwnNr$Q,BJDFLr '8|i%;)XpGGlZqg$&*%3*93JmXLP=e830xVA@ή4A@.4g9ysJ 덥[ penG _N;J Ԣ)(큻I͡ v%ɧe euypVUI=2 l˔ JV=iǏ`6TQ.ȕ.Q_.o厭#˶(g!]:&'5^}li@ d>w%=impťs!fAS-z*I*GVD%IRdm7Tr PU^dJHRtODTׁ8wYun%rv̴s H*Q2 MI:ϝ;d92TLlL Tr)fD"e-F-Im=kU!KZg(%%(z_)$-&@jZ? `1i%*i Uvהot ŲRPgʤTo ZD- R4J]ze(R]vՌ%:,!]'7%' Y cV6T@4'SY-79P+IJLqobC4a!HXa 6͡ JG3ٲ\6XʈRIyGNFw>RQ%xԔ3.v3k)86(IS~\pYl̷Te 4U9)]EШʐNQ)m9e9[hRC4nZ u u5r!@+*&k(OB3^Rimʁ&}P3٣">E7/6u"݂̌I1+ƙٗմ6eiJ0MRڌ.F- mLx!n^+fJM!yVdQI2:d`?p 8 aj0j"RKY,iV;Jehѷ:BL)erӮfJxmʨa `XՓ:i䢭"-2(qs~N*% 'B MHTҤHJU)mZgpMnsͽxҶɟd5p@*m˄2s6f64 pWfd$LI撯SeͧxeZ!SL0[Nph8eUL$t);or%- C"qY ^U~HqKgW>9~W8MNagun0jEp.nksm-[ߺ^6T1$ ).>Us^9͢җ35L ͣK:%I*D'2JBFQ189|͜ԦJ9ꄹn~I"Opuak}n:WՓ B ̆I 0nJZ}Jdte9b’O !ž)C2> |v]q!92 ZkXo/H"C]7r쇌׾`dآrʒȄJ13TUO9F{qjDs4F?T(4g-.l7xjԔBBYmM9қVI`1sֆYPNt[ai$ 158%)?r>VI}fDf|1g044M)SZ"h֗>VʂS< LTKC͔hi+̃hɠ;#Sknn5tIPjFʜy.ػR6QRA}! AF_YxOyTί%񤹶QD"k[)ǀ12È6, 41D͐l%8y`LzfR0 C9tLt Lq:Ne1鄸^`TJ34j3+1׫\"2F Z U'ZGReR,$)Ѵ\զns8\y!@3S ZY>h>% 39՛Ù(:T:-(Ω)k'L% ݼ:UeSS H%)%zeG?n)_lp@lY!C9ҡ["QM+)BvUWN @IiҖҖA )tEaKzـ䂔SsXlP dx6^]NTu]^}6 SdƃhJP/C)uO$$qn. +VOd.r2SmrܜaI B^$nRŴ 'ǡJYVB;6ںSͧӜ27YUAhqG2% "{j=Y:9$IJx%%6 uh*U2z)!V0SCng.ۘ'lZm/bRX2[#V8bpaH!joa ar!9olO퍶-/L/՝#d(jBY.v, Fu5jJKK$k^`כђ'&PeU#S[[D"ii.6%)9jLM򿤚a9c*Y1Eiwk KrD1m`n)ͼv$G?GOPڻʘI`4O"q_e΄'X߂@YxkII7Q81vؤ/TIÚL\R&|칒{` RhP^e4݂shr醔 EUBΣ]"ғs$yuMhl*dRIYIەBFD8&SL:J!/uJS$ʹqnFSpӝc HʤRUmH T8*Jצ7k983R" x!ۢ~g  ͱqq[R',8$k'+U4JpC) IR5l&I}K60B┤hiY֦q-\" v` NpPZֲ|< RݣNrT{k=.C aV?a]--'ꨤƎ!Rȁmb AqJQIyvűp+mARrc)ʨy\8R ʼE ìvJIi9y a5NVZNT%L%mY_VR_qCm'%BJg_LKGDp0_ xk2NĂLcmծxZĻk5NFEQ6N(萔rխܺC)IC C4k) !fU,ɲb?n "ʹ%rZ XӮɑYaAiηJR8qAX7_ܭ+8Mh}Jk+#ektR%x(QJ8v]mj .ѧh̬y@v ,828\5ut;3 O>]S5s KlqԚEյj\ x휡tJ.+ k@,HU*Q~6ҕt\>84iuB<^R`n(]PKmꪜUVO^}I^_Sh2ҳHU-%c"ې+Oɫc<4Ero8$&AIpx&I J5N=-{LQn5шO:i#H4;CW@!{/L2^`=]r+*r KM M%m'zD e9imRU*Ԝ"H HI=udt,U<ܻHl${!-5|7TU,2@p$<-e#nu Km%\O%*L?B1+ˤ&ϘdJ4"a 5k5a 6CL~I넢+*d&eٍ;@!vl[*RVTH"ݵ@h3fxC+]Sm6,SbL9$eЗ JP&ۮ"C 6]Yg:2cH0ZW Dp8ǮTaa;QrjH7 OA^Zq\y["Br3_ Kp)Qr FϢT/a%!-g)U n>ݕ u;0MI* P K\\m-*DTqô%gL(]rm"̐wM)8R]w4e<9VL]6mC,c͠@JF Wf]P V%RxhRq{ULGgѷF0VqxI7 a 4g!ҘJSL1\-SًrVd L4~0F8)YߏDLKTᖜy#K&bYB6# 2k&2'\y@5aHjmȮ(yGOVED^[Wb|1+{n@&P9IAp03'*JAPG8rqTĔT pur=z7cє-E v="h4k5bz#iԙxdqm9'Suo ,=+QLXSA-R$4FlrLӧUPcˏGw7?io~$9fC|J{.=/7%Θc]#AK<㚴H7.F tNPI\ؓ +|!>j9SJyP;FqaXR<@Ѕsk wl`ۜh*x]#0[sHןo98}8Z|Ey9=|&Ƥsk_]sUqq|K=j/f1ꏬR_)uGoA?uJ}bRTP<A"ϘۓĂ<[!Tdius;ޏ"_"$y5+ިwϘW.?iW\~nqÊJds ӋFw"Иc]#Gw7.?iCp2 G8G~a\7ͯύx:.{Df_7jW{Tstw<6S7cd篜sFU}`jNo1[sHe]#0YqH^e-^sXee"_9z"_9z̿??!]d*dvu4Ixd +c]UCem=8(Z%&hjM+Yx!h b6numVmEcgHK[\ĖZ?5}?**Q4"kOm2t'tZnbPbGO<QoADyyqǓ?Go<y/s.q?OǚO>=3;rc|ނkw 7ؚL%߹߾|"xc2엉r[_r-9l]/R .YqR 3^8?ט>esK/;\r}'7Zyg5 -2ܧ~,3+<#Ku#51+>e`E=z2(ohss|3LuUpt$s=}9L%Er,d21?o?|Ls.\CImq.\ǡ3=" YcԹxfށľ)J,33 ]Ù6|2&_^<1g3,SƌU梨&sJ7 }MgIRmDɊz Px ubn23O.kW~"q1At3iK_Qx8`.YNZ\y&d%8Opc苹zWس"!X-Kd42Q{<~e8`kwbWL. CO̦kPJϦWSY}f+Xi}1J.o~!eu#<׎`s ^Ljrj u\9?RP*-8鮰m B+kf?rC̵\rdY,Oi-һgc \ %Dck:\IϧЮj̹uS4=b/o@&zyW>kt+-n.-rj̰fΊȭyP5״Iv;D˒Ǚ}ĽϘewO_3~e-yi?:UO⦗,~e*{{]N49~ P~g=>&:>9G?W2ݘ_T;[o.^^̼g̻Ǣi'G3ї`W^%0(ӿw[ANȇ*WC{/\m>ӸNxK\} r}9! ;J>T_41]J݌%x=qb{YW_Xwǘy-S#qpmOةsq~>nt~F~#sfƜs8CݖsuRPP9`7̋3.8Zܥr-Ȫyɔlq#\,|NuF —:gE&6?(uiEŲ޾1-=oO@5qP)+?q?-W7;,첝>R2Kz$k9lJU^4ǽ%#F׍^/AQJ:K9?B; ZS9n"{`6]M)p~:7U?y}/޽1ơSTOy^s͸XElVfoi zÔILf-e]W|ES%#_gUg.!}:Ow~'ar>>ޅxnw׭=&\2RA_59/bz $ zp_{14w# ;~Bf[pʷou*u+q,}'_m z& US넸jՑ~ pWf\Xfhixk8c*SvS^:03[1/d6[Q8ݦh9ӎY~D(=HSBu}[Xc/6KplؾB\͞8:s9pA-I\2ξpcG-~q|? /ԃ ?q7}[ _=]ffzyoYq}R]gO--贴yil4ݞge7-֧噊W,/񙱞x9ybt93#8un7FwWok<4kFbNLvZQ\Hj@Y^(3+h݇Z'p|iY]Z׼XUsj#/4ɬoZtw:[s)7|״W2 Ku!̴մb ޙn8ic\^no㙸g|BOx-C^agD,:|!M-RCUv?O__2}|5*f[lKIT%~n5HuIQNmџ>'H9aiM[V ȘunWX^joxjgU~=ot#R"ܭsIT[s.?#^'c@[z-]x(&i0V1'tX!7פ-g*ֻ\QP4M۷yQb:{> 7. kq> 5:ͻM 3_Uin~֙{r[aʛ՗Lmakyu/.5+w`gR呩rՉR=}1=>./BZ73ncUvOڍS]|1 p :mq^i':x0V(,7FO!d|=PFl7r_WAa5_[ys374/ճ"7eƟzo㤡Ř[˔ՙ~*/ 5Ի m1+ | M^fۅŴ9kGS s_G㍡] ʩEQ#Q|M%w9[0J`ɘڂcKN"P_J:Î C}#0G8xB*\P/tJ2鮱낮u\, +й辋.\l\_\_x1wkrY৷$7[ `M5EMc\3-V+'m\$DPWWZ\4ak%t E{Eݒ%ScE sH廬ٛUU4Cw`qVn 5])kz9 0o E-Dݝpm+ٺq2 g31::9pUƠVW" \'ңCY]w`+(isZoZ˖l; ;=?ԼfwboVа. ͟y|;vD8ܗ>X G% !r1a[pђ>0KxYf!UӮ -v*̻!B jso]/Չ_,.\K'Txr|1v>*1O(ķdp.GW gNefw_b`/J%(P^5Co}Vή9<ޛQՕu}99  Nʠh9zBԾӖevY~c ,7Z=ƄtUJ:0_ܱjsecY5ɍ\;6S iG;+cdH5 v5,:<|y~.\^D{8}'X8,3aS'SJhb ڔR˩Y:?msr$ii NޠET넎un=3h-V QZ3B<7^hM@axlzf`K.S[]%.Se2U#;qrd`vbr?_lR|0AMC~w֡F@ٍMWCW_Py6Qv2Q/ehuH&0 ",4`gbK@q5/#P( ɛ{[%a<Әr<u,;.~I`á]tg"7baɮ)E0q@"T3uY,0oJɃ*3o̹eqXgۼ~>[3|ɉsY1+.\dx N^[ yin6W%}GR_ξv_`/9@4[tݗ;602Zak#ZlP|$A֠|3@KY3hwĨ7X bh92=Hb )ot< a8W9joo;՜-oW5#ED\}/4XN|7 l[ ƍ (IV>aYK,ˣ!E2q3g0m*-W-igjv`` ]KdTvnNYc+b R[E1mTl;"f ւw` Z4rEP-_TsBʥ.-d2c]}@t(-O.bU,VwVŭ=QV+2ݡh3f[.\̶[-.[-\r˗/.[Yn\3{4Mv䚞sU*q{Q,Rk5{ i~& aDS(ݬb_8' ģ0..y?$.An2%QD%pqFl9oN4.e ΁W+)ѳ& ulJoوk,eT۞k[1'jj\s|=#dw2i9fmnhuv jȱݦ s5qq?2VnRQ֥nd{(-K-Y4+@qPeuS|ǟ$`vDᕐ!猰BasO dj0l T 5P iX^]BUnaQVSヤd,Au<ˬz_y=S{.]/_RRR\r.Y,zHX1;OJ-|0J;&0<(u9Yg(R#IH7X[E mnܵ`=첽DP>ەW/ V rv퉅 Wbhʫ^U|\bg %EJw.tQ%v+c@ kenRl{u)ḑO[=Ȯ4fދᩈ& -2YxZ 50 ՗ЍqTvb{ l^[f;L0$؍KU4`ɖ K ]l ƀ:]. e5D "*aۦ& ՖvawO/yYs7#>r:Q-{+0׀8:q-w, ,fmGh:1Y?)y "!BR6VRX:G}_%y}9iƬ %䩊23WY达.RY20 }ä2Ʌ;)q`8S7 ja)8`|փ ;JTv3w(D &)e t~ɽrtL*ibg 毙6 ?UӛjUU][(QqmZ7ќ%2‚/Zc%Q1o̡XF~^9ԧ@|2=\v]/flwjcq?F35qˬ}C?wWYHt#!w}3 jlz!n' &Ձ[.rԩofk69askɳ뗴Wuq~IJ2_}$f:(Yp+rPA(Vf0+[8Yi^gc1g2v>967`5笝c ,w)^8PZqoq{/ˀ3Mf,z)eifaMQaXKɸW3ǒ_r|r\bˇKenxT?ZwScXyenUCuO+BLPPx1\OĎ K&vV d j] 16+Q]7iF3wmKaAR;7Ijkr;4&U ;'1qC8sYŦ|A/{ Zw?h.7y#kիYGUCKD1ƃ5XPtf-Rs#0^];#* gܯK Ǟ_* 3?x>>s+dodXG `OP>DjɀSЕgY^&4gS+ ,p ^; ^^:2I(*=`8..^EzmhdRYN\Wmx" - e+WЁ/d4wqgua[bYU^J 4b)Pt4y+$5K~I},\iK%˗,%ˋ0."i~64U9=8Oixp}=7^-epS=<a.z![ % ٶ)%Y!@t,=D&,ca2.TPh3B1< vڑ^3*\ܤhb [,[h >@} ® [`olq;wd=CW2/A3@Z`'Vʳ{72sN_5^EUk1P f-*sQ҅KUM t0h>%8F ;/i˃/sp8qÈ+܀izJz&lD6,LYuwryu:Ujk[M2Ch5З̪[g'gJPV "&_\(t>aL5q Kv09}SelF?i*a67] fE BsP6FyUGQYwhQoe`(쾱OLƝ,?=pժj(b;W%Jφ4bp!S cT aN-k *p4"(gYf仛$hQuXq"` %) m2n<@x[.jOq)8_ ZO~-_W⽿a&/XPuAOTn{a~Ixـ` so-{tQPـ9^Bᛪ ]mfSf㗄-arD,ݏymabMEbB'69{..+kuK2Jv-6?f*zP(+uhkK=5zn,2ȷ,KjX->UÊmT+*tG7k*MTbvj^1nai .Rdk*-TܮkiyҴuB˧q&vxPJx⺀f\/_u؉ft\e: J򊔚4\MsF XYe(mQ]^!A%%uRB/>L! Yufo^ _p,`?Tp!5mR-Scx z*We]ήp 2͝W8jK.뻃{U>A23QR uL ;XF>ֻRhvԭ&Q~K*\F¡Cla!Dঙ{B-S ToS`isrgC& he&bSGBnRie-5  hm{InIħX= <: y2Yf[՚ҙnCzg8֙ٙrsrԜ@낷KM i-Av`,g{">U s Rt /{TK4ҹr iӡlWAv&!Ҩ* !L? #Ѹ6cUhf+ Nj״~ hR cE^u݁h|K.FDvqhCP,+|hc/#HB02]FZSU!=p|1V#y2_eKY-B=vQ(-ﬡKuqkw+HJ'lJX;{C +Jp<.;>Dr]W󇘢eIf[(pDzJA]"L1!Fbd8Y_d\|UKҥ v[dvNgHJ I3k6Ty=:X%]{|c2vp=%xO OuTggIΏ~1\ܳ. K<=a(xǏhc qmJix9EŊ2*੃+[*ZCVmw5(n#Mt V] Hemu52$m2q0]/Rk{1n< {[@]5\qųjT(l/?ܣoJȃm )f 9's!d/? T|$qz!F,X u]Őc]uT3$w8i7i}t Lzgܰ. P@mW69d6TB3B((7X 7-`ꗴ-ző!glZy(lKh @bg 1 1Ed:/S<<07 "!!Ѷ缡.T'(/u5 4r˙Q<>'p-Ke۬Y~]=|\yXX^ î1Nqe=1Ю f&eSk7}m8MrkS u K7ԇmްok3h_uIRi.A,`TWT1{5}z3\ipCXZu퟊iWE#{3 ћL.Q@Eyi|ԧ\\\psRҹl@\:z`3sAUf)`"ª ܆܇WjPIF #r2y.t6= }iJeF9dswBbdibɯ*7zo*Rγ:K=wƜ\S#-ĵBwQ:$Q{Ͻ˗r`c>oyOl?~e%~|B0iseb2^Tp|G82ɨ^h|[ЗJ P2TUF0eh8#4"n+,6Ñ#aj%'HGw. IX2Wf}r G6V`2/yaf.[WX u VgY4rido0A^|bXƣLjbJ?ݎc* <=A0 J&ei lz+ڽQ1JpfbP?O`P*rjbOi{A%g<} 'SvQ3K.}?w-r߷ٙ{yO-//p{T/[_[:ML":=ڈ g)dAFJutP/wa@tg[rEgD}۽ޞ 31mvltN TxOҷ%Mrōx.NEE qc|s]{寝}Ӆ8;ZYj\aqWbJ\aV5wߙBcL"= ʽK@pqr[jaDi4j)z5KU'6tۅls{3.瞰0)}[<7לfafN4ߏjtoJ9'j^ fXo7/Z;= 4CoJ3yk{1'_Ki<~ap\_~-/fx?3)INb>_:-oEPPX3vB Cbڻ 9Y]ٞJ@L*;vҀ3ѣ 8)&dk_hG]oD"gfjluof:t9^5oWf9י7w;!&ݙWE:qnekgUYXr[YPa?FbkJ7iƆYLg-R/3ϙ~s}8-|>=5E&<=>rN?K_/_N%}e5//ߡLw//̾{'2KV3E"ÕP3pth]9k5bǹm_f34SsMZ˃qhJb cɞSeF{eIW.w 'Ht69솅 m=9t#ZTf<]{u5;K*2\t֞t_Sg9du$./Sp^YuoO-y?smqK;yyS񎓳^%in%W{1-ߙx|7/1yߦz%z뎲_2o/}Vev|v!˷ D4w#]}&~~2>yřuIg۬ħO:v^ދio3?L2uwNϲKWO._lewp~a.tNk̿Y#_>%?7'Qrh?o϶%u)cs3>sJգ~m (lfù5)0^N+%j#/^u/̫Cެ]R^Y}hwa!N{w}[& f-a0C@+"[ IPCW 7__0 8/(BwdC5xT%$=.jrcbp`-׃-K`q#Ue s2#`񞤽ς3ug\]uנ_F=@/_ĹytV_yͷKҚ'Y{/2.v_/g#L_ߣ#gE2eg/_$ZU'u^P ]=n!%CL;Ǣ]xsY~&NϿKǷXea7oSOy]g'^XEplcLCo՝Otq,I5⮁"cTn9E u2̗ː4[A? -\A5>:\s&+[xo˗.(W,u*yrPyK~K~e&1+oXsqLmu 1K 1>~/OPKcEv-)Vv? E%j|QSi}[ g$/@q+".򑠍g~@yk/D. ]m ˭t?gY9loи䌩L.ۈuIU9WJy]>D)o (-S!bјvºOxBr8MdC-T*=,~{K ?ckcS߼ҭ~|K?חF{]z>ƅy}&UlU_+jAp(Z( $YDיYR坂Ӎ_JazmNק:eMGuKf5ZWKm.*ˮKuPDA+V) Zr!Vօ  @^Svo@:s߶'G̽ܿo\KߙoX3눢s~crA:?lϼlYuw=KvFNҵylbU|/ bel05D/>Դrs\&lªKۼI:?Ou-wz<=^P3}̴>>>=iv_[|2}/ߧif};}~ұ3:'~ѿ$geaذTIT.L?QG+uЃ&0baSĿ[I]z;1jy5+Yn'hh-p1Bh0ڌ?@Hyꯡ*-\zhM;>>O_e\frǜz}}eO3oIo̻Έ](&I-T 7\',pɎؙksS}:P*pȶX\#3eVƼ_lK宋[,nTV]Xq6L٩,vs O##׶*լdt. .҇i̼oOwR_h=?쿿=ߘ?o-^Kħ7盚^}n_ļo,X)} ?d}\|re:_]ʴ*Gl|S}Ygn-z  6T]\`l ~7GCC=GgSCMz΄nf& #9zL;tW=PˌLXP&☜GQb A]򁛓%UU|_#/Rx5.WWSɏ,,}W iRϼwwb?}11|j[cPa8))CL8 yf٪Ab}<@e$1cRcXoEC& $ (RXp3>k&c4@zL`_XV8'A){iFPe&o6y]x -~s.37qAĹ~̶Է}t~s?x./izĻ̻}or+ٳU\k,eK|O ϲk+=h$w׀l<=&8^JsN>WZKg zBBLwރXNǯiklu㭞{cnřɔSC{ [x)fþ%rʻkcksd^ʖɋ1u(=RVLe. `Es?3=%"JW_1W}[~\Yl|L=gx_73oAsr3Afҳd˓"U XFˀ(^Tda(ܽQb ՋߵDpK9lB GfiªSRsd%q.NWM9$) 7gs<_ľ/.礮{K3Sߤnyӻ+Y'ψkh{NxyjnR[g?F}CA ^{_qokttܘqO Bem` uNnˌ#khĥ:R6acŚ1sw5˅̧ zud'89<l$3R\Z|!Z\θdJyS\s>lۙ3ݖ˞/+{x0|b}sy3=*+Jdv8pd~Y5{KO̊;*6U2!(Gc+AP֜FVtr{FL&+ssWc#yV8P nʺOw8a}wg4_}-_`hi~`JZ*NdU_75?sL~?Px>5g^g߬]$Z/hb |ZלLus= zWcD @p#'eHKt8+FEn:~a=2¨5\AB C'ABS! ?RK}X64W~ MV4Dgs.1G-ز綧xg_+ޞN^5x5qӾ'lkˬ\sϥ˗_Iܾ|}'ż<2X6UYP9ėEuuJx) 1v7Ŷ%J1:#1b\kt%N-+<f[ ωe}ǕTOP9tƕz:R꧳LhTy=.[љpe}X=>pesN8 ;\U2`|UI901D<nbzvW; *IUc `ф-&E>ٖE ,ȡ (~ب~}_r}K/̧|} pGǩk/>?Q('M]u#GA\gql]K0h0rUWO.cÐ'܊^wՖ|mn˲7[L t1m8)pnˤu\àfcmjw*Xaxe`Vjv7Ki\^PnGߢ ~{CV%s1O31s:Kħt _7ƺn_$^;_W-%tͭ6!*Q#  lJs 9{OF\+?B-I q+ G0UKr< Զ:W%XM[t)͑2-xbOSinG[h8rx}^/^52.YmH0-QU)zqbV%FWV(J@uOEZ[][-Ľ+OYoOEN|s1 Gi}JL@^0s/t oN^[@TPXP2T6`)1wL_ YŽ )GyD꫖8:~)1=7R(V 㤨NwdhR\t|k1IK3CPoO5\tgqwouܳMAPڭ3jg:/S^~>fR<:c3Zq/ӣl2wt`٪V[q(-W$ME9#:P.Fekrw%4^Z-e:s3QW:&)7) TjK|0ml.[h@;BQ+o 5 Ð錜Ӆ̹يф.c_Є^4-8IL.wQjZ{߽Y>ӗo_fb{ϱOt{tfw1{\1;c=:7Z,sݓ$./&yrA luRO|BdsnȆ׍3ܱK<5>KĜ6v1:4|*@<}Р{:{@ 7 (5\"|MH 4ՙhy;^uY mJ-Acс>a^xmL7a M:/]K&|c63]F4s_oNRsr?}'v}')T?+c.Y,.\ǿxjY.\}%?Կr_R~ɗozsчs3z]LA)0UpHXB^Ģ*P۪dT{0 Kh'g1E\ Tqrb/xd@ݜd>=Ttl 1ı7OAe*CqA\)ߩp艂@Q26:Wsez?l-;e׷NGwy*[ҥvÚDD` !fŴ6e]Dlp/ bX@,RʎN~%ym;!L-/5yB0 yd* k/GwHsb]Ztej}}ijre7)ſ;1-K[}ؗrج[ ~ 1\S_3-/{nU9[ B3Խ:*_etŒ66p|_|Bۀj9Aٕ$G9Q\B\8Zcj'wIBeb. J]y*J 9.[ZH+-^Ωȃ0T<|Xp*_Ht,|SL욂. \o"C,8N)30T(n>)u̾>SϏpJM#F]CiX[ġ\ho)`[ux)8U0b˜Ҭo 9v,5w*_nQ >!y8ҐEp!`. zDW"fJN\5b-{LBMsJW(aQ-F( Bܔš4vӌ Q,D䠂K{E.ZX-ŭNyFL GWr4k+~H"hrap8RjKtQ2t3Nzc{wvzP{8釟:@ h=\e̲VvrcQqLˇXB6s0Z)Y ڌl6N:Aq)r-9x0Qqv 4Nθu׸[<Ң0JgiqZ<{킍LJ,6+T^eQE=3_rϴ^%idr垖w購ETygIY),dU%UC<-5SR{UVs ZR`zľtl_=0\)8yYYQT/ \:KRPa|5SÏ=uɚlӋT*`1zhFw)_e9ya+&p.#4@':Q+Ek!łEk #%0"'əg +i} W/vT i7T<1e$xԡJz{ [+0t\\wj]+ݟncon|̻ Ke{KKrrl[K|K/˖O p/w-[/v_Q ߞngQ5 q->1!pE@" mX3>(a̶f3x\.Zp⸌ÕZ,BDa^S*tQ.#ɋ~ !INC\s\p|}/ 8/`lw/'~xf=f5x`Y`T]ʨ{ʛ(ħdԷsr c(ud8\ Z.ItN)X5yR*wl-=M1v8<:Wcdn=;B\=eHnVjR:(^U٧N$2( T/tU3xU(x k*V^N} 8(K*r sKO 8:)(x-b _=n$T=_B\JW'Ӽ2lYoYk:Kes˛+s5̹r;%e.:e/bƁ(zFS A @Qh|EdQ_u^W\g~nI7H"jtg&M?UT{rG |MGib:FÂ=F!(hR|gH=dCrkqc_N+4AZKzaN=Dۯi}5 uo_P Uh=B˩p/ yszrV'#6 u ֡> I஄`÷5sh{i++!@WYUjr,tJ#ATu;l9ħ+F\&Uy$Y*9ͷAd5Ъ xy s(]2` 8fY4K&u%9 .[-oe1}?ߥ|2ŗ[}e˗_y._oLˌop}}ǝO}ZK5эK-i0%RPZNZHfJ֨-*yo$P j\g2Д/[UtX%td3e[f -tY(Hcp4, svJe!z6SuuRpyyȪekԘ0o,ӧlO4S:)Mv6X߷2M?4ӆ-Fj]U'!KbB28a%5<$pwl{?(oΦ.@P]EXꁃb3xmD,bNH&ԇ"Nj+(R+qt"djv4̾~M_ZZE >.\?_g']櫾}5i_yw.}K/koo/:ki= (WaJETV}M:=؁&fg)/ġŕ/RKTNL?ܾrOK}{k}O%:JN7XYgL. ZYpJʹ`fl ŭ0 C!hd*(y30#jczcnhs]jcMy%,_HĎ 85RL/*"9'.Ba˹Ap,ıPVNu9(:B@RZmG"knf`UrB8l[Eٙ, 䀬H% !PѸC%ԑޢIjZk0,h-Xםr݊ 8/iK ,-btT5n&._'ӳG6* qgbk,zȢӁFWbնn5y%!7JvMj 1}9ۀH+gR 1qtH8Ese=.8돾#+. qFuɰS+93Qš5/]0BƸc}?_/i}Yr} d}z_'q/Sܹ///ơEmjCV~a l`ͅ]oD˹_n.i`ay'@uw8ⳋIܒa  ӛ{ǂ兛ؤ`qxoO VI^;(.Gɍ|{hπtⲔ4z>wkOGg;?s)W^?gg+,/S=Ӈ0\>_a憎C@?e`pZ؉xP4CcyFq/35Y5Hب4oXJm6K-d Hݕ We̟ۢhf<|âR,*2+ڪRzUѵJFm|FT$Cu]Rek2e%_~Գ_e%P&Y8X 4Jf63ꯈ:+cNc[U%hN2%sDI+S 8d咽 bpJS+Ґk1q8AKs)ŴQTRZcp4K,b zy3|xfbI 1߅+( )SsdmF)^KBRs`kp Ut$7-G ^ yFqK1e%JSeYGHXH(pAѤn.ZU@{ 8" WdtȇNKf"7$;:/1rꙶPݎVK(;i Yé+#M*6!BS[V2s0X󛉈7t( +_{|L*F=3&Z3W0"̋Dl)eZ g (K8<FPCУF=i|~ jΡ+Lx v>bJe͠\u, y!6$XKៀQ%xqvV®ڇc ̑%Cn\*S=༝m90G|< fA 6̧4_#4g(F;"7Ȁ].H~nZ6$ …T=ae*Ypr6 ie0Lg=$買(iPiUd.QM:ɑ9M++VY_B*C$j{²J2xewFl.ARp˘9 r`!0ցvFLr}\SgZg}K%gr/>%q{3css2+pl>u]CBXi_{طtY0<9R6fz<2U|♯ fx0jΩp(;-Xݏ39x tz49:C)4l[(2вb/Lw| ` m 2RgM kn8n⁛cbS_cnʷn⇺8|Z@pUN^1s 7i-z Fi-7-Uā4,Oww6E#qD_aCco=#<.Cw̑a.y.Y9lMd 6]PHEɗ@ҙ]XsTP,7+4 K ]!ydTW :g9evеQ(5ŸKtRͅor"pALfݖBklF`+L쒕5 +{73#K X8ljrD(P,Y4Oefq ?"dB["RZ7kS6Eq mIybDClU4ZmB J:SM!\hs5%,Hy8*1Lഫo:C,қ'MiCo!Ǽky  oNRAԿ1n_~ "[-LAmϴpїE3btm-T6LD Z(t)jKkojMu˗,xXʳO\w r &BҮ/b"xkG]13YcMs*)jK^vviͿeqѵhtJW^B ie F!\q tC@.M*)r ֽ85K֜jQqalolx,:pv8Ɔ(Њ7&m t, ;n$K*:Mh H t7\l*@"U#b[(+{|Uہ^ R1&F0:9P/!{zGmb&Qto<LD2QJ{ݜu^i7WPdH8̴Jzfb]s8dj}ϲCHVR{TouJ c[n){;JPfM]1M6;Y ]ƛ4Ɏʿv}ú "RB{X5a3/.greajCm]"b\5 .R7QKr@=i0h ;jK.p9H!4%(jsR69,Uլ\p# x-4EwgD9] w5_D 3z {;*/'^^@CoQeۍ\1Ķ1pβeI+ <ؕe^c屒*vטx9Tյߴ  TqAPick*a sf-)[cr *h쀻ӀӼp*3 mk^-Kچ""b!"` kDYp3e&+qxNQrӘDt/7D֥E< X8'?6]C[jlµZVjMD7S`=b*D#U10uMǴXҰefHπYQ%W =㷻ڗyαJ*x]۫y.bh,t.V )6\qvpX4=qAAn.#D^#S C2twHͩt$vo>-/ c-`[Pֈ bY`;U1ܧd)FDAgaW|`7f\xrFSYG }Bzaj3$]kn_$h*V&F%x`* J'O}R ,7 }WaP/,&+j<;Υ\;&0#i͓BZ- sL&q(:aؽ/y{)*ƏD HU27ߒ-@EFV2.Cuyx9 2*,y 82XzE:'/@n4׷i<}b&vpY^+tpbr L%_Ok-2ǛQT;VL,-apSYYX;kM`22 Xayh-`{ # FaS!:!*ZT@~_1nƔ\זE~!U̡ {(%+ GAӷ1r:p/z8(Rmk-:PC/0\ lfIaqO+I{r'۰[Ir+:t kUBW:lrT3V]ud&})fy<_m<X#Y8jW d D*!rsI1$6g__qN`FحrQt`;&M _T<#cVP%J6g+Zw G\X+o0x2Ūf(@XZq6&p a^e0\4q@w~jQkuN2 PͽTR<۰^)`w7pu1 Q*Л;B/Q}ҦVB,/KYplX:^;<Ft.>i"i˱keh.a4*&@F*Өae3F2x/\(Z$ʶW)@E"}P̼;/)KW0"y!*@`UUf_GN 2ڼmr5q ONoe*]OIr?$t Ay]q{z0W*=X?AK( kmw)c*0t5-!,F5ZRʽQVn@b%u(JJ"cB~BTXaRGyi~GU$`9"őS,29q)%>  :9ԆMd@T)T7a96`5fI30 AEVfdax|4:oPZ_A3g"O5mz4鲰=N}IGP ܈ULm"G[PfKi͍J(h!+brL3"T>Y@A:t!&D= 5zqņa_55իjUБeyuxRTգ.wvso$^i/eˈWAmYX3Z]3mat;P,e/8.9UiG>*i'-9zU5ţov EvNQQ8j.C|4|i]tB]E'в SU\\hnaw+ĕ(28zM5CNQ<}eZ]xo9b~}h./%rc+PArӋzqk4J***NW(sg}[ˎL3~ĺLo8.@t­*եu=K65NaEzj᠑VDoI{ue Y^fr9m+ԁhUJP-VYF2ң+-:1j`wǩp#!y:lbu+ktM$%Ue|.v Zq8Dyy(ҕjWLi:'<(H+jKy]( ]٭Em̾Sy.uy\ Db&ıuX`$L8-߈XFN/\JYEU:A85當PDn4uZҾ t7+&bQѾ_ 0 0 0 0 0 0 0 0,0 3, 0,0 0,,0 0 0 0 0 &aea_/R++c.ng-s3s+__?s_z:ُ>_Jfe!r˗/S76%MLJ_M}X)^^>3Cy*W~=2N_W[3?9?NȤ{~a oNJ?.%++~+W>1E}wTJϥ8}~n-%יILs?D3lQuoD/a%˗.Y]WhMsUVTRRRRT_MKxW_üy'~=^u5䁌~׷T8;%?Qkd}mXl,ޅs~Gxul~ɿBxͽ }+I'?*@|%z^=?S^]zoя ow(u]L:ԿCnzKWpEg3Nfy^ӈC aC8ߏOEa̼KqL$Q!!(ja&tK>_Hc.w1O Ruzm zp/O1>%rS2{}75o ni!- (u3LL)Yϼ׉}%uLk DF.*;}}3fܯZMzc|K)q; G݇735or6IcQJ3I~KAw~'Ϡws>qOJjCQܿZF's^g<%F=dUߧSrG]ՕUg=r5^?O4bPOCטc$ 2]bfcђfo10kqj7gUCFyLƫ3^aD>Hׯ1=Dj_.oyu?^/V5)L}L?jSn"dɾfV6կC^Gf-J+x2.ެטFqRF}iGQΡbq\~DYK9Q733Y=3HG'~1̦[?Kls08x:@" %=abf~S}|';=bN-%GR*WCW><1F(Ru+~Rvs5`%7)`^=(xfOYVy}O/?^\Ĭ[f`! FJrK.,љ=f}/ bXn y]%b =:â_E7N nkc;"df/ 'FYf5SG/渓R-讒ye?K`0lZ#C^E3-w*}m&S( wy`KzJ0dbYçi/gÿuk,3YYGǢao3<`1 cD ^%K0orO p(Ez\ϴB Sc/3.W5̲ j\/UF8}~EEK&D5[HP %T,@؂SIzzc/N-As-%{t`0`^gl_CwӘ:Coc3ZҐ:z8syba~z4ɘbR<潥fZJnYľ"vGS^G/l'05>a d[zPG;2@3uzYE7.Na aw)s%rTd|N=,b0 0`,X`F[!0c'  x~X 0 ?! v%;1bqMȼEd[aK+< =c5n9 TE|C.C RNH#ݠ")-EaA|ƣVaۖC܆3eu1ome2r<Ŀ c?QU Bu<8[gRUε`FJw@iJc]9eӤy[8g͉E2p*E%ujc0^nS?~ESSx9ECRCElPMEl6 BpIA9 Q1"BM0HVh!Z,yyF٠59J tML^߽{62&ŨZ{vs~S c޾fPz4s3p ɸQ@۹ZdɃ|ԔK3/D>OʱfCgK]Zi5شleտ uģ& ^ PsѽYu]4X(֡[B#Z/4q%P]b= 5*KjΥ3"<P<dIRAB,*#aykU`h%X7 )ox%Qa 9Ak>lM:ca[Nhv58ý8FP6}!Y1l`g9+o.\9+uN"g6;H}^b!G:ß(,5XC0Ү-5*Ħ΅o˗\b_&#Wש?I cj~gvL}7~rş>}+ٹ~鮒q˘ /q<^._˗/^76~z;q.\r bbT5#f}q_rOw߭zW^c^Թrs~15ىR* _\zrEJ*TRK--ģiq rl"˗.鉉rM?ļ"1ǥzI5F%7ԯ[._z__CG &5G>dLL11*W=*TSUסïcꯣ}13ӏZsNң*;/Ϣ7~=W;ݹZz__/g)G|zTs~.6jk6%%˖Eu_ %OJ))=h^ ׉_o\Qnc:.Kn]!%uzvWEtbޥ |Dnf /EcsO#xwYQ--S^cbX+ lͲ'p[^D-/-///2lqYVhpd$l1]rz5_ZW3/A˨RSpE\vJԫFex5~100F#L *qK_ѧtj6} ncҽ3j\-EK: ʹ4}<kZjvF6K%uǡ"s~#h5M;JgoLPܯO:GnfoRjWI3ƽ/no5i1z?~&Gr2_M#6%O2OADz}:\Xo4͡j-/g)ܳFerL˚Gsӿ0-ndƓ,ʯ>ϥVXDbu5mK8 }\;CsLHUK=ca|M_~uיKl`}W2Dw^/5ӟMͱ@_)Š+*I[؉E(|1@Į]sO1zTQ4͑(Zxw`wd7;DW/@c\'y=Y7uf\_b]S5@L̩C(( z[* o]$eS2霐[NiR\Ļ*g}%wQ Ђ95eհ̵}RG\SAK-b%<0[Iۉu{GbژEx@F3Ms|i %Pez3D ۙ%dGT)uq,ֿˉF^`rqf[2*yW5ҠTjfKet9hZv4յw){XM2AqrLS&#| ~%f+8AN uLkExz+/x&JM\ <[oWd80WaZJ?58cN:{Jǿv'Իqy/kEsZ>D p{; ohk=џ oQ5/M 9KIVݸvܮ^#{8qB},5;(TjaɈSC~Տ[zm0#=CD nu?S+7z^]#eߟΡwL^x>Xz:PHR,/ߤ'J8 ߬_ce:t#Q`ySs) ר!flL@ `ąwvm4s]uQ:(%Rʹj^$Vq:A;m41Y,q"]=Ӏk(aAjR>&% qjjBTE^.7 'Ap׳&Qƈɩh ``cLV"Ee ohf1Oi}1+ ӹ#ezGrfAcɥ%%]f Qmb_9^1+&}x˽tAƢJ s\xzEK8wbUrkeǭ):LZ+s'XjX!bnu9|=YE_%%310 q,?LڇCdNQJNJT7X޸ 8 .V/>8Q%,Wy;31(٣ϣr/kGYTy_M̚eJ~: B W]K`N2/> 1oZ8q?.Πc׋ [ `k+@{1 28?hJ㼴gT3eJE*OdpRІ+EN%w5EיmNR$%}BcRO]Nud%.$npII2 }Z$XhBNp$E2H:CJҋӪ ǒ 4K$;QnB+.tN!NʟJ--.|-l'nẂܻ oRG4WcIpIY(Ibi C=ڀX"@/$e$LjM*;ؓ 5smrIl Y`fI2)J3YHp7؃~K;u|b8˖H$A1M[|Y%bAp3t4glmiK.d`B_LZD %rO6~܌x:~hgG_l6>$`әx[ 75 7%Z5Ԛu:V3⌷p2XeKmk2@^4d Y8m#2/Kbt:E-٭ RzLIu{d +ve#z*^"luikK^wƖӾ=޸>M B1-XM $I% m䙗hahY[oem K?Mo[j  npgk=kH$Rd$,˅bn-bH@N6)QbI @go[|[$֝hIlorymɫ+,&Ӫǻ}Jd5o-ۧv[[|(ED]5'4H HR0m}WkgNT&ʾg$MiyYet"So<Rbr}ݜ,sw,iZl k762` (2H5p8BMq ~.z&  Ii'GK'~b˴temi ACH4P."RImAYDiim;VM4%Z?}f/ӏ7?7˘gk@J St3R_'{$o+v@- /grIlRCS{B}ͣI??^&M}6e4Zc\AZ+[dY% K՞Zf[d`vҁ9z_eIO?YomY&:0(k{a5k5Tߚ;{{6S&~Ji|*owԁmjAJOwi{lWǿm_IxeP?H:EؤIKĞyH$/e!(;#B3!t̔$'jt$1`"QTGM՛p #yx}m ~$S5+ܗhv5 t a]=RyW %i&S?M#uZ맊D(G9n}O7NӰ})^GFGԅm. m">1ZgFVmX%=/ϱOxƞ$B($!aD`̒(r%;`Bd+@t`0HcI:(C!;7V&S( 20Af!Q7&|f%V[qż~f[l4u;#3hM%$l΀=@_WQ%!ՑLG1.yԢESTqf/L_.MSL7^m"@0`d{O-yCd{`7â,Qbx!#H q=5,,&UbŬ2{5Y "٣*ċT3y+ Xu[`;6 i <*X4`p 87Wnx u|˼]}q琗PiUl=El^Ie,iDES.\/] PώPx_DwЌ6^=cħ0Eͨv B6(u;I02bƇdB6釵*H͒CZ uoas2I[eq8 PD*mh0nn>kew| y9 f'KŁHbqpQLkz*d`RUHcoA c{*+U`ܝ݋80`)O+ EB@Mb;UeI"^(}\ `+8ʱ #8$# *5Ⱦ H)V;svu@!YkGx^Z]ČHqVGXVRIBIVe͓;}.oWrn~7oMÞjM>J=f~ePB Ӭ"jFZ>~>& asv~q龯u|A}(nHY#rV.׭C$W:Nb(o~֡M[Cwv~&Rcܷ1U&|/3>UwΓ!uPZzr>`R^?^@Qy9D]d4kQb$57tpUm6Z9}]#aQ_=AM_P6[v(z*Mf'hukap)x)`P].~2 w08Wܫ$`2B"&z|~7--կ2e^n9/+ǼWf{TUtՓ}wOJKY?{((8s?dZ4^`»+*%=_$k_˘9<`Ǽ,(n+9|SwyXJx.5޳rU3ɟ9 5CUW}/Z3j|3erǼڷkO )aCҔ b;(Gƭ1P#gDV)P'm9Z;qQW;ļWkg[z$"5һ{KZ~g4&&b;|!86qF=UvɋAYv-WU5y_2*/c(JRYh;WUt U*iz PV.j e@6 jзm.̺a!JoPq @o0,E~gh+4/͵[*K.Eff^F}௺U٦[OR~-b0)*vR~njAO}NI,]W}FWQZo\a{h +mG}|s_[L>.s{q\ʼ?t9E6ڽ.MT4;Eˈ wsg=3 ,>{c|b)Edho??="ԣY.2*WpqO$7881 ʰU!2/~T |2(r~';1L=ne ?zξ1iBO|bzV׻,յZ hQ  ZbS%#qUOCA.ɜcʖQk'@ӑ:D jǮbZ 5<  eq]^ԾW+P;B6gn`Z,߽)tvm ݯՈZYs+]A{p*fM/ XpɃ3.VS鮑wޣ-gCT bEJ`-qCkL|㴠řDهN;$R*nnw_+7CkI?-5bӭtvqơX_&·"1YV9quG Y^UsY{T0 kbgMXSe䥙 Lh1a4f1X]3bBCoi}3= Wr:%nFc7.N@攡W;.Q@ & {&\0&8皯5}ص 񮽮\<;<<*v/' 7qGCN/ fFt[1,wq}:.:Ct: ~ %_JLд-`"MRqr!}`Pz@> ߴCIJc`"ɫ[WR]eyeX&Q\紳I\yLR#ҫ,A)ʘ, 6M`nPN[ᲬTE]YU0 b YMqpP"T{{ƾKY^j㯌DդӬyhV'[!7VjzZQ .Y.M vbS ;Y2naZ:8XbH8\^ iam8Ql(Vjڵ7I00ҊsE:S73*m9FL@&B:fZYwlcb2VJjNNN%z90,(`Vc|ɆX4Xz>e?Y;9xlu+/|E>4XeE>a#!Wbӿk ѲP-\WR00@r@Ĩ꽠xs)7'^&u ZR#c0V>)^=4x)\뙙Oo}0-7Z83|K@wF{~, x 3ˁUΔGmc-nU'^NF}T+HY-Mڠ coQWwA6Ƣm6O"؇U53'xgy|CP S*4q&jƊUǕbKyVLf|J*XBy(]D]"8 xt +7ASW*n8)WB;iuR$}J7-uQly,u!쑴Z:TĻ,`nch-%g1A,.)")jOk`1Xj3V" $;grYˢf¶ -T ʹv e )hJW/Bwmi@qmwqួӈB #j6EqRʸ-ږ`.Ԡ>bhlBJ9K˖ &T^܍R4% +AFCv_"#mE.׏f(83^ëg7 `?IUKo^?5LWƱԵ;Gyvt{:~>%g3׎sKu-^6|?PnW[؀tuaCKr!{ Z=/* ll0WX*w2 I7g-[f{.SWc ]Pf#/SARUmkKZ,sf]+.\)xJ :1K í[3jFéXZW^6ƨc<jjf\B4ɂFzaZ /}Qu o"Xr2[d_.x%XU%b+5ϟ ĭXJ0]6C8k/(F;j86ylvū37ѫh_;{al `>J cqr8Z׼%X 7RlfhPk^[udZ:?% *8puI*CR,n&t!NrilRLn/xv-ZxjESte^$l ݇t+ b(9f ĬgX Vi_l[UzۇX%NbZŪ_*#qW4e&SrE*s~",MUNbCטSz(kRʫigG1@c1vnM,]%y.5`6e T@ .X.s VSU!el4a%DlкJhVc(֊԰Uwd;.m{ا uE 鮘1(MK](w0e6wH^vBıV /CZ`XuB(mcy2E3iXTy3[ YUx 8YZfU֌iJaj|3*V'n7*rATfeob8Rhelet8;Ġc#EFo[ts+QszۇgNck\oo 3. LЫ/TCڵ_b^s7uk>(mޯ_?V1[~3^o[So2*-Wk48+8k̡WvTLx9W]L-U~dQsX=31N+Fz]e)`[<{b]?uԶ쉷 4Yޖ D(@/0iTZҍGHaau\EƗT[T2KW]* F0i9 &=VJNp1{6eWKAx"! !Po*jyRS6 fLyLBa1vkd`Zk[^vಱ(Vgy\0ɪ8O@‡*rpIQ^EV!S"m`fp=mn3UqNTdUHٻM_6 tum&v F1E(nX=CQCKk,Wj.ĸzK<׀U^3ϼDu·U'pOmZx?J2P]B hp+QYF+D=&0*uc-T-yqk|ۤJk-o)?=S3eXs(ޓ}]'._ݸnrRc\S<A7*4}&TQqI`xPX@1jj=AR0qQw EYDaR85ZBpstoiLTSl͕,Y̰"m> TjrAIWƏ2gX2%&H6--%# f,p6us*J{^|lj4}ژO̵F,; !Ch̥Xa16n3Jy v#ʾl]-} Uu\)40A< fH$`ȡ0Y[׈N^GCBYB7{;zXJ-ۙbCPUR]VlF\M;EBEd<ĸogT}g1Ց&=XWy(*M a!M{JNF#Y0Pl[X}y[y!GJJ -62jQ (1iJ{ kl\KPiWP5/32eaUFnx%^@P͊fpm [AQAYQ&V ؈*Q]ZqE VeqR_q,1w(Dfof4X5X`]j{Txͷ8Ȫ Aakt13DR6[|QNb/,J߹}HhqcOh]r?u[ק_O0Ge25ۀg+ӧQ8y~zK.YߧYwҦ6S3Ls a8cm/t/qʡ@)i Ӆfŋ56IO 3ª2ѧOf&UQ- ȣOD#nK[7:#vA)K( ݦ i1G D-`k@VZ٦)'Ie# lT5 TjLj J!0TF3x(+ !t\EZ׆AVH ]PY]e:p3AV46" sɜXj%2b"& [0W4(jpX\۔@N*ҙ fQ|(+ M1-@ <^ap\a %֘UIk(t%ALQVBH^oK&!rTxkV!Xt]\3 Aw,0-din5E8U ̹~S?.%(,MxF}l(*R"gZ`MaF`\LhB=" r-J%<]ظ<_&cG!p`@.Ŷ]Bhi\͹L\)m`QR=A*]j;z9&]k\"2 @Tޠ@;1W7'?wĢwMN(dyzV9+ohehkORÝdOqy!㈄_ s}?5 I 5wo+ߝZ/~{,;xe{fCf;0:ǾeE Q 7yxO7g`U]1YF'`E:ַE"`$Yke94&^X]T1mcʆ-/5P^Bme%P13*ƇSn Vl9/tsSQ2Զte!CP:Z<ń^!ȑ c{T4ХKfөy_#ΫV4 q J]43mBUeo1DCGIcL)eVmTi4:2 B-(g#AA(񎓠QŒ`b̰9k!42{ ;ǃIGS]&e)vɏ Rpx"f8zTͪK8M lJ#W- FkIU-3\b ޷d;4<K%x~^}b}eӾ\2my:S`?m[::kw/w 2b'K_}s\N%񨕣5.@Ri^aɛiةMAkr yC#ۧjUh䂔;D HUݽ z<<\l,VSBTm-*^˷I;4(;`+yjWWmIg4PP g,W#kt41xӌ]"P(h@"RV D+"2ʪKJ`.7B}fRԺiSltc-VZ-yPZ]LU9zp}Z _1E-'yx]ٸ+H[߈^e /H8p( W?0GB D(lr4 *꜁RF VaƆ$Yn9iWQMl/CUűQHPi"iXEmG֖mZ. @ /lBzB+w.MLmpL0 I Oih5WvZ-LR $ۄJ-}ezW@fX,ᛗkݒC`)@]09Mdb@r(!pIPXl8sAg.2oЊjR({ߘG|UV'yUծz/qxijrUӛu{[kM z[xq3^Ƴ\W2oZ汏+bwg46qDMuψ#X[ a\n6d1ܯQ>:ڝ6TȻ7ف]'\|~߈5oXPM'X|Kn{8y|8^1;ۖx.A{7} ޺(WZZ" KVr4?]e⒨AU6kw SoV0xX5@PV  WGk,   vZ(FV@[ŽVx@044IS-@UKMTWJ/{\Hm‰@Vx^n7ck^A`BKd:dQ@\A%\.cns:glioNo6(6 XUJP !p6¥}ny2 Ǥ%(/ VIx%dP#Mly1"M4 jƀQ{{J$QV5K3,U]AUܬΊxP3MXZFn4Y%-&flѨ1QU0SHj$k >.hXQiu+ ZP:!)61ހ,:m\@Tl3Bfaf Vu51ʬ(c4fc5(dd:7c1.ҊHU*pt+5f]! *7e03mV :{R˔dzV(PHbPΕ%Tn'`ZƩ 75Mu(慿,y>UpdNkVg52m.T.cu@VR7"pmƎcE0EU'fYVwߝy7*>kSe+7_!S Xg* .޶+=_Z]u׮s(ųW1JlũOv9-8TRM E61+BH匓,SJ*XP60*+*-NX,eEҭ<*W+* r΍Eա2%Vk ,ԥV^ X/H/(^ mJO0q k_xfZ+aU)0mV̴ɍ-.8wA7-S yok .\bhg X&RŇ$"4U7Û3?A)yoP^HIm11Uޕ$b58˪ԗQ$*5]VG]iH d=ʎHD3x\\9Ċ4'0̕4eKlxڡB?j1W& ,f+qSd;(nejو6HV+ew/- h4P }-ۑ1+0qbrSV)0ٚ< Ad̀ +:WuS +Ӣ iuVh 6U%ʈ-+[J@B`^IQJJվl:q%;B렡1j\MgD&Ac}Hڻx$952WeQЙ6M%/.BePg@ْ,suȓZB$4ˊXSgU{ͳ +2 h{en ^UllV56 y(0 CK,F CW6y_2W-aUG I9(-l zR2 )K:e1Ji _NCᢲ̩1Q_SuxldaHhcY;-fq.PcaThRWSX7 p:KUmv;8m%` s-D${DlkQ¬ތB( B1Ǽ!ooAt \%zsi4^aQ@5,7RԎ\ҬV2լ;s-CJ"68@pNy( X\QsԸj)ĸҁO5TBV|^Z"_v,]谍@D:]e @"on T b"hF6!,e-FHƘ0"(Xq H4.CZBNFhr@ePj4h ]fkDPzmŵhr@D [/QT>Ap]yTჴ7C./sҋ\1IPzx%J {K`Jw{p`gS gKm(tnqf!.Z*z*$bM"5]X/Js-7Z49W%řDl|$ -%P:iU,Ób'{h. ؏F2&JwK4]\qukNn VcFeKQ⻻'2}Kͮ-Ws]ajD&tګ6 S&o=C `oZsprW=*ەF&QV@"=h3gx(, sMVjivpՆoe/!ѬViUqL3uߏKnãkoĦW PދR0l /*9:XgZ.񜤴*/,@S [%C6(hUbAjQԃ.pts(LLLՁkb0H0,*𛷏1]Ra(@N09XS@=6 7Q/x<nQ m GJ= FZ t2: imE[cv rS4SByq)e1T58Ʌ! %G/[! rniCyjo#Rt 0(/=Ww<\ /2(Q )(-f0 &t ,0 y lZCDށYuvb (6U2ܴkdE-UXhi .^%4&Ote`DѾ"M?60x{l8:A+@,s4 ݵWXgw@O @k_91wsƯ,k`Q =/X#elx9uiA7v\6SP!^a%;(bts嶜fSЅE2:JA7ֵlVxr{rà(g+K, Z擞׬8mᾗ,>;llުo-nmZ{@##k$a.A7*؆uʮhbEDYȌE!wʼ~&NMÜ4 pDӧ9 #Wb[;P+(e J+C]]\l2[1-5B.q\ހwpl _u ؼ!WcEG&?] Vꒂ`^ def,yH+;lB+oDT*j0L"E$@^ Qh..-7PV1kPd%.(2'7)⵬,ubY%{]Ku-bQcH`e0(Mհ* aw$VU Cx6Z9]\DTrkqͅ"Q#Vb0Cb[F3˘lU7MPk]"U_%KږD307wvKQ ] Eܩj֔iߩ+ )xmT|jjn9mwlc4ۛ u X7;=C( 0fֿp[wcǻ ~3-4ƜEwpUWyggA2Ymeh赨W )/_u  n`=5$:|5zӵVoe-繬.4&q@k7-) hVɌb; ].:\ޱju Yfڦ :̂ԫnXLJ ٫jeh9ե x8f G4k+F곢RӷmL(4kziqWtMSvo9"}Lz.bUIP`B`L մ~0hxg䛫7P&\ d"T(+~! <|WgspX2K ןr)u+ƁNlVD%|CS[w%cz%e \W"ҏHWpaJi [m] f19 Ղ6e+Z TnpQDľyq1%+L­XWojKJt(&V )VPZʁ%j2#)egCvWV!7 d/ U )JҢba,bP.ӊvPUHJBq+TXEFҩ`FkϜ[NTk a(0c͹o{hs_yBҰ|n9+ѫ`V:;Z=ǔ-E2\"h`hJE&Yi: kL,qT+(Q h8hC"rn8fVAg09 8J[hN47Nc oXb%dxdB4 (Dqʷky7s!i- +-nnbZJ9-yg2=_GÒXӎJ<ߙn\?%/#bůyz+n\R4-K{Տ91_TÓ6,Y3.!t+8u}"nK4-1wӞ Z&i}g9B҇Hil.-]lӁ ޣ 0)oVi݃-GfaɃfR2QY>Q2h(Lо# LV y2 ` SUz(at ug,RwXs,"l3U+"6j*(E( ea*]&H8˗4"Z|ZUIJ yW6%?d+|T H{cX;Ci_h6R9Au8jF@u 4VTʺYĠ165zUT2Эo.v-=UjJT[Rz%qK YEӢ]xim3pC'|2L؆N)g T|CK (/@^HtR¼qW, \rd5^!Xʥ_FԴ3[ ŝf6U#A6NmWUH(ۖZV Wk7TـW_J{kb:?wF}ரdȺ(@UlQ­b0ɐ YX@.Jy̽L( i,  iHX,M *(!9}yZ\à ATvg80 1EQӘ^m2ayH{w>.\nh05P+F{ @RުX+N4<9ƺ`XR<4hڍx% SK00­tʤUCl+Uoj(ݝ⯮A`)KGV,2eS` L=8@5[k-ۼKadGe+PAJ ubJ-2bPDb1WhᾱbcU50rwqW\0R7VlrrZBh;Ν1vצ++Y3VA_>BK[ IU‘}[ݣ?KҨjԸ-WE/*0dVxrfK%ժiO LՍSqsm)(o)yNxU T8"َk%d9UVsX+FO1c ,^Zr˨%Wu:3QWً֨2ӹJ?yhǙ͵A 1swiŠ҆9j %p5~*;Jё=L[ryk[+W䣞2W /W R-]b6*02P+e63E]r=UQOpnZw'ZL=]\.偛(~z@hTYKC%hʕ*;[op5f*Vc@š1@`5@Ӌ3rev]`hGtCX")L]T8\l)Cnod\PW9D۪h ͕.1}pUR!䋚(ZE7UP[sU s7T4ڗv*Ǽ[N;𜩾1*)n/gZdKviN0 K7AvqR!v\Vs  ]8liwF0-U9[jQQ@f'EkFtL[w6U rl{j)GW[ZyN XQvpE+8X2}V=p:7) %a:Fvھ7ef15P,Q)QACGYZ"!M:9, qm Lj42E  (,"H/\B&.<s,izK3GM{,]8uk9JkM87T{h۴^>}j\@UeZLQ\ w-D堂ᯖ 1%0Z`x0؂Wy*bRK.j`BLm5vc7 -1XA&/{]Jj!S T$GЧґL.-i1X" %hYj$ڎT+Zuq+_7'|K7IڡMdm#VޮܬEݣ62ٺj*V[_,axÃ4 L0*@TiTҵKnh&$ 0v:l,gT6AKQYJn]#W`6ч$XߨmNeјZٺFYίꘜ7NEn"9zdsm5=7@eE96ی\S5vu󘽠r_t6 ,@8Ej])%(v(۬MoWW{՗qH@&@0v`PN]  JoŚ,32LTJ.BfduiWj1*,3+,c~G{{mͮ:ՕZvTlWin-3h/Ñժq~=p^pgR1Sƒ R<^%ݩ})x\~1vHNh/CF<0!@8ՎxKg-_k8}J3U^}b6kʔaRu- ӫSeeNmHg#e+eZmEJڶR k GwYqo`߉kLSyqjUk`21 "k}c9"yfV_va*qewɋ)X֕@̠Wyp*\Bv+b. {\Nb(Lݭ9l kCQcu"4@G! kŰ/u™}*=qҡV^^#4V¥LC%zfVaPϖa+ؙQ*ˢԳMH<<)ŗJ)Y\g*GpG2PvPAto81ҷԹ^m`SoJ(N/zAnm6/FoyCB}U})'lVj`uչѥa olLqjn!-黭YK4²辍"~ˊѺ^h_h+ ')ĺ1設(쎐"kAHT@9"#Z3h4I tdm4ão%n_%ⅼ͈gƋzwHprfD,ZEԡ.qAt.LjqQXs"[W][[9Yǭj!pEmBT.'J@Fi¼6m!Ѯl1sSN; m Mc. Q@]Iwqlo,+M&L,GxeZSH)t2b튦zCQ C*ẩYzJSsj+^%^-58PhLM-TFKc9roX75*] KӎfšABXSTkRxr\J^@,:8Γ /t Όá ;H*7҂*Slw p ,]QIPr &Z:D^'GAXP-9%+ahKº1a5+\ Vt\j4DT-|8 jec@e\|w\;v X`t8MM@sHYYb]hKʩN&..1gvk9ós#P%7emL7JUVVc()l6,2hG3KùAZSI͗%te]޵W1kM9V+/<u,T.usR T>j@.p* SPbz9 M H%B'yIEYˑ0]\l咩o-R8bHY}1Ʌk ppw~eڪaɈ=f]4뉚*⬪rz\}BcVqb908s1H֕Aʡk\Ӏ@F_:lb,jVl6c TlΚ⥯P90;@a"Xtbf=ENg KqPٴɛ)W'iPET UU[$ JP)uT|r&;QBuKVY'7dԒ*UqVY2q4(9U96-/އ -eDM eAa 4bߖ#Ļ`ieÏ~5Rx #Tŀ^ۤ]l7-LcĶqh?>JdFtx#kAyXUT[\*9m\)F1+98ž?QHxqwY[P>3F?2zi8&1D9V|o%:wjݨ၆o^&{DƑ%qg(-rjڭCL>faoJٴɚC0uIS^A|l1t%Ul*))\ CHfj4DJACRPrW5 b:  ]whsLdi"Uth9y.~Gu 28iC/ ٌ.SA\l_|6QW{=%/*~`'<)wfaU#2S,͗V`a,$ }@%)Au~feIf+7deVm(R-V޺1gmŮ9!wU7``VagȖC_;īMT֫xG\+]x/PJa?g+”K-Pv&<24]V- 1vc+X i9e(T4VҘ{d/elrƋq̠Єmr5N %]3lZܡkԵxg)cMZIln':])\~Q(UТ,P5wu7,ݫ+cSmd1y^C./#(˖-qx%,u+dYIJ@-9.."6#þ&ib-鈀.tI{] wwjn)-2 ?0*c9)  cB(C/-RA X<EĨ2Fei)0j" qg">hcc܀7CZ2;RR,e fLe 7&]b:n:XsHмkVƃP @Yh#tB m= 3"O=.vy떮[ryqUn/Ժ UۼQ \i[G#P_Yhy];KUG"^V*X/9n=`&u5Xhxx1R;^FF[tC94Y+^ @&2-h"|$(G!vfzQ4P]]BEh*ܥCjjiDs "Y,ՍsIR+*Vː0/yV`lխi2 ):SYx.a{0jRuHރvbGd.ɛ8K =1`hvjW`b`C`U#n5̤muX%ycyˈ"flgr ݗLbWU UZQ@ߔs_k^:W_`">Ch@lR3 &alp08^ZC2؆@5* KIO'iY۫c ht:ZV V֛/V6ҖEe+ A MѐT Lu7swIZ,灪C0 ?,n]~ ^9yJ'7IU N^YC ,nqQ[T-;RT '\ƃvۊs]Y勫o H=Ngi6N]LС1̼+YƮZlWx䷋]5-U5CPp7tq ZbFĨvf]&VnX{J6rJqVUP`%UXץm0Ly 7  MvUX]ZNE O(ѫFwAE* K[!˱y4Z_yVm {H2@\[G|-NDBTЖCvlg3`Nj2`J"`f;ɮ_oL9]Lc^u@pJ۠#DA(@:4:e(<(5Dц2E]L+2K3E@+60A*di[Dk, ' 9O~UtCŭE?(b 15jcJ̘f N¡iuVLt1Z0 $/5ʀj <0s'ƌufxqtuq5Ldhmi¼CiSJwg! r ^ isḐGEPFi2A]ٕ҆ZK`9,P$ 5J/3; ^.P>XPaAmBF b/?mq\Fe>@O? ZfcLjr(KYxwvinTp(e̟@l#Hjf,J0[^YHTPYFF1CU&1.V.,mJ8L)^#Svk7ՇlGVr(U y;?,ys4(QW]]5eHZ+.%.Ug)gkcVE©[BʠPVjD̈@Z*@ΈO-JP@LfM_0RmCL8$vѨ)S8@mq A PjGj7zQtx)hpGF$CEqR^L9 6G n6DnFy;"ZNpAykS܇ B;JiAN#t7mܶ,vÚȼ%9^88 2ʥC n85D** m2CEbF-nRĔ4VMu qݶ/ +Jj夥._̠Š0^^„*.M~8x3/D]7{؈ڤ \]aEY[O!CӅ,,l7V\*=GǵA.uu 뚴?PU`V`@覺w@zTMł5\[éam)_$@5u"9:`Į@e)wm(AH$ %zJ@ CUFlrE֔aqlr/T'+»,SMTRÄg]VyP9Pri[ iR˓0DJfjjZ*UTڼ\㠖dch&Ze2 U/Ys#v%XQ=MA'ZC&nIpi&̖%bZ{M*5Mz]=̪uW-\NLZYiTݸBx(LmކVU^@j!ڨNLP[kkb̻WIW~zf `9Fv8wnm/-S CYؚ@0#x,)xȳ}9SIdDN/H:k aʪʚ]uA )ULٚ#jP8Wv3o8iV݌?Eٰ[咀x n9_O5CM5jtxNYj[0!U ),RC*k]0D8Th{x<`\՗& JfNa\0"`K LEbD"S_xFXU?Q-d*J)~΁M);m23& 2R_T,!k|`қsuBZ/NAk|Z6Acu ]{D2E(^{l 1H+V@Fܥם] qK/!i:vaW ]uz@SqXm-\uL -nhq]+Ky2C,1(Pi6CZn9Rm|o4R&R; -z8&Dl/m$B B+\\ ;-jd  { @K"AZlA.&+kQʣ1_FCCB /%jm^[!mlԀrs#h)ъMv T QɌ4u*qcc5g;( :9ኂ a`i\JUKIa)v [=5SXMۭP_Wu(ޫ/_ ' \ 8ZkTb}^元֗8Wxp ͳ;VJ\A /5y{7@#!P0;7uB@}u J¬BblJxل E̘򍪉M&i*\K‡*`6( 7w*mHT51ﭸ 5 vHlc\4nW;ĹJ,ɻ8< C6Sr֨[,o eZ(S"ǼOio7eT_iP+8$\r .}eZxdR)aMRmYx4yɾ&Ӂ쫲2iӠ gQnMQZ|L/nz+gYV˳ma"9㎱DKV?/r…edv}ohź.nmD[gu:*^?3^*}\[+kmGvK;yh855h^!r7:fӜ=(4^Klu Z=Nߎ,ӭPsA@ۓ{$PÊ3Hюgͨ+Eu1G/Y Ӊ/"QGִ4GZmFCmzJVV@%E3m5ƎJ ]s6Z%p9iX{;b,(՞ K`1'5TvSj|3;azVΑA\[]zΞU4 &Ζ3`׈Ȁ krqᘅPc/&l寈k8 F"-!ѨSdJfH ӡHat*pr2) U!K (,bT@Q40طDP'SH1`B*nN.DS^K0]O605ZΗ1b rYCp _ @/qRUEe B""L10A_Gq)`ͪd@h0nQEBB%fb#7T Q;)Z3"v*6 RlBox3T8*W1oA91XKқ1 U/1@ n;w`PE<4 pEYJiorGj.k?o qyWv8o [sgƀqȡVbNKJŢ٪ VuzL k.JU6!ݮ$zgRL-T~o7paߧΠ<]PWT..+:7MJǚoJiyFΏ9 Z'4>%2o=kCw[ky5L荸m5변r7bU8:in'K۶4o UۺjqMlK; %!zqe+GDVN7–'jQas6% l$Z/Tߏ Ue9yè%bY#"1aQe6 Zu5H5XKJh^7ZzMU9J1nWJZ1\nڨQːւ+tYuc:iͦ,@ڬXWK"숴7Gpo$NM*ZҽeN7V"t]^uJ֗nXsdSu8Ud ) B)Hww4 V(k !4^;m"qCE  ַmoj y!yP(%[,YaY92E߼ P0`!D;f Xh;`+wQSYD'p\Qf9]P H4t]Xτj QK EK1yfRS!$jnKden (2Mȉ%z0k }d{BVl;*Jik:.X@lڢƂ!Ӫk1}7X!c 6hG9gIt2milKiAFeDRn/vMAӁ/95^o8t: Vmf7}z&[dJsjp&7Y3/W%YJ?7˚!xM:4;;%zsŢZ&k+M?YpȧhV;e@98 qyxIuY;,M=!Og ^FW7]ʞxU.-(ކ[nڰ&ؔg8<L5C!eĭ` 6v|)4fhLR([ه|D^AH"ĸ{`Gh&KTb` uEo,n`s3HpA]YR{.is2`#CuexG7 :jnkUTQ,؂% af)y`E p[=A+IJReW34 qPRl$+2!,jKvd%$EYĸUF5v!鼹frnԺ* B0T$\C]Yr&@p@ aUrA;rg\ӭJw\YD]H9æD\ `$ ^CׂDn݈n)5_ 6̀[E](0X>hEk{GJ+H'y@$ B< { hdhZk4TQ" 7j 8 bMw \YəW*r d\ZAts^L1y$@zzl (%UL⣤YFKYYՙsTneB㙞o>;UeѪkFupcrCTص%Ym߉bftr%*3%Lc}tS)r1v׳~e V<\({SiSAמv)A[zv1V=3w2r;xZޞyYc\Uf[*·rxW]g >Fۂ9;ޥEV`z+fvltto/nNOR pm,%姨ӵq$t:Mouc?qܦ\Y\pBtkIo[%yT-2r^rD5nX VA͕őQJNi݄]wK{@5Vܺc.`؀cӈL^qNPthlYanV܊)424bIkkne;x )F2gR:![^K5XCTi[ %`֔V1PBt`pˑwDfon5+l:F`9C)k@b u\˺ lrHȺ&tQBp@9.B]f)P[ۈhQDEד &:Xu[Z& I#\VghkWفsj.װ",dEz5nnj{ ԵR0^aeF$2xѩ%AT\ Eѳ Lpc u[jhPC nYъ\S6i*(V MGph+e`r1%S)l,8)DUӵOq\nc]T[[ ͗EZָ.z^98*_).k]Yɮ3,`w:T.xT^Yoe/N-bוW8Zs^5-[<ߺfrr AosMߒaFw;s]—X뒺0Sۮ"뜜K춽aDqs_q=Lw.'fb՝3^ gtTݦJsf;TRaKqӭWUc-¹S%S[ 2H,ĺ%.yx`64P29^nZPEVӴw12D%9SAYW6}1$![c9PuqV JI }R-:2 ‘X0uxFQa9˾q2Ra[ZX aEU|I trb9FiLV1{宋 3uUv0<%r֯Jy_oS#wUwCi}*4۟"z pl;&4v7/y K:LC5JU;xg :j;blTl@ mF–I=Aޏ4ŦFZե#UXx7O;YPBUgԁF<" PAdQJ0f2c'K ZZQ3_úI*N*)%B֒ aZn"EYY¹yл-3I7x R1 l:)wZ/km]fȞEz_D5Cf{vgw׫0rq`ɽ 4 >wH CLlz`7&@4 U2+dJڪJŋVYO"䲱m tikESlV}1e"]) 38̿kۮphoxk s|%AQqw*ڕ E [toؘ(봸 "W `)bW7C[0V)\Sh6dH%֮׾'tjΥ=sX4hÛ]a`'xu/ ;k-g &7R؅سQظSAPD^̀]rC6&مG%_E7R @MPY@ CW! GEA,i30sLG12* A ݉pI<7k W U8-"̵ɢc7譇-GV !A 0GtR̔ejŀ-m#zVEz#%5aUIJdQHuNTKS\ge Fe֣qF`7[Dgs Eb\xXAψiÍ@ŹA@D!j*@ Z Q m+#J,)'YnU #hUpFD"TP,_>D-#{XCg N5&=ɔbad [&@jD\* Ab ة.U3pT |'+bM{얏t!R%qrJ&r/Rސ ඕv{[JGY<7 e7PPGθAT,KO29Xyuqnjia_4w )N?$ 8e_9j]`!c/6YUyRa{e&ZL듍L2k3ek`Ui+5n?0CU7EYʪ-e5t 3;ٺ362Za:VG1soĦJiкe++wZJFsE-WWjrgX&i뚪qW9sVþ;j/yZyc542_s]je+(;';a/I5}1-ajn;оBO $a,7ӈVYḽ(R-<ޙNKbbj-_DiTmxe?.#nj8>\l f1 \ N$5M@T#іYT/PpkȚq*h Mmw9"IZUkP 6rl[K+؈ ̃k$;U)vzaDN5@ |ؿ[65^R:0a 55wEKi$Vʱ]qU6̵gd)Q֑`uMUV!JQ)]8[3pfD#B0A*hK ^5c1WLD6ب AyF1.c\dcXݪ,0 Ug)fo[׊TaBHl-R ul@%P=d & Q.5 $fcضg  ؆ݽ=hu-Rw5Jr3TeY 5UV VjM0 18/RtҘ%nh`ۡ!SU:55*u+M@h +t,P#( DRn]-U6l2})] J,rr*HD@i /)B4 r)"h\ ,gS y*Va%\ c- Y!]3C@9]1gVY30nl[fpU8(B)b-S.ie0ib/Tpìjf*o{%_ d%@QhŚjəO1Dl LCsDeL`!bH)YMW%@+X3%ºJbWY1"kffS].b& *( Zˉ}ZrO1BMO}+P8P) tfPzKŮedJ3AV%8!1ܸ:UY`'Ȩ. ,<@ +Qb Ӫnru_*yɗok\p̌S?0Q*Zpwjw(ݠJ 5ws{:Pt\0X.7H#0e*(\ Vs=)]]Ƭ1*sEk +jv;,0g d2 y"IXPRxep( Fph455kAd~=.Ce4i)~xMq^\(S%r_#Fnq(%':oxPY_ K8W~%g{ӈ_SJIm0REL ᤭1cfSa 3`K7H bjuMΒLACie:8k}3ı hsa^FyWKYxtw3,e1R)uWнdۍdN Utf8L[E {,|)ETU;Ef .hø5p@> k4<0;To4t]E VzpL) w2Ĩk )ߙ{ „g*hRZ+Y]QQEPGc4t+I[ٔե 0bV-k>-NX5"Fb^c}U\46C0tlȃZا+5PUU̢DZjjKic](l d!AΜ&VU&ۀ]GBb\@ʰ+%[!߈U6,UI8)5t<-IBPsa} tˬLt]$ܮ+ʖH 湭cv&j&!ht" 86VC/1")00A]Q1iG أ"*3bk i7A3A5뇝=hr` qʭ\R:9,VU3EɋۄQZZBۆH Qe5͚49FUuT|wF^%]㪹[Sfswmv:@SCNrC%9MoMS8]0[x+ڥo,ټ(^ek8%j]@Bt l*BiNջ/r!,s#q.UBWƘ-#ÐWMVOh.D5,Ar.d%3aA@'ɺi/abZ*[h3L>WGKBbN X Ś%UP[ar1@XE0pZ*M, ̍mX~@ ٌV rWĥvP°EC+ ELE2ဂ )M@/,̩ފ։ Z% X^ b`Pgn2JF3Lnd%+H}Y=uA㓦7-5ZAm) ޤ@Rݔ"78D`. L/(&*p35+i4n̠W V1/.Gh6*U te>@(7k*^k۫$pP(ht Y6쫃0@ fV>HӢD+e`#Xrռ@wD֫ JGU+u&2ĄqPDnmcP;W5AFJ5-uCRV^TFuzRģ@\ $J&?^}JH ; FTcG2晪 md($aG bd eCP c )0Emdnrr#/Z^fyKFB\@SQu4IAw”E$> \+Yfh]+\XY(ھYY(4Seӓ ྜྷ`ye0.RoVY;0LKLFȣx)^(jxu6Q"iΆQŠc)tfxBݙq˴!QtY3jtslP%i g'ԩ M:;%+a0OFYvd@/Tr+M4YAhQF zHG46ARuJE>2e9a]+U;W!jeOM 6Z/PvX\ƭfWKX^)!r% `Z X)InZF\K"0KAz]uL&Az+uـ׼^(.9*L81 mRHfpQ֭:d L,UZb%WrLb ڮXHK fpփ}$.'iנ*4Z@P]Dա9LV:ѡέTk? )64nj(t0(¹P([ĖVB *#:r9OՀWˤn7V4-+a+dݵ_'0QicM/*ȉ73c7"US 5UJpB M֕ ,Py-.BJ@%(4 @%P5i'I02ё廩ZĮ µȚױFq USS8:=GS7 G U=XuIz«KxH4J,L):-[7&^71j/y-4b2"6Bϰ6\gD-V8-\ŋl1:Ĥ σ[T R0чSt!KQ-*@یFEZ&Q]DAh%T@*!M1u ^LB/ $@eV7NQ- pڴ&^2Sw)#PW+lb6Р*f4SgfUe%s5`8͘{aʉ^ m! -. 0J~FI i1[rߝun+) J^ML%aw Uתyel]l`` 5K5rL GCkqƽD@tDb iS~|IBlD.n;0ip4.,+քƴ52Bi]e)]@n!p@KH6 zoP-(5+뾠]!Z5 7HYa Y굨jR֮kdRЬ-;D`e2뭜0E F (h[߅Cuv-* QeV8rES&ZV#refΑkSTPVl E<&hU `Y7٢(fE sAJKLQ>ٱ.Y١i(0_%`{qMz4?<D^gf|imhQ)Y6*ͪωI+)\.'.V▞%iT|f5jV۲–7+%TmQN+r AB AAvp*0ZKEPא-mKPOWԭ3FݒH-Qj̬kEMܓRt\]-@mPg— o .LM&LD UT„2Nu]W  ) BT3rKAWlC3.F@=0J5`pOe LO ;UD{HũKlz bҊ2nJ Ha5ץ e"*+ 37ׅM@&8(9ҹ™eb׊iC hU6Q NζQQp?Sx m 7KLʹ KP8N" ,XlkPˤչ!~%vރ'b@*p"= Jk{IhMWZnXaI {qp]ǦCVfU3Չ3CC 9)n`n6+'KmFC"7UZO0'RVlhŨOȻhT jհ]ж ǩcvB+Rl2{eX ;t/݋=y ċ&)[rܱBnً'(']4R% غV/TkhR}Y0G D,ζQ!hq D<ؑ=$[Tl#r0&KJ\#3 "*$82bm%pd65YRطnXpޢs [ ~QNA6QOyX 7&U1"D)U.FX]QɘC23_DHÍJ|𺺗Ϝ]E\-5 `qFE2c2h2P±]ӺĔMV/3sw((hzI̘i,1N1t?5(E%BjZ+黦1>ϪbZVZ[:C8&ZJk܀ܜaZ(sE"oc|3*ԠT`*?^1X @H4% tEbB6j%vj@mnZE0 fH&1@hXDtTqd:7YWQIKѧ{B#G @M0-ѯ@az"*bIN a=C@t|Hd!!4PUJwY'[/OwECZ,Q:{ R^Zj&z3 #1}(G i/srRt+!4BRa:ZΕVkYȀy^y]YB@[ĉ"B`P؉qÌ3kӶ]IAI%IU`@b+"@Fˍ\{L|2 X$AJZA,\hv=}QRJj_sh] t[Z:*AQxa7??N2 xBR@DC7̜< ll5U30Ax٤)xJYȥOUhw% ,qpKŽC'+9c%B)F4HBeY6 }p( {IO,)rlE"`EzVmE W Қ4 eyHx3BB:J<)oKu /,48 k\Lg=â@|'7A$҅Cf^(RϡvS32}NR R57*V.~>z\\ǥzXO?UzbWĩj#)*TD "עRRJf}/ҙO|}1({L}צf&5roĹ}}^+֥KҽqĶy"}j_SzTJ'1'R=^љJ%32},3o֥J̩Pǥ雔enWzTrJ>3R7*Q+WeurRL\LMWYEMKJ3dЕ R10¦3XK%A5(1W*klz02KR&_*J%Dָj&Ị3>Ngb111@㈓ǣ:=5+0HvQ&ɔQ*Tߦ=+>QGuɏTGϠWSGu>0<5n9 3<ijlpKhkB\ߣP׼fW2>Jfn̲Y}2MP%]׏Z}ngT̾Z%Lʅ}½7,̷ҽ+JTDSXOz_+4Wf[~q=gyJPDx0Uʙү҄^MzUJ2ˊ'(iq c\7̧n;$OKfI))&nf\̦fy3-G˽gӣ2*JeqPO3IrJ}}75?P ._jTOENq*WJ*PWWJ̩NJU~3xEU~+5+=3/.(]#Jx0qܕ3*oR׹MfJfT˭"09f:ˋ2f>Мw%J+>}\}%˗/~_V=s*TtܺO=}z9e2n 3(n nd#gi}e1b*7W?Gy_G33r˖KK1鹉0/Z/ҥFT*TZ1x1ܩ@UC:O)3;@2_0#B2zT@)8ܤWiD^*U׭13oEW^%22OR2LS33333Lzߣm)Ms3RxަNӴ};zsWzw 4Ss3>aX7{‚K8UKRri3 25.x=33<>.fzEoMjTUxLK=331f!1<)@L{ԩ Ӽw6ͼz^w| =8RTR \K˗.\rRBK\.Y*h带\3jy1 fdrW_Aeq.3;ij3Ҧ JԱq:JϴiN=8;z\Y. 9YrV31 É\eNDs1ĬJ6T$R._Rˮe˗lt(={F1OP͜JTԩJLN13LuϦ+339J>=YN%bW:WiV: ǣR3*ww+QcQ;:@wqYD%˩K'(0J%V1>'q[a)%b#=2p pW52qTeS9:/3&o3O*j\zy*]wL>g>Is9{z/t̨@[xRпiL\bQ(DQ* }3-%^M3g;N&2zb=gzANPm?~oMAzsr~" \[̥o>Ҙʷ3GpG̸Xefu~zm,x%223;̦Q]ffgJeJznTP֠3$ϴh%M, x39)J69hD\W\L1觙ZY ^N'29,ù/553s,۹GeuJ=k?ߦ>WӟF_2()JRf[9s(5뙙yl;d(C3gKjSiY~%%ZKŰU럯3'fezoҽ3^3T;zg0ν4bEĬoJ^vWV7NY-N=RL|>ĦTjN=/̯J|z_џLxq8ǥJǥzf]Ky/%eNs7`9؀`ĩLfSKJ̩R*W~.&=1WOTq7;3BWSSMnS}V֥\ u0 9=/O?EiW=|ʕs?^gO3EzQ\9q3TLҽx5N%Ј* L1=5×Ǵw Q.k.}>'hzg5<2nxܼzKg/7;zϮ똲oC_Eq2:z%Zy%jV"3Ǡe4W[8 Ys_3=Z2xߦ}r;zg>W^*W+Ҿ=^҃RG/]c Kf&w}_?KDX׮1_OסWJ9S߉vG聗-fusjW^;>+_N~g~zˢq[7T1Q< Yq%ʖz@4eR+ Cҽs<}^}8^A*CWǓ2&IJW?^!D [V3sF yujW-K?2pko0/YǴ۹v;zT_GJ\X\sxHszA(.N.iVfVULޣO_V SǯLJ^J#:m̬ǡc5+/Iq_V&W+Oʕ+s?qįMzWz+R2*j _(%ijo]U5E('LzwӬ}LB^9tC#]bb_xo~?Sm\-[\sg ~Nqf}o?,OUbT_Oߣh-Q{{ ƛV%.pgMLMG˸MfY_3}=wjk?W^.۹q?sMU*gc\tA35" NL!6 @ #C~}V=Z}?+QB)ˈ0ψQ%`q陟\gfx.vʋ: T? ⿉zG'efybç2JRs*g?Vg![ sWe2NeYyS?q {Š2V]pem aWUMNz}3̿[nG=jC[WR9?ߣyfezWLO;F^F [`J/oKN!C*#ϴD/RU=.b]Dtj!(DĪ,33r3_~jE@/(n;߽ώu0qx >H)ܡ;KĹ3^s>=g>3~쎂U)2lfCֿз5)QqGn{Z!z L9PḭNe>j<EX7+U`4+ ]X26"۬&CG_9 Zƻ6 pXٕf! wZr ӨɎ3C9Wh&@mcn)u/?7"ToOá9^}1[Î{._V~9??CU*oO^ȇOߴaC-=+Ŧykq#sjf E:@Xqp6a_2[2r4:3_WKq QDPf[{g.M ^īQ¾\Kӧ,^ eNbtiJfzQ+Y\y.\r_cKj8R߿c15Ѹ`"5*WɃ%YJ]Fu V-%X%.|QYANRDP\,s7xUX oZr_0e;z:xg={̾{@&ZT! HN_OuSW~$>_⯫?CJ1v>e_jp^t¥!6zܾzK#Mx)r^3WP+. ELesp=ƻL}Pjdt}M AbYL2 5ƾGo=*nWw񿿾6~=G}c|E|xB:R9|?Rqn(aWR^2_M}98;p=BUPgЛbA1]&ϼD8ye}Oz7pԯLJWULFMtb@04]T[~FOA;y3^\_3& qOOs-pLr/ݗpD8`-\җnT[}돮鏧_V=EGm>P?}5^etmJ~Qh6:N=ԠJj\v2^H`>J&bw2֠Jos.;ܵAZXsj~Ho(0e0?w~GVqx!nkKӧ,<LLLz5_3iǧǥ'bbbQ(D171(Ǧ%(UK] f"f)ʘAGj~b ^ pױ#Xs_d!KĬW6u;+2약F:`ccj0iDJY]v|nUo(QM KӇ1V2C}w;z-Z=o+\2J̺KoկO}5R*T^J|qt\rdU|P/5R'h~`\}MA[bYEN"^%@3NB1|;eg?~Һľ#%: <᧷P[kDfU4#Ə*ijykZ{E^߿yi(P)`8tp~ghfujLzs5/>3,.\Ky?^/}Ye* N~oE,ACC&Vn/y %5 wU\TJw\CLr1}bWX uwvY%SbՓ ҰtLuP_y#+ ^nǴw4 óקNTzfWIWLs|̧뾹h5 p+T@ӟ35pYiHYBUrgwjc,:I[rȭJ_?{ƶ(C5yĢĮ{Ow+vp9"Yގ"kgtY-.1?Uuu?/,K_t0 !]ྡྷdFk95ƥq3Ǧ}33[ϥ>9 *S)PHy ЅbCgw o>` #ax`E.! gW0uCtzuqj5OCpk: ֯n=Ftt >ٗͭG~x_crѽ~! )v 6cQ ㉰r99~_Q)҆7mM:]*;ןVgџ]3輂 Qc{~N?(zJ=0z,EBd+YDbT?yP)Zy݌YaTYb$xY{Ð#KQF> י(,LhXzy\~&.pE4y۸BZ >OrdV4;{/-|qh?p"db,~(qF,*ώ {{Uu5 Mۂ_ľ\J޾,\Ch^rķ^m^\Z52> &VjD,x5@[UtLL>leoHMp szy _:Ex~Ca3W+-y`,#" `=!F۹g@K8i~" _bdx}µ*(,@0Жa.߸=> kit̓ӏsR~zq~ѱΟB0[ ЕU?C)_/NO兕j={B s^ՌY]l0FA.eĦ>s,~6g WWm῾Ðs!ow@G8u^qms4u QoSk)dap/P8M$ilql{nbMr".}"MGҸ/!pzLv˰?g^ہqJfS3י/jp}Dl x:s?^^*&nm\m-q0?vXwjs3^cz)"{W) kzD#E:#L{q-mxBp~"  l* %]A#>_^4X ueJ ?~E{}DĮ1T[Qm7,HK(y>VRBt!b7+Jˡrq1`dyM(%oHdav:Jv`?AHfJNGV7Bޏ~!ABys p*!j- G(XwL^lQebcR;ӧN>cP\fcQ,g??_8;?R|Diݟ9xsγ/O&ϴkש(h(oxbo?1cb+Vn}FgA.R,ip`ǎ971FhcŅm c-䛓< Ńzc _PbSA(R(_kǎL5/| ňF96L (/ Ǎ-mxFצ)O2LaS+( J+?<7\8:;ٸ 2eY, (XV ǭD-ʼn-'7zW 5ϓaAʨd DV zK VˢKCf4[IEPTMǵW}3])hGuȱeij ÐזZ3bLEe.j!p,$d CMbHD@Yb]Px B_sU(lry5 7n 3iV- hP&$AG3 A@La(+%x~ \o)gIϦ :+qE.A4۪YPXr14\ݤ!nC +\#pdԅiu1ZxG*9@ӄ=tijc)؅3e_L4 *ԏz[*/ȿ9؁X*ZJuaWBl\ElVW+lZ_[ )4z#. b1B 2.Bvs]9ZI*D/" s +9Z>$f(̐[EYi3\囯4=JMBY g! aE h3f_۠KteSg-L P"y ̔# {@t1^S_㿢ds3S_xԸ={zesZN%v՞=/׉q1Y1.\LLz_|Mʗ\g˖K&&?zf=8ǧy~%xMK%r31DĹo˚˙.q/迢}S2hN}*Q*S3RY.\qnW>J=.\~}.Y̲,7?J2gr.,~ gLMʝo_ Kzy85/Ҹ鈤/ӿ\d%_JWLϣ)֍ ؎e˖KBTԺ'i;M2i^LElrٴQsi|O)dQ=..Y#[3.qreuo3z072u,qI^eyyO3ǣk+h<1llpojFK:ܹ,.,Ř},zM3Is ~}7_˚.\{}oHz_&`0Dw vnqLˇ}z w8c\XF.r=H=oӈ0.qj7¥}\_s32=OKLz] ?Sf31A|z\ e癝zX}aI^^' cgֽzTSI\Jl̹^&f-%2<˗nTe|fUܯ^aUjLsy9euz,C &"ʼ˔CZczJ _oϧoZDm1Xq-F,T/̢LDzԼl^Z鉃 Y}'LMn[0Ӹ1w7 J+y;]LDXK&Lz~gJ%J%zԩR}RW;oFQ/0bWJ11bay5?_M߮?b)%֦HZUdvFSxLr՛ϠY.LJX%jܱܣq(DAHr%y3*. :jcsN%pauϥ-fyJ*Q(**TLXWF>3`bfq/v$Ҧ Lq7݀^sop/q@LKHTJH2EL}51]eB?e~ULlwĮ\;KquWkLKC6]n!~&MK<"jzUB uĶLj3S_Y%onbZqXSQ;5 RQI8)-|xɹls2l\ϭz\P;@[6‹ΉHw |NG|A%˜Yw-s33{mz3+Oi/iMF])8y(GRk1Yı+8cFJ/Nk]g{KMK̓s[.Թw9eK~צ=]˩Lss2ٞzI}R2J1e^#뉃<%qW(۩k0ؔ:L+P` b2D[ܤP)h~enb*0K‰fh€!,f˗?)3eY^e>. ¦&=x/[(53L^7R13?^.s w(8Ale]je>f> |fnݘ:% تPRQ-b65rȴb:}{L˗,._Ǯa+Y鉉1.cssĿZ=m˖fyW+T27Q mMżlQ5İ75!~DZQrMoE,K:oLMGP̵[)e*;Ήox7&;` CNiJXU^#K}_PD L_ d.Y.Y.Y.\q._̿[&꿧2K.\g=fg\r@^оxLԲԵ8chQ{GmSZܹy\o/_Y0vAKTP:Ǧ}[]j_ӟK\srz+eϮeB1*TG:b>Lw7~WvPfsQcFQ[S,wq51sR8'Y/NT=/bcsrsɂo3ľE.oPg3u2{q,o}fnԧmuK{LE1Uxƥ.*#\=?s@ļFv˥s̿KM.\3/} KĹN>jwr.\[),m|묵? }c qN3*_+lPjdD^56f2U4PmԹBwcҽwT<ܨMo^zxzx1xqN`. c̻ʿ?|L..s؉JniI!K0Qf Qe(ZJBٕ}(ɒ=%Fuy&e/\[r˗w9˗ELW S.#;@^G;@cEZ˻a=i/f/迭.7.QlBqZ,02[OvZ'+K=ȟPq 1;pu @ qKߥgҽMz-3:kpO~X}sOץ3LK~0F,~X,5_6u^y7RWnLq{ʦ~@QRo[=/K mKL39-i΢JSԸkw̵?F`S oj%b2Y?Pss,1,яF5鉏F\#HdÚ4+}IsVw82,vÃå1C:ǥB˙r}N%c |eB4pMxneXb| 5xfPIW SUsV51 qܿu~.2q1^q8"!uqD.U旴u垮? 2NfO/nvܿK?>׿ 6--#rP=8]#ep|jf6Tm }oM81ŌI!Bב}ϩs=,K(\bƫ{E2^^[ GqZ jcֹGDlg~_=qp%5E7-b} @ttxq^e[rqK Ghn )Gl;0r3z%ί#c92@fw3ֽsVٟJf}s2y;s:%۷߈([#sX 5xkәgϦ}+ӨN%>FxD^*ϿVº9|ӛ,+V@LZǴL_e~J(uz0<}\}W`i a!k]˗r,{.\r.\.a. Oxt}W.F Pݳ7xCf{^Zi,t_mۋs+2z˹rˋ/u.[.\rgr˖˗.\rߢy ,kϿH D4x0 (G76+~_ Nl)<3Ϫ]Cghh2w*W8LJw*T\J'Dnæ+%̠{B69|E %8ugۈ_@`3Woʕ+ҥfTR\LNbN} zS~a ;+@L~<(~ɵS3i`o8aPɿ|KnKaUF`q.+"TVCÓSQ'ʶd4L\ll=3/^e\zܿ~VYn׿߈c<^ap}y|E|}u( WW_pR;%z~3/~ٙ32u$ >ZH?rX,|A9 GC6 \˒"\$O >8f_mx]B_Y~=LUnQo}% Fi:LY^!SS84 u f%<}UϫFgLs5K[.Rޫ۪} 4u&!Zq3h*Mv;E-. U`d9r@a2ƻ,;g>btv;?SXޢq-0kZqqe[0j`:;s霿xa}yJl9tC,?U)J.C̱7Rcr\8˞eRO:ũ߭G tʣ]Y'31DºcJuc_1︜Ay :ǜJ=F?~`8:9~̡P|Pt: ܶ5.^uy&L 5%hYr.1ճ^e}To֧֧̩MGN~(W% N#mT0S,0'iuy{nX8jzF׷0ڝ_[\\ܠ..p3 r,d_WP%{|vxLq*e'NqC $)_$vI}+_H(DZI`0.p*^en^tB{⫃闢wb(-ɭ|/?W7soK0U.\E=8/|K}j_=8f-}Zº_W˥uWv9)m7D=Ful7N7Rb  j ]hblQշiS 3Gc 2n\>鋍^9>}g0Fʍgۼ3Π ~ U2X埈+oWy'|lkDLl\^Lpot7R OσuJ#_!ld;Ɓ~gigSkrVF"\U p{÷[;~uz]z/Z#RǏ~!K5h9&}8ni3 MKYO^*Wꯦ=jo_P札MW%OZ!jn1*c ꖇ64 I-jԮuK]^z;etaaïJm u7g1]% B)?ɯN`l{̻-՟}!qg%7%(ybYP`\Xh%Oobaa6lt8M¸"G JkPql:J~Uow)f~TQP0y3^ט XgU,Iɠob!څzۖh$kCNBx?SKV{W|aq3-- ^qO0!'_wr% 3vyc6}(m%+ۻ]ݯvx"9+O(xgx@]߼q9tnX^Ǻ~4%/RE3#J؝):?2x߯۾^?m"@E>9讎y-NzʬН6cxGy@hy%-~r ',' #*q*Mv\l20gĹsGxrCKKcwflwubR }aUP%g qB 8L8'0amr~EBS<zO#]f^kPkgMjڕF ؀oүQV+̲l"̡<?~Բr7%գĻ߼ҋZ8Y>.(Zwus{>>zn~" 3kGU0 ysmL+/l=qNqO;)`TM_]MV~|@fVs-KXZΕG~Ohӛ-}u1̋DlZLhRڧ#&Ak|ܙS o&ؾb;CC>,V}yhw<9ݚ:񷰝q6kQbj,QQ4[>V3rEh<}Wd͡Z%x'0q-+ܹ]#N!kS/2sȞS@soxr 돾'2뜸}2O7C>&wϠ'~}Ϯ/,5~tKP E1]Oi"o$sk>Xd}e>%H-^s\Na(h :Ihjźu5f8.9o}Pdc{G(%;o8ĮQ+W( V\ys -}2|EmqV_}̡} \d2pg}Աw?yĻ`WbQ.0 w"h?(NrT&crqſzb[ WyvBT?f;|d~?5=~?8_ !TY|ǧzSyW[1 lA뺍F^}1^`Av=X@`[m>PG1&y%`Z^}Xڽ 2`y;S)CKbz,%DU"өl_hã x`w,=}۷P:^ ~ӫط^^nzb7~6}J+kR}й:TC}K |`*k%m Xt J|v쩱oJ %Qm SlqGrϙ%q07 yg\0LJgb[Ν?l:",Hw]_1S7?mya~G*_f D@j9nc.1M[ս+qRHk{g-Ip 3KgNyo$}> J`j v?q%sURRαVzVOH`6:˶g RSa?Og4; ),c_W*=7L^IL8ix*t8~.+V#h`f ʿyCkQqLKK~!RُdɈ( *^F!05UFLjw%cǛ"%?3^\e qwtt`@گ6}oFYcQ\F5d Sk?w{wEafM˜#~]|?EN?OF8| fLr1*i\guYs1Nl5UC̟?P%㬬K`rB4[G?~bաΦȽNmׅe̲Y]^> tX>"Am>s[w u3:]*b-ɐiC'G~_j"X+`4F89(it?$ V龫^[ l[(_K)J?6nY%&lg1wpBE(NyhrR bW1>+} 'Y^vUQh%]oUQ\Gn%yӤ`1\k`Zs6;נ!]C wUQjf5pck{+kޢ\{@C_[U7e8A\~KC =? GxE[ coK?P7aݍL̡3d_1r>Dmoyѳ"E [~|W^izQ:PסHi{|, y_~/= m'=x|BsmVO Aԍlk`|U׾pcL3"NUq6uÚ:up6nr13׌?9>ktʍ~}2$HMK 9'>}M yk=r:Б]j'aU O_n;Dc& R֓QPNG  IHDR]< PLTEi#bKGDH cmPPJCmp0712OmIDATx](@z}QN`4FuAlTԅ+WGY.?xS|45g*; Wd&<w*\>s5sq;.g L\we){%YWrpKN C7eepLQĒm]44W Ҏ^ ̻L8+ɶ]!p;;zQ~ԓٸ3`'c;v.X_̺?=V:$.{q\\ ALelALjD\nH/h^*\f44%|˟5aK \uCF᣸CֵVRÂ<W[׍FqﶒtL}l1 ?,{T E.k~64ٺJX6eopًPϷ7qbTW.~70b;+ *ns+q #b]I;F \ڙ70q1VQi00ΤWrWкZq\9,q # 5U^]5F :M̺VJ\(.ںVL72l\S\vr62ݺpu5n F7 믘FuAY2nHaDpsˎᆄٳܰ s;Pܠϖ8 9 #t]7w!\}Ej1C9`ʺjj{2U<׌Fw<٦f UeX2'+AY2." S\ȾGbhݐ?[6 cdjςtDܰ_Y7;:#m#tics+%S-y1{"tFnHgꗀ .{A m4\} (sq$1EB2Kq9]44iLֽ.qK;WppgpSwcTKk>IM.•pE&HQsBZɏ'  Ĩ$FGkqrҝ  F%. na#w* nqf#vZ+*E}x :H1*)\s^D/ o.bD| fDz΄2>jº.[e=m ﲸ4 +j50d;#B+c֥Z7p{~uw8u+F(.ΧB^k]v|z6. UW7"xu1\Ajw<.<UWz)4+gB1\u> SqW nu7,C۸NFJ ݋+yI}e+ZU.\¥O}.]b|WKN"zV#3;Ⱥ2LPWxt+PUp? jucTpEnL\8/l]Ӻp@3wh8 %n@ozEJt W&օ +pMWw\R`]/ *m*m.:hOP“gƵep`ӺruE!/AwC #2 xC KørƷ ָR@ozE0ڐnƦj\y\Iכ $U[떀Ջ?^P ddXIsvκ :u%_[w3,q9G+w]%M\\RG'%qΖ/ϥ"^ppm^|7]c.T_MsstRBƕ<ڟPuY7Mׂʡf\ :f\| wBBJV>ݠR$J۸̮qu͡qJ\lIgO'ߍ+(7eRȺ4afV.Zpiv&.m]O&-p)e]zefI: Gsøcss>:\KU>nƕ3y>\_w<{AJN||q؝h{<p}(p3{ɸlL#HݸKpqcDP՞غ.Ԋ(|OvjIlz`Z납gܡG! Yr\;uf<\8,hݩOdƅS¸۩mr9RyOߒWcql Bys>tA; pdwz?5.+ ~kw5%oqͯfg5LFql) ͖R;_ƭWGU7 bƵtX59;۲5ݠ ;II)},n\)j!C]Jq~\,hh@o$(u qIX̪tFVZT&DT[d9)E:6r,dz ]א~t}yԺ1X".M}yY+:}t~qE! `pyt+n)%}z!qYwyU f|R@3TR%n8K/{p,n(K..(n0㋇;O=n eqe WzKP2.S[/&.2d\ }7lN'wRC/.äIa.ueĺR^MIyvwzv+GMa-p^Qܺڅ>U cSXKk#I { ~Źg삝z#F 3,:vTkg]$mgU>I*%\x6 V\3{rŨ}P,]g< /n|leXeuG9.OL.=Sp↊' 'ƭ d,y: %$YȞYʺ~E8{f\^L +Y?2Dp˹XY }.W|QpK)hp"nFJ\|\\p \- nkn{+\|#JOΞ5\[-=˸vΞYh⨀gn)@B!1^kql==n WA3cÔ]bX9V˛o]1SVAKaq˪Gg|Wx?\Yq,ĥ>ծR\#ϹjzFX%oӂ|hNk&Zŵq<@.=kZ WSqbϡq\o=wv"]w] ֵQgFq"U򼣟zGΞ5Q\^wȞMzySqyܬ&Ĵ"-jmh<@ZܼKÍt%sK{@^d]'ω3W;aקn p4A:y`:|wHqŽ*V<'6pNK3BLZ/ ;;ҐQBV;sigRu5Wna\F<̓Ԗ]Eː\hw\ {"\X7+PS帙Jӓl+.ʹ'.Ǥ8ƷfjE: ]n0sp쿇qW !ʱYM|\8W~W;s:\k{AQ<:yNP3}֩DWF0|>ǽ7!ER=$GuZwfŬWs+u\zh#uu,R5G|w'7.f9\e0d.Pz09 qidgN'+)nKpzPACy.ͺPzB{tI`z ]|wH<%)20=oz}ytRd B7}7%]twGWl!)􂸁_l!)Zql!)Zql!)q-Ы=}pe *ǥsit<'MU.y帾<w~z\5 7d6 2-ٸbsݵ92<ۧtw8{ՌIٮw=l׍kR\yƕɬ5'V+y&Բ2#uJ\PIЉU* +m]Ȏ! [.nȊ mwEO•q/+V7YJN}pE`7{\>.֨NV7p% bܲ-zTW9WV$nffg u&\vff nm\e7'[H }po{)OF?=WߨGIENDB`nx}{J sPNG  IHDRX PLTEi#bKGDH cmPPJCmp0712OmPHƑޖSRE.Ƙ}NUJN,CAAAAR>GjXd4S`Na~1fn3BVVtVYIa7BuQB´eRSjkM{.HRp2ZZX:sjOssf)e+= "Ohfju>ؙM;sD03ckny fa^=A fufͭ^0 30bf̭FoE31 kYмch7^ۋa=ol?n8ahnu[5-&e~ Y4֐2El4]K(r0A<7eLu|h~w̎]ukB9g9y1ϜξB4~Ԝ}04yDͣ&j&;pG՜c&k ~lfg l14E)K :gy(4mskg:>"yvkO+O Mfޭlb8nՉO;؜?kN7:z<׆Xhljgܰf]iIu>ҚK4:YDvWf])[+ӄ燉aWL3y1xl[,Lr,ҒtaC|JӬNfE|Jlֶ/mFJYia;xI?_4r\ٱ7tm<}7_deo9|0RW[E0a~%sd/Pgafay3H{3"qaNf5)(&5Bi#Ik>} afayNKj1Od0 3Ͷ:u:JéVkkAbKs\Hdk|]A76泛|;1s¼AafV'GE4s^<)qsܿ/jץjݜUɎ'/E}書Vqcggvfafa~)SӚomG7[1S̺>t9.~-<ܘSfG U&6\eBsV|dYZ2iTӛ8>fۚ߳ȅǼsQܧtDnXg|d[j^o}GԼ32A<%YO*mN?lR24S֪YV\&beWcVtF\ۙۻ{i,stw;Pgєc꼢df.ñy@bMf|faf*yi`ٕMV3̱͛0 30 3̯c8Z/0J&)R`&afifaffaf`faafifⵍ?mݜW]TȢ!v^$3󗘚k7p0{pf)u}އ}ÈҘ" JaS5w >|-Ölm]U޾qΈ9ivcεjwf/h|柤߿NBQgfU:C̱0 30 ˘1s+afaf9έ8I;Mpci*CIENDB`n[-Vvݑ0PNG  IHDR PLTEi#bKGDH cmPPJCmp0712Om#IDATxώ8aߧ 6c@|+Sٱ8UTikF~hǏjժUVZjժUVZjժUVZjժUVY+`e_BV XȆ 5}d!ugz}݁Aȅ9͇C <H}QHo m+OEg E8B~sȱEHszB:$hAI+EٓI`N9!i.;fpeT^YOJ!ۋ@+ ?I{']SCHTt}e>9|52NNU9cH[!+d oII)zFNFB;5[퇔?E$]qO_ʋWH~ $̀R˳m[^kF{HB|~ջ!e A!eWtQU@nꭞ䘟j8i i7BfxrdF˓ jHB23Ծ/Mh4}CyRʶ/ hq*#۝'b4WF>Gu>RnyZt=P=ifmLCyj$ N6glIldhG8|6[ok%!]XqH"{ۅ3rhʢM}x[zr<s [wǫ Jg@H'6@n G۷x٦VfCNDkM[O7@vzrev+DoJ{# RYovAIVONDJy!uׂ^ ;k38wEZ9CO7u!-.q'o[z7䦫=z"dqOA,Y՞4Ґ ^7Az'%ΐUdrhC2!Ǔ6C; pwv|:`dn|`OZhrYHhZO1!]xק_ W '@\!Wg73 ruvc>1\XAnO!JKɵm3=dBsqVKA3\/Z 2 Y!C|'#9T=Zl=9` $LUd\DԹ#d 2cA>DI 2aT >m I Hm],@j2A q,+bK{P!}=I)OPpt]OOIn̺BV =B 3ȩg@rT"yyr&zr&zÍp^OX4 t2NrtWEۍŽ0+HX?fÂfjfn. T \ s̺BVM=L% -{Ք+ȵjs?; Ymׯ?{)GzJ䏱Z!yH ~X@׭Hl, IoI,gc9<)|8+Hb88m#oNd珡}'{/A$?PҫlJKȴظR>)|8۷$~䆫Y7Aλ?/HIyMν؞9Z`veulŴ֬;iguHy8Óp4Q:i5ؼӌ:%gA\l2 wws{z依 l+^LD 5wr&zr/GƓsыTr\^y]7񂜋gԲ HBqҿQ@nnPKoH]XA:Ojv=U~; "?; 2{U&jgH\-Zrxz+ȵ=NsqO 7$ޙ;eaȌ/.^! B(2# z E89d%}҉^6WD\!ж-L!]% }Y:N~rUB~H 8!I?`H҉FJj$z0W <ُ25'=)֐q8ɬ;uLNhW1YAc2\_d rm:sH?91u!H A?Ksj"8R-8\s0] -fA;,1VU _ClpA>r-99Q!w\!q1L f7m1dά!Rd.t+{C>.W8BX^F3 Q-e/#H7l3K 2U-e/'HKR,e/+ȉd/Wș ' SŲ2ȘQ{ gu {rrkt Ivc!3g Y!+d h|Og׉5DsD/6<2$Q5!%q#WYBiTsr5T Y!+!龬 1%;{pLj-o=X"Cȩ"Dc 9~Ka}^^qf Y!+d|#S*sq7ȉ%(6X'zUc9PKB79^u+'zr!z^^b'?jƩBV7BLomzf !!%7ȩPJ{@NEoklb9+oBN!ћҶ4KZ҉'o8qf Y!w@ '@ NQ ҉ a NzwANE/ M&A<{Ul WRy}>rȅ}'N襐Y3Nl5!C1 *t9Hf/'^&B!'yrwR*E^9!іdؽ-l.m \"${ڛwo@ 듹XrKC+Y֓Y!'$slc#L6nH[7"S%%ARk@تҐ>FZ#HCIڰyQxh{~ RJyd ; G ю r9C>'%cPe2=ʙ/97b'N):2^h>H'zM\8q`>H-h`''3+%zc!WV!+d|!aHm9]H+ >NHj@ ui|W0$A;O6?V=!c;t [' c5A,ɰC_>I^ gt9U Y!+$k|(f^j9VHuX r yAzѫ{_'T{!ÃtE/aݠz}ݞϬ}7weL|BVO WC,HSWħ9 jË! e@? .Rћ2&!Ic< iUZʁ. 8!3B!w/"@lj/@'z!ِG\D/kCEo6d=!z!!8 >S!+deEѓo &2o2dXOn[ 尳'!ITOƏO'+d}AL>q!!)nD)4AF`'+O nٖw_z`)Ҷ#Md= }@:'m>͍h >g Y!+d|/$ 2Wio q|sS!Knk4',vM/%zr< Hb9z2ow3O-8 '@r5vqړBpR21 '񇴝eOr'C";pU y}Cj ?kf/IENDB`n 67ۅRPNG  IHDR^} PLTEi#bKGDH cmPPJCmp0712Om vIDATxͮ*)wɼA6OKbl$xʡ9mE9Q;eWEQoں 6y~kݙl\9B{F()c v;(/nc**l 5lw;1;(Nk5ņs쇵Nwʽ>dkUwQS2ZUc]2^:,Z3-X`5ئmG7g鶠N-t-6"i}v4svl,ƻ)T;?Mc{5fzy߽GVhVfܾ1g?}}l+vl6_ާi.Ҕ W#mKJ$;}m[AH#ܯ&cAuV}{J3 X>I܄{R]ƤU}t=ћMvxM`>(nPZ/v0aIrɭ,}D1Mϻ:]Msڏ$>=fmam0IPS(۸.a|,:1C,[ʑbv^Şʍ:)M z޺ t (_l֘ 5ۮEװ<_TX,_T4fEm+|QYv/͎k%/Yh/ی铢~͍ }m,$zZ*Fϖi#l$m92DSׯor7!d(o?lBIZإcMl%*(o֟S_ʖekEvљY_kk~U0ɑ zXIپ0'9fr{l؝sGOy1n +*uPt흚VB-ѝm; JYцblO#쨷0[Q)ǦAz^˥;8.& muv3m-AaE;v@icp3hSQs?R&09ؙ l߯H́nvʁfg@3sȽ/Zyg@˲k\ Ŗا 陿+z(;8L3a|ZYqN3[=MG3fe|>_[cFSWu6hbEi6L =[Tɉޱ`aH \``L۫In> 0H쵵4ynGn;t7w =^.-}֚Rآnnf8ML;܉ RR^.3i&[X|APӫ&NX,>e )XX}+,Xźd9*%t,kv{ q(/3x, ٗo?[dd]mrme5>Vƶw[m;gcuQj'{y!v> :6; v0eCPb:F*viٸrƆٛ}9_| a]ƾ ٻ6{ bfAro$0W fo$\ζ<|7׾Kwv*y0 _Q-v _Tf←8۟{P?}?#w/Z;-gS~9t~ߍg1\xز JLX;`D[-My/=TZ5SR~uwNpepB#)xWu8yJU{hX<{쵾i^wU4^ȶWR؞/~8v%7}t{Z*35,=^›2 ~=/c@G(p-de #ӜlZ nv|b.jova0Wqv0\< r7aCYeC{0q}A׌,T Eyx89bGZ,[wJM>=gb$%7-eF`k vxaS*1گ{4 NwtMl)'즢N,fmagJ]/)R}"v8]}x.P}|ء@Ϋۖwݧp0_} I67PMý-Rv*xE9g+Զw>v,lcה*ۦೱL=GjphsDJN/3ce!Y$w~;C_fbefoa=VִaS0Xιdb5[PIĠ%ÑaP/@nZOsWlCl^VvÇш̥ةIϓl&>~{;L@^ѥVl<x^.,v'CO`a'Czl.>~{;6we!5AA2%|ذ/facظG~4name How to access functions of the object (case insensitive) $oLayer = $oMap->getlayer(0); ZDZ5ZZ9ZZZZZZA6:               D  C        ,Access to the Map object  How to modify member of the object $oMap->set("name", "a new name"); common mistake : $oMap->name = "a new name"; How to access the sub objects $oMap->web->set(...); #X!Z%  5  8   - Layer Object     . Access to the Layer object  Accessing layers through the map object $nLayers = $oMap->numlayers; for ($i=0; $i<$nLayers; $i++) { $oLayer = oMap->getlayer($i); echo $oLayer->name; . .. } Creating a new layer $oLayer = ms_newLayerObj($oMap) $oLayer->set("name", "my_new_layer"); $oLayer->set("type", MS_LAYER_LINE); //can be used to create a layer from another layer : $oLayer = ms_newLayerObj($oMap, $srclayer) (ZZZZ()                 )         !  X          /  Layer object   Diffrent types of layers : predefined constants MS_LAYER_POINT, MS_LAYER_LINE, MS_LAYER_POLYGON MS_LAYER_RASTER MS_LAYER_ANNOTATION MS_LAYER_QUERY MS_LAYER_CIRCLE MS_LAYER_TILEINDEX ,00   0 Class and Style  Accessing classes through the layer object $nClass = $oLayer->numclass; for ($i=0; $i<$nClass; $i++) { $oClass = oMap->getclass($i); echo $oClass->name; ... } Creating a new class $oClass = ms_newClassObj($oLayer); $oLayer->set("name", "my_new_layer"); ... f+ZZZTZ,SD-                ,         ' 1 Class and Style  Creating a new style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 1); ... Will be covered with examples in Advanced Features section XG;F;t         W 2Shapefile Object    3Shapefile manipulation    Open existing shapefile //first argument is the shapefilename without the extension //second argument (type) is set to -1 to open an existing file $oShapeFile = ms_newShapefileObj("my_shapefile", -1); Creating a shape object //The argument represents the type of shape object to be created. //Valid types are : MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON $oShape = ms_newShapeObj(MS_SHP_POINT); n       Y              4Shapefile manipulation    Creating a line/Point object $oLine = ms_newLineObj(); $oPoint = ms_newPointObj(); Will be covered with examples in Advanced features sectionL9;8;t           @ 5Application Building : Contents  *Drawing a Map Adding a Key Map Adding a Scalebar Adding Navigation Tools (zoom in, & ) Navigation using the Key Map Adding a Legend HTML Legend Query &(   e 9!Prepare the application structure " Directory structure of the application (data, map file, html, symbol file & ) URL to access the application Temporary files {  7The whole application  whttp://http://localhost/mum2_php_mapscript/index.phtml The directory /ms4w/apps/mum2_php_mapscript/ Data, htdocs, etc wxt1           06:Application structure  Index(X).phtml and step(X).php Separate HTML from the PHP code Phtml file contains already calls to PHP functions. PHP functions are there but are empty. t         T   ;Step1 : General  http://localhost/mum2_php_mapscript/index1.phtml /ms4w/apps/mum2_php_mapscript/htdocs/Step1.php /ms4w/apps/mum2_php_mapscript/htdocs/index1.phtml 0                       00<Step2 : Adding a map  uLoading the php mapscript module Loading the map file Draw map function function DrawMap() { $img = $GLOBALS["goMap"]->draw(); $url = $img->saveWebImage(); $nWidth = $GLOBALS["goMap"]->width; $nHeight = $GLOBALS["goMap"]->height; echo"\n"; } .HZ.ZH.   6                          0          =Step3 : Keymap&   Draw a key map function DrawKeyMap() { $img = $GLOBALS["goMap"]->drawreferencemap(); $url = $img->saveWebImage(); echo "\n"; } .ZZ                   &     >Step4 : Saclebar&   Draw scalebar function DrawScaleBar() { $img = $GLOBALS["goMap"]->drawScaleBar(); $url = $img->saveWebImage(); echo"\n"; }                            ?#Step5 : adding Navigation (zoom in)$$$ $ Know what type of navigation is selected $_GET ($_POST) : super global associative array for HTTP GET Preserve current map extents, width and height   @$Step 5 : adding Navigation (zoom in)$% $ % Top of the file $aVars = (sizeof($_POST) > 0) ? $_POST : (sizeof($_GET) > 0) ? $_GET : array(); ProcessURLArray( $aVars ); In DrawMap function echo"\n"; echo "extent->minx."\">\n"; echo "extent->miny."\">\n"; echo "extent->maxx."\">\n"; echo "extent->maxy."\">\n"; `ZlZZ Zl              *       ]  _     O     O         A$Step 5 : adding Navigation (zoom in)$% $ % Nfunction ProcessURLArray( $aVars) { //set up the previous extents $oExt = $GLOBALS["goMap"]; $fMinX = isset($aVars["MINX"]) ? $aVars["MINX"] : $oExt->extent->minx; $fMinY = isset($aVars["MINY"]) ? $aVars["MINY"] : $oExt->extent->miny;; $fMaxX = isset($aVars["MAXX"]) ? $aVars["MAXX"] : $oExt->extent->maxx;; $fMaxY = isset($aVars["MAXY"]) ? $aVars["MAXY"] : $oExt->extent->maxy;; $GLOBALS["goMap"]->setextent( $fMinX, $fMinY, $fMaxX, $fMaxY ); //some short cuts $fWidthPix = $GLOBALS["goMap"]->width; $fHeightPix = $GLOBALS["goMap"]->height; OZO    +                                                                                         B#Step5 : adding Navigation (zoom in)$$$ $ T//process commands if (isset($aVars["CMD"])) { //determine where to navigate to. $nX = isset($aVars["MAINMAP_x"]) ? intval($aVars["MAINMAP_x"]) : $fWidthPix/2.0; $nY = isset($aVars["MAINMAP_y"]) ? intval($aVars["MAINMAP_y"]) : $fWidthPix/2.0; if (isset($aVars["MAINMAP_x"]) && isset($aVars["MAINMAP_y"])) { $oPixelPos = ms_newpointobj(); $oPixelPos->setxy($nX, $nY); $oGeorefExt = ms_newrectobj(); $oGeorefExt->setextent($fMinX, $fMinY, $fMaxX, $fMaxY); if ($aVars["CMD"] == "ZOOM_IN") { $GLOBALS["goMap"]->zoompoint(2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } } } } $TZZU    C          =             =           '                                     >                 $ C Step 6 : All Nav. tools&    Modify function ProcessURLArray to look for other CMD values & . else if ($aVars["CMD"] == "ZOOM_OUT") { $GLOBALS["goMap"]->zoompoint(-2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "RECENTER") { $GLOBALS["goMap"]->zoompoint(1, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "ZOOM_FULL") { $GLOBALS["goMap"]->setextent($GLOBALS["gfMinX"],$GLOBALS["gfMinY"], $GLOBALS["gfMaxX"],$GLOBALS["gfMaxY"]); } .=ZZHb  <  ?                 '  ?                 '  @           ;        D!Step7 : Keep selected tool  j$GLOBALS["gszCurrentTool"] = "ZOOM_IN"; function ProcessURLArray( $aVars) { //record the current command $GLOBALS["gszCurrentTool"] = (isset($aVars["CMD"])) ? $aVars["CMD"] : "ZOOM_IN"; & } function IsCurrentTool( $szTool ) { return (strcasecmp($GLOBALS["gszCurrentTool"], $szTool) == 0); } .)Z Z) D       3         &              E"Step8 : KeyMap navigation &    )Inside function ProcessURLArray else if (isset($aVars["KEYMAP_x"]) && isset($aVars["KEYMAP_y"])) { $oRefExt = $GLOBALS["goMap"]->reference->extent; $nX = intval($aVars["KEYMAP_x"]); $nY = intval($aVars["KEYMAP_y"]); $fWidthPix = doubleval($GLOBALS["goMap"]->reference->width); $fHeightPix = doubleval($GLOBALS["goMap"]->reference->height); $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $oRefExt->minx, $oRefExt->maxx, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $oRefExt->miny, $oRefExt->maxy, 1); $fDeltaX = ($fMaxX - $fMinX) / 2.0; $fDeltaY = ($fMaxY - $fMinY) / 2.0; $GLOBALS["goMap"]->setextent($nGeoX - $fDeltaX, $nGeoY - $fDeltaY, $nGeoX + $fDeltaX, $nGeoY + $fDeltaY); } . Z Z                  %                              &                                                          &           F#Step9 : draw legend   function DrawLegend() { $img = $GLOBALS["goMap"]->drawLegend(); $url = $img->saveWebImage(); echo"\n"; }                           G$Step10 : HTML Legend  hDocs at : http://mapserver.gis.umn.edu/doc40/html-legend-howto.html The HTML legend is an alternative to the traditional GIF legend in MapServer Set TEMPLATE "legend.html in the map file inside the legend object [leg_layer_html order=ascending opt_flag=15] <tr height=20px> <td align="center"><input type="checkbox" name="legendlayername[]" value="[leg_layer_name]"[if name=layer_status oper=eq value=1]CHECKED[/if][if name=layer_status oper=eq value=2]CHECKED[/if]></td> <td>&nbsp;<img src="[leg_icon width=20 height=13]" width=20 height=13>&nbsp;</td> <td><font face="Arial, Helvetica, sans-serif" size="3">[metadata name=DESCRIPTION]</font></td> </tr> [/leg_layer_html] :ZZZv  9 D   u      1    +    %    5  n      0 CH%Step 10 : HTML Legend  1Call function DrawHTMLLegend(); in index10.phtml function DrawHTMLLegend() { echo ""; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo $GLOBALS["goMap"]->processLegendTemplate( array() ); echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
Update
"; } P3ZZ3x                N        )    5  T  " I&Step11 : Layer control  bInside function ProcessURLArray & //process layer visibility if (isset($_GET["legendlayername"])) { for( $i=0; $i<$GLOBALS["goMap"]->numlayers; $i++ ) { $oLayer = $GLOBALS["goMap"]->getLayer($i); if (in_array( $oLayer->name, $_GET["legendlayername"] )) $oLayer->set( "status", MS_ON ); else $oLayer->set( "status", MS_OFF ); } } . ZZ"^  &    +             !      <  *   J'Step12 : Query  Set templates in a layer Function ProcessURLArray & . else if ($aVars["CMD"] == "QUERY") { $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $fMinX, $fMaxX, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $fMinY, $fMaxY, 1); $oGeo = ms_newPointObj(); $oGeo->setXY($nGeoX, $nGeoY); // Use '@' to avoid warning if query found nothing @$GLOBALS["goMap"]->queryByPoint($oGeo, MS_MULTIPLE, -1); $GLOBALS["gShowQueryResults"] = TRUE; } .2Z<Z59b"    3        !            !                 b       /     K(Step12 : Query  L$GLOBALS["gShowQueryResults"] = FALSE; function DrawMap() { if ($GLOBALS["gShowQueryResults"]) $img = $GLOBALS["goMap"]->drawQuery(); else $img = $GLOBALS["goMap"]->draw(); & function DrawQueryResults() { if (!$GLOBALS["gShowQueryResults"]) echo "&nbsp;"; else { $sTemplate = $GLOBALS["goMap"]->processquerytemplate(array(), 0); echo $sTemplate; } }$'ZZ                           %             6Advanced Features  ZCreating a new Shapefile Adding a new layer dynamically Adding classification dynamically @   @   L)Creating a shape file  :Files advanced.phtml and advanced.php function AddDynamicLayer() { //Creating the shapefiles $oMap = $GLOBALS["goMap"]; $szFileName = $oMap->web->imagepath . uniqid(""); $oShapFile = ms_newShapeFileObj($szFileName, MS_SHP_POINT); //create a new DBF attached with few attributes $hDbf = dbase_create($szFileName.".dbf", array(array("POP_RANGE", "N", 5, 0), array("NAME", "C", 50, 0), array("CAPITAL", "N", 5, 0))); if (!$hDbf) return; .&ZZ&                                   K        M*Creating a shape file  Jopen the original dbf file $szOrginalDbfName = "../data/canada_cities.dbf"; $hOrigDbf = dbase_open($szOrginalDbfName, 0); if (!$hOrigDbf) return; $nRecords = dbase_numrecords($hOrigDbf); for ($i=1; $i<=$nRecords; $i++) { //retreive field attributes $aRecord = dbase_get_record_with_names($hOrigDbf, $i); $dfLat = floatval($aRecord["LAT"]); $dfLong = floatval($aRecord["LONG"]); $nPopRange = intval($aRecord["POP_RANGE"]); $szName = strval($aRecord["NAME"]); $nCapital = intval($aRecord["CAPITAL"]); KZK                                                               N+Creating a shape file  a//create a point for each record and add it to the shapefile $oShp = ms_newShapeObj(MS_SHP_POINT); $oLine = ms_newLineObj(); $oLine->addXY($dfLong, $dfLat); $oShp->add( $oLine ); $oShapFile->addShape($oShp); //add a record to the DBF $aAttValues[0] = $nPopRange; $aAttValues[1] = $szName; $aAttValues[2] = $nCapital; dbase_add_record($hDbf, $aAttValues); $oShp->free(); } dbase_close($hOrigDbf); dbase_close($hDbf); $oShapFile->free(); //Add a new layer in the map CreateLayer($szFileName); } .aZZa2                                    /                          !       +        O,!Adding a new layer and styling it " function CreateLayer($szDataName) { $oMap = $GLOBALS["goMap"]; //create layer and set members $oLayer = ms_newLayerObj($oMap); $oLayer->set("name", "canada_cities"); $oLayer->set("status", MS_ON); $oLayer->set("data", $szDataName); $oLayer->set("type", MS_LAYER_POINT); //projection is latlong $oLayer->setProjection("init=epsg:4326"); $oLayer->set("labelitem", "NAME"); $oLayer->set("classitem", "CAPITAL"); Z.            ,                    3                    P-!Adding a new layer and styling it " ] //Country capital //create class $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Capital"); $oClass->setexpression("/1/"); //create style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 2); $oStyle->set("size", 8); $oStyle->color->setRGB(255, 0, 0); //set label object $oClass->label->set("font", "fritqat-italic"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(255, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); "^Z]b+               "                 *      (           (  % Q.!Adding a new layer and styling it " <//provincial capitals $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Provincial Capital"); $oClass->setexpression("/2|3/"); $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 7); $oStyle->set("size", 6); $oStyle->color->setRGB(0, 0, 0); //set label object $oClass->label->set("font", "fritqat"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(0, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); }=Z=b         *                      (       (           (  & F  ` ` ̙33` 333MMM` ff3333f` f` f` 3>?" dd@,|?" dd@   " @ ` n?" dd@   @@``PR    @ ` ` p>> xf(    6@j P  T Click to edit Master title style! !  0l   RClick to edit Master text styles Second level Third level Fourth level Fifth level!     S  0Tq ``  >*  0v `   @*  0{ `   @*  A޽h ?C:\Documents and Settings\jody.DMSG\My Documents\Presentations\birdge-e.jpg ̙33 Default Design 0$(  r  S $wC C r  S wC `   C H  0޽h ? ̙33 P0(  x  c $L{y` y x  c ${y y H  0޽h ? ̙33  `$(  r  S kyP  y r  S (ly y H  0޽h ? ̙33  p$(  r  S uyP  y r  S vy y H  0޽h ? ̙33  $(  r  S yP  y r  S \y y H  0޽h ? ̙33  F>(  r  S "yP  y r  S t#y y   C AjC:\Program Files\PoseidonCE1.6.1\projects\global.gifPe?H  0޽h ? ̙33z  *"(  r  S *yP   y r  S +y y   C fANC:\phpms_workshop\object_model\map.gifPH  0޽h ? ̙33  $(  r  S ('yP  y r  S ly y H  0޽h ? ̙33  $(  r  S :yP  y r  S :y y H  0޽h ? ̙33~  .&(  r  S CP  C r  S C C   C jARC:\phpms_workshop\object_model\layer.gif0`H  0޽h ? ̙33  $(  r  S CPPp`  C r  S C  C H  0޽h ? ̙33  $(  r  S tyP  y r  S 0y y H  0޽h ? ̙33  $(  r  S xyP  y r  S 4y y H  0޽h ? ̙33  $(  r  S yP  y r  S y y H  0޽h ? ̙33  4, (  r  S yP  y r  S y y   C pAXC:\phpms_workshop\object_model\shpefile.gifP`aH  0޽h ? ̙33  0$(  r  S yP  y r  S y y H  0޽h ? ̙33  @$(  r  S yP  y r  S y y H  0޽h ? ̙33  P$(  r  S TyP  y r  S y y H  0޽h ? ̙33  0(  x  c $|]P  ] x  c $ n] ] H  0޽h ? ̙33  @$(  r  S  yP  y r  S 4 y y H  0޽h ? ̙33  $(  r  S 4?]P  ] r  S z] ] H  0޽h ? ̙33  $(  r  S Te]P  N r  S |] ] H  0޽h ? ̙33  $(  r  S N`  N r  S N  N H  0޽h ? ̙33  $(  r  S )NP  N r  S FN N H  0޽h ? ̙33  $(  r  S NP  N r  S N N H  0޽h ? ̙33  $(  r  S NP  N r  S  iN N H  0޽h ? ̙33  $(  r  S dNP  N r  S P] ] H  0޽h ? ̙33  $(  r  S  P   r  S l  H  0޽h ? ̙33  $(  r  S  `   r  S `   H  0޽h ? ̙33    $(   r   S s0   r   S w0P   H   0޽h ? ̙33  0$(  r  S Y   r  S N @ N H  0޽h ? ̙33  @$(  r  S /   r  S 0]` ] H  0޽h ? ̙33  P$(  r  S  `P   r  S )  H  0޽h ? ̙33  `$(  r  S mP   r  S <  H  0޽h ? ̙33  p $(   r   S P   r   S   H   0޽h ? ̙33  $$(  $r $ S KP   r $ S L  H $ 0޽h ? ̙33  ($(  (r ( S    r ( S d] ] H ( 0޽h ? ̙33  ,$(  ,r , S ,   r , S 80  H , 0޽h ? ̙33   $(  r  S gCP  C r  S hC C H  0޽h ? ̙33  0$(  0r 0 S *vbN .: QAΩ(   lhttp://http://localhost/mum2_php_mapscript/index.phtmOh+'0R `h  0 < HT\WOpen Source Technologies Supporting Publishing and Discovery of Geospatial InformationDM Solutions Group Inc.Assefa Yewondwossen119Microsoft PowerPointc.@0@6@P(LGPg  R('& &&#TNPP2OMi & TNPP &&TNPP     'A x(xKʦ """)))UUUMMMBBB999|PP3f3333f333ff3fffff3f3f̙f3333f3333333333f3333333f3f33ff3f3f3f3333f3333333f3̙33333f333ff3ffffff3f33f3ff3f3f3ffff3fffffffff3fffffff3f̙ffff3ff333f3ff33fff33f3ff̙3f3f3333f333ff3fffff̙̙3̙f̙̙̙3f̙3f3f3333f333ff3fffff3f3f̙3ffffffffff!___wwwܻ ⼻ݻ⼼ܻݻ»ݻܻ ݻݻݼﶼﵒݼݼ¼ݽ¼ݼݼݼ“¼ݼﵓﻵݼݼݼݼݼ޼񼼼¼񼻼ݼ޻ݼ񼼼⼼ﵼݼﻼ½⼓񼘵¼⼶ݼ񼵘½¼ݼݼ⼵񼼼¼¼ݼ񼼼ݼ¼ݽݼ񼼻ݼݼݻݼݼݼݼ񼼼ݼ\⼼ݼݼݼݼﻼݼ⼼ݼݼݼݽݼ¼ݼ񼼻ݼ¼޼ݼݼݼݼݼ⼼ݼݼݼ¼⼼񼼼޼ݘﻼݼ¼ݼ¼񼼼ݼ¼¼ݼﻓ⼶[ݼݼݼݼ񼼼2⼼ﵼݼ񼼼¼¼񼼼ݼ񼼼ݼ񼼼񻓒8⼼ݼ¼񼼼¼񼼵ﵼﻶﻼݼ񼼼⼼¼¼ݼݼݼ⼼ݼﵙݼݼݼݼݼݶݼ¼⼼¼ﵙ½ݼݼݼݼ񼻶ݼ⼓ﻶ¼ݙ\ﵙݼ¶񼻓⼓ݻ¼ݼݼﵙݼ񼼻⼓¶񼼼ݼݼݼﶘݼݙ޼ݼ񼼽ݼ¼ݼݼ⼼¼ݼ޼¼񼻶޼ݼ¼ݼµݼ⼼ݼݼ⼼¼޼ﶘ⼻ݼ⼼ݼݻݼݼ⼼ݼݼݼ񼙻⼼¼ݼݼݼ⼵ ݼݼ¼ݼ񼼻⼼ݼ⼼ݻݼ⼼񻼼ݼ¼ݼ¼ݼݼݻݼ񼼻¼ݼ ݼܼݻ⼼⼼ݼ¼⼼ݼݼ⼼ ⽼¶ݼ⼼޼⼼ݼݼݻ⼼⼼ݼ¼ܼݼݼܼ޼޼񼼼ݼݼݼݼݻܼݼݼݼ⼼⽼⼼¼ݼݼݻݻݼ¼ݼݼܼݼݼ⼻ݼݼݼݼݼ¼ݼܼܼ¼ݼݼ⼼ݼ⻼»¼ݼ⼼ݼݼݼݼݼݼݼݼݼ¼ݼݻ¼񼼻޼¼ݼݼݼݼݼݼݼݼݼ⼼¼¼񼼼¼¼ݼݼݼݼݼݼ⼼ݼݼݼݼ¼¼¼ݼ¼¼ݼݼݼݼ¼ݼݼ⼼ݼ¼ݼ¼¼ܼݼݼݼݼ¼ݼݼݼݼݼ¼⼼ݼ¼ݼݼ޼񼼼ݼݼݼ¼ݼݼݼ¼ݼ¼¼¼¼ݼݼݼݼ¼ݼݼݼ⼼ݼ¼¼⼼ݼݽݼ¼¼ݼݼݼݼݼݼ¼ݼݼݼ¼ݼݼ¼¼ݼ¼ݼ¼ݼݼ¼ݼݼ¼⽼ݼ񼼼ݼݼ⼼ݼ¼ݼݼ¼ݼݼݼݼݼ¼ݼ¼⼼¼ݼݼݼݼ¼¼ݼݼ޼񼼼ݼݼ¼¼ݼ¼ݼݼݼ¼¼ݼݼݼݼ⼼ݼ⼼ݼݼݼ¼񼼼ݼ¼ݼ⽼ݼݼ¼񼼼ݼݼݼݼ¼ݼ񼼼ݼݼݼݼ¼¼ݼ¼ݼ񼼼ݼݼݼݼ⼼ݼݼ¼ݼݼݼ¼ݼ¼ݼ¼񼼼¼ݼݼݼ¼ݼݼ¼⼼񼼼¼ݼݼݼݼ¼ݼ¼¼ݼݼ⼼ݼݼ¼¼ݼݼ¼ݼ¼ݼݼݼ¼¼ݼݼݼ¼ݼ⼽ݼݼݼݼݼ½ݼݼüݼ¼⼼ݼݼݼ¼ݽݼݼ¼⼼¼¼ݼ¼ݼݼݼ½ݼݽݼ¼ݼݼ¼¼ݼ񼼼ݼ¼ݼݼݼݼ޼ݼ½ݼݼݼ¼ݼݼݼݼ޼ݼ񼼼¼ݼ¼ݼݼ⼼ݼݼ¼ݼݽݼݽ⼼ݼݼݼ¼¼ݼݼ⼼ݼݼ¼½½ݼüݼ޼½¼¼ݼ⼼¼ݼ¼ݼ¼ݼݽݼݼݼݼ񼼼ݼݽ½ݼݽ½ݽ¼ݼ⼼ݼ¼⽼½½޼ݽݼ½ݽݽ⼼¼ݼ񼼼ݽ½½޼ݽ޼޼޼¼⼼⽼½ݽݼݽݽݽ¼ݽ⽼޼޼޼ݽݽ¼½ݽ½ݽ¼¼޼ݽݽݽݽݽݽݽ޼޼ݽ½ݽݼݽݽݽݽݽݽݽݽ½½պ۴պ۴պպպ۴۴պ۴۴۴۴۴۴պպ۴պԺ۳ճۺܺۺ۴ۻۺݹ--&TNPP &.phtmlt`http://localhost/mum2_php_mapscript/index1.phtmlrhttp://mapserver.gis.umn.edu/doc40/html-legend-howto.html/ 00DTimes New Roman30Wo 0DArialNew Roman30Wo 0" DArial Unicode MS0Wo 00DCouriericode MS0Wo 0 ` .  @n?" dd@  @@`` LT.     !"#$%&'()*+,/012_R$-o1R䰹mE sb$Dc& R֓QCsb$x}{J sb$[-Vvݑ0b$67ۅR 3,c $@7a<@ʚ;2Nʚ;g45d5d0ppp@ <4!d!d 0h4<4dddd 0h4 ? % PHP Mapscript( ? Yewondwossen Assefa Daniel Morissette DM Solutions Group Inc.@@ %Contents  h Introduction to PHP Mapscript Object Model Application building Some Advanced features Questions &hi H&What is PHP Mapscript&     one flavour of MapScript (Perl, Python, Java versions exist also) custom extension for PHP abstracts the MapServer object model in PHP constructsZ     K     'Why do we use PHP Mapscript&    ;Because it provides the ability to do things that can't be done in MapServer's CGI mode Dynamic layers Customized navigation On the fly classification Enhanced legends and layer controls Advanced query capabilities PHP is an advanced open source programming language with significant modules such as GD, dbase, odbc<Z<@C      ) Object Model  4Cover the main objects found in php/mapscript and how to access members and functions of some of the objects Php Mapscript : "Jacket" on top of mapserver library Most of the mapserver elements accessible through php/mapscript Documentation at : http://mapserver.gis.umn.edu/doc/phpmapscript-class-guide.html5Z5D      A                          (Object Model : global view    * Map Object   +Access to the Map object  How to create a new map object $oMap = ms_newMapObj("mymapfile.map"); $oMap = ms_newMapObj(""); How to access members of the object (case sensitive) echo $oMap->name How to access functions of the object (case insensitive) $oLayer = $oMap->getlayer(0); ZDZ5ZZ9ZZZZZZA6:               D  C        ,Access to the Map object  How to modify member of the object $oMap->set("name", "a new name"); common mistake : $oMap->name = "a new name"; How to access the sub objects $oMap->web->set(...); #X!Z%  5  8   - Layer Object     . Access to the Layer object  Accessing layers through the map object $nLayers = $oMap->numlayers; for ($i=0; $i<$nLayers; $i++) { $oLayer = oMap->getlayer($i); echo $oLayer->name; . .. } Creating a new layer $oLayer = ms_newLayerObj($oMap) $oLayer->set("name", "my_new_layer"); $oLayer->set("type", MS_LAYER_LINE); //can be used to create a layer from another layer : $oLayer = ms_newLayerObj($oMap, $srclayer) (ZZZZ()                 )         !  X          /  Layer object   Diffrent types of layers : predefined constants MS_LAYER_POINT, MS_LAYER_LINE, MS_LAYER_POLYGON MS_LAYER_RASTER MS_LAYER_ANNOTATION MS_LAYER_QUERY MS_LAYER_CIRCLE MS_LAYER_TILEINDEX ,00   0 Class and Style  Accessing classes through the layer object $nClass = $oLayer->numclass; for ($i=0; $i<$nClass; $i++) { $oClass = oMap->getclass($i); echo $oClass->name; ... } Creating a new class $oClass =   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#e%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMOPQRSTUVWXYZ[\]dfghijklmnopqrstuvwxyz{|~Root EntrydO)P~(L Pictures89Current User%YSummaryInformation($HRPowerPoint Document(pDocumentSummaryInformation8 lt`http://localhost/mum2_php_mapscript/index1.phtmlrhttp://mapserver.gis.umn.edu/doc40/html-legend-howto.html/ 00DTimes New Roman3|d0|Wo 0DArialNew Roman3|d0|Wo 0" DArial Unicode MS|d0|Wo 00DCouriericode MS|d0|Wo 0 ` .  @n?" dd@  @@`` LT.     !"#$%&'()*+,/012_R$-o1R䰹mE sb$Dc& R֓QCsb$x}{J sb$[-Vvݑ0b$67ۅR 3,c $@7a<@ʚ;2Nʚ;g45d5d0pppp@ <4!d!d 0,4<4dddd 0,4 ? % PHP Mapscript( ? Yewondwossen Assefa Daniel Morissette DM Solutions Group Inc.@@ %Contents  h Introduction to PHP Mapscript Object Model Application building Some Advanced features Questions &hi H&What is PHP Mapscript&     one flavour of MapScript (Perl, Python, Java versions exist also) custom extension for PHP abstracts the MapServer object model in PHP constructsZ     K     'Why do we use PHP Mapscript&    ;Because it provides the ability to do things that can't be done in MapServer's CGI mode Dynamic layers Customized navigation On the fly classification Enhanced legends and layer controls Advanced query capabilities PHP is an advanced open source programming language with significant modules such as GD, dbase, odbc<Z<@C      ) Object Model  4Cover the main objects found in php/mapscript and how to access members and functions of some of the objects Php Mapscript : "Jacket" on top of mapserver library Most of the mapserver elements accessible through php/mapscript Documentation at : http://mapserver.gis.umn.edu/doc/phpmapscript-class-guide.html5Z5D      A                          (Object Model : global view    * Map Object   +Access to the Map object  How to create a new map object $oMap = ms_newMapObj("mymapfile.map"); $oMap = ms_newMapObj(""); How to access members of the object (case sensitive) echo $oMap->name How to access functions of the object (case insensitive) $oLayer = $oMap->getlayer(0); ZDZ5ZZ9ZZZZZZA6:               D  C        ,Access to the Map object  How to modify member of the object $oMap->set("name", "a new name"); common mistake : $oMap->name = "a new name"; How to access the sub objects $oMap->web->set(...); #X!Z%  5  8   - Layer Object     . Access to the Layer object  Accessing layers through the map object $nLayers = $oMap->numlayers; for ($i=0; $i<$nLayers; $i++) { $oLayer = oMap->getlayer($i); echo $oLayer->name; . .. } Creating a new layer $oLayer = ms_newLayerObj($oMap) $oLayer->set("name", "my_new_layer"); $oLayer->set("type", MS_LAYER_LINE); //can be used to create a layer from another layer : $oLayer = ms_newLayerObj($oMap, $srclayer) (ZZZZ()                 )         !  X          /  Layer object   Diffrent types of layers : predefined constants MS_LAYER_POINT, MS_LAYER_LINE, MS_LAYER_POLYGON MS_LAYER_RASTER MS_LAYER_ANNOTATION MS_LAYER_QUERY MS_LAYER_CIRCLE MS_LAYER_TILEINDEX ,00   0 Class and Style  Accessing classes through the layer object $nClass = $oLayer->numclass; for ($i=0; $i<$nClass; $i++) { $oClass = oMap->getclass($i); echo $oClass->name; ... } Creating a new class $oClass = ms_newClassObj($oLayer); $oLayer->set("name", "my_new_layer"); ... f+ZZZTZ,SD-                ,         ' 1 Class and Style  Creating a new style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 1); ... Will be covered with examples in Advanced Features section XG;F;t         W 2Shapefile Object    3Shapefile manipulation    Open existing shapefile //first argument is the shapefilename without the extension //second argument (type) is set to -1 to open an existing file $oShapeFile = ms_newShapefileObj("my_shapefile", -1); Creating a shape object //The argument represents the type of shape object to be created. //Valid types are : MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON $oShape = ms_newShapeObj(MS_SHP_POINT); n       Y              4Shapefile manipulation    Creating a line/Point object $oLine = ms_newLineObj(); $oPoint = ms_newPointObj(); Will be covered with examples in Advanced features sectionL9;8;t           @ 5Application Building : Contents  *Drawing a Map Adding a Key Map Adding a Scalebar Adding Navigation Tools (zoom in, & ) Navigation using the Key Map Adding a Legend HTML Legend Query &(   e 9!Prepare the application structure " Directory structure of the application (data, map file, html, symbol file & ) URL to access the application Temporary files {  7The whole application  whttp://http://localhost/mum2_php_mapscript/index.phtml The directory /ms4w/apps/mum2_php_mapscript/ Data, htdocs, etc wxt1           06:Application structure  Index(X).phtml and step(X).php Separate HTML from the PHP code Phtml file contains already calls to PHP functions. PHP functions are there but are empty. t  N       T   ;Step1 : General  http://localhost/mum2_php_mapscript/index1.phtml /ms4w/apps/mum2_php_mapscript/htdocs/Step1.php /ms4w/apps/mum2_php_mapscript/htdocs/index1.phtml 0                       00<Step2 : Adding a map  uLoading the php mapscript module Loading the map file Draw map function function DrawMap() { $img = $GLOBALS["goMap"]->draw(); $url = $img->saveWebImage(); $nWidth = $GLOBALS["goMap"]->width; $nHeight = $GLOBALS["goMap"]->height; echo"\n"; } .HZ.ZH.   6                          0          =Step3 : Keymap&   Draw a key map function DrawKeyMap() { $img = $GLOBALS["goMap"]->drawreferencemap(); $url = $img->saveWebImage(); echo "\n"; } .ZZ                   &     >Step4 : Saclebar&   Draw scalebar function DrawScaleBar() { $img = $GLOBALS["goMap"]->drawScaleBar(); $url = $img->saveWebImage(); echo"\n"; }                            ?#Step5 : adding Navigation (zoom in)$$$ $ Know what type of navigation is selected $_GET ($_POST) : super global associative array for HTTP GET Preserve current map extents, width and height   @$Step 5 : adding Navigation (zoom in)$% $ % Top of the file $aVars = (sizeof($_POST) > 0) ? $_POST : (sizeof($_GET) > 0) ? $_GET : array(); ProcessURLArray( $aVars ); In DrawMap function echo"\n"; echo "extent->minx."\">\n"; echo "extent->miny."\">\n"; echo "extent->maxx."\">\n"; echo "extent->maxy."\">\n"; `ZlZZ Zl              *       ]  _     O     O         A$Step 5 : adding Navigation (zoom in)$% $ % Nfunction ProcessURLArray( $aVars) { //set up the previous extents $oExt = $GLOBALS["goMap"]; $fMinX = isset($aVars["MINX"]) ? $aVars["MINX"] : $oExt->extent->minx; $fMinY = isset($aVars["MINY"]) ? $aVars["MINY"] : $oExt->extent->miny;; $fMaxX = isset($aVars["MAXX"]) ? $aVars["MAXX"] : $oExt->extent->maxx;; $fMaxY = isset($aVars["MAXY"]) ? $aVars["MAXY"] : $oExt->extent->maxy;; $GLOBALS["goMap"]->setextent( $fMinX, $fMinY, $fMaxX, $fMaxY ); //some short cuts $fWidthPix = $GLOBALS["goMap"]->width; $fHeightPix = $GLOBALS["goMap"]->height; OZO    +                                                                                         B#Step5 : adding Navigation (zoom in)$$$ $ T//process commands if (isset($aVars["CMD"])) { //determine where to navigate to. $nX = isset($aVars["MAINMAP_x"]) ? intval($aVars["MAINMAP_x"]) : $fWidthPix/2.0; $nY = isset($aVars["MAINMAP_y"]) ? intval($aVars["MAINMAP_y"]) : $fWidthPix/2.0; if (isset($aVars["MAINMAP_x"]) && isset($aVars["MAINMAP_y"])) { $oPixelPos = ms_newpointobj(); $oPixelPos->setxy($nX, $nY); $oGeorefExt = ms_newrectobj(); $oGeorefExt->setextent($fMinX, $fMinY, $fMaxX, $fMaxY); if ($aVars["CMD"] == "ZOOM_IN") { $GLOBALS["goMap"]->zoompoint(2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } } } } $TZZU    C          =             =           '                                     >                 $ C Step 6 : All Nav. tools&    Modify function ProcessURLArray to look for other CMD values & . else if ($aVars["CMD"] == "ZOOM_OUT") { $GLOBALS["goMap"]->zoompoint(-2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "RECENTER") { $GLOBALS["goMap"]->zoompoint(1, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "ZOOM_FULL") { $GLOBALS["goMap"]->setextent($GLOBALS["gfMinX"],$GLOBALS["gfMinY"], $GLOBALS["gfMaxX"],$GLOBALS["gfMaxY"]); } .=ZZHb  <  ?                 '  ?                 '  @           ;        D!Step7 : Keep selected tool  j$GLOBALS["gszCurrentTool"] = "ZOOM_IN"; function ProcessURLArray( $aVars) { //record the current command $GLOBALS["gszCurrentTool"] = (isset($aVars["CMD"])) ? $aVars["CMD"] : "ZOOM_IN"; & } function IsCurrentTool( $szTool ) { return (strcasecmp($GLOBALS["gszCurrentTool"], $szTool) == 0); } .)Z Z) D       3         &              E"Step8 : KeyMap navigation &    )Inside function ProcessURLArray else if (isset($aVars["KEYMAP_x"]) && isset($aVars["KEYMAP_y"])) { $oRefExt = $GLOBALS["goMap"]->reference->extent; $nX = intval($aVars["KEYMAP_x"]); $nY = intval($aVars["KEYMAP_y"]); $fWidthPix = doubleval($GLOBALS["goMap"]->reference->width); $fHeightPix = doubleval($GLOBALS["goMap"]->reference->height); $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $oRefExt->minx, $oRefExt->maxx, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $oRefExt->miny, $oRefExt->maxy, 1); $fDeltaX = ($fMaxX - $fMinX) / 2.0; $fDeltaY = ($fMaxY - $fMinY) / 2.0; $GLOBALS["goMap"]->setextent($nGeoX - $fDeltaX, $nGeoY - $fDeltaY, $nGeoX + $fDeltaX, $nGeoY + $fDeltaY); } . Z Z                  %                              &                                                          &           F#Step9 : draw legend   function DrawLegend() { $img = $GLOBALS["goMap"]->drawLegend(); $url = $img->saveWebImage(); echo"\n"; }                           G$Step10 : HTML Legend  hDocs at : http://mapserver.gis.umn.edu/doc40/html-legend-howto.html The HTML legend is an alternative to the traditional GIF legend in MapServer Set TEMPLATE "legend.html in the map file inside the legend object [leg_layer_html order=ascending opt_flag=15] <tr height=20px> <td align="center"><input type="checkbox" name="legendlayername[]" value="[leg_layer_name]"[if name=layer_status oper=eq value=1]CHECKED[/if][if name=layer_status oper=eq value=2]CHECKED[/if]></td> <td>&nbsp;<img src="[leg_icon width=20 height=13]" width=20 height=13>&nbsp;</td> <td><font face="Arial, Helvetica, sans-serif" size="3">[metadata name=DESCRIPTION]</font></td> </tr> [/leg_layer_html] :ZZZv  9 D   u      1    +    %    5  n      0 CH%Step 10 : HTML Legend  1Call function DrawHTMLLegend(); in index10.phtml function DrawHTMLLegend() { echo ""; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo $GLOBALS["goMap"]->processLegendTemplate( array() ); echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
Update
"; } P3ZZ3x                N        )    5  T  " I&Step11 : Layer control  bInside function ProcessURLArray & //process layer visibility if (isset($_GET["legendlayername"])) { for( $i=0; $i<$GLOBALS["goMap"]->numlayers; $i++ ) { $oLayer = $GLOBALS["goMap"]->getLayer($i); if (in_array( $oLayer->name, $_GET["legendlayername"] )) $oLayer->set( "status", MS_ON ); else $oLayer->set( "status", MS_OFF ); } } . ZZ"^  &    +             !      <  *   J'Step12 : Query  Set templates in a layer Function ProcessURLArray & . else if ($aVars["CMD"] == "QUERY") { $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $fMinX, $fMaxX, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $fMinY, $fMaxY, 1); $oGeo = ms_newPointObj(); $oGeo->setXY($nGeoX, $nGeoY); // Use '@' to avoid warning if query found nothing @$GLOBALS["goMap"]->queryByPoint($oGeo, MS_MULTIPLE, -1); $GLOBALS["gShowQueryResults"] = TRUE; } .2Z<Z59b"    3        !            !                 b       /     K(Step12 : Query  L$GLOBALS["gShowQueryResults"] = FALSE; function DrawMap() { if ($GLOBALS["gShowQueryResults"]) $img = $GLOBALS["goMap"]->drawQuery(); else $img = $GLOBALS["goMap"]->draw(); & function DrawQueryResults() { if (!$GLOBALS["gShowQueryResults"]) echo "&nbsp;"; else { $sTemplate = $GLOBALS["goMap"]->processquerytemplate(array(), 0); echo $sTemplate; } }$'ZZ                           %             6Advanced Features  ZCreating a new Shapefile Adding a new layer dynamically Adding classification dynamically @   @   L)Creating a shape file  :Files advanced.phtml and advanced.php function AddDynamicLayer() { //Creating the shapefiles $oMap = $GLOBALS["goMap"]; $szFileName = $oMap->web->imagepath . uniqid(""); $oShapFile = ms_newShapeFileObj($szFileName, MS_SHP_POINT); //create a new DBF attached with few attributes $hDbf = dbase_create($szFileName.".dbf", array(array("POP_RANGE", "N", 5, 0), array("NAME", "C", 50, 0), array("CAPITAL", "N", 5, 0))); if (!$hDbf) return; .&ZZ&                                   K        M*Creating a shape file  Jopen the original dbf file $szOrginalDbfName = "../data/canada_cities.dbf"; $hOrigDbf = dbase_open($szOrginalDbfName, 0); if (!$hOrigDbf) return; $nRecords = dbase_numrecords($hOrigDbf); for ($i=1; $i<=$nRecords; $i++) { //retreive field attributes $aRecord = dbase_get_record_with_names($hOrigDbf, $i); $dfLat = floatval($aRecord["LAT"]); $dfLong = floatval($aRecord["LONG"]); $nPopRange = intval($aRecord["POP_RANGE"]); $szName = strval($aRecord["NAME"]); $nCapital = intval($aRecord["CAPITAL"]); KZK                                                               N+Creating a shape file  a//create a point for each record and add it to the shapefile $oShp = ms_newShapeObj(MS_SHP_POINT); $oLine = ms_newLineObj(); $oLine->addXY($dfLong, $dfLat); $oShp->add( $oLine ); $oShapFile->addShape($oShp); //add a record to the DBF $aAttValues[0] = $nPopRange; $aAttValues[1] = $szName; $aAttValues[2] = $nCapital; dbase_add_record($hDbf, $aAttValues); $oShp->free(); } dbase_close($hOrigDbf); dbase_close($hDbf); $oShapFile->free(); //Add a new layer in the map CreateLayer($szFileName); } .aZZa2                                    /                          !       +        O,!Adding a new layer and styling it " function CreateLayer($szDataName) { $oMap = $GLOBALS["goMap"]; //create layer and set members $oLayer = ms_newLayerObj($oMap); $oLayer->set("name", "canada_cities"); $oLayer->set("status", MS_ON); $oLayer->set("data", $szDataName); $oLayer->set("type", MS_LAYER_POINT); //projection is latlong $oLayer->setProjection("init=epsg:4326"); $oLayer->set("labelitem", "NAME"); $oLayer->set("classitem", "CAPITAL"); Z.            ,                    3                    P-!Adding a new layer and styling it " ] //Country capital //create class $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Capital"); $oClass->setexpression("/1/"); //create style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 2); $oStyle->set("size", 8); $oStyle->color->setRGB(255, 0, 0); //set label object $oClass->label->set("font", "fritqat-italic"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(255, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); "^Z]b+               "                 *      (           (  % Q.!Adding a new layer and styling it " <//provincial capitals $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Provincial Capital"); $oClass->setexpression("/2|3/"); $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 7); $oStyle->set("size", 6); $oStyle->color->setRGB(0, 0, 0); //set label object $oClass->label->set("font", "fritqat"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(0, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); }=Z=b         *                      (       (           (  & r. . QAΩ(   lhttp://http://localhost/mum2_php_mapscript/index  !"#$&՜.+,D՜.+,    5On-screen ShowDM Solutions Group Inc.p- 2Times New RomanArialArial Unicode MSCourierDefault DesignPHP Mapscript ContentsWhat is PHP MapscriptWhy do we use PHP Mapscript Object ModelObject Model : global view Map ObjectAccess to the Map objectAccess to the Map objectLayer Object Access to the Layer objectLayer object Class and StyleClass and StyleShapefile ObjectShapefile manipulationShapefile manipulation Application Building : Contents"Prepare the application structureThe whole applicationApplication structureStep1 : GeneralStep2 : Adding a mapStep3 : KeymapStep4 : Scalebar$Step5 : adding Navigation (zoom in)%Step 5 : adding Navigation (zoom in)%Step 5 : adding Navigation (zoom in)$Step5 : adding Navigation (zoom in)Step 6 : All Nav. toolsStep7 : Keep selected toolStep8 : KeyMap navigationStep9 : draw legendStep10 : HTML LegendStep 10 : HTML LegendStep11 : Layer controlStep12 : QueryStep12 : QueryAdvanced FeaturesCreating a shape fileCreating a shape fileCreating a shape file"Adding a new layer and styling it"Adding a new layer and styling it"Adding a new layer and styling it  Fonts UsedDesign Template Slide Titles-0 8@ _PID_HLINKSA7http://http://localhost/mum2_php_mapscript/index.phtml1http://localhost/mum2_php_mapscript/index1.phtml:http://mapserver.gis.umn.edu/doc40/html-legend-howto.html+_pAssefa YewondwossenAssefa Yewondwossenms_newClassObj($oLayer); $oLayer->set("name", "my_new_layer"); ... f+ZZZTZ,SD-                ,         ' 1 Class and Style  Creating a new style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 1); ... Will be covered with examples in Advanced Features section XG;F;t         W 2Shapefile Object    3Shapefile manipulation    Open existing shapefile //first argument is the shapefilename without the extension //second argument (type) is set to -1 to open an existing file $oShapeFile = ms_newShapefileObj("my_shapefile", -1); Creating a shape object //The argument represents the type of shape object to be created. //Valid types are : MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON $oShape = ms_newShapeObj(MS_SHP_POINT); n       Y              4Shapefile manipulation    Creating a line/Point object $oLine = ms_newLineObj(); $oPoint = ms_newPointObj(); Will be covered with examples in Advanced features sectionL9;8;t           @ 5Application Building : Contents  *Drawing a Map Adding a Key Map Adding a Scalebar Adding Navigation Tools (zoom in, & ) Navigation using the Key Map Adding a Legend HTML Legend Query &(   e 9!Prepare the application structure " Directory structure of the application (data, map file, html, symbol file & ) URL to access the application Temporary files {  7The whole application  whttp://http://localhost/mum2_php_mapscript/index.phtml The directory /ms4w/apps/mum2_php_mapscript/ Data, htdocs, etc wxt1           06:Application structure  Index(X).phtml and step(X).php Separate HTML from the PHP code Phtml file contains already calls to PHP functions. PHP functions are there but are empty. t         T   ;Step1 : General  http://localhost/mum2_php_mapscript/index1.phtml /ms4w/apps/mum2_php_mapscript/htdocs/Step1.php /ms4w/apps/mum2_php_mapscript/htdocs/index1.phtml 0                       00<Step2 : Adding a map  uLoading the php mapscript module Loading the map file Draw map function function DrawMap() { $img = $GLOBALS["goMap"]->draw(); $url = $img->saveWebImage(); $nWidth = $GLOBALS["goMap"]->width; $nHeight = $GLOBALS["goMap"]->height; echo"\n"; } .HZ.ZH.   6                          0          =Step3 : Keymap&   Draw a key map function DrawKeyMap() { $img = $GLOBALS["goMap"]->drawreferencemap(); $url = $img->saveWebImage(); echo "\n"; } .ZZ                   &     >Step4 : Scalebar&   Draw scalebar function DrawScaleBar() { $img = $GLOBALS["goMap"]->drawScaleBar(); $url = $img->saveWebImage(); echo"\n"; }                            ?#Step5 : adding Navigation (zoom in)$$$ $ Know what type of navigation is selected $_GET ($_POST) : super global associative array for HTTP GET Preserve current map extents, width and height   @$Step 5 : adding Navigation (zoom in)$% $ % Top of the file $aVars = (sizeof($_POST) > 0) ? $_POST : (sizeof($_GET) > 0) ? $_GET : array(); ProcessURLArray( $aVars ); In DrawMap function echo"\n"; echo "extent->minx."\">\n"; echo "extent->miny."\">\n"; echo "extent->maxx."\">\n"; echo "extent->maxy."\">\n"; `ZlZZ Zl              *       ]  _     O     O         A$Step 5 : adding Navigation (zoom in)$% $ % Nfunction ProcessURLArray( $aVars) { //set up the previous extents $oExt = $GLOBALS["goMap"]; $fMinX = isset($aVars["MINX"]) ? $aVars["MINX"] : $oExt->extent->minx; $fMinY = isset($aVars["MINY"]) ? $aVars["MINY"] : $oExt->extent->miny;; $fMaxX = isset($aVars["MAXX"]) ? $aVars["MAXX"] : $oExt->extent->maxx;; $fMaxY = isset($aVars["MAXY"]) ? $aVars["MAXY"] : $oExt->extent->maxy;; $GLOBALS["goMap"]->setextent( $fMinX, $fMinY, $fMaxX, $fMaxY ); //some short cuts $fWidthPix = $GLOBALS["goMap"]->width; $fHeightPix = $GLOBALS["goMap"]->height; OZO    +                                                                                         B#Step5 : adding Navigation (zoom in)$$$ $ T//process commands if (isset($aVars["CMD"])) { //determine where to navigate to. $nX = isset($aVars["MAINMAP_x"]) ? intval($aVars["MAINMAP_x"]) : $fWidthPix/2.0; $nY = isset($aVars["MAINMAP_y"]) ? intval($aVars["MAINMAP_y"]) : $fWidthPix/2.0; if (isset($aVars["MAINMAP_x"]) && isset($aVars["MAINMAP_y"])) { $oPixelPos = ms_newpointobj(); $oPixelPos->setxy($nX, $nY); $oGeorefExt = ms_newrectobj(); $oGeorefExt->setextent($fMinX, $fMinY, $fMaxX, $fMaxY); if ($aVars["CMD"] == "ZOOM_IN") { $GLOBALS["goMap"]->zoompoint(2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } } } } $TZZU    C          =             =           '                                     >                 $ C Step 6 : All Nav. tools&    Modify function ProcessURLArray to look for other CMD values & . else if ($aVars["CMD"] == "ZOOM_OUT") { $GLOBALS["goMap"]->zoompoint(-2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "RECENTER") { $GLOBALS["goMap"]->zoompoint(1, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "ZOOM_FULL") { $GLOBALS["goMap"]->setextent($GLOBALS["gfMinX"],$GLOBALS["gfMinY"], $GLOBALS["gfMaxX"],$GLOBALS["gfMaxY"]); } .=ZZHb  <  ?                 '  ?                 '  @           ;        D!Step7 : Keep selected tool  j$GLOBALS["gszCurrentTool"] = "ZOOM_IN"; function ProcessURLArray( $aVars) { //record the current command $GLOBALS["gszCurrentTool"] = (isset($aVars["CMD"])) ? $aVars["CMD"] : "ZOOM_IN"; & } function IsCurrentTool( $szTool ) { return (strcasecmp($GLOBALS["gszCurrentTool"], $szTool) == 0); } .)Z Z) D       3         &              E"Step8 : KeyMap navigation &    )Inside function ProcessURLArray else if (isset($aVars["KEYMAP_x"]) && isset($aVars["KEYMAP_y"])) { $oRefExt = $GLOBALS["goMap"]->reference->extent; $nX = intval($aVars["KEYMAP_x"]); $nY = intval($aVars["KEYMAP_y"]); $fWidthPix = doubleval($GLOBALS["goMap"]->reference->width); $fHeightPix = doubleval($GLOBALS["goMap"]->reference->height); $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $oRefExt->minx, $oRefExt->maxx, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $oRefExt->miny, $oRefExt->maxy, 1); $fDeltaX = ($fMaxX - $fMinX) / 2.0; $fDeltaY = ($fMaxY - $fMinY) / 2.0; $GLOBALS["goMap"]->setextent($nGeoX - $fDeltaX, $nGeoY - $fDeltaY, $nGeoX + $fDeltaX, $nGeoY + $fDeltaY); } . Z Z                  %                              &                                                          &           F#Step9 : draw legend   function DrawLegend() { $img = $GLOBALS["goMap"]->drawLegend(); $url = $img->saveWebImage(); echo"\n"; }                           G$Step10 : HTML Legend  hDocs at : http://mapserver.gis.umn.edu/doc40/html-legend-howto.html The HTML legend is an alternative to the traditional GIF legend in MapServer Set TEMPLATE "legend.html in the map file inside the legend object [leg_layer_html order=ascending opt_flag=15] <tr height=20px> <td align="center"><input type="checkbox" name="legendlayername[]" value="[leg_layer_name]"[if name=layer_status oper=eq value=1]CHECKED[/if][if name=layer_status oper=eq value=2]CHECKED[/if]></td> <td>&nbsp;<img src="[leg_icon width=20 height=13]" width=20 height=13>&nbsp;</td> <td><font face="Arial, Helvetica, sans-serif" size="3">[metadata name=DESCRIPTION]</font></td> </tr> [/leg_layer_html] :ZZZv  9 D   u      1    +    %    5  n      0 CH%Step 10 : HTML Legend  1Call function DrawHTMLLegend(); in index10.phtml function DrawHTMLLegend() { echo ""; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo $GLOBALS["goMap"]->processLegendTemplate( array() ); echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
Update
"; } P3ZZ3x                N        )    5  T  " I&Step11 : Layer control  bInside function ProcessURLArray & //process layer visibility if (isset($_GET["legendlayername"])) { for( $i=0; $i<$GLOBALS["goMap"]->numlayers; $i++ ) { $oLayer = $GLOBALS["goMap"]->getLayer($i); if (in_array( $oLayer->name, $_GET["legendlayername"] )) $oLayer->set( "status", MS_ON ); else $oLayer->set( "status", MS_OFF ); } } . ZZ"^  &    +             !      <  *   J'Step12 : Query  Set templates in a layer Function ProcessURLArray & . else if ($aVars["CMD"] == "QUERY") { $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $fMinX, $fMaxX, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $fMinY, $fMaxY, 1); $oGeo = ms_newPointObj(); $oGeo->setXY($nGeoX, $nGeoY); // Use '@' to avoid warning if query found nothing @$GLOBALS["goMap"]->queryByPoint($oGeo, MS_MULTIPLE, -1); $GLOBALS["gShowQueryResults"] = TRUE; } .2Z<Z59b"    3        !            !                 b       /     K(Step12 : Query  L$GLOBALS["gShowQueryResults"] = FALSE; function DrawMap() { if ($GLOBALS["gShowQueryResults"]) $img = $GLOBALS["goMap"]->drawQuery(); else $img = $GLOBALS["goMap"]->draw(); & function DrawQueryResults() { if (!$GLOBALS["gShowQueryResults"]) echo "&nbsp;"; else { $sTemplate = $GLOBALS["goMap"]->processquerytemplate(array(), 0); echo $sTemplate; } }$'ZZ                           %             6Advanced Features  ZCreating a new Shapefile Adding a new layer dynamically Adding classification dynamically @   @   L)Creating a shape file  :Files advanced.phtml and advanced.php function AddDynamicLayer() { //Creating the shapefiles $oMap = $GLOBALS["goMap"]; $szFileName = $oMap->web->imagepath . uniqid(""); $oShapFile = ms_newShapeFileObj($szFileName, MS_SHP_POINT); //create a new DBF attached with few attributes $hDbf = dbase_create($szFileName.".dbf", array(array("POP_RANGE", "N", 5, 0), array("NAME", "C", 50, 0), array("CAPITAL", "N", 5, 0))); if (!$hDbf) return; .&ZZ&                                   K        M*Creating a shape file  Jopen the original dbf file $szOrginalDbfName = "../data/canada_cities.dbf"; $hOrigDbf = dbase_open($szOrginalDbfName, 0); if (!$hOrigDbf) return; $nRecords = dbase_numrecords($hOrigDbf); for ($i=1; $i<=$nRecords; $i++) { //retreive field attributes $aRecord = dbase_get_record_with_names($hOrigDbf, $i); $dfLat = floatval($aRecord["LAT"]); $dfLon      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|~g = floatval($aRecord["LONG"]); $nPopRange = intval($aRecord["POP_RANGE"]); $szName = strval($aRecord["NAME"]); $nCapital = intval($aRecord["CAPITAL"]); KZK                                                               N+Creating a shape file  a//create a point for each record and add it to the shapefile $oShp = ms_newShapeObj(MS_SHP_POINT); $oLine = ms_newLineObj(); $oLine->addXY($dfLong, $dfLat); $oShp->add( $oLine ); $oShapFile->addShape($oShp); //add a record to the DBF $aAttValues[0] = $nPopRange; $aAttValues[1] = $szName; $aAttValues[2] = $nCapital; dbase_add_record($hDbf, $aAttValues); $oShp->free(); } dbase_close($hOrigDbf); dbase_close($hDbf); $oShapFile->free(); //Add a new layer in the map CreateLayer($szFileName); } .aZZa2                                    /                          !       +        O,!Adding a new layer and styling it " function CreateLayer($szDataName) { $oMap = $GLOBALS["goMap"]; //create layer and set members $oLayer = ms_newLayerObj($oMap); $oLayer->set("name", "canada_cities"); $oLayer->set("status", MS_ON); $oLayer->set("data", $szDataName); $oLayer->set("type", MS_LAYER_POINT); //projection is latlong $oLayer->setProjection("init=epsg:4326"); $oLayer->set("labelitem", "NAME"); $oLayer->set("classitem", "CAPITAL"); Z.            ,                    3                    P-!Adding a new layer and styling it " ] //Country capital //create class $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Capital"); $oClass->setexpression("/1/"); //create style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 2); $oStyle->set("size", 8); $oStyle->color->setRGB(255, 0, 0); //set label object $oClass->label->set("font", "fritqat-italic"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(255, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); "^Z]b+               "                 *      (           (  % Q.!Adding a new layer and styling it " <//provincial capitals $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Provincial Capital"); $oClass->setexpression("/2|3/"); $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 7); $oStyle->set("size", 6); $oStyle->color->setRGB(0, 0, 0); //set label object $oClass->label->set("font", "fritqat"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(0, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); }=Z=b         *                      (       (           (  &   $(  r  S NP  N r  S N N H  0޽h ? ̙33r8>abQAΩ(   lhttp://http://localhost/mum2_php_mapscript/index.phtmlt`http://localhost/mum2_php_mapscript/index1.phtmlrhttp://mapserver.gis.umn.edu/doc40/html-legend-howto.html/ 00DTimes New Roman3|d0|Wo 0DArialNew Roman3|d0|Wo 0" DArial Unicode MS|d0|Wo 00DCouriericode MS|d0|Wo 0 ` .  @n?" dd@  @@`` LT.     !"#$%&'()*+,/012_R$-o1R䰹mE sb$Dc& R֓QCsb$x}{J sb$[-Vvݑ0b$67ۅR 3,c $@7a<@ʚ;2Nʚ;g45d5d0pppp@ <4!d!d 0,4<4dddd 0,4 ? % PHP Mapscript( ? Yewondwossen Assefa Daniel Morissette DM Solutions Group Inc.@@ %Contents  h Introduction to PHP Mapscript Object Model Application building Some Advanced features Questions &hi H&What is PHP Mapscript&     one flavour of MapScript (Perl, Python, Java versions exist also) custom extension for PHP abstracts the MapServer object model in PHP constructsZ     K     'Why do we use PHP Mapscript&    ;Because it provides the ability to do things that can't be done in MapServer's CGI mode Dynamic layers Customized navigation On the fly classification Enhanced legends and layer controls Advanced query capabilities PHP is an advanced open source programming language with significant modules such as GD, dbase, odbc<Z<@C      ) Object Model  4Cover the main objects found in php/mapscript and how to access members and functions of some of the objects Php Mapscript : "Jacket" on top of mapserver library Most of the mapserver elements accessible through php/mapscript Documentation at : http://mapserver.gis.umn.edu/doc/phpmapscript-class-guide.html5Z5D      A                          (Object Model : global view    * Map Object   +Access to the Map object  How to create a new map object $oMap = ms_newMapObj("mymapfile.map"); $oMap = ms_newMapObj(""); How to access members of the object (case sensitive) echo $oMap->name How to access functions of the object (case insensitive) $oLayer = $oMap->getlayer(0); ZDZ5ZZ9ZZZZZZA6:               D  C        ,Access to the Map object  How to modify member of the object $oMap->set("name", "a new name"); common mistake : $oMap->name = "a new name"; How to access the sub objects $oMap->web->set(...); #X!Z%  5  8   - Layer Object     . Access to the Layer object  Accessing layers through the map object $nLayers = $oMap->numlayers; for ($i=0; $i<$nLayers; $i++) { $oLayer = oMap->getlayer($i); echo $oLayer->name; . .. } Creating a new layer $oLayer = ms_newLayerObj($oMap) $oLayer->set("name", "my_new_layer"); $oLayer->set("type", MS_LAYER_LINE); //can be used to create a layer from another layer : $oLayer = ms_newLayerObj($oMap, $srclayer) (ZZZZ()                 )         !  X          /  Layer object   Diffrent types of layers : predefined constants MS_LAYER_POINT, MS_LAYER_LINE, MS_LAYER_POLYGON MS_LAYER_RASTER MS_LAYER_ANNOTATION MS_LAYER_QUERY MS_LAYER_CIRCLE MS_LAYER_TILEINDEX ,00   0 Class and Style  Accessing classes through the layer object $nClass = $oLayer->numclass; for ($i=0; $i<$nClass; $i++) { $oClass = oMap->getclass($i); echo $oClass->name; ... } Creating a new class $oClass = ms_newClassObj($oLayer); $oLayer->set("name", "my_new_layer"); ... f+ZZZTZ,SD-                ,         ' 1 Class and Style  Creating a new style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 1); ... Will be covered with examples in Advanced Features section XG;F;t         W 2Shapefile Object    3Shapefile manipulation    Open existing shapefile //first argument is the shapefilename without the extension //second argument (type) is set to -1 to open an existing file $oShapeFile = ms_newShapefileObj("my_shapefile", -1); Creating a shape object //The argument represents the type of shape object to be created. //Valid types are : MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON $oShape = ms_newShapeObj(MS_SHP_POINT); n       Y              4Shapefile manipulation    Creating a line/Point object $oLine = ms_newLineObj(); $oPoint = ms_newPointObj(); Will be covered with examples in Advanced features sectionL9;8;t           @ 5Application Building : Contents  *Drawing a Map Adding a Key Map Adding a Scalebar Adding Navigation Tools (zoom in, & ) Navigation using the Key Map Adding a Legend HTML Legend Query &(   e 9!Prepare the application structure " Directory structure of the application (data, map file, html, symbol file & ) URL to access the application Temporary files {  7The whole application  whttp://http://localhost/mum2_php_mapscript/index.phtml The directory /ms4w/apps/mum2_php_mapscript/ Data, htdocs, etc wxt1           06:Application structure  Index(X).phtml and step(X).php Separate HTML from the PHP code Phtml file contains already calls to PHP functions. PHP functions are there but are empty. t         T   ;Step1 : General  http://localhost/mum2_php_mapscript/index1.phtml /ms4w/apps/mum2_php_mapscript/htdocs/Step1.php /ms4w/apps/mum2_php_mapscript/htdocs/index1.phtml 0                       00<Step2 : Adding a map  uLoading the php mapscript module Loading the map file Draw map function function DrawMap() { $img = $GLOBALS["goMap"]->draw(); $url = $img->saveWebImage(); $nWidth = $GLOBALS["goMap"]->width; $nHeight = $GLOBALS["goMap"]->height; echo"\n"; } .HZ.ZH.   6                          0          =Step3 : Keymap&   Draw a key map function DrawKeyMap() { $img = $GLOBALS["goMap"]->drawreferencemap(); $url = $img->saveWebImage(); echo "\n"; } .ZZ                   &     >Step4 : Scalebar&   Draw scalebar function DrawScaleBar() { $img = $GLOBALS["goMap"]->drawScaleBar(); $url = $img->saveWebImage(); echo"\n"; }                            ?#Step5 : adding Navigation (zoom in)$$$ $ Know what type of navigation is selected $_GET ($_POST) : super global associative array for HTTP GET Preserve current map extents, width and height   @$Step 5 : adding Navigation (zoom in)$% $ % Top of the file $aVars = (sizeof($_POST) > 0) ? $_POST : (sizeof($_GET) > 0) ? $_GET : array(); ProcessURLArray( $aVars ); In DrawMap function echo"\n"; echo "extent->minx."\">\n"; echo "extent->miny."\">\n"; echo "extent->maxx."\">\n"; echo "extent->maxy."\">\n"; `ZlZZ Zl              *       ]  _     O     O         A$Step 5 : adding Navigation (zoom in)$% $ % Nfunction ProcessURLArray( $aVars) { //set up the previous extents $oExt = $GLOBALS["goMap"]; $fMinX = isset($aVars["MINX"]) ? $aVars["MINX"] : $oExt->extent->minx; $fMinY = isset($aVars["MINY"]) ? $aVars["MINY"] : $oExt->extent->miny;; $fMaxX = isset($aVars["MAXX"]) ? $aVars["MAXX"] : $oExt->extent->maxx;; $fMaxY = isset($aVars["MAXY"]) ? $aVars["MAXY"] : $oExt->extent->maxy;; $GLOBALS["goMap"]->setextent( $fMinX, $fMinY, $fMaxX, $fMaxY ); //some short cuts $fWidthPix = $GLOBALS["goMap"]->width; $fHeightPix = $GLOBALS["goMap"]->height; OZO    +                                                                                         B#Step5 : adding Navigation (zoom in)$$$ $ T//process commands if (isset($aVars["CMD"])) { //determine where to navigate to. $nX = isset($aVars["MAINMAP_x"]) ? intval($aVars["MAINMAP_x"]) : $fWidthPix/2.0; $nY = isset($aVars["MAINMAP_y"]) ? intval($aVars["MAINMAP_y"]) : $fWidthPix/2.0; if (isset($aVars["MAINMAP_x"]) && isset($aVars["MAINMAP_y"])) { $oPixelPos = ms_newpointobj(); $oPixelPos->setxy($nX, $nY); $oGeorefExt = ms_newrectobj(); $oGeorefExt->setextent($fMinX, $fMinY, $fMaxX, $fMaxY); if ($aVars["CMD"] == "ZOOM_IN") { $GLOBALS["goMap"]->zoompoint(2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } } } } $TZZU    C          =             =           '                                     >                 $ C Step 6 : All Nav. tools&    Modify function ProcessURLArray to look for other CMD values & . else if ($aVars["CMD"] == "ZOOM_OUT") { $GLOBALS["goMap"]->zoompoint(-2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "RECENTER") { $GLOBALS["goMap"]->zoompoint(1, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "ZOOM_FULL") { $GLOBALS["goMap"]->setextent($GLOBALS["gfMinX"],$GLOBALS["gfMinY"], $GLOBALS["gfMaxX"],$GLOBALS["gfMaxY"]); } .=ZZHb  <  ?                 '  ?                 '  @           ;        D!Step7 : Keep selected tool  j$GLOBALS["gszCurrentTool"] = "ZOOM_IN"; function ProcessURLArray( $aVars) { //record the current command $GLOBALS["gszCurrentTool"] = (isset($aVars["CMD"])) ? $aVars["CMD"] : "ZOOM_IN"; & } function IsCurrentTool( $szTool ) { return (strcasecmp($GLOBALS["gszCurrentTool"], $szTool) == 0); } .)Z Z) D       3         &              E"Step8 : KeyMap navigation &    )Inside function ProcessURLArray else if (isset($aVars["KEYMAP_x"]) && isset($aVars["KEYMAP_y"])) { $oRefExt = $GLOBALS["goMap"]->reference->extent; $nX = intval($aVars["KEYMAP_x"]); $nY = intval($aVars["KEYMAP_y"]); $fWidthPix = doubleval($GLOBALS["goMap"]->reference->width); $fHeightPix = doubleval($GLOBALS["goMap"]->reference->height); $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $oRefExt->minx, $oRefExt->maxx, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $oRefExt->miny, $oRefExt->maxy, 1); $fDeltaX = ($fMaxX - $fMinX) / 2.0; $fDeltaY = ($fMaxY - $fMinY) / 2.0; $GLOBALS["goMap"]->setextent($nGeoX - $fDeltaX, $nGeoY - $fDeltaY, $nGeoX + $fDeltaX, $nGeoY + $fDeltaY); } . Z Z                  %                              &                                                          &           F#Step9 : draw legend   function DrawLegend() { $img = $GLOBALS["goMap"]->drawLegend(); $url = $img->saveWebImage(); echo"\n"; }                           G$Step10 : HTML Legend  hDocs at : http://mapserver.gis.umn.edu/doc40/html-legend-howto.html The HTML legend is an alternative to the traditional GIF legend in MapServer Set TEMPLATE "legend.html in the map file inside the legend object [leg_layer_html order=ascending opt_flag=15] <tr height=20px> <td align="center"><input type="checkbox" name="legendlayername[]" value="[leg_layer_name]"[if name=layer_status oper=eq value=1]CHECKED[/if][if name=layer_status oper=eq value=2]CHECKED[/if]></td> <td>&nbsp;<img src="[leg_icon width=20 height=13]" width=20 height=13>&nbsp;</td> <td><font face="Arial, Helvetica, sans-serif" size="3">[metadata name=DESCRIPTION]</font></td> </tr> [/leg_layer_html] :ZZZv  9 D   u      1    +    %    5  n      0 CH%Step 10 : HTML Legend  1Call function DrawHTMLLegend(); in index10.phtml function DrawHTMLLegend() { echo ""; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo $GLOBALS["goMap"]->processLegendTemplate( array() ); echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
Update
"; } P3ZZ3x                N        )    5  T  " I&Step11 : Layer control  bInside function ProcessURLArray & //process layer visibility if (isset($_GET["legendlayername"])) { for( $i=0; $i<$GLOBALS["goMap"]->numlayers; $i++ ) { $oLayer = $GLOBALS["goMap"]->getLayer($i); if (in_array( $oLayer->name, $_GET["legendlayername"] )) $oLayer->set( "status", MS_ON ); else $oLayer->set( "status", MS_OFF ); } } . ZZ"^  &    +             !      <  *   J'Step12 : Query  Set templates in a layer Function ProcessURLArray & . else if ($aVars["CMD"] == "QUERY") { $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $fMinX, $fMaxX, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $fMinY, $fMaxY, 1); $oGeo = ms_newPointObj(); $oGeo->setXY($nGeoX, $nGeoY); // Use '@' to avoid warning if query found nothing @$GLOBALS["goMap"]->queryByPoint($oGeo, MS_MULTIPLE, -1); $GLOBALS["gShowQueryResults"] = TRUE; } .2Z<Z59b"    3        !            !                 b       /     K(Step12 : Query  L$GLOBALS["gShowQueryResults"] = FALSE; function DrawMap() { if ($GLOBALS["gShowQueryResults"]) $img = $GLOBALS["goMap"]->drawQuery(); else $img = $GLOBALS["goMap"]->draw(); & function DrawQueryResults() { if (!$GLOBALS["gShowQueryResults"]) echo "&nbsp;"; else { $sTemplate = $GLOBALS["goMap"]->processquerytemplate(array(), 0); echo $sTemplate; } }$'ZZ                           %             6Advanced Features  ZCreating a new Shapefile Adding a new layer dynamically Adding classification dynamically @   @   L)Creating a shape file  :Files advanced.phtml and advanced.php function AddDynamicLayer() { //Creating the shapefiles $oMap = $GLOBALS["goMap"]; $szFileName = $oMap->web->imagepath . uniqid(""); $oShapFile = ms_newShapeFileObj($szFileName, MS_SHP_POINT); //create a new DBF attached with few attributes $hDbf = dbase_create($szFileName.".dbf", array(array("POP_RANGE", "N", 5, 0), array("NAME", "C", 50, 0), array("CAPITAL", "N", 5, 0))); if (!$hDbf) return; .&ZZ&                                   K        M*Creating a shape file  Jopen the original dbf file $szOrginalDbfName = "../data/canada_cities.dbf"; $hOrigDbf = dbase_open($szOrginalDbfName, 0); if (!$hOrigDbf) return; $nRecords = dbase_numrecords($hOrigDbf); for ($i=1; $i<=$nRecords; $i++) { //retreive field attributes $aRecord = dbase_get_record_with_names($hOrigDbf, $i); $dfLat = floatval($aRecord["LAT"]); $dfLong = floatval($aRecord["LONG"]); $nPopRange = intval($aRecord["POP_RANGE"]); $szName = strval($aRecord["NAME"]); $nCapital = intval($aRecord["CAPITAL"]); KZK                                                               N+Creating a shape file  a//create a point for each record and add it to the shapefile $oShp = ms_newShapeObj(MS_SHP_POINT); $oLine = ms_newLineObj(); $oLine->addXY($dfLong, $dfLat); $oShp->add( $oLine ); $oShapFile->addShape($oShp); //add a record to the DBF $aAttValues[0] = $nPopRange; $aAttValues[1] = $szName; $aAttValues[2] = $nCapital; dbase_add_record($hDbf, $aAttValues); $oShp->free(); } dbase_close($hOrigDbf); dbase_close($hDbf); $oShapFile->free(); //Add a new layer in the map CreateLayer($szFileName); } .aZZa2                                    /                          !       +        O,!Adding a new layer and styling it " function CreateLayer($szDataName) { $oMap = $GLOBALS["goMap"]; //create layer and set members $oLayer = ms_newLayerObj($oMap); $oLayer->set("name", "canada_cities"); $oLayer->set("status", MS_ON); $oLayer->set("data", $szDataName); $oLayer->set("type", MS_LAYER_POINT); //projection is latlong $oLayer->setProjection("init=epsg:4326"); $oLayer->set("labelitem", "NAME"); $oLayer->set("classitem", "CAPITAL"); Z.            ,                    3                    P-!Adding a new layer and styling it " ] //Country capital //create class $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Capital"); $oClass->setexpression("/1/"); //create style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 2); $oStyle->set("size", 8); $oStyle->color->setRGB(255, 0, 0); //set label object $oClass->label->set("font", "fritqat-italic"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(255, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); "^Z]b+               "                 *      (           (  % Q.!Adding a new layer and styling it " <//provincial capitals $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Provincial Capital"); $oClass->setexpression("/2|3/"); $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 7); $oStyle->set("size", 6); $oStyle->color->setRGB(0, 0, 0); //set label object $oClass->label->set("font", "fritqat"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(0, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); }=Z=b         *                      (       (           (  & r6cc QA( RS  lhttp://http://localhost/mum2_php_mapscript/index.phtmlt`http://localhost/mum2_php_mapscript/index1.phtmlrhttp://mapserver.gis.umn.edu/doc40/html-legend-howto.html/ 00DTimes New Roman30Wo 0DArialNew Roman30Wo 0" DArial Unicode MS0Wo 00DCouriericode MS0Wo 0 ` .  @n?" dd@  @@`` \X2    * !"#$%&'()+,-./0 12_R$-o1R䰹mE sb$Dc& R֓QCsb$x}{J sb$[-Vvݑ0b$67ۅR 3,c $@7a<@ʚ;>2ʚ;g45d5d0ppp@ <4!d!d 0h4<4dddd 0h4 ? %c PHP Mapscript( ? Yewondwossen Assefa Daniel Morissette DM Solutions Group Inc.@@ %Contents  h Introduction to PHP Mapscript Object Model Application building Some Advanced features Questions &hi H&What is PHP Mapscript&     one flavour of MapScript (Perl, Python, Java versions exist also) custom extension for PHP abstracts the MapServer object model in PHP constructsZ     K     'Why do we use PHP Mapscript&    ;Because it provides the ability to do things that can't be done in MapServer's CGI mode Dynamic layers Customized navigation On the fly classification Enhanced legends and layer controls Advanced query capabilities PHP is an advanced open source programming language with significant modules such as GD, dbase, odbc<Z<@C      ) Object Model  4Cover the main objects found in php/mapscript and how to access members and functions of some of the objects Php Mapscript : "Jacket" on top of mapserver library Most of the mapserver elements accessible through php/mapscript Documentation at : http://mapserver.gis.umn.edu/doc/phpmapscript-class-guide.html5Z5D      A                          (Object Model : global view    * Map Object   +Access to the Map object  How to create a new map object $oMap = ms_newMapObj("mymapfile.map"); $oMap = ms_newMapObj(""); How to access members of the object (case sensitive) echo $oMap->name How to access functions of the object (case insensitive) $oLayer = $oMap->getlayer(0); ZDZ5ZZ9ZZZZZZA6:               D  C        ,Access to the Map object  How to modify member of the object $oMap->set("name", "a new name"); common mistake : $oMap->name = "a new name"; How to access the sub objects $oMap->web->set(...); #X!Z%  5  8   - Layer Object     . Access to the Layer object  Accessing layers through the map object $nLayers = $oMap->numlayers; for ($i=0; $i<$nLayers; $i++) { $oLayer = oMap->getlayer($i); echo $oLayer->name; . .. } Creating a new layer $oLayer = ms_newLayerObj($oMap) $oLayer->set("name", "my_new_layer"); $oLayer->set("type", MS_LAYER_LINE); //can be used to create a layer from another layer : $oLayer = ms_newLayerObj($oMap, $srclayer) (ZZZZ()                 )         !  X          /  Layer object   Diffrent types of layers : predefined constants MS_LAYER_POINT, MS_LAYER_LINE, MS_LAYER_POLYGON MS_LAYER_RASTER MS_LAYER_ANNOTATION MS_LAYER_QUERY MS_LAYER_CIRCLE MS_LAYER_TILEINDEX ,00   0 Class and Style  Accessing classes through the layer object $nClass = $oLayer->numclass; for ($i=0; $i<$nClass; $i++) { $oClass = oMap->getclass($i); echo $oClass->name; ... } Creating a new class $oClass = ms_newClassObj($oLayer); $oLayer->set("name", "my_new_layer"); ... f+ZZZTZ,SD-                ,         ' 1 Class and Style  Creating a new style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 1); ... Will be covered with examples in Advanced Features section XG;F;t         W 2Shapefile Object    3Shapefile manipulation    Open existing shapefile //first argument is the shapefilename without the extension //second argument (type) is set to -1 to open an existing file $oShapeFile = ms_newShapefileObj("my_shapefile", -1); Creating a shape object //The argument represents the type of shape object to be created. //Valid types are : MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON $oShape = ms_newShapeObj(MS_SHP_POINT); n       Y              4Shapefile manipulation    Creating a line/Point object $oLine = ms_newLineObj(); $oPoint = ms_newPointObj(); Will be covered with examples in Advanced features sectionL9;8;t           @ 5Application Building : Contents  *Drawing a Map Adding a Key Map Adding a Scalebar Adding Navigation Tools (zoom in, & ) Navigation using the Key Map Adding a Legend HTML Legend Query &(   e 9!Prepare the application structure " Directory structure of the application (data, map file, html, symbol file & ) URL to access the application Temporary files  | 7The whole application  whttp://http://localhost/mum2_php_mapscript/index.phtml The directory /ms4w/apps/mum2_php_mapscript/ Data, htdocs, etc wx                   06:Application structure  Index(X).phtml and step(X).php Separate HTML from the PHP code Phtml file contains already calls to PHP functions. PHP functions are there but are empty. Z         V ;Step1 : General  http://localhost/mum2_php_mapscript/index1.phtml /ms4w/apps/mum2_php_mapscript/htdocs/Step1.php /ms4w/apps/mum2_php_mapscript/htdocs/index1.phtml D                              00<Step2 : Adding a map  uLoading the php mapscript module Loading the map file Draw map function function DrawMap() { $img = $GLOBALS["goMap"]->draw(); $url = $img->saveWebImage(); $nWidth = $GLOBALS["goMap"]->width; $nHeight = $GLOBALS["goMap"]->height; echo"\n"; } .HZ.ZH.x   7                          0        =Step3 : Keymap&   Draw a key map function DrawKeyMap() { $img = $GLOBALS["goMap"]->drawreferencemap(); $url = $img->saveWebImage(); echo "\n"; } .ZZ                   &   >Step4 : Scalebar&   Draw scalebar function DrawScaleBar() { $img = $GLOBALS["goMap"]->drawScaleBar(); $url = $img->saveWebImage(); echo"\n"; }                             ?#Step5 : adding Navigation (zoom in)$$$ $ Know what type of navigation is selected $_GET ($_POST) : super global associative array for HTTP GET Preserve current map extents, width and height   @$Step 5 : adding Navigation (zoom in)$% $ % Top of the file $aVars = (sizeof($_POST) > 0) ? $_POST : (sizeof($_GET) > 0) ? $_GET : array(); ProcessURLArray( $aVars ); In DrawMap function echo"\n"; echo "extent->minx."\">\n"; echo "extent->miny."\">\n"; echo "extent->maxx."\">\n"; echo "extent->maxy."\">\n"; `ZlZZ Zl              *       ]  _     O     O       A$Step 5 : adding Navigation (zoom in)$% $ % Nfunction ProcessURLArray( $aVars) { //set up the previous extents $oExt = $GLOBALS["goMap"]; $fMinX = isset($aVars["MINX"]) ? $aVars["MINX"] : $oExt->extent->minx; $fMinY = isset($aVars["MINY"]) ? $aVars["MINY"] : $oExt->extent->miny;; $fMaxX = isset($aVars["MAXX"]) ? $aVars["MAXX"] : $oExt->extent->maxx;; $fMaxY = isset($aVars["MAXY"]) ? $aVars["MAXY"] : $oExt->extent->maxy;; $GLOBALS["goMap"]->setextent( $fMinX, $fMinY, $fMaxX, $fMaxY ); //some short cuts $fWidthPix = $GLOBALS["goMap"]->width; $fHeightPix = $GLOBALS["goMap"]->height; OZO     +                                                                                          B#Step5 : adding Navigation (zoom in)$$$ $ T//process commands if (isset($aVars["CMD"])) { //determine where to navigate to. $nX = isset($aVars["MAINMAP_x"]) ? intval($aVars["MAINMAP_x"]) : $fWidthPix/2.0; $nY = isset($aVars["MAINMAP_y"]) ? intval($aVars["MAINMAP_y"]) : $fWidthPix/2.0; if (isset($aVars["MAINMAP_x"]) && isset($aVars["MAINMAP_y"])) { $oPixelPos = ms_newpointobj(); $oPixelPos->setxy($nX, $nY); $oGeorefExt = ms_newrectobj(); $oGeorefExt->setextent($fMinX, $fMinY, $fMaxX, $fMaxY); if ($aVars["CMD"] == "ZOOM_IN") { $GLOBALS["goMap"]->zoompoint(2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } } } } $TZZU    C          =             =           '                                     >                 $ C Step 6 : All Nav. tools&    Modify function ProcessURLArray to look for other CMD values & . else if ($aVars["CMD"] == "ZOOM_OUT") { $GLOBALS["goMap"]->zoompoint(-2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "RECENTER") { $GLOBALS["goMap"]->zoompoint(1, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "ZOOM_FULL") { $GLOBALS["goMap"]->setextent($GLOBALS["gfMinX"],$GLOBALS["gfMinY"], $GLOBALS["gfMaxX"],$GLOBALS["gfMaxY"]); } .=ZZHH  <  ?                 '  ?                 '  @           ;      D!Step7 : Keep selected tool  j$GLOBALS["gszCurrentTool"] = "ZOOM_IN"; function ProcessURLArray( $aVars) { //record the current command $GLOBALS["gszCurrentTool"] = (isset($aVars["CMD"])) ? $aVars["CMD"] : "ZOOM_IN"; & } function IsCurrentTool( $szTool ) { return (strcasecmp($GLOBALS["gszCurrentTool"], $szTool) == 0); } .)Z Z) D       3         '               E"Step8 : KeyMap navigation &    )Inside function ProcessURLArray else if (isset($aVars["KEYMAP_x"]) && isset($aVars["KEYMAP_y"])) { $oRefExt = $GLOBALS["goMap"]->reference->extent; $nX = intval($aVars["KEYMAP_x"]); $nY = intval($aVars["KEYMAP_y"]); $fWidthPix = doubleval($GLOBALS["goMap"]->reference->width); $fHeightPix = doubleval($GLOBALS["goMap"]->reference->height); $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $oRefExt->minx, $oRefExt->maxx, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $oRefExt->miny, $oRefExt->maxy, 1); $fDeltaX = ($fMaxX - $fMinX) / 2.0; $fDeltaY = ($fMaxY - $fMinY) / 2.0; $GLOBALS["goMap"]->setextent($nGeoX - $fDeltaX, $nGeoY - $fDeltaY, $nGeoX + $fDeltaX, $nGeoY + $fDeltaY); } . Z Z                  %                              &                                                          &          F#Step9 : draw legend   function DrawLegend() { $img = $GLOBALS["goMap"]->drawLegend(); $url = $img->saveWebImage(); echo"\n"; }                         G$Step10 : HTML Legend  hDocs at : http://mapserver.gis.umn.edu/doc40/html-legend-howto.html The HTML legend is an alternative to the traditional GIF legend in MapServer Set TEMPLATE "legend.html in the map file inside the legend object [leg_layer_html order=ascending opt_flag=15] <tr height=20px> <td align="center"><input type="checkbox" name="legendlayername[]" value="[leg_layer_name]"[if name=layer_status oper=eq value=1]CHECKED[/if][if name=layer_status oper=eq value=2]CHECKED[/if]></td> <td>&nbsp;<img src="[leg_icon width=20 height=13]" width=20 height=13>&nbsp;</td> <td><font face="Arial, Helvetica, sans-serif" size="3">[metadata name=DESCRIPTION]</font></td> </tr> [/leg_layer_html] :ZZZ              D   u      2    *    %    5  n    0 CH%Step 10 : HTML Legend  1Call function DrawHTMLLegend(); in index10.phtml function DrawHTMLLegend() { echo ""; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo $GLOBALS["goMap"]->processLegendTemplate( array() ); echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
Update
"; } P3ZZ3x                N        *    6  T  " I&Step11 : Layer control  bInside function ProcessURLArray & //process layer visibility if (isset($_GET["legendlayername"])) { for( $i=0; $i<$GLOBALS["goMap"]->numlayers; $i++ ) { $oLayer = $GLOBALS["goMap"]->getLayer($i); if (in_array( $oLayer->name, $_GET["legendlayername"] )) $oLayer->set( "status", MS_ON ); else $oLayer->set( "status", MS_OFF ); } } . ZZ"D  &    +             !      <  , J'Step12 : Query  Set templates in a layer Function ProcessURLArray & . else if ($aVars["CMD"] == "QUERY") { $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $fMinX, $fMaxX, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $fMinY, $fMaxY, 1); $oGeo = ms_newPointObj(); $oGeo->setXY($nGeoX, $nGeoY); // Use '@' to avoid warning if query found nothing @$GLOBALS["goMap"]->queryByPoint($oGeo, MS_MULTIPLE, -1); $GLOBALS["gShowQueryResults"] = TRUE; } .2Z<Z59H"    3        !            !                 b       /   K(Step12 : Query  L$GLOBALS["gShowQueryResults"] = FALSE; function DrawMap() { if ($GLOBALS["gShowQueryResults"]) $img = $GLOBALS["goMap"]->drawQuery(); else $img = $GLOBALS["goMap"]->draw(); & function DrawQueryResults() { if (!$GLOBALS["gShowQueryResults"]) echo "&nbsp;"; else { $sTemplate = $GLOBALS["goMap"]->processquerytemplate(array(), 0); echo $sTemplate; } }$'ZZ                           %             6Advanced Features  ZCreating a new Shapefile Adding a new layer dynamically Adding classification dynamically &   B L)Creating a shape file  :Files advanced.phtml and advanced.php function AddDynamicLayer() { //Creating the shapefiles $oMap = $GLOBALS["goMap"]; $szFileName = $oMap->web->imagepath . uniqid(""); $oShapFile = ms_newShapeFileObj($szFileName, MS_SHP_POINT); //create a new DBF attached with few attributes $hDbf = dbase_create($szFileName.".dbf", array(array("POP_RANGE", "N", 5, 0), array("NAME", "C", 50, 0), array("CAPITAL", "N", 5, 0))); if (!$hDbf) return; .&ZZ&                                   K        M*Creating a shape file  Jopen the original dbf file $szOrginalDbfName = "../data/canada_cities.dbf"; $hOrigDbf = dbase_open($szOrginalDbfName, 0); if (!$hOrigDbf) return; $nRecords = dbase_numrecords($hOrigDbf); for ($i=1; $i<=$nRecords; $i++) { //retreive field attributes $aRecord = dbase_get_record_with_names($hOrigDbf, $i); $dfLat = floatval($aRecord["LAT"]); $dfLong = floatval($aRecord["LONG"]); $nPopRange = intval($aRecord["POP_RANGE"]); $szName = strval($aRecord["NAME"]); $nCapital = intval($aRecord["CAPITAL"]); KZK                                                             N+Creating a shape file  a//create a point for each record and add it to the shapefile $oShp = ms_newShapeObj(MS_SHP_POINT); $oLine = ms_newLineObj(); $oLine->addXY($dfLong, $dfLat); $oShp->add( $oLine ); $oShapFile->addShape($oShp); //add a record to the DBF $aAttValues[0] = $nPopRange; $aAttValues[1] = $szName; $aAttValues[2] = $nCapital; dbase_add_record($hDbf, $aAttValues); $oShp->free(); } dbase_close($hOrigDbf); dbase_close($hDbf); $oShapFile->free(); //Add a new layer in the map CreateLayer($szFileName); } .aZZa3                                  /                          !       0       O,!Adding a new layer and styling it " function CreateLayer($szDataName) { $oMap = $GLOBALS["goMap"]; //create layer and set members $oLayer = ms_newLayerObj($oMap); $oLayer->set("name", "canada_cities"); $oLayer->set("status", MS_ON); $oLayer->set("data", $szDataName); $oLayer->set("type", MS_LAYER_POINT); //projection is latlong $oLayer->setProjection("init=epsg:4326"); $oLayer->set("labelitem", "NAME"); $oLayer->set("classitem", "CAPITAL"); Z.             ,                    4                     P-!Adding a new layer and styling it " ] //Country capital //create class $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Capital"); $oClass->setexpression("/1/"); //create style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 2); $oStyle->set("size", 8); $oStyle->color->setRGB(255, 0, 0); //set label object $oClass->label->set("font", "fritqat-italic"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(255, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); "^Z]b+               "                 *      (           (  % Q.!Adding a new layer and styling it " <//provincial capitals $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Provincial Capital"); $oClass->setexpression("/2|3/"); $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 7); $oStyle->set("size", 6); $oStyle->color->setRGB(0, 0, 0); //set label object $oClass->label->set("font", "fritqat"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(0, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); }=Z=b         *                      (       (           (  & /T 0 X(  X X 0l*L P   L T*   X 0 /L    L V*  d X c $ ?  L X 0X4L  @ L RClick to edit Master text styles Second level Third level Fourth level Fifth level!    S  X 66L `P  L T*   X 6?L `  L V*  H X 0޽h ? ̙330 PT(  T T 0`G P   G T*   T 0G    G V*   T 6h/ `P   T*   T 6G `  G V*  H T 0޽h ? ̙33  0$(  0r 0 S P   r 0 S @  H 0 0޽h ? ̙33 ) 0  \](  \X \ C X   L \ S HLX @  L _Add projection in the map file PROJECTION "init=epsg:42304" END Call AddDynamicLayer(); just after the ProcessURLArray $oLayer->setMetaData("DESCRIPTION", "New Cities Layer");4           % H \ 0޽h ? ̙33r @ LDR06 0) ET( RS  lhttp://http://localhost/mum2_php_mapscript/index.phtmlt`http://localhost/mum2_php_mapscript/index1.phtmlrhttp://mapserver.gis.umn.edu/doc40/html-legend-howto.html/ 00DTimes New Roman3|d0|Wo 0DArialNew Roman3|d0|Wo 0" DArial Unicode MS|d0|Wo 00DCouriericode MS|d0|Wo 0 ` .  @n?" dd@  @@`` \X2    * !"#$%&'()+,-./0 12_R$-o1R䰹mE sb$Dc& R֓QCsb$x}{J sb$[-Vvݑ0b$67ۅR 3,c $@7a<@ʚ;>2ʚ;g45d5d0pppp@ <4!d!d 0,4<4dddd 0,4 ? %m PHP Mapscript( ? Yewondwossen Assefa Daniel Morissette DM Solutions Group Inc.@@ %Contents  h Introduction to PHP Mapscript Object Model Application building Some Advanced features Questions &hi H&What is PHP Mapscript&     one flavour of MapScript (Perl, Python, Java versions exist also) custom extension for PHP abstracts the MapServer object model in PHP constructsZ     K     'Why do we use PHP Mapscript&    ;Because it provides the ability to do things that can't be done in MapServer's CGI mode Dynamic layers Customized navigation On the fly classification Enhanced legends and layer controls Advanced query capabilities PHP is an advanced open source programming language with significant modules such as GD, dbase, odbc<Z<@C      ) Object Model  4Cover the main objects found in php/mapscript and how to access members and functions of some of the objects Php Mapscript : "Jacket" on top of mapserver library Most of the mapserver elements accessible through php/mapscript Documentation at : http://mapserver.gis.umn.edu/doc/phpmapscript-class-guide.html5Z5D      A                          (Object Model : global view    * Map Object   +Access to the Map object  How to create a new map object $oMap = ms_newMapObj("mymapfile.map"); $oMap = ms_newMapObj(""); How to access members of the object (case sensitive) echo $oMap->name How to access functions of the object (case insensitive) $oLayer = $oMap->getlayer(0); ZDZ5ZZ9ZZZZZZA6:               D  C        ,Access to the Map object  How to modify member of the object $oMap->set("name", "a new name"); common mistake : $oMap->name = "a new name"; How to access the sub objects $oMap->web->set(...); #X!Z%  5  8   - Layer Object     . Access to the Layer object  Accessing layers through the map object $nLayers = $oMap->numlayers; for ($i=0; $i<$nLayers; $i++) { $oLayer = oMap->getlayer($i); echo $oLayer->name; . .. } Creating a new layer $oLayer = ms_newLayerObj($oMap) $oLayer->set("name", "my_new_layer"); $oLayer->set("type", MS_LAYER_LINE); //can be used to create a layer from another layer : $oLayer = ms_newLayerObj($oMap, $srclayer) (ZZZZ()                 )         !  X          /  Layer object   Diffrent types of layers : predefined constants MS_LAYER_POINT, MS_LAYER_LINE, MS_LAYER_POLYGON MS_LAYER_RASTER MS_LAYER_ANNOTATION MS_LAYER_QUERY MS_LAYER_CIRCLE MS_LAYER_TILEINDEX ,00   0 Class and Style  Accessing classes through the layer object $nClass = $oLayer->numclass; for ($i=0; $i<$nClass; $i++) { $oClass = oMap->getclass($i); echo $oClass->name; ... } Creating a new class $oClass = ms_newClassObj($oLayer); $oLayer->set("name", "my_new_layer"); ... f+ZZZTZ,SD-                ,         ' 1 Class and Style  Creating a new style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 1); ... Will be covered with examples in Advanced Features section XG;F;t         W 2Shapefile Object    3Shapefile manipulation    Open existing shapefile //first argument is the shapefilename without the extension //second argument (type) is set to -1 to open an existing file $oShapeFile = ms_newShapefileObj("my_shapefile", -1); Creating a shape object //The argument represents the type of shape object to be created. //Valid types are : MS_SHAPE_POINT, MS_SHAPE_LINE, MS_SHAPE_POLYGON $oShape = ms_newShapeObj(MS_SHP_POINT); n       Y              4Shapefile manipulation    Creating a line/Point object $oLine = ms_newLineObj(); $oPoint = ms_newPointObj(); Will be covered with examples in Advanced features sectionL9;8;t           @ 5Application Building : Contents  *Drawing a Map Adding a Key Map Adding a Scalebar Adding Navigation Tools (zoom in, & ) Navigation using the Key Map Adding a Legend HTML Legend Query &(   e 9!Prepare the application structure " Directory structure of the application (data, map file, html, symbol file & ) URL to access the application Temporary files  | 7The whole application  whttp://http://localhost/mum2_php_mapscript/index.phtml The directory /ms4w/apps/mum2_php_mapscript/ Data, htdocs, etc wx                   06:Application structure  Index(X).phtml and step(X).php Separate HTML from the PHP code Phtml file contains already calls to PHP functions. PHP functions are there but are empty. Z         V ;Step1 : General  http://localhost/mum2_php_mapscript/index1.phtml /ms4w/apps/mum2_php_mapscript/htdocs/Step1.php /ms4w/apps/mum2_php_mapscript/htdocs/index1.phtml D                              00<Step2 : Adding a map  uLoading the php mapscript module Loading the map file Draw map function function DrawMap() { $img = $GLOBALS["goMap"]->draw(); $url = $img->saveWebImage(); $nWidth = $GLOBALS["goMap"]->width; $nHeight = $GLOBALS["goMap"]->height; echo"\n"; } .HZ.ZH.x   7                          0        =Step3 : Keymap&   Draw a key map function DrawKeyMap() { $img = $GLOBALS["goMap"]->drawreferencemap(); $url = $img->saveWebImage(); echo "\n"; } .ZZ                   &   >Step4 : Scalebar&   Draw scalebar function DrawScaleBar() { $img = $GLOBALS["goMap"]->drawScaleBar(); $url = $img->saveWebImage(); echo"\n"; }                             ?#Step5 : adding Navigation (zoom in)$$$ $ Know what type of navigation is selected $_GET ($_POST) : super global associative array for HTTP GET Preserve current map extents, width and height   @$Step 5 : adding Navigation (zoom in)$% $ % Top of the file $aVars = (sizeof($_POST) > 0) ? $_POST : (sizeof($_GET) > 0) ? $_GET : array(); ProcessURLArray( $aVars ); In DrawMap function echo"\n"; echo "extent->minx."\">\n"; echo "extent->miny."\">\n"; echo "extent->maxx."\">\n"; echo "extent->maxy."\">\n"; `ZlZZ Zl              *       ]  _     O     O        A$Step 5 : adding Navigation (zoom in)$% $ % Nfunction ProcessURLArray( $aVars) { //set up the previous extents $oExt = $GLOBALS["goMap"]; $fMinX = isset($aVars["MINX"]) ? $aVars["MINX"] : $oExt->extent->minx; $fMinY = isset($aVars["MINY"]) ? $aVars["MINY"] : $oExt->extent->miny;; $fMaxX = isset($aVars["MAXX"]) ? $aVars["MAXX"] : $oExt->extent->maxx;; $fMaxY = isset($aVars["MAXY"]) ? $aVars["MAXY"] : $oExt->extent->maxy;; $GLOBALS["goMap"]->setextent( $fMinX, $fMinY, $fMaxX, $fMaxY ); //some short cuts $fWidthPix = $GLOBALS["goMap"]->width; $fHeightPix = $GLOBALS["goMap"]->height; OZO     +                                                                                          B#Step5 : adding Navigation (zoom in)$$$ $ T//process commands if (isset($aVars["CMD"])) { //determine where to navigate to. $nX = isset($aVars["MAINMAP_x"]) ? intval($aVars["MAINMAP_x"]) : $fWidthPix/2.0; $nY = isset($aVars["MAINMAP_y"]) ? intval($aVars["MAINMAP_y"]) : $fWidthPix/2.0; if (isset($aVars["MAINMAP_x"]) && isset($aVars["MAINMAP_y"])) { $oPixelPos = ms_newpointobj(); $oPixelPos->setxy($nX, $nY); $oGeorefExt = ms_newrectobj(); $oGeorefExt->setextent($fMinX, $fMinY, $fMaxX, $fMaxY); if ($aVars["CMD"] == "ZOOM_IN") { $GLOBALS["goMap"]->zoompoint(2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } } } } $TZZU    C          =             =           '                                     >                 $ C Step 6 : All Nav. tools&    Modify function ProcessURLArray to look for other CMD values & . else if ($aVars["CMD"] == "ZOOM_OUT") { $GLOBALS["goMap"]->zoompoint(-2, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "RECENTER") { $GLOBALS["goMap"]->zoompoint(1, $oPixelPos, $fWidthPix, $fHeightPix, $oGeorefExt); } else if ($aVars["CMD"] == "ZOOM_FULL") { $GLOBALS["goMap"]->setextent($GLOBALS["gfMinX"],$GLOBALS["gfMinY"], $GLOBALS["gfMaxX"],$GLOBALS["gfMaxY"]); } .=ZZHH  <  ?                 '  ?                 '  @           ;      D!Step7 : Keep selected tool  j$GLOBALS["gszCurrentTool"] = "ZOOM_IN"; function ProcessURLArray( $aVars) { //record the current command $GLOBALS["gszCurrentTool"] = (isset($aVars["CMD"])) ? $aVars["CMD"] : "ZOOM_IN"; & } function IsCurrentTool( $szTool ) { return (strcasecmp($GLOBALS["gszCurrentTool"], $szTool) == 0); } .)Z Z) D       3         '               E"Step8 : KeyMap navigation &    )Inside function ProcessURLArray else if (isset($aVars["KEYMAP_x"]) && isset($aVars["KEYMAP_y"])) { $oRefExt = $GLOBALS["goMap"]->reference->extent; $nX = intval($aVars["KEYMAP_x"]); $nY = intval($aVars["KEYMAP_y"]); $fWidthPix = doubleval($GLOBALS["goMap"]->reference->width); $fHeightPix = doubleval($GLOBALS["goMap"]->reference->height); $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $oRefExt->minx, $oRefExt->maxx, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $oRefExt->miny, $oRefExt->maxy, 1); $fDeltaX = ($fMaxX - $fMinX) / 2.0; $fDeltaY = ($fMaxY - $fMinY) / 2.0; $GLOBALS["goMap"]->setextent($nGeoX - $fDeltaX, $nGeoY - $fDeltaY, $nGeoX + $fDeltaX, $nGeoY + $fDeltaY); } . Z Z                  %                              &                                                          &           F#Step9 : draw legend   function DrawLegend() { $img = $GLOBALS["goMap"]->drawLegend(); $url = $img->saveWebImage(); echo"\n"; }                         G$Step10 : HTML Legend  hDocs at : http://mapserver.gis.umn.edu/doc40/html-legend-howto.html The HTML legend is an alternative to the traditional GIF legend in MapServer Set TEMPLATE "legend.html in the map file inside the legend object [leg_layer_html order=ascending opt_flag=15] <tr height=20px> <td align="center"><input type="checkbox" name="legendlayername[]" value="[leg_layer_name]"[if name=layer_status oper=eq value=1]CHECKED[/if][if name=layer_status oper=eq value=2]CHECKED[/if]></td> <td>&nbsp;<img src="[leg_icon width=20 height=13]" width=20 height=13>&nbsp;</td> <td><font face="Arial, Helvetica, sans-serif" size="3">[metadata name=DESCRIPTION]</font></td> </tr> [/leg_layer_html] :ZZZ              D   u      2    *    %    5  n    0 CH%Step 10 : HTML Legend  1Call function DrawHTMLLegend(); in index10.phtml function DrawHTMLLegend() { echo ""; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo $GLOBALS["goMap"]->processLegendTemplate( array() ); echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
Update
"; } P3ZZ3x                N        *    6  T  " I&Step11 : Layer control  bInside function ProcessURLArray & //process layer visibility if (isset($_GET["legendlayername"])) { for( $i=0; $i<$GLOBALS["goMap"]->numlayers; $i++ ) { $oLayer = $GLOBALS["goMap"]->getLayer($i); if (in_array( $oLayer->name, $_GET["legendlayername"] )) $oLayer->set( "status", MS_ON ); else $oLayer->set( "status", MS_OFF ); } } . ZZ"D  &    +             !      <  , J'Step12 : Query  Set templates in a layer Function ProcessURLArray & . else if ($aVars["CMD"] == "QUERY") { $nGeoX = Pix2Geo($nX, 0, $fWidthPix, $fMinX, $fMaxX, 0); $nGeoY = Pix2Geo($nY, 0, $fHeightPix, $fMinY, $fMaxY, 1); $oGeo = ms_newPointObj(); $oGeo->setXY($nGeoX, $nGeoY); // Use '@' to avoid warning if query found nothing @$GLOBALS["goMap"]->queryByPoint($oGeo, MS_MULTIPLE, -1); $GLOBALS["gShowQueryResults"] = TRUE; } .2Z<     Z59H"    3        !            !                 b       /   K(Step12 : Query  L$GLOBALS["gShowQueryResults"] = FALSE; function DrawMap() { if ($GLOBALS["gShowQueryResults"]) $img = $GLOBALS["goMap"]->drawQuery(); else $img = $GLOBALS["goMap"]->draw(); & function DrawQueryResults() { if (!$GLOBALS["gShowQueryResults"]) echo "&nbsp;"; else { $sTemplate = $GLOBALS["goMap"]->processquerytemplate(array(), 0); echo $sTemplate; } }$'ZZ                           %             6Advanced Features  ZCreating a new Shapefile Adding a new layer dynamically Adding classification dynamically &   B L)Creating a shape file  :Files advanced.phtml and advanced.php function AddDynamicLayer() { //Creating the shapefiles $oMap = $GLOBALS["goMap"]; $szFileName = $oMap->web->imagepath . uniqid(""); $oShapFile = ms_newShapeFileObj($szFileName, MS_SHP_POINT); //create a new DBF attached with few attributes $hDbf = dbase_create($szFileName.".dbf", array(array("POP_RANGE", "N", 5, 0), array("NAME", "C", 50, 0), array("CAPITAL", "N", 5, 0))); if (!$hDbf) return; .&ZZ&                                   K        M*Creating a shape file  Jopen the original dbf file $szOrginalDbfName = "../data/canada_cities.dbf"; $hOrigDbf = dbase_open($szOrginalDbfName, 0); if (!$hOrigDbf) return; $nRecords = dbase_numrecords($hOrigDbf); for ($i=1; $i<=$nRecords; $i++) { //retreive field attributes $aRecord = dbase_get_record_with_names($hOrigDbf, $i); $dfLat = floatval($aRecord["LAT"]); $dfLong = floatval($aRecord["LONG"]); $nPopRange = intval($aRecord["POP_RANGE"]); $szName = strval($aRecord["NAME"]); $nCapital = intval($aRecord["CAPITAL"]); KZK                                                             N+Creating a shape file  a//create a point for each record and add it to the shapefile $oShp = ms_newShapeObj(MS_SHP_POINT); $oLine = ms_newLineObj(); $oLine->addXY($dfLong, $dfLat); $oShp->add( $oLine ); $oShapFile->addShape($oShp); //add a record to the DBF $aAttValues[0] = $nPopRange; $aAttValues[1] = $szName; $aAttValues[2] = $nCapital; dbase_add_record($hDbf, $aAttValues); $oShp->free(); } dbase_close($hOrigDbf); dbase_close($hDbf); $oShapFile->free(); //Add a new layer in the map CreateLayer($szFileName); } .aZZa3                                  /                          !       0        O,!Adding a new layer and styling it " function CreateLayer($szDataName) { $oMap = $GLOBALS["goMap"]; //create layer and set members $oLayer = ms_newLayerObj($oMap); $oLayer->set("name", "canada_cities"); $oLayer->set("status", MS_ON); $oLayer->set("data", $szDataName); $oLayer->set("type", MS_LAYER_POINT); //projection is latlong $oLayer->setProjection("init=epsg:4326"); $oLayer->set("labelitem", "NAME"); $oLayer->set("classitem", "CAPITAL"); Z.             ,                    4                     P-!Adding a new layer and styling it " ] //Country capital //create class $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Capital"); $oClass->setexpression("/1/"); //create style $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 2); $oStyle->set("size", 8); $oStyle->color->setRGB(255, 0, 0); //set label object $oClass->label->set("font", "fritqat-italic"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(255, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); "^Z]b+               "                 *      (           (  % Q.!Adding a new layer and styling it " <//provincial capitals $oClass = ms_newClassObj($oLayer); $oClass->set("name", "Provincial Capital"); $oClass->setexpression("/2|3/"); $oStyle = ms_newStyleObj($oClass); $oStyle->set("symbol", 7); $oStyle->set("size", 6); $oStyle->color->setRGB(0, 0, 0); //set label object $oClass->label->set("font", "fritqat"); $oClass->label->set("type", MS_TRUETYPE); $oClass->label->set("size", 8); $oClass->label->color->setRGB(0, 0 , 0); $oClass->label->set("position", MS_AUTO); $oClass->label->set("partials", MS_FALSE); }=Z=b         *                      (       (           (  & /Tr)mpTRoot EntrydO)}6U] Pictures89Current User%DSummaryInformation($HR     d      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|~N      !"#e%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMOPQRSTUVWXYZ[\]fghijklmnopqrstuvwxyz{|~  !"#$&/localhost/mum2_php_mapscript/index1.phtml:http://mapserver.gis.umn.edu/doc40/html-legend-howto.html$_p Jeff McKennaJeff McKennawondwossen