
^V                 @   s  d  d l  Z  d  d l m Z d  d l Z d  d l Z d  d l m 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 Z d  d l Z d  d l Z d  d l Z y d  d l Z Wn e k
 rd  d l Z Yn Xd  d l Z d d l m Z d d l m Z m Z m Z m Z m  Z  m! Z! m" Z" m# Z# m$ Z$ m% Z% m& Z& m' Z' m( Z) m* Z* m+ Z+ m, Z, m- Z- m. Z. m/ Z/ m0 Z0 m1 Z1 e
 j2 e3  Z4 d Z5 e j6 e5  Z7 d Z8 d	 e8 d
 Z9 e8 d Z: d Z; d e; d e: d e5 d e; d e: d Z< d Z= d e< d e= d e< d Z> e9 d e5 e9 d Z? d e? d Z@ d e8 d e@ d e> d ZA e j6 eA  ZB d e; d e: d
 ZC e j6 eC  ZD d d    ZE d! d"   ZF d# d$   ZG d% d&   ZH d d d' d(  ZI d) d*   ZJ d+ d,   ZK d- d.   ZL e jM d/ d0    ZN e jM d1 d2    ZO e jM d3 d4 d5   ZP Gd6 d7   d7 eQ  ZR d8 d9   ZS Gd: d;   d; eQ  ZT d< d=   ZU Gd> d?   d? eQ  ZV e j6 d@ e jW  ZX dA dB   ZY d dC dD  ZZ dE dF   Z[ dG dH   Z\ dI dJ   Z] dK dL   Z^ dM dN   Z_ e j6 dO e j`  Za e j6 dP  Zb d dQ dR  Zc e j6 dS  Zd dT dU   Ze dV dW   Zf dX dY   Zg dZ Zh d[ d\   Zi d] d^   Zj Gd_ d`   d` eQ  Zk Gda db   db eQ  Zl Gdc dd   dd eQ  Zm d Zn d dl dm dn  Zo do dp   Zp d Zq Gdw dx   dx eQ  Zr e j6 dy  Zs e j6 dz  Zt e j6 d{  Zu d| d}   Z d~ d   Zv Gd d   d e$ jw  Zw Gd d   d e)  Z( Gd d   d e( e'  Zx e jy d d  Zz ez d k r&Gd d   d e$ j{  Z{ Gd d   d e$ j|  Z| n  Gd d   d e% j}  Z} Gd d   d e% j~  Z~ Gd d   d e% j  Z d d   Z Gd d   d eQ  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e*  Z Gd d   d eQ  Z d S)    N)deque)iglob   )DistlibException)string_types	text_typeshutil	raw_inputStringIOcache_from_sourceurlopenurljoinhttplib	xmlrpclib	splittypeHTTPHandlerHTTPSHandlerBaseConfiguratorvalid_ident	ContainerconfigparserURLErrormatch_hostnameCertificateErrorZipFilez\s*,\s*z
(\w|[.-])+z(\*|:(\*|\w+):|)z\*?z([<>=!~]=)|[<>](z)?\s*(z)(z)\s*(z))*z(from\s+(?P<diref>.*))z\(\s*(?P<c1>|z)\s*\)|(?P<c2>z\s*)z)*z\[\s*(?P<ex>z)?\s*\]z(?P<dn>z	\s*)?(\s*z)?$z(?P<op>z)\s*(?P<vn>c                s^  d d     d  } t  j |   } | rZ| j   } | d } | d pN | d } | d sd d  } n d  } | d j   } | s d  } d } | d } nk | d d	 k r d
 | } n  t j |  }	   f d d   |	 D } d | d j d d   | D  f } | d sd  }
 n t j | d  }
 t	 d | d | d |
 d | d |  d |  } n  | S)Nc             S   s   |  j    } | d | d f S)Nopvn)	groupdict)md r#   7/tmp/pip-build-9m6vxulb/pip/pip/_vendor/distlib/util.pyget_constraintV   s    z)parse_requirement.<locals>.get_constraintdnc1c2diref r   z<>!=z~=c                s   g  |  ] }   |   q Sr#   r#   ).0r!   )r%   r#   r$   
<listcomp>n   s   	 z%parse_requirement.<locals>.<listcomp>z%s (%s)z, c             S   s   g  |  ] } d  |  q S)z%s %sr#   )r+   conr#   r#   r$   r,   o   s   	 exnameconstraintsextrasrequirementsourceurl)
REQUIREMENT_REmatchr    stripRELOP_IDENT_REfinditerjoinCOMMA_REsplitr   )sresultr!   r"   r/   consr4   constrrsiteratorr1   r#   )r%   r$   parse_requirementT   s4    

	&
	rC   c             C   s   d d   } i  } x | D] \ } } } t  j j |  |  } x t |  D] } t  j j | |  }	 x t |	  D]v }
 | |  |
  } | d k r | j | d  qr | | |
  } | j t  j j d  j d  } | d | | | <qr WqJ Wq W| S)z%Find destinations for resources filesc             S   sb   |  j  t j j d  }  | j  t j j d  } | j |   sE t  | t |   d   j d  S)N/)replaceospathsep
startswithAssertionErrorlenlstrip)baserG   r#   r#   r$   get_rel_path|   s    z)get_resources_dests.<locals>.get_rel_pathNrD   )rF   rG   r:   r   poprE   rH   rstrip)resources_rootrulesrN   destinationsrM   suffixdestprefixabs_baseabs_globabs_pathresource_filerel_pathrel_destr#   r#   r$   get_resources_destsy   s    !r]   c              C   s:   t  t d  r d }  n t j t t d t j  k }  |  S)Nreal_prefixTbase_prefix)hasattrsysrV   getattr)r>   r#   r#   r$   in_venv   s    	rc   c               C   s   t  j j t j  S)N)rF   rG   normcasera   
executabler#   r#   r#   r$   get_executable   s    
rf   c             C   s~   |  } xq t  |  } |  } | r1 | r1 | } n  | r	 | d j   } | | k rW Pn  | rv d | | |  f } qv q	 q	 W| S)Nr   z	%c: %s
%s)r	   lower)promptallowed_charserror_promptdefaultpr=   cr#   r#   r$   proceed   s    	rn   c             C   sV   t  | t  r | j   } n  i  } x+ | D]# } | |  k r+ |  | | | <q+ q+ W| S)N)
isinstancer   r<   )r"   keysr>   keyr#   r#   r$   extract_by_key   s    rr   c             C   s  t  j d d k r+ t j d  |   }  n  |  j   } t |  }  y t j |   } | d d d } xo | j   D]a \ } } xR | j   D]D \ } } d | | f } t	 |  }	 |	 d  k	 s t
  |	 | | <q Wqt W| SWn" t k
 r|  j d d  Yn Xd d	   }
 t j   } y |
 | |   WnG t j k
 ru|  j   t j |  } t |  }  |
 | |   Yn Xi  } xz | j   D]l } i  | | <} xU | j |  D]D \ } } d | | f } t	 |  }	 |	 d  k	 st
  |	 | | <qWqW| S)
Nr      zutf-8
extensionszpython.exportsexportsz%s = %sc             S   s0   t  |  d  r |  j |  n |  j |  d  S)N	read_file)r`   rv   readfp)cpstreamr#   r#   r$   read_stream   s    z!read_exports.<locals>.read_stream)ra   version_infocodecs	getreaderreadr
   jsonloaditemsget_export_entryrJ   	Exceptionseekr   ConfigParserMissingSectionHeaderErrorclosetextwrapdedentsections)ry   datajdatar>   groupentrieskvr=   entryrz   rx   rq   r/   valuer#   r#   r$   read_exports   sD    
r   c             C   s   t  j d d k r+ t j d  |  } n  t j   } x |  j   D] \ } } | j |  x | j   D]u } | j	 d  k r | j
 } n d | j
 | j	 f } | j r d | d j | j  f } n  | j | | j |  qj WqD W| j |  d  S)Nr   rs   zutf-8z%s:%sz%s [%s]z, )ra   r{   r|   	getwriterr   r   r   add_sectionvaluesrT   rV   flagsr:   setr/   write)ru   ry   rx   r   r   r   r=   r#   r#   r$   write_exports   s    	r   c              c   s*   t  j   }  z	 |  VWd  t j |   Xd  S)N)tempfilemkdtempr   rmtree)tdr#   r#   r$   tempdir  s    	r   c             c   s7   t  j   } z t  j |   d  VWd  t  j |  Xd  S)N)rF   getcwdchdir)r"   cwdr#   r#   r$   r     s
    	r      c             c   s7   t  j   } z t  j |   d  VWd  t  j |  Xd  S)N)socketgetdefaulttimeoutsetdefaulttimeout)secondsctor#   r#   r$   socket_timeout  s
    	r   c               @   s+   e  Z d  Z d d   Z d d d  Z d S)cached_propertyc             C   s   | |  _  d  S)N)func)selfr   r#   r#   r$   __init__#  s    zcached_property.__init__Nc             C   s<   | d  k r |  S|  j  |  } t j | |  j  j |  | S)N)r   object__setattr____name__)r   objclsr   r#   r#   r$   __get__(  s
    zcached_property.__get__)r   
__module____qualname__r   r   r#   r#   r#   r$   r   "  s   r   c             C   s   t  j d k r |  S|  s |  S|  d d k r@ t d |    n  |  d d k rc t d |    n  |  j d  } x# t  j | k r | j t  j  qu W| s t  j St  j j |   S)a  Return 'pathname' as a name that will work on the native filesystem.

    The path is split on '/' and put back together again using the current
    directory separator.  Needed because filenames in the setup script are
    always supplied in Unix style, and have to be converted to the local
    convention before we can actually use them in the filesystem.  Raises
    ValueError on non-Unix-ish systems if 'pathname' either starts or
    ends with a slash.
    rD   r   zpath '%s' cannot be absoluter   zpath '%s' cannot end with '/')rF   rH   
ValueErrorr<   curdirremoverG   r:   )pathnamepathsr#   r#   r$   convert_path0  s    
r   c               @   s   e  Z d  Z d d d  Z d d   Z d 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 d d   Z d d d d d  Z d d   Z d d   Z d  d!   Z d" d#   Z d S)$FileOperatorFc             C   s#   | |  _  t   |  _ |  j   d  S)N)dry_runr   ensured_init_record)r   r   r#   r#   r$   r   L  s    	zFileOperator.__init__c             C   s%   d |  _  t   |  _ t   |  _ d  S)NF)recordr   files_writtendirs_created)r   r#   r#   r$   r   Q  s    	zFileOperator._init_recordc             C   s    |  j  r |  j j |  n  d  S)N)r   r   add)r   rG   r#   r#   r$   record_as_writtenV  s    	zFileOperator.record_as_writtenc             C   si   t  j j |  s1 t d t  j j |    n  t  j j |  sG d St  j |  j t  j |  j k S)a  Tell if the target is newer than the source.

        Returns true if 'source' exists and is more recently modified than
        'target', or if 'source' exists and 'target' doesn't.

        Returns false if both exist and 'target' is the same age or younger
        than 'source'. Raise PackagingFileError if 'source' does not exist.

        Note that this test is not very accurate: files created in the same
        second will have the same "age".
        zfile '%r' does not existT)rF   rG   existsr   abspathstatst_mtime)r   r3   targetr#   r#   r$   newerZ  s    zFileOperator.newerTc             C   s   |  j  t j j |   t j d | |  |  j s d } | r t j j |  r` d | } q t j j |  r t j j	 |  r d | } q n  | r t
 | d   n  t j | |  n  |  j |  d S)z8Copy a file respecting dry-run and force flags.
        zCopying %s to %sNz%s is a symlinkz%s is a non-regular filez which would be overwritten)
ensure_dirrF   rG   dirnameloggerinfor   islinkr   isfiler   r   copyfiler   )r   infileoutfilecheckmsgr#   r#   r$   	copy_filen  s    	%zFileOperator.copy_fileNc          
   C   s   t  j j |  s t  |  j t  j j |   t j d | |  |  j s | d  k rl t	 | d  } n t
 j	 | d d | } z t j | |  Wd  | j   Xn  |  j |  d  S)NzCopying stream %s to %swbwencoding)rF   rG   isdirrJ   r   r   r   r   r   openr|   r   copyfileobjr   r   )r   instreamr   r   	outstreamr#   r#   r$   copy_stream  s    	zFileOperator.copy_streamc          	   C   s[   |  j  t j j |   |  j sJ t | d   } | j |  Wd  QXn  |  j |  d  S)Nr   )r   rF   rG   r   r   r   r   r   )r   rG   r   fr#   r#   r$   write_binary_file  s
    	zFileOperator.write_binary_filec          
   C   sd   |  j  t j j |   |  j sS t | d   } | j | j |   Wd  QXn  |  j |  d  S)Nr   )	r   rF   rG   r   r   r   r   encoder   )r   rG   r   r   r   r#   r#   r$   write_text_file  s
    	zFileOperator.write_text_filec             C   s   t  j d k s- t  j d k r t  j d k r xj | D]_ } |  j rV t j d |  q4 t  j |  j | B| @} t j d | |  t  j | |  q4 Wn  d  S)Nposixjavazchanging mode of %szchanging mode of %s to %o)	rF   r/   _namer   r   r   r   st_modechmod)r   bitsmaskfilesr   moder#   r#   r$   set_mode  s    -	zFileOperator.set_modec             C   s   |  j  d d |  S)Nim  i  )r   )r=   r   r#   r#   r$   <lambda>  s    zFileOperator.<lambda>c             C   s   t  j j |  } | |  j k r t  j j |  r |  j j |  t  j j |  \ } } |  j |  t j	 d |  |  j
 s t  j |  n  |  j r |  j j |  q n  d  S)NzCreating %s)rF   rG   r   r   r   r   r<   r   r   r   r   mkdirr   r   )r   rG   r"   r   r#   r#   r$   r     s    "		zFileOperator.ensure_dirc             C   s   t  | |  } t j d | |  |  j s | sD |  j | |  r | sS d  } q | j |  sh t  | t |  d   } n  t j	 | | | d  n  |  j
 |  | S)NzByte-compiling %s to %sT)r   r   r   r   r   rI   rJ   rK   
py_compilecompiler   )r   rG   optimizeforcerV   dpathdiagpathr#   r#   r$   byte_compile  s    		zFileOperator.byte_compilec             C   s  t  j j |  rt  j j |  r t  j j |  r t j d |  |  j s` t j	 |  n  |  j
 r| |  j k r |  j j |  q qqt  j j |  r d } n d } t j d | |  |  j s t  j |  n  |  j
 r| |  j k r|  j j |  qqn  d  S)NzRemoving directory tree at %slinkfilezRemoving %s %s)rF   rG   r   r   r   r   debugr   r   r   r   r   r   r   )r   rG   r=   r#   r#   r$   ensure_removed  s"    %					zFileOperator.ensure_removedc             C   sj   d } x] | se t  j j |  r: t  j | t  j  } Pn  t  j j |  } | | k r\ Pn  | } q	 W| S)NF)rF   rG   r   accessW_OKr   )r   rG   r>   parentr#   r#   r$   is_writable  s    	
zFileOperator.is_writablec             C   s/   |  j  s t  |  j |  j f } |  j   | S)zV
        Commit recorded changes, turn off recording, return
        changes.
        )r   rJ   r   r   r   )r   r>   r#   r#   r$   commit  s    
zFileOperator.commitc             C   s   |  j  s x9 t |  j  D]( } t j j |  r t j |  q q Wt |  j d d } xq | D]f } t j	 |  } | r | d g k s t
  t j j | | d  } t j |  n  t j |  qa Wn  |  j   d  S)NreverseT__pycache__r   )r   listr   rF   rG   r   r   sortedr   listdirrJ   r:   rmdirr   )r   r   dirsr"   flistsdr#   r#   r$   rollback  s    	zFileOperator.rollback)r   r   r   r   r   r   r   r   r   r   r   r   set_executable_moder   r   r   r   r   r
  r#   r#   r#   r$   r   K  s    
r   c             C   s   |  t  j k r t  j |  } n t |   } | d  k r@ | } nG | j d  } t | | j d   } x | D] } t | |  } qn W| S)N.r   )ra   modules
__import__r<   rb   rO   )module_namedotted_pathmodr>   partsrl   r#   r#   r$   resolve  s    	r  c               @   sO   e  Z d  Z d d   Z e d d    Z d d   Z d d   Z e j	 Z	 d	 S)
ExportEntryc             C   s(   | |  _  | |  _ | |  _ | |  _ d  S)N)r/   rV   rT   r   )r   r/   rV   rT   r   r#   r#   r$   r     s    			zExportEntry.__init__c             C   s   t  |  j |  j  S)N)r  rV   rT   )r   r#   r#   r$   r     s    zExportEntry.valuec             C   s    d |  j  |  j |  j |  j f S)Nz<ExportEntry %s = %s:%s %s>)r/   rV   rT   r   )r   r#   r#   r$   __repr__  s    zExportEntry.__repr__c             C   sd   t  | t  s d } nH |  j | j k o] |  j | j k o] |  j | j k o] |  j | j k } | S)NF)ro   r  r/   rV   rT   r   )r   otherr>   r#   r#   r$   __eq__  s    	zExportEntry.__eq__N)
r   r   r   r   r   r   r  r  r   __hash__r#   r#   r#   r$   r    s
   
r  z(?P<name>(\w|[-.])+)
                      \s*=\s*(?P<callable>(\w+)([:\.]\w+)*)
                      \s*(\[\s*(?P<flags>\w+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])?
                      c       
      C   sG  t  j |   } | sI d  } d |  k s3 d |  k rCt d |    qCn | j   } | d } | d } | j d  } | d k r | d  } } n4 | d k r t d |    n  | j d  \ } } | d	 }	 |	 d  k rd |  k s d |  k r	t d |    n  g  }	 n d
 d   |	 j d  D }	 t | | | |	  } | S)N[]zInvalid specification %rr/   callable:r   r   r   c             S   s   g  |  ] } | j     q Sr#   )r7   )r+   r   r#   r#   r$   r,   L  s   	 z$get_export_entry.<locals>.<listcomp>,)ENTRY_REsearchr   r    countr<   r  )
specificationr!   r>   r"   r/   rG   colonsrV   rT   r   r#   r#   r$   r   2  s2    


	r   c             C   s  |  d k r d }  n  t  j d k rH d t  j k rH t  j j d  } n t  j j d  } t  j j |  r t  j | t  j  } | s t	 j
 d |  q nH y t  j |  d } Wn. t k
 r t	 j
 d	 | d
 d d } Yn X| s
t j   } t	 j
 d |  n  t  j j | |   S)a  
    Return the default base location for distlib caches. If the directory does
    not exist, it is created. Use the suffix provided for the base directory,
    and default to '.distlib' if it isn't provided.

    On Windows, if LOCALAPPDATA is defined in the environment, then it is
    assumed to be a directory, and will be the parent directory of the result.
    On POSIX, and on Windows if LOCALAPPDATA is not defined, the user's home
    directory - using os.expanduser('~') - will be the parent directory of
    the result.

    The result is just the directory '.distlib' in the parent directory as
    determined above, or with the name specified with ``suffix``.
    Nz.distlibntLOCALAPPDATAz$localappdata~z(Directory exists but is not writable: %sTzUnable to create %sexc_infoFz#Default location unusable, using %s)rF   r/   environrG   
expandvars
expanduserr   r   r   r   warningmakedirsOSErrorr   r   r:   )rT   r>   usabler#   r#   r$   get_cache_baseQ  s&    	
r.  c             C   s`   t  j j t  j j |    \ } } | r? | j d d  } n  | j t  j d  } | | d S)a  
    Convert an absolute path to a directory name for use in a cache.

    The algorithm used is:

    #. On Windows, any ``':'`` in the drive is replaced with ``'---'``.
    #. Any occurrence of ``os.sep`` is replaced with ``'--'``.
    #. ``'.cache'`` is appended.
    r  z---z--z.cache)rF   rG   
splitdriver   rE   rH   )rG   r"   rl   r#   r#   r$   path_to_cache_dirz  s
    
$r0  c             C   s   |  j  d  s |  d S|  S)NrD   )endswith)r=   r#   r#   r$   ensure_slash  s    r2  c             C   sk   d  } } d |  k r^ |  j  d d  \ } }  d | k rC | } q^ | j  d d  \ } } n  | | |  f S)N@r   r  )r<   )netlocusernamepasswordrV   r#   r#   r$   parse_credentials  s    
	r7  c              C   s    t  j d  }  t  j |   |  S)N   )rF   umask)r>   r#   r#   r$   get_process_umask  s    r:  c             C   sX   d } d  } x3 t  |   D]% \ } } t | t  s d } Pq q W| d  k	 sT t  | S)NTF)	enumeratero   r   rJ   )seqr>   ir=   r#   r#   r$   is_string_sequence  s    r>  z3([a-z0-9_]+([.-][a-z_][a-z0-9_]*)*)-([a-z0-9_.+-]+)z-py(\d\.?\d?)c             C   s  d } d } t  j |   } | rI | j d  } |  d | j    }  n  | r t |   t |  d k r t j t j |  d |   } | r | j   } |  d |  |  | d d  | f } q n  | d k rt	 j |   } | r| j d  | j d  | f } qn  | S)zw
    Extract name, version, python version from a filename (no extension)

    Return name, version, pyver or None
    Nr   z\brs   )
PYTHON_VERSIONr  r   startrK   rer6   escapeendPROJECT_NAME_AND_VERSION)filenameproject_namer>   pyverr!   nr#   r#   r$   split_filename  s     "-'rI  z-(?P<name>[\w .-]+)\s*\(\s*(?P<ver>[^\s)]+)\)$c             C   sR   t  j |   } | s( t d |    n  | j   } | d j   j   | d f S)z
    A utility method used to get name and version from a string.

    From e.g. a Provides-Dist value.

    :param p: A value in a form 'foo (1.0)'
    :return: The name and version as a tuple.
    z$Ill-formed name/version string: '%s'r/   ver)NAME_VERSION_REr6   r   r    r7   rg   )rl   r!   r"   r#   r#   r$   parse_name_and_version  s
    	rL  c             C   s  t    } t  |  p g   }  t  | p' g   } d |  k rS |  j d  | | O} n  x |  D] } | d k r| | j |  qZ | j d  r | d d   } | | k r t j d |  n  | | k r| j |  qqZ | | k r t j d |  n  | j |  qZ W| S)N*-r   zundeclared extra: %s)r   r   r   rI   r   r*  )	requested	availabler>   runwantedr#   r#   r$   
get_extras  s&    	rS  c             C   s   i  } ye t  |   } | j   } | j d  d k rF t j d  n$ t j d  |  } t j |  } Wn8 t	 k
 r } z t j
 d |  |  WYd  d  } ~ Xn X| S)NzContent-Typezapplication/jsonz$Unexpected response for JSON requestzutf-8z&Failed to get external data for %s: %s)r   r   getr   r   r|   r}   r   r   r   	exception)r4   r>   respheadersreaderer#   r#   r$   _get_external_data  s    &rZ  z'https://www.red-dove.com/pypi/projects/c             C   s9   d |  d j    |  f } t t |  } t |  } | S)Nz%s/%s/project.jsonr   )upperr   _external_data_base_urlrZ  )r/   r4   r>   r#   r#   r$   get_project_data  s    r]  c             C   s6   d |  d j    |  | f } t t |  } t |  S)Nz%s/%s/package-%s.jsonr   )r[  r   r\  rZ  )r/   versionr4   r#   r#   r$   get_package_data  s    r_  c               @   s:   e  Z d  Z d Z d d   Z d d   Z d d   Z d S)	Cachez
    A class implementing a cache for resources that need to live in the file system
    e.g. shared libraries. This class was moved from resources to here because it
    could be used by other modules, e.g. the wheel module.
    c             C   sv   t  j j |  s" t  j |  n  t  j |  j d @d k rQ t j d |  n  t  j j t  j j	 |   |  _
 d S)zu
        Initialise an instance.

        :param base: The base directory where the cache should be located.
        ?   r   zDirectory '%s' is not privateN)rF   rG   r   r+  r   r   r   r*  r   normpathrM   )r   rM   r#   r#   r$   r     s
    zCache.__init__c             C   s
   t  |  S)zN
        Converts a resource prefix to a directory name in the cache.
        )r0  )r   rV   r#   r#   r$   prefix_to_dir)  s    zCache.prefix_to_dirc             C   s   g  } x t  j |  j  D] } t  j j |  j |  } yZ t  j j |  s^ t  j j |  rn t  j |  n" t  j j |  r t	 j
 |  n  Wq t k
 r | j |  Yq Xq W| S)z"
        Clear the cache.
        )rF   r  rM   rG   r:   r   r   r   r   r   r   r   append)r   not_removedfnr#   r#   r$   clear/  s    $zCache.clearN)r   r   r   __doc__r   rc  rg  r#   r#   r#   r$   r`    s   r`  c               @   sU   e  Z d  Z d Z d d   Z d d d  Z d d   Z d	 d
   Z d d   Z d S)
EventMixinz1
    A very simple publish/subscribe system.
    c             C   s   i  |  _  d  S)N)_subscribers)r   r#   r#   r$   r   D  s    zEventMixin.__init__Tc             C   s\   |  j  } | | k r+ t | g  | | <n- | | } | rK | j |  n | j |  d S)a`  
        Add a subscriber for an event.

        :param event: The name of an event.
        :param subscriber: The subscriber to be added (and called when the
                           event is published).
        :param append: Whether to append or prepend the subscriber to an
                       existing subscriber list for the event.
        N)rj  r   rd  
appendleft)r   event
subscriberrd  subssqr#   r#   r$   r   G  s    
	
zEventMixin.addc             C   s=   |  j  } | | k r( t d |   n  | | j |  d S)z
        Remove a subscriber for an event.

        :param event: The name of an event.
        :param subscriber: The subscriber to be removed.
        zNo subscribers: %rN)rj  r   r   )r   rl  rm  rn  r#   r#   r$   r   [  s    	zEventMixin.removec             C   s   t  |  j j | f    S)z
        Return an iterator for the subscribers for an event.
        :param event: The event to return subscribers for.
        )iterrj  rT  )r   rl  r#   r#   r$   get_subscribersg  s    zEventMixin.get_subscribersc             O   s   g  } xb |  j  |  D]Q } y | | | |  } Wn% t k
 rY t j d  d } Yn X| j |  q Wt j d | | | |  | S)a^  
        Publish a event and return a list of values returned by its
        subscribers.

        :param event: The event to publish.
        :param args: The positional arguments to pass to the event's
                     subscribers.
        :param kwargs: The keyword arguments to pass to the event's
                       subscribers.
        z"Exception during event publicationNz/publish %s: args = %s, kwargs = %s, result = %s)rq  r   r   rU  rd  r   )r   rl  argskwargsr>   rm  r   r#   r#   r$   publishn  s    	zEventMixin.publishN)	r   r   r   rh  r   r   r   rq  rt  r#   r#   r#   r$   ri  @  s   ri  c               @   s   e  Z d  Z d d   Z d d   Z d d d  Z d d	   Z d
 d   Z d d   Z d d   Z	 e
 d d    Z e
 d d    Z d S)	Sequencerc             C   s"   i  |  _  i  |  _ t   |  _ d  S)N)_preds_succsr   _nodes)r   r#   r#   r$   r     s    		zSequencer.__init__c             C   s   |  j  j |  d  S)N)rx  r   )r   noder#   r#   r$   add_node  s    zSequencer.add_nodeFc             C   s  | |  j  k r" |  j  j |  n  | r	x3 t |  j j | f    D] } |  j | |  qD Wx3 t |  j j | f    D] } |  j | |  qz Wx6 t |  j j    D] \ } } | s |  j | =q q Wx9 t |  j j    D] \ } } | s |  j | =q q Wn  d  S)N)rx  r   r   rv  rT  rw  r  r   )r   ry  edgesrl   r=   r   r   r#   r#   r$   remove_node  s    """"zSequencer.remove_nodec             C   sT   | | k s t   |  j j | t    j |  |  j j | t    j |  d  S)N)rJ   rv  
setdefaultr   r   rw  )r   predsuccr#   r#   r$   r     s    zSequencer.addc             C   s   | | k s t   y |  j | } |  j | } Wn" t k
 rT t d |   Yn Xy | j |  | j |  Wn( t k
 r t d | | f   Yn Xd  S)Nz%r not a successor of anythingz%r not a successor of %r)rJ   rv  rw  KeyErrorr   r   )r   r~  r  predssuccsr#   r#   r$   r     s    zSequencer.removec             C   s+   | |  j  k p* | |  j k p* | |  j k S)N)rv  rw  rx  )r   stepr#   r#   r$   is_step  s    zSequencer.is_stepc             C   s   |  j  |  s" t d |   n  g  } g  } t   } | j |  x | r | j d  } | | k r | | k r | j |  | j |  q qG | j |  | j |  |  j j | f   } | j	 |  qG Wt
 |  S)NzUnknown: %rr   )r  r   r   rd  rO   r   r   rv  rT  extendreversed)r   finalr>   todoseenr  r  r#   r#   r$   	get_steps  s"    		zSequencer.get_stepsc                s|   d g  g   i   i   g   |  j            f d d    x'   D] } |  k rU  |  qU qU W S)Nr   c                s9   d  |  < d  |  < d d 7< j  |   y   |  } Wn t k
 r_ g  } Yn Xxl | D]d } |  k r  |  t  |   |   |  <qg |  k rg t  |   |   |  <qg qg W |   |  k r5g  } x-  j   } | j  |  | |  k r Pq q Wt |  }  j  |  n  d  S)Nr   r   )rd  r   minrO   tuple)ry  
successors	successorconnected_component	component)graphindexindex_counterlowlinksr>   stackstrongconnectr#   r$   r    s.    
" z3Sequencer.strong_connections.<locals>.strongconnect)rw  )r   ry  r#   )r  r  r  r  r>   r  r  r$   strong_connections  s    		$"zSequencer.strong_connectionsc             C   s   d g } xF |  j  D]; } |  j  | } x% | D] } | j d | | f  q- Wq Wx" |  j D] } | j d |  q\ W| j d  d j |  S)Nzdigraph G {z  %s -> %s;z  %s;}
)rv  rd  rx  r:   )r   r>   r  r  r~  ry  r#   r#   r$   dot  s    	zSequencer.dotN)r   r   r   r   rz  r|  r   r   r  r  propertyr  r  r#   r#   r#   r$   ru    s   3ru  .tar.gz.tar.bz2.tar.zip.tgz.tbz.whlTc       
   
      s     f d d   } t  j j      t     d  } | d  k r |  j d  r] d } q |  j d  r{ d } d	 } q |  j d  r d } d } q |  j d  r d } d } q t d |    n  z| d k rt |  d  } | r]| j   } x | D] } | |  qWq]nB t j	 |  |  } | r]| j
   } x | D] } | |  qFWn  | d k rt j d d k  rxA | j   D]0 }	 t |	 j t  s|	 j j d  |	 _ qqWn  | j    Wd  | r| j   n  Xd  S)Nc                s|   t  |  t  s! |  j d  }  n  t j j t j j   |    } | j    se |  t j k rx t	 d |   n  d  S)Nzutf-8zpath outside destination: %r)
ro   r   decoderF   rG   r   r:   rI   rH   r   )rG   rl   )dest_dirplenr#   r$   
check_path  s
    !#zunarchive.<locals>.check_path.zip.whlzip.tar.gz.tgztgzzr:gz.tar.bz2.tbztbzzr:bz2z.tartarrQ  zUnknown format for %rr   rs   zutf-8)r  r  )r  r  )r  r  )rF   rG   r   rK   r1  r   r   namelisttarfiler   getnamesra   r{   
getmembersro   r/   r   r  
extractallr   )
archive_filenamer  formatr   r  archiver   namesr/   tarinfor#   )r  r  r$   	unarchive  sH    				r  c             C   s   t  j   } t |   } t | d   } x{ t j |   D]j \ } } } xX | D]P } t j j | |  } | | d  }	 t j j |	 |  }
 | j | |
  qP Wq: WWd QX| S)z*zip a directory tree into a BytesIO objectr   N)	ioBytesIOrK   r   rF   walkrG   r:   r   )	directoryr>   dlenzfrootr  r   r/   fullrelrU   r#   r#   r$   zip_dirL  s    r  r*   KMGTPc               @   s   e  Z d  Z d Z d d d d  Z d d   Z d d	   Z d
 d   Z d d   Z e	 d d    Z
 e	 d d    Z d d   Z e	 d d    Z e	 d d    Z d S)ProgressUNKNOWNr   d   c             C   sV   | d  k s | | k s t   | |  _ |  _ | |  _ d  |  _ d |  _ d |  _ d  S)Nr   F)rJ   r  curmaxstartedelapseddone)r   minvalmaxvalr#   r#   r$   r   c  s    			zProgress.__init__c             C   s}   |  j  | k s t  |  j d  k s9 | |  j k s9 t  | |  _ t j   } |  j d  k ri | |  _ n | |  j |  _ d  S)N)r  rJ   r  r  timer  r  )r   curvalnowr#   r#   r$   updatek  s    $	zProgress.updatec             C   s*   | d k s t   |  j |  j |  d  S)Nr   )rJ   r  r  )r   incrr#   r#   r$   	incrementu  s    zProgress.incrementc             C   s   |  j  |  j  |  S)N)r  r  )r   r#   r#   r$   r@  y  s    zProgress.startc             C   s/   |  j  d  k	 r" |  j |  j   n  d |  _ d  S)NT)r  r  r  )r   r#   r#   r$   stop}  s    zProgress.stopc             C   s   |  j  d  k r |  j S|  j  S)N)r  unknown)r   r#   r#   r$   maximum  s    zProgress.maximumc             C   sZ   |  j  r d } nD |  j d  k r* d } n, d |  j |  j |  j |  j } d | } | S)Nz100 %z ?? %g      Y@z%3d %%)r  r  r  r  )r   r>   r   r#   r#   r$   
percentage  s    			"
zProgress.percentagec             C   sU   | d k r |  j  d  k s- |  j |  j k r6 d } n t j d t j |   } | S)Nr   z??:??:??z%H:%M:%S)r  r  r  r  strftimegmtime)r   durationr>   r#   r#   r$   format_duration  s    -	zProgress.format_durationc             C   s   |  j  r d } |  j } n d } |  j d  k r9 d } ne |  j d k sZ |  j |  j k rc d } n; t |  j |  j  } | |  j |  j } | d |  j } d | |  j |  f S)NDonezETA r   r   z%s: %sr   )r  r  r  r  r  floatr  )r   rV   tr#   r#   r$   ETA  s    		!	zProgress.ETAc             C   sh   |  j  d k r d } n |  j |  j |  j  } x( t D]  } | d k  rL Pn  | d } q6 Wd | | f S)Nr   g        i  g     @@z%d %sB/s)r  r  r  UNITS)r   r>   unitr#   r#   r$   speed  s    	zProgress.speedN)r   r   r   r  r   r  r  r@  r  r  r  r  r  r  r  r#   r#   r#   r$   r  `  s   
	r  z\{([^}]*)\}z[^/\\,{]\*\*|\*\*[^/\\,}]z^[^{]*\}|\{[^}]*$c             C   sZ   t  j |   r( d } t | |    n  t j |   rP d } t | |    n  t |   S)zAExtended globbing function that supports ** and {opt1,opt2,opt3}.z7invalid glob %r: recursive glob "**" must be used alonez2invalid glob %r: mismatching set marker '{' or '}')_CHECK_RECURSIVE_GLOBr  r   _CHECK_MISMATCH_SET_iglob)	path_globr   r#   r#   r$   r     s    r   c             c   s  t  j |  d  } t |  d k r t |  d k sB t |   | \ } } } x3| j d  D]4 } x+ t d j | | | f   D] } | Vq Wqa Wn d |  k r x t |   D] } | Vq Wn |  j d d  \ } } | d k r d } n  | d k r	d } n | j d  } | j d	  } x] t j	 |  D]L \ } } }	 t j
 j |  } x( t t j
 j | |   D] }
 |
 VqtWq7Wd  S)
Nr   rs   r  r*   z**r  rM  rD   \)	RICH_GLOBr<   rK   rJ   r  r:   	std_iglobrL   rF   r  rG   rb  )r  rich_path_globrV   r   rT   itemrG   radicaldirr   rf  r#   r#   r$   r    s*    %		"r  c               @   s(   e  Z d  Z d Z d Z d d   Z d S)HTTPSConnectionNTc             C   s  t  j |  j |  j f |  j  } t |  d d  rI | |  _ |  j   n  t t	 d  s |  j
 rm t	 j } n	 t	 j } t	 j | |  j |  j d | d t	 j d |  j
 |  _ n t	 j t	 j  } | j t	 j O_ |  j r | j |  j |  j  n  i  } |  j
 rHt	 j | _ | j d |  j
  t t	 d d  rH|  j | d	 <qHn  | j | |  |  _ |  j
 r|  j ry0 t |  j j   |  j  t j d
 |  j  Wqt k
 r|  j j t  j  |  j j     YqXn  d  S)N_tunnel_hostF
SSLContext	cert_reqsssl_versionca_certscafileHAS_SNIserver_hostnamezHost verified: %s) r   create_connectionhostporttimeoutrb   sock_tunnelr`   sslr  CERT_REQUIRED	CERT_NONEwrap_socketkey_file	cert_filePROTOCOL_SSLv23r  optionsOP_NO_SSLv2load_cert_chainverify_modeload_verify_locationscheck_domainr   getpeercertr   r   r   shutdown	SHUT_RDWRr   )r   r  r  contextrs  r#   r#   r$   connect  s>    !						zHTTPSConnection.connect)r   r   r   r  r  r  r#   r#   r#   r$   r    s   r  c               @   s7   e  Z d  Z d d d  Z d d   Z d d   Z d S)	r   Tc             C   s#   t  j |   | |  _ | |  _ d  S)N)BaseHTTPSHandlerr   r  r  )r   r  r  r#   r#   r$   r     s    	zHTTPSHandler.__init__c             O   s7   t  | |   } |  j r3 |  j | _ |  j | _ n  | S)a  
        This is called to create a connection instance. Normally you'd
        pass a connection class to do_open, but it doesn't actually check for
        a class, and just expects a callable. As long as we behave just as a
        constructor would have, we should be OK. If it ever changes so that
        we *must* pass a class, we'll create an UnsafeHTTPSConnection class
        which just sets check_domain to False in the class definition, and
        choose which one to pass to do_open.
        )r  r  r  )r   rr  rs  r>   r#   r#   r$   _conn_maker  s
    
	zHTTPSHandler._conn_makerc             C   sq   y |  j  |  j |  SWnS t k
 rl } z3 d t | j  k rW t d | j   n   WYd  d  } ~ Xn Xd  S)Nzcertificate verify failedz*Unable to verify server certificate for %s)do_openr  r   strreasonr   r  )r   reqrY  r#   r#   r$   
https_open.  s    zHTTPSHandler.https_openN)r   r   r   r   r  r  r#   r#   r#   r$   r     s   r   c               @   s   e  Z d  Z d d   Z d S)HTTPSOnlyHandlerc             C   s   t  d |   d  S)NzAUnexpected HTTP request on what should be a secure connection: %s)r   )r   r  r#   r#   r$   	http_openB  s    zHTTPSOnlyHandler.http_openN)r   r   r   r  r#   r#   r#   r$   r  A  s   r        c               @   s"   e  Z d  Z d d d d  Z d S)HTTPr*   Nc             K   s5   | d k r d  } n  |  j  |  j | | |   d  S)Nr   )_setup_connection_class)r   r  r   rs  r#   r#   r$   r   N  s    	zHTTP.__init__)r   r   r   r   r#   r#   r#   r$   r!  M  s   r!  c               @   s"   e  Z d  Z d d d d  Z d S)HTTPSr*   Nc             K   s5   | d k r d  } n  |  j  |  j | | |   d  S)Nr   )r"  r#  )r   r  r   rs  r#   r#   r$   r   U  s    	zHTTPS.__init__)r   r   r   r   r#   r#   r#   r$   r$  T  s   r$  c               @   s+   e  Z d  Z d d d  Z d d   Z d S)	Transportr   c             C   s    | |  _  t j j |  |  d  S)N)r  r   r%  r   )r   r  use_datetimer#   r#   r$   r   \  s    	zTransport.__init__c             C   s   |  j  |  \ } } } t d k r< t | d |  j } nN |  j sY | |  j d k r} | |  _ | t j |  f |  _ n  |  j d } | S)Nr  r   r  r   r   )r  r   )get_host_info	_ver_infor!  r  _connection_extra_headersr   HTTPConnection)r   r  hehx509r>   r#   r#   r$   make_connection`  s    	zTransport.make_connectionN)r   r   r   r   r/  r#   r#   r#   r$   r%  [  s   r%  c               @   s+   e  Z d  Z d d d  Z d d   Z d S)SafeTransportr   c             C   s    | |  _  t j j |  |  d  S)N)r  r   r0  r   )r   r  r&  r#   r#   r$   r   l  s    	zSafeTransport.__init__c             C   s   |  j  |  \ } } } | s' i  } n  |  j | d <t d k rU t | d  |  } nT |  j sr | |  j d k r | |  _ | t j | d  |  f |  _ n  |  j d } | S)Nr  r  r   r   r   )r  r   )r'  r  r(  r$  r)  r*  r   r  )r   r  r,  r-  rs  r>   r#   r#   r$   r/  p  s    		zSafeTransport.make_connectionN)r   r   r   r   r/  r#   r#   r#   r$   r0  k  s   r0  c               @   s   e  Z d  Z d d   Z d S)ServerProxyc       	      K   s   | j  d d   |  _ } | d  k	 r t |  \ } } | j d d  } | d k r^ t } n t } | | d | | d <} | |  _ n  t j j	 |  | |  d  S)Nr  r&  r   https	transport)
rO   r  r   rT  r0  r%  r3  r   r1  r   )	r   urirs  r  scheme_r&  tclsr  r#   r#   r$   r     s    	zServerProxy.__init__N)r   r   r   r   r#   r#   r#   r$   r1    s   r1  c             K   s:   t  j d d k  r  | d 7} n
 d | d <t |  | |  S)Nr   rs   br*   newline)ra   r{   r   )rf  r   rs  r#   r#   r$   	_csv_open  s    
r:  c               @   sU   e  Z d  Z i e d  d 6e d  d 6e d  d 6Z d d   Z d	 d
   Z d S)CSVBaser  	delimiter"	quotecharr  lineterminatorc             C   s   |  S)Nr#   )r   r#   r#   r$   	__enter__  s    zCSVBase.__enter__c             G   s   |  j  j   d  S)N)ry   r   )r   r&  r#   r#   r$   __exit__  s    zCSVBase.__exit__N)r   r   r   r  defaultsr@  rA  r#   r#   r#   r$   r;    s   r;  c               @   s:   e  Z d  Z d d   Z d d   Z d d   Z e Z d S)	CSVReaderc             K   s   d | k rM | d } t  j d d k rA t j d  |  } n  | |  _ n t | d d  |  _ t j |  j |  j  |  _ d  S)Nry   r   rs   zutf-8rG   rQ  )	ra   r{   r|   r}   ry   r:  csvrX  rB  )r   rs  ry   r#   r#   r$   r     s    
zCSVReader.__init__c             C   s   |  S)Nr#   )r   r#   r#   r$   __iter__  s    zCSVReader.__iter__c             C   sk   t  |  j  } t j d d k  rg xB t |  D]1 \ } } t | t  s/ | j d  | | <q/ q/ Wn  | S)Nr   rs   zutf-8)nextrX  ra   r{   r;  ro   r   r  )r   r>   r=  r  r#   r#   r$   rF    s    zCSVReader.nextN)r   r   r   r   rE  rF  __next__r#   r#   r#   r$   rC    s   rC  c               @   s(   e  Z d  Z d d   Z d d   Z d S)	CSVWriterc             K   s1   t  | d  |  _ t j |  j |  j  |  _ d  S)Nr   )r:  ry   rD  writerrB  )r   rf  rs  r#   r#   r$   r     s    zCSVWriter.__init__c             C   su   t  j d d k  ra g  } x< | D]4 } t | t  rG | j d  } n  | j |  q  W| } n  |  j j |  d  S)Nr   rs   zutf-8)ra   r{   ro   r   r   rd  rI  writerow)r   rowrQ  r  r#   r#   r$   rJ    s    	zCSVWriter.writerowN)r   r   r   r   rJ  r#   r#   r#   r$   rH    s   rH  c                   sb   e  Z d  Z e e j  Z d e d <d   f d d  Z d d   Z d d	   Z d
 d   Z	   S)Configuratorinc_convertincNc                s/   t  t |   j |  | p% t j   |  _ d  S)N)superrL  r   rF   r   rM   )r   configrM   )	__class__r#   r$   r     s    zConfigurator.__init__c       
         s    f d d      j  d  } t |  sB  j |  } n    j  d d   }   j  d f   } | r t  f d d   | D  } n     f d d     D } t |  } | | |   } | rx3 | j   D]" \ } }	 t | |  |	   q Wn  | S)	Nc                s   t  |  t t f  r= t |     f d d   |  D  } nj t  |  t  r d |  k rj  j |   } q i  } x4 |  D] }   |  |  | | <qw Wn  j |   } | S)Nc                s   g  |  ] }   |   q Sr#   r#   )r+   r=  )convertr#   r$   r,     s   	 zBConfigurator.configure_custom.<locals>.convert.<locals>.<listcomp>z())ro   r  r  typedictconfigure_customrR  )or>   r   )rR  r   r#   r$   rR    s    (z.Configurator.configure_custom.<locals>.convertz()r  z[]c                s   g  |  ] }   |   q Sr#   r#   )r+   rV  )rR  r#   r$   r,     s   	 z1Configurator.configure_custom.<locals>.<listcomp>c                s2   g  |  ]( } t  |  r |    |  f  q Sr#   )r   )r+   r   )rP  rR  r#   r$   r,     s   	 )rO   r  r  r  rT  r   setattr)
r   rP  rm   propsrr  r   rs  r>   rH  r   r#   )rP  rR  r   r$   rU    s    "zConfigurator.configure_customc             C   sI   |  j  | } t | t  rE d | k rE |  j |  |  j  | <} n  | S)Nz())rP  ro   rT  rU  )r   rq   r>   r#   r#   r$   __getitem__  s    zConfigurator.__getitem__c          	   C   sa   t  j j |  s- t  j j |  j |  } n  t j | d d d  } t j |  } Wd QX| S)z*Default converter for the inc:// protocol.rQ  r   zutf-8N)	rF   rG   isabsr:   rM   r|   r   r   r   )r   r   r   r>   r#   r#   r$   rM    s
    zConfigurator.inc_convert)
r   r   r   rT  r   value_convertersr   rU  rY  rM  r#   r#   )rQ  r$   rL    s   
rL  c               @   s:   e  Z d  Z d d d d  Z d d   Z d d   Z d S)	SubprocessMixinFNc             C   s   | |  _  | |  _ d  S)N)verboseprogress)r   r]  r^  r#   r#   r$   r     s    	zSubprocessMixin.__init__c             C   s   |  j  } |  j } xu | j   } | s+ Pn  | d k	 rG | | |  q | s` t j j d  n t j j | j d   t j j   q W| j   d S)z
        Read lines from a subprocess' output stream and either pass to a progress
        callable (if specified) or write progress information to sys.stderr.
        Nr  zutf-8)	r^  r]  readlinera   stderrr   r  flushr   )r   ry   r  r^  r]  r=   r#   r#   r$   rX    s    		zSubprocessMixin.readerc             K   s   t  j | d t  j d t  j | } t j d |  j d | j d f  } | j   t j d |  j d | j d f  } | j   | j	   | j
   | j
   |  j d  k	 r |  j d d  n |  j r t j j d  n  | S)Nstdoutr`  r   rr  zdone.mainzdone.
)
subprocessPopenPIPE	threadingThreadrX  rb  r@  r`  waitr:   r^  r]  ra   r   )r   cmdrs  rl   t1t2r#   r#   r$   run_command+  s    $
$



	zSubprocessMixin.run_command)r   r   r   r   rX  rm  r#   r#   r#   r$   r\    s   r\  )r  r  r  r  r  r  r  )r*   r  r  r  r  r  )r  r   )r|   collectionsr   
contextlibrD  globr   r  r  r   loggingrF   r   rA  r   r   r  rd  ra   r  r   r   rg  ImportErrordummy_threadingr  r*   r   compatr   r   r	   r
   r   r   r   r   r   r   r   r   r  r   r   r   r   r   r   r   r   	getLoggerr   r   COMMAr   r;   IDENTEXTRA_IDENTVERSPECRELOPBARE_CONSTRAINTS
DIRECT_REFCONSTRAINTS
EXTRA_LISTEXTRASREQUIREMENTr5   RELOP_IDENTr8   rC   r]   rc   rf   rn   rr   r   r   contextmanagerr   r   r   r   r   r   r   r  r  VERBOSEr  r   r.  r0  r2  r7  r:  r>  IrD  r?  rI  rK  rL  rS  rZ  r\  r]  r_  r`  ri  ru  ARCHIVE_EXTENSIONSr  r  r  r  r  r  r  r  r  r  r{   r(  r!  r$  r%  r0  r1  r:  r;  rC  rH  rL  r\  r#   r#   r#   r$   <module>   s   
.%
	/
	)
	,H 6]!*)	: