
    F\hE                         S r / SQrSSKrSrSrSr/ SQr/ SQrSSSSS	S
SS	SSSSSSS.rS r	S r
S rS rS r " S S5      r " S S\5      rg)zcEmail address parsing code.

Lifted directly from rfc822.py.  This should eventually be rewritten.
)	mktime_tz	parsedateparsedate_tzquote    N  z, )janfebmaraprmayjunjulaugsepoctnovdecjanuaryfebruarymarchaprilr   junejulyaugust	septemberoctobernovemberdecember)montuewedthufrisatsunipiiiiDi)UTUTCGMTZASTADTESTEDTCSTCDTMSTMDTPSTPDTc                 T    [        U 5      nU(       d  gUS   c  SUS'   [        U5      $ )zIConvert a date string to a time tuple.

Accounts for military timezones.
N	   r   )_parsedate_tztuple)dataress     '/usr/lib/python3.13/email/_parseaddr.pyr   r   -   s0    
 
C
1v~A:    c           
         U (       d  gU R                  5       n U (       d  gU S   R                  S5      (       d  U S   R                  5       [        ;   a  U S	 O(U S   R	                  S5      nUS:  a  U S   US-   S U S'   [        U 5      S:X  a*  U S   R                  S5      n[        U5      S:X  a  X SS -   n [        U 5      S:X  aQ  U S   nUR                  S5      nUS	:X  a  UR                  S5      nUS:  a  USU X1S /U SS& OU R                  S
5        [        U 5      S:  a  gU SS n U u  pEpgnU(       a  U(       a  U(       d  gUR                  5       nU[        ;  a  XTR                  5       pTU[        ;  a  g[        R                  U5      S-   nUS:  a  US-  nUS	   S:X  a  USS	 nUR                  S5      nUS:  a  XvpvUS	   S:X  a  USS	 nU(       d  gUS   R                  5       (       d  XpUS	   S:X  a  USS	 nUR                  S5      n[        U5      S:X  a  Uu  pSnOn[        U5      S:X  a  Uu  pnOY[        U5      S:X  aI  SUS   ;   a@  US   R                  S5      n[        U5      S:X  a  Uu  pSnO[        U5      S:X  a  Uu  pnOgg [        U5      n[        U5      n[        U	5      n	[        U
5      n
[        U5      nUS:  a  US:  a  US-  nOUS-  nSnUR                  5       nU[        ;   a
  [        U   nO* [        U5      nUS:X  a  UR                  S5      (       a  SnU(       a!  US:  a  S	nU* nOSnXS-  S-  US-  S-  -   -  nXeXIXSSS	U/
$ ! [         a     gf = f! [         a     Nkf = f)an  Convert date to extended time tuple.

The last (additional) element is the time zone offset in seconds, except if
the timezone was specified as -0000.  In that case the last element is
None.  This indicates a UTC timestamp that explicitly declaims knowledge of
the source timezone, as opposed to a +0000 timestamp that indicates the
source timezone really was UTC.

Nr   ,      -   +r         :   0.d   D   il  i  i  <   )splitendswithlower	_daynamesrfindlenfindappend_monthnamesindexisdigitint
ValueErrorupper
_timezones
startswith)r9   istuffsddmmyytmtzthhtmmtsstzoffsettzsigns                 r;   r7   r7   9   s    ::<D AwQ9 <GGMM#61gacdmDG
4yA~Qc"u:?8#D
4yA~GFF3K7sAq5"1qu~DHKKO
4y1}8DRRR2"	B	XXZB[ 			2		"B	Bw
b	"v}W
A1uB	"v}Wa5==??B	"v}W	#B
2w!|
	RA3	RA#A,U[[r7a<JSCW\ OSsWW#h#h#h 
Cx7$JB $JBH	B	Zb>	2wH Q;2==--Ha<F yHF}d2hnb5HHIBSq!R::E  *  		s$   7M- M= -
M:9M:=
N
	N
c                 P    [        U 5      n[        U[        5      (       a  USS $ U$ )z&Convert a time string to a time tuple.Nr6   )r   
isinstancer8   )r9   ts     r;   r   r      s)    TA!U!ur<   c                 ~    U S   c  [         R                  " U SS S-   5      $ SSKnUR                  U 5      nX S   -
  $ )zETurn a 10-tuple as returned by parsedate_tz() into a POSIX timestamp.r6   N   )rD   r   )timemktimecalendartimegm)r9   rr   rm   s      r;   r   r      sD    Aw{{48e+,, 	OOD!7{r<   c                 F    U R                  SS5      R                  SS5      $ )zPrepare string to be used in a quoted string.

Turns backslash and double quote characters into quoted pairs.  These
are the only characters that need to be quoted inside a quoted string.
Does not add the surrounding double quotes.
\z\\"z\")replace)strs    r;   r   r      s"     ;;tV$,,S%88r<   c                   n    \ rS rSrSrS rS rS rS rS r	S r
S	 rSS
 jrS rS rS rSS jrS rSrg)AddrlistClass   zAddress parser class by Ben Escoto.

To understand what this class does, it helps to have a copy of RFC 2822 in
front of you.

Note: this class interface is deprecated and may be removed in the future.
Use email.utils.AddressList instead.
c                 *   SU l         SU l        SU l        SU l        U R                  U R                  -   U l        U R                   U R                  -   U R                  -   U l        U R
                  R                  SS5      U l        Xl        / U l	        g)zkInitialize a new instance.

`field' is an unparsed address header field, containing
one or more addresses.
z()<>@,:;."[]r   z 	z
rJ   r   N)
specialsposLWSCRFWSatomendsrw   
phraseendsfieldcommentlistselfr   s     r;   __init__AddrlistClass.__init__   sx     (88dgg%0477: --//R8
r<   c                 Z   / nU R                   [        U R                  5      :  a  U R                  U R                      U R                  S-   ;   a[  U R                  U R                      S;  a(  UR	                  U R                  U R                      5        U =R                   S-  sl         OHU R                  U R                      S:X  a*  U R
                  R	                  U R                  5       5        OO%U R                   [        U R                  5      :  a  M  [        R                  U5      $ )z&Skip white space and extract comments.z
r?   ()	r~   rS   r   r   rU   r   
getcommentEMPTYSTRINGjoin)r   wslists     r;   gotonextAddrlistClass.gotonext   s    hhTZZ(zz$((#txx&'88::dhh'v5MM$**TXX"67ADHH%,  ''(9: hhTZZ( ''r<   c                     / nU R                   [        U R                  5      :  aR  U R                  5       nU(       a  X-  nOUR	                  S5        U R                   [        U R                  5      :  a  MR  U$ )zFParse all addresses.

Returns a list containing all of the addresses.
)r   r   )r~   rS   r   
getaddressrU   )r   resultads      r;   getaddrlistAddrlistClass.getaddrlist  s\    
 hhTZZ("Bh' hhTZZ( r<   c                    / U l         U R                  5         U R                  nU R                   nU R                  5       nU R                  5         / nU R                  [	        U R
                  5      :  a.  U(       a%  [        R                  U R                   5      US   4/nGOPU R
                  U R                     S;   a@  Xl        X l         U R                  5       n[        R                  U R                   5      U4/nGOU R
                  U R                     S:X  a  / n[	        U R
                  5      nU =R                  S-  sl        U R                  [	        U R
                  5      :  a  U R                  5         U R                  U:  a4  U R
                  U R                     S:X  a  U =R                  S-  sl        GO3X@R                  5       -   nU R                  [	        U R
                  5      :  a  M  OU R
                  U R                     S:X  au  U R                  5       nU R                   (       a;  [        R                  U5      S-   SR                  U R                   5      -   S	-   U4/nO[        R                  U5      U4/nOiU(       a&  [        R                  U R                   5      US   4/nO<U R
                  U R                     U R                  ;   a  U =R                  S-  sl        U R                  5         U R                  [	        U R
                  5      :  a2  U R
                  U R                     S
:X  a  U =R                  S-  sl        U$ )zParse the next address.r   z.@rG   r?   ;<z (r   )r>   )r   r   r~   getphraselistrS   r   SPACEr   getaddrspecr   getrouteaddrr}   )r   oldposoldclplist
returnlistaddrspecfieldlen	routeaddrs           r;   r   AddrlistClass.getaddress  s     ""$
88s4::&$zz$*:*:;U1XFG
ZZ!T) H$'')H ::d&6&67BCJZZ!S(J4::HHHMH((S_,88h&4::dhh+?3+FHHMH'//*;;
 ((S_, ZZ!S())+I$zz%047"xx(8(89 :<? @AJL M
  %zz%0)<=
 $zz$*:*:;U1XFG
DHH%6A88c$**o%$**TXX*>#*EHHMHr<   c                    U R                   U R                     S:w  a  gSnU =R                  S-  sl        U R                  5         SnU R                  [        U R                   5      :  Ga  U(       a  U R	                  5         SnOU R                   U R                     S:X  a  U =R                  S-  sl         U$ U R                   U R                     S:X  a  U =R                  S-  sl        SnO[U R                   U R                     S	:X  a  U =R                  S-  sl        O(U R                  5       nU =R                  S-  sl         U$ U R                  5         U R                  [        U R                   5      :  a  GM  U$ )
zqParse a route address (Return-path value).

This method just skips all the route stuff and returns the addrspec.
r   NFr?   r   >@TrG   )r   r~   r   rS   	getdomainr   )r   expectrouteadlists      r;   r   AddrlistClass.getrouteaddrJ  s&   
 ::dhh3&AhhTZZ( #DHH%,A  DHH%,A"DHH%,A))+A  MMO! hhTZZ($ r<   c                    / nU R                  5         U R                  [        U R                  5      :  Ga  SnU R                  U R                     S:X  aX  U(       a(  US   R	                  5       (       d  UR                  5         UR                  S5        U =R                  S-  sl        SnOU R                  U R                     S:X  a,  UR                  S[        U R                  5       5      -  5        OvU R                  U R                     U R                  ;   a0  U(       a(  US   R	                  5       (       d  UR                  5         OtUR                  U R                  5       5        U R                  5       nU(       a  U(       a  UR                  U5        U R                  [        U R                  5      :  a  GM  U R                  [        U R                  5      :  d  U R                  U R                     S:w  a  [        R                  U5      $ UR                  S5        U =R                  S-  sl        U R                  5         U R                  5       nU(       d  [        $ [        R                  U5      U-   $ )	zParse an RFC 2822 addr-spec.TrJ   rD   r?   Frv   z"%s"r   )r   r~   rS   r   strippoprU   r   getquoter   getatomr   r   r   )r   aslistpreserve_wswsdomains        r;   r   AddrlistClass.getaddrspecj  s   hhTZZ(Kzz$((#s*&*"2"2"4"4JJLc"A#DHH%,fuT]]_'==>DHH%6&*"2"2"4"4JJLdlln-Brb!% hhTZZ(( 88s4::&$**TXX*>#*E##F++cA! '&00r<   c                    / nU R                   [        U R                  5      :  Ga  U R                  U R                      U R                  ;   a  U =R                   S-  sl         GO2U R                  U R                      S:X  a*  U R                  R                  U R                  5       5        OU R                  U R                      S:X  a   UR                  U R                  5       5        OU R                  U R                      S:X  a'  U =R                   S-  sl         UR                  S5        OjU R                  U R                      S:X  a  [        $ U R                  U R                      U R                  ;   a  OEUR                  U R                  5       5        U R                   [        U R                  5      :  a  GM  [        R                  U5      $ )z-Get the complete domain name from an address.r?   r   [rJ   r   )r~   rS   r   r   r   rU   r   getdomainliteralr   r   r   r   )r   sdlists     r;   r   AddrlistClass.getdomain  s=   hhTZZ(zz$((#txx/ADHH%,  ''(9:DHH%,d3356DHH%,Ac"DHH%, #"DHH%6dlln-# hhTZZ($ ''r<   c                 >   U R                   U R                     U:w  a  gS/nSnU =R                  S-  sl        U R                  [        U R                   5      :  Ga-  U(       a+  UR                  U R                   U R                     5        SnOU R                   U R                     U;   a  U =R                  S-  sl        OU(       a>  U R                   U R                     S:X  a!  UR                  U R	                  5       5        M  U R                   U R                     S:X  a  SnO(UR                  U R                   U R                     5        U =R                  S-  sl        U R                  [        U R                   5      :  a  GM-  [
        R                  U5      $ )a  Parse a header fragment delimited by special characters.

`beginchar' is the start character for the fragment.
If self is not looking at an instance of `beginchar' then
getdelimited returns the empty string.

`endchars' is a sequence of allowable end-delimiting characters.
Parsing stops when one of these is encountered.

If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed
within the parsed fragment.
r   Fr?   r   ru   T)r   r~   rS   rU   r   r   r   )r   	begincharendcharsallowcommentsslistr   s         r;   getdelimitedAddrlistClass.getdelimited  s%    ::dhh9,AhhTZZ(TZZ12DHH%1A4::dhh#73#>T__./DHH%-TZZ12HHMH hhTZZ(  &&r<   c                 (    U R                  SSS5      $ )z1Get a quote-delimited fragment from self's field.rv   z"Fr   r   s    r;   r   AddrlistClass.getquote  s      eU33r<   c                 (    U R                  SSS5      $ )z7Get a parenthesis-delimited fragment from self's field.r   z)Tr   r   s    r;   r   AddrlistClass.getcomment  s      eT22r<   c                 .    SU R                  SSS5      -  $ )z!Parse an RFC 2822 domain-literal.z[%s]r   z]Fr   r   s    r;   r   AddrlistClass.getdomainliteral  s    ))#ue<<<r<   Nc                    S/nUc  U R                   nU R                  [        U R                  5      :  a  U R                  U R                     U;   a  ObUR	                  U R                  U R                     5        U =R                  S-  sl        U R                  [        U R                  5      :  a  M  [
        R                  U5      $ )zParse an RFC 2822 atom.

Optional atomends specifies a different set of end token delimiters
(the default is to use self.atomends).  This is used e.g. in
getphraselist() since phrase endings must not include the `.' (which
is legal in phrases).r   r?   )r   r~   rS   r   rU   r   r   )r   r   atomlists      r;   r   AddrlistClass.getatom  s     4}}HhhTZZ(zz$((#x/

488 45HHMH hhTZZ( ))r<   c                    / nU R                   [        U R                  5      :  Ga;  U R                  U R                      U R                  ;   a  U =R                   S-  sl         OU R                  U R                      S:X  a   UR	                  U R                  5       5        OU R                  U R                      S:X  a*  U R                  R	                  U R                  5       5        OTU R                  U R                      U R                  ;   a   U$ UR	                  U R                  U R                  5      5        U R                   [        U R                  5      :  a  GM;  U$ )zParse a sequence of RFC 2822 phrases.

A phrase is a sequence of words, which are in turn either RFC 2822
atoms or quoted-strings.  Phrases are canonicalized by squeezing all
runs of continuous whitespace into one space.
r?   rv   r   )
r~   rS   r   r   rU   r   r   r   r   r   )r   r   s     r;   r   AddrlistClass.getphraselist  s     hhTZZ(zz$((#txx/ADHH%,T]]_-DHH%,  ''(9:DHH%8  T\\$//:; hhTZZ( r<   )	r   r   r   r   r   r   r   r~   r}   )TN)__name__
__module____qualname____firstlineno____doc__r   r   r   r   r   r   r   r   r   r   r   r   r   __static_attributes__ r<   r;   rz   rz      sL    &(9v@$1L(.#'J43=*(r<   rz   c                   B    \ rS rSrSrS rS rS rS rS r	S r
S	 rS
rg)AddressListi  z@An AddressList encapsulates a list of parsed RFC 2822 addresses.c                 v    [         R                  X5        U(       a  U R                  5       U l        g / U l        g r   )rz   r   r   addresslistr   s     r;   r   AddressList.__init__  s,    t+#//1D!Dr<   c                 ,    [        U R                  5      $ r   )rS   r   r   s    r;   __len__AddressList.__len__  s    4##$$r<   c                     [        S 5      nU R                  S S  Ul        UR                   H/  nX0R                  ;  d  M  UR                  R                  U5        M1     U$ r   r   r   rU   r   othernewaddrxs       r;   __add__AddressList.__add__  sV    d#"..q1""A(((##**1- # r<   c                     UR                    H/  nX R                   ;  d  M  U R                   R                  U5        M1     U $ r   )r   rU   r   r   r   s      r;   __iadd__AddressList.__iadd__  s9    ""A(((  ''* # r<   c                     [        S 5      nU R                   H/  nX1R                  ;  d  M  UR                  R                  U5        M1     U$ r   r   r   s       r;   __sub__AddressList.__sub__  sC    d#!!A)))##**1- " r<   c                     UR                    H/  nX R                   ;   d  M  U R                   R                  U5        M1     U $ r   )r   remover   s      r;   __isub__AddressList.__isub__'  s9    ""A$$$  ''* # r<   c                      U R                   U   $ r   r   )r   rW   s     r;   __getitem__AddressList.__getitem__.  s    &&r<   r   N)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r<   r;   r   r     s(    J"%'r<   r   )r   __all__rp   r   r   
COMMASPACErV   rQ   r\   r   r7   r   r   r   rz   r   r   r<   r;   <module>r      s   
 
I
 >	 AQA$$$$$

z;z
9k kZ	-'- -'r<   