;ibddlmZ ddlZdZdZdZdZdZedkreej ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZdd lmZdd lmZmZmZdd lm Z dd l!m"Z"m#Z#dd l$m%Z% ddl&m'Z(m)Z*n#e+$r ddl,m'Z(m)Z*YnwxYwej-Z.e.j/dkZ0e0rxddl1m2Z3ddl4Z5ddl6m7Z7m8Z9ddl6m:Z:m;Zej?e>dZ>ddl@mAZAmBZBmCZCddlDmEZFddlmGZHddlIZIddlJmKZKddlLZLddlmMZMeMjNZOddlPmQZQdZReSZTeSZUdZVdZWeXZYdZZnej[de\ddl3Z3ddl5Z5ddl]m7Z7m8Z9ddl^m:Z:m;Zddl_mAZAmBZBmCZCddlmYZYddl`ZIdd lamHZHdd!lbmbZKddlcZLddldmEZFdd"lPmRZRdd#lmeZeGd$d%eeZfefZOeUZUe*ZVegehd&d'd(dd*Zidd,Zje0rejneiZkd-Zld.Zmdd0Znd1ZoGd2d3epZqGd4d5epZrGd6d7epZsGd8d9etZuGd:d;euZvGd<d=euZwGd>d?evZxGd@dAevZyGdBdCevZzdDZ{GdEdFepZ|GdGdHepZ}GdIdJepZ~GdKdLepZdMZdNZGdOdPepZGdQdRepZdSZGdTdUeZGdVdWeZeZeZGdXdYeeuZGdZd[eZGd\d]euZGd^d_epZGd`daepZGdbdcepZGdddeeFZGdfdgeZGdhdieZGdjdkeFZepZGdldmeZGdndoeZGdpdqepZGdrdsepZGdtduepZGdvdwepZddzZdd{Zdd}Z ddZddZdZdZdZddZejhdjZdZdZdZddZddZdZdZdZdZddZd dZdZedZedZedZedZedZedZedZedZedZedZedZedZGddeZGddepZGddepZGddepZGdde¦ZGdde¦ZGdde¦ZGdde¦ZGdde¦ZGdde¦ZGdde¦ZGdde¦ZGdde¦ZGdde¦ZGdde¦ZGdde¦ZGdÄde¦ZGdńde¦ZGdDŽde¦ZGdɄde¦ZGd˄de¦ZGd̈́de¦ZGdτdeԦZGdфdeզZGdӄde¦ZideÓdeēdeœdeȓdeƓdeǓdeɓde˓de̓de͓deΓdeϓdeʓdeѓdeғdeГdeӓeeedZdZdZeZ d!dZGddejZGddeuZGddepZGddeZGddeZGddeZGddeZGddeߦZGddepZdZej?eeZej?eeZej?eeZdZej?eeZej?eeZej?eeZddgZiZdadae3jZded<ded<ded<d ed <d ed <d ed<edeDZdezZeZeZejZexZxZZeedkrdnedzdjZdZdZedkr edSdS(")print_functionNzMarcel Hellkampz0.13.4MITcddlm}||dd}|j}|ddd|d d d d |dddd|dddd|ddddd|ddddd|d dd!|d"dd#|d$d%d&'||d(d}||fS))Nr)ArgumentParserz%%(prog)s [options] package.module:app)progusagez --version store_truezshow version number.)actionhelpz-bz--bindADDRESSzbind socket to ADDRESS.)metavarr z-sz--serverwsgirefzuse SERVER as backend.defaultr z-pz--pluginappendzinstall additional plugin/s.z-cz--confFILEzload config values from FILE.)r r r z-Cz--paramz NAME=VALUEzoverride config values.z--debugzstart server in debug mode.z--reloadzauto-reload on file changes.appzWSGI app entry point.?)r nargs)argparser add_argument parse_args)argsrparseroptcli_argss :C:\PYTHON\MyICR_Workspace\venv\Lib\site-packages\bottle.py _cli_parsersQ'''''' ^a0W X X XF  CC L/EFFFFCh 0IJJJJCj)2JKKKKCj0NOOOOChx ,....Ci, &((((C ,-JKKKKC <.LMMMMC+37777  abb**H V ct|\}}|}|jrm|jdrddl}|jdS|jdrddl}|dSdSdS)Ngeventreventlet)rserver startswith gevent.monkeymonkey patch_allr# monkey_patch)r parsed_args_optsr"r#s r _cli_patchr-5s))NK D {$ ; ! !( + + $ M # # % % % % % [ # #J / / $ OOO  ! ! # # # # # $$ $ $r __main__) FunctionType)datedatetime timedelta)NamedTemporaryFile) format_exc print_exc) normalize)dumpsloads)urljoin SplitResult) urlencodequoteunquotelatin1)encoding) SimpleCookieMorsel CookieError)MutableMapping) ModuleType)BytesIO)timezone)getfullargspecct|}t|dt|jz}||d|d|dfS)Nrrr9)rHmakelist kwonlyargs)funcspeckwargss r getargspecrPksJd##$q'""Xdo%>%>>tAwQa00r c:tt|SN)json_ldstouni)ss rrVrs8E!HH--r c"t|dSN__call__)hasattrxs rrVrVssJ//r cb|d|d|d)Nrrr9)with_traceback)as r_raiser`vs*ad1Q4jj''!---r z/Python 2 support will be dropped in Bottle 0.14)imap) new_module)StringIO)rP)tzinfoc eZdZdZdZdZdS)_UTCc tdSNrr2selfdts r utcoffsetz_UTC.utcoffsets ! !4r cdS)NUTCrjs rtznamez _UTC.tznamesUUr c tdSrhrirjs rdstz_UTC.dsts )A,,.r N)__name__ __module__ __qualname__rmrqrsrpr rrfrfs+444***.....r rfz&def _raise(*a): raise a[0], a[1], a[2]zexecutf8c|t|tr||S|dnt|S)Nr ) isinstanceunicodeencodebytes)rUencs rtobrs8!Wxx}})33q)r strictc~t|tr|||St|dn|SN)rzr}decoder{)rUr~errs rrTrTs>!U"xxS!!! 22 * **r cd t|dtjidS#ttf$rYdSwxYw)Nfile)printsysstderrIOErrorAttributeError)rs r_stderrrsI  t%#*%%%%% ^ $     s //cV tj||g|Ri|dS#t$rYdSwxYwrR) functoolsupdate_wrapperr)wrapperwrappedr_kas rrrsR  '.>ws|s|r cl|jrtd|t||j|j<dSNzRead-Only property.rrrrrrkrvalues r__set__zDictProperty.__set__s6 >F0E!F!FF,1TY)))r ch|jrtdt||j|j=dSrrrkrs r __delete__zDictProperty.__delete__s4 >F0E!F!FF C # #DH - - -r NF) rtrurv__doc__rrYrrrrpr rrrsnGGCCCC  222.....r rceZdZdZdZdZdS)cached_propertyz A property that is only computed once per instance and then replaces itself with an ordinary attribute. Deleting the attribute resets the property. c4t||||_dSrR)rrMrs rrzcached_property.__init__stT""" r c`||S||x}|j|jj<|SrR)rM__dict__rtrkrrrs rrzcached_property.__get__s0 ;t 3799S>>A TY/0 r Nrtrurvrrrrpr rrrs<r rceZdZdZdZdZdS)lazy_attributez4 A property that caches itself to the class object. cBtj||g||_dSr)rrrrs rrzlazy_attribute.__init__s% tR8888 r c\||}t||j||SrR)rsetattrrtrs rrzlazy_attribute.__get__s, C  T]E*** r Nrrpr rrrs8>>r rceZdZdZdS)BottleExceptionz- A base class for exceptions used by bottle. Nrtrurvrrpr rrrs77Dr rceZdZdZdS) RouteErrorz9 This is a base class for all routing related exceptions Nrrpr rrr sCCCCr rceZdZdZdS) RouteResetzf If raised by a plugin or request handler, the route is reset and all plugins are re-applied. Nrrpr rrrs$$$$r rceZdZdS)RouterUnknownModeErrorNrtrurvrpr rrrsDr rceZdZdZdS)RouteSyntaxErrorz@ The route parser found something not supported by this router. Nrrpr rrrsJJJJr rceZdZdZdS)RouteBuildErrorz The route could not be built. Nrrpr rrrs))))r rc<d|vr|Stjdd|S)z^ Turn all capturing groups in a regular expression pattern into non-capturing groups. (z(\\*)(\(\?P<[^>]+>|\((?!\?))ct|ddzr|dn|ddzS)Nrr9rz(?:)lengroup)ms rrVz_re_flatten..'sDaggajj//A%>>QWWQZZZ+,771::+=r )resubps r _re_flattenr"s9 !|| 614>4>?@ B BBr cleZdZdZdZdZdZddZdZe j dZ d Z dd Z d Zd ZdZd S)RouteraA A Router is an ordered collection of route->target pairs. It is used to efficiently match WSGI requests against a number of routes and return the first target that satisfies the request. The target may be anything, usually a string, ID or callable object. A route consists of a path-rule and a HTTP method. The path-rule is either a static path (e.g. `/contact`) or a dynamic path that contains wildcards (e.g. `/wiki/`). The wildcard syntax and details on the matching order are described in docs:`routing`. z[^/]+rcFcg_i_i_i_i_i_|_fddddd_dS)Nc6t|pjddfSrR)rdefault_pattern)confrks rrVz!Router.__init__..Hs! D,HD4H I I $d ,r cdtdfS)Nz-?\d+c:tt|SrR)strintr[s rrVz3Router.__init__....Js#c!ff++r )rrs rrVz!Router.__init__..Js30E0E Fr cdtdfS)Nz-?[\d.]+c:tt|SrR)rfloatr[s rrVz3Router.__init__....KsU1XXr )rrs rrVz!Router.__init__..Ks;7N7N"Or cdS)N)z.+?NNrprs rrVz!Router.__init__..Ls!5r )rrrpath)rules_groupsbuilderstatic dyna_routes dyna_regexes strict_orderfilters)rkrs` rrzRouter.__init__>so    ",,,,FFOO55    r c||j|<dS)z Add a filter. The provided function is called with the configuration string as parameter and must return a (regexp, to_python, to_url) tuple. The first element is a string, the last two are callables or None. N)rrknamerMs r add_filterzRouter.add_filterOs" Tr z(\\*)(?:(?::([a-zA-Z_][a-zA-Z_0-9]*)?()(?:#(.*?)#)?)|(?:<([a-zA-Z_][a-zA-Z_0-9]*)?(?::([a-zA-Z_]*)(?::((?:\\.|[^\\>])+)?)?)?>))c#Kd\}}|j|D]}||||z }|}|dt dddddt |ddzrH||dt |ddz }|}|r|ddfV|d |dd n |d d\}}}||pd |pdfV|d }}|t |ks|r|||dzddfVdSdS) N)rrr9r zUse of old route syntax.z&Use instead of :name in routes.rrrr) rule_syntaxfinditerstartgroupsrrrend) rkruleoffsetprefixmatchgrfiltrrs r _itertokenszRouter._itertokensZs%..t44 - -E d6%++--/0 0F AtQ6D'(****1Q4yy1} %++a..QqT44 )dD((((*+A$,!A#AacF D%*DLD8 8 8 8"YY[["FFF SYY  & 4=($4 4 4 4 4 4  r Ncd}g}d}gg}d} ||D]\} } } | rd} | dkr|j} |j| | \} }}| s|d| zz }d|z} |dz }n!|d | d | d z }|| |r| |f|| |ptf| r.|t j| z }|d | f||j|<|r ||j|<| rI|jsB|j |i|d f|j || |<d S t j d |z}|j n-#t j$r}td|d|d d }~wwxYwrfd}n|jrfd}nd }t#|}||||f}||f|jvrHt&r#d}t)j|||fzt,d||j||j||f<nU|j |g|t1|j|dz |j||f<||d S)z< Add a new rule or replace the target for an existing rule. rrTFrz(?:%s)anon%drz(?P<>)Nz^(%s)$zCould not add Route: z (c|}D]8\}} |||||<#t$rtddwxYw|S)NzPath has wrong format.) groupdict ValueError HTTPError)rurl_argsrwildcard_filterrre_matchs rgetargszRouter.add..getargss#8D>>3355-4GG)D/G)8$)H)H%GGG'-EFFFGs <Ac>|SrR)r)rr"s rr#zRouter.add..getargssx~~//111r z3Route <%s %s> overwrites a previously defined routerJr)rdefault_filterrrrrescaperrr setdefaultbuildcompilererrorr groupindexrrrrrRuntimeWarningrr_compile)rkrmethodtargetranonskeyspatternr is_staticrmodermask in_filter out_filter re_patterner#flatpat whole_rulemsgrr"s @@raddz Router.addos_ #//55 , ,OCt ,! 9$$T-@d.@dl4.@.F.F+i%x$.G"U*CQJEEGsssDDD99GKK$$$>gnnc9-=>>>Z%6378888 ,29S>>)c{+++$ T -gd#  T.  K " "62 . . .5;TNDK  4 0 0 1 F OHw$677J!'HHx O O O""TTT111#MNN N O          "  2 2 2 2 2 2Gg&&GVW5 V  , , RK cVTN2NqQQQQ1;  V $ Wf_- / /   ' ' 3 3 : :: F F F,/0@0H,I,IA,MDL& ) fsE55FFFcp|j|}gx}|j|<|j}tdt ||D]v}||||z}d|D}dd|D}t j|j}d|D}| ||fwdS)Nrc3$K|] \}}}}|V dSrRrp).0r+r:s r z"Router._compile..s+??$6QA??????r |c3 K|] }d|zV dS)z(^%s$)Nrp)r@r:s rrAz"Router._compile..s'KKw7 2KKKKKKr c g|] \}}}}||f Srprp)r@r+r/r#s r z#Router._compile..s&KKK+BAq&'fg&KKKr ) rr_MAX_GROUPS_PER_PATTERNrangerjoinrr)rr) rkr. all_rules comborules maxgroupsr\somecombinedrs rr-zRouter._compiles$V, 133 T&v.0 q#i..)44 1 1AQq9}_-D??$???HxxKK(KKKKKHz(++1HKKdKKKE   x/ 0 0 0 0  1 1r cj|j|}|std| t|D] \}}|d|z<dfd|D}s|n|dzt zS#t $r"}td|jdzd}~wwxYw) z2 Build an URL by filling the wildcards in a rule. zNo route with that name.rrcZg|]'\}}|r||n|(Srp)pop)r@nfquerys rrEz Router.build..s8MMM6Aqa611UYYq\\???QMMMr rzMissing URL argument: %rrN)rgetr enumeraterHr<KeyErrorr) rk_namer0rSrirurlEs ` rr(z Router.builds,""5)) E!"Kt}t|jj|jzD]j}d|jvrdSt |dd}|r||jvs||vr/||jvst ||jvrO|r|||VkdS)z) Yield all Plugins affecting this route. TrFN)rreversedrrtrurtyper=)rkuniquerrs r all_pluginszRoute.all_plugins#s$(*T\9::  At}$$eee1fe,,D K..$&..8DM!!T!WW %=%=x %VZZ%%%GGGG   r c2|j}|D]z} t|dr|||}n ||}n&#t$r|cYcSwxYw||jurt ||j{|S)Napply)rsrrZrrrzr)rkrsplugins rrzzRoute._make_callback.s=&&(( 8 8F -67++0%||Hd;;HH%vh//H - - -**,,,,,,, -t},,x777s2AA54A5c |j} t|ddr|j}nkt|ddr|j}nRt|ddr@d|jD}d}t t t|||}nn|S)zq Return the callback. If the callback is a decorated function, try to recover the original function. T __wrapped__F__func__ __closure__c3$K|] }|jV dSrR) cell_contents)r@cells rrAz1Route.get_undecorated_callback..Fs%PPt 2PPPPPPr cLt|tpt|dSrX)rzr/rZr[s rrVz0Route.get_undecorated_callback..Gs:a#>#>#X'!ZBXBXr )rsrrrrnextiterfilter)rkrM cells_valuesisfuncs rget_undecorated_callbackzRoute.get_undecorated_callback<s} t]E22 'z511 }}e44 PPt?OPPP XXD !=!=>>EE  r cPt|dS)z Return a list of argument names the callback (most likely) accepts as keyword arguments. If the callback is a decorated function, try to recover the original function before inspection. r)rPrr{s rget_callback_argszRoute.get_callback_argsMs#$7799::1==r c\tdddd|j||S)zp Lookup a config field and return its value, first checking the route.config, then route.app.config.rrz!Route.get_config() is deprecated.zsThe Route.config property already includes values from the application config for missing keys. Access it directly.)rrvrTrkrrs r get_configzRoute.get_configSs> Q7P Q Q Q{sG,,,r c |}d|jd|jd|jdt |ddd S)N< z -> :rtrYr)rr.rrur)rkcbs r__repr__zRoute.__repr__[sL  * * , , KKKBMMM72z:3V3V3V3V  r )NNNrR)rtrurvrrrr|r~rrrzrrrrrpr rrqrqs &&&&0%%_% (((       ">>> ----     r rqc>eZdZdZedZdZeddZdZ dhZ e dZ d Z d Zd Zd Zd ZdZdZdZdZdZd/dZdZdZdZdZdZ d0dZd1dZd2dZd3d Z d4d"Z!d5d$Z"d6d&Z#d'Z$d(Z%d/d)Z&d*Z'd+Z(d,Z)d-Z*d.Z+dS)7Bottlea^ Each Bottle object represents a single, distinct web application and consists of routes, callbacks, plugins, resources and configuration. Instances are callable WSGI applications. :param catchall: If true (default), handle all exceptions. Turn off to let debugging middleware handle exceptions. cZt}|ddt|S)Ncatchallvalidate) ConfigDictmeta_setbool)rcfgs r_global_configzBottle._global_configos&ll ZT222 r c |j|_|jt j|jd|jddi|ddurtddddd|jd<|d durtddd d d|jd <g|_ t|_ g|_ t|_i|_g|_|t'|t)dS) NrvrTFrrz"Bottle(catchall) keyword argument.zbThe 'catchall' setting is now part of the app configuration. Fix: `app.config['catchall'] = False`autojsonz"Bottle(autojson) keyword argument.zeThe 'autojson' setting is now part of the app configuration. Fix: `app.config['json.enable'] = False`z json.disable)rrwrv_add_change_listenerrpartial trigger_hookupdaterTr_mountsResourceManager resourcesroutesrrouter error_handlerrtinstall JSONPluginTemplatePluginrkrOs rrzBottle.__init__ush)7799  ((  d/ : : < < <       ::j ! !U * * B<O P P P',DK # ::j ! !U * * B<K L L L+/DK ' )** hh   Z\\""" ^%%&&&&&r rvr)before_request after_request app_resetrvrc>td|jDS)Nc3K|]}|gfV dSrRrp)r@rs rrAz Bottle._hooks..s&==4T2J======r )r_Bottle__hook_namesr{s r_hooksz Bottle._hookss"==4+<======r c||jvr#|j|d|dS|j||dS)a Attach a callback to a hook. Three hooks are currently implemented: before_request Executed once before each request. The request context is available, but no routing has happened yet. after_request Executed once after each request regardless of its outcome. app_reset Called whenever :meth:`Bottle.reset` is called. rN)_Bottle__hook_reversedrinsertrrs radd_hookzBottle.add_hooksV 4' ' ' K  $ $Q - - - - - K  $ $T * * * * *r c~||jvr1||j|vr$|j||dSdSdS)z Remove a callback from a hook. TN)rremovers r remove_hookzBottle.remove_hooksN 4;  44;t+<#<#< K  $ $T * * *4  #<#.s(III$d%f%%IIIr N)r)rk _Bottle__namerrOs ``rrzBottle.trigger_hooks1IIIII$+f2Eaaa2HIIIIr cfd}|S)ze Return a decorator that attaches a callback to a hook. See :meth:`add_hook` for details.c4||SrR)r)rMrrks r decoratorzBottle.hook..decorators MM$ % % %Kr rp)rkrrs`` rrz Bottle.hooks*      r c d|dD}|stdt|fd}|dd|dd|d |d ||d <|jd d|zfi||ds&|jdd|zfi|dSdS) Ncg|]}||Srprp)r@rs rrEz&Bottle._mount_wsgi..s666!A6A666r r^z+WSGI applications cannot be mounted to "/".c\ ttgdfd }tj|}jrt jj|n|_t S#t wxYw)Nc|r t|tr4|dd}d|D}|_|D]\}}||jjS)Nr?rxchg|]/\}}||ddf0S)r?rxr|rr@kvs rrEzZBottle._mount_wsgi..mountpoint_wrapper..start_response..sQ&@&@&@*01a()!((8*<*<*C*CF*K*K&L&@&@&@r )r`py3kr|rstatus add_headerbodyr)r headerlistexc_inforrrss rstart_responsezFBottle._mount_wsgi..mountpoint_wrapper..start_responses*))@"(x!8!8!?!?!G!G&@&@4>&@&@&@ &BI'133 e dE22227>)r rR)request path_shift HTTPResponserjr itertoolschain)rrrr path_depths @rmountpoint_wrapperz.Bottle._mount_wsgi..mountpoint_wrappers 0"":...!"%% * * * * * *s7?N;;<>GM)/"'4888""J;////""J;////s A.BB+skipTr.r` mountpoint)rr/rsz /%s/<:re:.*>)splitrrr'routerHendswith)rkrroptionssegmentsrrs ` @r _mount_wsgizBottle._mount_wsgis466v||C00666 LJKK K]]  0 0 0 0 0 04 64(((8W---CHHX$6$66BB'BBBs## < DJsSXXh/// ; ;7 ; ; ; ; ; < ') def hello(name): return 'Hello %s' % name The ```` part is a wildcard. See :class:`Router` for syntax details. :param path: Request path or a list of paths to listen to. If no path is specified, it is automatically generated from the signature of the function. :param method: HTTP method (`GET`, `POST`, `PUT`, ...) or a list of methods to listen to. (default: `GET`) :param callback: An optional shortcut to avoid the decorator syntax. ``route(..., callback=func)`` equals ``route(...)(func)`` :param name: The name for this route. (default: None) :param apply: A decorator or plugin or a list of plugins. These are applied to the route callback in addition to installed plugins. :param skip: A list of plugins, plugin classes or names. Matching plugins are not installed to this route. ``True`` skips all. Any additional keyword arguments are stored as route-specific configuration and passed to plugins (see :meth:`Plugin.apply`). Nc 0t|trt|}tpt |D]Q}tD]?}|}t |||f d} |@R|S)N)rrtru)rz basestringloadrK yieldroutesrfrqr) rsrrkrrvr.rrrtrkrus rrzBottle.route..decorators(J// JDNN ?+h*?*? * *$V,,**D::<??ENN5)))) *Or )rrK) rkrr.rsrrrrvrrtrus ``` ` ` @@rrz Bottle.routess@ D>>6D$>45//D>>           '/=yy"""I=r c |j||fi|S)z Equals :meth:`route`. rrkrr.rs rrTz Bottle.gettz$22'222r POSTc |j||fi|S)z8 Equals :meth:`route` with a ``POST`` method parameter. rrs rpostz Bottle.postrr PUTc |j||fi|S)z7 Equals :meth:`route` with a ``PUT`` method parameter. rrs rputz Bottle.putrr DELETEc |j||fi|S)z: Equals :meth:`route` with a ``DELETE`` method parameter. rrs rdeletez Bottle.deleterr PATCHc |j||fi|S)z9 Equals :meth:`route` with a ``PATCH`` method parameter. rrs rpatchz Bottle.patchrr c0fd}|r ||n|S)a Register an output handler for a HTTP error code. Can be used as a decorator or called directly :: def error_handler_500(error): return 'error_handler_500' app.error(code=500, callback=error_handler_500) @app.error(404) def error_handler_404(error): return 'error_handler_404' c~t|trt|}|jt <|SrR)rzrrrr)rscoderks rrzBottle.error..decorators5(J// JDNN,4D s4yy )Or rp)rkr-rsrs`` rr*z Bottle.errors>       '/=yy"""I=r c fttt|tdS)N__ERROR_PAGE_TEMPLATEr)r9template_settings)rtemplateERROR_PAGE_TEMPLATEr)rkress rdefault_error_handlerzBottle.default_error_handlers,8/3$TkJlJlJlmmmnnnr c|dx}|d<tr,|ddd|d<||d<t|t  d} |d|j|\}}||d <||d <||d <|j di|} t|tr| t  |d n#t$r'}|}| t Yd}~nd}~wwxYw#t$r}|}Yd}~t|tr| t  |d nd#t$r'}|}| t Yd}~n8d}~wwxYwd}~wt$rtd ddd|Yt|tr| t  |d #t$r'}|}| t Yd}~d}~wwxYwwxYw#t|tr| t  |d w#t$r&}|}| t Yd}~wd}~wwxYwxYwn#t t"t$f$rt&$r}|jst+}|d||dt1j|d<t5dd||}| t Yd}~nd}~wwxYw|S)Nr]zbottle.raw_pathr?rxignore bottle.appTrz route.handle bottle.routeroute.url_argsrrrzRouteReset exception deprecatedz.Ds)9 : :r zUnsupported response type: %s)&r=rzrrr}r{rHr|rLrrrrrT status_coder4_castrrrZrrjWSGIFileWrapperrr StopIterationr>r?r@rArr4rrrar _closeiterr) rkrDpeekioutfirstrZr*new_iterencoderr<s rrNz Bottle._casts x//-.)*I cE4= ) ) ( s1vw/ 0 0 (a&1+""3''C c7 # # /**X-..C c5 ! ! x//-0XX)*5L c9 % % # IIh   E$$(()-)CEEEHJJC::c?? " c< ( ( ( IIh   ::ch'' ' 3   ,"go55':;C@@@g&& ,gc:.F.F ,&s+++ O99DJJE #T  # " " "::b>> ! ! !   EEEEEE!:{;     O O O= '%c#8%NNEEEEEE O e\ * * 3::e$$ $ u % % 3 w55HH w ' ' 3::GGY_eWd%C%CDDHH1DKK?C::iS1122 2 3  7!(CI66Hs*1H::J? J?$I++$J?&J::J?c x |||}tjdvs |ddkr&t |dr|g}|d}||d=|ttj||S#tttf$rt$r}|j sdt|dd z}tr?|d tt!|d tt#d z }|d ||d dg}|d|t)jt-|gcYd}~Sd}~wwxYw)z The bottle WSGI-interface. )de0r\r_rr;Nz4

Critical error while processing request: %s

r]r^z

Error:

z"

Traceback:

z
r:) Content-Typetext/html; charset=UTF-8z500 INTERNAL SERVER ERROR)rNrFr= _status_coderZrrT_wsgi_status_linerr>r?r@rAr html_escaperrir4rBrCrrr)rkrjrrDrrZrheaderss rwsgiz Bottle.wsgiMs **T\\'2233C$(<<<'(F223((5#))+++{{#455H#-. N855779Lh W W WJ!:{;       = '%H K = =>>?C K%d1gg.... JLL0I0I0I0IKK M " ( ( - - - M " ( ( * * *CDG N6 P P PHH:       sB1B44!F9CF4.F94F9c.|||S)z9 Each instance of :class:'Bottle' is a WSGI application. rb)rkrjrs rrYzBottle.__call__ksyy.111r c:t||S)zA Use this application as default for all module-level shortcuts. ) default_apppushr{s r __enter__zBottle.__enter__os r c8tdSrR)rfrP)rkexc_type exc_value tracebacks r__exit__zBottle.__exit__tsr ct||jvrtd|zt|||dS)Nz.Attribute %s already defined. Plugin conflict?)rrobject __setattr__rkrrs rrpzBottle.__setattr__wsB 4=  !QTX!XYY Y4u-----r rR)NraNNNN)Nra)Nr)Nr!)Nr$)Nr')r*N),rtrurvrrrrrrrrrrrrrrrrrrrrr~rrrrrrrTr r#r&r)r*r4rFrNrbrYrhrmrprpr rrrfs^ !'!'!'H|Hj11HKL&'O>>_>+++  JJJ'<'<'0>0>0>d33333333333333333333>>>>,ooo000dGGGGR<222 .....r rcZeZdZdZdZdZdEdZeddd d Zedd d d Z edd d dZ e dZ e dZ eddd dZdEdZeddd dZddejfdZeddd dZeddd dZeddd dZeddd dZeddd d Zd!Zed"Zedd#d d$Zd%Ze d&Ze d'ZeZ edd(d d)Z!e d*Z"edd+d d,Z#e d-Z$e d.Z%e d/Z&dFd1Z'e d2Z(e d3Z)e d4Z*e d5Z+e d6Z,e d7Z-e d8Z.d9Z/dEd:Z0d;Z1d<Z2d=Z3d>Z4d?Z5d@Z6dAZ7dBZ8dCZ9dDZ:dS)G BaseRequestad A wrapper for WSGI environment dictionaries that adds a lot of convenient access methods and properties. Most of them are read-only. Adding new attributes to a request actually adds them to the environ dictionary (as 'bottle.request.ext.'). This is the recommended way to store and access request-specific data. rjiNc0|in||_||jd<dS)z! Wrap a WSGI environ dictionary. Nzbottle.requestrtr s rrzBaseRequest.__init__s&%_rr' )- %&&&r rjr7T)rc td)z+ Bottle application handling this request. z0This request is not connected to an application. RuntimeErrorr{s rrzBaseRequest.appsMNNNr r8c td)z= The bottle :class:`Route` object that matches this request. )This request is not connected to a route.rwr{s rrzBaseRequest.routeFGGGr r9c td)z' The arguments extracted from the URL. rzrwr{s rr zBaseRequest.url_argsr{r cdd|jdddzS)z The value of ``PATH_INFO`` with exactly one prefixed slash (to fix broken clients and avoid the "empty path" edge case). r^r]r)rjrTrr{s rrzBaseRequest.paths/T\%%k266==cBBBBr c\|jddS)z6 The ``REQUEST_METHOD`` value as an uppercase string. r\ra)rjrTrfr{s rr.zBaseRequest.methods)| 0%88>>@@@r zbottle.request.headersc*t|jS)zf A :class:`WSGIHeaderDict` that provides case-insensitive access to HTTP request headers. )WSGIHeaderDictrjr{s rrazBaseRequest.headerssdl+++r c8|j||S)zA Return the value of a request header, or a given default value. rarTrkrrs r get_headerzBaseRequest.get_header|g...r zbottle.request.cookiesct|jdd}t d|DS)z Cookies parsed into a :class:`FormsDict`. Signed cookies are NOT decoded. Use :meth:`get_cookie` if you expect signed cookies. HTTP_COOKIErc32K|]}|j|jfVdSrR)rr)r@cs rrAz&BaseRequest.cookies..s+;;a!%);;;;;;r )rArjrTvalues FormsDict)rkcookiess rrzBaseRequest.cookiessLt|// rBBCCJJLL;;7;;;;;;r c |j|}|r|r|drd|vrtt|dddd\}}t jt |||}t|tj |r>***# %) \" !  s-AAc|j|krtdd|j|dz}t ||krtdd|S)z[ Read body into a string. Raise HTTPError(413) on requests that are too large. izRequest entity too larger)rrrrIr)rkrrs rrzBaseRequest._get_body_stringPsa   ( (C!;<< <y~~gk** t99w  C!;<< < r cD|jd|jS)al The HTTP request body as a seek-able file-like object. Depending on :attr:`MEMFILE_MAX`, this is either a temporary file or a :class:`io.BytesIO` instance. Accessing this property for the first time reads and replaces the ``wsgi.input`` environ variable. Subsequent accesses just do a `seek(0)` on the file object. r)rrr{s rrzBaseRequest.bodyZs  zr c`d|jddvS)z( True if Chunked transfer encoding was. rHTTP_TRANSFER_ENCODINGrrjrTrr{s rrzBaseRequest.chunkedds3DL,, $b***/%''2 2r zbottle.request.postct}|jdd}t|d\}}|dsDt ||jd}t|D] \}}|||< |Sd|_ |dd}|d }|std t|j ||j |j|j| } | D]i} | js2| rt | jd|| j<;t'| j| j| j| j|| j<j|S) z The values of :attr:`forms` and :attr:`files` combined into a single :class:`FormsDict`. Values are either strings (form values) or instances of :class:`FileUpload`. rrrz multipart/r?FrLrxboundaryz-Invalid content type header, missing boundary) mem_limit memfile_limitrL)rrjrT_parse_http_headerr%rrrrrMultipartError_MultipartParserrrparsefilename is_bufferedrrrrr) rkr  content_typerrrrrLrrrs rrzBaseRequest.POSTms {{|'';; 2< @ @ C g&&|44 ..t/?@@(KKD(.. " " U!S K#++i00;;z** R !PQQ Q!$)Xt7J&d6FLLNN L LD= LT%5%5%7%7 L"' F";";TY",TY ,0M4?#L#LTY r c4|jS)z The full request URI including hostname and scheme. If your app lives behind a reverse proxy or load balancer and you get confusing results, make sure that the ``X-Forwarded-Host`` header is set correctly. )urlpartsgeturlr{s rrYzBaseRequest.urls }##%%%r zbottle.request.urlpartsc|j}|dp|dd}|dp|d}|sC|dd}|d}|r||dkrd nd kr|d |zz }t|j}t ||||d d S)z The :attr:`url` string as an :class:`urlparse.SplitResult` tuple. The tuple contains (scheme, host, path, query_string and fragment), but the fragment is always empty because it is not visible to the server. HTTP_X_FORWARDED_PROTOzwsgi.url_schemehttpHTTP_X_FORWARDED_HOST HTTP_HOST SERVER_NAME 127.0.0.1 SERVER_PORT80443rrr)rjrTurlquotefullpathUrlSplitResult)rkenvrhostportrs rrzBaseRequest.urlpartss lww/003)622 ww.//G377;3G3G #77=+66D77=))D #UCCd " &&dD$0G0GLLLr c\t|j|jdS)z: Request path including :attr:`script_name` (if present). r^)r: script_namerrr{s rrzBaseRequest.fullpaths't')9)9#)>)>???r c8|jddS)zh The raw :attr:`query` part of the URL (everything in between ``?`` and ``#``) as a string. rrrjrTr{s r query_stringzBaseRequest.query_strings|333r cv|jddd}|rd|zdzndS)z The initial portion of the URL's `path` that was removed by a higher level (server or routing middleware) before the application was called. This script path is returned with leading and tailing slashes. r rr^)rjrTr )rkrs rrzBaseRequest.script_namesC l&&}b99??DD *5>s[ 3&&3>r rct|jdd|j|\}}||c|d<|d<dS)z Shift path segments from :attr:`path` to :attr:`script_name` and vice versa. :param shift: The number of path segments to shift. May be negative to change the shift direction. (default: 1) r r^r]N)rrjrTr)rkshiftscriptrs rrzBaseRequest.path_shiftsJ"$,"2"2=#"F"F SXYY 17.]T+...r cTt|jdpdS)z The request body length as an integer. The client is responsible to set this header. Otherwise, the real length of the body is unknown and -1 is returned. In this case, :attr:`body` will be empty. CONTENT_LENGTHr)rrjrTr{s rrzBaseRequest.content_lengths( 4<##$455;<<.s @@@"((**@@@r rc REMOTE_ADDR)rjrTr)rkproxyremotes r remote_routezBaseRequest.remote_routesf    !788 @@@u{{3/?/?@@@@!!-00!)xxr)r c(|j}|r|dndS)zg The client IP as a string. Note that this information can be forged by malicious clients. rN)rrs r remote_addrzBaseRequest.remote_addrs! *uQxxd*r cNt|jS)zD Return a new :class:`Request` with a shallow :attr:`environ` copy. )Requestrjcopyr{s rr"zBaseRequest.copyst|((**+++r c8|j||SrRr)rkrrs rrTzBaseRequest.gets|w///r c|j|SrRrtrkrs r __getitem__zBaseRequest.__getitem__ s|C  r c d||<|j|=dSrrtr%s r __delitem__zBaseRequest.__delitem__ sS \#   r c*t|jSrR)rrjr{s rrJzBaseRequest.__iter__sDL!!!r c*t|jSrR)rrjr{s r__len__zBaseRequest.__len__s4<   r c4|jSrR)rjr1r{s rr1zBaseRequest.keyss|  """r c|jdrtd||j|<d}|dkrd}n |dkrd}n|drd }|D] }|jd |zd !d S) zA Change an environ value and clear all caches that depend on it. zbottle.request.readonlyz$The environ dictionary is read-only.rpr)rrrrr rr)rSrHTTP_)rarzbottle.request.N)rjrTrVr%rP)rkrrtodeletes r __setitem__zBaseRequest.__setitem__s <  5 6 6 CABB B! S ,  KHH N " "*HH ^^G $ $ .-H < C(/Y(?(?H3;;t$$$S H E E E !>>HH?>HCCXC AAXA\)5FFF,,GF, ////\)5FFF<<GF< '+47>    $\)3tDDD  ED \)3tDDD  ED \)4EEEFE\)3tDDD  ED \)2dCCCDC$!!!\6\)2dCCCDC(X22X2 C\)2dCCC  DC D&&X&\)6$GGGMMHGM$@@X@44X4 ??X?>>>>==X= <<X<::X:X  X **X*++X+ ,,,0000!!!   """!!!###<<<&PPPEEE"""EEEEEr rscd|vsd|vsd|vrtd|z|ddS)N  z4Header names must not contain control characters: %rr+-)rtitlereplace)rs r_hkeyrIFsN s{{dckkTS[[ORUUVVV 99;;  sC ( ((r c`t|}d|vsd|vsd|vrtd|z|S)NrCrDrEz4Header value must not contain control characters: %r)rrrs r_hvalrLLs@ %LLE u}} ORWWXXX Lr c(eZdZddZdZdZdZdS)HeaderPropertyNrcz||c|_|_||c|_|_d|z|_dS)NzCurrent value of the %r header.)rrreaderwriterrGr)rkrrPrQrs rrzHeaderProperty.__init__Ts:"& 4<#)6  T[84::<<G r c||S||j|j}|jr||n|SrR)rrrrP)rkrr+rs rrzHeaderProperty.__get__Ys@ ;t ty$,77%)[;t{{5!!!e;r cR|jr||n|||j<dSrR)rQrrs rrzHeaderProperty.__set__^s)/3{EU+++DIr c||j=dSrRrrs rrzHeaderProperty.__delete__as  NNNr )NNr)rtrurvrrrrrpr rrNrNSs\HHHH <<< FFFr rNceZdZdZdZdZededdZd*d Zd+d Z d Z d Z e d Z e dZdZdZe eeddZ[[e dZdZdZdZdZd+dZdZdZdZdZe dZedZeded Z ed!d"d#$Z!e d,d&Z"de#j$fd'Z%d(Z&d)Z'dS)- BaseResponsea Storage class for a response body as well as headers and cookies. This class does support dict-like case-insensitive item-access to headers, but is NOT a dict. Most notably, iterating over a response yields parts of the body and not the headers. r])r\rH)rdzContent-EncodingzContent-LanguagerH Content-Ranger\z Content-Md5 Last-Modified)rZr[rNc Fd|_i|_||_|p|j|_|rGt |t r|}|D]\}}||||r0|D]\}}|||dSdS)a Create a new response object. :param body: The response body as one of the supported types. :param status: Either an HTTP status code (e.g. 200) or a status line including the reason phrase (e.g. '200 OK'). :param headers: A dictionary or a list of name-value pairs. Additional keyword arguments are added to the list of headers. Underscores in the header name are replaced with dashes. N) _cookies_headersrdefault_statusrrzritemsr)rkrrra more_headersrrs rrzBaseResponse.__init__ys   3 3  -'4(( *!--//& - - ee,,,,  -+1133 - - ee,,,, - - - -r c|pt}t|tsJ|}|j|_td|jD|_|jrYtx}|_|jD]*\}}|j||<|| |+|S)z Returns a copy of self. c34K|]\}}||ddfVdSrRrprs rrAz$BaseResponse.copy..s2KK6Aqa111YKKKKKKr ) rV issubclassrrr\r^r[rArr)rkrr"rrrs rr"zBaseResponse.copys!\#|,,,,,suuk KKT]5H5H5J5JKKKKK = %&2nn 4Gdm}**,, % %!W  !!!$$$$ r c*t|jSrR)rrr{s rrJzBaseResponse.__iter__DIr cft|jdr|jdSdS)Nr)rZrrr{s rrzBaseResponse.closes8 49g & &  IOO       r c|jS)z; The HTTP status line as a string (e.g. ``404 Not Found``). _status_liner{s r status_linezBaseResponse.status_line   r c|jS)z/ The HTTP status code as an integer (e.g. 404).)r^r{s rrMzBaseResponse.status_coderjr ct|tr|t|}}njd|vrWd|vsd|vsd|vrt d|}t|d}nt dd|cxkrd ksnt d ||_t|pd |z|_ dS) NrrCrDrEz+Status line must not include control chars.rz+String status line without a reason phrase.rXizStatus code out of range.z %d Unknown) rzr_HTTP_STATUS_LINESrTrr rr^rrh)rkrr-s r _set_statuszBaseResponse._set_statuss fc " " L!#5#9#9&#A#A&DD F]]v~~46>> !NOOO\\^^Fv||~~a())DDJKK Kd!!!!c!!!!899 9  ?<$+>@@r c|jSrRrgr{s r _get_statuszBaseResponse._get_statuss   r aQ A writeable property to change the HTTP response status. It accepts either a numeric code (100-999) or a string with a custom reason phrase (e.g. "404 Brain not found"). Both :data:`status_line` and :data:`status_code` are updated accordingly. The return value is always a status string. c:t}|j|_|S)zl An instance of :class:`HeaderDict`, a case-insensitive dict-like view on the response headers. ) HeaderDictr\r)rkhdicts rrazBaseResponse.headerss ]  r c.t||jvSrR)rIr\r:s r __contains__zBaseResponse.__contains__sT{{dm++r c0|jt|=dSrRr\rIr:s rr(zBaseResponse.__delitem__s M%++ & & &r cB|jt|dSNrrwr:s rr&zBaseResponse.__getitem__s}U4[[)"--r cPt|g|jt|<dSrRrLr\rIrqs rr0zBaseResponse.__setitem__s"&+Ell^ eDkk"""r c`|jt||gdS)z| Return the value of a previously defined header. If there is no header with that name, return a default value. r)r\rTrIrs rrzBaseResponse.get_headers)}  twi88<.s'EEEQQqT-D-Dq-D-D-Dr c&g|]\}}|D]}||fSrprp)r@rvalsvals rrEz+BaseResponse.headerlist..s-HHH t4HHCs HHHHr z Set-Cookiechg|]/\}}||ddf0S)rxr?rrs rrEz+BaseResponse.headerlist..s;LLLfq!Aqxx''..x889LLLr ) rr\r^rdefault_content_typer^rr[rrL OutputStringr)rkrDrarrs @rrzBaseResponse.headerlistst}**,,--  . . NNNT-F,GH I I I   0 0 0*4+<=KEEEE'EEEG HHHHHH = D]))++ D D L%0@0@*A*ABCCCC  MLLLLLC r r\rHrrPrExpirescPtjt|tSrR)r1 fromtimestamp parse_dateror[s rrVzBaseResponse.s/ 1 sCCr c t|SrR) http_dater[s rrVzBaseResponse.s 1r )rPrQUTF-8cd|jvrK|jddddS|S)zJ Return the charset specified in the content-type header (default: utf8). charset=rrr)rrr )rkrs rrLzBaseResponse.charsetsR * * *$**:66r:@@EEaHNNPP Pr c 4|jst|_tdkr tjdd|rt |tstddddtj tj ||gd}tj tjt||| }t#td |ztd z|z}n$t |tst%d t'|t'|zd krt)d||j|<|D]\}}|dvr,d}t |t,r|j|jdzdzz}|dkrt3|}|dvr+d|pd}}|dvrt7d|dvr|s||j||<dS)a Create a new cookie or replace an old one. If the `secret` parameter is set, create a `Signed Cookie` (described below). :param name: the name of the cookie. :param value: the value of the cookie. :param secret: a signature key required for signed cookies. Additionally, this method accepts all RFC 2109 attributes that are supported by :class:`cookie.Morsel`, including: :param maxage: maximum age in seconds. (default: None) :param expires: a datetime object or UNIX timestamp. (default: None) :param domain: the domain that is allowed to read the cookie. (default: current domain) :param path: limits the cookie to a given path (default: current path) :param secure: limit the cookie to HTTPS connections (default: off). :param httponly: prevents client-side javascript to read this cookie (default: off, requires Python 2.6 or newer). :param samesite: Control or disable third-party use for this cookie. Possible values: `lax`, `strict` or `none` (default). If neither `expires` nor `maxage` is set (default), the cookie will expire at the end of the browser session (as soon as the browser window is closed). Signed cookies may store any pickle-able object and are cryptographically signed to prevent manipulation. Keep in mind that cookies are limited to 4kb in most browsers. Warning: Pickle is a potentially dangerous format. If an attacker gains access to the secret key, he could forge cookies that execute code on server side if unpickled. Using pickle is discouraged and support for it will be removed in later versions of bottle. Warning: Signed cookies are not encrypted (the client can still see the content) and not copy-protected (the client can restore an old cookie). The main intention is to make pickling and unpickling save, not to store secret information at client side. )rJrsamesiteSameSiterrz9Pickling of arbitrary objects into cookies is deprecated.z:Only store strings in cookies. JSON strings are fine, too.rrrrz+Secret key required for non-string cookies.iz#Content does not fit into a cookie.)max_agemaxagezmax-ageiexpires) same_siternone)laxrrzInvalid value for SameSite)securehttponlyN)r[rApyrB _reservedr'rzrrrrrr7rrrrrTrrrr^r2secondsdaysrrrC) rkrrrrrencodedrrs r set_cookiezBaseResponse.set_cookies?P} +(NNDM  >>   ' ' J ? ? ?  KeZ00 ;Q*,:;;;&v|T5M2'F'FGGG"48CKK6?$A$A$AAGKKC#c((S.3s883g=>>EEE:.. KIJJ J t99s5zz !D ( (BCC C# d!--// - -JC+++eY//C!MEJOd,BBEi!%((///'%/6)@)@)B)BU 999%&BCCC,,,U,',DM$  $ $ - -r c 8d|d<d|d<|j|dfi|dS)zq Delete a cookie. Be sure to use the same `domain` and `path` settings as used to create the cookie. rrrrrN)r)rkrrOs r delete_cookiezBaseResponse.delete_cookieis:yyR**6*****r cd}|jD]4\}}||d|dz }5|S)Nrr2rC)rrGr )rkrDrrs rrzBaseResponse.__repr__psJ? > >KD% u{{}}}}= =CC r rNNrR)r)(rtrurvrr]r frozensetrrr"rJrr>rirMrnrprrarur(r&r0rr~rrr_rrNrrrrrLr?r@rrrrpr rrVrVesN5 Y9 : : Y233K----0    !!X!!!X! A A A!!!X[$ ())F [ X,,,'''...444==== 444 GGG !!! X"">.11L#^$4S"MMMNnCC%%'''G X .2W^O-O-O-O-b+++r rVcltjfd}fd}fd}t|||dS)NcN jS#t$rtdwxYw)Nz Request context not initialized.)r6rrxr+lss rfgetz_local_property..fgetzs> C6M C C CABB B Cs $c|_dSrRr6)r+rrs rfsetz_local_property..fsetsr c `dSrRrrs rfdelz_local_property..fdels FFFr zThread-local property) threadinglocalr>)rrrrs @r_local_propertyrwsw   BCCCCC  D$&= > >>r c4eZdZdZejZeZdS) LocalRequestaT A thread-local subclass of :class:`BaseRequest` with a different set of attributes for each thread. There is usually only one global instance of this class (:data:`request`). If accessed during a request/response cycle, this instance always refers to the *current* request (even on a multithreaded server). N) rtrurvrrsrr<rrjrpr rrrs/66  DoGGGr rceZdZdZejZeZeZ eZ eZ eZ dS) LocalResponsea+ A thread-local subclass of :class:`BaseResponse` with a different set of attributes for each thread. There is usually only one global instance of this class (:data:`response`). Its attributes are used to build the HTTP response at the end of the request/response cycle. N) rtrurvrrVrr<rrhr^r[r\rrpr rrrsc  D"?$$L"?$$L  H  H ?  DDDr rc*eZdZdZdfd ZdZxZS)raf A subclass of :class:`Response` that can be raised or returned from request handlers to short-curcuit request processing and override changes made to the global :data:`request` object. This bypasses error handlers, even if the status code indicates an error. Return or raise :class:`HTTPError` to trigger error handlers. rNc Ntt|j|||fi|dSrR)superrr)rkrrrar_r3s rrzHTTPResponse.__init__s2*lD!!*4QQLQQQQQr c~|j|_|j|_|j|_|j|_|j|_dS)zJ Copy the state of this response to a different :class:`Response` object. N)r^rhr\r[r)rkothers rrzHTTPResponse.applys7!.!.Y r r)rtrurvrrr __classcell__r3s@rrrs\RRRRRRr rc0eZdZdZdZ dfd ZxZS)rzC A subclass of :class:`HTTPResponse` that triggers error handlers. r*Nc h||_||_tt|j||fi|dSrR) exceptionrlrrr)rkrrrrlr_r3s rrzHTTPError.__init__s@ #"'i'fEE EEEEEr )NNNN)rtrurvrr]rrrs@rrrs`MMN FFFFFFFFFFr rceZdZdS) PluginErrorNrrpr rrrDr rc,eZdZdZdZefdZdZdZdS)rrr9c||_dSrR) json_dumps)rkrs rrzJSONPlugin.__init__s $r c|jddtd|jddtd|jddtd |jd dd dS) Nz json.enableTz.Enable or disable automatic dict->json filter.)rrr z json.asciiFz*Use only 7-bit ASCII characters in output.z json.indentz*Add whitespace to make json more readable.zjson.dump_funcz]If defined, use this function to transform dict into json. The other options no longer apply.r)rv_definerrkrs rrzJSONPlugin.setups =$O  Q Q Q <K  M M M =$K  M M M +T )  * * * * *r cj|j|jsStjfd}|S)Nc@ |i|}n#t$r }|}Yd}~nd}~wwxYwt|tr|}dt_|St|tr6t|jtr|j|_d|_|S)Nr)rrzrr=rr)r_rrvresp json_responsersr7s rrz!JSONPlugin.apply..wrappers Xq'B''    "d## 5 %b (:%$$B -- 5*RWd2K2K 5%.."4Is "")rrwraps)rkrsrrr7s ` @rrzJSONPlugin.applysQ/x  " "      # " "r N) rtrurvrapirrrrrpr rrrsS D C",%%%% * * *r rc&eZdZdZdZdZdZdZdS)ra This plugin applies the :func:`view` decorator to all routes with a `template` config parameter. If the parameter is a tuple, the second element must be a dict with additional options (e.g. `template_engine`) or default variables for the template. r1r9c||_dSrR)tplrs rrzTemplatePlugin.setups r c6|jd}t|ttfr5t |dkr"t |dfi|d|St|trt ||S|S)Nr1r9rr)rvrTrzrrrviewr)rkrsrrs rrzTemplatePlugin.applys| ++ dUDM * * s4yyA~~+4Q++47++H55 5 c " " 4::h'' 'Or N)rtrurvrrrrrrpr rrrsH33 D Cr rc6eZdZdZddZddZdZdZdZdS) _ImportRedirectc||_||_tj|t ||_|jjtgg|dtj |dS)z@ Create a virtual package that redirects imports (see PEP 302). )__file____path____all__ __loader__N) rimpmaskrmodulesr'rbmodulerrr meta_pathr)rkrrs rrz_ImportRedirect.__init__s  k,,T:d3C3CDD  ##  % %    T"""""r Ncd|vrdS|ddd|jkrdSddlm}|||S)N.rr)spec_from_loader)rsplitrimportlib.utilr)rkfullnamerr/rs r find_specz_ImportRedirect.find_spec sZ h   ??3 " "1 % 2 2FF333333$///r c`d|vrdS|ddd|jkrdS|S)Nrrr)rr)rkrrs r find_modulez_ImportRedirect.find_module&s: h   ??3 " "1 % 2 2FF r c6||jSrR) load_moduler)rkrNs r create_modulez_ImportRedirect.create_module+s ***r cdSrRrp)rkrs r exec_modulez_ImportRedirect.exec_module. r c,|tjvrtj|S|ddd}|j|z}t |tj|x}tj|<t |j||||_|S)Nrr)rrrr __import__rrr)rkrmodnamerealnamers rrz_ImportRedirect.load_module1s s{ " "3;x+@$@//#q))!,<')8),X)>>X& Wf---  r rR) rtrurvrrrrrrrpr rrrsx # # #0000  +++   r rceZdZdZdZdZdZdZdZdZ dZ d Z e rd Z d Zd Ze Ze ZeZeZnd Z dZdZdZdZdZdZddZdZdZdZeZeZdS) MultiDictz This dict stores multiple values per key, but behaves exactly like a normal dict in that it returns only the newest value for any given key. There are special methods available to access the full list of values. cztdt|i|D|_dS)Nc3&K|] \}}||gfV dSrRrprs rrAz%MultiDict.__init__..Gs,FFfq!!aSFFFFFFr rr^)rkr_rs rrzMultiDict.__init__Fs:FFa 1 0C0C0E0EFFFFF r c*t|jSrR)rrr{s rr+zMultiDict.__len__Is49~~r c*t|jSrR)rrr{s rrJzMultiDict.__iter__Lrdr c||jvSrRrr%s rruzMultiDict.__contains__Osdir c|j|=dSrRrr%s rr(zMultiDict.__delitem__Rs IcNNNr c(|j|dSryrr%s rr&zMultiDict.__getitem__Usy~b!!r c2|||dSrR)rrkrrs rr0zMultiDict.__setitem__Xs Cr c4|jSrR)rr1r{s rr1zMultiDict.keys[sy~~r cHd|jDS)Nc3&K|] }|dV dSrNrpr@rs rrAz#MultiDict.values..as&66aAbE666666r rrr{s rrzMultiDict.values`$6649#3#3#5#5666 6r cHd|jDS)Nc30K|]\}}||dfVdSrrprs rrAz"MultiDict.items..ds.==41aQ"J======r rr{s rr^zMultiDict.itemsc"==49??+<+<=== =r cHd|jDS)Nc3.K|]\}}|D]}||fV dSrRrpr@rvlrs rrAz%MultiDict.allitems..gs7FFuq"2FFaQFFFFFFFFr rr{s rrzMultiDict.allitemsfs"FF (9(9FFF Fr cHd|jDS)Ncg|] }|d Srrprs rrEz$MultiDict.values..qs666aAbE666r rr{s rrzMultiDict.valuesprr cHd|jDS)Nc(g|]\}}||dfSrrprs rrEz#MultiDict.items..ts$===41aQ"J===r rr{s rr^zMultiDict.itemssrr c4|jSrR)riterkeysr{s rrzMultiDict.iterkeysvs9%%'' 'r cHd|jDS)Nc3&K|] }|dV dSrrprs rrAz'MultiDict.itervalues..zs&::aAbE::::::r )r itervaluesr{s rr"zMultiDict.itervaluesys$::49#7#7#9#9::: :r cHd|jDS)Nc30K|]\}}||dfVdSrrprs rrAz&MultiDict.iteritems..}s.AA41aQ"JAAAAAAr r iteritemsr{s rr&zMultiDict.iteritems|s$AA49+>+>+@+@AAA Ar cHd|jDS)Nc3.K|]\}}|D]}||fV dSrRrprs rrAz)MultiDict.iterallitems..s7JJuq"rJJ!QFJJJJJJJr r%r{s r iterallitemszMultiDict.iterallitems$JJ (;(;(=(=JJJ Jr cHd|jDS)Nc&g|]\}}|D]}||fSrprprs rrEz&MultiDict.allitems..s-JJJuq"rJJ!QFJJJJr r%r{s rrzMultiDict.allitemsr*r Nrcl |j||}|r ||n|S#t$rYnwxYw|S)a Return the most recent value for a key. :param default: The default value to be returned if the key is not present or the type conversion fails. :param index: An index for the list of available values. :param type: If defined, this callable is used to cast the value into a specific type. Exception are suppressed and result in the default value to be returned. )rrA)rkrrindexrrs rrTz MultiDict.getsS )C.'C $-44999# -    D s !$ 11cb|j|g|dS)z5 Add a new value to the list of values for this key. N)rr'rr s rrzMultiDict.appends. S"%%,,U33333r c|g|j|<dS)z1 Replace the list of values with a single value. Nrr s rrHzMultiDict.replaces #r c:|j|pgS)z5 Return a (possibly empty) list of values for a key. )rrTr%s rgetallzMultiDict.getallsy}}S!!'R'r )NrN)rtrurvrrr+rJrur(r&r0r1rrr^rrr"r&r)rTrrHr2getonegetlistrpr rrr@s GGG   """       %K 7 7 7 > > > G G G    7 7 7 > > > ( ( ( ; ; ; B B B K K K K K K"444!!!((( FGGGr rcVeZdZdZdZdZd dZd dZd dZe ffd Z xZ S) ra This :class:`MultiDict` subclass is used to store request form data. Additionally to the normal dict-like item access methods (which return unmodified data as native strings), this container also supports attribute-like access to its values. Attributes are automatically de- or recoded to match :attr:`input_encoding` (default: 'utf8'). Missing attributes default to an empty string. rxTNct|tr6|jr/|d|p|jSt|t r||p|jS|S)Nr?)rzr{rr|rinput_encodingr})rkrUr@s r_fixzFormsDict._fixsw a ! ! d&9 88H%%,,X-L9LMM M 5 ! ! 88H;(;<< <Hr ct}|p|jx}|_d|_|D]C\}}|||||||D|S)z Returns a copy with all keys and values de- or recoded to match :attr:`input_encoding`. Some libraries (e.g. WTForms) want a unicode dictionary. F)rr7rrrr8)rkr@r"r~rrs rrzFormsDict.decodes{{$,$C0CCd!#--// D DJC KK #s++TYYuc-B-B C C C C r cn ||||S#ttf$r|cYSwxYw)z7 Return the value as a unicode string, or the default. )r8 UnicodeErrorrV)rkrrr@s r getunicodezFormsDict.getunicodesH 99T$Z22 2h'   NNN s 44c|dr=|dr(tt||S|||S)N__r)r%rrrr7r<)rkrrr3s rr7zFormsDict.__getattr__s^ ??4  >>r cFd|DD]}||jvr|j|=dS)Nc34K|]}t|VdSrR)rI)r@rQs rrAz$HeaderDict.filter..s(--!U1XX------r r)rknamesrs rrzHeaderDict.filters@--u--- $ $Dty  IdO $ $r ry)rtrurvrrrur(r&r0rrHr2rTrrpr rrrrrs;;***'''""")))///BBB//////????$$$$$r rrcTeZdZdZdZdZdZddZdZdZ d Z d Z d Z d Z d ZdS)ra  This dict-like class wraps a WSGI environ dict and provides convenient access to HTTP_* fields. Keys and values are native strings (2.x bytes or 3.x unicode) and keys are case-insensitive. If the WSGI environment contains non-native string values, these are de- or encoded using a lossless 'latin1' character set. The API will remain stable even on changes to the relevant PEPs. Currently PEP 333, 444 and 3333 are supported. (PEP 444 is the only one that uses non-native strings.) )rrc||_dSrRrtr s rrzWSGIHeaderDict.__init__ s  r cr|dd}||jvr|Sd|zS)z6 Translate header field name to CGI/WSGI environ key. rFr+r.)rHrfcgikeysr%s r_ekeyzWSGIHeaderDict._ekey s=kk#s##))++ $,  J}r Nc^|j|||S)z: Return the header value as is (may be bytes or unicode). )rjrTrUrs rrawzWSGIHeaderDict.raw s$| 3999r c|j||}trSt|tr)|dd}n|d}|S)Nr?rx)rjrUrrzr{r|r)rkrrs rr&zWSGIHeaderDict.__getitem__ sil4::c??+  )#w'' )jj**11&99jj(( r c0td|jzNz%s is read-only.rr3r s rr0zWSGIHeaderDict.__setitem__ *T^;<<.. s   a   r rpr{s rr1zWSGIHeaderDict.keys- s  4    r cDt|SrR)rr1r{s rr+zWSGIHeaderDict.__len__0 s499;;r c:|||jvSrR)rUrjr%s rruzWSGIHeaderDict.__contains__3 szz#$,..r rR)rtrurvrrTrrUrWr&r0r(rJr1r+rurpr rrrs  1G::::======!!!!!!   /////r rceZdZdZdZdZddZdZddZd Z dd Z d Z d Z dZ dZdZdZddZdZdZeeefdZdZdZd S)ra  A dict-like configuration storage with additional support for namespaces, validators, meta-data and overlays. This dict-like class is heavily optimized for read access. Read-only methods and item access should be as fast as a native dict. )_meta_change_listener _overlays _virtual_keys_source __weakref__cdi|_g|_g|_d|_t |_dSrR)rfrgrhrjrrir{s rrzConfigDict.__init__B s1 "  UUr Tct|fdtD}|r||n|||S)aoLoad values from a Python module. Import a python module by name and add all upper-case module-level variables to this config dict. :param name: Module name to import and load. :param squash: If true (default), nested dicts are assumed to represent namespaces and flattened (see :meth:`load_dict`). cZi|]'}||t|(Srp)isupperr)r@r config_objs r z*ConfigDict.load_module..W sA<<<S[[]]>> c = ConfigDict() >>> c.load_dict({'some': {'namespace': {'key': 'value'} } }) {'some.namespace.key': 'value'} r) namespaceKey has type %r (not a string))r^rzrr rrxrr)rksourcerrrnskeys rrxzConfigDict.load_dict~ s!,,.. N NJC#z** N"S3.55c::eT**(NN5EN::::"'DKK @499 LMMM r cd}|rCt|dtr(|dddz}|dd}t|i|D] \}}||||z<dS)z If the first parameter is a string, all keys are prefixed with this namespace. Apart from that it works just as the usual dict.update(). >>> c = ConfigDict() >>> c.update('some.namespace', key='value') rrrrN)rzrr rr^)rkr_rrrrs rrzConfigDict.update s  AaD*-- qTZZ__s*F!""A.R....00 ' 'JC!&D#   ' 'r Nc$||vr|||<||SrRrpr s rr'zConfigDict.setdefault s d??DICyr ct|tstdt|z|j|||dd|}||vr |||urdS|||t |||| D]}| ||dS)Nrrc|SrRrpr[s rrVz(ConfigDict.__setitem__.. sqr ) rzrrrridiscardmeta_get _on_changerr0_iter_overlays _set_virtualrkrroverlays rr0zConfigDict.__setitem__ s#z** Jt|||||j|dS||dt|||D]}||dS)Nz"Virtual keys cannot be deleted: %s) rVrirjrr(rrr_delete_virtualrkrrs rr(zConfigDict.__delitem__ s d??3--  $$ $ $?#EFF F < -C4<//   T3 ' ' '   c4<#4 5 5 5 5 5 OOC & & &   T3 ' ' '..00 - -'',,,, - -r c2||vr ||jvrdS|j|||vr |||ur|||t||||D]}|||dS)z) Recursively set or update virtual keys. N)rir=rrr0rrrs rrzConfigDict._set_virtual s $;;3d&888 F s### $;;49E11 OOC ' ' ' sE*****,, - -G  e , , , , - -r c||jvrdS||vr||dt|||j||D]}||dS)z# Recursively delete virtual entry. N)rirrr(rrrrs rrzConfigDict._delete_virtual s d( ( ( F $;; OOC & & & s### ""3'''**,, ) )G  # #C ( ( ( ( ) )r c:|jD]}||||rdSdSNT)rg)rkrrrs rrzConfigDict._on_change s@'  Br$U## tt   r c:|j||SrR)rgrrs rrzConfigDict._add_change_listener s $$T*** r c`|j|i||S)z- Return the value of a meta field for a key. )rfrT)rkr metafieldrs rrzConfigDict.meta_get s(z~~c2&&**9g>>>r cB||j|i|<dS)z Set the meta field for a key to a new value. Meta-fields are shared between all members of an overlay tree. N)rfr')rkrrrs rrzConfigDict.meta_set s& 5: c2&&y111r c\|j|iS)z; Return an iterable of meta field names defined for a key. )rfrTr1r%s r meta_listzConfigDict.meta_list s$z~~c2&&++---r c|tur||||tur||d||tur||d|dSdS)zB (Unstable) Shortcut for plugins to define own config parameters. r rN)_UNSETr'r)rkrrr rs rrzConfigDict._define sq & OOC ) ) ) v   MM#vt , , , 6 ! ! MM#z8 4 4 4 4 4 " !r c#>K|jD]}|}||VdSrR)rh)rkrefrs rrzConfigDict._iter_overlays s<>  CceeG"   r cd|jD|jdd<t}|j|_||_|jt j||D]}|||||S)a (Unstable) Create a new overlay that acts like a chained map: Values missing in the overlay are copied from the source map. Both maps share the same meta entries. Entries that were copied from the source are called 'virtual'. You can not delete virtual keys, but overwrite them, which turns them into non-virtual entries. Setting keys on an overlay never affects its source, but may affect any number of child overlays. Other than collections.ChainMap or most other implementations, this approach does not resolve missing keys on demand, but instead actively copies all values from the source to the overlay and keeps track of virtual and non-virtual keys internally. This removes any lookup-overhead. Read-access is as fast as a build-in dict for both virtual and non-virtual keys. Changes are propagated recursively and depth-first. A failing on-change handler in an overlay stops the propagation of virtual values and may result in an partly updated tree. Take extra care here and make sure that on-change handlers never fail. Used by Route.config c&g|]}| |SrRrp)r@rs rrEz,ConfigDict._make_overlay.. s#PPPSccee>OS>O>O>Or N)rhrrfrjrweakrefrr)rkrrs rrwzConfigDict._make_overlay s2QPDNPPPqqq,,   gk'22333 1 1C  d3i 0 0 0 0r TrrR)rtrurvrr=rrr~rxrr'r0r(rrrrrrrrrrrwrpr rrr8 sVfI###(<& ' ' ' --- --- - - - ) ) ) ????:::...$*5555 !!!!!r rc:eZdZdZdZddZeZedZdS)AppStackz> A stack-like list. Calling it returns the head of the stack. c|jS)z) Return the current default application. r?r{s rrYzAppStack.__call__, |r Ncvt|tst}|||S)z1 Add a new :class:`Bottle` instance to the stack )rzrr)rkrs rrgz AppStack.push0 s4%(( HHE E r c\ |dS#t$r|cYSwxYwry) IndexErrorrgr{s rrzAppStack.default8 s? 8O   99;;    s  ++rR) rtrurvrrYrgnew_appr>rrpr rrr) s]HH G Xr rceZdZddZdZdS)rOc ||c|_|_dD]1}t||rt||t ||2dS)N)filenorrI readlinestellr)fp buffer_sizerZrr)rkrrrs rrzWSGIFileWrapper.__init__A s\$& !!J I IDr4  H'$gb$6G6G"H"H"H I Ir c#fK|j|j}}||}|r|V||}|dSdSrR)rrI)rkrrIrs rrJzWSGIFileWrapper.__iter__F s]%tydtDzz JJJ4::D     r Nr)rtrurvrrJrpr rrOrO@ s;IIII r rOc&eZdZdZddZdZdZdS)rQz This only exists to be able to attach a .close method to iterators that do not support attribute assignment (most of itertools). Nc<||_t||_dSrR)iteratorrKclose_callbacks)rkrrs rrz_closeiter.__init__R s  'r c*t|jSrR)rrr{s rrJz_closeiter.__iter__V sDM"""r c.|jD] }| dSrR)rrs rrz_closeiter.closeY s+(  D DFFFF  r rR)rtrurvrrrJrrpr rrQrQN sREE////###r rQc<eZdZdZdedfdZd dZdZd Zd d ZdS)raf This class manages a list of search paths and helps to find and open application-bound resources (files). :param base: default value for :meth:`add_path` calls. :param opener: callable used to open resources. :param cachemode: controls which lookups are cached. One of 'all', 'found' or 'none'. ./allcL||_||_||_g|_i|_dSrR)openerbase cachemodercache)rkrrrs rrzResourceManager.__init__h s+  "  r NFctjtj|p|j}tjtj|tj|}|tjz }||jvr|j||r3tj|stj |||j |n|j |||j tj|S)a Add a new path to the list of search paths. Return False if the path does not exist. :param path: The new search path. Relative paths are turned into an absolute and normalized form. If the path looks like a file (not ending in `/`), the filename is stripped off. :param base: Path used to absolutize relative search paths. Defaults to :attr:`base` which defaults to ``os.getcwd()``. :param index: Position within the list of search paths. Defaults to last index (appends to the list). The `base` parameter makes it easy to reference files installed along with a python module or package:: res.add_path('./resources/', __file__) )osrabspathdirnamerrHseprisdirmakedirsrrrclearexists)rkrrr.creates radd_pathzResourceManager.add_pathr s"wrwt/@tyAABBwrw||D"'//$2G2GHHII  49   I  T " " "  "'----  K    = I  T " " " " I  UD ) ) ) w~~d###r c#|K|jdd}|r|}tj|s6tj|D][}tj||}tj|r||W|V\|dSdS)z: Iterate over all existing files in all registered paths. N)rrPrrlistdirrHr)rksearchrrfulls rrJzResourceManager.__iter__ s111 !::<>%((!~)999+0 4( LLL!~&&#' 4 z$r rcz||}|std|z|j|g|Rd|i|S)z= Find a resource and return a file object, or raise IOError. zResource %r not found.r4)rrr)rkrr4rrOfnames ropenzResourceManager.open sS D!!DG$ ! ! !   ">>>>>>r rcveZdZd dZedZededZd dZe dZ dd Z dd Z dS)rNcx||_||_||_|rt|n t|_dS)zA Wrapper for a single file uploaded via ``multipart/form-data``. N)rr raw_filenamerrra)rkfileobjrrras rrzFileUpload.__init__ s;  $.5Gz'***:<< r r\rHrrc8|j||S)z9 Return the value of a header within the multipart part. rrs rrzFileUpload.get_header rr c|j}t|ts|dd}t d|}|ddd}t j| dt jj }tj dd| }tj dd | d }|d d pd S)a Name of the file on the client file system, but normalized to ensure file system compatibility. An empty filename is returned as 'empty'. Only ASCII letters, digits, dashes, underscores and dots are allowed in the final filename. Accents are removed, if possible. Whitespace is replaced by a single dash. Leading or tailing dots or dashes are removed. The filename is limited to 255 characters. rxr6NFKDASCII\z[^a-zA-Z0-9-_.\s]rz[-\s]+rFz.-Nempty)rrzr{rr6r|rrbasenamerHrrrr )rkrs rrzFileUpload.filename s!%)) 3LL22E&%(( Wh//66w??  tRW[!A!ABB+R77==??y#u--33D99TcT{%g%r rc|jj|j|j}}} ||}|sn |||j|dSrR)rrIrBrr)rkr chunk_sizerIrBrbufs r _copy_filezFileUpload._copy_file sk"inbh 8H8HVe $z""C  E#JJJ  vr Fct|trtj|r%tj||j}|s.tj|rtdt|d5}| ||ddddS#1swxYwYdS| ||dS)a Save file to disk or copy its content to an open file(-like) object. If *destination* is a directory, :attr:`filename` is added to the path. Existing files are not overwritten by default (IOError). :param destination: File path, directory or file(-like) object. :param overwrite: If True, replace existing files. (default: False) :param chunk_size: Bytes to read at a time. (default: 64kb) z File exists.wbN) rzrrrrrHrrrrr)rk destination overwriterrs rsavezFileUpload.save s k: . . 5w}}[)) G gll; FF  . !>CCrRr)Fr) rtrurvrrNrrrrrrrrrpr rrr s H H H H">.11L#^$4S"MMMN////&&_&&555555r rr*Unknown Error.c"t||)z+ Aborts execution and causes a HTTP error. )r)r-rs rabortr s D$  r c|s"tddkrdnd}tt}||_d|_|dttj ||)zd Aborts execution and causes a 303 or 302 redirect, depending on the HTTP protocol version. SERVER_PROTOCOLzHTTP/1.1i/i.)rrLocation) rrTr=r"rrrr~r:rY)rYr-r3s rredirectr ss Lkk"344 BBss --L- ) )CCJCHNN:ww{C88999 Ir c#K|||dkrE|t||}|sdS|t|z}|V|dkCdSdS)z& Yield chunks from a range in a file. rN)rrIrr)rrlimitrrs r _rangeiterr srGGFOOO !))wws5'**++  E T !))))))r TFrctjtj|d}tjtj||d}|r|ni}t jj}| |stddStj |rtj |stddStj |tjstddS|dur@t|t r|n|}t#j|\}} | d krd }n| rd | z}|r"|r d |vr|d ddks|dkr|d|zz }|r||d<|durtj|}|r|dd}d|z|d<tj|} | jx|d<} t.j| jd|d<t.jt7jd|d<|Ld| j| j| j| |fz}t=jtA|!}|r&||d<|d} | r| |krtEd-ddi|S|d} | rbtG| $d d!} | &| tK| jkrtEd-ddi|St j&d"krdntO|d#}d$|d%<|d&}|rtQtS|| }|std'd(S|d!\}}||z }d)||d*z | fz|d+<t!||d<|r$tUtW||||j,}tE|fdd,i|StE|fi|S).a Open a file in a safe way and return an instance of :exc:`HTTPResponse` that can be sent back to the client. :param filename: Name or path of the file to send, relative to ``root``. :param root: Root path for file lookups. Should be an absolute directory path. :param mimetype: Provide the content-type header (default: guess from file extension) :param download: If True, ask the browser to open a `Save as...` dialog instead of opening the file with the associated program. You can specify a custom filename as a string. If not specified, the original filename is used (default: False). :param charset: The charset for files with a ``text/*`` mime-type. (default: UTF-8) :param etag: Provide a pre-computed ETag header. If set to ``False``, ETag handling is disabled. (default: auto-generate ETag header) :param headers: Additional headers dict to add to the response. While checking user input is always a good idea, this function provides additional protection against malicious ``filename`` parameters from breaking out of the ``root`` directory and leaking sensitive information to an attacker. Read-protected files or files outside of the ``root`` directory are answered with ``403 Access Denied``. Missing files result in a ``404 Not Found`` response. Conditional requests (``If-Modified-Since``, ``If-None-Match``) are answered with ``304 Not Modified`` whenever possible. ``HEAD`` and ``Range`` requests (used by download managers to check or continue partial downloads) are also handled automatically. rz/\izAccess denied.rezFile does not exist.z/You do not have permission to access this file.Tgzipzapplication/gzipzapplication/x-rNr_ztext/zapplication/javascriptz ; charset=%sr\"zattachment; filename="%s"Content-DispositionrHusegmtrYDatez%d:%d:%d:%d:%sETagHTTP_IF_NONE_MATCHrr[HTTP_IF_MODIFIED_SINCErrr_rbr}z Accept-Ranges HTTP_RANGEizRequested Range Not Satisfiablezbytes %d-%d/%drrXrp)-rrrHrr r"rrjrTr%rrraccessR_OKrzr mimetypes guess_typerrHstatst_sizeemailutils formatdatest_mtimetimest_devst_inor?sha1r hexdigestrrrrr.rrparse_range_headerrQrr)rrootmimetypedownloadrLetagragetenvrr@statsclencheckimsr range_headerrangesrrrlens r static_filer& srJ 7<<--r 2 2Dwrw||D(..2G2GHHIIH '/gllnnnRG _ F   t $ $0./// 7>>( # #627>>(+C+C64555 9Xrw ' 'QOPPP4%h44Bxx(&1$77( v  )HH  3'(2H-8- ( : : bqb\W $ $4L(L(LNW,,+"*47##H--P##C++)Dx)O%& GH  E',}4G ${55enT5RRGOk,,TY[[,FFGFO |5<u~#'#33|CII&&0022 7+,,  7Ud]]66s6g66 6 &) * *C 73*002233 ?sc%.&9&99966s6g66 66))22tHd/C/CD&GO6,''L 9(t<<== ES"CDD DQi V|#3vsQw6M#M $'II ! N :dFD#A#A4:NND888888  ( ( ( ((r cP|rtjdt|adS)zS Change the debug level. There is only one debug level supported at the moment.rN)r simplefilterrrrs rdebugr) s) -X "9 - - - JJEEEr cxt|tr|St|tr|}n)t|tr|}t|t tfstj |}tj |dS)NTr) rzrr1 utctimetupledatedate timetuplerrcalendartimegmrrrrKs rrr s%$$ %"""""$$ E8 $ $"!! ec5\ * *'&& ; ! !% ! 5 55r c tj|}tj|dddz|dpdz S#t t ttf$rYdSwxYw)zD Parse rfc1123, rfc850 and asctime timestamps and return UTC epoch. Nrr r) rr parsedate_tzr.r/rrr OverflowError)r"tss rrr sp [ % %c * *r"1"v~.."Q%*1== z:} =ttsAA A,+A,c, |dd\}}|dkrIttjt |dd\}}||fSdS#t tf$rYdSwxYw)z] Parse rfc2617 HTTP authentication header string (basic) and return (user,pass) tuple or NoneNrrr)rrrTrrrrVr)rr.ruserpwds rrr s||D!,,  <<>>W $ $f.s4yy99::@@aHHID#9  % $ j !ttsA9A>>BBc#K|r|dddkrdSd|dddD}|D]\}} |s#td|t|z |}}nC|st||}}n/t|tt|dz|}}d|cxkr |cxkr|kr nn||fV#t$rYwxYwdS)z~ Yield (start, end) ranges parsed from a HTTP Range header. Skip unsatisfiable ranges. The end index is non-inclusive.Nzbytes=cBg|]}d|v|ddS)rFr)r)r@rs rrEz&parse_range_header.. s) I I I!qaggc1oor rcrr)rrrrr)rmaxlenr$r rs rrr s6 3VBQBZ8++VV I Ivabbz'7'7'<'< I I IF   s  C FSXX$566s C ZZs ZZSXX\6)B)BsE))))C))))6)))))Sj       D   sBC  CCz-(?:(?:"((?:[^"\\]|\\.)*)")|([^;,=]+))([;,=]?)cRg}d|vr|dD]}|d}||dif|ddD]b}|dd\}}||dd|<cnddi}}}t |D]\} } } | r| n| d d}|dkri}|||fnl|dkr3| dkr|}n]d ||<n3|dkr-|r+|||<d}| }|S) a Parses a typical multi-valued and parametrised HTTP header (e.g. Accept headers) and returns a list of values and parameters. For non-standard or broken input, this implementation may return partial results. :param h: A header string (e.g. ``text/html,text/plain;q=0.9,*/*;q=0.8``) :return: List of (value, params) tuples. The second element is a (possibly empty) dict. rrcrrrN=rz\"r)rrr r_hsplitrH) rrrpartsrrloprattrsquotedplaintoks rrr s F !||WWS\\ D DEKK$$E MM58>>++R0 1 1 1abb  D D"jja00 e6;kkmmr 1 djjll002233 D DtR%S")!**   FE3%*JEKKMMMuc0J0JEczz uen----#::CC35E%++----//00-2ciikk''))*CC Mr cg}|dD]}|s|dd}t|dkr|dt|ddd}t|ddd}|||f|S) N&r=rr9rr+r)rrr urlunquoterH)qsrpairnvrrs rrr s A X ZZQ   r77a<<2AsC00112a5==c2233 #u Hr ctdt||D ot|t|kS)zs Compares two strings in a cryptographically safe way: Runtime is not affected by length of common prefix. c30K|]\}}||krdndVdS)rrNrp)r@r\ys rrAz_lscmp.. sF**q!Q11A******r )sumzipr)r_rs rrr sX**"1ayy***** * ?.1!ffA.>?r cjtdddd|p tj}tjt j|d}tjtjt||| }td|ztdz|zS) z> Encode and sign a pickle-able object. Return a (byte) string rrz%cookie_encode() will be removed soon.Do not use this API directly.rrrr) rr?r@rrrr7rrrr)rrrr<rs r cookie_encoderS sB7/111+W^I  6<b11 2 2C  48CHHcYGGGNNPP Q QC s88c>CHH $s **r ctddddt|}t|r|tdd\}}|p tj}t jt|||}t|ddtj |r&tj tj|SdS) z? Verify and decode an encoded string. Return an object or None.rrz%cookie_decode() will be removed soon.rRrrrN)rrcookie_is_encodedrr?r@rrrrrrrr8r)rrrrr<hasheds r cookie_decoderW sB7/111 t99D7::c#hh**S/ #c((C9===DDFF #abb'6+F33 4 4 7< 0 5 566 6 4r ctddddt|tdotd|vS)z9 Return True if the argument looks like a encoded cookie.rrz)cookie_is_encoded() will be removed soon.rRrr)rrr%rrs rrUrU sNB;/111 C))>c#hh$.> ? ??r c|ddddddddd d S) z; Escape HTML special characters ``&<>`` and quotes ``'"``. rFz&rz<rz>rz"'z')rHstrings rr`r` sV >>#w ' ' / /V < < D DS& Q Q'#x((h)?)?@r cdt|ddddddzS)z; Escape and quote a string to be used as an HTTP attribute.z"%s"rCz rDz  z )r`rHr[s r html_quoter_$ sH K''//g>>WT7++GGD&,A,A BBr c#vKd|jdddz}t|}t |dt |dpgz }|d|zt |dd|zz }|V|d|dD]}|d|zz }|VdS)a Return a generator for routes that match the signature (name, args) of the func parameter. This may yield more than one route if the function takes optional keyword arguments. The output is best described by example:: a() -> '/a' b(x, y) -> '/b//' c(x, y=5) -> '/c/' and '/c//' d(x=5, y=6) -> '/d' and '/d/' and '/d//' r^r>rrJz/<%s>N)rtrHrrPrr)rMrrNargcargs rrr* s &&tS1188== =D d  D tAw<<#d1gm,, ,DWt^uT!WUdU^44 44D JJJAwtuu~ #  r rc|dkr||fS|dd}|dd}|r|ddkrg}|r|ddkrg}d|cxkrt|krnn|d|}||z}||d}nTd|cxkrt| krnn||d}||z}|d|}n|dkrdnd}td|zdd|z}dd|z}|dr|r|dz }||fS)aS Shift path fragments from PATH_INFO to SCRIPT_NAME and vice versa. :return: The modified paths. :param script_name: The SCRIPT_NAME path. :param script_name: The PATH_INFO path. :param shift: The number of path fragments to shift. May be negative to change the shift direction. (default: 1) rr^rNr r]z"Cannot shift. Nothing left from %s)r rrAssertionErrorrHr) r path_inforpathlist scriptlistmovedrnew_script_name new_path_infos rrr> s zz+y00s##))#..H""3''--c22J4HQK2%%"x:jmr)):5!!!!CMM!!!!!% %' EFF# U & & & &s:& & & & & &566"8#' !& AEIJJJCHHZ000O#((8,,,M#A8A]c-A] M ))r private Access deniedcfd}|S)ze Callback decorator to require HTTP auth (basic). TODO: Add route(check_auth=...) parameter. cNtjfd}|S)Nctjpd\}}| ||s+td}|ddz|S|i|S)Nr@izWWW-AuthenticatezBasic realm="%s")rrrr) r_rr6passwordrr!rMrealmrs rrz.auth_basic..decorator..wrapperc si$\9\ND(|55x#8#8|T**13E3MNNN 4>b>> !r rr)rMrr!rqrs` rrzauth_basic..decoratora sH    " " " " " " "   "r rp)r!rqrrs``` r auth_basicrs] s0        r cltjttfd}|S)zA Return a callable that relays calls to the current default app. cHtt|i|SrR)rr)r_rrs rrz)make_default_app_wrapper..wrapperw s&#wsuud##Q-"---r )rrrr)rrs` rmake_default_app_wrapperrvt sD_WVT**++....,+. Nr rrTr r#r&r)r*rrrrrceZdZdZdS)rcDt|dd|zdS)NrzMultipartError: )rr)rkr<s rrzMultipartError.__init__ s&4&83&>?????r N)rtrurvrrpr rrr s(@@@@@r rc.eZdZ d dZdZd Zd S) rr@rrr?c 8||_||_||_||_||_t ||j|_t ||j|_||_|std|jdz t|krtddS)Nz No boundary.r9z'Boundary does not fit into buffer_size.) streamrr disk_limitrrrrrLrr) rkr}rrr~rrrrLs rrz_MultipartParser.__init__ s   ,$*Y88{DN;;  1 00 0  a #h-- / / !JKK K 0 /r c#K|jj}|j|j}}d} ||dkr|nt ||}|t |z}|s |r|dfVdS|r||z}d} |d|}|dkr|||dfV|dz}n|r ||dn|}n@t ||kr|dddfV|dd})aR Iterate over a binary file-like object (crlf terminated) line by line. Each line is returned as a (line, crlf) tuple. Lines larger than buffer_size are split into chunks where all but the last chunk has an empty string instead of crlf. Maximum chunk size is twice the buffer size. r Trs r9Nr)r}rIrrrrfind)rkrIrmaxbufrchunkscanposrXs r _lineiterz_MultipartParser._lineiter s={-t/? 'D7Q;;C4H4HIIE s5zz !G '!3,&&& (%G JJw0066 *G3333!eGG18CeGHHooeG 7||f$$crclC''''!"##,/ 'r c#K|d}}dt|jz}|dz}d\}}d}|D] \}}|||fvrntd||kr|D]} tddS|j|j|jd} td i| } |D]\}}|sb||ks||krV| | r || j z }n || j z }| V||krntd i| } i| } | ||| r#| j |z|j krtd n"| j |z|j krtd #t$r| wxYw| ||krtd dS) z7 Return a MultiPart iterator. Can only be called once. rs--rrFz Stream does not contain boundaryz'Found data after empty multipart streamN)rrrLzMemory limit reached.zDisk limit reached.z#Unexpected end of multipart stream.rp)rrrrrrrL_MultipartPartfinishrrfeedrr~r) rklinesline separator terminatormem_used disk_usedis_tailnlr+ part_optionsrs rrz_MultipartParser.parse sfnn&&tC ... & ") E EHD" :.../!!CDD D :   P P$%NOOO F +!/|  -- --  HD"  1 1TZ5G5G ##%%+ )HH*I :%%E%55 55 & IIdB'''''))D9x/$.@@"01H"I"IIAY.@@,-BCCC%JJLLL JJLLL :   !FGG G  s A/E66 FN)rrzrr{rr?)rtrurvrrrrpr rrr sd LLLL4#'#'#'J9H9H9H9H9Hr rcneZdZddZddZdZdZd Zd Zd Z e d Z e d Z dZ dS)rrr{r?cg|_d|_d|_d|_d|_d|_d|_d|_d|_||_ ||_ ||_ dS)NFrr ) rrarr_buf dispositionrrrrLrr)rkrrrLs rrz_MultipartPart.__init__ s`        *&r rch|jr|||S|||SrR)r write_body write_header)rkrrs rrz_MultipartPart.feed# s6 9 -??4,, ,  r***r cH||j}|std|s|dS|ddvrV|jrO|j\}}|j|||zfdSd|vrtd|dd\}}|j||fdS)Nz!Unexpected end of line in header.rz rz!Syntax error in header: No colon.r) rrLrr  finish_headerrrPrr)rkrrrrs rrz_MultipartPart.write_header( s{{4<(( F !DEE Ezz|| B    !W  $/ /--//KD% O " "D%$**,,*>#? @ @ @ @ @$$%HIII**S!,,KD% O " "DJJLL%++--#@ A A A A Ar c|s|sdS|xjt|t|jzz c_|j|j|z||_|jdkr|j|jkrt d|j|jkrt|jtrtd|jc|_}| dd|j|j }}}|j |jj}}||krE|t|||z } || |t| z }||k?dSdSdSdS)Nrz+Size of body exceeds Content-Length header.rr)rrrrrBrrrrzrFr3rrrIr) rkrroldcopiedmaxcopy chunksizerIrBrs rrz_MultipartPart.write_body: sa B  F SYYTY//   D()))   " "ty43F'F'F !NOO O 9t) ) )jG.L.L )/U;;;TYNDIs HHQKKK)*DIt7GYGF(DIO%D7""SGf,<==>>e #e**$7"""" * ) ) ) #"r c2t|_t|j|_|jd}|jd}|st dt|d\|_|_ |j d|_ d|j vrj|j d|_ |j ddd ks|j dd d kr%|j d d |_ |rt|dndif\|_ }|dp|j|_t|jdd|_dS)Nrr\z&Content-Disposition header is missing.rrrrrJz:\r9z\\rrrLrHz-1)rFrrrrrarTrrrrrrrrrLrr)rkcontent_dispositionrrs rrz_MultipartPart.finish_headerP sqII !$/22 "l../DEE|''77 " K !IJJ J);>## INN3    DINN3    s A((BcX|jr"|jd|_dSdSr)rrr{s rrz_MultipartPart.close s3 9  IOO   DIII  r N)rr{r?r)rtrurvrrrrrrrr>rrWrrpr rrr s ' ' ' '++++ BBB$%%%,LLL* ...--X-   X r rc&eZdZdZddZdZdZdS) ServerAdapterFrc J||_||_t||_dSrR)rrrr)rkrrrs rrzServerAdapter.__init__ s!  II r cdSrRrprkhandlers rrzServerAdapter.run rr cdd|jD}|jjd|dS)N, c3DK|]\}}|dt|VdS)r=N)rirs rrAz)ServerAdapter.__repr__.. sK<<"a%&AAtAwww/<<<<<222DDD99r N)rr)rtrurvquietrrrrpr rrr sK E    :::::r rceZdZdZdZdS) CGIServerTcXddlm}fd}||dS)Nr) CGIHandlercH|dd||S)Nr]r)r'rjrrs r fixed_environz$CGIServer.run..fixed_environ s+   {B / / /77N33 3r )wsgiref.handlersrr)rkrrrs ` rrz CGIServer.run sP////// 4 4 4 4 4  '''''r N)rtrurvrrrpr rrr s( E(((((r rceZdZdZdS)FlupFCGIServercddl}|jd|j|jf|jjj|fi|jdS)Nr bindAddress) flup.server.fcgirr'rrr$fcgi WSGIServerr)rkrflups rrzFlupFCGIServer.run sc   49/EFFF# #G<.FixedHandlerc|jdSrh)client_addressr{s raddress_stringz6WSGIRefServer.run..FixedHandler.address_string s*1--r c0js j|i|SdSrR)r log_request)rkwrrks rrz3WSGIRefServer.run..FixedHandler.log_request s3zG9-94F2FFFGGr N)rtrurvrr)rrksr FixedHandlerr sJ . . . G G G G G G G Gr r handler_class server_classraddress_familyceZdZjZdS)%WSGIRefServer.run..server_clsN)rtrurvAF_INET6r)socketsr server_clsr s%+_NNNr r)wsgiref.simple_serverrrrrrrTrrAF_INETrsrv server_port serve_foreverr> server_close) rkrrrr handler_clsrrrs ` @@rrzWSGIRefServer.run s555555HHHHHHHH  G G G G G G G G- G G Gl&& EE \%%njAA $)  z#344FF5555555555;ty$)S**,,H(   H " " $ $ $ $ $     H ! ! # # #  s ?C%C?Nrrpr rrr s#r rceZdZdZdS)CherryPyServerctddddddlm}|j|jf|jd<||jd<|jd}|r|jd=|jd }|r|jd =|jd i|j}|r||_|r||_ | | dS#| wxYw) NrrzOThe wsgi server part of cherrypy was split into a new project called 'cheroot'.z5Use the 'cheroot' server adapter instead of cherrypy.) wsgiserver bind_addrwsgi_appcertfilekeyfilerp) rcherrypyrrrrrTCherryPyWSGIServerssl_certificatessl_private_keyr stop)rkrrrrr$s rrzCherryPyServer.run s Q023 4 4 4 ('''''%)Y $: [!#* Z <##J//  ) Z(,""9--  ( Y'..>>>>  .%-F "  -%,F "  LLNNN KKMMMMMFKKMMMMs &CC&Nrrpr rrr s#r rceZdZdZdS) CherootServercddlm}ddlm}|j|jf|jd<||jd<|jdd}|jdd}|jdd}|jd i|j}|r|r| ||||_ | | dS#| wxYw) Nrrd)builtinrrrr chainfilerp) cherootrb cheroot.sslrrrrrPServerBuiltinSSLAdapter ssl_adapterr r)rkrrbrrrrr$s rrzCherootServer.run s      ''''''%)Y $: [!#* Z <##J55,""9d33L$$[$77 ,,t|,,  2 2!(!:!:gy"2"2F   LLNNN KKMMMMMFKKMMMMs 1CC1Nrrpr rrr s#r rceZdZdZdS)WaitressServercTddlm}||f|j|j|jd|jdS)Nrserve)rr_quiet)waitressrrrrr)rkrrs rrzWaitressServer.runsC"""""" gYDIDIdjYYDLYYYYYr Nrrpr rrrs(ZZZZZr rceZdZdZdS) PasteServercddlm}ddlm}|||j }|j|f|jt|jd|j dS)Nr) httpserver) TransLogger)setup_console_handlerrr) pasterpaste.transloggerrrrrrrr)rkrrrs rrzPasteServer.run s$$$$$$111111+g$*nNNN  >"i!$)nn > >04  > > > > >r Nrrpr rrrs#>>>>>r rceZdZdZdS)MeinheldServerc~ddlm}||j|jf||dS)Nr)r$)meinheldr$listenrrr)rkrr$s rrzMeinheldServer.runsG###### ty$),--- 7r Nrrpr rr r s#r r ceZdZdZdZdS) FapwsServerzR Extremely fast webserver using libev. See https://github.com/william-os4y/fapws3 ctdddddlm}ddlm}m}|j}t|jdddkrt|}| |j |dtj vr%|jstdtd ||fd }|d |f|dS) Nrrz5fapws3 is not maintained and support will be dropped.)rrvrg? BOTTLE_CHILDz2WARNING: Auto-reloading does not work with Fapws3.z. (Fapws3 breaks python thread support)c&d|d<||S)NFzwsgi.multiprocessrprs rrzFapwsServer.run..app+s +0G' (77N33 3r r)r fapws._evwsgi_evwsgifapwsrrvrr SERVER_IDENTrr rrrjrrset_base_modulewsgi_cbr)rkrevwsgirrvrrs ` rrzFapwsServer.runs QKLLL&&&&&&&&&&&&&&y $RSS) * *S 0 0t99D TY%%% RZ ' ' ' H I I I D E E Et$$$ 4 4 4 4 4 Cy!!! r Nrtrurvrrrpr rrrs)\\r rceZdZdZdZdS) TornadoServerz< The super hyped asynchronous server by facebook. Untested. c(ddl}ddl}ddl}|j|}|j|}||j|j |j j dS)Nr)raddress) tornado.wsgitornado.httpservertornado.iolooprb WSGIContainerr HTTPServerr rrioloopIOLoopinstancer )rkrtornado containerr$s rrzTornadoServer.run6s????????????L..w77 #..y99 49di 888&&((..00000r Nrrpr rrr3s)FF11111r rceZdZdZdZdZdS)AppEngineServerz Adapter for Google App Engine. Tctddddddlmtjd}|rt |ds fd|_dS) Nrrz"AppEngineServer no longer requiredz4Configure your application directly in your app.yaml)utilr.mainc.SrR) run_wsgi_app)rr,srrVz%AppEngineServer.run..Js$"3"3G"<"<r ) rgoogle.appengine.ext.webappr,rrrTrZr-r/)rkrrr,s ` @rrzAppEngineServer.runBs Q8 C E E E444444,,  ='&&11 =<<<<s.** E # # # # #r r*ceZdZdZdZdS) TwistedServer Untested. ctddlm}m}ddlm}ddlm}|}||dd|j | | |||}| |j ||j|js|dSdS)Nr)r$rb) ThreadPool)reactoraftershutdown) interface) twisted.webr$rbtwisted.python.threadpoolr5twisted.internetr6r addSystemEventTriggerrSite WSGIResource listenTCPrrrunningr)rkrr$rbr5r6 thread_poolfactorys rrzTwistedServer.runQs,,,,,,,,888888,,,,,, jll %%gz;;KLLL++d//gNNOO$)W BBB  KKMMMMM  r Nrrpr rr2r2Ns)     r r2ceZdZdZdZdS) DieselServerr3ctdddddlm}|||j}|dS)Nrrz6Diesel is not tested or supported and will be removed.)WSGIApplication)r)rdiesel.protocols.wsgirGrr)rkrrGrs rrzDieselServer.runasN QLMMM999999ogDI666  r Nrrpr rrErE^s)r rEceZdZdZdZdS) GeventServerz` Untested. Options: * See gevent.wsgi.WSGIServer() documentation for more options. ctddlm}m}tt j|jsd}t ||jr d|jd<|j|j f}|j ||fi|jdtj vr"ddl }| |jfddS)Nr)pywsgirz9Bottle requires gevent.monkey.patch_all() (before import)logrc,SrR)r)rUrRr$s rrVz"GeventServer.run..ysfkkmmr )r"rLrrzrrxrrrrrrrjsignalSIGINTr)rkrrLrr<rrOr$s @rrzGeventServer.runns(((((((()/++U[99 $MCs## # : '"&DL 9di(""7GDDt|DD RZ ' ' MMM MM&-)C)C)C)C D D Dr Nrrpr rrJrJhs-     r rJceZdZdZdZdS)GunicornServerz? Untested. See http://gunicorn.org/configure.html for options. cddlm}|jdr d|jindd|j|jfzi|jGfdd|}|dS)Nr)BaseApplicationunix:r<z%s:%dc$eZdZfdZfdZdS)/GunicornServer.run..GunicornApplicationcrD] \}}|j||!dSrR)r^rr)rkrrrvs rr~z;GunicornServer.run..GunicornApplication.load_configsA"(,,..--JCHLLe,,,,--r cSrRrprs rrz4GunicornServer.run..GunicornApplication.loadsr N)rtrurvr~r)rvrsrGunicornApplicationrWsG - - - - -       r rZ)gunicorn.app.baserTrr%rrrr)rkrrTrZrvs ` @rrzGunicornServer.runs555555 9   ( ( @di(FFgDI(>>?F dl###        /    !!#####r Nrrpr rrRrR}s)II$$$$$r rRceZdZdZdZdS)EventletServeraN Untested. Options: * `backlog` adjust the eventlet backlog parameter which is the maximum number of queued connections. Should be at least 1; the maximum value is system-dependent. * `family`: (default is 2) socket family, optional. See socket documentation for available families. cddlm}m}m}|t sd}t |i}dD]0} |j|||<!#t$rY-wxYw|j |j f} | ||fi|||j dS#t$r#| |||YdSwxYw)Nr)rbr patcherz7Bottle requires eventlet.monkey_patch() (before import))backlogfamily) log_output)r#rbr r_is_monkey_patchedrrxrrPrVrrr$rr) rkrrbr r_r< socket_argsrbrs rrzEventletServer.runs42222222222((,, $KCs## # (  C #'<#3#3C#8#8 C      9di( 2 KKw66+66(, N  5 5 5 5 5 2 2 2 KKw 1 1 1 1 1 1 2s#A A('A(:%B!!)C CNrrpr rr]r]s-22222r r]ceZdZdZdZdS) BjoernServerz? Fast server written in C: https://github.com/jonashaag/bjoern cDddlm}|||j|jddS)NrrT) reuse_port)bjoernrrr)rkrrs rrzBjoernServer.runs7 GTY d;;;;;;r Nrrpr rrfrfs)II<<<<.sdinn6F6Fr r) rraiohttp_wsgi.wsgirrmrvset_event_looprrjrOrPrr)rkrrrrrOs` rrzAiohttpServer.runs++++++'')) ty))) RZ ' ' MMM MM&-)F)F)F)F G G G gDIDI666666r N)rtrurvrrmrrpr rrprps< ((( 7 7 7 7 7r rpceZdZdZdZdS)AiohttpUVLoopServerz7uvloop https://github.com/MagicStack/uvloop c2ddl}|Srh)uvlooprs)rkr|s rrmz"AiohttpUVLoopServer.get_event_loops $$&&&r Nrnrpr rrzrzs-'''''r rzc(eZdZdZeeeeee gZ dZ dS) AutoServerr3c|jD]@} ||j|jfi|j|cS#t $rY=wxYwdSrR)adaptersrrrr ImportError)rkrsas rrzAutoServer.runsv-  B r$)TY??$,??CCGLLLLL      s+9 AAN) rtrurvrrrr2rrrrrrpr rr~r~s> ]N}.Hr r~cgirrrrrrfapws3r'gaetwisteddieselr gunicornr#r"ri)aiohttpr|autoc d|vr|ddn|df\}}|tjvrt||stj|S|r t tj||S|dd}tj|||<t |d||S)a Import a module or fetch an object from a module. * ``package.module`` returns `module` as a module object. * ``pack.mod:name`` returns the module variable `name` from `pack.mod`. * ``pack.mod:func()`` calls `pack.mod.func()` and returns the result. The last form accepts not only function calls, but any type of expression. Keyword arguments passed to this function are available as local variables. Example: ``import_string('re:compile(x)', x='[a-z]')`` rrNrr)rrrrisalnumreval)r/rr package_names rrrs.1F]]V\\#q)))NFF S[  *V"4"4"4 -#+f-- ~~D F(;V D DD<<$$Q'L!k,7Il 66666*I 6 66r c dtca}t} t|}t |r|n| t||aS#t||awxYw)z Load a bottle application from a module and make sure that the import does not affect the current default application, but returns a separate application object. See :func:`load` for the target parameter. T)NORUNrfrgrrr)r/nr_oldrrs rload_apprs %ME6     C &\\b\\*rrs*3 3s !A$$Brrc  \ trdS|r+tjds ddl} t jdd\} } tj}d|d<| |d<tj gtj z}ttj d d drd tj d j g|d d < tj| tj| r| || }|=tj| dt)j||=|jdkrtj|jtj| n#t0$rYnwxYwtj| rtj| n9#tj| rtj| wwxYwdS |t5||p t7}t9|t:rt=|}t?|stAd|z|pgD];}t9|t:rtC|}|"|<| r|j#$| |tJvrtJ|}t9|t:rtC|}t9|tLr |d||d| }t9|tNstAd|z|j(p||_(|j(stSdtTdtW|d|j,-drtSd|j,zntSd|j,|j.fztSd|rtjd} t_| |}|5|0|dddn #1swxYwY|j1dkrtjddSdS|0|dS#t0$rYdStdtff$r|st|d|stit)j|tjdYdSxYw)a Start a server instance. This method blocks until the server terminates. :param app: WSGI application or target string supported by :func:`load_app`. (default: :func:`default_app`) :param server: Server adapter to use. See :data:`server_names` keys for valid names or pass a :class:`ServerAdapter` subclass. (default: `wsgiref`) :param host: Server address to bind to. Pass ``0.0.0.0`` to listens on all interfaces including the external one. (default: 127.0.0.1) :param port: Server port to bind to. Values below 1024 require root privileges. (default: 8080) :param reloader: Start auto-reloading server? (default: False) :param interval: Auto-reloader interval in seconds (default: 1) :param quiet: Suppress output to stdout and stderr? (default: False) :param options: Options passed to the server adapter. Nrrzbottle.z.lock)rsuffixtrueBOTTLE_LOCKFILEr. __package__z-mr)rrJzApplication is not callable: %rrz!Unknown or unsupported server: %rzBottle vz server starting up (using z)...rUzListening on %szListening on http://%s:%d/zHit Ctrl-C to quit. reloadrrp)5rrrjrT subprocesstempfilemkstempr"r executableargvrrrrrrPopenpollutimersleep returncodeexitr>unlink_debugrfrzrrrrrrrvr server_namesrrrr __version__rirr%rFileCheckerThreadrrr?r@r5)rr$rrintervalreloaderrrtr)rvrrfdlockfilerjrrrbgchecks rrr-s]4 ff ~66'yIII H*//##"(%-!"#(* 3;??:.. t D D Ds{:6BCD1I $ HRLLL'..** '$$Tw$77ffhh&HXt,,,Jx(((ffhh&<1$$&&&'..** '!    D w~~h'' $ (###w~~h'' $ (#### $6  fUmmm"[]] c: & & 3--C}} F>DEE Em  F&*-- &f KK      & J  f % % % \ ! !!%%f--F fj ) ) "&\\F fd # # ;V:D::E::F&-00 K@6IJJ J|,u | - G [[$v,,,,0 1 1 1{%%g.. 4)FK788884fk23444 + , , ,  z~~&788H'(;;G   3               ~)) *) JJsOOOOO       $ vw..  KKK 8  siCF98G=9 GG=GG==6H39HR?Q:. R?:Q>>R?Q>"R?(R?? T+ AT+c*eZdZdZdZdZdZdZdS)rzx Interrupt main-thread as soon as a changed module file is detected, the lockfile gets deleted or gets too old. c~tj|d|_||c|_|_d|_dSr)rThreadrdaemonrrr)rkrrs rrzFileCheckerThread.__init__s;!!$''' '/$ t} r ctjj}d}t}t t jD]F}t|ddpd}|dddvr |dd}|r||r||||<G|j s||j r0||j tj |j z dz krd|_ tjt |D];\}}||r|||krd |_ tjn.s"'!**-r rr)z.pyoz.pycrr_r*r)rrrrrrrrrrrrrthreadinterrupt_mainr^r)rkrmtimerrrlmtimes rrzFileCheckerThread.runs--3;--//00 @ @F6:r228bDBCCy,,,T#2#Yd ?t ?EE$KKeDk+ &6$-(( (uT]##dikkDM&AA&EEE% %''' $U[[]] 3 3   fvd||uuT{{V';';"*DK)+++E(< Jt} % % %+ & & & & &r c.|dSrR)r r{s rrhzFileCheckerThread.__enter__s r cx|jsd|_||duot|tS)Nr)rrHrbr>)rkrjr+s rrmzFileCheckerThread.__exit__s8{0&DK t#O 8=N(O(OOr N)rtrurvrrrrhrmrpr rrrs_77&&&,PPPPPr rceZdZdS) TemplateErrorNrrpr rrrrr rcleZdZdZgdZiZiZ d dZed dZ edZ dZ d Z dS) BaseTemplatez2 Base class and minimal API for template adapters )rhtmlthtmlstplNrxc ^||_t|dr|n||_t|dr|jnd|_|r d|Dng|_||_|j|_|j ||jsR|jrK| |j|j|_|jstdt|z|js|jstd|j di|jdS)a= Create a new template. If the source parameter (str or buffer) is missing, the name argument is used to guess a template filename. Subclasses can assume that self.source and/or self.filename are set. Both are strings. The lookup, encoding and settings parameters are stored as instance variables. The lookup parameter stores a list containing directory paths. The encoding parameter should be used to decode byte strings or files. The settings parameter contains a dict for engine-specific settings. rIrNcLg|]!}tj|"Srp)rrrrbs rrEz)BaseTemplate.__init__..s&:::arwq)):::r zTemplate %s not found.zNo template specified.rp)rrZrIrrrr@settingsr"rrrrir)rkrrrr@rs rrzBaseTemplate.__init__s0 '.vv'>'>JfkkmmmF +26:+F+FPD >DL::6::::"    **,,  X&&&{ Kty K KK 4;??DM= K#$>E##E** 4Hw~~e$$ 2Ulll~ 2 27>>UUUCC"8992&+eeSS1111112 2  2 2r c|r0|j|_|d|j|<dS|j|S)zB This reads or sets the global settings stored in class.settings. rN)rr")rrrs r global_configzBaseTemplate.global_configsD  %<,,..CL $QCL   <$ $r c t)z Run preparations (parsing, caching, ...). It should be possible to call this again to refresh a template or to update settings. NotImplementedError)rkrs rrzBaseTemplate.prepares "!r ct)aF Render the template with the specified local variables and return a single byte or unicode string. If it is a byte string, the encoding must match self.encoding. This method must be thread-safe! Local variables may be provided in dictionaries (args) or directly, as keywords (kwargs). r)rkrrOs rrenderzBaseTemplate.renders "!r )NNNrxrR) rtrurvrrrdefaultsr classmethodrrrrrpr rrrs<<111JHH &&&&<222[2&%%[%""""""""r rceZdZdZdZdS) MakoTemplatec 6ddlm}ddlm}|d|ji|dtt|d d|j i|}|j r||j fd|i||_ dS|d |j |j |d||_ dS) NrTemplate)TemplateLookupr7format_exceptions directoriesr)urirrrp) mako.templater mako.lookuprrr@r'rrrrrrr)rkrrrrs rrzMakoTemplate.prepare#s******......($-8999.U <<<CCDKC7CC ; :x FFFFgFFDHHHx:DI)-'-::18::DHHHr c|D]}|||j}|||jjdi|SNrprrr"rrrkrrOdictarg _defaultss rrzMakoTemplate.render0g # #G MM' " " " "M&&((    tx+++++r Nrtrurvrrrpr rrr"s2 : : :,,,,,r rceZdZdZdZdS)CheetahTemplatec ddlm}tj|_i|j_|jjg|d<|jr|dd|ji||_dS|dd|ji||_dS)Nrr searchListrrrp) Cheetah.Templaterrrcontextvarsrrr)rkrrs rrzCheetahTemplate.prepare9s------ ((  !%!2 3  ; ?x>>t{>g>>DHHHx>>T]>g>>DHHHr c$|D]}|||jj|j|jj|t |j}|jj|SrR)rrrrrrr)rkrrOrrDs rrzCheetahTemplate.renderCs # #G MM' " " " "   ///   ((($(mm !!! r Nrrpr rrr8s2???r rc(eZdZddifdZdZdZdS)Jinja2TemplateNc ddlm}m}|dd||ji||_|r|jj||r|jj||r|jj||j r&|j |j |_ dS|j |j |_ dS)Nr) EnvironmentFunctionLoaderloaderrp)jinja2rrrrrrtestsglobalsr from_stringr get_templater)rkrrrrOrrs rrzJinja2Template.prepareNs66666666;LLnnT[&A&ALVLL 4DH$++G444 .$(.''... 4DH$++G444 ; 8x++DK88DHHHx,,TY77DHHHr c|D]}|||j}|||jjdi|Srrrs rrzJinja2Template.renderYrr c||jkr|}n|||j}|sdSt|d5}||j|dfcdddS#1swxYwYdS)NrcdSrrprpr rrVz'Jinja2Template.loader..gs5r )rrrrrIrr@)rkrrrRs rrzJinja2Template.loader`s 4= EEKKdk22Eff %   J!FFHHOODM22E==I J J J J J J J J J J J J J J J J J Js0A;;A?A?)rtrurvrrrrpr rrrMsR"$ 8 8 8 8,,,JJJJJr rcdeZdZeddfdZedZedZd dZd dZ dZ d Z dS) SimpleTemplateFNc i|_|jfd|_fd|_||_|r|j|jc|_|_dSdS)Nc$t|SrRrT)r\r~s rrVz(SimpleTemplate.prepare..qseAsmmr c6t|SrRr)r\r~ escape_funcs rrVz(SimpleTemplate.prepare..rsU1c]]!;!;r )rr@_str_escapesyntax)rkrnoescaperrr~s ` @rrzSimpleTemplate.prepareksh m++++ ;;;;;   >&*lDI #DIt||| > >r c<t|j|jpddS)Nzrw)r)r-rr{s rcozSimpleTemplate.cowsty$-"=:vFFFr cn|j}|sAt|jd5}|}dddn #1swxYwY t |d}}n #t $rt ddddwxYwt|||j}| }|j |_ |S)Nrrxr zUnsupported template encodings.zUse utf-8 for templates.)r@r) rrrrIrTr;r StplParserr translater@)rkrrRr@rr-s rr-zSimpleTemplate.code{s "dmT** "a " " " " " " " " " " " " " " " ]$V}}fHFF ] ] ]q"?A[\\ \ ]FXdkJJJ!!  sAAA AA;c ||f|d<dS)N_rebaserp)rk_envrWrOs rrzSimpleTemplate._rebases &/Yr c |}||||jvr*|||j|j|j|<|j||d|S)N)rrr_stdout)r"rrr3rrexecute)rkrrWrOrs r_includezSimpleTemplate._includessiikk 6  " " $E$+VZVa b bDJu z% ((Y===r c |j}|||||jt j|j|t j|j|d|j|j |j |j |j d t|j|| drD|d\}}d||d<|dd=|j||fi|S|S)N) r _printlistincluderebaserrrrTr'definedrrr)rr"rextendrrrrrrrTr'rurwr rPrH)rkrrOrsubtplrargss rrzSimpleTemplate.executesm  "" 6 !. (<<' c::I|7.'    TWc 779   7GGI..MFEGGG,,E&M  4=f6666 6 r ci}g}|D]}|||||||d|S)zA Render the template using keyword arguments as local variables. r)rrrH)rkrrOrstdoutrs rrzSimpleTemplate.rendersf  G JJw     6 VS!!!wwvr rR) rtrurvr`rrr r-rrrrrpr rrrjs' > > > >GG_G  _ ****>>>>.r rceZdZdS)StplSyntaxErrorNrrpr rr r rr r ceZdZdZiZdZeddZedz ZdZdezZdezZdezZd Z dd Z d Z dZ e e e ZdZdZdZedZddZd S)r z Parser for stpl templates. a( [urbURB]* (?: ''(?!') |""(?!") |'{6} |"{6} |'(?:[^\\']|\\.)+?' |"(?:[^\\"]|\\.)+?" |'{3}(?:[^\\]|\\.|\n)+?'{3} |"{3}(?:[^\\]|\\.|\n)+?"{3} ) )z|\nra # 2: Comments (until end of line, but not the newline itself) |(\#.*) # 3: Open and close (4) grouping tokens |([\[\{\(]) |([\]\}\)]) # 5,6: Keywords that start or continue a python block (only start of line) |^([\ \t]*(?:if|for|while|with|try|def|class)\b) |^([\ \t]*(?:elif|else|except|finally)\b) # 7: Our special 'end' keyword (but only if it stands alone) |((?:^|;)[\ \t]*end[\ \t]*(?=(?:%(block_close)s[\ \t]*)?\r?$|;|\#)) # 8: A customizable end-of-code-block template token (only end of line) |(%(block_close)s[\ \t]*(?=\r?$)) # 9: And finally, a single newline. The 10th token is 'everything else' |(\r?\n) z4(?m)^[ \t]*(\\?)((%(line_start)s)|(%(block_start)s))z2%%(inline_start)s((?:%s|[^'"\n])*?)%%(inline_end)sz(?mx)z <% %> % {{ }}Nrxct|||c|_|_||p|jggc|_|_d\|_|_d\|_ |_ d|_ dS)N)rrrr) rTrr@ set_syntaxdefault_syntax code_buffer text_bufferlinenorindent indent_mod paren_depth)rkrrr@s rrzStplParser.__init__sr%*68%<% % {{ }}) )_syntaxr{s r get_syntaxzStplParser.get_syntaxrr c||_||_||jvr|d}t t j|j}tt|||j |j |j f}fd|D}||j|<|j|\|_ |_ |_dS)Nz:block_start block_close line_start inline_start inline_endc>g|]}tj|zSrp)rr))r@r pattern_varss rrEz)StplParser.set_syntax..s(GGG 1|#344GGGr )r,r_tokens _re_cacherrr&rrP _re_split_re_tok_re_inlre_splitre_tokre_inl)rkrrPetokenspatternsr0s @rr#zStplParser.set_syntaxs ||~~  ' 'PE")T\22GEKKMM7 ; ;<@C-DEEEKK3tcz??2KK!!! t~~dk$+,,.G8zStplParser.flush_textYs,wwt'((  QQQ VVQ ); ;Bs%%d++ B BAs17799}-quuwwCF J RWWSv/@/@/F/F%G%GHHIIIt$$ 5eBiii2oiii LL,,QWWQZZ-=-=-?-?@@ A A A A T??#$$ZF%%d++ERy!!(++ Lr3B3U2YYr##J// KU2Yss^r LLT5!1!122 3 3 3"TYYu%5%55 tzz$''!++  r c>|ddkr d|ddzSd|zS)Nrrz_str(%s)rz _escape(%s)rp)rs rrQzStplParser.process_inlinens, 8s??:abb #99u$$r cd|j|jzz}|||zdzz }|j|dS)NrNrC)r(r)rr%r)rkrrDr-s rrAzStplParser.write_codessNt{T_45  '$.. %%%%%r )Nrxr)rtrurvrr2r4rHr5r3r$rr-r#r>rr r?r>rArQrArpr rr r s&&I  Goofb))G G.LIG'QGGG%N I I IXj* - -F))).333j*%%\%&&&&&&r r c|r|dnd}|ddD]}|||dt}|dt}t ||f}|t vst r|di}t||r$|t |<|rt |jdi|n7d|vs d|vsd |vsd |vr|d||d |t |<n|d||d |t |<t |std d|zt | |S)z Get a rendered template as a string iterator. You can use a name, a filename or a template string as first parameter. Template rendering arguments can be passed as dictionaries or directly (as keyword arguments). rNrtemplate_adaptertemplate_lookupr0rC{%$)rr)rrr*zTemplate (%s) not foundrp) rrPr TEMPLATE_PATHid TEMPLATESrrzrrr)rrOrradapterrtplidrs rr1r1ys #$q''tC8 gjj+^<.decorator..wrappersT4*6**F&4"344 6"--//v&&&44G44455H555Mr rr)rMrrrfs` rrzview..decoratorsC            r rp)rfrrs`` rrrs*       r rz./views/z I'm a teapotizPrecondition RequiredizToo Many RequestsizRequest Header Fields Too LargeizUnavailable For Legal ReasonsizNetwork Authentication Requiredic#.K|]\}}|d||fzfVdS)z%d %sNrprs rrArAsH<<$q!gA./<<<<< Error: {{e.status}}

Error: {{e.status}}

Sorry, the requested URL {{repr(request.url)}} caused an error:

{{e.body}}
%%if DEBUG and e.exception:

Exception:

%%try: %%exc = repr(e.exception) %%except: %%exc = '' %% type(e.exception).__name__ %%end
{{exc}}
%%end %%if DEBUG and e.traceback:

Traceback:

{{e.traceback}}
%%end %%except ImportError: ImportError: Could not generate the error page. Please add bottle to the import path. %%end z bottle.extz.extz bottle_%sc N t|\} fd}|jr+tdtzt jd|js |dtjddtj dtj d|j pdd }}d |vrE| d | d kr| d d \}}|d }t}|jpgD]} |dr]t%|d5}|t)|dddn #1swxYwYn||#t.j$r}||Yd}~d}~wt2$r|d|zYt4t6t8f$r} |d|d| Yd} ~ d} ~ wwxYw|jpgD]6} d| vr+|| dd f1d|| <7tA|j|tC||j"|j#|j$|j%|dS)Nc|td|ztjddS)Nz Error: %s r) print_helprrr)cli_msgrs r _cli_errorz_main.._cli_errors9')***  r z Bottle %srz%No application entry point specified.rrwr. localhostrr]rz[]z.jsonrzUnable to read config file %rzUnable to parse config file r2r=T)rrr$rrtr)rv)&rversionrrrrrrrrr'r<rfindrr rrrrrxrrIr~ryErrorrr;rrparamrrrrr$rrr)) rrrlrrrvcfiler parse_errorr*cvalrs @r_mainrvs9d##LD&  | kK'(((  8< :;;;HOOAsK8S[%<===)*{T$D d{{tzz#C88[[a(( d ::d  D \\Fb N N N~~g&& *%&&<"$$Z %:%:;;;<<<<<<<<<<<<<<<""5)))! $ $ $ J{ # # # # # # # # @ @ @ J6> ? ? ? ? ?i4 N N N JJuuueeL M M M M M M M M N  b   $;; MM4::c1--/ 0 0 0 0F4LL  YY{ jsN0%F85F F8F F8F F88H% GH%4H% H  H%c8ttjdSrR)rvrrrpr rr-r-Ds #(OOOOOr )rx)rxr)rJ)r*rrR)r)TFrNNrrr<)rkrl) NrrrrFFNNN( __future__rr __author__r __license__rr-rtrrr. email.utilsrrrrr rrrrrrrr?typesr/r1r0r,r2r3rlr4r5 unicodedatar6ujsonr7rr8rSrr version_inforrr http.clientclienthttplib_threadr urllib.parser:r;rr<r=rr>rHr http.cookiesrArBrCcollections.abcrDrcrErbriorFryrGutcroinspectrHrPrrr{rrrrar`rrurlparseurllibCookiecPickleimprcr{ collectionsrdrfrwr)rrTrrrrrKrorrrrArrrrrrrrrqrrsrIrLrNrVrrrr!ResponserrrrrrrrrrrrrrrrrOrQrrrrrr&r)rrrrfindallr>rrrrSrWrUr`r_rrrsrvrrTr r#r&r)r*rrrrrYrrrrrrrrrrrr rrr*r2rErJrRr]rfrkrprzr~rrrrrrrrrrrrrr r r1 mako_templatecheetah_templatejinja2_templater mako_view cheetah_view jinja2_viewr[r]rr responsesr" HTTP_CODESr^rmr2rr=rappsrrfrrrvr-rpr rrs&%%%%%     , $ $ $ zJsx PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP::::::::::''''''++++++++!!!!!!<<<<<<<<<<<<<;;;;;;;;;;<  x!|7P!!!!!!CCCCCCCCPPPPPPPPPP"":AAAJ>>>>>>>>>>;;;;;;......MMM!!!!!! ,C'&&&&&111 JG--J//H D....HMCEWXXXNNNMMM????????JJJJJJJJJJ8888888888,,,,,,''''777777""""""/////v/// $&&CGJD9:v N NOOO**** ++++ 3      $$$$.....6...4     f        V   $     i   DDDDDDDD$$$$$$$$      Z   KKKKKzKKK*****j***BBBH9H9H9H9H9VH9H9H9Vi i i i i Fi i i `T.T.T.T.T.VT.T.T.vBEBEBEBEBE&BEBEBEJ))) V$OOOOO6OOOd???$     ;        L     8_( F F F F F F F F&     /   ))))))))XV,'''''f'''\ddddd dddN,6,6,6,6,6 ,6,6,6\#$#$#$#$#$#$#$#$L9/9/9/9/9/Y9/9/9/v llllllllbt.     f            S>S>S>S>S>fS>S>S>l@5@5@5@5@5@5@5@5N        k)k)k)k)d 6 6 6 ( "*H I I QB    ???++++    @@@@@@ BBB (****>. % $W - - $ $U + + $ $V , , $ $U + + $ $X . . $ $W - - $ $W - - $ $W - - $ $V , , $ $Y / / $ $[ 1 1 $ $Y / /@@@@@Y@@@ yHyHyHyHyHvyHyHyHxnnnnnVnnnp:::::F:::" ( ( ( ( ( ( ( (CCCCC]CCCMB]:M&ZZZZZ]ZZZ >>>>>->>>]-411111M111 # # # # #m # # #     M    ==*$$$$$]$$$022222]222<<<<<<=<<<     =   77777(777.'''''-'''         9 N}    }  [ k} ?} l  l!" l#$! ) 8777(       nnnnb'P'P'P'P'P ('P'P'P\     O   O"O"O"O"O"6O"O"O"d,,,,,<,,,,l*JJJJJ\JJJ:IIIII\IIIX     m   |&|&|&|&|&|&|&|&~+++6" !(\JJJ $9$X6EGGG#)#H~NNN: I d\ B B B  y HHH i~FFF z"      # # % %  3) 3% 33 31 33 3T<<(2(8(8(:(:<<<<<&LM&V ,.. =??  $8::%%s[oh*&<&