
    AHj>                       d 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ZddlmZ dd	lmZ dd
lmZ  G d d      Zej*                  j,                   G d d             Zedk(  r e       Zej5                  dd       yy)zm
Fuzzy matcher.

This class is used by the [command palette](/guide/command_palette) to match search terms.

    )annotations)	lru_cache)
itemgetter)finditer)IterableSequenceN)LRUCache)Content)Stylec                  z    e Zd ZdZ	 ddd	 	 	 	 	 ddZddZe ed      dd              Zdd	Z		 	 	 	 	 	 dd
Z
y)FuzzySearchzaPerforms a fuzzy search.

    Unlike a regex solution, this will finds all possible matches.
    i   )
cache_sizec               2    || _         t        |      | _        y)zInitialize fuzzy search.

        Args:
            case_sensitive: Is the match case sensitive?
            cache_size: Number of queries to cache.
        N)case_sensitiver	   cache)selfr   r   s      E/root/tools/cai/cai_env/lib/python3.12/site-packages/textual/fuzzy.py__init__zFuzzySearch.__init__   s     -MUN

    c                    ||f}|| j                   v r| j                   |   S dg f}t        | j                  ||      t        d      |      }|| j                   |<   |S )zMatch against a query.

        Args:
            query: The fuzzy query.
            candidate: A candidate to check,.

        Returns:
            A pair of (score, tuple of offsets). `(0, ())` for no result.
                r   )keydefault)r   max_matchr   )r   query	candidate	cache_keyr   results         r   matchzFuzzySearch.match+   sb     I&	

"::i((03RyT[[	2
1wW &

9r   i   )maxsizec                n    t        t        d|      D ch c]  }|j                          c}      S c c}w )Nz\w+)	frozensetr   start)clsr   r    s      r   get_first_letterszFuzzySearch.get_first_letters>   s*     Xfi5PQE%++-QRRQs   2c                    | j                  |      }t        |      }|t        |j                  |            z   }d}|^}}|D ]  }	|	|dz   k7  r|dz  }|	} ||dz
  z
  |z  }
|d|
|
z  z   z  }|S )zoScore a search.

        Args:
            search: Search object.

        Returns:
            Score.
           )r&   lenintersection)r   r   	positionsfirst_lettersoffset_countscoregroupslast_offsetoffsetsoffsetnormalized_groupss              r   r.   zFuzzySearch.scoreC   s     ..y9 9~#c-*D*DY*O&PP )g 	!Fq(! K	! *VaZ8LH'*;;<<r   c           	   #    K   g d}| j                   s |j                         }|j                         }| j                  }||v rJ|j                  |      }t	        t        ||t        |      z               } |||      ||k(  rdndz  |f y t        |      D ]  \  }}t        |      |z
  }	g }
j                  |
       |}|j                  ||      x}dk7  r4|
j                  |       |dz   }||	k\  rn|j                  ||      x}dk7  r4|
sd  y |
d   dz   } g t        |      dfd g d       D ]  } |||      |f  y w)	Nr   g       @g      ?r(   )r    c                    |   D ]?  }| r	|| d   kD  sg | |}t        |      k(  rj                  |       4 ||dz          A y)zRecursively match offsets.

            Args:
                offsets: A list of offsets.
                positions_index: Index of query letter.

            r5   r(   N)r)   append)r1   positions_indexr2   new_offsetsget_offsetsletter_positionspossible_offsetsquery_lengths       r   r;   z'FuzzySearch._match.<locals>.get_offsets   sb     +?; F&72;"6"4G"4V"4K;'<7(//<#K11DEFr   )r1   z	list[int]r9   intreturnNone)
r   lowerr.   rfindlistranger)   	enumerater8   find)r   r   r   positionr.   query_locationr1   r2   letter
last_indexr+   indexlocationr;   r<   r=   r>   s                @@@@r   r   zFuzzySearch._match^   s     -/""!)IKKME

I&__U3N5#e*1LMNGi)I4FSCP  '. 	(NFFY&0J#%I##I.E(~~fe<<8C  * 1J&	  )~~fe<<8C
  |a'H	( -/5z	F 	F  	B' 	5G	7+W44	5s   D	EAEN)F)r   boolr   r?   r@   rA   )r   strr   rO   r@   ztuple[float, Sequence[int]])r   rO   r@   zfrozenset[int])r   rO   r+   zSequence[int]r@   float)r   rO   r   rO   r@   z%Iterable[tuple[float, Sequence[int]]])__name__
__module____qualname____doc__r   r    classmethodr   r&   r.   r   r6   r   r   r   r      s{     &+
AI
"
;>
	
& tS  S69595%(95	.95r   r   c                  t    e Zd ZdZddd	 	 	 	 	 	 	 ddZedd       Zedd       Zedd       Zdd	Z	dd
Z
y)MatcherzA fuzzy matcher.NF)match_styler   c               h    || _         |t        d      n|| _        || _        t	               | _        y)a  Initialise the fuzzy matching object.

        Args:
            query: A query as typed in by the user.
            match_style: The style to use to highlight matched portions of a string.
            case_sensitive: Should matching be case sensitive?
        NT)reverse)_queryr   _match_style_case_sensitiver   fuzzy_search)r   r   rX   r   s       r   r   zMatcher.__init__   s1     3>3FE$/K-'Mr   c                    | j                   S )zThe query string to look for.)r[   r   s    r   r   zMatcher.query   s     {{r   c                    | j                   S )zBThe style that will be used to highlight hits in the matched text.)r\   r`   s    r   rX   zMatcher.match_style   s        r   c                    | j                   S )zIs this matcher case sensitive?)r]   r`   s    r   r   zMatcher.case_sensitive   s     ###r   c                T    | j                   j                  | j                  |      d   S )zMatch the candidate against the query.

        Args:
            candidate: Candidate string to match against the query.

        Returns:
            Strength of the match from 0 to 1.
        r   )r^   r    r   )r   r   s     r   r    zMatcher.match   s&       &&tzz9=a@@r   c                    t        j                  |      }| j                  j                  | j                  |      \  }}|s|S |D ]6  }||   j                         r|j                  | j                  ||dz         }8 |S )zHighlight the candidate with the fuzzy match.

        Args:
            candidate: The candidate string to match against the query.

        Returns:
            A [`Text`][rich.text.Text] object with highlighted matches.
        r(   )r
   from_markupr^   r    r   isspacestylizer\   )r   r   contentr.   r1   r2   s         r   	highlightzMatcher.highlight   s     %%i0**00YGwN 	QFV$,,.!//$*;*;VVaZP	Q r   )r   rO   rX   zStyle | Noner   rN   r@   rA   )r@   rO   )r@   r   )r@   rN   )r   rO   r@   rP   )r   rO   r@   r
   )rQ   rR   rS   rT   r   propertyr   rX   r   r    ri   r6   r   r   rW   rW      s     %)$** "	*
 * 
*&   ! ! $ $	Ar   rW   __main__zfoo.barzfoo/egg.bar)rT   
__future__r   	functoolsr   operatorr   rer   typingr   r   	rich.reprrichtextual.cacher	   textual.contentr
   textual.visualr   r   reprautorW   rQ   r^   r    r6   r   r   <module>rx      s    #    %  " #  A5 A5H @ @ @F z=Ly-0 r   