§
    E«jj:  ã                   óB  — d Z ddlZddlmZ ddlZddlZddlZddlmZ ddl	m
Z
 ddlmZmZmZmZmZmZmZ ddlmZ ddlmZmZ dd	lmZmZmZmZ  ej        e¦  «        Zd
e de!fd„Z" G d„ d¦  «        Z# G d„ de e¦  «        Z$ G d„ d¦  «        Z% G d„ d¦  «        Z&dS )z?Store information about a challenge, game or player in a class.é    N)Úurljoin)ÚEnum)ÚOnlineBlocklist)ÚTimerÚmsecÚsecondsÚsec_strÚto_msecÚ
to_secondsÚyears)ÚConfiguration)ÚdefaultdictÚCounter)ÚUserProfileTypeÚChallengeTypeÚGameEventTypeÚ
PlayerTypeÚfenÚreturnc                 óZ   — t          j        | ¦  «        t          j        | d¬¦  «        k    S )z;Determine whether an FEN string represents a chess960 game.T)Úchess960)ÚchessÚBoard)r   s    ú$/app/lichess-bot-master/lib/model.pyÚis_chess_960r      s&   € åŒ;�sÑÔ�uœ{¨3¸Ð>Ñ>Ô>Ò>Ð>ó    c                   ó6  — e Zd ZdZdededdfd„Zdedefd„Z	dedefd	„Z
dedefd
„Zdededefd„Zdedeeee         f         defd„Zdededefd„Zdedeeee         f         dee         dededeeef         fd„Zdefd„Zdefd„Zdefd„Zdefd„ZdS )Ú	Challengez$Store information about a challenge.Úchallenge_infoÚuser_profiler   Nc                 ó  — |d         | _         |d         | _        |d         d         | _        |d         d         | _        |d         | _        |                     di ¦  «                             d	¦  «        | _        |                     di ¦  «                             d
¦  «        | _        |                     di ¦  «                             d¦  «        | _        t          |                     d¦  «        pi ¦  «        | _
        t          |                     d¦  «        pi ¦  «        | _        | j
        j        |d         k    | _        |                     dd¦  «        | _        |d         }|dk    r|n|d         | _        |d         | _        dS )z/:param user_profile: Information about our bot.ÚidÚratedÚvariantÚkeyÚperfÚnameÚspeedÚtimeControlÚ	incrementÚlimitÚdaysPerTurnÚ
challengerÚdestUserÚusernameÚ
initialFenÚstartposÚcolorÚrandomÚ
finalColorN)r"   r#   r$   Ú	perf_namer(   Úgetr*   ÚbaseÚdaysÚPlayerr-   Úchallenge_targetr'   Ú	from_selfÚinitial_fenr2   Útime_control)Úselfr   r    r2   s       r   Ú__init__zChallenge.__init__   sa  € à  Ô&ˆŒØ# GÔ,ˆŒ
Ø% iÔ0°Ô7ˆŒØ'¨Ô/°Ô7ˆŒØ# GÔ,ˆŒ
Ø'×+Ò+¨M¸2Ñ>Ô>×BÒBÀ;ÑOÔOˆŒØ"×&Ò& }°bÑ9Ô9×=Ò=¸gÑFÔFˆŒ	Ø"×&Ò& }°bÑ9Ô9×=Ò=¸mÑLÔLˆŒ	Ý  ×!3Ò!3°LÑ!AÔ!AÐ!GÀRÑHÔHˆŒÝ & ~×'9Ò'9¸*Ñ'EÔ'EÐ'KÈÑ LÔ LˆÔØœÔ-°¸jÔ1IÒIˆŒØ)×-Ò-¨l¸JÑGÔGˆÔØ˜wÔ'ˆØ# xÒ/Ð/�U�U°^ÀLÔ5QˆŒ
Ø*¨=Ô9ˆÔÐÐr   Úchallenge_cfgc                 óz   — | j         |j        vrdS | j        dk    rdS t          | j        ¦  «        r	d|j        v S dS )z'Check whether the variant is supported.Fr1   Tr   )r$   Úvariantsr<   r   ©r>   r@   s     r   Úis_supported_variantzChallenge.is_supported_variant+   sP   € àŒ<˜}Ô5Ð5Ð5Ø�5àÔ˜zÒ)Ð)Ø�4å˜Ô(Ñ)Ô)ð 	8Ø Ô!7Ð7Ð7àˆtr   c                 ó¦  — |j         }|j        }|j        }|j        }|j        }|j        }|j        }| j        |vrdS | j        j	        o| j        dk    o|j
        }	t          ||	rdnd¦  «        }| j        �1| j        �*|| j        cxk    o|k    nc o|| j        cxk    o|k    nc S | j        �|| j        cxk    o|k    nc S |t          j        k    S )z,Check whether the time control is supported.FÚbulleté   r   )Útime_controlsÚmax_incrementÚmin_incrementÚmax_baseÚmin_baseÚmax_daysÚmin_daysr(   r-   Úis_botÚbullet_requires_incrementÚmaxr7   r*   r8   ÚmathÚinf)
r>   r@   ÚspeedsÚincrement_maxÚincrement_minÚbase_maxÚbase_minÚdays_maxÚdays_minÚrequire_non_zero_increments
             r   Úis_supported_time_controlz#Challenge.is_supported_time_control8   s'  € àÔ,ˆØ*Ô8ˆØ*Ô8ˆØ%Ô.ˆØ%Ô.ˆØ'Ô0ˆØ'Ô0ˆàŒ:˜VÐ#Ð#Ø�5à&*¤oÔ&<ð 'RØ*.¬*¸Ò*@ð'Rà*7Ô*Qð 	#õ ˜MÐ0JÐ+Q¨1¨1ÐPQÑRÔRˆàŒ9Ð  T¤^Ð%?à! T¤^ÐDÐDÒDÐD°}ÒDÐDÐDÐDð :Ø  D¤IÐ9Ð9Ò9Ð9°Ò9Ð9Ð9Ð9ð;àŒYÐ"à˜tœyÐ4Ð4Ò4Ð4¨HÒ4Ð4Ð4Ð4Ð4ð �tœxÒ'Ð'r   c                 ó&   — | j         rdnd|j        v S )z$Check whether the mode is supported.r#   Úcasual)r#   ÚmodesrC   s     r   Úis_supported_modezChallenge.is_supported_modeU   s   € àœ:Ð3��¨8¸Ô8KÐKÐKr   c                 óh  — | j         j        }|€dS |j        }|j        }|j        }|�||                     di ¦  «                             | j                             ¦   «         i ¦  «                             d¦  «        }|r&t          |||z
  ¦  «        }t          |||z   ¦  «        }||cxk    o|k    nc S )zECheck whether the challenger's rating is within the acceptable range.NTÚperfsÚrating)
r-   rc   Ú
min_ratingÚ
max_ratingÚrating_differencer6   r5   ÚlowerrQ   Úmin)r>   r@   r    Úchallenger_ratingrd   re   Úrating_diffÚ
bot_ratings           r   Úis_supported_ratingzChallenge.is_supported_ratingY   sÍ   € à œOÔ2ÐØÐ$Ø�4à'Ô2ˆ
Ø'Ô2ˆ
Ø"/Ô"AˆàÐ"Ø%×)Ò)¨'°2Ñ6Ô6×:Ò:¸4¼>×;OÒ;OÑ;QÔ;QÐSUÑVÔV×ZÒZÐ[cÑdÔdˆJØð GÝ  ¨Z¸+Ñ-EÑFÔF�
Ý  ¨Z¸+Ñ-EÑFÔF�
àÐ.Ð<Ð<Ò<Ð<°*Ò<Ð<Ð<Ð<Ð<r   ÚconfigÚrecent_bot_challengesc                 óÊ   — d„ || j         j                 D ¦   «         || j         j        <   |j        }| j         j         p&|du p"t	          || j         j                 ¦  «        |k     S )znCheck whether we have played a lot of games with this opponent recently. Only used when the opponent is a BOT.c                 ó:   — g | ]}|                      ¦   «         °|‘ŒS © )Ú
is_expired)Ú.0Útimers     r   ú
<listcomp>z1Challenge.is_supported_recent.<locals>.<listcomp>n   s?   € ð 7Rð 7Rð 7RÀà>C×>NÒ>NÑ>PÔ>Pð7R°uð 7Rð 7Rð 7Rr   N)r-   r'   Úmax_recent_bot_challengesrO   Úlen)r>   rm   rn   Úmax_recent_challengess       r   Úis_supported_recentzChallenge.is_supported_recentk   sˆ   € ð7Rð 7RØ:OÐPTÔP_ÔPdÔ:eð7Rñ 7Rô 7RÐ˜dœoÔ2Ñ3ð !'Ô @ÐØ”OÔ*Ð*ð \Ø(¨DÐ0ð\åÐ,¨T¬_Ô-AÔBÑCÔCÐF[Ò[ð	]r   Úrequirement_metÚdecline_reasonc                 ó   — |rdn|S )aL  
        Get the reason lichess-bot declined an incoming challenge.

        :param requirement_met: Whether a requirement is met.
        :param decline_reason: The reason we declined the challenge if the requirement wasn't met.
        :return: `decline_reason` if `requirement_met` is false else returns an empty string.
        Ú rq   )r>   rz   r{   s      r   Údecline_due_tozChallenge.decline_due_tov   s   € ð %Ð8ˆrˆr¨.Ð8r   Úopponent_engagementsÚonline_block_listc                 ó¾  — 	 | j         rdS ddlm} t          t	          d|j        ¦  «        ¦  «        p| j        j        g}|                      |j	        p| j        j
         d¦  «        �p¼|                      |j         p| j        j
        d¦  «        �p“|                      |                      |¦  «        d¦  «        �pi|                      |                      |¦  «        d¦  «        �p?|                      |                      |¦  «        | j        rd	nd
¦  «        �p|                      |                      ||¦  «        d¦  «        pâ|                      | j        j        |j        vd¦  «        p»|                      | j        j        |vd¦  «        p™|                      | j        j        |v d¦  «        pw|                      |                      ||¦  «        d¦  «        pM|                      || j        j                 |j        k     d¦  «        p|                       || ¦  «        d¦  «        }| |fS # t(          $ r' t*                               d| j        › d�¦  «         Y dS w xY w)z#Whether the challenge is supported.)Tr}   r   )Úis_supported_extraNÚnoBotÚonlyBotr)   r$   r^   r#   ÚgenericÚlaterzError while checking challenge ú:)Fr…   )r;   Úextra_game_handlersr‚   ÚlistÚfilterÚ
allow_listr-   r'   r~   Ú
accept_botrO   Úonly_botr\   rD   r`   r#   rl   Ú
block_listry   Úmax_simultaneous_games_per_userÚ	ExceptionÚloggerÚ	exceptionr"   )	r>   rm   rn   r   r€   r    r‚   Úallowed_opponentsr{   s	            r   Úis_supportedzChallenge.is_supported€   s¸  € ð	$ØŒ~ð  Ø�xà>Ð>Ð>Ð>Ð>Ð>å+/µ°t¸VÔ=NÑ0OÔ0OÑ+PÔ+PÐ+jÐUYÔUdÔUiÐTjÐØ"×1Ò1°&Ô2CÐ2aÈ4Ì?ÔKaÐGaÐcjÑkÔkñ ZØ!%×!4Ò!4¸¼Ð5HÐ5bÈDÌOÔLbÐdmÑ!nÔ!nñZà!%×!4Ò!4°T×5SÒ5SÐTZÑ5[Ô5[Ð]jÑ!kÔ!kñZð "&×!4Ò!4°T×5NÒ5NÈvÑ5VÔ5VÐXaÑ!bÔ!bñZð "&×!4Ò!4°T×5KÒ5KÈFÑ5SÔ5SÐaeÔakÐUxÐU]ÐU]ÐqxÑ!yÔ!yñ	Zð
 "&×!4Ò!4°T×5MÒ5MÈfÐVbÑ5cÔ5cÐenÑ!oÔ!oðZð "&×!4Ò!4°T´_Ô5IÐQWÔQbÐ5bÐdmÑ!nÔ!nðZð "&×!4Ò!4°T´_Ô5IÐQbÐ5bÐdmÑ!nÔ!nðZð "&×!4Ò!4°T´_Ô5IÐM^Ð5^Ð`iÑ!jÔ!jðZð "&×!4Ò!4°T×5MÒ5MÈfÐVkÑ5lÔ5lÐnuÑ!vÔ!vðZð "&×!4Ò!4Ð5IÈ$Ì/ÔJ^Ô5_Ø7=Ô7]ò6^Ø_fñ"hô "hðZð "&×!4Ò!4Ð5GÐ5GÈÑ5MÔ5MÈyÑ!YÔ!Yð ð &Ð% ~Ð5Ð5øåð 	$ð 	$ð 	$Ý×ÒÐI¸t¼wÐIÐIÐIÑJÔJÐJØ#Ð#Ð#ð	$øøøs   ‚H+ ‹HH+ È+-IÉIc                 ó„   — | j         rdnd}| j        j        s| j        j        nd}|rdnd}| j        j        pd}||z   |z   S )z'Give a rating estimate to the opponent.éÈ   r   N)r#   r-   rO   Útitlerc   )r>   Úrated_bonusÚchallenger_master_titleÚtitled_bonusÚchallenger_rating_ints        r   ÚscorezChallenge.scoreŸ   s[   € à!œZÐ.�c�c¨QˆØ?C¼Ô?UÐ"_ $¤/Ô"7Ð"7Ð[_ÐØ5Ð<�s�s¸1ˆØ $¤Ô 6Ð ;¸!ÐØ$ {Ñ2°\ÑAÐAr   c                 ó   — | j         rdndS )z0Get the mode of the challenge (rated or casual).r#   r^   )r#   ©r>   s    r   ÚmodezChallenge.mode§   s   € àœ*Ð2ˆwˆw¨(Ð2r   c                 ó`   — | j         › d|                      ¦   «         › d| j        › d| j        › d�S )ú+Get a string representation of `Challenge`.ú z challenge from ú (ú))r5   rŸ   r-   r"   rž   s    r   Ú__str__zChallenge.__str__«   s9   € à”.Ð]Ð] 4§9¢9¡;¤;Ð]Ð]ÀÄÐ]Ð]ÐSWÔSZÐ]Ð]Ð]Ð]r   c                 ó*   — |                       ¦   «         S )r¡   ©r¥   rž   s    r   Ú__repr__zChallenge.__repr__¯   ó   € à�|Š|‰~Œ~Ðr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r?   r   ÚboolrD   r\   r`   rl   r   Ústrr‰   r   ry   r~   r   r   Útupler”   Úintrœ   rŸ   r¥   r¨   rq   r   r   r   r      s  € € € € € Ø.Ð.ð: }ð :ÀOð :ÐX\ð :ð :ð :ð :ð$°-ð ÀDð ð ð ð ð(°}ð (Èð (ð (ð (ð (ð:L¨}ð LÀð Lð Lð Lð Lð=°ð =Èoð =Ðbfð =ð =ð =ð =ð$	]¨-ð 	]ÐP[Ð\_ÐaeÐfkÔalÐ\lÔPmð 	]Ðrvð 	]ð 	]ð 	]ð 	]ð9¨dð 9ÀCð 9ÈCð 9ð 9ð 9ð 9ð$ =ð $ÈÐUXÐZ^Ð_dÔZeÐUeÔIfð $Ø+2°3¬<ð$ØL[ð$à#2ð$à7<¸TÀ3¸YÔ7Gð$ð $ð $ð $ð>B�sð Bð Bð Bð Bð3�cð 3ð 3ð 3ð 3ð^˜ð ^ð ^ð ^ð ^ð˜#ð ð ð ð ð ð r   r   c                   ó&   — e Zd ZdZdZdZdZdZdZdS )ÚTerminationzThe possible game terminations.ÚmateÚ	outoftimeÚresignÚabortedÚdrawN)	rª   r«   r¬   r­   ÚMATEÚTIMEOUTÚRESIGNÚABORTÚDRAWrq   r   r   r³   r³   ´   s-   € € € € € Ø)Ð)à€DØ€GØ€FØ€EØ€D€D€Dr   r³   c            
       ó  — e Zd ZdZdedededej        ddf
d„Zdefd	„Z	defd
„Z
defd„Zdefd„Zdefd„Zdej        dej        dej        ddfd„Zdefd„Zdefd„Zdefd„Zdej        fd„Zdefd„Zdefd„Zdefd„ZdS )ÚGamezStore information about a game.Ú	game_infor/   Úbase_urlÚ
abort_timer   Nc                 óˆ  — || _         |d         | _        |                     d¦  «        | _        |                     d¦  «        pi }t	          t          d¦  «        ¦  «        }t          |                     d|¦  «        ¦  «        | _        t          |                     dd¦  «        ¦  «        | _        |                     d¦  «        pi                      d	d
¦  «        | _	        |d         d	         | _
        |                     d¦  «        rdnd| _        t          |d         ¦  «        | _        t          |d         ¦  «        | _        |                     d¦  «        | _        |d         | _        | j        j        pd                     ¦   «         |                     ¦   «         k    | _        | j        rdnd| _        | j        rdnd| _        | j        r| j        n| j        | _        | j        r| j        n| j        | _        || _        t2          j                             t7          t          |d         ¦  «        ¦  «        t2          j        j        ¬¦  «        | _        t?          |¦  «        | _         t?          | j        | j        z   |z   tC          d¦  «        z   ¦  «        | _"        t?          tC          d¦  «        ¦  «        | _#        dS )z=:param abort_time: How long to wait before aborting the game.r"   r(   Úclocké
   Úinitialr*   r   r&   r'   z{perf?}r$   r#   r^   ÚwhiteÚblackr0   Ústater}   Ú	createdAt)Útzé<   N)$r/   r"   r6   r(   r
   r   r   Úclock_initialÚclock_incrementr5   Úvariant_namerŸ   r9   rÇ   rÈ   r<   rÉ   r'   rg   Úis_whiteÚmy_colorÚopponent_colorÚmeÚopponentrÁ   ÚdatetimeÚfromtimestampr   ÚtimezoneÚutcÚ
game_startr   rÂ   r   Úterminate_timeÚdisconnect_time)r>   rÀ   r/   rÁ   rÂ   rÄ   Úten_years_in_mss          r   r?   zGame.__init__Á   sJ  € à ˆŒØ˜D”/ˆŒØ—]’] 7Ñ+Ô+ˆŒ
Ø—’˜gÑ&Ô&Ð,¨"ˆÝ!¥%¨¡)¤)Ñ,Ô,ˆÝ! %§)¢)¨I°Ñ"GÔ"GÑHÔHˆÔÝ# E§I¢I¨k¸1Ñ$=Ô$=Ñ>Ô>ˆÔØ#Ÿ-š-¨Ñ/Ô/Ð5°2×:Ò:¸6À9ÑMÔMˆŒØ% iÔ0°Ô8ˆÔØ(Ÿ}š}¨WÑ5Ô5ÐC�G�G¸8ˆŒ	Ý˜I gÔ.Ñ/Ô/ˆŒ
Ý˜I gÔ.Ñ/Ô/ˆŒ
Ø$Ÿ=š=¨Ñ6Ô6ˆÔØ˜wÔ'ˆŒ
ØœœÐ.¨B×5Ò5Ñ7Ô7¸8¿>º>Ñ;KÔ;KÒKˆŒØ#'¤=Ð=˜˜°gˆŒØ)-¬ÐC˜g˜g¸GˆÔØ $¤Ð=�$”*�*°4´:ˆŒØ&*¤mÐC˜œ
˜
¸¼ˆŒØ ˆŒÝ"Ô+×9Ò9½*ÅTÈ)ÐT_ÔJ`ÑEaÔEaÑ:bÔ:bÝ=EÔ=NÔ=Rð :ñ Tô TˆŒå 
Ñ+Ô+ˆŒÝ# DÔ$6¸Ô9MÑ$MÐPZÑ$ZÕ]dÐegÑ]hÔ]hÑ$hÑiÔiˆÔÝ$¥W¨Q¡Z¤ZÑ0Ô0ˆÔÐÐr   c                 ó>   — |                       ¦   «         › d| j        › �S )zGet the url of the game.ú/)Ú	short_urlrÑ   rž   s    r   ÚurlzGame.urlÝ   s"   € à—.’.Ñ"Ô"Ð4Ð4 T¤]Ð4Ð4Ð4r   c                 ó6   — t          | j        | j        ¦  «        S )zGet the short url of the game.)r   rÁ   r"   rž   s    r   rß   zGame.short_urlá   s   € å�t”} d¤gÑ.Ô.Ð.r   c                 óÈ   — | j         dv r6| j                             ¦   «         › d| j                             ¦   «         › d�S | j                             ¦   «         › d| j         › d�S )z'Get the event to write in the PGN file.)ÚStandardzFrom Positionr¢   z game)rÏ   rŸ   r—   r5   rž   s    r   Ú	pgn_eventzGame.pgn_eventå   sh   € àÔÐ =Ð=Ð=Ø”i—o’oÑ'Ô'ÐGÐG¨$¬.×*>Ò*>Ñ*@Ô*@ÐGÐGÐGÐGà”i—o’oÑ'Ô'ÐBÐB¨$Ô*;ÐBÐBÐBÐBr   c                 óX   — t          | j        ¦  «        › dt          | j        ¦  «        › �S )z!Get the time control of the game.ú+)r	   rÍ   rÎ   rž   s    r   r=   zGame.time_controlì   s,   € å˜$Ô,Ñ-Ô-ÐOÐOµ¸Ô8LÑ0MÔ0MÐOÐOÐOr   c                 ó    — d| j         d         vS )z Whether the game can be aborted.r¢   Úmoves)rÉ   rž   s    r   Úis_abortablezGame.is_abortableð   s   € ð ˜$œ* WÔ-Ð-Ð-r   Úabort_inÚterminate_inÚdisconnect_inc                 ó¦   — |                       ¦   «         rt          |¦  «        | _        t          |¦  «        | _        t          |¦  «        | _        dS )a/  
        Tell the bot when to abort, terminate, and disconnect from a game.

        :param abort_in: How many seconds to wait before aborting.
        :param terminate_in: How many seconds to wait before terminating.
        :param disconnect_in: How many seconds to wait before disconnecting.
        N)ré   r   rÂ   rÚ   rÛ   )r>   rê   rë   rì   s       r   Úpingz	Game.pingö   sK   € ð ×ÒÑÔð 	.Ý# H™oœoˆDŒOÝ# LÑ1Ô1ˆÔÝ$ ]Ñ3Ô3ˆÔÐÐr   c                 ó\   — |                       ¦   «         o| j                             ¦   «         S )z!Whether we should abort the game.)ré   rÂ   rr   rž   s    r   Úshould_abort_nowzGame.should_abort_now  s'   € à× Ò Ñ"Ô"ÐC t¤×'AÒ'AÑ'CÔ'CÐCr   c                 ó4   — | j                              ¦   «         S )z%Whether we should terminate the game.)rÚ   rr   rž   s    r   Úshould_terminate_nowzGame.should_terminate_now  s   € àÔ"×-Ò-Ñ/Ô/Ð/r   c                 ó4   — | j                              ¦   «         S )z+Whether we should disconnect form the game.)rÛ   rr   rž   s    r   Úshould_disconnect_nowzGame.should_disconnect_now  s   € àÔ#×.Ò.Ñ0Ô0Ð0r   c                 ó€   — t          | j        d         ¦  «        }t          | j        d         ¦  «        }| j        r|n|S )zHow many seconds we have left.ÚwtimeÚbtime)r   rÉ   rÐ   )r>   rö   r÷   s      r   Úmy_remaining_timezGame.my_remaining_time  s;   € å�T”Z Ô(Ñ)Ô)ˆÝ�T”Z Ô(Ñ)Ô)ˆØœÐ0ˆuˆu¨5Ð0r   c                 ó4  —  G d„ dt           t          ¦  «        }| j                             d¦  «        }| j                             d¦  «        }|dk    r|j        }n7|dk    r|j        }n)|t          j        t          j        fv r|j        }n|j	        }|j
        S )zGet the result of the game.c                   ó   — e Zd ZdZdZdZdZdS )úGame.result.<locals>.GameEndingz1-0z0-1z1/2-1/2Ú*N)rª   r«   r¬   Ú
WHITE_WINSÚ
BLACK_WINSr½   Ú
INCOMPLETErq   r   r   Ú
GameEndingrû     s"   € € € € € ØˆJØˆJØˆDØˆJˆJˆJr   r   ÚwinnerÚstatusrÇ   rÈ   )r¯   r   rÉ   r6   rý   rþ   r³   r½   rº   rÿ   Úvalue)r>   r   r  ÚterminationÚresults        r   r  zGame.result  s¯   € ð	ð 	ð 	ð 	ð 	��dñ 	ô 	ð 	ð ”—’ Ñ)Ô)ˆØ”j—n’n XÑ.Ô.ˆà�WÒÐØÔ*ˆFˆFØ�wÒÐØÔ*ˆFˆFØ�[Ô-­{Ô/BÐCÐCÐCØ”_ˆFˆFàÔ*ˆFàŒ|Ðr   c                 ó`   — |                       ¦   «         › d| j        › d| j        › d| j        › d�S )ú&Get a string representation of `Game`.r¢   z vs r£   r¤   )rà   r5   rÔ   r"   rž   s    r   r¥   zGame.__str__+  s7   € à—(’(‘*”*ÐNÐN˜tœ~ÐNÐN°4´=ÐNÐNÀDÄGÐNÐNÐNÐNr   c                 ó*   — |                       ¦   «         S )r  r§   rž   s    r   r¨   zGame.__repr__/  r©   r   )rª   r«   r¬   r­   r   r¯   rÕ   Ú	timedeltar?   rà   rß   rä   r=   r®   ré   rî   rð   rò   rô   rø   r  r¥   r¨   rq   r   r   r¿   r¿   ¾   sì  € € € € € Ø)Ð)ð1 -ð 1¸3ð 1È#ð 1Ð[cÔ[mð 1Ðrvð 1ð 1ð 1ð 1ð85�Sð 5ð 5ð 5ð 5ð/˜3ð /ð /ð /ð /ðC˜3ð Cð Cð Cð CðP˜cð Pð Pð Pð Pð.˜dð .ð .ð .ð .ð4˜XÔ/ð 4¸xÔ?Qð 4ÐbjÔbtð 4Ðy}ð 4ð 4ð 4ð 4ðD $ð Dð Dð Dð Dð0 dð 0ð 0ð 0ð 0ð1 tð 1ð 1ð 1ð 1ð1 8Ô#5ð 1ð 1ð 1ð 1ð˜ð ð ð ð ð,O˜ð Oð Oð Oð Oð˜#ð ð ð ð ð ð r   r¿   c                   ó:   — e Zd ZdZdeddfd„Zdefd„Zdefd„ZdS )r9   z!Store information about a player.Úplayer_infor   Nc                 ó`  — |                      d¦  «        | _        |                      d¦  «        | _        |                      d¦  «        | _        |                      d¦  «        | _        | j        dk    p| j        du| _        | j        r
d| j        › �n|                      dd	¦  «        | _        dS )
z8:param player_info: Contains information about a player.r—   rc   ÚprovisionalÚaiLevelÚBOTNz	AI level r'   r}   )r6   r—   rc   r  r  rO   r'   )r>   r  s     r   r?   zPlayer.__init__7  s›   € à —_’_ WÑ-Ô-ˆŒ
Ø!—o’o hÑ/Ô/ˆŒØ&Ÿ?š?¨=Ñ9Ô9ˆÔØ"—’ yÑ1Ô1ˆŒØ”j EÒ)ÐE¨T¬\ÀÐ-EˆŒØ26´,Ð_Ð. ¤Ð.Ð.Ð.ÀKÇOÂOÐTZÐ\^ÑD_ÔD_ˆŒ	ˆ	ˆ	r   c                 ó˜   — | j         r| j        S | j        › | j        rdnd› �}| j        pd› d| j        › d|› d�                     ¦   «         S )ú(Get a string representation of `Player`.ú?r}   r¢   r£   r¤   )r  r'   rc   r  r—   Ústrip)r>   rc   s     r   r¥   zPlayer.__str__@  sf   € àŒ<ð 	Ø”9ÐØ”KÐB¨Ô(8Ð!@  ¸bÐBÐBˆØ”*Ð" Ð;Ð; T¤YÐ;Ð;°&Ð;Ð;Ð;×AÒAÑCÔCÐCr   c                 ó*   — |                       ¦   «         S )r  r§   rž   s    r   r¨   zPlayer.__repr__G  r©   r   )	rª   r«   r¬   r­   r   r?   r¯   r¥   r¨   rq   r   r   r9   r9   4  s}   € € € € € Ø+Ð+ð` Jð `°4ð `ð `ð `ð `ðD˜ð Dð Dð Dð Dð˜#ð ð ð ð ð ð r   r9   )'r­   rR   Úurllib.parser   ÚloggingrÕ   r   Úenumr   Úlib.blocklistr   Ú	lib.timerr   r   r   r	   r
   r   r   Ú
lib.configr   Úcollectionsr   r   Úlib.lichess_typesr   r   r   r   Ú	getLoggerrª   r‘   r¯   r®   r   r   r³   r¿   r9   rq   r   r   ú<module>r     sÝ  ðØ EÐ EØ €€€Ø  Ð  Ð  Ð  Ð  Ð  Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø )Ð )Ð )Ð )Ð )Ð )Ø OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OÐ OØ $Ð $Ð $Ð $Ð $Ð $Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ø WÐ WÐ WÐ WÐ WÐ WÐ WÐ WÐ WÐ WÐ WÐ Wà	ˆÔ	˜8Ñ	$Ô	$€ð?�cð ?˜dð ?ð ?ð ?ð ?ð
[ð [ð [ð [ð [ñ [ô [ð [ð|ð ð ð ð �#�tñ ô ð ðsð sð sð sð sñ sô sð sðlð ð ð ð ñ ô ð ð ð r   