§
    ¿jN:  ã                  óT  — U d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
ZddlZddlZddlZddlZddlmZ ddlmZmZmZ  eej        d¦  «        rej                             d¬¦  «          ee¦  «                             ¦   «         j        j        j        Zed	z  d
z  Zg d¢Zdddddddœdddddddœdddddddœdddddd dœd!d"d#d$d%d!d&d'œd(d)d*d+d,d(d-d'œd.d/d0d1d2d.d3d4œd5œZd6e d7<    G d8„ d9ej!        j"        ¦  «        Z# G d:„ d;ej$        ¦  «        Z%e&d<k    r ej'        ¦   «          dS dS )=aÙ  
Empirical Challenger Test Suite: Adversarial Stress-Testing of Reactive i18n & Chat UI (Milestone 2).
Validates:
1. Sub-second rapid programmatic switching between all 9 languages (< 1000ms SLA).
2. Deep DOM update veracity for non-Latin scripts (Chinese, Japanese, Korean, Thai, German umlauts, Russian Cyrillic).
3. Zero console errors or unhandled page exceptions under stress.
4. Resilience against race conditions, rapid interleaved UI events, and headless timeouts.
é    )ÚannotationsN)ÚPath)ÚAnyÚDictÚListÚreconfigurezutf-8)ÚencodingÚclientÚwebapp)	ÚviÚenÚzhÚjaÚkoÚthÚdeÚruÚesu   ä¸–ç•Œu   ç³»ç»Ÿu   å�‘é€�u	   å·²é”�å®šu'   ç³»ç»Ÿé¢‘é�“ä»…ä¾›æœ�åŠ¡å™¨å…¬å‘Šä½¿ç”¨)Útab_1Útab_6Úsend_btnÚbadge_lockedÚplaceholder_subÚsys_warn_subu   ãƒ¯ãƒ¼ãƒ«ãƒ‰u   ã‚·ã‚¹ãƒ†ãƒ u   é€�ä¿¡u	   ãƒ­ãƒƒã‚¯u<   ã‚·ã‚¹ãƒ†ãƒ ãƒ�ãƒ£ãƒ³ãƒ�ãƒ«ã�¯ã‚µãƒ¼ãƒ�ãƒ¼å‘ŠçŸ¥å°‚ç”¨ã�§ã�™u   ì›”ë“œu	   ì‹œìŠ¤í…œu   ì „ì†¡u   ìž ê¹€u1   ì‹œìŠ¤í…œ ì±„ë„�ì�€ ì„œë²„ ê³µì§€ ì „ìš©ìž…ë‹ˆë‹¤u	   à¹‚à¸¥à¸�u   à¸£à¸°à¸šà¸šu	   à¸ªà¹ˆà¸‡u   à¸¥à¹‡à¸­à¸„u~   à¸Šà¹ˆà¸­à¸‡à¸£à¸°à¸šà¸šà¸ªà¸³à¸«à¸£à¸±à¸šà¸›à¸£à¸°à¸�à¸²à¸¨à¸ˆà¸²à¸�à¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹€à¸—à¹ˆà¸²à¸™à¸±à¹‰à¸™ÚWeltu	   FlÃ¼sternÚSystemÚSendenÚGesperrtu8   Der Systemkanal ist fÃ¼r ServerankÃ¼ndigungen reserviert)r   Útab_5r   r   r   r   r   u   ÐœÐ¸Ñ€u
   Ð¨ÐµÐ¿Ð¾Ñ‚u   Ð¡Ð¸Ñ�Ñ‚ÐµÐ¼Ð°u   ÐžÑ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÑŒu   Ð‘Ð»Ð¾ÐºuU   Ð¡Ð¸Ñ�Ñ‚ÐµÐ¼Ð½Ñ‹Ð¹ ÐºÐ°Ð½Ð°Ð» Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ� Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ð¹ Ñ�ÐµÑ€Ð²ÐµÑ€Ð°ÚMundou   OpiniÃ³nÚSistemaÚEnviarÚ	Bloqueadou>   El canal de sistema estÃ¡ reservado para anuncios del servidor)r   Útab_8r   r   r   r   r   )r   r   r   r   r   r   r   zDict[str, Dict[str, str]]ÚNON_LATIN_EXPECTATIONSc                  ó   — e Zd ZdZd
d„Zd	S )ÚQuietHTTPHandlerzCSuppresses stdout access logging during adversarial test execution.ÚformatÚstrÚargsr   ÚreturnÚNonec                ó   — d S ©N© )Úselfr(   r*   s      úAC:\Projects\FreeExile\tests\e2e\test_challenger_i18n_m2_stress.pyÚlog_messagezQuietHTTPHandler.log_message_   s   € Øˆó    N)r(   r)   r*   r   r+   r,   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r2   r/   r3   r1   r'   r'   \   s.   € € € € € ØMÐMðð ð ð ð ð r3   r'   c                  ó¤   — e Zd ZU dZdZded<   dZded<   dZded	<   d
Zded<   e	dd„¦   «         Z
e	dd„¦   «         Zdd„Zdd„Zdd„Zdd„Zdd„ZdS )ÚTestChallengerI18nM2StresszGAdversarial stress-testing suite for FreeExile reactive i18n subsystem.Nz&http.server.ThreadingHTTPServer | NoneÚserverzthreading.Thread | NoneÚserver_threadr   ÚintÚserver_portÚ r)   Ú
server_urlr+   r,   c                óŒ  — t          j        t          t          t          ¦  «        ¬¦  «        }t
          j                             d|¦  «        | _        t          | j        j	        d         ¦  «        | _
        d| j
        › �| _        t          j        | j        j        d¬¦  «        | _        | j                             ¦   «          d S )N)Ú	directory)z	127.0.0.1r   é   zhttp://127.0.0.1:T)ÚtargetÚdaemon)Ú	functoolsÚpartialr'   r)   Ú
WEBAPP_DIRÚhttpr:   ÚThreadingHTTPServerr<   Úserver_addressr=   r?   Ú	threadingÚThreadÚserve_foreverr;   Ústart)ÚclsÚhandlers     r1   Ú
setUpClassz%TestChallengerI18nM2Stress.setUpClassk   s›   € åÔ#Õ$4ÅÅJÁÄÐPÑPÔPˆå”[×4Ò4Ð5EÀwÑOÔOˆŒ
Ý˜cœjÔ7¸Ô:Ñ;Ô;ˆŒØ>¨S¬_Ð>Ð>ˆŒÝ%Ô,°C´JÔ4LÐUYÐZÑZÔZˆÔØÔ×ÒÑ!Ô!Ð!Ð!Ð!r3   c                ó|   — | j         r4| j                              ¦   «          | j                              ¦   «          d S d S r.   )r:   ÚshutdownÚserver_close)rO   s    r1   ÚtearDownClassz(TestChallengerI18nM2Stress.tearDownClassu   sD   € àŒ:ð 	&ØŒJ×ÒÑ!Ô!Ð!ØŒJ×#Ò#Ñ%Ô%Ð%Ð%Ð%ð	&ð 	&r3   Úplaywright_instancer   útuple[Any, Any, List[str]]c                ór  ‡— |j                              dd¬¦  «        }|                     ¦   «         }g Š|                     dˆfd„¦  «         dˆfd
„}|                     d|¦  «         |                     | j        › d�d¬¦  «         |                     dd¬¦  «         |                     d¦  «         ||‰fS )NÚmsedgeT)ÚchannelÚheadlessÚ	pageerrorc                ó4   •— ‰                      d| › �¦  «        S )NzPageError: )Úappend)ÚerrÚ	js_errorss    €r1   ú<lambda>z7TestChallengerI18nM2Stress._init_page.<locals>.<lambda>€   s   ø€ ¨×)9Ò)9Ð:MÈÐ:MÐ:MÑ)NÔ)N€ r3   Úmsgr   r+   r,   c                óœ   •‡— | j         dk    r<| j        Št          ˆfd„dD ¦   «         ¦  «        s‰                     d‰› �¦  «         d S d S d S )NÚerrorc              3  ó    •K  — | ]}|‰v V — Œ	d S r.   r/   )Ú.0ÚignÚtxts     €r1   ú	<genexpr>zPTestChallengerI18nM2Stress._init_page.<locals>.handle_console.<locals>.<genexpr>…   s'   øè è € ÐOÐO¨#˜3 #˜:ÐOÐOÐOÐOÐOÐOr3   )Ú404Úfaviconzapi/mapzConsoleError: )ÚtypeÚtextÚanyr^   )rb   rh   r`   s    @€r1   Úhandle_consolez=TestChallengerI18nM2Stress._init_page.<locals>.handle_console‚   ss   øø€ ØŒx˜7Ò"Ð"Ø”h�ÝÐOÐOÐOÐOÐ1NÐOÑOÔOÑOÔOð =Ø×$Ò$Ð%;°cÐ%;Ð%;Ñ<Ô<Ð<Ð<Ð<ð #Ð"ð=ð =r3   Úconsolez/index.htmlÚdomcontentloaded)Ú
wait_untilz
#chat-dockiˆ  )Útimeoutzu() => { document.getElementById('modal-char-create')?.classList.add('hidden'); window.chatUI?.toggleChatDock(true); })rb   r   r+   r,   )ÚchromiumÚlaunchÚnew_pageÚonÚgotor?   Úwait_for_selectorÚevaluate)r0   rV   ÚbrowserÚpagero   r`   s        @r1   Ú
_init_pagez%TestChallengerI18nM2Stress._init_page{   sì   ø€ Ø%Ô.×5Ò5¸hÐQUÐ5ÑVÔVˆØ×ÒÑ!Ô!ˆØ!ˆ	à�Š�ÐNÐNÐNÐNÑOÔOÐOð	=ð 	=ð 	=ð 	=ð 	=ð 	=ð 	�Š�	˜>Ñ*Ô*Ð*Ø�	Š	�T”_Ð1Ð1Ð1Ð>Pˆ	ÑQÔQÐQØ×Ò˜|°TÐÑ:Ô:Ð:Ø�Šð5ñ	
ô 	
ð 	
ð ˜˜iÐ'Ð'r3   c                óP  — ddl m}  |¦   «         5 }|                      |¦  «        \  }}}	 |                     d¦  «        }|d         }|                      |dd|› d�¦  «         |                      |d         d	¦  «         |                      |d
         d¦  «         |                      |d         d¦  «         |                      t          |¦  «        dd|› �¦  «         |                     ¦   «          n# |                     ¦   «          w xY w	 ddd¦  «         dS # 1 swxY w Y   dS )zLAsserts rapid switching across all 9 languages in under 1 second (< 1000ms).r   ©Úsync_playwrightaL  () => {
                    const locales = ['vi', 'en', 'zh', 'ja', 'ko', 'th', 'de', 'ru', 'es'];
                    const t0 = performance.now();
                    for (let round = 0; round < 3; round++) {
                        for (const loc of locales) {
                            window.FreeExileI18n.setLocale(loc);
                        }
                    }
                    const totalDurationMs = performance.now() - t0;
                    return {
                        totalDurationMs,
                        currentLocale: window.FreeExileI18n.getLocale(),
                        tab1Text: document.querySelector('#chat-dock .chat-channel-tab[data-channel-id="1"]')?.textContent,
                        sendBtnText: document.getElementById('chat-send-btn')?.textContent
                    };
                }ÚtotalDurationMsg     @�@zRapid 9-lang cycle took zms, exceeded 1s limitÚcurrentLocaler   Útab1Textr    ÚsendBtnTextr"   z&Errors logged during rapid switching: N)Úplaywright.sync_apir€   r}   rz   Ú
assertLessÚassertEqualÚlenÚclose)r0   r€   Úpr{   r|   r`   Úperf_resultÚduration_mss           r1   Ú/test_01_rapid_programmatic_switching_sub_secondzJTestChallengerI18nM2Stress.test_01_rapid_programmatic_switching_sub_second‘   s„  € à7Ð7Ð7Ð7Ð7Ð7àˆ_ÑÔð 	  !Ø'+§¢°qÑ'9Ô'9Ñ$ˆG�T˜9ð à"Ÿmšmð -ñ ô �ð" *Ð*;Ô<�à—’ ¨VÐ5rÐP[Ð5rÐ5rÐ5rÑsÔsÐsØ× Ò  ¨_Ô!=¸tÑDÔDÐDØ× Ò  ¨ZÔ!8¸'ÑBÔBÐBØ× Ò  ¨]Ô!;¸XÑFÔFÐFØ× Ò ¥ Y¡¤°Ð4hÐ]fÐ4hÐ4hÑiÔiÐià—’‘”��ø�—’‘”��øøø�ð;	 ð 	 ð 	 ñ 	 ô 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 øøøð 	 ð 	 ð 	 ð 	 ð 	 ð 	 s)   ‘D¬B3C4ÃDÃ4D
Ä
DÄDÄ"Dc                óŽ  — ddl m}  |¦   «         5 }|                      |¦  «        \  }}}	 t                               ¦   «         D �]\  }}|                     d|› d�¦  «         |                     d¦  «        }|                      ||d         d|› d�¦  «         |                     d	¦  «        }	|                      |	|d
         d|› d�¦  «         d|v r6|                     d¦  «        }
|                      |
|d         d|› d�¦  «         d|v r6|                     d¦  «        }|                      ||d         d|› d�¦  «         |                     d¦  «        }|                      ||d         d|› d�¦  «         |                     d¦  «         |                     dd¦  «        pd}|  	                    |d         |d|› d|d         › d�¦  «         |                     d¦  «         |                     dd¦  «        pd}|  	                    |d         |d|› d�¦  «         |                     d¦  «        }|                      ||d          d|› d!�¦  «         �Œ|                      t          |¦  «        dd"|› �¦  «         |                     ¦   «          n# |                     ¦   «          w xY w	 d#d#d#¦  «         d#S # 1 swxY w Y   d#S )$zJVerifies DOM updates match catalog expectations for all non-Latin scripts.r   r   z window.FreeExileI18n.setLocale('z')z1#chat-dock .chat-channel-tab[data-channel-id="1"]r   zLocale 'z' tab 1 mismatchz1#chat-dock .chat-channel-tab[data-channel-id="6"]r   z' tab 6 mismatchr   z1#chat-dock .chat-channel-tab[data-channel-id="5"]u   ' tab 5 (FlÃ¼stern) mismatchr$   z1#chat-dock .chat-channel-tab[data-channel-id="8"]u   ' tab 8 (OpiniÃ³n) mismatchz#chat-send-btnr   z' send btn mismatchzwindow.chatUI.switchChannel(1)z#chat-inputÚplaceholderr>   r   z' placeholder did not contain 'ú'zwindow.chatUI.switchChannel(6)r   z+' system lock text missing from placeholderz#chat-cooldown-badger   z' badge text mismatchz,Errors encountered during non-Latin checks: N)r…   r€   r}   r%   Úitemsrz   Ú
inner_textr‡   Úget_attributeÚassertInrˆ   r‰   )r0   r€   rŠ   r{   r|   r`   ÚlocÚexpectedÚtab1Útab6Útab5Útab8r   r�   Úsys_placeholderÚ
badge_texts                   r1   Ú*test_02_non_latin_dom_veracity_all_scriptszETestChallengerI18nM2Stress.test_02_non_latin_dom_veracity_all_scripts´   s  € à7Ð7Ð7Ð7Ð7Ð7àˆ_ÑÔð 2	  !Ø'+§¢°qÑ'9Ô'9Ñ$ˆG�T˜9ð0 Ý%;×%AÒ%AÑ%CÔ%Cð +rñ +r‘M�C˜à—M’MÐ"LÀSÐ"LÐ"LÐ"LÑMÔMÐMð  Ÿ?š?Ð+^Ñ_Ô_�DØ×$Ò$ T¨8°GÔ+<Ð>^ÈÐ>^Ð>^Ð>^Ñ_Ô_Ð_ð  Ÿ?š?Ð+^Ñ_Ô_�DØ×$Ò$ T¨8°GÔ+<Ð>^ÈÐ>^Ð>^Ð>^Ñ_Ô_Ð_ð  (Ð*Ð*Ø#ŸšÐ/bÑcÔc˜Ø×(Ò(¨¨x¸Ô/@ÐBnÈSÐBnÐBnÐBnÑoÔoÐoØ (Ð*Ð*Ø#ŸšÐ/bÑcÔc˜Ø×(Ò(¨¨x¸Ô/@ÐBmÈSÐBmÐBmÐBmÑnÔnÐnð  $ŸšÐ/?Ñ@Ô@�HØ×$Ò$ X¨x¸
Ô/CÐEhÐPSÐEhÐEhÐEhÑiÔiÐið —M’MÐ"BÑCÔCÐCØ"&×"4Ò"4°]ÀMÑ"RÔ"RÐ"XÐVX�KØ—M’MØ Ð!2Ô3Ø#Øe 3ÐeÐeÀxÐPaÔGbÐeÐeÐeñô ð ð —M’MÐ"BÑCÔCÐCØ&*×&8Ò&8¸ÈÑ&VÔ&VÐ&\ÐZ\�OØ—M’MØ  Ô0Ø'ØS 3ÐSÐSÐSñô ð ð "&§¢Ð1GÑ!HÔ!H�JØ×$Ò$ Z°¸.Ô1IÐKpÐVYÐKpÐKpÐKpÑqÔqÐqÑqà× Ò ¥ Y¡¤°Ð4nÐclÐ4nÐ4nÑoÔoÐoà—’‘”��ø�—’‘”��øøø�ðe2	 ð 2	 ð 2	 ñ 2	 ô 2	 ð 2	 ð 2	 ð 2	 ð 2	 ð 2	 ð 2	 ð 2	 øøøð 2	 ð 2	 ð 2	 ð 2	 ð 2	 ð 2	 s)   ‘J:¬IJÉ>J:ÊJ)Ê)J:Ê:J>ËJ>c                ó  — ddl m}  |¦   «         5 }|                      |¦  «        \  }}}	 d}|                     |¦  «        }|                      |d         d¦  «         |                      |d         d¦  «         |                      |d         d	¦  «         |                      t          |¦  «        dd
|› �¦  «         |                     ¦   «          n# |                     ¦   «          w xY w	 ddd¦  «         dS # 1 swxY w Y   dS )z[Stress-tests interleaved locale changes, tooltip opens, and channel switches with 0 errors.r   r   u¨  () => {
                    const testItem = {
                        itemUuid: 'stress_item_001',
                        signature: 'valid_sig_123',
                        itemName: 'ThÃ¡i Cá»• TÃ  Ä�ao',
                        rarity: 5,
                        element: 4,
                        quality: 20,
                        itemLevel: 85,
                        crafterName: 'ThiÃªn CÃ´ng',
                        affixes: [{ statName: 'SÃ¡t ThÆ°Æ¡ng Há»�a', statValue: 125, isImplicit: true }],
                        isVerified: true
                    };
                    window.chatUI.registerItemSnapshot(testItem);
                    window.chatUI.openItemTooltip(testItem);

                    const locales = ['zh', 'ja', 'ko', 'th', 'de', 'ru', 'es', 'vi', 'en'];
                    for (let i = 0; i < 50; i++) {
                        const loc = locales[i % locales.length];
                        window.FreeExileI18n.setLocale(loc);
                        window.chatUI.switchChannel((i % 8) + 1);
                    }
                    return {
                        tooltipVisible: !document.getElementById('modal-item-link-tooltip').classList.contains('hidden'),
                        tooltipSub: document.getElementById('item-tooltip-sub')?.textContent,
                        hmacBadge: document.getElementById('item-tooltip-hmac-badge')?.textContent
                    };
                }ÚtooltipVisiblez7Tooltip should remain open and reactive during switchesÚ
tooltipSubz Tooltip subtext must not be nullÚ	hmacBadgezHMAC badge must not be nullz%Detected console errors under burst: N)	r…   r€   r}   rz   Ú
assertTrueÚassertIsNotNoner‡   rˆ   r‰   )r0   r€   rŠ   r{   r|   r`   Ústress_scriptÚress           r1   Ú;test_03_zero_console_errors_under_burst_events_and_tooltipszVTestChallengerI18nM2Stress.test_03_zero_console_errors_under_burst_events_and_tooltipsì   sY  € à7Ð7Ð7Ð7Ð7Ð7àˆ_ÑÔð '	  !Ø'+§¢°qÑ'9Ô'9Ñ$ˆG�T˜9ð% ð!�ð8 —m’m MÑ2Ô2�Ø—’ Ð$4Ô 5Ð7pÑqÔqÐqà×$Ò$ S¨Ô%6Ð8ZÑ[Ô[Ð[Ø×$Ò$ S¨Ô%5Ð7TÑUÔUÐUØ× Ò ¥ Y¡¤°Ð4gÐ\eÐ4gÐ4gÑhÔhÐhà—’‘”��ø�—’‘”��øøø�ðO'	 ð '	 ð '	 ñ '	 ô '	 ð '	 ð '	 ð '	 ð '	 ð '	 ð '	 ð '	 øøøð '	 ð '	 ð '	 ð '	 ð '	 ð '	 s)   ‘C:¬BCÂ>C:ÃC)Ã)C:Ã:C>ÄC>c                ó4  — ddl m}  |¦   «         5 }|                      |¦  «        \  }}}	 |                     d¦  «        }|                      |d         d         dd¦  «         |                      |d         d         d	d
¦  «         |                      |d         d         dd¦  «         |                      t          |¦  «        dd|› �¦  «         |                     ¦   «          n# |                     ¦   «          w xY w	 ddd¦  «         dS # 1 swxY w Y   dS )z\Verifies resilience against concurrent async events, storage sync, and rapid unsubscription.r   r   aq  () => {
                    let callCounts = { a: 0, b: 0, c: 0 };
                    const unsubA = window.FreeExileI18n.subscribe(() => { callCounts.a++; });
                    const unsubB = window.FreeExileI18n.subscribe(() => { callCounts.b++; });
                    const unsubC = window.FreeExileI18n.subscribe(() => { callCounts.c++; });

                    // Concurrently dispatch custom events and direct setLocale
                    for (let i = 0; i < 20; i++) {
                        if (i === 5) unsubA();
                        if (i === 10) unsubB();
                        window.FreeExileI18n.setLocale(i % 2 === 0 ? 'vi' : 'en');
                        window.dispatchEvent(new CustomEvent('freeexile:localeChanged', {
                            detail: { locale: 'en' }
                        }));
                    }
                    unsubC();

                    return {
                        callCounts,
                        finalLocale: window.FreeExileI18n.getLocale(),
                        listenerCount: window.FreeExileI18n.listeners.length
                    };
                }Ú
callCountsÚaé   z/Unsubscribed listener A must not receive eventsÚbé
   z/Unsubscribed listener B must not receive eventsÚcé   z$Listener C must receive all 20 callsz%Errors during race condition stress: N)r…   r€   r}   rz   r‡   rˆ   r‰   )r0   r€   rŠ   r{   r|   r`   Úrace_ress          r1   Ú7test_04_race_conditions_and_headless_timeout_resiliencezRTestChallengerI18nM2Stress.test_04_race_conditions_and_headless_timeout_resilience  sn  € à7Ð7Ð7Ð7Ð7Ð7àˆ_ÑÔð 	  !Ø'+§¢°qÑ'9Ô'9Ñ$ˆG�T˜9ð ØŸ=š=ð *ñ ô �ð. × Ò  ¨,Ô!7¸Ô!<¸aÐArÑsÔsÐsØ× Ò  ¨,Ô!7¸Ô!<¸bÐBsÑtÔtÐtØ× Ò  ¨,Ô!7¸Ô!<¸bÐBhÑiÔiÐiØ× Ò ¥ Y¡¤°Ð4gÐ\eÐ4gÐ4gÑhÔhÐhà—’‘”��ø�—’‘”��øøø�ð?	 ð 	 ð 	 ñ 	 ô 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 øøøð 	 ð 	 ð 	 ð 	 ð 	 ð 	 s)   ‘D¬B%C&ÃDÃ&C<Ã<DÄDÄD)r+   r,   )rV   r   r+   rW   )r4   r5   r6   r7   r:   Ú__annotations__r;   r=   r?   ÚclassmethodrQ   rU   r}   r�   r�   r¦   r°   r/   r3   r1   r9   r9   c   s  € € € € € € ØQÐQà59€FÐ9Ð9Ð9Ñ9Ø-1€MÐ1Ð1Ð1Ñ1Ø€KÐÐÐÑØ€JÐÐÐÑàð"ð "ð "ñ „[ð"ð ð&ð &ð &ñ „[ð&ð
(ð (ð (ð (ð,! ð ! ð ! ð ! ðF6 ð 6 ð 6 ð 6 ðp+ ð + ð + ð + ðZ# ð # ð # ð # ð # ð # r3   r9   Ú__main__)(r7   Ú
__future__r   ÚbuiltinsÚ@py_builtinsÚ_pytest.assertion.rewriteÚ	assertionÚrewriteÚ
@pytest_arrE   Úhttp.serverrH   ÚsysrK   ÚtimeÚunittestÚpathlibr   Útypingr   r   r   ÚhasattrÚstdoutr   Ú__file__ÚresolveÚparentÚPROJECT_ROOTrG   ÚALL_9_LOCALESr%   r±   r:   ÚSimpleHTTPRequestHandlerr'   ÚTestCaser9   r4   Úmainr/   r3   r1   ú<module>rË      s©  ððð ð ð #Ð "Ð "Ð "Ð "Ð "à  € € € € € € € € € € € € Ð Ð Ð Ð Ø Ð Ð Ð Ø 
€
€
€
Ø Ð Ð Ð Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø "Ð "Ð "Ð "Ð "Ð "Ð "Ð "Ð "Ð "à
€7ˆ3Œ:�}Ñ%Ô%ð -Ø„J×Ò GÐÑ,Ô,Ð,àˆt�H‰~Œ~×%Ò%Ñ'Ô'Ô.Ô5Ô<€Ø˜HÑ$ xÑ/€
àFÐFÐF€ð ØØØ#Ø#ØAðð ð  ØØØ#Ø)ØVðð ð ØØØ Ø#ØKðð ð ØØØ&Ø&ð Yðð ð ØØØØ"Ø!ØRðð ð ØØ!Ø(Ø"Ø#Øoðð ð ØØØØ#Ø"ØXðð ðg<5ð <5Ð ð <ð <ð <ñ <ð~ð ð ð ð �t”{Ô;ñ ô ð ðY ð Y ð Y ð Y ð Y  Ô!2ñ Y ô Y ð Y ðx ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr3   