
    \Jj                     
   d dl mZ d dlZd dlZd dlZd dlZd dlmZmZm	Z	m
Z
 d dlmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZmZ d dlmZ d dlmZmZ dadadZ d	 Z!d
Z" G d de      Z# G d de      Z$ G d de      Z%dZ&dZ'dZ(dZ) ejT                  d ejV                  e)      z        Z, ejT                  d      Z- ejT                  d      Z. ejT                  d      Z/ e0d      Z1d Z2 G d d      Z3 G d de3      Z4y)    )IntEnumN)ChunkedReaderLengthReader	EOFReaderBody)InvalidHeaderInvalidHeaderName
NoMoreDataInvalidRequestLineInvalidRequestMethodInvalidHTTPVersionLimitRequestLineLimitRequestHeadersUnsupportedTransferCodingObsoleteFoldingExpectationFailed)InvalidProxyLineInvalidProxyHeaderForbiddenProxyRequest)InvalidSchemeHeaders)bytes_to_strsplit_request_uri)permit_obsolete_foldingstrip_header_spacesc                    t        | dd      }|dk(  ryt        		 ddl}da|at        s|dk(  rt        d	      t        syt        t        d
      s|dk(  rt        d      yg }t        D ]!  }t        | |d      s|j                  |       # |r#|dk(  rt        ddj                  |      z        yy# t        $ r daY w xY w)a  Check if fast C parser is available and should be used.

    Returns False if:
    - http_parser='python' is explicitly set
    - gunicorn_h1c is not installed (in 'auto' mode)
    - gunicorn_h1c < 0.4.1 (in 'auto' mode)
    - Incompatible compatibility flags are enabled (in 'auto' mode)

    Raises RuntimeError if:
    - http_parser='fast' but gunicorn_h1c is not installed
    - http_parser='fast' but gunicorn_h1c < 0.4.1
    - http_parser='fast' but incompatible flags are enabled
    http_parserautopythonFNr   Tfastz1gunicorn_h1c not installed but http_parser='fast'r   zigunicorn_h1c >= 0.4.1 required for http_parser='fast'. Please upgrade: pip install --upgrade gunicorn_h1czqhttp_parser='fast' is incompatible with compatibility flags: %s. Use http_parser='python' or disable these flags.z, )
getattr_fast_parser_availablegunicorn_h1c_fast_parser_moduleImportErrorRuntimeErrorhasattr_FAST_PARSER_INCOMPATIBLE_FLAGSappendjoin)cfgparser_settingr"   incompatibleflags        P/var/www/html/Extract/venv/lib/python3.12/site-packages/gunicorn/http/message.py_check_fast_parserr/   #   s     S-8N!%	+%)"". "n&>NOO! &(:;V#E 
  L/ &3e$%& V#C))L)*  G  	+%*"	+s   B3 3C Cs   

 
QUIT
c                       e Zd ZdZdZdZy)	PPCommandzPROXY protocol v2 commands.r      N)__name__
__module____qualname____doc__LOCALPROXY     r.   r1   r1   f   s    %EEr:   r1   c                        e Zd ZdZdZdZdZdZy)PPFamilyz#PROXY protocol v2 address families.r   r2         N)r3   r4   r5   r6   UNSPECINETINET6UNIXr9   r:   r.   r<   r<   l   s    -FDEDr:   r<   c                       e Zd ZdZdZdZdZy)
PPProtocolz&PROXY protocol v2 transport protocols.r   r2   r=   N)r3   r4   r5   r6   r?   STREAMDGRAMr9   r:   r.   rD   rD   t   s    0FFEr:   rD   i  i   z!#$%&'*+-.^_`|~z[%s0-9a-zA-Z]+z[a-z#]zHTTP/(\d)\.(\d)z[\x00-\x08\x0a-\x1f\x7f])HOSTCONTENT-LENGTHTRANSFER-ENCODINGTRAILERAUTHORIZATIONTEc                 r    d|v ry	 t        j                  |       }|D ]  }||v s y y# t        $ r Y yw xY w)zCheck if IP address is in the allow list.

    Args:
        ip_str: The IP address string to check
        allow_list: The original allow list (strings, may contain "*")
        networks: Pre-computed ipaddress.ip_network objects from config
    *TF)	ipaddress
ip_address
ValueError)ip_str
allow_listnetworksipnetworks        r.   _ip_in_allow_listrW      sX     j!!&)  =   s   * 	66c                   B    e Zd Zd Zd Zd Zd Z	 d
dZd
dZd Z	d Z
y	)Messagec                 t   || _         || _        || _        || _        d | _        g | _        g | _        d | _        |j                  rdnd| _	        d| _
        d| _        |j                  | _        | j                  dk  s| j                  t        kD  rt        | _        |j                  | _        | j                  dk  rt        | _        | j                  xs t        }| j                  |dz   z  dz   | _        | j#                  | j                        }| j                  j%                  |       | j'                          y )NhttpshttpFr   r=      )r*   unreader	peer_addrremote_addrversionheaderstrailersbodyis_sslscheme
must_close_expected_100_continuelimit_request_fieldsMAX_HEADERSlimit_request_field_sizeDEFAULT_MAX_HEADERFIELD_SIZEmax_buffer_headersparseunreadset_body_reader)selfr*   r^   r_   max_header_field_sizeunuseds         r.   __init__zMessage.__init__   s    "$	!$g&+# %($<$<!%%*,,{:(3D%(+(D(D%((A-,HD) !% = = ]A]"&";";"Q&#(*+#, DMM*V$r:   c                     d| _         y )NT)rg   rq   s    r.   force_closezMessage.force_close   s	    r:   c                     t               N)NotImplementedError)rq   r^   s     r.   rn   zMessage.parse   s    !##r:   c                     | j                   }t        | j                  t              r2t	        | j                  d   |j
                  |j                               r|j                  |j                  fS i g fS )a>  Return the (secure_scheme_headers, forwarder_headers) the peer is allowed to set.

        When the peer's address is not in ``forwarded_allow_ips`` (or networks),
        configured forwarding/secure-scheme policy must be ignored to prevent
        spoofing.  Returns ``({}, [])`` when the peer is untrusted.
        r   )	r*   
isinstancer_   tuplerW   forwarded_allow_ipsforwarded_allow_networkssecure_scheme_headersforwarder_headers)rq   r*   s     r.   _peer_trusted_for_forwardedz#Message._peer_trusted_for_forwarded   sc     hh4>>51$T^^A%68O8O%(%A%A%CE,,c.C.CCC2vr:   c                    |s;|dk(  r6|j                         dk(  r| j                  dk  rnd| _        nt        |      ||v r8|||   k(  }|rdnd}|d   r|| j                  k7  rt               d|d<   || _        d|v rP||v sd	|v r	 ||fS | j                  j                  d
k(  r	 ||fS | j                  j                  dk(  ryt        |      ||fS )a   Apply per-header policy shared between Python and fast parsers.

        Mutates ``self._expected_100_continue`` and ``self.scheme`` as needed.
        ``scheme_state`` is a single-element list used as a mutable sentinel
        so the caller can detect repeated scheme headers.

        Returns the (name, value) pair to retain, or ``None`` to drop the
        header (per ``header_map='drop'``).  Raises the same exceptions the
        Python path raises so behavior is identical regardless of parser.
        EXPECTz100-continuer2   r2   Tr[   r\   r   _rN   	dangerousdropN)	lowerra   rh   r   rf   r   r*   
header_mapr	   )	rq   namevaluescheme_stater   r   from_trailersecurerf   s	            r.   _apply_header_policyzMessage._apply_header_policy   s     0 {{}.<<&( 26D/ (..((3D99F &WFFAT[[(.00"&Q$ $;((C3D,D e} $$3 e} $$.  (--e}r:   c                    g }|j                  d      D cg c]  }t        |       }}dg}|ri g }}n| j                         \  }}|r9t        |      | j                  k\  rt        d      |j                  d      }	t        |	      t        d      z   }
|	j                  d      dk  rt        |	      |	j                  dd      \  }}| j                  j                  r|j                  d      }t        j                  |      st        |      |j                         }|r|t         v rt        |      |j#                  d      g}|r|d   j%                  d	      r| j                  j&                  st)        |      |j                  d      }	|
t        |	      t        d      z   z  }
|
| j*                  cxkD  rdkD  rt        d
       |j-                  |	j#                  d             |r|d   j%                  d	      rdj/                  |      }t0        j3                  |      rt        |      |
| j*                  cxkD  rdkD  rt        d
       | j5                  ||||||      }|'|j-                  |       |r9|S c c}w )N   
Fzlimit request headers fieldsr   z
:r2    	) 	z!limit request headers fields sizez	 r   r   )splitr   r   lenri   r   popfindr   r*   r   rstripTOKEN_RE	fullmatchr	   upperRFC9110_6_5_1_FORBIDDEN_TRAILERstrip
startswithr   r   rk   r(   r)   !RFC9110_5_5_INVALID_AND_DANGEROUSsearchr   )rq   datar   rb   linelinesr   r   r   currheader_lengthr   r   kepts                 r.   parse_headerszMessage.parse_headers  s~    15

70CDd#DD w 8:2#4!7;7W7W7Y4!#4 7|t888)*HII 99Q<DIF3Myy~"#D))**S!,KD%xx++{{5)%%d+'-- ::<D (G G'--[['(E E!H//<xx77)$//yy|TS[!88 4#@#@D1D- /< = = E TZZ./ E!H//< HHUOE077>#D))t<<@q@)*MNN A ,,e\%'8) - D
 |NN4 k n I Es   Jc                    d}d }| j                   D ]  \  }}|dk(  r|t        d|       |}|dk(  s#|j                  d      D cg c]  }|j                          }}|D ]  }|j	                         dk(  r|rt        d|       d}(|j	                         dk(  r|s>t        d|       |j	                         d	v r |rt        d|       | j                          }t        |        |rP| j                  d
k  rt        d|       |t        d|       t        t        | | j                              | _        y |k	 t        |      j                         rt        |      }nt        d|       	 |dk  rt        d|       t        t!        | j                  |            | _        y t        t#        | j                              | _        y c c}w # t        $ r t        d|       w xY w)NFrH   )reqrI   ,chunkedTidentity)compressdeflategzipr   r   )rb   r   r   r   r   rw   r   ra   r   r   r^   rd   str	isnumericintrQ   r   r   )rq   r   content_lengthr   r   vvalsvals           r.   rp   zMessage.set_body_readere  s   !\\ 	?MT5''!-'(8dCC!&,, ,1;;s+;<a	<< ?Cyy{i/""/0C"NN"&
2 #"/0C"NN(GG""/0C"NN((*7>>#?	?8  ||f$#$7TBB) $$4$??]4?@DI'@~&002%(%8N'(8dCC # !#$4$??\$--HIDIYt}}56DI] =L  @#$4$??@s   G2G G,c                     | j                   ry| j                  D ]9  \  }}|dk(  s|j                         j                  d      }|dk(  r y|dk(  r y n | j                  dk  S )NT
CONNECTIONr   closez
keep-aliveFr2   r   )rg   rb   r   r   ra   )rq   hr   s      r.   should_closezMessage.should_close  sh    ??ll 	FQL GGIOOE*<,& 	 ||v%%r:   NF)r3   r4   r5   rt   rw   rn   r   r   r   rp   r   r9   r:   r.   rY   rY      s3    >$  +0:xHT:7x&r:   rY   c                   x     e Zd Zd fd	ZddZd Zd Zd ZddZddZ	d Z
d	 Zd
 Zd Zd Zd Z fdZ xZS )Requestc                    d | _         d | _        d | _        d | _        d | _        |j
                  | _        | j
                  dk  rt        | _        | j
                  dk(  rd| _        n;| j
                  t        k\  rt        | _        t        | _        n| j
                  | _        || _        d | _	        t        |      | _        t        | 5  |||       y )Nr   i   )methoduripathqueryfragmentlimit_request_lineMAX_REQUEST_LINE_fast_limit_request_line
req_numberproxy_protocol_infor/   	_use_fastsuperrt   )rq   r*   r^   r_   r   	__class__s        r.   rt   zRequest.__init__  s    	
 #&"8"8""Q&&6D# ""a',7D)$$(88,<D)&6D#,0,C,CD)$#'  ,C0h	2r:   c                     |j                         }|s%|r
t               t        |j                               |j	                  |       y ry   )readStopIterationr
   getvaluewriterq   r^   bufstopr   s        r.   get_datazRequest.get_data  s7    }}#o%S\\^,,		$r:   c                    t               }| j                  ||d       | j                  j                  }|dk7  r"| j                  dk(  r| j                  |||      }| j                  r| j                  ||      S | j                  ||      S )NT)r   offr2   )		bytearray	read_intor*   proxy_protocolr   _handle_proxy_protocolr   _parse_fast_parse_pythonrq   r^   r   modes       r.   rn   zRequest.parse  s    kx40 xx&&5=T__1--hTBC >>##Hc22!!(C00r:   c           	      F   t        |      }d}	 	 t        j                  ||| j                  | j                  | j
                  | j                  j                  | j                  j                        }	 t-        |d         | _        t-        |d         | _        | j                  j2                  r| j.                  j5                         | _        t        | j0                        dk(  rt+        | j0                        	 t7        | j0                        }|j:                  xs d| _        |j<                  xs d| _        |j>                  xs d| _        d|d	   f| _         g | _!        d
g}| jE                         \  }	}
|d   D ]\  \  }}t-        |      j5                         }t-        |      }| jG                  ||||	|
      }|B| jB                  jI                  |       ^ |d   }||d S # t        j                  $ r\ t        |      }| j                  ||       t        |      }t        |      | j                  | j                  z   kD  rt        d      Y n*t        j                  $ r}t        t        |            d}~wt        j                  $ r}t        t        |            d}~wt        j                   $ r}t!        t        |            d}~wt        j"                  $ r}t#        t        |            d}~wt        j$                  $ r}t%        t        |            d}~wt        j&                  $ r}t'        t        |            d}~wt        j(                  $ r}t+        t        |            d}~ww xY wr# t8        $ r t+        | j0                        w xY w)z:Parse request using fast C parser (gunicorn_h1c >= 0.4.1).r   )last_lenr   ri   rk   !permit_unconventional_http_method"permit_unconventional_http_versionmax buffer headersNr   r    r2   minor_versionFrb   consumed)%bytesr#   parse_requestr   ri   rk   r*   r   r   IncompleteErrorr   r   rm   r   r   r   r   r   r	   r   
ParseErrorr   r   r   r   casefold_http_methodr   r   rQ   r   r   r   ra   rb   r   r   r(   )rq   r^   r   r   r   resultepartsr   r   r   
name_bytesvalue_bytesr   r   r   r   s                    r.   r   zRequest._parse_fast  s=    Sz 1 -::%'+'D'D)-)B)B-1-J-J6:hh6`6`7;xx7b7b ;  . #6(#34v/ 88((++++-DK txx=A$TXX..	/%dhh/E JJ$"	[[&B
," 6/23 w373S3S3U00'-i'8 
	&#J
+113D -E,,e\%'8D |LL%
	& *%HIC '66 Dt9x-Szt9t669V9VVV-.BCC W&77 /&s1v..&:: 2)#a&11&;; 3*3q622&99 1(Q00&88 0'A//&44 ,#CF++&11 1(Q001A `  	/$TXX..	/ss   A"G' <N 'A+M<M<'I;;M<J%%M<;KM<%K99M<L##M<9MM<#M77M<N c                    | j                  ||| j                        \  }}| j                  |       t        |      }|dd dk(  }	 |j	                  d      }|dd dk(  }|dk  rB|s@| j                  ||       t        |      }t        |      | j                  kD  rt        d      nb|r| j                  j                  |dd        y| j                  |d| d	      | _        ||d
z   d }|S )z'Parse request using pure Python parser.Nr=   r   s   

r   r   r:   Fr   r]   )	read_liner   parse_request_liner   r   r   r   rm   r   r^   ro   r   rb   )rq   r^   r   r   r   doneidxrets           r.   r   zRequest._parse_python;  s    NN8S$2I2IJ	c% SzBQx7"))K(C8w&DQwtx-Szt9t666-.BCC  MM  ab*))$t*5)I378n
r:   c                     |j                         }|s |r
t               t        t        |            |j	                  |       y)z7Read data from unreader and append to bytearray buffer.N)r   r   r
   r   extendr   s        r.   r   zRequest.read_into[  s6    }}#o%U3Z((

4r:   c                 B   t        |      }	 |j                  d      }|dk\  r||cxkD  rdkD  rn nt        ||      nMt        |      dz
  |cxkD  rdkD  rn nt        t        |      |      | j	                  ||       t        |      }~|d| t        ||dz   d       fS )z<Read a line from buffer, returning (line, remaining_buffer).r   r   r=   N)r   r   r   r   r   r   )rq   r^   r   limitr   r   s         r.   r   zRequest.read_lined  s    Sz))G$Cax??*3664y1}u(q(&s4y%88NN8S):D  Tc
$sQwx.)+ 	+r:   c                     t        |      |k  r!| j                  ||       t        |      |k  r!t        |d|       t        ||d       fS )z.Read exactly count bytes from buffer/unreader.N)r   r   r   r   )rq   r^   r   counts       r.   
read_byteszRequest.read_bytesw  sK    #hNN8S) #hS%[!9S[#999r:   c                 $   t        |      dk  r!| j                  ||       t        |      dk  r!|dv r.|dd t        k(  r"| j                          | j	                  ||      S |dv r*|dd dk(  r"| j                          | j                  ||      S |S )ztHandle PROXY protocol detection and parsing.

        Returns the buffer with proxy protocol data consumed.
           )v2r   N)v1r      s   PROXY )r   r   PP_V2_SIGNATUREproxy_protocol_access_check_parse_proxy_protocol_v2_parse_proxy_protocol_v1r   s       r.   r   zRequest._handle_proxy_protocol}  s     #hmNN8S) #hm >!c#2h/&A,,.003?? >!c"1g&:,,.003?? 
r:   c                     t        | j                  t              r_t        | j                  d   | j                  j
                  | j                  j                               st        | j                  d         yy)z2Check if proxy protocol is allowed from this peer.r   N)r|   r_   r}   rW   r*   proxy_allow_ipsproxy_allow_networksr   rv   s    r.   r
  z#Request.proxy_protocol_access_check  s_    t~~u-%dnnQ&79Q9Q&*hh&C&C&EG'q(9::G .r:   c                    t        |      }d|vr"| j                  ||       t        |      }d|vr"|j                  d      }t        |d|       }t	        ||dz   d       }|j                  d      }t        |      dk7  rt        |      |d   }|d   }	|d   }
|dvrt        d	|z        |d
k(  rJ	 t        j                  t        j                  |	       t        j                  t        j                  |
       nN|dk(  rI	 t        j                  t        j                  |	       t        j                  t        j                  |
       	 t        |d         }t        |d         }d|cxk  rdk  rn nd|cxk  rdk  sn t        d|z        ||	||
|d| _        |S # t        $ r t        |      w xY w# t        $ r t        |      w xY w# t        $ r t        d|z        w xY w)z`Parse PROXY protocol v1 (text format).

        Returns buffer with v1 header consumed.
        r   Nr=   r   r  r2   r>   )TCP4TCP6zprotocol '%s' not supportedr  r  r]      zinvalid port %sr   i  r   client_addrclient_port
proxy_addr
proxy_port)r   r   r   r   r   r   r   r   socket	inet_ptonAF_INETOSErrorAF_INET6r   rQ   r   )rq   r^   r   r   r   r   	remainingbitsprotos_addrd_addrs_portd_ports                r.   r  z Request._parse_proxy_protocol_v1  s    SzT!NN8S):D T! ii D#J'd378n-	zz#t9>"4(( Qaa (("#@5#HIIF?-  8  8 f_-  &9  &9	=a\Fa\F f%%A,@5,@"#4t#;<< $!!  $
  7  -&t,,-  -&t,,-  	="#4t#;<<	=s&   3AF AF7 G F47GG'c                    t        |      dk  r!| j                  ||       t        |      dk  r!|d   }|d   }t        j                  dt	        |dd             d   }|dz  dz	  }|d	k7  rt        d
|z        |dz  }|t        j                  t        j                  fvrt        d|z        d|z   }t        |      |k  r!| j                  ||       t        |      |k  r!|t        j                  k(  rdddddd| _	        t        ||d       S |dz  dz	  }	|dz  }
|
t        j                  k7  rt        d      t	        |dd|z          }|	t        j                  k(  r|dk  rt        d      t        j                   t        j"                  |dd       }t        j                   t        j"                  |dd       }t        j                  d|dd       d   }t        j                  d|dd       d   }d}n|	t        j$                  k(  r|dk  rt        d      t        j                   t        j&                  |dd       }t        j                   t        j&                  |dd       }t        j                  d|dd       d   }t        j                  d|dd       d   }d}n<|	t        j(                  k(  rdddddd| _	        t        ||d       S t        d|	z        |||||d| _	        t        ||d       S )zbParse PROXY protocol v2 (binary format).

        Returns buffer with v2 header consumed.
           r     z>H   r      r]   r=   zunsupported version %d   zunsupported command %dr7   Nr  zonly TCP protocol is supportedz"insufficient address data for IPv4   
   r  $   z"insufficient address data for IPv6    "   r  r?   zunsupported address family %d)r   r   structunpackr   r   r1   r7   r8   r   r   rD   rE   r<   r@   r  	inet_ntopr  rA   r  r?   )rq   r^   r   ver_cmd	fam_protolengthra   commandtotal_header_sizefamilyprotocol	addr_datar!  r"  r#  r$  r   s                    r.   r  z Request._parse_proxy_protocol_v2  s    #hmNN8S) #hm b'G	tU3r":%67: T>a'a<$%=%GHH D.9??IOO<<$%=%GHH K#h**NN8S) #h** ioo%")##""(D$ S!2!3455 d"q(t# z((($%EFF#bf-.	X]]"{()MNN%%fnni!nEF%%fnni!nEF]]41R9!<F]]42b)9:1=FEx~~%{()MNN%%fooy2GF%%fooyB7GHF]]42b)9:1=F]]42b)9:1=FEx& #+##""(D$ S!2!3455 %%Dv%MNN $!!  $
  ./011r:   c                 2   |j                  dd      D cg c]  }t        |       }}t        |      dk7  rt        t        |            |d   | _        | j
                  j                  sbt        j                  | j                        rt        | j                        dt        |d         cxk  rdk  sn t        | j                        t        j                  | j                        st        | j                        | j
                  j                  r| j                  j                         | _        |d   | _        t        | j                        dk(  rt        t        |            | j                  dk(  r#| j                  dk7  rt        t        |            | j                  d	k7  rL| j                  dk7  r=| j                  j                  d
      s"d| j                  vrt        t        |            	 t!        | j                        }|j$                  xs d| _        |j&                  xs d| _        |j(                  xs d| _        t*        j                  |d         }|t-        |d         t/        |j1                  d            t/        |j1                  d            f| _        d| j2                  cxk  rdk  s.n | j
                  j4                  st-        | j2                        y y c c}w # t"        $ r t        t        |            w xY w)N    r=   r>   r      r2   rN   OPTIONSCONNECT/z://r   r   )r=   r   )r   r   r   r   r   r*   r   METHOD_BADCHAR_REr   r   r   r   r   r   r   r   r   rQ   r   r   r   
VERSION_REr   r   groupra   r   )rq   
line_bytesbitr  r   matchs         r.   r   zRequest.parse_request_line4  sz   -7-=-=dA-FGcS!GGt9>$\*%=>> 1g xx99 ''4*4;;77DG***4;;77!!$++.&t{{33 88((++++-DK 7 txx=A$\*%=>> 88s?t{{i7$\*%=>>
 KK9$HHO++C0)$\*%=>>	?%dhh/E JJ$"	[[&B
," $$T!W-=$T!W--EKKN+SQ-@A..88>>(66 ? /} Hf  	?$\*%=>>	?s   K3:K8 8Lc                     t         |           t        | j                  j                  t
              r%t        t        | j                  d            | _        y y )Nr   )	r   rp   r|   rd   readerr   r   r   r^   )rq   r   s    r.   rp   zRequest.set_body_readerx  s>    !dii&&	2\$--;<DI 3r:   )r2   r   )r   )r3   r4   r5   rt   r   rn   r   r   r   r   r  r   r
  r  r  r   rp   __classcell__)r   s   @r.   r   r     sV    3:1Un@+&:,;;z[2zB7H= =r:   r   )5enumr   rO   rer  r0  gunicorn.http.bodyr   r   r   r   gunicorn.http.errorsr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   gunicorn.utilr   r   r!   r#   r'   r/   r	  r1   r<   rD   r   rj   rl   RFC9110_5_6_2_TOKEN_SPECIALScompileescaper   rA  rB  r   	frozensetr   rW   rY   r   r9   r:   r.   <module>rS     s,  
   	   K K    ] \ 5 9   # <@ F w    #   2 2::'92995Q+RSTBJJx( RZZ*+
 %/BJJ/J$K !
 #, - # (A& A&HL=g L=r:   