o
    *j*                     @   s:  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mZ d dlmZmZmZmZmZmZ d dlmZ d dlmZmZ g d	Zd
d Zd)ddZd*ddZdd Zdd Z dd Z!dd Z"G dd dZ#e j$dd Z%dd Z&dd  Z'd!d" Z(d#d$ Z)d%d& Z*e j$d'd( Z+dS )+    N)Future)partial)Path)
MethodTypeSimpleNamespace)BinaryIODictIterableListOptionalUnion) DEFAULT_MODELSCOPE_DATA_ENDPOINT)
CommitInfoCommitOperation)
z*.binz*.safetensorsz*.pthz*.ptz*.h5z*.ckptz*.zipz*.onnxz*.tarz*.gzc            
         s
  g } g d}ddgg d t jddur^ddl}tjd j}|D ]9}d| v r-q$|| }|D ])tfd	d
|D r\zt 	d| |j
}t||  W q3   Y q3q3q$t jddurzddlW n   Y nt}dd
 |D }| fdd
|D  t jddurzddl}	W n   Y | S tjd tdrj}|D ]9}d| v rq|| }|D ])tfdd
 D rzt 	d| |	j
}t||  W q   Y qqq| S t}dd
 |D }|  fdd
|D  | S )z/Find all modules in transformers/peft/diffusers)zAuto.*zT5.*ZBitsAndBytesConfigGenerationConfigzAwq.*zGPTQ.*ZBatchFeaturezQwen.*zLlama.*zIntern.*z
Deepseek.*ZPretrainedConfigZPreTrainedTokenizerPreTrainedModelZPreTrainedTokenizerFastz.*PeftModel.*z.*Config)z^(?!TF|Flax).*Pipeline$z^(?!TF|Flax).*Autoencoder.*z^(?!TF|Flax).*Model$z^(?!TF|Flax).*Adapter$ZImageProjectionz^(?!TF|Flax).*UNet$z^(?!TF|Flax).*Scheduler$transformersNr   dummyc                       g | ]}t | qS  re	fullmatch.0namevaluer   a/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/utils/hf_util/patcher.py
<listcomp>C       
z,get_all_imported_modules.<locals>.<listcomp>.peftc                 S      g | ]	}| d s|qS __
startswithr   attrr   r   r   r   V   
    
c                    s,   g | ] t  fd dD rt qS )c                    r   r   r   r   Z_importr   r   r   Z   s    7get_all_imported_modules.<locals>.<listcomp>.<listcomp>anygetattrr   )r"   peft_include_namesr+   r   r   Y   s    	diffusers_import_structurec                    r   r   r   r   r   r   r   r   m   r    c                 S   r#   r$   r&   r(   r   r   r   r   z   r*   c                    s,   g | ] t  fd dD rt qS )c                    r   r   r   r   r+   r   r   r      r    r,   r-   r0   )diffusers_include_nameslazy_moduler+   r   r   }   s    )	importlibutil	find_specr   sysmodulesr3   lowerr.   import_module__name__r/   appendr"   dirextendr2   hasattr)
all_imported_modulesZtransformers_include_namesr   r3   keyvaluesmodule
attributesZimportsr2   r   )r4   r5   r"   r1   r   r   get_all_imported_modules   s   

!


rG   c                 C   s   d }d| v rddl m} |dg}|S d| v r"ddlm} |dg}|S d| v r>t|d ur5t|dr5|j ng g d	 }|S d
| v rFg d	}|S )Nr   r   )GENERATION_CONFIG_NAME*.pyConfig)CONFIG_NAME	Tokenizervocab_files_names)zchat_template.jinjaz*.jsonrI   z*.txtz*.modelz
*.tiktoken	Processor)transformers.utilsrH   r   rK   listrA   rM   rD   )module_nameclsextra_allow_file_patternrH   rK   r   r   r   _decide_allow_file_pattern   s*   
rT   Fc                    sz  		d%dd  fdd} fdd} fdd	} fd
d}		d%dddt tttt f  dt tttt f  f fdd}g }| D ]։du sOtdsPqDj}d| v p^d| v }	|	sdi }
ndti}
ztd}td}td}td}W n   Y qD|sd| v r|rz|s|s|s|s| n||fi |
 W qD   | Y qD|rtdst	
jj}d|v od|v }j_|stt|fi |
_ntt|fi |
_|rtdsj_tt|fi |
_|rtdsj_tt|fi |
_| qDdd  }d!d"lm} t|d#s;|j|_||_d!d$lm} ||_|S )&zPatch all class to download from modelscope

    Args:
        wrap: Wrap the class or monkey patch the original class

    Returns:
        The classes after patched
    Nc           
      [   s   ddl m} |dd }d }|r| d}tj| sK|dd }|d u s)|dkr+d}|d ur1|}|dd	}|| ||||d
}	|rItj|	|}	|	S | }	|	S )Nr   snapshot_download	subfolderz/*revisionmainmasterlocal_files_onlyF)rX   r[   ignore_file_patternallow_file_pattern)
modelscoperV   popospathexistsjoin)
pretrained_model_name_or_pathr\   r]   kwargsrV   rW   Zfile_filterrX   r[   	model_dirr   r   r   get_model_dir   s0   
z._patch_pretrained_class.<locals>.get_model_dirc                    @    || dd| ddfi |}| jj| |g|R i |S )zPatch all from_pretrainedr\   Nr]   r_   _from_pretrained_origin__func__rR   rd   
model_argsre   rf   rg   r   r   #patch_pretrained_model_name_or_path      

zD_patch_pretrained_class.<locals>.patch_pretrained_model_name_or_pathc                    rh   )zPatch all get_config_dictr\   Nr]   )r_   _get_config_dict_originrk   rl   rn   r   r   patch_get_config_dict   rp   z6_patch_pretrained_class.<locals>.patch_get_config_dictc                    sB    || dd| ddfi |}| jj| ||g|R i |S )zPatch all peft.from_pretrainedr\   Nr]   ri   )rR   modelmodel_idrm   re   rf   rn   r   r   patch_peft_model_id   s   

z4_patch_pretrained_class.<locals>.patch_peft_model_idc                    s:    || dd| ddfi |}| jj| |fi |S )zPatch all _get_peft_typer\   Nr]   )r_   _get_peft_type_originrk   )rR   rt   re   rf   rn   r   r   patch_get_peft_type   s   

z4_patch_pretrained_class.<locals>.patch_get_peft_typemodule_classr   r\   r]   c                    s   t j fddfdd}G  fddd}tds(|`ntjj}d|v r:d	|v r:||_td
sA|`tdsH|`tdsO|`	j
|_
j|_|S )a?  Get a custom wrapper class for  auto classes to download the models from the ModelScope hub
        Args:
            module_class (`PreTrainedModel`): The actual module class
            ignore_file_pattern (`str` or `List`, *optional*, default to `None`):
                Any file pattern to be ignored, like exact file names or file extensions.
            allow_file_pattern (`str` or `List`, *optional*, default to `None`):
                Any file pattern to be included, like exact file names or file extensions.
        Returns:
            The wrapped class
        c                 3   sn    d| vr	 | d< d| vr| d< |  dd u r&|d ur&t|j|}|| d< d V  | dd  | dd  d S )Nr]   r\   )getrT   r=   r_   )re   rx   rR   rS   )r]   r\   r   r   file_pattern_context   s$   zP_patch_pretrained_class.<locals>.get_wrapped_class.<locals>.file_pattern_contextc                    s\    | |fd|}W d    n1 sw   Y  j | |g|R i |}|S )N)rx   rR   )from_pretrained)rs   rt   rm   re   rf   
module_objrz   rg   rx   r   r   r{   	  s    

zK_patch_pretrained_class.<locals>.get_wrapped_class.<locals>.from_pretrainedc                       sx   e Zd ZefddZefddZefddZ	ddeee	j
f d	ef fd
dZ  ZS )zH_patch_pretrained_class.<locals>.get_wrapped_class.<locals>.ClassWrapperc                    sj    ||  |fi |}W d    n1 sw   Y  j |g|R i |}jdr3||_|S )NZ	AutoModel)r{   r=   r'   rf   rR   rd   rm   re   rf   r|   r}   r   r   r{     s   zX_patch_pretrained_class.<locals>.get_wrapped_class.<locals>.ClassWrapper.from_pretrainedc                    sX   ||  |f d|}W d    n1 sw   Y  j |fi |}|S N)r\   r]   )_get_peft_type)rR   rt   re   rf   r|   r]   rz   rg   r\   rx   r   r   r   (  s   zW_patch_pretrained_class.<locals>.get_wrapped_class.<locals>.ClassWrapper._get_peft_typec                    s^   ||  |f d|}W d    n1 sw   Y  j |g|R i |}|S r   )get_config_dictr~   r   r   r   r   4  s$   zX_patch_pretrained_class.<locals>.get_wrapped_class.<locals>.ClassWrapper.get_config_dictTsave_directorysafe_serializationc                    s   | dd}|rDddlm} ddlm} ddlm} |d}| dd }| d	|t	j
jd
 }	| }
|
| |
|	 |||	 t jd||dd| |r]||	|||d d S d S )Npush_to_hubFr   )r   HubApi)
Repositorytokencommit_messagerepo_id)r   r   r   )	repo_name
output_dirr   r   r   )r_   modelscope.hub.push_to_hubr   modelscope.hub.apir   Zmodelscope.hub.repositoryr   ry   splitr`   ra   seplogincreate_reposupersave_pretrained)selfr   r   re   r   r   r   r   r   r   api	__class__r   r   r   B  s<   




zX_patch_pretrained_class.<locals>.get_wrapped_class.<locals>.ClassWrapper.save_pretrained)T)r=   
__module____qualname__classmethodr{   r   r   r   strr`   PathLikeboolr   __classcell__r   r   r   r   ClassWrapper  s    r   r{   rs   rt   r   r   r   )
contextlibcontextmanagerrA   r{   inspect	signature
parametersr   r   r   r=   r   )rx   r\   r]   re   r{   r   r   rg   var)r]   rz   r\   rx   r   get_wrapped_class   s$   
P


z2_patch_pretrained_class.<locals>.get_wrapped_classr=   	tokenizerconfigr{   r   r   r   Zpipelinerj   rs   rt   rv   rq   c           	      _   s   ddl m} dt|jv r$|d }tj|s$ddlm	} |||d< d| v rg| 
d\}} tj|sai }t| }|d urC||d< d| v sOd| v sOd	| v rSt|d
< ddlm	} ||fi |}|d |  } || g|R i |S )Nr   )$origin_get_class_from_dynamic_modulerd   rU   z--r]   rJ   rN   rL   r\   )Z!transformers.dynamic_module_utilsr   r   r   r   r`   ra   rb   r^   rV   r   rT   r\   )	Zclass_referenceargsre   r   rd   rV   r   Zdownload_kwargsrS   r   r   r   get_class_from_dynamic_module  sB   z>_patch_pretrained_class.<locals>.get_class_from_dynamic_moduler   dynamic_module_utilsr   configuration_auto)NN)r   r   r   r
   rA   r=   r;   r\   r>   r   r   r{   r   rj   r   r   r   rv   r   rq   r   r   r   r   transformers.models.autor   )rB   wrapro   rr   ru   rw   r   Zall_available_modulesr   Z
skip_modelZignore_file_pattern_kwargshas_from_pretrainedhas_get_peft_typehas_get_config_dictZhas_save_pretrainedr   Zis_peftr   r   r   r   r   r   _patch_pretrained_class   s   


	
 



r   c                 C   s  | D ]d}|d u r	qzt |d}t |d}t |d}W n   Y q|r7t |dr7|j|_zt|d W n   Y |rNt |drN|j|_zt|d W n   Y |rft |drf|j|_zt|d W q   Y qqddlm	} t |d	r|j
|_dd
lm} |j
|_t|d	 d S d S )Nr{   r   r   rj   rv   rq   r   r   r   r   )rA   rj   r{   delattrrv   r   rq   r   r   r   r   r   r   r   )rB   r   r   r   r   r   r   r   r   r   _unpatch_pretrained_class  sF   


r   c                  C   sL   zddl m}  W n
 ty   Y dS w t| drdS | j| _ddd| _dS )a   Monkey-patch the `kernels` library to route HF API calls to ModelScope.

    Only `kernels.utils._get_hf_api` is replaced; every download, file check
    and ref listing performed by `kernels` goes through `_MsKernelApi`, so
    the kernel loading/variant/lock logic stays untouched.
    r   utilsN_get_hf_api_originc                 S   s   t  S N)_MsKernelApi)
user_agentr   r   r   <lambda>  s    z _patch_kernels.<locals>.<lambda>r   )kernelsr   ImportErrorrA   _get_hf_apir   kernels_utilsr   r   r   _patch_kernels  s   
r   c                  C   sL   zddl m}  W n
 ty   Y d S w t| dd }|d ur$|| _| `d S d S )Nr   r   r   )r   r   r   r/   r   r   )r   originr   r   r   _unpatch_kernels  s   r   c                 C   s   | dv rdS | S )z<Translate an HF revision string into one ModelScope accepts.)NrY   rZ   r   rX   r   r   r   _ms_revision"  s   r   c                   @   sT   e Zd ZdZddddddddZddddd	Zdd
ddZdd Zdd ZdS )r   zMinimal `HfApi` look-alike that forwards to ModelScope. Only the
    handful of methods that `kernels` actually calls are implemented.
    NF)allow_patternsignore_patterns	cache_dirrX   r[   c          	      K   s,   ddl m} ||ft|||||d|S )Nr   rU   )rX   r   r[   r   r   )r^   rV   r   )	r   r   r   r   r   rX   r[   re   Zms_snapshot_downloadr   r   r   rV   ,  s   	z_MsKernelApi.snapshot_download)path_in_reporX   c                K   sz   ddl m} ddlm} | j|t||dd}g }|D ]}	|	ddkr&q|	dp/|	d	}
|||
d
d d q|S )Nr   )
RepoFolderr   F)rX   root	recursiveTypetreer   Name )ra   oidZlast_commit)huggingface_hub.hf_apir   r   r   Zget_model_filesr   ry   r>   )r   r   r   rX   re   r   r   entriesfoldersentryra   r   r   r   list_repo_tree?  s   z_MsKernelApi.list_repo_treer   c                K   s"   ddl m} | j||t|dS )Nr   r   r   )r   r   file_existsr   )r   r   filenamerX   re   r   r   r   r   r   T  s   
z_MsKernelApi.file_existsc                    sZ   ddl m  ddlm} | |\}}t fdd|pg D  fdd|p'g D g dS )Nr   
GitRefInfor   c                        g | ]} |d | |dqS )zrefs/heads/r   refZtarget_commitr   r   nr   r   r   r   `      z/_MsKernelApi.list_repo_refs.<locals>.<listcomp>c                    r   )z
refs/tags/r   r   r   r   r   r   r   d  r   )branchestagsZconverts)r   r   r   r   Zget_model_branches_and_tagsr   )r   r   re   r   r   r   r   r   r   list_repo_refsY  s   

z_MsKernelApi.list_repo_refsc                 O   s   ddl m} |d)Nr   )EntryNotFoundErrorz2kernel-status.toml lookup is skipped on ModelScope)Zhuggingface_hub.errorsr   )r   r   re   r   r   r   r   hf_hub_downloadj  s   z_MsKernelApi.hf_hub_download)	r=   r   r   __doc__rV   r   r   r   r   r   r   r   r   r   '  s    r   c                  c   sD    ddl m}  t| drdV  dS t  z	dV  W t  dS t  w )zApply `_patch_kernels` for the duration of the `with` block, unless an
    outer patch (e.g. `patch_hub()`) is already in effect.
    r   r   r   N)r   r   rA   r   r   r   r   r   r   _kernels_patch_scopes  s   
r   c                    s    fdd}  |_ |_|S )a  Return a wrapper around `kernels.<attr_name>` that scopes the ModelScope
    patch on `kernels.utils._get_hf_api` to the call itself, so
    `from kernels import <attr_name>` stays on HuggingFace unless the user
    explicitly calls `patch_hub()` / `patch_context()`.
    c                     sF   dd l }t  t| | i |W  d    S 1 sw   Y  d S )Nr   )r   r   r/   )r   re   r   	attr_namer   r   _wrapped  s   $z(_wrap_kernels_callable.<locals>._wrapped)r=   r   )r   r   r   r   r   _wrap_kernels_callable  s   r   c                     sp  dd l } ddl m} ddlm} ddlm} ddlm} |  d d d ddtdtd	tt d
tt dt	tt
d f f
 fdd}d d d d d d dddtdtdtt d	tt d
tt dt	ttd f dt	ttd f dt	t
td f dt
f fdd}d@dt	t
td f dtfdd}d dddtdt	tt
d f dt
ddfdd}|d d d d dd ddtd t	ttf d!tt d"tt d#tt dt	tt
d f d
tt d$tt	tt tf  fd%d&}	dd'lm}
 |d |
d d d(d)t	ttttf d!tdtdt	tt
d f d
tt d"tt d#tt fd*d+}|d d d |
d,dtd-tt d"td#tt dt	tt
d f d	tt d
tt dt	ttt f fd.d/}	 	 	dAd0t	ttf d	tt dtt d1t
fd2d3}dd4l m} t|jd5st|jj|j_d6d7 |j_|jj|j_t||j|j_t|d8s| jj|_ || _|| j_t|d9s|j!|_"t|||_!|j!| _!|j!| j_!t|d:s|j#|_$t|||_#|j#| _#|j#| j_#t|d;sdd<l%m&} |j'|_(t|||_'|j'| _'|j'| j_'|j'|_'t|d=s|j)|_*t|	||_)|j)| _)|j)| j_)t|d>s|j+|_,t|||_+|j+| _+|j+| j_+|j+|_+t|d?s6|j-|_.t|||_-|j-| _-|j-| j_-dd<l%m&} |j-|_-d S d S )BNr   hf_api)r   )future_compatible)
get_logger)	repo_typerX   r   r   r   r   rX   r   c                   sR   |dur	  d ddlm} | }|| |du s|dkr!d}|j|||dS )z!Patch huggingface_hub.file_existsNz[The passed in repo_type will not be used in modelscope. Now only model repo can be queried.r   r   rY   rZ   r   )warningr   r   r   r   )r   r   r   r   rX   r   r   r   loggerr   r   _file_exists  s   

z _patch_hub.<locals>._file_existsF)rW   r   rX   r   	local_dirr   r[   rW   r   r   r[   c                   s   t |	dkr d |dv sJ d| d|dv r"ddlm}
 nddlm}
 dd	lm} | }|| |d
u s>|dkr@d}|
| |rKtj	
||n|||||dS )z%Patch huggingface_hub.hf_hub_downloadr   zThe passed in library_name,library_version,user_agent,force_download,proxiesetag_timeout,headers,endpoint will not be used in modelscope.)Nrs   datasetz
repo_type=z is not supported in ModelScope)Nrs   model_file_downloaddataset_file_downloadr   NrY   rZ   )	file_pathr   r   r[   rX   )lenr   Zmodelscope.hub.file_downloadr   r  r^   r   r   r`   ra   rc   )r   r   rW   r   rX   r   r   r   r[   re   file_downloadr   r   r   r   r   _file_download  s2   


z"_patch_hub.<locals>._file_downloadreturnc                 S   s<   ddl m} ddl m} | }|| d| d pdiS )Nr   )ModelScopeConfigr   r   unknown)r   r  r   r   Zget_user_info)r   r   r  r   r   r   r   r   _whoami  s
   
z_patch_hub.<locals>._whoami)r   privater
  RepoUrlc          
      [   sP   ddl m} | }|rdnd}|j|f||d|}ddlm}	 |	|d|dS )	af  
        Create a new repository on the hub.

        Args:
            repo_id: The ID of the repository to create.
            token: The authentication token to use.
            private: Whether the repository should be private.
            **kwargs: Additional arguments.

        Returns:
            RepoUrl: The URL of the created repository.
        r   r   r
  public)r   
visibility)r  rs   )urlr   r   )r   r   r   modelscope.utils.repo_utilsr  )
r   r   r   r
  re   r   r   r  repo_urlr  r   r   r   r     s   z_patch_hub.<locals>.create_reporZ   )r   r   commit_descriptionr   rX   r   folder_pathr   r   r  r   c             	   [   s^   ddl m}
 |d u s|dkrd}|
|||||||d ddlm} |t d| d||d d	S )
Nr   _push_files_to_hubrY   rZ   )path_or_fileobjr   r   r   r  rX   r   )r   z/models/z/files)Z
commit_urlr   r  r   )r   r  r  r   r   )r   r   r  r   r   r  r   rX   r   re   r  r   r   r   r   upload_folder  s&   z!_patch_hub.<locals>.upload_folder)DEFAULT_REPOSITORY_REVISION)r   rX   r   r  r  c          
      [   s8   |d u s|dkr
d}ddl m}	 |	||||||| d S )NrY   rZ   r   r  )r   r  )
r   r  r   r   r   rX   r   r  re   r  r   r   r   upload_file  s   
z_patch_hub.<locals>.upload_file)r  r   r   rX   
operationsc             	   [   sn   ddl m}	 |	 }
tdd |D rtd|d u s|dkr d}dd |D }|
j|||||||p2d	d
 d S )Nr   r   c                 S   s   g | ]}d |j jvqS )Add)r   r=   r   opr   r   r   r   =  s    z5_patch_hub.<locals>.create_commit.<locals>.<listcomp>z<ModelScope create_commit only support Add operation for now.rY   rZ   c                 S   s   g | ]}|j qS r   )r  r  r   r   r   r   B  s    rs   )r   r  r   r  r   rX   r   )r   r   r.   
ValueErrorr  )r   r   r  r   r  r   r   rX   re   r   r   	all_filesr   r   r   create_commit.  s$   
z!_patch_hub.<locals>.create_commitrepo_id_or_pathignore_metadata_errorsc                 S   s   ddl m} | }|| tj|r|}n+|dks|d u r+ddlm} ||d}n|dkr;ddlm}	 |	|d}nt	d| t
|d	}
| |
 |d
}t|jdsZg |j_|W  d    S 1 sfw   Y  d S )Nr   r   rs   r   z	README.mdr   r   z5repo_type should be `model` or `dataset`, but now is r)r!  r   )r   r   r   r`   ra   rb   r^   r   r  r  openreadrA   datar   )rR   r   r   r   r!  r   r   r  r   r  fZ	repo_cardr   r   r   loadL  s,   
$z_patch_hub.<locals>.loadrepocard_validate_originc                  _   s   d S r   r   )r   re   r   r   r   r   n  s    z_patch_hub.<locals>.<lambda>_hf_hub_download_origin_file_exists_origin_whoami_origin_create_repo_originhub_upload_folder_origin_upload_file_origin_create_commit_originr   )NNF)/huggingface_hubr   r   r   r   r^   r   r   r   r   r   r   r   r
   Zmodelscope.utils.constantr  bytesr   r	   r   r   r   r)  rA   RepoCardvalidater*  r'  _load_originr   r  r   r+  r   r,  whoamir-  rO   r0  r   r.  r  r1  r  r2  r  r3  )r4  r   r   r   r   r   r  r	  r   r  r  r  r  r'  r)  r0  r   r   r   
_patch_hub  sj  
	&


	
!		 








r:  c                  C   s  dd l } ddl m} ddl m} t|jdr"|jj|j_t|jd t|jdr4|jj|j_	t|jd t|drL|j
| j_|j
| _|j
| j_t|d t|drc|j|_|j| _|j| j_t|d t|drz|j|_|j| _|j| j_t|d t|d	rdd
lm} |j|_|j| _|j| j_|j|_t|d	 t|dr|j|_|j| _|j| j_t|d t|dr|j|_|j| _|j| j_|j|_t|d t|dr|j|_|j| _|j| j_dd
lm} |j|_t|d d S d S )Nr   r   r(  r*  r8  r+  r,  r-  r.  r/  r1  r2  r3  )r4  r   r)  rA   r6  r*  r7  r   r8  r'  r+  r  r   r,  r   r-  r9  rO   r0  r.  r   r1  r  r2  r  r3  r  )r4  r   r)  r0  r   r   r   _unpatch_hub  sd   




















r;  c                   C   s   t   t  tt  d S r   )r:  r   r   rG   r   r   r   r   	patch_hub  s   r<  c                   C   s   t t  t  t  d S r   )r   rG   r   r;  r   r   r   r   unpatch_hub  s   

r=  c                   c   s    t   d V  t  d S r   )r<  r=  r   r   r   r   patch_context  s   
r>  r   )F),r   r6   r   r`   r   r9   Zasyncior   	functoolsr   pathlibr   typesr   r   typingr   r   r	   r
   r   r   Zmodelscope.hub.constantsr   r  r   r   r\   rG   rT   r   r   r   r   r   r   r   r   r   r:  r;  r<  r=  r>  r   r   r   r   <module>   sF    
h
  D&L
  <