o
    gs                     @  s0  U d 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	m
Z
 ddl	mZ ddl	mZ ddl	mZ ddl	mZ d	d
lmZ d	dlmZ d	dlmZ d	dlmZ d	dlmZ ejrbd	dlmZ edZ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(d!e)d"< ddd)d*Z*dd4d5Z+ddd7d8Z,	9ddd>d?Z-	@	A	B	#dddFdGZ.e. Z/e.dHdIdJZ0ddKdLZ1	@	A	B	#dddMdNZ2	#dddOdPZ3ddSdTZ4	@	U	#dddWdXZ5	UdddYdZZ6ddd[d\Z7dd`daZ8e9dbe8 ddfdgZ:e;g e!dhdidjR < Z=e:dke=Z>e:dle=dm Z?e:dne=do Z@e:dpe=dq ZA		dddtduZB			dddydzZCdd{d|ZD	@	9	U	}	ddddZE	@	9	U			ddddZFdddZG	@			}ddddZH		@			}ddddZI	9ddddZJ	@ddddZKdS )zFunctions for working with URLs.

Contains implementations of functions from :mod:`urllib.parse` that
handle bytes and strings.
    )annotationsN)quote)unquote)	urlencode)urlsplit)
urlunsplit   )_check_str_tuple)_decode_idna)_make_encode_wrapper)_to_striter_multi_items)datastructuresz^[a-zA-Z0-9+-.]+$zKabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~$!'()*+,;ascii0123456789ABCDEFabcdefc                 C  s8   i | ]}t D ]}| | d t| | dqqS )r      )
_hexdigitsencodeint).0ab r   Z/var/www/html/portale_awareness/portale-venv/lib/python3.10/site-packages/werkzeug/urls.py
<dictcomp>*   s     r   c                 C  s   g | ]}d |d dqS )%02Xr   )r   )r   charr   r   r   
<listcomp>/   s    r      c                   @  s6   e Zd ZU ded< ded< ded< ded< ded< dS )	_URLTuplestrschemenetlocpathqueryfragmentN)__name__
__module____qualname____annotations__r   r   r   r   r!   2   s   
 r!   c                      s>  e Zd ZU dZdZded< ded< ded< ded< d? fddZd@ddZdAddZe	dBddZ
e	dBddZe	dCddZe	dBddZe	dBddZe	dBddZe	dBd d!Ze	dBd"d#ZdDd%d&Zd?d'd(Zd@d)d*Zd@d+d,Zd@d-d.ZdEd/d0ZdEd1d2Z	3dFdGd6d7ZdHd9d:ZdId;d<ZdId=d>Z  ZS )JBaseURLzSuperclass of :py:class:`URL` and :py:class:`BytesURL`.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use the ``urllib.parse`` library instead.
    r   r"   _at_colon	_lbracket	_rbracketargst.Anykwargsreturnc                   s4   t jd| j dtdd t j| g|R i |S )Nz'werkzeug.urls.z\' is deprecated and will be removed in Werkzeug 3.0. Use the 'urllib.parse' library instead.   
stacklevel)warningswarnr(   DeprecationWarningsuper__new__)clsr1   r3   	__class__r   r   r<   G   s   zBaseURL.__new__c                 C  s   |   S N)to_urlselfr   r   r   __str__P   s   zBaseURL.__str__c                 K  s   | j di |S )zReturn an URL with the same values, except for those parameters
        given new values by whichever keyword arguments are specified.Nr   )_replace)rC   r3   r   r   r   replaceS   s   zBaseURL.replace
str | Nonec                 C     |   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_hostrB   r   r   r   hostX   s   zBaseURL.hostc                 C  sH   | j }|dur"t|tr"z|dd}W |S  ty!   Y |S w |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.
        Nidnar   )rJ   
isinstancer"   r   decodeUnicodeErrorrC   rvr   r   r   
ascii_host`   s   zBaseURL.ascii_host
int | Nonec              	   C  sT   zt t|  d }d|  krdkr|W S  W dS W dS  ttfy)   Y dS w )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   rI   
ValueError	TypeErrorrO   r   r   r   porto   s   zBaseURL.portc                 C  rH   )zSThe authentication part in the URL if available, `None`
        otherwise.
        r   )_split_netlocrB   r   r   r   auth|      zBaseURL.authc                 C      |   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_legacyrO   r   r   r   username      zBaseURL.usernamec                 C  rH   )zThe username if it was part of the URL, `None` otherwise.
        Unlike :attr:`username` this one is not being decoded.
        r   r[   rB   r   r   r   raw_username   rX   zBaseURL.raw_usernamec                 C  rY   )zThe password if it was part of the URL, `None` otherwise.
        This undergoes URL decoding and will always be a string.
        r   NrZ   rO   r   r   r   password   r^   zBaseURL.passwordc                 C  rH   )zThe password if it was part of the URL, `None` otherwise.
        Unlike :attr:`password` this one is not being decoded.
        r   r_   rB   r   r   r   raw_password   rX   zBaseURL.raw_passwordds.MultiDict[str, str]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&   rC   r1   r3   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_joinre   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_unparserB   r   r   r   rA      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p&d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/:%@)rQ   rU   ri   filter	url_quoter`   rb   )rC   rP   rU   rW   r   r   r   encode_netloc   s"   
	zBaseURL.encode_netlocc                 C  s   | j pd}t|tr| }t|}d|v rd| d}| j}|dur*| d| }dtdt| j	p3ddt| j
p:ddg}|rI| d| }|S )z&Decodes the netloc part into a string.rk   rl   rm   rn   Nz/:%@rq   )rJ   rL   bytesrM   r
   rU   ri   rr   r\   r`   rb   )rC   rJ   rP   rU   rW   r   r   r   decode_netloc   s(   

	zBaseURL.decode_netlocc                 C     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.
        )rg   
iri_to_urirB   r   r   r   to_uri_tuple   s   zBaseURL.to_uri_tuplec                 C  rw   )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.
        )rg   
uri_to_irirB   r   r   r   to_iri_tuple   s   	zBaseURL.to_iri_tupleN
pathformattuple[str | None, str | None]c                 C  s6  | 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rJ|dd	  rJ|d	d
 dv rJ|dd	  d|d
d  }|dd
 dv }ddl}||}|r{|du r{|	d
dd}t|d	kru|\}}n|d }d}n|dkrddl}||}ntd||dv rd}||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   /r5      z|:rl   )z\\\z///r   \rk   zInvalid path format )z	127.0.0.1z::1	localhost)r#   url_unquoter%   r$   osnameisalphantpathnormpathlstripsplitlen	posixpathrT   )rC   r|   r%   rJ   windows_sharer   partsr   r   r   r   get_file_location   s8   



0

zBaseURL.get_file_locationtuple[str | None, str]c                 C  s2   | j | jv r| j| j \}}}||fS d | jfS r@   )r-   r$   	partition)rC   rW   _r$   r   r   r   rV   =  s   
zBaseURL._split_netlocc                 C  s@   |   d }|s
dS | j|vr|d fS || j\}}}||fS )Nr   r   )rV   r.   r   )rC   rW   r]   r   ra   r   r   r   r[   C  s   
zBaseURL._split_authc                 C  s   |   d }|s
dS || js&| j|v r"|| j\}}}||fS |d fS || j}|dk r4|d fS |d| }||d d  }|| jrP||dd  fS |d fS )Nr   r   r   )rV   
startswithr/   r.   r   findr0   )rC   rP   rJ   r   rU   idxrestr   r   r   rI   M  s    
zBaseURL._split_host)r1   r2   r3   r2   r4   r,   r4   r"   )r3   r2   r4   r,   )r4   rG   )r4   rR   )r1   r2   r3   r2   r4   rc   )r4   r,   r@   )r|   rG   r4   r}   )r4   r   )r4   r}   )r(   r)   r*   __doc__	__slots__r+   r<   rD   rF   propertyrJ   rQ   rU   rW   r]   r`   ra   rb   rf   ri   rA   rt   rv   ry   r{   r   rV   r[   rI   __classcell__r   r   r>   r   r,   :   sL   
 
	
		








>

r,   c                   @  s0   e Zd ZdZdZdZdZdZdZ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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use the ``urllib.parse`` library instead.
    r   rq   rl   rm   rn   ro   rF   charsetr"   errorsr4   BytesURLc              	   C  :   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   rt   r%   r&   r'   rC   r   r   r   r   r   r   r     
z
URL.encodeNro   rF   )r   r"   r   r"   r4   r   )
r(   r)   r*   r   r   r-   r.   r/   r0   r   r   r   r   r   r   c  s    r   c                   @  sD   e Zd ZdZdZdZdZdZdZdd	d
Z	dddZ
ddddZdS )r   zRepresents a parsed URL in bytes.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use the ``urllib.parse`` library instead.
    r      @   :   [   ]r4   r"   c                 C  s   |   ddS )Nro   rF   )rA   rM   rB   r   r   r   rD        zBytesURL.__str__ru   c                 C  s   | j S )z&Returns the netloc unchanged as bytes.)r$   rB   r   r   r   rt     s   zBytesURL.encode_netlocro   rF   r   r   r   c              	   C  r   )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#   rM   rv   r%   r&   r'   r   r   r   r   rM     r   zBytesURL.decodeNr   )r4   ru   r   )r   r"   r   r"   r4   r   )r(   r)   r*   r   r   r-   r.   r/   r0   rD   rt   rM   r   r   r   r   r     s    

r   z&dict[frozenset[int], dict[bytes, int]]_unquote_mapsrk   stringstr | bytesunsafer4   ru   c                   s   t | tr
| d} t  tr d tt  t| d}tt|d}zt  }W n t	yF    fddt
 D  }t < Y nw |D ]'}|d d }||v rf|||  ||dd   qI|d || qIt|S )Nro      %    c                   s   i | ]\}}| vr||qS r   r   )r   hr   r   r   r   r     s    z%_unquote_to_bytes.<locals>.<dictcomp>r5   %   )rL   r"   r   	frozenset	bytearrayiterr   nextr   KeyError
_hextobyteitemsappendextendru   )r   r   groupsresulthex_to_bytegroupcoder   r   r   _unquote_to_bytes  s,   





r   obj1t.Mapping[str, str] | t.Iterable[tuple[str, str]]r   r"   sortboolkey+t.Callable[[tuple[str, str]], t.Any] | Nonet.Iterator[str]c           
      c  s    ddl m} || }|rt||d}|D ]3\}}|d u rqt|ts+t||}n|}t|ts:t||}	n|}	t| dt|	 V  qd S )Nr   r   )r   =)r   r   sortedrL   ru   r"   r   _fast_url_quote_plus)
r   r   r   r   r   iterablekey_str	value_str	key_bytesvalue_bytesr   r   r   _url_encode_impl  s    

r   valuec                 C  s4   z	t | dd|dW S  ty   t | d|d Y S w )Nro   rp   )r   r   r   latin1)r   r   )r   rN   )r   r   r   r   r   r\     s
   r\   Turlr#   rG   allow_fragmentsc                   s  t jdtdd t|  t| t}|du r d} d } }}|  d}|dkrYtt	| d| dd	rY| |d
 d }|rNt
 fdd|D rY| d|  |}} | dd  dkrt| }	 dD ]}
| |
d}|dkr|t|	|}	qk| d|	 | |	d }}  d|v r d|vs d|v r d|vrtd|r d| v r|  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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.urlsplit`` instead.
    zq'werkzeug.urls.url_parse' is deprecated and will be removed in Werkzeug 3.0. Use 'urllib.parse.urlsplit' instead.r5   r6   Nrk   rl   r   rF   )r   r   c                 3  s    | ]	}| d vV  qdS )
0123456789Nr   r   csr   r   	<genexpr>
      zurl_parse.<locals>.<genexpr>///?#rm   rn   zInvalid IPv6 URL#?)r8   r9   r:   r   rL   r"   r   
_scheme_rematchr   anylowerr   minrS   r   r   r   )r   r#   r   is_text_basedr$   r&   r'   ir   delimr   wdelimresult_typer   r   r   rg     s@   
"
rg   ro   rp   /:r   safet.Callable[[bytes], str]c                   sp   t  tr | | t |tr|| |}tt tB tt|   fddtdD 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   ;  s   ( z(_make_fast_url_quote.<locals>.<listcomp>r    r   ru   r4   r"   c                   s   d  fdd| D S )Nrk   c                   s   g | ]} | qS r   r   r   tabler   r   r   >  s    z7_make_fast_url_quote.<locals>.quote.<locals>.<listcomp>)ri   r   r   r   r   r   =  s   z#_make_fast_url_quote.<locals>.quoteNr   ru   r4   r"   )rL   r"   r   r   r   _always_saferange)r   r   r   r   r   r   )r   r   r   _make_fast_url_quote$  s   

r    +)r   r   c                 C  s   t | ddS )Nr   r   )_fast_quote_plusrF   r   r   r   r   r   G  r   r   c                 C  s   t jdtdd t| tttfst| } t| tr| ||} t|tr*|||}t|tr5|||}tt|t	B tt| }t }t| D ]}||v rV|
| qJ|t|  qJt||S )a  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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.quote`` instead.

    .. versionadded:: 0.9.2
       The `unsafe` parameter was added.
    zn'werkzeug.urls.url_quote' is deprecated and will be removed in Werkzeug 3.0. Use 'urllib.parse.quote' instead.r5   r6   )r8   r9   r:   rL   r"   ru   r   r   r   r   r   r   
_bytetohexrM   )r   r   r   r   r   rP   r   r   r   r   rs   K  s(   


rs   c                 C  s,   t jdtdd t| |||d dddS )aO  URL 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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.quote_plus`` instead.
    zx'werkzeug.urls.url_quote_plus' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.quote_plus' instead.r5   r6   r   r   )r8   r9   r:   rs   rF   )r   r   r   r   r   r   r   url_quote_plusx  s   r   
componentstuple[str, str, str, str, str]c                 C  s   t jdtdd t|  | \}}}}}t|}|d}|s&|rE||drE|r8|dd |dkr8|d| }|d|p@|d | }n|rK||7 }|rU||d	 | }|r_||d
 | }|ri||d | }|S )ai  The 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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.urlunsplit`` instead.
    zu'werkzeug.urls.url_unparse' is deprecated and will be removed in Werkzeug 3.0. Use 'urllib.parse.urlunsplit' instead.r5   r6   rk   r   Nr   r   rl   r   r   )r8   r9   r:   r	   r   r   )r   r#   r$   r%   r&   r'   r   r   r   r   r   rj     s,   
rj   rF   r   c                 C  s2   t jdtdd t| |}|du r|S |||S )a  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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.unquote`` instead.
    zr'werkzeug.urls.url_unquote' is deprecated and will be removed in Werkzeug 3.0. Use 'urllib.parse.unquote' instead.r5   r6   N)r8   r9   r:   r   rM   )r   r   r   r   rP   r   r   r   r     s   
r   c                 C  s@   t jdtdd 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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.unquote_plus`` instead.
    z|'werkzeug.urls.url_unquote_plus' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.unquote_plus' instead.r5   r6   r   r      +    )r8   r9   r:   rL   r"   rF   r   )r   r   r   r   r   r   url_unquote_plus  s   
r  c                 C  s   t jdtdd t| |ddd} | dr0| dd	  r0| d	d
 dv r0d| dd  } t| }t|j	|dd}t
|j|dd}t
|j|dd}t|j| |||fS )aF  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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0.
    zJ'werkzeug.urls.url_fix' is deprecated and will be removed in Werkzeug 3.0.r5   r6   rF   r   r   zfile://      
   )z:/z|/zfile:///Nz
/%+$!*'(),r   z:&%=+$!*'(),)r8   r9   r:   r   rF   r   r   rg   rs   r%   r   r&   r'   rj   r#   rt   )r   r   r   r%   qsanchorr   r   r   url_fix  s   *r	  erN   tuple[str, int]c                 C  s$   t | j| j| j dd}|| jfS )zRUsed in :func:`uri_to_iri` after unquoting to re-quote any
    invalid bytes.
    rk   r   )r   objectstartend)r
  outr   r   r   _codec_error_url_quote  s   
r  werkzeug.url_quoter   chars t.Callable[[str, str, str], str]c                   sL   d dd t|D }td| dtj d fdd}d|  |_|S )zCreate a function that unquotes all percent encoded characters except those
    given. This allows working with unquoted characters if possible while not changing
    the meaning of a given part of a URL.
    |c                 s  s    | ]	}t |d V  qdS )r   N)ordr   r   r   r   r   -  r   z%_make_unquote_part.<locals>.<genexpr>z((?:%(?:z))+)r   r"   encodingr   r4   c                   sH   t  | }g }|D ]}|t||| |t|d qd|S )Nrk   )r   r   r   r   r   ri   )r   r  r   r   r  partpatternr   r   _unquote_partial0  s   
z,_make_unquote_part.<locals>._unquote_partial	_unquote_N)r   r"   r  r"   r   r"   r4   r"   )ri   r   recompileIr(   )r   r  choicesr  r   r  r   _make_unquote_part(  s
   
r   !   r      r'   r&   z&=+#r%   r   userz:@/?#uri$str | tuple[str, str, str, str, str]c           	      C  sF  t | trtjdtdd t| } t | tr"tjdtdd |  } |dur/tjdtdd nd}|dur>tjdtdd nd	}t| }t	|j
||}t|j||}t|j||}|jrbt|j}nd
}d|v rnd| d}|jry| d|j }|jrt|j||}|jr| dt|j|| }| d| }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:: 2.3
        Passing a tuple or bytes, and the ``charset`` and ``errors`` parameters, are
        deprecated and will be removed in Werkzeug 3.0.

    .. versionchanged:: 2.3
        Which characters remain quoted is specific to each part of the URL.

    .. 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
    HPassing a tuple is deprecated and will not be supported in Werkzeug 3.0.r5   r6   FPassing bytes is deprecated and will not be supported in Werkzeug 3.0.NJThe 'charset' parameter is deprecated and will be removed in Werkzeug 3.0.ro   IThe 'errors' parameter is deprecated and will be removed in Werkzeug 3.0.r  rk   rl   rm   rn   rq   )rL   tupler8   r9   r:   r   ru   rM   r   _unquote_pathr%   _unquote_queryr&   _unquote_fragmentr'   hostnamer
   rU   r]   _unquote_userra   r#   )	r$  r   r   r   r%   r&   r'   r$   rW   r   r   r   rz   H  sZ   

rz   irisafe_conversionbool | Nonec                 C  s  |durt jdtdd nd}t| tr t jdtdd t| } t| tr2t jdtdd | |} |dur?t jdtdd nd	}|durMt jd
tdd |rkz| d}t	|
 dkr`| W S W n	 tyj   Y nw t| }t|jd||d}t|jd||d}t|jd||d}|jr|jdd}	nd}	d|	v rd|	 d}	|jr|	 d|j }	|jrt|jdd}
|jrt|jdd}|
 d| }
|
 d|	 }	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``.

    .. versionchanged:: 2.3
        Passing a tuple or bytes, and the ``charset`` and ``errors`` parameters, are
        deprecated and will be removed in Werkzeug 3.0.

    .. versionchanged:: 2.3
        Which characters remain unquoted is specific to each part of the URL.

    .. versionchanged:: 2.3
        The ``safe_conversion`` parameter is deprecated and will be removed in Werkzeug
        2.4.

    .. 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
    Nr(  r5   r6   ro   r&  r'  r)  rp   zRThe 'safe_conversion' parameter is deprecated and will be removed in Werkzeug 3.0.r   r   z%!$&'()*+,/:;=@)r   r  r   z%!$&'()*+,/:;=?@z%!#$&'()*+,/:;=?@rK   rk   rl   rm   rn   z%!$&'()*+,;=r   rq   )r8   r9   r:   rL   r*  r   ru   rM   r   r   r   rN   r   r   r%   r&   r'   r.  rU   r]   ra   r#   )r0  r   r   r1  	ascii_irir   r%   r&   r'   r$   rW   pass_quotedr   r   r   rx     s~   $




rx   c                 C  sH   z|  d W n ty   Y t| S w t| dddkr | S t| S )a  The URL scheme ``itms-services://`` must contain the ``//`` even though it does
    not have a host component. There may be other invalid schemes as well. Currently,
    responses will always call ``iri_to_uri`` on the redirect ``Location`` header, which
    removes the ``//``. For now, if the IRI only contains ASCII and does not contain
    spaces, pass it on as-is. In Werkzeug 3.0, this should become a
    ``response.process_location`` flag.

    :meta private:
    r   Nr   )r   rN   r   r   rx   )r0  r   r   r   _invalid_iri_to_uri   s   
r5  &t.AnyStrinclude_empty	separatorr=   type[ds.MultiDict] | Nonerc   c                 C  s   t jdtdd |du rddlm} |}t| tr&t|ts&||p#d}nt| tr7t|ts7|	|p5d}|t
| ||||S )a  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`.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.parse_qs`` instead.

    .. versionchanged:: 2.1
        The ``decode_keys`` parameter was removed.

    .. 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.
    zr'werkzeug.urls.url_decode' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.parse_qs' instead.r5   r6   Nr   	MultiDictr   )r8   r9   r:   r   r<  rL   r"   rM   ru   r   _url_decode_implr   )r   r   r8  r   r9  r=   r<  r   r   r   rd   5  s"    rd      &streamt.IO[bytes]limitrR   c                 C  sV   t jdtdd 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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 2.4. Use ``urllib.parse.parse_qs`` instead.

    .. versionchanged:: 2.1
        The ``decode_keys`` and ``return_iterator`` parameters were removed.

    .. versionadded:: 0.8
    zy'werkzeug.urls.url_decode_stream' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.parse_qs' instead.r5   r6   r   )make_chunk_iterNr;  )r8   r9   r:   wsgirB  r=  r   r<  )r?  r   r8  r   r9  r=   rA  rB  	pair_iterdecoderr<  r   r   r   url_decode_streamk  s   #rF  rD  t.Iterable[t.AnyStr]t.Iterator[tuple[str, str]]c           	      c  sl    | D ]0}|sqt |}|d}||v r||d\}}n	|s q|}|d}t|||t|||fV  qd S )Nr   r   rk   )r   r   r  )	rD  r   r8  r   pairr   equalr   r   r   r   r   r=    s    

r=  Fc                 C  s.   t jdtdd t|d}|t| |||S )aP  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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 2.4. Use ``urllib.parse.urlencode`` instead.

    .. versionchanged:: 2.1
        The ``encode_keys`` parameter was removed.

    .. versionchanged:: 0.5
        Added the ``sort``, ``key``, and ``separator`` parameters.
    zs'werkzeug.urls.url_encode' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.urlencode' instead.r5   r6   r   )r8   r9   r:   r   ri   r   )r   r   r   r   r9  r   r   r   
url_encode  s   
rK  t.IO[str] | NoneNonec           	      C  sb   t jdtdd t|d}t| |||}|du r|S t|D ]\}}|r)|| || 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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 2.4. Use ``urllib.parse.urlencode`` instead.

    .. versionchanged:: 2.1
        The ``encode_keys`` parameter was removed.

    .. versionadded:: 0.8
    zz'werkzeug.urls.url_encode_stream' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.urlencode' instead.r5   r6   r   N)r8   r9   r:   r   r   	enumeratewrite)	r   r?  r   r   r   r9  genr   chunkr   r   r   url_encode_stream  s   

rR  basec                   s   t jdtdd t| trt| } t|trt|}t| |f t|  | s(|S |s,| S t| |d\}}}}}t|||\}}	}
}}||krH|S |	rSt||	|
||fS |}	|
dd  dkrg|
	 d}n |
su|	 d}|st|}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 = n	|d7 }||k snq d
 dg}|dd |kr|d= |dd |ks d|}
t||	|
||fS )aq  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.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 2.4. Use ``urllib.parse.urljoin`` instead.
    zo'werkzeug.urls.url_join' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.urljoin' instead.r5   r6   )r   Nr   r   .rk   c                   s   g | ]
}| d kr|qS )rU  r   )r   segmentr   r   r   r   G      zurl_join.<locals>.<listcomp>Tz..)r8   r9   r:   rL   r*  rj   r	   r   rg   r   r   ri   )rS  r   r   bschemebnetlocbpathbquery	bfragmentr#   r$   r%   r&   r'   segmentsr   nunwanted_markerr   r   r   rh     sh   

$,rh   r  c                 C  s    dd t | D }t|d|dS )Nc                 S  s   g | ]
}|d  dur|qS )r   Nr   )r   xr   r   r   r   _  rW  z_urlencode.<locals>.<listcomp>z!$'()*,/:;?@)r   r  )r   r   )r&   r  r   r   r   r   
_urlencode\  s   ra  )rk   )r   r   r   r   r4   ru   )
r   r   r   r"   r   r   r   r   r4   r   )r   r"   r   r"   r4   r"   )NT)r   r"   r#   rG   r   r   r4   r,   )ro   rp   r   rk   )
r   r"   r   r"   r   r   r   r   r4   r   r   )r   r   r   r"   r   r"   r   r   r   r   r4   r"   )ro   rp   rk   )
r   r"   r   r"   r   r"   r   r"   r4   r"   )r   r   r4   r"   )ro   rF   rk   )
r   r   r   r"   r   r"   r   r"   r4   r"   r   )r   r   r   r"   r   r"   r4   r"   )ro   )r   r"   r   r"   r4   r"   )r
  rN   r4   r  )r   r"   r  r"   r4   r  r   )r$  r%  r   rG   r   rG   r4   r"   )NNN)
r0  r%  r   rG   r   rG   r1  r2  r4   r"   )r0  r"   r4   r"   )ro   TrF   r6  N)r   r7  r   r"   r8  r   r   r"   r9  r"   r=   r:  r4   rc   )ro   TrF   r>  NN)r?  r@  r   r"   r8  r   r   r"   r9  ru   r=   r:  rA  rR   r4   rc   )
rD  rG  r   r"   r8  r   r   r"   r4   rH  )ro   FNr6  )r   r   r   r"   r   r   r   r   r9  r"   r4   r"   )Nro   FNr6  )r   r   r?  rL  r   r"   r   r   r   r   r9  r"   r4   rM  )T)rS  r%  r   r%  r   r   r4   r"   )r&   r   r  r"   r4   r"   )Lr   
__future__r   codecsr   r  typingtr8   urllib.parser   r   r   r   r   	_internalr	   r
   r   r   r   r   TYPE_CHECKINGrk   dsr  r   _always_safe_charsr   r   r   r   r   r   r   
NamedTupler!   r,   r   r   r   r+   r   r   r\   rg   r   _fast_url_quoter   r   rs   r   rj   r   r  r	  r  register_errorr   ru   rM   _always_unsafer-  r,  r+  r/  rz   rx   r5  rd   rF  r=  rK  rR  rh   ra  r   r   r   r   <module>   s    
  +!
>
.
* 
&


_
{8
7'2R