+
   ʎ綐c                    s   R t ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIH	t	 ^ R	I
t
^ R	It^ R	It^ R	It^ R	It^ R	It^ R	It^ R	It^ R	It^ R	It^ R	It^ R	ItR
sR R ltR R ltRt ^ R	ItRtRt ^ R	ItRtRt ^ R	ItRtRt  ^ R	I!t!Rt Rt" ^ R	I#t#Rt"]#PH                  ! 4       t%Rt& ^ R	I't'Rt&]PP                  ! R
4      t)]
PT                  PW                  ]
PT                  PY                  ]-4      R4      t.]P^                  ! R4      t0]0].RR3t1]0].RR3t2]0].RR3t3/ RRRRRRR/bRRRRRRR /bR!RRRRRR"/bR#RRRRRR$/bR%RRRRRR&/bR'RRRR(RR)/bR*RRRR(RR+/bR,RRRR(RR/bR-RRRR(RR./bR/RRRR(RR0/bR1RRRR2RR3/bR4RRRR2RR5/bR6RRRR2RR7/bR8RRRR9RR:/bR;RRRR9RR(/bR<RRRR9RR/bR=RRRR>RR?/bR@RRRR>RRA/RBRRRR>RRC/RDRRRR>RRE/RFRRRR>RRG/RHRRRR>RR/RIRRRR>RRJ/RKRRRRLRRM/RNRRRRLRR+/RORRRRLRRP/RQRRRRLRR/RRRRRRSRRT/RURRRRSRRV/RWRRRRSRRX//Ct4RY. R|ORZ. R|OR[R\.R]R\.R^R_.R`R`.RaRa.RbRa.RcRc.RdRc.ReRe.RfRf.RgRg.RhRh.RiRi./t5R}t60 R~mt7Rt8Rt9]"'       d	   RRj Rk llt:Rl Rm lt;RRn Ro llt<Rp Rq lt=]P|                  ! R	Rr7      Rs Rt l4       t?]P|                  ! R	Rr7      Ru Rv l4       t@ ! Rw Rx4      tARtBRy Rz ltC]DR{8X  d
   ]C! 4        R	# R	#   ] d     ELsi ; i  ] d     ELxi ; i  ]3 d    Rt ELi ; i  ]3 d    Rt  ELi ; i  ]3 d    Rt" ELi ; i  ]3 d    Rt& ELi ; i)zUA module used by ibus-typing-booster to match emoji and similar
Unicode characters.

)Any)List)Tuple)Dict)Set)Optional)Iterable)CallableNzibus-typing-boosterc                0    V ^8  d   QhR\         R\         /#    textreturnstrformat   "2/usr/share/ibus-typing-booster/engine/itb_emoji.py__annotate__r   0   s     . .C .C .    c                s8    \         P                  ! \        V 4      # )zGettext translation function.)gettextZdgettext
DOMAINNAMEr      &r   _r   0   s    J--r   c                r   r	   r   r   r   r   r   r   4   s      S S r   c                s    V # )z{Mark string for translation without actually translating.

Used by gettext tools to extract strings that need translation.
 r   r   r   N_r   4   s	    
 Kr   FTz../datazibus-typing-booster/dataz/usr/share/unicode/ucdz/usr/share/unicode/z/usr/share/unicode/emojiz/usr/share/unicode/ucd/z/usr/share/unicode/cldr/common/z/local/mfabian/src/cldr/common/CcvalidmajorZOtherminorZControlZCfZFormatZCnzNot assignedCozPrivate useCsZ	SurrogateZLlZLetterZ	LowercaseZLmZModifierZLoZLtZ	TitlecaseZLuZ	UppercaseZMcZMarkzSpacing combiningZMeZ	EnclosingZMnZ
NonspacingZNdZNumberzDecimal digitZNlZNoZPcZPunctuationZ	ConnectorZPdZDashZPeZCloseZPfzFinal quoteZPizInitial quoteZPoZPsZOpenZScZSymbolZCurrencyZSkZSmZMathZSoZZlZ	SeparatorZLineZZpZ	ParagraphZZsZSpacez1.0z2.0z3.0z9.0z4.0z5.0z10.0z11.0z12.0z12.1z13.0z13.1z14.0z15.0z15.1z16.0z17.0c                s<    V ^8  d   QhR\         R\         R\         /# )r
   r   targetr   r   r   r   r   r   r     s!     ) )S )# ) )r   c                s    \         '       d   VR8X  d   V # Rp\        P                  V 4       F  pW#V,          ,          pK  	  V# )u  
Convert Japanese text to hiragana, katakana, or romaji

:param text: The text to be converted
:param target: The target to be converted to, can be:
               'orig':     return original text, no conversion
               'hira':     convert to hiragana
               'kana':     convert to katakana
               'hepburn':  convert to Hepburn romanization
               'kunrei':   convert to Kunrei romanization
               'passport': convert to Passport romanization

Examples:

>>> kakasi_convert('かな漢字')
'かな漢字'

>>> kakasi_convert('かな漢字', target='hira')
'かなかんじ'

>>> kakasi_convert('かな, foobar, 漢字,', target='hira')
'かな, foobar, かんじ,'

>>> kakasi_convert('かな漢字', target='kana')
'カナカンジ'

>>> kakasi_convert('かな漢字', target='hepburn')
'kanakanji'

>>> kakasi_convert('かな漢字', target='kunrei')
'kanakanzi'

>>> kakasi_convert('かな漢字', target='passport')
'kanakanji'
orig )IMPORT_PYKAKASI_SUCCESSFULKAKASI_INSTANCEZconvert)r   r"   resultZitems   &&  r   kakasi_convertr(     sB    H *)Vv-=K#++D1D6l"F 2r   c                s0    V ^8  d   QhR\         R\        /# )r
   	codepointr   )intboolr   r   r   r   r   6  s     8 8 8 8r   c           	     sz    \        \         UUu. uF  w  rYu;8*  ;'       d    V8*  Mu NK  	  upp4      # u uppi )uh  Checks whether the codepoint is in one of the valid ranges

Returns True if the codepoint is in one of the valid ranges,
else it returns False.

:param codepoint: The Unicode codepoint to check

Examples:

>>> _in_range(0x1F915)
True

>>> _in_range(0x1F815)
False

>>> _in_range(ord('€'))
True

>>> _in_range(ord('₹'))
True

>>> _in_range(ord('₺'))
True
)anyVALID_RANGES)r)   xZy   &  r   	_in_ranger0   6  s3    2 )56		1	68 86s    7
c                s    V ^8  d   QhR\         \        ,          R\         \        ,          R\        R\        \        \        \        \
        .\
        3,          ,          3,          /# )r
   dirnames	basenamessubdirr   )r   r   r   r   r   r    r   r   r   r   r   R  sR     1 13-1C=1 1 #33%*1E(F#FG1r   c           	     s|   V EF  pV  EF  p\         P                  P                  \         P                  P                  WBV4      4      p\         P                  P	                  V4      '       Ed   VP                  R4      '       d-   \        P                  RV4       V\        P                  3u u # VP                  R4      '       d9   \        '       d-   \        P                  RV4       V\        P                  3u u # VP                  R4      '       d9   \        '       d-   \        P                  RV4       V\        P                  3u u # \        P                  RV4       V\        3u u # VR,           p\         P                  P	                  V4      '       d-   \        P                  RV4       V\        P                  3u u # \        '       d[   VR,           p\         P                  P	                  V4      '       d-   \        P                  RV4       V\        P                  3u u # \        '       g   EK9  VR,           p\         P                  P	                  V4      '       g   EKj  \        P                  RV4       V\        P                  3u u # 	  EK  	  \        P                  RW4       R	# )
u  Find the first existing file of a list of basenames and dirnames

For each file in “basenames”, tries whether that file or the
file with “.gz|.bz2|.xz” added can be found in the list of directories
“dirnames” where “subdir” is added to each directory in the list.

Returns a tuple (path, open_function) where “path” is the
complete path of the first file found and the open function
is either “open()”, “gzip.open()”, “bz2.open()”, or “lzma.open()”.

:param dirnames: A list of directories to search in
:param basenames: A list of file names to search for
:param subdir: A subdirectory to be added to each directory in the list
.gzzFound gzip file: %s.bz2zFound bzip2 file: %s.xzzFound xz file: %szFound uncompressed file: %szCould not find any "%s" in "%s")r$   N)ospathZ
expanduserjoinZexistsZendswithLOGGERZdebuggzipZopenIMPORT_BZ2_SUCCESSFULbz2IMPORT_LZMA_SUCCESSFULlzmawarning)	r1   r2   r3   basenamedirnameZ	base_pathZgz_pathZbz2_pathZxz_paths	   &&&      r   _find_path_and_open_functionrC   R  s   $ G**Wh79Iww~~i((%%e,,LL!6	B%tyy11%%f--2G2GLL!7C%sxx00%%e,,1G1GLL!4i@%tyy11:IF!4((%'Gww~~g&&2G<++$$$v-77>>(++LL!7B$chh//%%#e+77>>'**LL!4g>#TYY//9   < NN4iJr   c                r   )r
   languager   r   r   r   r   r   r     s        r   c                s   \         p\        P                  ! V 4      pVP                  pVP                  '       d   VRVP                  ,           ,          p\        P
                  ! V .4       F{  pVR,           3p\        WRR7      w  rgV'       g   K&  \        P                  P                  V4      P                  V4      '       g   K\  \        P                  P                  V4      u # 	  R# )a  
Finds which CLDR annotation file would be used for the language given

Returns the full path of the  file found or an empty string if
no file can be found for the language given.

This function is intended to be used by the ibus-typing-booster
setup tool to check whether CLDR annotations exist for a certain
language.

:param language: The language to search the annotation file for
r   .xmlannotationsr3   r$   )CLDR_ANNOTATION_DIRNAMESitb_utilZparse_localerD   Zscriptexpand_languagesrC   r7   r8   rA   
startswithZabspath)rD   r1   ZlocaleZacceptable_match	_languager2   r8   Zdummy_open_functions   &       r   find_cldr_annotation_pathrM     s     (H""8,F}}}C&--//..z:	')	&B'7#4BGG$$T*556FGG77??4(( ; r   Zmaxsizec                <    V ^8  d   QhR\         R\         R\        /# r
   labelmatch_stringr   r   floatr   r   r   r   r     s!     . .# .S .U .r   c                s0   \         P                  ! V P                  4       4      p Rp\        V P	                  4       4      pV P                  RR4      p\        VP	                  RR7      \        RR7      p\        V4      pW68X  d
   VR,          pV F&  pWp8X  g   K  T\        V4      ^8X  d   R	MR
,          pK(  	  T pTp	V F  pVP                  V4      p
V
^ 8  d]   V
^ 8X  g   W^,
          ,          R8X  dB   Y*^ 8X  d   RMR,          pV\        V4      ,          pVRV
 W\        V4      ,           R ,           pV	P                  V4      p
V
^ 8  g   K  Y*^ 8X  d   RMR,          pV\        V4      ,          pV	RV
 W\        V4      ,           R ,           p	K  	  V# )z=Matches a label from the emoji data against the query string.         r$   NZsepT)keyZreverseg     @@g     r@      i@g      ^@g      Y@g      D@g      4@)	rI   remove_accentslowersetsplitreplacesortedlenfind)rQ   rR   total_scoreZlabel_wordsZlabel_no_spacesZ	word_listZword_setwordZ	tmp_labelZtmp_no_spacesZmatch_starts   &&         r   _match_classicrd     s    ##EKKM2EKekkm$KmmC,O|))d)3dKI9~H v =C	Na$75UBK	  I#MnnT*!a91_#=#Dq(8ueCs4y(
 &l{3icRVi@W@X6YY	 $((.!!#34=K3t9$K
 *,;7-VYZ^V_H_H`:aaM- . r   c                rO   rP   rS   r   r   r   r   r     s!     ? ?C ?s ?u ?r   c                s    \         P                  ! V P                  4       4      p \        P                  P                  W4      # )zMMatches a label from the emoji data against the query string using rapidfuzz.)rI   rZ   r[   	rapidfuzzZfuzzZtoken_set_ratio)rQ   rR      &&r   _match_rapidfuzzrg     s/     ##EKKM2E>>))%>>r   c                   sx  a  ] tR tRt o RtRWV 3R lR lltRXV 3R lR lltRYV 3R lR lltV 3R	 lR
 lt]	P                  ! RR7      RYV 3R lR ll4       tV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR  ltV 3R! lR" ltV 3R# lR$ ltV 3R% lR& ltV 3R' lR( ltV 3R) lR* ltRZV 3R+ lR, lltRZV 3R- lR. llt]	P                  ! RR7      V 3R/ lR0 l4       tR[V 3R1 lR2 lltR[V 3R3 lR4 lltR[V 3R5 lR6 lltR[V 3R7 lR8 llt R\V 3R9 lR: llt!V 3R; lR< lt"V 3R= lR> lt#V 3R? lR@ lt$V 3RA lRB lt%V 3RC lRD lt&V 3RE lRF lt'V 3RG lRH lt(V 3RI lRJ lt)V 3RK lRL lt*V 3RM lRN lt+V 3RO lRP lt,V 3RQ lRR lt-V 3RS lRT lt.RUt/V t0RV# )]EmojiMatcheri  z5A class to find Emoji which best match a query stringc                sp   < V ^8  d   QhRS[ S[,          RS[RS[RS[RS[RS[RS[RS[R	S[R
S[RS[RR/# )r
   	languagesunicode_dataunicode_data_allunikemet	nameslistemoji_unicode_minemoji_unicode_max	cldr_datavariation_selectorromajimatch_algorithmr   N)r   r   r+   r   __classdict__   "r   r   EmojiMatcher.__annotate__  s     U$ U$(3- U$#U$#'U$  U$ !	U$
 %(U$ %(U$ !U$ &)U$ U$ #&U$ 9=U$r   c                s   Wn         / V n        \        P                  ! V P                   4       F  p\        P
                  ! \        V.R7      pV'       dU   RV,           R,           \        ,           R,           V9   d.    \        P                  ! \        V.R7      V P                  V&   K|  RV P                  V&   K  	  W0n	        W`n
        Wpn        Wn        Wn        / V n        . V n        \         '       da   V P                    FP  p\"        P$                  ! V4      '       g   K!  V P                  P'                  \"        P(                  ! V4      4       KR  	  / V n        / V n        \.        V n        RV n        V P5                  V4       V'       dQ   V P7                  4        V P9                  4        V'       d   V P;                  4        V'       d   V P=                  4        V P?                  4        V PA                  4        V PC                  4        V PE                  4        V PG                  4        V PI                  4        V'       dL   \        P                  ! V P                   4       F'  pV PK                  VR4       V PK                  VR4       K)  	  V PM                  4        R#   \        3 d    RT P                  T&    EK  i ; i)	a  
Initialize the emoji matcher

:param languages: A list of languages to use for matching emoji
:param unicode_data: Whether to load the UnicodeData.txt file as well
:param unicode_data_all: Whether to load *all* of the Unicode
                         characters from UnicodeData.txt.
                         If False, most regular letters are omitted.
:param unikemet: Whether to load the Unikemet.txt file
                 for Egyptian Hieroglyphs (requires unicode_data == True)
:param cldr_data: Whether to load data from CLDR as well
:param romaji: Whether to add Latin transliteration for Japanese.
               Works only when pykakasi is available, if this is not
               the case, this option is ignored.
)ri   Z/z/LC_MESSAGES/z.moN      N@rF   ZannotationsDerived)'
_languages_gettext_translationsrI   rJ   r   ra   r   ZtranslationOSError_unicode_data_all_emoji_unicode_min_emoji_unicode_max_variation_selector_romaji_unicode_blocks_enchant_dictsIMPORT_ENCHANT_SUCCESSFULenchantZdict_existsappendr   _emoji_dict_candidate_cacherd   _match_function_good_match_scoreset_match_algorithm_load_unicode_data_load_name_aliases_load_unikemet_load_nameslist_load_unicode_emoji_data_load_unicode_emoji_sequences!_load_unicode_emoji_zwj_sequences_load_derived_age_load_unicode_emoji_test_load_emojione_data_load_cldr_annotation_data_load_unicode_blocks)selfri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rD   Zmo_files   &&&&&&&&&&&&  r   __init__ZEmojiMatcher.__init__  s3   4 $57" 11$//BHll:(DG(No5
BUJ@;B;N;N"xj<:D..x8
 8<**84# C$ "2"3"3#5 13 $$ OO&&x00''..w||H/EF , CENP 	:H(,  1 ##%##%##%$$&%%'**,..0 %%'  "$55dooF//-H//:NO G 	!!#W  { @;?D..x8@s   >*J##KKc                $   < V ^8  d   QhRS[ RR/# )r
   namer   Nr   rt   rv   r   r   rw   <  s       d r   c                s    / V n         VR8X  d!   \        '       d   \        V n        RV n        R# VR8X  d   RV n        \
        V n        R# RV n        \
        V n        R# )zSets the match algorithm

Currently supported: 'rapidfuzz', 'classic'

When 'rapidfuzz is requested but `import rapidfuzz` has failed,
a fallback to 'classic' is used.

Changing the match algorithm clears the candidate cache.
re   rx   NZclassicrY   )r   IMPORT_RAPIDFUZZ_SUCCESSFULrg   r   r   rd   )r   r   rf   r   r   Z EmojiMatcher.set_match_algorithm<  s[     !#;$?$?#3D %)D"9%*D"#1D !&-r   c                r   )r
   rq   r   Nr   rt   rv   r   r   rw   S  s     6 6 6$ 6r   c                s     / V n         Wn        R# )u  Set the emoji variation selector

:param variation_selector:
                        emoji' means to use fully qualified
                        sequences in “Emoji style” (which
                        usually means to prefer color). 'text'
                        means to use fully qualified emoji
                        sequences in “Text style” (which
                        usually means to prefer black and
                        white).  Other values than 'emoji' and
                        'text' mean to use unqualified emoji
                        sequences.

Changing the variation selector clears the candidate cache.
N)r   r   )r   rq   rf   r   set_variation_selectorZ#EmojiMatcher.set_variation_selectorS  s      !##5 r   c                s0   < V ^8  d   QhRS[ S[,          /# r
   r   )r   r   rt   rv   r   r   rw   f  s     % %tCy %r   c                s,    \        V P                  4      # )a+  Returns a copy of the list of languages of this EmojiMatcher

Useful to check whether an already available EmojiMatcher instance
can be used or whether one needs a new instance because one needs
a different list of languages.

Note that the order of that list is important, a matcher which
supports the same languages but in an different order might
return different results.

Examples:

>>> m = EmojiMatcher(languages = ['en_US', 'it_IT', 'es_MX', 'es_ES', 'de_DE', 'ja_JP'])
>>> m.get_languages()
['en_US', 'it_IT', 'es_MX', 'es_ES', 'de_DE', 'ja_JP']

)listry   )r   r   r   get_languagesZEmojiMatcher.get_languagesf  s    2 DOO$$r   i  rN   c                ,   < V ^8  d   QhRS[ RS[ RS[ /# )r
   emoji_stringrq   r   r   rt   rv   r   r   rw     s*     Z Z #Z9<ZJMZr   c                sP   VR
9   d   V# VP                  RR4      P                  RR4      pVR9  d   V# RV^ ,          u;8:  d
   R8:  d    V#  . pVR8X  d   RMRp\        V4       F  w  rVVP                  V4       V\        V4      ^,
          8H  pV'       g   W^,           ,          MRpV\        9   p	V\        9  g   KZ  RV P                  V4      9   g   Kr  VR8X  g   R	V P                  V4      9  g   K  V	'       d   K  VP                  V4       K  	  RP                  V4      # )u  Removes or adds emoji presentation selectors

U+FE0E VARIATION SELECTOR-15 selects text presentation
U+FE0F VARIATION SELECTOR-16 selects emoji presentation

Returns the possibly changed sequence.

If emoji_string is equal to '︎' or '️', it is returned unchanged.

See:

http://unicode.org/reports/tr51/#Emoji_Variation_Selector_Notes
http://unicode.org/reports/tr51/#def_fully_qualified_emoji_zwj_sequence
http://unicode.org/reports/tr51/#def_non_fully_qualified_emoji_zwj_sequence

:param emoji_string: The emoji sequence to change.
:param variation_selector: If 'emoji', make it a fully qualified
                           sequence using VS16 characters as needed.
                           If 'text' use VS15 characters as needed
                           to choose the text presentation of the emojis.
                           If it is neither 'emoji' nor 'text',  remove
                           all VS15 and VS16 characters.

Examples:

>>> matcher = EmojiMatcher()

If variation_selector is neither 'emoji' nor 'text, all variation selectors
are removed from a sequence, no matter whether the sequence
was correct or not:

>>> matcher.variation_selector_normalize('⛹️‍♀️', variation_selector='')
'⛹‍♀'

>>> matcher.variation_selector_normalize('⛹🏿‍♀️', variation_selector='')
'⛹🏿‍♀'

>>> matcher.variation_selector_normalize('#️⃣', variation_selector='')
'#⃣'

>>> matcher.variation_selector_normalize('#⃣️', variation_selector='')
'#⃣'

If variation_selector='emoji', variation selectors-16 are added to
sequences as needed to make sequences fully qualified
and incorrect sequences are repaired:

>>> matcher.variation_selector_normalize('⛹🏿️‍♀️', variation_selector='emoji')
'⛹🏿‍♀️'

>>> matcher.variation_selector_normalize('⛹️🏿‍♀️', variation_selector='emoji')
'⛹🏿‍♀️'

>>> matcher.variation_selector_normalize('⛹‍️♀', variation_selector='emoji')
'⛹️‍♀️'

>>> matcher.variation_selector_normalize('#⃣️', variation_selector='emoji')
'#️⃣'

>>> matcher.variation_selector_normalize('⛹️♀', variation_selector='emoji')
'⛹️♀️'

>>> matcher.variation_selector_normalize('⛹', variation_selector='emoji')
'⛹️'
   ︎   ️r$   emojir   u   🇦u   🇿EmojiZEmoji_Presentation>   r   r   )r   r   )r^   	enumerater   r`   SKIN_TONE_MODIFIERS
propertiesr9   )
r   r   rq   r'   Zselectorindex	characterZis_lastZnext_characterZis_skin_tone_nexts
   &&&       r   variation_selector_normalizeZ)EmojiMatcher.variation_selector_normalize  s   L //#++Hb9AA(BO%66<?:l: ; 1W<8( ), 7EMM)$s<0144G<C\!)4N .2E E!44ty99'61,DOOI4NN))h' !8 wwvr   c                sF   < V ^8  d   QhRS[ S[S[3,          RS[RS[RR/# )r
   emoji_dict_key
values_keyvaluesr   N)r   r   r    rt   rv   r   r   rw     s;     %, %,!#s(O%, %, 	%, !	%,r   c                sz   V'       d   V'       d	   V'       g   R# V P                  V^ ,          RR7      V^,          3p V P                  V,          p\        V\        4      '       d/   W%9  d   . WR&   WR,          pV F  pWv9  g   K  Wg.,          pK  	  R# W5V&   R#   \         d    / pYPP                  T&    Lgi ; i)z0Adds data to the emoji_dict if not already thereNr$   rq   )r   r   ZKeyErrorZ
isinstancer   )r   r   r   r   Znormalized_keyZ
inner_dictZexistingvalues   &&&&    r   _add_to_emoji_dictZEmojiMatcher._add_to_emoji_dict  s     Zv--q!b . :1	:)).9J
 fd##+)+
&!-H('H  
 &,z"  	:J/9^,	:s   B B:9B:c                   < V ^8  d   QhRR/# r
   r   Nr   rt   rv   r   r   rw     s     (7 (7 (7r   c           
     s.   \         pRp\        W4      w  r4V'       d   Vf   R#  V! VRRR7      ;_uu_ 4       p\        P                  ! R4      p\        P                  ! R4      pRpRp	V F  p
VP	                  V
4      pV'       d,   VP                  4       w  r\        \        V^4      4      pVR3p	WP                  9  d   KY  VP	                  V
4      pV'       g   Kt  VP                  R	4      pVP                  R
4       F%  pV P                  V	R	VP                  4       .4       K'  	  K  	  RRR4       R#   + '       g   i     R# ; i  \        \        3 d8   p\        P!                  RTTP"                  P$                  T4        Rp?R# Rp?ii ; i)u)  Loads alternative names from NamesList.txt

The rules used for this process are aimed at readability for
the human reader, at the expense of some details; therefore,
this file should not be parsed for machine-readable
information.

But after all humans are reading this when using emoji-picker…
Nrtutf-8ZmodeZencodingz([0-9A-F]+)\s(\S.*\S)z\s+=\ (?P<names>\S.*\S)r$   ennames,z-Error while loading NamesList from %s: %s: %s)zNamesList.txt)r$   r   )UNICODE_DATA_DIRNAMESrC   recompilematchgroupschrr*   r   groupr]   r   stripr{   IOErrorr:   	exception	__class____name__)r   r1   r2   r8   open_functionZnameslist_fileZcode_point_line_patternZname_line_patternr   r   liner   codepoint_stringZ_official_namer   r   error   &                r   r   ZEmojiMatcher._load_nameslist  sl    )&	 <!!},	7tg7 7:H*,**5M*N'$&JJ/I$J!!!++D399$?E;@<<>8('*3/?+D'E*6)=%-=-== -33D9Eu %G 4$)KK$4D 33 .$**,I %5 ,7 7 7 7( ! 	7?eoo..7 7	7s<   E B"D8AD8.E 8E		E 	E F,FFc                r   r   r   rt   rv   r   r   rw   =  s     +7 +7 +7r   c           
     s   \         pRp\        W4      w  r4V'       d   Vf   R#  V! VRRR7      ;_uu_ 4       pV EFA  pVP                  R4      ^ ,          P                  4       pV'       g   K4   R VP	                  R^4       4       w  rxp	\        \        TR,          ^4      4      p
T
R	3pYP                  9   g   K  TR
8X  d@   T	P                  R4      p	T	P	                  R4       F  pT P                  TRT.4       K  	  K  TR8X  g   K  RT	9  d   T P                  TRT	.4       K  R T	P	                  R^4       4       w  rT P                  TRT.4       T P                  TRTP                  R4      .4       EKD  	  RRR4       R#   \
         d     EK_  i ; i  + '       g   i     R# ; i  \        \        3 d7   p\        P                  RY?P                  P                  T4        Rp?R# Rp?ii ; i)z+Loads Unikemet.txt for Egyptian HieroglyphsNr   r   r   #c              3   @   "   T F  qP                  4       x  K  	  R # 5iNr   .0part   & r   	<genexpr>.EmojiMatcher._load_unikemet.<locals>.<genexpr>M  s      8J5HTJJLL5H   Z	:r
   NNr   ZkEH_DescZ.r   r   ZkEH_FuncrV   keywordsc              3   r   r   r   r   r   r   r   r   ^  s      9R=PTJJLL=Pr   z()*Error while loading Blocks from %s: %s: %s)zUnikemet.txt)r   rC   	partitionr   r]   
ValueErrorr   r*   r   r   r{   r   r:   r   r   r   )r   r1   r2   r8   r   Zunikemet_filer   r   Ztagr   r   r   r   ZfunctionZdescriptionr   s   &               r   r   ZEmojiMatcher._load_unikemet=  s   (%	 <!!},#	7tg7 7:G)D>>#.q1779D !8J59ZZa5H8J4(u $'s+;B+?'C#DL&2D%9N%)9)99*,$)KK$4E(-C(8 $ 7 7$2GdV!E )9 !J."%/ $ 7 7$2J!I9R=B[[a=P9R 5 $ 7 7$2J
!L $ 7 7$2J%0%6%6t%<$=!?5 *7 7 & ! !7 7 7> ! 	7<oo..7 7	7sf   F2 7F0F-F>A
FA4FF2 F	FF	FF/	)F2 /F2 2G9+G44G9c                r   r   r   rt   rv   r   r   rw   j  s      7  7d  7r   c           
     sH   \         pR
p\        W4      w  r4V'       d   Vf   R#  V! VRRR7      ;_uu_ 4       p\        P                  ! R4      pV F  pVP	                  R4      ^ ,          P                  4       pV'       g   K3  VP                  V4      pV'       g   KN  VP                  4       w  rp\        V	^4      p\        V
^4      pVV P                  \        W^,           4      &   \        W^,           4       F8  p\        V4      pVR3pVV P                  9   g   K%  V P                  VRV4       K:  	  K  	  RRR4       R#   + '       g   i     R# ; i  \        \        3 d8   p\         P#                  R	TTP$                  P&                  T4        Rp?R# Rp?ii ; i)z!Loads the names of Unicode blocksNr   r   r   z%([0-9A-F]+)\.\.([0-9A-F]+);\ (\S.*\S)r   r   blockr   )z
Blocks.txt)r   rC   r   r   r   r   r   r   r*   r   ranger   r   r   r{   r   r:   r   r   r   )r   r1   r2   r8   r   Zblocks_fileZblocks_patternr   r   Zblock_startZ	block_end
block_nameZ	start_intZend_intr)   r   r   r      &                 r   r   Z!EmojiMatcher._load_unicode_blocksj  sw   (#	 <!!},	7tg7 7:E!#,T!U'D>>#.q1779D *006Eu=B\\^:
$'R$8	"%i"4=G ,,!)q[9;).yA+)FI+.y>L.:D-AN-1A1AA $ 7 7$2GZ!I	 *G (7 7 7 7( ! 	7<eoo..7 7	7sB   E A"EA<E E;E E	E E F!*,FF!c                r   r   r   rt   rv   r   r   rw     s     .1 .14 .1r   c           	     s   \         pRp\        W4      w  r4V'       d   Vf   R#  V! VRRR7      ;_uu_ 4       pV F  pVP                  R4      ^ ,          P                  4       pV'       g   K3   R VP	                  R^4       4       w  rxRT9   d,   TP	                  R4      w  r\        T	^4      \        T
^4      rM\        T^4      ;r\        Y^,           4       F7  p\        T4      pTR	3pYP                  9   g   K$  T P                  TR
T4       K9  	  K  	  RRR4       R#   \
         d     K  i ; i  + '       g   i     R# ; i  \         d7   p\        P                  RTP                  P                  T4        Rp?R# Rp?ii ; i)u  Loads in which Unicode versions code points were added

This updates 'uversion' for codepoints in `self._emoji_dict`, based on
the DerivedAge.txt Unicode data file.

This might overwrite uversion data already loaded from the
emoji-data.txt file, for example:

🧦 was added in Unicode 10.0 in and added to Emoji 5.0 in
2017. So when by the emoji data files 5.0 was found,
'uversion' will be overwritten with 10.0 here and 5.0 will
still be available as 'eversion'.
Nr   r   r   r   c              3   r   r   r   r   r   r   r   Z1EmojiMatcher._load_derived_age.<locals>.<genexpr>  s      =I5GTJJLL5Gr   ;..r   uversionz&Error while loading DerivedAge: %s: %s)zDerivedAge.txt)r   rC   r   r   r]   r   r*   r   r   r   r   	Exceptionr:   r   r   r   )r   r1   r2   r8   r   Zderived_age_filer   r   unicode_version	start_hexend_hexstartendr)   r   r   r   r   r   r   ZEmojiMatcher._load_derived_age  s    )'	 <!!},	1tg7 7:J,D>>#.q1779D !=I59ZZQ5G=I9( //-=-C-CD-I*	%(B%7Wb9Is&)*:B&??%*5'%:	'*9~*6)=)-=-== 33 .
OM	 &; -7 7 & ! !7 7 7,  	18((%1 1	1s_   E
 6D6/D$
A0D6?D6E
 $D3	/D62D3	3D66E	E
 E
 
F+FFc                r   r   r   rt   rv   r   r   rw     s     1 1D 1r   c           	     s   \         pRp\        W4      w  r4V'       d   Vf   R#  V! VRRR7      ;_uu_ 4       pV F  pVP                  R4      ^ ,          P                  4       pV'       g   K3   R VP	                  R^4       4       w  rxp	\        \        T^4      4      p
T
R3pYP                  9   g   K{  T P                  TR	TP                  4       .4       K  	  RRR4       R#   \
         d     K  i ; i  + '       g   i     R# ; i  \         d7   p\        P                  R
TP                  P                  T4        Rp?R# Rp?ii ; i)z,Loads alternative names from NameAliases.txtNr   r   r   r   c              3   r   r   r   r   r   r   r   Z2EmojiMatcher._load_name_aliases.<locals>.<genexpr>  s      @I5GTJJLL5Gr   r   r   r   z'Error while loading NameAliases: %s: %s)zNameAliases.txt)r   rC   r   r   r]   r   r   r*   r   r   r[   r   r:   r   r   r   )r   r1   r2   r8   r   Zname_aliases_filer   r   aliasZ_alias_typer   r   r   s   &            r   r   ZEmojiMatcher._load_name_aliases  sD   ((	 <!!},	1tg7 7:K-D>>#.q1779D !@I59ZZQ5G@I<( $'s+;R'@#AL&2D%9N%)9)99//*Gekkm_F .7 7 & ! !7 7 7   	19((%1 1	1s^   D 6C8/C&&C86&C8D &C5	1C84C5	5C88D		D 	D E+EEc                r   r   r   rt   rv   r   r   rw     s     01 01D 01r   c                s   \         pRp\        W4      w  r4V'       d   Vf   R#  V! VRRR7      ;_uu_ 4       p\        P                  ! V\        4       EF:  pVP                  4       P                  R4      p\        V4      ^8  d   K5  V^ ,          pV^,          p	V^,          p
V^
,          p\        \        V^4      4      pV
R9   d   Kw  V P                  '       g(   \        V
,          R,          '       g   V\        9  d   K  VR3pV P                  VRV	P                  4       .4       V'       d#   V P                  VRVP                  4       .4       V P                  VR	V
\        V
,          R
,          \        V
,          R,          .4       EK=  	  RRR4       R#   + '       g   i     R# ; i  \         d7   p\         P#                  RTP$                  P&                  T4        Rp?R# Rp?ii ; i)z*Loads character names from UnicodeData.txtNr   r   r   r   r   r   r   ucategoriesr   r   z'Error while loading UnicodeData: %s: %s)zUnicodeData.txt)r   r    r!   )r   rC   	itertoolschainUNICODE_DATA_EXTRA_LINESr   r]   r`   r   r*   r|   UNICODE_CATEGORIESVALID_CHARACTERSr   r[   r   r:   r   r   r   )r   r1   r2   r8   r   Zunicode_data_filer   fieldsr   r   categoryZold_namer   r   r   s   &              r   r   ZEmojiMatcher._load_unicode_data  s   ((	 <!!},(	1tg7 7:K%OO,=,DFD!ZZ\//4F6{R' '-ay$!!9D%ayH%bzH#&s+;R'@#AL#55 ! 222$6x$@$I$I ,4D D &2D%9N++&$**,A//*Ghnn6F5GI++&%$.x8A.x8A(CD9F7 7 7 7H  	19((%1 1	1sH   F1 B$FF7:F2A!FF1 F.	(F1 .F1 1G2<+G--G2c                r   r   r   rt   rv   r   r   rw     s     51 51$ 51r   c           	     s.   \         pRp\        W4      w  r4V'       d   Vf   R#  V! VRRR7      ;_uu_ 4       pVP                  4        EFT  pRp\        P                  ! R4      pVP                  V4      p	V	'       d)   V	P                  R4      '       d   V	P                  R4      pVP                  R4      ^ ,          P                  4       pV'       g   K   R VP                  R	^4       4       w  rR
T
9   d,   T
P                  R
4      w  r\        T^4      \        T^4      rM\        T
^4      ;r\        Y^,           4       FV  p\        T4      pTR3pT P                  TRT.4       T'       g   K0  T P                  TRT4       T P                  TRT4       KX  	  EKW  	  RRR4       R#   \         d     EKr  i ; i  + '       g   i     R# ; i  \         d7   p\         P#                  RTP$                  P&                  T4        Rp?R# Rp?ii ; i)zc
Loads emoji property data from emoji-data.txt

http://unicode.org/Public/emoji/5.0/emoji-data.txt
Nr   r   r   r$   eversionr   c              3   r   r   r   r   r.   r   r   r   Z8EmojiMatcher._load_unicode_emoji_data.<locals>.<genexpr>'        =C/A!GGII/Ar   r   r   r   r   r   z*Error while loading emoji-data.txt: %s: %s)zemoji-data.txtz9[^;]*;[^;]*#\s*E(?P<eversion>[0-9]+\.[0-9]+)\s*\[[0-9]+\])UNICODE_EMOJI_DATA_DIRNAMESrC   Z	readlinesr   r   r   r   r   r   r]   r   r*   r   r   r   r   r:   r   r   r   )r   r1   r2   r8   r   Zunicode_emoji_data_filer   emoji_versionpatternr   r   property_stringr   r   r   r   r)   r   r   r   s   &                   r   r   Z%EmojiMatcher._load_unicode_emoji_data  s    /'	 <!!},)	1tg7 7:Q3==?D$&M jj()G $MM$/EZ!8!8(-J(?>>#.q1779D !=C/3zz#q/A=C9( //-=-C-CD-I*	%(B%7Wb9Is&)*:B&??%*5q&%9	'*9~*6)=//*L?:KM(= 33 .
MK !33 .
MK &:+ @7 7  & ! !!7 7 7J  	1<((%1 1	1sl   G AF?>F?F?F,2A<F?3/F?"G ,F<	7F?;F<	<F??G	
G G H+HHc                r   r   r   rt   rv   r   r   rw   C  s     =1 =1t =1r   c                s   \         pRp\        W4      w  r4V'       d   Vf   R#  V! VRRR7      ;_uu_ 4       pV EF  pRp\        P                  ! R4      pVP	                  V4      p	V	'       d)   V	P                  R4      '       d   V	P                  R4      pVP                  R4      ^ ,          P                  4       pV'       g   K   R VP                  R	^4       4       w  rpTR
8X  d   K  T
R8X  d
   TR8X  d   RpRpT
P                  R4       F  pT\        \        T^4      4      ,          pK!  	  T'       g   EK  TR3pT P                  TRT.4       T P                  TRTP                  4       .4       T'       g   EKI  T P                  TRT4       TpT\        9   d   \        T,          R,          pT P                  TRT4       EK  	  RRR4       R#   \         d     EK  i ; i  + '       g   i     R# ; i  \         d7   p\         P#                  RTP$                  P&                  T4        Rp?R# Rp?ii ; i)zm
Loads emoji property data from emoji-sequences.txt

http://unicode.org/Public/emoji/5.0/emoji-sequences.txt
Nr   r   r   r$   r   r   c              3   r   r   r   r   r   r   r   Z=EmojiMatcher._load_unicode_emoji_sequences.<locals>.<genexpr>`  r   r   r   ZBasic_Emojiz0023 FE0F 20E3zkeycap:z	keycap: #rV   r   r   r   r   z/Error while loading emoji-sequences.txt: %s: %s)zemoji-sequences.txt?[^;]*;[^;]*;[^;]*#\s*E(?P<eversion>[0-9]+\.[0-9]+)\s*\[[0-9]+\]r   rC   r   r   r   r   r   r   r]   r   r   r*   r   r[   !EMOJI_VERSION_TO_UNICODE_VERSIONSr   r:   r   r   r   )r   r1   r2   r8   r   Zunicode_emoji_sequences_filer   r   r   r   
codepointsr   r   r   r)   r   r   r   r   r   r   Z*EmojiMatcher._load_unicode_emoji_sequencesC  s7    /,	 <!!},1	1$& & *F8D$&M jj()G $MM$/EZ!8!8(-J(?>>#.q1779D !=C/3zz#q/A=C9
T '-7 !%55$):K*#%L%/%5%5c%:	$C	2,>(?? &;#|*6)=//*L?:KM//*Gdjjl^E(= 33 .
MK
 /<O,0QQ2S$1333537 33 .
OMO 9	& &$ & ! !%& & &Z  	1A((%1 1	1ss   H AG->G-G-	G%AG-??G-AG-H G*	%G-)G*	*G--G>	8H >H I+H==Ic                r   r   r   rt   rv   r   r   rw     s     91 914 91r   c                sV   \         pRp\        W4      w  r4V'       d   Vf   R#  V! VRRR7      ;_uu_ 4       pV EFv  pRp\        P                  ! R4      pVP	                  V4      p	V	'       d)   V	P                  R4      '       d   V	P                  R4      pVP                  R4      ^ ,          P                  4       pV'       g   K   R VP                  R	^4       4       w  rpRpT
P                  R
4       F  pT\        \        T^4      4      ,          pK!  	  T'       g   K  TR3pT P                  TRT.4       T P                  TRTP                  4       .4       T'       g   EK/  T P                  TRT4       TpT\        9   d   \        T,          R,          pT P                  TRT4       EKy  	  RRR4       R#   \         d     EK  i ; i  + '       g   i     R# ; i  \         d7   p\         P#                  RTP$                  P&                  T4        Rp?R# Rp?ii ; i)zu
Loads emoji property data from emoji-zwj-sequences.txt

http://unicode.org/Public/emoji/5.0/emoji-zwj-sequences.txt
Nr   r   r   r$   r   r   c              3   r   r   r   r   r   r   r   ZAEmojiMatcher._load_unicode_emoji_zwj_sequences.<locals>.<genexpr>  r   r   r   rV   r   r   r   r   z3Error while loading emoji-zwj-sequences.txt: %s: %s)zemoji-zwj-sequences.txtr   r   r   )r   r1   r2   r8   r   Z unicode_emoji_zwj_sequences_filer   r   r   r   r   r   r   r   r)   r   r   r   r   r   r   Z.EmojiMatcher._load_unicode_emoji_zwj_sequences  s    /0	 <!!},-	1$& & *J<D$&M jj()G $MM$/EZ!8!8(-J(?>>#.q1779D !=C/3zz#q/A=C9
T $&L%/%5%5c%:	$C	2,>(?? &;#|*6)=//*L?:KM//*Gdjjl^E(= 33 .
MK
 /<O,0QQ2S$1333537 33 .
OMG =	& &$ & ! !%& & &R  	1E((%1 1	1sr   G' AG>GG	G %;G%?G*AG6G'  G	GG	GG$	G' $G' 'H(2+H##H(c                r   r   r   rt   rv   r   r   rw     s     b1 b1$ b1r   c                sH   \         pR/p\        W4      w  r4V'       d   Vf   R#  V! VRRR7      ;_uu_ 4       pRpRp^ pR\        R4      R\        R4      R	\        R4      R
\        R4      R\        R4      R\        R4      R\        R4      R\        R4      R\        R4      R\        R4      R\        R4      R\        R4      R\        R4      /p	R\        R4      /p
V EF  p\        P                  ! R4      pVP                  V4      pV'       d9   VP                  R4      '       d"   VP                  R4      P                  4       pKk  \        P                  ! R 4      pVP                  V4      pV'       d9   VP                  R!4      '       d"   VP                  R!4      P                  4       pK  Rp\        P                  ! R04      pVP                  V4      pV'       d7   VP                  R"4      '       d    VP                  R"4      P                  4       pVP                  R#4      ^ ,          P                  4       pV'       g   EKj   R$ VP                  R%^4       4       w  ppTR&8w  d   EK  T^,          pRpTP                  R'4       F  pT\        \        T^4      4      ,          pK!  	  T'       g   EK  TR(3pY,          .pYz9   d   TP                  Y,          4       T P                  TR)\        T4      4       T P                  TR*T4       T P!                  TT4       T'       d#   T P                  TR+TP#                  4       .4       T P%                  T4      R8X  d   \&        P)                  R,T4       T P+                  T4      R8X  g   EK  \&        P)                  R-T4       EK  	  RRR4       R#   \         d     EK  i ; i  + '       g   i     R# ; i  \,         d7   p\&        P/                  R.TP0                  P2                  T4        Rp?R# Rp?ii ; i)1zLoads emoji property data from emoji-test.txt

http://unicode.org/Public/emoji/4.0/emoji-test.txt

This is mostly for emoji sorting and for some categorization
Nr   r   r   r$   zSmileys & PeoplepeoplezSmileys & EmotionzPeople & BodyzAnimals & NaturenaturezFood & DrinkfoodzTravel & PlacestravelZ
ActivitiesactivityZObjectsobjectsZSymbolssymbolsZFlagsflagsZ	ModifiersmodifierZ	ComponentZRegionalregionalzperson-sportz# group:(?P<group>.+)$r   z# subgroup:(?P<subgroup>.+)$subgroupr   r   c              3   r   r   r   r   r   r   r   Z8EmojiMatcher._load_unicode_emoji_test.<locals>.<genexpr>  s      7C/A!GGII/Ar   r   zfully-qualifiedrV   r   
cldr_order
categoriesr   u;   Emoji “%s” lacks emoji version, this should not happen!u=   Emoji “%s” lacks Unicode version, this should not happen!z*Error while loading emoji-test.txt: %s: %s)zemoji-test.txtz<[^#]+#\s+\S+\s+E(?P<eversion>[0-9]+\.[0-9]+)\s+(?P<name>.+)$)r   rC   r   r   r   r   r   r   r   r]   r   r   r*   r   r   r   (_add_translated_categories_to_emoji_dictr[   r   r:   r@   r   r   r   r   r   )r   r1   r2   r8   r   Zunicode_emoji_test_filer   r  r  Zcldr_group_to_emojione_categoryZ"cldr_subgroup_to_emojione_categoryr   r   r   r   r   r   r   r)   r   r  r   s   &                     r   r   Z%EmojiMatcher._load_unicode_emoji_test  s    /'	 <!!},U	1tg7 7:Q
&8'H#R\&8"BvJ%r(| "Z.r)}r)}R[JJ:3/  #R
^62 4D jj)BCG#MM$/EW!5!5 %G 4 : : <  jj)HIG#MM$/EZ!8!8#(;;z#:#@#@#B D jj./G $MM$/EV!4!4${{6288:>>#.q1779D !7C/3zz#q/A7C3
O '*;; !!OJ#%L%/%5%5c%:	$C	2,>(?? &;#|*6)=&E&L%M
#I&-- B LN//*L#j/K//*L*FEE(*6 33 .$**,I--l;rA"NN ,E+79  //=C"NN ,E+79o 4/7 7^ & ! !_7 7 7b  	1<((%1 1	1s   O  C0O)AO9OA(O9AOO
N9&AO:COO/O  9O		OO			OO	O  O   P!++PP!c                r   r   r   rt   rv   r   r   rw   !  s     g* g*T g*r   c                s   \         \        3pRp\        W4      w  r4V'       d   Vf   R# V! VRRR7      ;_uu_ 4       p\        P                  ! V4      pRRR4       XP                  4        EFW  w  rxVR,          R,          p	RP                  V	P                  R4       U
u. uF  p
\        \        V
^4      4      NK  	  up
4      pVR	,          P                  4       p\        P                  ! R
RV4      P                  R4      pV.pVR,          P                  RR4      P                  R4      pVR,           Uu. uF$  pVP                  RR4      P                  R4      NK&  	  ppVR,          pW9  d
   W.,          pW9  d
   W.,          pVV,            F  pVV9  g   K  VV.,          pK  	  VR,          .p\        \!        \#        VR,          4      4      4      pRV9   d   VP%                  R4       VR,          pVR8X  d   Rp\'        V4      ^8X  d   VR9   d   R.pV\(        9   d   R.p\'        V4      ^8X  d   V^,          R8X  d   V^ ,          R9   d   . pV P+                  VR3RV4       V P+                  VR3RV4       V P+                  VR3RV4       V P+                  VR3RV4       V P-                  VV4       EKZ  	  R#   + '       g   i     EL; iu up
i u upi ) zS
Loads emoji names, aliases, keywords, and categories from
the emojione.json file.
Nr   r   r   Zcode_pointsZfully_qualifiedr$   Z-r   z	 ?[(,)] ?rV   	shortnamer   Z:Zshortname_alternatesZasciir   r   Zorderu   🏳🌈u   🏳‍🌈uh   🇦🇧🇨🇩🇪🇫🇬🇭🇮🇯🇰🇱🇲🇳🇴🇵🇶🇷🇸🇹🇺🇻🇼🇽🇾🇿r  r  r   z#*0123456789r   r   r  emoji_order)z
emoji.jsonzemojione.json)USER_DATADIRDATADIRrC   jsonZloaditemsr9   r]   r   r*   r[   r   subr   r^   r_   r   r\   Zremover`   r   r   r	  )r   r1   r2   r8   r   Zemoji_one_fileZemojioneZdummy_emojione_keyZemojione_valuer   r)   r   display_nameZ
match_namer   r
  r.   ZaliasesZascii_aliasesr   r  r   r  s   &                      r   r   Z EmojiMatcher._load_emojione_data!  s    
 !'* 4	 <!!},4'3 36Dyy0H3 3;..2B.'67HIJ779C9I9I#9N$9NIC	2&'9N$ L *&1779LdLAGGLJ!NE&$WS#.uuSz  !//E FH F1 yyc*005 F  H*73M&%%$ =00%eW$E 1 )45J d3~j'A#BCDHX~ #(1Kz)
  0L!Q&$  )S  S )\
22 )\
L!Q&<?h+F$Q>9  
##t$gu6##t$lJ@##t$j(<##t$m[B 99j*k 3C3 3 3$$Hs   K
 K
9*K#
K	c                s:   < V ^8  d   QhRS[ RS[S[ ,          RR/# )r
   r   r  r   Nr   r   rt   rv   r   r   rw     s)     29 29 #2915c29?C29r   c                s   \        R4      \        R4      \        R4      \        R4      \        R4      \        R4      \        R4      \        R4      \        R	4      \        R
4      .
p\        P                  ! V P                  4       F  pV P                  V,          '       g   K  V P                  V,          P
                  p. pV F  pV! V4      pVP                  V4       VR8X  g   K%  \        '       g   K3  \        VRR7      p	W8w  d   VP                  V	4       V P                  '       g   Kk  \        VRR7      P                  4       p
W8w  g   K  VP                  V
4       K  	  V P                  W3RV4       K  	  R# )z
Add translated versions of categories for an emoji
to self._emoji_dict

:param emoji_string: An emoji
:param categories: The categories of the emoji
r   r  r   r  r   r  r   r  r  r   jahirar"   hepburnr  N)r   rI   rJ   ry   rz   r   r   r%   r(   r   r[   r   )r   r   r  Z_dummy_categories_to_translaterD   Z
translatorZtranslated_categoriesr   Z
translatedhiraganarr   s   &&&        r   r	  Z5EmojiMatcher._add_translated_categories_to_emoji_dict  s=    zNwKvJzNxLyMxLzNyMxL)*
&. !11$//BH))(33!77AII
(*% *H!+H!5J)00<4',F,F#1*V#L#1188B<<<%3 *9&>>Ceg #%3 5 < <V D !+ ''!, "79! Cr   c                s*   < V ^8  d   QhRS[ RS[ RR/# )r
   rD   r3   r   Nr   rt   rv   r   r   rw     s'     F1 F13 F1 F1 F1r   c           
     s   \         pVR,           3p\        W4VR7      w  rVV'       d   Vf   R# \        P                  P	                  V4      P                  RR4      P                  RR4      P                  RR4      P                  RR4      pVP                  R4      pVR9   ;'       d    \        pVR	8H  ;'       d    \        p	 V! VR
RR7      ;_uu_ 4       p
\        P                  ! R4      pV
 EF  pVP                  V4      pV'       g   K  VP                  R4      pW3p\        P                  ! VP                  R4      4      pVR8X  d   Ka  V'       d   VP                  4       pVP                  R4      '       d   VP!                  4       .pRpM0VP#                  R4       Uu. uF  pVP!                  4       NK  	  ppRpV'       d8   V F.  p\$        P&                  ! V4      pV P)                  VVVV.4       K0  	  EK  V	'       d}   V F%  p\+        VRR7      pV P)                  VVVV.4       K'  	  V P,                  '       d=   V F3  p\+        VRR7      P                  4       pV P)                  VVVV.4       K5  	  EK  EK  V P)                  VVV4       EK  	  RRR4       R# u upi   + '       g   i     R# ; i  \.         d7   p\0        P3                  RTP4                  P6                  T4        Rp?R# Rp?ii ; i)zL
Loads emoji name translations and keywords from CLDR XML annotation files.
rE   rG   Nr4   r$   r5   r6   r   r  r   r   r   Zemojistringcontentu	   ↑↑↑Zttsr   Z|r   r  r  r  z0Error while loading cldr annotation data: %s: %s)ZzhZzh_Hantzh.*<annotation cp="(?P<emojistring>[^"]+)"\s*(?P<tts>type="tts"){0,1}[^>]*>(?P<content>.+)</annotation>.*)rH   rC   r7   r8   rA   r^   rK   IMPORT_PINYIN_SUCCESSFULr%   r   r   r   r   htmlZunescaper[   r   r]   pinyingetr   r(   r   r   r:   r   r   r   )r   rD   r3   r1   r2   r8   r   Z
is_englishZ
add_pinyinZadd_japanese_phoneticsZcldr_annotation_filer   r   r   r   r   r  Zcontent_partsrQ   r   Z
pinyin_strr  rr   r   s   &&&                     r   r   Z'EmojiMatcher._load_cldr_annotation_data  s    ,&(	 <!0}, 77##D)112w#G2&w $ 	
 ((.
!22OO7O
!)T!1!P!P6P1	1tg7 7:N**( 1D#MM$/E  #(;;}#=L&2%=N"mmEKK	,BCG+- !")--/{{5)))0(9 'BI--PSBT(UBT$BT(U *!$1D)/D)9J 33 .j7IK %2 0$1D'5d6'JH 33 .h7GI %2  <<<(5)7$(*<<AEG !' $ 7 7$2ED&>!K )6 ( //*E=BE 17 70 )V17 7 7Z  	1B((%1 1	1sh   K BJ/&J/'J/(J*
J/>J/<J/	AJ/ K *J//K 	:K  K L+K??Lc                \   < V ^8  d   QhRS[ RS[RS[ RS[RS[S[P
                  ,          /# r
   query_stringmatch_limittrigger_characters
spellcheckr   r   r*   r+   r   rI   PredictionCandidatert   rv   r   r   rw     sO     { {{ { !$	{
 {
 *.h.J.J)K{r   c                s    WW43V P                   9   d   V P                   WW43,          # V P                  VVVVR7      pVV P                   VVVV3&   V# )uV#  
Find a list of emoji which best match a query string.

:param query_string: A search string
:param match_limit: Limit the number of matches to this amount
:return: List of emoji which best match the query string

Returns a list of tuples of the form (<emoji>, <name>, <score),
        i.e. a list like this:
        [('🎂', 'birthday cake', 3106), ...]

Examples:

>>> mq = EmojiMatcher(languages = ['en_US', 'it_IT', 'es_MX', 'es_ES', 'de_DE', 'ja_JP'])

If the query string is an emoji itself, similar emoji are returned:

>>> matches = mq.candidates('😺', match_limit=3)
>>> matches[0].phrase
'😺'
>>> matches[0].comment
'smiling cat face with open mouth [😺, So, people, cat, face, mouth, open, smile, uc6, animal, grinning, smiling]'
>>> matches[0].user_freq
12.0
>>> matches[1].phrase
'😸'
>>> matches[1].comment
'grinning cat face with smiling eyes [So, people, cat, face, smile, uc6, animal, grinning, smiling]'
>>> matches[1].user_freq
9.0
>>> matches[2].phrase
'😅'
>>> matches[2].comment
'smiling face with open mouth and cold sweat [So, people, face, open, smile, uc6, grinning, mouth, smiling]'
>>> matches[2].user_freq
9.0

It works in different languages:

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('ネコ＿')[0]
>>> first_match.phrase
'🐈'
>>> first_match.comment
'ネコ'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('ネコ＿')[0]
>>> first_match.phrase
'🐈'
>>> first_match.comment
'ネコ'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('ant')[0]
>>> first_match.phrase
'🐜'
>>> first_match.comment
'ant'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('ant')[0]
>>> first_match.phrase
'🐜'
>>> first_match.comment
'ant'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('ameise')[0]
>>> first_match.phrase
'🐜'
>>> first_match.comment
'Ameise'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('ameise')[0]
>>> first_match.phrase
'🐜'
>>> first_match.comment
'Ameise'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('formica')[0]
>>> first_match.phrase
'🐜'
>>> first_match.comment
'formica [formichina]'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('formica')[0]
>>> first_match.phrase
'🐜'
>>> first_match.comment
'formica'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('hormiga')[0]
>>> first_match.phrase
'🐜'
>>> first_match.comment
'hormiga'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('hormiga')[0]
>>> first_match.phrase
'🐜'
>>> first_match.comment
'hormiga'

Any white space and '_' can be used to separate keywords in the
query string:

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('gatto sorride')[0]
>>> first_match.phrase
'😺'
>>> first_match.comment
'gatto che sorride [sorridente]'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('gatto sorride')[0]
>>> first_match.phrase
'😺'
>>> first_match.comment
'gatto che sorride'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('gatto_  sorride')[0]
>>> first_match.phrase
'😺'
>>> first_match.comment
'gatto che sorride [sorridente]'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('gatto_  sorride')[0]
>>> first_match.phrase
'😺'
>>> first_match.comment
'gatto che sorride'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('nerd glasses')[0]
>>> first_match.phrase
'🤓'
>>> first_match.comment
'nerd face [glasses]'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('nerd glasses')[0]
>>> first_match.phrase
'🤓'
>>> first_match.comment
'nerd face [glasses]'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('smiling face with sunglasses')[0]
>>> first_match.phrase
'😎'
>>> first_match.comment
'smiling face with sunglasses'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('smiling face with sunglasses')[0]
>>> first_match.phrase
'😎'
>>> first_match.comment
'smiling face with sunglasses'

ASCII emoji match as well:

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates(':-)')[0]
>>> first_match.phrase
'🙂'
>>> first_match.comment
'slightly smiling face “:)”'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates(':-)')[0]
>>> first_match.phrase
'🙂'
>>> first_match.comment
'slightly smiling face “:-)”'

The query string can contain typos:

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('buterfly', spellcheck=True)[0]
>>> first_match.phrase
'🦋'
>>> first_match.comment
'butterfly'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('buterfly', spellcheck=True)[0]
>>> first_match.phrase
'🦋'
>>> first_match.comment
'butterfly'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('badminton')[0]
>>> first_match.phrase
'🏸'
>>> first_match.comment
'Badminton'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('badminton')[0]
>>> first_match.phrase
'🏸'
>>> first_match.comment
'Badminton'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('badminton')[0]
>>> first_match.phrase
'🏸'
>>> first_match.comment
'Badminton'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('badminton')[0]
>>> first_match.phrase
'🏸'
>>> first_match.comment
'Badminton'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('badmynton', spellcheck=True)[0]
>>> first_match.phrase
'🏸'
>>> first_match.comment
'Badminton'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('badmynton', spellcheck=True)[0]
>>> first_match.phrase
'🏸'
>>> first_match.comment
'Badminton'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('padminton', spellcheck=True)[0]
>>> first_match.phrase
'🏸'
>>> first_match.comment
'Badminton'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('padminton', spellcheck=True)[0]
>>> first_match.phrase
'🏸'
>>> first_match.comment
'Badminton'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('hedgehgo', spellcheck=True)[0]
>>> first_match.phrase
'🦔'
>>> first_match.comment
'hedgehog'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('hedgehgo', spellcheck=True)[0]
>>> first_match.phrase
'🦔'
>>> first_match.comment
'hedgehog'

Non-emoji Unicode characters can be matched as well, as emoji
are preferred, the first match might be an emoji if there is a
suitable one:

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match, second_match = mq.candidates('euro sign')[:2]
>>> first_match.phrase
'💶'
>>> first_match.comment
'banknote with euro sign'
>>> second_match.phrase
'€'
>>> second_match.comment
'euro sign'
>>> first_match = mq.candidates('integral surf')[0]
>>> first_match.phrase
'∯'
>>> first_match.comment
'surface integral'
>>> mq.set_match_algorithm('classic')
>>> first_match, second_match = mq.candidates('euro sign')[:2]
>>> first_match.phrase
'💶'
>>> first_match.comment
'banknote with euro sign'
>>> second_match.phrase
'€'
>>> second_match.comment
'euro sign'
>>> first_match = mq.candidates('integral surf')[0]
>>> first_match.phrase
'∯'
>>> first_match.comment
'surface integral'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('superscript one')[0]
>>> first_match.phrase
'¹'
>>> first_match.comment
'superscript one'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('superscript one')[0]
>>> first_match.phrase
'¹'
>>> first_match.comment
'superscript one'

Unicode code points can be used in the query:

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('2019')[0]
>>> first_match.phrase
'’'
>>> first_match.comment
'U+2019 right single quotation mark'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('2019')[0]
>>> first_match.phrase
'’'
>>> first_match.comment
'U+2019 right single quotation mark'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('41')[0]
>>> first_match.phrase
'A'
>>> first_match.comment
'U+41 latin capital letter a'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('41')[0]
>>> first_match.phrase
'A'
>>> first_match.comment
'U+41 latin capital letter a'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('2a')[0]
>>> first_match.phrase
'*'
>>> first_match.comment
'U+2A asterisk'
>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('2a')[0]
>>> first_match.phrase
'*'
>>> first_match.comment
'U+2A asterisk'

>>> mq.set_match_algorithm('rapidfuzz')
>>> first_match = mq.candidates('1b')[0]
>>> first_match.phrase
'\x1b'
>>> first_match.comment
'U+1B'

>>> mq.set_match_algorithm('classic')
>>> first_match = mq.candidates('1b')[0]
>>> first_match.phrase
'\x1b'
>>> first_match.comment
'U+1B'
)r  r   r!  r"  )r   _candidates)r   r  r   r!  r"  
candidatess   &&&&& r   r&  ZEmojiMatcher.candidates  s    Z (:G$$%((+=*K L L%%%#1!	 & #
 &	 		 	
 r   c                r  r  r#  rt   rv   r   r   rw     sO     g! g!g! g! !$	g!
 g!
 *.h.J.J)Kg!r   c           	     s  a aaa VR ,          '       d   VR ,          V9   d
   VR,          pVR*R '       d   VR*R V9   d   VRR* pV'       g   . # S P                  VRR7      p\        P                  ! RRV4      pVR3S P                  9   d   S P	                  WR7      pV# TpV'       Ed   VP                  RR	7       F  o\        S4      ^8  g   K  \        '       g   K#  SP                  4       o\        ;QJ d*    VV3R
 lS P                   4       F  '       g   K   RM	  RM! VV3R
 lS P                   4       4      '       d   K  S P                   UUu0 uF=  pVP                  S4       F%  p\        V4      ^8  g   K  VP                  4       kK'  	  K?  	  p	ppVRRP                  V	4       2,          pK  	  \        P                  ! VP                  4       4      p. pS P                  P!                  4        EF  w  op
V'       ga   \        ;QJ d.    VV 3R lVP                  4        4       F  '       g   K   RM#	  RM! VV 3R lVP                  4        4       4      '       d   Ko  RpRpRpRpRpRpV
P#                  R. 4       FC  pS P%                  VV4      pV'       g   VS P&                  8  d   Tp\)        VRV,          4      pKE  	  V
P#                  R. 4       F4  pS P%                  VV4      pVS P&                  8  d   Tp\)        VV4      pK6  	  V
P#                  R. 4       F4  pS P%                  VV4      pVS P&                  8  d   Tp\)        VV4      pK6  	  V
P#                  R. 4       F4  pS P%                  VV4      pVS P&                  8  d   Tp\)        VV4      pK6  	  V
P#                  RR4      pV'       d2   S P%                  VV4      pVS P&                  8  d   Tp\)        VV4      p\        ;QJ d&    V 3R lS^ ,           4       F  '       g   K   RM	  RM! V 3R lS^ ,           4       4      '       d
   VR,          pV^ 8  g   EK^  RV
9   d   V
R,          ^ ,          pMS P+                  S^ ,          4      p\        S^ ,          4      ^8X  dB   \        P,                  ! S^ ,          4      '       d   R\/        S^ ,          4      R R2V,           pVV9  d   VRV,           R,           ,          pVV9  d   VRV,           R,           ,          pVV9  d   VRV,           R,           ,          pVV9  d   VRV,           R,           ,          pVV9  d   VRV,           R,           ,          pVP1                  \        P2                  ! S P                  S^ ,          S P4                  4      VVR7      4       EK  	   \7        V^4      p^ Tu;8:  d   R 8:  d   M MR!Tu;8:  d   R"8:  g   M R#Tu;8:  d   R$8:  g   M R%Tu;8:  d   R&8:  g   M \9        V4      pS P+                  V4      pV'       g&    \:        P*                  ! V4      P                  4       pV'       d
   RV,           pVP1                  \        P2                  ! VS P&                  R',          RVP?                  4        V 2R7      4       \A        VV 3R( lR)7      RV pV# u uppi   \<        3 d     Li ; i  \<        3 d     L<i ; i)+:N   N:r'  NNNr$   r   u	   [＿_\s]+rV   r   )r   rW   c              3   sx   <"   T F/  pVP                  S4      ;'       g    VP                  S4      x  K1  	  R # 5ir   )Zcheck)r   dicrc   
word_titles   & r   r   +EmojiMatcher._candidates.<locals>.<genexpr>  s4      ?*=3  #yyGG#))J2GG*=s   ::TFc              3   s   <a"   T F]  o\         ;QJ d.    V3R  lSP                  S4       4       F  '       d   K   RM#	  RM! V3R  lSP                  S4       4       4      x  K_  	  R# 5i)c              3   s.   <"   T F
  pSV9  x  K  	  R # 5ir   r   )r   rQ   token   & r   r   Z5EmojiMatcher._candidates.<locals>.<genexpr>.<genexpr>  s      N)L ".)Ls   FTN)Zallget_all_label_words)r   r+  	emoji_keyr   s   &@r   r   r*    s`      ;%9E  N)-)A)A))LN N)-)A)A))LN N N%9s   A)#A)/A)rU   r   g       @r   r  r   r   c              3   sL   <"   T F  pR SP                  V4      9   x  K  	  R# 5i)r   N)r   )r   r   r   r,  r   r   r*    s     W,Y7dooi88,s   !$g      @U+04Xu    “u   ”z {Z} []phrase	user_freqcommenti i   i  i   i i   i g      $@c                 s   < V P                   ) SP                  V P                  4      \        V P                  4      ) V P                  3# r   )r5  r  r4  r`   r6  r.   r      &r   <lambda>Z*EmojiMatcher._candidates.<locals>.<lambda>#  s5    ++)ahh-			r   rX   r   )!r   r   r  r   similarr]   r`   r   Ztitler,   r   Zsuggestr[   r9   rI   rZ   r  r  r   r   Zmaxr   is_invisibleordr   r$  r   r*   r   unicodedatar   Zupperr_   )r   r  r   r!  r"  r&  rR   r(  r.   Zsuggestionsemoji_valuerb   Zname_good_matchZucategory_good_matchZcategory_good_matchZkeyword_good_matchZblock_good_matchr   scoreZ	ucategoryr   Zkeywordr   r  r)   ZcharZsorted_candidatesr.  rc   r)  s   f&&&&                      @@@r   r%  ZEmojiMatcher._candidates  s\    R 04F F'+Lbc!26H!H',LI 88R 9 1 vvlC>$4#3#33lLJ#:$**t*4 t9q=%>%>!%J3 ?*.*=*=?333 ?*.*=*=? ? ?
 (,':':'':%([[%6"1vz &AGGI%6 &': $ ' %!CHH[,A+B(CC# 5$  ..|/A/A/CD
&*&6&6&<&<&>"I{C ;%1%7%7%9;CCC ;%1%7%7%9; ; ; K O#% "$!#!#4,,T<@&5D4J4J+J&*O!+sU{;	 5
 )__]B?	,,YED222+4(!+u5	 @
 (OOL"=,,X|DD222*2'!+u5	 >
 '??:r:,,WlCD222)0&!+u5	 ;
  OOGR0E,,ULAD222',$!+u5sW)TU,WsssW)TU,WWWs"Qk)#.w#7#:L#'99Yq\#:L	!%*$11)A,?? ')Yq\):3(?q$A&2%3L #,6 F_$<u$DDL'|; D+?$?#$EEL&l: D+>$>$DDL%\9 D+=$=$CCL#<7 D+;$;c$AAL!!(">"><<!!002 *(#* +[ '?h	L"-Iy,H,"i969#y;G;$	=X=9~yy*//5;;= :D!!(">">"44t; !3!3!5 6tf=#? @ #  ! {'R '=  } 		sP   &[[[- &A[- >$[ "[- *A[- [*'[- )[**[- -[<;[<c                sL   < V ^8  d   QhRS[ S[S[3,          RS[S[,          /# )r
   r.  r   )r   r   r   rt   rv   r   r   rw   :  s'     
 
U38_ 
S 
r   c                s  a V P                   P                  VR4      oSf   \        4       # . ROp\        P                  ! \        P                  P                  V3R lV 4       4      SP                  RR4      .4      pV UUu0 uFG  qD'       g   K  VP                  4       P                  4        F  p\        P                  ! V4      kK  	  KI  	  upp# u uppi )z+Returns all words in all labels of an emojiNc              3   sH   <"   T F  pSP                  V. 4      x  K  	  R # 5ir   )r  )r   Zfieldr?  r,  r   r   Z3EmojiMatcher.get_all_label_words.<locals>.<genexpr>B  s     @++s   "r   r$   )r   r   r  r   )
r   r  r\   r   r   Zfrom_iterabler[   r]   rI   rZ   )r   r.  r   Z
all_labelsrQ   rc   r?  s   &&    @r   r-  Z EmojiMatcher.get_all_label_words9  s     &&**9d;5LC__OO))@@B__Wb)*,
 $
#u *++- ##D)- *#
 	
 
s   	C?Cc                <   < V ^8  d   QhRS[ RS[ RS[S[ ,          /# r
   r   rD   r   r  rt   rv   r   r   rw   J  s&     + +# + +d3i +r   c                s   V P                  VRR7      pV'       d7   \        V P                  P                  W3/ 4      P                  R. 4      4      # \        P
                  ! V P                  4       FE  p\        V P                  P                  W3/ 4      P                  R. 4      4      pV'       g   KC  Vu # 	  \        V4      ^8X  d'    \        P                  ! V4      P                  4       .# . #   \         d    . u # i ; i)u  Find the names of an emoji

Returns a list of names of the emoji in the language requested
or and empty list if no name can be found in that language.

If no language is requested, the list of names is returned in
the first language of this EmojiMatcher for which a list of
names can be found.

:param emoji_string: The string of Unicode characters which are
                     used to encode the emoji
:param language: The language requested for the name

Examples:

>>> matcher = EmojiMatcher(languages = ['en_US', 'it_IT', 'es_MX', 'es_ES', 'de_DE', 'ja_JP'])
>>> matcher.names('🙂')
['slightly smiling face', 'slight smile', ':)', ':-)', '=]', '=)', ':]']

>>> matcher.names('🙂', language='it')
['faccina con sorriso accennato']
r$   r   r   )r   r   r   r  rI   rJ   ry   r`   r>  r   r[   r   )r   r   rD   rL   r      &&&  r   r   ZEmojiMatcher.namesJ  s    8 88R 9 1((,,("..1c'2.>@ @!224??CI))--)2//2s7B/?AEu	 D
 |!#((6<<>?? 	  	s   $C3 3DDc                r   rB  r   rt   rv   r   r   rw   w  s'     J J J JS Jr   c                sL    V P                  WR7      pV'       d
   V^ ,          # R# )u  Find the main name of an emoji.

Returns a name of the emoji in the language requested
or and empty string if no name can be found in that language.

If no language is requested, the name is returned in the first
language of this EmojiMatcher for which a name can be
found.

:param emoji_string: The string of Unicode characters which are
                     used to encode the emoji
:param language: The language requested for the name

Examples:

>>> matcher = EmojiMatcher(languages = ['en_US', 'it_IT', 'es_MX', 'es_ES', 'de_DE', 'ja_JP'])

>>> matcher.name('🏸')
'badminton racquet and shuttlecock'

>>> matcher.name('🖥')
'desktop computer'

>>> matcher = EmojiMatcher(languages=['es_MX', 'es_ES', 'it_IT', 'ja_JP'])
>>> matcher.name('🖥')
'computadora de escritorio'

>>> matcher = EmojiMatcher(languages=['es_ES', 'es_MX', 'it_IT', 'ja_JP'])
>>> matcher.name('🖥')
'ordenador de sobremesa'

>>> matcher = EmojiMatcher(languages=['de_DE', 'es_ES', 'es_MX', 'it_IT', 'ja_JP'])
>>> matcher.name('🖥')
'Desktopcomputer'

>>> matcher = EmojiMatcher(languages=['it_IT', 'es_ES', 'es_MX', 'ja_JP'])
>>> matcher.name('🖥')
'computer fisso'

>>> matcher = EmojiMatcher(languages=['fr_FR'])
>>> matcher.name('🖥')
'ordinateur de bureau'

>>> matcher.name('🤔')
'visage en pleine réflexion'

>>> matcher = EmojiMatcher(languages=['de_DE'])
>>> matcher.name('🤔')
'nachdenkendes Gesicht'

>>> matcher.name('⚽')
'Fußball'

>>> matcher = EmojiMatcher(languages=['de_CH'])
>>> matcher.name('🤔')
'nachdenkendes Gesicht'

>>> matcher.name('⚽')
'Fussball'

Fallback from unicodedata.name('a'):

>>> matcher.name('a')
'latin small letter a'

>>> matcher.name(' ')
'space'
)rD   r$   )r   )r   r   rD   r   s   &&& r   r   ZEmojiMatcher.namew  s$    N 

<
;8Or   c                rA  rB  r  rt   rv   r   r   rw     s&     & &S &C &c &r   c                z   V P                  VRR7      pV'       d7   \        V P                  P                  W3/ 4      P                  R. 4      4      # \        P
                  ! V P                  4       FE  p\        V P                  P                  W3/ 4      P                  R. 4      4      pV'       g   KC  Vu # 	  . # )u  Return the keywords of an emoji

Returns a list of keywords of the emoji in the language requested
or an empty list if no keywords can be found in that language.

If no language is requested, the list of keywords is returned in
the first language of this EmojiMatcher for which a list of
keywords can be found.

:param emoji_string: The string of Unicode characters which are
                     used to encode the emoji
:param language: The language requested for the name

Examples:

>>> matcher = EmojiMatcher(languages = ['en_US', 'it_IT', 'es_MX', 'es_ES', 'de_DE', 'ja_JP'])
>>> matcher.keywords('🙂')
['face', 'smile', 'uc7', 'happy', 'slightly', 'smiling']

>>> matcher.keywords('🙂', language='it')
['contento', 'faccina', 'faccina che sorride', 'faccina con sorriso accennato', 'felice', 'mezzo sorriso', 'ok', 'sorrisetto', 'sorriso', 'sorriso a bocca chiusa', 'sorriso accennato', 'va bene']
r$   r   r   r   r   r   r  rI   rJ   ry   )r   r   rD   rL   r   rC  r   r   ZEmojiMatcher.keywords  s    8 88R 9 1((,,("..1c*b.AC C!224??CID,,00!-r3363z23FHHx	 D
 	r   c                rA  rB  r  rt   rv   r   r   rw     s&     # #s #c #49 #r   c                rD  )u{  Return the categories of an emoji

Returns a list of categories of the emoji in the language requested
or and empty list if no categories can be found in that language.

If no language is requested, the list of categories is returned in
the first language of this EmojiMatcher for which a list of
categories can be found.

:param emoji_string: The string of Unicode characters which are
                     used to encode the emoji
:param language: The language requested for the name

Examples:

>>> matcher = EmojiMatcher(languages = ['en_US', 'it_IT', 'es_MX', 'es_ES', 'de_DE', 'ja_JP'])
>>> matcher.categories('🙂')
['people']
r$   r   r  rE  )r   r   rD   rL   r  rC  r   r  ZEmojiMatcher.categories  s    2 88R 9 1((,,("..1c,.CE E!224??CId..22)2//2s</DFJz!!	 D
 	r   c          	      sV   < V ^8  d   QhRS[ RS[RS[RS[S[P
                  ,          /# )r
   r   r   show_keywordsr   r#  rt   rv   r   r   rw   	  sD     e ee e  	e ,00L0L+M	er   c           	     s  a aa S P                  VRR7      p/ p/ p\        P                  ! S P                  4      oRpS F  p\	        4       WW&   W3pVS P
                  9  d   K%  V Fl  p	V	S P
                  V,          9   g   K  S P
                  V,          V	,           F1  p
WW,          P                  V
4       V	R8X  g   K#  V
\        9   g   K0   Kj  	  Kn  	  K  	  S P
                  P                  4        EF  w  rV^ ,          pV^,          pRV9   d   VR,          ^ ,          pMS P                  V4      p\        V4      ^8X  d4   \        P                  ! V4      '       d   R\        V4      R R2V,           pWV3pW8X  d!   S P                  VS P                  R7      .WO&   V FM  p	W9   g   K  W,           F6  p
WV,          9   g   K  W9   d   WO,          P                  V
4       K1  V
.WO&   K8  	  KO  	  EK  	  . pS P                  V4      o\!        VP                  4       VVV 3R lR	7      R
V  F  pS P                  V^ ,          ^ ,          S P                  R7      pV'       d=   V^ ,          ^,          R,           RP#                  V^,          4      ,           R,           pMV^ ,          ^,          p\        V^,          4      pVP                  \        P$                  ! V\'        V4      VR7      4       K  	  V# )uh  Find similar emojis

“Similar” means they share categories or keywords.

:param emoji_string: The string of Unicode  characters which are
                     used to encode the emoji
:param match_limit: Limit the number of matches to this amount
:param show_keywords: Whether the list of keywords and categories which
                      matched should be included in the names of the
                      ressults.
:return: List of similar emoji
        A list of tuples of the form (<emoji>, <name>, <score>),
        i.e. a list like this:

        [('🐫', "cammello ['🐫', 'gobba', 'animale']", 3), ...]

        The name includes the list of categories or keywords
        which matched, the score is the number of categories
        or keywords matched.

        The list is sorted by preferred language, then score,
        then name.

Examples:

>>> matcher = EmojiMatcher(languages = ['en_US'])

>>> matcher.similar('this is not an emoji', match_limit = 5)
[]

>>> matches = matcher.similar('☺', match_limit = 5)
>>> matches[0].phrase
'☺️'
>>> matches[0].comment
'white smiling face [☺️, So, people, face, outlined, relaxed, smile, uc1, happy, smiling]'
>>> matches[0].user_freq
10.0
>>> matches[1].phrase
'🥲'
>>> matches[1].comment
'smiling face with tear [So, people, face, happy, smile, smiling]'
>>> matches[1].user_freq
6.0
>>> matches[2].phrase
'😇'
>>> matches[2].comment
'smiling face with halo [So, people, face, smile, happy, smiling]'
>>> matches[2].user_freq
6.0
>>> matches[3].phrase
'🙂'
>>> matches[3].comment
'slightly smiling face [So, people, face, smile, happy, smiling]'
>>> matches[3].user_freq
6.0
>>> matches[4].phrase
'😆'
>>> matches[4].comment
'smiling face with open mouth and tightly-closed eyes [So, people, face, smile, happy, smiling]'
>>> matches[4].user_freq
6.0

>>> matcher = EmojiMatcher(languages = ['it_IT'])
>>> matches = matcher.similar('☺', match_limit = 5)
>>> matches[0].phrase
'☺️'
>>> matches[0].comment
'faccina sorridente [☺️, contorno faccina sorridente, delineata, emozionarsi, faccina, felice, rilassata, sorridente]'
>>> matches[0].user_freq
8.0
>>> matches[1].phrase
'😊'
>>> matches[1].comment
'faccina con occhi sorridenti [faccina, felice]'
>>> matches[1].user_freq
2.0
>>> matches[2].phrase
'🙂'
>>> matches[2].comment
'faccina con sorriso accennato [faccina, felice]'
>>> matches[2].user_freq
2.0
>>> matches[3].phrase
'😂'
>>> matches[3].comment
'faccina con lacrime di gioia [faccina, felice]'
>>> matches[3].user_freq
2.0
>>> matches[4].phrase
'😃'
>>> matches[4].comment
'faccina con sorriso e occhi spalancati [felice, sorridente]'
>>> matches[4].user_freq
2.0

Some symbols which are not emoji work as well:

>>> matcher = EmojiMatcher(languages = ['es_ES',  'it_IT', 'es_MX', 'de_DE', 'en_US', 'ja_JP'])
>>> matches = matcher.similar('€', match_limit = 5)
>>> matches[0].phrase
'€'
>>> matches[0].comment
'euro [€, divisa, EUR, euro, moneda]'
>>> matches[0].user_freq
5.0
>>> matches[1].phrase
'£'
>>> matches[1].comment
'libra esterlina [divisa, moneda]'
>>> matches[1].user_freq
2.0
>>> matches[2].phrase
'₽'
>>> matches[2].comment
'rublo [divisa, moneda]'
>>> matches[2].user_freq
2.0
>>> matches[3].phrase
'₹'
>>> matches[3].comment
'rupia india [divisa, moneda]'
>>> matches[3].user_freq
2.0
>>> matches[4].phrase
'¥'
>>> matches[4].comment
'yen [divisa, moneda]'
>>> matches[4].user_freq
2.0
r$   r   r   r   r/  r0  rV   c                 sR  < SP                  V ^ ,          ^,          4      \        V ^,          4      ) \        SP                  V ^ ,          ^ ,          4      S,
          4      5SP                  V ^ ,          ^ ,          4      \        V ^ ,          ^ ,          4      ) V ^ ,          ^,          3# )i    )r   r`   Zabsr  )csicldr_order_emoji_stringexpanded_languagesr   s   &r   r9  Z&EmojiMatcher.similar.<locals>.<lambda>	  s    &,,SVAY7#a&kM$//#a&)434 5 5OOCF1I.#a&)n$F1I	!r   r:  Nr1  , r2  r3  )r   r  r   )r   rI   rJ   ry   r\   r   Zaddr   r  r   r`   r<  r=  r   r   r  r_   r9   r$  rT   )r   r   r   rF  Zcandidate_scoresZoriginal_labels
label_keysrD   r.  	label_keyrQ   Zsimilar_keyZsimilar_key_valueZsimilar_stringZsimilar_nameZ
scores_keyr&  rG  r   r   r@  rH  rI  s   f&&&                 @@r   r;  ZEmojiMatcher.similar	  s   X 88R 9 1BD/1%66tG>
*H(+O%%0I 0 00'	 0 0 ;;!%!1!1)!<Y!G!G'155e<%6$)-?$? "# "H ( +2 /3.>.>.D.D.F*K(^N"1~H++09!<#yy8N#q( --n== #%S%8$=Q ?".!/ ,8J- 55$+/+C+C 6 E0F , (	1!2!=!= H$==)= 0 < C CE J@Ew 0 < "> (5 /GD :<
"&//,"? &&(	  K!C 55Aq	#'#;#; 6 =E 1vay4'$))CF*;;cA1vayAKEh::edD E)!, r   c          	      sr   < V ^8  d   QhRS[ S[S[ S[S[ S[S[S[,          3,          3,          3,          /# r   )r   r   r   rt   rv   r   r   rw   	  s8     A# A#S$sDd3i4H/H*I%I J A#r   c                s  a  Rp/ pV EF  pS P                   P                  4        EFy  w  rES P                  V^ ,          S P                  R7      pS P	                  V4      '       g   KC  \        V4      ^8  d$   Rp\         F  pW9   g   K  RpK  	  V'       d   Kv  V^,          p	W9  d   / W)&   W59   g   K  W2V	,          9  d   / W),          V&   VR8X  dk   RP                  WS,          4      p
V
W),          V,          9  d   V.VV	,          V,          V
&   K  VV	,          V,          V
,          P                  V4       EK  WS,           FS  pWV	,          V,          9  d   V.VV	,          V,          V&   K-  VV	,          V,          V,          P                  V4       KU  	  EK|  	  EK  	  VP                  4        FD  w  rV F9  pW,           F*  p\        W,          V,          V 3R lR7      W,          V&   K,  	  K;  	  KF  	  V# )	z0
Return a dictionary listing the emoji by label
r   r   FTrJ  c                 s*   < SP                  V 4      V 3# r   )r  r7  r8  r   r9  Z-EmojiMatcher.emoji_by_label.<locals>.<lambda>4
  s     OOA.'r   r:  )r   r  r   r   )
r   r  r   r   unicode_version_in_ranger`   r   r9   r   r_   )r   rK  Zemoji_by_label_dictrL  r.  r?  r   Zhas_skin_tone_modifierr  rD   Zucategory_label_fullrQ   Zlanguage_values   f            r   emoji_by_labelZEmojiMatcher.emoji_by_label	  s/    H
JL#I*.*:*:*@*@*B&	99aL'+'?'? : A 44U;;u:>-2*$7#,592 %8 .
 !$Q<646'1+ H(EECE+5i@ M1/3yy'204,0#6#@#KL
 BG 0 (*$-/ )=>
 0 (*$-/ )=> ?EfUm%0%;%;E$,I),TT 7<W !4$,!.(1!3 -2!3
 !4$,!.(1!3 -2!3 4:6%= &<M +C $d )<(A(A(C$H+	+66E7=&1%88N-e4 7 , )D #"r   c                &   < V ^8  d   QhRS[ RS[/# r
   r   r   r   r*   rt   rv   r   r   rw   :
  s        r   c                    V P                  VRR7      pVR3V P                  9   d@   RV P                  VR3,          9   d&   \        V P                  VR3,          R,          4      # R# )uE  Returns the “emoji_order” number from emojione

Useful for sorting emoji. For characters which do not
have an emoji order, 0xffffffff is returned.

:param emoji_string: An emoji

Examples:

>>> matcher = EmojiMatcher(languages = ['en'])
>>> matcher.emoji_order('😀')
1

>>> hex(matcher.emoji_order('∬'))
'0xffffffff'
r$   r   r   r      r   r   r*   r   r   rf   r   r  ZEmojiMatcher.emoji_order:
  sl    & 88R 9 14 D$4$44!T%5%5|T6J%KKt''t(<=mLMMr   c                rO  rP  rQ  rt   rv   r   r   rw   T
  s      s s r   c                rR  )u  Returns a “cldr_order” number from CLDR

Useful for sorting emoji. For characters which do not
have a “cldr_order” number, 0xffffffff is returned.

The “cldr_order” number is generated  by parsing
emoji-test.txt.

:param emoji_string: An emoji

Examples:

>>> matcher = EmojiMatcher(languages = ['en'])
>>> matcher.cldr_order('😀')
1

>>> hex(matcher.cldr_order('∬'))
'0xffffffff'
r$   r   r   r  rS  rT  rU  rf   r   r  ZEmojiMatcher.cldr_orderT
  sl    , 88R 9 14 D$4$44 D$4$4lD5I$JJt''t(<=lKLLr   c                6   < V ^8  d   QhRS[ RS[S[ ,          /# rP  r  rt   rv   r   r   rw   q
  s      s tCy r   c                    V P                  VRR7      pVR3V P                  9   d@   RV P                  VR3,          9   d&   \        V P                  VR3,          R,          4      # . # )ze
Returns the emoji properties of this emoji from the unicode.org data

:param emoji_string: An emoji
r$   r   r   r   r   r   r   rU  rf   r   r   ZEmojiMatcher.propertiesq
  sn     88R 9 1D!T%5%55!T%5%5|T6J%KK((,)=>|LMM	r   c                rV  rP  r  rt   rv   r   r   rw   
  s      S T#Y r   c                rW  )zu
Returns the Unicode category of this emoji from UnicodeData.txt

:param emoji_string: An emoji or Unicode character
r$   r   r   r   rX  rU  rf   r   unicode_categoryZEmojiMatcher.unicode_category
  sn     88R 9 1D!T%5%55"d&6&6d7K&LL((,)=>}MNN	r   c                &   < V ^8  d   QhRS[ RS[ /# rP  r   rt   rv   r   r   rw   
  s      # # r   c                    V P                  VRR7      pVR3V P                  9   d@   RV P                  VR3,          9   d&   \        V P                  VR3,          R,          4      # R# )z^
Returns the Emoji version when this emoji/character was added

:param emoji_string: An emoji
r$   r   r   r   r   r   r   rU  rf   r   r   ZEmojiMatcher.emoji_version
  l     88R 9 1D!T%5%554#3#3\44H#IIt''t(<=jIJJr   c                rZ  rP  r   rt   rv   r   r   rw   
  s      C C r   c                r[  )z`
Returns the Unicode version when this emoji/character was added

:param emoji_string: An emoji
r$   r   r   r   r\  rU  rf   r   r   ZEmojiMatcher.unicode_version
  r]  r   c                rO  rP  r   r+   rt   rv   r   r   rw   
  s      S T r   c                s   V P                  V4      pV'       g   R# \        P                  ! RV4       Uu. uF  p\        V4      NK  	  pp\        P                  ! RV P                  4       Uu. uF  p\        V4      NK  	  pp\        P                  ! RV P
                  4       Uu. uF  p\        V4      NK  	  ppV^ .^\        V4      ,
          ,          ,          pV^ .^\        V4      ,
          ,          ,          pV^ .^\        V4      ,
          ,          ,          pYTu;8:  d
   V8:  d    R#  R# R# u upi u upi u upi )z
Checks whether the Unicode version of this emoji is in the desired
range

:param emoji_string: An emoji
:return: True if the Unicode version is in the desired range,
         False if not.
Fz\d+T)r   r   Zfindallr*   r}   r~   r`   )r   r   r   ZnumberZversionZmin_versionZmax_versions   &&     r   rM  Z%EmojiMatcher.unicode_version_in_range
  s6    ..|< **V_=?= K= 	 ?
 **VT-D-DEGE KE 	 G
 **VT-D-DEGE KE 	 G 	A3!c'l*++sa#k"2233sa#k"22330[0 1%?GGs   D6.D;'E c                rZ  rP  r   rt   rv   r   r   rw   
  s      # # r   c                s    V P                  VRR7      p\        V4      ^8w  d   R# \        V4      pV P                  P	                  4        F  w  r4W#9   g   K  Vu # 	  R# )z9Returns the name of the Unicode block the character is inr$   r   )r   r`   r=  r   r  )r   r   r)   Zblock_ranger   s   &&   r   unicode_blockZEmojiMatcher.unicode_block
  sf     88R 9 1|!%	'+';';'A'A'C#K'!! (D r   c                rO  rP  r^  rt   rv   r   r   rw   
  s     " " " "r   c                sH    \        V P                  V4      4      ^8  d   R# R# )u  Checks whether skin tone modifiers are possible for this emoji

Returns True if skin  tone modifiers  are possible
for this emoji_string, False if not.

:param emoji_string: The emoji to check

Examples:

>>> matcher = EmojiMatcher(languages = ['en'])
>>> matcher.skin_tone_modifier_supported('👩')
True

>>> matcher.skin_tone_modifier_supported('👩🏻')
True

>>> matcher.skin_tone_modifier_supported('👮‍♀')
True

>>> matcher.skin_tone_modifier_supported('😀')
False

>>> matcher.skin_tone_modifier_supported('😀🏻')
False

>>> matcher.skin_tone_modifier_supported('')
False

>>> matcher.skin_tone_modifier_supported('🏻')
False
TF)r`   skin_tone_variantsrU  rf   r   skin_tone_modifier_supportedZ)EmojiMatcher.skin_tone_modifier_supported
  s#    @ t&&|459r   c                rV  rP  r  rt   rv   r   r   rw   
  s#     H: H:s H:tCy H:r   c                s   V'       d   V\         9   d   V.# V P                  VRR7      pRV P                  V4      9   d?   R\         ,            Uu. uF&  pV P                  W,           V P                  R7      NK(  	  up# VR,          \         9   dV   VR3V P                  9   dC   R\         ,            Uu. uF*  pV P                  VRR V,           V P                  R7      NK,  	  up# VP                  R4      p\        V4      ^8  Ed!   \        V4      ^8:  Ed   \          F+  p\        V4       F  w  rVVP                  VR4      W5&   K  	  K-  	  . p\        V4      ^8X  d^   V P                  V^ ,          4       FA  pV P                  V^,          4       F"  p	VP                  VR,           V	,           4       K$  	  KC  	  \        V4      ^8X  d   V P                  V^ ,          4       Fn  pV P                  V^,          4       FO  p	V P                  V^,          4       F0  p
VP                  VR,           V	,           R,           V
,           4       K2  	  KQ  	  Kp  	  \        V4      ^8X  d   V P                  V^ ,          4       F  pV P                  V^,          4       F|  p	V P                  V^,          4       F]  p
V P                  V^,          4       F>  pVP                  VR,           V	,           R,           V
,           R,           V,           4       K@  	  K_  	  K~  	  K  	  V'       d   V# V P                  VV P                  R7      .# u upi u upi )	u;  
Returns a list of skin tone variants for the given emoji

If the given emoji does not support skin tones, a list
containing only the original emoji is returned.

:param emoji_string: The emoji to check

Examples:

>>> matcher = EmojiMatcher(languages = ['en'])
>>> matcher.skin_tone_variants('👩')
['👩', '👩🏻', '👩🏼', '👩🏽', '👩🏾', '👩🏿']

>>> matcher.skin_tone_variants('👩🏻')
['👩', '👩🏻', '👩🏼', '👩🏽', '👩🏾', '👩🏿']

>>> matcher.skin_tone_variants('👮‍♀️')
['👮‍♀️', '👮🏻‍♀️', '👮🏼‍♀️', '👮🏽‍♀️', '👮🏾‍♀️', '👮🏿‍♀️']

>>> matcher.skin_tone_variants('👩‍🎓')
['👩‍🎓', '👩🏻‍🎓', '👩🏼‍🎓', '👩🏽‍🎓', '👩🏾‍🎓', '👩🏿‍🎓']

>>> matcher.skin_tone_variants('😀')
['😀']

>>> matcher.skin_tone_variants('😀🏿')
['😀🏿']

>>> matcher.skin_tone_variants('')
['']

>>> matcher.skin_tone_variants('🏿')
['🏿']

# Family: woman, girl
# See: http://unicode.org/Public/emoji/5.0/emoji-zwj-sequences.txt
# which contains the line:
#
# 1F469 200D 1F467; Emoji_ZWJ_Sequence; family: woman, girl # 6.0  [1] (👩‍👧)
>>> len(matcher.skin_tone_variants('👩‍👧'))
36

>>> len(matcher.skin_tone_variants('👩🏼‍👧🏿'))
36

>>> matcher.skin_tone_variants('👩🏼‍👧🏿') == matcher.skin_tone_variants('👩‍👧')
True

>>> matcher.skin_tone_variants('👩‍👧')
['👩‍👧', '👩‍👧🏻', '👩‍👧🏼', '👩‍👧🏽', '👩‍👧🏾', '👩‍👧🏿', '👩🏻‍👧', '👩🏻‍👧🏻', '👩🏻‍👧🏼', '👩🏻‍👧🏽', '👩🏻‍👧🏾', '👩🏻‍👧🏿', '👩🏼‍👧', '👩🏼‍👧🏻', '👩🏼‍👧🏼', '👩🏼‍👧🏽', '👩🏼‍👧🏾', '👩🏼‍👧🏿', '👩🏽‍👧', '👩🏽‍👧🏻', '👩🏽‍👧🏼', '👩🏽‍👧🏽', '👩🏽‍👧🏾', '👩🏽‍👧🏿', '👩🏾‍👧', '👩🏾‍👧🏻', '👩🏾‍👧🏼', '👩🏾‍👧🏽', '👩🏾‍👧🏾', '👩🏾‍👧🏿', '👩🏿‍👧', '👩🏿‍👧🏻', '👩🏿‍👧🏼', '👩🏿‍👧🏽', '👩🏿‍👧🏾', '👩🏿‍👧🏿']

>>> len(matcher.skin_tone_variants('👨‍👩‍👧‍👦'))
1296

# Woman in lotus position
# Does support skin tone in http://unicode.org/Public/emoji/5.0/emoji-data.txt
# which contains the line:
#
# “1F9D1..1F9DD  ; Emoji_Modifier_Base  #10.0 [13] (🧑..🧝)    adult..elf”
>>> matcher.skin_tone_variants('🧘‍♀️')
['🧘‍♀️', '🧘🏻‍♀️', '🧘🏼‍♀️', '🧘🏽‍♀️', '🧘🏾‍♀️', '🧘🏿‍♀️']

>>> matcher.skin_tone_variants('🏌️‍♂️')
['🏌️‍♂️', '🏌🏻‍♂️', '🏌🏼‍♂️', '🏌🏽‍♂️', '🏌🏾‍♂️', '🏌🏿‍♂️']

>>> matcher.skin_tone_variants('✌️')
['✌️', '✌🏻', '✌🏼', '✌🏽', '✌🏾', '✌🏿']

>>> matcher = EmojiMatcher(languages = ['en'], variation_selector='')
>>> matcher.skin_tone_variants('🏌️‍♂️')
['🏌‍♂', '🏌🏻‍♂', '🏌🏼‍♂', '🏌🏽‍♂', '🏌🏾‍♂', '🏌🏿‍♂']

>>> matcher.skin_tone_variants('🏌‍♂')
['🏌‍♂', '🏌🏻‍♂', '🏌🏼‍♂', '🏌🏽‍♂', '🏌🏾‍♂', '🏌🏿‍♂']
r$   r   Emoji_Modifier_Baser   N   ‍r$   r   )r   r   r   r   r   r]   r`   r   r^   r`  r   )r   r   ZtoneZemoji_partsr  ZiZ
emoji_partr`  Zvariant0Zvariant1Zvariant2Zvariant3s   &&          r   r`  ZEmojiMatcher.skin_tone_variants
  s]   ^ |/BB >!88R 9 1 DOOL$AA
 "$77	9 8D 11 ''+'?'? 2 A 8	9 9
 "!44"D)T-=-==
 "$77	9 8D 11 "%,'+'?'? 2 A 8	9 9
 #((2{q S%5%:/%.{%;MA%/%7%7"%EKN &< 0 "$;1$ $ 7 7A GH$($;$;KN$K*11$&'&'( %L !H ;1$ $ 7 7A GH$($;$;KN$K(,(?(?A(OH.55 ("*!+"*!+ #+!+ #+	!+, )P %L !H ;1$ $ 7 7A GH$($;$;KN$K(,(?(?A(OH,0,C,CKPQN,S 2 9 9$,&.%/&.%/ '/%/ '/	%/
 '/%/ '/%/!0 -T )P %L !H "))11#77 2 9 : 	:e99s   ,M20M
c                r   r   r   rt   rv   r   r   rw     s        D  r   c           
     s    ^ p\        V P                  P                  4       4       F6  w  r#\        RV R\        VP                  4       4       24       V^,          pK8  	  \        RV 24       R# )z3To debug whether the data has been loaded correctlyzkey=z value=zcount=N)r_   r   r  print)r   ZcountrX   r   s   &   r   debug_loading_dataZEmojiMatcher.debug_loading_data  sb     !1!1!7!7!9:JCDWVEKKM%:$;<=QJE ; 	ugr   c                r   r   r   rt   rv   r   r   rw     s     %D %DT %Dr   c           
     s   \        R4       \        R4       \        R4       \        R4       \        V P                  P                  4       4       EF  w  rV^,          R8X  g   K  V^ ,          \        ^ ,          ,           R3V P                  9   dH   RV P                  V^ ,          4      9  d+   \        RV^ ,           R\        V^ ,          4      R R	24       RV P                  V^ ,          4      9   d^   R
V P                  V^ ,          \        ^ ,          ,           R3,          9  d+   \        RV^ ,           R\        V^ ,          4      R R24       RV P                  V^ ,          4      9   d>   R
V P                  V^ ,          R3,          9  d   \        RV^ ,           R24       EKZ  EK]  R
V P                  V^ ,          R3,          9   g   EK  RV^ ,          9   g   EK  \        RV^ ,           R24       EK  	  R# )zE
Function to list bugs in emojione.json to help with reporting bugs.
z2--------------------------------------------------zPossible bugs in emojione.json:Z
r   rb  u	   emoji “u   ” (U+r0  zW) has skintones in emojione but not the Emoji_Modifier_Base property in emoji-data.txt.r  zW) has the property Emoji_Modifier_Base in emoji-data.txt but no skin tones in emojione.ZEmoji_ZWJ_Sequenceu   ZWJ sequence “u(   ” from unicode.org missing in emojionerc  u&   ” in emojione but not in unicode.orgN)re  r_   r   r  r   r   r=  )r   r.  Zdummy_emoji_valuer/   r   list_emoji_one_bugsZ EmojiMatcher.list_emoji_one_bugs  s    	BC/0BCd,243C3C3I3I3K,L(I|t#q\$7$::DA++,-#'??9Q<#@A $$-aL>Yq\9J38O P<< =
 )DOOIaL,II%T-=-=&q\,?,BBDI.K K $$-aL>Yq\9J38O P-- .
 (4??9Q<+HH%#'#3#3Yq\44H#IJ 01 ?E E FJ
 ' ,,ilD-ABC (IaL 8 01 ?C C D9 -Mr   )r   r   r~   r}   r   rz   r   ry   r   r   r   r|   r   N))Zen_USTFFTz0.0z100.0Tr   Tre   )re   )r   )i   r$   Frd  )i  T)1r   Z
__module__Z__qualname__Z__firstlineno____doc__r   r   r   r   	functools	lru_cacher   r   r   r   r   r   r   r   r   r   r   r   r   r	  r   r&  r%  r-  r   r   r   r  r;  rN  r  r  r   rY  r   r   rM  r_  ra  r`  rf  rg  Z__static_attributes__Z__classdictcell__)ru   s   @r   rh   rh     s    ?U$ U$n .6 6&% %P )Z Z *Zx%, %,N(7 (7V+7 +7Z 7  7D.1 .1`1 1<01 01d51 51n=1 =1~91 91vb1 b1Hg* g*R29 29hF1 F1P{ {zg! g!l )
 *
 + +ZJ JX& &P# #Je eNA# A#F 4 :     @ " "HH: H:V   %D %Dr   rh   c                s    V ^8  d   QhRR/# r   r   r   r   r   r   r     s     A Ad Ar   c                 s   \         P                  ! \        P                  R7      p \        P                  \         P                  4       \        P                  V 4       \        '       d)   ^ RI	p^ RI
pVP                  4       pVP                  4        ^ p \         '       g   \        P#                  R4       MH\$        '       g   \        P#                  R4       M&^ RIpRsTP*                  pTP-                  TR7      w  rH\        '       dg   XP/                  4        XP1                  T4      p	T	P3                  4        T	P5                  R4       T	P7                  R^24       T	P7                  R	^4       \        P#                  R
\8        P:                  P=                  4       4       \        P#                  R\        P>                  P=                  4       4       \        P#                  R\        P@                  P=                  4       4       \        P#                  R\B        P=                  4       4       \        P#                  R\D        P=                  4       4       \        PF                  ! T4       R# )ui   
Used for testing and profiling.

“python3 itb_emoji.py”

runs some tests and prints profiling data.
)ZstreamNz5Skipping doctests because rapidfuzz is not available.z3Skipping doctests because enchant is not available.r$   )ZoptionflagsZ
cumulativeZ	itb_emojir   z(itb_util.remove_accents() cache info: %sz:EmojiMatcher.variation_selector_normalize() cache info: %sz1EmojiMatcher.get_all_label_words() cache info: %sz_match_classic() cache info: %sz!_match_rapidfuzz() cache info: %s)$loggingZStreamHandlersysZstderrr:   ZsetLevelZDEBUGZ
addHandler	BENCHMARKcProfilepstatsZProfileZenablerh   rf  rg  r   Zinfor   doctestr   ZREPORT_NDIFFZtestmodZdisableZStatsZ
strip_dirsZ
sort_statsZprint_statsrI   rZ   Z
cache_infor   r-  rd   rg   Zexit)
Zlog_handlerrn  ro  ZprofileZfailedZmatcherrp  r  Z
_attemptedZstatss
             r   mainrq    s    ''szz:K
OOGMM"
k"y""$F )(KL&&IJ 
$$&5AyW%&+r*)R(
KK2**,. KKD11<<>@ KK;((3357 KK)!!#% KK+##%' HHVr   Z__main__)z6.0z6.1z7.0z8.0)2)$   rr  )i   i   )  rs  )  rt  )i	  i	  )	  ru  )
  rv  )  rw  )?  rx  )  ry  )i    io   )ip   i   )i   i   )i   i   )i !  iO!  )iP!  i!  )i!  i!  )i "  i"  )i #  i#  )i6#  iz#  )i $  i?$  )i@$  i_$  )i`$  i$  )i %  i%  )i%  i%  )i%  i%  )i &  i&  )i&  i&  )iT&  i_&  )i`&  ig&  )i0&  i7&  )i&  i&  )i&  i&  )i '  i'  )i'  i'  )i'  i'  )i (  i(  )i )  i)  )i)  i)  )i *  i*  )i +  i+  )8  rz  )  r{  )i  r|  )i  i`  )i  i )i  iO )iP i )i i )i  i >   u   ﷺu   ﷻu   ﷽u   𰻝u   𰻞)uN   30EDE;<CJK Ideograph Extension G> biáng Traditional Chinese;Lo;0;L;;;;;N;;;;;uM   30EDD;<CJK Ideograph Extension G> biáng Simplified Chinese;Lo;0;L;;;;;N;;;;;)u   🏻u   🏼u   🏽u   🏾u   🏿)r#   rd  )Erh  Ztypingr    r   r   r   r   r   r   r   r7   rl  r   ri  r   r;   r  r>  r  rk  r   rI   r   r   r   r<   r=   ZImportErrorr>   r?   r   re   r   r   r%   ZpykakasiZkakasir&   r  r  Z	getLoggerr:   r8   r9   rB   Z__file__r  Zxdg_save_data_pathr  r   r   rH   r   r   r-   r   r   r   r(   r0   rC   rM   rj  rd   rg   rh   rm  rq  r   r   r   r   <module>r}     s  (
         	 
 	         "
.  	   	! $ ("& " & $ # '!%oo'O ! %# 
		0	1
'',,rwwx0)
<**+EF'   '    '
 &%' !7E7GWi
@! 	7D'7GX
>! 	7E7GWn
E	!
 	7E7GWm
D! 	7E7GWk
B! 	7E7Hg{
C! 	7E7Hgz
B! 	7E7Hgw
?! 	7E7Hg{
C! 	7E7Hg{
C! 	7E7FG5H
I! 	7E7FG[
A! 	7E7FG\
B! 	7E7Hg
G!  	7E7Hgx
@!!$ 	7D'8Wg
>%!& 	7D'=';
G'!( 	7D'='6
B7D'='7
C7D'='=
I7D'='?
K7D'='7
C7D'='6
B7D'8Wj
A7D'8Wj
A7D'8Wf
=7D'8Wg
>7D';
@7D';
E7D';
AA! J 
' 
'	E7	E7	F8 VH
VH VH
VH VH
VH
VH
VH
VH
VH3% !<4l  
 ? )V881fL T". #.` T"? #?
S'D S'DjN 	AF zF {]  		  		 	~ ("'( 	~ & %& 	~ '!&' 	~ %$%sl   4K# =K1 K? L L! 2L2 #K.-K.1K<;K<?
LL
LL!
L/.L/2
M ?M 