
    (hU                        S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
Jr  SSKJrJrJrJr  SSKJrJr  SS	KJr  SS
KJrJrJrJr  SSKJr   SSKJrJr  SSK J!r!J"r"  SSK#J$r$  Sr%\RP                  " \)5      r* " S S5      r+ " S S5      r, " S S\5      r- " S S5      r.S\\/\04   S\/4S jr1S\2S\24S jr3g! \& a  r'\'r% Sr'C'N`Sr'C'ff = f)a   
Utilities to perform encryption following the PDF standards.

The contents of this module are internal to fpdf2, and not part of the public API.
They may change at any time without prior warning or any deprecation period,
in non-backward-compatible ways.
    N)hexlify)BOM_UTF16_BEurandom)CallableIterableTypeUnion   )AccessPermissionEncryptionMethod)FPDFException)Name	PDFObject	PDFStringbuild_obj_dict)create_dictionary_string)Ciphermodes)AES128AES256)PKCS7c                   f    \ rS rSrSrSrS\S\4S jrS\S\	\
   4S jrS\S	\\\4   S\4S
 jrSrg)ARC4&   aZ  
This is a simplified version of the ARC4 (alleged RC4) algorithm,
created based on the following sources:
* Wikipedia article on RC4
* github.com/manojpandey/rc4 (MIT License)
* http://people.csail.mit.edu/rivest/pubs/RS14.pdf

Having this ARC4 implementation makes it possible to have basic
encryption functions without additional dependencies
   keyreturnc                     [        U5      n[        [        U R                  5      5      nSn[        U R                  5       H,  nXCU   -   XU-     -   U R                  -  nX4   X5   sX5'   X4'   M.     U$ )Nr   )lenlistrangeMOD)selfr   
key_lengthSjis         KC:\Users\13-19\Desktop\PokeDex\pokedex\Lib\site-packages\fpdf/encryption.pyKSAARC4.KSA4   sn    X
txx!txxAqTCJ//488;AqtJAD!$ !     r&   c              #      #    SnSn US-   U R                   -  nX1U   -   U R                   -  nX   X   sX'   X'   XU   X   -   U R                   -     nUv   MR  7f)Nr   r   )r#   )r$   r&   r(   r'   Ks        r)   PRGA	ARC4.PRGA=   sp     Q$(("AqTTXX%AqtJAD!$Q4!$;$((*+AG s   AAtextc                     U R                  U R                  U5      5      n/ nU H   nUR                  U[        U5      -  5        M"     U$ N)r/   r*   appendnext)r$   r   r1   	keystreamrescs         r)   encryptARC4.encryptG   sA    IIdhhsm,	AJJq4	?*+ 
r,    N)__name__
__module____qualname____firstlineno____doc__r#   bytesr!   r*   r   intr/   r
   	bytearrayr9   __static_attributes__r;   r,   r)   r   r   &   s\    	 Cu  d x} 5 eY.>(? D r,   r   c                   J   ^  \ rS rSrSrS\S\SS4U 4S jjrS\4S jrS	r	U =r
$ )
CryptFilterO   zMRepresents one crypt filter, listed under CF inside the encryption dictionarymodelengthr   Nc                    > [         TU ]  5         [        S5      U l        [        U5      U l        [        US-  5      U l        g )NrF      )super__init__r   typec_f_mrB   rI   )r$   rH   rI   	__class__s      r)   rM   CryptFilter.__init__R   s4    '	$Z
&1*or,   c           
      ~    [        [        U 5       Vs0 s H  o[        X5      _M     sn5      n[        U5      $ s  snf r3   )r   dirgetattrpdf_dict)r$   r   obj_dicts      r)   	serializeCryptFilter.serializeX   s8    !c$i"Pis(:#:i"PQ!! #Qs   :)rO   rI   rN   )r<   r=   r>   r?   r@   strrB   rM   rW   rD   __classcell__rP   s   @r)   rF   rF   O   s1    W&S &# &$ &"3 " "r,   rF   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )EncryptionDictionary]   z
This class represents an encryption dictionary
PDF 32000 reference - Table 20
The PDF trailer must reference this object (/Encrypt)
c                   > [         TU ]  5         [        S5      U l        UR                  U l        UR                  U l        SUR                  R                  5        S3U l        SUR                  R                  5        S3U l
        UR                  S:X  ai  SUR                  R                  5        S3U l        SUR                  R                  5        S3U l        SUR                  R                  5        S3U l        UR                   U l        [%        UR&                  5      U l        UR*                  (       d  SU l        UR,                  (       a*  [/        SUR,                  R1                  5       05      U l        UR4                  [6        R8                  :X  a!  [        S5      U l        [        S5      U l        g [        S5      U l        [        S5      U l        g )	NStandard<>   falsez/StdCFIdentityStdCF)rL   rM   r   filterr%   rI   revisionroupperuoeo_eueu_epermsversionvint32access_permissionpencrypt_metadatacfrU   rW   c_fencryption_methodr   NO_ENCRYPTIONstm_fstr_f)r$   security_handlerrP   s     r)   rM   EncryptionDictionary.__init__d   s   :&&11!**%''--/02%''--/02$$)+..4467q9DH+..4467q9DH-3399;<A>DJ!))'99:00$+D!+;+>+>+H+H+J KLDH--1A1O1OOj)DJj)DJgDJgDJr,   )ry   rw   rg   rI   rj   rn   rv   rq   ri   r|   r}   rl   rp   rs   )r~   StandardSecurityHandlerr   N)r<   r=   r>   r?   r@   rM   rD   rZ   r[   s   @r)   r]   r]   ]   s    ' 'r,   r]   c                      \ rS rSrSrSrS\R                  " 5       \R                  S4S\
S\\
S4   S\S	\S
\4
S jjrS\
SS4S jrS\4S jrS\\
\\4   S\S\\
\4   4S jrS\
S\S\
4S jrS\S\S\4S jrS\4S jrS\S\4S jrS\S\S\4S jr\S\S    S\S\4S j5       r\S\S    S\
S\4S j5       rS \
S\4S! jrS\
4S" jrS\
4S# jr \\" 5       4S\S    S$\S%\S&\S\4
S' jj5       r!S-S( jr"S-S) jr#S-S* jr$S\4S+ jr%S,r&g).r   }   z
This class is referenced in the main PDF class and is used to handle all encryption functions
    * Calculate password and hashes
    * Provide encrypt method to be called by stream and strings
    * Set the access permissions on the document
s    (N^NuAd NV.. h>/dSizNFowner_passworduser_password
permissionrz   rw   c                 z   Xl         Uc  SOSU-  U l        X l        U(       a  UOSU l        XPl        S U l        SU l        [        (       a@  U R                  [        R                  [        R                  4;   a  [        S[         35      eU R                  [        R                  :X  a9  SU l        SU l        UR                  S5        [        SU R                  S9U l        OU R                  [        R                  :X  a@  S	U l        S
U l        UR                  S5        SU l        [        SU R                  S9U l        OvU R                  [        R                   :X  a9  SU l        SU l        UR                  S5        [        SU R                  S9U l        OSU l        SU l        UR                  S5        X`l        g )Nl   p     zucryptography module not available - Try: 'pip install cryptography' or use RC4 encryption method - Import error was:    z1.6AESV2)rH   rI      rc   z2.0r   AESV3V2      z1.5)fpdfru   r   r   rz   rx   r%   import_errorr   AES_128AES_256EnvironmentErrorrr   rh   _set_min_pdf_versionrF   r{   rw   )r$   r   r   r   r   rz   rw   s          r)   rM    StandardSecurityHandler.__init__   s    	 ! /4zA 	
 -.;]!2<D22$$$$7
 
 #((4~7 
 !!%5%=%==DLDM%%e,!wtGDG##'7'?'??DLDM%%e,!DO!wtGDG##'7'E'EEDLDM%%e,!tDOODDGDLDM%%e, !1r,   file_idr   c                 P   Xl         USS U l        U R                  S:X  aG  U R                  S5      U l        U R                  5         U R                  5         U R                  5         gU R                  5       U l	        U R                  5       U l        U R                  5       U l        g)z,File_id is the first hash of the PDF file idr   !   rc       N)r   info_idrh   get_random_byteskgenerate_user_password_rev6generate_owner_password_rev6generate_perms_rev6generate_owner_passwordrj   generate_encryption_keygenerate_user_passwordrl   )r$   r   s     r)   generate_passwords*StandardSecurityHandler.generate_passwords   s    q}==A**2.DF,,.--/$$&113DF113DF002DFr,   c                     [        U 5      $ )zReturn an encryption dictionary)r]   r$   s    r)   get_encryption_obj*StandardSecurityHandler.get_encryption_obj   s    #D))r,   r1   obj_idc                     [         R                  SU5        [        U[        [        45      (       a  U R                  X5      $ U R                  X5      $ )zOMethod invoked by PDFObject and PDFContentStream to encrypt strings and streamszEncrypting %s)LOGGERdebug
isinstancerC   rA   encrypt_streamencrypt_string)r$   r1   r   s      r)   r9   StandardSecurityHandler.encrypt   sP     	_d+ $E 233 -	
 $$T2	
r,   stringc                    U R                   [        R                  :X  a  [        USS9R	                  5       $ [
        R                  SU5         UR                  S5        S[        U R                  UR                  S5      U5      5      R                  5       R                  5        S3$ ! [         aP    S[        [        U R                  [        UR                  S5      -   U5      5      5      R!                  S5       S3s $ f = f)NF)r9   zEncrypting string: %szlatin-1ra   rb   z	utf-16-be)rz   r   r{   r   rW   r   r   encoderA   encrypt_byteshexrk   UnicodeEncodeErrorr   rC   r   decode)r$   r   r   s      r)   r   &StandardSecurityHandler.encrypt_string   s    !!%5%C%CCVU3==??,f5	FMM)$uT//i0H&QRVVX^^`aabcc! 	Fwy););L6==YdKe<egm)nopww  yB  C  D  DE  F  F	Fs   AB) )ADDstreamc                 v    U R                   [        R                  :X  a  U$ [        U R	                  X5      5      $ r3   )rz   r   r{   rA   r   )r$   r   r   s      r)   r   &StandardSecurityHandler.encrypt_stream   s2    !!%5%C%CCMT''788r,   c                 \    U R                   [        R                  [        R                  4;   $ r3   )rz   r   r   r   r   s    r)   is_aes_algorithm(StandardSecurityHandler.is_aes_algorithm   s,    %%$$$$*
 
 	
r,   datac                    [         R                  " SSS9nUR                  U R                  5        UR                  US-  R	                  SSSS95        UR                  SR	                  S	SSS95        U R                  5       (       a  UR                  [        / S
Q5      5        UR                  5       nU R                  5       (       a  U R                  XA5      $ [        5       R                  XA5      $ )z
PDF32000 reference - Algorithm 1: Encryption of data using the RC4 or AES algorithms
Append object ID and generation ID to the key and encrypt the data
Generation ID is fixed as 0. Will need to revisit if the application start changing generation ID
md5Fusedforsecurityi r   little	byteordersignedr   r   )s   A   l   T   )hashlibnewupdater   to_bytesr   rA   digestencrypt_AES_cryptographyr   r9   )r$   r   r   hr   s        r)   r   %StandardSecurityHandler.encrypt_bytes   s     KKu5		h((hu(M	
 	
!!!x!F	
   ""HHU345hhj  ""00;;v~~c((r,   r   c                 ,   [        U R                  S5      5      n[        S5      R                  5       nUR	                  U5      nXTR                  5       -  nU R                  [        R                  :X  a)  [        [        U5      [        R                  " U5      5      O2[        [        U R                  5      [        R                  " U5      5      nUR                  5       nUR	                  U5      UR                  5       -   nUR!                  U5        U$ )zDEncrypts an array of bytes using AES algorithms (AES 128 or AES 256)   r   )rC   r   r   padderr   finalizerz   r   r   r   r   r   CBCr   r   	encryptorextend)r$   r   r   ivr   padded_datacipherr   s           r)   r   0StandardSecurityHandler.encrypt_AES_cryptography  s    t,,R01s""$mmD)(( %%)9)A)AA 6#;		".tvv		"6 	
 $$&	,y/A/A/CC
		$	r,   clssizec                     [        U5      $ )z
https://docs.python.org/3/library/os.html#os.urandom
os.urandom will use OS-specific sources to generate random bytes
suitable for cryptographic use
r   )r   r   s     r)   r   (StandardSecurityHandler.get_random_bytes  s     t}r,   c                   ^ S[         S[         4S jm[        U5      S:  a
  [        5       $ SR                  U4S jU 5       5      n[        R
                  R                  SU5      nS[         S[        4S jnU H  nU" U5      (       d  M  [        S	U S
35      e   S[         S[        S[        4S jnU" U[        R                  5      (       av  U" U[        R                  5      (       a  [        S	U S35      e[        R                  " US   5      (       a  [        R                  " US   5      (       d  [        S	U S35      e[        U5      S:  a  USS nUR                  S5      $ )a,  
PDF2.0 - ISO 32000-2:2020
All passwords for revision 6 shall be based on Unicode. Preprocessing of a user-provided password
consists first of normalizing its representation by applying the "SASLPrep" profile (Internet RFC 4013)
of the "stringprep" algorithm (Internet RFC 3454) to the supplied password using the Normalize and BiDi
options. Next, the password string shall be converted to UTF-8 encoding, and then truncated to the
first 127 bytes if the string is longer than 127 bytes

Python offers a stringprep module with the tables mapped in methods
charr   c                     U (       d  g[         R                  " U 5      (       a  g[         R                  " U 5      (       a  gU $ )Nr    )
stringprepin_table_b1in_table_c12r   s    r)   char_map8StandardSecurityHandler.prepare_string.<locals>.char_map/  s5    %%d++&&t,,Kr,   r   r   c              3   4   >#    U  H  nT" U5      v   M     g 7fr3   r;   ).0r8   r   s     r)   	<genexpr>9StandardSecurityHandler.prepare_string.<locals>.<genexpr>=  s     !>v!(1++v   NFKCc                    [         R                  " U 5      =(       d    [         R                  " U 5      =(       d    [         R                  " U 5      =(       d    [         R                  " U 5      =(       d    [         R
                  " U 5      =(       dm    [         R                  " U 5      =(       dP    [         R                  " U 5      =(       d3    [         R                  " U 5      =(       d    [         R                  " U 5      $ r3   )
r   r   in_table_c21_c22in_table_c3in_table_c4in_table_c5in_table_c6in_table_c7in_table_c8in_table_c9r   s    r)   is_prohibited=StandardSecurityHandler.prepare_string.<locals>.is_prohibitedC  s    ''- 0..t40))$/0 ))$/0 ))$/	0
 ))$/0 ))0 ))0 ))$/r,   zThe password z contains prohibited charactersr   func                 .   ^ [        U4S jU  5       5      $ )Nc              3   4   >#    U  H  nT" U5      v   M     g 7fr3   r;   )r   r   r   s     r)   r   PStandardSecurityHandler.prepare_string.<locals>.has_character.<locals>.<genexpr>\  s     4VTs4yyVr   )any)r   r   s    `r)   has_character=StandardSecurityHandler.prepare_string.<locals>.has_character[  s    4V444r,   z+ contains invalid bidirectional characters.r      NzUTF-8)rY   r    rA   joinunicodedata	ucd_3_2_0	normalizeboolr   r   r   in_table_d1in_table_d2r   )r   r   prepared_stringr   r   r  r   s         @r)   prepare_string&StandardSecurityHandler.prepare_string!  sl   		3 		3 		 v;?7N''!>v!>> &//99&/R	 	 	" $DT""##F8+JK  $	5# 	5H 	5 	5 **@*@AA_j.D.DEE##F8+VW  &&q'9::**?2+>??##F8+VW  #%-ds3O%%g..r,   passwordc                     [        U5      S:  a  USS n[        UR                  S5      5      nUR                  U R                  SS[        U5      -
   5        U$ )z
PDF32000 reference - Algorithm 2: Computing an encryption key
Step (a) - Add the default padding at the end of provided password to make it 32 bit long
r   Nlatin1)r    rC   r   r   DEFAULT_PADDING)r$   r  rv   s      r)   padded_password'StandardSecurityHandler.padded_passwords  sT    
 x=2}Hhooh/0	%%oc!f67r,   c                    U R                  U R                  5      n[        S5       H  n[        U5      nM     US[        R
                  " U R                  S-  5       nU R                  U R                  5      n[        S5       HD  n/ nU H  nUR                  Xu-  5        M     [        5       R                  [        U5      U5      nMF     [        U5      R                  5       $ )z
PDF32000 reference - Algorithm 3: Computing the encryption dictionary's O (owner password) value
The security handler is only using revision 3 or 4, so the legacy r2 version is not implemented here
3   NrK      )r  r   r"   r   mathceilr%   r   r4   r   r9   rA   r   )r$   m_rc4keyresultr(   new_keyr   s           r)   r   /StandardSecurityHandler.generate_owner_password~  s    
   !4!45rAAA 5dii! 346%%d&8&89rAGqu% V^^E'NF;F	 
 V}  ""r,   c                 @  ^ ^ [         R                  " SSS9nUR                  [        T R                  5      5        UR                  [
        R                  T R                  5      5        [        UR                  5       5      mT R                  n[        S5       HD  n/ nU H  nUR                  XS-  5        M     [        5       R                  [        U5      T5      mMF     TR                  UU 4S j[        S5       5       5        [        T5      R                  5       $ )z
PDF32000 reference - Algorithm 5: Computing the encryption dictionary's U (user password) value
The security handler is only using revision 3 or 4, so the legacy r2 version is not implemented here
r   Fr   r  c              3   N   >#    U  H  nTU   TR                   U   -  v   M     g 7fr3   )r  )r   xr   r$   s     r)   r   AStandardSecurityHandler.generate_user_password.<locals>.<genexpr>  s(      
;DaVAY--a009s   "%r   )r   r   r   rC   r  rA   fromhexr   r   r   r"   r4   r   r9   r   r   )r$   r  r   r(   r!  r   r   s   `     @r)   r   .StandardSecurityHandler.generate_user_password  s    
 KKu5	4//01	t||,-188:&ffrAGqu% V^^E'NF;F	 
 	 
;@9
 	
 V}  ""r,   input_passwordsaltuser_keyc                    [         R                  " X-   U-   5      R                  5       nSn US-  nX-   U-   n[        [	        USS 5      [
        R                  " USS 5      5      nUR                  5       nUR                  US-  5      UR                  5       -   n	[        U	SS 5      S-  n
U
S:X  a%  [         R                  " U	5      R                  5       nOOU
S:X  a%  [         R                  " U	5      R                  5       nO$[         R                  " U	5      R                  5       nUS:  a  U	S   US-
  ::  a  OGM  USS $ )	zb
Algorithm 2B - section 7.6.4.3.4 of the ISO 32000-2:2020
Applied on Security handlers revision 6
r   r   Nr   r   @   r   r  )r   sha256r   r   r   r   r   r   r   r   sumsha384sha512)r   r)  r*  r+  r   round_numberk1r   r   e	remainders              r)   compute_hash$StandardSecurityHandler.compute_hash  s,    NN>08;<CCEAL#h.BF1Sb6NEIIa2h,?@F((*I  b)I,>,>,@@A AcrFaIA~NN1%,,.aNN1%,,.NN1%,,.r!ae|b/@&@' * "vr,   c                    U R                  U R                  5      nU(       d
  [        5       nU R                  S5      nU R                  S5      nU R	                  XS9U-   U-   nUR                  5       U l        U R	                  XS9n[        [        U5      [        R                  " S5      5      nUR                  5       nUR                  U R                  5      UR                  5       -   nUR                  5       U l        g)z
Generating the U (user password) and UE (user encryption)
for security handlers of revision 6
Algorithm 8 - Section 7.6.4.4.7 of the ISO 32000-2:2020
rK   )r)  r*                     N)r  r   rC   r   r6  r   rl   r   r   r   r   r   r   r   r   ro   )	r$   r   user_validation_saltuser_key_saltrl   r   r   r   ro   s	            r)   r   3StandardSecurityHandler.generate_user_password_rev6  s     ++D,>,>?%KM#44Q7--a0]V"# 	

 }QsUYY|%<=$$&	dff%	(:(:(<<&&(r,   c                    U R                  U R                  5      nU(       d  [        SU R                   35      eU R                  S5      nU R                  S5      nU R	                  UU[
        R                  U R                  5      S9U-   U-   nUR                  5       U l	        U R	                  UU[
        R                  U R                  5      S9n[        [        U5      [        R                  " S5      5      nUR                  5       nUR                  U R                   5      UR#                  5       -   nUR                  5       U l        g)z
Generating the O (owner password) and OE (owner encryption)
for security handlers of revision 6
Algorithm 9 - Section 7.6.4.4.8 of the ISO 32000-2:2020
zInvalid owner password rK   )r)  r*  r+  r9  N)r  r   r   r   r6  rA   r'  rl   r   rj   r   r   r   r   r   r   r   r   rm   )	r$   r   owner_validation_saltowner_key_saltrj   r   r   r   rm   s	            r)   r   4StandardSecurityHandler.generate_owner_password_rev6  s,    ,,T-@-@A"9$:M:M9N OPP $ 5 5a 8..q1-*tvv.  
 $$  	
 )]]466*   
 sUYY|%<=$$&	dff%	(:(:(<<&&(r,   c                    SU R                   -  nU R                  (       a  SOSnUR                  SSSS9U-   S-   U R                  S	5      -   n[	        [        U R                  5      [        R                  " 5       5      nUR                  5       nUR                  U5      UR                  5       -   nUR                  5       U l        g
)u   
7.6.4.4.9 Algorithm 10: Computing the encryption dictionary’s Perms (permissions) value
(Security handlers of revision 6) of the ISO 32000-2:2020
l           T   FrK   r   Fr   s   adbr   N)ru   rw   r   r   r   r   r   r   ECBr   r   r   r   rq   )r$   perms64brw   perms_inputr   r   rq   s          r)   r   +StandardSecurityHandler.generate_perms_rev6   s    
 &(>(>>#'#8#84da8EB ##A&' 	 tvv		4$$&	  -	0B0B0DDYY[
r,   c                    [         R                  " SSS9nUR                  U R                  U R                  5      5        UR                  [
        R                  U R                  5      5        UR                  U R                  S-  R                  SSSS95        UR                  [
        R                  U R                  5      5        U R                  SL a,  U R                  S:X  a  UR                  [        / SQ5      5        UR                  5       S	[        R                  " U R                   S
-  5       n[#        S5       H2  n[%        U5      S	[        R                  " U R                   S
-  5       nM4     U$ )z=
PDF32000 reference
Algorithm 2: Computing an encryption key
r   Fr       r   r   r   )   rJ  rJ  rJ  NrK   2   )r   r   r   r  r   rA   r'  rj   ru   r   r   rw   rr   r   r  r  r%   r"   r   )r$   r  r   r  s       r)   r   /StandardSecurityHandler.generate_encryption_key  s   
 KKu5	%%d&8&89:	tvv&'	##j0::Xe ; 	

 	
t||,-  E)dlla.?HHU345>tyy1)<=?rA[!CDIIdoo.A$BDF r,   )ru   rx   rw   rz   r   r   r   r   r%   rj   rm   r   rq   rh   rl   ro   r   rr   )r   N)'r<   r=   r>   r?   r@   r  r   allr   RC4rY   r
   r  rM   r   r]   r   rC   rA   rB   r9   r   r   r   r   r   classmethodr	   r   r  r  r   r   r6  r   r   r   r   rD   r;   r,   r)   r   r   }   s.    	V  +/'7';';'=.>.B.B!&51 51 S$Y'	51
 %51 ,51 51n3# 3$ 3*$8 *	
#y%/0	
:=	
	sEz		
FS F# F# F9U 9C 9E 9

$ 
)% ) ),E  5   d#<= S U   O/D!:; O/S O/U O/ O/b	 		 	# #"# #( 
 $+	!+,!! ! 	!
 
! !F0B!& r,   r   r   r   c                 n    [         R                  " SSS9nUR                  U 5        UR                  5       $ )Nr   Fr   )r   r   r   r   )r   r   s     r)   r   r   )  s)    E51AHHTN88:r,   nc                     U S-  n U S-  S-
  $ )z%convert long to signed 32 bit integerrI  l        r;   )rQ  s    r)   rt   rt   /  s    	JA
Nj((r,   )4r@   r   loggingr  r   r	  binasciir   codecsr   osr   typingr   r   r	   r
   enumsr   r   errorsr   syntaxr   r   r   r   r   rU   &cryptography.hazmat.primitives.ciphersr   r   1cryptography.hazmat.primitives.ciphers.algorithmsr   r   &cryptography.hazmat.primitives.paddingr   r   ImportErrorerror	getLoggerr<   r   r   rF   r]   r   rA   rC   r   rB   rt   r;   r,   r)   <module>ra     s            2 2 5 ! > > 8DP<L
 
		8	$& &R" "'9 '@i iXeE9$% % )S )S )a  Ls   C CCC