o
    >eɩ                     @   s  d dl Z d dlZd dlmZ d dl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mZmZ d dlmZmZmZmZ d dlmZ d dlmZ d dl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( d d
l)m*Z* d dl+m,Z, d dl-m.Z. d dl/m0Z0m1Z1 d dl2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZBmCZC ddlDmEZE ddlFmGZG ddlHmIZImJZJmKZKmLZLmMZMmNZNmOZO ddlPmQZQmRZRmSZSmTZT g dZUeVeWZXedeMdZYdejZdeej[ej\df fddZ]d e^fd!d"Z_d#ej`dejZfd$d%Zad&ejZd'ejbd(ejcfd)d*Zd		dmd+ejed#ej`d,efd-egd.eeR d/ee dee^e^f fd0d1Zhd2ejide7fd3d4Zj						dnd2ejid5eeg d6ee d7eek d8ee, d9ee. d:eeR d;eGde	efef fd<d=Zl	dod#ej`d6ed;eGd>ee, d9ee. dd?fd@dAZmedddddBd2ejidCeeY d5eeg d6ee d7eek d;eeG deYfdDdEZnedddddBd2ejid5eeg d6ee d7eek d;eeG deMfdFdEZneMdddddfd2ejid5eeg d6ee d7eek d;eeG d:eeR deYfdGdEZnd+ejedee fdHdIZo	Jdpd+ejedKe^deeji fdLdMZpd+ejedeeg fdNdOZqd+ejedPee d5egfdQdRZr	dodSejid6ee dTegd:eeR fdUdVZsdWeejt dXej`d6edeee0 eee%e$e#f  f fdYdZZud[eejt dXej`d6ee d\ejZfd]d^Zvddddde>jwdfd_eegeejxejyf d2ejid`ee dPee daee d;eeG d:eeR deNfdbdcZzedddedfZ{ededgG dhdi die
e{ Z|djee{ de|e{ fdkdlZ}dS )q    N)	dataclass)datetime)IOAny	AwaitableDictGenericIterableListOptionalTupleTypeTypeVarUnionoverload)cmscoretspx509)InvalidSignature)hashes)CancelableAsyncIteratorValidationContextfind_valid_path)DisallowedAlgorithmErrorExpiredErrorInvalidCertificateErrorPathBuildingErrorPathValidationErrorRevokedErrorStaleRevinfoErrorValidationError)TimeSlideFailure)ValidationPath)PKIXValidationParams)ACValidationResultasync_validate_ac)
CMSExtractionErrorCMSStructuralErrorMultivaluedAttributeErrorNonexistentAttributeErrorSignedDataCertscheck_ess_certidextract_certificate_infoextract_signer_infofind_unique_cms_attributeget_pyca_cryptography_hash   )misc)lift_iterable_async   )AdESFailureAdESIndeterminate   )errors)KeyUsageConstraints)CAdESSignerAttributeAssertionsCertifiedAttributesClaimedAttributesRevocationDetailsSignatureStatusStandardCMSSignatureStatusTimestampSignatureStatus)DEFAULT_ALGORITHM_USAGE_POLICYCMSAlgorithmUsagePolicyextract_message_digestvalidate_raw)validate_sig_integrityasync_validate_cms_signaturecollect_timing_infovalidate_tst_signed_dataasync_validate_detached_cmscms_basic_validationcompute_signature_tst_digestextract_tst_dataextract_self_reported_tsextract_certs_for_validationcollect_signer_attr_statusvalidate_algorithm_protectionget_signing_cert_attr
StatusType)boundsigned_attrsreturnc                 C   s$   t | dd}|du rt | dd}|S )a   
    Retrieve the ``signingCertificate`` or ``signingCertificateV2`` attribute
    (giving preference to the latter) from a signature's signed attributes.

    :param signed_attrs:
        Signed attributes.
    :return:
        The value of the attribute, if present, else ``None``.
    T)v2NF)_grab_signing_cert_attr)rT   attr rY   d/var/www/html/humari/django-venv/lib/python3.10/site-packages/pyhanko/sign/validation/generic_cms.pyrQ   c   s   rQ   rV   c              
   C   sx   |rdnd}|rt jnt j}zt| |}|| W S  ty%   Y d S  ty; } ztj	}t
jd|d|d }~ww )Nsigning_certificate_v2signing_certificatez3Wrong cardinality for signing certificate attributeades_subindication)r   SigningCertificateV2SigningCertificater/   loaddumpr*   r)   r6   NO_SIGNING_CERTIFICATE_FOUNDr8   SignatureValidationError)rT   rV   	attr_nameclsvalueeerrrY   rY   rZ   rW   u   s"   
rW   certc                 C   sN   t |}|d u r
d S |d d }t| |s%tj}tjd| jj d|dd S )Ncertsr   zWSigning certificate attribute does not match selected signer's certificate for subject"z".r]   )rQ   r,   r6   rc   r8   rd   subjecthuman_friendly)rj   rT   rX   certidri   rY   rY   rZ   _check_signing_certificate   s   
ro   attrsclaimed_digest_algorithm_objclaimed_signature_algorithm_objc                 C   s   zt | d}W n ty   d}Y n ty   tdw |durH|d j}||jkr0td|d j}|du r>td||jkrJtddS dS )	a+  
    Internal API to validate the CMS algorithm protection attribute
    defined in :rfc:`6211`, if present.

    :param attrs:
        A CMS attribute list.
    :param claimed_digest_algorithm_obj:
        The claimed (i.e. unprotected) digest algorithm value.
    :param claimed_signature_algorithm_obj:
        The claimed (i.e. unprotected) signature algorithm value.
    :raises errors.CMSStructuralError:
        if multiple CMS protection attributes are present
    :raises errors.CMSAlgorithmProtectionError:
        if a mismatch is detected
    cms_algorithm_protectionNz4Multiple CMS algorithm protection attributes presentdigest_algorithmzCDigest algorithm does not match CMS algorithm protection attribute.signature_algorithmz<CMS algorithm protection attribute not valid for signed datazFSignature mechanism does not match CMS algorithm protection attribute.)r/   r*   r)   r(   nativer8   CMSAlgorithmProtectionError)rp   rq   rr   cms_algid_protectionauth_digest_algorithmsigned_sig_algorithmrY   rY   rZ   rP      s@   


rP   signer_infoexpected_content_typeactual_digestalgorithm_usage_policy
time_indicc              
   C   s>  | d }| d }|d j }|durg|j|||jd}	|	s=d|d j  d}
|	jdur3|
d|	j d	7 }
tj|
|	jdu d
|j||d}|sgd|d j  d}
|jdur]|
d|j d	7 }
tj|
|jdu d
| d j }| d }|tj	u r|d}d}|}nw| d 
 }| }d}z	t|||d W n* ty } z	tj|jtjdd}~w tjy } z	tj|jtjdd}~ww t|| zt|d}W n ttfy   tjdtjdw |j }||krtjd| d| tjdt| }zt||||||||d d}W n ty   d}Y nw |dur||kn|}||fS )ae  
    Validate the integrity of a signature for a particular signerInfo object
    inside a CMS signed data container.

    .. warning::
        This function does not do any trust checks, and is considered
        "dangerous" API because it is easy to misuse.

    :param signer_info:
        A :class:`cms.SignerInfo` object.
    :param cert:
        The signer's certificate.

        .. note::
            This function will not attempt to extract certificates from
            the signed data.
    :param expected_content_type:
        The expected value for the content type attribute (as a Python string,
        see :class:`cms.ContentType`).
    :param actual_digest:
        The actual digest to be matched to the message digest attribute.
    :param algorithm_usage_policy:
        Algorithm usage policy.
    :param time_indic:
        Time indication for the production of the signature.
    :return:
        A tuple of two booleans. The first indicates whether the provided
        digest matches the value in the signed attributes.
        The second indicates whether the signature of the digest is valid.
    ru   rt   	algorithmN)moment
public_keyzThe algorithm z, is not allowed by the current usage policy.z	 Reason: .)	permanent)r   	signaturerT   TF)rq   rr   r]   content_typezQContent type not found in signature, or multiple content-type attributes present.zContent type z did not match expected value )	prehashedalgorithm_policyr   )rv   signature_algorithm_allowedr   failure_reasonr8   r   not_allowed_afterdigest_algorithm_allowedr   VOIDuntagrb   rP   r(   rd   failure_messager5   FORMAT_FAILURErw   r6   GENERICro   r/   r*   r)   rC   rD   r   )r{   rj   r|   r}   r~   r   ru   digest_algorithm_objmd_algorithmsig_algo_allowedmsgdigest_algo_allowedr   signed_attrs_origembedded_digestr   signed_datarT   rh   r   validintactrY   rY   rZ   rE      s   '






	



rE   r   c                 C   sP   z	t | }|j}W n ty   tjdtjdw t| }|d }t|| |S )a  
    Extract certificates from a CMS signed data object for validation purposes,
    identifying the signer's certificate in accordance with ETSI EN 319 102-1,
    5.2.3.4.

    :param signed_data:
        The CMS payload.
    :return:
        The extracted certificates.
    z,signer certificate not included in signaturer]   rT   )	r-   signer_certr'   r8   rd   r6   rc   r.   ro   )r   	cert_inforj   r{   rT   rY   rY   rZ   rN     s   

rN   
raw_digestvalidation_contextstatus_kwargsvalidation_pathpkix_validation_paramsr   key_usage_settingsc                   s   t | }t| }	|	j}
|	j}d}|dur |pt|j}|j}|p$t }|du r+t	}|d }|d j
}|d d j
}| d }|d j
}|du rat|d }t|}t|}|| | }n|d tjurptjdtjd	zt||
||||d
\}}W n ty } ztjd|j tjd	|d}~ww d } } }}|rz3|j| |durt|g}n|j|
}t|
||||dI dH }|j }|j!}|j"p|j#}|j$}W n t%y } zt&j'd|d t(j)}W Y d}~nd}~ww |pi }|du rdn|j*|d< |j|||
||||||d	 |S )z
    Perform basic validation of CMS and PKCS#7 signatures in isolation
    (i.e. integrity and trust checks).

    Internal API.
    Nru   r   rt   encap_content_infor   contentzKCMS structural error: detached signatures should not have encapsulated datar]   )r|   r}   r~   r   zCMS structural error: )r   pathsr   z&Processing error in validation processexc_infovalidation_time)	r   r   signing_certr   pkcs7_signature_mechanismtrust_problem_indicr   revocation_detailserror_time_horizon)+r.   rN   r   other_certsrB   lift_policyr   best_signature_timer   rA   rv   bytesr0   r   Hashupdatefinalizer   r   r8   rd   r5   r   rE   r(   r   certificate_registryregister_multipler3   path_builderasync_build_paths_lazyvalidate_cert_usageerror_subindicrevo_detailssuccess_result
error_pathr   
ValueErrorloggererrorr6   !CERTIFICATE_CHAIN_GENERAL_FAILUREr   )r   r   r   r   r   r   r   r   r{   r   rj   r   r   ru   	mechanismr   ecir|   rawmd_specmdr   r   rh   ades_statuspathr   r   r   	op_resultrY   rY   rZ   rJ     s   







rJ   r   z,CertvalidatorOperationResult[ValidationPath]c                    s,   dt f fdd}t| I dH S )zE
    Low-level certificate validation routine.
    Internal API.
    rU   c                      s"      t dI d H S )N)r   r   )validater   rY   rj   r   r   r   r   rY   rZ   _check(  s   
z#validate_cert_usage.<locals>._checkN)r#   handle_certvalidator_errors)rj   r   r   r   r   r   rY   r   rZ   r     s   
r   )r   r   r   r   
status_clsc                      d S NrY   )r   r   r   r   r   r   rY   rY   rZ   rF   5  s   
rF   c                   r   r   rY   )r   r   r   r   r   rY   rY   rZ   rF   B  s   	c                    s4   | |}t| |||||dI dH }|di |S )a  
    Validate a CMS signature (i.e. a ``SignedData`` object).

    :param signed_data:
        The :class:`.asn1crypto.cms.SignedData` object to validate.
    :param status_cls:
        Status class to use for the validation result.
    :param raw_digest:
        Raw digest, computed from context.
    :param validation_context:
        Validation context to validate the signer's certificate.
    :param status_kwargs:
        Other keyword arguments to pass to the ``status_class`` when reporting
        validation results.
    :param key_usage_settings:
        A :class:`.KeyUsageConstraints` object specifying which key usages
        must or must not be present in the signer's certificate.
    :param algorithm_policy:
        The algorithm usage policy for the signature validation.

        .. warning::
            This is distinct from the algorithm usage policy used for
            certificate validation, but the latter will be used as a fallback
            if this parameter is not specified.

            It is nonetheless recommended to align both policies unless
            there is a clear reason to do otherwise.
    :return:
        A :class:`.SignatureStatus` object (or an instance of a proper subclass)
    )r   r   NrY   )default_usage_constraintsrJ   )r   r   r   r   r   r   r   eff_key_usage_settingsrY   rY   rZ   rF   N  s   '	c              	   C   s4   z| d }t |d}|jW S  ttfy   Y dS w )a  
    Extract self-reported timestamp (from the ``signingTime`` attribute)

    Internal API.

    :param signer_info:
        A ``SignerInfo`` value.
    :return:
        The value of the ``signingTime`` attribute as a ``datetime``, or
        ``None``.
    rT   signing_timeN)r/   rv   r*   r)   )r{   sastrY   rY   rZ   rM     s   
rM   Fsignedc              	   C   sR   z|r| d }t |d}n	| d }t |d}|d }|W S  ttfy(   Y dS w )a  
    Extract signed data associated with a timestamp token.

    Internal API.

    :param signer_info:
        A ``SignerInfo`` value.
    :param signed:
        If ``True``, look for a content timestamp (among the signed
        attributes), else look for a signature timestamp (among the unsigned
        attributes).
    :return:
        The ``SignedData`` value found, or ``None``.
    rT   content_time_stampunsigned_attrssignature_time_stamp_tokenr   N)r/   r*   r)   )r{   r   r   tstuatst_signed_datarY   rY   rZ   rL     s   
rL   c                 C   sf   t | }|du r
dS |d }|d jd }|d d j}| d j}t|}t|}|| | S )a.  
    Compute the digest of the signature according to the message imprint
    algorithm information in a signature timestamp token.

    Internal API.

    :param signer_info:
        A ``SignerInfo`` value.
    :return:
        The computed digest, or ``None`` if there is no signature timestamp.
    Nr   r   message_imprinthash_algorithmr   r   )rL   parsedrv   r0   r   r   r   r   )r{   tst_datar   mitst_md_algorithmsignature_bytestst_md_specr   rY   rY   rZ   rK     s   


rK   ts_validation_contextc                    s   i }t | }|dur||d< t| dd}|dur7t| }|dus#J t|||I dH }td	i |}||d< t| dd}	|	durVt|	||dI dH }
td	i |
}||d< |S )
a  
    Collect and validate timing information in a ``SignerInfo`` value.
    This includes the ``signingTime`` attribute, content timestamp information
    and signature timestamp information.

    :param signer_info:
        A ``SignerInfo`` value.
    :param ts_validation_context:
        The timestamp validation context to validate against.
    :param raw_digest:
        The raw external message digest bytes (only relevant for the
        validation of the content timestamp token, if there is one)
    Nsigner_reported_dtF)r   timestamp_validityT)expected_tst_imprintcontent_timestamp_validityrY   )rM   rL   rK   rH   r@   )r{   r   r   r   r   r   tst_signature_digesttst_validity_kwargstst_validitycontent_tst_signed_datacontent_tst_validity_kwargscontent_tst_validityrY   rY   rZ   rG     s8   
rG   r   r   c           
         s   d}| d d }t |tjr|j}t |tjs tjdtj	d|d j
}t }t| |d|i||dI dH }|d	 d
 j
}	||	krVtd|	  d|  d d|d< |S )a  
    Validate the ``SignedData`` of a time stamp token.

    :param tst_signed_data:
        The ``SignedData`` value to validate; must encapsulate a ``TSTInfo``
        value.
    :param validation_context:
        The validation context to validate against.
    :param expected_tst_imprint:
        The expected message imprint value that should be contained in
        the encapsulated ``TSTInfo``.
    :param algorithm_policy:
        The algorithm usage policy for the signature validation.

        .. warning::
            This is distinct from the algorithm usage policy used for
            certificate validation, but the latter will be used as a fallback
            if this parameter is not specified.

            It is nonetheless recommended to align both policies unless
            there is a clear reason to do otherwise.
    :return:
        Keyword arguments for a :class:`.TimeStampSignatureStatus`.
    Nr   r   z'SignedData does not encapsulate TSTInfor]   gen_time	timestamp)r   r   r   r   r   hashed_messagezTimestamp token imprint is z, but expected r   Fr   )
isinstancer   ParsableOctetStringr   r   TSTInfor8   rd   r5   r   rv   r@   r   rJ   r   warninghex)
r   r   r   r   tst_infotst_info_bytesr   ku_settingsr   tst_imprintrY   rY   rZ   rH     s8   
	rH   acsr   c                    s~    fdd| D }g }g }t |D ]&}z
||I d H  W q tttfy: } z|| W Y d }~qd }~ww ||fS )Nc                    s   g | ]	}t | d qS ))holder_cert)r&   ).0acr   r   rY   rZ   
<listcomp>T  s    z+process_certified_attrs.<locals>.<listcomp>)asyncioas_completedappendr   r   r   )r   r   r   jobsresultsr8   jobrh   rY   r  rZ   process_certified_attrsJ  s$   
r	  sd_attr_certificatessd_signed_attrsc              
      s  zt |d}W n! ty   d }Y n ty) } ztjt|tjd|d }~ww i }d }d }|d ur|d }	t	t
|	tjsB|	nd}
|d }d}t
|tjsqdd |D }t|t|k}|d urqt|||}|I d H \}}|d ur{t|}nd }|pt
|d	 tj }|d ur|rtd
 t|
|||d|d< |d urt| ||I d H \}}|r|| |r|| t||d< ||d< |S )Nsigner_attributes_v2r]   claimed_attributesrY   certified_attributes_v2Fc                 S   s   g | ]
}|j d kr|jqS )	attr_cert)namechosen)r   rX   rY   rY   rZ   r    s
    
z.collect_signer_attr_status.<locals>.<listcomp>signed_assertionszCAdES signer attributes with externally certified assertions for which no validation method is available. This may affect signature semantics in unexpected ways.)claimed_attrscertified_attrsac_validation_errsunknown_attrs_presentcades_signer_attrsac_attrsr  )r/   r*   r)   r8   rd   strr5   r   r<   from_iterabler   r   Voidlenr	  r;   from_resultsr   r   r:   extend)r
  r   r   r  signer_attrsrh   resultcades_ac_resultscades_ac_errorsclaimed_asn1claimedcertified_asn1unknown_cert_attrs	cades_acsval_job	certifiedunknown_attrs
ac_results	ac_errorsrY   rY   rZ   rO   f  s   




rO   
input_datasigner_validation_contextac_validation_contextc	                    s  |du r|}t |}	|	d d j}
tt|
}t| tr$||  n t| tj	tj
fr7|t| d  nt|}tj|| ||d | }t|	||dI dH }t|}t||||||dI dH }t|}|durs|j|j |t|j|j||	d d	I dH  td
i |S )a  
    .. versionadded: 0.9.0

    .. versionchanged: 0.11.0
        Added ``ac_validation_context`` param.

    Validate a detached CMS signature.

    :param input_data:
        The input data to sign. This can be either a :class:`bytes` object,
        a file-like object or a :class:`cms.ContentInfo` /
        :class:`cms.EncapsulatedContentInfo` object.

        If a CMS content info object is passed in, the `content` field
        will be extracted.
    :param signed_data:
        The :class:`cms.SignedData` object containing the signature to verify.
    :param signer_validation_context:
        Validation context to use to verify the signer certificate's trust.
    :param ts_validation_context:
        Validation context to use to verify the TSA certificate's trust, if
        a timestamp token is present.
        By default, the same validation context as that of the signer is used.
    :param ac_validation_context:
        Validation context to use to validate attribute certificates.
        If not supplied, no AC validation will be performed.

        .. note::
            :rfc:`5755` requires attribute authority trust roots to be specified
            explicitly; hence why there's no default.
    :param algorithm_policy:
        The algorithm usage policy for the signature validation.

        .. warning::
            This is distinct from the algorithm usage policy used for
            certificate validation, but the latter will be used as a fallback
            if this parameter is not specified.

            It is nonetheless recommended to align both policies unless
            there is a clear reason to do otherwise.
    :param key_usage_settings:
        Key usage parameters for the signer.
    :param chunk_size:
        Chunk size to use when consuming input data.
    :param max_read:
        Maximal number of bytes to read from the input stream.
    :return:
        A description of the signature's status.
    Nrt   r   r   )max_read)r   r   )r   r   r   r   r   rT   )r
  r   r   r  rY   )r.   rv   r   r   r0   r   r   r   r   ContentInfoEncapsulatedContentInfo	bytearrayr2   chunked_digestr   rG   r?   r   rJ   r-   r   r   r   rO   attribute_certsr   )r-  r   r.  r   r/  r   r   
chunk_sizer0  r{   rt   htemp_bufdigest_bytesr   r   rY   rY   rZ   rI     sV   =

rI   
ResultTypeT)	covariant)frozenc                   @   s^   e Zd ZU dZee ed< dZee ed< dZ	ee
 ed< dZee ed< dZee ed< dS )CertvalidatorOperationResultzB
    Internal class to inspect error data from certvalidator.
    r   Nr   r   r   r   )__name__
__module____qualname____doc__r   r:  __annotations__r   r=   r   r   r   r#   r   r6   rY   rY   rY   rZ   r=  9  s   
 r=  coroc              
      s  d}d }}z	t | I dH dW S  ty. } ztj|j|d tj}W Y d}~n1d}~w tyK } ztj|j|d tj}W Y d}~nd}~w t	yj } ztj|j|d tj
}|j}W Y d}~nd}~w ty } z tj|j|d |j}|jdu rtj}ntj}|j}W Y d}~nd}~w ty } z5|j}t|j |j}|jrtj}n|jrtj}td|j|jd}ntj}td|j|jd}W Y d}~nd}~w ty } ztjd|d tj}W Y d}~nod}~w ty } z!|j}t|j |j}|js|jrtj}ntj}W Y d}~nBd}~w ty= } z|j}tj|j|d tj}W Y d}~n"d}~w t yZ } ztj|j|d tj}W Y d}~nd}~ww t d||||dS )	z
    Internal error handling function that maps certvalidator errors
    to AdES status indications.

    :param coro:
    :return:
    N)r   r   F)
ca_revokedrevocation_daterevocation_reasonTzFailed to build path)r   r   r   r   r   )!r=  r   r   r   failure_msgr6   CHAIN_CONSTRAINTS_FAILUREr"   NO_POEr    	TRY_LATERtime_cutoffr   original_pathbanned_sinceCRYPTO_CONSTRAINTS_FAILURE!CRYPTO_CONSTRAINTS_FAILURE_NO_POEr   revocation_dtis_side_validationr   
is_ee_certREVOKED_NO_POEr=   reasonREVOKED_CA_NO_POEr   NO_CERTIFICATE_CHAIN_FOUNDr   
expired_dtOUT_OF_BOUNDS_NO_POEr   r!   )rC  time_horizonr   r   rh   r   rY   rY   rZ   r   F  s   

r   )NN)NNNNNNr   )F)~r  loggingdataclassesr   r   typingr   r   r   r   r   r	   r
   r   r   r   r   r   r   
asn1cryptor   r   r   r   cryptography.exceptionsr   cryptography.hazmat.primitivesr   pyhanko_certvalidatorr   r   r   pyhanko_certvalidator.errorsr   r   r   r   r   r   r    r!    pyhanko_certvalidator.ltv.errorsr"   pyhanko_certvalidator.pathr#   !pyhanko_certvalidator.policy_declr$   pyhanko_certvalidator.validater%   r&   pyhanko.sign.generalr'   r(   r)   r*   r+   r,   r-   r.   r/   r0   	pdf_utilsr2   pdf_utils.miscr3   ades.reportr5   r6    r8   settingsr9   statusr:   r;   r<   r=   r>   r?   r@   utilsrA   rB   rC   rD   __all__	getLoggerr>  r   rR   CMSAttributesr`   r_   rQ   boolrW   Certificatero   DigestAlgorithmSignedDigestAlgorithmrP   
SignerInfor  r   rE   
SignedDatarN   dictrJ   r   rF   rM   rL   rK   rG   rH   AttributeCertificateV2r	  rO   DEFAULT_CHUNK_SIZEr1  r2  rI   r:  r=  r   rY   rY   rY   rZ   <module>   s   <(
0$	



;

 (
!	


 

6

!
9
>

h

k