o
    VÛë\BS  ã                	   @   s‚  d Z ddlZddlmZ dZdZdd„ ZG dd	„ d	eƒZd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ ZG dd„ deƒZdZde dej¡fde d e¡¡fde d¡fde d¡fd e d!ej¡fgZd"d#„ ZdBd$d%„ZdBd&d'„Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ ZG d0d1„ d1eƒZd2d3„ Zd4d5„ Zd6d7„ Z G d8d9„ d9eƒZ!G d:d;„ d;e!ƒZ"G d<d=„ d=e!ƒZ#G d>d?„ d?e#ƒZ$G d@dA„ dAe!ƒZ%dS )Cz°
    babel.numbers
    ~~~~~~~~~~~~~

    CLDR Plural support.  See UTS #35.

    :copyright: (c) 2013-2019 by the Babel Team.
    :license: BSD, see LICENSE for more details.
é    N)Údecimal)ÚzeroÚoneÚtwoÚfewÚmanyÚotherr   c                 C   sÒ   t | ƒ}t|ƒ}t|tƒr||kr|}nt t|ƒ¡}t|tjƒrY| ¡ }|j}|dk r3|j	|d… nd}d 
dd„ |D ƒ¡}| d¡}t|ƒ}t|ƒ}	t|pPdƒ}
t|pVdƒ}nd } }	 }
}||||	|
|fS )a#  Extract operands from a decimal, a float or an int, according to `CLDR rules`_.

    The result is a 6-tuple (n, i, v, w, f, t), where those symbols are as follows:

    ====== ===============================================================
    Symbol Value
    ------ ---------------------------------------------------------------
    n      absolute value of the source number (integer and decimals).
    i      integer digits of n.
    v      number of visible fraction digits in n, with trailing zeros.
    w      number of visible fraction digits in n, without trailing zeros.
    f      visible fractional digits in n, with trailing zeros.
    t      visible fractional digits in n, without trailing zeros.
    ====== ===============================================================

    .. _`CLDR rules`: https://www.unicode.org/reports/tr35/tr35-33/tr35-numbers.html#Operands

    :param source: A real number
    :type source: int|float|decimal.Decimal
    :return: A n-i-v-w-f-t tuple
    :rtype: tuple[decimal.Decimal, int, int, int, int, int]
    r   N© Ú c                 s   s   � | ]}t |ƒV  qd S ©N©Ústr)Ú.0Údr	   r	   ú./usr/lib/python3/dist-packages/babel/plural.pyÚ	<genexpr>A   s   € z#extract_operands.<locals>.<genexpr>Ú0)ÚabsÚintÚ
isinstanceÚfloatr   ÚDecimalr   Úas_tupleÚexponentÚdigitsÚjoinÚrstripÚlen)ÚsourceÚnÚiÚ	dec_tupleÚexpÚfraction_digitsÚtrailingÚno_trailingÚvÚwÚfÚtr	   r	   r   Úextract_operands   s$   

r*   c                   @   sd   e Zd ZdZdZdd„ Zdd„ Zedd„ ƒZe	d	d
„ ƒZ
e	dd„ dd�Zdd„ Zdd„ Zdd„ ZdS )Ú
PluralRuleaf  Represents a set of language pluralization rules.  The constructor
    accepts a list of (tag, expr) tuples or a dict of `CLDR rules`_. The
    resulting object is callable and accepts one parameter with a positive or
    negative number (both integer and float) for the number that indicates the
    plural form for a string and returns the tag for the format:

    >>> rule = PluralRule({'one': 'n is 1'})
    >>> rule(1)
    'one'
    >>> rule(2)
    'other'

    Currently the CLDR defines these tags: zero, one, two, few, many and
    other where other is an implicit default.  Rules should be mutually
    exclusive; for a given numeric value, only one rule should apply (i.e.
    the condition should only be true for one of the plural rule elements.

    .. _`CLDR rules`: https://www.unicode.org/reports/tr35/tr35-33/tr35-numbers.html#Language_Plural_Rules
    )ÚabstractÚ_funcc                 C   sˆ   t |tƒr	| ¡ }tƒ }g | _tt|ƒƒD ],\}}|tvr#td| ƒ‚||v r-td| ƒ‚| 	|¡ t
|ƒj}|rA| j ||f¡ qdS )a$  Initialize the rule instance.

        :param rules: a list of ``(tag, expr)``) tuples with the rules
                      conforming to UTS #35 or a dict with the tags as keys
                      and expressions as values.
        :raise RuleError: if the expression is malformed
        zunknown tag %rztag %r defined twiceN)r   ÚdictÚitemsÚsetr,   ÚsortedÚlistÚ_plural_tagsÚ
ValueErrorÚaddÚ_ParserÚastÚappend)ÚselfÚrulesÚfoundÚkeyÚexprr7   r	   r	   r   Ú__init__c   s   


€øzPluralRule.__init__c                    s,   | j ‰ dt| ƒjd ‡ fdd„tD ƒ¡f S )Nz<%s %r>z, c                    s$   g | ]}|ˆ v rd |ˆ | f ‘qS )z%s: %sr	   ©r   Útag©r:   r	   r   Ú
<listcomp>}   s    ÿz'PluralRule.__repr__.<locals>.<listcomp>)r:   ÚtypeÚ__name__r   r3   ©r9   r	   rA   r   Ú__repr__y   s
   þzPluralRule.__repr__c                 C   s   t || ƒr|S | |ƒS )a
  Create a `PluralRule` instance for the given rules.  If the rules
        are a `PluralRule` object, that object is returned.

        :param rules: the rules as list or dict, or a `PluralRule` object
        :raise RuleError: if the expression is malformed
        )r   )Úclsr:   r	   r	   r   Úparse�   s   
zPluralRule.parsec                    s    t ƒ j‰ t‡ fdd„| jD ƒƒS )zŸThe `PluralRule` as a dict of unicode plural rules.

        >>> rule = PluralRule({'one': 'n is 1'})
        >>> rule.rules
        {'one': 'n is 1'}
        c                    s   g | ]
\}}|ˆ |ƒf‘qS r	   r	   )r   r@   r7   ©Ú_compiler	   r   rB   –   s    z$PluralRule.rules.<locals>.<listcomp>)Ú_UnicodeCompilerÚcompiler.   r,   rE   r	   rI   r   r:   �   s   zPluralRule.rulesc                 C   s   t dd„ | jD ƒƒS )Nc                 S   s   g | ]}|d  ‘qS )r   r	   )r   r    r	   r	   r   rB   ˜   ó    z'PluralRule.<lambda>.<locals>.<listcomp>)Ú	frozensetr,   ©Úxr	   r	   r   Ú<lambda>˜   rM   zPluralRule.<lambda>z°
        A set of explicitly defined tags in this rule.  The implicit default
        ``'other'`` rules is not part of this set unless there is an explicit
        rule for it.)Údocc                 C   s   | j S r   ©r,   rE   r	   r	   r   Ú__getstate__�   ó   zPluralRule.__getstate__c                 C   s
   || _ d S r   rS   )r9   r,   r	   r	   r   Ú__setstate__    ó   
zPluralRule.__setstate__c                 C   s   t | dƒs
t| ƒ| _|  |¡S )Nr-   )ÚhasattrÚ	to_pythonr-   )r9   r   r	   r	   r   Ú__call__£   s   


zPluralRule.__call__N)rD   Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r>   rF   ÚclassmethodrH   Úpropertyr:   ÚtagsrT   rV   rZ   r	   r	   r	   r   r+   L   s    


r+   c                 C   sR   t ƒ j}dg}t | ¡jD ]\}}| d||ƒ|f ¡ q| dt ¡ d |¡S )a‚  Convert a list/dict of rules or a `PluralRule` object into a JavaScript
    function.  This function depends on no external library:

    >>> to_javascript({'one': 'n is 1'})
    "(function(n) { return (n == 1) ? 'one' : 'other'; })"

    Implementation detail: The function generated will probably evaluate
    expressions involved into range operations multiple times.  This has the
    advantage that external helper functions are not required and is not a
    big performance hit for these simple calculations.

    :param rule: the rules as list or dict, or a `PluralRule` object
    :raise RuleError: if the expression is malformed
    z(function(n) { return z
%s ? %r : z%r; })r
   )Ú_JavaScriptCompilerrL   r+   rH   r,   r8   Ú_fallback_tagr   )ÚruleÚto_jsÚresultr@   r7   r	   r	   r   Úto_javascript©   s   
rg   c                 C   s€   t tttdœ}tƒ j}ddg}t | ¡jD ]\}}| 	d||ƒt
|ƒf ¡ q| 	dt ¡ td |¡ddƒ}t||ƒ |d	 S )
a<  Convert a list/dict of rules or a `PluralRule` object into a regular
    Python function.  This is useful in situations where you need a real
    function and don't are about the actual rule object:

    >>> func = to_python({'one': 'n is 1', 'few': 'n in 2..4'})
    >>> func(1)
    'one'
    >>> func(3)
    'few'
    >>> func = to_python({'one': 'n in 1,11', 'few': 'n in 3..10,13..19'})
    >>> func(11)
    'one'
    >>> func(15)
    'few'

    :param rule: the rules as list or dict, or a `PluralRule` object
    :raise RuleError: if the expression is malformed
    )ÚINÚWITHINÚMODr*   zdef evaluate(n):z' n, i, v, w, f, t = extract_operands(n)z if (%s): return %rz
 return %rÚ
z<rule>ÚexecÚevaluate)Úin_range_listÚwithin_range_listÚcldr_modulor*   Ú_PythonCompilerrL   r+   rH   r,   r8   r   rc   r   Úeval)rd   Ú	namespaceÚto_python_funcrf   r@   r7   Úcoder	   r	   r   rY   À   s   üþ
rY   c                    s†   t  | ¡} | jthB ‰ tƒ j}‡ fdd„tD ƒj}dtˆ ƒ g}| j	D ]\}}| 
d||ƒ||ƒf ¡ q#| 
d|tƒ ¡ d |¡S )a~  The plural rule as gettext expression.  The gettext expression is
    technically limited to integers and returns indices rather than tags.

    >>> to_gettext({'one': 'n is 1', 'two': 'n is 2'})
    'nplurals=3; plural=((n == 1) ? 0 : (n == 2) ? 1 : 2)'

    :param rule: the rules as list or dict, or a `PluralRule` object
    :raise RuleError: if the expression is malformed
    c                    s   g | ]}|ˆ v r|‘qS r	   r	   r?   ©Ú	used_tagsr	   r   rB   ö   ó    zto_gettext.<locals>.<listcomp>znplurals=%d; plural=(z
%s ? %d : z%d)r
   )r+   rH   ra   rc   Ú_GettextCompilerrL   r3   Úindexr   r,   r8   r   )rd   rJ   Ú
_get_indexrf   r@   r7   r	   rv   r   Ú
to_gettextè   s   


r|   c                 C   s   | t | ƒko
t| |ƒS )a™  Integer range list test.  This is the callback for the "in" operator
    of the UTS #35 pluralization rule language:

    >>> in_range_list(1, [(1, 3)])
    True
    >>> in_range_list(3, [(1, 3)])
    True
    >>> in_range_list(3, [(1, 3), (5, 8)])
    True
    >>> in_range_list(1.2, [(1, 4)])
    False
    >>> in_range_list(10, [(1, 4)])
    False
    >>> in_range_list(10, [(1, 4), (6, 8)])
    False
    )r   ro   ©ÚnumÚ
range_listr	   r	   r   rn   ÿ   ó   rn   c                    s   t ‡ fdd„|D ƒƒS )a¶  Float range test.  This is the callback for the "within" operator
    of the UTS #35 pluralization rule language:

    >>> within_range_list(1, [(1, 3)])
    True
    >>> within_range_list(1.0, [(1, 3)])
    True
    >>> within_range_list(1.2, [(1, 4)])
    True
    >>> within_range_list(8.8, [(1, 4), (7, 15)])
    True
    >>> within_range_list(10, [(1, 4)])
    False
    >>> within_range_list(10.5, [(1, 4), (20, 30)])
    False
    c                 3   s$   � | ]\}}ˆ |koˆ |kV  qd S r   r	   )r   Úmin_Úmax_©r~   r	   r   r   $  s   €" z$within_range_list.<locals>.<genexpr>)Úanyr}   r	   rƒ   r   ro     r€   ro   c                 C   s@   d}| dk r| d9 } d}|dk r|d9 }| | }|r|d9 }|S )zîJavaish modulo.  This modulo operator returns the value with the sign
    of the dividend rather than the divisor like Python does:

    >>> cldr_modulo(-3, 5)
    -3
    >>> cldr_modulo(-3, -5)
    -3
    >>> cldr_modulo(3, 5)
    3
    r   éÿÿÿÿé   r	   )ÚaÚbÚreverseÚrvr	   r	   r   rp   '  s   rp   c                   @   s   e Zd ZdZdS )Ú	RuleErrorzRaised if a rule is malformed.N)rD   r[   r\   r]   r	   r	   r	   r   r‹   >  s    r‹   Únivwftz\s+Úwordz)\b(and|or|is|(?:with)?in|not|mod|[{0}])\bÚvaluez\d+Úsymbolz%|,|!=|=Úellipsisz\.{2,3}|\u2026c                 C   s�   |   d¡d } g }d}t| ƒ}||k rAtD ]\}}| | |¡}|d ur4| ¡ }|r2| || ¡ f¡  n	qtd| |  ƒ‚||k s|d d d… S )Nú@r   z5malformed CLDR pluralization rule.  Got unexpected %rr…   )Úsplitr   Ú_RULESÚmatchÚendr8   Úgroupr‹   )Úsrf   Úposr•   Útokrd   r”   r	   r	   r   Útokenize_ruleM  s$   üÿ÷rš   c                 C   s,   | o| d d |ko|d u p| d d |kS )Nr…   r   r†   r	   ©ÚtokensÚtype_rŽ   r	   r	   r   Útest_next_token`  s   ÿrž   c                 C   s   t | ||ƒr
|  ¡ S d S r   )rž   Úpopr›   r	   r	   r   Ú
skip_tokene  s   ÿr    c                 C   ó
   d| ffS )NrŽ   r	   )rŽ   r	   r	   r   Ú
value_nodej  rW   r¢   c                 C   s   | dfS )Nr	   r	   )Únamer	   r	   r   Ú
ident_noden  ó   r¤   c                 C   s   d| fS )Nr   r	   )r   r	   r	   r   Úrange_list_noder  r¥   r¦   c                 C   r¡   )NÚnotr	   )rŠ   r	   r	   r   Únegatev  rW   r¨   c                   @   sb   e Zd ZdZdd„ Zddd„Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ ZdS )r6   uò  Internal parser.  This class can translate a single rule into an abstract
    tree of tuples. It implements the following grammar::

        condition     = and_condition ('or' and_condition)*
                        ('@integer' samples)?
                        ('@decimal' samples)?
        and_condition = relation ('and' relation)*
        relation      = is_relation | in_relation | within_relation
        is_relation   = expr 'is' ('not')? value
        in_relation   = expr (('not')? 'in' | '=' | '!=') range_list
        within_relation = expr ('not')? 'within' range_list
        expr          = operand (('mod' | '%') value)?
        operand       = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
        range_list    = (range | value) (',' range_list)*
        value         = digit+
        digit         = 0|1|2|3|4|5|6|7|8|9
        range         = value'..'value
        samples       = sampleRange (',' sampleRange)* (',' ('â€¦'|'...'))?
        sampleRange   = decimalValue '~' decimalValue
        decimalValue  = value ('.' value)?

    - Whitespace can occur between or around any of the above tokens.
    - Rules should be mutually exclusive; for a given numeric value, only one
      rule should apply (i.e. the condition should only be true for one of
      the plural rule elements).
    - The in and within relations can take comma-separated lists, such as:
      'n in 3,5,7..15'.
    - Samples are ignored.

    The translator parses the expression on instanciation into an attribute
    called `ast`.
    c                 C   sD   t |ƒ| _| jsd | _d S |  ¡ | _| jr td| jd d  ƒ‚d S )NzExpected end of rule, got %rr…   r†   )rš   rœ   r7   Ú	conditionr‹   )r9   Ústringr	   r	   r   r>   œ  s   

ÿÿz_Parser.__init__Nc                 C   sb   t | j||ƒ}|d ur|S |d u rt|d u r|p|ƒ}| js$td| ƒ‚td|| jd d f ƒ‚)Nz#expected %s but end of rule reachedzexpected %s but got %rr…   r†   )r    rœ   Úreprr‹   )r9   r�   rŽ   ÚtermÚtokenr	   r	   r   Úexpect¨  s   z_Parser.expectc                 C   ó8   |   ¡ }t| jddƒrd||   ¡ ff}t| jddƒs|S )Nr�   Úor)Úand_conditionr    rœ   ©r9   Úopr	   r	   r   r©   ²  ó
   ÿz_Parser.conditionc                 C   r¯   )Nr�   Úand)Úrelationr    rœ   r²   r	   r	   r   r±   ¸  r´   z_Parser.and_conditionc                 C   s¤   |   ¡ }t| jddƒrt| jddƒrdpd||  ¡ ffS t| jddƒ}d}t| jddƒr/d}nt| jddƒsA|r<tdƒ‚|  |¡S d|||  ¡ ff}|rPt|ƒS |S )	Nr�   Úisr§   ÚisnotÚinÚwithinz#Cannot negate operator based rules.r¶   )r=   r    rœ   rŽ   r‹   Únewfangled_relationr   r¨   )r9   ÚleftÚnegatedÚmethodrŠ   r	   r	   r   r¶   ¾  s   
ÿ
z_Parser.relationc                 C   sR   t | jddƒr
d}nt | jddƒrd}ntdƒ‚dd||  ¡ ff}|r't|ƒS |S )	Nr�   ú=Fz!=Tz'Expected "=" or "!=" or legacy relationr¶   r¹   )r    rœ   r‹   r   r¨   )r9   r¼   r½   rŠ   r	   r	   r   r»   Ï  s   z_Parser.newfangled_relationc                 C   s(   |   ¡ }t| jdƒr||   ¡ fS ||fS )Nr�   )rŽ   r    rœ   )r9   r¼   r	   r	   r   Úrange_or_valueÙ  s   z_Parser.range_or_valuec                 C   s<   |   ¡ g}t| jddƒr| |   ¡ ¡ t| jddƒst|ƒS )Nr�   ú,)rÀ   r    rœ   r8   r¦   )r9   r   r	   r	   r   r   à  s
   
ÿz_Parser.range_listc                 C   s|   t | jdƒ}|d u s|d tvrtdƒ‚|d }t | jddƒr)d|df|  ¡ ffS t | jddƒr:d|df|  ¡ ffS t|ƒS )Nr�   r†   zExpected identifier variableÚmodr	   r�   ú%)r    rœ   Ú_VARSr‹   rŽ   r¤   )r9   r�   r£   r	   r	   r   r=   æ  s   z_Parser.exprc                 C   s   t t|  d¡d ƒƒS )NrŽ   r†   )r¢   r   r®   rE   r	   r	   r   rŽ   ñ  s   z_Parser.value)NN)rD   r[   r\   r]   r>   r®   r©   r±   r¶   r»   rÀ   r   r=   rŽ   r	   r	   r	   r   r6   z  s    !


r6   c                    ó   ‡ fdd„S )ú%Compiler factory for the `_Compiler`.c                    s   ˆ |   |¡|   |¡f S r   ©rL   )r9   ÚlÚr©Útmplr	   r   rQ   ÷  rx   z"_binary_compiler.<locals>.<lambda>r	   rÊ   r	   rÊ   r   Ú_binary_compilerõ  ó   rÌ   c                    rÅ   )rÆ   c                    s   ˆ |   |¡ S r   rÇ   )r9   rP   rÊ   r	   r   rQ   ü  s    z!_unary_compiler.<locals>.<lambda>r	   rÊ   r	   rÊ   r   Ú_unary_compilerú  rÍ   rÎ   c                 C   ó   dS )Nr   r	   rO   r	   r	   r   rQ   ÿ  ó    rQ   c                   @   sˆ   e Zd ZdZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd	d„ Z	d
d„ Z
dd„ ZedƒZedƒZedƒZedƒZedƒZedƒZdd„ ZdS )Ú	_CompilerzZThe compilers are able to transform the expressions into multiple
    output formats.
    c                 C   s   |\}}t | d| ƒ|Ž S )NÚcompile_)Úgetattr)r9   Úargr³   Úargsr	   r	   r   rL     s   z_Compiler.compilec                 C   rÏ   )Nr   r	   rO   r	   r	   r   rQ     rÐ   z_Compiler.<lambda>c                 C   rÏ   )Nr    r	   rO   r	   r	   r   rQ     rÐ   c                 C   rÏ   )Nr&   r	   rO   r	   r	   r   rQ     rÐ   c                 C   rÏ   )Nr'   r	   rO   r	   r	   r   rQ     rÐ   c                 C   rÏ   )Nr(   r	   rO   r	   r	   r   rQ     rÐ   c                 C   rÏ   )Nr)   r	   rO   r	   r	   r   rQ     rÐ   c                 C   s   t |ƒS r   r   )rP   r&   r	   r	   r   rQ     s    z
(%s && %s)z
(%s || %s)z(!%s)z
(%s %% %s)ú
(%s == %s)z
(%s != %s)c                 C   s   t ƒ ‚r   )ÚNotImplementedError)r9   r¾   r=   r   r	   r	   r   Úcompile_relation  rU   z_Compiler.compile_relationN)rD   r[   r\   r]   rL   Ú	compile_nÚ	compile_iÚ	compile_vÚ	compile_wÚ	compile_fÚ	compile_tÚcompile_valuerÌ   Úcompile_andÚ
compile_orrÎ   Úcompile_notÚcompile_modÚ
compile_isÚcompile_isnotrØ   r	   r	   r	   r   rÑ     s"    rÑ   c                   @   s8   e Zd ZdZedƒZedƒZedƒZedƒZ	dd„ Z
dS )	rq   z!Compiles an expression to Python.z(%s and %s)z
(%s or %s)z(not %s)zMOD(%s, %s)c                    s8   dd  ‡ fdd„|d D ƒ¡ }d| ¡ ˆ  |¡|f S )Nz[%s]rÁ   c                    s    g | ]}d t tˆ j|ƒƒ ‘qS )z(%s, %s))ÚtupleÚmaprL   )r   Úrange_rE   r	   r   rB   '  s    ÿz4_PythonCompiler.compile_relation.<locals>.<listcomp>r†   z
%s(%s, %s))r   ÚupperrL   )r9   r¾   r=   r   Úcompile_range_listr	   rE   r   rØ   %  s   
ÿÿÿz _PythonCompiler.compile_relationN)rD   r[   r\   r]   rÌ   rà   rá   rÎ   râ   rã   rØ   r	   r	   r	   r   rq     s    rq   c                   @   s.   e Zd ZdZejZeZeZ	eZ
eZdd„ ZdS )ry   z)Compile into a gettext plural expression.c              	   C   s~   g }|   |¡}|d D ],}|d |d kr$| d||   |d ¡f ¡ qt| j |ƒ\}}| d||||f ¡ qdd |¡ S )Nr†   r   rÖ   z(%s >= %s && %s <= %s)z(%s)z || )rL   r8   rç   r   )r9   r¾   r=   r   rŠ   ÚitemÚminÚmaxr	   r	   r   rØ   6  s    

þ
üz!_GettextCompiler.compile_relationN)rD   r[   r\   r]   rÑ   rÙ   rÚ   Úcompile_zerorÛ   rÜ   rÝ   rÞ   rØ   r	   r	   r	   r   ry   -  s    ry   c                   @   s0   e Zd ZdZdd„ ZeZeZeZeZ	dd„ Z
dS )rb   z/Compiles the expression to plain of JavaScript.c                 C   rÏ   )NzparseInt(n, 10)r	   rO   r	   r	   r   rQ   O  rÐ   z_JavaScriptCompiler.<lambda>c                 C   s4   t  | |||¡}|dkr|  |¡}d|||f }|S )Nr¹   z(parseInt(%s, 10) == %s && %s))ry   rØ   rL   )r9   r¾   r=   r   ru   r	   r	   r   rØ   U  s   ÿ
z$_JavaScriptCompiler.compile_relationN)rD   r[   r\   r]   rÚ   rî   rÛ   rÜ   rÝ   rÞ   rØ   r	   r	   r	   r   rb   J  s    rb   c                   @   sJ   e Zd ZdZedƒZedƒZedƒZedƒZedƒZ	dd„ Z
dd
d„ZdS )rK   z+Returns a unicode pluralization rule again.z%s is %sz%s is not %sz	%s and %sz%s or %sz	%s mod %sc                 C   s   | j |d ddiŽS )Nr†   r½   T)rØ   )r9   r¶   r	   r	   r   râ   k  s   z_UnicodeCompiler.compile_notFc                 C   sv   g }|d D ]"}|d |d kr|  |  |d ¡¡ q|  dtt| j|ƒƒ ¡ qd|  |¡|r2dp3d|d |¡f S )Nr†   r   z%s..%sz
%s%s %s %sz notr
   rÁ   )r8   rL   ræ   rç   r   )r9   r¾   r=   r   r½   Úrangesrë   r	   r	   r   rØ   n  s   
þz!_UnicodeCompiler.compile_relationN)F)rD   r[   r\   r]   rÌ   rä   rå   rà   rá   rã   râ   rØ   r	   r	   r	   r   rK   ^  s    rK   r   )&r]   ÚreÚbabel._compatr   r3   rc   r*   Úobjectr+   rg   rY   r|   rn   ro   rp   Ú	Exceptionr‹   rÄ   rL   ÚUNICODEÚformatr“   rš   rž   r    r¢   r¤   r¦   r¨   r6   rÌ   rÎ   rî   rÑ   rq   ry   rb   rK   r	   r	   r	   r   Ú<module>   sN   	8](ÿú


{