ó
    Eñi¥B  ã                   ó”   • S SK r S SKrS SKJr  S SKJrJrJrJr  S SK	J
r
JrJrJr  S SKJr  \(       a  S SKJr  \ " S S5      5       rg)	é    N)Ú	dataclass)ÚTYPE_CHECKINGÚLiteralÚOptionalÚUnion)ÚDeepSpeedSequenceParallelConfigÚDistributedTypeÚTorchContextParallelConfigÚTorchTensorParallelConfig)Úis_torch_version)ÚAcceleratorc                   óR  • \ rS rSr% SrSr\\   \S'   Sr	\\   \S'   Sr
\\   \S'   Sr\\   \S'   Sr\S   \S	'   Sr\\   \S
'   Sr\S   \S'   Sr\S\4   \S'   Sr\S\4   \S'   Sr\S\4   \S'   SrS rS r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r \S 5       r!\S 5       r"\S 5       r#\S 5       r$\S 5       r%\S 5       r&\S 5       r'\S 5       r(S \)4S! jr*S,S \\)   4S" jjr+S#\,\,\S$4   \,\)S$4   4   4S% jr-S& r.S'\)S(\4S) jr/S-S* jr0S+r1g).ÚParallelismConfigé!   aM  
A dataclass to configure parallelisms applied to the model. Inspired by torchtitan's `ParallelDims`
https://github.com/pytorch/torchtitan/blob/main/torchtitan/distributed/parallel_dims.py

Args:
    dp_replicate_size (`int`, defaults to `1`):
        The size of the data parallel group. If `dp_replicate_size` is set to 1, the data parallel replication
        group will not be used.
    dp_shard_size (`int`, defaults to `1`):
        The size of the model shard group. If `dp_replicate_size > 1` and `tp_size > 1`, `dp_shard_size` must also
        be greater than 1, as composing DDP + TP is currently not supported.
    tp_size (`int`, defaults to `1`):
        The size of the tensor parallel group. If `tp_size` is set to `1`, the tensor parallel group will not be
        used.
    tp_handler (`~utils.TorchTensorParallelConfig`, defaults to `None`):
        The handler for the tensor parallel group.
    cp_size (`int`, defaults to `1`):
        The size of the context parallel group. Currently not supported, but reserved for future use and enabled
        for downstream libraries.
    cp_backend (`str`, defaults to `torch`):
        Which CP backend to use: `torch` (FSDP2)
    sp_size (`int`, defaults to `1`):
        The size of the sequence parallel group.
    sp_backend (`str`, defaults to `deepspeed`):
        Which SP backend to use:`deepspeed` (ALST/Ulysses)

You may obtain different distributed data parallel paradigms by configuring `dp_replicate_size` and `dp_shard_size`
together:
    - `dp_replicate_size == 1` and `dp_shard_size > 1`, we obtain Fully Sharded Data Parallel (FSDP).
    - `dp_replicate_size > 1` and `dp_shard_size > 1`, we obtain Hybrid Sharded Data Parallel (HSDP).
    - `dp_replicate_size > 1` and `dp_shard_size == 1` is an invalid configuration, to use pure DP, use
      `DistributedDataParallelKwargs` instead.

NÚdp_replicate_sizeÚdp_shard_sizeÚtp_sizeÚcp_sizeÚtorchÚ
cp_backendÚsp_sizeÚ	deepspeedÚ
sp_backendÚ
tp_handlerÚ
cp_handlerÚ
sp_handlerc                 ó  • SU R                    SU R                   SU R                   SU R                   SU R                   SU R
                   SU R                   SU R                   S	U R                   S
U R                   S3$ )Nz'ParallelismConfig(
 	dp_replicate_size=z,
	dp_shard_size=z,
	tp_size=z,
	cp_size=z,
	cp_backend=z,
	sp_size=z,
	sp_backend=z,
	total_size=z
	tp_handler=z,
	cp_handler=z)
)
r   r   r   r   r   r   r   Ú
total_sizer   r   ©Úselfs    ÚZ/home/mande/repo/quber/.venv/lib/python3.13/site-packages/accelerate/parallelism_config.pyÚ__repr__ÚParallelismConfig.__repr__U   s¥   € ð#Ø#'×#9Ñ#9Ð":ð ;Ø#×1Ñ1Ð2ð 3ØŸ™˜ð 'ØŸ™˜ð 'Ø ŸO™OÐ,ð -ØŸ™˜ð 'Ø ŸO™OÐ,ð -Ø ŸO™OÐ,ð -Ø ŸO™OÐ,ð -Ø ŸO™OÐ,¨Cð
1ð	
ó    c                 ó  • SS K nS/nUR                  U R                  R                  5        VVs0 s H;  u  p4X2;  d  M  U[	        US5      (       a  UR                  UR                  5      OU_M=     snn5        g s  snnf )Nr   Údevice_meshÚ__dict__)ÚcopyÚdeepcopyr'   ÚitemsÚhasattr)r    r(   Ú_non_serializable_fieldsÚkÚvs        r!   Úto_jsonÚParallelismConfig.to_jsond   ss   € Ûà$1 ?Ð à�‰ð !ŸM™M×/Ñ/Ô1ôâ1‘D�AØÑ4ó N�´¸¸:×0FÑ0F�4—=‘= §¡Ô,ÈAÒMÙ1òõ	
ùós
   °A;
¿3A;
c                 óf   • / nU R                   (       a  US/-  nU R                  (       a  US/-  nU$ )zENames of enabled dimensions across which data parallelism is applied.Údp_replicateÚdp_shard)Údp_replicate_enabledÚdp_shard_enabled©r    Údimss     r!   Údp_dim_namesÚParallelismConfig.dp_dim_namesq   s9   € ð ˆØ×$×$Ø�^Ð$Ñ$ˆDØ× × Ø�Z�LÑ ˆDØˆr$   c                 ó”   • / nU R                   (       a  US/-  nU R                  (       a  US/-  nU R                  (       a  US/-  nU$ )z]Names of enabled dimensions which will receive the same batch (non-data parallel dimensions).ÚtpÚcpÚsp)Ú
tp_enabledÚ
cp_enabledÚ
sp_enabledr6   s     r!   Únon_dp_dim_namesÚ"ParallelismConfig.non_dp_dim_names{   sD   € ð ˆØ�?�?Ø�T�F‰NˆDØ�?�?Ø�T�F‰NˆDØ�?�?Ø�T�F‰NˆDØˆr$   c                 óf   • / nU R                   (       a  US/-  nU R                  (       a  US/-  nU$ )zlNames of enabled dimensions which will be flattened into a joint mesh across which is model sharded in FSDP.r3   r<   )r5   r?   r6   s     r!   Údp_shard_cp_dim_namesÚ'ParallelismConfig.dp_shard_cp_dim_names‡   s5   € ð ˆØ× × Ø�Z�LÑ ˆDØ�?�?Ø�T�F‰NˆDØˆr$   c                 ó”   • / nU R                   (       a  US/-  nU R                  (       a  US/-  nU R                  (       a  US/-  nU$ )z@Names of enabled dimensions across which loss should be averagedr2   r3   r<   )r4   r5   r?   r6   s     r!   Údp_cp_dim_namesÚ!ParallelismConfig.dp_cp_dim_names‘   sK   € ð ˆØ×$×$Ø�^Ð$Ñ$ˆDØ× × Ø�Z�LÑ ˆDØ�?�?Ø�T�F‰NˆDØˆr$   c                 óD   • / nU R                   (       a  US/-  nUS/-  nU$ )z^Names of enabled dimensions across which FSDP is applied, including data parallel replication.r2   Údp_shard_cp)r4   r6   s     r!   Úfsdp_dim_namesÚ ParallelismConfig.fsdp_dim_names�   s0   € ð ˆØ×$×$Ø�^Ð$Ñ$ˆDØ��ÑˆØˆr$   c                 ó‚   • U R                   U R                  -  U R                  -  U R                  -  U R                  -  $ )zSThe total size of the parallelism configuration, which is the product of all sizes.)r   r   r   r   r   r   s    r!   r   ÚParallelismConfig.total_size¦   s9   € ð ×%Ñ%¨×(:Ñ(:Ñ:¸T¿\¹\ÑIÈDÏLÉLÑXÐ[_×[gÑ[gÑgÐgr$   c                 óN   • U R                   U R                  -  U R                  -  $ )zhThe size of the non-data parallel dimensions, which is the product of tensor and context parallel sizes.)r   r   r   r   s    r!   Únon_data_parallel_sizeÚ(ParallelismConfig.non_data_parallel_size«   s    € ð �|‰|˜dŸl™lÑ*¨T¯\©\Ñ9Ð9r$   c                 ó4   • U R                   U R                  -  $ )z_The size of the data parallel dimensions, which is the product of data parallel replication and)r   r   r   s    r!   Údata_parallel_sizeÚ$ParallelismConfig.data_parallel_size°   s   € ð ×%Ñ%¨×(:Ñ(:Ñ:Ð:r$   c                 ó    • U R                   S:„  $ )zKTrue if data parallel replication is enabled, i.e. `dp_replicate_size > 1`.é   )r   r   s    r!   r4   Ú&ParallelismConfig.dp_replicate_enabledµ   s   € ð ×%Ñ%¨Ñ)Ð)r$   c                 ó    • U R                   S:„  $ )zDTrue if data parallel sharding is enabled, i.e. `dp_shard_size > 1`.rV   )r   r   s    r!   r5   Ú"ParallelismConfig.dp_shard_enabledº   s   € ð ×!Ñ! AÑ%Ð%r$   c                 ó    • U R                   S:„  $ )z:True if tensor parallelism is enabled, i.e. `tp_size > 1`.rV   )r   r   s    r!   r>   ÚParallelismConfig.tp_enabled¿   ó   € ð �|‰|˜aÑÐr$   c                 ó    • U R                   S:„  $ )z;True if context parallelism is enabled, i.e. `cp_size > 1`.rV   )r   r   s    r!   r?   ÚParallelismConfig.cp_enabledÄ   r\   r$   c                 ó    • U R                   S:„  $ )z;True if context parallelism is enabled, i.e. `sp_size > 1`.rV   )r   r   s    r!   r@   ÚParallelismConfig.sp_enabledÉ   r\   r$   c                 ó4   • U R                   U R                  -   $ )z$Names of all active mesh dimensions.)r8   rA   r   s    r!   Úactive_mesh_dimsÚ"ParallelismConfig.active_mesh_dimsÎ   s   € ð × Ñ  4×#8Ñ#8Ñ8Ð8r$   Údevice_typec                 óú  • U R                   S:X  a  U R                  S:”  a  g[        SS5      (       a  SSKJn  O[        S5      eU R                  5       n[        U5      S:X  a  gUu  pEU" UUUS	9nU R                  (       a  X`R                     R                  S
5        U R                  (       a  X`R                     R                  S5        U R                  (       a  X`R                     R                  S5        U$ )a  Builds a device mesh for the given device type based on the parallelism configuration.
This method will also create required joint meshes (e.g. `dp_shard_cp`, `dp_cp`, `dp`).

Args:
    device_type (`str`): The type of device for which to build the mesh, e
r   rV   Nz>=z2.2.0r   )Úinit_device_meshz4Building a device_mesh requires to have torch>=2.2.0)Úmesh_dim_namesÚdprJ   Údp_cp)r   r   r   Útorch.distributed.device_meshrf   ÚRuntimeErrorÚ	_get_meshÚlenr8   Ú_flattenrD   rG   )r    rd   rf   Úmeshrg   Ú
mesh_shaper&   s          r!   Úbuild_device_meshÚ#ParallelismConfig.build_device_meshÓ   s×   € ð �?‰?˜kÓ)¨d¯l©l¸QÓ.>Øä˜D '×*Ñ*ÞFäÐUÓVÐVà�~‰~ÓˆÜˆt‹9˜‹>ØØ%)Ñ"ˆÙ&ØØØ)ñ
ˆð
 ××Ø×)Ñ)Ñ*×3Ñ3°DÔ9Ø×%×%Ø×2Ñ2Ñ3×<Ñ<¸]ÔKØ××Ø×,Ñ,Ñ-×6Ñ6°wÔ?àÐr$   c                 ó  • U R                   c'  Ub"  U R                  U5      U l         U R                   $ SeUb@  U R                   R                  U:w  a&  [        SU R                   R                   SU S35      eU R                   $ )Nz@You need to pass a device_type e.g cuda to build the device meshz4The device_mesh is already created with device type z@. However, you are trying to get a device mesh with device_type z<. Please check if you correctly initialized your device_mesh)r&   rq   rd   Ú
ValueError)r    rd   s     r!   Úget_device_meshÚ!ParallelismConfig.get_device_meshö   s©   € Ø×ÑÑ#ØÑ&Ø#'×#9Ñ#9¸+Ó#F�Ô ð ×ÑÐð ZÐZàÑ&Ø×#Ñ#×/Ñ/°;Ó>Ü$ØNÈt×O_ÑO_×OkÑOkÐNlð  mmð  nyð  mzð  zvð  wóð ð ×ÑÐr$   Úreturn.c                 óÂ   ^• U R                    Vs0 s H  oU R                  U   _M     nn/ SQm[        UR                  5       U4S jS9n[	        [        U6 5      $ s  snf )zQGenerate mesh shape and dimension names for torch.distributed.init_device_mesh().)r2   r3   r<   r=   r;   c                 ó,   >• TR                  U S   5      $ )Nr   )Úindex)ÚxÚ
mesh_orders    €r!   Ú<lambda>Ú-ParallelismConfig._get_mesh.<locals>.<lambda>  s   ø€ ˜:×+Ñ+¨A¨a©DÔ1r$   )Úkey)rb   Ú_sizesÚsortedr*   ÚtupleÚzip)r    ÚparallelismÚ	mesh_dimsÚsorted_itemsr|   s       @r!   rl   ÚParallelismConfig._get_mesh  sf   ø€ ð OS×NcÒNcÓdÒNc¸{ $§+¡+¨kÑ":Ò:ÑNcˆ	Ðdò Dˆ
ÜØ�O‰OÓÜ2ñ
ˆô ”S˜,Ð'Ó(Ð(ùò es   �Ac           
      óî  • U R                   c.  [        [        R                  R	                  SS5      5      U l         U R
                  c.  [        [        R                  R	                  SS5      5      U l        U R                  c.  [        [        R                  R	                  SS5      5      U l        U R                  c.  [        [        R                  R	                  SS5      5      U l        U R                  c%  [        R                  R	                  SS5      U l        U R                  c.  [        [        R                  R	                  SS5      5      U l	        U R                  c%  [        R                  R	                  S	S
5      U l
        U R                  S:”  a  U R                  c  [        5       U l        U R                  S:”  aŽ  U R                  c  [        5       U l        Oq[        [        S9n[!        U R                  XR                     5      (       d=  [#        SU R                   SXR                      S[%        U R                  5       35      eU R                  S:”  a  U R&                  c  [)        5       U l        U R                   S:  a  [#        SU R                    35      eU R
                  S:  a  [#        SU R
                   35      eU R                  S:  a  [#        SU R                   35      eU R                  S:  a  [#        SU R                   35      eS/nU R                  U;  a  [#        SU SU R                   35      eU R                  S:  a  [#        SU R                   35      eS
/nU R                  U;  a  [#        SU SU R                   35      eU R                  S:”  a6  U R                  S:”  a&  [#        SU R                   SU R                   S35      eU R                  S:”  d  U R                  S:”  a+  U R                   S:”  a  U R
                  S:X  a  [#        S5      eU R                   U R
                  U R                  U R                  U R                  S.U l        g )NÚ$PARALLELISM_CONFIG_DP_REPLICATE_SIZEÚ1Ú PARALLELISM_CONFIG_DP_SHARD_SIZEÚPARALLELISM_CONFIG_TP_SIZEÚPARALLELISM_CONFIG_CP_SIZEÚPARALLELISM_CONFIG_CP_BACKENDr   ÚPARALLELISM_CONFIG_SP_SIZEÚPARALLELISM_CONFIG_SP_BACKENDr   rV   )r   zParallelismConfig's cp_backend=z
 requires z, but cp_handler was set to z.dp_replicate_size must be at least 1, but got z*dp_shard_size must be at least 1, but got z$tp_size must be at least 1, but got z$cp_size must be at least 1, but got zcp_backend must be one of z
, but got z$sp_size must be at least 1, but got zsp_backend must be one of z[Context Parallelism (CP) and Sequence Parallelism (SP) are mutually exclusive. Got cp_size=z and sp_size=z+. Please set either cp_size=1 or sp_size=1.aC  Tensor/Context parallelism (tp/cp_size > 1) cannot be used with pure data parallelism (dp_replicate_size > 1 and dp_shard_size == 1). Please set dp_shard_size > 1 and dp_replicate_size == 1 to compose FSDP + TP/CP for 2D parallel, or set dp_replicate_size == 1 and dp_shard_size > 1 to compose HSDP + TP/CP for 3D parallel.)r2   r3   r;   r<   r=   )r   ÚintÚosÚenvironÚgetr   r   r   r   r   r   r   r   r   r
   ÚdictÚ
isinstancert   Útyper   r   r€   )r    Úcp_backends_config_mapÚvalid_cp_backendsÚvalid_sp_backendss       r!   Ú__post_init__ÚParallelismConfig.__post_init__  sâ  € à×!Ñ!Ñ)Ü%(¬¯©¯©Ð8^Ð`cÓ)dÓ%eˆDÔ"Ø×ÑÑ%Ü!$¤R§Z¡Z§^¡^Ð4VÐX[Ó%\Ó!]ˆDÔØ�<‰<ÑÜœrŸz™zŸ~™~Ð.JÈCÓPÓQˆDŒLØ�<‰<ÑÜœrŸz™zŸ~™~Ð.JÈCÓPÓQˆDŒLØ�?‰?Ñ"Ü Ÿj™jŸn™nÐ-LÈgÓVˆDŒOØ�<‰<ÑÜœrŸz™zŸ~™~Ð.JÈCÓPÓQˆDŒLØ�?‰?Ñ"Ü Ÿj™jŸn™nÐ-LÈkÓZˆDŒOà�<‰<˜!ÓØ�‰Ñ&Ü";Ó"=�”à�<‰<˜!ÓØ�‰Ñ&Ü"<Ó">�•ä)-Ü4ñ*Ð&ô " $§/¡/Ð3IÏ/É/Ñ3Z×[Ñ[Ü$Ø9¸$¿/¹/Ð9JÈ*ÐUk×l{Ñl{ÑU|ÐT}ð  ~Zô  [_ð  `d÷  `oñ  `oó  [pð  Zqð  róð ð �<‰<˜!ÓØ�‰Ñ&Ü"AÓ"C�”Ø×!Ñ! AÓ%ÜÐMÈd×NdÑNdÐMeÐfÓgÐgØ×Ñ Ó!ÜÐIÈ$×J\ÑJ\ÐI]Ð^Ó_Ð_Ø�<‰<˜!ÓÜÐCÀDÇLÁLÀ>ÐRÓSÐSØ�<‰<˜!ÓÜÐCÀDÇLÁLÀ>ÐRÓSÐSØ$˜IÐØ�?‰?Ð"3Ó3ÜÐ9Ð:KÐ9LÈJÐW[×WfÑWfÐVgÐhÓiÐià�<‰<˜!ÓÜÐCÀDÇLÁLÀ>ÐRÓSÐSØ(˜MÐØ�?‰?Ð"3Ó3ÜÐ9Ð:KÐ9LÈJÐW[×WfÑWfÐVgÐhÓiÐið �<‰<˜!Ó §¡¨qÓ 0ÜðØ#Ÿ|™|˜n¨M¸$¿,¹,¸ð H<ð<óð ð �L‰L˜1Ó §¡¨qÓ 0°d×6LÑ6LÈqÓ6PÐUY×UgÑUgÐklÓUlÜðoóð ð !×2Ñ2Ø×*Ñ*Ø—,‘,Ø—,‘,Ø—,‘,ñ
ˆ�r$   r„   Úsizec                 ó¼   • XR                   R                  5       ;   d"   SU R                   R                  5        35       eX R                   U'   [        X S3U5        g )NzParallelism must be one of Ú_size)r€   ÚkeysÚsetattr)r    r„   r�   s      r!   Ú	_set_sizeÚParallelismConfig._set_size^  sV   € ØŸk™k×.Ñ.Ó0Ó0ÐdÐ4OÐPT×P[ÑP[×P`ÑP`ÓPbÐOcÐ2dÓdÐ0Ø#'�‰�KÑ Ü�˜ UÐ+¨TÕ2r$   c                 ó€  • [        5       nUR                  (       d  U R                  S:X  a  g U R                  S:X  a  U R                  SUR                  5        U R
                  S:X  a  U R                  S:”  a  O@U R                  UR                  :w  a&  [        SU R                   SUR                   S35      eU R                  S:”  aY  UR                  (       dH  UR                  (       d7  UR                  [        R                  :X  d  [        SUR                   S35      eU R                  R                  5        H7  u  p4US:X  d  M  [        X S	3S 5      c  M  UR                  S
U SU S35        M9     U(       a@  UR                   (       a.  ["        R$                  " SSR'                  U5      -   [(        5        g g g )NrV   r2   r   zParallelismConfig total_size (z ) does not match num_processes (zJ). Please adjust dp_replicate_size/ dp_shard_size/tp_size/cp_size/sp_size.z�ParallelismConfig is only compatible DistributedType.FSDP (version 2) or DistributedType.Multi{Device} or DistributedType.DEEPSPEED, but got Ú.Ú_handlerzParallelismConfig.z_handler is set, but z0_size is set to 1. This handler will be ignored.z.ParallelismConfig has the following warnings:
Ú
)ÚsetÚmulti_devicer   r¢   Únum_processesr   r   rt   Úis_fsdp2Údistributed_typer	   Ú	DEEPSPEEDr€   r*   ÚgetattrÚaddÚis_main_processÚwarningsÚwarnÚjoinÚUserWarning)r    ÚacceleratorÚ	_warningsr„   r�   s        r!   Ú_validate_acceleratorÚ'ParallelismConfig._validate_acceleratorc  s¦  € Ü“Eˆ	Ø×'×'¨D¯O©O¸qÓ,@àð �?‰?˜aÓØ�N‰N˜>¨;×+DÑ+DÔEð �?‰?˜kÓ)¨d¯l©l¸QÓ.>ØØ�_‰_ × 9Ñ 9Ó9ÜØ0°·±Ð0Að B"Ø"-×";Ñ";Ð!<ð =9ð:óð ð �?‰?˜QÓØ× × Ø×'×'Ø×+Ñ+¬×/HÑ/HÓHäð bð  cn÷  cñ  cð  b@ð  @Að  Bóð ð "&§¡×!2Ñ!2Ö!4ÑˆKØ�q�yœW T¨]¸(Ð+CÀTÓJÓVØ—‘Ø(¨¨Ð5JÈ;È-ð  XHð  Iöñ "5ö ˜×4×4Ü�MŠMØAÀDÇIÁIÈiÓDXÑXÜõð 5ˆ9r$   )r€   r   r   r   r&   r   r   r   r   r   r   r   )N)rµ   r   )2Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r   r‘   Ú__annotations__r   r   r   r   r   r   r   r   r   r   r   r
   r   r   r&   r"   r/   Úpropertyr8   rA   rD   rG   rK   r   rP   rS   r4   r5   r>   r?   r@   rb   Ústrrq   ru   r‚   rl   r›   r¢   r·   Ú__static_attributes__© r$   r!   r   r   !   s;  ‡ ñ!ðF (,Ð�x ‘}Ó+Ø#'€M�8˜C‘=Ó'Ø!€GˆX�c‰]Ó!Ø!€GˆX�c‰]Ó!Ø#'€J�˜Ñ Ó'Ø!€GˆX�c‰]Ó!Ø'+€J�˜Ñ$Ó+ð :>€J��dÐ5Ð5Ñ6Ó=Ø:>€J��dÐ6Ð6Ñ7Ó>Ø?C€J��dÐ;Ð;Ñ<ÓCà€Kò
ò
ð ñó ðð ñ	ó ð	ð ñó ðð ñ	ó ð	ð ñó ðð ñhó ðhð ñ:ó ð:ð ñ;ó ð;ð ñ*ó ð*ð ñ&ó ð&ð ñ ó ð ð ñ ó ð ð ñ ó ð ð ñ9ó ð9ð!¨Sô !ñF ¨8°C©=õ  ð)˜5  s¨C x¡°%¸¸S¸±/Ð!AÑBô )òJ
ðX3 Sð 3°ô 3÷
+r$   r   )r’   r±   Údataclassesr   Útypingr   r   r   r   Úaccelerate.utils.dataclassesr   r	   r
   r   Úaccelerate.utils.versionsr   Ú
accelerater   r   rÂ   r$   r!   Ú<module>rÈ      sI   ðó 
Û Ý !ß :Ó :÷ó õ 7ö Ý&ð ÷lð ló ñlr$   