ࡱ> naAA%p/PNG  IHDR:sRGB pHYs+IDATx^与$:39_y}qx8Td"2H A`ANN#{A`cx0  0 #0  0  0 p`A`nG`! A`AKgA` G 0  0`p}Zd4[42yɷ-嗞v3#.*{?<I $[F_鹲_U= _grcNB$"2K,*{{(^8a"AFY_Je9%.ZCɢ;$ !`p+8qgb&Ɠ@Z Emڔ! ~H jʹp aJn$:b2(H=可+KL8? x׏Ii>ɂVLSs/Yv1=Gmh/0Z q贱2AcQ6 嶢Ǩ&$R\y1}m()fslݓ274nY<2N aΖe^ Y ]LɁ,m`$0J7 w#JZ-k^IQ>̻-75֩[歅0CB >9TG[Bz4|CF`n%y_77= w އ8{_ELY*R:A e&[?#6B@bxq! EږXMco @1`s(CJixb&C,K W 3X%&h2>@e'JS!I^`ɫ"3jF˳w:Bn8 D tڙ6yӨ_:,  Gps͎f; %3"6ECqECoxrf@L [u]2G.(n""-7*%dunK !W^5d4a5-=N)/w4ʽ@zFW[C K_YeޑPXJY=.Lˎ^xr+dQO {kwD]AuU7:iPG#zVQr'Gh5D~}G/a?_V]Q4ev*`Wظ\H'c]**4 /"|6%@" ],q1 *=)Ep,a>^9z{vPR aa(~ihXRy>? b r@F/;33] ]c {]Ud T;Tf]6Sqث*39K4N!'C]$`+d2[mdkXpBwCkӓ[Uӌ |U=zd֕LbKw|* HC^ᰉ1%TʕA5H7[NyW]}]6k/~{mXJ/_&K<>ٲZHœ#,0^ҲpLh{vu2a-&LY ٵ&BS^x:We&_7Z].PL+}fmN%6KEw32Hi&UJ&@C1 Ele"Ve{|Qn$I3 _iHw+ka-$y- "3yI@* g)p8T~k/0چ:uFvy$@طL 8#4-:8ǩDɽ~zAgxK( 0  p+{~#|A` pd{X!A`A//!fZ=  0 _*2#DZzA`L 0  0 p ?A`An?  0 5[`A`nG`! A`A` 0  0܎4C<  0 4ÁA`A`i8nx6A`i8 0  p;pl0  0 p A`Av`A`  0 Lq;ij 0  0L1A`vgA`A`c80  0 #0  0  _?5hf_&R )ܫ!!08h@̶) c]*%Ų!1,-W]m({3s~ 'u?YbnǀUzL-K=Ctmu ΖZ4|of0ECI5U!mƢ9bA)/WxXQd, D^ِlct @-ac GA33Bw0  ?r~%I_ K \ć3iJ4_3ç`ʧ{I@9=3ҞcQ݂%%1z~mF]pJ_̄A`"P?R { pQo 1:)w%LKóEihlz F k=1cn)3MJt]d}Yk3g~i8?ulҧ]g>ٕE t-W &׃z[䠞#j/R4}䓻T~p# *4<&M{}&pfT"~#cjF?@)kvcyOq{bW0CX{&W)MjvY~ XF$̈́HGh쿥쟦"_-G8=,Cd~hzAz~w_VlΫVu 8t!O v٦L'9xv~Ԙcv5"P^ 0A ʤ&p+G?O0WW %LrG]5o?r!!\[҇~|ӰTI:;?!t{]o en8^c% o22 >hW6[d3H<_o4_ucxp|L W1! ` ͶBBu IH/Rg z $P,"PG"[l믙_"@}i4l~`“C쫩kG7GUнQJO7&,4&:׈e +Bx}Ba^Lcfkhr[XCYCer8b'X&z):goE=RьA V=98Ln;|klL0;N|]0{\^,%R}E ;Ӌ+~4fr+9!*6N@I 1L!e4f 0 R 6qwb1sz8C6|P!@N~oi {ک`}xL"^0ǵPF/x?+Ӄ\8y79Q&|Xq2zv֜Q KZ̐'pPAc+^6J`懿& EAztHOU?|jcFH'x 3d쒮.L_eT V=M㼇c80  0 #п#J9Vުyog[z_]/p\27za~eUHA~6.? 7Vd(&_*S^.{8ʘ4Us7ʕ|x+(W( ;ѸbCW֩$ +jeR+\C)a1mw(8Hn`p.?$1,OgFUQԗFÞ:PgTV%OVCkn_|B4ilpyI mR/P?Rj@{ Jda,8. 䅷|{%)a`^|aXt,(* z° PVCP~p&aa^Uϙ-=_ΪG=Ril.䏉m(aN\φ tz&X lfkq?[;WƖ3 t+2a^[:mnȤwG&z(B!Kœ_c,(ymK`rM噡^5QQbNF*(.e&ӤA-_8G~| on;rqv^&S%}>uSA4h~/@]\8;=/w_QaMfA`~n8fc_&1 MMRlv#g}|EU0oZu!$sSջ%«:^b@ҕ~9oJy0A@*ի4?`bHzʗτA#@rބ|Iy|R*M)]4-^O\fC{͐o>?ޔ=x{ԓ{Q_ C}i'q wr+zpt?Cn /,','uMȆsBׇjiu3Ř%b&"(J/&T-_d 6=Xֶvoæݷ]=:?O@`oL$+W#^'J0U}>d* X>q93aNyB֫zQS$2X _R&u!!Z{eT'(Ia F~Hva1epB`z!Och.WvVfXuuG^_tXvs䠣ۮ3X ZU2g2|_>I 3+^ǘW5%#õMvaa׶FVzc.(}'BɁV #AG*F9am FD U[ 0Ar`9|t}/^BVZ}[/Z~^P4cPX;ȧ ͵+]g ;I ~Qwd6v+$VdCCQ\l:K`@]z#Wʵ͔0g~ip=qmh 0܄-74Mb8[şcȧ.xKsLyq>#1zG; 0oR#T* ] 9Μ0-v}$qo3)|.ȚiWwO ݆+i7 Vft$ =zYJPldލ52.lOrȒ SOws7I>QӮ.燐BސߺTxEJ5p'A|<@|B$r,M+f愛Cf/lEJoN|dRr蔬vmT'RHfӚq sSz"bpM6KJҒ~%igN'mO7R`/E{YÒ^ɁI 5t>U,UfM`>~w`뿇CݶzҊ,b5k"$HòT7dd}_.~35U!7@߸\s+`A 8x0'9H)%$ [80#Y"RvG*YSUzJBam.Wۗ, Ptu2=F[/`}&ɽHy oN/{Lc)ڷRJzJ!i nPȖ._a4J+u1ڲ{9`w1^2p+o#~/j>r|9 "=flVQcWLî 6#VY> 9L6)e'3؋'^?ΦC kWy!StÜ0e7> dպlhh+,YqCFpNVz} )cL8dnx%XK Ct=<_Rt1ylTe˂(knzo!06'-<aLV_?l:Jx,%*ܰoww0aWt9G ##o2v"&U V e w[vt#*`/wѓXߴ  y2@ {{BR sNFrH}bЍ .L6ޢT$:n<i<[K<#<?5|UCgC/}a4aD>H,Z[M0! lDzA̿]Լ=8?@k`vC`2EpSQW"^!^rġdK4w1kA`]΋DCet_+>! 1$Wt ᆲg|$,*zjɴ1kA`z/'sT͆@y~bl4QaV\-܋qFZ{pمX":#܄) 3g_Ҩ6.>邡Ɛ *sy>se $\ v|(ׂB l pr  [CJ.B<iOjyxV ^;EK @L ,=FyЭa 0n6a5.`Ҕgs^'A.ynW)?ܯ+A`Hd[}CSy; 0 p9lA`A`841 0  #0 ǰcA`nG`! A`A` 0  0܎4C<  0 4ÁA`A`φ-[C~y]m:@ wo Atm[A#x+ubp~iaOEh OXoCI6Y1 hE*Du>JToSsHh:`o56> ِWzXhzKܻ6VO$f_@sdqS ) o17ro/ڠ4(ffHKCm3e_x5f _j(3g ц1[P^woYxX[xf TwGR^9{$=Pndv\{ñdƻ0iK(֟nݟqPϋ@e;/ .&y}z3ғiV] +hsugF paY) s o,, g8HQW,e%wg%]J :; <"3J8"}MrS. w #sC/3rv5 ;]D`fܷ 09)YjY">vA#-_ aY!,H[EqD펑?| HA (R>o|&OO 7 044 !`x  {^+oךd+\L2dBxU?|y[ ƫݴt. /_[U>C9cVl\z%&M;jJT% 6#7= ʄS}Wmf}9g ~IOE{K j|> PgU-XId:V]Q^PϘ !dC"ln 0hZn1g۸-@ax=5+2n7$[cѠ(0}1jd Ge3'3F.b9Yd0Д蟩ښhnNÃroF.3o(;M "Vy#lm9pmG*U{Yހ s+ ­jWao^cFw K嗠#nɨd|u=L2v•a6eAn;Sn6ka3Fdopռ #jA`b=}֬wT)6~Y;mL4ęGx. BݼuetEWXU'G\:P4\sW@d+3v=HrXr;}{8x =f4$ֵ#V᯦Ixɲ5`I6^{!6ثT Ct,? &eeIϸ@1R\]vH廁y/K~ %~|#OL8%v ,[2SJn^-l@ :Hip# p(r2Kepvpl5z(\+ -cEfgMZݮK Cb?oc^L6g]<\@a\CuFs2bӤ+:T>/:37UyXWeЀU#=UY1&M*'[dOU@= *_eO6=GwK^dY,Q&L"gr=̳%seJt/`A`A`pZN^G#Yj |M6Gp`"5 `򇰌=bUCKori@{9 =b#= ? B&#2 /@_cG@ O^srӐlM8Hy T_崌W:Ȝ5 wq27^ ol}ӜxGiA%EjJe|ëyS:T&(G\ -C% lr_&VC&K,!=kHz5^-KdQ>KBnUmX~bӧ5nv2C .fC#sl2 F1bgc/$1b5\$dErW@GL#Qfz˹I˙@vߓ-p!S%2s*Z[b9dݥe1Ɵ[4dU/CbKLV{R u%dcR d=G8[B蟩ښ>F /pdWdbI5?bŖm2p ț:0iTwFO-?& mXw%$0QM`fW/Vinm}=G*m‹m=sC8A2Y3lo :"0;(5Da|Dա#39hb{52-B旲Jmڐ^~@ 38~INje iiN*fHb [C>|Vς Mnk.d4s,H-y_ 2ۅðbI S*vmE7 qML]x$(KLlLѺRˆ~YT̖g0Y\dukc8h,a4!F@wۑQVֲ?0E ?>z*]i5Rẗ́]Br g2pV{؀0㬷?$&EluU+6|,GޔgϙL[7:`Y#Ň30Y [s=2?2a3$.-%hnJלּcqweu42+3☺qLa$0A eg=YhL¡~j]&g+:Kl|^~ə[~MB "Mg*>Uma xbp×'GJlacY{89A`A @`(q_|S|wq>"q%s7N"`؃ܜջ(U^͍9WqX&c£j?ev#{f l{J?8$2C*M%]SLLa@Ð%)v I6'J_3Yͨ BXf)mEzhI]z=C~س0nIpeyAWnPd~^ _g2V8s,ej!^fAq8|nOL,HkR:iA"bW2&eeuw ;Ϋ! 4$ά& &z!f4ęsĒʳr/?f lL^1[ȇcP_`IWhbؖb<d2 W`^ C/@6?e%2lʍ2 $7|M)95gSBl2n8 b4DcO2)^!3^[bkQ> |.hd݃]wL~*iI2(' |E𤎕 d6 /ɉ1(tJL ӵ)sYVv0nS0a9J&`4+w  2w ϼd@D79̼}M!Q5.9k獔f3q9דmQ^&3<2FJ9.l ɒfń_ 3tVx1>CjL"_^#' ٙaA(KMÓ$X)ZA,Np&&gp| ;V&GH).<'Cz#M 3N=@&!71AiWq/&$GUØc ٙ}sFOgJv$_7W@So(taK%4!z{mEݹe@̱gi]&;% {Vej Sd=FaxYIg28HA`?(b]:_l#PWXyWwdsg>D>f{y7?m"/xXl[ =R!3GR *  e#԰rRC_M:^JfO4{@5I<9= ٨(a\{X${{Yٮ^Mbou AXx9Rt-.,Uxo5VvKN]=K5~%|xb4v ~hޞzJw$??kY(C2ebnۨ ~ZV[}SMp-,:x*&*O@&b.Q;HÁʪ|)e"ڥM>yXiMb}5cmPDL58򗴌*|YdL6&p_f>|d|z FEێJeyttx==0)^Zuhp&7phu`NJY2US괥e1 M&. hOCet*-*'orE|- g SnB~Lϔ* &jd{8t-w09ZoF䥛OFYK3IdeuUjK8+hi͍r!g +Bycm2}l(٬S5 6)&cgXoa5Ea4ĕ j8dx*OOZLCyae7T>,vWRz&Q+?]z(b{b3aV}OٕEYMf׼0bocb܋_MY[(C=AkvlW"WYPrߛ&dPgq =9Fp!S[tylUռ?hrY/S!ir>aȪLdGƮ-5HMèụWyxy%6[7А%!dRvfW)!uʼ,#mA`tLYÆ=ixCLi]8\2ԓz.[h0{C蓮,rviIgr媏20#g9"͗bKso!_f\Hj2|kI/(/qbߚJEo{Q8>+yz031V'̐5d4d @$\~it-n B'P[D]ݙχ]e_aI4d;ҕ\хWz&p'vH&_Mt=޴xńC@09Y: :ea¿D54_o>LYK'n|iXf]}dg$`(P]GL.PӃ'*v[Cˌ 6F !8*3[2Ӑm)E Ƚ+Fy/kΐt~dN7kgݡ"wL^Yz-,ړ{%mmgbI$I+[,&{]1ڲ?M55ɟ16^8.gWyN8EY8h 5LJ#&T>b4lܠW[`n"S 7X[¿WOZb%al# px1Vz(6T\B*!L..]i H|\y^ &gir$x]R/e,&) 1:$9=ȟS0hFkc֟*Lh:Ro*W~W0Aξg=aD_ [1GhliUw?EmN if4)d2~+ИzP,/J<#Ԫ8ِ|BNCCA\LgrЯ7F(ag ڕ@5K {t fR TY& 7BLh2S#d a*| Yה&E[;C=:+G*c񠟛)hN "-;N彞dI۽;8Dȋn [2o԰ɳmx2嗆v?9mn J{r:2I 5s@_M7(d^2fwP|[JLyV_bӧ6~+Trkh5Jv{>tB]V;[3r>RbɟZD  ^y+X .94&kx/WNiQn/_ y^c9=鋄4YS=tؽjKlȐ6kS_j ;o!X[SB?yGɳjA`6pz*"{Xsn{ξu&cVv0(ܜ?{=yuLi0{{w)!SHà]/O_O|oU>zyXiMb}0:wE`LW e*[~ɾRzC&Dp︿2SlL~/_u,S)OC] ss@,llqXf|{8( FnqEGXMf!0D>I[$65y˽ (zrK&3w[ŴwL`jb@Ò3v @@Cd_rkI$pHc~!Ml ݰ[{hGdyp!cj笗q;ճ dzV,_e+N F&}|ȤJbSpP0Y$'eH|ipYnkG&)9_qXBcMF;T#\\NR^ (EA 1o0Y;1)Kϊ2 l#M$ A6P 8+!&bzyM{U& 5rokD"Z蟩3ǿLp4R. ǭF/0hM+ O{@ʼdBmRb2Xg͗^b' )ؕRY1$5䃊kL6 6-5~˫]X?C|/- MfػeW^%6+ÐKǂ!Vtew`mЃoV{89A`A @`(qѬ4As@BwRj ͧ-/3G{T՜|0T^蔞*}|&Ė7x&Cd ]PH@!h-H噂wLx?:0Q~w!ФʉY L^(_q>knjľdO*Q{#/@m+"2\ȚjVߏ:2֎wC#&`YK䬪,qU/NrJ<%^bbPc ڮ-A|&/SvJHﵒzB z-%HA~z-yIfK'O^U~ñY 5É{&f4r;&-vvM^۫dG ÁށCFlbW걏T>0a^uOd30@vVZ=&ːP.1Y#Lb:KBegClcp w=[@ם${ϗ5 330 C>_=9 0  ".f\o01Gj qT&(FĮ*{cߔ~抗2@y X GRz 4on8zʀlDSZ]O$P̋"Mp)0L&}_] +x:`Hzو"7N"[Vv=·=`/`ՓC%BAX˽ބ'# !a:Aff.$wW3{ob6 Ӑ o0)KkJZ]ƨ4āװDCA?2SשA% )>:k =2*C> ,Vc?դ]md!ѵ\$djfs&RG҇$@K8d̺,GnM6b4gL* lZjp oky P|&J`UHEF4qJ/Pf#Ŀ^o2y6M>U+nJYak>`e@e!$y2 [@_7b <b8f*V19daEG=wWI[Hk9˻2hkVwJ{8v{b>StA}Bx&b4dR+jh>k^4'EVY, >uT>/"W允9Q#E{]QYe?nrΐӜ @Y™_GLD^)x\I{ϗ0̘, $M&=zξlclpʼ,A`==p#1ȃX,]q8;&/R 7ihvK^p3֡W]Aj DزƠUSPeCuR5Qx~eWΤ._{]ׁez cց}% cp;W^>>z)-ن# 8<)kÑ!s ;sXb!|Ԛ4V `gܑ\* ˧R> _D<3 IΗ%8'1h19 >n Z80''S6v _X0Y"ciF`KPjmxK|)%g{ʗeU ʇB-s"*cIl?3@.>qe3׾T?X{|Ra~zR3 +-3ymMZoϳ=o<Z ޮt=*rZ]z߳Wz{i\L^[u#gTsɚl^ $?3Kz 5oxG*ULf4SQKO K"_^y.`e׵'dP&rժ UGL&UOl"̇¨6m^04q-~/!CFCB^(db BiЀex3  0 p14ô<$lu叏K6-Wbn?NI0z{ZCaL.3$|@]}0̟XM$A9~_\/a6Zv{D? C^*~)ZCsW*&\ݵĐD4boIe}ɡ+Pi`E“/-@`FL\︿A5bfGK&>5a3JA-8PK6FyܸgaXPc)ͺit}8锩W&]8yuM[|rȬ&2e4Pv 4* &9zW=KK.I}W} yaW$|e!01bu uel3!$E4t8xF L{Wb?LoЕ_x#90aӲV-bJDe5rk?hDY+4Bd+{X#[&T =W);2_=nrX.\+ȫtm/!f)I$1\YX޲"S5t&{84[<> ҫv(v2٤+VVn{U䴬:+PK(d05փY2T/̹x.#걏T>aZװ-BQ'0=LU>_b\ ʓ ЄI"ڄ5,o&}V{89A`A @ Á{'}a!BI1L!}@a ҕ yvh<oު[brCCɆ\(zK#SGqe2aЫG 0DeBjb8&K& =Ca7n}*&^$FE 92LI˥+ALiX[uP䞆7)sdw [~:eZRbffva%=fbLA*\ľ/`WLHATv2yLR+_KLН>-dP װm{(֊QmeBKk9gꚭӟ4֚(Qf&0,feƥ.cu/\݄my9_8Cz*{*2]A/_@ ӗO˒e^v%8G&k7Ţ9KlYB=.#r>CD}{8pHdv9Bƒirxˆ2!Ň6H' ChOR5BfE޴a٥9^"yRAn[sxxM36Pb&>Ri&ZI/_6S/k,6aWϯyf[#vqٚO]eԥwK[&qaoYM)12?ODGS@vR?H7Ct#*=puO:hР㗄j_f2gfh0C!_e!P~Lhv^x6 0H/r띫.@: Lj}CyKlHoy^Eq'=1[ތaXSΚp4@% 0  ׿ckqDu)O0kn\rC y [dWYc|Ko. P wU x/.`r~en]3k=$d둕Nz(> Jm5msJF8o2w(w*l :kn@,,gWo rWིjyW垞7)sd׿cp@2))E]2.&KA(}Nd<, r S2Cbph{؀ ddO+5tMWO5}2~C^D{g<4f>Pn/. 9[0գه9 §C%z 6׃/ȌMnd%eCyz|Ib3j0z,"QFϓ2&G$pdDB3, $tfi'f\O3 o JDmz%pfd:S 2uV=] ÖL֙ݛ&|H]b2/7avLT^ #D)2fv`Wyaŭ=_ hm%WEw!h~{84mr#~2K&|LKzӆY5[6m&wo;>Y,gZR:}Pjb|T aL~ܠ,M'0=_; ^kaFH/gv=G6% Z fqx$n8|U.WRFsae=y)$G 0  0|{8Lަz*;Mq}FX]z'?hr'WW#$O5^.s %d솶7mhrj׼#|䟪2O*sU =?1铲<7odӛ?T֡zm{?hr/v(XfRpMb{YЦ|*,%CJZzQq.Lꡲ0m@l+ M.i`bO: 2CzP=pRo56Y0 b @EIxb=dқ!EU!@l69L-Uv!`GmH#hɺz@u&ο_/`r6^U'-M'+$=IPPNAZ6Caf аpFC=[WO [Yͬ P9 4&\,R$$ɺf1$%d!fN ض{]Ms\Izj58kYiPX]SٹU'jVim~+P V4d>gih3g"__l+}0}ծfgrx%~3ÅKx@?hr)oU3&o /akJ^"%sT&3MoyFcQ7ei΋ÑYC+s:eUL3*vTto[<<5,2QVh0B^^iL'+w5hS:wwj 7pB᮱2?K V#[phf߯YbcްY\̮T$LaUxXEϥ*}֮M% Gef6_|1 CdK4*Y/+"Zv3K8{YgT`*3%^aIpP^a4zjUoyYL|n`IYN1hSvxE`c1 xg+W;`w504sz|yg,=r&ŭ ]oi+þ4kg >CYpŲmkXz&Dtkۨp.}K!<xѴY_eB]Էt889#nBA|J@[7^?Z`FV5,xWD 5\Gs<`%9Fd{K4 Pa2Ц1ؐ!m֎ 5k {%xA`A`py'OEd+ֲ<}F o@z"'j6UCJ3}gd|=nmr3r|e|P?TxiMb}kDcXt~Ca$nr Ꮫl\  d!v|C篵jd+~UQ )1iקɼ'xMb}ᐆ {9h,drt=j2H+o {k߀2Fud>vҘ<'*wi"3o iB V]|KҌ:k&<_o12e-;χdnp2ɂC Č25@fްw7@>GL&t2s7fțVv8!L6pV buz,lM4w,^Tsv (\wgyWs̸'W"k]$oK˙f27TCc˨^_^I:ǖ8>Axtk9Gt/k?_Ͷ[;nB&j䛐:87۔̟29T8Ls|+m_uW]yYgPs_jw.糏T{@7d ުEПI2G՗s_`rW>[3qJ_5ػQʘfBibDI Gue ԩ.>̱ P_:ɛ 6@e!S>$_|N0 i 0  G w]l= ǟ< c4_g2/eY±>nL|2`i4* &7"2KkYv 0$n?[?_wmGvaٟm M g2rLL>hPY2~rf&T^ ^O}]SqB'[,PܽōL3YqLp"jsȰj!m<~,tW!OŚ6RÄ' izgJ/ z]Jcy\플SBV넵%n/_,p{Me 3|{ϗ0d愆&kK;ӝ SpH? %I $e-PTM 5"څgW>'b[Zoȓ]!d>l˼[1xd2(Rt-~ӛZwpwyAWT0A$ދfG7gny3Nyf p+5^/4,MNX֊Cd29ֲVo5$m2 JZ+ ;jWCofd@H;dUf(\aa|w98'f5$01UɞY煐=_s({ɐw>~6%3ǜ]!p%?+v4̲4Lƻ,n塺be"@z2~_epl_f0uj;݆&=X_eM6z-UYY(;Y*~HUQ{ ^zYcz$y&+M3=_[_W[s|.;+ZZgӳKP&)ѧz[X= f 0  0!` q5 {Jz{bm{=\^b j/MVWMi(ۋ0I >&%K-@7%wc׼O%LR;W=S)f*ROl\ ¡iA,I6cXUFnr <I7J2n4h!IP]W[ 4&7p|h,zM ,.J҄ ^{ɪ]' *pFjCJ T>let# ~ׇL?fTVLUBa/"\_zjd =9p!:M?v{ 6Au}M| >3TzOqLiMf`re )Wr.ff4lt4m.1A- &! Sn֒4-VEȇ&!e07z# @4JrzHudP W.-a]Zh*u >/o1q%0g.JguE$D!!LF΃*C/8G2w3TۘlzB-gZU|ƯyYQ5.?;RLUM~w+[58HA`xGy0 fj=ltE`y@?ኆ1ٜs3C]0ܫefۍRn,3|3slo|`Kɥ(P/xP3&J@sۋ?K@Gtڍɾ:Tn !9k$kRr ^)=5U(M. '$̑Ue*#ph ,0[(Pfm3!?hr^쯐B࣯N) 2y'|eM_Dt *wG0Cz֐VC/jl џ҇w'f/md".cu/\Y>1l, g+"S1 UZ"4y7zKrw%l8=˦fY]Z (}+.[!>s !ɡQ֎e52dteBnPY($G1}>mRRW9: ?XaC _W2E&0 il-?5Y k9蜩5^R:uiXpL,~R@lOy]LIl}crdmzU5 d+ߟLJ@vRߟ:ڄ0n s!4^~-s\7^#E(c1u}0 hk"ϴB&`H^ +'BAC&^ & *%S>,kJ_hdA`p4悳%zPy3gR`x8#i/!<\l@$Vv=޷!yC\~zsV(XL5i˫p A}E1UPg"ˆ\5lCz?˽\}^axӪ2{&$̑U_#(x!!TG1j;&K/!``Z{bwDgʛTzJl v}4${ȴ4"+P$|Ү>f ѵ|$U,#w=_/-7 XB;lW~ 4QJv*7s*ELn$6ԏa:B :2n ?NlpԛlX=3gFИĊ8a (mY(+7Y iINy=2) \;IdEZFRC2& $髇'34mm@ INT_p kiLO 'HDX.3gA/-)F&=]%KG*m{}1cUCl>!VUI1v!8U$3&yl A^-o@}x!(70ӰE>fʇy{8| 0 E;áO4=bR6XN؛326 ߻h4d [(8c^>>cV_I_ {mlؒ/x)Yj!TZ}~įz(7-y2B5 %Oɾ98omiCe\fve Y$7eiw0w-ï%KiѲ.ؚM>@!OX *ٛJ>˥κg&˜?e%I>|s/zhW e135S׵ 4"?'fk iKoGz݆+|>KB,'CI-:x@uXi rw M%< v@1lW;,RWVy`7Pv`חf аWZ l7l'K|wY(g@/R'Auͺ+2ݹVPnĢ2UN/zYO z+Vcɦw P ͳ>>r!VkwC6FBPt),w;4M6 wU" xnx113.?oFl 矴Jwʮڥ+8]{I|Hex>կOB ꭱɲįj-pH'? aPe`w>P`|rծ:){34k !beA7xYb~ɦ̓-$=5a7.9 ĢsY4UzVÐL=eU_E S{H1amM(6+<2|V1A1 Cu͏+?䍷qɒtved0r!9^3 !mXzt&Bݵ3૬]H,f(XwQpWC8,VC w1YI/`>2߱ dN)cK B(Yo4XC6Jɔ7_p&36A`A`/xGwn5XF+-FÁocq0ljs=5@|N.ً pNadtzi!@C649 ñL=_R|Gte^;4ʓzjIכLa r'5Ҿ=F&<^밤NHxWeqS|o6٨r 1s^|O]erU:d}$!m{Gd |ɎAg]:tF,"uEL= azpr߭.lks~י\*@ް?Uhm`o(sfj>&6E FCGEvձW^ Ь!ȑV~@ Jr 4;2oL&is[ط*ë49oWvtˬix<@R,u=\Hz?R?0ån8%C(V{6^rSv5 yd#t)uQjd_y)ߴ[="N[*TU>#h}q$]dd-W6=m\'lqcG )e0f6v TA¬'M #h!6d6X@bV}t hCQ>JUu*xVy B v][0zWt )0L˙: U2z;:` EV%psD  0 @G* 0  0  p0(͜A`A`4Ń 0  0 A`KLq Y<  0  p0(͜A`A`4Ń 0  0 A`K7Ƒ/,>%ju\ 094ʄ]~Փ:_}j|5{p:`ߟ=ޯKf5G(&/-W1!ڃ7żW7vfA_^1 ?0e68װmYKE.} *kG0^D/<2o7دa+6(F_e: _л&J=m05 d#ɃCL s. !Q@a>GA8`5C/oqcKCF̜x[<K7&Ke F6:bccaF^C Z~d [ҕ%IpB$`|mf+~@2$Dѳ9J[%wŠi>\Mg|iTZM p/KeJ <.JW-Vc1rT<2BBAp,0^&Wb@m5&2z>D„qY3ol89@d׃&McoC?YP}^fWZ>sʃAQ̪sq\ rN]ً^ޘA,w8zfOfJo* B2P et#K(=x|q5 ,MjVsFl;o 3e-v H>W ѿ̆+,mNu~UybnP*(x'FssM-Ŋ X 7x ^€,dN*#!6X3DF%$~i,*aNC+6V"c |5̀f !#K7( G ښW(aR1A]^y=ݽ%L*Y4]TDTQn!aϒa򹑔0(0$8* SPTVb:xieן>|W2,J[J[@5H-|m*^Bt1 sn[̙pd*e"mdF`?oU>o]aJ: l!0O;)]>M0{ii3\ږ22=ɽe eo,%>90XTǾ&3+K]^Cj+* K­J7ynby%fk kMxbLsZGx9=z|5nl8{KАս>jK/A3pJE+YG>ꔿj5w}\sӫ Jx06V@3*p%02ׁIAݤ@t|w^*&#TNzZ&a°o]"udP{c( d^<^e\#{`)#%sJF ,R&=e+_ YHF(v?zS׸@b兇t_&ç,gRdF(r 4g*F^Yb\I`gu-^蚍NHˆM<$ i$43s%ɖ>}f%L3"`~Xj0؍R -jxÁ`UQ˨SX/4ث4O@a\IRtW[d Y!O;T2ytEڐκ`Mm8F>ySHe"f^iZhVD/,q) awi*ƛn m'ދw I$FԾzf_l⡸8&/j5߉@;c+D3IOlWy]u+A^0Eڨhң&Y G5 > ʐČ«h] (F^0$9#jl44:}L6 #)ACQIENDB`n `e)6ᾢ{dPNG  IHDR00` PLTEo!31H^#!<--,MK蔎SQ85S% w"+(e !k30102.lZY* t"+)WXX!##kONZQQ?<=4+'贮uuug^&"=:0 .+‘223KG$"96j UUU'&\<<\ZLq!BA{zzusCCC i/-srrMJ555zGWQ`bba0._%#+++CAvkTR1-j~|PPO30ࢡ63GFF+' &%1/}#"E?us665E0041)&abyo/ / y#!x# x! IE?l E4/20"!C@LJSPdcDCCBA2/~&"UNmkrgpHG5096"%$PMkkppp{uz$!-+LLdZ33jjj# " 31<8309%#0-]```''(v ZZZ拄u 63h0,.+JJJ0/t$!q)(41EDEBBBd@@@1.&#=>=W63m)&-+TS'&ƿ`$#.,w! ,*,( )&ϧ/.@=$"/,-,?. %H NgfbhUQɈ"!l%:]{sƋDuWc+ #5qS)e?˕F9OE$5_U+5Q(ǽ _5|CUdb8X D)f5W-Zß[V7mxt/B PkqHYpNecE:==Sݟ.h۴!|3Sb'II;ZHܥIM#I$FD` x cC[lux77ŋ>$Qѣ,Ujt#+NO-?e'j{pVJ>jy-[L}|*{&Obmi 13GcݸK2D+p0K4IQCĸiyC[3!4I4e('$Y@ai>rKiCD{t!ؓ!"I}ky$yySpd)-m-ulL~?_UUCwygZb *9w+%>1\~~]l=5ϫ[FLp>k^e[{ai_\Kj셲|:}{^crʇ˅5$:2d̍C琴ѓ0ƿd(9 Da0 9 fߦ^xQab }Y^~DV$]ׁcd矼p|XTCCzw 8(^@%s+ͶXSԽȱ41j;3$f'ԙov̍Z SM) J[X81=gCF IENDB`@= ;@=Mo-,Sl7C}TX x[}lT?sw[>,U*[*"DyOZ) ibEW%} cE1~D`;gtmN=ss3sf  i*!,\w^ Pݴ|/`\,&~yBp R5Xxː}Ubeg%0᪒2و҉%2yu<IȤ <嫯Y YTBi NOBqT[/e6K^ISjV=a<݋ꘌG [٤~:_ZJ `S(9NunV%zM|D+=*gԦҍϟ%rn@ΔA'c*(U!ez{gK_MJ 家c寧bp PZotĥBֽtO#{V.T}eGSyp"9ӽbGP]>GvhvHqÃGr@Tv8Iݟ$U .2+g&T[ai[:> s7m\۾aYֺ6CH=U([辦bp'XX|S|2IlAg$( #'2%'I"7 z1!H\{"޿D\u݈xDze9 W4ƚ3)neSJuf5:=o4'/ |>HI]ZݙtTt;%@'w 39͛׿Bj!>Em߇tDr*CwO:_gK ~?hwh^o5[ J ~ȶ7CSAlou@ MŔ%D}*C5(,`3xa6+;c-5.ף!+53zNŌH( dcn|2(i@*q*ʹٹBI1Ӂ'i!$ 0ӏ,~/vIM W fwSFIbʦQοyXM(R9vǃlCvqJQ>l#>m8:(?vmh.y~i7ϷodڶcKڍN#9DR﷣1*k:8ߤlk}aS?e ~/5փFjW?.!5_.'=lQ+r"_bK\!l'=d=ݾ#\ۼ g-k[PǑEH+{?-f Pz" ޭ~ u7p'w?]QAyW 1mBEma5X%|pgB}nls0~~wWyrBrHg_sR'qk@ '/ K|aV̶^o / Kt1Js;}`C_qa 1_pw+f[W[a"/j 1=d{_(^/dޞv瓴gC4O? =m CV V}Bǟ1ao2x]0ƍh]IdN{6~~ :'_[E>_']0{ H!niG?_<_z2~$brc׸ڋnśa{0C;l6ƿb?Ab't&\a?+egD]vMyFR-DO%YrCЍ4ӲyʗA&xȐ2fh@R,{TJA^:t[(_ŋzCgl-p7חs*l{1}٭%+-G_88v Y iylE}z|o1Bߓκ6\ϸBrN$:\|Q+N+PVesHUD;b\DFER虫̕Å}r'Hr'W~_,﹝Q)*7̨8 wUM2^[o.F'ikϦlZ;k?,vn)h'U(6ANƤPNG  IHDR_ PLTE->tRNS@f IDATxێ㸲m p^$NgwUe-tHƍn~7C^! ?ox7C^! ?ox7C^! _M3|6fr!O;/ɱPn /HP/+)'?_1RoH AHϽx 9?_ !eEC/@?c |E/@GH#?#l#B6#!ɷ/)vq?;9+ H>!|{F4Bjo. 'A}sF4ox:ߛ? V70y rz[&#p*\ȠF=#|G~A߫gYiW ֟E|=?E]"| /\#| ?P-ZnQX? ?PnQ_!| ?МWuߍQ7$Bl?ȫ| ?nnI?F~^ | ?OSodDz~zsCS_98(>\9VꆟC{!k _ |!W !?ۏ~!W?0+d++_"WF Swwc}nB|nB ?pLY!!o_#1g^OB8G/' &G/'ˑ3GF n«3r3W# ŧ~<$>Dx~! HB؏ )jANp-V-@xz#\@xj# RS?G2~Ao|p5F JixKsJ9\X-`, ĹGBNOKkp 9e)# {r[˻:T" g_DʄJ?¼JA_r~2xp@xkn!pwAg_f 4+.n0GTie:?+Z1do-w. ]=_`#oD@V7wj^[-76IK~+~3+mT"!ĂQǤ!l͊z>Ai*6)?dNvVCHXxxb񾥍qwU.XYr~9P}E[sG3jE ;fD䣷"DzՊr>)|JN(fJ9V>~/B{rq-$hF3I"m+Q$+FW*^1 O=3)L{A#^[e{ΊF$^1ݱU*j4>$O# $c,DE`{L!ؼH}{+fR!$[ᎌ߀`S EqTrG C[z؄AM !]J9!ҽ 6]HNވߎ`kZw!6oc@| חtv6a yADx-~+BltID#f"!I1sG2i aZ~oEXkG4uj *1J֟Ahg֬A@&*Q$0#X}zG6m~#BpvK>Q)zbDErm !V]C(}`ڨ* x~ @tIE0:qn.jg9 PEщR_>`-vR؈\]_:"T-Ca5-XJﺝtӢ ޥu"|GW!P!CDp?)BK{Ծ'}uLxZ T#RA.~w!/m& (߂kk&RR?b-=TRG/UONі_^5Z=桉7zP =T[]Ć8̈v !Uَfuk_#I[M8ߎn!<~"n=뤺zGFc oIB_,& $ T+_~1!pRx!G_08ThO%543ibǯʟ@8T쫢ߢj@Bm(0!WwR1ZC'0Z` "PljZ2K?p脚;L&Fhz..vM#z~) -?u=働LUY ! Ibc :t._Vn`r pdח#& W";^Z{}h !FʖEiߍpnzPREXzĢ v>zd^)X/H@H/uۯC8wp iftϱ9aknwpWE(bƎ _;a0Q5sܮbibrIR^So O zeC'z</9!lv"mboD;A\Wu fߎBжJ^w#YV$jqpa97j ُ!z]!^5sBO A {!˴I,hS" H;G! IfAu6E]AuJ=;j!:,>pkY xB,HZIJׯA袳9z 7v_)*]Bo; ڳ;F~K(5F@l've$ zpk~0y^_#pMo\Q8"Mƨq:"/N igI.D] nO W_]| VC/O6AN0ZV-Lpj&%zK7y|u )ͅ#I<ꅷJ-rˊP~C6(WNAP7+O1ܬ/*2xʏ 2>,A49˓ o3\K-D`o7 DLpӸdC8N1<ĥaC6۸:T{Sô>DC¢yvMI$dT;4%Q;lPv-(! =`Ħǐ̋{^W[`sLlDqO'B(,Un:/{"A7!߃`5mup=;i0I;ݴv_._tʉ/npIKkM1S1 j-^k=| !Z66}rFHT78OzFd3xVsP8T73_jly""[n=. aMY^'W| PQ>-=؇"D}]tP@qэD-3~;Ҽ3Gר!ra-@FniCFXɓg7im-(f/H&ѵ_j\M ,$"d_SbbWw7 !.ۮی&B8uMiPފ=8 E3qu@x=?BU aT=05Z uI~Av[<: Xl!-s)8 (†ą08p}=/,NT;X6Ar J6"`ŶMG% ˀ:At{ܿBhtő$U0Zezϼ2(M 6sKPb-/'戰zuPاӗ6s~Ms1ʅ&= QXǸĆ0_:Bxm:`6݄STJkxg9 ^oF}J'N*|nQ;He4Α;=5,2 2d^Mp gG8eINHN#jn„C( FbomwFeut8sd!r%BFe!<9ې)j1kPrP "DE`ۤ*zRG[\{2|oUw ͊rs(3QE [vX}@pīBquPZ)Ah^XnfF9G-R|'6W؁08(tL!a~-CM9mIn/,5:{F_bM©#o+x:g<%*!Jn;‹5d BM!enTbG!$9":ø4*shdO)G{Eu?@‹5jq9%ľd-eѶCF)A2TAD ~W.Cޙt1{Oi*ɞqa)0O̅!z>\}\Zl1#fէx0'< dH[g5^O/%fuiאLCHef4@7;cU8!:\,O:B_ :cF|GH6\: 9=~XNy1BHRzpZvFH 2SsVl{uro a1 ,Ď"wf?"Ċov_j>)^"xoA!VFAc?@Fh<"6f P7N@-*F-s!ZVnRs\g{ ቔ&5E 1F`N3#Gg;o!$ݮ{bF V һA %ZhP4 cDXBMuרow8Qr6F<܉qkkGj0N>R5A 6*X4)Ebw=DCР~ F\s2Op3g$Zq,ea.W5 O Ad++>ڒ<}XIٜE0@sZ"0L nSďZ 2юَ z6&:ƽFg=m2|fsE#O8=a3Í+ÔLfOm!}2\v W >Dgό~DCdBQ+k%0L,ZmAO}Ѧ'"wX"nT *pj> *4:`ko~DCY;a i鮏!0E;dG-װ戀Smߣk~YTLP-"FC`ԣ"=h_ .KG=-nOp0jDKCPA˔ה,` En 9Ս9.]$fx["`Jc` ^Y$Cy8/#pbK`Y*-E@7V&%yߓREHv56{mmf*4at倰u7k,m2?AHي<#7PfL=F!٩6DTT ݖaoR="Uv4P}a#+Ԟ^&Ŧr& B|@K"AjLTwL ߀.掰[n$`!e8 A+y@pGG v4RG@^*. >lNE q}?u| IDAT3rnjz}U35[nWF6>Ff7[juG4|ոߑg3(I߉נڮG"5IU!Qܖ[06uܞbhC=UWMEks\f~wwD0E/ѿvRu=MKwa"YzC0w^iL^QɆ`7R;.hL$!,byom2EK UMb-[7=8UFhqr9ø|@A>D<ܕsEpcZQb8WvLm&*MaPӒ&ç񈐎5/: < 916qΕ}EXNh'R7ڙu2<"@B a[1OsWj%w iy|Cl4+w>V$^!$F殜 lkwHuTi#RdG-@h$^!DF~+'.0|5;Fލ^K07n!3M pTSa|l mggC}5>5Ci;_uS!$?^5X3>V6Nn\: P/l QMm@XQN"g̯=yD貢F]64<1minDhx`}~I/8u.0>ۊPl!@(R/0BCTWkHuA^S'3>9SEEHtϻX3mȘ}>E >.Gi@-0<dΓ!! \)T6|Pmݑ+c7HUGFhJd>#vz3t"+/"T!.>"Ȕj/G6"%8KG@ 6 ۳|h8!Y  }J3|~][zsE7K tޏZ",=?ޏ:>CHoW,g a4)B6"^w` !a?"hp3@89ܧ|&H;Vo#xE5]wrD#P Zh֓RyFa q~DX*W͂Om> ful5z=UݬF&tībEeK3&CklP*vX#? *a/R5Z_kACˊp脊FMR-QEy@G$"'c B<#8pBSa!7MPJ |dBVǗpI'zymTRr@P DKuq9#j}@$#3$6, i'D`+Jb@ 9"@ -4.|ӗ&. +QͧPݪ/$$FJK.&lsEZ R7ss'wpTgBJ(>k+T~!sgmWXGKՔzh_̇ v0@G,TBj1'PzKGG#M8Ҳt.b}A^J_;_!!]XT';0➧eQRTBPLgn0rTmB'UW~{T9([6on.h)h+d=go.]#1Zl1QJPL)eP#2C-x_D(W-aWiR.h L>J$e_(~}Bs%Vr Ȁ$k5T4Bj..KbU$uqcRu#rS f@jT.N冀4%R:Czl!8o=G !YL"0Ôr] J4AI: 9 wm@Ȯ#aEhDbE UE;]rl DWm[wɳlY0haV!` E# 5 {F(@[NZE{xB.\E[3Պ `Dw4EF:ŒIp~kڹFf_DX!ޣ+‹b 9R!2=*H@HZ}D6BI|ŢgoZ5zIJ0r.an H;r[ A@gBr@``Ӝ8 D7ik50aS נ$B锂:'{UA+BIokʕXV񆭨{"yw~DPB$ z5S4æ' TTά"Ig]`9R %'bcmvF.!VvM`G)Qa0;)NeĨFա!ڷYdSGXG" uvk;>i ;[wkQw6KD8C𘊪GQFjGjG0ܜyٵD@BQ@Lֆ[GI1p^ 2hBha=eP!jDxJ0Gp6<7EءBE 94Ipw~s5zidK"]&d2f&¶#Z>>a#:KRTS^<#&H 'ǮQٺD`(;Mv:!lv/B1Ɇw1"/JV '˴!Ɋ0j# \b1N"̉pK]8B4DͽT* sAN A#Bڋ+1 h^t!\! >¤ղm"#XGKaSx(-=ؓEQbGX)YT!i/,&S!*K:.mW々\\{^3V(P?|uŒ#wycKahW͊j.3KJ/k]z|zQ|EJI'i<+DT}BK]lO]Cˎjv[f+,/f\c) ¸q{ ' aɊuWkzEM xl6:c%<7՝*!i4ExĴߴRahACW6>_{<zti*ڢ*+4 SD:i #LG1"7#nݿ@XXl&Li_ѡʺsJeWV@% nGVI,mNPCp@!?C[l1ouM0E{V|E g{ي4 0vX[ns34TmBQ :϶[̊Qhnu4sPm<щ! gB,rBe):0xP ׎E΍&ϓ,܄x[;M2(W_wn_=NAD1ڵ}' [C0ɣ8ф*WyENvOe.x" S@]L=Bh!pg5Aj,*C%7BbCH^RT} H:B Q߱G] Hq2!qM5Y 灖 ͥ腂PtnNЇ9z?^ : ޒ3lG*"IEX`WRGǴJc=wP7&  W /|K  ݄ɲybrA܈aŠSFH5w\-R5 , xd%DCqvgEZ>;x:6BHT3)5 )/|A\+SE^"\#tCX1Ȋ$/!vLu8 Ac FP˂GCv[´!`TL0>2^ݾ.ov7|D#B\R?Bs>]V1M*0ʜ';R>aCܐŒz jA)g\7޵"h*8#Eo ʧW7#:?AE9<#瀠u2[D QI"eչw{C(þ\Ф(.^{QK{8Rs.Db2ˉV-$KX&LFX:Bѽ xee,Ru?TD n#! C+,#7aRUr/g*0MWsCHO^pWYu -" /5 ,Z-ۿDhj CT'PӃj/w`ny\" xϒKG;Z%e_ŽG"@]ߌQlRG !Bf?# NmXW H0wK>"\xD'# P3ʭ E봫@^nBdF@9Y,U61k[BBX#ƪ 6aCyp"jAE憰Uv /!XIP:([NA Bso.(pjEXfC U_-j#}*>&+v.W< hAPEvZXEuERVTZoZS}`R~FټS< `E1 C@VܶP7YxKG 1^ ̞Gn|1uA=#,6gy2?Ԕ۽4EM aWX.{E#g> <"BTRl6JJa2O;D($Ҝ`eay6+O {E`BmoZ !YX tDࢺ0Ew׀IaD/Xtj6 m"HTm-2\B ߣLZaiOb0'A21Lɷ4(JGVL]zîF*]HD=Q/l:El@%mIn{B0Uk j=d jB|HLWD#jVS]I/~r6.D݋jʃ*Bʆ GGx]'n S7̵y@({?њ^#"5B6lh4'6C9ZH̋abu4EͶx3:6 b69.bC%tҵs"zoEHwE`k_#@vm5BBbE) `xN`;pAP-n|B(M qD`^t5_ L$r)j5{6G8}C!_Q< "#'65F\XVhiW*#:R@VsE)u!P,܀ K~D}!['nG =7+*B\OOX;x!mgڝaV>F1g'dYݡ#!aSA Oz [E` _CT4z»PTJ-~< aRK5[EB*`<`R9"Ea!B/ !<QͨkoPx~1!#bXcl5AOcCg)Y/{G:(B<"0jIhe[$vTqo"Vki@HrD3 n#'v@[ ՗hEU<Y4jM,u}@( ~y*nFH;!Gn Z/gR6P6閶;e`1Z۲"`q dug͎mE8]m6ZV O{F a{["g<#@sEYKa{c89Fb퀠HV؉ja@1|+Kދ(8,34hTAÚ5]fE j+~9 hܞz0)C7.HL IDATHW dVfjy= OBIw̙+0"&qMyB p%<CֹyJW,]57;#NFuMv ~.kmjGu؎+ !BucsvDvՐ,>"DEeP.&VO{wP#HE cFA@[;l'(Pr S3ټU4˭s%gdj*{&sV!®V;7&mDIܜC+{iWAX"OqIwQM]@_ 73*[:"[nIjQnĈ!`E7:Bb='W"!ܰ=~ %u OLrOjA"π` 6bD]gU+1JyBBDP[U rP (a  x ¶UN2RnU1l# iY@FƊ3BvSm ^6fB>"DY. A=f  !=>!*t٠"ܫ\ϕv ;L(<:B(L@8ϻe h9[ lZR!l#+H !B4NQ g(’za[=%f;!~ w%'twazHM:""HGH"PDq"!=!E΂g6Ŧv߽dhQ K?{jJ1p8yiBѶ)E\2ZwDH\o4`+B0[*3l)\KX:C="B,g5忨 Pޏ oՑhO6u/vL :w51DHɴk&3\.[^1vͬ5GSD@ba-3"x@y@@e\k\ϼmIO2 lv76)pߌ0奎X$l3진T!,jkb LgC0X~ #BV?<"س̨zs `'8TcRq܋S)M r뽰[Y+9kf8!76X 0yԑbحP~'GFۊ0ER0pG꿮MeupZnWމmwyŀv=u%L+ڕv,2s+E.sg44C)w*Ey6QLZdq#Ѝ] ;c:d@X&ˬ|[x+_v8[~ 9촘ʯʭ<8瑶\qPΞ&Ugp >ίͪdT ZGABf,JX= <x7ŝ6 5yǸr/=/2q+grigP/}g[F:*sl{\|<- 0R`\^<zܩtYOf9 QTlsW'k+h9[1ER۾ qqTo]Vd ؛VW0$L˄?^G#,8%G˚DՆ-X# 5l,I #Y4΂hxWd9pL;?P9̇ BGO")>u!06꺄P7HvךAt?"l"4m"O2#q5]h4"W(5 Uޖu# y2g I(!FXӬK~Y*jE!rpÍxD7AWvu-Bf$7:Q"l4B.,\=mhE~NJPFQp1[sDL,D-,zB@E;.hTbv&R> }5`k8 [8 )CAf;ye (S4׃D+'h|DXxB >bC ]phb`)qT;MPiɨ{5>渿DPዂ !"T` aH6qB虭"B}( KUvjBQj7h=#Ô(~C1w' ҝz!HW$nc پr-!]5Ӯ=k.~o;UcoXDŊ@7 j5%6STwn`EzRǎB}N)+0'-Ǒ8URw`tB2agވdCp9!uai`k+-~OHþe OoDXL!hL)BR"3B {4vfya_o1^,BdwEަID! 'D(ϼ"x&#B"@E-ۆXcv z@!Y"Qk6ouQK}hiXqt gˌ% &UR+-7hWKE5B^QP"3 iF"E+ϋR qu]*5&Sk4:¾IDH[uJcRO)!B\!a9ÄxTS^"l a$UJW5? xk~E΄[twVz"V*RCL]NХ*aCv R\97|B3Ew˼hzͪ`uAHrWM=>uX,&LBl?Ek! qy*@ñ0#m!~ 9ۼ6?d a3Ϡ D!Ԁe !;;?GGB? .d2b,M)G ڒt q- q@6CXW;B- |n)J }^|!j"9.'BE+b5#̧*҈SlumG2$4 $7`achWyDHU-ԃHjyKyIQGla6SڤRcؚ~Uq0t D"#[ "ȬC0fl.<[,=n4[bn"dYa'IbF1T"ԤkD6ѳ¢ոT<[AdšjXh!S=T! 6lkZdH7ʖRS#؉!#x3b `Xma%t%RoGͰac:"DZΉ ! 0-5#'"xEhnSx`ڪpFzGкhC=AuXǶ+n")*`CÛlάI 4Z^p@Z #}i#w91 = !Fb"uT Q7/~YKem:#ZC PB09k괤>hm@ۜ ԨҚUFaB!~|("lAǴ;"`":\ƪ/Ԧ'ZKR:Jb`RbQ{fs 4&*<,I VZvŦ;CJꦄSh * $5WC_#  <6Z(c~mO+5 !~ Ʈ!x Ԑ-E6| H4L£u*޿q48ERP\5:B!U_ 09"<nP3K/WjG. ^ ̜ᑇU;BrV@)8aajuVV.%?KP7!#24!xPBC !%( 3 BgĂ?iET<.8Em7kaA.r6T-CIG=G"bܵSs;s 1$H\ITBވY ۱іL"bs@yM`!jѼ3REo AZn턬 Yq@H079j 1m@@g v@`ү̙Ӑݒ uDUٱJЊov%tMO/FPv`ֲi !m3+Sڐ*'9-_ !PX^/\j!u&aߵȀPj-Rmu=&†ў-,(k>z:^8 P^}5фST^K@[-CX `4vi A(*&UhFK@"6ia5S& Sǚ/x"0 qlo{i[GK \1f@@ ڪ*FV4*\44U(!WFjATArqA`skw7Z% u !V*Rww+Âaϱ!_! 0nB"(͆Ʈl^|3xB׺k(K2 ikS6!0v,-P#\ kq!KgTmr0IM2Lt,yNi13'pkELy \i^tbCp/"3 `?Ee lKz{5#̼\BDPN" ĥ#q;B#jtizG=c" {.GEPF΁y>Mdq|5:"@S{~U'w#-y2ȀD8#"8iDhAF&^kap4zq6fVx@p[Eg. ֘TPv~5 9~ͪp6hLa~wՄABEPnLCQmb޽yǧ]y¤@yOnᴎ!fnnkaNғ"u3GϠi 7 ^f=^g o DsfB! [zLÔ4\ w(BuXQ "xZ ݔ?AK aG/RosZ:pb?~Ey&gy"o3 gACp+sH`aY߿@(0Exl:#ʃ5C@- !…mtGd~!!~!kXÂ畧F5ExmRDŗBUhϊDUhM;|E]DpOtS,qBmhDBU]tBʭZ=u,C? 3&Fnj|x5U'Bs}+T)ϝ. Z [bAG@7m kd">%zC# CHya&9S'dk( Ubहia߬Њpa ]#Xfe{EDsɏ4yn׎ ϝP8Dn[K@Ga1WDa9d,_Z] Wي@S 8",-m5MAc#@1!4W"Wã!1#n ofؤXvDۡ)CеΆ B<#}FvKE/TgZ9|ǞFyȇ 8C~I;`"lg/X"R4ȷc*BO{4*:N#3:ׯ;CmsE(ct'T<PuacFGx@J]V;A)HsRd@X6L: ՋOh"uhMVaY׵` <\HU azDnNRaDHOXKz趎/#6=!̚ZUrDL a}@`v% #WFv-6䥶" w5@=']qx48Ak#!/L e0hdm!Ie@.[>C-JS`j*)AWʅ)1%@ uE8?!b`EEӈ6t.v%3Yܖ / !Tng\%sCS+g&?>"]`s j@H#̺;nq@6 ;?y! !Hѫh+=. {6T3_"p)Bï#Dqy]'BxYyD, (\ &uM3"<<:wy%Rq=U w,551ZR)[C@[I !^#h>2c@ތ1̃7緩<ܤd5V8"DC(iLs)GL1ϱ-vl5Awm$\G{!popg*G\nQy-R3ŀiصiC/XB+8 pN!6Ce ϯdi@w/d:耺F4^!`gTD&ES 2"RAq !zQsaL(ŧ5۫1pZH]-I.SA0׷&&r4^F}t)> 켅WSz pL3ci]yE2p5Es>,\d 0!Q("x}IF[dVӰpeZ 3$8T`+ %HSنǎa?LBB+&zH"FVA '5:^H:7Bah-t~$ CȘhmTZ O#. -JP$4 @R`#@34ë#Y#\1U+HŰhmUcv )*$W4R_L\E]ß# a<[/(eАvUsv׼S4hr6!*@޷0'QH@a,rqg7Gok@_. gu#8ުhqew܂gבMeJ{2*B/r6}E9/T"y#;񑅁* ."P n8~?@k(:v22BԬu .Ek~k?Bxj $XEp1Ҕ\E="ؓaU% N#iU j=j! ElCdl-:"'o'#d6#XAqWD `+CUrcTk1iX HNiKB;vnzзwjeJ`/"ЃaVx2;Bҩ,$WFxao9J A:Η{ʞh咒&6G:nI@\iV"N&Ќ)㱪ULN""<` )|o< m(Q1u&t4qGɣJ7l9 -T9x @(G#9=$glY%60+"ˈ8v5w:v80/o%Lc9BԩE//^f!@ !3 a{@w &[ Ȯ.-:govA<Y"Hq}2ժhpNyi``rm"*~ډz|ApB~.B gtRHYJx" Ř۲ #804]D(%)!T#[q!J+6L%*ՊVb%fm?*7HWw^@NR"/N)Nj [#vͣ@a2;8;G >f |㮆`%N?iY"``!Q!pPu#ڒp$+V/Τ}=n#p{D0! e ĤDa|:¤5kz_<a)}CDJ&\Gp )zl[ :Yr˱ɾr``#~. C`[k)/$EӤk"N5ʅy_> S !}dƖ 1PR 8 sw-]GZ1C+TE/V;&5hGx Fi?k`1m)!3{CyOzuS"Pj] `jkje;JNBT58$;鞰0z{^m(^B Bkn.5?L+DDx'D\%0]=Dž8]靁YAނa!|G?K[뱓8@O"I*=De_c^ogBsDׯ #™J8 >"tM ] !d'{>&JТ"w:+:߆ԛ}k:fxƤ|E0„Q4ײC/^D*B#Iaj0AÏha~&!w#L aCqgF{wLg/NBMss A+F3n'.1_ ιޙ7#}F׹g@c[AʝBlBV~`;׍Yq5!~qaaZ}>^O ~mg@y|at~֭v!#K! 90ֿ^j;Dsuh&"wp>aOC֎oXz%V 9f³}UT,<&/`"| w 0 /=`!G-g\9ؾ]0-sAU'OAdV.#>`!~C*BS0a0&뻒lg.0h@NA_Skv!tV'5ZΕ*؈mCD0d"gT K^շ [2"*T(5=~&m0tfP$ a""eh;G\ԹSL}0b[Pv.!7cZ'jQ($BpӨ[kv:-[]q JQzM! ["uK` Hb?A0h<_G3{ЖYh]h]n_(Ba8q!P[YjG8jYB-!>$"dw6GނvN]3<>-!j& !F)1 D;7k~&:.=P-Y}ӧ"fl;E +L7p#NHgNX6:b-]xnaP(S. bQ?kJG ;?#Բ~ܔ ,UsrB!C!=0gM YI=ڎK{v/Q+OO%Gzgf#\.]-u# +0nsg ;Gf?s*Bച|Ҕp] 7#[:ŘMfZJR!# UGMɤiy[#\'}T"hYS[vֳ-i) t&*5!:A+.LKB0+Cps?rόMj#@g.U.] mNؔ`0SHė4q (}S dD}ySf-tk/{6s#Ħדe:3{ANZ8~'5ͺ@z6 i>`V|+20^X :me?#DaJ)jf3tN;~ЦtQ."S3 g-&!.F)]Ԭv@'.y}8ѬpI9n Z_J>TA<ؔM *qS IDATiOLΏ"~E;eLf=Hm lSL̘i>s )~Se>>"8t4<+G@/O"¼ <ٺ`|=Z"UnaeeD(5bxp.Z>=q]CV]^ƹU&%E."MX!BjoܱTkҼc)KC/FRqoySRK<o!֚P/pfzq 9`kMC,Lz#ZCjJ2HjkF2H,m\ERDN C-OmRN>]Q<-N'C2B!B!ԧxqϑ -%I݉,PXRDAJ]08\ , !4mSEYD(|1?AD|V^(|Dwӕr ‡Iadw*9B;TB&m3y ‘Q)KNLX}mHt‘Q)BrLtrqA{;aNoZHЕ%.]R &Bibu^Tguj4]Q`n@"r(6{?rHqD`ŏӟOnAP,܍yi*R ̳|A]u=v*;4`dp>Ac\RߎfU&1 jyjWb֩O狹+@p3~)zo 0Ŕ/knbw\]mZ1e7."\r@jx7Yw1PgK`xcFˎgC/D&Za52yv+="*/J; Vh2Ku i6}^ƥKތvH*π q- ]2o $" qT~gAb:|pLMR px:"ĚePNN 3m\/gß-McΏNlw{H(FӮyD laĻĹZp,<_!- ){ifؖ/jŪJvT.~'j!C /_(?P~B!C /_(?P~B!C /_(?4w]+?o_[/?凰_`o݇B!C L1 -IENDB`naZr4D*ji,PNG  IHDRcͪPLTEQatRNS@f IDATx 㺮[SD"?J6jlGfduΰ-"6?9?op| |@78> op| |@78> op| |@78> op| |@78> op| |@;~| ؟uw xf28g $џJPF|Io i 򫤿'0|lNY =¯Ʋv*e*qԲf85i| V̱2| >\we=:ALo@+o?O)xmCŧU_KCHk)| q,/5?R@(le T!T/ޯ2?B) rE_$hEkWPj鮪/!T_! ntN!^|MC~|3 a,ۭ>{)\VG~,h 0&wR݅F ~܆> ?,FBX C!, 7QVz {(L+y?aGBXIr{;(DR= \H/px8Dki?e ?¦P/@x+^tT]^ (| _R^-ҋ^1?VԯBx84 y~xO6? AY (w@x8 ĩw@x,,Gy ςpTO) ? aq m4op8 >Op,7B~¼] TwB>;!K@8+[!gn)8^wR1Nfwp*wCB\f7lOp.C~ s?⊷C~ Wy?i| !.πpE_Z?• %5K \JG@$ppI'|+~ E_k* 9zB^G^[t~?ᢚ2euN}KN!\uzY}WER@‰y`_ $?+b \}L$wmH@ql$#$\(C)һ1~CLV>[̙ `1js^?n w9v9%am4Q3ǿ{QɑC*dՓ/ 60t9mDf/ J/D)6ms{Gwz tF`f:4y59C~Mwf8*ya氇V/euuW9NdA¤X³Mopܭ7HY\>CI4Mg@AW5wH+67>U$vfvS@ @Yp {AC~VY> ԫ\-[/peUx]:f=*I*m7=y<\ևYT]l+ ṦC8-&8DA8-mv j5wie{O5#O[ima'$1Yچ٫-5lC ;矧ѿ ;ɒM&-${OpTؔKok &Vi:5dTh ,fZ"Ƹ_!fL2NAY}WCgBrBxx0*N򜍎>7!47(P:ϛ^L dkr³识+q!VB#55Oz)\ú y5Պwq'4C%<b5(%:è `-n=~8{[nJ%N,G Q mm}C+|d<\sm 0*ͦ/@g\#:anY<) 3~)K7<4 @/ې诇Pg3:u6odfS! AAKfi倶P+ԋ>{!@ :K飿HzL~vשB9z߻ƔΎOK&2*aClOW:`~ < jJGx(#ЦI|XQh?baI9zΐ4bdt"[b.]Y( ڵ㲎> N\Rb|!Wb;诃 > q.!F/ ÁU[ LPicNbo.ml#Wo2&9SFo1, m TSWu'7_;șňp[=)8c_o"j,!j.l+M~Z!z^v=Hyx}@gO1TP@&=Ƽ -ÿa5q,hcd3wO _偎ı.g>$t>l\E+xa5XW@UCAX!ͩ2 )\шXW0;U3ljW A`z@_M||M[/A]Gv˅|c2B(a ȗa EuE"jMbPB6{~|g{|~\C`@j,࿼Q0ȩ1bMe58#7_43lAhTn+4 w}+g|\]-WoV8ӕ|wA3cpT#qO)k )G8:~Y[< E d~rDy3w|&ڷ:!kϫw”==Jw a3S)eII˟A;άBYY;pO9; X}!^^/8εC0Fɟ² ]}WC|rwxKb{l2%qqQt$F^8,,BDz, x !N`<[!By)A eG@)=mt\y2YC(98cW{f-3ſ+ N*Dp$B8g_3pq9N Ù^˻5C`4{GWCw<j[{әxZ]׌^wx|1xEk|x[1|0_ tEK'8@?C\{B>2O|sUK;ų A}KH_gpRA!68^R͐h Z.58-}Qf 'ɟ6r< A;PoQ^o1X 8k;Ů+A s'OBgQE ?ʗlA雞!hin5U8c+6N# ^2Ah筭'm'1_H У(7u }C!nJYz2 5yhb*8qB0Q 9q>FZkq(fkvrG92=+ >ݼ8~P";FV9Eq]xKjuq"9U_YE"mM>SCȇN "*ȍfl_iyTaiqX(3y[-@ZxA&!_X=7= +hޑV\plXǏ#uiӎIbw2іz@QRѽivn^ٚgp0/[c~jэl"1eJݘ{Ei_x7m̅ȷ+yJ9 *ƾYr:з :ZkM,,Ҹ/maysBlV6=[u6g < J+ML=~%wwfy3Z'=[3 \ ʖů)@0A`u;J[gy0BX5`]Uy?x?8)V^G_ WG,CU%SWr6iE=[rtc$BSx;Ν8ސ$LlX¶yR7FL^!R< !7M4v M`7!IDZBf;ak7]2"Qk-!iPHᅦ^lm?+~y`{I׾=G1pS状Lvm Us@_94kR2).Gl6F(<'^B0⻋8쾒^F@x)V \`uVօR&<RW^+q5f抛Z!< HN Jk=lA%ߐlWA`bCxX!Y\8ڝ9-U.0{ T+UbH>!!j Eb,`;yQLƱjyB-PV{>Ojb\sP5Mm ƮBx)BM`{)Tۋd .⾪9yAࢥfYB ^Y |+6bYCjtLG!të" Af+g3 g "lVU4yNAl Xkalw\ Da3M]6]yv8k׹sK6Zτm-XܲP@F?A FJKk*Ce eN'׺ BA8MލNBTG6`M/!<sUB(yk/Ft, <`b_5%sbzcM|7f| /@p8Ϗle81K2C+ڍ_>zS=T>-Nx>37FA`h1h !; xKbJjZ=Z ۖBF)x8SFY7U vJ@(=Isr B&Slpn `fa[e՜r@P ;\U xhY䷛[ hC+Cު|㼣ipszԦO sZ9k+hszm o@֦OqaL&ݚz.8"5ọdz0f~5^m;VueF}۠(q%[8B%Ѕ)l^]}F+Sf`kA_b2D 2@lj|AC9n67@x ʘB}ӛLRht›: -踀 >o67@0o ̬>oW``i˔?- MrB`?Jo+8^dF/GͰw$:CR5ju!0@H :"o4>I" ^}J+B$ tB}:BmtBNkoJoB_ά֋* B؜NƁ^ڈk Ҫl}Қǖ!4:;vOG|\7rP2hEm wmBՈae DB;rˋ]Iwǫ!5r*\uF<55¥H] 4wz-o{FbOٛTۻVhGJovjG*iqrʵ+3c aG/B ,$[SUU (Y@ONlptcE+mt˶Ws,HP_eaLqI,$@o4!Y|^P:\#)!Oo@XC!Ap52Y+3jAO,]w4z+dmK5MS^ht*.sA lI IDATEs.B 3T P1V-mRA0_7/P(C $D}<v`>?wv h/E}<^g 1o<č "fFbKHe1qD +Mi0I8fkÉArғ&~[Q* g*C(fym3?9x?: .>FmZLm{M= A@}֛7?ԟJM1`Z {O`-Hp@x)닭*eM+4#ʕ[4B쵅yj́UAUB*eSRU]@wg3m v\qZ~wM>z ;!V1p嬗T-K#`#]PLu _BBkj _ AQ:zÊ.<>/>`cAFU xi._O!qjdx,L!(x!a?p Arj B2>? 4ɛOy_"B%5 RُBh}^B#US:6&/!Lr>l۪%~C \h4\w ,}+/@N/zM?C8:ҮCBh@1xiС.)M1SE{f:Q%5Ok**n@g0bM cIk!6$~V }~B*6:GZWr aa?y 6D ΅yy Ṧ rgg=S!S̱ϭ+5eu,8ZXeߖyK/ՑbMhrҪۢptuKoQ>O¹BAA.݀@(E)Z+h![ އ'bA؈c<aF"cS8G!xNSNG`tɉĊP G/" <&Gd }i !XVAO.VtWMSVuꛥ0(ExTcjզV=)C\$!Vp M쏻Ta\6Yl 62Kܩkr82Dž};/4BL?^wn &6Bʜ-״n6LT -!4ӥL(Kf|nBYXtgɅ>[R!snAKDBsnBd :saPIM_v!S]@&V,^B`Kr-ݛ@ ֦gk߿s!Y?4kzOG@H[Az"l!5M>w˙a81en]k6zB7hybe@="F!<=VǪ:c;AjgN3ԃSu?j_+9 d+a;²>Tug,e%'rq¨KzE8`No" vTfAmAwmͮG D݂l ACq˚9؟g- d B3i>h w!C1?%nKѯ amї B,!n<:pU݁\mfi Mne=@`JrA'gȇZf2.F4>ԟ:]bMFwH)ZQι!PUw . =CX ^!l;*f;Z+!Vڄe=hIX@ Z[ۻhA:>C᏶7@Kmpd:vٞ;4Oh !#9)B*s6!G X-;0CB eޘs03~?re[,!D!2E˦a& V{'ܞBUEU D@p;FS7G!H!1`8^&qL!4@5BXv92`Gzs 'GgK M~5G* e N|qBj#Hk˭Fq1#>D~*u3e[LD": !+ P]O/5۵I'_%G%W{S! v75\h ;  [Ӧ8%^0W!6*+dh&kt8wW>ؗ E@!,d!I޻W{X. CC}^3#D5[Լ`f !V+@/B ,,.1J4@(NN景Ap1a0-CqCe-:ځhQx|Ȍ- 0#^yB  H*@!}< yUㄠlaĝǓW= qHDZuǣ5-!,Pd4+ƼAnǙ~k}=a A#&Q*2FsTZ5uZI! .^nA_q럲3,zrSs_ 62{UO0&+. }>`@9a-I3M%i#ۊ]ʂ`^i>!,som,z@rtR-.sK='E# N;;A-%~#KvxI]0lҝa$[kmZaz fv /lUTo9tڥNr  [օ`z?AwZlqC9#@pӲƴ8p[ϩ$;qX9V_E:O}I]ڨZiՒS&C7J>qf- Ms 2;fkb;XX ATMlRLփl ?.BHmTǝQ0hZ[6%.+.xBhmW$j-OnۨKPUwաROTo )d!PJqYWcıd,=l~X0y n2kcw>@A";t28K[' Q=!+@ ue8bjpґeڧـaۓ ff.! 8Ri!4dJt hnkIF :]p!&߻LOL4Ǒ; nLT 9y Q-%2_BFzKmCoQ= !puLV._ (& |o |W@w Mr{rzqVrB-\@,gqW~,T'w>֟50O)7ՄC e\XK>a SB +l}zX囀.VwKY>ӶLl <0 /x@f-rӫw_秋D4v/dA!p}:"Z=]3MnsU' u\jvl1sOj̯HsH]**Z4חwY%AfS:]$uR+!m !:+C40j$,Xncw{BL(!!xj{i?UB1 )P3R A SY6JH!H̻&)tZ D}d1+Oƨֺ MBEzy{@\rz;!Z-@Њ`+klNL:qo#Au,՞=@x4=*B/D) Pj a'e SFah~ T! F7Unr6vv+|0@x!/@ŴNM9uFaB!P8~ }9,J_kZΰ t!CGbC9q!g`6:ob!3 !  xlBTzN %i5jzpk#IB`xMVFI>:0h#.C ɡSD^M]Z>%~y !JӋmdV*:rm@ub$mfNB/ԑǐTuDm4cU!((1K4nAnj[(s$Z9 )Vf4ȯг7AʒFO%mW53Q)#}WzOcBrAL\̜x2eӠ& ;av =fJ_P!t7߸@:qCB( hiOrL''0%5|-&øu3W3@@Bb ]mY"Mv`l"~3)I8$b2y+'kg%Rg%Ww\"Snm6M-3%zMy7 YU8P% Ar3d\ٸod.LҠ8$d1mT>P!Kd`N Ep&%I Rn74 mfBkZ75*=2&Ene=чt{6B}.B>ĥ9U99 9z-(P-6!T!KΏj!=xFݻՙ@TG H[A(ׅ!L!pPҵhIn8 zL` u p a[Qfguv IC55SΙ@ 9`Ƹ3yuԨ$VtĚ Nꁐ).f <BKBzAMw>bJ}RK mf<@eK_Կ{ ^!YQ 9;XLn6B51Bሸj6 , 0VqBbڐΌ-I!8=vԧy$M@N+_͙2} @hH7:GHʚ8SMQSA) U%lS\拡|OV H@?Z@ _+qiD<·}0x k%A#pd\k 0JPWFBvEx:6t6gt>f; cX=&F&.?Z>.'?Tb0Gމ멓@37a<[M3JxfYYkZA@%J(B'&5k;'i4mU^w5 ZgY zXfvpC8IPx ͪ TmqU]d ւoB o_(\0?e~-TA0" !O;nM Wy9ֲnG!b. z@B( !ܣ)|_̢B1b=%FfgGB[@k aV}t¨vlX\ JK:@K[!;Ty7 F!QRu5a2 g 5JBI@(ӆF9;ȜZhS[[oTGD[L I-Sgd&)zZ@؛'D‹4 &`ڌ%7ͮ\[ਉM!%2CRی߁0|:=sv 4CSPh$骦om|g)+87ZĄ@v=6 w TL(Bh0yFR0 qAK@Z,$B)%|݁6x)IXBȫHVNK~E+l6A͍)C'L-?!U_qa6 (#g8a GDdtZɫ!w_]߇+ƱZf:"C#}uy Zy={u`@AaAxq/=R'k6 <.5W-aq.x&0@~ DC'2y C+U:U1ڧe]Cx*x B0_~!,2U0?=V DcBiZ !mC;Ⱦ1^Fb̈́Q&mxeOR`~aF()X9+q@=rLV~w}_BG1qRvͪC AfT* fL9bx!&a!N-1?7vc?B zULInHmޚY2sn#B!4Y@O)~37!͹KAV|x{`s!m Z? ~ ش 0ǨLm!N/?G!L&AקD3 g%Gm2&9haԡC=Z5#e] t 4ێBQE>H@a-x@Mva6 B`)V䊧 6ErpߤU|[^ "l' BYoB  zBp^\2d[6DNh Jd 0 (E4 W &A CW" @eUV6(ppQ9ћL@~Ӷ%HAfB!pj*p9nQ¥M=\](j a !cDd] BELDU2BX2^lΊ4kURd<;l˷賽?;e8uf^#3B>V!P`.Q8kɇ2=%ee!iMQn }S_n@0G ;+3>g?zm F.TwC Ba Ǩm z>jE7 !hӱNbf!YvsvP !!x%xsp <3 mw^l!Qએn@hJ^K%TBgj$ !Pe@`ĊkyB:` av@z; y@`2lrpiՉLB>B!hT2!Lh`Gk(@`\e*I -SA.߁Ѭx/ -!OBLK)R  W5 ^C&F07f6]A6\=/t ±>Wx@^)2(*Hfw 7K=JZK9kos<'T xZ!BA2!j\VšZS]8I%!.1n!\h+B# Y sA< Ydw Nr("m_sZ y&iM1%k KhuUH! Q84 @;Թ.%z±cY D3*A[BpmʿG&koM+L5u]xtT4wjH! h}4% @#! MV FH!2;5g*J1.A9h4*侔܃r `H 3O`! $ߛB2anus8G9i!"˻YAmQHB<0wg/D`P{a\\UuPHҒ ^lׇ\7Z,!x&xasWYV6/3΃(j#iШd/dl-3e [P^ߴ]q,{MGh nCXm0!r~e!X d> va)wKChC,RkG5xuZ2jAuL*bF !6LDpLE9w۬q)SpM<2u{1AR:B}< v)G1e,"{| dtElꗈ!"6>:@}ud`ɸzZ yB`54B\);bQ?^fi0!U !(d]A*( Ui}` YOL=S&L_ShBC2-Jl2<,!7@|rq}ʻP5FE2#f3E> θ*L9Yc["-!ty (G L5@MWDr tS͆rxFMBl;"ui-9>9z['L6@0TŇaB/j =Bm\J`LU\M&+pxbu и\`߆I@(vS"W~ Bd2.@ð(M Br!;nҙ`΍; XB B,,33ՌPj#_C]IZFzφ !T= /A MܒRA2FB‡p>>@ȆS5ߝ!XMYo 6F:#!M 'BGBEg@P_QF(yhBgUYayC!ɚjz 9C(fR B)4 ހPTF'ٔ@!@hq SvV}d&n]:lMEh,A i@Q~C@CzBzR8@kah *:CG枘d[jdJlo@ЇwԖ)[@@!{&- 0&J "oVҬS5FQ-X4'>f !j'4l`@,W ԆjhAQmg B] @Md*UL d@`3׎ 1c2O&6RB`D xd;[ Ƽ _\7uim@A@AAߝ- ؤ dYn!DI p1ͳ1pZX%qq`uku>#/EZ@Q\!Pʯv Em "g1V5f`!D$!%=l%yB*oתW_70uB4&8@L3 ϮfB$fa.y .bQI<h!=A%q@06d1k \fB$> J>H]#7^Jf]c"ٶW6 GH; $R!LEIQ pG<V!_p[Ƹ B?L%& _Z@hkB d 2y7rB؈@u8 #Vd ʐ:z@rtaFu3(@G `arTR#Ut2`\!\@>A( 8@igVϭc@ɲ+@(DO%H4!ZYm3 B" ](JxÏ¢' dpBPψ(BqՑAйF)eȶ&mKxpƐ+XM L*ũB x'tg!p1ͥ&nA9Or  5-L p8Wè[a'] iS!' xˢ&tr=BNB!󻅠\B#zssW`3w &F @ &䩹i$0ܨ@%% 3 g"+Xۛ5U*;L+1(qRT $F<2t9c?']nrbl&!$،ݺz*"*PI@0 as-YlC77Yjc`:qK-}DOנr NQ< h6EȠҳz G>!HlOx&pP;n8A jb Ӧ/.^BPA(4+m%16?zdur .GKF¢0(j)MڈGz7! B-X– {X !>D32>hSJj*о fmP.!"+Ew&#^8U4@'HN}c>=AL VJ ]d£n TjKБ槖@tZrcİPp abޫ w+۫>Bbh%f 9 lH̶i0ֿc)S"s*zg,~5u-9=XoN3WC[[z_ NaE+5',֐ b޳ d`(/a{yU]@07>]fOނ}[guõ@r6,JV}v^ũ Tn{Uk/Gv f][%&]>ؚ)Z/wD ]8UI ݷ"8ۓ5fES:#`U9-M%x`Z&~K$VL!WZC|Ƈ==Die4xv ÿ"!! J~}Ƶf@'qZЗ3!]@1?D2ͷ|_V龎Mvv@3ʚbڙ!ԢZ BfY/V=iDO0Q4/RE]ZVx[=mwmd %iU;.8!0Ԇr|G#[^Cu%:f^Ͻ|+zjPY2.4 Z`)fi]3GnBPp,;]/-RmUC qg4 JUmr a r $"D#Y 3 Y%:QtEKEc d۵ٜ 4IH`N1=CܡzUنOBY:]eAuAhɸ4ڣCi"6Oˋ) B/wGN!x\z, V^Y Bhn;R{hl'5A`Vq@ #<&9k2-! tSCp}Rvm[ZLcanZC|Sx) ^*)3$sv1ȼ/h1 dc {^ #i ,kGJÜ4CZ6[I =6BЍ>gjVF[A@t~i?it$ u2Qȝz(G791Aowl4\룖cVR{o)Oy f]V+Uo A,m5G@Y0n`4~!PH|BxM !LKov.K- [r9/K>hsJEf!PoU>ZKcC)]~YTU}QƲCD. $YyBBX` h AbxЉ*ol \ɱBetz^:J`|]!xV*+Y4C:m<ڪT"T Ĕ33at23B1!A,$ pdL8Ϣ|ˎCgou#¦+v.E4H" [&`GM#BpK >yLVt z`vz ^B\53rBYB|LW B6XDe\:c4^3\rTvFSNL| /ZAx et9l>R`)!5ւ&RB%b0k*G< %`pIeࣖ S܄bz%̥s9A/> {x%I{gab, ȇkW@S<<@X $ A6@(o˥ưv@nƧ;v=L0hVrR m}~ !7?rk ~kiܞb} 47 8|#q.b$B!9B!Q4$л`BU+:G @|4/Y}Mk̖@_?} !"G^,[ L+0 ^# J,G; )vNyh5'Bׯ 473նC}pN)Qd}H1\`CŤmI>CR-pB`+fA_x bna4eo&]ȸ"w6ZB!D[GhnO D|BϜ{F&Tv4eސa;cEL<P[ .TŞb3@h9.br4i+16C 9sC[(dwmAK7kM;X<@;-@ W\B/D@.[~MtH2B6AiE͔%+-Bx[BīB<9}, !5n-1E0^`t{cs~$7f"8j\d5 N`c.\!ZW@@`AߊܱUqXO,T6Ie 5u q8rzL 84}ph+bʫyB#P BLa 9b6+|)! bsn3ˢ:8 rc`R,c"uzت-!F؋V!Nd pޞz5N (8I3,re@`M@+Z+a4%@%UxBLb(V6!|aʞN'kgbdz  B?%9jK1Scg]czY|0Ukh&!b_@I"#V<&e*!AKM࠘ۇ6wsm.[ň ZC \٭A4z L.  W[M`6 xg] U HNĩ8gX='A91u} xw`@.G<)[BpP\Q) +.L]OS'\-#5`^4$I-jzbϰ0p Ot=7p ` vםYiC׽d!%&r0[B!9!)i5\ Z3/+?bជ̖pAgFxZ?Ox[(s$lq@ !U"/z>w>qZ+%[@4Bέ*+[n 2v<cIxQ]i+0<^E]¨+Z>5s"F229 =CLKF]^(04᷷@=><@X $L17Bډru;"r |#(9ՏubݷvCeϑm46pr"H /y !O wAxE+tkk8*F6-!`w,m L*bGVm Ym¨\xQ| G_ BBX?[Fa׼XnIίfޠpKyߐnTֈB?/՜w-[Fɝ`T!ǫI/OUC3w$-ZGK˽>TCHC$UeLLANd!;k](!do1TGo<x+gP!!r7Mވ hQ-sVф:iϳd<ħK>!L݃`;ǧC-xƱ0{&"x%-XK@1 I9Bż01ƾDвmWY: AwRY ⷇C2Ek)b1>6̶ܓ4ٛe%W! 8OsT>-jj@4<Ϳj  (*f[A Ry {n, \3ǀ`c'fG"=_qph0 y^@hGE4W|)mwWĕCHW !xMu Ga]< @'!F'#sH#n|N!|AChu]IfxT <[,H/{Ĕ+2>$ߜՑeʦ^deў 6pOFUF^cEP|AK.FiN Y@11G} ó AB HiZ:lKE$ W~/m&F5BZ/ZF?u(l 4DI*!v BG:!Ts[ *ڒ|LuǨ*2PMҳ}!e2J(\Ir%k D2YIECϺ$Xq B }/ kk b(K* ̹BL6!mI|gl06+R?J1V6. ;:)"2;=Aw| E%!x>5gP_]e6-253d%}8b\*K*[C-w@;hִŶ"שּׂI} eoz4"i>%> "V瓍6@ ZBȦ@=BkvXy"e-}(pdmo˼72;}v7h=*efBB^Bo;?H2H BO~7S):R7jCuTWBkA=½uFSbd[Q-;f.K IiG. 9i s`[9Q=R ;y Hk4/hKZ*WWZ>%ĝ-+`!}^ࢅXLQvuPqQRA|Z1P 0=I#C浛eQ@@ ,4`Eh5&oO2S_1vdHUr_R'ꥵ+>Q'pձ '"_GoZNz:Mk=hyv`B%LTW'H-OHڮiڑ*b RvrCp?`?tB Ε#ޝ*=P; cŜVQI} m."r\s\AsZ (V!LҞ*nVW+\j&4yi @57 T18#_}4l*4֪B|U!Ty|ڒ :8c -{I7Aʨp2j!@ a^H̩iSqt=/ MI\Zʴfm'%W/݆}5 `MF8dujN@Pa{PBL!z1^ZccLQkYl5h<5(1=B}@~phar=w OՈJI$TM_ c@os =-$,32t5 B1!+Ul݄Bv*;S;TR%k=)5h QXi톞9i g)h{ݱƼ`BFe<&*$dQ^x=4|Ze}/}`yC]H'sdMPdb%B#az)Z@"]dZfk@ SĖȍz&mV{7u+v -M-D-/@j2 US85ҜScԵjzCf!z r-V[Y0[m.Q#. E*qU,K3|+ywo)5&z75R &~IL|1CТS)f,f0ucTGգSXmeMkf?L쑒8!F& H^ $;-*v/@]DWg K0qJ*B6@A|tJ G;ַ}GY_cd=|'ŤsNa6M_%존IąUvuC6lBhyusvP*NBr m[8;˶.&Lʃd2Ț<^ G0L/']4M hB1TYsBZ%-|Y\>FQUA:59Zu%EI@1\Y)lN5qt/!P>Ag;#S )93.kUCs Az! Ū쐳Mg 儙tY\(_epE 0LA2J%h푳I; h4F~2ZPf46m v!' K8Jʪ`; ltxO~ +!Y/;Tyo vBȬ$}4.fDjWf?rN3&Sp.:.abD-dl xD qIBJ<>QUKpMc!c.toT*{d:Cz CC5z3 y1ZZ 12c Wۊ0v'jn.߶N4.<,s V-sxomk,0X'f. #=\ M{PcADYߦ a(7C.[3~ ;!H5U~&>}d =>!m&js* a%nn7Q}mV jF';K~bUAa <crAn $km< j:- !SI\o6J0,-/ HD u5J5{f\B!p_ѣe =HZ!k$g䕡Bk @Тg~e \`"X#Q$<<{RA@ˮaFw;`N *sCx5S_txBW( 0 BkpVC%⩗W7jڰl !0A5F x AB]MGB.'hqiFmΡo g\# ލgQG^ V .)k1!OAdjd=C0Ab!HIB6[ q*oIDAT8*: .`os)h!`ϘvCy1)Yi~AYvꪇ`:koEp :i3`z=!Xb*F)g6I.Dƫ 0v APk326AdH>P!ȊrN@n]Նb"SA%E2<*1LF"}Bk28vXX 4 5ހ+GmU\B0G%b<_ RMGPa=ib3FYW!d8A/}3ve `5YW 5Z!5F!`υNBm'H0@i02M΅oY:)L!s1RBs_ 1eCUW଑W fzv :vU( A=žSfRaL~0<!iQ=BklC5ojջ!@^RiA7{j@K*{˖ i ?t?s|N7aBȧ AQYwB3 ޝ |' ήkH:}_[էm:+LuQh A!B8] ETt!5 ЋNv d h_[߅ (2qrB)g! j$I {nT´rStB{&J:wbwCJ*H7k#}6Ovb:J e 8B(Iip|6q턐 /л'EGXj@3& *F! [`ݟ gPL.z-253zwb~Q6]zvx qOlbvAYU%{iE62qB}w ~  iaں#Who"k,a.g! g!.!C@lRsr ar Bob`z%; [bI qVgn! 6=!w O@GU,)4 E 5j:wpt<֒ !˧ ^hgB Z*)yay\Y;8.a5z BZ-z2老jmgoG!@旷!tAS}ޔEZm{9`C)he'L_S(қVdR+ 6F!,.2mp8@*^.B= 6\PҿK$.Ʌ9! e-Y Kq8 ZQAY 嘬%|BuB =CFkS`(:.Ʌ%o~B-B/b!!޶iިfKXMBSzXv]2|DFn hs^e@nBQk: `̱9/M\ \T֭A|kw,O JJ9_d y:{Xv*- pB j EC/^K3Yd_,΄:zwRxit>r_5mMR4efEx;8kB02s.8F혜ф:Q@Hd1o/:[ZHݞãi7ƠUk?Y /5[&Q}.T;ZjP0^ˆ8wAfR{"C=d{!5c{ T>yr<1NB b߭!`o. @NR2aV [ t=]yʵhpcyL* %{$KxB;AذFOA@ 28Jϭ2d)TkarBט/A~ PKزFs+:BЛ-i|33a=G. >/ 3,͟3 O#AYg&%LoK39glCp#`@+`BXb֨ `)p\yg&L#W| q 66<a[n 8 Ao;y|Pvn,X}p'jmZNCضFAziwMQ3k asƅt(h WMRo\/ϳr%< axpi߯P˘ Aa4H#fDz&삽.aECHN )ZS.M$8/K!l=aƩ$]VzECu:VBXSCHA_%f~YaKXS_r;9BڝBި 8;IB~_W% ! R_϶r}upB/$LFah ºR?.Rp7M>(7!$Oifq= Bv.a5!j+& ݀!Lbg'\/(a v8|vZ# C&,v6燩ǡ$qҴm;ei+iℽI2l{PL lI2l4)Վ vX2l$6\^k(ɜ)av*~\VRK$}6кYtgwoXeGv>(a5z }|$c".ay9>yl`4I!S0B2Gp5چ> ^ b/!AXY6?>A+l oUVw,W> +Zi5ۯ~B)yV 3ZyN){)4z';i=,綢U2|eۖ]FA|=!e *C!H9bB!iEWԛxG)Nky6;,LQ4ݳ"[_aCV0{!$Ev2A¦5շBF1e⤥G3a"lBXm< AXs'Vs^k4@ hE<\M BoNOe15ބZWP) a-rwZ@\zwB7WVث9!cazti!Gnm((*Be )/ܰ T,=[[pCϪg= 1} !8a8]z[p6ɝSA0Yaf?!x/gaלMn?@ s=I/vӖ|^q6Mg!X׀Mktȧ!\dk+ʠ9.?%^+p&Lƒu c+bhF Ɋr-܄-/#p }v4@|`Wo0L?4z\ >1%'g |Syt߼K{u )9s=.q#VO)o,uАӊ@vJZ%@;"Ban L^.#!BVͷ^Wߧڢ@[bN{+4wZ%ow HxۡaW5)fM">&+Y#I̳bo7i:EŬ[wg!IX2D`!E! |`~b[۬,=N.):yo0THyӛop('H}X*eJʳң%WAC[g2Iz"cG? !)gՊI -b}Q}nEEٱAnS TqAXɱ?!j0L|gq'{nCHZ' t׬ wRNBAFYV0-Ý_=( Wݧ P!dv=tfFuW1!< %]C'=2B';Nʇ Pb!-3e@iA} 帬AX A-5d3y= AR!7QSPߐM 7@93AlRo5 do<%+&PNczuqט#@h&PUW'df\CA!ho!qBCXIo+}ŧk Hu"AHk˻Ŋ} .EXam9hEIPlMڥ¿rUp DBbUnT\;._O [ ʀ}bE)"3="WG!|(nB(Ť|RCjj.V"*U() eAN!ĩ 8v/"[3wR> 5T+&t;+;*;a~lVsuЙ ㎷vO!_`1V.>껓l3$}B}#u S$|^>[RI/Hu@Hp ndzI!բК[d `+H171Cبy6s#Xkn;Ig% |By-ޕ"P}S)F+hc5t#jKz a6 )hsM~G!/,cŵbP, ;(?39[i 3&B4%DbY{x/3 4B;fsHHpk7C:C ᯋWKJ+ 7hFXt&0_"rf&Les'G45G -ZXb^;ՎVqʄF#~rL~^ ?/ Ax @~^ ?/ Ax @~^ ?/ Ax @~^ ?/ Ax @~^ ?/ Ax @~^ ?/_P&dU~^ ?/ހ?ߔ&@~^ ?/?*O~r @~^ ?/ A:-DXq,IENDB`nޜp_3;JPNG  IHDRcͪPLTEQatRNS@f IDATx :{ y7RXM/LL?8ha[E#?sϟ+? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pV~ qOe'?h 9&?qf~<g ǃ-, %(c`uB?(@# |4`,oWI?A[%@x,Y%@x_z4 V̱2@ Le}:rQߥ~ /,I?.oV w<(@p!Ӈt Bh~yxiqRRe\ ?8oF)|s Sy72p?IPlgo ?rE$}kEkgPj鮪O!T_! ntNB|70f X[}RFӭ[)|[SAx+o aM]!% ~ q(|WCxo aQ' 73D{BX)=!eRwo aY'!c[BXI!K,s!+;BXKy/S6z«!_ \a' FB*{A" lE*w/7 ?OSnrzA8( wp,7B¼] TwB~ wBpVBe>4{!RH?{!I@8-ʛ!i ©L Fr?7Ca s u] .'!x;M@ Op5M \'@~ %BS \K{@R!?µ!.Is \- \ J?ρp5~ ~לuzQO=B^G^[t~?ᢚ4~eyN!/%C|",!!<'r!\}& ^?d'cB'@ 8[{$6O2!\ʑJ…9?h+,X{9#?$aeU8Ϝ b/J_s^97/ƻCMkG$GͨE#QT>dՓ/ 60t9mDf{ %W"Z t\ѝ^n>j3ӡ??NVN6!?jqU: a3#>2ѺϏ'aRH,٦CX֛}!R59y$zdScU7u !Ҋ͍O:'IwD4µA(55pVY ~ \^PPFzU2*WmVr!\w:0uN?l}JBJM5?ma4"k Bx)Nˬ kkNK)]Z]ZepcSM߆S`u:j[y, -B8ɽu !U;6ZB :U@ ;}'? H1{H@~}VШ'^6 !kbF|հHa So WAn:F&!GP%3P[[é :.Qs BAu{cS=F> ]%oo?;}@#fs@$ DF0:j@!$II S+la#AMtWC@ja{ٻ [NC͓!l 1uAaTsY]7 \xG_7h'B(Fs6>!`M@Lq_}d>~`J fS T[UA0,PBv  e@cn|JHu`fm]}Cʙvp:ڷ@Sjoc A2z)%3ϴr@`(uEBxFhvE} gqpzGJoajT%tOg a L \l &A?;tT !]|cJg_ %FGA0! 6y+0E„MYpBE 5BN%ҋ#k0=BYgH waTj:lݭJ xVӮ,BqYGu_}Vz'`o)b1 +1T}Ah`WGUQ8}AY*-| q&41T'7 6Ǒ7 }YRFF`S)aMm7AEy ʈ6)իͺ/bD~B/JMP5gw| E5T^6&?R=E/;<<>[ ̳*A @tv@gcތ_M8s1R'R @ZQp[X3Z@H zbyl:I]6 Dpuk0+R ,TMuKhD+A]G_ªHF65wo s0jNL mdmd @F]>o&ڭ ꣯ aB1Y[!0IK|V0ǿa"5& bC!J =?2=ABL?!l 5o A_s(|aJC~1I+2xiyIi6/@2]aRgAC0_VPィ,= rQ.!V]AxTn=ߘ9z! v[8KLABrDKꇴE]G_1ե9cSpjN LJvA$ *y NLwC"CLc-!18$]P%\V.\.V1/-u }5B=-*gxʎ6ۧIO!>7+J 1C8* ¸5 ף ,-qP``"fZ?9y<;>~ j[Ɍkr Y@ՏaƞQ;)seX ¤$PngV} S8_E,~>a/sZ!QSK#JOaYή!CCq >\l ;<~[=6AÒ8JDt(:MwYa x!@ćZ"=n/ag -`{w!Լv B# Tw㔁f6:ps,j!ı+=3l kJJ'"`N!3B A诀` 'L/]ؚ!q!x;Fo=L`[kQL ;<><" > p>pO"%bCC!eݽ? !ҧ?t*UYfxYK [_%3XA8) ls wp|*fHwMm@-A¾r(Q z3Oc9Kv Z7}Z(,bmgA`bו Xʹ'!س"yǟ Bktz6 MO4*sB1C?A[]o/C` Gb'R<(M]$+&A߿PC!gRnVBMj8ڹ> B;<nCbLT}Nܼc֚i گ_hC8I-!cRܙ6ΩX&?6/:}M[گE^s>BXE"mM>SCȇN "*ȍfl_iyTaiqX(3y[-@ZւZ f/tKқSdzB~H+V\.86SUǑ4viG$U;IhK=(^4yx;}Y/l38-U1?fFc?0GaR748v^ѹ'pW8< As:e5s!-JRo@,+꣖ZSx?>)4.K[ry}YmflfH{KmcBx)[ϊ(_}ҵoQ>E@蹢-(]ۯkBo@Ea (W͚ԮL&+M7 ωLu"4Q+.o `})X]|uԻ T=((@WqJmMVO7Bұ;Қ;i[P~7$0[Uiz3ش?r;V h{@eW`7vgNfKUKE7㦅A= {մO@Ƚ#{zQ+$>z3< !XN^0n~vӦqhzj0wDTlSx'Ae~RVƈZ[sQ9F ޥ`@#^\?';!T QmpyBWnMNWM{[n[@B0FF=\#{ tjXi =6@PRTZeF&OdAȽm52[ =n2DG]4G:|F$\!@{[t Go@ub-*(M~M/BBWs6A@1`G@dq\Sx݅6BR*}ZS!$EqK*B;Ir8OJ6!4),p_* ؀{@ !^Z{: p}Ͳ9i Dj {XeJ"-ogKoz*afi^hYBks.C#_ ¤X:+Qݫ𪈴aPw ̳4}62dlB;c=ld?zc9uy*[8QGXlLSx.*ulaNuM3!eE[ >?"֥%, 4,QO4wAPQ=RJyFYCljprNw8 !XSKFO47A`f{J wK@`">{E}&ؿEqxMm4B-_4qËμ.'CNC~L(wv, <Tռ eKS4̍lA(8E B"mHNF'ީZwA:V¾󶥐Q ԣQM]RyaJOҜ\IT:>"){ YFm4AVdx51>CAk?pCN)7~F;v *_8hZ`2ܜnh`3)GS᜖v w[ S@"ӹ `}^ g0fMfn:_Maΰ2P`}+qS/,+iB`KF':. x)M 3n$pZ72l rHϱF[J&7!'YK둮{3݃u9`31ɇBeaGTdC nm*<8OȀtyWgJkđǶ ݬ d YV'z^uZ($>2^zN Qʷj 8W![e;A VkS ' UF6K B%զsȕ"Ƞ#P B8N!䤰.Q8F!L ,-ƳӾ*|Z Ḃ5< <*{+YT!\8^Yz]6ǟ a wFӿ!@0FoHJLAg B6_)}f=-=vVU.%@!fi^3Jx h#OBF!PmLh0~]uArzn$ 5@eS0hqFBv \9C1U҈m!H4Sݾ—:2v!gBjK6ONjF=`rQdj^ZlbWf9q30?^6ӯGA- ^HX/Blu;EÆ.z4_PϏ 6B8F& >mS^r0H uMlcZa> IK+[j _&x!t *˦pA=JA)  :1Fλ!=#P6Z,tdi~thA `0j8ryTQlf @(ٻ}T@m ӚJs> ;%e̶kSXc )C!p_x>z¬!QUCuO߂Q}sx^fBx)<rsApE>Ĥee"ssk wYt|< 7v ķeRKu$AZ%궨,'c=km(S}p.gi~K%z7,7@l Z_zأv6O@n} CA[% {J{mN\ v~BЛ N}^Ӕ1X%4Cr"?帅@ы'b;YC`_C3g}UPӢB( •|SG锕{]#x8f)h !u?0iy3i{ 5T`εA ML݆ 7:cn!i 4;^B(M=k)a`n~S Eqg?iMb0't!b}qGjH̝[_Cv~/;77C횕iBfo2#亳B&IDַ{ JtQx8ªDZxxZ)oF7}lsA &lA=lq\C/./B8G=M3[ͼ,wB ;qaKl6 {ӏ❛±> a潯¢2gb5ms[ $U@Kti&047qV]FFrT<@ȜA&qf۸6Fg!"sB`>`BX7TR׻BTx~&ؒ\K>!C?pÙ\HO04Bگ.pVа[| fS'rf69NLwZi{EM:ZXYtȆv;57BO'*!gx*ıjD4N"ٲ 3T?Ͻ,xa-.AlA%lD#=U3Ax2 jYɪx܆0jRux7eƛk/@znA]q`k-Q 9{iaPE² x` Yd l]P ORyvBX[%{( K|r!\Gw 6{EF%_ZB8w=El!X5Aə5!L> A)f&a׽~SQ kusnFԠkqpBh#H{Bi­tَJ.#@U6amY1)B4b`CA־>.v;wf'g `_"vF!)ķ]> ;O@R ,$ %;飷@Hm&a6r"sF;m.*&qZCHxiN ᡐʜs7=Vˎ2ЪC;Cs77?'pV;KQGlL粩6<:CXj BUž>zEQQ7܎,!-u!R|4FG *qN|}IS@!g{ ]1<8nAL!ÉQ,Ǿ%!R9 7C_͑!H4{2p\rQrsꈦ axfpLSz4q{a/CȊa@G9Khwvmh! WDy Um݁k !6W,Z0@EE#B|V{#)%uŵW LUJ/*ZcE9䕧e@Q%Cp 9hk}j>xP{LѼp5o!XBq@  c+A.K 9$ yk\}n pLؾLPz\PYoµv ~Թ:(V#킥)翅8S3 WM-SA0?{2 7 E2 qT  yZ9Y˸1AנaY^B>m yY+k,Uۇl.>,۞V4C6St L1ܔJ3 YI'S´wK@cw[#NnN*6 W 0 a7ezz|f9Qw۷`B`ȱ]@m)R 0@x4Z[jz iKg2wxt}4\8B7G_5 s7  6BE-Z5 G piF/]=PIpeHX͇u}*MFn=<3 6.(SU!*O5%UZ {Mv# dHl2: <LF@=C `Q{F"Ao11X(*quw]i3ADS9 @MnmU4 4IC#Z@` =ي(2IGgmwBy<9?tˡiKC+|Ç/!ZiszR[MlJEGbZ- 4R,lɀ@Q:w\Mсb{ޜ@`w| J;<"%fF`| !qK#4}tTKQSS9G9Ŋyz"HYi@s6>*EtDأ1 B Az xS[3I>0Old}:N![< B *.S XQ8nSE-m@Un ƣDfro%dnƷj~PQA`-K 4Bξ6RoF=a0 D B&vA3u}lrqZ**5Ww\"Snm6M-3%zMy7 YU8P% Ar3d\ٸod.LҠ8$d1mT>P!Kd`N Ep&%I Rn74 mfBkZ75*=2&Ene=чt{6B}.B>ĥ9U99 9z-(P-6!T!KΏj!=xFݻՙ@TG H[A(ׅ!L!pPҵhIn8 zL` u p a[Qfguv IC55SΙ@ 9`Ƹ3yuԨ$VtĚ Nꁐ).f <BKBzAMw>bJ}RK mf<@eK_Կ{ ^!YQ 9;XLn6B51Bሸj6 , 0VqBbڐΌ-I!8=vԧy$M@N+_͙2} @hH7:GHʚ8SMQSA) U%lS\拡|OV H@?Z@ _+qiD<·}0x k%A#pd\k 0JPWFBvEx:6t6gt>f; cX=&F&.?Z>.'?Tb0Gމ멓@37a<[M3JxfYYkZA@%J(B'&5k;'i4mU^w5 ZgY zXfvpC8IPx ͪ TmqU]d ւoB o_(\0?e~-TA0" !O;nM Wy9ֲnG!b. z@B( !ܣ)|_̢B1b=%FfgGB[@k aV}t¨vlX\ JK:@K[!;Ty7 F!QRu5a2 g 5JBI@(ӆF9;ȜZhS[[oTGD[L I-Sgd&)zZ@؛'D‹4 &`ڌ%7ͮ\[ਉM!%2CRی߁0|:=sv 4CSPh$骦om|g)+87ZĄ@v=6 w TL(Bh0yFR0 qAK@Z,$B)%|݁6x)IXBȫHVNK~E+l6A͍)C'L-?!U_qa6 (#g8a GDdtZɫ!w_]߇+ƱZf:"C#}uy Zy={u`@AaAxq/=R'k6 <.5W-aq.x&0@~ DC'2y C+U:U1ڧe]Cx*x B0_~!,2U0?=V DcBiZ !mC;Ⱦ1^Fb̈́Q&mxeOR`~aF()X9+q@=rLV~w}_BG1qRvͪC AfT* fL9bx!&a!N-1?7vc?B zULInHmޚY2sn#B!4Y@O)~37!͹KAV|x{`s!m Z? ~ ش 0ǨLm!N/?G!L&AקD3 g%Gm2&9haԡC=Z5#e] t 4ێBQE>H@a-x@Mva6 B`)V䊧 6ErpߤU|[^ "l' BYoB  zBp^\2d[6DNh Jd 0 (E4 W &A CW" @eUV6(ppQ9ћL@~Ӷ%HAfB!pj*p9nQ¥M=\](j a !cDd] BELDU2BX2^lΊ4kURd<;l˷賽?;e8uf^#3B>V!P`.Q8kɇ2=%ee!iMQn }S_n@0G ;+3>g?zm F.TwC Ba Ǩm z>jE7 !hӱNbf!YvsvP !!x%xsp <3 mw^l!Qએn@hJ^K%TBgj$ !Pe@`ĊkyB:` av@z; y@`2lrpiՉLB>B!hT2!Lh`Gk(@`\e*I -SA.߁Ѭx/ -!OBLK)R  W5 ^C&F07f6]A6\=/t ±>Wx@^)2(*Hfw 7K=JZK9kos<'T xZ!BA2!j\VšZS]8I%!.1n!\h+B# Y sA< Ydw Nr("m_sZ y&iM1%k KhuUH! Q84 @;Թ.%z±cY D3*A[BpmʿG&koM+L5u]xtT4wjH! h}4% @#! MV FH!2;5g*J1.A9h4*侔܃r `H 3O`! $ߛB2anus8G9i!"˻YAmQHB<0wg/D`P{a\\UuPHҒ ^lׇ\7Z,!x&xasWYV6/3΃(j#iШd/dl-3e [P^ߴ]q,{MGh nCXm0!r~e!X d> va)wKChC,RkG5xuZ2jAuL*bF !6LDpLE9w۬q)SpM<2u{1AR:B}< v)G1e,"{| dtElꗈ!"6>:@}ud`ɸzZ yB`54B\);bQ?^fi0!U !(d]A*( Ui}` YOL=S&L_ShBC2-Jl2<,!7@|rq}ʻP5FE2#f3E> θ*L9Yc["-!ty (G L5@MWDr tS͆rxFMBl;"ui-9>9z['L6@0TŇaB/j =Bm\J`LU\M&+pxbu и\`߆I@(vS"W~ Bd2.@ð(M Br!;nҙ`΍; XB B,,33ՌPj#_C]IZFzφ !T= /A MܒRA2FB‡p>>@ȆS5ߝ!XMYo 6F:#!M 'BGBEg@P_QF(yhBgUYayC!ɚjz 9C(fR B)4 ހPTF'ٔ@!@hq SvV}d&n]:lMEh,A i@Q~C@CzBzR8@kah *:CG枘d[jdJlo@ЇwԖ)[@@!{&- 0&J "oVҬS5FQ-X4'>f !j'4l`@,W ԆjhAQmg B] @Md*UL d@`3׎ 1c2O&6RB`D xd;[ Ƽ _\7uim@A@AAߝ- ؤ dYn!DI p1ͳ1pZX%qq`uku>#/EZ@Q\!Pʯv Em "g1V5f`!D$!%=l%yB*oתW_70uB4&8@L3 ϮfB$fa.y .bQI<h!=A%q@06d1k \fB$> J>H]#7^Jf]c"ٶW6 GH; $R!LEIQ pG<V!_p[Ƹ B?L%& _Z@hkB d 2y7rB؈@u8 #Vd ʐ:z@rtaFu3(@G `arTR#Ut2`\!\@>A( 8@igVϭc@ɲ+@(DO%H4!ZYm3 B" ](JxÏ¢' dpBPψ(BqՑAйF)eȶ&mKxpƐ+XM L*ũB x'tg!p1ͥ&nA9Or  5-L p8Wè[a'] iS!' xˢ&tr=BNB!󻅠\B#zssW`3w &F @ &䩹i$0ܨ@%% 3 g"+Xۛ5U*;L+1(qRT $F<2t9c?']nrbl&!$،ݺz*"*PI@0 as-YlC77Yjc`:qK-}DOנr NQ< h6EȠҳz G>!HlOx&pP;n8A jb Ӧ/.^BPA(4+m%16?zdur .GKF¢0(j)MڈGz7! B-X– {X !>D32>hSJj*о fmP.!"+Ew&#^8U4@'HN}c>=AL VJ ]d£n TjKБ槖@tZrcİPp abޫ w+۫>Bbh%f 9 lH̶i0ֿg[Aoz ]G[fYٞǯ)t7+=wJihBGxMJHCLoaa{{H뗕!gі0wa%o7N`V~CH}2kB_SSϸ te@Hf\7]~z[:7M(kwuU{$; ?8v9۪" #ʚ7RZ- ٕ-pv׆(K0[- -!P!XzA*@BhL"P 9@`4Y3/nqz ו={=,CfRvW ȸhnf u9  AañtķHU`ĝрʫ+*U])qoʁ(ZkBhCNd%(dhD .{d;!pJK|OmZfsЬ&!9( ' hs"UVe7? !gt!}Bj g&hr Պ<./4 ZI:q ZQzg%eYH_'! f2ranZ- P ɴ|Zv+XO= uK?ڵ-ni1! XC i !MY m0tJ37x,g̐-4ۮ=3-C@#?5`luao1V!֫Dp|$ e Hi`؂ƒbhCaKx2pWq&UlTMJ<_h+hC 7 X#:662S UIKz+ 8#`dfkkxrf" ^J;zc-G(!z|btS qkxh,%f&Mn{Koa ! J~k- gCFT8} d]{?r@| >*c"1N@\hF '/{(T?V4·nP&7 SSv=!?0&-<Κ}2t BjO-)/ckjjm!8fM,د19 6@i$i Eb)%xaK.e)GMqNRT9MGkul(?/Xv($+OC(A ,!!BB:ܼXMk69VڡNOK^GT ̕x+UJ%%ˠfVt_'-G[ W rf!.TF|f"@~B˨B 9Pʘfr['y jbi0=!scb!/s65㓱e ##̢. HxBr%4ZCG}*vE=*r”2@>KP ,sX+<@mYl0H(!TGs&!^x{Mw 82C&gQ>eGAС޷ºa{;Hc$Bc0&!8ZQG @<\+:`=}0FZ F9!X,!s]>&+e q,҂2I.A1.F9*;j)~'U&u {Gyv\AUk8F![!tb o~_@i0 ߪKBWp@\SK>&rfK?xK ȯ>#p/-ryuA@T%yx z[dĂB`;P< Brj l>I 8A'Ȕ(riu_O.mb6$L!tQ{~~w!?|/vA107I A.Ad\;AxY-!ύ"-|4@`'ee gۉ=H ja`#*;Z}W A2ZWoH0beQPz1"&QdR(-`bOm P19ZZ[!뜹!``q%țuT,xF +. v"uMT @ d-erQ&i:$rP|rK !P "PfJے!@xf|!U!B>n Vڄ_kROb /hg}d19 ]?^f3xh 5.2n+z z BL8@W)QךEy0S_+  oE*8g'N*FPR$2B:À89= &voL 4?1<!u(^E!01O@ybu>x@1G97ؙeGf Åb1B0V AfQ| @1:lUH^VEtKA2 8oOh'lS2 &B  Hb0W *` Yom!&BrG~+9J<˸{ $h*'wB0 FMQ~sYd2# &#/yayE^U)CGPD ] Q>Ұ_ehN53oW%rB)1ɳً,A 54BB1/B ~$Cxy@2%&KpPL[CGbIJlȹ6ۭbB!.V =GW&B&~ 3veCх*$'k`t Tp 䜘>]uk;0@ #-!ً(.؈s'ϩ.ؑo @0Os~$5L=zgX~[CW:8~GGNG᬴ۊ@=SaT_)A! HI W IDATjmКyY <d:3 բ!~ m˘)Ưy% @?M? tN@`R Ԛ)ThTPI(%]!@onq}03p7M~X.2np$9w/B"MkW) g[ D !@x l?yަ's50A;(.蒱`فm\B(?T*HRT !pEh FOwFyθBH&15_m! Em(!|[ChR=m -MwBy$ 0HEI khW[ B݅ K1Z!6惇9Hz2qb)YR(E=!pF욙Bhheerȏ B!D,s2jBقD1#aZa(xΠF\a/ Y_ЖrnU9d0_r3hVp3Mrě@P*7F^'L#XH<]!%t.F]AZYЬ{Yg4 Q`0@`Z2pB !B !Xv&a xǽN@?=ߖ#w+]J&*XkrT?u x z=GO<"]B6:'.%p<  E A,_!ش8ԃݍ|0(^[Y!- *`[gmg6rEB% fP΄$6#wtEAyU!ĜBI8Cg#c.=BzFD_BEhǨbB `#2c9`]@D@pœkzB D!{b5'5B=MҦ^;G{W ayVqqC`e3,eԩܺRD{!Jьf25wVkM9_[j R.5Ma%0B(7!>~-L Q1gB!@йA g!,K' VawS{j74CN@` H'J8;J=^3@p_D]Bh4@`O\%r(&Tt3/t Uഄ ƷB!Ca\/R*?'riAZ*ҡ[CXVHAFx_C0aۼBˌco3\xa57+9 R, <nC'!jW (IO0S/XՋA 2BRsQؤN sp:AWsu5ղ*t`csE5u%G}Aɚ· G#k4k z×F$M1L AEa5Ό7= xM}MHEjQUefz:B*(,*}Xw<6c@35!~Y]q 3f "蜁Zz.C4n!3Ci_O6B`y3Hu{|T|VO/ ^BQ"8 .Ee+^+O*gr4Bl5G~&3j v B[b@6*!pp`Z%B.8֖`=W!дaDBB#] #)oeN=H׊T}Ę6Ba VS}Đ :A(QOB`}l]b c& :f#{‰",F}CfQBX#v @TsQTl%wS˯"'!H:$j(-ZY R!h)`Hs;Vᦡֻo1Pixf"_N[N.exh: dM ;%ˮg]j)qN2i&lG ?Bпhf$ dCJq {vIq!#3n0䴇` zS!v7+pZ1!PM`܃ p5^|n6"rZ!5 aaBЁ .sw7&@cvB({ v͵m㓛MoFccʴObqp !`+1}h@RteM'!_ۭn;ݾ&k *-<غ}1e@CňSܯ XFLՂfHӔz JIte¡Jz#mx!_ଡ଼BU<>t~cȥ7y#'^TGYE=VXV&f,<;dV3uy3kBhN$k2 Bśжb-ŀJ'-0>6}YӤGsaH vx dG%  !_=;DFS1v|e,ZҤb GM, H&q|+u @P`5G=A!HsI`u<7.6V8< E&5m {btt5`Z  Afa]3EVMcqHw|kp!TQJ4u>+ǛOnu!Dhow >A Dм7@@mX( !UN%\!X ,4/fdMrj\sqCi 6Zf^B3Z *AL.v,&3ofVM.AxX̨!TRdTд: WBQ&(GJZ /G{Z^}wT4Ɯ SB˶^eI$$I%ga!FZBh-Ƙ0rOdo6_@ *#?%eSDC4Q` h7%sn$L>m*_J!jsX{Ql~ݣ(kyY'#^}]jWf.r !u\_@6}'u xhϞ!E;9#w%9rpR0nl#!SJtpKsVG)zE{zk>PȎ);=U=z :BBAЪo=I`S8{X>'BC- mC.C`YB<}!Ԃe\3Uȅ9dQ5 j?# ^hV|^_aF܋3S,ø`M3y@XxD"P2H.V1 ޾y  V1-F>H!:g ż^>) 6 Xv" i-^IWBDM>l kdBh1f,+&!p$FSoЪhKrϋC1ȸC7Ic,N;[5˼+ryKF^D&Q?‚gA7W`+뷃]Ld%#Z:]\#?ړ`%-ryz%6. \P ;0b 3لзu$-جHy|T(njzbZ|JH][꤈@hN% PA|u9[ ̖ٴ`eϊUl ׷*{hYۊܗoľ&-pB _ЗsD(~BXO6&@a7.^h !!;YK`ЗE>Zsk^NCeT, X-ޠOR] ax A_tG޹`;t uz6-`iAꨫ_cZ(%})A( iTHBe6ruʹ7(Qlj)ȝG-uC9)hu=~0Ϛ)`y^$0@909Q=\\ۯ,8Zi&S_ȗ U,&MCZ>eФ->Wz*&C`"}j`1EUpږ7hB5TO#$ .Ei5*K5M5\(ڪJ[ѷ;l Y;P 2*%٣/)0A+:|O Ec OA@:~ӪtiZS#^ VV@mv*[ X*b RvrCp?`tBRU+G;7U2Ȧ?}`yC]H'sdMTdb%B#fAS .2\ go-5bsk )bSB.i= jSV{7u*v -M-D-|@j US5ҒScԵj&p1- d s-V[Y0[m.Q)#~TPE7 Y k An3|+ywSj&z7Ȃ5R &~LcwN-6y`M.a%= 4ƨ'Zg -#%qBfL|h!JvؿZtQ3^82L L]I;P>Uz2#Sa>[e} 2kIll4 A\^"&?| \Sa%=dQUj6N# VH=z#oPk@Ȭ WhAN?/ofsq  &6Չ*gTq2_m'i3mQAj&V\4j{B)- ݶsIl[nAILt Y T prRhlHGkdqj*@?OBǾlUS?S0Ug@\BP#ɕU;FگTGG9u<v:MQ*dhN!dșqYߝ L҃A!.V`m?S$4|M+B*;0~4s Z: ]9>&w@JیmС8xtGXiQY}MUCɏA`"3e'*ϡ*`'Iw*OlvȤ>Cs7 T0xF~t Eg%LHmh !IY\G3 5w Nߠ>u> 7#~eF5G)é9q q]w\PV@?I9ƴ֋!T@!*GU!@"cN}&"- uIt`Sj@#}k[c:6`u0)zW R5BEZȱ; k!x-4fT{gCd9vJW3EE!tҋC(H7gU8]}<5xq  ]c|b- 9y4K)k*j@zȥ-!3DհU$ax T*&/sq9.9z m6;ܨۣ -60zd|㧓O,7@гwBhdpky.89ه49Լnw-B3]޼WQXf iBjBA:AB0H5"]zCiᵋ$cC0n)-ߌ53 6iBʭ@ч( J,n9= FTφU!3@?BKx7Mʵ&49BPV,]} ;$"9B"sZv)(\,i骀Ap֨+[U_A@A݂,#!U2g % QCa<|-ª5w y>bG>M"A܂3HF`^a$QXtYŜ B?i F AFA> wATJm,m?AEcbB  -uRD`R 0 j?* }8ƒh11H?(& ܯ5 !ÉPZUS'JO([i%"x 8i3`z=!Xb*F)g6.Dυ@e~h{P 5oBm2$qdEq`' pjCG"htCHn*1LF"ݽBk28vXXh4nAkԽWښ8eh`ߗ `׃!|!2H4Ae!Req !A95$xg]%(hէ:L}.tPl;!@#Bσir.n-Na N3PAI!d>Ax X6di[uEO+ Chy ЋC !l&= *o+v[rL xe`V`אykW!MӊQ;d'|ín1H* .I/;T־ZW 4Dõ\ A9-fX Bw ]%t`o2!m!p2gqUx/& LUt!5jPCujv4T) REfՋ X#8*vԅjG+YM&v? q1Jv@Xzp B'Yq΃M.nB__aep m+>P( PiI01!P6g)@@).a!_S=7?})S, -kt0 (}f.aY!g&R1L K^×(fxs؆FV?$8QA@R.#:aL ^[LC q 66a[. 4(AO;y| (;,X}p'jiZp!l[wB` =4&(5ڄ0>BJM&)ַWn0ܸ jx&)2f2fvX#7 BیȄM?h@u +:Bޟ!$|?}!dcZJ#VBA]AA(0\mAXp\*A_JNұRI;p7:,4>gvA(5b%F; ; Iz2`m X $uv%ELAnN6\Nk!ax;|I:  kt;aqx?c8iZ\䲝ei+iℽIz2l{PL lI2l4)^Վ] ErX}2l$6\^kt+ɜ)av*]VrKPupBhݬAH:rλ7#;O]=B >e@)uy9M>yl`4Io&S0Bg,Onk !*^My,'[%mmȫr^lyBWA!Y()| &iVz;z~k_3y/VMZe3 ka: nDa(½˞JV ݾ!o[v!CaWs:n}8SVW ,ͦFO@[0ܪ r j`t 5zB(I+b׾^{J 7GWZCطّLda"E!ܧ !oe,a $6Τ>6)'-'8-;ajCV:@[<ݰZ^];7=ps5iRk!:=CIsYbo`C (FB]6)$ keHWxґ*tг\3sk[?uЗtHga D|b+HoS!\g^05Dv"ɒǕ `8QE!x/CSeךLQ92n?ə;ИM 8Ck dO I%*p5!H]; ڀ>p17ބZWP5!Sb=]iFһ2* xc8[&qG/B;-ȥ-e@"$\? "ri k,@ғe@xyŹ2\гjYpF !pC Axʚe Z<op2 0[ DplTj6eTsktF~)۔ap 3{ 8|K¿Dy^FH?~4N/|v`8)E ݀03o<ӗʰ k& Mg9ewIiKAC\dMme5ai-/n/Z 2+ʠ%.?%^+1l]/PF:?6ZZlE9n–&}v4B|`W/0L?4y *}cNN@!>L?}.!1[!$0ʳ čS|J|ƭ\VBkUҊ؎}.1,g |P @w;h:Jf!@~xB@_n8w i~jfwA%m> Y4dZ}.{sxb`mE  Il0~aڑ5B !>&9M@~ãX4v.y/2 > Ql"ޤ966WA0COlK|GKa! ҟ7I)Ǐ˞ Aw@BR VUyV @zt2fc묔]&)A]O{,X~K!$YbBcv_T_Z"mXЏȠ f)m* SӇqAX)_!)j0L|gq'k.CHZ' t׬ wRNBAFYQ0-Ý_=( ܏]S2:3I#:P|f8xLrϮ!LSؓ'M(3>3e@iAK} r\ E k ۚ N晼@ʠF).O&u A˜ _R d6jA _Zi  2a#^]\s|D@i`6?>?xB&jOAȕJ1VR'<T2,.W|Țo4[W) BZ[]-Vv [W)՘ChoD[-JLbKl.]Wa @k!$6i)^Um H\>¨ 'V"*k1^#}+te2V`[ٍ^h 4OyYMͥ*\_ap@OU3J`R B@w2KsTz`_խ;)ghi•hjxGAp6 9:LOq[pZs@_i+_IvE>)lA!z-aBv['!ޣk2F)m(&"؊,p/E 6j^ ~kҙF~rroP w.T_TjJhwF9XM1'.D>’mpa CG 2EpQO*X"pi=˥y#)LpזdCzIO+ziIS.~p_,k/ wd?$NAgZ¥cf!Zץ pхf.!C i ?| ʊśnOUC43GU)egqkGQݪ;R{5HmW Bx|!<@ _/ Bx|!<@ _/ Bx|!<@ _/ Bx|!<@ _/ Bx|!<@ _/ ݄ !@ Մ KCjW/ Bx|!<@:MhIENDB`@=dk"zJ:7q %9ihFB2xZohGwlE4jLcH49S+r_VXBIh$&X JYSd-"R~Ŕ"B Q6_JXB`)p}oev{c ̼߼ 8k& {} SU[w`J@y-(/b@ e7R%@@*B Z+0]JLv1n'Vl(fTKnC }{$Ԯ [U7niϩ^DG4h&U_ i=XMI@yHڷЀ鞷3nK*5o C.C+=XF}h}%?oCw0OQ>_jHT}`ߛ݃_U;]μJZؓ}y6 gF "m`i[Ʌx'}uʱxbc4IiANRBƾCW7[v̱9@c9arSv(p-iA2ئ aO#xT 7Qitw;!2%I $`Wdm̶mk"Ma;Ę<}FWp_HI}z~cDhl\k !1!w y!o1 Ceۘ6sۘ}u5kc1،Qo7Q.}4ſ}VeG9bcӕ>ݤXZ?za"7cI+%٧Emm類}RWL㿊%c*QѿFd `B#ڵxpW4~W<^Μ Zi\aI.?*9?o<gB+U>zɘKF>wqR^,9)^=wol1Op{}|n?hW "1X:ޤFՁy+%: +|Y 'bH:ÿ/qs&֖Bu1{: sF3*坆ӐZC>n2n?bG cCb[ y&~R?1V C^"3 =C~ϐﵼW>j;Nun57Hz Inyi|{Ag̹yhAɨ%lFʾgeT2+g=}x+iފx0.{yb9¼ ^%%uȫǟb]>P9̿̇?,N3=ü7 eƆ|qIdE]3昒W̓N%r&%gGω̳b2!qW2;ïڠ1 O5 %hCk!֡mik6}=hF|A"S9~XZkN?OӹϷAcK([rsČwehiBϯ 7A|x'ߦغ<O} K3H5m(h.vIa0bJi:7{l4~+*L?|p"asfh={!,xU(k'|֩,xa~?}_ j}u=JK= ~ [( : P y Chart MSGraph.Chart.80*Microsoft Graph Chartc Chart MSGraph.Chart.80*Microsoft Graph Chart/ 00DArialBlack0tt0- 0DWingdingsk0tt0- 0 DCourier New0tt0- 010DArial Black0tt0- 0" B .  @n?" dd@  @@`` "** t;-)# " s  _ ('?1V#H 2+6"3 $f\g ' 8-A  "%P'      b % =x# B sU8)1]]^&&  B       "P#&  )#    "! '?%+$#p_h /[ # #  2 *     -&q/)J @S".3+!(  $5''r'+}*&!()YWW`b$AA%p/ib$`e)6ᾢ{d i"$;@=Mo-,Sl b$h'U(6ANƤ1b$Zr4D*ji,i,b$p_3;J$"$k"zJ:7q lf 0e0e    A AԔ 8c8c     ?1 d0u0@Ty2 NP'p<'pA)BCD|E|| "0e@      @ABC DEEFGHIJK5%LMNOPQRSTUWYZ[ \]^_ `abN E5%  N E5%  N F   5%    !"?N@ABC DEFFGHIJK5%LMNOPQRSTUWYZ[ \]^_ `ab ݻ3ff3@8wGʚ;^$8ʚ;g4-d-d` 0@ppp@  <4dddd@x 0t<4BdBd@x 0tv80___PPT10 ?-HotOS XI fMicrodrivers: A New Architecture for Device DriversO  =(22Microdrivers A New Architecture for Device Drivers"3 2&"HotOS XI, 8th May 20072Z   3 IntroductionDevice drivers account for a large fraction of kernel code Over 70% in Linux [Chou et al., 2001] Buggy device drivers are a major source of reliability problems Account for over 85% of Windows XP crashes [Orgovan and Tricker, 2003] ;&AG;ff f@+fff3hChallenging to write and debug Writing a device driver Must handle asynchronous events Must obey kernel programming rules Debugging a device driver Non-reproducible failures Fewer advanced development tools Many drivers written by non-kernel experts`C;+C;+7 Macrokernels <User-space device drivers >But&  Limited by existing kernel/driver interface [Van Maren, 1999] Written expecting local procedure calls New interfaces (e.g., new system calls) New device drivers [Chubb 2004, Leslie et al., 2005] |?(a-f(=ff f;!Best of both worlds: Microdrivers  =pHow to produce a microdriver?  JHow big is the kernel driver?Studied 455 drivers from Linux-2.6.18 Identified critical functions Interrupt handlers Tasklets, bottom-halves Supply/receive data to/from the device Plus the functions that they transitively call Analysis is automatic Uses the call-graph of the device driverlD)1 )K  L  M  N W Mechanics  [Architecture of a microdriver \ Communication,Mechanisms for control and data transfer Control transfer: LRPC [Bershad et al., 1990], Nooks XPC [Swift et al., 2003] Stubs in kerndriver for userdriver functions Upcall and downcall mechanism Data transfer: Copy function arguments Copy shared data structures Synchronization done by object tracker<4'< fff fffK]Object tracking 5jObject tracking: Key challenges  ^RecoveryDetect and recover from failed userdriver Ideally transparent to applications Detection done at interface Parameter checks and timeouts Recovery  compatible with prior work Shadow driver mechanism [Swift et al., 2004] SafeDrive recovery mechanism [Zhou et al., 2006]*$&^*$&   f  f  f     f  f  f&`Benefits  'aImproved fault isolation (bGood common-case performance )cCompatibility with commodity OS *dCompatibility with commodity OS +eEase of driver development X Pragmatics   QGenerating a microdriver UMarshaling annotationsN char *nullterm string; struct net_device *list next; struct pcnet32_rx_head *array( rx_ringsize ) rx_ring; Program analysis algorithms to infer need for annotations ; RPerformance of a microdrivere1000 device driver from Linux-2.6.18 Intel PRO/1000 gigabit network adapter Methodology Split into kerndriver and userdriver Ran both halves in the kernel Used delays to simulate user/kernel crosses Infrastructure is still in construction! Testbed Dual-core 3Ghz Pentium-D machine.t&' "&' " HTCP-send performanceYOpen questionsWill microdrivers improve system reliability in practice? Where are most of the bugs  in the kerndriver or in the userdriver? Will the transition to microdrivers expose otherwise latent bugs in device drivers?6:FT:FT4Microdrivers &  0  ,gSupplementary Material[ 8lObject tracking :m The splitter?Goal: Split the driver at function granularity Inputs: (1) Driver source code; (2) Hints specific to driver family irqreturn_t (int, void*, struct pt_regs*) int (struct sk_buff*, struct net_device*) Algorithm: Static call-graph based Identify and mark functions that match hints Mark functions called by these functions sT#V+>  V;nThe code generatorVGoal: Generate code for the kerndriver, the userdriver, and the runtime library Input: (1) Splitter output; (2) Marshaling annotations char *nullterm string; struct net_device *list next; struct pcnet32_rx_head *array( rx_ringsize ) rx_ring; Program analysis algorithms to infer need for annotationsk:J2 :7k Related workHardware-based isolation schemes Nooks [Swift et al., 2003], Using virtual machines [LeVasseur et al., 2004], Microkernel OSes Language-based isolation SafeDrive [Zhou et al., 2006], XFI [Erlingsson et al., 2006] User-space driver frameworks Fluke [Van Maren, 1999], FUSD [Elson, 2004] Automatic program partitioning Privtrans [Brumley and Song, 2004], Jif/Split [Zdancewic et al., 2001], Coign [Hunt and Scott, 1999] !Z^ZZ=ZZ,Z ZeZ!fff fff fff ff fff f  ffff/   ! #$./01469>   0` 33` Sf3f` 33g` f` www3PP` ZXdbmo` \ғ3y`Ӣ` 3f3ff` 3f3FKf` hk]wwwfܹ` ff>>\`Y{ff` R>&- {p_/̴>?" dd@,?dd@ "  o@ ` n?" dd@   @@``PN    @ ` `pB`B` A(    6X ` `  T Click to edit Master title style! !  0D  `  y9Click to edit Master text styles Second level Third level!   :  00    >*   0\     @*   04 `  @* H  0޽h ? 33D<___PPT10..p6-O Default Design3  0  9'(    0 "`>`   T Click to edit Master title style! !  0  `    W#Click to edit Master subtitle style$ $  0X ^ `  >*   0 ^   @*   0 ^ `  @* H  0޽h ? 33D<___PPT10..i0"6 0 @*(    00m` P%   X*   0`  %  Z* d  c $ ?(K    0 `  0)  RClick to edit Master text styles Second level Third level Fourth level Fifth level!     S  6a P   X*   6@f    Z* H  0޽h ? 3380___PPT10.+{L 8(    08  P%  "  >*   0?"   % "  @*   6G"  P  "  >*   6J"    "  @* H  0޽h ? 3380___PPT10.w`bC 0 ZRP9( (     60` " ``  `  h @L  ( #"@L 4  # lԔ?"6@ NNN?N( @L  R Somesh Jha   @`7  # l`Ԕ?"6@ NNN?N( L  U Michael Swift @`<  # ld`Ԕ?"6@ NNN?N( @ ZArini Balakrishnan @`9  # l"`Ԕ?"6@ NNN?N(  WVinod Ganapathy @`B   Z1?"0@NNN?N( B   Z1?"0@NNN?NL ( L B   Z1?"0@NNN?NB  Z1?"0@NNN?N@@B " Z1?"0@NNN?N( @B # Z1?"0@NNN?NL B % Z1?"0@NNN?N@@L B ' Z1?"0@NNN?N( L @L r  S l+`P `p `   0,`  0  p<Computer Sciences Department University of Wisconsin-Madison=Z=H  0޽h ? 33___PPT10i.zP+D='  = @B +2   0 `9\(  x  c $t`` `  `   c $u` `<$D 0 ` H  0޽h ? 33___PPT10.i0[b+YD'  = @B Du' = @BA?%,( < +O%,( < +D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*;a%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*b%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(+N   0  ?8(  8x 8 c $`` `  `  8 c $` ` <$@ 0 ` 8 8 3 rp`Ԕ?"6@`NNN?N X$Device drivers are hard to get right%%$H 8 0޽h ? 33___PPT10.R U+ED'  = @B DQ' = @BA?%,( < +O%,( < +DL' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8\v%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8v%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8%(+M  0 9IP(  r  S `` `  ` B   `DԔ?"0@NNN?N R8  pp   # l1?"6@`NNN?N(  C x`1?"6@`NNN?N  :Kernel  # l`1?"6@`NNN?N0 0 P  :DriverB   # lDԔ?"0@NNN?N  F8  P p .0 @P   # l`Ԕ?"6@ NNN?N` Pp :Device # # l1?"6@`NNN?N P p - # l`1?"6@`NNN?N 0  :DriverB 3 # lDԔ?"0@NNN?N  HF  P p 4  @ 5  f`Ԕ?"6@ NNN?N` Pp :Device 6  f1?"6@`NNN?N P pB 7 # lDԔ?"0@NNN?NP B 8 # lDԔ?"0@NNN?N 0 B 9 # lDԔ?"0@NNN?N 0 0F ` 0  = PP >  f1?"6@`NNN?N  p  ?  f1?"6@`NNN?N  " @ # lH(1?"6@`NNN?N`P @0  @ Applications  | A # l `Ԕ?"6@`NNN?NJ1 ,$D 0 n,L Poor fault isolation&$$ I C (Aladybug P ,$D 0 F  fAԔ?"6@ NNN?N ,$D 0H  0޽h ? 33SK___PPT10+.p>++}PD'  = @B D' = @BA?%,( < +O%,( < +DA' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*A%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*I%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*F%(+8+0+A0 +$  0 G? :'R0 (  TF  P pp Q  f1?"6@`NNN?N" R 3 r`1?"6@`NNN?N  :KernelB $  `DԔ?"0@NNN?N x  c $`` `  `   # l`1?"6@`NNN?N@ P :DriverHF  P p   0 @P     fd`Ԕ?"6@ NNN?N` Pp :Device    f1?"6@`NNN?N P p   # l`1?"6@`NNN?N PP :Driver   # l`1?"6@`NNN?N   ;RuntimeHF  P p   @   fl`Ԕ?"6@ NNN?N` Pp :Device   f1?"6@`NNN?N P p8 Pp  *Pp B   fDԔ?"0@NNN?Np p B  # lDԔ?"0@NNN?NPp 0F ` 0   PP   f1?"6@`NNN?N  p    f1?"6@`NNN?N  "  # l`1?"6@`NNN?N`P @0  @ Applications  B % # lDԔ?"0@NNN?NP B )@ # lDԔ?"0@NNN?NP @ z  `  =  p ,$D 0B > HD0?"0@NNN?N ` B ?B HD0?"0@NNN?N ` 8  0  M 0 B A # lDԔ?"0@NNN?N  B B  fDԔ?"0@NNN?N 0B C  fDԔ?"0@NNN?N00 B DB # lDԔ?"0@NNN?N@ 0 8 P00  LP00 B J  fDԔ?"0@NNN?NP0B K  fDԔ?"0@NNN?N000  O C (Aladybug@ `,$D 0z  `  : P` P,$@ 0B ; HD0?"0@NNN?N ` B <B HD0?"0@NNN?N ` H  0޽h ? 33^V___PPT106.p>+(D '  = @B D' = @BA?%,( < +O%,( < +D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*O%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*:%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*=%(+  0 @:d(  r  S 8` `     S 8 `<$@ 0  t  # lԔ?"6@`NNN?Nd,$D 0 f$L Poor performance&$$  # l`Ԕ?"6@`NNN?N  ,$D 0 @L Incompatible with commodity OS&!$$H  0޽h ? 33  ___PPT10 .օO}+MD( '  = @B D ' = @BA?%,( < +O%,( < +DA' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*%(DA' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*?%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*?g%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*i%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(+p+0+0 ++0+0 +@  0 ##:)?0 9#(  TF  3 pp 4  f1?"6@`NNN?N" 5 3 r`1?"6@`NNN?N  :KernelB .  `DԔ?"0@NNN?N x  c $"`   0F ` 0   PP   f1?"6@`NNN?N  p    f1?"6@`NNN?N  "  # l '1?"6@`NNN?N`P @0  @ Applications     # l,1?"6@`NNN?N` p  > Kerndriver  B   # lDԔ?"0@NNN?N0 0 ,$@ 0HF  P p    @    f0Ԕ?"6@ NNN?N` Pp :Device   f1?"6@`NNN?N P p,l PPp  /PPp ,$@ 0B  # lDԔ?"0@NNN?NPPP B  # lDԔ?"0@NNN?NP p    # l51?"6@`NNN?NPp  > Userdriver   ! # l:1?"6@`NNN?Np  ;Runtime # # l=1?"6@`NNN?N p `  ;RuntimeB $ # lDԔ?"0@NNN?N  ,$@  0B % # lDԔ?"0@NNN?N  ,$@  0,l  0  + 0 ,$@ 0B & # lDԔ?"0@NNN?N00 B 'B # lDԔ?"0@NNN?N 0,l Pp  *Pp ,$@  0B ( # lDԔ?"0@NNN?NP B ) # lDԔ?"0@NNN?N p / , # lBԔ?"6@`NNN?Np U!Split device driver functionality""$l  aP  2 aP ,$D 0 0 3 rԔ?"6@`NNN?N P P ' 1 3 rHԔ?"6@`NNN?N( Pa ? Microdriver  l  p@  9  ,$@ 0< 6 # lLԔ?"6@`NNN?N p  Z"Performance-critical functionality##B 8B  fD)?"0@NNN?N @ l   = ,$D  0G ; 3 rlQݻԔ?"6@`NNN?N  _'Startup, shutdown, device configuration((B < # lD)?"0@NNN?N M > # lDԔ?"6@`NNN?NL ,$@ 0 ? Common case  K ? # lNԔ?"6@`NNN?NP ,$D 0 = Rare case  H  0޽h ? 33___PPT10.p>+iD'  = @B D' = @BA?%,( < +O%,( < +D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*2%(D' =%(Df' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*9%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*2%(D' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*/%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* %(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*>%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*9%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*=%(D ' =%(D: ' =%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*=%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<**%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*$%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*+%(D' =A@BBBB0B%(D' =1:Bhidden*o3>+B#style.visibility<*>%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*?%(++0+>0 ++0+>0 ++0+?0 +l  0L0 k c `@p (  px p c $``     p # lp1?"6@`NNN?NPP > Userdriver   p # ldu1?"6@`NNN?NP  ;RuntimeB p # lDԔ?"0@NNN?N pp B p # lDԔ?"0@NNN?N  3  p # l,tԔ?"6@`NNN?Np{ Y%Use program analysis & transformation&&$'  p # lL~1?"6@`NNN?NP  MTraditional device driverM"  p C xԔ?"6@`NNN?NPpP  gSplitter and Code generator0B  p  fDԔ?"0@NNN?NB  p  fDԔ?"0@NNN?NpP@B p  fDԔ?"0@NNN?N` pPp  p # l䉨1?"6@`NNN?N P`  > Kerndriver   p # l41?"6@`NNN?N P  ;RuntimeH p 0޽h ? 33___PPT10i.p>+D='  = @B +  0 ;8\(  8x 8 c $D``     8 c $D `<$@ 0  H 8 0޽h ? 33  ___PPT10f .0@+ED: '  = @B D ' = @BA?%,( < +O%,( < +Dd' =%(D ' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8&D%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8DW%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8Wo%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8o%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*8%(+  0 ; @~(  @V @ C .Aorig-graph*z @  @ @ ,$@ 0 @ 3 rԔ?"6@`NNN?N@ -2 @ 3 r<Ԕ?"6@`NNN?N` p Ee100_xmit_frame12 @ C xtԔ?"6@`NNN?N` @ C e100_exec_cmdB @  fDԔ?"0@NNN?N B @ # lD|?"0@NNN?N  ,$D 0* z `P   @ `P ,$D 0  @  0e0e    BpCDEF Ԕ 8c8c     ?1 d0u0@Ty2 NP'p<'pA)BCD|E||(P`@ph`@  "0e@`     @ABC DEFGHIJK5%LMNOPQRSTUWYZ[ \]^_ `abN 5%  N 5%  N    5%    !"?N@ABC DEFGHIJK5%LMNOPQRSTUWYZ[ \]^_ `ab P 2  @ # lԔ?"6@`NNN?NP P 2  @ # lԔ?"6@`NNN?N`H @ 0޽h ? 33^V___PPT106.`a"+cn_D '  = @B D' = @BA?%,( < +O%,( < +D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* @%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*@%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*@%(+c  0 zr; D (  DR D C *Apre-prop* F `P  D `P  D  0e0e    BpCDEF Ԕ 8c8c     ?1 d0u0@Ty2 NP'p<'pA)BCD|E||(P`@ph`@  "0e@`     @ABC DEFGHIJK5%LMNOPQRSTUWYZ[ \]^_ `abN 5%  N 5%  N    5%    !"?N@ABC DEFGHIJK5%LMNOPQRSTUWYZ[ \]^_ `ab P 2 D # lԔ?"6@`NNN?NP P 2 D # lԔ?"6@`NNN?N`zF @  D @  D 3 rԔ?"6@`NNN?N@ -2  D 3 rԔ?"6@`NNN?N` p Ee100_xmit_frame12  D C xԔ?"6@`NNN?N` @ C e100_exec_cmdB  D  fDԔ?"0@NNN?N H D 0޽h ? 33___PPT10i.`a"+D='  = @B +)  0 V$N$<##H#(  HV H C .Aafter-prop* F `P  H `P  H  0e0e    BpCDEF Ԕ 8c8c     ?1 d0u0@Ty2 NP'p<'pA)BCD|E||(P`@ph`@  "0e@`     @ABC DEFGHIJK5%LMNOPQRSTUWYZ[ \]^_ `abN 5%  N 5%  N    5%    !"?N@ABC DEFGHIJK5%LMNOPQRSTUWYZ[ \]^_ `ab P 2 H # lԔ?"6@`NNN?NP P 2 H # lԔ?"6@`NNN?N`z p H p,$@ 02 H # lԔ?"6@`NNN?NP p 2  H # lԔ?"6@`NNN?N @ 2  H # lԔ?"6@`NNN?NP @ 2  H # lԔ?"6@`NNN?N 2  H # lԔ?"6@`NNN?N@2  H # lԔ?"6@`NNN?NP p 2 H # lԔ?"6@`NNN?NP P 2 H # lԔ?"6@`NNN?N ` 2 H # lԔ?"6@`NNN?NP ` 2 H # lԔ?"6@`NNN?N@`2 H # lԔ?"6@`NNN?N  2 H # lԔ?"6@`NNN?N  2 H # lԔ?"6@`NNN?N@  2 H # lԔ?"6@`NNN?N  2 H # lԔ?"6@`NNN?N  P @ 2 H # lԔ?"6@`NNN?N  p @ 2 H # lԔ?"6@`NNN?N  0 @ 2 H # lԔ?"6@`NNN?NpP 2 H # lԔ?"6@`NNN?N P 0 2 H # lԔ?"6@`NNN?N`  @ 2 H # lԔ?"6@`NNN?N  p@ 2 H # lԔ?"6@`NNN?N P @ 2 H # lԔ?"6@`NNN?N @zF @  H @   H 3 rԔ?"6@`NNN?N@ -2 !H 3 rԔ?"6@`NNN?N` p Ee100_xmit_frame12 "H C x$ŨԔ?"6@`NNN?N` @ C e100_exec_cmdB #H  fDԔ?"0@NNN?N H H 0޽h ? 33 ___PPT10.`a"+ѥD'  = @B D' = @BA?%,( < +O%,( < +D' =%(Df' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*H%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*H%(+  0 <L(  L L0  `A y? ?D y  L 6|b ` 4 In-kernel driver code is reducedH L 0޽h ? 33___PPT10i.+D='  = @B +   0  =(  x  c $@f `   H  0޽h ? 33___PPT10i.+D='  = @B +   0 =5=*(  TF   pp   f1?"6@`NNN?N"  3 r4l1?"6@`NNN?N  :KernelB   `DԔ?"0@NNN?N x  c $8Z``    0F ` 0   PP   f1?"6@`NNN?N  p     f1?"6@`NNN?N  "   # ldp1?"6@`NNN?N`P @0  @ Applications  B   # lDԔ?"0@NNN?N0 0 HF  P p    @    fsԔ?"6@ NNN?N` Pp :Device   f1?"6@`NNN?N P pB   fDԔ?"0@NNN?NPPP B   fDԔ?"0@NNN?N Pp   # llx1?"6@`NNN?NPp  > Userdriver    # l 1?"6@`NNN?Np  ;RuntimeB  # lDԔ?"0@NNN?N  B  # lDԔ?"0@NNN?N  F  0    0 B  # lDԔ?"0@NNN?N00 B B # lDԔ?"0@NNN?N 0F Pp   Pp B  # lDԔ?"0@NNN?NP B  # lDԔ?"0@NNN?N p  (  fԔ?"6@`NNN?N0  ,$D 0 7Responsibilities Communication Object tracking Recovery0''8X ) # l؎1?"6@`NNN?N` p  > Kerndriver   * # l|+1?"6@`NNN?N p `  ;Runtime ' C xL)?"6@`NNN?N ,$D 0H  0޽h ? 33___PPT10.p>+DcD'  = @B DF' = @BA?%,( < +O%,( < +D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*'%(DA' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*(%(+8+0+(0 +   0 >P(  r  S $` `     S ̛ `<$@ 0  H  0޽h ? 33___PPT10.m+EDv'  = @B D1' = @BA?%,( < +O%,( < +D' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*)<%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*<x%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*x%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(DL' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*-%(+P  0 Z7R70>>|$ 6(     # ll1?"6@`NNN?N0 > Userdriver  >l P P@ e)P Py ,$D  02 \ C xԔ?"6@`NNN?NP@B ] # lDԔ?"0@NNN?NP 0  # l4#1?"6@`NNN?Np > Kerndriver  >l  0 @ b0 0 ,$@  02 P C xԔ?"6@`NNN?N `@B Q # lDԔ?"0@NNN?N@0 r  S P` `   r  S  `  dp  `  . #""r (  # lLԔ?"6@ NNN?N   F @`(  # lɮԔ?"6@ NNN?N   F @`(  # lD̮Ԕ?"6@ NNN?N   F @`(  # lخԔ?"6@ NNN?N   F @`5  # lԔ?"6@ NNN?N 3  S0x248 @`5  # lԔ?"6@ NNN?N 3  S0x196 @`5  # lԔ?"6@ NNN?N ` 3 S0x512 @`5   # lԔ?"6@ NNN?N ` 3 S0x128 @`B  Zo ?"0@NNN?N ` `B  T1 ?"0@NNN?N 3 3B  T1 ?"0@NNN?N  B  T1 ?"0@NNN?N  B  Zo ?"0@NNN?N  B  Zo ?"0@NNN?N ` B  T1 ?"0@NNN?N ` B  Zo ?"0@NNN?N `  2 1 3 r ?"6@`NNN?N ,$D 0Gl y   : P ,$@ 02 2 # lԔ?"6@`NNN?Npp  2 3 # lԔ?"6@`NNN?Np  2 4 # lԔ?"6@`NNN?Np @ B 5  fDԔ?"0@NNN?N  B 6  fDԔ?"0@NNN?N  # 7 3 rԔ?"6@ NNN?Ny M  ;0x128# 8 3 rHԔ?"6@ NNN?NXy MM  ;0x196# 9 3 rp Ԕ?"6@ NNN?Ny M  ;0x202ll    A ,$@ 0 ; 3 rԔ?"6@`NNN?N  B <  `DԔ?"0@NNN?N  B =  `DԔ?"0@NNN?N  B >  `DԔ?"0@NNN?N@ @ B ?  `DԔ?"0@NNN?N  B @  `DԔ?"0@NNN?N  B B  fD ?"0@NNN?N  ,$@  0L C 3 rԔ?"6@ NNN?N @,$  0 8Upcalll A6  M A6 ,$@ 02 E 3 rԔ?"6@ NNN?Nw ) J C x8Ԕ?"6@ NNN?NA6T ;0x512il v  N ~ ,$@ 02 F 3 rԔ?"6@ NNN?Nw( B H # lDԔ?"0@NNN?N  ) K C xԔ?"6@ NNN?NvT ;0x248il (  O ( ,$D 02 G 3 rԔ?"6@ NNN?Nwh B I # lDԔ?"0@NNN?N(  ) L C xԔ?"6@ NNN?NT ;0x296~8  w  l  w  j  ft Ԕ?"6@ NNN?N   ;0x202 k  f$Ԕ?"6@ NNN?Np w  ;0x2960 w # ld(Ԕ?"6@`NNN?Ns  V"Synchronize shared data structures##$H  0޽h ? 33%___PPT10.F+DD'  = @B DT' = @BA?%,( < +O%,( < +D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*1%(Db' =%(D ' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*:%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*1%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*M%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*N%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*O%(DY' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*A%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*B%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*C%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*b%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*e%(D' =%(Dd' =%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*b%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*e%(+8+0+C0 +!  0 ?XD7(  Dx D c $T` `   x D c $, `   WD 0  `,$@ 0 * Challenging cases Locks Device memory and registers DMA memory Solution Userdriver must synchronize and update version seen by the kerndriverL- F- F,I 1 9 XD 3 rԔ?"6@`NNN?NvP Y%Memory objects with special semantics&&"H D 0޽h ? 33"  ___PPT10 .F+*D '  = @B D ' = @BA?%,( < +O%,( < +D' =%(%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*WD%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*WD%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*WD5%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*WD5@%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*WD@I%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*WDI%(+   0 @>P(  r  S ,` `     S , `<$@ 0  H  0޽h ? 33v n ___PPT10N .-+ED" '  = @B D ' = @BA?%,( < +O%,( < +D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*Nk%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*k%(DL' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* %(+   0  >(  x  c $P9  `   H  0޽h ? 33___PPT10i.+D='  = @B +v(  0 ph>$)(  TF   pp   f1?"6@`NNN?N"  3 rڨ1?"6@`NNN?N  :KernelB   `DԔ?"0@NNN?N x  c $` `   0F ` 0   PP   f1?"6@`NNN?N  p     f1?"6@`NNN?N  "   # l`1?"6@`NNN?N`P @0  @ Applications  B   # lDԔ?"0@NNN?N0 0 HF  P p    @    f`Ԕ?"6@ NNN?N` Pp :Device   f1?"6@`NNN?N P pB   fDԔ?"0@NNN?NPPP B   fDԔ?"0@NNN?N Pp   # l\@ 1?"6@`NNN?NPp  > Userdriver    # l 1?"6@`NNN?Np  ;RuntimeB  # lDԔ?"0@NNN?N  B  # lDԔ?"0@NNN?N  F  0    0 B  # lDԔ?"0@NNN?N00 B B # lDԔ?"0@NNN?N 0F Pp   Pp B  # lDԔ?"0@NNN?NP B  # lDԔ?"0@NNN?N p z  `    p ,$D 0B  HD0?"0@NNN?N ` B B HD0?"0@NNN?N `    C (Aladybug  ,$@ 0z  `  !   ,$@ 0B " HD0?"0@NNN?N ` B #B HD0?"0@NNN?N ` f $ # l$L Ԕ?"6@`NNN?Np,$D 0 X$Fewer lines of in-kernel driver code%%$ ( # lpQ 1?"6@`NNN?N` p  > Kerndriver   ) # lP 1?"6@`NNN?N p `  ;RuntimeH  0޽h ? 33  ___PPT10 .p>+D '  = @B D ' = @BA?%,( < +O%,( < +DA' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*$%(D' =%(Ds' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* %(D' =A@BBBB0B%(D' =1:Bhidden*o3>+B#style.visibility<*$%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*!%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(+p+0+$0 ++0+$0 +!!  0 > %(  TF   pp   f1?"6@`NNN?N"  3 rb 1?"6@`NNN?N  :KernelB   `DԔ?"0@NNN?N x  c $(f `    0F ` 0   PP   f1?"6@`NNN?N  p     f1?"6@`NNN?N  "   # lDh 1?"6@`NNN?N`P @0  @ Applications  B   # lDԔ?"0@NNN?N0 0 HF  P p    @    fm Ԕ?"6@ NNN?N` Pp :Device   f1?"6@`NNN?N P pB   fDԔ?"0@NNN?NPPP B   fDԔ?"0@NNN?N Pp   # l,r 1?"6@`NNN?NPp  > Userdriver    # lv 1?"6@`NNN?Np  ;RuntimeB  # lDԔ?"0@NNN?N  B  # lDԔ?"0@NNN?N  F  0    0 B  # lDԔ?"0@NNN?N00 B B # lDԔ?"0@NNN?N 0F Pp   Pp B  # lDԔ?"0@NNN?NP B  # lDԔ?"0@NNN?N p d   # ld| Ԕ?"6@`NNN?Np,$D 0 V"User/kernel crosses are infrequent##$z  p@  !  p ,$D 0< " # l4 Ԕ?"6@`NNN?N p  Z"Performance-critical functionality##B #B  fD)?"0@NNN?N @  $ # l̆ 1?"6@`NNN?N` p  > Kerndriver   % # l 1?"6@`NNN?N p `  ;RuntimeH  0޽h ? 337/___PPT10.p>+]>D'  = @B Df' = @BA?%,( < +O%,( < +Da' =%(%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<* %(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*!%(+8+0+ 0 +  0 > t(   TF    pp    f1?"6@`NNN?N"   3 r$ 1?"6@`NNN?N  :KernelB    `DԔ?"0@NNN?N x   c $< ``    0F ` 0    PP    f1?"6@`NNN?N  p     f1?"6@`NNN?N  "   # lX 1?"6@`NNN?N`P @0  @ Applications  B   # lDԔ?"0@NNN?N0 0 HF  P p    @     f Ԕ?"6@ NNN?N` Pp :Device    f1?"6@`NNN?N P pB    fDԔ?"0@NNN?NPPP B    fDԔ?"0@NNN?N Pp    # l@ 1?"6@`NNN?NPp  > Userdriver     # lL 1?"6@`NNN?Np  ;RuntimeB   # lDԔ?"0@NNN?N  B   # lDԔ?"0@NNN?N  F  0     0 B   # lDԔ?"0@NNN?N00 B  B # lDԔ?"0@NNN?N 0F Pp    Pp B   # lDԔ?"0@NNN?NP B   # lDԔ?"0@NNN?N p B    `D$?"0@NNN?N  ,$@ 0f   # ll Ԕ?"6@`NNN?NpC7,$D 0 X$Kernel/driver interface is unchanged%%$   # lD 1?"6@`NNN?N` p  > Kerndriver     # l 1?"6@`NNN?N p `  ;RuntimeH   0޽h ? 33g____PPT10?.p>+B>wD'  = @B D' = @BA?%,( < +O%,( < +D' =%(Du' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* %(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<* %(+8+0+ 0 +w"  0 $?%'(  TF   p`   f1?"6@`NNN?N"  3 r 1?"6@`NNN?N X :KernelB   `DԔ?"0@NNN?N x  c $ ``    0F ` 0   PP   f1?"6@`NNN?N  p     f1?"6@`NNN?N  "   # l 1?"6@`NNN?N`P @0  @ Applications  B   # lDԔ?"0@NNN?N0 0 HF  P p    @    f Ԕ?"6@ NNN?N` Pp :Device   f1?"6@`NNN?N P pB   fDԔ?"0@NNN?NPPP B   fDԔ?"0@NNN?N Pp   # l| 1?"6@`NNN?NPp  > Userdriver    # l 1?"6@`NNN?Np  ;RuntimeB  # lDԔ?"0@NNN?N  B  # lDԔ?"0@NNN?N  F  0    0 B  # lDԔ?"0@NNN?N00 B B # lDԔ?"0@NNN?N 0F Pp   Pp B  # lDԔ?"0@NNN?NP B  # lDԔ?"0@NNN?N p f  # l Ԕ?"6@`NNN?Np,$D 0 X$Can coexist with traditional drivers%%$HF  P p   @   f Ԕ?"6@ NNN?N` Pp :Device    f1?"6@`NNN?N P p ! # lp 1?"6@`NNN?N p  :DriverB " # lDԔ?"0@NNN?N@ @F P p@ #  Pp@B $  fDԔ?"0@NNN?NP@p@B %  `DԔ?"0@NNN?NP P@ & # l, 1?"6@`NNN?N` p  > Kerndriver   ' # l 1?"6@`NNN?N p `  ;RuntimeH  0޽h ? 33___PPT10.p>+(Do'  = @B D*' = @BA?%,( < +O%,( < +Da' =%(%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*%(+8+0+0 ++  0 YQ ?&((  TF   pp   f1?"6@`NNN?N"  3 r 1?"6@`NNN?N  :KernelB   `DԔ?"0@NNN?N x  c $ ``    0F ` 0   PP   f1?"6@`NNN?N  p     f1?"6@`NNN?N  "   # l 1?"6@`NNN?N`P @0  @ Applications  B   # lDԔ?"0@NNN?N0 0 HF  P p    @    f  Ԕ?"6@ NNN?N` Pp :Device   f1?"6@`NNN?N P pB   fDԔ?"0@NNN?NPPP B   fDԔ?"0@NNN?N Pp   # lL 1?"6@`NNN?NPp  > Userdriver    # l 1?"6@`NNN?Np  ;RuntimeB  # lDԔ?"0@NNN?N  B  # lDԔ?"0@NNN?N  F  0    0 B  # lDԔ?"0@NNN?N00 B B # lDԔ?"0@NNN?N 0F Pp   Pp B  # lDԔ?"0@NNN?NP B  # lDԔ?"0@NNN?N p 9  # l Ԕ?"6@`NNN?N _+More tools available for driver development,,   # l ݻԔ?"6@`NNN?N` ,$D 0 *gdb,gprof, valgrind,& $ B   fDԔ?"0@NNN?N@ ,$@ 0B  @  fDԔ?"0@NNN?N`  ,$@ 0z  `  !  ` ,$D 0B " HD?"0@NNN?N ` B #B HD?"0@NNN?N ` z 0  $ 00P,$D 0B % HD?"0@NNN?N0@B &B HD?"0@NNN?N  ' # l 1?"6@`NNN?N` p  > Kerndriver   ( # l# 1?"6@`NNN?N p `  ;RuntimeH  0޽h ? 33k c ___PPT10C .p>+0D '  = @B D ' = @BA?%,( < +O%,( < +DA' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*$%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* %(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*!%(+8+0+0 +   0  =(  x  c $x1  `   H  0޽h ? 33___PPT10i.+D='  = @B +D  0 VN<p(  px p c $ ``    L p # l|* 1?"6@`NNN?N0 @ ,$@ 0 > Userdriver  I p # lh1?"6@`NNN?N @,$@ 0 ;Runtime\  p # lN1?"6@`NNN?Np ,$D 0 NTraditional device driverV"  p C x Ԕ?"6@`NNN?N` P ,$D 0 <Splitter  B  p@  fDԔ?"0@NNN?N  ,$@  0B p  fDԔ?"0@NNN?N 0  ,$@ 0B p  fDԔ?"0@NNN?Np p ,$@ 0\ p # l` 1?"6@`NNN?N  ,$@ 0 NTraditional device driverB p  fDԔ?"0@NNN?Np p ,$@ 0\" p C x Ԕ?"6@`NNN?N  ,$D  0 BCode generatorB p  fDԔ?"0@NNN?N p p ,$@  0X p  &h0e0e    BCPDEXF(  8c8c     ?1 d0u0@Ty2 NP'p<'pA)BCD|E||PPPpP(PPP P P`P8 P@       "0e@`     @ABC DEFGHIJK5%LMNOPQRSTUWYZ[ \]^_ `abN 5%  N 5%  N    5%    !"?N@ABC DEFGHIJK5%LMNOPQRSTUWYZ[ \]^_ `ab0p,$@ 0R p  f1?"6@`NNN?N 0 ,$D 0 JMarshaling annotationsB p  fDԔ?"0@NNN?N 0 ,$@ 0F p # l Ԕ?"6@`NNN?Nz,$D  0 8KernF p # l Ԕ?"6@`NNN?N,$@  0 8UserL p # l0 1?"6@`NNN?N @,$D 0 > Kerndriver  I p # l 1?"6@`NNN?N  ,$@ 0 ;RuntimeH p 0޽h ? 33&&___PPT10%.p>+B2D&#'  = @B D"' = @BA?%,( < +O%,( < +DA' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<* p%(Df' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<* p%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<* p%(D' =%(D3' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =%(Du' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D$ ' =%(D ' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* p%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =%(Du' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*p%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*p%(++0+p0 ++0+p0 ++0+ p0 ++0+ p0 ++0+ p0 ++0+p0 ++0+p0 ++0+p0 ++0+p0 ++0+p0 ++0+p0 ++0+p0 +   0 P=(  r  S x ` `     S x <$D 0   =  3 rdԔ?"6@`NNN?N#AN ])Need to serialize complex data structures**#H  0޽h ? 33J B ___PPT10" .p+YD '  = @B D ' = @BA?%,( < +O%,( < +D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*7%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*7m%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*n%(+  0 <P(  r  S % ` `     S -  `<$@ 0   H  0޽h ? 33___PPT10.*Ȧ+ED'  = @B Dm' = @BA?%,( < +O%,( < +D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*&%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*&M%(D' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*MY%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*Y~%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*~%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(+T  0  ~ ;  (  r  S l4 ` `    0 ZA c? ?V_) c  l 0   0,$@ 0;  C x: Ԕ?"6@`NNN?N0 0P  M60 million machine cyclesB   # lDԔ?"0@NNN?N0P l  0 ` ,$@ 0*  C x7 Ԕ?"6@`NNN?N 0 <26% rise  B  # lDԔ?"0@NNN?Nwl   P  P,$D 0%  3 rC Ԕ?"6@`NNN?N P = 6.8% drop  B   fDԔ?"0@NNN?N   # lԔ?"6@`NNN?Nppp ,$D 0\  3 rG Ԕ?"6@`NNN?N ?z,$@ 0 HRelative performance  3 rxK Ԕ?"6@`NNN?N,$D 0 t@Delay to simulate cost of user/kernel crossing (in microseconds)AAH  0޽h ? 33vn___PPT10N.?+D'  = @B Dm' = @BA?%,( < +O%,( < +D' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =%(Df' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(+p+0+0 ++0+0 +v    0 =P(  r  S \ ` `     S 0] <$@ 0   H  0޽h ? 33^V___PPT106.P +ED '  = @B D' = @BA?%,( < +O%,( < +D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*:%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*:%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(+5  0`L0  p9(     fԔ?"6@`NNN?N 0`@,$@ 0   fԔ?"6@`NNN?N`  ,$@  0   fԔ?"6@`NNN?NP,$@ 0   fԔ?"6@`NNN?N ,$@  0   fԔ?"6@`NNN?N`,$@ 0    fԔ?"6@`NNN?N,$@ 0x  c $g ` `   t  # ll Ԕ?"6@`NNN?N6 ,$ 0 f2& improve fault isolation  # lp Ԕ?"6@`NNN?N9j,$ 0 zF& have good common-case performance$$  # lt Ԕ?"6@`NNN?N  ,$  0 |H& are compatible with commodity OSes%%  # lHy Ԕ?"6@`NNN?N P,$ 0 R& reduce the amount of code in the kernel**   # lz Ԕ?"6@`NNN?NL  ,$ 0 v& permit the use of user-mode tools for driver development<<   # lX Ԕ?"6@`NNN?N `V@,$ 0 ~& can be generated largely automatically from existing drivers@@H  0޽h ? 33##___PPT10l#.i0[b+D!'  = @B D!' = @BA?%,( < +O%,( < +D' =%(Du' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*%(DW' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* %(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*%(DW' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<* %(DW' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*%(DW' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<* %(DW' =%(D' =%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<* %(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*%(D2' =%(D' =%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*%(+P+0+0 ++0+0 ++0+0 ++0+0 ++0+ 0 ++0+ 0 + 0 9.(  p `0  + #""rL Z`P =   # lH Ԕ?"6@ NNN?Np 8 0  [jha@cs.wisc.edu @`4   # ll Ԕ?"6@ NNN?N8 p  R Somesh Jha   @`o   # l Ԕ?"6@ NNN?Np 08  swift@cs.wisc.edu 0 @`7   # l Ԕ?"6@ NNN?Np 8  U Michael Swift @`p   # lh Ԕ?"6@ NNN?Np 0 arinib@cs.wisc.edu 0 @`<  # l Ԕ?"6@ NNN?Np  ZArini Balakrishnan @`l  # ld Ԕ?"6@ NNN?Np `0 vg@cs.wisc.edu 0 @`9  # lh Ԕ?"6@ NNN?N`p  WVinod Ganapathy @`B  Zo?"0@NNN?N`p `B  Zo?"0@NNN?N p B  Zo?"0@NNN?N`B  Zo?"0@NNN?N0`0B  Zo?"0@NNN?Np `0`B  Zo?"0@NNN?NB   Zo?"0@NNN?N00B " Zo?"0@NNN?N8 B $ Zo?"0@NNN?N008 B & Zo?"0@NNN?N8  B ( Zo?"0@NNN?N08 0 B * Zo?"0@NNN?Np 0  , 0  " ``  p2Microdrivers A New Architecture for Device Drivers"3 2&" . 0   0 p<Computer Sciences Department University of Wisconsin-Madison=Z=H  0޽h ? 33___PPT10i.O+D='  = @B +A  0L0 @8?4(  4 4  6 "`   H 4 0޽h ? 33___PPT10i.R+D='  = @B ++  0L0 II@VV\H(  \:z  0 0 \  ,$D 02 \ # lԔ?"6@`NNN?Np0B \  fDԔ?"0@NNN?N 0 p \ # l1?"6@`NNN?N0 > Userdriver  @z P P@ \ )P Py ,$D  02 \ 3 rԔ?"6@`NNN?NP@B \  fDԔ?"0@NNN?NP 0@z P @  \ P y ,$D 02  \ 3 rԔ?"6@`NNN?NP@B  \  fDԔ?"0@NNN?NP p@z P p@  \ P  ,$D 02  \ 3 rԔ?"6@`NNN?N@B \  fDԔ?"0@NNN?NP p \ # l 1?"6@`NNN?Np > Kerndriver  @z  0 @ \ 0 0 ,$D  02 \ 3 rԔ?"6@`NNN?N `@B \  fDԔ?"0@NNN?N@0 :z  @ \  ,$D 02 \ # lԔ?"6@`NNN?N@B \  fDԔ?"0@NNN?N @z `0 @ \ `0 ,$D 02 \ 3 rԔ?"6@`NNN?N`@B \  fDԔ?"0@NNN?N0 x \ c $@ ` `    x \ c $  `   jv  `  \# #""r ( \ # l Ԕ?"6@ NNN?N   F @`( \ # l Ԕ?"6@ NNN?N   F @`( \ # lx# Ԕ?"6@ NNN?N   F @`( \ # l, Ԕ?"6@ NNN?N   F @`5  \ # l6 Ԕ?"6@ NNN?N 3  S0x248 @`5 !\ # l> Ԕ?"6@ NNN?N 3  S0x196 @`5 "\ # lG Ԕ?"6@ NNN?N ` 3 S0x512 @`5 #\ # lP Ԕ?"6@ NNN?N ` 3 S0x128 @`B $\ Zo ?"0@NNN?N ` `B %\ T1 ?"0@NNN?N 3 3B &\ T1 ?"0@NNN?N  B '\ T1 ?"0@NNN?N  B (\ Zo ?"0@NNN?N  B )\ Zo ?"0@NNN?N ` B *\ T1 ?"0@NNN?N ` B +\ Zo ?"0@NNN?N `  2 ,\ 3 r ?"6@`NNN?N ,$D 0Uz y   -\  P ,$@ 02 .\ # lԔ?"6@`NNN?Npp  2 /\ # lԔ?"6@`NNN?Np  2 0\ # lԔ?"6@`NNN?Np @ B 1\  fDԔ?"0@NNN?N  B 2\  fDԔ?"0@NNN?N  # 3\ 3 rV Ԕ?"6@ NNN?Ny M  ;0x128# 4\ 3 r@[ Ԕ?"6@ NNN?NXy MM  ;0x196# 5\ 3 rh_ Ԕ?"6@ NNN?Ny M  ;0x202zz    6\  ,$@ 0 7\ 3 rԔ?"6@`NNN?N  B 8\  `DԔ?"0@NNN?N  B 9\  `DԔ?"0@NNN?N  B :\  `DԔ?"0@NNN?N@ @ B ;\  `DԔ?"0@NNN?N  B <\  `DԔ?"0@NNN?N  B =\  fD ?"0@NNN?N  ,$@ 0L >\ 3 rd Ԕ?"6@ NNN?N @,$ 0 8Upcallz A6  ?\  A6 ,$@ 02 @\ # lԔ?"6@ NNN?Nw # A\ 3 rPi Ԕ?"6@ NNN?NA6T ;0x512ez v  B\  ~ ,$D  02 C\ # lԔ?"6@ NNN?Nw( B D\  fDԔ?"0@NNN?N  # E\ 3 rm Ԕ?"6@ NNN?NvT ;0x248ez (  F\  ( ,$D 02 G\ # lԔ?"6@ NNN?Nwh B H\  fDԔ?"0@NNN?N(  # I\ 3 r`r Ԕ?"6@ NNN?NT ;0x296z  w  J\   w ,$@ 0 K\  fv Ԕ?"6@ NNN?N   ;0x202 L\  fz Ԕ?"6@ NNN?Np w  ;0x296z  `  M\  p ,$D 0B N\ HD?"0@NNN?N ` B O\B HD?"0@NNN?N ` z  `  P\  0 ,$@ 0B Q\ HD?"0@NNN?N ` B R\B HD?"0@NNN?N ` "z  pP p S\  P ,$@ 0B T\  `DԔ?"0@NNN?Np pP pB U\  `DԔ?"0@NNN?N p p0 V\ # l؀ Ԕ?"6@`NNN?Ns  V"Synchronize shared data structures##$H \ 0޽h ? 3355___PPT10}5.F+r$^D5'  = @B D4' = @BA?%,( < +O%,( < +D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*,\%(D' =%(Df' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*-\%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*,\%(DY' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*6\%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*=\%(D' =A@BBBB0B%(D' =1:Bvisible*o3>+B#style.visibility<*>\%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*?\%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*B\%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*\%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*\%(DH' =%(D' =%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*\%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*\%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*\%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* \%(DH' =%(D' =%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*\%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<* \%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*\%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*F\%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*J\%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* \%(D' =%(Dd' =%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<*\%(D' =4@BBBB%(D' =1:Bhidden*o3>+B#style.visibility<* \%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*M\%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*S\%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<* \%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*P\%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*\%(+8+0+>\0 +  0L0 0@d\(  dx d c $H ` `     d c $ <$D 0   H d 0޽h ? 33  ___PPT10 .+YD^ '  = @B D ' = @BA?%,( < +O%,( < +D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*d/s%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*ds%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*d%(DL' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*d%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*d%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*d@%(+  0L0 @@h\(  hx h c $H ` `     h c $4 <$D 0   H h 0޽h ? 33 ~ ___PPT10^ .p+YD2 '  = @B D ' = @BA?%,( < +O%,( < +D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*hP%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*h%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*h%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*h%(D4' =%(D' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*h,%(+  0L0 ?Pn(  Px P c $ ` `     P c $  `<$@ 0    H P 0޽h ? 33  ___PPT10 .`"+ED^ '  = @B D ' = @BA?%,( < +O%,( < +D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*P%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*P%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*P%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*P%(D' =%(Dh' =%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*P>%(D' =4@BBBB%(D' =1:Bvisible*o3>+B#style.visibility<*P>%(+> 0 qi:(  X  C (K   i  S  0)   Is it possible to obtain good fault isolation, good performance, and retain compatibility with commodity operating systems? The answer is yes, and the solution is the Microdrivers architecture that I will describe in the rest of this talk.H  0޽h ? 3380___PPT10.< 0 h`:(  X  C (K   `  S p 0)   A popular solution to improve fault isolation is to use user-space device drivers. In this architecture, each device driver is programmed as a user-space process. Applications that need to communicate with a device do so via the operating system, which implements a runtime component that communicates with the device driver process. This is the solution adopted, for instance, by microkernel operating systems. The advantage of this architecture is that it offers good fault isolation. When a buggy device driver crashes, it does not bring down the rest of the operating system with it. At worst, the corresponding device is rendered unusable. In this case the buggy device driver was isolated via hardware, that is, process-based isolation.H  0޽h ? 3380___PPT10.'QD<J 0 ;<L(  <^ < S (K    < c $\` 0)   B- Define critical functions! Describe the algorithm used to identify critical functions  mention that you used function templates, identified once per family of drivers to identify these functions. Mention that you identified criticality at the function level of granularity, so this is only a conservative estimate of the number of lines of code along the critical path in the kernel."f-H < 0޽h ? 3380___PPT10.nsQ 0 <t(  t^ t S (K    z t c $d 0)    There are several sophisticated tools that work with user space applications, but not with the kernel. Ability to use these tools during the driver development process (with the userdriver, because it contains most of the code of the device driver). H t 0޽h ? 3380___PPT10.@o[ 0 >(  ^  S (K   z  c $;  0)   There are several sophisticated tools that work with user space applications, but not with the kernel. Ability to use these tools during the driver development process (with the userdriver, because it contains most of the code of the device driver). H  0޽h ? 3380___PPT10.@o\ 0 2* >(  X  C (K   *  S ~  0)   The runtime component must provide mechanisms for both control and data transfer. The mechanism used to implement control transfer is very similar to that of LRPC. Functions that are implemented in the userdriver are represented in the kernel driver as stubs. When the kernel driver needs to invoke functionality implemented in the userdriver, it invokes this function using an upcall mechanism. A symmetric downcall mechanism enables the user driver to call into the kerneldriver, in case it needs to invoke functionality implemented in the kernel. In our implementation, we used the ioctl system call to implement downcalls. We implemented upcalls by having the user process wait in the kernel for requests until woken up by the kernel with a request to execute a function implemented in the userdriver. The userdriver itself is implemented as a multithreaded process, so we can associate a unique thread to process a request from each different kernel thread. To invoke a function in the userdriver, the kerneldriver must also copy any necessary arguments as well as any data structures stored on the heap that may be needed by the function. We do so by marshaling the data structure in the kerneldriver and unmarshaling it in the user driver, or vice versa. Note that as a result, a data structure that is manipulated by both the kernel driver and the userdriver will exist in both kernel memory as well as in the memory of the userprocess. Thus, these copies of the data structure must be synchronized carefully. It is this need to synchronize shared data structures between the userdriver and kerndriver that differentiates the runtime of the microdriver from LRPC and Nooks XPCZH  0޽h ? 3380___PPT10..Y 0 P>(  X  C (K     S @ 0)   We studied the CVS logs of the e1000 driver to track changes to code in the kernel driver half and the user driver half, and our results were inconclusive.H  0޽h ? 3380___PPT10.0ҌUx] 0 p>(  X  C (K     S D 0)   vSuppose that the kernel driver needs to invoke functionality in the userdriver that will manipulate a data structure, such as a linked list. In this case, the stub for the function in the kerneldriver will serialize the linked list, and send it to the userdriver. The userdriver will use this buffer to either update the copy of the data structure that it has in its memory (if it exists already), or will create the data structure afresh. For example, suppose that the userdriver already has a copy of the list in memory, but the copy is stale, as shown here. In this case, the object tracker will use the table to update the existing nodes, and will create a new node when it finds a missing entry for 0x.202. Entries are removed from the object tracker when an shared data structure is freed in a protection domain. This is achieved by writing a wrapper around deallocator functions.H  0޽h ? 3380___PPT10.$H 0 YQ>(  X  C (K   Q  S  0)   In this case, just 25% of the code of the Microdriver was in the kerneldriver, the remaining was in the Userdriver. We needed about 20 distinct user decisions to annotate this driver (this is still work in progress)H  0޽h ? 3380___PPT10.ÇE;a 0 ld>(  ^  S (K   ^  c $"  0)   Microdrivers offer better fault isolation. There are two reasons for this. First, microdrivers reduce the amount of device driver code running in the kernel. Device driver functionality is now split between a kerneldriver and a userdriver. It is always good to reduce the amount of third party code running in the kernel. Reducing the amount of code running in the kernel has been a holy grail of systems research, and indeed has been the main motivation for several lines of research including extensible kernels and microkernels. Second, because the userdriver runs as a user-space process, it is automatically isolated from the rest of the operating system kernel. Thus, even if the userdriver is buggy, it will crash the process that runs the userdriver, and will render the device unusuable, but will not affect the rest of the OS. Even in this case, recovery mechanisms such as shadow drivers can be used to ensure that applications that access the device do not crash. Of course, a bug in the kerneldriver will still crash the operating system, but we hypothesize that the kerneldriver will contain fewer bugs per line of code than the userdriver. This is because the kerneldriver contains heavily tested functionality, i.e., functionality along the performance-critical path. Even so, if we can ensure that the fraction of code running in the kernel is much smaller than the code running in userspace, we can use techniques such as SFI to protect the kerneldriver.ZH  0޽h ? 3380___PPT10.Qc 0 >(  ^  S (K   "   c $ "  0)  "  Interface is unchanged, so no changes needed to the operating system. Further, microdrivers can co-exist with traditional device driversH  0޽h ? 3380___PPT10. d 0 ?(  ^  S (K   "   c $4("  0)  "  Interface is unchanged, so no changes needed to the operating system. Further, microdrivers can co-exist with traditional device driversH  0޽h ? 3380___PPT10. e 0 0? (   ^   S (K   " z   c $D  0)  "  There are several sophisticated tools that work with user space applications, but not with the kernel. Ability to use these tools during the driver development process (with the userdriver, because it contains most of the code of the device driver). H   0޽h ? 3380___PPT10.@o; 0 D<?<(  <X < C (K   < < S  0)   Microdrivers combine the best features of macrokernels and user-space device drivers, and provide a path to create user-level device drivers.  OH < 0޽h ? 3380___PPT10.@j`j 0 ?H(  H^ H S (K    H c $ܯ  0)   vSuppose that the kernel driver needs to invoke functionality in the userdriver that will manipulate a data structure, such as a linked list. In this case, the stub for the function in the kerneldriver will serialize the linked list, and send it to the userdriver. The userdriver will use this buffer to either update the copy of the data structure that it has in its memory (if it exists already), or will create the data structure afresh. For example, suppose that the userdriver already has a copy of the list in memory, but the copy is stale, as shown here. In this case, the object tracker will use the table to update the existing nodes, and will create a new node when it finds a missing entry for 0x.202. Entries are removed from the object tracker when an shared data structure is freed in a protection domain. This is achieved by writing a wrapper around deallocator functions.H H 0޽h ? 3380___PPT10.$l 0  @`(  `^ ` S (K   "  ` c $/"  0)  "  vSuppose that the kernel driver needs to invoke functionality in the userdriver that will manipulate a data structure, such as a linked list. In this case, the stub for the function in the kerneldriver will serialize the linked list, and send it to the userdriver. The userdriver will use this buffer to either update the copy of the data structure that it has in its memory (if it exists already), or will create the data structure afresh. For example, suppose that the userdriver already has a copy of the list in memory, but the copy is stale, as shown here. In this case, the object tracker will use the table to update the existing nodes, and will create a new node when it finds a missing entry for 0x.202. Entries are removed from the object tracker when an shared data structure is freed in a protection domain. This is achieved by writing a wrapper around deallocator functions.H ` 0޽h ? 3380___PPT10.$p 0 p@t(  t^ t S (K   z t c $ 0)   There are several sophisticated tools that work with user space applications, but not with the kernel. Ability to use these tools during the driver development process (with the userdriver, because it contains most of the code of the device driver). H t 0޽h ? 3380___PPT10.@o hx[lܙ~L8$qv8cDIhPcC\)N]1$lL(HCUSF")Bn"]A K۴JͣJ6Vڪ=ܹwfgwωs̉ ,ſ w=9Cߛ }?yJ]="oý៳d#e*cmX!T#,G!A]jUuAa ZpL#H{^̳aX﫿gvy ""1@)Mrx YJk'!T!C~@Qm?3)ls?Ct!O>E@C~YK3{ f~8kmg09CKs`9sh1K$ ﳛx`oáb= svi:N;:;/fR)55+֬XPнzCW]MmqЂ׋~ 1m'8K1'-rM@҄;wIQ0xGyC[0+>ׄgf5kkwS7NǤ%N؈DfRD~,ƍf̠.j~dFc%G^(1W B̽?b:Fro><*R|J֤|=>|<>:~7r4?+OÈۧ?gڻ +:whB[v_W]߽|]xgӆۑ?##b||Fht`tF'q&`bB|`,o3'nHhb'F!:ӎ Ǐc{"2 LQDtY弫ZRi@D1݊Ֆi|ڒ{۬ByZ%y?ؽh[s{ @qyP]%xJtDP~3 {{5 $9=>mu6D-Q=jiSSGq~`hmbRsD9LR(F9Ltne ezvb KN "IwXe*oJd&\$݆e~j@AvCwB!62KwYdh8Fh1Cr'"u!^"f銬2-8$(G(=V|~ݑ[y]MzЦLd{cdGhVTA7'zui`f@A"1֢͡q+s>|ԁ*`\r\eL.HWsE Xϗ%S a _2m4#D+kG p߃j] oW;lY Y><,IE e[.Ya^c/I!bgo1mm=oˏ:,D8Zc+`!m[pEB[uyqe򏱊Q>bd{?HV0ᬑS~-Y ߶=(Fn(xU15 'ZdF_DGQdl,`(.} 5Qߩ8P<7v"՝cVĨUf|ߤb9yFBKn2x=_(Qk6{M'Q^+U+CoӔð3=7q5_FMC˱Oa49w5?\}ݨ7H+[M/̧lr^T(`򵵢0(jk;! Ϙ6 *ii|$Db3U{Akָf j\P΀©lL9XNja;qסqa k(ݎ[B W{[8w#9##rL3M8.I{,$Hɘ8,io ܁WGZnJwb6SӢ{" smepNr`5z ˘H}$kdYTk9xP^AUKuLx 7W,=sg+.qZZ[]MyUktZ6GK9!&8&?!d&JGN0nh҆0j> llX l#n௵M <7l|?f[<_h[5^J{%H[3# ̻d;{5 ?z!XhExk?%\-H3?7VbO%TcKF.3|S%T7 {|Ir?D X,EB(FʓBuVQ9zI`}VFeTga~nQI??Oӯ̥W.~Ƕ8|2_Xye]Oӯ?OdԿKd{&f:M 渊~_k'_H~甕~%?Oӯ?geLOӯ?g3YU.2R;U}ip#G[&y֫5#1v4Ջ*e9R 8~u)C@k~ܢHІtμZ?YisӨLg5giJh M[b,=7i dC? HX"nuy;|X S7o>2)8Vw5ei hٌKNkܾf]ado.1 uu#_7DB f"_ RxZ}lT}w>y&|9L )R mm>\( (EDꑄ$TH^UUPi(QKӐ&ᏪQhQ6 */pgf?޻Jc+S);A0n`v_{=2XOB? ,{djws~%ȧaS`4Jl#Ő=?VTm( Q1kek=gӇ> w)c|ZƐMmM5F+g5QkURWwN)=aH`RX4א˖9,ZTg,@#؜A-a d۠}KO*UmoKgv69ո/t`2GqYgFTlɑCƷ !+o!h/^C˂Em#~u]]w}$d9Py|UA~Խ<kӗޯcv Ǝ=;袖BV=o RWx: o$~r[C,o&?bA<~X5o)b3 ֳʦMĒ}rlTneMNKw}ɱS b YމxKfg.PSneJNbߧ% ֹz:rmIixIqW[mtt_ '9"Nc/|7ĽMbPǰ=ڔFe@;g[Bj}=: #-,+Q{ٵIJ\ce.6-6 ١f[[YX8 D>M.- P An;?>khk.Լ#.KudOC%6eeI?yϕ:G{&KNpV;2Ba\QH{MZ]nӹH/*L3Ht'-QFU'4JRZ" <7(Y,3!3ݮH m.3f>TYAYeYyctJ`uJ, oAnOob.:.vTL) Q^ ا e8n!1H"b,\_g"w/.=wO;$8LL3%.Sr2m1uǭEp)!3-R3Ws{|B-r{wc?)g$x?wcx{?ǼN@0c>!BuA'A *D ,41$l->L~n֬&/ÏuCMvΝvU?i+7"PT @fx`n8ull\)v,O1%3[2ҶylO/18.YD #`d ӛ\<~{o[0M7-VV3ʛ<3zǚKl3 Hlnn.l,b0PNhmTM5QRG ;o!Vsw%X~Wekzh5_oAsa _k[t|VB|#W`;H^BGE^ 1q5lfhLGph[k,b0'6RYv ^5XИ|#=ca&Jo4XR?0 ~r8"q(/։C }KLaDMhitM,.O ]؏0cO,c1i&j|GVGtm͝q-[>VZ<+.ca+BkQ ?-W|%G5~guN~I-$2O9]C`ynmTP"w %r×aO3:6Wq4M"U`pɑXj5UIWPlduuxB֟34hf;v;{H;{=?ʘQ؁Z#YAF5hʦM3g~\⃣SGAq}fMnZ+ss t=wۿnc4v?WLrL [i:p od05tQ0ej whp?OFhx 0QTϗF nӅpߚ3%;# Nή&pGIJrs^.@A߾3){G]l= l12>1Oh+'0 px    (0PowerPoint PresentationVinod Ganapathy2080Microsoft PowerPoint@@-v5@@@"5; G g  ?  y--$xx--'@Arial-. 332 - Microdrivers ."System:-@Arial-. ?2 % %A New Architecture for Device Drivers.-@Arial-. 2 @^ Somesh Jha.-@Arial-. 2 @ Michael Swift.-@Arial-. "2 7WArini Balakrishnan.-@Arial-. 2 7Vinod Ganapathy.-@Arial-. 2 e/ HotOS XI, 8a.-@Arial-.  2 cOth.-@Arial-. 2 eTMay 2007.-@Arial-. 12 J'Computer Sciences Department.-@Arial-. *2 Q'University of Wisconsin.-@Arial-.  2 Qa-C.-@Arial-. 2 QcMadison7.-՜.+,D՜.+,    On-screen ShowZP& ,Arial Wingdings Courier New Arial BlackDefault DesignMicrosoft Graph Chart3Microdrivers A New Architecture for Device Drivers IntroductionChallenging to write and debug MacrokernelsUser-space device driversBut"Best of both worlds: MicrodriversHow to produce a microdriver?How big is the kernel driver? Slide 10 Slide 11 Slide 12 Slide 13 MechanicsArchitecture of a microdriverCommunicationObject tracking Object tracking: Key challenges Recovery BenefitsImproved fault isolationGood common-case performance Compatibility with commodity OS Compatibility with commodity OSEase of driver development PragmaticsGenerating a microdriverMarshaling annotationsPerformance of a microdriverTCP-send performanceOpen questionsMicrodrivers Slide 33Supplementary MaterialObject tracking The splitterThe code generator Related work  Fonts UsedDesign TemplateEmbedded OLE Servers Slide Titles&D 4<Version'_o0Vinod GanapathyVinod Ganapathy  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./012345689:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~Root EntrydO)PicturespmCurrent UserSummaryInformation(PowerPoint Document(7DocumentSummaryInformation8