summaryrefslogtreecommitdiffstats
path: root/lib/shell/system-command.rb
blob: f87ba890ea0f9e7e3a856c1ed7e9858317ab4b5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#
#   shell/system-command.rb - 
#   	$Release Version: 0.6.0 $
#   	$Revision$
#   	$Date$
#   	by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
#
# --
#
#   
#

require "shell/filter"

class Shell
  class SystemCommand < Filter
    def initialize(sh, command, *opts)
      if t = opts.find{|opt| !opt.kind_of?(String) && opt.class}
	Shell.Fail Error::TypeError, t.class, "String"
      end
      super(sh)
      @command = command
      @opts = opts
      
      @input_queue = Queue.new
      @pid = nil

      sh.process_controller.add_schedule(self)
    end

    attr_reader :command
    alias name command

    def wait?
      @shell.process_controller.waiting_job?(self)
    end

    def active?
      @shell.process_controller.active_job?(self)
    end

    def input=(inp)
      super
      if active?
	start_export
      end
    end

    def start
      @pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {
	Dir.chdir @shell.pwd
	exec(@command, *@opts)
      }
      if @input
	start_export
      end
      start_import
    end

    def flush
      @pipe_out.flush if @pipe_out and !@pipe_out.closed?
    end

    def terminate
      begin
	@pipe_in.close
      rescue IOError
      end
      begin
	@pipe_out.close
      rescue IOError
      end
    end

    def kill(sig)
      if @pid
	Process.kill(sig, @pid)
      end
    end


    def start_import
#      Thread.critical = true
      notify "Job(%id) start imp-pipe.", @shell.debug?
      rs = @shell.record_separator unless rs
      _eop = true
#      Thread.critical = false
      th = Thread.start {
	Thread.critical = true
	begin
	  Thread.critical = false
	  while l = @pipe_in.gets
	    @input_queue.push l
	  end
	  _eop = false
	rescue Errno::EPIPE
	  _eop = false
	ensure
	  if _eop
	    notify("warn: Process finishing...",
		   "wait for Job[%id] to finish pipe importing.",
		   "You can use Shell#transact or Shell#check_point for more safe execution.")
#	    Tracer.on
	    Thread.current.run
	    redo
	  end
	  Thread.exclusive do
	    notify "job(%id}) close imp-pipe.", @shell.debug?
	    @input_queue.push :EOF
	    @pipe_in.close
	  end
	end
      }
    end

    def start_export
      notify "job(%id) start exp-pipe.", @shell.debug?
      _eop = true
      th = Thread.start{
	Thread.critical = true
	begin
	  Thread.critical = false
	  @input.each{|l| @pipe_out.print l}
	  _eop = false
	rescue Errno::EPIPE
	  _eop = false
	ensure
	  if _eop
	    notify("shell: warn: Process finishing...",
		   "wait for Job(%id) to finish pipe exporting.",
		   "You can use Shell#transact or Shell#check_point for more safe execution.")
#	    Tracer.on
	    redo
	  end
	  Thread.exclusive do
	    notify "job(%id) close exp-pipe.", @shell.debug?
	    @pipe_out.close
	  end
	end
      }
    end

    alias super_each each
    def each(rs = nil)
      while (l = @input_queue.pop) != :EOF
	yield l
      end
    end

    # ex)
    #    if you wish to output: 
    #	    "shell: job(#{@command}:#{@pid}) close pipe-out."
    #	 then 
    #	    mes: "job(%id) close pipe-out."
    #    yorn: Boolean(@shell.debug? or @shell.verbose?)
    def notify(*opts, &block)
      Thread.exclusive do
	@shell.notify(*opts) {|mes|
	  yield mes if iterator?

	  mes.gsub!("%id", "#{@command}:##{@pid}")
	  mes.gsub!("%name", "#{@command}")
	  mes.gsub!("%pid", "#{@pid}")
	}
      end
    end
  end
end
uK Beė,Zr5z:uvK/@{Ǫ7p8\Pv- fvUP52O”:g7x_,N*F=>DI=Afm ̴(- ɝd:NljȐ(|3r{2?z:?aX˒˛ysoί[,uœ/$JP\LXBQ$gҠ7!ωgͿ\͊|5ۓXO#'OF,)}vs3:}xRnsi0Ԍ!YUt4f!8!/ë9l϶0V?=H;~O,ʑb@w !놴 CFT7pqsH(:@0I$V?UFp̱y&4  ;%Q"ҤgܪSWQDT\rLfh-VUfC'Kj*6ZD[2@} ^7w/$\pw6ȟ2Sm߻!)Ԥp2w }Yc/?a'W6mu"%ԶoX+({BH[WuKk0 xJ&f~8I{5?ױK6-=hWFzIi]L*j^ߵcv?Sl;JkF L_mNA<7g4ݵ Q;rd܏oRϖЍg'}^)q7VuP3& ̥$\&a=P-R5'QN'oe+A>j,@!aRјg+ JSHG3 cD"1+Aq%ͅQVٗȼqʓeܬ;` Q?~e/BaGlr5b1МHө'6=f FbIs8aׂrJG2he3qďbL6\Δzjo4i0/Jpx1eX#(1'fff)W1FbvUYömLe&wO׭=TK7zVN7e^G!Lܗ KrQ^&"KP: `orrXd<< V Wa~gF"|*N J.=zU'欺M,?2z\Go'xϐ0wau裂RPe0YEhRj9HJߘtx|5l$"c2E{ũLt)kg5h>7/{|>"/*u< o7M^ICڣc vXUc; 8Dȫww>poųIvD"Ԡ5^{ΙرIi,}*ih}osr#)"o,sI[2i^58PQ, ?ӿI,B"Mi-3(cM Q<=?7;iR. >Ռ=P2$1Lę8/=k5B?!e?wײ 94R Yyb扱k>轈VP|a/T(C'd%KB4z'I!b6ht!׶;/jͲE1*M(oVoreXü_h?dyO=w/RY@"I`kƱO CPΏH{{Q] %nG6 wc+.7 Pq a.J$qngiȭSLqz\i+pf!p l~T\%M$oc>k;gTxm@ȹ+:Q.qa2u}Qe׶Y!6Ա)X?nP$9m`{SN!hdjnT>K{dz^6pٚodÞ(^1krİ5;6 b) ȏ$hIqEI5p1B&@,9EȜ)eY@E> TE0KOZ ?B- +tV -͊2M7MyUgtsRBX}E7pŘgvK 6xv\سe8}/94d%"XD%t}“_Y5^&q]G(UK&4끑S2=,wXZWv#km0ʱ%Y`p& b yF2"&Xu$Kc?>E)"5Bm|>p+(&TКD`;/C!ac=獽I*:=,xdxuE2z~TrӦ'3DH(r$/d>"̱["*Z\R%dcsk=ߩp~÷x؍t;J`J_-5оY ^J=bs1v *_X'swoSXè[pf>I5(ONE%;O]z0xgoʇ4E&8?hcH&:~;B]T܃T?0f@y] Hf(8jD֤G)sӴhI$ŚTVrT7ȳ0A og'칓*,ai.* SJIGzL[nD|q[TK LT&[90R&ѣKs{05pWgqc< K^lg_I!cDv2I‚kmZV!IgѽeA>)+)86l\ |u!i6|h@Qd w{2_"H1`LYqVP?h3*W }z s =!fHR+9ܦ3%h/-0Ƅ6dD;^Jk*ք1ʅ =a-pP!#@VȦ~%TZcrPߥ2y.^A_cjBs~nLm3@hF3{$_JM)3?_?PJ5rvCMzA&f{J#Cא& Mf8ҩ" ?rt>EM0}PF Ai¹H`pѯ7|b] {R?5Fڦg@T~w Y&)1?T6DQNDŚHs"{X;ӻ#|Pk6!ɵ)׻ڑSpڤgM+rA2ndv%hՃ;TZõE)h[b \n%OEuK!cެ XIEYe]:a=')1C:ȦV*^ݨWCȒZ*n~)07ԖEg7ðr_PO?= VdG(eeIp7űSf"J~Tͽ;+^WX0oEO]nو^ɸfQmJKpy92C!KyN߉!CaI-&'?$KK KK*];qנez*L@|'=T/?uqa)Xa_i(2ؓ }7-& ]MƵ)9誊\)e`_Y˜~fLB)`վ!4ν=,v3)UpVz+ ҙɯ3Ok>R*&ʊ8sd J+Ȅvl_m7yTt*&qpڐ|~\ŝP0w09d﫦v pS~e y&S~a` dSH-"%}_uFAT'ҔM]+@^Lj9|4hRdBa֭?yz0lU4b cf2ys,c7i8|a~r">`f]0,^cQX3C;̺GNXlhӒ Oc)# r޵ $2 9z$WɫRZzMǴ}O򧙪=Շf˛iVٔ9`R~0DJRFVwd,U`-;R[(i"CG) '?/XzYT@y:|%ߖ/ϟ)Z4>w;v|w)+p/$ۘ FKRx. MXV֙e՗RKJ/ }*!]Ic%7 ~ 6at*Xg zt}kbDiB  s>dڢBsAekJ $B4ܞQ\A5|}kr&c˴H_8ѐ7"gq6ȥަsG>X^XDvWҥH\Q>` (x6 ~WG{=DL~x6Ǭ!s)]#<BTy:" TAZ4uEnУ"i4^ke[b<d:Vn@ye}\ .cu{7)e|W2lAAV'/+Mpawm*RhȁlVT6!!~)t"$]B6..(ʘ~ԗWRk >hzwc+)iѩf ae ? A $$A;Ȁ%@c!w?iq('ON %qܡD@3/ hbP\e:&d>aϝ(`C?b/:.PR# ]S+M k }1o[CۥZ Fvs?S;ƿᯙd:ә{+Z4TM?c /ΘZx]HvIX ̻i:~XK fYXDt7෎&exU,IE6g@vvS+XD{a^վkߜITz0{z.V b*-h`4}h0r~4셇4i]Ryu@4b66=Ksj8q4w97,򰣖(9XP䜩AFOWR-TQAq2y^RF^6ܴmE;3q6@?ygi5%\}>=E>JĐsq JWFKwsr.N8ECb/bWR&8tEo(lw ,Ю(Vgyiwbor\'zKY TgKJH'UJwkwi7=Er[ w[/%(92KFG`Gϖm5byq@G.gDž!N !.D%VB5ͭ\jhGtpk #l |\`8!QIGF0)i#һq>* aNouۓ}pE\ĠTIPiF^OH:r$ǵ:^Vs2,Z&ƏȪk]W=gNyW<4)722é1_k2/ Q?:PE l !Zb:|mйXǭISipSqN-Xet+ pi?BO ]?5YQ}tQSb6q3QuXZSO5SҿI^ AhC?{Gi#YL]P(lTץ)6*Dm+SdQTɠ-w| WUOώf\6׹a{R9wBlpty aOQnĜ}:;/ I/zjb0=^^/~n(q.PNۂ~ qHADj{^܂'qƦW}‭ -7,fÿ-{^2u%M*ksvTM(4C65. z/,Tva.GaKPԮJsaHM_mV+Ol$Ep7*nh]XA`4eZ"+~)\3e$˜;=hSx6[v]F9=Sʮ/mAV"C;i FxLoq7tqOjߋ `C0\Maob?`$0 u*M1E,~тջH& B1Q~j i-_#IfR ƴ86XLE/ jd5\ m$GNJu_zSt"'|g"XDz@@z:hr HX؁#Џm7aVlijx $aX_vuh<&)Azi¦.`T,۔GYAmXôs 9"!BDpӱb{cn~8`._ ˒x2j@:)B NxRw1T\˩bJG(^]`Yg]OZ&"3mjTm#*K_/܊33'adNgM9 <%AkIC:HrPIs}h Ol<4f9lS7zJGYEmHf|Z_){ Rh@'ߠ`:R%g_1'ʟYX]^ƔǠY{R|yNCZ bΙC^M,]?BT爚+ֹa.̻.!Z$(0tڋd%J0&C& 2Y1hrwL!aM&$EuY hh ',Y0Q PFB>F[blfxY e }pM㦪]Od-PJGmhF --1*mGWwD/rqՒ3"p7pK %h[ nlz&{-m(0"b<4$WZ^1{Pr?LBkVGɠ'Z-|Mܯ 3)ۺ`Ί3"/@KF&eG7C't9 l gh d A%2DĨbxx]O;(Cpڮ7eW=s;U$T"tmKU -3]'9D}u޶+.jY3nǍJp\rp@^: ~)i_V[ ֭@Tį9IYY$X'6'M $?Du>dݿko :1;(Yh6N*OP< *oqos;d|)6 £?,Kw1wrb?CArOYw(W܎H#E\abYi\3v!{2W9Ok&۫cb tn2pܷ!TGnM^ s8BWx=*և9$ӽ=dsȆ [ҢC/2L"eң0_gJxߥv`%O01L4x:o֩@#RH6{_gsV:kp5v`eH1!|/L`zKfJrC9/:U(N.+t ?fQ7el` 3FxFs[e*5T5ż)7[o8XxHYoV-p}I6OI7rY#O)6ˤ̐ dRj]puYU(E,;- I-k٣=MTdt-KLfE"C\R^^ eZi8և359:t}.S5m`-"Sרء ctnUUF_]CKIK  ߿rM~ݬIs?n)JWR-C9V/Q{Q^Q!H bPy>'4NăGDY1ԁԣi=D>|=eiK/ϟ=ew2avo~ŰOk|P`۟aQ[]]0/2o*wB0/.T6RM QT0|M_u} I|bz-r6wA]ڊd)vOާ 3DѝIm+Je߼=pǛϛ"jJOh@ {gyMC}(Nzj[<\*E֔\_ٹ 1ce8!X[JmoF( [Z!f]y2ő, ouW?>tF.F,F#]8ε%ӌqx({#޿EyҌ)0ZY _}g,GAb ^bN4PZE^A!@e.~"#,Q6.oWAӪtH܋:ߪ/T P+f*V752;H`b=)qߚD;=*;Q/L;޳tmN"{uժe7 i$W#C,b5%n{u.$Gl!Jюn:hig \SEص~T{1x”Q [e5o4[c|Qlg%!^ffX9Jj -gmџR9c _y3-.1o>q~+߳phL-6UP] x&|i]c ӉO~['ȆމynihQF eȷM}Xt^Ȱp;怸mNⳏ Ƚ:@AqC01tB;|>+0*YW m aj8*f9)˻N@]]9EO[aR2o<ʽ ٚ* >E==OC|whbtM_$Ugg}?{S`fkїG ~iݬGgH6I`v dcRŇ_{}Dpr_n=`ۄfjԛrdUJ6n,>}=SWQ#XE D !R')ʦ9De@gQD%ӻ d՜VzzP֬"kwZ'&-']64alu9(ZR35N þ#z}!gluMNÜ )y)Y/5e) XfS9l@3P5fD ՃMmEʋiM̎YHv}%⵫ZxH93<|D}Xmy)00x%5a0P`GlyM`f?[gw }qvgфV5blw f]JEi gTcH]> b.mjRwWx7֟b0vr=~IЗ[F'ĮXDzg!:3F+ 4!)s-e w1G#dĆƪnVMй~o(qq%~vKJ*+&q-fɬOj~CKFEqpviR~Bϗ@A'* @.E]Ģ3F]QHQل(ݰPN0<ʏRgdq$DKK M~FmaNs'΂_nu ^\wkLRmfCqwI lzA(T҇fX_O[Br%gV5?({F,,sӦ/>bpʰr``ۈS<.Xz<,"kUFiߝDǑY&g00R?i":\"cT*U͖,&8i}e~ Ɛ? O}֍U kAZ~B@j Jt/OY1 <q#E82kTqF8ђ8~We\aCn֚%b$d1w77*ЖJ6so!1@62:PIoaf~Q :R%K ۨXпV.:hwe\V%rh~RS VQN2`*\ ,pAe')nFFǣV@ uCZTt!t*7,'7 ^| vLeshO[aKX(˸6c[mqI{!_K╥l {/m{i)jt pSVҁ &0$IJHyr1MvSosޘ8!D<ӹD0vOg(9-VwA#MP']%̗\+oyj̗ؒV Vq?wSoK4 Z~3?]l߳hV4+لUg'\bmB }R rM33pwyýtmNǒd <?}b6m8!6"l/Vݖ4t/RW! }l\G2c^\ca) %50k>?iM(*e5(IzxϥTA ܵBs H2x f:`F+יxQKͷ{sz~̏(ǂB(Q%¯P٠I"!a-BߤHViSFf@HT÷wH*!ڟ3iѵQIqd/CO'* VX+-]y4oUn+9'? V%oDhEy"(7/a5YaʒFȯJE4Mh^- 洚|q%Hm z֩鶎n1;~0]3E6_[c"X,2JSBw&VaEאAu^P 2_3#.HBrqc]DCݽ[KGүDi/>X!֍i$ 7]qEZ{ȓ=7w0 qîZQ%ҢHWSXV+q@=\ ,.)*h5BWi`"6A؄@a<ٱy7`-aWI*n+C=)Jort'݊ԙ)d(*\X@G6'+_U5bv\]b]nOMK pŽMF=dxF-k+_;U uWTS&{-,btk{֛(eKڶ`u.0xK܂piA$nq+CΧjzvtv>sL>&,J+$QI{{@22Ő]թ+]#-êgľnmr`=cTr7,(^۪l^Hr/ ]U\a ,iBd!B 0e7izF~-BjT;e NHRs<]˼s8f Xm6Uz`YVp<"7KV}йXc!ExҷHVq-D3ZSa-E.%[^5:;N?L#/=8lyzah#%KG^.TPq w}8+MV625mb xuEy$"p`~]Oүۏא/;g~=?t¤}9u+v^vW0_C^ qQ9X.xqGzKŴ.Ʀ7uW!%me!Wn$҂?oUQ op(5vۨ=TY)BU:Fշwb}nXԥaéh Mc?-a *a|]K5g4e [`^Yr )?|΂*aK(D5)BSC ;RRu DR3RpO@ b@@=.䪻ݸ[UGNpy$;85S!$`6 uu$@QoV%^a4s 7S4g%0{s|[EA3+K'uKߵfn1Tj/ $nC9  hՍݫZ:!2~K  7~] /6 3"BkJc-Da![rA8OF&\LUñ* W>f;(O)HYtڏ…ž(Getsx?mĻu}c#!tz*ԈOR:UAܠ`0p!n,e!Ddž%a\$=', $]|0fmKv^ƻ\@0^7N={%*lcvhH[6^5mT;\ʋ'\,2שUaְ` -84?:V3|"Y.D67ӧxnj◟$XHfRZd( n}9"46YDuzwz4`[L.N:"1`0 rdv :I@%@"EU,̬}P>X\yGY zKt~sCq o Al).yz3=H4X< G0gA.م+upLq'CL/6ip%QtXlЎQ5\@H+8IkCbក[%'Cos4ߍL7T KZÉwΜ5<@Z=lsJ9p}ePB/@4赡!پDzKh1z ?}8yIx؞I+YTv<8),ht0)-t"{Jm˻2;e޹bXaWF1 |i>u 3R}Ԕ&G9ICc#l:I3Es5'aDxrA EmAT8e ൔH˜,b3hVO%/|\=zXd4gEvƌA) u}rV !_}-k=B£,İ1ϕ2vuaxN$1Z7$IOM5ѰͥTmLnx'8fKECI{Sn"P 8X|;C&'+]!k3=*]"vU%ؗRa˝c_oJ/_]tQtӷ '<ϑOT;")V c1(7B:|$){{KD[=d]^,#zlHDYʸJT@-W*&}HTcﰑ.["l#PV B_BLT Qky|1>Wli4EbH_u]7ZZw,ъ (QSqk|HXa$yy4$Ex+Ϝ$YPpQVP힬>\z!dٙÖI60!tco<NJZ)8Ukr =Jт҂}(̪fDv8Y틷(w]CfIF1]!F$!Ъ%%}o#ga_YVA^ly7 rIܞЅ:WV1txAM]_NsزFOs^ƐGsX=^.^h*ܷZG9؝0I9Ms9iDEԄ#WRoL9pA #9DV9`K#e 2nNAi}%)rHD aDԳ"\ܧpʬ:<(/MˁTL$W{kB3ЯX]pPmu^iY忛f瓸LsFŊxy9m }i2(u9mm236S2e9C}qbH IV,øEEi4X^]wRm JjÚEbU7jTSɤRB֊6:p6 F ܿ? v:kF % ױ J- YS=[ 7Cx<ʙ<#rp~jFO&Xٵ! XrӰL\DoEý6K:@Cchi!E ۓA!Mb G8饞/r,YW/2;7\^Oy-O} !69wz^WW3k9{8@MRWu,{NwZ5n~`fy(rN+xz+(Y4d@(}b-4"J6aS0 쥧)dVstI8qe+NFMǛroy,laPtU梗_uW?XDg*Ab+I :+?s[nlNMQAڏdkQKuA|'#y#RieQh ~XvrS`%v,SػfKݣ~L Rw_{ޕLP wfdhΧ"ic{mW=A7Ø˦dzA@qoGo话$@kQcA?}]fkuo,@4k;Kթ+ )Gߋܹ<ar i!OpoGj ]} t_"rľΰI_ؽ'Pg"Sq4u6#s=Dm1yj%;tql!Vi_ *;@^ːYK0Q `4/DM&b>Ҭʱmƾ:||,OQeӘޏvOW7:U|lH¨s54J윲}-'K㿷CedS'y&+k; @y~"x2bKO.,H3!ӎ젭z# t^~E]!O\ۄ MSa`649kƒޛhLJ>1I.~ Ie $H=! Lf O{s/<"Gn [$6:ui(^XYIIaQf8dT᜞zF$GC8Y%p{k|M6J>GGá[/1qrvJDqSCLXt <@ 0zpVZxbЌEob* :dq D.]~? *2ӡΚH;3^獁ZXd6i$`&-G1#.L!+mBDأCepo+ 2&D;q׼|ڈ0gѐ:f,5pHRSuӆ@{%(Nܩb۩MeqѼdYv!lΤ%d?aNZ'v._o[0k?e RMݰ+[? ەti s~\ٲSI"$sZЉ3+Ɩa:j p 49L?1IQv;=-r?W+b*p'^cpg$Y1=qjD~IDrhtL1.ݫ{Fbs$fs? \m %Ks k%1FB+`_C| ɪyH2 _ }QgԤX,bk7؄l',,s/J(B]5Ǫ%2k"4@b 2kʄGT5jZAPX@hցWPGJ#`n]:g[ !ZCح>='`Wxmj@w޵bL-~hI,\mh0\2*\+L[ l1+آ=^GF9mcA0lxnTqKr"f*ؠg\CUt[bCp:Cd+&N6԰!@ϊ)T.:K;֫!t\V )wE$.#pxNJ!ZGgF  z/{\Θ}4M-`sSD0z9S.9(H~T#&-柞V$c: jR S%/_. D̓/K0I}m@dfh.r|Sp-u6,m<)&Z7%0ACoݏ6sy~soC#ڎM.=! o+3: l/ѹC-8O-uuQk%%*I&p;X4. L?*&/mh!<;#2U|N[y!dw 5 {:wd SЕ}.H{؞]T2LJsKu C>s@Xc ͟Ke[n7qgCF֕dFoѯj3Y& 4 [{`_;fwE9 1 Xs6N }tG|2`1^` .*v=QcT6cb(Fp?FT$H 3ED:Y?[yZts6(ԯE}>ucgͯuJIƠPiӴr&/'Cgޤ+:B]>WHTA@g8`WRmeM7+ ]"_4WlVpO@gQ)EY.xITl~vw7o'/-amv {^C!7$8-Փ>xIyd[oZlPRGD">Kf?D{B  ^X7N\6EJտtM^X7ԬXm)3e/L(&s zDTqwF/ S>κOU9!ͥ0Vhi@¨:8[YXT{WRrw=lŨˮV";S5zɋ 진:Z(%@z9Q6'nR3:@YD+:vi0G[P0ICCE0n{<{.bCѱ[e 'Zk׋}uWbqp\T -vqql>]d`|Iնd.Fh!Jh5`Pi5d k-+Q·gkGM8LU1U nhgխ w6=p'r9jH_ BDYŖLR[v79+L*^AqGijz%2^o0y8FV9+C)NmߌtaLZ+ ŅZupkq)~+-Us%VC&&cn^ח@p~SOLA~g[M{ h{tFrSԍ>"`Ȩ3tx? 0&;S!;U7fMyk"X5A[2;vʷD35IT vM`z]⼯#8-KRAq<¥b9.pT*uŚf έ{157v&J鍑BY^ڼ\ǖ 4hl=JL^I/5ol^dp2z{)K/K&I|;.WI pi tLaSpl+^4gB!?8pnHCฐ[wKA<tM/v\J㽝E06^4Efr?9)Ī_vBel;⊀Ʌglo =BK=x/DQ!:Bf(c*x-ώɮrnaL*58= ~puo-'\ Y0&ID^:JSUt=,Jv UF۟3+z^Y%]Ѕ|tbd'o#V 'r*^>)aT\eS6J()U=GkU~D׉4%)Fnԧމ|PZEe@`4vr/۝=H":?MV,ZyR(-di<<Ε˫1sTYь&ruNBiaQkA&=mCjkB";yU/ x8=5l Wμl,x֚8U/]a gsH*Vsu3*퟽l !elH s{uGhnk-C"gQ挂i!PN1:#&<%.er>L'j & R ɰ?IZ ;^MU]o%9ç(7 pU ?7PF 56ȜKp֞1gB'Fa>+;d 4D"r9_ z^d01$)HrN02X Ԓ#kqBb~@CܒPACs邶VDa*xOs6)Ko$1d˃3(Uqoqل{[ذK*{*_a7tδmhP}1pyHz]?6tތ" e:}+0XzĊ'0%2ScՊZD~1]́>>2RS:[Y=I3B_u*R~DA̍ LӦY(j<۲$P`R jxlD$2 $ɱ{ad3.U2 Zh ?wEOьڸ.V4S)5V3#~t{_5kj<%`JdLe?[q|Si@$SqQQDo.^Ua윕O!K\ѶdaA2+OhHH\a_3 ,4cg<:YM6?iSvlLo]"61w5Hu+~*Y==itHJ-'(n}@5$ @-c׽VEm@7Afs&T,CzjnYƎ_W΃PXtzM6%_bE^KCgu]AeK¾ w>}KRtcB <8 كm tYhXtixzi\u݇<1~] uڰnHiOuX{Pu ً8i:!󋌠HrX>Mʦ*f`x13`SxW98U8c0I1rLВ0Ys|Bʗ冂BQ#IOW?4C̍XI.L5b/ yuˌym &05BzGrw9nTO4@M=]ON4B.sI~k7Ltb2v*Ec$.[IO낋Sc Ro hoje\l<`S[Uhoۼold$T/u'Pd+5[U`å>&Qȫ=Ē臯RIX I^-#h}j\~9|yyŌdR iO)r ˷/j ǐM~{⅑Ԭ= ~~-[GVB0=zHu3W_Q l;1-|0;^b$xuT6}+|ߎ9S=/0O֓d6wh$.?1SdPEOX$'8{)O;c&o)>ZlTⅡRa^Q䄒@i"X>y>$8d}T;,_Rn53$,cX'Z }90|}$Q^1o 6<Ӯ]FDv?g6A|1ѡ8sC}oh#9m~۬h:S6[a+#2fӃBhABabF 23M1 `Y2a&*C.^T SnY0o2UYMYHjs4O"4A0\xjcѺvU-L؀ZtLZYlAdX[2Q+ 9[FER׾.mr6̐NQ!h-ʡtf$1K< $HZAD.06jsGTXshk\6%z6quNpbXӥyg˵! 劸|]Ȼ']4X*u&?zu%K}ʻE-6Y? Љ4dz2EtH<Ů^B,}ѫAiF{SKH ӣj0mYZuc;IHCDf0NP*ip{}-6@`=5W7++t0P]S8Mt#C/#Me21!xlmAjDwYPni6pZ. R\ 1O Eb!!RL:AѪ>Hv<ⰼgr-nm3P9"5~5 *048?9@sTbJCO4`o(T󨙻_/j=_CKuTdy0{kHc̬zp)ԓ.>I1r;XCpnIh~@$Y2CKĵ{NZe#7u*"ȟ8ZFUoS2zhzmXϚ揞8} "w/HGI.˲ϭKķOĹ !^dH$wTIszTVTyT\r0::%r%rw]K)p=q7yi91{(3њۏ92 HtXIn<ר #uT`adŀ4(lIq~I:Ix !Օha!BA™621WJW{<ڐb9 c^ [xn9|Cr%cIԌˏ(+Tq4TTJ1C7*#)F5V~2tf@ y̾4Sy5ĪOݨV;f4/e?w~Ire9"F-*Z0k*:܃Qx`~[ܧV/֠5Gܝ=~W|#M]GT"JVh$1wQ (: utN,ہgu{3_%ϊg Qհu$' [HvC5pV]VX2ڕgOGY"hda3nl}h ';b{W-YXvEZD. `hI#) 3,gy.G;xQ:)$,13R A~L,%.;yxMM^K~P}_9(,D)(tfgE.#@hAwM[`mD9a-s6R )/Z 饩􀔫I%F4 4f&-|OyF+W1O _.m,KKOC?j8,c6 @gZ]Ɲ<4'Wh}@$"E e;+ViL'G{rL0IĞ.9'AK#Z6M<,Ę۶ M^ E\p%$.LqLU{NacK g4[yt k"d𤝋08WT4õpW`k= !gZZz)Rӻ'H'A91Yx_ }tJ}~`t?!8 ܒѮ~j!p#_=hB >BYݐQ Nr+ьȻf-Z" -{2;^W7Cd\ܺIodd>֭E͞>xL(*2/Ā Ac:6U4'Ks}pY%| tt1P4fYMX<wXBcɶC=iѪMH<:h+V ֍"bƷ}c djE`@E"89q~ؔ*{PLΗcjf_~DQ[Y m*qc^~7 A^G[RxIՊ9E?tH%jNv#qw-YIf)UЁ^'`! ˜ĦKRi" Y }!DdRU2BD,Tl7& ZiλE93E_}q :;]p=E]DWX 4r3h9o@'s(!]2mxx?88vk~]ajlͩCp˩ȡv_:fKP`j4 u4[_0*kM1LMumAm;jY#|e}z>ҼEWǂӐ"l5v^KkZˈҘM/x75$L"  Zo{ob&7C# 1aʇ*s+0rً)YrPvvnmf8t\YՅz;c;no$UcsR i-ǽv"!?BV~pVg!Du XI!Ni!xqEh>cܫk(jkQLQ@9$/o5$p#uC:XŘGyxYHJ<t6{'dt1Z^ͳta\ͪ!q$KFFN3JY>X⳪Ă39+&;~| )Q8ʩ|AWDVnʮSHy \)E(Ԋ+HRd!4?Dam\C9?|0416OB;0+}ROkmeJii4Dͤ pB׿IԱm0`44FA&gݘ?cpxq+R4irA'OzU0 ;7@;7Y==c庍r{ӂtP}6'=zG"I_GW@ñ)˲ޛ݁^GE Ս;YE(cעD&|uVǾ"ǢH|}Fh@bo)ɖ22x IZ욬A̅ WZoβejoj[@MѢCz.jG(|ƀ f&<;f>aX.}@F̾6QYθ4EE􄤜u❸̵U\Y5 MQmeOk[Z)z0*tSaQȒeکӌp9_lGkkTU 3[0Q? X埼 jaר7{e8TEhIwPuJUeBi y1ۄ6%YiI⸥;`D^Y"r/HDaMGxViv7ݑU6 $hLK"BY&/RY@@ET˧6Β3{T`2*!&<H[FEY*";-F 1vt:KO8&pbkD~5{&Cj"bJoX&itf;u#?%(&+ 5U>u>IK ltбpdȌk9^=-J\SQmLވOJ9u$8"fkO/UϤ!xBs1[#v/5za:-PrM.=gс#XȥeQkhΏXDwdd`NZ n*#Đi+ў^0QWݜ ^eEEZ.`pȈ/|ݥ&f: Fu24p(,Yw6`BF7(>|_r~5fN)zŜ#8fgaMz1K1]$Fw[U`Tā VIE{ u9 ѓALJI~% !$^A γ S]bH[A|r.F51m+8qMo+JXcetɼY1II](񤍓- ׭Դ0:4hK]ޤ"B[nFblz TW~F9k<ˀsQd 3SQDG):,N.-"*vJOHe4zɐKݹ Bg|I _fg;[ Ba&`OA}͐ң* /!oN:Ҁc#JP8JWC;DT?$2]$:c-G7(:gw}xrkBRͳ-;ÿh@Sxs5vq~R / ()Sl;Q fVAsSmjod4TF'Y wOxmcWn+儏L/ϴ(,KZYax1Y$|>jʟ4?L1C9\?OF,m1Ȯ讯(Vg 4Ya^}WqVO&ψd >8D8t^}/9%8w'K%W"M #g=|)SL!Z6qeNAm3FE>5Crϫyep6i-1B +m;G ~!uqy^7jX