Ë
    g^(h32  ã                   óˆ  — U d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
mZ ddlmZ ddlZddlZddlmZmZ ddlmZmZmZ dd	lmZmZ d
dlmZ d
dlmZ d
dlmZ d
dl m!Z! eejD                  e#e$e%f   Z&de&fd„Z'de&fd„Z(e G d„ d«      «       Z) G d„ d«      Z*e G d„ d«      «       Z+ee+e,d   f   Z-ee.d<    G d„ de«      Z/y)aÝ  This file implements the IndexPropagation ops handler, which wraps an
underlying handler to add a limited form of constant propagation, as well as
propagation of sympy expressions downstream of ops.index_expr calls.

For example, say we have the IR:

    tmp0 = ops.index_expr(x, torch.int32)
    tmp1 = ops.constant(2, torch.int32)
    tmp2 = ops.mul(tmp0, tmp1)
    tmp3 = ops.indirect_indexing(tmp2, x_size)
    tmp4 = ops.load("buf0", tmp3)

The underlying handler would just see:

    ops.load("buf0", x * 2)

This is limited by the set of operators handled in the sympy expression
printers. So simple operations like minimum and maximum cannot be translated to
SymPy expressions yet, despite sympy.Min and sympy.Max existing.

é    N)ÚSequence)Ú	dataclass)ÚAnyÚLiteralÚOptionalÚoverloadÚUnion)Ú	TypeAlias)Údtype_to_typeÚis_integer_dtype)ÚFloorDivÚModularIndexingÚWhere)Úbound_sympyÚValueRangesé   )ÚDefaultHandler)Úevaluate_expr)Úgenerate_assert)ÚVÚvalc                 ó„   — t        | t        j                  «      r| j                  S t        | t        t
        t        f«      S ©N)Ú
isinstanceÚsympyÚBasicÚ	is_numberÚintÚfloatÚbool©r   s    ú_/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/_inductor/index_propagation.pyÚ_is_constantr#   .   s.   € Ü�#”u—{‘{Ô#Ø�}‰}ÐÜ�cœC¤¬Ð-Ó.Ð.ó    c                 ód   — t        | t        j                  «      rt        | «      j                  S | S r   )r   r   ÚExprr   Úupperr!   s    r"   Úupper_boundr(   4   s%   € Ü%/°´U·Z±ZÔ%@Œ;�sÓ×!Ñ!ÐIÀcÐIr$   c                   óF   — e Zd ZU dZeed<   ej                  ed<   d„ Zd„ Z	y)Ú	TypedExprz'A SymPy expression with associated typeÚexprÚdtypec                 ó,   — t        | j                  «      S r   )r#   r+   ©Úselfs    r"   Úis_constantzTypedExpr.is_constant?   s   € Ü˜DŸI™IÓ&Ð&r$   c                 ó„   — t        | j                  «      r+ t        | j                  «      | j                  «      | _        y y r   )r#   r+   r   r,   r.   s    r"   Ú__post_init__zTypedExpr.__post_init__B   s.   € Ü˜Ÿ	™	Ô"Ø1œ d§j¡jÓ1°$·)±)Ó<ˆD�Ið #r$   N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	_ExprTypeÚ__annotations__Útorchr,   r0   r2   © r$   r"   r*   r*   8   s   … á1à
ƒOØ�;‰;Óò'ó=r$   r*   c                   ó\  — e Zd ZdZededefd„«       Zedeee	e
f   dej                  defd„«       Zedeej                   ef   dej                  defd„«       Ze	 	 ddedej                  d	eej                     d
e
def
d„«       Zededefd„«       Zededefd„«       Zedededefd„«       Zedededefd„«       Zedededefd„«       Zededefd„«       Zedededefd„«       Zedededee   fd„«       Zedededee   fd„«       Zedededefd„«       Zedededefd„«       Zy)ÚSymPyOpsz½An ops handler where all IR values are SymPy expressions

    When a value cannot be represented as a SymPy expression, the method is
    either not defined, or returns NotImplemented

    ÚvalueÚreturnc                 ó   — | S r   r:   )r=   s    r"   ÚidentityzSymPyOps.identityO   s   € àˆr$   r,   c                 ó   — t        | |«      S r   ©r*   ©r=   r,   s     r"   ÚconstantzSymPyOps.constantS   ó   € ä˜ Ó&Ð&r$   c                 ó   — t        | |«      S r   rB   rC   s     r"   Ú
index_exprzSymPyOps.index_exprW   rE   r$   NÚ	src_dtypeÚuse_compute_typesc                 ó.   — t        | j                  |«      S r   )r*   r+   )r=   r,   rH   rI   s       r"   Úto_dtypezSymPyOps.to_dtype[   s   € ô ˜Ÿ™ UÓ+Ð+r$   Úxc                 óT   — t        t        | j                  «      | j                  «      S r   )r*   Úabsr+   r,   ©rL   s    r"   rN   zSymPyOps.absd   s   € äœ˜QŸV™V› a§g¡gÓ.Ð.r$   c                 ó\   — t        | j                  | j                  z  | j                  «      S r   ©r*   r+   r,   rO   s    r"   ÚsquarezSymPyOps.squareh   s   € ä˜Ÿ™ !§&¡&™¨!¯'©'Ó2Ð2r$   Úyc                 óœ   — t        j                  | j                  |j                  «      }t        | j                  |j                  z   |«      S r   ©r9   Úpromote_typesr,   r*   r+   ©rL   rS   Úresult_types      r"   ÚaddzSymPyOps.addl   ó5   € ä×)Ñ)¨!¯'©'°1·7±7Ó;ˆÜ˜Ÿ™ !§&¡&™¨+Ó6Ð6r$   c                 óœ   — t        j                  | j                  |j                  «      }t        | j                  |j                  z
  |«      S r   rU   rW   s      r"   ÚsubzSymPyOps.subq   rZ   r$   c                 óœ   — t        j                  | j                  |j                  «      }t        | j                  |j                  z  |«      S r   rU   rW   s      r"   ÚmulzSymPyOps.mulv   rZ   r$   c                 óD   — t        | j                   | j                  «      S r   rQ   rO   s    r"   ÚnegzSymPyOps.neg{   s   € ä˜!Ÿ&™&˜ !§'¡'Ó*Ð*r$   c                 óÌ   — t        j                  | j                  |j                  «      }t        |«      st        S t        t        | j                  |j                  «      |«      S r   )r9   rV   r,   r   ÚNotImplementedr*   r   r+   rW   s      r"   ÚfloordivzSymPyOps.floordiv   sF   € ä×)Ñ)¨!¯'©'°1·7±7Ó;ˆÜ Ô,Ü!Ð!äœ !§&¡&¨!¯&©&Ó1°;Ó?Ð?r$   c                 ó  — t        j                  | j                  |j                  «      }t        |«      st        S t        | j                  t        j                  j                  |j                  «      }t        ||«      S r   )r9   rV   r,   r   rb   r   r+   r   ÚSÚOner*   )rL   rS   rX   Úresult_exprs       r"   ÚmodzSymPyOps.mod‡   sU   € ä×)Ñ)¨!¯'©'°1·7±7Ó;ˆÜ Ô,Ü!Ð!ä% a§f¡f¬e¯g©g¯k©k¸1¿6¹6ÓBˆÜ˜ kÓ2Ð2r$   c                 óÔ  — t        j                  | j                  |j                  «      }t        |«      st        S t        j                  | j                  «      }t        j                  |j                  «      }|j                  �^|j                  |j                  k(  rEt        | j                  t
        j                  j                  |j                  «      }t        ||«      S t        S r   )r9   rV   r,   r   rb   r   Úsympifyr+   Úis_nonnegativeÚis_positiver   re   rf   r*   )rL   rS   rX   Úx_exprÚy_exprrg   s         r"   Ú	remainderzSymPyOps.remainder�   s¡   € ä×)Ñ)¨!¯'©'°1·7±7Ó;ˆÜ Ô,Ü!Ð!ä—‘˜qŸv™vÓ&ˆÜ—‘˜qŸv™vÓ&ˆð ×!Ñ!Ð-Ø×%Ñ%¨×);Ñ);Ò;ä)¨!¯&©&´%·'±'·+±+¸q¿v¹vÓFˆKÜ˜[¨+Ó6Ð6ÜÐr$   c                 ó¾   — t        j                  | j                  |j                  «      }t        t	        j
                  | j                  |j                  «      |«      S r   )r9   rV   r,   r*   r   ÚMinr+   rW   s      r"   ÚminimumzSymPyOps.minimum¢   ó<   € ä×)Ñ)¨!¯'©'°1·7±7Ó;ˆÜœŸ™ 1§6¡6¨1¯6©6Ó2°KÓ@Ð@r$   c                 ó¾   — t        j                  | j                  |j                  «      }t        t	        j
                  | j                  |j                  «      |«      S r   )r9   rV   r,   r*   r   ÚMaxr+   rW   s      r"   ÚmaximumzSymPyOps.maximum§   rs   r$   )NF)r3   r4   r5   r6   Ústaticmethodr   r@   r	   r   r   r    r9   r,   r*   rD   r   r&   rG   r   rK   rN   rR   rY   r\   r^   r`   rc   rh   ro   rr   rv   r:   r$   r"   r<   r<   G   sº  „ ñð ð˜ð  ò ó ðð ð'˜˜c 5¨$Ð.Ñ/ð '¸¿¹ð 'È	ò 'ó ð'ð ð'˜% §
¡
¨C Ñ0ð '¸¿¹ð 'Èò 'ó ð'ð ð ,0Ø"'ñ	,Øð,à�{‰{ð,ð ˜EŸK™KÑ(ð,ð  ð	,ð
 
ò,ó ð,ð ð/ˆyð /˜Yò /ó ð/ð ð3�)ð 3 	ò 3ó ð3ð ð7ˆyð 7˜Yð 7¨9ò 7ó ð7ð ð7ˆyð 7˜Yð 7¨9ò 7ó ð7ð ð7ˆyð 7˜Yð 7¨9ò 7ó ð7ð ð+ˆyð +˜Yò +ó ð+ð ð@�Ið @ )ð @°	ò @ó ð@ð ð3ˆyð 3˜Yð 3¨8°IÑ+>ò 3ó ð3ð ð�Yð  9ð °¸)Ñ1Dò ó ðð" ðA�9ð A ð A¨yò Aó ðAð ðA�9ð A ð A¨yò Aó ñAr$   r<   c                   óF   — e Zd ZU eed<   dZeed<   ededd fd„«       Z	d„ Z
y)	ÚIndexPropVarr=   FÚis_symbolicr+   r>   c                 ó   — t        | d¬«      S )NT©rz   )ry   )r+   s    r"   Únew_symboliczIndexPropVar.new_symbolic²   s   € ä˜D¨dÔ3Ð3r$   c                 ó`   — | j                   r"t        | j                  t        «      sJ d«       ‚y y )Nz.Symbolic IndexPropVar must contain a TypedExpr)rz   r   r=   r*   r.   s    r"   r2   zIndexPropVar.__post_init__¶   s.   € Ø×#Ò#¤z°$·*±*¼iÔ'Hð 	
Ø<ó	
ÐHÐ'HÐ#r$   N)r3   r4   r5   r   r8   rz   r    rw   r*   r}   r2   r:   r$   r"   ry   ry   ­   s6   … àƒJØ€K�Óàð4˜9ð 4¨ò 4ó ð4ó
r$   ry   )ÚIndexPropResult.r   c            	       ó  — e Zd ZdZdedeej                  ej                  f   deej                  ej                  f   ddfd„Z	dej                  d	e
j                  defd
„Zdeeef   defd„Zdefd„Zeded   dee   deeef   defd„«       Zededee   deeef   defd„«       Zdedee   deeef   defd„Zdedee   deeef   defd„Zdedeedf   deeef   defd„Zd„ Z	 	 ddeeef   dededefd„Zy)ÚIndexPropagationzñOps wrapper that tries to propagate constant and index_expr values through the computation.

    This aims to maximize the compile time simplification possible, and convert
    indirect indexing from arange into normal static indexing.

    ÚinnerÚiter_rangesÚindirect_var_rangesr>   Nc                 ór  — || _         t        j                  j                  j                  | _        |j                  «       D ��ci c]  \  }}|t        dt        |«      dz
  «      “Œ  }}}t        t        j                  | j                  j                  j                  «       |j                  «       «      «      | _        || _        g }|j                  «       D ]-  \  }}	|j                  d|k  «       |j                  ||	k  «       Œ/ t        |«      | j                  j                  «       z   | _        y c c}}w )Nr   r   )Ú_innerr   ÚgraphÚsizevarsÚ	shape_envÚitemsr   r(   ÚtupleÚ	itertoolsÚchainÚvar_to_ranger„   ÚappendÚ
get_axiomsÚaxioms)
r/   r‚   rƒ   r„   ÚkÚvrŽ   r‘   rL   Úss
             r"   Ú__init__zIndexPropagation.__init__Ç   s	  € ð ˆŒÜŸ™×)Ñ)×3Ñ3ˆŒð ?J×>OÑ>OÓ>Q÷
Ù6:°a¸ˆAŒ{˜1œk¨!›n¨qÑ0Ó1Ñ1ð
ˆñ 
ô "Ü�O‰O˜DŸN™N×7Ñ7×=Ñ=Ó?À×ASÑASÓAUÓVó
ˆÔð
 $7ˆÔ àˆØ×%Ñ%Ó'ò 	!‰DˆAˆqØ�M‰M˜!˜q™&Ô!Ø�M‰M˜!˜a™%Õ ð	!ô ˜F“m d§n¡n×&?Ñ&?Ó&AÑAˆ�ùó
s   Á#D3r+   r,   c                 óª   — t        |«      r- t        |«      |«      }| j                  j                  ||«      S | j                  j	                  ||«      S r   )r#   r   r†   rD   rG   )r/   r+   r,   r   s       r"   Úmaterialize_exprz!IndexPropagation.materialize_exprà   sI   € ä˜ÔØ&”- Ó& tÓ,ˆCØ—;‘;×'Ñ'¨¨UÓ3Ð3Ø�{‰{×%Ñ% d¨EÓ2Ð2r$   Úac                 ó   ‡ — t        |t        t        f«      rt        ˆ fd„|D «       «      S t        |t        «      s|S |j                  r:‰ j                  |j                  j                  |j                  j                  «      S |j                  S )Nc              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wr   )Úunwrap©Ú.0r“   r/   s     €r"   ú	<genexpr>z*IndexPropagation.unwrap.<locals>.<genexpr>é   s   øè ø€ Ò3¨A˜Ÿ™ QŸÑ3ùó   ƒ)	r   Úlistr‹   ry   rz   r—   r=   r+   r,   ©r/   r˜   s   ` r"   r›   zIndexPropagation.unwrapç   sf   ø€ Ü�aœ$¤˜Ô'ÜÓ3°Ô3Ó3Ð3ä˜!œ\Ô*ØˆHð �=Š=Ø×(Ñ(¨¯©¯©°q·w±w·}±}ÓEÐEà�w‰wˆr$   c                 ón   ‡ — t        |t        t        f«      rt        ˆ fd„|D «       «      S t        |«      S )Nc              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wr   )Úwraprœ   s     €r"   rž   z(IndexPropagation.wrap.<locals>.<genexpr>ö   s   øè ø€ Ò1¨!˜Ÿ™ 1ŸÑ1ùrŸ   )r   r    r‹   ry   r¡   s   ` r"   r¤   zIndexPropagation.wrapô   s,   ø€ Ü�aœ$¤˜Ô'ÜÓ1¨qÔ1Ó1Ð1Ü˜A‹Ðr$   ÚnameÚindirect_indexingÚargsÚkwargsc                  ó   — y r   r:   ©r/   r¥   r§   r¨   s       r"   ÚfallbackzIndexPropagation.fallbackù   s   € ð r$   c                  ó   — y r   r:   rª   s       r"   r«   zIndexPropagation.fallback  s   € ð r$   c                 ó  — |D �cg c]  }| j                  |«      ‘Œ }}|j                  «       D ��ci c]  \  }}|| j                  |«      “Œ }}}| j                   t        | j                  |«      |i |¤Ž«      S c c}w c c}}w r   )r›   rŠ   r¤   Úgetattrr†   )	r/   r¥   r§   r¨   r˜   Únew_argsr’   r“   Ú
new_kwargss	            r"   r«   zIndexPropagation.fallback  sx   € ð -1Ö1 q�D—K‘K •NÐ1ˆÐ1Ø4:·L±L³N×C©D¨A¨q�a˜Ÿ™ Q›Ñ'ÐCˆ
ÑCØ�y‰yÐ3œ §¡¨dÓ3°XÐLÀÑLÓMÐMùò 2ùÛCs
   …A<²Bc                 ó²  — dt         t        t        f   dt        fd„}|D �cg c]
  } ||«      ‘Œ }}|j                  «       D ��ci c]  \  }}| ||«      “Œ }	}} t	        t
        |«      |i |	¤Ž}
|
t        uxr( |
j                  «       xs |
j                  j                  }|s| j                  |||«      S t        j                  |
«      S c c}w c c}}w )Nr˜   r>   c                 ó>   — t        | t        «      s| S | j                  S r   )r   ry   r=   )r˜   s    r"   r›   z0IndexPropagation.propagate_sympy.<locals>.unwrap  s   € Ü˜a¤Ô.Ø�Ø—7‘7ˆNr$   )r	   r   ry   rŠ   r®   r<   rb   r0   r+   Ú
is_integerr«   r}   )r/   r¥   r§   r¨   r›   r˜   r¯   r’   r“   r°   Únew_exprÚis_valid_exprs               r"   Úpropagate_sympyz IndexPropagation.propagate_sympy  sÕ   € ð	”eœC¤Ð-Ñ.ð 	´3ó 	ð
 (,Ö, !‘F˜1•IÐ,ˆÐ,Ø/5¯|©|«~×>¡t q¨!�a™ ›‘lÐ>ˆ
Ñ>Ø*”7œ8 TÓ*¨HÐC¸
ÑCˆØ ¬Ð6ò 
ð × Ñ Ó"Ò> h§m¡m×&>Ñ&>ð 	ñ
 Ø—=‘=  t¨VÓ4Ð4Ü×(Ñ(¨Ó2Ð2ùò -ùÛ>s   ¢CÁC.c                 óD  — t        t        |«      s| j                  |||«      S t        j                  ||j                  «       «      D �cg c]  }t        |t        «      r|‘Œ }}t        d„ |D «       «      s| j                  |||«      S | j                  |||«      S c c}w )Nc              3   ó4   K  — | ]  }|j                   –— Œ y ­wr   r|   )r�   r“   s     r"   rž   z,IndexPropagation._default.<locals>.<genexpr>,  s   è ø€ Ò8 Q�1—=•=Ñ8ùs   ‚)
Úhasattrr<   r«   rŒ   r�   Úvaluesr   ry   Úallr¶   )r/   r¥   r§   r¨   r˜   Úvar_argumentss         r"   Ú_defaultzIndexPropagation._default#  s–   € Ü”x Ô&Ø—=‘=  t¨VÓ4Ð4ô —_‘_ T¨6¯=©=«?Ó;ö
àÜ˜!œ\Ô*ò ð
ˆð 
ô
 Ñ8¨-Ô8Ô8Ø—=‘=  t¨VÓ4Ð4à×#Ñ# D¨$°Ó7Ð7ùò
s   Á
Bc                 ó¦   — g | j                   ¢d„ | j                  j                  «       D «       ¢­}t        | j                  || j
                  |«      S )a°  
        Given some iter_ranges, return a function that given an expression, returns whether
        it is true or false using value ranges, guard knowledge and runtime_asserts.

        FIXME I think this may not be entirely right, as we may not be able to use all runtime_asserts
              If this is an issue, just use guards in `self.axioms`.

              The proper way of handling this would be to have a global shape_env that adds
              runtime_asserts as they happen in the code. Then, it shuld be used in SimplifyIndexing
              to perform wrap_expr and in CSEProxy.check_bounds to elide upper / lower bounds also
              for indirect_indexing
        c              3   óV   K  — | ]!  \  }}|t        d t        |«      dz
  «      f–— Œ# y­w)r   r   N)r   r(   )r�   r’   r“   s      r"   rž   z3IndexPropagation.statically_true.<locals>.<genexpr>@  s1   è ø€ ò á�A�qð ”K ¤;¨q£>°AÑ#5Ó6Ô7ñùs   ‚'))rŽ   r„   rŠ   r   r‰   r‘   )r/   ÚerŽ   s      r"   Ústatically_truez IndexPropagation.statically_true1  sS   € ð
Ø×Ñð
ñà ×4Ñ4×:Ñ:Ó<ôñ
ˆô ˜TŸ^™^¨Q°·±¸\ÓJÐJr$   ÚindexÚsizeÚcheckc                 óÒ  ‡ ‡— t        |t        «      r³|j                  r§t        j                  |j
                  j                  «      }ˆ ˆfd„}‰ j                  d|k  «      xs ‰ j                  ‰ |k  «      }‰ j                  |‰k  «      }|r ||«      }t        |«      r"‰ j                  d|‰ft        | | ¬«      «       |S ‰ j                  d|‰||fi «      j
                  }	|	S )Nc                 óˆ   •— ‰j                  d| k  «      r| S ‰j                  | dk  «      r| ‰z   S t        | dk  | ‰z   | «      S )Nr   )rÁ   r   )r+   r/   rÃ   s    €€r"   Ú	wrap_exprz5IndexPropagation.indirect_indexing.<locals>.wrap_exprW  sM   ø€ à×'Ñ'¨¨T©	Ô2Ø�KØ×)Ñ)¨$°©(Ô3Ø $™;Ð&ä  ¨¡¨4°$©;¸Ó=Ð=r$   r   Úcheck_bounds)Úlowerr'   r¦   )r   ry   rz   r   rj   r=   r+   rÁ   r   r«   Údict)
r/   rÂ   rÃ   rÄ   Úwrap_negr+   rÇ   Úcan_prove_lowerÚcan_prove_upperÚindirect_vars
   ` `       r"   r¦   z"IndexPropagation.indirect_indexingG  sí   ù€ ô �eœ\Ô*¨u×/@Ò/@ô —=‘= §¡×!1Ñ!1Ó2ˆDõ>ð #×2Ñ2°1¸±9Ó=ò À×AUÑAUØ�˜‘óBˆOð #×2Ñ2°4¸$±;Ó?ˆOÙÙ  “�Ü˜uÔ%Ø—‘Ø"Ø˜4�LÜ ?Ð2¸oÐ:MÔNôð
 ˆKà—}‘}Ø %¨¨u°hÐ!?Àó
ç
‰%ð 	ð Ðr$   )TT)r3   r4   r5   r6   r   rÊ   r   ÚSymbolr&   r•   r9   r,   r—   r	   ry   r›   r   r¤   r   r   r   Ústrr«   r¶   r‹   r½   rÁ   r    r¦   r:   r$   r"   r�   r�   ¿   s  „ ñðBàðBð ˜%Ÿ,™,¨¯
©
Ð2Ñ3ðBð " %§,¡,°·
±
Ð":Ñ;ð	Bð
 
óBð23 U§Z¡Zð 3¸¿¹ð 3Èó 3ð˜˜c <Ð/Ñ0ð °Só ð˜ó ð
 ðàÐ)Ñ*ðð �s‰mðð �S˜#�X‘ð	ð
 
òó ðð ðØðØ'¨™}ðØ6:¸3À¸8±nðà	òó ððNØðNØ'¨™}ðNØ6:¸3À¸8±nðNà	óNð3Øð3Ø'¨™}ð3Ø6:¸3À¸8±nð3à	ó3ð*8˜Sð 8¨¨c°3¨h©ð 8ÀÀcÈ3ÀhÁð 8ÐTWó 8òKð4 Øñ+à�S˜,Ð&Ñ'ð+ð ð+ð ð	+ð 
ô+r$   r�   )0r6   rŒ   Úcollections.abcr   Údataclassesr   Útypingr   r   r   r   r	   Útyping_extensionsr
   r   r9   Útorch._prims_commonr   r   Útorch.utils._sympy.functionsr   r   r   Útorch.utils._sympy.value_rangesr   r   Úops_handlerr   rˆ   r   Úutilsr   Úvirtualizedr   r&   r   r   r    r7   r#   r(   r*   r<   ry   r‹   r   r8   r�   r:   r$   r"   ú<module>rÛ      sÚ   ðòó, Ý $Ý !ß :Õ :Ý 'ã ã ß ?ß IÑ Iß Då 'Ý #Ý "Ý ð �%—*‘*˜e S¨$Ð.Ñ/€	ð/�ió /ðJ�Yó Jð ÷=ð =ó ð=÷cAñ cAðL ÷
ð 
ó ð
ð # <°Ð7MÑ1NÐ#NÑO€�Ó Oôs�~õ sr$   