Ë
    Gêñi”B  ã            	       ó:  — d dl Z d dlZd dlZd dlZd dlmZmZ d dlmZ ddl	m
Z
 ddlmZmZ  e«       r-d dlZd dlmZ dZej$                  j'                  «       r	d dlZd	ZndZ e
j*                  e«      Zd
„ Z ej2                  d«      Zdedefd„Zd„ Z	 d!dedz  dededz  fd„Zd!dedz  dededz  fd„Z dejB                  fd„Z"d„ Z# ej2                  d«      Z$d„ Z%d„ Z&dedz  fd„Z'	 	 	 d"dededefd„Z( ed¬«      e	 	 	 d#dedz  dedefd „«       «       Z)y)$é    N)ÚcontextmanagerÚredirect_stdout)ÚStringIOé   )Úlogging)Úis_torch_availableÚrequires)Ú	save_fileFTc                  óŽ   — t         rt        j                  j                  «       syt        j                  j	                  «       dk(  S )z7Return True if rank=0 or we aren't running distributed.Tr   )Ú_torch_distributed_availableÚtorchÚdistributedÚis_initializedÚget_rank© ó    úd/var/www/pod-logistic/pod-ai/venv/lib/python3.12/site-packages/transformers/model_debugging_utils.pyÚ_is_rank_zeror   ,   s3   € å(¬U×->Ñ->×-MÑ-MÔ-OØÜ×Ñ×%Ñ%Ó'¨1Ñ,Ð,r   zobject at 0x[0-9A-Fa-f]+Úx_strÚreturnc                 ó.   — t         j                  d| «      S )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   6   s   € ô
  ×#Ñ#Ð$:¸EÓBÐBr   c                 óH   — t        «       rdt        | j                  «      › �S y)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   >   s!   € ä„Ø$¤T¨!¯/©/Ó%:Ð$;Ð<Ð<Ør   Ú
debug_pathÚuse_reprÚpath_to_valuec                 ó`  — t        j                  d¬«       |rt        | «      }nŒ|rx|j                  d«      s|dz  }|r t        j
                  j                  ||«      n|}t        d| j                  «       j                  «       j                  «       i|«       d|› �}nt        d|›d|›d�«      ‚t        | j                  «      t        | j                  «      |d	œ}| j                  t         j                  t         j                   t         j"                  hv r–|j%                  t'        t        | j)                  «       «      «      t'        t        | j+                  «       «      «      t'        t        | j-                  «       «      «      t'        t        | j/                  «       «      «      d
œ«       |S )a‘  
    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 asscoiated 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)r   Ú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>   E   sN  € ô$ 
×Ñ DÕ)áÜ! %Ó(‰	Ù	Ø×%Ñ% nÔ5Ø˜^Ñ+ˆMá>H”2—7‘7—<‘< 
¨MÔ:È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                 óö  — t        | t        t        f«      r0t        | «      D ��cg c]  \  }}t	        ||||› d|› �¬«      ‘Œ c}}S t        | t
        «      r6| j                  «       D ��ci c]  \  }}|t	        ||||› d|› �¬«      “Œ c}}S t        | d«      rt        | j                  |||¬«      S t        | t        j                  «      rt        | |||¬«      S t        t        | «      «      S c c}}w c c}}w )a’  
    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 asscoiated 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   rF   rF   v   s  € ô( �%œ$¤˜Ô'ô " %Ó(÷
á��1ô ˜!¨
¸XÐXeÐWfÐfgÐhiÐgjÐUkÖló
ð 	
ô
 �%œÔð Ÿ™›÷
á��1ð Œ}˜Q¨:ÀÐ[hÐZiÐijÐklÐjmÐXnÔoÑoó
ð 	
ô
 ˆu�oÔ&Ü(Ø×Ñ¨JÀÐYfô
ð 	
ô �%œŸ™Ô&Ü(¨¸:ÐPXÐhuÔvÐvä"¤4¨£;Ó/Ð/ùó'
ùó
s   ¥C/Á*C5r(   c                 ó  — t        j                  dd¬«       t        «       5 }t        |«      5  t	        | «       |j                  «       }ddd«       ddd«       t        «      j                  «       S # 1 sw Y   Œ*xY w# 1 sw Y   Œ.xY w)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.   ¡   st   € ô 
×Ñ D°CÕ8Ü	‹ð �sœO¨CÓ0ñ ÜˆeŒØ�l‰l‹nˆ÷÷ ô # 3Ó'×2Ñ2Ó4Ð4÷ð ú÷ ð ús"   ¢A?®A3Á
A?Á3A<	Á8A?Á?Bc                 óv   — | j                  d«      r(| j                  dd «       | d   D ]  }t        |«       Œ y y )NÚchildrenÚoutputs)ÚgetÚpopÚprune_outputs_if_children)ÚnodeÚchilds     r   r[   r[   ²   s?   € ð ‡x�x�
ÔØ�‰�˜DÔ!Ø˜*Ñ%ò 	-ˆEÜ% eÕ,ñ	-ð r   z(.*)\.(\d+)$c                 óÆ   ‡— t         j                  | j                  dd«      «      }|r| j                  d«      sy|j                  d«      Št	        ˆfd„| d   D «       «      S )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Ú rW   Fé   c              3   óN   •K  — | ]  }d ‰› d �|j                  dd«      v –— Œ y­w)ú.r_   r`   N©rY   )Ú.0r]   Únumbers     €r   ú	<genexpr>z!is_layer_block.<locals>.<genexpr>Ì   s)   øè ø€ Ò[À��6�(˜!ˆ} §	¡	¨-¸Ó <Ô<Ñ[ùs   ƒ"%)ÚLAYER_SUFFIX_REÚmatchrY   ÚgroupÚany)r\   ri   rf   s     @r   Úis_layer_blockrl   ¾   sT   ø€ ô ×!Ñ! $§(¡(¨=¸"Ó"=Ó>€EÙ˜Ÿ™ Ô,ØØ�[‰[˜‹^€FÜÓ[È$ÈzÑJZÔ[Ó[Ð[r   c                 ón  — | j                  d«      syt        | d   «      D ��cg c]  \  }}t        |«      sŒ||f‘Œ }}}t        |«      dkD  r@|dd D ��cg c]  \  }}|‘Œ	 }}}t        | d   «      D ��cg c]  \  }}||vsŒ|‘Œ c}}| d<   | d   D ]  }t	        |«       Œ yc c}}w c c}}w c c}}w )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.
    rW   Nra   r   éÿÿÿÿ)rY   rE   rl   ÚlenÚprune_intermediate_layers)r\   rK   r]   Úlayer_blocksr@   Ú	to_removes         r   rp   rp   Ï   sÁ   € ð �8‰8�JÔØÜ/8¸¸jÑ9IÓ/J×d¡8 1 eÌnÐ]bÕNc�Q˜’JÐd€LÑdä
ˆ<Ó˜1ÒØ#/°°"Ð#5×6™4˜1˜a’QÐ6ˆ	Ñ6Ü2;¸DÀÑ<LÓ2M×d¡h a¨ÐQRÐZcÒQcšEÓdˆˆZÑà�jÑ!ò )ˆÜ! %Õ(ñ)ùó eùó 7ùÛds   ¤B%¸B%ÁB+Á7B1ÂB1c                 óÜ  ‡— | rF	 t        j                  | d¬«       t         j                  j                  | |j                  dz   «      }n|j                  dz   }t        j                  d|› d�«       |dz   }|d	z   }t        |j                  «       t        |d
«      5 }t        j                  |j                  |d¬«       d d d «       ˆfd„Št        j                  t        j                  |j                  «      «      } ‰|«       t        |d
«      5 }t        j                  ||d¬«       d d d «       y # t
        $ r}t        d| › d�«      |‚d }~ww xY w# 1 sw Y   Œ—xY w# 1 sw Y   y xY w)NT©Úexist_okÚ_debug_treeú"Unexpected or existing debug_path=rc   zWriting model trace at z.jsonz_FULL_TENSORS.jsonz_SUMMARY.jsonÚwra   )Úindentc                 ó°   •‡— ˆfd„Š ‰| j                  di «      «        ‰| j                  di «      «       | j                  dg «      D ]
  } ‰|«       Œ y )Nc                 óÆ   •— t        | t        «      r0| j                  dd «       | j                  «       D ]
  } ‰|«       Œ y t        | t        «      r| D ]
  } ‰|«       Œ y y )Nr(   )rB   rG   rZ   ÚvaluesrC   )ÚvalrL   ÚitemÚcleans      €r   r   z:log_model_debug_trace.<locals>.strip_values.<locals>.cleanø   s\   ø€ Ü˜#œtÔ$Ø—‘˜ Ô&ØŸ™›ò �AÙ˜!•Hñä˜C¤Ô&Øò  �DÙ˜$•Kñ ð 'r   ÚinputsrX   rW   rd   )r\   r]   r   Ústrip_valuess     @€r   r�   z+log_model_debug_trace.<locals>.strip_values÷   sR   ù€ ô	 ñ 	ˆd�h‰h�x Ó$Ô%Ùˆd�h‰h�y "Ó%Ô&à—X‘X˜j¨"Ó-ò 	 ˆEÙ˜Õñ	 r   )r0   Úmakedirsr1   r2   Ú_debugger_module_dump_nameÚ	Exceptionr6   ÚloggerÚinfor[   Ú
_call_treeÚopenÚjsonÚdumpÚloadsÚdumps)	r    ÚmodelÚbaseÚeÚ	full_pathÚsummary_pathÚfÚ	tree_copyr�   s	           @r   Úlog_model_debug_tracer”   ã   sJ  ø€ Ùð	XÜ�K‰K˜
¨TÕ2Ü—7‘7—<‘< 
¨E×,LÑ,LÈ}Ñ,\Ó]‰Dð ×/Ñ/°-Ñ?ˆä
‡K�KÐ)¨$¨¨uÐ5Ô6ØÐ+Ñ+€IØ˜/Ñ)€Lä˜e×.Ñ.Ô/ä	ˆi˜Ó	ð 1 Ü�	‰	�%×"Ñ" A¨aÕ0÷1ô ô  —
‘
œ4Ÿ:™: e×&6Ñ&6Ó7Ó8€IÙ�Ôä	ˆl˜CÓ	 ð * AÜ�	‰	�)˜Q qÕ)÷*ð *øôE ò 	XÜÐAÀ*ÀÈQÐOÓPÐVWÐWûð	Xú÷1ð 1ú÷.*ð *ús0   …AD5 Â#EÄE"Ä5	EÄ>EÅEÅEÅ"E+Údo_prune_layersc                 ó¶  ‡ ‡‡‡‡	‡
— ‰ j                   j                  Š	‰	ddg dœ‰ _        g ‰ _        ‰	‰ _        ‰r	 t        j                  ‰d¬«       ˆˆ ˆfd„}‰ j                  «       D ]  \  }}|dk(  rŒ ||‰	› d|› �«       Œ ‰ j                  Š
t        j                  ‰
«      ˆ	ˆˆˆ ˆ
ˆfd	„«       }|‰ _
        y# t        $ r}t        d‰› d�«      |‚d}~ww xY w)
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€   rX   rW   Trt   rw   rc   c                 óv   •‡ ‡‡— ‰ j                   Št        j                  ‰«      ˆˆˆˆ ˆˆfd„«       }|‰ _         y )Nc                  óŠ  •— t        «       r\| |dœ}|D �ci c]  }t        ||   «      dkD  sŒ|||   “Œ }}‰t        |‰‰‰› d�¬«      d g dœ}‰	j                  j	                  |«       t        j                  «       5   ‰| i |¤Ž}d d d «       t        «       r›t        d„ ‰
j                  «       D «       «      dkD  rd d<   nt        ‰‰‰› d�¬«      d<   ‰	j                  j                  «       }|d	   s|j                  d	«       ‰	j                  r!‰	j                  d
   d	   j	                  |«       S c c}w # 1 sw Y   ŒµxY w)N©ÚargsÚkwargsr   Ú_inputsrA   r—   c              3   ó    K  — | ]  }d –— Œ y­w)r   Nr   )re   r@   s     r   rg   zX_attach_debugger_logic.<locals>.wrap_forward.<locals>.wrapped_forward.<locals>.<genexpr>F  s   è ø€ Ò:˜Q”qÑ:ùs   ‚rX   Ú_outputsrW   rn   )
r   ro   rF   Ú_debugger_model_call_stackÚappendr   Úno_gradÚsumÚnamed_childrenrZ   )ÚinpsÚkwsÚdict_inputsrM   r\   r=   Úfinishedr    r�   r�   ÚmoduleÚorig_forwardr!   s          €€€€€€r   Úwrapped_forwardzE_attach_debugger_logic.<locals>.wrap_forward.<locals>.wrapped_forward1  sZ  ø€ äŒØ'+°sÑ;�Ø:EÖa°QÌÈ[ÐYZÉ^ÓI\Ð_`ÓI`˜q +¨a¡.Ñ0Ða�Ðaà#,Ü+Ø#Ø#-Ø!)Ø)2¨°7Ð&;ô	ð  $Ø "ñ
�ð ×0Ñ0×7Ñ7¸Ô=Ü—‘“ñ 1Ù" DÐ0¨CÑ0�÷1ô ŒÜÑ: &×"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÷1ð 1ús   •D4¬D4Á<	D9Ä9E)ÚforwardÚ	functoolsÚwraps)r©   r�   r«   rª   r    r�   r!   s   `` @€€€r   Úwrap_forwardz,_attach_debugger_logic.<locals>.wrap_forward.  s6   û€ Ø—~‘~ˆä	�‰˜Ó	&÷%	ð %	ó 
'ð%	ðN )ˆ�r   r`   c                  óš  •— t        «       r8‰› d�t        | |dœ‰‰‰› d�¬«      d g dœ}‰	j                  j                  |«        ‰
| i |¤Ž}t        «       rð‰	j                  rät        |‰‰‰› d�¬«      d<   ‰	j                  j	                  «       }|d   ‰	j
                  d<   |d   ‰	j
                  d<   |d	   ‰	j
                  d	<   t        ‰	j
                  j                  «       «      D �cg c].  }‰	j
                  |   rŒ‰	j
                  j	                  |d «      ‘Œ0 c} ‰rt        ‰	j
                  «       t        ‰‰	¬
«       |S c c}w )Nz (top-level)rš   r�   rA   r—   rŸ   rX   r€   rW   )r    r�   )
r   rF   r    r¡   rZ   r‡   rC   Úkeysrp   r”   )r¥   r¦   Útop_noder=   r¨   rM   Ú
class_namer    r•   r�   Úreal_top_forwardr!   s         €€€€€€r   Útop_wrapped_forwardz3_attach_debugger_logic.<locals>.top_wrapped_forwardd  sV  ø€ äŒ?à", ¨\Ð:Ü'Ø!¨SÑ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¨qÐY^×YiÑYiÐjkÓYlˆU×Ñ×!Ñ! ! TÕ*Ómñ Ü)¨%×*:Ñ*:Ô;ä!¨Z¸uÕEØˆ
ùò ns   Ã,EÄE)Ú	__class__Ú__name__r‡   r    rƒ   r0   r‚   r„   r6   Ú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ò 8‰ˆˆiØ�2Š:ØÙ�Y : ,¨a°¨vÐ 6Õ7ð8ð —}‘}Ðä‡_�_Ð%Ó&÷#ð #ó 'ð#ðJ (€E…Møô ò 	XÜÐAÀ*ÀÈQÐOÓPÐVWÐWûð	Xús   ºB: Â:	CÃCÃC)r   )Úbackendsc              #   ó<  K  — | j                  «       D ��ci c]  \  }}||j                  “Œ }}}| j                  || <   t        | |||«       	 | –— |j                  «       D ]  \  }}||_        Œ yc c}}w # |j                  «       D ]  \  }}||_        Œ w xY w­w)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»   rH   )	r�   r    r•   r!   r@   ÚmÚorig_forwardsÚmodule_instanceÚforward_methods	            r   Úmodel_addition_debugger_contextrÂ   �  sª   è ø€ ðf /4×.AÑ.AÓ.C×D¡d a¨�Q˜Ÿ	™	‘\ÐD€MÑDØ Ÿ=™=€M�%ÑÜ˜5 *¨o¸xÔHð5ØŠà/<×/BÑ/BÓ/Dò 	5Ñ+ˆO˜^Ø&4ˆOÕ#ñ	5ùó Eøð 0=×/BÑ/BÓ/Dò 	5Ñ+ˆO˜^Ø&4ˆOÕ#ñ	5üs'   ‚B–A2­ BÁA8 Á&BÁ8!BÂB)NTN)rc   TT)NTT)*r­   r‰   r0   ÚreÚ
contextlibr   r   Úior   Úutilsr   Úutils.import_utilsr   r	   r   Úsafetensors.torchr
   r   r   Úis_availableÚtorch.distributed.tensorÚ
get_loggerr·   r…   r   Úcompiler   Ústrr   r   Úboolr>   rF   rJ   r.   r[   rh   rl   rp   r”   r»   rÂ   r   r   r   ú<module>rÏ      s±  ðó  Û Û 	Û 	ß 6Ý å ß <ñ ÔÛÝ+à#(Ð à×Ñ×%Ñ%Ô'Û'à'+Ñ$à#(Ð ð 
ˆ×	Ñ	˜HÓ	%€ò-ð "�r—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   