ó
    >:jwj  ã                  ó”  • S r SSKJr  SSKrSSKrSSKJr  SSKJrJ	r	  SSK
Jr  SSKrSSKrSSKJrJrJrJr   SSKJr   SS	KJrJr  \R8                  " \5      rS
S
S
S
S.rSS jr SS jr!SS jr"SS jr#SS jr$SS jr% " S S5      r& S     SS jjr' S     SS jjr(SS jr)g! \ a    Sr Ntf = f! \\4 a    SrSr N}f = f)zAModality detection, input parsing, and message format conversion.é    )ÚannotationsN)Údefaultdict)ÚAnyÚLiteral)Úurlparse)ÚMessageFormatÚModalityÚ	PairInputÚSingleInput)ÚImage)ÚAudioDecoderÚVideoDecoderÚflat)ÚapertusÚdeepseek_v3Úgpt_ossÚseed_ossc                ó<   • U R                  S5      =(       a    SU ;  $ )zQCheck if a string looks like a valid URL (starts with http(s) and has no spaces).)zhttp://zhttps://Ú )Ú
startswith©Útexts    Ú`/home/mande/repo/quber/.venv/lib/python3.13/site-packages/sentence_transformers/base/modality.pyÚ_looks_like_urlr   ,   s   € à�?‰?Ð2Ó3×G¸À4¹ÐGó    c                ó  • [        U 5      (       a4  [        U 5      R                  R                  5       nUR	                  U5      $ U R                  5       R	                  U5      =(       a    [
        R                  R                  U 5      $ )zOCheck if a string is a URL or local file path with one of the given extensions.)r   r   ÚpathÚlowerÚendswithÚosÚisfile)r   Ú
extensionsr   s      r   Ú_is_media_url_or_pathr#   1   s]   € ä�t×ÑÜ˜‹~×"Ñ"×(Ñ(Ó*ˆØ�}‰}˜ZÓ(Ð(Ø�:‰:‹<× Ñ  Ó,×E´·±·±ÀÓ1EÐEr   c                óH   • U R                  S5      (       a  g[        U S5      $ )z:Check if a string is an image URL, file path, or data URI.zdata:image/T)z.jpgz.jpegz.pngz.gifz.bmpz.tiffz.webp)r   r#   r   s    r   Úis_image_url_or_pathr%   9   s"   € à‡��}×%Ñ%ØÜ  Ð'bÓcÐcr   c                óz   • [        U S5      (       a  g[        U 5      =(       a    [        U 5      R                  S;   $ )z.Check if a string is a video URL or file path.)z.mp4z.aviz.movz.wmvz.flvz.mkvT)zwww.youtube.comzyoutube.comzyoutu.bezm.youtube.com)r#   r   r   Únetlocr   s    r   Úis_video_url_or_pathr(   @   s;   € ä˜TÐ#S×TÑTØÜ˜4Ó ÷ ¤X¨d£^×%:Ñ%:ð ?ñ &ð r   c                ó   • [        U S5      $ )z/Check if a string is an audio URL or file path.)z.mp3z.wavz.oggz.flacz.aac)r#   r   s    r   Úis_audio_url_or_pathr*   L   s   € ä  Ð'PÓQÐQr   c                óˆ  • [        U [        [        45      (       a  [        U 5      S:w  a  g[        U S   [        5      (       a  [        U S   [        5      (       a  gU  H`  n[        U[
        5      (       a  SU;   a  SU;   a    g[        U[        5      (       d  M=  U(       d  MF  [        US   [
        5      (       d  M`    g   g)ay  Check if a sample is a non-text pair (2-element tuple/list with at least one non-string element).

Text pairs ``(str, str)`` are handled natively by tokenizers and detected as ``"text"`` modality
by :func:`infer_modality`. This helper detects pairs that contain at least one non-string element
(e.g. an image, audio array, or dict), which require conversion to message format.
é   Fr   é   ÚroleÚcontentT)Ú
isinstanceÚtupleÚlistÚlenÚstrÚdict)ÚsampleÚelems     r   Ú_is_non_text_pairr8   Q   s—   € ô �fœu¤d˜m×,Ñ,´°F³¸qÓ0@Øä�&˜‘)œS×!Ñ!¤j°¸±¼C×&@Ñ&@ØãˆÜ�dœD×!Ñ! f°£n¸ÀdÓ9JÙÜ�dœD×!Ó!§d d¬z¸$¸q¹'Ä4×/HÓ/HÙñ	 ð
 r   c                  óÎ   • \ rS rSrSr   S       SS jjrSS jr    SS jrSS jrSSS jjr	      SS	 jr
\SS
 j5       rSS jr      SS jr      SS jrSrg)ÚInputFormatteréf   aH  Handles input parsing, modality detection, and message format conversion.

This class manages the complete input preprocessing pipeline:
1. Parsing raw inputs to detect their modality (text, image, audio, video, message)
2. Converting inputs to different chat template formats
3. Normalizing mixed-modality inputs

Different models require different message/chat template formats:
- **Structured format**: Content is a list of dicts with type annotations
    [{"role": "user", "content": [{"type": "text", "text": "hello"}]}]

- **Flat format**: Content is the direct value
    [{"role": "user", "content": "hello"}]

Args:
    model_type: The model type string (e.g. from ``config.model_type``).
    message_format: Message format to use. Options:
        - ``"structured"``: Content is a list of dicts with type/modality keys
        - ``"flat"``: Content is the direct value
        - ``"auto"``: Automatically infer from processor (default)
    processor: Optional processor to infer format from when ``message_format="auto"``.
    supported_modalities: Optional list of modalities supported by the model. When provided,
        string inputs that look like media URLs/paths are only classified as non-text if the
        model actually supports that modality. This prevents text-only models from
        misclassifying text containing media URLs.
Nc                ó€   • Xl         X0l        X@l        US:X  a   U(       a  U R                  U5      OSU l        g X l        g )NÚautoÚ
structured)Ú
model_typeÚ	processorÚsupported_modalitiesÚ_infer_formatÚmessage_format)Úselfr?   rC   r@   rA   s        r   Ú__init__ÚInputFormatter.__init__‚   s:   € ð %ŒØ"ŒØ$8Ô!Ø˜VÓ#ÞCL $×"4Ñ"4°YÔ"?ÐR^ˆDÕà"0Õr   c                óæ   ^• U R                   [        ;   a  [        U R                      $ [        USS5      m[        T[        5      (       a  T(       d  g/ SQn[        U4S jU 5       5      (       a  gg)ac  Infer the message format expected by the processor.

Checks known model types first, then inspects the processor's chat template
for patterns indicating structured format. Defaults to ``"structured"`` if
neither approach is conclusive.

Args:
    processor: The processor/tokenizer to inspect.

Returns:
    ``"structured"`` or ``"flat"`` message format.
Úchat_templateNr>   )z
content[0]z.typez'type'z"type"z	item.typezmessage.content[c              3  ó,   >#   • U  H	  oT;   v •  M     g 7f©N© )Ú.0ÚpatternÚtemplates     €r   Ú	<genexpr>Ú/InputFormatter._infer_format.<locals>.<genexpr>®   s   øé € ÐFÒ2E w˜(Ö"Ò2Eùs   ƒr   )r?   Ú!KNOWN_MODEL_TYPES_MESSAGE_FORMATSÚgetattrr0   r4   Úany)rD   r@   Ústructured_patternsrN   s      @r   rB   ÚInputFormatter._infer_format‘   sc   ø€ ð �?‰?Ô?Ó?Ü4°T·_±_ÑEÐEä˜9 o°tÓ<ˆÜ˜(¤C×(Ñ(¶Øò
Ðô ÔFÑ2EÓF×FÑFØàr   c                ót  • U(       d  SS/ 0[        [        5      4$ / n[        [        5      nSnU GH  n[        U5      (       a  UR                  SU45        SnM+  [	        XPR
                  S9nUS:X  a'  [        U[        5      (       a  US   nUS   US   S'   GO›US:X  ag  [        b`  [        U[        5      (       aK  UR                  5       nUR                  R                  S	S
9R                  5       nUR                  US   S'   GO.US:X  aB  [        U[        5      (       a-  US   nUS   R                  S/ 5      R                  US   5        OæUS:X  a¿  [        b¸  [        U[        5      (       a£  [        U5      n	UR!                  S	U	5      n
U
R                  nUS   R                  S/ 5      R                  UR"                  R$                  UR"                  R&                  [)        [+        U
R                  R,                  S	   5      5      S.5        O!US:X  a  [        U[        5      (       a  U/nOUnUR                  Xg45        GM     U(       aá  / nU HÒ  u  pÇUS:X  a"  UR                  U R/                  U5      5        M-  US:X  aL  [        U[0        [(        45      (       a1  [        U5      S:X  a"  UR                  U R/                  U5      5        M  US:X  a  UR                  U5        M˜  [        U[0        5      (       a  UOXÇ0nUR                  U R3                  U5      5        MÔ     SSU0U4$ [5        U6 u  pï[)        U5      n[7        U5      n[        U5      S:X  ae  UR9                  5       n[        U[:        5      (       a  Xo0nO—US	   R=                  5       nU VVs0 s H  oÌU Vs/ s H  nUU   PM
     sn_M     nnnO[[>        RA                  SU S35        SU VVs/ s H.  u  pgU R3                  [        U[0        5      (       a  UOXg05      PM0     snn0nSnXoU4$ s  snf s  snnf s  snnf )a•  Parse inputs and group by modality.

Analyzes a list of inputs to detect their modality (text, image, audio, video, message)
and groups them appropriately for the processor. Handles mixed modalities by converting
to message format when necessary.

Non-text pairs (e.g. ``(image, text)`` or ``(image, image)``) are detected and converted
to message format with ``"query"``/``"document"`` roles via :meth:`pair_to_messages`.

Args:
    inputs: List of inputs to parse. Can be:
        - str: Text inputs
        - tuple/list of str: Text pairs (for cross-encoders)
        - tuple/list of mixed types: Non-text pairs (e.g. image + text)
        - dict: Chat messages, audio data, or multimodal inputs
        - PIL.Image.Image: Image inputs
        - np.ndarray/torch.Tensor: Audio (1-2D) or video (3-5D) inputs

Returns:
    Tuple of (modality, processor_inputs_dict, extra_modality_kwargs) where:
        - modality: Detected modality string (``"text"``, ``"image"``, etc.) or tuple of modalities
        - processor_inputs_dict: Dictionary mapping modality names to input lists
        - extra_modality_kwargs: Extra kwargs per modality (e.g. ``sampling_rate`` for audio)
r   FÚpairT©rA   ÚaudioÚarrayÚsampling_rater   )ÚdimÚvideoÚvideo_metadata)ÚfpsÚtotal_num_framesÚframes_indicesÚmessager,   r-   zMixed modalities detected: z!. Converting to 'message' format.)!r   r5   r8   ÚappendÚinfer_modalityrA   r0   r   Úget_all_samplesÚdataÚmeanÚnumpyÚsample_rateÚ
setdefaultr   r3   Úget_frames_in_rangeÚmetadataÚaverage_fpsÚ
num_framesr2   ÚrangeÚshapeÚpair_to_messagesr1   Ú
to_messageÚzipÚsetÚpopr4   ÚkeysÚloggerÚdebug)rD   ÚinputsÚtyped_inputsÚextra_modality_kwargsÚ	has_pairsÚitemÚmodalityÚvalueÚsamplesrn   Úframe_batchÚmessagesÚmodÚtypedÚ
modalitiesÚprocessed_inputsÚunique_modalitiesÚordered_keysÚentrys                      r   Úparse_inputsÚInputFormatter.parse_inputs³   sú  € ö8 Ø˜F B˜<¬´TÓ):Ð:Ð:àEGˆÜ +¬DÓ 1ÐØˆ	äˆDô ! ×&Ñ&Ø×#Ñ# V¨T NÔ3Ø �	Ùä% d×AZÑAZÑ[ˆHð ˜7Ó"¤z°$¼×'=Ñ'=Ø˜W™�ØBFÀÑBWÐ% gÑ.¨Ó?Ø˜WÓ$¬Ñ)AÄjÐQUÔWc×FdÑFdØ×.Ñ.Ó0�àŸ™×)Ñ)¨aÐ)Ð0×6Ñ6Ó8�ØBI×BUÑBUÐ% gÑ.¨Ó?Ø˜WÓ$¬°D¼$×)?Ñ)?Ø˜W™�Ø% gÑ.×9Ñ9Ð:JÈBÓO×VÑVÐW[Ð\lÑWmÕnØ˜WÓ$¬Ñ)AÄjÐQUÔWc×FdÑFdÜ  ›Y�
Ø"×6Ñ6°q¸*ÓE�Ø#×(Ñ(�Ø% gÑ.×9Ñ9Ð:JÈBÓO×VÑVà#Ÿ}™}×8Ñ8Ø,0¯M©M×,DÑ,DÜ*.¬u°[×5EÑ5E×5KÑ5KÈAÑ5NÓ/OÓ*Pñõð ˜YÓ&¬:°d¼D×+AÑ+AØ˜‘à�à×Ñ Ð 1×2ñQ öZ ØˆHÛ*‘
�Ø˜&“=Ø—O‘O D×$9Ñ$9¸%Ó$@ÖAØ˜F“]¤z°%¼%Ä¸×'GÑ'GÌCÐPUËJÐZ[ËOØ—O‘O D×$9Ñ$9¸%Ó$@ÖAØ˜IÓ%Ø—O‘O EÖ*ä%/°´U×%;Ñ%;™EÀ#À�EØ—O‘O D§O¡O°EÓ$:Ö;ñ +ð ˜y¨(Ð3Ð5JÐJÐJä'*¨LÐ'9Ñ$ˆ
ÜÐ 0Ó1ÐÜ 
›OÐäÐ Ó! QÓ&Ø(×,Ñ,Ó.ˆHÜ˜(¤C×(Ñ(Ø$,Ð#?Ñ ð  0°Ñ2×7Ñ7Ó9�Ù_kÔ#lÒ_kÐX[ÑBRÓ)SÒBR¸¨%°¬*ÑBRÑ)SÒ$SÑ_kÐ Ñ#lÐ ä�L‰LÐ6Ð7HÐ6IÐIjÐkÔlàá+7ôâ+7™˜ð —O‘O¬Z¸Ä%×-HÑ-H¡EÈxÐN_Ö`Ù+7òð Ðð !ˆHàÐ+@Ð@Ð@ùò *TùÓ#lùós   Î&
P.Î0P)Î?P.Ï)5P4Ð)P.c                óœ   • Uu  p#[        U5      n[        U5      nU R                  S:X  a
  SUS.SUS./$ S nSU" XB5      S.SU" XS5      S./$ )a²  Convert a pair of inputs to query/document message format.

Each element of the pair is wrapped in a message with role ``"query"`` (first element)
or ``"document"`` (second element). The modality of each element is inferred individually
via :func:`infer_modality`.

Args:
    pair: A 2-element tuple or list of inputs (e.g. ``(image, text)``).

Returns:
    List of two message dictionaries with ``"query"`` and ``"document"`` roles.
r   Úquery©r.   r/   Údocumentc                óª   • [        U [        5      (       a4  [        U[        5      (       a  U  Vs/ s H  o"U;   d  M
  SX"X   0PM     sn$ SX U0/$ s  snf )NÚtype)r0   r1   r5   )r~   r}   rƒ   s      r   Ú_to_contentÚ4InputFormatter.pair_to_messages.<locals>._to_content@  sY   € ô ˜(¤E×*Ñ*¬z¸$Ä×/EÑ/EÙAIÓYÂ¸#ÐTXÉ[Ó5˜ ¨4©9Ó5ÁÑYÐYØ˜X°Ð6Ð7Ð7ùò Zs
   ¯	A¼A)rd   rC   )rD   rW   Ú
query_itemÚdoc_itemÚquery_modalityÚdoc_modalityr’   s          r   rq   ÚInputFormatter.pair_to_messages)  ss   € ð  $Ñˆ
Ü'¨
Ó3ˆÜ% hÓ/ˆà×Ñ &Ó(à ¨ZÑ8Ø#°Ñ9ðð ò
	8ð ©°^Ó)PÑQØ©K¸Ó,OÑPð
ð 	
r   c           	     ó   • U R                   S:X  aM  [        U5      S:X  a)  [        [        UR	                  5       5      5      u  p4X$S./$ [
        R                  S5        UUR	                  5        VVs/ s H
  u  pTSXUU0PM     snnS./$ s  snnf )a¶  Convert a typed input dictionary to message format.

Produces a single message with the given ``role``. For pair/multi-value inputs,
use :meth:`pair_to_messages` instead (which is called automatically by :meth:`parse_inputs`).

Args:
    typed_input: Dictionary mapping modality to input value (single value per modality).
    role: Role for the message (default: ``"user"``).

Returns:
    List of message dictionaries (single message).
r   r-   rŽ   zbFlat message format requested but multiple modalities detected. Falling back to structured format.r‘   )rC   r3   ÚnextÚiterÚitemsrw   Úwarning)rD   Útyped_inputr.   Ú_r   r~   s         r   rr   ÚInputFormatter.to_messageL  s–   € ð ×Ñ &Ó(Ü�;Ó 1Ó$Ü¤ [×%6Ñ%6Ó%8Ó 9Ó:‘�Ø!%Ñ8Ð9Ð9ä—‘ð9ôð ØWb×WhÑWhÔWjÔkÒWjÁOÀH˜V X¸Ó?ÑWjÒkñð
ð 	
ùó ls   Á2B
c                óŠ  • U(       d  SS/ 04$ [        U[        5      (       a  U4OUn[        [        [	        UR                  5       5      5      5      n/ n[        U5       HÖ  nU Vs0 s H  owU;   d  M
  XrU   U   _M     nn[        U5      S:X  a…  [        [	        UR                  5       5      5      n	[        U	[        [        45      (       aH  [        U	5      S:X  a9  [        S U	 5       5      (       a"  UR                  U R                  U	5      5        M¶  UR                  U R                  U5      5        MØ     SSU04$ s  snf )a3  Convert a batch of modality-specific inputs into the unified message format.

Args:
    modality: The modality key (string) or tuple of modality keys.
    processor_inputs: Dictionary mapping modality names to lists of inputs.

Returns:
    Tuple of ``("message", {"message": [messages_per_sample, ...]})``
rb   r-   r,   c              3  óB   #   • U  H  n[        U[        5      v •  M     g 7frJ   )r0   r4   )rL   Úvs     r   rO   Ú2InputFormatter.batch_to_message.<locals>.<genexpr>�  s    é € ÐOrÒlqÐghÔPZÐ[\Ô^a×PbÐPbÒlqùs   ‚)r0   r4   r3   rš   r›   Úvaluesro   r1   r2   Úallrc   rq   rr   )
rD   r~   Úprocessor_inputsr…   Ú
batch_sizer‚   Úirƒ   rž   r   s
             r   Úbatch_to_messageÚInputFormatter.batch_to_messagej  s!  € ö  Ø˜y¨"˜oÐ-Ð-Ü$.¨x¼×$=Ñ$=�h‘[À8ˆ
ÜœœdÐ#3×#:Ñ#:Ó#<Ó=Ó>Ó?ˆ
ØˆÜ�zÖ"ˆAáDTÓjÒDT¸SÐ_iÑXiÓ8˜3°Ñ 5°aÑ 8Ò8ÑDTˆKÐjä�;Ó 1Ó$ÜœT +×"4Ñ"4Ó"6Ó7Ó8�Ü˜e¤e¬T ]×3Ñ3¼¸E»
Àa»ÌCÑOrÑlqÓOr×LrÑLrØ—O‘O D×$9Ñ$9¸%Ó$@ÔAÙØ�O‰O˜DŸO™O¨KÓ8Ö9ñ #ð ˜9 hÐ/Ð/Ð/ùò ks   Á'	E Á4E c                óÜ   • U  Hf  nU H]  nUR                  S5      n[        U[        5      (       a  M+  [        U[        5      (       a  [	        S U 5       5      (       a      gM\      g   Mh     g)ah  Check whether all messages in a batch contain only text content.

Works with both flat format (``{"content": "hello"}``) and structured format
(``{"content": [{"type": "text", "text": "hello"}]}``).

Args:
    messages_batch: List of message lists, one per sample.

Returns:
    True if every message contains only text, False if any contain non-text content.
r/   c              3  óJ   #   • U  H  oR                  S S5      S:g  v •  M     g7f)r‘   r   N)Úget)rL   r}   s     r   rO   Ú7InputFormatter.is_text_only_messages.<locals>.<genexpr>š  s   é € ÐRÊ'À$Ÿ8™8 F¨FÓ3°vÖ=Ê'ùs   ‚!#FT)r®   r0   r4   r2   rS   )Úmessages_batchr‚   rb   r/   s       r   Úis_text_only_messagesÚ$InputFormatter.is_text_only_messages‡  sg   € ó 'ˆHÛ#�Ø!Ÿ+™+ iÓ0�Ü˜g¤s×+Ñ+ÙÜ˜g¤t×,Ñ,ÜÑRÉ'ÓR×RÑRÚ$ñ Sò !ó $ñ 'ð r   c                óÂ  • / nU GHU  nSU;  d  SU;  a  [         R                  SU S35        M+  US   n[        U[        5      =(       a    U=(       a    [        US   [        5      nU R
                  S:X  as  U(       al  [        U5      S:X  a(  SUS   ;   a  UR                  0 UESUS   S   0E5        M±  [         R                  S	[        U5       S
35        UR                  U5        Mæ  U R
                  S:X  aN  U(       dG  [        U[        5      (       a  UR                  0 UESSUS./0E5        GM0  UR                  U5        GMD  UR                  U5        GMX     U$ )a  Normalize messages to the target format (``self.message_format``).

Extra keys beyond ``"role"`` and ``"content"`` are preserved during conversion.

Args:
    messages: List of message dictionaries to normalize.

Returns:
    Normalized list of message dictionaries.
r.   r/   zInvalid message format: z. Skipping.r   r   r-   r   z;Cannot convert structured message to flat format: contains z# content items. Keeping structured.r>   ©r‘   r   )	rw   r�   r0   r2   r5   rC   r3   rc   r4   )rD   r‚   Ú
normalizedrb   r/   Úis_currently_structureds         r   Únormalize_messagesÚ!InputFormatter.normalize_messages   sQ  € ð ˆ
ÜˆGØ˜WÓ$¨	¸Ó(@Ü—‘Ð!9¸'¸À+ÐNÔOÙà˜iÑ(ˆGÜ&0°¼$Ó&?×&lÀG×&lÔPZÐ[bÐcdÑ[eÔgkÓPlÐ#à×"Ñ" fÓ,Ö1HÜ�w“< 1Ó$¨°7¸1±:Ó)=Ø×%Ñ%Ð&P¨Ð&P°)¸WÀQ¹ZÈÑ=OÑ&PÖQä—N‘Nð$Ü$'¨£L >Ð1TðVôð ×%Ñ% gÖ.Ø×$Ñ$¨Ó4Ö=TÜ˜g¤s×+Ñ+Ø×%Ñ%Ð&a¨Ð&a°)ÀvÐW^Ñ>_Ð=`Ñ&a×bà×%Ñ% g×.à×!Ñ! '×*ñ/  ð2 Ðr   c                ó¦   • U R                   S:X  a  U Vs/ s H  nSUS./U-   PM     sn$ U Vs/ s H  nSSUS./S./U-   PM     sn$ s  snf s  snf )z÷Prepend a system prompt to message format inputs.

Args:
    messages: List of message lists (each message list represents one input).
    prompt: System prompt to prepend.

Returns:
    Messages with system prompt prepended to each message list.
r   ÚsystemrŽ   r   r´   )rC   )rD   r‚   ÚpromptÚmessage_lists       r   Úprepend_prompt_to_messagesÚ)InputFormatter.prepend_prompt_to_messagesÇ  sy   € ð ×Ñ &Ó(Ù_gÓhÒ_gÈ|˜h°6Ñ:Ð;¸lÔJÑ_gÑhÐhñ !)ó
â (�ð °VÀVÑ,LÐ+MÑNÐOÐR^Ô^Ù (ñ
ð 	
ùò iùò
s
   •A	¯Ac           	     ó¼   • / nU HS  n[        U[        5      (       a  UR                  X$-   5        M-  UR                  X$S   -   /[        USS 5      -   5        MU     U$ )a"  Prepend a prompt to text format inputs.

For single texts, prepends the prompt directly.
For text pairs (cross-encoder inputs), prepends only to the first text.

Args:
    texts: List of text inputs (strings or pairs)
    prompt: Prompt to prepend

Returns:
    Texts with prompt prepended
r   r-   N)r0   r4   rc   r2   )rD   Útextsr»   Úresultr   s        r   Úprepend_prompt_to_textsÚ&InputFormatter.prepend_prompt_to_textsÚ  sZ   € ð ˆÛˆDÜ˜$¤×$Ñ$Ø—‘˜f™mÖ,à—‘˜v¨Q©Ñ/Ð0´4¸¸Q¸R¸³>ÑAÖBñ	 ð
 ˆr   )rC   r?   r@   rA   )r=   NN)r?   r4   rC   r   rA   úlist[Modality] | NoneÚreturnÚNone)rÅ   zLiteral['structured', 'flat'])ry   úlist[SingleInput | PairInput]rÅ   zBtuple[Modality, dict[str, list], defaultdict[str, dict[str, Any]]])rW   ztuple | listrÅ   úlist[dict[str, Any]])Úuser)rž   zdict[Modality, Any]r.   r4   rÅ   rÈ   )r~   r	   r§   r5   rÅ   z*tuple[Literal['message'], dict[str, list]])r°   úlist[list[dict[str, Any]]]rÅ   Úbool)r‚   rÈ   rÅ   rÈ   )r‚   rÊ   r»   r4   rÅ   rÊ   )rÀ   z'list[str | tuple[str, str] | list[str]]r»   r4   rÅ   zlist[str | list[str]])Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__rE   rB   rŠ   rq   rr   rª   Ústaticmethodr±   r·   r½   rÂ   Ú__static_attributes__rK   r   r   r:   r:   f   sÞ   † ñð< )/ØØ6:ð1àð1ð &ð1ð
 4ð1ð 
õ1ô ðDtAà-ðtAð 
LôtAôl!
öF
ð<0Ø ð0Ø48ð0à	3ô0ð: óó ðô0%ðN
Ø2ð
Ø<?ð
à	#ô
ð&Ø<ðØFIðà	÷r   r:   c                ón  • [         b  [        U [         5      (       a  g[        b  [        U [        5      (       a  g[        b  [        U [        5      (       a  gU =[        S` =b  u   [        U 5      (       a    Ub  SU;  a  gg  =[        S` =b  u   [        U 5      (       a    Ub  SU;  a  gg  =[        S` =b  u   [        U 5      (       a    Ub  SU;  a  gg  ==[        S` =b  u   OQ  = a"   S:H  a  u  [        S` =b  u   [        S` =b  u   O+    = a"   S:H  a  u  [        S` =b  u   [        S` =b  u   O      O    g=[        S` =b  u   SU ;   a	  SU ;   a    g	  =[        S` =b5  u   U (       a-  [        U S
   [        5      (       a  SU S
   ;   a  SU S
   ;   a    g	  =[        S` =b  u   SU ;   a	  SU ;   a    g  =[        S` =b  u   SU ;   a	  SU ;   a    g  =[        S` =b.  u   SU ;   a'    [        S[        U R                  5       5       35      e  =[        S` =bd  u   U (       a\    1 Skn[        U R                  5       5      U-
  nU(       a  [        SU SU 35      e[        [        U R                  5       5      5      $   =[        S` =b  u     [        S5      e  =[        R                   S` =b  u   O  =["        R$                  S` =b  u   O    OM  U R&                  S;   a  gU R&                  S:X  a  gU R&                  S;   a  g[        SU R&                   S35      e [        S[)        U 5      R*                   S35      e)a×  Infer the modality of a single input sample by inspecting its type/structure.

Pure type-based detection, does not require a processor or tokenizer.

Args:
    sample: A single input sample to inspect.
    supported_modalities: Optional list of modalities the model supports. When provided,
        string inputs that would be classified as image/video/audio based on URL/path
        heuristics are instead classified as ``"text"`` if that modality is not supported.
        This prevents misclassification of text that happens to contain media URLs.

Returns:
    The detected modality string, or a tuple of modality strings for multimodal dict inputs.

Raises:
    ValueError: If the input type/structure is not recognized.
ÚimagerY   r]   rK   r   r,   r.   r/   rb   r   rZ   r[   r^   zuDict input with 'array' key must also include 'sampling_rate' (for audio) or 'video_metadata' (for video). Got keys: >   r   rY   rÔ   r]   z;Multimodal dict input contains unrecognized modality keys: z. Expected keys from: z-Empty dict input is not a valid input sample.)r-   r,   é   )é   é   z#Unsupported tensor dimensionality: z<D. Expected 1-2D for audio, 3D for image, or 4-5D for video.zUnsupported input type: zG. Expected one of: str, dict, PIL.Image.Image, np.ndarray, torch.Tensor)ÚPILImager0   r   r   r4   r%   r(   r*   r5   r2   Ú
ValueErrorrt   rv   r1   ÚsortedÚnpÚndarrayÚtorchÚTensorÚndimr‘   rÌ   )r6   rA   Úvalid_modalitiesÚinvalid_keyss       r   rd   rd   ò  s  € ô, Ñ¤
¨6´8× <Ñ <ØäÑ¤J¨v´|×$DÑ$DØäÑ¤J¨v´|×$DÑ$DØà
ØŒSŽUÔ*¨6×2Ñ2ˆUØ#Ñ/°GÐCWÓ4WØØð ð ŒSŽUÔ*¨6×2Ñ2ˆUØ#Ñ/°GÐCWÓ4WØØð ð ŒSŽUÔ*¨6×2Ñ2ˆUØ#Ñ/°GÐCWÓ4WØØð ð 5ˆUŒS�UˆU—^“^”c–eœSžU’^§n£n¤s¦u¬c®e¢nÓ4ØØŒTŽV�v Ó'¨I¸Ó,?ˆVØð àŒTŽV–v¤*¨V°A©Y¼×"=Ñ"=À&ÈFÐSTÉIÓBUÐZcÐgmÐnoÑgpÓZpˆVØð àŒTŽV�w &Ó(¨_ÀÓ-FˆVØð àŒTŽV�w &Ó(Ð-=ÀÓ-GˆVØð àŒTŽV�w &Ó(ˆVÜðä  §¡£Ó/Ð0ð2óð ð ð ŒTŽV–vˆVâBÐÜ˜vŸ{™{›}Ó-Ð0@Ñ@ˆLÞÜ ØQÐR^ÐQ_ð `+Ø+;Ð*<ð>óð ô œ §¡£Ó.Ó/Ð/ð ð ŒT�VÜÐLÓMÐMð àŒR�Z‰Z�\ˆ\˜NœEŸL™LŸN˜NÒ*Ø�{‰{˜fÓ$ØØ—‘ Ó!ØØ—‘ Ó&Øä Ø9¸&¿+¹+¸ð GPð Qóð ð ÜØ*¬4°«<×+@Ñ+@Ð*Að BXð Yóð r   c                ó�   • U (       d  gU  Vs1 s H  n[        X!S9iM     nn[        U5      S:X  a  UR                  5       $ S$ s  snf )ah  Infer the modality of a batch of input samples.

If all samples share the same modality, that modality is returned. If the batch contains
mixed modalities, ``"message"`` is returned, consistent with how :class:`InputFormatter`
handles mixed-modality batches in :meth:`~InputFormatter.parse_inputs`.

Args:
    samples: List of input samples to inspect.
    supported_modalities: Optional list of modalities the model supports. Passed through
        to :func:`infer_modality` to prevent misclassification of text as media modalities.

Returns:
    The detected modality, or ``"message"`` for mixed-modality batches.
r   rX   r-   rb   )rd   r3   ru   )r€   rA   r6   r…   s       r   Úinfer_batch_modalityrã   M  sI   € ö$ ØÙbiÓjÒbiÐX^”. ÔSÑbi€JÐjÜ" :›°!Ó3ˆ:�>‰>ÓÐB¸ÐBùò ks   �Ac                óR   • [        U [        5      (       a  SR                  U 5      $ U $ )zSFormat a modality for display, e.g. ``("text", "image")`` becomes ``"text+image"``.Ú+)r0   r1   Újoin)r~   s    r   Úformat_modalityrç   e  s#   € ä�(œE×"Ñ"Ø�x‰x˜Ó!Ð!Ø€Or   )r   r4   rÅ   rË   )r   r4   r"   ztuple[str, ...]rÅ   rË   )r6   r   rÅ   rË   rJ   )r6   zSingleInput | PairInput | AnyrA   rÄ   rÅ   r	   )r€   rÇ   rA   rÄ   rÅ   r	   )r~   r	   rÅ   r4   )*rÐ   Ú
__future__r   Úloggingr    Úcollectionsr   Útypingr   r   Úurllib.parser   rh   rÛ   rÝ   Ú)sentence_transformers.base.modality_typesr   r	   r
   r   Ú	PIL.Imager   rØ   ÚImportErrorÚtorchcodec.decodersr   r   ÚOSErrorÚ	getLoggerrÌ   rw   rQ   r   r#   r%   r(   r*   r8   r:   rd   rã   rç   rK   r   r   Ú<module>ró      s  ðÙ Gå "ã Û 	Ý #ß Ý !ã Û ÷ó ðÝ+ðß>ð
 
×	Ò	˜8Ó	$€ð
 ØØØñ	%Ð !ôHô
Fôdô	ôRô
÷*Iñ Ið\ 37ðXØ)ðXà/ðXð õXðz 37ðCØ*ðCà/ðCð õCõ0øð] ó Ø‚Hðûð
 	�WÐó Ø€LØ‚Lðús#   ºB* ÁB8 Â*B5Â4B5Â8CÃC