§
    Ÿj&�  ã                   ó4  — d Z ddlZddlZddlmZ  G d„ de¦  «        Z G d„ de¦  «        Z G d„ d	e¦  «        Zd
Z	 e
d¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d „ d!e¦  «        Z G d"„ d#e¦  «        Z G d$„ d%e¦  «        Z G d&„ d'¦  «        Z G d(„ d)¦  «        ZdS )*zš
HTTP parser for ASGI workers.

Provides callback-based parsing using either the fast C parser (gunicorn_h1c)
or the pure Python PythonProtocol fallback.
é    N)ÚIntEnumc                   ó   — e Zd ZdZdS )Ú
ParseErrorz&Base error raised during HTTP parsing.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    úa/var/www/finuniver-perm.ru/html/student/venv/lib/python3.11/site-packages/gunicorn/asgi/parser.pyr   r      ó   € € € € € Ø0Ð0Ð0Ð0r   r   c                   ó   — e Zd ZdZdS )ÚInvalidProxyLinezInvalid PROXY protocol v1 line.Nr   r   r   r   r   r      s   € € € € € Ø)Ð)Ð)Ð)r   r   c                   ó   — e Zd ZdZdS )ÚInvalidProxyHeaderz!Invalid PROXY protocol v2 header.Nr   r   r   r   r   r      s   € € € € € Ø+Ð+Ð+Ð+r   r   s   

 
QUIT
)s   hostó   content-lengthó   transfer-encodings   trailers   authorizations   tec                   ó   — e Zd ZdZdZdZdS )Ú	PPCommandzPROXY protocol v2 commands.r   é   N)r   r   r	   r
   ÚLOCALÚPROXYr   r   r   r   r   -   s   € € € € € Ø%Ð%Ø€EØ€E€E€Er   r   c                   ó"   — e Zd ZdZdZdZdZdZdS )ÚPPFamilyz#PROXY protocol v2 address families.r   r   é   é   N)r   r   r	   r
   ÚUNSPECÚINETÚINET6ÚUNIXr   r   r   r   r   3   s(   € € € € € Ø-Ð-Ø€FØ€DØ€EØ€D€D€Dr   r   c                   ó   — e Zd ZdZdZdZdZdS )Ú
PPProtocolz&PROXY protocol v2 transport protocols.r   r   r   N)r   r   r	   r
   r   ÚSTREAMÚDGRAMr   r   r   r#   r#   ;   s#   € € € € € Ø0Ð0Ø€FØ€FØ€E€E€Er   r#   c                   ó   — e Zd ZdZdS )ÚLimitRequestLinez&Request line exceeds configured limit.Nr   r   r   r   r'   r'   B   r   r   r'   c                   ó   — e Zd ZdZdS )ÚLimitRequestHeadersz+Too many headers or header field too large.Nr   r   r   r   r)   r)   F   s   € € € € € Ø5Ð5Ð5Ð5r   r)   c                   ó   — e Zd ZdZdS )ÚInvalidRequestLinezInvalid request line.Nr   r   r   r   r+   r+   J   ó   € € € € € ØÐÐÐr   r+   c                   ó   — e Zd ZdZdS )ÚInvalidRequestMethodzInvalid HTTP method.Nr   r   r   r   r.   r.   N   ó   € € € € € ØÐÐÐr   r.   c                   ó   — e Zd ZdZdS )ÚInvalidHTTPVersionzInvalid HTTP version.Nr   r   r   r   r1   r1   R   r,   r   r1   c                   ó   — e Zd ZdZdS )ÚInvalidHeaderNamezInvalid header name.Nr   r   r   r   r3   r3   V   r/   r   r3   c                   ó   — e Zd ZdZdS )ÚInvalidHeaderzInvalid header value.Nr   r   r   r   r5   r5   Z   r,   r   r5   c                   ó   — e Zd ZdZdS )ÚUnsupportedTransferCodingz$Unsupported Transfer-Encoding value.Nr   r   r   r   r7   r7   ^   s   € € € € € Ø.Ð.Ð.Ð.r   r7   c                   ó   — e Zd ZdZdS )ÚInvalidChunkSizez0Invalid chunk size in chunked transfer encoding.Nr   r   r   r   r9   r9   b   s   € € € € € Ø:Ð:Ð:Ð:r   r9   c                   ó   — e Zd ZdZdS )ÚInvalidChunkExtensionz%Invalid chunk extension per RFC 9112.Nr   r   r   r   r;   r;   f   s   € € € € € Ø/Ð/Ð/Ð/r   r;   c                   ó    — e Zd ZdZdZ	 	 	 	 	 	 	 	 	 	 	 	 dd„Zd	„ Zed
„ ¦   «         Zd„ Z	d„ Z
d„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ ZdS )ÚPythonProtocola‡  Callback-based HTTP/1.1 parser (pure Python fallback).

    Mirrors H1CProtocol interface for seamless switching between
    the C extension and pure Python implementations.

    Callbacks:
        on_message_begin: () -> None - Called when request starts
        on_url: (url: bytes) -> None - Called with request URL/path
        on_header: (name: bytes, value: bytes) -> None - Called for each header
        on_headers_complete: () -> bool - Called when headers done (return True to skip body)
        on_body: (chunk: bytes) -> None - Called with body data chunks
        on_message_complete: () -> None - Called when request is complete
    )Ú_on_message_beginÚ_on_urlÚ
_on_headerÚ_on_headers_completeÚ_on_bodyÚ_on_message_completeÚ_stateÚ_bufferÚ_headers_listÚmethodÚpathÚhttp_versionÚheadersÚcontent_lengthÚ
is_chunkedÚshould_keep_aliveÚis_completeÚ_body_remainingÚ
_skip_bodyÚ_chunk_stateÚ_chunk_sizeÚ_chunk_remainingÚ_limit_request_lineÚ_limit_request_fieldsÚ_limit_request_field_sizeÚ"_permit_unconventional_http_methodÚ#_permit_unconventional_http_versionÚ_header_countÚ_proxy_protocolÚ_proxy_protocol_infoÚ_proxy_protocol_doneNéþ  éd   FÚoffc                 óè  — || _         || _        || _        || _        || _        || _        || _        || _        |	| _        |
| _	        || _
        d| _        || _        d | _        |dk    | _        |dk    rdnd| _        t!          ¦   «         | _        g | _        d | _        d | _        d | _        g | _        d | _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d S )Nr   r_   Úproxy_protocolÚrequest_lineFTÚsize) r>   r?   r@   rA   rB   rC   rT   rU   rV   rW   rX   rY   rZ   r[   r\   rD   Ú	bytearrayrE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   )ÚselfÚon_message_beginÚon_urlÚ	on_headerÚon_headers_completeÚon_bodyÚon_message_completeÚlimit_request_lineÚlimit_request_fieldsÚlimit_request_field_sizeÚ!permit_unconventional_http_methodÚ"permit_unconventional_http_versionra   s                r   Ú__init__zPythonProtocol.__init__‡   s  € ð "2ˆÔØˆŒØ#ˆŒØ$7ˆÔ!ØˆŒØ$7ˆÔ!ð $6ˆÔ Ø%9ˆÔ"Ø)AˆÔ&Ø2SˆÔ/Ø3UˆÔ0ØˆÔð  .ˆÔØ$(ˆÔ!Ø$2°eÒ$;ˆÔ!ð +9¸EÒ*AÐ*AÐ&Ð&À~ˆŒÝ ‘{”{ˆŒØˆÔð ˆŒØˆŒ	Ø ˆÔØˆŒØ"ˆÔØˆŒØ!%ˆÔØ ˆÔð  !ˆÔØˆŒð #ˆÔØˆÔØ !ˆÔÐÐr   c                 ó²  — | j                              |¦  «         | j         rµ| j        dk    r|                      ¦   «         sdS nŠ| j        dk    r|                      ¦   «         sdS nh| j        dk    r|                      ¦   «         sdS nF| j        dk    r|                      ¦   «         sdS n$| j        dk    r|                      ¦   «         sdS ndS | j         °³dS dS )zÃProcess data, fire callbacks synchronously.

        Args:
            data: bytes or bytearray of incoming data

        Raises:
            ParseError: If the HTTP request is malformed
        ra   rb   rJ   ÚbodyÚchunkedN)rE   ÚextendrD   Ú_parse_proxy_protocolÚ_parse_request_lineÚ_parse_headersÚ_parse_bodyÚ_parse_chunked_body)re   Údatas     r   ÚfeedzPythonProtocol.feedÂ   s#  € ð 	Œ×Ò˜DÑ!Ô!Ð!àŒlð 	ØŒ{Ð.Ò.Ð.Ø×1Ò1Ñ3Ô3ð Ø�Eðà” Ò.Ð.Ø×/Ò/Ñ1Ô1ð Ø�Eðà” 	Ò)Ð)Ø×*Ò*Ñ,Ô,ð Ø�Eðà” Ò&Ð&Ø×'Ò'Ñ)Ô)ð Ø�Eðà” 	Ò)Ð)Ø×/Ò/Ñ1Ô1ð Ø�Eðð �ð# Œlð 	ð 	ð 	ð 	ð 	r   c                 ó   — | j         S )z%Return proxy protocol info if parsed.)r[   ©re   s    r   Úproxy_protocol_infoz"PythonProtocol.proxy_protocol_infoà   s   € ð Ô(Ð(r   c                 ó  — d| _         | j                             ¦   «          g | _        d| _        d| _        d| _        g | _        d| _        d| _	        d| _
        d| _        d| _        d| _        d| _        d| _        d| _        d| _        dS )z#Reset for next request (keepalive).rb   NFTr   rc   )rD   rE   ÚclearrF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rY   r~   s    r   ÚresetzPythonProtocol.resetå   s–   € à$ˆŒØŒ×ÒÑÔÐØˆÔØˆŒØˆŒ	Ø ˆÔØˆŒØ"ˆÔØˆŒØ!%ˆÔØ ˆÔØ ˆÔØˆŒØ"ˆÔØˆÔØ !ˆÔØˆÔÐÐr   c                 ó�   — | j         dk    r6| j        dk    r-d| _         d| _        | j        r|                      ¦   «          dS dS dS dS )z¯Mark parsing complete for EOF handling.

        Call when no more data will be received. Handles edge cases like
        chunked encoding without final trailer CRLF.
        rt   ÚtrailerÚcompleteTN)rD   rQ   rN   rC   r~   s    r   ÚfinishzPythonProtocol.finishù   sh   € ð Œ;˜)Ò#Ð#¨Ô(9¸YÒ(FÐ(Fà$ˆDŒKØ#ˆDÔØÔ(ð ,Ø×)Ò)Ñ+Ô+Ð+Ð+Ð+ð $Ð#Ð(FÐ(Fð,ð ,r   c                 ó  — t          | j        ¦  «        dk     rdS | j        }|dv r,| j        dd…         t          k    r|                      ¦   «         S |dv r'| j        dd…         dk    r|                      ¦   «         S d| _        d	| _        dS )
z˜Parse PROXY protocol header if enabled.

        Returns True if parsing is complete (or not applicable),
        False if more data is needed.
        é   F)Úv2ÚautoN)Úv1rŠ   é   s   PROXY Trb   )ÚlenrE   rZ   ÚPP_V2_SIGNATUREÚ_parse_proxy_protocol_v2Ú_parse_proxy_protocol_v1r\   rD   )re   Úmodes     r   rv   z$PythonProtocol._parse_proxy_protocol  s¤   € õ ˆtŒ|ÑÔ˜rÒ!Ð!Ø�5àÔ#ˆð �>Ð!Ð! d¤l°3°B°3Ô&7½?Ò&JÐ&JØ×0Ò0Ñ2Ô2Ð2ð �>Ð!Ð! d¤l°2°A°2Ô&6¸)Ò&CÐ&CØ×0Ò0Ñ2Ô2Ð2ð %)ˆÔ!Ø$ˆŒØˆtr   c                 óŠ  — | j                              d¦  «        }|dk    r)t          | j         ¦  «        dk    rt          d¦  «        ‚dS t	          | j         d|…         ¦  «                             d¦  «        }| j         d|dz   …= |                     d	¦  «        }t          |¦  «        dk     rt          d
¦  «        ‚|d                              ¦   «         }|dk    rddddddœ| _        �nI|dv �r2t          |¦  «        dk    rt          d|z  ¦  «        ‚|d         }|d         }|dk    rt          j
        nt          j        }	 t          j        ||¦  «         t          j        ||¦  «         n'# t          t          f$ r t          d|z  ¦  «        ‚w xY w	 t          |d         ¦  «        }t          |d         ¦  «        }	n$# t          $ r}
t          d|
z  ¦  «        ‚d}
~
ww xY wd|cxk    rdk    rn nd|	cxk    rdk    sn t          d¦  «        ‚|||||	dœ| _        nt          d|z  ¦  «        ‚d| _        d| _        dS )z|Parse PROXY protocol v1 (text format).

        Format: PROXY <PROTO> <SRC_ADDR> <DST_ADDR> <SRC_PORT> <DST_PORT>

        ó   
éÿÿÿÿék   zPROXY v1 header too longFNúlatin-1r   ú zInvalid PROXY v1 liner   ÚUNKNOWN©ra   Úclient_addrÚclient_portÚ
proxy_addrÚ
proxy_port)ÚTCP4ÚTCP6rŒ   zInvalid PROXY v1 line for %sr   rž   zInvalid PROXY v1 %s addressé   é   zInvalid PROXY v1 port: %sr   iÿÿ  zInvalid PROXY v1 port rangezUnknown PROXY v1 protocol: %sTrb   )rE   Úfindr�   r   ÚbytesÚdecodeÚsplitÚupperr[   ÚsocketÚAF_INETÚAF_INET6Ú	inet_ptonÚOSErrorÚ
ValueErrorÚintr\   rD   )re   ÚidxÚlineÚpartsÚprotoÚs_addrÚd_addrÚafÚs_portÚd_portÚes              r   r�   z'PythonProtocol._parse_proxy_protocol_v1  s¯  € ð Œl×Ò Ñ(Ô(ˆØ�"Š9ˆ9å�4”<Ñ Ô  3Ò&Ð&Ý&Ð'AÑBÔBÐBØ�5å�T”\ $ 3 $Ô'Ñ(Ô(×/Ò/°	Ñ:Ô:ˆØŒL˜˜# ™'˜Ð"ð —
’
˜3‘”ˆÝˆu‰:Œ:˜Š>ˆ>Ý"Ð#:Ñ;Ô;Ð;à�a”—’Ñ Ô ˆà�IÒÐð #,Ø#Ø#Ø"Ø"ð)ð )ˆDÔ%Ñ%ð Ð&Ð&Ñ&Ý�5‰zŒz˜QŠˆÝ&Ð'EÈÑ'MÑNÔNÐNà˜1”XˆFØ˜1”XˆFð $)¨F¢? ?•”�½¼ˆBðNÝÔ   VÑ,Ô,Ð,ÝÔ   VÑ,Ô,Ð,Ð,øÝ�ZÐ(ð Nð Nð NÝ&Ð'DÀuÑ'LÑMÔMÐMðNøøøðHÝ˜U 1œX™œ�Ý˜U 1œX™œ��øÝð Hð Hð HÝ&Ð'BÀQÑ'FÑGÔGÐGøøøøðHøøøð ˜Ð(Ð(Ò(Ð( 5Ò(Ð(Ð(Ð(Ð(¨Q°&Ð-AÐ-AÒ-AÐ-A¸EÒ-AÐ-AÐ-AÐ-AÝ&Ð'DÑEÔEÐEð #(Ø%Ø%Ø$Ø$ð)ð )ˆDÔ%Ð%õ #Ð#BÀUÑ#JÑKÔKÐKà$(ˆÔ!Ø$ˆŒØˆts$   Å*E0 Å0$FÆ*G Ç
G$ÇGÇG$c                 ó  — t          | j        ¦  «        dk     rdS | j        d         }| j        d         }t          j        dt	          | j        dd…         ¦  «        ¦  «        d         }|dz  d	z	  }|d
k    rt          d|z  ¦  «        ‚|dz  }|t          j        t          j        fvrt          d|z  ¦  «        ‚d|z   }t          | j        ¦  «        |k     rdS t	          | j        d|…         ¦  «        }| j        d|…= |t          j        k    rddddddœ| _	        d| _
        d| _        dS |dz  d	z	  }|dz  }	|t          j        t          j        fv r|	t          j        k    rt          d¦  «        ‚|t          j        k    rºt          |¦  «        dk     rt          d¦  «        ‚d                     d„ |dd	…         D ¦   «         ¦  «        }
d                     d„ |d	d…         D ¦   «         ¦  «        }t          j        d|dd…         ¦  «        d         }t          j        d|dd…         ¦  «        d         }d}�n2|t          j        k    rãt          |¦  «        dk     rt          d¦  «        ‚t          j        d|dd…         ¦  «        }t          j        d|dd…         ¦  «        }d                     d „ |D ¦   «         ¦  «        }
d                     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œ| _	        d| _
        d| _        dS t          d%|z  ¦  «        ‚||
|||dœ| _	        d| _
        d| _        dS )&z(Parse PROXY protocol v2 (binary format).é   Frˆ   é   z>Hé   r   éð   r    r   z Unsupported PROXY v2 version: %dé   z Unsupported PROXY v2 command: %dNr   r™   Trb   z1PROXY v2: only TCP (STREAM) protocol is supportedz"Invalid PROXY v2 IPv4 address dataú.c              3   ó4   K  — | ]}t          |¦  «        V — Œd S ©N©Ústr©Ú.0Úbs     r   ú	<genexpr>z:PythonProtocol._parse_proxy_protocol_v2.<locals>.<genexpr>   s(   è è € Ð<Ð<¨�c !™fœfÐ<Ð<Ð<Ð<Ð<Ð<r   c              3   ó4   K  — | ]}t          |¦  «        V — Œd S rÀ   rÁ   rÃ   s     r   rÆ   z:PythonProtocol._parse_proxy_protocol_v2.<locals>.<genexpr>¡  s(   è è € Ð=Ð=¨�c !™fœfÐ=Ð=Ð=Ð=Ð=Ð=r   é   é
   rž   é$   z"Invalid PROXY v2 IPv6 address dataz>8Hé    ú:c              3   ó    K  — | ]	}d |z  V — Œ
dS ©z%xNr   ©rÄ   Úws     r   rÆ   z:PythonProtocol._parse_proxy_protocol_v2.<locals>.<genexpr>­  ó&   è è € Ð8Ð8¨1˜d Q™hÐ8Ð8Ð8Ð8Ð8Ð8r   c              3   ó    K  — | ]	}d |z  V — Œ
dS rÎ   r   rÏ   s     r   rÆ   z:PythonProtocol._parse_proxy_protocol_v2.<locals>.<genexpr>®  rÑ   r   é"   rŸ   r   z'Unsupported PROXY v2 address family: %d)r�   rE   ÚstructÚunpackr£   r   r   r   r   r[   r\   rD   r   r   r    r#   r$   Újoinr   )re   Úver_cmdÚfam_protÚlengthÚversionÚcommandÚ
total_sizeÚ	addr_dataÚfamilyÚprotocolr²   r³   rµ   r¶   r±   Ús_wordsÚd_wordss                    r   r�   z'PythonProtocol._parse_proxy_protocol_v2f  sÚ  € õ ˆtŒ|ÑÔ˜rÒ!Ð!Ø�5ð ”,˜rÔ"ˆØ”< Ô#ˆÝ”˜t¥U¨4¬<¸¸2¸Ô+>Ñ%?Ô%?Ñ@Ô@ÀÔCˆð ˜T‘> aÑ'ˆØ�aŠ<ˆ<Ý$Ð%GÈ'Ñ%QÑRÔRÐRð ˜D‘.ˆØ�9œ?­I¬OÐ<Ð<Ð<Ý$Ð%GÈ'Ñ%QÑRÔRÐRð ˜&‘[ˆ
ÝˆtŒ|ÑÔ˜zÒ)Ð)Ø�5õ ˜$œ, r¨* }Ô5Ñ6Ô6ˆ	ØŒL˜˜*˜Ð%ð •i”oÒ%Ð%à")Ø#Ø#Ø"Ø"ð)ð )ˆDÔ%ð )-ˆDÔ%Ø(ˆDŒKØ�4ð ˜T‘/ aÑ'ˆØ˜d‘?ˆð •h”m¥X¤^Ð4Ð4Ð4¸ÅZÔEVÒ9VÐ9VÝ$ØCñô ð ð •X”]Ò"Ð"å�9‰~Œ~ Ò"Ð"Ý(Ð)MÑNÔNÐNØ—X’XÐ<Ð<¨i¸¸¸¬mÐ<Ñ<Ô<Ñ<Ô<ˆFØ—X’XÐ=Ð=¨i¸¸!¸¬nÐ=Ñ=Ô=Ñ=Ô=ˆFÝ”] 4¨°1°R°4¬Ñ9Ô9¸!Ô<ˆFÝ”] 4¨°2°b°5Ô)9Ñ:Ô:¸1Ô=ˆFØˆE‰Eà•x”~Ò%Ð%å�9‰~Œ~ Ò"Ð"Ý(Ð)MÑNÔNÐNå”m E¨9°S°b°S¬>Ñ:Ô:ˆGÝ”m E¨9°R¸°UÔ+;Ñ<Ô<ˆGØ—X’XÐ8Ð8°Ð8Ñ8Ô8Ñ8Ô8ˆFØ—X’XÐ8Ð8°Ð8Ñ8Ô8Ñ8Ô8ˆFÝ”] 4¨°2°b°5Ô)9Ñ:Ô:¸1Ô=ˆFÝ”] 4¨°2°b°5Ô)9Ñ:Ô:¸1Ô=ˆFØˆEˆEà•x”Ò&Ð&ð #+Ø#Ø#Ø"Ø"ð)ð )ˆDÔ%ð )-ˆDÔ%Ø(ˆDŒKØ�4õ %Ð%NÐQWÑ%WÑXÔXÐXð $Ø!Ø!Ø Ø ð%
ð %
ˆÔ!ð %)ˆÔ!Ø$ˆŒØˆtr   c                 ó&  — | j                              d¦  «        }|dk    rdS | j        dk    r|| j        k    rt          d¦  «        ‚t	          | j         d|…         ¦  «        }| j         d|dz   …= |                     dd¦  «        }t          |¦  «        d	k    rt          d
¦  «        ‚|d         | _        |d         | _	        | j
        sA|                      | j        ¦  «        s't          | j                             d¦  «        ¦  «        ‚| j	        dk    r| j        dk    rt          d
¦  «        ‚| j        dk    r=| j	        dk    r2| j	                             d¦  «        sd| j	        vrt          d
¦  «        ‚|d         }|dk    rd| _        nÀ|dk    rd| _        n²| j        s"t#          |                     d¦  «        ¦  «        ‚|                     d¦  «        rR	 t%          |dd…         ¦  «        }d|f| _        nR# t&          $ r# t#          |                     d¦  «        ¦  «        ‚w xY wt#          |                     d¦  «        ¦  «        ‚| j        r|                      ¦   «          | j        r|                      | j	        ¦  «         d| _        dS )z,Parse request line, return True if complete.r“   r”   Fr   zRequest line is too largeNr   ó    r   zInvalid request liner   r–   ó   *s   OPTIONSs   CONNECTó   /s   ://s   HTTP/1.1©r   r   s   HTTP/1.0©r   r   s   HTTP/1.é   rJ   T)rE   r¢   rT   r'   r£   r¥   r�   r+   rG   rH   rW   Ú_is_valid_methodr.   r¤   Ú
startswithrI   rX   r1   r­   r¬   r>   r?   rD   )re   r®   r¯   r°   rÚ   Úminors         r   rw   z"PythonProtocol._parse_request_lineÏ  s½  € àŒl×Ò Ñ(Ô(ˆØ�"Š9ˆ9Ø�5ð Ô# aÒ'Ð'¨C°$Ô2JÒ,JÐ,JÝ"Ð#>Ñ?Ô?Ð?å�T”\ $ 3 $Ô'Ñ(Ô(ˆØŒL˜˜# ™'˜Ð"ð —
’
˜4 Ñ#Ô#ˆÝˆu‰:Œ:˜Š?ˆ?Ý$Ð%;Ñ<Ô<Ð<à˜A”hˆŒØ˜!”HˆŒ	ð Ô6ð 	JØ×(Ò(¨¬Ñ5Ô5ð JÝ*¨4¬;×+=Ò+=¸iÑ+HÔ+HÑIÔIÐIð Œ9˜ÒÐ ¤°
Ò!:Ð!:Ý$Ð%;Ñ<Ô<Ð<ð ŒK˜:Ò%Ð%Ø”I Ò%Ð%Øœ	×,Ò,¨TÑ2Ô2ð &à $¤)Ð+Ð+Ý$Ð%;Ñ<Ô<Ð<ð ˜”(ˆØ�kÒ!Ð!Ø &ˆDÔÐØ˜Ò#Ð#Ø &ˆDÔÐàÔ;ð DÝ(¨¯ª¸	Ñ)BÔ)BÑCÔCÐCà×!Ò! *Ñ-Ô-ð DðHÝ ¨¨¨¤Ñ,Ô,�EØ)*¨E¨
�DÔ%Ð%øÝ!ð Hð Hð HÝ,¨W¯^ª^¸IÑ-FÔ-FÑGÔGÐGðHøøøõ )¨¯ª¸	Ñ)BÔ)BÑCÔCÐCàÔ!ð 	%Ø×"Ò"Ñ$Ô$Ð$ØŒ<ð 	$Ø�LŠL˜œÑ#Ô#Ð#àˆŒØˆts   Ç G< Ç<-H)c                 óÆ  — 	 | j                              d¦  «        }|dk    rdS t          | j         d|…         ¦  «        }| j         d|dz   …= |s|                      ¦   «          dS | j        dk    r*t          |¦  «        dz   | j        k    rt          d¦  «        ‚| xj        d	z  c_        | j        dk    r| j        | j        k    rt          d
¦  «        ‚|                     d¦  «        }|dk    rt          d¦  «        ‚|d|…          
                    ¦   «         }|                      |¦  «        s"t          |                     d¦  «        ¦  «        ‚||d	z   d…          
                    ¦   «         }|                      |¦  «        rt          d¦  «        ‚|                     ¦   «         }| j                             ||f¦  «         | j        r|                      ||¦  «         �Œá)z3Parse headers, return True if headers are complete.Tr“   r”   FNr   r   z!Request header field is too larger   zToo many headersó   :zMissing colon in headerr–   z"Invalid characters in header value)rE   r¢   r£   Ú_finalize_headersrV   r�   r)   rY   rU   r5   ÚstripÚ_is_valid_tokenr3   r¤   Ú_has_invalid_header_charsÚlowerrF   Úappendr@   )re   r®   r¯   ÚcolonÚnameÚvalueÚ
name_lowers          r   rx   zPythonProtocol._parse_headers  sò  € ð(	3Ø”,×#Ò# GÑ,Ô,ˆCØ�bŠyˆyØ�uå˜œ d s dÔ+Ñ,Ô,ˆDØ”˜X˜c A™g˜XÐ&àð à×&Ò&Ñ(Ô(Ð(Ø�tð Ô-°Ò1Ð1µc¸$±i´iÀ!±mÀdÔFdÒ6dÐ6dÝ)Ð*MÑNÔNÐNð ÐÔ !Ñ#ÐÔØÔ)¨AÒ-Ð-°$Ô2DÀtÔGaÒ2aÐ2aÝ)Ð*<Ñ=Ô=Ð=ð —I’I˜d‘O”OˆEØ˜Š{ˆ{Ý#Ð$=Ñ>Ô>Ð>à˜˜˜”<×%Ò%Ñ'Ô'ˆDØ×'Ò'¨Ñ-Ô-ð @Ý'¨¯ª°IÑ(>Ô(>Ñ?Ô?Ð?à˜ ™˜˜Ô$×*Ò*Ñ,Ô,ˆEØ×-Ò-¨eÑ4Ô4ð JÝ#Ð$HÑIÔIÐIð Ÿš™œˆJØÔ×%Ò% z°5Ð&9Ñ:Ô:Ð:àŒð 3Ø—’ 
¨EÑ2Ô2Ð2ñQ(	3r   c                 óZ  — | j         | _        d}d}| j        D �]E\  }}|dk    rW|�t          d¦  «        ‚	 t          |¦  «        }n# t          $ r t          d¦  «        ‚w xY w|dk     rt          d¦  «        ‚|}Œc|dk    rªd	„ |                     d
¦  «        D ¦   «         }|D ]†}|                     ¦   «         }|dk    r|rt          d¦  «        ‚d}Œ0|dk    r|rt          d¦  «        ‚ŒH|dv r|rt          d¦  «        ‚d| _        Œet          | 	                    d¦  «        ¦  «        ‚�Œ|dk    r,|                     ¦   «         }d|v r	d| _        �Œ:d|v rd| _        �ŒG|rA| j
        dk     rt          d¦  «        ‚|�t          d¦  «        ‚d| _        d| _        d| _        n|�|| _        || _        nd| _        d| _        | j
        dk    r.| j        r't          d„ | j        D ¦   «         ¦  «        }	|	sd| _        | j        r|                      ¦   «         | _        | j        r-d| _        d| _        | j        r|                      ¦   «          dS dS | j        rd| _        d| _        dS | j        r| j        dk    r	d| _        dS d| _        d| _        | j        r|                      ¦   «          dS dS )ay  Called when all headers received.

        Validates headers for request smuggling vulnerabilities:
        - Rejects duplicate Content-Length headers
        - Rejects requests with both Content-Length and Transfer-Encoding
        - Rejects chunked Transfer-Encoding in HTTP/1.0
        - Rejects stacked chunked encoding
        - Validates Transfer-Encoding values
        NFr   zDuplicate Content-Length headerzInvalid Content-Length valuer   zNegative Content-Lengthr   c                 ó6   — g | ]}|                      ¦   «         ‘ŒS r   )rï   )rÄ   Úvs     r   ú
<listcomp>z4PythonProtocol._finalize_headers.<locals>.<listcomp>[  s    € Ð=Ð=Ð= a˜Ÿš™	œ	Ð=Ð=Ð=r   ó   ,s   chunkedzStacked chunked encodingTs   identityz'Invalid Transfer-Encoding after chunked)s   compresss   deflates   gzipr–   ó
   connections   closeó
   keep-aliveræ   z(Chunked encoding not allowed in HTTP/1.0z%Content-Length with Transfer-Encodingr”   rç   c              3   óT   K  — | ]#\  }}|d k    od|                      ¦   «         v V — Œ$dS )rý   rþ   N)rò   )rÄ   rõ   rö   s      r   rÆ   z3PythonProtocol._finalize_headers.<locals>.<genexpr>Ž  sQ   è è € ð  ð  á�D˜%ð ˜Ò%ÐH¨-¸5¿;º;¹=¼=Ð*Hð ð  ð  ð  ð  ð  r   r…   rt   rc   rs   )rF   rJ   r5   r­   r¬   r¥   rò   rM   r7   r¤   rI   rL   rK   rO   ÚanyrA   rP   rD   rN   rC   rQ   )
re   rK   rt   rõ   rö   Úcl_valueÚvalsÚvalÚ	val_lowerÚhas_keepalives
             r   rî   z PythonProtocol._finalize_headers;  sŸ  € ð Ô)ˆŒð ˆØˆàœ<ð +	2ñ +	2‰KˆD�%ØÐ(Ò(Ð(à!Ð-Ý'Ð(IÑJÔJÐJðHÝ" 5™zœz�H�HøÝ!ð Hð Hð HÝ'Ð(FÑGÔGÐGðHøøøà˜a’<�<Ý'Ð(AÑBÔBÐBØ!)��àÐ-Ò-Ð-ð >Ð=¨5¯;ª;°tÑ+<Ô+<Ð=Ñ=Ô=�Øð Oð O�CØ #§	¢	¡¤�IØ  JÒ.Ð.à"ð LÝ"/Ð0JÑ"KÔ"KÐKØ"&˜˜Ø" kÒ1Ð1à"ð [Ý"/Ð0YÑ"ZÔ"ZÐZð[à"Ð&HÐHÐHà"ð [Ý"/Ð0YÑ"ZÔ"ZÐZà16˜Ô.Ð.õ 8¸¿
º
À9Ñ8MÔ8MÑNÔNÐNñ'Oð* ˜Ò&Ð&Ø—k’k‘m”m�Ø˜s�?�?Ø-2�DÔ*Ñ*Ø" cÐ)Ð)Ø-1�DÔ*ùð ð 	%àÔ  6Ò)Ð)Ý#Ð$NÑOÔOÐOàÐ)Ý#Ð$KÑLÔLÐLØ"ˆDŒOØ"&ˆDÔØ#%ˆDÔ Ð ØÐ'Ø"0ˆDÔØ#1ˆDÔ Ð ð #'ˆDÔØ#$ˆDÔ ð Ô Ò&Ð&¨4Ô+AÐ&åð  ð  à#'¤<ð ñ  ô  ñ ô ˆMð !ð /Ø).�Ô&àÔ$ð 	:Ø"×7Ò7Ñ9Ô9ˆDŒOð Œ?ð 	,Ø$ˆDŒKØ#ˆDÔØÔ(ð ,Ø×)Ò)Ñ+Ô+Ð+Ð+Ð+ð,ð ,àŒ_ð 
	,Ø#ˆDŒKØ &ˆDÔÐÐØÔ ð 	, TÔ%8¸1Ò%<Ð%<Ø ˆDŒKˆKˆKð %ˆDŒKØ#ˆDÔØÔ(ð ,Ø×)Ò)Ñ+Ô+Ð+Ð+Ð+ð,ð ,s   ¶AÁA c                 óˆ  — | j         r| j        dk    rdS t          t          | j         ¦  «        | j        ¦  «        }t	          | j         d|…         ¦  «        }| j         d|…= | xj        |z  c_        | j        r|                      |¦  «         | j        dk    r)d| _        d| _        | j        r|                      ¦   «          dS )z$Parse Content-Length delimited body.r   FNr…   T)	rE   rO   Úminr�   r£   rB   rD   rN   rC   )re   Ú
chunk_sizeÚchunks      r   ry   zPythonProtocol._parse_bodyª  sÏ   € àŒ|ð 	˜tÔ3°qÒ8Ð8Ø�5å�˜Tœ\Ñ*Ô*¨DÔ,@ÑAÔAˆ
Ý�d”l ; J ;Ô/Ñ0Ô0ˆØŒL˜˜*˜Ð%ØÐÔ 
Ñ*ÐÔàŒ=ð 	!Ø�MŠM˜%Ñ Ô Ð àÔ 1Ò$Ð$Ø$ˆDŒKØ#ˆDÔØÔ(ð ,Ø×)Ò)Ñ+Ô+Ð+àˆtr   c                 óX  — | j         �r!| j        dk    �r=| j                              d¦  «        }|dk    rdS t          | j         d|…         ¦  «        }| j         d|dz   …= |                     d¦  «        }|dk    r*||dz   d…         }d	|v rt	          d
¦  «        ‚|d|…         }||                     ¦   «         k    rt          d¦  «        ‚|st          d¦  «        ‚|D ]}|dvrt          d¦  «        ‚Œ	 t          |d¦  «        | _        n# t          $ r t          d¦  «        ‚w xY w| j        dk    r	d| _        �nå| j        | _
        d| _        �nÐ| j        dk    r–| j         sdS t          t          | j         ¦  «        | j
        ¦  «        }t          | j         d|…         ¦  «        }| j         d|…= | xj
        |z  c_
        | j        r|                      |¦  «         | j
        dk    rd| _        �n/| j        dk    r,t          | j         ¦  «        dk     rdS | j         dd…= d| _        nø| j        dk    rí| j                              d¦  «        }|dk    rdS t          | j         d|…         ¦  «        }| j         d|dz   …= |s+d| _        d| _        | j        r|                      ¦   «          dS |                     d¦  «        }	|	dk    rZ|d|	…                              d¦  «                             ¦   «         }
|
t$          v r"t'          |
                     d¦  «        ¦  «        ‚| j         �°!dS )z Parse chunked transfer encoding.rc   r“   r”   FNr   ó   ;r   ó   zbare CR not allowedzWhitespace in chunk sizezEmpty chunk sizes   0123456789abcdefABCDEFzInvalid character in chunk sizer¹   zInvalid chunk sizer   r„   r{   Úcrlfr…   Trí   s    	r–   )rE   rQ   r¢   r£   r;   rï   r9   r­   rR   r¬   rS   r  r�   rB   rD   rN   rC   rò   ÚRFC9110_6_5_1_FORBIDDEN_TRAILERr3   r¤   )re   r®   Ú	size_lineÚ	semicolonÚ	chunk_extÚcÚto_readr	  r¯   rô   rõ   s              r   rz   z"PythonProtocol._parse_chunked_body¿  s¢  € àŒlñ Z	HØÔ  FÒ*Ñ*à”l×'Ò'¨Ñ0Ô0�Ø˜"’9�9Ø ˜5å! $¤,¨t°¨tÔ"4Ñ5Ô5�	Ø”L  #¨¡' Ð*ð &ŸNšN¨4Ñ0Ô0�	Ø ’?�?à )¨)°a©-¨.¨.Ô 9�IØ 	Ð)Ð)Ý3Ð4IÑJÔJÐJØ )¨*¨9¨*Ô 5�Ið  	§¢Ñ 1Ô 1Ò1Ð1Ý*Ð+EÑFÔFÐFØ ð ?Ý*Ð+=Ñ>Ô>Ð>ð #ð Rð R�AØÐ 9Ð9Ð9Ý.Ð/PÑQÔQÐQð :ðAÝ'*¨9°bÑ'9Ô'9�DÔ$Ð$øÝ!ð Að Að AÝ*Ð+?Ñ@Ô@Ð@ðAøøøð Ô# qÒ(Ð(à(1�DÔ%Ñ%à,0Ô,<�DÔ)Ø(.�DÔ%Ñ%àÔ" fÒ,Ð,à”|ð !Ø ˜5å�c $¤,Ñ/Ô/°Ô1FÑGÔG�Ý˜dœl¨8¨G¨8Ô4Ñ5Ô5�Ø”L  ' Ð*ØÐ%Ô%¨Ñ0Ð%Ô%à”=ð )Ø—M’M %Ñ(Ô(Ð(àÔ(¨AÒ-Ð-à(.�DÔ%ùàÔ" fÒ,Ð,å�t”|Ñ$Ô$ qÒ(Ð(Ø ˜5Ø”L  ! Ð$Ø$*�Ô!Ð!àÔ" iÒ/Ð/à”l×'Ò'¨Ñ0Ô0�Ø˜"’9�9Ø ˜5å˜Tœ\¨$¨3¨$Ô/Ñ0Ô0�Ø”L  #¨¡' Ð*àð  à",�D”KØ'+�DÔ$ØÔ0ð 4Ø×1Ò1Ñ3Ô3Ð3Ø˜4ð Ÿ	š	 $™œ�Ø˜1’9�9Ø   œ<×-Ò-¨fÑ5Ô5×;Ò;Ñ=Ô=�DØÕ>Ð>Ð>Ý/°·²¸IÑ0FÔ0FÑGÔGÐGðu Œlñ Z	Hðx ˆus   Ã6D ÄD&c                 óˆ   — |sdS dt          |¦  «        cxk    rdk    sn dS |D ]	}|dv r dS Œ
|                      |¦  «        S )z>Check if method is valid token with conventional restrictions.Fr   é   s   abcdefghijklmnopqrstuvwxyz#)r�   rð   )re   rG   r  s      r   ré   zPythonProtocol._is_valid_method  st   € àð 	Ø�5à•C˜‘K”KÐ%Ð%Ò%Ð% 2Ò%Ð%Ð%Ð%Ø�5àð 	ð 	ˆAØÐ2Ð2Ð2Ø�u�uð 3à×#Ò# FÑ+Ô+Ð+r   c                 óD   — |sdS |D ]}|dk     s|dk    r dS |dv r dS ŒdS )z6Check if data contains only RFC 9110 token characters.Fé!   é~   s   "(),/:;<=>?@[\]{}"Tr   )re   r{   r  s      r   rð   zPythonProtocol._is_valid_token,  sS   € àð 	Ø�5Øð 	ð 	ˆAØ�4Šxˆx˜1˜tš8˜8Ø�u�uàÐ*Ð*Ð*Ø�u�uð +àˆtr   c                 óL   — |D ] }|dk    sd|cxk    rdk    sn |dk    r dS Œ!dS )zARFC 9110 section 5.5: only VCHAR, SP, HTAB, and obs-text allowed.rÈ   rÉ   é   é   TFr   )re   rö   r  s      r   rñ   z(PythonProtocol._has_invalid_header_chars8  sQ   € àð 	ð 	ˆAØ�DŠyˆy˜D AÐ-Ð-Ò-Ð-¨Ò-Ð-Ð-Ð-°°d²°Ø�t�tð 2;àˆur   )NNNNNNr]   r^   r]   FFr_   )r   r   r	   r
   Ú	__slots__rq   r|   Úpropertyr   r‚   r†   rv   r�   r�   rw   rx   rî   ry   rz   ré   rð   rñ   r   r   r   r=   r=   j   s_  € € € € € ðð ð€Ið  ØØØ ØØ ØØ Ø!%Ø*/Ø+0Øð9"ð 9"ð 9"ð 9"ðvð ð ð< ð)ð )ñ „Xð)ðð ð ð(,ð ,ð ,ðð ð ð2Eð Eð EðNgð gð gðR>ð >ð >ð@*3ð *3ð *3ðXm,ð m,ð m,ð^ð ð ð*^ð ^ð ^ð@,ð ,ð ,ð
ð 
ð 
ðð ð ð ð r   r=   c                   ó@   — e Zd ZdZdZd„ Zed	d„¦   «         Zd„ Zd„ Z	dS )
ÚCallbackRequestzxRequest object built from callback parser state.

    Works with both H1CProtocol (C extension) and PythonProtocol.
    ©rG   ÚurirH   ÚqueryÚfragmentrÚ   rJ   Úheaders_bytesÚschemeÚraw_pathrK   rt   Ú
must_closer   Ú_expect_100_continuec                 óØ   — d | _         d | _        d | _        d | _        d | _        d | _        g | _        g | _        d| _        d| _	        d| _
        d| _        d| _        d | _        d| _        d S )NÚhttpr   r   Fr   r~   s    r   rq   zCallbackRequest.__init__M  su   € ØˆŒØˆŒØˆŒ	ØˆŒ
ØˆŒØˆŒØˆŒØˆÔØˆŒØˆŒØˆÔØˆŒØˆŒØ#'ˆÔ Ø$)ˆÔ!Ð!Ð!r   Fc                 óF  — ddl m}  | ¦   «         }|j                             d¦  «        |_        |j        }d|v r`|                     dd¦  «        \  }}||_         ||¦  «                             dd¬¦  «        |_        |                     d	¦  «        |_        n3||_         ||¦  «                             dd¬¦  «        |_        d
|_        |                     d	¦  «        |_        d
|_	        |j
        |_        t          t          |dd¦  «        p|j        ¦  «        |_        d„ |j        D ¦   «         |_        |rdnd|_        |j        pd|_        |j        |_        |j         |_        |j        D ],\  }}	|dk    r!|	                     ¦   «         dk    r	d|_         nŒ-|S )zåBuild request from callback parser state.

        Args:
            parser: H1CProtocol or PythonProtocol instance
            is_ssl: Whether connection is SSL/TLS

        Returns:
            CallbackRequest instance
        r   )Úunquote_to_bytesÚasciió   ?r   zutf-8Úreplace)Úerrorsr–   Ú Úasgi_headersNc                 óŒ   — g | ]A\  }}|                      d ¦  «                             ¦   «         |                      d ¦  «        f‘ŒBS )r–   )r¤   r¦   )rÄ   Únrú   s      r   rû   z/CallbackRequest.from_parser.<locals>.<listcomp>…  sU   € ð 
ð 
ð 
á��1ð �XŠX�iÑ Ô ×&Ò&Ñ(Ô(¨!¯(ª(°9Ñ*=Ô*=Ð>ð
ð 
ð 
r   Úhttpsr*  s   expects   100-continueT)Úurllib.parser,  rG   r¤   rH   r¥   r&  r"  r!  r#  rI   rÚ   ÚlistÚgetattrrJ   r$  r%  rK   rL   rt   rM   r'  rò   r(  )
ÚclsÚparserÚis_sslr,  ÚreqÚraw_urlÚ	path_partÚ
query_partrõ   rö   s
             r   Úfrom_parserzCallbackRequest.from_parser^  sÃ  € ð 	2Ð1Ð1Ð1Ð1Ð1àˆc‰eŒeˆØ”]×)Ò)¨'Ñ2Ô2ˆŒ
ð ”+ˆØ�7ˆ?ˆ?Ø$+§M¢M°$¸Ñ$:Ô$:Ñ!ˆI�zØ$ˆCŒLØ'Ð'¨	Ñ2Ô2×9Ò9¸'È)Ð9ÑTÔTˆCŒHØ"×)Ò)¨)Ñ4Ô4ˆCŒIˆIà"ˆCŒLØ'Ð'¨Ñ0Ô0×7Ò7¸È	Ð7ÑRÔRˆCŒHØˆCŒIà—.’. Ñ+Ô+ˆŒØˆŒØÔ)ˆŒõ
 !¥¨°ÀÑ!FÔ!FÐ!XÈ&Ì.ÑYÔYˆÔð
ð 
àœð
ñ 
ô 
ˆŒð
 !'Ð2�W�W¨FˆŒ
Ø#Ô2Ð7°aˆÔØÔ'ˆŒØ#Ô5Ð5ˆŒð "œ>ð 	ð 	‰KˆD�%Ø�yÒ Ð  U§[¢[¡]¤]°oÒ%EÐ%EØ+/�Ô(Ø�øàˆ
r   c                 óÆ   — | j         rdS | j        D ]F\  }}|dk    r;|                     ¦   «                              d¦  «        }|dk    r dS |dk    r dS  nŒG| j        dk    S )z8Check if connection should be closed after this request.TÚ
CONNECTIONz 	Úclosez
keep-aliveFrç   )r'  rJ   rò   rï   rÚ   )re   rõ   rö   rú   s       r   Úshould_closezCallbackRequest.should_close—  s‡   € àŒ?ð 	Ø�4Øœ<ð 	ð 	‰KˆD�%Ø�|Ò#Ð#Ø—K’K‘M”M×'Ò'¨Ñ.Ô.�Ø˜’<�<Ø˜4˜4Ø˜,Ò&Ð&Ø ˜5˜5Ø�ð $ð Œ|˜vÒ%Ð%r   c                 ó\   — |                      ¦   «         }| j        D ]\  }}||k    r|c S ŒdS )z.Get a header value by name (case-insensitive).N)r¦   rJ   )re   rõ   Úhrú   s       r   Ú
get_headerzCallbackRequest.get_header¥  s@   € à�zŠz‰|Œ|ˆØ”Lð 	ð 	‰DˆAˆqØ�DŠyˆyØ���ð àˆtr   N)F)
r   r   r	   r
   r  rq   Úclassmethodr@  rD  rG  r   r   r   r  r  @  ss   € € € € € ðð ð
€Ið*ð *ð *ð" ð6ð 6ð 6ñ „[ð6ðp&ð &ð &ðð ð ð ð r   r  )r
   r§   rÔ   Úenumr   Ú	Exceptionr   r   r   rŽ   Ú	frozensetr  r   r   r#   r'   r)   r+   r.   r1   r3   r5   r7   r9   r;   r=   r  r   r   r   ú<module>rL     sc  ðð
ð ð €€€Ø €€€Ø Ð Ð Ð Ð Ð ð1ð 1ð 1ð 1ð 1�ñ 1ô 1ð 1ð*ð *ð *ð *ð *�zñ *ô *ð *ð,ð ,ð ,ð ,ð ,˜ñ ,ô ,ð ,ð
 F€ð
 #, )ð -ñ #ô #Ð ðð ð ð ð �ñ ô ð ðð ð ð ð ˆwñ ô ð ðð ð ð ð �ñ ô ð ð1ð 1ð 1ð 1ð 1�zñ 1ô 1ð 1ð6ð 6ð 6ð 6ð 6˜*ñ 6ô 6ð 6ð ð  ð  ð  ð  ˜ñ  ô  ð  ðð ð ð ð ˜:ñ ô ð ð ð  ð  ð  ð  ˜ñ  ô  ð  ðð ð ð ð ˜
ñ ô ð ð ð  ð  ð  ð  �Jñ  ô  ð  ð/ð /ð /ð /ð / 
ñ /ô /ð /ð;ð ;ð ;ð ;ð ;�zñ ;ô ;ð ;ð0ð 0ð 0ð 0ð 0˜Jñ 0ô 0ð 0ðSð Sð Sð Sð Sñ Sô Sð Sðlkð kð kð kð kñ kô kð kð kð kr   