o
    Uhf                     @  st   d dl mZ dd Zdd ZG dd dZG dd	 d	ZG d
d dZG dd dZG dd dZG dd dZ	dS )    )annotationsc           
      C  sD  | sg S t | d dkrt| || jS g }| D ]?}|\}}}||ks(||kr.d}t|||kr<|dkr<d}t|||krJ|dkrJd}t||dkrOq|t||| qtt |d D ]>}	||	d  j||	 jk s{||	d  j	||	 j	k rd}t|||	d  j||	 jkr||	d  j	||	 j	krd	}t|qa|S )
Nr      List of edit operations invalidinsertdeleteequal   z$List of edit operations out of orderzDuplicated edit operation)
lenOpcodes
as_editops_editops
ValueErrorappendEditoprangesrc_posdest_pos)
opssrc_lendest_lenblocksop	edit_typer   r   msgi r   u/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/rapidfuzz/distance/_initialize_py.py_list_to_editops   s8   
00r   c              	   C  s  | r
t | d dkrt| || jS g }| D ]}|\}}}}}	||ks(|	|kr.d}
t|
||k s6|	|k r<d}
t|
|dv rR|| |	| ksL||krRd}
t|
|dkrd||ks^||	krdd}
t|
|dkrv||ksp||	krvd}
t|
|r|d j|kr|d j|kr|d j|kr||d _|	|d _q|t	|||||	 q|d j
dks|d jdkrd}
t|
|d j|ks|d j|krd	}
t|
tt |d
 D ] }||d
  j
|| jks||d
  j|| jkrd}
t|
q|S )Nr      r   >   r   replacer   r   z4List of edit operations does not start at position 0z7List of edit operations does not end at the string endsr   z)List of edit operations is not continuous)r	   Editops
as_opcodes_opcodesr   tagsrc_enddest_endr   Opcode	src_start
dest_startr   )r   r   r   r   r   r   r(   r%   r)   r&   r   r   r   r   r   _list_to_opcodes2   sL    *

0r*   c                   @  @   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )MatchingBlockz1
    Triple describing matching subsequences
    c                 C     || _ || _|| _d S Nabsize)selfr0   r1   r2   r   r   r   __init__m      
zMatchingBlock.__init__c                 C     dS Nr   r   r3   r   r   r   __len__r      zMatchingBlock.__len__c                 C  X   z!t |dkr
W dS t|d | jko|d | jko|d | jkW S  ty+   Y dS w Nr   Fr   r      )r	   boolr0   r1   r2   	TypeErrorr3   otherr   r   r   __eq__u      0zMatchingBlock.__eq__c                 C  6   |dv r| j S |dv r| jS |dv r| jS d}t|)N   r      r      r=   r    z MatchingBlock index out of range)r0   r1   r2   
IndexErrorr3   r   r   r   r   r   __getitem__~      zMatchingBlock.__getitem__c                 c      t dD ]}| | V  qd S r7   r   r3   r   r   r   r   __iter__      zMatchingBlock.__iter__c                 C  s   d| j  d| j d| j dS )NzMatchingBlock(a=z, b=z, size=)r/   r8   r   r   r   __repr__      zMatchingBlock.__repr__N
__name__
__module____qualname____doc__r4   r9   rB   rL   rQ   rT   r   r   r   r   r,   h   s    	r,   c                   @  r+   )r   a  
    Tuple like object describing an edit operation.
    It is in the form (tag, src_pos, dest_pos)

    The tags are strings, with these meanings:

    +-----------+---------------------------------------------------+
    | tag       | explanation                                       |
    +===========+===================================================+
    | 'replace' | src[src_pos] should be replaced by dest[dest_pos] |
    +-----------+---------------------------------------------------+
    | 'delete'  | src[src_pos] should be deleted                    |
    +-----------+---------------------------------------------------+
    | 'insert'  | dest[dest_pos] should be inserted at src[src_pos] |
    +-----------+---------------------------------------------------+
    c                 C  r-   r.   r$   r   r   )r3   r$   r   r   r   r   r   r4      r5   zEditop.__init__c                 C  r6   r7   r   r8   r   r   r   r9      r:   zEditop.__len__c                 C  r;   r<   )r	   r>   r$   r   r   r?   r@   r   r   r   rB      rC   zEditop.__eq__c                 C  rD   )NrE   rG   rI   zEditop index out of range)r$   r   r   rJ   rK   r   r   r   rL      rM   zEditop.__getitem__c                 c  rN   r7   rO   rP   r   r   r   rQ      rR   zEditop.__iter__c                 C  s   d| j d| j d| j dS )NzEditop(tag=z
, src_pos=z, dest_pos=rS   r[   r8   r   r   r   rT      rU   zEditop.__repr__NrV   r   r   r   r   r      s    	r   c                   @  s   e Zd ZdZ			d(ddZedd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zedd Zejdd Zedd Zejdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' ZdS ))r!   zH
    List like object of Editops describing how to turn s1 into s2.
    Nr   c                 C     || _ || _t|||| _d S r.   )_src_len	_dest_lenr   r   )r3   editopsr   r   r   r   r   r4         zEditops.__init__c                 C     |  S )z
        Create Editops from Opcodes

        Parameters
        ----------
        opcodes : Opcodes
            opcodes to convert to editops

        Returns
        -------
        editops : Editops
            Opcodes converted to Editops
        )r   )clsopcodesr   r   r   from_opcodes      zEditops.from_opcodesc           	   	   C  s  t t }| j|_| j|_g }d}d}d}|t| jk r|| j| jk s,|| j| jk rK|t	d|| j| j|| j| j | j| j}| j| j}|}|}| j| j
}|t| jk r| j| j
|kr|| j| jkr|| j| jkr|dkr|d7 }|d7 }n|dkr|d7 }n|dkr|d7 }|d7 }|t| jk r| j| j
|kr|| j| jkr|| j| jkst|t	||||| |t| jk s|| jk s|| jk r|t	d|| j|| j ||_|S )z
        Convert to Opcodes

        Returns
        -------
        opcodes : Opcodes
            Editops converted to Opcodes
        r   r   r   r   r   r   )r
   __new__r]   r^   r	   r   r   r   r   r'   r$   r   r   r#   )	r3   xr   r   r   r   	src_begin
dest_beginr$   r   r   r   r"      sZ   
	 

	

#zEditops.as_opcodesc                 C  s  g }d}d}| D ]K}||j k s||jk r2t|j | |j| }|dkr,|t||| |j }|j}|jdkr@|d7 }|d7 }q|jdkrJ|d7 }q|jdkrS|d7 }q|| jk s^|| jk rvt| j| | j| }|dkrv|t||| |t| j| jd |S )z
        Convert to matching blocks

        Returns
        -------
        matching blocks : list[MatchingBlock]
            Editops converted to matching blocks
        r   r   r   r   r   )r   r   minr   r,   r$   r   r   )r3   r   r   r   r   lengthr   r   r   as_matching_blocks   s0   	




zEditops.as_matching_blocksc                 C     dd | j D S )zr
        Convert Editops to a list of tuples.

        This is the equivalent of ``[x for x in editops]``
        c                 S     g | ]}t |qS r   tuple.0r   r   r   r   
<listcomp>J      z#Editops.as_list.<locals>.<listcomp>r   r8   r   r   r   as_listD  s   zEditops.as_listc                 C  .   t t }| j|_| j|_| jdd |_|S )z*
        performs copy of Editops
        N)r!   rf   r]   r^   r   r3   rg   r   r   r   copyL  
   
zEditops.copyc                 C  sh   g }| D ]}|j }|dkrd}n|dkrd}|t||j|j qtt}| j|_| j	|_
||_|S )a  
        Invert Editops, so it describes how to transform the destination string to
        the source string.

        Returns
        -------
        editops : Editops
            inverted Editops

        Examples
        --------
        >>> from rapidfuzz.distance import Levenshtein
        >>> Levenshtein.editops('spam', 'park')
        [Editop(tag=delete, src_pos=0, dest_pos=0),
         Editop(tag=replace, src_pos=3, dest_pos=2),
         Editop(tag=insert, src_pos=4, dest_pos=3)]

        >>> Levenshtein.editops('spam', 'park').inverse()
        [Editop(tag=insert, src_pos=0, dest_pos=0),
         Editop(tag=replace, src_pos=2, dest_pos=3),
         Editop(tag=delete, src_pos=3, dest_pos=4)]
        r   r   )r$   r   r   r   r   r!   rf   r   r]   r   r^   r   r3   r   r   r$   rg   r   r   r   inverseV  s   
zEditops.inversec                 C  sZ  t t }| j|_| j|_t|t| krd}t|dgt| t|  |_d}d}d}|D ]W}|t| krc|| j| krc| j| ||< ||  j|7  _|d7 }|d7 }|t| krc|| j| ks>|t| krod}t||jdkry|d7 }n	|jdkr|d8 }|d7 }q/|t| kr| j| ||< ||  j|7  _|d7 }|d7 }|t| ks|S )a#  
        remove a subsequence

        Parameters
        ----------
        subsequence : Editops
            subsequence to remove (has to be a subset of editops)

        Returns
        -------
        sequence : Editops
            a copy of the editops without the subsequence
        z subsequence is not a subsequenceNr   r   r   r   )	r!   rf   r]   r^   r	   r   r   r   r$   )r3   subsequenceresultr   offsetop_pos
result_possopr   r   r   remove_subsequence}  s@   




zEditops.remove_subsequencec                 C  s   d}d}| j D ]=}||jk r||| 7 }|d7 }||jk s|jdkr.|||j 7 }|d7 }q|jdkr;|||j 7 }q|jdkrD|d7 }q|t|k r[||| 7 }|d7 }|t|k sK|S )at  
        apply editops to source_string

        Parameters
        ----------
        source_string : str | bytes
            string to apply editops to
        destination_string : str | bytes
            string to use for replacements / insertions into source_string

        Returns
        -------
        mod_string : str
            modified source_string

         r   r   r   r   r   )r   r   r$   r   r	   )r3   source_stringdestination_stringres_strr   r   r   r   r   apply  s(   






zEditops.applyc                 C     | j S r.   r]   r8   r   r   r   r        zEditops.src_lenc                 C  
   || _ d S r.   r   r3   valuer   r   r   r        
c                 C  r   r.   r^   r8   r   r   r   r     r   zEditops.dest_lenc                 C  r   r.   r   r   r   r   r   r     r   c                 C  2   t |tsdS | j|jko| j|jko| j|jkS NF)
isinstancer!   r   r   r   r@   r   r   r   rB        
$zEditops.__eq__c                 C  
   t | jS r.   )r	   r   r8   r   r   r   r9        
zEditops.__len__c                 C  s   | j |= d S r.   ru   )r3   keyr   r   r   __delitem__  s   zEditops.__delitem__c                 C  sn   t |tr
| j| S |t| j\}}}|dk rd}t|tt}| j|_| j	|_	| j||| |_|S )Nr   z6step sizes below 0 lead to an invalid order of editops)
r   intr   indicesr	   r   r!   rf   r]   r^   )r3   r   startstopstepr   rg   r   r   r   rL     s   


zEditops.__getitem__c                 c      | j E d H  d S r.   ru   r8   r   r   r   rQ   
     zEditops.__iter__c                 C  .   dd dd | D  d| j d| j d S )Nz	Editops([, c                 s      | ]}t |V  qd S r.   reprrq   r   r   r   	<genexpr>      z#Editops.__repr__.<locals>.<genexpr>], src_len=, dest_len=rS   joinr   r   r8   r   r   r   rT        ,zEditops.__repr__Nr   r   )rW   rX   rY   rZ   r4   classmethodrd   r"   rl   rv   ry   r|   r   r   propertyr   setterr   rB   r9   r   rL   rQ   rT   r   r   r   r   r!      s:    


9$
'9)



r!   c                   @  r+   )r'   ai  
    Tuple like object describing an edit operation.
    It is in the form (tag, src_start, src_end, dest_start, dest_end)

    The tags are strings, with these meanings:

    +-----------+-----------------------------------------------------+
    | tag       | explanation                                         |
    +===========+=====================================================+
    | 'replace' | src[src_start:src_end] should be                    |
    |           | replaced by dest[dest_start:dest_end]               |
    +-----------+-----------------------------------------------------+
    | 'delete'  | src[src_start:src_end] should be deleted.           |
    |           | Note that dest_start==dest_end in this case.        |
    +-----------+-----------------------------------------------------+
    | 'insert'  | dest[dest_start:dest_end] should be inserted        |
    |           | at src[src_start:src_start].                        |
    |           | Note that src_start==src_end in this case.          |
    +-----------+-----------------------------------------------------+
    | 'equal'   | src[src_start:src_end] == dest[dest_start:dest_end] |
    +-----------+-----------------------------------------------------+

    Note
    ----
    Opcode is compatible with the tuples returned by difflib's SequenceMatcher to make them
    interoperable
    c                 C  "   || _ || _|| _|| _|| _d S r.   r$   r(   r%   r)   r&   )r3   r$   r(   r%   r)   r&   r   r   r   r4   0  s
   
zOpcode.__init__c                 C  r6   Nr   r   r8   r   r   r   r9   7  r:   zOpcode.__len__c                 C  t   z/t |dkr
W dS t|d | jko-|d | jko-|d | jko-|d | jko-|d | jkW S  ty9   Y dS w Nr   Fr   r   r=   r      )r	   r>   r$   r(   r%   r)   r&   r?   r@   r   r   r   rB   :      zOpcode.__eq__c                 C  R   |dv r| j S |dv r| jS |dv r| jS |dv r| jS |dv r#| jS d}t|N>   r   >   r   >   r=   rF   >   r   rH   >   r   r    zOpcode index out of range)r$   r(   r%   r)   r&   rJ   rK   r   r   r   rL   I     zOpcode.__getitem__c                 c  rN   r   rO   rP   r   r   r   rQ   X  rR   zOpcode.__iter__c                 C  s.   d| j d| j d| j d| j d| j dS )NzOpcode(tag=, src_start=
, src_end=, dest_start=, dest_end=rS   r   r8   r   r   r   rT   \  s   zOpcode.__repr__NrV   r   r   r   r   r'     s    r'   c                   @  s   e Zd ZdZ			d$ddZedd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zedd Zejdd Zedd Zejdd Zdd Zdd Zdd Zd d! Zd"d# ZdS )%r
   a  
    List like object of Opcodes describing how to turn s1 into s2.
    The first Opcode has src_start == dest_start == 0, and remaining tuples
    have src_start == the src_end from the tuple preceding it,
    and likewise for dest_start == the previous dest_end.
    Nr   c                 C  r\   r.   )r]   r^   r*   r#   )r3   rc   r   r   r   r   r   r4   k  r`   zOpcodes.__init__c                 C  ra   )z
        Create Opcodes from Editops

        Parameters
        ----------
        editops : Editops
            editops to convert to opcodes

        Returns
        -------
        opcodes : Opcodes
            Editops converted to Opcodes
        )r"   )rb   r_   r   r   r   from_editopsu  re   zOpcodes.from_editopsc              	   C  s   t t }| j|_| j|_g }| D ]]}|jdkr3t|j|j D ]}|t	d|j| |j
|  q q|jdkrQt|j|j
 D ]}|t	d|j|j
|  q@q|jdkrnt|j|j D ]}|t	d|j| |j
 q^q||_|S )z
        Convert Opcodes to Editops

        Returns
        -------
        editops : Editops
            Opcodes converted to Editops
        r   r   r   )r!   rf   r]   r^   r$   r   r%   r(   r   r   r)   r&   r   )r3   rg   r   r   jr   r   r   r     s&   
	
 

zOpcodes.as_editopsc                 C  sj   g }| D ]#}|j dkr't|j|j |j|j }|dkr'|t|j|j| q|t| j| j	d |S )z
        Convert to matching blocks

        Returns
        -------
        matching blocks : list[MatchingBlock]
            Opcodes converted to matching blocks
        r   r   )
r$   rj   r%   r(   r&   r)   r   r,   r   r   )r3   r   r   rk   r   r   r   rl     s   	
zOpcodes.as_matching_blocksc                 C  rm   )z
        Convert Opcodes to a list of tuples, which is compatible
        with the opcodes of difflibs SequenceMatcher.

        This is the equivalent of ``[x for x in opcodes]``
        c                 S  rn   r   ro   rq   r   r   r   rs     rt   z#Opcodes.as_list.<locals>.<listcomp>r#   r8   r   r   r   rv     s   zOpcodes.as_listc                 C  rw   )z*
        performs copy of Opcodes
        N)r
   rf   r]   r^   r#   rx   r   r   r   ry     rz   zOpcodes.copyc              	   C  sp   g }| D ]!}|j }|dkrd}n|dkrd}|t||j|j|j|j qtt}| j	|_
| j|_||_|S )a  
        Invert Opcodes, so it describes how to transform the destination string to
        the source string.

        Returns
        -------
        opcodes : Opcodes
            inverted Opcodes

        Examples
        --------
        >>> from rapidfuzz.distance import Levenshtein
        >>> Levenshtein.opcodes('spam', 'park')
        [Opcode(tag=delete, src_start=0, src_end=1, dest_start=0, dest_end=0),
         Opcode(tag=equal, src_start=1, src_end=3, dest_start=0, dest_end=2),
         Opcode(tag=replace, src_start=3, src_end=4, dest_start=2, dest_end=3),
         Opcode(tag=insert, src_start=4, src_end=4, dest_start=3, dest_end=4)]

        >>> Levenshtein.opcodes('spam', 'park').inverse()
        [Opcode(tag=insert, src_start=0, src_end=0, dest_start=0, dest_end=1),
         Opcode(tag=equal, src_start=0, src_end=2, dest_start=1, dest_end=3),
         Opcode(tag=replace, src_start=2, src_end=3, dest_start=3, dest_end=4),
         Opcode(tag=delete, src_start=3, src_end=4, dest_start=4, dest_end=4)]
        r   r   )r$   r   r'   r)   r&   r(   r%   r
   rf   r   r]   r   r^   r#   r{   r   r   r   r|     s    
zOpcodes.inversec                 C  sR   d}| j D ]!}|jdkr|||j|j 7 }q|jdv r&|||j|j 7 }q|S )at  
        apply opcodes to source_string

        Parameters
        ----------
        source_string : str | bytes
            string to apply opcodes to
        destination_string : str | bytes
            string to use for replacements / insertions into source_string

        Returns
        -------
        mod_string : str
            modified source_string

        r   r   >   r   r   )r#   r$   r(   r%   r)   r&   )r3   r   r   r   r   r   r   r   r     s   


zOpcodes.applyc                 C  r   r.   r   r8   r   r   r   r     r   zOpcodes.src_lenc                 C  r   r.   r   r   r   r   r   r     r   c                 C  r   r.   r   r8   r   r   r   r     r   zOpcodes.dest_lenc                 C  r   r.   r   r   r   r   r   r     r   c                 C  r   r   )r   r
   r   r   r#   r@   r   r   r   rB     r   zOpcodes.__eq__c                 C  r   r.   )r	   r#   r8   r   r   r   r9   !  r   zOpcodes.__len__c                 C  s    t |tr
| j| S d}t|)NzExpected index)r   r   r#   r?   )r3   r   r   r   r   r   rL   $  s   

zOpcodes.__getitem__c                 c  r   r.   r   r8   r   r   r   rQ   +  r   zOpcodes.__iter__c                 C  r   )Nz	Opcodes([r   c                 s  r   r.   r   rq   r   r   r   r   0  r   z#Opcodes.__repr__.<locals>.<genexpr>r   r   rS   r   r8   r   r   r   rT   .  r   zOpcodes.__repr__r   )rW   rX   rY   rZ   r4   r   r   r   rl   rv   ry   r|   r   r   r   r   r   rB   r9   rL   rQ   rT   r   r   r   r   r
   c  s6    	


	
)



r
   c                   @  r+   )ScoreAlignmentz
    Tuple like object describing the position of the compared strings in
    src and dest.

    It indicates that the score has been calculated between
    src[src_start:src_end] and dest[dest_start:dest_end]
    c                 C  r   r.   scorer(   r%   r)   r&   )r3   r   r(   r%   r)   r&   r   r   r   r4   =  s
   
zScoreAlignment.__init__c                 C  r6   r   r   r8   r   r   r   r9   K  r:   zScoreAlignment.__len__c                 C  r   r   )r	   r>   r   r(   r%   r)   r&   r?   r@   r   r   r   rB   N  r   zScoreAlignment.__eq__c                 C  r   r   )r   r(   r%   r)   r&   rJ   rK   r   r   r   rL   ]  r   zScoreAlignment.__getitem__c                 c  rN   r   rO   rP   r   r   r   rQ   l  rR   zScoreAlignment.__iter__c                 C  s.   d| j  d| j d| j d| j d| j dS )NzScoreAlignment(score=r   r   r   r   rS   r   r8   r   r   r   rT   p  s   zScoreAlignment.__repr__NrV   r   r   r   r   r   4  s    r   N)

__future__r   r   r*   r,   r   r!   r'   r
   r   r   r   r   r   <module>   s   ,6)6  NP R