
    kcss                        d Z ddlZddlZddlZddlZddlmZ ddlmc m	Z
 ddlmc mZ ddlmc mZ ddlmc mZ ddlmc mZ e j)                         d   ZddlmZ 	 ddlmZmZ  G d d      Z G d	 d
ej<                        Z G d de
j@                        Z!d Z" ejF                  dejH                        Z%d Z&d"dZ'd Z( ejF                  d      Z)d Z*e+dk(  r e,ejZ                        dk  r e.dejZ                  d   z         yddl/mc m0Z0 ddl1mc m2Z2 ddl3mc m4Z4 ddl5mc m6Z6 ddl7mc m8Z8 ddl9mc m:Z:  e:jv                  d      Z< ejz                  ej|                        Z? e0j                  ddd      ZA e2j                  ejZ                  d         ZC e4jh                  eC      ZD e!d eEejZ                  d         e<e?      ZFeFj                  eD        e6jl                   e6j                  ejZ                  d         de<e?      ZI e8jp                  dd      ZJdejZ                  v rd ZKddlLZL eLj                  d d!       y e
j                          yy# e$ r ddlmZmZ Y w xY w)#z>$Id: http_server.py,v 1.12 2004/04/21 15:11:44 akuchling Exp $    N)as_bytes   )counter)unquote
splitqueryc                      e Zd ZdZ e       ZdZdZd Zd Z	d Z
d Zd Zd	 Zd
 Zd ZdedZd Zd Z ej(                  d      Zd Zd Zd Zd Zd Zd ZdfdZd ZeZd Zd Z d Z!i ddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;i d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`daZ"dbjG                  dc      Z$dd Z%y)ghttp_request      Nc                 <   |\  | _         | _        | _        | _        | _        | _        g | _        dt        z  t        j                  t        j                               d| _        g | _        t        j                  j                         | _        d | _        i | _        y )Nz	Medusa/%s)ServerDate)channelrequestcommanduriversionheaderoutgoingVERSION_STRING	http_datebuild_http_datetimereply_headers _http_request__reply_header_listr	   request_counter	incrementrequest_number
_split_uri_header_cacheselfargss     ?/usr/lib/python3/dist-packages/supervisor/medusa/http_server.py__init__zhttp_request.__init__9   s     	t|	tx	"-">"+";";TYY["I $& *::DDF    c                 "    || j                   |<   y Nr   )r"   keyvalues      r$   __setitem__zhttp_request.__setitem__P   s    "'3r&   c                      | j                   |   S r(   r)   r"   r*   s     r$   __getitem__zhttp_request.__getitem__S   s    !!#&&r&   c                     || j                   v S r(   r)   r.   s     r$   __contains__zhttp_request.__contains__V       d((((r&   c                     || j                   v S r(   r)   r.   s     r$   has_keyzhttp_request.has_keyY   r2   r&   c                     | j                   j                         D cg c]  }d|z  	 }}dj                  | j                  | j                        g|z         dz   }t        |      S c c}w )N%s: %s


)r   itemsjoinresponse
reply_coder   )r"   itemheader_itemsresults       r$   build_reply_headerzhttp_request.build_reply_header\   sh    484F4F4L4L4NOD4OO]]4??+,|;=?IJ Ps   A'c                 >    | j                   j                  ||f       y)z$ Adds a header to the reply headers N)r   append)r"   namer+   s      r$   
add_headerzhttp_request.add_headerm   s      ''u6r&   c                 V    | j                   j                          g | j                  dd y)z Clears the reply header list N)r   clearr   r"   s    r$   clear_headerszhttp_request.clear_headersq   s&     	  "&(  #r&   c                 ~   d}|| j                   v r#|| j                   |   |k(  r| j                   |= d}g }|||f| j                  v r5||fg}d}n-| j                  D ]  }|d   |k(  s|j                  |       d}  |s|d|z  }n|d|}t        d|z        |D ]  }| j                  j	                  |        y)z Removes the specified header.
        If a value is provided, the name and
        value must match to remove the header.
        If the value is None, removes all headers
        with that name.r   Nr   z%s: zHeader '%s' not found)r   r   rB   LookupErrorremove)r"   rC   r+   found_itremoved_headershsearch_values          r$   remove_headerzhttp_request.remove_headery   s      D&&&]%.""4(H }e} 8 88$(%=/-- !Q44<#**1- H!
 }#d{+/75DEE  	/A$$++A.	/r&   c                     | j                   dd }|D cg c]  \  }}|	 }}}| j                  j                         D ].  \  }}||vs|j                  ||f       |j                  |       0 |S c c}}w )zP Get the tuple of headers that will be used
        for generating reply headersN)r   r   r9   rB   )r"   header_tuplesnvheader_namess        r$   get_reply_headerszhttp_request.get_reply_headers   s     003 &33ca33%%++- 	'CAa$$$aU+##A&	'  4s   A1c                     | j                         }| j                  | j                        g}||D cg c]  }d|z  	 c}z  }dj                  |      dz   S c c}w )zE Gets the reply header (including status and
        additional crlf)r6   r7   r8   )rW   r;   r<   r:   )r"   rS   headersrO   s       r$   get_reply_header_textz"http_request.get_reply_header_text   sY     ..0==12-8QHqL88{{7#j00 9s   Az#([^;?#]*)(;[^?#]*)?(\?[^#]*)?(#.*)?c                    | j                   k| j                  j                  | j                        }|j	                         t        | j                        k7  rt        d      |j                         | _         | j                   S )Nz
Broken URI)r   
path_regexmatchr   endlen
ValueErrorgroups)r"   ms     r$   	split_urizhttp_request.split_uri   s\    ??"%%txx0Auuw#dhh-' .."#((*r&   c                     | j                   D ]B  }|j                  |      }|j                         t        |      k(  s1|j	                  |      c S  yN )r   r]   r^   r_   group)r"   head_regrg   linerb   s        r$   get_header_with_regexz"http_request.get_header_with_regex   sH    KK 	'D%Auuw#d)#ww&	' r&   c                     |j                         }| j                  }||vrK|dz   }t        |      }| j                  D ]&  }|d | j                         |k(  s||d  }|||<   |c S  d ||<   y ||   S )NrJ   )lowerr    r_   r   )r"   r   hcrO   hlri   rs          r$   
get_headerzhttp_request.get_header   s    AQB 9??$)RS	A!"BvJH	
 BvJf:r&   c                     | j                   r| j                   j                  |       y | j                  dt        |      z  d       y )Nz*Dropping %d bytes of incoming request datawarning)	collectorcollect_incoming_datalog_infor_   r"   datas     r$   rt   z"http_request.collect_incoming_data   s6    >>NN00$7MM@3t9Lr&   c                 v    | j                   r| j                   j                          y | j                  dd       y )Nz-Unexpected end-of-record for incoming requestrr   )rs   found_terminatorru   rG   s    r$   ry   zhttp_request.found_terminator   s+    >>NN++-MMCr&   c                     t        |t              rt        |      }t        |t              r t	        j
                  |t        |            }| j                  j                  |       y )N)buffer_size)	
isinstancestrr   bytes	producerssimple_producerr_   r   rB   )r"   things     r$   pushzhttp_request.push	  sI     eS!UOEeU#--eULEU#r&   c                 R    | j                   |   }|| _        d| j                  ||fz  S )NzHTTP/%s %d %s)	responsesr<   r   )r"   codemessages      r$   r;   zhttp_request.response  s-    ..&$,,g!>>>r&   c                     || _         | j                  |   }| j                  ||dz  }t        |      }t	        |      | d<   d| d<   | j                  |       | j                          y )N)r   r   Content-Lengthz	text/htmlzContent-Type)r<   r   DEFAULT_ERROR_MESSAGEr   r_   r   done)r"   r   r   ss       r$   errorzhttp_request.error  sj    ..&&&"*  QK!$Q*^		!		r&   c                    t        t        | j                        j                         }d}d}| j                  dk(  r|dk(  rd| vrd}nXd| d<   nRd}nO| j                  dk(  r2|d	k(  rd}n8d| vr4d
| v r| d
   dk(  s(d}n%| j
                  rd| d
<   d}nd}n| j                  d}t        j                  | j                               }|rd	| d<   |rJt        j                  t        j                  | j                              }t        j                  ||g      }n;| j                  j                  d|       t        j                  | j                        }| j                  j                  t        j                  t        j                   || j"                                     d| j                  _        |r| j                  j'                          yy)z;finalize this transaction - send output to the http channelr   z1.0z
keep-aliver   r   z
Keep-Alive
Connectionz1.1closezTransfer-EncodingchunkedN)rp   
CONNECTIONr   rl   r   use_chunkedr   r   rZ   chunked_producercomposite_producerr   insertr   push_with_producerglobbing_producerhooked_producerlogcurrent_requestclose_when_done)r"   
connectionclose_itwrap_in_chunkingoutgoing_headeroutgoing_producers         r$   r   zhttp_request.done(  s     
DKK8>>@
<<5 \)#4/ H)5D&\\U"W$!-&$. 34	A#$%%09D,-'($ H\\!
 H#33D4N4N4PQ!(D ) : :00$--@! !* < < "34!
 MM  O4 ) < <dmm L 	''++!11 1 $"		 (,$LL((* r&   c                 B   t        j                  |      }t         j                  r|d   rt         j                  }nt         j                  }|dkD  rd}nd}| }t        |d      \  }}t        |d      \  }}|rd||fz  }nd||fz  }t        j                  d|      |z   S )	N   r   r   i  <   z	-%02d%02dz	+%02d%02dz%d/%b/%Y:%H:%M:%S )r   gmtimedaylightaltzonetimezonedivmodstrftime)	r"   whengmttznegrO   remrb   offsets	            r$   log_date_stringzhttp_request.log_date_stringt  s    kk$==SVBB6CCBT"3b!3 Aq6)F Aq6)F}}3S9FBBr&   c           	      :   | j                   j                  j                  j                  | j                   j                  d   d| j                   j                  d   | j                  t        j                               | j                  | j                  |fz         y )Nr   z%d - - [%s] "%s" %d %d
r   )	r   serverloggerr   addrr   r   r   r<   )r"   r~   s     r$   r   zhttp_request.log  sv    ""&&!!!$*))!,,,diik:. 		r&   d   Continuee   zSwitching ProtocolsOK   Created   Accepted   zNon-Authoritative Information   z
No Content   zReset Content   zPartial Contenti,  zMultiple Choicesi-  zMoved Permanentlyi.  zMoved Temporarilyi/  z	See Otheri0  zNot Modifiedi1  z	Use Proxy  zBad Requesti  Unauthorizedi  zPayment Requiredi  	Forbidden  z	Not Foundi  zMethod Not Allowedi  zNot Acceptablei  zProxy Authentication Requiredi  zRequest Time-outi  Conflicti  Gonei  zLength Requiredi  zPrecondition Failedi  zRequest Entity Too Largei  zRequest-URI Too Largei  zUnsupported Media Type  zInternal Server Errori  zNot Implementedi  zBad GatewayzService UnavailablezGateway Time-outzHTTP Version not supported)i  i  i  r7   )	z<head>z<title>Error response</title>z</head>z<body>z<h1>Error response</h1>z<p>Error code %(code)d.z<p>Message: %(message)s.z</body>rf   c                      y r(    )r"   msglevels      r$   ru   zhttp_request.log_info      r&   r(   )r
   )&__name__
__module____qualname__r<   r   r   r   rs   r%   r,   r/   r1   r4   r@   rD   rH   rQ   rW   rZ   recompiler\   rc   rj   rp   rt   ry   r   r;   r   	reply_nowr   r   r   r   r:   r   ru   r   r&   r$   r	   r	   &   s    JiO K I .(')) "7)%/P01* 2J
($?
 IJ+XC(
&&&& & 	&
 & 0& & & "& #& $& $& & & &  !&" #&$ #%&& '&( )&* %+&, !-&. 0/&0 #1&2 3&4 5&6 "7&8 &9&: +;&< (=&> )?&@ (A&B "C&D E&F '#-K&IR #KK	r&   r	   c                   r    e Zd ZdZdZ e       Zd Zd ZdZ	d Z
d ZdZd	 Zd
 Zd Zd Zd Zd Zd Zd Zy)http_channeli   Nc                 z   t         j                  j                         | _        t	               | _        t        j                  j                  | |       || _	        || _
        | j                  d       d| _        t        t        j                               | _        | j                  | _        | j#                          y )Ns   

r&   )r   channel_counterr   channel_numberr   r   asynchat
async_chatr%   r   r   set_terminator	in_bufferintr   creation_time	last_usedcheck_maintenance)r"   r   connr   s       r$   r%   zhttp_channel.__init__  s    *::DDF&y$$dD1	[) $))+.++ r&   c                     t         j                  j                  |       dd }d|d| j                  d| j                  dS )Nr   <z channel#: z
 requests:>)r   r   __repr__r   r   )r"   ars     r$   r   zhttp_channel.__repr__  s>      ))$/"5##$$ 	r&   r   c                 X    | j                   | j                  z  s| j                          y y r(   )r   maintenance_intervalmaintenancerG   s    r$   r   zhttp_channel.check_maintenance  s'    ""T%>%>> ?r&   c                 $    | j                          y r(   )kill_zombiesrG   s    r$   r   zhttp_channel.maintenance  s    r&   i  c                 $   t        t        j                               }t        t        j                  j                               D ]I  }|j                  | j                  k(  s||j                  z
  |j                  kD  s:|j                          K y r(   )
r   r   listasyncore
socket_mapvalues	__class__r   zombie_timeoutr   )r"   nowr   s      r$   r   zhttp_channel.kill_zombies  si    499;H//6689 	$G  DNN2'+++w/E/EEMMO	$r&   c                     t         j                  j                  | |      }| j                  j                  j                  t        |             t        t        j                               | _	        |S r(   )
r   r   sendr   	bytes_outr   r_   r   r   r   )r"   rw   r?   s      r$   r   zhttp_channel.send  sM    $$))46''T3diik*r&   c                 0   	 t         j                  j                  | |      }| j                  j                  j                  t        |             t        t        j                               | _	        |S # t        $ r t        j                  d       Y y w xY w)NzOut of Memory!)r   r   recvr   bytes_inr   r_   r   r   r   MemoryErrorsysexit)r"   r{   r?   s      r$   r   zhttp_channel.recv  sp    	(((--t[AFKK  **CK8 $))+.DNM 	( HH&'	(s   A1A4 4BBc                     t        j                         d d \  }}|t        u r ||      t        j                  j                  |        y )Nr   )r   exc_info
SystemExitr   r   handle_error)r"   trU   s      r$   r   zhttp_channel.handle_error  s<    ||~bq!1
?A$J,,d3r&   c                      y r(   r   r!   s     r$   r   zhttp_channel.log$  r   r&   c                 |    | j                   r| j                   j                  |       y | j                  |z   | _        y r(   )r   rt   r   rv   s     r$   rt   z"http_channel.collect_incoming_data+  s1      66= "^^d2DNr&   c                 B   | j                   r| j                   j                          y | j                  }d| _        |j                  d      }|r|d   s|dd  }|r|d   s|s| j	                          y |d   }t        |      \  }}}t        |dd        }t        |      \  }}d|v r|rt        |      dz   |z   }nt        |      }t        | |||||      }	| j                  j                          | j                  j                  j                          |0| j                  dt        |      z  d       |	j!                  d	       y | j                  j"                  D ].  }
|
j%                  |	      s	 |	| _         |
j'                  |	        y  |	j!                  d       y #  | j                  j(                  j                          t+        j,                         \  \  }}}}}}| j                  d
|d|d|d|d       	 |	j!                  d       Y  y #  Y Y  y xY wxY w)Nr&   s   
r   r   %?zBad HTTP request: %sr   r   zServer Error: z, z: file: z line: r   r   )r   ry   r   splitr   crack_requestjoin_headersr   r   r	   r   r   r   total_requestsru   reprr   handlersr]   handle_request
exceptionsr   compact_traceback)r"   r   linesr   r   r   r   rpathrqueryro   rO   filefunri   r  rU   tbinfos                    r$   ry   zhttp_channel.found_terminator3  s     113^^F DNLL)E a
 ab	 a $$&AhG$17$;!GS'!59-F 'sOME6e|!5/C/&8C!5/CdGWc7FKA  **,KK&&0025WEwO
 [[)) 77A;!/0, ((!, #( GGSM	!..88::B:T:T:V7)sD1aUVWXY]^b(c(/1!GGSM ! s%   2FA!HHHHHc                     | j                   ryt        | j                        r8| j                  j                         }t	        |d      r|j                          S yy )Nr   stalled)ac_out_bufferr_   producer_fifofirsthasattrr  )r"   ps     r$   writable_for_proxyzhttp_channel.writable_for_proxyz  sR     ##$""((*A9%99;& %r&   )r   r   r   ac_out_buffer_sizer   r   r   r%   r   r   r   r   r   r   r   r   r   r   rt   ry   r  r   r&   r$   r   r     sc     OiO
!  N$(43ENr&   r   c                   T    e Zd Zdez  ZeZddZd Zd Z	d Z
d Zd Zdd	Zd
 Zd Zy)http_serverzHTTP Server (V%s)Nc                    || _         || _        t        j                  j	                  |        | j                  t        j                  t        j                         g | _	        |s#t        j                  t        j                        }| j                          | j                  ||f       | j!                  d       | j                  j#                         \  }}|s9| j%                  dd       t        j&                  t        j(                               }	 t        j*                  |      d   | _        || _        t3               | _        t3               | _        t3               | _        t3               | _        t3               | _        |s#t        j                  t        j                        }|rt        j>                  ||      | _
        nt        j@                  |      | _
        | j%                  dtB        tE        jF                  tE        jD                               | j,                  |fz         y # t        j.                  $ r | j%                  dd       || _        Y *w xY w)Ni   zComputing default hostnamerr   r   zCannot do reverse lookupz2Medusa (V%s) started at %s
	Hostname: %s
	Port:%d
)$ipportr   
dispatcherr%   create_socketsocketAF_INETSOCK_STREAMr  r   file_loggerr   stdoutset_reuse_addrbindlistengetsocknameru   gethostbynamegethostnamegethostbyaddrserver_namer   server_portr   total_clientsr
  r  r   r   resolving_loggerunresolving_loggerr   r   ctime)r"   r"  r#  resolverlogger_objecthosts         r$   r%   zhttp_server.__init__  s   	$$d+FNNF,>,>?"..

;M		B: 	T[[,,.
dMM6	B%%v'9'9';<B	"%33R8;D
  $Y%i!)  "..

;M 118]KDK 33]CDK '

499;/((	
	' || 	"MM4i@!D	"s   H- -,IIc                      yNr   r   rG   s    r$   writablezhttp_server.writable  s    r&   c                      y r(   r   rG   s    r$   handle_readzhttp_server.handle_read  r   r&   c                     | j                   S r(   )	acceptingrG   s    r$   readablezhttp_server.readable  s    ~~r&   c                      y r(   r   rG   s    r$   handle_connectzhttp_server.handle_connect  r   r&   c                    | j                   j                          	 | j                         \  }}| j                  | ||       y # t        j                  $ r | j                  dd       Y y t        $ r | j                  dd       Y y w xY w)Nz+warning: server accept() threw an exceptionrr   z*warning: server accept() threw EWOULDBLOCK)r4  r   acceptr&  r   ru   	TypeErrorchannel_class)r"   r   r   s      r$   handle_acceptzhttp_server.handle_accept  s    $$&	JD$  	D$- || 	
 MMH)T 	
 MMGS	s   A %B*BBc                 x    |r| j                   j                  |       y | j                   j                  d|       y r<  )r  rB   r   )r"   handlerbacks      r$   install_handlerzhttp_server.install_handler  s+    MM  '*MM  !W-r&   c                 :    | j                   j                  |       y r(   )r  rL   )r"   rK  s     r$   remove_handlerzhttp_server.remove_handler  s    g&r&   c                    ddl m fd}t        t        | j                        D cg c]  }|s|	 }}| j
                  r?| j                  j                         t        | j
                  j                               z  }nd}t        j                  t        j                  d| j                  z  d| j                  z  d| j                  z  d| j
                  z  d	| j                  z  d
|z  d || j                  j                               z  d || j                   j                               z  d| j"                  z  dg
      g|z   t        j$                  d      gz         S c c}w )Nr   )english_bytesc                 2    dj                   |             S re   )r:   )rT   rQ  s    r$   
nice_bytesz&http_server.status.<locals>.nice_bytes  s    77=!,--r&   g        z<h2>%s</h2>z!<br>Listening on: <b>Host:</b> %sz<b>Port:</b> %dz#<p><ul><li>Total <b>Clients:</b> %sz<b>Requests:</b> %sz<b>Requests/Client:</b> %.1fz<li>Total <b>Bytes In:</b> %sz<b>Bytes Out:</b> %sz<li>Total <b>Exceptions:</b> %sz!</ul><p><b>Extension List</b><ul>z</ul>)supervisor.medusa.utilrQ  mapmaybe_statusr  r4  r
  as_longfloatr   r   lines_producerSERVER_IDENTr2  r#  r   r   r  r   )r"   rS  _fhandler_statsratiorQ  s        @r$   statuszhttp_server.status  s[   8	. '*<&GN2NN''//1E$:L:L:T:T:V4WWEE++))&Z^ZkZkk;$JZJZZ)Z^ZcZcc8JNJ\J\].RVReRee7%O8:t}}OdOdOfCgh/:W[WeWeWmWmWoKpq:$//Y5   -- 1:0I0I'0R/ST 	 Os
   E$E$)NN)r   )r   r   r   r   rZ  r   rH  r%   r=  r?  rB  rD  rI  rM  rO  r^  r   r&   r$   r   r     s?    &7L M4l.*.'r&   r   c                 <    t        | d      r| j                         S y )Nr^  )r  r^  )r   s    r$   rV  rV    s    x ||~r&   zConnection: (.*)c                     g }t        t        |             D ]2  }| |   d   dv r|d   | |   dd  z   |d<   |j                  | |          4 |S )Nr   z 	r   r   )ranger_   rB   )rY   ro   is      r$   r	  r	    sb    
A3w<  "1:a=E!bEGAJqrN*AbEHHgaj!	"
 Hr&   r   c                     |D ]E  }| j                  |      }|s|j                         t        |      k(  s4|j                  |      c S  yre   )r]   r^   r_   rg   )rh   r  rg   ri   rb   s        r$   rp   rp   $  sF     #NND!CI%77E?"# r&   c                 z    |D ]6  }| j                  |      }|s|j                         t        |      k(  s4|c S  yre   )r]   r^   r_   )rh   r  ri   rb   s       r$   get_header_matchre  +  s=     NND!CI%H r&   z%([^ ]+) ([^ ]+)(( HTTP/([0-9.]+))$|$)c                     t         j                  |       }|rd|j                         t        |       k(  rH|j	                  d      r|j	                  d      }nd }|j	                  d      |j	                  d      |fS y)N      r   r   )NNN)REQUESTr]   r^   r_   rg   )ro   rb   r   s      r$   r  r  4  sa    qAQUUWA771:ggajGGwwqz1771:w..r&   __main__zusage: %s <root> <port>z	127.0.0.1fnordi'  rf   iU  )r#  r8  r9  ia  z-pc                  L    	 t        j                          y # t        $ r Y y w xY wr(   )r   loopKeyboardInterruptr   r&   r$   profile_loopro  X  s"    MMO( s    	##zprofile_loop()zprofile.out)r   )ORCS_IDr   r&  r   r   supervisor.compatr   supervisor.medusa.asyncore_25medusaasyncore_25r   supervisor.medusa.asynchat_25asynchat_25r   supervisor.medusa.http_dater   supervisor.medusa.producersr   supervisor.medusa.loggerr   r  r   supervisor.medusa.counterr   urllibr   r   ImportErrorurllib.parser	   r   r   r$  r   rV  r   
IGNORECASEr   r	  rp   re  ri  r  r   r_   argvprintsupervisor.medusa.monitormonitorsupervisor.medusa.filesysfilesys!supervisor.medusa.default_handlerdefault_handlersupervisor.medusa.ftp_server
ftp_serversupervisor.medusa.chat_serverchat_serversupervisor.medusa.resolverr8  caching_resolverrsr)  r*  lgsecure_monitor_servermsos_filesystemfsdhr   hsrM  dummy_authorizerftpcsro  profilerunrm  r   r&   r$   <module>r     sY   K 
  
  & 1 0 0 0 0 / / / ) )" -1*e eXvH'' vxA8&& AF RZZ+R]];
 "**=
>	  z
388}q'388A;783333CC99;;55&X&&4V,*W**G[$G"W""CHHQK0,_,,b1S!-r26
B#j##+
++CHHQK8 	 %[$$b$/388
 GKK)=9HMMOC A  1001s    I) )I:9I: