src/js/utils.js
author veltr
Mon, 19 Mar 2012 18:46:17 +0100
branchpopcorn-port
changeset 834 573c7ca752e0
parent 830 18ca612e9ff0
child 835 a8af9da7c622
permissions -rw-r--r--
Adapted Stackgraph for Cinecast

/* utils.js - various utils that don't belong anywhere else */

/* trace function, for debugging */

IriSP.traceNum = 0;
IriSP.trace = function( msg, value ) {
/*
	if( IriSP.config.gui.debug === true ) {
		IriSP.traceNum += 1;
		IriSP.jQuery( "<div>"+IriSP.traceNum+" - "+msg+" : "+value+"</div>" ).appendTo( "#Ldt-output" );
	}
*/
};

/* used in callbacks - because in callbacks we lose "this",
   we need to have a special function which wraps "this" in 
   a closure. This way, the 
*/   
IriSP.wrap = function (obj, fn) {
  return function() {    
    var args = Array.prototype.slice.call(arguments, 0);
    return fn.apply(obj, args);
  }
}

/* convert a time to a percentage in the media */
IriSP.timeToPourcent = function(time, timetotal){
	var time = Math.abs(time);
  var timetotal = Math.abs(timetotal);
  
	return Math.floor((time/timetotal) * 100);
};

IriSP.padWithZeros = function(num) {
  if (Math.abs(num) < 10) {
    return "0" + num.toString();
  } else {
    return num.toString();
  }
};

/* convert a number of milliseconds to a tuple of the form 
   [hours, minutes, seconds]
*/
IriSP.msToTime = function(ms) {
  return IriSP.secondsToTime(ms / 1000);
}
/* convert a number of seconds to a tuple of the form 
   [hours, minutes, seconds]
*/
IriSP.secondsToTime = function(secs) {  
  var hours = Math.abs(parseInt( secs / 3600 ) % 24);
  var minutes = Math.abs(parseInt( secs / 60 ) % 60);
  var seconds = parseFloat(Math.abs(secs % 60).toFixed(0));
  
  var toString_fn = function() {
    var ret = "";
    if (hours > 0)
       ret = IriSP.padWithZeros(this.hours) + ":";
    ret += IriSP.padWithZeros(this.minutes) + ":" + IriSP.padWithZeros(this.seconds);

    return ret;
  }
  return {"hours" : hours, "minutes" : minutes, "seconds" : seconds, toString: toString_fn};
};

/* format a tweet - replaces @name by a link to the profile, #hashtag, etc. */
IriSP.formatTweet = function(tweet) {
  /*
    an array of arrays which hold a regexp and its replacement.
  */
  var regExps = [
    /* copied from http://codegolf.stackexchange.com/questions/464/shortest-url-regex-match-in-javascript/480#480 */
    [/((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)/gi, "<a href='$1'>$1</a>"],
    [/@(\w+)/gi, "<a href='http://twitter.com/$1'>@$1</a>"], // matches a @handle
    [/#(\w+)/gi, "<a href='http://twitter.com/search?q=%23$1'>#$1</a>"],// matches a hashtag
    [/(\+\+)/gi, "<span class='Ldt-PolemicPlusPlus'>$1</span>"],
    [/(--)/gi, "<span class='Ldt-PolemicMinusMinus'>$1</span>"],
    [/(==)/gi, "<span class='Ldt-PolemicEqualEqual'>$1</span>"],
    [/(\?\?)/gi, "<span class='Ldt-PolemicQuestion'>$1</span>"]
  ]; 

  var i = 0;
  for(i = 0; i < regExps.length; i++) {
     tweet = tweet.replace(regExps[i][0], regExps[i][1]);
  }
  
  return tweet;
};

IriSP.countProperties = function(obj) {
    var count = 0;

    for(var prop in obj) {
        if(obj.hasOwnProperty(prop))
                ++count;
    }

    return count;
};

// conversion de couleur Decimal vers HexaDecimal || 000 si fff
IriSP.DEC_HEXA_COLOR = function (dec) {
  var val = +dec;
  var str = val.toString(16);
  var zeroes = "";
  if (str.length < 6) {
    for (var i = 0; i < 6 - str.length; i++)
      zeroes += "0";
  }
  return zeroes + str;
};

/* shortcut to have global variables in templates */
IriSP.templToHTML = function(template, values) {
  var params = IriSP.jQuery.extend(IriSP.default_templates_vars, values);
  return Mustache.to_html(template, params);
};

/* we need to be stricter than encodeURIComponent,
   because of twitter
*/  
IriSP.encodeURI = function(str) {
  return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').  
                                 replace(/\)/g, '%29').replace(/\*/g, '%2A');  
}

IriSP.jqId = function (myid) { 
   return IriSP.jQuery('#' + myid.replace(/(:|\.)/g,'\\$1'));
 }  

IriSP.__guidCounter = 0;
IriSP.guid = function(prefix) {
  IriSP.__guidCounter += 1;
  return prefix + IriSP.__guidCounter;
};

/** returns an url to share on facebook */
IriSP.mkFbUrl = function(url, text) {
  if (typeof(text) === "undefined")
    text = "I'm watching ";
  
  return "http://www.facebook.com/share.php?u=" + IriSP.encodeURI(text) + IriSP.shorten_url(url);
};

/** returns an url to share on twitter */
IriSP.mkTweetUrl = function(url, text) {
  if (typeof(text) === "undefined")
    text = "I'm watching ";
  
  return "http://twitter.com/home?status=" + IriSP.encodeURI(text) + IriSP.shorten_url(url);
};

/** returns an url to share on google + */
IriSP.mkGplusUrl = function(url, text) {
  return "https://plusone.google.com/_/+1/confirm?hl=en&url=" + IriSP.shorten_url(url);
};

/** test if a value is null or undefined */
IriSP.null_or_undefined = function(val) {
  return (typeof(val) === "undefined" || val === null);
};

/** get a property that can have multiple names **/

IriSP.get_aliased = function(_obj, _aliases) {
    for (var _i = 0; _i < _aliases.length; _i++) {
        if (typeof _obj[_aliases[_i]] !== "undefined") {
            return _obj[_aliases[_i]];
        }
    }
    return null;
}

/** issue a call to an url shortener and return the shortened url */
IriSP.shorten_url = function(url) {
  if (IriSP.config.shortener.hasOwnProperty("shortening_function"))
    return IriSP.config.shortener.shortening_function(url);
    
  return url;
};

/** Similar to substr but remove the last word if
    we're breaking a word in two.
 */ 
IriSP.clean_substr = function(str, start, end) {
  var s = str.substr(start, end).substr(start, end).split(" ");
  s.pop();
  return s.join(" ");
};
/* for ie compatibility
if (Object.prototype.__defineGetter__&&!Object.defineProperty) {
   Object.defineProperty=function(obj,prop,desc) {
      if ("get" in desc) obj.__defineGetter__(prop,desc.get);
      if ("set" in desc) obj.__defineSetter__(prop,desc.set);
   }
}
*/

/* Creates regexps from text */
IriSP.regexpFromText = function(_text) {
    return new RegExp('(' + _text.replace(/(\W)/gim,'\\$1') + ')','gim');
}
Á)'# @;zaf; M$2Ov#idJX$fJb+ݩ,gd U3@! RifTKvdEFQE&{h4Da̺GQ*]bm$j9*Yc$lH߅hs,iU i=حW2&IƖAVtmsS&1-|&sxޙ4vCY N*wq8razEgTicEe\ŤJ2ZYi5iXC#aU)"8zNj=uJ]B>nZ;Ϯt=@wkZֵkΉG;{L0U1bc4Z8Jj'=uuy{n6$~ M! rKr0KU}nt%tfc.f%X$akhS]X.ܓ$@c- 6.)-+X)Z#oγC5*{\qXfadJZR抦cUԕ-^1w P}%jtqt9yKɤr~uݭkZ־?l)AwٙΪGb'*K|(_M~QmZ9$<3rOjW^K^ͪC^ q*p'"qyi{)'d| ^; wlƬ+VɚU Ԓm%I-ǿC333zsp8CޫֵZ]y=>g~RޔⲠ,E}(?bLE " G 7A8v61nwnj-P4ve5BTG0V#;HmƚT[P8Z${m@^]%Hpn5CUAGv[3ULMK FKh&@!`Kcdlӷ=* 4 zJ͡@4H4:j;T : ,2PRɲUS;miTvus]\y61U;jT=Q`˓5٭$I VL2d(("4 f ]qR AE) [0O @[4S"$*$P(J)PJ%<ƃdP TPQsـղ!"vk^ 9+C=%ݲ(M[a$cJ %@ E{zx$DBhҞbS&ChDF 21"STQ OD@p hш$JIDb4D~a1MFCDMMҞ!22h#CGQ" @`biMj~Liiba4iY=88 >QU_?tgQ?yIq/Ω"DyRW8 !cH_8vKVS i 5HhYZFDH0PhfAjV%qTW+e2٤eXd͙`-MLB6ֶ8cb}C U B5T4VDڔU,j5m,6)13L#fefdb&j#1Sj54YLʘ2bɫE&RSde%RȱY1Tm)1(Eơ fb(eUU2jMX-E IZZ̚[.kYmAƴK P`h-0#CdjSj&JP[(sm[Alډc\F,jI3fLVE&(Ld+m_uTJ3QFVh5zBԹ1\*? :( \< 0!tTώ7lXfmV/miɹJڣU۳hG%B >-T;iJOKɑ&TˡG jF/8w:B˻#-4JJ3.%a̹3-E3P(Tze<ҡ%U\,e #W:#'rr5Ve6)tT:q?o`.iԼR8%S3[_W*ZWQijִMi5 LҦKYᵙj)SEe'x.J-֊(ڍ\lVb˅ʸRLRYU+J±Z +ʟ=:{)~MSGXbF_{]5)|2xQgGad6;ߖNMؾ'|Dz%+q_AYKYUXpWPf|AQPѲg4TߩbC%>aqIYާ)@G$t\{ƒBjN)kJUhyl\>{%g_<nL5$$>*JB6+j- G+PTҊiMQcf4l5\i3=nw,<;(2;`1{0f#sL} (CrS w&Bq '\qf0@iu?= 'tx`R>TsZ&2V*W$ EJiqRI}(0흜ioId[w'wKyv+竂'm>} 6Fgb6HAA{s'r:o/~ * \P%ɝyAKZK c0fCDF* 2s)jU2=88:UWRg Qg@XgRk{[]Ƭn>AQd }E3۰'^(J:4Ĵ0/:8,/&U/ bd9Af?G*}P% 'ɶsߐ% K%O.X{Z2f bóx$!BJGR dR͎jLXv2Iv%Nz7?X"U{nd#O)[leKkW,Ix9x10!pd/s2y H_N&@3gńiBkJ2ATZa^ آ:-ةD<Ӈj vܚ?INxٝ3LJg#LI'X,46|%c&g%Jo\! y ]`I(u#i2sW|5 '#~m Be@ō!%if]M2iaI[rPiF1LBPKd$(@@ KrSIn7./3|v ڡ#"i׉l)>B @R2%Xj#4-&YBׅ1E(lBWI)G䣧s(-Zvs f3CաT֦MJx7 Ha#GQ\M\$21w%(쨿t0x ##B^ xB 1$"k8${-==$99dW%{Uxf&׈8A)nv/ *oR*]sL]|z&?p J)88#- ZCTSAX}j>Ul.6X_,1} sdpqɢ e\*0s_֦J :YNjg m?cwT5jIL'~Hz"^G>3!%WƴYv]ZGX;pUrK v41>5`RވycbG Ќ`ұbT[`9c6pH@#]#HUs#9)A@ԟ 6ޠ9Yj}p׹Vu9IFiE}N2#HB!Ic EpeM(Q ;4~CXZ83DB= 7ʡ+D=)6P E>sX8504p׸V7I1T^_M5r KG6 ]wfB̻gA+; ۄ{2Xi*B(h*?Yr~ `Xy|ϛ}N6ͯDΑ D<t%* ߛ<ڈ >O9<5$#lLުϭ )V&ǏWhZP#T?4\cmXc2j% "b'gcy%U{Hl(K$eAA%6 2LQ2mc[F}:0˫eJ0w7aɳe@B #ԊM\Lխ_]Ov+paQx.p@!K$TtҪJl|/MY=eQahf_d>l"i0($~nzã=%]VJ+bNtpV L @ƁH$VL-IU lYu%ouw*hfwi01RHAٱʪ4~/{M&uc&t BEh _Y^ x0DY.0yGȪkI̟X*DI"Ņc3\% XӘg23Ȍi)h) 5^֠a(Ӯ l$wƓx cqJhEOṡӴeX\g? ]:j`fx+d;+2$fbI=&vɅ i5I=؉X:#4ng5!C40p`aN(,_{h/HEuE]Nñc؟B)ޫ1JQiVxj!`H/BI8RcE _ыMTIog*8czvg1~V/v/ƒHI3$Doۆu*eV|gaPPgy'Sz,k**ҷ>,©U`S; ޚ4 _ z2u8k^1]R,srdӆ7Ie@(l E]Kp]U^D2#Z'9 s@ ƽ QI$RqrRN}1qp(PM!eMmHI@GE>mƛ#ay,2;(wNz+gB*aMh!)ೌYD =E Oy$(> m!$r[z$bT M?~k=7̚Jx[%4۠_g</ܺ PPcުӞs'ĸ"+]ګpDUݭ]>KTa D$@I |ncHTi2̆/VI "E䎈$2O%Qɂb6*T,1!<3t6 JdhAdQ}J$nkaqFyt[]R~2a _ܝd:C4"n\*!bPAnB&ט I˖O36>i5Hm$㒱qqOUY?]-3S'Ս30IUUO+rIuc\ _WOgdAWp6!G"X~Ñ PagK!!)9 xd#(( #K'P6b4i$K)㾊$\VWIY;Bc+kNJoc\~Gb 7 a0|lK%\yRd҃?Da" p#^Q]ϰJ;IR7;)-P$8cESRH%R2V$MRor /d00[:dqOBjSy>0'JhD6aHañ"RNu86نtKJsNbqη~^=*ԨjVxafL4ڍ6(غ"'#ys91$uBn$! _l޽q,nܒ +@<Āl$@^;E|t1_%[6sŏ.=\Lb k{aMl5?Cdh=Gߓ^s[wo7|ro'Bcqz:jҹ1G"(A6}( )1[Ԯ &,ܥroI2Y(.R$M<O\Nh>L6s5-,RhI}RNYĒǻFK#N 1 on=\5wf$9 2EmIUTmد).qg -Rxyݥ'sX4{o%܎>4B% Yb.s":|8˃%~D*<f >]!) OgDPI>C"jd}L)sBi;+؍YPw[4>],HI*\B ,'<̝ 3H*6MLGN}lf/:qVU ~ Cl@I%N;,>z)(G$=?JG'~'?lɇc9:gppl169;v8)z; <9;=Nt886zwcb6(MCbTizz S祶ڬ)Q;à&+{.#p)GM ԥ)М#$RaJQGarR)x ˑlѣF(>う9~wNGQ'GPtD(لr;4hh4GBs lQrt)NC;aG`hM#ՃG=bt94v=͛6l0Rh)JSGO3hQɅ)=C 0)Ju x9)IJv)0qh 0a)JXCaRx4yG 4pphh(Ò$sADq8ǸG'S |͝q(=?3NMl3FΧ&Bhu;?1N'?S9=Ǒ=9;NنpS>Fit6>fNJe%0Sy9680a)0أ)JarrlJhGOS4{{͘u(0zg7NJz4{Jy0; N N )F'bǸ%)v: )t9'%:Χ6l6pu0r:L``<a yF͝<:)aƇ6ha:OBgCp~lrp><{:Gy4rryƎɁч%(plp`·=CL=Ce))>4aFJt0paGO04w(aw;>f6NǑɣG'Cgs;7͇o'w^]MkjWîBtQU"UvQ"iN*sf0kYjIUV+NtF(; Xqk*2dDeQUGtYM2S&[;⠒kDUI]1iWP⠹D` ĕʉz9xյPLSL 5foRnZZ̛k4ufmӗ MeȉqQU'Mj ɖ89.c7Ljb$t*0`TLlpi1mcQQL"f0dUe)h6mdB!NHSQ26I0UA.npIO |zWo={R}kܒ`U=VUT8 j:vTᩱR.?ȔWa{{+—d$*ʪC xW*Gau(,}<%\ iI+ޕ) >؇h'&+BXhp<$z&ǡ6>@H: ~︈_\_i#/3B1]Z"%IXI Q$_mJ(vƛ4|g:z&w csy|ti3`_#52q:Ju  WBly!ݯ61g-CܖFc .48CnwvXW_/Yc&ۚx˹2 ۏ`đѶ2@\;Ԋc0gҘg9ϟ5#zL[drnf̩p79yFhd[|d$,xaEBQ)" 0yq\y؞\ݹ> _t}3وN `9?%C,=sldLR|F|-f2}.m1ϣۼo3.mIg yd/Hq0:𱸲p `gzcj=R##[`y3"Cp\"hzbjnOg.ɖc*3&JuMi*gwtFUgZBEg1[3f~/p |bu#&c=&X* c 3 U˶1s7c,໲ *gnl!EKūz*jhH鈾[oSqmڍ)sm $̖2'[zC xcs1#nA+D5^/1Ze^wn u~zgxɕP8#lg3_]2 {׆kPd :f*eI/PDMxtMM2xFiXGO:]Q.^J׸(IcZI%o͝sMXɕ™]Cw蚚ނ%z,MVyY^7j哘1eL҆K|n'IA>ڨܓ@:"Xd LsUN8\-m ̕L $?+c~xN8yWiTb"?oSlWk)1%R, e"c;=ׯeֽOɷx,$__؊ꧾs9Q=[&"I}2G\wL*w">f7y}^2m֩q,ٚ/|l5xtrўq-9LOswx<^URřk%!E|;s=7۴q[ѽG [z:;XS,cfBZS=()JJ?Jvn(vpF?4vsYkZ9\x)VSl˺N _TΗA!ܟr{ztyM=FƉB))0aGr)>JS2ǃ0yN pS)NS;Cȧ4acrv=9)Sru4{hOŸ3px?gO)Sv?ÓF QٳɣGХ:0Nƌ<u>C?y39:{·ap(0Âa0yMQOJ%0pQ| cɱS hQٲ)Jarrlrha)6a=MRG6yacSSa84{͝ǡF3GsF86S:| pRl N v:MaMSGcG&90`M>gSGC :0y0'aO#GGcw)y:}gO| >z8{yL:YЦNMSu6|Ms0;6yl><{:gC<3g0Se< :>›9Oy:cF6lal84Qo]`lH但&ӡaX$ EL V@SuYD3cېiha%ʈrIdխ*cS8zIH!B)˒fSnILqHIx^9lHU .E&cXӈRse&oO_Vϻ{<bWCEʨw[alG$?w(*p "-5-Ga7 ?%~ T5px"a uf;ipSMv;^R; к[l}p 7r d Et4SClZȍ#L`ˑU^<$XO%=j<{*oԔ* JD h!O58I 1RI#d#AiݷwYy]=ɺ>tj~#n>/51f mdoGwx]w_צ^['EYYmq1ec2!I[G8o \L\c"6,u0_VEME4Ο3iW]D\ Iog}MU|ӧ,2zR G_ԡpA#ةi=L26ҜIpE2AKzzQgI$;P|DD0mզ݇eM8ṅE"?~ăpg~!օBQ_Wbw?E8?á܄=>έwߩ͘uO~:.K!"Z% 1")'KwW/֚܏LH}"ßHR2[cJX?fjT {6iK)blZhGይj=Z U&6]v[Tݼngێ5Ye_V 4iQˑ:KDeRaс~:Q6lɍct#B$eN}5͛6FkYcأ2Nk" ]޵#fx蹣E,]\9Xm'MR̮btʼW]"&զIq~OS~_]k,՚ImC*a v\UdeXÛ\( Nډ9C*Nd0&$[iTeL"cXєxNlU)9&l[FjXl 5UlP^J(Twd8ȭ4V)fY:6[+hV&qxjZumpG.6]jӑ.& ]ԃ#$f#YmZUun]$v˥I$]4V*MjJfrKs41Yc$gۥ4LVav*ujDGS.b";8i[OBGkУWf^vWJ(- G&a&棤6V K(б yY5pWFɓk؏C29(] v] >G cԡ+UC++^ $cb!óXɌTW;7fXQQl&Blbr:*^a$H*8±9m`-S6hm^O&t趣[םֿ}QMB n9lEܻ©ʵ+đH {Rq9\eY8G*8859SJwjWO˶CHIS.վQуxq^3%_x8?C\RG's 1 ;9\-3R<'ةVDJSFGpq).1^ncT5HR!Ma(AB(u.ʹc4d06QZx+W_ 7w<52idSL& 4p8p(VLmj$!2sve WÒ x:; tjY䪖=.УxV;ƒu$q Jжߝ;H&Sc36g\W/}mZatcьc)M >E0#QC 6{M4hɹzZɊұUƗճSMj֬ۢ_hUQC;C׎GѺWjԻ8jv4S&Dܜ:LGiJxh&M+ BYiZst))Jp,mn :N7N qfnoF6''&{ﮯ}z@ >j0yZiSOΧCGp{~gBGs3slQ|b*1>gq!N:<HHaI~ںk5vUlx> 4h;wiMo4}? ɆhԔ)\üa)JR)JRۤ9/KWp1̟!41LI^~21QS3NћN"fp#s#"e:7N}w d\3u_A_tTӪs.b`3jVsrkGn1)F͘·c4v4h٣[6}v4]~PuzޫJROgu3-OhE0l|nGN )+ a=ga9=9x32om7?}vګ3I0$Pzt0VP|EhJR)jGyw1иavҲefgx{>N'wxW)JR(R0)JRJR)JR)B)J{[mٱɓ~OGO'gb;tYmfdwtwqwuޯu)JR)J}g>zu?90?_tMGrt?݋u._c{/ڵ6`0џ4lѣf"-/c> 0u:!%CXZg}Ub!n [BHJIFx,rC gcf''&8$z"Bs_Ǒ{Ⱙ{qc ſ6ldOHIM4֘]ky7i|F˵NNL Mf%8-7$+?Plj54F)J|Q)SfS@a>t#[mn,r:kjYۢ0^ЪiyG#_;NͩVګ#G# )JRHb}o̪iuN;R$ѸId0YeL)O1b{4SF/ mnLlӃ@&V=jv}BGvMSC[})VSY3-uumO`Qꁈ?rlP}opzN aE?)M9e?\g,/ J& 3@?333332LmclmO?e)T׌ieU[5}IL&'%׷[m:;eմPI#C0ž?EYpè ?jgD>!=J#q';=׌'qacq㆚RxtYi8[qUUMǔW7ϩ'y~|~x?@d?d?KU?oѳF94RaϴRujթkFR)JR)c1c0)JR)JR)JR)JRJR)JSL0gW~ ظXj|1=sKl5${bL<4a3:LW' R)J{>f 28o]_7޻1Om aGE?!"u'%> SRy(OCܥ)JR)JR97OyF?by %~gu4hѣC0WܟAmUSANJhMK`Z 69dՍ!lʖUtDJCcgC M,8C2?֒Tz/w~4phهOEZl?X9)JSJw&M|#l3 hN_G&H:JR()JR)JR MxmQ(蒘ҔےQ0_dkb*Y!pjY g[-јNq[)Jy~~WA@QSfD1"f[L5঵E)JR()JR)JR)JR)JRJSaJ`gVPM]6TƎm]+mڮtܱkyjfD6Z2bJV~5 6aJRWs33- E)&cf 0)JR)JRy-Ɍ-b_rr~5ZxO[mӌS{efi.KoJ ;m" fff?O/n<>)JR|*Y 7')E)JR+~?˘MoF>OWF5'A5^ 0ÓɂiڕC~~Tj{*eeqqwGp84h)5SR)S*d&N;?w8)TMq.|2_ګWL{%Gg%)IHLBGI>cSEO$MI.١3}+O~P3R+K=O׉"~pI3{/nHkVZ+ZLi5YS4V&XF5L֌eƏqtɓ&L2dɊϱяeYXbau,+L2dɫH\nm/5k++sjz̻L;Lj/RYL2dɓ/K) lYZnmdiMom%)e0ɚi0K)2afVVLf]MMLfL`Ʌ1nHww9yeƓ2M1z•rRYK9aox&f}RC%"<(>Zd<#AUf2 iDDRD Eq+ !CmNbd!w$e(bTm!뛓m\⬧.N›Lp^w/޻udyyۯ]<[s^^]盀ݺI45JRAL#LdcLǓ1ɗxLfj]YlZgNhƳ ׎+q:guߩֳ@ɹr5ʉ,?Gw&8t}U##< c^(;85WALJ0l{lXbtG;dܶmCVGaE4a b4:JR0˜QCF6: 9>gĤ )*vqNfi̫b1a 'ۃS,),?y5#1((E9m}ˎC՛K2=8G0q^ՍUfz~^RyaQgCJq;aOnkэP6cbj5ywCx8D)??u Z! /zDL RQL*#e)jUmDjczdR{SGeTT< ϭO©ZM=ʃʹTdYYY=U)=\rߜ 2=>*t{uHf(Ņ4iJmV C^URRdz[7T2ȣ-& Q[[QŘp8dVڪ+Vk8*O?W+=CTtD.U]JZM9 Q_Xc~4dm>2q66tt/ Ie1dŘicm{'1~CIa0pT9FO)JR)JRL)̒D#;zj1:G4hv%(RJ&1U-(*}YckL'aF)Fo c9z>f X-_QO_=$-I¦1Zkuk]-mSI&el*̙'t>vr=\g&4 L|4Xr+CG Qvhٳf Q8FғX&>'ZH[a'0N&6D/X,JƤT|?3c00ItQTg㚉4Z*6z$)d6Ѫ{˦2cX~Q:R)w)J/~6Sm$Sek[o{J PQb$)(H2DDDDo-rRږřOG";;1c⺃Nv59QyڼsJR)JR)JS|?IOCJnMOB>FF GyxA&S寖ƚc1cWLttte\(hL5 0az.Ɩ'v1M a*_pҮ+g#)Ng)JRR2U't+U{ݐ@խTm+C!!o;%U1CVjG9Gc8cبyǘat6O){T'WaΘy~J{!Cʮ0|mq}q`tc 9B0ari(00`c_MDG8RNøQ ^:=ZTZg9)%*Qɑ))0R,W-ܯ5YYK99BrI?/}lCUpy{5?g89u*eZgU*) )u.ef*dY:m2fU8vVE`SӖjS+i3AdkI4ަ]iЛ֥']Wmvffn]})JR)JR)JR)JSf R1c1cR)JR)JJR)J+Ļ 43 W{ǑcR)JR)JLc p'%6TY:ma$35vk]tݼ 1pa9 \c3FH=YVXtUjew|(bx4WWGVW^םԓI#9%٭-jZrpņ:l4RQK+f ܙ#S ]n=}DeOJai24ҫ&1)A${?iCa>{>A :gSf[ޓbwRT= dP|D|>Iy۟٦p *] :ss+57+s($ 7ʵZA4 R&L^ nU4~X/.sB,T ϓ]z40 Bla3t+6IryN x<뫕j`Ҽ(ǴD+\gjrYYђeKrb['2.A%ݡd P˫wg*ysI=4m9GRe$ R4 X:bOb([-^A!m4xbVBw dPi$4 ezTH*:z8хaB$t Jm+ qf1(cdRv*fضL}D)2k3yc/vziR3 lm c0P%Bi^pID.&RII\]PQU 4m-T59#bL82bb1\ZÅ݄6-%qcVwRvrծw([ ,Ōtx8oP{/!d`dMg`+cJT2HBaaU6َy'5T"[%Ϋ%1ʴӖѕ Qdp3WΠ$N*e 4.}bpy“wvH!ڻݦoz# gW.pjIZ :i ㉃ dM\y8"Z;04`i$ 0ʽqCͮik=<4:XZgAlay$hW(}h)DzƯgXqzÁu:g#y6hѣF%<M )I@CA Bp0QMaM4hJuCc9ǰc) kdR\:NPAg|qZN7TQC;Jq m˒/ܙE"TPQCFl)hhJaa只^! fGrSF{qek-~<~G3 B}NXxBa1/)8إR J025=ӘE**QPKpeiU[(#%HߩUU@9 b6h*00w~?~$?Y)JR)JRʼwW}@r> j#?35cU2d+2hqM v4C ^meEF *Rz1si j+rd$dinI'=A1)4hцhѣGwv#|1F)I(RR{#ڟhz!V<|?7äl_flO!G>/5.8^}7Ōw՜c!&X3 e2$,h?Ǐy6A$[&R};Y"I4}E<菜khMj'~~WZW\:R, R~oT]U[L]֕RYa&k(Y$u%zVݔkTp*))L0˜d3" Uّ]0v.LZtqJRTՂ@wVJkծ4]KqEGԛ6OqQ1˒K鉒6ifV5--KN&yem4@7urwk6uojRj5 UW*nٚC2V1-أ>F5E)0,&)ٲ)M0)JR) Sq&M)x:qSpITһT->gE:SS-bUaf=ǙĻy'L9ÉWpi G&Dc֌&֯tvXsQF"f#}{ζz[2͚sMFjٌkjJNNM$rM16*-%q}C"E%PC䮒@œbફS9ьY2[c#-xD@= cQ~snGD2C#?Rj?ϢjMQ_;Hf"N'oL 8SJxH4)F9SٌdL{ 6U7jl6Ƶl֥i= c1{ORAzxNHcerGSz_iW`|N`UmCKR X`c,> 181H+GãKTQ%T9Ο~ٸIēS qV'F/DêD,󟨥9St_A6W_6ScX;&vxuү6͒ Laf2j+Sc#J8jjԥ)M 81pu6Z2{'6{+ov%e[VfREcUL5I R,-Ѧl5q>+}z~V~Ls!&b,ʺiV{Ɖ8Xq;O>u>f1?zF1p]U(q=w~' x{|၀@ $׭v6+~u[LjJʥőJ[lVbJ)F6R(ÂbFeACV$ny}0\r_tՖnL;цDcWW{%A̍aG4lp5g/NF>9]/~'|b+T}o6iwOJF|TWF֙?cCw)NS"IU8T*WвRaDt}e)dJ$h#I a)SUGgf 45F0cC%vr.l3JE˧WzL2> ~Zx6,dd¿7Gm1rq&faՒaE$$r%G 6SeaINFOđN;#1'ClŒ);)hCLTa8GaGNQrPxJRJ tEGAz:W[RS 0 LcR1*ٷD%2V1Rj*3EK121ed0v[:2s3PkAe=OIUǧGxV>?9Oy0Ouvc0dFecl6m,]b(0aLaH{|Bv9W"KQ\]M 29,a0 у GU? w<\zCK +{GϪl#jS믝ø>rLd5tu'0*=^`v7Q?\XfYkYS!M)AL:)J!5v4קH=;80euK)&uk.4\U3 2͛C>`QF!!CBE5QN 6iGK)899l-$jV`Ć>GŮԥ1 }LTzjs :Ǿ!b攩 &5a"Ú+anq,=&R2}njU>wKjUv~&?vUW %նĭiIDDDDDDDDDDDDDDDDDIDDDDh1b1Abƌb1c4F,QF51ccFE-ѣi4!(RA%&!,&IIbM d )HM\>|jW'z¢XdaԤ1 %_aN;DapaN$I0>#>g4=|E O3Sd;6בK$J7e55)Z[ۆ)f 28a-GF52pM6^GDUb8$ު[k&dhd1S񦩷z5K3!&Ʒx\Ƶ 4fR&94-v˱ U~|khenV +*LSI\.*lmSCͻu3E#!"is "Lj5&54+iiJB!EӞQ0өR `ah b3+eɑ#RIPH"eHP%E" (aL : ZZV…n%"%[6I.5 ena ,B dNbI1c&Ӱ(0sNN~8fӍj\惛 _K 3URE$§n~Cai9)ʲbTbEzM]33dw者]zH6TjBƉ։_SйCUOJw9)SŞ># (IV;j-=k=1je*Kը5]YݻEUI)VJDuڸ*~fͫm_/Cp/1c1b0”)Ma'L4Wj'xK2 =)æ7'MNf.9qBþ&-I8`8$lIwGliUf Ɠ6v2Fx7`s!cWqfxzOFC-4A֥.+aBG 4-i9Nk؇MN-SNNOI#|Lb~?@?Φ>rpaÓXYӥ/r;$p.1UG b́4L.'?yGRűX{xboѶjI<>C ѩqcNh8n3MMQʫ c(Qr㌴ 5EL.1wQ+T*c#j >X@Gb~ί}(h<ð^_+0lc.QA]Vl18/ԠUecT-)0#8>Ñ{N㹆Tc `diZa?<\ʛThuUfgU8ҕ\kWbCe4'hE)<F6ccfaH6< c<_C=^L̦e#kjM}ݳƯƞUW/Ǹ1cX0 6e [fmiTmVV6Zea,5dǬ?$|r_!/|LtUUUR*Eo䏃4Q>яD]ԕywx4mVfUUU~c^'COeD.ʵd)i27REUo{Y33K]^Y1eKcbi]WulݼraJB3&L0aJ>#Q K bٍt^syx󙟂_=z߆UtM%8&\؅_tGl1hfٌcG ~ֿB`xcƆ`uV٧:Lj}!Nѡ41%%=D$^f$8?sO3>Uxzspy>᧲+Ppw'O5.cG-<}C>=By Ssӌ GayvƞR[-2~#"}FurM_󜝼O+D`!Wϟ9?t =BR0l 5F R4aɳG&4heLDfI]q݇:-}Jb!;^t.᤾Wou35AE|u>,̅[BGx: ;)*rNz` kcEbZ&ZZZ&lpq.krrXc0ЗViktc0 ڬq&E[1qXb8¶JG88XYWn\4nɩu3Llvb}bdLiʙzIn2dy,ҮDJ F5[:MT!1CRmcC / >Ssk̍<ՙ +XcSLc%^fTxVۓoBbp.*GdB _ErJោ.\R aXҕ0;`(NYF D$c)MBD]a!腤` aS-t 97).$LPm W`k+Y x 罫XpX{>Lm (IHW}\70 <L3.p2HK ;j:JP5JGLX,WoT$ȓl@ =Ic-sO gOn)ZJ" ̶׶M<6`t;HjA6x"n9:BOk=+U2yv`8phzپ߆ulщ6xdcd(I$Ctҧl,2`CZte y]QݔՀ0!a!&4FA(dr0NCԐ84g#Atm8eR8;f 2;F@40$[OM f:bkK[jУg)I4x)SE$чQp;6h0{w948HQYdxڜjӌÙ894f05&PMTUVjIdK(`ª K8L./Ut1#Ee߷ Cw <^nf̯ʧ &N䔛PI|7Iv$ 4lrlcMt4R)&:)p;;ѣ8)GsJpuEkudK $o#ar揨TM}a$ʖ8}2Ljj{eZk3ȟ)McOzy=#v/mg v}Q;Jаv!~夜{.e ҭdHϯɭНx;ȬIѹnK$s%ڿe pk>IR^{G+Kٹ&1y.1ꥇ)ݛ3کVXbɴl$YXQ0঎''CG:7dUf|ɏ/@š[jʭhө%k,`M;qF,ֳssNnP%enqī22ˍz$#O +<ys:~C%~-fhff.1\eĦTɔ~ i[UXjj{zy2,k B()4)L)j )0Q'k:2z2݄]7J{ i.)LH)JR1ylkE-QbƊXZzWzwp<1⼝}&%xbιޒSVU},5qгȸ¸Mi6u8L699ʻTنΝf+1\ƃ {vxGrO:3%fTS)WaWc̚bM%h-)[R0cjjT֖1MXkifZݷ˱Ȋ`1vCUƸ˃\:)sy[-3ZZyC88c-?y۱Xq¤Mcz8H|ߙvOEK}LmQ`6§Bfgq8e` 0dp0S 'RKWOw >b{ϘO1ȥ--C5H,N>yc-R*u89ZɬcjC Ƙİ:$K {=he b>?Y?:hĦ&3˅{V0ܱ91c|j~oUy sztt^W0q_f3GMJ鳃-;t9|+%tk&P;O> T}牌vJiS22T10JSr%|wȘ4򗐿ac110Raܱ)H~WWyZ}I+~3r?g Tvd1]"rdb[LV#pw=0dE:^U RD LpB bI$9F!*Ll>dtoFIs):;pb$vd# `^^  c$οYyov= Mlc(:u^emyq7(;ysFcΧSF0jwyUL~Z'FǃhÃ8)܃'kЫ'Zq\xdž,N9!ĪU/sΕF3HC:1qdi"-1Uﴫ*h8Rƌ)ShY4:Q;DS?)|snZWO5V`UtkZ4%lڢUضMZ`az1zw4\j7N41{ÃIDsE$HG?dMf<<5Qg~&@8id4#& 4ѦL hDO(zeMS724eP8id4#& 4ѦL h$M dSM2jz)Dm( 6Gy6~B'Z"$QQQr*QR(abe$b,sSg2IGQicT !HKI4E Ԓm7x=.DD@1yFa`t 1%(:k- ?cS"Ǽie33JIkɻǕ*v^ mU^Jgߧٯ)M+}Vn.Tү֣8ӧZY-J<{8ewIJ1KBk~;2ͺos01@R'tH8etnjR4EB/$__^nז!K42tiWzle:TYek\$zt_,kctȭ/kֲُ &Ѡ"$-$"}_as,ҽjψnnΧ^V㒲Wǧ}c{Otqv2<¥̟y/)J)J8 i3.ZLpL KުEPcJ-RcYF^ =ХU*^TZ(hd\X⪢,FfA(JBHw݀/e}F+Se(y) ld8O29d/k"ǑՁSSћݷ_EUUZuMϿ~4Yx<9R^6\> $z;5U?>$ОcG̼ٗ8bI5aލaC37kYOF-{[bw.є>X}c/+/Ņ[>"&8; y"Ȳo dZ(KeG^,qRʲʴNZe**T#-)#iWDbI72|N疼ZgSd^YY<;vie'Rl[呡z7\+7]UW|e4/"zUTsdꢬF?Ҹ4kR3G:_v|z4UUXRvNeUGVN*b.Pc򶴎> ̪{k!GҔKϔo9GRjXFP[7*JrR^TUJUEUgY{e\(CQD*xɜ8riL0_xOJM#g4蔪KJq1GrSMzgy&=%Tʪ~I=~!r-.Ԓd\ezR%l+M83keKʇUL3Fr.%#8ۆtLΑѢgދ w'K)Lr*J+eogO'?a^DOمl:{>X($76gTfϾT9[/-ZYe+V] h6F D0K_|*XXejZ=g/QVIjU*)8 LgMbFޝS5b$R-ډ:4Vq^oe[roSr݉|jMXNFM(*,ml-8b($neTZϾJp9w9 'E%h:?~&:8WpyUxĥ'JI7ij.]_ΩJkWn3'N55}N<.p n>