
    Pi                       U d Z ddlmZ ddlZddlZddlmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZmZ ddlmZ ddlmZ ddlmZmZ er!ddl m!Z! e"e#e"df         z  e$e"         z  Z%de&d<   g dZ'd1dZ( ej)        dej*                  Z+d2dZ,d3d Z- G d! d"          Z. G d# d$e/          Z0d%Z1d4d'Z2d5d6d.Z3 G d/ d0          Z4dS )7z
babel.messages.catalog
~~~~~~~~~~~~~~~~~~~~~~

Data structures for message catalogs.

:copyright: (c) 2013-2026 by the Babel Team.
:license: BSD, see LICENSE for more details.
    )annotationsN)IterableIterator)copy)SequenceMatcher)message_from_string)nlargest)	Formatter)TYPE_CHECKING)__version__)LocaleUnknownLocaleError)format_datetime)
get_plural)LOCALTZ_cmp)	TypeAlias.r   
_MessageID)DEFAULT_HEADERPYTHON_FORMATCatalogMessageTranslationError   333333?c                   |dk    st          d|          d|cxk    rdk    sn t          d|          g }t          d          }|                    |            |D ]}|                    |           |                                |k    rY|                                |k    rA|                                |k    r)|                    |                                |f           t          ||          }d |D             S )	zA modified version of ``difflib.get_close_matches``.

    It just passes ``autojunk=False`` to the ``SequenceMatcher``, to work
    around https://github.com/python/cpython/issues/90825.
    r   zn must be > 0: g        g      ?zcutoff must be in [0.0, 1.0]: F)autojunkc                    g | ]\  }}|S  r   ).0scorexs      j/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/babel/messages/catalog.py
<listcomp>z%get_close_matches.<locals>.<listcomp>D   s    %%%(%A%%%    )	
ValueErrorr   set_seq2set_seq1real_quick_ratioquick_ratioratioappendr	   )wordpossibilitiesncutoffresultsr"   s          r#   get_close_matchesr3   +   s     q550100111&CD&DDEEEF'''AJJt * *	

1  F**6))		V##MM17799a.))) a  F%%f%%%%r%   z
    \%
        (?:\(([\w]*)\))?
        (
            [-#0\ +]?(?:\*|[\d]+)?
            (?:\.(?:\*|[\d]+))?
            [hlL]?
        )
        ([diouxXeEfFgGcrs%])
stringstrreturnboolc                    d| vrdS t                      }	 d}|                    |           D ]}|d         d}n# t          $ r Y dS w xY w|S )N{F   T)r
   parser&   )r4   fmtfield_name_seents       r#   _has_python_brace_formatr?   V   s    
&u
++C  6"" 	' 	'At"&	'
    uus   $; 
A	A	valuedatetime.datetimec                   t          j        d|           }t          j                            |                    d          d          }|                    d          }||d         |dd          }}|d d         |dd          }}t          | d          }t          |          }	t          |          }
|	d	z  }||
z  }||z  }t          j        t          j        |
          d|d          }|                    |          }|S )Nz+^(?P<datetime>.*?)(?P<tzoffset>[+-]\d{4})?$datetimez%Y-%m-%d %H:%Mtzoffsetr   r:      1<   )minuteszEtc/GMTz+d)offsetnametzinfo)	rematchrC   strptimegroupinttimezone	timedeltareplace)r@   rN   dtrD   plus_minus_sresthours_offset_smins_offset_s
plus_minushours_offsetmins_offsetnet_mins_offsets               r#   _parse_datetime_headerr^   i   s$   HCUKKE			#	#EKK
$;$;=M	N	NB {{:&&H%a[(122,d(,RaR$qrr( L+++,,
>**-(( '+;&:% $%o>>>/?///
 
 
 ZZxZ((Ir%   c                      e Zd ZdZ	 	 	 	 	 	 	 	 d.d/dZd0dZd1dZd2dZd2dZd2d Z	d2d!Z
d2d"Zd2d#Zd3d$Zd4d%Zd5d6d)Zed7d*            Zed7d+            Zed7d,            Zed7d-            ZdS )8r   z0Representation of a single message in a catalog. r   Nidr   r4   _MessageID | None	locationsIterable[tuple[str, int]]flagsIterable[str]auto_commentsuser_commentsprevious_idlineno
int | Nonecontext
str | Noner6   Nonec
                   || _         |s	| j        rd}|| _        |r't          t                              |                    ng | _        t          |          | _        |r"| j	        r| j        
                    d           n| j                            d           |r"| j        r| j        
                    d           n| j                            d           |r't          t                              |                    ng | _        |r't          t                              |                    ng | _        |r3t          |t                     r	|g| _        nt          |          | _        ng | _        || _        |	| _        dS )a_  Create the message object.

        :param id: the message ID, or a ``(singular, plural)`` tuple for
                   pluralizable messages
        :param string: the translated message string, or a
                       ``(singular, plural)`` tuple for pluralizable messages
        :param locations: a sequence of ``(filename, lineno)`` tuples
        :param flags: a set or sequence of flags
        :param auto_comments: a sequence of automatic comments for the message
        :param user_comments: a sequence of user comments for the message
        :param previous_id: the previous message ID, or a ``(singular, plural)``
                            tuple for pluralizable messages
        :param lineno: the line number on which the msgid line was found in the
                       PO file, if any
        :param context: the message context
        )r`   r`   zpython-formatzpython-brace-formatN)ra   pluralizabler4   listdictfromkeysrc   setre   python_formatadddiscardpython_brace_formatrg   rh   
isinstancer5   ri   rj   rl   )
selfra   r4   rc   re   rg   rh   ri   rj   rl   s
             r#   __init__zMessage.__init__   s}   8  	$+ 	F;DLdmmI66777"ZZ
 	0$$ 	0JNN?++++J/// 	6$* 	6JNN01111J4555CPXT$--">">???VXCPXT$--">">???VX 	"+s++ 5$/=  #'#4#4  !Dr%   r5   c                l    dt          |           j         d| j        dt          | j                  dS )N< z	 (flags: z)>)type__name__ra   rq   re   rz   s    r#   __repr__zMessage.__repr__   s8    S4::&SSSST$*=M=MSSSSr%   otherobjectrQ   c                L    d }t           ||            ||                    S )z0Compare Messages, taking into account plural idsc                    t          | t                    r| j        r| j        d         | j        pdfS | j        | j        pdfS )Nr   r`   )ry   r   rp   ra   rl   )objs    r#   values_to_comparez*Message.__cmp__.<locals>.values_to_compare   sJ    #w'' 4C,< 4vay#+"33363;,",,r%   )r   )rz   r   r   s      r#   __cmp__zMessage.__cmp__   s;    	- 	- 	-
 %%d++->->u-E-EFFFr%   r7   c                4    |                      |          dk    S Nr   r   rz   r   s     r#   __gt__zMessage.__gt__       ||E""Q&&r%   c                4    |                      |          dk     S r   r   r   s     r#   __lt__zMessage.__lt__   r   r%   c                4    |                      |          dk    S r   r   r   s     r#   __ge__zMessage.__ge__       ||E""a''r%   c                4    |                      |          dk    S r   r   r   s     r#   __le__zMessage.__le__   r   r%   c                4    |                      |          dk    S r   r   r   s     r#   __eq__zMessage.__eq__   r   r%   c                4    |                      |          dk    S r   r   r   s     r#   __ne__zMessage.__ne__   r   r%   c                P    t          |t                    sJ | j        |j        k    S )z[Checks whether messages are identical, taking into account all
        properties.
        )ry   r   __dict__r   s     r#   is_identicalzMessage.is_identical   s)     %)))))}..r%   c                B   t          t          | j                  t          | j                  t          | j                  t          | j                  t          | j                  t          | j                  t          | j                  | j	        | j
        	  	        S )N)	ra   r4   rc   re   rg   rh   ri   rj   rl   )r   r   ra   r4   rc   re   rg   rh   ri   rj   rl   r   s    r#   clonezMessage.clone   s    DG}}$$4>**tz""t122t122T-..;L

 

 

 
	
r%   catalogCatalog | Nonelist[TranslationError]c                    ddl m} g }|D ];}	  |||            # t          $ r}|                    |           Y d}~4d}~ww xY w|S )a  Run various validation checks on the message.  Some validations
        are only performed if the catalog is provided.  This method returns
        a sequence of `TranslationError` objects.

        :rtype: ``iterator``
        :param catalog: A catalog instance that is passed to the checkers
        :see: `Catalog.check` for a way to perform checks for all messages
              in a catalog.
        r   )checkersN)babel.messages.checkersr   r   r,   )rz   r   r   errorscheckeres         r#   checkzMessage.check   s     	544444)+ 	! 	!G!&&&&# ! ! !a        !s   
A?Ac                    d| j         v S )a   Whether the translation is fuzzy.

        >>> Message('foo').fuzzy
        False
        >>> msg = Message('foo', 'foo', flags=['fuzzy'])
        >>> msg.fuzzy
        True
        >>> msg
        <Message 'foo' (flags: ['fuzzy'])>

        :type:  `bool`fuzzyre   r   s    r#   r   zMessage.fuzzy
  s     $*$$r%   c                D    t          | j        t          t          f          S )zWhether the message is plurizable.

        >>> Message('foo').pluralizable
        False
        >>> Message(('foo', 'bar')).pluralizable
        True

        :type:  `bool`)ry   ra   rq   tupler   s    r#   rp   zMessage.pluralizable  s     $'D%=111r%   c                    | j         }t          |t          t          f          r$|D ]}t                              |          r dS  dS t          t                              |                    S )zWhether the message contains Python-style parameters.

        >>> Message('foo %(name)s bar').python_format
        True
        >>> Message(('foo %(name)s', 'foo %(name)s')).python_format
        True

        :type:  `bool`TF)ra   ry   rq   r   r   searchr7   rz   idsra   s      r#   ru   zMessage.python_format%  ss     gcD%=)) 	     ''++  44 5M((--...r%   c                    | j         }t          |t          t          f          r|D ]}t	          |          r dS dS t	          |          S )zWhether the message contains Python f-string parameters.

        >>> Message('Hello, {name}!').python_brace_format
        True
        >>> Message(('One apple', '{count} apples')).python_brace_format
        True

        :type:  `bool`TF)ra   ry   rq   r   r?   r   s      r#   rx   zMessage.python_brace_format7  s_     gcD%=)) 	    +B//  44 5',,,r%   )r`   r   r   r   r   r   NN)ra   r   r4   rb   rc   rd   re   rf   rg   rf   rh   rf   ri   r   rj   rk   rl   rm   r6   rn   r6   r5   )r   r   r6   rQ   )r   r   r6   r7   )r   r   r6   r7   )r6   r   N)r   r   r6   r   )r6   r7   )r   
__module____qualname____doc__r{   r   r   r   r   r   r   r   r   r   r   r   propertyr   rp   ru   rx   r   r%   r#   r   r      s       ::
 %'/1!')')"$!"4 4 4 4 4lT T T TG G G G' ' ' '' ' ' '( ( ( (( ( ( (( ( ( (( ( ( (/ / / /
 
 
 
    ( % % % X% 	2 	2 	2 X	2 / / / X/" - - - X- - -r%   r   c                      e Zd ZdZdS )r   z_Exception thrown by translation checkers when invalid message
    translations are encountered.N)r   r   r   r   r   r%   r#   r   r   J  s        % % % %r%   r   z# Translations template for PROJECT.
# Copyright (C) YEAR ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#dict[str, str]c                n    ddl m}  |            }| |d<   t          |                                          S )Nr   )r   content-type)email.messager   rr   
get_params)r@   r   ms      r#   parse_separated_headerr   W  s?    %%%%%%		AAnr%   utf-8strictr2   str | bytesencodingr   c                    t          | t                    r| S t          | t                    r|                     ||          S t          |           S r   )ry   r5   bytesdecode)r2   r   r   s      r#   _force_textr   `  sJ    !S !U *xx&)))q66Mr%   c                     e Zd ZdZddeddddddddddfdXdZdYdZdZdZd[dZ e	ee          Z
 e	e          Zd\dZd]d Z e	eed!"          Zd^d$Zd_d'Z e	eed("          Ze	d`d*            Ze	d\d+            Ze	d\d,            Zdad/Zd`d0Zdbd2Zd\d3Zdcd4Zddd6Zded8Z	 	 	 	 	 	 	 	 dfdgdEZdhdGZdidjdIZdidkdJZ	 	 	 	 dldmdQZ dndTZ!	 didodUZ"dpdWZ#dS )qr   z$Representation of a message catalog.NTlocaleLocale | str | Nonedomainrm   header_commentprojectversioncopyright_holdermsgid_bugs_addresscreation_datedatetime.datetime | str | Nonerevision_date6datetime.datetime | datetime.time | float | str | Nonelast_translatorlanguage_teamcharsetr   r7   r6   rn   c                \   || _         || _        || _        i | _        |pd| _        |pd| _        |pd| _        |pd| _        |
pd| _        	 |pd| _	        	 |pd| _
        |%t          j                            t                    }n<t          |t          j                  r"|j        s|                    t          	          }|| _        |	d
}	n<t          |	t          j                  r"|	j        s|	                    t          	          }	|	| _        || _        i | _        d| _        d| _        dS )aD  Initialize the catalog object.

        :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 header_comment: the header comment as string, or `None` for the
                               default header
        :param project: the project's name
        :param version: the project's version
        :param copyright_holder: the copyright holder of the catalog
        :param msgid_bugs_address: the email address or URL to submit bug
                                   reports to
        :param creation_date: the date the catalog was created
        :param revision_date: the date the catalog was revised
        :param last_translator: the name and email of the last translator
        :param language_team: the name and email of the language team
        :param charset: the encoding to use in the output (defaults to utf-8)
        :param fuzzy: the fuzzy bit on the catalog header
        PROJECTVERSIONORGANIZATIONzEMAIL@ADDRESSzFULL NAME <EMAIL@ADDRESS>zLANGUAGE <LL@li.org>r   NrK   zYEAR-MO-DA HO:MI+ZONE)r   r   _header_comment	_messagesr   r   r   r   r   r   r   rC   nowr   ry   rL   rT   r   r   r   obsolete_num_plurals_plural_expr)rz   r   r   r   r   r   r   r   r   r   r   r   r   r   s                 r#   r{   zCatalog.__init__k  sR   H -?A+)+) 0 BN"4"G.M2M<*D.D:)' $-11'::MMx'899 	B-BV 	B)111AAM* 3MMx'899 	B-BV 	B)111AAM*
 ?A  r%   c                h   |d | _         d | _        d S t          |t                    rt	          |          | _         || _        d S t          |t                    rHt	          |          | _         	 t          j        |          | _        n# t          $ r
 d | _        Y nw xY wd S t          d|          )NzD`locale` must be a Locale, a locale identifier string, or None; got )_locale_identifier_localery   r   r5   r;   r   	TypeErrorrz   r   s     r#   _set_localezCatalog._set_locale  s    >&*D#DLFff%% 	&)&kkD#!DLFfc"" 	&)&kkD#$%|F33% $ $ $#$F]SY]]
 
 	
s   /B	 	BBLocale | Nonec                    | j         S r   )r   r   s    r#   _get_localezCatalog._get_locale  s
    |r%   c                    | j         S r   )r   r   s    r#   _get_locale_identifierzCatalog._get_locale_identifier  s    &&r%   r5   c                   | j         }t          j                            t                                        d          }t          | j        d          r| j                            d          }|                    d| j                                      d| j	                                      d|                              d| j
                  }| j        r| j        j        n| j        }|r|                    d| d          }|S )	Nz%Ystrftimer   r   YEARr   zTranslations templatez translations)r   rC   r   r   r   hasattrr   rT   r   r   r   r   english_namelocale_identifier)rz   commentyearlocale_names       r#   _get_header_commentzCatalog._get_header_comment  s    & $$W--66t<<4%z22 	5%..t44DOOIt|44WY--WVT""W^T%:;;	 	 37+Ydk..4CY 	^oo&=+?\?\?\]]Gr%   r4   c                    || _         d S r   )r   )rz   r4   s     r#   _set_header_commentzCatalog._set_header_comment  s    %r%   a      The header comment for the catalog.

    >>> catalog = Catalog(project='Foobar', version='1.0',
    ...                   copyright_holder='Foo Company')
    >>> print(catalog.header_comment) #doctest: +ELLIPSIS
    # Translations template for Foobar.
    # Copyright (C) ... Foo Company
    # This file is distributed under the same license as the Foobar project.
    # FIRST AUTHOR <EMAIL@ADDRESS>, ....
    #

    The header can also be set from a string. Any known upper-case variables
    will be replaced when the header is retrieved again:

    >>> catalog = Catalog(project='Foobar', version='1.0',
    ...                   copyright_holder='Foo Company')
    >>> catalog.header_comment = '''\
    ... # The POT for my really cool PROJECT project.
    ... # Copyright (C) 1990-2003 ORGANIZATION
    ... # This file is distributed under the same license as the PROJECT
    ... # project.
    ... #'''
    >>> print(catalog.header_comment)
    # The POT for my really cool Foobar project.
    # Copyright (C) 1990-2003 Foo Company
    # This file is distributed under the same license as the Foobar
    # project.
    #

    :type: `unicode`
    )doclist[tuple[str, str]]c                   t          | j        t          j        t          j        t          t
          f          rt          | j        dd          }n| j        }| j        }| j        r,d|v r(|	                    dt          | j                            }d| j         d| j         fd| j        fdt          | j        dd          fd	|fd
| j        fg}| j        r)|                    dt          | j                  f           |                    d|f           | j        |                    d| j        f           |ddd| j         fdddt(           dfgz  }|S )Nzyyyy-MM-dd HH:mmZen)r   LANGUAGEzProject-Id-Versionr~   zReport-Msgid-Bugs-TozPOT-Creation-DatezPO-Revision-DatezLast-TranslatorLanguagezLanguage-TeamzPlural-Forms)zMIME-Versionz1.0zContent-Typeztext/plain; charset=)zContent-Transfer-Encoding8bitzGenerated-ByzBabel 
)ry   r   rC   timerQ   floatr   r   r   rT   r5   r   r   r   r   r   r,   r   plural_formsr   r   )rz   r   r   headerss       r#   _get_mime_headerszCatalog._get_mime_headers	  s   d(8+<hmSRW*XYY 	/+"#  MM !.M*! 	[jM&A&A)11*c$BX>Y>YZZM "dl#C#CT\#C#CD#T%<= /$2DFYbf"g"g"gh/ 45*
 ! 	FNNJD,B(C(CDEEE7888;"NNND,=>???#BDLBBC11g1112	
 	
 r%   r  Iterable[tuple[str, str]]c                   |D ]\  }}t          |                                | j                  }t          || j                  }|dk    rE|                    d          }d                    |d d                   | _        |d         | _        |dk    r|| _        |dk    r|| _        |dk    r.|	                    dd	          }| 
                    |pd            |d
k    r|| _        |dk    r4t          |          }d|v r|d                                         | _        '|dk    rWt          d|           }t          |                    dd                    | _        |                    dd          | _        |dk    rt#          |          | _        |dk    rd|vrt#          |          | _        d S )N)r   zproject-id-versionr~   zreport-msgid-bugs-tozlast-translatorlanguage-_zlanguage-teamr   r   zplural-formsz ;npluralsrE   plural(n != 1)zpot-creation-datezpo-revision-dater   )r   lowerr   splitjoinr   r   r   r   rT   r   r   r   rQ   getr   r   r^   r   r   )rz   r  rJ   r@   partsparamss         r#   _set_mime_headerszCatalog._set_mime_headers+  s   " !	G !	GKD%tzz||dlCCCD===E+++C(("xxcrc
33$Ry///*/''***',$$##c3//
   $////((%*""''/66&&#))#4#:#:#<#<DL''/U==$'

:q(A(A$B$B!$*JJx$D$D!!,,,%;E%B%B""+++&&)?)F)FD&C!	G !	Gr%   a      The MIME headers of the catalog, used for the special ``msgid ""`` entry.

    The behavior of this property changes slightly depending on whether a locale
    is set or not, the latter indicating that the catalog is actually a template
    for actual translations.

    Here's an example of the output for such a catalog template:

    >>> from babel.dates import UTC
    >>> from datetime import datetime
    >>> created = datetime(1990, 4, 1, 15, 30, tzinfo=UTC)
    >>> catalog = Catalog(project='Foobar', version='1.0',
    ...                   creation_date=created)
    >>> for name, value in catalog.mime_headers:
    ...     print('%s: %s' % (name, value))
    Project-Id-Version: Foobar 1.0
    Report-Msgid-Bugs-To: EMAIL@ADDRESS
    POT-Creation-Date: 1990-04-01 15:30+0000
    PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
    Last-Translator: FULL NAME <EMAIL@ADDRESS>
    Language-Team: LANGUAGE <LL@li.org>
    MIME-Version: 1.0
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: 8bit
    Generated-By: Babel ...

    And here's an example of the output when the locale is set:

    >>> revised = datetime(1990, 8, 3, 12, 0, tzinfo=UTC)
    >>> catalog = Catalog(locale='de_DE', project='Foobar', version='1.0',
    ...                   creation_date=created, revision_date=revised,
    ...                   last_translator='John Doe <jd@example.com>',
    ...                   language_team='de_DE <de@example.com>')
    >>> for name, value in catalog.mime_headers:
    ...     print('%s: %s' % (name, value))
    Project-Id-Version: Foobar 1.0
    Report-Msgid-Bugs-To: EMAIL@ADDRESS
    POT-Creation-Date: 1990-04-01 15:30+0000
    PO-Revision-Date: 1990-08-03 12:00+0000
    Last-Translator: John Doe <jd@example.com>
    Language: de_DE
    Language-Team: de_DE <de@example.com>
    Plural-Forms: nplurals=2; plural=(n != 1);
    MIME-Version: 1.0
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: 8bit
    Generated-By: Babel ...

    :type: `list`
    rQ   c                r    | j         *d}| j        rt          | j                  d         }|| _         | j         S )zThe number of plurals used by the catalog or locale.

        >>> Catalog(locale='en').num_plurals
        2
        >>> Catalog(locale='ga').num_plurals
        5

        :type: `int`NrE   r   )r   r   r   )rz   nums     r#   num_pluralszCatalog.num_plurals  sA     $C{ 1 --a0 #D  r%   c                r    | j         *d}| j        rt          | j                  d         }|| _         | j         S )aW  The plural expression used by the catalog or locale.

        >>> Catalog(locale='en').plural_expr
        '(n != 1)'
        >>> Catalog(locale='ga').plural_expr
        '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)'
        >>> Catalog(locale='ding').plural_expr  # unknown locale
        '(n != 1)'

        :type: `str`Nr  r:   )r   r   r   )rz   exprs     r#   plural_exprzCatalog.plural_expr  sA     $D{ 2!$+..q1 $D  r%   c                (    d| j          d| j         dS )zReturn the plural forms declaration for the locale.

        >>> Catalog(locale='en').plural_forms
        'nplurals=2; plural=(n != 1);'
        >>> Catalog(locale='pt_BR').plural_forms
        'nplurals=2; plural=(n > 1);'

        :type: `str`z	nplurals=z	; plural=;)r  r  r   s    r#   r  zCatalog.plural_forms  s$     J4+IId6FIIIIr%   ra   r   c                :    |                      |          | j        v S )z?Return whether the catalog has a message with the specified ID._key_forr   rz   ra   s     r#   __contains__zCatalog.__contains__  s    }}R  DN22r%   c                *    t          | j                  S )zeThe number of messages in the catalog.

        This does not include the special ``msgid ""`` entry.)lenr   r   s    r#   __len__zCatalog.__len__  s     4>"""r%   Iterator[Message]c              #    K   g }| j         D ]\  }}|                    | d|             t                      }| j        r|dhz  }t	          dd                    |          |          V  | j        D ]}| j        |         V  dS )zIterates through all the entries in the catalog, in the order they
        were added, yielding a `Message` object for every entry.

        :rtype: ``iterator``z: r   r`   r  r   N)mime_headersr,   rt   r   r   r  r   )rz   bufrJ   r@   re   keys         r#   __iter__zCatalog.__iter__  s      
 , 	+ 	+KD%JJ$))%))****: 	gYEb$))C..666666> 	& 	&C.%%%%%	& 	&r%   c                l    d}| j         r
d| j          }dt          |           j         d| j        | dS )Nr`   r~   r}   >)r   r   r   r   r   s     r#   r   zCatalog.__repr__  sI    ; 	'&&&FA4::&AAAAAAAr%   c                0    |                      |           dS )z)Delete the message with the specified ID.N)deleter#  s     r#   __delitem__zCatalog.__delitem__  s    Br%   r   c                ,    |                      |          S )zUReturn the message with the specified ID.

        :param id: the message ID
        )r  r#  s     r#   __getitem__zCatalog.__getitem__  s    
 xx||r%   messagec                $   t          |t                    s
J d            |                     ||j                  }| j                            |          }|r|j        r|j        s|j        |_        |j        |_        t          t                              g |j        |j                            |_        t          t                              g |j        |j                            |_        t          t                              g |j        |j                            |_        |xj        |j        z  c_        dS |dk    rbt!          |j                                                  | _        d                    d |j        D                       | _        |j        | _        dS t          |t          t,          f          r@t          |j        t          t,          f          sJ dt/          |j                               || j        |<   dS )a  Add or update the message with the specified ID.

        >>> catalog = Catalog()
        >>> catalog['foo'] = Message('foo')
        >>> catalog['foo']
        <Message 'foo' (flags: [])>

        If a message with that ID is already in the catalog, it is updated
        to include the locations and flags of the new message.

        >>> catalog = Catalog()
        >>> catalog['foo'] = Message('foo', locations=[('main.py', 1)])
        >>> catalog['foo'].locations
        [('main.py', 1)]
        >>> catalog['foo'] = Message('foo', locations=[('utils.py', 5)])
        >>> catalog['foo'].locations
        [('main.py', 1), ('utils.py', 5)]

        :param id: the message ID
        :param message: the `Message` object
        zexpected a Message objectr`   r  c              3  D   K   | ]}d |                                  V  dS )z# N)rstrip)r    cs     r#   	<genexpr>z&Catalog.__setitem__.<locals>.<genexpr>  s2      +]+]!HHHOO,=,=+]+]+]+]+]+]r%   zExpected sequence but got N)ry   r   r"  rl   r   r  rp   ra   r4   rq   rr   rs   rc   rg   rh   re   r   itemsr*  r  r   r   r   r   )rz   ra   r5  r,  currents        r#   __setitem__zCatalog.__setitem__  s   , '7++HH-HHH+mmB00.$$S)) 	*# 0G,@ 0$Z
!( $T]]3[W5F3[IZ3[%\%\ ] ]G$(7g9N7gQXQf7g)h)h$i$iG!$(7g9N7gQXQf7g)h)h$i$iG!MMW]*MMMM2XX 3GN C C I I K KD"&))+]+]wG\+]+]+]"]"]D DJJJ"tUm,, !'.4-@@  Ggn1E1EGG @ #*DN3r%   r   rb   rc   rd   re   rf   rg   rh   ri   rj   rk   rl   c
                Z    t          ||t          |          ||||||		  	        }
|
| |<   |
S )aq  Add or update the message with the specified ID.

        >>> catalog = Catalog()
        >>> catalog.add('foo')
        <Message ...>
        >>> catalog['foo']
        <Message 'foo' (flags: [])>

        This method simply constructs a `Message` object with the given
        arguments and invokes `__setitem__` with that object.

        :param id: the message ID, or a ``(singular, plural)`` tuple for
                   pluralizable messages
        :param string: the translated message string, or a
                       ``(singular, plural)`` tuple for pluralizable messages
        :param locations: a sequence of ``(filename, lineno)`` tuples
        :param flags: a set or sequence of flags
        :param auto_comments: a sequence of automatic comments
        :param user_comments: a sequence of user comments
        :param previous_id: the previous message ID, or a ``(singular, plural)``
                            tuple for pluralizable messages
        :param lineno: the line number on which the msgid line was found in the
                       PO file, if any
        :param context: the message context
        )rj   rl   )r   rq   )rz   ra   r4   rc   re   rg   rh   ri   rj   rl   r5  s              r#   rv   zCatalog.add  sJ    J OO

 

 

 Rr%   0Iterable[tuple[Message, list[TranslationError]]]c              #  ~   K   | j                                         D ] }|                    |           }|r||fV  !dS )a\  Run various validation checks on the translations in the catalog.

        For every message which fails validation, this method yield a
        ``(message, errors)`` tuple, where ``message`` is the `Message` object
        and ``errors`` is a sequence of `TranslationError` objects.

        :rtype: ``generator`` of ``(message, errors)``
        )r   N)r   valuesr   )rz   r5  r   s      r#   r   zCatalog.checkB  s[       ~,,.. 	& 	&G]]4]00F &vo%%%	& 	&r%   Message | Nonec                ^    | j                             |                     ||                    S )zReturn the message with the specified ID and context.

        :param id: the message ID
        :param context: the message context, or ``None`` for no context
        )r   r  r"  )rz   ra   rl   s      r#   r  zCatalog.getP  s(     ~!!$--G"<"<===r%   c                X    |                      ||          }|| j        v r
| j        |= dS dS )zDelete the message with the specified ID and context.

        :param id: the message ID
        :param context: the message context, or ``None`` for no context
        Nr!  rz   ra   rl   r,  s       r#   r1  zCatalog.deleteX  s<     mmB(($.  s### ! r%   Ftemplateno_fuzzy_matchingupdate_header_commentkeep_user_commentsupdate_creation_datec                     j                                         i  _         i }|sPD ]M}|rI|         j        r<                     |          }|         j        }	||	f|                     |          <   Nt                      d fd}
|D ]}|j        r                     |j        |j                  }|v r |
|||           ;|s_t                               |          |	                                d	          }|r'|d
         }||         \  }}|||f} |
|||           | |j        <   D ]}|s|vr|          j
        |<   |r|j         _        |r|j         _        dS dS )a  Update the catalog based on the given template catalog.

        >>> from babel.messages import Catalog
        >>> template = Catalog()
        >>> template.add('green', locations=[('main.py', 99)])
        <Message ...>
        >>> template.add('blue', locations=[('main.py', 100)])
        <Message ...>
        >>> template.add(('salad', 'salads'), locations=[('util.py', 42)])
        <Message ...>
        >>> catalog = Catalog(locale='de_DE')
        >>> catalog.add('blue', 'blau', locations=[('main.py', 98)])
        <Message ...>
        >>> catalog.add('head', 'Kopf', locations=[('util.py', 33)])
        <Message ...>
        >>> catalog.add(('salad', 'salads'), ('Salat', 'Salate'),
        ...             locations=[('util.py', 38)])
        <Message ...>

        >>> catalog.update(template)
        >>> len(catalog)
        3

        >>> msg1 = catalog['green']
        >>> msg1.string
        >>> msg1.locations
        [('main.py', 99)]

        >>> msg2 = catalog['blue']
        >>> msg2.string
        'blau'
        >>> msg2.locations
        [('main.py', 100)]

        >>> msg3 = catalog['salad']
        >>> msg3.string
        ('Salat', 'Salate')
        >>> msg3.locations
        [('util.py', 42)]

        Messages that are in the catalog but not in the template are removed
        from the main collection, but can still be accessed via the `obsolete`
        member:

        >>> 'head' in catalog
        False
        >>> list(catalog.obsolete.values())
        [<Message 'head' (flags: [])>]

        :param template: the reference catalog, usually read from a POT file
        :param no_fuzzy_matching: whether to use fuzzy matching of message IDs
        :param update_header_comment: whether to copy the header comment from the template
        :param keep_user_comments: whether to keep user comments from the old catalog
        :param update_creation_date: whether to copy the creation date from the template
        r5  r   oldkeytuple[str, str] | strnewkeyr6   rn   c                N   |                                  } d}||k    rrd}                    |                               |          }|J t          |j        t
                    r|j        g| _        n4t          |j                  | _        n                    |d           }|J |j	        | _	        r8|j
        r1t          t                              |j
                            | _
        t          | j        t          t          f          rt          | j	        t          t          f          s9d}t          | j	        gdgt          | j                  dz
  z  z             | _	        nt          | j	                  	j        k    r5d}t          | j	        d t          |j	                                     | _	        n5t          | j	        t          t          f          rd}| j	        d         | _	        | xj        |j        z  c_        |r| xj        dhz  c_        | 	| j        <   d S )NFTr`   r:   r   r   )r   rv   r  ry   ra   r5   ri   rq   popr4   rh   rr   rs   r   r&  r  re   )
r5  rL  rN  r   oldmsgfuzzy_matchesrI  messages	remainingrz   s
        r#   _mergezCatalog.update.<locals>._merge  s   
 mmooGE!!&)))!f--)))fi-- :+19+G''*.vy//G''"vt44)))#]GN! Rf&: R(,T]]6;O-P-P(Q(Q%'*tUm44 3!'.4-@@ Q E%* (RDC
OOa4G,HI& &GNN ((D,<<< E%*7>:NC<N<N:N+O%P%PGNGNT5M:: 3!(!2MMV\)MM +'*&Dr%   r:   r   N)r5  r   rL  rM  rN  rM  r6   rn   )r   r   r4   r"  rl   _to_fuzzy_match_keyrt   ra   r3   keysr   r   r   )rz   rF  rG  rH  rI  rJ  fuzzy_candidatesmsgidr,  ctxtrU  r5  matchesmodified_keyrN  newctxtrR  rS  rT  s   `   `           @@@r#   updatezCatalog.updateb  s#   ~ >MMOO	   	R! R R RXe_3 R--..C#E?2DGJDk$T%=%=c%B%BC'	' '	' '	' '	' '	' '	' '	' '	' '	' '	'R   	/ 	/Gz /mmGJ@@(??F7C----, %"3 44S99,1133# #
 # %+21:L.>|.LOFG&2)/"F7FC888$'.D$ 	8 	8E  8E$>$>'0'7e$  	: #+"9D   	8!)!7D	8 	8r%   r,  rM  c                    t          |t                    r	|d         }n|}|                                                                S )z?Converts a message key to a string suitable for fuzzy matching.r   )ry   r   r  strip)rz   r,  matchkeys      r#   rV  zCatalog._to_fuzzy_match_key  s@    c5!! 	1vHHH~~%%'''r%   c                ^    |}t          |t          t          f          r|d         }|||f}|S )zThe key for a message is just the singular ID even for pluralizable
        messages, but is a ``(msgid, msgctxt)`` tuple for context-specific
        messages.
        r   )ry   rq   r   rE  s       r#   r"  zCatalog._key_for  s<     cD%=)) 	Q%C.C
r%   r   c                |   t          |t                    sJ | j                                        |j                                        z  D ]H}|                     |          }|                    |          }|||                    |          s dS It          | j                  t          |j                  k    S )z\Checks if catalogs are identical, taking into account messages and
        headers.
        NF)ry   r   r   rW  r  r   rr   r*  )rz   r   r,  	message_1	message_2s        r#   r   zCatalog.is_identical  s     %)))))>&&((5?+?+?+A+AA 	 	CI		#I I$5Y=S=ST]=^=^$5uu %6D%&&$u/A*B*BBBr%   )r   r   r   rm   r   rm   r   rm   r   rm   r   rm   r   rm   r   r   r   r   r   rm   r   rm   r   rm   r   r7   r6   rn   )r   r   r6   rn   )r6   r   )r6   rm   r   )r4   rm   r6   rn   )r6   r   )r  r  r6   rn   )r6   rQ   )ra   r   r6   r7   )r6   r(  )ra   r   r6   rn   )ra   r   r6   r   )ra   r   r5  r   r6   rn   )Nr   r   r   r   r   NN)ra   r   r4   rb   rc   rd   re   rf   rg   rf   rh   rf   ri   r   rj   rk   rl   rm   r6   r   )r6   r?  r   )ra   r   rl   rm   r6   rB  )ra   r   rl   rm   r6   rn   )FFTT)rF  r   rG  r7   rH  r7   rI  r7   rJ  r7   r6   rn   )r,  rM  r6   r5   )ra   r   rl   rm   r6   rM  )r   r   r6   r7   )$r   r   r   r   r   r{   r   r   r   r   r   r   r   r   r   r  r  r*  r  r  r  r$  r'  r-  r   r2  r4  r=  rv   r   r  r1  r^  rV  r"  r   r   r%   r#   r   r   h  sH       .. '+!%3""'+)-8<PT&*$("D! D! D! D! D!L
 
 
 
.   ' ' ' ' Xk;//F !788    & & & & X# # #NJ       D"G "G "G "GH 826 6 6Lp ! ! ! X!  ! ! ! X!$ 	J 	J 	J X	J3 3 3 3# # # #& & & &B B B B      ,* ,* ,* ,*b %)/1!')')"$!"1 1 1 1 1f& & & &> > > > >$ $ $ $ $ #(&+#'%)Y8 Y8 Y8 Y8 Y8v( ( ( ( #     
C 
C 
C 
C 
C 
Cr%   r   )r   r   )r4   r5   r6   r7   )r@   r5   r6   rA   )r@   r5   r6   r   )r   r   )r2   r   r   r5   r   r5   r6   r5   )5r   
__future__r   rC   rM   collections.abcr   r   r   difflibr   emailr   heapqr	   r4   r
   typingr   babelr   r   
babel.corer   r   babel.datesr   babel.messages.pluralsr   
babel.utilr   r   typing_extensionsr   r5   r   rq   r   __annotations____all__r3   compileVERBOSEr   r?   r^   r   	Exceptionr   r   r   r   r   r   r%   r#   <module>rw     s     # " " " " "  				 . . . . . . . .       # # # # # # % % % % % %                         ( ( ( ( ( ( 1 1 1 1 1 1 1 1 ' ' ' ' ' ' - - - - - - $ $ $ $ $ $ $ $ >++++++%S/1DI=J====  & & & &8 
	 J    &   B}- }- }- }- }- }- }- }-@% % % % %y % % %
           w
C w
C w
C w
C w
C w
C w
C w
C w
C w
Cr%   