f33efe14bff1

bundled: update flask
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Thu, 27 Jan 2011 18:23:59 -0500
parents 3fe8d9b6705b
children 4d308e5f132c
branches/tags (none)
files bundled/flask/.gitignore bundled/flask/.gitmodules bundled/flask/AUTHORS bundled/flask/CHANGES bundled/flask/LICENSE bundled/flask/MANIFEST.in bundled/flask/Makefile bundled/flask/artwork/LICENSE bundled/flask/artwork/logo-full.svg bundled/flask/docs/.gitignore bundled/flask/docs/Makefile bundled/flask/docs/_static/debugger.png bundled/flask/docs/_static/flask.png bundled/flask/docs/_static/flaskr.png bundled/flask/docs/_static/logo-full.png bundled/flask/docs/_static/no.png bundled/flask/docs/_static/touch-icon.png bundled/flask/docs/_static/yes.png bundled/flask/docs/_templates/sidebarintro.html bundled/flask/docs/_templates/sidebarlogo.html bundled/flask/docs/api.rst bundled/flask/docs/becomingbig.rst bundled/flask/docs/changelog.rst bundled/flask/docs/conf.py bundled/flask/docs/config.rst bundled/flask/docs/contents.rst.inc bundled/flask/docs/deploying/cgi.rst bundled/flask/docs/deploying/fastcgi.rst bundled/flask/docs/deploying/index.rst bundled/flask/docs/deploying/mod_wsgi.rst bundled/flask/docs/deploying/others.rst bundled/flask/docs/design.rst bundled/flask/docs/errorhandling.rst bundled/flask/docs/extensiondev.rst bundled/flask/docs/flaskext.py bundled/flask/docs/flaskstyle.sty bundled/flask/docs/foreword.rst bundled/flask/docs/htmlfaq.rst bundled/flask/docs/index.rst bundled/flask/docs/installation.rst bundled/flask/docs/latexindex.rst bundled/flask/docs/license.rst bundled/flask/docs/logo.pdf bundled/flask/docs/make.bat bundled/flask/docs/patterns/appfactories.rst bundled/flask/docs/patterns/caching.rst bundled/flask/docs/patterns/distribute.rst bundled/flask/docs/patterns/errorpages.rst bundled/flask/docs/patterns/fabric.rst bundled/flask/docs/patterns/favicon.rst bundled/flask/docs/patterns/fileuploads.rst bundled/flask/docs/patterns/flashing.rst bundled/flask/docs/patterns/index.rst bundled/flask/docs/patterns/jquery.rst bundled/flask/docs/patterns/lazyloading.rst bundled/flask/docs/patterns/mongokit.rst bundled/flask/docs/patterns/packages.rst bundled/flask/docs/patterns/sqlalchemy.rst bundled/flask/docs/patterns/sqlite3.rst bundled/flask/docs/patterns/templateinheritance.rst bundled/flask/docs/patterns/viewdecorators.rst bundled/flask/docs/patterns/wtforms.rst bundled/flask/docs/quickstart.rst bundled/flask/docs/security.rst bundled/flask/docs/shell.rst bundled/flask/docs/signals.rst bundled/flask/docs/styleguide.rst bundled/flask/docs/templating.rst bundled/flask/docs/testing.rst bundled/flask/docs/tutorial/css.rst bundled/flask/docs/tutorial/dbcon.rst bundled/flask/docs/tutorial/dbinit.rst bundled/flask/docs/tutorial/folders.rst bundled/flask/docs/tutorial/index.rst bundled/flask/docs/tutorial/introduction.rst bundled/flask/docs/tutorial/schema.rst bundled/flask/docs/tutorial/setup.rst bundled/flask/docs/tutorial/templates.rst bundled/flask/docs/tutorial/testing.rst bundled/flask/docs/tutorial/views.rst bundled/flask/docs/unicode.rst bundled/flask/docs/upgrading.rst bundled/flask/examples/flaskr/README bundled/flask/examples/flaskr/flaskr.py bundled/flask/examples/flaskr/flaskr_tests.py bundled/flask/examples/flaskr/schema.sql bundled/flask/examples/flaskr/static/style.css bundled/flask/examples/flaskr/templates/layout.html bundled/flask/examples/flaskr/templates/login.html bundled/flask/examples/flaskr/templates/show_entries.html bundled/flask/examples/jqueryexample/jqueryexample.py bundled/flask/examples/jqueryexample/templates/index.html bundled/flask/examples/jqueryexample/templates/layout.html bundled/flask/examples/minitwit/README bundled/flask/examples/minitwit/minitwit.py bundled/flask/examples/minitwit/minitwit_tests.py bundled/flask/examples/minitwit/schema.sql bundled/flask/examples/minitwit/static/style.css bundled/flask/examples/minitwit/templates/layout.html bundled/flask/examples/minitwit/templates/login.html bundled/flask/examples/minitwit/templates/register.html bundled/flask/examples/minitwit/templates/timeline.html bundled/flask/extreview/approved.rst bundled/flask/extreview/listed.rst bundled/flask/extreview/unlisted.rst bundled/flask/flask.py bundled/flask/flask/__init__.py bundled/flask/flask/app.py bundled/flask/flask/config.py bundled/flask/flask/ctx.py bundled/flask/flask/globals.py bundled/flask/flask/helpers.py bundled/flask/flask/logging.py bundled/flask/flask/module.py bundled/flask/flask/session.py bundled/flask/flask/signals.py bundled/flask/flask/templating.py bundled/flask/flask/testing.py bundled/flask/flask/wrappers.py bundled/flask/setup.py bundled/flask/tests/flask_tests.py bundled/flask/tests/flaskext_test.py bundled/flask/tests/moduleapp/__init__.py bundled/flask/tests/moduleapp/apps/__init__.py bundled/flask/tests/moduleapp/apps/admin/__init__.py bundled/flask/tests/moduleapp/apps/admin/static/css/test.css bundled/flask/tests/moduleapp/apps/admin/static/test.txt bundled/flask/tests/moduleapp/apps/admin/templates/index.html bundled/flask/tests/moduleapp/apps/frontend/__init__.py bundled/flask/tests/moduleapp/apps/frontend/templates/index.html bundled/flask/tests/static/index.html bundled/flask/tests/subdomaintestmodule/__init__.py bundled/flask/tests/subdomaintestmodule/static/hello.txt bundled/flask/tests/templates/_macro.html bundled/flask/tests/templates/context_template.html bundled/flask/tests/templates/escaping_template.html bundled/flask/tests/templates/mail.txt bundled/flask/tests/templates/nested/nested.txt bundled/flask/tests/templates/simple_template.html bundled/flask/tests/templates/template_filter.html bundled/flask/tox.ini

Changes

--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/.gitignore	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,10 @@
+.DS_Store
+*.pyc
+*.pyo
+env
+env*
+dist
+*.egg
+*.egg-info
+_mailinglist
+.tox
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/.gitmodules	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,3 @@
+[submodule "docs/_themes"]
+	path = docs/_themes
+	url = git://github.com/mitsuhiko/flask-sphinx-themes.git
--- a/bundled/flask/AUTHORS	Thu Jan 27 18:15:55 2011 -0500
+++ b/bundled/flask/AUTHORS	Thu Jan 27 18:23:59 2011 -0500
@@ -9,16 +9,22 @@
 Patches and Suggestions
 ```````````````````````
 
+- Adam Zapletal
+- Ali Afshar
 - Chris Edgemon
 - Chris Grindstaff
+- Christopher Grebs
 - Florent Xicluna
 - Georg Brandl
 - Justin Quick
 - Kenneth Reitz
 - Marian Sigler
+- Matt Campell
 - Matthew Frazier
+- Michael van Tellingen
 - Ron DuPlain
 - Sebastien Estienne
 - Simon Sapin
 - Stephane Wirtel
+- Thomas Schranz
 - Zhao Xiaohong
--- a/bundled/flask/CHANGES	Thu Jan 27 18:15:55 2011 -0500
+++ b/bundled/flask/CHANGES	Thu Jan 27 18:23:59 2011 -0500
@@ -3,10 +3,134 @@
 
 Here you can see the full list of changes between each Flask release.
 
+Version 0.7
+-----------
+
+Release date to be announced, codename to be selected
+
+- Added :meth:`~flask.Flask.make_default_options_response`
+  which can be used by subclasses to alter the default
+  behaviour for `OPTIONS` responses.
+- Unbound locals now raise a proper :exc:`RuntimeError` instead
+  of an :exc:`AttributeError`.
+- Mimetype guessing and etag support based on file objects is now
+  deprecated for :func:`flask.send_file` because it was unreliable.
+  Pass filenames instead or attach your own etags and provide a
+  proper mimetype by hand.
+- Static file handling for modules now requires the name of the
+  static folder to be supplied explicitly.  The previous autodetection
+  was not reliable and caused issues on Google's App Engine.  Until
+  1.0 the old behaviour will continue to work but issue dependency
+  warnings.
+- fixed a problem for Flask to run on jython.
+- added a `PROPAGATE_EXCEPTIONS` configuration variable that can be
+  used to flip the setting of exception propagation which previously
+  was linked to `DEBUG` alone and is now linked to either `DEBUG` or
+  `TESTING`.
+- Flask no longer internally depends on rules being added through the
+  `add_url_rule` function and can now also accept regular werkzeug
+  rules added to the url map.
+- Added an `endpoint` method to the flask application object which
+  allows one to register a callback to an arbitrary endpoint with
+  a decorator.
+
+Version 0.6.1
+-------------
+
+Bugfix release, released on December 31st 2010
+
+- Fixed an issue where the default `OPTIONS` response was
+  not exposing all valid methods in the `Allow` header.
+- Jinja2 template loading syntax now allows "./" in front of
+  a template load path.  Previously this caused issues with
+  module setups.
+- Fixed an issue where the subdomain setting for modules was
+  ignored for the static folder.
+- Fixed a security problem that allowed clients to download arbitrary files
+  if the host server was a windows based operating system and the client
+  uses backslashes to escape the directory the files where exposed from.
+
+Version 0.6
+-----------
+
+Released on July 27th 2010, codename Whisky
+
+- after request functions are now called in reverse order of
+  registration.
+- OPTIONS is now automatically implemented by Flask unless the
+  application explicitly adds 'OPTIONS' as method to the URL rule.
+  In this case no automatic OPTIONS handling kicks in.
+- static rules are now even in place if there is no static folder
+  for the module.  This was implemented to aid GAE which will
+  remove the static folder if it's part of a mapping in the .yml
+  file.
+- the :attr:`~flask.Flask.config` is now available in the templates
+  as `config`.
+- context processors will no longer override values passed directly
+  to the render function.
+- added the ability to limit the incoming request data with the
+  new ``MAX_CONTENT_LENGTH`` configuration value.
+- the endpoint for the :meth:`flask.Module.add_url_rule` method
+  is now optional to be consistent with the function of the
+  same name on the application object.
+- added a :func:`flask.make_response` function that simplifies
+  creating response object instances in views.
+- added signalling support based on blinker.  This feature is currently
+  optional and supposed to be used by extensions and applications.  If
+  you want to use it, make sure to have `blinker`_ installed.
+- refactored the way URL adapters are created.  This process is now
+  fully customizable with the :meth:`~flask.Flask.create_url_adapter`
+  method.
+- modules can now register for a subdomain instead of just an URL
+  prefix.  This makes it possible to bind a whole module to a
+  configurable subdomain.
+
+.. _blinker: http://pypi.python.org/pypi/blinker
+
+Version 0.5.2
+-------------
+
+Bugfix Release, released on July 15th 2010
+
+- fixed another issue with loading templates from directories when
+  modules were used.
+
+Version 0.5.1
+-------------
+
+Bugfix Release, released on July 6th 2010
+
+- fixes an issue with template loading from directories when modules
+  where used.
+
+Version 0.5
+-----------
+
+Released on July 6th 2010, codename Calvados
+
+- fixed a bug with subdomains that was caused by the inability to
+  specify the server name.  The server name can now be set with
+  the `SERVER_NAME` config key.  This key is now also used to set
+  the session cookie cross-subdomain wide.
+- autoescaping is no longer active for all templates.  Instead it
+  is only active for ``.html``, ``.htm``, ``.xml`` and ``.xhtml``.
+  Inside templates this behaviour can be changed with the
+  ``autoescape`` tag.
+- refactored Flask internally.  It now consists of more than a
+  single file.
+- :func:`flask.send_file` now emits etags and has the ability to
+  do conditional responses builtin.
+- (temporarily) dropped support for zipped applications.  This was a
+  rarely used feature and led to some confusing behaviour.
+- added support for per-package template and static-file directories.
+- removed support for `create_jinja_loader` which is no longer used
+  in 0.5 due to the improved module support.
+- added a helper function to expose files from any directory.
+
 Version 0.4
 -----------
 
-Release date to be announced, codename to be selected.
+Released on June 18th 2010, codename Rakia
 
 - added the ability to register application wide error handlers
   from modules.
@@ -19,11 +143,12 @@
 - because the Python standard library caches loggers, the name of
   the logger is configurable now to better support unittests.
 - added `TESTING` switch that can activate unittesting helpers.
+- the logger switches to `DEBUG` mode now if debug is enabled.
 
 Version 0.3.1
 -------------
 
-Bugfix release, released May 28th
+Bugfix release, released on May 28th 2010
 
 - fixed a error reporting bug with :meth:`flask.Config.from_envvar`
 - removed some unused code from flask
@@ -34,7 +159,7 @@
 Version 0.3
 -----------
 
-Released on May 28th, codename Schnaps
+Released on May 28th 2010, codename Schnaps
 
 - added support for categories for flashed messages.
 - the application now configures a :class:`logging.Handler` and will
@@ -50,7 +175,7 @@
 Version 0.2
 -----------
 
-Released on May 12th, codename Jägermeister
+Released on May 12th 2010, codename Jägermeister
 
 - various bugfixes
 - integrated JSON support
--- a/bundled/flask/LICENSE	Thu Jan 27 18:15:55 2011 -0500
+++ b/bundled/flask/LICENSE	Thu Jan 27 18:23:59 2011 -0500
@@ -3,9 +3,9 @@
 
 Some rights reserved.
 
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
+Redistribution and use in source and binary forms of the software as well
+as documentation, with or without modification, are permitted provided
+that the following conditions are met:
 
 * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
@@ -19,14 +19,15 @@
   promote products derived from this software without specific
   prior written permission.
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
--- a/bundled/flask/MANIFEST.in	Thu Jan 27 18:15:55 2011 -0500
+++ b/bundled/flask/MANIFEST.in	Thu Jan 27 18:23:59 2011 -0500
@@ -1,9 +1,12 @@
 include Makefile CHANGES LICENSE AUTHORS
+recursive-include artwork *
 recursive-include tests *
 recursive-include examples *
 recursive-include docs *
 recursive-exclude docs *.pyc
 recursive-exclude docs *.pyo
+recursive-exclude tests *.pyc
+recursive-exclude tests *.pyo
 recursive-exclude examples *.pyc
 recursive-exclude examples *.pyo
 prune docs/_build
--- a/bundled/flask/Makefile	Thu Jan 27 18:15:55 2011 -0500
+++ b/bundled/flask/Makefile	Thu Jan 27 18:23:59 2011 -0500
@@ -1,10 +1,19 @@
-.PHONY: clean-pyc test upload-docs
+.PHONY: clean-pyc ext-test test upload-docs docs audit
 
 all: clean-pyc test
 
 test:
 	python setup.py test
 
+audit:
+	python setup.py audit
+
+tox-test:
+	PYTHONDONTWRITEBYTECODE= tox
+
+ext-test:
+	python tests/flaskext_test.py --browse
+
 release:
 	python setup.py release sdist upload
 
@@ -20,3 +29,6 @@
 	scp -r docs/_build/dirhtml/* pocoo.org:/var/www/flask.pocoo.org/docs/
 	scp -r docs/_build/latex/Flask.pdf pocoo.org:/var/www/flask.pocoo.org/docs/flask-docs.pdf
 	scp -r docs/_build/flask-docs.zip pocoo.org:/var/www/flask.pocoo.org/docs/
+
+docs:
+	$(MAKE) -C docs html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/artwork/LICENSE	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,20 @@
+Copyright (c) 2010 by Armin Ronacher.
+
+Some rights reserved.
+
+This logo or a modified version may be used by anyone to refer to the
+Flask project, but does not indicate endorsement by the project.
+
+Redistribution and use in source (the SVG file) and binary forms (rendered
+PNG files etc.) of the image, with or without modification, are permitted
+provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright
+  notice and this list of conditions.
+
+* The names of the contributors to the Flask software (see AUTHORS) may
+  not be used to endorse or promote products derived from this software
+  without specific prior written permission.
+
+Note: we would appreciate that you make the image a link to
+http://flask.pocoo.org/ if you use it on a web page.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/artwork/logo-full.svg	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,290 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="460"
+   height="180"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="logo.svg">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <inkscape:perspective
+       id="perspective2824"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2840"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2878"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2894"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2910"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2926"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2976"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3020"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3036"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3052"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3866"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98994949"
+     inkscape:cx="240.32415"
+     inkscape:cy="-37.836532"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1680"
+     inkscape:window-height="998"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-27.820801,-24.714976)">
+    <path
+       style="fill:#000000"
+       d="M 96.944917,182.03377 C 89.662681,176.30608 81.894549,170.81448 76.586317,163.08166 65.416842,149.44499 56.816875,133.6567 50.937585,117.06515 47.383955,106.27654 46.166898,94.709824 41.585799,84.338096 c -4.792287,-7.533044 0.821224,-15.767897 9.072722,-18.16242 3.673742,-0.705104 10.133327,-4.170258 2.335951,-1.693539 -6.990592,5.128871 -7.667129,-4.655603 -0.498823,-5.27517 4.892026,-0.650249 6.692895,-4.655044 5.019966,-8.260251 -5.251326,-3.424464 12.733737,-7.18801 3.684373,-12.297799 -9.426987,-10.170666 13.186339,-12.128546 7.607283,-0.577786 -1.335447,8.882061 15.801226,-1.627907 11.825117,8.628945 4.041283,4.925694 15.133562,1.1211 14.85838,8.031392 5.887092,0.404678 7.907562,5.358061 13.433992,5.738347 5.72759,2.586557 16.1108,4.624792 18.0598,11.079149 -5.68242,4.498756 -18.84089,-9.292674 -19.47305,3.160397 1.71659,18.396078 1.27926,37.346439 8.00986,54.864989 3.18353,10.60759 10.9012,18.95779 17.87109,27.21946 6.66875,8.09126 15.70186,13.78715 24.90885,18.58338 8.07647,3.80901 16.78383,6.33528 25.58583,7.92044 3.5701,-2.7307 9.87303,-12.8828 15.44238,-8.60188 0.26423,4.81007 -11.0541,10.05512 -0.53248,9.5235 6.17819,-1.86378 10.46336,4.77803 15.55099,-1.21289 4.68719,5.55206 19.48197,-3.54734 16.14693,7.80115 -4.50972,2.90955 -11.08689,1.15142 -15.60404,5.15397 -7.44757,-3.71979 -13.37691,3.32843 -21.6219,2.43707 -9.15641,1.64002 -18.4716,2.30204 -27.75473,2.31642 -15.22952,-1.20328 -30.78158,-1.71049 -45.26969,-7.01291 -8.16166,-2.37161 -16.12649,-7.01887 -23.299683,-11.66829 z m 12.862043,5.5729 c 7.9696,3.44651 15.76243,7.07889 24.49656,8.17457 13.85682,1.92727 28.16653,4.89163 42.07301,2.18757 -6.2939,-2.84199 -12.80077,1.10719 -19.07096,-2.0322 -7.52033,1.61821 -15.59049,-0.41223 -23.23574,-1.41189 -8.69395,-3.87259 -18.0762,-6.53549 -26.21772,-11.56219 -10.173155,-3.71578 5.26142,4.76524 8.00873,5.45214 6.35952,3.60969 -6.99343,-1.85044 -8.87589,-3.35101 -5.32648,-2.9879 -6.00529,-2.36357 -0.52745,0.67085 1.10332,0.64577 2.19359,1.32226 3.34946,1.87216 z M 94.642259,176.88976 c 7.722781,2.86052 -0.03406,-5.43082 -3.572941,-4.94904 -1.567906,-2.72015 -5.9903,-4.43854 -2.870721,-5.89973 -5.611524,1.9481 -5.878319,-7.40814 -8.516004,-6.07139 -5.936516,-1.87454 -2.310496,-8.51501 -9.381929,-12.59292 -0.645488,-4.29697 -7.02577,-8.02393 -9.060801,-14.50525 -0.898786,-3.31843 -7.208336,-12.84783 -3.332369,-3.97927 3.300194,8.53747 9.106618,15.84879 13.93868,23.15175 3.752083,6.95328 8.182497,14.22026 15.015767,18.55788 2.303436,2.20963 4.527452,5.59533 7.780318,6.28797 z M 72.39456,152.46355 c 0.26956,-1.16626 1.412424,2.52422 0,0 z m 31.49641,27.85526 c 1.71013,-0.76577 -2.45912,-0.96476 0,0 z m 4.19228,1.52924 c -0.43419,-2.1116 -1.91376,1.18074 0,0 z m 5.24749,2.18891 c 2.49828,-2.37871 -3.85009,-1.49983 0,0 z m 8.99389,5.01274 c 1.51811,-2.2439 -4.85872,-0.84682 0,0 z m -17.2707,-12.03933 c 3.88031,-2.51023 -5.01186,-0.0347 0,0 z m 3.9366,1.96293 c -0.11004,-1.32709 -1.40297,0.59432 0,0 z m 19.67473,12.28006 c 3.16281,1.99601 18.46961,4.3749 8.88477,0.81847 -1.60377,0.33811 -17.77263,-4.57336 -8.88477,-0.81847 z M 97.430958,166.92721 c -0.307503,-1.33094 -4.909341,-1.4694 0,0 z m 9.159302,5.33813 c 2.38371,-1.66255 -4.94757,-1.28235 0,0 z m 7.70426,4.72382 c 3.42065,-1.28963 -5.54907,-1.29571 0,0 z M 93.703927,162.86805 c 3.711374,2.84621 14.967683,0.36473 5.683776,-1.69906 -4.225516,-2.2524 -13.74889,-3.79415 -7.25757,1.35821 l 1.573785,0.34088 9e-6,-3e-5 z m 25.808723,15.75216 c 1.54595,-2.63388 -6.48298,-1.50411 0,0 z m -7.84249,-6.23284 c 9.0752,2.56719 -7.63142,-5.739 -2.23911,-0.94466 l 1.19513,0.54082 1.04399,0.4039 -1e-5,-6e-5 z m 15.72354,9.0878 c 8.59474,0.082 -7.76304,-1.18486 0,1e-5 l 0,-1e-5 z M 90.396984,157.89545 c -0.335695,-1.60094 -2.120962,0.13419 0,0 z m 51.535396,31.73502 c 0.2292,-2.89141 -2.80486,2.15157 0,0 z m -36.86817,-22.75299 c -0.51986,-1.52251 -2.68548,-0.0622 0,0 z m -13.852128,-9.98649 c 4.934237,-0.29629 -6.755322,-2.17418 0,0 z M 74.802387,146.28394 c -0.614146,-2.36536 -5.369213,-4.2519 0,0 z m 43.079323,27.33941 c -0.90373,-1.0307 -0.4251,0.22546 0,0 z m 26.81408,16.45475 c -0.086,-1.57503 -1.46039,0.59616 0,0 z m -29.18712,-18.90528 c 0.48266,-2.02932 -4.20741,-0.61442 0,0 z M 95.532612,158.51286 c 3.670785,-0.39305 -5.880434,-2.48161 0,0 z M 129.32396,179.51 c 5.72042,-2.26627 -5.57541,-1.10635 0,0 z m -17.57682,-11.93145 c 6.59278,0.85002 -7.84442,-4.48425 -1.44651,-0.4773 l 1.4465,0.47734 1e-5,-4e-5 z m 22.91296,14.0886 c 6.15514,-3.67975 4.12588,8.61677 10.44254,1.0388 6.23086,-4.54942 -5.38086,5.62451 2.29838,0.81116 5.55359,-3.71438 13.75643,1.76075 18.93848,3.5472 3.72659,-0.18307 7.34938,3.22236 11.16973,1.15059 7.3542,-1.98082 -14.38097,-2.93789 -8.68344,-6.4523 -6.72914,1.95848 -11.70093,-2.33483 -15.01213,-6.64508 -7.54812,-1.74298 -16.27548,-5.602 -20.04257,-12.28184 -1.5359,-2.50802 2.21884,0.35333 -1.32586,-3.74638 -4.54834,-4.04546 -6.81948,-8.63766 -9.87278,-13.5552 -3.64755,-1.94587 -4.07249,-7.67345 -4.44123,-0.19201 0.0289,-4.72164 -4.40393,-7.89964 -5.48589,-6.57859 -0.0194,-4.54721 4.74396,-2.26787 1.40945,-5.63228 -0.71771,-4.71302 -3.08085,-9.6241 -3.79115,-14.9453 -1.1036,-2.56502 -0.15541,-8.05863 -3.76662,-2.25204 -1.31566,6.13669 -0.43668,-7.54129 1.6093,-3.03083 2.68543,-4.60251 -0.9641,-4.0612 -1.11361,-3.42211 1.74931,-3.88333 1.10719,-9.39159 -0.45644,-7.29023 0.93213,-4.11586 1.47259,-15.147529 -1.3951,-13.192579 1.73833,-4.303958 3.29668,-19.694077 -4.24961,-13.826325 -3.058358,0.04294 -8.354541,1.110195 -10.858032,2.355243 7.849502,4.326857 -0.789543,1.562577 -3.984808,0.874879 -0.416343,4.003642 -3.58119,2.272086 -7.535123,2.311339 6.315273,0.781339 -3.075253,6.458962 -6.698132,4.253506 -4.705102,2.248756 4.060621,7.862038 0.0944,9.597586 0.487433,2.616581 -7.208227,-0.944906 -6.603832,5.097711 -4.56774,-1.92155 -0.628961,7.16796 1.656273,4.09382 7.768882,2.10261 5.469108,6.89631 5.666947,11.44992 -1.265833,2.6534 -6.249495,-6.23691 -1.109939,-5.82517 -4.054715,-6.58674 -4.485232,-2.38081 -7.854566,0.67911 -0.783857,0.22222 8.5944,4.35376 2.709059,6.3967 5.177884,0.79894 5.325199,5.33008 6.379284,8.19735 3.11219,3.24152 2.475226,-3.57931 6.199071,0.31623 -2.356488,-3.4705 -12.48183,-9.77839 -4.329567,-7.7553 -0.04358,-3.49291 -1.474412,-6.30951 1.02322,-6.24118 2.473367,-4.47926 -2.590385,11.044 2.984725,5.35124 1.543285,-0.67388 1.92554,-4.48494 4.699544,0.35989 4.029096,3.96363 1.45533,6.83577 -4.228162,3.20648 1.016828,3.44946 7.603062,4.68217 6.365348,10.07646 1.3121,4.7444 3.147844,2.99695 4.747999,2.72266 1.25523,4.60973 1.968016,1.2201 2.027559,-0.97355 5.747357,1.23033 4.401142,4.62773 6.199456,7.00134 3.960416,1.78761 -5.668696,-12.11713 1.130659,-4.18106 7.153577,6.4586 2.682797,9.15464 -3.736856,8.11995 4.063129,-0.32824 5.373423,5.49305 10.455693,5.28853 4.63456,2.20477 7.77237,10.67291 -0.21613,7.1478 -2.77074,-2.49821 -12.575734,-5.5801 -4.56731,-0.82823 7.39657,3.42523 13.27117,5.47432 20.40487,9.77384 5.10535,3.64464 7.31104,7.81908 9.24607,8.64541 -4.29084,2.04946 -12.93089,-1.63655 -6.51514,-2.76618 -4.00168,-0.72894 -8.50258,-2.75259 -4.66961,2.2333 3.25926,2.72127 11.54708,2.43298 13.0328,2.74132 -1.25934,2.77488 -3.4207,2.99556 0.0516,3.21078 -3.87375,2.06438 1.24216,2.38403 1.60114,3.56362 z m -7.9215,-22.36993 c -2.35682,-2.46475 -2.9662,-7.08134 -0.41852,-3.06426 1.30648,0.52466 4.18523,7.54428 0.41857,3.06426 l -5e-5,0 z m 25.79733,16.38693 c 1.47004,-0.0952 0.0427,1.11681 0,0 z m -29.51867,-22.43039 c -0.0904,-3.72637 0.8525,2.87419 0,0 z m -2.56392,-3.44965 c -2.96446,-5.72787 3.73721,1.62212 0,0 z M 89.382646,128.35916 c 1.7416,-0.46446 0.856841,2.97864 0,0 z m 24.728294,13.40357 c 1.06957,-4.01654 1.25692,3.37014 0,0 z M 96.64115,129.61525 c -1.231543,-2.21638 2.576009,2.07865 0,0 z m 14.99279,4.80618 c -2.80851,-6.29223 1.98836,-3.43699 0.62135,1.03124 l -0.62135,-1.03124 0,0 z M 85.778757,117.17864 c -1.255624,-2.06432 -3.332663,-8.12135 -2.663982,-9.97042 0.604935,3.0114 6.403914,12.95956 2.844571,4.12096 -3.933386,-7.40908 4.701805,2.40491 5.590052,4.2529 0.413624,1.83837 -2.426789,-0.50225 -0.502192,3.80828 -3.509809,-4.90766 -2.071967,2.71088 -5.268449,-2.21172 z m -7.990701,-5.50612 c 0.328938,-4.79981 1.829262,3.29132 0,0 z m 3.594293,1.23728 c 1.715175,-3.62282 2.908243,5.05052 0,0 z m -8.64616,-6.68847 c -2.974956,-2.95622 -5.127809,-5.68132 0.139193,-1.83474 2.029482,0.0792 -4.509002,-6.19705 0.488751,-1.99305 5.25531,0.95822 2.5951,8.61674 -0.627944,3.82779 z m 4.541717,-0.11873 c 1.727646,-1.71203 0.917172,1.6853 0,0 z m 2.794587,0.8959 c -2.619181,-4.9094 3.178801,2.05822 0,0 z m -5.55546,-5.30909 c -8.64844,-7.696511 10.867309,4.02451 1.4129,1.4269 l -1.412955,-1.42683 5.5e-5,-7e-5 z m 24.77908,14.39717 c -3.742506,-2.24398 -0.991777,-15.79747 0.284503,-6.52785 3.638294,-1.17695 -0.200879,4.78728 2.512784,4.73208 -0.42767,3.76305 -1.64169,5.11594 -2.797287,1.79577 z m 9.165207,5.41684 c 0.36705,-4.08462 0.77249,2.79262 0,0 z m -1.59198,-1.57295 c 0.41206,-1.74497 0.0426,2.05487 0,0 z M 76.213566,99.16032 c -5.556046,-7.665657 16.147323,7.75413 3.558556,1.9443 -1.315432,-0.34404 -2.898208,-0.46688 -3.558556,-1.9443 z m 17.649112,9.35749 c -0.525779,-6.45461 1.174169,1.06991 -1.92e-4,-2e-5 l 1.92e-4,2e-5 z m 13.399762,8.59585 c 1.03698,-3.67668 0.0773,2.43221 0,0 z M 77.064685,96.23472 c 3.302172,-0.706291 13.684695,5.79939 4.150224,1.85832 -1.059396,-1.17279 -3.317802,-0.63994 -4.150224,-1.85832 z m 28.356745,14.13312 c 0.35296,-6.60002 1.97138,-3.94233 0.0122,0.94474 l -0.0121,-0.94473 -5e-5,-1e-5 z M 79.52277,93.938099 c 1.345456,-1.97361 -3.571631,-8.923063 0.708795,-2.492797 1.849543,1.469605 5.355103,2.461959 2.260017,3.080216 4.867744,4.294162 -1.187244,1.163612 -2.968812,-0.587419 z m 24.49612,14.368161 c 0.92952,-7.51843 0.81971,4.40485 0,0 z M 76.712755,86.993902 c 1.027706,-0.439207 0.542746,1.369335 0,0 z m 6.389622,3.803092 c 1.644416,-3.450522 3.03351,3.848297 0,0 z m 18.023553,10.026276 c -0.0174,-1.3252 0.34003,1.92765 0,0 z m -1.04404,-2.31139 c -2.501612,-6.171646 2.32693,3.26759 0,0 z m -1.536003,-4.046372 c -0.419906,-2.550188 1.427129,3.203862 -7.3e-5,-9e-6 l 7.3e-5,9e-6 z m 2.499773,-4.063514 c -1.71663,-3.025123 2.16777,-13.331073 2.60122,-6.939418 -1.81185,4.980256 -0.52268,7.766309 0.74129,1.086388 2.33417,-5.257159 -0.50421,10.374054 -3.34255,5.853057 l 4e-5,-2.7e-5 z m 2.56889,-15.326649 c 0.74833,-0.918921 0.16609,1.107082 0,0 z m -4.290016,84.534235 c -1.017552,-0.88802 0.127775,0.56506 0,0 z m 8.837726,4.47065 c 4.91599,1.26135 4.89086,-0.76487 0.44782,-1.36683 -2.3898,-2.22316 -9.930475,-4.58124 -3.18119,-0.27586 0.44699,1.13227 1.85944,1.10589 2.73337,1.64269 z M 90.708067,152.48725 c 2.708244,2.01956 10.201213,5.72375 3.858186,0.76868 2.138588,-2.48467 -4.093336,-3.80722 -2.026067,-5.46927 -5.258175,-3.21755 -4.147962,-2.93133 -0.464111,-2.8301 -6.319385,-2.82462 0.912163,-2.61333 0.571661,-4.06067 -2.436706,-0.48126 -12.103074,-4.29664 -6.416395,0.31341 -5.780887,-2.94751 -1.377603,1.09799 -3.12488,0.67029 -5.911336,-1.61178 5.264392,4.50224 -0.938845,2.98448 3.391327,2.6875 9.128301,6.88393 1.433786,2.84407 -1.013816,1.45934 5.506273,3.67136 7.106665,4.77911 z m 9.243194,5.31013 c 11.238769,3.62163 -5.510018,-4.4246 0,0 z m 47.316399,28.66432 c 0.14496,-2.22965 -1.53604,1.90201 0,0 z m 4.86324,2.04679 c 2.59297,-2.51255 0.106,4.00222 4.29655,-0.61509 0.0453,-3.30544 -0.12904,-5.25783 -4.81563,-1.24252 -1.29194,0.71648 -1.86871,3.76288 0.51908,1.85761 z M 74.932378,140.02637 c -0.796355,-3.1304 -5.581949,-3.11418 0,0 z m 5.193029,3.40294 c -1.928397,-3.19739 -6.880525,-2.89469 0,0 z m 29.543373,17.81697 c 2.8844,2.56199 13.24761,1.87984 3.50331,0.31527 -1.44321,-2.13386 -9.16415,-1.6203 -3.50331,-0.31527 z m 40.61236,25.08153 c 4.43933,-3.72512 -4.30122,1.66183 0,0 z m 9.2328,6.34473 c 0.0277,-1.19543 -1.91352,0.52338 0,0 z m 0.0142,-1.6736 c 4.91602,-5.20866 -4.76346,0.30807 -4e-5,0 l 4e-5,0 z M 62.15981,129.33339 c -4.189944,-5.97826 -2.604586,-8.66544 -6.645136,-13.54677 -0.764913,-3.73279 -6.931672,-12.20326 -3.189579,-3.22947 3.42754,5.24836 4.446054,13.37434 9.834715,16.77624 z m 95.82635,60.00977 c 9.04429,-5.84575 -3.7125,-2.54641 0,0 z m 6.9041,2.70461 c 4.52911,-3.88867 -2.86491,-0.81334 0,0 z M 73.393094,133.41838 c 1.296204,-1.92838 -3.347642,-0.24666 0,0 z m 90.055596,56.78275 c 4.38526,-2.82746 -1.01036,-2.39335 -0.79483,0.26003 l 0.79484,-0.26003 -1e-5,0 z m -59.51386,-37.51178 c -0.15075,-1.90924 -2.31574,0.16206 0,0 z m 3.67794,2.11629 c -1.16888,-2.36318 -1.79716,0.37121 0,0 z m 62.8725,37.30625 c 5.61806,-4.05283 -3.4056,-0.77594 -1.17927,0.76785 l 1.17927,-0.76785 0,0 z m -2.15131,-1.03979 c 4.57663,-3.83506 -4.83183,1.69954 0,0 z m 10.99163,7.31983 c 3.0728,-2.05816 -3.73316,-0.66575 0,0 z M 76.211249,132.02781 c 4.118965,0.92286 16.460394,10.1439 9.179466,0.63772 -3.728991,-1.10384 -1.492605,-10.21906 -5.29621,-8.60579 2.552972,4.2649 2.100461,6.08018 -3.259642,3.3914 -6.736808,-3.28853 -3.785888,1.6297 -2.469293,2.98518 -1.794185,0.40772 2.373226,1.5572 1.845679,1.59149 z m -18.76588,-14.82026 c 0.737407,-3.04991 -6.789814,-16.77881 -3.554464,-6.87916 1.167861,2.07373 1.049123,6.00387 3.554464,6.87916 z m 34.443451,21.23513 c -2.120989,-1.77378 -0.100792,-0.25103 0,0 z m 5.222997,1.21548 c -0.0027,-3.23079 -5.77326,-1.31196 0,0 z m 45.261473,28.53321 c -0.86326,-2.20739 -3.41229,-0.0512 8e-5,4e-5 l -8e-5,-4e-5 z m 2.17351,1.58769 c -0.32087,-1.23546 -1.25399,0.23848 0,0 z m 17.94015,11.3001 c 1.72546,-1.27472 -2.15318,-0.1628 0,0 z M 66.819057,119.6006 c 4.935243,-1.91072 -5.28775,-1.36248 0,0 z m 71.569733,45.08937 c -0.0549,-3.19499 -3.14622,0.79264 0,0 z M 64.869152,115.05675 c 3.170167,-1.07084 -2.932663,-0.70531 0,0 z m 9.201532,4.45726 c -0.0575,-1.05014 -0.973336,0.39747 0,0 z m 112.231406,68.82181 c 4.0765,-0.8265 13.36606,2.07489 14.86752,-1.08086 -4.95044,-0.12019 -17.12734,-3.49263 -17.70346,0.80479 l 1.08368,0.17072 1.75226,0.10534 0,1e-5 z M 76.995161,120.25099 c 0.07087,-3.23755 -2.524669,-0.12092 0,0 z M 52.801998,103.4687 c -1.098703,-6.16843 -4.178791,-0.93357 0,0 z m 5.769195,1.45013 c 0.07087,-1.9807 -5.280562,-1.78224 0,0 z m 3.296917,1.61923 c -0.953019,-0.77196 -0.745959,0.97521 0,0 z m 20.744719,13.30775 c 0.976615,-0.89718 -2.312116,-0.66455 0,0 z M 59.672204,102.88617 c -0.557624,-4.65897 -6.681999,-0.69805 0,0 z M 47.844441,95.21166 c -0.168219,-2.150189 -1.152625,0.81111 0,0 z m 1.759336,-1.328672 c -0.28703,-2.549584 -1.510515,0.324387 0,0 z m 9.720792,5.802442 c 4.110486,-1.61465 -7.487254,-3.33984 -0.839893,-0.30506 l 0.839893,0.30506 z m 130.097601,80.35913 c 2.63092,-2.4121 -3.34373,-0.74577 0,0 z m 15.71669,8.14691 c 1.05433,-3.1186 -2.65452,0.41058 0,0 z M 60.318012,94.590436 c 0.433018,-3.016773 -3.258762,0.59902 0,0 z M 46.487687,85.324242 c -0.742965,-4.25911 -0.64134,-11.735065 6.465133,-9.208583 -9.485962,1.883339 6.56534,11.790095 4.538357,3.968363 3.988626,0.195294 7.802669,-2.357284 5.709487,1.516403 7.85876,-0.867958 13.307129,-7.682612 20.898169,-6.72768 5.913058,-0.782493 12.378182,-1.375955 18.750257,-3.756157 5.23905,-0.37743 10.28235,-6.018062 7.41068,-9.361383 -7.14456,-0.604513 -14.62339,0.289393 -22.520112,1.858993 -8.750559,1.819117 -16.699014,5.275307 -25.528125,6.758866 -8.605891,1.15604 1.730998,3.185165 -0.734074,3.637227 -4.490681,1.558136 5.355488,2.608852 -0.582182,4.251428 C 57.228283,77.56448 53.411411,76.304535 54.977788,72.440196 46.7341,73.50992 39.490264,76.931325 46.003276,85.320342 l 0.484402,0.0037 9e-6,-2.56e-4 z m 19.864291,-10.1168 c 1.932856,-7.120464 10.355229,5.859274 3.168052,0.945776 -0.858453,-0.642457 -2.2703,-1.166588 -3.168052,-0.945776 z m 0.376038,-3.452197 c 2.789661,-2.078257 1.482964,1.16516 0,0 z m 3.542213,0.05622 c 0.251833,-3.27648 8.108752,1.73455 1.295517,1.179499 l -1.295517,-1.179499 0,0 z m 4.84543,-1.948193 c 1.769481,-2.067535 0.50862,1.83906 0,0 z m 1.239563,-0.83005 c 2.946379,-3.540216 16.68561,-2.259413 6.628966,-0.34519 -2.695543,-2.029363 -4.761797,1.196575 -6.628966,0.34519 z m 17.930017,-2.763886 c -0.448199,-9.670222 8.907771,3.436477 0,0 z m 5.087539,-0.02784 c 1.860022,-4.873906 7.218072,-1.955774 0.860732,-0.979407 0.13805,0.518656 -0.18642,2.516173 -0.860732,0.979407 z M 58.311842,92.088739 c 5.55753,-3.403212 -5.899945,-2.952541 0,0 l 0,0 z m 4.109214,1.141866 c 1.948513,-2.071884 -4.233857,-0.840369 0,0 z M 50.313395,84.63767 c 3.175569,-2.439416 -3.757842,-0.927473 0,0 z M 214.41578,187.30012 c 0.0918,-2.83019 -2.42718,1.27537 0,0 z m -16.67487,-11.37935 c 0.47417,-3.25845 -2.14286,0.28408 0,0 z m 21.26022,12.47672 c 4.43994,0.015 13.45265,-1.37884 3.79217,-1.37442 -1.51594,0.23641 -8.83311,0.18571 -3.79216,1.37439 l -1e-5,3e-5 z M 66.035603,91.23339 c 3.593258,-0.246807 5.621861,-3.963629 -0.694932,-3.749977 -9.789949,-1.013541 8.637508,3.352129 -1.255898,2.10383 -1.329368,0.880346 1.873606,1.889721 1.95083,1.646147 z m 3.164618,1.601748 c -0.375177,-2.307063 -1.111156,1.225591 0,0 z m 3.753896,-10.009901 c 1.559281,-1.934055 -2.157697,-0.517053 0,0 z M 61.003998,62.84999 c 6.412879,-2.181631 15.182392,-4.633087 18.210335,1.074184 -3.081589,-3.70893 -1.24361,-7.360157 1.666959,-1.937407 4.115576,5.486669 6.175915,-2.495489 3.499086,-4.335821 3.050468,3.790246 6.520044,5.581281 2.042429,0.239564 4.865693,-5.852929 -9.742712,0.766433 -13.063105,0.699775 -1.597564,0.717062 -16.493576,3.79889 -12.355704,4.259705 z m 3.75831,-7.197834 c 3.657324,-2.760416 12.648968,1.641989 6.879078,-2.743367 -0.564117,-0.498292 -12.636077,3.325475 -6.879078,2.743367 z m 13.333489,0.550473 c 4.280389,0.109225 -1.84632,-5.750287 3.254304,-3.095159 -0.837696,-2.736627 -5.938558,-3.248956 -8.432316,-4.342312 -1.410474,2.502054 2.870977,7.471102 5.178012,7.437471 z M 67.100291,44.099162 c 1.480803,-2.007406 -2.59521,1.017699 0,0 z m 5.449586,1.304353 c 6.897867,-0.914901 -1.758292,-2.970542 -1.389954,-0.07352 l 1.389954,0.07352 0,-9e-6 z M 62.374386,37.441437 c -4.856866,-6.340205 9.133987,1.065769 4.199411,-5.572646 -4.153254,-3.307245 -8.144297,3.721775 -4.199411,5.572646 z m 62.330124,33.572802 c 2.22762,-3.948988 -9.19697,-5.323011 -1.5009,-1.399578 0.70858,0.236781 0.54821,1.6727 1.5009,1.399578 z"
+       id="path2900" />
+    <g
+       style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+       id="text3850">
+      <path
+         d="m 229.85182,43.77803 c -0.79695,3.140714 -1.28913,8.414146 -1.47656,15.820313 -7e-5,1.453199 -0.65632,2.179761 -1.96875,2.179687 -1.31257,7.4e-5 -2.22663,-0.632738 -2.74219,-1.898437 -1.40631,-3.421796 -2.74225,-5.812419 -4.00781,-7.171875 -1.50006,-1.593666 -3.49225,-2.554603 -5.97656,-2.882813 -2.67193,-0.421789 -9.32818,-0.632726 -19.96875,-0.632812 -2.43754,8.6e-5 -4.03129,0.257898 -4.78125,0.773437 -0.46879,0.32821 -0.70316,1.031335 -0.70313,2.109375 l 0,31.851563 c -3e-5,1.078175 0.67966,1.5938 2.03906,1.546875 4.17184,-0.04682 10.21871,-0.328075 18.14063,-0.84375 1.54682,-0.187449 2.58979,-0.691355 3.12891,-1.511719 0.539,-0.820259 1.06634,-2.941351 1.58203,-6.363281 0.32806,-1.87494 1.42963,-2.601502 3.30468,-2.179688 1.59369,0.328186 2.27338,1.054747 2.03907,2.179688 -1.31256,6.375052 -1.73444,14.671919 -1.26563,24.890627 0.0468,1.21878 -0.72662,1.87503 -2.32031,1.96875 -1.31256,0.14065 -2.13287,-0.56247 -2.46094,-2.10938 -1.2188,-5.859333 -3.48052,-8.988236 -6.78515,-9.386716 -3.30474,-0.398394 -8.68364,-0.597612 -16.13672,-0.597656 -0.84379,4.4e-5 -1.26566,0.304731 -1.26563,0.914062 l 0,31.64063 c -3e-5,2.34375 0.86716,3.9375 2.60156,4.78125 1.35934,0.70313 4.28903,1.33594 8.78907,1.89843 2.29683,0.23438 3.30464,1.24219 3.02343,3.02344 -0.28129,1.54688 -2.34379,2.15625 -6.1875,1.82813 -11.1094,-0.89063 -20.27345,-0.84375 -27.49218,0.14062 -2.01564,0.28125 -3.02345,-0.53906 -3.02344,-2.46094 -1e-5,-1.21874 1.0078,-1.92187 3.02344,-2.10937 4.59373,-0.51562 6.8906,-4.54687 6.89062,-12.09375 l 0,-60.187502 c -2e-5,-3.093671 -0.5508,-5.472575 -1.65234,-7.136719 -1.10158,-1.663977 -3.15236,-3.175695 -6.15235,-4.535156 -1.87501,-0.843661 -2.57813,-1.992098 -2.10937,-3.445313 0.23436,-0.890532 0.60936,-1.382719 1.125,-1.476562 0.46874,-0.140532 1.71092,-0.04678 3.72656,0.28125 2.95311,0.468842 9.91404,0.703217 20.88281,0.703125 12.93746,9.2e-5 24.11713,-0.281158 33.53907,-0.84375 3.14055,-0.187407 4.71086,0.07041 4.71093,0.773437 -7e-5,0.187592 -0.0235,0.375092 -0.0703,0.5625 z"
+         style="font-size:144px;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2830" />
+      <path
+         d="m 275.55495,133.14522 c -4e-5,1.875 -1.05473,2.69531 -3.16407,2.46094 -6.46877,-0.60938 -14.48439,-0.51563 -24.04687,0.28125 -1.92189,0.18749 -3.10548,0.14062 -3.55078,-0.14063 -0.44532,-0.28125 -0.66798,-1.05469 -0.66797,-2.32031 -1e-5,-1.125 1.27733,-2.07422 3.83203,-2.84766 2.55467,-0.77343 3.83202,-3.08202 3.83203,-6.92578 l 0,-63.632812 c -1e-5,-3.796796 -0.55079,-6.585856 -1.65234,-8.367188 -1.10158,-1.781164 -3.03517,-3.163975 -5.80078,-4.148437 -1.45313,-0.515537 -2.1797,-1.242099 -2.17969,-2.179688 -1e-5,-1.406158 1.05468,-2.460845 3.16406,-3.164062 3.18749,-1.031156 6.49217,-2.624904 9.91406,-4.78125 2.81248,-1.687401 4.59373,-2.53115 5.34375,-2.53125 1.73435,1e-4 2.60154,1.195412 2.60157,3.585937 -3e-5,-0.187403 -0.0938,2.156345 -0.28125,7.03125 -0.14065,4.64071 -0.18753,9.211018 -0.14063,13.710938 l 0.28125,62.789062 c -2e-5,2.85939 0.7031,4.9336 2.10938,6.22266 1.40622,1.28906 3.82028,2.14453 7.24218,2.5664 2.10934,0.23438 3.16403,1.03126 3.16407,2.39063 z"
+         style="font-size:144px;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2832" />
+      <path
+         d="m 339.67995,128.43428 c -7e-5,0.98438 -1.79303,2.47266 -5.37891,4.46484 -3.58599,1.99219 -6.45708,2.98828 -8.61328,2.98829 -1.82817,-10e-6 -3.44536,-0.89063 -4.85156,-2.67188 -1.40629,-1.78125 -2.39067,-2.67187 -2.95313,-2.67187 -0.42191,0 -2.64847,0.96094 -6.67969,2.88281 -4.03128,1.92187 -8.08596,2.88281 -12.16406,2.88281 -3.84377,0 -7.0547,-1.125 -9.63281,-3.375 -2.81251,-2.48437 -4.21876,-5.85937 -4.21875,-10.125 -1e-5,-8.10935 9.28123,-13.92185 27.84375,-17.4375 3.18746,-0.60934 4.80465,-1.89841 4.85156,-3.86719 l 0.14063,-4.499997 c 0.28121,-7.687454 -3.11723,-11.5312 -10.19532,-11.53125 -2.01565,5e-5 -3.9258,1.804735 -5.73046,5.414062 -1.80471,3.609416 -4.39456,5.554727 -7.76954,5.835938 -3.84376,0.375038 -5.76563,-1.242148 -5.76562,-4.851563 -1e-5,-2.249954 2.85936,-4.874951 8.57812,-7.875 5.99998,-3.14057 11.7656,-4.710881 17.29688,-4.710937 9.51558,5.6e-5 14.22651,4.523489 14.13281,13.570312 l -0.28125,28.968755 c -0.0469,3.04688 1.24214,4.57032 3.86719,4.57031 0.51557,1e-5 1.49994,-0.11718 2.95312,-0.35156 1.45307,-0.23437 2.29682,-0.35156 2.53125,-0.35157 1.35932,1e-5 2.039,0.91407 2.03907,2.74219 z M 318.0237,112.40303 c 0.0468,-1.17185 -0.2227,-1.94529 -0.8086,-2.32031 -0.58597,-0.37498 -1.51175,-0.44529 -2.77734,-0.21094 -11.2969,2.01565 -16.94533,5.69533 -16.94531,11.03906 -2e-5,5.39064 2.92966,8.08595 8.78906,8.08594 2.34372,1e-5 4.75778,-0.44531 7.24219,-1.33594 2.90621,-1.03124 4.35933,-2.27342 4.35937,-3.72656 z"
+         style="font-size:144px;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2834" />
+      <path
+         d="m 392.13307,120.06709 c -5e-5,4.96876 -1.9102,8.91798 -5.73047,11.84766 -3.82035,2.92969 -9.03519,4.39453 -15.64453,4.39453 -4.40627,0 -8.81252,-0.46875 -13.21875,-1.40625 -3.79688,-0.84375 -6.00001,-1.61719 -6.60937,-2.32031 -0.37501,-0.65625 -0.56251,-3.86718 -0.5625,-9.63281 -1e-5,-2.48436 0.56249,-3.77343 1.6875,-3.86719 1.12499,-0.14061 2.08592,0.46876 2.88281,1.82812 3.51561,6.14064 9.18748,9.21095 17.01562,9.21094 6.60934,1e-5 9.91403,-2.29687 9.91407,-6.89062 -4e-5,-2.01562 -0.75004,-3.70311 -2.25,-5.0625 -1.64066,-1.54686 -4.82816,-3.35155 -9.5625,-5.41407 -6.84377,-3.04685 -11.41408,-5.71872 -13.71094,-8.01562 -2.48439,-2.43747 -3.72657,-5.718716 -3.72656,-9.843752 -1e-5,-5.062455 1.9453,-8.999951 5.83593,-11.8125 3.60936,-2.718695 8.43748,-4.078069 14.48438,-4.078125 3.79684,5.6e-5 7.26559,0.304743 10.40625,0.914062 3.37496,0.60943 5.13277,1.359429 5.27344,2.25 0.37495,2.625051 1.14839,6.421922 2.32031,11.390625 0.14058,0.609416 -0.51567,1.101603 -1.96875,1.476563 -1.54692,0.328165 -2.57817,0.07035 -3.09375,-0.773438 -3.70317,-6.046828 -8.39066,-9.070262 -14.0625,-9.070312 -6.4219,5e-5 -9.63283,2.062548 -9.63281,6.1875 -2e-5,2.296916 0.86716,4.12504 2.60156,5.484375 1.54685,1.171912 5.17966,3.000035 10.89844,5.484372 5.99996,2.57816 10.07808,4.89847 12.23437,6.96094 2.81245,2.6719 4.2187,6.25783 4.21875,10.75781 z"
+         style="font-size:144px;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2836" />
+      <path
+         d="m 473.69557,132.72334 c -7e-5,1.64063 -1.10163,2.50782 -3.30469,2.60157 -3.28131,0.0469 -7.57037,0.28124 -12.86718,0.70312 -2.62506,0.51562 -4.50006,0.1875 -5.625,-0.98437 -7.4063,-7.96875 -13.68754,-16.31249 -18.84375,-25.03125 -0.42191,-0.74998 -0.96097,-1.12498 -1.61719,-1.125 -0.79691,2e-5 -2.17972,0.70315 -4.14844,2.10937 -2.20315,1.21877 -3.30471,2.95315 -3.30469,5.20313 -2e-5,1.59376 0.0469,3.89064 0.14063,6.89062 0.0937,3.00001 0.84372,4.96876 2.25,5.90625 0.98435,0.65626 3.25778,1.17188 6.82031,1.54688 2.20309,0.28125 3.30465,1.10156 3.30469,2.46093 -4e-5,1.07813 -0.17582,1.7461 -0.52734,2.00391 -0.3516,0.25781 -1.27738,0.31641 -2.77735,0.17578 -4.68753,-0.42187 -12.60939,-0.1875 -23.76562,0.70313 -2.81251,0.23437 -4.33595,-0.11719 -4.57032,-1.05469 -0.0937,-0.32813 -0.14063,-0.79688 -0.14062,-1.40625 -1e-5,-1.45312 1.42968,-2.55469 4.28906,-3.30469 2.57811,-0.65624 3.86718,-3.67968 3.86719,-9.07031 l 0,-61.453127 c -1e-5,-3.843671 -0.37501,-6.515543 -1.125,-8.015625 -1.03126,-1.92179 -3.18751,-3.421788 -6.46875,-4.5 -1.54688,-0.515536 -2.32032,-1.242098 -2.32031,-2.179688 -1e-5,-1.359283 1.10155,-2.413969 3.30468,-3.164062 3.51562,-1.17178 6.86718,-2.788966 10.05469,-4.851563 2.57811,-1.6874 4.17186,-2.531149 4.78125,-2.53125 1.92185,1.01e-4 2.88279,1.21885 2.88281,3.65625 -2e-5,-0.328027 -0.0235,1.992283 -0.0703,6.960938 -0.0469,3.421962 -0.0703,8.015707 -0.0703,13.78125 l 0.14062,44.015627 c -2e-5,1.21878 0.3281,1.82815 0.98438,1.82812 0.7031,3e-5 1.78122,-0.60934 3.23437,-1.82812 3.8906,-3.046842 8.67184,-7.031213 14.34375,-11.953127 1.12496,-1.17183 1.68746,-2.109329 1.6875,-2.8125 -4e-5,-1.265577 -1.89848,-2.156201 -5.69531,-2.671875 -1.64066,-0.18745 -2.4141,-1.101512 -2.32031,-2.742188 0.14059,-1.64057 0.9609,-2.343695 2.46094,-2.109375 3.37495,0.468805 8.29682,0.726617 14.76562,0.773438 4.49994,0.04693 8.9765,0.07037 13.42969,0.07031 1.45306,0.04693 2.17962,0.914116 2.17969,2.601563 -7e-5,1.5938 -1.14851,2.460986 -3.44532,2.601562 -3.60943,0.140674 -7.00787,0.960986 -10.19531,2.460938 -4.45317,2.015669 -9.21098,5.554728 -14.27344,10.617187 -0.37504,0.281286 -0.56254,0.632845 -0.5625,1.054685 -4e-5,0.65629 0.79684,2.2266 2.39063,4.71094 5.85933,8.90627 11.39057,15.63283 16.59375,20.17969 3.32806,2.85938 6.44525,4.28907 9.35156,4.28906 2.15618,1e-5 3.49212,0.15235 4.00781,0.45703 0.51556,0.30469 0.77337,1.11329 0.77344,2.42578 z"
+         style="font-size:144px;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2838" />
+    </g>
+    <g
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:89.99999762%;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+       id="text2870"
+       transform="translate(0,4)">
+      <path
+         d="m 285.18048,153.2296 c -2e-5,0.16407 -0.31447,0.33269 -0.94336,0.50586 -0.41017,0.10938 -0.75653,0.48308 -1.03906,1.12109 -1.64064,3.64584 -3.10809,6.58529 -4.40234,8.81836 -0.0274,0.0547 -0.0957,0.0775 -0.20508,0.0684 -0.10028,-0.009 -0.16864,-0.041 -0.20508,-0.0957 -0.21876,-0.32813 -0.77931,-1.47201 -1.68164,-3.43164 -0.82944,-1.80469 -1.27605,-2.70703 -1.33985,-2.70703 -0.10027,0 -0.5879,0.87044 -1.46289,2.61132 -0.99349,1.94141 -1.58138,3.04883 -1.76367,3.32227 -0.0274,0.0638 -0.0912,0.0911 -0.1914,0.082 -0.10027,0 -0.17775,-0.0365 -0.23243,-0.10937 -0.66537,-1.03907 -2.19662,-3.88281 -4.59375,-8.53125 -0.27344,-0.54687 -0.57877,-0.89322 -0.91601,-1.03907 -0.58334,-0.2552 -0.875,-0.44204 -0.875,-0.56054 0,-0.35546 0.19596,-0.51497 0.58789,-0.47852 1.75911,0.1823 3.29947,0.14584 4.62109,-0.10937 0.30078,-0.0547 0.45117,0.0456 0.45117,0.30078 0,0.35548 -0.20508,0.58334 -0.61523,0.68359 -0.53777,0.12761 -0.80665,0.32814 -0.80664,0.60156 -1e-5,0.17319 0.0638,0.4284 0.19141,0.76563 0.32812,0.84766 0.8203,1.92318 1.47656,3.22656 0.65624,1.30339 1.03905,1.95508 1.14844,1.95508 0.0729,0 0.46027,-0.67903 1.16211,-2.03711 0.70181,-1.35807 1.05272,-2.11002 1.05273,-2.25586 -1e-5,-0.35546 -0.1185,-0.73827 -0.35547,-1.14844 -0.28256,-0.60155 -0.61069,-0.96158 -0.98437,-1.08008 -0.60157,-0.20962 -0.90236,-0.4147 -0.90235,-0.61523 -1e-5,-0.36457 0.20507,-0.51496 0.61524,-0.45117 1.40363,0.19142 2.88931,0.15496 4.45703,-0.10938 0.30077,-0.0547 0.45116,0.0365 0.45117,0.27344 -1e-5,0.34637 -0.22332,0.56056 -0.66992,0.64258 -0.52866,0.10027 -0.79298,0.36915 -0.79297,0.80664 -10e-6,0.20964 0.0592,0.45574 0.17773,0.73828 1.40364,3.4362 2.21483,5.1543 2.4336,5.1543 0.082,0 0.4466,-0.66992 1.09375,-2.00977 0.69269,-1.43098 1.17576,-2.58397 1.44922,-3.45898 0.0182,-0.0456 0.0273,-0.0957 0.0273,-0.15039 -2e-5,-0.39192 -0.30536,-0.69726 -0.91602,-0.91602 -0.47397,-0.15494 -0.71095,-0.32811 -0.71093,-0.51953 -2e-5,-0.319 0.15037,-0.44205 0.45117,-0.36914 0.41014,0.0912 1.14842,0.15952 2.21484,0.20508 1.00259,0.0365 1.66339,0.0319 1.98242,-0.0137 0.37368,-0.0456 0.56053,0.0592 0.56055,0.31445 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2877" />
+      <path
+         d="m 297.29376,160.98155 c -1e-5,0.39193 -0.52865,0.87956 -1.58594,1.46289 -1.20313,0.64714 -2.43815,0.97071 -3.70507,0.97071 -1.37631,0 -2.53386,-0.45118 -3.47266,-1.35352 -1.00261,-0.95703 -1.50391,-2.23307 -1.50391,-3.82812 0,-1.80469 0.56055,-3.2539 1.68164,-4.34766 1.04818,-1.02082 2.33333,-1.53124 3.85547,-1.53125 0.90234,1e-5 1.74544,0.28712 2.5293,0.86133 0.70181,0.51042 1.16666,1.09376 1.39453,1.75 0.082,0.22787 0.20507,0.35547 0.36914,0.38281 0.23697,0.0456 0.35546,0.20509 0.35547,0.47852 -10e-6,0.3737 -0.44662,0.69271 -1.33984,0.95703 l -6.30274,1.87304 c 0.41016,2.16928 1.52213,3.25391 3.33594,3.25391 1.04817,0 2.24218,-0.38281 3.58203,-1.14844 0.20051,-0.11848 0.39648,-0.17773 0.58789,-0.17773 0.14582,0 0.21874,0.13216 0.21875,0.39648 z m -3.24023,-5.48242 c -1e-5,-0.50129 -0.20281,-0.94107 -0.6084,-1.31934 -0.40561,-0.37824 -0.90463,-0.56737 -1.49707,-0.56738 -1.67709,10e-6 -2.51563,1.20769 -2.51563,3.62305 l 0,0.32812 3.71875,-1.12109 c 0.60156,-0.17317 0.90234,-0.48762 0.90235,-0.94336 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2879" />
+      <path
+         d="m 311.11603,157.13976 c -2e-5,1.80469 -0.62892,3.31771 -1.88672,4.53906 -1.20314,1.17578 -2.63412,1.76367 -4.29297,1.76367 -0.93881,0 -1.91862,-0.15495 -2.93945,-0.46484 -0.98438,-0.30078 -1.48112,-0.57422 -1.49024,-0.82032 -0.009,-0.20963 -0.005,-0.94335 0.0137,-2.20117 0.0273,-1.54036 0.041,-2.66145 0.041,-3.36328 0,-1.05728 -0.009,-2.59081 -0.0273,-4.60059 -0.0182,-2.00975 -0.0274,-3.34275 -0.0274,-3.99902 0,-0.65623 -0.10026,-1.1074 -0.30078,-1.35351 -0.18229,-0.21874 -0.57878,-0.39191 -1.18945,-0.51954 -0.23698,-0.082 -0.35547,-0.2324 -0.35547,-0.45117 0,-0.19139 0.17773,-0.35089 0.5332,-0.47851 0.51042,-0.18228 1.14388,-0.48762 1.90039,-0.91602 0.60156,-0.33722 0.97526,-0.50584 1.1211,-0.50586 0.28254,2e-5 0.42382,0.23244 0.42383,0.69727 -1e-5,0.0365 -0.0137,0.51043 -0.041,1.42187 -0.0182,0.85679 -0.0228,1.72723 -0.0137,2.61133 l 0.0273,4.73047 c 0,0.44662 0.15494,0.57423 0.46485,0.38281 1.09374,-0.62889 2.23306,-0.94335 3.41796,-0.94336 1.36718,1e-5 2.47916,0.41245 3.33594,1.23731 0.85676,0.82488 1.28514,1.90267 1.28516,3.2334 z m -2.1875,1.21679 c -1e-5,-1.24869 -0.34637,-2.27408 -1.03906,-3.07617 -0.65626,-0.7565 -1.45379,-1.13476 -2.39258,-1.13477 -0.64714,1e-5 -1.28517,0.16863 -1.91407,0.50586 -0.62891,0.33725 -0.94336,0.69272 -0.94335,1.06641 l 0,3.66406 c -1e-5,1.75912 0.97069,2.63868 2.9121,2.63867 1.01172,1e-5 1.82747,-0.32584 2.44727,-0.97753 0.61978,-0.65169 0.92968,-1.5472 0.92969,-2.68653 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2881" />
+      <path
+         d="m 333.23712,161.93858 c 0.0365,0.082 0.0547,0.14128 0.0547,0.17774 -2e-5,0.1914 -0.46486,0.50586 -1.39453,0.94336 -1.07553,0.5013 -1.709,0.75195 -1.90039,0.75195 -0.16408,0 -0.3532,-0.27572 -0.56739,-0.82715 -0.2142,-0.55143 -0.36231,-0.82715 -0.44433,-0.82715 0.009,0 -0.50815,0.23926 -1.55176,0.71778 -1.04363,0.47851 -1.83432,0.71777 -2.37207,0.71777 -1.20313,0 -2.24675,-0.43294 -3.13086,-1.29883 -1.06641,-1.02994 -1.59961,-2.4746 -1.59961,-4.33398 0,-1.55859 0.62891,-2.90299 1.88672,-4.03321 1.11198,-0.99347 2.24674,-1.49022 3.4043,-1.49023 0.8203,1e-5 1.80012,0.10483 2.93945,0.31445 0.35546,0.0638 0.53319,-0.041 0.5332,-0.31445 l 0,-4.67578 c -1e-5,-0.52863 -0.12761,-0.90233 -0.38281,-1.12109 -0.16407,-0.14582 -0.55144,-0.319 -1.16211,-0.51954 -0.29167,-0.10935 -0.43751,-0.28709 -0.4375,-0.5332 -10e-6,-0.22785 0.19596,-0.39647 0.58789,-0.50586 0.53775,-0.16404 1.18033,-0.43748 1.92774,-0.82031 0.61978,-0.32811 1.00259,-0.49217 1.14843,-0.49219 0.33723,2e-5 0.50585,0.23244 0.50586,0.69727 -1e-5,-0.009 -0.0137,0.44435 -0.041,1.36035 -0.0274,0.91603 -0.041,1.80698 -0.041,2.67285 l 0,12.42773 c -10e-6,0.51954 0.23241,0.7793 0.69727,0.7793 0.17316,0 0.40558,-0.0273 0.69726,-0.082 0.319,-0.0547 0.53319,0.0501 0.64258,0.31445 z m -4.22461,-1.35351 0,-4.89453 c -1e-5,-0.40104 -0.35548,-0.81575 -1.0664,-1.24414 -0.75652,-0.45572 -1.57683,-0.68359 -2.46094,-0.6836 -1.90495,1e-5 -2.85743,1.17579 -2.85742,3.52735 -10e-6,1.25781 0.37825,2.33333 1.13476,3.22656 0.75651,0.89323 1.64518,1.33984 2.66602,1.33984 0.46483,0 1.01171,-0.15494 1.64062,-0.46484 0.6289,-0.3099 0.94335,-0.57878 0.94336,-0.80664 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2883" />
+      <path
+         d="m 345.09064,160.98155 c -1e-5,0.39193 -0.52866,0.87956 -1.58594,1.46289 -1.20313,0.64714 -2.43816,0.97071 -3.70508,0.97071 -1.37631,0 -2.53386,-0.45118 -3.47265,-1.35352 -1.00261,-0.95703 -1.50391,-2.23307 -1.50391,-3.82812 0,-1.80469 0.56054,-3.2539 1.68164,-4.34766 1.04817,-1.02082 2.33333,-1.53124 3.85547,-1.53125 0.90233,1e-5 1.74543,0.28712 2.5293,0.86133 0.70181,0.51042 1.16665,1.09376 1.39453,1.75 0.082,0.22787 0.20506,0.35547 0.36914,0.38281 0.23697,0.0456 0.35545,0.20509 0.35547,0.47852 -2e-5,0.3737 -0.44663,0.69271 -1.33985,0.95703 l -6.30273,1.87304 c 0.41015,2.16928 1.52213,3.25391 3.33594,3.25391 1.04816,0 2.24217,-0.38281 3.58203,-1.14844 0.20051,-0.11848 0.39647,-0.17773 0.58789,-0.17773 0.14582,0 0.21874,0.13216 0.21875,0.39648 z m -3.24024,-5.48242 c -10e-6,-0.50129 -0.2028,-0.94107 -0.6084,-1.31934 -0.4056,-0.37824 -0.90462,-0.56737 -1.49707,-0.56738 -1.67708,10e-6 -2.51562,1.20769 -2.51562,3.62305 l 0,0.32812 3.71875,-1.12109 c 0.60155,-0.17317 0.90233,-0.48762 0.90234,-0.94336 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2885" />
+      <path
+         d="m 360.08868,153.20226 c -1e-5,0.17318 -0.28712,0.35092 -0.86132,0.5332 -0.37371,0.10938 -0.69272,0.48308 -0.95704,1.12109 -0.44662,1.07553 -1.22592,2.65235 -2.33789,4.73047 -0.93881,1.75912 -1.66342,3.04427 -2.17382,3.85547 -0.0274,0.0638 -0.0866,0.0911 -0.17774,0.082 -0.0912,-0.009 -0.15951,-0.0456 -0.20508,-0.10937 -1.93229,-2.77995 -3.58659,-5.6237 -4.96289,-8.53125 -0.29167,-0.61979 -0.57878,-0.96614 -0.86133,-1.03907 -0.52864,-0.20962 -0.79296,-0.39647 -0.79296,-0.56054 0,-0.36458 0.17773,-0.52408 0.5332,-0.47852 0.55599,0.0729 1.38086,0.0912 2.47461,0.0547 1.05729,-0.0273 1.80012,-0.082 2.22851,-0.16406 0.26432,-0.0547 0.39648,0.0456 0.39649,0.30078 -10e-6,0.31902 -0.18686,0.5241 -0.56055,0.61523 -0.71094,0.19142 -1.06641,0.43751 -1.0664,0.73828 -1e-5,0.13673 0.0456,0.33269 0.13671,0.58789 0.30989,0.76564 0.86588,1.87078 1.66797,3.31543 0.80208,1.44467 1.25781,2.167 1.36719,2.167 0.082,0 0.46939,-0.69271 1.16211,-2.07813 0.72916,-1.46744 1.25324,-2.65234 1.57227,-3.55469 0.0456,-0.10025 0.0683,-0.20051 0.0684,-0.30078 -1e-5,-0.35546 -0.21876,-0.64712 -0.65625,-0.875 -0.42839,-0.17317 -0.64258,-0.33723 -0.64257,-0.49219 -10e-6,-0.319 0.14126,-0.45116 0.42382,-0.39648 0.36458,0.0638 1.00716,0.1185 1.92774,0.16406 0.92056,0.0456 1.51756,0.0547 1.79101,0.0274 0.33723,-0.0638 0.50585,0.0319 0.50586,0.28711 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2887" />
+      <path
+         d="m 372.21564,160.98155 c -1e-5,0.39193 -0.52866,0.87956 -1.58594,1.46289 -1.20313,0.64714 -2.43816,0.97071 -3.70508,0.97071 -1.37631,0 -2.53386,-0.45118 -3.47265,-1.35352 -1.00261,-0.95703 -1.50391,-2.23307 -1.50391,-3.82812 0,-1.80469 0.56054,-3.2539 1.68164,-4.34766 1.04817,-1.02082 2.33333,-1.53124 3.85547,-1.53125 0.90233,1e-5 1.74543,0.28712 2.5293,0.86133 0.70181,0.51042 1.16665,1.09376 1.39453,1.75 0.082,0.22787 0.20506,0.35547 0.36914,0.38281 0.23697,0.0456 0.35545,0.20509 0.35547,0.47852 -2e-5,0.3737 -0.44663,0.69271 -1.33985,0.95703 l -6.30273,1.87304 c 0.41015,2.16928 1.52213,3.25391 3.33594,3.25391 1.04816,0 2.24217,-0.38281 3.58203,-1.14844 0.20051,-0.11848 0.39647,-0.17773 0.58789,-0.17773 0.14582,0 0.21874,0.13216 0.21875,0.39648 z m -3.24024,-5.48242 c -10e-6,-0.50129 -0.2028,-0.94107 -0.6084,-1.31934 -0.4056,-0.37824 -0.90462,-0.56737 -1.49707,-0.56738 -1.67708,10e-6 -2.51562,1.20769 -2.51562,3.62305 l 0,0.32812 3.71875,-1.12109 c 0.60155,-0.17317 0.90233,-0.48762 0.90234,-0.94336 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2889" />
+      <path
+         d="m 380.66486,162.88194 c -10e-6,0.36459 -0.20509,0.52409 -0.61524,0.47852 -1.25782,-0.11849 -2.81641,-0.10026 -4.67578,0.0547 -0.3737,0.0365 -0.60384,0.0273 -0.69043,-0.0274 -0.0866,-0.0547 -0.12988,-0.20508 -0.12988,-0.45117 0,-0.21875 0.24837,-0.40332 0.74512,-0.55371 0.49674,-0.15039 0.74511,-0.59928 0.74511,-1.34668 l 0,-12.37305 c 0,-0.73826 -0.1071,-1.28058 -0.32129,-1.62695 -0.21419,-0.34634 -0.59017,-0.61522 -1.12793,-0.80664 -0.28255,-0.10024 -0.42383,-0.24152 -0.42382,-0.42383 -1e-5,-0.27342 0.20507,-0.4785 0.61523,-0.61523 0.61979,-0.20051 1.26237,-0.5104 1.92773,-0.92969 0.54687,-0.32811 0.89323,-0.49217 1.03907,-0.49219 0.33723,2e-5 0.50585,0.23244 0.50586,0.69727 -10e-6,-0.0364 -0.0182,0.41929 -0.0547,1.36718 -0.0273,0.90236 -0.0365,1.79104 -0.0273,2.66602 l 0.0547,12.20898 c 0,0.556 0.13672,0.95932 0.41016,1.20997 0.27343,0.25065 0.74283,0.41699 1.4082,0.49902 0.41015,0.0456 0.61523,0.20052 0.61524,0.46484 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2891" />
+      <path
+         d="m 393.9129,157.76866 c -10e-6,1.58594 -0.5879,2.92806 -1.76367,4.02637 -1.17579,1.09831 -2.63412,1.64746 -4.375,1.64746 -1.74089,0 -3.11719,-0.48307 -4.12891,-1.44922 -0.97526,-0.94791 -1.46289,-2.20117 -1.46289,-3.75976 0,-1.61328 0.61524,-2.97135 1.84571,-4.07422 1.194,-1.0664 2.62043,-1.5996 4.27929,-1.59961 1.77734,1e-5 3.16275,0.47852 4.15625,1.43554 0.96614,0.9297 1.44921,2.18751 1.44922,3.77344 z m -2.40625,0.83399 c -10e-6,-1.43099 -0.34636,-2.5931 -1.03906,-3.48633 -0.67449,-0.86588 -1.53126,-1.29882 -2.57031,-1.29883 -0.96615,1e-5 -1.75456,0.33953 -2.36524,1.01855 -0.61068,0.67905 -0.91602,1.5062 -0.91601,2.48145 -1e-5,1.56771 0.35546,2.78907 1.0664,3.66406 0.65625,0.80209 1.51302,1.20313 2.57032,1.20313 1.00259,0 1.79556,-0.33268 2.3789,-0.99805 0.58333,-0.66536 0.87499,-1.52669 0.875,-2.58398 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2893" />
+      <path
+         d="m 408.20001,157.39952 c -1e-5,1.70443 -0.57195,3.15137 -1.71582,4.34082 -1.14389,1.18945 -2.4769,1.78418 -3.99902,1.78418 -0.92058,0 -1.80925,-0.16406 -2.66602,-0.49219 -0.0911,-0.0365 -0.13672,0.18685 -0.13672,0.66993 l 0,4.11523 c 0,0.66536 0.54232,1.09374 1.62696,1.28516 0.50129,0.0911 0.81802,0.17545 0.95019,0.25293 0.13216,0.0775 0.19824,0.20735 0.19824,0.38964 0,0.30989 -0.20508,0.45117 -0.61523,0.42383 -1.91407,-0.12761 -3.59571,-0.082 -5.04492,0.13672 -0.30078,0.0456 -0.48763,0.0456 -0.56055,0 -0.0729,-0.0456 -0.10937,-0.16863 -0.10937,-0.36914 0,-0.15495 0.25976,-0.3418 0.77929,-0.56055 0.44662,-0.18229 0.66992,-0.61979 0.66993,-1.3125 l 0,-12.05859 c -1e-5,-0.97525 -0.26889,-1.58593 -0.80665,-1.83203 -0.63802,-0.28254 -0.95703,-0.51497 -0.95703,-0.69727 0,-0.20051 0.18685,-0.3509 0.56055,-0.45117 0.48307,-0.11848 0.97982,-0.32811 1.49023,-0.62891 0.42839,-0.24608 0.68815,-0.36912 0.7793,-0.36914 0.27344,2e-5 0.49674,0.25067 0.66992,0.75196 0.25521,0.72917 0.42383,1.09376 0.50586,1.09375 0.0182,1e-5 0.41015,-0.21419 1.17578,-0.64258 0.83854,-0.46483 1.65885,-0.69726 2.46094,-0.69727 1.30338,1e-5 2.3789,0.36915 3.22656,1.10743 1.01171,0.86589 1.51757,2.11914 1.51758,3.75976 z m -2.32422,1.09375 c -10e-6,-1.48567 -0.36915,-2.64322 -1.10742,-3.47266 -0.60157,-0.69269 -1.30795,-1.03905 -2.11914,-1.03906 -0.62891,1e-5 -1.23047,0.21876 -1.80469,0.65625 -0.75651,0.56511 -1.13477,1.35353 -1.13476,2.36524 l 0,3.86914 c -1e-5,0.24609 0.34635,0.50586 1.03906,0.77929 0.74739,0.30079 1.55859,0.45118 2.43359,0.45118 1.79557,0 2.69335,-1.20313 2.69336,-3.60938 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2895" />
+      <path
+         d="m 432.90509,162.90929 c -2e-5,0.30078 -0.1413,0.44205 -0.42383,0.42382 -1.85939,-0.13671 -3.59116,-0.13671 -5.19531,0 -0.35549,0.0273 -0.53322,-0.13216 -0.5332,-0.47851 -2e-5,-0.27344 0.24152,-0.41927 0.72461,-0.4375 0.61065,-0.0365 0.91599,-0.5332 0.91601,-1.49024 l 0,-3.63671 c -2e-5,-2.04166 -0.82944,-3.0625 -2.48828,-3.0625 -0.87502,0 -1.6771,0.15951 -2.40625,0.47851 -0.66538,0.28256 -1.00262,0.56511 -1.01172,0.84766 l -0.0547,5.42773 c -10e-6,0.56511 0.0684,0.93881 0.20508,1.1211 0.10025,0.1276 0.32356,0.21875 0.66992,0.27343 0.80207,0.13672 1.20311,0.30534 1.20313,0.50586 -2e-5,0.17318 -0.0228,0.29167 -0.0684,0.35547 -0.0547,0.0911 -0.21877,0.13216 -0.49219,0.12305 -1.03907,-0.0365 -2.55209,-0.0182 -4.53906,0.0547 -0.28256,0.009 -0.46485,-0.0137 -0.54688,-0.0684 -0.082,-0.0547 -0.12305,-0.1823 -0.12304,-0.38282 -10e-6,-0.23697 0.25975,-0.38281 0.77929,-0.4375 0.5651,-0.0638 0.84765,-0.57877 0.84766,-1.54492 l 0,-3.71875 c -10e-6,-1.0026 -0.22787,-1.77733 -0.68359,-2.32422 -0.40105,-0.49218 -0.91147,-0.73827 -1.53125,-0.73828 -0.91147,1e-5 -1.73178,0.18458 -2.46094,0.55371 -0.72917,0.36915 -1.09376,0.76336 -1.09375,1.18262 l 0,4.99023 c -1e-5,0.56511 0.14583,0.95704 0.4375,1.17579 0.26432,0.20052 0.74283,0.32356 1.43555,0.36914 0.37369,0.0182 0.56054,0.14583 0.56054,0.38281 0,0.26432 -0.15039,0.39648 -0.45117,0.39648 -2.27865,0 -3.92839,0.0638 -4.94922,0.19141 -0.34635,0.0456 -0.56966,0.0456 -0.66992,0 -0.082,-0.0456 -0.12305,-0.15495 -0.12305,-0.32813 0,-0.22786 0.33724,-0.42382 1.01172,-0.58789 0.41016,-0.10937 0.61523,-0.64257 0.61524,-1.59961 l 0,-4.19726 c -1e-5,-1.0664 -0.28711,-1.68163 -0.86133,-1.8457 -0.48308,-0.13671 -0.77702,-0.23697 -0.88184,-0.30079 -0.10482,-0.0638 -0.15722,-0.16861 -0.15722,-0.31445 0,-0.16405 0.47395,-0.51041 1.42187,-1.03906 1.0026,-0.56509 1.61784,-0.84765 1.8457,-0.84766 0.19141,1e-5 0.35319,0.27573 0.48536,0.82715 0.13215,0.55144 0.23469,0.82716 0.30761,0.82715 0.10026,10e-6 0.37825,-0.14127 0.83399,-0.42383 0.5651,-0.35546 1.07551,-0.61978 1.53125,-0.79297 0.74739,-0.29165 1.51757,-0.43749 2.31054,-0.4375 0.63802,1e-5 1.194,0.13673 1.66797,0.41016 0.32812,0.1823 0.62434,0.43295 0.88868,0.75195 0.21873,0.27345 0.32811,0.41017 0.32812,0.41016 -10e-6,1e-5 0.23697,-0.13671 0.71094,-0.41016 0.55597,-0.319 1.09829,-0.56965 1.62695,-0.75195 0.77472,-0.27343 1.52668,-0.41015 2.25586,-0.41016 2.49738,1e-5 3.74607,1.37176 3.74609,4.11524 l 0,4.42968 c -2e-5,0.51954 0.12303,0.88868 0.36914,1.10743 0.21873,0.18229 0.64712,0.33724 1.28516,0.46484 0.48305,0.0911 0.72459,0.22787 0.72461,0.41016 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2897" />
+      <path
+         d="m 444.45782,160.98155 c -1e-5,0.39193 -0.52865,0.87956 -1.58593,1.46289 -1.20314,0.64714 -2.43816,0.97071 -3.70508,0.97071 -1.37631,0 -2.53386,-0.45118 -3.47266,-1.35352 -1.0026,-0.95703 -1.5039,-2.23307 -1.5039,-3.82812 0,-1.80469 0.56054,-3.2539 1.68164,-4.34766 1.04817,-1.02082 2.33333,-1.53124 3.85547,-1.53125 0.90233,1e-5 1.74543,0.28712 2.52929,0.86133 0.70182,0.51042 1.16666,1.09376 1.39453,1.75 0.082,0.22787 0.20507,0.35547 0.36914,0.38281 0.23697,0.0456 0.35546,0.20509 0.35547,0.47852 -10e-6,0.3737 -0.44662,0.69271 -1.33984,0.95703 l -6.30273,1.87304 c 0.41015,2.16928 1.52213,3.25391 3.33593,3.25391 1.04817,0 2.24218,-0.38281 3.58203,-1.14844 0.20051,-0.11848 0.39648,-0.17773 0.58789,-0.17773 0.14583,0 0.21874,0.13216 0.21875,0.39648 z m -3.24023,-5.48242 c -10e-6,-0.50129 -0.20281,-0.94107 -0.6084,-1.31934 -0.4056,-0.37824 -0.90463,-0.56737 -1.49707,-0.56738 -1.67709,10e-6 -2.51563,1.20769 -2.51562,3.62305 l 0,0.32812 3.71875,-1.12109 c 0.60155,-0.17317 0.90233,-0.48762 0.90234,-0.94336 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2899" />
+      <path
+         d="m 460.86407,163.03233 c -1e-5,0.28256 -0.20509,0.41016 -0.61523,0.38282 -1.95965,-0.10026 -3.44532,-0.11849 -4.45703,-0.0547 -0.51954,0.0365 -0.80209,-0.0273 -0.84766,-0.19141 -0.0182,-0.0547 -0.0273,-0.13216 -0.0273,-0.23242 -1e-5,-0.18229 0.26431,-0.34635 0.79297,-0.49219 0.48306,-0.13672 0.7246,-0.60612 0.72461,-1.4082 l 0,-3.63672 c -1e-5,-2.08723 -0.90691,-3.13085 -2.72071,-3.13086 -0.8112,1e-5 -1.56315,0.19142 -2.25586,0.57422 -0.65625,0.37371 -0.98438,0.76108 -0.98437,1.16211 l 0,5.00391 c -1e-5,0.85677 0.56054,1.33528 1.68164,1.43554 0.42838,0.0365 0.64257,0.17318 0.64258,0.41016 -10e-6,0.22786 -0.0592,0.36458 -0.17774,0.41016 -0.0547,0.0182 -0.20964,0.0228 -0.46484,0.0137 -1.43099,-0.0547 -2.90756,0.0182 -4.42969,0.21875 -0.32812,0.0456 -0.5332,0.0592 -0.61523,0.041 -0.18229,-0.0365 -0.27344,-0.17773 -0.27344,-0.42383 0,-0.21874 0.25976,-0.40559 0.7793,-0.56054 0.48307,-0.14583 0.7246,-0.75195 0.72461,-1.81836 l 0,-4.14258 c -1e-5,-0.70182 -0.0912,-1.14843 -0.27344,-1.33984 -0.12761,-0.13671 -0.55143,-0.32812 -1.27148,-0.57422 -0.1823,-0.0638 -0.27344,-0.1914 -0.27344,-0.38281 0,-0.18229 0.18685,-0.34179 0.56054,-0.47852 0.51042,-0.1914 1.07097,-0.49674 1.68165,-0.91602 0.51041,-0.34634 0.83853,-0.51952 0.98437,-0.51953 0.24609,1e-5 0.41015,0.28029 0.49219,0.84082 0.082,0.56056 0.19596,0.84083 0.34179,0.84082 -0.0729,1e-5 0.39193,-0.26659 1.39454,-0.7998 1.00259,-0.53319 1.99152,-0.7998 2.96679,-0.79981 2.36067,1e-5 3.55012,1.34441 3.56836,4.03321 l 0.0273,4.40234 c -2e-5,0.56511 0.14582,0.97071 0.4375,1.2168 0.21873,0.18229 0.64256,0.33724 1.27148,0.46484 0.41014,0.082 0.61522,0.23242 0.61523,0.45117 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2901" />
+      <path
+         d="m 469.64142,161.99327 c -10e-6,0.4375 -0.40105,0.8112 -1.20313,1.12109 -0.71094,0.27344 -1.43099,0.41016 -2.16015,0.41016 -1.97787,0 -2.9668,-1.05273 -2.9668,-3.1582 l 0,-4.94922 c 0,-0.6289 -0.0501,-1.01399 -0.15039,-1.15527 -0.10026,-0.14127 -0.43294,-0.28027 -0.99805,-0.417 -0.14583,-0.0365 -0.21875,-0.17772 -0.21875,-0.42382 0,-0.26432 0.0547,-0.42382 0.16407,-0.47852 0.98437,-0.48306 1.84114,-1.34895 2.57031,-2.59766 0.10025,-0.17316 0.29622,-0.22785 0.58789,-0.16406 0.20051,0.0638 0.30533,0.18231 0.31445,0.35547 l 0.0547,1.70898 c -10e-6,0.12762 0.0228,0.21876 0.0684,0.27344 0.0638,0.082 0.20963,0.12306 0.4375,0.12305 l 3.04883,0 c 0.17317,1e-5 0.17317,0.2142 0,0.64258 -0.20965,0.51954 -0.51954,0.7793 -0.92969,0.77929 l -2.06445,0 c -0.35548,1e-5 -0.57423,0.0593 -0.65625,0.17774 -0.0638,0.082 -0.0957,0.30535 -0.0957,0.66992 l 0,4.4707 c 0,1.13021 0.10026,1.84571 0.30078,2.14649 0.26432,0.38281 0.87956,0.57422 1.84571,0.57422 0.319,0 0.70637,-0.0524 1.16211,-0.15723 0.45572,-0.10482 0.69725,-0.15723 0.72461,-0.15723 0.10936,0 0.16405,0.0684 0.16406,0.20508 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2903" />
+      <path
+         d="m 475.84845,162.60851 c -1e-5,2.36979 -0.99805,4.15168 -2.99414,5.3457 -0.18229,0.10937 -0.31446,0.16406 -0.39649,0.16406 -0.1276,0 -0.24609,-0.14584 -0.35546,-0.4375 -0.0365,-0.10026 -0.0547,-0.1823 -0.0547,-0.24609 0,-0.15495 0.25976,-0.41016 0.7793,-0.76563 0.89322,-0.61979 1.33984,-1.32161 1.33984,-2.10547 0,-0.40104 -0.25977,-0.76562 -0.7793,-1.09375 -0.72917,-0.45573 -1.09375,-1.01627 -1.09375,-1.68164 0,-0.44661 0.15039,-0.81803 0.45117,-1.11426 0.30078,-0.29622 0.70182,-0.44433 1.20313,-0.44433 0.60156,0 1.06868,0.21875 1.40137,0.65625 0.33267,0.4375 0.49901,1.01172 0.49902,1.72266 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2905" />
+      <path
+         d="m 278.95978,182.96866 c -1e-5,1.58594 -0.58791,2.92806 -1.76367,4.02637 -1.1758,1.09831 -2.63413,1.64746 -4.375,1.64746 -1.74089,0 -3.1172,-0.48307 -4.12891,-1.44922 -0.97526,-0.94791 -1.46289,-2.20117 -1.46289,-3.75977 0,-1.61327 0.61523,-2.97134 1.8457,-4.07421 1.19401,-1.0664 2.62044,-1.5996 4.2793,-1.59961 1.77733,1e-5 3.16275,0.47852 4.15625,1.43554 0.96613,0.9297 1.44921,2.18751 1.44922,3.77344 z m -2.40625,0.83399 c -1e-5,-1.43099 -0.34637,-2.5931 -1.03906,-3.48633 -0.67449,-0.86588 -1.53126,-1.29882 -2.57032,-1.29883 -0.96615,1e-5 -1.75456,0.33953 -2.36523,1.01855 -0.61068,0.67905 -0.91602,1.5062 -0.91602,2.48145 0,1.56771 0.35547,2.78906 1.06641,3.66406 0.65624,0.80209 1.51301,1.20313 2.57031,1.20313 1.0026,0 1.79557,-0.33268 2.37891,-0.99805 0.58332,-0.66536 0.87499,-1.52669 0.875,-2.58398 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2907" />
+      <path
+         d="m 295.59845,188.23233 c -2e-5,0.28255 -0.20509,0.41016 -0.61523,0.38282 -1.95965,-0.10027 -3.44533,-0.11849 -4.45704,-0.0547 -0.51954,0.0365 -0.80209,-0.0274 -0.84765,-0.19141 -0.0182,-0.0547 -0.0274,-0.13216 -0.0274,-0.23242 -1e-5,-0.18229 0.26432,-0.34635 0.79297,-0.49219 0.48306,-0.13672 0.7246,-0.60612 0.72461,-1.4082 l 0,-3.63672 c -10e-6,-2.08723 -0.90691,-3.13085 -2.7207,-3.13086 -0.81121,1e-5 -1.56316,0.19142 -2.25586,0.57422 -0.65626,0.37371 -0.98438,0.76107 -0.98438,1.16211 l 0,5.00391 c 0,0.85677 0.56055,1.33528 1.68165,1.43554 0.42837,0.0365 0.64257,0.17318 0.64257,0.41016 0,0.22786 -0.0593,0.36458 -0.17773,0.41015 -0.0547,0.0182 -0.20964,0.0228 -0.46484,0.0137 -1.431,-0.0547 -2.90756,0.0182 -4.42969,0.21875 -0.32813,0.0456 -0.53321,0.0592 -0.61524,0.041 -0.18229,-0.0365 -0.27344,-0.17773 -0.27343,-0.42383 -10e-6,-0.21875 0.25976,-0.40559 0.77929,-0.56054 0.48307,-0.14584 0.72461,-0.75195 0.72461,-1.81836 l 0,-4.14258 c 0,-0.70182 -0.0912,-1.14843 -0.27344,-1.33984 -0.1276,-0.13671 -0.55143,-0.32812 -1.27148,-0.57422 -0.18229,-0.0638 -0.27344,-0.1914 -0.27344,-0.38282 0,-0.18228 0.18685,-0.34178 0.56055,-0.47851 0.51041,-0.1914 1.07096,-0.49674 1.68164,-0.91602 0.51041,-0.34634 0.83854,-0.51952 0.98438,-0.51953 0.24608,1e-5 0.41015,0.28029 0.49218,0.84082 0.082,0.56056 0.19596,0.84083 0.3418,0.84082 -0.0729,1e-5 0.39192,-0.26659 1.39453,-0.7998 1.0026,-0.53319 1.99153,-0.7998 2.9668,-0.79981 2.36066,1e-5 3.55011,1.34441 3.56836,4.03321 l 0.0273,4.40234 c -10e-6,0.56511 0.14582,0.9707 0.4375,1.2168 0.21874,0.18229 0.64256,0.33724 1.27149,0.46484 0.41014,0.082 0.61521,0.23242 0.61523,0.45117 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2909" />
+      <path
+         d="m 307.02814,186.18155 c -1e-5,0.39193 -0.52866,0.87956 -1.58594,1.46289 -1.20313,0.64714 -2.43816,0.97071 -3.70508,0.97071 -1.37631,0 -2.53386,-0.45118 -3.47265,-1.35352 -1.00261,-0.95703 -1.50391,-2.23307 -1.50391,-3.82813 0,-1.80468 0.56054,-3.25389 1.68164,-4.34765 1.04817,-1.02082 2.33333,-1.53124 3.85547,-1.53125 0.90233,1e-5 1.74543,0.28712 2.5293,0.86133 0.70181,0.51042 1.16665,1.09376 1.39453,1.75 0.082,0.22787 0.20506,0.35547 0.36914,0.38281 0.23697,0.0456 0.35545,0.20508 0.35547,0.47851 -2e-5,0.37371 -0.44663,0.69272 -1.33985,0.95704 l -6.30273,1.87304 c 0.41015,2.16928 1.52213,3.25391 3.33594,3.25391 1.04816,0 2.24217,-0.38281 3.58203,-1.14844 0.20051,-0.11849 0.39647,-0.17773 0.58789,-0.17773 0.14582,0 0.21874,0.13216 0.21875,0.39648 z m -3.24024,-5.48242 c -10e-6,-0.50129 -0.2028,-0.94107 -0.6084,-1.31934 -0.4056,-0.37824 -0.90462,-0.56737 -1.49707,-0.56738 -1.67708,1e-5 -2.51562,1.20769 -2.51562,3.62305 l 0,0.32812 3.71875,-1.12109 c 0.60155,-0.17317 0.90233,-0.48762 0.90234,-0.94336 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2911" />
+      <path
+         d="m 328.91681,187.13858 c 0.0364,0.082 0.0547,0.14128 0.0547,0.17774 -2e-5,0.1914 -0.46486,0.50586 -1.39453,0.94336 -1.07554,0.5013 -1.709,0.75195 -1.9004,0.75195 -0.16407,0 -0.3532,-0.27572 -0.56738,-0.82715 -0.2142,-0.55143 -0.36231,-0.82715 -0.44433,-0.82715 0.009,0 -0.50815,0.23926 -1.55176,0.71778 -1.04363,0.47851 -1.83432,0.71777 -2.37207,0.71777 -1.20313,0 -2.24675,-0.43294 -3.13086,-1.29883 -1.06641,-1.02994 -1.59961,-2.4746 -1.59961,-4.33398 0,-1.55859 0.6289,-2.90299 1.88672,-4.03321 1.11197,-0.99348 2.24674,-1.49022 3.40429,-1.49023 0.82031,1e-5 1.80013,0.10483 2.93946,0.31445 0.35546,0.0638 0.53319,-0.041 0.5332,-0.31445 l 0,-4.67578 c -1e-5,-0.52863 -0.12761,-0.90233 -0.38281,-1.1211 -0.16407,-0.14581 -0.55144,-0.31899 -1.16211,-0.51953 -0.29168,-0.10935 -0.43751,-0.28709 -0.4375,-0.5332 -10e-6,-0.22785 0.19595,-0.39647 0.58789,-0.50586 0.53775,-0.16404 1.18033,-0.43748 1.92773,-0.82031 0.61978,-0.32811 1.0026,-0.49217 1.14844,-0.49219 0.33723,2e-5 0.50585,0.23244 0.50586,0.69727 -1e-5,-0.009 -0.0137,0.44435 -0.041,1.36035 -0.0274,0.91603 -0.041,1.80698 -0.041,2.67285 l 0,12.42773 c -1e-5,0.51954 0.23241,0.7793 0.69727,0.7793 0.17316,0 0.40558,-0.0273 0.69726,-0.082 0.319,-0.0547 0.53319,0.0501 0.64258,0.31445 z m -4.22461,-1.35351 0,-4.89453 c -1e-5,-0.40104 -0.35548,-0.81575 -1.06641,-1.24414 -0.75651,-0.45572 -1.57683,-0.68359 -2.46093,-0.6836 -1.90496,1e-5 -2.85743,1.17579 -2.85743,3.52735 0,1.25781 0.37826,2.33333 1.13477,3.22656 0.7565,0.89323 1.64518,1.33984 2.66602,1.33984 0.46483,0 1.01171,-0.15494 1.64062,-0.46484 0.6289,-0.3099 0.94335,-0.57878 0.94336,-0.80664 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2913" />
+      <path
+         d="m 339.23907,178.78507 c -1e-5,1.10287 -0.31902,1.6543 -0.95703,1.65429 -0.10027,1e-5 -0.43295,-0.0638 -0.99804,-0.1914 -0.56511,-0.1276 -0.97983,-0.1914 -1.24414,-0.19141 -1.02084,1e-5 -1.53126,0.68816 -1.53125,2.06445 l 0,4.03321 c -10e-6,0.47396 0.16405,0.8112 0.49218,1.01172 0.1914,0.11849 0.66992,0.27799 1.43555,0.47851 0.41015,0.10026 0.61523,0.25521 0.61523,0.46485 0,0.24609 -0.0342,0.3942 -0.10253,0.44433 -0.0684,0.0501 -0.23927,0.0615 -0.5127,0.0342 -2.00521,-0.20963 -3.59115,-0.21875 -4.75781,-0.0273 -0.36459,0.0638 -0.59701,0.0638 -0.69727,0 -0.082,-0.0547 -0.12305,-0.21419 -0.12304,-0.47852 -1e-5,-0.24609 0.25292,-0.44205 0.75878,-0.58789 0.50586,-0.14583 0.75879,-0.58333 0.75879,-1.3125 l 0,-4.38867 c 0,-0.57421 -0.0752,-0.96158 -0.22558,-1.16211 -0.1504,-0.20051 -0.56283,-0.46939 -1.23731,-0.80664 l -0.082,-0.041 c -0.18229,-0.0911 -0.27344,-0.21874 -0.27344,-0.38281 0,-0.18228 0.18685,-0.33723 0.56055,-0.46484 0.6289,-0.21874 1.20312,-0.52864 1.72266,-0.92969 0.42838,-0.33723 0.70182,-0.50585 0.82031,-0.50586 0.32812,1e-5 0.52408,0.28256 0.58789,0.84766 0.082,0.72006 0.17773,1.08008 0.28711,1.08008 0.009,0 0.51953,-0.34179 1.53125,-1.0254 0.66536,-0.4466 1.39452,-0.66991 2.1875,-0.66992 0.65624,1e-5 0.98436,0.35092 0.98437,1.05274 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2915" />
+      <path
+         d="m 352.7879,182.96866 c -10e-6,1.58594 -0.5879,2.92806 -1.76367,4.02637 -1.17579,1.09831 -2.63412,1.64746 -4.375,1.64746 -1.74089,0 -3.11719,-0.48307 -4.12891,-1.44922 -0.97526,-0.94791 -1.46289,-2.20117 -1.46289,-3.75977 0,-1.61327 0.61524,-2.97134 1.84571,-4.07421 1.194,-1.0664 2.62043,-1.5996 4.27929,-1.59961 1.77734,1e-5 3.16275,0.47852 4.15625,1.43554 0.96614,0.9297 1.44921,2.18751 1.44922,3.77344 z m -2.40625,0.83399 c -10e-6,-1.43099 -0.34636,-2.5931 -1.03906,-3.48633 -0.67449,-0.86588 -1.53126,-1.29882 -2.57031,-1.29883 -0.96615,1e-5 -1.75456,0.33953 -2.36524,1.01855 -0.61068,0.67905 -0.91602,1.5062 -0.91601,2.48145 -1e-5,1.56771 0.35546,2.78906 1.0664,3.66406 0.65625,0.80209 1.51302,1.20313 2.57032,1.20313 1.00259,0 1.79556,-0.33268 2.3789,-0.99805 0.58333,-0.66536 0.87499,-1.52669 0.875,-2.58398 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2917" />
+      <path
+         d="m 367.07501,182.59952 c -1e-5,1.70443 -0.57195,3.15137 -1.71582,4.34082 -1.14389,1.18945 -2.4769,1.78418 -3.99902,1.78418 -0.92058,0 -1.80925,-0.16406 -2.66602,-0.49219 -0.0911,-0.0365 -0.13672,0.18685 -0.13672,0.66992 l 0,4.11524 c 0,0.66536 0.54232,1.09374 1.62696,1.28516 0.50129,0.0911 0.81802,0.17544 0.95019,0.25292 0.13216,0.0775 0.19824,0.20736 0.19824,0.38965 0,0.30989 -0.20508,0.45117 -0.61523,0.42383 -1.91407,-0.12761 -3.59571,-0.082 -5.04492,0.13672 -0.30078,0.0456 -0.48763,0.0456 -0.56055,0 -0.0729,-0.0456 -0.10937,-0.16863 -0.10937,-0.36914 0,-0.15495 0.25976,-0.3418 0.77929,-0.56055 0.44662,-0.18229 0.66992,-0.61979 0.66993,-1.3125 l 0,-12.05859 c -1e-5,-0.97525 -0.26889,-1.58593 -0.80665,-1.83203 -0.63802,-0.28254 -0.95703,-0.51497 -0.95703,-0.69727 0,-0.20051 0.18685,-0.3509 0.56055,-0.45117 0.48307,-0.11848 0.97982,-0.32811 1.49023,-0.62891 0.42839,-0.24608 0.68815,-0.36913 0.7793,-0.36914 0.27344,1e-5 0.49674,0.25067 0.66992,0.75196 0.25521,0.72917 0.42383,1.09376 0.50586,1.09375 0.0182,1e-5 0.41015,-0.21419 1.17578,-0.64258 0.83854,-0.46483 1.65885,-0.69726 2.46094,-0.69727 1.30338,1e-5 2.3789,0.36915 3.22656,1.10742 1.01171,0.8659 1.51757,2.11915 1.51758,3.75977 z m -2.32422,1.09375 c -10e-6,-1.48567 -0.36915,-2.64322 -1.10742,-3.47266 -0.60157,-0.6927 -1.30795,-1.03905 -2.11914,-1.03906 -0.62891,1e-5 -1.23047,0.21876 -1.80469,0.65625 -0.75651,0.56511 -1.13477,1.35352 -1.13476,2.36524 l 0,3.86914 c -1e-5,0.24609 0.34635,0.50586 1.03906,0.77929 0.74739,0.30079 1.55859,0.45118 2.43359,0.45118 1.79557,0 2.69335,-1.20313 2.69336,-3.60938 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2919" />
+      <path
+         d="m 387.33673,187.16593 c -10e-6,0.1914 -0.34864,0.48079 -1.0459,0.86816 -0.69727,0.38737 -1.25554,0.58106 -1.6748,0.58106 -0.35548,0 -0.66993,-0.17318 -0.94336,-0.51954 -0.27345,-0.34635 -0.46485,-0.51953 -0.57422,-0.51953 -0.082,0 -0.51498,0.18685 -1.29883,0.56055 -0.78386,0.3737 -1.57227,0.56055 -2.36523,0.56055 -0.7474,0 -1.37175,-0.21875 -1.87305,-0.65625 -0.54688,-0.48308 -0.82031,-1.13932 -0.82031,-1.96875 0,-1.57682 1.80468,-2.70703 5.41406,-3.39063 0.61978,-0.11848 0.93424,-0.36913 0.94336,-0.75195 l 0.0273,-0.875 c 0.0547,-1.49478 -0.60612,-2.24218 -1.98242,-2.24219 -0.39193,1e-5 -0.76335,0.35092 -1.11426,1.05274 -0.35091,0.70183 -0.85449,1.08008 -1.51074,1.13476 -0.7474,0.0729 -1.12109,-0.24153 -1.12109,-0.94336 0,-0.43749 0.55598,-0.94791 1.66797,-1.53125 1.16666,-0.61067 2.28775,-0.916 3.36328,-0.91601 1.85025,1e-5 2.76626,0.87956 2.74804,2.63867 l -0.0547,5.63281 c -0.009,0.59245 0.24152,0.88867 0.75195,0.88867 0.10025,0 0.29166,-0.0228 0.57422,-0.0684 0.28254,-0.0456 0.4466,-0.0683 0.49219,-0.0684 0.26431,1e-5 0.39647,0.17774 0.39648,0.53321 z m -4.21094,-3.11719 c 0.009,-0.22786 -0.0433,-0.37825 -0.15722,-0.45117 -0.11394,-0.0729 -0.29396,-0.0866 -0.54004,-0.041 -2.19662,0.39193 -3.29493,1.10743 -3.29492,2.14649 -10e-6,1.04817 0.56965,1.57226 1.70898,1.57226 0.45572,0 0.92512,-0.0866 1.4082,-0.25976 0.5651,-0.20052 0.84765,-0.44206 0.84766,-0.72461 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2921" />
+      <path
+         d="m 396.52423,187.19327 c -10e-6,0.4375 -0.40105,0.8112 -1.20312,1.12109 -0.71095,0.27344 -1.431,0.41016 -2.16016,0.41016 -1.97787,0 -2.9668,-1.05273 -2.9668,-3.1582 l 0,-4.94922 c 0,-0.6289 -0.0501,-1.01399 -0.15039,-1.15528 -0.10026,-0.14126 -0.43294,-0.28026 -0.99804,-0.41699 -0.14584,-0.0365 -0.21876,-0.17772 -0.21875,-0.42383 -1e-5,-0.26431 0.0547,-0.42381 0.16406,-0.47851 0.98437,-0.48306 1.84114,-1.34895 2.57031,-2.59766 0.10026,-0.17316 0.29622,-0.22785 0.58789,-0.16406 0.20052,0.0638 0.30533,0.1823 0.31445,0.35547 l 0.0547,1.70898 c 0,0.12762 0.0228,0.21876 0.0684,0.27344 0.0638,0.082 0.20963,0.12306 0.4375,0.12305 l 3.04883,0 c 0.17317,1e-5 0.17317,0.2142 0,0.64258 -0.20964,0.51954 -0.51954,0.7793 -0.92969,0.77929 l -2.06445,0 c -0.35548,1e-5 -0.57422,0.0593 -0.65625,0.17774 -0.0638,0.082 -0.0957,0.30534 -0.0957,0.66992 l 0,4.4707 c -1e-5,1.13021 0.10025,1.84571 0.30078,2.14649 0.26431,0.38281 0.87955,0.57422 1.8457,0.57422 0.319,0 0.70637,-0.0524 1.16211,-0.15723 0.45572,-0.10482 0.69726,-0.15723 0.72461,-0.15723 0.10936,0 0.16405,0.0684 0.16406,0.20508 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2923" />
+      <path
+         d="m 416.32111,187.16593 c -2e-5,0.1914 -0.34865,0.48079 -1.0459,0.86816 -0.69728,0.38737 -1.25555,0.58106 -1.67481,0.58106 -0.35547,0 -0.66993,-0.17318 -0.94336,-0.51954 -0.27344,-0.34635 -0.46485,-0.51953 -0.57422,-0.51953 -0.082,0 -0.51498,0.18685 -1.29882,0.56055 -0.78386,0.3737 -1.57227,0.56055 -2.36524,0.56055 -0.7474,0 -1.37175,-0.21875 -1.87304,-0.65625 -0.54688,-0.48308 -0.82032,-1.13932 -0.82032,-1.96875 0,-1.57682 1.80469,-2.70703 5.41407,-3.39063 0.61978,-0.11848 0.93423,-0.36913 0.94335,-0.75195 l 0.0273,-0.875 c 0.0547,-1.49478 -0.60613,-2.24218 -1.98242,-2.24219 -0.39194,1e-5 -0.76335,0.35092 -1.11426,1.05274 -0.35092,0.70183 -0.8545,1.08008 -1.51074,1.13476 -0.7474,0.0729 -1.1211,-0.24153 -1.1211,-0.94336 0,-0.43749 0.55599,-0.94791 1.66797,-1.53125 1.16666,-0.61067 2.28776,-0.916 3.36328,-0.91601 1.85025,1e-5 2.76627,0.87956 2.74805,2.63867 l -0.0547,5.63281 c -0.009,0.59245 0.24153,0.88867 0.75196,0.88867 0.10025,0 0.29165,-0.0228 0.57421,-0.0684 0.28254,-0.0456 0.44661,-0.0683 0.49219,-0.0684 0.26431,1e-5 0.39647,0.17774 0.39649,0.53321 z m -4.21094,-3.11719 c 0.009,-0.22786 -0.0433,-0.37825 -0.15723,-0.45117 -0.11394,-0.0729 -0.29395,-0.0866 -0.54004,-0.041 -2.19662,0.39193 -3.29492,1.10743 -3.29492,2.14649 0,1.04817 0.56966,1.57226 1.70899,1.57226 0.45572,0 0.92512,-0.0866 1.4082,-0.25976 0.5651,-0.20052 0.84765,-0.44206 0.84765,-0.72461 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2925" />
+      <path
+         d="m 432.45392,187.19327 c -10e-6,0.4375 -0.40105,0.8112 -1.20313,1.12109 -0.71094,0.27344 -1.43099,0.41016 -2.16015,0.41016 -1.97787,0 -2.9668,-1.05273 -2.9668,-3.1582 l 0,-4.94922 c 0,-0.6289 -0.0501,-1.01399 -0.15039,-1.15528 -0.10026,-0.14126 -0.43294,-0.28026 -0.99805,-0.41699 -0.14583,-0.0365 -0.21875,-0.17772 -0.21875,-0.42383 0,-0.26431 0.0547,-0.42381 0.16407,-0.47851 0.98437,-0.48306 1.84114,-1.34895 2.57031,-2.59766 0.10025,-0.17316 0.29622,-0.22785 0.58789,-0.16406 0.20051,0.0638 0.30533,0.1823 0.31445,0.35547 l 0.0547,1.70898 c -10e-6,0.12762 0.0228,0.21876 0.0684,0.27344 0.0638,0.082 0.20963,0.12306 0.4375,0.12305 l 3.04883,0 c 0.17317,1e-5 0.17317,0.2142 0,0.64258 -0.20965,0.51954 -0.51954,0.7793 -0.92969,0.77929 l -2.06445,0 c -0.35548,1e-5 -0.57423,0.0593 -0.65625,0.17774 -0.0638,0.082 -0.0957,0.30534 -0.0957,0.66992 l 0,4.4707 c 0,1.13021 0.10026,1.84571 0.30078,2.14649 0.26432,0.38281 0.87956,0.57422 1.84571,0.57422 0.319,0 0.70637,-0.0524 1.16211,-0.15723 0.45572,-0.10482 0.69725,-0.15723 0.72461,-0.15723 0.10936,0 0.16405,0.0684 0.16406,0.20508 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2927" />
+      <path
+         d="m 439.30353,172.66007 c -1e-5,0.41928 -0.15723,0.80893 -0.47168,1.16894 -0.31446,0.36004 -0.65854,0.54006 -1.03223,0.54004 -0.42839,2e-5 -0.7793,-0.12759 -1.05273,-0.38281 -0.27344,-0.25519 -0.41016,-0.58788 -0.41016,-0.99805 0,-0.40102 0.16634,-0.77472 0.49902,-1.12109 0.33268,-0.34634 0.69043,-0.51952 1.07325,-0.51953 0.92968,1e-5 1.39452,0.43751 1.39453,1.3125 z m 1.51758,15.47656 c -0.0456,0.26432 -0.15496,0.41471 -0.32813,0.45117 -0.0456,0.009 -0.26433,0 -0.65625,-0.0273 -1.35808,-0.0911 -2.69336,-0.0729 -4.00586,0.0547 -0.35547,0.0365 -0.57878,0.0228 -0.66992,-0.041 -0.0912,-0.0638 -0.13672,-0.20964 -0.13672,-0.4375 0,-0.20964 0.24154,-0.38281 0.72461,-0.51953 0.52864,-0.15495 0.79297,-0.66081 0.79297,-1.51758 l 0,-3.58203 c 0,-0.72005 -0.0729,-1.22591 -0.21875,-1.51758 -0.20052,-0.40103 -0.61524,-0.70637 -1.24414,-0.91601 -0.28256,-0.10026 -0.42383,-0.25065 -0.42383,-0.45118 0,-0.26431 0.20508,-0.46027 0.61523,-0.58789 0.76563,-0.23697 1.44466,-0.55142 2.03711,-0.94336 0.47396,-0.32811 0.76562,-0.49217 0.875,-0.49218 0.36458,1e-5 0.54232,0.23699 0.53321,0.71093 -0.0365,2.38803 -0.0547,4.82162 -0.0547,7.30078 -10e-6,0.59245 0.0866,1.01628 0.25977,1.27149 0.1914,0.28255 0.55598,0.48307 1.09375,0.60156 0.59244,0.13672 0.86132,0.35091 0.80664,0.64258 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2929" />
+      <path
+         d="m 464.89728,188.10929 c -3e-5,0.30078 -0.1413,0.44205 -0.42383,0.42382 -1.8594,-0.13671 -3.59117,-0.13671 -5.19531,0 -0.35549,0.0274 -0.53322,-0.13216 -0.53321,-0.47851 -1e-5,-0.27344 0.24152,-0.41927 0.72461,-0.4375 0.61066,-0.0365 0.916,-0.5332 0.91602,-1.49024 l 0,-3.63671 c -2e-5,-2.04166 -0.82945,-3.0625 -2.48828,-3.0625 -0.87502,0 -1.6771,0.15951 -2.40625,0.47851 -0.66538,0.28256 -1.00262,0.56511 -1.01172,0.84766 l -0.0547,5.42773 c -10e-6,0.56511 0.0684,0.9388 0.20508,1.1211 0.10025,0.1276 0.32355,0.21875 0.66992,0.27343 0.80207,0.13672 1.20311,0.30534 1.20313,0.50586 -2e-5,0.17318 -0.0228,0.29167 -0.0684,0.35547 -0.0547,0.0911 -0.21877,0.13216 -0.49219,0.12305 -1.03908,-0.0365 -2.5521,-0.0182 -4.53906,0.0547 -0.28256,0.009 -0.46486,-0.0137 -0.54688,-0.0684 -0.082,-0.0547 -0.12305,-0.1823 -0.12304,-0.38282 -10e-6,-0.23698 0.25975,-0.38281 0.77929,-0.4375 0.5651,-0.0638 0.84765,-0.57877 0.84766,-1.54492 l 0,-3.71875 c -10e-6,-1.0026 -0.22788,-1.77733 -0.6836,-2.32422 -0.40105,-0.49218 -0.91146,-0.73827 -1.53125,-0.73828 -0.91146,1e-5 -1.73177,0.18458 -2.46093,0.55371 -0.72917,0.36915 -1.09376,0.76336 -1.09375,1.18262 l 0,4.99023 c -1e-5,0.56511 0.14583,0.95704 0.4375,1.17579 0.26431,0.20052 0.74283,0.32356 1.43554,0.36914 0.37369,0.0182 0.56054,0.14583 0.56055,0.38281 -10e-6,0.26432 -0.1504,0.39648 -0.45117,0.39648 -2.27865,0 -3.92839,0.0638 -4.94922,0.19141 -0.34636,0.0456 -0.56966,0.0456 -0.66992,0 -0.082,-0.0456 -0.12305,-0.15495 -0.12305,-0.32813 0,-0.22786 0.33724,-0.42382 1.01172,-0.58789 0.41015,-0.10937 0.61523,-0.64257 0.61523,-1.59961 l 0,-4.19726 c 0,-1.0664 -0.28711,-1.68163 -0.86132,-1.8457 -0.48308,-0.13672 -0.77702,-0.23698 -0.88184,-0.30079 -0.10482,-0.0638 -0.15723,-0.16861 -0.15723,-0.31445 0,-0.16405 0.47396,-0.51041 1.42188,-1.03906 1.0026,-0.5651 1.61783,-0.84765 1.8457,-0.84766 0.1914,1e-5 0.35319,0.27573 0.48535,0.82715 0.13216,0.55144 0.2347,0.82716 0.30762,0.82715 0.10026,1e-5 0.37825,-0.14127 0.83399,-0.42383 0.56509,-0.35546 1.07551,-0.61978 1.53125,-0.79297 0.74738,-0.29165 1.51756,-0.43749 2.31054,-0.4375 0.63801,1e-5 1.194,0.13673 1.66797,0.41016 0.32811,0.1823 0.62434,0.43295 0.88867,0.75195 0.21874,0.27345 0.32812,0.41017 0.32813,0.41016 -10e-6,1e-5 0.23696,-0.13671 0.71094,-0.41016 0.55597,-0.319 1.09829,-0.56965 1.62695,-0.75195 0.77472,-0.27343 1.52667,-0.41015 2.25586,-0.41016 2.49737,1e-5 3.74607,1.37176 3.74609,4.11524 l 0,4.42968 c -2e-5,0.51954 0.12303,0.88868 0.36914,1.10743 0.21873,0.18229 0.64712,0.33724 1.28516,0.46484 0.48305,0.0911 0.72458,0.22786 0.72461,0.41016 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2931" />
+      <path
+         d="m 476.45001,186.18155 c -1e-5,0.39193 -0.52865,0.87956 -1.58594,1.46289 -1.20313,0.64714 -2.43815,0.97071 -3.70507,0.97071 -1.37631,0 -2.53386,-0.45118 -3.47266,-1.35352 -1.00261,-0.95703 -1.50391,-2.23307 -1.50391,-3.82813 0,-1.80468 0.56055,-3.25389 1.68164,-4.34765 1.04818,-1.02082 2.33333,-1.53124 3.85547,-1.53125 0.90234,1e-5 1.74544,0.28712 2.5293,0.86133 0.70181,0.51042 1.16666,1.09376 1.39453,1.75 0.082,0.22787 0.20507,0.35547 0.36914,0.38281 0.23697,0.0456 0.35546,0.20508 0.35547,0.47851 -10e-6,0.37371 -0.44662,0.69272 -1.33984,0.95704 l -6.30274,1.87304 c 0.41016,2.16928 1.52213,3.25391 3.33594,3.25391 1.04817,0 2.24218,-0.38281 3.58203,-1.14844 0.20051,-0.11849 0.39648,-0.17773 0.58789,-0.17773 0.14582,0 0.21874,0.13216 0.21875,0.39648 z m -3.24023,-5.48242 c -1e-5,-0.50129 -0.20281,-0.94107 -0.6084,-1.31934 -0.40561,-0.37824 -0.90463,-0.56737 -1.49707,-0.56738 -1.67709,1e-5 -2.51563,1.20769 -2.51563,3.62305 l 0,0.32812 3.71875,-1.12109 c 0.60156,-0.17317 0.90234,-0.48762 0.90235,-0.94336 z"
+         style="font-size:28px;font-variant:normal;font-stretch:normal;text-align:end;line-height:89.99999762%;writing-mode:lr-tb;text-anchor:end;font-family:High Tower Text;-inkscape-font-specification:High Tower Text"
+         id="path2933" />
+    </g>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/.gitignore	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+_build
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/Makefile	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,118 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp epub latex changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Flask.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Flask.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) _build/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/Flask"
+	@echo "# ln -s _build/devhelp $$HOME/.local/share/devhelp/Flask"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+latexpdf: latex
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
+	@echo "Running LaTeX files through pdflatex..."
+	make -C _build/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in _build/latex."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
Binary file bundled/flask/docs/_static/debugger.png has changed
Binary file bundled/flask/docs/_static/flask.png has changed
Binary file bundled/flask/docs/_static/flaskr.png has changed
Binary file bundled/flask/docs/_static/logo-full.png has changed
Binary file bundled/flask/docs/_static/no.png has changed
Binary file bundled/flask/docs/_static/touch-icon.png has changed
Binary file bundled/flask/docs/_static/yes.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/_templates/sidebarintro.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,21 @@
+<h3>About Flask</h3>
+<p>
+  Flask is a micro webdevelopment framework for Python.  You are currently
+  looking at the documentation of the development version.  Things are
+  not stable yet, but if you have some feedback,
+  <a href="mailto:armin.ronacher@active-4.com">let me know</a>.
+</p>
+<h3>Other Formats</h3>
+<p>
+  You can download the documentation in other formats as well:
+</p>
+<ul>
+  <li><a href="http://flask.pocoo.org/docs/flask-docs.pdf">as PDF</a>
+  <li><a href="http://flask.pocoo.org/docs/flask-docs.zip">as zipped HTML</a>
+</ul>
+<h3>Useful Links</h3>
+<ul>
+  <li><a href="http://flask.pocoo.org/">The Flask Website</a></li>
+  <li><a href="http://pypi.python.org/pypi/Flask">Flask @ PyPI</a></li>
+  <li><a href="http://github.com/mitsuhiko/flask">Flask @ github</a></li>
+</ul>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/_templates/sidebarlogo.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,3 @@
+<p class="logo"><a href="{{ pathto(master_doc) }}">
+  <img class="logo" src="{{ pathto('_static/flask.png', 1) }}" alt="Logo"/>
+</a></p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/api.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,441 @@
+.. _api:
+
+API
+===
+
+.. module:: flask
+
+This part of the documentation covers all the interfaces of Flask.  For
+parts where Flask depends on external libraries, we document the most
+important right here and provide links to the canonical documentation.
+
+
+Application Object
+------------------
+
+.. autoclass:: Flask
+   :members:
+   :inherited-members:
+
+
+Module Objects
+--------------
+
+.. autoclass:: Module
+   :members:
+   :inherited-members:
+
+Incoming Request Data
+---------------------
+
+.. autoclass:: Request
+
+.. class:: request
+
+   To access incoming request data, you can use the global `request`
+   object.  Flask parses incoming request data for you and gives you
+   access to it through that global object.  Internally Flask makes
+   sure that you always get the correct data for the active thread if you
+   are in a multithreaded environment.
+
+   This is a proxy.  See :ref:`notes-on-proxies` for more information.
+
+   The request object is an instance of a :class:`~werkzeug.Request`
+   subclass and provides all of the attributes Werkzeug defines.  This
+   just shows a quick overview of the most important ones.
+
+   .. attribute:: form
+
+      A :class:`~werkzeug.MultiDict` with the parsed form data from `POST`
+      or `PUT` requests.  Please keep in mind that file uploads will not
+      end up here,  but instead in the :attr:`files` attribute.
+
+   .. attribute:: args
+
+      A :class:`~werkzeug.MultiDict` with the parsed contents of the query
+      string.  (The part in the URL after the question mark).
+
+   .. attribute:: values
+
+      A :class:`~werkzeug.CombinedMultiDict` with the contents of both
+      :attr:`form` and :attr:`args`.
+
+   .. attribute:: cookies
+
+      A :class:`dict` with the contents of all cookies transmitted with
+      the request.
+
+   .. attribute:: stream
+
+      If the incoming form data was not encoded with a known mimetype
+      the data is stored unmodified in this stream for consumption.  Most
+      of the time it is a better idea to use :attr:`data` which will give
+      you that data as a string.  The stream only returns the data once.
+
+   .. attribute:: data
+
+      Contains the incoming request data as string in case it came with
+      a mimetype Flask does not handle.
+
+   .. attribute:: files
+
+      A :class:`~werkzeug.MultiDict` with files uploaded as part of a
+      `POST` or `PUT` request.  Each file is stored as
+      :class:`~werkzeug.FileStorage` object.  It basically behaves like a
+      standard file object you know from Python, with the difference that
+      it also has a :meth:`~werkzeug.FileStorage.save` function that can
+      store the file on the filesystem.
+
+   .. attribute:: environ
+
+      The underlying WSGI environment.
+
+   .. attribute:: method
+
+      The current request method (``POST``, ``GET`` etc.)
+
+   .. attribute:: path
+   .. attribute:: script_root
+   .. attribute:: url
+   .. attribute:: base_url
+   .. attribute:: url_root
+
+      Provides different ways to look at the current URL.  Imagine your
+      application is listening on the following URL::
+
+          http://www.example.com/myapplication
+
+      And a user requests the following URL::
+
+          http://www.example.com/myapplication/page.html?x=y
+
+      In this case the values of the above mentioned attributes would be
+      the following:
+
+      ============= ======================================================
+      `path`        ``/page.html``
+      `script_root` ``/myapplication``
+      `base_url`    ``http://www.example.com/myapplication/page.html``
+      `url`         ``http://www.example.com/myapplication/page.html?x=y``
+      `url_root`    ``http://www.example.com/myapplication/``
+      ============= ======================================================
+
+   .. attribute:: is_xhr
+
+      `True` if the request was triggered via a JavaScript
+      `XMLHttpRequest`. This only works with libraries that support the
+      ``X-Requested-With`` header and set it to `XMLHttpRequest`.
+      Libraries that do that are prototype, jQuery and Mochikit and
+      probably some more.
+
+   .. attribute:: json
+
+      Contains the parsed body of the JSON request if the mimetype of
+      the incoming data was `application/json`.  This requires Python 2.6
+      or an installed version of simplejson.
+
+Response Objects
+----------------
+
+.. autoclass:: flask.Response
+   :members: set_cookie, data, mimetype
+
+   .. attribute:: headers
+
+      A :class:`Headers` object representing the response headers.
+
+   .. attribute:: status_code
+
+      The response status as integer.
+
+
+Sessions
+--------
+
+If you have the :attr:`Flask.secret_key` set you can use sessions in Flask
+applications.  A session basically makes it possible to remember
+information from one request to another.  The way Flask does this is by
+using a signed cookie.  So the user can look at the session contents, but
+not modify it unless he knows the secret key, so make sure to set that to
+something complex and unguessable.
+
+To access the current session you can use the :class:`session` object:
+
+.. class:: session
+
+   The session object works pretty much like an ordinary dict, with the
+   difference that it keeps track on modifications.
+
+   This is a proxy.  See :ref:`notes-on-proxies` for more information.
+
+   The following attributes are interesting:
+
+   .. attribute:: new
+
+      `True` if the session is new, `False` otherwise.
+
+   .. attribute:: modified
+
+      `True` if the session object detected a modification.  Be advised
+      that modifications on mutable structures are not picked up
+      automatically, in that situation you have to explicitly set the
+      attribute to `True` yourself.  Here an example::
+
+          # this change is not picked up because a mutable object (here
+          # a list) is changed.
+          session['objects'].append(42)
+          # so mark it as modified yourself
+          session.modified = True
+
+   .. attribute:: permanent
+
+      If set to `True` the session lives for
+      :attr:`~flask.Flask.permanent_session_lifetime` seconds.  The
+      default is 31 days.  If set to `False` (which is the default) the
+      session will be deleted when the user closes the browser.
+
+
+Application Globals
+-------------------
+
+To share data that is valid for one request only from one function to
+another, a global variable is not good enough because it would break in
+threaded environments.  Flask provides you with a special object that
+ensures it is only valid for the active request and that will return
+different values for each request.  In a nutshell: it does the right
+thing, like it does for :class:`request` and :class:`session`.
+
+.. data:: g
+
+   Just store on this whatever you want.  For example a database
+   connection or the user that is currently logged in.
+
+   This is a proxy.  See :ref:`notes-on-proxies` for more information.
+
+
+Useful Functions and Classes
+----------------------------
+
+.. data:: current_app
+
+   Points to the application handling the request.  This is useful for
+   extensions that want to support multiple applications running side
+   by side.
+
+   This is a proxy.  See :ref:`notes-on-proxies` for more information.
+
+.. autofunction:: url_for
+
+.. function:: abort(code)
+
+   Raises an :exc:`~werkzeug.exception.HTTPException` for the given
+   status code.  For example to abort request handling with a page not
+   found exception, you would call ``abort(404)``.
+
+   :param code: the HTTP error code.
+
+.. autofunction:: redirect
+
+.. autofunction:: make_response
+
+.. autofunction:: send_file
+
+.. autofunction:: send_from_directory
+
+.. autofunction:: escape
+
+.. autoclass:: Markup
+   :members: escape, unescape, striptags
+
+Message Flashing
+----------------
+
+.. autofunction:: flash
+
+.. autofunction:: get_flashed_messages
+
+Returning JSON
+--------------
+
+.. autofunction:: jsonify
+
+.. data:: json
+
+    If JSON support is picked up, this will be the module that Flask is
+    using to parse and serialize JSON.  So instead of doing this yourself::
+
+        try:
+            import simplejson as json
+        except ImportError:
+            import json
+
+    You can instead just do this::
+
+        from flask import json
+
+    For usage examples, read the :mod:`json` documentation.
+
+    The :func:`~json.dumps` function of this json module is also available
+    as filter called ``|tojson`` in Jinja2.  Note that inside `script`
+    tags no escaping must take place, so make sure to disable escaping
+    with ``|safe`` if you intend to use it inside `script` tags:
+
+    .. sourcecode:: html+jinja
+
+        <script type=text/javascript>
+            doSomethingWith({{ user.username|tojson|safe }});
+        </script>
+
+    Note that the ``|tojson`` filter escapes forward slashes properly.
+
+Template Rendering
+------------------
+
+.. autofunction:: render_template
+
+.. autofunction:: render_template_string
+
+.. autofunction:: get_template_attribute
+
+Configuration
+-------------
+
+.. autoclass:: Config
+   :members:
+
+Useful Internals
+----------------
+
+.. data:: _request_ctx_stack
+
+   The internal :class:`~werkzeug.LocalStack` that is used to implement
+   all the context local objects used in Flask.  This is a documented
+   instance and can be used by extensions and application code but the
+   use is discouraged in general.
+
+   The following attributes are always present on each layer of the
+   stack:
+
+   `app`
+      the active Flask application.
+
+   `url_adapter`
+      the URL adapter that was used to match the request.
+
+   `request`
+      the current request object.
+
+   `session`
+      the active session object.
+
+   `g`
+      an object with all the attributes of the :data:`flask.g` object.
+
+   `flashes`
+      an internal cache for the flashed messages.
+
+   Example usage::
+
+      from flask import _request_ctx_stack
+
+      def get_session():
+          ctx = _request_ctx_stack.top
+          if ctx is not None:
+              return ctx.session
+
+   .. versionchanged:: 0.4
+
+   The request context is automatically popped at the end of the request
+   for you.  In debug mode the request context is kept around if
+   exceptions happen so that interactive debuggers have a chance to
+   introspect the data.  With 0.4 this can also be forced for requests
+   that did not fail and outside of `DEBUG` mode.  By setting
+   ``'flask._preserve_context'`` to `True` on the WSGI environment the
+   context will not pop itself at the end of the request.  This is used by
+   the :meth:`~flask.Flask.test_client` for example to implement the
+   deferred cleanup functionality.
+
+   You might find this helpful for unittests where you need the
+   information from the context local around for a little longer.  Make
+   sure to properly :meth:`~werkzeug.LocalStack.pop` the stack yourself in
+   that situation, otherwise your unittests will leak memory.
+
+Signals
+-------
+
+.. when modifying this list, also update the one in signals.rst
+
+.. versionadded:: 0.6
+
+.. data:: signals_available
+
+   `True` if the signalling system is available.  This is the case
+   when `blinker`_ is installed.
+
+.. data:: template_rendered
+
+   This signal is sent when a template was successfully rendered.  The
+   signal is invoked with the instance of the template as `template`
+   and the context as dictionary (named `context`).
+
+.. data:: request_started
+
+   This signal is sent before any request processing started but when the
+   request context was set up.  Because the request context is already
+   bound, the subscriber can access the request with the standard global
+   proxies such as :class:`~flask.request`.
+
+.. data:: request_finished
+
+   This signal is sent right before the response is sent to the client.
+   It is passed the response to be sent named `response`.
+
+.. data:: got_request_exception
+
+   This signal is sent when an exception happens during request processing.
+   It is sent *before* the standard exception handling kicks in and even
+   in debug mode, where no exception handling happens.  The exception
+   itself is passed to the subscriber as `exception`.
+
+.. currentmodule:: None
+
+.. class:: flask.signals.Namespace
+
+   An alias for :class:`blinker.base.Namespace` if blinker is available,
+   otherwise a dummy class that creates fake signals.  This class is
+   available for Flask extensions that want to provide the same fallback
+   system as Flask itself.
+
+   .. method:: signal(name, doc=None)
+
+      Creates a new signal for this namespace if blinker is available,
+      otherwise returns a fake signal that has a send method that will
+      do nothing but will fail with a :exc:`RuntimeError` for all other
+      operations, including connecting.
+
+.. _blinker: http://pypi.python.org/pypi/blinker
+
+.. _notes-on-proxies:
+
+Notes On Proxies
+----------------
+
+Some of the objects provided by Flask are proxies to other objects.  The
+reason behind this is that these proxies are shared between threads and
+they have to dispatch to the actual object bound to a thread behind the
+scenes as necessary.
+
+Most of the time you don't have to care about that, but there are some
+exceptions where it is good to know that this object is an actual proxy:
+
+-   The proxy objects do not fake their inherited types, so if you want to
+    perform actual instance checks, you have to do that on the instance
+    that is being proxied (see `_get_current_object` below).
+-   if the object reference is important (so for example for sending
+    :ref:`signals`)
+
+If you need to get access to the underlying object that is proxied, you
+can use the :meth:`~werkzeug.LocalProxy._get_current_object` method::
+
+    app = current_app._get_current_object()
+    my_signal.send(app)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/becomingbig.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,88 @@
+.. _becomingbig:
+
+Becoming Big
+============
+
+Your application is becoming more and more complex?  If you suddenly
+realize that Flask does things in a way that does not work out for your
+application there are ways to deal with that.
+
+Flask is powered by Werkzeug and Jinja2, two libraries that are in use at
+a number of large websites out there and all Flask does is bring those
+two together.  Being a microframework Flask does not do much more than
+combining existing libraries - there is not a lot of code involved.
+What that means for large applications is that it's very easy to take the
+code from Flask and put it into a new module within the applications and
+expand on that.
+
+Flask is designed to be extended and modified in a couple of different
+ways:
+
+-   Flask extensions.  For a lot of reusable functionality you can create
+    extensions.  For extensions a number of hooks exist throughout Flask
+    with signals and callback functions.
+
+-   Subclassing.  The majority of functionality can be changed by creating
+    a new subclass of the :class:`~flask.Flask` class and overriding
+    methods provided for this exact purpose.
+
+-   Forking.  If nothing else works out you can just take the Flask
+    codebase at a given point and copy/paste it into your application
+    and change it.  Flask is designed with that in mind and makes this
+    incredible easy.  You just have to take the package and copy it
+    into your application's code and rename it (for example to
+    `framework`).  Then you can start modifying the code in there.
+
+Why consider Forking?
+---------------------
+
+The majority of code of Flask is within Werkzeug and Jinja2.  These
+libraries do the majority of the work.  Flask is just the paste that glues
+those together.  For every project there is the point where the underlying
+framework gets in the way (due to assumptions the original developers
+had).  This is natural because if this would not be the case, the
+framework would be a very complex system to begin with which causes a
+steep learning curve and a lot of user frustration.
+
+This is not unique to Flask.  Many people use patched and modified
+versions of their framework to counter shortcomings.  This idea is also
+reflected in the license of Flask.  You don't have to contribute any
+changes back if you decide to modify the framework.
+
+The downside of forking is of course that Flask extensions will most
+likely break because the new framework has a different import name.
+Furthermore integrating upstream changes can be a complex process,
+depending on the number of changes.  Because of that, forking should be
+the very last resort.
+
+Scaling like a Pro
+------------------
+
+For many web applications the complexity of the code is less an issue than
+the scaling for the number of users or data entries expected.  Flask by
+itself is only limited in terms of scaling by your application code, the
+data store you want to use and the Python implementation and webserver you
+are running on.
+
+Scaling well means for example that if you double the amount of servers
+you get about twice the performance.  Scaling bad means that if you add a
+new server the application won't perform any better or would not even
+support a second server.
+
+There is only one limiting factor regarding scaling in Flask which are
+the context local proxies.  They depend on context which in Flask is
+defined as being either a thread, process or greenlet.  If your server
+uses some kind of concurrency that is not based on threads or greenlets,
+Flask will no longer be able to support these global proxies.  However the
+majority of servers are using either threads, greenlets or separate
+processes to achieve concurrency which are all methods well supported by
+the underlying Werkzeug library.
+
+Dialogue with the Community
+---------------------------
+
+The Flask developers are very interested to keep everybody happy, so as
+soon as you find an obstacle in your way, caused by Flask, don't hesitate
+to contact the developers on the mailinglist or IRC channel.  The best way
+for the Flask and Flask-extension developers to improve it for larger
+applications is getting feedback from users.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/changelog.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+.. include:: ../CHANGES
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/conf.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,267 @@
+# -*- coding: utf-8 -*-
+#
+# Flask documentation build configuration file, created by
+# sphinx-quickstart on Tue Apr  6 15:24:58 2010.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+sys.path.append(os.path.abspath('_themes'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Flask'
+copyright = u'2010, Armin Ronacher'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+import pkg_resources
+try:
+    release = pkg_resources.get_distribution('Flask').version
+except pkg_resources.DistributionNotFound:
+    print 'To build the documentation, The distribution information of Flask'
+    print 'Has to be available.  Either install the package into your'
+    print 'development environment or run "setup.py develop" to setup the'
+    print 'metadata.  A virtualenv is recommended!'
+    sys.exit(1)
+del pkg_resources
+
+if 'dev' in release:
+    release = release.split('dev')[0] + 'dev'
+version = '.'.join(release.split('.')[:2])
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'flask'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+html_theme_options = {
+    'touch_icon':   'touch-icon.png'
+}
+
+# Add any paths that contain custom themes here, relative to this directory.
+html_theme_path = ['_themes']
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.  Do not set, template magic!
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+html_sidebars = {
+    'index':    ['sidebarintro.html', 'sourcelink.html', 'searchbox.html'],
+    '**':       ['sidebarlogo.html', 'localtoc.html', 'relations.html',
+                 'sourcelink.html', 'searchbox.html']
+}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+html_use_modindex = False
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+html_show_sphinx = False
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Flaskdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('latexindex', 'Flask.tex', u'Flask Documentation',
+   u'Armin Ronacher', 'manual'),
+]
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+latex_use_modindex = False
+
+latex_elements = {
+    'fontpkg':      r'\usepackage{mathpazo}',
+    'papersize':    'a4paper',
+    'pointsize':    '12pt',
+    'preamble':     r'\usepackage{flaskstyle}'
+}
+latex_use_parts = True
+
+latex_additional_files = ['flaskstyle.sty', 'logo.pdf']
+
+
+# -- Options for Epub output ---------------------------------------------------
+
+# Bibliographic Dublin Core info.
+#epub_title = ''
+#epub_author = ''
+#epub_publisher = ''
+#epub_copyright = ''
+
+# The language of the text. It defaults to the language option
+# or en if the language is not set.
+#epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+#epub_scheme = ''
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#epub_identifier = ''
+
+# A unique identification for the text.
+#epub_uid = ''
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_pre_files = []
+
+# HTML files shat should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+#epub_exclude_files = []
+
+# The depth of the table of contents in toc.ncx.
+#epub_tocdepth = 3
+
+intersphinx_mapping = {
+    'http://docs.python.org/dev': None,
+    'http://werkzeug.pocoo.org/docs/': None,
+    'http://www.sqlalchemy.org/docs/': None,
+    'http://wtforms.simplecodes.com/docs/0.5/': None,
+    'http://discorporate.us/projects/Blinker/docs/1.1/': None
+}
+
+pygments_style = 'flask_theme_support.FlaskyStyle'
+
+# fall back if theme is not there
+try:
+    __import__('flask_theme_support')
+except ImportError, e:
+    print '-' * 74
+    print 'Warning: Flask themes unavailable.  Building with default theme'
+    print 'If you want the Flask themes, run this command and build again:'
+    print
+    print '  git submodule update --init'
+    print '-' * 74
+
+    pygments_style = 'tango'
+    html_theme = 'default'
+    html_theme_options = {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/config.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,236 @@
+.. _config:
+
+Configuration Handling
+======================
+
+.. versionadded:: 0.3
+
+Applications need some kind of configuration.  There are different things
+you might want to change like toggling debug mode, the secret key, and a
+lot of very similar things.
+
+The way Flask is designed usually requires the configuration to be
+available when the application starts up.  You can hardcode the
+configuration in the code, which for many small applications is not
+actually that bad, but there are better ways.
+
+Independent of how you load your config, there is a config object
+available which holds the loaded configuration values:
+The :attr:`~flask.Flask.config` attribute of the :class:`~flask.Flask`
+object.  This is the place where Flask itself puts certain configuration
+values and also where extensions can put their configuration values.  But
+this is also where you can have your own configuration.
+
+Configuration Basics
+--------------------
+
+The :attr:`~flask.Flask.config` is actually a subclass of a dictionary and
+can be modified just like any dictionary::
+
+    app = Flask(__name__)
+    app.config['DEBUG'] = True
+
+Certain configuration values are also forwarded to the
+:attr:`~flask.Flask` object so that you can read and write them from
+there::
+
+    app.debug = True
+
+To update multiple keys at once you can use the :meth:`dict.update`
+method::
+
+    app.config.update(
+        DEBUG=True,
+        SECRET_KEY='...'
+    )
+
+Builtin Configuration Values
+----------------------------
+
+The following configuration values are used internally by Flask:
+
+.. tabularcolumns:: |p{6.5cm}|p{8.5cm}|
+
+=============================== =========================================
+``DEBUG``                       enable/disable debug mode
+``TESTING``                     enable/disable testing mode
+``PROPAGATE_EXCEPTIONS``        explicitly enable or disable the
+                                propagation of exceptions.  If not set or
+                                explicitly set to `None` this is
+                                implicitly true if either `TESTING` or
+                                `DEBUG` is true.
+``SECRET_KEY``                  the secret key
+``SESSION_COOKIE_NAME``         the name of the session cookie
+``PERMANENT_SESSION_LIFETIME``  the lifetime of a permanent session as
+                                :class:`datetime.timedelta` object.
+``USE_X_SENDFILE``              enable/disable x-sendfile
+``LOGGER_NAME``                 the name of the logger
+``SERVER_NAME``                 the name of the server.  Required for
+                                subdomain support (e.g.: ``'localhost'``)
+``MAX_CONTENT_LENGTH``          If set to a value in bytes, Flask will
+                                reject incoming requests with a
+                                content length greater than this by
+                                returning a 413 status code.
+=============================== =========================================
+
+.. admonition:: More on ``SERVER_NAME``
+
+   The ``SERVER_NAME`` key is used for the subdomain support.  Because
+   Flask cannot guess the subdomain part without the knowledge of the
+   actual server name, this is required if you want to work with
+   subdomains.  This is also used for the session cookie.
+
+   Please keep in mind that not only Flask has the problem of not knowing
+   what subdomains are, your web browser does as well.  Most modern web
+   browsers will not allow cross-subdomain cookies to be set on a
+   server name without dots in it.  So if your server name is
+   ``'localhost'`` you will not be able to set a cookie for
+   ``'localhost'`` and every subdomain of it.  Please chose a different
+   server name in that case, like ``'myapplication.local'`` and add
+   this name + the subdomains you want to use into your host config
+   or setup a local `bind`_.
+
+.. _bind: https://www.isc.org/software/bind
+
+.. versionadded:: 0.4
+   ``LOGGER_NAME``
+
+.. versionadded:: 0.5
+   ``SERVER_NAME``
+
+.. versionadded:: 0.6
+   ``MAX_CONTENT_LENGTH``
+
+.. versionadded:: 0.7
+   ``PROPAGATE_EXCEPTIONS``
+
+Configuring from Files
+----------------------
+
+Configuration becomes more useful if you can configure from a file, and
+ideally that file would be outside of the actual application package so that
+you can install the package with distribute (:ref:`distribute-deployment`)
+and still modify that file afterwards.
+
+So a common pattern is this::
+
+    app = Flask(__name__)
+    app.config.from_object('yourapplication.default_settings')
+    app.config.from_envvar('YOURAPPLICATION_SETTINGS')
+
+This first loads the configuration from the
+`yourapplication.default_settings` module and then overrides the values
+with the contents of the file the :envvar:`YOURAPPLICATION_SETTINGS`
+environment variable points to.  This environment variable can be set on
+Linux or OS X with the export command in the shell before starting the
+server::
+
+    $ export YOURAPPLICATION_SETTINGS=/path/to/settings.cfg
+    $ python run-app.py
+     * Running on http://127.0.0.1:5000/
+     * Restarting with reloader...
+
+On Windows systems use the `set` builtin instead::
+
+    >set YOURAPPLICATION_SETTINGS=\path\to\settings.cfg
+
+The configuration files themselves are actual Python files.  Only values
+in uppercase are actually stored in the config object later on.  So make
+sure to use uppercase letters for your config keys.
+
+Here is an example configuration file::
+
+    DEBUG = False
+    SECRET_KEY = '?\xbf,\xb4\x8d\xa3"<\x9c\xb0@\x0f5\xab,w\xee\x8d$0\x13\x8b83'
+
+Make sure to load the configuration very early on so that extensions have
+the ability to access the configuration when starting up.  There are other
+methods on the config object as well to load from individual files.  For a
+complete reference, read the :class:`~flask.Config` object's
+documentation.
+
+
+Configuration Best Practices
+----------------------------
+
+The downside with the approach mentioned earlier is that it makes testing
+a little harder.  There is no one 100% solution for this problem in
+general, but there are a couple of things you can do to improve that
+experience:
+
+1.  create your application in a function and register modules on it.
+    That way you can create multiple instances of your application with
+    different configurations attached which makes unittesting a lot
+    easier.  You can use this to pass in configuration as needed.
+
+2.  Do not write code that needs the configuration at import time.  If you
+    limit yourself to request-only accesses to the configuration you can
+    reconfigure the object later on as needed.
+
+
+Development / Production
+------------------------
+
+Most applications need more than one configuration.  There will at least
+be a separate configuration for a production server and one used during
+development.  The easiest way to handle this is to use a default
+configuration that is always loaded and part of version control, and a
+separate configuration that overrides the values as necessary as mentioned
+in the example above::
+
+    app = Flask(__name__)
+    app.config.from_object('yourapplication.default_settings')
+    app.config.from_envvar('YOURAPPLICATION_SETTINGS')
+
+Then you just have to add a separate `config.py` file and export
+``YOURAPPLICATION_SETTINGS=/path/to/config.py`` and you are done.  However
+there are alternative ways as well.  For example you could use imports or
+subclassing.
+
+What is very popular in the Django world is to make the import explicit in
+the config file by adding an ``from yourapplication.default_settings
+import *`` to the top of the file and then overriding the changes by hand.
+You could also inspect an environment variable like
+``YOURAPPLICATION_MODE`` and set that to `production`, `development` etc
+and import different hardcoded files based on that.
+
+An interesting pattern is also to use classes and inheritance for
+configuration::
+
+    class Config(object):
+        DEBUG = False
+        TESTING = False
+        DATABASE_URI = 'sqlite://:memory:'
+
+    class ProductionConfig(Config):
+        DATABASE_URI = 'mysql://user@localhost/foo'
+    
+    class DevelopmentConfig(Config):
+        DEBUG = True
+
+    class TestinConfig(Config):
+        TESTING = True
+
+To enable such a config you just have to call into
+:meth:`~flask.Config.from_object`::
+
+    app.config.from_object('configmodule.ProductionConfig')
+
+There are many different ways and it's up to you how you want to manage
+your configuration files.  However here a list of good recommendations:
+
+-   keep a default configuration in version control.  Either populate the
+    config with this default configuration or import it in your own
+    configuration files before overriding values.
+-   use an environment variable to switch between the configurations.
+    This can be done from outside the Python interpreter and makes
+    development and deployment much easier because you can quickly and
+    easily switch between different configs without having to touch the
+    code at all.  If you are working often on different projects you can
+    even create your own script for sourcing that activates a virtualenv
+    and exports the development configuration for you.
+-   Use a tool like `fabric`_ in production to push code and
+    configurations separately to the production server(s).  For some
+    details about how to do that, head over to the :ref:`deploy` pattern.
+
+.. _fabric: http://fabfile.org/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/contents.rst.inc	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,52 @@
+User's Guide
+------------
+
+This part of the documentation, which is mostly prose, begins with some
+background information about Flask, then focuses on step-by-step
+instructions for web development with Flask.
+
+.. toctree::
+   :maxdepth: 2
+
+   foreword
+   installation
+   quickstart
+   tutorial/index
+   templating
+   testing
+   errorhandling
+   config
+   signals
+   shell
+   patterns/index
+   deploying/index
+   becomingbig
+
+API Reference
+-------------
+
+If you are looking for information on a specific function, class or
+method, this part of the documentation is for you.
+
+.. toctree::
+   :maxdepth: 2
+
+   api
+
+Additional Notes
+----------------
+
+Design notes, legal information and changelog are here for the interested.
+
+.. toctree::
+   :maxdepth: 2
+
+   design
+   htmlfaq
+   security
+   unicode
+   extensiondev
+   styleguide
+   upgrading
+   changelog
+   license
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/deploying/cgi.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,47 @@
+CGI
+===
+
+If all other deployment methods do not work, CGI will work for sure.  CGI
+is supported by all major servers but usually has a less-than-optimal
+performance.
+
+This is also the way you can use a Flask application on Google's
+`App Engine`_, there however the execution does happen in a CGI-like
+environment.  The application's performance is unaffected because of that.
+
+.. admonition:: Watch Out
+
+   Please make sure in advance that your ``app.run()`` call you might
+   have in your application file, is inside an ``if __name__ ==
+   '__main__':`` or moved to a separate file.  Just make sure it's not
+   called because this will always start a local WSGI server which we do
+   not want if we deploy that application to CGI / app engine.
+
+.. _App Engine: http://code.google.com/appengine/
+
+Creating a `.cgi` file
+----------------------
+
+First you need to create the CGI application file.  Let's call it
+`yourapplication.cgi`::
+
+    #!/usr/bin/python
+    from wsgiref.handlers import CGIHandler
+    from yourapplication import app
+
+    CGIHandler().run(app)
+
+Server Setup
+------------
+
+Usually there are two ways to configure the server.  Either just copy the
+`.cgi` into a `cgi-bin` (and use `mod_rewrite` or something similar to
+rewrite the URL) or let the server point to the file directly.
+
+In Apache for example you can put a like like this into the config:
+
+.. sourcecode:: apache
+
+    ScriptAlias /app /path/to/the/application.cgi
+
+For more information consult the documentation of your webserver.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/deploying/fastcgi.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,139 @@
+FastCGI
+=======
+
+A very popular deployment setup on servers like `lighttpd`_ and `nginx`_
+is FastCGI.  To use your WSGI application with any of them you will need
+a FastCGI server first.
+
+The most popular one is `flup`_ which we will use for this guide.  Make
+sure to have it installed.
+
+.. admonition:: Watch Out
+
+   Please make sure in advance that your ``app.run()`` call you might
+   have in your application file, is inside an ``if __name__ ==
+   '__main__':`` or moved to a separate file.  Just make sure it's not
+   called because this will always start a local WSGI server which we do
+   not want if we deploy that application to FastCGI.
+
+Creating a `.fcgi` file
+-----------------------
+
+First you need to create the FastCGI server file.  Let's call it
+`yourapplication.fcgi`::
+
+    #!/usr/bin/python
+    from flup.server.fcgi import WSGIServer
+    from yourapplication import app
+
+    WSGIServer(app).run()
+
+This is enough for Apache to work, however lighttpd and nginx need a
+socket to communicate with the FastCGI server.  For that to work you
+need to pass the path to the socket to the
+:class:`~flup.server.fcgi.WSGIServer`::
+
+    WSGIServer(application, bindAddress='/path/to/fcgi.sock').run()
+
+The path has to be the exact same path you define in the server
+config.
+
+Save the `yourapplication.fcgi` file somewhere you will find it again.
+It makes sense to have that in `/var/www/yourapplication` or something
+similar.
+
+Make sure to set the executable bit on that file so that the servers
+can execute it:
+
+.. sourcecode:: text
+
+    # chmod +x /var/www/yourapplication/yourapplication.fcgi
+
+Configuring lighttpd
+--------------------
+
+A basic FastCGI configuration for lighttpd looks like that::
+
+    fastcgi.server = ("/yourapplication" =>
+        "yourapplication" => (
+            "socket" => "/tmp/yourapplication-fcgi.sock",
+            "bin-path" => "/var/www/yourapplication/yourapplication.fcgi",
+            "check-local" => "disable"
+        )
+    )
+
+This configuration binds the application to `/yourapplication`.  If you
+want the application to work in the URL root you have to work around a
+lighttpd bug with the :class:`~werkzeug.contrib.fixers.LighttpdCGIRootFix`
+middleware.
+
+Make sure to apply it only if you are mounting the application the URL
+root.
+
+Configuring nginx
+-----------------
+
+Installing FastCGI applications on nginx is a bit different because by default
+no FastCGI parameters are forwarded.
+
+A basic flask FastCGI configuration for nginx looks like this::
+
+    location = /yourapplication { rewrite ^ /yourapplication/ last; }
+    location /yourapplication { try_files $uri @yourapplication; }
+    location @yourapplication {
+        include fastcgi_params;
+	fastcgi_split_path_info ^(/yourapplication)(.*)$;
+        fastcgi_param PATH_INFO $fastcgi_path_info;
+        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
+        fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
+    }
+
+This configuration binds the application to `/yourapplication`.  If you want
+to have it in the URL root it's a bit simpler because you don't have to figure
+out how to calculate `PATH_INFO` and `SCRIPT_NAME`::
+
+    location / { try_files $uri @yourapplication; }
+    location @yourapplication {
+        include fastcgi_params;
+        fastcgi_param PATH_INFO $fastcgi_script_name;
+        fastcgi_param SCRIPT_NAME "";
+        fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
+    }
+
+Since Nginx doesn't load FastCGI apps, you have to do it by yourself.  You
+can either write an `init.d` script for that or execute it inside a screen
+session::
+
+    $ screen
+    $ /var/www/yourapplication/yourapplication.fcgi
+
+Debugging
+---------
+
+FastCGI deployments tend to be hard to debug on most webservers.  Very often the
+only thing the server log tells you is something along the lines of "premature
+end of headers".  In order to debug the application the only thing that can
+really give you ideas why it breaks is switching to the correct user and
+executing the application by hand.
+
+This example assumes your application is called `application.fcgi` and that your
+webserver user is `www-data`::
+
+    $ su www-data
+    $ cd /var/www/yourapplication
+    $ python application.fcgi
+    Traceback (most recent call last):
+      File "yourapplication.fcgi", line 4, in <module>
+    ImportError: No module named yourapplication
+
+In this case the error seems to be "yourapplication" not being on the python
+path.  Common problems are:
+
+-   relative paths being used.  Don't rely on the current working directory
+-   the code depending on environment variables that are not set by the
+    web server.
+-   different python interpreters being used.
+
+.. _lighttpd: http://www.lighttpd.net/
+.. _nginx: http://nginx.net/
+.. _flup: http://trac.saddi.com/flup
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/deploying/index.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,19 @@
+Deployment Options
+==================
+
+Depending on what you have available there are multiple ways to run Flask
+applications.  A very common method is to use the builtin server during
+development and maybe behind a proxy for simple applications, but there
+are more options available.
+
+If you have a different WSGI server look up the server documentation about
+how to use a WSGI app with it.  Just remember that your application object
+is the actual WSGI application.
+
+.. toctree::
+   :maxdepth: 2
+
+   mod_wsgi
+   cgi
+   fastcgi
+   others
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/deploying/mod_wsgi.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,166 @@
+.. _mod_wsgi-deployment:
+
+mod_wsgi (Apache)
+=================
+
+If you are using the `Apache`_ webserver you should consider using `mod_wsgi`_.
+
+.. admonition:: Watch Out
+
+   Please make sure in advance that your ``app.run()`` call you might
+   have in your application file, is inside an ``if __name__ ==
+   '__main__':`` or moved to a separate file.  Just make sure it's not
+   called because this will always start a local WSGI server which we do
+   not want if we deploy that application to mod_wsgi.
+
+.. _Apache: http://httpd.apache.org/
+
+Installing `mod_wsgi`
+---------------------
+
+If you don't have `mod_wsgi` installed yet you have to either install it using
+a package manager or compile it yourself.
+
+The mod_wsgi `installation instructions`_ cover source installations on UNIX
+systems.
+
+If you are using Ubuntu/Debian you can apt-get it and activate it as follows:
+
+.. sourcecode:: text
+
+    # apt-get install libapache2-mod-wsgi
+
+On FreeBSD install `mod_wsgi` by compiling the `www/mod_wsgi` port or by using
+pkg_add:
+
+.. sourcecode:: text
+
+    # pkg_add -r mod_wsgi
+
+If you are using pkgsrc you can install `mod_wsgi` by compiling the
+`www/ap2-wsgi` package.
+
+If you encounter segfaulting child processes after the first apache reload you
+can safely ignore them.  Just restart the server.
+
+Creating a `.wsgi` file
+-----------------------
+
+To run your application you need a `yourapplication.wsgi` file.  This file
+contains the code `mod_wsgi` is executing on startup to get the application
+object.  The object called `application` in that file is then used as
+application.
+
+For most applications the following file should be sufficient::
+
+    from yourapplication import app as application
+
+If you don't have a factory function for application creation but a singleton
+instance you can directly import that one as `application`.
+
+Store that file somewhere that you will find it again (e.g.:
+`/var/www/yourapplication`) and make sure that `yourapplication` and all
+the libraries that are in use are on the python load path.  If you don't
+want to install it system wide consider using a `virtual python`_ instance.
+
+Configuring Apache
+------------------
+
+The last thing you have to do is to create an Apache configuration file for
+your application.  In this example we are telling `mod_wsgi` to execute the
+application under a different user for security reasons:
+
+.. sourcecode:: apache
+
+    <VirtualHost *>
+        ServerName example.com
+
+        WSGIDaemonProcess yourapplication user=user1 group=group1 threads=5
+        WSGIScriptAlias / /var/www/yourapplication/yourapplication.wsgi
+
+        <Directory /var/www/yourapplication>
+            WSGIProcessGroup yourapplication
+            WSGIApplicationGroup %{GLOBAL}
+            Order deny,allow
+            Allow from all
+        </Directory>
+    </VirtualHost>
+
+For more information consult the `mod_wsgi wiki`_.
+
+.. _mod_wsgi: http://code.google.com/p/modwsgi/
+.. _installation instructions: http://code.google.com/p/modwsgi/wiki/QuickInstallationGuide
+.. _virtual python: http://pypi.python.org/pypi/virtualenv
+.. _mod_wsgi wiki: http://code.google.com/p/modwsgi/wiki/
+
+Troubleshooting
+---------------
+
+If your application does not run, follow this guide to troubleshoot:
+
+**Problem:** application does not run, errorlog shows SystemExit ignored
+    You have a ``app.run()`` call in your application file that is not
+    guarded by an ``if __name__ == '__main__':`` condition.  Either remove
+    that :meth:`~flask.Flask.run` call from the file and move it into a
+    separate `run.py` file or put it into such an if block.
+
+**Problem:** application gives permission errors
+    Probably caused by your application running as the wrong user.  Make
+    sure the folders the application needs access to have the proper
+    privileges set and the application runs as the correct user (``user``
+    and ``group`` parameter to the `WSGIDaemonProcess` directive)
+
+**Problem:** application dies with an error on print
+    Keep in mind that mod_wsgi disallows doing anything with
+    :data:`sys.stdout` and :data:`sys.stderr`.  You can disable this
+    protection from the config by setting the `WSGIRestrictStdout` to
+    ``off``:
+
+    .. sourcecode:: apache
+
+        WSGIRestrictStdout Off
+
+    Alternatively you can also replace the standard out in the .wsgi file
+    with a different stream::
+
+        import sys
+        sys.stdout = sys.stderr
+
+**Problem:** accessing resources gives IO errors
+    Your application probably is a single .py file you symlinked into the
+    site-packages folder.  Please be aware that this does not work,
+    instead you either have to put the folder into the pythonpath the file
+    is stored in, or convert your application into a package.
+
+    The reason for this is that for non-installed packages, the module
+    filename is used to locate the resources and for symlinks the wrong
+    filename is picked up.
+
+Support for Automatic Reloading
+-------------------------------
+
+To help deployment tools you can activate support for automatic reloading.
+Whenever something changes the `.wsgi` file, `mod_wsgi` will reload all
+the daemon processes for us.
+
+For that, just add the following directive to your `Directory` section:
+
+.. sourcecode:: apache
+
+   WSGIScriptReloading On
+
+Working with Virtual Environments
+---------------------------------
+
+Virtual environments have the advantage that they never install the
+required dependencies system wide so you have a better control over what
+is used where.  If you want to use a virtual environment with mod_wsgi you
+have to modify your `.wsgi` file slightly.
+
+Add the following lines to the top of your `.wsgi` file::
+
+    activate_this = '/path/to/env/bin/activate_this.py'
+    execfile(activate_this, dict(__file__=activate_this))
+
+This sets up the load paths according to the settings of the virtual
+environment.  Keep in mind that the path has to be absolute.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/deploying/others.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,98 @@
+Other Servers
+=============
+
+There are popular servers written in Python that allow the execution of
+WSGI applications as well.  Keep in mind though that some of these servers
+were written for very specific applications and might not work as well for
+standard WSGI application such as Flask powered ones.
+
+
+Tornado
+--------
+
+`Tornado`_ is an open source version of the scalable, non-blocking web
+server and tools that power `FriendFeed`_.  Because it is non-blocking and
+uses epoll, it can handle thousands of simultaneous standing connections,
+which means it is ideal for real-time web services.  Integrating this
+service with Flask is a trivial task::
+    
+    from tornado.wsgi import WSGIContainer
+    from tornado.httpserver import HTTPServer
+    from tornado.ioloop import IOLoop
+    from yourapplication import app
+    
+    http_server = HTTPServer(WSGIContainer(app))
+    http_server.listen(5000)
+    IOLoop.instance().start()
+
+
+.. _Tornado: http://www.tornadoweb.org/
+.. _FriendFeed: http://friendfeed.com/
+
+
+Gevent
+-------
+
+`Gevent`_ is a coroutine-based Python networking library that uses
+`greenlet`_ to provide a high-level synchronous API on top of `libevent`_
+event loop::
+
+    from gevent.wsgi import WSGIServer
+    from yourapplication import app
+
+    http_server = WSGIServer(('', 5000), app)
+    http_server.serve_forever()
+
+.. _Gevent: http://www.gevent.org/
+.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html
+.. _libevent: http://monkey.org/~provos/libevent/
+
+
+Gunicorn
+--------
+
+`Gunicorn`_ 'Green Unicorn' is a WSGI HTTP Server for UNIX. It's a pre-fork
+worker model ported from Ruby's Unicorn project. It supports both `eventlet`_
+and `greenlet`_. Running a Flask application on this server is quite simple::
+
+    gunicorn myproject:app
+
+.. _Gunicorn: http://gunicorn.org/
+.. _eventlet: http://eventlet.net/
+.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html
+
+
+Proxy Setups
+------------
+
+If you deploy your application behind an HTTP proxy you will need to
+rewrite a few headers in order for the application to work.  The two
+problematic values in the WSGI environment usually are `REMOTE_ADDR` and
+`HTTP_HOST`.  Werkzeug ships a fixer that will solve some common setups,
+but you might want to write your own WSGI middleware for specific setups.
+
+The most common setup invokes the host being set from `X-Forwarded-Host`
+and the remote address from `X-Forward-For`::
+
+    from werkzeug.contrib.fixers import ProxyFix
+    app.wsgi_app = ProxyFix(app.wsgi_app)
+
+Please keep in mind that it is a security issue to use such a middleware
+in a non-proxy setup because it will blindly trust the incoming
+headers which might be forged by malicious clients.
+
+If you want to rewrite the headers from another header, you might want to
+use a fixer like this::
+
+    class CustomProxyFix(object):
+
+        def __init__(self, app):
+            self.app = app
+
+        def __call__(self, environ, start_response):
+            host = environ.get('HTTP_X_FHOST', '')
+            if host:
+                environ['HTTP_HOST'] = host
+            return self.app(environ, start_response)
+
+    app.wsgi_app = CustomProxyFix(app.wsgi_app)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/design.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,175 @@
+.. _design:
+
+Design Decisions in Flask
+=========================
+
+If you are curious why Flask does certain things the way it does and not
+differently, this section is for you.  This should give you an idea about
+some of the design decisions that may appear arbitrary and surprising at
+first, especially in direct comparison with other frameworks.
+
+
+The Explicit Application Object
+-------------------------------
+
+A Python web application based on WSGI has to have one central callable
+object that implements the actual application.  In Flask this is an
+instance of the :class:`~flask.Flask` class.  Each Flask application has
+to create an instance of this class itself and pass it the name of the
+module, but why can't Flask do that itself?
+
+Without such an explicit application object the following code::
+
+    from flask import Flask
+    app = Flask(__name__)
+
+    @app.route('/')
+    def index():
+        return 'Hello World!'
+
+Would look like this instead::
+
+    from hypothetical_flask import route
+
+    @route('/')
+    def index():
+        return 'Hello World!'
+
+There are three major reasons for this.  The most important one is that
+implicit application objects require that there may only be one instance at
+the time.  There are ways to fake multiple applications with a single
+application object, like maintaining a stack of applications, but this
+causes some problems I won't outline here in detail.  Now the question is:
+when does a microframework need more than one application at the same
+time?  A good example for this is unittesting.  When you want to test
+something it can be very helpful to create a minimal application to test
+specific behavior.  When the application object is deleted everything it
+allocated will be freed again.
+
+Another thing that becomes possible when you have an explicit object lying
+around in your code is that you can subclass the base class
+(:class:`~flask.Flask`) to alter specific behaviour.  This would not be
+possible without hacks if the object were created ahead of time for you
+based on a class that is not exposed to you.
+
+But there is another very important reason why Flask depends on an
+explicit instantiation of that class: the package name.  Whenever you
+create a Flask instance you usually pass it `__name__` as package name.
+Flask depends on that information to properly load resources relative
+to your module.  With Python's outstanding support for reflection it can
+then access the package to figure out where the templates and static files
+are stored (see :meth:`~flask.Flask.open_resource`).  Now obviously there
+are frameworks around that do not need any configuration and will still be
+able to load templates relative to your application module.  But they have
+to use the current working directory for that, which is a very unreliable
+way to determine where the application is.  The current working directory
+is process-wide and if you are running multiple applications in one
+process (which could happen in a webserver without you knowing) the paths
+will be off.  Worse: many webservers do not set the working directory to
+the directory of your application but to the document root which does not
+have to be the same folder.
+
+The third reason is "explicit is better than implicit".  That object is
+your WSGI application, you don't have to remember anything else.  If you
+want to apply a WSGI middleware, just wrap it and you're done (though
+there are better ways to do that so that you do not lose the reference
+to the application object :meth:`~flask.Flask.wsgi_app`).
+
+Furthermore this design makes it possible to use a factory function to
+create the application which is very helpful for unittesting and similar
+things (:ref:`app-factories`).
+
+One Template Engine
+-------------------
+
+Flask decides on one template engine: Jinja2.  Why doesn't Flask have a
+pluggable template engine interface?  You can obviously use a different
+template engine, but Flask will still configure Jinja2 for you.  While
+that limitation that Jinja2 is *always* configured will probably go away,
+the decision to bundle one template engine and use that will not.
+
+Template engines are like programming languages and each of those engines
+has a certain understanding about how things work.  On the surface they
+all work the same: you tell the engine to evaluate a template with a set
+of variables and take the return value as string.
+
+But that's about where similarities end.  Jinja2 for example has an
+extensive filter system, a certain way to do template inheritance, support
+for reusable blocks (macros) that can be used from inside templates and
+also from Python code, uses Unicode for all operations, supports
+iterative template rendering, configurable syntax and more.  On the other
+hand an engine like Genshi is based on XML stream evaluation, template
+inheritance by taking the availability of XPath into account and more.
+Mako on the other hand treats templates similar to Python modules.
+
+When it comes to connecting a template engine with an application or
+framework there is more than just rendering templates.  For instance,
+Flask uses Jinja2's extensive autoescaping support.  Also it provides
+ways to access macros from Jinja2 templates.
+
+A template abstraction layer that would not take the unique features of
+the template engines away is a science on its own and a too large
+undertaking for a microframework like Flask.
+
+Furthermore extensions can then easily depend on one template language
+being present.  You can easily use your own templating language, but an
+extension could still depend on Jinja itself.
+
+
+Micro with Dependencies
+-----------------------
+
+Why does Flask call itself a microframework and yet it depends on two
+libraries (namely Werkzeug and Jinja2).  Why shouldn't it?  If we look
+over to the Ruby side of web development there we have a protocol very
+similar to WSGI.  Just that it's called Rack there, but besides that it
+looks very much like a WSGI rendition for Ruby.  But nearly all
+applications in Ruby land do not work with Rack directly, but on top of a
+library with the same name.  This Rack library has two equivalents in
+Python: WebOb (formerly Paste) and Werkzeug.  Paste is still around but
+from my understanding it's sort of deprecated in favour of WebOb.  The
+development of WebOb and Werkzeug started side by side with similar ideas
+in mind: be a good implementation of WSGI for other applications to take
+advantage.
+
+Flask is a framework that takes advantage of the work already done by
+Werkzeug to properly interface WSGI (which can be a complex task at
+times).  Thanks to recent developments in the Python package
+infrastructure, packages with dependencies are no longer an issue and
+there are very few reasons against having libraries that depend on others.
+
+
+Thread Locals
+-------------
+
+Flask uses thread local objects (context local objects in fact, they
+support greenlet contexts as well) for request, session and an extra
+object you can put your own things on (:data:`~flask.g`).  Why is that and
+isn't that a bad idea?
+
+Yes it is usually not such a bright idea to use thread locals.  They cause
+troubles for servers that are not based on the concept of threads and make
+large applications harder to maintain.  However Flask is just not designed
+for large applications or asynchronous servers.  Flask wants to make it
+quick and easy to write a traditional web application.
+
+Also see the :ref:`becomingbig` section of the documentation for some
+inspiration for larger applications based on Flask.
+
+
+What Flask is, What Flask is Not
+--------------------------------
+
+Flask will never have a database layer.  It will not have a form library
+or anything else in that direction.  Flask itself just bridges to Werkzeug
+to implement a proper WSGI application and to Jinja2 to handle templating.
+It also binds to a few common standard library packages such as logging.
+Everything else is up for extensions.
+
+Why is this the case?  Because people have different preferences and
+requirements and Flask could not meet those if it would force any of this
+into the core.  The majority of web applications will need a template
+engine in some sort.  However not every application needs a SQL database.
+
+The idea of Flask is to build a good foundation for all applications.
+Everything else is up to you or extensions.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/errorhandling.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,237 @@
+.. _application-errors:
+
+Handling Application Errors
+===========================
+
+.. versionadded:: 0.3
+
+Applications fail, servers fail.  Sooner or later you will see an exception
+in production.  Even if your code is 100% correct, you will still see
+exceptions from time to time.  Why?  Because everything else involved will
+fail.  Here some situations where perfectly fine code can lead to server
+errors:
+
+-   the client terminated the request early and the application was still
+    reading from the incoming data.
+-   the database server was overloaded and could not handle the query.
+-   a filesystem is full
+-   a harddrive crashed
+-   a backend server overloaded
+-   a programming error in a library you are using
+-   network connection of the server to another system failed.
+
+And that's just a small sample of issues you could be facing.  So how do we
+deal with that sort of problem?  By default if your application runs in
+production mode, Flask will display a very simple page for you and log the
+exception to the :attr:`~flask.Flask.logger`.
+
+But there is more you can do, and we will cover some better setups to deal
+with errors.
+
+Error Mails
+-----------
+
+If the application runs in production mode (which it will do on your
+server) you won't see any log messages by default.  Why is that?  Flask
+tries to be a zero-configuration framework.  Where should it drop the logs
+for you if there is no configuration?  Guessing is not a good idea because
+chances are, the place it guessed is not the place where the user has
+permission to create a logfile.  Also, for most small applications nobody
+will look at the logs anyways.
+
+In fact, I promise you right now that if you configure a logfile for the
+application errors you will never look at it except for debugging an issue
+when a user reported it for you.  What you want instead is a mail the
+second the exception happened.  Then you get an alert and you can do
+something about it.
+
+Flask uses the Python builtin logging system, and it can actually send
+you mails for errors which is probably what you want.  Here is how you can
+configure the Flask logger to send you mails for exceptions::
+
+    ADMINS = ['yourname@example.com']
+    if not app.debug:
+        import logging
+        from logging.handlers import SMTPHandler
+        mail_handler = SMTPHandler('127.0.0.1',
+                                   'server-error@example.com',
+                                   ADMINS, 'YourApplication Failed')
+        mail_handler.setLevel(logging.ERROR)
+        app.logger.addHandler(mail_handler)
+
+So what just happened?  We created a new
+:class:`~logging.handlers.SMTPHandler` that will send mails with the mail
+server listening on ``127.0.0.1`` to all the `ADMINS` from the address
+*server-error@example.com* with the subject "YourApplication Failed".  If
+your mail server requires credentials, these can also be provided.  For
+that check out the documentation for the
+:class:`~logging.handlers.SMTPHandler`.
+
+We also tell the handler to only send errors and more critical messages.
+Because we certainly don't want to get a mail for warnings or other
+useless logs that might happen during request handling.
+
+Before you run that in production, please also look at :ref:`logformat` to
+put more information into that error mail.  That will save you from a lot
+of frustration.
+
+
+Logging to a File
+-----------------
+
+Even if you get mails, you probably also want to log warnings.  It's a
+good idea to keep as much information around that might be required to
+debug a problem.  Please note that Flask itself will not issue any
+warnings in the core system, so it's your responsibility to warn in the
+code if something seems odd.
+
+There are a couple of handlers provided by the logging system out of the
+box but not all of them are useful for basic error logging.  The most
+interesting are probably the following:
+
+-   :class:`~logging.FileHandler` - logs messages to a file on the
+    filesystem.
+-   :class:`~logging.handlers.RotatingFileHandler` - logs messages to a file
+    on the filesystem and will rotate after a certain number of messages.
+-   :class:`~logging.handlers.NTEventLogHandler` - will log to the system
+    event log of a Windows system.  If you are deploying on a Windows box,
+    this is what you want to use.
+-   :class:`~logging.handlers.SysLogHandler` - sends logs to a UNIX
+    syslog.
+
+Once you picked your log handler, do like you did with the SMTP handler
+above, just make sure to use a lower setting (I would recommend
+`WARNING`)::
+
+    if not app.debug:
+        import logging
+        from themodule import TheHandler YouWant
+        file_handler = TheHandlerYouWant(...)
+        file_handler.setLevel(logging.WARNING)
+        app.logger.addHandler(file_handler)
+
+.. _logformat:
+
+Controlling the Log Format
+--------------------------
+
+By default a handler will only write the message string into a file or
+send you that message as mail.  A log record stores more information,
+and it makes a lot of sense to configure your logger to also contain that
+information so that you have a better idea of why that error happened, and
+more importantly, where it did.
+
+A formatter can be instantiated with a format string.  Note that
+tracebacks are appended to the log entry automatically.  You don't have to
+do that in the log formatter format string.
+
+Here some example setups:
+
+Email
+`````
+
+::
+
+    from logging import Formatter
+    mail_handler.setFormatter(Formatter('''
+    Message type:       %(levelname)s
+    Location:           %(pathname)s:%(lineno)d
+    Module:             %(module)s
+    Function:           %(funcName)s
+    Time:               %(asctime)s
+
+    Message:
+
+    %(message)s
+    '''))
+
+File logging
+````````````
+
+::
+
+    from logging import Formatter
+    file_handler.setFormatter(Formatter(
+        '%(asctime)s %(levelname)s: %(message)s '
+        '[in %(pathname)s:%(lineno)d]'
+    ))
+
+
+Complex Log Formatting
+``````````````````````
+
+Here is a list of useful formatting variables for the format string.  Note
+that this list is not complete, consult the official documentation of the
+:mod:`logging` package for a full list.
+
+.. tabularcolumns:: |p{3cm}|p{12cm}|
+
++------------------+----------------------------------------------------+
+| Format           | Description                                        |
++==================+====================================================+
+| ``%(levelname)s``| Text logging level for the message                 |
+|                  | (``'DEBUG'``, ``'INFO'``, ``'WARNING'``,           |
+|                  | ``'ERROR'``, ``'CRITICAL'``).                      |
++------------------+----------------------------------------------------+
+| ``%(pathname)s`` | Full pathname of the source file where the         |
+|                  | logging call was issued (if available).            |
++------------------+----------------------------------------------------+
+| ``%(filename)s`` | Filename portion of pathname.                      |
++------------------+----------------------------------------------------+
+| ``%(module)s``   | Module (name portion of filename).                 |
++------------------+----------------------------------------------------+
+| ``%(funcName)s`` | Name of function containing the logging call.      |
++------------------+----------------------------------------------------+
+| ``%(lineno)d``   | Source line number where the logging call was      |
+|                  | issued (if available).                             |
++------------------+----------------------------------------------------+
+| ``%(asctime)s``  | Human-readable time when the LogRecord` was        |
+|                  | created.  By default this is of the form           |
+|                  | ``"2003-07-08 16:49:45,896"`` (the numbers after   |
+|                  | the comma are millisecond portion of the time).    |
+|                  | This can be changed by subclassing the formatter   |
+|                  | and overriding the                                 |
+|                  | :meth:`~logging.Formatter.formatTime` method.      |
++------------------+----------------------------------------------------+
+| ``%(message)s``  | The logged message, computed as ``msg % args``     |
++------------------+----------------------------------------------------+
+
+If you want to further customize the formatting, you can subclass the
+formatter.  The formatter has three interesting methods:
+
+:meth:`~logging.Formatter.format`:
+    handles the actual formatting.  It is passed a
+    :class:`~logging.LogRecord` object and has to return the formatted
+    string.
+:meth:`~logging.Formatter.formatTime`:
+    called for `asctime` formatting.  If you want a different time format
+    you can override this method.
+:meth:`~logging.Formatter.formatException`
+    called for exception formatting.  It is passed an :attr:`~sys.exc_info`
+    tuple and has to return a string.  The default is usually fine, you
+    don't have to override it.
+
+For more information, head over to the official documentation.
+
+
+Other Libraries
+---------------
+
+So far we only configured the logger your application created itself.
+Other libraries might log themselves as well.  For example, SQLAlchemy uses
+logging heavily in its core.  While there is a method to configure all
+loggers at once in the :mod:`logging` package, I would not recommend using
+it.  There might be a situation in which you want to have multiple
+separate applications running side by side in the same Python interpreter
+and then it becomes impossible to have different logging setups for those.
+
+Instead, I would recommend figuring out which loggers you are interested
+in, getting the loggers with the :func:`~logging.getLogger` function and
+iterating over them to attach handlers::
+
+    from logging import getLogger
+    loggers = [app.logger, getLogger('sqlalchemy'),
+               getLogger('otherlibrary')]
+    for logger in loggers:
+        logger.addHandler(mail_handler)
+        logger.addHandler(file_handler)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/extensiondev.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,327 @@
+Flask Extension Development
+===========================
+
+Flask, being a microframework, often requires some repetitive steps to get
+a third party library working.  Because very often these steps could be
+abstracted to support multiple projects the `Flask Extension Registry`_
+was created.
+
+If you want to create your own Flask extension for something that does not
+exist yet, this guide to extension development will help you get your
+extension running in no time and to feel like users would expect your
+extension to behave.
+
+.. _Flask Extension Registry: http://flask.pocoo.org/extensions/
+
+Anatomy of an Extension
+-----------------------
+
+Extensions are all located in a package called ``flaskext.something``
+where "something" is the name of the library you want to bridge.  So for
+example if you plan to add support for a library named `simplexml` to
+Flask, you would name your extension's package ``flaskext.simplexml``.
+
+The name of the actual extension (the human readable name) however would
+be something like "Flask-SimpleXML".  Make sure to include the name
+"Flask" somewhere in that name and that you check the capitalization.
+This is how users can then register dependencies to your extension in
+their `setup.py` files.
+
+The magic that makes it possible to have your library in a package called
+``flaskext.something`` is called a "namespace package".  Check out the
+guide below how to create something like that.
+
+But how do extensions look like themselves?  An extension has to ensure
+that it works with multiple Flask application instances at once.  This is
+a requirement because many people will use patterns like the
+:ref:`app-factories` pattern to create their application as needed to aid
+unittests and to support multiple configurations.  Because of that it is
+crucial that your application supports that kind of behaviour.
+
+Most importantly the extension must be shipped with a `setup.py` file and
+registered on PyPI.  Also the development checkout link should work so
+that people can easily install the development version into their
+virtualenv without having to download the library by hand.
+
+Flask extensions must be licensed as BSD or MIT or a more liberal license
+to be enlisted on the Flask Extension Registry.  Keep in mind that the
+Flask Extension Registry is a moderated place and libraries will be
+reviewed upfront if they behave as required.
+
+"Hello Flaskext!"
+-----------------
+
+So let's get started with creating such a Flask extension.  The extension
+we want to create here will provide very basic support for SQLite3.
+
+There is a script on github called `Flask Extension Wizard`_ which helps
+you create the initial folder structure.  But for this very basic example
+we want to create all by hand to get a better feeling for it.
+
+First we create the following folder structure::
+
+    flask-sqlite3/
+        flaskext/
+            __init__.py
+            sqlite3.py
+        setup.py
+        LICENSE
+
+Here's the contents of the most important files:
+
+flaskext/__init__.py
+````````````````````
+
+The only purpose of this file is to mark the package as namespace package.
+This is required so that multiple modules from different PyPI packages can
+reside in the same Python package::
+
+    __import__('pkg_resources').declare_namespace(__name__)
+
+If you want to know exactly what is happening there, checkout the
+distribute or setuptools docs which explain how this works.
+
+Just make sure to not put anything else in there!
+
+setup.py
+````````
+
+The next file that is absolutely required is the `setup.py` file which is
+used to install your Flask extension.  The following contents are
+something you can work with::
+
+    """
+    Flask-SQLite3
+    -------------
+
+    This is the description for that library
+    """
+    from setuptools import setup
+
+
+    setup(
+        name='Flask-SQLite3',
+        version='1.0',
+        url='http://example.com/flask-sqlite3/',
+        license='BSD',
+        author='Your Name',
+        author_email='your-email@example.com',
+        description='Very short description',
+        long_description=__doc__,
+        packages=['flaskext'],
+        namespace_packages=['flaskext'],
+        zip_safe=False,
+        platforms='any',
+        install_requires=[
+            'Flask'
+        ],
+        classifiers=[
+            'Environment :: Web Environment',
+            'Intended Audience :: Developers',
+            'License :: OSI Approved :: BSD License',
+            'Operating System :: OS Independent',
+            'Programming Language :: Python',
+            'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
+            'Topic :: Software Development :: Libraries :: Python Modules'
+        ]
+    )
+
+That's a lot of code but you can really just copy/paste that from existing
+extensions and adapt.  This is also what the wizard creates for you if you
+use it.
+
+flaskext/sqlite3.py
+```````````````````
+
+Now this is where your extension code goes.  But how exactly should such
+an extension look like?  What are the best practices?  Continue reading
+for some insight.
+
+
+Initializing Extensions
+-----------------------
+
+Many extensions will need some kind of initialization step.  For example,
+consider your application is currently connecting to SQLite like the
+documentation suggests (:ref:`sqlite3`) you will need to provide a few
+functions and before / after request handlers.  So how does the extension
+know the name of the application object?
+
+Quite simple: you pass it to it.
+
+There are two recommended ways for an extension to initialize:
+
+initialization functions:
+    If your extension is called `helloworld` you might have a function
+    called ``init_helloworld(app[, extra_args])`` that initializes the
+    extension for that application.  It could attach before / after
+    handlers etc.
+
+classes:
+    Classes work mostly like initialization functions but can later be
+    used to further change the behaviour.  For an example look at how the
+    `OAuth extension`_ works: there is an `OAuth` object that provides
+    some helper functions like `OAuth.remote_app` to create a reference to
+    a remote application that uses OAuth.
+
+What to use depends on what you have in mind.  For the SQLite 3 extension
+we will need to use the class based approach because we have to use a
+controller object that can be used to connect to the database.
+
+The Extension Code
+------------------
+
+Here's the contents of the `flaskext/sqlite3.py` for copy/paste::
+
+    from __future__ import absolute_import
+    import sqlite3
+    from flask import g
+
+    class SQLite3(object):
+    
+        def __init__(self, app):
+            self.app = app
+            self.app.config.setdefault('SQLITE3_DATABASE', ':memory:')
+
+            self.app.before_request(self.before_request)
+            self.app.after_request(self.after_request)
+
+        def connect(self):
+            return sqlite3.connect(self.app.config['SQLITE3_DATABASE'])
+
+        def before_request(self):
+            g.sqlite3_db = self.connect()
+
+        def after_request(self, response):
+            g.sqlite3_db.close()
+            return response
+
+So here's what the lines of code do:
+
+1.  the ``__future__`` import is necessary to activate absolute imports.
+    This is needed because otherwise we could not call our module
+    `sqlite3.py` and import the top-level `sqlite3` module which actually
+    implements the connection to SQLite.
+2.  We create a class for our extension that sets a default configuration
+    for the SQLite 3 database if it's not there (:meth:`dict.setdefault`)
+    and connects two functions as before and after request handlers.
+3.  Then it implements a `connect` function that returns a new database
+    connection and the two handlers.
+
+So why did we decide on a class based approach here?  Because using that
+extension looks something like this::
+
+    from flask import Flask, g
+    from flaskext.sqlite3 import SQLite3
+
+    app = Flask(__name__)
+    app.config.from_pyfile('the-config.cfg')
+    db = SQLite(app)
+
+Either way you can use the database from the views like this::
+
+    @app.route('/')
+    def show_all():
+        cur = g.sqlite3_db.cursor()
+        cur.execute(...)
+
+But how would you open a database connection from outside a view function?
+This is where the `db` object now comes into play:
+
+>>> from yourapplication import db
+>>> con = db.connect()
+>>> cur = con.cursor()
+
+If you don't need that, you can go with initialization functions.
+
+Initialization Functions
+------------------------
+
+Here's what the module would look like with initialization functions::
+
+    from __future__ import absolute_import
+    import sqlite3
+    from flask import g
+
+    def init_sqlite3(app):
+        app = app
+        app.config.setdefault('SQLITE3_DATABASE', ':memory:')
+
+        @app.before_request
+        def before_request():
+            g.sqlite3_db = sqlite3.connect(self.app.config['SQLITE3_DATABASE'])
+
+        @app.after_request
+        def after_request(response):
+            g.sqlite3_db.close()
+            return response
+
+Learn from Others
+-----------------
+
+This documentation only touches the bare minimum for extension
+development.  If you want to learn more, it's a very good idea to check
+out existing extensions on the `Flask Extension Registry`_.  If you feel
+lost there is still the `mailinglist`_ and the `IRC channel`_ to get some
+ideas for nice looking APIs.  Especially if you do something nobody before
+you did, it might be a very good idea to get some more input.  This not
+only to get an idea about what people might want to have from an
+extension, but also to avoid having multiple developers working on pretty
+much the same side by side.
+
+Remember: good API design is hard, so introduce your project on the
+mailinglist, and let other developers give you a helping hand with
+designing the API.
+
+The best Flask extensions are extensions that share common idioms for the
+API.  And this can only work if collaboration happens early.
+
+
+Approved Extensions
+-------------------
+
+Flask also has the concept of approved extensions.  Approved extensions
+are tested as part of Flask itself to ensure extensions do not break on
+new releases.  These approved extensions are listed on the `Flask
+Extension Registry`_ and marked appropriately.  If you want your own
+extension to be approved you have to follow these guidelines:
+
+1.  An approved Flask extension must provide exactly one package or module
+    inside the `flaskext` namespace package.
+2.  It must ship a testsuite that can either be invoked with ``make test``
+    or ``python setup.py test``.  For testsuites invoked with ``make
+    test`` the extension has to ensure that all dependencies for the test
+    are installed automatically, in case of ``python setup.py test``
+    dependencies for tests alone can be specified in the `setup.py`
+    file.  The testsuite also has to be part of the distribution.
+3.  APIs of approved extensions will be checked for the following
+    characteristics:
+
+    -   an approved extension has to support multiple applications
+        running in the same Python process.
+    -   it must be possible to use the factory pattern for creating
+        applications.
+
+4.  The license must be BSD/MIT/WTFPL licensed.
+5.  The naming scheme for official extensions is *Flask-ExtensionName* or
+    *ExtensionName-Flask*.
+6.  Approved extensions must define all their dependencies in the
+    `setup.py` file unless a dependency cannot be met because it is not
+    available on PyPI.
+7.  The extension must have documentation that uses one of the two Flask
+    themes for Sphinx documentation.
+8.  The setup.py description (and thus the PyPI description) has to
+    link to the documentation, website (if there is one) and there
+    must be a link to automatically install the development version
+    (``PackageName==dev``).
+9.  The ``zip_safe`` flag in the setup script must be set to ``False``,
+    even if the extension would be safe for zipping.
+10. An extension currently has to support Python 2.5, 2.6 as well as
+    Python 2.7
+
+
+.. _Flask Extension Wizard:
+   http://github.com/mitsuhiko/flask-extension-wizard
+.. _OAuth extension: http://packages.python.org/Flask-OAuth/
+.. _mailinglist: http://flask.pocoo.org/mailinglist/
+.. _IRC channel: http://flask.pocoo.org/community/irc/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/flaskext.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,86 @@
+# flasky extensions.  flasky pygments style based on tango style
+from pygments.style import Style
+from pygments.token import Keyword, Name, Comment, String, Error, \
+     Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
+
+
+class FlaskyStyle(Style):
+    background_color = "#f8f8f8"
+    default_style = ""
+
+    styles = {
+        # No corresponding class for the following:
+        #Text:                     "", # class:  ''
+        Whitespace:                "underline #f8f8f8",      # class: 'w'
+        Error:                     "#a40000 border:#ef2929", # class: 'err'
+        Other:                     "#000000",                # class 'x'
+
+        Comment:                   "italic #8f5902", # class: 'c'
+        Comment.Preproc:           "noitalic",       # class: 'cp'
+
+        Keyword:                   "bold #004461",   # class: 'k'
+        Keyword.Constant:          "bold #004461",   # class: 'kc'
+        Keyword.Declaration:       "bold #004461",   # class: 'kd'
+        Keyword.Namespace:         "bold #004461",   # class: 'kn'
+        Keyword.Pseudo:            "bold #004461",   # class: 'kp'
+        Keyword.Reserved:          "bold #004461",   # class: 'kr'
+        Keyword.Type:              "bold #004461",   # class: 'kt'
+
+        Operator:                  "#582800",   # class: 'o'
+        Operator.Word:             "bold #004461",   # class: 'ow' - like keywords
+
+        Punctuation:               "bold #000000",   # class: 'p'
+
+        # because special names such as Name.Class, Name.Function, etc.
+        # are not recognized as such later in the parsing, we choose them
+        # to look the same as ordinary variables.
+        Name:                      "#000000",        # class: 'n'
+        Name.Attribute:            "#c4a000",        # class: 'na' - to be revised
+        Name.Builtin:              "#004461",        # class: 'nb'
+        Name.Builtin.Pseudo:       "#3465a4",        # class: 'bp'
+        Name.Class:                "#000000",        # class: 'nc' - to be revised
+        Name.Constant:             "#000000",        # class: 'no' - to be revised
+        Name.Decorator:            "#888",           # class: 'nd' - to be revised
+        Name.Entity:               "#ce5c00",        # class: 'ni'
+        Name.Exception:            "bold #cc0000",   # class: 'ne'
+        Name.Function:             "#000000",        # class: 'nf'
+        Name.Property:             "#000000",        # class: 'py'
+        Name.Label:                "#f57900",        # class: 'nl'
+        Name.Namespace:            "#000000",        # class: 'nn' - to be revised
+        Name.Other:                "#000000",        # class: 'nx'
+        Name.Tag:                  "bold #004461",   # class: 'nt' - like a keyword
+        Name.Variable:             "#000000",        # class: 'nv' - to be revised
+        Name.Variable.Class:       "#000000",        # class: 'vc' - to be revised
+        Name.Variable.Global:      "#000000",        # class: 'vg' - to be revised
+        Name.Variable.Instance:    "#000000",        # class: 'vi' - to be revised
+
+        Number:                    "#990000",        # class: 'm'
+
+        Literal:                   "#000000",        # class: 'l'
+        Literal.Date:              "#000000",        # class: 'ld'
+
+        String:                    "#4e9a06",        # class: 's'
+        String.Backtick:           "#4e9a06",        # class: 'sb'
+        String.Char:               "#4e9a06",        # class: 'sc'
+        String.Doc:                "italic #8f5902", # class: 'sd' - like a comment
+        String.Double:             "#4e9a06",        # class: 's2'
+        String.Escape:             "#4e9a06",        # class: 'se'
+        String.Heredoc:            "#4e9a06",        # class: 'sh'
+        String.Interpol:           "#4e9a06",        # class: 'si'
+        String.Other:              "#4e9a06",        # class: 'sx'
+        String.Regex:              "#4e9a06",        # class: 'sr'
+        String.Single:             "#4e9a06",        # class: 's1'
+        String.Symbol:             "#4e9a06",        # class: 'ss'
+
+        Generic:                   "#000000",        # class: 'g'
+        Generic.Deleted:           "#a40000",        # class: 'gd'
+        Generic.Emph:              "italic #000000", # class: 'ge'
+        Generic.Error:             "#ef2929",        # class: 'gr'
+        Generic.Heading:           "bold #000080",   # class: 'gh'
+        Generic.Inserted:          "#00A000",        # class: 'gi'
+        Generic.Output:            "#888",           # class: 'go'
+        Generic.Prompt:            "#745334",        # class: 'gp'
+        Generic.Strong:            "bold #000000",   # class: 'gs'
+        Generic.Subheading:        "bold #800080",   # class: 'gu'
+        Generic.Traceback:         "bold #a40000",   # class: 'gt'
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/flaskstyle.sty	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,118 @@
+\definecolor{TitleColor}{rgb}{0,0,0}
+\definecolor{InnerLinkColor}{rgb}{0,0,0}
+
+\renewcommand{\maketitle}{%
+  \begin{titlepage}%
+    \let\footnotesize\small
+    \let\footnoterule\relax
+    \ifsphinxpdfoutput
+      \begingroup
+      % This \def is required to deal with multi-line authors; it
+      % changes \\ to ', ' (comma-space), making it pass muster for
+      % generating document info in the PDF file.
+      \def\\{, }
+      \pdfinfo{
+        /Author (\@author)
+        /Title (\@title)
+      }
+      \endgroup
+    \fi
+    \begin{flushright}%
+      %\sphinxlogo%
+      {\center
+        \vspace*{3cm}
+      	\includegraphics{logo.pdf}
+        \vspace{3cm}
+	\par
+        {\rm\Huge \@title \par}%
+        {\em\LARGE \py@release\releaseinfo \par}
+        {\large
+         \@date \par
+         \py@authoraddress \par
+        }}%
+    \end{flushright}%\par
+    \@thanks
+  \end{titlepage}%
+  \cleardoublepage%
+  \setcounter{footnote}{0}%
+  \let\thanks\relax\let\maketitle\relax
+  %\gdef\@thanks{}\gdef\@author{}\gdef\@title{}
+}
+
+\fancypagestyle{normal}{
+  \fancyhf{}
+  \fancyfoot[LE,RO]{{\thepage}}
+  \fancyfoot[LO]{{\nouppercase{\rightmark}}}
+  \fancyfoot[RE]{{\nouppercase{\leftmark}}}
+  \fancyhead[LE,RO]{{ \@title, \py@release}}
+  \renewcommand{\headrulewidth}{0.4pt}
+  \renewcommand{\footrulewidth}{0.4pt}
+}
+
+\fancypagestyle{plain}{
+  \fancyhf{}
+  \fancyfoot[LE,RO]{{\thepage}}
+  \renewcommand{\headrulewidth}{0pt}
+  \renewcommand{\footrulewidth}{0.4pt}
+}
+
+\titleformat{\section}{\Large}%
+            {\py@TitleColor\thesection}{0.5em}{\py@TitleColor}{\py@NormalColor}
+\titleformat{\subsection}{\large}%
+            {\py@TitleColor\thesubsection}{0.5em}{\py@TitleColor}{\py@NormalColor}
+\titleformat{\subsubsection}{}%
+            {\py@TitleColor\thesubsubsection}{0.5em}{\py@TitleColor}{\py@NormalColor}
+\titleformat{\paragraph}{\large}%
+            {\py@TitleColor}{0em}{\py@TitleColor}{\py@NormalColor}
+
+\ChNameVar{\raggedleft\normalsize}
+\ChNumVar{\raggedleft \bfseries\Large}
+\ChTitleVar{\raggedleft \rm\Huge}
+
+\renewcommand\thepart{\@Roman\c@part}
+\renewcommand\part{%
+   \pagestyle{empty}
+   \if@noskipsec \leavevmode \fi
+   \cleardoublepage
+   \vspace*{6cm}%
+   \@afterindentfalse
+   \secdef\@part\@spart}
+
+\def\@part[#1]#2{%
+    \ifnum \c@secnumdepth >\m@ne
+      \refstepcounter{part}%
+      \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}%
+    \else
+      \addcontentsline{toc}{part}{#1}%
+    \fi
+    {\parindent \z@ %\center
+     \interlinepenalty \@M
+     \normalfont
+     \ifnum \c@secnumdepth >\m@ne
+       \rm\Large \partname~\thepart
+       \par\nobreak
+     \fi
+     \MakeUppercase{\rm\Huge #2}%
+     \markboth{}{}\par}%
+    \nobreak
+    \vskip 8ex
+    \@afterheading}
+\def\@spart#1{%
+    {\parindent \z@ %\center
+     \interlinepenalty \@M
+     \normalfont
+     \huge \bfseries #1\par}%
+     \nobreak
+     \vskip 3ex
+     \@afterheading}
+
+% use inconsolata font
+\usepackage{inconsolata}
+
+% fix single quotes, for inconsolata. (does not work)
+%%\usepackage{textcomp}
+%%\begingroup
+%%  \catcode`'=\active
+%%  \g@addto@macro\@noligs{\let'\textsinglequote}
+%%  \endgroup
+%%\endinput
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/foreword.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,109 @@
+Foreword
+========
+
+Read this before you get started with Flask.  This hopefully answers some
+questions about the purpose and goals of the project, and when you
+should or should not be using it.
+
+What does "micro" mean?
+-----------------------
+
+To me, the "micro" in microframework refers not only to the simplicity and
+small size of the framework, but also to the typically limited complexity
+and size of applications that are written with the framework.  Also the
+fact that you can have an entire application in a single Python file.  To
+be approachable and concise, a microframework sacrifices a few features
+that may be necessary in larger or more complex applications.
+
+For example, Flask uses thread-local objects internally so that you don't
+have to pass objects around from function to function within a request in
+order to stay threadsafe.  While this is a really easy approach and saves
+you a lot of time, it might also cause some troubles for very large
+applications because changes on these thread-local objects can happen
+anywhere in the same thread.
+
+Flask provides some tools to deal with the downsides of this approach but
+it might be an issue for larger applications because in theory
+modifications on these objects might happen anywhere in the same thread.
+
+Flask is also based on convention over configuration, which means that
+many things are preconfigured.  For example, by convention, templates and
+static files are in subdirectories within the Python source tree of the
+application.
+
+The main reason however why Flask is called a "microframework" is the idea
+to keep the core simple but extensible.  There is no database abstraction
+layer, no form validation or anything else where different libraries
+already exist that can handle that.  However Flask knows the concept of
+extensions that can add this functionality into your application as if it
+was implemented in Flask itself.  There are currently extensions for
+object relational mappers, form validation, upload handling, various open
+authentication technologies and more.
+
+However Flask is not much code and it is built on a very solid foundation
+and with that it is very easy to adapt for large applications.  If you are
+interested in that, check out the :ref:`becomingbig` chapter.
+
+If you are curious about the Flask design principles, head over to the
+section about :ref:`design`.
+
+A Framework and an Example
+--------------------------
+
+Flask is not only a microframework; it is also an example.  Based on
+Flask, there will be a series of blog posts that explain how to create a
+framework.  Flask itself is just one way to implement a framework on top
+of existing libraries.  Unlike many other microframeworks, Flask does not
+try to implement everything on its own; it reuses existing code.
+
+Web Development is Dangerous
+----------------------------
+
+I'm not joking.  Well, maybe a little.  If you write a web
+application, you are probably allowing users to register and leave their
+data on your server.  The users are entrusting you with data.  And even if
+you are the only user that might leave data in your application, you still
+want that data to be stored securely.
+
+Unfortunately, there are many ways the security of a web application can be
+compromised.  Flask protects you against one of the most common security
+problems of modern web applications: cross-site scripting (XSS).  Unless
+you deliberately mark insecure HTML as secure, Flask and the underlying
+Jinja2 template engine have you covered.  But there are many more ways to
+cause security problems.
+
+The documentation will warn you about aspects of web development that
+require attention to security.  Some of these security concerns
+are far more complex than one might think, and we all sometimes underestimate
+the likelihood that a vulnerability will be exploited, until a clever
+attacker figures out a way to exploit our applications.  And don't think
+that your application is not important enough to attract an attacker.
+Depending on the kind of attack, chances are that automated bots are
+probing for ways to fill your database with spam, links to malicious
+software, and the like.
+
+So always keep security in mind when doing web development.
+
+The Status of Python 3
+----------------------
+
+Currently the Python community is in the process of improving libraries to
+support the new iteration of the Python programming language.
+Unfortunately there are a few problems with Python 3, namely the missing
+consent on what WSGI for Python 3 should look like.  These problems are
+partially caused by changes in the language that went unreviewed for too
+long, also partially the ambitions of everyone involved to drive the WSGI
+standard forward.
+
+Because of that we strongly recommend against using Python 3 for web
+development of any kind and wait until the WSGI situation is resolved.
+You will find a couple of frameworks and web libraries on PyPI that claim
+Python 3 support, but this support is based on the broken WSGI
+implementation provided by Python 3.0 and 3.1 which will most likely
+change in the near future.
+
+Werkzeug and Flask will be ported to Python 3 as soon as a solution for
+WSGI is found, and we will provide helpful tips how to upgrade existing
+applications to Python 3.  Until then, we strongly recommend using Python
+2.6 and 2.7 with activated Python 3 warnings during development, as well
+as the Unicode literals `__future__` feature.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/htmlfaq.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,207 @@
+HTML/XHTML FAQ
+==============
+
+The Flask documentation and example applications are using HTML5.  You
+may notice that in many situations, when end tags are optional they are
+not used, so that the HTML is cleaner and faster to load.  Because there
+is much confusion about HTML and XHTML among developers, this document tries
+to answer some of the major questions.
+
+
+History of XHTML
+----------------
+
+For a while, it appeared that HTML was about to be replaced by XHTML.
+However, barely any websites on the Internet are actual XHTML (which is
+HTML processed using XML rules).  There are a couple of major reasons
+why this is the case.  One of them is Internet Explorer's lack of proper
+XHTML support. The XHTML spec states that XHTML must be served with the MIME
+type `application/xhtml+xml`, but Internet Explorer refuses to read files
+with that MIME type.
+While it is relatively easy to configure Web servers to serve XHTML properly,
+few people do.  This is likely because properly using XHTML can be quite
+painful.
+
+One of the most important causes of pain is XML's draconian (strict and
+ruthless) error handling.  When an XML parsing error is encountered,
+the browser is supposed to show the user an ugly error message, instead
+of attempting to recover from the error and display what it can.  Most of
+the (X)HTML generation on the web is based on non-XML template engines
+(such as Jinja, the one used in Flask) which do not protect you from
+accidentally creating invalid XHTML.  There are XML based template engines,
+such as Kid and the popular Genshi, but they often come with a larger
+runtime overhead and, are not as straightforward to use because they have
+to obey XML rules.
+
+The majority of users, however, assumed they were properly using XHTML.
+They wrote an XHTML doctype at the top of the document and self-closed all
+the necessary tags (``<br>`` becomes ``<br/>`` or ``<br></br>`` in XHTML).
+However, even if the document properly validates as XHTML, what really
+determines XHTML/HTML processing in browsers is the MIME type, which as
+said before is often not set properly. So the valid XHTML was being treated
+as invalid HTML.
+
+XHTML also changed the way JavaScript is used. To properly work with XHTML,
+programmers have to use the namespaced DOM interface with the XHTML
+namespace to query for HTML elements.
+
+History of HTML5
+----------------
+
+Development of the HTML5 specification was started in 2004 under the name
+"Web Applications 1.0" by the Web Hypertext Application Technology Working
+Group, or WHATWG (which was formed by the major browser vendors Apple,
+Mozilla, and Opera) with the goal of writing a new and improved HTML
+specification, based on existing browser behaviour instead of unrealistic
+and backwards-incompatible specifications.
+
+For example, in HTML4 ``<title/Hello/`` theoretically parses exactly the
+same as ``<title>Hello</title>``.  However, since people were using
+XHTML-like tags along the lines of ``<link />``, browser vendors implemented
+the XHTML syntax over the syntax defined by the specification.
+
+In 2007, the specification was adopted as the basis of a new HTML
+specification under the umbrella of the W3C, known as HTML5.  Currently,
+it appears that XHTML is losing traction, as the XHTML 2 working group has
+been disbanded and HTML5 is being implemented by all major browser vendors.
+
+HTML versus XHTML
+-----------------
+
+The following table gives you a quick overview of features available in
+HTML 4.01, XHTML 1.1 and HTML5. (XHTML 1.0 is not included, as it was
+superseded by XHTML 1.1 and the barely-used XHTML5.)
+
+.. tabularcolumns:: |p{9cm}|p{2cm}|p{2cm}|p{2cm}|
+
++-----------------------------------------+----------+----------+----------+
+|                                         | HTML4.01 | XHTML1.1 | HTML5    |
++=========================================+==========+==========+==========+
+| ``<tag/value/`` == ``<tag>value</tag>`` | |Y| [1]_ | |N|      | |N|      |
++-----------------------------------------+----------+----------+----------+
+| ``<br/>`` supported                     | |N|      | |Y|      | |Y| [2]_ |
++-----------------------------------------+----------+----------+----------+
+| ``<script/>`` supported                 | |N|      | |Y|      | |N|      |
++-----------------------------------------+----------+----------+----------+
+| should be served as `text/html`         | |Y|      | |N| [3]_ | |Y|      |
++-----------------------------------------+----------+----------+----------+
+| should be served as                     | |N|      | |Y|      | |N|      |
+| `application/xhtml+xml`                 |          |          |          |
++-----------------------------------------+----------+----------+----------+
+| strict error handling                   | |N|      | |Y|      | |N|      |
++-----------------------------------------+----------+----------+----------+
+| inline SVG                              | |N|      | |Y|      | |Y|      |
++-----------------------------------------+----------+----------+----------+
+| inline MathML                           | |N|      | |Y|      | |Y|      |
++-----------------------------------------+----------+----------+----------+
+| ``<video>`` tag                         | |N|      | |N|      | |Y|      |
++-----------------------------------------+----------+----------+----------+
+| ``<audio>`` tag                         | |N|      | |N|      | |Y|      |
++-----------------------------------------+----------+----------+----------+
+| New semantic tags like ``<article>``    | |N|      | |N|      | |Y|      |
++-----------------------------------------+----------+----------+----------+
+
+.. [1] This is an obscure feature inherited from SGML. It is usually not
+       supported by browsers, for reasons detailed above.
+.. [2] This is for compatibility with server code that generates XHTML for
+       tags such as ``<br>``.  It should not be used in new code.
+.. [3] XHTML 1.0 is the last XHTML standard that allows to be served
+       as `text/html` for backwards compatibility reasons.
+
+.. |Y| image:: _static/yes.png
+       :alt: Yes
+.. |N| image:: _static/no.png
+       :alt: No
+
+What does "strict" mean?
+------------------------
+
+HTML5 has strictly defined parsing rules, but it also specifies exactly
+how a browser should react to parsing errors - unlike XHTML, which simply
+states parsing should abort. Some people are confused by apparently
+invalid syntax that still generates the expected results (for example,
+missing end tags or unquoted attribute values).
+
+Some of these work because of the lenient error handling most browsers use
+when they encounter a markup error, others are actually specified.  The
+following constructs are optional in HTML5 by standard, but have to be
+supported by browsers:
+
+-   Wrapping the document in an ``<html>`` tag
+-   Wrapping header elements in ``<head>`` or the body elements in
+    ``<body>``
+-   Closing the ``<p>``, ``<li>``, ``<dt>``, ``<dd>``, ``<tr>``,
+    ``<td>``, ``<th>``, ``<tbody>``, ``<thead>``, or ``<tfoot>`` tags.
+-   Quoting attributes, so long as they contain no whitespace or
+    special characters (like ``<``, ``>``, ``'``, or ``"``).
+-   Requiring boolean attributes to have a value.
+
+This means the following page in HTML5 is perfectly valid:
+
+.. sourcecode:: html
+
+    <!doctype html>
+    <title>Hello HTML5</title>
+    <div class=header>
+      <h1>Hello HTML5</h1>
+      <p class=tagline>HTML5 is awesome
+    </div>
+    <ul class=nav>
+      <li><a href=/index>Index</a>
+      <li><a href=/downloads>Downloads</a>
+      <li><a href=/about>About</a>
+    </ul>
+    <div class=body>
+      <h2>HTML5 is probably the future</h2>
+      <p>
+        There might be some other things around but in terms of
+        browser vendor support, HTML5 is hard to beat.
+      <dl>
+        <dt>Key 1
+        <dd>Value 1
+        <dt>Key 2
+        <dd>Value 2
+      </dl>
+    </div>
+
+
+New technologies in HTML5
+-------------------------
+
+HTML5 adds many new features that make Web applications easier to write
+and to use.
+
+-   The ``<audio>`` and ``<video>`` tags provide a way to embed audio and
+    video without complicated add-ons like QuickTime or Flash.
+-   Semantic elements like ``<article>``, ``<header>``, ``<nav>``, and
+    ``<time>`` that make content easier to understand.
+-   The ``<canvas>`` tag, which supports a powerful drawing API, reducing
+    the need for server-generated images to present data graphically.
+-   New form control types like ``<input type="date">`` that allow user
+    agents to make entering and validating values easier.
+-   Advanced JavaScript APIs like Web Storage, Web Workers, Web Sockets,
+    geolocation, and offline applications.
+
+Many other features have been added, as well. A good guide to new features
+in HTML5 is Mark Pilgrim's soon-to-be-published book, `Dive Into HTML5`_.
+Not all of them are supported in browsers yet, however, so use caution.
+
+.. _Dive Into HTML5: http://www.diveintohtml5.org/
+
+What should be used?
+--------------------
+
+Currently, the answer is HTML5.  There are very few reasons to use XHTML
+considering the latest developments in Web browsers.  To summarize the
+reasons given above:
+
+-   Internet Explorer (which, sadly, currently leads in market share)
+    has poor support for XHTML.
+-   Many JavaScript libraries also do not support XHTML, due to the more
+    complicated namespacing API it requires.
+-   HTML5 adds several new features, including semantic tags and the
+    long-awaited ``<audio>`` and ``<video>`` tags.
+-   It has the support of most browser vendors behind it.
+-   It is much easier to write, and more compact.
+
+For most applications, it is undoubtedly better to use HTML5 than XHTML.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/index.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,30 @@
+:orphan:
+
+Welcome to Flask
+================
+
+.. image:: _static/logo-full.png
+   :alt: Flask: web development, one drop at a time
+   :class: floatingflask
+
+Welcome to Flask's documentation.  This documentation is divided into
+different parts.  I recommend that you get started with
+:ref:`installation` and then head over to the :ref:`quickstart`.
+Besides the quickstart there is also a more detailed :ref:`tutorial` that
+shows how to create a complete (albeit small) application with Flask.  If
+you'd rather dive into the internals of Flask, check out
+the :ref:`api` documentation.  Common patterns are described in the
+:ref:`patterns` section.
+
+Flask depends on two external libraries: the `Jinja2`_ template
+engine and the `Werkzeug`_ WSGI toolkit.  These libraries are not documented
+here.  If you want to dive into their documentation check out the
+following links:
+
+-   `Jinja2 Documentation <http://jinja.pocoo.org/2/documentation/>`_
+-   `Werkzeug Documentation <http://werkzeug.pocoo.org/documentation/>`_
+
+.. _Jinja2: http://jinja.pocoo.org/2/
+.. _Werkzeug: http://werkzeug.pocoo.org/
+
+.. include:: contents.rst.inc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/installation.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,175 @@
+.. _installation:
+
+Installation
+============
+
+Flask depends on two external libraries, `Werkzeug
+<http://werkzeug.pocoo.org/>`_ and `Jinja2 <http://jinja.pocoo.org/2/>`_.
+Werkzeug is a toolkit for WSGI, the standard Python interface between web
+applications and a variety of servers for both development and deployment.
+Jinja2 renders templates.
+
+So how do you get all that on your computer quickly?  There are many ways
+which this section will explain, but the most kick-ass method is
+virtualenv, so let's look at that first.
+
+Either way, you will need Python 2.5 or higher to get started, so be sure
+to have an up to date Python 2.x installation.  At the time of writing,
+the WSGI specification is not yet finalized for Python 3, so Flask cannot
+support the 3.x series of Python.
+
+.. _virtualenv:
+
+virtualenv
+----------
+
+Virtualenv is probably what you want to use during development, and in
+production too if you have shell access there.
+
+What problem does virtualenv solve?  If you like Python as I do,
+chances are you want to use it for other projects besides Flask-based
+web applications.  But the more projects you have, the more likely it is
+that you will be working with different versions of Python itself, or at
+least different versions of Python libraries.  Let's face it; quite often
+libraries break backwards compatibility, and it's unlikely that any serious
+application will have zero dependencies.  So what do you do if two or more
+of your projects have conflicting dependencies?
+
+Virtualenv to the rescue!  It basically enables multiple side-by-side
+installations of Python, one for each project.  It doesn't actually
+install separate copies of Python, but it does provide a clever way
+to keep different project environments isolated.
+
+So let's see how virtualenv works!
+
+If you are on Mac OS X or Linux, chances are that one of the following two
+commands will work for you::
+
+    $ sudo easy_install virtualenv
+
+or even better::
+
+    $ sudo pip install virtualenv
+
+One of these will probably install virtualenv on your system.  Maybe it's
+even in your package manager.  If you use Ubuntu, try::
+
+    $ sudo apt-get install python-virtualenv
+
+If you are on Windows and don't have the `easy_install` command, you must
+install it first.  Check the :ref:`windows-easy-install` section for more
+information about how to do that.  Once you have it installed, run the
+same commands as above, but without the `sudo` prefix.
+
+Once you have virtualenv installed, just fire up a shell and create
+your own environment.  I usually create a project folder and an `env`
+folder within::
+
+    $ mkdir myproject
+    $ cd myproject
+    $ virtualenv env
+    New python executable in env/bin/python
+    Installing setuptools............done.
+
+Now, whenever you want to work on a project, you only have to activate
+the corresponding environment.  On OS X and Linux, do the following::
+
+    $ . env/bin/activate
+
+(Note the space between the dot and the script name.  The dot means that
+this script should run in the context of the current shell.  If this command
+does not work in your shell, try replacing the dot with ``source``)
+
+If you are a Windows user, the following command is for you::
+
+    $ env\scripts\activate
+
+Either way, you should now be using your virtualenv (see how the prompt of
+your shell has changed to show the virtualenv).
+
+Now you can just enter the following command to get Flask activated in
+your virtualenv::
+
+    $ easy_install Flask
+
+A few seconds later you are good to go.
+
+
+System Wide Installation
+------------------------
+
+This is possible as well, but I do not recommend it.  Just run
+`easy_install` with root rights::
+
+    $ sudo easy_install Flask
+
+(Run it in an Admin shell on Windows systems and without `sudo`).
+
+
+Living on the Edge
+------------------
+
+If you want to work with the latest version of Flask, there are two ways: you
+can either let `easy_install` pull in the development version, or tell it
+to operate on a git checkout.  Either way, virtualenv is recommended.
+
+Get the git checkout in a new virtualenv and run in development mode::
+
+    $ git clone http://github.com/mitsuhiko/flask.git
+    Initialized empty Git repository in ~/dev/flask/.git/
+    $ cd flask
+    $ virtualenv env
+    $ . env/bin/activate
+    New python executable in env/bin/python
+    Installing setuptools............done.
+    $ python setup.py develop
+    ...
+    Finished processing dependencies for Flask
+
+This will pull in the dependencies and activate the git head as the current
+version inside the virtualenv.  Then you just have to ``git pull origin``
+to get the latest version.
+
+To just get the development version without git, do this instead::
+
+    $ mkdir flask
+    $ cd flask
+    $ virtualenv env
+    $ . env/bin/activate
+    New python executable in env/bin/python
+    Installing setuptools............done.
+    $ easy_install Flask==dev
+    ...
+    Finished processing dependencies for Flask==dev
+
+.. _windows-easy-install:
+
+`easy_install` on Windows
+-------------------------
+
+On Windows, installation of `easy_install` is a little bit trickier because
+slightly different rules apply on Windows than on Unix-like systems, but
+it's not difficult.  The easiest way to do it is to download the
+`ez_setup.py`_ file and run it.  The easiest way to run the file is to
+open your downloads folder and double-click on the file.
+
+Next, add the `easy_install` command and other Python scripts to the
+command search path, by adding your Python installation's Scripts folder
+to the `PATH` environment variable.  To do that, right-click on the
+"Computer" icon on the Desktop or in the Start menu, and choose
+"Properties".  Then, on Windows Vista and Windows 7 click on "Advanced System
+settings"; on Windows XP, click on the "Advanced" tab instead.  Then click
+on the "Environment variables" button and double click on the "Path"
+variable in the "System variables" section.  There append the path of your
+Python interpreter's Scripts folder; make sure you delimit it from
+existing values with a semicolon.  Assuming you are using Python 2.6 on
+the default path, add the following value::
+
+    ;C:\Python26\Scripts
+
+Then you are done.  To check that it worked, open the Command Prompt and
+execute ``easy_install``.  If you have User Account Control enabled on
+Windows Vista or Windows 7, it should prompt you for admin privileges.
+
+
+.. _ez_setup.py: http://peak.telecommunity.com/dist/ez_setup.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/latexindex.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,6 @@
+:orphan:
+
+Flask Documentation
+===================
+
+.. include:: contents.rst.inc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/license.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,48 @@
+License
+=======
+
+Flask is licensed under a three clause BSD License.  It basically means:
+do whatever you want with it as long as the copyright in Flask sticks
+around, the conditions are not modified and the disclaimer is present.
+Furthermore you must not use the names of the authors to promote derivatives
+of the software without written consent.
+
+The full license text can be found below (:ref:`flask-license`).  For the
+documentation and artwork different licenses apply.
+
+.. _authors:
+
+Authors
+-------
+
+.. include:: ../AUTHORS
+
+General License Definitions
+---------------------------
+
+The following section contains the full license texts for Flask and the
+documentation.
+
+-   "AUTHORS" hereby refers to all the authors listed in the
+    :ref:`authors` section.
+
+-   The ":ref:`flask-license`" applies to all the sourcecode shipped as
+    part of Flask (Flask itself as well as the examples and the unittests)
+    as well as documentation.
+
+-   The ":ref:`artwork-license`" applies to the project's Horn-Logo.
+
+.. _flask-license:
+
+Flask License
+-------------
+
+.. include:: ../LICENSE
+
+
+.. _artwork-license:
+
+Flask Artwork License
+---------------------
+
+.. include:: ../artwork/LICENSE
Binary file bundled/flask/docs/logo.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/make.bat	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,139 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html       to make standalone HTML files
+	echo.  dirhtml    to make HTML files named index.html in directories
+	echo.  singlehtml to make a single large HTML file
+	echo.  pickle     to make pickle files
+	echo.  json       to make JSON files
+	echo.  htmlhelp   to make HTML files and a HTML help project
+	echo.  qthelp     to make HTML files and a qthelp project
+	echo.  devhelp    to make HTML files and a Devhelp project
+	echo.  epub       to make an epub
+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  changes    to make an overview over all changed/added/deprecated items
+	echo.  linkcheck  to check all external links for integrity
+	echo.  doctest    to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "singlehtml" (
+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Flask.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Flask.ghc
+	goto end
+)
+
+if "%1" == "devhelp" (
+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% _build/devhelp
+	echo.
+	echo.Build finished.
+	goto end
+)
+
+if "%1" == "epub" (
+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+	echo.
+	echo.Build finished. The epub file is in %BUILDDIR%/epub.
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/appfactories.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,75 @@
+.. _app-factories:
+
+Application Factories
+=====================
+
+If you are already using packages and modules for your application
+(:ref:`packages`) there are a couple of really nice ways to further improve
+the experience.  A common pattern is creating the application object when
+the module is imported.  But if you move the creation of this object,
+into a function, you can then create multiple instances of this and later.
+
+So why would you want to do this?
+
+1.  Testing.  You can have instances of the application with different
+    settings to test every case.
+2.  Multiple instances.  Imagine you want to run different versions of the
+    same application.  Of course you could have multiple instances with
+    different configs set up in your webserver, but if you use factories,
+    you can have multiple instances of the same application running in the
+    same application process which can be handy.
+
+So how would you then actually implement that?
+
+Basic Factories
+---------------
+
+The idea is to set up the application in a function.  Like this::
+
+    def create_app(config_filename):
+        app = Flask(__name__)
+        app.config.from_pyfile(config_filename)
+
+        from yourapplication.views.admin import admin
+        from yourapplication.views.frontend import frontend
+        app.register_module(admin)
+        app.register_module(frontend)
+
+        return app
+
+The downside is that you cannot use the application object in the modules
+at import time.  You can however use it from within a request.  How do you
+get access the application with the config?  Use
+:data:`~flask.current_app`::
+
+    from flask import current_app, Module, render_template
+    admin = Module(__name__, url_prefix='/admin')
+
+    @admin.route('/')
+    def index():
+        return render_template(current_app.config['INDEX_TEMPLATE'])
+
+Here we look up the name of a template in the config.
+
+Using Applications
+------------------
+
+So to use such an application you then have to create the application
+first.  Here an example `run.py` file that runs such an application::
+
+    from yourapplication import create_app
+    app = create_app('/path/to/config.cfg')
+    app.run()
+
+Factory Improvements
+--------------------
+
+The factory function from above is not very clever so far, you can improve
+it.  The following changes are straightforward and possible:
+
+1.  make it possible to pass in configuration values for unittests so that
+    you don't have to create config files on the filesystem
+2.  call a function from a module when the application is setting up so
+    that you have a place to modify attributes of the application (like
+    hooking in before / after request handlers etc.)
+3.  Add in WSGI middlewares when the application is creating if necessary.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/caching.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,69 @@
+.. _caching-pattern:
+
+Caching
+=======
+
+When your application runs slow, throw some caches in.  Well, at least
+it's the easiest way to speed up things.  What does a cache do?  Say you
+have a function that takes some time to complete but the results would
+still be good enough if they were 5 minutes old.  So then the idea is that
+you actually put the result of that calculation into a cache for some
+time.
+
+Flask itself does not provide caching for you, but Werkzeug, one of the
+libraries it is based on, has some very basic cache support.  It supports
+multiple cache backends, normally you want to use a memcached server.
+
+Setting up a Cache
+------------------
+
+You create a cache object once and keep it around, similar to how
+:class:`~flask.Flask` objects are created.  If you are using the
+development server you can create a
+:class:`~werkzeug.contrib.cache.SimpleCache` object, that one is a simple
+cache that keeps the item stored in the memory of the Python interpreter::
+
+    from werkzeug.contrib.cache import SimpleCache
+    cache = SimpleCache()
+
+If you want to use memcached, make sure to have one of the memcache modules
+supported (you get them from `PyPI <http://pypi.python.org/>`_) and a
+memcached server running somewhere.  This is how you connect to such an
+memcached server then::
+
+    from werkzeug.contrib.cache import MemcachedCache
+    cache = MemcachedCache(['127.0.0.1:11211'])
+
+If you are using App Engine, you can connect to the App Engine memcache
+server easily::
+
+    from werkzeug.contrib.cache import GAEMemcachedCache
+    cache = GAEMemcachedCache()
+
+Using a Cache
+-------------
+
+Now how can one use such a cache?  There are two very important
+operations: :meth:`~werkzeug.contrib.cache.BaseCache.get` and 
+:meth:`~werkzeug.contrib.cache.BaseCache.set`.  This is how to use them:
+
+To get an item from the cache call
+:meth:`~werkzeug.contrib.cache.BaseCache.get` with a string as key name.
+If something is in the cache, it is returned.  Otherwise that function
+will return `None`::
+
+    rv = cache.get('my-item')
+
+To add items to the cache, use the :meth:`~werkzeug.contrib.cache.BaseCache.set`
+method instead.  The first argument is the key and the second the value
+that should be set.  Also a timeout can be provided after which the cache
+will automatically remove item.
+
+Here a full example how this looks like normally::
+
+    def get_my_item():
+        rv = cache.get('my-item')
+        if rv is None:
+            rv = calculate_value()
+            cache.set('my-item', rv, timeout=5 * 60)
+        return rv
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/distribute.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,166 @@
+.. _distribute-deployment:
+
+Deploying with Distribute
+=========================
+
+`distribute`_, formerly setuptools, is an extension library that is
+commonly used to (like the name says) distribute Python libraries and
+extensions.  It extends distutils, a basic module installation system
+shipped with Python to also support various more complex constructs that
+make larger applications easier to distribute:
+
+- **support for dependencies**: a library or application can declare a
+  list of other libraries it depends on which will be installed
+  automatically for you.
+- **package registry**: setuptools registers your package with your
+  Python installation.  This makes it possible to query information
+  provided by one package from another package.  The best known feature of
+  this system is the entry point support which allows one package to
+  declare an "entry point" another package can hook into to extend the
+  other package.
+- **installation manager**: `easy_install`, which comes with distribute
+  can install other libraries for you.  You can also use `pip`_ which
+  sooner or later will replace `easy_install` which does more than just
+  installing packages for you.
+
+Flask itself, and all the libraries you can find on the cheeseshop
+are distributed with either distribute, the older setuptools or distutils.
+
+In this case we assume your application is called
+`yourapplication.py` and you are not using a module, but a :ref:`package
+<larger-applications>`.  Distributing resources with standard modules is
+not supported by `distribute`_ so we will not bother with it.  If you have
+not yet converted your application into a package, head over to the
+:ref:`larger-applications` pattern to see how this can be done.
+
+A working deployment with distribute is the first step into more complex
+and more automated deployment scenarios.  If you want to fully automate
+the process, also read the :ref:`fabric-deployment` chapter.
+
+Basic Setup Script
+------------------
+
+Because you have Flask running, you either have setuptools or distribute
+available on your system anyways.  If you do not, fear not, there is a
+script to install it for you: `distribute_setup.py`_.  Just download and
+run with your Python interpreter.
+
+Standard disclaimer applies: :ref:`you better use a virtualenv
+<virtualenv>`.
+
+Your setup code always goes into a file named `setup.py` next to your
+application.  The name of the file is only convention, but because
+everybody will look for a file with that name, you better not change it.
+
+Yes, even if you are using `distribute`, you are importing from a package
+called `setuptools`.  `distribute` is fully backwards compatible with
+`setuptools`, so it also uses the same import name.
+
+A basic `setup.py` file for a Flask application looks like this::
+
+    from setuptools import setup
+
+    setup(
+        name='Your Application',
+        version='1.0',
+        long_description=__doc__,
+        packages=['yourapplication'],
+        include_package_data=True,
+        zip_safe=False,
+        install_requires=['Flask']
+    )
+
+Please keep in mind that you have to list subpackages explicitly.  If you
+want distribute to lookup the packages for you automatically, you can use
+the `find_packages` function::
+
+    from setuptools import setup, find_packages
+
+    setup(
+        ...
+        packages=find_packages()
+    )
+
+Most parameters to the `setup` function should be self explanatory,
+`include_package_data` and `zip_safe` might not be.
+`include_package_data` tells distribute to look for a `MANIFEST.in` file
+and install all the entries that match as package data.  We will use this
+to distribute the static files and templates along with the Python module
+(see :ref:`distributing-resources`).  The `zip_safe` flag can be used to
+force or prevent zip Archive creation.  In general you probably don't want
+your packages to be installed as zip files because some tools do not
+support them and they make debugging a lot harder.
+
+
+.. _distributing-resources:
+
+Distributing Resources
+----------------------
+
+If you try to install the package you just created, you will notice that
+folders like `static` or `templates` are not installed for you.  The
+reason for this is that distribute does not know which files to add for
+you.  What you should do, is to create a `MANIFEST.in` file next to your
+`setup.py` file.  This file lists all the files that should be added to
+your tarball::
+
+    recursive-include yourapplication/templates *
+    recursive-include yourapplication/static *
+
+Don't forget that even if you enlist them in your `MANIFEST.in` file, they
+won't be installed for you unless you set the `include_package_data`
+parameter of the `setup` function to `True`!
+
+
+Declaring Dependencies
+----------------------
+
+Dependencies are declared in the `install_requires` parameter as list.
+Each item in that list is the name of a package that should be pulled from
+PyPI on installation.  By default it will always use the most recent
+version, but you can also provide minimum and maximum version
+requirements.  Here some examples::
+
+    install_requires=[
+        'Flask>=0.2',
+        'SQLAlchemy>=0.6',
+        'BrokenPackage>=0.7,<=1.0'
+    ]
+
+I mentioned earlier that dependencies are pulled from PyPI.  What if you
+want to depend on a package that cannot be found on PyPI and won't be
+because it is an internal package you don't want to share with anyone?
+Just still do as if there was a PyPI entry for it and provide a list of
+alternative locations where distribute should look for tarballs::
+
+    dependency_links=['http://example.com/yourfiles']
+
+Make sure that page has a directory listing and the links on the page are
+pointing to the actual tarballs with their correct filenames as this is
+how distribute will find the files.  If you have an internal company
+server that contains the packages, provide the URL to that server there.
+
+
+Installing / Developing
+-----------------------
+
+To install your application (ideally into a virtualenv) just run the
+`setup.py` script with the `install` parameter.  It will install your
+application into the virtualenv's site-packages folder and also download
+and install all dependencies::
+
+    $ python setup.py install
+
+If you are developing on the package and also want the requirements to be
+installed, you can use the `develop` command instead::
+
+    $ python setup.py develop
+
+This has the advantage of just installing a link to the site-packages
+folder instead of copying the data over.  You can then continue to work on
+the code without having to run `install` again after each change.
+
+
+.. _distribute: http://pypi.python.org/pypi/distribute
+.. _pip: http://pypi.python.org/pypi/pip
+.. _distribute_setup.py: http://python-distribute.org/distribute_setup.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/errorpages.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,77 @@
+Custom Error Pages
+==================
+
+Flask comes with a handy :func:`~flask.abort` function that aborts a
+request with an HTTP error code early.  It will also provide a plain black
+and white error page for you with a basic description, but nothing fancy.
+
+Depending on the error code it is less or more likely for the user to
+actually see such an error.
+
+Common Error Codes
+------------------
+
+The following error codes are some that are often displayed to the user,
+even if the application behaves correctly:
+
+*404 Not Found*
+    The good old "chap, you made a mistake typing that URL" message.  So
+    common that even novices to the internet know that 404 means: damn,
+    the thing I was looking for is not there.  It's a very good idea to
+    make sure there is actually something useful on a 404 page, at least a
+    link back to the index.
+
+*403 Forbidden*
+    If you have some kind of access control on your website, you will have
+    to send a 403 code for disallowed resources.  So make sure the user
+    is not lost when he tries to access a resource he cannot access.
+
+*410 Gone*
+    Did you know that there the "404 Not Found" has a brother named "410
+    Gone"?  Few people actually implement that, but the idea is that
+    resources that previously existed and got deleted answer with 410
+    instead of 404.  If you are not deleting documents permanently from
+    the database but just mark them as deleted, do the user a favour and
+    use the 410 code instead and display a message that what he was
+    looking for was deleted for all eternity.
+
+*500 Internal Server Error*
+    Usually happens on programming errors or if the server is overloaded.
+    A terrible good idea to have a nice page there, because your
+    application *will* fail sooner or later (see also:
+    :ref:`application-errors`).
+
+
+Error Handlers
+--------------
+
+An error handler is a function, just like a view function, but it is
+called when an error happens and is passed that error.  The error is most
+likely a :exc:`~werkzeug.exceptions.HTTPException`, but in one case it
+can be a different error: a handler for internal server errors will be
+passed other exception instances as well if they are uncaught.
+
+An error handler is registered with the :meth:`~flask.Flask.errorhandler`
+decorator and the error code of the exception.  Keep in mind that Flask
+will *not* set the error code for you, so make sure to also provide the
+HTTP status code when returning a response.
+
+Here an example implementation for a "404 Page Not Found" exception::
+
+    from flask import render_template
+
+    @app.errorhandler(404)
+    def page_not_found(e):
+        return render_template('404.html'), 404
+
+An example template might be this:
+
+.. sourcecode:: html+jinja
+
+   {% extends "layout.html" %}
+   {% block title %}Page Not Found{% endblock %}
+   {% block body %}
+     <h1>Page Not Found</h1>
+     <p>What you were looking for is just not there.
+     <p><a href="{{ url_for('index') }}">go somewhere nice</a>
+   {% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/fabric.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,196 @@
+.. _fabric-deployment:
+
+Deploying with Fabric
+=====================
+
+`Fabric`_ is a tool for Python similar to Makefiles but with the ability
+to execute commands on a remote server.  In combination with a properly
+set up Python package (:ref:`larger-applications`) and a good concept for
+configurations (:ref:`config`) it is very easy to deploy Flask
+applications to external servers.
+
+Before we get started, here a quick checklist of things we have to ensure
+upfront:
+
+-   Fabric 1.0 has to be installed locally.  This tutorial assumes the
+    latest version of Fabric.
+-   The application already has to be a package and requires a working
+    `setup.py` file (:ref:`distribute-deployment`).
+-   In the following example we are using `mod_wsgi` for the remote
+    servers.  You can of course use your own favourite server there, but
+    for this example we chose Apache + `mod_wsgi` because it's very easy
+    to setup and has a simple way to reload applications without root
+    access.
+
+Creating the first Fabfile
+--------------------------
+
+A fabfile is what controls what Fabric executes.  It is named `fabfile.py`
+and executed by the `fab` command.  All the functions defined in that file
+will show up as `fab` subcommands.  They are executed on one or more
+hosts.  These hosts can be defined either in the fabfile or on the command
+line.  In this case we will add them to the fabfile.
+
+This is a basic first example that has the ability to upload the current
+sourcecode to the server and install it into a already existing
+virtual environment::
+
+    from fabric.api import *
+
+    # the user to use for the remote commands
+    env.user = 'appuser'
+    # the servers where the commands are executed
+    env.hosts = ['server1.example.com', 'server2.example.com']
+
+    def pack():
+        # create a new source distribution as tarball
+        local('python setup.py sdist --formats=gztar', capture=False)
+
+    def deploy():
+        # figure out the release name and version
+        dist = local('python setup.py --fullname').strip()
+        # upload the source tarball to the temporary folder on the server
+        put('dist/%s.tar.gz' % dist, '/tmp/yourapplication.tar.gz')
+        # create a place where we can unzip the tarball, then enter
+        # that directory and unzip it
+        run('mkdir yourapplication')
+        with cd('/tmp/yourapplication'):
+            run('tar xzf /tmp/yourapplication.tar.gz')
+        # now setup the package with our virtual environment's
+        # python interpreter
+        run('/var/www/yourapplication/env/bin/python setup.py install')
+        # now that all is set up, delete the folder again
+        run('rm -rf /tmp/yourapplication /tmp/yourapplication.tar.gz')
+        # and finally touch the .wsgi file so that mod_wsgi triggers
+        # a reload of the application
+        run('touch /var/www/yourapplication.wsgi')
+
+The example above is well documented and should be straightforward.  Here
+a recap of the most common commands fabric provides:
+
+-   `run` - executes a command on a remote server
+-   `local` - executes a command on the local machine
+-   `put` - uploads a file to the remote server
+-   `cd` - changes the directory on the serverside.  This has to be used
+    in combination with the `with` statement.
+
+Running Fabfiles
+----------------
+
+Now how do you execute that fabfile?  You use the `fab` command.  To
+deploy the current version of the code on the remote server you would use
+this command::
+
+    $ fab pack deploy
+
+However this requires that our server already has the
+``/var/www/yourapplication`` folder created and
+``/var/www/yourapplication/env`` to be a virtual environment.  Furthermore
+are we not creating the configuration or `.wsgi` file on the server.  So
+how do we bootstrap a new server into our infrastructure?
+
+This now depends on the number of servers we want to set up.  If we just
+have one application server (which the majority of applications will
+have), creating a command in the fabfile for this is overkill.  But
+obviously you can do that.  In that case you would probably call it
+`setup` or `bootstrap` and then pass the servername explicitly on the
+command line::
+
+    $ fab -H newserver.example.com bootstrap
+
+To setup a new server you would roughly do these steps:
+
+1.  Create the directory structure in ``/var/www``::
+
+        $ mkdir /var/www/yourapplication
+        $ cd /var/www/yourapplication
+        $ virtualenv --distribute env
+
+2.  Upload a new `application.wsgi` file to the server and the
+    configuration file for the application (eg: `application.cfg`)
+
+3.  Create a new Apache config for `yourapplication` and activate it.
+    Make sure to activate watching for changes of the `.wsgi` file so
+    that we can automatically reload the application by touching it.
+    (See :ref:`mod_wsgi-deployment` for more information)
+
+So now the question is, where do the `application.wsgi` and
+`application.cfg` files come from?
+
+The WSGI File
+-------------
+
+The WSGI file has to import the application and also to set an environment
+variable so that the application knows where to look for the config.  This
+is a short example that does exactly that::
+
+    import os
+    os.environ['YOURAPPLICATION_CONFIG'] = '/var/www/yourapplication/application.cfg'
+    from yourapplication import app
+
+The application itself then has to initialize itself like this to look for
+the config at that environment variable::
+
+    app = Flask(__name__)
+    app.config.from_object('yourapplication.default_config')
+    app.config.from_envvar('YOURAPPLICATION_CONFIG')
+
+This approach is explained in detail in the :ref:`config` section of the
+documentation.
+
+The Configuration File
+----------------------
+
+Now as mentioned above, the application will find the correct
+configuration file by looking up the `YOURAPPLICATION_CONFIG` environment
+variable.  So we have to put the configuration in a place where the
+application will able to find it.  Configuration files have the unfriendly
+quality of being different on all computers, so you do not version them
+usually.
+
+A popular approach is to store configuration files for different servers
+in a separate version control repository and check them out on all
+servers.  Then symlink the file that is active for the server into the
+location where it's expected (eg: ``/var/www/yourapplication``).
+
+Either way, in our case here we only expect one or two servers and we can
+upload them ahead of time by hand.
+
+First Deployment
+----------------
+
+Now we can do our first deployment.  We have set up the servers so that
+they have their virtual environments and activated apache configs.  Now we
+can pack up the application and deploy it::
+
+    $ fab pack deploy
+
+Fabric will now connect to all servers and run the commands as written
+down in the fabfile.  First it will execute pack so that we have our
+tarball ready and then it will execute deploy and upload the source code
+to all servers and install it there.  Thanks to the `setup.py` file we
+will automatically pull in the required libraries into our virtual
+environment.
+
+Next Steps
+----------
+
+From that point onwards there is so much that can be done to make
+deployment actually fun:
+
+-   Create a `bootstrap` command that initializes new servers.  It could
+    initialize a new virtual environment, setup apache appropriately etc.
+-   Put configuration files into a separate version control repository
+    and symlink the active configs into place.
+-   You could also put your application code into a repository and check
+    out the latest version on the server and then install.  That way you
+    can also easily go back to older versions.
+-   hook in testing functionality so that you can deploy to an external
+    server and run the testsuite.  
+
+Working with Fabric is fun and you will notice that it's quite magical to
+type ``fab deploy`` and see your application being deployed automatically
+to one or more remote servers.
+
+
+.. _Fabric: http://fabfile.org/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/favicon.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,53 @@
+Adding a favicon
+================
+
+A "favicon" is an icon used by browsers for tabs and bookmarks. This helps
+to distinguish your website and to give it a unique brand.
+
+A common question is how to add a favicon to a flask application. First, of
+course, you need an icon. It should be 16 × 16 pixels and in the ICO file
+format. This is not a requirement but a de-facto standard supported by all
+relevant browsers. Put the icon in your static directory as
+:file:`favicon.ico`.
+
+Now, to get browsers to find your icon, the correct way is to add a link
+tag in your HTML. So, for example:
+
+.. sourcecode:: html+jinja
+
+    <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
+
+That's all you need for most browsers, however some really old ones do not
+support this standard. The old de-facto standard is to serve this file,
+with this name, at the website root. If your application is not mounted at
+the root path of the domain you either need to configure the webserver to
+serve the icon at the root or if you can't do that you're out of luck. If
+however your application is the root you can simply route a redirect::
+
+    app.add_url_rule('/favicon.ico',
+                     redirect_to=url_for('static', filename='favicon.ico'))
+
+If you want to save the extra redirect request you can also write a view
+using :func:`~flask.send_from_directory`::
+
+    import os
+    from flask import send_from_directory
+
+    @app.route('/favicon.ico')
+    def favicon():
+        return send_from_directory(os.path.join(app.root_path, 'static'),
+                                   'favicon.ico', mimetype='image/vnd.microsoft.icon')
+
+We can leave out the explicit mimetype and it will be guessed, but we may
+as well specify it to avoid the extra guessing, as it will always be the
+same.
+
+The above will serve the icon via your application and if possible it's
+better to configure your dedicated web server to serve it; refer to the
+webserver's documentation.
+
+See also
+--------
+
+* The `Favicon <http://en.wikipedia.org/wiki/Favicon>`_ article on
+  Wikipedia
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/fileuploads.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,180 @@
+.. _uploading-files:
+
+Uploading Files
+===============
+
+Ah yes, the good old problem of file uploads.  The basic idea of file
+uploads is actually quite simple.  It basically works like this:
+
+1. A ``<form>`` tag is marked with ``enctype=multipart/form-data``
+   and an ``<input type=file>`` is placed in that form.
+2. The application accesses the file from the :attr:`~flask.request.files`
+   dictionary on the request object.
+3. use the :meth:`~werkzeug.FileStorage.save` method of the file to save
+   the file permanently somewhere on the filesystem.
+
+A Gentle Introduction
+---------------------
+
+Let's start with a very basic application that uploads a file to a
+specific upload folder and displays a file to the user.  Let's look at the
+bootstrapping code for our application::
+
+    import os
+    from flask import Flask, request, redirect, url_for
+    from werkzeug import secure_filename
+
+    UPLOAD_FOLDER = '/path/to/the/uploads'
+    ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
+
+    app = Flask(__name__)
+
+So first we need a couple of imports.  Most should be straightforward, the
+:func:`werkzeug.secure_filename` is explained a little bit later.  The
+`UPLOAD_FOLDER` is where we will store the uploaded files and the
+`ALLOWED_EXTENSIONS` is the set of allowed file extensions.  Then we add a
+URL rule by hand to the application.  Now usually we're not doing that, so
+why here?  The reasons is that we want the webserver (or our development
+server) to serve these files for us and so we only need a rule to generate
+the URL to these files.
+
+Why do we limit the extensions that are allowed?  You probably don't want
+your users to be able to upload everything there if the server is directly
+sending out the data to the client.  That way you can make sure that users
+are not able to upload HTML files that would cause XSS problems (see
+:ref:`xss`).  Also make sure to disallow `.php` files if the server
+executes them, but who has PHP installed on his server, right?  :)
+
+Next the functions that check if an extension is valid and that uploads
+the file and redirects the user to the URL for the uploaded file::
+
+    def allowed_file(filename):
+        return '.' in filename and \
+               filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
+
+    @app.route('/', methods=['GET', 'POST'])
+    def upload_file():
+        if request.method == 'POST':
+            file = request.files['file']
+            if file and allowed_file(file.filename):
+                filename = secure_filename(file.filename)
+                file.save(os.path.join(UPLOAD_FOLDER, filename))
+                return redirect(url_for('uploaded_file',
+                                        filename=filename))
+        return '''
+        <!doctype html>
+        <title>Upload new File</title>
+        <h1>Upload new File</h1>
+        <form action="" method=post enctype=multipart/form-data>
+          <p><input type=file name=file>
+             <input type=submit value=Upload>
+        </form>
+        '''
+
+So what does that :func:`~werkzeug.secure_filename` function actually do?
+Now the problem is that there is that principle called "never trust user
+input".  This is also true for the filename of an uploaded file.  All
+submitted form data can be forged, and filenames can be dangerous.  For
+the moment just remember: always use that function to secure a filename
+before storing it directly on the filesystem.
+
+.. admonition:: Information for the Pros
+
+   So you're interested in what that :func:`~werkzeug.secure_filename`
+   function does and what the problem is if you're not using it?  So just
+   imagine someone would send the following information as `filename` to
+   your application::
+
+      filename = "../../../../home/username/.bashrc"
+
+   Assuming the number of ``../`` is correct and you would join this with
+   the `UPLOAD_FOLDER` the user might have the ability to modify a file on
+   the server's filesystem he should not modify.  This does require some
+   knowledge about how the application looks like, but trust me, hackers
+   are patient :)
+
+   Now let's look how that function works:
+
+   >>> secure_filename('../../../../home/username/.bashrc')
+   'home_username_.bashrc'
+
+Now one last thing is missing: the serving of the uploaded files.  As of
+Flask 0.5 we can use a function that does that for us::
+
+    from flask import send_from_directory
+
+    @app.route('/uploads/<filename>')
+    def uploaded_file(filename):
+        return send_from_directory(app.config['UPLOAD_FOLDER'],
+                                   filename)
+
+Alternatively you can register `uploaded_file` as `build_only` rule and
+use the :class:`~werkzeug.SharedDataMiddleware`.  This also works with
+older versions of Flask::
+
+    from werkzeug import SharedDataMiddleware
+    app.add_url_rule('/uploads/<filename>', 'uploaded_file',
+                     build_only=True)
+    app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
+        '/uploads':  UPLOAD_FOLDER
+    })
+
+If you now run the application everything should work as expected.
+
+
+Improving Uploads
+-----------------
+
+.. versionadded:: 0.6
+
+So how exactly does Flask handle uploads?  Well it will store them in the
+webserver's memory if the files are reasonable small otherwise in a
+temporary location (as returned by :func:`tempfile.gettempdir`).  But how
+do you specify the maximum file size after which an upload is aborted?  By
+default Flask will happily accept file uploads to an unlimited amount of
+memory, but you can limit that by setting the ``MAX_CONTENT_LENGTH``
+config key::
+
+    from flask import Flask, Request
+
+    app = Flask(__name__)
+    app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
+
+The code above will limited the maximum allowed payload to 16 megabytes.
+If a larger file is transmitted, Flask will raise an
+:exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception.
+
+This feature was added in Flask 0.6 but can be achieved in older versions
+as well by subclassing the request object.  For more information on that
+consult the Werkzeug documentation on file handling.
+
+
+Upload Progress Bars
+--------------------
+
+A while ago many developers had the idea to read the incoming file in
+small chunks and store the upload progress in the database to be able to
+poll the progress with JavaScript from the client.  Long story short: the
+client asks the server every 5 seconds how much he has transmitted
+already.  Do you realize the irony?  The client is asking for something he
+should already know.
+
+Now there are better solutions to that work faster and more reliable.  The
+web changed a lot lately and you can use HTML5, Java, Silverlight or Flash
+to get a nicer uploading experience on the client side.  Look at the
+following libraries for some nice examples how to do that:
+
+-   `Plupload <http://www.plupload.com/>`_ - HTML5, Java, Flash
+-   `SWFUpload <http://www.swfupload.org/>`_ - Flash
+-   `JumpLoader <http://jumploader.com/>`_ - Java
+
+
+An Easier Solution
+------------------
+
+Because the common pattern for file uploads exists almost unchanged in all
+applications dealing with uploads, there is a Flask extension called
+`Flask-Uploads`_ that implements a full fledged upload mechanism with
+white and blacklisting of extensions and more.
+
+.. _Flask-Uploads: http://packages.python.org/Flask-Uploads/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/flashing.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,119 @@
+.. _message-flashing-pattern:
+
+Message Flashing
+================
+
+Good applications and user interfaces are all about feedback.  If the user
+does not get enough feedback he will probably end up hating the
+application.  Flask provides a really simple way to give feedback to a
+user with the flashing system.  The flashing system basically makes it
+possible to record a message at the end of a request and access it next
+request and only next request.  This is usually combined with a layout
+template that does this.
+
+Simple Flashing
+---------------
+
+So here is a full example::
+
+    from flask import flash, redirect, url_for, render_template
+
+    @app.route('/')
+    def index():
+        return render_template('index.html')
+
+    @app.route('/login', methods=['GET', 'POST'])
+    def login():
+        error = None
+        if request.method == 'POST':
+            if request.form['username'] != 'admin' or \
+               request.form['password'] != 'secret':
+                error = 'Invalid credentials'
+            else:
+                flash('You were successfully logged in')
+                return redirect(url_for('index'))
+        return render_template('login.html', error=error)
+
+And here the ``layout.html`` template which does the magic:
+
+.. sourcecode:: html+jinja
+
+   <!doctype html>
+   <title>My Application</title>
+   {% with messages = get_flashed_messages() %}
+     {% if messages %}
+       <ul class=flashes>
+       {% for message in messages %}
+         <li>{{ message }}</li>
+       {% endfor %}
+       </ul>
+     {% endif %}
+   {% endwith %}
+   {% block body %}{% endblock %}
+
+And here the index.html template:
+
+.. sourcecode:: html+jinja
+
+   {% extends "layout.html" %}
+   {% block body %}
+     <h1>Overview</h1>
+     <p>Do you want to <a href="{{ url_for('login') }}">log in?</a>
+   {% endblock %}
+
+And of course the login template:
+
+.. sourcecode:: html+jinja
+
+   {% extends "layout.html" %}
+   {% block body %}
+     <h1>Login</h1>
+     {% if error %}
+       <p class=error><strong>Error:</strong> {{ error }}
+     {% endif %}
+     <form action="" method=post>
+       <dl>
+         <dt>Username:
+         <dd><input type=text name=username value="{{
+             request.form.username }}">
+         <dt>Password:
+         <dd><input type=password name=password>
+       </dl>
+       <p><input type=submit value=Login>
+     </form>
+   {% endblock %}
+
+Flashing With Categories
+------------------------
+
+.. versionadded:: 0.3
+
+It is also possible to provide categories when flashing a message.  The
+default category if nothing is provided is ``'message'``.  Alternative
+categories can be used to give the user better feedback.  For example
+error messages could be displayed with a red background.
+
+To flash a message with a different category, just use the second argument
+to the :func:`~flask.flash` function::
+
+    flash(u'Invalid password provided', 'error')
+
+Inside the template you then have to tell the
+:func:`~flask.get_flashed_messages` function to also return the
+categories.  The loop looks slightly different in that situation then:
+
+.. sourcecode:: html+jinja
+
+   {% with messages = get_flashed_messages(with_categories=true) %}
+     {% if messages %}
+       <ul class=flashes>
+       {% for category, message in messages %}
+         <li class="{{ category }}">{{ message }}</li>
+       {% endfor %}
+       </ul>
+     {% endif %}
+   {% endwith %}
+
+This is just one example of how to render these flashed messages.  One
+might also use the category to add a prefix such as
+``<strong>Error:</strong>`` to the message.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/index.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,35 @@
+.. _patterns:
+
+Patterns for Flask
+==================
+
+Certain things are common enough that the chances are high you will find
+them in most web applications.  For example quite a lot of applications
+are using relational databases and user authentication.  In that case,
+chances are they will open a database connection at the beginning of the
+request and get the information of the currently logged in user.  At the
+end of the request, the database connection is closed again.
+
+There are more user contributed snippets and patterns in the `Flask
+Snippet Archives <http://flask.pocoo.org/snippets/>`_.
+
+.. toctree::
+   :maxdepth: 2
+
+   packages
+   appfactories
+   distribute
+   fabric
+   sqlite3
+   sqlalchemy
+   fileuploads
+   caching
+   viewdecorators
+   wtforms
+   templateinheritance
+   flashing
+   jquery
+   errorpages
+   lazyloading
+   mongokit
+   favicon
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/jquery.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,167 @@
+AJAX with jQuery
+================
+
+`jQuery`_ is a small JavaScript library commonly used to simplify working
+with the DOM and JavaScript in general.  It is the perfect tool to make
+web applications more dynamic by exchanging JSON between server and
+client.
+
+JSON itself is a very lightweight transport format, very similar to how
+Python primitives (numbers, strings, dicts and lists) look like which is
+widely supported and very easy to parse.  It became popular a few years
+ago and quickly replaced XML as transport format in web applications.
+
+If you have Python 2.6 JSON will work out of the box, in Python 2.5 you
+will have to install the `simplejson`_ library from PyPI.
+
+.. _jQuery: http://jquery.com/
+.. _simplejson: http://pypi.python.org/pypi/simplejson
+
+Loading jQuery
+--------------
+
+In order to use jQuery, you have to download it first and place it in the
+static folder of your application and then ensure it's loaded.  Ideally
+you have a layout template that is used for all pages where you just have
+to add a script statement to your `head` to load jQuery:
+
+.. sourcecode:: html
+
+   <script type=text/javascript src="{{
+     url_for('static', filename='jquery.js') }}"></script>
+
+Another method is using Google's `AJAX Libraries API
+<http://code.google.com/apis/ajaxlibs/documentation/>`_ to load jQuery:
+
+.. sourcecode:: html
+
+    <script type=text/javascript
+      src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
+
+In this case you don't have to put jQuery into your static folder, it will
+instead be loaded from Google directly.  This has the advantage that your
+website will probably load faster for users if they went to at least one
+other website before using the same jQuery version from Google because it
+will already be in the browser cache.  Downside is that if you don't have
+network connectivity during development jQuery will not load.
+
+Where is My Site?
+-----------------
+
+Do you know where your application is?  If you are developing the answer
+is quite simple: it's on localhost port something and directly on the root
+of that server.  But what if you later decide to move your application to
+a different location?  For example to ``http://example.com/myapp``?  On
+the server side this never was a problem because we were using the handy
+:func:`~flask.url_for` function that could answer that question for
+us, but if we are using jQuery we should not hardcode the path to
+the application but make that dynamic, so how can we do that?
+
+A simple method would be to add a script tag to our page that sets a
+global variable to the prefix to the root of the application.  Something
+like this:
+
+.. sourcecode:: html+jinja
+
+   <script type=text/javascript>
+     $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
+   </script>
+
+The ``|safe`` is necessary so that Jinja does not escape the JSON encoded
+string with HTML rules.  Usually this would be necessary, but we are
+inside a `script` block here where different rules apply.
+
+.. admonition:: Information for Pros
+
+   In HTML the `script` tag is declared `CDATA` which means that entities
+   will not be parsed.  Everything until ``</script>`` is handled as script.
+   This also means that there must never be any ``</`` between the script
+   tags.  ``|tojson`` is kind enough to do the right thing here and
+   escape slashes for you (``{{ "</script>"|tojson|safe }}`` is rendered as
+   ``"<\/script>"``).
+
+
+JSON View Functions
+-------------------
+
+Now let's create a server side function that accepts two URL arguments of
+numbers which should be added together and then sent back to the
+application in a JSON object.  This is a really ridiculous example and is
+something you usually would do on the client side alone, but a simple
+example that shows how you would use jQuery and Flask nonetheless::
+
+    from flask import Flask, jsonify, render_template, request
+    app = Flask(__name__)
+
+    @app.route('/_add_numbers')
+    def add_numbers():
+        a = request.args.get('a', 0, type=int)
+        b = request.args.get('b', 0, type=int)
+        return jsonify(result=a + b)
+
+    @app.route('/')
+    def index():
+        return render_template('index.html')
+
+As you can see I also added an `index` method here that renders a
+template.  This template will load jQuery as above and have a little form
+we can add two numbers and a link to trigger the function on the server
+side.
+
+Note that we are using the :meth:`~werkzeug.MultiDict.get` method here
+which will never fail.  If the key is missing a default value (here ``0``)
+is returned.  Furthermore it can convert values to a specific type (like
+in our case `int`).  This is especially handy for code that is
+triggered by a script (APIs, JavaScript etc.) because you don't need
+special error reporting in that case.
+
+The HTML
+--------
+
+Your index.html template either has to extend a `layout.html` template with
+jQuery loaded and the `$SCRIPT_ROOT` variable set, or do that on the top.
+Here's the HTML code needed for our little application (`index.html`).
+Notice that we also drop the script directly into the HTML here.  It is
+usually a better idea to have that in a separate script file:
+
+.. sourcecode:: html
+
+    <script type=text/javascript>
+      $(function() {
+        $('a#calculate').bind('click', function() {
+          $.getJSON($SCRIPT_ROOT + '/_add_numbers', {
+            a: $('input[name="a"]').val(),
+            b: $('input[name="b"]').val()
+          }, function(data) {
+            $("#result").text(data.result);
+          });
+          return false;
+        });
+      });
+    </script>
+    <h1>jQuery Example</h1>
+    <p><input type=text size=5 name=a> +
+       <input type=text size=5 name=b> =
+       <span id=result>?</span>
+    <p><a href=# id=calculate>calculate server side</a>
+
+I won't got into detail here about how jQuery works, just a very quick
+explanation of the little bit of code above:
+
+1. ``$(function() { ... })`` specifies code that should run once the
+   browser is done loading the basic parts of the page.
+2. ``$('selector')`` selects an element and lets you operate on it.
+3. ``element.bind('event', func)`` specifies a function that should run
+   when the user clicked on the element.  If that function returns
+   `false`, the default behaviour will not kick in (in this case, navigate
+   to the `#` URL).
+4. ``$.getJSON(url, data, func)`` sends a `GET` request to `url` and will
+   send the contents of the `data` object as query parameters.  Once the
+   data arrived, it will call the given function with the return value as
+   argument.  Note that we can use the `$SCRIPT_ROOT` variable here that
+   we set earlier.
+
+If you don't get the whole picture, download the `sourcecode
+for this example
+<http://github.com/mitsuhiko/flask/tree/master/examples/jqueryexample>`_
+from github.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/lazyloading.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,104 @@
+Lazily Loading Views
+====================
+
+Flask is usually used with the decorators.  Decorators are simple and you
+have the URL right next to the function that is called for that specific
+URL.  However there is a downside to this approach: it means all your code
+that uses decorators has to be imported upfront or Flask will never
+actually find your function.
+
+This can be a problem if your application has to import quick.  It might
+have to do that on systems like Google's App Engine or other systems.  So
+if you suddenly notice that your application outgrows this approach you
+can fall back to a centralized URL mapping.
+
+The system that enables having a central URL map is the
+:meth:`~flask.Flask.add_url_rule` function.  Instead of using decorators,
+you have a file that sets up the application with all URLs.
+
+Converting to Centralized URL Map
+---------------------------------
+
+Imagine the current application looks somewhat like this::
+
+    from flask import Flask
+    app = Flask(__name__)
+
+    @app.route('/')
+    def index():
+        pass
+
+    @app.route('/user/<username>')
+    def user(username):
+        pass
+
+Then the centralized approach you would have one file with the views
+(`views.py`) but without any decorator::
+
+    def index():
+        pass
+
+    def user(username):
+        pass
+
+And then a file that sets up an application which maps the functions to
+URLs::
+
+    from flask import Flask
+    from yourapplication import views
+    app = Flask(__name__)
+    app.add_url_rule('/', view_func=views.index)
+    app.add_url_rule('/user/<username>', view_func=views.user)
+
+Loading Late
+------------
+
+So far we only split up the views and the routing, but the module is still
+loaded upfront.  The trick to actually load the view function as needed.
+This can be accomplished with a helper class that behaves just like a
+function but internally imports the real function on first use::
+
+    from werkzeug import import_string, cached_property
+
+    class LazyView(object):
+
+        def __init__(self, import_name):
+            self.__module__, self.__name__ = import_name.rsplit('.', 1)
+            self.import_name = import_name
+
+        @cached_property
+        def view(self):
+            return import_string(self.import_name)
+
+        def __call__(self, *args, **kwargs):
+            return self.view(*args, **kwargs)
+
+What's important here is is that `__module__` and `__name__` are properly
+set.  This is used by Flask internally to figure out how to name the
+URL rules in case you don't provide a name for the rule yourself.
+
+Then you can define your central place to combine the views like this::
+
+    from flask import Flask
+    from yourapplication.helpers import LazyView
+    app = Flask(__name__)
+    app.add_url_rule('/',
+                     view_func=LazyView('yourapplication.views.index'))
+    app.add_url_rule('/user/<username>',
+                     view_func=LazyView('yourapplication.views.user'))
+
+You can further optimize this in terms of amount of keystrokes needed to
+write this by having a function that calls into
+:meth:`~flask.Flask.add_url_rule` by prefixing a string with the project
+name and a dot, and by wrapping `view_func` in a `LazyView` as needed::
+
+    def url(url_rule, import_name, **options):
+        view = LazyView('yourapplication.' + import_name)
+        app.add_url_rule(url_rule, view_func=view, **options)
+
+    url('/', 'views.index')
+    url('/user/<username>', 'views.user')
+
+One thing to keep in mind is that before and after request handlers have
+to be in a file that is imported upfront to work properly on the first
+request.  The same goes for any kind of remaining decorator.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/mongokit.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,144 @@
+.. mongokit-pattern:
+
+MongoKit in Flask
+=================
+
+Using a document database rather than a full DBMS gets more common these days.
+This pattern shows how to use MongoKit, a document mapper library, to
+integrate with MongoDB.
+
+This pattern requires a running MongoDB server and the MongoKit library
+installed.
+
+There are two very common ways to use MongoKit.  I will outline each of them
+here:
+
+
+Declarative
+-----------
+
+The default behaviour of MongoKit is the declarative one that is based on
+common ideas from Django or the SQLAlchemy declarative extension.
+
+Here an example `app.py` module for your application::
+
+    from flask import Flask
+    from mongokit import Connection, Document
+
+    # configuration
+    MONGODB_HOST = 'localhost'
+    MONGODB_PORT = 27017
+
+    # create the little application object
+    app = Flask(__name__)
+    app.config.from_object(__name__)
+
+    # connect to the database
+    connection = Connection(app.config['MONGODB_HOST'],
+                            app.config['MONGODB_PORT'])
+
+
+To define your models, just subclass the `Document` class that is imported
+from MongoKit.  If you've seen the SQLAlchemy pattern you may wonder why we do
+not have a session and even do not define a `init_db` function here.  On the
+one hand, MongoKit does not have something like a session.  This sometimes
+makes it more to type but also makes it blazingly fast.  On the other hand,
+MongoDB is schemaless.  This means you can modify the data structure from one
+insert query to the next without any problem.  MongoKit is just schemaless
+too, but implements some validation to ensure data integrity.
+
+Here is an example document (put this also into `app.py`, e.g.)::
+
+    def max_length(length):
+        def validate(value):
+            if len(value) <= length:
+                return True
+            raise Exception('%s must be at most %s characters long' % length)
+        return validate
+
+    class User(Document):
+        structure = {
+            'name': unicode,
+            'email': unicode,
+        }
+        validators = {
+            'name': max_length(50),
+            'email': max_length(120)
+        }
+        use_dot_notation = True
+        def __repr__(self):
+            return '<User %r>' % (self.name)
+
+    # register the User document with our current connection
+    connection.register([User])
+
+
+This example shows you how to define your schema (named structure), a
+validator for the maximum character length and uses a special MongoKit feature
+called `use_dot_notation`.  Per default MongoKit behaves like a python
+dictionary but with `use_dot_notation` set to `True` you can use your
+documents like you use models in nearly any other ORM by using dots to
+separate between attributes.
+
+You can insert entries into the database like this:
+
+>>> from yourapplication.database import connection
+>>> from yourapplication.models import User
+>>> collection = connection['test'].users
+>>> user = collection.User()
+>>> user['name'] = u'admin'
+>>> user['email'] = u'admin@localhost'
+>>> user.save()
+
+Note that MongoKit is kinda strict with used column types, you must not use a
+common `str` type for either `name` or `email` but unicode.
+
+Querying is simple as well:
+
+>>> list(collection.User.find())
+[<User u'admin'>]
+>>> collection.User.find_one({'name': u'admin'})
+<User u'admin'>
+
+.. _MongoKit: http://bytebucket.org/namlook/mongokit/
+
+
+PyMongo Compatibility Layer
+---------------------------
+
+If you just want to use PyMongo, you can do that with MongoKit as well.  You
+may use this process if you need the best performance to get.  Note that this
+example does not show how to couple it with Flask, see the above MongoKit code
+for examples::
+
+    from MongoKit import Connection
+
+    connection = Connection()
+
+To insert data you can use the `insert` method.  We have to get a
+collection first, this is somewhat the same as a table in the SQL world.
+
+>>> collection = connection['test'].users
+>>> user = {'name': u'admin', 'email': u'admin@localhost'}
+>>> collection.insert(user)
+
+print list(collection.find())
+print collection.find_one({'name': u'admin'})
+
+MongoKit will automatically commit for us.
+
+To query your database, you use the collection directly:
+
+>>> list(collection.find())
+[{u'_id': ObjectId('4c271729e13823182f000000'), u'name': u'admin', u'email': u'admin@localhost'}]
+>>> collection.find_one({'name': u'admin'})
+{u'_id': ObjectId('4c271729e13823182f000000'), u'name': u'admin', u'email': u'admin@localhost'}
+
+These results are also dict-like objects:
+
+>>> r = collection.find_one({'name': u'admin'})
+>>> r['email']
+u'admin@localhost'
+
+For more information about MongoKit, head over to the
+`website <http://bytebucket.org/namlook/mongokit/>`_.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/packages.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,286 @@
+.. _larger-applications:
+
+Larger Applications
+===================
+
+For larger applications it's a good idea to use a package instead of a
+module.  That is quite simple.  Imagine a small application looks like
+this::
+
+    /yourapplication
+        /yourapplication.py
+        /static
+            /style.css
+        /templates
+            layout.html
+            index.html
+            login.html
+            ...
+
+Simple Packages
+---------------
+
+To convert that into a larger one, just create a new folder
+`yourapplication` inside the existing one and move everything below it.
+Then rename `yourapplication.py` to `__init__.py`.  (Make sure to delete
+all `.pyc` files first, otherwise things would most likely break)
+
+You should then end up with something like that::
+
+    /yourapplication
+        /yourapplication
+            /__init__.py
+            /static
+                /style.css
+            /templates
+                layout.html
+                index.html
+                login.html
+                ...
+
+But how do you run your application now?  The naive ``python
+yourapplication/__init__.py`` will not work.  Let's just say that Python
+does not want modules in packages to be the startup file.  But that is not
+a big problem, just add a new file called `runserver.py` next to the inner
+`yourapplication` folder with the following contents::
+
+    from yourapplication import app
+    app.run(debug=True)
+
+What did we gain from this?  Now we can restructure the application a bit
+into multiple modules.  The only thing you have to remember is the
+following quick checklist:
+
+1. the `Flask` application object creation has to be in the
+   `__init__.py` file.  That way each module can import it safely and the
+   `__name__` variable will resolve to the correct package.
+2. all the view functions (the ones with a :meth:`~flask.Flask.route`
+   decorator on top) have to be imported when in the `__init__.py` file.
+   Not the object itself, but the module it is in.  Do the importing at
+   the *bottom* of the file.
+
+Here's an example `__init__.py`::
+
+    from flask import Flask
+    app = Flask(__name__)
+
+    import yourapplication.views
+
+And this is what `views.py` would look like::
+
+    from yourapplication import app
+
+    @app.route('/')
+    def index():
+        return 'Hello World!'
+
+You should then end up with something like that::
+
+    /yourapplication
+        /yourapplication
+            /__init__.py
+            /views.py
+            /static
+                /style.css
+            /templates
+                layout.html
+                index.html
+                login.html
+                ...
+
+.. admonition:: Circular Imports
+
+   Every Python programmer hates them, and yet we just added some:
+   circular imports (That's when two modules depend on each other.  In this
+   case `views.py` depends on `__init__.py`).  Be advised that this is a
+   bad idea in general but here it is actually fine.  The reason for this is
+   that we are not actually using the views in `__init__.py` and just
+   ensuring the module is imported and we are doing that at the bottom of
+   the file.
+
+   There are still some problems with that approach but if you want to use
+   decorators there is no way around that.  Check out the
+   :ref:`becomingbig` section for some inspiration how to deal with that.
+
+
+.. _working-with-modules:
+
+Working with Modules
+--------------------
+
+For larger applications with more than a dozen views it makes sense to
+split the views into modules.  First let's look at the typical structure of
+such an application::
+
+    /yourapplication
+        /yourapplication
+            /__init__.py
+            /views
+                __init__.py
+                admin.py
+                frontend.py
+            /static
+                /style.css
+            /templates
+                layout.html
+                index.html
+                login.html
+                ...
+
+The views are stored in the `yourapplication.views` package.  Just make
+sure to place an empty `__init__.py` file in there.  Let's start with the
+`admin.py` file in the view package.
+
+First we have to create a :class:`~flask.Module` object with the name of
+the package.  This works very similar to the :class:`~flask.Flask` object
+you have already worked with, it just does not support all of the methods,
+but most of them are the same.
+
+Long story short, here's a nice and concise example::
+
+    from flask import Module
+
+    admin = Module(__name__)
+
+    @admin.route('/')
+    def index():
+        pass
+
+    @admin.route('/login')
+    def login():
+        pass
+
+    @admin.route('/logout')
+    def logout():
+        pass
+
+Do the same with the `frontend.py` and then make sure to register the
+modules in the application (`__init__.py`) like this::
+
+    from flask import Flask
+    from yourapplication.views.admin import admin
+    from yourapplication.views.frontend import frontend
+
+    app = Flask(__name__)
+    app.register_module(admin, url_prefix='/admin')
+    app.register_module(frontend)
+
+We register the modules with the app so that it can add them to the
+URL map for our application.  Note the prefix argument to the admin
+module: by default when we register a module, that module's end-points
+will be registered on `/` unless we specify this argument.
+
+So what is different when working with modules?  It mainly affects URL
+generation.  Remember the :func:`~flask.url_for` function?  When not
+working with modules it accepts the name of the function as first
+argument.  This first argument is called the "endpoint".  When you are
+working with modules you can use the name of the function like you did
+without, when generating modules from a function or template in the same
+module.  If you want to generate the URL to another module, prefix it with
+the name of the module and a dot.
+
+Confused?  Let's clear that up with some examples.  Imagine you have a
+method in one module (say `admin`) and you want to redirect to a
+different module (say `frontend`).  This would look like this::
+
+    @admin.route('/to_frontend')
+    def to_frontend():
+        return redirect(url_for('frontend.index'))
+
+    @frontend.route('/')
+    def index():
+        return "I'm the frontend index"
+
+Now let's say we only want to redirect to a different function in the same
+module.  Then we can either use the full qualified endpoint name like we
+did in the example above, or we just use the function name::
+
+    @frontend.route('/to_index')
+    def to_index():
+        return redirect(url_for('index'))
+
+    @frontend.route('/')
+    def index():
+        return "I'm the index"
+
+.. _modules-and-resources:
+
+Modules and Resources
+---------------------
+
+.. versionadded:: 0.5
+
+If a module is located inside an actual Python package it may contain
+static files and templates.  Imagine you have an application like this::
+
+
+    /yourapplication
+        __init__.py
+        /apps
+	    __init__.py
+            /frontend
+                __init__.py
+                views.py
+                /static
+                    style.css
+                /templates
+                    index.html
+                    about.html
+                    ...
+            /admin
+                __init__.py
+                views.py
+                /static
+                    style.css
+                /templates
+                    list_items.html
+                    show_item.html
+                    ...
+
+The static folders automatically become exposed as URLs.  For example if
+the `admin` module is exported with an URL prefix of ``/admin`` you can
+access the style css from its static folder by going to
+``/admin/static/style.css``.  The URL endpoint for the static files of the
+admin would be ``'admin.static'``, similar to how you refer to the regular
+static folder of the whole application as ``'static'``.
+
+If you want to refer to the templates you just have to prefix it with the
+name of the module.  So for the admin it would be
+``render_template('admin/list_items.html')`` and so on.  It is not
+possible to refer to templates without the prefixed module name.  This is
+explicit unlike URL rules.
+
+You also need to explicitly pass the ``url_prefix`` argument when
+registering your modules this way::
+
+    # in yourapplication/__init__.py
+    from flask import Flask
+    from yourapplication.apps.admin.views import admin
+    from yourapplication.apps.frontend.views import frontend
+
+
+    app = Flask(__name__)
+    app.register_module(admin, url_prefix='/admin')
+    app.register_module(frontend, url_prefix='/frontend')
+
+This is because Flask cannot infer the prefix from the package names.
+
+.. admonition:: References to Static Folders
+
+   Please keep in mind that if you are using unqualified endpoints by
+   default Flask will always assume the module's static folder, even if
+   there is no such folder.
+
+   If you want to refer to the application's static folder, use a leading
+   dot::
+
+       # this refers to the application's static folder
+       url_for('.static', filename='static.css')
+
+       # this refers to the current module's static folder
+       url_for('static', filename='static.css')
+
+   This is the case for all endpoints, not just static folders, but for
+   static folders it's more common that you will stumble upon this because
+   most applications will have a static folder in the application and not
+   a specific module.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/sqlalchemy.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,216 @@
+.. _sqlalchemy-pattern:
+
+SQLAlchemy in Flask
+===================
+
+Many people prefer `SQLAlchemy`_ for database access.  In this case it's
+encouraged to use a package instead of a module for your flask application
+and drop the models into a separate module (:ref:`larger-applications`).
+While that is not necessary, it makes a lot of sense.
+
+There are four very common ways to use SQLAlchemy.  I will outline each
+of them here:
+
+Flask-SQLAlchemy Extension
+--------------------------
+
+Because SQLAlchemy is a common database abstraction layer and object
+relational mapper that requires a little bit of configuration effort,
+there is a Flask extension that handles that for you.  This is recommended
+if you want to get started quickly.
+
+You can download `Flask-SQLAlchemy`_ from `PyPI
+<http://pypi.python.org/pypi/Flask-SQLAlchemy>`_.
+
+.. _Flask-SQLAlchemy: http://packages.python.org/Flask-SQLAlchemy/
+
+
+Declarative
+-----------
+
+The declarative extension in SQLAlchemy is the most recent method of using
+SQLAlchemy.  It allows you to define tables and models in one go, similar
+to how Django works.  In addition to the following text I recommend the
+official documentation on the `declarative`_ extension.
+
+Here the example `database.py` module for your application::
+
+    from sqlalchemy import create_engine
+    from sqlalchemy.orm import scoped_session, sessionmaker
+    from sqlalchemy.ext.declarative import declarative_base
+
+    engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
+    db_session = scoped_session(sessionmaker(autocommit=False,
+                                             autoflush=False,
+                                             bind=engine)) 
+    Base = declarative_base()
+    Base.query = db_session.query_property()
+
+    def init_db():
+        # import all modules here that might define models so that
+        # they will be registered properly on the metadata.  Otherwise
+        # you will have to import them first before calling init_db()
+        import yourapplication.models
+        Base.metadata.create_all(bind=engine)
+
+To define your models, just subclass the `Base` class that was created by
+the code above.  If you are wondering why we don't have to care about
+threads here (like we did in the SQLite3 example above with the
+:data:`~flask.g` object): that's because SQLAlchemy does that for us
+already with the :class:`~sqlalchemy.orm.scoped_session`.
+
+To use SQLAlchemy in a declarative way with your application, you just
+have to put the following code into your application module.  Flask will
+automatically remove database sessions at the end of the request for you::
+
+    from yourapplication.database import db_session
+
+    @app.after_request
+    def shutdown_session(response):
+        db_session.remove()
+        return response
+
+Here is an example model (put this into `models.py`, e.g.)::
+
+    from sqlalchemy import Column, Integer, String
+    from yourapplication.database import Base
+
+    class User(Base):
+        __tablename__ = 'users'
+        id = Column(Integer, primary_key=True)
+        name = Column(String(50), unique=True)
+        email = Column(String(120), unique=True)
+
+        def __init__(self, name=None, email=None):
+            self.name = name
+            self.email = email
+
+        def __repr__(self):
+            return '<User %r>' % (self.name)
+
+To create the database you can use the `init_db` function:
+
+>>> from yourapplication.database import init_db
+>>> init_db()
+
+You can insert entries into the database like this:
+
+>>> from yourapplication.database import db_session
+>>> from yourapplication.models import User
+>>> u = User('admin', 'admin@localhost')
+>>> db_session.add(u)
+>>> db_session.commit()
+
+Querying is simple as well:
+
+>>> User.query.all()
+[<User u'admin'>]
+>>> User.query.filter(User.name == 'admin').first()
+<User u'admin'>
+
+.. _SQLAlchemy: http://www.sqlalchemy.org/
+.. _declarative:
+   http://www.sqlalchemy.org/docs/reference/ext/declarative.html
+
+Manual Object Relational Mapping
+--------------------------------
+
+Manual object relational mapping has a few upsides and a few downsides
+versus the declarative approach from above.  The main difference is that
+you define tables and classes separately and map them together.  It's more
+flexible but a little more to type.  In general it works like the
+declarative approach, so make sure to also split up your application into
+multiple modules in a package.
+
+Here is an example `database.py` module for your application::
+
+    from sqlalchemy import create_engine, MetaData
+    from sqlalchemy.orm import scoped_session, sessionmaker
+
+    engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
+    metadata = MetaData()
+    db_session = scoped_session(sessionmaker(autocommit=False,
+                                             autoflush=False,
+                                             bind=engine)) 
+    def init_db():
+        metadata.create_all(bind=engine)
+
+As for the declarative approach you need to close the session after
+each request.  Put this into your application module::
+
+    from yourapplication.database import db_session
+
+    @app.after_request
+    def shutdown_session(response):
+        db_session.remove()
+        return response
+
+Here is an example table and model (put this into `models.py`)::
+
+    from sqlalchemy import Table, Column, Integer, String
+    from sqlalchemy.orm import mapper
+    from yourapplication.database import metadata, db_session
+
+    class User(object):
+        query = db_session.query_property()
+
+        def __init__(self, name=None, email=None):
+            self.name = name
+            self.email = email
+
+        def __repr__(self):
+            return '<User %r>' % (self.name, self.email)
+
+    users = Table('users', metadata,
+        Column('id', Integer, primary_key=True),
+        Column('name', String(50), unique=True),
+        Column('email', String(120), unique=True)
+    )
+    mapper(User, users)
+
+Querying and inserting works exactly the same as in the example above.
+
+
+SQL Abstraction Layer
+---------------------
+
+If you just want to use the database system (and SQL) abstraction layer
+you basically only need the engine::
+
+    from sqlalchemy import create_engine, MetaData
+
+    engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
+    metadata = MetaData(bind=engine)
+
+Then you can either declare the tables in your code like in the examples
+above, or automatically load them::
+
+    users = Table('users', metadata, autoload=True)
+
+To insert data you can use the `insert` method.  We have to get a
+connection first so that we can use a transaction:
+
+>>> con = engine.connect()
+>>> con.execute(users.insert(name='admin', email='admin@localhost'))
+
+SQLAlchemy will automatically commit for us.
+
+To query your database, you use the engine directly or use a connection:
+
+>>> users.select(users.c.id == 1).execute().first()
+(1, u'admin', u'admin@localhost')
+
+These results are also dict-like tuples:
+
+>>> r = users.select(users.c.id == 1).execute().first()
+>>> r['name']
+u'admin'
+
+You can also pass strings of SQL statements to the
+:meth:`~sqlalchemy.engine.base.Connection.execute` method:
+
+>>> engine.execute('select * from users where id = :1', [1]).first()
+(1, u'admin', u'admin@localhost')
+
+For more information about SQLAlchemy, head over to the
+`website <http://sqlalchemy.org/>`_.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/sqlite3.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,87 @@
+.. _sqlite3:
+
+Using SQLite 3 with Flask
+=========================
+
+In Flask you can implement the opening of database connections at the
+beginning of the request and closing at the end with the
+:meth:`~flask.Flask.before_request` and :meth:`~flask.Flask.after_request`
+decorators in combination with the special :class:`~flask.g` object.
+
+So here is a simple example of how you can use SQLite 3 with Flask::
+
+    import sqlite3
+    from flask import g
+
+    DATABASE = '/path/to/database.db'
+
+    def connect_db():
+        return sqlite3.connect(DATABASE)
+
+    @app.before_request
+    def before_request():
+        g.db = connect_db()
+
+    @app.after_request
+    def after_request(response):
+        g.db.close()
+        return response
+
+.. _easy-querying:
+
+Easy Querying
+-------------
+
+Now in each request handling function you can access `g.db` to get the
+current open database connection.  To simplify working with SQLite, a
+helper function can be useful::
+
+    def query_db(query, args=(), one=False):
+        cur = g.db.execute(query, args)
+        rv = [dict((cur.description[idx][0], value)
+                   for idx, value in enumerate(row)) for row in cur.fetchall()]
+        return (rv[0] if rv else None) if one else rv
+
+This handy little function makes working with the database much more
+pleasant than it is by just using the raw cursor and connection objects.
+
+Here is how you can use it::
+
+    for user in query_db('select * from users'):
+        print user['username'], 'has the id', user['user_id']
+
+Or if you just want a single result::
+
+    user = query_db('select * from users where username = ?',
+                    [the_username], one=True)
+    if user is None:
+        print 'No such user'
+    else:
+        print the_username, 'has the id', user['user_id']
+
+To pass variable parts to the SQL statement, use a question mark in the
+statement and pass in the arguments as a list.  Never directly add them to
+the SQL statement with string formatting because this makes it possible
+to attack the application using `SQL Injections
+<http://en.wikipedia.org/wiki/SQL_injection>`_.
+
+Initial Schemas
+---------------
+
+Relational databases need schemas, so applications often ship a
+`schema.sql` file that creates the database.  It's a good idea to provide
+a function that creates the database based on that schema.  This function
+can do that for you::
+
+    from contextlib import closing
+    
+    def init_db():
+        with closing(connect_db()) as db:
+            with app.open_resource('schema.sql') as f:
+                db.cursor().executescript(f.read())
+            db.commit()
+
+You can then create such a database from the python shell:
+
+>>> from yourapplication import init_db
+>>> init_db()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/templateinheritance.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,69 @@
+.. _template-inheritance:
+
+Template Inheritance
+====================
+
+The most powerful part of Jinja is template inheritance. Template inheritance
+allows you to build a base "skeleton" template that contains all the common
+elements of your site and defines **blocks** that child templates can override.
+
+Sounds complicated but is very basic. It's easiest to understand it by starting
+with an example.
+
+
+Base Template
+-------------
+
+This template, which we'll call ``layout.html``, defines a simple HTML skeleton
+document that you might use for a simple two-column page. It's the job of
+"child" templates to fill the empty blocks with content:
+
+.. sourcecode:: html+jinja
+
+    <!doctype html>
+    <html>
+      <head>
+        {% block head %}
+        <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
+        <title>{% block title %}{% endblock %} - My Webpage</title>
+        {% endblock %}
+      </head>
+    <body>
+      <div id="content">{% block content %}{% endblock %}</div>
+      <div id="footer">
+        {% block footer %}
+        &copy; Copyright 2010 by <a href="http://domain.invalid/">you</a>.
+        {% endblock %}
+      </div>
+    </body>
+
+In this example, the ``{% block %}`` tags define four blocks that child templates
+can fill in. All the `block` tag does is to tell the template engine that a
+child template may override those portions of the template.
+
+Child Template
+--------------
+
+A child template might look like this:
+
+.. sourcecode:: html+jinja
+
+    {% extends "layout.html" %}
+    {% block title %}Index{% endblock %}
+    {% block head %}
+      {{ super() }}
+      <style type="text/css">
+        .important { color: #336699; }
+      </style>
+    {% endblock %}
+    {% block content %}
+      <h1>Index</h1>
+      <p class="important">
+        Welcome on my awesome homepage.
+    {% endblock %}
+
+The ``{% extends %}`` tag is the key here. It tells the template engine that
+this template "extends" another template.  When the template system evaluates
+this template, first it locates the parent.  The extends tag must be the
+first tag in the template.  To render the contents of a block defined in
+the parent template, use ``{{ super() }}``.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/viewdecorators.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,168 @@
+View Decorators
+===============
+
+Python has a really interesting feature called function decorators.  This
+allow some really neat things for web applications.  Because each view in
+Flask is a function decorators can be used to inject additional
+functionality to one or more functions.  The :meth:`~flask.Flask.route`
+decorator is the one you probably used already.  But there are use cases
+for implementing your own decorator.  For instance, imagine you have a
+view that should only be used by people that are logged in to.  If a user
+goes to the site and is not logged in, he should be redirected to the
+login page.  This is a good example of a use case where a decorator is an
+excellent solution.
+
+Login Required Decorator
+------------------------
+
+So let's implement such a decorator.  A decorator is a function that
+returns a function.  Pretty simple actually.  The only thing you have to
+keep in mind when implementing something like this is to update the
+`__name__`, `__module__` and some other attributes of a function.  This is
+often forgotten, but you don't have to do that by hand, there is a
+function for that that is used like a decorator (:func:`functools.wraps`).
+
+This example assumes that the login page is called ``'login'`` and that
+the current user is stored as `g.user` and `None` if there is no-one
+logged in::
+
+    from functools import wraps
+    from flask import g, request, redirect, url_for
+
+    def login_required(f):
+        @wraps(f)
+        def decorated_function(*args, **kwargs):
+            if g.user is None:
+                return redirect(url_for('login', next=request.url))
+            return f(*args, **kwargs)
+        return decorated_function
+
+So how would you use that decorator now?  Apply it as innermost decorator
+to a view function.  When applying further decorators, always remember
+that the :meth:`~flask.Flask.route` decorator is the outermost::
+
+    @app.route('/secret_page')
+    @login_required
+    def secret_page():
+        pass
+
+Caching Decorator
+-----------------
+
+Imagine you have a view function that does an expensive calculation and
+because of that you would like to cache the generated results for a
+certain amount of time.  A decorator would be nice for that.  We're
+assuming you have set up a cache like mentioned in :ref:`caching-pattern`.
+
+Here an example cache function.  It generates the cache key from a
+specific prefix (actually a format string) and the current path of the
+request.  Notice that we are using a function that first creates the
+decorator that then decorates the function.  Sounds awful? Unfortunately
+it is a little bit more complex, but the code should still be
+straightforward to read.
+
+The decorated function will then work as follows
+
+1. get the unique cache key for the current request base on the current
+   path.
+2. get the value for that key from the cache. If the cache returned
+   something we will return that value.
+3. otherwise the original function is called and the return value is
+   stored in the cache for the timeout provided (by default 5 minutes).
+
+Here the code::
+
+    from functools import wraps
+    from flask import request
+
+    def cached(timeout=5 * 60, key='view/%s'):
+        def decorator(f):
+            @wraps(f)
+            def decorated_function(*args, **kwargs):
+                cache_key = key % request.path
+                rv = cache.get(cache_key)
+                if rv is not None:
+                    return rv
+                rv = f(*args, **kwargs)
+                cache.set(cache_key, rv, timeout=timeout)
+                return rv
+            return decorated_function
+        return decorator
+
+Notice that this assumes an instantiated `cache` object is available, see
+:ref:`caching-pattern` for more information.
+
+
+Templating Decorator
+--------------------
+
+A common pattern invented by the TurboGears guys a while back is a
+templating decorator.  The idea of that decorator is that you return a
+dictionary with the values passed to the template from the view function
+and the template is automatically rendered.  With that, the following
+three examples do exactly the same::
+
+    @app.route('/')
+    def index():
+        return render_template('index.html', value=42)
+
+    @app.route('/')
+    @templated('index.html')
+    def index():
+        return dict(value=42)
+
+    @app.route('/')
+    @templated()
+    def index():
+        return dict(value=42)
+
+As you can see, if no template name is provided it will use the endpoint
+of the URL map with dots converted to slashes + ``'.html'``.  Otherwise
+the provided template name is used.  When the decorated function returns,
+the dictionary returned is passed to the template rendering function.  If
+`None` is returned, an empty dictionary is assumed, if something else than
+a dictionary is returned we return it from the function unchanged.  That
+way you can still use the redirect function or return simple strings.
+
+Here the code for that decorator::
+
+    from functools import wraps
+    from flask import request
+
+    def templated(template=None):
+        def decorator(f):
+            @wraps(f)
+            def decorated_function(*args, **kwargs):
+                template_name = template
+                if template_name is None:
+                    template_name = request.endpoint \
+                        .replace('.', '/') + '.html'
+                ctx = f(*args, **kwargs)
+                if ctx is None:
+                    ctx = {}
+                elif not isinstance(ctx, dict):
+                    return ctx
+                return render_template(template_name, **ctx)
+            return decorated_function
+        return decorator
+
+
+Endpoint Decorator
+------------------
+
+When you want to use the werkzeug routing system for more flexibility you
+need to map the endpoint as defined in the :class:`~werkzeug.routing.Rule` 
+to a view function. This is possible with this decorator. For example:: 
+
+    from flask import Flask
+    from werkzeug.routing import Rule
+
+    app = Flask(__name__)                                                          
+    app.url_map.add(Rule('/', endpoint='index'))                                   
+
+    @app.endpoint('index')                                                         
+    def my_index():                                                                
+        return "Hello world"     
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/patterns/wtforms.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,124 @@
+Form Validation with WTForms
+============================
+
+When you have to work with form data submitted by a browser view code
+quickly becomes very hard to read.  There are libraries out there designed
+to make this process easier to manage.  One of them is `WTForms`_ which we
+will handle here.  If you find yourself in the situation of having many
+forms, you might want to give it a try.
+
+When you are working with WTForms you have to define your forms as classes
+first.  I recommend breaking up the application into multiple modules 
+(:ref:`larger-applications`) for that and adding a separate module for the
+forms.
+
+.. admonition:: Getting most of WTForms with an Extension
+
+   The `Flask-WTF`_ extension expands on this pattern and adds a few
+   handful little helpers that make working with forms and Flask more
+   fun.  You can get it from `PyPI
+   <http://pypi.python.org/pypi/Flask-WTF>`_.
+
+.. _Flask-WTF: http://packages.python.org/Flask-WTF/
+
+The Forms
+---------
+
+This is an example form for a typical registration page::
+
+    from wtforms import Form, BooleanField, TextField, validators
+
+    class RegistrationForm(Form):
+        username = TextField('Username', [validators.Length(min=4, max=25)])
+        email = TextField('Email Address', [validators.Length(min=6, max=35)])
+        password = PasswordField('New Password', [
+            validators.Required(),
+            validators.EqualTo('confirm', message='Passwords must match')
+        ])
+        confirm = PasswordField('Repeat Password')
+        accept_tos = BooleanField('I accept the TOS', [validators.Required()])
+
+In the View
+-----------
+
+In the view function, the usage of this form looks like this::
+
+    @app.route('/register', methods=['GET', 'POST'])
+    def register():
+        form = RegistrationForm(request.form)
+        if request.method == 'POST' and form.validate():
+            user = User(form.username.data, form.email.data,
+                        form.password.data)
+            db_session.add(user)
+            flash('Thanks for registering')
+            return redirect(url_for('login'))
+        return render_template('register.html', form=form)
+
+Notice that we are implying that the view is using SQLAlchemy here
+(:ref:`sqlalchemy-pattern`) but this is no requirement of course.  Adapt
+the code as necessary.
+
+Things to remember:
+
+1. create the form from the request :attr:`~flask.request.form` value if
+   the data is submitted via the HTTP `POST` method and
+   :attr:`~flask.request.args` if the data is submitted as `GET`.
+2. to validate the data, call the :func:`~wtforms.form.Form.validate`
+   method which will return `True` if the data validates, `False`
+   otherwise.
+3. to access individual values from the form, access `form.<NAME>.data`.
+
+Forms in Templates
+------------------
+
+Now to the template side.  When you pass the form to the templates you can
+easily render them there.  Look at the following example template to see
+how easy this is.  WTForms does half the form generation for us already.
+To make it even nicer, we can write a macro that renders a field with
+label and a list of errors if there are any.
+
+Here's an example `_formhelpers.html` template with such a macro:
+
+.. sourcecode:: html+jinja
+
+    {% macro render_field(field) %}
+      <dt>{{ field.label }}
+      <dd>{{ field(**kwargs)|safe }}
+      {% if field.errors %}
+        <ul class="errors">
+        {% for error in field.errors %}<li>{{ error }}{% endfor %}
+        </ul>
+      {% endif %}
+      </dd>
+    {% endmacro %}
+
+This macro accepts a couple of keyword arguments that are forwarded to
+WTForm's field function that renders the field for us.  The keyword
+arguments will be inserted as HTML attributes.  So for example you can
+call ``render_field(form.username, class='username')`` to add a class to
+the input element.  Note that WTForms returns standard Python unicode
+strings, so we have to tell Jinja2 that this data is already HTML escaped
+with the `|safe` filter.
+
+Here the `register.html` template for the function we used above which
+takes advantage of the `_formhelpers.html` template:
+
+.. sourcecode:: html+jinja
+
+    {% from "_formhelpers.html" import render_field %}
+    <form method="post" action="/register">
+      <dl>
+        {{ render_field(form.username) }}
+        {{ render_field(form.email) }}
+        {{ render_field(form.password) }}
+        {{ render_field(form.confirm) }}
+        {{ render_field(form.accept_tos) }}
+      </dl>
+      <p><input type=submit value=Register>
+    </form>
+
+For more information about WTForms, head over to the `WTForms
+website`_.
+
+.. _WTForms: http://wtforms.simplecodes.com/
+.. _WTForms website: http://wtforms.simplecodes.com/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/quickstart.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,745 @@
+.. _quickstart:
+
+Quickstart
+==========
+
+Eager to get started?  This page gives a good introduction in how to get
+started with Flask.  This assumes you already have Flask installed.  If
+you do not, head over to the :ref:`installation` section.
+
+
+A Minimal Application
+---------------------
+
+A minimal Flask application looks something like that::
+
+    from flask import Flask
+    app = Flask(__name__)
+
+    @app.route('/')
+    def hello_world():
+        return "Hello World!"
+
+    if __name__ == '__main__':
+        app.run()
+
+Just save it as `hello.py` or something similar and run it with your
+Python interpreter.  Make sure to not call your application `flask.py`
+because this would conflict with Flask itself.
+
+::
+
+    $ python hello.py
+     * Running on http://127.0.0.1:5000/
+
+Head over to `http://127.0.0.1:5000/ <http://127.0.0.1:5000/>`_, you should
+see your hello world greeting.
+
+So what did that code do?
+
+1. First we imported the :class:`~flask.Flask` class.  An instance of this
+   class will be our WSGI application.  The first argument is the name of
+   the application's module.  If you are using a single module (like here)
+   you should use `__name__` because depending on if it's started as
+   application or imported as module the name will be different
+   (``'__main__'`` versus the actual import name).  For more information
+   on that, have a look at the :class:`~flask.Flask` documentation.
+2. Next we create an instance of it.  We pass it the name of the module /
+   package.  This is needed so that Flask knows where it should look for
+   templates, static files and so on.
+3. Then we use the :meth:`~flask.Flask.route` decorator to tell Flask
+   what URL should trigger our function.
+4. The function then has a name which is also used to generate URLs to
+   that particular function, and returns the message we want to display in
+   the user's browser.
+5. Finally we use the :meth:`~flask.Flask.run` function to run the
+   local server with our application.  The ``if __name__ == '__main__':``
+   makes sure the server only runs if the script is executed directly from
+   the Python interpreter and not used as imported module.
+
+To stop the server, hit control-C.
+
+.. _public-server:
+
+.. admonition:: Externally Visible Server
+
+   If you run the server you will notice that the server is only available
+   from your own computer, not from any other in the network.  This is the
+   default because in debugging mode a user of the application can execute
+   arbitrary Python code on your computer.  If you have `debug` disabled
+   or trust the users on your network, you can make the server publicly
+   available.
+
+   Just change the call of the :meth:`~flask.Flask.run` method to look
+   like this::
+
+       app.run(host='0.0.0.0')
+
+   This tells your operating system to listen on a public IP.
+
+
+Debug Mode
+----------
+
+The :meth:`~flask.Flask.run` method is nice to start a local
+development server, but you would have to restart it manually after each
+change you do to code.  That is not very nice and Flask can do better.  If
+you enable the debug support the server will reload itself on code changes
+and also provide you with a helpful debugger if things go wrong.
+
+There are two ways to enable debugging.  Either set that flag on the
+application object::
+
+    app.debug = True
+    app.run()
+
+Or pass it to run::
+
+    app.run(debug=True)
+
+Both will have exactly the same effect.
+
+.. admonition:: Attention
+
+   Even though the interactive debugger does not work in forking environments
+   (which makes it nearly impossible to use on production servers), it still
+   allows the execution of arbitrary code. That makes it a major security
+   risk and therefore it **must never be used on production machines**.
+
+Screenshot of the debugger in action:
+
+.. image:: _static/debugger.png
+   :align: center
+   :class: screenshot
+   :alt: screenshot of debugger in action
+
+
+Routing
+-------
+
+Modern web applications have beautiful URLs.  This helps people remember
+the URLs which is especially handy for applications that are used from
+mobile devices with slower network connections.  If the user can directly
+go to the desired page without having to hit the index page it is more
+likely he will like the page and come back next time.
+
+As you have seen above, the :meth:`~flask.Flask.route` decorator is used
+to bind a function to a URL.  Here are some basic examples::
+
+    @app.route('/')
+    def index():
+        return 'Index Page'
+
+    @app.route('/hello')
+    def hello():
+        return 'Hello World'
+
+But there is more to it!  You can make certain parts of the URL dynamic
+and attach multiple rules to a function.
+
+Variable Rules
+``````````````
+
+To add variable parts to a URL you can mark these special sections as
+``<variable_name>``.  Such a part is then passed as keyword argument to
+your function.  Optionally a converter can be specified by specifying a
+rule with ``<converter:variable_name>``.  Here are some nice examples::
+
+    @app.route('/user/<username>')
+    def show_user_profile(username):
+        # show the user profile for that user
+        pass
+
+    @app.route('/post/<int:post_id>')
+    def show_post(post_id):
+        # show the post with the given id, the id is an integer
+        pass
+
+The following converters exist:
+
+=========== ===========================================
+`int`       accepts integers
+`float`     like `int` but for floating point values
+`path`      like the default but also accepts slashes
+=========== ===========================================
+
+.. admonition:: Unique URLs / Redirection Behaviour
+
+   Flask's URL rules are based on Werkzeug's routing module.  The idea
+   behind that module is to ensure nice looking and also unique URLs based
+   on behaviour Apache and earlier servers coined.
+
+   Take these two rules::
+
+        @app.route('/projects/')
+        def projects():
+            pass
+
+        @app.route('/about')
+        def about():
+            pass
+
+   They look rather similar, the difference is the trailing slash in the
+   URL *definition*.  In the first case, the canonical URL for the
+   `projects` endpoint has a trailing slash.  It's similar to a folder in
+   that sense.  Accessing it without a trailing slash will cause Flask to
+   redirect to the canonical URL with the trailing slash.
+
+   However in the second case the URL is defined without a slash so it
+   behaves similar to a file and accessing the URL with a trailing slash
+   will be a 404 error.
+
+   Why is this?  This allows relative URLs to continue working if users
+   access the page when they forget a trailing slash.  This behaviour is
+   also consistent with how Apache and other servers work.  Also, the URLs
+   will stay unique which helps search engines not indexing the same page
+   twice.
+
+
+.. _url-building:
+
+URL Building
+````````````
+
+If it can match URLs, can it also generate them?  Of course it can.  To
+build a URL to a specific function you can use the :func:`~flask.url_for`
+function.  It accepts the name of the function as first argument and a
+number of keyword arguments, each corresponding to the variable part of
+the URL rule.  Unknown variable parts are appended to the URL as query
+parameter.  Here are some examples:
+
+>>> from flask import Flask, url_for
+>>> app = Flask(__name__)
+>>> @app.route('/')
+... def index(): pass
+...
+>>> @app.route('/login')
+... def login(): pass
+...
+>>> @app.route('/user/<username>')
+... def profile(username): pass
+...
+>>> with app.test_request_context():
+...  print url_for('index')
+...  print url_for('login')
+...  print url_for('login', next='/')
+...  print url_for('profile', username='John Doe')
+...
+/
+/login
+/login?next=/
+/user/John%20Doe
+
+(This also uses the :meth:`~flask.Flask.test_request_context` method
+explained below.  It basically tells Flask to think we are handling a
+request even though we are not, we are in an interactive Python shell.
+Have a look at the explanation below. :ref:`context-locals`).
+
+Why would you want to build URLs instead of hardcoding them in your
+templates?  There are three good reasons for this:
+
+1. reversing is often more descriptive than hardcoding the URLs.  Also and
+   more importantly you can change URLs in one go without having to change
+   the URLs all over the place.
+2. URL building will handle escaping of special characters and Unicode
+   data transparently for you, you don't have to deal with that.
+3. If your application is placed outside the URL root (so say in
+   ``/myapplication`` instead of ``/``), :func:`~flask.url_for` will
+   handle that properly for you.
+
+
+HTTP Methods
+````````````
+
+HTTP (the protocol web applications are speaking) knows different methods
+to access URLs.  By default a route only answers to `GET` requests, but
+that can be changed by providing the `methods` argument to the
+:meth:`~flask.Flask.route` decorator.  Here are some examples::
+
+    @app.route('/login', methods=['GET', 'POST'])
+    def login():
+        if request.method == 'POST':
+            do_the_login()
+        else:
+            show_the_login_form()
+
+If `GET` is present, `HEAD` will be added automatically for you.  You
+don't have to deal with that.  It will also make sure that `HEAD` requests
+are handled like the `HTTP RFC`_ (the document describing the HTTP
+protocol) demands, so you can completely ignore that part of the HTTP
+specification.  Likewise as of Flask 0.6, `OPTIONS` is implemented for you
+as well automatically.
+
+You have no idea what an HTTP method is?  Worry not, here is a quick
+introduction to HTTP methods and why they matter:
+
+The HTTP method (also often called "the verb") tells the server what the
+clients wants to *do* with the requested page.  The following methods are
+very common:
+
+`GET`
+    The browser tells the server to just *get* the information stored on
+    that page and send it.  This is probably the most common method.
+
+`HEAD`
+    The browser tells the server to get the information, but it is only
+    interested in the *headers*, not the content of the page.  An
+    application is supposed to handle that as if a `GET` request was
+    received but to not deliver the actual content.  In Flask you don't
+    have to deal with that at all, the underlying Werkzeug library handles
+    that for you.
+
+`POST`
+    The browser tells the server that it wants to *post* some new
+    information to that URL and that the server must ensure the data is
+    stored and only stored once.  This is how HTML forms are usually
+    transmitting data to the server.
+
+`PUT`
+    Similar to `POST` but the server might trigger the store procedure
+    multiple times by overwriting the old values more than once.  Now you
+    might be asking why is this useful, but there are some good reasons
+    to do it this way.  Consider that the connection gets lost during
+    transmission: in this situation a system between the browser and the
+    server might receive the request safely a second time without breaking
+    things.  With `POST` that would not be possible because it must only
+    be triggered once.
+
+`DELETE`
+    Remove the information at the given location.
+
+`OPTIONS`
+    Provides a quick way for a client to figure out which methods are
+    supported by this URL.  Starting with Flask 0.6, this is implemented
+    for you automatically.
+
+Now the interesting part is that in HTML4 and XHTML1, the only methods a
+form can submit to the server are `GET` and `POST`.  But with JavaScript
+and future HTML standards you can use the other methods as well.  Furthermore
+HTTP has become quite popular lately and browsers are no longer the only
+clients that are using HTTP. For instance, many revision control system
+use it.
+
+.. _HTTP RFC: http://www.ietf.org/rfc/rfc2068.txt
+
+Static Files
+------------
+
+Dynamic web applications need static files as well.  That's usually where
+the CSS and JavaScript files are coming from.  Ideally your web server is
+configured to serve them for you, but during development Flask can do that
+as well.  Just create a folder called `static` in your package or next to
+your module and it will be available at `/static` on the application.
+
+To generate URLs to that part of the URL, use the special ``'static'`` URL
+name::
+
+    url_for('static', filename='style.css')
+
+The file has to be stored on the filesystem as ``static/style.css``.
+
+Rendering Templates
+-------------------
+
+Generating HTML from within Python is not fun, and actually pretty
+cumbersome because you have to do the HTML escaping on your own to keep
+the application secure.  Because of that Flask configures the `Jinja2
+<http://jinja.pocoo.org/2/>`_ template engine for you automatically.
+
+To render a template you can use the :func:`~flask.render_template`
+method.  All you have to do is to provide the name of the template and the
+variables you want to pass to the template engine as keyword arguments.
+Here's a simple example of how to render a template::
+
+    from flask import render_template
+
+    @app.route('/hello/')
+    @app.route('/hello/<name>')
+    def hello(name=None):
+        return render_template('hello.html', name=name)
+
+Flask will look for templates in the `templates` folder.  So if your
+application is a module, that folder is next to that module, if it's a
+package it's actually inside your package:
+
+**Case 1**: a module::
+
+    /application.py
+    /templates
+        /hello.html
+
+**Case 2**: a package::
+
+    /application
+        /__init__.py
+        /templates
+            /hello.html
+
+For templates you can use the full power of Jinja2 templates.  Head over
+to the :ref:`templating` section of the documentation or the official
+`Jinja2 Template Documentation
+<http://jinja.pocoo.org/2/documentation/templates>`_ for more information.
+
+Here is an example template:
+
+.. sourcecode:: html+jinja
+
+    <!doctype html>
+    <title>Hello from Flask</title>
+    {% if name %}
+      <h1>Hello {{ name }}!</h1>
+    {% else %}
+      <h1>Hello World!</h1>
+    {% endif %}
+
+Inside templates you also have access to the :class:`~flask.request`,
+:class:`~flask.session` and :class:`~flask.g` [#]_ objects
+as well as the :func:`~flask.get_flashed_messages` function.
+
+Templates are especially useful if inheritance is used.  If you want to
+know how that works, head over to the :ref:`template-inheritance` pattern
+documentation.  Basically template inheritance makes it possible to keep
+certain elements on each page (like header, navigation and footer).
+
+Automatic escaping is enabled, so if name contains HTML it will be escaped
+automatically.  If you can trust a variable and you know that it will be
+safe HTML (because for example it came from a module that converts wiki
+markup to HTML) you can mark it as safe by using the
+:class:`~jinja2.Markup` class or by using the ``|safe`` filter in the
+template.  Head over to the Jinja 2 documentation for more examples.
+
+Here is a basic introduction to how the :class:`~jinja2.Markup` class works:
+
+>>> from flask import Markup
+>>> Markup('<strong>Hello %s!</strong>') % '<blink>hacker</blink>'
+Markup(u'<strong>Hello &lt;blink&gt;hacker&lt;/blink&gt;!</strong>')
+>>> Markup.escape('<blink>hacker</blink>')
+Markup(u'&lt;blink&gt;hacker&lt;/blink&gt;')
+>>> Markup('<em>Marked up</em> &raquo; HTML').striptags()
+u'Marked up \xbb HTML'
+
+.. versionchanged:: 0.5
+
+   Autoescaping is no longer enabled for all templates.  The following
+   extensions for templates trigger autoescaping: ``.html``, ``.htm``,
+   ``.xml``, ``.xhtml``.  Templates loaded from a string will have
+   autoescaping disabled.
+
+.. [#] Unsure what that :class:`~flask.g` object is? It's something in which
+   you can store information for your own needs, check the documentation of
+   that object (:class:`~flask.g`) and the :ref:`sqlite3` for more
+   information.
+
+
+Accessing Request Data
+----------------------
+
+For web applications it's crucial to react to the data a client sent to
+the server.  In Flask this information is provided by the global
+:class:`~flask.request` object.  If you have some experience with Python
+you might be wondering how that object can be global and how Flask
+manages to still be threadsafe.  The answer are context locals:
+
+
+.. _context-locals:
+
+Context Locals
+``````````````
+
+.. admonition:: Insider Information
+
+   If you want to understand how that works and how you can implement
+   tests with context locals, read this section, otherwise just skip it.
+
+Certain objects in Flask are global objects, but not of the usual kind.
+These objects are actually proxies to objects that are local to a specific
+context.  What a mouthful.  But that is actually quite easy to understand.
+
+Imagine the context being the handling thread.  A request comes in and the
+webserver decides to spawn a new thread (or something else, the
+underlying object is capable of dealing with other concurrency systems
+than threads as well).  When Flask starts its internal request handling it
+figures out that the current thread is the active context and binds the
+current application and the WSGI environments to that context (thread).
+It does that in an intelligent way that one application can invoke another
+application without breaking.
+
+So what does this mean to you?  Basically you can completely ignore that
+this is the case unless you are doing something like unittesting.  You
+will notice that code that depends on a request object will suddenly break
+because there is no request object.  The solution is creating a request
+object yourself and binding it to the context.  The easiest solution for
+unittesting is by using the :meth:`~flask.Flask.test_request_context`
+context manager.  In combination with the `with` statement it will bind a
+test request so that you can interact with it.  Here is an example::
+
+    from flask import request
+
+    with app.test_request_context('/hello', method='POST'):
+        # now you can do something with the request until the
+        # end of the with block, such as basic assertions:
+        assert request.path == '/hello'
+        assert request.method == 'POST'
+
+The other possibility is passing a whole WSGI environment to the
+:meth:`~flask.Flask.request_context` method::
+
+    from flask import request
+
+    with app.request_context(environ):
+        assert request.method == 'POST'
+
+The Request Object
+``````````````````
+
+The request object is documented in the API section and we will not cover
+it here in detail (see :class:`~flask.request`). Here is a broad overview of
+some of the most common operations.  First of all you have to import it from
+the `flask` module::
+
+    from flask import request
+
+The current request method is available by using the
+:attr:`~flask.request.method` attribute.  To access form data (data
+transmitted in a `POST` or `PUT` request) you can use the
+:attr:`~flask.request.form` attribute.  Here is a full example of the two
+attributes mentioned above::
+
+    @app.route('/login', methods=['POST', 'GET'])
+    def login():
+        error = None
+        if request.method == 'POST':
+            if valid_login(request.form['username'],
+                           request.form['password']):
+                return log_the_user_in(request.form['username'])
+            else:
+                error = 'Invalid username/password'
+        # this is executed if the request method was GET or the
+        # credentials were invalid
+
+What happens if the key does not exist in the `form` attribute?  In that
+case a special :exc:`KeyError` is raised.  You can catch it like a
+standard :exc:`KeyError` but if you don't do that, a HTTP 400 Bad Request
+error page is shown instead.  So for many situations you don't have to
+deal with that problem.
+
+To access parameters submitted in the URL (``?key=value``) you can use the
+:attr:`~flask.request.args` attribute::
+
+    searchword = request.args.get('q', '')
+
+We recommend accessing URL parameters with `get` or by catching the
+`KeyError` because users might change the URL and presenting them a 400
+bad request page in that case is not user friendly.
+
+For a full list of methods and attributes of the request object, head over
+to the :class:`~flask.request` documentation.
+
+
+File Uploads
+````````````
+
+You can handle uploaded files with Flask easily.  Just make sure not to
+forget to set the ``enctype="multipart/form-data"`` attribute on your HTML
+form, otherwise the browser will not transmit your files at all.
+
+Uploaded files are stored in memory or at a temporary location on the
+filesystem.  You can access those files by looking at the
+:attr:`~flask.request.files` attribute on the request object.  Each
+uploaded file is stored in that dictionary.  It behaves just like a
+standard Python :class:`file` object, but it also has a
+:meth:`~werkzeug.FileStorage.save` method that allows you to store that
+file on the filesystem of the server.  Here is a simple example showing how
+that works::
+
+    from flask import request
+
+    @app.route('/upload', methods=['GET', 'POST'])
+    def upload_file():
+        if request.method == 'POST':
+            f = request.files['the_file']
+            f.save('/var/www/uploads/uploaded_file.txt')
+        ...
+
+If you want to know how the file was named on the client before it was
+uploaded to your application, you can access the
+:attr:`~werkzeug.FileStorage.filename` attribute.  However please keep in
+mind that this value can be forged so never ever trust that value.  If you
+want to use the filename of the client to store the file on the server,
+pass it through the :func:`~werkzeug.secure_filename` function that
+Werkzeug provides for you::
+
+    from flask import request
+    from werkzeug import secure_filename
+
+    @app.route('/upload', methods=['GET', 'POST'])
+    def upload_file():
+        if request.method == 'POST':
+            f = request.files['the_file']
+            f.save('/var/www/uploads/' + secure_filename(f.filename))
+        ...
+
+For some better examples, checkout the :ref:`uploading-files` pattern.
+
+Cookies
+```````
+
+To access cookies you can use the :attr:`~flask.request.cookies`
+attribute.  Again this is a dictionary with all the cookies the client
+transmits.  If you want to use sessions, do not use the cookies directly
+but instead use the :ref:`sessions` in Flask that add some security on top
+of cookies for you.
+
+
+Redirects and Errors
+--------------------
+
+To redirect a user to somewhere else you can use the
+:func:`~flask.redirect` function. To abort a request early with an error
+code use the :func:`~flask.abort` function.  Here an example how this works::
+
+    from flask import abort, redirect, url_for
+
+    @app.route('/')
+    def index():
+        return redirect(url_for('login'))
+
+    @app.route('/login')
+    def login():
+        abort(401)
+        this_is_never_executed()
+
+This is a rather pointless example because a user will be redirected from
+the index to a page he cannot access (401 means access denied) but it
+shows how that works.
+
+By default a black and white error page is shown for each error code.  If
+you want to customize the error page, you can use the
+:meth:`~flask.Flask.errorhandler` decorator::
+
+    from flask import render_template
+
+    @app.errorhandler(404)
+    def page_not_found(error):
+        return render_template('page_not_found.html'), 404
+
+Note the ``404`` after the :func:`~flask.render_template` call.  This
+tells Flask that the status code of that page should be 404 which means
+not found.  By default 200 is assumed which translates to: all went well.
+
+.. _sessions:
+
+Sessions
+--------
+
+Besides the request object there is also a second object called
+:class:`~flask.session` that allows you to store information specific to a
+user from one request to the next.  This is implemented on top of cookies
+for you and signs the cookies cryptographically.  What this means is that
+the user could look at the contents of your cookie but not modify it,
+unless he knows the secret key used for signing.
+
+In order to use sessions you have to set a secret key.  Here is how
+sessions work::
+
+    from flask import Flask, session, redirect, url_for, escape, request
+
+    app = Flask(__name__)
+
+    @app.route('/')
+    def index():
+        if 'username' in session:
+            return 'Logged in as %s' % escape(session['username'])
+        return 'You are not logged in'
+
+    @app.route('/login', methods=['GET', 'POST'])
+    def login():
+        if request.method == 'POST':
+            session['username'] = request.form['username']
+            return redirect(url_for('index'))
+        return '''
+            <form action="" method="post">
+                <p><input type=text name=username>
+                <p><input type=submit value=Login>
+            </form>
+        '''
+
+    @app.route('/logout')
+    def logout():
+        # remove the username from the session if its there
+        session.pop('username', None)
+        return redirect(url_for('index'))
+
+    # set the secret key.  keep this really secret:
+    app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
+
+The here mentioned :func:`~flask.escape` does escaping for you if you are
+not using the template engine (like in this example).
+
+.. admonition:: How to generate good secret keys
+
+   The problem with random is that it's hard to judge what random is.  And
+   a secret key should be as random as possible.  Your operating system
+   has ways to generate pretty random stuff based on a cryptographic
+   random generator which can be used to get such a key:
+
+   >>> import os
+   >>> os.urandom(24)
+   '\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8'
+
+   Just take that thing and copy/paste it into your code and you're done.
+
+Message Flashing
+----------------
+
+Good applications and user interfaces are all about feedback.  If the user
+does not get enough feedback he will probably end up hating the
+application.  Flask provides a really simple way to give feedback to a
+user with the flashing system.  The flashing system basically makes it
+possible to record a message at the end of a request and access it next
+request and only next request.  This is usually combined with a layout
+template that does this.
+
+To flash a message use the :func:`~flask.flash` method, to get hold of the
+messages you can use :func:`~flask.get_flashed_messages` which is also
+available in the templates.  Check out the :ref:`message-flashing-pattern`
+for a full example.
+
+Logging
+-------
+
+.. versionadded:: 0.3
+
+Sometimes you might be in a situation where you deal with data that
+should be correct, but actually is not.  For example you may have some client
+side code that sends an HTTP request to the server but it's obviously
+malformed.  This might be caused by a user tempering with the data, or the
+client code failing.  Most of the time, it's okay to reply with ``400 Bad
+Request`` in that situation, but sometimes that won't do and the code has
+to continue working.
+
+You may still want to log that something fishy happened.  This is where
+loggers come in handy.  As of Flask 0.3 a logger is preconfigured for you
+to use.
+
+Here are some example log calls::
+
+    app.logger.debug('A value for debugging')
+    app.logger.warning('A warning occurred (%d apples)', 42)
+    app.logger.error('An error occurred')
+
+The attached :attr:`~flask.Flask.logger` is a standard logging
+:class:`~logging.Logger`, so head over to the official `logging
+documentation <http://docs.python.org/library/logging.html>`_ for more
+information.
+
+Hooking in WSGI Middlewares
+---------------------------
+
+If you want to add a WSGI middleware to your application you can wrap the
+internal WSGI application.  For example if you want to use one of the
+middlewares from the Werkzeug package to work around bugs in lighttpd, you
+can do it like this::
+
+    from werkzeug.contrib.fixers import LighttpdCGIRootFix
+    app.wsgi_app = LighttpdCGIRootFix(app.wsgi_app)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/security.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,168 @@
+Security Considerations
+=======================
+
+Web applications usually face all kinds of security problems and it's very
+hard to get everything right.  Flask tries to solve a few of these things
+for you, but there are a couple more you have to take care of yourself.
+
+.. _xss:
+
+Cross-Site Scripting (XSS)
+--------------------------
+
+Cross site scripting is the concept of injecting arbitrary HTML (and with
+it JavaScript) into the context of a website.  To remedy this, developers
+have to properly escape text so that it cannot include arbitrary HTML
+tags.  For more information on that have a look at the Wikipedia article
+on `Cross-Site Scripting
+<http://en.wikipedia.org/wiki/Cross-site_scripting>`_.
+
+Flask configures Jinja2 to automatically escape all values unless
+explicitly told otherwise.  This should rule out all XSS problems caused
+in templates, but there are still other places where you have to be
+careful:
+
+-   generating HTML without the help of Jinja2
+-   calling :class:`~flask.Markup` on data submitted by users
+-   sending out HTML from uploaded files, never do that, use the
+    `Content-Disposition: attachment` header to prevent that problem.
+-   sending out textfiles from uploaded files.  Some browsers are using
+    content-type guessing based on the first few bytes so users could
+    trick a browser to execute HTML.
+
+Another thing that is very important are unquoted attributes.  While
+Jinja2 can protect you from XSS issues by escaping HTML, there is one
+thing it cannot protect you from: XSS by attribute injection.  To counter
+this possible attack vector, be sure to always quote your attributes with
+either double or single quotes when using Jinja expressions in them:
+
+.. sourcecode:: html+jinja
+
+   <a href="{{ href }}">the text</a>
+
+Why is this necessary?  Because if you would not be doing that, an
+attacker could easily inject custom JavaScript handlers.  For example an
+attacker could inject this piece of HTML+JavaScript:
+
+.. sourcecode:: html
+
+   onmouseover=alert(document.cookie)
+
+When the user would then move with the mouse over the link, the cookie
+would be presented to the user in an alert window.  But instead of showing
+the cookie to the user, a good attacker might also execute any other
+JavaScript code.  In combination with CSS injections the attacker might
+even make the element fill out the entire page so that the user would
+just have to have the mouse anywhere on the page to trigger the attack.
+
+Cross-Site Request Forgery (CSRF)
+---------------------------------
+
+Another big problem is CSRF.  This is a very complex topic and I won't
+outline it here in detail just mention what it is and how to theoretically
+prevent it.
+
+If your authentication information is stored in cookies, you have implicit
+state management.  The state of "being logged in" is controlled by a
+cookie, and that cookie is sent with each request to a page.
+Unfortunately that includes requests triggered by 3rd party sites.  If you
+don't keep that in mind, some people might be able to trick your
+application's users with social engineering to do stupid things without
+them knowing.
+
+Say you have a specific URL that, when you sent `POST` requests to will
+delete a user's profile (say `http://example.com/user/delete`).  If an
+attacker now creates a page that sends a post request to that page with
+some JavaScript he just has to trick some users to load that page and
+their profiles will end up being deleted.
+
+Imagine you were to run Facebook with millions of concurrent users and
+someone would send out links to images of little kittens.  When users
+would go to that page, their profiles would get deleted while they are
+looking at images of fluffy cats.
+
+How can you prevent that?  Basically for each request that modifies
+content on the server you would have to either use a one-time token and
+store that in the cookie **and** also transmit it with the form data.
+After receiving the data on the server again, you would then have to
+compare the two tokens and ensure they are equal.
+
+Why does Flask not do that for you?  The ideal place for this to happen is
+the form validation framework, which does not exist in Flask.
+
+.. _json-security:
+
+JSON Security
+-------------
+
+JSON itself is a high-level serialization format, so there is barely
+anything that could cause security problems, right?  You can't declare
+recursive structures that could cause problems and the only thing that
+could possibly break are very large responses that can cause some kind of
+denial of service at the receiver's side.
+
+However there is a catch.  Due to how browsers work the CSRF issue comes
+up with JSON unfortunately.  Fortunately there is also a weird part of the
+JavaScript specification that can be used to solve that problem easily and
+Flask is kinda doing that for you by preventing you from doing dangerous
+stuff.  Unfortunately that protection is only there for
+:func:`~flask.jsonify` so you are still at risk when using other ways to
+generate JSON.
+
+So what is the issue and how to avoid it?  The problem are arrays at
+toplevel in JSON.  Imagine you send the following data out in a JSON
+request.  Say that's exporting the names and email addresses of all your
+friends for a part of the user interface that is written in JavaScript.
+Not very uncommon:
+
+.. sourcecode:: javascript
+
+    [
+        {"username": "admin",
+         "email": "admin@localhost"}
+    ]
+
+And it is doing that of course only as long as you are logged in and only
+for you.  And it is doing that for all `GET` requests to a certain URL,
+say the URL for that request is
+``http://example.com/api/get_friends.json``.
+
+So now what happens if a clever hacker is embedding this to his website
+and social engineers a victim to visiting his site:
+
+.. sourcecode:: html
+
+    <script type=text/javascript>
+    var captured = [];
+    var oldArray = Array;
+    function Array() {
+      var obj = this, id = 0, capture = function(value) {
+        obj.__defineSetter__(id++, capture);
+        if (value)
+          captured.push(value);
+      };
+      capture();
+    }
+    </script>
+    <script type=text/javascript
+      src=http://example.com/api/get_friends.json></script>
+    <script type=text/javascript>
+    Array = oldArray;
+    // now we have all the data in the captured array.
+    </script>
+
+If you know a bit of JavaScript internals you might know that it's
+possible to patch constructors and register callbacks for setters.  An
+attacker can use this (like above) to get all the data you exported in
+your JSON file.  The browser will totally ignore the ``application/json``
+mimetype if ``text/javascript`` is defined as content type in the script
+tag and evaluate that as JavaScript.  Because toplevel array elements are
+allowed (albeit useless) and we hooked in our own constructor, after that
+page loaded the data from the JSON response is in the `captured` array.
+
+Because it is a syntax error in JavaScript to have an object literal
+(``{...}``) toplevel an attacker could not just do a request to an
+external URL with the script tag to load up the data.  So what Flask does
+is to only allow objects as toplevel elements when using
+:func:`~flask.jsonify`.  Make sure to do the same when using an ordinary
+JSON generate function.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/shell.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,110 @@
+Working with the Shell
+======================
+
+.. versionadded:: 0.3
+
+One of the reasons everybody loves Python is the interactive shell.  It
+basically allows you to execute Python commands in real time and
+immediately get results back.  Flask itself does not come with an
+interactive shell, because it does not require any specific setup upfront,
+just import your application and start playing around.
+
+There are however some handy helpers to make playing around in the shell a
+more pleasant experience.  The main issue with interactive console
+sessions is that you're not triggering a request like a browser does which
+means that :data:`~flask.g`, :data:`~flask.request` and others are not
+available.  But the code you want to test might depend on them, so what
+can you do?
+
+This is where some helper functions come in handy.  Keep in mind however
+that these functions are not only there for interactive shell usage, but
+also for unittesting and other situations that require a faked request
+context.
+
+Diving into Context Locals
+--------------------------
+
+Say you have a utility function that returns the URL the user should be
+redirected to.  Imagine it would always redirect to the URL's ``next``
+parameter or the HTTP referrer or the index page::
+
+    from flask import request, url_for
+
+    def redirect_url():
+        return request.args.get('next') or \
+               request.referrer or \
+               url_for('index')
+
+As you can see, it accesses the request object.  If you try to run this
+from a plain Python shell, this is the exception you will see:
+
+>>> redirect_url()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in <module>
+AttributeError: 'NoneType' object has no attribute 'request'
+
+That makes a lot of sense because we currently do not have a request we
+could access.  So we have to make a request and bind it to the current
+context.  The :attr:`~flask.Flask.test_request_context` method can create
+us a request context:
+
+>>> ctx = app.test_request_context('/?next=http://example.com/')
+
+This context can be used in two ways.  Either with the `with` statement
+(which unfortunately is not very handy for shell sessions).  The
+alternative way is to call the `push` and `pop` methods:
+
+>>> ctx.push()
+
+From that point onwards you can work with the request object:
+
+>>> redirect_url()
+u'http://example.com/'
+
+Until you call `pop`:
+
+>>> ctx.pop()
+>>> redirect_url()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in <module>
+AttributeError: 'NoneType' object has no attribute 'request'
+
+
+Firing Before/After Request
+---------------------------
+
+By just creating a request context, you still don't have run the code that
+is normally run before a request.  This probably results in your database
+being unavailable, the current user not being stored on the
+:data:`~flask.g` object etc.
+
+This however can easily be done yourself.  Just call
+:meth:`~flask.Flask.preprocess_request`:
+
+>>> ctx = app.test_request_context()
+>>> ctx.push()
+>>> app.preprocess_request()
+
+Keep in mind that the :meth:`~flask.Flask.preprocess_request` function
+might return a response object, in that case just ignore it.
+
+To shutdown a request, you need to trick a bit before the after request
+functions (triggered by :meth:`~flask.Flask.process_response`) operate on
+a response object:
+
+>>> app.process_response(app.response_class())
+<Response 0 bytes [200 OK]>
+>>> ctx.pop()
+
+
+Further Improving the Shell Experience
+--------------------------------------
+
+If you like the idea of experimenting in a shell, create yourself a module
+with stuff you want to star import into your interactive session.  There
+you could also define some more helper methods for common things such as
+initializing the database, dropping tables etc.
+
+Just put them into a module (like `shelltools` and import from there):
+
+>>> from shelltools import *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/signals.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,239 @@
+.. _signals:
+
+Signals
+=======
+
+.. versionadded:: 0.6
+
+Starting with Flask 0.6, there is integrated support for signalling in
+Flask.  This support is provided by the excellent `blinker`_ library and
+will gracefully fall back if it is not available.
+
+What are signals?  Signals help you decouple applications by sending
+notifications when actions occur elsewhere in the core framework or
+another Flask extensions.  In short, signals allow certain senders to
+notify subscribers that something happened.
+
+Flask comes with a couple of signals and other extensions might provide
+more.  Also keep in mind that signals are intended to notify subscribers
+and should not encourage subscribers to modify data.  You will notice that
+there are signals that appear to do the same thing like some of the
+builtin decorators do (eg: :data:`~flask.request_started` is very similar
+to :meth:`~flask.Flask.before_request`).  There are however difference in
+how they work.  The core :meth:`~flask.Flask.before_request` handler for
+example is executed in a specific order and is able to abort the request
+early by returning a response.  In contrast all signal handlers are
+executed in undefined order and do not modify any data.
+
+The big advantage of signals over handlers is that you can safely
+subscribe to them for the split of a second.  These temporary
+subscriptions are helpful for unittesting for example.  Say you want to
+know what templates were rendered as part of a request: signals allow you
+to do exactly that.
+
+Subscribing to Signals
+----------------------
+
+To subscribe to a signal, you can use the
+:meth:`~blinker.base.Signal.connect` method of a signal.  The first
+argument is the function that should be called when the signal is emitted,
+the optional second argument specifies a sender.  To unsubscribe from a
+signal, you can use the :meth:`~blinker.base.Signal.disconnect` method.
+
+For all core Flask signals, the sender is the application that issued the
+signal.  When you subscribe to a signal, be sure to also provide a sender
+unless you really want to listen for signals of all applications.  This is
+especially true if you are developing an extension.
+
+Here for example a helper context manager that can be used to figure out
+in a unittest which templates were rendered and what variables were passed
+to the template::
+
+    from flask import template_rendered
+    from contextlib import contextmanager
+
+    @contextmanager
+    def captured_templates(app):
+        recorded = []
+        def record(sender, template, context):
+            recorded.append((template, context))
+        template_rendered.connect(record, app)
+        try:
+            yield recorded
+        finally:
+            template_rendered.disconnect(record, app)
+
+This can now easily be paired with a test client::
+
+    with captured_templates(app) as templates:
+        rv = app.test_client().get('/')
+        assert rv.status_code == 200
+        assert len(templates) == 1
+        template, context = templates[0]
+        assert template.name == 'index.html'
+        assert len(context['items']) == 10
+
+All the template rendering in the code issued by the application `app`
+in the body of the `with` block will now be recorded in the `templates`
+variable.  Whenever a template is rendered, the template object as well as
+context are appended to it.
+
+Additionally there is a convenient helper method
+(:meth:`~blinker.base.Signal.connected_to`).  that allows you to
+temporarily subscribe a function to a signal with is a context manager on
+its own.  Because the return value of the context manager cannot be
+specified that way one has to pass the list in as argument::
+
+    from flask import template_rendered
+
+    def captured_templates(app, recorded):
+        def record(sender, template, context):
+            recorded.append((template, context))
+        return template_rendered.connected_to(record, app)
+
+The example above would then look like this::
+
+    templates = []
+    with captured_templates(app, templates):
+        ...
+        template, context = templates[0]
+
+.. admonition:: Blinker API Changes
+
+   The :meth:`~blinker.base.Signal.connected_to` method arrived in Blinker
+   with version 1.1.
+
+Creating Signals
+----------------
+
+If you want to use signals in your own application, you can use the
+blinker library directly.  The most common use case are named signals in a
+custom :class:`~blinker.base.Namespace`..  This is what is recommended
+most of the time::
+
+    from blinker import Namespace
+    my_signals = Namespace()
+
+Now you can create new signals like this::
+
+    model_saved = my_signals.signal('model-saved')
+
+The name for the signal here makes it unique and also simplifies
+debugging.  You can access the name of the signal with the
+:attr:`~blinker.base.NamedSignal.name` attribute.
+
+.. admonition:: For Extension Developers
+
+   If you are writing a Flask extension and you to gracefully degrade for
+   missing blinker installations, you can do so by using the
+   :class:`flask.signals.Namespace` class.
+
+Sending Signals
+---------------
+
+If you want to emit a signal, you can do so by calling the
+:meth:`~blinker.base.Signal.send` method.  It accepts a sender as first
+argument and optionally some keyword arguments that are forwarded to the
+signal subscribers::
+
+    class Model(object):
+        ...
+
+        def save(self):
+            model_saved.send(self)
+
+Try to always pick a good sender.  If you have a class that is emitting a
+signal, pass `self` as sender.  If you emitting a signal from a random
+function, you can pass ``current_app._get_current_object()`` as sender.
+
+.. admonition:: Passing Proxies as Senders
+
+   Never pass :data:`~flask.current_app` as sender to a signal.  Use
+   ``current_app._get_current_object()`` instead.  The reason for this is
+   that :data:`~flask.current_app` is a proxy and not the real application
+   object.
+
+Decorator Based Signal Subscriptions
+------------------------------------
+
+With Blinker 1.1 you can also easily subscribe to signals by using the new
+:meth:`~blinker.base.NamedSignal.connect_via` decorator::
+
+    from flask import template_rendered
+
+    @template_rendered.connect_via(app)
+    def when_template_rendered(sender, template, context):
+        print 'Template %s is rendered with %s' % (template.name, context)
+
+Core Signals
+------------
+
+.. when modifying this list, also update the one in api.rst
+
+The following signals exist in Flask:
+
+.. data:: flask.template_rendered
+   :noindex:
+
+   This signal is sent when a template was successfully rendered.  The
+   signal is invoked with the instance of the template as `template`
+   and the context as dictionary (named `context`).
+
+   Example subscriber::
+
+        def log_template_renders(sender, template, context):
+            sender.logger.debug('Rendering template "%s" with context %s',
+                                template.name or 'string template',
+                                context)
+
+        from flask import template_rendered
+        template_rendered.connect(log_template_renders, app)
+
+.. data:: flask.request_started
+   :noindex:
+
+   This signal is sent before any request processing started but when the
+   request context was set up.  Because the request context is already
+   bound, the subscriber can access the request with the standard global
+   proxies such as :class:`~flask.request`.
+
+   Example subscriber::
+
+        def log_request(sender):
+            sender.logger.debug('Request context is set up')
+
+        from flask import request_started
+        request_started.connect(log_request, app)
+
+.. data:: flask.request_finished
+   :noindex:
+
+   This signal is sent right before the response is sent to the client.
+   It is passed the response to be sent named `response`.
+
+   Example subscriber::
+
+        def log_response(sender, response):
+            sender.logger.debug('Request context is about to close down.  '
+                                'Response: %s', response)
+
+        from flask import request_finished
+        request_finished.connect(log_response, app)
+
+.. data:: flask.got_request_exception
+   :noindex:
+
+   This signal is sent when an exception happens during request processing.
+   It is sent *before* the standard exception handling kicks in and even
+   in debug mode, where no exception handling happens.  The exception
+   itself is passed to the subscriber as `exception`.
+
+   Example subscriber::
+
+        def log_exception(sender, exception):
+            sender.logger.debug('Got exception during processing: %s', exception)
+
+        from flask import got_request_exception
+        got_request_exception.connect(log_exception, app)
+
+.. _blinker: http://pypi.python.org/pypi/blinker
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/styleguide.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,200 @@
+Pocoo Styleguide
+================
+
+The Pocoo styleguide is the styleguide for all Pocoo Projects, including
+Flask.  This styleguide is a requirement for Patches to Flask and a
+recommendation for Flask extensions.
+
+In general the Pocoo Styleguide closely follows :pep:`8` with some small
+differences and extensions.
+
+General Layout
+--------------
+
+Indentation:
+  4 real spaces.  No tabs, no exceptions.
+
+Maximum line length:
+  79 characters with a soft limit for 84 if absolutely necessary.  Try
+  to avoid too nested code by cleverly placing `break`, `continue` and
+  `return` statements.
+
+Continuing long statements:
+  To continue a statement you can use backslashes in which case you should
+  align the next line with the last dot or equal sign, or indent four
+  spaces::
+
+    this_is_a_very_long(function_call, 'with many parameters') \
+        .that_returns_an_object_with_an_attribute
+
+    MyModel.query.filter(MyModel.scalar > 120) \
+                 .order_by(MyModel.name.desc()) \
+                 .limit(10)
+
+  If you break in a statement with parentheses or braces, align to the
+  braces::
+
+    this_is_a_very_long(function_call, 'with many parameters',
+                        23, 42, 'and even more')
+
+  For lists or tuples with many items, break immediately after the
+  opening brace::
+
+    items = [
+        'this is the first', 'set of items', 'with more items',
+        'to come in this line', 'like this'
+    ]
+
+Blank lines:
+  Top level functions and classes are separated by two lines, everything
+  else by one.  Do not use too many blank lines to separate logical
+  segments in code.  Example::
+
+    def hello(name):
+        print 'Hello %s!' % name
+
+
+    def goodbye(name):
+        print 'See you %s.' % name
+
+
+    class MyClass(object):
+        """This is a simple docstring"""
+
+        def __init__(self, name):
+            self.name = name
+
+        def get_annoying_name(self):
+            return self.name.upper() + '!!!!111'
+
+Expressions and Statements
+--------------------------
+
+General whitespace rules:
+  - No whitespace for unary operators that are not words
+    (e.g.: ``-``, ``~`` etc.) as well on the inner side of parentheses.
+  - Whitespace is placed between binary operators.
+
+  Good::
+
+    exp = -1.05
+    value = (item_value / item_count) * offset / exp
+    value = my_list[index]
+    value = my_dict['key']
+
+  Bad::
+
+    exp = - 1.05
+    value = ( item_value / item_count ) * offset / exp
+    value = (item_value/item_count)*offset/exp
+    value=( item_value/item_count ) * offset/exp
+    value = my_list[ index ]
+    value = my_dict ['key']
+
+Yoda statements are a nogo:
+  Never compare constant with variable, always variable with constant:
+
+  Good::
+
+    if method == 'md5':
+        pass
+
+  Bad::
+
+    if 'md5' == method:
+        pass
+
+Comparisons:
+  - against arbitrary types: ``==`` and ``!=``
+  - against singletons with ``is`` and ``is not`` (eg: ``foo is not
+    None``)
+  - never compare something with `True` or `False` (for example never
+    do ``foo == False``, do ``not foo`` instead)
+
+Negated containment checks:
+  use ``foo not in bar`` instead of ``not foo in bar``
+
+Instance checks:
+  ``isinstance(a, C)`` instead of ``type(A) is C``, but try to avoid
+  instance checks in general.  Check for features.
+
+
+Naming Conventions
+------------------
+
+- Class names: ``CamelCase``, with acronyms kept uppercase (``HTTPWriter``
+  and not ``HttpWriter``)
+- Variable names: ``lowercase_with_underscores``
+- Method and function names: ``lowercase_with_underscores``
+- Constants: ``UPPERCASE_WITH_UNDERSCORES``
+- precompiled regular expressions: ``name_re``
+
+Protected members are prefixed with a single underscore.  Double
+underscores are reserved for mixin classes.
+
+On classes with keywords, trailing underscores are appended.  Clashes with
+builtins are allowed and **must not** be resolved by appending an
+underline to the variable name.  If the function needs to access a
+shadowed builtin, rebind the builtin to a different name instead.
+
+Function and method arguments:
+  - class methods: ``cls`` as first parameter
+  - instance methods: ``self`` as first parameter
+  - lambdas for properties might have the first parameter replaced
+    with ``x`` like in ``display_name = property(lambda x: x.real_name
+    or x.username)``
+
+
+Docstrings
+----------
+
+Docstring conventions:
+  All docstrings are formatted with reStructuredText as understood by
+  Sphinx.  Depending on the number of lines in the docstring, they are
+  laid out differently.  If it's just one line, the closing triple
+  quote is on the same line as the opening, otherwise the text is on
+  the same line as the opening quote and the triple quote that closes
+  the string on its own line::
+
+    def foo():
+        """This is a simple docstring"""
+
+
+    def bar():
+        """This is a longer docstring with so much information in there
+        that it spans three lines.  In this case the closing triple quote
+        is on its own line.
+        """
+
+Module header:
+  The module header consists of an utf-8 encoding declaration (if non
+  ASCII letters are used, but it is recommended all the time) and a
+  standard docstring::
+
+    # -*- coding: utf-8 -*-
+    """
+        package.module
+        ~~~~~~~~~~~~~~
+
+        A brief description goes here.
+
+        :copyright: (c) YEAR by AUTHOR.
+        :license: LICENSE_NAME, see LICENSE_FILE for more details.
+    """
+
+  Please keep in mind that proper copyrights and license files are a
+  requirement for approved Flask extensions.
+
+
+Comments
+--------
+
+Rules for comments are similar to docstrings.  Both are formatted with
+reStructuredText.  If a comment is used to document an attribute, put a
+colon after the opening pound sign (``#``)::
+
+    class User(object):
+        #: the name of the user as unicode string
+        name = Column(String)
+        #: the sha1 hash of the password + inline salt
+        pw_hash = Column(String)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/templating.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,188 @@
+Templates
+=========
+
+Flask leverages Jinja2 as template engine.  You are obviously free to use
+a different template engine, but you still have to install Jinja2 to run
+Flask itself.  This requirement is necessary to enable rich extensions.
+An extension can depend on Jinja2 being present.
+
+This section only gives a very quick introduction into how Jinja2
+is integrated into Flask.  If you want information on the template
+engine's syntax itself, head over to the official `Jinja2 Template
+Documentation <http://jinja.pocoo.org/2/documentation/templates>`_ for
+more information.
+
+Jinja Setup
+-----------
+
+Unless customized, Jinja2 is configured by Flask as follows:
+
+-   autoescaping is enabled for all templates ending in ``.html``,
+    ``.htm``, ``.xml`` as well as ``.xhtml``
+-   a template has the ability to opt in/out autoescaping with the
+    ``{% autoescape %}`` tag.
+-   Flask inserts a couple of global functions and helpers into the
+    Jinja2 context, additionally to the values that are present by
+    default.
+
+Standard Context
+----------------
+
+The following global variables are available within Jinja2 templates
+by default:
+
+.. data:: config
+   :noindex:
+
+   The current configuration object (:data:`flask.config`)
+
+   .. versionadded:: 0.6
+
+.. data:: request
+   :noindex:
+
+   The current request object (:class:`flask.request`)
+
+.. data:: session
+   :noindex:
+
+   The current session object (:class:`flask.session`)
+
+.. data:: g
+   :noindex:
+
+   The request-bound object for global variables (:data:`flask.g`)
+
+.. function:: url_for
+   :noindex:
+
+   The :func:`flask.url_for` function.
+
+.. function:: get_flashed_messages
+   :noindex:
+
+   The :func:`flask.get_flashed_messages` function.
+
+.. admonition:: The Jinja Context Behaviour
+
+   These variables are added to the context of variables, they are not
+   global variables.  The difference is that by default these will not
+   show up in the context of imported templates.  This is partially caused
+   by performance considerations, partially to keep things explicit.
+
+   What does this mean for you?  If you have a macro you want to import,
+   that needs to access the request object you have two possibilities:
+
+   1.   you explicitly pass the request to the macro as parameter, or
+        the attribute of the request object you are interested in.
+   2.   you import the macro "with context".
+
+   Importing with context looks like this:
+
+   .. sourcecode:: jinja
+
+      {% from '_helpers.html' import my_macro with context %}
+
+Standard Filters
+----------------
+
+These filters are available in Jinja2 additionally to the filters provided
+by Jinja2 itself:
+
+.. function:: tojson
+   :noindex:
+
+   This function converts the given object into JSON representation.  This
+   is for example very helpful if you try to generate JavaScript on the
+   fly.
+
+   Note that inside `script` tags no escaping must take place, so make
+   sure to disable escaping with ``|safe`` if you intend to use it inside
+   `script` tags:
+
+   .. sourcecode:: html+jinja
+
+       <script type=text/javascript>
+           doSomethingWith({{ user.username|tojson|safe }});
+       </script>
+
+   That the ``|tojson`` filter escapes forward slashes properly for you.
+
+Controlling Autoescaping
+------------------------
+
+Autoescaping is the concept of automatically escaping special characters
+of you.  Special characters in the sense of HTML (or XML, and thus XHTML)
+are ``&``, ``>``, ``<``, ``"`` as well as ``'``.  Because these characters
+carry specific meanings in documents on their own you have to replace them
+by so called "entities" if you want to use them for text.  Not doing so
+would not only cause user frustration by the inability to use these
+characters in text, but can also lead to security problems.  (see
+:ref:`xss`)
+
+Sometimes however you will need to disable autoescaping in templates.
+This can be the case if you want to explicitly inject HTML into pages, for
+example if they come from a system that generate secure HTML like a
+markdown to HTML converter.
+
+There are three ways to accomplish that:
+
+-   In the Python code, wrap the HTML string in a :class:`~flask.Markup`
+    object before passing it to the template.  This is in general the
+    recommended way.
+-   Inside the template, use the ``|safe`` filter to explicitly mark a
+    string as safe HTML (``{{ myvariable|safe }}``)
+-   Temporarily disable the autoescape system altogether.
+
+To disable the autoescape system in templates, you can use the ``{%
+autoescape %}`` block:
+
+.. sourcecode:: html+jinja
+
+    {% autoescape false %}
+        <p>autoescaping is disabled here
+        <p>{{ will_not_be_escaped }}
+    {% endautoescape %}
+
+Whenever you do this, please be very cautious about the variables you are
+using in this block.
+
+Registering Filters
+-------------------
+
+If you want to register your own filters in Jinja2 you have two ways to do
+that.  You can either put them by hand into the
+:attr:`~flask.Flask.jinja_env` of the application or use the
+:meth:`~flask.Flask.template_filter` decorator.
+
+The two following examples work the same and both reverse an object::
+
+    @app.template_filter('reverse')
+    def reverse_filter(s):
+        return s[::-1]
+
+    def reverse_filter(s):
+        return s[::-1]
+    app.jinja_env.filters['reverse'] = reverse_filter
+
+In case of the decorator the argument is optional if you want to use the
+function name as name of the filter.
+
+Context Processors
+------------------
+
+To inject new variables automatically into the context of a template
+context processors exist in Flask.  Context processors run before the
+template is rendered and have the ability to inject new values into the
+template context.  A context processor is a function that returns a
+dictionary.  The keys and values of this dictionary are then merged with
+the template context::
+
+    @app.context_processor
+    def inject_user():
+        return dict(user=g.user)
+
+The context processor above makes a variable called `user` available in
+the template with the value of `g.user`.  This example is not very
+interesting because `g` is available in templates anyways, but it gives an
+idea how this works.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/testing.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,244 @@
+.. _testing:
+
+Testing Flask Applications
+==========================
+
+   **Something that is untested is broken.**
+
+Not sure where that is coming from, and it's not entirely correct, but
+also not that far from the truth.  Untested applications make it hard to
+improve existing code and developers of untested applications tend to
+become pretty paranoid.  If an application has automated tests, you can
+safely change things, and you will instantly know if your change broke
+something.
+
+Flask gives you a couple of ways to test applications.  It mainly does
+that by exposing the Werkzeug test :class:`~werkzeug.Client` class to your
+code and handling the context locals for you.  You can then use that with
+your favourite testing solution.  In this documentation we will use the
+:mod:`unittest` package that comes preinstalled with each Python
+installation.
+
+The Application
+---------------
+
+First we need an application to test for functionality.  For the testing
+we will use the application from the :ref:`tutorial`.  If you don't have
+that application yet, get the sources from `the examples`_.
+
+.. _the examples:
+   http://github.com/mitsuhiko/flask/tree/master/examples/flaskr/
+
+The Testing Skeleton
+--------------------
+
+In order to test that, we add a second module (
+`flaskr_tests.py`) and create a unittest skeleton there::
+
+    import os
+    import flaskr
+    import unittest
+    import tempfile
+
+    class FlaskrTestCase(unittest.TestCase):
+
+        def setUp(self):
+            self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
+            self.app = flaskr.app.test_client()
+            flaskr.init_db()
+
+        def tearDown(self):
+            os.close(self.db_fd)
+            os.unlink(flaskr.app.config['DATABASE'])
+
+    if __name__ == '__main__':
+        unittest.main()
+
+The code in the :meth:`~unittest.TestCase.setUp` method creates a new test
+client and initializes a new database.  That function is called before
+each individual test function.  To delete the database after the test, we
+close the file and remove it from the filesystem in the
+:meth:`~unittest.TestCase.tearDown` method.  What the test client does is
+give us a simple interface to the application.  We can trigger test
+requests to the application, and the client will also keep track of cookies
+for us.
+
+Because SQLite3 is filesystem-based we can easily use the tempfile module
+to create a temporary database and initialize it.  The
+:func:`~tempfile.mkstemp` function does two things for us: it returns a
+low-level file handle and a random file name, the latter we use as
+database name.  We just have to keep the `db_fd` around so that we can use
+the :func:`os.close` function to close the file.
+
+If we now run that test suite, we should see the following output::
+
+    $ python flaskr_tests.py
+
+    ----------------------------------------------------------------------
+    Ran 0 tests in 0.000s
+
+    OK
+
+Even though it did not run any tests, we already know that our flaskr
+application is syntactically valid, otherwise the import would have died
+with an exception.
+
+The First Test
+--------------
+
+Now we can add the first test.  Let's check that the application shows
+"No entries here so far" if we access the root of the application (``/``).
+For that we modify our created test case class so that it looks like
+this::
+
+    class FlaskrTestCase(unittest.TestCase):
+
+        def setUp(self):
+            self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
+            self.app = flaskr.app.test_client()
+            flaskr.init_db()
+
+        def tearDown(self):
+            os.close(self.db_fd)
+            os.unlink(flaskr.DATABASE)
+
+        def test_empty_db(self):
+            rv = self.app.get('/')
+            assert 'No entries here so far' in rv.data
+
+Test functions begin with the word `test`.  Every function named like that
+will be picked up automatically.  By using `self.app.get` we can send an
+HTTP `GET` request to the application with the given path.  The return
+value will be a :class:`~flask.Flask.response_class` object.  We can now
+use the :attr:`~werkzeug.BaseResponse.data` attribute to inspect the
+return value (as string) from the application.  In this case, we ensure
+that ``'No entries here so far'`` is part of the output.
+
+Run it again and you should see one passing test::
+
+    $ python flaskr_tests.py
+    .
+    ----------------------------------------------------------------------
+    Ran 1 test in 0.034s
+
+    OK
+
+Of course you can submit forms with the test client as well, which we will
+use now to log our user in.
+
+Logging In and Out
+------------------
+
+The majority of the functionality of our application is only available for
+the administrative user, so we need a way to log our test client in to the
+application and out of it again.  For that we fire some requests to the
+login and logout pages with the required form data (username and
+password).  Because the login and logout pages redirect, we tell the
+client to `follow_redirects`.
+
+Add the following two methods to your `FlaskrTestCase` class::
+
+   def login(self, username, password):
+       return self.app.post('/login', data=dict(
+           username=username,
+           password=password
+       ), follow_redirects=True)
+
+   def logout(self):
+       return self.app.get('/logout', follow_redirects=True)
+
+Now we can easily test if logging in and out works and that it fails with
+invalid credentials.  Add this new test to the class::
+
+   def test_login_logout(self):
+       rv = self.login('admin', 'default')
+       assert 'You were logged in' in rv.data
+       rv = self.logout()
+       assert 'You were logged out' in rv.data
+       rv = self.login('adminx', 'default')
+       assert 'Invalid username' in rv.data
+       rv = self.login('admin', 'defaultx')
+       assert 'Invalid password' in rv.data
+
+Test Adding Messages
+--------------------
+
+Now we can also test that adding messages works.  Add a new test method
+like this::
+
+    def test_messages(self):
+        self.login('admin', 'default')
+        rv = self.app.post('/add', data=dict(
+            title='<Hello>',
+            text='<strong>HTML</strong> allowed here'
+        ), follow_redirects=True)
+        assert 'No entries here so far' not in rv.data
+        assert '&lt;Hello&gt;' in rv.data
+        assert '<strong>HTML</strong> allowed here' in rv.data
+
+Here we check that HTML is allowed in the text but not in the title,
+which is the intended behavior.
+
+Running that should now give us three passing tests::
+
+    $ python flaskr_tests.py
+    ...
+    ----------------------------------------------------------------------
+    Ran 3 tests in 0.332s
+
+    OK
+
+For more complex tests with headers and status codes, check out the
+`MiniTwit Example`_ from the sources.  That one contains a larger test
+suite.
+
+
+.. _MiniTwit Example:
+   http://github.com/mitsuhiko/flask/tree/master/examples/minitwit/
+
+
+Other Testing Tricks
+--------------------
+
+Besides using the test client we used above, there is also the
+:meth:`~flask.Flask.test_request_context` method that in combination with
+the `with` statement can be used to activate a request context
+temporarily.  With that you can access the :class:`~flask.request`,
+:class:`~flask.g` and :class:`~flask.session` objects like in view
+functions.  Here's a full example that showcases this::
+
+    app = flask.Flask(__name__)
+
+    with app.test_request_context('/?name=Peter'):
+        assert flask.request.path == '/'
+        assert flask.request.args['name'] == 'Peter'
+
+All the other objects that are context bound can be used the same.
+
+If you want to test your application with different configurations and
+there does not seem to be a good way to do that, consider switching to
+application factories (see :ref:`app-factories`).
+
+
+Keeping the Context Around
+--------------------------
+
+.. versionadded:: 0.4
+
+Sometimes it can be helpful to trigger a regular request but keep the
+context around for a little longer so that additional introspection can
+happen.  With Flask 0.4 this is possible by using the
+:meth:`~flask.Flask.test_client` with a `with` block::
+
+    app = flask.Flask(__name__)
+
+    with app.test_client() as c:
+        rv = c.get('/?tequila=42')
+        assert request.args['tequila'] == '42'
+
+If you would just be using the :meth:`~flask.Flask.test_client` without
+the `with` block, the `assert` would fail with an error because `request`
+is no longer available (because used outside of an actual request).
+Keep in mind however that :meth:`~flask.Flask.after_request` functions
+are already called at that point so your database connection and
+everything involved is probably already closed down.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/css.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,31 @@
+.. _tutorial-css:
+
+Step 7: Adding Style
+====================
+
+Now that everything else works, it's time to add some style to the
+application.  Just create a stylesheet called `style.css` in the `static`
+folder we created before:
+
+.. sourcecode:: css
+
+    body            { font-family: sans-serif; background: #eee; }
+    a, h1, h2       { color: #377BA8; }
+    h1, h2          { font-family: 'Georgia', serif; margin: 0; }
+    h1              { border-bottom: 2px solid #eee; }
+    h2              { font-size: 1.2em; }
+
+    .page           { margin: 2em auto; width: 35em; border: 5px solid #ccc;
+                      padding: 0.8em; background: white; }
+    .entries        { list-style: none; margin: 0; padding: 0; }
+    .entries li     { margin: 0.8em 1.2em; }
+    .entries li h2  { margin-left: -1em; }
+    .add-entry      { font-size: 0.9em; border-bottom: 1px solid #ccc; }
+    .add-entry dl   { font-weight: bold; }
+    .metanav        { text-align: right; font-size: 0.8em; padding: 0.3em;
+                      margin-bottom: 1em; background: #fafafa; }
+    .flash          { background: #CEE5F5; padding: 0.5em;
+                      border: 1px solid #AACBE2; }
+    .error          { background: #F0D6D6; padding: 0.5em; }
+
+Continue with :ref:`tutorial-testing`.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/dbcon.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,37 @@
+.. _tutorial-dbcon:
+
+Step 4: Request Database Connections
+------------------------------------
+
+Now we know how we can open database connections and use them for scripts,
+but how can we elegantly do that for requests?  We will need the database
+connection in all our functions so it makes sense to initialize them
+before each request and shut them down afterwards.
+
+Flask allows us to do that with the :meth:`~flask.Flask.before_request` and
+:meth:`~flask.Flask.after_request` decorators::
+
+    @app.before_request
+    def before_request():
+        g.db = connect_db()
+
+    @app.after_request
+    def after_request(response):
+        g.db.close()
+        return response
+
+Functions marked with :meth:`~flask.Flask.before_request` are called before
+a request and passed no arguments, functions marked with
+:meth:`~flask.Flask.after_request` are called after a request and
+passed the response that will be sent to the client.  They have to return
+that response object or a different one.  In this case we just return it
+unchanged.
+
+We store our current database connection on the special :data:`~flask.g`
+object that flask provides for us.  This object stores information for one
+request only and is available from within each function.  Never store such
+things on other objects because this would not work with threaded
+environments.  That special :data:`~flask.g` object does some magic behind
+the scenes to ensure it does the right thing.
+
+Continue to :ref:`tutorial-views`.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/dbinit.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,67 @@
+.. _tutorial-dbinit:
+
+Step 3: Creating The Database
+=============================
+
+Flaskr is a database powered application as outlined earlier, and more
+precisely, an application powered by a relational database system.  Such
+systems need a schema that tells them how to store that information. So
+before starting the server for the first time it's important to create
+that schema.
+
+Such a schema can be created by piping the `schema.sql` file into the
+`sqlite3` command as follows::
+
+    sqlite3 /tmp/flaskr.db < schema.sql
+
+The downside of this is that it requires the sqlite3 command to be
+installed which is not necessarily the case on every system.  Also one has
+to provide the path to the database there which leaves some place for
+errors.  It's a good idea to add a function that initializes the database
+for you to the application.
+
+If you want to do that, you first have to import the
+:func:`contextlib.closing` function from the contextlib package.  If you
+want to use Python 2.5 it's also necessary to enable the `with` statement
+first (`__future__` imports must be the very first import)::
+
+    from __future__ import with_statement
+    from contextlib import closing
+
+Next we can create a function called `init_db` that initializes the
+database.  For this we can use the `connect_db` function we defined
+earlier.  Just add that function below the `connect_db` function::
+
+    def init_db():
+        with closing(connect_db()) as db:
+            with app.open_resource('schema.sql') as f:
+                db.cursor().executescript(f.read())
+            db.commit()
+
+The :func:`~contextlib.closing` helper function allows us to keep a
+connection open for the duration of the `with` block.  The
+:func:`~flask.Flask.open_resource` method of the application object
+supports that functionality out of the box, so it can be used in the
+`with` block directly.  This function opens a file from the resource
+location (your `flaskr` folder) and allows you to read from it.  We are
+using this here to execute a script on the database connection.
+
+When we connect to a database we get a connection object (here called
+`db`) that can give us a cursor.  On that cursor there is a method to
+execute a complete script.  Finally we only have to commit the changes.
+SQLite 3 and other transactional databases will not commit unless you
+explicitly tell it to.
+
+Now it is possible to create a database by starting up a Python shell and
+importing and calling that function::
+
+>>> from flaskr import init_db
+>>> init_db()
+
+.. admonition:: Troubleshooting
+
+   If you get an exception later that a table cannot be found check that
+   you did call the `init_db` function and that your table names are
+   correct (singular vs. plural for example).
+
+Continue with :ref:`tutorial-dbcon`
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/folders.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,23 @@
+.. _tutorial-folders:
+
+Step 0: Creating The Folders
+============================
+
+Before we get started, let's create the folders needed for this
+application::
+
+    /flaskr
+        /static
+        /templates
+
+The `flaskr` folder is not a python package, but just something where we
+drop our files.  Directly into this folder we will then put our database
+schema as well as main module in the following steps.  The files inside
+the `static` folder are available to users of the application via `HTTP`.
+This is the place where css and javascript files go.  Inside the
+`templates` folder Flask will look for `Jinja2`_ templates.  The
+templates you create later in the tutorial will go in this directory.
+
+Continue with :ref:`tutorial-schema`.
+
+.. _Jinja2: http://jinja.pocoo.org/2/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/index.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,32 @@
+.. _tutorial:
+
+Tutorial
+========
+
+You want to develop an application with Python and Flask?  Here you have
+the chance to learn that by example.  In this tutorial we will create a
+simple microblog application.  It only supports one user that can create
+text-only entries and there are no feeds or comments, but it still
+features everything you need to get started.  We will use Flask and SQLite
+as database which comes out of the box with Python, so there is nothing
+else you need.
+
+If you want the full sourcecode in advance or for comparison, check out
+the `example source`_.
+
+.. _example source:
+   http://github.com/mitsuhiko/flask/tree/master/examples/flaskr/
+
+.. toctree::
+   :maxdepth: 2
+
+   introduction
+   folders
+   schema
+   setup
+   dbinit
+   dbcon
+   views
+   templates
+   css
+   testing
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/introduction.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,33 @@
+.. _tutorial-introduction:
+
+Introducing Flaskr
+==================
+
+We will call our blogging application flaskr here, feel free to chose a
+less web-2.0-ish name ;)  Basically we want it to do the following things:
+
+1. let the user sign in and out with credentials specified in the
+   configuration.  Only one user is supported.
+2. when the user is logged in he or she can add new entries to the page
+   consisting of a text-only title and some HTML for the text.  This HTML
+   is not sanitized because we trust the user here.
+3. the page shows all entries so far in reverse order (newest on top) and
+   the user can add new ones from there if logged in.
+
+We will be using SQLite3 directly for that application because it's good
+enough for an application of that size.  For larger applications however
+it makes a lot of sense to use `SQLAlchemy`_ that handles database
+connections in a more intelligent way, allows you to target different
+relational databases at once and more.  You might also want to consider
+one of the popular NoSQL databases if your data is more suited for those.
+
+Here a screenshot from the final application:
+
+.. image:: ../_static/flaskr.png
+   :align: center
+   :class: screenshot
+   :alt: screenshot of the final application
+
+Continue with :ref:`tutorial-folders`.
+
+.. _SQLAlchemy: http://www.sqlalchemy.org/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/schema.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,25 @@
+.. _tutorial-schema:
+
+Step 1: Database Schema
+=======================
+
+First we want to create the database schema.  For this application only a
+single table is needed and we only want to support SQLite so that is quite
+easy.  Just put the following contents into a file named `schema.sql` in
+the just created `flaskr` folder:
+
+.. sourcecode:: sql
+
+    drop table if exists entries;
+    create table entries (
+      id integer primary key autoincrement,
+      title string not null,
+      text string not null
+    );
+
+This schema consists of a single table called `entries` and each row in
+this table has an `id`, a `title` and a `text`.  The `id` is an
+automatically incrementing integer and a primary key, the other two are
+strings that must not be null.
+
+Continue with :ref:`tutorial-setup`.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/setup.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,83 @@
+.. _tutorial-setup:
+
+Step 2: Application Setup Code
+==============================
+
+Now that we have the schema in place we can create the application module.
+Let's call it `flaskr.py` inside the `flaskr` folder.  For starters we
+will add the imports we will need as well as the config section.  For
+small applications it's a possibility to drop the configuration directly
+into the module which we will be doing here.  However a cleaner solution
+would be to create a separate `.ini` or `.py` file and load that or import
+the values from there.
+
+::
+
+    # all the imports
+    import sqlite3
+    from flask import Flask, request, session, g, redirect, url_for, \
+         abort, render_template, flash
+
+    # configuration
+    DATABASE = '/tmp/flaskr.db'
+    DEBUG = True
+    SECRET_KEY = 'development key'
+    USERNAME = 'admin'
+    PASSWORD = 'default'
+
+Next we can create our actual application and initialize it with the
+config from the same file::
+
+    # create our little application :)
+    app = Flask(__name__)
+    app.config.from_object(__name__)
+
+:meth:`~flask.Config.from_object` will look at the given object (if it's a
+string it will import it) and then look for all uppercase variables
+defined there.  In our case, the configuration we just wrote a few lines
+of code above.  You can also move that into a separate file.
+
+It is also a good idea to be able to load a configuration from a
+configurable file.  This is what :meth:`~flask.Config.from_envvar` can
+do::
+
+    app.config.from_envvar('FLASKR_SETTINGS', silent=True)
+
+That way someone can set an environment variable called
+:envvar:`FLASKR_SETTINGS` to specify a config file to be loaded which will
+then override the default values.  The silent switch just tells Flask to
+not complain if no such environment key is set.
+
+The `secret_key` is needed to keep the client-side sessions secure.
+Choose that key wisely and as hard to guess and complex as possible.  The
+debug flag enables or disables the interactive debugger.  Never leave
+debug mode activated in a production system because it will allow users to
+execute code on the server!
+
+We also add a method to easily connect to the database specified.  That
+can be used to open a connection on request and also from the interactive
+Python shell or a script.  This will come in handy later.
+
+::
+
+    def connect_db():
+        return sqlite3.connect(app.config['DATABASE'])
+
+Finally we just add a line to the bottom of the file that fires up the
+server if we want to run that file as a standalone application::
+
+    if __name__ == '__main__':
+        app.run()
+
+With that out of the way you should be able to start up the application
+without problems.  When you head over to the server you will get an 404
+page not found error because we don't have any views yet.  But we will
+focus on that a little later.  First we should get the database working.
+
+.. admonition:: Externally Visible Server
+
+   Want your server to be publicly available?  Check out the
+   :ref:`externally visible server <public-server>` section for more
+   information.
+
+Continue with :ref:`tutorial-dbinit`.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/templates.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,111 @@
+.. _tutorial-templates:
+
+Step 6: The Templates
+=====================
+
+Now we should start working on the templates.  If we request the URLs now
+we would only get an exception that Flask cannot find the templates.  The
+templates are using `Jinja2`_ syntax and have autoescaping enabled by
+default.  This means that unless you mark a value in the code with
+:class:`~flask.Markup` or with the ``|safe`` filter in the template,
+Jinja2 will ensure that special characters such as ``<`` or ``>`` are
+escaped with their XML equivalents.
+
+We are also using template inheritance which makes it possible to reuse
+the layout of the website in all pages.
+
+Put the following templates into the `templates` folder:
+
+.. _Jinja2: http://jinja.pocoo.org/2/documentation/templates
+
+layout.html
+-----------
+
+This template contains the HTML skeleton, the header and a link to log in
+(or log out if the user was already logged in).  It also displays the
+flashed messages if there are any.  The ``{% block body %}`` block can be
+replaced by a block of the same name (``body``) in a child template.
+
+The :class:`~flask.session` dict is available in the template as well and
+you can use that to check if the user is logged in or not.  Note that in
+Jinja you can access missing attributes and items of objects / dicts which
+makes the following code work, even if there is no ``'logged_in'`` key in
+the session:
+
+.. sourcecode:: html+jinja
+
+    <!doctype html>
+    <title>Flaskr</title>
+    <link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
+    <div class=page>
+      <h1>Flaskr</h1>
+      <div class=metanav>
+      {% if not session.logged_in %}
+        <a href="{{ url_for('login') }}">log in</a>
+      {% else %}
+        <a href="{{ url_for('logout') }}">log out</a>
+      {% endif %}
+      </div>
+      {% for message in get_flashed_messages() %}
+        <div class=flash>{{ message }}</div>
+      {% endfor %}
+      {% block body %}{% endblock %}
+    </div>
+
+show_entries.html
+-----------------
+
+This template extends the `layout.html` template from above to display the
+messages.  Note that the `for` loop iterates over the messages we passed
+in with the :func:`~flask.render_template` function.  We also tell the
+form to submit to your `add_entry` function and use `POST` as `HTTP`
+method:
+
+.. sourcecode:: html+jinja
+
+    {% extends "layout.html" %}
+    {% block body %}
+      {% if session.logged_in %}
+        <form action="{{ url_for('add_entry') }}" method=post class=add-entry>
+          <dl>
+            <dt>Title:
+            <dd><input type=text size=30 name=title>
+            <dt>Text:
+            <dd><textarea name=text rows=5 cols=40></textarea>
+            <dd><input type=submit value=Share>
+          </dl>
+        </form>
+      {% endif %}
+      <ul class=entries>
+      {% for entry in entries %}
+        <li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}
+      {% else %}
+        <li><em>Unbelievable.  No entries here so far</em>
+      {% endfor %}
+      </ul>
+    {% endblock %}
+
+login.html
+----------
+
+Finally the login template which basically just displays a form to allow
+the user to login:
+
+.. sourcecode:: html+jinja
+
+    {% extends "layout.html" %}
+    {% block body %}
+      <h2>Login</h2>
+      {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
+      <form action="{{ url_for('login') }}" method=post>
+        <dl>
+          <dt>Username:
+          <dd><input type=text name=username>
+          <dt>Password:
+          <dd><input type=password name=password>
+          <dd><input type=submit value=Login>
+        </dl>
+      </form>
+    {% endblock %}
+
+Continue with :ref:`tutorial-css`.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/testing.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,10 @@
+.. _tutorial-testing:
+
+Bonus: Testing the Application
+==============================
+
+Now that you have finished the application and everything works as
+expected, it's probably not a bad idea to add automated tests to simplify
+modifications in the future.  The application above is used as a basic
+example of how to perform unittesting in the :ref:`testing` section of the
+documentation.  Go there to see how easy it is to test Flask applications.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/tutorial/views.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,98 @@
+.. _tutorial-views:
+
+Step 5: The View Functions
+==========================
+
+Now that the database connections are working we can start writing the
+view functions.  We will need four of them:
+
+Show Entries
+------------
+
+This view shows all the entries stored in the database.  It listens on the
+root of the application and will select title and text from the database.
+The one with the highest id (the newest entry) will be on top.  The rows
+returned from the cursor are tuples with the columns ordered like specified
+in the select statement.  This is good enough for small applications like
+here, but you might want to convert them into a dict.  If you are
+interested in how to do that, check out the :ref:`easy-querying` example.
+
+The view function will pass the entries as dicts to the
+`show_entries.html` template and return the rendered one::
+
+    @app.route('/')
+    def show_entries():
+        cur = g.db.execute('select title, text from entries order by id desc')
+        entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
+        return render_template('show_entries.html', entries=entries)
+
+Add New Entry
+-------------
+
+This view lets the user add new entries if he's logged in.  This only
+responds to `POST` requests, the actual form is shown on the
+`show_entries` page.  If everything worked out well we will
+:func:`~flask.flash` an information message to the next request and
+redirect back to the `show_entries` page::
+
+    @app.route('/add', methods=['POST'])
+    def add_entry():
+        if not session.get('logged_in'):
+            abort(401)
+        g.db.execute('insert into entries (title, text) values (?, ?)',
+                     [request.form['title'], request.form['text']])
+        g.db.commit()
+        flash('New entry was successfully posted')
+        return redirect(url_for('show_entries'))
+
+Note that we check that the user is logged in here (the `logged_in` key is
+present in the session and `True`).
+
+.. admonition:: Security Note
+
+   Be sure to use question marks when building SQL statements, as done in the
+   example above.  Otherwise, your app will be vulnerable to SQL injection when
+   you use string formatting to build SQL statements.
+   See :ref:`sqlite3` for more.
+
+Login and Logout
+----------------
+
+These functions are used to sign the user in and out.  Login checks the
+username and password against the ones from the configuration and sets the
+`logged_in` key in the session.  If the user logged in successfully, that
+key is set to `True`, and the user is redirected back to the `show_entries`
+page.  In addition, a message is flashed that informs the user that he or
+she was logged in successfully.  If an error occurred, the template is
+notified about that, and the user is asked again::
+
+    @app.route('/login', methods=['GET', 'POST'])
+    def login():
+        error = None
+        if request.method == 'POST':
+            if request.form['username'] != app.config['USERNAME']:
+                error = 'Invalid username'
+            elif request.form['password'] != app.config['PASSWORD']:
+                error = 'Invalid password'
+            else:
+                session['logged_in'] = True
+                flash('You were logged in')
+                return redirect(url_for('show_entries'))
+        return render_template('login.html', error=error)
+
+The logout function, on the other hand, removes that key from the session
+again.  We use a neat trick here: if you use the :meth:`~dict.pop` method
+of the dict and pass a second parameter to it (the default), the method
+will delete the key from the dictionary if present or do nothing when that
+key is not in there.  This is helpful because now we don't have to check
+if the user was logged in.
+
+::
+
+    @app.route('/logout')
+    def logout():
+        session.pop('logged_in', None)
+        flash('You were logged out')
+        return redirect(url_for('show_entries'))
+
+Continue with :ref:`tutorial-templates`.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/unicode.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,107 @@
+Unicode in Flask
+================
+
+Flask like Jinja2 and Werkzeug is totally Unicode based when it comes to
+text.  Not only these libraries, also the majority of web related Python
+libraries that deal with text.  If you don't know Unicode so far, you
+should probably read `The Absolute Minimum Every Software Developer
+Absolutely, Positively Must Know About Unicode and Character Sets
+<http://www.joelonsoftware.com/articles/Unicode.html>`_.  This part of the
+documentation just tries to cover the very basics so that you have a
+pleasant experience with Unicode related things.
+
+Automatic Conversion
+--------------------
+
+Flask has a few assumptions about your application (which you can change
+of course) that give you basic and painless Unicode support:
+
+-   the encoding for text on your website is UTF-8
+-   internally you will always use Unicode exclusively for text except
+    for literal strings with only ASCII character points.
+-   encoding and decoding happens whenever you are talking over a protocol
+    that requires bytes to be transmitted.
+
+So what does this mean to you?
+
+HTTP is based on bytes.  Not only the protocol, also the system used to
+address documents on servers (so called URIs or URLs).  However HTML which
+is usually transmitted on top of HTTP supports a large variety of
+character sets and which ones are used, are transmitted in an HTTP header.
+To not make this too complex Flask just assumes that if you are sending
+Unicode out you want it to be UTF-8 encoded.  Flask will do the encoding
+and setting of the appropriate headers for you.
+
+The same is true if you are talking to databases with the help of
+SQLAlchemy or a similar ORM system.  Some databases have a protocol that
+already transmits Unicode and if they do not, SQLAlchemy or your other ORM
+should take care of that.
+
+The Golden Rule
+---------------
+
+So the rule of thumb: if you are not dealing with binary data, work with
+Unicode.  What does working with Unicode in Python 2.x mean?
+
+-   as long as you are using ASCII charpoints only (basically numbers,
+    some special characters of latin letters without umlauts or anything
+    fancy) you can use regular string literals (``'Hello World'``).
+-   if you need anything else than ASCII in a string you have to mark
+    this string as Unicode string by prefixing it with a lowercase `u`.
+    (like ``u'Hänsel und Gretel'``)
+-   if you are using non-Unicode characters in your Python files you have
+    to tell Python which encoding your file uses.  Again, I recommend
+    UTF-8 for this purpose.  To tell the interpreter your encoding you can
+    put the ``# -*- coding: utf-8 -*-`` into the first or second line of
+    your Python source file.
+-   Jinja is configured to decode the template files from UTF-8.  So make
+    sure to tell your editor to save the file as UTF-8 there as well.
+
+Encoding and Decoding Yourself
+------------------------------
+
+If you are talking with a filesystem or something that is not really based
+on Unicode you will have to ensure that you decode properly when working
+with Unicode interface.  So for example if you want to load a file on the
+filesystem and embed it into a Jinja2 template you will have to decode it
+from the encoding of that file.  Here the old problem that text files do
+not specify their encoding comes into play.  So do yourself a favour and
+limit yourself to UTF-8 for text files as well.
+
+Anyways.  To load such a file with Unicode you can use the built-in
+:meth:`str.decode` method::
+
+    def read_file(filename, charset='utf-8'):
+        with open(filename, 'r') as f:
+            return f.read().decode(charset)
+
+To go from Unicode into a specific charset such as UTF-8 you can use the
+:meth:`unicode.encode` method::
+
+    def write_file(filename, contents, charset='utf-8'):
+        with open(filename, 'w') as f:
+            f.write(contents.encode(charset))
+
+Configuring Editors
+-------------------
+
+Most editors save as UTF-8 by default nowadays but in case your editor is
+not configured to do this you have to change it.  Here some common ways to
+set your editor to store as UTF-8:
+
+-   Vim: put ``set enc=utf-8`` to your ``.vimrc`` file.
+
+-   Emacs: either use an encoding cookie or put this into your ``.emacs``
+    file::
+
+        (prefer-coding-system 'utf-8)
+        (setq default-buffer-file-coding-system 'utf-8)
+
+-   Notepad++:
+
+    1. Go to *Settings -> Preferences ...*
+    2. Select the "New Document/Default Directory" tab
+    3. Select "UTF-8 without BOM" as encoding
+
+    It is also recommended to use the Unix newline format, you can select
+    it in the same panel but this is not a requirement.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/docs/upgrading.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,137 @@
+Upgrading to Newer Releases
+===========================
+
+Flask itself is changing like any software is changing over time.  Most of
+the changes are the nice kind, the kind where you don't have to change
+anything in your code to profit from a new release.
+
+However every once in a while there are changes that do require some
+changes in your code or there are changes that make it possible for you to
+improve your own code quality by taking advantage of new features in
+Flask.
+
+This section of the documentation enumerates all the changes in Flask from
+release to release and how you can change your code to have a painless
+updating experience.
+
+If you want to use the `easy_install` command to upgrade your Flask
+installation, make sure to pass it the ``-U`` parameter::
+
+    $ easy_install -U Flask
+
+Version 0.7
+-----------
+
+Due to a bug in earlier implementations the request local proxies now
+raise a :exc:`RuntimeError` instead of an :exc:`AttributeError` when they
+are unbound.  If you caught these exceptions with :exc:`AttributeError`
+before, you should catch them with :exc:`RuntimeError` now.
+
+Additionally the :func:`~flask.send_file` function is now issuing
+deprecation warnings if you depend on functionality that will be removed
+in Flask 1.0.  Previously it was possible to use etags and mimetypes
+when file objects were passed.  This was unreliable and caused issues
+for a few setups.  If you get a deprecation warning, make sure to
+update your application to work with either filenames there or disable
+etag attaching and attach them yourself.
+
+Old code::
+
+    return send_file(my_file_object)
+    return send_file(my_file_object)
+
+New code::
+
+    return send_file(my_file_object, add_etags=False)
+
+Version 0.6
+-----------
+
+Flask 0.6 comes with a backwards incompatible change which affects the
+order of after-request handlers.  Previously they were called in the order
+of the registration, now they are called in reverse order.  This change
+was made so that Flask behaves more like people expected it to work and
+how other systems handle request pre- and postprocessing.  If you
+depend on the order of execution of post-request functions, be sure to
+change the order.
+
+Another change that breaks backwards compatibility is that context
+processors will no longer override values passed directly to the template
+rendering function.  If for example `request` is as variable passed
+directly to the template, the default context processor will not override
+it with the current request object.  This makes it easier to extend
+context processors later to inject additional variables without breaking
+existing template not expecting them.
+
+Version 0.5
+-----------
+
+Flask 0.5 is the first release that comes as a Python package instead of a
+single module.  There were a couple of internal refactoring so if you
+depend on undocumented internal details you probably have to adapt the
+imports.
+
+The following changes may be relevant to your application:
+
+-   autoescaping no longer happens for all templates.  Instead it is
+    configured to only happen on files ending with ``.html``, ``.htm``,
+    ``.xml`` and ``.xhtml``.  If you have templates with different
+    extensions you should override the
+    :meth:`~flask.Flask.select_jinja_autoescape` method.
+-   Flask no longer supports zipped applications in this release.  This
+    functionality might come back in future releases if there is demand
+    for this feature.  Removing support for this makes the Flask internal
+    code easier to understand and fixes a couple of small issues that make
+    debugging harder than necessary.
+-   The `create_jinja_loader` function is gone.  If you want to customize
+    the Jinja loader now, use the
+    :meth:`~flask.Flask.create_jinja_environment` method instead.
+
+Version 0.4
+-----------
+
+For application developers there are no changes that require changes in
+your code.  In case you are developing on a Flask extension however, and
+that extension has a unittest-mode you might want to link the activation
+of that mode to the new ``TESTING`` flag.
+
+Version 0.3
+-----------
+
+Flask 0.3 introduces configuration support and logging as well as
+categories for flashing messages.  All these are features that are 100%
+backwards compatible but you might want to take advantage of them.
+
+Configuration Support
+`````````````````````
+
+The configuration support makes it easier to write any kind of application
+that requires some sort of configuration.  (Which most likely is the case
+for any application out there).
+
+If you previously had code like this::
+
+    app.debug = DEBUG
+    app.secret_key = SECRET_KEY
+
+You no longer have to do that, instead you can just load a configuration
+into the config object.  How this works is outlined in :ref:`config`.
+
+Logging Integration
+```````````````````
+
+Flask now configures a logger for you with some basic and useful defaults.
+If you run your application in production and want to profit from
+automatic error logging, you might be interested in attaching a proper log
+handler.  Also you can start logging warnings and errors into the logger
+when appropriately.  For more information on that, read
+:ref:`application-errors`.
+
+Categories for Flash Messages
+`````````````````````````````
+
+Flash messages can now have categories attached.  This makes it possible
+to render errors, warnings or regular messages differently for example.
+This is an opt-in feature because it requires some rethinking in the code.
+
+Read all about that in the :ref:`message-flashing-pattern` pattern.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/flaskr/README	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,28 @@
+
+                         / Flaskr /
+
+                 a minimal blog application
+
+
+    ~ What is Flaskr?
+
+      A sqlite powered thumble blog application
+
+    ~ How do I use it?
+
+      1. edit the configuration in the flaskr.py file or
+         export an FLASKR_SETTINGS environment variable
+         pointing to a configuration file.
+
+      2. fire up a python shell and run this:
+
+         >>> from flaskr import init_db; init_db()
+
+      3. now you can run the flaskr.py file with your
+         python interpreter and the application will
+         greet you on http://localhost:5000/
+	
+    ~ Is it tested?
+
+      You betcha.  Run the `flaskr_tests.py` file to see
+      the tests pass.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/flaskr/flaskr.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+"""
+    Flaskr
+    ~~~~~~
+
+    A microblog example application written as Flask tutorial with
+    Flask and sqlite3.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+from __future__ import with_statement
+from sqlite3 import dbapi2 as sqlite3
+from contextlib import closing
+from flask import Flask, request, session, g, redirect, url_for, abort, \
+     render_template, flash
+
+# configuration
+DATABASE = '/tmp/flaskr.db'
+DEBUG = True
+SECRET_KEY = 'development key'
+USERNAME = 'admin'
+PASSWORD = 'default'
+
+# create our little application :)
+app = Flask(__name__)
+app.config.from_object(__name__)
+app.config.from_envvar('FLASKR_SETTINGS', silent=True)
+
+
+def connect_db():
+    """Returns a new connection to the database."""
+    return sqlite3.connect(app.config['DATABASE'])
+
+
+def init_db():
+    """Creates the database tables."""
+    with closing(connect_db()) as db:
+        with app.open_resource('schema.sql') as f:
+            db.cursor().executescript(f.read())
+        db.commit()
+
+
+@app.before_request
+def before_request():
+    """Make sure we are connected to the database each request."""
+    g.db = connect_db()
+
+
+@app.after_request
+def after_request(response):
+    """Closes the database again at the end of the request."""
+    g.db.close()
+    return response
+
+
+@app.route('/')
+def show_entries():
+    cur = g.db.execute('select title, text from entries order by id desc')
+    entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
+    return render_template('show_entries.html', entries=entries)
+
+
+@app.route('/add', methods=['POST'])
+def add_entry():
+    if not session.get('logged_in'):
+        abort(401)
+    g.db.execute('insert into entries (title, text) values (?, ?)',
+                 [request.form['title'], request.form['text']])
+    g.db.commit()
+    flash('New entry was successfully posted')
+    return redirect(url_for('show_entries'))
+
+
+@app.route('/login', methods=['GET', 'POST'])
+def login():
+    error = None
+    if request.method == 'POST':
+        if request.form['username'] != app.config['USERNAME']:
+            error = 'Invalid username'
+        elif request.form['password'] != app.config['PASSWORD']:
+            error = 'Invalid password'
+        else:
+            session['logged_in'] = True
+            flash('You were logged in')
+            return redirect(url_for('show_entries'))
+    return render_template('login.html', error=error)
+
+
+@app.route('/logout')
+def logout():
+    session.pop('logged_in', None)
+    flash('You were logged out')
+    return redirect(url_for('show_entries'))
+
+
+if __name__ == '__main__':
+    app.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/flaskr/flaskr_tests.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+"""
+    Flaskr Tests
+    ~~~~~~~~~~~~
+
+    Tests the Flaskr application.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+import os
+import flaskr
+import unittest
+import tempfile
+
+
+class FlaskrTestCase(unittest.TestCase):
+
+    def setUp(self):
+        """Before each test, set up a blank database"""
+        self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
+        self.app = flaskr.app.test_client()
+        flaskr.init_db()
+
+    def tearDown(self):
+        """Get rid of the database again after each test."""
+        os.close(self.db_fd)
+        os.unlink(flaskr.app.config['DATABASE'])
+
+    def login(self, username, password):
+        return self.app.post('/login', data=dict(
+            username=username,
+            password=password
+        ), follow_redirects=True)
+
+    def logout(self):
+        return self.app.get('/logout', follow_redirects=True)
+
+    # testing functions
+
+    def test_empty_db(self):
+        """Start with a blank database."""
+        rv = self.app.get('/')
+        assert 'No entries here so far' in rv.data
+
+    def test_login_logout(self):
+        """Make sure login and logout works"""
+        rv = self.login(flaskr.app.config['USERNAME'],
+                        flaskr.app.config['PASSWORD'])
+        assert 'You were logged in' in rv.data
+        rv = self.logout()
+        assert 'You were logged out' in rv.data
+        rv = self.login(flaskr.app.config['USERNAME'] + 'x',
+                        flaskr.app.config['PASSWORD'])
+        assert 'Invalid username' in rv.data
+        rv = self.login(flaskr.app.config['USERNAME'],
+                        flaskr.app.config['PASSWORD'] + 'x')
+        assert 'Invalid password' in rv.data
+
+    def test_messages(self):
+        """Test that messages work"""
+        self.login(flaskr.app.config['USERNAME'],
+                   flaskr.app.config['PASSWORD'])
+        rv = self.app.post('/add', data=dict(
+            title='<Hello>',
+            text='<strong>HTML</strong> allowed here'
+        ), follow_redirects=True)
+        assert 'No entries here so far' not in rv.data
+        assert '&lt;Hello&gt;' in rv.data
+        assert '<strong>HTML</strong> allowed here' in rv.data
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/flaskr/schema.sql	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,6 @@
+drop table if exists entries;
+create table entries (
+  id integer primary key autoincrement,
+  title string not null,
+  text string not null
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/flaskr/static/style.css	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,18 @@
+body            { font-family: sans-serif; background: #eee; }
+a, h1, h2       { color: #377BA8; }
+h1, h2          { font-family: 'Georgia', serif; margin: 0; }
+h1              { border-bottom: 2px solid #eee; }
+h2              { font-size: 1.2em; }
+
+.page           { margin: 2em auto; width: 35em; border: 5px solid #ccc;
+                  padding: 0.8em; background: white; }
+.entries        { list-style: none; margin: 0; padding: 0; }
+.entries li     { margin: 0.8em 1.2em; }
+.entries li h2  { margin-left: -1em; }
+.add-entry      { font-size: 0.9em; border-bottom: 1px solid #ccc; }
+.add-entry dl   { font-weight: bold; }
+.metanav        { text-align: right; font-size: 0.8em; padding: 0.3em;
+                  margin-bottom: 1em; background: #fafafa; }
+.flash          { background: #CEE5F5; padding: 0.5em;
+                  border: 1px solid #AACBE2; }
+.error          { background: #F0D6D6; padding: 0.5em; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/flaskr/templates/layout.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>Flaskr</title>
+<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
+<div class=page>
+  <h1>Flaskr</h1>
+  <div class=metanav>
+  {% if not session.logged_in %}
+    <a href="{{ url_for('login') }}">log in</a>
+  {% else %}
+    <a href="{{ url_for('logout') }}">log out</a>
+  {% endif %}
+  </div>
+  {% for message in get_flashed_messages() %}
+    <div class=flash>{{ message }}</div>
+  {% endfor %}
+  {% block body %}{% endblock %}
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/flaskr/templates/login.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,14 @@
+{% extends "layout.html" %}
+{% block body %}
+  <h2>Login</h2>
+  {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
+  <form action="{{ url_for('login') }}" method=post>
+    <dl>
+      <dt>Username:
+      <dd><input type=text name=username>
+      <dt>Password:
+      <dd><input type=password name=password>
+      <dd><input type=submit value=Login>
+    </dl>
+  </form>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/flaskr/templates/show_entries.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,21 @@
+{% extends "layout.html" %}
+{% block body %}
+  {% if session.logged_in %}
+    <form action="{{ url_for('add_entry') }}" method=post class=add-entry>
+      <dl>
+        <dt>Title:
+        <dd><input type=text size=30 name=title>
+        <dt>Text:
+        <dd><textarea name=text rows=5 cols=40></textarea>
+        <dd><input type=submit value=Share>
+      </dl>
+    </form>
+  {% endif %}
+  <ul class=entries>
+  {% for entry in entries %}
+    <li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}
+  {% else %}
+    <li><em>Unbelievable.  No entries here so far</em>
+  {% endfor %}
+  </ul>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/jqueryexample/jqueryexample.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+"""
+    jQuery Example
+    ~~~~~~~~~~~~~~
+
+    A simple application that shows how Flask and jQuery get along.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+from flask import Flask, jsonify, render_template, request
+app = Flask(__name__)
+
+
+@app.route('/_add_numbers')
+def add_numbers():
+    """Add two numbers server side, ridiculous but well..."""
+    a = request.args.get('a', 0, type=int)
+    b = request.args.get('b', 0, type=int)
+    return jsonify(result=a + b)
+
+
+@app.route('/')
+def index():
+    return render_template('index.html')
+
+
+if __name__ == '__main__':
+    app.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/jqueryexample/templates/index.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,21 @@
+{% extends "layout.html" %}
+{% block body %}
+<script type=text/javascript>
+  $(function() {
+    $('a#calculate').bind('click', function() {
+      $.getJSON($SCRIPT_ROOT + '/_add_numbers', {
+        a: $('input[name="a"]').val(),
+        b: $('input[name="b"]').val()
+      }, function(data) {
+        $("#result").text(data.result);
+      });
+      return false;
+    });
+  });
+</script>
+<h1>jQuery Example</h1>
+<p><input type=text size=5 name=a> +
+   <input type=text size=5 name=b> =
+   <span id=result>?</span>
+<p><a href=# id=calculate>calculate server side</a>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/jqueryexample/templates/layout.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,8 @@
+<!doctype html>
+<title>jQuery Example</title>
+<script type=text/javascript
+  src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
+<script type=text/javascript>
+  var $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
+</script>
+{% block body %}{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/minitwit/README	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,28 @@
+
+                        / MiniTwit /
+
+           because writing todo lists is not fun
+
+
+    ~ What is MiniTwit?
+
+      A SQLite and Flask powered twitter clone
+
+    ~ How do I use it?
+
+      1. edit the configuration in the minitwit.py file or
+         export an MINITWIT_SETTINGS environment variable
+         pointing to a configuration file.
+
+      2. fire up a python shell and run this:
+
+         >>> from minitwit import init_db; init_db()
+
+      3. now you can run the minitwit.py file with your
+         python interpreter and the application will
+         greet you on http://localhost:5000/
+	
+    ~ Is it tested?
+
+      You betcha.  Run the `minitwit_tests.py` file to
+      see the tests pass.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/minitwit/minitwit.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,248 @@
+# -*- coding: utf-8 -*-
+"""
+    MiniTwit
+    ~~~~~~~~
+
+    A microblogging application written with Flask and sqlite3.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+from __future__ import with_statement
+import time
+from sqlite3 import dbapi2 as sqlite3
+from hashlib import md5
+from datetime import datetime
+from contextlib import closing
+from flask import Flask, request, session, url_for, redirect, \
+     render_template, abort, g, flash
+from werkzeug import check_password_hash, generate_password_hash
+
+
+# configuration
+DATABASE = '/tmp/minitwit.db'
+PER_PAGE = 30
+DEBUG = True
+SECRET_KEY = 'development key'
+
+# create our little application :)
+app = Flask(__name__)
+app.config.from_object(__name__)
+app.config.from_envvar('MINITWIT_SETTINGS', silent=True)
+
+
+def connect_db():
+    """Returns a new connection to the database."""
+    return sqlite3.connect(app.config['DATABASE'])
+
+
+def init_db():
+    """Creates the database tables."""
+    with closing(connect_db()) as db:
+        with app.open_resource('schema.sql') as f:
+            db.cursor().executescript(f.read())
+        db.commit()
+
+
+def query_db(query, args=(), one=False):
+    """Queries the database and returns a list of dictionaries."""
+    cur = g.db.execute(query, args)
+    rv = [dict((cur.description[idx][0], value)
+               for idx, value in enumerate(row)) for row in cur.fetchall()]
+    return (rv[0] if rv else None) if one else rv
+
+
+def get_user_id(username):
+    """Convenience method to look up the id for a username."""
+    rv = g.db.execute('select user_id from user where username = ?',
+                       [username]).fetchone()
+    return rv[0] if rv else None
+
+
+def format_datetime(timestamp):
+    """Format a timestamp for display."""
+    return datetime.utcfromtimestamp(timestamp).strftime('%Y-%m-%d @ %H:%M')
+
+
+def gravatar_url(email, size=80):
+    """Return the gravatar image for the given email address."""
+    return 'http://www.gravatar.com/avatar/%s?d=identicon&s=%d' % \
+        (md5(email.strip().lower().encode('utf-8')).hexdigest(), size)
+
+
+@app.before_request
+def before_request():
+    """Make sure we are connected to the database each request and look
+    up the current user so that we know he's there.
+    """
+    g.db = connect_db()
+    g.user = None
+    if 'user_id' in session:
+        g.user = query_db('select * from user where user_id = ?',
+                          [session['user_id']], one=True)
+
+
+@app.after_request
+def after_request(response):
+    """Closes the database again at the end of the request."""
+    g.db.close()
+    return response
+
+
+@app.route('/')
+def timeline():
+    """Shows a users timeline or if no user is logged in it will
+    redirect to the public timeline.  This timeline shows the user's
+    messages as well as all the messages of followed users.
+    """
+    if not g.user:
+        return redirect(url_for('public_timeline'))
+    return render_template('timeline.html', messages=query_db('''
+        select message.*, user.* from message, user
+        where message.author_id = user.user_id and (
+            user.user_id = ? or
+            user.user_id in (select whom_id from follower
+                                    where who_id = ?))
+        order by message.pub_date desc limit ?''',
+        [session['user_id'], session['user_id'], PER_PAGE]))
+
+
+@app.route('/public')
+def public_timeline():
+    """Displays the latest messages of all users."""
+    return render_template('timeline.html', messages=query_db('''
+        select message.*, user.* from message, user
+        where message.author_id = user.user_id
+        order by message.pub_date desc limit ?''', [PER_PAGE]))
+
+
+@app.route('/<username>')
+def user_timeline(username):
+    """Display's a users tweets."""
+    profile_user = query_db('select * from user where username = ?',
+                            [username], one=True)
+    if profile_user is None:
+        abort(404)
+    followed = False
+    if g.user:
+        followed = query_db('''select 1 from follower where
+            follower.who_id = ? and follower.whom_id = ?''',
+            [session['user_id'], profile_user['user_id']],
+            one=True) is not None
+    return render_template('timeline.html', messages=query_db('''
+            select message.*, user.* from message, user where
+            user.user_id = message.author_id and user.user_id = ?
+            order by message.pub_date desc limit ?''',
+            [profile_user['user_id'], PER_PAGE]), followed=followed,
+            profile_user=profile_user)
+
+
+@app.route('/<username>/follow')
+def follow_user(username):
+    """Adds the current user as follower of the given user."""
+    if not g.user:
+        abort(401)
+    whom_id = get_user_id(username)
+    if whom_id is None:
+        abort(404)
+    g.db.execute('insert into follower (who_id, whom_id) values (?, ?)',
+                [session['user_id'], whom_id])
+    g.db.commit()
+    flash('You are now following "%s"' % username)
+    return redirect(url_for('user_timeline', username=username))
+
+
+@app.route('/<username>/unfollow')
+def unfollow_user(username):
+    """Removes the current user as follower of the given user."""
+    if not g.user:
+        abort(401)
+    whom_id = get_user_id(username)
+    if whom_id is None:
+        abort(404)
+    g.db.execute('delete from follower where who_id=? and whom_id=?',
+                [session['user_id'], whom_id])
+    g.db.commit()
+    flash('You are no longer following "%s"' % username)
+    return redirect(url_for('user_timeline', username=username))
+
+
+@app.route('/add_message', methods=['POST'])
+def add_message():
+    """Registers a new message for the user."""
+    if 'user_id' not in session:
+        abort(401)
+    if request.form['text']:
+        g.db.execute('''insert into message (author_id, text, pub_date)
+            values (?, ?, ?)''', (session['user_id'], request.form['text'],
+                                  int(time.time())))
+        g.db.commit()
+        flash('Your message was recorded')
+    return redirect(url_for('timeline'))
+
+
+@app.route('/login', methods=['GET', 'POST'])
+def login():
+    """Logs the user in."""
+    if g.user:
+        return redirect(url_for('timeline'))
+    error = None
+    if request.method == 'POST':
+        user = query_db('''select * from user where
+            username = ?''', [request.form['username']], one=True)
+        if user is None:
+            error = 'Invalid username'
+        elif not check_password_hash(user['pw_hash'],
+                                     request.form['password']):
+            error = 'Invalid password'
+        else:
+            flash('You were logged in')
+            session['user_id'] = user['user_id']
+            return redirect(url_for('timeline'))
+    return render_template('login.html', error=error)
+
+
+@app.route('/register', methods=['GET', 'POST'])
+def register():
+    """Registers the user."""
+    if g.user:
+        return redirect(url_for('timeline'))
+    error = None
+    if request.method == 'POST':
+        if not request.form['username']:
+            error = 'You have to enter a username'
+        elif not request.form['email'] or \
+                 '@' not in request.form['email']:
+            error = 'You have to enter a valid email address'
+        elif not request.form['password']:
+            error = 'You have to enter a password'
+        elif request.form['password'] != request.form['password2']:
+            error = 'The two passwords do not match'
+        elif get_user_id(request.form['username']) is not None:
+            error = 'The username is already taken'
+        else:
+            g.db.execute('''insert into user (
+                username, email, pw_hash) values (?, ?, ?)''',
+                [request.form['username'], request.form['email'],
+                 generate_password_hash(request.form['password'])])
+            g.db.commit()
+            flash('You were successfully registered and can login now')
+            return redirect(url_for('login'))
+    return render_template('register.html', error=error)
+
+
+@app.route('/logout')
+def logout():
+    """Logs the user out."""
+    flash('You were logged out')
+    session.pop('user_id', None)
+    return redirect(url_for('public_timeline'))
+
+
+# add some filters to jinja
+app.jinja_env.filters['datetimeformat'] = format_datetime
+app.jinja_env.filters['gravatar'] = gravatar_url
+
+
+if __name__ == '__main__':
+    app.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/minitwit/minitwit_tests.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,149 @@
+# -*- coding: utf-8 -*-
+"""
+    MiniTwit Tests
+    ~~~~~~~~~~~~~~
+
+    Tests the MiniTwit application.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+import os
+import minitwit
+import unittest
+import tempfile
+
+
+class MiniTwitTestCase(unittest.TestCase):
+
+    def setUp(self):
+        """Before each test, set up a blank database"""
+        self.db_fd, minitwit.app.config['DATABASE'] = tempfile.mkstemp()
+        self.app = minitwit.app.test_client()
+        minitwit.init_db()
+
+    def tearDown(self):
+        """Get rid of the database again after each test."""
+        os.close(self.db_fd)
+        os.unlink(minitwit.app.config['DATABASE'])
+
+    # helper functions
+
+    def register(self, username, password, password2=None, email=None):
+        """Helper function to register a user"""
+        if password2 is None:
+            password2 = password
+        if email is None:
+            email = username + '@example.com'
+        return self.app.post('/register', data={
+            'username':     username,
+            'password':     password,
+            'password2':    password2,
+            'email':        email,
+        }, follow_redirects=True)
+
+    def login(self, username, password):
+        """Helper function to login"""
+        return self.app.post('/login', data={
+            'username': username,
+            'password': password
+        }, follow_redirects=True)
+
+    def register_and_login(self, username, password):
+        """Registers and logs in in one go"""
+        self.register(username, password)
+        return self.login(username, password)
+
+    def logout(self):
+        """Helper function to logout"""
+        return self.app.get('/logout', follow_redirects=True)
+
+    def add_message(self, text):
+        """Records a message"""
+        rv = self.app.post('/add_message', data={'text': text},
+                                    follow_redirects=True)
+        if text:
+            assert 'Your message was recorded' in rv.data
+        return rv
+
+    # testing functions
+
+    def test_register(self):
+        """Make sure registering works"""
+        rv = self.register('user1', 'default')
+        assert 'You were successfully registered ' \
+               'and can login now' in rv.data
+        rv = self.register('user1', 'default')
+        assert 'The username is already taken' in rv.data
+        rv = self.register('', 'default')
+        assert 'You have to enter a username' in rv.data
+        rv = self.register('meh', '')
+        assert 'You have to enter a password' in rv.data
+        rv = self.register('meh', 'x', 'y')
+        assert 'The two passwords do not match' in rv.data
+        rv = self.register('meh', 'foo', email='broken')
+        assert 'You have to enter a valid email address' in rv.data
+
+    def test_login_logout(self):
+        """Make sure logging in and logging out works"""
+        rv = self.register_and_login('user1', 'default')
+        assert 'You were logged in' in rv.data
+        rv = self.logout()
+        assert 'You were logged out' in rv.data
+        rv = self.login('user1', 'wrongpassword')
+        assert 'Invalid password' in rv.data
+        rv = self.login('user2', 'wrongpassword')
+        assert 'Invalid username' in rv.data
+
+    def test_message_recording(self):
+        """Check if adding messages works"""
+        self.register_and_login('foo', 'default')
+        self.add_message('test message 1')
+        self.add_message('<test message 2>')
+        rv = self.app.get('/')
+        assert 'test message 1' in rv.data
+        assert '&lt;test message 2&gt;' in rv.data
+
+    def test_timelines(self):
+        """Make sure that timelines work"""
+        self.register_and_login('foo', 'default')
+        self.add_message('the message by foo')
+        self.logout()
+        self.register_and_login('bar', 'default')
+        self.add_message('the message by bar')
+        rv = self.app.get('/public')
+        assert 'the message by foo' in rv.data
+        assert 'the message by bar' in rv.data
+
+        # bar's timeline should just show bar's message
+        rv = self.app.get('/')
+        assert 'the message by foo' not in rv.data
+        assert 'the message by bar' in rv.data
+
+        # now let's follow foo
+        rv = self.app.get('/foo/follow', follow_redirects=True)
+        assert 'You are now following &#34;foo&#34;' in rv.data
+
+        # we should now see foo's message
+        rv = self.app.get('/')
+        assert 'the message by foo' in rv.data
+        assert 'the message by bar' in rv.data
+
+        # but on the user's page we only want the user's message
+        rv = self.app.get('/bar')
+        assert 'the message by foo' not in rv.data
+        assert 'the message by bar' in rv.data
+        rv = self.app.get('/foo')
+        assert 'the message by foo' in rv.data
+        assert 'the message by bar' not in rv.data
+
+        # now unfollow and check if that worked
+        rv = self.app.get('/foo/unfollow', follow_redirects=True)
+        assert 'You are no longer following &#34;foo&#34;' in rv.data
+        rv = self.app.get('/')
+        assert 'the message by foo' not in rv.data
+        assert 'the message by bar' in rv.data
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/minitwit/schema.sql	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,21 @@
+drop table if exists user;
+create table user (
+  user_id integer primary key autoincrement,
+  username string not null,
+  email string not null,
+  pw_hash string not null
+);
+
+drop table if exists follower;
+create table follower (
+  who_id integer,
+  whom_id integer
+);
+
+drop table if exists message;
+create table message (
+  message_id integer primary key autoincrement,
+  author_id integer not null,
+  text string not null,
+  pub_date integer
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/minitwit/static/style.css	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,178 @@
+body {
+    background: #CAECE9;
+    font-family: 'Trebuchet MS', sans-serif;
+    font-size: 14px;
+}
+
+a {
+    color: #26776F;
+}
+
+a:hover {
+    color: #333;
+}
+
+input[type="text"],
+input[type="password"] {
+    background: white;
+    border: 1px solid #BFE6E2;
+    padding: 2px;
+    font-family: 'Trebuchet MS', sans-serif;
+    font-size: 14px;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    color: #105751;
+}
+
+input[type="submit"] {
+    background: #105751;
+    border: 1px solid #073B36;
+    padding: 1px 3px;
+    font-family: 'Trebuchet MS', sans-serif;
+    font-size: 14px;
+    font-weight: bold;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    color: white;
+}
+
+div.page {
+    background: white;
+    border: 1px solid #6ECCC4;
+    width: 700px;
+    margin: 30px auto;
+}
+
+div.page h1 {
+    background: #6ECCC4;
+    margin: 0;
+    padding: 10px 14px;
+    color: white;
+    letter-spacing: 1px;
+    text-shadow: 0 0 3px #24776F;
+    font-weight: normal;
+}
+
+div.page div.navigation {
+    background: #DEE9E8;
+    padding: 4px 10px;
+    border-top: 1px solid #ccc;
+    border-bottom: 1px solid #eee;
+    color: #888;
+    font-size: 12px;
+    letter-spacing: 0.5px;
+}
+
+div.page div.navigation a {
+    color: #444;
+    font-weight: bold;
+}
+
+div.page h2 {
+    margin: 0 0 15px 0;
+    color: #105751;
+    text-shadow: 0 1px 2px #ccc;
+}
+
+div.page div.body {
+    padding: 10px;
+}
+
+div.page div.footer {
+    background: #eee;
+    color: #888;
+    padding: 5px 10px;
+    font-size: 12px;
+}
+
+div.page div.followstatus {
+    border: 1px solid #ccc;
+    background: #E3EBEA;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    padding: 3px;
+    font-size: 13px;
+}
+
+div.page ul.messages {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+
+div.page ul.messages li {
+    margin: 10px 0;
+    padding: 5px;
+    background: #F0FAF9;
+    border: 1px solid #DBF3F1;
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    min-height: 48px;
+}
+
+div.page ul.messages p {
+    margin: 0;
+}
+
+div.page ul.messages li img {
+    float: left;
+    padding: 0 10px 0 0;
+}
+
+div.page ul.messages li small {
+    font-size: 0.9em;
+    color: #888;
+}
+
+div.page div.twitbox {
+    margin: 10px 0;
+    padding: 5px;
+    background: #F0FAF9;
+    border: 1px solid #94E2DA;
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+}
+
+div.page div.twitbox h3 {
+    margin: 0;
+    font-size: 1em;
+    color: #2C7E76;
+}
+
+div.page div.twitbox p {
+    margin: 0;
+}
+
+div.page div.twitbox input[type="text"] {
+    width: 585px;
+}
+
+div.page div.twitbox input[type="submit"] {
+    width: 70px;
+    margin-left: 5px;
+}
+
+ul.flashes {
+    list-style: none;
+    margin: 10px 10px 0 10px;
+    padding: 0;
+}
+
+ul.flashes li {
+    background: #B9F3ED;
+    border: 1px solid #81CEC6;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    padding: 4px;
+    font-size: 13px;
+}
+
+div.error {
+    margin: 10px 0;
+    background: #FAE4E4;
+    border: 1px solid #DD6F6F;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    padding: 4px;
+    font-size: 13px;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/minitwit/templates/layout.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,32 @@
+<!doctype html>
+<title>{% block title %}Welcome{% endblock %} | MiniTwit</title>
+<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
+<div class=page>
+  <h1>MiniTwit</h1>
+  <div class=navigation>
+  {% if g.user %}
+    <a href="{{ url_for('timeline') }}">my timeline</a> |
+    <a href="{{ url_for('public_timeline') }}">public timeline</a> |
+    <a href="{{ url_for('logout') }}">sign out [{{ g.user.username }}]</a>
+  {% else %}
+    <a href="{{ url_for('public_timeline') }}">public timeline</a> |
+    <a href="{{ url_for('register') }}">sign up</a> |
+    <a href="{{ url_for('login') }}">sign in</a>
+  {% endif %}
+  </div>
+  {% with flashes = get_flashed_messages() %}
+    {% if flashes %}
+      <ul class=flashes>
+      {% for message in flashes %}
+        <li>{{ message }}
+      {% endfor %}
+      </ul>
+    {% endif %}
+  {% endwith %}
+  <div class=body>
+  {% block body %}{% endblock %}
+  </div>
+  <div class=footer>
+    MiniTwit &mdash; A Flask Application
+  </div>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/minitwit/templates/login.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,16 @@
+{% extends "layout.html" %}
+{% block title %}Sign In{% endblock %}
+{% block body %}
+  <h2>Sign In</h2>
+  {% if error %}<div class=error><strong>Error:</strong> {{ error }}</div>{% endif %}
+  <form action="" method=post>
+    <dl>
+      <dt>Username:
+      <dd><input type=text name=username size=30 value="{{ request.form.username }}">
+      <dt>Password:
+      <dd><input type=password name=password size=30>
+    </dl>
+    <div class=actions><input type=submit value="Sign In"></div>
+  </form>
+{% endblock %}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/minitwit/templates/register.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,19 @@
+{% extends "layout.html" %}
+{% block title %}Sign Up{% endblock %}
+{% block body %}
+  <h2>Sign Up</h2>
+  {% if error %}<div class=error><strong>Error:</strong> {{ error }}</div>{% endif %}
+  <form action="" method=post>
+    <dl>
+      <dt>Username:
+      <dd><input type=text name=username size=30 value="{{ request.form.username }}">
+      <dt>E-Mail:
+      <dd><input type=text name=email size=30 value="{{ request.form.email }}">
+      <dt>Password:
+      <dd><input type=password name=password size=30>
+      <dt>Password <small>(repeat)</small>:
+      <dd><input type=password name=password2 size=30>
+    </dl>
+    <div class=actions><input type=submit value="Sign Up"></div>
+  </form>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/examples/minitwit/templates/timeline.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,49 @@
+{% extends "layout.html" %}
+{% block title %}
+  {% if request.endpoint == 'public_timeline' %}
+    Public Timeline
+  {% elif request.endpoint == 'user_timeline' %}
+    {{ profile_user.username }}'s Timeline
+  {% else %}
+    My Timeline
+  {% endif %}
+{% endblock %}
+{% block body %}
+  <h2>{{ self.title() }}</h2>
+  {% if g.user %}
+    {% if request.endpoint == 'user_timeline' %}
+      <div class=followstatus>
+      {% if g.user.user_id == profile_user.user_id %}
+        This is you!
+      {% elif followed %}
+        You are currently following this user.
+        <a class=unfollow href="{{ url_for('unfollow_user', username=profile_user.username)
+          }}">Unfollow user</a>.
+      {% else %}
+        You are not yet following this user.
+        <a class=follow href="{{ url_for('follow_user', username=profile_user.username)
+          }}">Follow user</a>.
+      {% endif %}
+      </div>
+    {% elif request.endpoint == 'timeline' %}
+      <div class=twitbox>
+        <h3>What's on your mind {{ g.user.username }}?</h3>
+        <form action="{{ url_for('add_message') }}" method=post>
+          <p><input type=text name=text size=60><!--
+          --><input type=submit value="Share">
+        </form>
+      </div>
+    {% endif %}
+  {% endif %}
+  <ul class=messages>
+  {% for message in messages %}
+    <li><img src="{{ message.email|gravatar(size=48) }}"><p>
+      <strong><a href="{{ url_for('user_timeline', username=message.username)
+      }}">{{ message.username }}</a></strong>
+      {{ message.text }}
+      <small>&mdash; {{ message.pub_date|datetimeformat }}</small>
+  {% else %}
+    <li><em>There's no message so far.</em>
+  {% endfor %}
+  </ul>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/extreview/approved.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,146 @@
+Approved Extensions
+===================
+
+This document contains a list of all extensions that were approved and the
+date of approval as well as notes.  This should make it possible to better
+track the extension approval process.
+
+
+Flask-Babel
+-----------
+
+:First Approval: 2010-07-23
+:Last Review: 2010-07-23
+:Approved Version: 0.6
+:Approved License: BSD
+
+Notes: Developed by the Flask development head
+
+How to improve: add a better long description to the next release
+
+
+Flask-SQLAlchemy
+----------------
+
+:First Approval: 2010-07-25
+:Last Review: 2010-07-25
+:Approved Version: 0.9.1
+:Approved License: BSD
+
+Notes: Developed by the Flask development head
+
+How to improve: add a better long description to the next release
+
+
+Flask-Creole
+------------
+
+:First Approval: 2010-07-25
+:Last Review: 2010-07-25
+:Approved Version: 0.4.4
+:Approved License: BSD
+
+Notes: Flask-Markdown and this should share API, consider that when
+approving Flask-Markdown
+
+
+Flask-Genshi
+------------
+
+:First Approval: 2010-07-26
+:Last Review: 2010-07-26
+:Approved Version: 0.3.1
+:Approved License: BSD
+
+Notes: This is the first template engine extension.  When others come
+around it would be a good idea to decide on a common interface.
+
+
+Flask-Script
+------------
+
+:First Approval: 2010-07-26
+:Last Review: 2010-07-26
+:Approved Version: 0.3
+:Approved License: BSD
+
+Notes: Flask-Actions has some overlap.  Consider that when approving
+Flask-Actions or similar packages.
+
+
+Flask-CouchDB
+-------------
+
+:First Approval: 2010-07-26
+:Last Review: 2010-07-26
+:Approved Version: 0.2.1
+:Approved License: MIT
+
+There is also Flask-CouchDBKit.  Both are fine because they are doing
+different things, but the latter is not yet approved.
+
+
+Flask-Testing
+-------------
+
+:First Approval: 2010-07-27
+:Last Review: 2010-07-27
+:Approved Version: 0.2.3
+:Approved License: BSD
+
+All fine.
+
+
+Flask-WTF
+---------
+
+:First Approval: 2010-07-27
+:Last Review: 2010-07-27
+:Approved Version: 0.2.3
+:Approved License: BSD
+
+All fine.
+
+
+Flask-Themes
+------------
+
+:First Approval: 2010-07-27
+:Last Review: 2010-07-27
+:Approved Version: 0.1.2
+:Approved License: MIT
+
+All fine.
+
+
+Flask-Uploads
+-------------
+
+:First Approval: 2010-07-27
+:Last Review: 2010-07-27
+:Approved Version: 0.1.2
+:Approved License: MIT
+
+All fine.
+
+
+Flask-Mail
+----------
+
+:First Approval: 2010-07-29
+:Last Review: 2010-07-29
+:Approved Version: 0.3.4
+:Approved License: BSD
+
+All fine.
+
+
+Flask-XML-RPC
+-------------
+
+:First Approval: 2010-07-30
+:Last Review: 2010-07-30
+:Approved Version: 0.1.2
+:Approved License: MIT
+
+All fine.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/extreview/listed.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,64 @@
+Listed Extensions
+=================
+
+This list contains extensions that passed listing.  This means the
+extension is on the list of extensions on the website.  It does not
+contain extensions that are approved.
+
+
+Flask-CouchDBKit
+----------------
+
+:Last-Review: 2010-07-25
+:Reviewed Version: 0.2
+
+Would be fine for approval, but the test suite is not part of the sdist
+package (missing entry in MANIFEST.in) and the test suite does not respond
+to either "make test" or "python setup.py test".
+
+
+flask-csrf
+----------
+
+:Last-Review: 2010-07-25
+:Reviewed Version: 0.2
+
+Will not be approved because this is functionality that should be handled
+in the form handling systems which is for Flask-WTF already the case.
+Also, this implementation only supports one open tab with forms.
+
+Name is not following Flask extension naming rules.
+
+Considered for unlisting.
+
+
+flask-lesscss
+-------------
+
+:Last-Review: 2010-07-25
+:Reviewed Version: 0.9.1
+
+Broken package description, nonconforming package name, does not follow
+standard API rules (init_lesscss instead of lesscss).
+
+Considered for unlisting, improved version should release as
+"Flask-LessCSS" with a conforming API and fixed packages indices, as well
+as a testsuite.
+
+
+Flask-OAuth
+-----------
+
+:Last-Review: 2010-07-25
+:Reviewed Version: 0.9
+
+Short long description, missing tests.
+
+
+Flask-OpenID
+------------
+
+:Last-Review: 2010-07-25
+:Reviewed Version: 1.0.1
+
+Short long description, missing tests.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/extreview/unlisted.rst	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,55 @@
+Unlisted Extensions
+===================
+
+This is a list of extensions that is currently rejected from listing and
+with that also not approved.  If an extension ends up here it should
+improved to be listed.
+
+
+Flask-Actions
+-------------
+
+:Last Review: 2010-07-25
+:Reviewed Version: 0.2
+
+Rejected because of missing description in PyPI, formatting issues with
+the documentation (missing headlines, scrollbars etc.) and a general clash
+of functionality with the Flask-Script package.  Latter should not be a
+problem, but the documentation should improve.  For listing, the extension
+developer should probably discuss the extension on the mailinglist with
+others.
+
+Futhermore it also has an egg registered with an invalid filename.
+
+
+Flask-Jinja2Extender
+--------------------
+
+:Last Review: 2010-07-25
+:Reviewed Version: 0.1
+
+Usecase not obvious, hacky implementation, does not solve a problem that
+could not be solved with Flask itself.  I suppose it is to aid other
+extensions, but that should be discussed on the mailinglist.
+
+
+Flask-Markdown
+--------------
+
+:Last Review: 2010-07-25
+:Reviewed Version: 0.2
+
+Would be great for enlisting but it should follow the API of Flask-Creole.
+Besides that, the docstrings are not valid rst (run through rst2html to
+see the issue) and it is missing tests.  Otherwise fine :)
+
+
+flask-urls
+----------
+
+:Last Review: 2010-07-25
+:Reviewed Version: 0.9.2
+
+Broken PyPI index and non-conforming extension name.  Due to the small
+featureset this was also delisted from the list.  It was there previously
+before the approval process was introduced.
--- a/bundled/flask/flask.py	Thu Jan 27 18:15:55 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1512 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-    flask
-    ~~~~~
-
-    A microframework based on Werkzeug.  It's extensively documented
-    and follows best practice patterns.
-
-    :copyright: (c) 2010 by Armin Ronacher.
-    :license: BSD, see LICENSE for more details.
-"""
-from __future__ import with_statement
-import os
-import sys
-import mimetypes
-from datetime import datetime, timedelta
-
-from itertools import chain
-from threading import Lock
-from jinja2 import Environment, PackageLoader, FileSystemLoader
-from werkzeug import Request as RequestBase, Response as ResponseBase, \
-     LocalStack, LocalProxy, create_environ, SharedDataMiddleware, \
-     ImmutableDict, cached_property, wrap_file, Headers, \
-     import_string
-from werkzeug.routing import Map, Rule
-from werkzeug.exceptions import HTTPException, InternalServerError
-from werkzeug.contrib.securecookie import SecureCookie
-
-# try to load the best simplejson implementation available.  If JSON
-# is not installed, we add a failing class.
-json_available = True
-try:
-    import simplejson as json
-except ImportError:
-    try:
-        import json
-    except ImportError:
-        json_available = False
-
-# utilities we import from Werkzeug and Jinja2 that are unused
-# in the module but are exported as public interface.
-from werkzeug import abort, redirect
-from jinja2 import Markup, escape
-
-# use pkg_resource if that works, otherwise fall back to cwd.  The
-# current working directory is generally not reliable with the notable
-# exception of google appengine.
-try:
-    import pkg_resources
-    pkg_resources.resource_stream
-except (ImportError, AttributeError):
-    pkg_resources = None
-
-# a lock used for logger initialization
-_logger_lock = Lock()
-
-
-class Request(RequestBase):
-    """The request object used by default in flask.  Remembers the
-    matched endpoint and view arguments.
-
-    It is what ends up as :class:`~flask.request`.  If you want to replace
-    the request object used you can subclass this and set
-    :attr:`~flask.Flask.request_class` to your subclass.
-    """
-
-    endpoint = view_args = routing_exception = None
-
-    @property
-    def module(self):
-        """The name of the current module"""
-        if self.endpoint and '.' in self.endpoint:
-            return self.endpoint.rsplit('.', 1)[0]
-
-    @cached_property
-    def json(self):
-        """If the mimetype is `application/json` this will contain the
-        parsed JSON data.
-        """
-        if __debug__:
-            _assert_have_json()
-        if self.mimetype == 'application/json':
-            return json.loads(self.data)
-
-
-class Response(ResponseBase):
-    """The response object that is used by default in flask.  Works like the
-    response object from Werkzeug but is set to have a HTML mimetype by
-    default.  Quite often you don't have to create this object yourself because
-    :meth:`~flask.Flask.make_response` will take care of that for you.
-
-    If you want to replace the response object used you can subclass this and
-    set :attr:`~flask.Flask.response_class` to your subclass.
-    """
-    default_mimetype = 'text/html'
-
-
-class _RequestGlobals(object):
-    pass
-
-
-class Session(SecureCookie):
-    """Expands the session with support for switching between permanent
-    and non-permanent sessions.
-    """
-
-    def _get_permanent(self):
-        return self.get('_permanent', False)
-
-    def _set_permanent(self, value):
-        self['_permanent'] = bool(value)
-
-    permanent = property(_get_permanent, _set_permanent)
-    del _get_permanent, _set_permanent
-
-
-class _NullSession(Session):
-    """Class used to generate nicer error messages if sessions are not
-    available.  Will still allow read-only access to the empty session
-    but fail on setting.
-    """
-
-    def _fail(self, *args, **kwargs):
-        raise RuntimeError('the session is unavailable because no secret '
-                           'key was set.  Set the secret_key on the '
-                           'application to something unique and secret')
-    __setitem__ = __delitem__ = clear = pop = popitem = \
-        update = setdefault = _fail
-    del _fail
-
-
-class _RequestContext(object):
-    """The request context contains all request relevant information.  It is
-    created at the beginning of the request and pushed to the
-    `_request_ctx_stack` and removed at the end of it.  It will create the
-    URL adapter and request object for the WSGI environment provided.
-    """
-
-    def __init__(self, app, environ):
-        self.app = app
-        self.url_adapter = app.url_map.bind_to_environ(environ)
-        self.request = app.request_class(environ)
-        self.session = app.open_session(self.request)
-        if self.session is None:
-            self.session = _NullSession()
-        self.g = _RequestGlobals()
-        self.flashes = None
-
-        try:
-            self.request.endpoint, self.request.view_args = \
-                self.url_adapter.match()
-        except HTTPException, e:
-            self.request.routing_exception = e
-
-    def push(self):
-        """Binds the request context."""
-        _request_ctx_stack.push(self)
-
-    def pop(self):
-        """Pops the request context."""
-        _request_ctx_stack.pop()
-
-    def __enter__(self):
-        self.push()
-        return self
-
-    def __exit__(self, exc_type, exc_value, tb):
-        # do not pop the request stack if we are in debug mode and an
-        # exception happened.  This will allow the debugger to still
-        # access the request object in the interactive shell.  Furthermore
-        # the context can be force kept alive for the test client.
-        if not self.request.environ.get('flask._preserve_context') and \
-           (tb is None or not self.app.debug):
-            self.pop()
-
-
-def url_for(endpoint, **values):
-    """Generates a URL to the given endpoint with the method provided.
-    The endpoint is relative to the active module if modules are in use.
-
-    Here some examples:
-
-    ==================== ======================= =============================
-    Active Module        Target Endpoint         Target Function
-    ==================== ======================= =============================
-    `None`               ``'index'``             `index` of the application
-    `None`               ``'.index'``            `index` of the application
-    ``'admin'``          ``'index'``             `index` of the `admin` module
-    any                  ``'.index'``            `index` of the application
-    any                  ``'admin.index'``       `index` of the `admin` module
-    ==================== ======================= =============================
-
-    Variable arguments that are unknown to the target endpoint are appended
-    to the generated URL as query arguments.
-
-    For more information, head over to the :ref:`Quickstart <url-building>`.
-
-    :param endpoint: the endpoint of the URL (name of the function)
-    :param values: the variable arguments of the URL rule
-    :param _external: if set to `True`, an absolute URL is generated.
-    """
-    ctx = _request_ctx_stack.top
-    if '.' not in endpoint:
-        mod = ctx.request.module
-        if mod is not None:
-            endpoint = mod + '.' + endpoint
-    elif endpoint.startswith('.'):
-        endpoint = endpoint[1:]
-    external = values.pop('_external', False)
-    return ctx.url_adapter.build(endpoint, values, force_external=external)
-
-
-def get_template_attribute(template_name, attribute):
-    """Loads a macro (or variable) a template exports.  This can be used to
-    invoke a macro from within Python code.  If you for example have a
-    template named `_cider.html` with the following contents:
-
-    .. sourcecode:: html+jinja
-
-       {% macro hello(name) %}Hello {{ name }}!{% endmacro %}
-
-    You can access this from Python code like this::
-
-        hello = get_template_attribute('_cider.html', 'hello')
-        return hello('World')
-
-    .. versionadded:: 0.2
-
-    :param template_name: the name of the template
-    :param attribute: the name of the variable of macro to acccess
-    """
-    return getattr(current_app.jinja_env.get_template(template_name).module,
-                   attribute)
-
-
-def flash(message, category='message'):
-    """Flashes a message to the next request.  In order to remove the
-    flashed message from the session and to display it to the user,
-    the template has to call :func:`get_flashed_messages`.
-
-    .. versionchanged: 0.3
-       `category` parameter added.
-
-    :param message: the message to be flashed.
-    :param category: the category for the message.  The following values
-                     are recommended: ``'message'`` for any kind of message,
-                     ``'error'`` for errors, ``'info'`` for information
-                     messages and ``'warning'`` for warnings.  However any
-                     kind of string can be used as category.
-    """
-    session.setdefault('_flashes', []).append((category, message))
-
-
-def get_flashed_messages(with_categories=False):
-    """Pulls all flashed messages from the session and returns them.
-    Further calls in the same request to the function will return
-    the same messages.  By default just the messages are returned,
-    but when `with_categories` is set to `True`, the return value will
-    be a list of tuples in the form ``(category, message)`` instead.
-
-    Example usage:
-
-    .. sourcecode:: html+jinja
-
-        {% for category, msg in get_flashed_messages(with_categories=true) %}
-          <p class=flash-{{ category }}>{{ msg }}
-        {% endfor %}
-
-    .. versionchanged:: 0.3
-       `with_categories` parameter added.
-
-    :param with_categories: set to `True` to also receive categories.
-    """
-    flashes = _request_ctx_stack.top.flashes
-    if flashes is None:
-        _request_ctx_stack.top.flashes = flashes = session.pop('_flashes', [])
-    if not with_categories:
-        return [x[1] for x in flashes]
-    return flashes
-
-
-def jsonify(*args, **kwargs):
-    """Creates a :class:`~flask.Response` with the JSON representation of
-    the given arguments with an `application/json` mimetype.  The arguments
-    to this function are the same as to the :class:`dict` constructor.
-
-    Example usage::
-
-        @app.route('/_get_current_user')
-        def get_current_user():
-            return jsonify(username=g.user.username,
-                           email=g.user.email,
-                           id=g.user.id)
-
-    This will send a JSON response like this to the browser::
-
-        {
-            "username": "admin",
-            "email": "admin@localhost",
-            "id": 42
-        }
-
-    This requires Python 2.6 or an installed version of simplejson.  For
-    security reasons only objects are supported toplevel.  For more
-    information about this, have a look at :ref:`json-security`.
-
-    .. versionadded:: 0.2
-    """
-    if __debug__:
-        _assert_have_json()
-    return current_app.response_class(json.dumps(dict(*args, **kwargs),
-        indent=None if request.is_xhr else 2), mimetype='application/json')
-
-
-def send_file(filename_or_fp, mimetype=None, as_attachment=False,
-              attachment_filename=None):
-    """Sends the contents of a file to the client.  This will use the
-    most efficient method available and configured.  By default it will
-    try to use the WSGI server's file_wrapper support.  Alternatively
-    you can set the application's :attr:`~Flask.use_x_sendfile` attribute
-    to ``True`` to directly emit an `X-Sendfile` header.  This however
-    requires support of the underlying webserver for `X-Sendfile`.
-
-    By default it will try to guess the mimetype for you, but you can
-    also explicitly provide one.  For extra security you probably want
-    to sent certain files as attachment (HTML for instance).
-
-    Please never pass filenames to this function from user sources without
-    checking them first.  Something like this is usually sufficient to
-    avoid security problems::
-
-        if '..' in filename or filename.startswith('/'):
-            abort(404)
-
-    .. versionadded:: 0.2
-
-    :param filename_or_fp: the filename of the file to send.  This is
-                           relative to the :attr:`~Flask.root_path` if a
-                           relative path is specified.
-                           Alternatively a file object might be provided
-                           in which case `X-Sendfile` might not work and
-                           fall back to the traditional method.
-    :param mimetype: the mimetype of the file if provided, otherwise
-                     auto detection happens.
-    :param as_attachment: set to `True` if you want to send this file with
-                          a ``Content-Disposition: attachment`` header.
-    :param attachment_filename: the filename for the attachment if it
-                                differs from the file's filename.
-    """
-    if isinstance(filename_or_fp, basestring):
-        filename = filename_or_fp
-        file = None
-    else:
-        file = filename_or_fp
-        filename = getattr(file, 'name', None)
-    if filename is not None:
-        filename = os.path.join(current_app.root_path, filename)
-    if mimetype is None and (filename or attachment_filename):
-        mimetype = mimetypes.guess_type(filename or attachment_filename)[0]
-    if mimetype is None:
-        mimetype = 'application/octet-stream'
-
-    headers = Headers()
-    if as_attachment:
-        if attachment_filename is None:
-            if filename is None:
-                raise TypeError('filename unavailable, required for '
-                                'sending as attachment')
-            attachment_filename = os.path.basename(filename)
-        headers.add('Content-Disposition', 'attachment',
-                    filename=attachment_filename)
-
-    if current_app.use_x_sendfile and filename:
-        if file is not None:
-            file.close()
-        headers['X-Sendfile'] = filename
-        data = None
-    else:
-        if file is None:
-            file = open(filename, 'rb')
-        data = wrap_file(request.environ, file)
-
-    return Response(data, mimetype=mimetype, headers=headers,
-                    direct_passthrough=True)
-
-
-def render_template(template_name, **context):
-    """Renders a template from the template folder with the given
-    context.
-
-    :param template_name: the name of the template to be rendered
-    :param context: the variables that should be available in the
-                    context of the template.
-    """
-    current_app.update_template_context(context)
-    return current_app.jinja_env.get_template(template_name).render(context)
-
-
-def render_template_string(source, **context):
-    """Renders a template from the given template source string
-    with the given context.
-
-    :param template_name: the sourcecode of the template to be
-                          rendered
-    :param context: the variables that should be available in the
-                    context of the template.
-    """
-    current_app.update_template_context(context)
-    return current_app.jinja_env.from_string(source).render(context)
-
-
-def _default_template_ctx_processor():
-    """Default template context processor.  Injects `request`,
-    `session` and `g`.
-    """
-    reqctx = _request_ctx_stack.top
-    return dict(
-        request=reqctx.request,
-        session=reqctx.session,
-        g=reqctx.g
-    )
-
-
-def _assert_have_json():
-    """Helper function that fails if JSON is unavailable."""
-    if not json_available:
-        raise RuntimeError('simplejson not installed')
-
-
-def _get_package_path(name):
-    """Returns the path to a package or cwd if that cannot be found."""
-    try:
-        return os.path.abspath(os.path.dirname(sys.modules[name].__file__))
-    except (KeyError, AttributeError):
-        return os.getcwd()
-
-
-# figure out if simplejson escapes slashes.  This behaviour was changed
-# from one version to another without reason.
-if not json_available or '\\/' not in json.dumps('/'):
-
-    def _tojson_filter(*args, **kwargs):
-        if __debug__:
-            _assert_have_json()
-        return json.dumps(*args, **kwargs).replace('/', '\\/')
-else:
-    _tojson_filter = json.dumps
-
-
-class _PackageBoundObject(object):
-
-    def __init__(self, import_name):
-        #: The name of the package or module.  Do not change this once
-        #: it was set by the constructor.
-        self.import_name = import_name
-
-        #: Where is the app root located?
-        self.root_path = _get_package_path(self.import_name)
-
-    def open_resource(self, resource):
-        """Opens a resource from the application's resource folder.  To see
-        how this works, consider the following folder structure::
-
-            /myapplication.py
-            /schemal.sql
-            /static
-                /style.css
-            /templates
-                /layout.html
-                /index.html
-
-        If you want to open the `schema.sql` file you would do the
-        following::
-
-            with app.open_resource('schema.sql') as f:
-                contents = f.read()
-                do_something_with(contents)
-
-        :param resource: the name of the resource.  To access resources within
-                         subfolders use forward slashes as separator.
-        """
-        if pkg_resources is None:
-            return open(os.path.join(self.root_path, resource), 'rb')
-        return pkg_resources.resource_stream(self.import_name, resource)
-
-
-class _ModuleSetupState(object):
-
-    def __init__(self, app, url_prefix=None):
-        self.app = app
-        self.url_prefix = url_prefix
-
-
-class Module(_PackageBoundObject):
-    """Container object that enables pluggable applications.  A module can
-    be used to organize larger applications.  They represent blueprints that,
-    in combination with a :class:`Flask` object are used to create a large
-    application.
-
-    A module is like an application bound to an `import_name`.  Multiple
-    modules can share the same import names, but in that case a `name` has
-    to be provided to keep them apart.  If different import names are used,
-    the rightmost part of the import name is used as name.
-
-    Here an example structure for a larger appliation::
-
-        /myapplication
-            /__init__.py
-            /views
-                /__init__.py
-                /admin.py
-                /frontend.py
-
-    The `myapplication/__init__.py` can look like this::
-
-        from flask import Flask
-        from myapplication.views.admin import admin
-        from myapplication.views.frontend import frontend
-
-        app = Flask(__name__)
-        app.register_module(admin, url_prefix='/admin')
-        app.register_module(frontend)
-
-    And here an example view module (`myapplication/views/admin.py`)::
-
-        from flask import Module
-
-        admin = Module(__name__)
-
-        @admin.route('/')
-        def index():
-            pass
-
-        @admin.route('/login')
-        def login():
-            pass
-
-    For a gentle introduction into modules, checkout the
-    :ref:`working-with-modules` section.
-    """
-
-    def __init__(self, import_name, name=None, url_prefix=None):
-        if name is None:
-            assert '.' in import_name, 'name required if package name ' \
-                'does not point to a submodule'
-            name = import_name.rsplit('.', 1)[1]
-        _PackageBoundObject.__init__(self, import_name)
-        self.name = name
-        self.url_prefix = url_prefix
-        self._register_events = []
-
-    def route(self, rule, **options):
-        """Like :meth:`Flask.route` but for a module.  The endpoint for the
-        :func:`url_for` function is prefixed with the name of the module.
-        """
-        def decorator(f):
-            self.add_url_rule(rule, f.__name__, f, **options)
-            return f
-        return decorator
-
-    def add_url_rule(self, rule, endpoint, view_func=None, **options):
-        """Like :meth:`Flask.add_url_rule` but for a module.  The endpoint for
-        the :func:`url_for` function is prefixed with the name of the module.
-        """
-        def register_rule(state):
-            the_rule = rule
-            if state.url_prefix:
-                the_rule = state.url_prefix + rule
-            state.app.add_url_rule(the_rule, '%s.%s' % (self.name, endpoint),
-                                   view_func, **options)
-        self._record(register_rule)
-
-    def before_request(self, f):
-        """Like :meth:`Flask.before_request` but for a module.  This function
-        is only executed before each request that is handled by a function of
-        that module.
-        """
-        self._record(lambda s: s.app.before_request_funcs
-            .setdefault(self.name, []).append(f))
-        return f
-
-    def before_app_request(self, f):
-        """Like :meth:`Flask.before_request`.  Such a function is executed
-        before each request, even if outside of a module.
-        """
-        self._record(lambda s: s.app.before_request_funcs
-            .setdefault(None, []).append(f))
-        return f
-
-    def after_request(self, f):
-        """Like :meth:`Flask.after_request` but for a module.  This function
-        is only executed after each request that is handled by a function of
-        that module.
-        """
-        self._record(lambda s: s.app.after_request_funcs
-            .setdefault(self.name, []).append(f))
-        return f
-
-    def after_app_request(self, f):
-        """Like :meth:`Flask.after_request` but for a module.  Such a function
-        is executed after each request, even if outside of the module.
-        """
-        self._record(lambda s: s.app.after_request_funcs
-            .setdefault(None, []).append(f))
-        return f
-
-    def context_processor(self, f):
-        """Like :meth:`Flask.context_processor` but for a module.  This
-        function is only executed for requests handled by a module.
-        """
-        self._record(lambda s: s.app.template_context_processors
-            .setdefault(self.name, []).append(f))
-        return f
-
-    def app_context_processor(self, f):
-        """Like :meth:`Flask.context_processor` but for a module.  Such a
-        function is executed each request, even if outside of the module.
-        """
-        self._record(lambda s: s.app.template_context_processors
-            .setdefault(None, []).append(f))
-        return f
-
-    def app_errorhandler(self, code):
-        """Like :meth:`Flask.errorhandler` but for a module.  This
-        handler is used for all requests, even if outside of the module.
-
-        .. versionadded:: 0.4
-        """
-        def decorator(f):
-            self._record(lambda s: s.app.errorhandler(code)(f))
-            return f
-        return decorator
-
-    def _record(self, func):
-        self._register_events.append(func)
-
-
-class ConfigAttribute(object):
-    """Makes an attribute forward to the config"""
-
-    def __init__(self, name):
-        self.__name__ = name
-
-    def __get__(self, obj, type=None):
-        if obj is None:
-            return self
-        return obj.config[self.__name__]
-
-    def __set__(self, obj, value):
-        obj.config[self.__name__] = value
-
-
-class Config(dict):
-    """Works exactly like a dict but provides ways to fill it from files
-    or special dictionaries.  There are two common patterns to populate the
-    config.
-
-    Either you can fill the config from a config file::
-
-        app.config.from_pyfile('yourconfig.cfg')
-
-    Or alternatively you can define the configuration options in the
-    module that calls :meth:`from_object` or provide an import path to
-    a module that should be loaded.  It is also possible to tell it to
-    use the same module and with that provide the configuration values
-    just before the call::
-
-        DEBUG = True
-        SECRET_KEY = 'development key'
-        app.config.from_object(__name__)
-
-    In both cases (loading from any Python file or loading from modules),
-    only uppercase keys are added to the config.  This makes it possible to use
-    lowercase values in the config file for temporary values that are not added
-    to the config or to define the config keys in the same file that implements
-    the application.
-
-    Probably the most interesting way to load configurations is from an
-    environment variable pointing to a file::
-
-        app.config.from_envvar('YOURAPPLICATION_SETTINGS')
-
-    In this case before launching the application you have to set this
-    environment variable to the file you want to use.  On Linux and OS X
-    use the export statement::
-
-        export YOURAPPLICATION_SETTINGS='/path/to/config/file'
-
-    On windows use `set` instead.
-
-    :param root_path: path to which files are read relative from.  When the
-                      config object is created by the application, this is
-                      the application's :attr:`~flask.Flask.root_path`.
-    :param defaults: an optional dictionary of default values
-    """
-
-    def __init__(self, root_path, defaults=None):
-        dict.__init__(self, defaults or {})
-        self.root_path = root_path
-
-    def from_envvar(self, variable_name, silent=False):
-        """Loads a configuration from an environment variable pointing to
-        a configuration file.  This basically is just a shortcut with nicer
-        error messages for this line of code::
-
-            app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS'])
-
-        :param variable_name: name of the environment variable
-        :param silent: set to `True` if you want silent failing for missing
-                       files.
-        :return: bool. `True` if able to load config, `False` otherwise.
-        """
-        rv = os.environ.get(variable_name)
-        if not rv:
-            if silent:
-                return False
-            raise RuntimeError('The environment variable %r is not set '
-                               'and as such configuration could not be '
-                               'loaded.  Set this variable and make it '
-                               'point to a configuration file' %
-                               variable_name)
-        self.from_pyfile(rv)
-        return True
-
-    def from_pyfile(self, filename):
-        """Updates the values in the config from a Python file.  This function
-        behaves as if the file was imported as module with the
-        :meth:`from_object` function.
-
-        :param filename: the filename of the config.  This can either be an
-                         absolute filename or a filename relative to the
-                         root path.
-        """
-        filename = os.path.join(self.root_path, filename)
-        d = type(sys)('config')
-        d.__file__ = filename
-        execfile(filename, d.__dict__)
-        self.from_object(d)
-
-    def from_object(self, obj):
-        """Updates the values from the given object.  An object can be of one
-        of the following two types:
-
-        -   a string: in this case the object with that name will be imported
-        -   an actual object reference: that object is used directly
-
-        Objects are usually either modules or classes.
-
-        Just the uppercase variables in that object are stored in the config
-        after lowercasing.  Example usage::
-
-            app.config.from_object('yourapplication.default_config')
-            from yourapplication import default_config
-            app.config.from_object(default_config)
-
-        You should not use this function to load the actual configuration but
-        rather configuration defaults.  The actual config should be loaded
-        with :meth:`from_pyfile` and ideally from a location not within the
-        package because the package might be installed system wide.
-
-        :param obj: an import name or object
-        """
-        if isinstance(obj, basestring):
-            obj = import_string(obj)
-        for key in dir(obj):
-            if key.isupper():
-                self[key] = getattr(obj, key)
-
-    def __repr__(self):
-        return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self))
-
-
-class Flask(_PackageBoundObject):
-    """The flask object implements a WSGI application and acts as the central
-    object.  It is passed the name of the module or package of the
-    application.  Once it is created it will act as a central registry for
-    the view functions, the URL rules, template configuration and much more.
-
-    The name of the package is used to resolve resources from inside the
-    package or the folder the module is contained in depending on if the
-    package parameter resolves to an actual python package (a folder with
-    an `__init__.py` file inside) or a standard module (just a `.py` file).
-
-    For more information about resource loading, see :func:`open_resource`.
-
-    Usually you create a :class:`Flask` instance in your main module or
-    in the `__init__.py` file of your package like this::
-
-        from flask import Flask
-        app = Flask(__name__)
-    """
-
-    #: The class that is used for request objects.  See :class:`~flask.Request`
-    #: for more information.
-    request_class = Request
-
-    #: The class that is used for response objects.  See
-    #: :class:`~flask.Response` for more information.
-    response_class = Response
-
-    #: Path for the static files.  If you don't want to use static files
-    #: you can set this value to `None` in which case no URL rule is added
-    #: and the development server will no longer serve any static files.
-    static_path = '/static'
-
-    #: The debug flag.  Set this to `True` to enable debugging of the
-    #: application.  In debug mode the debugger will kick in when an unhandled
-    #: exception ocurrs and the integrated server will automatically reload
-    #: the application if changes in the code are detected.
-    #:
-    #: This attribute can also be configured from the config with the `DEBUG`
-    #: configuration key.  Defaults to `False`.
-    debug = ConfigAttribute('DEBUG')
-
-    #: The testing flask.  Set this to `True` to enable the test mode of
-    #: Flask extensions (and in the future probably also Flask itself).
-    #: For example this might activate unittest helpers that have an
-    #: additional runtime cost which should not be enabled by default.
-    #:
-    #: This attribute can also be configured from the config with the
-    #: `TESTING` configuration key.  Defaults to `False`.
-    testing = ConfigAttribute('TESTING')
-
-    #: If a secret key is set, cryptographic components can use this to
-    #: sign cookies and other things.  Set this to a complex random value
-    #: when you want to use the secure cookie for instance.
-    #:
-    #: This attribute can also be configured from the config with the
-    #: `SECRET_KEY` configuration key.  Defaults to `None`.
-    secret_key = ConfigAttribute('SECRET_KEY')
-
-    #: The secure cookie uses this for the name of the session cookie.
-    #:
-    #: This attribute can also be configured from the config with the
-    #: `SESSION_COOKIE_NAME` configuration key.  Defaults to ``'session'``
-    session_cookie_name = ConfigAttribute('SESSION_COOKIE_NAME')
-
-    #: A :class:`~datetime.timedelta` which is used to set the expiration
-    #: date of a permanent session.  The default is 31 days which makes a
-    #: permanent session survive for roughly one month.
-    #:
-    #: This attribute can also be configured from the config with the
-    #: `PERMANENT_SESSION_LIFETIME` configuration key.  Defaults to
-    #: ``timedelta(days=31)``
-    permanent_session_lifetime = ConfigAttribute('PERMANENT_SESSION_LIFETIME')
-
-    #: Enable this if you want to use the X-Sendfile feature.  Keep in
-    #: mind that the server has to support this.  This only affects files
-    #: sent with the :func:`send_file` method.
-    #:
-    #: .. versionadded:: 0.2
-    #:
-    #: This attribute can also be configured from the config with the
-    #: `USE_X_SENDFILE` configuration key.  Defaults to `False`.
-    use_x_sendfile = ConfigAttribute('USE_X_SENDFILE')
-
-    #: The name of the logger to use.  By default the logger name is the
-    #: package name passed to the constructor.
-    #:
-    #: .. versionadded:: 0.4
-    logger_name = ConfigAttribute('LOGGER_NAME')
-
-    #: The logging format used for the debug logger.  This is only used when
-    #: the application is in debug mode, otherwise the attached logging
-    #: handler does the formatting.
-    #:
-    #: .. versionadded:: 0.3
-    debug_log_format = (
-        '-' * 80 + '\n' +
-        '%(levelname)s in %(module)s, %(pathname)s:%(lineno)d]:\n' +
-        '%(message)s\n' +
-        '-' * 80
-    )
-
-    #: Options that are passed directly to the Jinja2 environment.
-    jinja_options = ImmutableDict(
-        autoescape=True,
-        extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_']
-    )
-
-    #: Default configuration parameters.
-    default_config = ImmutableDict({
-        'DEBUG':                                False,
-        'TESTING':                              False,
-        'SECRET_KEY':                           None,
-        'SESSION_COOKIE_NAME':                  'session',
-        'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
-        'USE_X_SENDFILE':                       False,
-        'LOGGER_NAME':                          None
-    })
-
-    def __init__(self, import_name):
-        _PackageBoundObject.__init__(self, import_name)
-
-        #: The configuration dictionary as :class:`Config`.  This behaves
-        #: exactly like a regular dictionary but supports additional methods
-        #: to load a config from files.
-        self.config = Config(self.root_path, self.default_config)
-
-        #: Prepare the deferred setup of the logger.
-        self._logger = None
-        self.logger_name = self.import_name
-
-        #: A dictionary of all view functions registered.  The keys will
-        #: be function names which are also used to generate URLs and
-        #: the values are the function objects themselves.
-        #: to register a view function, use the :meth:`route` decorator.
-        self.view_functions = {}
-
-        #: A dictionary of all registered error handlers.  The key is
-        #: be the error code as integer, the value the function that
-        #: should handle that error.
-        #: To register a error handler, use the :meth:`errorhandler`
-        #: decorator.
-        self.error_handlers = {}
-
-        #: A dictionary with lists of functions that should be called at the
-        #: beginning of the request.  The key of the dictionary is the name of
-        #: the module this function is active for, `None` for all requests.
-        #: This can for example be used to open database connections or
-        #: getting hold of the currently logged in user.  To register a
-        #: function here, use the :meth:`before_request` decorator.
-        self.before_request_funcs = {}
-
-        #: A dictionary with lists of functions that should be called after
-        #: each request.  The key of the dictionary is the name of the module
-        #: this function is active for, `None` for all requests.  This can for
-        #: example be used to open database connections or getting hold of the
-        #: currently logged in user.  To register a function here, use the
-        #: :meth:`before_request` decorator.
-        self.after_request_funcs = {}
-
-        #: A dictionary with list of functions that are called without argument
-        #: to populate the template context.  They key of the dictionary is the
-        #: name of the module this function is active for, `None` for all
-        #: requests.  Each returns a dictionary that the template context is
-        #: updated with.  To register a function here, use the
-        #: :meth:`context_processor` decorator.
-        self.template_context_processors = {
-            None: [_default_template_ctx_processor]
-        }
-
-        #: The :class:`~werkzeug.routing.Map` for this instance.  You can use
-        #: this to change the routing converters after the class was created
-        #: but before any routes are connected.  Example::
-        #:
-        #:    from werkzeug import BaseConverter
-        #:
-        #:    class ListConverter(BaseConverter):
-        #:        def to_python(self, value):
-        #:            return value.split(',')
-        #:        def to_url(self, values):
-        #:            return ','.join(BaseConverter.to_url(value)
-        #:                            for value in values)
-        #:
-        #:    app = Flask(__name__)
-        #:    app.url_map.converters['list'] = ListConverter
-        self.url_map = Map()
-
-        if self.static_path is not None:
-            self.add_url_rule(self.static_path + '/<filename>',
-                              build_only=True, endpoint='static')
-            if pkg_resources is not None:
-                target = (self.import_name, 'static')
-            else:
-                target = os.path.join(self.root_path, 'static')
-            self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {
-                self.static_path: target
-            })
-
-        #: The Jinja2 environment.  It is created from the
-        #: :attr:`jinja_options` and the loader that is returned
-        #: by the :meth:`create_jinja_loader` function.
-        self.jinja_env = Environment(loader=self.create_jinja_loader(),
-                                     **self.jinja_options)
-        self.jinja_env.globals.update(
-            url_for=url_for,
-            get_flashed_messages=get_flashed_messages
-        )
-        self.jinja_env.filters['tojson'] = _tojson_filter
-
-    @property
-    def logger(self):
-        """A :class:`logging.Logger` object for this application.  The
-        default configuration is to log to stderr if the application is
-        in debug mode.  This logger can be used to (surprise) log messages.
-        Here some examples::
-
-            app.logger.debug('A value for debugging')
-            app.logger.warning('A warning ocurred (%d apples)', 42)
-            app.logger.error('An error occoured')
-
-        .. versionadded:: 0.3
-        """
-        if self._logger and self._logger.name == self.logger_name:
-            return self._logger
-        with _logger_lock:
-            if self._logger and self._logger.name == self.logger_name:
-                return self._logger
-            from logging import getLogger, StreamHandler, Formatter, DEBUG
-            class DebugHandler(StreamHandler):
-                def emit(x, record):
-                    if self.debug:
-                        StreamHandler.emit(x, record)
-            handler = DebugHandler()
-            handler.setLevel(DEBUG)
-            handler.setFormatter(Formatter(self.debug_log_format))
-            logger = getLogger(self.logger_name)
-            logger.addHandler(handler)
-            self._logger = logger
-            return logger
-
-    def create_jinja_loader(self):
-        """Creates the Jinja loader.  By default just a package loader for
-        the configured package is returned that looks up templates in the
-        `templates` folder.  To add other loaders it's possible to
-        override this method.
-        """
-        if pkg_resources is None:
-            return FileSystemLoader(os.path.join(self.root_path, 'templates'))
-        return PackageLoader(self.import_name)
-
-    def update_template_context(self, context):
-        """Update the template context with some commonly used variables.
-        This injects request, session and g into the template context.
-
-        :param context: the context as a dictionary that is updated in place
-                        to add extra variables.
-        """
-        funcs = self.template_context_processors[None]
-        mod = _request_ctx_stack.top.request.module
-        if mod is not None and mod in self.template_context_processors:
-            funcs = chain(funcs, self.template_context_processors[mod])
-        for func in funcs:
-            context.update(func())
-
-    def run(self, host='127.0.0.1', port=5000, **options):
-        """Runs the application on a local development server.  If the
-        :attr:`debug` flag is set the server will automatically reload
-        for code changes and show a debugger in case an exception happened.
-
-        :param host: the hostname to listen on.  set this to ``'0.0.0.0'``
-                     to have the server available externally as well.
-        :param port: the port of the webserver
-        :param options: the options to be forwarded to the underlying
-                        Werkzeug server.  See :func:`werkzeug.run_simple`
-                        for more information.
-        """
-        from werkzeug import run_simple
-        if 'debug' in options:
-            self.debug = options.pop('debug')
-        options.setdefault('use_reloader', self.debug)
-        options.setdefault('use_debugger', self.debug)
-        return run_simple(host, port, self, **options)
-
-    def test_client(self):
-        """Creates a test client for this application.  For information
-        about unit testing head over to :ref:`testing`.
-
-        The test client can be used in a `with` block to defer the closing down
-        of the context until the end of the `with` block.  This is useful if
-        you want to access the context locals for testing::
-
-            with app.test_client() as c:
-                rv = c.get('/?vodka=42')
-                assert request.args['vodka'] == '42'
-
-        .. versionchanged:: 0.4
-           added support for `with` block usage for the client.
-        """
-        from werkzeug import Client
-        class FlaskClient(Client):
-            preserve_context = context_preserved = False
-            def open(self, *args, **kwargs):
-                if self.context_preserved:
-                    _request_ctx_stack.pop()
-                    self.context_preserved = False
-                kwargs.setdefault('environ_overrides', {}) \
-                    ['flask._preserve_context'] = self.preserve_context
-                old = _request_ctx_stack.top
-                try:
-                    return Client.open(self, *args, **kwargs)
-                finally:
-                    self.context_preserved = _request_ctx_stack.top is not old
-            def __enter__(self):
-                self.preserve_context = True
-                return self
-            def __exit__(self, exc_type, exc_value, tb):
-                self.preserve_context = False
-                if self.context_preserved:
-                    _request_ctx_stack.pop()
-        return FlaskClient(self, self.response_class, use_cookies=True)
-
-    def open_session(self, request):
-        """Creates or opens a new session.  Default implementation stores all
-        session data in a signed cookie.  This requires that the
-        :attr:`secret_key` is set.
-
-        :param request: an instance of :attr:`request_class`.
-        """
-        key = self.secret_key
-        if key is not None:
-            return Session.load_cookie(request, self.session_cookie_name,
-                                       secret_key=key)
-
-    def save_session(self, session, response):
-        """Saves the session if it needs updates.  For the default
-        implementation, check :meth:`open_session`.
-
-        :param session: the session to be saved (a
-                        :class:`~werkzeug.contrib.securecookie.SecureCookie`
-                        object)
-        :param response: an instance of :attr:`response_class`
-        """
-        expires = None
-        if session.permanent:
-            expires = datetime.utcnow() + self.permanent_session_lifetime
-        session.save_cookie(response, self.session_cookie_name,
-                            expires=expires, httponly=True)
-
-    def register_module(self, module, **options):
-        """Registers a module with this application.  The keyword argument
-        of this function are the same as the ones for the constructor of the
-        :class:`Module` class and will override the values of the module if
-        provided.
-        """
-        options.setdefault('url_prefix', module.url_prefix)
-        state = _ModuleSetupState(self, **options)
-        for func in module._register_events:
-            func(state)
-
-    def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
-        """Connects a URL rule.  Works exactly like the :meth:`route`
-        decorator.  If a view_func is provided it will be registered with the
-        endpoint.
-
-        Basically this example::
-
-            @app.route('/')
-            def index():
-                pass
-
-        Is equivalent to the following::
-
-            def index():
-                pass
-            app.add_url_rule('/', 'index', index)
-
-        If the view_func is not provided you will need to connect the endpoint
-        to a view function like so::
-
-            app.view_functions['index'] = index
-
-        .. versionchanged:: 0.2
-           `view_func` parameter added.
-
-        :param rule: the URL rule as string
-        :param endpoint: the endpoint for the registered URL rule.  Flask
-                         itself assumes the name of the view function as
-                         endpoint
-        :param view_func: the function to call when serving a request to the
-                          provided endpoint
-        :param options: the options to be forwarded to the underlying
-                        :class:`~werkzeug.routing.Rule` object
-        """
-        if endpoint is None:
-            assert view_func is not None, 'expected view func if endpoint ' \
-                                          'is not provided.'
-            endpoint = view_func.__name__
-        options['endpoint'] = endpoint
-        options.setdefault('methods', ('GET',))
-        self.url_map.add(Rule(rule, **options))
-        if view_func is not None:
-            self.view_functions[endpoint] = view_func
-
-    def route(self, rule, **options):
-        """A decorator that is used to register a view function for a
-        given URL rule.  Example::
-
-            @app.route('/')
-            def index():
-                return 'Hello World'
-
-        Variables parts in the route can be specified with angular
-        brackets (``/user/<username>``).  By default a variable part
-        in the URL accepts any string without a slash however a different
-        converter can be specified as well by using ``<converter:name>``.
-
-        Variable parts are passed to the view function as keyword
-        arguments.
-
-        The following converters are possible:
-
-        =========== ===========================================
-        `int`       accepts integers
-        `float`     like `int` but for floating point values
-        `path`      like the default but also accepts slashes
-        =========== ===========================================
-
-        Here some examples::
-
-            @app.route('/')
-            def index():
-                pass
-
-            @app.route('/<username>')
-            def show_user(username):
-                pass
-
-            @app.route('/post/<int:post_id>')
-            def show_post(post_id):
-                pass
-
-        An important detail to keep in mind is how Flask deals with trailing
-        slashes.  The idea is to keep each URL unique so the following rules
-        apply:
-
-        1. If a rule ends with a slash and is requested without a slash
-           by the user, the user is automatically redirected to the same
-           page with a trailing slash attached.
-        2. If a rule does not end with a trailing slash and the user request
-           the page with a trailing slash, a 404 not found is raised.
-
-        This is consistent with how web servers deal with static files.  This
-        also makes it possible to use relative link targets safely.
-
-        The :meth:`route` decorator accepts a couple of other arguments
-        as well:
-
-        :param rule: the URL rule as string
-        :param methods: a list of methods this rule should be limited
-                        to (``GET``, ``POST`` etc.).  By default a rule
-                        just listens for ``GET`` (and implicitly ``HEAD``).
-        :param subdomain: specifies the rule for the subdoain in case
-                          subdomain matching is in use.
-        :param strict_slashes: can be used to disable the strict slashes
-                               setting for this rule.  See above.
-        :param options: other options to be forwarded to the underlying
-                        :class:`~werkzeug.routing.Rule` object.
-        """
-        def decorator(f):
-            self.add_url_rule(rule, None, f, **options)
-            return f
-        return decorator
-
-    def errorhandler(self, code):
-        """A decorator that is used to register a function give a given
-        error code.  Example::
-
-            @app.errorhandler(404)
-            def page_not_found(error):
-                return 'This page does not exist', 404
-
-        You can also register a function as error handler without using
-        the :meth:`errorhandler` decorator.  The following example is
-        equivalent to the one above::
-
-            def page_not_found(error):
-                return 'This page does not exist', 404
-            app.error_handlers[404] = page_not_found
-
-        :param code: the code as integer for the handler
-        """
-        def decorator(f):
-            self.error_handlers[code] = f
-            return f
-        return decorator
-
-    def template_filter(self, name=None):
-        """A decorator that is used to register custom template filter.
-        You can specify a name for the filter, otherwise the function
-        name will be used. Example::
-
-          @app.template_filter()
-          def reverse(s):
-              return s[::-1]
-
-        :param name: the optional name of the filter, otherwise the
-                     function name will be used.
-        """
-        def decorator(f):
-            self.jinja_env.filters[name or f.__name__] = f
-            return f
-        return decorator
-
-    def before_request(self, f):
-        """Registers a function to run before each request."""
-        self.before_request_funcs.setdefault(None, []).append(f)
-        return f
-
-    def after_request(self, f):
-        """Register a function to be run after each request."""
-        self.after_request_funcs.setdefault(None, []).append(f)
-        return f
-
-    def context_processor(self, f):
-        """Registers a template context processor function."""
-        self.template_context_processors[None].append(f)
-        return f
-
-    def handle_http_exception(self, e):
-        """Handles an HTTP exception.  By default this will invoke the
-        registered error handlers and fall back to returning the
-        exception as response.
-
-        .. versionadded: 0.3
-        """
-        handler = self.error_handlers.get(e.code)
-        if handler is None:
-            return e
-        return handler(e)
-
-    def handle_exception(self, e):
-        """Default exception handling that kicks in when an exception
-        occours that is not catched.  In debug mode the exception will
-        be re-raised immediately, otherwise it is logged and the handler
-        for a 500 internal server error is used.  If no such handler
-        exists, a default 500 internal server error message is displayed.
-
-        .. versionadded: 0.3
-        """
-        handler = self.error_handlers.get(500)
-        if self.debug:
-            raise
-        self.logger.exception('Exception on %s [%s]' % (
-            request.path,
-            request.method
-        ))
-        if handler is None:
-            return InternalServerError()
-        return handler(e)
-
-    def dispatch_request(self):
-        """Does the request dispatching.  Matches the URL and returns the
-        return value of the view or error handler.  This does not have to
-        be a response object.  In order to convert the return value to a
-        proper response object, call :func:`make_response`.
-        """
-        req = _request_ctx_stack.top.request
-        try:
-            if req.routing_exception is not None:
-                raise req.routing_exception
-            return self.view_functions[req.endpoint](**req.view_args)
-        except HTTPException, e:
-            return self.handle_http_exception(e)
-
-    def make_response(self, rv):
-        """Converts the return value from a view function to a real
-        response object that is an instance of :attr:`response_class`.
-
-        The following types are allowed for `rv`:
-
-        .. tabularcolumns:: |p{3.5cm}|p{9.5cm}|
-
-        ======================= ===========================================
-        :attr:`response_class`  the object is returned unchanged
-        :class:`str`            a response object is created with the
-                                string as body
-        :class:`unicode`        a response object is created with the
-                                string encoded to utf-8 as body
-        :class:`tuple`          the response object is created with the
-                                contents of the tuple as arguments
-        a WSGI function         the function is called as WSGI application
-                                and buffered as response object
-        ======================= ===========================================
-
-        :param rv: the return value from the view function
-        """
-        if rv is None:
-            raise ValueError('View function did not return a response')
-        if isinstance(rv, self.response_class):
-            return rv
-        if isinstance(rv, basestring):
-            return self.response_class(rv)
-        if isinstance(rv, tuple):
-            return self.response_class(*rv)
-        return self.response_class.force_type(rv, request.environ)
-
-    def preprocess_request(self):
-        """Called before the actual request dispatching and will
-        call every as :meth:`before_request` decorated function.
-        If any of these function returns a value it's handled as
-        if it was the return value from the view and further
-        request handling is stopped.
-        """
-        funcs = self.before_request_funcs.get(None, ())
-        mod = request.module
-        if mod and mod in self.before_request_funcs:
-            funcs = chain(funcs, self.before_request_funcs[mod])
-        for func in funcs:
-            rv = func()
-            if rv is not None:
-                return rv
-
-    def process_response(self, response):
-        """Can be overridden in order to modify the response object
-        before it's sent to the WSGI server.  By default this will
-        call all the :meth:`after_request` decorated functions.
-
-        :param response: a :attr:`response_class` object.
-        :return: a new response object or the same, has to be an
-                 instance of :attr:`response_class`.
-        """
-        ctx = _request_ctx_stack.top
-        mod = ctx.request.module
-        if not isinstance(ctx.session, _NullSession):
-            self.save_session(ctx.session, response)
-        funcs = ()
-        if mod and mod in self.after_request_funcs:
-            funcs = chain(funcs, self.after_request_funcs[mod])
-        if None in self.after_request_funcs:
-            funcs = chain(funcs, self.after_request_funcs[None])
-        for handler in funcs:
-            response = handler(response)
-        return response
-
-    def wsgi_app(self, environ, start_response):
-        """The actual WSGI application.  This is not implemented in
-        `__call__` so that middlewares can be applied without losing a
-        reference to the class.  So instead of doing this::
-
-            app = MyMiddleware(app)
-
-        It's a better idea to do this instead::
-
-            app.wsgi_app = MyMiddleware(app.wsgi_app)
-
-        Then you still have the original application object around and
-        can continue to call methods on it.
-
-        .. versionchanged:: 0.4
-           The :meth:`after_request` functions are now called even if an
-           error handler took over request processing.  This ensures that
-           even if an exception happens database have the chance to
-           properly close the connection.
-
-        :param environ: a WSGI environment
-        :param start_response: a callable accepting a status code,
-                               a list of headers and an optional
-                               exception context to start the response
-        """
-        with self.request_context(environ):
-            try:
-                rv = self.preprocess_request()
-                if rv is None:
-                    rv = self.dispatch_request()
-                response = self.make_response(rv)
-            except Exception, e:
-                response = self.make_response(self.handle_exception(e))
-            try:
-                response = self.process_response(response)
-            except Exception, e:
-                response = self.make_response(self.handle_exception(e))
-            return response(environ, start_response)
-
-    def request_context(self, environ):
-        """Creates a request context from the given environment and binds
-        it to the current context.  This must be used in combination with
-        the `with` statement because the request is only bound to the
-        current context for the duration of the `with` block.
-
-        Example usage::
-
-            with app.request_context(environ):
-                do_something_with(request)
-
-        The object returned can also be used without the `with` statement
-        which is useful for working in the shell.  The example above is
-        doing exactly the same as this code::
-
-            ctx = app.request_context(environ)
-            ctx.push()
-            try:
-                do_something_with(request)
-            finally:
-                ctx.pop()
-
-        The big advantage of this approach is that you can use it without
-        the try/finally statement in a shell for interactive testing:
-
-        >>> ctx = app.test_request_context()
-        >>> ctx.bind()
-        >>> request.path
-        u'/'
-        >>> ctx.unbind()
-
-        .. versionchanged:: 0.3
-           Added support for non-with statement usage and `with` statement
-           is now passed the ctx object.
-
-        :param environ: a WSGI environment
-        """
-        return _RequestContext(self, environ)
-
-    def test_request_context(self, *args, **kwargs):
-        """Creates a WSGI environment from the given values (see
-        :func:`werkzeug.create_environ` for more information, this
-        function accepts the same arguments).
-        """
-        return self.request_context(create_environ(*args, **kwargs))
-
-    def __call__(self, environ, start_response):
-        """Shortcut for :attr:`wsgi_app`."""
-        return self.wsgi_app(environ, start_response)
-
-
-# context locals
-_request_ctx_stack = LocalStack()
-current_app = LocalProxy(lambda: _request_ctx_stack.top.app)
-request = LocalProxy(lambda: _request_ctx_stack.top.request)
-session = LocalProxy(lambda: _request_ctx_stack.top.session)
-g = LocalProxy(lambda: _request_ctx_stack.top.g)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/__init__.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+"""
+    flask
+    ~~~~~
+
+    A microframework based on Werkzeug.  It's extensively documented
+    and follows best practice patterns.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+# utilities we import from Werkzeug and Jinja2 that are unused
+# in the module but are exported as public interface.
+from werkzeug import abort, redirect
+from jinja2 import Markup, escape
+
+from .app import Flask, Request, Response
+from .config import Config
+from .helpers import url_for, jsonify, json_available, flash, \
+    send_file, send_from_directory, get_flashed_messages, \
+    get_template_attribute, make_response
+from .globals import current_app, g, request, session, _request_ctx_stack
+from .module import Module
+from .templating import render_template, render_template_string
+from .session import Session
+
+# the signals
+from .signals import signals_available, template_rendered, request_started, \
+     request_finished, got_request_exception
+
+# only import json if it's available
+if json_available:
+    from .helpers import json
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/app.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,965 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.app
+    ~~~~~~~~~
+
+    This module implements the central WSGI application object.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from __future__ import with_statement
+
+from threading import Lock
+from datetime import timedelta, datetime
+from itertools import chain
+
+from jinja2 import Environment
+
+from werkzeug import ImmutableDict
+from werkzeug.routing import Map, Rule
+from werkzeug.exceptions import HTTPException, InternalServerError, \
+     MethodNotAllowed
+
+from .helpers import _PackageBoundObject, url_for, get_flashed_messages, \
+    _tojson_filter, _endpoint_from_view_func
+from .wrappers import Request, Response
+from .config import ConfigAttribute, Config
+from .ctx import _RequestContext
+from .globals import _request_ctx_stack, request
+from .session import Session, _NullSession
+from .module import _ModuleSetupState
+from .templating import _DispatchingJinjaLoader, \
+    _default_template_ctx_processor
+from .signals import request_started, request_finished, got_request_exception
+
+# a lock used for logger initialization
+_logger_lock = Lock()
+
+
+class Flask(_PackageBoundObject):
+    """The flask object implements a WSGI application and acts as the central
+    object.  It is passed the name of the module or package of the
+    application.  Once it is created it will act as a central registry for
+    the view functions, the URL rules, template configuration and much more.
+
+    The name of the package is used to resolve resources from inside the
+    package or the folder the module is contained in depending on if the
+    package parameter resolves to an actual python package (a folder with
+    an `__init__.py` file inside) or a standard module (just a `.py` file).
+
+    For more information about resource loading, see :func:`open_resource`.
+
+    Usually you create a :class:`Flask` instance in your main module or
+    in the `__init__.py` file of your package like this::
+
+        from flask import Flask
+        app = Flask(__name__)
+
+    .. admonition:: About the First Parameter
+
+        The idea of the first parameter is to give Flask an idea what
+        belongs to your application.  This name is used to find resources
+        on the file system, can be used by extensions to improve debugging
+        information and a lot more.
+
+        So it's important what you provide there.  If you are using a single
+        module, `__name__` is always the correct value.  If you however are
+        using a package, it's usually recommended to hardcode the name of
+        your package there.
+
+        For example if your application is defined in `yourapplication/app.py`
+        you should create it with one of the two versions below::
+
+            app = Flask('yourapplication')
+            app = Flask(__name__.split('.')[0])
+
+        Why is that?  The application will work even with `__name__`, thanks
+        to how resources are looked up.  However it will make debugging more
+        painful.  Certain extensions can make assumptions based on the
+        import name of your application.  For example the Flask-SQLAlchemy
+        extension will look for the code in your application that triggered
+        an SQL query in debug mode.  If the import name is not properly set
+        up, that debugging information is lost.  (For example it would only
+        pick up SQL queries in `yourapplicaiton.app` and not
+        `yourapplication.views.frontend`)
+
+    .. versionadded:: 0.5
+       The `static_path` parameter was added.
+
+    :param import_name: the name of the application package
+    :param static_path: can be used to specify a different path for the
+                        static files on the web.  Defaults to ``/static``.
+                        This does not affect the folder the files are served
+                        *from*.
+    """
+
+    #: The class that is used for request objects.  See :class:`~flask.Request`
+    #: for more information.
+    request_class = Request
+
+    #: The class that is used for response objects.  See
+    #: :class:`~flask.Response` for more information.
+    response_class = Response
+
+    #: Path for the static files.  If you don't want to use static files
+    #: you can set this value to `None` in which case no URL rule is added
+    #: and the development server will no longer serve any static files.
+    #:
+    #: This is the default used for application and modules unless a
+    #: different value is passed to the constructor.
+    static_path = '/static'
+
+    #: The debug flag.  Set this to `True` to enable debugging of the
+    #: application.  In debug mode the debugger will kick in when an unhandled
+    #: exception ocurrs and the integrated server will automatically reload
+    #: the application if changes in the code are detected.
+    #:
+    #: This attribute can also be configured from the config with the `DEBUG`
+    #: configuration key.  Defaults to `False`.
+    debug = ConfigAttribute('DEBUG')
+
+    #: The testing flask.  Set this to `True` to enable the test mode of
+    #: Flask extensions (and in the future probably also Flask itself).
+    #: For example this might activate unittest helpers that have an
+    #: additional runtime cost which should not be enabled by default.
+    #:
+    #: This attribute can also be configured from the config with the
+    #: `TESTING` configuration key.  Defaults to `False`.
+    testing = ConfigAttribute('TESTING')
+
+    #: If a secret key is set, cryptographic components can use this to
+    #: sign cookies and other things.  Set this to a complex random value
+    #: when you want to use the secure cookie for instance.
+    #:
+    #: This attribute can also be configured from the config with the
+    #: `SECRET_KEY` configuration key.  Defaults to `None`.
+    secret_key = ConfigAttribute('SECRET_KEY')
+
+    #: The secure cookie uses this for the name of the session cookie.
+    #:
+    #: This attribute can also be configured from the config with the
+    #: `SESSION_COOKIE_NAME` configuration key.  Defaults to ``'session'``
+    session_cookie_name = ConfigAttribute('SESSION_COOKIE_NAME')
+
+    #: A :class:`~datetime.timedelta` which is used to set the expiration
+    #: date of a permanent session.  The default is 31 days which makes a
+    #: permanent session survive for roughly one month.
+    #:
+    #: This attribute can also be configured from the config with the
+    #: `PERMANENT_SESSION_LIFETIME` configuration key.  Defaults to
+    #: ``timedelta(days=31)``
+    permanent_session_lifetime = ConfigAttribute('PERMANENT_SESSION_LIFETIME')
+
+    #: Enable this if you want to use the X-Sendfile feature.  Keep in
+    #: mind that the server has to support this.  This only affects files
+    #: sent with the :func:`send_file` method.
+    #:
+    #: .. versionadded:: 0.2
+    #:
+    #: This attribute can also be configured from the config with the
+    #: `USE_X_SENDFILE` configuration key.  Defaults to `False`.
+    use_x_sendfile = ConfigAttribute('USE_X_SENDFILE')
+
+    #: The name of the logger to use.  By default the logger name is the
+    #: package name passed to the constructor.
+    #:
+    #: .. versionadded:: 0.4
+    logger_name = ConfigAttribute('LOGGER_NAME')
+
+    #: The logging format used for the debug logger.  This is only used when
+    #: the application is in debug mode, otherwise the attached logging
+    #: handler does the formatting.
+    #:
+    #: .. versionadded:: 0.3
+    debug_log_format = (
+        '-' * 80 + '\n' +
+        '%(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n' +
+        '%(message)s\n' +
+        '-' * 80
+    )
+
+    #: Options that are passed directly to the Jinja2 environment.
+    jinja_options = ImmutableDict(
+        extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_']
+    )
+
+    #: Default configuration parameters.
+    default_config = ImmutableDict({
+        'DEBUG':                                False,
+        'TESTING':                              False,
+        'PROPAGATE_EXCEPTIONS':                 None,
+        'SECRET_KEY':                           None,
+        'SESSION_COOKIE_NAME':                  'session',
+        'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
+        'USE_X_SENDFILE':                       False,
+        'LOGGER_NAME':                          None,
+        'SERVER_NAME':                          None,
+        'MAX_CONTENT_LENGTH':                   None
+    })
+
+    #: the test client that is used with when `test_client` is used.
+    #:
+    #: .. versionadded:: 0.7
+    test_client_class = None
+
+    def __init__(self, import_name, static_path=None):
+        _PackageBoundObject.__init__(self, import_name)
+        if static_path is not None:
+            self.static_path = static_path
+
+        #: The configuration dictionary as :class:`Config`.  This behaves
+        #: exactly like a regular dictionary but supports additional methods
+        #: to load a config from files.
+        self.config = Config(self.root_path, self.default_config)
+
+        #: Prepare the deferred setup of the logger.
+        self._logger = None
+        self.logger_name = self.import_name
+
+        #: A dictionary of all view functions registered.  The keys will
+        #: be function names which are also used to generate URLs and
+        #: the values are the function objects themselves.
+        #: To register a view function, use the :meth:`route` decorator.
+        self.view_functions = {}
+
+        #: A dictionary of all registered error handlers.  The key is
+        #: be the error code as integer, the value the function that
+        #: should handle that error.
+        #: To register a error handler, use the :meth:`errorhandler`
+        #: decorator.
+        self.error_handlers = {}
+
+        #: A dictionary with lists of functions that should be called at the
+        #: beginning of the request.  The key of the dictionary is the name of
+        #: the module this function is active for, `None` for all requests.
+        #: This can for example be used to open database connections or
+        #: getting hold of the currently logged in user.  To register a
+        #: function here, use the :meth:`before_request` decorator.
+        self.before_request_funcs = {}
+
+        #: A dictionary with lists of functions that should be called after
+        #: each request.  The key of the dictionary is the name of the module
+        #: this function is active for, `None` for all requests.  This can for
+        #: example be used to open database connections or getting hold of the
+        #: currently logged in user.  To register a function here, use the
+        #: :meth:`after_request` decorator.
+        self.after_request_funcs = {}
+
+        #: A dictionary with list of functions that are called without argument
+        #: to populate the template context.  The key of the dictionary is the
+        #: name of the module this function is active for, `None` for all
+        #: requests.  Each returns a dictionary that the template context is
+        #: updated with.  To register a function here, use the
+        #: :meth:`context_processor` decorator.
+        self.template_context_processors = {
+            None: [_default_template_ctx_processor]
+        }
+
+        #: all the loaded modules in a dictionary by name.
+        #:
+        #: .. versionadded:: 0.5
+        self.modules = {}
+
+        #: a place where extensions can store application specific state.  For
+        #: example this is where an extension could store database engines and
+        #: similar things.  For backwards compatibility extensions should register
+        #: themselves like this::
+        #:
+        #:      if not hasattr(app, 'extensions'):
+        #:          app.extensions = {}
+        #:      app.extensions['extensionname'] = SomeObject()
+        #:
+        #: The key must match the name of the `flaskext` module.  For example in
+        #: case of a "Flask-Foo" extension in `flaskext.foo`, the key would be
+        #: ``'foo'``.
+        #:
+        #: .. versionadded:: 0.7
+        self.extensions = {}
+
+        #: The :class:`~werkzeug.routing.Map` for this instance.  You can use
+        #: this to change the routing converters after the class was created
+        #: but before any routes are connected.  Example::
+        #:
+        #:    from werkzeug.routing import BaseConverter
+        #:
+        #:    class ListConverter(BaseConverter):
+        #:        def to_python(self, value):
+        #:            return value.split(',')
+        #:        def to_url(self, values):
+        #:            return ','.join(BaseConverter.to_url(value)
+        #:                            for value in values)
+        #:
+        #:    app = Flask(__name__)
+        #:    app.url_map.converters['list'] = ListConverter
+        self.url_map = Map()
+
+        # register the static folder for the application.  Do that even
+        # if the folder does not exist.  First of all it might be created
+        # while the server is running (usually happens during development)
+        # but also because google appengine stores static files somewhere
+        # else when mapped with the .yml file.
+        self.add_url_rule(self.static_path + '/<path:filename>',
+                          endpoint='static',
+                          view_func=self.send_static_file)
+
+        #: The Jinja2 environment.  It is created from the
+        #: :attr:`jinja_options`.
+        self.jinja_env = self.create_jinja_environment()
+        self.init_jinja_globals()
+
+    @property
+    def propagate_exceptions(self):
+        """Returns the value of the `PROPAGATE_EXCEPTIONS` configuration
+        value in case it's set, otherwise a sensible default is returned.
+
+        .. versionadded:: 0.7
+        """
+        rv = self.config['PROPAGATE_EXCEPTIONS']
+        if rv is not None:
+            return rv
+        return self.testing or self.debug
+
+    @property
+    def logger(self):
+        """A :class:`logging.Logger` object for this application.  The
+        default configuration is to log to stderr if the application is
+        in debug mode.  This logger can be used to (surprise) log messages.
+        Here some examples::
+
+            app.logger.debug('A value for debugging')
+            app.logger.warning('A warning ocurred (%d apples)', 42)
+            app.logger.error('An error occoured')
+
+        .. versionadded:: 0.3
+        """
+        if self._logger and self._logger.name == self.logger_name:
+            return self._logger
+        with _logger_lock:
+            if self._logger and self._logger.name == self.logger_name:
+                return self._logger
+            from flask.logging import create_logger
+            self._logger = rv = create_logger(self)
+            return rv
+
+    def create_jinja_environment(self):
+        """Creates the Jinja2 environment based on :attr:`jinja_options`
+        and :meth:`select_jinja_autoescape`.
+
+        .. versionadded:: 0.5
+        """
+        options = dict(self.jinja_options)
+        if 'autoescape' not in options:
+            options['autoescape'] = self.select_jinja_autoescape
+        return Environment(loader=_DispatchingJinjaLoader(self), **options)
+
+    def init_jinja_globals(self):
+        """Called directly after the environment was created to inject
+        some defaults (like `url_for`, `get_flashed_messages` and the
+        `tojson` filter.
+
+        .. versionadded:: 0.5
+        """
+        self.jinja_env.globals.update(
+            url_for=url_for,
+            get_flashed_messages=get_flashed_messages
+        )
+        self.jinja_env.filters['tojson'] = _tojson_filter
+
+    def select_jinja_autoescape(self, filename):
+        """Returns `True` if autoescaping should be active for the given
+        template name.
+
+        .. versionadded:: 0.5
+        """
+        if filename is None:
+            return False
+        return filename.endswith(('.html', '.htm', '.xml', '.xhtml'))
+
+    def update_template_context(self, context):
+        """Update the template context with some commonly used variables.
+        This injects request, session, config and g into the template
+        context as well as everything template context processors want
+        to inject.  Note that the as of Flask 0.6, the original values
+        in the context will not be overriden if a context processor
+        decides to return a value with the same key.
+
+        :param context: the context as a dictionary that is updated in place
+                        to add extra variables.
+        """
+        funcs = self.template_context_processors[None]
+        mod = _request_ctx_stack.top.request.module
+        if mod is not None and mod in self.template_context_processors:
+            funcs = chain(funcs, self.template_context_processors[mod])
+        orig_ctx = context.copy()
+        for func in funcs:
+            context.update(func())
+        # make sure the original values win.  This makes it possible to
+        # easier add new variables in context processors without breaking
+        # existing views.
+        context.update(orig_ctx)
+
+    def run(self, host='127.0.0.1', port=5000, **options):
+        """Runs the application on a local development server.  If the
+        :attr:`debug` flag is set the server will automatically reload
+        for code changes and show a debugger in case an exception happened.
+
+        If you want to run the application in debug mode, but disable the
+        code execution on the interactive debugger, you can pass
+        ``use_evalex=False`` as parameter.  This will keep the debugger's
+        traceback screen active, but disable code execution.
+
+        .. admonition:: Keep in Mind
+
+           Flask will suppress any server error with a generic error page
+           unless it is in debug mode.  As such to enable just the
+           interactive debugger without the code reloading, you have to
+           invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``.
+           Setting ``use_debugger`` to `True` without being in debug mode
+           won't catch any exceptions because there won't be any to
+           catch.
+
+        :param host: the hostname to listen on.  set this to ``'0.0.0.0'``
+                     to have the server available externally as well.
+        :param port: the port of the webserver
+        :param options: the options to be forwarded to the underlying
+                        Werkzeug server.  See :func:`werkzeug.run_simple`
+                        for more information.
+        """
+        from werkzeug import run_simple
+        if 'debug' in options:
+            self.debug = options.pop('debug')
+        options.setdefault('use_reloader', self.debug)
+        options.setdefault('use_debugger', self.debug)
+        return run_simple(host, port, self, **options)
+
+    def test_client(self, use_cookies=True):
+        """Creates a test client for this application.  For information
+        about unit testing head over to :ref:`testing`.
+
+        The test client can be used in a `with` block to defer the closing down
+        of the context until the end of the `with` block.  This is useful if
+        you want to access the context locals for testing::
+
+            with app.test_client() as c:
+                rv = c.get('/?vodka=42')
+                assert request.args['vodka'] == '42'
+
+        .. versionchanged:: 0.4
+           added support for `with` block usage for the client.
+
+        .. versionadded:: 0.7
+           The `use_cookies` parameter was added as well as the ability
+           to override the client to be used by setting the
+           :attr:`test_client_class` attribute.
+        """
+        cls = self.test_client_class
+        if cls is None:
+            from flask.testing import FlaskClient as cls
+        return cls(self, self.response_class, use_cookies=use_cookies)
+
+    def open_session(self, request):
+        """Creates or opens a new session.  Default implementation stores all
+        session data in a signed cookie.  This requires that the
+        :attr:`secret_key` is set.
+
+        :param request: an instance of :attr:`request_class`.
+        """
+        key = self.secret_key
+        if key is not None:
+            return Session.load_cookie(request, self.session_cookie_name,
+                                       secret_key=key)
+
+    def save_session(self, session, response):
+        """Saves the session if it needs updates.  For the default
+        implementation, check :meth:`open_session`.
+
+        :param session: the session to be saved (a
+                        :class:`~werkzeug.contrib.securecookie.SecureCookie`
+                        object)
+        :param response: an instance of :attr:`response_class`
+        """
+        expires = domain = None
+        if session.permanent:
+            expires = datetime.utcnow() + self.permanent_session_lifetime
+        if self.config['SERVER_NAME'] is not None:
+            domain = '.' + self.config['SERVER_NAME']
+        session.save_cookie(response, self.session_cookie_name,
+                            expires=expires, httponly=True, domain=domain)
+
+    def register_module(self, module, **options):
+        """Registers a module with this application.  The keyword argument
+        of this function are the same as the ones for the constructor of the
+        :class:`Module` class and will override the values of the module if
+        provided.
+        """
+        options.setdefault('url_prefix', module.url_prefix)
+        options.setdefault('subdomain', module.subdomain)
+        self.view_functions.update(module.view_functions)
+        state = _ModuleSetupState(self, **options)
+        for func in module._register_events:
+            func(state)
+
+    def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
+        """Connects a URL rule.  Works exactly like the :meth:`route`
+        decorator.  If a view_func is provided it will be registered with the
+        endpoint.
+
+        Basically this example::
+
+            @app.route('/')
+            def index():
+                pass
+
+        Is equivalent to the following::
+
+            def index():
+                pass
+            app.add_url_rule('/', 'index', index)
+
+        If the view_func is not provided you will need to connect the endpoint
+        to a view function like so::
+
+            app.view_functions['index'] = index
+
+        .. versionchanged:: 0.2
+           `view_func` parameter added.
+
+        .. versionchanged:: 0.6
+           `OPTIONS` is added automatically as method.
+
+        :param rule: the URL rule as string
+        :param endpoint: the endpoint for the registered URL rule.  Flask
+                         itself assumes the name of the view function as
+                         endpoint
+        :param view_func: the function to call when serving a request to the
+                          provided endpoint
+        :param options: the options to be forwarded to the underlying
+                        :class:`~werkzeug.routing.Rule` object.  A change
+                        to Werkzeug is handling of method options.  methods
+                        is a list of methods this rule should be limited
+                        to (`GET`, `POST` etc.).  By default a rule
+                        just listens for `GET` (and implicitly `HEAD`).
+                        Starting with Flask 0.6, `OPTIONS` is implicitly
+                        added and handled by the standard request handling.
+        """
+        if endpoint is None:
+            endpoint = _endpoint_from_view_func(view_func)
+        options['endpoint'] = endpoint
+        methods = options.pop('methods', ('GET',))
+        provide_automatic_options = False
+        if 'OPTIONS' not in methods:
+            methods = tuple(methods) + ('OPTIONS',)
+            provide_automatic_options = True
+        rule = Rule(rule, methods=methods, **options)
+        rule.provide_automatic_options = provide_automatic_options
+        self.url_map.add(rule)
+        if view_func is not None:
+            self.view_functions[endpoint] = view_func
+
+    def route(self, rule, **options):
+        """A decorator that is used to register a view function for a
+        given URL rule.  Example::
+
+            @app.route('/')
+            def index():
+                return 'Hello World'
+
+        Variables parts in the route can be specified with angular
+        brackets (``/user/<username>``).  By default a variable part
+        in the URL accepts any string without a slash however a different
+        converter can be specified as well by using ``<converter:name>``.
+
+        Variable parts are passed to the view function as keyword
+        arguments.
+
+        The following converters are possible:
+
+        =========== ===========================================
+        `int`       accepts integers
+        `float`     like `int` but for floating point values
+        `path`      like the default but also accepts slashes
+        =========== ===========================================
+
+        Here some examples::
+
+            @app.route('/')
+            def index():
+                pass
+
+            @app.route('/<username>')
+            def show_user(username):
+                pass
+
+            @app.route('/post/<int:post_id>')
+            def show_post(post_id):
+                pass
+
+        An important detail to keep in mind is how Flask deals with trailing
+        slashes.  The idea is to keep each URL unique so the following rules
+        apply:
+
+        1. If a rule ends with a slash and is requested without a slash
+           by the user, the user is automatically redirected to the same
+           page with a trailing slash attached.
+        2. If a rule does not end with a trailing slash and the user request
+           the page with a trailing slash, a 404 not found is raised.
+
+        This is consistent with how web servers deal with static files.  This
+        also makes it possible to use relative link targets safely.
+
+        The :meth:`route` decorator accepts a couple of other arguments
+        as well:
+
+        :param rule: the URL rule as string
+        :param methods: a list of methods this rule should be limited
+                        to (`GET`, `POST` etc.).  By default a rule
+                        just listens for `GET` (and implicitly `HEAD`).
+                        Starting with Flask 0.6, `OPTIONS` is implicitly
+                        added and handled by the standard request handling.
+        :param subdomain: specifies the rule for the subdomain in case
+                          subdomain matching is in use.
+        :param strict_slashes: can be used to disable the strict slashes
+                               setting for this rule.  See above.
+        :param options: other options to be forwarded to the underlying
+                        :class:`~werkzeug.routing.Rule` object.
+        """
+        def decorator(f):
+            self.add_url_rule(rule, None, f, **options)
+            return f
+        return decorator
+
+
+    def endpoint(self, endpoint):
+        """A decorator to register a function as an endpoint.
+        Example::
+
+            @app.endpoint('example.endpoint')
+            def example():
+                return "example"
+
+        :param endpoint: the name of the endpoint
+        """
+        def decorator(f):
+            self.view_functions[endpoint] = f
+            return f
+        return decorator
+
+    def errorhandler(self, code):
+        """A decorator that is used to register a function give a given
+        error code.  Example::
+
+            @app.errorhandler(404)
+            def page_not_found(error):
+                return 'This page does not exist', 404
+
+        You can also register a function as error handler without using
+        the :meth:`errorhandler` decorator.  The following example is
+        equivalent to the one above::
+
+            def page_not_found(error):
+                return 'This page does not exist', 404
+            app.error_handlers[404] = page_not_found
+
+        :param code: the code as integer for the handler
+        """
+        def decorator(f):
+            self.error_handlers[code] = f
+            return f
+        return decorator
+
+    def template_filter(self, name=None):
+        """A decorator that is used to register custom template filter.
+        You can specify a name for the filter, otherwise the function
+        name will be used. Example::
+
+          @app.template_filter()
+          def reverse(s):
+              return s[::-1]
+
+        :param name: the optional name of the filter, otherwise the
+                     function name will be used.
+        """
+        def decorator(f):
+            self.jinja_env.filters[name or f.__name__] = f
+            return f
+        return decorator
+
+    def before_request(self, f):
+        """Registers a function to run before each request."""
+        self.before_request_funcs.setdefault(None, []).append(f)
+        return f
+
+    def after_request(self, f):
+        """Register a function to be run after each request."""
+        self.after_request_funcs.setdefault(None, []).append(f)
+        return f
+
+    def context_processor(self, f):
+        """Registers a template context processor function."""
+        self.template_context_processors[None].append(f)
+        return f
+
+    def handle_http_exception(self, e):
+        """Handles an HTTP exception.  By default this will invoke the
+        registered error handlers and fall back to returning the
+        exception as response.
+
+        .. versionadded: 0.3
+        """
+        handler = self.error_handlers.get(e.code)
+        if handler is None:
+            return e
+        return handler(e)
+
+    def handle_exception(self, e):
+        """Default exception handling that kicks in when an exception
+        occours that is not catched.  In debug mode the exception will
+        be re-raised immediately, otherwise it is logged and the handler
+        for a 500 internal server error is used.  If no such handler
+        exists, a default 500 internal server error message is displayed.
+
+        .. versionadded: 0.3
+        """
+        got_request_exception.send(self, exception=e)
+        handler = self.error_handlers.get(500)
+        if self.propagate_exceptions:
+            raise
+        self.logger.exception('Exception on %s [%s]' % (
+            request.path,
+            request.method
+        ))
+        if handler is None:
+            return InternalServerError()
+        return handler(e)
+
+    def dispatch_request(self):
+        """Does the request dispatching.  Matches the URL and returns the
+        return value of the view or error handler.  This does not have to
+        be a response object.  In order to convert the return value to a
+        proper response object, call :func:`make_response`.
+        """
+        req = _request_ctx_stack.top.request
+        try:
+            if req.routing_exception is not None:
+                raise req.routing_exception
+            rule = req.url_rule
+            # if we provide automatic options for this URL and the
+            # request came with the OPTIONS method, reply automatically
+            if getattr(rule, 'provide_automatic_options', False) \
+               and req.method == 'OPTIONS':
+                return self.make_default_options_response()
+            # otherwise dispatch to the handler for that endpoint
+            return self.view_functions[rule.endpoint](**req.view_args)
+        except HTTPException, e:
+            return self.handle_http_exception(e)
+
+    def make_default_options_response(self):
+        """This method is called to create the default `OPTIONS` response.
+        This can be changed through subclassing to change the default
+        behaviour of `OPTIONS` responses.
+
+        .. versionadded:: 0.7
+        """
+        # This would be nicer in Werkzeug 0.7, which however currently
+        # is not released.  Werkzeug 0.7 provides a method called
+        # allowed_methods() that returns all methods that are valid for
+        # a given path.
+        methods = []
+        try:
+            _request_ctx_stack.top.url_adapter.match(method='--')
+        except MethodNotAllowed, e:
+            methods = e.valid_methods
+        except HTTPException, e:
+            pass
+        rv = self.response_class()
+        rv.allow.update(methods)
+        return rv
+
+    def make_response(self, rv):
+        """Converts the return value from a view function to a real
+        response object that is an instance of :attr:`response_class`.
+
+        The following types are allowed for `rv`:
+
+        .. tabularcolumns:: |p{3.5cm}|p{9.5cm}|
+
+        ======================= ===========================================
+        :attr:`response_class`  the object is returned unchanged
+        :class:`str`            a response object is created with the
+                                string as body
+        :class:`unicode`        a response object is created with the
+                                string encoded to utf-8 as body
+        :class:`tuple`          the response object is created with the
+                                contents of the tuple as arguments
+        a WSGI function         the function is called as WSGI application
+                                and buffered as response object
+        ======================= ===========================================
+
+        :param rv: the return value from the view function
+        """
+        if rv is None:
+            raise ValueError('View function did not return a response')
+        if isinstance(rv, self.response_class):
+            return rv
+        if isinstance(rv, basestring):
+            return self.response_class(rv)
+        if isinstance(rv, tuple):
+            return self.response_class(*rv)
+        return self.response_class.force_type(rv, request.environ)
+
+    def create_url_adapter(self, request):
+        """Creates a URL adapter for the given request.  The URL adapter
+        is created at a point where the request context is not yet set up
+        so the request is passed explicitly.
+
+        .. versionadded:: 0.6
+        """
+        return self.url_map.bind_to_environ(request.environ,
+            server_name=self.config['SERVER_NAME'])
+
+    def preprocess_request(self):
+        """Called before the actual request dispatching and will
+        call every as :meth:`before_request` decorated function.
+        If any of these function returns a value it's handled as
+        if it was the return value from the view and further
+        request handling is stopped.
+        """
+        funcs = self.before_request_funcs.get(None, ())
+        mod = request.module
+        if mod and mod in self.before_request_funcs:
+            funcs = chain(funcs, self.before_request_funcs[mod])
+        for func in funcs:
+            rv = func()
+            if rv is not None:
+                return rv
+
+    def process_response(self, response):
+        """Can be overridden in order to modify the response object
+        before it's sent to the WSGI server.  By default this will
+        call all the :meth:`after_request` decorated functions.
+
+        .. versionchanged:: 0.5
+           As of Flask 0.5 the functions registered for after request
+           execution are called in reverse order of registration.
+
+        :param response: a :attr:`response_class` object.
+        :return: a new response object or the same, has to be an
+                 instance of :attr:`response_class`.
+        """
+        ctx = _request_ctx_stack.top
+        mod = ctx.request.module
+        if not isinstance(ctx.session, _NullSession):
+            self.save_session(ctx.session, response)
+        funcs = ()
+        if mod and mod in self.after_request_funcs:
+            funcs = reversed(self.after_request_funcs[mod])
+        if None in self.after_request_funcs:
+            funcs = chain(funcs, reversed(self.after_request_funcs[None]))
+        for handler in funcs:
+            response = handler(response)
+        return response
+
+    def request_context(self, environ):
+        """Creates a request context from the given environment and binds
+        it to the current context.  This must be used in combination with
+        the `with` statement because the request is only bound to the
+        current context for the duration of the `with` block.
+
+        Example usage::
+
+            with app.request_context(environ):
+                do_something_with(request)
+
+        The object returned can also be used without the `with` statement
+        which is useful for working in the shell.  The example above is
+        doing exactly the same as this code::
+
+            ctx = app.request_context(environ)
+            ctx.push()
+            try:
+                do_something_with(request)
+            finally:
+                ctx.pop()
+
+        The big advantage of this approach is that you can use it without
+        the try/finally statement in a shell for interactive testing:
+
+        >>> ctx = app.test_request_context()
+        >>> ctx.bind()
+        >>> request.path
+        u'/'
+        >>> ctx.unbind()
+
+        .. versionchanged:: 0.3
+           Added support for non-with statement usage and `with` statement
+           is now passed the ctx object.
+
+        :param environ: a WSGI environment
+        """
+        return _RequestContext(self, environ)
+
+    def test_request_context(self, *args, **kwargs):
+        """Creates a WSGI environment from the given values (see
+        :func:`werkzeug.create_environ` for more information, this
+        function accepts the same arguments).
+        """
+        from werkzeug import create_environ
+        environ_overrides = kwargs.setdefault('environ_overrides', {})
+        if self.config.get('SERVER_NAME'):
+            server_name = self.config.get('SERVER_NAME')
+            if ':' not in server_name:
+                http_host, http_port = server_name, '80'
+            else:
+                http_host, http_port = server_name.split(':', 1)
+
+            environ_overrides.setdefault('SERVER_NAME', server_name)
+            environ_overrides.setdefault('HTTP_HOST', server_name)
+            environ_overrides.setdefault('SERVER_PORT', http_port)
+        return self.request_context(create_environ(*args, **kwargs))
+
+    def wsgi_app(self, environ, start_response):
+        """The actual WSGI application.  This is not implemented in
+        `__call__` so that middlewares can be applied without losing a
+        reference to the class.  So instead of doing this::
+
+            app = MyMiddleware(app)
+
+        It's a better idea to do this instead::
+
+            app.wsgi_app = MyMiddleware(app.wsgi_app)
+
+        Then you still have the original application object around and
+        can continue to call methods on it.
+
+        .. versionchanged:: 0.4
+           The :meth:`after_request` functions are now called even if an
+           error handler took over request processing.  This ensures that
+           even if an exception happens database have the chance to
+           properly close the connection.
+
+        :param environ: a WSGI environment
+        :param start_response: a callable accepting a status code,
+                               a list of headers and an optional
+                               exception context to start the response
+        """
+        with self.request_context(environ):
+            try:
+                request_started.send(self)
+                rv = self.preprocess_request()
+                if rv is None:
+                    rv = self.dispatch_request()
+                response = self.make_response(rv)
+            except Exception, e:
+                response = self.make_response(self.handle_exception(e))
+            try:
+                response = self.process_response(response)
+            except Exception, e:
+                response = self.make_response(self.handle_exception(e))
+            request_finished.send(self, response=response)
+            return response(environ, start_response)
+
+    def __call__(self, environ, start_response):
+        """Shortcut for :attr:`wsgi_app`."""
+        return self.wsgi_app(environ, start_response)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/config.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,157 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.config
+    ~~~~~~~~~~~~
+
+    Implements the configuration related objects.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from __future__ import with_statement
+
+import imp
+import os
+import sys
+
+from werkzeug import import_string
+
+
+class ConfigAttribute(object):
+    """Makes an attribute forward to the config"""
+
+    def __init__(self, name):
+        self.__name__ = name
+
+    def __get__(self, obj, type=None):
+        if obj is None:
+            return self
+        return obj.config[self.__name__]
+
+    def __set__(self, obj, value):
+        obj.config[self.__name__] = value
+
+
+class Config(dict):
+    """Works exactly like a dict but provides ways to fill it from files
+    or special dictionaries.  There are two common patterns to populate the
+    config.
+
+    Either you can fill the config from a config file::
+
+        app.config.from_pyfile('yourconfig.cfg')
+
+    Or alternatively you can define the configuration options in the
+    module that calls :meth:`from_object` or provide an import path to
+    a module that should be loaded.  It is also possible to tell it to
+    use the same module and with that provide the configuration values
+    just before the call::
+
+        DEBUG = True
+        SECRET_KEY = 'development key'
+        app.config.from_object(__name__)
+
+    In both cases (loading from any Python file or loading from modules),
+    only uppercase keys are added to the config.  This makes it possible to use
+    lowercase values in the config file for temporary values that are not added
+    to the config or to define the config keys in the same file that implements
+    the application.
+
+    Probably the most interesting way to load configurations is from an
+    environment variable pointing to a file::
+
+        app.config.from_envvar('YOURAPPLICATION_SETTINGS')
+
+    In this case before launching the application you have to set this
+    environment variable to the file you want to use.  On Linux and OS X
+    use the export statement::
+
+        export YOURAPPLICATION_SETTINGS='/path/to/config/file'
+
+    On windows use `set` instead.
+
+    :param root_path: path to which files are read relative from.  When the
+                      config object is created by the application, this is
+                      the application's :attr:`~flask.Flask.root_path`.
+    :param defaults: an optional dictionary of default values
+    """
+
+    def __init__(self, root_path, defaults=None):
+        dict.__init__(self, defaults or {})
+        self.root_path = root_path
+
+    def from_envvar(self, variable_name, silent=False):
+        """Loads a configuration from an environment variable pointing to
+        a configuration file.  This basically is just a shortcut with nicer
+        error messages for this line of code::
+
+            app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS'])
+
+        :param variable_name: name of the environment variable
+        :param silent: set to `True` if you want silent failing for missing
+                       files.
+        :return: bool. `True` if able to load config, `False` otherwise.
+        """
+        rv = os.environ.get(variable_name)
+        if not rv:
+            if silent:
+                return False
+            raise RuntimeError('The environment variable %r is not set '
+                               'and as such configuration could not be '
+                               'loaded.  Set this variable and make it '
+                               'point to a configuration file' %
+                               variable_name)
+        self.from_pyfile(rv)
+        return True
+
+    def from_pyfile(self, filename):
+        """Updates the values in the config from a Python file.  This function
+        behaves as if the file was imported as module with the
+        :meth:`from_object` function.
+
+        :param filename: the filename of the config.  This can either be an
+                         absolute filename or a filename relative to the
+                         root path.
+        """
+        filename = os.path.join(self.root_path, filename)
+        d = imp.new_module('config')
+        d.__file__ = filename
+        try:
+            execfile(filename, d.__dict__)
+        except IOError, e:
+            e.strerror = 'Unable to load configuration file (%s)' % e.strerror
+            raise
+        self.from_object(d)
+
+    def from_object(self, obj):
+        """Updates the values from the given object.  An object can be of one
+        of the following two types:
+
+        -   a string: in this case the object with that name will be imported
+        -   an actual object reference: that object is used directly
+
+        Objects are usually either modules or classes.
+
+        Just the uppercase variables in that object are stored in the config
+        after lowercasing.  Example usage::
+
+            app.config.from_object('yourapplication.default_config')
+            from yourapplication import default_config
+            app.config.from_object(default_config)
+
+        You should not use this function to load the actual configuration but
+        rather configuration defaults.  The actual config should be loaded
+        with :meth:`from_pyfile` and ideally from a location not within the
+        package because the package might be installed system wide.
+
+        :param obj: an import name or object
+        """
+        if isinstance(obj, basestring):
+            obj = import_string(obj)
+        for key in dir(obj):
+            if key.isupper():
+                self[key] = getattr(obj, key)
+
+    def __repr__(self):
+        return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/ctx.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.ctx
+    ~~~~~~~~~
+
+    Implements the objects required to keep the context.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from werkzeug.exceptions import HTTPException
+
+from .globals import _request_ctx_stack
+from .session import _NullSession
+
+
+class _RequestGlobals(object):
+    pass
+
+
+class _RequestContext(object):
+    """The request context contains all request relevant information.  It is
+    created at the beginning of the request and pushed to the
+    `_request_ctx_stack` and removed at the end of it.  It will create the
+    URL adapter and request object for the WSGI environment provided.
+    """
+
+    def __init__(self, app, environ):
+        self.app = app
+        self.request = app.request_class(environ)
+        self.url_adapter = app.create_url_adapter(self.request)
+        self.session = app.open_session(self.request)
+        if self.session is None:
+            self.session = _NullSession()
+        self.g = _RequestGlobals()
+        self.flashes = None
+
+        try:
+            url_rule, self.request.view_args = \
+                self.url_adapter.match(return_rule=True)
+            self.request.url_rule = url_rule
+        except HTTPException, e:
+            self.request.routing_exception = e
+
+    def push(self):
+        """Binds the request context."""
+        _request_ctx_stack.push(self)
+
+    def pop(self):
+        """Pops the request context."""
+        _request_ctx_stack.pop()
+
+    def __enter__(self):
+        self.push()
+        return self
+
+    def __exit__(self, exc_type, exc_value, tb):
+        # do not pop the request stack if we are in debug mode and an
+        # exception happened.  This will allow the debugger to still
+        # access the request object in the interactive shell.  Furthermore
+        # the context can be force kept alive for the test client.
+        # See flask.testing for how this works.
+        if not self.request.environ.get('flask._preserve_context') and \
+           (tb is None or not self.app.debug):
+            self.pop()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/globals.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.globals
+    ~~~~~~~~~~~~~
+
+    Defines all the global objects that are proxies to the current
+    active context.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from functools import partial
+from werkzeug import LocalStack, LocalProxy
+
+def _lookup_object(name):
+    top = _request_ctx_stack.top
+    if top is None:
+        raise RuntimeError('working outside of request context')
+    return getattr(top, name)
+
+# context locals
+_request_ctx_stack = LocalStack()
+current_app = LocalProxy(partial(_lookup_object, 'app'))
+request = LocalProxy(partial(_lookup_object, 'request'))
+session = LocalProxy(partial(_lookup_object, 'session'))
+g = LocalProxy(partial(_lookup_object, 'g'))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/helpers.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,500 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.helpers
+    ~~~~~~~~~~~~~
+
+    Implements various helpers.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+import os
+import sys
+import posixpath
+import mimetypes
+from time import time
+from zlib import adler32
+
+# try to load the best simplejson implementation available.  If JSON
+# is not installed, we add a failing class.
+json_available = True
+json = None
+try:
+    import simplejson as json
+except ImportError:
+    try:
+        import json
+    except ImportError:
+        try:
+            # Google Appengine offers simplejson via django
+            from django.utils import simplejson as json
+        except ImportError:
+            json_available = False
+
+
+from werkzeug import Headers, wrap_file, cached_property
+from werkzeug.exceptions import NotFound
+
+from jinja2 import FileSystemLoader
+
+from .globals import session, _request_ctx_stack, current_app, request
+
+
+def _assert_have_json():
+    """Helper function that fails if JSON is unavailable."""
+    if not json_available:
+        raise RuntimeError('simplejson not installed')
+
+# figure out if simplejson escapes slashes.  This behaviour was changed
+# from one version to another without reason.
+if not json_available or '\\/' not in json.dumps('/'):
+
+    def _tojson_filter(*args, **kwargs):
+        if __debug__:
+            _assert_have_json()
+        return json.dumps(*args, **kwargs).replace('/', '\\/')
+else:
+    _tojson_filter = json.dumps
+
+
+# what separators does this operating system provide that are not a slash?
+# this is used by the send_from_directory function to ensure that nobody is
+# able to access files from outside the filesystem.
+_os_alt_seps = list(sep for sep in [os.path.sep, os.path.altsep]
+                    if sep not in (None, '/'))
+
+
+def _endpoint_from_view_func(view_func):
+    """Internal helper that returns the default endpoint for a given
+    function.  This always is the function name.
+    """
+    assert view_func is not None, 'expected view func if endpoint ' \
+                                  'is not provided.'
+    return view_func.__name__
+
+
+def jsonify(*args, **kwargs):
+    """Creates a :class:`~flask.Response` with the JSON representation of
+    the given arguments with an `application/json` mimetype.  The arguments
+    to this function are the same as to the :class:`dict` constructor.
+
+    Example usage::
+
+        @app.route('/_get_current_user')
+        def get_current_user():
+            return jsonify(username=g.user.username,
+                           email=g.user.email,
+                           id=g.user.id)
+
+    This will send a JSON response like this to the browser::
+
+        {
+            "username": "admin",
+            "email": "admin@localhost",
+            "id": 42
+        }
+
+    This requires Python 2.6 or an installed version of simplejson.  For
+    security reasons only objects are supported toplevel.  For more
+    information about this, have a look at :ref:`json-security`.
+
+    .. versionadded:: 0.2
+    """
+    if __debug__:
+        _assert_have_json()
+    return current_app.response_class(json.dumps(dict(*args, **kwargs),
+        indent=None if request.is_xhr else 2), mimetype='application/json')
+
+
+def make_response(*args):
+    """Sometimes it is necessary to set additional headers in a view.  Because
+    views do not have to return response objects but can return a value that
+    is converted into a response object by Flask itself, it becomes tricky to
+    add headers to it.  This function can be called instead of using a return
+    and you will get a response object which you can use to attach headers.
+
+    If view looked like this and you want to add a new header::
+
+        def index():
+            return render_template('index.html', foo=42)
+
+    You can now do something like this::
+
+        def index():
+            response = make_response(render_template('index.html', foo=42))
+            response.headers['X-Parachutes'] = 'parachutes are cool'
+            return response
+
+    This function accepts the very same arguments you can return from a
+    view function.  This for example creates a response with a 404 error
+    code::
+
+        response = make_response(render_template('not_found.html'), 404)
+
+    Internally this function does the following things:
+
+    -   if no arguments are passed, it creates a new response argument
+    -   if one argument is passed, :meth:`flask.Flask.make_response`
+        is invoked with it.
+    -   if more than one argument is passed, the arguments are passed
+        to the :meth:`flask.Flask.make_response` function as tuple.
+
+    .. versionadded:: 0.6
+    """
+    if not args:
+        return current_app.response_class()
+    if len(args) == 1:
+        args = args[0]
+    return current_app.make_response(args)
+
+
+def url_for(endpoint, **values):
+    """Generates a URL to the given endpoint with the method provided.
+    The endpoint is relative to the active module if modules are in use.
+
+    Here are some examples:
+
+    ==================== ======================= =============================
+    Active Module        Target Endpoint         Target Function
+    ==================== ======================= =============================
+    `None`               ``'index'``             `index` of the application
+    `None`               ``'.index'``            `index` of the application
+    ``'admin'``          ``'index'``             `index` of the `admin` module
+    any                  ``'.index'``            `index` of the application
+    any                  ``'admin.index'``       `index` of the `admin` module
+    ==================== ======================= =============================
+
+    Variable arguments that are unknown to the target endpoint are appended
+    to the generated URL as query arguments.
+
+    For more information, head over to the :ref:`Quickstart <url-building>`.
+
+    :param endpoint: the endpoint of the URL (name of the function)
+    :param values: the variable arguments of the URL rule
+    :param _external: if set to `True`, an absolute URL is generated.
+    """
+    ctx = _request_ctx_stack.top
+    if '.' not in endpoint:
+        mod = ctx.request.module
+        if mod is not None:
+            endpoint = mod + '.' + endpoint
+    elif endpoint.startswith('.'):
+        endpoint = endpoint[1:]
+    external = values.pop('_external', False)
+    return ctx.url_adapter.build(endpoint, values, force_external=external)
+
+
+def get_template_attribute(template_name, attribute):
+    """Loads a macro (or variable) a template exports.  This can be used to
+    invoke a macro from within Python code.  If you for example have a
+    template named `_cider.html` with the following contents:
+
+    .. sourcecode:: html+jinja
+
+       {% macro hello(name) %}Hello {{ name }}!{% endmacro %}
+
+    You can access this from Python code like this::
+
+        hello = get_template_attribute('_cider.html', 'hello')
+        return hello('World')
+
+    .. versionadded:: 0.2
+
+    :param template_name: the name of the template
+    :param attribute: the name of the variable of macro to acccess
+    """
+    return getattr(current_app.jinja_env.get_template(template_name).module,
+                   attribute)
+
+
+def flash(message, category='message'):
+    """Flashes a message to the next request.  In order to remove the
+    flashed message from the session and to display it to the user,
+    the template has to call :func:`get_flashed_messages`.
+
+    .. versionchanged: 0.3
+       `category` parameter added.
+
+    :param message: the message to be flashed.
+    :param category: the category for the message.  The following values
+                     are recommended: ``'message'`` for any kind of message,
+                     ``'error'`` for errors, ``'info'`` for information
+                     messages and ``'warning'`` for warnings.  However any
+                     kind of string can be used as category.
+    """
+    session.setdefault('_flashes', []).append((category, message))
+
+
+def get_flashed_messages(with_categories=False):
+    """Pulls all flashed messages from the session and returns them.
+    Further calls in the same request to the function will return
+    the same messages.  By default just the messages are returned,
+    but when `with_categories` is set to `True`, the return value will
+    be a list of tuples in the form ``(category, message)`` instead.
+
+    Example usage:
+
+    .. sourcecode:: html+jinja
+
+        {% for category, msg in get_flashed_messages(with_categories=true) %}
+          <p class=flash-{{ category }}>{{ msg }}
+        {% endfor %}
+
+    .. versionchanged:: 0.3
+       `with_categories` parameter added.
+
+    :param with_categories: set to `True` to also receive categories.
+    """
+    flashes = _request_ctx_stack.top.flashes
+    if flashes is None:
+        _request_ctx_stack.top.flashes = flashes = session.pop('_flashes', [])
+    if not with_categories:
+        return [x[1] for x in flashes]
+    return flashes
+
+
+def send_file(filename_or_fp, mimetype=None, as_attachment=False,
+              attachment_filename=None, add_etags=True,
+              cache_timeout=60 * 60 * 12, conditional=False):
+    """Sends the contents of a file to the client.  This will use the
+    most efficient method available and configured.  By default it will
+    try to use the WSGI server's file_wrapper support.  Alternatively
+    you can set the application's :attr:`~Flask.use_x_sendfile` attribute
+    to ``True`` to directly emit an `X-Sendfile` header.  This however
+    requires support of the underlying webserver for `X-Sendfile`.
+
+    By default it will try to guess the mimetype for you, but you can
+    also explicitly provide one.  For extra security you probably want
+    to send certain files as attachment (HTML for instance).  The mimetype
+    guessing requires a `filename` or an `attachment_filename` to be
+    provided.
+
+    Please never pass filenames to this function from user sources without
+    checking them first.  Something like this is usually sufficient to
+    avoid security problems::
+
+        if '..' in filename or filename.startswith('/'):
+            abort(404)
+
+    .. versionadded:: 0.2
+
+    .. versionadded:: 0.5
+       The `add_etags`, `cache_timeout` and `conditional` parameters were
+       added.  The default behaviour is now to attach etags.
+
+    .. versionchanged:: 0.7
+       mimetype guessing and etag support for file objects was
+       deprecated because it was unreliable.  Pass a filename if you are
+       able to, otherwise attach an etag yourself.  This functionality
+       will be removed in Flask 1.0
+
+    :param filename_or_fp: the filename of the file to send.  This is
+                           relative to the :attr:`~Flask.root_path` if a
+                           relative path is specified.
+                           Alternatively a file object might be provided
+                           in which case `X-Sendfile` might not work and
+                           fall back to the traditional method.  Make sure
+                           that the file pointer is positioned at the start
+                           of data to send before calling :func:`send_file`.
+    :param mimetype: the mimetype of the file if provided, otherwise
+                     auto detection happens.
+    :param as_attachment: set to `True` if you want to send this file with
+                          a ``Content-Disposition: attachment`` header.
+    :param attachment_filename: the filename for the attachment if it
+                                differs from the file's filename.
+    :param add_etags: set to `False` to disable attaching of etags.
+    :param conditional: set to `True` to enable conditional responses.
+    :param cache_timeout: the timeout in seconds for the headers.
+    """
+    mtime = None
+    if isinstance(filename_or_fp, basestring):
+        filename = filename_or_fp
+        file = None
+    else:
+        from warnings import warn
+        file = filename_or_fp
+        filename = getattr(file, 'name', None)
+
+        # XXX: this behaviour is now deprecated because it was unreliable.
+        # removed in Flask 1.0
+        if not attachment_filename and not mimetype \
+           and isinstance(filename, basestring):
+            warn(DeprecationWarning('The filename support for file objects '
+                'passed to send_file is not deprecated.  Pass an '
+                'attach_filename if you want mimetypes to be guessed.'),
+                stacklevel=2)
+        if add_etags:
+            warn(DeprecationWarning('In future flask releases etags will no '
+                'longer be generated for file objects passed to the send_file '
+                'function because this behaviour was unreliable.  Pass '
+                'filenames instead if possible, otherwise attach an etag '
+                'yourself based on another value'), stacklevel=2)
+
+    if filename is not None:
+        if not os.path.isabs(filename):
+            filename = os.path.join(current_app.root_path, filename)
+    if mimetype is None and (filename or attachment_filename):
+        mimetype = mimetypes.guess_type(filename or attachment_filename)[0]
+    if mimetype is None:
+        mimetype = 'application/octet-stream'
+
+    headers = Headers()
+    if as_attachment:
+        if attachment_filename is None:
+            if filename is None:
+                raise TypeError('filename unavailable, required for '
+                                'sending as attachment')
+            attachment_filename = os.path.basename(filename)
+        headers.add('Content-Disposition', 'attachment',
+                    filename=attachment_filename)
+
+    if current_app.use_x_sendfile and filename:
+        if file is not None:
+            file.close()
+        headers['X-Sendfile'] = filename
+        data = None
+    else:
+        if file is None:
+            file = open(filename, 'rb')
+            mtime = os.path.getmtime(filename)
+        data = wrap_file(request.environ, file)
+
+    rv = current_app.response_class(data, mimetype=mimetype, headers=headers,
+                                    direct_passthrough=True)
+
+    # if we know the file modification date, we can store it as the
+    # current time to better support conditional requests.  Werkzeug
+    # as of 0.6.1 will override this value however in the conditional
+    # response with the current time.  This will be fixed in Werkzeug
+    # with a new release, however many WSGI servers will still emit
+    # a separate date header.
+    if mtime is not None:
+        rv.date = int(mtime)
+
+    rv.cache_control.public = True
+    if cache_timeout:
+        rv.cache_control.max_age = cache_timeout
+        rv.expires = int(time() + cache_timeout)
+
+    if add_etags and filename is not None:
+        rv.set_etag('flask-%s-%s-%s' % (
+            os.path.getmtime(filename),
+            os.path.getsize(filename),
+            adler32(filename) & 0xffffffff
+        ))
+        if conditional:
+            rv = rv.make_conditional(request)
+            # make sure we don't send x-sendfile for servers that
+            # ignore the 304 status code for x-sendfile.
+            if rv.status_code == 304:
+                rv.headers.pop('x-sendfile', None)
+    return rv
+
+
+def send_from_directory(directory, filename, **options):
+    """Send a file from a given directory with :func:`send_file`.  This
+    is a secure way to quickly expose static files from an upload folder
+    or something similar.
+
+    Example usage::
+
+        @app.route('/uploads/<path:filename>')
+        def download_file(filename):
+            return send_from_directory(app.config['UPLOAD_FOLDER'],
+                                       filename, as_attachment=True)
+
+    .. admonition:: Sending files and Performance
+
+       It is strongly recommended to activate either `X-Sendfile` support in
+       your webserver or (if no authentication happens) to tell the webserver
+       to serve files for the given path on its own without calling into the
+       web application for improved performance.
+
+    .. versionadded:: 0.5
+
+    :param directory: the directory where all the files are stored.
+    :param filename: the filename relative to that directory to
+                     download.
+    :param options: optional keyword arguments that are directly
+                    forwarded to :func:`send_file`.
+    """
+    filename = posixpath.normpath(filename)
+    for sep in _os_alt_seps:
+        if sep in filename:
+            raise NotFound()
+    if os.path.isabs(filename) or filename.startswith('../'):
+        raise NotFound()
+    filename = os.path.join(directory, filename)
+    if not os.path.isfile(filename):
+        raise NotFound()
+    return send_file(filename, conditional=True, **options)
+
+
+def _get_package_path(name):
+    """Returns the path to a package or cwd if that cannot be found."""
+    try:
+        return os.path.abspath(os.path.dirname(sys.modules[name].__file__))
+    except (KeyError, AttributeError):
+        return os.getcwd()
+
+
+class _PackageBoundObject(object):
+
+    def __init__(self, import_name):
+        #: The name of the package or module.  Do not change this once
+        #: it was set by the constructor.
+        self.import_name = import_name
+
+        #: Where is the app root located?
+        self.root_path = _get_package_path(self.import_name)
+
+    @property
+    def has_static_folder(self):
+        """This is `True` if the package bound object's container has a
+        folder named ``'static'``.
+
+        .. versionadded:: 0.5
+        """
+        return os.path.isdir(os.path.join(self.root_path, 'static'))
+
+    @cached_property
+    def jinja_loader(self):
+        """The Jinja loader for this package bound object.
+
+        .. versionadded:: 0.5
+        """
+        return FileSystemLoader(os.path.join(self.root_path, 'templates'))
+
+    def send_static_file(self, filename):
+        """Function used internally to send static files from the static
+        folder to the browser.
+
+        .. versionadded:: 0.5
+        """
+        return send_from_directory(os.path.join(self.root_path, 'static'),
+                                   filename)
+
+    def open_resource(self, resource):
+        """Opens a resource from the application's resource folder.  To see
+        how this works, consider the following folder structure::
+
+            /myapplication.py
+            /schema.sql
+            /static
+                /style.css
+            /templates
+                /layout.html
+                /index.html
+
+        If you want to open the `schema.sql` file you would do the
+        following::
+
+            with app.open_resource('schema.sql') as f:
+                contents = f.read()
+                do_something_with(contents)
+
+        :param resource: the name of the resource.  To access resources within
+                         subfolders use forward slashes as separator.
+        """
+        return open(os.path.join(self.root_path, resource), 'rb')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/logging.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.logging
+    ~~~~~~~~~~~~~
+
+    Implements the logging support for Flask.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from __future__ import absolute_import
+
+from logging import getLogger, StreamHandler, Formatter, Logger, DEBUG
+
+
+def create_logger(app):
+    """Creates a logger for the given application.  This logger works
+    similar to a regular Python logger but changes the effective logging
+    level based on the application's debug flag.  Furthermore this
+    function also removes all attached handlers in case there was a
+    logger with the log name before.
+    """
+
+    class DebugLogger(Logger):
+        def getEffectiveLevel(x):
+            return DEBUG if app.debug else Logger.getEffectiveLevel(x)
+
+    class DebugHandler(StreamHandler):
+        def emit(x, record):
+            StreamHandler.emit(x, record) if app.debug else None
+
+    handler = DebugHandler()
+    handler.setLevel(DEBUG)
+    handler.setFormatter(Formatter(app.debug_log_format))
+    logger = getLogger(app.logger_name)
+    # just in case that was not a new logger, get rid of all the handlers
+    # already attached to it.
+    del logger.handlers[:]
+    logger.__class__ = DebugLogger
+    logger.addHandler(handler)
+    return logger
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/module.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,230 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.module
+    ~~~~~~~~~~~~
+
+    Implements a class that represents module blueprints.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from .helpers import _PackageBoundObject, _endpoint_from_view_func
+
+
+def _register_module(module, static_path):
+    """Internal helper function that returns a function for recording
+    that registers the `send_static_file` function for the module on
+    the application if necessary.  It also registers the module on
+    the application.
+    """
+    def _register(state):
+        state.app.modules[module.name] = module
+        # do not register the rule if the static folder of the
+        # module is the same as the one from the application.
+        if state.app.root_path == module.root_path:
+            return
+        path = static_path
+        if path is None:
+            path = state.app.static_path
+        if state.url_prefix:
+            path = state.url_prefix + path
+        state.app.add_url_rule(path + '/<path:filename>',
+                               endpoint='%s.static' % module.name,
+                               view_func=module.send_static_file,
+                               subdomain=state.subdomain)
+    return _register
+
+
+class _ModuleSetupState(object):
+
+    def __init__(self, app, url_prefix=None, subdomain=None):
+        self.app = app
+        self.url_prefix = url_prefix
+        self.subdomain = subdomain
+
+
+class Module(_PackageBoundObject):
+    """Container object that enables pluggable applications.  A module can
+    be used to organize larger applications.  They represent blueprints that,
+    in combination with a :class:`Flask` object are used to create a large
+    application.
+
+    A module is like an application bound to an `import_name`.  Multiple
+    modules can share the same import names, but in that case a `name` has
+    to be provided to keep them apart.  If different import names are used,
+    the rightmost part of the import name is used as name.
+
+    Here's an example structure for a larger application::
+
+        /myapplication
+            /__init__.py
+            /views
+                /__init__.py
+                /admin.py
+                /frontend.py
+
+    The `myapplication/__init__.py` can look like this::
+
+        from flask import Flask
+        from myapplication.views.admin import admin
+        from myapplication.views.frontend import frontend
+
+        app = Flask(__name__)
+        app.register_module(admin, url_prefix='/admin')
+        app.register_module(frontend)
+
+    And here's an example view module (`myapplication/views/admin.py`)::
+
+        from flask import Module
+
+        admin = Module(__name__)
+
+        @admin.route('/')
+        def index():
+            pass
+
+        @admin.route('/login')
+        def login():
+            pass
+
+    For a gentle introduction into modules, checkout the
+    :ref:`working-with-modules` section.
+
+    .. versionadded:: 0.5
+       The `static_path` parameter was added and it's now possible for
+       modules to refer to their own templates and static files.  See
+       :ref:`modules-and-resources` for more information.
+
+    .. versionadded:: 0.6
+       The `subdomain` parameter was added.
+
+    :param import_name: the name of the Python package or module
+                        implementing this :class:`Module`.
+    :param name: the internal short name for the module.  Unless specified
+                 the rightmost part of the import name
+    :param url_prefix: an optional string that is used to prefix all the
+                       URL rules of this module.  This can also be specified
+                       when registering the module with the application.
+    :param subdomain: used to set the subdomain setting for URL rules that
+                      do not have a subdomain setting set.
+    :param static_path: can be used to specify a different path for the
+                        static files on the web.  Defaults to ``/static``.
+                        This does not affect the folder the files are served
+                        *from*.
+    """
+
+    def __init__(self, import_name, name=None, url_prefix=None,
+                 static_path=None, subdomain=None):
+        if name is None:
+            assert '.' in import_name, 'name required if package name ' \
+                'does not point to a submodule'
+            name = import_name.rsplit('.', 1)[1]
+        _PackageBoundObject.__init__(self, import_name)
+        self.name = name
+        self.url_prefix = url_prefix
+        self.subdomain = subdomain
+        self.view_functions = {}
+        self._register_events = [_register_module(self, static_path)]
+
+    def route(self, rule, **options):
+        """Like :meth:`Flask.route` but for a module.  The endpoint for the
+        :func:`url_for` function is prefixed with the name of the module.
+        """
+        def decorator(f):
+            self.add_url_rule(rule, f.__name__, f, **options)
+            return f
+        return decorator
+
+    def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
+        """Like :meth:`Flask.add_url_rule` but for a module.  The endpoint for
+        the :func:`url_for` function is prefixed with the name of the module.
+
+        .. versionchanged:: 0.6
+           The `endpoint` argument is now optional and will default to the
+           function name to consistent with the function of the same name
+           on the application object.
+        """
+        def register_rule(state):
+            the_rule = rule
+            if state.url_prefix:
+                the_rule = state.url_prefix + rule
+            options.setdefault('subdomain', state.subdomain)
+            the_endpoint = endpoint
+            if the_endpoint is None:
+                the_endpoint = _endpoint_from_view_func(view_func)
+            state.app.add_url_rule(the_rule, '%s.%s' % (self.name,
+                                                        the_endpoint),
+                                   view_func, **options)
+        self._record(register_rule)
+
+    def endpoint(self, endpoint):
+        """Like :meth:`Flask.endpoint` but for a module."""
+        def decorator(f):
+            self.view_functions[endpoint] = f
+            return f
+        return decorator
+
+    def before_request(self, f):
+        """Like :meth:`Flask.before_request` but for a module.  This function
+        is only executed before each request that is handled by a function of
+        that module.
+        """
+        self._record(lambda s: s.app.before_request_funcs
+            .setdefault(self.name, []).append(f))
+        return f
+
+    def before_app_request(self, f):
+        """Like :meth:`Flask.before_request`.  Such a function is executed
+        before each request, even if outside of a module.
+        """
+        self._record(lambda s: s.app.before_request_funcs
+            .setdefault(None, []).append(f))
+        return f
+
+    def after_request(self, f):
+        """Like :meth:`Flask.after_request` but for a module.  This function
+        is only executed after each request that is handled by a function of
+        that module.
+        """
+        self._record(lambda s: s.app.after_request_funcs
+            .setdefault(self.name, []).append(f))
+        return f
+
+    def after_app_request(self, f):
+        """Like :meth:`Flask.after_request` but for a module.  Such a function
+        is executed after each request, even if outside of the module.
+        """
+        self._record(lambda s: s.app.after_request_funcs
+            .setdefault(None, []).append(f))
+        return f
+
+    def context_processor(self, f):
+        """Like :meth:`Flask.context_processor` but for a module.  This
+        function is only executed for requests handled by a module.
+        """
+        self._record(lambda s: s.app.template_context_processors
+            .setdefault(self.name, []).append(f))
+        return f
+
+    def app_context_processor(self, f):
+        """Like :meth:`Flask.context_processor` but for a module.  Such a
+        function is executed each request, even if outside of the module.
+        """
+        self._record(lambda s: s.app.template_context_processors
+            .setdefault(None, []).append(f))
+        return f
+
+    def app_errorhandler(self, code):
+        """Like :meth:`Flask.errorhandler` but for a module.  This
+        handler is used for all requests, even if outside of the module.
+
+        .. versionadded:: 0.4
+        """
+        def decorator(f):
+            self._record(lambda s: s.app.errorhandler(code)(f))
+            return f
+        return decorator
+
+    def _record(self, func):
+        self._register_events.append(func)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/session.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.session
+    ~~~~~~~~~~~~~
+
+    Implements cookie based sessions based on Werkzeug's secure cookie
+    system.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from werkzeug.contrib.securecookie import SecureCookie
+
+
+class Session(SecureCookie):
+    """Expands the session with support for switching between permanent
+    and non-permanent sessions.
+    """
+
+    def _get_permanent(self):
+        return self.get('_permanent', False)
+
+    def _set_permanent(self, value):
+        self['_permanent'] = bool(value)
+
+    permanent = property(_get_permanent, _set_permanent)
+    del _get_permanent, _set_permanent
+
+
+class _NullSession(Session):
+    """Class used to generate nicer error messages if sessions are not
+    available.  Will still allow read-only access to the empty session
+    but fail on setting.
+    """
+
+    def _fail(self, *args, **kwargs):
+        raise RuntimeError('the session is unavailable because no secret '
+                           'key was set.  Set the secret_key on the '
+                           'application to something unique and secret.')
+    __setitem__ = __delitem__ = clear = pop = popitem = \
+        update = setdefault = _fail
+    del _fail
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/signals.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.signals
+    ~~~~~~~~~~~~~
+
+    Implements signals based on blinker if available, otherwise
+    falls silently back to a noop
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+signals_available = False
+try:
+    from blinker import Namespace
+    signals_available = True
+except ImportError:
+    class Namespace(object):
+        def signal(self, name, doc=None):
+            return _FakeSignal(name, doc)
+
+    class _FakeSignal(object):
+        """If blinker is unavailable, create a fake class with the same
+        interface that allows sending of signals but will fail with an
+        error on anything else.  Instead of doing anything on send, it
+        will just ignore the arguments and do nothing instead.
+        """
+
+        def __init__(self, name, doc=None):
+            self.name = name
+            self.__doc__ = doc
+        def _fail(self, *args, **kwargs):
+            raise RuntimeError('signalling support is unavailable '
+                               'because the blinker library is '
+                               'not installed.')
+        send = lambda *a, **kw: None
+        connect = disconnect = has_receivers_for = receivers_for = \
+            temporarily_connected_to = _fail
+        del _fail
+
+# the namespace for code signals.  If you are not flask code, do
+# not put signals in here.  Create your own namespace instead.
+_signals = Namespace()
+
+
+# core signals.  For usage examples grep the sourcecode or consult
+# the API documentation in docs/api.rst as well as docs/signals.rst
+template_rendered = _signals.signal('template-rendered')
+request_started = _signals.signal('request-started')
+request_finished = _signals.signal('request-finished')
+got_request_exception = _signals.signal('got-request-exception')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/templating.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.templating
+    ~~~~~~~~~~~~~~~~
+
+    Implements the bridge to Jinja2.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+import posixpath
+from jinja2 import BaseLoader, TemplateNotFound
+
+from .globals import _request_ctx_stack
+from .signals import template_rendered
+
+
+def _default_template_ctx_processor():
+    """Default template context processor.  Injects `request`,
+    `session` and `g`.
+    """
+    reqctx = _request_ctx_stack.top
+    return dict(
+        config=reqctx.app.config,
+        request=reqctx.request,
+        session=reqctx.session,
+        g=reqctx.g
+    )
+
+
+class _DispatchingJinjaLoader(BaseLoader):
+    """A loader that looks for templates in the application and all
+    the module folders.
+    """
+
+    def __init__(self, app):
+        self.app = app
+
+    def get_source(self, environment, template):
+        template = posixpath.normpath(template)
+        if template.startswith('../'):
+            raise TemplateNotFound(template)
+        loader = None
+        try:
+            module, name = template.split('/', 1)
+            loader = self.app.modules[module].jinja_loader
+        except (ValueError, KeyError):
+            pass
+        # if there was a module and it has a loader, try this first
+        if loader is not None:
+            try:
+                return loader.get_source(environment, name)
+            except TemplateNotFound:
+                pass
+        # fall back to application loader if module failed
+        return self.app.jinja_loader.get_source(environment, template)
+
+    def list_templates(self):
+        result = self.app.jinja_loader.list_templates()
+        for name, module in self.app.modules.iteritems():
+            if module.jinja_loader is not None:
+                for template in module.jinja_loader.list_templates():
+                    result.append('%s/%s' % (name, template))
+        return result
+
+
+def _render(template, context, app):
+    """Renders the template and fires the signal"""
+    rv = template.render(context)
+    template_rendered.send(app, template=template, context=context)
+    return rv
+
+
+def render_template(template_name, **context):
+    """Renders a template from the template folder with the given
+    context.
+
+    :param template_name: the name of the template to be rendered
+    :param context: the variables that should be available in the
+                    context of the template.
+    """
+    ctx = _request_ctx_stack.top
+    ctx.app.update_template_context(context)
+    return _render(ctx.app.jinja_env.get_template(template_name),
+                   context, ctx.app)
+
+
+def render_template_string(source, **context):
+    """Renders a template from the given template source string
+    with the given context.
+
+    :param template_name: the sourcecode of the template to be
+                          rendered
+    :param context: the variables that should be available in the
+                    context of the template.
+    """
+    ctx = _request_ctx_stack.top
+    ctx.app.update_template_context(context)
+    return _render(ctx.app.jinja_env.from_string(source),
+                   context, ctx.app)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/testing.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.testing
+    ~~~~~~~~~~~~~
+
+    Implements test support helpers.  This module is lazily imported
+    and usually not used in production environments.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from werkzeug import Client, EnvironBuilder
+from flask import _request_ctx_stack
+
+
+class FlaskClient(Client):
+    """Works like a regular Werkzeug test client but has some
+    knowledge about how Flask works to defer the cleanup of the
+    request context stack to the end of a with body when used
+    in a with statement.
+    """
+
+    preserve_context = context_preserved = False
+
+    def open(self, *args, **kwargs):
+        if self.context_preserved:
+            _request_ctx_stack.pop()
+            self.context_preserved = False
+        kwargs.setdefault('environ_overrides', {}) \
+            ['flask._preserve_context'] = self.preserve_context
+
+        as_tuple = kwargs.pop('as_tuple', False)
+        buffered = kwargs.pop('buffered', False)
+        follow_redirects = kwargs.pop('follow_redirects', False)
+
+        builder = EnvironBuilder(*args, **kwargs)
+
+        if self.application.config.get('SERVER_NAME'):
+            server_name = self.application.config.get('SERVER_NAME')
+            if ':' not in server_name:
+                http_host, http_port = server_name, None
+            else:
+                http_host, http_port = server_name.split(':', 1)
+            if builder.base_url == 'http://localhost/':
+                # Default Generated Base URL
+                if http_port != None:
+                    builder.host = http_host + ':' + http_port
+                else:
+                    builder.host = http_host
+        old = _request_ctx_stack.top
+        try:
+            return Client.open(self, builder,
+                               as_tuple=as_tuple,
+                               buffered=buffered,
+                               follow_redirects=follow_redirects)
+        finally:
+            self.context_preserved = _request_ctx_stack.top is not old
+
+    def __enter__(self):
+        self.preserve_context = True
+        return self
+
+    def __exit__(self, exc_type, exc_value, tb):
+        self.preserve_context = False
+        if self.context_preserved:
+            _request_ctx_stack.pop()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/flask/wrappers.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+"""
+    flask.wrappers
+    ~~~~~~~~~~~~~~
+
+    Implements the WSGI wrappers (request and response).
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from werkzeug import Request as RequestBase, Response as ResponseBase, \
+    cached_property
+
+from .helpers import json, _assert_have_json
+from .globals import _request_ctx_stack
+
+
+class Request(RequestBase):
+    """The request object used by default in Flask.  Remembers the
+    matched endpoint and view arguments.
+
+    It is what ends up as :class:`~flask.request`.  If you want to replace
+    the request object used you can subclass this and set
+    :attr:`~flask.Flask.request_class` to your subclass.
+    """
+
+    #: the internal URL rule that matched the request.  This can be
+    #: useful to inspect which methods are allowed for the URL from
+    #: a before/after handler (``request.url_rule.methods``) etc.
+    #:
+    #: .. versionadded:: 0.6
+    url_rule = None
+
+    #: a dict of view arguments that matched the request.  If an exception
+    #: happened when matching, this will be `None`.
+    view_args = None
+
+    #: if matching the URL failed, this is the exception that will be
+    #: raised / was raised as part of the request handling.  This is
+    #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or
+    #: something similar.
+    routing_exception = None
+
+    @property
+    def max_content_length(self):
+        """Read-only view of the `MAX_CONTENT_LENGTH` config key."""
+        ctx = _request_ctx_stack.top
+        if ctx is not None:
+            return ctx.app.config['MAX_CONTENT_LENGTH']
+
+    @property
+    def endpoint(self):
+        """The endpoint that matched the request.  This in combination with
+        :attr:`view_args` can be used to reconstruct the same or a
+        modified URL.  If an exception happened when matching, this will
+        be `None`.
+        """
+        if self.url_rule is not None:
+            return self.url_rule.endpoint
+
+    @property
+    def module(self):
+        """The name of the current module"""
+        if self.url_rule and '.' in self.url_rule.endpoint:
+            return self.url_rule.endpoint.rsplit('.', 1)[0]
+
+    @cached_property
+    def json(self):
+        """If the mimetype is `application/json` this will contain the
+        parsed JSON data.
+        """
+        if __debug__:
+            _assert_have_json()
+        if self.mimetype == 'application/json':
+            return json.loads(self.data)
+
+
+class Response(ResponseBase):
+    """The response object that is used by default in Flask.  Works like the
+    response object from Werkzeug but is set to have an HTML mimetype by
+    default.  Quite often you don't have to create this object yourself because
+    :meth:`~flask.Flask.make_response` will take care of that for you.
+
+    If you want to replace the response object used you can subclass this and
+    set :attr:`~flask.Flask.response_class` to your subclass.
+    """
+    default_mimetype = 'text/html'
--- a/bundled/flask/setup.py	Thu Jan 27 18:15:55 2011 -0500
+++ b/bundled/flask/setup.py	Thu Jan 27 18:23:59 2011 -0500
@@ -38,8 +38,44 @@
   <http://github.com/mitsuhiko/flask/zipball/master#egg=Flask-dev>`_
 
 """
-from setuptools import setup
+from setuptools import Command, setup
+
+class run_audit(Command):
+    """Audits source code using PyFlakes for following issues:
+        - Names which are used but not defined or used before they are defined.
+        - Names which are redefined without having been used.
+    """
+    description = "Audit source code with PyFlakes"
+    user_options = []
+
+    def initialize_options(self):
+        all = None
+
+    def finalize_options(self):
+        pass
 
+    def run(self):
+        import os, sys
+        try:
+            import pyflakes.scripts.pyflakes as flakes
+        except ImportError:
+            print "Audit requires PyFlakes installed in your system."""
+            sys.exit(-1)
+
+        dirs = ['flask', 'tests']
+        # Add example directories
+        for dir in ['flaskr', 'jqueryexample', 'minitwit']:
+            dirs.append(os.path.join('examples', dir))
+        # TODO: Add test subdirectories
+        warns = 0
+        for dir in dirs:
+            for filename in os.listdir(dir):
+                if filename.endswith('.py') and filename != '__init__.py':
+                    warns += flakes.checkPath(os.path.join(dir, filename))
+        if warns > 0:
+            print ("Audit finished with total %d warnings." % warns)
+        else:
+            print ("No problems found in sourcecode.")
 
 def run_tests():
     import os, sys
@@ -50,7 +86,7 @@
 
 setup(
     name='Flask',
-    version='0.4',
+    version='0.7',
     url='http://github.com/mitsuhiko/flask/',
     license='BSD',
     author='Armin Ronacher',
@@ -58,7 +94,7 @@
     description='A microframework based on Werkzeug, Jinja2 '
                 'and good intentions',
     long_description=__doc__,
-    py_modules=['flask'],
+    packages=['flask'],
     zip_safe=False,
     platforms='any',
     install_requires=[
@@ -75,5 +111,6 @@
         'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
         'Topic :: Software Development :: Libraries :: Python Modules'
     ],
+    cmdclass={'audit': run_audit},
     test_suite='__main__.run_tests'
 )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/flask_tests.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1487 @@
+# -*- coding: utf-8 -*-
+"""
+    Flask Tests
+    ~~~~~~~~~~~
+
+    Tests Flask itself.  The majority of Flask is already tested
+    as part of Werkzeug.
+
+    :copyright: (c) 2010 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+from __future__ import with_statement
+import os
+import re
+import sys
+import flask
+import unittest
+from threading import Thread
+from logging import StreamHandler
+from contextlib import contextmanager
+from datetime import datetime
+from werkzeug import parse_date, parse_options_header
+from werkzeug.exceptions import NotFound
+from jinja2 import TemplateNotFound
+from cStringIO import StringIO
+
+example_path = os.path.join(os.path.dirname(__file__), '..', 'examples')
+sys.path.append(os.path.join(example_path, 'flaskr'))
+sys.path.append(os.path.join(example_path, 'minitwit'))
+
+
+def has_encoding(name):
+    try:
+        import codecs
+        codecs.lookup(name)
+        return True
+    except LookupError:
+        return False
+
+
+# config keys used for the ConfigTestCase
+TEST_KEY = 'foo'
+SECRET_KEY = 'devkey'
+
+
+@contextmanager
+def catch_warnings():
+    """Catch warnings in a with block in a list"""
+    import warnings
+    filters = warnings.filters
+    warnings.filters = filters[:]
+    old_showwarning = warnings.showwarning
+    log = []
+    def showwarning(message, category, filename, lineno, file=None, line=None):
+        log.append(locals())
+    try:
+        warnings.showwarning = showwarning
+        yield log
+    finally:
+        warnings.filters = filters
+        warnings.showwarning = old_showwarning
+
+
+@contextmanager
+def catch_stderr():
+    """Catch stderr in a StringIO"""
+    old_stderr = sys.stderr
+    sys.stderr = rv = StringIO()
+    try:
+        yield rv
+    finally:
+        sys.stderr = old_stderr
+
+
+class ContextTestCase(unittest.TestCase):
+
+    def test_context_binding(self):
+        app = flask.Flask(__name__)
+        @app.route('/')
+        def index():
+            return 'Hello %s!' % flask.request.args['name']
+        @app.route('/meh')
+        def meh():
+            return flask.request.url
+
+        with app.test_request_context('/?name=World'):
+            assert index() == 'Hello World!'
+        with app.test_request_context('/meh'):
+            assert meh() == 'http://localhost/meh'
+        assert flask._request_ctx_stack.top is None
+
+    def test_manual_context_binding(self):
+        app = flask.Flask(__name__)
+        @app.route('/')
+        def index():
+            return 'Hello %s!' % flask.request.args['name']
+
+        ctx = app.test_request_context('/?name=World')
+        ctx.push()
+        assert index() == 'Hello World!'
+        ctx.pop()
+        try:
+            index()
+        except RuntimeError:
+            pass
+        else:
+            assert 0, 'expected runtime error'
+
+    def test_test_client_context_binding(self):
+        app = flask.Flask(__name__)
+        @app.route('/')
+        def index():
+            flask.g.value = 42
+            return 'Hello World!'
+
+        @app.route('/other')
+        def other():
+            1/0
+
+        with app.test_client() as c:
+            resp = c.get('/')
+            assert flask.g.value == 42
+            assert resp.data == 'Hello World!'
+            assert resp.status_code == 200
+
+            resp = c.get('/other')
+            assert not hasattr(flask.g, 'value')
+            assert 'Internal Server Error' in resp.data
+            assert resp.status_code == 500
+            flask.g.value = 23
+
+        try:
+            flask.g.value
+        except (AttributeError, RuntimeError):
+            pass
+        else:
+            raise AssertionError('some kind of exception expected')
+
+
+class BasicFunctionalityTestCase(unittest.TestCase):
+
+    def test_options_work(self):
+        app = flask.Flask(__name__)
+        @app.route('/', methods=['GET', 'POST'])
+        def index():
+            return 'Hello World'
+        rv = app.test_client().open('/', method='OPTIONS')
+        assert sorted(rv.allow) == ['GET', 'HEAD', 'OPTIONS', 'POST']
+        assert rv.data == ''
+
+    def test_options_on_multiple_rules(self):
+        app = flask.Flask(__name__)
+        @app.route('/', methods=['GET', 'POST'])
+        def index():
+            return 'Hello World'
+        @app.route('/', methods=['PUT'])
+        def index_put():
+            return 'Aha!'
+        rv = app.test_client().open('/', method='OPTIONS')
+        assert sorted(rv.allow) == ['GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
+
+    def test_request_dispatching(self):
+        app = flask.Flask(__name__)
+        @app.route('/')
+        def index():
+            return flask.request.method
+        @app.route('/more', methods=['GET', 'POST'])
+        def more():
+            return flask.request.method
+
+        c = app.test_client()
+        assert c.get('/').data == 'GET'
+        rv = c.post('/')
+        assert rv.status_code == 405
+        assert sorted(rv.allow) == ['GET', 'HEAD', 'OPTIONS']
+        rv = c.head('/')
+        assert rv.status_code == 200
+        assert not rv.data  # head truncates
+        assert c.post('/more').data == 'POST'
+        assert c.get('/more').data == 'GET'
+        rv = c.delete('/more')
+        assert rv.status_code == 405
+        assert sorted(rv.allow) == ['GET', 'HEAD', 'OPTIONS', 'POST']
+
+    def test_url_mapping(self):
+        app = flask.Flask(__name__)
+        def index():
+            return flask.request.method
+        def more():
+            return flask.request.method
+
+        app.add_url_rule('/', 'index', index)
+        app.add_url_rule('/more', 'more', more, methods=['GET', 'POST'])
+
+        c = app.test_client()
+        assert c.get('/').data == 'GET'
+        rv = c.post('/')
+        assert rv.status_code == 405
+        assert sorted(rv.allow) == ['GET', 'HEAD', 'OPTIONS']
+        rv = c.head('/')
+        assert rv.status_code == 200
+        assert not rv.data  # head truncates
+        assert c.post('/more').data == 'POST'
+        assert c.get('/more').data == 'GET'
+        rv = c.delete('/more')
+        assert rv.status_code == 405
+        assert sorted(rv.allow) == ['GET', 'HEAD', 'OPTIONS', 'POST']
+
+    def test_werkzeug_routing(self):
+        from werkzeug.routing import Submount, Rule
+        app = flask.Flask(__name__)
+        app.url_map.add(Submount('/foo', [
+            Rule('/bar', endpoint='bar'),
+            Rule('/', endpoint='index')
+        ]))
+        def bar():
+            return 'bar'
+        def index():
+            return 'index'
+        app.view_functions['bar'] = bar
+        app.view_functions['index'] = index
+
+        c = app.test_client()
+        assert c.get('/foo/').data == 'index'
+        assert c.get('/foo/bar').data == 'bar'
+
+    def test_endpoint_decorator(self):
+        from werkzeug.routing import Submount, Rule
+        app = flask.Flask(__name__)
+        app.url_map.add(Submount('/foo', [
+            Rule('/bar', endpoint='bar'),
+            Rule('/', endpoint='index')
+        ]))
+
+        @app.endpoint('bar')
+        def bar():
+            return 'bar'
+
+        @app.endpoint('index')
+        def index():
+            return 'index'
+
+        c = app.test_client()
+        assert c.get('/foo/').data == 'index'
+        assert c.get('/foo/bar').data == 'bar'
+
+    def test_session(self):
+        app = flask.Flask(__name__)
+        app.secret_key = 'testkey'
+        @app.route('/set', methods=['POST'])
+        def set():
+            flask.session['value'] = flask.request.form['value']
+            return 'value set'
+        @app.route('/get')
+        def get():
+            return flask.session['value']
+
+        c = app.test_client()
+        assert c.post('/set', data={'value': '42'}).data == 'value set'
+        assert c.get('/get').data == '42'
+
+    def test_session_using_server_name(self):
+        app = flask.Flask(__name__)
+        app.config.update(
+            SECRET_KEY='foo',
+            SERVER_NAME='example.com'
+        )
+        @app.route('/')
+        def index():
+            flask.session['testing'] = 42
+            return 'Hello World'
+        rv = app.test_client().get('/', 'http://example.com/')
+        assert 'domain=.example.com' in rv.headers['set-cookie'].lower()
+        assert 'httponly' in rv.headers['set-cookie'].lower()
+
+    def test_missing_session(self):
+        app = flask.Flask(__name__)
+        def expect_exception(f, *args, **kwargs):
+            try:
+                f(*args, **kwargs)
+            except RuntimeError, e:
+                assert e.args and 'session is unavailable' in e.args[0]
+            else:
+                assert False, 'expected exception'
+        with app.test_request_context():
+            assert flask.session.get('missing_key') is None
+            expect_exception(flask.session.__setitem__, 'foo', 42)
+            expect_exception(flask.session.pop, 'foo')
+
+    def test_session_expiration(self):
+        permanent = True
+        app = flask.Flask(__name__)
+        app.secret_key = 'testkey'
+        @app.route('/')
+        def index():
+            flask.session['test'] = 42
+            flask.session.permanent = permanent
+            return ''
+
+        @app.route('/test')
+        def test():
+            return unicode(flask.session.permanent)
+
+        client = app.test_client()
+        rv = client.get('/')
+        assert 'set-cookie' in rv.headers
+        match = re.search(r'\bexpires=([^;]+)', rv.headers['set-cookie'])
+        expires = parse_date(match.group())
+        expected = datetime.utcnow() + app.permanent_session_lifetime
+        assert expires.year == expected.year
+        assert expires.month == expected.month
+        assert expires.day == expected.day
+
+        rv = client.get('/test')
+        assert rv.data == 'True'
+
+        permanent = False
+        rv = app.test_client().get('/')
+        assert 'set-cookie' in rv.headers
+        match = re.search(r'\bexpires=([^;]+)', rv.headers['set-cookie'])
+        assert match is None
+
+    def test_flashes(self):
+        app = flask.Flask(__name__)
+        app.secret_key = 'testkey'
+
+        with app.test_request_context():
+            assert not flask.session.modified
+            flask.flash('Zap')
+            flask.session.modified = False
+            flask.flash('Zip')
+            assert flask.session.modified
+            assert list(flask.get_flashed_messages()) == ['Zap', 'Zip']
+
+    def test_extended_flashing(self):
+        app = flask.Flask(__name__)
+        app.secret_key = 'testkey'
+
+        @app.route('/')
+        def index():
+            flask.flash(u'Hello World')
+            flask.flash(u'Hello World', 'error')
+            flask.flash(flask.Markup(u'<em>Testing</em>'), 'warning')
+            return ''
+
+        @app.route('/test')
+        def test():
+            messages = flask.get_flashed_messages(with_categories=True)
+            assert len(messages) == 3
+            assert messages[0] == ('message', u'Hello World')
+            assert messages[1] == ('error', u'Hello World')
+            assert messages[2] == ('warning', flask.Markup(u'<em>Testing</em>'))
+            return ''
+            messages = flask.get_flashed_messages()
+            assert len(messages) == 3
+            assert messages[0] == u'Hello World'
+            assert messages[1] == u'Hello World'
+            assert messages[2] == flask.Markup(u'<em>Testing</em>')
+
+        c = app.test_client()
+        c.get('/')
+        c.get('/test')
+
+    def test_request_processing(self):
+        app = flask.Flask(__name__)
+        evts = []
+        @app.before_request
+        def before_request():
+            evts.append('before')
+        @app.after_request
+        def after_request(response):
+            response.data += '|after'
+            evts.append('after')
+            return response
+        @app.route('/')
+        def index():
+            assert 'before' in evts
+            assert 'after' not in evts
+            return 'request'
+        assert 'after' not in evts
+        rv = app.test_client().get('/').data
+        assert 'after' in evts
+        assert rv == 'request|after'
+
+    def test_after_request_errors(self):
+        app = flask.Flask(__name__)
+        called = []
+        @app.after_request
+        def after_request(response):
+            called.append(True)
+            return response
+        @app.route('/')
+        def fails():
+            1/0
+        rv = app.test_client().get('/')
+        assert rv.status_code == 500
+        assert 'Internal Server Error' in rv.data
+        assert len(called) == 1
+
+    def test_after_request_handler_error(self):
+        called = []
+        app = flask.Flask(__name__)
+        @app.after_request
+        def after_request(response):
+            called.append(True)
+            1/0
+            return response
+        @app.route('/')
+        def fails():
+            1/0
+        rv = app.test_client().get('/')
+        assert rv.status_code == 500
+        assert 'Internal Server Error' in rv.data
+        assert len(called) == 1
+
+    def test_before_after_request_order(self):
+        called = []
+        app = flask.Flask(__name__)
+        @app.before_request
+        def before1():
+            called.append(1)
+        @app.before_request
+        def before2():
+            called.append(2)
+        @app.after_request
+        def after1(response):
+            called.append(4)
+            return response
+        @app.after_request
+        def after2(response):
+            called.append(3)
+            return response
+        @app.route('/')
+        def index():
+            return '42'
+        rv = app.test_client().get('/')
+        assert rv.data == '42'
+        assert called == [1, 2, 3, 4]
+
+    def test_error_handling(self):
+        app = flask.Flask(__name__)
+        @app.errorhandler(404)
+        def not_found(e):
+            return 'not found', 404
+        @app.errorhandler(500)
+        def internal_server_error(e):
+            return 'internal server error', 500
+        @app.route('/')
+        def index():
+            flask.abort(404)
+        @app.route('/error')
+        def error():
+            1 // 0
+        c = app.test_client()
+        rv = c.get('/')
+        assert rv.status_code == 404
+        assert rv.data == 'not found'
+        rv = c.get('/error')
+        assert rv.status_code == 500
+        assert 'internal server error' == rv.data
+
+    def test_response_creation(self):
+        app = flask.Flask(__name__)
+        @app.route('/unicode')
+        def from_unicode():
+            return u'Hällo Wörld'
+        @app.route('/string')
+        def from_string():
+            return u'Hällo Wörld'.encode('utf-8')
+        @app.route('/args')
+        def from_tuple():
+            return 'Meh', 400, {'X-Foo': 'Testing'}, 'text/plain'
+        c = app.test_client()
+        assert c.get('/unicode').data == u'Hällo Wörld'.encode('utf-8')
+        assert c.get('/string').data == u'Hällo Wörld'.encode('utf-8')
+        rv = c.get('/args')
+        assert rv.data == 'Meh'
+        assert rv.headers['X-Foo'] == 'Testing'
+        assert rv.status_code == 400
+        assert rv.mimetype == 'text/plain'
+
+    def test_make_response(self):
+        app = flask.Flask(__name__)
+        with app.test_request_context():
+            rv = flask.make_response()
+            assert rv.status_code == 200
+            assert rv.data == ''
+            assert rv.mimetype == 'text/html'
+
+            rv = flask.make_response('Awesome')
+            assert rv.status_code == 200
+            assert rv.data == 'Awesome'
+            assert rv.mimetype == 'text/html'
+
+            rv = flask.make_response('W00t', 404)
+            assert rv.status_code == 404
+            assert rv.data == 'W00t'
+            assert rv.mimetype == 'text/html'
+
+    def test_url_generation(self):
+        app = flask.Flask(__name__)
+        @app.route('/hello/<name>', methods=['POST'])
+        def hello():
+            pass
+        with app.test_request_context():
+            assert flask.url_for('hello', name='test x') == '/hello/test%20x'
+            assert flask.url_for('hello', name='test x', _external=True) \
+                == 'http://localhost/hello/test%20x'
+
+    def test_custom_converters(self):
+        from werkzeug.routing import BaseConverter
+        class ListConverter(BaseConverter):
+            def to_python(self, value):
+                return value.split(',')
+            def to_url(self, value):
+                base_to_url = super(ListConverter, self).to_url
+                return ','.join(base_to_url(x) for x in value)
+        app = flask.Flask(__name__)
+        app.url_map.converters['list'] = ListConverter
+        @app.route('/<list:args>')
+        def index(args):
+            return '|'.join(args)
+        c = app.test_client()
+        assert c.get('/1,2,3').data == '1|2|3'
+
+    def test_static_files(self):
+        app = flask.Flask(__name__)
+        rv = app.test_client().get('/static/index.html')
+        assert rv.status_code == 200
+        assert rv.data.strip() == '<h1>Hello World!</h1>'
+        with app.test_request_context():
+            assert flask.url_for('static', filename='index.html') \
+                == '/static/index.html'
+
+    def test_none_response(self):
+        app = flask.Flask(__name__)
+        @app.route('/')
+        def test():
+            return None
+        try:
+            app.test_client().get('/')
+        except ValueError, e:
+            assert str(e) == 'View function did not return a response'
+            pass
+        else:
+            assert "Expected ValueError"
+
+    def test_request_locals(self):
+        self.assertEqual(repr(flask.g), '<LocalProxy unbound>')
+        self.assertFalse(flask.g)
+
+    def test_proper_test_request_context(self):
+        app = flask.Flask(__name__)
+        app.config.update(
+            SERVER_NAME='localhost.localdomain:5000'
+        )
+        @app.route('/')
+        def index():
+            return None
+
+        @app.route('/', subdomain='foo')
+        def sub():
+            return None
+
+        with app.test_request_context('/'):
+            assert flask.url_for('index', _external=True) == 'http://localhost.localdomain:5000/'
+
+        with app.test_request_context('/'):
+            assert flask.url_for('sub', _external=True) == 'http://foo.localhost.localdomain:5000/'
+
+        try:
+            with app.test_request_context('/', environ_overrides={'HTTP_HOST': 'localhost'}):
+                pass
+        except Exception, e:
+            assert isinstance(e, ValueError)
+            assert str(e) == "the server name provided " + \
+                    "('localhost.localdomain:5000') does not match the " + \
+                    "server name from the WSGI environment ('localhost')", str(e)
+
+        try:
+            app.config.update(SERVER_NAME='localhost')
+            with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost'}):
+                pass
+        except ValueError, e:
+            raise ValueError(
+                "No ValueError exception should have been raised \"%s\"" % e
+            )
+
+        try:
+            app.config.update(SERVER_NAME='localhost:80')
+            with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost:80'}):
+                pass
+        except ValueError, e:
+            raise ValueError(
+                "No ValueError exception should have been raised \"%s\"" % e
+            )
+
+    def test_test_app_proper_environ(self):
+        app = flask.Flask(__name__)
+        app.config.update(
+            SERVER_NAME='localhost.localdomain:5000'
+        )
+        @app.route('/')
+        def index():
+            return 'Foo'
+
+        @app.route('/', subdomain='foo')
+        def subdomain():
+            return 'Foo SubDomain'
+
+        try:
+            rv = app.test_client().get('/')
+            assert rv.data == 'Foo'
+        except ValueError, e:
+            raise ValueError(
+                "No ValueError exception should have been raised \"%s\"" % e
+            )
+
+        try:
+            rv = app.test_client().get('/', 'http://localhost.localdomain:5000')
+            assert rv.data == 'Foo'
+        except ValueError, e:
+            raise ValueError(
+                "No ValueError exception should have been raised \"%s\"" % e
+            )
+
+        try:
+            rv = app.test_client().get('/', 'https://localhost.localdomain:5000')
+            assert rv.data == 'Foo'
+        except ValueError, e:
+            raise ValueError(
+                "No ValueError exception should have been raised \"%s\"" % e
+            )
+
+        try:
+            app.config.update(SERVER_NAME='localhost.localdomain')
+            rv = app.test_client().get('/', 'https://localhost.localdomain')
+            assert rv.data == 'Foo'
+        except ValueError, e:
+            raise ValueError(
+                "No ValueError exception should have been raised \"%s\"" % e
+            )
+
+        try:
+            app.config.update(SERVER_NAME='localhost.localdomain:443')
+            rv = app.test_client().get('/', 'https://localhost.localdomain')
+            assert rv.data == 'Foo'
+        except ValueError, e:
+            assert str(e) == "the server name provided " + \
+                    "('localhost.localdomain:443') does not match the " + \
+                    "server name from the WSGI environment ('localhost.localdomain')", str(e)
+
+        try:
+            app.config.update(SERVER_NAME='localhost.localdomain')
+            app.test_client().get('/', 'http://foo.localhost')
+        except ValueError, e:
+            assert str(e) == "the server name provided " + \
+                    "('localhost.localdomain') does not match the " + \
+                    "server name from the WSGI environment ('foo.localhost')", str(e)
+
+        try:
+            rv = app.test_client().get('/', 'http://foo.localhost.localdomain')
+            assert rv.data == 'Foo SubDomain'
+        except ValueError, e:
+            raise ValueError(
+                "No ValueError exception should have been raised \"%s\"" % e
+            )
+
+    def test_exception_propagation(self):
+        def apprunner(configkey):
+            app = flask.Flask(__name__)
+            @app.route('/')
+            def index():
+                1/0
+            c = app.test_client()
+            if config_key is not None:
+                app.config[config_key] = True
+                try:
+                    resp = c.get('/')
+                except Exception:
+                    pass
+                else:
+                    self.fail('expected exception')
+            else:
+                assert c.get('/').status_code == 500
+
+        # we have to run this test in an isolated thread because if the
+        # debug flag is set to true and an exception happens the context is
+        # not torn down.  This causes other tests that run after this fail
+        # when they expect no exception on the stack.
+        for config_key in 'TESTING', 'PROPAGATE_EXCEPTIONS', 'DEBUG', None:
+            t = Thread(target=apprunner, args=(config_key,))
+            t.start()
+            t.join()
+
+
+class JSONTestCase(unittest.TestCase):
+
+    def test_jsonify(self):
+        d = dict(a=23, b=42, c=[1, 2, 3])
+        app = flask.Flask(__name__)
+        @app.route('/kw')
+        def return_kwargs():
+            return flask.jsonify(**d)
+        @app.route('/dict')
+        def return_dict():
+            return flask.jsonify(d)
+        c = app.test_client()
+        for url in '/kw', '/dict':
+            rv = c.get(url)
+            assert rv.mimetype == 'application/json'
+            assert flask.json.loads(rv.data) == d
+
+    def test_json_attr(self):
+        app = flask.Flask(__name__)
+        @app.route('/add', methods=['POST'])
+        def add():
+            return unicode(flask.request.json['a'] + flask.request.json['b'])
+        c = app.test_client()
+        rv = c.post('/add', data=flask.json.dumps({'a': 1, 'b': 2}),
+                            content_type='application/json')
+        assert rv.data == '3'
+
+    def test_template_escaping(self):
+        app = flask.Flask(__name__)
+        render = flask.render_template_string
+        with app.test_request_context():
+            rv = render('{{ "</script>"|tojson|safe }}')
+            assert rv == '"<\\/script>"'
+            rv = render('{{ "<\0/script>"|tojson|safe }}')
+            assert rv == '"<\\u0000\\/script>"'
+
+    def test_modified_url_encoding(self):
+        class ModifiedRequest(flask.Request):
+            url_charset = 'euc-kr'
+        app = flask.Flask(__name__)
+        app.request_class = ModifiedRequest
+        app.url_map.charset = 'euc-kr'
+
+        @app.route('/')
+        def index():
+            return flask.request.args['foo']
+
+        rv = app.test_client().get(u'/?foo=정상처리'.encode('euc-kr'))
+        assert rv.status_code == 200
+        assert rv.data == u'정상처리'.encode('utf-8')
+
+    if not has_encoding('euc-kr'):
+        test_modified_url_encoding = None
+
+
+class TemplatingTestCase(unittest.TestCase):
+
+    def test_context_processing(self):
+        app = flask.Flask(__name__)
+        @app.context_processor
+        def context_processor():
+            return {'injected_value': 42}
+        @app.route('/')
+        def index():
+            return flask.render_template('context_template.html', value=23)
+        rv = app.test_client().get('/')
+        assert rv.data == '<p>23|42'
+
+    def test_original_win(self):
+        app = flask.Flask(__name__)
+        @app.route('/')
+        def index():
+            return flask.render_template_string('{{ config }}', config=42)
+        rv = app.test_client().get('/')
+        assert rv.data == '42'
+
+    def test_standard_context(self):
+        app = flask.Flask(__name__)
+        app.secret_key = 'development key'
+        @app.route('/')
+        def index():
+            flask.g.foo = 23
+            flask.session['test'] = 'aha'
+            return flask.render_template_string('''
+                {{ request.args.foo }}
+                {{ g.foo }}
+                {{ config.DEBUG }}
+                {{ session.test }}
+            ''')
+        rv = app.test_client().get('/?foo=42')
+        assert rv.data.split() == ['42', '23', 'False', 'aha']
+
+    def test_escaping(self):
+        text = '<p>Hello World!'
+        app = flask.Flask(__name__)
+        @app.route('/')
+        def index():
+            return flask.render_template('escaping_template.html', text=text,
+                                         html=flask.Markup(text))
+        lines = app.test_client().get('/').data.splitlines()
+        assert lines == [
+            '&lt;p&gt;Hello World!',
+            '<p>Hello World!',
+            '<p>Hello World!',
+            '<p>Hello World!',
+            '&lt;p&gt;Hello World!',
+            '<p>Hello World!'
+        ]
+
+    def test_no_escaping(self):
+        app = flask.Flask(__name__)
+        with app.test_request_context():
+            assert flask.render_template_string('{{ foo }}',
+                foo='<test>') == '<test>'
+            assert flask.render_template('mail.txt', foo='<test>') \
+                == '<test> Mail'
+
+    def test_macros(self):
+        app = flask.Flask(__name__)
+        with app.test_request_context():
+            macro = flask.get_template_attribute('_macro.html', 'hello')
+            assert macro('World') == 'Hello World!'
+
+    def test_template_filter(self):
+        app = flask.Flask(__name__)
+        @app.template_filter()
+        def my_reverse(s):
+            return s[::-1]
+        assert 'my_reverse' in  app.jinja_env.filters.keys()
+        assert app.jinja_env.filters['my_reverse'] == my_reverse
+        assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba'
+
+    def test_template_filter_with_name(self):
+        app = flask.Flask(__name__)
+        @app.template_filter('strrev')
+        def my_reverse(s):
+            return s[::-1]
+        assert 'strrev' in  app.jinja_env.filters.keys()
+        assert app.jinja_env.filters['strrev'] == my_reverse
+        assert app.jinja_env.filters['strrev']('abcd') == 'dcba'
+
+    def test_template_filter_with_template(self):
+        app = flask.Flask(__name__)
+        @app.template_filter()
+        def super_reverse(s):
+            return s[::-1]
+        @app.route('/')
+        def index():
+            return flask.render_template('template_filter.html', value='abcd')
+        rv = app.test_client().get('/')
+        assert rv.data == 'dcba'
+
+    def test_template_filter_with_name_and_template(self):
+        app = flask.Flask(__name__)
+        @app.template_filter('super_reverse')
+        def my_reverse(s):
+            return s[::-1]
+        @app.route('/')
+        def index():
+            return flask.render_template('template_filter.html', value='abcd')
+        rv = app.test_client().get('/')
+        assert rv.data == 'dcba'
+
+
+class ModuleTestCase(unittest.TestCase):
+
+    def test_basic_module(self):
+        app = flask.Flask(__name__)
+        admin = flask.Module(__name__, 'admin', url_prefix='/admin')
+        @admin.route('/')
+        def admin_index():
+            return 'admin index'
+        @admin.route('/login')
+        def admin_login():
+            return 'admin login'
+        @admin.route('/logout')
+        def admin_logout():
+            return 'admin logout'
+        @app.route('/')
+        def index():
+            return 'the index'
+        app.register_module(admin)
+        c = app.test_client()
+        assert c.get('/').data == 'the index'
+        assert c.get('/admin/').data == 'admin index'
+        assert c.get('/admin/login').data == 'admin login'
+        assert c.get('/admin/logout').data == 'admin logout'
+
+    def test_default_endpoint_name(self):
+        app = flask.Flask(__name__)
+        mod = flask.Module(__name__, 'frontend')
+        def index():
+            return 'Awesome'
+        mod.add_url_rule('/', view_func=index)
+        app.register_module(mod)
+        rv = app.test_client().get('/')
+        assert rv.data == 'Awesome'
+        with app.test_request_context():
+            assert flask.url_for('frontend.index') == '/'
+
+    def test_request_processing(self):
+        catched = []
+        app = flask.Flask(__name__)
+        admin = flask.Module(__name__, 'admin', url_prefix='/admin')
+        @admin.before_request
+        def before_admin_request():
+            catched.append('before-admin')
+        @admin.after_request
+        def after_admin_request(response):
+            catched.append('after-admin')
+            return response
+        @admin.route('/')
+        def admin_index():
+            return 'the admin'
+        @app.before_request
+        def before_request():
+            catched.append('before-app')
+        @app.after_request
+        def after_request(response):
+            catched.append('after-app')
+            return response
+        @app.route('/')
+        def index():
+            return 'the index'
+        app.register_module(admin)
+        c = app.test_client()
+
+        assert c.get('/').data == 'the index'
+        assert catched == ['before-app', 'after-app']
+        del catched[:]
+
+        assert c.get('/admin/').data == 'the admin'
+        assert catched == ['before-app', 'before-admin',
+                           'after-admin', 'after-app']
+
+    def test_context_processors(self):
+        app = flask.Flask(__name__)
+        admin = flask.Module(__name__, 'admin', url_prefix='/admin')
+        @app.context_processor
+        def inject_all_regualr():
+            return {'a': 1}
+        @admin.context_processor
+        def inject_admin():
+            return {'b': 2}
+        @admin.app_context_processor
+        def inject_all_module():
+            return {'c': 3}
+        @app.route('/')
+        def index():
+            return flask.render_template_string('{{ a }}{{ b }}{{ c }}')
+        @admin.route('/')
+        def admin_index():
+            return flask.render_template_string('{{ a }}{{ b }}{{ c }}')
+        app.register_module(admin)
+        c = app.test_client()
+        assert c.get('/').data == '13'
+        assert c.get('/admin/').data == '123'
+
+    def test_late_binding(self):
+        app = flask.Flask(__name__)
+        admin = flask.Module(__name__, 'admin')
+        @admin.route('/')
+        def index():
+            return '42'
+        app.register_module(admin, url_prefix='/admin')
+        assert app.test_client().get('/admin/').data == '42'
+
+    def test_error_handling(self):
+        app = flask.Flask(__name__)
+        admin = flask.Module(__name__, 'admin')
+        @admin.app_errorhandler(404)
+        def not_found(e):
+            return 'not found', 404
+        @admin.app_errorhandler(500)
+        def internal_server_error(e):
+            return 'internal server error', 500
+        @admin.route('/')
+        def index():
+            flask.abort(404)
+        @admin.route('/error')
+        def error():
+            1 // 0
+        app.register_module(admin)
+        c = app.test_client()
+        rv = c.get('/')
+        assert rv.status_code == 404
+        assert rv.data == 'not found'
+        rv = c.get('/error')
+        assert rv.status_code == 500
+        assert 'internal server error' == rv.data
+
+    def test_templates_and_static(self):
+        from moduleapp import app
+        c = app.test_client()
+
+        rv = c.get('/')
+        assert rv.data == 'Hello from the Frontend'
+        rv = c.get('/admin/')
+        assert rv.data == 'Hello from the Admin'
+        rv = c.get('/admin/index2')
+        assert rv.data == 'Hello from the Admin'
+        rv = c.get('/admin/static/test.txt')
+        assert rv.data.strip() == 'Admin File'
+        rv = c.get('/admin/static/css/test.css')
+        assert rv.data.strip() == '/* nested file */'
+
+        with app.test_request_context():
+            assert flask.url_for('admin.static', filename='test.txt') \
+                == '/admin/static/test.txt'
+
+        with app.test_request_context():
+            try:
+                flask.render_template('missing.html')
+            except TemplateNotFound, e:
+                assert e.name == 'missing.html'
+            else:
+                assert 0, 'expected exception'
+
+        with flask.Flask(__name__).test_request_context():
+            assert flask.render_template('nested/nested.txt') == 'I\'m nested'
+
+    def test_safe_access(self):
+        from moduleapp import app
+
+        with app.test_request_context():
+            f = app.view_functions['admin.static']
+
+            try:
+                f('/etc/passwd')
+            except NotFound:
+                pass
+            else:
+                assert 0, 'expected exception'
+            try:
+                f('../__init__.py')
+            except NotFound:
+                pass
+            else:
+                assert 0, 'expected exception'
+
+            # testcase for a security issue that may exist on windows systems
+            import os
+            import ntpath
+            old_path = os.path
+            os.path = ntpath
+            try:
+                try:
+                    f('..\\__init__.py')
+                except NotFound:
+                    pass
+                else:
+                    assert 0, 'expected exception'
+            finally:
+                os.path = old_path
+
+    def test_endpoint_decorator(self):
+        from werkzeug.routing import Submount, Rule
+        from flask import Module
+
+        app = flask.Flask(__name__)
+        app.url_map.add(Submount('/foo', [
+            Rule('/bar', endpoint='bar'),
+            Rule('/', endpoint='index')
+        ]))
+        module = Module(__name__, __name__)
+
+        @module.endpoint('bar')
+        def bar():
+            return 'bar'
+
+        @module.endpoint('index')
+        def index():
+            return 'index'
+
+        app.register_module(module)
+
+        c = app.test_client()
+        assert c.get('/foo/').data == 'index'
+        assert c.get('/foo/bar').data == 'bar'
+
+
+class SendfileTestCase(unittest.TestCase):
+
+    def test_send_file_regular(self):
+        app = flask.Flask(__name__)
+        with app.test_request_context():
+            rv = flask.send_file('static/index.html')
+            assert rv.direct_passthrough
+            assert rv.mimetype == 'text/html'
+            with app.open_resource('static/index.html') as f:
+                assert rv.data == f.read()
+
+    def test_send_file_xsendfile(self):
+        app = flask.Flask(__name__)
+        app.use_x_sendfile = True
+        with app.test_request_context():
+            rv = flask.send_file('static/index.html')
+            assert rv.direct_passthrough
+            assert 'x-sendfile' in rv.headers
+            assert rv.headers['x-sendfile'] == \
+                os.path.join(app.root_path, 'static/index.html')
+            assert rv.mimetype == 'text/html'
+
+    def test_send_file_object(self):
+        app = flask.Flask(__name__)
+        with catch_warnings() as captured:
+            with app.test_request_context():
+                f = open(os.path.join(app.root_path, 'static/index.html'))
+                rv = flask.send_file(f)
+                with app.open_resource('static/index.html') as f:
+                    assert rv.data == f.read()
+                assert rv.mimetype == 'text/html'
+            # mimetypes + etag
+            assert len(captured) == 2
+
+        app.use_x_sendfile = True
+        with catch_warnings() as captured:
+            with app.test_request_context():
+                f = open(os.path.join(app.root_path, 'static/index.html'))
+                rv = flask.send_file(f)
+                assert rv.mimetype == 'text/html'
+                assert 'x-sendfile' in rv.headers
+                assert rv.headers['x-sendfile'] == \
+                    os.path.join(app.root_path, 'static/index.html')
+            # mimetypes + etag
+            assert len(captured) == 2
+
+        app.use_x_sendfile = False
+        with app.test_request_context():
+            with catch_warnings() as captured:
+                f = StringIO('Test')
+                rv = flask.send_file(f)
+                assert rv.data == 'Test'
+                assert rv.mimetype == 'application/octet-stream'
+            # etags
+            assert len(captured) == 1
+            with catch_warnings() as captured:
+                f = StringIO('Test')
+                rv = flask.send_file(f, mimetype='text/plain')
+                assert rv.data == 'Test'
+                assert rv.mimetype == 'text/plain'
+            # etags
+            assert len(captured) == 1
+
+        app.use_x_sendfile = True
+        with catch_warnings() as captured:
+            with app.test_request_context():
+                f = StringIO('Test')
+                rv = flask.send_file(f)
+                assert 'x-sendfile' not in rv.headers
+            # etags
+            assert len(captured) == 1
+
+    def test_attachment(self):
+        app = flask.Flask(__name__)
+        with catch_warnings() as captured:
+            with app.test_request_context():
+                f = open(os.path.join(app.root_path, 'static/index.html'))
+                rv = flask.send_file(f, as_attachment=True)
+                value, options = parse_options_header(rv.headers['Content-Disposition'])
+                assert value == 'attachment'
+            # mimetypes + etag
+            assert len(captured) == 2
+
+        with app.test_request_context():
+            assert options['filename'] == 'index.html'
+            rv = flask.send_file('static/index.html', as_attachment=True)
+            value, options = parse_options_header(rv.headers['Content-Disposition'])
+            assert value == 'attachment'
+            assert options['filename'] == 'index.html'
+
+        with app.test_request_context():
+            rv = flask.send_file(StringIO('Test'), as_attachment=True,
+                                 attachment_filename='index.txt',
+                                 add_etags=False)
+            assert rv.mimetype == 'text/plain'
+            value, options = parse_options_header(rv.headers['Content-Disposition'])
+            assert value == 'attachment'
+            assert options['filename'] == 'index.txt'
+
+
+class LoggingTestCase(unittest.TestCase):
+
+    def test_logger_cache(self):
+        app = flask.Flask(__name__)
+        logger1 = app.logger
+        assert app.logger is logger1
+        assert logger1.name == __name__
+        app.logger_name = __name__ + '/test_logger_cache'
+        assert app.logger is not logger1
+
+    def test_debug_log(self):
+        app = flask.Flask(__name__)
+        app.debug = True
+
+        @app.route('/')
+        def index():
+            app.logger.warning('the standard library is dead')
+            app.logger.debug('this is a debug statement')
+            return ''
+
+        @app.route('/exc')
+        def exc():
+            1/0
+        c = app.test_client()
+
+        with catch_stderr() as err:
+            c.get('/')
+            out = err.getvalue()
+            assert 'WARNING in flask_tests [' in out
+            assert 'flask_tests.py' in out
+            assert 'the standard library is dead' in out
+            assert 'this is a debug statement' in out
+
+        with catch_stderr() as err:
+            try:
+                c.get('/exc')
+            except ZeroDivisionError:
+                pass
+            else:
+                assert False, 'debug log ate the exception'
+
+    def test_exception_logging(self):
+        out = StringIO()
+        app = flask.Flask(__name__)
+        app.logger_name = 'flask_tests/test_exception_logging'
+        app.logger.addHandler(StreamHandler(out))
+
+        @app.route('/')
+        def index():
+            1/0
+
+        rv = app.test_client().get('/')
+        assert rv.status_code == 500
+        assert 'Internal Server Error' in rv.data
+
+        err = out.getvalue()
+        assert 'Exception on / [GET]' in err
+        assert 'Traceback (most recent call last):' in err
+        assert '1/0' in err
+        assert 'ZeroDivisionError:' in err
+
+    def test_processor_exceptions(self):
+        app = flask.Flask(__name__)
+        @app.before_request
+        def before_request():
+            if trigger == 'before':
+                1/0
+        @app.after_request
+        def after_request(response):
+            if trigger == 'after':
+                1/0
+            return response
+        @app.route('/')
+        def index():
+            return 'Foo'
+        @app.errorhandler(500)
+        def internal_server_error(e):
+            return 'Hello Server Error', 500
+        for trigger in 'before', 'after':
+            rv = app.test_client().get('/')
+            assert rv.status_code == 500
+            assert rv.data == 'Hello Server Error'
+
+
+class ConfigTestCase(unittest.TestCase):
+
+    def common_object_test(self, app):
+        assert app.secret_key == 'devkey'
+        assert app.config['TEST_KEY'] == 'foo'
+        assert 'ConfigTestCase' not in app.config
+
+    def test_config_from_file(self):
+        app = flask.Flask(__name__)
+        app.config.from_pyfile('flask_tests.py')
+        self.common_object_test(app)
+
+    def test_config_from_object(self):
+        app = flask.Flask(__name__)
+        app.config.from_object(__name__)
+        self.common_object_test(app)
+
+    def test_config_from_class(self):
+        class Base(object):
+            TEST_KEY = 'foo'
+        class Test(Base):
+            SECRET_KEY = 'devkey'
+        app = flask.Flask(__name__)
+        app.config.from_object(Test)
+        self.common_object_test(app)
+
+    def test_config_from_envvar(self):
+        import os
+        env = os.environ
+        try:
+            os.environ = {}
+            app = flask.Flask(__name__)
+            try:
+                app.config.from_envvar('FOO_SETTINGS')
+            except RuntimeError, e:
+                assert "'FOO_SETTINGS' is not set" in str(e)
+            else:
+                assert 0, 'expected exception'
+            not app.config.from_envvar('FOO_SETTINGS', silent=True)
+
+            os.environ = {'FOO_SETTINGS': 'flask_tests.py'}
+            assert app.config.from_envvar('FOO_SETTINGS')
+            self.common_object_test(app)
+        finally:
+            os.environ = env
+
+    def test_config_missing(self):
+        app = flask.Flask(__name__)
+        try:
+            app.config.from_pyfile('missing.cfg')
+        except IOError, e:
+            msg = str(e)
+            assert msg.startswith('[Errno 2] Unable to load configuration '
+                                  'file (No such file or directory):')
+            assert msg.endswith("missing.cfg'")
+        else:
+            assert 0, 'expected config'
+
+
+class SubdomainTestCase(unittest.TestCase):
+
+    def test_basic_support(self):
+        app = flask.Flask(__name__)
+        app.config['SERVER_NAME'] = 'localhost'
+        @app.route('/')
+        def normal_index():
+            return 'normal index'
+        @app.route('/', subdomain='test')
+        def test_index():
+            return 'test index'
+
+        c = app.test_client()
+        rv = c.get('/', 'http://localhost/')
+        assert rv.data == 'normal index'
+
+        rv = c.get('/', 'http://test.localhost/')
+        assert rv.data == 'test index'
+
+    def test_module_static_path_subdomain(self):
+        app = flask.Flask(__name__)
+        app.config['SERVER_NAME'] = 'example.com'
+        from subdomaintestmodule import mod
+        app.register_module(mod)
+        c = app.test_client()
+        rv = c.get('/static/hello.txt', 'http://foo.example.com/')
+        assert rv.data.strip() == 'Hello Subdomain'
+
+    def test_subdomain_matching(self):
+        app = flask.Flask(__name__)
+        app.config['SERVER_NAME'] = 'localhost'
+        @app.route('/', subdomain='<user>')
+        def index(user):
+            return 'index for %s' % user
+
+        c = app.test_client()
+        rv = c.get('/', 'http://mitsuhiko.localhost/')
+        assert rv.data == 'index for mitsuhiko'
+
+    def test_module_subdomain_support(self):
+        app = flask.Flask(__name__)
+        mod = flask.Module(__name__, 'test', subdomain='testing')
+        app.config['SERVER_NAME'] = 'localhost'
+
+        @mod.route('/test')
+        def test():
+            return 'Test'
+
+        @mod.route('/outside', subdomain='xtesting')
+        def bar():
+            return 'Outside'
+
+        app.register_module(mod)
+
+        c = app.test_client()
+        rv = c.get('/test', 'http://testing.localhost/')
+        assert rv.data == 'Test'
+        rv = c.get('/outside', 'http://xtesting.localhost/')
+        assert rv.data == 'Outside'
+
+
+class TestSignals(unittest.TestCase):
+
+    def test_template_rendered(self):
+        app = flask.Flask(__name__)
+
+        @app.route('/')
+        def index():
+            return flask.render_template('simple_template.html', whiskey=42)
+
+        recorded = []
+        def record(sender, template, context):
+            recorded.append((template, context))
+
+        flask.template_rendered.connect(record, app)
+        try:
+            app.test_client().get('/')
+            assert len(recorded) == 1
+            template, context = recorded[0]
+            assert template.name == 'simple_template.html'
+            assert context['whiskey'] == 42
+        finally:
+            flask.template_rendered.disconnect(record, app)
+
+    def test_request_signals(self):
+        app = flask.Flask(__name__)
+        calls = []
+
+        def before_request_signal(sender):
+            calls.append('before-signal')
+
+        def after_request_signal(sender, response):
+            assert response.data == 'stuff'
+            calls.append('after-signal')
+
+        @app.before_request
+        def before_request_handler():
+            calls.append('before-handler')
+
+        @app.after_request
+        def after_request_handler(response):
+            calls.append('after-handler')
+            response.data = 'stuff'
+            return response
+
+        @app.route('/')
+        def index():
+            calls.append('handler')
+            return 'ignored anyway'
+
+        flask.request_started.connect(before_request_signal, app)
+        flask.request_finished.connect(after_request_signal, app)
+
+        try:
+            rv = app.test_client().get('/')
+            assert rv.data == 'stuff'
+
+            assert calls == ['before-signal', 'before-handler',
+                             'handler', 'after-handler',
+                             'after-signal']
+        finally:
+            flask.request_started.disconnect(before_request_signal, app)
+            flask.request_finished.disconnect(after_request_signal, app)
+
+    def test_request_exception_signal(self):
+        app = flask.Flask(__name__)
+        recorded = []
+
+        @app.route('/')
+        def index():
+            1/0
+
+        def record(sender, exception):
+            recorded.append(exception)
+
+        flask.got_request_exception.connect(record, app)
+        try:
+            assert app.test_client().get('/').status_code == 500
+            assert len(recorded) == 1
+            assert isinstance(recorded[0], ZeroDivisionError)
+        finally:
+            flask.got_request_exception.disconnect(record, app)
+
+
+def suite():
+    from minitwit_tests import MiniTwitTestCase
+    from flaskr_tests import FlaskrTestCase
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(ContextTestCase))
+    suite.addTest(unittest.makeSuite(BasicFunctionalityTestCase))
+    suite.addTest(unittest.makeSuite(TemplatingTestCase))
+    suite.addTest(unittest.makeSuite(ModuleTestCase))
+    suite.addTest(unittest.makeSuite(SendfileTestCase))
+    suite.addTest(unittest.makeSuite(LoggingTestCase))
+    suite.addTest(unittest.makeSuite(ConfigTestCase))
+    suite.addTest(unittest.makeSuite(SubdomainTestCase))
+    if flask.json_available:
+        suite.addTest(unittest.makeSuite(JSONTestCase))
+    if flask.signals_available:
+        suite.addTest(unittest.makeSuite(TestSignals))
+    suite.addTest(unittest.makeSuite(MiniTwitTestCase))
+    suite.addTest(unittest.makeSuite(FlaskrTestCase))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='suite')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/flaskext_test.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,311 @@
+# -*- coding: utf-8 -*-
+"""
+    Flask Extension Tests
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Tests the Flask extensions.
+
+    :copyright: (c) 2010 by Ali Afshar.
+    :license: BSD, see LICENSE for more details.
+"""
+
+from __future__ import with_statement
+
+import os
+import sys
+import shutil
+import urllib2
+import tempfile
+import subprocess
+import argparse
+
+from flask import json
+
+from setuptools.package_index import PackageIndex
+from setuptools.archive_util import unpack_archive
+
+flask_svc_url = 'http://flask.pocoo.org/extensions/'
+
+
+# OS X has awful paths when using mkstemp or gettempdir().  I don't
+# care about security or clashes here, so pick something that is
+# actually rememberable.
+if sys.platform == 'darwin':
+    _tempdir = '/private/tmp'
+else:
+    _tempdir = tempfile.gettempdir()
+tdir = _tempdir + '/flaskext-test'
+flaskdir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+
+
+# virtualenv hack *cough*
+os.environ['PYTHONDONTWRITEBYTECODE'] = ''
+
+
+RESULT_TEMPATE = u'''\
+<!doctype html>
+<title>Flask-Extension Test Results</title>
+<style type=text/css>
+  body         { font-family: 'Georgia', serif; font-size: 17px; color: #000; }
+  a            { color: #004B6B; }
+  a:hover      { color: #6D4100; }
+  h1, h2, h3   { font-family: 'Garamond', 'Georgia', serif; font-weight: normal; }
+  h1           { font-size: 30px; margin: 15px 0 5px 0; }
+  h2           { font-size: 24px; margin: 15px 0 5px 0; }
+  h3           { font-size: 19px; margin: 15px 0 5px 0; }
+  textarea, code,
+  pre          { font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono',
+                 'Bitstream Vera Sans Mono', monospace!important; font-size: 15px;
+                 background: #eee; }
+  pre          { padding: 7px 15px; line-height: 1.3; }
+  p            { line-height: 1.4; }
+  table        { border: 1px solid black; border-collapse: collapse;
+                 margin: 15px 0; }
+  td, th       { border: 1px solid black; padding: 4px 10px;
+                 text-align: left; }
+  th           { background: #eee; font-weight: normal; }
+  tr.success   { background: #D3F5CC; }
+  tr.failed    { background: #F5D2CB; }
+</style>
+<h1>Flask-Extension Test Results</h1>
+<p>
+  This page contains the detailed test results for the test run of
+  all {{ 'approved' if approved }} Flask extensions.
+<h2>Summary</h2>
+<table class=results>
+  <thead>
+    <tr>
+      <th>Extension
+      <th>Version
+      <th>Author
+      <th>License
+      <th>Outcome
+      {%- for iptr, _ in results[0].logs|dictsort %}
+        <th>{{ iptr }}
+      {%- endfor %}
+    </tr>
+  </thead>
+  <tbody>
+  {%- for result in results %}
+    {% set outcome = 'success' if result.success else 'failed' %}
+    <tr class={{ outcome }}>
+      <th>{{ result.name }}
+      <td>{{ result.version }}
+      <td>{{ result.author }}
+      <td>{{ result.license }}
+      <td>{{ outcome }}
+      {%- for iptr, _ in result.logs|dictsort %}
+        <td><a href="#{{ result.name }}-{{ iptr }}">see log</a>
+      {%- endfor %}
+    </tr>
+  {%- endfor %}
+  </tbody>
+</table>
+<h2>Test Logs</h2>
+<p>Detailed test logs for all tests on all platforms:
+{%- for result in results %}
+  {%- for iptr, log in result.logs|dictsort %}
+    <h3 id="{{ result.name }}-{{ iptr }}">
+      {{ result.name }} - {{ result.version }} [{{ iptr }}]</h3>
+    <pre>{{ log }}</pre>
+  {%- endfor %}
+{%- endfor %}
+'''
+
+
+def log(msg, *args):
+    print '[EXTTEST]', msg % args
+
+
+class TestResult(object):
+
+    def __init__(self, name, folder, statuscode, interpreters):
+        intrptr = os.path.join(folder, '.tox/%s/bin/python'
+                               % interpreters[0])
+        self.statuscode = statuscode
+        self.folder = folder
+        self.success = statuscode == 0
+
+        def fetch(field):
+            try:
+                c = subprocess.Popen([intrptr, 'setup.py',
+                                      '--' + field], cwd=folder,
+                                      stdout=subprocess.PIPE)
+                return c.communicate()[0].strip()
+            except OSError:
+                return '?'
+        self.name = name
+        self.license = fetch('license')
+        self.author = fetch('author')
+        self.version = fetch('version')
+
+        self.logs = {}
+        for interpreter in interpreters:
+            logfile = os.path.join(folder, '.tox/%s/log/test.log'
+                                   % interpreter)
+            if os.path.isfile(logfile):
+                self.logs[interpreter] = open(logfile).read()
+            else:
+                self.logs[interpreter] = ''
+
+
+def create_tdir():
+    try:
+        shutil.rmtree(tdir)
+    except Exception:
+        pass
+    os.mkdir(tdir)
+
+
+def package_flask():
+    distfolder = tdir + '/.flask-dist'
+    c = subprocess.Popen(['python', 'setup.py', 'sdist', '--formats=gztar',
+                          '--dist', distfolder], cwd=flaskdir)
+    c.wait()
+    return os.path.join(distfolder, os.listdir(distfolder)[0])
+
+
+def get_test_command(checkout_dir):
+    if os.path.isfile(checkout_dir + '/Makefile'):
+        return 'make test'
+    return 'python setup.py test'
+
+
+def fetch_extensions_list():
+    req = urllib2.Request(flask_svc_url, headers={'accept':'application/json'})
+    d = urllib2.urlopen(req).read()
+    data = json.loads(d)
+    for ext in data['extensions']:
+        yield ext
+
+
+def checkout_extension(name):
+    log('Downloading extension %s to temporary folder', name)
+    root = os.path.join(tdir, name)
+    os.mkdir(root)
+    checkout_path = PackageIndex().download(name, root)
+
+    unpack_archive(checkout_path, root)
+    path = None
+    for fn in os.listdir(root):
+        path = os.path.join(root, fn)
+        if os.path.isdir(path):
+            break
+    log('Downloaded to %s', path)
+    return path
+
+
+tox_template = """[tox]
+envlist=%(env)s
+
+[testenv]
+deps=
+  %(deps)s
+  distribute
+  py
+commands=bash flaskext-runtest.sh {envlogdir}/test.log
+downloadcache=%(cache)s
+"""
+
+
+def create_tox_ini(checkout_path, interpreters, flask_dep):
+    tox_path = os.path.join(checkout_path, 'tox-flask-test.ini')
+    if not os.path.exists(tox_path):
+        with open(tox_path, 'w') as f:
+            f.write(tox_template % {
+                'env':      ','.join(interpreters),
+                'cache':    tdir,
+                'deps':     flask_dep
+            })
+    return tox_path
+
+
+def iter_extensions(only_approved=True):
+    for ext in fetch_extensions_list():
+        if ext['approved'] or not only_approved:
+            yield ext['name']
+
+
+def test_extension(name, interpreters, flask_dep):
+    checkout_path = checkout_extension(name)
+    log('Running tests with tox in %s', checkout_path)
+
+    # figure out the test command and write a wrapper script.  We
+    # can't write that directly into the tox ini because tox does
+    # not invoke the command from the shell so we have no chance
+    # to pipe the output into a logfile.  The /dev/null hack is
+    # to trick py.test (if used) into not guessing widths from the
+    # invoking terminal.
+    test_command = get_test_command(checkout_path)
+    log('Test command: %s', test_command)
+    f = open(checkout_path + '/flaskext-runtest.sh', 'w')
+    f.write(test_command + ' &> "$1" < /dev/null\n')
+    f.close()
+
+    # if there is a tox.ini, remove it, it will cause troubles
+    # for us.  Remove it if present, we are running tox ourselves
+    # afterall.
+
+    create_tox_ini(checkout_path, interpreters, flask_dep)
+    rv = subprocess.call(['tox', '-c', 'tox-flask-test.ini'], cwd=checkout_path)
+    return TestResult(name, checkout_path, rv, interpreters)
+
+
+def run_tests(extensions, interpreters):
+    results = {}
+    create_tdir()
+    log('Packaging Flask')
+    flask_dep = package_flask()
+    log('Running extension tests')
+    log('Temporary Environment: %s', tdir)
+    for name in extensions:
+        log('Testing %s', name)
+        result = test_extension(name, interpreters, flask_dep)
+        if result.success:
+            log('Extension test succeeded')
+        else:
+            log('Extension test failed')
+        results[name] = result
+    return results
+
+
+def render_results(results, approved):
+    from jinja2 import Template
+    items = results.values()
+    items.sort(key=lambda x: x.name.lower())
+    rv = Template(RESULT_TEMPATE, autoescape=True).render(results=items,
+                                                          approved=approved)
+    fd, filename = tempfile.mkstemp(suffix='.html')
+    os.fdopen(fd, 'w').write(rv.encode('utf-8') + '\n')
+    return filename
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Runs Flask extension tests')
+    parser.add_argument('--all', dest='all', action='store_true',
+                        help='run against all extensions, not just approved')
+    parser.add_argument('--browse', dest='browse', action='store_true',
+                        help='show browser with the result summary')
+    parser.add_argument('--env', dest='env', default='py25,py26,py27',
+                        help='the tox environments to run against')
+    parser.add_argument('--extension=', dest='extension', default=None,
+                        help='tests a single extension')
+    args = parser.parse_args()
+
+    if args.extension is not None:
+        only_approved = False
+        extensions = [args.extension]
+    else:
+        only_approved = not args.all
+        extensions = iter_extensions(only_approved)
+
+    results = run_tests(extensions, [x.strip() for x in args.env.split(',')])
+    filename = render_results(results, only_approved)
+    if args.browse:
+        import webbrowser
+        webbrowser.open('file:///' + filename.lstrip('/'))
+    print 'Results written to', filename
+
+
+if __name__ == '__main__':
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/moduleapp/__init__.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,7 @@
+from flask import Flask
+
+app = Flask(__name__)
+from moduleapp.apps.admin import admin
+from moduleapp.apps.frontend import frontend
+app.register_module(admin)
+app.register_module(frontend)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/moduleapp/apps/admin/__init__.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,14 @@
+from flask import Module, render_template
+
+
+admin = Module(__name__, url_prefix='/admin')
+
+
+@admin.route('/')
+def index():
+    return render_template('admin/index.html')
+
+
+@admin.route('/index2')
+def index2():
+    return render_template('./admin/index.html')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/moduleapp/apps/admin/static/css/test.css	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+/* nested file */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/moduleapp/apps/admin/static/test.txt	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+Admin File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/moduleapp/apps/admin/templates/index.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+Hello from the Admin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/moduleapp/apps/frontend/__init__.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,9 @@
+from flask import Module, render_template
+
+
+frontend = Module(__name__)
+
+
+@frontend.route('/')
+def index():
+    return render_template('frontend/index.html')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/moduleapp/apps/frontend/templates/index.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+Hello from the Frontend
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/static/index.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+<h1>Hello World!</h1>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/subdomaintestmodule/__init__.py	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,4 @@
+from flask import Module
+
+
+mod = Module(__name__, 'foo', subdomain='foo')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/subdomaintestmodule/static/hello.txt	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+Hello Subdomain
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/templates/_macro.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+{% macro hello(name) %}Hello {{ name }}!{% endmacro %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/templates/context_template.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+<p>{{ value }}|{{ injected_value }}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/templates/escaping_template.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,6 @@
+{{ text }}
+{{ html }}
+{% autoescape false %}{{ text }}
+{{ html }}{% endautoescape %}
+{% autoescape true %}{{ text }}
+{{ html }}{% endautoescape %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/templates/mail.txt	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+{{ foo}} Mail
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/templates/nested/nested.txt	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+I'm nested
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/templates/simple_template.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+<h1>{{ whiskey }}</h1>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tests/templates/template_filter.html	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,1 @@
+{{ value|super_reverse }}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bundled/flask/tox.ini	Thu Jan 27 18:23:59 2011 -0500
@@ -0,0 +1,5 @@
+[tox]
+envlist=py25,py26,py27
+
+[testenv]
+commands=make test