
    Kix              *          U d dl Z d dlZd dlZd dlmZmZmZ d dlmZ d dlm	Z	m
Z
 d dlZd dlmZ d dlmZ d dlmZ d dlmZmZmZmZmZmZ d d	lmZ d d
lmZmZ d dlmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z, d dl-m.Z.m/Z/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6  ejn                  ddd      Z8ejn                  e9d<   e8ju                  d      dd       Z;e8ju                  d      dgdd e!       ejx                  ejz                  j}                         re j~                  ne j                  d ed       ed       ed !       ed"!      dd#d#dddfd$e	eAeB    ej                  d%d&d'(      f   d)e	eB ej                  d*d+d,(      f   d-e	eB ej                  d.d/(      f   d0e	eBdz   ej                  d1d2(      f   d3e	e ej                  d4d5e+6      f   d7e	e  ej                  d8d9e*6      f   d:e	eD ej                  d;d<(      f   d=e	e ej                  e"d>d?@      f   dAe	e ej                  e"dBdC@      f   dDe	e ej                  e"dEdF@      f   dGe	e ej                  e"dHdI@      f   dJe	eE ej                  dKdL      f   dMe	eE ej                  dNdOdP(      f   dQe	eE ej                  dRdS      f   dTe	eDdz   ej                  dUdVdW(      f   dXe	eDdz   ej                  dYdZd[(      f   d\e	eBdz   ej                  d]d^d_(      f   ddf$d`       ZFe8ju                  da      dbdbe4j                  dddfdce	eB ej                  dde$e      f   dfe	eB ej                  dge$e      f   dhe	e4 ej                  di      f   dje	eBdz   ej                  dk      f   d)e	eB ej                  d*d+d,(      f   d-e	eB ej                  d.d/e,6      f   ddfdl       ZIe8ju                  dm      	 	 dd)e	eB ej                  d*d+d,(      f   d-e	eB ej                  d.d/e,6      f   ddfdn       ZJe8ju                  do      dbdbe4j                  dddfdce	eB ej                  dpe$e      f   dfe	eB ej                  dqe$e      f   dhe	e4 ej                  di      f   dje	eBdz   ej                  dr      f   d)e	eB ej                  d*d+d,(      f   d-e	eB ej                  d.d/e,6      f   ddfds       ZK ejn                  dtdu      ZLejn                  e9dv<   e8j                  eLd$w       eLju                  dx      dddy ed       fd)e	eB ej                  d*d+d,(      f   d-e	eB ej                  d.d/e,6      f   dze	eB ej                  d{      f   d|e	e ej                  e"d}~      f   ddf
d       ZNeLju                  d      dddy ed       fd)e	eB ej                  d*d+d,(      f   d-e	eB ej                  d.d/e,6      f   dze	eB ej                  d{      f   d|e	e ej                  e"d}~      f   ddf
d       ZOeLju                  d      ddd ed       fd)e	eB ej                  d*d+d,(      f   d-e	eB ej                  d.d/e,6      f   de	eP ej                  d      f   d|e	e ej                  e"d}~      f   ddf
d       ZQe8ju                  d      dgddd#fd$e	eAeB    ej                  d%d&d'(      f   d)e	eB ej                  d*d+d,(      f   d-e	eB ej                  d.d/e,6      f   de	eE ej                  dd      f   ddf
d       ZRe8ju                  d      	 	 dde	eB ej                  d      f   d-e	eB ej                  dddd      f   de	eB ej                  d*dd,d      f   ddfd       ZS ejn                  ddu      ZTejn                  e9d<   e8j                  eTdw       eTju                  dd      	 	 dd)e	eB ej                  d*d+d,(      f   d-e	eB ej                  d.d/e,6      f   ddfd       ZUeTju                  dd      	 	 dde	eB ej                  d      f   d)e	eB ej                  d*d+d,(      f   d-e	eB ej                  d.d/e,6      f   ddfd       ZVy)    N)datetime	timedeltatimezone)partial)	Annotated
Collection)Console)Layout)Live)	BarColumnProgressTaskProgressColumn
TextColumnTimeElapsedColumnTaskID)Table)__version__tasks)LogLevel	LogFormatdefault_worker_namedurationget_task_statshandle_strike_wildcardinterpret_python_valueiterate_with_timeout
local_timeprint_workersrelative_timeset_logging_formatset_logging_levelvalidate_url)DocketDocketSnapshot
WorkerInfo)ExecutionState)Operator)WorkerzBDocket - A distributed background task system for Python functionsT)helpadd_completionno_args_is_helpappzPrint the version of docket)r)   returnc                  "    t        t               y N)printr        _/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/docket/cli/__init__.pyversionr4   4   s     
+r2   zStart a worker to process taskszdocket.tasks:standard_tasksdocketredis://localhost:6379/0
      )minutes)secondsd   )milliseconds   Fr   z--taskszThe dotted path of a task collection to register with the docket. This can be specified multiple times.  A task collection is any iterable of async functions.DOCKET_TASKS)r)   envvardocket_z--docketzThe name of the docketDOCKET_NAMEurlzThe URL of the Redis server
DOCKET_URLnamezThe name of the workerDOCKET_WORKER_NAMElogging_levelzThe logging levelDOCKET_LOGGING_LEVEL)r)   r?   callbacklogging_formatzThe logging formatDOCKET_LOGGING_FORMATconcurrencyz3The maximum number of tasks to process concurrentlyDOCKET_WORKER_CONCURRENCYredelivery_timeoutz=How long to wait before redelivering a task to another worker DOCKET_WORKER_REDELIVERY_TIMEOUT)parserr)   r?   reconnection_delayzQHow long to wait before reconnecting to the Redis server after a connection error DOCKET_WORKER_RECONNECTION_DELAYminimum_check_intervalz'The minimum interval to check for tasks$DOCKET_WORKER_MINIMUM_CHECK_INTERVALscheduling_resolutionz8How frequently to check for future tasks to be scheduled#DOCKET_WORKER_SCHEDULING_RESOLUTIONschedule_automatic_tasksz--schedule-automatic-taskszSchedule automatic tasksenable_internal_instrumentationzF--enable-internal-instrumentation/--no-enable-internal-instrumentationz@Enable OpenTelemetry spans for internal Redis polling operations-DOCKET_WORKER_ENABLE_INTERNAL_INSTRUMENTATIONuntil_finishedz--until-finishedz)Exit after the current docket is finishedhealthcheck_portz--healthcheck-portz"The port to serve a healthcheck onDOCKET_WORKER_HEALTHCHECK_PORTmetrics_portz--metrics-portz'The port to serve Prometheus metrics onDOCKET_WORKER_METRICS_PORTfallback_taskz--fallback-taskzDotted path to a fallback task for unknown functions (e.g., myapp.tasks:my_fallback). Receives original args/kwargs and supports full dependency injection.DOCKET_FALLBACK_TASKc                 r    t        j                  t        j                  |||||||	|
|||||| |             y )N)docket_namerB   rD   rK   rM   rP   rR   rT   rV   rW   rY   rZ   r\   r   r^   )asynciorunr(   )r   r@   rB   rD   rF   rI   rK   rM   rP   rR   rT   rV   rW   rY   rZ   r\   r^   s                    r3   workerrd   ;   sJ    f KK

#11#9"7%=,K)-%'	
r2   z,Strikes a task or parameters from the docket*functionzThe function to strike)r)   rH   	parameterzThe parameter to strikeoperatorz)The operator to compare the value againstvaluez#The value to strike from the docketc           
           sst        j                  d      t        |      r) xs d }t        d| d dj                   d       nt        d         d fd}t        j                   |              y )N1Must provide either a function and/or a parametermessage(all tasks)z	Striking  c                     K   t              4 d {   } | j                         d {    d d d       d {    y 7 17 7 	# 1 d {  7  sw Y   y xY wwNrD   rB   )r#   striker5   r@   rf   rh   rg   rB   value_s    r3   rc   zstrike.<locals>.run  sg     wC0 	G 	GF--)XvFFF	G 	G 	GF	G 	G 	G 	GS   A"AA"AA	AA"AA"	AA"AAAA"r-   NtyperBadParameterr   r0   ri   rb   rc   	rf   rg   rh   ri   r@   rB   function_namerc   ru   s	   ``` ``  @r3   rs   rs      s    Z I  G
 	
 $E*F#4}5	-)Ahnn5EQvjQR	($%G G KKr2   z4Clear all queued and scheduled tasks from the docketc                 J     d fd}t        j                   |              y )Nc                     K   t              4 d {   } | j                          d {   }t        d| d d       d d d       d {    y 7 ?7 )7 	# 1 d {  7  sw Y   y xY ww)Nrr   zCleared z tasks from docket '')r#   clearr0   )r5   cleared_countr@   rB   s     r3   rc   zclear.<locals>.run6  su     wC0 	L 	LF"(,,.0MH]O+?yJK	L 	L 	L0	L 	L 	L 	LsT   A0AA0AAAA0AA0AA0A-!A$"A-)A0rw   rb   rc   )r@   rB   rc   s   `` r3   r   r   #  s    &L
 KKr2   z+Restores a task or parameters to the DocketzThe function to restorezThe parameter to restorez"The value to restore to the docketc           
           sst        j                  d      t        |      r) xs d }t        d| d dj                   d       nt        d         d fd}t        j                   |              y )Nrk   rl   rn   z
Restoring ro   c                     K   t              4 d {   } | j                         d {    d d d       d {    y 7 17 7 	# 1 d {  7  sw Y   y xY wwrq   )r#   restorert   s    r3   rc   zrestore.<locals>.runw  sg     wC0 	H 	HF..9hGGG	H 	H 	HG	H 	H 	H 	Hrv   rw   rx   r{   s	   ``` ``  @r3   r   r   >  s    Z I  G
 	
 $E*F#4}5
=/9+Qx~~6FazRS
8*%&H H KKr2   zRun docket's built-in tasks)r)   r+   	tasks_apprD   zAdds a trace task to the DocketzHowdy!rm   zThe message to printdelayz0The delay before the task is added to the docket)rO   r)   c                 R     d fd}t        j                   |              y )Nc                    K   t              4 d {   } t        j                  t        j                        z   } | j                  t        j                  |             d {   }t        d|j                  d| j                         d d d       d {    y 7 7 <7 	# 1 d {  7  sw Y   y xY ww)Nrr   zAdded trace task  to the docket )r#   r   nowr   utcaddr   tracer0   keyrD   r5   when	executionr   r@   rm   rB   s      r3   rc   ztrace.<locals>.run       wC0 	W 	WF<<-5D;fjjd;GDDI%imm%6ofkk_UV	W 	W 	WD	W 	W 	W 	WW   B?B$B?AB*)B&*)B*B?B(B?&B*(B?*B<0B31B<8B?rw   r   r@   rB   rm   r   rc   s   ```` r3   r   r          @W W KKr2   zAdds a fail task to the Docketc                 R     d fd}t        j                   |              y )Nc                    K   t              4 d {   } t        j                  t        j                        z   } | j                  t        j                  |             d {   }t        d|j                  d| j                         d d d       d {    y 7 7 <7 	# 1 d {  7  sw Y   y xY ww)Nrr   zAdded fail task r   )r#   r   r   r   r   r   r   failr0   r   rD   r   s      r3   rc   zfail.<locals>.run  s     wC0 	V 	VF<<-5D:fjjT:7CCI$Y]]$5_V[[OTU	V 	V 	VC	V 	V 	V 	Vr   rw   r   r   s   ```` r3   r   r     s     @V V KKr2   zAdds a sleep task to the Docket   r:   zThe number of seconds to sleepc                 R     d fd}t        j                   |              y )Nc                    K   t              4 d {   } t        j                  t        j                        z   } | j                  t        j                  |             d {   }t        d|j                  d| j                         d d d       d {    y 7 7 <7 	# 1 d {  7  sw Y   y xY ww)Nrr   zAdded sleep task r   )r#   r   r   r   r   r   r   sleepr0   r   rD   )r5   r   r   r   r@   r:   rB   s      r3   rc   zsleep.<locals>.run  r   r   rw   r   )r@   rB   r:   r   rc   s   ```` r3   r   r     r   r2   z2Shows a snapshot of what's on the docket right nowstatsz--statsz+Show task count statistics by function namec           
          dt         f fd}t        j                   |             }t        t        |j
                        }t               }ddt        |j
                         t        |j                         dt        |j                         d|j                   dg}t        dj                  |      	      }	|	j                  d
d       |	j                  dd       |	j                  dd       |	j                  dd       |	j                  dd       |j                  D ]U  }
|	j                   ||
j                         |
j"                  |
j$                  |
j&                   ||
j(                               W |j*                  D ];  }
|	j                   ||
j                         |
j"                  |
j$                  dd       = |j-                  |	       |rlt/        |      r]|j-                          t        d	      }|j                  dd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       |j                  ddd       t1        j3                         fdd       D ]  }|   }d}d}|j4                   ||j4                        }|j6                   ||j6                        }|j                  |t9        |j:                        t9        |j                        t9        |j<                        ||        |j-                  |       y y y )!Nr-   c                     K   t              4 d {   } D ]  }| j                  |        | j                          d {   cd d d       d {    S 7 E7 7 	# 1 d {  7  sw Y   y xY wwrq   )r#   register_collectionsnapshot)r5   	task_pathr@   r   rB   s     r3   rc   zsnapshot.<locals>.run%  st     wC0 	+ 	+F" 6	**956  **		+ 	+ 	+ +		+ 	+ 	+ 	+sV   A6AA6,A!AA!	A6AA6A!A6!A3'A*(A3/A6zDocket: zas of z
 workers, /z running
)titleWhengreenstyleFunctioncyanKeyr(   yellowStarted z!Task Count Statistics by FunctionTotalzbold magentaright)r   justifyRunningQueuedzOldest Queuedz
dim yellowzLatest Queuedc                 "    |    j                   S r/   )total)x
task_statss    r3   <lambda>zsnapshot.<locals>.<lambda>e  s    A1D1D r2   T)r   reverse)r$   rb   rc   r   r   takenr	   r   lenworkersrunningtotal_tasksr   join
add_columnadd_rowr   r|   r   rd   startedfuturer0   r   sortedkeysoldest_queuedlatest_queuedstrr   queued)r   r@   rB   r   rc   r   relativeconsolesummary_linestabler   stats_table	func_namecountsr   r   r   s   ```             @r3   r   r     s   L+~ + {{35!H}hnn5HiG 7+
HNN+,-8##$%Z8##$%Qx';';&<HF	M 		-01E	V7+	Zv.	U&)	XX.	Yg.%% 
	Y^^$##MMY&&'	

 __ 
	Y^^$##MM	

 MM% #H-
MMO&IJK"":V"<""7.'"R""9GW"M""88W"M""?,PW"X""?,PW"X $!'Dd 	 $I. !# "''3$,V-A-A$BM''3$,V-A-A$BM##%'&!!, MM+&C  r2   z-Monitor progress of a specific task executionr   z!The task execution key to monitorz--urlz-uDOCKET_REDIS_URLz*Redis URL (e.g., redis://localhost:6379/0))r?   r)   ra   z-dzDocket namec                 N     d fd}t        j                   |              y)zZMonitor the progress of a specific task execution in real-time using event-driven updates.Nc                  	  K   t              4 d {   } | j                         d {   }|s3t               }|j                  d dd       	 d d d       d {    y t               }t        j
                  dt        j                  dt        j                  dt        j                  dt        j                  d	i|j                          d {    |j                  |j                  |j                  |j                  j                  |j                  j                  nd
}|j                  j                   }|j                  j"                  }t%        t'        d      t)        d       t+               t-               d      d dt.        dt0        dd ffd}|d
kD  r<|d
kD  r7j3                  |xs d||      |j4                   ||j4                         dt6        ffd} |       }t        j                  t        j                  fv r#|j                  |       	 d d d       d {    y t9        ||d      5 }	d}
t;        |j=                         |
      2 3 d {   }||j                          d {    |j                  k7  rWd|j                  j>                  |j                  |j                  |j4                  r|j4                  jA                         nd d}n|d   dk(  rt	        |d         |jC                  d      x}r||jC                  d      x}r||jC                  d      x}r/t1        jD                  |      |_         ||j4                          |       }|	jG                  |       t        j                  t        j                  fv sH n|d   dk(  sT|d   }|jC                  d |j                  j                         }|jC                  d!|j                  j"                        }|d
kD  re|j4                  Y>j3                  |xs d||xs d
      |j4                  x}r- ||j4                         njG                  |||xs d"        |       }|	jG                  |       )d d d        d d d       d {    y 7 7 7 T7 7 7 M7 66 0# 1 sw Y   1xY w7 (# 1 d {  7  sw Y   y xY ww)#Nz![red]Error:[/red] Task with key 'z&' not found or function not registeredboldr   r   r   bluer   redr   z[bold blue]{task.description})	bar_widthT)expandtask_id
started_atr-   c                     t        j                  t        j                        |z
  }t	        j
                         |j                         z
  }|j                  |    _        y)z:Set progress bar start time based on execution start time.N)	r   r   r   r   time	monotonictotal_secondsr   
start_time)r   r   elapsed_since_startmonotonic_startactive_progresss       r3   set_progress_start_timez7watch.<locals>.monitor.<locals>.set_progress_start_time  sI    &.ll8<<&@:&M#"&.."25H5V5V5X"X<K%%g.9r2   zProcessing...)r   	completedc            	      l   t               } d d g}
j                  d      }|j                  d| dj                  j	                          d| d       r|j                  d        r|j                  d        t
        j                  k(  r|j                  d	       n$t
        j                  k(  r|j                  d
       dj                  |      }	5| j                  t        |dt        |            t        dd             | S | j                  t        |d             | S )z$Create the layout for watch display.z[bold]Task:[/bold] z[bold]Docket:[/bold] whitez[bold]State:[/bold] []z[/z[bold]Worker:[/bold] z[red bold]Error:[/red bold] u8   [green bold]✓ Task completed successfully[/green bold]u$   [red bold]✗ Task failed[/red bold]r   info)rD   sizeprogress   r   )r
   getappendri   upperr&   	COMPLETEDFAILEDr   split_columnr   update)layout
info_linesstate_colorinfo_sectionr   current_statera   error_messager   progress_task_idstate_colorsworker_names       r3   create_display_layoutz5watch.<locals>.monitor.<locals>.create_display_layout  sN    *#/+K=9
 +..}gF!!+K=-:M:M:S:S:U9VVXYdXeefg
 %%(=k]&KL !%%(D]O&TU !N$<$<<%%R #n&;&;;%%&LM#yy4 $/ ''|&s:OZaH  MM&F"CDr2      )r   refresh_per_secondg      ?state)typer  rd   errorr   r  rd   r  r   currentr   rm   )r   r   description)$r#   get_executionr	   r0   r&   	SCHEDULEDQUEUEDRUNNINGr   r   syncr  rd   r  r   r  r   rm   r   r   r   r   r   r   r   add_taskr   r
   r   r   	subscriberi   	isoformatr   fromisoformatr   )r5   r   r   current_val	total_valprogress_messager   r   r   livepoll_intervaleventrd   r  r   r   r   r   r   r   r   ra   r   rB   s                  @@@@@@r3   monitorzwatch.<locals>.monitor  s!    +s+ R	, R	,v$22377I!)7u<bc    R	, R	, R	, iG (((%%v&&(('%%uL ..""" &OOM&/&6&6K(1M
 %%--9 ""** 
 "**00I(1199&:;D)"$!#O  $L LX LRV L Q9q=#2#;#;$7#) $< $  ''3+,<i>R>RS.6 . .b +,F !9!9>;P;P QQf%oR	, R	, R	,t fg!D X, !$#7'')=$ S, S,% }'nn...$??m; )0)2)>)>*3*:*:)2 (1';'; %.$8$8$B$B$D)-
%E % V}/(6uW~(F%*YYx%8868*0K$)IIg$6656,1M).<)@@:@3;3I3I*3UI0/; 7$4i6J6J!"
 "7!8F+ )*44*11-  "v*4&+I&6).7I<N<N<T<T)U	+099%y'9'9'A'A,(
 %q=Y-A-A-M/73B3K3K$4$G*3.9.>Q 4L 4" 0 2;1E1E#E:#E$;(8):N:N%&
 !0 6 6$4.9*30@0SO	 !7 !" "7!8F+qX,uR	, R	, R	,7R	,, #-R	,~S,
 /$X, X,uR	, R	, R	, R	,s   S/R5S/SR8(SS/'R;(S/-A/SR>ES7S/SS/SS3S
7S
8S
;SS
D'S;
SCSS$S//S0S/8S;S/>SS/S
S
SS	SS/S, S#!S,(S/rw   r   )r   rB   ra   r  s   ``` r3   watchr  }  s    0S,j KK	r2   zLook at the workers on a docketworkers_appr   lszList all workers on the docket)rD   r)   c                 |     dt         t           f fd}t        j                   |             }t	         |       y )Nr-   c                     K   t              4 d {   } | j                          d {   cd d d       d {    S 7 -7 7 	# 1 d {  7  sw Y   y xY wwrq   )r#   r   )r5   r@   rB   s    r3   rc   zlist_workers.<locals>.run  sS     wC0 	* 	*F))	* 	* 	*)	* 	* 	* 	*sQ   AAAA	AA	AAAA	A	AAAAr   r%   rb   rc   r   )r@   rB   rc   r   s   ``  r3   list_workersr  s  s0    &*z*- * kk#% G'7#r2   zfor-taskz>List the workers on the docket that can process a certain tasktaskzThe name of the taskc                      dt         t           f fd}t        j                   |             }t	        |        y )Nr-   c                     K   t              4 d {   } | j                         d {   cd d d       d {    S 7 .7 7 	# 1 d {  7  sw Y   y xY wwrq   )r#   task_workers)r5   r@   r  rB   s    r3   rc   zworkers_for_task.<locals>.run  sW     wC0 	3 	3F,,T22	3 	3 	32	3 	3 	3 	3sQ   AAAA
AA
AAAA
A
AAAA)highlight_taskr  )r  r@   rB   rc   r   s   ```  r3   workers_for_taskr#    s2    83z*- 3 kk#% G'748r2   rw   )r5   r6   )r6   r5   )Wrb   sysr   r   r   r   	functoolsr   typingr   r   ry   rich.consoler	   rich.layoutr
   	rich.liver   rich.progressr   r   r   r   r   r   
rich.tabler   r5   r   r   docket.cli._supportr   r   r   r   r   r   r   r   r   r   r   r    r!   r"   docket.docketr#   r$   r%   docket.executionr&   docket.strikelistr'   docket.workerr(   Typerr,   __annotations__commandr4   INFOstdoutisattyRICHPLAINlistr   Optionintboolrd   EQUALArgumentrs   r   r   r   	add_typerr   r   floatr   r   r  r  r  r#  r1   r2   r3   <module>rA     sI    
  2 2  (        %     = < + &   5;;	MU[[  	&   	*   
'' 	 	# 	 	 **++-	9?? 	 	! 	! 	s# 	s# 	 	 	 	 	 	]bS	/ "	
		b ) 	
	b* 
.	
	
+b8 d
)'	
	9bF $)&	
	GbV %*'	
	Wbf F.	
	gbt "P5	
	ubD "% 6	
	
EbZ &:9	
	[bj %K8	
	kbz ((+	
	{bH &/TSB	
	&IbX <	
	Ybf  d
 53	
	gbv d
:/	
	wbF d
: *	
		Gb^ 
_bbJ @A 	 	 	 	 	 	#U<)+	
	< *+	
	< <	
	<* d
6	
	+<6 ) 	
	7<F 
.!	
	
G<V 
W< B<~ HI 	 	#!) 	
	 
.!	
	
" 
# J4 ?@ 	 	 	 	 	 	#U<*+	
	< ++	
	< <	
	<* d
5	
	+<6 ) 	
	7<F 
.!	
	
G<V 
W< A<~ %	&	5;;  ig & 9: 	 	# 	 	!;%) 	
	% 
.!	
	
%" '	
	#%. C	
	/%< 
=% ;%P 89 	 	# 	 	!;%) 	
	% 
.!	
	
%" '	
	#%. C	
	/%< 
=% :%P 9: 	 	# 	
 	!;%) 	
	% 
.!	
	
%" 1	
	#%. C	
	/%< 
=% ;%P FG 
'' 	 	# 	Gz'S	/ "	
		z' ) 	
	z'* 
.!	
	
+z': >	
	;z'H 
Iz' Hz'z AB 	# 	'l	3,OPP	Ql	%=		
	
l  		
	l( 
)l Cl^ '5;;	*DU[[  k	 * $%EF 	 	#!$) 	
	$ 
.!	
	
$" 
#$ G$6 		I  $ 	 	#-9
'	
	9 ) 	
	9 
.!	
	
9. 
/9	9r2   