ÿØÿàJFIFÿþ ÿÛC       ÿÛC ÿÀÿÄÿÄ"#QrÿÄÿÄ&1!A"2qQaáÿÚ ?Øy,æ/3JæÝ¹È߲؋5êXw²±ÉyˆR”¾I0ó2—PI¾IÌÚiMö¯–þrìN&"KgX:Šíµ•nTJnLK„…@!‰-ý ùúmë;ºgµŒ&ó±hw’¯Õ@”Ü— 9ñ-ë.²1<yà‚¹ïQÐU„ہ?.’¦èûbß±©Ö«Âw*VŒ) `$‰bØÔŸ’ëXÖ-ËTÜíGÚ3ð«g Ÿ§¯—Jx„–’U/ÂÅv_s(Hÿ@TñJÑãõçn­‚!ÈgfbÓc­:él[ðQe 9ÀPLbÃãCµm[5¿ç'ªjglå‡Ûí_§Úõl-;"PkÞÞÁQâ¼_Ñ^¢SŸx?"¸¦ùY騐ÒOÈ q’`~~ÚtËU¹CڒêV  I1Áß_ÿÙ HXc@sdZddlZddlmZd5Zd Zd Zd efd YZd Z dZ dZ dZ dZ dZdefdYZdZdejdejfdejdjefdejdfdejdfdejdejfgZdZdd Zdd!Zd"Zd#Zd$Zd%Zd&efd'YZd(Zd)Z d*Z!d+efd,YZ"d-e"fd.YZ#d/e"fd0YZ$d1e$fd2YZ%d3e"fd4YZ&dS(6s babel.numbers ~~~~~~~~~~~~~ CLDR Plural support. See UTS #35. :copyright: (c) 2013 by the Babel Team. :license: BSD, see LICENSE for more details. iN(tdecimaltzerotonettwotfewtmanytotherc Cs)t|}t|}t|trT||kr<|}qTtjt|}nt|tjr|j}|j}|dkr|j |nd}dj d|D}|j d}t |}t |} t|pd} t|pd} nd}} } } |||| | | fS(s"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`: http://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] itcss|]}t|VqdS(N(tstr(t.0td((s0/usr/lib/python2.7/site-packages/babel/plural.pys Ast0(( tabstintt isinstancetfloatRtDecimalRtas_tupletexponenttdigitstjointrstriptlen( tsourcetntit dec_tupletexptfraction_digitsttrailingt no_trailingtvtwtftt((s0/usr/lib/python2.7/site-packages/babel/plural.pytextract_operandss$        t PluralRulecBsteZdZd ZdZdZedZedZ eddd Z d Z d Z d Z RS(seRepresents 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`: http://www.unicode.org/reports/tr35/tr35-33/tr35-numbers.html#Language_Plural_Rules tabstractt_funccCst|tr|j}nt}g|_xtt|D]\}}|tkrntd|n||krtd|n|j |t |j }|rC|jj ||fqCqCWdS(s$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 sunknown tag %rstag %r defined twiceN( RtdicttitemstsetR%tsortedtlistt _plural_tagst ValueErrortaddt_Parsertasttappend(tselftrulestfoundtkeytexprR0((s0/usr/lib/python2.7/site-packages/babel/plural.pyt__init__cs     c CsV|j}dt|jdjgtD]&}||kr%d|||f^q%fS(Ns<%s %r>s, s%s: %s(R3ttypet__name__RR,(R2R3ttag((s0/usr/lib/python2.7/site-packages/babel/plural.pyt__repr__ys   cCst||r|S||S(s 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(tclsR3((s0/usr/lib/python2.7/site-packages/babel/plural.pytparsescCs>tj}tg|jD]\}}|||f^qS(sThe `PluralRule` as a dict of unicode plural rules. >>> rule = PluralRule({'one': 'n is 1'}) >>> rule.rules {'one': 'n is 1'} (t_UnicodeCompilertcompileR'R%(R2t_compileR:R0((s0/usr/lib/python2.7/site-packages/babel/plural.pyR3s cCs$tg|jD]}|d^q S(Ni(t frozensetR%(txR((s0/usr/lib/python2.7/site-packages/babel/plural.pytRtdocs 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.cCs|jS(N(R%(R2((s0/usr/lib/python2.7/site-packages/babel/plural.pyt __getstate__scCs ||_dS(N(R%(R2R%((s0/usr/lib/python2.7/site-packages/babel/plural.pyt __setstate__scCs.t|ds!t||_n|j|S(NR&(thasattrt to_pythonR&(R2R((s0/usr/lib/python2.7/site-packages/babel/plural.pyt__call__s(R%R&(R9t __module__t__doc__t __slots__R7R;t classmethodR=tpropertyR3ttagsRERFRI(((s0/usr/lib/python2.7/site-packages/babel/plural.pyR$Ls       cCsstj}dg}x=tj|jD])\}}|jd|||fq(W|jdtdj|S(sConvert 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 s(function(n) { return s %s ? %r : s%r; })R(t_JavaScriptCompilerR?R$R=R%R1t _fallback_tagR(truletto_jstresultR:R0((s0/usr/lib/python2.7/site-packages/babel/plural.pyt to_javascripts   !cCsitd6td6td6td6}tj}ddg}xCtj|jD]/\}}|j d||t |fqMW|j dt td j |d d }t |||d S( s<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 tINtWITHINtMODR#sdef evaluate(n):s' n, i, v, w, f, t = extract_operands(n)s if (%s): return %rs return %rs stexectevaluate(t in_range_listtwithin_range_listt cldr_moduloR#t_PythonCompilerR?R$R=R%R1RRQRteval(RRt namespacetto_python_funcRTR:R0tcode((s0/usr/lib/python2.7/site-packages/babel/plural.pyRHs   ' cCstj|}|jttgB}tj}gtD]}||kr8|^q8j}dt |g}x:|j D]/\}}|j d||||fqvW|j d|tdj |S(s~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 snplurals=%d; plural=(s %s ? %d : s%d)R( R$R=ROR)RQt_GettextCompilerR?R,tindexRR%R1R(RRt used_tagsR@R:t _get_indexRTR0((s0/usr/lib/python2.7/site-packages/babel/plural.pyt to_gettexts  ('cCs|t|kot||S(sInteger 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 R\(tnumt range_list((s0/usr/lib/python2.7/site-packages/babel/plural.pyR[scstfd|DS(sFloat 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 c3s-|]#\}}|ko$|kVqdS(N((R tmin_tmax_(Rh(s0/usr/lib/python2.7/site-packages/babel/plural.pys $s(tany(RhRi((Rhs0/usr/lib/python2.7/site-packages/babel/plural.pyR\scCs_d}|dkr%|d9}d}n|dkr>|d9}n||}|r[|d9}n|S(sJavaish 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 iii((tatbtreversetrv((s0/usr/lib/python2.7/site-packages/babel/plural.pyR]'s        t RuleErrorcBseZdZRS(sRaised if a rule is malformed.(R9RJRK(((s0/usr/lib/python2.7/site-packages/babel/plural.pyRq>stnivwfts\s+twords)\b(and|or|is|(?:with)?in|not|mod|[{0}])\btvalues\d+tsymbols%|,|!=|=tellipsiss\.{2,3}|\u2026cCs|jdd}g}d}t|}x||krxxtD]\\}}|j||}|dk rA|j}|r|j||jfnPqAqAWtd||q.W|dddS(Nt@is5malformed CLDR pluralization rule. Got unexpected %ri( tsplitRt_RULEStmatchtNonetendR1tgroupRq(tsRTtposR|ttokRRRz((s0/usr/lib/python2.7/site-packages/babel/plural.pyt tokenize_ruleMs   cCs8|o7|dd|ko7|dkp7|dd|kS(Niii(R{(ttokensttype_Rt((s0/usr/lib/python2.7/site-packages/babel/plural.pyttest_next_token`scCs t|||r|jSdS(N(Rtpop(RRRt((s0/usr/lib/python2.7/site-packages/babel/plural.pyt skip_tokenescCs d|ffS(NRt((Rt((s0/usr/lib/python2.7/site-packages/babel/plural.pyt value_nodejscCs |dfS(N(((tname((s0/usr/lib/python2.7/site-packages/babel/plural.pyt ident_nodenscCs d|fS(NRi((Ri((s0/usr/lib/python2.7/site-packages/babel/plural.pytrange_list_noderscCs d|ffS(Ntnot((Rp((s0/usr/lib/python2.7/site-packages/babel/plural.pytnegatevsR/cBsneZdZdZd d dZdZdZdZdZ dZ dZ d Z d Z RS( sInternal 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`. cCs_t||_|js%d|_dS|j|_|jr[td|jddndS(NsExpected end of rule, got %rii(RRR{R0t conditionRq(R2tstring((s0/usr/lib/python2.7/site-packages/babel/plural.pyR7s   cCst|j||}|dk r%|S|dkrRt|dkrF|pI|}n|jsntd|ntd||jddfdS(Ns#expected %s but end of rule reachedsexpected %s but got %rii(RRR{treprRq(R2RRtttermttoken((s0/usr/lib/python2.7/site-packages/babel/plural.pytexpects  ! cCsD|j}x1t|jddr?d||jff}qW|S(NRstor(t and_conditionRR(R2top((s0/usr/lib/python2.7/site-packages/babel/plural.pyRs cCsD|j}x1t|jddr?d||jff}qW|S(NRstand(trelationRR(R2R((s0/usr/lib/python2.7/site-packages/babel/plural.pyRs cCs|j}t|jddrRt|jddr<dp?d||jffSt|jdd}d}t|jddrd}n7t|jdds|rtdn|j|Sd|||jff}|rt|S|S( NRstisRtisnottintwithins#Cannot negate operator based rules.R(R6RRRtRqtnewfangled_relationRiR(R2tlefttnegatedtmethodRp((s0/usr/lib/python2.7/site-packages/babel/plural.pyRs   cCswt|jddrt}n*t|jddr<t}n tddd||jff}|rst|S|S(NRut=s!=s'Expected "=" or "!=" or legacy relationRR(RRtFalsetTrueRqRiR(R2RRRp((s0/usr/lib/python2.7/site-packages/babel/plural.pyRs   cCs<|j}t|jdr.||jfS||fSdS(NRv(RtRR(R2R((s0/usr/lib/python2.7/site-packages/babel/plural.pytrange_or_values cCsH|jg}x,t|jddr=|j|jqWt|S(NRut,(RRRR1R(R2Ri((s0/usr/lib/python2.7/site-packages/babel/plural.pyRiscCst|jd}|dks.|dtkr=tdn|d}t|jddrxd|df|jffSt|jddrd|df|jffSt|S( NRsisExpected identifier variabletmodRut%(((RRR{t_VARSRqRtR(R2RsR((s0/usr/lib/python2.7/site-packages/babel/plural.pyR6s cCstt|jddS(NRti(RR R(R2((s0/usr/lib/python2.7/site-packages/babel/plural.pyRtsN(R9RJRKR7R{RRRRRRRiR6Rt(((s0/usr/lib/python2.7/site-packages/babel/plural.pyR/zs        cs fdS(s%Compiler factory for the `_Compiler`.cs |j||j|fS(N(R?(R2tltr(ttmpl(s0/usr/lib/python2.7/site-packages/babel/plural.pyRCR((R((Rs0/usr/lib/python2.7/site-packages/babel/plural.pyt_binary_compilerscs fdS(s%Compiler factory for the `_Compiler`.cs|j|S(N(R?(R2RB(R(s0/usr/lib/python2.7/site-packages/babel/plural.pyRCR((R((Rs0/usr/lib/python2.7/site-packages/babel/plural.pyt_unary_compilerscCsdS(NR ((RB((s0/usr/lib/python2.7/site-packages/babel/plural.pyRCRt _CompilercBseZdZdZdZdZdZdZdZdZ dZ e d Z e d Z ed Ze d Ze d Ze dZdZRS(sZThe compilers are able to transform the expressions into multiple output formats. cCs#|\}}t|d||S(Ntcompile_(tgetattr(R2targRtargs((s0/usr/lib/python2.7/site-packages/babel/plural.pyR?s cCsdS(NR((RB((s0/usr/lib/python2.7/site-packages/babel/plural.pyRC RcCsdS(NR((RB((s0/usr/lib/python2.7/site-packages/babel/plural.pyRC RcCsdS(NR((RB((s0/usr/lib/python2.7/site-packages/babel/plural.pyRC RcCsdS(NR ((RB((s0/usr/lib/python2.7/site-packages/babel/plural.pyRCRcCsdS(NR!((RB((s0/usr/lib/python2.7/site-packages/babel/plural.pyRCRcCsdS(NR"((RB((s0/usr/lib/python2.7/site-packages/babel/plural.pyRCRcCs t|S(N(R(RBR((s0/usr/lib/python2.7/site-packages/babel/plural.pyRCRs (%s && %s)s (%s || %s)s(!%s)s (%s %% %s)s (%s == %s)s (%s != %s)cCs tdS(N(tNotImplementedError(R2RR6Ri((s0/usr/lib/python2.7/site-packages/babel/plural.pytcompile_relations(R9RJRKR?t compile_nt compile_it compile_vt compile_wt compile_ft compile_tt compile_valueRt compile_andt compile_orRt compile_nott compile_modt compile_ist compile_isnotR(((s0/usr/lib/python2.7/site-packages/babel/plural.pyRs               R^cBsGeZdZedZedZedZedZdZ RS(s!Compiles an expression to Python.s (%s and %s)s (%s or %s)s(not %s)s MOD(%s, %s)c Cs`ddjg|dD]"}dtt|j|^q}d|j|j||fS(Ns[%s]Ris(%s, %s)s %s(%s, %s)(RttupletmapR?tupper(R2RR6Ritrange_tcompile_range_list((s0/usr/lib/python2.7/site-packages/babel/plural.pyR%s  4( R9RJRKRRRRRRR(((s0/usr/lib/python2.7/site-packages/babel/plural.pyR^s     RccBs8eZdZejZeZeZeZ eZ dZ RS(s)Compile into a gettext plural expression.cCsg}|j|}x|dD]v}|d|dkra|jd||j|dfq t|j|\}}|jd||||fq Wddj|S(Niis (%s == %s)s(%s >= %s && %s <= %s)s(%s)s || (R?R1RR(R2RR6RiRptitemtmintmax((s0/usr/lib/python2.7/site-packages/babel/plural.pyR6s  ( R9RJRKRRRt compile_zeroRRRRR(((s0/usr/lib/python2.7/site-packages/babel/plural.pyRc-s RPcBs8eZdZdZeZeZeZeZdZ RS(s/Compiles the expression to plain of JavaScript.cCsdS(NsparseInt(n, 10)((RB((s0/usr/lib/python2.7/site-packages/babel/plural.pyRCORcCsMtj||||}|dkrI|j|}d|||f}n|S(NRs(parseInt(%s, 10) == %s && %s)(RcRR?(R2RR6RiRb((s0/usr/lib/python2.7/site-packages/babel/plural.pyRUs  ( R9RJRKRRRRRRR(((s0/usr/lib/python2.7/site-packages/babel/plural.pyRPJs R>cBs_eZdZedZedZedZedZedZdZ e dZ RS(s+Returns a unicode pluralization rule again.s%s is %ss %s is not %ss %s and %ss%s or %ss %s mod %scCs|jdt|dS(NRi(RR(R2R((s0/usr/lib/python2.7/site-packages/babel/plural.pyRkscCsg}xf|dD]Z}|d|dkrH|j|j|dq|jdtt|j|qWd|j||rdpd|dj|fS(Niis%s..%ss %s%s %s %ss notRR(R1R?RRR(R2RR6RiRtrangesR((s0/usr/lib/python2.7/site-packages/babel/plural.pyRns'( R9RJRKRRRRRRRRR(((s0/usr/lib/python2.7/site-packages/babel/plural.pyR>^s      (RRRRRR('RKtret babel._compatRR,RQR#tobjectR$RURHRgR[R\R]t ExceptionRqRR{R?tUNICODEtformatRyRRRRRRRR/RRRRR^RcRPR>(((s0/usr/lib/python2.7/site-packages/babel/plural.pyt sH  8]  (            {