§
    }Štjÿ°  ã            &       óœ  — d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
mZmZ ddlmZmZ ddlmZ ddlmZmZmZ dd	lmZmZ dd
lmZ ddlmZmZmZmZmZm Z m!Z! ddl"m#Z# erddl$m%Z%  ej&        e'¦  «        Z(dZ)dZ*e G d„ d¦  «        ¦   «         Z+e G d„ d¦  «        ¦   «         Z,e G d„ d¦  «        ¦   «         Z-e G d„ d¦  «        ¦   «         Z. ed¬¦  «         G d„ d¦  «        ¦   «         Z/e G d„ d¦  «        ¦   «         Z0e G d„ d¦  «        ¦   «         Z1e G d „ d!¦  «        ¦   «         Z2d"e3d#efd$„Z4d"e3d#e5fd%„Z6e G d&„ d'¦  «        ¦   «         Z7e G d(„ d)¦  «        ¦   «         Z8 G d*„ d+¦  «        Z9d,e3d#e:e;e3e3f                  fd-„Z<d"e3d#e;e=e>f         dz  fd.„Z?d/e3d#e	e;e3e=e>f                  fd0„Z@d1d2d3e3d4e3d#e	e;e3e=e>ef                  fd5„ZAd6e>d#e3fd7„ZBdd8œd"e3d9ed:         d;e=d<e>d=e=d>e>d?e3d@e3dAe5dBe5dCe5dDedz  d#e7fdE„ZC	 	 	 	 	 	 	 d_dGe3dHe3d1d2dIe5dBe5dAe5dJe5dCe5dKe9dz  dLedz  d#e8fdM„ZDdNe8d#dfdO„ZEdNe8dPe3d#dfdQ„ZFdPe3d#e8fdR„ZGd`dNe8d1d2dSe5dLedz  d#df
dT„ZHdNe8d#dfdU„ZI	 	 dadFdFdFdFdFddddddFdFdFddVœdGe3dz  dHe3dz  d1d2dIe5dBe5dAe5dJe5dCe5dWe:e3         dz  dXe:e3         dz  dYe3dz  dNe3dz  dZe3dz  d[e5dSe5d\e5d]e5e3z  dz  d#e8f$d^„ZJdS )bzzShared logic for bucket operations.

This module contains the core buckets logic used by both the CLI and the Python API.
é    N)ÚIterator)Ú	dataclassÚfield)ÚdatetimeÚtimezone)ÚPath)ÚTYPE_CHECKINGÚAnyÚLiteralé   )Ú	constantsÚlogging)ÚBucketNotFoundError)ÚHfUriÚ
StatusLineÚXetFileDataÚdisable_progress_barsÚenable_progress_barsÚparse_datetimeÚparse_hf_uri)Ú_looks_like_hf_url©ÚHfApizhf://buckets/éè  c                   óL   — e Zd ZU dZeed<   eed<   eed<   eed<   eed<   d„ Z	dS )	Ú
BucketInfoaß  
    Contains information about a bucket on the Hub. This object is returned by [`bucket_info`] and [`list_buckets`].

    Attributes:
        id (`str`):
            ID of the bucket.
        private (`bool`):
            Is the bucket private.
        created_at (`datetime`):
            Date of creation of the bucket on the Hub.
        size (`int`):
            Size of the bucket in bytes.
        total_files (`int`):
            Total number of files in the bucket.
    ÚidÚprivateÚ
created_atÚsizeÚtotal_filesc                 óH  — |                      d¦  «        | _        |                      d¦  «        | _        t          |                      d¦  «        ¦  «        | _        |                      d¦  «        | _        |                      d¦  «        | _         | j        j        di |¤Ž d S )Nr   r   Ú	createdAtr    Ú
totalFiles© )	Úpopr   r   r   r   r    r!   Ú__dict__Úupdate)ÚselfÚkwargss     úV/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/huggingface_hub/_buckets.pyÚ__init__zBucketInfo.__init__V   s‹   € Ø—*’*˜TÑ"Ô"ˆŒØ—z’z )Ñ,Ô,ˆŒÝ(¨¯ª°KÑ)@Ô)@ÑAÔAˆŒØ—J’J˜vÑ&Ô&ˆŒ	Ø!Ÿ:š: lÑ3Ô3ˆÔØˆŒÔÐ&Ð&˜vÐ&Ð&Ð&Ð&Ð&ó    N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstrÚ__annotations__Úboolr   Úintr,   r%   r-   r+   r   r   >   sd   € € € € € € ðð ð  	€G€G�GØ€M€M�MØÐÐÑØ
€I€I�IØÐÐÑð'ð 'ð 'ð 'ð 'r-   r   c                   óÒ   — e Zd ZU eez  ez  ed<   eed<    ed¬¦  «        Zedz  ed<    ed¬¦  «        Z	e
dz  ed<    ed¬¦  «        Ze
ed	<    ed¬¦  «        Zedz  ed
<   dd„ZdS )Ú_BucketAddFileÚsourceÚdestinationN©ÚdefaultÚxet_hashr    F©ÚinitÚmtimeÚcontent_typeÚreturnc                 óÆ  — d | _         t          | j        t          t          f¦  «        r$t          j        | j        ¦  «        d         | _         | j         €$t          j        | j        ¦  «        d         | _         t          t          | j        t          ¦  «        s't          j                             | j        ¦  «        dz  nt          j        ¦   «         dz  ¦  «        | _        d S ©Nr   r   )r@   Ú
isinstancer8   r2   r   Ú	mimetypesÚ
guess_typer9   r5   ÚbytesÚosÚpathÚgetmtimeÚtimer?   ©r)   s    r+   Ú__post_init__z_BucketAddFile.__post_init__i   s·   € Ø ˆÔÝ�d”k¥C­ ;Ñ/Ô/ð 	EÝ )Ô 4°T´[Ñ AÔ AÀ!Ô DˆDÔØÔÐ$Ý )Ô 4°TÔ5EÑ FÔ FÀqÔ IˆDÔåÝ8BÀ4Ä;ÕPUÑ8VÔ8VÐn�BŒG×Ò˜Tœ[Ñ)Ô)¨DÑ0Ð0Õ\`Ô\eÑ\gÔ\gÐjnÑ\nñ
ô 
ˆŒ
ˆ
ˆ
r-   ©rA   N)r.   r/   r0   r2   r   rG   r3   r   r<   r    r5   r?   r@   rM   r%   r-   r+   r7   r7   _   sË   € € € € € € à�$‰J˜ÑÐÐÑØÐÐÑà ˜5¨Ð.Ñ.Ô.€Hˆc�D‰jÐ.Ð.Ñ.Ø�u TÐ*Ñ*Ô*€Dˆ#�‰*Ð*Ð*Ñ*Ø�˜EÐ"Ñ"Ô"€Eˆ3Ð"Ð"Ñ"Ø$˜u¨%Ð0Ñ0Ô0€L�#˜‘*Ð0Ð0Ñ0ð	
ð 	
ð 	
ð 	
ð 	
ð 	
r-   r7   c                   ó²   — e Zd ZU eed<   eed<   eed<   eed<    ed¬¦  «        Zedz  ed<    ed¬	¦  «        Zeed
<    ed¬	¦  «        Z	edz  ed<   dd„Z
dS )Ú_BucketCopyFiler9   r<   Úsource_repo_typeÚsource_repo_idNr:   r    Fr=   r?   r@   rA   c                 óž   — t          j        | j        ¦  «        d         | _        t	          t          j        ¦   «         dz  ¦  «        | _        d S rC   )rE   rF   r9   r@   r5   rK   r?   rL   s    r+   rM   z_BucketCopyFile.__post_init__   s;   € Ý%Ô0°Ô1AÑBÔBÀ1ÔEˆÔÝ�œ™œ tÑ+Ñ,Ô,ˆŒ
ˆ
ˆ
r-   rN   )r.   r/   r0   r2   r3   r   r    r5   r?   r@   rM   r%   r-   r+   rP   rP   u   s¶   € € € € € € àÐÐÑØ€M€M�MØÐÐÑØÐÐÑØ�u TÐ*Ñ*Ô*€Dˆ#�‰*Ð*Ð*Ñ*Ø�˜EÐ"Ñ"Ô"€Eˆ3Ð"Ð"Ñ"Ø$˜u¨%Ð0Ñ0Ô0€L�#˜‘*Ð0Ð0Ñ0ð-ð -ð -ð -ð -ð -r-   rP   c                   ó   — e Zd ZU eed<   dS )Ú_BucketDeleteFilerI   N)r.   r/   r0   r2   r3   r%   r-   r+   rU   rU   „   s   € € € € € € à
€I€I�I€I€Ir-   rU   T)Úfrozenc                   ó(   — e Zd ZU dZeed<   eed<   dS )ÚBucketFileMetadataa%  Data structure containing information about a file in a bucket.

    Returned by [`get_bucket_file_metadata`].

    Args:
        size (`int`):
            Size of the file in bytes.
        xet_file_data (`XetFileData`):
            Xet information for the file (hash and refresh route).
    r    Úxet_file_dataN)r.   r/   r0   r1   r5   r3   r   r%   r-   r+   rX   rX   ‰   s3   € € € € € € ð	ð 	ð €I€I�IØÐÐÑÐÐr-   rX   c                   óš   — e Zd ZU dZeed<   dZeed<    ed¬¦  «        Zeed<    ed¬¦  «        Z	eed<    ed¬¦  «        Z
eed	<   dd„ZdS )Ú	BucketUrla½  Describes a bucket URL on the Hub.

    `BucketUrl` is returned by [`create_bucket`]. At initialization, the URL is parsed to populate properties:
    - endpoint (`str`)
    - namespace (`str`)
    - bucket_id (`str`)
    - url (`str`)
    - uri (`HfUri`)

    Args:
        url (`str`):
            String value of the bucket url.
        endpoint (`str`, *optional*):
            Endpoint of the Hub. Defaults to <https://huggingface.co>.
    ÚurlÚ ÚendpointFr=   Ú	namespaceÚ	bucket_idÚurirA   Nc                 ó¾  — | j         pt          j        | _         | j                             | j         d¦  «                             d¦  «        }|                     d¦  «        r|t          d¦  «        d …         }t          |¦  «        }|j	        rt          d| j        › �¦  «        ‚|j                             d¦  «        d         | _        |j        | _        || _        d S )Nr]   ú/zbuckets/zUnable to parse bucket URL: r   )r^   r   ÚENDPOINTr\   ÚreplaceÚstripÚ
startswithÚlenÚ_parse_bucket_uriÚpath_in_repoÚ
ValueErrorr   Úsplitr_   r`   ra   )r)   Úurl_pathÚparseds      r+   rM   zBucketUrl.__post_init__²   sÈ   € ØœÐ;­Ô);ˆŒð ”8×#Ò# D¤M°2Ñ6Ô6×<Ò<¸SÑAÔAˆà×Ò˜zÑ*Ô*ð 	3Ø¥ J¡¤Ð 1Ð 1Ô2ˆHÝ" 8Ñ,Ô,ˆØÔð 	HÝÐF¸D¼HÐFÐFÑGÔGÐGØœŸš¨Ñ-Ô-¨aÔ0ˆŒØœˆŒØˆŒˆˆr-   rN   )r.   r/   r0   r1   r2   r3   r^   r   r_   r`   ra   r   rM   r%   r-   r+   r[   r[   š   s¦   € € € € € € ðð ð  
€H€H�HØ€HˆcÐÐÑØ�U Ð&Ñ&Ô&€IˆsÐ&Ð&Ñ&Ø�U Ð&Ñ&Ô&€IˆsÐ&Ð&Ñ&Ø�˜EÐ"Ñ"Ô"€CˆÐ"Ð"Ñ"ðð ð ð ð ð r-   r[   c                   ón   — e Zd ZU dZed         ed<   eed<   eed<   eed<   edz  ed<   edz  ed	<   d
„ Z	dS )Ú
BucketFilez«
    Contains information about a file in a bucket on the Hub. This object is returned by [`list_bucket_tree`].

    Similar to [`RepoFile`] but for files in buckets.
    ÚfileÚtyperI   r    r<   Nr?   Úuploaded_atc                 óŽ  — |                      d¦  «        | _        |                      d¦  «        | _        |                      d¦  «        | _        |                      d¦  «        | _        |                      dd ¦  «        }|rt          |¦  «        nd | _        |                      dd ¦  «        }|rt          |¦  «        nd | _        d S )Nrr   rI   r    ÚxetHashr?   Ú
uploadedAt)r&   rr   rI   r    r<   r   r?   rs   )r)   r*   r?   rs   s       r+   r,   zBucketFile.__init__Ñ   s­   € Ø—J’J˜vÑ&Ô&ˆŒ	Ø—J’J˜vÑ&Ô&ˆŒ	Ø—J’J˜vÑ&Ô&ˆŒ	ØŸ
š
 9Ñ-Ô-ˆŒØ—
’
˜7 DÑ)Ô)ˆØ.3Ð=•^ EÑ*Ô*Ð*¸ˆŒ
Ø—j’j ¨tÑ4Ô4ˆØ:EÐO�>¨+Ñ6Ô6Ð6È4ˆÔÐÐr-   )
r.   r/   r0   r1   r   r3   r2   r5   r   r,   r%   r-   r+   rp   rp   Â   s�   € € € € € € ðð ð �&Œ/ÐÐÑØ
€I€I�IØ
€I€I�IØ€M€M�MØ�d‰?ÐÐÑØ˜D‘Ð Ð Ñ ðPð Pð Pð Pð Pr-   rp   c                   óJ   — e Zd ZU dZed         ed<   eed<   edz  ed<   d„ ZdS )ÚBucketFolderz¸
    Contains information about a directory in a bucket on the Hub. This object is returned by [`list_bucket_tree`].

    Similar to [`RepoFolder`] but for directories in buckets.
    Ú	directoryrr   rI   Nrs   c                 ó$  — |                      d¦  «        | _        |                      d¦  «        | _        |                      dd ¦  «        p|                      dd ¦  «        }|r&t          |t          ¦  «        r|nt          |¦  «        nd | _        d S )Nrr   rI   rv   rs   )r&   rr   rI   rD   r   r   rs   )r)   r*   rs   s      r+   r,   zBucketFolder.__init__è   s‹   € Ø—J’J˜vÑ&Ô&ˆŒ	Ø—J’J˜vÑ&Ô&ˆŒ	Ø—j’j ¨tÑ4Ô4ÐW¸¿
º
À=ÐRVÑ8WÔ8Wˆð ð�J {µHÑ=Ô=Ð^ˆ[ˆ[Å>ÐR]ÑC^ÔC^ÐC^àð 	ÔÐÐr-   )	r.   r/   r0   r1   r   r3   r2   r   r,   r%   r-   r+   rx   rx   Ü   s[   € € € € € € ðð ð �+Ô
ÐÐÑØ
€I€I�IØ˜D‘Ð Ð Ñ ð
ð 
ð 
ð 
ð 
r-   rx   rI   rA   c                 óÐ  — |                       t          j        ¦  «        st          | ¦  «        r+t	          | ¦  «        }|j        st          d| › d�¦  «        ‚|S |                      dd¦  «        }t          |¦  «        dk     s|d         r|d         st          d| › d�¦  «        ‚|d         › d|d         › �}d 	                    |dd	…         ¦  «        }t          d
||¬¦  «        S )a  Parse a bucket path into a HfUri.

    Accepts:
    - `hf://buckets/namespace/name(/path/in/repo)` URIs,
    - Hugging Face web URLs such as `https://huggingface.co/buckets/namespace/name(/tree/path)`,
    - plain `namespace/name(/path/in/repo)` paths.
    zInvalid bucket path: z*. Must be a bucket URI (hf://buckets/...).rc   é   r   r   zInvalid bucket path: 'z)'. Expected format: namespace/bucket_nameNÚbucket)rr   r   rj   )rg   r   ÚHF_PROTOCOLr   r   Ú	is_bucketrk   rl   rh   Újoinr   )rI   rn   Úpartsr`   Úprefixs        r+   ri   ri   ø   sø   € ð ‡‚•yÔ,Ñ-Ô-ð Õ1CÀDÑ1IÔ1Ið å˜dÑ#Ô#ˆØÔð 	gÝÐe°TÐeÐeÐeÑfÔfÐfØˆØ�JŠJ�s˜AÑÔ€EÝ
ˆ5�z„z�A‚~€~˜U 1œX€~¨U°1¬X€~ÝÐa°$ÐaÐaÐaÑbÔbÐbØ˜”8Ð(Ð(˜e AœhÐ(Ð(€IØ�XŠX�e˜A˜B˜B”iÑ Ô €FÝ�h 9¸6ÐBÑBÔBÐBr-   c                 ól   — |                       t          j        ¦  «        sdS t          | ¦  «        j        S )z›Check if a path is a bucket path.

    Do not raise if the path is not a hf:// URI.
    Raise if the path is a hf:// URI but with an incorrect format.
    F)rg   r   r~   r   r   )rI   s    r+   Ú_is_bucket_pathr„     s1   € ð �?Š?�9Ô0Ñ1Ô1ð ØˆuÝ˜ÑÔÔ'Ð'r-   c                   ó’   — e Zd ZU dZed         ed<   eed<   dZedz  ed<   dZ	eed<   dZ
edz  ed	<   dZedz  ed
<   dZedz  ed<   dS )ÚSyncOperationz,Represents a sync operation to be performed.)ÚuploadÚdownloadÚdeleteÚskipÚactionrI   Nr    r]   ÚreasonÚlocal_mtimeÚremote_mtimeÚbucket_file)r.   r/   r0   r1   r   r3   r2   r    r5   rŒ   r�   rŽ   r�   rp   r%   r-   r+   r†   r†     s”   € € € € € € à6Ð6àÐ:Ô;Ð;Ð;Ñ;Ø
€I€I�IØ€Dˆ#�‰*ÐÐÑØ€FˆCÐÐÑØ"€K��t‘Ð"Ð"Ñ"Ø#€L�#˜‘*Ð#Ð#Ñ#Ø%)€K�˜dÑ"Ð)Ð)Ñ)Ð)Ð)r-   r†   c                   ó‚   — e Zd ZU dZeed<   eed<   eed<    ee¬¦  «        Zee	         ed<   de
eeez  f         fd„Zd	S )
ÚSyncPlanz Represents a complete sync plan.r8   ÚdestÚ	timestamp)Údefault_factoryÚ
operationsrA   c                 ó>  — t          d„ | j        D ¦   «         ¦  «        }t          d„ | j        D ¦   «         ¦  «        }t          d„ | j        D ¦   «         ¦  «        }t          d„ | j        D ¦   «         ¦  «        }t          d„ | j        D ¦   «         ¦  «        }|||||dœS )Nc              3   ó0   K  — | ]}|j         d k    ¯dV — ŒdS )r‡   r   N©r‹   ©Ú.0Úops     r+   ú	<genexpr>z#SyncPlan.summary.<locals>.<genexpr>5  ó.   è è € ÐKÐK˜B°R´YÀ(Ò5JÐ5J�aÐ5JÐ5JÐ5JÐ5JÐKÐKr-   c              3   ó0   K  — | ]}|j         d k    ¯dV — ŒdS )rˆ   r   Nr˜   r™   s     r+   rœ   z#SyncPlan.summary.<locals>.<genexpr>6  s.   è è € ÐOÐO˜b°r´yÀJÒ7NÐ7N˜Ð7NÐ7NÐ7NÐ7NÐOÐOr-   c              3   ó0   K  — | ]}|j         d k    ¯dV — ŒdS )r‰   r   Nr˜   r™   s     r+   rœ   z#SyncPlan.summary.<locals>.<genexpr>7  r�   r-   c              3   ó0   K  — | ]}|j         d k    ¯dV — ŒdS )rŠ   r   Nr˜   r™   s     r+   rœ   z#SyncPlan.summary.<locals>.<genexpr>8  s.   è è € ÐGÐG˜"°2´9ÀÒ3FÐ3F�AÐ3FÐ3FÐ3FÐ3FÐGÐGr-   c              3   ó:   K  — | ]}|j         d v ¯|j        pdV — ŒdS )©r‡   rˆ   r   N)r‹   r    r™   s     r+   rœ   z#SyncPlan.summary.<locals>.<genexpr>9  s5   è è € ÐgÐg¨"À2Ä9ÐPfÐCfÐCf˜œ˜ AÐCfÐCfÐCfÐCfÐgÐgr-   )ÚuploadsÚ	downloadsÚdeletesÚskipsÚ
total_size)Úsumr•   )r)   r£   r¤   r¥   r¦   r§   s         r+   ÚsummaryzSyncPlan.summary4  s¶   € ÝÐKÐK $¤/ÐKÑKÔKÑKÔKˆÝÐOÐO D¤OÐOÑOÔOÑOÔOˆ	ÝÐKÐK $¤/ÐKÑKÔKÑKÔKˆÝÐGÐG ¤ÐGÑGÔGÑGÔGˆÝÐgÐg°´ÐgÑgÔgÑgÔgˆ
àØ"ØØØ$ð
ð 
ð 	
r-   N)r.   r/   r0   r1   r2   r3   r   Úlistr•   r†   Údictr5   r©   r%   r-   r+   r‘   r‘   +  s�   € € € € € € à*Ð*à€K€K�KØ
€I€I�IØ€N€N�NØ&+ e¸DÐ&AÑ&AÔ&A€J��]Ô#ÐAÐAÑAð
˜˜c 3¨¡9˜nÔ-ð 
ð 
ð 
ð 
ð 
ð 
r-   r‘   c            
       ó„   — e Zd ZdZ	 	 	 d
dee         dz  dee         dz  deeeef                  dz  fd„Zdedefd	„Z	dS )ÚFilterMatcherz4Matches file paths against include/exclude patterns.NÚinclude_patternsÚexclude_patternsÚfilter_rulesc                 ó<   — |pg | _         |pg | _        |pg | _        dS )a  Initialize the filter matcher.

        Args:
            include_patterns: Patterns to include (from --include)
            exclude_patterns: Patterns to exclude (from --exclude)
            filter_rules: Rules from filter file as list of ("+"/"-", pattern) tuples
        N©r®   r¯   r°   )r)   r®   r¯   r°   s       r+   r,   zFilterMatcher.__init__K  s1   € ð !1Ð 6°BˆÔØ 0Ð 6°BˆÔØ(Ð.¨BˆÔÐÐr-   rI   rA   c                 óô   — | j         D ]"\  }}t          j        ||¦  «        r|dk    c S Œ#| j        D ]}t          j        ||¦  «        r dS Œ| j        D ]}t          j        ||¦  «        r dS Œ| j        rdS dS )zþCheck if a path should be included based on the filter rules.

        Filtering rules:
        - Filters are evaluated in order, first matching rule decides
        - If no rules match, include by default (unless include patterns are specified)
        ú+FT)r°   Úfnmatchr¯   r®   )r)   rI   ÚsignÚpatterns       r+   ÚmatcheszFilterMatcher.matches\  sÄ   € ð "Ô.ð 	#ð 	#‰MˆD�'ÝŒ˜t WÑ-Ô-ð #Ø˜s’{Ð"Ð"Ð"ð#ð Ô,ð 	ð 	ˆGÝŒ˜t WÑ-Ô-ð Ø�u�uðð Ô,ð 	ð 	ˆGÝŒ˜t WÑ-Ô-ð Ø�t�tðð Ô ð 	Ø�5ð ˆtr-   )NNN)
r.   r/   r0   r1   rª   r2   Útupler,   r4   r¸   r%   r-   r+   r­   r­   H  s    € € € € € Ø>Ð>ð .2Ø-1Ø59ð	/ð /à˜sœ) dÑ*ð/ð ˜sœ) dÑ*ð/ð ˜5  c œ?Ô+¨dÑ2ð	/ð /ð /ð /ð"˜Cð  Dð ð ð ð ð ð r-   r­   Úfilter_filec                 ó  — g }t          | ¦  «        5 }|D ]Ó}|                     ¦   «         }|r|                     d¦  «        rŒ.|                     d¦  «        r2|                     d|dd…                              ¦   «         f¦  «         Œu|                     d¦  «        r2|                     d|dd…                              ¦   «         f¦  «         Œ¼|                     d|f¦  «         ŒÔ	 ddd¦  «         n# 1 swxY w Y   |S )zþParse a filter file and return a list of (sign, pattern) tuples.

    Filter file format:
    - Lines starting with "+" are include patterns
    - Lines starting with "-" are exclude patterns
    - Empty lines and lines starting with "#" are ignored
    ú#r´   r   Nú-)Úopenrf   rg   Úappend)rº   ÚrulesÚfÚlines       r+   Ú_parse_filter_filerÃ   y  sJ  € ð €EÝ	ˆkÑ	Ô	ð *˜aØð 
	*ð 
	*ˆDØ—:’:‘<”<ˆDØð ˜4Ÿ?š?¨3Ñ/Ô/ð ØØ�Š˜sÑ#Ô#ð *Ø—’˜c 4¨¨¨¤8§>¢>Ñ#3Ô#3Ð4Ñ5Ô5Ð5Ð5Ø—’ Ñ%Ô%ð *Ø—’˜c 4¨¨¨¤8§>¢>Ñ#3Ô#3Ð4Ñ5Ô5Ð5Ð5ð —’˜c 4˜[Ñ)Ô)Ð)Ð)ð
	*ð*ð *ð *ñ *ô *ð *ð *ð *ð *ð *ð *øøøð *ð *ð *ð *ð €Ls   ’CC6Ã6C:Ã=C:c                 ó¨   — 	 t          j        | ¦  «        }n# t          $ r Y dS w xY wt          j        |j        ¦  «        rdS |j        |j        dz  fS )zÇStat a local file and return (size, mtime_ms).

    Returns None if the path is missing or is a directory. Uses a single
    ``os.stat`` call so callers don't pay for multiple syscalls per file.
    Nr   )rH   ÚstatÚOSErrorÚS_ISDIRÚst_modeÚst_sizeÚst_mtime)rI   Ústs     r+   Ú_stat_localrÌ   –  se   € ðÝŒW�T‰]Œ]ˆˆøÝð ð ð Øˆtˆtðøøøå„|�B”JÑÔð ØˆtØŒ:�r”{ TÑ)Ð)Ð)s   ‚ —
%¤%Ú
local_pathc              #   óô  K  — t           j                             | ¦  «        } t           j                             | ¦  «        st	          d| › �¦  «        ‚t          j        | ¦  «        D ]�\  }}}|D ]‡}t           j                             ||¦  «        }t          |¦  «        }|€Œ4t           j                             || ¦  «        }| 	                    t           j
        d¦  «        }||d         |d         fV — ŒˆŒ‘dS )zsList all files in a local directory.

    Yields:
        tuple: (relative_path, size, mtime_ms) for each file
    z Local path must be a directory: Nrc   r   r   )rH   rI   ÚabspathÚisdirrk   Úwalkr€   rÌ   Úrelpathre   Úsep)rÍ   ÚrootÚ_ÚfilesÚfilenameÚ	full_pathÚ	stat_infoÚrel_paths           r+   Ú_list_local_filesrÛ   ¥  sû   è è € õ ”—’ Ñ,Ô,€JÝŒ7�=Š=˜Ñ$Ô$ð JÝÐH¸JÐHÐHÑIÔIÐIåœ' *Ñ-Ô-ð 	7ð 	7‰ˆˆa�Øð 	7ð 	7ˆHÝœŸš T¨8Ñ4Ô4ˆIÝ# IÑ.Ô.ˆIØÐ ØÝ”w—’ y°*Ñ=Ô=ˆHà×'Ò'­¬°Ñ4Ô4ˆHØ˜I aœL¨)°A¬,Ð6Ð6Ð6Ð6Ð6ð	7ð	7ð 	7r-   Úapir   r`   r‚   c              #   ó¤  K  — |                       ||pdd¬¦  «        D ]²}t          |t          ¦  «        rŒ|j        }|r]|                     |dz   ¦  «        r|t          |¦  «        dz   d…         }n,||k    r#d|v r|                     dd¦  «        d         n|}nŒ~|}|j        r|j                             ¦   «         dz  nd}||j	        ||fV — Œ³dS )	zÔList all files in a bucket with a given prefix.

    Yields:
        tuple: (relative_path, size, mtime_ms, bucket_file) for each file.
            bucket_file is the BucketFile object from list_bucket_tree.
    NT)r‚   Ú	recursiverc   r   éÿÿÿÿr   r   )
Úlist_bucket_treerD   rx   rI   rg   rh   Úrsplitr?   r“   r    )rÜ   r`   r‚   ÚitemrI   rÚ   Úmtime_mss          r+   Ú_list_remote_filesrä   »  s  è è € ð ×$Ò$ Y°v°~ÀÐQUÐ$ÑVÔVð 2ð 2ˆÝ�d�LÑ)Ô)ð 	ØØŒyˆð ð 	Ø�Š˜v¨™|Ñ,Ô,ð Ø¥ F¡¤¨a¡Ð 1Ð 1Ô2��Ø˜’�à69¸T°k°k˜4Ÿ;š; s¨AÑ.Ô.¨rÔ2Ð2Àt��ð àˆHØ48´JÐE�4”:×'Ò'Ñ)Ô)¨DÑ0Ð0ÀAˆØ˜œ	 8¨TÐ1Ð1Ð1Ð1Ð1ð'2ð 2r-   rã   c                 ól   — t          j        | dz  t          j        ¬¦  «                             ¦   «         S )z3Convert mtime in milliseconds to ISO format string.r   )Útz)r   Úfromtimestampr   ÚutcÚ	isoformat)rã   s    r+   Ú_mtime_to_isorê   Ý  s*   € åÔ! (¨T¡/µh´lÐCÑCÔC×MÒMÑOÔOÐOr-   )r�   r‹   r¢   Úsource_sizeÚsource_mtimeÚ	dest_sizeÚ
dest_mtimeÚsource_newer_labelÚdest_newer_labelÚignore_sizesÚignore_timesÚignore_existingr�   c                 ó¼  — t          |dk    r|n|¦  «        }t          |dk    r|n|¦  «        }| |||dœ}|
rt          ddddœ|¤ŽS ||k    }||z
  t          k    }|r5|rt          d|||dœ|¤ŽS ||z
  t          k    }|r|nd}t          dd|dœ|¤ŽS |	r!|rt          d|d|dœ|¤ŽS t          ddd	dœ|¤ŽS |s|r|rdn|}t          d|||dœ|¤ŽS t          ddd
dœ|¤ŽS )a—  Compare source and dest files and return the appropriate sync operation.

    This is a unified helper for both upload and download directions.

    Args:
        path: Relative file path
        action: "upload" or "download"
        source_size: Size of the source file (bytes)
        source_mtime: Mtime of the source file (milliseconds)
        dest_size: Size of the destination file (bytes)
        dest_mtime: Mtime of the destination file (milliseconds)
        source_newer_label: Label when source is newer (e.g., "local newer" or "remote newer")
        dest_newer_label: Label when dest is newer (e.g., "remote newer" or "local newer")
        ignore_sizes: Only compare mtime
        ignore_times: Only compare size
        ignore_existing: Skip files that exist on receiver
        bucket_file: BucketFile object (for downloads only)

    Returns:
        SyncOperation describing the action to take
    r‡   )rI   r    r�   rŽ   rŠ   z&exists on receiver (--ignore-existing))r‹   rŒ   )r‹   rŒ   r�   z
same mtimezsize differsz	same sizeÚ	identicalNr%   )rê   r†   Ú_SYNC_TIME_WINDOW_MS)rI   r‹   rë   rì   rí   rî   rï   rð   rñ   rò   ró   r�   Úlocal_mtime_isoÚremote_mtime_isoÚbase_kwargsÚsize_differsÚsource_newerÚ
dest_newerÚskip_reasonrŒ   s                       r+   Ú_compare_files_for_syncrþ   â  sª  € õH $°F¸hÒ4FÐ4F L LÈJÑWÔW€OÝ$°6¸XÒ3EÐ3E Z ZÈ<ÑXÔXÐð ØØ&Ø(ð	#ð #€Kð ð lÝÐk FÐ3[ÐkÐkÐ_jÐkÐkÐkà )Ò+€LØ  :Ñ-Õ1EÒE€Làð SØð 	SÝ Ðr¨Ð7IÐWbÐrÐrÐfqÐrÐrÐrà$ |Ñ3Õ7KÒKˆJØ.8ÐJÐ*Ð*¸lˆKÝ ÐR¨°{ÐRÐRÀkÐRÐRÐRØ	ð 
SØð 	SÝ Ðn¨°~ÐS^ÐnÐnÐbmÐnÐnÐnå ÐR¨°{ÐRÐRÀkÐRÐRÐRàð 	S˜<ð 	SØ'3ÐK�^�^Ð9KˆFÝ Ðf¨°vÈ;ÐfÐfÐZeÐfÐfÐfå ÐR¨°{ÐRÐRÀkÐRÐRÐRr-   Fr8   r’   r‰   ÚexistingÚfilter_matcherÚstatusc
                 ó¢  — |pt          ¦   «         }t          | ¦  «         ot          |¦  «        }
t          | ¦  «        ot          |¦  «         }|
s|st          d¦  «        ‚t          | |t	          j        t          j        ¦  «                             ¦   «         ¬¦  «        }d}|
�r«t          j
                             | ¦  «        }t          |¦  «        }|j        |j        }}t          j
                             |¦  «        st          d|› �¦  «        ‚i }t!          |¦  «        D ]J\  }}}|                     |¦  «        r||f||<   |	r&|	                     dt'          |¦  «        › d�¦  «         ŒK|	r&|	                     dt'          |¦  «        › d�¦  «         i }|	r,	 |                     |¦  «        j        }n# t.          $ r Y nw xY w	 t1          |||¦  «        D ]V\  }}}}|                     |¦  «        r||f||<   |	r1|�d|› �nd}|	                     d	t'          |¦  «        › |› d�¦  «         ŒWn.# t2          $ r! t4                               d
|› d�¦  «         Y nw xY w|	r&|	                     d	t'          |¦  «        › d�¦  «         t9          |                     ¦   «         ¦  «        t9          |                     ¦   «         ¦  «        z  }|	r&|	                     dt'          |¦  «        › d�¦  «         t=          |¦  «        D �]L}|                     |¦  «        }|                     |¦  «        }|r�|sŽ|rF|j          !                    tE          d||d         dtG          |d         ¦  «        ¬¦  «        ¦  «         Œy|j          !                    tE          d||d         dtG          |d         ¦  «        ¬¦  «        ¦  «         Œ¿|r@|r>|\  }}|\  }} |j          !                    tI          |d|||| dd|||¬¦  «        ¦  «         �Œ|sI|rG|rE|j          !                    tE          d||d         dtG          |d         ¦  «        ¬¦  «        ¦  «         �ŒN�nýt          | ¦  «        }|j        |j        }}t          j
                             |¦  «        }i }i }!|	r,	 |                     |¦  «        j        }n# t.          $ r Y nw xY wt1          |||¦  «        D ][\  }}}}"|                     |¦  «        r||f||<   |"|!|<   |	r1|�d|› �nd}|	                     d	t'          |¦  «        › |› d�¦  «         Œ\|	r&|	                     d	t'          |¦  «        › d�¦  «         i }t          j
                             |¦  «        rÁ|r[t!          |¦  «        D ]J\  }}}|                     |¦  «        r||f||<   |	r&|	                     dt'          |¦  «        › d�¦  «         ŒKnd|D ]a}t          j
         %                    ||¦  «        }#tM          |#¦  «        }$|$€Œ4|$||<   |	r&|	                     dt'          |¦  «        › d�¦  «         Œb|	r&|	                     dt'          |¦  «        › d�¦  «         t9          |                     ¦   «         ¦  «        t9          |                     ¦   «         ¦  «        z  }|	r&|	                     dt'          |¦  «        › d�¦  «         t=          |¦  «        D �]t}|                     |¦  «        }|                     |¦  «        }|r¤|s¢|rF|j          !                    tE          d||d         dtG          |d         ¦  «        ¬¦  «        ¦  «         Œy|j          !                    tE          d||d         dtG          |d         ¦  «        |!                     |¦  «        ¬¦  «        ¦  «         ŒÓ|rT|rR|\  }} |\  }}|j          !                    tI          |d|| ||dd||||!                     |¦  «        ¬¦  «        ¦  «         �Œ)|sI|rG|rE|j          !                    tE          d||d         dtG          |d         ¦  «        ¬¦  «        ¦  «         �Œv|S )z‚Compute the sync plan by comparing source and destination.

    Returns:
        SyncPlan with all operations to be performed
    z[One of source or dest must be a bucket path (hf://buckets/...) and the other must be local.©r8   r’   r“   NzSource must be a directory: zScanning local directory (z files)rc   r]   zScanning remote bucket (zBucket 'z' not found, treating as empty.zComparing files (z paths)rŠ   r   znew file (--existing)r   )r‹   rI   r    rŒ   r�   r‡   znew filezlocal newerzremote newer)rI   r‹   rë   rì   rí   rî   rï   rð   rñ   rò   ró   r‰   znot in source (--delete))r‹   rI   r    rŒ   rŽ   rˆ   )r‹   rI   r    rŒ   rŽ   r�   )rI   r‹   rë   rì   rí   rî   rï   rð   rñ   rò   ró   r�   )'r­   r„   rk   r‘   r   Únowr   rè   ré   rH   rI   rÏ   ri   r   rj   rÐ   rÛ   r¸   r(   rh   ÚdoneÚbucket_infor!   Ú	Exceptionrä   r   ÚloggerÚdebugÚsetÚkeysÚsortedÚgetr•   r¿   r†   rê   rþ   r€   rÌ   )%r8   r’   rÜ   r‰   rò   rñ   rÿ   ró   r   r  Ú	is_uploadÚis_downloadÚplanÚremote_totalrÍ   rn   r`   r‚   Úlocal_filesrÚ   r    rã   Úremote_filesrÕ   Ú	total_strÚ	all_pathsrI   Ú
local_infoÚremote_infoÚ
local_sizer�   Úremote_sizerŽ   Úbucket_file_mapr�   Ú
local_filerÙ   s%                                        r+   Ú_compute_sync_planr  *  sG
  € ð" $Ð6¥}¡¤€NÝ# FÑ+Ô+Ð+ÐEµÀÑ0EÔ0E€IÝ! &Ñ)Ô)ÐGµ/À$Ñ2GÔ2GÐ.G€Kàð x˜[ð xÝÐvÑwÔwÐwåØØÝ”,�xœ|Ñ,Ô,×6Ò6Ñ8Ô8ðñ ô €Dð  $€LØñ Så”W—_’_ VÑ,Ô,ˆ
Ý" 4Ñ(Ô(ˆØ"œI vÔ':�6ˆ	åŒw�}Š}˜ZÑ(Ô(ð 	JÝÐH¸JÐHÐHÑIÔIÐIð ˆÝ(9¸*Ñ(EÔ(Eð 	Vð 	VÑ$ˆH�d˜HØ×%Ò% hÑ/Ô/ð 9Ø)-¨xÐ(8�˜HÑ%Øð VØ—’ÐT½3¸{Ñ;KÔ;KÐTÐTÐTÑUÔUÐUøØð 	PØ�KŠKÐNµS¸Ñ5EÔ5EÐNÐNÐNÑOÔOÐOàˆØð 	ðØ"Ÿš¨yÑ9Ô9ÔE��øÝð ð ð Ø�ðøøøð		PÝ/AÀ#ÀyÐRXÑ/YÔ/Yð dð dÑ+�˜$ ¨!Ø!×)Ò)¨(Ñ3Ô3ð >Ø.2°HÐ-=�L Ñ*Øð dØ6BÐ6NÐ 2 LÐ 2Ð 2Ð 2ÐTV�IØ—M’MÐ"b½SÀÑ=NÔ=NÐ"bÐPYÐ"bÐ"bÐ"bÑcÔcÐcøðdøõ #ð 	Pð 	Pð 	På�LŠLÐN IÐNÐNÐNÑOÔOÐOÐOÐOð	Pøøøð ð 	OØ�KŠKÐMµ3°|Ñ3DÔ3DÐMÐMÐMÑNÔNÐNõ ˜×(Ò(Ñ*Ô*Ñ+Ô+­c°,×2CÒ2CÑ2EÔ2EÑ.FÔ.FÑFˆ	Øð 	EØ�KŠKÐC­C°	©N¬NÐCÐCÐCÑDÔDÐDÝ˜9Ñ%Ô%ð 8	ñ 8	ˆDØ$Ÿš¨Ñ.Ô.ˆJØ&×*Ò*¨4Ñ0Ô0ˆKàð 4 +ð 4àð à”O×*Ò*Ý%Ø#)Ø!%Ø!+¨A¤Ø#:Ý(5°jÀ´mÑ(DÔ(Dðñ ô ñô ð ð ð ”O×*Ò*Ý%Ø#+Ø!%Ø!+¨A¤Ø#-Ý(5°jÀ´mÑ(DÔ(Dðñ ô ñô ð ð ð ð  ð à*4Ñ'�
˜KØ,7Ñ)�˜\Ø”×&Ò&Ý+Ø!Ø'Ø$.Ø%0Ø"-Ø#/Ø+8Ø)7Ø%1Ø%1Ø(7ðñ ô ñô ð ñ ð  ð 
 Kð 
°Fð 
à”×&Ò&Ý!Ø'Ø!Ø(¨œ^Ø9Ý%2°;¸q´>Ñ%BÔ%Bðñ ô ñô ð ùña8	õx # 6Ñ*Ô*ˆØ"œI vÔ':�6ˆ	Ý”W—_’_ TÑ*Ô*ˆ
ð ˆØ*,ˆØð 	ðØ"Ÿš¨yÑ9Ô9ÔE��øÝð ð ð Ø�ðøøøå5GÈÈYÐX^Ñ5_Ô5_ð 	`ð 	`Ñ1ˆH�d˜H kØ×%Ò% hÑ/Ô/ð 8Ø*.°Ð)9�˜XÑ&Ø,7� Ñ)Øð `Ø2>Ð2JÐ. Ð.Ð.Ð.ÐPR�	Ø—’Ð^½¸\Ñ9JÔ9JÐ^ÈIÐ^Ð^Ð^Ñ_Ô_Ð_øØð 	OØ�KŠKÐMµ3°|Ñ3DÔ3DÐMÐMÐMÑNÔNÐNàˆÝŒ7�=Š=˜Ñ$Ô$ð 	^Øð ^å0AÀ*Ñ0MÔ0Mð ^ð ^Ñ,�H˜d HØ%×-Ò-¨hÑ7Ô7ð AØ15°xÐ0@˜ HÑ-Øð ^ØŸšÐ&\Å3À{ÑCSÔCSÐ&\Ð&\Ð&\Ñ]Ô]Ð]øð	^ð !-ð ^ð ^�HÝ!#¤§¢¨j¸(Ñ!CÔ!C�JÝ +¨JÑ 7Ô 7�IØ Ð(Ø Ø,5�K Ñ)Øð ^ØŸšÐ&\Å3À{ÑCSÔCSÐ&\Ð&\Ð&\Ñ]Ô]Ð]øØð 	PØ�KŠKÐNµS¸Ñ5EÔ5EÐNÐNÐNÑOÔOÐOõ ˜×)Ò)Ñ+Ô+Ñ,Ô,­s°;×3CÒ3CÑ3EÔ3EÑ/FÔ/FÑFˆ	Øð 	EØ�KŠKÐC­C°	©N¬NÐCÐCÐCÑDÔDÐDÝ˜9Ñ%Ô%ð :	ñ :	ˆDØ&×*Ò*¨4Ñ0Ô0ˆKØ$Ÿš¨Ñ.Ô.ˆJàð 6 :ð 6àð à”O×*Ò*Ý%Ø#)Ø!%Ø!,¨Q¤Ø#:Ý)6°{À1´~Ñ)FÔ)Fðñ ô ñô ð ð ð ”O×*Ò*Ý%Ø#-Ø!%Ø!,¨Q¤Ø#-Ý)6°{À1´~Ñ)FÔ)FØ(7×(;Ò(;¸DÑ(AÔ(Aðñ ô ñ	ô 	ð 	ð 	ð ð  ð à,7Ñ)�˜\Ø*4Ñ'�
˜KØ”×&Ò&Ý+Ø!Ø)Ø$/Ø%1Ø",Ø#.Ø+9Ø)6Ø%1Ø%1Ø(7Ø$3×$7Ò$7¸Ñ$=Ô$=ðñ ô ñô ð ñ ð  !ð 
 Zð 
°Fð 
à”×&Ò&Ý!Ø'Ø!Ø'¨œ]Ø9Ý$1°*¸Q´-Ñ$@Ô$@ðñ ô ñô ð ùð €Ks7   ÆF8 Æ8
GÇGÇ	A(H2 È2(IÉIÒR0 Ò0
R=Ò<R=r  c                 ó¦  — d| j         | j        | j        |                      ¦   «         dœ}|                     t          j        |¦  «        dz   ¦  «         | j        D ]u}d|j        |j	        |j
        dœ}|j        �
|j        |d<   |j        �
|j        |d<   |j        �
|j        |d	<   |                     t          j        |¦  «        dz   ¦  «         ŒvdS )
z1Write a sync plan as JSONL to a file-like object.Úheader)rr   r8   r’   r“   r©   ú
Ú	operation)rr   r‹   rI   rŒ   Nr    r�   rŽ   )r8   r’   r“   r©   ÚwriteÚjsonÚdumpsr•   r‹   rI   rŒ   r    r�   rŽ   )r  rÁ   r  r›   Úop_dicts        r+   Ú_write_planr%  &  sì   € ð Ø”+Ø”	Ø”^Ø—<’<‘>”>ðð €Fð ‡G‚G�DŒJ�vÑÔ Ñ%Ñ&Ô&Ð&ð Œoð ,ð ,ˆàØ”iØ”GØ”ið	#
ð #
ˆð Œ7ÐØ œgˆG�F‰OØŒ>Ð%Ø%'¤^ˆG�MÑ"ØŒ?Ð&Ø&(¤oˆG�NÑ#Ø	�Š•”
˜7Ñ#Ô# dÑ*Ñ+Ô+Ð+Ð+ð,ð ,r-   Ú	plan_filec                 óx   — t          |d¦  «        5 }t          | |¦  «         ddd¦  «         dS # 1 swxY w Y   dS )z!Save a sync plan to a JSONL file.ÚwN)r¾   r%  )r  r&  rÁ   s      r+   Ú
_save_planr)  C  sƒ   € å	ˆi˜Ñ	Ô	ð  Ý�D˜!ÑÔÐðð ð ñ ô ð ð ð ð ð ð ð øøøð ð ð ð ð ð s   ‘/¯3¶3c                 óò  — t          | ¦  «        5 }|                     ¦   «         }ddd¦  «         n# 1 swxY w Y   |st          d| › �¦  «        ‚t          j        |d         ¦  «        }|                     d¦  «        dk    rt          d¦  «        ‚t          |d         |d         |d	         ¬
¦  «        }|dd…         D ]¶}t          j        |¦  «        }|                     d¦  «        dk    rŒ0|j                             t          |d         |d         |                     d¦  «        |                     dd¦  «        |                     d¦  «        |                     d¦  «        ¬¦  «        ¦  «         Œ·|S )z#Load a sync plan from a JSONL file.NzEmpty plan file: r   rr   r  z0Invalid plan file: expected header as first liner8   r’   r“   r  r   r   r‹   rI   r    rŒ   r]   r�   rŽ   )r‹   rI   r    rŒ   r�   rŽ   )
r¾   Ú	readlinesrk   r"  Úloadsr  r‘   r•   r¿   r†   )r&  rÁ   Úlinesr  r  rÂ   r$  s          r+   Ú
_load_planr.  I  s»  € å	ˆi‰Œð ˜AØ—’‘”ˆðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ð :ÝÐ8¨YÐ8Ð8Ñ9Ô9Ð9õ ŒZ˜˜aœÑ!Ô!€FØ‡z‚z�&ÑÔ˜XÒ%Ð%ÝÐKÑLÔLÐLåØ�hÔØ�FŒ^Ø˜Ô%ðñ ô €Dð �a�b�b”	ð 
ð 
ˆÝ”*˜TÑ"Ô"ˆØ�;Š;�vÑÔ +Ò-Ð-ØØŒ×ÒÝØ˜xÔ(Ø˜V”_Ø—[’[ Ñ(Ô(Ø—{’{ 8¨RÑ0Ô0Ø#ŸKšK¨Ñ6Ô6Ø$Ÿ[š[¨Ñ8Ô8ðñ ô ñ		
ô 		
ð 		
ð 		
ð €Ks   �1±5¸5Úverbosec                 ó¼
  — t          | j        ¦  «         ot          | j        ¦  «        }t          | j        ¦  «        ot          | j        ¦  «         }|�rt          j                             | j        ¦  «        }t          | j        ¦  «        }|j        |j        }	}g }
g }| j	        D �]}|j
        xdk    ru t          j                             ||j        ¦  «        }|	r|	› d|j        › �n|j        }|r t          d|j        › d|j        › d�¦  «         |
                     ||f¦  «         Œ„xdk    rN |	r|	› d|j        › �n|j        }|r t          d|j        › d|j        › d�¦  «         |                     |¦  «         ŒØdk    r$|r"t          d	|j        › d|j        › d�¦  «         �Œ�Œ|
s|r¬|rŒg }|
r&|                     d
t          |
¦  «        › d�¦  «         |r&|                     dt          |¦  «        › d�¦  «         |                     d                     |¦  «                             ¦   «         ¦  «         |                     ||
pd|pd¬¦  «         dS dS |�rût          | j        ¦  «        }|j        |j        }	}t          j                             | j        ¦  «        }t          j        |d¬¦  «         g }g }| j	        D �]o}|j
        dk    rËt          j                             ||j        ¦  «        }t          j        t          j                             |¦  «        d¬¦  «         |r t          d|j        › d|j        › d�¦  «         |j        �|                     |j        |f¦  «         Œ¬|	r|	› d|j        › �n|j        }|                     ||f¦  «         ŒÙ|j
        dk    r^t          j                             ||j        ¦  «        }|r t          d|j        › d|j        › d�¦  «         |                     |¦  «         �ŒB|j
        dk    r"|r t          d	|j        › d|j        › d�¦  «         �Œqt          |¦  «        dk    r>|r&|                     dt          |¦  «        › d�¦  «         |                     ||¦  «         |r(|r&|                     dt          |¦  «        › d�¦  «         |D ]§}t          j                             |¦  «        r„t          j        |¦  «         t          j                             |¦  «        }||k    rK	 t          j        |¦  «         t          j                             |¦  «        }n# t4          $ r Y n
w xY w||k    °KŒ¦dS dS )zExecute a sync plan.r‡   rc   z  Uploading: z (ú)r‰   z  Deleting: rŠ   z  Skipping: z
uploading z filesz	deleting z, N)Úaddr‰   T)Úexist_okrˆ   z  Downloading: r   zDownloading z	Deleting z local files)r„   r8   r’   rH   rI   rÏ   ri   r   rj   r•   r‹   r€   ÚprintrŒ   r¿   rh   r  Ú
capitalizeÚbatch_bucket_filesÚmakedirsÚdirnamer�   Údownload_bucket_filesÚexistsÚremoveÚrmdirrÆ   )r  rÜ   r/  r  r  r  rÍ   rn   r`   r‚   Ú	add_filesÚdelete_pathsr›   r  Úremote_pathr�   Údownload_filesÚdelete_filesÚ	file_pathÚparents                       r+   Ú_execute_planrD  t  s  € å# D¤KÑ0Ô0Ð0ÐOµ_ÀTÄYÑ5OÔ5O€IÝ! $¤+Ñ.Ô.ÐQµÀtÄyÑ7QÔ7QÐ3Q€Kàñ \Ý”W—_’_ T¤[Ñ1Ô1ˆ
Ý" 4¤9Ñ-Ô-ˆØ"œI vÔ':�6ˆ	ð ;=ˆ	Ø"$ˆà”/ð 	Bñ 	BˆBØ”)Ø�X’X�X�XÝ!#¤§¢¨j¸"¼'Ñ!BÔ!B�JØ;AÐ"N VÐ"7Ð"7¨b¬gÐ"7Ð"7Ð"7ÀrÄw�KØð GÝÐE¨b¬gÐEÐE¸¼ÐEÐEÐEÑFÔFÐFØ×$Ò$ j°+Ð%>Ñ?Ô?Ð?Ð?Ø�X’X�X�XØ;AÐ"N VÐ"7Ð"7¨b¬gÐ"7Ð"7Ð"7ÀrÄw�KØð FÝÐD¨R¬WÐDÐD¸¼	ÐDÐDÐDÑEÔEÐEØ ×'Ò'¨Ñ4Ô4Ð4Ð4Ø’V�V˜w�VÝÐ@¨¬Ð@Ð@°B´IÐ@Ð@Ð@ÑAÔAÐAÑAùð ð 	˜ð 	Øð ;Ø�Øð FØ—L’LÐ!D­c°)©n¬nÐ!DÐ!DÐ!DÑEÔEÐEØð HØ—L’LÐ!F­S°Ñ->Ô->Ð!FÐ!FÐ!FÑGÔGÐGØ—’˜DŸIšI eÑ,Ô,×7Ò7Ñ9Ô9Ñ:Ô:Ð:Ø×"Ò"ØØÐ% Ø#Ð+ tð #ñ ô ð ð ð ð	ð 	ð 
ñ 4Ý" 4¤;Ñ/Ô/ˆØ"œI vÔ':�6ˆ	Ý”W—_’_ T¤YÑ/Ô/ˆ
õ 	Œ�J¨Ð.Ñ.Ô.Ð.ð EGˆØ"$ˆà”/ð 	>ñ 	>ˆBØŒy˜JÒ&Ð&ÝœWŸ\š\¨*°b´gÑ>Ô>�
å”�BœGŸOšO¨JÑ7Ô7À$ÐGÑGÔGÐGØð EÝÐC¨B¬GÐCÐC°r´yÐCÐCÐCÑDÔDÐDà”>Ð-Ø"×)Ò)¨2¬>¸:Ð*FÑGÔGÐGÐGà;AÐ"N VÐ"7Ð"7¨b¬gÐ"7Ð"7Ð"7ÀrÄw�KØ"×)Ò)¨;¸
Ð*CÑDÔDÐDÐDØ”˜hÒ&Ð&ÝœWŸ\š\¨*°b´gÑ>Ô>�
Øð BÝÐ@¨¬Ð@Ð@°B´IÐ@Ð@Ð@ÑAÔAÐAØ×#Ò# JÑ/Ô/Ð/Ñ/Ø”˜fÒ$Ð$¨Ð$ÝÐ< R¤WÐ<Ð<°´	Ð<Ð<Ð<Ñ=Ô=Ð=ùõ ˆ~ÑÔ Ò"Ð"Øð HØ—’ÐF­3¨~Ñ+>Ô+>ÐFÐFÐFÑGÔGÐGØ×%Ò% i°Ñ@Ô@Ð@ð ð 	E�lð 	EØ�KŠKÐC¥C¨Ñ$5Ô$5ÐCÐCÐCÑDÔDÐDØ%ð 
	ð 
	ˆIÝŒw�~Š~˜iÑ(Ô(ð 	Ý”	˜)Ñ$Ô$Ð$åœŸš¨Ñ3Ô3�Ø 
Ò*Ð*ðÝœ Ñ(Ô(Ð(Ý!#¤§¢°Ñ!8Ô!8˜˜øÝ"ð ð ð Ø˜ðøøøð	  
Ò*Ð*øð_4ð 4ðT
	ð 
	s   Ô3UÕ
UÕUc                 ó,  — |                       ¦   «         }t          d| j        › d| j        › �¦  «         t          d|d         › �¦  «         t          d|d         › �¦  «         t          d|d         › �¦  «         t          d	|d
         › �¦  «         dS )z!Print a summary of the sync plan.zSync plan: z -> z  Uploads: r£   z  Downloads: r¤   z  Deletes: r¥   z	  Skips: r¦   N)r©   r4  r8   r’   )r  r©   s     r+   Ú_print_plan_summaryrF  Ø  s¨   € à�lŠl‰nŒn€GÝ	Ð
4˜œÐ
4Ð
4¨¬Ð
4Ð
4Ñ5Ô5Ð5Ý	Ð
,˜ 	Ô*Ð
,Ð
,Ñ-Ô-Ð-Ý	Ð
0˜' +Ô.Ð
0Ð
0Ñ1Ô1Ð1Ý	Ð
,˜ 	Ô*Ð
,Ð
,Ñ-Ô-Ð-Ý	Ð
(�g˜gÔ&Ð
(Ð
(Ñ)Ô)Ð)Ð)Ð)r-   )r‰   rò   rñ   rÿ   ró   ÚincludeÚexcludeÚfilter_fromr  ÚapplyÚdry_runr/  ÚquietÚtokenrG  rH  rI  rJ  rK  rL  rM  c                ó.  — |�0ddl m}  ||j        ||j        |j        |j        |j        ¬¦  «        }|�r[| s|rt          d¦  «        ‚|�t          d¦  «        ‚|rt          d¦  «        ‚|rt          d¦  «        ‚|rt          d	¦  «        ‚|rt          d
¦  «        ‚|	rt          d¦  «        ‚|
rt          d¦  «        ‚|rt          d¦  «        ‚|rt          d¦  «        ‚|rt          d¦  «        ‚t          |¦  «        }t          | ¬¦  «        }|st          |¦  «         t          d¦  «         |rt          ¦   «          	 t          ||||¬¦  «         |rt          ¦   «          n# |rt          ¦   «          w w xY w|st          d¦  «         |S | r|st          d¦  «        ‚t          | ¦  «        }t          |¦  «        }|r|rt          d¦  «        ‚|s|st          d¦  «        ‚|r|rt          d¦  «        ‚|r|rt          d¦  «        ‚|r|rt          d¦  «        ‚|rQt           j                             |¦  «        r1t           j                             |¦  «        st          d|› �¦  «        ‚n1t           j                             | ¦  «        st          d| › �¦  «        ‚d}|
rt)          |
¦  «        }t+          ||	|¬¦  «        }t          | o| ¬¦  «        }t-          | |||||||||¬¦
  «
        }|rt/          |t0          j        ¦  «         |S |r5t5          ||¦  «         |s!t          |¦  «         t          d|› �¦  «         |S |st          |¦  «         |                     ¦   «         }|d         d k    r+|d!         d k    r|d"         d k    r|st          d#¦  «         |S |st          d$¦  «         |rt          ¦   «          	 t          ||||¬¦  «         |rt          ¦   «          n# |rt          ¦   «          w w xY w|st          d¦  «         |S )%a  Sync files between a local directory and a bucket.

    This is equivalent to the ``hf buckets sync`` CLI command. One of ``source`` or ``dest`` must be a bucket path
    (``hf://buckets/...``) and the other must be a local directory path.

    Args:
        source (`str`, *optional*):
            Source path: local directory or ``hf://buckets/namespace/bucket_name(/prefix)``.
            Required unless using ``apply``.
        dest (`str`, *optional*):
            Destination path: local directory or ``hf://buckets/namespace/bucket_name(/prefix)``.
            Required unless using ``apply``.
        api ([`HfApi`]):
            The HfApi instance to use for API calls.
        delete (`bool`, *optional*, defaults to `False`):
            Delete destination files not present in source.
        ignore_times (`bool`, *optional*, defaults to `False`):
            Skip files only based on size, ignoring modification times.
        ignore_sizes (`bool`, *optional*, defaults to `False`):
            Skip files only based on modification times, ignoring sizes.
        existing (`bool`, *optional*, defaults to `False`):
            Skip creating new files on receiver (only update existing files).
        ignore_existing (`bool`, *optional*, defaults to `False`):
            Skip updating files that exist on receiver (only create new files).
        include (`list[str]`, *optional*):
            Include files matching patterns (fnmatch-style).
        exclude (`list[str]`, *optional*):
            Exclude files matching patterns (fnmatch-style).
        filter_from (`str`, *optional*):
            Path to a filter file with include/exclude rules.
        plan (`str`, *optional*):
            Save sync plan to this JSONL file instead of executing.
        apply (`str`, *optional*):
            Apply a previously saved plan file. When set, ``source`` and ``dest`` are not needed.
        dry_run (`bool`, *optional*, defaults to `False`):
            Print sync plan to stdout as JSONL without executing.
        verbose (`bool`, *optional*, defaults to `False`):
            Show detailed per-file operations.
        quiet (`bool`, *optional*, defaults to `False`):
            Suppress all output and progress bars.
        token (Union[bool, str, None], optional):
            A valid user access token. If not provided, the locally saved token will be used.

    Returns:
        [`SyncPlan`]: The computed (or loaded) sync plan.

    Raises:
        `ValueError`: If arguments are invalid (e.g., both paths are remote, conflicting options).

    Example:
        ```python
        >>> from huggingface_hub import HfApi
        >>> api = HfApi()

        # Upload local directory to bucket
        >>> api.sync_bucket("./data", "hf://buckets/username/my-bucket")

        # Download bucket to local directory
        >>> api.sync_bucket("hf://buckets/username/my-bucket", "./data")

        # Sync with delete and filtering
        >>> api.sync_bucket(
        ...     "./data",
        ...     "hf://buckets/username/my-bucket",
        ...     delete=True,
        ...     include=["*.safetensors"],
        ... )

        # Dry run: preview what would be synced
        >>> plan = api.sync_bucket("./data", "hf://buckets/username/my-bucket", dry_run=True)
        >>> plan.summary()
        {'uploads': 3, 'downloads': 0, 'deletes': 0, 'skips': 1, 'total_size': 4096}

        # Save plan for review, then apply
        >>> api.sync_bucket("./data", "hf://buckets/username/my-bucket", plan="sync-plan.jsonl")
        >>> api.sync_bucket(apply="sync-plan.jsonl")
        ```
    Nr   r   )r^   rM  Úlibrary_nameÚlibrary_versionÚ
user_agentÚheadersz,Cannot specify source/dest when using apply.z#Cannot specify both plan and apply.z'Cannot specify delete when using apply.z-Cannot specify ignore_times when using apply.z-Cannot specify ignore_sizes when using apply.z(Cannot specify include when using apply.z(Cannot specify exclude when using apply.z,Cannot specify filter_from when using apply.z)Cannot specify existing when using apply.z0Cannot specify ignore_existing when using apply.z(Cannot specify dry_run when using apply.)ÚenabledzExecuting plan...)r/  r  zSync completed.z7Both source and dest are required (unless using apply).z?Remote to remote sync is not supported. One path must be local.z?One of source or dest must be a bucket path (hf://buckets/...).z2Cannot specify both ignore_times and ignore_sizes.z1Cannot specify both existing and ignore_existing.z%Cannot specify both dry_run and plan.z!Destination must be a directory: z&Source must be an existing directory: r²   )
r8   r’   rÜ   r‰   rò   rñ   rÿ   ró   r   r  zPlan saved to: r£   r   r¤   r¥   zNothing to sync.z
Syncing...)Úhf_apir   r^   rO  rP  rQ  rR  rk   r.  r   rF  r4  r   rD  r   r„   rH   rI   r:  rÐ   rÃ   r­   r  r%  ÚsysÚstdoutr)  r©   )r8   r’   rÜ   r‰   rò   rñ   rÿ   ró   rG  rH  rI  r  rJ  rK  r/  rL  rM  r   Ú	sync_planr  Úsource_is_bucketÚdest_is_bucketr°   r   r©   s                            r+   Úsync_bucket_internalrZ  ç  s‘  € ðF ÐØ!Ð!Ð!Ð!Ð!Ð!àˆeØ”\ØØÔ)ØÔ/Ø”~Ø”Kð
ñ 
ô 
ˆð ñ )Øð 	M�Tð 	MÝÐKÑLÔLÐLØÐÝÐBÑCÔCÐCØð 	HÝÐFÑGÔGÐGØð 	NÝÐLÑMÔMÐMØð 	NÝÐLÑMÔMÐMØð 	IÝÐGÑHÔHÐHØð 	IÝÐGÑHÔHÐHØð 	MÝÐKÑLÔLÐLØð 	JÝÐHÑIÔIÐIØð 	QÝÐOÑPÔPÐPØð 	IÝÐGÑHÔHÐHå˜uÑ%Ô%ˆ	Ý¨ IÐ.Ñ.Ô.ˆØð 	'Ý 	Ñ*Ô*Ð*ÝÐ%Ñ&Ô&Ð&àð 	$Ý!Ñ#Ô#Ð#ð	'Ý˜) S°'À&ÐIÑIÔIÐIàð 'Ý$Ñ&Ô&Ð&øøð ð 'Ý$Ñ&Ô&Ð&Ð&ð'øøøð ð 	%ÝÐ#Ñ$Ô$Ð$àÐð ð T˜ð TÝÐRÑSÔSÐSå& vÑ.Ô.ÐÝ$ TÑ*Ô*€Nàð \˜Nð \ÝÐZÑ[Ô[Ð[àð \ Nð \ÝÐZÑ[Ô[Ð[àð O˜ð OÝÐMÑNÔNÐNàð N�Oð NÝÐLÑMÔMÐMàð B�4ð BÝÐ@ÑAÔAÐAð ð PÝŒ7�>Š>˜$ÑÔð 	I­¬¯ª°dÑ(;Ô(;ð 	IÝÐGÀÐGÐGÑHÔHÐHøåŒw�}Š}˜VÑ$Ô$ð 	PÝÐNÀfÐNÐNÑOÔOÐOð €LØð 7Ý)¨+Ñ6Ô6ˆå"Ø Ø Ø!ðñ ô €Nõ  E 	Ð 9°'¨kÐ:Ñ:Ô:€FÝ"ØØØØØ!Ø!ØØ'Ø%Øðñ ô €Ið ð Ý�I�sœzÑ*Ô*Ð*ØÐàð Ý�9˜dÑ#Ô#Ð#Øð 	,Ý 	Ñ*Ô*Ð*ÝÐ* DÐ*Ð*Ñ+Ô+Ð+ØÐð ð 'Ý˜IÑ&Ô&Ð&à×ÒÑ!Ô!€GØˆyÔ˜QÒÐ 7¨;Ô#7¸1Ò#<Ð#<ÀÈÔASÐWXÒAXÐAXØð 	&ÝÐ$Ñ%Ô%Ð%ØÐàð ÝˆlÑÔÐàð  ÝÑÔÐð#Ý�i ¨g¸fÐEÑEÔEÐEàð 	#Ý Ñ"Ô"Ð"øøð ð 	#Ý Ñ"Ô"Ð"Ð"ð	#øøøð ð !ÝÐÑ Ô Ð àÐs   ÅE( Å(E;Ï
O. Ï.P)FFFFFNN)FN)NN)Kr1   rµ   r"  rE   rH   rÅ   rU  rK   Úcollections.abcr   Údataclassesr   r   r   r   Úpathlibr   Útypingr	   r
   r   r]   r   r   Úerrorsr   Úutilsr   r   r   r   r   r   r   Úutils._hf_urisr   rT  r   Ú
get_loggerr.   r  ÚBUCKET_PREFIXrö   r   r7   rP   rU   rX   r[   rp   rx   r2   ri   r4   r„   r†   r‘   r­   rª   r¹   rÃ   r5   ÚfloatrÌ   rÛ   rä   rê   rþ   r  r%  r)  r.  rD  rF  rZ  r%   r-   r+   ú<module>re     sî  ððð ð
 €€€Ø €€€Ø Ð Ð Ð Ø 	€	€	€	Ø €€€Ø 
€
€
€
Ø €€€Ø $Ð $Ð $Ð $Ð $Ð $Ø (Ð (Ð (Ð (Ð (Ð (Ð (Ð (Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø Ð Ð Ð Ð Ð Ø .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .à  Ð  Ð  Ð  Ð  Ð  Ð  Ð  Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð /Ð .Ð .Ð .Ð .Ð .ð ð ØÐÐÐÐÐð 
ˆÔ	˜HÑ	%Ô	%€ð  €ØÐ ð ð'ð 'ð 'ð 'ð 'ñ 'ô 'ñ „ð'ð@ ð
ð 
ð 
ð 
ð 
ñ 
ô 
ñ „ð
ð* ð-ð -ð -ð -ð -ñ -ô -ñ „ð-ð ðð ð ð ð ñ ô ñ „ðð €�$ÐÑÔðð ð ð ð ñ ô ñ Ôðð  ð$ð $ð $ð $ð $ñ $ô $ñ „ð$ðN ðPð Pð Pð Pð Pñ Pô Pñ „ðPð2 ð
ð 
ð 
ð 
ð 
ñ 
ô 
ñ „ð
ð6C˜Cð C Eð Cð Cð Cð Cð,(˜#ð ( $ð (ð (ð (ð (ð  ð	*ð 	*ð 	*ð 	*ð 	*ñ 	*ô 	*ñ „ð	*ð ð
ð 
ð 
ð 
ð 
ñ 
ô 
ñ „ð
ð8.ð .ð .ð .ð .ñ .ô .ð .ðb Cð ¨D°°s¸C°x´Ô,Að ð ð ð ð:*�cð *˜e C¨ JÔ/°$Ñ6ð *ð *ð *ð *ð7 #ð 7¨(°5¸¸cÀ5¸Ô3IÔ*Jð 7ð 7ð 7ð 7ð,2˜Gð 2°ð 2¸Sð 2ÀXÈeÐTWÐY\Ð^cÐehÐThÔNiÔEjð 2ð 2ð 2ð 2ðDP˜Eð P cð Pð Pð Pð Pð$ #ðESð ESð ESà
ðESð Ð(Ô)ðESð ð	ESð
 ðESð ðESð ðESð ðESð ðESð ðESð ðESð ðESð �t‘ðESð ðESð ESð ESð ESðX ØØØØ!Ø+/Øðtð tØðtà
ðtð 
ðtð ð	tð
 ðtð ðtð ðtð ðtð " DÑ(ðtð �$‰Jðtð ðtð tð tð tðx,�hð , dð ,ð ,ð ,ð ,ð:�Xð ¨#ð °$ð ð ð ð ð#˜#ð # (ð #ð #ð #ð #ðVað a˜ð a wð a¸ð aÈsÐUYÉzð aÐeið að að að aðH*˜hð *¨4ð *ð *ð *ð *ð  Øðuð
 ØØØØ!Ø $Ø $Ø"ØØØØØØ#ð%uð uð uØ�$‰Jðuà
�‰*ðuð 
ð	uð
 ðuð ðuð ðuð ðuð ðuð �#ŒY˜Ñðuð �#ŒY˜Ñðuð �t‘ðuð �‰*ðuð �‰:ðuð ðuð  ð!uð" ð#uð$ �#‰:˜Ñð%uð& ð'uð uð uð uð uð ur-   