camping-2.1.532/0000755000004100000410000000000012154156727013344 5ustar www-datawww-datacamping-2.1.532/extras/0000755000004100000410000000000012154156727014652 5ustar www-datawww-datacamping-2.1.532/extras/rdoc/0000755000004100000410000000000012154156727015601 5ustar www-datawww-datacamping-2.1.532/extras/rdoc/generator/0000755000004100000410000000000012154156727017567 5ustar www-datawww-datacamping-2.1.532/extras/rdoc/generator/template/0000755000004100000410000000000012154156727021402 5ustar www-datawww-datacamping-2.1.532/extras/rdoc/generator/template/flipbook/0000755000004100000410000000000012154156727023207 5ustar www-datawww-datacamping-2.1.532/extras/rdoc/generator/template/flipbook/rdoc.css0000644000004100000410000000501112154156727024645 0ustar www-datawww-data body { font: normal 14px verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif; line-height: 160%; padding: 0; margin: 0; margin-bottom: 30px; background-color: #694; } p#version, h1, h2, h3, h4 { font-family: Utopia, Georgia, serif; font-weight: bold; letter-spacing: -0.018em; } #logo { width: 150px; margin: 2em auto; display: block; } h1 { font-size: 36px; margin: 1em; } h2 { font-size: 24px } h3, p#version { font-size: 19px } h4 { font-size: 17px; font-weight: normal; } h2.ruled { padding-top: 35px; border-top: solid 1px #AA5; } /* Link styles */ :link, :visited { color: #00b; } :link:hover, :visited:hover { background-color: #eee; color: #B22; } /* menu */ #menu { background-color: #dfa; padding: 4px 12px; margin: 0; } #menu #version { padding: 0; margin: 0; } #menu #links { float: right; padding:0; margin: 0;} #menu #links ul { display: inline; } #menu #links li { display: inline; } #fullpage { width: 720px; margin: 3em auto; } .page_shade, .page { clear: both; padding: 0px 5px 5px 0px; background-color: #fcfcf9; border: solid 1px #983; } .page { margin-left: -5px; margin-top: -5px; padding: 20px 35px; } .page .header { float: right; color: #777; font-size: 10px; } .page h1, .page h2, .page h3 { clear: both; text-align: center; } .ref h2 a { background-color: #eee; color: black; display: block; text-align: left; text-decoration: none; padding: 0.5em 1em; } .ref h2 a:hover { text-decoration: underline; } .ref h4 a { border-bottom: solid 1px #CC9; color: #000; display: block; text-decoration: none; } .ref h4 a:hover { border-color: #694; } .ref .mod { padding: 0 2em; } pre { font-weight: bold; color: #730; } tt { color: #703; font-size: 12pt; } pre.sourcecode { color: #DDDDDD; background-color: #775915; padding: 4px 8px; margin: 0; display: none; font-size: 8pt; } .source-link { text-align: right; font-size: 8pt; } .ruby-comment { color: green; font-style: italic } .ruby-constant { color: #CCDDFF; font-weight: bold; } .ruby-identifier { color: #CCCCCC; } .ruby-ivar { color: #BBCCFF; } .ruby-keyword { color: #EEEEFF; font-weight: bold } .ruby-node { color: #FFFFFF; } .ruby-operator { color: #CCCCCC; } .ruby-regexp { color: #DDFFDD; } .ruby-value { color: #FFAAAA; font-style: italic } .kw { color: #DDDDFF; font-weight: bold } .cmt { color: #CCFFCC; font-style: italic } .str { color: #EECCCC; font-style: italic } .re { color: #EECCCC; }camping-2.1.532/extras/rdoc/generator/template/flipbook/reference.rhtml0000644000004100000410000000436512154156727026225 0ustar www-datawww-data Camping, the Reference

<%= Time.now %>

Camping, the Reference

<% @modsort.each_with_index do |klass, index| %>

<%= klass.type.capitalize %> <%= klass.full_name %> <% if klass.type == 'class' %> < <% unless String === klass.superclass %> <%= klass.superclass.full_name %> <% else %> <%= klass.superclass %> <% end %> <% end %>

<%= klass.description.gsub(/<(\/?)h(\d)>/) do # replace

with

and so. "<#{$1}h#{$2.to_i + 1}>" end %>

Methods

<% methods_for(klass) do |method, type, visibility| %>

<%= visibility.to_s.capitalize %> <%= type.capitalize %> method: <%= method.pretty_name %><%= method.params %>

<%= method.description %>
<%= method.markup_code %>
<% end %>
<% end %>
camping-2.1.532/extras/rdoc/generator/template/flipbook/images/0000755000004100000410000000000012154156727024454 5ustar www-datawww-datacamping-2.1.532/extras/rdoc/generator/template/flipbook/images/loadingAnimation.gif0000644000004100000410000001337612154156727030432 0ustar www-datawww-dataGIF89a ! NETSCAPE2.0! ,  @Rihlp,tm#6N+rrD4h@FCjz]Lj]﹬R3-H$wPy |KI\K Q\]PI ~$ ~ J %:`@ XP@AO 2|(D**HE}lF=$Ƌ@\9L J()? ``C=4RO@>}5TDU^=UQH~Xe֫:|AoG4Q]V;ޙ  jUzҧ]$jQM ʆķ7721@ܒDH;܋%ЅqۛXMgNάgMWz!`dѥ]uja}a ݸ6;5լDzTh,5~z~@y[:3M7gG]q=@c5 4u흃5__9_AMtB\K ⵘ}" @lDiQu+baq&{#'LHjz"$& $B! ,  EI@*PR*;ò[Ll7DҎ%GI0)mIԲ`I}>ă}-RwFu}y|O(p*"rt{RA>( ^( "4 333..Чɞ v.*o 3u zz( D.z Ha рP*6=%8A%ϤH]JQ&2Lz녆Aɔ>50j( ]T.s *I@m:nTx^7}v(Hy!8/ 4^ֹGi`zA"?l8]'STҧX*3@XMS<@蜮-./Ay5|Uv۬ϰVr4<A:\4bmdvi{˿ӛW'7naq{"8V_u_^2_[koTpbp :M skx_"Vؓ! ,  %R4 yԬԢ\K٩l'#QZ0ՠVTyïe]U4f!Pc0zkW+_ ^ў`v"Ŋa@x:@O,ȬtK5zsRtH5y3ʥ>yz=3[/Z|&x @7nGdn B^|{ZCN3Z&$p{f;^C}Co %! ,  %$5,%:k.]#> B"ZRp]2Shk9E-e<ͩkGj6-twsz|mOQtix41 ) U"  BQ B)# B+u  )ێ #" pg߿=QǍPa Q*֑Xb<88l$Q,? y2=0յT#rΗ5 9`jLmgTJ2MWy6jukիKy0iP0JCg&(`oq]혗']u}C*  ^\sxaGtKpeÈa@jvlgVDz$ͣQ>mb16}4 @l`ѪzvsGt 2y֐/V+SNJ=^"+Y  09ڛ>0}Lj`abqO '8^Xd|5 [ahWY7֑W6!i!qHX&(@3&B! ,  Q$@RS" k; S]3X'+ζS tUik `m0c]wldt$v}k~zq,lryux?)B ; 00;+ ­G 0-g+ .z%$z +l(jx9hNt<; 8O7yxH#|bH$ѼLipȅѐ 2"-A(P$tj@{s(W$( =!u5(jmn wmĸoA@w/d1+:'l1f#|,z20Hg@1}թٯ[3S+|7Uǃ.{ P卵0ʶc=+PL03:~p'v{On<~)@uP6 k (àK'vK V`I9(ZLG!! ,  PeRN*',Ԣv*o<bKs M3k>oR sAE1fm):kvvM{wl rtqPm|uF~?W a3& A66 - 3- .,6o 3/h-o 'dzz&(CGo߉Oa9ќD= kOOEuj(ǑLʏTIR&K.H= ttI£B0E:qjԪPhY‰ ʾBFdÎT0@ܝK!Aݽ_aw9hP(!Ѣ,fʓmZ,rƝ[|.1鑣wZh%.:^mRi綽7V޿}c\u;o>oüu+],Ebd]/\.*h3;߯~ |HoXg6] !! ,  E9$#%5(,Ԓr(i0.݊`lXtD%ydJ6H^.pl[k=.˿(>Sx~gypv}lNtjx{e> ( ~~ -- ,-(Ĺ ' e -/p(u '" u GN šL1:I<9uG '9cɕ-Q$L'lD7UTTׄ tѦBU@%JJŪ)W?LSY bZvmމБ]xF0I{VXg|-BfE#|.@4OP4u8S g ֥_n;Ө՞(բQ)wǮ<.(ʳ2?eG|LՅ"x/-/y+,p=E1 dQٷ~2Kꔛ$r `m*YsC zFn ak}nnI#Q! ,  %R4Ԝ"CA,(~ں8׼دDA֐2hs݌+p]ˤObKw8^>uz`H~htkv"xm|1Z, -#51"1''[#, ,}, ' p#h1 w a"w #p"b1V-akcB)P@;]XqČ#N-A"߲SyrL4eMʚph\@eq/o D2(𯘳q s:gu@Fu+QAUӯZ#xbR4vG1 Mɻ;8FP`B۩3he11O~ ˟>z(C3A=\Z-ڇAa-qiSRYmG(1;Ž=dtqB[! ,  %dihlp,40T:Ԕn琘9␄\< P)JZ+^f(-N Ǥ4ant#o~$z|u#Svx@"'% #m# S%  $%§ #ְͽ$& A"%  $#H݃'/9BH EdOC)Lq#Fo gBbDIʤC'CRg̙G 4^M=F\dd3 X堙Kl٣̊@@T?}IVUT+ol|gr TeluӭޒvG]l<ݑsg_D )4EQ_i)Pi#!h Da %.@qMOQ `pnyHWC"$s* ]hp$V 8Ix/b\J2f'<p Ke$׶2RE" :q6t*AP'1aA\<~kVo:Otu/"\_m IAIK:q20l*Y({" kyTekd̨m.s)/%E Fh%*JT~gY/|Dmebqn 1UIu Y*[1CΠ6|7+8@ݰ/lj:xs5C5bg4SS-Dw_KIXSD{4NٙZfx7?9ռԌP͙ zh!Mp3E$pPNM+xIӞ. qی8E~ӤiydB 'k e uy=BWW8gh꾉O Kw 2PS 1}b/"u:Z v S _mf6D11"P'k@ 3 d&5׃ȲQ%>1q;E" Pe~U'=ߢ06@]S-<1*w;%R +qS!b>tc&#"{XDoh}Q}+/!,Wp XW%Ȳ~!r lStrMN!?EGP1"kq xw! 7,pNӐ Ry7 1UyqȦ/"B [.I:+%}"i!W C)'#q+P+MvVUBʐw)lsVӎB&PQJɱt!W!7H A$k}[Y ҃zɓ!G)D j ywǕjl`+1, ;=ezUWY9!FqֱW@VcDOyA K8<ɆB9} E2'XO &DͶriU!ҕjz4=hR),]\]]`1Y}UrQaw9}_w;5bvQd1%w=hEtnT-vh7xq^wLwyC2\0٢+O`[#S " >T/rVڄpCJQv~8hWRфh!yaé/1i21/| vM1($΂ʡ0B. d oF  "q;@!eaUИp\90\ I-!,P`P0TA' gau%)"J P!gTJiD$,y!%b61ࢋR!+P5%2{UyELאؘV,4AWQxNd5|]VOeda N$UǮ\m<܍ܩpI˴Zfm+,X$ЩVӨ RynTrc*WhT*]\  I R<,Kř,ɍy<";qv p+2bY}ʝ:lí3ZV!\ǩk0j[l7XK1];|1DI!"ݫR Jtu- q}Y1UNP1<X|$2ɟ]l=lmq5C #cUV JՃ,cڏ[-Kzgz=ɱ ĻΏYL]ØÂx)\+eP1)`]{,@L՜>dmNVinZZMnPP:>ɝ>ɾ>M~ͬu+U".QT=,ɻ^+$pI&=,+@vZ=Φlp4;0m+Z,O Q! QJ^)<Ėlӎ;eDm>ʟE( H߿߭LY2ݔ-+P$PIn q!r!'G 5O@o+T S~/1CoT{Y<%n5 a,!"pm+RwiM %|N_hM/ ckJl^5 nN;{1OP$O1. } )`2PØ~ANU'/+N bJA+2p  A++ Xd0FD+XX +(qࡂ81"'1|Rb*K,kXat^|إ v G+,d!PrYU^e.e<&jY (|C-`Mv;MӢ&Lۉ?T('=@(zD9b" (V,%2 ;p),4V:(%) ChZ7Vj" :zС$K=ZJDQJӯ"V@YM.`.0RaHУ=#'*z(kR*($vB" 2q& (22!SNQ=dH@T/Qղh*i'+B*PEVRSM{&O {H .b,`9 TFز4h1l=*z)1T+V)Nk7L0hRkJK+X9v-$hAl* bZ /sIH9:¾hp'= 8dͪ@&PD*hfA@VLXLY֎\Į@ܒ,FGl k""SE!B 4i pbU@*%K15۬{:H$Wg 8i3Pb4o 踘x*֣@c(wdžokBd(h"Vb(FkA^C4=M+2I{&(%$! ÚApXaENB:"͂Pp֖!ѰBnR(y觕V+~UA"3M;j!ka$F0 Q#†ltT*K% O#^c7<_lcC\!h8vY`P"P M;jb:eS3a8≌X!c{C)&z@,1(E 2J#, dZujEE2Ce/yip2c\36ǂVr$Qr*V|OI QL D4䰀WO,X eA<d"p1NJDYA9ل $#hP: j$B&~*A"sHldW5bVXFD ˏ4X%@䲊* ˾hd$j:R){PV̢*}M30cvI&k*(<$aˋh Mh]iV$>&&RPj2Ft8WQqh8S.H rtLȝ,2bg($9*V(@t" a 9\GV RRQ~WlAfE͊VBOjAL¼(!y\(#ǫV qD[U!d@50"gM0d6:r 5/T2ѠgxRxN Q[)yҢjT61X8Gn:O|W? Ԟ^h_<,$-7J#1j7+!…'+deRC_qg 'jkega-Y*IZ3 * E0 )qrB؂ Ѐ 4D)N:Nh@#ǂFX Ys`aXt 2B;|I\CV( eLߧ9yE\'D=3JѐFo~JZa )NV./ ސ&$*Jºc)H=LE'vTPz*Jq)tnؚ:MdN֭.O A?"U\d)..-3&wpbwU[vK zݩkU5!RgE {]VA {/IGX'^"]m>7QN ua b`~mIQ%(`Mɓqp>Ai[жxBV06DNjE(/ZΊP,,ejdz1Ƚe^ ~TPs~pC-+4cW{>lck3m>896p.IyX x+⃂< hSC֨@l! 0 (˾! ¸+?q (@49`/:pMb<A)كQj =Ïh8ؗ!@5e5$$:#@ 8*9=@2۔Z<1U5,2tY< \ȉwZ!鉠=2 E##y|A8zQRH;Y4cDȄ Ӽ,يCAF\'Pq) PE^ ۉ#2(L "PA؍1:@dA*;љP U,+>4YL9((G U܏B>qpDEZ39_dܙ+>%ix 8V $ DE'xX#+ bMA O9QI+@2F+=.P2I+z;SPS"xA=Њ4>ͻUBJ =@G -UF|?H!1,JbbM6kݝO>۸<$X12Ph; \EX+VxSM :V׀<) SX ۛ?#@'֡K 2R⓶М*5R YPMxA=Lx'Vİ̡\K#! Ra )\[A3<LU0&j4 ya͐aD+`:TkHpqCQ ndP_AO ƿILt |V`=xъk܍żx@婇~<&H8O 6Gm0 S8SӐՊ( [ٸ@՟U X|[y VHXU Q MҒW,) =@ůLH$鳍ZsƑ4S;+ħE$yNI5[x]-sSg-`ҌÝ#zOL\SA_y[M)f!@Uf:}AUU[߫URA܅QŒX#tVL糘+ɒZC ߠjcm:_T~/p.+Rɡ (jj>::ʫЋnk`LLȄkNl^lnlR;camping-2.1.532/extras/rdoc/generator/template/flipbook/readme.rhtml0000644000004100000410000000213012154156727025510 0ustar www-datawww-data <%= h @options.title %>

<%= Time.now %>

<%= h @options.title %>

<%= @files.find { |f| f.full_name == @options.main_page }.description.sub(%r{^\s*}i, '') %>
camping-2.1.532/extras/rdoc/generator/template/flipbook/js/0000755000004100000410000000000012154156727023623 5ustar www-datawww-datacamping-2.1.532/extras/rdoc/generator/template/flipbook/js/jquery.js0000644000004100000410000015473412154156727025516 0ustar www-datawww-data/* * jQuery 1.2.6 - New Wave Javascript * * Copyright (c) 2008 John Resig (jquery.com) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * $Date: 2008-09-25 09:50:52 -0700 (Thu, 25 Sep 2008) $ * $Rev: 38 $ */ (function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
","
"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&¬xml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})();camping-2.1.532/extras/rdoc/generator/template/flipbook/js/camping.js0000644000004100000410000000350712154156727025604 0ustar www-datawww-data// I know, I know. $(function() { // #M0001 -> $(the section + the method body) function m(name) { var base = $(name); return base.parent().add(base.next()); } // #class-something -> $(the section below) function s(name) { return $(name).next(); } $('.source-link a').click(function() { var link = $(this); var code = link.parent().next(); if (link.text() == 'show source') { code.show(); link.text('hide source'); } else { code.hide(); link.text('show source'); } return false; }); if ($('.ref')[0]) { $('.mod').hide(); $('.method').hide(); var hash = window.location.hash.replace(/--$/, ''); if (hash.substring(0, 2) == "#M") { // Show the method and the section m(hash).show(); } else if (hash.substring(0, 7) == "#class-") { // Show the section. s(hash).show(); } else { // Show the first section. s("h2:first").show(); } // We need to scroll! if (hash != window.location.hash) { window.location.hash = hash; } $('a[href*="#class-"]').click(function() { var link = this.href; var id = link.substring(link.indexOf("#")); if ($(this).parent().is("h2")) { // We're in a headline s(id).toggle(); window.location.hash = id + "--"; return false; } else { // A normal link s(id).show(); } }); $('a[href*="#M"]').click(function() { var link = this.href; var id = link.substring(link.indexOf("#")); if ($(this).parent().is("h4")) { // We're in a headline window.location.hash = id + "--"; s(id).toggle(); return false; } else { // Normal link m(id).show(); } }); } });camping-2.1.532/extras/rdoc/generator/template/flipbook/page.rhtml0000644000004100000410000000173012154156727025174 0ustar www-datawww-data <%= h @options.title %>

<%= Time.now %>

<%= file.content %>
camping-2.1.532/extras/rdoc/generator/template/flipbook/toc.rhtml0000644000004100000410000000245712154156727025054 0ustar www-datawww-data <%= @options.title %>

<%= Time.now %>

Camping, the Book

    <% chapters.each do |chapter| %>
  1. <%= chapter.title %> <% unless chapter.toc.empty? %>
      <% chapter.toc.each do |id, title| %>
    • <%= title %>
    • <% end %>
    <% end %>
  2. <% end %>
camping-2.1.532/extras/rdoc/generator/singledarkfish.rb0000644000004100000410000001354312154156727023117 0ustar www-datawww-data#!ruby # vim: noet ts=2 sts=8 sw=2 require 'rubygems' gem 'rdoc', '>= 2.4' require 'pp' require 'pathname' require 'fileutils' require 'erb' require 'yaml' require 'rdoc/rdoc' require 'rdoc/generator' require 'rdoc/generator/markup' require 'uri' # # Darkfish RDoc HTML Generator # # $Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $ # # == Author/s # * Michael Granger (ged@FaerieMUD.org) # # == Contributors # * Mahlon E. Smith (mahlon@martini.nu) # * Eric Hodel (drbrain@segment7.net) # # == License # # Copyright (c) 2007, 2008, Michael Granger. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the author/s, nor the names of the project's # contributors may be used to endorse or promote products derived from this # software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # class RDoc::Generator::SingleDarkfish < RDoc::Generator::Darkfish RDoc::RDoc.add_generator( self ) RDoc::Context.instance_eval do org = instance_method(:http_url) define_method(:http_url) do |prefix| if RDoc::Generator::SingleDarkfish.current? prefix + full_name.gsub("::", '-') else org.bind(self).call(prefix) end end end RDoc::AnyMethod.instance_eval do org = instance_method(:path) define_method(:path) do if RDoc::Generator::SingleDarkfish.current? "/api.html##{@aref}" else org.bind(self).call end end end def self.current? RDoc::RDoc.current.generator.class.ancestors.include?(self) end ################################################################# ### I N S T A N C E M E T H O D S ################################################################# ### Initialize a few instance variables before we start def initialize( options ) @options = options @options.diagram = false template = @options.template || 'darkfish' template_dir = $LOAD_PATH.map do |path| File.join path, GENERATOR_DIR, 'template', template end.find do |dir| File.directory? dir end raise RDoc::Error, "could not find template #{template.inspect}" unless template_dir @template_dir = Pathname.new File.expand_path(template_dir) @basedir = Pathname.pwd.expand_path end ###### public ###### def class_dir '/api.html#class-' end def template(name) "#{name}.rhtml" end ### Build the initial indices and output objects ### based on an array of TopLevel objects containing ### the extracted information. def generate( top_levels ) @outputdir = Pathname.new( @options.op_dir ).expand_path( @basedir ) @files = top_levels.sort @classes = RDoc::TopLevel.all_classes_and_modules.sort @methods = @classes.map { |m| m.method_list }.flatten.sort @modsort = get_sorted_module_list( @classes ) # Now actually write the output write_style_sheet generate_thing(:readme, 'index.html') generate_thing(:reference, 'api.html') generate_thing(:toc, 'book.html') generate_book rescue StandardError => err debug_msg "%s: %s\n %s" % [ err.class.name, err.message, err.backtrace.join("\n ") ] raise end def generate_book chapters.each do |file| templatefile = @template_dir + template(:page) outfile = @basedir + @options.op_dir + file.path rel_prefix = @outputdir.relative_path_from(outfile.dirname) render_template(templatefile, binding, outfile) end end def generate_thing(name, to) debug_msg "Rendering #{name}..." templatefile = @template_dir + template(name) outfile = @basedir + @options.op_dir + to rel_prefix = @outputdir.relative_path_from(outfile.dirname) FileUtils.mkdir_p(File.dirname(outfile)) render_template(templatefile, binding, outfile) end def methods_for(klass) klass.methods_by_type.each do |type, visibilities| next if visibilities.empty? visibilities.each do |visibility, methods| next if methods.empty? methods.each do |method| yield method, type, visibility end end end end ## For book.rhtml def chapters @chapters ||= @files.select do |file| next unless file.full_name =~ /^book\// (class << file; self; end).class_eval { attr_accessor :title, :content, :toc, :id } file.toc = [] file.content = file.description file.title = file.content[%r{

(.*?)

}, 1] file.content.gsub!(%r{

(.*?)

}) do |match| arr = [make_id($1), $1] file.toc << arr '

%s

' % arr end true end end def make_id(title) title.downcase.gsub(/\s/, '-').gsub(/[^\w-]+/, '') end end # Roc::Generator::SingleDarkfish # :stopdoc:camping-2.1.532/extras/images/0000755000004100000410000000000012154156727016117 5ustar www-datawww-datacamping-2.1.532/extras/images/uniform.png0000644000004100000410000012050512154156727020307 0ustar www-datawww-dataPNG  IHDRgAMA7tEXtSoftwareAdobe ImageReadyqe<PLTE{eyat[öŹҕm밣…xZ̯'֣pٹʱltG󩛽嵵 v]y픋p{khz}f4Ǽԧi}zbّAߢv`Ѣ-瞏xb{f+bGw_{hww`ड़hQmSǿŚ]{dbJrYĺצaʾhfNi{czc:$u~wcxꤡswKIDATx읍[V3!&1 ) WZ$GTg]:wӯ׭an߽ / өw^T@^'s=| x4?'O x4?~O!z'oh⃸, 844O g^$ˡuYYYH}>t{^}٬z .,BYdwՃ Xm鰧TdCU "-I YU F1HkmȊI˺!)H1jA 2j0U&$ME|m3T7Q Y!6  !-%$]LKoG^5i[0 Dr/2\M+A_ ֳE>QT ZWyz,Ǖލhd7AR];4P,_ިBP2zF]Bݹ=^ތד00^d1)ۻw#v(-e;z>d! uCQn"'n*ME֒+[@Eܫ-s &oEDb s$PIФYӱ_3bPME'_9BpWnPO߃VYJ$)p&qC ?ERcL',#+Zq&y=^3vc櫓jW i(yeT-"ωj>=^{>zMb7+$CxAiWUlm]?^v$1^CN{97#qqVP.0{z+}W } Y`۶- 2whyڟe!I[ xRW(ޔu8L}f/\2J6TSr.`fd C$Fܖ: d&jZ9S\7URrC>K{ YGCv~v-v/&*v `jy{r}eY\y"C"<=T++%6@tt˥n뉚 ղ?+Ȟ7;D-aYOz'ݤIYSTÝCXEdnpL dYಫbDSAɽp5=\r 8 ;.7k`M n' . "h^I~'H_Kqx0]}dO,0 m&ە`Uw9=*0@*LT TBLZZ,ܪŇGΟ JL(PV$Nc Wp89; nV`\r)W{dU @Elz*- ;Q77[?];L9a 6\IlGE"IX&RMv#-O1~pi94 ߨWpΕBg=qSc$ê9f;-"SK'vpD҂?)zqGIRi $'zn4,in$ظwfFr E w`1N*S7Z,e6EΡkD@/ʀh-M{m 뺱G_oNTѱ| Ln$j1EByC歮OϺERoOsE $٤'zT>ͯ[Fq|Lo-Tt+)kpH["`m͍0e9.S{ZP{k #JbKJ<]zDridΙeF*Iڨ~X*Ʉ'D;B,Mcn".X+Ժ*IMOܞ {ʮȧ"&!cj|4_[NZj(Bn8l"T=wwwd$g! )6XN d$ J_F z.CM6`egJ V>&T,G8|`xF"pnd@꒒J|Db(Lȴ׭yA`agJBHUY24G>RWﮇ_b>&v`@,=-⚯WUDNeaII L y.BSs**! {SX*Rf*Y#IeHz7xE͢ n>!Ne7mBM < H\zVJlth롩J򴄯 #_˺RWJ-A@*CeRD|1nYEfGL߯RufWi,.\C\#и ބ1*45jR8ִ}z92ZiRVI(2"Df?-pw,f!u,BNoM%IQ7:*aΪeDSrfl+^@VQNh?%ZTBH.u`u-)*Y˴g",p1-]8*Z޲:!WAfXSՇjڑ8UjCGZR|5C*~h2hd_ҠΥ^6Y%ʐ@%\'tjǹٜ4Z**GGh\E]MJ nTC.kxP($.bD:濸A[A ^qU#]XE+mWIܵ t`K.obWC+"Q+"ƞ-E^! hEkY*Q _P|Ls!c3^UExW+T>f k/ #gLM4`(YSDR6$IBEՠ{AYI>7@%tNfEPY+5t*2'#b kBX"&\| b"\^<44|Pz_TKhgEopZ"cL,:.soY GMnBrh{; {XuhzS{OL.^5Օx$,SԱNcYR['6dЯB9ø?;:Y-GG5x |P&9n/ 0^gfU.wZ鬓=,4=׃ #{'%W)k|>BwPt䢔M&xi U|3$U 40[v_M*nh )iC5~| A1{a](ƒ{(ZlXECjjUCiNMۯy?tRwPגTOks{T0ZZD M9Nl2v `#5?)ͳW^}q!﹢xIG29P%- c.ed'9BNc[2 ogN#W++Ϟ=[y7.S=맡E4{i"4]['n08__NT`MPbkH,ҔJ ,~J&qGHJ7`.+-$|A$ި6<%GwhqZƃMH`7qz:md_cOEx͟1`'Y>D])\ŅJl) ߈ظ&uL?mߣ{F(l6*i^#xOSJSuHDojV͓8\"._߽'- '2'@)W:'>Ku^'kh|Nж,g> ۓsƠQYB8 ٣#.؏Oo^ܤ| 2џorZ Ty >C h3{ЪC xh'JұRj`޽6)EI$T58f}IRVZ0qnVt(9Sb}>gR[_YWЍ0]vk3wg@G.wSYܷCUUIUPT2)6;/!͜^B:H4}[WIRոM2}&N݈m %CqArwDԀW R/0-6Rf DSs(_侇vI[.;jɾzY7澑NN-zhyR1G3o ^~T}tf<8 -iOZOKPi$. Q{ -*h\Ǎ!7o54 ,Rws]i5ũ+\/Aٮ@lǬx`ht]֠aJ`G@X3bTidLp ůh嵓r _>@Ket!V(4$U%J0͎V74E.n`ko0WB~"f*~]FF'o_j@նȸePEV,NS7j{.gah*2h,~o| {m=ƂuȢg #Fv8S=8# pY,܏ŧ;<x>7*cEI)6V])%@}IBECnR4<N:RFԾ`yؑO!z, x#,u|n_~o~g߿yϞ^ҏ+ H8b!vBqIC|H:? HXtxl!n}nlkAs`J-s/`6V^s?oZLq; sԧ- ȧ;yղ6tXqfM?ul8|I\G5v+XS// ի <^~wtՏxmT&VFT !SLڟ(Be kZ=LBBVq,PYntRvއڵj@V[tO njZuʜ/f[2,%OV+e]֍.i@C ~Մny,ė{i錙vZC}iH1W>V>ŧ:s]Taɿ|KbrLQvir*rJJA4Ht=u n[\쵣e.`*ΐJ&p۽A {^!gy:%#jkyCF vg.^Npg]{(n4>rΊ[WHe'?e_grXrʂaL|!o;#NfJ$8+i߁@t0htlgaXrj?3]?JlFGFIf0|IC&Fl#\GN9bǀ@hC&!AkI  ? 3}N`@e]{I<ÍFf6ER Kw >=&|Wˢv"7НM/`JWsrIC&F:-U'~5Jil4i<0"5kF;' f6ih:tifU|ꕕվ7Z_ &7[ Ux4qH>@hvcS]CeрYem+z$ݷ٠]FXuĐǘ?3z6go6<_?L3?QC}xR;O~hH9Az`W&pVȿmHT$YÖIŠ}|5g LQs[Z|,+d.ShѲ2]¹v=*~~A϶g< AkVY$wɧI~xрG״kF[0U^o7z󇷟SfW]Gx挗O{.Agqf bNH":rdp;AwJ_k%_Pė/޼~ehVUU.#Nӵڇc⒫6Qע!=eu=W+?zO9Ϟ}w5ǖHNOtc#}GU{l#fsog_ <~Qޡ?wRdb3>"dÀڹh իfcCْJuܝqCKJiZ?j z-(!Q8͕T(VWQg T%ԮM{7QM~ܙhXUhv~eQxԞ}#xJw;t;gte():cait 8AO1|o[vkoG섺_RIzuT{"vܻ7,!ď,! DŽِ搾%:[ `.wb#+F,z?o_wx7[$a}RtRT|gNͥ\?UWH::[rIw鼵[FP:,0w«.pNc;F]qB~&rJz8K[NWW>q:=tYNg}ӑW_|GCyEJE%f{L,_`kEB,Z*VUeN|3mt_<{}\͌hWnjXuNg+IW?^C4LfڏX÷/43Ǽ 覼e5-4} wUe]+eBL2 ?T;ħFD䑹)br0MRI)^}K-OeoݻM*w(9- HQ],p^J1'FM۹0(VgqXS^ś/~~|;?dBP8X9"9f5m\l~r>:˦_{ CYOW?zg5|bi h<avsgN! SRcTVJ=,p@L :+t7 \2Hk7HjSĴArYe"Dȫ$YP߭tBRK\Ijjv4%eץdZ'ء!|-ph@cvNE[C:-~(`OKCc7=XAn_]=/B*Z_9>6, 1-#]kml."XqʝT/VW_}gҋ^ l?{5Ӑƒh l/+6.f?"+kcybgE[/]RY%ihhRܿ\o&qhfMRvH\$.݅qLFWW8"Az7MwA_/>{K6$/:$mA|"Ha)􎓒΄]VEfɭ0eV8ܡ?-I~M 9IJ2,ɍAY$ KyO=w/u&t2Bn#q\޾bq0 Υ$)Jyn`. J$"F pjis3?7.ab6<ґC;4~\eLjnYsciϼ=wzq.|'J hT4,И, ^V:@WkzC=iK9#H;$7s,XfI X&Cv;<0 ИҡB2( jYcE]E]T*AhGȵd^EX8#A>M2;>(n[=)y2k knob~wHVޫq90r͵Y Ǐ̲.^`%W|fݪVx0zyГX 8 x _ :oRKfH:WF?lt?web5nρVu!.J^9d};x<0HCf2 "YVKY瀆*۟JʍVIq&GX6˽]^>ixs4!(]01knO06XpcՍSI pƐ~DB;G8~)KI 䑀l֑'[`M\&OBp\:Lǯ;ԏ\OG^ZHwXx `e&vhRëa##㪀uHjr޷kQrA6ǡ\X U] o4Uu2&4"Kjow88yk]:cM.LV4Z>`CY^x5K- W'֐䙚u. Ű\v5OR! bREʺ=, \B ;[S< J0,6+IVQ,и܌]*B2dYt/ z'` ~?R]cN825'b'@1U`+z4IhC?fU!uv6(fXQTngA__lzfw=)&J"$\0v+eI:Wao?tԛ8y( Jgpdzz4x$.7  &S;|,܉\k.nTn2=ml{\.Iu\f{9t71*Pug[K~h:9^jh !̙^#f5|w3 m@;$eIFQaMji(gV}:6"v(A)((u%5pox5C螸i/ Gpi H֜I"f Q_?Kt?)atn;ez<;n K+ǻP'Wn%3]}ڝ (Mar$^ΌYiYdҁ7'5`Kz9śIo4`ww99nSA[9"0AU4&7Fbr $E3aXJ /$fUthz+2k], ޱ'NOiK ^C7[~ȜQ@w5q0U`$es_6|\B~Ҙckw8EbޫIywGI20馻]aaG8~/?ݔ5 ]0asܺӜJ"U4K`FA:r-F%YCFVF]!Ze:VgQ;AY'+>a1+KK@XRIX%G-f>m2n%X9;:|:pݛgS琿œ/ 0 5R\N}f*r Yq 7;01 v;MUBf)n l0d_gns~?'#JD!I/ae^Fr==qK! $E{糦mM@ .Lx2w6G!3kb%8WIէTɞ#|_SX]kshr7rhRv)w![ 88<6٠i[}FdY7``yNаw]p[$ȶ?hj"tvm4NTаζ_3Г63dqm^E#hs|FL JoL=! (M, 7?U[@'*η(!-Xj5})uC>F*i*Zq8< Knϳ!YK ɀsv&JhAr|999sRgN|O?S#s+>{L$N@ҙz=;45x7E܊ēnhHaHh"FI3sRxsPCV>0pS蓷 N[[|$,et&J7/T2_\fv+ׯᣝF GiY@20s6v .!B[} il2lI tgpiR]8R!N|>_9FBUN@JPߦK%6|$뜽1h[=؊h ^\׬GDBz' |7\FnҜK +>#`jtta͆vRCл{ZMuژpI˖xh9Vk1C]gU"/ ɀW~l.n Ej\jRV"DE:zzoHC]&ӥ˓`薚8@02wciVz :葹6Y88$ݒH~>᎝~ 7Cঊp7Pu0tݪG=Y1HwvS^K k+X{.Ἣ D=vwـU!C|}ŅIj/ ]]GriO(+k[*d4- pH.vmt:I'ր' N =,ք(z E(CH0\ /Cysq|;`E*.w-^_Zc 7 # wlNZ iսӽSTzcH|pA|-p}Y5%El/plX.rN1&eԸ0Ok/! ;cc4;9]0[]&ܠUbi"&Z՞t:!sA-bh(l@hl6|,p*BxeKpc(~ToLez8I0r#hhY0` QuVr%kT,ZӱMpT2:TFN6NPOw{̸kmgj!PZ8UIHʮ}sG-p^ԥ,7.# {pg.S2.r4jP)Y*:^S9Wlݵ]bH闔X!4v>?׿^nRL[fﷄQ]ޚÁq;u:gH?^_ ߂ ^<[I#{p7]qYCYPb1Z#C ᅵBvIp4wL(U+޿n0nStzo e*@<7鋩ӗ2/$ghF2$J_?~owG}o\Z6`<(9@$kp1 zj3N,0n8{e'D-fzƺh8QOn$\f8'HD׼n>15A.Fn#GWJSt,3Hq7N߽Sߜ;\%ekV0|A~p*LjVFhyF9Y9^+/;C f#RLZXߋo AӃY~{:`88ES{(`^o#Q#HkWAfcM'e9pͽ[X1 {SNE|K  vrm ^yaX&ҤK\V!NJbC- K? gqe\k0`:2{AG2CyѹFgzJp M[D im˱̰+l:LWllxl`\ dE\Z]D~Ď]7K5wH.$s!P<#GMnxC ` }\Ay؏&M;Ͼ5g_ yW9T2rАNXK~:A!`}g_=\0g0`aflmx;8|6`mNgqcZ:`IjL_2P;P8Eڸ~]GF 6eq`x fA 6'"P}::l^VIةёnUZLw=d:}W*Te`uSHlm:c+\UI%i9 AjS0(s5ΚJdn "lj€u #5Jdg麠e>#A^ҥ' 6Kn|xIMgZ*? 06ݶ9= w2gdILLny@zUnqs|"ȡ'*pOa8C, p5`|#\~^MW[ ~L` de[u 2D6˳CSx@A{h5]*%TGNS!|p1CV57JHnF{~4`ܡ6[l [ǐ H·g4}u|_+a`a;bAKCP-ҍSrjx̍:}=NYGj/iHԍH"i& ]gQ-m5aT ֦^Opϓqh4JU0(~7Y$8@ ~}󪲃f34ehﷲ2 )~ƿ D%8;p)LϠ^3utO {d`ql pacգNMutCZ' c-y '  _JdY =# EqaYǏ Isx Qp!Lo 1LX.g;Ώ9tR@Vn 9G#;mzN{JZލw7MX a Kr#@굡gt;!Z]߸K?&E*9^H3׏`B8$AonyU?7ڻ[V{K]߯38qހs0`8 Y޾Yw+^E(~3Q|x$`/XVnψvjʪo5p px%TH%#4i8HbΡxv)&s%d֝<ދsiW/M.'N‡|H beYB~y>gho ebَ\tj.;њ<}*`TE{cYEx`\| +oGwBz=H/:2Gt x=?em7m2O1:<J3Zww"ԏv7Yѐ_/\yiex^Fx@e#;z7u3I|~3Np-9*uIR(>s  +^ppJ=_v(˄[˒rץκͮsc^.9~WEx */IrWͦ\v*g-CʉUO 򱱓׵t$etq\Az&ADOkDҺʤ*>B'C ibVO Em0\X\'W v3Z˩ͱ o<yJǞ\M^]ndC*^ =E3W.(uN %mt?ص֒$EiF%bob׀Kf<7SH^ՊPӤ'd)Ma1 #-*~-i.+WUi!Ύ7OWtjn&.>P<{@Q.ڪG4}߇ D3_!( u}zyFBU6Tn 8HF)VlTvnʳTr M1|~/4eŊ=Ok֪), T%5Ոtlf*n`ׁ R室WK -`E|ZáNSr%k;&[d 8^,V; KW+,׮)>4;X(:R g5}})):[GA1`f&;rFƽv/w ҋ\Cjl-"[Ai)RV_j*DNtȺm p֊;U@ǯN yZ^f$*!;.h.;@)DfUge[%(UZ'yXD@LrԳS z9"ϵ&*qyV)e5tMul܋N̶c@1m12SthC~8SnҘܗsE.!|F^LzG tX+Ɠ.qV8$t]|ohS+,*tZS~hEХCd 7/[H0+X`v& JA!єGO(Z@Ȝՠz^e|5x @ZUo5d0ؕG+2TkCmAtĞǸI%( O+\ک@Gn;nZff緁&\I\hcҩTQβ}t:AX/ֻᰞ=:֋{@T鉴ӭ㶥IL,vGg@O* 3\'WSѸ 9ósD6ٚa̞Vn7 "̬$ "d%o;4S]_v GHJHAՖ TeS5G$@ N98B1 X[%cYOj?SzXW7' }ɠ=7^\_ܸt׌d٪$Wp 8>OJ]5ٵ{"9S3oG7 \Wl BfH~FDžiUɨ|]مb$J.*2/9Rb _Vc'&_= >"il| "m-Nr^}~4Ctks& D 0˺R<0>O|X5̧4`K\,Gͦ0|-=r s `=r ž (| TO2R}Gt( 0'ǟ]\|4WiD8mr\T&1V ƚ9U DWN5NH)o" ?׾ǀM%XQ-f<*~t N,8Jw CݡVJ&M~݋p@=c<; -Y~R!^8ꛦj.oXn'U9=&KhTV.F3կ҃OTZ*lpl$H!UF6`O)0&':CIkzFl[iUod8RM'K%|yVJrdx,aAg:ˠrL'hT4JՅOɪ{N`dmws@bj,EGM;l"x88a(gWgBwa!'G+&h 3H%d;qյAila++A Ea۱!II*P_h-tZӔqa]Ld#ỎYwVkGxF;|)DdDW/)Qt9dJ`-HDvڅ xN tuv0-Jiΐ%*`&ʣ@{Q !<Ó;ONEYŌf \'6ꠍGV;2c=S%܂@y{JSO*>߳^SWU+Ex@)uJ'\V$S52:㽎TO§4v 5Vi &P5;PoR`EAkBv,jvRŎYM__̢@\DX/8=2I6puckDo̔GS)X+v:x\CkwT!m' jk%(R٫c #%b-s1QVA!N;#v`]6ـsI` ;BV5'Ms"\qPpr Kƶ8D d/\4$5 &'L{15Q9(3R-FS"r=Ķ&`R(OiӋNlS|8TXN.K/||7kcE{0`#Sj&Erb0Q){8uXw~ml=T|`ce خfG)/`^)9$<_b=y'SL: T8eSI0*ڪfG:::&^4D3*/ ĘnaŅܮ$}#fxnLi^F/\H8;N;P:v+{vEWerkdEAhP` tW`Ysۮt4D8< 0&+ ]t)t_[.prFt_qsB/jϻܻQ)dF8܄f/XY p(Yq(N[9k0N: $D }Nq\%㑶xwW(MǪx\t[Z+5r>eC7 qjRo'bB0\,r0VL[8ħЛj rH0UI) $l8d}; NYG0Gvb-X*b墣җE_Z\MSZuF7 +p:aFrvQƀ=+1:;,kNˢP]!,}<)&8lKppoer 6"ik&G'l4I x]n$ͮ q ݹ\qxֵl0o`Mlpq7Eb 6bi$]9"2T%+32{/*3ډ{Sz1j{ %,{^[4X}C\ty^*Oꈤ0X?moj]&nv@\`w7ULl<+bpP9CP:VGeQ~:9dPGWڹ87CSdkØs?rO3Pȟ+2S׫)`][ #VB9dvߓĽ5EQ~׺:` ^oa{1j0i 0>|$Ӄݒ`nR젼m"{c`9ܩrfFҤ., ^d5z削NV 7^.e6 Mqҗ;.4`7Ui[VF)`pC*Bs𥷥|Y m|<yd(s$q݁$PfLd(N`QGN|e7 RN>)>ws^Mq qRݠꙸnHL_mwL9 0%4_7sm:EZ ;nppPo x88?sOzHΓ5|:rNpPb: >*0,lV͔=Yl66^j{'+=^hVpp\TE||!&tn{/͉eNPdG."\Ipvr{]fR+0nΜl@ɋahc\KRnJB{ol8'3u x:_gV U vpN7OtGюt}iY۸x|©=5je7&&JZen3S )$ AÍq{u6,n{fUpQUklO\r!JZ /.*dc˦&H9)jPp*cK0nc6%2rF7MZƠ͇6%OG0^j=0Dĥ,Vs. =Q]:r~8&ܣm?qCqko*YAR({m7粏X%X;s0 ǿb /Z-He` ljVBX8iB8JsـoB" {c~p !M}nl Pb:VmDmO)ភ|qFn 7͗(ƧCpJ.1߉ h|{b7}tlXsޟw +0f—nbS|'7xw6}tI!сۀ{Bm%-|Ïo$ӟ{繃tdcJJU;:QWE^o L'S?͙JT Ǔx3Y9 9h9e%ql7(qp/zcL}ψ/Gr UAcCjꦿs~A`Gp5|$E]d <~m oZx46ܽB6ڗ\) 8X)҂K_t abߏ"o>|+St)yw✕ ԌoҒt3m*$~F:Y < 0?uK3[-fG5v+0[AL`i4l019w] )q2}g6wb|) _1;EUc_'lԏq򷻡2gz^١df▀C  _="w2DŽ޾$LtE{Ki JAw*.0*d>[e?+&s ҨU?afҝܓL9 3S]Ox߾_wER6mx4tDxͬ%YßmLЌ0f)%t0UtOKOߜ]MK>N pkj&c-+Y=ױ);SjхNiQS_Fxijc?#i"d:k6_$y3Bnf=5]++/{*7_ #d8^Y(il&Mo5ݟq17{9~5KY-#Uk+/vh 1[=[pNj^P ܚ6a7n&o%7ח_[E7kLӉ=(]R/.Ày !rW `jꙟ6ߟ~˄0OBd3lNSCxH}:dW77[Z|L$xc(JbhPcig aaS~|\27ސpSfC{ҺƬPͷK<#1紨vBJOi, 7u6d{KH?ۚ} 7L0 O?L/{ n p Ba6:~[~ߒã@+; Wz=Kp|6Naq(A&"s~6ŗ |-—N; gfJ˓cM )u*ždo;&v \i 7 #u7*^+ѵ2o&"lR1~{}uo5Yŝvq%(p# 6JgRUNtMWU~?;9. Ú@&󆥴a\ q> 4w 4؍\O&K0]v$(?||,K O>>v7KhG( .6ɋ_W*7Jw ѫ@ȍK)uQ4?Di)nZn׸5BN't&;qX4;}xg̪]KpP+nZdL= MV{9~T i諚N ?(/Ly,۩-J}gS-B_&K40SoƗ>20Ct Gg+&\`|fݕ~)G0_3 Jof.c^B696Mf]t\9$PՖ@2q[c\d od?'iQ%f,J!i[ tb_0nXx3ZзpznA!Xh`z?_tC$8=ݔ W2|7PKK0޿/kO$feaʊ>& J:&G/SY#<6n>u$\m/ܛkNn|:wi|νߤE-{{EClvxoIox45i5i?vU.JtLe<!%rNVȉ"vpUC7&UcϾ)K3B}Lp!`[?7%:ͰquM}X,Agm0c,[y|ɵ4f*>|KO|٢*?'O='7=6nm s]]\E6 5?dCAkd>.R0X7+v碤ds@} >P<;^Q>__lc&wX 2RȉmM5Bݛ9q+EGn"ԖVvOV8.2c5=yl#խ@Xʲ<`Q]r~T? l0@2U!n8Bi_WUT]{yxXz!8ݱȹPZ%3~Q}X02d ܜDR})Y\\ ƭ^@1 <@G<^;FyƵ bYS!<[+S2s?>]ៅ&a ̅x ރ#,cnrU_$~WoXOGIݍ*ʱH0* J|1՘!ȅ}dVJ)|hncȌ\}4n#=k("fd;yDeA# r"뵴ŋ?5X+S'Uw'I[oa3@e:N)e|cBz^ &.V;S!{:ҵP '}c`oʵ(MI'\9 ]vɊ rݲwN+]V; t"n5)O.B,g]x|戡^8Ko ;>!EIJ9p'$P-[:`+*X웞J?/ûn& Xt K& 7馚+M P/uUs9Yϑ8.#eRk_)Lᘑ>eoŷ?SyIxUĔ)FGGF@ҘU[Dj %3-/e`ߗC q6r|5 &CwzX,6d=0Ѫ>p\1FTEIRXy8sk E-?5ve,}ǥ p^DLl7]e$vqibƝr{윬9>o-ǝQ0x󝝟zT=>8>8dJ #I(U$ ]%dϱXp:TQbDBQ3J$9/XJ#s ^Wh!'@i ܖ-?i[`w"ads9s&& $e[R J,rTEqҐ"!*kx_t蔐qx#%=/>;j •gFy(ׅ{de('N?[ɮB6:t }a4!8 tuׁ|hdY,W `( !zC04ba6 DZ1PCC(ϗ'`x?4ʞqZPU I (3{ T_]tS<l$RqXHXsG_N#W@_u#9sr3 k()Hd5LC&@5u^//fsC0ҩC'u (&%FwR7T(妳9`d x1"M F(:$4.JR5]ՑI*2_Z(\ vʀ= 9E#J %QLeFxe,'>osN^]w=d 5N5uI"Pҙb[k5oxQ[$h@ƛ3iX3~E552ގ%@I eEnM`cjuIBNdP`L7+C0h$X\{<^2ֲB[ yUkK#!+uhJLzѵZS+֠DIёjAVy?'?>MC>w ȱHmv!/!nmKרS0%ѕǻiUJZD&=YFPQT^S)ю[3,c骪酜2ݴFEd7rFGC#N(RN͈E>lNH|W5k(pH20#5++w K6_ }1@3(7["&IXO?N(7p"j(K(XBRۻa4|nPK LLoǫ75kWk ØZ@1UERM>K PjG~ր;}ƝuOV7KcpQE.,'UuPQl `0qNnr|=@-,W{=@IC•6@*| }VLJ{/ 0o8kScuU \Agw(ڳrR*j/eC&Zz:\;S5!/zKO x2\ e͟DkUXz]Afs' pvxX9)q"^wElp`d44@\676z/H(h. AB$]UdW_H:RH#afz*rimdjR Xu>E+DT_LzaXXҒXV TPLUD@&#TwO֧?Ӹ o5:!2ըi1^)HݰC"kz8[9KAM>N.ηax\J˿`P꜒ %z||,Okԕ(&rO?^GWx]fX"[O5<3Ir^/owB}HDڛi BpY>(` 6BzyWƾU6pKU G(^)O/kN@*Al뷳|J75c6m/1oOwkh pg(6D1pH9t*Ba*Ip4gN ƀ,o]Z'sUyw՞ XI%f KAa{JV:~ufo,}0 p+aakMSػ쁿.|:Pi/PrEغDG{:T: ۸>bQ'e|_|{acȭگ>f?z6`Zj eK,y$D? W8AiDPu`^%Bo[Oٽ`EV/tm{~ǏYxq h$ZкZ+˷Ǯ/Z_bnwl}Y+@l 0{(ļҰcC)$>ap Jk\7e[C=J:vÕvsv">=Y!#K$>o#.ۮ@iYEp}i"tEŏb[ kƯq(y=+kvIDuT(ȐQ2jVNMUgв]$Ǖ㐮~3!C`Rt^J$PKXgy@3)A3clSE=ԺKܑHl6&rW@ag3`)GIRY)}ak7j{v/dzKqMko,<| (sdj 쨾 BIfCJ9^F2G`%rmB㇃WgS: _n/JÚA w_NrPlf>rsF{h / qSjXbo{+K) Q JR vUQ !gwOo7i2Vwz'lBP"CYkBbSgPWrtmC/ U" _Z8X,vI^zBs2 %|ˉl%7{F@T6`t(qಞPJA=g}(9w^g\[S>)>ָ^+Qo^Iq9/MhrVB@;o~Ҕ^U¥_dJpv˵ZM_UU$UU[-`M" /];qe ps(4osۏ|> ǀ?N:&{NB^?Pz*IP D(LHcy$eea]fs@ⷷxEKd=xu㛖ލ [QGѬ %jp 0׶Ό.LZ'ZfIt5x$ -%? Ƞt:W=O? ŬUDI-Hpg2m )@ŏT|jԛ/ß }T!"XG,իTA#7:ҘoUlF]ZV0RkqS|@c] aDGg$I0$s*-wB(آE:~rσ[|GmBY- -:@*΀ [%S-U(ϣw74?߳z);QP)ކw\}( hB>?:zXJukeQQ?sӗ2#0 <8ZqSK)^{xMǛI/0`J{;!=Yczr3{c_q͋i鄳FsMw21=<ӵPJi䮚UV Sgo_^Gzupy=aEZ$JR({ڇA+[]'l2+95lFCP6:{ֺ#ddLB{y%u0/ al9 ?hSR {DCp!0ښe*^[ F M %$`6 3XO޵OzLz2dn8~K(d{(;mw,;Vve)k9YX{pdC*g'9N |@)F/"\S;G`\m^2"茓)= vJLvICbRz{DWQzռh怟q R]FK0> T0~=I=o8 RAP>vpصSuR6]xz٨$,XKe\IQ4tr(y>=F^)eogrLr: scr@}M*5qenBsٯ0nL)5m8U`#{\Ռx;>Zq'㐁**'R`Z0lh':n'Fo@K'%[!oyPz8t0`;5& BWT4^Aۭ{JS;K]pj>H:AZ.) ^*b_̢2^0c3|i) ,1޾ dq%_`:LIgWI%M{ ?P =F_.u=`  1 7p?{t"ֽt*Sm.):: %MV Vǒp%~2LgҒBA$i\lOgk3g˫' Y>#8Řp5c/0FCiDr=U-l*nZ`KxJƇb{NK۬j* ?`&x`I` )ppwk9'rO*|6dME"x:`M-E2BoH*hrG‰;\_ǀWIp)]<e* @Sloҿ*J(-EL9ʜcx╰sf]_+FQJ~c{68=X/8A$P!}06FJf6jdf:è@ՅZ~|V{42iK/Dp1RejHlE%R$J|ܧڸu٭do=ATLGYx&Aalf{n9~(Rq,9F6{kD JPlv 5F9;2{Ko;vX:' }wQKeVhEJF׷"9Nzxz.jCRwN2]kca>X! ?['iYT )MRq<ƒ(/s]Qj|<Ы'J^ﴬt[ÌgKDEwg&<886Җ[A f|c(~FY.UV5J7GGD#7 0kZK3m* _~YɪKϦAS!g 4'Ñ4N,dZ@P܌ w'yxw\W+n^utb`;E@o+!mln1J 6zPF@ĹI2ug?8 H}mˢIU?M/|aV%8g1IKE~p!C(lō($ERޣxo86k.eĘ l4gKKccb!~KY[1nq Ip0~=E{럺~Od-UatA'F8hgH,2%Ӌ>#.tM_ C!1o>c4%'mpIԚ;S}FyܺnWɹS e\qNzFc?ʴ+2~ΫI?x :r+Wu ծ_GN\fOIENDB`camping-2.1.532/extras/images/whale-bounce.png0000644000004100000410000010752212154156727021205 0ustar www-datawww-dataPNG  IHDRjgAMA7tEXtSoftwareAdobe ImageReadyqe<PLTE[fSvjzЌdմŘtHWeo_i9EL0wKPPrrٍwڥ[htz̥//y&P\c3:Bjtffh##'3484swyga6۵DEH9HS[TUYl`mu*jC%*2DڡALTP.sxḸ[q{s%w$x_"TP{*4=V_j#+8yJHdFX rȂq=enmm殢c[P&" mLB5Vuqp 1QDvhgZ@;0` j52.kFdQPS$LKP boou h9d..7kko eLS<>C [ \~~+*)󫫭 ~Ypssu:+02:Z]_cLPQclf)sIDATx[H\/Z Xr b+h]eyXBYK(AĜ IrBêA?&ް|hJ\1$0Tg^F"Ɋ'59ckͺIgֲ.;M"XwV? zUmK'ML$d7iߏ,NU儌r.B|Cr;2ݕ |B)bk(a$k0o@H2ߖgRߟH$_B^VB0iD)dbTđsƐ$ѿ"I qW+(dbe$.$io6^B@Jh%іTS' $a¢(KS*l_W9nز?CX |D/]"QuB:؜ u1vqgy} ᯞH9]7jEZ)_DXg'.LɻROY?%2$y"]?#3Y8?0E5~~r56A=$DJ8qOW[3 F~1)a,#t 2Dw -ÊFȹtwf;†HlRW|qGPm&erw T_8򭻬C.qOe +Îj٨XqG$!$ CSJbZ|1*#EY jkhr84fw|X1\(#K9C;-EΦQGVʊȟβʚf\j"mQ dM!lchMsH!=OsuV)uIB#)9"Sf}W]VmltGVB_u_uY470Q=PQV]=1#do̱QocYJUh-zYh"-rؘB-P()J0M}&M"r}M]ƁaÎQgDçO}@/&YH \߂`VRDy0dq(2足(Z!BS`EyPeBH+yTX_gNY, .~^$QxE8N"ئ*O,rURU \I$aeab*H"K% Y$_GbDD'ab=bZ aa"ZF;Nv97g9brz i."|EظɎik<|ӪPWpu)6V>(*BWee1Vf#23u6EW*&f<ɤweCA OAB\PCqfMEޔ"Ȕ+ " ɞm`~ Ddɷޗ1ׂ]_"qkL' ȳ$(AV,ģHƙCwTÎL^JH?S؊1x!$s%za" 4\%5]aSȬMءDO`d|1$VY粦>nf@|."flY(Ӑ겍+[s*3I3 pMئX]򥂱HddZ&\ՓQXwkǣ^򺽾:a8H",DcԼ2&,AhI]QU$&{Xf4N0+f*dj$v?t"1i[Bbu0>#'+e[YDBʝ)e֝ޑX7enK޺XDEץ䘼_sPTY"ȷ%xԹ4"Q p.n205IZϤ-[dDZ^˜_ t? Y wT`X 2^8; Cէ\<cAN@dqj( <'&r`H`:+14O E9e<5H-81%mZ YzdV`]2٤Q!Qh"@ AۺI>rxNS_]]MNm#>'1ingb 4rcD=2UE!$R(?& !#!w BlqK3w4yxSw!O0vŷ|mmm"Epc~~fx1r*KM QE45`֧/&E7$a49–߿2F$ၧ']ʿ(˄F[^?O`Wl}\,9Ѻag|;BB3"=o]w+QXP~jtUX7$=4\z42S Q܁"o꒧5G{!vYyoܻrE'~e/8_]+&'9FN77O7ol47yEV[9?fQL(%&lh# e 8s9❫bb` F(87T9?0>1;8/kpwE݁/n[vm;H[[$F{Sm- t$PeH^eC__6=" \fcDY{X0@#b2z(enoh(*G #♍!keoW Ë@m~[w>ܘXiA%dX\J]sΏ J7#(o'w>{㡰Ww/7;ÊP`n0Ϝ*/Ul퍜ƴEDJ2\'H[vF݈D2ؤ `{Ç?.Z{29m ܬo1 x++En,ybjww}t1 WFWQָh%g~pmeĂ }ft=e} (H'F%Uֱ&O]7***nT{+lr"o=Yh{lqyitU溯:${0@$uECGYaէ#F9QZJIQZvFO8\Z,s?;}@H{h9as g&A yͭCoRwDzChM1.DhtBr>tDR\>@ܽq<;n8*OQoBW7Zt.8Y\`-0x[-ƋaLc([GW"9Hz(H2qN"T!ݽ>6V4S1?MWR]I~?.䈧[ ׾M] lmmm[c(f./xdqwDb=kI$L9cxP[XV1Gyh(<˛a*bssa7p!; ?cfSff<Ѫ̵BbDW'T_2NM,*m .go@9m`> ^֝zZ@'Y%R{F8Cdf7#q{"m+8ov𕥩s/X@>{g$$ w;MEKƕ WFjCwheؘFxjQ}$UD";E6_[r}$0pZ%NHEYѥ $D&P0@ sWϭ7LgCCmghnk[`x0*}H[ۢtno;V_`7d#no<_^ [}+}= -XhV )">BhJ[]#(eg 2Omn}e1̌c~u#wGCs[A;#"6OQoͅ!M]0V#N2Cc2Қ4,366rUIZZLR*rX2|lwM錬@` u͛q-OE>ZWN9oWrsc”z8' _0x;mMS+<$,qF`eg=B(>u0/Uk-DVKx0-he駟\<:W? _%`BzJĴ<0800mir9ޭx`ldln 6ZjB6H JY`|k*ٚDR˪j:-T1L (b H*(o)w(GMɟi6Z#ErΣʉƕsYix}h469CƾKMV˵Nu C/CM Ym ŨR Y4q-]gN"ɬD@ fT$L xj!퐌LƆ|>_LOF斍ͥ E{ȿ5߷?]v9 s`z<+>v1'cPf,tp^M0S361ؒA: +r"}p`M3q" HPϽǃא7۽l(ZO4±z䌶7L9+]Ѩ+r&{Ub]` Fd-k#ss'%Nˋi;JgБYHT! WPgS3Tr098Q <"xxӁxl`||`|`j*dA֨("@ޤ),o-M+*L"P^e IHyaJҜpK&F}#HSr鮬E\ڋ-go  ΰ~/$Q }~㖙/Z%үiRr8w~I&ݢ霄m)<u:\vhqqU@+:0*ЮbAR jER ̆e|3!|f$aOEew;`hB3_sa$^P~vG6RSުS&dD}LkK+'eADcqnBsU=`{Ffhx}EC;\?X6`-is+dM2GZ*%A ͚,!%HrHR*~u #kO%o#ZR E.>oWY]Xp [xi BLH{E!%,}UDʖBi}RMJuD~ͷlN\>HVB'O|brQ9Q0,CY)1è5^`~#g!R17ɢȷ;͛1B,55~FT 7`6hnjs43>תxXd~D+qL2ԻܽTI6v,&DN`=bJGjFPzS)rRy"՚JsNjN::*\G6 <]Ku#lv?Gw~O+a*"=_@^}P99z0@?;>JTI[;{in  .8Pl4W:tNb|uQT'ňN W ;E;9dAku3Zu޽{r5jj ;?HȨ涒1jѤC%IzMbuf RZc*'!a֒Xj̺kUnR_']U)9DbkԺJ%<@TYwg:K?|!ҌCM͙[/tzfk wI-BgCz`*Ϋhq`  \sEY(]nX?=`65 nCM-x XfA0myH[ZO\SJ "!ԓjjoWbtG!:ykJ6njU-6Q`72xj$_ŋ"ҙONP5s"dq߻ /p*~=Wwv97${~=uL͇.xPP=\`υt{3f5^tHg3EPH}!RXM1UZ5IU?3 ImqX x  FsIwS?.v &1=!zja#X3b&`Ib0TlڳFL_Fg3^lR0ȧ<yAhYěn9)(^ 䝼0Ի';u˫ӞEX.`$`Zٌ}_۽7U6Ϳ"+kqgN8Sz0:'d-' Dt؃6B#M~&w0 !31#:|Y-79zy`I륵\(jS> -%de}k:5#i$vha6,VY!` F$XE?rȵN-C==y\z8WD}#"T@,ftAVeH$xg[Oc|\Q牔;{mAfpB7201GP$yˢיX/½{0=xygy[ zWeW"3#pV1$AK} [z35k4:4Jfn!܈s 10 :Z-uQ~v,|M@/)CP2hQv]`!%P>'|`4m9|Z|@*X^&v:5QTUqɎ\D: Y'?8dZMY=TphoccOJcn+wWVےHK!"w{{"QF&?m&;6EVta!L=,n:"Z$ ?bgɼ2D&n%`f 2Qc=|Mdn0Iڿ5XYtafĺf,?V9ă+=N䳬.;WTO 7OZ B톱w}#ΗWd+!X9LjJr*}incem4"Ք>!.X.`y6%D#Q<6y8eRw%RE"R.֜<4RGA¦GoEq^rzT#lLnj8 #>$3&جY2Ҷ e(-( ŢdEp@v-3ɔsP.KDҁ'f 2 x*V\!YJޓ5/ڈ P&7mz"?`D:Ək%B΃/3to7EX 0Da4}-vj H&jrV:IH 8kޢBl BH5ī?|s,m1m9kmyЙѼI΃D5Ք~55GCd#U1,Y&x&j'54ᬘh!k_*X/,ޟ)=\hx4N(GRU5 AeUޱ.D):7'2I@3¬IԵi^g- C\U|~l2A4_(wNxWZ`Fye{a'D rxù Ԕfhk`0k;`k3~ 5n2G#2 'aLh[6Dy+",H("I# '3hV5Wm,@Y".\rL$ OjPdbF*RE`XNy*oP)Ђ\30Ӊ''6e^_;Qő4CN1 @  ehk"kE ȎHkCLaK31b\AVU TjBq:6Ԁ:G+aoGR"\TYgut XUjڐ* @͐0G#3ơz`"  d7a 3qG8KUYի @[7!5 [[IW0  z kd+ڀƑuj觍}^PN¬*K ɨ<qDջy0i{0XVLV[DЃl֒V2,+6@vS$;9Z lB:U'.~ֺpiV"2BoIsf˻WulHu5JxT6˕3R"P3/Nj2CWemEv#yLO>(= l9!GvH(iA5U=އ 0V;{6nx̊x kas8v;ŚoaaaǞC󔈵r!`9\7ej'X!t`[s3@tdBMd-]+L K֏Lاn0'/?Sh(*b˃{8 b,cTMx͹_Ey&§o&"yG(j&ߊr(3m e.YZy==bOSnkYV^?Y>؎ ȔPQo*!RQ ('T<Go==.c{PF͔d3dM摝S(wu k9G('욗̱k@W"1гIςۓ`eƌ{zjtC쯻RBRs;!DOyhG}"kڳk"i"YC.Q(AA ZD$uPw/_!gûhMN :'WwE$=ޡ_p{ľS/lD[RX(':5vDF;+Dg"|7ju{(:4!(X"/\> * T,'e)_sFrk'QI˚`8S+ 6X }~IDki %KYqϜ$r.dbsDuVj˵!ƑRU 5*Iv9xN0"&Įu ;gL$V؄-XQeYA> K 5l!\{ DfPχĭ.Hs;>c+u`*'sݘFA.eMM tg[mwD=ggSuckw=1/ы5؉5y[<ƙ࢏ްaI|>k,.JP,?vC$Z΄T(؜xD4ԮPClB#~: a!/lXZM3sMOՊzIF$l2YHO^YNF*/Y` 5Hm3k9-Y uX<찞FX f#FLZUH,oZ's/d_zaV@Dy"$xe~V-FqZisHFQtq6\9iY2 R}(yZ0+@dT Pn:xƼʂ!lJ0D&ojo܄MWEDmj CL|O'Obm{@NZn#^_-j  _{TM~=^1e-9ɞHLU"+x["e2-yS*^b; $R6>*2H@-$XUuq7=k iIih+ uIr4ߝ/t'6!L[аb@A{@T{zUX8)/J#t]'^ة`J'Rhb]oZC9k{?SzaZ(sƠz2V!TUs/9B(.DJMmղHW93!ў@s؜h *K:siqo:ܙ 3K-$'i/$AG0lgHMJ!4]AX(.6OTgI5,i)޴B]ջF~¶|__3s31SQ#QA1dg2!)NW:R"%NK3E_؛ug=uGJ5We(»hlkw&-8_H\t;2(kV ZUo?a!!l`u$( 4_'&?+cw Cv1 ~19,ҏX:Fb$z-[-N$DHѲ l/گa I9|8l V[["Btq'YdLzŻ @1tO#ZGqsefHq Q$)'l9!Wd&Ofi@fkHwCݬt Rg Kpn"+'A$Ȋ$QK]Hh_Hq%6HR9&YiZ \ZiCQ(b9^uLlSQ,8Qp"uO; TTf"@Pf$9fŻٜ: g2TG 6Nnͧ݅L[>sRT2 ˅0)htF@(-GCMZ.<bovfZc6*:OTfCHxpBzm&KWR*F#\6*7;f);ܨyX/yK. nuR-yMn$ZvYΠ^N_bM_De{"q 3)~2 1,HV k x,5FawpUzq!7n,kw7,/\A7GNf[6OtT`{ SswB:hݤl^n!# Y\qRYT;IM?0#LˌV3V_9BDsr7JJB|s7ߔu?}֕ڒH9YR{ԃrP:.iM.~Y-BIQ z$gӉQdecPڟd Rc}…P7-Bc'+yb̓<' ` lqvHa\ @4&.37Qmm7A3`.8ub1mBֈ%e4tp҅N<&dIQJ$P 0ɵUU#a8'}r ##5ıy4gQur [(*6HPáwF$1*WΞ|MIP$\{ᛒI0~fD"Tr@%?V>hl[uk)aH);cCRYh \]HkI-5(}ˁޙhT#Gj}JmTr#EN1(j@$5,9#ZX,PfK~FڅvȭJm 4K[i?lvN"=yX.6v-' `sW5fO;PA$ uƏ bgVK }PYE~Q'tIv t$\$C4d3‡5yJ,ka &sZc e⺻C1&T#.զ H+MEVNZKrH0H(Wl;ͅS@?bn pYf(9.~rSt. ,gk=Md yx8ϖ-9 %%Nծ::sA}ZFssΰ;**zc~HM9!jZH3$bR,IEv6og WiGv2 9m@fjfaXLL\Cl0׹I."q0DTwݔ: (+zzknݻ_/o=n>.w LK?8_ .!=hqjx:S]IJEFhSjyA+4J>e='}&=K`?\aBl"y莢<=ZR%5ȳ8yRP^.=E!\aM Ń(sedb=H:!𧻓.{6CuuQ"r"s":2}4LЭǎ݃P!plcGOX֋r(}K^ɱ w1~ȱY`yww ecQf SBC04LvN , 6]i\J؜i0|W-!pZHQGg*&Euk&s9.B]kdD1oZD+0J $tZ8E<#4$r,~vǎ>BmUʃT D}j YIJ&Nplo3R緔qËGYI] 0q/'` 2!m‰QuY $$&+LrȱWEZ{SmfxJooD0rM*>Vtq7 zQ_AT -(@dyɞZ:yFЯg55Q?OB8g0z9Xu9I}T"$%2L=?ʁ°LoȾ܂2VvɹIj뺢$eqOV ̋Z_W#_1+%%GkONExzDu1y  22;lHf(ʊ$CK"eB 5L+ %=P(U%=lA/Vu 91(/`_5 i@TrXmr_Dp3bW6b>ݛ&a`JeEEG,V;uz{d/T ιY%ieI@ :Hc#[e!'LΊ`J$+rI@t( Ϙj8X=ڻ d9,YpVe*OeWj3ef-bCu kh^Lޟ_pmt8 gj\4{+~4tݩF Ʈ|J @i Y;gN EWFwv~\&G|,,Gax!;cl\JSsySkusYUUF$,"`{:yrL65o쌵9İ^] UXYPy|{G" @Idb};EʮbᾤzBv5g+v gY@Z--IR~p _* 5&j _HY@}ѯ^yz-Хi)CXŜ<9 w=>vMy1?(Dˤkj7SȁTj;K1/-XNSxH$g--pRcic oޕDRgh&a@vH\AXYLs LIGZfVlȧh;9'>~'kOt|BKM>okhA>xG^2XQ&È kP T#TR.S5CQFEG`;5 v|e2 zXW/I͆rdȾ4J9+ISr kйX։$ӌ]xd 4L+W~9sD4rUO5:NB#[buBmAXy Y lt9sFVQ+}w2_)Eiz>ozKśK6.Wx( w`ðhy4Vri(IaRZpb݉6rf!O.;YfMؿdttj8X8Xq:'VB#;޹M:2wNƃ`*T)U4ǰ(3\kߖW^gpS"NM*Je Rb14 WHؘځr`(PA/CKfXxzf(|S>2W: M/Cen3ei.ulfV|*}eC'f~1 U/WKV5$Q+H܏@lLf>ҚIIDUMAn@35v]zobs6n7m_xDێHP;hpq5̷nu/ tO *ӺD(ܕJ$*ڥD-E5=+*3': ss1싥C.rK+.TL- {JiŽHZ`iSY üpB-P"oy0 WrZe}@ O @'9)EHGR1_s4ݕNbb^!ӨwZQRqdžʛ*#Ec=BkǶFH5`-v ӿR Z2mn# ]ndX7"7GV̼"~~4H . m> Z:^{v'H`do r]mXYY!icöɳx,kkX gso4X g(1Z1#s.$ 9h Mr1QLu+oW%ڒ=P!H4@{.Lq7AL.(ći4K zW?^\}񂂆:zu``j`M`,ҶH6&A3#ss"ȫ>?Q\帹ȼAF=HTos%A,2TӰ<ڦC4S=]W M'm"۰ ޙCj|m;D)%/\Vܺ|T^{`ԔoB[/ F# me_ejƍ w9:Z1sՏQ! dd:CxDI *B/>v,cQ)MVB Lb#Sz(qO]A@%Njf$ B-nxe+O(ݘq(J3}u *nAEh\ʕ\z\hswj;}Eo_0%@j`H+z;I$h9\ hSwvx/D4Ӛjj9EI> *Ju0!B" ESiXۘ7J6Pm1! Nw^RK!\유9 fJnԷܝe4ud2YoCo}+>xb/9ci@M5wqb;TTbks[upWDҧ/'+/ 뉔M[!OrȈҁ0Z$/8(; L="q;pć$WR7ч#,(璄YJlݙbpbZ6-ج}*yCyi%X7Hy1y}H&CSׯ'dil_mo_xu R,ɡʛHDgK9H/u68  Mp]K:jY;uSO wʜM*^\-|mˋbEbb3 {xcc>w@訳rr%;8O~z:0TFF= $,؆V/ww; @|cN*12f$1A3.*X`vio][T>td;R|"-Cϳߒu2F0HND`FI3ZsIuT]TWByp^_=k|nwhi~>Jm W weLExu4+ T mJCnm1( (0lD+W?x٩?b3 ADb!R%u}abX x"iPƬ'b]Ų%6UV塉hRxO&3Ukcg_`G">/+&>ds Iԣ;tL5q|`|k30X%0 :#ki<؍P, W-(j5&xaVG= ɾǷb؜0T^XXXu6vzhGw<3V,𱻍|4zS~I#f10&UN+_U7F;BHlXǁ.|>EG,K 0 +Bes;e O|\rne@sw # :CKNݺwW&>9?OĽVfJ/0 LC* /36]Lr~AC*򻴻cҳ4*rv ͖ -,hDJ&.c0@ zOKBG*Q{!lK$)*zm8HD1orR*Νޅ9VpO~F뎦S@ֽo_X=rR9x҃U]jMWˆ$'dL4ObWQ1Z-c[%D pG|qӞHf89̑RBa&`Ef $ڡ(S]zw ܆FZ`<DsT&Vv7_9ExrDQAH* j^Sͪt䆚W])~Z'jbK&q^MR{T t6R mV=:nz@NJ:<ÒHWR51b,=V:T/wH`I(Q_$2Ծ;{ߞ?^B_|@ cN28PRipjJ04(!R/T8{r[J8=KVNمٳYB(ݞh{8ۛ^i8qˏ_oߟ[{1554v۶#Z[PFoWMpGU1PymCW7XfDPߕP.}W-buϼE_|n^~gDxYFJLJGS)}ֳC=y6}+:y>Iɓ>|p|9Y#CCi9;x cU '>|ҳUBsimk~>[_WgF_d ?~d7j6 6ϸ: vLNnT*S/~mڌldG'x/ vߝ_X^,R?%s{9E@vo~`sr`܀ܷ3Y:Q^ 7^nռҭJκ*?e/n}!2ixTT-cLA]Ul!YZ_Q'tZYzHtE ɐzPoQ]jñfIy %= %YZ$D,C*AjW/=2ԤئU&xy˺Ծn|m99_JMRG|ئ8%S*&xƥLhnԞM_IUP|Ϳ7z[&S.MbMS#R#Kk4 WޥٔCX{tK͎pҤylvUƾ2r@U)~y_£Yxw4 uJ֥ŇԺO^z+v`FkDӃd8ʩ+_ ]z! IIkiuSWFC De>Ȑz[,x9i$uIsOiԙ,U*$&qzpG!z}Zko3p:^3[=:EB S >J@4`ٙ:"aIQ?< ~+_M,D޼]0d!X ~`(Ґ3Y/_L6ᘆtBV}S$Gߞy!|EV$薩q~]qA $'Z0OfH"  7i$xlM2C=:h̠&%-T^J 4A+'uo 8yz>tK|`&A2C 0N#hyV#qaVQ5_8;{w=}Iot>8 $5K$ls$`tV } F0 A}RV$Ǩ?8id恬LSf1g5 4#7{Sѝ>< Fw>E&s̀.~F5GW!R~TdBłryzi26kcuK'5Z<␗RnSwsIVep:t[TJHImX{qq[3ϵE@budH% W }2kssrgG,~u[TR{xq64EAJ^t"BJx@zkzGGG${wʐJ64wyfT/~yيjMG~[T:sacQ-v1NjZǗa %UCpunܸNzeOT2]jnO?Z@UgwU2-&,u ޹NR4IaԜǦl(OuːJ乿Y;{O68ߥIbDJB4WW'CL$W7rܒi"lxe;<*1 GáH^#CZPnKu}PFHv2: HNm8ؼj[[ɚ4c{7\lhٛ<:!-ar&cg#P8l2oUzEY %=}ىl9[?b7r Fsdy ⅌&6?&b 7sR2ur<^ bWkrorbluө3ɪK0 UDVHf̕21sdHEys- cZ1g)/:xǺz^ $y%8;j9I;xH;v,:'!+%B,]x3Ne[c ;š6XUiB!u6;Q!`LVgn偱ݮm4t䡱Ҿ *ۍ&]BJi02hGGuk.Պ$W-d2LWU]Ŧ'LDSӝQͦv[tǺ5Jeuh&@PDd2EkaS⬦y}+m@RY{.\jd ^Xw<;^RnnDb1JXSd&KKIIC;WSMǏ 0HC]7ӯNJ±s#8W^㿙ܗ`"X4:ӤT62 k?y}Ep]2Hq懟dƇ[?iJĢ7n4&d pKlWjz6<ܴKFQ?G?y;eH,ĿxS׮ML Mml~=RDuܳX:H@[eW?o||u_~~ eڏM%4U7ީ?)CKsDG]WǀY;:kdHnp7mu+x>SI_jGvwː#ѡ,r<:Co R!ױ!Z..;6Ay~^EJ(ԯa>ͳ2$iOul,{=QratlbĨixd )_٪K(M`.Y,#Md5[Hvːr|[ʜ|r*C}|lUf+=}HOyhJaΚ"цwvjZ5)C!神PGuBۧyϰd:h}×eIXVYq>L&:i'uOQ7x\r %eH$`tsh>YuZ`Ѷ]wOGӃAZ4hhv7}rdzr<>.hN}==S7Z=q28։hku(/DS¬*W0NykQ]%R*2QZzZ:sOHhHtₖ&gDVO}oo'sWdrE{WM$EdHf{z ɔv|Z:*CZ6+`s9/YnҎJ~h9B͞(2 I I®J"Vɐ-  F&RxtOiAPy1ɐ H%*P{8߳io$C* 隟C3lڔ%C*k~zKʫK29!͕= @IL]S!- м: ;f(Om id] ̫0bANITj'bTwz waNITH-Aqnw BIGn̕2+!`tRU8A^7"! OU +@P 8kDr\M QBZ 4Jrv pJv"x^;ʑHy )ׄD x#ܣq^0%, pvy@ rN 'D pC.Pr@p01NK K92%҂jeYn`0ŋ I, RN0;HC bmNIewVQr eHPzi:A^<"('qXbcj5ftgLI4 A@\Dy qZr@nͻ.CV/ŅYpQ@,Ub8GRm @ ni띜Soqxe)U8œA`(%w1cI3Ba(NX,T2"t1! PA'fO9jPdA0r#wdip9YC R!Z@ͱʩqY  =qB1a$%ÂrA% `h()U"Kad ֶi;Hz W63>Dx՜ҟCXJTX9@(S,ur$kOq@r^9+`A`bq#3HɔT)u:aYIќZM ަPu39⢨鸐T;:-(0#+t i&!meae Tt6j,@85+V'ܴo E"/DY()U$IN(u7phXC^tq;HA$PX8=NVGS=cnK(|UIR@/3ʢ4^h02^7p q2sV.RmႴ7lAaIAĹ]XՐ$G p$Z8)`򃩁3R:,zpNM9 WAj}K(@²%^CŋpJt&?;DX!m$, pBr{N ;G(@\IirA}hΒo\eAJyY u@ ~8m#:r)= 8%XaVS\m7|:! rmrȤ/B$A(` o mT)ԫY Q%!A_9XT7,Iv$NҲy"U 2ʭB8l !i(`.M4ՎJ-e-nXCpڐ+8:Ϣw\ЉW"D]v 8&R\ \xvVdg9(!Fݓ#^ #]k))SA. :@ ,a$r@^j`  9'a;< dDS3`،:(j[?d<:+4{)$@ 3\VSJ)ZbT Bn4ꊻ(#H\> 3.pz3?#r".,N\i D;4 XP0א4< p*Kc f "'T!ۖVYNIz"*RFVWJRD&j)?Uy 5*K*R"K U ݣBʄZVV?NI&qUujH0/\U]r'T1;(aS-ꅔ{wEE;2qByO o!h-`2ԠJTi[KeH _ rHiyH2EZt:! Af W!pN8tɧd[$Q2)) I*%C- i>Lˆf* RjHL$CE$CE$ I$ I IRB d."e^IENDB`camping-2.1.532/extras/images/hill.png0000644000004100000410000006714412154156727017571 0ustar www-datawww-dataPNG  IHDRB[gAMA7tEXtSoftwareAdobe ImageReadyqe<mIDATxwXGE@A{ZֶvE׵XQ좢bwu-XVP,b/tP@& H=;5d2L2domkժ%BAц@)&8;;\@!!!?m]ADP;]6n8M_~A`aa1i$666{8q"͉pѣ( BL{gggsssccc٣}Ν;K ;r@ALzz۷v2D6$ѣULÇ3lqF///U9+W<~1c_# !]Md;%׫W13!nnn:}ѣGt]4iwAPa\ie˖ƩSKE׬Y97d|DH$&&޸q*e޼y{500]낵-Z#F  >"$\]]ǎ0y5-Z$;DU@$gXXX(J=]3~Ȥl$*tLtI~~h#,Ѥ(̽{Cφ Fe.FŋVzʕEi)pc}zllg͚իWpwvvvLwr?GNя'=ed<4ݺuS)0FI= #Vi&xX:KȖUDuJn~)w #ٳgFܹsT[.**JonӚa+EIE_V*jsh)콠+M6_r%a- .=w73j(]K_i:dY~S7,y۲=rc`rQ~lL雍>55ՕU6ab߻wU꺤عs']p]֭[)]4Vl>O;X"OHH6ȕRq|lu¡C؝hooϫy:}4M䈈?ߴi9Ű.$ZnApϥKy\lQOO `g 'ܕgNN?oD6}H)2 )>H3#E(sI`9.]b74f͚d5!҈O>A( V}+LiԿY]7nܠ9jkk[lY-'Ipŋϴ]#ȑ#iii" VjժuDm259KH!HsV3Y 믿nܸIȱc24iRR%'''+++J~Eܗ{RE6 Ƚ\n4k ЬO H\]HlYC\P/!$XU100Wׯ߾}CQP۰aæMhzyy;vAp#ٹs'&K. J Wq2Yʑ֗HE"RbHnb fe ۄۛ7oe$>T50ϲ`'sqFA;"/cG{FDFFF\\W QG6 _~E8Ꚉ5&Zn/[\ Xڔ'3O&F!0ދUyK-((?yyyT冁***4ǭPc(mR1~HP5͵kN:6]} g?l]^ׯ_{zzJ;xS?~ Wp_>_H:"NHP5͛7`tj90j(a r}ٲex wQidȐw[))]ܖ, PAVڒ%K ru~UF(ɇtW^2Kl0C0D 1{lw |xk@Ⱦ|&L9`)3(|NN31X(}Y_W)PI⶛ 딚)SFkѣ)SHtss8q)Ç?_dITGu Ϟ=|*Ut9s`h Q)/_8Nג3RFJ3ѸMvioodKO:/^J&CCCϟ?mZf|aЄ'@W >HAM[.]4sL5E ̘1#55ɓ?V3Bm۶i.d$! !c}||:*d?s/AGĉhY-[⬨(}'PF͛O>v׮];w n݂7oԽyɐ[^Ç W$%B6T_O|$<{D60Jn*58`<*;9?WTw^-bZ ~HtS޽suuZ>|Sm+++cc6m۷OPFFƍ7`U/{IIIR;aΝ;vž۷o뇙}v0'>}ZZ"Dy~3ԚԖʜp2%VVz˜DSP͛7:99RJR;alo!]vzw͚5‚B*1|rAQ-^S>BZнweތ9gVUC꺪fë0L朌o=De謀\x%5kM(}(5jЏL^n,aaaX^B%fKyIwelh"HC.M0 d}9d d˗|e󍜜9//`ʕrCJ1ߟ c*UZn$<ܻJ$(**R4i&u'&vbP[[[;;;$/^7o߾żLvhT_|Y/&. |E$D3gرCr[6R-8 &ćulXXN+Е+W?z~CxR~4J? ߅Yϯlٲ pGG)u5[uz+UjtEGԥJ*L:T?ޮ];sׯʕ 8 rO$G*_U};t0zhEX1cK&$CNӈ˶6+mv Վ!@V(}^=rh1{P)X=z?+ o߾AI:111YnH!ooorTѹ'??ϒ;*Wɔ)SP( (QQQRBbb"Emذ$9;;ZCg>,G;K?W%3gŋIG.ٓ}޽?EAɓ'Ç sќ cJ\%VjkDQgPr{֭`JAl}E@@vA.FJݼUA4H+j:$yN#5GMFGK,$ trr*L566*Xڐ=p]3e(#定B"Bw#Rzeƌ׮]17Ǐ/]$H~ч!C+Wjժ:\uv߾} о}{&QF(qI4u7[-'`СٰC%CuLɂxb1 _iFX@+Z܇HC mF :1f ߥKudv~\\\_N`2%os):$d7^_NA( Ǝ{-\.))Z$ V-X/>_ *PӶ_'C0SQ2e@_~I<#֭KiBJJ^B><xj:ҏ @UN:Y,Cptt$]փG0C0PD:H*W^e}.Id233S(,,SYGG=ǧ^z?>zݛ5oݺ,R"8HwjjjTT|gB J?=ʕzF.@J_.[ϨV乕-$^U /Y#bddD:f[hd O>HIϞ=֭K:6F;$$$HN"î^z%70d &\@G}`2  XıұI.k.}g0ɩ%KrCe1{K'IZZWQ/_5iΜ9[n%۷C$yyy\IN@+ 7_tiss_ΆXd*:TBYfGm[ZZcRRRRSSmmm]6֭/}XXdѣG'N0`ÇWx9ۇOϟ4hN:Q>} 9%8կ.r{1|SNJIe{… 5x: lC q1bB>rHsɩSB9Yx/_ʖ-v)A g苸k_`/dooo8qu`bx^| Sz. )f L`9R|Ԃ"a7f!> ?VsN'#i`&2>>ѣG M!ifm'@_7 S4FEuovҼys^`҉Y{nAXjj*fvw*(EØ'NOOOII Sϫ41xڴiKaĠA}6u_bbbex񂷷"ۆC}rG{dORp6!C$?K9 wj5j ǀE݄U0b)SZSKf>B4A$)677?{,jGDD(H+,,\v-7N:a^!GСCLMMNdK:Q3'^sܷc'o߾]pm}-&@ȕ~.=d_ *@}vڿDUZxċot"/_|ذaԺB>z@ 'mڴgݿ?>>H?$; $;1;;͛7*E 9I~ NիNt'-ZJ;$$$11Q$n›5kҥKUQ,8:D6BCCCM9̀'= 6l D9|P2ATL̪UR "2y/\vUG1x`s___%.5kL 57oޔ/_,7#uL1Gi۶mǎ=<<4h" Vx=hK.- LJKTAJfZZZ6?{l>LL`N~~~aa!ww'O>~'/ ׿ 'R!^B{QAvȫA*:Km6}*~@۵k'HkUuC_D 7y;7hNj o˖-dmZ{WBСCP{]QfggS;㍌519ٳg4-EEE_~@m~^$4XY"H{qY۷ϟ?Q,RL MSL]jXK߿_n)R#!,_$=vX)|QQQqqqAAAJݨۙ|d%C 0%@>}&:Ξ= 1l4lؐ8B 0O?}4`M65m33Сԭ~=DGG'''szH9P VԘ!K*Ezd0gLhf$[^|٩S'ɪܘ/_,_~!k[:ȑ#]GIKKK[5%Dw<==a@?~̤t辤,Yя =*G/ѣ߯R4@O?AcuL٤IhNFZs׮]Gf,H%<<|GG1cDyCgmP3}i?dP{rrr$.]z7n$e~ȑ3fX|#rG K?Mׯ߷o_EG]\\+͛`Çm3D}=tD[`nn^zu}vvvGMMMMCihԈ9ssC7";8TR+WVtJLLSOt6A20hmM)2`/ C#u_vZ={v>}dRU)aRECK, Bu>s]tN䠼܎X%lٲJ=z46w"zgdda ױ^:77[bڵk;_ZP=zЇy /jbuH  ijM PUٳ˶rb6ip/ܽ{wuuuu}^Hy)oܸq߾}aڵJü~ZvbPPPy漼> 0pGR]abbYfMկ_vׯcƌz@RRRɒ%GI%C}Dݻ۷ooʔ)+W0XCjFX7f߾}Tmzn:^%dTG-\0$$|Smڴ)[iv>":DWZUo^;:88JFDDd39DBRɠ<QTCEYf3gH֭[5j$1VVV'NСCP(4X"M0A̱{h >^a/*T0z@9ydh(%s$?-aH- e!!!NNNXD;P@߿v H<Ȓ~5jJVWs"NuJN ,,,ݠA|Ј MHHؽ{7+W` ?uޗ/_ ee{}ead|J_ >3PK.ڵGh8/^iӦZja b޸qc O>J@aa!m>&_2 h޼͉'ʔ)CIOOə0aT+ԩkH?s=>Lj`א7G@+++}555mԨ>9{  cǎa6Ϝ9l󤤤(~bĜ9sdɒJ233d>G[\imm}vEsHoݺ+C5g2XjԚvJC0 ުU#go!˗ǏvUT 3gμvf)ӥK0V0+P9)SFjO z%O4tmll0?͛7}}}\bllydxxxFF|dn߾kNt~NbϡC^jݻРJ?=޽{Ok׮BI+Znf|(#ԩ~Fdǎr O>h#L#~_XX"-Ç}||0KHLL ?Wa{N,YK;#ѴiSNsR̜9S^+9#1|sssRE Tg/Y)))MyRRիGQaÆ>7//Pp8qlٲsp͛ɓ'1 J?ˎ &l2??=KIiڴif3f1YVAG@RSS)Wnՠ|<'ψ]v.]P yڷo:88Pu7>!(8Zj%Fo;Nccc,YsCGԥQFfffO/_<~sR>|ŋ{ʖ-ȷtB&L0sL~n8q"8s 󳼽Сۘ,m۶I6|e̘1SLy  $-Z{Ԑ4iwD=.\@YJz *Owر4a0'yKfff`` 5555,,Zj߿_tCุ8 KÔC2!"(йsgN8?ӝ;wClܽ{IT_kԨ+6rOJ~k׮}ńʕ+=>|1b]voD)ڽ{7R C~nX"۔ăF >4תU 6@VZӃrrr0K7}b_dddDEEAC2e.\%U'O{l4lؐ& p0M4o 0'%%|΃Trk-垞8KA vj߾=~Pu"O~MR)و' ؘ6 ˋ& RNn\ewH@%&&ROx-}|nn.è?_v ˖-CG8'N$xz{{{رc\MS 'Nسg"hkk566fqzF K Kh䀀jժCP/N d(Z[=uR{СSCPGތoo${yy) j(SN4iB_4nܘ4^cǎ\z2 ߾}c!ر~eJ (@`"s]L>pҥ/_?ӧOXj>2_g^&4wW=#33[|yVVֆ ʔ) A f"x-xݩSի}vLD)ׯ7008rfүK9I&G焅z֡C>}N:5..!( wP}ٵ3888`fꐢ"O@;η}||ʕ+wA44iӦGGG8^f椀 ؕ+Wb#@G#HJqPu,?YYYZ[JŐ!C3V? O<܂!ѱiӦdgDDR OCgGRRҜ9sOp~~ѿ0Yct"L|C M_eȑ3g3AYMd%J=ta1a&Qeddc"PΝ;n8},d>A$ ?`/Yٳ3/<үm8`jj %4lo??9K<==Ɇ 011X"RrƍUVرv\~֭}C?ea dCA|4E>}R 4po/ii߾өzy>Lќeܻwoܹ`#('?A1.*vvÀA[hAƤUgO}ԌaܸqzF5,Yڵk===_AuTGGG ?z(f;~ff&|b9_)gϞ-Zhذ!Yb̘1ZzȀ{`D%&&bfjA~*J*YJ"w@fff!%r%̼U ˗c#(mXXX۶m?~lKmf48>˖-<үKN\qk%qtҡCRݻUFRCDGFFB>S*OmTTy#(ŝ5k. 61 4;s…^z5oޜoV?333ڨݻwA>үϘvժNt钰+RCBB+4IՊ~@탃;e}tI_K.R{BCC&J266fXUŧ8}7J1ONN5k:^ZX7Nz=:qD&аlٲ_n'eu!W`;w?NIIaT@?ަM8Y$&&tr<\r6<,~~~|Ço۶ 6w3fpppz4)钓j;ߩǍ +Zo߾fff켸8::ϋJLLw^TTTzzz /_>dȐcBcAAA--- xRB(ŚY.\Hm9r?%KS~.]D9s@ᯛ<СC6jHRmmmWXE]W:I<:6n^`jj Fqtt4S 0Y}dd,ٳgϟ?=S|/zxx4iƍaZPkٳFQPQ 55؞2eH( ŋ;w\V-.ZPOA;6-{u!N%޽0} !}du)zQ|y,ųzA]!] (:`ŊժUӧ-R#?qСHݨs"={yRBɉڮ[lf͚&e->y$ Fvvvm7#??K||("##߇F>}D豷R pSX>X*կJ.mnn<#E~UpzjQFF7%11q oZϜ9ESR%=z4 ~q2eʐmC1Tk 5FIrvvֽPREzOjj[_KK 888i&** +W8YԉZnA=bT:E2$#F7of ps/Ԝ * f)5mthc7nׯ_ӧO%Pt:;;8p )) ,ƍ׮]{̙˗/[ѣ_zEW;QG3av'aaae߻wo͚57nܸrJ2+[N3E٭,bر#(,,]K/-n^ݻw߲e_թS'sŊPws8iKᶵGn$ZkAs̡)QƍWT w͚5 Œ ֧L4[nŸ,_Arg? E:w\FLcrH?zԨQqqqnɔX8ŒP`EU4i$11_0K5Ǘ/_\";rM6Æ Sߋ S~};w(4uTOQ@7o,?55LFih`MIIR 2< R@QQ'$C 'NHT l=z`c&_~̌/_y @(Y m7o"-{ %ݻw'VR'O޺uK9/ 0rHS?g(:f-Z3<%++래 P%|all|~->>~W.]4U=Sbvȑ#Db_/^=ٳʕ+cNrd&|\O8Y^~<CC0?~QI%{gzn߾!D722[~ׅ b'GP`?&hfϞݴiS~rriibSԟy~`bbbiiҸq㨨( ӧvڵ0e",՛[TT5]dpP9880r_Ν;~-|H~QR7nLd+1"dQFk׮VZ֭[Ík׮$?t-Ȇ (f͚`)=GN|rѣG"9 @Ք++4ؐ @ ߰aH<|te_~}֭X8pe˖ 'N ҟI=I u^^?'Po@jj*ՌC.JFK!ꊐర0!D~4i(5\v[/@(SR*QZl޼~ϟ/)԰aiiLvN>׮]SꇢL -m|a 4>ay9sV^M!RҬE8*NR),`G]]V8~ץTɢFbN:k֬yz~֭nܸL^:L]#G̜9Sͷ\O!PBNJIE #5j899qu+V dKD%ɓkXljկA>}J6Zjfr\\K" YǼyH`>ej^v rIREs:*,ebrX 1+W| gꊺ\eȓy%JUeJƠedx9 Jn# W繰Kʕ;y䴴4j'&2Dʑ\jkkD h޼9_jU 8p"߿_PngllWN,-888>>*m< R.%r7)wCCw![(T,Vv'`r)4iwһwK.0%d%_wޱ^zj>_f{K/O֭ၪWm۾#sT@L.?WQR> :(.ëg}0F dAV?ihԨsݳgim׮^bәX,Ϗ5jԩhūi2kӖ҆}.|7o8p`˖-" a њ>nݺN:֭06m/]ٳ,Nk=""GohhvRWXdI~~ʕ+MMMQYEH5&@wfjG >3gP:66Id-Z;d`Ν-AГ=NNN߾}c0 ?m> 7д(mRR M a,70[v3\ > TYDT^|֭wu֭J*MO'1:E 5kְ5##g0{ezj0Fz^4nzٲePP43}sRJI ˗/[|hsXX8yfuw8f᜙Ofw—G\%~iBU5WԵ y!E K. 2XiJ߾}i߾}{ƍUx>̄/; &hzsq*j맷8/${-ɝ7nܰc݇g'/)Y$#y(;;{֭߶mJn~ J4ʕ޽{wPPp<^5H,ZHiErROAgD_jz).O>2ky|aҥ pŰ׭[gϞa޽{wA<}@ܹ('^~M5D }PP|۶m u#;;q;hefCuriu2ǁDDD,\p׮]eʔ)W\1}}}FV͡&7k,{uOOO?~8!!֭[үh_TT5' +gDw`mm 0o޼@x**URڌenTŶq-Zx9ŋo޼133޽ٳ9cĐmx]t WzXϟ?_xQ$vNJJJNN&Yl2tP###0*TX83`2#A*%Ă%&]r6}~}]hsss ɝΝc5k$;v2A> FAbV6 n[tKBL x@@"m?fO>={v֬YժU#;MO-hrΒ%K޿?sL[ű&x~" dKLBrڣ~ “~!QQQ/HMMz?cgg m.ɼUArRWK-1obxܑN(}.D.EI-[PӅYӤ>|xРA999GQsufh9<&Ni* L9LiMËzH_3®b16gNNNJ:wĉ---1ODC[?B&8"""bbbJ,_\A ;wtqq -Z?{vo!BE"={>͛7ǂ!^^^ܹsݺu1[D􇇇_z6wԩ9 +v[3nի!>E2dرcϟ?5 )D;__M環uS4]D)< >J 7 .r׃J||B1۷b8eP%ètT$C 4H)u mʍSmiږJ\QJM:귳 G֤@)==}ԩ(m `ZY$ Q<40tH~VRɿ1C/941vް-'NNNu z FsJP) Kdgq}“~UPPPvvvZի1<;w7+W1bfauDUR f>HVVkXX۷oɞ01`QDD1C-WAOa?5y- .z*h~S;wã}6l@K_A*&&xnR٢Nj&ҽN:Dz//>r{{΂tcǎElYV֜ܨ._EpxS=!k::yV&@5PpG?}TJ|Yp%KZZZh}o`ދ+W(C_*y_ҕoU\vaN '] 0`ӦMM6ŒC,|KaOСCϝ;usss㏷oFGG'''شmVp+Dnnnf } 2ԔIH4ܻw1>9ڹsgaO0!$$d۶mرΝ;8p:k陙 999wޅ=O>-_SN% vv/_1 ~<++>Lxx Ο?ʕjqr娿?.**sTA/·uֵlWEDߡCGEFFrsPPЙ3gn߾ 1K7nܸtҋ/&ϟO011ٱclt…ؑ >HJ֭{],ճׯd"޾}-|\y>5))ĉ߇/YAA j>\`φ޽{8p&ߟ;w۷oo\\`+V TPbyED?<<|4O4DDCf͚mbIEDݻw~eBBBzz`bԹivZlQ1Ϟ=ԁ6mvZ,ϛ7ʕ+?~d]B*U@K.dɒ 4i҄#00pʕ7o߿?NAM>>7o|'hٳg]tV^:o޼UbYDD;**ׯ_[a[pŋq  /6 Hsrr233wڅ6).?|ϟ?wuu\ !+S$^]fw~,,, h:pnAP9۷0>|o  E矓'Oٺu p. Am7oh;ٳgyɳfͺy&/_~ٔ}yՕ+W ƫl={vaa%׀Dˊ+"##5w5=9s'OD?3!/;w͛79_qWvQyiP| bBIǏAw Vt~rrn;?i\el8 ,sYaVCH@-$ ,!2# hh-A5¬VfECc޻n{۽9s>{7n_ K+W]t: rFdWFx?z׸߿-Y'f=j}LLLvv7=ZT:u|Juӎ?600p &MZ`Ajj@Fu9***?N=t#K?QX"߹'NXd^g@dΜ92 ɚ}@Rݹs `VBwؑظgׯ_T3ooo?? џ9sc Å ~+|͛f{iTyٳgGe?p@||۷u!$][[N3k&sᵵ=jxYYYd$@HH 333.]:|Y?]U*/]%ŅYYY~~~|mZt:]WW׽{0P7[[[LuVÇ@+F Ųe${WJBBB||͛7G.p?l^{u_V,^x޽}~ٳ߿/..Bm AbjGyx{=* &={F>u;jԨM6peDRZZ@/0/_TTl\@ϟ߹sȑ#~ #FJ䓳oBk]իӦMٳuuuD"000%%۷oOYZ)$aAGZ'22244A2O<٪CZ]YYIA_[ '"%x,wtn X+Ю82k׺m222ӧΝ6b:50+mUPӪw|ѪM\\P477Ϝ9pO}8 ҂Fu?KR̊F}e~?07C2s0q$7mrt dأ~lܸ"&L`t:u W+#,]91bk FgU?~&:::,,S }5E]O<ݻ AAAB777@hX>'KKtX XhQK?A3gѣ&''oذ{ĐZc[ uPgl|SHRñ)$vG؊X.3&..ϏiTm۶AD.[UA$O,h`)Grcc)&f-MثR Y>ij= `4%H5 ێM> ,Za ]]]EEE3f̀kH?X `\mܹf[K5K 5Vٚ! tn O>MhOoDQgU>&MIt C1y :Cf[6id >8ۛT]]ڊaoӴP]Zc3^b5;,O DaweeeqK[RR.1 q3k>񧞩9Zb^ P }㴆2T Ys^Y!<Ӟ17߾}?qE bG Z. K m}"n"Sfg~0s:f~ǡ+w Jڵ -c03iͲ^Z ۦn-V5p_@áe xV!744]Yag&d1y&ߡo_D<"'\ YYdv)Ȣ_YC5f(JgG@t{6,BpfQQ6:onjd-lItdqf ؎΢LD&odgY|~ Z{E\my#mbOpsg,8WUJVUJVUJVUJVUJVK})&:R*W%UAUV%/ʬ:5Mi'0WFn"_Il*\BqI0Jdgm-cjgek^|fZ֟LA*_NbṞdq5O"ыn?X0q6W9[,v/ vY5l}ŽJ #'k *0vyk ٫mF!dQW1X7ZKP>,}0_A֖̬gi1do'U CNlr Kg .=IТ3aC;, %r)d- ]H(cPBqA2AF-YJ5ŭX1t , QM*ӥ]ۍ1XI)2okO隑)%).#.K&q{ Fb%~׭K kdrY1\".-SvC;n'hDmn5 φ)X!VMmY95Ff ߍH܁ 4er)ƅ,p Tc@ onT3wkUUZUZ-k_h,@V d-l0 S{-? `{mBP.Wմ.x%+ׄMB+D AO<7PJ p4lىzoDk?A.Ďiv7E5$hBIU1e 6GŵMlwX'vڊ,$d蜯mȂ G0VYVוog JԄl}(7d5Rc+%y%;gqJ,906H{ƛSA6]xc aj1ژd :ȮƋu#.Dݾ"Bd Z:m̐-\ 3U!}A5Z3HQBB`5UZm:`ndaH0^sV&űdD{Mk"!ҀV(.: Ɵ4 Jed/2Fətvn5,^ n#)<f3ȃLjjQJV9dԜɂ,4J6^foLdsdi9˜eܘF:4)L"}"IUZUZUZUZUZUZ?`aw17IENDB`camping-2.1.532/extras/images/deerputer.png0000644000004100000410000001140012154156727020620 0ustar www-datawww-dataPNG  IHDR[f gAMA7tEXtSoftwareAdobe ImageReadyqe<PLTE U2t+Z3ɨ1$Z-fس^k3g&p. W/'b*a22pR\qX.[1^-.ƌXx$lz$ķ~@m%ί¨Y.Ks#uV+)E|XĞ,٩ }oO4+W-~xV3Ty5,$1.ZGt4ӵ< 4h8ɥ Y%&d9ޱ:a#["ɳT22Uh]8\7\/]02~.ŝT% Y+`2T%ҬǰGe+TX*U;2^)b$5q&P+ ^*9qDK6W8 Q,۸ ɫ]{ [1Y/ߓIDATx[ضhqb?(FTi۱)Sj-vNŃL_kht̜]5ksBppp%C__>S;L0dftzO^<1>`<><<8?@oeNÃə?`y^|s8_?:awunzEnG*,stt{tqso|o7_MmF3A4Λ4rLٔ$M$k櫑/37cX ̳uhm" (z癞i^W07GG4fl\.EIo@4Eϧþf>BגsYC,>F)dc!u0EDQ.q|qË>ǛG%Ҿ?FLht'yz5Poڠe6-1%ITjB"<z<}:D]iQGc_z-[iv- $OtSXQ1ǞF{.^?͞ u;li/^\"*ǎ o`!_åLO8-*7m`kZLb7 'q`>s rJ5]huE򎭝'{%0Y-XEX.@h|Eq0v{%Z̀ѬeN[KW?>f{~naۇ%7~40ۖ,+`l)~O\^Ů~ew&ٍC8< }<_Ỳ-5ܲXa,ÜlegК9SGz\ph{/=ٯj JSgc?IlBK*4TCr陫c@ۅa#`'D!q}ab)uEzĊSy]ܓ=2=Y ̆&9]ί{S5J,\؇Ǎ qq@pK'0pV [6b` W%\|;f>T"]|]/<ړD 2 D0ʒ$[u,Şir= cvOKBDZR>ڗg0s)K\|ff$D>N\fxzy*f8k`* e"s9;B\bX[MIg{$6ƞfwl9A {ؿĜbg e8np^̞铽e̶q( Vtq>}|'KK[*θ  \췷+mj=.+*1fi)]b%rikLհP]0@o c9ڥI p-9ᮖ:TvxяډOB8}CYd ɩb ̞21L?G釤k N#/E5қ=uO}7Rؘ%s2o`䄙GEKyU|?޵ݴkykZ%.q v:3 WqHB㰞75p1L Ыu_~fl9y,\!{ru5oB6Rw|O|źakv%f 21вZ7^7/C,MN@XZ6pnXT+v]W~;gyW>t,+iF=ߚ^ ZMԵ*27CuR>wKl¯ f]NJ tg.%%\r\,YM[{"6dx.u^#k;;|lhߏ=C4mǃI\2r%S|(quX !D$X.>|4Wn7(_HmO}+(`Z!48AI4m)`-Yc5ivUfc?O_\-؎ ;Bd ZnP+a$˗>7LU.<ޭCMw!": kZ xO9/;<l3f1g+yPudT(Z7UgK}ړ==7hZӦ)-~Ŕʬ!A=B"<"b;ۄ稺аtEXw#ŽR{6B]w؆M3*C]=UBnͳFt($ח:<;x~u24eՏGgoz ;]ϜVɑy{egݼ Rs=ݹxջ^. {lC99ƻv`ǃ2m5mTLo Ш5$0AC;ȑ( GH$|gExE {aEP24saϣ !azcw9R2Z hz Gx ܓ|{ J2Ix*lz0[.'Up/ژ_Up;ai% E5y&p߮')_Q6Sj1Mk>drñD|i#IX͞ sCd.1U2X%\z'ʥb2a4DH"tϨJzV ri1µ5}WU/pQ8U[lpI)PU%(*0!*Wr Uɦdpt!9b f$RIj:t J&P2  Ոك} s>+ڙD+JTM)Rj}9nНIaD" `D(,wTpG>j_mfQ8\OsT2ICL"r+ !=Cq-NDB!t+нj4U 9K=Fdq u9˨B R VelTw (x8\f b-D`Б5DN칕b¾ [@ɵc-7$ b+eHZl"? ܲ2@޺)A1pk;p LT6 Su')-HXo_ 1ab"Tj "ɦ4L|RT'nC/[̀(0+ 5(j(m Ѝݣ3t[^Y(C;kgbDnW[ńΨY2m@J`{z!.TP\WdabyJ!E7|c&&G90:9p[h#WS *`WIENDB`camping-2.1.532/extras/images/diagram.png0000644000004100000410000010566212154156727020243 0ustar www-datawww-dataPNG  IHDRgAMA7tEXtSoftwareAdobe ImageReadyqe<PLTE""Tvh,)&&rrrs@$MKQQQqldžȲoIF%ұٯY4L㸸Г4 {W4Ɩ`;o=;S-Q,`[)qJ&ϛL-9'?݈{d>[4xݺ K}˥ $a܏]N_艧ݕv؏YzVF]!^݂VGڳ1+ o_[$1\ n?nz3<Yyxi^ :_$ gwV YB罅 :;.vw6 ]plyމy~9/FLv3}o+QO;=?BwX3~/- -zminwΖˇ zr ?KqsT=4|>!jƿ9St=o&3򍩲8zIy=_do1%?ٺ x??g\ynj\qv띙mhM{"qxxj )2;x9p;#; /ΘONuM6ukj~͍wCԟ]q膠> q[i^" Yׅs^]wy%6n w'Е Yt}ya5CБŝD/&\$x5Nb}Dw6v+;',\h3b𬹐DegX1g 0x>wnYA΁!醞qN{6/t8|sZf(Lu>h DL gg ;XP .iB^ӱai.r{vdTHvwO$!UNDHǗ %/ wxQnyA>xaʎ͞Bbc t K/z d6 ›Gyiܧz_Wo$;ٵJtttq, z[;,Vz>M;F~aVc/X<39TU}V{ly&\1aݑCA喕wv zۍ~G /Mm 2wh?W4Vxf\"4zƙѫݕͻg;uCؿ0m8#OHA84.uwYλ]O_sa ldo& x'g+n@wp6vK4wVv+gf ?+ osmBo߿Hl{ڵx.wu1sFߞf,Dad{|}gnH8Xx/`W;3%*/=]E vz13p#/Ox>IXţUgy$ [7XK<=4l ?n$6J'$lodlz}gY'r v$ۄ&+.-U߳[㜟IO,/lB6^]yxyҞ}:ހ;/̦.lHO|,4W&Mm^gx UoK+6Ͽ;aoޛf)0lo8 OjW{r(.uپ/gHk]tqL/Ϡm7g'7z"ʹb2PɯW(m:@<5l:>u z0NY'6l4߁/e›ؗm?yy'ۯ]^=8;Mk^*QG6$ZX/pcr6%^rv{r9n;?'(pf^vec uY7~wK{ߏڞ~)Ý$'Y%~i>.7UK^s/]N=qii~Rsc-?o?6ҷghҗZ9;c ]csxeu͝'Om~{O RCo45{o -S_#/ w;EM_ml ve5arsu[|saug7ymB _\1vjo?Lx!ow瘭!ZbV^#?ǖ;A7ɗhɤ񕦗ZɤLFUZ˺&ӗh*˪x|n5YǃϧdM'x6scQN_}XmcKB@4#i%$ 5KA-1wNO͋uzc>l7ނ_ R$~sgCf1j:}p'! I;:(3Pcl:cGt F b3.揢}F`eN/σ?Qt_pIӳHViIѻ?[;|n绕~Ϡg~lO %n#юqE{ 8~4u 3W=o[&kv h膓'j=ېww?po_ B1>ξrFxiA.o- .v4%{p L=\:FG({F?~+v?XstO#.RLTzfmg G'o vNF8YcI5Oڞ"=SM-nI q~//uo_Q`%]KRWNLJN>\3`DzY7sIヴx2gcIT{2mPdt>LxiMx}^ i gyfm~XC>j%~{m ēWդJ¨k F]R5ԴAbt9]SwC+܋cXy >Bks3;]i=ӓs'o_Nø+r6^x\B}:J|>" 5z+ff\PEfl:)3fUFJ\/@~ν|&Px/b5MOav90~mFwt"Ƣu Xu& n_S GλO_ !U+#{&!Id0gd912O &F^0OI5ljQ\|nR` <_l|foMO}n|ΛM;xF"GӪ1<; :vPV*TUJZe2)|-{uC_ ّ0b}"?rPKfX+̯҅Xڤ26.+f(?y'<($4Qx)+FYC7I_W&#%Aȉ8Aݦ(#!1sb*؋yz2r͚#>"_Bo|Ҟ}tNqp bOy\# MkIx};嚘N[#')2 sa0_֍NգX m!%1Ad^W9WL&|쯦&ԫcPI!j\خ)IuƧц؛^]fJO8caIA e02IO0aRIp Iu aXȪN|^j-WC0v=d^?]6U/Ƴ])4Fo- $_Lӳ襆^v ;1,g7![ޅ:'xC.. ?,6]9btɒ8$pVO%L2[b|k! "몛s)gӊ b5$lluc=4#=$N4rP6I"ozY/}aMzjp#? /Qk' ܪ _$f*}).`1oWHL4TcgI؇Л~LS;N:djN(IFV+tD6I\2(zV’sjWo 5|Xw"1`7^TI?$ۀ){+)d39Y4dL*RMUHHa| [!XȴjccŸ`R5X+HL!mp<ܙ]慙Gtt39玬,yEQe$n16#s X 50dKe̘R M6FR(c6|FΔeKHQa EζY+D#sg']E5Cc/[,,/jtAHbhf?=ĽM+gr,E[ YYI؂[Y@=;;}k|.Տ}+ٵ]oHÆ:4/ K`> &nq#!+dDPs(*_-p&c$p17F/1-k$$#Ve,ޠTby!4s7  ^II׊^Jzx{m7 ~Zȶ6KjFv؟`0RweEQe(R.g*e؞S!d(CĂՔ2.V(~%VFtHl\Ve:. ȭ7TI&rу^ۏv=)?m{xtXG8+frsW27%$Cےx<مooK펰MϬ `"x\ЕZ!VI JZ͔>A@)fTAUTJR,:9Rρ":g-|BVGM!~޶`߫?{?y/OHbD/z+?Bu&䆭o8e&xW:[e ;r39wsx(K e.e?;%'(sMcL@5 _ f 3H)T]DEqO31W[/|G6}>xO~Yxo\"xlje'-q7Jn4^5ӵ{<$KظzmtZJ4~WJ:P9[༬s5bND$`O^.@/"^q`QTK l+9&/?!{?ȵ'p{70btq#RrIl߲^ZqEN``K&S5K>!ϖlZ~W傯HzsY۟}B* id\@*@uAOe &c;mub Q#; iC瓯t&{ǕV0@o5.GT0R8+QLDD^aeAW<Ų٘I:m@ &- 'ϟPd2OY7c]X.?9}t7,i0A tAbKpXl=b΀?W1.A&MQeEm?6 ^1x}l|m<ٟL_ |4ΩUsI}<(Pw?>xt8*K8N)Bh1U-ѓnBmm\TSq.ovlEPX dS7ۻrQpozNEl-eU1anTɗdiLE-~x@N;9$tsWݝMʤ)@g=̃!WVҨxB8(_mo@~:.~({7Z<}`tϯɳs\7P`\]vܖ+?T5P {P沁@*>06ڍ0y6˅Du`NtsaR Xˎ6ݧi&@aF"8S*#c]d-S9L $A/PS^wˊ[v25=j4g0rXA/%^-GqթT"[7P*ciM}WfʲVu{I఍=Y7<'< r{-;XӻаdgV ;>!zWsQRYz*E׳ ' SGx~V9"r~wcdZA6T@'FNr+dޛШXڶ}ԢeLL4ږ*[k-]d:ϰȳ{Oa<%dƃs,RDknfԈGȥGd 7Tfꈎ⯨ۻhwLѹ.\F(jБ Fx;IVքx獌2cB?jڈqs9*yFq^L%ayzuN~'l%S?2gY秤;=(tzXr#&>OLG݄_ެomzn w soz~ VT UK*TkiMܱBM :D '5,B: MP(r6F~fz|NMv_8Jx̹޶_~aINcWyjIwnaS)yaO,!%MJ;YBS\]!fjl|j}fdooHOWWC, T5TR q UCMtNpLP V 䮫W; 9 O:)=,KtZKJҤ2seQ a;sp~})r^ט3p.i1?AH dsBGGsGg)+Qv.}j7oW8 qJsp~oC5ݧ":2* ~mIt5`n$#) U67ϣI/F߹#TTQD4eL'ĬRhxmbTxZG'sF+uf VOpOuL Tx54:͑W-8D6 V͂[!1"ɯGr8yt^= =c6*X"A)cľ<ϵJd }!WF^ rC]$Pǥ4UԿLӫOf~x33vp14{rϏ 冴#v֫{yڻGYGFnv߾ýܝې8&CǐNHf25EԥUT+%K3j9;tRR9$u%i՗nšH!E_Øjsskg"$]?ؙ)㥏&Zl~ <2@ 57B]d+p3l*LMgbWZKU*䆃F-I K9L _P'qbݱ$r9eU&S|*"4"2=݄Gg^&M^dŷlnrR!C:ηmrXzEyvIs|UP4Sű8rbYht\#hFF3bh@3d]IH tk2ؓ *+2ڤ ;?.T ݍU7|0HJޒ#W^t Z74,,T_df*玎oۻͭox/DNNG4}5֣0B.td__ r;bu^vTzɤʓ \~,MnD] *Pݲ|d&`q~ܲOyIb#PkU2V!OT=t{$~ާĒJ69DbwY񏥯WW 0!o<7ƟϟG*3-EFEI>MGaK)Zxu>^K"C L)%yV\җTJ ]*d+ 谛aFgrhm[LڑfxgWYIc-;.H H sKq6:PG墓s;*M>L>ʘf)!&Q'_t\eEk5%'^}!AvHsFlyYdPx»“a0fDMދIF6ڧ`;_KǧQ8kN)/=_;=]nb`8 MO^[Qh:+HgPgogWKh.TtF^)heϢZ W VކSd|4jq?E??";JRvlM?fW_i#YO_5Yn7d0&^4E &;8wHXR^5rUɂ\FU*7'_f 6ǖz 5H+`lF>k rrmďyejﳡfmGof|ekooK$ڬ#GB6dGY"K~1FC9_ͫ?6W˒Tܗ,NQ\Z DчR aT*$^[\gl*DJ-S)ܩꓱ,S<'#hLv^Fwϙy__ R,juHSwx)۝wJ`\UQ5 +,&Nr*t&eĪ/]AܴZhHީpbubERP 2J0*R@Jb2kZ|?UI (@qZHgC1gaΥ7o(_A6t* _#cʺ[?%~ 'p(k1Q #Rt(5, IBFC@)'Ǎf5nޕLGqD JF)v*G ^BQDB2zmɁЏi臱 ۫o7or}º+x|4 >W]XW [ɻ V0[*$h^1eIX+'Ҙ2ii-K=: f[zӜ/P(yms\]Z|=&6ߎB>ݖəA Y*w֗޶j#KEXJ$<-HT{ǫ#|;ʖAmL&HJcxQBLVdt F1۞L2Rø|:Ǡ+j-Ã}\=@k)zs˱w{LGEbomޞɹ!i[ ){+I߼"Ib]̋sW79 t1br&V)QlZU4rH3}A:𥆉ر Gu>=JQ { uxKQ 7Xhr`( D4/mOP O>ə9sO?q1 ;)h*pWBj7j _9`?&v$r;Hk:_ ̨Vy 1*eld˔[xPRt=`0$ j r$<;MNƳl5|sz^kc=Q'}}wo'^_9Ǯ7Squº&)HxSD#Qh)N oۢ$o(:^Qڹܻ$p(CeXYA)z;"tPjQ ˡ]7m.d0:,5Tq[[066*8$29z8rj Ң3mG&]g›J gb)=m{3y1'g|pwy'~~ۈ6D4WƗovUj 5h%z#4>+٥{[wB&&p$3Z*) d P6j&+t"c †`4$j_"9N55d8?vfcL/\79ls_ZJ,%Nh.5]J4ֵZ 'ĭŨk8w&x+f8k~4`%<.2&PbE&LC!JL$3FM+~Ti>ʣ<ƶ%5:xH>C5[x j<@>~ @s3er=};)dn4HɅsc |lH[-oOR^oO r% $/ғb<"wOe\*ԥOEA-sԅGQ5p0K+5]=Nنw#*\0WCaZ= y6@f~dr29K%[8l7m-`ƨeCܸb+f1djFZ-5%{m1uUwsHu$X $Jiz F) 6LAJݩbؓ D07~l3{xoZKBaZ!X4RWAB 83WoថY298.یh>xU~ 2 Uw&rKDӛvT!Oԣ-܊=O\¸Vv/Ƌw),L" Ik12JAk5_1zL+԰"F&fn<1ˤ U\: !d72^r5ə!3)ox/~lc ԪT'FFa|&gs̐&¯\jo$>xq+* j$zMvF⌭De3\+1zPQ ;UDNޚȹ*͊NQnb&'F&'RCٕJ/v8Oc39d1q:125^6G9[Kҋ"T =QtVb7w^E xx\= LʨrϋgȗQ uq{j˰dsz!F5oZ{+Q[!ag2*fb.Vq9w#X~BTx&gG.+:B*P!qMUs~ ձn6^e_DWxgs%{**DqZT`!vfE:.dL:dvdwAw/V~= {w,;Ud @cBx䬝Fs;=Y_^?&d Ωh{PY\ kW(hjxK^[x 2ۄY)+$;SH_S,VK>]N'UyAlb1Tgͳ$DZL ,<75a۞4<]Puf 8-kc渘GWCAM,\s=ZOˑ!"{-ơyz&:>F)OpEV`*'}dŰʫ7E^6p8Qc{vw^bfrA .Ι oS)>vN&fa+A aUj\.}때 j^y ͏5r_]= $pɱf:6P T.IHpa;$E[Wx̺6$e"՝VnUTGI 2QK(n=-)>ô+t+1+y3 Fy%Vb{_ÚrV"\ԦÑM\-y[Z-sք{~?h_󓋶:9rɅsJ`IlVorUB4[D>50t[p~N/6B.~~K^t*}TyՆNz 냵R@"k< rըQ"צ]+Ra6܅I<_L}_$v7.ۚIm{*+X3Da" xep|o^a9`XC⺾!櫾s='Z h6 @<xsepQdD3j\Y?ƩiW1;VϾ*7nW\ 8UgfS[Z弌yT\pl~ ؘi睊&ӕmU=rj< Y\CF`e_8%`TGS-Ë_{Kyܐ ܩbhLCp"E{X;r[Cdq"wpnh[[Vlq5+f<4M|64VCEQ;KV{Y޺G:oSgGwLg׫zj蜋av5%Gp8c:f?hrVv~O1O}lHO,Z0uJ.q 7g^lt|nnp[ 'q?{RzsSO40+ JRC&)({~Yyp'tY¹zCk y3LTGi1+KzR^ _+Bx]=v~ {VhI5]YN"FaRkxV_wI _'GIit1ItLQwg]S_,@0F&<I)=?>;tr<:;SW~#5\$O)SĹ _<[ݜ.>qz=R }uugN$\w=}ywOLܧkFFj,=|փI\rsƹ |φ ׾C471Sq? ^w ~t .H}N^y|3YFsq>d皒ilKx_r֝aOoܼໍExJRB~YRt$yK\JP~!NIqzѡfuxZ?u#axouG;S5%Yr :NK~: Oa7x;tKR ;fsK.iMCO'sIj]zm_g2DN+ NUwkӣ&'LУ goC^o9<9/N)E6;vk|:]qmRCj9{ow2xkoZxM{ːNMRT=]I 'ɶ7ț9=[S$mM8wm%>pZrz\:ܖ$g o8ۍvSwoCϟ#߇we -t2d;F}#OsRK&0#p:Hu tyvLzѪC;F]s\ѵFޏxd[3.oKNȷkH Nzwb +~KLD;1'}_lޝ[BpjQ6R`O;*owtK DFC,QX'pڮkXť jPl*Qf<'z,CRt}Ȭސp;:EyO>Y\lISXa_8bf0BjQT^@JED/QxN$do%֍smcې}[w#K c@Ge<2hᏅzxsy VD"wt}iZx4] /ރtD÷R惧R4u~v_Ñ92nK'Rhz1AuIc!m,6)x8B՛=k~d)bA[jZuS=x|!lMrbfxoK,N.x?C^/TۢG܏ W=w%i?ﱫv{{yg=1mF>ҷm%>?D6<6;K>]v0+{|xn9ϠyWrE\Rېni/1/OVJ8x-l`lQ(vzagӞhkkWI_&'*2]?"]n)Hz]n/]˜A]kݒa$N"oG&t|q\7[=ۇ {Vgþw;ݾ_J|votwy:z5u1Fq*9u=|?N_9$wݏ\q;zvkȼz~7̓WYrvq;.)/LS-9vI:OdUw:uo;fgsN}$k,К-1~?w :1oP0mwԿq\~=bfl-ҳp3Vi7ZFBH?RKjoџ;"dO\~k)Ue?)`t Ks65ؽ[ㆃv}萞ZҚt~m;uoxm =a|i똈imʾdon6/u=If{>FkI#%ґ%ꄻK%ajw/ĹVcao#o ~NN?{mQ l!DE !#J)OeDl/>\f&$s9zٙ |o=͈ٺ>hYVC Y2}Zncxle60on h]7Ie:U,KʕrbxlXrxewlwEXu|(ΙϽ(fi}P%CbrvD<ݧԝ,q{[=r19U L:({!sg[' $v{-*!5]gכ~R%Ep'k)o>bSҾ=YW늒mo^D lЂ%bhk-=ݼ3l/X[Z4# <@/IJrgloƋHR b$+/pw!%GϏGHw|S3GGʒIhѢ>nß=č(o<3]۩qU9սyc 7SN>;&~fDbh wqNe @teUp:689B;f^wg x;Kp7xhO+۪vPf.qY<27]XMx#x`EB}PpuktgH,,5n3l ~I%O&m*usޙku >@> `y{^=PBo1pOI\-˪,NL[JiEXW_X{N%j˻ˑa4/dvaoqn}t&p+W{6氭dWHe`%TpEoUNy cIdTæ-ܷwEkJ<Ouwz/K2G\c/xvc}h\7Wa+fntV7:w7ݒw|Nd^ƳCVg,d]9@!Ŝڮ|3|ÌwsnHf k>9clO{?H_}_U -*k)&Ef8"KAG_"`\̾f@Sv!ɉ4;/>ճod|=xd\47'&IL6Yfۈ.Q7T[PIb=BbG~%QG\Gz{;Sm$ gj[qD-,EO1`oQfPSڵƏjK}oӾFDP<xڄ<ї))?y_߲WҘEq& # eo"~>&آZgP47;艎:NDUA8y>Xs#i^d{zڤNV >y30,WS hn 2~>2rV_Vo˸w<̐IpΎ7-`EGM] lmUm5;.$+itoǣt+=w+wEw ɟ~HЙڮrnUsXk,͊j[ TD4kXH!ܞ`;l+yVW8O<Ȝ3kWyHV߯mĎ}S]+g*mEqE4nrMY7 Z4ОY-o"bj*i L 0?WN#.:_aqG[k+p' n-^c*}B{77m YN΄؟!OL/(`mWp|=ݘdN(j4cϹJ=jbb'.I>^y^AUdeUYI1)l^7Y]Ğsϯb+SMU &!RVOcM}fgX}[UUxme[vUѶ6S~LaҌ%,khvU0[ \cm6ifkR!DI.Y[sB2e|mQbP_Cñ/K_X}!ߟ]߯\,0,V2ז Uī<&U$el%ٺl8]S~S?!?wݬo(- l ܮf"2(vKEnsYv}B[ߔoΑkz 2kKt]$CNF#ޖkZTe`)3IuB*h^;xIѣR7A o[!5хN#%5U(516 W2I#%)*wgYW~s\l=)#l^Hj56щX\+)h՞-H/uV4-͢׬/¥GM.ߦQ_^}-NfA&idmoc F6mβ¦ F?ZK0Խ:IߺW\!덶9w&|14궫'j+QtRzzI뵧::?~U:4{Kë{A0 p;!Ξ٧toF_hG^A()2Dۍ40vKі\ʤqIwkliwymiL'm ,p'Bӕؙ] $F?D<6-9\|4^^;Iݭ[9?{ .1!<󋼶W{4bEol~c*.;(w ucf,sB~sB:ܘY%,=,egzQ~?nPX:jf2yL`DNXyW<זP{:oΑp'b & :'ihs}@K}a& RrGH_[dہ) Ft*  f<?fXw)=1>-I㖦@ NiNўtP܀' $|y as| ?xrOny y_1{#¦>l0={^A0+#d ͡PNM, Hȓ㨎ԣ3y+f-l &t"<3 6J^Z(s| m.9,4yLmFR9(~?Â\q7mߢ)?䉝<`&@i.6j.$3&ʎ P6ltX>i9!?8mZv |߁Csj7)qttip6ay ME a)loIq{myۤv\_~yG7R{OӋɯtk Wj`n#~j=dhf dBswYij>C |mu3LW{tmUH,+9b 7<8x;=])V^#QWag$16#wa&2y4A1k!=>;G+qS(W Dꟿ$6 1zuVA { V#HO]NX[FVo{Rc 9v=ڽ?M&Y˩ID{CrZZ*&JQe ΜNL-\e9u}8nTA_A+<ƭ:[FL)|,;s X Գ$j0 6Dj^N8(wYw1})r/ݣ`_śJQʧ貭*΍ʜXL;^*T;ےgo'yCKo €!1=QDw^?{Y'0}w\鯏p5fڧpΙviFSzg]Vºpğ2Eti&p>p#1>sߛa XorT1yǘ $rh"0 xl~ hz4[X\gs]3r5r9zAA7ɜO~%>w 6&0A"OfY}c\J _>-'4,{yE.[**$[ ̬-1(8̷ËRL}rř]$(cv1qPGw[G$P? ӂgTӅQRΌ>ǠQ$ c}UE}^'r|彬|JZ qn3^ 8)[39j[HǴ{@0 h \߀q'AG1Ҹ1^2Œ{ϲȚۻ~n.WҍI15?#gR@4=gWhu:[Wiљ!'t٤anաpJs9?FXcfڷSo!Ih"8;jRN b.5fEʪW ^:MP8F^l>Dx'^@>ltj3ّ'90=aцCC]D !N{ Z%L]o|m6#9]O5^:m IbCmJA8{ -}t:AQx'sBGuuk Ow^-rs = '] 3Pv`` `# <|t, P {b_'p`T [)F #49(\>':sT݌}oMZ< c.d|އ'IwP0^o.09 Le <"PyD8 F8NNG,19.=RV AA2af`l6I_ΉPEm< ÆzZ=ϣ"$eeAox4ޚ\vJĚ:{|5;47v%yl|X6P'}:]U14}[xdj dܡu.l}mGx'qrjm\03a M;n2?U 6 ۰Inos̃MV!99w;C,; \.݂EВj|V.2U/X0G + `:Wb@ * Yb^`wqط@>%q +sv.>u]T1lKwj}ћ\WBXܶl3bctMy%|;PDNȲI)=;l]svBZ@O0O[,RNob17ayyo(>ĵf&4 yW yLĐ1 ב]%OmLoB3R:Xʜ;A6vHl 'yQ`&D?<6om7]P*ĶsjZiotn9uR)gR2NKy'.yFAc[ ,2%Hzح\``ϰu7x5V .hEr!U/9T=Xȷ̒8jwAiCM:O^Jscς`y}|h gm;ZD Gљ zo!\;~E',ς>7òWym=G9mk/_}3hy(`c w:ë '+ޅfyO}xuR)U'CKxG" 2*t?=m|}w?Dԏ@F<2l̃]ɿEM#m̔1M0+d g$9Y/UK'! "eWb2$&}b wCdjὦyO/Sr89̇ÒaVjȢՑXw܃浝`nb֥`.%f9fe?R?xdG IՓeE=u^B:i3 `kn*CF|H c ] 6'ƴ6nItQtk0tG{ɾc/BDzTՈV+ ΥJ ɱVrO5DX`/[ Q; о`%ŋk9씜c„ 8<r'H̪w䚩.`>+ 6`JF4QDo~ǯ/?HQ:ty^x%t3bElM'9 [yrKǩ߱<˸E\R@Q`B8CN$ȈNB~Pss%˃K ̬@yL_UЍHߏ |O1<4a\<;i%<17^q% _ Y$lv5IAl~9'̖RD3Qs} ԶʄhV喎8Y(K,LgS0@c?=+KK*>VJ;\e f 0M56` bÏsݛff3RsOt[x8Ulͳ.ٹذ`m(/)H?ՋHi\o{+ j5^s5PDn@{^sP"1^P(@ZcmLY'[l15>К\zk ѓ^AjVCk.y$T-,BceT"Kax2 1tng&;]"=w5 |)PDod7T,G3vQyb)G?-_v?,K 48נY#bSvZD?l$襭^z±*B.L|nc"΂UN1hQS4ko5C P(P.j]84x~BOY)+pKi8U]N oA[z]G&芖,8GB'j0% [-G_ [ 2yh_o=xXN`aoQR Tj09^Z #1]KHzK %u^[$WW[IQS9mzc`Ci7OS05U/~A񒗢s;&,?uPl-aK|QѪ<t-3V]c<$h^ۣ{&_rYȵ1gZXM΀=ZN zc(\4z'{Ymn[qΘp} cU9:k&@1(<UcnϤʤ+5:ҁ1Ө"ȑxk{[_:ٙm&1h{og,sjW!mvo3T°zӠYu T&|lIM]Z] s;jEPilx"kף)=iZ Q<2ZHҧe&۹DIA!Te% 7-WVo(}V+Ոt'Q臡#:7<MPmw@vYE\{ ^K`XŤ[ X-\njIP:QuA we{w`6ץKaY--i_58><cA5<@Hvɾ4kf_%jG &\6|4(~y ۡVžF|?gʼZ>`x;z\,+m }ЌKvͨsnwQƚC~3сz(gOuD7Go;]d%aͨfpqT ֤_+ ?ՐQTqvMO59>)c"ð111u|BBIDATx읋ƑZHBOĶ78رv=gזWrv&r<dsjnI $0B)K,K) M5VEn  'ƅțoWb?}*{Ǟ'*9(W #ne tjדTcȅ=kA5= <;e_TJ%RN,Kтg,KzS-_(K~g¿1l?38e<.).VvV!yb0)>,&qǘ@K8}:Urpb9W9dJU;Oy|AIMgJv:Nf.yR%O,nſ=iy+ g׼4p(9ڠ乏<Q\ſjwlFr9Q\!qO(ebƙW)63 e&ĄXnsMB,/ZyrV,VE踊1Ǣ?Nu`I[A^(WeaA?gze"4E20بm; .t83 Ï Rd<^eVKbPyP,nqywQ}Sz5ʧ~aUktp ܸ:Σ6*t ܐ:+#pȅY$E.]e]9$ 9Z$hT Ozuz]UU_]'I1 Ϧrol9oWl֫5XsQ8dS MU]6 YӬj"U^g^ #Y~M8i<'|18)MX{1x :svh!C~5)F C²}|HV.W*=$6C?? ;GRKQ5<8Q6M"nƼ>_ۡE4E=!Jc QDa*{*o[l(OfvqО 6 N$ƚع ~^S/MgU?Gv*Wئ \edu66EYJ+ItůgĿRՔɴ|?\9LEGL%3,$-9Q%5犢>qtk4j)u]{HrGɖq9+npW7Ȉ=sF'bny\L|RۓϞ}k5ƦyyMߞȽ+pq*Aכw~h+XU=$j&}|Mt$bu9ΣANM#\|D80ՁQ㒪ʩ¢S+6YtĞ$B7wLB96[M椫 e9ej,IStBy|u8l iRrZom)C)у=-;0j>&<*5 ?d tb{;@7@OQc(Z[xh~h'~f#uRCIwǚ=yqIa?siA2z{Jzh b}7Tgt$LLCOQO2n#Oґ"4ҼbM|Wfoh074:S-ܩR1DKT+ҟu#/d2> p$*MagǐlyczrX3[<洏J[x׏f`AJzV=l PV^N๷h b B1Qݟi\# VJ + ϓ·!,[İdm8t:Y 67dԁ00@TeGL.M&Fm pyU܆bG0|qtLvRp ţ3ַ67/,B,+M+RWDu\([>!z/{ d۾&Ɋǧ ~; R#VU_}pJ"-H  VUW!'qNVKrekPc}- yӁi_>Odg{KW<=V=fHIHAͯs4n-ˏqjV2U @ded/SicOFE^X$U$@\gp12>_h&@q|\}qȞI gf+ԑb.s@N"L5`?=41Q ǃ jܷ"]aKJÄk-C-P<']${5Ap)ꓜCplUcx[WCN@hO05}.h&E֎#69P9PTppq]{CIhh@ lW͙lΐ'b~{ L"4\KF6rሱl @^yh:Lf'z.}ui^КRZZ4VG! ß$h FSzدDO<hi. :d}A~N)91܊wF ͓ ph-Lƍ=~c}HMp8 CaS\yRPe^r@˞fo ޛdGAzh0؈?)y44#2Gy+5IbU8?Y .ox+ qsKȁ@:Q̷(hom+=zS%vD˚*o=iw'2d,TAnѼ^Mn8>Df)="iEKJ9xj8Pjb~11[wzVow< z13,GvC~*zz@Xnh{ߒq.6P.~E݊uit5'E"^[+1b߹ zhO r? <35t` ^mk2_ y1b"\ .Kk8u^f.W :äVhpRΙ+ X >Z|ѿ5tAoWN;#$f}DKPA%$z/UQZ 3݅:k=#5iV C?dJ>p3ʿY'0X d/<=åy~ʹ{9T1gY%%yd+gcOΣn>6t;&vʒT+ᒅoWQo׺-ftK$"dg sIڠ]eAT`2G&_nGݎY$˚sTnEL(VF3z6xm{[G; ͿT-!lek:!!"yb)SGs;Mfr1 q[*٣[2ܛ7/'Yz(9\V&m:,MoHVo3xEaSВ'58 8j9udLK;6EQlqT_2g:7F/2 r(b̔VU>SI2pfv+`DHb j$O|q?/Wo~* jHu;p8ǽaxH@:zӷnHn<:m>OV}WVagЫz{xD1ۋk5-rgԌ$tJhOj(sUO荐1,1}S43V!dhGhheQ ƐTň'ϧnO>'0)^/I=x~xIc09ya7&7ߔWZ^nǚP FCh ^mFI^Ukڸ֞CٜESh>w|K¤1yJ[h&xt-Ts_m?v $9z( ?> \=E==G@? !WGݶ+!#BGDA7#|s}pA,eS>}_=*_=Ec"ԕSrI{? ҴB^I )0 ye()eQ\TJ%RJs%q~u<8Ldn g7Ώg"KO8 5<_zsjM(S~2bnm$3 GRG{;NIQv>ӓ,MAq >D69~@>y䲬ָ e0NV8ȹ9͍>=/zm\PmH4WRQoma*^>,V\kF8إ?w6a{5hEUQrdI`v睦]QD"^97)jYmȑHt*b畚քKX%[s 3NJҚw$/}YfH?ucO@חє͙Ne6mq=GIAq)x:/p6 qS{<ę[6Ldx^'i=g@W0AlͿz=0,iOunT;(3orR;3\2$h^2(YB;ykxTnݟ%N3or} u5C;:*|;W_EmeWO>K;vTFAt85Ҹ-QJD){0v~ϬDάV2`Ɵbk¿hӣV7( [idۋ'B"k)޼I]ϱ-8Ⳙtdװ~ Ϧ7l[.U Ϙ'rbi7C2cfB3liے6Gl9g~  'ixS=- GyjAD^6M}]X5GxR^S;N4ۋ\&.7E3$yf@j`dRYx}<7|_uw30u6~},s:21=A"!.VyDz5|bdeKv5}#鱸Q$w%u~ E@+<7=B8Pmsj_ț?e:zU'Ro++ ynxT!$7RxWw_2nFAa# \;>uCs o3T鈖~pZ0NiHSz ]Ϝ\O r_64@8/b`(p"*$ka̫AG z .'SV+2( =^?'J=F~@i]5@ȰlP\v6 lt~ )TM FDжuIrlIcM׌eE4Kቔt [3qZ8td0?~'SAObȓ p=j.Wzs|V\ ϕ~6G(>S\͑`/i|GR`8_y8F0Ra0VKn3 xy\l<.ƭ{j :-(lltô-2 9QyZٵ1TO`s \1els$2)pmb GY,ڶ*H=4;4$>Hh`2b!ږk)1ڤ|. ;=&Hi+P[ez vLh/MbPɷ4t2qO0ը$o`8AEyc^F.z1!:Y{~J7"D fOmu剔Cv >| jXz@OT6g3jSÈgk+0u`"c |ZJɯ_O/y*w%!gi֘}INZoەd@% oryn]Utw2o$'k^AQ 'zē{O,*--/W "͘[U]82Lh|XDדie*Q~_&pvY+oTd(M $9MweJyi d6^ *y~U ^xbYVȨj  A򤱐z5 S ۢ)%EŸFȽeG`8e_'nu{XOpƄ *d!&;e(1<7<0bY&Ca(H3A[&ሾ+TEԷ/v$ ^%C!58{k. ?jzL9F(l˽F ZkGf?#biDxO96),ˆU\MJaT_e/XpOD?e r vUo>3 O*y&yvW,"qBL/çx_,"/lPq !>(fvݾ~v|/w-k:v2'JñOӑ8jy*P$#1Nin~XryɥxD4)q<'q(I![8}C!DYƨLIܲxi3a*tQTYuHfa!*wN<eGGC2[W ƢA'IeJ"Qw 8TYrx)#LŴ2Ra5(y_ϯ3ѯ9Ԫpt"FaX;e$ ^6ONqh`Jh.x//H]#"<IBE4ҳ+B XoOZ>=Ϥa~x(Fϝ>CGK2@MEeϹ#uѡ ?oMZ,R_fL An9t޶Otp~ hē?)\:fҥ: [>eh4> Mؔ=$zFjLtYfU?q;!XiZJޖ *yfk@+n"dTE7zWwTMT>ծ`s.m7z\炥hd~ΜsyFhk/|1f/Sr̃?on]-$pcp&x9 Xk'O'j5f'ָg"(y ZPj`9r:$;{Rζ{v81[dyiM}8Ŧ@>AQts"Է?2+3Q)z島eЉJm;Zdzc쀫&6_3<.3>3cНJ};,]bt0I.{Z$}++jӜo?f;[N3k$9tOi +I0 Z\(O\7ͪoU֚ͩ+)OB_3F[m q0MG1qg=fVs,H /'Als$Ɋt|`üxP't:C`Μ;F(|XsL WN)Sv:Qi` 9|B҆?!a_{{q{kez!JcmwLJLöx뾨^S)=h,uga}'Q.aq ?,ꀫ"Q].kSṗyAT*"3 _Q6ea!H9ZszA0Mk%ɍ9=iZzտ1ÃMKbl#J>K}R <%%mC)gdHN[{4Kxճ{2ӻ7*L`&.O^!g*> EwqL͉\xgܼD 'DXժ%OL$7,P Um/>oo+Z_/xs oJY% yކ?xA :Bc1Q"AD͇B$68}n??1o ~0o[A?7?|}jKa?Ғ-::7kZ~#|8 y~Mfě؅$>y/>mc?0G>jw!+~_z{>b8pޗ:}lK;CH??cIm/ˎ\l~ђ;l;NS,6Xn-$yA-=qL5QfNIcqG]Uנ6Uq[O:f>ٴjcF\P~)2)YJɳg)%ϒg)%ύьEjގ:(myİJ ]Q8VS97$(;S\njnxI;ၢzAf)+Sif͗7pY nS=yWOo{O}xa;O9^ܐ?$Eq߹y"̓ɾ fΏ)۹Rq4˼ڹfp8R6Ff6Tm{C<[lyh/fvEۉgax2x<=ŧ4'̬~CyETܗgBf8,v8`िɮ&ZFňr>Os(i6VPo)'kȻMExz%P7@N'S$" Vk83UdExf"-ɣm̆Jͮ_4N;4sޡ"<[~5yn1t…f{G9ճLRU2'ss ɬ4zxyw''x5('8KNVQ&x+,Ѣs/smnm?s weyk. 7UR6+ gwc3Ij# 2_۠\ X:u8|ç*B6lI^_)Ԗ7-g/O3c3SYs百ڊ\f6l)sᙸ#]og!x22*s百 ìx.OaK$`Qi4(?*:+ˠgU3&uL 4a <7|uKJ_g1H= gf||`yn`D/hiʙxƧ߲0?#axj5㽂ЮDz5-ȧ:U~ڎ&l([I=VR ܨDي *97*gKҙ픻hU2~kqRyns-yeXYO\WX=Vx!@W/{Zٖw-^1z\X>1eSm]_-ή9 ֆsx&D7T̈ DHLDDfcSBBRpDDTԣYMRZ)5 NㄤUWd DK3~RU?>fvՌv] D5|Zk>U2%|"Oc*J)ia5ZK)tADe1ujf]ʹ6)M̥x:^?8sRbvTOںx1niM1e1tꇮ֒Rrs9fVhjz}~93SJ`*Zmj, "\s2s1s>$]S,<&DK4M3G?,֘h9xce\r?&iZu)s2# 3RJ Tr^VjaLQ]^^^v=^)uϭ>Ǟ"TLJnn^<xxϞ>{sBD~ysGȈyV2/TJ !,BUU%&0PU@ b&Ub\}k9D&B"3er*MZڹp8:k!,>Yy9z8PKafRVuUUE5#Zj΋ 3 КA9'"sN>8v HMA ɀ[+ΑhCdmy155v\%jOff9罈DZkg>>XUb)uW__}wkK~`GYdL`u/樈s{˙*CRejʎ漯%j!&S@^2HQDT_ Wf&sY f,{"މ9VD"j1կ7~W_DTɟ'tUU2QU2@MQT$DT͇@/"Dx̜cDj1GB1R٠{Zk"9FBԱcEU !FJ.Uj;;쭵3^\ 9`d0#FfBDk)8N;__߳mwfeJ}?g7gΣJ򗢡#3zo~?/\)hcC]odmD<$s=7BV=fq__3DZV>D LV3%0T4k-"62jnOe2- ˸,b٪" *6Gng4d.s;H1 j}|ٳ+p'?wﵩ 3 CSmFj񗞌ejsQnUJ .Л:Gy}M+W*<~y]nk*[]\}ӆ18/]|ՒbhKYdJtQHР톋^3i*}jeO ȂiݭLE82{ntT+9eM/Yϧ?l(|lǏǽO"=M .1S7 dYҜz-UDkS $7 Ly{~L_PARb\?Ç4SUgavT5i3g~:8}40Go=y.az*,]<9Va=Dt8(Dj780~p2k +\]-xcVpY@pqOxwDxdXtScr~9Kz'YaJRp t== ]]mS846!`]>nn8w6ó>><=߉ԛO|zC?ôFmg_ʗw<=wFΛԚcpw`hwz8o0wTDa94@|+R1*_W{ֵ]G?Ho=MK 8zC]tJ裣. <:Vu>hMǻ6λPk}z+ R7Knus|8b2-.xh?Iq3i"0?n6_·epzGu\V[e Y^|\'m鋗?C>ۏ!w!nCriy~wXxz=ƇϾ|28=(2:ps:MT؅XTn޼e>5hx{:݌rR4r'/-# *Xڥ4^.❗_ܕiy*&u@!Oq^輏{F{٫U$V'l; Ϲ?ؙ7SV*Y"ܴa:3]Jm80n,xwnm9Ou8,MDSƻS=f(0N`~aGS=FPQve.|\Nr<餭yr,gЙS{͙oS==힚>Om.{d:-~|qU۹ugj, O'ǢYۢDZ(Ә[6)Ps[.2ԩa%Y% b,2 0֥JsV4NIQ3BqʇlYƻͲ2801׹-HZjb"N \ER"]__}/O"}":aO[NTM $`Va֥_Swva-3YZ.uDբe<i8 }#j$ \O3qTЯK.㲄[= JԤ x%/S SˍrV/Ux ZJ; +.F•2D$![us(5{_΋*2,uؤvC8x׻ 5U+a{bUZJn{ڙin ˂V 7seܟuS~08pqswK*uz${,N!BEd Uk/RJ~\ POl@M96:z΅Nk1IDpEI~0x5L[z|S-A6Mu8KU~]xqzѓeEqnz=2.iKȌo֯kBթeRѯ(:*pX/rZJC -xE6,qn֣ 5JVä WO)w}jC_q^?If6yEU6C |pZc7tcu_ŞS.ī5Oecxw,B>DEh^s>88tr.[E,>[L:(5{w?/I3«|f6?/)qICKĈA֭{0y6n J@v+!.duV":6Ko,>ZLjɓ+LiKUhC>! O$]2(Kʲt,Ǵ}tE&R쯮(6`,j5yм.RA溈Vb 5npW0yv[7 Pʉ??\ ۂ V2Ax0wc #i[ ۋՓb.v֢۫Jq>ZQߚf(B玧E]\q>nzWc?nVntD%Tߍǣu\ֱ޽#}t25AK!`QeYR~\0J=֬7vXfsKJ} A7Dn/Cŕ ֏j~}v>_/CPwh֫UK4'fBrH,EO R ']@ݔ~^+0x󊃍1hU\y5D\V?܄RveӘvu6mK )}!xJU0z}x̫>/c^>z2OaગSs/U7g;,]>y~gCwNu _#!C{o6abKqw )x/^3V)2Pwi]qZ^;j79T\4q\JMq3>l_qp"RNS׭jQ0vUBKpwFvm8IեR_Dg#ry. Dduw/} 'oGᄐVn>|{w`|s"SZ&ڬ۫Uڮ(y}e1A;:)֦y>7]R jlп<og~]RN7f TNł\זy&7}iy,Knд)@?~7~ >;{5۝SPGZcQ8Ӻ{x7[7“ 1}V`eޤxѹQo&n_&Rr딠1K4:Gj!h9·= R/fñ3 sbhZAa^%3.RJmCSYqNkEmڹ4M V7t,KCp9kpC`ZSu\]҉n^Q,oY'e^ڰ1r8+Rג88>]n`:q^9z~y.4Jv+YEj(͛k!s_-d4mye^~p#>mmb*":w}+ _s?iK -|7/o #Bi+ E~I[7NxiA+vw7 Ap᪷Ӽ߭}MX\ (vP\&K"OsU-s%/)agIȴTp)~|"d)xy)TVA"D&5jHqEeߪ.Kryѻi5P[Ay1F|Ws>ֶlCx86wG69B?%;rutz܅t)$ly2eA-fU `jRQ"·}|W&b By} .e^4_/,EX@ 2nKJH $S IDAT&qr3"Fʥ*#V1-{~/mL~lḨM_I͖y! {}yCHsvnۥ/{/VPFFSfOu::Ҝ-UdXo)!>2-o.VhY Ze ZAE4iͤl~G,cQh"|iY3jCgكw,ma`ad]Jᾯ:GT1#\QE}028b'b59\_mٯ(K{uX S\u[\AMlʨD. }׮.b~u:Xf\9̙ڔKMŁ:WĪ:lVi *!GL ؅k+􃇮5P9Fn1 hrwىGB&G T ` PJw .D|ث4D]_}uTʐb:m [Խ Vn#VRT\Uׯ_E('O J L\?եx]'Xq<0:B6N n@p}~+bمZ.vWp10Jb^S670࢈4-9ê)Ft[rVɡJιO4DDԱ*5BSȎV 4btNRLbށ"[ cC\'sfFðN10dz?z8(0b1UJj,%jv ZZHBѺ 2V8P B)xiԼ+8`#jIYqɠ lm,"U2S/هA \B]_}=?{8޿)UׅO]yØ3ffZCfZ;ڔ.Ld+Ks"ח_}ڻwmy*%3B4q@$:+z0[E.uԻ`&4>51AujTXiR+zQ@-3 8Hj6sjh8d՜k"bBZA(]^[B(ą}isQY "QUgpZMJ"1ZkJ`dqCWH,%jX$9DUI=G XD 10w 7HGm!γALɡU?mw>}z֏>כmMh@ U Z8IDV$ў>t֩R ̦6!je^o3 dM- *9SXa"zj89Ri%ԻA||) ȦKT} iCxGq:̑])[}|H-bF̢1כۗ/nn[~t'=%Ua;S`<7u)mpL]7/9DfU3dg6bZD#w"UsMp.a T"MqX$zdr4&T&SCe^@#`e{21X*Պ4XJ-=xg9g5SfH@TU# QBTР:B-%k fy.I{c4PUJֵͥd1E#[J VPZ[ Pm9)9yq3A"S3@Nsۺ VQ,'G_g!YԁX꼉BqlfВo !ib͂"b&"peL?t|Տ00 &C)lժg@fRD۲";o_?yBM"PudꝧTkEv1Qk-DrL҅ B{Ykkyk&BdPB`]ul1YV1UPf*֒ qT]Gh& :ɇ!  )8ua.KnE =6BHs]H {^IAa5/ 90sC EiC$Qe914|/ONbr.8 AQ<{ fT-W#Zfڮ~UiuV"zآ.o]֑#3R빒9ȯJi̎iYG')g$4`!FbN)!&HU{yZݛw(rMTCd&P3aK>)+Msk|HqUU"65 @Ťy,ad˒'S*(\9 2ܒ*N` DZ6 >:ڪ9ժML0b*)b͸L5IUUKEEbKăas@.E R-&c8Rn[Ecd"Jm[vϾrSǪ؝Zm6<9%UKE&Q2(i)v⬭HV8VCzlP!pnTsKi.DU +lZRA`4͑rj\JS] ѷȑ/ {XåbHvnRfͶduV9jБDYtramU$ ۝fNEY3b5H\sػ.N:-L;(w )ҎSZ8ho;x.ퟳ20 mkޝ.UNMlFJA]0ܝj)M?Y[jV(b$2Lp} uvݗx̛ g~zDŽ$ֺ̙fPuEè@1}9!K,Cn+R*FDA-aɦH1 ¸M;9'X9e9Бu)nX1Î1EìGf1q;-ͿћSYR_<+UzcNVS&1~ǿo>~h anOM\ϱ}6TM}7n>9k*PS\)0b[CrZ~=~;OeYRD,FD\Ϗ!Nջ;E?:$Dq=튀fǾ 扖\ O9ș])W2+KNEXP,uGRCJ yK2ڠ \N}7ݶx_$9%dZ'`"|F")y+$MjΜhߺʼnf8" ^ڞpXK]01DI}jFT^vV9O.aLZ(G)Ipty϶ܺʊN1?\ۇx~ٟ^n}I@Cx!:tnOW H) hzJY{ȩXضzk[;z[ a`Ӓ(Nr6zgx]+spnf&Lc6P؞O>řXtYYg7:){kcQۻ53SE bojh@ԏFMg^1'ޏjJzE/e3@x=?~wo TnGT8`]1 H9Xf] ljT0krbb6j-"NỸ0iqHH8_1)&h:e{`缮"BW{9ю(cOV/ ~o=!ʘ})Xp!K-HBȘ:}>SYm=r*3%KuI~Ǜ SqW sw]!@k[ $zyyq1 &>=ח#n|9܌|48p Jr@ǡ9a&XķJթj K)e5$wOW37@gE $f~:uIkP0zFfL>€Y&*IǘJk*@#8r^xT!L։ YLI OJ0|Y=m#z7+Fx\_|s2'_´<圗j5"aA™TM#3I(.BDBAԄ)ɢW|xy|: 6O S_ B:^[MW{6@\SHv. }LD:t>a P)Y]t?9ɺo]٧{0ETzY)j)5*O//Ooy秒o/3K^L2u):[}0c y;ltp br#>2Co=[M}clVy@HHbT$zt#5cNiLNEnWHCoE7+7?[:Rb1ajew?9&qz]^鳕U}w<1R03!`u@0].{?,a&f-V ;L9✓qN}gVP|?/E a`la bDNC 1<>交-R]h<yUU< Ic0&ȜpDݳ/OW_BURmjʆVj"\AX ה!/F=LIDi,nqOxl$5GnpDj$y6HJ0[Ǻ1%-gz~KWOz<{ c½o3*Q/8WďlSa*&ǔT{ O M% b%%7JWGgP&0y`:?sM;;Քw=cNDZpB07 Ӳj sIaZz1\r.x9qKP gp,joU2mN@"v9Hȑ'04ۏ`@rǑ}_cG42X"%-5ÜR}N @!kYEtLE7{dF4d#`pň5u:FTTpG:Gܭ4[HRq ctRLތϿzvxz9p P̀co>+Z s)p@>ztw7X̽ݚ#q$:wXӕ ?q!.9%\JB桀nZ쀀'}D?)9 ZpְOsUR噐a`z~y!R0G cC'#C"hhjHtrv! ׃1n7my4/'N LI k: юC3!3"y!&!WBr yeI{ f\^)M8xE$=LH+z_巷O>t83Qմv%@ݝ~?7_uC{mS똮~T kbqӄ*!܎P j x]- `Ʊ܀#Bݣ8HLq)"hn9RkpBakm4"RNzǔ51{wYnf=1FL$3:xkt 5gN0xEE y*N+eDRkIy}{>e N|8_A.ՕWĉ!Tjzb[SxŐ!38"䜘{ů0SWXs^:NDs"vŶ]Hǜ SfB8)Bra%j6>f7kBn뚀cO>]oG9o9A=_㷿11LF>=3,bB>U"4F`yZݭ~ө $SM7uk_^F;dY1V}+sɔ?$O͉Q۱Hʩ22M`y97}: yk3r,TΉzC 9IzEVR#0D ̩(ITK.Irk3H ̬R ?k-0\.!!1FD`J„)9O޳1R%"Z)Q9RA6t 4pb.40©ājMRĿ_쯟?|/ܽ)m9z~oGU?Sm;P;fB(i?TU1D)P7)uEӈi3Ht%11aB|N,%鳎^cZj0}2VO0~vGxr­ϮEgpk+f!eɽڄguKke/)ԱͣlxߎsYOfOeɜ aYAl;y~{N,ڻ$Op'1ODv';`2,G] )Tv^˂hb# yAuCmz^^yj1m̩co+<>] \D)v%k9ZRWx#sZ"XEhQsv0w=-Ąq48O_󲤔p(N38!;JLc L^jt}؉.SmDrEο-r6>ȗ2&nC9>~$_xo<|u]>sWR q9hݪvhᾮxYۜTБWh3TSJݺ_[.}$N0ѯt9jm=sByjPs|.M̲$cҽ'M? #p]y%K]H8 t#t4L %Lg4zB}mIB;mL_N7Gm+ɏ8TS {3ߙ1g{pt(<R 1tyn<>_n/ހlZ:|}}y dLh6m1Eѧp8.>37'g`(8uW(|/f(ac`xu# SWRZmף=eJ\O?~i;Z PT 0w=>]Avۆ">正0;5)lfj6hj{EPaU DÔCDoRcKݪ%Vǭq]+(KsR$2M?iAOwF 5"fH SUv Hhc%RiL,'ʔdnfLX.D߬,Jx%rD>17&g?}]N{Sfm\ Y YHbf)"R|y_dp)ӡ‘.HE|ZMJ>;DL99Wޓ8ne$A 8f{|<2ԥ>yx!F=a5Ku$Ǿ*2Q.KԼ39((R N2S9\3h^s 5LZ}ѷba"$:`yiۥlKQ@WJ~MmpE<-s!Lrrc̔0iU9G:Nf,ᖘZ!z<_G?,\t:rY }1KD\LJ۷hqeL: RzWJe!өV15Ĕs{XJnw|!tfArn{ZU2$cE@*Șn6; ֵP iIR6g?ӿН";1('p 5RR"b$* sI,|:UIԒSrI)-՗^$Vr!@/uTZ\6Zo* ޲Kw8x>tC`d34@ΙHU֓ [돷O&02IvTK[y:eL/ @Ĺ#g1v\/[")a,^tp@ Z+؍1b6m}6}܎_%Rᜡ滒O)qm(9Ղit2qٵe(pu`mHJd7HԲTH$99/*Kql[*B=X0Zv1T=)]e9<2'Gk3#s8I8!HFiMKf><Nh]qc#ѥV ?m>/ytM5y8 I tLL) 'I93' ~ͧҲH?Zk[f)ֶclJ%RgxW243p 8ߝKNNu빦$6RS3W1F{d(8nm N]gJ6;(]c?PRR#Cqm.[gyff@#Z?>s}٫Ȱr߼*SECtd`@h9},?^Ә6"mU(SϹ Э5 K@NX0ҧ-@v;2~>%}r3WΗ\z81s_W_/0'\^[9q]@Kk.%0Ra""3Hۏ$ZJ(InvDVYCt(dR-l)nho' P3` H,өZR,QL;;ZLfzai]e[y)_^>ƴ9݀IbG f!Nךr/90#:d!98’hM5h4#$ 3O嘞׼ @Î>j^EՈ%>F*9>ݯ:ˉJx,y]Qˆ6G")1P9)k ºp%f{S0fcD$sDLA< hzxMOĘ6uL9-iA@$,1Usx{[K:m49 LRʐӌ>lh8nuz |m}}ƈr}Bwx:C&awW33Gp|<;v{1s``C &$2pkh/On! }9$?j~[~m{Q\rF؃L9:6r8%,į0| ?!?iIs)8^˘c[m9$R6w,Yjm-*$)iI"9C{oM(ej,EJIМ p"n/?/|4](`dis-']_)$r=.?_SD.:52Q ̈́{ۏ#3"L/߼szX RK9Q<:;iα,Kܭ#2O r5h¹Ǎh'I(r>/ XaoK]z]r>Ē/?xi;,ˆH]͇?u)ϩ%9IYdIעM_x:U46EJ2JYed dDd^! t,~ʩ_<_ZR78ā~ p=%v/sϵ?t!;nā~¨VDXʞ2|]󘑲FoHb\p,,}ڣ7 tҒWpoظpw;6G,Ҳ8)e]T;-,Konu:4c}5jwP,IfgeLP0_\NU/}~ܔP\ڲ\^TؖP=UaغԹ+K#u>{TsN9;E@!yx|Q!zoiXu%פ1m ="W30Fkb??ӿǖ(KBfR蓀 uwmm__vk ns&ϲ%GzOq̼P(PVeL%6f7* Uo7391-tl#Y&-Kp}OIG K"q4Esn#'8]Z;6=iD6%AhmԮG"9ǘfeyM)ܯۻ/}|x[8J.xJsxx:y^NRh>`0}vzw#0pVއHGA3un̔o o]u; <;&) ЉDS؏>ߵyJ)Ao'`ICz1B;*-EO_"m @. iN/ 6y*/ )S [ݾ0qӆFn0IyzDəzv=n"G"wt=RW]2\v49e: LNˌt\uZtd )%TUo@ȓ"$(VfOw}%^?>Vq5uUʙmJ)w9 ,#{i/!\:ⰙZ%&JY#P=DdyN\ӟx\9"8g LZh$#B,(PQedZS% &NyBupo6F.r~8# <_N tr^%Zw_IGYaA<Ӝ sPkk s,OSB I8[ûw#҇%Nn +1Z68D* pΗKqwPbup):T`F`,Exbre޾oN82IFfȜC=426 }60:Zۭj{}~ 0/TNw=)í#>\c0e0ԅqI:jULy^&1vG("+y쨛$zX^i9Bh!Xj  L#;pq5fΥO'8[9QCǨ*9>n14Fnk.)}{~ͻ6m "L{DHJiѮa%M%%@wG)V/?/x,G~q-s9 In:+j3 xnMXxӖ=߿_L>I8I.6<1Kj:'VP:F ,%Jy]^|HLjIDھ 1ym0WZ&(t8LY!10>01^՞S ~>vj)nZJmWL\ASxr~>Y$#@b!OG/x_EᾷD4uy1\ .H8zշ?y&$1 !&U@ !"rn=FS?ݟKtM@ txBbΐz(/i&_ůO 6p :yor:$\iq3 +)~P>Ws4Fcq ZhcAƮfHB]WBYGߍXpG\X +~p>ڮ=vǧG3y眙y?nug]Pǧkɂo߾#0D"^b!Sm4|aӄ`fiQho5N%IUf"""D>cIQ95F]p*k4\L5(ҲDݭf׈PJ#d4\bDHI*כzhmwG#sӼQCL-m8BBXJЮLāĬ9'p>3kZ[OЩ>t)i}C4tZ^1KIkb:yc!%잒q@a9˯bφcrw;2pɜFLA숂(D! q(缚PU5w8Z xm`T.яN)j{1Q IDAT>D4ZM['b"hvD|$ܷR)OwIVFhϥHJI&f$5 Hpp=zEWL!HJɕGo`cױo~7WiU8jØujÎmnvTh,"a̟$<+w26꘧4!<cTBP0> l"Prj[NJZͫ>y,ÿ\U ,rxx>n1?}UKX(e.Ki.~ RӉD4eqb4-Z\$O_byTrNizBZ]D(p3ѵd>K&m(,C\r^ח8FU D,IfI (,Si> $4r"X-"Vdv|?ލO\䝯S g!Eɑ1S@:cdP(nG8զ@˲Pgəskamz`| U^GIt Dd)}oV@n؅ @'!p`RJ%y%ey*p y#b C[kZQhPΩ>[>E59N#|:R &}8 b2wwWSʠP@ U<$B:"܇ ?~xRRGO@bZF~$%71^qLijkBjkVPAPpcp,~ys%N614MjCm(:&FNʂM:O7_ſWښkキk;tt wU-Y@@ݞ9d{9L2w)SN͔ enn2e@L [OU pr<}p YJqzWN%9ՑuH,cO HG4K\.ikQ8KyR:~TBTL\fGf1tJ+! 3i^~Oo& W+>8Ja4 tw(y=(V.pvonjynTx8}jǯ?? Z;8c8:XNA22gӎduih, TdtWo_i6nyFZZ$|-/u)Q%6ևOǣG/I&6$ Ջ-=܇ƾpTÀ1?P'[k1RJrZvwzc;wW6 h{Q1Ȕ XBRZ=54W0<ޯo~ǣOǧ.Q%s~Dbf4P|W˒/ggཏ1KSo:MuD({am=-c k")%H zkHbyӓk}w_giqVw7Oe2ǛRޣ/5܎*@r"FNtyxPR $i'?]"*9FkRzڰ )F)a&00Tӑ{ ok~I04F'u>3}~ޜB4M 0޻z.w 1mi9g?|:|<+Y1xr:-PCXktS.чyx,) xy2YAH3زw!mN" CW=JlU5Kk 撵1z@\y1t\hcJsO3*WO/~Af1q0.izX_L^(,rWqf۶3_v9ej˴^.C6/bNѵ?>Z9aJf}Ҩm Ŷ|1[4n훷OzkP^9K}⩔ڽK  ,={$1FW ~ Wwθ4z}X3jy1ҳ.r ĤUvLl!bo^xq,F"e?W. nmBFD{kNDAQf $)Iyf?Gm6D[e~CY5}is?_m7iӇ[qj恽nY^ͧ"Y:x'y)i'fF ߷Q)%" ˋyy0|a"0uYjG2ͥd&`2C)z*w&a2_߿.-R+K^} "G8 RfwwaLRJD "9gdM'3(i*L-SunTRN%yʀsN99C2c'X/Ym4Lϗf%`ǹGQJ%N:}!СlɎs7ca6WYgOH6gy}o_~ 3 lY׮Q &VLi<=|J:taZN]zWէ#1~ظl?7a1p'm~?HRQ~4z͜'6٧Ym4 -tܮTÛۗuWd0>RJEJZn;8;!H@^(tCկyQ6?Zݎv$-U+ 9鰮CK !Cqs #1ewPb: =ܽԶцHN8qjr9O>j~>jGu91=ÚT}~lf:!12}?XRo: pk7JBˇw\lzl 0ìP;5BМ߾?6,{d5Ü "'sŒai4fZ5 O|@oLJ}ݑk*|ǨPB< L8)ED1N_z0AD9gUC$#)pV5zvћ(T}6$fp g@v/dJ 6v$'9aĄKct$$ C{.׶0sNmݷ}۷BĀ8ͫ"bc/u]ȅx4@2~wT~6,e#&P 'm2Hyr}.$1:#aXGXë#؏oO/|~ЧגĨNhihq}:>1FW$-adDݎ@a*&`tܫ6KSvm SPĜѶ2nvܪ+HȐXȚ,#/^oM| FգE׭҄0 r$CNR)i4M{^kc攒86#M'/?&O-ZN \3k2guq?/tljr*qcif@?ZIzdL aQhB0]LS.f a?]Lpד6PXŚg3`〱Uni= m`^ eJi[fS*]{ITm{圥$$}ߞ̹_aa쳋*qTQ h@? 3x!(S2ݨw'0{&l={-`x~qP2,Aħy6ck} J)yl/ҒdwO)iRvtڏ:υ)GP"I+|`NyXYG|v}$C*D`ZϭΙbqNi^U%Mᠪi@s GMNl-k=LGChRI9ewiJevI `6"fD6w [ /N;B4#q6gnM$4O`j.ugbJ٨㎄!'iMBvռ: 1ƳV-iYZ߶iiP];"Fxw9g~;N39IKq;eE±vC\81 lק-H0_ C9O2h Nݦ64;`r]m,|$Հz<|r_Z2Mzϋ\dHXJi/ HDdfx eJSayԱM_n7kwkYBfS)*b nt0Z2ޝEj潇EX~_;I2C*iov !d$bV8(PZ3{& RyJ} gqy2:wyehZw^93p7t`$x& Bwq-ųUpv1G<ۭxein9A@Pm!<vS#`4pg*~o?~4i1[>V΂f&Y1U3~")6ę~-8iσgfV老,{RH)AW݋Gr^!a8~~ gFVhc$@б ud,q:iג 1.soRk,qi7D e^nU/e~&ԵDL r)hDh1N `*Q@H̷ Hz8Oo޼t9y w u 4rTD ' , R@|w6JKF4@Ԑ`=61Ͼ'?>t#t;ԣHYrM=! 6ͩ ^)G>Ru{~ 6M nic~ZV138LyzF*3s4Q%y]9 F13s$z~lovM}>/M2Q¸Si>r!#1P){Nzu-Y>gOWۮ3=eL4T(S̉j"%=GEuyJ)gx_EJ.j0m9I6p43E߷6nO~߾S9>^lfϖ8"#'D2sIݔ|}p2\oC X,ƒRHSۺ_?OLVYhw &$Bj B'2N0Ed?C<~Av"7% ˤ6h*{_uψ[Jn:(v NDX7߿+v*i$D4$4R[27XdzyNvOwj׷S 43CiTJX-' }v҄0b#huj] ВA ƶM/Ȳ7wvxDyHmz<|N~5#r/kznϗgzK >~|chUFRӔsX2_>}y{󷵟rdBZ'N[%$N"e2L6k([+:j¯^^}6K `ovYzqmZf̛,a7^m{KqԒ%R*mCF@ tfYĢff>P .kAHhDTm=-;yێ -TrI 'zýOO^j| ++"fm?2L@=F÷c 7r]ІCJY#R.3!:g>SV)Pbͺ[;OyJdcs_7øHhmeݗCw^_}|a7ugm b.eo;S Oӄe^Ҕfn`mLuDd ^\msN/י_<< t04K=|j,`"8t?DF6O_hs9ZǗ_'㭊=DƉet,}) }v}nTYՂIGrh ϧL$ű|=?vׄ2g1e!E~zPI{}HBs1 eA0sMpUuwU]s#s+d0֧\,=׬6`v $^y?_}}:t BJ"l0a=׻sIiu>imO7D9!PH)I $ zyyN.k N$ ]c0"@t '}3AOL]pY~&Z>R̝UXh պ{.//^ֽ"nFBM@JOoOH4Mi@ d)멶o޿{jO::Q#8VS:2`>\M#=g#2`DL +W6!fnNZ.KJXkWrǧu@=M6s7-_VZջGLK)z2r#]0:guUy?&uk% ZR`EHu#*LJُ)mbE~1wMQoOC40 j7np +E$z$[Ӯ5o4n㈷& `1Sm!\V@tۇ??<.j1U2rY7%,Zz^RyNC*Z^{ fsyk.X͆i<4G7ԥ|Hi۠Ȁ>9H!)vSĝ#ڄKS(n˽Oχ٫$9w(zHa䴟88X@2qmYBt$ T֕$44l`q/[՗y|7M]B1/Vq48E$(Ҷ( _ ȤHHqg?D"S j:~7lł13O< @ #)WcvR'7YV&ֶ!R7# qܶ-*eQBpR4OAs_+XJmmw5Xk'_?!w?T+s@1"Sw׼PX$D jO5F#>MZ}|h^KϹe ћons~8Cf h wpuBasT5ReC79eE[P[zo<='Q(jĮT>ZY~vD4NӲsl՜U$t ܭi߬˶9­{k@Ch͵ik%攈#߼Euc`rbgUpś-NR>>k/b1zQTK)r;8lus"1uawǽ-v#2P"Jk%53bA 8۵Ow]|igm餠p~0#"y T D`?W!ݮ60a?t CH28Nhxyv854"C 'D A jNܑ_?U="ziX|~`f`R bH?U#03PBމӐ81<{< TZ0NCVP`Д3VmC 9 =?{u7's  |ssΧ)笪9gdq8sW3 aG 7"m0jPHPW߾ [y4rqt~kMu72U,ϔ>O_A5N8xfNhTbTK.A9hאRo>$HQ AkA(E z^J-{kA0^bDAHCwz.u͙F.M"֖/^ ig0u3tbb@ j[Z'Qw`!NøTZ%!" Ⱥ  <nLEnVP.9S@?s/ݏvڹVtNtҡ|(D5R[R00Rջǘ̙x?ns^ur֛^J'>5VZzw.No/v؃aw]1BDuZ7O_?{U(VGP\C@a,5/b!&1=yvU"q+[bYAk%9I*#;Hֻ9bGq۶Z{73G 6 =²l^j-}߼gI[7-RUql~#~)9R\Pl[+Lx[^;MӲ,(Fu@3vW0\_W?z|8]xf%Zr:ڼ^nBYhUǼtB"Ґz^}R3 vYlmn^0Hܵi"Mǹ9V8a4TڧiveiZ"/'ˋRJ>'"m#%8픸Ѵik)uR!bk*u4e0@lO1IVm٧80!19Nc^՛M`09 J@p4öC7uKE{aJDD$"9RD)Mkk% -DH@= %H),B=nfC0z AZv_|7/CqxKCoCVNY Ɇ0#nw/ڗnSEf0귨_d+uz>v$ &UV!tU$f~{~?=ӇG01q[<ώi+ mNe 3pYG!H[gw_r,`JP)u]Wp, C'bbT륔"{&n 2G|x|B0||a[6,w#Cw!^8-\{;wyeϿnSڍa:ZDZBD&wwwkSכ$qsUk0+aH[o];"qpDDʵ+/_j7̓SE㔚.nh-1s>]vǷOqٛG8ĺp#2?ߗZj!H Bc{~(eeԪ!˥u=pZޗS҇5;e {!vۺլ'cٍ.[xCL<r Tkvߖ咷z=U445,TiP!j5DTjA^E 0X֊=r']fbHm(^NPL48 M{x_|aNӹ8z) > :7_7iܴEMFH$BfjZzg1 ZĘiZh9gpUҮwOO{zmJH^rmS`ǔv'ռ-fOo>y)/ÇdESc9 z ഞsGƩ!9Q6N|8:ZR-u5N^sEkG3o?<~놇! nb}KM׳?ˣmm #3Y@c""X;:3)TMX{9Zru33^L=9q#$Aww;WE^O~tNZ)uE7s)m8JmR+8u1ަo ǀ`м6SoHBH{@@^Ume(ڻZPغ7O;OQ{|q~桪n<[wlRI2k4BTȄX!nz" pZFU n$|wx{wW{ؽzGXs,V0RO~E͗m^[98Yhxpúm)9Bg@PUR86A49LL]kq֦04lmw'h9k~=O/+O!yZ{vu2g jk(1D֛u] "s+Z/aB!td˲qi|z΃!uAy<qm\K AdX>lb t5pZ4oem,6j9KG]U5#¿s,+3c MVk9 -0iwo?%K3۲ [o.?o~+-N[YK6σ"mHn %r03y]Wm,SmHA㡔\{ED*hE-v9~ώ=! *//[sa$z\r3cO8Ĩ{Yq杻#8Ws$ w9()}syI~vxΑwO[C BU$[y$7,]5@$!N^Z%dKеg°m: ;U#\;3"\3^[IipĘn#P~䲬` VgǨnOOd77(3W/bbFarY sG7׮;F ?tF[uڿ>1XkZoA42/:Ҳe`Dڶ8R.G~Y50J@iѥe?&ZM?M)Zc {b.l",PJs%- jmֽH0ܨ@wsnS~Λ9:bnŽḟ.E!a5B  cj0J@i4qΧ 8𦷙4 ^_Oq8y). Rc5p l!Hw]V;3-XD$i os1Pan@Cq9tiZkefF8"!UZO~߲E@75DR+@e-ukރltgsGe7MndzJ˭,viֻwU~ $$UBkU$XSwpz9RyU3!iAz<|:ר`"ڄݷ0C^czc b%A#IN!Լq)8߯1H>I$VzoP8On"(g#lOtօVYXk,F К0~rFYZƪu秝丗5bU)9s"RnQOTt#Ĝm12 2)i4bx% 9Bý)'>kQCkE1 o[S`@Uժ1S]mHa6C0,H-u'P*pIZzv4h5)p-D`\cL/پh.9Y>MaH㳽nn9bvt:1&)%kJoʲ^/ZxA,u~SdmzZk+. Zp?{vLʉCݽVxvz91X[j7E ]i(-o5PGLj4g쓹/wSeFS"bS\C-IQ"B/{w#QH3uWnB-.$>a^[v7@i Fk@#ǢQ| IDATd6af`Z աDFڴĠA"! ܎]SW=I4#8,8Ma3~ʡ1 /zٶY::/ԵI8~|]WxUqaMǦJe5Ⱥ>wk}zw(`#N_)t "× bGZy%Gk"Dw#?pɽaTj[JM[62Gϻt<ߟջo~<-Zb [i˿kUM10m )vj{H?{3§qOxz5_iBrTU$z:k^!RRIڦ$Odq)NC'wGW 0w ϠKux|wSD5f k^Nv^gGYߝxԴ9A棽[y\˖?xb,,.bSL)hĿ>;V]vcjLg|[D4"Fh0nkéֱ՘O1wlRr}w[QcMTrqpuGA31ܢ JLlDL`<0ĦM$xLC靚o>;zPvPծESDz](8L%a8aj&QHݮ;jkwòmT&XZSio C߆6]Ka`"ջrLڱ$6hB!>Oqn]"#6q@[H7 ڦi܍;nge>dfo}?|68JDQ,]XO_c5{vw+GN|]h~yhXug~~V{{8qԡݽ|6Ș2Թ]z}?Ff%Y3b)mkݿ:ڛP/z^5ppw0'$D~K,;sOTɖWt40zo޼F ]6^/}_/fሕ!ioh$92 Md'^[M1JL4ȭ RZS(1TkRBλj*7/$gÃ=Ck{lN !2Vj6q$ךjU%M͝bʪM̒жmF;!1ySDP)0T= v'۝~???>T?է|]~gxL__/m7Aї?zj8<{15[;<;\!4-nkMji14OLLȮH0P 1b`@eVR8斅)94\Ծ_ŞywWuбfWdGo_凵Ry+mEfaH8ȒS}d q K Pj3'bP2B:Zzik2+9C- %6t1jbdڝ%(wFo ]49P"AjN!3 Qj tۯ?ޥC @9nwG<}|r޾h6x Rgw}% =%H@G~j :<$Н*xVTL]@L/%2FJG Gr]ikӶ}8k`"VuX֭U(@]?􏿾5,cCfjkL d88A#N2 ݛ#a q&gF9`<}`Yrx*C=;|~|sW/" }@鵣pEütbQ"dbus5@D$2an ݰ4%B5dF fFiDI!tU4`7@65wk4y>-m]Cq篎~ݍ>5zǵ"?9@)yvN'=x/.OӇ]?MXcy~1nO]gCnu$[A.hf۽(q,Tr u~>3;՚yϥtewWCw/Ks}PVFm((:on @ME#ZPZ6Q PDpSlE:"aZ5RВ3̹ tP%DKPEOVdrɻp,aoWmCоYEjwLWYm)+s)[p[^ji~P//{~߮~;暲lnY0cքP ֵ #ZfEtY@RAUVr+gUQc aA?{4)ox-}G{o?} E\?%8<ć㪯h[!Z)M6y 9 㼥☻Jz7VTptU-);PRډJEaȬ ιZ+ik *VD8 drmKfrА 㲞sMl[r~6|qò^Ͽ˿~+ ۷~{ey]|h/0hZ*Dz)im<++c 0xB:@@Qt%2m}:]dK mÉTG:=w<~{{8=0xzp/!w~u#U!珿v M\^˿zÁIz=o?}7?+&a9"P7 2 ZMx > ,BӊDR(#0֪TjA{5tR [\+"QZn3l9ZR-'T J_v!ցy+~&|c ϰ Bɩ1"]yYRן]ZVD!Π7nŰc fRe0@8fv_VԍuD5PAwş3ޑp]㻨RޜӽUȾp%)Yl<:M:rG]ar:E}*ӧ d~x4are_&wqd1Y)rn-0_\]yW^Zab)boR#LR3kzYᡋBwMwLtc|cx4~/ܧ9uNQ{5^)=f\x8mSNd!ewAB-lM.ՆaM9XVUջ Zk%-U[c$USyZD臀]>qnx]vaħAP~}neIyk`G>>U췌uCA8[B* bN낦7j:~?2#kJITJ@oPRĪEDU*U-G%ZZk]JZe.:bTATd-;!a_GAܚ17t0fd NJm,u>`s~wu@OR&p;[3` h\n4{aW̍t/o۫f5!v+r?sѹ5Z}bVyրu"u٩1ۦ.К(yCN<*sm`=W:4}8%)0viYq,nmc_>˓^N_?j-e jF* rs>e(֜jM=U6$l\Pt_p@=mz)ܮ7ƪ*pi} I[;Hc "ʿ]$9˲!xj"=.ڵӃҴbLy6~1#MZiGǾo4g# W;js @GT |Zz~PHhU{Kh w?T ֪徼ܒavcɿҲe S:Zfø/K*ĂXTɸ[NDzл ZkmDj`YWQbyI o>H+L&Kh{C1_1t _ׯ˯q>]# T?N[|S_.9߮jѿ{УH.}Ӊi׃yIۭ'OUiHJSz7hڼsxYW&Zo9Θn.ִQ@%C{Kj JoKeוcMMy4 dqԚ7?hd˾[ñvYvA]/u-#^ϗm z1F~]_82C#BkDSj ǙyGYfQyשSΙ5XkU5A"< Pri*^|<״H- Coik0o9wmY. vBUݶnhg4Vimyk}xT*ARsr;{oARwCT61,t/kH%SUY.a}zY3b8vrm95٪%$eR˶Ơ#Ҷ[@o8r4%;Qߑmc0qKkX vD"76riL-1 j]AC!N4By6Vv}m[k)Gk)tyݤV7`*l?9n<5|f\yAsb5_pJjk~nvu9!~ȭ2i޿Qyڱyy^-0mA48# jl@q<Ъj@OUXBacq/}ݿ~})-DZc;{îRr8 sn欉B,`\txZMv3m$weJ3dN|=_K]Tգ=OiWA!@E5\JOsD92 /p^u ֏4?}giDGlJ,z~_ner}6įlU.پ?XVdPo`>}Oן>8CFQ+u{rY/]7L Cz_;x2?~u?|[`"ܷ/ۃO%X6H6f|}>GOџҾuI$w]! Wn=Cl ;M+-okeGDBt”F#ެX벯?o׶Ax7?|+#$I~Vn[R.rmwYӾք\oD0Ss„,KYv4={0*( C-MGzM M޻6"TfF6(6D$BUs 범ROuo).[ZVڕE$睍-yu6ֵI70v.a_3>No֧eU:e#,c?}7G~T-&zIOǧ6)Kxủ85On~|F}AeTjgnK!eZMv--wa>xyW A eck+ߖrħ)`iyY,]mshh|^%|O(B]Rwj|PH J1. -WIj6[2Ck%gW\|DȱQ$q( IGW4뺀vO;IR%;06T7!2DDZS1?ñCy"Hp䋵Z[iyAB k le $u].FVy}28|ey];d+y-{?aY^LJ>m)nBçX}.?E9v(ϙr$C*3_LOtmm!Qc5r==?|K{(NSS^.ǓyI[9?0s#ihk{׼{3˗O-tzkq ʲHMԜ`wKz޼'e8 *ZSĮkɵZ6Һz몴akMyIE5Z\&1Xxpadg:vdItK֠`˷֭KłߊPsSKIk`:,LWj:XߖY"4>Қ xO[) 9ax˺]w_p IDAT4c(aăw.C kNǸض^lC6O[rж A?2n9°5ݒMw$Ox 58iЍiÇ܍vHԢS.P֤cB4` x玱NyK@cx C5u奘"cPG0;-Hb e+tʩ"$ǵ Ve3Yk;TI 11X~ä[ςZ+/OTUs!Kuk "R*]`" *~w&0y 2)ն}Aq s<$|0 ecDK:Rږy-龷\_Km#\ػ'ژ$럎&uY: m-/_xv@yhQ{%Vk=_ 8uӷ1Dol5pp,r̀bjaZ  NbJGzOއΖaT9&l0 j;? z.]1mݫt5ts]jf2R*..%WzYW-#[kv&l}.cTRj/N6\k+28 ;\rBc[05Lf~e$vޘl7%{1S"IM5fe=rK{ID)xrn뾯 b!o *N㔸emYWڗᑌ)iK-$o.nw7<@HsZ&@&" bP8qAE1ƾCo0Ov ַO__]h8?>>_J{p:[Jji,6}YJ-}I,2ٓt0TXqCTA^ @hP;KޑjZ{]Meٻ=1؉/UTa[ڗj$/)7GeQ覡5#c޷/K=MnהR[J붋4.G YZȘ 5eKI_L{[o[y}S|K"ٌUå4$OyM{^iܓhё ,ou߷|އZ_<=*]ey>< cU1I1W&.><<[!aFNm[ki]ûGi>ڹTԈH7z獋DJU\徥}<>y8 wuΗ\٘*MTiC{Ny:s ˖. B-u_(r+ c0K}fR8.CpS!D>Y/=okX2Xk&BxUnT@co1gc8Č(88qܧ=k.l1SN{21l՞eFsixOO.B>γ+}O8s}_R]t¡1Yk;ҍut2eߥBR-2(~IOn\좋#c)-!nZKe oG  UJ^UP¿t0 8G UJ] ;SrjU58gakRV<==Zrnpnr&H*فq֖Z8d5`j.6XDySjs`pԲ Tc J*ч.T;j bۖl x򇁽r1"B5fosj8E`d%RwSoȩkfO׺T7"p:a&#&k+9U絤L"X1k56f"tH˚b߻ּwUm[yղĀakjn jkOHQŢ}8qr[AoaBo-Z!H8e{39q E/^}jۻTJ[6L4t^c<!,R`;|%m 4 ,hAD vd}-7G(z-˲ j+"$"ъ<.A Qp`#R&׻5D1Гjе ]Fz/[f½c`Y;FXo}?oK],Խ` C1쩀 *uoOfC{] 9cm_MoMC`d ț1 ׾ !4}kpx:y_^׊n%_{3HJUjPZScx|y}\ui٨@Vh& C@ke ɚam) Ae_9zjeO@/_Jn}=3xoQlRݗz(ݧi:9]T Pjg dc!SG#\k]Z{j$1s0y}e/ 0/!F NR9[ҚWgU{ɹV6\^o8[v֎Tm-K]_h= Ce)yjmZTCJGv_wŻ}ɻ{<8g)[uHowA8WR`!/_y͌FeՖsVD2,o?y"%r*uPUG 'o^ζcRdǖ ̈RI @jftM뵥^4˥ cGtۺU4477w/V_6mӢa^[K. l4YࣇN]: 9'ƈD;=)e(v?D[K~iPbjg[.PZPo&&'ܲR#֚1> ~m_=*0b OCU ;Z IYq % ekrϷ4`Qm] yzZ4HuEѴo:h}7j-Zgi;v a f.oФzng(Rk%]j'wŞnݺl뺫jMyӶ<}<%!]g$VQ!i3"JP[(} hEC͒"X:DQP:B^4s. q(HD5#8˶8ҞhV/) zт*h;!<@![)څpܶrZmʝr!@7eT40TcQۚ5*,)q\˝8U{tB)E)4)=i7̷eɨvyrYrDM|35 D.Ԁ'g@mLG6=Zm./YQy{ﭷ=oؐ1d^^W,܋0T|tֺ7|;7.8D"fgq.,4 bں(esqͧ#a%n{sbpA3 ] XwZ+;L JReCJ (3 Uџq0jn޲^je=@V*UR$V<4. @ٓQ&QBfnҀUm߰:P)wbߕtYR1Dd1`FymYEʖ6N Tjm9Ty 2MRMnhqfo[Om=8N󩶺W;0E\kQAN3 &_!m\z z0qWBCDTr{'DvjloNH0=w~nxgt@[j"mK }xd9B)8;<2FƱ*hτ@sc[3PUmWjvRDFwV2J!Tb'iaxV' 3mSggU~O6iz߻ X{ڛw8ϵԡfͻ{3Gil,}u-Q(a-&NRo}7L$0s09$@DڴrUkZHnŔ3;A!vN k'8U,%Jc@Tm#֥=Ra8 ϗVS^;L?I;[l?ܪa"&ZwCv]U)228󖖼T̀E[MhC.DjzCf4uF:O]u~kIYET> D^{Xw*yi^Nj؍>8c/cmSֺ}f1-q:{|7"D`LKiuyUjԐc"rjD\QzM ɜodJlaw@ HR4f,KT1J_6V~o:0AK_2(H ք` 9ow]()'kG%Ty`1m)0rv-5 L=J;8ߍb_{ߒcUz*1}[΂Tu:ZV!r:9K4,v;1O߮_όɟNnOPZs2Çnhf0a4b$g~y';:0hu`Oe얌MTIwvlep^K&ə{/RUU\ra#4i =3-JdVfS#xЍ5[.v0fs8!gN_sj!E\y/& 4'"Aog{dJTB)!:0NDov(Fˮ:YJ!g]\yPv+:t1>F#mH0yڶMK0t6rMɟsW]m-jYY V/UU w{ǣ5v}3tK"M KNY oۦLh&Hv|&3q*8}7̇Gq1Bir RA)@@ RҺjw QA.BH)A 0.@;c \ z= e,quy b橔8\\KIE?߾k|7?6YZB >㘟_'QqbBUwzMJ Wpiڴ\$·k  xYђc(/o%4l$=Oথ$GRpXa]| @Jg|a6dmՑu>-/G/k㣉 1U6@wcb+%&OH$t/-/: ud u'|:_0wCs"vh+uWc܍J޷UR-4+8OCH \:}uoO%YRJo!8M1ZkSc?bPon.n$L+77RyJ?O!`r7d?i  fMe%vye)c?-eU8ͦb]{VI82qO$lZbPڔdU:1쩼tmz*1XH1@C ^56ٿLuM"O|׬x:8NjnV;|:j+UD.y5e~:7(G;نySqۡ(J\R2iFXSJw~]\ @)$=,Tbʔ K SRH@9Cɀrz=.fDt=+%)BRDN4 \W;۵%z4WR>ɺey]m򊵌1ak9D+E-Psi֚38ỏ/w7?ٙu^_+>}C!Q:K4aɋ_^|dvb?cZ{*%pXtZkeU}~^61C^ ӄS~zMS^O̗㯾 F83yna gL ;N!L>bNwxAbXIވze\rpeY~}a,OR.vМr/<`d2R.DuYSBy2)aV,P7K$0}ʄ2(}]_Ep0bR-UT )eYRDv'&5ӴuZ0kMYx&!j^_|] uӯc\ׅJ[;:xúuM.`!fq~c~Vhk0u>CƸJɺوnFJ4n& Igh^IM VH~zݦ4߿s(#r8jO꽋zv~B&f1_,aDR:݌f\\<3Mt!\4L洛6iukF}_|:NKmX4Qyw^FJa?_G/h7_ ;u>ϣwf5??!SJcJ>})"\B:u]5KPXJF3-2傅΃ж}d]{YurV&KS]U%3͂3DR(RFOjy޹Laq]M BuOS&mv IDAT 񩮪&DQh< YkcqaNh$S.tZBIMdO瘎Ut>אP":C RLhj BS*+n+Wo f[źn=jf.R \UL\67}*6τBôq/J.ERFr^x?|,ԬJ꺽lv_fkMXav}2eowy6޿%@JUN3ՑB. R1D) g%2KRJ{!bV4MIJxϛau=LU2L\m沸vD6 >OȘFoOƜ=PWja p3# U0kbV[IXS8UCox)<)\D4Ja1DŽ$S$6'R'N(\AoM)Iૺɴ!E\4CJ삥Q-/ .-lXIA:LizV'.Q:H8vTnN a3t\'ur#dnCqaѲ2tT$H \JFk@rz4s ޝWs21^VH&@ ?× +);<ϋP$/>oG[#T#R(y7/Χq JVc! H1boq()&Z})2MFkҚs0XF$(ĴB~*BS|?g`9!W(u}$tOQ0ъXr4*.n#g}(g⮯,OB :+DgZba°xI0 nE' e+'Vs}pBO$yH0@c>`&7))`{la@}bVFUy-13/+u,T5@KˡP2/6$@,ͮ#)dd1.K(PRrRzE_qM +QQEBLjt~ZJlxniRxάsɺ@$'M~Gd{Kmu."\܈HsZfE 9f&:Լk3wJ Сֵ#),,+"9Ӵ6sỳ@p2-eRP^GhRq e6wUTX^9mucJ m8oyl9.dkW.{\RzYt8iMG)+n8%Y%cNKU]Uz3-1)ݯ{+T*W"\+~j^GoHl8-4ZofF I u)(6]?rinvkŞ,{ h%, %L*&+&Z JcT~mݘoү@~k势L`Xs2`MM +-hUkW#벾fPe/Zˎ('Uݡ.Lrda5T C˧vh!(0@_]DA)@HjG RAkKxX_~i&]z j|ct݋tO/o~w KY/Hl]tHQPB[^)¦ƭV Hq-Mm_7xܫPtG.hDiKӳww;J=4vݎJs,e<}sǏo]I-<<4Mi+|̩'Nfr:}xPyJobq\BVӚ e|2ˊ#T \pI)ϻ'aZJrvн>}%9/[+U\ 4|bv\5pS^qA))A9{k\|>jgs.2M@?F>8ivRNJ%>sh75TIk}J%0yp$LJoLαЌE KImșpF)EB #  `ɐ"$#PQXj7zZU":3E?hQBpφ&Z3t  (x d&K5ZRL y/WrO%uNLXp&,8fZ a:T4Ffgj^#`V+6X_2T;Si%?ar \u5R7(jV}9,V6/yƧИˉn dFV[S!VН[&1?(_M잻XDp>%֤@5YT?mzؾ]xAb%/3Q&ɮ< By9z.);޼bCn[!*<>>xrN"Pxr JL)˥h-ZpNH)_di`J|DYkʪajBYp39CR\jOka D 9\7_/4uss q 9̟?__~>i<)cP߱fͶD)EAFr=|>rG}ǟU6s~xfD;e1NtH|Dխ??x).Jcu凧ݽ?=5*~O.>W^G$ώZbE Ǔpٚ瓭j:h<~xȐXDO˒4LxKgζZ/ߏm]R5%SIW;4͛JA'߿8b|N7/k{j]yr|wO?yPNΔ-- .bOgnt✧1&55V BjN9xLp5wi O鳼̝ b%#tWWK%<e5JoeMPzϤDVxu؀gEjtΚu΅JH1q>clr/Gm9s)y1΅"(Ʈ"ؤÞqhi auP] ? f3fFVtߝ'SbfJ՚義1᯿៏Is}e+4j{J *ȳ}fr<ywƞQ% -/q^U~WcS9Y@}?^ʹ|{߭ q`$y4S pDxfZ/$$:cB 9%H# Ɵ?:^sJ_cH'>l>*ɭG)`WFXS4V~NQW=ǏYe}B& K`B놐ۼp\T#OsAIN#~ gRnWؔxxZa͘aW*a7 :[TۜT, u;=>õǗ(M8}3CULH+Ґ|녞.p e?XPHQd:H˻2MzG-~#EW2ǝ[=NүaV+hTˆjqV]nJZVb^q69͹] P:zWEH;`@+s. V\Ҭ9|$l@rǔVC̗ML ވdB\/ö)U-a3JimI9L.T@~|4Y]=Ӳ9k.uua4ۛ@hxF[Yt=$Aܶ&&gCy" )@^]1aZ}7 R O/W}4MѸiY8Y!jkхȕ P~@/SF]fRLh`?:RX)3H xL/N6Xk)Rb_oa٪\Z|'%__ l|JJ S*c{E901v⯿ՌQXMMdVTW^p$ 8gZԴ0UUx/7=֭oj"ʢk2K%.Y;4)$ UΉ"uB6€V2g"H-7mUgݾ^aʛhfM!lKT 0K3b RUBj" goT$0$B[k2!+u̴8kW3H^1c !SRMK% \fd1r^:3b.L9x69^sA@~ (8_±"@\81V֒.(XY"lUD~#m%}VL`1qK15J0Ry&JJQ!-B/݆R7&Z_'f`%4Lѝ)٠Eij8&u p #I.۰k_ u#+Fkt4r&J|,ϩ 0eI# QzMi*1(0yB80'd F0m*m)( !9dL{$WRwM+ |PJ! JIwNfQ` (EwY量_{KQæ;1h) m`%֊W_[N yzNxnM'6k7q-^nI%r%E[-$ܓpMLQyJxOMp.miـqd]`19=_'Œ.k:%s\!'Y1:gP7&DrAR!ZrH-uDJ.>C Ml=e@ϝg# R ;&|nu 6SBS΄3A[r̋IBVBG6wd-Gmq miW.Iаz*HBɛN =F/)jo6hRyw2}7'x;n:XZj%&s9)ǘl8s%z k1Y%!,8GFvKxG%`M\޾_4e})j/?і9Q _ƣlT!C&B}7XF/;8_W:yb|8crA΂\sU*U8E["(s,$Z2rO #adyS-"7v@8 ŕRa +k!8@K))~5|;&:-OX:itLuiUx^4 ܵdI양N5KZU]tNsc U9BH-z8f>0.{fsΌ+ ,%+!ucv%m٣'# m'Vbތ/eKϮ<иmWC2+ʅH+ڕ'e(${ײ34]ƬR[M%gZk1|bK 9iz)D! Y'D0"i Bʄfc><. i? _~IlKJ C6nkBA,VxqYtGkniNRy4 #U.)$z*At ^$L IDAT7lc$Wt9Fݰ&HOJU/>\BsqRRZb9!4n뙇ҕX ΡFCN_.u9)0c"@fg(4ض%}U0v[5>u؋+͋>Y |)/cuZW^y!^azU_u*z9/)OY䜢w2;8"ooog`!xdb{CU^QtbY/16LX [.ho{d?X U.,>9.%E'kZr :5zc!Jӫ]^e)4 =]i^V9;t0EdRޕRҴ?M!斄`J`R~qPN1KYuM=4FƪuY1Ň4_tcöYtWwuv }n'"nIV}W3a ε㸖0Ȧ%BWTy=cNQ.$^"3ySBW%XA %e)1x);~^h `Rv1z")3cw0&dbh]}ԯRuwI8o}m.*0f4?fKۏoӗ7OzpZqHN2dsu|8!:U[7,[֬5\0_PLr8O\ߥ䷛Pƺo}UZitq~v2C{-.87|jy*|?٢eY?-Oφ=.E]<7;Mìc[ `rxw)]g .w|q3:]:Wwy t:*68K: 1Ϸ.Yf0`v7׏ x`i SYn@kN2ts[bWZ>NV$TUi !i9g0H;bj+`A C7g?J3G%{8 Mz4XEX2T 4s\w'ǷjτV-{go!NFsYW޺ڇ-Edo~*;nbW.KRDt%/p&/=y)n;|u6b@y iU>OS y3loا ͆^$Յ@JSYUvU uBh@T">w\M8;$AmK! ϳiS"K}SDΑ;o nex<5ѹ5t ,M̈ZQe^fT33G0A]QDT=(OrsFT缁{zoMTKUMdi -tɼV,D+*f;V @45v;fmK 1֥ݷ񘧩\>4ZN]CR[(7SS]6a杆e gTj+x1ܩMU!4eS9G爠Y2#p71RIp;fhd>lieZ{woŝ(CŃGNKwvKɥUufCnjiq!ThFR؛kpe! 0/y?t rn[\C~3BJ!SPw Z:w1qJ2bd睡hmVC"ZM~}?32.Ɣ D=7%Bbp)Vplְ ju&T:w).]^^^FSv JiR=x" 5̳Zn\N6b%Wj*j^rʹ "+%/\kD:fBTET #&R✇S9s\KF2C3mNr--׳͈ =YߥO_@fv@/>ηUF&=z2K]1sSk Uuff^FZkIrXԴT1 $G$cN1㸌5mJk-ZA^rJε ˒SQMH9fVk%w,K.{?3&)S*L_rЏ &Zi(GB20fWnDjy294e !GAD^ m"yCfTUEtĪέWdL9Llf>1eBk/R7t]/!]:91;K->%nskG2e8P Am>/D |o2H!"`ͭf4UUDVI\ىHyҚ9bn-TEՊ˲0xly2.+kSB>/ YDZkkEk)ᤦ̬❫ a:o緿OJ^b} A@~굯|yo~f%tp jCjιj{_JYg]QU#bD\"RVo+jk pDBI!"13;f1Ndh\JYq7Qªn *R"t.͠|+"jҼsLkusƞC3v]"bkH QJSR "8}ߔRknm/Q+.N'"Z5hya<@J|i<(. I@i.hXg?|=LӇcOO~D1Y@cdςW/сATI1q) "r_UTB[9f~TDTkslfLb fbBpއVz^eq\fJLfD:=2B̀X+92j7U(.TLZ1Z NMaCx]]߱ct,uYGRZ~` πD>b^{16f.'$U"WK1ZٻUjk"!h~9s Cˈ=/?}k?;wȺgdv$m}s_w;u?v[xxq;lsaAՙX{]X5 !YV#BYTy)b)e٬nʊ%@Fb*0ju# ~]lDgԂKK̨}8Spe29 UQ%@~!@Db ZVͽU뻎)缺kuf{JQѪ֟1Z[k+"iZ]e 1fgulS1u] Zk!ŔTNVHSO.xJEvö_?~B$F(}N><]`p>Op]q(d.C5i-1#!;"dcR_U_WZ#cETȱ2ʎEsjSDf޹e'G]xd<"VY\ j{^x;ŽWR3<&Ctl*!xeJLM$$"5%]k-lTj y !#;sCShر9`̳s~+%)(sa"91 1@oVbMªGԵ8ǍCcö΋p>!,xu'۹ͣϽ/o/ tXfϷ[m2_tllK?>"erAyk:r<PUxS5 km2gL^IU ȱd;B{'SɒaL8(vӴ\+rw{'\_pu fӌ|vZ,cWj02CS$$J\sV͚ʳ܊ ;%CFS Z!98vEL޹. ҬSR[t^ƘsvZ!]1>>!"N'")N)tqw ǼMKIҋWk|X2TEpb n CHq8w.w2Ӟ=!>du9.b՚M*8"FGЙt<9"St p8pRK154@#yёc.V,Hp8A&݀n;shVN8,Z~۝扐vik̮ꐬ6nxWկW>W#D0PD@T3%h{zO'E'/|us墿{!zhBmmuG.Hx9= vpg$M8#..*itn9y\Klȭ[ax}dw»o?9>98t/yYXuw ^NWO ?~V4?|7{㟿ͷT,X6C/ ÈjͶKݲsf? [v!0SĬLt"Te/|bRpB!xOWR~ͥyf z/KʃO?!_I_|qu sإZz%V*&NL,ٻO.0./cԘ">kr!ƀ0pX{l;@ wMt[˲0Z8&?s %/*mwH&ؤ30)@6q`DNə` 1e6Yϗ1C]l9H~e1jẐ u]RhuU3pm`mǧb[i˸<}|;O{5Mfr:u)9?2lVJmvWWR'>)xBKfd]R qJ!4)ZbsO46gC;_'$oo{aL}9K YJL5WC]LIJT$ƈ!Rf38֝xvDJXD|Hsp!ĮDt)9UԒ@ZuB11(ZB LdwM  1gW,?+󵚱qH+~X?g 1Tlm\ I<-c-3lfКl609| ZK]J)029B@"ʹ!sdbjd;Ufd&e"CBS#F&$Bh,ƌT8G&2=D$D@Mo11AD@Ռl=5ׁVggFU@}U/?_&u3B[2@"0P5fg%o׹5gd p@ㅟ {4f,^Vl L" =S Dh?L Z[k>= ޾/(Ln`gA[߆BfuSe{Om ,̞;3Zz& |^Æk+V`J~{5XEk?+#Zreo~GYR<۳ے5! 2|x>=i EWyݺ`@kIDAT~C?Pc35f?a]tC{Ǘ}ttGV GvmU<~??>y?ߩƏ.I5hȷL}@>?Qe/8~(?β<}fg2ii| c|>?GᓆIENDB`camping-2.1.532/extras/images/badge.gif0000644000004100000410000002474112154156727017660 0ustar www-datawww-dataGIF89a3f3333f333ff3fffff3f3f̙3f3333f3333333333f3333333f3f33ff3f3f3f3333f3333333f3̙333333f333ff3ffffff3f33f3ff3f3f3ffff3fffffffffff3fffffff3fff̙ffff3fffff3f̙3333f33̙3ff3ffff̙f3f̙3f̙̙3f̙3f3333f333ff3fffff̙̙3̙f̙̙̙3f̙3f3f3333f333ff3fffff3f3f̙3fM!, H*\ȰÇ#JHŋ3jȱǏ? TG$L@\2:{`~g+5|BIM, H = d ўR 4ui =4yB2L3ZaʊCΚ Ī"lʓO)RLMbJV R 1TM*K{3?eRn-hN m[hp@Y-&\4ĩ"=Zkd%fpQ^ر%{7VȝG[57y·֭t]g=U!Wy֜'x%('\pvU^T_,&X{x\3`7`%X"ȕZbjDvVy65,8)W\rX%qФVuML |\) +g\Msz]eZF,b^j`p2:5W d M [[{<Te_iy'䊄h̀Ҝ يuWUkY9"˽9%4Zq=byN:nRɊJحRYa]ZԲG|Ι颜!VLzSIxXضT+b+&ն)cECUr( dYY{@wp{ rma RWx |tqX<k Mʘ/iLR=zwc^l+2A]-0C3u 4D1,Wl=),_ \)}ԹGmrl{E3 R4М}^\1tWHxX}dsJxyy[y .M 4 ^,93D92'2Mr0ⴰwUOHka^Qx1]_9 dK9 8ʆ?ͬfWV\P1ݮTEYL 2MZp_Pb#w6,4laZ\9ax`=4=R)(X! 9|ADSu@,S[v<غVr_$ 1<-Ӹ3(TUCE1Myz. 30 ix?%kC~^[d5agH3GIx/b\J2f'<p Ke$׶2RE" :q6t*AP'1aA\<~kVo:Otu/"\_m IAIK:q20l*Y({" kyTekd̨m.s)/%E Fh%*JT~gY/|Dmebqn 1UIu Y*[1CΠ6|7+8@ݰ/lj:xs5C5bg4SS-Dw_KIXSD{4NٙZfx7?9ռԌP͙ zh!Mp3E$pPNM+xIӞ. qی8E~ӤiydB 'k e uy=BWW8gh꾉O Kw 2PS 1}b/"u:Z v S _mf6D11"P'k@ 3 d&5׃ȲQ%>1q;E" Pe~U'=ߢ06@]S-<1*w;%R +qS!b>tc&#"{XDoh}Q}+/!,Wp XW%Ȳ~!r lStrMN!?EGP1"kq xw! 7,pNӐ Ry7 1UyqȦ/"B [.I:+%}"i!W C)'#q+P+MvVUBʐw)lsVӎB&PQJɱt!W!7H A$k}[Y ҃zɓ!G)D j ywǕjl`+1, ;=ezUWY9!FqֱW@VcDOyA K8<ɆB9} E2'XO &DͶriU!ҕjz4=hR),]\]]`1Y}UrQaw9}_w;5bvQd1%w=hEtnT-vh7xq^wLwyC2\0٢+O`[#S " >T/rVڄpCJQv~8hWRфh!yaé/1i21/| vM1($΂ʡ0B. d oF  "q;@!eaUИp\90\ I-!,P`P0TA' gau%)"J P!gTJiD$,y!%b61ࢋR!+P5%2{UyELאؘV,4AWQxNd5|]VOeda N$UǮ\m<܍ܩpI˴Zfm+,X$ЩVӨ RynTrc*WhT*]\  I R<,Kř,ɍy<";qv p+2bY}ʝ:lí3ZV!\ǩk0j[l7XK1];|1DI!"ݫR Jtu- q}Y1UNP1<X|$2ɟ]l=lmq5C #cUV JՃ,cڏ[-Kzgz=ɱ ĻΏYL]ØÂx)\+eP1)`]{,@L՜>dmNVinZZMnPP:>ɝ>ɾ>M~ͬu+U".QT=,ɻ^+$pI&=,+@vZ=Φlp4;0m+Z,O Q! QJ^)<Ėlӎ;eDm>ʟE( H߿߭LY2ݔ-+P$PIn q!r!'G 5O@o+T S~/1CoT{Y<%n5 a,!"pm+RwiM %|N_hM/ ckJl^5 nN;{1OP$O1. } )`2PØ~ANU'/+N bJA+2p  A++ Xd0FD+XX +(qࡂ81"'1|Rb*K,kXat^|إ v G+,d!PrYU^e.e<&jY (|C-`Mv;MӢ&Lۉ?T('=@(zD9b" (V,%2 ;p),4V:(%) ChZ7Vj" :zС$K=ZJDQJӯ"V@YM.`.0RaHУ=#'*z(kR*($vB" 2q& (22!SNQ=dH@T/Qղh*i'+B*PEVRSM{&O {H .b,`9 TFز4h1l=*z)1T+V)Nk7L0hRkJK+X9v-$hAl* bZ /sIH9:¾hp'= 8dͪ@&PD*hfA@VLXLY֎\Į@ܒ,FGl k""SE!B 4i pbU@*%K15۬{:H$Wg 8i3Pb4o 踘x*֣@c(wdžokBd(h"Vb(FkA^C4=M+2I{&(%$! ÚApXaENB:"͂Pp֖!ѰBnR(y觕V+~UA"3M;j!ka$F0 Q#†ltT*K% O#^c7<_lcC\!h8vY`P"P M;jb:eS3a8≌X!c{C)&z@,1(E 2J#, dZujEE2Ce/yip2c\36ǂVr$Qr*V|OI QL D4䰀WO,X eA<d"p1NJDYA9ل $#hP: j$B&~*A"sHldW5bVXFD ˏ4X%@䲊* ˾hd$j:R){PV̢*}M30cvI&k*(<$aˋh Mh]iV$>&&RPj2Ft8WQqh8S.H rtLȝ,2bg($9*V(@t" a 9\GV RRQ~WlAfE͊VBOjAL¼(!y\(#ǫV qD[U!d@50"gM0d6:r 5/T2ѠgxRxN Q[)yҢjT61X8Gn:O|W? Ԟ^h_<,$-7J#1j7+!…'+deRC_qg 'jkega-Y*IZ3 * E0 )qrB؂ Ѐ 4D)N:Nh@#ǂFX Ys`aXt 2B;|I\CV( eLߧ9yE\'D=3JѐFo~JZa )NV./ ސ&$*Jºc)H=LE'vTPz*Jq)tnؚ:MdN֭.O A?"U\d)..-3&wpbwU[vK zݩkU5!RgE {]VA {/IGX'^"]m>7QN ua b`~mIQ%(`Mɓqp>Ai[жxBV06DNjE(/ZΊP,,ejdz1Ƚe^ ~TPs~pC-+4cW{>lck3m>896p.IyX x+⃂< hSC֨@l! 0 (˾! ¸+?q (@49`/:pMb<A)كQj =Ïh8ؗ!@5e5$$:#@ 8*9=@2۔Z<1U5,2tY< \ȉwZ!鉠=2 E##y|A8zQRH;Y4cDȄ Ӽ,يCAF\'Pq) PE^ ۉ#2(L "PA؍1:@dA*;љP U,+>4YL9((G U܏B>qpDEZ39_dܙ+>%ix 8V $ DE'xX#+ bMA O9QI+@2F+=.P2I+z;SPS"xA=Њ4>ͻUBJ =@G -UF|?H!1,JbbM6kݝO>۸<$X12Ph; \EX+VxSM :V׀<) SX ۛ?#@'֡K 2R⓶М*5R YPMxA=Lx'Vİ̡\K#! Ra )\[A3<LU0&j4 ya͐aD+`:TkHpqCQ ndP_AO ƿILt |V`=xъk܍żx@婇~<&H8O 6Gm0 S8SӐՊ( [ٸ@՟U X|[y VHXU Q MҒW,) =@ůLH$鳍ZsƑ4S;+ħE$yNI5[x]-sSg-`ҌÝ#zOL\SA_y[M)f!@Uf:}AUU[߫URA܅QŒX#tVL糘+ɒZC ߠjcm:_T~/p.+Rɡ (jj>::ʫЋnk`LLȄkNl^lnlR;camping-2.1.532/extras/images/latl.png0000644000004100000410000011711612154156727017570 0ustar www-datawww-dataPNG  IHDR3tgAMA7tEXtSoftwareAdobe ImageReadyqe<PLTEqqquuuiii++*mmmfffZZZaaa]]]MMMIIIQQQ999AAA===444ð111 շ---!!!%%%TTTFFF{~~~ͦzzzxxx|||WWWDDDktѯddc⍍Ȟr}ٯĖcl`TIDATx]SLWDrX$r؂vy)`E)〥wMy[*9HX Ǭj>s c|19s c|19s c|19s c|19s c|19s :?|gCk=Lcf~͇|g Z! #,egO|/,ώ<}geTX2nsfG/m1g><8̈mH[c`GbRr,p̀}x1 p$D #'ѹasvTǗx tٰ}PtW)׆S4W]Icrr@SrMkܚ ѺǃZH*9'WHhs$gCE-_6w^~uެ9 {JBEгJb,[J4s G껒@'b=(t{w=o1쏆jlS l!s ghTON}g@dZ7pfFrٗfw gW^]ḧۃ,*b˖ÙP>;Gs gf%e@RE/4s gd֗SX11a3<;G5pFFZq\L`$ZΪ ]3pvFàD7"P(˹ֈkEk944Ag0D}ŇU ?:Ls gilhz(wEQ0?eHdSɊ=acG!0kdg@,0Z\_r67/Gz[G\Mu@4ļ[md3ÿ< W;`bNih9'H*1em3 ڰ5$9yD ׮ceXJ뫎SW/l#&PNwG3h * aDfc{(IM 1YQ"[/9Dn5bOm_~F.HpȔ؊F<3,?V>^ } ˯f]}*_#w7ܨ|ukj'#f> ?>cx( 3f 17똅/f 2ĦQlWvV_VcxXcv y5~d`pҲLgޛ3Uq)ZVMi4>˖5b#]_s{c14>Ҍv:j ꚩ}*̋Р) =KWIGL£h͉5(~OGD=܅ czQ"s&6uchy*WNa,:?$HP(߆#}qA0k,+AL0pMDqI{_i 9XEXyظIlA0v-iCuw!NW | E>+pW>/:|Թ?W@_g"J@> fG 0L/L"L :sJFۥI-!FVaDJ;n; 0hJw7`K0l^FW0z\2ҷr7rBR=ċ̱Iy8cIu_w7AZ))4'0S=ƭh7 \Sc8k,W)~Gs gmTiE4pF5I&z԰U+wa%ٮ(a߃PpT=1o48lye^fؠ'`IKR ْSTQwVBN)%F Q Jԁ8S[ ^e C@Hts'wQH6qGVg*g ͆PPb5.nwRD>cP"D7j!{cP7!G$TbSBH:WL$%<"i^z W&2%A=) MtfgbPoPQE) eaWQ3 l1T<& ;/0K?ŰpEn;~48 rnŰcP"|TPfF !*$,G*w? Æz=ŰKFSaاCwBnp5ҡ[V;zh%4B thpFНUaܱ@=CdT3b%XW1TA:H o bE%MGFC9.䈇:!Zr4C:`aP%Q9DJ3yrG"Izy10?Bs+ha7NYݍN4hJRy,'} ,fP0JԁJ jC=M=F#9mFIiZ'g?O'!p97 1E9381pKg#97b~_»!Ե]ly\ ̀[pRCNKg9n!UՁVCP 0lpW` ahs(;a ;?`EA~?G0H"{^`hw :z '1\PKwDIV:obhZ;T c@(CĀ^hE Z en"7t_6q xHȄ96UFkግp -'Ùc8SMCXJګ91p@ttۃ}}, ;wa2E6¥j2X11j+oO:GQ?N7b)@::՚->;c8|%ڎȦmba ҡi~}VokdBʙrNᨃHwGx ; &eaQ_rۑaT alL Q^N7m|æVwQ1ܛéAiOԜv%@B841: A@v@b-I as ;9 rέH_>bwta5Vx=+BP]|yZ:i@RO{ }X\ڌ`% P/ &: !YI6[- hǹ@L1Tls&0IJ 8fC=/qB $?o$7V_yEgCƋx.ǞG_pJ+e9=?-[:j3@rv xߢߚ9 [$|Ǹ{8fߺ1xFFߞz MЏ5DYZ7֐Kt41NaO="pڇEp#~~ytA17GP2E^+2_ JS|n0lDTYsGul2E^. %+-uߩ& I@ll'r}W N>Z f8WMKk0~84aU7?vw/%d}I (gI(QBiсlk0$c<*S]n(ІZQofeۈw)Q5ZqU*7C#UR+5e@ns}0<1O z?FF!S`L+>@Wke HX`9,k$h<@f=nɤUİ1LH;}3! BYC!)M16Ձ`m1K"&[.ΐv K "LQ؞^3M5oJOdGEsSZRh +i HsqF3db޵"wj>QǬv̗Z#3$WOmQHk5}V9@yLWߒظʁ6/:Vf%񗶗2ٜw܎AWx+KbS'(ٺVŮ5H[M;0(ʏnl {bE15{@dI\jYgˣ&8z~gab|J&:U䔓@C\d`[?kY5k$/b" 0QinRt,.3MX;1u,u)0)@lJ]>toFZk! ȘU,|'w[ S\qV`SՄUs,*V^:"U) h0<+Ş;I!:H %8DX@z,ĪCXZsFsp2U"sH.Q8TφcNJؠ2*!AJ~V*Kpz Zc w&@Rtn(;t-]! 1tab/~map;eCINX2S-NůTgBz m.yj$*_\ܑ7Ə][$95~ %&S'u|q;q(C + %4 f@^i L! J_nqDlVEKⲞhݖtbXs$mƆ؜=n24>xT(ږϕ?0t653 A -%D}cG쨊tjT)2gXGaX:=|0:; #~T۱?f ?ò ^J]\^-T-,c! 9Ka%ˑ2xX !7N)K6ز5zݯqJبˤBz+h[s/ojZ!d2$Ctk*"7o''@8v*h`bGtWQYf6pyɅ:ƾ e("[.k|R+U鬕 6QJtLcT- 'b\r@&r`^8< G?72Jz4wV3P}년oYs=Kӝ&oՒ+b~MŦBNE2cPHKE}d:1hL@鰳@L☕p^ZXII&Q1il( nPR_n2A2CRxoƒd:;Abd[̛4uн=7?Y1zC!MӜE:}o9LI'yIK2;m:2)eJ^bg?;Y>cŪuqdy)Tsӯ@ / ߏ9_{Yd]ۿ[@Q/e35eXpE(n\Hamp>26'~65cHaPj0+0l>%O$y]831 4> ^@ЊE'*٘|K]^+@lv1HY  U? \iĕjӅ!m]0pC[Y '+~d|?%B ɣ.'kJ @MVS Ep; mhBs,BdDy^BPөPǼAN;O05`fozw9 *{,D 4>AZpUl"sf#'y1]+zxXˢt5d(ԕh[2$L 9y\/^"x(ZVPEZ /!}hd G @Vca^ yPI?`3|qEb[#r*+=t~U Zhѫ`xI+,i.nӃ⹳k*gF\Qa8c5 iM_!bQlqt9:K0lf,-[ZIRe,S _,*\  RGy]j6gwGյ9m1 s)zF՗ϯW'aPh4v{9${,&uiS nD ( ahЦNk&P0P4 9:o,-$peW:* ?{aH +=<Ǹ)<7Hi.U5 D 3n^aBT|knLin@J6tXд#vDѥh+!$1S=2'DTөG=:#,cȲXiy |ػZMN/P LP]BCȄ)PP0a#na Y}MO}D?i"`C@L Vlq{ӂ>D# ѱqϽ}UƒDS]քe E7$ h:î6ޤ{e?.|D߱EI;ŷh)\ uY;dɺƧȹ$p=+gB"s  nȴxG-vi|U<,p)õu1WϏM8_ddpa_Ie2scIOc$uJ'Ưl"1ҰuɋhzZ ZI5p5Q]14'/CP~}jŶ-ʥڞCte<)ҁ ȯR$Tȑjޠ ;ZlAVD&yʥg*fa%G oDwjR _o_Q7,l:N:ʲf݃;n6d*k JVbT)4ڽ$@Ov_ 7*dq?Ģ'x% af9nyvcu=rb#<{zj_LWEQ_cyք sb!nB*h%EN>bI*J;[ӉJ%H I==@Wm-IN9VXJaQ{1|Ni$Dh^ U3XjuېOq:aխ 1ͤCzGԪN#iZH5Uo0 0MXiC2ݒFn*{?72=M tOCܬi,zENkZV[e M8MgKm!4Y2~^myjт#}?T%nLyUe:NO2U<4ٞ7CvTķ-c(\%;J+%UmS_À(HN3sSIRDRS<8ZHts@`.$ Nu%( JOPDJpM84 Ŏw@ %TtQL0V6ZJa,=kKAÐ>pB35u3i8״ɮ, O:t̏^!JOayS1(Nq6h;!YnK+K@Og XU Rӛ'Ćy6=){Tu3ÒuE<g:d\Zڗ/=(-DrC){CYDf6ȤM)vaub%l'a K@&g7- 5sh` A1)0=򈓋,C~6Ї!-7󧪿r @H<2Rk AoBz0nPkOŵVBwu |E{\󘜧=}^sVGPf/v x@=i͕v1a$'ёPFLFȐˠ,o^L\+xb0,TɯwW defr.0ӇSeQWƦծ{ܙDn0]@\?3 Vu[uCfYH9 >v%⮘(PMǮ ZHj؆h[yV5~ɷԄ{I(uUfz ]J;MCA2F Q<bBނ9+!NP%fŽpC-kQd1/D<7xqpCW,UD?Y !lF 7"o1qG|'Y`S Z\ $EN)<|}QKO rS}(ۤ/5lHj!0^RI6e(%'OLf}y0t`(|WԜ-VEAmׯPS̸[z½LEAlRvA3a( DqT_I8}k6ze0L1|KϿTQޙ~ R}&RfaG,i!1f!% ~wfĽ <ȰҽKsĦ zI 2+mέpF6 V /Zn!g*+$W?wɆ^/d`e+VL*X^Hœ{u*ݫ'Jë)܆4'C `#}@Z=St3Ke -HR0.8ޗM>TӜޏ2T sZ*w^+26LMՀo6SF^Zi0l~Ծ3:qI .{4_vlN&n} ܈k<04țɫ^\& Wr~d}x[ >ƥ$WnCo0EUșM#K1rU\fC&W-5ѭYI=ht\4eVu2O]2ip'v Y`f^0+z~AiBLW P#ڔgRaЫ]\iv(ነ,x"2ormX,IVfؚ" Fu#LYY} d&$hpF1WCt6 3b,|Zޛ:mlJ!2{e{9˝2Erzm,d6o=1^'Au"Ȍ+tѰs}nuͨ,2m5'tFFc9J{]sL M3K+0ܓ~l4Sؼ * .Wl +,72ގjc Fm\dKeu}K-oHN)=.V)oW;{L{OKj+KM+UEJP{BHO,Z+Ì9O Ã| I:!4y&~{9 tVgiG򩵬Զ,"~?SJY\AՖESVT"FˑgR2P{b>? IWawV_!iRS1ЧІg"NТ :ݝLvNqþ~`PϏ݂`C4:c{fJ0>)72 Kk&?v.SG8vuU(Vf/6?w'5ZEr-5~wTAJ[2 kOCGר _A%`3V% vyF)`Hd҅?ƺۄ?+|b:0jhQBDdhƲܗzC;W^{5z(؅ IVQ ߵǫnwA}Rm6r NK1Txq0"@dQ.C%#-=  VDW;VoOqqt=5B{ˁ`hvr|#<֔NJ]_0 C:&>mȔDW- ' RQ(9s1)tȠ\ x`R o/#OeI*Y8]=PEݬq%c*h *o2>NYd?*l9 j $;]SEw4tG'^]5 ^su]k"J=D{e&p8? ӟP@l2'ĺhI91-3ꢔ_$b  &k"Qw\&ͭ|ZZ[zq+ >a*MfSX0یR'`.#p'$ jʉBG1۞?5cM-K:!D "x! qtH]7I=yiƧg̕V==eӂ,D؜K2}0qYP֞2C;?՗PCG'c腙mtGk⥍ iH=Z6AjbEVaOd8ߤ)ɑ~IxoKxS^zn(3﷏P\{ a_a9S&YA追o{!^zH@}8<|8rl!)bTMA<&: 1-״Q, zI{_tsu4tNJ_r r~{N?;b3t+>S~<'iD("b7PݠC=ΰ'gS6p`8*GDF5^>[¶ܴEӑxA ~3+j+aaFh˫c+!:, ՘~B "RZGC9 sVEIra@E %a15oz{RL|:#qOɏJPgmx1/p6̶Z <) x|/C`E0Ԉ!4N=0&=,a9^ֲ.$,\ &[.R[ӊoDK6j֣mǻB1LYY '>K*!~t18ab'ٸkԁ BvP,-mf5} 3g{D=# )gnba8v&Ed.]=Y9Snp%0lu5f ֌RzljZX݄TVD554wŮ|);J\դeďf& 9o-Xd~zxkDr|D]_^O2!Zخ+)]o3Nѵfe5XVf=+Y[%H;ld}vʞ"dc c0 /VuI1Oy~FSAjr9dLa(벂~ϩrȑ}EŤKT K<@Na*^CP0qJ ?9dP"\k4k'0})vgq nśBJ f^hb@/Y0Tvi2=/j}atN]W4ž"#n;2/Č2$c+,qZ4ۛ:wɦѶQ ${ܢi7Kfͬ¡'-84\Vt4/!2ˌ<ЎvPcs;PRc4Vmk+r*shC?#!0 d\g!~$$VEcOQ4e.ހC@6eb(Sí]ӹ\4܍*>FDZ1.8uK'$&8gR=EedJtt9yw"M՞rg_?v|}q)tFeb̮rͱ5FDj@R0׶?`"TLmSO?'Һ E|SrJ)^FjC#)Bq 5pA6 JH.Tqu;f\m%ylZ^$u7qr7jVXw9N0\k93˿^X2)B4;FVQSHSZV^UX-$;>>H}#EXivWnEub ЛjȖJon"E)0 qbߙX_`)Fɱ5 GP:|6J0S_3.7e<,J56{kv 06w.r(BMDi׷ dbHX@H(7 N﹠U콝yp$ћV8ϗg?M8C7o7[^Cك8Bk+~Qsp' )'i@a1w!CSHm- @D@cQ'&kA/2 W> #$mx^CzF?X!c0ch/UniBe4( s_dդ|j-"t(7.yL=?gu1 /h WY8J"Q+W)(#;PZ Ch jዤHOwWD;z %N*1vl-aγ.Wj|;eNDL !-  |0TøvOU5bpZ'Jh$bZu:f@R it(0_B0ʢWmFű6-H,væ$QZhK.L-X=7 K/` #+S-{='> 4Ȑ˥NWs JWĭ'bٜЈ(E U~ɾ:8te2C[b4>8L@[{2?(%J%e՘o@óltNXq[jh[}Vy:(T)%u[gAzwTt&ም~'6K]JMQ6? tg牡)77?W4Nn;k~CIٗ1EnXU({ENϤܚ}frŴ溄Lm}\8ռԱUWb 5 BLp#0]Zg}wXgnA5WfrN rGgpJ,,1٬XɫPW]P,KЭ4 a¨.=SDn젷"77A3K SLvp(;(0XI08̎}E"?X=e#v!!s-1D" -E5%۾/{iU9[U= !3qCzw[)֝% |[,N /MLBF?Kuax1XE mȮ}q X!Y3rAjS,J =Z -4OV  dBD)Q>êhygo2OhQՎ[F*uiyAI'Yh!9^z̙ Ӡ%S^+T ="w0l ,#љH~RoLg KU>0SiXR=qi.&>Qm$L~w 09@e᷃q, ggUZY2*g90S<ٓ?䊘a!|mLP `D>Frr<<*L| UYtOm"5cdG7,'Y 8%)4ߺW@Y."Kx'W5S"{tH5d@\? ɾmu0nݯavaŭ8E}p ɋD`ark! 5d!<d1QiNs[jw>a pU;u퉭^a$BԔ `Y_;j r,2Fa:Sp̓Ā3{cw7}-%zҕzfw25%*~&Fs?a+UM֞qnW1ljWxWش<ќC WapJ9zO :l0%Ժ=,$%LG? χ`FʡU%qi@۱9fc6=Q3uhlDiB~YBQ]lt((,I".#MȖyx**A )Äm'k;ɸV*ػM2DI,`S ROJ{wTy=5w5n*jGy b's>Ut9/C16G<ăN,&MFl{z,g ܃zWb;1j<9To D coGE% -SBb*4Mz{7R}]:hBa^fE{%d)Zh~E(Nvyy,@Æ𵍚'#c{0h%/K>jL X7.S2U -# 7Rt4ƭ`4E"uqs;dQwO:@ #qE`atxE5:jzݸyi \i6EOP;ApES Ţsv eP)ullhltF]+ek%}f\mPZ>G3#NU:xdT~U24Y[ A _ \TCSviF?66Tqcxܦ跈<&M ,ob%m(cO*'q饾2"3 a\4_W`sݠ&BVRԵfC"+Glkg=_B5j( ΍ai+\ KaAQ@V`Ц|S9{9ҳ>Ks%BHDM>L{Dzv3a H2i^ id;[=ӻH+hn C{mXϲkIͽG"WWmWmT/H^Z*o3 Be;n 0U@ $610 ;Ԑ)hX96b/5X NEbL \ ޱP2Z@M;9&bBōx1kDY#JXI1{"kK7#CM\(Vk{NQ!nۢሪt ԂKpǶnyFգhdUx2 DT(󱼋Yh99C2@G}D D֣v1$lFζ$ 3X֌du>.0QBR#)=]GT, ;]t y:8soA?&3 ^٦i4u)/؜=Úp7 hL'ILg|lRCMg)ޖ|C]겖*b MIHx|Gҡ/mmiFrDӠ%$+V:Ho$6klVGh-ڎҺ ^ttM,!ߦf i7_.2!hNXGxZ2r5f@(é(e-8Ea|[ "T"_YNQv2u)hNW&+U5I ,M$X\: v,pVU*)"JIi1Fpj'Ƣ 8\JG6K vzGMh318蠞?F|Թvy12GS8Oh?RiÎm+HjxqFiYZG yyH8ה3e:8 _?Ъ'X:0( _|dQ+sa~t]Fb:ݳ":cA:AVO̿tSj6byK^1` X ޓXz3,?ա"]%I@g>@yoi )&ՂZʛEf( ra@|UJ4uqH9Lz+/QoijVAZpC9Z-ۭѮ@3+$KQXadZc'ZyJi3oa6b7G!HQ Ԃ pHm;֖+?lu+?\.q8mkddx:k}FobxtDdAxeYʹE(JRB379~ {+3,-k@&m9/a-s;S%-2kU/h-ޤ!E$UZֶ3ZxPH4ؕvӠwkBPUDNsR"32̦q%ʋM>>n4gt#jQN/aѵvtb(#$)gVu;D&7~ X Afbo8f@[ygxCV2\ Vljn%xojk.#2|֙"X Uj v~,qu}l{nJu~% )c {RE'? !U0(+)(Eړ ,i@!Cv-D}m 6j ss\*jMΜ7R:Eq8+M'2k̔i/UR8m~vVlcf+wjLudhrd/,n28Pk?Hm+󘾕1QZSwHqopx5\D4\}hg7AK=EZhY*x@X@%Y(d:Dtv`H UN5p*[GdʴR[7U;bRCoTtd=㧊LKjgs %+_'JHuNz`VyQ38j$PĮSj> jY [jG~MD%-l{ӛ7$ZFK 2uMLI-8ךHb%WO GI=a(_2 oχ3DA!U%'$e#Ԇ.ܐʅ}@&K4=4E}|ɢm#IJxB9Cy]8^,J szWU/ HW J@⭾'9)1uw5 39xoϺP*Hvj>\Biccm Rʊxe(L]gtW6ifS ~.㎦+ .U $w=P=zk>h4KL٢t "s* ^Gr4"r/ݛ' Aϯhl+*el]ENLEL4.G|o]OC-,iAi=-RlΥgBJq0*r (nJu5+k5޹ @\Afd6`<ɹֳeۉYQb-YxCJd_{Ee-r~`ov3?agKŃr+)#hJ/ j`vǦiN'5ET7e1X reBo`__s@F9qUrh\=Z$JpO R6ME~X3ؑv=ʘJq\y5E7`z8/?Ϩ=ϖtKV+OlNC׆>r%tߛQdNX -FH@xӎM\_#)\8,+X;ڰ b5rqg6*ˇ1JGGo$;?cآq;) ;D_}j/U׆Tqh׽y;\4{\'ϧ \t!j5TnW^.`+$(cN/NuWdMheKǛ&Msg/) 5SKi@2e|( Mz0l OC%*t MTxȇⶾ.S%'d֛ ,yQ tDD9KN$(gkG$MYٳ  (5Q3%n74Y(R^dE>ox J]?g %D "fɇ<>koA% 7̥ V[$/k<EQr *J109 Ñf2h [n{8r,C= vP&uLz[/_" ,ɶ42`캩ԩ pfS U^AlyH\n:MxbۺBH9)\Pfmg @DR I-$kK||Ÿdu͜ܓ ]}al+&:j@R~O.|O(Ȏx 7'h$eZoSdfV.d;3!&x5#宱rB3JCqyFrxE]ĭfKaE=3S'P# ++MD+fOZ̓ "VTkrݮMIuŜ=1H Ѡ>h{rkAR"+'3l`EE5 2OaAþ2[yDwxEZ O8c(DY`ɜsٞMƿU X9Y*Q*fTGɄ1@zIOe#2oM"_[\I>chO_iޓ&XA^iM '羹[MB) )r$6ǝgM悹E٬U '=cX NB;P 'ۮ o`| Xy&!a  <Mix2q3o%c"eBZG:&ϙ ̶#:ƕ7fktR'C̠Ot?w@=K%n 怩gqRWq2* ^_pqѕH@y M5ALM*=ɨΊw!VJV`c%X{x-=ul[ĕQտb^,Ԉ/%!AWR^&K]{͞)ʐ*%!NmRw$b͟<:,X?RѫkmċlSRon[pqZ@[nɣPas)ctψjl@Ȋ>COma@oF/"r7י 7x+ϔR7b; ՆJ@Q ueI/$+Ypx^,gnۥӍ:a>ʊ]meiu|B4l>2Gi`s[6 $$n( T-aðl={E%G<TruڎV,5bB%b8oc֍쨥Nh:̰@'Fe5'ʕJ5xAhYoCN=lW)a hÒW:Ѵ1)} BB,)$;؞,t)i`R^6-ƙ8QB`uy_Knk/bX+;ʮVó4|.-$'{[[F8}#RJX1朔ҵHMI= 9kM[ڪX+_--1)yoaD{o'6=f .>ڤ5o]QY+go%TCyՑFN07 1pj[0rG/J(EVR4c*SٲN:^g3n~Rwަȕ8%>wQؑV/7 NE)GZ ne?L )4oȏvV\8bW*罼o a6;G'uKOxN51 _ mo*U ܱwur>r(o液O'w!)J܏Z szOܢD!H?)C }bu`߯]҅=c(k*oK/C,N;g{&dHּcLmżaxcn ױyZ<ǝs\(dwudm ϯC~[x01dC0r%K h{ǰXHqᎹ|_&׸x‘~y8Qc\yf. ĕr!6D9軥e%z(i[d{ت)L"8#k#Y/2Cn3?kcXq;V ioԛ{ȍ;/YtOzm1)V2">.qoG홎*eW1<AL5FRZ5/{ra5JN=W1 h9vxx D#סf7$'n:"YtA0V/*Y/=?hTݫ7w$C^żb֨{~ĨB2L%s8mBS0O& x{ FM.|_00*ku8LzŞdk+u}GC^QGc>{t{DG070,YT P1;5y/}Fw'C^w;k7WwMDн<*eF&ϰb 24 m5΢h)l-bNQbw2a^':hvTU 1N\Z{*Rv@Cf;0 ?"1TÉh!wl+R9; 񋈝 J<wKaR~NI*Xv'H ]l CLa b#Q_IC{>'E+j,>gjQ LƱ#7?D{?]3,2u^y#21\dԣYjPSe@  D5OBr^oZb]$иHJ͉z`V0Pu\U1(Yk(O cp:cdwRGJrh\fY0%D¼dհ)0.ߓAǪz_M;ZIoP\J k_ǩ" spB^_9*Uh=4WpT`f)OYYhBhsIJ::dxk L _R:si;&T|[b)9r:l!o-r㍳O~qZ+s57(pN7=!@3gbJ̋˯w+ l"SK<,Uwޥ!OecYirll;|(Z隺R:#8&h8<UY-.ro%U|(0jT*RT-@Zr2B^Mn"reT;&BHM{ 6 V1˜V䰿u`ǕKL>L)}rcS*OQ֕_I{6=k,ZUuB\叼7o#kYn! 1օĝlPIN1NlFIL4T:ͳw|EE7ӔiS!3Ov$5LkUfb bg4"dB[VPg77ʭKeP2doGrY(zWyy*%!2 Yh/#Eove*=Ʃ3bmɉ'$l ֔;ڒ/C _\K/C#-:5(I8h{ "Ns12ZU\SPfQkTZ S8STA j`52Z>n(<.3r Ne*K}I{ ; ON8."c<#z8.A(NaNn-bԺB gv;oJ}ZFЂoT'݈ É<ZL;i !q°닣{l):W!~ٵbpHKvN!OߐPMn%0)Nݱw+x?kt֧~*1FHwEʜ,op >(E4[ K2զփNBDU%\NS8F+˱0 }x}k:{=A?EsWt0.g09k;ʘO}>qs=F{yv+l6r=qQV'je=a8^bqYuϨן0ob?{iTO|{0. s<*Є*e:9ɒ*XNu:c8@͹UrvqqCpXtmИ ?}}<W_^G+??bݫ>??}z~ϻ5^1μg~GCB_{ŧO އHB'sbdw˶rLK3q5qf˘cH(ýa=TJl1.זX_ذ.=/Qi JIt7G`x;ÿ?ÿGP>,}Q/@orx}C>gY҅{}}7C|p@[5 Qy$*N)-d(OGk \EB4ɔ|L07"Dj^be Hj8|qOV\Ӵ v۽`zM͢7҇h_"]@WJZ!Nj^·%{_G.//s7WDc!˪9ڸDo=١yRldR NʥBQf,$'}67i|0#\LY hU.ȺIQb@%g+y{Յk\Ͱ~䝛cw_1Nʡ;$_b?:D k/Yr//` v1īY {nt# 52jԾ>54. "֧ P:ڈV*M4XB,<O(:Ì&)OrA4|p i~?+$bחɼW/1|  Y 6G #*m~ti>,ak×H~ )3e\ hH;^# gjʂ4ͺ+  .G$r??Gf;tiG~ƗS;t#cEa>zïxs i U NʅցcN&)嬴D|*2VI(7hB(;n޶@>Y3ܴG_?%om|m}wʗga Fiחz/eYv},!y cMiuۄ`oW`u<VUh9γ-QCC:FFBq _j!?;l t;.9FڽJ0󬽅A:v⤙j2J$$ gU`q9 bՔҥd0'x4 G!Nt QjU1| \/_~~[?TO6{#M<^**Pmm9qLY/~f=wvnTG]sN$k5(_K_{+E08&Fs|IKmo4-nV\^51ǸE\9D)ɥ7~ T P ))DxeeD14>"oԒ{iöhq$\x2,e|6MR SCRJc-({a.4'8k:l 'l"zG `um-m͌MxO$/=;"hڸ@ĭMx//[IJFɐ VW~G11-An660Fqf~g~YISւ1E@<(B~[΄JɻϷ1_&f6'-$@GȆդb&HKjE4NX{ZBZjۜ˶iTDPAϪӉ 0N*UUeȴњ} h`f`R[[bh P#(jϲBL-qD81QUJ*Lm=ʒr26c2)6NX(BQRC?2v{ ߽jSH_q./^8s>{߾}}:<&B{spg;&.{и燳"à )8rQe2Be0?yDD@yatC<\(y(?*.𜞟NAidX̜bOLwQzh_4+k~,}_~bݟc .>~G.R|+_v~\{|^]\pͶe^8M9Q,][{5/O^|G ^D5 խ݅*-y. j![-)ɲSCƛRNI$ͦX rbQƋT=")dHEgZVϒ3ɒvy^WE=tko}H 4} K _ӏkbO;r;cn~A(h,fY@3O G^'BOڨ>$v4ٔj ¬rV~xk0g3B%Dx7q;RW1|f8Vb쇽+>z`Y~ṛ/hmc'͝1BPHf?'B(O.eT/G2FyJm Rhp\fe= ySkiؑBDŮBNS :,>i2T/1g- ~ _ . I/8%F}F4jcqhad Oڶ&9r?Ú|Ve~J¶U-NM[>uaSq'gXVjPiWlSΕZt2LqҀ&bRdo*KY[d@>엥_)K},>`F{# +NO goo **qm1K<6+Y,p©W8-jZBL?4K'yÏ_'Fc6DIWaOٿF"Ϝn!jJ|+Ȣ0ѷ vP眨Y 1\0R5ŨyNS1U)^YfBH1i7D5!e* q^N挗ة7f#ٔcRmg ѝzr鵬@ B֣tva^l@%D61n'za{1w1_8kl_z>|9!k>#ֿx~LO]alUHz]B-RVF-Yܦ;c;ԤVЧq&ڜ2[3~-4m}vI?݋}~A ߟ92v=;4EԺҷJj,L9'#cMr.z#!(!,ǯ~|L w[ڥ/ |^]]2sg&>o]yxx:_H8_Z\W[Y>a" lGy8\>//L1RSxV;lxKʽgpf:*}2 j7X#0rVV}90,U$g╓ Rm2%v ZmoTnuFt0qs&_ Qf6= vo`Un}Rzw~ vCz1 }?^S9`0s? `?? w;_wB=IENDB`camping-2.1.532/extras/images/i-wish.png0000644000004100000410000000441512154156727020031 0ustar www-datawww-dataPNG  IHDRI[0gAMAOX2tEXtSoftwareAdobe ImageReadyqe<`PLTEbkյˉԫksu{޻ʛٳæϣœktˢǺھu}ЫfvtRNS0J%IDATxb` h CȈ @pK2 ! *u6@A/&0Ā4qÐ`br Cc gg_LdH~|~!~ FF_`_ |SU `NN 3JC]b``0 - YrUrB㉝I&NVv Ap-PAtyvVs?'+ V Aj{`ADc _,YN yst$P["jfT9p[0v=B?s7f'ťnLc z` vAJs FNgv؁GOHn iI1ٵ'Slq /f39 (7띲{ꇆXlxˇ 6P1RX3_je1yZ֭O-ha]~nS," ݎhuhQD:pءې}NI,(?%@X/,+( ~fN!.&VXn``gG^`N],Hh +Jeb`g@N-rp ~φB@(᪀X<`_ p>)(R*= 6>^6$+Td` vaj8@9x^Y_Ii`΍OdqKՙG.cMte4 /jaăt RAcgЃ!?V'! ۿ {qh*LCS$ ˿<ʋp $~P3JGe#~"~ n(yg  $DBHvo ~H8 xL`^~"~ّBhuD^CP91 Ro‚%Oss0<9PJy"ͬ&ADDXDs qB[XCO`P3qI%x -"삨=\B]2~p B t&XQGaAmT]ka~p {F b /"Jj}4OhH_ %~~qFF_r:_v: @C1H\@ۢC[?/3 @|ЩdE%` h ;,F5!IENDB`camping-2.1.532/test/0000755000004100000410000000000012154156727014323 5ustar www-datawww-datacamping-2.1.532/test/apps/0000755000004100000410000000000012154156727015266 5ustar www-datawww-datacamping-2.1.532/test/apps/migrations.rb0000644000004100000410000000426412154156727017775 0ustar www-datawww-datarequire "camping" Camping.goes :Migrations module Migrations module Models class BadDude < Base; end class TableCreation < V 1.0 def self.up puts "FORCE THE TABLES" create_table BadDude.table_name, :force=>true do |t| t.string :name, :limit => 255 t.integer :bad t.timestamps end end def self.down drop_table BadDude.table_name end end class StartingDudes < V 1.3 def self.up puts "There is only one way to make sure Bruce is the baddest" BadDude.create :name => "Bruce", :bad => 1 BadDude.create :name => "Bruce", :bad => 2 BadDude.create :name => "Bruce", :bad => 5 end def self.down BadDude.delete_by_name "Bruce" end end class WeNeedMoreDudes < V 2.7 def self.up puts "Maybe a non Bruce would help our worst case scenario planning" BadDude.create :name => "Bob", :bad => 3 BadDude.create :name => "Samantha", :bad => 3 end def self.down BadDude.delete_by_name "Bob" BadDude.delete_by_name "Samantha" end end class NoIMeanWeNeedBadderDudes < V 3.14159 def self.up puts "just in case things get ugly" sam = BadDude.find_by_name "Samantha" sam.bad = 9001 sam.save end def self.down sam = BadDude.find_by_name "Samantha" sam.bad = 3 sam.save end end class WaitWeShouldDoThisEarlier < V 3.11 def self.up puts "for workgroups" bruce = BadDude.find_by_name "Bob" bruce.bad = 45 bruce.save end def self.down bruce = BadDude.find_by_name "Bob" bruce.bad = 3 bruce.save end end end module Controllers class Bad < R '/(\d+)?' def get enough @dudes = BadDude.all :conditions => ["bad >= ?", enough.to_i] @howbad = enough render :savethepresident end end end module Views def savethepresident h1.ohnoes "The President Has Been Kidnapped By #{@howbad} Ninjas!" if @dudes.empty? div "None of the dudes are bad enough to rescue him, We are doomed!" else div "Please get the following dudes:" ul.dudes do @dudes.each do |dude| li.dude dude.name end end end end end end def Migrations.create Migrations::Models.create_schema end camping-2.1.532/test/apps/reloader/0000755000004100000410000000000012154156727017063 5ustar www-datawww-datacamping-2.1.532/test/apps/reloader/reload_me.rb0000644000004100000410000000001712154156727021335 0ustar www-datawww-data$counter += 1 camping-2.1.532/test/apps/reloader/config.ru0000644000004100000410000000012012154156727020671 0ustar www-datawww-data$LOAD_PATH << File.dirname(__FILE__) + '/../' require 'reloader' run Reloader camping-2.1.532/test/apps/sessions.rb0000644000004100000410000000135612154156727017466 0ustar www-datawww-data#!/usr/bin/env ruby require "rubygems" require "camping" Camping.goes :Sessions require 'camping/session' module Sessions include Camping::Session module Controllers class One < R('/') def get @state = C::H['one',rand(100)] puts "1:" + @state.inspect redirect R(Two) end end class Two < R('/steptwo') def get @state['two'] = "This is in two" puts "2:" + @state.inspect redirect R(Three) end end class Three < R('/stepthree') def get @state['three'] = "This is in three" puts "3:" + @state.inspect return "Accumulated state across redirects: #{@state.inspect}" redirect R(Three) end end end end camping-2.1.532/test/apps/reloader_indirect.rb0000644000004100000410000000007112154156727021267 0ustar www-datawww-data$LOAD_PATH << File.dirname(__FILE__) require 'reloader' camping-2.1.532/test/apps/misc.rb0000644000004100000410000000351312154156727016550 0ustar www-datawww-datarequire "camping" Camping.goes :Misc module Misc module Controllers class Index < R '/' def get; render :index end end class RenderPartial def get; render :_partial; end end class Xsendfile def get @headers["X-Sendfile"] = File.expand_path(__FILE__) "You shouldn't get this text" end end class Links < R '/links', '/links/(\w+)/with/(\d+)/args' def get(*args); render :links; end end class Redirect def get; redirect(RR) end end class RR def get; render :rr; end end class BadLinks def get; render :bad_links; end end class BadMethod; end end module Views def layout html do head{ title C } body do ul do li{ a "index", :href=>R(Index)} li{ a "render partial", :href=>R(RenderPartial)} li{ a "X-Sendfile", :href=>R(Xsendfile)} li{ a "Links", :href=>R(Links)} li{ a "BadLinks", :href=>R(BadLinks)} li{ a "Redirect", :href=>R(Redirect)} li{ a "BadMethod", :href=>R(BadMethod)} end p { yield } end end end def _partial a "go back to index", :href=>R(Index) end def index h1 "Welcome on the Camping test app" end def links a "plain", :href=>R(Links); br a "with args and hash", :href=>R(Links, "moo", 3, :with=>"Hash"); br a "with args and mult. hash", :href=>R(Links, "hoi", 8, :with=>"multiple", 3=>"hash"); br # TODO : with R(nil) a "bad arity", :href=>R(RR, :moo) a "bad args", :href=>R(Links, 3, "moo") end def rr p "got redirected" end end end # For CGI if $0 == __FILE__ Misc.create Misc.run end camping-2.1.532/test/apps/env_debug.rb0000644000004100000410000000232612154156727017554 0ustar www-datawww-data#!/usr/bin/env ruby begin require "rubygems" rescue LoadError end require "camping" Camping.goes :EnvDebug module EnvDebug module Controllers class ShowEnv < R '/', '/(.*)' def get(extra = nil) @extra = extra render :show_env end alias post get end end module Views def layout html do head{ title C } body do ul do li{ a "show env", :href=>R(ShowEnv)} end p { yield } end end end def _print_hash(hash) hash.keys.sort.each do |key| value = hash[key] pre "%30s: %s" % [key.inspect, value.inspect] end end def show_env b "extra: #{@extra.inspect}" h2 "@status : #{@status.inspect}" h2 "@method : #{@method.inspect}" h2 "@root : #{@root.inspect}" h2 "@env :" _print_hash @env h2 "@input : " _print_hash @input h2 "@headers :" _print_hash @headers end end end # For CGI if $0 == __FILE__ EnvDebug.create if EnvDebug.respond_to? :create if ARGV.any? require 'camping/fastcgi' #Dir.chdir('/var/camping/blog/') Camping::FastCGI.start(EnvDebug) else puts EnvDebug.run end end camping-2.1.532/test/apps/reloader.rb0000644000004100000410000000015612154156727017412 0ustar www-datawww-datarequire 'camping' Camping.goes :Reloader $LOAD_PATH << File.dirname(__FILE__) require 'reloader/reload_me' camping-2.1.532/test/apps/forward_to_other_controller.rb0000644000004100000410000000214412154156727023426 0ustar www-datawww-datarequire 'camping' Camping.goes :ForwardToOtherController module ForwardToOtherController module Controllers class Index < R '/' attr_accessor :msg def get puts "msg=#{@msg}" puts "input=#{input.inspect}" render :index end end class Start < R '/start' def get render :start end end class Welcome < R '/welcome' def post if input.name == '_why' msg = "Wow you're back _why! This is front-page news!" r *ForwardToOtherController.get(:Index, :msg => msg, :input => input ) end @result = "Welcome #{input.name}!" render :welcome end end end module Views def index h1 @msg if @msg && !@msg.empty? a "Start", :href=> "/start" end def start h3 "Start" form :action=>R(Welcome), :method=>:post do label "Who are you?", :for=>:name div "Note: type _why if you want to test the forward logic otherwise just type your name", :style=>"color:green;font-size:8pt;" input :type=>:text, :name=>:name; br input :type=>:submit end end def welcome div "#{@result}" end end end camping-2.1.532/test/apps/forms.rb0000644000004100000410000000430112154156727016737 0ustar www-datawww-datarequire "camping" Camping.goes :Forms module Forms module Controllers class Index < R '/' def get; render :index end end class GetForm def get; render :get_form; end end class GetFormResult def get; render :form_result; end end class PostForm def get; render :post_form; end def post; render :form_result; end end class FileForm def get; render :file_form; end def post; render :form_result; end end end module Views def layout html do head{ title C } body do ul do li{ a "index", :href=>R(Index)} li{ a "get form", :href=>R(GetForm)} li{ a "post form", :href=>R(PostForm)} li{ a "file form", :href=>R(FileForm)} end p { yield } end end end def form_result p @input.inspect end def index h1 "Welcome on the Camping test app" end def get_form form :action=>R(GetFormResult), :method=>:get do label "Give me your name!", :for=>:name input :type=>:text, :name=>:name; br input :type=>:text, :name=>"arr[]"; br input :type=>:text, :name=>"arr[]"; br input :type=>:text, :name=>"hash[x]"; br input :type=>:text, :name=>"hash[y]"; br input :type=>:submit end end def post_form form :action=>R(PostForm), :method=>:post do label "Give me your name!", :for=>:name input :type=>:text, :name=>:name; br input :type=>:text, :name=>"arr[]"; br input :type=>:text, :name=>"arr[]"; br input :type=>:text, :name=>"hash[x]"; br input :type=>:text, :name=>"hash[y]"; br input :type=>:submit end end def file_form form :action=>R(FileForm), :method=>:post, :enctype=>"multipart/form-data" do input :type=>:text, :name=>"arr" input :type=>:text, :name=>"arr"; br input :type=>:file, :name=>"first_file"; br input :type=>:file, :name=>"files[]"; br input :type=>:file, :name=>"files[]"; br input :type=>:submit end end end end # For CGI if $0 == __FILE__ Forms.create Forms.run end camping-2.1.532/test/app_partials.rb0000644000004100000410000000330212154156727017325 0ustar www-datawww-datarequire 'test_helper' require 'camping' Camping.goes :Partials Camping.goes :TiltPartials module Partials::Controllers class Index def get render :index end end class Partial def get render :_partial end end class Nolayout def get render :index, :layout => false end end class Forcelayout def get render :_partial, :layout => true end end class Nested def get render :nested end end end # Copy over all controllers module TiltPartials::Controllers Partials::Controllers.constants.each do |const| const_set(const, Partials::Controllers.const_get(const).dup) end end module Partials::Views def layout body do yield end end def index h1 "Index" _partial end def _partial p "Partial" end def nested h1 "Nested" regular end def regular p "Regular" end end class Partials::Test < TestCase def test_underscore_partial get '/' assert_body "

Index

Partial

" end def test_underscore_partial_only get '/partial' assert_body "

Partial

" end def test_nolayout get '/nolayout' assert_body "

Index

Partial

" end def test_forcelayout get '/forcelayout' assert_body "

Partial

" end def test_netsted get '/nested' assert_body "

Nested

Regular

" end end class TiltPartials::Test < Partials::Test end __END__ @@ layout.str #{yield.strip} @@ index.str

Index

#{render(:_partial).strip} @@ _partial.str

Partial

@@ nested.str

Nested

#{render(:regular).strip} @@ regular.str

Regular

camping-2.1.532/test/app_markup.rb0000644000004100000410000000355612154156727017020 0ustar www-datawww-datarequire 'test_helper' require 'camping' Camping.goes :Markup module Markup::Controllers class Index def get render :index end end class NoLayout def get render :index, :layout => false end end class AutoPrepend def get mab do img :src => '/hello.png' end end end class Compat < R '/compat/(.*?)' def get(type) mab do send(type) do body { h1 'Nice' } end end end end class CompatHelpers def get mab do helpers.R CompatHelpers end end end end module Markup::Views def index h1 "Welcome!" end def layout self << '' html do head do title "Web Page" end body { yield } end end end class Markup::Test < TestCase def test_render get '/' assert_body %r{\A} assert_body %r{

Welcome!

} assert_body %r{Web Page} end def test_no_layout get '/no/layout' assert_body %r{

Welcome!

} assert_reverse do assert_body %r{Web Page} end end def test_auto_prepend get '/auto/prepend', {}, 'SCRIPT_NAME' => '/mount' assert_body '' end def test_compat warning = "xhtml_strict is no longer supported (or an active standard); using HTML5 instead\n" assert_output '', warning * 3 do get '/compat/xhtml_strict' assert_body '

Nice

' get '/compat/xhtml_transitional' assert_body '

Nice

' get '/compat/xhtml_frameset' assert_body '

Nice

' end end def test_compat_helpers get '/compat/helpers' assert_body '/compat/helpers' end end camping-2.1.532/test/app_reloader.rb0000644000004100000410000000244712154156727017314 0ustar www-datawww-datarequire 'test_helper' require 'fileutils' require 'camping/reloader' $counter = 0 module TestCaseReloader def reloader @reloader ||= Camping::Reloader.new(file) end def setup super reloader.reload! assert Object.const_defined?(:Reloader), "Reloader didn't load app" end def teardown super assert Object.const_defined?(:Reloader), "Test removed app" reloader.remove_apps assert !Object.const_defined?(:Reloader), "Reloader didn't remove app" end end class TestReloader < TestCase include TestCaseReloader BASE = File.expand_path('../apps/reloader', __FILE__) def file; BASE + '.rb' end def setup $counter = 0 super end def test_counter assert_equal 1, $counter end def test_forced_reload reloader.reload! assert_equal 2, $counter end def test_mtime_reload reloader.reload assert_equal 1, $counter FileUtils.touch(BASE + '.rb') sleep 1 reloader.reload assert_equal 2, $counter FileUtils.touch(BASE + '/reload_me.rb') sleep 1 reloader.reload assert_equal 3, $counter end end class TestConfigRu < TestReloader BASE = File.expand_path('../apps/reloader', __FILE__) def file; BASE + '/config.ru' end def test_name assert_equal Reloader, reloader.apps[:reloader] end end camping-2.1.532/test/app_file.rb0000644000004100000410000000137012154156727016430 0ustar www-datawww-datarequire 'test_helper' require 'camping' Camping.goes :FileSource module FileSource::Controllers class Index def get FileSource.options[:__FILE__] end end end class FileSource::Test < TestCase def test_source get '/' assert_body __FILE__ end def test_file get '/style.css' assert_body "* { margin: 0; padding: 0 }" assert_equal "text/css", last_response.headers['Content-Type'] get '/test.foo' assert_body "Hello" assert_equal "text/html", last_response.headers['Content-Type'] get '/test' assert_body "No extension" assert_equal "text/html", last_response.headers['Content-Type'] end end __END__ @@ /style.css * { margin: 0; padding: 0 } @@ /test.foo Hello @@ /test No extension camping-2.1.532/test/app_sessions.rb0000644000004100000410000000116712154156727017363 0ustar www-datawww-datarequire 'test_helper' require 'camping' require 'camping/session' Camping.goes :Sessions module Sessions include Camping::Session end module Sessions::Controllers class One def get @state.clear @state.one = 42 redirect R(Two) end end class Two def get @state.two = 56 redirect R(Three) end end class Three def get @state.three = 99 @state.values_at("one", "two", "three").inspect end end end class Sessions::Test < TestCase def test_session get '/one' follow_redirect! follow_redirect! assert_body "[42, 56, 99]" end end camping-2.1.532/test/test_helper.rb0000644000004100000410000000165212154156727017172 0ustar www-datawww-data$:.unshift File.dirname(__FILE__) + '/../lib' begin require 'rubygems' rescue LoadError end if ENV['ABRIDGED'] require 'camping' else require 'camping-unabridged' end require 'minitest/autorun' require 'rack/test' class TestCase < MiniTest::Unit::TestCase include Rack::Test::Methods def self.inherited(mod) mod.app = Object.const_get(mod.to_s[/\w+/]) super end class << self attr_accessor :app end def body() last_response.body end def app() self.class.app end def assert_reverse begin yield rescue Exception else assert false, "Block didn't fail" end end def assert_body(str) case str when Regexp assert_match(str, last_response.body.strip) else assert_equal(str.to_s, last_response.body.strip) end end def assert_status(code) assert_equal(code, last_response.status) end def test_silly; end end camping-2.1.532/test/app_route_generating.rb0000644000004100000410000000044512154156727021054 0ustar www-datawww-datarequire 'test_helper' require 'camping' Camping.goes :Routes module Routes::Controllers class Index def get R(Style) end end class Style < R '/style\.css' end end class Routes::Test < TestCase def test_backslash get '/' assert_body '/style.css' end end camping-2.1.532/test/app_cookies.rb0000644000004100000410000000215312154156727017145 0ustar www-datawww-datarequire 'test_helper' require 'camping' Camping.goes :Cookies module Cookies::Controllers class One def get @cookies.simple = '42' @cookies.set :complex, '43' @cookies.set :past, 'past', :expires => Time.now - 5 render :show end end class Two def get render :show end end class Old def get @cookies.simple = '42' @cookies.complex = { :value => '43' } @cookies.past = { :value => 'past', :expires => Time.now - 5 } @cookies.past.class.name end end end module Cookies::Views def show @cookies.values_at('simple', 'complex', 'past').inspect end end class Cookies::Test < TestCase def test_cookies get '/one' assert_body '["42", "43", "past"]' get '/two' assert_body '["42", "43", nil]' end def test_backward_compatible get '/old' assert_body 'Hash' get '/two' assert_body '["42", "43", nil]' end def test_path get '/one', {}, 'SCRIPT_NAME' => '/mnt' assert_body '["42", "43", "past"]' assert_equal 3, last_response.headers["Set-Cookie"].scan('path=/mnt/').size end end camping-2.1.532/test/app_inline_templates.rb0000644000004100000410000000077212154156727021052 0ustar www-datawww-datarequire 'test_helper' require 'camping' Camping.goes :Inline module Inline::Controllers class Index def get @world = "World" render :index end end class UserX def get(name) @name = name render :user end end end class Inline::Test < TestCase def test_inline get '/' assert_body "Hello World" get '/user/Bluebie' assert_body "My name is Bluebie" end end __END__ @@ index.erb Hello <%= @world %> @@ user.erb My name is <%= @name %> camping-2.1.532/test/app_simple.rb0000644000004100000410000000332612154156727017005 0ustar www-datawww-datarequire 'test_helper' require 'camping' Camping.goes :Simple module Simple::Controllers class Index def get "Hello World!" end def post "Hello Post!" end def custom "Hello Custom!" end end class PostN def get(id) "Post ##{id}" end end class MultipleComplexX def get(str) "Complex: #{str}" end end class DateNNN def get(year, month, day) [year, month, day] * "-" end end class Regexp < R '/ohmy/([a-f]+)' def get(value) value end end class Optional < R '/optional', '/optional/([^/]+)' def get(value = "default") "Optional: #{value}" end end class Weird def get redirect MultipleComplexX, 'hello%#/world' end end end class Simple::Test < TestCase def test_index get '/' assert_body "Hello World!" assert_equal "text/html", last_response.headers['Content-Type'] post '/' assert_body "Hello Post!" end def test_post get '/post/1' assert_body "Post #1" get '/post/2' assert_body "Post #2" get '/post/2-oh-no' assert_status 404 end def test_complex get '/multiple/complex/Hello' assert_body "Complex: Hello" end def test_date get '/date/2010/04/01' assert_body "2010-04-01" end def test_regexp get '/ohmy/cafebabe' assert_body "cafebabe" get '/ohmy/CAFEBABE' assert_status 404 end def test_optional get '/optional' assert_body "Optional: default" get '/optional/override' assert_body "Optional: override" end def test_weird get '/weird' follow_redirect! assert_body 'Complex: hello%#/world' end end camping-2.1.532/test/app_helpers.rb0000644000004100000410000000132312154156727017151 0ustar www-datawww-datarequire 'test_helper' require 'camping' Camping.goes :Helpers module Helpers::Helpers def frontpage R(Index) end def current_user User.new end end module Helpers::Models class User def name 'Bob' end end end module Helpers::Controllers class Index def get URL('/').to_s end end class Model def get current_user.name end end class Users def get frontpage end end end class Helpers::Test < TestCase def test_models get '/model' assert_body "Bob" end def test_controllers get '/users' assert_body "/" end def test_url get '/', {}, 'PATH_INFO' => '' assert_body "http://example.org/" end end camping-2.1.532/examples/0000755000004100000410000000000012154156727015162 5ustar www-datawww-datacamping-2.1.532/examples/blog.rb0000755000004100000410000001670112154156727016442 0ustar www-datawww-data#!/usr/bin/env ruby $:.unshift File.dirname(__FILE__) + '/../lib' require 'camping' require 'camping/ar' require 'camping/session' require 'redcloth' Camping.goes :Blog module Blog include Camping::Session module Models class Post < Base belongs_to :user before_save do |record| cloth = RedCloth.new(record.body) cloth.hard_breaks = false record.html_body = cloth.to_html end end class Comment < Base; belongs_to :user; end class User < Base; end class BasicFields < V 1.1 def self.up create_table :blog_posts, :force => true do |t| t.integer :user_id, :null => false t.string :title, :limit => 255 t.text :body, :html_body t.timestamps end create_table :blog_users, :force => true do |t| t.string :username, :password end create_table :blog_comments, :force => true do |t| t.integer :post_id, :null => false t.string :username t.text :body, :html_body t.timestamps end User.create :username => 'admin', :password => 'camping' end def self.down drop_table :blog_posts drop_table :blog_users drop_table :blog_comments end end end module Controllers class Index def get @posts = Post.all(:order => 'updated_at DESC') render :index end end class PostNew def get require_login! @post = Post.new render :add end def post require_login! post = Post.create(:title => input.post_title, :body => input.post_body, :user_id => @state.user_id) redirect PostN, post end end class PostN def get(post_id) @post = Post.find(post_id) render :view end end class Edit < R '/post/(\d+)/edit' def get(post_id) require_login! @post = Post.find(post_id) render :edit end def post(post_id) require_login! @post = Post.find(post_id) @post.update_attributes :title => input.post_title, :body => input.post_body redirect PostN, @post end end class Login def get render :login end def post @user = User.find_by_username_and_password(input.username, input.password) if @user @state.user_id = @user.id redirect R(Index) else @info = 'Wrong username or password.' end render :login end end class Logout def get @state.user_id = nil redirect Index end end class Style < R '/styles\.css' STYLE = File.read(__FILE__).gsub(/.*__END__/m, '') def get @headers['Content-Type'] = 'text/css; charset=utf-8' STYLE end end end module Helpers def logged_in? !!@state.user_id end def require_login! unless logged_in? redirect Controllers::Login throw :halt end end end module Views def layout html do head do title 'My Blog' link :rel => 'stylesheet', :type => 'text/css', :href => '/styles.css', :media => 'screen' end body do h1 { a 'My Blog', :href => R(Index) } div.wrapper! do text yield end hr p.footer! do if logged_in? _admin_menu else a 'Login', :href => R(Login) text ' to the adminpanel' end text ' – Powered by ' a 'Camping', :href => 'http://camping.rubyforge.org/' end end end end def index if @posts.empty? h2 'No posts' p do text 'Could not find any posts. Feel free to ' a 'add one', :href => R(PostNew) text ' yourself. ' end else @posts.each do |post| _post(post) end end end def login h2 'Login' p.info @info if @info form :action => R(Login), :method => 'post' do input :name => 'to', :type => 'hidden', :value => @to if @to label 'Username', :for => 'username' input :name => 'username', :id => 'username', :type => 'text' label 'Password', :for => 'password' input :name => 'password', :id => 'password', :type => 'password' input :type => 'submit', :class => 'submit', :value => 'Login' end end def add _form(@post, :action => R(PostNew)) end def edit _form(@post, :action => R(Edit, @post)) end def view _post(@post) end # partials def _admin_menu text [['Log out', R(Logout)], ['New', R(PostNew)]].map { |name, to| capture { a name, :href => to} }.join(' – ') end def _post(post) h2 { a post.title, :href => R(PostN, post) } p.info do text "Written by #{post.user.username} " text post.updated_at.strftime('%B %M, %Y @ %H:%M ') _post_menu(post) end text post.html_body end def _post_menu(post) if logged_in? a '(edit)', :href => R(Edit, post) end end def _form(post, opts) form({:method => 'post'}.merge(opts)) do label 'Title', :for => 'post_title' input :name => 'post_title', :id => 'post_title', :type => 'text', :value => post.title label 'Body', :for => 'post_body' textarea post.body, :name => 'post_body', :id => 'post_body' input :type => 'hidden', :name => 'post_id', :value => post.id input :type => 'submit', :class => 'submit', :value => 'Submit' end end end end def Blog.create Blog::Models.create_schema :assume => (Blog::Models::Post.table_exists? ? 1.0 : 0.0) end __END__ * { margin: 0; padding: 0; } body { font: normal 14px Arial, 'Bitstream Vera Sans', Helvetica, sans-serif; line-height: 1.5; } h1, h2, h3, h4 { font-family: Georgia, serif; font-weight: normal; } h1 { background-color: #EEE; border-bottom: 5px solid #6F812D; outline: 5px solid #9CB441; font-weight: normal; font-size: 3em; padding: 0.5em 0; text-align: center; } h2 { margin-top: 1em; font-size: 2em; } h1 a { color: #143D55; text-decoration: none } h1 a:hover { color: #143D55; text-decoration: underline } h2 a { color: #287AA9; text-decoration: none } h2 a:hover { color: #287AA9; text-decoration: underline } #wrapper { margin: 3em auto; width: 700px; } p { margin-bottom: 1em; } p.info, p#footer { color: #999; margin-left: 1em; } p.info a, p#footer a { color: #999; } p.info a:hover, p#footer a:hover { text-decoration: none; } a { color: #6F812D; } a:hover { color: #9CB441; } hr { border-width: 5px 0; border-style: solid; border-color: #9CB441; border-bottom-color: #6F812D; height: 0; } p#footer { font-size: 0.9em; margin: 0; padding: 1em; text-align: center; } label { display: block; width: 100%; } input, textarea { padding: 5px; margin-bottom: 1em; margin-right: 490px; width: 200px; } input.submit { width: auto; } textarea { font: normal 14px Arial, 'Bitstream Vera Sans', Helvetica, sans-serif; height: 300px; width: 400px; } camping-2.1.532/README.md0000644000004100000410000000641612154156727014632 0ustar www-datawww-data[![Build Status](https://secure.travis-ci.org/camping/camping.png)](http://travis-ci.org/camping/camping) #Camping, a Microframework Camping is a web framework which consistently stays at less than 4kB of code. You can probably view the complete source code on a single page. But, you know, it's so small that, if you think about it, what can it really do? The idea here is to store a complete fledgling web application in a single file like many small CGIs. But to organize it as a Model-View-Controller application like Rails does. You can then easily move it to Rails once you've got it going. ##A Camping Skeleton A skeletal Camping blog could look like this: require 'camping' Camping.goes :Blog module Blog::Models class Post < Base; belongs_to :user; end class Comment < Base; belongs_to :user; end class User < Base; end end module Blog::Controllers class Index def get @posts = Post.find :all render :index end end end module Blog::Views def layout html do head { title "My Blog" } body do h1 "My Blog" self << yield end end end def index @posts.each do |post| h1 post.title end end end ##Installation Interested yet? Luckily it's quite easy to install Camping. We'll be using a tool called RubyGems, so if you don't have that installed yet, go grab it! Once that's sorted out, open up a Terminal or Command Line and enter: gem install camping Even better, install the Camping Omnibus, a full package of recommended libs: gem install camping-omnibus --source http://gems.judofyr.net If not, you should be aware of that Camping itself only depends on [Rack](http://rack.rubyforge.org), and if you're going to use the views you also need to install **[markaby](http://markaby.github.com/)**, and if you're going to use the database you need **activerecord** as well. gem install markaby gem install activerecord ##Learning First of all, you should read [the first chapters](camping/blob/master/book/01_introduction.md) of The Camping Book. It should hopefully get you started pretty quick. While you're doing that, you should be aware of the _reference_ which contains documentation for all the different parts of Camping. [The wiki](http://wiki.github.com/camping/camping) is the place for all tiny, useful tricks that we've collected over the years. Don't be afraid to share your own discoveries; the more, the better! And if there's anything you're wondering about, don't be shy, but rather subscribe to [the mailing list](http://rubyforge.org/mailman/listinfo/camping-list) and ask there. We also have an IRC channel over at Freenode, so if you feel like chatting with us, you should join [#camping @ irc.freenode.net](http://java.freenode.net/?channel=camping). ##Authors Camping was originally crafted by [why the lucky stiff](http://en.wikipedia.org/wiki/Why_the_lucky_stiff), but is now maintained by the _community_. This simply means that if we like your patch, it will be applied. Everything is managed through [the mailing list](http://rubyforge.org/mailman/listinfo/camping-list), so just subscribe and you can instantly take a part in shaping Camping.camping-2.1.532/Rakefile0000644000004100000410000000667512154156727015027 0ustar www-datawww-data$:.unshift 'extras' begin require 'rake/dsl_definition' require 'rake/alt_system' rescue LoadError else begin if defined?(Rake::DeprecatedObjectDSL) Rake::DeprecatedObjectDSL.class_eval do private_instance_methods(false).each do |meth| remove_method meth end end end rescue Exception end end require 'rake' require 'rake/clean' require 'rake/testtask' require 'tempfile' require 'open3' require File.expand_path('../constants', __FILE__) CLEAN.include ['**/.*.sw?', '*.gem', '.config', 'test/test.log', '.*.pt'] task :default => :check ## RDoc begin gem 'rdoc', '~>3.9.0' rescue LoadError task :docs do puts "** Camping needs RDoc 3.9 in order to use the Flipbook template." end else require 'rdoc/task' RDoc::Task.new(:docs) do |rdoc| # We have a recent version of RDoc, so let's use flipbook. require 'rdoc/generator/singledarkfish' rdoc.options += ['-f', 'singledarkfish', *RDOC_OPTS] rdoc.template = "flipbook" rdoc.rdoc_dir = 'doc' rdoc.title = "Camping, a Microframework" rdoc.rdoc_files.add ['README', 'lib/camping-unabridged.rb', 'lib/camping/**/*.rb', 'book/*'] end end task :rubygems_docs do require 'rubygems/doc_manager' def spec.installation_path; '.' end def spec.full_gem_path; '.' end manager = Gem::DocManager.new(spec) manager.generate_rdoc end desc "Packages Camping." task :package => :clean ## Tests Rake::TestTask.new(:test) do |t| t.libs << "test" t.test_files = FileList['test/app_*.rb'] end ## Diff desc "Compare camping and camping-unabridged" task :diff do require 'ruby2ruby' require 'ruby_parser' u = Tempfile.new('unabridged') m = Tempfile.new('mural') u << Ruby2Ruby.new.process(RubyParser.new.parse(File.read("lib/camping.rb"))) mtext = Ruby2Ruby.new.process(RubyParser.new.parse(File.read("lib/camping-unabridged.rb"))) m << mtext.gsub(/^\s*#.*\n/, '') u.flush m.flush sh "diff -u #{u.path} #{m.path} | less" u.delete m.delete end error = false ## Check task :check => ["test", "check:valid", "check:equal", "check:size", "check:lines", "check:exit"] namespace :check do desc "Check source code validity" task :valid do sh "ruby -c lib/camping.rb" end desc "Check equality between mural and unabridged" task :equal do require 'ruby_parser' u = RubyParser.new.parse(File.read("lib/camping-unabridged.rb")) m = RubyParser.new.parse(File.read("lib/camping.rb")) u.reject! do |sexp| sexp.is_a?(Sexp) and sexp[1] == s(:gvar, :$LOADED_FEATURES) end unless u == m STDERR.puts "camping.rb and camping-unabridged.rb are not synchronized." error = true end end SIZE_LIMIT = 4096 desc "Compare camping sizes to unabridged" task :size do FileList["lib/camping*.rb"].each do |path| s = File.size(path) puts "%21s : % 6d % 4d%" % [File.basename(path), s, (100 * s / SIZE_LIMIT)] end if File.size("lib/camping.rb") > SIZE_LIMIT STDERR.puts "lib/camping.rb: file is too big (> #{SIZE_LIMIT})" error = true end end desc "Verify that line lenght doesn't exceed 80 chars for camping.rb" task :lines do i = 1 File.open("lib/camping.rb").each_line do |line| if line.size > 81 # 1 added for \n error = true STDERR.puts "lib/camping.rb:#{i}: line too long (#{line[-10..-1].inspect})" end i += 1 end end task :exit do exit 1 if error end end camping-2.1.532/book/0000755000004100000410000000000012154156727014276 5ustar www-datawww-datacamping-2.1.532/book/51_upgrading.md0000644000004100000410000000624312154156727017112 0ustar www-datawww-data# Appendix I: Upgrade Notes This document includes everything needed in order to *upgrade* your applications. If you're looking for all the new features in a version, please have a look at the CHANGELOG in the Camping source. ##From 2.0 to 2.1 ###Options In Camping 2.1 there is now a built-in way to store options and settings. If you use cookie session, it means that you'll now have to change to: module Nuts set :secret, "Very secret text, which no-one else should know!" include Camping::Session end ##From 1.5 to 2.0 ###Rack The biggest change in 2.0 is that it now uses [Rack](http://rack.rubyforge.org/) internally. This means that you'll now have to deploy Camping differently, but hopefully more easily too. Now every Camping application is also a Rack application, so simply check out the documentation to the server of your choice. ###`require 'camping/db'` In earlier versions of Camping, you loaded database support by: require 'camping/db' Actually, this loaded a very thin layer on top of ActiveRecord, and in the future we want to experiment with other libraries. Therefore you should now simply remove the line, and instead just inherit from Base right away. This also means you'll have to place your migrations *after* the models. We also encourage you to use Model.table_name instead of :appname_model, just to make sure it's named correctly. ## Don't require anything: # require 'camping/db' module Nuts::Models ## Just inherit Base: class Page < Base; end ## Migrations have to come *after* the models: class CreateTheBasics < V 0.1 def self.up create_table Page.table_name do |t| ... end end def self.down drop_table Page.table_name end end end ###Cookie Sessions Camping 2.0 now uses a cookie-based session system, which means you now longer need a database in order to use sessions. The disadvantage of this is that you are restricted to only around 4k of data. See below for the changes required, and see Camping::Session more details. module Nuts ## Include Camping::Session as before: include Camping::Session ## But also define a secret: secret "Very secret text, which no-one else should know!" end def Nuts.create ## And remove the following line: # Camping::Models::Session.create_schema end ###Error handling Camping now uses three methods in order to handle errors. These replaces the old classes NotFound and ServerError. * Camping::Base#r404 is called when a route can't be found. * Camping::Base#r501 is called when a route is found, but doesn't respond to the method. * Camping::Base#r500 is called when an error happens. You can override these in your application: module Nuts def r404(path) "Sorry, but I can't find #{path}." end def r501(method) "Sorry, but I can't respond to #{method}." end def r500(klass, method, ex) "Sorry, but #{klass}##{method} failed with #{ex}." end end It should be noted that this might change in the future. camping-2.1.532/book/02_getting_started.md0000644000004100000410000003020612154156727020311 0ustar www-datawww-data#Getting Started Start a new text file called nuts.rb. Here's what you put inside: Camping.goes :Nuts Save it. Then, open a command prompt in the same directory. You'll want to run: $ camping nuts.rb And you should get a message which reads: ** Camping running on 0.0.0.0:3301. This means that right now The Camping Server is running on port 3301 on your machine. Open your browser and visit http://localhost:3301/. Your browser window should show: Camping Problem! / Not found No problem with that. The Camping Server is running, but it doesn't know what to show. Let's tell him. ##Hello clock So, you've got Camping installed and it's running. Keep it running. You can edit files and The Camping Server will reload automatically. When you need to stop the server, press Control-C. Let's show something. At the bottom of nuts.rb add: module Nuts::Controllers class Index < R '/' def get Time.now.to_s end end end Save the file and refresh the browser window. Your browser window should show the time, e.g. Sun Jul 15 12:56:15 +0200 2007 ##Enjoying the view The Camping microframework allows us to separate our code using the MVC (Model-View-Controller) design pattern. Let's add a view to our Nuts application. Replace the module Nuts::Controllers with: module Nuts::Controllers class Index < R '/' def get @time = Time.now render :sundial end end end module Nuts::Views def layout html do head do title { "Nuts And GORP" } end body { self << yield } end end def sundial p "The current time is: #{@time}" end end Save the file and refresh your browser window and it should show a message like: The current time is: Sun Jul 15 13:05:41 +0200 2007 And the window title reads "Nuts And GORP". Here you can see we call render :sundial from our controller. This does exactly what it says, and renders our sundial method. We've also added a special method called layout which Camping will automatically wrap our sundial output in. If you're familiar with HTML, you'll see that our view contains what looks HTML tag names. This is Markaby, which is like writing HTML using Ruby! Soon enough, you'll find that you can return anything from the controller, and it will be sent to the browser. But let's keep that for later and start investigating the routes. ##Routes You probably noticed the weird R '/' syntax in the previous page. This is an uncommon feature of Ruby that is used in our favorite microframework, to describe the routes which the controller can be accessed on. These routes can be very powerful, but we're going to have look at the simplest ones first. module Nuts::Controllers class Words < R '/welcome/to/my/site' def get "You got here by: /welcome/to/my/site" end end class Digits < R '/nuts/(\d+)' def get(number) "You got here by: /nuts/#{number}" end end class Segment < R '/gorp/([^/]+)' def get(everything_else_than_a_slash) "You got here by: /gorp/#{everything_else_than_a_slash}" end end class DigitsAndEverything < R '/nuts/(\d+)/([^/]+)' def get(number, everything) "You got here by: /nuts/#{number}/#{everything}" end end end Add this to `nuts.rb` and try if you can hit all of the controllers. Also notice how everything inside a parenthesis gets passed into the method, and is ready at your disposal. ###Simpler routes This just in: module Nuts::Controllers class Index def get "You got here by: /" end end class WelcomeToMySite def get "You got here by: /welcome/to/my/site" end end class NutsN def get(number) "You got here by: /nuts/#{number}" end end class GorpX def get(everything_else_than_a_slash) "You got here by: /gorp/#{everything_else_than_a_slash}" end end class NutsNX def get(number, everything) "You got here by: /nuts/#{number}/#{everything}" end end end Drop the < R-part and it attemps to read your mind. It won't always succeed, but it can simplify your application once in a while. ## Modeling the world You can get pretty far with what you've learned now, and hopefully you've been playing a bit off-book, but it's time to take the next step: Storing data. Let's start over again. Camping.goes :Nuts module Nuts::Models class Page < Base end end Obviously, this won't do anything, since we don't have any controllers, but let's rather have a look at we _do_ have. We have a model named Page. This means we now can store wiki pages and retrieve them later. In fact, we can have as many models as we want. Need one for your users and one for your blog posts? Well, I think you already know how to do it. However, our model is missing something essential: a skeleton. Camping.goes :Nuts module Nuts::Models class Page < Base end class BasicFields < V 1.0 def self.up create_table Page.table_name do |t| t.string :title t.text :content # This gives us created_at and updated_at t.timestamps end end def self.down drop_table Page.table_name end end end Now we have our first version of our model. It says: If you want to migrate up to version one, create the skeleton for the Page model, which should be able to store, "title" which is a string, "content" which is a larger text, "created_at" which is the time it was created, "updated_at" which is the previous time it was updated. If you want to migrate down from version one, remove the skeleton for the Page model. This is called a _migration_. Whenever you want to change or add new models you simply add a new migration below, where you increase the version number. All of these migrations builds upon each other like LEGO blocks. Now we just need to tell Camping to use our migration. Write this at the bottom of nuts.rb def Nuts.create Nuts::Models.create_schema end When The Camping Server boots up, it will automatically call Nuts.create. You can put all kind of startup-code here, but right now we only want to create our skeleton (or upgrade if needed). Start The Camping Server again and observe: $ camping nuts.rb ** Starting Mongrel on 0.0.0.0:3301 -- create_table("nuts_schema_infos") -> 0.1035s == Nuts::Models::BasicFields: migrating =================================== -- create_table(:nuts_pages) -> 0.0033s == Nuts::Models::BasicFields: migrated (0.0038s) ========================== Restart it, and enjoy the silence. There's no point of re-creating the skeleton this time. Before we go on, there's one rule you must known: Always place your models before your migrations. ## Using our model Let's explore how our model works by going into the _console_ $ camping -C nuts.rb ** Starting console >> Now it's waiting for your input, and will give you the answer when you press Enter. Here's what I did, leaving out the boring answers. You should add your own pages. >> Page = Nuts::Models::Page >> hiking = Page.new(:title => "Hiking") >> hiking.content = "You can also set the values like this." >> hiking.save >> page = Page.find_by_title("Hiking") => # >> page = Page.find(1) => # >> page.title >> page.content >> page.created_at >> page.updated_at >> Page.find_by_title("Fishing") => nil ## Page.create automatically saves the page for you. >> Page.create(:title => "Fishing", :content => "Go fish!") >> Page.count => 2 Now I have two pages: One about hiking and one about fishing. ##Wrapping it up Wouldn't it be nice if we could show this wonderful our pages in a browser? Update nuts.rb so it also contains something like this: module Nuts::Controllers class Pages def get # Only fetch the titles of the pages. @pages = Page.all(:select => "title") render :list end end class PageX def get(title) @page = Page.find_by_title(title) render :view end end end module Nuts::Views def list h1 "All pages" ul do @pages.each do |page| li do a page.title, :href => R(PageX, page.title) end end end end def view h1 @page.title self << @page.content end end Here we meet our first _helper_: R(PageX, page.title) This is the reversed router and it generates a URL based on a controller. Camping ships with a few, but very useful, helpers and you can easily add your owns. Have a look at Camping::Helpers for how you use these. There's a lot of improvements you could do here. Let me suggest: * Show when the page was created and last updated. * What happens when the page doesn't exist? * What should the front page show? * Add a layout. * Jazz it up a bit. ##The last touch We have one major flaw in our little application. You can't edit or add new pages. Let's see if we can fix that: module Nuts::Controllers class PageX def get(title) if @page = Page.find_by_title(title) render :view else redirect PageXEdit, title end end def post(title) # If it doesn't exist, initialize it: @page = Page.find_or_initialize_by_title(title) # This is the same as: # @page = Page.find_by_title(title) || Page.new(:title => title) @page.content = @input.content @page.save redirect PageX, title end end class PageXEdit def get(title) @page = Page.find_or_initialize_by_title(title) render :edit end end end The core of this code lies in the new post method in the PageX controller. When someone types an address or follows a link, they'll end up at the get method, but you can easily create a form which rather sends you to the post when submitted. There are other names you can use, but they won't always work. So for now, don't be fancy and just stick to get and post. We'll show you how this really works later. You might also notice that we use @input.content. The @input-hash contains any extra parameters sent, like those in the forms and those in the URL (/posts?page=50). Here's an edit-view, but you can probably do better. See if you can integrate all of this with what you already have. module Nuts::Views def edit h1 @page.title form :action => R(PageX, @page.title), :method => :post do textarea @page.content, :name => :content, :rows => 10, :cols => 50 br input :type => :submit, :value => "Submit!" end end end ##Phew. You've taken quite a few steps in the last minutes. You deserve a break. But let's recap for a moment: * Always place Camping.goes :App at the top of your file. * Every route ends at a controller, but ... * ... the controller only delegates the work. * @input contains the extra parameters. * The views are HTML disguised as Ruby. * They can access the instances variables (those that starts with a single at-sign) from the controller. * The models allows you to store all kinds of data. * Place your models before your migrations. * Helpers are helpful. Unfortunately, the book stops here for now. Come back in a few months, or join the mailing list to stay updated, and hopefully there's another chapter waiting for you. camping-2.1.532/book/01_introduction.md0000644000004100000410000000163212154156727017643 0ustar www-datawww-data#Introduction Camping is a small web framework, less than 4k, a little white blood cell in the vein of Rails. This little book will start with a tutorial which takes about fifteen minutes - by the end you should have a little Camping site up. The following chapters will eventually go deeper into how both Camping, HTTP and Rack works. ("Eventually", because these chapters are not written yet. This book is currently a very much work in progress, and we'll be very grateful if you want to help out.) If you at any moment need some help or have any questions or comments, we highly recommend [the mailing list](http://rubyforge.org/mailman/listinfo/camping-list) which got plenty of nice people willing to help. We also have an IRC-channel at [#camping @ irc.freenode.net](http://java.freenode.net/?channel=camping) if you're into that sort of things. Enough talk. Ready? Let's ["get started"](02_getting_started.md). camping-2.1.532/bin/0000755000004100000410000000000012154156727014114 5ustar www-datawww-datacamping-2.1.532/bin/camping0000755000004100000410000000044412154156727015462 0ustar www-datawww-data#!/usr/bin/env ruby $:.unshift File.dirname(__FILE__) + "/../lib" require 'camping' require 'camping/server' begin Camping::Server.start rescue OptionParser::ParseError => ex STDERR.puts "!! #{ex.message}" puts "** use `#{File.basename($0)} --help` for more details..." exit 1 end camping-2.1.532/metadata.yml0000644000004100000410000001070612154156727015653 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: camping version: !ruby/object:Gem::Version version: 2.1.532 prerelease: platform: ruby authors: - why the lucky stiff autorequire: bindir: bin cert_chain: [] date: 2013-03-21 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: rack requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '1.0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '1.0' - !ruby/object:Gem::Dependency name: mab requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 0.0.3 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 0.0.3 - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rack-test requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' description: email: why@ruby-lang.org executables: - camping extensions: [] extra_rdoc_files: - README.md - CHANGELOG - COPYING - book/01_introduction.md - book/02_getting_started.md - book/51_upgrading.md files: - COPYING - README.md - Rakefile - bin/camping - test/app_cookies.rb - test/app_file.rb - test/app_helpers.rb - test/app_inline_templates.rb - test/app_markup.rb - test/app_partials.rb - test/app_reloader.rb - test/app_route_generating.rb - test/app_sessions.rb - test/app_simple.rb - test/apps/env_debug.rb - test/apps/forms.rb - test/apps/forward_to_other_controller.rb - test/apps/migrations.rb - test/apps/misc.rb - test/apps/reloader/config.ru - test/apps/reloader/reload_me.rb - test/apps/reloader.rb - test/apps/reloader_indirect.rb - test/apps/sessions.rb - test/test_helper.rb - lib/camping/ar.rb - lib/camping/mab.rb - lib/camping/reloader.rb - lib/camping/server.rb - lib/camping/session.rb - lib/camping/template.rb - lib/camping-unabridged.rb - lib/camping.rb - extras/images/badge.gif - extras/images/boys-life.png - extras/images/deerputer.png - extras/images/diagram.png - extras/images/hill.png - extras/images/i-wish.png - extras/images/latl.png - extras/images/little-wheels.png - extras/images/square-badge.png - extras/images/uniform.png - extras/images/whale-bounce.png - extras/rdoc/generator/singledarkfish.rb - extras/rdoc/generator/template/flipbook/images/Camping.gif - extras/rdoc/generator/template/flipbook/images/loadingAnimation.gif - extras/rdoc/generator/template/flipbook/images/permalink.gif - extras/rdoc/generator/template/flipbook/js/camping.js - extras/rdoc/generator/template/flipbook/js/jquery.js - extras/rdoc/generator/template/flipbook/page.rhtml - extras/rdoc/generator/template/flipbook/rdoc.css - extras/rdoc/generator/template/flipbook/readme.rhtml - extras/rdoc/generator/template/flipbook/reference.rhtml - extras/rdoc/generator/template/flipbook/toc.rhtml - book/01_introduction.md - book/02_getting_started.md - book/51_upgrading.md - examples/blog.rb - CHANGELOG homepage: http://camping.rubyforge.org/ licenses: [] post_install_message: rdoc_options: - --line-numbers - --quiet - --main - README - --exclude - ^(examples|extras)\/ - --exclude - lib/camping.rb require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 1.8.2 required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: camping rubygems_version: 1.8.25 signing_key: specification_version: 3 summary: minature rails for stay-at-home moms test_files: [] camping-2.1.532/CHANGELOG0000644000004100000410000001330312154156727014556 0ustar www-datawww-data= 2.1 === 19th Aug, 2010 (whyday) * Helpers#R now calls to_param on any object it passes in * Fix route generation issue with routes including "." (#22) * Improved tests * Improved 1.9 support * Camping::Server is now built upon Rack::Server * Add support for ERB, Haml etc through Tilt * Introducing Camping.options and Camping#set * Camping::Server only loads ActiveRecord when needed = 2.0 === 9th Apr, 2010 * Speed-up of Camping::Mab (thanks zimbatm!) * @state is now an alias of @env['rack.session'] * Camping.use injects a Rack middleware. * Update Flipbook to RDoc 2.4 * Removed old examples. * Updated examples/blog.rb * Camping::Apps returns! * Session-cookies now timeout naturally (thanks jenna!) * You can now `throw :halt` to halt the response in a helper. * Camping::H#u is gone (was an alias to merge!) * Camping::Session now uses session-cookies. The AR-backend is gone for now. * camping/db.rb has been renamed to camping/ar.rb. * Camping now uses Rack internally. Every app responds to #call. = 1.6 === Never released * Camping::Apps removed, it wasn't reliable. * bin/camping server kinds splitted in various files. * NotFound and ServerError controllers changed to methods : r404 : called when a controller was not found r500 : called on uncaught exception r501 : called on undefined method All of those can be overridden at your taste. * Markaby no longer required. Like AR, is it autoloaded on (Mab) usage. * Camping::H is now inheriting from Hash instead of HashWithIndifferentAccess. * Which made possible to remove the last strict dependency : active_support * #errors_for removed, it wasn't really used * Bug fixes ! = 1.5 === 3rd Oct, 2006 * Camping::Apps stores an array of classes for all loaded apps. * bin/camping can be given a directory. Like: camping examples/ * Console mode -- thank zimbatm. Use: camping -C yourapp.rb * Call controllers with Camping.method_missing. Tepee.get(:Index) #=> (Response) Blog.post(:Delete, id) #=> (Response) Blog.post(:Login, :input => {'username' => 'admin', 'password' => 'camping'}) #=> # Blog.get(:Info, :env => {:HTTP_HOST => 'wagon'}) #=> #'wagon'} ...> * Using \r\n instead of \n on output. FastCGI has these needs. * ActiveRecord no longer required or installed. * If you refer to Models::Base, however, ActiveRecord will be loaded with autoload. (see lib/camping/db.rb) * new Camping::FastCGI.serve which will serve a whole directory of apps (see http://code.whytheluckystiff.net/camping/wiki/TheCampingServer) * ~/.campingrc can contain database connection info if you want your default to be something other than SQLite. database: adapter: mysql username: camping socket: /tmp/mysql.sock password: NOFORESTFIRES database: camping * controllers are now *ordered*. uses the inherited hook to keep track of all classes created with R. those classes are scanned, in order, when a request is made. any other controllers are handled first. so if you plan on overriding the urls method, be sure to subclass from R(). * Console mode will load .irbrc in the working directory, if present. (for example, in my ~/git/balloon directory, i have this in the .irbrc: include Balloon::Models when camping -C balloon.rb gets run, the models all get included in main.) * And, of course, many other bugfixes from myself and the loyal+kind zimbatm... * Markaby updated to 0.5. (See its CHANGELOG.) = 1.4.2 === 18th May, 2006 * Efficient file uploads for multipart/form-data POSTs. * Camping tool now uses Mongrel, if available. If not, sticks with WEBrick. * Multiple apps can be loaded with the camping tool, each mounted according to their file name. = 1.4.1 === 3rd May, 2006 * Streaming HTTP support. If body is IO, will simply pass to the controller. Mongrel, in particular, supports this nicely. = 1.4 === 11th April, 2006 * Moved Camping::Controllers::Base to Camping::Base. * Moved Camping::Controllers::R to Camping::R. * New session library (lib/camping/session.rb). * WEBrick handler (lib/camping/webrick.rb) and Mongrel handler (lib/camping/mongrel.rb). * Helpers#URL, builds a complete URL for a route. Returns a URI object. This way relative links could just return self.URL.path. * Base#initialize takes over some of Base#service's duties. * ENV now available as @env in controllers and views. * Beautiful multi-page docs without frames! = 1.3 === 28th January, 2006 * bin/camping: an application launcher. * Camping.run(request, response) now changed to controller = Camping.run(request, env) * This means outputting the response is the wrapper/server's job. See bin/camping, you can do a controller.to_s at the least. * Controllers::Base.env is the new thread-safe home for ENV. * The input hash now works more like Rails params. You can call keys like methods or with symbols or strings. * Queries are now parsed more like PHP/Rails, in that you can denote structure with brackets: post[user]=_why;post[id]=2 * Auto-prefix table names, to help prevent name clash. * Helpers.errors_for simple validation. * Lots of empty :href and :action attributes, a bug. * New single-page flipbook RDoc template. = 1.2 === 23rd January, 2006 * Camping.goes allows fresh modules build from all Camping parts. * File uploads now supported (multipart/form-data). * Helpers.R can rebuild routes. * Helpers./ for tracing paths from the root. = 1.1 === 19th January, 2006 * Allowed request and response streams to be passed in, to allow WEBrick and FastCGI support. = 1.0 === 17th January, 2006 * Initial checkin, see announcement at http://redhanded.hobix.com/bits/campingAMicroframework.html. camping-2.1.532/COPYING0000644000004100000410000000203012154156727014372 0ustar www-datawww-dataCopyright (c) 2006 why the lucky stiff Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. camping-2.1.532/lib/0000755000004100000410000000000012154156727014112 5ustar www-datawww-datacamping-2.1.532/lib/camping/0000755000004100000410000000000012154156727015530 5ustar www-datawww-datacamping-2.1.532/lib/camping/session.rb0000644000004100000410000000213112154156727017535 0ustar www-datawww-datamodule Camping # == Getting Started # # To get sessions working for your application: # 1. require 'camping/session' # 2. Define a secret (and keep it secret): set :secret, "SECRET!" # 3. Mixin the module: include Camping::Session # 4. Throughout your application, use the @state var like a hash # to store your application's data. # # require 'camping/session' # 1 # # module Nuts # set :secret, "Oh yeah!" # 2 # include Camping::Session # 3 # end # # == Other backends # # Camping only ships with session-cookies. However, the @state # variable is simply a shortcut for @env['rack.session']. Therefore # you can also use any middleware which sets this variable: # # module Nuts # use Rack::Session::Memcache # end module Session def self.included(app) key = "#{app}.state".downcase secret = app.options[:secret] || [__FILE__, File.mtime(__FILE__)].join(":") app.use Rack::Session::Cookie, :key => key, :secret => secret end end endcamping-2.1.532/lib/camping/ar.rb0000644000004100000410000000435312154156727016464 0ustar www-datawww-dataclass MissingLibrary < Exception #:nodoc: all end begin require 'active_record' rescue LoadError => e raise MissingLibrary, "ActiveRecord could not be loaded (is it installed?): #{e.message}" end $AR_EXTRAS = %{ Base = ActiveRecord::Base unless const_defined? :Base class SchemaInfo < Base end def self.V(n) @final = [n, @final.to_f].max m = (@migrations ||= []) Class.new(ActiveRecord::Migration) do meta_def(:version) { n } meta_def(:inherited) { |k| m << k } end end def self.create_schema(opts = {}) opts[:assume] ||= 0 opts[:version] ||= @final if @migrations unless SchemaInfo.table_exists? ActiveRecord::Schema.define do create_table SchemaInfo.table_name do |t| t.column :version, :float end end end si = SchemaInfo.find(:first) || SchemaInfo.new(:version => opts[:assume]) if si.version < opts[:version] @migrations.sort_by { |m| m.version }.each do |k| k.migrate(:up) if si.version < k.version and k.version <= opts[:version] k.migrate(:down) if si.version > k.version and k.version > opts[:version] end si.update_attributes(:version => opts[:version]) end end end } module Camping module Models A = ActiveRecord # Base is an alias for ActiveRecord::Base. The big warning I'm going to give you # about this: *Base overloads table_name_prefix.* This means that if you have a # model class Blog::Models::Post, it's table name will be blog_posts. # # ActiveRecord is not loaded if you never reference this class. The minute you # use the ActiveRecord or Camping::Models::Base class, then the ActiveRecord library # is loaded. Base = A::Base # The default prefix for Camping model classes is the topmost module name lowercase # and followed with an underscore. # # Tepee::Models::Page.table_name_prefix # #=> "tepee_pages" # def Base.table_name_prefix "#{name[/\w+/]}_".downcase.sub(/^(#{A}|camping)_/i,'') end module_eval $AR_EXTRAS end end Camping::S.sub! /autoload\s*:Base\s*,\s*['"]camping\/ar['"]/, $AR_EXTRAS Camping::Apps.each do |c| c::Models.module_eval $AR_EXTRAS end camping-2.1.532/lib/camping/server.rb0000644000004100000410000001267012154156727017371 0ustar www-datawww-datarequire 'irb' require 'erb' require 'rack' require 'camping/reloader' # == The Camping Server (for development) # # Camping includes a pretty nifty server which is built for development. # It follows these rules: # # * Load all Camping apps in a directory or a file. # * Load new apps that appear in that directory or that file. # * Mount those apps according to their name. (e.g. Blog is mounted at /blog.) # * Run each app's create method upon startup. # * Reload the app if its modification time changes. # * Reload the app if it requires any files under the same directory and one # of their modification times changes. # * Support the X-Sendfile header. # # Run it like this: # # camping examples/ # Mounts all apps in that directory # camping blog.rb # Mounts Blog at / # # And visit http://localhost:3301/ in your browser. module Camping class Server < Rack::Server class Options if home = ENV['HOME'] # POSIX DB = File.join(home, '.camping.db') RC = File.join(home, '.campingrc') elsif home = ENV['APPDATA'] # MSWIN DB = File.join(home, 'Camping.db') RC = File.join(home, 'Campingrc') else DB = nil RC = nil end HOME = File.expand_path(home) + '/' def parse!(args) args = args.dup options = {} opt_parser = OptionParser.new("", 24, ' ') do |opts| opts.banner = "Usage: camping my-camping-app.rb" opts.define_head "#{File.basename($0)}, the microframework ON-button for ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]" opts.separator "" opts.separator "Specific options:" opts.on("-h", "--host HOSTNAME", "Host for web server to bind to (default is all IPs)") { |v| options[:Host] = v } opts.on("-p", "--port NUM", "Port for web server (defaults to 3301)") { |v| options[:Port] = v } db = DB.sub(HOME, '~/') if DB opts.on("-d", "--database FILE", "SQLite3 database path (defaults to #{db ? db : ''})") { |db_path| options[:database] = db_path } opts.on("-C", "--console", "Run in console mode with IRB") { options[:server] = "console" } server_list = ["thin", "webrick", "console"] opts.on("-s", "--server NAME", "Server to force (#{server_list.join(', ')})") { |v| options[:server] = v } opts.separator "" opts.separator "Common options:" # No argument, shows at tail. This will print an options summary. # Try it and see! opts.on_tail("-?", "--help", "Show this message") do puts opts exit end # Another typical switch to print the version. opts.on_tail("-v", "--version", "Show version") do puts Gem.loaded_specs['camping'].version exit end end opt_parser.parse!(args) if args.empty? puts opt_parser exit end options[:script] = args.shift options end end def initialize(*) super @reloader = Camping::Reloader.new(options[:script]) do |app| if !app.options.has_key?(:dynamic_templates) app.options[:dynamic_templates] = true end if !Camping::Models.autoload?(:Base) && options[:database] Camping::Models::Base.establish_connection( :adapter => 'sqlite3', :database => options[:database] ) end end end def opt_parser Options.new end def default_options super.merge({ :Port => 3301, :database => Options::DB }) end def middleware h = super h["development"] << [XSendfile] h end def start if options[:server] == "console" puts "** Starting console" @reloader.reload! r = @reloader eval("self", TOPLEVEL_BINDING).meta_def(:reload!) { r.reload!; nil } ARGV.clear IRB.start exit else name = server.name[/\w+$/] puts "** Starting #{name} on #{options[:Host]}:#{options[:Port]}" super end end def public_dir File.expand_path('../public', @reloader.file) end def app Rack::Cascade.new([Rack::File.new(public_dir), self], [405, 404, 403]) end def current_app @reloader.reload apps = @reloader.apps return apps.values.first if apps.size == 1 if key = apps.keys.grep(/^#{@reloader.name}$/i)[0] apps[key] end end def call(env) app = current_app || raise("Could not find an app called `#{@reloader.name}`") app.call(env) end class XSendfile def initialize(app) @app = app end def call(env) status, headers, body = @app.call(env) if key = headers.keys.grep(/X-Sendfile/i).first filename = headers[key] content = open(filename,'rb') { | io | io.read} headers['Content-Length'] = size(content).to_s body = [content] end return status, headers, body end if "".respond_to?(:bytesize) def size(str) str.bytesize end else def size(str) str.size end end end end end camping-2.1.532/lib/camping/template.rb0000644000004100000410000000066112154156727017673 0ustar www-datawww-dataclass MissingLibrary < Exception #:nodoc: all end begin require 'tilt' rescue LoadError => e raise MissingLibrary, "Tilt could not be loaded (is it installed?): #{e.message}" end $TILT_CODE = %{ Template = Tilt include Tilt::CompileSite unless self.options[:dynamic_templates] } Camping::S.sub! /autoload\s*:Template\s*,\s*['"]camping\/template['"]/, $TILT_CODE Camping::Apps.each do |c| c.module_eval $TILT_CODE end camping-2.1.532/lib/camping/reloader.rb0000644000004100000410000000761412154156727017662 0ustar www-datawww-datamodule Camping # == The Camping Reloader # # Camping apps are generally small and predictable. Many Camping apps are # contained within a single file. Larger apps are split into a handful of # other Ruby libraries within the same directory. # # Since Camping apps (and their dependencies) are loaded with Ruby's require # method, there is a record of them in $LOADED_FEATURES. Which leaves a # perfect space for this class to manage auto-reloading an app if any of its # immediate dependencies changes. # # == Wrapping Your Apps # # Since bin/camping and the Camping::Server class already use the Reloader, # you probably don't need to hack it on your own. But, if you're rolling your # own situation, here's how. # # Rather than this: # # require 'yourapp' # # Use this: # # require 'camping/reloader' # reloader = Camping::Reloader.new('/path/to/yourapp.rb') # blog = reloader.apps[:Blog] # wiki = reloader.apps[:Wiki] # # The blog and wiki objects will behave exactly like your # Blog and Wiki, but they will update themselves if yourapp.rb changes. # # You can also give Reloader more than one script. class Reloader attr_reader :file def initialize(file, &blk) @file = file @mtime = Time.at(0) @requires = [] @apps = {} @callback = blk end def name @name ||= begin base = @file.dup base = File.dirname(base) if base =~ /\bconfig\.ru$/ base.sub!(/\.[^.]+/, '') File.basename(base).to_sym end end # Loads the apps availble in this script. Use apps to get # the loaded apps. def load_apps(old_apps) all_requires = $LOADED_FEATURES.dup all_apps = Camping::Apps.dup load_file ensure @requires = [] dirs = [] new_apps = Camping::Apps - all_apps @apps = new_apps.inject({}) do |hash, app| if file = app.options[:__FILE__] full = File.expand_path(file) @requires << [file, full] dirs << full.sub(/\.[^.]+$/, '') end key = app.name.to_sym hash[key] = app if !old_apps.include?(key) @callback.call(app) if @callback app.create if app.respond_to?(:create) end hash end ($LOADED_FEATURES - all_requires).each do |req| full = full_path(req) @requires << [req, full] if dirs.any? { |x| full.index(x) == 0 } end @mtime = mtime self end def load_file if @file =~ /\.ru$/ @app,_ = Rack::Builder.parse_file(@file) else load(@file) end end # Removes all the apps defined in this script. def remove_apps @requires.each do |(path, full)| $LOADED_FEATURES.delete(path) end @apps.each do |name, app| Camping::Apps.delete(app) Object.send :remove_const, name end.dup ensure @apps.clear end # Reloads the file if needed. No harm is done by calling this multiple # times, so feel free call just to be sure. def reload return if @mtime >= mtime rescue nil reload! end def reload! load_apps(remove_apps) end # Checks if both scripts watches the same file. def ==(other) @file == other.file end def apps if @app { name => @app } else @apps end end private def mtime @requires.map do |(path, full)| File.mtime(full) end.reject {|t| t > Time.now }.max || Time.now end # Figures out the full path of a required file. def full_path(req) return req if File.exists?(req) dir = $LOAD_PATH.detect { |l| File.exists?(File.join(l, req)) } if dir File.expand_path(req, File.expand_path(dir)) else req end end end end camping-2.1.532/lib/camping/mab.rb0000644000004100000410000000156412154156727016622 0ustar www-datawww-dataclass MissingLibrary < Exception #:nodoc: all end begin require 'mab' rescue LoadError => e raise MissingLibrary, "Mab could not be loaded (is it installed?): #{e.message}" end $MAB_CODE = %q{ module Mab include ::Mab::Mixin::HTML5 include Views alias << text! def xhtml(*a, &b) warn "xhtml_strict is no longer supported (or an active standard); using HTML5 instead" html(*a, &b) end def xhtml_strict(*a, &b) xhtml(*a, &b) end def xhtml_transitional(*a, &b) xhtml(*a, &b) end def xhtml_frameset(*a, &b) xhtml(*a, &b) end def helpers() self end def html(*) doctype!; super end def mab_done(tag) h=tag._attributes [:href,:action,:src].map{|a|h[a]&&=self/h[a]} end end } Camping::S.sub! /autoload\s*:Mab\s*,\s*['"]camping\/mab['"]/, $MAB_CODE Camping::Apps.each do |c| c.module_eval $MAB_CODE end camping-2.1.532/lib/camping-unabridged.rb0000644000004100000410000006145012154156727020165 0ustar www-datawww-data# == About camping.rb # # Camping comes with two versions of its source code. The code contained in # lib/camping.rb is compressed, stripped of whitespace, using compact algorithms # to keep it tight. The unspoken rule is that camping.rb should be flowed with # no more than 80 characters per line and must not exceed four kilobytes. # # On the other hand, lib/camping-unabridged.rb contains the same code, laid out # nicely with piles of documentation everywhere. This documentation is entirely # generated from lib/camping-unabridged.rb using RDoc and our "flipbook" template # found in the extras directory of any camping distribution. require "uri" require "rack" $LOADED_FEATURES << "camping.rb" class Object #:nodoc: def meta_def(m,&b) #:nodoc: (class<Camping.goes :Nuts # copies the Camping module into Nuts. This means that you should never use # any of these methods/classes on the Camping module, but rather on your own # app. Here's a short explanation on how Camping is organized: # # * Camping::Controllers is where your controllers live. # * Camping::Models is where your models live. # * Camping::Views is where your views live. # * Camping::Base is a module which is included in all your controllers. # * Camping::Helpers is a module with useful helpers, both for the controllers # and the views. You should fill this up with your own helpers. # # Camping also ships with: # # * Camping::Session adds states to your app. # * Camping::Server starts up your app in development. # * Camping::Reloader automatically reloads your apps when a file has changed. # # More importantly, Camping also installs The Camping Server, # please see Camping::Server. module Camping C = self S = IO.read(__FILE__) rescue nil P = "

Cam\ping Problem!

%s

" U = Rack::Utils O = {} Apps = [] SK = :camping #Key for r.session # An object-like Hash. # All Camping query string and cookie variables are loaded as this. # # To access the query string, for instance, use the @input variable. # # module Blog::Controllers # class Index < R '/' # def get # if (page = @input.page.to_i) > 0 # page -= 1 # end # @posts = Post.all, :offset => page * 20, :limit => 20 # render :index # end # end # end # # In the above example if you visit /?page=2, you'll get the second # page of twenty posts. You can also use @input['page'] to get the # value for the page query variable. class H < Hash # Gets or sets keys in the hash. # # @cookies.my_favorite = :macadamian # @cookies.my_favorite # => :macadamian # def method_missing(m,*a) m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.to_s]:super end undef id, type if ?? == 63 end class Cookies < H attr_accessor :_p # # Cookies that are set at this response def _n; @n ||= {} end alias _s []= def set(k, v, o = {}) _s(j=k.to_s, v) _n[j] = {:value => v, :path => _p}.update(o) end def []=(k, v) set k, v, v.is_a?(Hash) ? v : {} end end # Helpers contains methods available in your controllers and views. You may # add methods of your own to this module, including many helper methods from # Rails. This is analogous to Rails' ApplicationHelper module. # # == Using ActionPack Helpers # # If you'd like to include helpers from Rails' modules, you'll need to look # up the helper module in the Rails documentation at http://api.rubyonrails.org/. # # For example, if you look up the ActionView::Helpers::FormTagHelper # class, you'll find that it's loaded from the action_view/helpers/form_tag_helper.rb # file. You'll need to have the ActionPack gem installed for this to work. # # Often the helpers depends on other helpers, so you would have to look up # the dependencies too. FormTagHelper for instance required the # content_tag provided by TagHelper. # # require 'action_view/helpers/form_tag_helper' # # module Nuts::Helpers # include ActionView::Helpers::TagHelper # include ActionView::Helpers::FormTagHelper # end # # == Return a response immediately # If you need to return a response inside a helper, you can use throw :halt. # # module Nuts::Helpers # def requires_login! # unless @state.user_id # redirect Login # throw :halt # end # end # end # # module Nuts::Controllers # class Admin # def get # requires_login! # "Never gets here unless you're logged in" # end # end # end module Helpers # From inside your controllers and views, you will often need to figure out # the route used to get to a certain controller +c+. Pass the controller # class and any arguments into the R method, a string containing the route # will be returned to you. # # Assuming you have a specific route in an edit controller: # # class Edit < R '/edit/(\d+)' # # A specific route to the Edit controller can be built with: # # R(Edit, 1) # # Which outputs: /edit/1. # # If a controller has many routes, the route will be selected if it is the # first in the routing list to have the right number of arguments. # # == Using R in the View # # Keep in mind that this route doesn't include the root path. You will # need to use / (the slash method above) in your controllers. # Or, go ahead and use the Helpers#URL method to build a complete URL for # a route. # # However, in your views, the :href, :src and :action attributes # automatically pass through the slash method, so you are encouraged to # use R or URL in your views. # # module Nuts::Views # def menu # div.menu! do # a 'Home', :href => URL() # a 'Profile', :href => "/profile" # a 'Logout', :href => R(Logout) # a 'Google', :href => 'http://google.com' # end # end # end # # Let's say the above example takes place inside an application mounted at # http://localhost:3301/frodo and that a controller named # Logout is assigned to route /logout. # The HTML will come out as: # #
# def R(c,*g) p,h=/\(.+?\)/,g.grep(Hash) g-=h raise "bad route" if !u = c.urls.find{|x| break x if x.scan(p).size == g.size && /^#{x}\/?$/ =~ (x=g.inject(x){|x,a| x.sub p,U.escape((a.to_param rescue a))}.gsub(/\\(.)/){$1}) } h.any?? u+"?"+U.build_query(h[0]) : u end # Simply builds a complete path from a path +p+ within the app. If your # application is mounted at /blog: # # self / "/view/1" #=> "/blog/view/1" # self / "styles.css" #=> "styles.css" # self / R(Edit, 1) #=> "/blog/edit/1" # def /(p); p[0] == ?/ ? @root + p : p end # Builds a URL route to a controller or a path, returning a URI object. # This way you'll get the hostname and the port number, a complete URL. # # You can use this to grab URLs for controllers using the R-style syntax. # So, if your application is mounted at http://test.ing/blog/ # and you have a View controller which routes as R '/view/(\d+)': # # URL(View, @post.id) #=> # # # Or you can use the direct path: # # self.URL #=> # # self.URL + "view/12" #=> # # URL("/view/12") #=> # # # It's okay to pass URL strings through this method as well: # # URL("http://google.com") #=> # # # Any string which doesn't begin with a slash will pass through # unscathed. def URL c='/',*a c = R(c, *a) if c.respond_to? :urls c = self/c c = @request.url[/.{8,}?(?=\/|$)/]+c if c[0]==?/ URI(c) end end # Camping::Base is built into each controller by way of the generic routing # class Camping::R. In some ways, this class is trying to do too much, but # it saves code for all the glue to stay in one place. Forgivable, # considering that it's only really a handful of methods and accessors. # # Everything in this module is accessible inside your controllers. module Base attr_accessor :env, :request, :root, :input, :cookies, :state, :status, :headers, :body T = {} L = :layout # Finds a template, returning either: # # false # => Could not find template # true # => Found template in Views # instance of Tilt # => Found template in a file def lookup(n) T.fetch(n.to_sym) do |k| t = Views.method_defined?(k) || (t = O[:_t].keys.grep(/^#{n}\./)[0]and Template[t].new{O[:_t][t]}) || (f = Dir[[O[:views] || "views", "#{n}.*"]*'/'][0]) && Template.new(f, O[f[/\.(\w+)$/, 1].to_sym] || {}) O[:dynamic_templates] ? t : T[k] = t end end # Display a view, calling it by its method name +v+. If a layout # method is found in Camping::Views, it will be used to wrap the HTML. # # module Nuts::Controllers # class Show # def get # @posts = Post.find :all # render :index # end # end # end # def render(v, *a, &b) if t = lookup(v) r, @_r = @_r, o = Hash === a[-1] ? a.pop : {} s = (t == true) ? mab { send(v, *a, &b) } : t.render(self, o[:locals] || {}, &b) s = render(L, o.merge(L => false)) { s } if o[L] or o[L].nil? && lookup(L) && (!r && v.to_s[0] != ?_) s else raise "no template: #{v}" end end # You can directly return HTML from your controller for quick debugging # by calling this method and passing some Markaby to it. # # module Nuts::Controllers # class Info # def get; mab{ code @headers.inspect } end # end # end # # You can also pass true to use the :layout HTML wrapping method def mab(&b) extend Mab mab(&b) end # A quick means of setting this controller's status, body and headers # based on a Rack response: # # r(302, 'Location' => self / "/view/12", '') # r(*another_app.call(@env)) # # You can also switch the body and the header if you want: # # r(404, "Could not find page") # # See also: #r404, #r500 and #r501 def r(s, b, h = {}) b, h = h, b if Hash === b @status = s @headers.merge!(h) @body = b end # Formulate a redirect response: a 302 status with Location header # and a blank body. Uses Helpers#URL to build the location from a # controller route or path. # # So, given a root of http://localhost:3301/articles: # # redirect "view/12" # redirects to "//localhost:3301/articles/view/12" # redirect View, 12 # redirects to "//localhost:3301/articles/view/12" # # NOTE: This method doesn't magically exit your methods and redirect. # You'll need to return redirect(...) if this isn't the last statement # in your code, or throw :halt if it's in a helper. # # See: Controllers def redirect(*a) r(302,'','Location'=>URL(*a).to_s) end # Called when a controller was not found. You can override this if you # want to customize the error page: # # module Nuts # def r404(path) # @path = path # render :not_found # end # end def r404(p) P % "#{p} not found" end # Called when an exception is raised. However, if there is a parse error # in Camping or in your application's source code, it will not be caught. # # +k+ is the controller class, +m+ is the request method (GET, POST, etc.) # and +e+ is the Exception which can be mined for useful info. # # Be default this simply re-raises the error so a Rack middleware can # handle it, but you are free to override it here: # # module Nuts # def r500(klass, method, exception) # send_email_alert(klass, method, exception) # render :server_error # end # end def r500(k,m,e) raise e end # Called if an undefined method is called on a controller, along with the # request method +m+ (GET, POST, etc.) def r501(m) P % "#{m.upcase} not implemented" end # Serves the string +c+ with the MIME type of the filename +p+. # Default text/html def serve(p, c) t = Rack::Mime.mime_type(p[/\..*$/], "text/html") and @headers['Content-Type'] = t c end # Turn a controller into a Rack response. This is designed to be used to # pipe controllers into the r method. A great way to forward your # requests! # # class Read < '/(\d+)' # def get(id) # Post.find(id) # rescue # r *Blog.get(:NotFound, @headers.REQUEST_URI) # end # end def to_a @env['rack.session'][SK] = Hash[@state] r = Rack::Response.new(@body, @status, @headers) @cookies._n.each do |k, v| r.set_cookie(k, v) end r.to_a end def initialize(env, m) #:nodoc: r = @request = Rack::Request.new(@env = env) @root, @input, @cookies, @state, @headers, @status, @method = r.script_name.sub(/\/$/,''), n(r.params), Cookies[r.cookies], H[r.session[SK]||{}], {'Content-Type'=>'text/html'}, m =~ /r(\d+)/ ? $1.to_i : 200, m @cookies._p = self/"/" end def n(h) # :nodoc: if Hash === h h.inject(H[]) do |m, (k, v)| m[k] = n(v) m end else h end end # All requests pass through this method before going to the controller. # Some magic in Camping can be performed by overriding this method. def service(*a) r = catch(:halt){send(@method, *a)} @body ||= r self end end # Controllers receive the requests and sends a response back to the client. # A controller is simply a class which must implement the HTTP methods it # wants to accept: # # module Nuts::Controllers # class Index # def get # "Hello World" # end # end # # class Posts # def post # Post.create(@input) # redirect Index # end # end # end # # == Defining a controller # # There are two ways to define controllers: Just defining a class and let # Camping figure out the route, or add the route explicitly using R. # # If you don't use R, Camping will first split the controller name up by # words (HelloWorld => Hello and World). Then it would do the following: # # * Replace Index with / # * Replace X with ([^/]+) # * Replace N with (\\\d+) # * Everything else turns into lowercase # * Join the words with slashes # #-- # NB! N will actually be replaced with (\d+), but it needs to be escaped # here in order to work correctly with RDoc. #++ # # Here's a few examples: # # Index # => / # PostN # => /post/(\d+) # PageX # => /page/([^/]+) # Pages # => /pages # # == The request # # You have these variables which describes the request: # # * @env contains the environment as defined in http://rack.rubyforge.org/doc/SPEC.html # * @request is Rack::Request.new(@env) # * @root is the path where the app is mounted # * @cookies is a hash with the cookies sent by the client # * @state is a hash with the sessions (see Camping::Session) # * @method is the HTTP method in lowercase # # == The response # # You can change these variables to your needs: # # * @status is the HTTP status (defaults to 200) # * @headers is a hash with the headers # * @body is the body (a string or something which responds to #each) # * Any changes in @cookies and @state will also be sent to the client # # If you haven't set @body, it will use the return value of the method: # # module Nuts::Controllers # class Index # def get # "This is the body" # end # end # # class Posts # def get # @body = "Hello World!" # "This is ignored" # end # end # end module Controllers @r = [] class << self # Add routes to a controller class by piling them into the R method. # # The route is a regexp which will match the request path. Anything # enclosed in parenthesis will be sent to the method as arguments. # # module Camping::Controllers # class Edit < R '/edit/(\d+)', '/new' # def get(id) # if id # edit # else # new # end # end # end # end def R *u r=@r Class.new { meta_def(:urls){u} meta_def(:inherited){|x|r< '(\d+)', "X" => '([^/]+)', "Index" => '' # The route maker, this is called by Camping internally, you shouldn't # need to call it. # # Still, it's worth know what this method does. Since Ruby doesn't keep # track of class creation order, we're keeping an internal list of the # controllers which inherit from R(). This method goes through and adds # all the remaining routes to the beginning of the list and ensures all # the controllers have the right mixins. # # Anyway, if you are calling the URI dispatcher from outside of a # Camping server, you'll definitely need to call this to set things up. # Don't call it too early though. Any controllers added after this # method is called won't work properly def M def M #:nodoc: end constants.map { |c| k = const_get(c) k.send :include,C,X,Base,Helpers,Models @r=[k]+@r if @r-[k]==@r k.meta_def(:urls){["/#{c.to_s.scan(/.[^A-Z]*/).map(&N.method(:[]))*'/'}"]}if !k.respond_to?:urls } end end # Internal controller with no route. Used to show internal messages. I = R() end X = Controllers class << self # When you are running many applications, you may want to create # independent modules for each Camping application. Camping::goes # defines a toplevel constant with the whole MVC rack inside: # # require 'camping' # Camping.goes :Nuts # # module Nuts::Controllers; ... end # module Nuts::Models; ... end # module Nuts::Views; ... end # # Additionally, you can pass a Binding as the second parameter, # which enables you to create a Camping-based application within # another module, for example to namespace your web interface and # code for a worker process together: # # module YourApplication # Camping.goes :Web, binding() # module Web # ... # end # module Worker # ... # end # end # # All the applications will be available in Camping::Apps. def goes(m, g=TOPLEVEL_BINDING) Apps << a = eval(S.gsub(/Camping/,m.to_s), g) caller[0]=~/:/ IO.read(a.set:__FILE__,$`)=~/^__END__/ && (b=$'.split(/^@@\s*(.+?)\s*\r?\n/m)).shift rescue nil a.set :_t,H[*b||[]] end # Ruby web servers use this method to enter the Camping realm. The +e+ # argument is the environment variables hash as per the Rack specification. # And array with [status, headers, body] is expected at the output. # # See: http://rack.rubyforge.org/doc/SPEC.html def call(e) X.M k,m,*a=X.D e['PATH_INFO'],e['REQUEST_METHOD'].downcase,e k.new(e,m).service(*a).to_a rescue r500(:I, k, m, $!, :env => e).to_a end # The Camping scriptable dispatcher. Any unhandled method call to the app # module will be sent to a controller class, specified as an argument. # # Blog.get(:Index) # #=> # # # The controller object contains all the @cookies, @body, @headers, etc. # formulated by the response. # # You can also feed environment variables and query variables as a hash, # the final argument. # # Blog.post(:Login, :input => {'username' => 'admin', 'password' => 'camping'}) # #=> # # # Blog.get(:Info, :env => {'HTTP_HOST' => 'wagon'}) # #=> #'wagon'} ...> # def method_missing(m, c, *a) X.M h = Hash === a[-1] ? a.pop : {} e = H[Rack::MockRequest.env_for('',h.delete(:env)||{})] k = X.const_get(c).new(e,m.to_s) h.each { |i, v| k.send("#{i}=", v) } k.service(*a) end # Injects a middleware: # # module Blog # use Rack::MethodOverride # use Rack::Session::Memcache, :key => "session" # end def use(*a, &b) m = a.shift.new(method(:call), *a, &b) meta_def(:call) { |e| m.call(e) } end # A hash where you can set different settings. def options O end # Shortcut for setting options: # # module Blog # set :secret, "Hello!" # end def set(k, v) O[k] = v end end # Views is an empty module for storing methods which create HTML. The HTML # is described using the Markaby language. # # == Defining and calling templates # # Templates are simply Ruby methods with Markaby inside: # # module Blog::Views # def index # p "Welcome to my blog" # end # # def show # h1 @post.title # self << @post.content # end # end # # In your controllers you just call render :template_name which will # invoke the template. The views and controllers will share instance # variables (as you can see above). # # == Using the layout method # # If your Views module has a layout method defined, it will be # called with a block which will insert content from your view: # # module Blog::Views # def layout # html do # head { title "My Blog "} # body { self << yield } # end # end # end module Views; include X, Helpers end # Models is an empty Ruby module for housing model classes derived # from ActiveRecord::Base. As a shortcut, you may derive from Base # which is an alias for ActiveRecord::Base. # # module Camping::Models # class Post < Base; belongs_to :user end # class User < Base; has_many :posts end # end # # == Where Models are Used # # Models are used in your controller classes. However, if your model class # name conflicts with a controller class name, you will need to refer to it # using the Models module. # # module Camping::Controllers # class Post < R '/post/(\d+)' # def get(post_id) # @post = Models::Post.find post_id # render :index # end # end # end # # Models cannot be referred to in Views at this time. module Models autoload :Base,'camping/ar' Helpers.send(:include, X, self) end autoload :Mab, 'camping/mab' autoload :Template, 'camping/template' C end camping-2.1.532/lib/camping.rb0000644000004100000410000000770512154156727016066 0ustar www-datawww-datarequire "uri";require "rack";class Object;def meta_def m,&b;(class<v,:path=>_p}.update o;end;def []=(k,v)set(k,v,v.is_a?(Hash)?v:{})end end;module Helpers;def R c,*g;p,h= /\(.+?\)/,g.grep(Hash);g-=h;raise"bad route"unless u=c.urls.find{|x|break x if x.scan(p).size==g.size&&/^#{x}\/?$/=~(x=g.inject(x){|x,a|x.sub p,U.escape((a. to_param rescue a))}.gsub(/\\(.)/){$1})};h.any?? u+"?"+U.build_query(h[0]):u end;def / p;p[0]==?/?@root+p :p end;def URL c='/',*a;c=R(c,*a) if c.respond_to?( :urls);c=self/c;c=@request.url[/.{8,}?(?=\/|$)/]+c if c[0]==?/;URI c end end module Base;attr_accessor:env,:request,:root,:input,:cookies,:state,:status, :headers,:body;T={};L=:layout;def lookup n;T.fetch(n.to_sym){|k|t=Views. method_defined?(k)||(t=O[:_t].keys.grep(/^#{n}\./)[0]and Template[t].new{ O[:_t][t]})||(f=Dir[[O[:views]||"views","#{n}.*"]*'/'][0])&&Template. new(f,O[f[/\.(\w+)$/,1].to_sym]||{});O[:dynamic_templates]?t:T[k]=t} end def render v,*a,&b;if t=lookup(v);r,@_r=@_r,o=Hash===a[-1]?a.pop: {};s=(t==true)?mab{ send v,*a,&b}: t.render(self,o[:locals]||{},&b);s=render(L,o.merge(L=>false)){s }if o[L]or o[L].nil?&&lookup(L)&&!r&&v.to_s[0]!=?_;s;else;raise"no template: #{v}" end;end;def mab &b;extend(Mab);mab(&b) end;def r s,b,h={};b,h= h,b if Hash===b;@status=s;@headers.merge!(h);@body=b end;def redirect *a;r 302, '','Location'=>URL(*a).to_s end;def r404 p;P%"#{p} not found"end;def r500 k,m,e raise e end;def r501 m;P%"#{m.upcase} not implemented"end;def serve(p,c) (t=Rack::Mime.mime_type p[/\..*$/],"text/html")&&@headers["Content-Type"]=t;c;end;def to_a;@env[ 'rack.session'][SK]=Hash[@state];r=Rack::Response.new(@body,@status,@headers) @cookies._n.each{|k,v|r.set_cookie k,v};r.to_a end;def initialize env,m r=@request=Rack:: Request.new(@env=env);@root,@input,@cookies,@state,@headers, @status,@method=r.script_name.sub(/\/$/,''),n(r.params),Cookies[r.cookies], H[r.session[SK]||{}],{'Content-Type'=>'text/html'},m=~/r(\d+)/?$1.to_i: 200,m;@cookies._p=self/"/" end def n h;Hash===h ?h.inject(H[]){|m,(k,v)|m[k]= n(v);m}: h end;def service *a;r=catch(:halt){send(@method,*a)};@body||=r;self end end;module Controllers;@r=[];class<'(\d+)',"X"=>'([^/]+)',"Index"=>'');def M;def M;end;constants. map{|c|k=const_get(c);k.send:include,C,X,Base,Helpers,Models @r=[k]+@r if @r-[k]==@r;k.meta_def(:urls){["/#{c.to_s.scan(/.[^A-Z]*/).map(& N.method(:[]))*'/'}"]}if !k.respond_to?:urls}end end;I=R()end;X= Controllers;class<e).to_a end def method_missing m,c,*a;X.M;h=Hash===a[-1]?a.pop: {};e=H[Rack::MockRequest. env_for('',h.delete(:env)||{})];k=X.const_get(c).new(e,m.to_s);h.each{|i,v|k. send"#{i}=",v};k.service(*a) end;def use*a,&b;m=a.shift.new(method(:call),*a,&b) meta_def(:call){|e|m.call(e)}end;def options;O end;def set k,v;O[k]=v end end module Views;include X,Helpers end;module Models;autoload:Base,'camping/ar' Helpers.send:include,X,self end;autoload:Mab,'camping/mab' autoload:Template,'camping/template';C end