
    Mhh`                       d dl mZ d dlZd dlZd dlZd dl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ZmZmZmZmZmZ d dlmZ er/ej        ej        z  ej        z  ej        z  ej        z  ej        z  Zdd
ZddZ G d de          Z G d de          Z G d dej                   Z! G d d          Z" G d de          Z#dS )    )annotationsN)
ModuleType)TYPE_CHECKINGAny	GeneratorIterable
NamedTuplecast)DeduperReloaderPatchingMixinmoduleModuleType | strreturnstrc                    t          | t                    rt          j                            |           n| x}dS t          |dd          pdS )zHReturns the module's file path, or the empty string if it's inaccessibleN __file__)
isinstancer   sysmodulesgetgetattr)r   mods     n/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/IPython/extensions/deduperreload/deduperreload.pyget_module_file_namer      sK    *4VS*A*AMs{v&&&vMVr3
B''-2-    node1ast.AST | list[ast.AST]node2boolc                   t          |           t          |          urdS t          | t          j                  rW| j                                        D ];\  }}|dv r
t          ||          rt          |t          ||                    s dS <dS t          | t                    r\t          |t                    rGt          |           t          |          k    o&t          d t          | |          D                       S | |k    S )zYChecks if node1 and node2 have identical AST structure/values, apart from some attributesF)lineno
end_lineno
col_offsetend_col_offsetctxparentTc              3  <   K   | ]\  }}t          ||          V  d S N)compare_ast).0n1n2s      r   	<genexpr>zcompare_ast.<locals>.<genexpr>:   sA       0
 0
$*BKB0
 0
 0
 0
 0
 0
r   )typer   astAST__dict__itemshasattrr)   r   listlenallzip)r   r   kvs       r   r)   r)   #   s.   E{{$u++%%u%!! N((** 	 	DAq    5!$$ K75!;L;L,M,M uut	E4	 	  Zt& &  5zzSZZ' 
C 0
 0
.1%.?.?0
 0
 0
 -
 -
 	
 ~r   c                  (    e Zd ZU dZded<   ded<   dS )DependencyNodea  
    Each node represents a function.
    qualified_name: string which represents the namespace/name of the function
    abstract_syntax_tree: subtree of the overall module which corresponds to this function

    qualified_name is of the structure: (namespace1, namespace2, ..., name)

    For example, foo() in the following would be represented as (A, B, foo):

    class A:
        class B:
            def foo():
                pass
    tuple[str, ...]qualified_nameast.ASTabstract_syntax_treeN)__name__
__module____qualname____doc____annotations__ r   r   r;   r;   A   s6           $###!!!!!!r   r;   c                  ~    e Zd ZU g Zded<   g Zded<   g Zded<   i Zded<   g Zd	ed
<   e	dd            Z
ddZddZdS )GatherResultz9list[tuple[tuple[str, ...], ast.Import | ast.ImportFrom]]import_defsz8list[tuple[tuple[str, ...], ast.Assign | ast.AnnAssign]]assign_defszDlist[tuple[tuple[str, ...], ast.FunctionDef | ast.AsyncFunctionDef]]function_defszdict[str, ast.ClassDef]classeszlist[ast.AST]	unfixabler   c                      | g g g i g           S r(   rE   )clss    r   createzGatherResult.create^   s    s2r2r2&&&r   0Iterable[tuple[tuple[str, ...], TDefinitionAst]]c                L    t          j        | j        | j        | j                  S r(   )	itertoolschainrH   rI   rJ   selfs    r   all_defszGatherResult.all_defsb   s    t/1A4CUVVVr   otherNonec                <   | j                             |j                    | j                            |j                   | j                            |j                   | j                            |j                   | j                            |j                   d S r(   )rH   extendrI   rJ   rK   updaterL   )rU   rW   s     r   inplace_mergezGatherResult.inplace_mergee   s     1222 1222!!%"5666EM***eo.....r   N)r   rG   )r   rP   )rW   rG   r   rX   )r@   rA   rB   rH   rD   rI   rJ   rK   rL   classmethodrO   rV   r\   rE   r   r   rG   rG   U   s         MOKOOOOLNKNNNN 	      (*G))))!I!!!!' ' ' ['W W W W/ / / / / /r   rG   c                  b     e Zd ZddZej        dd            ZddZdd
Zd fdZ	ddZ
 xZS )ConstexprDetectorr   rX   c                "    d| _         d| _        d S NT)is_constexpr_allow_builtins_exceptionsrT   s    r   __init__zConstexprDetector.__init__n   s     *.'''r   Generator[None, None, None]c              #  V   K   | j         }d| _         	 d V  || _         d S # || _         w xY wNF)rc   )rU   
prev_allows     r   disallow_builtins_exceptionsz.ConstexprDetector.disallow_builtins_exceptionsr   sF      4
*/'	9EEE.8D+++jD+8888s    	(nodeast.Attributec                    |                                  5  |                     |j                   d d d            d S # 1 swxY w Y   d S r(   )ri   visitvaluerU   rj   s     r   visit_Attributez!ConstexprDetector.visit_Attribute{   s    ..00 	# 	#JJtz"""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#s   =AAast.Namec                Z    | j         rt          t          |j                  rd S d| _        d S rg   )rc   r3   builtinsidrb   ro   s     r   
visit_NamezConstexprDetector.visit_Name   s3    * 	wx/I/I 	F!r   r>   c                \    | j         sd S t                                          |           d S r(   )rb   superrm   )rU   rj   	__class__s     r   rm   zConstexprDetector.visit   s/      	Fdr   r   c                H    d| _         |                     |           | j         S ra   )rb   rm   ro   s     r   __call__zConstexprDetector.__call__   s%     

4  r   r   rX   )r   re   )rj   rk   r   rX   )rj   rq   r   rX   )rj   r>   r   rX   )rj   r>   r   r   )r@   rA   rB   rd   
contextlibcontextmanagerri   rp   ru   rm   rz   __classcell__)rx   s   @r   r_   r_   m   s        / / / / 9 9 9 9# # # #" " " "
     ! ! ! ! ! ! ! !r   r_   c                  "    e Zd ZdZd	dZd
dZdS )AutoreloadTreea  
    Recursive data structure to keep track of reloadable functions/methods. Each object corresponds to a specific scope level.
    children: classes inside given scope, maps class name to autoreload tree for that class's scope
    funcs_to_autoreload: list of function names that can be autoreloaded in given scope.
    new_nested_classes: Classes getting added in new autoreload cycle
    r   rX   c                V    i | _         g | _        t                      | _        i | _        d S r(   )childrendefs_to_reloadsetdefs_to_deletenew_nested_classesrT   s    r   rd   zAutoreloadTree.__init__   s+    35EG(+68r   prefixes	list[str]c                l    | }|D ].}||j         vrt                      |j         |<   |j         |         }/|S )zY
        Return ref to the AutoreloadTree at the namespace specified by prefixes
        )r   r   )rU   r   curprefixs       r   traverse_prefixesz AutoreloadTree.traverse_prefixes   sJ      	' 	'FS\))'5'7'7V$,v&CC
r   Nr{   )r   r   r   r   )r@   rA   rB   rC   rd   r   rE   r   r   r   r      sF         9 9 9 9	 	 	 	 	 	r   r   c                  $   e Zd ZdZd1dZed2d            Zej        d3d            Zd1d	Z e	            Z
ed4d            Zed5d            Zed6d            Z	 d7d8dZd2dZd9dZ	 d7d:dZd;d!Z	 d7d<d$Z	 d7d<d%Zd=d(Zd>d,Z	 d7d?d.Zd@d0ZdS )ADeduperReloadera  
    This version of autoreload detects when we can leverage targeted recompilation of a subset of a module and patching
    existing function/method objects to reflect these changes.

    Detects what functions/methods can be reloaded by recursively comparing the old/new AST of module-level classes,
    module-level classes' methods, recursing through nested classes' methods. If other changes are made, original
    autoreload algorithm is called directly.
    r   rX   c                V    t                      | _        i | _        i | _        d| _        d S ra   )r   _to_autoreloadsource_by_modnamedependency_graph_enabledrT   s    r   rd   zDeduperReloader.__init__   s+    .<.>.>13MOr   r   c                >    | j         ot          j                    dk    S )NCPython)r   platformpython_implementationrT   s    r   enabledzDeduperReloader.enabled   s    }N!?!A!AY!NNr   rn   c                    || _         d S r(   )r   )rU   rn   s     r   r   zDeduperReloader.enabled   s    r   c                   | j         sdS t          j                                        | j                                        z
  D ]}t          j        |         }t          |          x}	 'd|v s#d|v st          j        |t          j                  sd| j        |<   Xt          |d          5 }	 |
                                | j        |<   n# t          $ r d| j        |<   Y nw xY wddd           n# 1 swxY w Y   dS )zY
        Update dictionary source_by_modname with current modules' source codes.
        Nzsite-packageszdist-packagesr   r)r   r   r   keysr   r   osaccessR_OKopenread	Exception)rU   new_modname
new_modulefnamefs        r   update_sourceszDeduperReloader.update_sources   s^    | 	F;++--0F0K0K0M0MM 	= 	=K[1J.z:::"e++"e++y00 , 79&{3eS!! =Q=:;&&((D*;77  = = =:<D*;777== = = = = = = = = = = = = = =	= 	=s6   *C/,C	C/	C C/C  C//C3	6C3	rj   ast.Module | ast.ClassDefc                P   t          | t          j                  rdS | j        D ]}t          |t          j                  r|j        dk    r dS t          |t          j                  r=|j        dk    r2t          |j        t          j                  r|j        j        dk    r dS dS )NFEnumTenum)	r   r/   ModulebasesNamert   	Attributeattrrn   )rj   bases     r   is_enum_subclassz DeduperReloader.is_enum_subclass   s    dCJ'' 	5J 		 		D$)) dg.?.?tt4//I''tz3844 (JMV++ttur   r>   parent_nodec                T   t          |t          j        t          j        f          r|j        dS |                     |          rdS t          |t          j                  r|j        n|j        gD ]}t          |t          j                  s dS  | 	                    |j                  S rg   )
r   r/   Assign	AnnAssignrn   r   targetstargetr   constexpr_detector)rN   rj   r   r   s       r   is_constexpr_assignz#DeduperReloader.is_constexpr_assign   s     $S] ;<< 	
@R5,, 	5&0sz&B&BUdll 	 	Ffch// uu%%dj111r   bodylist[ast.stmt]rG   c                >   t                                           }|D ]}|}t          |t          j                  r!|j        }t          |t          j                  !t          |t          j        t          j        f          r#|j        	                    |j
        f|f           t          |t          j        t          j        f          r9|j        	                    t          d |j        D                       |f           t          |t          j                  r||j        |j
        <   t          |t          j                  r}|j        	                    |j                   |                    |                     |j        |                     |                    |                     |j        |                     t          |t          j        t          j        f          rO|j                            |j                   |                    |                     |j        |                     t          |t          j                  r|                    |                     |j        |                     |                    |                     |j        |                     |                    |                     |j        |                     |j        D ]V}|j         |j        	                    |j                    |                    |                     |j        |                     W#t          |t          j!        t          j"        f          s| #                    ||          rt          |t          j$        t          j%        f          sJ t          |t          j$                  r|j&        n|j'        g}|j(        	                    t          d |D                       |f           |j        	                    |           |S )z
        Given list of ast elements, return:
        1. dict mapping function names to their ASTs.
        2. dict mapping class names to their ASTs.
        3. list of any other ASTs.
        c              3  2   K   | ]}|j         p|j        V  d S r(   )asnamename)r*   r   s     r   r-   z3DeduperReloader._gather_children.<locals>.<genexpr>  s+      NN4;3$)NNNNNNr   Nc              3  T   K   | ]#}t          t          j        |          j        V  $d S r(   )r
   r/   r   rt   )r*   r   s     r   r-   z3DeduperReloader._gather_children.<locals>.<genexpr>,  s1      !R!R$sx"8"8";!R!R!R!R!R!Rr   ))rG   rO   r   r/   Exprrn   FunctionDefAsyncFunctionDefrJ   appendr   Import
ImportFromrH   tuplenamesClassDefrK   IfrL   testr\   _gather_childrenr   orelse	AsyncWithWithrZ   r2   Try	finalbodyhandlersr.   EllipsisPassr   r   r   r   r   rI   )rN   r   r   resultast_nodeast_elthandlerr   s           r   r   z DeduperReloader._gather_children   s    $$&& .	5 .	5H+3GWch// (!- Wch// ('COS5I#JKK *5$++gl_g,FGGGGGcj#.%ABB (5"))NNNNNNNPWX    GS\22 $5/6w|,,GSV,, "5 ''555$$S%9%9',%T%TUUU$$S%9%9'.+%V%VWWWWGcmSX%>?? 5 ''666$$S%9%9',%T%TUUUUGSW-- 5$$S%9%9',%T%TUUU$$S%9%9'.+%V%VWWW$$(():KHH    '/  G|/(//===((,,W\;GG     #,)ABB 5**7K@@ 5%g
CM/JKKKKK &gsz::.%n- 
 &--!!R!R'!R!R!RRR#    $++G444r   Nold_nodenew_noder   list[str] | Nonec                   | j         sdS |pg }|                     |j        |          }|                     |j        |          }d |                                D             }d |                                D             }t	          |j        |j                  sdS | j                            |          }|                                D ]q\  }	}
g }|	D ]<}||         |
ur||vst	          |
||                   s|                    |           =|r)|j	                            t          |	          |
f           r|xj        t          |                                          t          |                                          z
  z  c_        |j                                        D ]]\  }}||j        vr||j        |<   t	          ||j        |                   s)|                     |j        |         |||gz             s dS ^dS )z
        Returns
        -------
        `True` if we can run our targeted autoreload algorithm safely.
        `False` if we should instead use IPython's original autoreload implementation.
        Fc                $    i | ]\  }}|D ]}||S rE   rE   r*   r   ast_defr   s       r   
<dictcomp>z5DeduperReloader.detect_autoreload.<locals>.<dictcomp>F  @     0
 0
 0
,eWRW0
 0
JND'0
 0
 0
 0
r   c                $    i | ]\  }}|D ]}||S rE   rE   r   s       r   r   z5DeduperReloader.detect_autoreload.<locals>.<dictcomp>I  r   r   T)r   r   r   rV   r)   rL   r   r   r   r   r   r   r   r   rK   r2   r   detect_autoreload)rU   r   r   r   
old_result
new_resultold_defs_by_namenew_defs_by_namer   r   new_ast_defnames_to_reloadr   new_ast_def_classs                 r   r   z!DeduperReloader.detect_autoreload4  ss    | 	5>r**8=(CC
**8=(CC
0
 0
0:0C0C0E0E0
 0
 0
0
 0
0:0C0C0E0E0
 0
 0
 :/1EFF 	5!33H==","5"5"7"7 
	G 
	GE; O 1 1#D)<<///{!1$!78 8/ $**4000 G"))5<<*EFFFc"2"7"7"9"9::S!!##>
 >
 
 	
 (2'9'?'?'A'A 	 	#D#:---/@&t,, !:#5d#;  ,,"4(*;X=N 
 uutr   c                ^    |                                  D ]}|                     |           dS )z
        If a decorator function is modified, we should similarly reload the functions which are decorated by this
        decorator. Iterate through the Dependency Graph to find such cases in the given AutoreloadTree.
        T)_check_dependents_inner_add_node_to_autoreload_treero   s     r   _check_dependentsz!DeduperReloader._check_dependentsj  s;    
 0022 	4 	4D--d3333tr   r;   c                   t          |j                  dk    rdS | j                            t	          |j        dd                             }|j        /|j                            |j        d         f|j        f           dS dS )zj
        Given a node of the dependency graph, add decorator dependencies to the autoreload tree.
        r   N)r5   r=   r   r   r4   r?   r   r   )rU   rj   r   s      r   r   z,DeduperReloader._add_node_to_autoreload_trees  s     t"##q((F!33D9LSbS9Q4R4RSS$0%%%b)+T-FG     10r   list[DependencyNode]c                F   |pg }| j                             |          }g }|j        D ]B\  ^}}}t          ||gz             }|                    |                     |                     C|j        D ].}|                    |                     ||gz                        /|S r(   )r   r   r   r   rZ   _gen_dependentsr   r   )rU   r   r   ans	func_name_rj   
class_names           r   r   z'DeduperReloader._check_dependents_inner  s     >r!33H=="%"4 	3 	3OYQYK/00DJJt++D1122220 	N 	NJJJt33H
|4KLLMMMM
r   qualnamer<   c                    g }|| j         vrg S | j         |         D ]D}|                    |                     |j                             |                    |           E|S r(   )r   rZ   r   r=   r   )rU   r   r   elts       r   r   zDeduperReloader._gen_dependents  sj    4000I(2 	 	CJJt++C,>??@@@JJsOOOO
r   nsModuleType | typec           	        |pg }| j                             |          }|}|D ]}|j        |         }|j        D ]\  }}i }t	          |t
          j        t
          j        f          r|d         x}	|j        v rnt          |          dk    sJ |j        |	         }
t	          |
t          t          f          r|
j        }
t          j        t          j        |                    }t          |          dk    x}rdt          j        |d          z   }|j        }t!          |
d          r|
j        }nPt	          |
t$                    r;|
j        |
j        j        }n'|
j        |
j        j        }n|
j        |
j        j        }t	          |t,                    st-          |          }t/          |||           |rt1          |d         |	          }n||	         }t	          |t          t          f          r|j        }t	          |
t$                    rt	          |t$                    rrdD ]m}t1          |
|          t1          ||          |                     |
||           :|                     t1          |
|          t1          ||          |           n]t	          |
t$                    s.t	          |t$                    s|                     |
||           t7          d	          t/          t          j        |          |j        |j        z  |           |D ]}	t9          ||	||	                    |j                                         |j        D ]0}		 t?          ||	           # t@          tB          t6          f$ r Y -w xY w|j                                         |j"        #                                D ]N\  }}i }t/          t          j        |          |j        |j        z  |           t9          ||||                    O|j"                                         |j$        %                                D ]}| &                    |||gz             s d
S  |j$                                         dS )a  
        This function patches module functions and methods. Specifically, only objects with their name in
        self.to_autoreload will be considered for patching. If an object has been marked to be autoreloaded,
        new_source_code gets executed in the old version's global environment. Then, replace the old function's
        attributes with the new function's attributes.
        r      zclass __autoreload_class__:
z    __globals__N__autoreload_class__)fgetfsetfdelz5adding or removing property decorations not supportedFT)'r   r   r1   r   r   r/   r   r   r5   staticmethodr]   __func__textwrapdedentunparseindentr3   r   propertyr  r  r  dictexecr   try_patch_attrpatch_function
ValueErrorsetattrclearr   delattrAttributeError	TypeErrorr   r2   r   r   _patch_namespace)rU   r   r   r   namespace_to_checkr   r   r   	local_envr   to_patch_to	func_code	is_method
global_envto_patch_fromr   r   class_ast_nodelocal_env_classs                      r   _patch_namespace_innerz&DeduperReloader._patch_namespace_inner  s    >r!33H== 	E 	EF!3!<V!D"%"4 B	G B	GE;(*I;#:N(OPP@G"1X%T*<*EEE5zzQ09$?kL++FGG 7"-"6K$OCK,D,DEE	!$X!239  ?(/!6C C !I 08
;66 B!,!8JJX66 B"'3%0%5%A

$)5%0%5%A

$)5%0%5%A
!*d33 2!%j!1!1JY
I666 4$+I6L,Mt$T$TMM$-dOMmlK-HII ;$1$:Mk844 !8: :  !9  #K66>&}d;;C //]DQQQQ // 'T : : 't < < )    $K:: :!8D D  '']INNNN$O   K,,K"4"==  
 " G GD.ioFFFFG  """& 	 	D*D1111"Iz:    	  """*-*@*F*F*H*H 	Q 	Q&J.0ON++099  
 &
OJ4OPPPP$$&&&,++-- 	 	J((X-DEE uuts   M++NNc                T    	 |                      ||          S # t          $ r Y dS w xY w)z
        Wrapper for patching all elements in a namespace as specified by the to_autoreload member variable.
        Returns `true` if patching was successful, and `false` if unsuccessful.
        )r   F)r   r   )rU   r   r   s      r   r  z DeduperReloader._patch_namespace  sB    	..rH.EEE 	 	 	55	s    
''r   r   c                   | j         sdS t          |dd          x}sdS t          |          x}dS t          |d          5 }|                                }ddd           n# 1 swxY w Y   d}| j                            |          x}r	 t          j        |          }t          j        |          }	n# t          $ r Y dS w xY wt          j                    }
|
5  |                     |	           |                     ||	          r+|                                 r|                     |          rd}ddd           n# 1 swxY w Y   || j        |<   t!                      | _        |S )zy
        Uses Deduperreload to try to update a module.
        Returns `true` on success and `false` on failure.
        Fr@   Nr   T)r   r   r   r   r   r   r   r/   parser   r|   suppress_build_dependency_graphr   r   r  r   r   )rU   r   modnamer   r   new_source_codepatched_flagold_source_codeold_module_astnew_module_astr%   s              r   maybe_reload_modulez#DeduperReloader.maybe_reload_module	  s   
 | 	5"6:t<<< 	5)&111E:5% 	'ffhhO	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	'"488AAA? 	(!$?!;!;!$?!;!;   uu %''C ( (,,^<<<**>>JJ(..00( --f55(
 $(L( ( ( ( ( ( ( ( ( ( ( ( ( ( ( +:w',..s7   A##A'*A'(B6 6
CCAD??EE	decorator.ast.Attribute | ast.Name | ast.Call | ast.expraccept_callsc                D   t          |t          j                  r|j        gS t          |t          j                  r|r|                     |j        d          S dS t          |t          j                  sdS |                     |j        d          x}r||j	        gz   S dS )ze
        Generates a qualified name for a given decorator by finding its relative namespace.
        FN)
r   r/   r   rt   Call_separate_namefuncr   rn   r   )rU   r-  r/  prefs       r   r2  zDeduperReloader._separate_name-  s     i** 	L>!	38,, 	 **9>5AAAt)S]33 	4&&y>>>4 	9>***4r   body_prefixesc                   |pg }|D ]}|}t          |t          j                  r%|                     |j        ||j        gz              Ct          |t          j        t          j        f          sjt          ||j        gz             }t          ||          }|j
        D ]X}|                     |d          }|st          |          }	| j                            |	g                               |           YdS ra   )r   r/   r   _gather_dependentsr   r   r   r   r   r;   decorator_listr2  r   
setdefaultr   )
rU   r   r5  r   r   r=   cur_dependency_noder-  decorator_pathdecorator_path_tuples
             r   r7  z"DeduperReloader._gather_dependentsC  s    &+ 	 	H+3G'3<00 ''mw|n6TUUUg9M'NOO "=GL>#ABBN"0"I"I$3  	!%!4!4Y!E!E% ',^'<'<$%001ErJJQQ'    tr   new_astc                6    |                      |j                  S )z
        Wrapper function for generating dependency graph given some AST.
        Returns `true` on success. Returns `false` on failure.
        Currently, only returns `true` as we do not block on failure to build this graph.
        )r7  r   )rU   r=  s     r   r%  z'DeduperReloader._build_dependency_graphZ  s     &&w|444r   r{   )r   r   )rn   r   r   rX   )rj   r   r   r   )rj   r>   r   r   r   r   )r   r   r   r   r   rG   r(   )r   r   r   r   r   r   r   r   )rj   r;   r   rX   )r   r   r   r   )r   r<   r   r   )r   r   r   r   r   r   )r   r   r   r   )r-  r.  r/  r   r   r   )r   r   r5  r   r   r   )r=  r   r   r   )r@   rA   rB   rC   rd   r  r   setterr   r_   r   r  r   r]   r   r   r   r   r   r   r   r   r  r,  r2  r7  r%  rE   r   r   r   r      s            O O O XO ^   ^= = = =. +*,,   \ 
2 
2 
2 [
2 9 9 9 [9~ &*	4 4 4 4 4l   
 
 
 
 ,0        CGf f f f fR CG
 
 
 
 
" " " "H   . GK    .5 5 5 5 5 5r   r   )r   r   r   r   )r   r   r   r   r   r   )$
__future__r   r/   rs   r|   rR   r   r   r   r  typesr   typingr   r   r   r   r	   r
   7IPython.extensions.deduperreload.deduperreload_patchingr   r   r   r   r   r   r   TDefinitionAstr   r)   r;   rG   NodeVisitorr_   r   r   rE   r   r   <module>rF     s"   " " " " " " 



          				  



        L L L L L L L L L L L L L L L L       

	
*	 .	 *		
 -	 . . . .   <" " " " "Z " " "(/ / / / /: / / /0 !  !  !  !  !  !  !  !F       4v5 v5 v5 v5 v52 v5 v5 v5 v5 v5r   