Ë
    O/æjä;  ã                   ó  — 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Zd dl	Z	d dl
Zd dlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ  G d	„ d
«      Z G d„ de«      Z	 	 d"dej.                  ej0                  ej2                        dej4                  ej6                  eef      dedej<                  ej0                  ej2                        fd„Zd„ Z  G d„ d«      Z!dededejD                  e#ejH                  e   f   fd„Z%dde%fdej.                  ej0                  ej2                        dede&dejN                  ddf
d„Z(ejR                  d#dej.                  e#   dej<                  d   fd„«       Z* G d „ d!«      Z+y)$é    N)ÚPathé   )Úcore)ÚJobEnvironment)ÚCommandFunction©ÚDelayedSubmission)Úenvironment_variablesc                   ó^   ‡ — e Zd ZdZˆ fd„Zdej                  dej                  defd„Zˆ xZ	S )ÚCheckpointablea#  Derived callable classes are requeued after timeout with their current
    state dumped at checkpoint.

    __call__ method must be implemented to make your class a callable.

    Note
    ----
    The following implementation of the checkpoint method resubmits the full current
    state of the callable (self) with the initial argument. You may want to replace the method to
    curate the state (dump a neural network to a standard format and remove it from
    the state so that not to pickle it) and change/remove the initial parameters.
    c                 óf   •— t         ‰| �  | «      }t        |«      sJ d| j                  › d�«       ‚|S )NzClass z^ is marked as Checkpointable but doesn't have a __call__ method. Please add a __call__ method.)ÚsuperÚ__new__ÚcallableÚ__name__)ÚclsÚargsÚkwargsÚinstanceÚ	__class__s       €úS/root/repos/pocs/video-evals/.venv/lib/python3.12/site-packages/submitit/helpers.pyr   zCheckpointable.__new__,   sH   ø€ Ü‘7‘? 3Ó'ˆÜØô
ð 	Aà�C—L‘L�>Ð!ð  Aó	Að 
ð ˆó    r   r   Úreturnc                 ó    — t        | g|¢­i |¤ŽS )z3Resubmits the same callable with the same argumentsr   )Úselfr   r   s      r   Ú
checkpointzCheckpointable.checkpoint3   s   € ô ! Ð7¨Ò7°Ñ7Ð7r   )
r   Ú
__module__Ú__qualname__Ú__doc__r   ÚtpÚAnyr	   r   Ú__classcell__)r   s   @r   r   r      s0   ø„ ñôð8 §¡ð 8°"·&±&ð 8Ð=N÷ 8r   r   c                   ó   — e Zd ZdZddeddfd„Zdej                  dej                  f   dej                  d	ej                  ddfd
„Z	de
fd„Zdej                  e   fd„Zdej                  ej                     fd„Zy)ÚFunctionSequencea  This is for gathering several estimations into one function, which
    will return the sequence of outputs.
    Also this "function" is stateful, hence it can be stopped, and recovered,
    which is useful when job can be preempted.

    Usage
    -----
    func = FunctionSequence()
    func.add(my_function1, arg1, kwarg1=value_kwarg1)
    func.add(my_function2, arg1, arg2)
    result1, result2 = func()

    Note
    ----
    This function is checkpointable because:
    - it derives from Checkpointable
    - it keeps DelayedSubmission objects as attribute, which in turn store the
      results of the computation in memory once they are computed. So at checkpoint
      time, those results will be saved, and only the non-computed results
      will be computed once the job restarts.
    Úverboser   Nc                 ó    — || _         g | _        y ©N)r%   Údelayed_functions)r   r%   s     r   Ú__init__zFunctionSequence.__init__Q   s   € ØˆŒØ=?ˆÕr   Úfunc.r   r   c                 óT   — | j                   j                  t        |g|¢­i |¤Ž«       y r'   )r(   Úappendr	   )r   r*   r   r   s       r   ÚaddzFunctionSequence.addU   s&   € Ø×Ñ×%Ñ%Ô&7¸Ð&N¸tÒ&NÀvÑ&NÕOr   c                 ó,   — t        | j                  «      S r'   )Úlenr(   ©r   s    r   Ú__len__zFunctionSequence.__len__X   s   € Ü�4×)Ñ)Ó*Ð*r   c                 ó,   — t        | j                  «      S r'   )Úiterr(   r0   s    r   Ú__iter__zFunctionSequence.__iter__[   s   € Ü�D×*Ñ*Ó+Ð+r   c                 óä   — | j                   r8t        d„ | D «       «      }t        d|› dt        | j                  «      › �d¬«       | j                  D �cg c]  }|j                  «       ‘Œ c}S c c}w )Nc              3   ó<   K  — | ]  }|j                  «       –— Œ y ­wr'   )Údone)Ú.0Úfs     r   ú	<genexpr>z,FunctionSequence.__call__.<locals>.<genexpr>`   s   è ø€ Ò. A�q—v‘v—xÑ.ùs   ‚zStarting from ú/T©Úflush)r%   ÚsumÚprintr/   r(   Úresult)r   r7   r9   s      r   Ú__call__zFunctionSequence.__call__^   se   € Ø�<Š<ÜÑ.¨Ô.Ó.ˆDÜ�N 4 &¨¬#¨d×.DÑ.DÓ*EÐ)FÐGÈtÕTà $× 6Ñ 6ö
ØˆA�H‰H�Jò
ð 	
ùò 
s   ÁA-©F)r   r   r   r   Úboolr)   r    ÚCallabler!   r-   Úintr1   ÚIteratorr	   r4   ÚListrA   © r   r   r$   r$   :   s—   „ ññ,@ ð @°ó @ðP˜Ÿ™ C¨¯© KÑ0ð P¸¿¹ð PÈ2Ï6É6ð PÐVZó Pð+˜ó +ð,˜"Ÿ+™+Ð&7Ñ8ó ,ð
˜"Ÿ'™' "§&¡&™/ô 
r   r$   ÚjobsÚtimeoutÚpoll_frequencyr   c              #   ód  K  — t        j                   «       }t        «       }	 |� t        j                   «       |z
  |kD  rt        ‚t        | «      D ]0  \  }}||v rŒ|j	                  «       sŒ|j                  |«       |–— Œ2 t        |«      t        | «      k(  ryt        j                  |«       ŒŽ­w)u8  
    Yields jobs as they complete (finished, failed or were cancelled).
    Raises a TimeoutError if the result isnâ€™t available after timeout seconds.
    timeout can be an int or float. If timeout is not specified or None, there is no
    limit to the wait time.

    Parameters
    ----------
    jobs: list
        Jobs instances

    timeout: int/float
        Maximum time (in sec) to wait for jobs completion

    poll_frequency: float
        Frequency in second at which we check job status.

    Yields
    ------
    Job
        The next completed job
    N)ÚtimeÚsetÚTimeoutErrorÚ	enumerater7   r-   r/   Úsleep)rI   rJ   rK   ÚstartÚ	jobs_doneÚiÚjobs          r   Úas_completedrV   g   sœ   è ø€ ô6 �I‰I‹K€EÜ ›U€IØ
ØÐ¤4§9¡9£;°Ñ#6¸Ò#@ÜÐÜ “oò 	‰FˆAˆsØ�I‰~ØØ�x‰x�zØ—‘˜aÔ Ø“	ð	ô ˆy‹>œS ›YÒ&ØÜ�
‰
�>Ô"ð ùs   ‚A(B0Á+AB0c                 óh   — t        j                  | fi |¤Žj                  d«      j                  «       S )Nzutf-8)Ú
subprocessÚcheck_outputÚdecodeÚstrip)Ústr_argsr   s     r   Úrun_cmdr]   ’   s,   € Ü×"Ñ" 8Ñ6¨vÑ6×=Ñ=¸gÓF×LÑLÓNÐNr   c                   ó®   — e Zd ZdZ	 	 	 	 ddedej                  e   dedej                  e	   dej                  e	   f
d„Z
edd	ed
efd„«       Zdd„Zd„ Zy)ÚRsyncSnapshotaÓ  Takes a snapshot of the git repository that the script lives in.

    This ensures that remote jobs always use the code from when they are scheduled
    and not the code from when they are launched / re-started.


    Parameters
    ----------
    snapshot_dir: Path
        A path to where the snapshot should be created
    with_submodules: bool
        Whether or not submodules should be included in the snapshot
    exclude: Sequence[str]
        An optional list of patterns to exclude from the snapshot
    include: Sequence[str]
        A list of relative file names to include from the snapshot.
        Useful for .so or other build artifacts that are genarally not tracked by git.

    Note
    ----
    - Only files that are checked in to the repository are included in the snapshot.
        If you have experimental code that you would like to include in the snapshot,
        you'll need to `git add` the file first for it to be included, or use `include` arg.
    NÚsnapshot_dirÚroot_dirÚwith_submodulesÚexcludeÚincludec                 óÐ   — | j                  d¬«       t        |«      | _        |xs t        g d¢«      | _        t        j
                  «       | _        || _        || _        || _	        y )NT©Úthrow)Úgitz	rev-parsez--show-toplevel)
Ú	availabler   r`   r]   ra   ÚcwdÚoriginal_dirrb   rc   rd   )r   r`   ra   rb   rc   rd   s         r   r)   zRsyncSnapshot.__init__°   sU   € ð 	�‰˜TˆÔ"Ü  Ó.ˆÔØ ÒT¤GÒ,SÓ$TˆŒÜ ŸH™H›JˆÔØ.ˆÔØˆŒØˆ�r   rg   r   c                 óJ   — t        j                  d«      s| rt        d«      ‚yy)NÚrsyncz-RsyncSnapshot requires rsync to be installed.FT)ÚshutilÚwhichÚRuntimeErrorrf   s    r   ri   zRsyncSnapshot.availableÀ   s#   € ä�|‰|˜GÔ$ÙÜ"Ð#RÓSÐSØØr   c                 óš  — t        j                  «       | _        t        | j                  «      }| j
                  rdnd}| j                  j                  «       sW| j                  j                  j                  dd¬«       t        j                  dddd|› �t        | j                  «      g«       t        j                  «       5 }t        d	|› d
|j                  › �|d¬«       t!        t"        j$                  j'                  d„ | j(                  D «       «      «      }t+        |j                  dd¬«      5 }| j,                  D ]  }t/        ||¬«       Œ 	 d d d «       t        ddd|j                  |t        | j                  «      g|z   «       d d d «       t1        j2                  | j                  «       y # 1 sw Y   ŒbxY w# 1 sw Y   Œ5xY w)Nz--recurse-submodulesz-sT)ÚparentsÚexist_okrh   Úclonez	--depth=2zfile://zgit ls-files z | grep -v ^16 | cut -f2- > )rj   Úshellc              3   ó$   K  — | ]  }d |f–— Œ
 y­w)z	--excludeNrH   )r8   Úpats     r   r:   z*RsyncSnapshot.__enter__.<locals>.<genexpr>×   s   è ø€ Ò8dÐPS¸+ÀsÔ9KÑ8dùs   ‚ÚaÚutf8)Úencoding)Úfilerm   z-az--files-from)r   rj   rk   Ústrra   rb   r`   ÚexistsÚparentÚmkdirrX   Ú
check_callÚtempfileÚNamedTemporaryFiler]   ÚnameÚlistÚ	itertoolsÚchainÚfrom_iterablerc   Úopenrd   r?   ÚosÚchdir)r   ra   ÚsubÚtfilerc   ÚoÚincs          r   Ú	__enter__zRsyncSnapshot.__enter__È   s  € Ü ŸH™H›JˆÔä�t—}‘}Ó%ˆØ(,×(<Ò(<Ñ$À$ˆà× Ñ ×'Ñ'Ô)Ø×Ñ×$Ñ$×*Ñ*°4À$Ð*ÔGÜ×!Ñ! 5¨'°;À'È(ÈÐ@TÔVYÐZ^×ZkÑZkÓVlÐ"mÔnô ×(Ñ(Ó*ð 	m¨eä�m C 5Ð(DÀUÇZÁZÀLÐQÐW_ÐgkÕlÜœ9Ÿ?™?×8Ñ8Ñ8dÐW[×WcÑWcÔ8dÓdÓeˆGÜ�e—j‘j #°Ô7ð '¸1ØŸ<™<ò '�CÜ˜# AÖ&ñ'÷'ô �W˜d N°E·J±JÀÌ#Èd×N_ÑN_ÓJ`ÐaÐdkÑkÔl÷	mô 	�‰�×"Ñ"Õ#÷	'ð 'ú÷		mð 	mús%   ÃA0GÄ4F5Å9GÆ5F>	Æ:GÇG
c                 óB   — t        j                  | j                  «       y r'   )r‰   rŠ   rk   )r   r   s     r   Ú__exit__zRsyncSnapshot.__exit__Þ   s   € Ü
�‰�×"Ñ"Õ#r   )NFrH   rH   rB   ©r   N)r   r   r   r   r   r    ÚOptionalrC   ÚSequencer|   r)   Ústaticmethodri   r�   r‘   rH   r   r   r_   r_   –   s‘   „ ñð8 '+Ø %Ø$&Ø$&ñàðð —+‘+˜dÑ#ðð ð	ð
 —‘˜SÑ!ðð —‘˜SÑ!óð  ñ˜ð ¨$ò ó ðó$ó,$r   r_   Úmonitoring_start_timeÚn_jobsÚ
state_jobsc           	      óð  — t        j                   «       | z
  }t        j                  j                  «       j                  d«      }t	        |d   «      }t        t        |«      «      }t        d|› dt        |dz  «      › d�t        |d   «      |› d�›d	|› d
�t        |«      |› d�›d	|› d�t        |d   «      t        |«      z
  |› d�›d	|› d�d¬«       t        |«      dkD  rt        d|› d|› �d¬«       y y )Nz%Y-%m-%d %H:%M:%SÚFAILEDú[z] Launched é<   z minutes ago,ÚRUNNINGÚ r;   z jobs running,z jobs failed,ÚDONEz
 jobs doneTr<   r   z] Failed jobs, indices )	rM   ÚdatetimeÚnowÚstrftimeÚsortedr/   r|   r?   rE   )r–   r—   r˜   Úrun_timeÚ	date_timeÚfailed_job_indicesÚn_charss          r   Ú_default_custom_loggingr¨   â   s  € Ü�y‰y‹{Ð2Ñ2€HÜ×!Ñ!×%Ñ%Ó'×0Ñ0Ð1DÓE€IÜ 
¨8Ñ 4Ó5ÐÜ”#�f“+Ó€Gä	Ø
ˆIˆ;�k¤# h°¡mÓ"4Ð!5°]ÐCÜˆz˜)Ñ$Ó% w i¨p ZÐ
0°°&°¸ÐHÜÐ!Ó" G 9¨@ *Ð
-¨Q¨v¨h°mÐDÜˆz˜&Ñ!Ó"¤SÐ);Ó%<Ñ<¸g¸YÀ`¸JÐ
GÀqÈÈÐPZÐ[Øõô ÐÓ Ò"Ü��)�Ð3Ð4FÐ3GÐHÐPTÖUð #r   é   FÚ	test_modeÚcustom_loggingc                 ó6  — |s|dk\  sJ d«       ‚t        | «      }|dk(  rt        d«       ydj                  t        t	        d„ | D «       «      «      «      }t        d|› d	|› d
�«       t        j
                  «       }	 |s| d   j                  d¬«       t        j                  t        «      }t        | «      D ]V  \  }}	||	j                  j                  «          j                  |«       |	j                  «       sŒC|d   j                  |«       ŒX t        |d   «      }
t        |d   «      t        | «      k(  rt        d|
› d�d¬«       n  ||||«       t        j                  |«       Œît        dt        t        j
                  «       |z
  dz  «      › d�«       y)ay  Continuously monitors given jobs until they are all done or failed.

    Parameters
    ----------
    jobs: List[Jobs]
        A list of jobs to monitor
    poll_frequency: int
        The time (in seconds) between two refreshes of the monitoring.
        Can't be inferior to 30s.
    test_mode: bool
        If in test mode, we do not check the length of poll_frequency
    r©   z@You can't refresh too often (>= 30s) to avoid overloading squeuer   zThere are no jobs to monitorNz, c              3   ól   K  — | ],  }t        |j                  «      j                  d d«      d   –— Œ. y­w)Ú_r   r   N)r|   Újob_idÚsplit)r8   rU   s     r   r:   zmonitor_jobs.<locals>.<genexpr>  s*   è ø€ Ò%WÈ3¤c¨#¯*©*£o×&;Ñ&;¸CÀÓ&CÀAÕ&FÑ%Wùs   ‚24zMonitoring z jobs from job arrays z 
TÚforce)ÚmoderŸ   rš   z%All jobs finished, jobs with indices z failedr<   z Whole process is finished, took rœ   z minutes)r/   r?   Újoinr£   rN   rM   Úget_infoÚcollectionsÚdefaultdictrP   ÚstateÚupperr-   r7   rQ   rE   )rI   rK   rª   r«   r—   Ú
job_arraysr–   r˜   rT   rU   r¦   s              r   Úmonitor_jobsrº   ô   sƒ  € ñ& Ø Ò#ÐgÐ%gÓgÐ#ä�‹Y€FØ�‚{ÜÐ,Ô-Øà—‘œ6¤#Ñ%WÐRVÔ%WÓ"WÓXÓY€JÜ	ˆK˜�xÐ5°j°\ÀÐ
EÔFä ŸI™I›KÐØ
ÙØ�‰G×Ñ 'ÐÔ*Ü ×,Ñ,¬SÓ1ˆ
Ü “oò 	*‰FˆAˆsØ�s—y‘y—‘Ó(Ñ)×-Ñ-¨aÔ0Ø�x‰x�zØ˜6Ñ"×&Ñ& qÕ)ð	*ô
 $ J¨xÑ$8Ó9ÐÜˆz˜&Ñ!Ó"¤c¨$£iÒ/ÜÐ9Ð:LÐ9MÈWÐUÐ]aÕbØáÐ,¨f°jÔAÜ�
‰
�>Ô"ð ô" 
Ð,¬S´$·)±)³+Ð@UÑ2UÐY[Ñ1[Ó-\Ð,]Ð]eÐ
fÕgr   Úextra_namesc              #   óR  K  — d}t         j                  D �ci c];  }|j                  d«      s||v s|| v r |t         j                  j                  |«      “Œ= }}	 d–— t         j                  j	                  |«       yc c}w # t         j                  j	                  |«       w xY w­w)a   Removes slurm and submitit related environment variables so as to avoid interferences
    when submiting a new job from a job.

    Parameters
    ----------
    extra_names: Sequence[str]
        Additional environment variables to hide inside the context,
        e.g. TRITON_CACHE_DIR and TORCHINDUCTOR_CACHE_DIR when using torch.compile.

    Note
    ----
    A slurm job submitted from within a slurm job inherits some of its attributes, which may
    be confusing a cause weird gres errors (or pytorch distributed).
    Submitting within this context should prevent this.

    Usage
    -----
    with submitit.helpers.clean_env():
        executor.submit(...)
    ©ÚMASTER_ADDRÚMASTER_PORTÚRANKÚ
WORLD_SIZEÚ
LOCAL_RANKÚLOCAL_WORLD_SIZE)ÚSLURM_ÚSLURMD_ÚSRUN_ÚSBATCH_Ú	SUBMITIT_N)r‰   ÚenvironÚ
startswithÚpopÚupdate)r»   Údistrib_namesÚxÚcluster_envs       r   Ú	clean_envrÐ   '  s”   è ø€ ð, k€Mô —‘öàà�L‰LÐOÔPØ�MÑ!Ø�KÑð 	
Œ2�:‰:�>‰>˜!ÓÑð€Kð ð'Ûä
�
‰
×Ñ˜+Õ&ùòøô 	�
‰
×Ñ˜+Õ&üs)   ‚B'—A A>ÁB'ÁB Á%B'Â!B$Â$B'c                   ó:   — e Zd Zdd„Zdefd„Z	 	 d	dededd fd„Zy)
ÚTorchDistributedEnvironmentr   Nc                 óŽ  — t        «       | _        | j                  j                  d   | _        | j	                  «       | _        | j                  j                  | _        | j                  j                  | _	        | j                  j                  | _
        | j                  j                  | j                  j                  z  | _        y)a‡  Construct a class holding the parameters required to properly setup
        PyTorch distributed (with the default env:// initialization method).

        Examples
        --------
        >>> dist_env = TorchDistributedEnvironment().export()
        >>> torch.distributed.init_process_group(backend="nccl")
        >>> print(f"master: {dist_env.master_addr}:{dist_env.master_port}")
        r   N)r   Ú_job_envÚ	hostnamesÚmaster_addrÚ_get_master_portÚmaster_portÚglobal_rankÚrankÚ	num_tasksÚ
world_sizeÚ
local_rankÚ	num_nodesÚlocal_world_sizer0   s    r   r)   z$TorchDistributedEnvironment.__init__N  sŠ   € ô 'Ó(ˆŒØŸ=™=×2Ñ2°1Ñ5ˆÔØ×0Ñ0Ó2ˆÔØ—M‘M×-Ñ-ˆŒ	ØŸ-™-×1Ñ1ˆŒØŸ-™-×2Ñ2ˆŒØ $§¡× 7Ñ 7¸4¿=¹=×;RÑ;RÑ RˆÕr   c                 óÞ   — d\  }}t         j                  j                  d«      }|€;t        j                  | j
                  j                  «      }|j                  ||«      S t        |«      }|S )N)i N  i`ê  r¿   )	r‰   rÉ   ÚgetÚrandomÚRandomrÔ   r¯   ÚrandintrE   )r   ÚMIN_MASTER_PORTÚMAX_MASTER_PORTÚmaster_port_strÚrngrØ   s         r   r×   z,TorchDistributedEnvironment._get_master_port`  s]   € à+9Ñ(ˆ˜äŸ*™*Ÿ.™.¨Ó7ˆØÐ"Ü—-‘- §¡× 4Ñ 4Ó5ˆCØ—;‘;˜°Ó@Ð@ä˜/Ó*ˆàÐr   Úset_cuda_visible_devicesÚ	overwritec                 ó°  — | j                   t        | j                  «      t        | j                  «      t        | j                  «      t        | j
                  «      t        | j                  «      dœ}|s(|D ]#  }|t        j                  v sŒt        d|› d�«      ‚ |rt        | j
                  «      |d<   t        j                  j                  |«       | S )aÒ  Export all the environment variables required to properly setup
        PyTorch distributed (with the default env:// initialization method) i.e.
        MASTER_ADDR, MASTER_PORT, RANK, WORLD_SIZE (to which LOCAL_RANK and
        LOCAL_WORLD_SIZE are added).

        Parameter
        ----------
        set_cuda_visible_device: bool
            if True, updates CUDA_VISIBLE_DEVICES to use only the device
            matching the local rank.
        overwrite: bool
            if True, overwrites the environment variables if they exist;
            this can be useful when launching a job from another job.

        Returns
        --------
        TorchDistributedEnvironment
            the current instance
        r½   z'Cannot export environment variables as z is already setÚCUDA_VISIBLE_DEVICES)rÖ   r|   rØ   rÚ   rÜ   rÝ   rß   r‰   rÉ   rp   rÌ   )r   ré   rê   Úenv_varsÚkeys        r   Úexportz"TorchDistributedEnvironment.exportm  s½   € ð8  ×+Ñ+Ü˜t×/Ñ/Ó0Ü˜Ÿ	™	“NÜ˜dŸo™oÓ.Ü˜dŸo™oÓ.Ü # D×$9Ñ$9Ó :ñ
ˆñ Øò g�Øœ"Ÿ*™*Ò$Ü&Ð)PÐQTÐPUÐUdÐ'eÓfÐfðgñ $Ü/2°4·?±?Ó/CˆHÐ+Ñ,Ü
�
‰
×Ñ˜(Ô#Øˆr   r’   )TF)r   r   r   r)   rE   r×   rC   rï   rH   r   r   rÒ   rÒ   M  s=   „ óSð$ #ó ð *.Øñ+à"&ð+ð ð+ð 
'ô	+r   rÒ   )Né
   )rH   ),rµ   Ú
contextlibr    r…   r‰   râ   rn   rX   r�   rM   Útypingr    Úpathlibr   r   Úcore.job_environmentr   Ú
core.utilsr   r	   r
   r   r$   r”   ÚJobÚRr“   ÚUnionrE   ÚfloatrF   rV   r]   r_   ÚDictr|   ÚSetr¨   rC   rD   rº   ÚcontextmanagerrÐ   rÒ   rH   r   r   ú<module>rý      s½  ðó Û Û Û Û 	Û Û Û Û Û Û Ý õ Ý 0Ý :Ý >Ý F÷8ñ 8ô:*
�~ô *
ð^ 26Øñ(#Ø
�+‰+�d—h‘h˜tŸv™vÑ&Ñ
'ð(#à�[‰[˜Ÿ™ # u *Ñ-Ñ.ð(#ð ð(#ð ‡[�[�—‘˜$Ÿ&™&Ñ!Ñ"ó	(#òVO÷I$ñ I$ðXV°5ð VÀ#ð VÐSU×SZÑSZÐ[^Ð`b×`fÑ`fÐgjÑ`kÐ[kÑSló Vð( ØØ"9ñ	0hØ
�+‰+�d—h‘h˜tŸv™vÑ&Ñ
'ð0hàð0hð ð0hð —K‘Kð	0hð
 
ó0hðf ×Ññ"'˜2Ÿ;™; sÑ+ð "'°R·[±[ÀÑ5Fò "'ó ð"'÷JKò Kr   