ó
    ‡Ž¡jB  ã            	       ó:  • S SK r S SKrS SKrS SKrS SKJrJr  S SKJr  SSK	J
r
  SSKJr  SSKJrJrJr  \" 5       (       a  S SKrS SKJr  \" 5       (       a  S SKr\R*                  " \5      rS	 r\R2                  " S
5      rS\S\4S jrS r S S\S-  S\S\S-  4S jjrS S\S-  S\S\S-  4S jjr S\RB                  4S jr"S r#\R2                  " S5      r$S r%S r&S\S-  4S jr'   S!S\S\S\4S jjr(\" SS9\   S"S\S-  S\S\4S jj5       5       r)g)#é    N)ÚcontextmanagerÚredirect_stdout)ÚStringIOé   ©Ú_get_torch_distributed_rank)Úlogging)Úis_torch_availableÚis_torch_distributed_availableÚrequires)Ú	save_filec                  ó   • [        5       S:H  $ )z7Return True if rank=0 or we aren't running distributed.r   r   © ó    Ú°C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\transformers/model_debugging_utils.pyÚ_is_rank_zeror   (   s   € ä&Ó(¨AÑ-Ð-r   zobject at 0x[0-9A-Fa-f]+Úx_strÚreturnc                 ó.   • [         R                  SU 5      $ )z�
Replace memory addresses in an object's repr with a stable placeholder
so that beautiful JSON diffs won't be ruined by ephemeral addresses.
zobject at 0xXXXXXXXX)ÚMEMORY_ADDRESS_REGEXÚsub)r   s    r   Ú_sanitize_repr_for_diffr   0   s   € ô
  ×#Ñ#Ð$:¸EÓBÐBr   c                 óR   • [        5       (       a  S[        U R                  5       3$ g)z@Return a stable string representation for a DTensor-like object.zDTensor (rank0) -> zDTensor(non-rank0))r   ÚreprÚ_local_tensor)Úxs    r   Ú_dtensor_reprr   8   s#   € ä‡�Ø$¤T¨!¯/©/Ó%:Ð$;Ð<Ð<Ør   Ú
debug_pathÚuse_reprÚpath_to_valuec                 óŠ  • [         R                  " SS9  U(       a  [        U 5      nOœU(       a�  UR                  S5      (       d  US-  nU(       a  [        R
                  R                  X5      OUn[        SU R                  5       R                  5       R                  5       0U5        SU 3nO[        SU< SU< S35      e[        U R                  5      [        U R                  5      US	.nU R                  [         R                  [         R                   [         R"                  1;   a–  UR%                  ['        [        U R)                  5       5      5      ['        [        U R+                  5       5      5      ['        [        U R-                  5       5      5      ['        [        U R/                  5       5      5      S
.5        U$ )aa  
Converts Tensors and DTensors to a JSON-serializable dictionary representation.

Args:
    value: Any Python object, often including torch Tensors, lists, dicts, etc.
    debug_path (`str`, *optional*, defaults to `None`): Directory to dump debug JSON and SafeTensors files.
    use_repr (bool, *optional*, defaults to `True`): Whether to save a `repr()`-ized version of the tensor as the
        `value` property in the associated FULL_TENSORS.json file, or to store the full tensors in separate
        SafeTensors file and store the relative path to that file in the `value` property in the dictionary.
    path_to_value (`str`, *optional*, defaults to `None`): The file name for the SafeTensors file holding the full
        tensor value if `use_repr=False`.

Returns:
    A nested Python structure (list, dict, or sanitized string) that is safe to json.dump.
T)Úsci_modez.safetensorsÚdataz./z	use_repr=z and path_to_value=z cannot both be falsy.)ÚshapeÚdtypeÚvalue)ÚmeanÚstdÚminÚmax)ÚtorchÚset_printoptionsÚ_repr_to_listÚendswithÚosÚpathÚjoinr   Ú
contiguousÚdetachÚcpuÚ
ValueErrorr   r$   r%   Úfloat16Úfloat32Úbfloat16Úupdater   r'   r(   r)   r*   )r&   r   r   r    Ú	value_outÚfilepathÚouts          r   Ú_serialize_tensor_like_ior=   ?   sO  € ô$ 
×Ò DÒ)æÜ! %Ó(‰	Þ	Ø×%Ñ% n×5Ñ5Ø˜^Ñ+ˆMæ>H”2—7‘7—<‘< 
Ô:ÈmˆÜ�6˜5×+Ñ+Ó-×4Ñ4Ó6×:Ñ:Ó<Ð=¸xÔHØ˜˜Ð(‰	ä˜I˜H™;Ð&:¨MÑ+;Ð;QÐRÓSÐSô �e—k‘kÓ"Ü�e—k‘kÓ"Øñ€Cð
 ‡{�{”u—}‘}¤e§m¡m´U·^±^ÐDÓDØ�
‰
ä/´°U·Z±Z³\Ó0BÓCÜ.¬t°E·I±I³KÓ/@ÓAÜ.¬t°E·I±I³KÓ/@ÓAÜ.¬t°E·I±I³KÓ/@ÓAñ	ô	
ð €Jr   c                 ó   • [        U [        [        45      (       a-  [        U 5       VVs/ s H  u  pE[	        XQX# SU 3S9PM     snn$ [        U [
        5      (       a3  U R                  5        VVs0 s H  u  peU[	        XQX# SU 3S9_M     snn$ [        U S5      (       a  [        U R                  XUS9$ [        U [        R                  5      (       a
  [        XX#S9$ [        [        U 5      5      $ s  snnf s  snnf )aR  
Recursively build a JSON-serializable Python structure from `value`.
Tensors and DTensors become either sanitized repr strings, or are saved to disk as SafeTensors files and their
relative paths are recorded in the returned Python structure.
Lists/tuples/dicts are recursed into.
All memory addresses are replaced with a stable placeholder.

Args:
    value: Any Python object, often including torch Tensors, lists, dicts, etc.
    debug_path (`str`, *optional*, defaults to `None`): Directory to dump debug JSON and SafeTensors files.
    use_repr (bool, *optional*, defaults to `True`): Whether to save a `repr()`-ized version of the tensors as the
        `value` property in the associated FULL_TENSORS.json file, or to store full tensors in separate SafeTensors
        files and store the relative path to that file in the `value` property.
    path_to_value (`str`, *optional*, defaults to `None`): The file name for the SafeTensors file holding the full
        tensor value if `use_repr=False`.

Returns:
    A nested Python structure (list, dict, or sanitized string) that is safe to json.dump.
Ú_©r   r   r    r   )Ú
isinstanceÚlistÚtupleÚ	enumerateÚ_serialize_ioÚdictÚitemsÚhasattrr=   r   r+   ÚTensorr   r   )r&   r   r   r    ÚiÚvÚks          r   rE   rE   p   s  € ô( �%œ$¤˜×'Ñ'ô " %Ô(ô
â(‘�ô ˜!¸XÐWfÐfgÐhiÐgjÐUkÔlÙ(ò
ð 	
ô
 �%œ×Ñð Ÿ™œô
â%‘�ð Œ}˜QÀÐZiÐijÐklÐjmÐXnÑoÒoÙ%ò
ð 	
ô
 ˆu�o×&Ñ&Ü(Ø×Ñ¨JÐYfñ
ð 	
ô �%œŸ™×&Ñ&Ü(¨ÐPXÑvÐvä"¤4¨£;Ó/Ð/ùó'
ùó
s   ªC4Á1C:r&   c                 ó&  • [         R                  " SSS9  [        5        n[        U5         [	        U 5        UR                  5       nSSS5        SSS5        [        W5      R                  5       $ ! , (       d  f       N/= f! , (       d  f       N8= f)zË
Converts a tensor into a sanitized multi-line string representation.

Args:
    value (`torch.Tensor`): The tensor to represent.

Returns:
    `list[str]`: List of string lines representing the tensor.
Téx   )r"   Ú	linewidthN)r+   r,   r   r   ÚprintÚgetvaluer   Ú
splitlines)r&   ÚbufÚraws      r   r-   r-   ›   s_   € ô 
×Ò D°CÒ8Ü	Œ�sœO¨CÕ0ÜˆeŒØ�l‰l‹nˆ÷ 1�ô # 3Ó'×2Ñ2Ó4Ð4÷ 1Õ0ú��ús"    B¬A1ÁBÁ1
A?	Á;BÂ
Bc                 ó„   • U R                  S5      (       a*  U R                  SS 5        U S    H  n[        U5        M     g g )NÚchildrenÚoutputs)ÚgetÚpopÚprune_outputs_if_children)ÚnodeÚchilds     r   rZ   rZ   ¬   s=   € ð ‡x�x�
×ÑØ�‰�˜DÔ!Ø˜*Ô%ˆEÜ% eÖ,ò &ð r   z(.*)\.(\d+)$c                 óÜ   ^• [         R                  U R                  SS5      5      nU(       a  U R                  S5      (       d  gUR                  S5      m[	        U4S jU S    5       5      $ )z¯
Checks whether a node represents a layer block with submodules.

Args:
    node (`dict`): A node from the call tree.

Returns:
    `bool`: Whether the node is a layer block.
Úmodule_pathÚ rV   Fé   c              3   óV   >#   • U  H  nS T S 3UR                  SS5      ;   v •  M      g7f)Ú.r^   r_   N©rX   )Ú.0r\   Únumbers     €r   Ú	<genexpr>Ú!is_layer_block.<locals>.<genexpr>Æ   s+   øé € Ð[ÒJZÀ��6�(˜!ˆ} §	¡	¨-¸Ó <Ö<ÒJZùs   ƒ&))ÚLAYER_SUFFIX_REÚmatchrX   ÚgroupÚany)r[   ri   re   s     @r   Úis_layer_blockrl   ¸   sW   ø€ ô ×!Ñ! $§(¡(¨=¸"Ó"=Ó>€EÞ˜Ÿ™ ×,Ñ,ØØ�[‰[˜‹^€FÜÔ[È$ÈzÒJZÓ[Ó[Ð[r   c                 ó˜  • U R                  S5      (       d  g[        U S   5       VVs/ s H  u  p[        U5      (       d  M  X4PM     nnn[        U5      S:”  aF  USS  VVs/ s H  u  pUPM	     nnn[        U S   5       VVs/ s H  u  pX;  d  M  UPM     snnU S'   U S    H  n[	        U5        M     gs  snnf s  snnf s  snnf )zä
Recursively removes intermediate layers from the tree to improve readability.
Keeps at least the first and last layers if many consecutive layers are present.

Args:
    node (`dict`): The root or subnode to prune recursively.
rV   Nr`   r   éÿÿÿÿ)rX   rD   rl   ÚlenÚprune_intermediate_layers)r[   rJ   r\   Úlayer_blocksr?   Ú	to_removes         r   rp   rp   É   sÂ   € ð �8‰8�J×ÑØÜ/8¸¸jÑ9IÔ/JÔdÒ/J¡8 1ÌnÐ]b×Nc“J�Q“JÑ/J€LÑdä
ˆ<Ó˜1ÓØ#/°°"Ñ#5Ô6Ò#5™4˜1“QÑ#5ˆ	Ñ6Ü2;¸DÀÑ<LÔ2MÔdÒ2M¡h aÐQRÑQcŸEÑ2MÒdˆˆZÑà�jÔ!ˆÜ! %Ö(ò "ùó eùó 7ùÛds   ©B:ÁB:Á$C ÂCÂCc                 óò  ^• U (       aC   [         R                  " U SS9  [         R                  R                  XR                  S-   5      nOUR                  S-   n[        R                  SU S35        US-   nUS	-   n[        UR                  5        [        US
5       n[        R                  " UR                  USS9  S S S 5        U4S jm[        R                  " [        R                  " UR                  5      5      nT" U5        [        US
5       n[        R                  " XvSS9  S S S 5        g ! [
         a  n[        SU  S35      UeS nAff = f! , (       d  f       N�= f! , (       d  f       g = f)NT©Úexist_okÚ_debug_treeú"Unexpected or existing debug_path=rb   zWriting model trace at z.jsonz_FULL_TENSORS.jsonz_SUMMARY.jsonÚwr`   )Úindentc                 ó¶   >^• U4S jmT" U R                  S0 5      5        T" U R                  S0 5      5        U R                  S/ 5       H  nT" U5        M     g )Nc                 óâ   >• [        U [        5      (       a2  U R                  SS 5        U R                  5        H  nT" U5        M     g [        U [        5      (       a  U  H  nT" U5        M     g g )Nr&   )rA   rF   rY   ÚvaluesrB   )ÚvalrK   ÚitemÚcleans      €r   r   Ú:log_model_debug_trace.<locals>.strip_values.<locals>.cleanò   sX   ø€ Ü˜#œt×$Ñ$Ø—‘˜ Ô&ØŸ™ž�AÙ˜!–Hò &ä˜C¤×&Ñ&Û�DÙ˜$–Kò  ð 'r   ÚinputsrW   rV   rc   )r[   r\   r   Ústrip_valuess     @€r   r‚   Ú+log_model_debug_trace.<locals>.strip_valuesñ   sM   ù€ õ	 ñ 	ˆd�h‰h�x Ó$Ô%Ùˆd�h‰h�y "Ó%Ô&à—X‘X˜j¨"Ö-ˆEÙ˜Öò .r   )r/   Úmakedirsr0   r1   Ú_debugger_module_dump_nameÚ	Exceptionr5   ÚloggerÚinforZ   Ú
_call_treeÚopenÚjsonÚdumpÚloadsÚdumps)	r   ÚmodelÚbaseÚeÚ	full_pathÚsummary_pathÚfÚ	tree_copyr‚   s	           @r   Úlog_model_debug_tracer–   Ý   s6  ø€ Þð	XÜ�KŠK˜
¨TÒ2Ü—7‘7—<‘< 
×,LÑ,LÈ}Ñ,\Ó]‰Dð ×/Ñ/°-Ñ?ˆä
‡K�KÐ)¨$¨¨uÐ5Ô6ØÐ+Ñ+€IØ˜/Ñ)€Lä˜e×.Ñ.Ô/ä	ˆi˜Ô	 Ü�	Š	�%×"Ñ" A¨aÒ0÷ 
õ ô  —
’
œ4Ÿ:š: e×&6Ñ&6Ó7Ó8€IÙ�Ôä	ˆl˜CÔ	  AÜ�	Š	�) qÒ)÷ 
!Ð	 øôE ó 	XÜÐAÀ*ÀÈQÐOÓPÐVWÐWûð	Xú÷ 
Õ	ú÷. 
!Õ	 ús0   ŠAD5 Â!EÄE(Ä5
EÄ?EÅEÅ
E%Å(
E6Údo_prune_layersc                 óÊ  ^ ^^^^	^
• T R                   R                  m	T	SS/ S.T l        / T l        T	T l        T(       a   [
        R                  " TSS9  UU U4S jnT R                  5        H  u  pgUS:X  a  M  U" UT	 SU 35        M     T R                  m
[        R                  " T
5      U	UUU U
U4S	 j5       nUT l
        g! [         a  n[        ST S35      UeSnAff = f)
a´  
Attaches a debugging wrapper to every module in the model.

This records structured inputs and outputs during the forward pass into a call tree.

Args:
    model (`PreTrainedModel`, `nn.Module`): Model to wrap.
    debug_path (`str`): Optional directory to dump debug JSON files.
    do_prune_layers (`bool`, *optional*, defaults to `True`): Whether to prune intermediate layers.
    use_repr (bool, *optional*, defaults to `True`): Whether to save a `repr()`-ized version of the tensors as the
        `value` property in the associated FULL_TENSORS.json file, or to store full tensors in separate SafeTensors
        files and store the relative path to that file in the `value` property.
N©r^   r�   rW   rV   Trt   rw   rb   c                 óz   >^ ^^• T R                   m[        R                  " T5      UUUU UU4S j5       nUT l         g )Nc                  ó¸  >• [        5       (       a[  XS.nU Vs0 s H  n[        X#   5      S:”  d  M  X2U   _M     nnT[        UTTT S3S9S / S.nT	R                  R	                  U5        [
        R                  " 5          T" U 0 UD6nS S S 5        [        5       (       a£  [        S T
R                  5        5       5      S:”  a  S WS'   O[        WTTT S3S9WS'   T	R                  R                  5       nUS	   (       d  UR                  S	5        T	R                  (       a!  T	R                  S
   S	   R	                  U5        W$ s  snf ! , (       d  f       NÇ= f)N©ÚargsÚkwargsr   Ú_inputsr@   r™   c              3   ó&   #   • U  H  nS v •  M	     g7f)r   Nr   )rd   r?   s     r   rf   ÚX_attach_debugger_logic.<locals>.wrap_forward.<locals>.wrapped_forward.<locals>.<genexpr>@  s   é € Ð:Ò"9˜Q•qÒ"9ùs   ‚rW   Ú_outputsrV   rn   )
r   ro   rE   Ú_debugger_model_call_stackÚappendr+   Úno_gradÚsumÚnamed_childrenrY   )ÚinpsÚkwsÚdict_inputsrL   r[   r<   Úfinishedr   r’   r�   ÚmoduleÚorig_forwardr   s          €€€€€€r   Úwrapped_forwardÚE_attach_debugger_logic.<locals>.wrap_forward.<locals>.wrapped_forward+  sS  ø€ ä�‰Ø'+Ñ;�Ù:EÓaº+°QÌÈ[É^ÓI\Ð_`ÑI`Ó0˜q¨a¡.Ò0¹+�Ðaà#,Ü+Ø#Ø#-Ø!)Ø)2¨°7Ð&;ñ	ð  $Ø "ñ
�ð ×0Ñ0×7Ñ7¸Ô=Ü—’•Ù" DÐ0¨CÑ0�÷ !ô �‰ÜÑ: &×"7Ñ"7Ô"9Ó:Ó:¸QÓ>Ø&*�D˜’Oä&3ØØ#-Ø!)Ø)2¨°8Ð&<ñ	'�D˜‘Oð !×;Ñ;×?Ñ?ÓA�à 
×+Ø—L‘L Ô,à×3×3Ø×4Ñ4°RÑ8¸ÑD×KÑKÈHÔUØˆJùòE b÷ !•ús   ™E²	EÂ	EÅ
E)ÚforwardÚ	functoolsÚwraps)r¬   r’   r®   r­   r   r�   r   s   `` @€€€r   Úwrap_forwardÚ,_attach_debugger_logic.<locals>.wrap_forward(  s6   û€ Ø—~‘~ˆä	�Š˜Ó	&÷%	ñ %	ó 
'ð%	ðN )ˆ�r   r_   c                  ó¾  >• [        5       (       a4  T S3[        XS.TTT S3S9S / S.nT	R                  R                  U5        T
" U 0 UD6n[        5       (       aü  T	R                  (       aë  [        UTTT S3S9WS'   T	R                  R	                  5       nUS   T	R
                  S'   US   T	R
                  S'   US	   T	R
                  S	'   [        T	R
                  R                  5       5       Vs/ s H5  nT	R
                  U   (       a  M  T	R
                  R	                  US 5      PM7       nT(       a  [        T	R
                  5        [        TT	S
9  U$ s  snf )Nz (top-level)rœ   rŸ   r@   r™   r¢   rW   r�   rV   )r   r�   )
r   rE   r£   r¤   rY   r‰   rB   Úkeysrp   r–   )r¨   r©   Útop_noder<   r«   rL   Ú
class_namer   r—   r�   Úreal_top_forwardr   s         €€€€€€r   Útop_wrapped_forwardÚ3_attach_debugger_logic.<locals>.top_wrapped_forward^  sa  ø€ ä�?‰?à", ¨\Ð:Ü'Ø!Ñ1Ø)Ø%Ø%/ L°Ð"8ñ	ð  Øñ
ˆHð ×,Ñ,×3Ñ3°HÔ=á Ð,¨Ñ,ˆÜ�?‰?˜u×?×?Ü"/ØØ%Ø!Ø!+ ¨HÐ5ñ	#ˆH�YÑð ×7Ñ7×;Ñ;Ó=ˆHØ)1°(Ñ);ˆE×Ñ˜XÑ&Ø*2°9Ñ*=ˆE×Ñ˜YÑ'Ø+3°JÑ+?ˆE×Ñ˜ZÑ(ä48¸×9IÑ9I×9NÑ9NÓ9PÔ4QÓmÒ4Q¨qÐY^×YiÑYiÐjkÕYlÓ*ˆU×Ñ×!Ñ! ! TÖ*Ñ4QÑmö Ü)¨%×*:Ñ*:Ô;ä!¨Z¸uÒEØˆ
ùò ns   Ã4EÄ E)Ú	__class__Ú__name__r‰   r£   r…   r/   r„   r†   r5   Únamed_modulesr°   r±   r²   )r�   r   r—   r   r‘   r³   ÚnameÚ	submodulerº   r¸   r¹   s   ````     @@r   Ú_attach_debugger_logicrÁ     sï   ý€ ð& —‘×)Ñ)€Jð (2¸TÈdÐ`bÑc€EÔØ')€EÔ$Ø'1€EÔ$æð	XÜ�KŠK˜
¨TÒ2÷+)ð\ !×.Ñ.Ö0‰ˆØ�2‹:ÙÙ�Y : ,¨a°¨vÐ 6Ö7ñ 1ð —}‘}Ðä‡_‚_Ð%Ó&÷#ñ #ó 'ð#ðJ (€E…Møô ó 	XÜÐAÀ*ÀÈQÐOÓPÐVWÐWûð	Xús   ¿C Ã
C"ÃCÃC")r+   )Úbackendsc              #   ó8  #   • U R                  5        VVs0 s H  u  pEXUR                  _M     nnnU R                  X`'   [        XX#5         U v •  UR                  5        H  u  pxX‡l        M     gs  snnf ! UR                  5        H  u  pxX‡l        M     f = f7f)a©  
# Model addition debugger - context manager for model adders
This context manager is a power user tool intended for model adders.

It tracks all forward calls within a model forward and logs a slice of each input and output on a nested JSON file.
If `use_repr=True` (the default), the JSON file will record a `repr()`-ized version of the tensors as a list of
strings. If `use_repr=False`, the full tensors will be stored in separate SafeTensors files and the JSON file will
provide a relative path to that file.

To note, this context manager enforces `torch.no_grad()`.

## Usage

add the context manager to a model to debug

```python
import torch

from PIL import Image
from transformers import LlavaProcessor, LlavaForConditionalGeneration, model_addition_debugger_context

torch.random.manual_seed(673)

# load pretrained model and processor
model_id = "llava-hf/llava-1.5-7b-hf"
processor = LlavaProcessor.from_pretrained(model_id)
model = LlavaForConditionalGeneration.from_pretrained(model_id)

# create random image input
random_image = Image.fromarray(torch.randint(0, 256, (224, 224, 3), dtype=torch.uint8).numpy())

# prompt
prompt = "<image>Describe this image."

# process inputs
inputs = processor(text=prompt, images=random_image, return_tensors="pt")

# call forward method (not .generate!)
with model_addition_debugger_context(model, debug_path="Your_debug_path", do_prune_layers=False):
    output = model.forward(**inputs)
```

N)r¾   r°   rÁ   rG   )	r�   r   r—   r   r?   ÚmÚorig_forwardsÚmodule_instanceÚforward_methods	            r   Úmodel_addition_debugger_contextrÈ   ‡  s’   é € ðf /4×.AÑ.AÔ.CÔDÒ.C¡d a�QŸ	™	’\Ñ.C€MÑDØ Ÿ=™=€MÑÜ˜5¨oÔHð5ØŠà/<×/BÑ/BÖ/DÑ+ˆOØ&4Ö#ò 0Eùó Eøð 0=×/BÑ/BÖ/DÑ+ˆOØ&4Ö#ò 0Eüs'   ‚B–A0®BÁA6 Á&BÁ6!BÂB)NTN)rb   TT)NTT)*r±   r‹   r/   ÚreÚ
contextlibr   r   Úior   Údistributed.utilsr   Úutilsr	   Úutils.import_utilsr
   r   r   r+   Úsafetensors.torchr   Útorch.distributed.tensorÚ
get_loggerr½   r‡   r   Úcompiler   Ústrr   r   Úboolr=   rE   rI   r-   rZ   rh   rl   rp   r–   rÁ   rÈ   r   r   r   Ú<module>rÕ      s›  ðó  Û Û 	Û 	ß 6Ý å :Ý ß \Ñ \ñ ×ÑÛÝ+ñ &×'Ñ'Û'ð 
×	Ò	˜HÓ	%€ò.ð
 —z’zÐ"=Ó>Ð ðC 3ð C¨3ô Cò ð ^bñ.Ø˜T‘zð.Ø48ð.ØPSÐVZÑPZõ.ñb(0 S¨4¡Zð (0À$ð (0Ð^aÐdhÑ^hõ (0ðV5˜Ÿ™ô 5ò"-ð —*’*˜_Ó-€ò\ò")ð((* c¨D¡jô (*ðZ Ø Øñ	|(àð|(ð ð|(ð õ	|(ñ~ 
�:ÑØð "Ø Øñ	85à�d‘
ð85ð ð85ð ô	85ó ó ñ85r   