Larry Bouthillier's Streaming Media Player Detection Tutorial - server-side JSP code

Listing One - playVideo.jsp (scroll down for Listing Two)

001 <%@ page import="PlayerDataObject"%><%@ page contentType=""%><% 002 003 // check for List of Available Players cookie 004 String theCookieVal=null; 005 Cookie[] cookies = request.getCookies(); 006 for(int i=0;i<cookies.length;i++){ 007 if(cookies[i].getName().equals("MediaPlayers")){ 008 theCookieVal = cookies[i].getValue(); 009 } 010 } 011 // if none found, call on detectPlugin.jsp, which will set the cookie and reload 012 if ( theCookieVal == null ) { 013 %><jsp:forward page="detectPlugin.jsp"/><% 014 } 015 // if we've got the MediaPlayers cookie, then we must have the MediaThroughput 016 // cookie as well - both are set in detectPlugin.jsp 017 theCookieVal=null; 018 int mediaThroughput=0; 019 for(int i=0;i<cookies.length;i++){ 020 if(cookies[i].getName().equals("MediaThroughput")){ 021 theCookieVal = cookies[i].getValue(); 022 try{ 023 if(theCookieVal != null){ mediaThroughput = (int)(Float.parseFloat( theCookieVal)); } 024 }catch (NumberFormatException nfe) { 025 mediaThroughput = 0; 026 }System.out.println("PLAYVIDEO: cookieval is "+theCookieVal+", and the mediaThroughput is "+mediaThroughput); 027 } 028 } 029 // now let's turn the connection speed number into a few 030 // useful ranges that measure what sort of video we can stream. 031 String bandwidth=null; 032 if ( mediaThroughput > 1000 ) { bandwidth = "BROADBAND"; } 033 else if ( mediaThroughput > 200 ) { bandwidth = "CABLE-DSL"; } 034 else if ( mediaThroughput > 35 ) { bandwidth = "56k"; } 035 else if ( mediaThroughput > 18 ) { bandwidth = "28k"; } 036 else if ( mediaThroughput > 10 ) { bandwidth = "14.4"; } 037 else bandwidth = "forget it"; 038 // set this in a session variable so that it's available to 039 // other pages and jsp's in our site 040 session.putValue("ConnectionType",bandwidth); 041 042 043 044 // check for selected player cookie 045 theCookieVal=null; 046 for(int i=0;i<cookies.length;i++){ 047 if(cookies[i].getName().equals("MediaPlayerPref")){ 048 theCookieVal = cookies[i].getValue(); 049 } 050 } 051 // if none found, call on selectPlayer.jsp, which will set the cookie and reload 052 if ( theCookieVal == null ) { 053 %><jsp:forward page="selectPlayer.jsp"/><% 054 } 055 056 // now let's get the clip parameter and pass it to a playerMetadata object 057 String clip = request.getParameter("clip"); 058 if ( clip==null ) { 059 %><jsp:forward page="error.jsp"/><% 060 } 061 062 PlayerDataObject playerData = PlayerDataObject.getPlayerDataObject(theCookieVal); 063 if ( playerData==null ) { 064 %><jsp:forward page="error.jsp"/><% 065 } 066 067 // now we have a playerData object - one that knows the mimetype and 068 // how to create the metafile for that player type. 069 System.out.println("mimetype is" +playerData.getMimetype()); 070 // first set the mimetype for the player we're using 071 response.setContentType(playerData.getMimetype()); 072 // then tell the playerData object which clip we want 073 playerData.setClipname(clip); 074 // finally, get the metafile and print it to the output stream 075 // to the client's browser 076 out.println(playerData.play()); 077 %>

Listing Two - detectPlugin.jsp

001 <%@ page import="PlayerDataObject"%> 002 <% 003 // detectPlugin.jsp 004 005 // set this page to not be cached by the browser 006 response.setHeader("Pragma", "No-cache"); 007 response.setDateHeader("Expires", -1); 008 response.setHeader("Cache-Control", "no-cache"); 009 010 /* -------------------------------------------------- 011 * Code between the &lt;% and %&gt; is Java that's executed on the server. 012 * All other code is treated like any other HTML page and 013 * is sent to to the browser. 014 * --------------------------------------------------*/ 015 016 boolean isActiveX=false; 017 boolean isPlugin=false; 018 String mUserAgent = request.getHeader("User-Agent"); 019 020 // see if this is MSIE 4.+ on Windows - this is primitive! 021 if( mUserAgent.indexOf("MSIE") != -1 && mUserAgent.indexOf("Win") != -1 ){ 022 isActiveX=true; 023 } else { // else it's plugin architecture 024 isPlugin=true; 025 } 026 027 %> 028 <!-- page header code --> 029 <HTML><HEAD> 030 <META HTTP-EQUIV="Pragma" CONTENT="No-cache"> 031 <META HTTP-EQUIV="Expires" CONTENT="-1"> 032 <TITLE>Browser Preference Test</TITLE> 033 034 <% 035 // Now send the client-side script appropriate for the typeof browser/platform wehave 036 if(isPlugin){ 037 //here's the plugin code 038 %> 039 <script language = "Javascript"> 040 var textMessage=""; 041 function setCookie(name, value, expire ){ 042 document.cookie = name + "=" + escape(value) + ((expire==null ? 043 "":(";expires=" + expire.toGMTString()))); 044 textMessage += name + " cookie has been set with value: "+value+"\n"; 045 } 046 function getExpireDate(){ 047 var expires = new Date(); 048 expires.setTime((new Date().getTime() + 1000*60*60*24*365)); 049 return expires; 050 } 051 052 var playerString; 053 if (navigator.userAgent.indexOf("MSIE")<0 || navigator.userAgent.indexOf("Win") < 0) 054 { 055 numPlugins = navigator.plugins.length; 056 for (i= 0; i<numPlugins; i++) 057 { 058 currentPlugin = navigator.plugins[i]; 059 if (currentPlugin.name.substring(0,10)=="RealPlayer") 060 { 061 playerString+="<%=PlayerDataObject.REAL_TYPE%>"+"," 062 } 063 if (currentPlugin.name.substring(0,20)=="Windows Media Player") 064 { 065 playerString+="<%=PlayerDataObject.WMP_TYPE%>"+"," 066 } 067 if (currentPlugin.name.substring(0,9)=="QuickTime") 068 { 069 playerString+="<%=PlayerDataObject.QT_TYPE%>"+"," 070 } 071 }//end for 072 setCookie("MediaPlayers", playerString, getExpireDate()); 073 }//end if 074 075 // ConnectionSpeed Detection section 076 var datasize=31468; // in Bytes 077 var startTime=0; 078 var endTime=0; 079 var date=0; 080 function calcThroughput() { 081 var diffTimeMilliseconds = endTime - startTime; 082 var diffTimeSeconds = diffTimeMilliseconds/1000; 083 var bits = (datasize*8); // convert Bytes to bits, 084 var kbits = bits/1024; // convert bits to kbits 085 var throughput = kbits/(diffTimeSeconds); 086 throughput = throughput * .93; // account for IP packet header overhead - averages about 7% 087 textMessage += "This connection took " + diffTimeSeconds + " seconds to load " + Math.round(kbits) + "kbits of data. The connection speed appears to be " + Math.round(throughput) + " kbps\n"; 088 setCookie("MediaThroughput", Math.round(throughput), getExpireDate()); 089 } 090 </script> 091 <script language = "Javascript"> 092 date = new Date(); 093 startTime=date.getTime(); 094 </script> 095 <script language = "Javascript"> 096 <!-- 097 // JFIF,,#%$""!&+7/&)4)!"0A149;%.DIC<H7=;C;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;c"}!1AQa"q2#BR$3br%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzw!1AQaq"2B#3Rbr$4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?iإ<#Q4fW(;_\xGh.3K?KP(}qKZ1_^x\RӫbQ_^|i.8|Q&)إǭ})qK\zW:iأΟR⯰t&)t}.)أOȣQ_`|❊1W:QOȥ.(}bΟbW:Q+|%8:OsJ$y)85qGȢgPaEQ<ArNxNrk'<h¹KԪ-fjaȽZ.4 q=]IJ-㥇PS('22A#4-FA;Xl&kӎ2SXh=-d1{rQzҬD9IWWџ畕4U3Ŵ0:㩩f"6ws^qH^]\\yf\tjT==}$1T{D£8惀2N}jZ<'-_⯯<ţS_^|ŧc\QSE}Ƞp.)qF+?Rӫ?StbOͦE}bv+?L{W:R▾Q_`|E}PE}-;ΟͬKRK~ghyS5-;bYq_C:~w<|5y⎡zfϘ$Gl{UJDžUhفqA$`'{ֱऽiΔ8Qҡ3=jl`F)jmǞ\ٚGFBAҳ]RUXE;NA=kVI)3H+BOO&OʊxM'53kpħ;֣E<G[ѣB§E䍰s1[HzzSIC+ber$+ K/Pi*Տ~!ulQ*ɜ㊴Gq<TJ,pku5Gley2\sҬJ:1階+aqlۃ6wgtȞTKy'ފĂTP#G5FW1u,QHvt2J*;z٘ʌe?)n[Ӂj"g+$M:j)cj8=v⑛PynAWxXX<(sKj<(?`V㯥[L3F2ŔWOhy2Il}Mg|F0™@?iǃkK.*omF'r87<NktIv*AG#'}w4YܲG.)uv;<v+?.)~8:D3ס1N.+?NNhѡ\Slң;,ӣ1IE/75^Pl8ŠVճ9ԣ)1T[SҶz{` Jgա\VMLHj\ŭH:}R֣LV$R%Hחyy$Ѽu+7*u?ʞ`|8;ʟpFI{6,/s4^]h@jٿCϧSWXPWDFNjFFOZo.(6.K2Mm,^Xr?v7y=LUᢊeZ9I?Ú`0obOeXúvQؚgvL- jkrO򋋙&U栢Г:h#(hڧ82hL(uNvLⴐB<zbSil8Ȅ1I50yR5SБ3QƯcN3[ tSDڦn߹VQ,WUawSk})YU?"IX.2{g-E^Y Yn8v?UHQǯҤAqJ^&Kv~;xl}kp?TGqޥ6o#y6a?XBG%kp?^f(FfZ}ɺո*:/z[KwW.)R\AozG^19翱i%g*3Pΰ~Y$5bEw-gԓ3v?y}\mn|2$ҐE$źv[c"p:Et]CeDfb3֮,V9^ ׎VPN#i"9bׇ2I{#N׊[y-dPҡidaF+OcVifRvbq5#rįB劈[IyJ!QWo(k.us3f34$_cͨ_DbI{R<<~⤗S1tIl]f%LЅfձ+,KǙsse$zçN-un̪?JU.?ֶ2Ƨif֬--ǷLS#n*#qMe^Us<<;箵[iH=XQSYdT/Ua֥"2am;nk-u!w6{ֻ"ΨAt?U;=fMz}1ߊo@m9QK4fu:B+dS̥I#hۑVPHf@5#fc^*RK*+VG'h,2j9a'9<)7I<Y$,KM[d-%ņab=h1wRs`9f.|ecmrlf6n9Mf2e [#A4ڬɽۻoG^$gq*zV5H?UKѻ85..NXyvAx:w:kX##*AεeSs]3xnЉ0%2e}ZO宬l(|T$#8`Ơr3VtP_$q["LMrQZUexrGٲORwf9?KA)V秸#(1HhFTqIu;󢵷+,)*ɟܾH'0܁?]V2 J6(T3۽Rb…2Nh[/"ul;b6aZ,P(؝G$VO-{Kc=픳<,vnHr+nu?У,ŪNce4r<{,AxM[npMX3m%o`?ÏKg.6m¬U|Bp,6^A[.ҰfID]AGs:-b$hL0Twˏ1xFiZ21ޕK@ը5:kfD?J<rE*؁8=9)D ܶc$˻:7Z<mȗj$U:zS%6((OU5f8\s9EncMY@@?Lkܹ?hIcpmC* }#?c]woqnuVp.@략F%3tW4۸8q[c&k7`8ʣ*Iv5iĦQi¹4N50H+}'ToB)$05'ÌE9b[啢[7}?ZX+=Zn$*89mKr0@[汷nsKmojӈY6`~]BIe?tsTq6Gka\4m %ضZڧceh$HqE9][V`6 UTf\r_[8rџKe4Kg"I_X$)Ob7vV`pj|öHcEl-S^f8.Ny2FώsO{XNGᦸp-#}iKNsSkߴ!~Wc[JO8ؓ,ʯ!Q]OL&r@3t_hXq͸M<u'4h8ir2OJpb;.0=A?T=IO;,}D8pGZGΟm\{ȓ²68iub2^mc]ޟ$Z/m'S!\ĜopC.QZ:mV(hI)V?T0$fbay(IךiKr;WV{m3׽I}1R$K⺈?llb1LOI׷o9V26p2y涚c-#tbRoSxL.c1f(6H<[@DrJmwmGԧZ{ҡm+^<@)'FSq@GH.##T|!v6H@PO5$Bg|)gi$dǭLC qLfK~xb\ǭYUdT֜cu3ĺi7<mVՄhˌoە:䃹H93kJ&i ֣dd\R3r0zԡ\ZrsԞ%1/Ogc*[,q#UJjҶXX\MUMifӂL}*1Y%<_ʧ:K$c橻yϙ0wbgԭqwp2qTaH4iTY[{Rn,X;Nz-7իqo[%wqƪ^ZGkF4õV@ZWi{ȃN6˦`5W&66'P1]`X5W8J\\9ݭ.W^z*y<?Zurh"9ֺYfUș.+#Saf-ԒxIq"D"c_\UxdO/ێ1P;H<b,+&C/Fe)!zBDR~U5RrP'JZVDvjNcs@*?.}J4 lwcobhXLdsU%HKUMCt6rpVsJ&EmHU3#gg.##V?(_#zU4bylni!$xYSֶ$2SQ\cG!jp}i?ؓPhq]#}ø˺hx|)ѲʶDonZAx@< HNkCj2Ilnj8_Md=EjK?:($Eb$O/21ګcgO;nA'U'FXm$ǡ*)U3"bd1,J*xǸu38ͷ1֔SY9a@s'L[j!|rЯm<w[o֦W^"A\ De)-x9isKX[n}*չvZ{N]9v4NzǦi$ޥPxڣ\ s[3祟BuftSRDڞ)_jFoS]Oj;@]*9uՎ(^|Ota[(3r1s^4WoqX֩enܽޭOlDgaUX2yxun8\۴G$-lpקX6֛uPKnS^d(cYy1#G?ŇI02;ȿN*he洍ɇf?sv9QҶѯ-\PɜO8\fH؞@=j&uzҩV^c$JMs/K®ؼi`bKmV+sȕ.TcbCuoE%m6E2tD#i&+C笵\̤ү9.Rekq66w18ܬ̲3[HcF<-SiinjCm<T?hȸI4ە\ta'Fά6ͼ~9I?o%M"Bw{V弹x✷Nmm!{V|ɛOWLji"$dK*dHۤrITxdlgm_F}52Ō`UoDjI$֥6Q%ACY8cmbS?'!|0\=zW'TsQ?BjMI?\{!$jm445$td@+c6<_b!cʆ 8{Le$Xck@G.,&I؆ Ij4zTD<#nԪ\Ϸ:jMlgP6eq]s&Ar'V' V"Sح8y]2ު\vL``|jIoq*PJcI{loAZr:~8c?Rq-2io6@''i[:92EnXg׸u+X⦑,G.=AKobEݰ?|,AkG*,QrZai+?ZճD՞BCxAt=ɣ{NK{ۉdoШǿOֆPba8~I^[GaEcOXp'^߄2ڴiףqaS?~^N8gcV+?Ռc1c9ǩ)u232U;Q֕&h$ٓ=qmfS$m#slF1۞ףFZҥ\_)vwgkd?x8&U6]O;sl.Ӎ yra@a?:\0tW-#|s SԮ`Wz֖}ԬmvevMXD!0f/sQLH$YdQZՒ[&G?R|*"1֪/`4uI0~EֲtN=WFraR F*rBUw/$ךgLۢz(ױom)FX-t*2䈋}`yqr=E6%s]:#A*9gqhW銐#=UImde\T-OѶ2n$&I8mB.$Fx_f5˕jMoHwֆvlһunR6F#`?M9`sWu\dnRifd8,֗"uq215?uX{InϮkC;ԃVӣmy3/1FSi\rBJQD8`z#,)եt+|+*{Tb~iOs+N<R4'qYGO:n%ǭjn #"BVJFdq.qڠo!pv5XIP%*C#P.6ql^y~LƶmHӂʫsguwQ+`ըU'1t#[/Eȋ*Q毢.x(U\De;sjeMʦ`+bnF<u'54NEYb]5faU9km\g=TsjNRB0skH$ԧjGA'&5T<}N1R3DˍZً]n6*[#+"ZҮEkk2Fg{v#3W4!AaVbǵ[1v3W-q[ZWocqoQ]kҊ?巸FiL*4+'<b0H$:ը=g {c5k NbN1M0#ynrJicoɞFhnJ#=;)IvO5d(q瘅=W?K@gX( LC#*F/̇f,VE@Z"?-on!G<lȕ,a<Yb;Z[1$FN3zЫ0PlB dPzsֶ!/4gwz 5v6'`FUr$;sm3(9SSc9ay:%#慝Ļ<n?5 qZVf\2`mɸe?2K)#&2¶/p*GUQWp^;UShH8j)t?ТmbuBxD-Gja:Z=OQE\1l|sI 5:-ʹ;,;tvQСRyT@6A*;(R+ItbHO#9TBmG6[嫕g`@_ʉ[m!^uEԞ8O"QS*J}^T-ɕYI֝ճs;0frjA1;6tvH7aRBUbֳoQ<:nH?-D,66;Zks$}*ש=sJ38,[5"W)!T#a$Rq31MG~1Sܼr~RNcɠ=:NM`1џ=%UKֵEʣ$9LoWx=;WS[ksSDY_,e;+&e3ǴZ:M_j'v.Q+!碑؃޴Cg¹d,kbܫ[?J{U.|35sI,3Z4J%9$0$_TŮs{0\/'.b)Q"͈-$GVbH2KsNWd`E}2Saʑ4iXdVn=Mj$?ᡖQy?J}Χ?c`-?O%GRJ(ŽNzzZ޺mP%T.~q<2GavȘfsV⅔,jG8O2y;WM2`cjgs4vmI"Z*=ܧvF{⠙0UUpmLK&3`7SIe0}DyOe&!<*$'vQ"2NFxۚՓ%U@/ʊV.ux"PV@v53˄2ܤ?osJ%Q8j+"Yqgjі(D+JB1[1ASVspȡJdhLlu돭OOtbZ򂎀NX(CcqilA+´hqj?U-Ag`:%}z{T.C/j)O:qTjθbÖBÐ9PIh32+B[X#QLҬHn]i,k4lF0ГK qqIHOnnj$Ͼ{V6Y`9RGN?t}\1dzНb22*ꪪ]K,?ЎԨ:A[{Ȕp|Z71,~Q)BU3.vv3L"\x#82YafE0,1ڧ?fr|.q֨KwѼ_R9u'1c?LO"JcBo|qZq?ʀ[!by@Uqۚ$f4)eHtSW)#a:є^ӏ)jf}r2Tk9@ 2䜨_V8ɆX+4Tp~5IVbR8NYhp*樾Tqg] z*+[$rU9$"_&AKXU8$gZ$i3?k˗^HUbHԲb#¢H`*xҷ-+m`pJzZ=6ԡ2Q$F0OTa]LRA0|UY}Wjl@XUrR?_e Wьwk$K?F$`sqR2AT2Ï®,c',7mb)rjlʱl8ɭr̓#ΉO"0#}̅aem[rjc$^-LUrIC=x4$'e}?XОpZ5_+A+V`rQ8NL2?G8v5GŬV2pYFT9`lLAA㷥<ܦҵ%ҡpdsG呌dj]['TnU9P4&qЅlesZlEg }*q|ՕL*3T/[d!K|p=kS;D͔6.OP8qLp+)*qmpVL3p~۬zF^͖hnbs%+NwsU+UVQ4Vo{Tek=­XceYTn˸{jC֠K$3aU]<RFG5PLF0cu5fu=?۹6GiKpequ4^bc͋Q)DvV]4؜qAZ֖?БmA߷g+&?QZͺvBvAg9ۜ¯͇1q&sUMmm$ 8\1W?lܕ?u歡pPcpH]VIl-NhN89ޕ滊FI#$/O̬ȑ8Wo*E9.0q݃Ƶԧ88O2W7h@ǵRRSO̱%R {Zɾ1|Sŏ[tmqn"_/啛APc&ĎjNS֧K5sOAWޛJ851ޯ6C^U׆é01?sVgC d2*eޕb҅t#xlgڮ*yc;՟Kxc9c BKR?W'"?2L|_ުj2\Zс._֬(۾K&Ng8vgUdW=edBϥh&V?tPJ.7+x-ݴ|oqp &+r%?)e;xvL~R/XpÞvk푩,jUm϶!Zԭc/'cj&dr$"1$qqDac 85L;ŷ0h<T(Si,k r3ҭa8s=[Z֤EpG:#څVHmrI3YiIgLRh`8zV;¸p$xHA<RyTf?dR$Z@VbJڶ0՟Эl*rCq!)&4Xq%nUgpсQʿhѡ;ŕ.?VDf;7j+#o@0d~5E7}g)$L:#?:{nb1b9RH0##_I<dْ"yhMe;]ޘYDk'+=XԷF%ʜNԖSCH={X4m2[0sZ6ZH'CUӞ;bva(;-_Oj#'&եIocW2`:u'}hH(v,g)W唰wҶG֭vqNpg28ar?V'apG|6HfW#l͵vuQ@?,3`v.)s(Kqwlccﯖك 1s^K#sVAxd+2is`0C.*[#֡ħ޶u]&89S%P~S6fծ/d,0T3,215cnOj]6eEÜֽSߤ\$k`2ڪ*_K]]L,{|wFrN+ܰ|ηࣲtȗMcrlw=1¬-\2 x<zCq-)A/=?UF7nNyǣ#heo|vqZW6h(2i.4i+08I?$%+,ڽAZ\˖˺iON$(rJVѯv'osqqG,MЫwȶ(互C;.9S.s= |nxWU%#9lf/k{eȭ/kHcIZ5=9ny#5<vڄۙp;޵3gX+*sbY4gqkB}6qʢ<r3^WY!m]dssVc;w{J;pj(<'N dִ7seO4Tَ*/5l`Ҭ4n?RZ7%K V}lZnm 8B*4ıXm=ON/ke+(r~7c<6hJڟM3ZIm~\`VL<giiPw7,77ִԛ]rR6Y;ONQ*\ǥfZj2NNpѱ;Jl6(nm̃bP^k[Ђ!$$skǙe89Lq0zִ\y*~d}L%ep<AVGpAqק%[%QhVc$JzU?hԆp@֭}U)Y.\-ދȚ8m:h&Ӯy2(+32{犤O)L˓oO\i;< (F*9Є`kc%ȲKD+66{~x[%XèɪĐP-1V<dkuR9w9+ޡbHo2?Lm@楸v"6 AnjJh֯+"9O֨@$@O)#s:c"oZר<v,Oj;M,qDXg__a,P7n&@8Pk-{ :ȷDv{snXGjv$^TIc3;ws"y@?i[-Ԍ41z}+ddѥr\u16CVa`eHђdfB@V홫%vƵyrr}*-3<"Tqn%ׇmi+FyH\p--eS~<0SLuZmy%=aQZ\ApLJ=wjHJPsNEtVŹč[`ڶﮯe2OҺ#/^Z@)<IgȐ\$SRv?/wm۸̪οjf%2v#6xlv eXi3iXMP6+Oyr[eԏwiK*w֨ϫM)hV37C]wzɸg%TE%q_hysdvV1m'n['8UPr#nveǸ\{U;fsUpҧӦّQ$cmͪ<m"<砭sѫsX٥Ŵu(A*,ICi%D*ˁ}7$!"M$O~kf`?Ac$QYNtVgӽt4BG$w4W#ɛßQ$)k#^ylmԿu1Ky*0P{TQ7vJ0:͂FQ9u֮bF,1k{:wG(KmajoJ:쪣ݻҡԵ"cI$ζ9Tt?֢ASޡ"lÞ0AYu"e}ĚOz=d#XS.׊y}u-b;]/Y-f$s4#67kr"UْQЩuuoqϕ\#BZI*B0r?DVTHsۨSxzIѩchyiO3pqI y9TD#5$̶fX)ѤCi{If_*?,.Q';y^ʅ$/yrqYō+ZT[r{hŸY#;P:dgXœnɭE"ĉCH9"KO6XAJ}vd(evkFW9<a}F(=3Kaj6 098 //Xʻ_Az!p|Ojn1bOK{|in$iIUC*d6zY֬5(,aKy)cݽ}}*#5$%snHM¹IUɟ5jש7exV"l@eo=j/~Xq.4ۉfx8)7gЧSpHcH'KyI:57뫣ĥ9G&tkkDZs3v[DMH]3A9m#yϴ-HT8,$duͶ[xv|:Z#ҕ9mdhċnz!OkdN?wZ6{$DχSEvP^vD/mcӇLw(v3HF<%FAV*Ey{=8)P}o:Hrr&V2JԨt614UW?Ee,#ZMfC&-ZTI Oȭ.Eժ`NrÀÊ)Y8aQT{f2@2lGI,cyRVsjOXʎsB(%nszң2CF9Z&ɒMl. yNx*g7v'Ve-tPr{wm&%yV(zGo{Ɉ@XF&InzGtD,{FjҪ[O2SsV{FǮN3Iѣmss8?F@Q73Ob+\Axe~R2)Jrns[[&VU@@p.[X(@&2#uj5@v۴qV9gAc'F\f%g8?ZS)fIkqr!Xknn3ǥosOm+${[=Ai0H +F}roQ$#}IJ8ʥֶ9uX-4m?R"R7ǵN֑C|L`9楹w;#ֶM[I)ةJ[MȬ#*F6SA!q@Y2YLo&.<BdVGׯ#r6O#-Ҩ1;ONݨ50?f\ĥdUi2:dW;oBʤOZԛ Qר;ʳlʞGҐ=2znUn-c)ɑ[|79=)w?fG"IySWBqj$7Ojt_$HUݳ=xṳ̊<Uh$2R.?4dLjp$Vυ]|9Fߘpk^f/cl1@VL';ONƭz*!;bԤ{⯦cs~UMȏ˻RX'˓Aެc ((]\wJ4//$jHFnK@)k:[{$+$;,!h*G3iq;mv#jeG%X2kn;yl|֫=fW9SDpr6ӚI.DŖ($ڬzT}o,A"H*Aqrճ%ү=;IʬbR]ǧҰ{dKhrGqjwvR}=+D\Z?dG}V@qY3ډh#ZiZ"͐O$rpj\EsnAH`ǥks-c.FjPEw&c3=@[A";UiO lbXV\J߹KmqqP|\(8嬌qKs#EH+pqڶf)|07G=*B#g55pꧽ4 ɉթcׂ5Wf98n)UNc"9uҦ1\`ZМ I<qڜЉ`9'qҪ!af3 $vRſ[ûlkFԑѴg` vně8npqNDHf]g)qlnɵs҃i2oFS1U[ޟZ4ލ}HڛG`x};sZӦ׬ҷQX};AKoe !c'ҟ,Wy,yNZ8TJ@mE Pҗ#'l*Ki,灍NGb1׵"1?<g}j_,-s[\^#MlY_فUwvۯ <_/#hA5t@a@vns6U-v/jOä۬n%梐~mZkXeM9fdD H%Xlas,5ORqmoc*:w-n,UP0MIť+MdU:)"H\T s[cew7\@⤷[u$=NY!Jt,K=1<S߭~\kkk}VMord:6tLHf:HVbFfqb]NjKine&LfXc.bҫFZE,3b,hXpqME$H?gMmhbJQhʾD|'Lfaw]&F:f*ZL35e{ԫk,~T\עGmF&9u$S$LB[61Qgpf'W?v4L7sҙ6䔀^3EHϙ!6Tp03*mI10Yc"r8Rs,QGPk&̻@U9MQF'ks!00i7bOAT7?,fxi@[oN? Uܖ_.Xǖ10_UL-<JCUhVcFãsZ"9$$Zw杧99zUHg_V_h99ҶPK;Lc'8j,q)qT;Ͳv<g{V57v/PiLgٗMi8#,3ū2,F|g֠եd61dvmzՑ,Xo<t6y_ήf9bXqE֮;'8=c(Ӗ(p?vUO7v$׬-(];iVlbr5)9bt'$تЭ(O@)U<Sq=13zgEPѦɌvuVpxwȻZrx,p?ҭkEdF6faԗLmM۳%A΀:PEWݪ#ӎU-Ud'rH69uN6@Yʫmoڌh[+1efZz-#U+;j}jyo)c}rWqMەVȮby‡,)wFvիlnuZlď eۿvobLeYݦ˩=ZȮh֛?֮G0Iq|i+5;dU|k.vFP̅%jƈ[wC4ס@"Md"evoT,^Mb*ֻ5*WuP]3DCh5gЭiܑW2<rsUVvI%ī+4@a2M::mmu%!M^D_wĈ-P0547v"640~d[N}wkQdR]WnkFs}F;h팖.YS,}|ϯRm$I<*aݷաӨo-\!f-"UK"a6?OF*/_q,s[9ܢD+KjaT5.(w!hֱ%ϔ0RD⨵ǖU_gZ˖$js_юfP\R;a}sS;'ҙ]2?.kS֣rAau/bAGfU7i0|zT(}\jFwsB*x!~V1"0=Ҧ[WOY$Ԍ!b߿)0@٦E!a,vz"Emz Y,- aX}N&PQycdX`U]Fm颛CE]l硹ȃ.<uF#5PcQX-;dk):<;ӱw(;S O)ctrIbFBhT#SNCbuN͈3UEQG]O1#5;K`tؽĦ"߻?SMxW#TcpR8=jJ[v-tN$T҂.66nNSVƛeeɆIFa,03i3H<yL0F~@P63,_I!%r1ڕY<w9%pF}*ʼnH7vƤNB(〱юa7_41d~،DFIevոB9a28$#YOF\犑b:U`bP}ҁ\Ӕ)g- ڧ#+wZs)2Fp8UԽ+"wi"!qL:iBFG՜l,7GDZⷍUd [pO?LTjY㵵߼@ֹ5\̴\n5({RfGZt(WW׺րϕ4g˓w͵J[mګ/Z՗j߻iq#sDJg7fyE"l̿*n_ի+l۩тh!I/ۈLﻇ۹F+h˫˂Y~UM/q+?(YvbWC̾ogYԦHn-?a`սsaja<aBevPˡZFȲ˵knSj|ÎcH$yԑb'ʣn֫)X%RJUi-ޟk_] Yb2D7vw27K*5ݳ`(?5d1,xhn[Z54/$I%m_x@oZ͎v˵]աg{*?+&߻S4ōJTUo/V{K}(WwZ֋v*"{ڦQ6<D|ZJ-׭w-ż+x·Ϸn֬і#+_UmF}J2c~D]AmVR?Ч"Xkۿuo.Ւ=p5PX.F1{rN]JOrOVd\M~^-wCQPjwQ{wZ%%!zӉLQJoibiD\sP]n[1SÑtӮ&򜲹'#B:sVYk;w(CTTH(cF<B*V+<a85f]=GnNn~-m{(f0F=}*9ʨ.XdwM;1`+eJnmHsZ\'Ҋ?Ergx}(]TE*4<29g^X+rw*TpFڤELBpgջX|\I9S[k͟R,0:$(ɟ*m!i~y([XYq4ҡ ؗlLE}oaI-ޖ[moX7?@ͺ5H5&#bڬpOif8j#^(ԫurE219tm<uzOC֛Cխo{(i(-֦*Bgu֎dy 2Atq9АH9(W~"Ja7g!%⡔oIH\lI F;g@LL6bv;|3%221իYX.C'P1[bÐN긠LVA4aք=GQJQ4M)XNÇJ?ۻ{i;$*d*Xṙ6,$d\R-])Դl@׻ p+ܤI2r=Nw":n~UG"\Fkmv7?ՔBrQu<}ZgfgF["\.WvGօ3bP7T"܏%/߼Ņ%$eMrǷմ&Ny|-u"[˝F?5+\,|~*{^EEIxO$fѾ_Zo=nI4{Y76Iz,لi[8t,OU/4PuH[*l7kUuKE/(#˻+7i72eITeX/nSZRg-;Y:}Ziڪmۛ}Iђk/rl!W9eQծ䕀pe*Zɐʳ.~_YYDIh#dR˷n/Tgң{6ݷɹC.uUav)?efY|UVeT1lH^2,եctFҙq6|o~EjAݕ!7ݪ9ʹ3Ÿ|˚5`7C+V-rc[Gqrm6֭TQ@rkS%|nڻ~j'գ&-5cbkGWO2ӦkؠS͑_zUDȮͿͶ2{ި#7q'VW[?$EǑwnqt1\mZlҨϸCq6,5r!qH#mV1,ǜ)=6-!7VQW?伩Q`N8[\(e^I<昧wMj0,sJc n$.Iy122?i%ILkus[|*Y=1ީL08EM1EQ?7kF9$g5jkv+B?Ze0_}ic&Y$T#խq ۸WgYؽDB ccϻsy')BaB?֧̹MH=٥E'8w27ZfFsvT'm%0oneMAO<UBybiw`I(љB$TQ%N%ךG7Uҟt\HϿQyn)%x'fhEPӑ@ӷcP4G#BZU2Kͷ'B?ԭ+8RpM,i==O&T$s"(V6A._w@'`ӐJ1NTQ,jFPzQSПW?ֺci#wd9+VL8YcPygoxҋGb0wc%zP$аy+$ɸST fB]Z?w;A'{C0@пݪо#s]3uVUP[ED]~\ҒH&QsS&xP̬HO#P|ҕ,($T7ԁ4ɯ+v5FݹjZZ^.;}LnfVQ .R'SDVK퀫g?z\ԯ}П+ʑVo5n.ԍVIjvl,ͻj2yQJK٬}~X.l|&5͵ķ'MڈUFՕAjڕ&(eWyr7,~]eglF<PJddڳGT6 hm.eYrֆ}wQ-1H*3H&mS:Ʊ $fuUu$7ݿ6)T3;Swme`|/Qp;Kc,:mmӱ/̽6PnzoGjü$yJn;"VX0`߽-Ij.1+'KDڛeUr!}_uF7:S,eR-\.RDػ|-3ɴđjj/nHܧ'WgŻg/ˏ6Iyp`pfLOUbu&G@v։\˙S&\Dd<jke0<Z"6 p`Z+K΢)FR$u!$o,jKyz8ic.kkjpί/p:ZKdiX<`3PTH?Ī%.ZU$"*Ҵ۟Eep1P,oڼa④N~UsTȢu_(̝$"VkDߵVR?O#`ۂǽQ'Ң8<Xrc$T@%R=< cmBUӯnufUvOt?<c\g=EF3vԅy8/J"A^e3֞p*qĤ9,@0g'A`qTIG;402s϶)<RH1 xڨG׮4JKms]{S%j&I{*$ĻN6ЭȪtmĭ.::VnȆ)$pȖ(XN\cwGѯo)8W6(R&1Tvlfi| q\ҲtEJE/]4#8W8Ӻ%W;܏Ң.eiNiI{PWԙPU99V@*Ty:vAi" XP+Պ,t<ŕQWj8[¿nėa"j{kV"H_[Dּ,8]mݺT{NIfXyKTOLvGI$l7}ݿzKF̸ֲܻh0ÓGޫ`Iq,cncڵ6`ҕճ)m՝+RomcwW/y(ahaDz)]vLѽYrDG.݈+nX~#772#!]jѵ/iWV\˶[qm?h2G~oOb"2?<!+$wj҈madݹ[vv<&_Qࣧ:ޥQ}ݶ<q+FTrLüд;V/~Z[M6ۉSܼ|/#Iv^/ӻ5"3X*~~fjbG%oYT?w3A|6T7pǗ5?ˑ(,ޠ-I:2cnܵ6ݲ.}jg9ti(*PEye3n*mݤZHcnMM0?g:D`rZ3~<}*tXڭ5e|ҝ.T5:d&#*l4N(V}'+qYI|k[;<#*M*!Cz"8 JI20*h6?uF'iH\giR-h#Uavԓ7[\V?{T#N,!@mqPsMGp9kZ<?E$֤b߸*%I2=1<[r#s*׮\|bB|͞{fLwЃie.HPUjOTLyW*Q7?d@)~^RQ6_%qh9GQ'ҏjG'Qw9ߕ^9i3ݰ}hӭ#+|Pj:Ayeb<r =i#LPbC2KpqQ8/+JؗxJb?Մ~Xݩ( w`q$_ިGb,c%CtWbPPsj(riA@ATI״LxۏLEH)d?LS1n@Вa2mXg-ˋi b|YWQ:т[cUWy<Tk0bFU%TuVtbB0s̖i˾3wݻj&8nڦ/VI_sӊVKYp?6ӷUxuH.&#fxx..)t]NI_hFsu\lk['lSk2{wjGgX\)5VFX*Vݖ5=֦)3̻.`3U۔YVr<vכi WSxY8ؿ2Tgǹt8?kHs%B/ݭKk$ͳBmîUbҤa*ۿ%5tƵF@5F4u[-$`o۟_jH'anP;]+OGyiofa [fa7e**~ZO2%ƀ͹|"NBw|LxaiYvߗˋA(*_"eyI !r.iŋWe͎B+3H86է<N#Ē]!Oum۩GFMKwPQJ|7ޫ2+۴(]ۿwTDq-OɐGVi\ڶ-7ys9ge-THag&02Ҹ֧ NP0$=ꤲGZƹ9-BA@qס|0vdJ-&,3dJjlR%c'gձ#Zxb@#'ٜ;hWy2Eyc`5pA)CD~n硩VӪrUJ=vq"d.ZM䓞ԫ}ji_a^QP+ycMknDծ|*QBLuUb^%Q*cpOjS,})X`0I@?1(נr;񨧕p\[g\|ƛՃzФv|H*{ԫ$B鹘`s֨b<Iga#*#wPl%1F*tYJy\OV9RCH'5ȲI$@?O*?,C, fSzV5jݏʸL@nLc.GqYB{ܜ=惝S9o/',9s+8vPCr0GB@H[Pk=BJuOSoՇӴ$?Zuh%EEFVHZЩ4i c6;Uh̒}uZXclҲ5X 1۷h΢Е-/$:HRH^=/?z]nxEIZNrv3lp]+#ti7-)@j|;,*a1 e-4Y~]m՝}tWݧe)+HD#jg˻wv8#iY`@Di$-0ܟ6()UcnԥAp;K_kB+;i Ffn[W6a+Uإxb$~rva`,,ʊLq?͵WnښE2FP:yeQ\G?X0/coy_/mwe?gO#!(GD%o_GץlB控OIY8M{s5rR7U+T3#Eļi.᭐ݺ\IַA0jX«LjSf#.VѥRJvަЧ˜j3)ȟ:yh|O~lna1oL0LHKv|UUr.+:J)e+rE%ƶխR<Uۭb0zW0lT,Ar}(2E'ʌWʌ?EOpsRCG{0:Me`A#}2@Tid`φ.Ily~䜉$^W5P%T_L\TNYMcy#֤af@;P`CXh#ON(JǮR׃2ET߭Щ}GJڼA7p,)0UѢ@ 1$o;T#M(ϰNp#'ujӭ25q۞06O#Ҕ6wqԦܕ;:rE1wV79vէ?E:kĎ(wlq|Q.O$T#ւw*<qPZ'Q'I8Y{;`܌P#ЭqauN=zZesҢ*JޑO+ѧ3cnbBX'z65V)oMR#c(NA4XN-aK.$ݎ^B.lUVެ{|EQG|҂8bH-DG\mOzV*34|AĽ|a{e\C8+F=}묁6[SQO]M(piLg29:WppM~lH+.—0JI'%'mMnI4G'F$ ^*5@'iȪ!ֵD/1;VEP<oI+zjy?hSPqW=)%XS֔6ҍf?(+HSf1v;pszYAv1h 099 //p3fY[eE|lch}kK3ҡMK{1;#ZY'ՊY8$i#ӡ-A#gzUE/e;7P9}jż pCg$gdԭ`Ic'PS0ܖQ޳nf9Xs,.!+jի,Y[:*5"RGbjb\%64@,G9*@֢w4%#4_Lҩ,@rRƹyz?kq(#mlX1*Vs!ׂrsޤǟOU-%l<8RfG$SʓKQY͊GjXmbjfLo"אjoqc5!c$##R1URԁχJ=YZBR@v#'Jn`g5ԡxS.`Ahƀ٩8UGҊ*Р9EѠ4<iǵUҭv/cEDӫ#ja&EB?Ԫ|LZ3(խ#cNX#< (֭,i"ⰵXڤE"YGbWaj͝F%7c(3eu%MGl?ѧo#˰iǥPn#04摬fx+?}1d慂/E] yQIB?ԩAFe{9n8a1QW?ա多PF;AO3QM@B5-"G~QZDGQ,Vtp?Ƒ9椑(?Ow<w T=h̏Ǡ$f*@<ǭg dUqELԠ|A<sHGգ!5ZGo<ryE?֣4[; _ƒ(EOh➌Dh f( 100 // 101 --> 102 </script> 103 <script language = "Javascript"> 104 date = new Date(); 105 endTime=date.getTime(); 106 calcThroughput(); 107 alert(textMessage); 108 window.location.reload(true); 109 </script> 110 <% 111 } 112 if(isActiveX){ 113 //here's the activeX code 114 %> 115 <script language="JavaScript"> 116 var textMessage=""; 117 function JSgetExpireDate(){ 118 var expires = new Date(); 119 expires.setTime((new Date().getTime() + 1000*60*60*24*365)); 120 return expires; 121 } 122 function JSsetCookie(name, value, expire ){ 123 document.cookie = name + "=" + escape(value) + ((expire==null ? 124 "":(";expires=" + expire.toGMTString()))); 125 textMessage += name + " cookie has been set with value: "+value+"\n"; 126 } 127 </script> 128 <script Language="VBscript"> 129 Dim hasReal 130 Dim hasWMP 131 Dim hasQT 132 Dim playerString 133 134 On Error Resume Next 135 hasReal = (NOT IsNull(CreateObject("rmocx.RealPlayer G2 Control"))) 136 hasWMP = (NOT IsNull(CreateObject("MediaPlayer.MediaPlayer.1"))) 137 hasQT = (NOT IsNull(CreateObject("QuickTime.QuickTime.1"))) 138 if (hasReal) then 139 playerString = playerString & "<%=PlayerDataObject.REAL_TYPE%>"+"," 140 end if 141 If (hasWMP) Then 142 playerString = playerString & "<%=PlayerDataObject.WMP_TYPE%>"+"," 143 End If 144 If (hasQT) Then 145 playerString = playerString & "<%=PlayerDataObject.QT_TYPE%>"+"," 146 End If 147 call JSsetCookie("MediaPlayers", playerString, JSgetExpireDate()) 148 </script> 149 <script language="Javascript"> 150 // ConnectionSpeed Detection section 151 var datasize=31468; // in Bytes 152 var startTime=0; 153 var endTime=0; 154 var date=0; 155 function calcThroughput() { 156 var diffTimeMilliseconds = endTime - startTime; 157 var diffTimeSeconds = diffTimeMilliseconds/1000; 158 var bits = (datasize*8); // convert Bytes to bits, 159 var kbits = bits/1024; // convert bits to kbits 160 var throughput = kbits/(diffTimeSeconds); 161 throughput = throughput * .93; // account for IP packet header overhead - averages about 7% 162 textMessage += "This connection took " + diffTimeSeconds + " seconds to load " + Math.round(kbits) + "kbits of data. The connection speed appears to be " + Math.round(throughput) + " kbps\n"; 163 JSsetCookie("MediaThroughput", Math.round(throughput), JSgetExpireDate()); 164 } 165 </script> 166 <script language = "Javascript"> 167 date = new Date(); 168 startTime=date.getTime(); 169 </script> 170 <script language = "Javascript"> 171 <!-- 172 // JFIF,,#%$""!&+7/&)4)!"0A149;%.DIC<H7=;C;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;c"}!1AQa"q2#BR$3br%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzw!1AQaq"2B#3Rbr$4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?iإ<#Q4fW(;_\xGh.3K?KP(}qKZ1_^x\RӫbQ_^|i.8|Q&)إǭ})qK\zW:iأΟR⯰t&)t}.)أOȣQ_`|❊1W:QOȥ.(}bΟbW:Q+|%8:OsJ$y)85qGȢgPaEQ<ArNxNrk'<h¹KԪ-fjaȽZ.4 q=]IJ-㥇PS('22A#4-FA;Xl&kӎ2SXh=-d1{rQzҬD9IWWџ畕4U3Ŵ0:㩩f"6ws^qH^]\\yf\tjT==}$1T{D£8惀2N}jZ<'-_⯯<ţS_^|ŧc\QSE}Ƞp.)qF+?Rӫ?StbOͦE}bv+?L{W:R▾Q_`|E}PE}-;ΟͬKRK~ghyS5-;bYq_C:~w<|5y⎡zfϘ$Gl{UJDžUhفqA$`'{ֱऽiΔ8Qҡ3=jl`F)jmǞ\ٚGFBAҳ]RUXE;NA=kVI)3H+BOO&OʊxM'53kpħ;֣E<G[ѣB§E䍰s1[HzzSIC+ber$+ K/Pi*Տ~!ulQ*ɜ㊴Gq<TJ,pku5Gley2\sҬJ:1階+aqlۃ6wgtȞTKy'ފĂTP#G5FW1u,QHvt2J*;z٘ʌe?)n[Ӂj"g+$M:j)cj8=v⑛PynAWxXX<(sKj<(?`V㯥[L3F2ŔWOhy2Il}Mg|F0™@?iǃkK.*omF'r87<NktIv*AG#'}w4YܲG.)uv;<v+?.)~8:D3ס1N.+?NNhѡ\Slң;,ӣ1IE/75^Pl8ŠVճ9ԣ)1T[SҶz{` Jgա\VMLHj\ŭH:}R֣LV$R%Hחyy$Ѽu+7*u?ʞ`|8;ʟpFI{6,/s4^]h@jٿCϧSWXPWDFNjFFOZo.(6.K2Mm,^Xr?v7y=LUᢊeZ9I?Ú`0obOeXúvQؚgvL- jkrO򋋙&U栢Г:h#(hڧ82hL(uNvLⴐB<zbSil8Ȅ1I50yR5SБ3QƯcN3[ tSDڦn߹VQ,WUawSk})YU?"IX.2{g-E^Y Yn8v?UHQǯҤAqJ^&Kv~;xl}kp?TGqޥ6o#y6a?XBG%kp?^f(FfZ}ɺո*:/z[KwW.)R\AozG^19翱i%g*3Pΰ~Y$5bEw-gԓ3v?y}\mn|2$ҐE$źv[c"p:Et]CeDfb3֮,V9^ ׎VPN#i"9bׇ2I{#N׊[y-dPҡidaF+OcVifRvbq5#rįB劈[IyJ!QWo(k.us3f34$_cͨ_DbI{R<<~⤗S1tIl]f%LЅfձ+,KǙsse$zçN-un̪?JU.?ֶ2Ƨif֬--ǷLS#n*#qMe^Us<<;箵[iH=XQSYdT/Ua֥"2am;nk-u!w6{ֻ"ΨAt?U;=fMz}1ߊo@m9QK4fu:B+dS̥I#hۑVPHf@5#fc^*RK*+VG'h,2j9a'9<)7I<Y$,KM[d-%ņab=h1wRs`9f.|ecmrlf6n9Mf2e [#A4ڬɽۻoG^$gq*zV5H?UKѻ85..NXyvAx:w:kX##*AεeSs]3xnЉ0%2e}ZO宬l(|T$#8`Ơr3VtP_$q["LMrQZUexrGٲORwf9?KA)V秸#(1HhFTqIu;󢵷+,)*ɟܾH'0܁?]V2 J6(T3۽Rb…2Nh[/"ul;b6aZ,P(؝G$VO-{Kc=픳<,vnHr+nu?У,ŪNce4r<{,AxM[npMX3m%o`?ÏKg.6m¬U|Bp,6^A[.ҰfID]AGs:-b$hL0Twˏ1xFiZ21ޕK@ը5:kfD?J<rE*؁8=9)D ܶc$˻:7Z<mȗj$U:zS%6((OU5f8\s9EncMY@@?Lkܹ?hIcpmC* }#?c]woqnuVp.@략F%3tW4۸8q[c&k7`8ʣ*Iv5iĦQi¹4N50H+}'ToB)$05'ÌE9b[啢[7}?ZX+=Zn$*89mKr0@[汷nsKmojӈY6`~]BIe?tsTq6Gka\4m %ضZڧceh$HqE9][V`6 UTf\r_[8rџKe4Kg"I_X$)Ob7vV`pj|öHcEl-S^f8.Ny2FώsO{XNGᦸp-#}iKNsSkߴ!~Wc[JO8ؓ,ʯ!Q]OL&r@3t_hXq͸M<u'4h8ir2OJpb;.0=A?T=IO;,}D8pGZGΟm\{ȓ²68iub2^mc]ޟ$Z/m'S!\ĜopC.QZ:mV(hI)V?T0$fbay(IךiKr;WV{m3׽I}1R$K⺈?llb1LOI׷o9V26p2y涚c-#tbRoSxL.c1f(6H<[@DrJmwmGԧZ{ҡm+^<@)'FSq@GH.##T|!v6H@PO5$Bg|)gi$dǭLC qLfK~xb\ǭYUdT֜cu3ĺi7<mVՄhˌoە:䃹H93kJ&i ֣dd\R3r0zԡ\ZrsԞ%1/Ogc*[,q#UJjҶXX\MUMifӂL}*1Y%<_ʧ:K$c橻yϙ0wbgԭqwp2qTaH4iTY[{Rn,X;Nz-7իqo[%wqƪ^ZGkF4õV@ZWi{ȃN6˦`5W&66'P1]`X5W8J\\9ݭ.W^z*y<?Zurh"9ֺYfUș.+#Saf-ԒxIq"D"c_\UxdO/ێ1P;H<b,+&C/Fe)!zBDR~U5RrP'JZVDvjNcs@*?.}J4 lwcobhXLdsU%HKUMCt6rpVsJ&EmHU3#gg.##V?(_#zU4bylni!$xYSֶ$2SQ\cG!jp}i?ؓPhq]#}ø˺hx|)ѲʶDonZAx@< HNkCj2Ilnj8_Md=EjK?:($Eb$O/21ګcgO;nA'U'FXm$ǡ*)U3"bd1,J*xǸu38ͷ1֔SY9a@s'L[j!|rЯm<w[o֦W^"A\ De)-x9isKX[n}*չvZ{N]9v4NzǦi$ޥPxڣ\ s[3祟BuftSRDڞ)_jFoS]Oj;@]*9uՎ(^|Ota[(3r1s^4WoqX֩enܽޭOlDgaUX2yxun8\۴G$-lpקX6֛uPKnS^d(cYy1#G?ŇI02;ȿN*he洍ɇf?sv9QҶѯ-\PɜO8\fH؞@=j&uzҩV^c$JMs/K®ؼi`bKmV+sȕ.TcbCuoE%m6E2tD#i&+C笵\̤ү9.Rekq66w18ܬ̲3[HcF<-SiinjCm<T?hȸI4ە\ta'Fά6ͼ~9I?o%M"Bw{V弹x✷Nmm!{V|ɛOWLji"$dK*dHۤrITxdlgm_F}52Ō`UoDjI$֥6Q%ACY8cmbS?'!|0\=zW'TsQ?BjMI?\{!$jm445$td@+c6<_b!cʆ 8{Le$Xck@G.,&I؆ Ij4zTD<#nԪ\Ϸ:jMlgP6eq]s&Ar'V' V"Sح8y]2ު\vL``|jIoq*PJcI{loAZr:~8c?Rq-2io6@''i[:92EnXg׸u+X⦑,G.=AKobEݰ?|,AkG*,QrZai+?ZճD՞BCxAt=ɣ{NK{ۉdoШǿOֆPba8~I^[GaEcOXp'^߄2ڴiףqaS?~^N8gcV+?Ռc1c9ǩ)u232U;Q֕&h$ٓ=qmfS$m#slF1۞ףFZҥ\_)vwgkd?x8&U6]O;sl.Ӎ yra@a?:\0tW-#|s SԮ`Wz֖}ԬmvevMXD!0f/sQLH$YdQZՒ[&G?R|*"1֪/`4uI0~EֲtN=WFraR F*rBUw/$ךgLۢz(ױom)FX-t*2䈋}`yqr=E6%s]:#A*9gqhW銐#=UImde\T-OѶ2n$&I8mB.$Fx_f5˕jMoHwֆvlһunR6F#`?M9`sWu\dnRifd8,֗"uq215?uX{InϮkC;ԃVӣmy3/1FSi\rBJQD8`z#,)եt+|+*{Tb~iOs+N<R4'qYGO:n%ǭjn #"BVJFdq.qڠo!pv5XIP%*C#P.6ql^y~LƶmHӂʫsguwQ+`ըU'1t#[/Eȋ*Q毢.x(U\De;sjeMʦ`+bnF<u'54NEYb]5faU9km\g=TsjNRB0skH$ԧjGA'&5T<}N1R3DˍZً]n6*[#+"ZҮEkk2Fg{v#3W4!AaVbǵ[1v3W-q[ZWocqoQ]kҊ?巸FiL*4+'<b0H$:ը=g {c5k NbN1M0#ynrJicoɞFhnJ#=;)IvO5d(q瘅=W?K@gX( LC#*F/̇f,VE@Z"?-on!G<lȕ,a<Yb;Z[1$FN3zЫ0PlB dPzsֶ!/4gwz 5v6'`FUr$;sm3(9SSc9ay:%#慝Ļ<n?5 qZVf\2`mɸe?2K)#&2¶/p*GUQWp^;UShH8j)t?ТmbuBxD-Gja:Z=OQE\1l|sI 5:-ʹ;,;tvQСRyT@6A*;(R+ItbHO#9TBmG6[嫕g`@_ʉ[m!^uEԞ8O"QS*J}^T-ɕYI֝ճs;0frjA1;6tvH7aRBUbֳoQ<:nH?-D,66;Zks$}*ש=sJ38,[5"W)!T#a$Rq31MG~1Sܼr~RNcɠ=:NM`1џ=%UKֵEʣ$9LoWx=;WS[ksSDY_,e;+&e3ǴZ:M_j'v.Q+!碑؃޴Cg¹d,kbܫ[?J{U.|35sI,3Z4J%9$0$_TŮs{0\/'.b)Q"͈-$GVbH2KsNWd`E}2Saʑ4iXdVn=Mj$?ᡖQy?J}Χ?c`-?O%GRJ(ŽNzzZ޺mP%T.~q<2GavȘfsV⅔,jG8O2y;WM2`cjgs4vmI"Z*=ܧvF{⠙0UUpmLK&3`7SIe0}DyOe&!<*$'vQ"2NFxۚՓ%U@/ʊV.ux"PV@v53˄2ܤ?osJ%Q8j+"Yqgjі(D+JB1[1ASVspȡJdhLlu돭OOtbZ򂎀NX(CcqilA+´hqj?U-Ag`:%}z{T.C/j)O:qTjθbÖBÐ9PIh32+B[X#QLҬHn]i,k4lF0ГK qqIHOnnj$Ͼ{V6Y`9RGN?t}\1dzНb22*ꪪ]K,?ЎԨ:A[{Ȕp|Z71,~Q)BU3.vv3L"\x#82YafE0,1ڧ?fr|.q֨KwѼ_R9u'1c?LO"JcBo|qZq?ʀ[!by@Uqۚ$f4)eHtSW)#a:є^ӏ)jf}r2Tk9@ 2䜨_V8ɆX+4Tp~5IVbR8NYhp*樾Tqg] z*+[$rU9$"_&AKXU8$gZ$i3?k˗^HUbHԲb#¢H`*xҷ-+m`pJzZ=6ԡ2Q$F0OTa]LRA0|UY}Wjl@XUrR?_e Wьwk$K?F$`sqR2AT2Ï®,c',7mb)rjlʱl8ɭr̓#ΉO"0#}̅aem[rjc$^-LUrIC=x4$'e}?XОpZ5_+A+V`rQ8NL2?G8v5GŬV2pYFT9`lLAA㷥<ܦҵ%ҡpdsG呌dj]['TnU9P4&qЅlesZlEg }*q|ՕL*3T/[d!K|p=kS;D͔6.OP8qLp+)*qmpVL3p~۬zF^͖hnbs%+NwsU+UVQ4Vo{Tek=­XceYTn˸{jC֠K$3aU]<RFG5PLF0cu5fu=?۹6GiKpequ4^bc͋Q)DvV]4؜qAZ֖?БmA߷g+&?QZͺvBvAg9ۜ¯͇1q&sUMmm$ 8\1W?lܕ?u歡pPcpH]VIl-NhN89ޕ滊FI#$/O̬ȑ8Wo*E9.0q݃Ƶԧ88O2W7h@ǵRRSO̱%R {Zɾ1|Sŏ[tmqn"_/啛APc&ĎjNS֧K5sOAWޛJ851ޯ6C^U׆é01?sVgC d2*eޕb҅t#xlgڮ*yc;՟Kxc9c BKR?W'"?2L|_ުj2\Zс._֬(۾K&Ng8vgUdW=edBϥh&V?tPJ.7+x-ݴ|oqp &+r%?)e;xvL~R/XpÞvk푩,jUm϶!Zԭc/'cj&dr$"1$qqDac 85L;ŷ0h<T(Si,k r3ҭa8s=[Z֤EpG:#څVHmrI3YiIgLRh`8zV;¸p$xHA<RyTf?dR$Z@VbJڶ0՟Эl*rCq!)&4Xq%nUgpсQʿhѡ;ŕ.?VDf;7j+#o@0d~5E7}g)$L:#?:{nb1b9RH0##_I<dْ"yhMe;]ޘYDk'+=XԷF%ʜNԖSCH={X4m2[0sZ6ZH'CUӞ;bva(;-_Oj#'&եIocW2`:u'}hH(v,g)W唰wҶG֭vqNpg28ar?V'apG|6HfW#l͵vuQ@?,3`v.)s(Kqwlccﯖك 1s^K#sVAxd+2is`0C.*[#֡ħ޶u]&89S%P~S6fծ/d,0T3,215cnOj]6eEÜֽSߤ\$k`2ڪ*_K]]L,{|wFrN+ܰ|ηࣲtȗMcrlw=1¬-\2 x<zCq-)A/=?UF7nNyǣ#heo|vqZW6h(2i.4i+08I?$%+,ڽAZ\˖˺iON$(rJVѯv'osqqG,MЫwȶ(互C;.9S.s= |nxWU%#9lf/k{eȭ/kHcIZ5=9ny#5<vڄۙp;޵3gX+*sbY4gqkB}6qʢ<r3^WY!m]dssVc;w{J;pj(<'N dִ7seO4Tَ*/5l`Ҭ4n?RZ7%K V}lZnm 8B*4ıXm=ON/ke+(r~7c<6hJڟM3ZIm~\`VL<giiPw7,77ִԛ]rR6Y;ONQ*\ǥfZj2NNpѱ;Jl6(nm̃bP^k[Ђ!$$skǙe89Lq0zִ\y*~d}L%ep<AVGpAqק%[%QhVc$JzU?hԆp@֭}U)Y.\-ދȚ8m:h&Ӯy2(+32{犤O)L˓oO\i;< (F*9Є`kc%ȲKD+66{~x[%XèɪĐP-1V<dkuR9w9+ޡbHo2?Lm@楸v"6 AnjJh֯+"9O֨@$@O)#s:c"oZר<v,Oj;M,qDXg__a,P7n&@8Pk-{ :ȷDv{snXGjv$^TIc3;ws"y@?i[-Ԍ41z}+ddѥr\u16CVa`eHђdfB@V홫%vƵyrr}*-3<"Tqn%ׇmi+FyH\p--eS~<0SLuZmy%=aQZ\ApLJ=wjHJPsNEtVŹč[`ڶﮯe2OҺ#/^Z@)<IgȐ\$SRv?/wm۸̪οjf%2v#6xlv eXi3iXMP6+Oyr[eԏwiK*w֨ϫM)hV37C]wzɸg%TE%q_hysdvV1m'n['8UPr#nveǸ\{U;fsUpҧӦّQ$cmͪ<m"<砭sѫsX٥Ŵu(A*,ICi%D*ˁ}7$!"M$O~kf`?Ac$QYNtVgӽt4BG$w4W#ɛßQ$)k#^ylmԿu1Ky*0P{TQ7vJ0:͂FQ9u֮bF,1k{:wG(KmajoJ:쪣ݻҡԵ"cI$ζ9Tt?֢ASޡ"lÞ0AYu"e}ĚOz=d#XS.׊y}u-b;]/Y-f$s4#67kr"UْQЩuuoqϕ\#BZI*B0r?DVTHsۨSxzIѩchyiO3pqI y9TD#5$̶fX)ѤCi{If_*?,.Q';y^ʅ$/yrqYō+ZT[r{hŸY#;P:dgXœnɭE"ĉCH9"KO6XAJ}vd(evkFW9<a}F(=3Kaj6 173 //Xʻ_Az!p|Ojn1bOK{|in$iIUC*d6zY֬5(,aKy)cݽ}}*#5$%snHM¹IUɟ5jש7exV"l@eo=j/~Xq.4ۉfx8)7gЧSpHcH'KyI:57뫣ĥ9G&tkkDZs3v[DMH]3A9m#yϴ-HT8,$duͶ[xv|:Z#ҕ9mdhċnz!OkdN?wZ6{$DχSEvP^vD/mcӇLw(v3HF<%FAV*Ey{=8)P}o:Hrr&V2JԨt614UW?Ee,#ZMfC&-ZTI Oȭ.Eժ`NrÀÊ)Y8aQT{f2@2lGI,cyRVsjOXʎsB(%nszң2CF9Z&ɒMl. yNx*g7v'Ve-tPr{wm&%yV(zGo{Ɉ@XF&InzGtD,{FjҪ[O2SsV{FǮN3Iѣmss8?F@Q73Ob+\Axe~R2)Jrns[[&VU@@p.[X(@&2#uj5@v۴qV9gAc'F\f%g8?ZS)fIkqr!Xknn3ǥosOm+${[=Ai0H +F}roQ$#}IJ8ʥֶ9uX-4m?R"R7ǵN֑C|L`9楹w;#ֶM[I)ةJ[MȬ#*F6SA!q@Y2YLo&.<BdVGׯ#r6O#-Ҩ1;ONݨ50?f\ĥdUi2:dW;oBʤOZԛ Qר;ʳlʞGҐ=2znUn-c)ɑ[|79=)w?fG"IySWBqj$7Ojt_$HUݳ=xṳ̊<Uh$2R.?4dLjp$Vυ]|9Fߘpk^f/cl1@VL';ONƭz*!;bԤ{⯦cs~UMȏ˻RX'˓Aެc ((]\wJ4//$jHFnK@)k:[{$+$;,!h*G3iq;mv#jeG%X2kn;yl|֫=fW9SDpr6ӚI.DŖ($ڬzT}o,A"H*Aqrճ%ү=;IʬbR]ǧҰ{dKhrGqjwvR}=+D\Z?dG}V@qY3ډh#ZiZ"͐O$rpj\EsnAH`ǥks-c.FjPEw&c3=@[A";UiO lbXV\J߹KmqqP|\(8嬌qKs#EH+pqڶf)|07G=*B#g55pꧽ4 ɉթcׂ5Wf98n)UNc"9uҦ1\`ZМ I<qڜЉ`9'qҪ!af3 $vRſ[ûlkFԑѴg` vně8npqNDHf]g)qlnɵs҃i2oFS1U[ޟZ4ލ}HڛG`x};sZӦ׬ҷQX};AKoe !c'ҟ,Wy,yNZ8TJ@mE Pҗ#'l*Ki,灍NGb1׵"1?<g}j_,-s[\^#MlY_فUwvۯ <_/#hA5t@a@vns6U-v/jOä۬n%梐~mZkXeM9fdD H%Xlas,5ORqmoc*:w-n,UP0MIť+MdU:)"H\T s[cew7\@⤷[u$=NY!Jt,K=1<S߭~\kkk}VMord:6tLHf:HVbFfqb]NjKine&LfXc.bҫFZE,3b,hXpqME$H?gMmhbJQhʾD|'Lfaw]&F:f*ZL35e{ԫk,~T\עGmF&9u$S$LB[61Qgpf'W?v4L7sҙ6䔀^3EHϙ!6Tp03*mI10Yc"r8Rs,QGPk&̻@U9MQF'ks!00i7bOAT7?,fxi@[oN? Uܖ_.Xǖ10_UL-<JCUhVcFãsZ"9$$Zw杧99zUHg_V_h99ҶPK;Lc'8j,q)qT;Ͳv<g{V57v/PiLgٗMi8#,3ū2,F|g֠եd61dvmzՑ,Xo<t6y_ήf9bXqE֮;'8=c(Ӗ(p?vUO7v$׬-(];iVlbr5)9bt'$تЭ(O@)U<Sq=13zgEPѦɌvuVpxwȻZrx,p?ҭkEdF6faԗLmM۳%A΀:PEWݪ#ӎU-Ud'rH69uN6@Yʫmoڌh[+1efZz-#U+;j}jyo)c}rWqMەVȮby‡,)wFvիlnuZlď eۿvobLeYݦ˩=ZȮh֛?֮G0Iq|i+5;dU|k.vFP̅%jƈ[wC4ס@"Md"evoT,^Mb*ֻ5*WuP]3DCh5gЭiܑW2<rsUVvI%ī+4@a2M::mmu%!M^D_wĈ-P0547v"640~d[N}wkQdR]WnkFs}F;h팖.YS,}|ϯRm$I<*aݷաӨo-\!f-"UK"a6?OF*/_q,s[9ܢD+KjaT5.(w!hֱ%ϔ0RD⨵ǖU_gZ˖$js_юfP\R;a}sS;'ҙ]2?.kS֣rAau/bAGfU7i0|zT(}\jFwsB*x!~V1"0=Ҧ[WOY$Ԍ!b߿)0@٦E!a,vz"Emz Y,- aX}N&PQycdX`U]Fm颛CE]l硹ȃ.<uF#5PcQX-;dk):<;ӱw(;S O)ctrIbFBhT#SNCbuN͈3UEQG]O1#5;K`tؽĦ"߻?SMxW#TcpR8=jJ[v-tN$T҂.66nNSVƛeeɆIFa,03i3H<yL0F~@P63,_I!%r1ڕY<w9%pF}*ʼnH7vƤNB(〱юa7_41d~،DFIevոB9a28$#YOF\犑b:U`bP}ҁ\Ӕ)g- ڧ#+wZs)2Fp8UԽ+"wi"!qL:iBFG՜l,7GDZⷍUd [pO?LTjY㵵߼@ֹ5\̴\n5({RfGZt(WW׺րϕ4g˓w͵J[mګ/Z՗j߻iq#sDJg7fyE"l̿*n_ի+l۩тh!I/ۈLﻇ۹F+h˫˂Y~UM/q+?(YvbWC̾ogYԦHn-?a`սsaja<aBevPˡZFȲ˵knSj|ÎcH$yԑb'ʣn֫)X%RJUi-ޟk_] Yb2D7vw27K*5ݳ`(?5d1,xhn[Z54/$I%m_x@oZ͎v˵]աg{*?+&߻S4ōJTUo/V{K}(WwZ֋v*"{ڦQ6<D|ZJ-׭w-ż+x·Ϸn֬і#+_UmF}J2c~D]AmVR?Ч"Xkۿuo.Ւ=p5PX.F1{rN]JOrOVd\M~^-wCQPjwQ{wZ%%!zӉLQJoibiD\sP]n[1SÑtӮ&򜲹'#B:sVYk;w(CTTH(cF<B*V+<a85f]=GnNn~-m{(f0F=}*9ʨ.XdwM;1`+eJnmHsZ\'Ҋ?Ergx}(]TE*4<29g^X+rw*TpFڤELBpgջX|\I9S[k͟R,0:$(ɟ*m!i~y([XYq4ҡ ؗlLE[moX7?@ͺ5H5&#bڬpOif8j#^(ԫurE219tm<uzOC֛Cխo{(i(-֦*Bgu֎dy 2Atq9АH9(W~"Ja7g!%⡔oIH\lI F;g@LL6bv;|3%221իYX.C'P1[bÐN긠LVA4aք=GQJQ4M)XNÇJ?ۻ{i;$*d*Xṙ6,$d\R-])Դl@׻ p+ܤI2r=Nw":n~UG"\Fkmv7?ՔBrQu<}ZgfgF["\.WvGօ3bP7T"܏%/߼Ņ%$eMrǷմ&Ny|-u"[˝F?5+\,|~*{^EEIxO$fѾ_Zo=nI4{Y76Iz,لi[8t,OU/4PuH[*l7kUuKE/(#˻+7i72eITeX/nSZRg-;Y:}Ziڪmۛ}Iђk/rl!W9eQծ䕀pe*Zɐʳ.~_YYDIh#dR˷n/Tgң{6ݷɹC.uUav)?efY|UVeT1lH^2,եctFҙq6|o~EjAݕ!7ݪ9ʹ3Ÿ|˚5`7C+V-rc[Gqrm6֭TQ@rkS%|nڻ~j'գ&-5cbkGWO2ӦkؠS͑_zUDȮͿͶ2{ި#7q'VW[?$EǑwnqt1\mZlҨϸCq6,5r!qH#mV1,ǜ)=6-!7VQW?伩Q`N8[\(e^I<昧wMj0,sJc n$.Iy122?i%ILkus[|*Y=1ީL08EM1EQ?7kF9$g5jkv+B?Ze0_}ic&Y$T#խq ۸WgYؽDB ccϻsy')BaB?֧̹MH=٥E'8w27ZfFsvT'm%0?קdއ<Cg9E6J<Uô'*sЯoneMAO<UBybiw`I(љB$TQ%N%ךG7Uҟt\HϿQyn)%x'fhEPӑ@ӷcP4G#BZU2Kͷ'B?ԭ+8RpM,i==O&T$s"(V6A._w@'`ӐJ1NTQ,jFPzQSПW?ֺci#wd9+VL8YcPygoxҋGb0wc%zP$аy+$ɸST fB]Z?w;A'{C0@пݪо#s]3uVUP[ED]~\ҒH&QsS&xP̬HO#P|ҕ,($T7ԁ4ɯ+v5FݹjZZ^.;}LnfVQ .R'SDVK퀫g?z\ԯ}П+ʑVo5n.ԍVIjvl,ͻj2yQJK٬}~X.l|&5͵ķ'MڈUFՕAjڕ&(eWyr7,~]eglF<PJddڳGT6 hm.eYrֆ}wQ-1H*3H&mS:Ʊ $fuUu$7ݿ6)T3;Swme`|/Qp;Kc,:mmӱ/̽6PnzoGjü$yJn;"VX0`߽-Ij.1+'KDڛeUr!}_uF7:S,eR-\.RDػ|-3ɴđjj/nHܧ'WgŻg/ˏ6Iyp`pfLOUbu&G@v։\˙S&\Dd<jke0<Z"6 p`Z+K΢)FR$u!$o,jKyz8ic.kkjpί/p:ZKdiX<`3PTH?Ī%.ZU$"*Ҵ۟Eep1P,oڼa④N~UsTȢu_(̝$"VkDߵVR?O#`ۂǽQ'Ң8<Xrc$T@%R=< cmBUӯnufUvOt?<c\g=EF3vԅy8/J"A^e3֞p*qĤ9,@0g'A`qTIG;402s϶)<RH1 xڨG׮4JKms]{S%j&I{*$ĻN6ЭȪtmĭ.::VnȆ)$pȖ(XN\cwGѯo)8W6(R&1Tvlfi| q\ҲtEJE/]4#8W8Ӻ%W;܏Ң.eiNiI{PWԙPU99V@*Ty:vAi" XP+Պ,t<ŕQWj8[¿nėa"j{kV"H_[Dּ,8]mݺT{NIfXyKTOLvGI$l7}ݿzKF̸ֲܻh0ÓGޫ`Iq,cncڵ6`ҕճ)m՝+RomcwW/y(ahaDz)]vLѽYrDG.݈+nX~#772#!]jѵ/iWV\˶[qm?h2G~oOb"2?<!+$wj҈madݹ[vv<&_Qࣧ:ޥQ}ݶ<q+FTrLüд;V/~Z[M6ۉSܼ|/#Iv^/ӻ5"3X*~~fjbG%oYT?w3A|6T7pǗ5?ˑ(,ޠ-I:2cnܵ6ݲ.}jg9ti(*PEye3n*mݤZHcnMM0?g:D`rZ3~<}*tXڭ5e|ҝ.T5:d&#*l4N(V}'+qYI|k[;<#*M*!Cz"8 JI20*h6?uF'iH\giR-h#Uavԓ7[\V?{T#N,!@mqPsMGp9kZ<?E$֤b߸*%I2=1<[r#s*׮\|bB|͞{fLwЃie.HPUjOTLyW*Q7?d@)~^RQ6_%qh9GQ'ҏjG'Qw9ߕ^9i3ݰ}hӭ#+|Pj:Ayeb<r =i#LPbC2KpqQ8/+JؗxJb?Մ~Xݩ( w`q$_ިGb,c%CtWbPPsj(riA@ATI״LxۏLEH)d?LS1n@Вa2mXg-ˋi b|YWQ:т[cUWy<Tk0bFU%TuVtbB0s̖i˾3wݻj&8nڦ/VI_sӊVKYp?6ӷUxuH.&#fxx..)t]NI_hFsu\lk['lSk2{wjGgX\)5VFX*Vݖ5=֦)3̻.`3U۔YVr<vכi WSxY8ؿ2Tgǹt8?kHs%B/ݭKk$ͳBmîUbҤa*ۿ%5tƵF@5F4u[-$`o۟_jH'anP;]+OGyiofa [fa7e**~ZO2%ƀ͹|"NBw|LxaiYvߗˋA(*_"eyI !r.iŋWe͎B+3H86է<N#Ē]!Oum۩GFMKwPQJ|7ޫ2+۴(]ۿwTDq-OɐGVi\ڶ-7ys9ge-THag&02Ҹ֧ NP0$=ꤲGZƹ9-BA@qס|0vdJ-&,3dJjlR%c'gձ#Zxb@#'ٜ;hWy2Eyc`5pA)CD~n硩VӪrUJ=vq"d.ZM䓞ԫ}ji_a^QP+ycMknDծ|*QBLuUb^%Q*cpOjS,})X`0I@?1(נr;񨧕p\[g\|ƛՃzФv|H*{ԫ$B鹘`s֨b<Iga#*#wPl%1F*tYJy\OV9RCH'5ȲI$@?O*?,C, fSzV5jݏʸL@nLc.GqYB{ܜ=惝S9o/',9s+8vPCr0GB@H[Pk=BJuOSoՇӴ$?Zuh%EEFVHZЩ4i c6;Uh̒}uZXclҲ5X 1۷h΢Е-/$:HRH^=/?z]nxEIZNrv3lp]+#ti7-)@j|;,*a1 e-4Y~]m՝}tWݧe)+HD#jg˻wv8#iY`@Di$-0ܟ6()UcnԥAp;K_kB+;i Ffn[W6a+Uإxb$~rva`,,ʊLq?͵WnښE2FP:yeQ\G?X0/coy_/mwe?gO#!(GD%o_GץlB控OIY8M{s5rR7U+T3#Eļi.᭐ݺ\IַA0jX«LjSf#.VѥRJvަЧ˜j3)ȟ:yh|O~lna1oL0LHKv|UUr.+:J)e+rE%ƶխR<Uۭb0zW0lT,Ar}(2E'ʌWʌ?EOpsRCG{0:Me`A#}2@Tid`φ.Ily~䜉$^W5P%T_L\TNYMcy#֤af@;P`CXh#ON(JǮR׃2ET߭Щ}GJڼA7p,)0UѢ@ 1$o;T#M(ϰNp#'ujӭ25q۞06O#Ҕ6wqԦܕ;:rE1wV79vէ?E:kĎ(wlq|Q.O$T#ւw*<qPZ'Q'I8Y{;`܌P#ЭqauN=zZesҢ*JޑO+ѧ3cnbBX'z65V)oMR#c(NA4XN-aK.$ݎ^B.lUVެ{|EQG|҂8bH-DG\mOzV*34|AĽ|a{e\C8+F=}묁6[SQO]M(piLg29:WppM~lH+.—0JI'%'mMnI4G'F$ ^*5@'iȪ!ֵD/1;VEP<oI+zjy?hSPqW=)%XS֔6ҍf?(+HSf1v;pszYAv1h 174 //p3fY[eE|lch}kK3ҡMK{1;#ZY'ՊY8$i#ӡ-A#gzUE/e;7P9}jż pCg$gdԭ`Ic'PS0ܖQ޳nf9Xs,.!+jի,Y[:*5"RGbjb\%64@,G9*@֢w4%#4_Lҩ,@rRƹyz?kq(#mlX1*Vs!ׂrsޤǟOU-%l<8RfG$SʓKQY͊GjXmbjfLo"אjoqc5!c$##R1URԁχJ=YZBR@v#'Jn`g5ԡxS.`Ahƀ٩8UGҊ*Р9EѠ4<iǵUҭv/cEDӫ#ja&EB?Ԫ|LZ3(խ#cNX#< (֭,i"ⰵXڤE"YGbWaj͝F%7c(3eu%MGl?ѧo#˰iǥPn#04摬fx+?}1d慂/E] yQIB?ԩAFe{9n8a1QW?ա多PF;AO3QM@B5-"G~QZDGQ,Vtp?Ƒ9椑(?Ow<w T=h̏Ǡ$f*@<ǭg dUqELԠ|A<sHGգ!5ZGo<ryE?֣4[; _ƒ(EOh➌Dh f( 175 // 176 --> 177 </script> 178 <script language = "Javascript"> 179 date = new Date(); 180 endTime=date.getTime(); 181 calcThroughput(); 182 alert(textMessage); 183 window.location.reload(true); 184 </script> 185 <% 186 } 187 %> 188 </HEAD></HTML>

Listing Three - selectPlayer.jsp

001 <%@ page import="PlayerDataObject"%> 002 <% 003 // selectPlayer.jsp 004 // Displays an HTML form that lets users pick their favorite media player 005 006 boolean hasReal=false, hasWMP=false, hasQT=false; 007 008 // check for cookie 009 String theCookieVal=null; 010 Cookie[] cookies = request.getCookies(); 011 for(int i=0;i<cookies.length;i++){ 012 if(cookies[i].getName().equals("MediaPlayers")){ 013 theCookieVal = cookies[i].getValue(); 014 } 015 } 016 //this condition should never happen 017 018 if ( theCookieVal == null ) { 019 %> 020 <jsp:forward page="detectPlugin.jsp"/> 021 <% 022 } 023 024 if ( theCookieVal.indexOf(PlayerDataObject.REAL_TYPE) != -1 ) { 025 hasReal=true; 026 } 027 if ( theCookieVal.indexOf(PlayerDataObject.WMP_TYPE) != -1 ) { 028 hasWMP=true; 029 } 030 if ( theCookieVal.indexOf(PlayerDataObject.QT_TYPE) != -1 ) { 031 hasQT=true; 032 } 033 %> 034 035 <HTML><HEAD><TITLE>Select your preferred media player</TITLE> 036 037 <SCRIPT Language="javascript"> 038 function processForm(form){ 039 var prefString=""; 040 for ( i=0; i<form.playerPref.length; i++ ) { 041 prefString += (form.playerPref[i].checked ? form.playerPref[i].value : ""); 042 } 043 setCookie("MediaPlayerPref", prefString); 044 } 045 046 function setCookie(name, value){ 047 var expires = new Date(); 048 expires.setTime((new Date().getTime() + 1000*60*60*24*365)); 049 document.cookie = name + "=" + escape(value) + ((expires==null ? "":(";expires=" + expires.toGMTString()))); 050 } 051 </script> 052 053 </HEAD> 054 <BODY> 055 <h4>Choose your preferred media player</h4> 056 <FORM METHOD="POST" onSubmit="processForm(this)"> 057 <TABLE CELLPADDING=4> 058 <% if(hasReal){ %> 059 <TR><TD>RealPlayer </TD><TD><INPUT TYPE=radio NAME="playerPref" VALUE=<%= PlayerDataObject.REAL_TYPE %>></TD></TR> 060 <% } %> 061 <% if(hasWMP){ %> 062 <TR><TD>WindowMedia Player </TD><TD><INPUT TYPE=radio NAME="playerPref" VALUE=<%= PlayerDataObject.WMP_TYPE %>></TD></TR> 063 <% } %> 064 <% if(hasQT){ %> 065 <TR><TD>QuickTime </TD><TD><INPUT TYPE=radio NAME="playerPref" VALUE=<%= PlayerDataObject.QT_TYPE %>></TD></TR> 066 <% } %> 067 <TR><TD COLSPAN="2"><INPUT TYPE="submit" VALUE="Select Player"></TD></TR> 068 </TABLE> 069 </FORM> 070 Your connection type appears to be <B><%= session.getValue("ConnectionType") %></B> 071 </BODY></HTML> 㯥[L3F2ŔWOhy2Il}Mg|F0™@?iǃkK.*omF'r87<NktIv*AG#'}w4YܲG.)uv;<v+?.)~8:D3ס1N.+?NNhѡ\Slң;,ӣ1IE/75^Pl8ŠVճ9ԣ)1T[SҶz{` Jgա\VMLHj\ŭH:}R֣LV$R%Hחyy$Ѽu+7*u?ʞ`|8;ʟpFI{6,/s4^]h@jٿCϧSWXPWDFNjFFOZo.(6.K2Mm,^Xr?v7y=LUᢊeZ9I?Ú`0obOeXúvQؚgvL- jkrO򋋙&U栢Г:h#(hڧ82hL(uNvLⴐB