
    ̆hce                       S r SSKJr  SSKrSSKrSSKJr  SSKJrJ	r	  SSK
Jr  SSKJrJr  SSKJrJr  \(       a  SS	KJrJr  SS
KJr  S S jrS S jrS!S jr " S S\5      r " S S5      r " S S5      r     S"             S#S jjr\R<                  " S5      rS S jr S$S%S jjr!S&S jr"        S'                     S(S jjr#SSSSSSSS.                 S)S jjr$S*S jr%g)+z
babel.messages.pofile
~~~~~~~~~~~~~~~~~~~~~

Reading and writing of files in the ``gettext`` PO (portable object)
format.

:copyright: (c) 2013-2025 by the Babel Team.
:license: BSD, see LICENSE for more details.
    )annotationsN)Iterable)TYPE_CHECKINGLiteral)Locale)CatalogMessage)TextWrapper_cmp)IOAnyStr)SupportsWritec                X    S n[         R                  " S5      R                  XSS 5      $ )zReverse `escape` the given string.

>>> print(unescape('"Say:\\n  \\"hello, world!\\"\\n"'))
Say:
  "hello, world!"
<BLANKLINE>

:param string: the string to unescape
c                R    U R                  S5      nUS:X  a  gUS:X  a  gUS:X  a  gU$ )N   n
t	r)group)matchms     M/opt/services/DDDS/venv/lib/python3.13/site-packages/babel/messages/pofile.pyreplace_escapes!unescape.<locals>.replace_escapes&   s2    KKN8#X#X    z\\([\\trn"])r   )recompilesub)stringr   s     r   unescaper$      s)    	 ::o&**?1RLIIr   c                    SU ;   aL  U R                  5       nU R                  S5      (       a  USS n[        [        U5      nSR	                  U5      $ [        U 5      $ )a  Reverse the normalization done by the `normalize` function.

>>> print(denormalize(r'''""
... "Say:\n"
... "  \"hello, world!\"\n"'''))
Say:
  "hello, world!"
<BLANKLINE>

>>> print(denormalize(r'''""
... "Say:\n"
... "  \"Lorem ipsum dolor sit "
... "amet, consectetur adipisicing"
... " elit, \"\n"'''))
Say:
  "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
<BLANKLINE>

:param string: the string to denormalize
r   ""r   N )
splitlines
startswithmapr$   join)r#   escaped_linesliness      r   denormalizer.   3   s[    * v~))+T"")!"-MHm,wwu~r   c                   SU ;  a$  SU ;  a  U R                  5       R                  5       $ / nSnSnU  Hp  nUS:X  a  U(       a  [        S5      eSnM  US:X  a  U(       d  [        S5      eSnM;  US:X  a+  U(       a  X$-  nMN  U(       a  UR                  U5        SnMj  Ml  X$-  nMr     U(       a#  U(       a  [        S5      eUR                  U5        U$ )	zExtract locations from location comments.

Locations are extracted while properly handling First Strong
Isolate (U+2068) and Pop Directional Isolate (U+2069), used by
gettext to enclose filenames with spaces and tabs in their names.
   ⁨   ⁩r'   Fzglocation comment contains more First Strong Isolate characters, than Pop Directional Isolate charactersTzglocation comment contains more Pop Directional Isolate characters, than First Strong Isolate characters )lstripsplit
ValueErrorappend)line	locationslocationin_filenamecs        r   _extract_locationsr<   R   s     t 4{{}""$$IHK=  "W X XK(]  "T U UK#X  *  MH) ,   "W X XX&r   c                  0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )PoFileError~   zDException thrown by PoParser when an invalid po file is encountered.c                R   > [         TU ]  U SU 35        X l        X0l        X@l        g )Nz on )super__init__catalogr7   lineno)selfmessagerC   r7   rD   	__class__s        r   rB   PoFileError.__init__   s*    G9D12	r   )rC   r7   rD   )
rF   strrC   r   r7   rI   rD   intreturnNone)__name__
__module____qualname____firstlineno____doc__rB   __static_attributes____classcell__)rG   s   @r   r>   r>   ~   s    N r   r>   c                      \ rS rSrSS jrSS jrSS jrSS jrSS jrSS jr	SS jr
SS	 jrSS
 jrSS jrSS jrSS jrSrg)_NormalizedString   c                F    / U l         U H  nU R                  U5        M     g N)_strsr6   )rE   argsargs      r   rB   _NormalizedString.__init__   s     "
CKK r   c                V    U R                   R                  UR                  5       5        g rX   )rY   r6   strip)rE   ss     r   r6   _NormalizedString.append   s    

!'')$r   c                T    SR                  [        [        U R                  5      5      $ )Nr'   )r+   r*   r$   rY   rE   s    r   r.   _NormalizedString.denormalize   s    wws8TZZ011r   c                ,    [        U R                  5      $ rX   )boolrY   rb   s    r   __bool___NormalizedString.__bool__   s    DJJr   c                T    [         R                  R                  U R                  5      $ rX   )oslinesepr+   rY   rb   s    r   __repr___NormalizedString.__repr__   s    zztzz**r   c                N    U(       d  g[        [        U 5      [        U5      5      $ )Nr   )r   rI   rE   others     r   __cmp___NormalizedString.__cmp__   s    CIs5z**r   c                *    U R                  U5      S:  $ Nr   rp   rn   s     r   __gt___NormalizedString.__gt__       ||E"Q&&r   c                *    U R                  U5      S:  $ rs   rt   rn   s     r   __lt___NormalizedString.__lt__   rw   r   c                *    U R                  U5      S:  $ rs   rt   rn   s     r   __ge___NormalizedString.__ge__       ||E"a''r   c                *    U R                  U5      S:*  $ rs   rt   rn   s     r   __le___NormalizedString.__le__   r~   r   c                *    U R                  U5      S:H  $ rs   rt   rn   s     r   __eq___NormalizedString.__eq__   r~   r   c                *    U R                  U5      S:g  $ rs   rt   rn   s     r   __ne___NormalizedString.__ne__   r~   r   )rY   N)rZ   rI   rK   rL   )r_   rI   rK   rL   )rK   rI   )rK   re   )ro   objectrK   rJ   )ro   r   rK   re   )rM   rN   rO   rP   rB   r6   r.   rf   rk   rp   ru   ry   r|   r   r   r   rR    r   r   rU   rU      s>    
%2 ++''((((r   rU   c                      \ rS rSrSr/ SQrSSS jjrSS jrSS jrSS jr	SSS jjr
SSS	 jjrSS
 jrSS jrSS jrSS jrSrg)PoFileParser   zSupport class to  read messages from a ``gettext`` PO (portable object) file
and add them to a `Catalog`

See `read_po` for simple cases.
)msgidmsgstrmsgctxtmsgid_pluralc                d    Xl         X l        SU l        SU l        X0l        U R                  5         g rs   )rC   ignore_obsoletecounteroffsetabort_invalid_reset_message_state)rE   rC   r   r   s       r   rB   PoFileParser.__init__   s-    .*!!#r   c                    / U l         / U l        / U l        / U l        / U l        / U l        S U l        SU l        SU l        SU l	        SU l
        g )NF)messagestranslationsr8   flagsuser_commentsauto_commentscontextobsoletein_msgid	in_msgstr
in_msgctxtrb   s    r   r   !PoFileParser._reset_message_state   sR    
r   c                   U R                   R                  5         [        U R                  5      S:  a  [	        S U R                   5       5      nOU R                  S   R                  5       n[        U[        [        45      (       a  [        U R                  R                  5       Vs/ s H  nSPM     nnU R                    HO  u  pEX@R                  R                  :  a  U R                  SU R                  S5        M=  UR                  5       X4'   MQ     [	        U5      nO U R                   S   S   R                  5       nU R                  (       a  U R                  R                  5       OSn[        X[        U R                  5      [!        U R"                  5      U R$                  U R&                  U R                  S-   US9nU R(                  (       aC  U R*                  (       d1  XpR                  R(                  U R                  R-                  X5      '   OXpR                  U'   U =R.                  S-  sl        U R1                  5         gs  snf )zw
Add a message to the catalog based on the current parser state and
clear the state ready to process the next message.
r   c              3  @   #    U  H  oR                  5       v   M     g 7frX   )r.   ).0r   s     r   	<genexpr>,PoFileParser._add_message.<locals>.<genexpr>   s     A=a--//=s   r   r'   z5msg has more translations than num_plurals of catalogN)rD   r   )r   sortlenr   tupler.   
isinstancelistrangerC   num_plurals_invalid_pofiler   r   r	   r8   setr   r   r   r   r   _key_forr   r   )rE   r   _r#   idxtranslationr   rF   s           r   _add_messagePoFileParser._add_message   s   
 	 t}}!A4==AAEMM!$002EedE]++"'(@(@"AB"AQb"AFB$($5$5 ,,222((T[[:qr)557	 %6
 6]F&&q)!,88:F04$,,**,$%dnn)=s4::,,d.@.@WX")+ ==''OV%%dll&;&;E&KL")LL!!#' Cs   *Ic                .   U R                   (       a  U R                  (       db  U R                  SU R                  SU R                   S   R	                  5        S35        U R                  R                  S[        S5      /5        U R                  5         g g )Nr'   zmissing msgstr for msgid 'r   ')r   r   r   r   r.   r6   rU   r   rb   s    r   _finish_current_message$PoFileParser._finish_current_message   sz    ==$$$$R8RSWS`S`abScSoSoSqRrrs6tu!!((!->r-B)CD	 r   c                x    UR                  S5      (       a  U R                  X!5        g U R                  XU5        g )N")r)   !_process_string_continuation_line_process_keyword_line)rE   rD   r7   r   s       r   _process_message_line"PoFileParser._process_message_line   s/    ??3224@&&vX>r   c                <   U R                    H>  n UR                  U5      (       a$  U[        U5         S;   a  U[        U5      S  n  OM>  M@     U R	                  X!S5        g US;   a  U R                  5         X0l        US:X  a  Xl        US;   a3  SU l        SU l	        U R                  R                  [        U5      5        g US	:X  a  SU l	        SU l        UR                  S
5      (       aG  USS  R                  SS5      u  pgU R                  R                  [!        U5      [        U5      /5        g U R                  R                  S[        U5      /5        g US:X  a  SU l        [        U5      U l        g g ! [         a    U R	                  X!S5         GM  f = f)N)r2   [z$Keyword must be followed by a stringz0Start of line didn't match any expected keyword.)r   r   r   )r   r   FTr   r   r   ]r   r   )	_keywordsr)   r   
IndexErrorr   r   r   r   r   r   r   r6   rU   r   r4   r   rJ   r   )rE   rD   r7   r   keywordr[   r   msgs           r   r   "PoFileParser._process_keyword_line  s   ~~G[??7++S\0Bj0Ps7|}-C 1Q+ &   /ab**((*  g K//#DO DMMM  !23!78 !DM!DN~~c""qr7==a0!!((#c(4Ec4J)KL!!((!->s-C)DE	!"DO,S1DL "=  [$$T3YZZ[s   6E::FFc                   U R                   (       a  U R                  S   nOUU R                  (       a  U R                  S   S   nO1U R                  (       a  U R
                  nOU R                  XS5        g UR                  U5        g )Nr   r   z<Got line starting with " but not in msgid, msgstr or msgctxt)r   r   r   r   r   r   r   r6   )rE   r7   rD   r_   s       r   r   .PoFileParser._process_string_continuation_line-  sb    ==b!A^^!!"%a(A__A  /no	r   c                D   U R                  5         USS  R                  S5      (       a}  [        USS  5       Hj  nUR                  S5      nUS:  a3   [	        X#S-   S  5      nU R                  R                  US U U45        MM  U R                  R                  US 45        Ml     g USS  R                  S5      (       aS  USS  R                  5       R                  S5       H,  nU R                  R                  UR                  5       5        M.     g USS  R                  S5      (       a7  USS  R                  5       nU(       a  U R                  R                  U5        g g U R                  R                  USS  R                  5       5        g ! [
         a     GMf  f = f)Nr   :   r   ,.)r   r)   r<   rfindrJ   r5   r8   r6   r3   r4   r   r^   r   r   )rE   r7   r9   posrD   flagcomments          r   _process_commentPoFileParser._process_comment9  sl   $$&8s##.tABx8nnS)!8!!$XAgh%7!8 NN))8DS>6*BCNN))8T*:; 9 !"X  %%QR)//4

!!$**,/ 5!"X  %%12hnn&G""))'2  %%d12hnn&67 & ! !s   F
FFc           	        [        U5       H  u  p#UR                  5       n[        U[        5      (       d%  UR	                  U R
                  R                  5      nU(       d  MX  UR                  S5      (       aP  USS R                  S5      (       a#  U R                  X#SS R                  5       SS9  M   U R                  U5        M  U R                  X#5        M     U R                  5         U R                  (       d  U R                  (       d"  U R                   (       d  U R"                  (       a[  U R$                  R'                  [)        S5      5        U R*                  R'                  S	[)        S5      /5        U R-                  5         ggg! [         a'  nU R                  X2[        U5      5         SnAGM  SnAff = f)
z
Reads from the file-like object `fileobj` and adds any po file
units found in it to the `Catalog` supplied to the constructor.
#r   N~r   T)r   r&   r   )	enumerater^   r   rI   decoderC   charsetr)   r   r3   r   r5   r   r   r   r   r   r   r   r6   rU   r   r   )rE   fileobjrD   r7   excs        r   parsePoFileParser.parseT  sZ    &g.LF::<DdC(({{4<<#7#78s##8&&s++..vABx7HSW.XE--d3 **68 /" 	$$& ||t/A/ATEWEWMM  !24!89$$a):4)@%AB FX| & E,,T3s8DDEs   7F
GF<<Gc                    [        U[        5      (       d   eU R                  (       a  [        X0R                  X5      e[        SU5        [        SUS-    SU< 35        g )NzWARNING:zWARNING: Problem on line r   z: )r   rI   r   r>   rC   print)rE   r7   rD   r   s       r   r   PoFileParser._invalid_pofilet  sS    $$$$$c<<>>j#)&1*Rx@Ar   )r   r   rC   r   r   r   r   r   r   r   r8   r   r   r   r   r   N)FF)rC   r   r   re   r   re   rK   rL   )rK   rL   )F)r   IO[AnyStr] | Iterable[AnyStr]rK   rL   )rM   rN   rO   rP   rQ   r   rB   r   r   r   r   r   r   r   r   r   rR   r   r   r   r   r      sD    I$ $@ ?'2R
86 @Br   r   Fc                P    [        XUS9n[        XcUS9nUR                  U 5        U$ )a  Read messages from a ``gettext`` PO (portable object) file from the given
file-like object (or an iterable of lines) and return a `Catalog`.

>>> from datetime import datetime
>>> from io import StringIO
>>> buf = StringIO('''
... #: main.py:1
... #, fuzzy, python-format
... msgid "foo %(name)s"
... msgstr "quux %(name)s"
...
... # A user comment
... #. An auto comment
... #: main.py:3
... msgid "bar"
... msgid_plural "baz"
... msgstr[0] "bar"
... msgstr[1] "baaz"
... ''')
>>> catalog = read_po(buf)
>>> catalog.revision_date = datetime(2007, 4, 1)

>>> for message in catalog:
...     if message.id:
...         print((message.id, message.string))
...         print(' ', (message.locations, sorted(list(message.flags))))
...         print(' ', (message.user_comments, message.auto_comments))
(u'foo %(name)s', u'quux %(name)s')
  ([(u'main.py', 1)], [u'fuzzy', u'python-format'])
  ([], [])
((u'bar', u'baz'), (u'bar', u'baaz'))
  ([(u'main.py', 3)], [])
  ([u'A user comment'], [u'An auto comment'])

.. versionadded:: 1.0
   Added support for explicit charset argument.

:param fileobj: the file-like object (or iterable of lines) to read the PO file from
:param locale: the locale identifier or `Locale` object, or `None`
               if the catalog is not bound to a locale (which basically
               means it's a template)
:param domain: the message domain
:param ignore_obsolete: whether to ignore obsolete messages in the input
:param charset: the character set of the catalog.
:param abort_invalid: abort read if po file is invalid
)localedomainr   )r   )r   r   r   )r   r   r   r   r   r   rC   parsers           r   read_por   |  s.    l VGDG'-PF
LLNr   zL(\s+|[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))c                    SU R                  SS5      R                  SS5      R                  SS5      R                  SS	5      R                  S
S5      -  $ )zEscape the given string so that it can be included in double-quoted
strings in ``PO`` files.

>>> escape('''Say:
...   "hello, world!"
... ''')
'"Say:\\n  \\"hello, world!\\"\\n"'

:param string: the string to escape
z"%s"\z\\r   z\tr   z\rr   z\nr   z\")replace)r#   s    r   escaper     sN     FNN40"74/"74/"74/"74/	0 0r   L   c           
        U(       Ga8  US:  Ga1  [        U5      n/ nU R                  S5       GH  n[        [        U5      5      U-   U:  a  [        R	                  U5      nUR                  5         U(       a  / nSnU(       ay  [        [        US   5      5      S-
  U-   n	X-   U:  a$  UR                  UR                  5       5        X-  nO'U(       d  UR                  UR                  5       5        O	U(       a  My  UR                  SR                  U5      5        U(       a  M  M  M  UR                  U5        GM     OU R                  S5      n[        U5      S::  a  [        U 5      $ U(       a  US   (       d  US	 US==   S-  ss'   SSR                  U Vs/ s H  oQ[        U5      -   PM     sn5      -   $ s  snf )	a]  Convert a string into a format that is appropriate for .po files.

>>> print(normalize('''Say:
...   "hello, world!"
... ''', width=None))
""
"Say:\n"
"  \"hello, world!\"\n"

>>> print(normalize('''Say:
...   "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
... ''', width=32))
""
"Say:\n"
"  \"Lorem ipsum dolor sit "
"amet, consectetur adipisicing"
" elit, \"\n"

:param string: the string to normalize
:param prefix: a string that should be prepended to every line
:param width: the maximum line width; use `None`, 0, or a negative number
              to completely disable line wrapping
r   Tr   r   r'   r   r   z""
)	r   r(   r   WORD_SEPr4   reverser6   popr+   )
r#   prefixwidth	prefixlenr-   r7   chunksbufsizelengths
             r   	normalizer     sn   0 K	%%d+D6$< 9,u4!- CD !$VF2J%7!81!<y!H=50JJvzz|4 ND#& !$

6::< 8! !& LL. f  T") ,, !!$'
5zQf~ U2Y"Ib	T	DII5I54 55IJJJIs   F=
c                    SU ;  a  SU ;  a  U $ U R                  S5      (       d  SU -   n U R                  S5      (       d  U S-  n U $ )zEnclose filenames which include white spaces or tabs.

Do the same as gettext and enclose filenames which contain white
spaces or tabs with First Strong Isolate (U+2068) and Pop
Directional Isolate (U+2069).
r2   r   r0   r1   )r)   endswith)filenames    r   _enclose_filename_if_necessaryr     sS     (t83x((h&X&&HOr   Tc
                    Sn
U(       a  Sn
O	U(       a  Sn
[        UUU	UUUU
US9 HE  n[        U[        5      (       a  UR                  UR                  S5      nU R                  U5        MG     g)a-  Write a ``gettext`` PO (portable object) template file for a given
message catalog to the provided file-like object.

>>> catalog = Catalog()
>>> catalog.add(u'foo %(name)s', locations=[('main.py', 1)],
...             flags=('fuzzy',))
<Message...>
>>> catalog.add((u'bar', u'baz'), locations=[('main.py', 3)])
<Message...>
>>> from io import BytesIO
>>> buf = BytesIO()
>>> write_po(buf, catalog, omit_header=True)
>>> print(buf.getvalue().decode("utf8"))
#: main.py:1
#, fuzzy, python-format
msgid "foo %(name)s"
msgstr ""
<BLANKLINE>
#: main.py:3
msgid "bar"
msgid_plural "baz"
msgstr[0] ""
msgstr[1] ""
<BLANKLINE>
<BLANKLINE>

:param fileobj: the file-like object to write to
:param catalog: the `Catalog` instance
:param width: the maximum line width for the generated output; use `None`,
              0, or a negative number to completely disable line wrapping
:param no_location: do not emit a location comment for every message
:param omit_header: do not include the ``msgid ""`` entry at the top of the
                    output
:param sort_output: whether to sort the messages in the output by msgid
:param sort_by_file: whether to sort the messages in the output by their
                     locations
:param ignore_obsolete: whether to ignore obsolete messages and not include
                        them in the output; by default they are included as
                        comments
:param include_previous: include the old msgid as a comment when
                         updating the catalog
:param include_lineno: include line number in the location comment
NrF   r9   r   include_linenoinclude_previousno_locationomit_headersort_byr   backslashreplace)generate_por   rI   encoder   write)r   rC   r   r  r  sort_outputsort_by_filer   r  r  r  r7   s               r   write_por    sq    p G	'%)	 dC  ;;w0BCDd	r   r   c          	   #  8  ^ ^^#    T(       a  TS:  a  TOSn[        USS9m[        TSSS9n	SU4S jjn
SU U4S	 jjn[        T US
9 GH6  nUR                  (       df  U(       a  M  T R                  nT(       aC  TS:  a=  / nUR	                  5        H  nXR                  U5      -  nM     SR                  U5      nU S3v   UR                   H  nU
" U5       Sh  vN   M     UR                   H  nU
" USS9 Sh  vN   M     U(       d  / n [        UR                  S S9nU H`  u  nnUR                  [        R                  S5      n[        U5      nU(       a  U(       a  U SUS 3nUU;  d  MO  UR!                  U5        Mb     U
" SR                  U5      SS9 Sh  vN   UR"                  (       a-  SSR                  S/[        UR"                  5      Q5       S3v   UR$                  (       ap  U(       ai  U
" S['        UR$                  S   TS9 3SS9 Sh  vN   [)        UR$                  5      S:  a)  ['        UR$                  S   TS9nU
" SU 3SS9 Sh  vN   U" U5       Sh  vN   Sv   GM9     U(       d`  [        T R*                  R-                  5       US
9 H9  nUR                   H  nU
" U5       Sh  vN   M     U" USS9 Sh  vN   Sv   M;     gg GN GN! [         a    UR                  n GNf = f GNh N N N NM N<7f)z|Yield text strings representing a ``gettext`` PO (portable object) file.

See `write_po()` for a more detailed description.
r   r   F)r   break_long_wordsz# )r   subsequent_indentr  r'   c              3  p   >#    TR                  U 5       H  nSU SUR                  5        S3v   M     g 7f)Nr   r2   r   )wrapr^   )r   r   r7   comment_wrappers      r   _format_comment$generate_po.<locals>._format_comment  s6     #((1DfXQtzz|nB// 2s   36c              3    >#    [        U R                  [        [        45      (       a  U R                  (       a  U S[        U R                  UTS9 S3v   U S[        U R                  S   UTS9 S3v   U S[        U R                  S   UTS9 S3v   [        TR                  5       H)  n U R                  U   nU S	US
 S[        X1TS9 S3v   M+     g U R                  (       a  U S[        U R                  UTS9 S3v   U S[        U R                  UTS9 S3v   U S[        U R                  =(       d    SUTS9 S3v   g ! [         a    Sn Nf = f7f)Nzmsgctxt )r   r   r   msgid r   msgid_plural r   r'   zmsgstr[dz] zmsgstr )
r   idr   r   r   r   r   r   r#   r   )rF   r   r   r#   rC   r   s       r   _format_message$generate_po.<locals>._format_message  sm    gjj4-007??6Y^)_(``bccHF9WZZ]6QV#W"XXZ[[HM)GJJqM&X]*^)__abbW001 $^^C0F  Awb6X]1^0__abb 2 7??6Y^)_(``bccHF9WZZe#T"UUWXXHGIgnn.B6Y^$_#``bcc "  F s+   B,E0E?BEEEEE)r  r   Nr   )r   c                \    U S   [        U S   [        5      =(       a    U S   =(       d    S4$ )Nr   r   r   )r   rJ   )xs    r   <lambda>generate_po.<locals>.<lambda>  s*    !A$
1Q48M8VRSTURV8\Z\1]r   key/r   r  r2   r   z, r  )r   |r   r  z#~ )r'   )r
   _sort_messagesr  header_commentr(   r  r+   r   r   sortedr8   	TypeErrorr   ri   sepr   r6   r   previous_idr   r   r   values)rC   r   r  r  r  r  r  r   comment_widthheader_wrapperr  r  rF   comment_headerr-   r7   r   locsr8   r   rD   r9   norm_previous_idr  s   `      `               @r   r  r  l  s    " #uqyEbM!NO uW\]N0d d& "'7;zz$33N*557D0066E 8!%5!1#$B'',,G&w/// -,,G&ws;;; - D."7#4#4']_	
 %. &#++BFFC89(Cn"*1VAJ7H4'KK) %. 'sxx~cBBB==dii <fW]]&; <=>bAA#3&7#6#6q#9GHI   7&&'!+#,W-@-@-C5#Q *];K:L+MVYZZZ"7+++
g <j %##%
G #00*7333 1&wu===J
 Q 0;  .#--	. C
 [+ 4=s   CLK*!L>K-?LK0&AL7.L%L&A<L"L#AL$L%L4L5ALL	LLL-L0L
L	L

LLLLLLc                x    [        U 5      n US:X  a  U R                  5         U $ US:X  a  U R                  S S9  U $ )z
Sort the given message iterable by the given criteria.

Always returns a list.

:param messages: An iterable of Messages.
:param sort_by: Sort by which criteria? Options are `message` and `location`.
:return: list[Message]
rF   r9   c                    U R                   $ rX   )r8   )r   s    r   r   _sort_messages.<locals>.<lambda>  s    AKKr   r   )r   r   )r   r  s     r   r$  r$    sC     H~H) O 
J	/0Or   )r#   rI   rK   rI   )r7   rI   rK   z	list[str])NNFNF)r   r   r   zLocale | str | Noner   
str | Noner   re   r   r3  r   re   rK   r   )r'   r   )r#   rI   r   rI   r   rJ   rK   rI   )r   rI   rK   rI   )r   FFFFFFT)r   zSupportsWrite[bytes]rC   r   r   rJ   r  re   r  re   r
  re   r  re   r   re   r  re   r  re   rK   rL   )rC   r   r   re   r  re   r  re   r  re   r  re   r  %Literal['message', 'location'] | Noner   rJ   rK   zIterable[str])r   zIterable[Message]r  r4  rK   zlist[Message])&rQ   
__future__r   ri   r    collections.abcr   typingr   r   
babel.corer   babel.messages.catalogr   r	   
babel.utilr
   r   r   r   	_typeshedr   r$   r.   r<   	Exceptionr>   rU   r   r   r!   r   r   r   r   r  r  r$  r   r   r   <module>r=     s  	 # 	 	 $ )  3 (!'J. >)X) )( )(XEB EBT #'!9*99 9 	9
 9 9 9x ::  0$:Kz( !"J!JJ J 	J
 J J J J J J 
J` ""59jj j 	j
 j j j 3j j jZr   