o ]Lbі@sdZddlmZmZddlZddlZddlmZddlm Z m Z ddl m Z m Z mZmZmZmZmZmZmZddlmZmZid d d d d ddddddddddddddddddd d!d"d#d$d%d&d'dZdd(d)Zdd+d,Zdd.d/Zdd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Z dd?Z"d@dAZ#dBdCZ$dDdEZ%dFdGZ&dHdIZ'dJdKZ(dLdMZ)dNdOZ*dPdQZ+dRdSZ,dTdUZ-dVdWZ.dXdYZ/dZd[Z0idd\d]d#d^d]d!d_d]d%e'd`dad]d e*de(d e)dbe-dce/dde0dded]ddfd]dge+ddhd]ddid]Z1e12Z3e1d!e3d<Gdjdkdkej4Z5dldmZ6dndoZ7Gdpdqdqe8Z9Gdrdsdse9Z:Gdtdudue8Z;dvdwZGd|d}d}e8Z?Gd~dde8Z@ddZAdddZBdddZCdS)aSlightly complicated template engine for commands and hgweb This module provides low-level interface to the template engine. See the formatter and cmdutil modules if you are looking for high-level functions such as ``cmdutil.rendertemplate(ctx, tmpl)``. Internal Data Types ------------------- Template keywords and functions take a dictionary of current symbols and resources (a "mapping") and return result. Inputs and outputs must be one of the following data types: bytes a byte string, which is generally a human-readable text in local encoding. generator a lazily-evaluated byte string, which is a possibly nested generator of values of any printable types, and will be folded by ``stringify()`` or ``flatten()``. None sometimes represents an empty value, which can be stringified to ''. True, False, int, float can be stringified as such. wrappedbytes, wrappedvalue a wrapper for the above printable types. date represents a (unixtime, offset) tuple. hybrid represents a list/dict of printable values, which can also be converted to mappings by % operator. hybriditem represents a scalar printable value, also supports % operator. revslist represents a list of revision numbers. mappinggenerator, mappinglist represents mappings (i.e. a list of dicts), which may have default output format. mappingdict represents a single mapping (i.e. a dict), which may have default output format. mappingnone represents None of Optional[mappable], which will be mapped to an empty string by % operation. mappedgenerator a lazily-evaluated list of byte strings, which is e.g. a result of % operation. )absolute_importprint_functionN)_)FileNotFoundErrorgetattr) configencodingerrorparserpycompattemplatefilters templatefuncs templateutilutil) resourceutil stringutil()N)groupr))funcrrN.)NN)rrN%)NN)rrN|)rNN)rrN*)NN)rrN/)rNN)rrN+)NN)r r!N-)r!N)negate)r"r!N=)NN)keyvaluer&N,)NN)listr)Nr)rNNNNinteger)rr+NNNsymbol)rr,NNNstring)rr-NNNtemplate)rr.NNNendc csV|}t|}||kr||}|rny|dvr#|d|fVnm|dvr@|d}t||||\}}d||fV|d8}nP|dkr|||ddvr||d}|d}}||kr||}|d krk|d7}qZ||krzd ||||fVn|d7}||ks^ttd |n|r|}||kr||}|sn|d7}||ksd ||||fV|d8}n|d kr|||dd vs|dkr=|||ddvr=|dkr|d7}d } nd} |||d} |d}}||kr4|d||r|d7}q|| ||r,t |||}| dkr!t|dt |d}| ||fV|d7}n|d7}||ksttd |nS| sG|dvr{|}|d7}||krj||}| sa|dksan |d7}||ksR|||} d| |fV|d8}n||krdd|fVdSttd||d7}||ks |rttd|dd|fVdS)z^Parse a template expression into a stream of tokens, which must end with term if specifieds (=,).%|+-*/Ns"'rr.rr))sr'sr"\r-unterminated stringr+)s\'s\"r&)sr\'sr\"s\\\r!r_r,r/s syntax errorsunterminated template expansion) r bytestrisspace_parsetemplater ParseErrorrisdigit startswithr unescapestrlenisalnum) programstartendtermposcsdatadtokenquotesymrI5/usr/lib/python3/dist-packages/mercurial/templater.pytokenizeus                    ZrKcCstg}t||||D]+\}}}|dkr|||fq |dkr$||q |dkr.||fStd|td)a >>> _parsetemplate(b'foo{bar}"baz', 0, 12) ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12) >>> _parsetemplate(b'foo{bar}"baz', 0, 12, quote=b'"') ([('string', 'foo'), ('symbol', 'bar')], 9) >>> _parsetemplate(b'foo"{bar}', 0, 9, quote=b'"') ([('string', 'foo')], 4) >>> _parsetemplate(br'foo\"bar"baz', 0, 12, quote=b'"') ([('string', 'foo"'), ('string', 'bar')], 9) >>> _parsetemplate(br'foo\\"bar', 0, 10, quote=b'"') ([('string', 'foo\\')], 6) r-r.r/sunexpected type: %s!unterminated scanning of template) _scantemplateappendr ProgrammingError)tmplr>stoprGparsedtypvalrArIrIrJr6s    r6FccsVd}t|dt||dD]\}}}|r||fV|dkr!dS||f}q td)aScan (type, start, end) positions of outermost elements in template If raw=True, a backslash is not taken as an escape character just like r'' string in Python. Note that this is different from r'' literal in template in that no template fragment can appear in r'', e.g. r'{foo}' is a literal '{foo}', but ('{foo}', raw=True) is a template expression 'foo'. >>> list(scantemplate(b'foo{bar}"baz')) [('string', 0, 3), ('template', 3, 8), ('string', 8, 12)] >>> list(scantemplate(b'outer{"inner"}outer')) [('string', 0, 5), ('template', 5, 14), ('string', 14, 19)] >>> list(scantemplate(b'foo\\{escaped}')) [('string', 0, 5), ('string', 5, 13)] >>> list(scantemplate(b'foo\\{escaped}', raw=True)) [('string', 0, 4), ('template', 4, 13)] Nr)rawr/rM)rNr;r rP)rQrVlastrTrUrArIrIrJ scantemplates   rXc #sd|}tjtjg|}|tt}zkrtfddt|Dddd}|dkr@d|fVn||d } d} |s[|t|d } | d d krvd||d | fV|d q|krd||fV| |krd d |d fVWd S| t |d d\}  dst tdd| |fVd 7ks|rt td|Wnt j y} zt| d } ~ wwd d fVd S)zEParse template string into chunks of strings and template expressions{c3s|] }|VqdSN)find).0rBrArRrQrIrJ sz _scantemplate..cSs |dk|fS)NrrI)nrIrIrJs z_scantemplate..)keyrr-rr1r)r/N} invalid tokenr.r2)r r:r identityelementsminr4r;rstripparserKr9r r7r_addparseerrorhint) rQr>rRrGrVsepcharsunescapepr_rBbsparseresinstrIr]rJrNsV      rNcCs\|jdurdS|j}|d|d}|dd}|dd|d|dtd|_dS)N s\n rs^ shere)locationcountreplacerhint)rorQlocoffsetrIrIrJri=s  *ricCst|ts|S|d}|dkr|ftdd|ddDSt|dks'Jtdd|dD}|s6d St|dkrH|ddd krH|dS|f|S) a;Expand list of templates to node tuple >>> def f(tree): ... print(pycompat.sysstr(prettyformat(_unnesttemplatelist(tree)))) >>> f((b'template', [])) (string '') >>> f((b'template', [(b'string', b'foo')])) (string 'foo') >>> f((b'template', [(b'string', b'foo'), (b'symbol', b'rev')])) (template (string 'foo') (symbol 'rev')) >>> f((b'template', [(b'symbol', b'rev')])) # template(rev) -> str (template (symbol 'rev')) >>> f((b'template', [(b'template', [(b'string', b'foo')])])) (string 'foo') rr.cs|]}t|VqdSrZ_unnesttemplatelistr\xrIrIrJr^dz&_unnesttemplatelist..rNr)csrxrZryr{rIrIrJr^gr})r-rLr-) isinstancetupler;)treeopxsrIrIrJrzMs   rzcCs4t|dt|\}}|t|ksJdtd|fS)zParse template string into treers$unquoted template should be consumedr.)r6r;rz)rQrSrArIrIrJrhps rhc Cs2zt|WStjy}zt||d}~ww)a=Parse a template expression into tree >>> parseexpr(b'"foo"') ('string', 'foo') >>> parseexpr(b'foo(bar)') ('func', ('symbol', 'foo'), ('symbol', 'bar')) >>> from . import error >>> from . import pycompat >>> try: ... parseexpr(b'foo(') ... except error.ParseError as e: ... pycompat.sysstr(e.message) ... e.location 'not a prefix: end' 4 >>> try: ... parseexpr(b'"foo" "bar"') ... except error.ParseError as e: ... pycompat.sysstr(e.message) ... e.location 'invalid token' 7 N) _parseexprr r7ri)exprrorIrIrJ parseexprws  rcCsHtt}|t|dt|\}}|t|kr ttd|t|S)Nrrc) r rerhrKr;r r7rrz)rrlrrArIrIrJrs  rcCs t|dS)N)r+r-r,)r prettyformatrrIrIrJrs rcCs(|s ttd|d}||||S)z1Compile parsed template tree to (func, data) pairsmissing argumentrr r7r)expcontext curmethodstrIrIrJ compileexpsrcCs*|ddkr |dSttd|d)Nrr,rsexpected a symbol, got '%s'r)rrIrIrJ getsymbols rcCs0|sgS|ddkrt|d|dgS|gS)Nrr*rr)getlist)r|rIrIrJrs  rcCs@|ddvr t||tS|ddkr||dSttd)z_Compile given template tree or load named template from map file; returns (func, data) pairr)r.r-r,rsexpected template specifier)rmethods_loadr r7rrrrIrIrJ gettemplates   rcCsttd|)Ns$recursive reference '%s' in template)r InputErrorr)rmappingrarIrIrJ_runrecursivesymbolsrcs$fdd|ddD}tj|fS)Ncsg|]}t|tqSrI)rr)r\errIrJ z!buildtemplate..r)r runtemplate)rrctmplrIrrJ buildtemplates rcCst|d}||jvr|j|}t|d|t}tj||ffS||jvr8|j|}t|d|t||j}||fSt t d|)Nr)runknown function '%s') r_filtersrrr runfilter_funcs_buildfuncargs_argspecr r7r)rrr_filtargfargsrIrIrJ buildfilters     rcCs,t|d|t}t|d|}tj||ffSNrr))rrrrrunmap)rrdargtargrIrIrJbuildmapsrcCs*t|d|t}t|d}tj||ffSr)rrrr runmember)rrrmembrIrIrJ buildmembers rcCst|d|t}tj|fSNr)r exprmethodsr runnegate)rrrrIrIrJ buildnegates rcCs0t|d|t}t|d|t}tj|||ffSr)rrr runarithmetic)rrfuncleftrightrIrIrJbuildarithmeticsrcCst|d}||jvr|j|}t|d|t||j}||fS||jvrLt|d|t|dd}t|dkr>tt d||j|}t j |d|ffStt d|)Nrr))argspecsfilter %s expects one argumentrr) rrrrrrr;r r7rrr)rrr_rrrIrIrJ buildfuncs      rc sfdd}fdd}|s|t|St|\}}} } }tjt|||ddd} t} |r<|| || |<| rG|| | | | <| || | S)aCompile parsed tree of function arguments into list or dict of (func, data) pairs >>> context = engine(lambda t: (templateutil.runsymbol, t)) >>> def fargs(expr, argspec): ... x = _parseexpr(expr) ... n = getsymbol(x[1]) ... return _buildfuncargs(x[2], context, exprmethods, n, argspec) >>> list(fargs(b'a(l=1, k=2)', b'k l m').keys()) ['l', 'k'] >>> args = fargs(b'a(opts=1, k=2)', b'**opts') >>> list(args.keys()), list(args[b'opts'].keys()) (['opts'], ['opts', 'k']) cs tfddt|DS)Nc3s$|] \}}|t|fVqdSrZr)r\kr|rrrIrJr^s  z6_buildfuncargs..compiledict..)rsortdictr iteritemsrrrIrJ compiledictsz#_buildfuncargs..compiledictcsfdd|DS)Ncsg|]}t|qSrIrr{rrIrJrrz7_buildfuncargs..compilelist..rIrrrIrJ compilelistz#_buildfuncargs..compilelistr'r,) keyvaluenodekeynode)rr splitargspec buildargsdictrrpopupdate) rrrfuncnamerrr_poskeysvarkey_keysoptkeytreeargscompargsrIrrJrs& rcCsttd)Ns*can't use a key-value pair in this contextr)rcontentrIrIrJbuildkeyvaluepair3srcCstjtdtdd)Ns can't use a list in this contextscheck place of comma and parensrurrrIrIrJ buildlist7srcCtj|dfSr)r runintegerrrBrIrIrJr`@r`cCrr)r runstringrrIrIrJr`ArcCrr)r runsymbolrrIrIrJr`BrrcCst|d|tSr)rrrrIrIrJr`Drr'r*cCt||ddS)NcSs||SrZrIabrIrIrJr`K..rrrIrIrJr`KrcCr)NcSs||SrZrIrrIrIrJr`LrrrrrIrIrJr`Lrr#cCr)NcSs||SrZrIrrIrIrJr`NrrrrrIrIrJr`NrcCr)NcSs||SrZrIrrIrIrJr`OrrrrrIrIrJr`Orc@s,eZdZdZedZeeZeddZ dS) _aliasrulesz2Parsing and expansion rule set of template aliasesstemplate aliascCsn|ddkr|dddkr|ddt|dfS|ddkr3|dddkr5|dd|dgfSdSdS)zNReturn (name, args) if tree is func(...) or ...|filter; otherwise Nonerrrr,r)rNrrrIrIrJ _trygetfunc]s z_aliasrules._trygetfuncN) __name__ __module__ __qualname____doc__r_section staticmethodr_parserrIrIrIrJrWs rcCst|}t||S)z'Return new tree of aliases are expanded)rrexpand)raliasesaliasmaprIrIrJ expandaliasesgs  rcCs8t|dks|ddvs|d|dkr|S|ddS)z9unwrap quotes if any; otherwise returns unmodified stringr)r'"r)r;)rCrIrIrJ unquotestringps( rc@sNeZdZdZejZejddZejddZ ejddZ ejdd Z d S) resourcemapperz%Mapper of internal template resourcescCdS)BReturn a set of available resource keys based on the given mappingNrIselfrrIrIrJ availablekeys|zresourcemapper.availablekeyscCr)'Return a set of supported resource keysNrIrrIrIrJ knownkeysrzresourcemapper.knownkeyscCr)z:Return a resource for the key if available; otherwise NoneNrIrrrarIrIrJlookuprzresourcemapper.lookupcCr)zcReturn a dict of additional mapping items which should be paired with the given new mappingNrIrr origmapping newmappingrIrIrJ populatemaprzresourcemapper.populatemapN) rrrrabcABCMeta __metaclass__abstractmethodrrrrrIrIrIrJrws   rc@s,eZdZddZddZddZddZd S) nullresourcemappercCtSrZsetrrIrIrJrz nullresourcemapper.availablekeyscCr rZr rrIrIrJrr znullresourcemapper.knownkeyscCsdSrZrIrrIrIrJrznullresourcemapper.lookupcCsiSrZrIrrIrIrJrrznullresourcemapper.populatemapN)rrrrrrrrIrIrIrJr s  r c@szeZdZdZdddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZddZddZdS)engineatemplate expansion engine. template expansion works like this. a map file contains key=value pairs. if value is quoted, it is treated as string. otherwise, it is treated as name of template file. templater is asked to expand a key in map. it looks up key, and looks for strings like this: {foo}. it expands {foo} by looking up foo in map, and substituting it. expansion is recursive: it stops when there is no more {foo} to replace. expansion also allows formatting and filtering. format uses key to expand each item in list. syntax is {key%format}. filter uses function to transform value. syntax is {key|filter1|filter2|...}.NcCsV||_|dur i}||_tj|_|duri}|durt}||_||_i|_i|_ dSrZ) _loaderrrfuncsrr  _defaults _resources_cache _tmplcache)rloaderfiltersdefaults resourcesrIrIrJ__init__s zengine.__init__csVjj|fddt|D}|||j|||S)zfCreate combined mapping from the original mapping and partial mapping to override the originalcs.i|]\}}|vs|r||qSrI) isdisjoint_defaultrequires)r\rvknownresnewresrrIrJ sz%engine.overlaymap..)rrrr rrr)rrrrrIrrJ overlaymaps   zengine.overlaymapcCs,|j|}|dust|sdSt|ddS)z?Resource keys required by the specified default symbol functionNrI _requires)rgetcallabler)rrarrIrIrJrs  zengine._defaultrequirescCs4d}||jvr||}|dur|j|}|S)z:Resolve symbol to value or function; None if nothing foundN)rrr$rrrrarrIrIrJsymbols   z engine.symbolcC |j|S)r)rrrrIrIrJavailableresourcekeys zengine.availableresourcekeyscCs |jS)r)rrrrIrIrJknownresourcekeyss zengine.knownresourcekeyscCs,|j||}|durttd||S)zNReturn internal data (e.g. cache) used for keyword/function evaluationNs#template resource not available: %s)rrrResourceUnavailablerr&rIrIrJresources  zengine.resourcecCsT||jvr%||}t|f|j|<z t||t|j|<Wn|j|=|j|S)z!load, parse, and cache a template)rrrrr)rrr|rIrIrJrs   z engine._loadcCs.||jvrt|}t||t|j|<|j|S)z"Parse and cache a literal template)rrhrrrrQr|rIrIrJrs  z engine._parsecCs(z||WdStjyYdSw)z:Load, parse, and cache the specified template if availableTF)rrTemplateNotFoundrrrIrIrJpreload s  zengine.preloadcC||\}}||||S)zPerform expansion. t is name of map element to expand. mapping contains added elements for use during expansion. Is a generator.)r_expand)rrrrrDrIrIrJprocessszengine.processcCr2)zPerform expansion over a literal template No user aliases will be expanded since this is supposed to be called with an internal template string. )rr3)rrQrrrDrIrIrJrsz engine.expandcCs8|j|i|}|r|||}t||||||SrZ)rrrrflatten)rrrDr extramappingrIrIrJr3"s  zengine._expand)NNN)rrrrrr"rr'r)r+r-rrr1r4rr3rIrIrIrJrs     rcCsjt}|s tdSt|}g}|D]}|d}|ddvr q|ddkr-||dqdt|S) Ns7no templates found, try `hg debuginstall` for more inforr)sorigsrejrs map-cmdliners, ) templatedirroslistdirsplitrOjoinsorted)pathdirlist stylelistfiler:rIrIrJr?-s    r?cCs8tj|r t|dStjtd|tdtd)Nrbsstyle '%s' not foundsavailable styles: %sr) r8r=existsr posixfiler Abortrr?)mapfilerIrIrJ _open_mapfile<s    rFc stjr|tj}d|}tj|tfdd| }j ||ddidi}i}g} dd}|r|dd vrtj tj|}tj |st} | d urtj tj| |} tj| ro| }ntj tj| d } tj| r| }t|}t||\}}}dD]@\} }|sttd d| |dd vr|d|d krttdd| t||| <q| dkrtj||| <q|d|||fS)z.Load template elements from the given map filercsd}rtjtj|}tj|rt|d}|sTtj|vr8|}zt d|}Wn't y7d}Ynwt }|rTtjtj||}tj|rTt|d}|rf| }j||||ddSdS)NrAsmercurial.templates)sectionsremapinclude)r8r=normpathr;isfilerrCr ossepr open_resourcerr7readrh)relrHrG subresourceabsdirrDbaseconfrIrIrJrIQs<       z_readmapfile..includerL templates)rHrIs__base__rrNsmaps missing valuersunmatched quotess templatealias)r iswindowsr:rLr;r8r=dirnamerrNrhr$rJrBr7rKrF _readmapfileitemsr r7rsourcerextend) fprE name_pathsrDcachetmaprrUr=rRp2p3rarIrSrJrYEsR         rYc@s@eZdZdZddZddZddZdd Zd d Zd d Z dS)rz2Load template fragments optionally from a map filecCs,|duri}||_i|_t||_dSrZ)copyr__maprr _aliasmap)rr_rrIrIrJrs  zloader.__init__cCs||jvp ||jvSrZ)r_rdrrarIrIrJ __contains__rzloader.__contains__c Cs||jvrWzt|j|\}}||j|<Wn?ty/}z ttd|jdd}~wt yV}ztd|j|t |jdf}t |jdt |d}~ww||j|S)?Get parsed tree for the given template name. Use a local cache.s"%s" not in template maprNstemplate file %s: %sr)r_ open_templaterdrNKeyErrorrr/rrIOErrorr forcebytestrr strfromlocalr)rrrEr]roreasonrIrIrJloads$ z loader.loadcCs t|}|jrt|j|}|SrZ)rhrerrr.rIrIrJrsz loader._parsecCs|sdS|d}|dkr4|d}||dvrdS|d|||jvs)||jvr2||||dS|dvr:dS|dkrS|dt|d||d|dS|dkrl|dt|d||d|dS|ddD]}|||qrdS)Nrr,r>r-r+rr)r)addr_rd_findsymbolsusedror)rrsymsrrCr|rIrIrJrqs0 zloader._findsymbolsusedcCs"ttf}|||||SzLook up (keywords, filters/functions) referenced from the name template 't' This may load additional templates from the map file. )r rqro)rrrrrIrIrJ symbolsuseds zloader.symbolsusedN) rrrrrrgrorrqrtrIrIrIrJrs rc@seZdZ       dddZe       dddZd d Zed d Zed dZ eddZ ddZ ddZ ddZ ddZddZddZdS) templaterNrIc CsJtj}|r ||t|||_t|jj||||_|||_ |_ dS)agCreate template engine optionally with preloaded template fragments - ``filters``: a dict of functions to transform a value into another. - ``defaults``: a dict of symbol values/functions; may be overridden by a ``mapping`` dict. - ``resources``: a resourcemapper object to look up internal data (e.g. cache), inaccessible from user template. - ``cache``: a dict of preloaded template fragments. - ``aliases``: a list of alias (name, replacement) pairs. self.cache may be updated later to register additional template fragments. N) r rrcrrrrro_proc _minchunk _maxchunk) rrrrr_rminchunkmaxchunk allfiltersrIrIrJrs   ztemplater.__init__c CsX|||||g||} |st|}t||\}} } | jj|| | j_t| | j_| S)z,Create templater from the specified map file) rFrYrr_rrdrrre) clsrEr]rrrr_r{r|rr`rrIrIrJ frommapfiles ztemplater.frommapfilecCs ||jvSrZ)rrfrIrIrJrgs ztemplater.__contains__cC|jjSrZ)rr_rrIrIrJr_ztemplater.cachecCrrZ)rxrrrIrIrJr$rztemplater._filterscCrrZ)rxrrrIrIrJr(rztemplater.defaultscCr()rh)rror0rIrIrJro,r*ztemplater.loadcCs |dS)zLook up (keywords, filters/functions) referenced from the default unnamed template This may load additional templates from the map file. rL)rtrrIrIrJsymbolsuseddefault0s ztemplater.symbolsuseddefaultcCr(rs)rrtr0rIrIrJrt8s ztemplater.symbolsusedcCs |d|S)z?Render the default unnamed template and return result as stringrL)renderrrIrIrJ renderdefault@r*ztemplater.renderdefaultcCsd|||S)z?Render the specified named template and return result as stringrL)r;generate)rrrrIrIrJrDsztemplater.rendercCs,|j||}|jrtj||j|jd}|S)zVReturn a generator that renders the specified named template and yields chunks)rfmax)rxr4ryrincreasingchunksrz)rrrstreamrIrIrJrHs  ztemplater.generate)NNNNrIrvrw)NNNNNrvrw)rrrr classmethodrrgpropertyr_rrrorrtrrrrIrIrIrJrus>      rucCs,tjtjtjd}tj|r|SdS)z6return the directory used for template files, or None.rVN)r8r=rJr;rdatapathisdir)r=rIrIrJr7Ssr7cCstj|s tj|r|t|ddfS|durt}|dur.tj||}|t|ddfStjr<| tj }d|}| d}dddg|dd}|t ||dfS) a returns a file-like object for the given template, and its full path If the name is a relative path and we're in a frozen binary, the template will be read from the mercurial.templates package instead. The returned path will then be the relative path. rb)modeNrrs mercurialrVr) r8r=rKisabsopenr7r;r rWr:rLrrM)name templatepathrr^ name_parts package_namerIrIrJriYs   ric Cs&zt||WSttfyYdSw)N)NN)riEnvironmentError ImportError)rrrIrIrJtry_open_template|s  rrZ)rL)F)rLF)Dr __future__rrrr8i18nrr rrrr r r r rrrutilsrrrerKr6rXrNrirzrhrrrrrrrrrrrrrrrrrrrrcrbasealiasrulesrrrobjectrr rr?rFrYrrur7rirrIrIrIrJs< ,        d  -#   /        WKl #