
    d                     
   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        rdd	lmZ  ej        d
          Z e ed                    ZdZd eD             Zd  ed          D             Z G d dej                  Z G d de          Z G d de          Z G d de          Z e            eiZej        ej         e!         ej        e"e!f         f         e#d<   	 dZdej$        e%e"f         dej$        e%e"f         de"fdZ&dej$        ej'        e%e%f         ej(        ej)        e%e%f                  f         de%d e*d!ej+        ej,        ej)        e%e%f         gej-        f                  dej.        e%         f
d"Z/dZd#e%de%de%fd$Z0	 d[d&e%d'ej+        e%         d(e*defd)Z1	 	 	 	 d\de%d-e%d.ej$        e%e"f         dej$        e%e"f         dej,        e"ge%f         f
d/Z2 e2            Z3 e2d0d12          Z4de"de%fd3Z5	 	 	 	 d\dej$        e%e"f         de%d-e%d.ej$        e%e"f         dej$        e%e"f         de%fd4Z6	 d]de%de%d-e%d.e%de%f
d5Z7d6ej)        e%e%e%e%e%f         de%fd7Z8	 	 	 d^d9ej$        e%e"f         de%d-e%de%de%f
d:Z9	 d_d9ej$        e%e"f         de%d-e%de%fd;Z:d`d9e%de%de%fd<Z;d<                    d=  ed>          D                       Z=d?e>dej)        e%e!f         fd@Z? ej@        dAe?           	 	 dadBej$        e%ej)        e%e%e%e%e%f         f         de%d-e%de%fdCZAdDZB	 	 	 dbdFej$        e%ej)        e%e%e%e%e%f         f         de%d-e%dGe*de%f
dHZC	 	 	 	 	 dcd9ejD        de%dJe*d-e%dKe%dLej+        ejE        dM                  ddNfdOZF	 	 	 	 	 	 dddQejG        e"         de%dJe*d-e%dKe"dLej+        ejE        dM                  dRej+        e!         ddNfdSZHdTej(        ejD                 de%dJe*d-e%dej.        ej)        e%e%f                  f
dUZI	 	 	 	 dedej$        ej'        e%e%f         ej(        ej)        e%e%f                  f         de%d e*d!ej+        ej,        ej)        e%e%f         gej-        f                  dKe%de%fdVZJ	 	 	 	 	 dfdej$        ej'        e%e%f         ej(        ej)        e%e%f                  f         dQej+        ejG        e%                  de%d e*d!ej+        ej,        ej)        e%e%f         gej-        f                  dKe%ddfdWZK	 dgdXej$        e%ej)        e%e%e%e%e%f         f         d&ej$        e%ej)        e%e%e%e%e%f         f         d(e*de%fdYZLdS )hzFunctions 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                 z    i | ]8}t           D ].}| |                     d           t          | | d          /9S )ascii   )
_hexdigitsencodeint).0abs      -lib/python3.11/site-packages/werkzeug/urls.py
<dictcomp>r   #   si       	  	
 	I!IIWsa999b11       c                 @    g | ]}d |d                     d          S )%02Xr   )r   )r   chars     r   
<listcomp>r   (   s.    DDDn$nnn##G,,DDDr      c                   B    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   +   s=         KKKKKK
IIIJJJMMMMMr   r   c                      e Zd ZU dZdZeed<   eed<   eed<   eed<   defdZd	ej	        dd fd
Z
edej        e         fd            Zedej        e         fd            Zedej        e         fd            Zedej        e         fd            Zedej        e         fd            Zedej        e         fd            Zedej        e         fd            Zedej        e         fd            Zdej	        d	ej	        ddfdZdej	        d	ej	        dd fdZdefdZdefdZdefdZd"dZd"dZ	 d#dej        e         dej        ej        e         ej        e         f         fdZdej        ej        e         ef         fdZdej        ej        e         ej        e         f         fd Z dej        ej        e         ej        e         f         fd!Z!dS )$BaseURLz7Superclass of :py:class:`URL` and :py:class:`BytesURL`.r)   _at_colon	_lbracket	_rbracketreturnc                 *    |                                  S N)to_urlselfs    r   __str__zBaseURL.__str__<   s    {{}}r   kwargsc                      | j         di |S )zReturn an URL with the same values, except for those parameters
        given new values by whichever keyword arguments are specified.r)   )_replace)r5   r7   s     r   replacezBaseURL.replace?   s     t}&&v&&&r   c                 6    |                                  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_hostr4   s    r   hostzBaseURL.hostD   s     !!!$$r   c                     | j         }|Lt          |t                    r7	 t          |          }n&# t          $ r |                    dd          }Y nw xY w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)r=   
isinstancer'   r   UnicodeErrorr   r   r5   rvs     r   
ascii_hostzBaseURL.ascii_hostL   s|     Y 	2jS11 	22!"%% 2 2 2YYw112r7H---s   0  AAc                     	 t          t          |                                 d                             }d|cxk    rdk    rn n|S n# t          t          f$ r Y nw xY w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   r<   
ValueError	TypeErrorrB   s     r   portzBaseURL.port[   s    
	WT--//23344BB    %     	I& 	 	 	D	ts   AA	 	AAc                 6    |                                  d         S )zSThe authentication part in the URL if available, `None`
        otherwise.
        r   )_split_netlocr4   s    r   authzBaseURL.authh   s    
 !!##A&&r   c                 \    |                                  d         }|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_legacyrB   s     r   usernamezBaseURL.usernameo   5    
 " 	+&r***tr   c                 6    |                                  d         S )zThe username if it was part of the URL, `None` otherwise.
        Unlike :attr:`username` this one is not being decoded.
        r   rN   r4   s    r   raw_usernamezBaseURL.raw_usernamey       
 !!!$$r   c                 \    |                                  d         }|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   NrM   rB   s     r   passwordzBaseURL.password   rQ   r   c                 6    |                                  d         S )zThe password if it was part of the URL, `None` otherwise.
        Unlike :attr:`password` this one is not being decoded.
        r   rS   r4   s    r   raw_passwordzBaseURL.raw_password   rU   r   argsds.MultiDict[str, str]c                 ,    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"   r5   rZ   r7   s      r   decode_queryzBaseURL.decode_query   s$    
 $*6t666v666r   c                 <    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_joinr^   s      r   joinzBaseURL.join   s*    
 $888888999r   c                      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_unparser4   s    r   r3   zBaseURL.to_url   s    
 4   r   c                    | j         pd}d|v rd| d}| j        }|| 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/:%@)rD   rH   rc   filter	url_quoterT   rY   r5   rC   rH   rK   s       r   encode_netloczBaseURL.encode_netloc   s    _""9 	RBy 	 Bxxd/52w%PPd/52w%PP 
 
  	 2B	r   c           
         t          | j        pd          }d|v rd| d}| j        }|| d| }d                    t	          dt          | j        pdd          t          | j        pdd          g                    }|r| d| }|S )z&Decodes the netloc part into a string.rg   rh   ri   rj   Nz/:%@rm   )r   r=   rH   rc   rn   rO   rT   rY   rp   s       r   decode_netloczBaseURL.decode_netloc   s    $)/r**"9 	RBy 	 Bxx'(9(?RHH'(9(?RHH 
 
  	 2B	r   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.
        )ra   
iri_to_urir4   s    r   to_uri_tuplezBaseURL.to_uri_tuple   s     D))***r   c                 :    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.
        )ra   
uri_to_irir4   s    r   to_iri_tuplezBaseURL.to_iri_tuple   s     D))***r   N
pathformatc                    | j         dk    rdS t          | j                  }| j        pd}|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}|                    |          }|rN|L|	                    d          
                    dd          }t          |          d	k    r|\  }}n=|d         }d}n2|dk    rddl}|                    |          }nt          d|          |dv rd}||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|:rh   )z\\\z///r   \rg   zInvalid path format )z	127.0.0.1z::1	localhost)r   url_unquoter!   r    osnameisalphantpathnormpathlstripsplitlen	posixpathrG   )r5   rz   r!   r=   windows_sharer   partsr   s           r   get_file_locationzBaseURL.get_file_location   s   ( ;&  	:49%%{"d 	%w$ %&

$
" 	CBQBx3 14!9#4#4#6#6 14!9;L 1qs)00d122h00 !H(;;MMMM??4((D
   D))//a88u::? !&JD$$ 8DD7" 	C%%d++DDA:AABBB44 	DTzr   c                 ~    | j         | j        v r'| j                            | j                   \  }}}||fS d | j        fS r2   )r,   r    	partition)r5   rK   _r    s       r   rJ   zBaseURL._split_netloc$  sG    8t{" 	 "k33DH==OD!V<T[  r   c                     |                                  d         }|sdS | j        |vr|d fS |                    | j                  \  }}}||fS )Nr   r}   )rJ   r-   r   )r5   rK   rP   r   rW   s        r   rN   zBaseURL._split_auth*  sc    !!##A& 	:;d" 	: $t{ ; ;!X!!r   c                    |                                  d         }|sdS |                    | j                  s/| j        |v r"|                    | j                  \  }}}||fS |d fS |                    | j                  }|dk     r|d fS |d|         }||dz   d          }|                    | j                  r||dd          fS |d fS )Nr   r}   r   )rJ   
startswithr.   r-   r   findr/   )r5   rC   r=   r   rH   idxrests          r   r<   zBaseURL._split_host4  s    !!!$ 	:}}T^,, 	{b  " "T[ 9 9aTz!t8Oggdn%%7 	t8O!C%y#'))}??4;'' 	"abb>!Tzr   )r0   r+   r2   )"r$   r%   r&   __doc__	__slots__r'   r(   r6   tAnyr:   propertyOptionalr=   rD   r   rH   rK   rP   rT   rW   rY   r_   rc   r3   rq   rs   rv   ry   Tupler   rJ   rN   r<   r)   r   r   r+   r+   3   s        AAI	HHHKKKNNNNNN    ' ') ' ' ' '
 %ajo % % % X% .AJsO . . . X. 
ajo 
 
 
 X
 'ajo ' ' ' X' !*S/    X %ajo % % % X% !*S/    X %ajo % % % X%7!% 715 7=U 7 7 7 7:!% :15 :Y : : : :! ! ! ! !s    *s    ,+ + + +	+ 	+ 	+ 	+ -1< <*S/<	
C!*S/1	2< < < <|!qwqz#';< ! ! ! !"QWQZ_ajo%EF " " " "QWQZ_ajo%EF      r   r+   c                   <    e Zd ZdZdZdZdZdZdZdd	e	d
e	ddf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)   rm   rh   ri   rj   rk   r:   charseterrorsr0   BytesURLc           
         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   rq   r!   r"   r#   r5   r   r   s      r   r   z
URL.encodeV  sw     Kw''  IWf--Jgv..M  &11
 
 	
r   Nrk   r:   )r$   r%   r&   r   r   r,   r-   r.   r/   r'   r   r)   r   r   r   r   J  sg         
 I
CFII

 

c 

S 

 

 

 

 

 

 

r   r   c                   T    e Zd ZdZdZdZdZdZdZde	fdZ
defd	Zdde	de	ddfdZdS )r   z!Represents a parsed URL in bytes.r)      @   :   [   ]r0   c                 R    |                                                      dd          S )Nrk   r:   )r3   decoder4   s    r   r6   zBytesURL.__str__l  s     {{}}##GY777r   c                     | j         S )z&Returns the netloc unchanged as bytes.)r    r4   s    r   rq   zBytesURL.encode_netloco  s
    {r   rk   r:   r   r   r   c           
         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   rs   r!   r"   r#   r   s      r   r   zBytesURL.decodes  sw     Kw''  IWf--Jgv..M  &11
 
 	
r   Nr   )r$   r%   r&   r   r   r,   r-   r.   r/   r'   r6   bytesrq   r   r)   r   r   r   r   c  s        ++I
CFII8 8 8 8 8u    

 

c 

S 

 

 

 

 

 

 

r   r   _unquote_mapsrg   stringunsafer0   c                    t          | t                    r|                     d          } t          t                    r                    d          t          t	                              t          |                     d                    }t	          t          |d                    }	 t                   }n?# t          $ r2 fdt                                          D             x}t          <   Y nw xY w|D ]s}|d d         }||v r9|                    ||                    |                    |dd                     I|                    d           |                    |           tt          |          S )Nrk      %r   c                 $    i | ]\  }}|v	||S r)   r)   )r   hr   r   s      r   r   z%_unquote_to_bytes.<locals>.<dictcomp>  s8     /
 /
 /
Q1F?/
q/
 /
 /
r   r   %   )r@   r'   r   	frozenset	bytearrayiterr   nextr   KeyError
_hextobyteitemsappendextendr   )r   r   groupsresulthex_to_bytegroupcodes    `     r   _unquote_to_bytesr     s    &# (w''&# (w''y(())F&,,t$$%%FtFC(())F
#F+ 
 
 
/
 /
 /
 /
'--///
 /
 /
 	
mF+++

  ! !RaRy; 	!MM+d+,,,MM%)$$$$MM"MM%    ==s   2C   9C<;C<objr   sortkeyc              #     K   ddl m}  ||           }|rt          ||          }|D ]\  }}|t          |t                    s#t          |                              |          }n|}t          |t                    s#t          |                              |          }	n|}	t          |           dt          |	           V  d S )Nr   )iter_multi_items)r   =)r	   r   sortedr@   r   r'   r   _fast_url_quote_plus)
r   r   r   r   r   iterablekey_str	value_str	key_bytesvalue_bytess
             r   _url_encode_implr     s      100000.>.>s.C.CH -(,,,& W W 	'5)) 	 G++G44III)U++ 	$i..//88KK#K%i00VV3G3T3TVVVVVVW Wr   valuec                 n    	 t          | dd|          S # t          $ r t          | d|          cY S w xY w)Nrk   rl   )r   r   r   latin1)r   r   )r   rA   )r   r   s     r   rO   rO     sY    C5'(6RRRR C C C5(6BBBBBBCs    44Turlr   allow_fragmentsc                 *   t          |           t          | t                    }| d          } d          x}x}}|                      d                    }|dk    ryt                              t          | d|         d                    rH| |dz   d         }|rt          fd|D                       r| d|                                         |} }| dd	          d
          k    rt          |           }	 d          D ].}
|                     |
d	          }|dk    rt          |	|          }	/| d	|	         | |	d         } } d          |v r d          |vs d          |v r d          |vrt          d          |r/ d          | v r"|                      d          d          \  } } d          | v r"|                      d          d          \  } }|rt          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.
    Nrg   rh   r   r:   )r   r   c              3   2   K   | ]}| d           vV  dS )
0123456789Nr)   )r   css     r   	<genexpr>zurl_parse.<locals>.<genexpr>  s0      BB1AAlOO3BBBBBBr   r   //z/?#ri   rj   zInvalid IPv6 URL#?)r   r@   r'   r   
_scheme_rematchr   anylowerr   minrF   r   r   r   )r   r   r   is_text_basedr    r"   r#   ir   delimr   wdelimresult_typer   s                @r   ra   ra     sp    	S!!AsC((M 2 !"%F%UX3A1u 0!!'#bqb')"D"D"DEE 0 1q577| 	0sBBBBTBBBBB 	0bqb'--//4CF
2A2w!!D'' 
1C5 	+ 	+AXXa^^F{ +E6**!E'lCKAcFFf 	13v!5 	1AcFFf	1!"3v!5	1 /000 -11S66S= -		!!C&&!,,Xqvv} *YYqqvvq))
U&4##HK;vvsE8<<<r   rk   rl   /:r   safec                    t          t                    r                    | |          t          |t                    r|                    | |          }t          t	                              t
          z  t          t	          |                    z
  fdt          d          D             dt          dt          ff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                 B    g | ]}|v rt          |          nd |dS )r   r   )chr)r   r   r   s     r   r   z(_make_fast_url_quote.<locals>.<listcomp>  s4    FFFaqDy1SVVVk!kkkFFFr   r   r   r0   c                 F    d                     fd| D                       S )Nrg   c                      g | ]
}|         S r)   r)   )r   r   tables     r   r   z7_make_fast_url_quote.<locals>.quote.<locals>.<listcomp>  s    111Qa111r   )rc   )r   r   s    r   quotez#_make_fast_url_quote.<locals>.quote  s*    ww1111&111222r   )r@   r'   r   r   r   _always_saferanger   )r   r   r   r   r   r   s     `  @r   _make_fast_url_quoter     s      $ ,{{7F++&# 0w//ioo&&59VCTCT9U9UUDFFFF5::FFFE3e 3 3 3 3 3 3 3 Lr    +)r   r   c                 H    t          |                               dd          S )Nr   r   )_fast_quote_plusr:   )r   s    r   r   r     s     F##++C555r   c                    t          | t          t          t          f          st          |           } t          | t                    r|                     ||          } t          |t                    r|                    ||          }t          |t                    r|                    ||          }t          t          |                    t          z  t          t          |                    z
  }t                      }t          |           D ]<}||v r|                    |           |                    t          |                    =t          |          
                    |          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.
    )r@   r'   r   r   r   r   r   r   r   
_bytetohexr   )r   r   r   r   r   rC   r   s          r   ro   ro   #  s5   " fsE9566 V&# 0w//$ ,{{7F++&# 0w//ioo&&59VCTCT9U9UUD	B&!! ( (4< 	(IIdOOOOIIj&''''99G$$$r   c                 V    t          | |||dz   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   )ro   r:   )r   r   r   r   s       r   url_quote_plusr  F  s.     VWfdSj#>>FFsCPPPr   
componentsc                    t          |            | \  }}}}}t          |          } |d          }|s |rb|                     |d                    rD|r%|dd          |d          k    r |d          |z   } |d          |p
 |d          z   |z   }n|r||z  }|r| |d          z   |z   }|r| |d          z   |z   }|r| |d          z   |z   }|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.
    rg   r   Nr   r   rh   r   r   )r   r   r   )r  r   r    r!   r"   r#   r   r   s           r   re   re   S  s2    Z   ,6)FFD%V$$A
!B%%C  & T__QQsVV44  	!D!H#& 	!1S66D=Dagg11R55)D0	 t $qqvvo# #AAcFFlU" &AAcFFlX%Jr   r:   r   c                 V    t          | |          }||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.
    )r   r   )r   r   r   r   rC   s        r   r   r   r  s4     
1f	%	%B 	99Wf%%%r   c                     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      +    )r@   r'   r:   r   )r   r   r   s      r   url_unquote_plusr    sP     !S "IIc3IIdD!!q'6***r   c                    t          | |d                              dd          } |                     d          r5| dd                                         r| dd         dv rd	| dd
          } t	          |           }t          |j        |d          }t          |j        |d          }t          |j	        |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.
    r:   r   r   zfile://      
   )z:/z|/zfile:///Nz
/%+$!*'(),)r   z:&%=+$!*'(),)r   r:   r   r   ra   ro   r!   r  r"   r#   re   r   rq   )r   r   r   r!   qsanchors         r   url_fixr    s      	7I&&..tS99A 	||I 1QqS6>>#3#3 !B$<8O qu
A,,CSXw\:::D		7	@	@	@BCL'GGGF
C$5$5$7$7r6JKKKr   c                 >    g | ]}|t           vt          |          S r)   )r   r   )r   r   s     r   r   r     s(    NNNQ8MN#a&&NNNr      ec                 `    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  outs     r   _codec_error_url_quoter    s,     !(17QU?3
4
4C:r   werkzeug.url_quoteuric                    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
    )r@   tuplere   ra   r   r   r!   _to_iri_unsafer"   r#   r   rs   )r  r   r   r!   r"   r#   s         r   rx   rx     s    0 #u #
GC))
*
*Csx&.AAD	7FNCCE3<&.IIH
C$5$5$7$7uhOPPPr   z:/?#[]@!$&'()*+,;=%Firisafe_conversionc                 B   t          | t                    rt          |           } |r]	 t          |           }|                    d          }t          |                                          dk    r|S n# t          $ r Y nw xY w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   )r@   r!  re   r   r   r   r   rA   ra   ro   r!   _to_uri_safer"   r#   r   rq   )	r#  r   r   r$  
native_iri	ascii_irir!   r"   r#   s	            r   ru   ru     s   V #u # 	 J"))'22I 9??$$%%* "!!" 	 	 	D	 GC&11
2
2CSXw==Dci&,??EwEEH
C$5$5$7$7uhOPPPs   A
A4 4
B B&include_empty	separatorclszds.MultiDictr[   c                 x   |ddl m} |}t          | t                    r-t          |t                    s|                    |pd          }nAt          | t
                    r,t          |t
                    s|                    |pd          } |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/  r@   r'   r   r   r   _url_decode_implr   )r   r   r*  r   r+  r,  r/  s          r   r]   r]   3  s    <  ------!S 9*Y"<"< 9$$W%788			Au		 9jE&B&B 9$$W%788	3GGI	
 	
  r      &streamlimitc                 v    ddl m}  || ||          }t          ||||          }	|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.  )wsgir5  r0  r	   r/  )r2  r   r*  r   r+  r,  r3  r5  	pair_iterdecoderr/  s              r   url_decode_streamr9  `  sj    B &%%%%%	599Iy'=&IIG
 ------3w<<r   r7  c              #      K   | D ]q}|st          |          } |d          }||v r|                    |d          \  }}n|s@|} |d          }t          |||          t          |||          fV  rd S )Nr   r   rg   )r   r   r  )	r7  r   r*  r   pairr   equalr   r   s	            r   r0  r0    s        
 
 	 &&#D= 	E1--JC  CAbEEES'622UGV44
 	
 	
 	
 	

 
r   c                 l    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   rc   r   )r   r   r   r   r+  s        r   
url_encoder>    s4    2 	7++I>>*3sCCDDDr   c                     t          |d          }t          | |||          }||S t          |          D ]1\  }}|r|                    |           |                    |           2d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   r2  r   r   r   r+  genr   chunks	            r   url_encode_streamrD    s    8 	7++I
3s
3
3C 
nn  
U 	$LL###U4r   basec                    t          | t                    rt          |           } t          |t                    rt          |          }t          | |f           t	          |           | s|S |s| S t          | |          \  }}}}}t          |||          \  }}	}
}}||k    r|S |	rt          ||	|
||f          S |}	|
dd          d          k    r|
                     d                    }nj|
s#|                     d                    }|s|}nE|                     d                    dd         |
                     d                    z   }|d          d          k    r d          |d<   fd|D             }	 d}t          |          dz
  }||k     rM||          d
          k    r-||dz
            d           d
          fvr||dz
  |dz   = n|dz  }||k     Mni d           d
          g}|dd         |k    r|d= |dd         |k     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   r   .rg   c                 2    g | ]}| d           k    |S )rH  r)   )r   segmentr   s     r   r   zurl_join.<locals>.<listcomp>  s+    EEEG7aaff3DEEEEr   Tz..r   )	r@   r!  re   r   r   ra   r   r   rc   )rE  r   r   bschemebnetlocbpathbquery	bfragmentr   r    r!   r"   r#   segmentsr   nunwanted_markerr   s                    @r   rb   rb     s    $ !4  #u #dC[!!!T""A 
 1:o2 2 2.GWeVY -6c7O,T,T)FFD% 
 DFFD%BCCCFBQBx11S66 A::aaff%% A;;qqvv&& 	E;;qqvv&&ss+djj3.@.@@ |qqvv quu FEEExEEEH	MMA!e 	{aagg% (1q5/!!B%%4AQ*Q QUQU]+FA	 !e 	 	 quuaagg&O
2A2,/
) QK 2A2,/
)  1S66;;x  DeX>???r   )rg   )NT)rk   rl   r   rg   )rk   rl   rg   )rk   r:   rg   r   )rk   )rk   r  )rk   rl   F)rk   Tr:   r)  N)rk   Tr:   r1  NN)rk   FNr)  )Nrk   FNr)  )T)Mr   codecsr   retypingr   	_internalr   r   r   r   r   TYPE_CHECKINGrg   r	   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   rO   ra   r   r  r  r   ro   r  re   r   r  r  rc   r"  rA   r  register_errorrx   r&  ru   AnyStrTyper]   IOr9  r0  r>  rD  rb   r)   r   r   <module>rg     s    
  				 				     ' ' ' ' ' ' # # # # # # # # # # # # + + + + + +      ? '&&&&&& RZ,--
 yI	   &
   

 EDsDDD
       T T T T Ti T T Tn
 
 
 
 
' 
 
 
2
 
 
 
 
w 
 
 
: @Iy{{J>Wqvak#&ucz(::; W W W @B GCJ)*e)<
   BW	
38$ajc1B&CC	DWW W 
AJS 12AE9:	;	W
 Z_W W W W<C Cs CC C C C C C GK0= 0=	0=jo0=?C0=0= 0= 0= 0=h  $"$	  '#u*
 GCJ	
 Z   > '&((''S=== 6 63 6 6 6 6  $"$ %  %GCJ % %  % '#u*
	 %
 GCJ % 	 %  %  %  %H NP
Q 
Q
Q
Q14
QGJ
Q
Q 
Q 
Q 
QAGCc3$;<     B 	& &wsEz&& & 	&
 	& & & &, CL+ +wsEz+%(+<?++ + + +*L Ls LS Ls L L L L> NN%%**NNNOOl qwsCx/@      *,B C C C
 &Q Q	
agc3S#566	7QQ Q 		Q Q Q QF %
 !	?Q ?Q	
agc3S#566	7?Q?Q ?Q 	?Q
 	?Q ?Q ?Q ?QH .2* *x** * 	*
 * 
AF>*	+* * * * *^ .2!+ +DK++ + 	+
 + 
AF>*	++ :c?+ + + + +\
z!(#
.1
BF
PS
ZS!"
 
 
 
. >BE E	
38$ajc1B&CC	DEE E 
AJS 12AE9:	;	E
 E 	E E E E> %)>B$ $	
38$ajc1B&CC	D$JqtCy!$ $ 	$
 
AJS 12AE9:	;$ $ 
$ $ $ $T !D@ D@
'#qwsCc3677
8D@	
agc3S#566	7D@ D@ 		D@ D@ D@ D@ D@ D@r   