§
    ™Štj�ö  ã                  óz  — d dl m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	 d dl
mZmZmZ d dlZd dlm
Z d dlZd dlmZmZ d dlmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZ d dl m!Z! d dl"m#Z# d dl$m%Z% d dl&m'Z' d dl(m)Z) d dl*m+Z+m,Z, d dl-m.Z.m/Z/ d dl0m1Z1 d dl2m3Z3  ej4        e5¦  «        Z6 G d„ de!¦  «        Z7dS )é    )ÚannotationsN)ÚCallable)ÚQueue)ÚAnyÚLiteralÚoverload)ÚTensorÚnn)Útrange)Ú
AutoConfigÚPretrainedConfig)ÚPreTrainedModel)Úlogging)Ú
deprecated)Ú	BaseModel)Ú	TextInput)ÚTransformer)ÚPooling)ÚSparseEncoderModelCardData)ÚSparseAutoEncoderÚSpladePooling)Úbatch_to_deviceÚselect_max_active_dims)Údeprecated_kwargs)ÚSimilarityFunctionc                  óÎ  ‡ — e Zd ZU dZeZdZded<   dddœZded<   d	Z	d Z
d
ed<    ed¬¦  «        	 d~dddddddddddddddddœdˆ fd,„¦   «         Z ed-¬.¦  «        	 	 	 	 	 	 	 	 	 	 	 d€d�dB„¦   «         Z ed-¬.¦  «        	 	 	 	 	 	 	 	 	 	 	 d€d�dC„¦   «         Z ed-¬.¦  «        	 	 	 	 	 	 	 	 	 	 	 d€d�dD„¦   «         Zd‚ˆ fdF„Zdƒˆ fdH„Zed„dJ„¦   «         Zej        d…dM„¦   «         Zd†dO„Zed‡dS„¦   «         ZedˆdU„¦   «         Zed‰dW„¦   «         Zed‡dX„¦   «         ZedˆdY„¦   «         Zed‰dZ„¦   «         Z	 	 	 	 dŠd‹d\„ZedŒdb„¦   «         Zd�dc„Z edde¬e¦  «        d�df„¦   «         Z	 	 	 	 	 	 dŽd�dh„Z 	 	 	 	 	 	 	 d�d‘di„Z!ed’dm„¦   «         Z"ed“ˆ fdn„¦   «         Z#e#j        d”do„¦   «         Z#ed•ˆ fdq„¦   «         Z$d–ds„Z%ed�dt„¦   «         Z&e&j        d—du„¦   «         Z&ed˜dx„¦   «         Z'	 d~d™d{„Z(dšd}„Z)ˆ xZ*S )›ÚSparseEncoderaJ  
    Loads or creates a SparseEncoder model that can be used to map text to sparse embeddings.

    Args:
        model_name_or_path (str, optional): If a filepath on disk, loads the model from that path. Otherwise, tries
            to download a pre-trained SparseEncoder model. If that fails, tries to construct a model from the
            Hugging Face Hub with that name. Defaults to None.
        modules (list[nn.Module], optional): A list of torch modules that are called sequentially. Can be used to
            create custom SparseEncoder models from scratch. Defaults to None.
        device (str, optional): Device (like ``"cuda"``, ``"cpu"``, ``"mps"``, ``"npu"``) that should be used for
            computation. If None, checks if a GPU can be used. If a ``device_map`` is provided via
            ``model_kwargs``, that controls device placement and this argument is ignored. Defaults to None.
        prompts (dict[str, str], optional): A dictionary with prompts for the model. The key is the prompt name,
            the value is the prompt text. The prompt text will be prepended before any text to encode. For example:
            ``{"query": "query: ", "passage": "passage: "}``. If a model has saved prompts, you can override
            them by passing your own, or pass ``{"query": "", "document": ""}`` to disable them.
            Defaults to None.
        default_prompt_name (str, optional): The name of the prompt that should be used by default. If not set,
            no prompt will be applied. Defaults to None.
        cache_folder (str, optional): Path to store models. Can also be set by the ``SENTENCE_TRANSFORMERS_HOME``
            environment variable. Defaults to None.
        trust_remote_code (bool, optional): Whether to allow for custom models defined on the Hub in their own
            modeling files. Only set to ``True`` for repositories you trust and in which you have read the code,
            as it will execute code present on the Hub on your local machine. Defaults to False.
        revision (str, optional): The specific model version to use. It can be a branch name, a tag name, or a
            commit id, for a stored model on Hugging Face. Defaults to None.
        local_files_only (bool, optional): Whether to only look at local files (i.e., do not try to download
            the model). Defaults to False.
        token (bool or str, optional): Hugging Face authentication token to download private models.
            Defaults to None.
        model_kwargs (dict[str, Any], optional): Keyword arguments passed to the underlying Hugging Face
            Transformers model via ``AutoModel.from_pretrained``. Particularly useful options include:

            - ``torch_dtype``: Override the default ``torch.dtype`` and load the model under a specific
              dtype. Can be ``torch.float16``, ``torch.bfloat16``, ``torch.float32``, or ``"auto"`` to
              use the dtype from the model's ``config.json``.
            - ``attn_implementation``: The attention implementation to use. For example ``"eager"``,
              ``"sdpa"``, or ``"flash_attention_2"``. If you ``pip install kernels``, then
              ``"flash_attention_2"`` should work without having to install ``flash_attn``. It is
              frequently the fastest option. Defaults to ``"sdpa"`` when available (torch>=2.1.1).
            - ``device_map``: Controls how the model is placed across devices, e.g. ``"auto"`` for
              model parallelism, or a single device like ``"cuda:1"`` to load the backbone directly
              onto one GPU (useful when serving multiple models in one process). When set, it takes
              precedence over the ``device`` argument.
            - ``provider``: For ``backend="onnx"``, the ONNX execution provider
              (e.g. ``"CUDAExecutionProvider"``).
            - ``file_name``: For ``backend="onnx"`` or ``"openvino"``, the filename to load
              (e.g. for optimized or quantized models).
            - ``export``: For ``backend="onnx"`` or ``"openvino"``, whether to export the model to the
              backend format. Also set automatically if the exported file doesn't exist.

            See the `PreTrainedModel.from_pretrained
            <https://huggingface.co/docs/transformers/en/main_classes/model#transformers.PreTrainedModel.from_pretrained>`_
            documentation for more details. Defaults to None.
        processor_kwargs (dict[str, Any], optional): Keyword arguments passed to the Hugging Face Transformers
            processor/tokenizer via ``AutoProcessor.from_pretrained``. See the `AutoTokenizer.from_pretrained
            <https://huggingface.co/docs/transformers/en/model_doc/auto#transformers.AutoTokenizer.from_pretrained>`_
            documentation for more details. Defaults to None.
        config_kwargs (dict[str, Any], optional): Keyword arguments passed to the Hugging Face Transformers
            config via ``AutoConfig.from_pretrained``. See the `AutoConfig.from_pretrained
            <https://huggingface.co/docs/transformers/en/model_doc/auto#transformers.AutoConfig.from_pretrained>`_
            documentation for more details. Defaults to None.
        model_card_data (:class:`~sentence_transformers.sparse_encoder.model_card.SparseEncoderModelCardData`, optional):
            A model card data object that contains information about the model. Used to generate a model card
            when saving the model. If not set, a default model card data object is created. Defaults to None.
        backend (str, optional): The backend to use for inference. Can be ``"torch"`` (default), ``"onnx"``,
            or ``"openvino"``. Defaults to ``"torch"``.
        similarity_fn_name (str or SimilarityFunction, optional): The name of the similarity function to use.
            Valid options are ``"cosine"``, ``"dot"``, ``"euclidean"``, and ``"manhattan"``. If not set, it is
            automatically set to ``"cosine"`` when :attr:`similarity` or :attr:`similarity_pairwise` are first
            accessed. Defaults to None.
        max_active_dims (int, optional): The maximum number of active (non-zero) dimensions in the output of the
            model. ``None`` means no limit, which can be slow or memory-intensive if your model wasn't (yet)
            finetuned to high sparsity. Defaults to None.

    Example:
        ::

            from sentence_transformers import SparseEncoder

            # Load a pre-trained SparseEncoder model
            model = SparseEncoder('naver/splade-cocondenser-ensembledistil')

            # Encode some texts
            sentences = [
                "The weather is lovely today.",
                "It's so sunny outside!",
                "He drove to the stadium.",
            ]
            embeddings = model.encode(sentences)
            print(embeddings.shape)
            # (3, 30522)

            # Get the similarity scores between all sentences
            similarities = model.similarity(embeddings, embeddings)
            print(similarities)
            # tensor([[   35.629,     9.154,     0.098],
            #         [    9.154,    27.478,     0.019],
            #         [    0.098,     0.019,    29.553]])
    zsparse-encoderú
str | NoneÚ default_huggingface_organizationN)ÚqueryÚdocumentzdict[str, str | None]Ú_default_promptsÚsparse_encoder_model_idÚstrÚ
model_typeÚprocessor_kwargs)Útokenizer_kwargsFÚtorch)ÚmodulesÚdeviceÚpromptsÚdefault_prompt_nameÚcache_folderÚtrust_remote_codeÚrevisionÚlocal_files_onlyÚtokenÚmodel_kwargsr&   Úconfig_kwargsÚmodel_card_dataÚbackendÚsimilarity_fn_nameÚmax_active_dimsÚmodel_name_or_pathr)   úlist[nn.Module] | Noner*   r+   údict[str, str] | Noner,   r-   r.   Úboolr/   r0   r1   úbool | str | Noner2   údict[str, Any] | Noner3   r4   ú!SparseEncoderModelCardData | Noner5   ú$Literal['torch', 'onnx', 'openvino']r6   ústr | SimilarityFunction | Noner7   ú
int | NoneÚreturnÚNonec               óF  •— || _         t          ¦   «                              |||||||	|
|||||||¬¦  «         |  |�|dk    rt          d|› d�¦  «        ‚|| _        |€@| j                             ¦   «         D ](}t          |t          ¦  «        r|j	        | _         d S Œ'd S d S )N)r8   r)   r*   r-   r.   r/   r0   r1   r2   r&   r3   r4   r5   r+   r,   r   z0max_active_dims must be a positive integer, got ú.)
r6   ÚsuperÚ__init__Ú
ValueErrorr7   Ú_modulesÚvaluesÚ
isinstancer   Úk)Úselfr8   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r&   r3   r4   r5   r6   r7   ÚmoduleÚ	__class__s                      €úh/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/sentence_transformers/sparse_encoder/model.pyrG   zSparseEncoder.__init__�   sô   ø€ ð0 #5ˆÔå‰Œ×ÒØ1ØØØ%Ø/ØØ-ØØ%Ø-Ø'Ø+ØØØ 3ð 	ñ 	
ô 	
ð 	
ð$ 	Ð8àÐ&¨?¸aÒ+?Ð+?ÝÐbÐP_ÐbÐbÐbÑcÔcÐcØ.ˆÔØÐ"Øœ-×.Ò.Ñ0Ô0ð ð �Ý˜fÕ&7Ñ8Ô8ð Ø+1¬8�DÔ(Ø�E�Eðð #Ð"ðð ó    Úinputs)Ú	sentencesé    Túlist[TextInput] | TextInputÚprompt_nameÚpromptÚ
batch_sizeÚintÚshow_progress_barúbool | NoneÚconvert_to_tensorÚconvert_to_sparse_tensorÚsave_to_cpuú4str | torch.device | list[str | torch.device] | NoneÚpoolú9dict[Literal['input', 'output', 'processes'], Any] | NoneÚ
chunk_sizeÚkwargsr   úlist[Tensor] | Tensorc                óV   — |€|€d| j         v rd} | j        d|||||||||	|
||ddœ|¤ŽS )aG  
        Computes embeddings specifically optimized for query representation.

        This method is a specialized version of :meth:`encode` that differs in exactly two ways:

        1. If no ``prompt_name`` or ``prompt`` is provided, it uses a predefined "query" prompt,
           if available in the model's ``prompts`` dictionary.
        2. It sets the ``task`` to "query". If the model has a :class:`~sentence_transformers.base.modules.Router`
           module, it will use the "query" task type to route the input through the appropriate submodules.

        .. tip::

            Adjusting ``batch_size`` can significantly improve processing speed. The optimal value depends on your
            hardware, model size, precision, and input length. Benchmark a few batch sizes on a small subset of your
            data to find the best value.

        All other parameters are identical to :meth:`encode`. See :meth:`encode` for the full parameter documentation.

        Example:
            ::

                from sentence_transformers import SparseEncoder

                # Load a pre-trained SparseEncoder model
                model = SparseEncoder("naver/splade-cocondenser-ensembledistil")

                # Encode some texts
                queries = [
                    "What are the effects of climate change?",
                    "History of artificial intelligence",
                    "Technical specifications product XYZ",
                ]
                embeddings = model.encode_query(queries)
                print(embeddings.shape)
                # (3, 30522)
        Nr    ©rR   rV   rW   rX   rZ   r\   r]   r^   r*   r7   r`   rb   Útask© ©r+   Úencode)rM   rR   rV   rW   rX   rZ   r\   r]   r^   r*   r7   r`   rb   rc   s                 rP   Úencode_queryzSparseEncoder.encode_queryÆ   sq   € ðj Ð 6 >°gÀÄÐ6MÐ6MØ!ˆKàˆtŒ{ð 
ØØ#ØØ!Ø/Ø/Ø%=Ø#ØØ+ØØ!Øð
ð 
ð ð
ð 
ð 	
rQ   c                ód   — |€|€dD ]}|| j         v r|} nŒ | j        d|||||||||	|
||ddœ|¤ŽS )aü  
        Computes embeddings specifically optimized for document/passage representation.

        This method is a specialized version of :meth:`encode` that differs in exactly two ways:

        1. If no ``prompt_name`` or ``prompt`` is provided, it uses the first available prompt from the following
           candidates: ``"document"``, ``"passage"``, ``"corpus"`` (checked in that order).
        2. It sets the ``task`` to "document". If the model has a :class:`~sentence_transformers.base.modules.Router`
           module, it will use the "document" task type to route the input through the appropriate submodules.

        .. tip::

            Adjusting ``batch_size`` can significantly improve processing speed. The optimal value depends on your
            hardware, model size, precision, and input length. Benchmark a few batch sizes on a small subset of your
            data to find the best value.

        All other parameters are identical to :meth:`encode`. See :meth:`encode` for the full parameter documentation.

        Example:
            ::

                from sentence_transformers import SparseEncoder

                # Load a pre-trained SparseEncoder model
                model = SparseEncoder("naver/splade-cocondenser-ensembledistil")

                # Encode some texts
                sentences = [
                    "This research paper discusses the effects of climate change on marine life.",
                    "The article explores the history of artificial intelligence development.",
                    "This document contains technical specifications for the new product line.",
                ]
                embeddings = model.encode_document(sentences)
                print(embeddings.shape)
                # (3, 30522)
        N)r!   ÚpassageÚcorpusr!   rf   rh   ri   )rM   rR   rV   rW   rX   rZ   r\   r]   r^   r*   r7   r`   rb   rc   Úcandidate_prompt_names                  rP   Úencode_documentzSparseEncoder.encode_document  sŽ   € ðj Ð 6 >Ø)Jð ð Ð%Ø(¨D¬LÐ8Ð8Ø"7�KØ�Eð 9ð ˆtŒ{ð 
ØØ#ØØ!Ø/Ø/Ø%=Ø#ØØ+ØØ!Øð
ð 
ð ð
ð 
ð 	
rQ   c                ó°  ‡ ‡‡— |€1t                                ¦   «         t          j        t          j        fv }|dk    rt          d|› d�¦  «        ‚‰                      ‰¦  «        }|r‰gŠnRt          ‰t          ¦  «        s=t          ‰t          j
        ¦  «        r‰                     ¦   «         nt          ‰¦  «        Š‰                      ¦   «         }t          |¦  «        t          |¦  «        z
  ddhz
  x}rRt          ‰ j        j        › dt          |¦  «        › d�|rd	‰ j        j        › d
|› d�nd	‰ j        j        › d�z   ¦  «        ‚|€(t          |	t          ¦  «        r9t!          |	¦  «        dk    r& ‰ j        d‰|||	||||||d|
dœ|¤Ž}|r|d         }|S ‰                      ||¦  «        }|	€‰ j        }	‰                      |	¦  «         ‰                      ¦   «          |
�|
n‰ j        }
t/          |¦  «        }|
�|
|d<   g Št          j        ˆ fd„‰D ¦   «         ¦  «        }‰                      ¦   «         r‰                      |¦  «        }ˆfd„|D ¦   «         }t7          dt!          ‰¦  «        |d| ¬¦  «        D ]½}||||z   …         } ‰ j        |fd|i|¤Ž}t;          ||	¦  «        }t=          j        ¦   «         5   ‰ |fi |¤Žd         }|
�tA          ||
¬¦  «        }ddd¦  «         n# 1 swxY w Y   |r| !                    ¦   «         }|r| "                    ¦   «         }‰ #                    |¦  «         Œ¾ˆfd„t          j        |¦  «        D ¦   «         Š|rot!          ‰¦  «        dk    rHt=          j$        g ‰ j        ¬¦  «        Š|r‰ !                    ¦   «         Š|r‰ "                    ¦   «         Šnt=          j%        ‰¦  «        Š|r‰d         Š‰S )aÐ  
        Computes sparse sentence embeddings.

        .. tip::

            If you are unsure whether you should use :meth:`encode`, :meth:`encode_query`, or :meth:`encode_document`,
            your best bet is to use :meth:`encode_query` and :meth:`encode_document` for Information Retrieval tasks
            with clear query and document/passage distinction, and use :meth:`encode` for all other tasks.

            Note that :meth:`encode` is the most general method and can be used for any task, including Information
            Retrieval, and that if the model was not trained with predefined prompts and/or task types, then all three
            methods will return identical embeddings.

        .. tip::

            Adjusting ``batch_size`` can significantly improve processing speed. The optimal value depends on your
            hardware, model size, precision, and input length. Benchmark a few batch sizes on a small subset of your
            data to find the best value.

        Args:
            inputs (Union[str, List[str]]): The texts to embed.
            prompt_name (str, optional): The name of the prompt to use for encoding. Must be a key in the ``prompts``
                dictionary, which is either set in the constructor or loaded from the model configuration. For example if
                ``prompt_name`` is "query" and the ``prompts`` is {"query": "query: ", ...}, then the sentence "What
                is the capital of France?" will be encoded as "query: What is the capital of France?" because the sentence
                is appended to the prompt. If ``prompt`` is also set, this argument is ignored. Defaults to None.
            prompt (str, optional): The prompt to use for encoding. For example, if the prompt is "query: ", then the
                sentence "What is the capital of France?" will be encoded as "query: What is the capital of France?"
                because the sentence is appended to the prompt. If ``prompt`` is set, ``prompt_name`` is ignored.
                Defaults to None.
            batch_size (int, optional): The batch size used for the computation. Defaults to 32.
            show_progress_bar (bool, optional): Whether to output a progress bar when encoding. Defaults to None,
                in which case the progress bar will be shown if the logger's effective level is INFO or DEBUG.
            convert_to_tensor (bool, optional): Whether the output should be a single stacked tensor (True) or a list
                of individual tensors (False). Sparse tensors may be challenging to slice, so this allows you to
                output lists of tensors instead. Defaults to True.
            convert_to_sparse_tensor (bool, optional): Whether the output should be in the format of a sparse (COO) tensor.
                Defaults to True.
            save_to_cpu (bool, optional): Whether the output should be moved to cpu or stay on the device it has been
                computed on. Defaults to False.
            device (str, torch.device, list, or None, optional): Device(s) to use for computation. Can be:

                - A single device string (e.g., "cuda:0", "cpu") for single-process encoding
                - A list of device strings (e.g., ["cuda:0", "cuda:1"], ["cpu", "cpu", "cpu", "cpu"]) to distribute
                  encoding across multiple processes
                - None to auto-detect available device for single-process encoding

                If a list is provided, multi-process encoding will be used. Defaults to None.
            max_active_dims (int, optional): The maximum number of active (non-zero) dimensions in the output of the
                model. ``None`` means the value from the model's config will be used. Defaults to None. If also None in
                the model's config, there will be no limit on the number of active dimensions, which can be slow or
                memory-intensive if your model wasn't (yet) finetuned to high sparsity.
            pool (dict, optional): A pool created by :meth:`start_multi_process_pool` for multi-process encoding.
                If provided, the encoding will be distributed across multiple processes. This is recommended for large
                datasets and when multiple GPUs are available. Defaults to None.
            chunk_size (int, optional): Size of chunks for multi-process encoding. Only used with multiprocessing, i.e.
                when ``pool`` is not None or ``device`` is a list. If None, a sensible default is calculated.
                Defaults to None.
            **kwargs: Additional keyword arguments forwarded to the model's ``preprocess`` and ``forward``. A notable
                one is ``processing_kwargs``, which lets you override the processor kwargs configured on the
                underlying :class:`~sentence_transformers.base.modules.Transformer` for this call only (e.g.
                ``processing_kwargs={"text": {"max_length": 256, "truncation": True}}``). See
                :meth:`Transformer.preprocess <sentence_transformers.base.modules.Transformer.preprocess>` for the
                accepted structure.

        Returns:
            Union[list[Tensor], Tensor]: By default, a 2d torch sparse tensor with shape [num_inputs, output_dimension]
            is returned. If only one string input is provided, then the output is a 1d tensor with shape
            [output_dimension]. If ``convert_to_tensor`` is False, a list of individual tensors is returned instead.

        Example:
            ::

                from sentence_transformers import SparseEncoder

                # Load a pre-trained SparseEncoder model
                model = SparseEncoder("naver/splade-cocondenser-ensembledistil")

                # Encode some texts
                sentences = [
                    "The weather is lovely today.",
                    "It's so sunny outside!",
                    "He drove to the stadium.",
                ]
                embeddings = model.encode(sentences)
                print(embeddings.shape)
                # (3, 30522)
        Nr   z+batch_size must be a positive integer, got rE   rg   Úprocessing_kwargszZ.encode() has been called with additional keyword arguments that this model does not use: z. zAs per zA.get_model_kwargs(), the valid additional keyword arguments are: zQ.get_model_kwargs(), this model does not accept any additional keyword arguments.T)rR   rZ   r`   r*   rb   rV   rW   rX   r\   r]   r^   r7   r7   c                ó<   •— g | ]}‰                      |¦  «         ‘ŒS rh   )Ú_input_length)Ú.0ÚsenrM   s     €rP   ú
<listcomp>z(SparseEncoder.encode.<locals>.<listcomp>	  s*   ø€ Ð'SÐ'SÐ'SÀS¨×);Ò);¸CÑ)@Ô)@Ð(@Ð'SÐ'SÐ'SrQ   c                ó    •— g | ]
}‰|         ‘ŒS rh   rh   )ru   ÚidxrR   s     €rP   rw   z(SparseEncoder.encode.<locals>.<listcomp>  s   ø€ ÐBÐBÐB¨˜ œÐBÐBÐBrQ   ÚBatches©ÚdescÚdisablerW   Úsentence_embedding)r7   c                ó    •— g | ]
}‰|         ‘ŒS rh   rh   )ru   ry   Úall_embeddingss     €rP   rw   z(SparseEncoder.encode.<locals>.<listcomp>!  s   ø€ ÐWÐWÐW°#˜.¨Ô-ÐWÐWÐWrQ   )r*   rh   )&ÚloggerÚgetEffectiveLevelr   ÚINFOÚDEBUGrH   Úis_singular_inputrK   ÚlistÚnpÚndarrayÚtolistÚget_model_kwargsÚsetrO   Ú__name__ÚlenÚ_multi_processÚ_resolve_promptr*   ÚtoÚevalr7   ÚdictÚargsortÚ_can_flatten_inputsÚ_interleave_sorted_indicesr   Ú
preprocessr   r(   Úinference_moder   Ú	to_sparseÚcpuÚextendÚtensorÚstack)rM   rR   rV   rW   rX   rZ   r\   r]   r^   r*   r7   r`   rb   rc   r…   r2   Úunused_kwargsÚ
embeddingsÚforward_kwargsÚlength_sorted_idxÚinputs_sortedÚstart_indexÚinputs_batchÚfeaturesr€   s   ``                      @rP   rj   zSparseEncoder.encode[  s)  øøø€ ðR Ð$Ý &× 8Ò 8Ñ :Ô :Ý”Ý”ð?ð !Ðð
 ˜Š?ˆ?ÝÐXÈ:ÐXÐXÐXÑYÔYÐYð !×2Ò2°6Ñ:Ô:ÐØð 	YØ�XˆFˆFÝ˜F¥DÑ)Ô)ð 	Yå(2°6½2¼:Ñ(FÔ(FÐX�V—]’]‘_”_�_ÍDÐQWÉLÌLˆFð ×,Ò,Ñ.Ô.ˆÝ ™KœK­#¨lÑ*;Ô*;Ñ;¸vÐGZÐ>[Ñ[Ð[ˆ=ð 	ÝØ”>Ô*ð  ^ð  ^õ  GKð  LYñ  GZô  GZð  ^ð  ^ð  ^ð $ðNð  H˜dœnÔ5ð  Hð  Hð  yEð  Hð  Hð  Hð  Hð N 4¤>Ô#:ð  Nð  Nð  Nñ	ñô ð ð Ð¥
¨6µ4Ñ 8Ô 8Ð½SÀ¹[¼[È1º_¸_Ø,˜Ô,ð Øà"3àØØ%à'ØØ%Ø"3Ø)AØ Ø /ðð ð  ð!ð ˆJð$ !ð +Ø'¨œ]�
ØÐà×%Ò% f¨kÑ:Ô:ˆàˆ>Ø”[ˆFà�Š�‰ŒˆØ�	Š	‰Œˆà-<Ð-H˜/˜/ÈdÔNbˆå˜f™œˆØÐ&Ø0?ˆNÐ,Ñ-àˆÝœJÐ'SÐ'SÐ'SÐ'SÈFÐ'SÑ'SÔ'SÑTÔTÐØ×#Ò#Ñ%Ô%ð 	SØ $× ?Ò ?Ð@QÑ RÔ RÐØBÐBÐBÐBÐ0AÐBÑBÔBˆå! !¥S¨¡[¤[°*À9ÐZkÐVkÐlÑlÔlð 	.ð 	.ˆKØ(¨°{ÀZÑ7OÐ)OÔPˆLØ&�t” |ÐMÐM¸FÐMÀfÐMÐMˆHÝ& x°Ñ8Ô8ˆHåÔ%Ñ'Ô'ð eð eà!˜T (Ð=Ð=¨nÐ=Ð=Ð>RÔS�
à"Ð.Ý!7¸
ÐTcÐ!dÑ!dÔ!d�Jðeð eð eñ eô eð eð eð eð eð eð eøøøð eð eð eð eð (ð 4Ø'×1Ò1Ñ3Ô3�
Øð .Ø'Ÿ^š^Ñ-Ô-�
à×!Ò! *Ñ-Ô-Ð-Ð-àWÐWÐWÐW½¼ÐDUÑ9VÔ9VÐWÑWÔWˆàð 	=Ý�>Ñ"Ô" aÒ'Ð'Ý!&¤¨b¸¼Ð!EÑ!EÔ!E�Ø+ð @Ø%3×%=Ò%=Ñ%?Ô%?�NØð :Ø%3×%7Ò%7Ñ%9Ô%9�Nøå!&¤¨^Ñ!<Ô!<�àð 	/Ø+¨AÔ.ˆNàÐs   Ê?#K.Ë.K2	Ë5K2	údict[str, Any]c                óX   •— t          ¦   «                              ¦   «         d| j        iz  S ©Nr6   )rF   Ú_get_model_configÚ_similarity_fn_name©rM   rO   s    €rP   r¨   zSparseEncoder._get_model_config2  s-   ø€ Ý‰wŒw×(Ò(Ñ*Ô*Ø  $Ô":ð.
ñ 
ð 	
rQ   Úmodel_configc                ó’   •— t          ¦   «                              |¦  «         | j        €|                     dd ¦  «        | _        d S d S r§   )rF   Ú_parse_model_configr©   Úgetr6   )rM   r«   rO   s     €rP   r­   z!SparseEncoder._parse_model_config7  sK   ø€ Ý‰Œ×#Ò# LÑ1Ô1Ð1ØÔ#Ð+Ø&2×&6Ò&6Ð7KÈTÑ&RÔ&RˆDÔ#Ð#Ð#ð ,Ð+rQ   ú2Literal['cosine', 'dot', 'euclidean', 'manhattan']c                ó@   — | j         €t          j        | _        | j         S )aí  Return the name of the similarity function used by :meth:`SparseEncoder.similarity` and :meth:`SparseEncoder.similarity_pairwise`.

        Returns:
            Literal["cosine", "dot", "euclidean", "manhattan"]: The name of the similarity function.
                Defaults to "dot" when first accessed if not explicitly set.

        Example:
            >>> model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
            >>> model.similarity_fn_name
            'dot'
        )r©   r   ÚDOTr6   ©rM   s    rP   r6   z SparseEncoder.similarity_fn_name<  s!   € ð Ô#Ð+Ý&8Ô&<ˆDÔ#ØÔ'Ð'rQ   ÚvalueúNLiteral['cosine', 'dot', 'euclidean', 'manhattan'] | SimilarityFunction | Nonec                ó¸   — t          |t          ¦  «        r|j        }|| _        |�4t          j        |¦  «        | _        t          j        |¦  «        | _        d S d S ©N)rK   r   r³   r©   Úto_similarity_fnÚ_similarityÚto_similarity_pairwise_fnÚ_similarity_pairwise©rM   r³   s     rP   r6   z SparseEncoder.similarity_fn_nameM  sa   € õ
 �eÕ/Ñ0Ô0ð 	 Ø”KˆEØ#(ˆÔ àÐÝ1ÔBÀ5ÑIÔIˆDÔÝ(:Ô(TÐUZÑ([Ô([ˆDÔ%Ð%Ð%ð ÐrQ   Úinclude_promptc                óN   — | D ]!}t          |t          ¦  «        r
||_         dS Œ"dS )a8  
        Sets the ``include_prompt`` attribute in the pooling layer in the model, if there is one.

        This is useful for models where the prompt should be excluded from the pooling strategy,
        e.g. CSR models with a :class:`~sentence_transformers.sentence_transformer.modules.Pooling` layer.
        N)rK   r   r¼   )rM   r¼   rN   s      rP   Úset_pooling_include_promptz(SparseEncoder.set_pooling_include_promptZ  sC   € ð ð 	ð 	ˆFÝ˜&¥'Ñ*Ô*ð Ø(6�Ô%Ø��ðð	ð 	rQ   Úembeddings1r	   Úembeddings2c                ó   — d S r¶   rh   ©rM   r¿   rÀ   s      rP   Ú
similarityzSparseEncoder.similarityf  s   € ØNQÈcrQ   únpt.NDArray[np.float32]c                ó   — d S r¶   rh   rÂ   s      rP   rÃ   zSparseEncoder.similarityi  s   € ØpsÐpsrQ   úVCallable[[Tensor | npt.NDArray[np.float32], Tensor | npt.NDArray[np.float32]], Tensor]c                ó   — | j          | j        S )aQ  
        Compute the similarity between two collections of embeddings. The output will be a matrix with the similarity
        scores between all embeddings from the first parameter and all embeddings from the second parameter. This
        differs from `similarity_pairwise` which computes the similarity between each pair of embeddings.
        This method supports only embeddings with fp32 precision and does not accommodate quantized embeddings.

        Args:
            embeddings1 (Union[Tensor, ndarray]): [num_embeddings_1, embedding_dim] or [embedding_dim]-shaped numpy array or torch tensor.
            embeddings2 (Union[Tensor, ndarray]): [num_embeddings_2, embedding_dim] or [embedding_dim]-shaped numpy array or torch tensor.

        Returns:
            Tensor: A [num_embeddings_1, num_embeddings_2]-shaped torch tensor with similarity scores.

        Example:
            ::

                >>> model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
                >>> sentences = [
                ...     "The weather is so nice!",
                ...     "It's so sunny outside.",
                ...     "He's driving to the movie theater.",
                ...     "She's going to the cinema.",
                ... ]
                >>> embeddings = model.encode(sentences)
                >>> model.similarity(embeddings, embeddings)
                tensor([[   30.953,    12.871,     0.000,     0.011],
                        [   12.871,    27.505,     0.580,     0.578],
                        [    0.000,     0.580,    36.068,    15.301],
                        [    0.011,     0.578,    15.301,    39.466]])
                >>> model.similarity_fn_name
                "dot"
                >>> model.similarity_fn_name = "cosine"
                >>> model.similarity(embeddings, embeddings)
                tensor([[    1.000,     0.441,     0.000,     0.000],
                        [    0.441,     1.000,     0.018,     0.018],
                        [    0.000,     0.018,     1.000,     0.406],
                        [    0.000,     0.018,     0.406,     1.000]])
        )r6   r¸   r²   s    rP   rÃ   zSparseEncoder.similarityl  s   € ðR 	ÔÐØÔÐrQ   c                ó   — d S r¶   rh   rÂ   s      rP   Úsimilarity_pairwisez!SparseEncoder.similarity_pairwise˜  s   € ØWZÐWZrQ   c                ó   — d S r¶   rh   rÂ   s      rP   rÉ   z!SparseEncoder.similarity_pairwise›  s	   € ð �rQ   c                ó   — | j          | j        S )aü  
        Compute the similarity between two collections of embeddings. The output will be a vector with the similarity
        scores between each pair of embeddings.
        This method supports only embeddings with fp32 precision and does not accommodate quantized embeddings.

        Args:
            embeddings1 (Union[Tensor, ndarray]): [num_embeddings, embedding_dim] or [embedding_dim]-shaped numpy array or torch tensor.
            embeddings2 (Union[Tensor, ndarray]): [num_embeddings, embedding_dim] or [embedding_dim]-shaped numpy array or torch tensor.

        Returns:
            Tensor: A [num_embeddings]-shaped torch tensor with pairwise similarity scores.

        Example:
            ::

                >>> model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
                >>> sentences = [
                ...     "The weather is so nice!",
                ...     "It's so sunny outside.",
                ...     "He's driving to the movie theater.",
                ...     "She's going to the cinema.",
                ... ]
                >>> embeddings = model.encode(sentences, convert_to_sparse_tensor=False)
                >>> model.similarity_pairwise(embeddings[::2], embeddings[1::2])
                tensor([12.871, 15.301])
                >>> model.similarity_fn_name
                "dot"
                >>> model.similarity_fn_name = "cosine"
                >>> model.similarity_pairwise(embeddings[::2], embeddings[1::2])
                tensor([0.441, 0.406])
        )r6   rº   r²   s    rP   rÉ   z!SparseEncoder.similarity_pairwise   s   € ðH 	ÔÐØÔ(Ð(rQ   úlist[TextInput]c           	     ó  ‡— |                      dd¦  «        }d|d<   d}|€,t          |t          ¦  «        r|                      |¦  «        }d}	 |€Xt	          t          j        t          |¦  «        t          |d         ¦  «        z  dz  ¦  «        d¦  «        }t          |d	¦  «        }|d
         }	|d         Š|r$t          j        t          |¦  «        |z  ¦  «        nd}
t          |
¦  «        D ],}||z  }||||z   …         }|	 
                    |||g¦  «         Œ-t          ˆfd„t          |
d| ¬¦  «        D ¦   «         d„ ¬¦  «        }|D ]%}t          |d	         t          ¦  «        r|d	         ‚Œ&d„ |D ¦   «         }|r´t          |d         t          ¦  «        r-t          t          j                             |¦  «        ¦  «        }n�t          |d         t"          j        ¦  «        rt#          j        |¦  «        }nLt          |d         t(          j        ¦  «        rt)          j        |d¬¦  «        }n|rt#          j        ¦   «         }||r|                      |¦  «         S S # |r|                      |¦  «         w w xY w)a  Internal method for multi-process encoding.

        Distributes encoding across multiple processes using the provided pool or list of devices.
        If a pool is not provided but ``device`` is a list, a pool is created and cleaned up automatically.
        r\   FrZ   NTÚ	processesé
   iˆ  é   ÚinputÚoutputr   c                ó8   •— g | ]}‰                      ¦   «         ‘ŒS rh   )r®   )ru   Ú_Úoutput_queues     €rP   rw   z0SparseEncoder._multi_process.<locals>.<listcomp>í  s%   ø€ ÐnÐnÐn¨�×!Ò!Ñ#Ô#ÐnÐnÐnrQ   ÚChunksr{   c                ó   — | d         S )Nr   rh   )Úxs    rP   ú<lambda>z.SparseEncoder._multi_process.<locals>.<lambda>î  s
   € ˜a œd€ rQ   )Úkeyc                ó   — g | ]
}|d          ‘ŒS )rÐ   rh   )ru   rÒ   s     rP   rw   z0SparseEncoder._multi_process.<locals>.<listcomp>÷  s   € Ð>Ð>Ð>¨˜& œ)Ð>Ð>Ð>rQ   )Úaxis)r®   rK   r†   Ústart_multi_process_poolÚminÚmathÚceilr�   ÚmaxÚrangeÚputÚsortedr   Ú	ExceptionÚ	itertoolsÚchainÚfrom_iterabler(   r	   Úcatr‡   rˆ   ÚconcatenateÚstop_multi_process_pool)rM   rR   rZ   r`   r*   rb   Úencode_kwargsr\   Úcreated_poolÚinput_queueÚ
num_chunksÚchunk_idÚchunk_startÚchunkÚoutput_listrÒ   rž   rÕ   s                    @rP   rŽ   zSparseEncoder._multi_processÇ  sº  ø€ ð *×-Ò-Ð.AÀ5ÑIÔIÐØ-2ˆÐ)Ñ*ð ˆØˆ<�J v­tÑ4Ô4ˆ<Ø×0Ò0°Ñ8Ô8ˆDØˆLð'	3ØÐ!Ý ¥¤­3¨v©;¬;½¸TÀ+Ô=NÑ9OÔ9OÑ+OÐRTÑ+TÑ!UÔ!UÐW[Ñ\Ô\�
Ý  ¨QÑ/Ô/�
à7;¸G´}ˆKØ8<¸X¼ˆLà@FÐM�œ¥3 v¡;¤;°Ñ#;Ñ<Ô<Ð<ÈAˆJÝ! *Ñ-Ô-ð Bð B�Ø&¨Ñ3�Ø˜{¨[¸:Ñ-EÐEÔF�Ø—’ ¨5°-Ð @ÑAÔAÐAÐAå ØnÐnÐnÐn­V°JÀXÐ[lÐWlÐ-mÑ-mÔ-mÐnÑnÔnØ"�Nðñ ô ˆKð &ð $ð $�Ý˜f Qœi­Ñ3Ô3ð $Ø  œ)�Oð$ð ?Ð>°+Ð>Ñ>Ô>ˆJØð ,Ý˜j¨œm­TÑ2Ô2ð DÝ!%¥i¤o×&CÒ&CÀJÑ&OÔ&OÑ!PÔ!P�J�JÝ 
¨1¤­u¬|Ñ<Ô<ð DÝ!&¤¨:Ñ!6Ô!6�J�JÝ 
¨1¤­r¬zÑ:Ô:ð DÝ!#¤°
ÀÐ!CÑ!CÔ!C�JøØ"ð ,Ý"œ\™^œ^�
Øð ð 3Ø×,Ò,¨TÑ2Ô2Ð2Ð2ð3øˆ|ð 3Ø×,Ò,¨TÑ2Ô2Ð2Ð2ð3øøøs   ÁG=I$ É$I>Útarget_deviceÚmodelrî   r   Úresults_queuec                óè  — 	 	 |                      ¦   «         \  }}} |j        |fd| i|¤Ž}t          |t          j        ¦  «        r$|j        j        dk    r|                     ¦   «         }|                     ||g¦  «         nr# t          j
        $ r Y dS t          $ rT}t                               d| › d|› �¦  «         	 |                     ||g¦  «         n# t          $ r Y nw xY wY d}~dS d}~ww xY wŒò)z™Internal working process to encode sentences in multi-process setup.

        Workers are terminated externally via ``stop_multi_process_pool``.
        Tr*   r™   zError in worker process on z: N)r®   rj   rK   r(   r	   r*   Útyper™   rã   ÚqueueÚEmptyrå   r�   Úerror)	rô   rõ   rî   rö   rð   rR   rc   rž   Úes	            rP   Ú_multi_process_workerz#SparseEncoder._multi_process_worker  s?  € ð	ðØ+6¯?ª?Ñ+<Ô+<Ñ(�˜& &Ø)˜Uœ\¨&ÐQÐQ¸ÐQÈ&ÐQÐQ�
Ý˜j­%¬,Ñ7Ô7ð 2¸JÔ<MÔ<RÐV[Ò<[Ð<[Ø!+§¢Ñ!1Ô!1�JØ×!Ò! 8¨ZÐ"8Ñ9Ô9Ð9Ð9øå”;ð ð ð Ø��Ýð ð ð Ý—’ÐO¸=ÐOÐOÈAÐOÐOÑPÔPÐPðØ!×%Ò% x° mÑ4Ô4Ð4Ð4øÝ ð ð ð Ø�Dðøøøà�����øøøøðøøøð	sB   ƒA=B ÂC0Â	C0Â C+Â=CÃC+Ã
C"ÃC+Ã!C"Ã"C+Ã+C0c                óÆ   — d}t          | j                             ¦   «         ¦  «        D ]7}dD ].}t          ||d¦  «        }t	          |¦  «        r |¦   «         } nŒ/|� nŒ8|S )aÌ  
        Returns the number of dimensions in the output of :meth:`SparseEncoder.encode`.

        Unlike :class:`~sentence_transformers.sentence_transformer.model.SentenceTransformer`, sparse encoders do not support ``truncate_dim``,
        so this returns the raw output dimension from the last module in the pipeline.

        Returns:
            int or None: The number of dimensions in the output of ``encode``. If it's not known, it's ``None``.
        N)Úget_embedding_dimensionÚ get_sentence_embedding_dimensionÚget_word_embedding_dimension)ÚreversedrI   rJ   ÚgetattrÚcallable)rM   Ú
output_dimrN   ÚnameÚmethods        rP   rÿ   z%SparseEncoder.get_embedding_dimension!  s�   € ð ˆ
Ý˜tœ}×3Ò3Ñ5Ô5Ñ6Ô6ð 	ð 	ˆFðð ð �õ
 ! ¨¨tÑ4Ô4�Ý˜FÑ#Ô#ð Ø!' ¡¤�JØ�Eðð Ð%Ø�ð &àÐrQ   z\The `get_sentence_embedding_dimension` method has been renamed to `get_embedding_dimension`.)Úcategoryc                ó*   — |                       ¦   «         S r¶   )rÿ   r²   s    rP   r   z.SparseEncoder.get_sentence_embedding_dimension:  s   € ð
 ×+Ò+Ñ-Ô-Ð-rQ   ú&tuple[list[nn.Module], dict[str, Any]]c
           	     óÆ  — ||||dœ}
i |
¥|pi ¥}i |
¥|pi ¥}i |
¥|	pi ¥}	t          j        |fd|i|	¤Ž}t          d„ t          |dd¦  «        pg D ¦   «         ¦  «        }|rJt	          |d||||	| j        ¬¦  «        }t                               d¦  «         t          d	¬
¦  «        }||g}n—t                               d¦  «         t	          |d||||	| j        ¬¦  «        }t          | 
                    ¦   «         d¬¦  «        }t          | 
                    ¦   «         d| 
                    ¦   «         z  dd¬¦  «        }|||g}|s| j                             ||¬¦  «         |i fS )a‡  
        Creates a simple transformer-based model and returns the modules.
        For models with a ForMaskedLM architecture, uses SpladePooling with 'max' strategy.
        For regular Transformers, uses a CSR implementation (Pooling + SparseAutoEncoder) by default.

        Args:
            model_name_or_path (str): The name or path of the pre-trained model.
            token (Optional[Union[bool, str]]): The token to use for the model.
            cache_folder (Optional[str]): The folder to cache the model.
            revision (Optional[str], optional): The revision of the model. Defaults to None.
            trust_remote_code (bool, optional): Whether to trust remote code. Defaults to False.
            local_files_only (bool, optional): Whether to use only local files. Defaults to False.
            model_kwargs (Optional[Dict[str, Any]], optional): Additional keyword arguments for the model. Defaults to None.
            processor_kwargs (Optional[Dict[str, Any]], optional): Additional keyword arguments for the processor/tokenizer. Defaults to None.
            config_kwargs (Optional[Dict[str, Any]], optional): Additional keyword arguments for the config. Defaults to None.
            has_modules (bool, optional): Whether the model has modules.json. Defaults to False.

        Returns:
            tuple[list[nn.Module], dict[str, Any]]: The modules and an empty kwargs dict.
        ©r1   r.   r/   r0   Ú	cache_dirc              3  ó@   K  — | ]}|                      d ¦  «        V — ŒdS )ÚForMaskedLMN)Úendswith)ru   Úarchs     rP   ú	<genexpr>z6SparseEncoder._load_default_modules.<locals>.<genexpr>o  s.   è è € ÐqÐq¸D˜4Ÿ=š=¨Ñ7Ô7ÐqÐqÐqÐqÐqÐqrQ   ÚarchitecturesNz	fill-mask)Útransformer_taskr  r2   r&   r3   r5   z.Detected MLM architecture, using SpladePoolingrá   )Úpooling_strategyz`No MLM architecture detected, using default Transformer + mean Pooling + SparseAutoEncoder (CSR)zfeature-extractionÚmean)Úpooling_modeé   é   i   ©Ú	input_dimÚ
hidden_dimrL   Úk_aux)r/   )r   Úfrom_pretrainedÚanyr  r   r5   r�   Úinfor   r   rÿ   r   r4   Úset_base_model)rM   r8   r1   r-   r/   r.   r0   r2   r&   r3   Úshared_kwargsÚconfigÚis_mlm_modelÚtransformer_modelÚpooling_modelr)   ÚpoolingÚsaes                     rP   Ú_load_default_modulesz#SparseEncoder._load_default_modulesA  s  € ðB Ø!2Ø Ø 0ð	
ð 
ˆð A˜-Ð@¨LÐ,>¸BÐ@ˆØH˜mÐHÐ0@Ð0FÀBÐHÐØB˜=ÐB¨]Ð-@¸bÐBˆå#-Ô#=Øð$
ð $
Ø*6ð$
Ø:Gð$
ð $
ˆõ ÐqÐqÅGÈFÐTcÐeiÑDjÔDjÐDpÐnpÐqÑqÔqÑqÔqˆàð #	8å +Ø"Ø!,Ø&Ø)Ø!1Ø+Øœð!ñ !ô !Ðõ �KŠKÐHÑIÔIÐIÝ)¸5ÐAÑAÔAˆMØ(¨-Ð8ˆGˆGõ �KŠKØrñô ð õ !,Ø"Ø!5Ø&Ø)Ø!1Ø+Øœð!ñ !ô !Ðõ Ð/×GÒGÑIÔIÐX^Ð_Ñ_Ô_ˆGÝ#Ø!×9Ò9Ñ;Ô;Ø˜w×>Ò>Ñ@Ô@Ñ@ØØð	ñ ô ˆCð )¨'°3Ð7ˆGàð 	WØÔ ×/Ò/Ð0BÈXÐ/ÑVÔVÐVØ˜ˆ{ÐrQ   c                ób  — |
dk    r|                       |||||||||	¬¦	  «	        S ||||dœ}i |¥|pi ¥}i |¥|pi ¥}i |¥|	pi ¥}	t                               d¦  «         |                      |||||||||	¬¦	  «	        \  }| _        t          |                     ¦   «         ¦  «        }d}t          |¦  «        D ](}t          |d¦  «        r| 	                    ¦   «         } nŒ)|€t          d¦  «        ‚t          |d|z  |dz  |d	z  ¬
¦  «        }|                     |¦  «         d| _        || j        fS )a)  Converts a non-SparseEncoder model into a SparseEncoder by appending a SparseAutoEncoder.

        If ``model_type`` is ``"SentenceTransformer"``, loads the SentenceTransformer modules and appends a
        SparseAutoEncoder on top. Otherwise, falls back to :meth:`_load_default_modules`.
        ÚSentenceTransformer)r1   r-   r/   r.   r0   r2   r&   r3   r  zWSentenceTransformer model found, appending SparseAutoEncoder on top to form a CSR modelNrÿ   zƒCannot determine the embedding dimension from the loaded modules. At least one module must have a `get_embedding_dimension` method.r  é   r  )r)  r�   r   Ú_load_config_modulesÚmodule_kwargsr†   rJ   r  Úhasattrrÿ   rH   r   ÚappendÚ_model_card_text)rM   r8   r1   r-   r/   r.   r0   r2   r&   r3   r%   r"  r)   r  rN   r(  s                   rP   Ú_load_converted_modulesz%SparseEncoder._load_converted_modulesš  sÏ  € ð$ Ð.Ò.Ð.Ø×-Ò-Ø"ØØ)Ø!Ø"3Ø!1Ø)Ø!1Ø+ð .ñ 
ô 
ð 
ð Ø!2Ø Ø 0ð	
ð 
ˆð A˜-Ð@¨LÐ,>¸BÐ@ˆØH˜mÐHÐ0@Ð0FÀBÐHÐØB˜=ÐB¨]Ð-@¸bÐBˆå�ŠÐmÑnÔnÐnØ&*×&?Ò&?ØØØ%ØØ/Ø-Ø%Ø-Ø'ð '@ñ 
'
ô 
'
Ñ#ˆ�Ô#õ �w—~’~Ñ'Ô'Ñ(Ô(ˆàˆ
Ý˜wÑ'Ô'ð 	ð 	ˆFÝ�vÐ8Ñ9Ô9ð Ø#×;Ò;Ñ=Ô=�
Ø�ðð ÐÝðTñô ð õ  Ø Ø˜:‘~Ø˜A‰oØ ‘/ð	
ñ 
ô 
ˆð 	�Š�sÑÔÐà $ˆÔØ˜Ô*Ð*Ð*rQ   rž   útorch.Tensorúdict[str, float]c                ó€  — t          | t          j        ¦  «        st          d¦  «        ‚| j        dvrt          d| j        › d�¦  «        ‚| j        dk    r|                      d¦  «        } | j        \  }}|dk    s|dk    rddd	œS 	 |                      ¦   «         } n6# t          $ r) |  
                    ¦   «                              ¦   «         } Y nw xY w|                      ¦   «         }|dd
…         |d
d…         z
  }t          j        |                     ¦   «         ¦  «                             ¦   «         }d||z  z
  }||d	œS )a  
        Calculate sparsity statistics for the given embeddings, including the mean number of active
        (non-zero) dimensions and the mean sparsity ratio.

        For a single embedding (1D), the values are for that embedding directly. For a batch of embeddings
        (2D), they are averaged across the batch.

        Args:
            embeddings (torch.Tensor): The embeddings to analyze. Must be a 1D or 2D tensor.

        Returns:
            dict[str, float]: Dictionary with ``"active_dims"`` (mean active dimensions) and
                ``"sparsity_ratio"`` (mean sparsity ratio).

        Example:
            ::

                from sentence_transformers import SparseEncoder

                model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
                embeddings = model.encode(["The weather is so nice!", "It's so sunny outside."])
                stats = model.sparsity(embeddings)
                print(stats)
                # => {'active_dims': 44.0, 'sparsity_ratio': 0.9985584020614624}
        z!Embeddings must be a torch.Tensor)rÐ   r,  z Expected a 1D or 2D tensor, got úD.rÐ   r   g        g      ð?)Úactive_dimsÚsparsity_ratioNéÿÿÿÿ)rK   r(   r	   Ú	TypeErrorÚndimrH   Ú	unsqueezeÚshapeÚto_sparse_csrÚNotImplementedErrorr™   Úcrow_indicesr  ÚfloatÚitem)rž   Únum_rowsÚnum_colsr@  Únon_zero_per_rowÚmean_active_dimsÚmean_sparsity_ratios          rP   ÚsparsityzSparseEncoder.sparsityæ  sw  € õ6 ˜*¥e¤lÑ3Ô3ð 	AÝÐ?Ñ@Ô@Ð@àŒ? &Ð(Ð(ÝÐSÀ
ÄÐSÐSÐSÑTÔTÐTð Œ?˜aÒÐØ#×-Ò-¨aÑ0Ô0ˆJà'Ô-Ñˆ�(à�qŠ=ˆ=˜H¨šM˜Mà"Ø"%ðð ð ð	:Ø#×1Ò1Ñ3Ô3ˆJˆJøÝ"ð 	:ð 	:ð 	:Ø#ŸšÑ)Ô)×7Ò7Ñ9Ô9ˆJˆJˆJð	:øøøà!×.Ò.Ñ0Ô0ˆØ'¨¨¨Ô+¨l¸3¸B¸3Ô.?Ñ?Ðå œ:Ð&6×&<Ò&<Ñ&>Ô&>Ñ?Ô?×DÒDÑFÔFÐØ!Ð%5¸Ñ%@ÑAÐð ,Ø1ð
ð 
ð 	
s   ÂB Â0CÃCc                ó*   •— t          ¦   «         j        S )aª  
        Returns the maximal input sequence length for the model. Longer inputs will be truncated.

        Returns:
            int: The maximal input sequence length.

        Example:
            ::

                from sentence_transformers import SparseEncoder

                model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
                print(model.max_seq_length)
                # => 512
        )rF   Úmax_seq_lengthrª   s    €rP   rJ  zSparseEncoder.max_seq_length#  s   ø€ õ" ‰wŒwÔ%Ð%rQ   c                ó    — || d         _         dS )zs
        Property to set the maximal input sequence length for the model. Longer inputs will be truncated.
        r   N)rJ  r»   s     rP   rJ  zSparseEncoder.max_seq_length6  s   € ð "'ˆˆQŒÔÐÐrQ   úPreTrainedModel | Nonec                ó*   •— t          ¦   «         j        S )a/  
        Property to get the underlying transformers PreTrainedModel instance, if it exists.
        Note that it's possible for a model to have multiple underlying transformers models, but this property
        will return the first one it finds in the module hierarchy.

        Returns:
            PreTrainedModel or None: The underlying transformers model or None if not found.

        Example:
            ::

                from sentence_transformers import SparseEncoder

                model = SparseEncoder("naver/splade-v3")

                # You can now access the underlying transformers model
                transformers_model = model.transformers_model
                print(type(transformers_model))
                # => <class 'transformers.models.bert.modeling_bert.BertForMaskedLM'>
        )rF   Útransformers_modelrª   s    €rP   rN  z SparseEncoder.transformers_model>  s   ø€ õ, ‰wŒwÔ)Ð)rQ   úSpladePooling | Nonec                óp   — | j                              ¦   «         D ]}t          |t          ¦  «        r|c S ŒdS )zVReturns the SpladePooling module if present, or None. Only searches top-level modules.N)rI   rJ   rK   r   )rM   rN   s     rP   Ú_get_splade_poolingz!SparseEncoder._get_splade_poolingV  sD   € à”m×*Ò*Ñ,Ô,ð 	ð 	ˆFÝ˜&¥-Ñ0Ô0ð Ø���ðàˆtrQ   c                ót   — |                       ¦   «         }|�|j        S t                               d¦  «         dS )aƒ  
        Returns the chunk size of the SpladePooling module, if present.

        This chunk size is along the sequence length dimension (i.e., number of tokens per chunk).
        If None, processes the entire sequence at once. Using smaller chunks reduces memory usage but may
        lower training and inference speed. Default is None.

        This property is only meaningful for SPLADE-architecture models. For CSR-architecture models
        (Transformer + Pooling + SparseAutoEncoder), it returns None.

        Returns:
            int or None: The chunk size, or None if SpladePooling is not found or chunk_size is not set.
        Nz6SpladePooling module not found. Cannot get chunk_size.©rQ  rb   r�   Úwarning)rM   Úsplade_poolings     rP   Úsplade_pooling_chunk_sizez'SparseEncoder.splade_pooling_chunk_size]  s<   € ð ×1Ò1Ñ3Ô3ˆØÐ%Ø!Ô,Ð,Ý�ŠÐOÑPÔPÐPØˆtrQ   c                óx   — |                       ¦   «         }|�	||_        dS t                               d¦  «         dS )zN
        Sets the chunk size of the SpladePooling module, if present.
        Nz6SpladePooling module not found. Cannot set chunk_size.rS  )rM   r³   rU  s      rP   rV  z'SparseEncoder.splade_pooling_chunk_sizer  sB   € ð
 ×1Ò1Ñ3Ô3ˆØÐ%Ø(-ˆNÔ%Ð%Ð%å�NŠNÐSÑTÔTÐTÐTÐTrQ   Úembeddings_1Úembeddings_2c                ó  ‡ — ‰ j         s‰                      ¦   «         Š |j         s|                     ¦   «         }‰ j        dk    rt          d‰ j        › d�¦  «        ‚‰ j        d         |j        d         k    r,t          d‰ j        d         › d|j        d         › d�¦  «        ‚|j        dk    r‰ |z  }nD|j        dk    r!t          j        ˆ fd	„|D ¦   «         ¦  «        }nt          d
|j        › d�¦  «        ‚|                     ¦   «         }|                     ¦   «         dk    }t          j	        | 
                    ¦   «         dd…|f         |                     ¦   «         |         |                     ¦   «         |j        ¬¦  «        }|S )aÇ  
        Compute the intersection of two sparse embeddings via element-wise multiplication.

        For each dimension, the result retains the minimum contribution from both embeddings, keeping only
        dimensions where both inputs are positive (i.e., shared active dimensions). This is useful for
        token-level matching and interpretability when combined with :meth:`decode`.

        Args:
            embeddings_1 (torch.Tensor): First embedding tensor of shape ``(vocab_size,)``.
            embeddings_2 (torch.Tensor): Second embedding tensor of shape ``(vocab_size,)`` or
                ``(batch_size, vocab_size)``.

        Returns:
            torch.Tensor: Sparse intersection tensor with the same shape as ``embeddings_2``.

        Example:
            ::

                from sentence_transformers import SparseEncoder

                model = SparseEncoder("naver/splade-cocondenser-ensembledistil")
                query_emb = model.encode_query("What is AI?")
                doc_emb = model.encode_document("Artificial intelligence is a branch of computer science.")
                shared = model.intersection(query_emb, doc_emb)
                print(model.decode(shared, top_k=5))
        rÐ   z-Expected 1D tensor for embeddings_1, but got z shape.r9  z+Vocab dimension mismatch: embeddings_1 has z, embeddings_2 has rE   r,  c                ó   •— g | ]}‰|z  ‘ŒS rh   rh   )ru   Ú	embeddingrX  s     €rP   rw   z.SparseEncoder.intersection.<locals>.<listcomp>®  s   ø€ Ð'_Ð'_Ð'_ÀY¨°yÑ(@Ð'_Ð'_Ð'_rQ   z3Expected 1D or 2D tensor for embeddings_2, but got r   N)Úsizer*   )Ú	is_sparser˜   r;  rH   r=  r(   rœ   ÚcoalescerJ   Úsparse_coo_tensorÚindicesr]  r*   )rX  rY  Úintersectionr7  s   `   rP   rb  zSparseEncoder.intersection}  sÅ  ø€ ð> Ô%ð 	4Ø'×1Ò1Ñ3Ô3ˆLØÔ%ð 	4Ø'×1Ò1Ñ3Ô3ˆLàÔ Ò!Ð!ÝÐhÈ\ÔM_ÐhÐhÐhÑiÔiÐiàÔ˜bÔ! \Ô%7¸Ô%;Ò;Ð;Ýð>¸lÔ>PÐQSÔ>Tð >ð >Ø$0Ô$6°rÔ$:ð>ð >ð >ñô ð ð
 Ô Ò!Ð!Ø'¨,Ñ6ˆLˆLØÔ !Ò#Ð#å œ;Ð'_Ð'_Ð'_Ð'_ÐR^Ð'_Ñ'_Ô'_Ñ`Ô`ˆLˆLåÐnÐS_ÔSeÐnÐnÐnÑoÔoÐoð $×,Ò,Ñ.Ô.ˆØ"×)Ò)Ñ+Ô+¨aÒ/ˆÝÔ.Ø× Ò Ñ"Ô" 1 1 1 k >Ô2Ø×ÒÑ!Ô! +Ô.Ø×"Ò"Ñ$Ô$ØÔ&ð	
ñ 
ô 
ˆð ÐrQ   Útop_kú7list[tuple[str, float]] | list[list[tuple[str, float]]]c           
     ó`  — |�|dk    rt          d|› d�¦  «        ‚t          |t          j        ¦  «        st	          dt          |¦  «        › �¦  «        ‚|j        dk    }|r|                     d¦  «        }n#|j        dk    rt          d|j        › d	�¦  «        ‚|j        s| 	                    ¦   «         }| 
                    ¦   «         }|                     ¦   «         }|                     ¦   «         }|                     ¦   «         dk    r8d
„ t          |                     d¦  «        ¦  «        D ¦   «         }|r|d         n|S |d         |d         }}t          j        ||                     d¦  «        ¬¦  «                             ¦   «         }	g }d}
|	D �]}|dk    r|                     g ¦  «         Œ||
|
|z   …         }||
|
|z   …         }|�t'          ||¦  «        n|}||k     r#t          j        ||¦  «        \  }}||         }|}n&t          j        |d¬¦  «        }||         }||         }| j                             |                     ¦   «         ¦  «        }|                     t1          t3          ||                     ¦   «         ¦  «        ¦  «        ¦  «         |
|z  }
�Œ|r|d         n|S )aû  
        Decode a sparse embedding into (token, weight) pairs sorted by descending weight.

        Args:
            embeddings (torch.Tensor): Sparse embedding tensor of shape ``(vocab_size,)``
                for a single embedding or ``(batch_size, vocab_size)`` for a batch.
            top_k (int, optional): Maximum number of top-weighted tokens to return per sample.
                If ``None``, all non-zero tokens are returned. Must be positive. Defaults to ``None``.

        Returns:
            list[tuple[str, float]] | list[list[tuple[str, float]]]:
                If the input is 1D, a list of ``(token, weight)`` tuples.
                If the input is 2D, a list (one per sample)
                of lists of ``(token, weight)`` tuples.
        Nr   z&top_k must be a positive integer, got rE   zExpected torch.Tensor, got rÐ   r,  z#Input tensor must be 1D or 2D, got r6  c                ó   — g | ]}g ‘ŒS rh   rh   )ru   rÔ   s     rP   rw   z(SparseEncoder.decode.<locals>.<listcomp>æ  s   € Ð5\Ð5\Ð5\¸Q°bÐ5\Ð5\Ð5\rQ   )Ú	minlengthT)Ú
descending)rH   rK   r(   r	   r:  rø   r;  r<  r^  r˜   r_  ra  rJ   Únumelrâ   r]  Úbincountr‰   r0  rÞ   Útopkr“   Ú	tokenizerÚconvert_ids_to_tokensr†   Úzip)rM   rž   rc  Úwas_1dra  rJ   ÚresultsÚsample_indicesÚtoken_indicesÚsample_countsÚ	start_idxÚcountÚsample_valuesÚsample_tokensÚeffective_kÚ
top_valuesÚtop_idxÚ
sorted_idxÚ
token_strss                      rP   ÚdecodezSparseEncoder.decode¾  sÔ  € ð$ Ð ¨!¢ ÝÐNÀeÐNÐNÐNÑOÔOÐOå˜*¥e¤lÑ3Ô3ð 	NÝÐL½$¸zÑ:JÔ:JÐLÐLÑMÔMÐMð ” AÒ%ˆØð 	XØ#×-Ò-¨aÑ0Ô0ˆJˆJØŒ_ Ò!Ð!ÝÐVÀ:Ä?ÐVÐVÐVÑWÔWÐWð Ô#ð 	0Ø#×-Ò-Ñ/Ô/ˆJà×(Ò(Ñ*Ô*ˆ
Ø×$Ò$Ñ&Ô&ˆØ×"Ò"Ñ$Ô$ˆà�<Š<‰>Œ>˜QÒÐØ5\Ð5\Å%È
ÏÊÐXYÑHZÔHZÑB[ÔB[Ð5\Ñ5\Ô5\ˆGØ!'Ð4�7˜1”:�:¨WÐ4à(/°¬
°G¸A´J˜ˆÝœ ~ÀÇÂÐQRÑASÔASÐTÑTÔT×[Ò[Ñ]Ô]ˆàˆØˆ	Ø"ð 	ñ 	ˆEØ˜ŠzˆzØ—’˜rÑ"Ô"Ð"Øà" 9¨y¸5Ñ/@Ð#@ÔAˆMØ)¨)°iÀ%Ñ6GÐ*GÔHˆMà/4Ð/@�#˜e UÑ+Ô+Ð+ÀeˆKØ˜UÒ"Ð"Ý&+¤j°ÀÑ&LÔ&LÑ#�
˜GØ -¨gÔ 6�Ø *��å"œ]¨=ÀTÐJÑJÔJ�
Ø -¨jÔ 9�Ø -¨jÔ 9�àœ×=Ò=¸m×>RÒ>RÑ>TÔ>TÑUÔUˆJØ�NŠN�4¥ J°×0DÒ0DÑ0FÔ0FÑ GÔ GÑHÔHÑIÔIÐIà˜ÑˆI‰Ià#Ð0ˆw�qŒzˆz¨Ð0rQ   Úrepo_idc           	     ó`   — | j         j        }|                      ¦   «         }d|› d|› d|› d|› d�	S )Nz·## Testing this pull request
You can test this pull request before merging by loading the model from this PR with the `revision` argument:
```python
from sentence_transformers import zO

# NOTE: Update this to the number of your pull request
pr_number = 2
model = z(
    "z5",
    revision=f"refs/pr/{pr_number}",
    backend="aÏ  ",
)

# Verify that everything works as expected
embeddings = model.encode(["The weather is lovely today.", "It's so sunny outside!", "He drove to the stadium."])
print(embeddings.shape)

similarities = model.similarity(embeddings, embeddings)
print(similarities)
```

---
*This PR was auto-generated with [`push_to_hub`](https://sbert.net/docs/package_reference/sparse_encoder/SparseEncoder.html#sentence_transformers.sparse_encoder.SparseEncoder.push_to_hub).*
)rO   rŒ   Úget_backend)rM   r~  Ú
class_namer5   s       rP   Ú_push_to_hub_usage_tipz$SparseEncoder._push_to_hub_usage_tip  sh   € Ø”^Ô,ˆ
Ø×"Ò"Ñ$Ô$ˆðð $.ð	ð ð 
ðð ð ðð ð ðð ð ð 	rQ   r¶   )$r8   r   r)   r9   r*   r   r+   r:   r,   r   r-   r   r.   r;   r/   r   r0   r;   r1   r<   r2   r=   r&   r=   r3   r=   r4   r>   r5   r?   r6   r@   r7   rA   rB   rC   )NNrT   NTTFNNNN)rR   rU   rV   r   rW   r   rX   rY   rZ   r[   r\   r;   r]   r;   r^   r;   r*   r_   r7   rA   r`   ra   rb   rA   rc   r   rB   rd   )rB   r¥   )r«   r¥   rB   rC   )rB   r¯   )r³   r´   rB   rC   )r¼   r;   rB   rC   )r¿   r	   rÀ   r	   rB   r	   )r¿   rÄ   rÀ   rÄ   rB   r	   )rB   rÆ   )TNNN)rR   rÌ   rZ   r[   r`   ra   r*   r_   rb   rA   rB   rd   )
rô   r$   rõ   r   rî   r   rö   r   rB   rC   )rB   rA   )NFFNNN)r8   r$   r1   r<   r-   r   r/   r   r.   r;   r0   r;   r2   r=   r&   r=   r3   r=   rB   r
  )NFFNNNN)r8   r$   r1   r<   r-   r   r/   r   r.   r;   r0   r;   r2   r=   r&   r=   r3   r=   r%   r   rB   r
  )rž   r3  rB   r4  )rB   rY   )r³   rY   rB   rC   )rB   rL  )rB   rO  )r³   rA   rB   rC   )rX  r3  rY  r3  rB   r	   )rž   r3  rc  rA   rB   rd  )r~  r$   rB   r$   )+rŒ   Ú
__module__Ú__qualname__Ú__doc__r   Úmodel_card_data_classr   Ú__annotations__r"   Ú _model_card_model_id_placeholderr%   r   rG   rk   rp   rj   r¨   r­   Úpropertyr6   Úsetterr¾   r   rÃ   rÉ   rŽ   Ústaticmethodrý   rÿ   r   ÚFutureWarningr   r)  r2  rH  rJ  rN  rQ  rV  rb  r}  r‚  Ú__classcell__)rO   s   @rP   r   r   #   sŸ  ø€ € € € € € ðcð cðJ 7ÐØ3CÐ$ÐCÐCÐCÑCØ8<È$Ð.OÐ.OÐÐOÐOÐOÑOØ'@Ð$Ø%€JÐ%Ð%Ð%Ñ%àÐÐ(:Ð;Ñ;Ô;ð *.ð4ð +/Ø!Ø)-Ø*.Ø#'Ø"'Ø#Ø!&Ø#'Ø.2Ø26Ø/3Ø=AØ8?à>BØ&*ð)4ð 4ð 4ð 4ð 4ð 4ð 4ñ <Ô;ð4ðl Ð Ð*Ñ*Ô*ð #'Ø!ØØ)-Ø"&Ø)-Ø!ØGKØ&*ØJNØ!%ðF
ð F
ð F
ð F
ñ +Ô*ðF
ðP Ð Ð*Ñ*Ô*ð #'Ø!ØØ)-Ø"&Ø)-Ø!ØGKØ&*ØJNØ!%ðI
ð I
ð I
ð I
ñ +Ô*ðI
ðV Ð Ð*Ñ*Ô*ð #'Ø!ØØ)-Ø"&Ø)-Ø!ØGKØ&*ØJNØ!%ðTð Tð Tð Tñ +Ô*ðTðl
ð 
ð 
ð 
ð 
ð 
ð
Sð Sð Sð Sð Sð Sð
 ð(ð (ð (ñ „Xð(ð  Ôð
\ð 
\ð 
\ñ Ôð
\ð
ð 
ð 
ð 
ð ØQÐQÐQñ „XØQàØsÐsÐsñ „XØsàð) ð ) ð ) ñ „Xð) ðV ØZÐZÐZñ „XØZàðð ð ñ „Xðð ð$)ð $)ð $)ñ „Xð$)ðR *.ØJNØGKØ!%ð>3ð >3ð >3ð >3ð >3ð@ ðð ð ñ „\ðð2ð ð ð ð2 €ZØfØðñ ô ð.ð .ð .ñ	ô ð.ð  $Ø"'Ø!&Ø.2Ø26Ø/3ðWð Wð Wð Wð Wð|  $Ø"'Ø!&Ø.2Ø26Ø/3Ø!%ðJ+ð J+ð J+ð J+ð J+ðX ð:
ð :
ð :
ñ „\ð:
ðx ð&ð &ð &ð &ð &ñ „Xð&ð$ Ôð'ð 'ð 'ñ Ôð'ð ð*ð *ð *ð *ð *ñ „Xð*ð.ð ð ð ð ðð ð ñ „Xðð( Ô%ðUð Uð Uñ &Ô%ðUð ð>ð >ð >ñ „\ð>ðB =AðG1ð G1ð G1ð G1ð G1ðRð ð ð ð ð ð ð rQ   r   )8Ú
__future__r   ræ   r   rß   rù   Úcollections.abcr   Úmultiprocessingr   Útypingr   r   r   Únumpyr‡   Únumpy.typingÚnptr(   r	   r
   Útqdmr   Útransformersr   r   Útransformers.modeling_utilsr   Útransformers.utilsÚtransformers_loggingÚtyping_extensionsr   Úsentence_transformers.baser   Ú)sentence_transformers.base.modality_typesr   Ú"sentence_transformers.base.modulesr   Ú2sentence_transformers.sentence_transformer.modulesr   Ú/sentence_transformers.sparse_encoder.model_cardr   Ú,sentence_transformers.sparse_encoder.modulesr   r   Úsentence_transformers.utilr   r   Ú%sentence_transformers.util.decoratorsr   Ú%sentence_transformers.util.similarityr   Ú
get_loggerrŒ   r�   r   rh   rQ   rP   ú<module>r¥     s   ðØ "Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ø €€€Ø €€€Ø €€€Ø $Ð $Ð $Ð $Ð $Ð $Ø !Ð !Ð !Ð !Ð !Ð !Ø )Ð )Ð )Ð )Ð )Ð )Ð )Ð )Ð )Ð )à Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø €€€Ø Ð Ð Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ø 7Ð 7Ð 7Ð 7Ð 7Ð 7Ø >Ð >Ð >Ð >Ð >Ð >Ø (Ð (Ð (Ð (Ð (Ð (à 0Ð 0Ð 0Ð 0Ð 0Ð 0Ø ?Ð ?Ð ?Ð ?Ð ?Ð ?Ø :Ð :Ð :Ð :Ð :Ð :Ø FÐ FÐ FÐ FÐ FÐ FØ VÐ VÐ VÐ VÐ VÐ VØ YÐ YÐ YÐ YÐ YÐ YÐ YÐ YØ NÐ NÐ NÐ NÐ NÐ NÐ NÐ NØ CÐ CÐ CÐ CÐ CÐ CØ DÐ DÐ DÐ DÐ DÐ Dð 
)Ð	Ô	(¨Ñ	2Ô	2€ð@ð @ð @ð @ð @�Iñ @ô @ð @ð @ð @rQ   