§
    #–¿jo#  ã                   ó2  — d 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mZ ddlmZ ddlmZ ddlmZ g d¢Zg d¢Z ej        d	¦  «        Zg d
¢Zg  ej        dej        ¦  «        ‘ ej        dej        ¦  «        ‘ ej        d¦  «        ‘ ej        d¦  «        ‘ ej        d¦  «        ‘ ej        d¦  «        ‘ ej        d¦  «        ‘ ej        d¦  «        ‘ ej        d¦  «        ‘ ej        dej        ¦  «        ‘ ej        dej        ¦  «        ‘ ej        dej        ¦  «        ‘ ej        dej        ¦  «        ‘ ej        dej        ¦  «        ‘ ej        d¦  «        ‘ ej        d¦  «        ‘ ej        dej        ¦  «        ‘ ej        d¦  «        ‘ ej        d¦  «        ‘ ej        d¦  «        ‘ ej        d¦  «        ‘ ej        d ¦  «        ‘ ej        d!¦  «        ‘ ej        d"ej        ¦  «        ‘ ej        d#¦  «        ‘ ej        d$¦  «        ‘ ej        d%¦  «        ‘ ej        d&¦  «        ‘ ej        d'¦  «        ‘ ej        d(¦  «        ‘ ej        d)¦  «        ‘Zd*„ Zd+„ Zd,„ Zd-„ Zd.„ Zd/„ Zd0„ Z d1„ Z!d2„ Z"dS )3zß
Unit test suite for FreeExile 9-Language Novel Localization Integrity.
Validates 100% adherence to canonical nomenclature, 216 chapter files,
0 residual Vietnamese characters in non-VI editions, and 0 vulgarity/anomalies.
é    N)ÚPath)ÚCHAPTER_TITLES)ÚCANONICAL_SECTION_HEADINGS)ÚENTITY_DICTIONARY)	ÚviÚenÚzhÚjaÚkoÚthÚdeÚruÚes)r   r	   r
   r   r   r   r   r   u“   [ÄƒÃ¢Ä‘ÃªÃ´Æ¡Æ°Ä‚Ã‚Ä�ÃŠÃ”Æ Æ¯áº±áº§á»�á»“á»�á»«áº³áº©áº»á»ƒá»‰á»�á»•á»Ÿá»§á»­á»·áºµáº«áº½á»…Ä©Ãµá»—á»¡Å©á»¯á»¹áº¡áº·áº­áº¹á»‡á»‹á»�á»™á»£á»¥á»±á»µ])zCon CotzNuoc DuczHac ThizHoang Cot ThozHung Sa CotzBang LoizLai Bo Thi Langz	Dai DoanhzCo ThizKim Van NhuczVu Hoa Shinhzfloorable sandwich bowlzMenstrual HatezSEXUALITY RISEu   æŒ‰æ‘©é»‘äººzKIM LOAN ELECTRICITYzTWO BINH CHANGEz	Chan Thuyz
Chan Thienz	Thanh LaczHai Monz	Trong Daou
   Qing Láº¡czJiang KyzNIVELA EL JIANG KYõ   ê³ ìœ„ ê°�ê·¤õ   é«˜ä½�ã�®ã�¿ã�‹ã‚“ÚmenstruÚ
monatsblutu   à¸›à¸£à¸°à¸ˆà¸³à¹€à¸”à¸·à¸­à¸™u   ç»�è¡€u   ç»�æœŸu   çµŒè¡€u   çµŒæœŸu   ìƒ�ë¦¬u	   ìƒ�ë¦¬í˜ˆz\bperiods?\bu   \bper[iÃ­]odos?\bz\bperiode[n]?\bu   \bÐ¿ÐµÑ€Ð¸Ð¾Ð´\w*zjiang kyr   r   zcapital of deathu	   æ­»åˆ‘æœŸu   æ­»åˆ‘æ™‚ä»£u   ì‚¬í˜•ì‹œëŒ€u   ì‚¬í˜•ìˆ˜\s*ê°�ì˜¥\s*ê¸°ê°„u<   à¸Šà¹ˆà¸§à¸‡à¸ˆà¸³à¸„à¸¸à¸�à¸›à¸£à¸°à¸«à¸²à¸£à¸Šà¸µà¸§à¸´à¸•u-   à¸Šà¹ˆà¸§à¸‡à¹�à¸«à¹ˆà¸‡à¸„à¸§à¸²à¸¡à¸•à¸²à¸¢zZeit des Todesu   å‰‘æ´¾å�²è¯—çº§u   å£®å¤§ã�ªæ™‚ä»£u   ê²€íŒŒì�˜ ì„œì‚¬ì‹œu!   à¸¢à¸¸à¸„à¸¡à¸«à¸²à¸�à¸²à¸žà¸¢à¹Œu   ã‚¼ãƒ³ãƒˆ\d*u   ä¸ƒå¹´å‰�ä¸ƒå¹´å‰�z$vor sieben Jahren.*vor sieben Jahrenc            	      óÞ  — t           D �]c} t          dd¦  «        D �]N}d| › d|d›d�}t          j        |¦  «        }t          |¦  «        }d}||k    }|�st	          j        d|fd||f¦  «        d	t          j        ¦   «         v st	          j        t          ¦  «        rt	          j	        t          ¦  «        nd	d
t          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        nd
t	          j	        |¦  «        t	          j	        |¦  «        dœz  }t	          j
        d|› d| › �¦  «        dz   d|iz  }t          t	          j        |¦  «        ¦  «        ‚dx}x}}�ŒP�ŒedS )zKVerify that all 24 chapters across 9 canonical languages exist (216 files).é   é   únovels/locales/ú/act_*/chuong_Ú03dú_*.md©ú==©z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sÚlenÚmatches©Úpy0Úpy1Úpy3Úpy6úMissing chapter z for language z
>assert %(py8)sÚpy8N)Ú	LANGUAGESÚrangeÚglobr   Ú
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚ_format_assertmsgÚAssertionErrorÚ_format_explanation)	ÚlangÚchÚpatternr   Ú@py_assert2Ú@py_assert5Ú@py_assert4Ú@py_format7Ú@py_format9s	            úEC:\Projects\FreeExile\tests\unit\test_novel_localization_integrity.pyÚ)test_exactly_216_localized_chapters_existr<   B   s¨  € åð Rñ RˆÝ˜˜2‘,”,ð 	Rñ 	RˆBØI¨ÐIÐI¸BÐIÐIÐIÐIˆGÝ”i Ñ(Ô(ˆGÝ�w‘<”<ÐQ 1ÐQ�< 1Ò$ÐQÐQÑQÕQÔQÐQÐQÐQÐQ�< 1ÐQÑQÔQÐQÕQÔQÑQÔQÐQÐQÕQÔQ•3ÑQÔQÐQÕQÔQ•3ÑQÔQÐQÐQÐQÕQÔQÑQÔQÐQÐQÕQÔQ�wÑQÔQÐQÕQÔQ�wÑQÔQÐQÐQÕQÔQ�<ÑQÔQÕQÔQ 1ÑQÔQÐQÐQÑQÐQÕQÔQÐ&Q¸Ð&QÐ&QÈ4Ð&QÐ&QÑQÔQÐQÑQÐQÐQÐQÑQÐQÕQÕQÔQÐQÑQÔQÑQÔQÐQÐQÐQÐQÐQÐQÐQÑQñ	RðRð Ró    c            	      ó^	  — dddddœ} t          dd¦  «        D �]“}t          D �]‡}t          j        d|› d	|d
›d�¦  «        }|s€t          j        d|› d|› �¦  «        dz   ddt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndiz  }t          t          j
        |¦  «        ¦  «        ‚t          |d         ¦  «                             d¬¦  «        }|                     ¦   «         d                              ¦   «         }t          |         |         }|dk    r«d|› d|› �}||v }	|	s—t          j        d|	fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }
dd|
iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}	�Œº|dv r­d|› d |› �}||k    }	|	s—t          j        d!|	fd"||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }
dd|
iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}	�Œk|d#k    r­d$|› d%|› �}||k    }	|	s—t          j        d!|	fd"||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }
dd|
iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}	�Œ|d&k    r­d'|› d|› �}||k    }	|	s—t          j        d!|	fd"||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }
dd|
iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}	�ŒÑ| |         }d(|› d)|› d|› �}||k    }	|	s—t          j        d!|	fd"||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }
dd|
iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}	�Œ‰�Œ•dS )*zNVerify that every chapter title level-1 heading matches the canonical catalog.ÚCHAPTERÚKAPITELu
   Ð“Ð›Ð�Ð’Ð�u	   CAPÃ�TULO)r   r   r   r   r   r   r   r   r   r   r%   z for z
>assert %(py0)sr!   Úfilesr   úutf-8©Úencodingr   u	   CHÆ¯Æ NG z: )Úin)z%(py1)s in %(py3)sÚ
first_line)r"   r#   zassert %(py5)sÚpy5N)r	   r
   u   # ç¬¬u   ç« ï¼šr   )z%(py1)s == %(py3)sr   u   # ì œu   ìž¥: r   u   # à¸šà¸—à¸—à¸µà¹ˆ z# ú )r(   r'   r)   r*   r0   r,   r-   r.   r/   r1   r2   r   Ú	read_textÚ
splitlinesÚstripr   r+   )Ú
prefix_mapr4   r3   rA   Ú@py_format1ÚcontentrF   ÚtitleÚ@py_assert0r6   Ú@py_format4Ú@py_format6Úprefixs                r;   Ú#test_chapter_titles_match_canonicalrT   J   sÍ  € ð ØØØð	ð €Jõ �A�r‰lŒlð Añ AˆÝð 	Añ 	AˆDÝ”IÐQ°ÐQÐQÀBÐQÐQÐQÐQÑRÔRˆEØÐ<Õ<Ô<Ð<¨RÐ<Ð<°dÐ<Ð<Ñ<Ô<Ð<Ñ<Ð<Ð<Õ<Ô<Ñ<Ô<Ð<Ð<Õ<Ô<�5Ñ<Ô<Ð<Õ<Ô<�5Ñ<Ô<Ð<Ð<Ð<Ñ<Ð<Õ<Õ<Ô<Ð<Ñ<Ô<Ñ<Ô<Ð<Ý˜5 œ8‘n”n×.Ò.¸Ð.Ñ@Ô@ˆGØ ×+Ò+Ñ-Ô-¨aÔ0×6Ò6Ñ8Ô8ˆJÝ" 2Ô& tÔ,ˆEà�tŠ|ˆ|Ø0 2Ð0Ð0¨Ð0Ð0Ð>Ð0°JÐ>Ð>Ð>Ð>Õ>Ô>Ð>Ð>Ð>Ð>Ð0°JÐ>Ñ>Ô>Õ>Ô>Ð0Ñ>Ô>Ð>Õ>Ô>Ñ>Ô>Ð>Ð>Õ>Ô>°JÑ>Ô>Ð>Õ>Ô>°JÑ>Ô>Ð>Ð>Ð>Ð>Ñ>Ð>Ð>Ð>Ð>Ð>Ñ>Ð>Õ>Õ>Ô>Ð>Ñ>Ô>Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ñ>Ø˜Ð%Ð%Ø0˜rÐ0Ð0¨Ð0Ð0Ð>Ð0°JÒ>Ð>Ð>Ð>Õ>Ô>Ð>Ð>Ð>Ð>Ð0°JÐ>Ñ>Ô>Õ>Ô>Ð0Ñ>Ô>Ð>Õ>Ô>Ñ>Ô>Ð>Ð>Õ>Ô>°JÑ>Ô>Ð>Õ>Ô>°JÑ>Ô>Ð>Ð>Ð>Ð>Ñ>Ð>Ð>Ð>Ð>Ð>Ñ>Ð>Õ>Õ>Ô>Ð>Ñ>Ô>Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ñ>Ø˜’�Ø/˜rÐ/Ð/¨Ð/Ð/Ð=Ð/°:Ò=Ð=Ð=Ð=Õ=Ô=Ð=Ð=Ð=Ð=Ð/°:Ð=Ñ=Ô=Õ=Ô=Ð/Ñ=Ô=Ð=Õ=Ô=Ñ=Ô=Ð=Ð=Õ=Ô=°:Ñ=Ô=Ð=Õ=Ô=°:Ñ=Ô=Ð=Ð=Ð=Ð=Ñ=Ð=Ð=Ð=Ð=Ð=Ñ=Ð=Õ=Õ=Ô=Ð=Ñ=Ô=Ñ=Ô=Ð=Ð=Ð=Ð=Ð=Ñ=Ø˜’�Ø9¨BÐ9Ð9°%Ð9Ð9ÐGÐ9¸ZÒGÐGÐGÐGÕGÔGÐGÐGÐGÐGÐ9¸ZÐGÑGÔGÕGÔGÐ9ÑGÔGÐGÕGÔGÑGÔGÐGÐGÕGÔG¸ZÑGÔGÐGÕGÔG¸ZÑGÔGÐGÐGÐGÐGÑGÐGÐGÐGÐGÐGÑGÐGÕGÕGÔGÐGÑGÔGÑGÔGÐGÐGÐGÐGÐGÑGà# DÔ)�Ø2˜FÐ2Ð2 RÐ2Ð2¨5Ð2Ð2Ð@Ð2°jÒ@Ð@Ð@Ð@Õ@Ô@Ð@Ð@Ð@Ð@Ð2°jÐ@Ñ@Ô@Õ@Ô@Ð2Ñ@Ô@Ð@Õ@Ô@Ñ@Ô@Ð@Ð@Õ@Ô@°jÑ@Ô@Ð@Õ@Ô@°jÑ@Ô@Ð@Ð@Ð@Ð@Ñ@Ð@Ð@Ð@Ð@Ð@Ñ@Ð@Õ@Õ@Ô@Ð@Ñ@Ô@Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ñ@ñ#	AðAð Ar=   c                  óÊ  — t          dd¦  «        D �]Ð} t          j        d| d›d�¦  «        }t          |d         ¦  «                             d¬¦  «        }d	„ |                     ¦   «         D ¦   «         }t
          D �]d}t          j        d
|› d| d›d�¦  «        }t          |d         ¦  «                             d¬¦  «        }d„ |                     ¦   «         D ¦   «         }t          |¦  «        }t          |¦  «        }	||	k    }
|
�s³t          j        d|
fd||	f¦  «        dt          j
        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nddt          j
        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        dt          j
        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nddt          j
        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |	¦  «        dœz  }t          j        d| › d|› dt          |¦  «        › dt          |¦  «        › �¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}
}	t!          |¦  «        D �]\  }}t"          ||                  |         }||k    }|sät          j        d|fd||f¦  «        dt          j
        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddt          j
        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d| › d|› d|› d|› d �	¦  «        d!z   d"|iz  }t          t          j        |¦  «        ¦  «        ‚d}�Œ�Œf�ŒÒdS )#zRVerify that every section heading in all 216 files matches the canonical headings.r   r   znovels/locales/vi/act_*/chuong_r   r   r   rB   rC   c                 ó„   — g | ]=}|                      ¦   «                              d ¦  «        ¯)|                      ¦   «         ‘Œ>S ©z### ©rK   Ú
startswith©Ú.0Úls     r;   ú
<listcomp>zAtest_all_113_section_headings_match_canonical.<locals>.<listcomp>k   s<   € ÐbÐbÐb QÀQÇWÂWÁYÄY×EYÒEYÐZ`ÑEaÔEaÐb�q—w’w‘y”yÐbÐbÐbr=   r   r   c                 ó„   — g | ]=}|                      ¦   «                              d ¦  «        ¯)|                      ¦   «         ‘Œ>S rW   rX   rZ   s     r;   r]   zAtest_all_113_section_headings_match_canonical.<locals>.<listcomp>p   s<   € ÐjÐjÐj¨1ÈQÏWÊWÉYÌY×MaÒMaÐbhÑMiÔMiÐj˜QŸWšW™YœYÐjÐjÐjr=   r   )zN%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py8)s
{%(py8)s = %(py5)s(%(py6)s)
}r   Úlang_headingsÚvi_headings)r!   r"   r#   rG   r$   r&   zChapter z (z) has z headings, expected z
>assert %(py10)sÚpy10N)z%(py0)s == %(py2)sÚhÚexpected©r!   Úpy2z) heading mismatch: 'z' != 'ú'ú
>assert %(py4)sÚpy4)r(   r)   r   rI   rJ   ÚNON_VI_LANGUAGESr   r*   r+   r,   r-   r.   r/   r0   r1   r2   Ú	enumerater   )r4   Úvi_filesÚ
vi_contentr`   r3   Ú
lang_filesÚlang_contentr_   r6   Ú@py_assert7r8   r:   Ú@py_format11Úidxrb   rc   Ú@py_assert1Ú@py_format3Ú@py_format5s                      r;   Ú-test_all_113_section_headings_match_canonicalru   f   s®  € å�A�r‰lŒlð ñ ˆÝ”9ÐL¸rÐLÐLÐLÐLÑMÔMˆÝ˜( 1œ+Ñ&Ô&×0Ò0¸'Ð0ÑBÔBˆ
ØbÐb¨*×*?Ò*?Ñ*AÔ*AÐbÑbÔbˆå$ð 	ñ 	ˆDÝœÐ#V°TÐ#VÐ#VÈÐ#VÐ#VÐ#VÐ#VÑWÔWˆJÝ 
¨1¤Ñ.Ô.×8Ò8À'Ð8ÑJÔJˆLØjÐj°×0GÒ0GÑ0IÔ0IÐjÑjÔjˆMå�}Ñ%Ô%ð ­¨[Ñ)9Ô)9ð Ð%Ð)9Ò9ð ð ñ õ ìðð ð ð Ð%Ð)9ð ñ ô ð õ äñô ð ð õ ìõ ñ ô ð õ äõ ñ ô ð ð ð õ äñô ð ð õ ìð %ñ ô ð õ äð %ñ ô ð ð õ äð &ñ ô ð õ äñô ð ð õ ìõ *-ñ ô ð õ äõ *-ñ ô ð ð ð õ äñô ð ð õ ìð .9ñ ô ð õ äð .9ñ ô ð ð õ äð *:ñ ô ð ð ñ ð õ ìð h˜2ÐgÐg ÐgÐg­S°Ñ-?Ô-?ÐgÐgÕUXÐYdÑUeÔUeÐgÐgñô ð ñ ð ð ð ñ ð õ õ ìðñ ô ñ ô ð ð ð ð ð ð ð õ $ MÑ2Ô2ð ñ ‘��QÝ5°kÀ#Ô6FÔGÈÔM�Ø˜H’}ð ð ð õ ä ðð ð ð �q˜Hð ñ ô ð õ äñô ð ð õ ìð ñ ô ð õ äð ñ ô ð ð ð õ äñô ð ð õ ìð %ñ ô ð õ äð %ñ ô ð ð ð ð ñ ð õ ä ð U˜rÐTÐT TÐTÐTÀÐTÐTÈÐTÐTÐTñô ð ñ ð ð ð ñ ð õ õ ìðñ ô ñ ô ð ð ð ñ ññ	ðð r=   c                  ó"  — g } t           D ]€}t          j        d|› d�¦  «        D ]e}t          |¦  «                             d¬¦  «        }t                               |¦  «        }|r$|                      |t          |¦  «        f¦  «         ŒfŒ�|  }|s}t          j	        d| › �¦  «        dz   ddt          j        ¦   «         v st          j        | ¦  «        rt          j        | ¦  «        ndiz  }t          t          j        |¦  «        ¦  «        ‚d	}d	S )
zIVerify that zero pure Vietnamese characters remain in any non-VI edition.r   ú/act_*/*.mdrB   rC   z&Found residual Vietnamese diacritics: ú
>assert not %(py0)sr!   Ú
violationsN)ri   r)   r   rI   ÚPURE_VI_DIACRITICSÚfindallÚappendÚsetr*   r0   r,   r-   r.   r/   r1   r2   )ry   r3   ÚfpathrN   r   rr   Ú@py_format2s          r;   Ú.test_zero_pure_vietnamese_diacritics_in_non_vir€   |   s0  € à€JÝ ð 9ð 9ˆÝ”YÐB°ÐBÐBÐBÑCÔCð 	9ð 	9ˆEÝ˜5‘k”k×+Ò+°WÐ+Ñ=Ô=ˆGÝ(×0Ò0°Ñ9Ô9ˆGØð 9Ø×!Ò! 5­#¨g©,¬,Ð"7Ñ8Ô8Ð8øð		9ð ˆ>ÐPˆ>ÐPÕPÔPÐPÀJÐPÐPÑPÔPÐPÑPÐPÐPÕPÔPÑPÔPÐPÐPÕPÔPˆzÑPÔPÐPÕPÔPˆzÑPÔPÐPÐPÐPÑPÐPÕPÕPÔPÐPÑPÔPÑPÔPÐPÐPÐPÐPÐPr=   c                  óì  — g } t           D ]e}t          j        d|› d�¦  «        D ]J}t          |¦  «                             d¬¦  «        }t          D ]}||v r|                      ||f¦  «         ŒŒKŒf|  }|s}t          j        d| › �¦  «        dz   ddt          j	        ¦   «         v st          j
        | ¦  «        rt          j        | ¦  «        ndiz  }t          t          j        |¦  «        ¦  «        ‚d	}d	S )
zNVerify that no corrupted tokens or vulgar machine-translation artifacts exist.r   rw   rB   rC   z"Found anomalous or vulgar tokens: rx   r!   ÚfoundN)ri   r)   r   rI   ÚANOMALOUS_STRINGSr|   r*   r0   r,   r-   r.   r/   r1   r2   )r‚   r3   r~   rN   Útokenrr   r   s          r;   Ú%test_zero_anomalous_or_vulgar_stringsr…   ˆ   s+  € à€EÝ ð 1ð 1ˆÝ”YÐB°ÐBÐBÐBÑCÔCð 	1ð 	1ˆEÝ˜5‘k”k×+Ò+°WÐ+Ñ=Ô=ˆGÝ*ð 1ð 1�Ø˜GÐ#Ð#Ø—L’L %¨ Ñ0Ô0Ð0øð1ð	1ð ˆ9ÐBˆ9ÐBÕBÔBÐB¸5ÐBÐBÑBÔBÐBÑBÐBÐBÕBÔBÑBÔBÐBÐBÕBÔBˆuÑBÔBÐBÕBÔBˆuÑBÔBÐBÐBÐBÑBÐBÕBÕBÔBÐBÑBÔBÑBÔBÐBÐBÐBÐBÐBr=   c                  ó  — g } t           D ]~}t          j        d|› d�¦  «        D ]c}t          |¦  «                             d¬¦  «        }t          D ]6}|                     |¦  «        }|r|                      ||j        |f¦  «         Œ7ŒdŒ|  }|s}t          j	        d| › �¦  «        dz   ddt          j        ¦   «         v st          j        | ¦  «        rt          j        | ¦  «        ndiz  }t          t          j        |¦  «        ¦  «        ‚d	}d	S )
u\   Verify that zero menstrual or inappropriate period/era mistranslations of 'kinh ká»³' exist.r   rw   rB   rC   z8Found forbidden menstrual/period mistranslation tokens: rx   r!   r‚   N)ri   r)   r   rI   ÚFORBIDDEN_KINH_KY_PATTERNSr{   r|   r5   r*   r0   r,   r-   r.   r/   r1   r2   )r‚   r3   r~   rN   Úpatr   rr   r   s           r;   Ú1test_zero_menstrual_or_inappropriate_period_termsr‰   ”   sH  € à€EÝ ð @ð @ˆÝ”YÐB°ÐBÐBÐBÑCÔCð 	@ð 	@ˆEÝ˜5‘k”k×+Ò+°WÐ+Ñ=Ô=ˆGÝ1ð @ð @�ØŸ+š+ gÑ.Ô.�Øð @Ø—L’L %¨¬°gÐ!>Ñ?Ô?Ð?øð@ð	@ð ˆ9ÐXˆ9ÐXÕXÔXÐXÐQVÐXÐXÑXÔXÐXÑXÐXÐXÕXÔXÑXÔXÐXÐXÕXÔXˆuÑXÔXÐXÕXÔXˆuÑXÔXÐXÐXÐXÑXÐXÕXÕXÔXÐXÑXÔXÑXÔXÐXÐXÐXÐXÐXr=   c                  óÐ  — g } t           D ]W}t          j        d|› d�¦  «        D ]<}t          |¦  «                             ¦   «         }d|v r|                      |¦  «         Œ=ŒX|  }|s}t          j        d| › �¦  «        dz   ddt          j        ¦   «         v st          j	        | ¦  «        rt          j
        | ¦  «        ndiz  }t          t          j        |¦  «        ¦  «        ‚d}dS )	z?Verify that all 216 chapter files strictly use LF line endings.r   rw   s   
zFiles with CRLF endings: rx   r!   Ú
crlf_filesN)r'   r)   r   Ú
read_bytesr|   r*   r0   r,   r-   r.   r/   r1   r2   )r‹   r3   r~   Údatarr   r   s         r;   Ú'test_no_crlf_line_endings_in_any_localerŽ   ¡   s  € à€JÝð )ð )ˆÝ”YÐB°ÐBÐBÐBÑCÔCð 	)ð 	)ˆEÝ˜‘;”;×)Ò)Ñ+Ô+ˆDØ˜$ˆˆØ×!Ò! %Ñ(Ô(Ð(øð	)ð
 ˆ>ÐCˆ>ÐCÕCÔCÐC°zÐCÐCÑCÔCÐCÑCÐCÐCÕCÔCÑCÔCÐCÐCÕCÔCˆzÑCÔCÐCÕCÔCˆzÑCÔCÐCÐCÐCÑCÐCÕCÕCÔCÐCÑCÔCÑCÔCÐCÐCÐCÐCÐCr=   c                  ó¶	  — t          t          ¦  «        } d}| |k    }|süt          j        d|fd| |f¦  «        dt	          j        ¦   «         v st          j        t           ¦  «        rt          j        t           ¦  «        nddt	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        ndt          j        | ¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x} x}}t          t          ¦  «        } d
}| |k    }|süt          j        d|fd| |f¦  «        dt	          j        ¦   «         v st          j        t           ¦  «        rt          j        t           ¦  «        nddt	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        ndt          j        | ¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x} x}}t          t          ¦  «        } d}| |k    }|süt          j        d|fd| |f¦  «        dt	          j        ¦   «         v st          j        t           ¦  «        rt          j        t           ¦  «        nddt	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        ndt          j        | ¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x} x}}d„ t          D ¦   «         }d}t          ||¬¦  «        }||k    }|�sEt          j        d|fd||f¦  «        dt	          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddt	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nddt	          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          j        d¦  «        dz   d|iz  }	t          t          j	        |	¦  «        ¦  «        ‚d	x}x}}d	S )z'Verify catalog imports and size limits.é   r   r   r   r   r    zassert %(py8)sr&   Néq   r   éd   )ú>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)sr   c                 ó8   — g | ]}t          |d          ¦  «        ‘ŒS )r   )r   )r[   Úes     r;   r]   z6test_catalogs_and_entity_integrity.<locals>.<listcomp>³   s"   € Ð4Ð4Ð4˜Q�s�1�Q”4‰yŒyÐ4Ð4Ð4r=   T)Úreverse)zA%(py0)s == %(py7)s
{%(py7)s = %(py2)s(%(py3)s, reverse=%(py5)s)
}ÚlengthsÚsorted)r!   re   r#   rG   Úpy7z1ENTITY_DICTIONARY not sorted descending by lengthz
>assert %(py9)sÚpy9)r   r   r*   r+   r,   r-   r.   r/   r1   r2   r   r   r˜   r0   )
r6   r7   r8   r9   r:   r—   Ú@py_assert6rr   Ú@py_format8Ú@py_format10s
             r;   Ú"test_catalogs_and_entity_integrityrž   ¬   sõ  € å�~ÑÔÐ$ "Ð$Ð "Ò$Ð$Ð$Ð$Õ$Ô$Ð$Ð$Ð$Ð$Ð "Ð$Ñ$Ô$Ð$Õ$Ô$Ñ$Ô$Ð$Ð$Õ$Ô$�3Ñ$Ô$Ð$Õ$Ô$�3Ñ$Ô$Ð$Ð$Ð$Õ$Ô$Ñ$Ô$Ð$Ð$Õ$Ô$�~Ñ$Ô$Ð$Õ$Ô$�~Ñ$Ô$Ð$Ð$Õ$Ô$ÐÑ$Ô$Õ$Ô$ "Ñ$Ô$Ð$Ð$Ñ$Ð$Ð$Ð$Ð$Ð$Ñ$Ð$Õ$Õ$Ô$Ð$Ñ$Ô$Ñ$Ô$Ð$Ð$Ð$Ð$Ð$Ð$Ð$ÝÕ)Ñ*Ô*Ð1¨cÐ1Ð*¨cÒ1Ð1Ð1Ð1Õ1Ô1Ð1Ð1Ð1Ð1Ð*¨cÐ1Ñ1Ô1Ð1Õ1Ô1Ñ1Ô1Ð1Ð1Õ1Ô1�3Ñ1Ô1Ð1Õ1Ô1�3Ñ1Ô1Ð1Ð1Ð1Õ1Ô1Ñ1Ô1Ð1Ð1Õ1Ô1Õ)Ñ1Ô1Ð1Õ1Ô1Õ)Ñ1Ô1Ð1Ð1Õ1Ô1Ð*Ñ1Ô1Õ1Ô1¨cÑ1Ô1Ð1Ð1Ñ1Ð1Ð1Ð1Ð1Ð1Ñ1Ð1Õ1Õ1Ô1Ð1Ñ1Ô1Ñ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1ÝÕ Ñ!Ô!Ð( SÐ(Ð! SÒ(Ð(Ð(Ð(Õ(Ô(Ð(Ð(Ð(Ð(Ð! SÐ(Ñ(Ô(Ð(Õ(Ô(Ñ(Ô(Ð(Ð(Õ(Ô(�3Ñ(Ô(Ð(Õ(Ô(�3Ñ(Ô(Ð(Ð(Ð(Õ(Ô(Ñ(Ô(Ð(Ð(Õ(Ô(Õ Ñ(Ô(Ð(Õ(Ô(Õ Ñ(Ô(Ð(Ð(Õ(Ô(Ð!Ñ(Ô(Õ(Ô( SÑ(Ô(Ð(Ð(Ñ(Ð(Ð(Ð(Ð(Ð(Ñ(Ð(Õ(Õ(Ô(Ð(Ñ(Ô(Ñ(Ô(Ð(Ð(Ð(Ð(Ð(Ð(Ð(ð 5Ð4Õ"3Ð4Ñ4Ô4€GØ.2Ðh•f˜W¨dÐ3Ñ3Ô3Ðhˆ7Ð3Ò3ÐhÐhÑhÕhÔhÐhÐhÐhÐhˆ7Ð3ÐhÑhÔhÐhÕhÔhÑhÔhÐhÐhÕhÔhˆ7ÑhÔhÐhÕhÔhˆ7ÑhÔhÐhÐhÐhÕhÔhÑhÔhÐhÐhÕhÔh•fÑhÔhÐhÕhÔh•fÑhÔhÐhÐhÐhÕhÔhÑhÔhÐhÐhÕhÔh˜WÑhÔhÐhÕhÔh˜WÑhÔhÐhÐhÕhÔh¨dÑhÔhÕhÔhÐ3ÑhÔhÐhÐhÑhÐhÕhÔhÐ5hÑhÔhÐhÑhÐhÐhÐhÑhÐhÕhÕhÔhÐhÑhÔhÑhÔhÐhÐhÐhÐhÐhÐhÐhÐhÐhr=   c            	      ót  — g d¢} | D �]/\  }}}t          j         d|› d|› �¦  «        D �]}t          |¦  «                             d¬¦  «        }||v}|sÞt          j        d|fd||f¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndd	t          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nd	d
œz  }t          j	        d|› d|› d�¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d}�Œ�Œ1dS )zPVerify that audited first-person slips in third-person narration are eradicated.))r   zchuong_001_*.mdztearing through my dry lungs)r   zchuong_009_*.mdz&receded to my knees, then to my ankles)r   úchuong_010_*.mdz My blade was made of Crude Flint)r   r    zIn just one slash, I cut)r   zchuong_015_*.mdzcorners of my dry, cracked lips)r   r    u[   à¹ƒà¸šà¸¡à¸µà¸”à¸‚à¸­à¸‡à¸‰à¸±à¸™à¸—à¸³à¸ˆà¸²à¸� à¸«à¸´à¸™à¹€à¸«à¸¥à¹‡à¸�à¹„à¸Ÿà¸«à¸¢à¸²à¸š)r   r    u3   à¸‰à¸±à¸™à¸•à¸±à¸”à¹‚à¸‹à¹ˆà¹€à¸«à¸¥à¹‡à¸�à¸«à¸™à¸²)r
   zchuong_022_*.mdu?   ã‚‚ã�—ç§�ã�Ÿã�¡ã�Œã��ã�®è…�ã�£ã�ŸçŽ‹åº§ã‚’ç ´å£Šã�—ã�ªã�‘ã‚Œã�°r   z/act_*/rB   rC   )únot in)z%(py0)s not in %(py2)sÚforbidden_strrN   rd   zFound POV slip in z: 'rf   rg   rh   N)r)   r   rI   r*   r+   r,   r-   r.   r/   r0   r1   r2   )	Úchecksr3   Úglob_patr¢   r~   rN   rr   rs   rt   s	            r;   Ú test_zero_pov_slips_in_narrationr¥   ¶   s“  € ð	ð 	ð 	€Fð *0ð añ aÑ%ˆˆh˜Ý”YÐH°ÐHÐH¸hÐHÐHÑIÔIð 	añ 	aˆEÝ˜5‘k”k×+Ò+°WÐ+Ñ=Ô=ˆGØ ¨Ð/Ð`Ð`Ð`Õ`Ô`Ð`Ð`Ð`Ð`�=¨Ð`Ñ`Ô`Ð`Õ`Ô`Ñ`Ô`Ð`Ð`Õ`Ô`�=Ñ`Ô`Ð`Õ`Ô`�=Ñ`Ô`Ð`Ð`Ð`Õ`Ô`Ñ`Ô`Ð`Ð`Õ`Ô`¨Ñ`Ô`Ð`Õ`Ô`¨Ñ`Ô`Ð`Ð`Ð`Ð`Ñ`Ð`Õ`Ô`Ð1`ÀeÐ1`Ð1`ÐP]Ð1`Ð1`Ð1`Ñ`Ô`Ð`Ñ`Ð`Ð`Ð`Ñ`Ð`Õ`Õ`Ô`Ð`Ñ`Ô`Ñ`Ô`Ð`Ð`Ð`Ñ`ñ	aðað ar=   )#Ú__doc__Úbuiltinsr,   Ú_pytest.assertion.rewriteÚ	assertionÚrewriter*   ÚosÚrer)   ÚpytestÚpathlibr   Ú'tools.localization.novel_titles_catalogr   Ú)tools.localization.novel_headings_catalogr   Ú)tools.localization.novel_entities_catalogr   r'   ri   Úcompilerz   rƒ   Ú
IGNORECASEr‡   r<   rT   ru   r€   r…   r‰   rŽ   rž   r¥   © r=   r;   ú<module>rµ      sk  ððð ð € € € € € € € € € € € € €	€	€	€	Ø 	€	€	€	Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð à BÐ BÐ BÐ BÐ BÐ BØ PÐ PÐ PÐ PÐ PÐ PØ GÐ GÐ GÐ GÐ GÐ GàBÐBÐB€	ØCÐCÐCÐ à�R”Zð  !wñ  xô  xÐ ðð ð Ð ð Ø€B„Jˆz˜2œ=Ñ)Ô)ð à€B„Jˆ}˜bœmÑ,Ô,ð ð €B„JÐ0Ñ1Ô1ð ð €B„JˆyÑÔð	 ð
 €B„JˆyÑÔð ð €B„JˆyÑÔð ð €B„JˆyÑÔð ð €B„JˆyÑÔð ð €B„Jˆ|ÑÔð ð €B„Jˆ ¤Ñ.Ô.ð ð €B„JÐ# R¤]Ñ3Ô3ð ð €B„JÐ! 2¤=Ñ1Ô1ð ð €B„JÐ# R¤]Ñ3Ô3ð ð €B„Jˆ{˜BœMÑ*Ô*ð ð €B„JÐ$Ñ%Ô%ð ð  €B„JÐÑ Ô ð! ð" €B„JÐ" B¤MÑ2Ô2ð# ð$ €B„Jˆ|ÑÔð% ð& €B„JˆÑÔð' ð( €B„JˆÑÔð) ð* €B„JÐ-Ñ.Ô.ð+ ð, €B„JÐNÑOÔOð- ð. €B„JÐ?Ñ@Ô@ð/ ð0 €B„JÐ  "¤-Ñ0Ô0ð1 ð2 €B„JÐ!Ñ"Ô"ð3 ð4 €B„JÐ!Ñ"Ô"ð5 ð6 €B„JÐ%Ñ&Ô&ð7 ð8 €B„JÐ3Ñ4Ô4ð9 ð: €B„JˆÑÔð; ð< €B„JÐ$Ñ%Ô%ð= ð> €B„JÐ6Ñ7Ô7ð? Ð ðDRð Rð RðAð Að Að8ð ð ð,
Qð 
Qð 
Qð
Cð 
Cð 
CðYð Yð Yð	Dð 	Dð 	Dðið ið iðað að að að ar=   