+
    ʇi,                        ^ RI Ht ^ RIHtHt ^ RIHtHt ^ RIH	t	H
t
 RRRR/R ltRR	 ltRRRR/R
 ltRRRR/R ltRRRR/R ltR tRR/R ltRR/R ltR# )    )annotations)common_affixconv_sequences)is_nonesetupPandas)EditopEditops	processorNscore_cutoffc                  Ve   V! V 4      p V! V4      pV '       g   ^ # \        W4      w  r^\        V 4      ,          ^,
          p/ pVP                  p^pV  F  pV! V^ 4      V,          WX&   V^,          pK   	  V F)  p	V! V	^ 4      p
WJ,          pWK,           WK,
          ,          pK+  	  \        V4      \        V 4      ) R P	                  R4      pVe   W8  d   V# ^ # )a  
Calculates the length of the longest common subsequence

Parameters
----------
s1 : Sequence[Hashable]
    First string to compare.
s2 : Sequence[Hashable]
    Second string to compare.
processor: callable, optional
    Optional callable that is used to preprocess the strings before
    comparing them. Default is None, which deactivates this behaviour.
score_cutoff : int, optional
    Maximum distance between s1 and s2, that is
    considered as a result. If the similarity is smaller than score_cutoff,
    0 is returned instead. Default is None, which deactivates
    this behaviour.

Returns
-------
similarity : int
    similarity between s1 and s2
N0)r   lengetbincount)s1s2r
   r   Sblock	block_getxch1ch2Matchesuress   &&$$         q/Users/max/.openclaw/workspace/postharvest/merge_env/lib/python3.14/site-packages/rapidfuzz/distance/LCSseq_py.py
similarityr   
   s    < r]r]B#FB	
c"gAE		I	AsA&*
	a  C#KUqu  a&#b'

"
"3
'C'3+>3FQF    c                (   V'       g   ^ # ^\        V4      ,          ^,
          pV P                  pV F)  pV! V^ 4      pWG,          pWH,           WH,
          ,          pK+  	  \        V4      \        V4      ) R P                  R4      p	Ve   W8  d   V	# ^ # r   Nr   )r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   s
   &&&&      r   _block_similarityr"   B   s     	
c"gA		IC#KUqu  a&#b'

"
"3
'C'3+>3FQFr   c                   Ve   V! V 4      p V! V4      p\        W4      w  r\        \        V 4      \        V4      4      p\        W4      pWE,
          pVe   Wc8:  d   V# V^,           # )a  
Calculates the LCS distance in the range [0, max].

This is calculated as ``max(len1, len2) - similarity``.

Parameters
----------
s1 : Sequence[Hashable]
    First string to compare.
s2 : Sequence[Hashable]
    Second string to compare.
processor: callable, optional
    Optional callable that is used to preprocess the strings before
    comparing them. Default is None, which deactivates this behaviour.
score_cutoff : int, optional
    Maximum distance between s1 and s2, that is
    considered as a result. If the distance is bigger than score_cutoff,
    score_cutoff + 1 is returned instead. Default is None, which deactivates
    this behaviour.

Returns
-------
distance : int
    distance between s1 and s2

Examples
--------
Find the LCS distance between two strings:

>>> from rapidfuzz.distance import LCSseq
>>> LCSseq.distance("lewenstein", "levenshtein")
2

Setting a maximum distance allows the implementation to select
a more efficient implementation:

>>> LCSseq.distance("lewenstein", "levenshtein", score_cutoff=1)
2

)r   maxr   r   )r   r   r
   r   maximumsimdists   &&$$   r   distancer(   X   si    ^ r]r]B#FB#b'3r7#G
R
C=D (D,@4W|VWGWWr   c               @   \        4        \        V 4      '       g   \        V4      '       d   R# Ve   V! V 4      p V! V4      pV '       d	   V'       g   ^ # \        W4      w  r\        \	        V 4      \	        V4      4      p\        W4      V,          pVe   WS8:  d   V# ^# )a  
Calculates a normalized LCS similarity in the range [1, 0].

This is calculated as ``distance / max(len1, len2)``.

Parameters
----------
s1 : Sequence[Hashable]
    First string to compare.
s2 : Sequence[Hashable]
    Second string to compare.
processor: callable, optional
    Optional callable that is used to preprocess the strings before
    comparing them. Default is None, which deactivates this behaviour.
score_cutoff : float, optional
    Optional argument for a score threshold as a float between 0 and 1.0.
    For norm_dist > score_cutoff 1.0 is returned instead. Default is 1.0,
    which deactivates this behaviour.

Returns
-------
norm_dist : float
    normalized distance between s1 and s2 as a float between 0 and 1.0
      ?)r   r   r   r$   r   r(   )r   r   r
   r   r%   norm_sims   &&$$  r   normalized_distancer,      s    > Mr{{gbkkr]r]RB#FB#b'3r7#G')H$,0H8PqPr   c                   \        4        \        V 4      '       g   \        V4      '       d   R# Ve   V! V 4      p V! V4      pR\        W4      ,
          pVe   WC8  d   V# ^ # )a	  
Calculates a normalized LCS similarity in the range [0, 1].

This is calculated as ``1 - normalized_distance``

Parameters
----------
s1 : Sequence[Hashable]
    First string to compare.
s2 : Sequence[Hashable]
    Second string to compare.
processor: callable, optional
    Optional callable that is used to preprocess the strings before
    comparing them. Default is None, which deactivates this behaviour.
score_cutoff : float, optional
    Optional argument for a score threshold as a float between 0 and 1.0.
    For norm_sim < score_cutoff 0 is returned instead. Default is 0,
    which deactivates this behaviour.

Returns
-------
norm_sim : float
    normalized similarity between s1 and s2 as a float between 0 and 1.0

Examples
--------
Find the normalized LCS similarity between two strings:

>>> from rapidfuzz.distance import LCSseq
>>> LCSseq.normalized_similarity("lewenstein", "levenshtein")
0.8181818181818181

Setting a score_cutoff allows the implementation to select
a more efficient implementation:

>>> LCSseq.normalized_similarity("lewenstein", "levenshtein", score_cutoff=0.9)
0.0

When a different processor is used s1 and s2 do not have to be strings

>>> LCSseq.normalized_similarity(["lewenstein"], ["levenshtein"], processor=lambda s: s[0])
0.81818181818181
g        r*   )r   r   r,   )r   r   r
   r   r+   s   &&$$ r   normalized_similarityr.      s[    d Mr{{gbkkr]r](00H$,0H8PqPr   c                   V '       g   ^ . 3# ^\        V 4      ,          ^,
          p/ pVP                  p^pV  F  pV! V^ 4      V,          W6&   V^,          pK   	  . pV F:  pV! V^ 4      p	W),          p
W*,           W*,
          ,          pVP                  V4       K<  	  \        V4      \        V 4      ) R P	                  R4      pW3# r!   )r   r   appendr   r   )r   r   r   r   r   r   r   matrixr   r   r   r&   s   &&          r   _matrixr2      s    2w	
c"gAE		I	AsA&*
	a  FC#KUqua	  a&#b'

"
"3
'C=r   c                  Ve   V! V 4      p V! V4      p\        W4      w  r\        W4      w  r4W\        V 4      V,
           p W\        V4      V,
           p\        W4      w  rV\	        . ^ ^ 4      p\        V 4      V,           V,           Vn        \        V4      V,           V,           Vn        \        V 4      \        V4      ,           ^V,          ,
          pV^ 8X  d   V# R.V,          p	\        V 4      p
\        V4      pV^ 8w  d   V
^ 8w  d   Wk^,
          ,          ^V
^,
          ,          ,          '       d0   V^,          pV
^,          p
\        RW,           W,           4      W&   Kg  V^,          pV'       dQ   Wk^,
          ,          ^V
^,
          ,          ,          '       g'   V^,          p\        RW,           W,           4      W&   K  V
^,          p
K  V
^ 8w  d0   V^,          pV
^,          p
\        RW,           W,           4      W&   K6  V^ 8w  d0   V^,          pV^,          p\        RW,           W,           4      W&   K6  Wn        V# )u  
Return Editops describing how to turn s1 into s2.

Parameters
----------
s1 : Sequence[Hashable]
    First string to compare.
s2 : Sequence[Hashable]
    Second string to compare.
processor: callable, optional
    Optional callable that is used to preprocess the strings before
    comparing them. Default is None, which deactivates this behaviour.

Returns
-------
editops : Editops
    edit operations required to turn s1 into s2

Notes
-----
The alignment is calculated using an algorithm of Heikki Hyyrö, which is
described in [6]_. It has a time complexity and memory usage of ``O([N/64] * M)``.

References
----------
.. [6] Hyyrö, Heikki. "A Note on Bit-Parallel Alignment Computation."
       Stringology (2004).

Examples
--------
>>> from rapidfuzz.distance import LCSseq
>>> for tag, src_pos, dest_pos in LCSseq.editops("qabxcd", "abycdf"):
...    print(("%7s s1[%d] s2[%d]" % (tag, src_pos, dest_pos)))
 delete s1[0] s2[0]
 delete s1[3] s2[2]
 insert s1[4] s2[2]
 insert s1[6] s2[5]
Ndeleteinsert)	r   r   r   r2   r	   _src_len	_dest_lenr   _editops)r   r   r
   
prefix_len
suffix_lenr&   r1   editopsr'   editop_listcolrows   &&$         r   r;   r;     s   X r]r]B#FB)"1J	R:-	.B	R:-	.B"/KCb!QG2w+j8GB*,z9Gr7SWq3w&Dqy&4-K
b'C
b'C
(sax'?aC!Gn--AID1HC &x1A3CS TK1HC F7OqS1W~>>	$*8S5EsGW$X! q
(	q"8S-=s?OP
(	q"8S-=s?OP"Nr   c               8    \        WVR7      P                  4       # )u  
Return Opcodes describing how to turn s1 into s2.

Parameters
----------
s1 : Sequence[Hashable]
    First string to compare.
s2 : Sequence[Hashable]
    Second string to compare.
processor: callable, optional
    Optional callable that is used to preprocess the strings before
    comparing them. Default is None, which deactivates this behaviour.

Returns
-------
opcodes : Opcodes
    edit operations required to turn s1 into s2

Notes
-----
The alignment is calculated using an algorithm of Heikki Hyyrö, which is
described in [7]_. It has a time complexity and memory usage of ``O([N/64] * M)``.

References
----------
.. [7] Hyyrö, Heikki. "A Note on Bit-Parallel Alignment Computation."
       Stringology (2004).

Examples
--------
>>> from rapidfuzz.distance import LCSseq

>>> a = "qabxcd"
>>> b = "abycdf"
>>> for tag, i1, i2, j1, j2 in LCSseq.opcodes(a, b):
...    print(("%7s a[%d:%d] (%s) b[%d:%d] (%s)" %
...           (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2])))
 delete a[0:1] (q) b[0:0] ()
  equal a[1:3] (ab) b[0:2] (ab)
 delete a[3:4] (x) b[2:2] ()
 insert a[4:4] () b[2:3] (y)
  equal a[4:6] (cd) b[3:5] (cd)
 insert a[6:6] () b[5:6] (f)
)r
   )r;   
as_opcodes)r   r   r
   s   &&$r   opcodesrA   x  s    d 2Y/::<<r   )N)
__future__r   rapidfuzz._common_pyr   r   rapidfuzz._utilsr   r   !rapidfuzz.distance._initialize_pyr   r	   r   r"   r(   r,   r.   r2   r;   rA    r   r   <module>rG      s    # = 1 =5G 	5G
 5GpG,7X 	7X
 7Xt-Q 	-Q
 -Q`;Q 	;Q
 ;Q|0] 	]@2= 	2=r   