Ë
    ÂÓ^j¦k  ã            
       ó�  — U d Z ddlZddlZddlmZmZ ddlmZmZm	Z	 ddl
mZ ddlmZmZ ddlmZ ej"                  j%                  «       D � �ci c]  \  } }|| “Œ
 c}} Zeeef   ed	<    ej.                  d
«      Z eej"                  j5                  «       «      Zee   ed<    eh d£«      Zee   ed<    eddh«      Zee   ed<    ed¬«       G d„ d«      «       Z ed¬«       G d„ d«      «       Zdede fd„Z!ejD                  d-dededz  defd„«       Z#dedz  de$edz  ef   fd„Z%dedz  dee   fd„Z&d-dededz  de fd„Z'dedefd „Z(d-d!ededz  defd"„Z)d#edefd$„Z*d%ed&ede$eedz  e dz  f   fd'„Z+d(ed&ede$ejX                  ef   fd)„Z-d(ed*ejX                  d&edefd+„Z.d(ed*ejX                  d&edefd,„Z/yc c}} w ).a  Centralized parser for Hugging Face Hub URIs ('hf://...') and mount specifications.

A HF URI is a URI-like string that identifies a location on the Hugging Face
Hub: a model/dataset/space/kernel repository, a bucket, optionally a revision,
and optionally a path inside the repo or bucket.

Canonical syntax:

```
hf://[<TYPE>/]<ID>[@<REVISION>][/<PATH>]
```

For convenience, [`parse_hf_uri`] also accepts Hugging Face **web URLs** (the
ones you copy-paste from your browser), e.g.
'https://huggingface.co/datasets/my-org/my-dataset/blob/main/train.csv'. They are
normalized to the canonical 'hf://' form before parsing. Only unambiguous URLs
(repository / bucket pages and file/folder viewer routes) are accepted; any other
route is rejected rather than guessed.

A HF mount wraps a HF URI with a local mount path and an optional ':ro'/':rw'
flag (used by Spaces and Jobs volumes):

```
hf://[<TYPE>/]<ID>[@<REVISION>][/<PATH>]:<MOUNT_PATH>[:ro|:rw]
```

See 'docs/source/en/package_reference/hf_uris.md' for the full grammar and examples.
é    N)Ú	dataclassÚfield)ÚquoteÚunquoteÚurlsplit)Ú	constants)Ú
HfUriErrorÚHFValidationErroré   )Úvalidate_repo_idÚ_TYPE_TO_PREFIXz ^refs/(?:convert/[\w.-]+|pr/\d+)Ú_VALID_URI_TYPES>   ÚrawÚblobÚtreeÚblameÚresolveÚ_URL_REPO_LOCATION_ACTIONSr   r   Ú_URL_BUCKET_LOCATION_ACTIONST)Úfrozenc                   óÜ   — e Zd ZU dZej
                  ed<   eed<   dZedz  ed<   dZ	eed<    e
dddd¬	«      Zedz  ed
<   dd„Zedefd„«       Zedefd„«       Zdefd„Zddedz  defd„Zy)ÚHfUriaé  Parsed representation of a Hugging Face Hub URI ('hf://...').

    Attributes:
        type (`str`):
            One of 'model', 'dataset', 'space', 'kernel' or 'bucket'.
        id (`str`):
            The repository id ('namespace/name', e.g. 'my-org/my-model') for repo URIs, or the bucket id ('namespace/name') for bucket URIs.
        revision (`str`, *optional*):
            The revision specified after '@' in the URI, URL-decoded. 'None' if no revision was specified, or for bucket URIs (which
            never carry a revision). Special refs like 'refs/pr/10' and 'refs/convert/parquet' are preserved as-is.
        path_in_repo (`str`):
            The path inside the repo or bucket. Empty string if the URI points at the root.
    ÚtypeÚidNÚrevisionÚ Úpath_in_repoF©ÚreprÚhashÚcompareÚdefaultÚ_rawÚreturnc           	      óþ  — | j                   xs d}| j                  t        vr+t        |d| j                  › dt	        t        «      › d�¬«      ‚| j
                  r| j
                  j                  d«      dk7  rt        |d| j
                  › d	�¬«      ‚| j                  d
k7  r	 t        | j
                  «       | j                  �| j                  st        |d¬«      ‚| j                  d
k(  r| j                  �t        |d¬«      ‚| j                  rE| j                  j                  d«      sd| j                  v rt        |d| j                  › d�¬«      ‚y y # t        $ r}t        |t        |«      ¬«      |‚d }~ww xY w)Nr   zInvalid type 'z'. Must be one of ú.©ÚuriÚmsgú/r   z"Id must be 'namespace/name', got 'ú'.Úbucketz%Revision must not be an empty string.z&Bucket URIs do not support a revision.ú//z+Path must not contain empty segments (got 'z').)r#   r   r   r	   Úsortedr   Úcountr   r
   Ústrr   r   Ú
startswith)Úselfr(   Úes      úi/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/huggingface_hub/utils/_hf_uris.pyÚ__post_init__zHfUri.__post_init__d   s]  € Ø�i‰iŠo˜2ˆð �9‰9Ô,Ñ,Ü ¨N¸4¿9¹9¸+ÐEWÔX^Ô_oÓXpÐWqÐqrÐ*sÔtÐtð �wŠw˜$Ÿ'™'Ÿ-™-¨Ó,°Ò1Ü Ð,NÈtÏwÉwÈiÐWYÐ*ZÔ[Ð[Ø�9‰9˜Ò ð=Ü  §¡Ô)ð
 �=‰=Ð$¨T¯]ª]Ü Ð*QÔRÐRØ�9‰9˜Ò  T§]¡]Ð%>Ü Ð*RÔSÐSð ×ÒØ× Ñ ×+Ñ+¨CÔ0°D¸D×<MÑ<MÑ4MÜ  SÐ0[Ð\`×\mÑ\mÐ[nÐnqÐ.rÔsÐsð 5Nð øô %ò =Ü  S¬c°!«fÔ5¸1Ð<ûð=ús   Â#E Å	E<Å E7Å7E<c                 ó    — | j                   dk(  S )z$True if this URI points at a bucket.r,   ©r   ©r2   s    r4   Ú	is_bucketzHfUri.is_bucket   ó   € ð �y‰y˜HÑ$Ð$ó    c                 ó    — | j                   dk7  S )zJTrue if this URI points at a repository (model, dataset, space or kernel).r,   r7   r8   s    r4   Úis_repozHfUri.is_repo„   r:   r;   c                 ó„  — t         j                  t        | j                     d| j                  g}| j
                  �K| j
                  }d|v r't        j                  |«      €|j                  dd«      }|j                  d|› �«       | j                  r|j                  d| j                  › �«       dj                  |«      S )z’Render the URI as a canonical 'hf://' string.

        The type prefix is always written explicitly (e.g. 'hf://models/my-org/my-model').
        r*   ú%2Fú@r   )r   ÚHF_PROTOCOLr   r   r   r   Ú_SPECIAL_REFS_REVISION_REGEXÚ	fullmatchÚreplaceÚappendr   Újoin)r2   Úpartsr   s      r4   Úto_urizHfUri.to_uri‰   sª   € ô
 &×1Ñ1´?À4Ç9Á9Ñ3MÈsÐTX×T[ÑT[Ð\ˆØ�=‰=Ð$ð —}‘}ˆHØ�h‰Ô#?×#IÑ#IÈ(Ó#SÐ#[Ø#×+Ñ+¨C°Ó7�Ø�L‰L˜1˜X˜J˜Ô(Ø×ÒØ�L‰L˜1˜T×.Ñ.Ð/Ð0Ô1Ø�w‰w�u‹~Ðr;   Úendpointc                 ó  — |xs t         j                  j                  d«      }t        | j                  d¬«      }| j
                  dk(  r|› d| j                  › �}|r|d|› �z  }|S | j
                  dk(  r|› d| j                  › �n$|› dt        | j
                     › d| j                  › �}| j                  }|�"t        j                  |«      €t        |d¬«      }|r|d|xs t         j                  › d|› �z  }|S |�|d|› �z  }|S )	a  Render the URI as a Hugging Face **web URL** (the kind you open in a browser).

        This is the inverse of parsing a URL with [`parse_hf_uri`]. The returned URL points at:

        - the repository / bucket landing page when no path or revision is set;
        - the folder viewer ('/tree/<revision>') when only a revision is set;
        - the file viewer ('/blob/<revision>/<path>') for repository files (revision defaults to 'main');
        - the tree route ('/tree/<path>') for bucket files (buckets are not versioned).

        Args:
            endpoint (`str`, *optional*):
                Base endpoint to use. Defaults to 'constants.ENDPOINT' (i.e. 'https://huggingface.co').

        Returns:
            `str`: the web URL.

        Example:
            ```py
            >>> from huggingface_hub import parse_hf_uri
            >>> parse_hf_uri("hf://datasets/my-org/my-dataset@v1/train.csv").to_url()
            'https://huggingface.co/datasets/my-org/my-dataset/blob/v1/train.csv'
            ```
        r*   )Úsafer,   z	/buckets/z/tree/Úmodelr   z/blob/)r   ÚENDPOINTÚrstripr   r   r   r   r   r   rB   rC   ÚDEFAULT_REVISION)r2   rI   ÚbaseÚpathÚurlr   s         r4   Úto_urlzHfUri.to_url›   s.  € ð0 Ò.œI×.Ñ.×6Ñ6°sÓ;ˆô �T×&Ñ&¨SÔ1ˆà�9‰9˜Ò Ø�F˜) D§G¡G 9Ð-ˆCÙØ˜ ˜v�Ñ&�ØˆJð &*§Y¡Y°'Ò%9���a˜Ÿ™�yÑ!À$ÀÀqÌÐY]×YbÑYbÑIcÐHdÐdeÐfj×fmÑfmÐenÐ?oˆØ—=‘=ˆð
 ÐÔ$@×$JÑ$JÈ8Ó$TÐ$\Ü˜X¨BÔ/ˆHÙØ�V˜HÒB¬	×(BÑ(BÐCÀ1ÀTÀFÐKÑKˆCð ˆ
ð Ð!Ø�V˜H˜:Ð&Ñ&ˆCØˆ
r;   ©r$   N©N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú	HfUriTypeÚ__annotations__r0   r   r   r   r#   r5   ÚpropertyÚboolr9   r=   rH   rS   © r;   r4   r   r   N   sª   … ñð ×
Ñ
ÓØƒGØ€Hˆc�D‰jÓØ€L�#ÓÙ %¨e¸UÈDÔQ€Dˆ#�‰*ÓQótð6 ð%˜4ò %ó ð%ð ð%˜ò %ó ð%ð˜ó ñ$0˜s T™zð 0°Sô 0r;   r   c                   óv   — e Zd ZU dZeed<   eed<   dZedz  ed<    e	dddd¬«      Z
edz  ed<   dd
„Zd	efd„Zy)ÚHfMountaF  A HF URI paired with a local mount path and optional read-only flag.

    Used by Spaces and Jobs to describe volume mounts. The full syntax is:

    ```
    hf://[<TYPE>/]<ID>[@<REVISION>][/<PATH>]:<MOUNT_PATH>[:ro|:rw]
    ```

    Attributes:
        source ([`HfUri`]):
            The parsed HF URI identifying the Hub resource to mount.
        mount_path (`str`):
            The local mount path (always starts with '/').
        read_only (`bool`, *optional*):
            True if the mount ends with ':ro', False if it ends with ':rw', 'None' if no flag was provided.
    ÚsourceÚ
mount_pathNÚ	read_onlyFr   r#   r$   c                 ó®   — | j                   xs d}| j                  j                  d«      r| j                  dk(  rt        |d| j                  › d�¬«      ‚y )Nr   r*   zEMount path must be a non-empty absolute path starting with '/', got 'r+   r'   )r#   rb   r1   r	   )r2   r   s     r4   r5   zHfMount.__post_init__æ   sW   € Ø�i‰iŠo˜2ˆØ�‰×)Ñ)¨#Ô.°$·/±/ÀSÒ2HÜØØ[Ð\`×\kÑ\kÐ[lÐlnÐoôð ð 3Ir;   c                 óÈ   — | j                   j                  «       d| j                  g}| j                  �|j	                  | j                  rdnd«       dj                  |«      S )zqRender the mount as a canonical 'hf://' string.

        Example: 'hf://models/my-org/my-model:/data:ro'
        ú:ú:roú:rwr   )ra   rH   rb   rc   rE   rF   )r2   rG   s     r4   rH   zHfMount.to_uriî   sM   € ð
 —‘×#Ñ#Ó% s¨D¯O©OÐ<ˆØ�>‰>Ð%Ø�L‰L $§.¢.™°eÔ<Ø�w‰w�u‹~Ðr;   rT   )rV   rW   rX   rY   r   r[   r0   rc   r]   r   r#   r5   rH   r^   r;   r4   r`   r`   Î   sK   … ñð" ƒMØƒOØ!€Iˆt�d‰{Ó!Ù %¨e¸UÈDÔQ€Dˆ#�‰*ÓQóð˜ô r;   r`   r(   r$   c                 ó:   — 	 t        | «       y# t        $ r Y yw xY w)zVCheck if a string is a valid HF URI ('hf://...') or a recognized Hugging Face web URL.TF)Úparse_hf_urir	   )r(   s    r4   Ú	is_hf_urirk   ù   s$   € ðÜ�SÔØøÜò Ùðús   ‚ Ž	™rI   c                 ó²  — | }| j                  t        j                  «      r<| t        t        j                  «      d }|sht	        | dt        j                  › d�«      ‚t        | |¬«      rt        | |¬«      }n/t	        | dt        j                  › dt        j                  › d�«      ‚t        ||¬«      \  }}|d	k(  rt        |||¬«      S t        |||¬«      S )
a·  Parse a Hugging Face Hub URI ('hf://...') or a Hugging Face web URL.

    A HF URI is a URI-like string identifying a location on the Hugging Face Hub. The full grammar is:

    ```
    hf://[<TYPE>/]<ID>[@<REVISION>][/<PATH>]
    ```

    For convenience, Hugging Face **web URLs** (the ones you copy-paste from the website) are also
    accepted and normalized to the canonical 'hf://' form, e.g.
    'https://huggingface.co/datasets/my-org/my-dataset/blob/main/train.csv'. Only unambiguous URLs
    (repository / bucket pages and file/folder viewer routes) are accepted; any other route is rejected.

    See 'docs/source/en/package_reference/hf_uris.md' for the full specification.

    Args:
        uri (`str`):
            The URI to parse. Must start with 'hf://', or be a Hugging Face URL (e.g. 'https://huggingface.co/...').
        endpoint (`str`, *optional*):
            A custom Hub endpoint (e.g. a self-hosted or proxied Hub like 'https://hub.my-company.com' or
            'http://localhost:8080/hf'). When provided, web URLs on that endpoint are recognized in addition to
            the default Hugging Face hosts. Has no effect on 'hf://' URIs.

    Returns:
        [`HfUri`]: the parsed URI.

    Raises:
        [`HfUriError`]:
            If the URI is malformed (missing prefix, invalid type, missing id, unsupported URL route, etc.).

    Examples:
        ```py
        >>> from huggingface_hub.utils import parse_hf_uri
        >>> parse_hf_uri("hf://my-org/my-model")
        HfUri(type='model', id='my-org/my-model', revision=None, path_in_repo='')
        >>> parse_hf_uri("hf://datasets/my-org/my-dataset@refs/pr/3/train.json")
        HfUri(type='dataset', id='my-org/my-dataset', revision='refs/pr/3', path_in_repo='train.json')
        >>> parse_hf_uri("https://huggingface.co/datasets/my-org/my-dataset/blob/main/train.csv")
        HfUri(type='dataset', id='my-org/my-dataset', revision='main', path_in_repo='train.csv')
        ```
    NúEmpty body after 'r+   )rI   úMust start with 'zQ' or be a Hugging Face URL (e.g. 'https://huggingface.co/...'). Expected format: z#[<TYPE>/]<ID>[@<REVISION>][/<PATH>]©r   r,   )
r1   r   rA   Úlenr	   Ú_looks_like_hf_urlÚ_url_to_uri_bodyÚ_split_typeÚ_parse_bucket_bodyÚ_parse_repo_body)r(   rI   r   ÚbodyÚtype_Úlocations         r4   rj   rj     sÛ   € ðV €CØ
‡~�~”i×+Ñ+Ô,Ø”3”y×,Ñ,Ó-Ð/Ð0ˆÙÜ˜SÐ$6´y×7LÑ7LÐ6MÈRÐ"PÓQÐQÜ	˜C¨(Õ	3Ü ¨hÔ7‰äØØ¤	× 5Ñ 5Ð6ð 7 Ü )× 5Ñ 5Ð6Ð6Yð[ó
ð 	
ô " $¨CÔ0�O€Eˆ8à�ÒÜ! (¨E°sÔ;Ð;Ü˜H e°Ô5Ð5r;   c                 óº   — | €yt        d| v r| nd| z   «      }|j                  r|j                  j                  «       nd}||j                  j	                  d«      fS )a  Return the lowercased host and stripped path prefix of a custom Hub 'endpoint'.

    E.g. 'https://hub.my-company.com' -> ('hub.my-company.com', '') and a self-hosted
    'http://localhost:8080/hf' -> ('localhost', 'hf'). Returns '(None, "")' when 'endpoint' is None.
    N)Nr   ú://r-   r*   )r   ÚhostnameÚlowerrQ   Ústrip)rI   ÚparsedÚhosts      r4   Ú_endpoint_host_and_pathr€   B  sX   € ð ÐØä %¨8Ñ"3‘h¸À¹ÓI€FØ&,§o¢oˆ6�?‰?× Ñ Ô"¸4€DØ�—‘×"Ñ" 3Ó'Ð'Ð'r;   c                 ój   — t        | «      \  }}|rt        j                  |hz  S t        j                  S )z^The set of hosts whose web URLs can be parsed: the default Hugging Face hosts plus 'endpoint'.)r€   r   ÚHF_URL_HOSTS)rI   r   Ú_s      r4   Ú_recognized_hostsr„   P  s0   € ä% hÓ/�G€Dˆ!Ù.2Œ9×!Ñ! T FÑ*ÐN¼	×8NÑ8NÐNr;   c                 ó‚   ‡— | j                  «       Š‰j                  d«      ryt        ˆfd„t        |«      D «       «      S )zNReturn True if 'uri' looks like a (possibly scheme-less) Hugging Face web URL.)zhttp://zhttps://Tc              3   óT   •K  — | ]  }‰|k(  xs ‰j                  |d z   «      –— Œ! y­w)r*   N)r1   )Ú.0r   Úlowereds     €r4   ú	<genexpr>z%_looks_like_hf_url.<locals>.<genexpr>\  s,   øè ø€ ÒiÀTˆw˜$‰Ò@ '×"4Ñ"4°T¸C±ZÓ"@Ó@Ñiùs   ƒ%()r|   r1   Úanyr„   )r(   rI   rˆ   s     @r4   rq   rq   V  s8   ø€ à�i‰i‹k€GØ×ÑÐ1Ô2ØäÓiÔM^Ð_gÓMhÔiÓiÐir;   Úsegmentc                 ó8   — t        | «      j                  dd«      S )aw  Percent-decode a single URL path segment (e.g. 'file%20name.txt' -> 'file name.txt').

    A decoded '/' is re-encoded as '%2F' so the segment stays atomic when the normalized body is
    re-split by the shared parser. This decodes ordinary path characters (spaces, '#', ...) that
    browsers encode, while keeping '%2F'-encoded revisions (e.g. 'feature%2Ffoo') intact.
    r*   r?   )r   rD   )r‹   s    r4   Ú_decode_url_path_segmentr�   _  s   € ô �7Ó×#Ñ# C¨Ó/Ð/r;   rR   c                 ó¸  — | }t        d| v r| nd| z   «      }|j                  xs dj                  «       }|t        |«      vrt	        |d|xs | › d�¬«      ‚|j
                  }t        |«      \  }}|r1||k(  r,d|z   }||k(  s|j                  |dz   «      r|t        |«      d }|j                  d«      D �	cg c]  }	|	sŒ|	‘Œ	 }
}	|
st	        |d	| › d
�¬«      ‚d}|
d   t        j                  v r
|
d   }|
dd }
t        |
«      dk  rt	        |d| › d�¬«      ‚|
d   › d|
d   › �}|
dd }|dk(  rN|sd|› �S |^}}|t        vrt	        |d| › d|› d�¬«      ‚dj                  d„ |D «       «      }|rd|› d|› �S d|› �S |r|› d�nd}|s|› |› �S |^}}|t        vrt	        |d| › d|› d�¬«      ‚|s|› |› �S dj                  d„ |D «       «      }|› |› d|› �S c c}	w )aâ  Normalize a Hugging Face web URL into the body of a 'hf://' URI (everything after 'hf://').

    The returned string is fed back into the regular URI parsing logic, so all validation
    (repo id, revision, empty path segments, ...) is shared with the canonical 'hf://' path.
    Only unambiguous URLs are accepted: any unrecognized route raises [`HfUriError`]. When 'endpoint'
    is provided, URLs on that custom Hub host are recognized too (and its path prefix is stripped).
    rz   r-   r   zUnrecognized host 'zC'. Expected a Hugging Face URL (e.g. 'https://huggingface.co/...').r'   r*   Nz0Missing repository or bucket identifier in URL 'r+   r   r   é   zCannot parse URL 'z{': expected a '<namespace>/<name>' repository or bucket. User/organization pages and single-segment URLs are not supported.Úbucketszbuckets/zCannot parse bucket URL 'z': unsupported '/z	/' route.c              3   ó2   K  — | ]  }t        |«      –— Œ y ­wrU   ©r�   ©r‡   r‹   s     r4   r‰   z#_url_to_uri_body.<locals>.<genexpr>¡  s   è ø€ ÒN¸gÔ0°×9ÑNùó   ‚zl/' route. Only repository pages and file/folder viewer routes (blob, resolve, raw, tree, ...) can be parsed.c              3   ó2   K  — | ]  }t        |«      –— Œ y ­wrU   r’   r“   s     r4   r‰   z#_url_to_uri_body.<locals>.<genexpr>·  s   è ø€ ÒM¸WÔ/°×8ÑMùr”   r@   )r   r{   r|   r„   r	   rQ   r€   r1   rp   Úsplitr   ÚHF_URI_TYPE_PREFIXESr   rF   r   )rR   rI   r   r~   r   rQ   Úendpoint_hostÚendpoint_pathÚprefixr‹   ÚsegmentsÚtype_prefixÚrepo_idÚrestÚactionÚtailÚdecodeds                    r4   rr   rr   i  s�  € ð €Cä˜U c™\‘c¨t°c©zÓ:€FØ�O‰OÒ!˜r×(Ñ(Ó*€DØÔ$ XÓ.Ñ.ÜØØ% d¢k¨c ]Ð2uÐvô
ð 	
ð �;‰;€Dô $;¸8Ó#DÑ €M�=Ù˜ Ò.Ø�}Ñ$ˆØ�6Š>˜TŸ_™_¨V°c©\Ô:Øœ˜F›˜Ð&ˆDØ'+§z¡z°#£ÖB˜Gº'’ÐB€HÐBÙÜ˜SÐ(XÐY\ÐX]Ð]_Ð&`ÔaÐað #€KØ��{”i×4Ñ4Ñ4Ø˜q‘kˆØ˜A˜B�<ˆô ˆ8ƒ}�qÒÜØà$ S Eð *Uð Uô
ð 	
ð ˜!‘�˜Q˜x¨™{˜mÐ,€GØ�A�Bˆ<€Dà�iÒÙØ˜g˜YÐ'Ð'Øˆˆ�ØÔ5Ñ5Ü Ð,EÀcÀUÐJ[Ð\bÐ[cÐclÐ*mÔnÐnØ�x‰xÑNÈÔNÓNˆÙ.2�˜'˜ ! D 6Ð*ÐL¸(À7À)Ð8LÐLá"-�ˆ}˜AÑ°2€FÙØ�˜'˜Ð#Ð#Ø€M€FˆTØÔ/Ñ/ÜØà$ S EÐ):¸6¸(ð Cuð uô
ð 	
ñ à�˜'˜Ð#Ð#ð
 �h‰hÑMÈÔMÓM€GØˆX�g�Y˜a ˜yÐ)Ð)ùòi Cs   Â7GÂ?GÚ	mount_strc                 óê  — | j                  t        j                  «      st        | dt        j                  › d�¬«      ‚| }| t	        t        j                  «      d }|st        |dt        j                  › d�¬«      ‚t        ||¬«      \  }}}|€t        |d¬«      ‚t        j                  |z   }	 t        |«      }t        ||||¬«      S # t        $ r}t        ||j                  ¬«      |‚d}~ww xY w)	a·  Parse a HF mount specification ('hf://...:<MOUNT_PATH>[:ro|:rw]').

    A mount specification is a HF URI followed by a local mount path and an optional read-only/read-write flag.
    The full grammar is:

    ```
    hf://[<TYPE>/]<ID>[@<REVISION>][/<PATH>]:<MOUNT_PATH>[:ro|:rw]
    ```

    See 'docs/source/en/package_reference/hf_uris.md' for the full specification.

    Args:
        mount_str (`str`):
            The mount string to parse. Must start with 'hf://' and contain a ':<MOUNT_PATH>' segment.

    Returns:
        [`HfMount`]: the parsed mount.

    Raises:
        [`HfUriError`]:
            If the mount string is malformed (missing mount path, invalid URI, etc.).

    Examples:
        ```py
        >>> from huggingface_hub.utils import parse_hf_mount
        >>> parse_hf_mount("hf://my-org/my-model:/data:ro")
        HfMount(source=HfUri(type='model', id='my-org/my-model', revision=None, path_in_repo=''), mount_path='/data', read_only=True)
        >>> parse_hf_mount("hf://buckets/my-org/my-bucket/sub/dir:/mnt:rw")
        HfMount(source=HfUri(type='bucket', id='my-org/my-bucket', revision=None, path_in_repo='sub/dir'), mount_path='/mnt', read_only=False)
        ```
    rn   r+   r'   Nrm   ro   zKMissing mount path. Expected ':<MOUNT_PATH>' (e.g. 'hf://org/model:/data').)ra   rb   rc   r#   )	r1   r   rA   r	   rp   Ú_split_mountrj   r)   r`   )	r¢   r   rv   rx   rb   rc   Úuri_strra   r3   s	            r4   Úparse_hf_mountr¦   »  sþ   € ð@ ×Ñ¤	× 5Ñ 5Ô6ÜØØ#¤I×$9Ñ$9Ð#:¸"Ð=ô
ð 	
ð
 €CØ”Sœ×.Ñ.Ó/Ð1Ð2€DÙÜ˜SÐ(:¼9×;PÑ;PÐ:QÐQSÐ&TÔUÐUä&2°4¸SÔ&AÑ#€Hˆj˜)àÐÜ˜SÐ&sÔtÐtô ×#Ñ# hÑ.€Gð4Ü˜gÓ&ˆô ˜&¨ZÀ9ÐSVÔWÐWøô ò 4Ü˜S a§e¡eÔ,°!Ð3ûð4ús   Â2C Ã	C2ÃC-Ã-C2rv   r   c                ó0  — | j                  d«      rd| j                  d«      } }n'| j                  d«      rd| j                  d«      } }nd}| j                  d«      }|dk(  r|�t        |d¬	«      ‚| ddfS | d| }| |d
z   d }|st        |d¬	«      ‚|||fS )z©Split the ':<MOUNT_PATH>[:ro|:rw]' suffix from 'body'.

    Returns '(location, mount_path, read_only)' where 'mount_path' is 'None' if no mount segment is present.
    rg   Trh   FNz:/éÿÿÿÿzb':ro'/':rw' suffix is only valid when a mount path is provided (e.g. 'hf://...:/<MOUNT_PATH>:ro').r'   r   z#Missing location before mount path.)ÚendswithÚremovesuffixÚrfindr	   )rv   r   rc   Úidxrx   rb   s         r4   r¤   r¤   õ  sÀ   € ð
 ‡}�}�UÔØ × 1Ñ 1°%Ó 8�4‰	Ø	�‰�uÔ	Ø ×!2Ñ!2°5Ó!9�4‰	àˆ	ð �*‰*�TÓ
€CØ
ˆb‚yØÐ ÜØØxôð ð �T˜4ÐÐà�D�Sˆz€HØ�c˜A‘g�i�€JÙÜ˜SÐ&KÔLÐLØ�Z Ð*Ð*r;   rx   c          	      óØ  — | j                  d«      }|dk(  rr| t        j                  v r$t        |d| › dt        j                  › | › d�¬«      ‚t
        j                  | «      x}�!t        |dt        j                  › |› d	�¬«      ‚d
| fS | d| }| |dz   d }|t        j                  v rt        j                  |   |fS t
        j                  |«      x}�t        |d|› d|› d�¬«      ‚d
| fS )zÙDetect the (optional) type prefix and return '(type, remaining_location)'.

    A missing type prefix defaults to 'model'. Singular forms ('model/', 'dataset/', etc.) are explicitly rejected with a helpful error.
    r*   r¨   zMissing identifier after 'z'. Expected 'z/<ID>'.r'   Nz*Type prefix must be plural. Did you mean 'z/...'?rL   r   z!Type prefix must be plural, got 'z/'. Did you mean 'z/'?)Úfindr   r—   r	   rA   r   Úget)rx   r   Ú	slash_idxÚsingular_pluralÚfirstrž   s         r4   rs   rs     s/  € ð
 —‘˜cÓ"€IØ�B‚à”y×5Ñ5Ñ5ÜØØ0°°
¸-Ì	×H]ÑH]ÐG^Ð_gÐ^hÐhoÐpôð ô  /×2Ñ2°8Ó<Ð<ˆOÐIÜØØ@Ä×AVÑAVÐ@WÐXgÐWhÐhnÐoôð ð ˜Ð Ð à�Z�iÐ €EØ�I ‘M�OÐ$€DØ”	×.Ñ.Ñ.Ü×-Ñ-¨eÑ4°dÐ:Ð:Ü*×.Ñ.¨uÓ5Ð5ˆÐBÜØÐ<¸U¸GÐCUÐVeÐUfÐfiÐjô
ð 	
ð �HÐÐr;   rw   c                ó   — | j                  d«      } | j                  dd«      }t        |«      dk  s
|d   r|d   st        |d| › d�¬«      ‚|d   › d|d   › �}d|v rt        |d	¬«      ‚t        |«      d
k\  r|d   nd}t	        ||d||¬«      S )z8Parse the body of a bucket URI: 'namespace/name[/path]'.r*   r�   r   r   z)Bucket id must be 'namespace/name', got 'r+   r'   r@   z3Bucket URIs do not support a revision marker ('@').é   r   N©r   r   r   r   r#   )r}   r–   rp   r	   r   )rx   rw   r   rG   Ú	bucket_idÚpath_in_buckets         r4   rt   rt   2  s²   € ð �~‰~˜cÓ"€HØ�N‰N˜3 Ó"€EÜ
ˆ5ƒz�A‚~˜U 1šX¨U°1ªXÜ˜SÐ(QÐRZÐQ[Ð[]Ð&^Ô_Ð_Ø˜‘8�*˜A˜e A™h˜ZÐ(€IØ
ˆiÑÜ˜SÐ&[Ô\Ð\Ü!$ U£¨q¢�U˜1’X°b€NÜØØØØ#Øôð r;   c                óø  — | j                  d«      } | st        |d¬«      ‚| j                  d«      }|dk(  s| d| j                  d«      dkD  rVd}| j	                  dd«      }t        |«      dk  rt        |d	| › d
�¬«      ‚|d   › d|d   › �}t        |«      dkD  r|d   nd}nÈ| d| }| |dz   d }|st        |d¬«      ‚|j                  d«      dk7  rt        |d	|› d�¬«      ‚t        j                  |«      }	|	�.|	j                  «       }|t        |«      d j                  d«      }n(|j                  d«      }
|
dk(  r|}d}n|d|
 }||
dz   d }t        |«      }|st        |d¬«      ‚t        |||||¬«      S )z@Parse the body of a repo URI: '<repo_id>[@<revision>][/<path>]'.r*   zMissing repository id.r'   r@   r¨   Nr   r�   z-Repository id must be 'namespace/name', got 'z'. r   r   z!Missing repository id before '@'.r+   zEmpty revision after '@'.rµ   )r}   r	   r®   r/   r–   rp   rB   ÚmatchÚgroupÚremoveprefixr   r   )rx   rw   r   Úat_idxr   rG   r�   r   Úrev_and_pathr¹   r°   s              r4   ru   ru   J  sÆ  € ð �~‰~˜cÓ"€HÙÜ˜SÐ&>Ô?Ð?ð
 �]‰]˜3Ó€Fð �‚|�x  Ð(×.Ñ.¨sÓ3°aÒ7àˆØ—‘˜s AÓ&ˆÜˆu‹:˜Š>Ü Ð,YÐZbÐYcÐcfÐ*gÔhÐhØ˜1‘X�J˜a  a¡˜zÐ*ˆÜ#& u£:°¢>�u˜Q’x°r‰à˜7˜FÐ#ˆØ ¨¡
 Ð-ˆÙÜ Ð*MÔNÐNØ�=‰=˜Ó Ò"Ü Ð,YÐZaÐYbÐbdÐ*eÔfÐfô -×2Ñ2°<Ó@ˆØÐØ—{‘{“}ˆHØ'¬¨H«¨Ð8×EÑEÀcÓJ‰Là$×)Ñ)¨#Ó.ˆIØ˜BŠØ'�Ø!‘à'¨
¨Ð3�Ø+¨I¸©M¨OÐ<�Ü˜8Ó$ˆÙÜ Ð*EÔFÐFäØØØØ!Øôð r;   rU   )0rY   Ú	functoolsÚreÚdataclassesr   r   Úurllib.parser   r   r   Úhuggingface_hubr   Úhuggingface_hub.errorsr	   r
   Ú_validatorsr   r—   Úitemsr   Údictr0   r[   ÚcompilerB   Ú	frozensetÚvaluesr   r   r   r   r`   r]   rk   Ú	lru_cacherj   Útupler€   r„   rq   r�   rr   r¦   r¤   rZ   rs   rt   ru   )ÚkÚvs   00r4   ú<module>rÎ      s»  ðòó: Û 	ß (ß 1Ñ 1å %ß @å )ð
 5>×4RÑ4R×4XÑ4XÓ4Z×"[©D¨A¨q 1 a¡4Ó"[€��c˜3�h‘Ó [ð  *˜rŸz™zÐ*MÓNÐ ñ $-¨Y×-KÑ-K×-RÑ-RÓ-TÓ#UÐ �)˜C‘.Ó Uñ .7Ò7bÓ-cÐ ˜I c™NÓ cñ 09¸)ÀVÐ9LÓ/MÐ ˜i¨™nÓ Mñ �$Ô÷|ð |ó ð|ñ~ �$Ô÷'ð 'ó ð'ðT�3ð ˜4ó ð ×Ññ<6�cð <6 S¨4¡Zð <6¸5ò <6ó ð<6ð~( c¨D¡jð (°U¸3À¹:Às¸?Ñ5Kó (ðO  d¡
ð O¨y¸©~ó Oñj˜Cð j¨3°©:ð jÀó jð0 cð 0¨có 0ñO*˜#ð O*¨¨t©ð O*¸só O*ðd7X˜cð 7X gó 7Xðt+�sð + Cð +¨E°#°s¸T±zÀ4È$Á;Ð2NÑ,Oó +ð<˜#ð  sð ¨u°Y×5HÑ5HÈ#Ð5MÑ/Nó ð>Øðà×Ñðð 
ð	ð
 óð08Øð8à×Ñð8ð 
ð	8ð
 ô8ùóe #\s   ÁG