a
    -=ic                  
   @   s8  U d 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 ejrtdd	lmZ ed
ZeedZdZdd eD Zdd edD ZG dd dejZG dd deZG dd deZG dd deZe eiZejej e! eje"e!f f e#d< dlej$e%e"f ej$e%e"f e"dddZ&ej$ej'e%e%f ej(ej)e%e%f  f e%e*ej+ej,ej)e%e%f gej-f  ej.e% dd d!Z/dme%e%e%d"d#d$Z0dne%ej+e% e*ed&d'd(Z1doe%e%ej$e%e"f ej$e%e"f ej,e"ge%f d,d-d.Z2e2 Z3e2d/d0d1Z4e"e%d2d3d4Z5dpej$e%e"f e%e%ej$e%e"f ej$e%e"f e%d5d6d7Z6dqe%e%e%e%e%d8d9d:Z7ej)e%e%e%e%e%f e%d;d<d=Z8drej$e%e"f e%e%e%e%d?d@dAZ9dsej$e%e"f e%e%e%dBdCdDZ:dte%e%e%dEdFdGZ;d<dHd edID Z=e>ej)e%e!f dJdKdLZ?e@dMe? duej$e%ej)e%e%e%e%e%f f e%e%e%dNdOdPZAdQZBdvej$e%ej)e%e%e%e%e%f f e%e%e*e%dSdTdUZCdwejDe%e*e%e%ej+ejEdW  dXdYdZd[ZFdxejGe" e%e*e%e"ej+ejEdW  ej+e! dXd]d^d_ZHej(ejD e%e*e%ej.ej)e%e%f  d`dadbZIdyej$ej'e%e%f ej(ej)e%e%f  f e%e*ej+ej,ej)e%e%f gej-f  e%e%dcdddeZJdzej$ej'e%e%f ej(ej)e%e%f  f ej+ejGe%  e%e*ej+ej,ej)e%e%f gej-f  e%ddfdgdhZKd{ej$e%ej)e%e%e%e%e%f f ej$e%ej)e%e%e%e%e%f f e*e%didjdkZLdS )|zFunctions for working with URLs.

Contains implementations of functions from :mod:`urllib.parse` that
handle bytes and strings.
    N   )_check_str_tuple)_decode_idna)_encode_idna)_make_encode_wrapper)_to_str)datastructuresz^[a-zA-Z0-9+-.]+$sK   abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~$!'()*+,;0123456789ABCDEFabcdefc                 C   s8   i | ]0}t D ]&}| | d t| | dqqS )ascii   )
_hexdigitsencodeint).0ab r   ^/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/werkzeug/urls.py
<dictcomp>#   s   r   c                 C   s   g | ]}d |d dqS )%02Xr
   )r   )r   charr   r   r   
<listcomp>(       r      c                   @   s6   e Zd ZU eed< eed< eed< eed< eed< dS )	_URLTupleschemenetlocpathqueryfragmentN)__name__
__module____qualname__str__annotations__r   r   r   r   r   +   s
   
r   c                   @   s  e Zd ZU dZdZeed< eed< eed< eed< eddd	Zej	d d
ddZ
eeje dddZeeje dddZeeje dddZeeje dddZeeje dddZeeje dddZeeje dddZeeje dddZej	ej	dddd Zej	ej	d dd!d"Zedd#d$Zedd%d&Zedd'd(Zd dd)d*Zd dd+d,Zd7eje ejeje eje f d.d/d0Zejeje ef dd1d2Zejeje eje f dd3d4Z ejeje eje f dd5d6Z!d-S )8BaseURLz7Superclass of :py:class:`URL` and :py:class:`BytesURL`.r   _at_colon	_lbracket	_rbracketreturnc                 C   s   |   S N)to_urlselfr   r   r   __str__<   s    zBaseURL.__str__)kwargsr,   c                 K   s   | j f i |S )zReturn an URL with the same values, except for those parameters
        given new values by whichever keyword arguments are specified.)_replace)r0   r2   r   r   r   replace?   s    zBaseURL.replacec                 C   s   |   d S )zThe host part of the URL if available, otherwise `None`.  The
        host is either the hostname or the IP address mentioned in the
        URL.  It will not contain the port.
        r   )_split_hostr/   r   r   r   hostD   s    zBaseURL.hostc                 C   sP   | j }|durDt|trDzt|}W n tyB   |dd}Y n0 t|ddS )a   Works exactly like :attr:`host` but will return a result that
        is restricted to ASCII.  If it finds a netloc that is not ASCII
        it will attempt to idna decode it.  This is useful for socket
        operations when the URL might include internationalized characters.
        Nr
   ignore)r6   
isinstancer$   r   UnicodeErrorr   r   r0   rvr   r   r   
ascii_hostL   s    zBaseURL.ascii_hostc              	   C   sR   z6t t|  d }d|  kr*dkr4n n|W S W n ttfyL   Y n0 dS )z}The port in the URL as an integer if it was present, `None`
        otherwise.  This does not fill in default ports.
        r   r   i  N)r   r   r5   
ValueError	TypeErrorr:   r   r   r   port[   s    
zBaseURL.portc                 C   s   |   d S )zSThe authentication part in the URL if available, `None`
        otherwise.
        r   )_split_netlocr/   r   r   r   authh   s    zBaseURL.authc                 C   s    |   d }|durt|S dS )zThe username if it was part of the URL, `None` otherwise.
        This undergoes URL decoding and will always be a string.
        r   N_split_auth_url_unquote_legacyr:   r   r   r   usernameo   s    zBaseURL.usernamec                 C   s   |   d S )zThe username if it was part of the URL, `None` otherwise.
        Unlike :attr:`username` this one is not being decoded.
        r   rC   r/   r   r   r   raw_usernamey   s    zBaseURL.raw_usernamec                 C   s    |   d }|durt|S dS )zThe password if it was part of the URL, `None` otherwise.
        This undergoes URL decoding and will always be a string.
        r   NrB   r:   r   r   r   password   s    zBaseURL.passwordc                 C   s   |   d S )zThe password if it was part of the URL, `None` otherwise.
        Unlike :attr:`password` this one is not being decoded.
        r   rF   r/   r   r   r   raw_password   s    zBaseURL.raw_passwordds.MultiDict[str, str])argsr2   r,   c                 O   s   t | jg|R i |S )zDecodes the query part of the URL.  Ths is a shortcut for
        calling :func:`url_decode` on the query argument.  The arguments and
        keyword arguments are forwarded to :func:`url_decode` unchanged.
        )
url_decoder   r0   rK   r2   r   r   r   decode_query   s    zBaseURL.decode_queryc                 O   s   t t| g|R i |S )zJoins this URL with another one.  This is just a convenience
        function for calling into :meth:`url_join` and then parsing the
        return value again.
        )	url_parseurl_joinrM   r   r   r   join   s    zBaseURL.joinc                 C   s   t | S )zReturns a URL string or bytes depending on the type of the
        information stored.  This is just a convenience function
        for calling :meth:`url_unparse` for this URL.
        )url_unparser/   r   r   r   r.      s    zBaseURL.to_urlc              
   C   s   | j pd}d|v rd| d}| j}|dur:| d| }dtdt| jpLddddt| jp^ddddg}|r| d	| }|S )
z6Encodes the netloc part to an ASCII safe URL as bytes. :[]Nutf-8strictz/:%@)r<   r?   rQ   filter	url_quoterG   rI   r0   r;   r?   rA   r   r   r   encode_netloc   s"    
	zBaseURL.encode_netlocc                 C   s   t | jp
d}d|v r"d| d}| j}|dur>| d| }dtdt| jpPddt| jp^ddg}|r|| d| }|S )z&Decodes the netloc part into a string.rS   rT   rU   rV   Nz/:%@rY   )r   r6   r?   rQ   rZ   rD   rG   rI   r\   r   r   r   decode_netloc   s"    	zBaseURL.decode_netlocc                 C   s   t t| S )a*  Returns a :class:`BytesURL` tuple that holds a URI.  This will
        encode all the information in the URL properly to ASCII using the
        rules a web browser would follow.

        It's usually more interesting to directly call :meth:`iri_to_uri` which
        will return a string.
        )rO   
iri_to_urir/   r   r   r   to_uri_tuple   s    zBaseURL.to_uri_tuplec                 C   s   t t| S )aS  Returns a :class:`URL` tuple that holds a IRI.  This will try
        to decode as much information as possible in the URL without
        losing information similar to how a web browser does it for the
        URL bar.

        It's usually more interesting to directly call :meth:`uri_to_iri` which
        will return a string.
        )rO   
uri_to_irir/   r   r   r   to_iri_tuple   s    	zBaseURL.to_iri_tupleN)
pathformatr,   c                 C   s:  | j dkrdS t| j}| jp d}|du r>tjdkr:d}nd}|dkr|dd dkr|dd	  r|d	d
 dv r|dd	  d|d
d  }|dd
 dv }ddl}||}|r|du r|	d
dd}t|d	kr|\}}n|d }d}n,|dkrddl}||}ntd||dv r2d}||fS )a@  Returns a tuple with the location of the file in the form
        ``(server, location)``.  If the netloc is empty in the URL or
        points to localhost, it's represented as ``None``.

        The `pathformat` by default is autodetection but needs to be set
        when working with URLs of a specific system.  The supported values
        are ``'windows'`` when working with Windows or DOS paths and
        ``'posix'`` when working with posix paths.

        If the URL does not point to a local file, the server and location
        are both represented as ``None``.

        :param pathformat: The expected format of the path component.
                           Currently ``'windows'`` and ``'posix'`` are
                           supported.  Defaults to ``None`` which is
                           autodetect.
        fileNNNntwindowsposixr   /      z|:rT   )z\\\z///r   \rS   zInvalid path format )z	127.0.0.1z::1	localhost)r   url_unquoter   r   osnameisalphantpathnormpathlstripsplitlen	posixpathr>   )r0   rc   r   r6   Zwindows_sharerr   partsrw   r   r   r   get_file_location   s6    



0



zBaseURL.get_file_locationc                 C   s2   | j | jv r(| j| j \}}}||fS d | jfS r-   )r'   r   	partition)r0   rA   _r   r   r   r   r@   $  s    zBaseURL._split_netlocc                 C   s@   |   d }|sdS | j|vr&|d fS || j\}}}||fS )Nr   re   )r@   r(   rz   )r0   rA   rE   r{   rH   r   r   r   rC   *  s    
zBaseURL._split_authc                 C   s   |   d }|sdS || jsL| j|v rD|| j\}}}||fS |d fS || j}|dk rh|d fS |d| }||d d  }|| jr||dd  fS |d fS )Nr   re   r   )r@   
startswithr)   r(   rz   findr*   )r0   r;   r6   r{   r?   idxrestr   r   r   r5   4  s     
zBaseURL._split_host)N)"r!   r"   r#   __doc__	__slots__r$   r%   r1   tAnyr4   propertyOptionalr6   r<   r   r?   rA   rE   rG   rH   rI   rN   rQ   r.   r]   r^   r`   rb   Tuplery   r@   rC   r5   r   r   r   r   r&   3   sN   
		
 >$
r&   c                   @   s8   e Zd ZdZdZdZdZdZdZde	e	d	d
ddZ
dS )URLzRepresents a parsed URL.  This behaves like a regular tuple but
    also has some extra attributes that give further insight into the
    URL.
    r   rY   rT   rU   rV   rW   r4   BytesURLcharseterrorsr,   c              	   C   s:   t | jd|  | j||| j||| j||S )zEncodes the URL to a tuple made out of bytes.  The charset is
        only being used for the path, query and fragment.
        r
   )r   r   r   r]   r   r   r    r0   r   r   r   r   r   r   V  s    
z
URL.encodeN)rW   r4   )r!   r"   r#   r   r   r'   r(   r)   r*   r$   r   r   r   r   r   r   J  s   r   c                   @   sT   e Zd ZdZdZdZdZdZdZe	ddd	Z
edd
dZde	e	ddddZdS )r   z!Represents a parsed URL in bytes.r      @   :   [   ]r+   c                 C   s   |   ddS )NrW   r4   )r.   decoder/   r   r   r   r1   l  s    zBytesURL.__str__c                 C   s   | j S )z&Returns the netloc unchanged as bytes.)r   r/   r   r   r   r]   o  s    zBytesURL.encode_netlocrW   r4   r   r   c              	   C   s:   t | jd|  | j||| j||| j||S )zDecodes the URL to a tuple made out of strings.  The charset is
        only being used for the path, query and fragment.
        r
   )r   r   r   r^   r   r   r    r   r   r   r   r   s  s    
zBytesURL.decodeN)rW   r4   )r!   r"   r#   r   r   r'   r(   r)   r*   r$   r1   bytesr]   r   r   r   r   r   r   c  s   r   _unquote_mapsrS   )stringunsafer,   c                    s   t | tr| d} t  tr( d tt  t| d}tt|d}zt  }W n0 t	y    fddt
 D  }t < Y n0 |D ]N}|d d }||v r|||  ||dd   q|d || qt|S )NrW      %r   c                    s   i | ]\}}| vr||qS r   r   )r   hr   r   r   r   r     s   z%_unquote_to_bytes.<locals>.<dictcomp>rj   %   )r8   r$   r   	frozenset	bytearrayiterru   nextr   KeyError
_hextobyteitemsappendextendr   )r   r   groupsresultZhex_to_bytegroupcoder   r   r   _unquote_to_bytes  s*    





r   )objr   sortkeyr,   c           
      c   s   ddl m} || }|r$t||d}|D ]f\}}|d u r:q(t|tsTt||}n|}t|tsrt||}	n|}	t| dt|	 V  q(d S )Nr   )iter_multi_items)r   =)r   r   sortedr8   r   r$   r   _fast_url_quote_plus)
r   r   r   r   r   iterablekey_strZ	value_str	key_bytesZvalue_bytesr   r   r   _url_encode_impl  s    

r   )valuer   r,   c                 C   s8   zt | dd|dW S  ty2   t | d|d Y S 0 d S )NrW   rX   )r   r   r   latin1)r   r   )rn   r9   )r   r   r   r   r   rD     s    rD   T)urlr   allow_fragmentsr,   c                    s  t |  t| t}|du r" d} d } }}|  d}|dkrtt| d| ddr| |d d }|rt fdd	|D r| d|  | }} | dd
  dkrFt	| }	 dD ]"}
| |
d
}|dkrt
|	|}	q| d
|	 | |	d  }}  d|v r" d|vs> d|v rF d|vrFtd|rn d| v rn|  dd\} } d| v r|  dd\} }|rtnt}|||| ||S )a  Parses a URL from a string into a :class:`URL` tuple.  If the URL
    is lacking a scheme it can be provided as second argument. Otherwise,
    it is ignored.  Optionally fragments can be stripped from the URL
    by setting `allow_fragments` to `False`.

    The inverse of this function is :func:`url_unparse`.

    :param url: the URL to parse.
    :param scheme: the default schema to use if the URL is schemaless.
    :param allow_fragments: if set to `False` a fragment will be removed
                            from the URL.
    NrS   rT   r   r4   )r   r   c                 3   s   | ]}| d vV  qdS )
0123456789Nr   r   csr   r   	<genexpr>  r   zurl_parse.<locals>.<genexpr>rj   //z/?#rU   rV   zInvalid IPv6 URL#?)r   r8   r$   r}   
_scheme_rematchr   anylowerrv   minr=   ru   r   r   )r   r   r   Zis_text_basedr   r   r    ir   delimr   wdelimZresult_typer   r   r   rO     s:    
"

rO   rW   rX   /:)r   r   safer   r,   c                    sv   t  tr | | t |tr,|| |}tt tB tt|   fddtdD ttdfdd}|S )a  Precompile the translation table for a URL encoding function.

    Unlike :func:`url_quote`, the generated function only takes the
    string to quote.

    :param charset: The charset to encode the result with.
    :param errors: How to handle encoding errors.
    :param safe: An optional sequence of safe characters to never encode.
    :param unsafe: An optional sequence of unsafe characters to always encode.
    c                    s(   g | ] }| v rt |n
d |dqS )r   r   )chrr   r   r   r   r     r   z(_make_fast_url_quote.<locals>.<listcomp>r   r   r,   c                    s   d  fdd| D S )NrS   c                    s   g | ]} | qS r   r   r   tabler   r   r     r   z7_make_fast_url_quote.<locals>.quote.<locals>.<listcomp>)rQ   r   r   r   r   quote  s    z#_make_fast_url_quote.<locals>.quote)r8   r$   r   r   r   _always_saferanger   )r   r   r   r   r   r   )r   r   r   _make_fast_url_quote  s    

r    +)r   r   r   c                 C   s   t | ddS )Nr   r   )_fast_quote_plusr4   r   r   r   r   r     s    r   )r   r   r   r   r   r,   c                 C   s   t | tttfst| } t | tr.| ||} t |trD|||}t |trZ|||}tt|tB tt| }t }t| D ]&}||v r|| q|t	|  qt|
|S )aD  URL encode a single string with a given encoding.

    :param s: the string to quote.
    :param charset: the charset to be used.
    :param safe: an optional sequence of safe characters.
    :param unsafe: an optional sequence of unsafe characters.

    .. versionadded:: 0.9.2
       The `unsafe` parameter was added.
    )r8   r$   r   r   r   r   r   r   r   
_bytetohexr   )r   r   r   r   r   r;   r   r   r   r   r[   #  s    


r[   )r   r   r   r   r,   c                 C   s   t | |||d dddS )zURL encode a single string with the given encoding and convert
    whitespace to "+".

    :param s: The string to quote.
    :param charset: The charset to be used.
    :param safe: An optional sequence of safe characters.
    r   r   )r[   r4   )r   r   r   r   r   r   r   url_quote_plusF  s    
r   )
componentsr,   c                 C   s   t |  | \}}}}}t|}|d}|s<|rz||drz|r`|dd |dkr`|d| }|d|pp|d | }n|r||7 }|r||d | }|r||d | }|r||d | }|S )	zThe reverse operation to :meth:`url_parse`.  This accepts arbitrary
    as well as :class:`URL` tuples and returns a URL as a string.

    :param components: the parsed URL as tuple which should be converted
                       into a URL string.
    rS   ri   Nr   r   rT   r   r   )r   r   r|   )r   r   r   r   r   r    r   r   r   r   r   rR   S  s"    rR   r4   )r   r   r   r   r,   c                 C   s"   t | |}|du r|S |||S )af  URL decode a single string with a given encoding.  If the charset
    is set to `None` no decoding is performed and raw bytes are
    returned.

    :param s: the string to unquote.
    :param charset: the charset of the query string.  If set to `None`
        no decoding will take place.
    :param errors: the error handling for the charset decoding.
    N)r   r   )r   r   r   r   r;   r   r   r   rn   r  s    
rn   )r   r   r   r,   c                 C   s0   t | tr| dd} n| dd} t| ||S )a  URL decode a single string with the given `charset` and decode "+" to
    whitespace.

    Per default encoding errors are ignored.  If you want a different behavior
    you can set `errors` to ``'replace'`` or ``'strict'``.

    :param s: The string to unquote.
    :param charset: the charset of the query string.  If set to `None`
        no decoding will take place.
    :param errors: The error handling for the `charset` decoding.
    r   r      +    )r8   r$   r4   rn   )r   r   r   r   r   r   url_unquote_plus  s    
r   )r   r   r,   c                 C   s   t | |ddd} | drP| dd  rP| dd dv rPd	| dd
  } t| }t|j|dd}t|j|dd}t|j	|dd}t
|j| |||fS )a  Sometimes you get an URL by a user that just isn't a real URL because
    it contains unsafe characters like ' ' and so on. This function can fix
    some of the problems in a similar way browsers handle data entered by the
    user:

    >>> url_fix('http://de.wikipedia.org/wiki/Elf (Begriffskl\xe4rung)')
    'http://de.wikipedia.org/wiki/Elf%20(Begriffskl%C3%A4rung)'

    :param s: the string with the URL to fix.
    :param charset: The target charset for the URL if the url was given
        as a string.
    r4   rl   ri   zfile://      
   )z:/z|/zfile:///Nz
/%+$!*'(),r   z:&%=+$!*'(),)r   r4   r|   rq   rO   r[   r   r   r   r    rR   r   r]   )r   r   r   r   qsanchorr   r   r   url_fix  s    *r   c                 C   s   g | ]}|t vrt|qS r   )r   r   r   r   r   r   r     r      )er,   c                 C   s    t | j| j| j }|| jfS )zRUsed in :func:`uri_to_iri` after unquoting to re-quote any
    invalid bytes.
    )_fast_url_quoteobjectstartend)r   outr   r   r   _codec_error_url_quote  s    r   werkzeug.url_quote)urir   r   r,   c                 C   sh   t | trt| } tt| |} t| j||t}t| j||t}t| j	||t}t| j
|  |||fS )a  Convert a URI to an IRI. All valid UTF-8 characters are unquoted,
    leaving all reserved and invalid characters quoted. If the URL has
    a domain, it is decoded from Punycode.

    >>> uri_to_iri("http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF")
    'http://\u2603.net/p\xe5th?q=\xe8ry%DF'

    :param uri: The URI to convert.
    :param charset: The encoding to encode unquoted bytes with.
    :param errors: Error handler to use during ``bytes.encode``. By
        default, invalid bytes are left quoted.

    .. versionchanged:: 0.15
        All reserved and invalid characters remain quoted. Previously,
        only some reserved characters were preserved, and invalid bytes
        were replaced instead of left quoted.

    .. versionadded:: 0.6
    )r8   tuplerR   rO   r   rn   r   _to_iri_unsafer   r    r   r^   )r   r   r   r   r   r    r   r   r   ra     s    
ra   z:/?#[]@!$&'()*+,;=%F)irir   r   safe_conversionr,   c           	      C   s   t | trt| } |rVz,t| }|d}t| dkr@|W S W n tyT   Y n0 tt| ||} t	| j
||t}t	| j||t}t	| j||t}t| j|  |||fS )a  Convert an IRI to a URI. All non-ASCII and unsafe characters are
    quoted. If the URL has a domain, it is encoded to Punycode.

    >>> iri_to_uri('http://\u2603.net/p\xe5th?q=\xe8ry%DF')
    'http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF'

    :param iri: The IRI to convert.
    :param charset: The encoding of the IRI.
    :param errors: Error handler to use during ``bytes.encode``.
    :param safe_conversion: Return the URL unchanged if it only contains
        ASCII characters and no whitespace. See the explanation below.

    There is a general problem with IRI conversion with some protocols
    that are in violation of the URI specification. Consider the
    following two IRIs::

        magnet:?xt=uri:whatever
        itms-services://?action=download-manifest

    After parsing, we don't know if the scheme requires the ``//``,
    which is dropped if empty, but conveys different meanings in the
    final URL if it's present or not. In this case, you can use
    ``safe_conversion``, which will return the URL unchanged if it only
    contains ASCII characters and no whitespace. This can result in a
    URI with unquoted characters if it was not already quoted correctly,
    but preserves the URL's semantics. Werkzeug uses this for the
    ``Location`` header for redirects.

    .. versionchanged:: 0.15
        All reserved characters remain unquoted. Previously, only some
        reserved characters were left unquoted.

    .. versionchanged:: 0.9.6
       The ``safe_conversion`` parameter was added.

    .. versionadded:: 0.6
    r
   r   )r8   r   rR   r   r   rv   ru   r9   rO   r[   r   _to_uri_safer   r    r   r]   )	r   r   r   r   Z
native_iriZ	ascii_irir   r   r    r   r   r   r_     s    +


r_   &zds.MultiDictrJ   )r   r   include_emptyr   	separatorclsr,   c                 C   sv   |du rddl m} |}t| tr<t|ts<||p6d}n"t| tr^t|ts^||pZd}|t| ||||S )aw  Parse a query string and return it as a :class:`MultiDict`.

    :param s: The query string to parse.
    :param charset: Decode bytes to string with this charset. If not
        given, bytes are returned as-is.
    :param include_empty: Include keys with empty values in the dict.
    :param errors: Error handling behavior when decoding bytes.
    :param separator: Separator character between pairs.
    :param cls: Container to hold result instead of :class:`MultiDict`.

    .. versionchanged:: 2.0
        The ``decode_keys`` parameter is deprecated and will be removed
        in Werkzeug 2.1.

    .. versionchanged:: 0.5
        In previous versions ";" and "&" could be used for url decoding.
        Now only "&" is supported. If you want to use ";", a different
        ``separator`` can be provided.

    .. versionchanged:: 0.5
        The ``cls`` parameter was added.
    Nr   	MultiDictr
   )	r   r   r8   r$   r   r   r   _url_decode_implru   )r   r   r   r   r   r   r   r   r   r   rL   3  s    rL      &)streamr   r   r   r   r   limitr,   c                 C   sF   ddl m} || ||}t||||}	|du r>ddlm}
 |
}||	S )a_  Works like :func:`url_decode` but decodes a stream.  The behavior
    of stream and limit follows functions like
    :func:`~werkzeug.wsgi.make_line_iter`.  The generator of pairs is
    directly fed to the `cls` so you can consume the data while it's
    parsed.

    :param stream: a stream with the encoded querystring
    :param charset: the charset of the query string.  If set to `None`
        no decoding will take place.
    :param include_empty: Set to `False` if you don't want empty values to
                          appear in the dict.
    :param errors: the decoding error behavior.
    :param separator: the pair separator to be used, defaults to ``&``
    :param cls: an optional dict class to use.  If this is not specified
                       or `None` the default :class:`MultiDict` is used.
    :param limit: the content length of the URL data.  Not necessary if
                  a limited stream is provided.

    .. versionchanged:: 2.0
        The ``decode_keys`` and ``return_iterator`` parameters are
        deprecated and will be removed in Werkzeug 2.1.

    .. versionadded:: 0.8
    r   )make_chunk_iterNr   )Zwsgir   r   r   r   )r   r   r   r   r   r   r   r   	pair_iterdecoderr   r   r   r   url_decode_stream`  s    !r   )r   r   r   r   r,   c           	      c   sj   | D ]`}|sqt |}|d}||v r8||d\}}n|s>q|}|d}t|||t|||fV  qd S )Nr   r   rS   )r   ru   r   )	r   r   r   r   pairr   equalr   r   r   r   r   r     s    

r   )r   r   r   r   r   r,   c                 C   s   t |d}|t| |||S )a  URL encode a dict/`MultiDict`.  If a value is `None` it will not appear
    in the result string.  Per default only values are encoded into the target
    charset strings.

    :param obj: the object to encode into a query string.
    :param charset: the charset of the query string.
    :param sort: set to `True` if you want parameters to be sorted by `key`.
    :param separator: the separator to be used for the pairs.
    :param key: an optional function to be used for sorting.  For more details
                check out the :func:`sorted` documentation.

    .. versionchanged:: 2.0
        The ``encode_keys`` parameter is deprecated and will be removed
        in Werkzeug 2.1.

    .. versionchanged:: 0.5
        Added the ``sort``, ``key``, and ``separator`` parameters.
    r
   )r   rQ   r   )r   r   r   r   r   r   r   r   
url_encode  s    
r  )r   r   r   r   r   r   r,   c           	      C   sR   t |d}t| |||}|du r$|S t|D ] \}}|rB|| || q,dS )a  Like :meth:`url_encode` but writes the results to a stream
    object.  If the stream is `None` a generator over all encoded
    pairs is returned.

    :param obj: the object to encode into a query string.
    :param stream: a stream to write the encoded object into or `None` if
                   an iterator over the encoded pairs should be returned.  In
                   that case the separator argument is ignored.
    :param charset: the charset of the query string.
    :param sort: set to `True` if you want parameters to be sorted by `key`.
    :param separator: the separator to be used for the pairs.
    :param key: an optional function to be used for sorting.  For more details
                check out the :func:`sorted` documentation.

    .. versionchanged:: 2.0
        The ``encode_keys`` parameter is deprecated and will be removed
        in Werkzeug 2.1.

    .. versionadded:: 0.8
    r
   N)r   r   	enumeratewrite)	r   r   r   r   r   r   genr~   chunkr   r   r   url_encode_stream  s    

r  )baser   r   r,   c                    s  t | trt| } t |tr$t|}t| |f t|  | s@|S |sH| S t| |d\}}}}}t|||\}}	}
}}||kr|S |	rt||	|
||fS |}	|
dd  dkr|
 d}n@|
s| d}|s|}n$| ddd |
 d }|d  dkr d|d<  fdd	|D }d}t|d }||k r||  d
kr||d   d d
fvr||d |d = q.|d7 }q>qq. d d
g}|dd |kr|d= q d|}
t||	|
||fS )a	  Join a base URL and a possibly relative URL to form an absolute
    interpretation of the latter.

    :param base: the base URL for the join operation.
    :param url: the URL to join.
    :param allow_fragments: indicates whether fragments should be allowed.
    )r   Nr   ri   .rS   c                    s   g | ]}| d kr|qS )r
  r   )r   segmentr   r   r   r     r   zurl_join.<locals>.<listcomp>z..rj   )	r8   r   rR   r   r   rO   ru   rv   rQ   )r  r   r   bschemebnetlocbpathbquery	bfragmentr   r   r   r   r    segmentsr   nZunwanted_markerr   r   r   rP     sT    

$
0
rP   )rS   )rS   )NT)rW   rX   r   rS   )rW   rX   r   rS   )rW   rX   rS   )rW   r4   rS   )rW   r4   )rW   )rW   r   )rW   rX   F)rW   Tr4   r   N)rW   Tr4   r   NN)rW   FNr   )NrW   FNr   )T)Mr   codecsro   retypingr   	_internalr   r   r   r   r   TYPE_CHECKINGrS   r   Zdscompiler   r   r   r   r   r   r   r   
NamedTupler   r&   r   r   r   Dict	FrozenSetr   r   r%   Unionr$   r   MappingIterabler   boolr   Callabler   Iteratorr   rD   rO   r   r   r   r   r[   r   rR   rn   r   r   rQ   r   r9   r   register_errorra   r   r_   AnyStrTyperL   IOr   r   r  r  rP   r   r   r   r   <module>   sl  

  , "&  4        $  !    
  #   D     /      /    &      & * 