Pylons-1.0.1/0000775000076500000240000000000012012307216012660 5ustar benstaff00000000000000Pylons-1.0.1/.gitignore0000664000076500000240000000011111671720166014656 0ustar benstaff00000000000000*.pyc *.egg-info *.egg tests/test_units/cache/ tests/test_units/session/ Pylons-1.0.1/CHANGELOG0000664000076500000240000012050212012307124014070 0ustar benstaff00000000000000Pylons Changelog ================ 1.0.1 (August 13th, 2012) * No changes since RC1. 1.0.1RC1 (December 12, 2011) * Updated dependencies to latest versions of Paste, PasteDeploy, and compatibility for the latest WebOb 1.2 betas. * authenticate_form allows for GET. Patch by iElectric. * jsonify now properly sets charset to utf-8. * Add ability for jsonify to handle objects with a __json__ attribute using custom JSONEncoder class similar to TG2. Patch by Bob Farrell. * Added ability for __before__ to reference a callable function. Patch contributed by mverdone. * Pulled in JSON-RPC support from agentultra's pylons fork. * Apply patch for proper pylons.__version__ under Windows. Contributed by Christoph Zwerschke. * Utilize MarkupSafe for faster HTML escaping. * Fix signed cookies by using standard base64 alphabet, and prevent timing attacks on signature comparison. * Added setup of app_globals and config to Pylons config.init_app to ensure as long as the Pylons application is loaded, the app_globals and config will be appropriately initialized. * Documentation updates. 1.0 (May 27, 2010) * Minor tweak to allow proper importing of pylons. 1.0RC1 (March 1, 2010) * Switched to using Routes 1.12 with support for no longer using the odd routes singleton. * Removed pylons.middleware.StaticJavascripts, this is not used anymore. * Added more unit tests. 1.0b1 (February 5, 2010) * Removed CacheMiddleware. cache object is now setup as an attribute on the app_globals object for use where needed. * WARNING: config only supports dict access * WARNING: Method arguments no longer assigned to 'tmpl_context' by default. * WARNING: Changed default to strict_tmpl_context. * WARNING: Removed legacy pylons.c and pylons.g globals. * WARNING: Removed legacy pylons.database module. * WARNING: Removed legacy pylons.config module. * WARNING: Removed Buffet options, setup, and legacy render/render_response function from pylons.templating. This also means config no longer accepts the add_template_engine option. * WARNING: Removed legacy redirect_to function. * WARNING: @https decorator no longer accepts url_for-like arguments. * Add a "paster routes" command. This prints the mapper, which from Routes 1.12 onwards gives sensibly formatted output. * Fix unit tests on Windows * Prepare for Routes 1.12, ensure tests don't assume implicit routing 0.10 (May 27, 2010) * Fix legacy warning replacement. 0.10RC1 (March 1, 2010) * No changes to Pylons core since b1. 0.10b1 (February 5, 2010) * redirect_to is now deprecated, use redirect(url(*args, **kwargs)) instead. * url_for like args to the https decorator are now deprecated, pass it a url or a callable returning a url instead. * Changed 1.0 deprecated pylons.c, pylons.g, pylons.buffet instances to throw deprecation warnings. * Fixed etag_cache matching when the If-None-Match header contains a comma separated list of etags. Fixes #557. Thanks magicbronson. * Added tests for restcontroller with sub-directory, and fixed generated unit tests. Patches supplied by Michael van Tellingen, fixes #571. * Retain the original controller exception when thrown under environ['pylons.controller.exception'] for use in the error controller. * Fixed bug with unit tests running the app load twice during testing. Fixes #620. * Updated project templates to use actual config instance, rather than the StackedObjectProxy classes. * Changed PylonsConfig to be dict subclass, rather than DispatchingConfig subclass. 0.9.7 (February 23, 2009) * WARNING: A new option is available to determine whether or not an actions arguments should be automatically attached to 'c'. To turn off this implicit behavior in environment.py: config['pylons.c_attach_args'] = False This is set to True by default. * WARNING: Fixed a minor security hole in the default Pylons error page that could result in an XSS security hole. * WARNING: Fixed a security hole in the default project template to use the StaticURLParser to ensure arbitrary files can't be sent. * WARNING: Refactored PylonsApp to remove legacy PylonsApp, moved session/cache and routes middleware into the project template. This will require projects to be updated to include those 3 middleware in the projects middleware.py. * Added redirect, preferred over redirect_to. Takes an explicit url instead of url_for like arguments * Changed to using WebTest instead of paste.fixture for app testing. * Added render_mako_def to render def blocks within a mako template. * Changes to cache_decorator and cached_template to support Beaker API changes in version 1.1. 1.0.3 is still supported. * Fix HEAD requests causing an Exception as if no content was returned by the controller. Fixes #507. Thanks mvtellingen, Petr Kobalicek. * Fix a crash when returning the result of ``etag_cache`` in a controller. Fixes #508. * "response" flag has been removed from pylons.decorators.cache.beaker_cache, as it sends all headers along unconditionally including cookies; additionally, the flag was taking effect in all cases previously so prior versions of beaker_cache are not secure. In its place, a new option "cache_headers" is provided, which is a tuple of specific header names to be cached. It defaults to ('content-type','content-length'). * "invalidate_on_startup" flag added to beaker_cache, which provides a "starttime" to the cache such that when the application is started or restarted, the cache entry is invalidated. * Updating host to use 127.0.0.1 for development binding. * Added option to specify the controller name with a __controller__ variable in the controller's module. This name will be used for the controller class rather than the default naming scheme. * setup.py egg_info now restores projects' paster_plugins.txt, allowing paster shell to work again after the egg-info directory was lost. fixes #282. Thanks sevkin. * The paste_deploy_config.ini_tmpl template is now located at package/config/deployment.ini_tmpl for new projects. * Project's default test fixtures no longer hardcode test.ini; the ini file used can now be specified via the nosetests --with-pylons argument (defaults to test.ini in setup.cfg). fixes #400. * @validate now defaults to translating FormEncode error messages via Pylons' gettext catalog, then falls back to FormEncode's. fixes #296. Thanks Max Ischenko. * Fixed SQLAlchemy logging not working in paster shell. Fixes #363. Thanks Christoph Haas. * Added optionally engine initialization, to prevent Buffet from loading if there's no 'buffet.template_engines' in the config. * Updated minimal template to work with Tempita and other new templating changes. * Fixed websetup to parse location config file properly when the section isn't 'main'. Fixes #399. * Added default Mako filter of escape for all template rendering. * Fixed template for Session.remove inclusion when using SA. Fixed render_genshi to properly use fragment/format options. Thanks Antonin Enfrun. * Remove template engine from load_environment call. * Removing template controller from projects. Fixes #383. * Added signed_cookie method to WebOb Request/Response sub-classes. * Updated project template to setup appropriate template loader and controller template to doc how to import render. * Added documentation for render functions in pylons.templating. * Adding specific render functions that don't require Buffet. * Added forward controller.util function for forwarding the request to WSGI apps. Fixes #355. * Added default input encoding for Mako to utf-8. Suggested in #348. * Fixed paster controller to raise an error if the controller for it already exists. Fixes #279. * Added __init__.py to template dir in project template if the template engine is genshi or kid. Fixes #353. * Fixed jsonify to use application/json as its the proper mime-type and now used all over the net. * Fixed minimal template not replacing variables properly. Fixes #377. * Fixed @validate decorator to no longer catch exceptions should they be raised in the action that is supposed to display a form. Fixes #374. * Fixed paster shell command to no longer search for egg_info dir. Allows usage of paster shell with installed packages. Suggested by Gavin Carothers. * Added mimetype function and MIMETypes class for registering mimetypes. * WARNING: Usage of pylons.Response is now deprecated. Please use pylons.response instead. * Removed use of WSGIRequest/WSGIResponse and replaced with WebOb subclasses that implement methods to make it backwards compatible with the Paste wsgiwrappers. * Fixed missing import in template controller. * Deprecated function uses string substitution to avoid Nonetype error when Python optimization is on. Fixes #334. * E-tag cache no longer returns Content-Type in the headers. Fixes #323. * XMLRPCController now properly includes the Content-Length of the response. Fixes #310, thanks Nicholas. * Added SQLAlchemy option to template, which adds SQLAlchemy setup to the project template. * Switched project templating to use Tempita. * Updated abort/redirect_to to use appropriate Response object when WebOb is used. * Updated so that 404's properly return as Response objects when WebOb is in use instead of WSGIResponse. * Added beaker_cache option to avoid caching/restoring global Response values that were present during the first cache operation. * Adding StatusCodeRedirect to handle internal redirects based on the status code returned by the app. This replaces the use of ErrorDocuments in projects. * Refactored error exceptions to use WebError. * WSGIController now uses the environ references to response, request, and the c object for higher performance. * Added optional use of WebOb instead of paste.wsgiwrapper objects. * Fixed bug with beaker_cache defaulting to dbm rather than the beaker cache app-wide default. * The --with-pylons nose plugin no longer requires a project to have been registered with setuptools to work. * The config object is now included in the template namespace. * StaticJavascripts now accepts keyword arguments for StaticURLParser. Suggested by Marcin Kasperski. * Fix pylons.database.AutoConnectHub's doInTransaction not automatically connecting when necessary. Fixes #327. 0.9.6.1 (September 27th, 2007) * Fixed validate decorator to resume pre-0.9.6 behavior of only validating POST requests by default. Added option to validate during GET as well and a recursion avoidance check to prevent validate from running more than once. * WARNING: Fixed a security hole allowing private controller methods (those beginning with an underscore) to be accessed from the outside. Found by Tomasz Nazar. * Added nose plugin '--with-pylons=test.ini' option to load the Pylons app before scanning for unit tests. This enables Pylons apps to be unit tested with doc tests. * PylonsBaseWSGIApp now caches controller lookup and the effective logging level for a little better performance. 0.9.6 (September 8th, 2007) * Updated requirements for newer WebHelpers for SQLAlchemy 0.4 compatibility. Fixes #300. * Fixed pylons.templating to not pull session objects if there are none in use for the request. Thanks Bob Ippolito. * Catch UnicodeEncodeErrors when finding the Controller action method and fail gracefully. Thanks max. Fixes #298. * Allow passing of a state keyword to the validate decorator for the to_python methods. Fixes #297. * paster shell now configures logging from the config file, like paster serve and setup-app. This can be disabled via the -q option. Thanks Yannick Gingras. 0.9.6rc3 (August 18, 2007) * Fixed controllers.core to allow responses of None (empty bodies). Logs a message indicating the response was empty. * pylons.helpers has been moved to pylons.controllers.util, to differentiate between controller utility functions and projects' helpers modules. * Fixed non-basestring/generator/WSGIResponse objects returned from Controllers not being set as the response content. Thanks Alex Conrad. * development.ini now configures the app's Logger level to DEBUG by default. Thanks Christoph Haas 0.9.6rc2 (August 2, 2007) * Projects now include a MANIFEST.in file: it directs distutils to recursively include all files in the project's public/ and templates/ dir. This fixes these dirs not being included in dists unless they were checked into an RCS recognized by setuptools. This is at the expense of dists now globbing all files in those dirs (even those not checked into your RCS). Thanks Christoph Haas. * Fixed the validate decorator not setting c.form_errors in certain circumstances. Thanks max. Fixes #286. * email_to lines commented out in development.ini and test.ini files to avoid emails being sent to a non-existent address by mistake. If an error occurs it is logged but no email is sent unless email_to is specified. * [paste.app_factory] entry points changed to point to the actual make_app() function to make it simpler for someone to work out how Pylons works (tests updated accordingly too). * All use of the ez_setup module is now tested by an ImportError to make Pylons compatible with Buildout. Note: Tags and releases should be made using an svn export and an svn add to ensure a real copy of the ez_setup module is included and not just an svn:external so that the module is tied to time of the release. * More full-featured README.txt included. * Updated beaker_cache to cache global response cookies/status/headers. Fixes #280. * Fixed missing abort name import in restrict rest decorator. Fixes #281. * Added cheetah as a supported template language for template_engine option. * Fixed public/ and templates/ directories not being created with paster create. 0.9.6rc1 (July 15, 2007) * Fixed cookie header addition to use add instead of append. Thanks to anonymous patcher. Fixes #268, again. * Added ability to pass _code option to specify the status code type for redirect_to. * Fixed redirect_to to not copy all headers into redirect for old _response usage. Fixes #268. * WARNING: By default, the Pylons request object now returns unicode parameter (pylons.GET/POST/params) values (and assumes those parameters were sent to Pylons as utf-8). Unicode parameters can cause major problems if your application is not setup to handle unicode. To disable unicode parameters (0.9.5 default behavior), add the following to your load_environment function (0.9.6 syntax): config['request_options']['charset'] = None or, if still using the deprecated pre-0.9.6 pylons.config syntax, add: request_settings = pylons.config.request_defaults.copy() request_settings['charset'] = None return pylons.config.Config(tmpl_options, map, paths, request_settings=request_settings) * WARNING: Template names beginning with a / (or the OS's path separator) will now result in the name not having the separator's replaced with '.'s for the template engine. This shouldn't affect most projects as they usually assume a dot notation will be used with dot notation template engines (Kid, Genshi, etc.). This change allows template engines that can take filename paths to function properly. Fixes #233. * WARNING: The pylons.util.get_prefix(environ) function is deprecated. Please use: environ.get('SCRIPT_NAME', '') instead (the get_prefix function is used in the default ErrorController). Fixes #243. * WARNING: The paths dictionary's 'root_path' has moved to the less redundant 'root'. * Fixed the Error Documents/EvalException css referencing non-existent images. Thanks Shannon -jj Behrens. Fixes #238. * Added ability to pass _code option to specify the status code type for redirect_to. * Fixed redirect_to to not copy all headers into redirect for old _response usage. Fixes #268. * Added logging statements throughout Pylons code, added logging setup to default template. Fixes #98. * Refactored global response to be setup in wsgiapp along with the other globals. Updated WSGIController to copy in global response headers and cookies into a WSGI app's output. * Added global pylons.response object. Thanks Shannon -jj Behrens and Damjan Georgievski. Fixes #268 and #201. * Updated default project template files for new configuration layout. Options to handle config now just in environment.py, and middleware.py handling just middleware. Fixes #203. * Removing mako tests, as its now the default. Default test changed from Myghty to Mako. * Changing default templating to mako. * Added the https decorator. It requires an action to be loaded via https. Patch by ido. Fixes #241. * Added upgrade instructions, and posted a copy on the wiki. Fixes #230. * Added deprecation warnings for usage of the Pylons Controller class, all controllers should inherit from WSGIController instead. Fixes #239. * Removed deprecated attach_locals function from Controller class. * Added an authenticate_form decorator for use with WebHelpers' secure_form_tag functions for preventing CSRF attacks. Original patch by David Turner. Fixes #157. * Fix Buffet's include_pylons_variables not being upheld. Thanks Jonathan LaCour. * The validate decorator now accepts extra keyword arguments (**htmlfill_kwargs) to pass along to formencode's htmlfill.render function. * Removed POST-only restriction on validate decorator, now handles GET requests. No form arg required during a GET request, which will run the current action with c.form_errors set to the errors. Fixes #246. * Added PylonsConfig, which gets accessed as pylons.config dict. Contains all the merged ini options, in addition to the Config options such as 'routes.map', 'pylons.paths', 'buffet.template_options', etc. Check the pylons.config docs on PylonsConfig for dict keys populated by it. * Split up resolution stages in wsgiapp, so that controller lookup is a separate function making it easier to subclass. PylonsApp now takes a base_wsgi_app argument which is then used for the BaseWSGIApp instead of the one from wsgiapp.py. * Added mako template render tests. * Added storage of the action func used to handle a call, for later code that might need a reference to the action that originally handled the request. Fixes #253. * Updated config object to optionally take a single merged conf dict, updated project templates to pass around the single merged conf dict. * Changed project template to use new Beaker session keys. * Changed default routing for raw template matching to not unicode decode the route argument. Fixes #242. * Catch any exceptions raised by template engine entry points and emit a warning instead of crashing. Thanks markbradley. Fixes #249 * Fixed the validate decorator not working with formencode's CompoundValidators when variable_decode=False. Fixes #209. * Fixed the validate decorator failing with a KeyError when no value is specified to validate against for separate validators (as opposed to a schema). Reported by Graham Stratton. * Fixed paster shell not merging app_conf and global_conf into the main CONFIG dict namespace. Original patch by David Smith. Fixes #244. * Added logging to decorators. Refs #98. * Fixed paster restcontroller to test for lib.base and only add that import statement when its present. This fixes the restcontroller template when used with minimal Pylons project templates. Fixes #237. * Fixed the EvalException debugger showing broken links and buttons when the app's ErrorController was broken (such as when BaseController's __before__ raises an exception). Suggested by Ian Bicking. Fixes #228. * paster create now accepts a 'template_engine' option to setup the new project's default template engine. E.g. to create a new project that uses Genshi by default, use: paster create --template=pylons mygenshiproj template_engine=genshi Suggested by Ian Bicking. Fixes #141. * Fixed the validate decorator triggering the following error with FormEncode>=0.7 and non-ascii rendered form content: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128) the form was passed in as an encoded string, but some data or error messages were unicode strings; the form should be passed in as a unicode string Reported by Christoph Haas. * HTTPExceptions are now converted to Response objects (for __after__), making the httpexceptions middleware no longer required. * Added Warning to jsonify to warn about cross-site attacks when returning a list as the outer-most element to jsonify. Fixes #232. * Fixed beaker_cache decorator to take optional keyword arguments intended for the backend cache container (such as url for memcached). * Fixed paster controller assuming the minimal template was in use when the lib.base module existed but raised an exception. * Fixed bug in XMLRPC Controller not setting proper Content-Type. Fixes #236. * Added the '-d' ('--disable-ipython') option to paster shell for disabling IPython. * Allow creation of controllers named 'setup' via paster controller. Reported by Matt Good. * Added support for generic arguments to SQLAlchemy's create_engine of the form sqlalchemy.* from the PasteDeploy config file. 0.9.5 (Apr 11th, 2007) * Fixed a Python 2.3 incompatibility with paster shell, causing the Exception: File "Pylons-0.9.5-py2.3.egg/pylons/commands.py", line 357, in command locs.update([(name, getattr(base, name)) for name in base_public]) AttributeError: keys * Fixed paster shell breaking for projects where the base package was not the first package listed in top_level.txt. Patch from Alberto Valverde. Fixes #229. * Fixed doc references to config['app_conf']. Fixes #116. * Changed `get_engine_conf` to properly evaluate sqlalchemy echo statement when its 'debug'. Fixes #226. * make_session and create_engine now accept keyword arguments to pass to SQLAlchemy's create_engine. * make_session now accepts the keyword argument 'session_kwargs' to pass to SQLAlchemy's create_session. * Fixed _inspect_call to call function with keyword arguments instead of list args. Corrects issue with action defaults that caused the value for the latter args to be in the wrong spots. Spotted by Topher. Fixes #223. * Added the allow_none option (passed to xmlrpc.dumps) to XMLRPCController. Suggested by Jaroslaw Zabiello. * Updated XMLRPC Controller with patch for name lookup and additional unit tests for the patch. Fixes #216. * Updated docs for validate decorator to more clearly illustrate what the post_only args apply to. Fixes #221. * Added ability to return strings in the WSGIController. Fixes #218. * Added lazy i18n translation functions. Patch from David Smith. Fixes #181. * Added fix for XMLRPCController system.methodHelp function and unit test. Patch and unit test submitted by Graham Higgins. * Fixed bug in validate decorator with new UnicodeMultiDict response content not properly retaining form content as unicode for formencode's htmlfill. * Fixed bug in XMLRPC Controller with xmlrpclib Faults not being properly transformed into a WSGI response within the controller. * WARNING: Pylons now requires the decorator module: it no longer packages it as pylons.decorator. Code relying on the pylons.decorator.decorator function will trigger a deprecation warning and should be changed to use decorator.decorator. * WARNING: pylons.h was deprecated for using projects' lib.helpers module directly in 0.9.3. pylons.h is now formally deprecated (emits DeprecationWarnings). Projects still accessing pylons.h must change the following import: from pylons import h to: import MYPROJ.lib.helpers as h * pylons.jsonify and pylons.Controller references have been deprecated (they are misplaced references). They continue to be available at pylons.decorators.jsonify and pylons.controllers.Controller, as they always have been. * Updated templating Buffet to recognize format parameter and properly pass it to the template engine. * Updated LICENSE for new year and to indicate license covering templates generated. Fixes #188. * Interactive debugger now supports Mako. After r1780 if you are using a custom theme you will need to change '%(myghty_data)s' to '%(template_data)s' in your template. If you are using JavaScript the tab id is now "template_data". * Fixed bug in WSGIController with private function attempts not returning a valid WSGI response. * Added full unit test coverage of cache decorator. * Adding messages binary file, enabling i18n unit tests. Updating pylons.i18n to import LanguageError. Fixes #193. * Adding i18n tests, not active yet as they're waiting on a binary file from a patch. Refs #193. * Updated tests so that they now work with nose, removing py.test requirement. * Switching config setup to load keys into main config dict with app_conf and global_conf keys set for any code looking for those keys. Fixes #116. * PylonsInstaller is now the default paste.app_install entry point for new projects: this makes Cheetah no longer required for the paster make-config command. (Thanks Alexander Schremmer, Ian Bicking) * Added custom redirect_to function in pylons.helpers that will take an optional _response arg to pull headers and cookies out for preservation during a redirect. Fixes #136. * Changed config.Config.__init__ to take all options as keyword args so unused args can be skipped. Fixes #162. * The request object can now automatically decode GET/POST/params vars to unicode, when its charset attribute is set. * Added a new request_settings keyword arg to Config's constructor. Allows setting the default charset and errors values of of the request object. * Deprecated Config constructor's default_charset keyword arg. Use Config's response_settings keyword arg instead. * Fixed paster controller to test for lib.base and only add that import statement when its present. This fixes the controller template when used with minimal Pylons project templates. Fixes #140 and fixes #139. * Fixed the paster shell error: KeyError: 'pylons.routes_dict' when calling app.get and app.post. * Fixed paster shell not working on projects with names containing hyphens. * Fixed the config directive 'sqlalchemy.echo' set to False being interpreted as True. Patch by Alex Conrad. * Fixed paster shell not restoring CONFIG['global_conf']. 0.9.4.1 (Jan. 5th, 2007) * Added restcontroller command that generates a RESTful controller template and provides the appropriate map.resource command to add. Suggested by Matthew Scott. * Fixed SQLObject pylons.database.PackageHub error: exceptions.NameError: global name 'CONFIG' is not defined * Fixed pylons.database.session_context not working outside of requests (such as in websetup.py). * Updated template options config to take template options for multiple engines for less binding to Myghty. * Fixed paster shell incorrectly importing the the tuple (model,) as the model object. 0.9.4 (Dec. 29th, 2006) * WARNING: Removed the lang_extract and lang_compile commands. They used pygettext.py and its associated msgfmt.py, which lacked the ability to extract ngettext style function calls and had issues with unicode strings. The new I18NToolBox project aims to provide this functionality (and more) via the gettext command line utilities. http://i18ntoolbox.ufsoft.org * All Pylons special objects are now available within paster shell (not just h and g). * WARNING: Myghty's allow_globals config var has changed, causing the following when running pre-compiled templates: Error(TypeError): do_run_component() takes exactly 13 non-keyword arguments (5 given) Delete the compiled Myghty templates directory (specified by cache_dir or myghty_data_dir in the config file) to resolve the error. * Changed i18n functions in templates to use proxy objects so that using set_lang in a template works right. Fixes #153. * Now allowing any template plugin to overwrite global PYLONS_VARS (such as c, g), not just pylonsmyghty. * Adding SQLAlchemy support to the database.py file. Saves the session engine to g to maintain it during the apps lifetime. Uses SessionContext plugin for management of the current session. * Updated config object so that init_app can take an optional template engine argument to declare the default template engine. * Updated Myghty plugin to use extra_vars_func when passed in. * Fixed Buffet to use extra_vars_func properly. * Fixed the validate decorator when there are validation errors and variable_decode=True: now passing the original params to htmlfill.render instead of the varable_decode'd version. Patch by FlimFlamMan. * Added ungettext function for use with pluralized i18n, and the N_ function (gettext_noop) to mark global strings for translation. Added ungettext, N_ and translator objects to be globals for templates. Refs #126. * WARNING: The localization function '_' now uses ugettext (returns unicode strings) instead of gettext. To preserve the old behavior, append the following line to your project's lib.base and lib.helpers imports: from pylons.helpers import gettext as _ * Pylons special objects are now available within the interactive debugger (deprecating _attach_locals). * Added setup-app run before unit tests run so that webapp has proper setup tasks handled. Fixes #113. * Added paste.deploy.CONFIG setup to middleware.py, websetup.py and testing files in the Pylons project templates. Closes #112. * Added security policy doc to index for use as Pylons security policy. Closes #91. * Improved the repr() of the c context object to show attributes. * Set environ['paste.testing_variables'] whenever that key is available, not just in testing mode. * Added capability to have an action be a generator function. * Added introspection capability to XMLRPCController and signature checking. * Updated Controller to use additional arg lookup scheme so that the source of the function args for _inspect_call can be easily overridden. * Updated RPCController, renamed to XMLRPCController. XMLRPCController now functions properly and will automatically return proper xmlrpc responses. * Added test configuration ini file to default template. Closes #114. * Fixed problem with pylons.database.PackageHub.__get__ raising errors other than AttributeError when the database isn't configured. Added new UnconfiguredConnectionError exception, instead of just KeyError or TypeError (depending on what part of the configuration failed). * Fixed default g init, since bare object has no init method. Reported by Ian Bicking. * Fixed issue with SQLObject method override having wrong name. Reported by climbus with patch. Fixes #133. * Moved log function to pylons.helpers and translation functions to pylons.i18n. using pylons.util purely for Pylons internal util functions. * WARNING: Removed 0.8.x legacy code and backwards compatibility functions. * PylonsApp now has option to not use Routes middleware, default resolving uses new wsgi.org routing_args spec. * Refactored routes dispatching to use new Routes middleware. * Fixed paster shell command to properly acquire mapper object without relying on the template being configured in a specific manner. * Added keyword argument pool_connection to pylons.database.PackageHub; if set to false then SQLObject connections won't use pooled database connections (a new connection will be opened for each request). 0.9.3 (Nov 1st, 2006) * Updated project template to support full_stack option to make it easier to use Pylons apps within larger WSGI stacks. * Added deprecation warnings to legacy objects and for 1.0 functionality that will change. * Added cache decorator and Cheetah template functional tests. Patch and unit tests provided by Climbus. * Fixed readline support in the stock interactive console paster shell. Reported by Alex Conrad. * A controller's __after__ method will now be called after actions invoke redirect_to (or raise any HTTPException). Reported by David Turner. * Fixed config to use myghty_data_dir instead of cache_dir setting if its set as well. Reported by Shannon -jj Behrens. * Added traceback hiding so that more of the traceback relating to Pylons code is removed from the default traceback making it easier to focus on the code in an app that actually caused the problem. Closes #119. * Added ability to use '_' translation method directly from templates and in the controller without having to use it under h._. * Added 's' and 'l' Myghty escaping flags to default project templates. Suggested by Jamie Wilkinson. Closes #110. * Fixed SCGI bug with QUERY_STRING test when WSGI states it doesn't have to exist. Reported by Riklaunim. * Added pylons_minimal template, prone to fine-tuning. * Added option for PylonsApp to take a globals object to avoid checking a hardcoded path for a Globals object. * Removed old Helpers legacy object entirely, replaced pylons.h with proper StackedObjectProxy. Cleaned up PylonsApp and PylonsBaseApp to accept a helpers reference so that Pylons can be ignorant of where the helpers came from. * Fixed bug with lang app_conf option being set improperly. Reported by Laurent. * Fixed pylons.h to work proper with new and old-style helper imports. * Fixed render functions always passing disable_unicode=False to Myghty. 0.9.2 (Sept. 7th, 2006) * Fixed problem with dashes in controller names, resolves #107. * Updated default ini file to use localhost from address. Refs #104. * Updated default development.ini to use a single cache_dir setting which is the base dir that cache files, session files, and template caching will be saved in. Config object now looks to cache_dir setting properly for Myghty templates. Fixes #104. * Updated default template controller to provide better example of directly serving Myghty templates. * Fixed legacy (0.8) controller methods' **ARGS (also m.request_args and pylons.params) to be of the expected mixed dictionary instead of MultiDict. * Fixed _attach_locals not attaching g and cache objects. * Added g object to the shell. Works as long as the Pylons app can respond to a path of '/'. The pylons.g variable will also be setup properly for use in the shell. * Myghty template options are now passed properly to the template creation, and allow_globals now works to add Myghty template globals. * Re-organized helpers, switched Helpers class to use static methods to reduce code duplication. * Helpers cleanup: - Old-style Helper object uses StackedObjectProxy just like the new scheme, thus avoiding possible WSGI stack issues. - New project templates use new-style Helpers scheme. - Updated wsgiapp to utilize new Helpers cleanup style. The 'h' object is now friendlier to use, and maps directly to a projects lib.helpers file. No more wacky Helpers object proxying to it. - Added translator global to __init__.py for use with new Helpers cleanup. - Copied Helpers function methods directly into util so they can be used stand-alone. - Deprecated h.lang (for h.set_lang/h.get_lang) * Moved the 'default_charset' option from PylonsApp's constructor to Config's. * Added 'error' controller route to the top of the Pylons template to avoid the common issue people discover when removing the generic default route. * Changing validate decorator to have variable_decode option, which will also run formencode's variable_decode function over the form input. * Switched to using Context obj classes instead of RequestLocal which is being phased out. * Added an 'encode_variables' option to the validate decorator. * Switched all current_obj calls to _current_obj to avoid triggering deprecation warnings. * Added is_xhr to Request object in Paste. * Bumping up dependency to latest Paste. * Switching back to prior controller import check, throwing a more detailed error with a suggest fix should the user really want a URL with that name in it. (refs #67) * Fixes bug with prior fix for #67. Wasn't properly testing the full package name to include the current project which would incorrectly restrict valid controller names (refs #67). * Fixed '_method_' checking to test in a more efficient manner. * Added deprecation warning for legacy mode activation. Not necessary to update multiple files, as all of legacy mode is enabled via the Legacy WSGI app. Fixes #89. * Fixed controller command to check controller name and refuse to create controllers that have name clashes with existing modules that could be imported. Reported (with patch) by Chuck Adams. Fixes #67. * Added capability for 'c' object to throw an exception when an attribute is used that doesn't exist. Closes #84. * Fix for endless error document call when an error document controller wants to throw a error that the error_mapper catches. 0.9.1 (August 11th, 2006) * Fixed __all__ export typo in templating.py. Added example of render with a template. * Fixed issue with set_lang not using proper CONFIG var. * Minor tweaks to update docs in pylons.helpers and move remaining legacy code into legacy module. Updated wsgiapp to refer to new locations of legacy compatibility objects. * The interactive debugger's 'full traceback' link is now only displayed when the full traceback differs from the regular (includes hidden frames). * Providing an optional text version of exception tracebacks and the associated extra data within the interactive debugger. * The 'Debug at: http://hostname/_debug/view/XXXXX' URLs now display the interactive debugger properly skinned. * Fixed issue in PasteScript with new controller sub-directories lacking a __init__.py file. This fixes an import error when using the controller. PasteScript dependency updated to fixed version. Reported by Artur Lew. * Removed lowercasing of the module name during resolver import. * Removed [full] recommendation from docs. 0.9 (July 28th, 2006) * config file option 'debug' now defaults to false when undefined * Removed the components directory from the template * Updated paste.errordocuments support * Fix for multi-word controller names such that front_page / FrontPageController can be used as a controller name. Patch contributed by Timo Mihaljov. * Cleaned up imports in wsgiapp and new project to better reflect where things really come from. * Removed unnecessary myghty usage from wsgiapp for url unescaping, now uses urllib as the myghty function did. * Removing 'response' to import, sticking with Response as its more consistent with the fact that Response is a class/factory and not an instance like request, and the other lower-case objects. * Added redirect_to under pylons.helpers, and added import from helpers directly into lib/base.py for use in controllers. * Consolidated legacy objects into legacy module. * Adding abort method that raises the appropriate exception for the status code. * Removing form_fill, obsolete by the validate decorator. * Relocated 'params' object to only take effect in legacy mode. * Updated Pylons template to use WSGIController as the new default Controller. * Altered the wsgi dispatch to examine the controller, and instantiate it if it's just a class. Otherwise, if the controller is a subclass of Controller but not of WSGIController, it assumes its an older Controller class that may return a WSGIResponse, and calls it appropriately. * Dispatch now fixes up environ to move 'path_info' Route var into the WSGI PATH_INFO, and the rest is pushed into SCRIPT_NAME. This is for use with other WSGI apps under controller mount points. * Added WSGIController which takes a normal WSGI interface call and returns the appropriate WSGI response. * Added automatic copying of Route variables declared in an action's function definition to the 'c' object. * WebHelpers' .js files are now automatically published under the '/javascripts/' URL path. Individual WebHelpers' .js files can be overridden by other .js files inside the project's 'public/javascripts' directory * Added exception toss when a template engine doesn't exist. * Added alias option to Buffet to support aliasing more template engines to other engine names * Buffet enhancements to support caching of any template with any template engine * All render commands processed through Buffet * Backwards compatibility 'm' object for use with legacy projects * Added use of Beaker middleware for session and caching functionality * Fixed error traceback and updated template to use proper error images and stylesheets. 0.8.2 (**dev**) * Fixed default controller to allow for actions with - in them. The - will be replaced with an underscore, while the original action name in the mapper dict is unchanged. Patch by Thomas Sidwick. 0.8.1 (May 10th, 2006) * Added REST decorators and re-arranged decorator layout to support more styles of decorators for future expansion. * Fixed dependency requirement bug that had Pylons locked to simplejson 1.1 even though a newer version was out. Pylons-1.0.1/ez_setup.py0000775000076500000240000002276411645401275015121 0ustar benstaff00000000000000#!python """Bootstrap setuptools installation If you want to use setuptools in your package's setup.py, just include this file in the same directory with it, and add this to the top of your setup.py:: from ez_setup import use_setuptools use_setuptools() If you want to require a specific version of setuptools, set a download mirror, or use an alternate download directory, you can do so by supplying the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import sys DEFAULT_VERSION = "0.6c9" DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] md5_data = { 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', } import sys, os try: from hashlib import md5 except ImportError: from md5 import md5 def _validate_md5(egg_name, data): if egg_name in md5_data: digest = md5(data).hexdigest() if digest != md5_data[egg_name]: print >>sys.stderr, ( "md5 validation of %s failed! (Possible download problem?)" % egg_name ) sys.exit(2) return data def use_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15 ): """Automatically find/download setuptools and make it available on sys.path `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where setuptools will be downloaded, if it is not already available. If `download_delay` is specified, it should be the number of seconds that will be paused before initiating a download, should one be required. If an older version of setuptools is installed, this routine will print a message to ``sys.stderr`` and raise SystemExit in an attempt to abort the calling script. """ was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules def do_download(): egg = download_setuptools(version, download_base, to_dir, download_delay) sys.path.insert(0, egg) import setuptools; setuptools.bootstrap_install_from = egg try: import pkg_resources except ImportError: return do_download() try: pkg_resources.require("setuptools>="+version); return except pkg_resources.VersionConflict, e: if was_imported: print >>sys.stderr, ( "The required version of setuptools (>=%s) is not available, and\n" "can't be installed while this script is running. Please install\n" " a more recent version first, using 'easy_install -U setuptools'." "\n\n(Currently using %r)" ) % (version, e.args[0]) sys.exit(2) else: del pkg_resources, sys.modules['pkg_resources'] # reload ok return do_download() except pkg_resources.DistributionNotFound: return do_download() def download_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay = 15 ): """Download setuptools from a specified location and return its filename `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. """ import urllib2, shutil egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) url = download_base + egg_name saveto = os.path.join(to_dir, egg_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads try: from distutils import log if delay: log.warn(""" --------------------------------------------------------------------------- This script requires setuptools version %s to run (even to display help). I will attempt to download it for you (from %s), but you may need to enable firewall access for this script first. I will start the download in %d seconds. (Note: if this machine does not have network access, please obtain the file %s and place it in this directory before rerunning this script.) ---------------------------------------------------------------------------""", version, download_base, delay, url ); from time import sleep; sleep(delay) log.warn("Downloading %s", url) src = urllib2.urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = _validate_md5(egg_name, src.read()) dst = open(saveto,"wb"); dst.write(data) finally: if src: src.close() if dst: dst.close() return os.path.realpath(saveto) def main(argv, version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" try: import setuptools except ImportError: egg = None try: egg = download_setuptools(version, delay=0) sys.path.insert(0,egg) from setuptools.command.easy_install import main return main(list(argv)+[egg]) # we're done here finally: if egg and os.path.exists(egg): os.unlink(egg) else: if setuptools.__version__ == '0.0.1': print >>sys.stderr, ( "You have an obsolete version of setuptools installed. Please\n" "remove it from your system entirely before rerunning this script." ) sys.exit(2) req = "setuptools>="+version import pkg_resources try: pkg_resources.require(req) except pkg_resources.VersionConflict: try: from setuptools.command.easy_install import main except ImportError: from easy_install import main main(list(argv)+[download_setuptools(delay=0)]) sys.exit(0) # try to force an exit else: if argv: from setuptools.command.easy_install import main main(argv) else: print "Setuptools version",version,"or greater has been installed." print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' def update_md5(filenames): """Update our built-in md5 registry""" import re for name in filenames: base = os.path.basename(name) f = open(name,'rb') md5_data[base] = md5(f.read()).hexdigest() f.close() data = [" %r: %r,\n" % it for it in md5_data.items()] data.sort() repl = "".join(data) import inspect srcfile = inspect.getsourcefile(sys.modules[__name__]) f = open(srcfile, 'rb'); src = f.read(); f.close() match = re.search("\nmd5_data = {\n([^}]+)}", src) if not match: print >>sys.stderr, "Internal error!" sys.exit(2) src = src[:match.start(1)] + repl + src[match.end(1):] f = open(srcfile,'w') f.write(src) f.close() if __name__=='__main__': if len(sys.argv)>2 and sys.argv[1]=='--md5update': update_md5(sys.argv[2:]) else: main(sys.argv[1:]) Pylons-1.0.1/LICENSE0000664000076500000240000000543311645412556013711 0ustar benstaff00000000000000Copyright (c) 2005-2011 Ben Bangert, James Gardner, Philip Jenvey and contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author or contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. ------------------------------------------------------------------------------- ALL TEMPLATES GENERATED ARE COVERED UNDER THE FOLLOWING LICENSE: Copyright (c) 2005-2011 Ben Bangert, James Gardner, Philip Jenvey and contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following condition is met: The name of the author or contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. Pylons-1.0.1/MANIFEST.in0000664000076500000240000000035611645401275014435 0ustar benstaff00000000000000recursive-include pylons/templates * recursive-include pylons/media * recursive-include tests * include CHANGELOG include LICENSE include UPGRADING recursive-exclude tests/test_units/session * global-exclude .DS_Store *.hgignore *.hgtags Pylons-1.0.1/PKG-INFO0000664000076500000240000000714212012307216013761 0ustar benstaff00000000000000Metadata-Version: 1.0 Name: Pylons Version: 1.0.1 Summary: Pylons Web Framework Home-page: http://www.pylonshq.com/ Author: Ben Bangert, Philip Jenvey, James Gardner Author-email: ben@groovie.org, pjenvey@underboss.org License: BSD Description: Pylons ====== The Pylons web framework is designed for building web applications and sites in an easy and concise manner. They can range from as small as a single Python module, to a substantial directory layout for larger and more complex web applications. Pylons comes with project templates that help boot-strap a new web application project, or you can start from scratch and set things up exactly as desired. Example `Hello World` --------------------- .. from paste.httpserver import serve from pylons import Configurator, Response class Hello(object): def __init__(self, request): self.request = request def index(self): return Response(body="Hello World!") if __name__ == '__main__': config = Configurator() config.begin() config.add_handler('home', '/', handler=Hello, action='index') config.end() serve(config.make_wsgi_app(), host='0.0.0.0') Core Features ------------- * A framework to make writing web applications in Python easy * Utilizes a minimalist, component-based philosophy that makes it easy to expand on * Harness existing knowledge about Python * Extensible application design * Fast and efficient, an incredibly small per-request call-stack providing top performance * Uses existing and well tested Python packages Current Status -------------- Pylons 1.0 series is stable and production ready. The Pylons Project now maintains the Pyramid web framework for future development. Pylons 1.0 users should strongly consider using it for their next project. Download and Installation ------------------------- Pylons can be installed with `Easy Install `_ by typing:: > easy_install Pylons Dependant packages are automatically installed from the `Pylons download page `_ . Development Version ------------------- Pylons development uses the Mercuial distributed version control system (DVCS) with BitBucket hosting the main repository here: `Pylons Bitbucket repository `_ Keywords: web wsgi lightweight framework sqlalchemy formencode mako templates Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Framework :: Pylons Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 :: Only Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Internet :: WWW/HTTP :: WSGI Classifier: Topic :: Software Development :: Libraries :: Python Modules Pylons-1.0.1/pylons/0000775000076500000240000000000012012307216014204 5ustar benstaff00000000000000Pylons-1.0.1/pylons/__init__.py0000664000076500000240000000265111671741662016342 0ustar benstaff00000000000000"""Base objects to be exported for use in Controllers""" # Import pkg_resources first so namespace handling is properly done so the # paste imports work import pkg_resources from paste.registry import StackedObjectProxy from pylons.configuration import config from pylons.controllers.util import Request from pylons.controllers.util import Response __all__ = ['app_globals', 'cache', 'config', 'request', 'response', 'session', 'tmpl_context', 'url', 'Request', 'Response'] def __figure_version(): try: from pkg_resources import require import os # NOTE: this only works when the package is either installed, # or has an .egg-info directory present (i.e. wont work with raw # SVN checkout) info = require('pylons')[0] if os.path.normcase(os.path.realpath(os.path.dirname( os.path.dirname(__file__)))) == info.location: return info.version else: return '(not installed)' except: return '(not installed)' __version__ = __figure_version() app_globals = StackedObjectProxy(name="app_globals") cache = StackedObjectProxy(name="cache") request = StackedObjectProxy(name="request") response = StackedObjectProxy(name="response") session = StackedObjectProxy(name="session") tmpl_context = StackedObjectProxy(name="tmpl_context or C") url = StackedObjectProxy(name="url") translator = StackedObjectProxy(name="translator") Pylons-1.0.1/pylons/commands.py0000664000076500000240000005404611671742023016401 0ustar benstaff00000000000000"""Paster Commands, for use with paster in your project .. highlight:: bash The following commands are made available via paster utilizing setuptools points discovery. These can be used from the command line when the directory is the Pylons project. Commands available: ``controller`` Create a Controller and accompanying functional test ``restcontroller`` Create a REST Controller and accompanying functional test ``shell`` Open an interactive shell with the Pylons app loaded Example usage:: ~/sample$ paster controller account Creating /Users/ben/sample/sample/controllers/account.py Creating /Users/ben/sample/sample/tests/functional/test_account.py ~/sample$ .. admonition:: How it Works :command:`paster` is a command line script (from the PasteScript package) that allows the creation of context sensitive commands. :command:`paster` looks in the current directory for a ``.egg-info`` directory, then loads the ``paster_plugins.txt`` file. Using setuptools entry points, :command:`paster` looks for functions registered with setuptools as :func:`paste.paster_command`. These are defined in the entry_points block in each packages :file:`setup.py` module. This same system is used when running :command:`paster create` to determine what templates are available when creating new projects. """ import os import sys import paste.fixture import paste.registry from paste.deploy import loadapp from paste.script.command import Command, BadCommand from paste.script.filemaker import FileOp from tempita import paste_script_template_renderer import pylons import pylons.util as util __all__ = ['ControllerCommand', 'RestControllerCommand', 'ShellCommand'] def can_import(name): """Attempt to __import__ the specified package/module, returning True when succeeding, otherwise False""" try: __import__(name) return True except ImportError: return False def is_minimal_template(package, fail_fast=False): """Determine if the specified Pylons project (package) uses the Pylons Minimal Template. fail_fast causes ImportErrors encountered during detection to be raised. """ minimal_template = False try: # Check if PACKAGE.lib.base exists __import__(package + '.lib.base') except ImportError, ie: if 'No module named lib.base' in str(ie): minimal_template = True except: # PACKAGE.lib.base exists but throws an error if fail_fast: raise return minimal_template def defines_render(package): """Determine if the specified Pylons project (package) defines a render callable in their base module """ base_module = (is_minimal_template(package) and package + '.controllers' or package + '.lib.base') try: base = __import__(base_module, globals(), locals(), ['__doc__']) except: return False return callable(getattr(base, 'render', None)) def validate_name(name): """Validate that the name for the controller isn't present on the path already""" if not name: # This happens when the name is an existing directory raise BadCommand('Please give the name of a controller.') # 'setup' is a valid controller name, but when paster controller is ran # from the root directory of a project, importing setup will import the # project's setup.py causing a sys.exit(). Blame relative imports if name != 'setup' and can_import(name): raise BadCommand( "\n\nA module named '%s' is already present in your " "PYTHON_PATH.\nChoosing a conflicting name will likely cause " "import problems in\nyour controller at some point. It's " "suggested that you choose an\nalternate name, and if you'd " "like that name to be accessible as\n'%s', add a route " "to your projects config/routing.py file similar\nto:\n" " map.connect('%s', controller='my_%s')" \ % (name, name, name, name)) return True def check_controller_existence(base_package, directory, name): """Check if given controller already exists in project.""" filename = os.path.join(base_package, 'controllers', directory, name + '.py') if os.path.exists(filename): raise BadCommand('Controller %s already exists.' % os.path.join(directory, name)) class ControllerCommand(Command): """Create a Controller and accompanying functional test The Controller command will create the standard controller template file and associated functional test to speed creation of controllers. Example usage:: yourproj% paster controller comments Creating yourproj/yourproj/controllers/comments.py Creating yourproj/yourproj/tests/functional/test_comments.py If you'd like to have controllers underneath a directory, just include the path as the controller name and the necessary directories will be created for you:: yourproj% paster controller admin/trackback Creating yourproj/controllers/admin Creating yourproj/yourproj/controllers/admin/trackback.py Creating yourproj/yourproj/tests/functional/test_admin_trackback.py """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ min_args = 1 max_args = 1 group_name = 'pylons' default_verbosity = 3 parser = Command.standard_parser(simulate=True) parser.add_option('--no-test', action='store_true', dest='no_test', help="Don't create the test; just the controller") def command(self): """Main command to create controller""" try: file_op = FileOp(source_dir=('pylons', 'templates')) try: name, directory = file_op.parse_path_name_args(self.args[0]) except: raise BadCommand('No egg_info directory was found') # Check the name isn't the same as the package base_package = file_op.find_dir('controllers', True)[0] if base_package.lower() == name.lower(): raise BadCommand( 'Your controller name should not be the same as ' 'the package name %r.' % base_package) # Validate the name name = name.replace('-', '_') validate_name(name) # Determine the module's import statement if is_minimal_template(base_package): importstatement = ('from %s.controllers import BaseController' % base_package) else: importstatement = ('from %s.lib.base import BaseController' % base_package) if defines_render(base_package): importstatement += ', render' # Setup the controller fullname = os.path.join(directory, name) controller_name = util.class_name_from_module_name( name.split('/')[-1]) if not fullname.startswith(os.sep): fullname = os.sep + fullname testname = fullname.replace(os.sep, '_')[1:] module_dir = directory.replace('/', os.path.sep) check_controller_existence(base_package, module_dir, name) file_op.template_vars.update( {'name': controller_name, 'fname': os.path.join(directory, name).replace('\\', '/'), 'tmpl_name': name, 'package': base_package, 'importstatement': importstatement}) file_op.copy_file(template='controller.py_tmpl', dest=os.path.join('controllers', directory), filename=name, template_renderer=paste_script_template_renderer) if not self.options.no_test: file_op.copy_file( template='test_controller.py_tmpl', dest=os.path.join('tests', 'functional'), filename='test_' + testname, template_renderer=paste_script_template_renderer) except BadCommand, e: raise BadCommand('An error occurred. %s' % e) except: msg = str(sys.exc_info()[1]) raise BadCommand('An unknown error occurred. %s' % msg) class RestControllerCommand(Command): """Create a REST Controller and accompanying functional test The RestController command will create a REST-based Controller file for use with the :meth:`~routes.mapper.Mapper.resource` REST-based dispatching. This template includes the methods that :meth:`~routes.mapper.Mapper.resource` dispatches to in addition to doc strings for clarification on when the methods will be called. The first argument should be the singular form of the REST resource. The second argument is the plural form of the word. If its a nested controller, put the directory information in front as shown in the second example below. Example usage:: yourproj% paster restcontroller comment comments Creating yourproj/yourproj/controllers/comments.py Creating yourproj/yourproj/tests/functional/test_comments.py If you'd like to have controllers underneath a directory, just include the path as the controller name and the necessary directories will be created for you:: yourproj% paster restcontroller admin/tracback admin/trackbacks Creating yourproj/controllers/admin Creating yourproj/yourproj/controllers/admin/trackbacks.py Creating yourproj/yourproj/tests/functional/test_admin_trackbacks.py """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ min_args = 2 max_args = 2 group_name = 'pylons' default_verbosity = 3 parser = Command.standard_parser(simulate=True) parser.add_option('--no-test', action='store_true', dest='no_test', help="Don't create the test; just the controller") def command(self): """Main command to create controller""" try: file_op = FileOp(source_dir=('pylons', 'templates')) try: singularname, singulardirectory = \ file_op.parse_path_name_args(self.args[0]) pluralname, pluraldirectory = \ file_op.parse_path_name_args(self.args[1]) except: raise BadCommand('No egg_info directory was found') # Check the name isn't the same as the package base_package = file_op.find_dir('controllers', True)[0] if base_package.lower() == pluralname.lower(): raise BadCommand( 'Your controller name should not be the same as ' 'the package name %r.' % base_package) # Validate the name for name in [pluralname]: name = name.replace('-', '_') validate_name(name) # Determine the module's import statement if is_minimal_template(base_package): importstatement = ('from %s.controllers import BaseController' % base_package) else: importstatement = ('from %s.lib.base import BaseController' % base_package) if defines_render(base_package): importstatement += ', render' module_dir = pluraldirectory.replace('/', os.path.sep) check_controller_existence(base_package, module_dir, name) # Setup the controller fullname = os.path.join(pluraldirectory, pluralname) controller_name = util.class_name_from_module_name( pluralname.split('/')[-1]) if not fullname.startswith(os.sep): fullname = os.sep + fullname testname = fullname.replace(os.sep, '_')[1:] nameprefix = '' path = '' if pluraldirectory: nameprefix = pluraldirectory.replace(os.path.sep, '_') + '_' path = pluraldirectory + '/' controller_c = '' if nameprefix: controller_c = ", controller='%s', \n\t" % \ '/'.join([pluraldirectory, pluralname]) controller_c += "path_prefix='/%s', name_prefix='%s'" % \ (pluraldirectory, nameprefix) command = "map.resource('%s', '%s'%s)\n" % \ (singularname, pluralname, controller_c) file_op.template_vars.update( {'classname': controller_name, 'pluralname': pluralname, 'singularname': singularname, 'name': controller_name, 'nameprefix': nameprefix, 'package': base_package, 'path': path, 'resource_command': command.replace('\n\t', '\n%s#%s' % \ (' ' * 4, ' ' * 9)), 'fname': os.path.join(pluraldirectory, pluralname), 'importstatement': importstatement}) resource_command = ("\nTo create the appropriate RESTful mapping, " "add a map statement to your\n") resource_command += ("config/routing.py file near the top like " "this:\n\n") resource_command += command file_op.copy_file(template='restcontroller.py_tmpl', dest=os.path.join('controllers', pluraldirectory), filename=pluralname, template_renderer=paste_script_template_renderer) if not self.options.no_test: file_op.copy_file( template='test_restcontroller.py_tmpl', dest=os.path.join('tests', 'functional'), filename='test_' + testname, template_renderer=paste_script_template_renderer) print resource_command except BadCommand, e: raise BadCommand('An error occurred. %s' % e) except: msg = str(sys.exc_info()[1]) raise BadCommand('An unknown error occurred. %s' % msg) class RoutesCommand(Command): """Print the applications routes The optional CONFIG_FILE argument specifies the config file to use. CONFIG_FILE defaults to 'development.ini'. Example:: $ paster routes my-development.ini """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ min_args = 0 max_args = 1 group_name = 'pylons' parser = Command.standard_parser(simulate=True) parser.add_option('-q', action='count', dest='quiet', default=0, help=("Do not load logging configuration from the " "config file")) def command(self): """Main command to create a new shell""" self.verbose = 3 if len(self.args) == 0: # Assume the .ini file is ./development.ini config_file = 'development.ini' if not os.path.isfile(config_file): raise BadCommand('%sError: CONFIG_FILE not found at: .%s%s\n' 'Please specify a CONFIG_FILE' % \ (self.parser.get_usage(), os.path.sep, config_file)) else: config_file = self.args[0] config_name = 'config:%s' % config_file here_dir = os.getcwd() if not self.options.quiet: # Configure logging from the config file self.logging_file_config(config_file) # Load the wsgi app first so that everything is initialized right wsgiapp = loadapp(config_name, relative_to=here_dir) test_app = paste.fixture.TestApp(wsgiapp) # Query the test app to setup the environment and get the mapper tresponse = test_app.get('/_test_vars') mapper = tresponse.config.get('routes.map') if mapper: print mapper class ShellCommand(Command): """Open an interactive shell with the Pylons app loaded The optional CONFIG_FILE argument specifies the config file to use for the interactive shell. CONFIG_FILE defaults to 'development.ini'. This allows you to test your mapper, models, and simulate web requests using ``paste.fixture``. Example:: $ paster shell my-development.ini """ summary = __doc__.splitlines()[0] usage = '\n' + __doc__ min_args = 0 max_args = 1 group_name = 'pylons' parser = Command.standard_parser(simulate=True) parser.add_option('-d', '--disable-ipython', action='store_true', dest='disable_ipython', help="Don't use IPython if it is available") parser.add_option('-q', action='count', dest='quiet', default=0, help=("Do not load logging configuration from the " "config file")) def command(self): """Main command to create a new shell""" self.verbose = 3 if len(self.args) == 0: # Assume the .ini file is ./development.ini config_file = 'development.ini' if not os.path.isfile(config_file): raise BadCommand('%sError: CONFIG_FILE not found at: .%s%s\n' 'Please specify a CONFIG_FILE' % \ (self.parser.get_usage(), os.path.sep, config_file)) else: config_file = self.args[0] config_name = 'config:%s' % config_file here_dir = os.getcwd() locs = dict(__name__="pylons-admin") if not self.options.quiet: # Configure logging from the config file self.logging_file_config(config_file) # Load locals and populate with objects for use in shell sys.path.insert(0, here_dir) # Load the wsgi app first so that everything is initialized right wsgiapp = loadapp(config_name, relative_to=here_dir) test_app = paste.fixture.TestApp(wsgiapp) # Query the test app to setup the environment tresponse = test_app.get('/_test_vars') request_id = int(tresponse.body) # Disable restoration during test_app requests test_app.pre_request_hook = lambda self: \ paste.registry.restorer.restoration_end() test_app.post_request_hook = lambda self: \ paste.registry.restorer.restoration_begin(request_id) # Restore the state of the Pylons special objects # (StackedObjectProxies) paste.registry.restorer.restoration_begin(request_id) # Determine the package name from the pylons.config object pkg_name = pylons.config['pylons.package'] # Start the rest of our imports now that the app is loaded if is_minimal_template(pkg_name, True): model_module = None helpers_module = pkg_name + '.helpers' base_module = pkg_name + '.controllers' else: model_module = pkg_name + '.model' helpers_module = pkg_name + '.lib.helpers' base_module = pkg_name + '.lib.base' if model_module and can_import(model_module): locs['model'] = sys.modules[model_module] if can_import(helpers_module): locs['h'] = sys.modules[helpers_module] exec ('from pylons import app_globals, config, request, response, ' 'session, tmpl_context, url') in locs exec ('from pylons.controllers.util import abort, redirect') in locs exec 'from pylons.i18n import _, ungettext, N_' in locs locs.pop('__builtins__', None) # Import all objects from the base module __import__(base_module) base = sys.modules[base_module] base_public = [__name for __name in dir(base) if not \ __name.startswith('_') or __name == '_'] locs.update((name, getattr(base, name)) for name in base_public) locs.update(dict(wsgiapp=wsgiapp, app=test_app)) mapper = tresponse.config.get('routes.map') if mapper: locs['mapper'] = mapper banner = " All objects from %s are available\n" % base_module banner += " Additional Objects:\n" if mapper: banner += " %-10s - %s\n" % ('mapper', 'Routes mapper object') banner += " %-10s - %s\n" % ('wsgiapp', "This project's WSGI App instance") banner += " %-10s - %s\n" % ('app', 'paste.fixture wrapped around wsgiapp') try: if self.options.disable_ipython: raise ImportError() # try to use IPython if possible try: # ipython >= 0.11 from IPython.frontend.terminal.embed import InteractiveShellEmbed shell = InteractiveShellEmbed(banner2=banner) except ImportError: # ipython < 0.11 from IPython.Shell import IPShellEmbed shell = IPShellEmbed(argv=self.args) shell.set_banner(shell.IP.BANNER + '\n\n' + banner) try: shell(local_ns=locs, global_ns={}) finally: paste.registry.restorer.restoration_end() except ImportError: import code py_prefix = sys.platform.startswith('java') and 'J' or 'P' newbanner = "Pylons Interactive Shell\n%sython %s\n\n" % \ (py_prefix, sys.version) banner = newbanner + banner shell = code.InteractiveConsole(locals=locs) try: import readline except ImportError: pass try: shell.interact(banner) finally: paste.registry.restorer.restoration_end() Pylons-1.0.1/pylons/configuration.py0000664000076500000240000002011711671742074017445 0ustar benstaff00000000000000"""Configuration object and defaults setup The PylonsConfig object is initialized in pylons projects inside the :file:`config/environment.py` module. Importing the :data:`config` object from module causes the PylonsConfig object to be created, and setup in app-safe manner so that multiple apps being setup avoid conflicts. After importing :data:`config`, the project should then call :meth:`~PylonsConfig.init_app` with the appropriate options to setup the configuration. In the config data passed with :meth:`~PylonsConfig.init_app`, various defaults are set use with Paste and Routes. """ import copy import logging import os from paste.config import DispatchingConfig from paste.deploy.converters import asbool from webhelpers.mimehelper import MIMETypes request_defaults = dict(charset='utf-8', errors='replace', decode_param_names=False, language='en-us') response_defaults = dict(content_type='text/html', charset='utf-8', errors='strict', headers={'Cache-Control': 'no-cache', 'Pragma': 'no-cache'}) log = logging.getLogger(__name__) config = DispatchingConfig() class PylonsConfig(dict): """Pylons configuration object The Pylons configuration object is a per-application instance object that retains the information regarding the global and app conf's as well as per-application instance specific data such as the mapper, and the paths for this instance. The config object is available in your application as the Pylons global :data:`pylons.config`. For example:: from pylons import config template_paths = config['pylons.paths']['templates'] There's several useful keys of the config object most people will be interested in: ``pylons.paths`` A dict of absolute paths that were defined in the applications ``config/environment.py`` module. ``pylons.environ_config`` Dict of environ keys for where in the environ to pickup various objects for registering with Pylons. If these are present then PylonsApp will use them from environ rather than using default middleware from Beaker. Valid keys are: ``session, cache`` ``pylons.strict_tmpl_context`` Whether or not the ``tmpl_context`` object should throw an attribute error when access is attempted to an attribute that doesn't exist. Defaults to True. ``pylons.tmpl_context_attach_args`` Whethor or not Routes variables should automatically be attached to the tmpl_context object when specified in a controllers method. ``pylons.request_options`` A dict of Content-Type related default settings for new instances of :class:`~pylons.controllers.util.Request`. May contain the values ``charset`` and ``errors`` and ``decode_param_names``. Overrides the Pylons default values specified by the ``request_defaults`` dict. ``pylons.response_options`` A dict of Content-Type related default settings for new instances of :class:`~pylons.controllers.util.Response`. May contain the values ``content_type``, ``charset`` and ``errors``. Overrides the Pylons default values specified by the ``response_defaults`` dict. ``routes.map`` Mapper object used for Routing. Yes, it is possible to add routes after your application has started running. """ defaults = { 'debug': False, 'pylons.package': None, 'pylons.paths': {'root': None, 'controllers': None, 'templates': [], 'static_files': None}, 'pylons.environ_config': dict(session='beaker.session', cache='beaker.cache'), 'pylons.app_globals': None, 'pylons.h': None, 'pylons.request_options': request_defaults.copy(), 'pylons.response_options': response_defaults.copy(), 'pylons.strict_tmpl_context': True, 'pylons.tmpl_context_attach_args': False, } def init_app(self, global_conf, app_conf, package=None, paths=None): """Initialize configuration for the application .. note This *must* be called at least once, as soon as possible to setup all the configuration options. ``global_conf`` Several options are expected to be set for a Pylons web application. They will be loaded from the global_config which has the main Paste options. If ``debug`` is not enabled as a global config option, the following option *must* be set: * error_to - The email address to send the debug error to The optional config options in this case are: * smtp_server - The SMTP server to use, defaults to 'localhost' * error_log - A logfile to write the error to * error_subject_prefix - The prefix of the error email subject * from_address - Whom the error email should be from ``app_conf`` Defaults supplied via the [app:main] section from the Paste config file. ``load_config`` only cares about whether a 'prefix' option is set, if so it will update Routes to ensure URL's take that into account. ``package`` The name of the application package, to be stored in the app_conf. .. versionchanged:: 1.0 ``template_engine`` option is no longer supported. """ log.debug("Initializing configuration, package: '%s'", package) conf = global_conf.copy() conf.update(app_conf) conf.update(dict(app_conf=app_conf, global_conf=global_conf)) conf.update(self.pop('environment_load', {})) if paths: conf['pylons.paths'] = paths conf['pylons.package'] = package conf['debug'] = asbool(conf.get('debug')) # Load the MIMETypes with its default types MIMETypes.init() # Ensure all the keys from defaults are present, load them if not for key, val in copy.deepcopy(PylonsConfig.defaults).iteritems(): conf.setdefault(key, val) # Load the errorware configuration from the Paste configuration file # These all have defaults, and emails are only sent if configured and # if this application is running in production mode errorware = {} errorware['debug'] = conf['debug'] if not errorware['debug']: errorware['debug'] = False errorware['error_email'] = conf.get('email_to') errorware['error_log'] = conf.get('error_log', None) errorware['smtp_server'] = conf.get('smtp_server', 'localhost') errorware['error_subject_prefix'] = conf.get( 'error_subject_prefix', 'WebApp Error: ') errorware['from_address'] = conf.get( 'from_address', conf.get('error_email_from', 'pylons@yourapp.com')) errorware['error_message'] = conf.get('error_message', 'An internal server error occurred') # Copy in some defaults if 'cache_dir' in conf: conf.setdefault('beaker.session.data_dir', os.path.join(conf['cache_dir'], 'sessions')) conf.setdefault('beaker.cache.data_dir', os.path.join(conf['cache_dir'], 'cache')) conf['pylons.cache_dir'] = conf.pop('cache_dir', conf['app_conf'].get('cache_dir')) # Save our errorware values conf['pylons.errorware'] = errorware # Load conf dict into self self.update(conf) pylons_config = PylonsConfig() # Push an empty config so all accesses to config at import time have something # to look at and modify. This config will be merged with the app's when it's # built in the paste.app_factory entry point. pylons_config.update(copy.deepcopy(PylonsConfig.defaults)) config.push_process_config(pylons_config) Pylons-1.0.1/pylons/controllers/0000775000076500000240000000000012012307216016552 5ustar benstaff00000000000000Pylons-1.0.1/pylons/controllers/__init__.py0000664000076500000240000000036711645401275020704 0ustar benstaff00000000000000"""Standard Controllers intended for subclassing by web developers""" from pylons.controllers.core import WSGIController from pylons.controllers.xmlrpc import XMLRPCController from pylons.controllers.jsonrpc import JSONRPCController, JSONRPCError Pylons-1.0.1/pylons/controllers/core.py0000664000076500000240000002547311671740741020105 0ustar benstaff00000000000000"""The core WSGIController""" import inspect import logging import types from webob.exc import HTTPException, HTTPNotFound import pylons __all__ = ['WSGIController'] log = logging.getLogger(__name__) class WSGIController(object): """WSGI Controller that follows WSGI spec for calling and return values The Pylons WSGI Controller handles incoming web requests that are dispatched from the PylonsBaseWSGIApp. These requests result in a new instance of the WSGIController being created, which is then called with the dict options from the Routes match. The standard WSGI response is then returned with start_response called as per the WSGI spec. Special WSGIController methods you may define: ``__before__`` This method is called before your action is, and should be used for setting up variables/objects, restricting access to other actions, or other tasks which should be executed before the action is called. ``__after__`` This method is called after the action is, unless an unexpected exception was raised. Subclasses of :class:`~webob.exc.HTTPException` (such as those raised by ``redirect_to`` and ``abort``) are expected; e.g. ``__after__`` will be called on redirects. Each action to be called is inspected with :meth:`_inspect_call` so that it is only passed the arguments in the Routes match dict that it asks for. The arguments passed into the action can be customized by overriding the :meth:`_get_method_args` function which is expected to return a dict. In the event that an action is not found to handle the request, the Controller will raise an "Action Not Found" error if in debug mode, otherwise a ``404 Not Found`` error will be returned. """ _pylons_log_debug = False def _perform_call(self, func, args): """Hide the traceback for everything above this method""" __traceback_hide__ = 'before_and_this' return func(**args) def _inspect_call(self, func): """Calls a function with arguments from :meth:`_get_method_args` Given a function, inspect_call will inspect the function args and call it with no further keyword args than it asked for. If the function has been decorated, it is assumed that the decorator preserved the function signature. """ # Check to see if the class has a cache of argspecs yet try: cached_argspecs = self.__class__._cached_argspecs except AttributeError: self.__class__._cached_argspecs = cached_argspecs = {} # function could be callable func_key = getattr(func, 'im_func', func.__call__) try: argspec = cached_argspecs[func_key] except KeyError: argspec = cached_argspecs[func_key] = inspect.getargspec(func_key) kargs = self._get_method_args() log_debug = self._pylons_log_debug c = self._py_object.tmpl_context environ = self._py_object.request.environ args = None if argspec[2]: if self._py_object.config['pylons.tmpl_context_attach_args']: for k, val in kargs.iteritems(): setattr(c, k, val) args = kargs else: args = {} argnames = argspec[0][isinstance(func, types.MethodType) and 1 or 0:] for name in argnames: if name in kargs: if self._py_object.config['pylons.tmpl_context_attach_args']: setattr(c, name, kargs[name]) args[name] = kargs[name] if log_debug: log.debug("Calling %r method with keyword args: **%r", func.__name__, args) try: result = self._perform_call(func, args) except HTTPException, httpe: if log_debug: log.debug("%r method raised HTTPException: %s (code: %s)", func.__name__, httpe.__class__.__name__, httpe.wsgi_response.code, exc_info=True) result = httpe # Store the exception in the environ environ['pylons.controller.exception'] = httpe # 304 Not Modified's shouldn't have a content-type set if result.wsgi_response.status_int == 304: result.wsgi_response.headers.pop('Content-Type', None) result._exception = True return result def _get_method_args(self): """Retrieve the method arguments to use with inspect call By default, this uses Routes to retrieve the arguments, override this method to customize the arguments your controller actions are called with. This method should return a dict. """ req = self._py_object.request kargs = req.environ['pylons.routes_dict'].copy() kargs['environ'] = req.environ kargs['start_response'] = self.start_response kargs['pylons'] = self._py_object return kargs def _dispatch_call(self): """Handles dispatching the request to the function using Routes""" log_debug = self._pylons_log_debug req = self._py_object.request try: action = req.environ['pylons.routes_dict']['action'] except KeyError: raise Exception("No action matched from Routes, unable to" "determine action dispatch.") action_method = action.replace('-', '_') if log_debug: log.debug("Looking for %r method to handle the request", action_method) try: func = getattr(self, action_method, None) except UnicodeEncodeError: func = None if action_method != 'start_response' and callable(func): # Store function used to handle request req.environ['pylons.action_method'] = func response = self._inspect_call(func) else: if log_debug: log.debug("Couldn't find %r method to handle response", action) if pylons.config['debug']: raise NotImplementedError('Action %r is not implemented' % action) else: response = HTTPNotFound() return response def __call__(self, environ, start_response): """The main call handler that is called to return a response""" log_debug = self._pylons_log_debug # Keep a local reference to the req/response objects self._py_object = environ['pylons.pylons'] # Keep private methods private try: if environ['pylons.routes_dict']['action'][:1] in ('_', '-'): if log_debug: log.debug("Action starts with _, private action not " "allowed. Returning a 404 response") return HTTPNotFound()(environ, start_response) except KeyError: # The check later will notice that there's no action pass start_response_called = [] def repl_start_response(status, headers, exc_info=None): response = self._py_object.response start_response_called.append(None) # Copy the headers from the global response if log_debug: log.debug("Merging pylons.response headers into " "start_response call, status: %s", status) headers.extend(header for header in response.headerlist if header[0] == 'Set-Cookie' or header[0].startswith('X-')) return start_response(status, headers, exc_info) self.start_response = repl_start_response if hasattr(self, '__before__'): response = self._inspect_call(self.__before__) if hasattr(response, '_exception'): return response(environ, self.start_response) response = self._dispatch_call() if not start_response_called: self.start_response = start_response py_response = self._py_object.response # If its not a WSGI response, and we have content, it needs to # be wrapped in the response object if isinstance(response, str): if log_debug: log.debug("Controller returned a string " ", writing it to pylons.response") py_response.body = py_response.body + response elif isinstance(response, unicode): if log_debug: log.debug("Controller returned a unicode string " ", writing it to pylons.response") py_response.unicode_body = py_response.unicode_body + \ response elif hasattr(response, 'wsgi_response'): # It's an exception that got tossed. if log_debug: log.debug("Controller returned a Response object, merging " "it with pylons.response") for name, value in py_response.headers.items(): if name.lower() == 'set-cookie': response.headers.add(name, value) else: response.headers.setdefault(name, value) try: registry = environ['paste.registry'] registry.replace(pylons.response, response) except KeyError: # Ignore the case when someone removes the registry pass py_response = response elif response is None: if log_debug: log.debug("Controller returned None") else: if log_debug: log.debug("Assuming controller returned an iterable, " "setting it as pylons.response.app_iter") py_response.app_iter = response response = py_response if hasattr(self, '__after__'): after = self._inspect_call(self.__after__) if hasattr(after, '_exception'): after.wsgi_response = True response = after if hasattr(response, 'wsgi_response'): # Copy the response object into the testing vars if we're testing if 'paste.testing_variables' in environ: environ['paste.testing_variables']['response'] = response if log_debug: log.debug("Calling Response object to return WSGI data") return response(environ, self.start_response) if log_debug: log.debug("Response assumed to be WSGI content, returning " "un-touched") return response Pylons-1.0.1/pylons/controllers/jsonrpc.py0000664000076500000240000001722011671741027020620 0ustar benstaff00000000000000"""The base WSGI JSONRPCController""" import inspect import json import logging import types import urllib from paste.response import replace_header from pylons.controllers import WSGIController from pylons.controllers.util import abort, Response __all__ = ['JSONRPCController', 'JSONRPCError', 'JSONRPC_PARSE_ERROR', 'JSONRPC_INVALID_REQUEST', 'JSONRPC_METHOD_NOT_FOUND', 'JSONRPC_INVALID_PARAMS', 'JSONRPC_INTERNAL_ERROR'] log = logging.getLogger(__name__) JSONRPC_VERSION = '2.0' class JSONRPCError(BaseException): def __init__(self, code, message): self.code = code self.message = message self.data = None def __str__(self): return str(self.code) + ': ' + self.message def as_dict(self): """Return a dictionary representation of this object for serialization in a JSON-RPC response.""" error = dict(code=self.code, message=self.message) if self.data: error['data'] = self.data return error JSONRPC_PARSE_ERROR = JSONRPCError(-32700, "Parse error") JSONRPC_INVALID_REQUEST = JSONRPCError(-32600, "Invalid Request") JSONRPC_METHOD_NOT_FOUND = JSONRPCError(-32601, "Method not found") JSONRPC_INVALID_PARAMS = JSONRPCError(-32602, "Invalid params") JSONRPC_INTERNAL_ERROR = JSONRPCError(-32603, "Internal error") _reserved_errors = dict(parse_error=JSONRPC_PARSE_ERROR, invalid_request=JSONRPC_INVALID_REQUEST, method_not_found=JSONRPC_METHOD_NOT_FOUND, invalid_params=JSONRPC_INVALID_PARAMS, internal_error=JSONRPC_INTERNAL_ERROR) def jsonrpc_error(req_id, error): """Generate a Response object with a JSON-RPC error body. Used to raise top-level pre-defined errors that happen outside the controller.""" if error in _reserved_errors: err = _reserved_errors[error] return Response(body=json.dumps(dict(jsonrpc=JSONRPC_VERSION, id=req_id, error=err.as_dict()))) class JSONRPCController(WSGIController): """ A WSGI-speaking JSON-RPC 2.0 controller class See the specification: ``. Many parts of this controller are modelled after XMLRPCController from Pylons 0.9.7 Valid controller return values should be json-serializable objects. Sub-classes should catch their exceptions and raise JSONRPCError if they want to pass meaningful errors to the client. Unhandled errors should be caught and return JSONRPC_INTERNAL_ERROR to the client. Parts of the specification not supported (yet): - Notifications - Batch """ def _get_method_args(self): """Return `self._rpc_args` to dispatched controller method chosen by __call__""" return self._rpc_args def __call__(self, environ, start_response): """Parse the request body as JSON, look up the method on the controller and if it exists, dispatch to it. """ length = 0 if 'CONTENT_LENGTH' not in environ: log.debug("No Content-Length") abort(411) else: if environ['CONTENT_LENGTH'] == '': abort(411) length = int(environ['CONTENT_LENGTH']) log.debug('Content-Length: %s', length) if length == 0: log.debug("Content-Length is 0") abort(411) raw_body = environ['wsgi.input'].read(length) json_body = json.loads(urllib.unquote_plus(raw_body)) self._req_id = json_body['id'] self._req_method = json_body['method'] self._req_params = json_body['params'] log.debug('id: %s, method: %s, params: %s', self._req_id, self._req_method, self._req_params) self._error = None try: self._func = self._find_method() except AttributeError: err = jsonrpc_error(self._req_id, 'method_not_found') return err(environ, start_response) # now that we have a method, make sure we have enough # parameters and pass off control to the controller. if not isinstance(self._req_params, dict): # JSON-RPC version 1 request. arglist = inspect.getargspec(self._func)[0][1:] if len(self._req_params) < len(arglist): err = jsonrpc_error(self._req_id, 'invalid_params') return err(environ, start_response) else: kargs = dict(zip(arglist, self._req_params)) else: # JSON-RPC version 2 request. Params may be default, and # are already a dict, so skip the parameter length check here. kargs = self._req_params # XX Fix this namespace clash. One cannot use names below as # method argument names as this stands! kargs['action'], kargs['environ'] = self._req_method, environ kargs['start_response'] = start_response self._rpc_args = kargs status = [] headers = [] exc_info = [] def change_content(new_status, new_headers, new_exc_info=None): status.append(new_status) headers.extend(new_headers) exc_info.append(new_exc_info) output = WSGIController.__call__(self, environ, change_content) output = list(output) headers.append(('Content-Length', str(len(output[0])))) replace_header(headers, 'Content-Type', 'application/json') start_response(status[0], headers, exc_info[0]) return output def _dispatch_call(self): """Implement dispatch interface specified by WSGIController""" try: raw_response = self._inspect_call(self._func) except JSONRPCError, e: self._error = e.as_dict() except TypeError, e: # Insufficient args in an arguments dict v2 call. if 'takes at least' in str(e): err = _reserved_errors['invalid_params'] self._error = err.as_dict() else: raise except Exception, e: log.debug('Encountered unhandled exception: %s', repr(e)) err = _reserved_errors['internal_error'] self._error = err.as_dict() response = dict(jsonrpc=JSONRPC_VERSION, id=self._req_id) if self._error is not None: response['error'] = self._error else: response['result'] = raw_response try: return json.dumps(response) except TypeError, e: log.debug('Error encoding response: %s', e) err = _reserved_errors['internal_error'] return json.dumps(dict( jsonrpc=JSONRPC_VERSION, id=self._req_id, error=err.as_dict())) def _find_method(self): """Return method named by `self._req_method` in controller if able""" log.debug('Trying to find JSON-RPC method: %s', self._req_method) if self._req_method.startswith('_'): raise AttributeError("Method not allowed") try: func = getattr(self, self._req_method, None) except UnicodeEncodeError: # XMLRPCController catches this, not sure why. raise AttributeError("Problem decoding unicode in requested " "method name.") if isinstance(func, types.MethodType): return func else: raise AttributeError("No such method: %s" % self._req_method) Pylons-1.0.1/pylons/controllers/util.py0000664000076500000240000001570411671752140020122 0ustar benstaff00000000000000"""Utility functions and classes available for use by Controllers Pylons subclasses the `WebOb `_ :class:`webob.Request` and :class:`webob.Response` classes to provide backwards compatible functions for earlier versions of Pylons as well as add a few helper functions to assist with signed cookies. For reference use, refer to the :class:`Request` and :class:`Response` below. Functions available: :func:`abort`, :func:`forward`, :func:`etag_cache`, :func:`mimetype` and :func:`redirect` """ import base64 import binascii import hmac import logging import re try: import cPickle as pickle except ImportError: import pickle try: from hashlib import sha1 except ImportError: import sha as sha1 from webob import BaseRequest as WebObRequest from webob import Response as WebObResponse from webob.exc import status_map import pylons __all__ = ['abort', 'etag_cache', 'redirect', 'Request', 'Response'] log = logging.getLogger(__name__) IF_NONE_MATCH = re.compile('(?:W/)?(?:"([^"]*)",?\s*)') class Request(WebObRequest): """WebOb Request subclass The WebOb :class:`webob.Request` has no charset, or other defaults. This subclass adds defaults, along with several methods for backwards compatibility with paste.wsgiwrappers.WSGIRequest. """ def determine_browser_charset(self): """Legacy method to return the :attr:`webob.Request.accept_charset`""" return self.accept_charset def languages(self): # And we now have the old best_matches code that webob ditched! al = self.accept_language items = [i for i, q in sorted(al._parsed, key=lambda iq: -iq[1])] for index, item in enumerate(items): if al._match(item, self.language): items[index:] = [self.language] break else: items.append(self.language) return items languages = property(languages) def match_accept(self, mimetypes): return self.accept.first_match(mimetypes) def signed_cookie(self, name, secret): """Extract a signed cookie of ``name`` from the request The cookie is expected to have been created with ``Response.signed_cookie``, and the ``secret`` should be the same as the one used to sign it. Any failure in the signature of the data will result in None being returned. """ cookie = self.str_cookies.get(name) if not cookie: return None try: input_sig, pickled = cookie[:40], base64.standard_b64decode(cookie[40:]) except binascii.Error: # Badly formed data can make base64 die return None sig = hmac.new(secret, pickled, sha1).hexdigest() # Avoid timing attacks invalid_bits = 0 if len(sig) != len(input_sig): return None for a, b in zip(sig, input_sig): invalid_bits += a != b if invalid_bits: return None else: return pickle.loads(pickled) class Response(WebObResponse): """WebOb Response subclass The WebOb Response has no default content type, or error defaults. This subclass adds defaults, along with several methods for backwards compatibility with paste.wsgiwrappers.WSGIResponse. """ content = WebObResponse.body def determine_charset(self): return self.charset def has_header(self, header): return header in self.headers def get_content(self): return self.body def wsgi_response(self): return self.status, self.headers, self.body def signed_cookie(self, name, data, secret=None, **kwargs): """Save a signed cookie with ``secret`` signature Saves a signed cookie of the pickled data. All other keyword arguments that ``WebOb.set_cookie`` accepts are usable and passed to the WebOb set_cookie method after creating the signed cookie value. """ pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) sig = hmac.new(secret, pickled, sha1).hexdigest() self.set_cookie(name, sig + base64.standard_b64encode(pickled), **kwargs) def etag_cache(key=None): """Use the HTTP Entity Tag cache for Browser side caching If a "If-None-Match" header is found, and equivilant to ``key``, then a ``304`` HTTP message will be returned with the ETag to tell the browser that it should use its current cache of the page. Otherwise, the ETag header will be added to the response headers. Suggested use is within a Controller Action like so: .. code-block:: python import pylons class YourController(BaseController): def index(self): etag_cache(key=1) return render('/splash.mako') .. note:: This works because etag_cache will raise an HTTPNotModified exception if the ETag received matches the key provided. """ if_none_matches = IF_NONE_MATCH.findall( pylons.request.environ.get('HTTP_IF_NONE_MATCH', '')) response = pylons.response._current_obj() response.headers['ETag'] = '"%s"' % key if str(key) in if_none_matches: log.debug("ETag match, returning 304 HTTP Not Modified Response") response.headers.pop('Content-Type', None) response.headers.pop('Cache-Control', None) response.headers.pop('Pragma', None) raise status_map[304]().exception else: log.debug("ETag didn't match, returning response object") def forward(wsgi_app): """Forward the request to a WSGI application. Returns its response. .. code-block:: python return forward(FileApp('filename')) """ environ = pylons.request.environ controller = environ.get('pylons.controller') if not controller or not hasattr(controller, 'start_response'): raise RuntimeError("Unable to forward: environ['pylons.controller'] " "is not a valid Pylons controller") return wsgi_app(environ, controller.start_response) def abort(status_code=None, detail="", headers=None, comment=None): """Aborts the request immediately by returning an HTTP exception In the event that the status_code is a 300 series error, the detail attribute will be used as the Location header should one not be specified in the headers attribute. """ exc = status_map[status_code](detail=detail, headers=headers, comment=comment) log.debug("Aborting request, status: %s, detail: %r, headers: %r, " "comment: %r", status_code, detail, headers, comment) raise exc.exception def redirect(url, code=302): """Raises a redirect exception to the specified URL Optionally, a code variable may be passed with the status code of the redirect, ie:: redirect(url(controller='home', action='index'), code=303) """ log.debug("Generating %s redirect" % code) exc = status_map[code] raise exc(location=url).exception Pylons-1.0.1/pylons/controllers/xmlrpc.py0000664000076500000240000002526011671741406020453 0ustar benstaff00000000000000"""The base WSGI XMLRPCController""" import inspect import logging import types import xmlrpclib from paste.response import replace_header from pylons.controllers import WSGIController from pylons.controllers.util import abort, Response __all__ = ['XMLRPCController'] log = logging.getLogger(__name__) XMLRPC_MAPPING = ((basestring, 'string'), (list, 'array'), (bool, 'boolean'), (int, 'int'), (float, 'double'), (dict, 'struct'), (xmlrpclib.DateTime, 'dateTime.iso8601'), (xmlrpclib.Binary, 'base64')) def xmlrpc_sig(args): """Returns a list of the function signature in string format based on a tuple provided by xmlrpclib.""" signature = [] for param in args: for type, xml_name in XMLRPC_MAPPING: if isinstance(param, type): signature.append(xml_name) break return signature def xmlrpc_fault(code, message): """Convienence method to return a Pylons response XMLRPC Fault""" fault = xmlrpclib.Fault(code, message) return Response(body=xmlrpclib.dumps(fault, methodresponse=True)) class XMLRPCController(WSGIController): """XML-RPC Controller that speaks WSGI This controller handles XML-RPC responses and complies with the `XML-RPC Specification `_ as well as the `XML-RPC Introspection `_ specification. By default, methods with names containing a dot are translated to use an underscore. For example, the `system.methodHelp` is handled by the method :meth:`system_methodHelp`. Methods in the XML-RPC controller will be called with the method given in the XMLRPC body. Methods may be annotated with a signature attribute to declare the valid arguments and return types. For example:: class MyXML(XMLRPCController): def userstatus(self): return 'basic string' userstatus.signature = [ ['string'] ] def userinfo(self, username, age=None): user = LookUpUser(username) response = {'username':user.name} if age and age > 10: response['age'] = age return response userinfo.signature = [['struct', 'string'], ['struct', 'string', 'int']] Since XML-RPC methods can take different sets of data, each set of valid arguments is its own list. The first value in the list is the type of the return argument. The rest of the arguments are the types of the data that must be passed in. In the last method in the example above, since the method can optionally take an integer value both sets of valid parameter lists should be provided. Valid types that can be checked in the signature and their corresponding Python types:: 'string' - str 'array' - list 'boolean' - bool 'int' - int 'double' - float 'struct' - dict 'dateTime.iso8601' - xmlrpclib.DateTime 'base64' - xmlrpclib.Binary The class variable ``allow_none`` is passed to xmlrpclib.dumps; enabling it allows translating ``None`` to XML (an extension to the XML-RPC specification) .. note:: Requiring a signature is optional. """ allow_none = False max_body_length = 4194304 def _get_method_args(self): return self.rpc_kargs def __call__(self, environ, start_response): """Parse an XMLRPC body for the method, and call it with the appropriate arguments""" # Pull out the length, return an error if there is no valid # length or if the length is larger than the max_body_length. log_debug = self._pylons_log_debug length = environ.get('CONTENT_LENGTH') if length: length = int(length) else: # No valid Content-Length header found if log_debug: log.debug("No Content-Length found, returning 411 error") abort(411) if length > self.max_body_length or length == 0: if log_debug: log.debug("Content-Length larger than max body length. Max: " "%s, Sent: %s. Returning 413 error", self.max_body_length, length) abort(413, "XML body too large") body = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH'])) rpc_args, orig_method = xmlrpclib.loads(body) method = self._find_method_name(orig_method) func = self._find_method(method) if not func: if log_debug: log.debug("Method: %r not found, returning xmlrpc fault", method) return xmlrpc_fault(0, "No such method name %r" % method)(environ, start_response) # Signature checking for params if hasattr(func, 'signature'): if log_debug: log.debug("Checking XMLRPC argument signature") valid_args = False params = xmlrpc_sig(rpc_args) for sig in func.signature: # Next sig if we don't have the same amount of args if len(sig) - 1 != len(rpc_args): continue # If the params match, we're valid if params == sig[1:]: valid_args = True break if not valid_args: if log_debug: log.debug("Bad argument signature recieved, returning " "xmlrpc fault") msg = ("Incorrect argument signature. %r recieved does not " "match %r signature for method %r" % \ (params, func.signature, orig_method)) return xmlrpc_fault(0, msg)(environ, start_response) # Change the arg list into a keyword dict based off the arg # names in the functions definition arglist = inspect.getargspec(func)[0][1:] kargs = dict(zip(arglist, rpc_args)) kargs['action'], kargs['environ'] = method, environ kargs['start_response'] = start_response self.rpc_kargs = kargs self._func = func # Now that we know the method is valid, and the args are valid, # we can dispatch control to the default WSGIController status = [] headers = [] exc_info = [] def change_content(new_status, new_headers, new_exc_info=None): status.append(new_status) headers.extend(new_headers) exc_info.append(new_exc_info) output = WSGIController.__call__(self, environ, change_content) output = list(output) headers.append(('Content-Length', str(len(output[0])))) replace_header(headers, 'Content-Type', 'text/xml') start_response(status[0], headers, exc_info[0]) return output def _dispatch_call(self): """Dispatch the call to the function chosen by __call__""" raw_response = self._inspect_call(self._func) if not isinstance(raw_response, xmlrpclib.Fault): raw_response = (raw_response,) response = xmlrpclib.dumps(raw_response, methodresponse=True, allow_none=self.allow_none) return response def _find_method(self, name): """Locate a method in the controller by the specified name and return it""" # Keep private methods private if name.startswith('_'): if self._pylons_log_debug: log.debug("Action starts with _, private action not allowed") return if self._pylons_log_debug: log.debug("Looking for XMLRPC method: %r", name) try: func = getattr(self, name, None) except UnicodeEncodeError: return if isinstance(func, types.MethodType): return func def _find_method_name(self, name): """Locate a method in the controller by the appropriate name By default, this translates method names like 'system.methodHelp' into 'system_methodHelp'. """ return name.replace('.', '_') def _publish_method_name(self, name): """Translate an internal method name to a publicly viewable one By default, this translates internal method names like 'blog_view' into 'blog.view'. """ return name.replace('_', '.') def system_listMethods(self): """Returns a list of XML-RPC methods for this XML-RPC resource""" methods = [] for method in dir(self): meth = getattr(self, method) if not method.startswith('_') and isinstance(meth, types.MethodType): methods.append(self._publish_method_name(method)) return methods system_listMethods.signature = [['array']] def system_methodSignature(self, name): """Returns an array of array's for the valid signatures for a method. The first value of each array is the return value of the method. The result is an array to indicate multiple signatures a method may be capable of. """ method = self._find_method(self._find_method_name(name)) if method: return getattr(method, 'signature', '') else: return xmlrpclib.Fault(0, 'No such method name') system_methodSignature.signature = [['array', 'string'], ['string', 'string']] def system_methodHelp(self, name): """Returns the documentation for a method""" method = self._find_method(self._find_method_name(name)) if method: help = MethodHelp.getdoc(method) sig = getattr(method, 'signature', None) if sig: help += "\n\nMethod signature: %s" % sig return help return xmlrpclib.Fault(0, "No such method name") system_methodHelp.signature = [['string', 'string']] class MethodHelp(object): """Wrapper for formatting doc strings from XMLRPCController methods""" def __init__(self, doc): self.__doc__ = doc def getdoc(method): """Return a formatted doc string, via inspect.getdoc, from the specified XMLRPCController method The method's help attribute is used if it exists, otherwise the method's doc string is used. """ help = getattr(method, 'help', None) if help is None: help = method.__doc__ doc = inspect.getdoc(MethodHelp(help)) if doc is None: return '' return doc getdoc = staticmethod(getdoc) Pylons-1.0.1/pylons/decorators/0000775000076500000240000000000012012307216016351 5ustar benstaff00000000000000Pylons-1.0.1/pylons/decorators/__init__.py0000664000076500000240000001760711671741462020514 0ustar benstaff00000000000000"""Pylons Decorators Common decorators intended for use in controllers. Additional decorators for use with controllers are in the :mod:`~pylons.decorators.cache`, :mod:`~pylons.decorators.rest` and :mod:`~pylons.decorators.secure` modules. """ import logging import warnings import formencode import simplejson from decorator import decorator from formencode import api, htmlfill, variabledecode from pylons.decorators.util import get_pylons from pylons.i18n import _ as pylons_gettext __all__ = ['jsonify', 'validate'] log = logging.getLogger(__name__) class JSONEncoder(simplejson.JSONEncoder): def default(self, obj): encoder = getattr(obj, '__json__', None) if encoder is not None: return encoder() return super(JSONEncoder, self).default(obj) @decorator def jsonify(func, *args, **kwargs): """Action decorator that formats output for JSON Given a function that will return content, this decorator will turn the result into JSON, with a content-type of 'application/json' and output it. """ pylons = get_pylons(args) pylons.response.headers['Content-Type'] = 'application/json; charset=utf-8' data = func(*args, **kwargs) if isinstance(data, (list, tuple)): msg = "JSON responses with Array envelopes are susceptible to " \ "cross-site data leak attacks, see " \ "http://wiki.pylonshq.com/display/pylonsfaq/Warnings" warnings.warn(msg, Warning, 2) log.warning(msg) log.debug("Returning JSON wrapped action output") return simplejson.dumps(data, cls=JSONEncoder, encoding='utf-8') def validate(schema=None, validators=None, form=None, variable_decode=False, dict_char='.', list_char='-', post_only=True, state=None, on_get=False, **htmlfill_kwargs): """Validate input either for a FormEncode schema, or individual validators Given a form schema or dict of validators, validate will attempt to validate the schema or validator list. If validation was successful, the valid result dict will be saved as ``self.form_result``. Otherwise, the action will be re-run as if it was a GET, and the output will be filled by FormEncode's htmlfill to fill in the form field errors. ``schema`` Refers to a FormEncode Schema object to use during validation. ``form`` Method used to display the form, which will be used to get the HTML representation of the form for error filling. ``variable_decode`` Boolean to indicate whether FormEncode's variable decode function should be run on the form input before validation. ``dict_char`` Passed through to FormEncode. Toggles the form field naming scheme used to determine what is used to represent a dict. This option is only applicable when used with variable_decode=True. ``list_char`` Passed through to FormEncode. Toggles the form field naming scheme used to determine what is used to represent a list. This option is only applicable when used with variable_decode=True. ``post_only`` Boolean that indicates whether or not GET (query) variables should be included during validation. .. warning:: ``post_only`` applies to *where* the arguments to be validated come from. It does *not* restrict the form to only working with post, merely only checking POST vars. ``state`` Passed through to FormEncode for use in validators that utilize a state object. ``on_get`` Whether to validate on GET requests. By default only POST requests are validated. Example:: class SomeController(BaseController): def create(self, id): return render('/myform.mako') @validate(schema=model.forms.myshema(), form='create') def update(self, id): # Do something with self.form_result pass """ if state is None: state = PylonsFormEncodeState def wrapper(func, self, *args, **kwargs): """Decorator Wrapper function""" request = self._py_object.request errors = {} # Skip the validation if on_get is False and its a GET if not on_get and request.environ['REQUEST_METHOD'] == 'GET': return func(self, *args, **kwargs) # If they want post args only, use just the post args if post_only: params = request.POST else: params = request.params params = params.mixed() if variable_decode: log.debug("Running variable_decode on params") decoded = variabledecode.variable_decode(params, dict_char, list_char) else: decoded = params if schema: log.debug("Validating against a schema") try: self.form_result = schema.to_python(decoded, state) except formencode.Invalid, e: errors = e.unpack_errors(variable_decode, dict_char, list_char) if validators: log.debug("Validating against provided validators") if isinstance(validators, dict): if not hasattr(self, 'form_result'): self.form_result = {} for field, validator in validators.iteritems(): try: self.form_result[field] = \ validator.to_python(decoded.get(field), state) except formencode.Invalid, error: errors[field] = error if errors: log.debug("Errors found in validation, parsing form with htmlfill " "for errors") request.environ['REQUEST_METHOD'] = 'GET' self._py_object.tmpl_context.form_errors = errors # If there's no form supplied, just continue with the current # function call. if not form: return func(self, *args, **kwargs) request.environ['pylons.routes_dict']['action'] = form response = self._dispatch_call() # If the form_content is an exception response, return it if hasattr(response, '_exception'): return response htmlfill_kwargs2 = htmlfill_kwargs.copy() htmlfill_kwargs2.setdefault('encoding', request.charset) return htmlfill.render(response, defaults=params, errors=errors, **htmlfill_kwargs2) return func(self, *args, **kwargs) return decorator(wrapper) def pylons_formencode_gettext(value): """Translates a string ``value`` using pylons gettext first and if that fails, formencode gettext. This allows to "merge" localized error messages from built-in FormEncode's validators with application-specific validators. """ trans = pylons_gettext(value) if trans == value: # translation failed, try formencode trans = api._stdtrans(value) return trans class PylonsFormEncodeState(object): """A ``state`` for FormEncode validate API that includes smart ``_`` hook. The FormEncode library used by validate() decorator has some provision for localizing error messages. In particular, it looks for attribute ``_`` in the application-specific state object that gets passed to every ``.to_python()`` call. If it is found, the ``_`` is assumed to be a gettext-like function and is called to localize error messages. One complication is that FormEncode ships with localized error messages for standard validators so the user may want to re-use them instead of gathering and translating everything from scratch. To allow this, we pass as ``_`` a function which looks up translation both in application and formencode message catalogs. """ _ = staticmethod(pylons_formencode_gettext) Pylons-1.0.1/pylons/decorators/cache.py0000664000076500000240000001305611671741530020006 0ustar benstaff00000000000000"""Caching decorator""" import inspect import logging import time from decorator import decorator from paste.deploy.converters import asbool from pylons.decorators.util import get_pylons log = logging.getLogger(__name__) def beaker_cache(key="cache_default", expire="never", type=None, query_args=False, cache_headers=('content-type', 'content-length'), invalidate_on_startup=False, cache_response=True, **b_kwargs): """Cache decorator utilizing Beaker. Caches action or other function that returns a pickle-able object as a result. Optional arguments: ``key`` None - No variable key, uses function name as key "cache_default" - Uses all function arguments as the key string - Use kwargs[key] as key list - Use [kwargs[k] for k in list] as key ``expire`` Time in seconds before cache expires, or the string "never". Defaults to "never" ``type`` Type of cache to use: dbm, memory, file, memcached, or None for Beaker's default ``query_args`` Uses the query arguments as the key, defaults to False ``cache_headers`` A tuple of header names indicating response headers that will also be cached. ``invalidate_on_startup`` If True, the cache will be invalidated each time the application starts or is restarted. ``cache_response`` Determines whether the response at the time beaker_cache is used should be cached or not, defaults to True. .. note:: When cache_response is set to False, the cache_headers argument is ignored as none of the response is cached. If cache_enabled is set to False in the .ini file, then cache is disabled globally. """ if invalidate_on_startup: starttime = time.time() else: starttime = None cache_headers = set(cache_headers) def wrapper(func, *args, **kwargs): """Decorator wrapper""" pylons = get_pylons(args) log.debug("Wrapped with key: %s, expire: %s, type: %s, query_args: %s", key, expire, type, query_args) enabled = pylons.config.get("cache_enabled", "True") if not asbool(enabled): log.debug("Caching disabled, skipping cache lookup") return func(*args, **kwargs) if key: key_dict = kwargs.copy() key_dict.update(_make_dict_from_args(func, args)) if query_args: key_dict.update(pylons.request.GET.mixed()) if key != "cache_default": if isinstance(key, list): key_dict = dict((k, key_dict[k]) for k in key) else: key_dict = {key: key_dict[key]} else: key_dict = None self = None if args: self = args[0] namespace, cache_key = create_cache_key(func, key_dict, self) if type: b_kwargs['type'] = type cache_obj = getattr(pylons.app_globals, 'cache', None) if not cache_obj: cache_obj = getattr(pylons, 'cache', None) if not cache_obj: raise Exception('No CacheMiddleware or cache object on ' ' app_globals was found') my_cache = cache_obj.get_cache(namespace, **b_kwargs) if expire == "never": cache_expire = None else: cache_expire = expire def create_func(): log.debug("Creating new cache copy with key: %s, type: %s", cache_key, type) result = func(*args, **kwargs) glob_response = pylons.response headers = glob_response.headerlist status = glob_response.status full_response = dict(headers=headers, status=status, cookies=None, content=result) return full_response response = my_cache.get_value(cache_key, createfunc=create_func, expiretime=cache_expire, starttime=starttime) if cache_response: glob_response = pylons.response glob_response.headerlist = [header for header in response['headers'] if header[0].lower() in cache_headers] glob_response.status = response['status'] return response['content'] return decorator(wrapper) def create_cache_key(func, key_dict=None, self=None): """Get a cache namespace and key used by the beaker_cache decorator. Example:: from pylons import cache from pylons.decorators.cache import create_cache_key namespace, key = create_cache_key(MyController.some_method) cache.get_cache(namespace).remove(key) """ kls = None if hasattr(func, 'im_func'): kls = func.im_class func = func.im_func cache_key = func.__name__ else: cache_key = func.__name__ if key_dict: cache_key += " " + " ".join("%s=%s" % (k, v) for k, v in key_dict.iteritems()) if not kls and self: kls = getattr(self, '__class__', None) if kls: return '%s.%s' % (kls.__module__, kls.__name__), cache_key else: return func.__module__, cache_key def _make_dict_from_args(func, args): """Inspects function for name of args""" args_keys = {} for i, arg in enumerate(inspect.getargspec(func)[0]): if arg != "self": args_keys[arg] = args[i] return args_keys Pylons-1.0.1/pylons/decorators/rest.py0000664000076500000240000000400311671741543017714 0ustar benstaff00000000000000"""REST decorators""" import logging from decorator import decorator from pylons.controllers.util import abort from pylons.decorators.util import get_pylons __all__ = ['dispatch_on', 'restrict'] log = logging.getLogger(__name__) def restrict(*methods): """Restricts access to the function depending on HTTP method Example: .. code-block:: python from pylons.decorators import rest class SomeController(BaseController): @rest.restrict('GET') def comment(self, id): """ def check_methods(func, *args, **kwargs): """Wrapper for restrict""" if get_pylons(args).request.method not in methods: log.debug("Method not allowed by restrict") abort(405, headers=[('Allow', ','.join(methods))]) return func(*args, **kwargs) return decorator(check_methods) def dispatch_on(**method_map): """Dispatches to alternate controller methods based on HTTP method Multiple keyword arguments should be passed, with the keyword corresponding to the HTTP method to dispatch on (DELETE, POST, GET, etc.) and the value being the function to call. The value should be a string indicating the name of the function to dispatch to. Example: .. code-block:: python from pylons.decorators import rest class SomeController(BaseController): @rest.dispatch_on(POST='create_comment') def comment(self): # Do something with the comment def create_comment(self, id): # Do something if its a post to comment """ def dispatcher(func, self, *args, **kwargs): """Wrapper for dispatch_on""" alt_method = method_map.get(get_pylons(args).request.method) if alt_method: alt_method = getattr(self, alt_method) log.debug("Dispatching to %s instead", alt_method) return self._inspect_call(alt_method, **kwargs) return func(self, *args, **kwargs) return decorator(dispatcher) Pylons-1.0.1/pylons/decorators/secure.py0000664000076500000240000000714111671741563020235 0ustar benstaff00000000000000"""Security related decorators""" import logging import urlparse from decorator import decorator try: import webhelpers.html.secure_form as secure_form except ImportError: import webhelpers.pylonslib.secure_form as secure_form from pylons.controllers.util import abort, redirect from pylons.decorators.util import get_pylons __all__ = ['authenticate_form', 'https'] log = logging.getLogger(__name__) csrf_detected_message = ( "Cross-site request forgery detected, request denied. See " "http://en.wikipedia.org/wiki/Cross-site_request_forgery for more " "information.") def authenticated_form(params): submitted_token = params.get(secure_form.token_key) return submitted_token is not None and \ submitted_token == secure_form.authentication_token() @decorator def authenticate_form(func, *args, **kwargs): """Decorator for authenticating a form This decorator uses an authorization token stored in the client's session for prevention of certain Cross-site request forgery (CSRF) attacks (See http://en.wikipedia.org/wiki/Cross-site_request_forgery for more information). For use with the ``webhelpers.html.secure_form`` helper functions. """ request = get_pylons(args).request if authenticated_form(request.params): try: del request.POST[secure_form.token_key] except KeyError: del request.GET[secure_form.token_key] return func(*args, **kwargs) else: log.warn('Cross-site request forgery detected, request denied: %r ' 'REMOTE_ADDR: %s' % (request, request.remote_addr)) abort(403, detail=csrf_detected_message) def https(url_or_callable=None): """Decorator to redirect to the SSL version of a page if not currently using HTTPS. Apply this decorator to controller methods (actions). Takes a url argument: either a string url, or a callable returning a string url. The callable will be called with no arguments when the decorated method is called. The url's scheme will be rewritten to https if necessary. Non-HTTPS POST requests are aborted (405 response code) by this decorator. Example: .. code-block:: python # redirect to HTTPS /pylons @https('/pylons') def index(self): do_secure() # redirect to HTTPS /auth/login, delaying the url() call until # later (as the url object may not be functional when the # decorator/method are defined) @https(lambda: url(controller='auth', action='login')) def login(self): do_secure() # redirect to HTTPS version of myself @https() def get(self): do_secure() """ def wrapper(func, *args, **kwargs): """Decorator Wrapper function""" request = get_pylons(args).request if request.scheme.lower() == 'https': return func(*args, **kwargs) if request.method.upper() == 'POST': # don't allow POSTs (raises an exception) abort(405, headers=[('Allow', 'GET')]) if url_or_callable is None: url = request.url elif callable(url_or_callable): url = url_or_callable() else: url = url_or_callable # Ensure an https scheme, which also needs a host parts = urlparse.urlparse(url) url = urlparse.urlunparse(('https', parts[1] or request.host) + parts[2:]) log.debug('Redirecting non-https request: %s to: %s', request.path_info, url) redirect(url) return decorator(wrapper) Pylons-1.0.1/pylons/decorators/util.py0000664000076500000240000000113611671741567017726 0ustar benstaff00000000000000"""Decorator internal utilities""" import pylons from pylons.controllers import WSGIController def get_pylons(decorator_args): """Return the `pylons` object: either the :mod`~pylons` module or the :attr:`~WSGIController._py_object` equivalent, searching a decorator's *args for the latter :attr:`~WSGIController._py_object` is more efficient as it provides direct access to the Pylons global variables. """ if decorator_args: controller = decorator_args[0] if isinstance(controller, WSGIController): return controller._py_object return pylons Pylons-1.0.1/pylons/docs/0000775000076500000240000000000012012307216015134 5ustar benstaff00000000000000Pylons-1.0.1/pylons/docs/en/0000775000076500000240000000000012012307216015536 5ustar benstaff00000000000000Pylons-1.0.1/pylons/docs/en/.gitignore0000644000076500000240000000001711674172351017537 0ustar benstaff00000000000000_build _themes Pylons-1.0.1/pylons/docs/en/_oldstatic/0000775000076500000240000000000012012307216017663 5ustar benstaff00000000000000Pylons-1.0.1/pylons/docs/en/_oldstatic/akhet.css0000664000076500000240000000025011645401275021501 0ustar benstaff00000000000000div.body h2 { font-size: 160%; background: url(akhettransaqua.png) 10px 3px no-repeat; padding-left: 2.66em;} pre { background: #efc url(background.png) 0 0 repeat; } Pylons-1.0.1/pylons/docs/en/_oldstatic/akhet.png0000664000076500000240000000222111645401275021475 0ustar benstaff00000000000000PNG  IHDR4"') _gAMAOX2tEXtSoftwareAdobe ImageReadyqe<PLTEHCH|PPGPFB9tP͇72*=2<]WGgFbi9,6]klܑU=Tʂ`aU8RPPʳsٌl}Չł{{zr\{nKҺwmmmB:,[Q8%""20&rkruNswNUL6,%+E4CُsfC`{SzfL9^ݚXF䥁 C-^?d9Z{@Kb,+q}ȵg>SÑ_Cz\LQr Af`d+@GL̫fGp]f![)Rܡ=z}tzb3I+F烉3\Q71tb+:KY:_"ӹ+ ~-w{VA eS䑢sצ"8),b*=AtdYntnMSQ˜ʅkV A#\ o[~M8_H2yqރvJaҚۭCEP-=\i@:CZ(U1iOg(B+~9Á 4O1QXϺ ]"R6t)}d;'L9 +RgwIENDB`Pylons-1.0.1/pylons/docs/en/_oldstatic/akhet_rev.png0000664000076500000240000001470611645401275022364 0ustar benstaff00000000000000PNG  IHDR;T gAMAOX2tEXtSoftwareAdobe ImageReadyqe<XIDATx]ku>\V<-m0Z 1MlDŽ SuH\[+0ZrbD$U,W9?‚!c`d;o\w=_թ߹scJ"[Vq|f=ֹ/&W2XFR("DWCV:Dss;܆B8o>LS(JvnWOUj\=(>raQބեeN;n\YA@pe_F؂ BnBt rElr y{ZMn<~R-P?P OP7vNf1I9/^_6v ۫l.BB">@\DŽ'LjR4ǯzcaQe˄& Cs<~}7؎kXBɎf:-&6^Ȅq6o_p]ӆ xߴd'^q'?L$avBd%hh(Ae. 92C\Pv'~Q/QCx ~;qϰR+HF37XNPk[9z l_c[6 ŭ4:G%&J GQv oog_\8W,WS(ZE{Myl7:pY*o3=>$uy&nl?;*pVNPkLkR3/zm'{'y;پaS ))׍a(ەlI2 !- ˁ~ 9qqJi`vUS(槲3du-dr˵ [.+J_!{@QvodP(5@pmD3DUTTjfI|b>.LN?BVˤdPOK 64ۗv+W 4;IA/d2H q|v1#p@-))sN͍9~oa68=d6_GX(Sű-8O1slȞr[2GRP LbcB@P/oI/S楚DcҠOTeP3LtwJeDx_b}2@қU(Jvo,S2%0cK$J>(ϛ( Rug %Y0PDkY֏ND9aIW}&YUrSSSVR(x*gG,f{Lx#lWBd7fe5) $e_,Bd,~,_&;&OPcYAլ"PuxUTc,P.dX˶]If0s( "d3S3 &Y gX!C\ TLͰ`rV\r2!9^cկQV# xĴÕ$A`oʧ],P6t1ɵoFz0mCqv.C##Ix*!^6vWd!Q>P}s}?)[#{մHHol/=f|8kz!)i,M Nۡ^@p';mTԳxݘYy% 759I ;a?oo獊jAdgToxHN*Xa;%*ce4; O3 -eR_G۠<,?#Ɗ"bvL ̳Ed$8'uh~nLvTvGbp<\ՠR#o"s ѠC`E/CJGqnH$G仧ƍ.r?gŽQ"!CͬYv(`1ZZ5HI,FY~?7游ë\LM.oQ*P5Q\\ٶfUX >CCC螐~)ߓoeS[mbb0:ù\z'eDX% / *R|-?SK^~oq]Og8+x8Sz[|Wn}_Q 7񣾼x˻&"5!d^9א0>(OT(]җtT${l}2-*)nJy%tWnEk;Bx$sUz#g6R}x$o|}WWnl06"Y%ܔ6ݮ:=q̣b}z䳄ICl&?{¸ ~/q99 ˲6p^@Y <^@_',ƒ[&dPWz)Zx I fq]ys>]C-a֨pv]]r~SP.z#7vSYTwNEg2쪡c5X/UL͈فz-j\aE w̮(Ga~8\o7mIժF U Ȣd CAO F[ƌBA=nڃ'Op@fRpFɟ]CX22 R%)@FqBvpeUj[9N{lZ~^9OhЈ 7jfYcp=>7tz{AKH(Ok#j3#Mqq[U\~I2&΄0>JoEvy&lG7:L^HWtM["dȡ\Ǘ_uVG O1*` )@=L~g4B Ȯ@0 ysfts@I nQ|(^dTTwL`}/hl0h,ۄ"n 7&u7om \h/k!gy4nT L/ˍ9{7שHM d511I]UwT*e;tN\zQ`k=nn.L(?IބG#;pW97lPw?!)EXɘ&|XT!Bqǟ5;{Y.Q7`Nnu^;މcᵅssGZ}yƩbHQX} sHCQj,ڐCfJ|ۓTMSPN.TOMp}wĶ^ʮ>2}|;zIe.&VB=kΈ3.3Mvb!DŽ;Nֆ"nd+j9MF#(iK?\V"APs;_N6p*B7q|32#AB:E3ۃ_eK1͔}C dFY|A?`tQdEGgt)!㛙~ceiqnH5#:#ia4B6$72*~[2gIn>ȄJ~JԀr/dE ~+2Q?.f!xkL'67tXoAsT"*84b4: +|Fb@vS4AJk0?d.L #70+am,^AْRq!@p(J}&Ό0-g :u{P1?pٿvՌ2ͺ8#QoZ8g[[ ;BxjeNTg5 eRSN}W"ngm 0ۭ$hRl \#~fcnʢ D;}P(d3.j.ٙzr ˕T]df:+uG'.RFބ@3 < p7qMqxҪUNWPp yd+0p0dokXVrv&6H1Er Bg}M$Fp:>ݍ ѣ` h,[cXTO`YcAY[%rqjęЦTm)2,s|Oiqw*J:5+hNJq/.&Yk8ر]h>&!WXeyGDOAk}_4 ΃=nBQ)2oX8rk+"5?zŏg6㫆WMR<MNjcKWSk,EK59u5)HnGN'=ޡ"4S/+l( ΅]e{ vOĖ5B{u 5#ҵTׂl驑^*%6򴐕96[v ֟c{=*?\FiԸ'>XdA kY~[=wC%isph/OTz{fĪp֔rB6^5<ۼ֒G9>l񕞊G댸.]ɕT58UY۲X#aKxK30#ȏi$Y̅*|=WDi KRL}¸)vc?*(ղg%⨏X銥quY*AP{SYXִW<3dg%ʺ's’+0"dL2&Dș"dNBr"dNBdL2&D>D8N83 8 vjvnvjagVp\'A;;;ww&}Ia;w ɠ&A>:"ct33˃T1\OZb!_>z aI^L 'f039c3# `=7)>gJ,@0`C1=UGWz94444IoqHG>V\z)> \O~>r1Jbdd,fϡֿѽX2#1#/HINn=k=u>}zdzuoE8Nb1`Lт!RG>mŰ({t@g#g3q3`&q33L3q3q3`&`Qw'9s9w!yw'rsܝ3s3cP{q3 ;s'hB8O?sfcbщǩ _FG+r" ^Wcp.9Bc~^Q$sO13дo)e$*g(!H=+2Ÿa{2b~?S1ѽ"La0&qYgqXI Cɉ0{ELzp(={oB209 _aރ(=NL'HgяHc>6!3>} 3A O" 0f? UkZfar$>38cq|iuן'^|yu֟'^|iu֟'Z|i֟'Z|i֟+Z|y5ן#^|yu֟'^|iuן'^|yu֟'^|yuȢ|yuן'^|x]פsÉ zg\Lt=D=2'$ʧr;ݪwk;ʄ}`Z\r1Nuv._5Wr6uIXdj3O~[BKf6Пb6i 'ǨG^pj?ى; 9ly[wCN0, VA=!4>4˴t+ܻxmU"F:޶Iv, 6n֏>=X:gڼ{:|}n&b>=|}LƘTkdk,>Bϟܘ*VpL;>N <LL0^B_GJZt̲*oWUuE|Z׭]Yew.n E:f|-<,=5Nmxu4" 5@ݭIqp{9*;6MM }x S{NҭcM<Ȩl}o/O={b*Rf^r? EOݬ6-{Om 1rTqR%YUI]{\jÐn븢ֶAV.7U5ۺQ&͊|B;4/V]yFGر\"EحC{[* aF==_,5y+fbYr/6n햨 Yjۊ/=;L_avk$³5$wZſ=Wu;]{tJ#eCZl[ۉh vyqrO^^Oً J6}m&@?fZjtڔ^S')M1pگ3;8-{> V6w7_E]aܫˊ[}ו2 k9tej*PRV!l׋8 bٮVK%@X@$%h͌g U]5HF ;z[M BsZ{Y ݧ`r_Rc-:o,|MUuLؠmbWRPe3c50ʺ`$Vj~ZG4 iKצrłlWr**Vua3WRԩ+YoASIXJZeEuͅiZYgO_!hS1s,scT )޿h3/yJM+kʘugditZI}g -O[]oֺrA=Wݲ8:BTK5~Y/e~?~K<o7!dk]UҞob!n[%oEq~mn\,5],"{i6~2a ijWoF2&zm M7\.],uume0&-ߝ%qG'oC#Rm׷W]Rumƪݝ{LE[\BR}4z1n;v}UʫM[VpX+ysY]kɒwFX&YȂݻMqSkM[W^Vuj ߷`Wug#NrfO7SGFn=鱏"þ"YmV!߲uLv ٚl[{쳽_i*<~b=FMPUZW7*\HISqdg'XzWa{S[0\9Te PEz* xKٷk_Y* BvlJuBK1}sic]BRPjT5l臚ɘ'/ۢ1O~<L偞LJFVc6"c,lon)KuQ{67_~Fe"{-{+o (X=evMkh`)5]lg8P마%uE nݺ3]X@8\dzرQݩj(A`dQ-af]g>Kn55ǭf`cMkj){LtɝJiƟ ߷w蚴k "raKVn+3g.0OOd5U+WWZl{jVkoby=:)Fk '+W=ׯ^Ydwl+>czdy$6zTxۓ_sKYv߭t jVܕZXyL^kX: *Ek((J25]F})háFYb.^Ni[lO^N$u1fw:IݮXevYky (ZlbQS5SR@(WH}CYu+ ^ N5[Q5#8K+׶4nuNMc]VA:c޼>9`tGA|t>>A>33Ο` 'ܟHGfip匷Cy6W|+Gʲ?,M:S^υ|o_< x -B2eōj| (( Gpketth.6.;#q aɱu/rº?"ض-bΓ΍AYegC_?Rp3_5=_5=_5=_5=_5=_5=_5=_5=_5=_5=_9=𯚞𯜞Ox{k槼+槼+'=m||||||||||||||||||||||||M 7>w7&Σy&<ՅcESPk9Fݕ:>ٯ]Rk1YAu(鸹~%֯}Qa_5q§XB?$aS'*MaPn=U q=Q+":Q„2E1Լ]hCW0 04pKqnn2IA+ciCO6Xʾ2C'0 70;mʹ5s wiE^Ǚs9`4v"78qSt'9$V<7 g |f~ VqnGi[TY܉_NPW;johXXOE(+D"=w×8(6mge@4iZX_4V @ꓶ1ZLB11ʳ LD8.M3M꡷"6^ʞοW&"QD.8z'2n]kns^l@mޫ*Rނ4N NtiѮZA *ad3aX՘򊝃.Y^p kJ'T:o>;)Y+e$lv!<@P8V3`P{g0hNbG 鰯 h{erE;6jb8VfMsOO>j7{<43AƖ&ۜnmK 6I`졧hǴnhT<*-AHS"%#ِ c^8ɦ}_Q>}NVbma'Z{SA4d[^/#vJ\&11ŧfI ؔfŀ"( "&Falbg*B܅Hn,љ|ZGrD r;BB;6B 3_S #´t10 a46es )=(WhDCk9z:,PNhVJb[ˋFYBaWc[0={: qeRӑ8 TXl7 c~dRPƠl=AB󗀿 /3A®mڶUaLאocY:PM10V#xnx[YՉV )o\&#|Sm=P{g ;ȄqMj.OS+PG7}8q97(G|Y aBs8F{|6 qne+L5,gLs6ŏ ջ8$n!8{8&e'=7n#f+Zg E%cmp]̸Kw, PSQ*X7g o!6'u\F*F}"{Di[̻MdGaV>yF6l^s!5i@38nK(m ~?bh (b\ÈRs߻eva= 3Ƹ5v  Xց3gmx!-_C%V~ߍ:ON8з'e,a;Z[K8׶_)1<% \" peIRtj ETm?Cc>j Z=9̫Dq:*SFL(:M1r9S2ƄS̀C7@M-LP:Iaz vx0t /X  ܰ|']S1ʵ8,}湅ԙٴvnpZEdꜶTԱ IMڬ):!?Gy:DcW^bv(p^u%Q\wŲ{ͱ׮j=ͻS7 c@-X6m>#-nV[PǏ6Vj;FHs6aםJ( :8iĎ*K*ghت$.B <5`kP0s l >zgLa諎Inj .,GU8RIF#oTSnoZu#gmqg:Vk* yip11+Z6`"Eg3v-2tP""NZ1WGy:_=G0(@ˑ8.FÔiYMKLpg}q^*i~((Y{)w.z6HQ1V.4n'%tC aT^j[Ϗ9U6(LZ%skoUNӳZuqno3?Qw|3q*m4y.`e.(m5gg뭋`$Dnf㹽z䥱mL{564PLA(ypK`aA&͡sQN]Qpb֐i-]RN{ŷKq>OPhnf{쇏4m1<-!) Ռqq4$_Xۤ1]&#ooM@;1gYTNuI8 g D$x$!woiJ',rźX{dqNDqK ʐf7 2 Vc$w I8uU1BuzN1_,V1vE C12:)9;:bۘ,Um8ߋ@$ hrF}@W 1Fj[`$gSMzpM`/+/EH1= xˏ40UN-ᶞ 0W%A.R0#nt"BH۝Hgb]zx\َ֬5Ur~Z kl9$"fvXY립mu,&3=74>6l5s:xXponOvj5ل~Qa{GUn;NGYCFdc=|@Ttg=,8Ieq\%t̅S48@2LHHVj NOR[ KW,bYcխJYbA\ ճTN|%XM?+#j 0KwfCl'FX^5֐ ז4F5CyoPNF1dV2ОtY\@0X ?3IԻVհ*AٶnONl6ĩh08b'$ >cV3&2=5 QkL1jf ;)SOFGlme qxS jՆJ׶Ck#=*~#vg vWB s-s.-a{(_ vDpqV'8A k8LOLy)Zhą}*[5;8HNC! `>];kk^n!'}|4<(;s16ܟt Wf zt=g47Wc9$uWip&H%KAE$Cu|tGcE9Vd7x|u|^y1A#0nH%9SndՖߝETn=տn7̝>v\J\Xk1#K$./e\RgF֒ӂeEFpωös!)zi p[u<."~jGEjuaq cXEG]aPsb| ocE3mwt9 EvtK1-ltV+p:kUZH{g궹c ]eba\pL̢*L;Fwr0pHKqWFR@TjdmZvzU<֬ڕPdcGo{3;\+ɡn-G(os?MXG@N8EQʼnDTU-\2( w:ս  58e-F ݶKv-).i+5JpQ8#-: r سhI iò4f*AIDl_-7G:6چ);~q;4ǕSmWxzV1qK1;&>^.ԫg^>JlN'j-686"7.;{QNnPT GȡH:L[Q!T'1M 8p|ejWh[`azLPQ^ϣ]S)kݳ"fvsZ&}@;(q$[` :Y` 8VնF7εȄ* bsY<ՁZcc{1HֺD›4\oQ !dmf6}bd= '#gӑ[S>3*$BxUS~)m<%l0A #1Ƒx|}SSX8oc|U\0էC:xĸ%5;wExdXׁIW,:+'sZ9H6 љv%^Y-/9fIqmZ# `j@]a]>˸,e> U[k@q^0 {eFl+H,T`N ^q<?yXo砻u4;hԾNoW~t2k:KqXT {/ʀ[YX);qd'kb}&McXhJ՞`(_\l"03^ܫNZ#VzVwspAGy$e\?>\S\7˗8~YJmn|5lu7c7sk7'~Z޵yfEXO.Dx'Ŵ޲xzRg, KxQyj~=czԿou(C>a5B6 3MtjBqn )q7J0neޭiXP:vq#z+K ?sA%:P YPtDdNuWsy8;o6ی|GHuxv )oX9=ཞz֘ꂾ>َPDfj_W2WS~VtF"}]5 "gvC?&3j~Ӱv}◲驫`>-htO騸RCXWɆ !6P0N=OWn\)£ 31:*#?u6skưڂ PN}BaN7U8 ;āQ!4i]]mۅUS9(ζD.l_Slj=6ԁubBټ7Gi?r5 c}6=O*u\Nz'XVuJZٲِͪrƴ,,6砓h{q\~+IJ+` I#dWJaDd+RK~6m4 $@֡r+N{ݵZ»(F۲]R\KHa[i,`K}dC#VjWPˁbϋ$;KfEi7Mø(2BfL(o+1>%e[f0UM[ v-R.m3CeӬŀQo52? jk kn'× a*tE[q-ߓj [KKAV4۹g9@$wj(0.y \iRoZZwrȫQmMU++O3+W 9fR6݁^QF,\<,\Oeaj<_Q݌zt6.Ӭ֮\ZgǴ Ok#ܸΆ@A-,t:0"\ zq=!vdq֯2jka\o W-s]T[XѾmu 4hAIpz/2FӎTՄ ~U8LI\cjmC18տڭ *ʸّMsVlbIhKxR )(ܻr RNePB`eyq50L9sYၳy?']AQ^L GL% ,@*1Fʼ%L'*y;L=_ 䗥Fl(xW)÷<;9VV`+ʟo.x"R0st.Jibl<E"^OP){EWRY#BPoi: U~?kD!.K}&0ܶk^? "{KK%U啼cqgL ?uj/aW7J.;Kq jG%5("@I7s)+AeY@|Ki_SŠB_}"ه'i_a?w󾧕<}O+y_Sw򾧕<ϩ}O;y_SW󾧝<}O;%o~ JJJLe: q%%`?xP#L Y)naO$?K9DR g~?x]KQ/M|q+GL0F?PrYcH4 A_281 5W Cxs`}g1KE+O؈rGP.K}uOQ~c??8F6u = y;ej+ }WKMUyİ9k>b%v4y] w^?sܫ-έ?rIK+|ܤ D/-7I4kԤ#Րx Kw+'b*2y0lk9цD^1*X̫VW6LFeXMȱagZօXEW)b:>[kU-DDVGܠ,tE8l-1b9 Zq ;ܣasuiuUr}g(WXN=r~ E.ud]`R)UTG;8UEp"+7\2KT]Xq»sk%t^"؆6.h? Z(b tWZjt @͸nP%IMP$fRcZ{V@D k0 [0 ݋/Ĉ6NB:WPDn3, `Q5]AjGޕi +*͞b bMk8+T+B0IuCw d9G􅂤>FG\K:cu/QD,9,D|;~Җ WQkLYXŲ<W0{E4'P+8mJZpzTg:ek\Ì$kGZzs@L^<L[ [^g70h {e*F,`eA,ȭ 1żT _5joYCȜڦi8sm@m[ רQQlT_i*Vm4u@\ 醭ؿ%B2ҖKWjKNNfDU7lsPXo̦!ح 5J>0/FG.h/y.1`{A(W2nʁdcKnDJ) QWqsUŮS0fX4w`QR5ء\t.IqA)irzsk,HZl?Q)Ԁ l4ng"$:Y}AU4b0Y!45 *w$t(iRprY YȽYq -Eӹz(Kh(ͽ(5K4fw̼siQU@ cB|nRVF )KX&Җ$xZ^xQUX4Yʵx+(~",`(lŒ)zw,PЮVJur38Z`4s԰DePmR\9,M2ɓKY'm4n dQTHc#U!R7BE16s+7!3B/^& Jq <75 PBS&V: t< ml_ VA W^ۀBUp@iAn #a1:CBqrfGa娮.pq,¼`I 6ct^[Nd$E]GJ@_\N6Y k?mBpes* ]Ne36B% CEiYFԭƺF:'9&lm-Q5arY^*®&~amBXXuc`</n91-!+0u鯶2a);ѢM:jh,Pܱ׻ zu=U+@m(l*%h!# {|;*"ΉR@/5<\BWE]RDQ5-B@2kb'')>` 8ۚҹQɖ+Y w&Cy%}].1E!գ-SSFA[ 7w]DZ.JܰEtcXW\mʱLG1[#'$SE(:l)+ɫX p+Fpd-GiC,Y !vM£UԕX\y]#Z(-<E-fV#y9a@UMOo V_ KC\q ι#sVҩHaB'.N2\Gف\kIm.3b rTSoJ mmJfSoJ^$.RcEmhW#8lԫԶCnP\% *Q@}\Ҟ#B' siLdl_@F VYZ!㠂Pkҕd )PqBvk&|^<\Qj5H,ZZA)#E }N >LbpHUld.Xg>.(J,T7(M'jc%k 8!@3- ]q,]ѕ"VSn44o㸆y)_O^E.k|\j Esτ ThShMUsp`em0TEF *}b ɰh[Nfi m8EP y4,9^CPdhwS#B`3G7!+fVY>nL +Ad[}Oh ֋U=1i.8YimDwrolԠ;)( ah^qUŽ"X:K'6j *zf3C =` ✰4RSpN0)wEҊ{9RJ&D٣bQڷ!AJ4f! r  }Ѩ5 1"gVi,#+cMyi8m' GnLfeAJs]5̸L N ]&2(P”ɶŭ  8Qڈ דrnsnVWBdYDxmQ[e9 ȷWyƙOvȞKX'21̵k,CB%uӀx I&)9b"-V-E9#'6!P@=$.ݐv FO6umvDBq9fS}M08`V8Ffs]NdP՚382VRDȁ HمtiWb`_f ;!Umy=XJ'杬%{hen*Y \  T`͘7A{ e%[Fh,qr8Jq*r2Mq$ʖ] (־DX{KXږM#!8EP1Tp6P:Sk7w*5}u &Mv|@Ħ*PK}(`\WKT5TAX4(ƅ; . .X$7vOj²pk̲jH9UdS&ʊ-E UqR_S`+ Qy|rZ5e0(.|@ O-5XRj`: fBRX8pK{jV&\O +o5S0*lSx_R 0;tH]o;ʢ@JUiŖtND6h7Ҥ!j*;b^㸠ip8[<]tCTgbH#hٷ XwbtLg lbLlE010U2@}U1#N%\+6.A+a٧@$s3:3Qrg"8G6⥥Mu`q 6͙.ka #VMP&.*>I. -Q"1 Ik tw2G:lEOA@ _%i3 Ձ\ ~Szv^UfTpĔrbUpkT#"`p.":Ou:Y \631|#.+Ѭk6b(~-C]讐znYf6!K@UY#0;am@֝d:1Z)ePc}n$ k4xͦԹ[f%#th wq b6t ɔe"ݭX,,ޥG(խ2D%h#U@B!xkH%"hWNu;C@Qb i,@ @bcEb, w* :" `Wb-ZTT] N9ףB V9Vqgn+ lBs F9l5.uEx\Q1e\pFmV[CP#rHXՓQP>RJ%PP7,J~yY"kAk "2v|PZqQ fZ̺(ɮS@x"])<9^ݣa}P(0Nl~B" 99k%Ud{HQ%JMMCi/ x7kDa*mգfQÞDde QϘ!ʔ)P%Ή,%Wmk[RY)cP5_&yO0$d`%4(DcQsP^.X1ZB,a3ER7PR #-qgح!A`]e%:7=KغU8pi08+ q"+t*6ه5 ixF>)f ٔZj1eehbRۙA L ZRQcX f5Ia^F,kWj0l:c4qfVÀoE< w78"DzPڏJ[wF_# q!4WOL¤댌4Em*rjL0 Mc L69ZO_z*\c# _1if~t(VdIzBN#woh4MU Հ%Tjz%"V;: D~:9ÜEeޢyWt|*&ur{ۼi%m,Pk> 1Mճҳ|.!L6mOqY44D Et@xfPE?1^`Uʐ>kN^mɰ\ CjfU CCOAd1nfPJ Q<` i[p"* LR@s 8aVp t;ö }&3#(Ld`, 7&t @1~<0A{ o`IlKT3Lb`"IY wi! B;MFܚ @9YݣyI5tвRЧ 4h@88), Ce (>Z  U ߁Qg.l@\Sᶈ. /~'*iJ ?FDSq8 38:Pa2KXj;`bxACaIA@˝^t'j dx1AuUG^=e`P  hS`1B/xJ6]e 3 = Բ 2|3STC?0)dџBI#M"!&ia AU Z&YP"$Q63b>syϹ qn:Ou6RݿYp)x D<S xI(_<`Z8.?AfD+lX#M;UNdMt ð*Hvw_?9W|+KH Ms$~rMGB):r;H.[+wker*mJ ("ߘKPoZ2 ֹcǝGS['޺XSs:95rHM4WFKnO"eK>OGW'/UarUcaX>arW դnrq }gq{3dLtL0 7t)\ec*㺮sDc*3kڃ@78oo*w0>dF[e%fs:-0 w$S +t6N,+eǶ@lF WZ@VJ;?K %vZZ7;z딋d0+?k/լG+?%ީGtk G?Hrcb=+ E9վ B)cA=9!1O}>*gӠX~,cV8!Y*A.yJ:#da$!+ݓOAQք3ru$@`³ѹ4!n+y>.eCjgzsXQgCHVeBrQ(z-b0t,!Uŕ#:Dˤ:Ht Cjb `$hNJ=ρpc|!` ?S4a,)GVtW~k,;3XROv5 -T#k2OEXLa@=-S$d"x:%3u:&$\.M'tsd`#Ϯ۲.ÞvJbn=.^rqմKsJǶJN. ab=Euam^KJϝ-~`t1ΝfdC648*K|z b5:5ɸbdG 3D6&Gl\1ZdRV(tdDGway')d@(c={X[='U!@1}AMg!WZ/Fl4_i5>߯g񬋑Cal\;#(~SC۶XQ .Yqi "@H >t|-תFy: LsN%+١trQRPٳM xv7W=r{ɴF.fbH[² 99ȥr:[yїrtWL'zv!hÑq@7_4r &͗ o[xBzPg"^wѷc+YcH+F*48DPWI0ݤx02`()bQ?g' $%+MēlUOC0@ _pveC.KZlQ=!QJ5CVฤ倖鏾A$s;n2=90R*#[׏7?Y ~Ja8* +ƂlH(w~A.:hSz  QՕXPMi L5p$}ʚ `X1U.  A%$(@E @ĄQ%{Dd&7Ǝā!{߳ w]58? Ԁk.bPٲMZnfB"|o>䘂pV%L律a ~ĭuz rs,^bލQGB>ٌ :wCIS;!U(L#ufj*&(+Ȭ(A%ʑ8zWnAe)Cΐ`9:śBD{*(i~:8<`{T+O,S0F p 8f<_ڄ6o,ɳnLfuڸ'X{ od6Hͭ%|)=87""ѩAjuj(t1ҪFR =Pwjy ~;zťmt/2hFpfo-/nڰx6 ,d2KWf@s.o|3kڅdu`+UHT6j6mKV UW[p6f9zKaRf~ >YTB?A8UmHFz=լZ]lh!P4O}wsdong65.m jQ孭 9%Ff%\;k=uJo|PYM iLrUjМpVs;L/$<yYAbuM.nZ pG M֗WH^03p/MD~/e^}|*"{|呟 jŸXL^ae1oRn{eFV0g9IYJ[n|^`:"АF}/s'߽k1ysfAB8"ɇ1O&bFt?GZ[r/\mw|ߣ} V9:_Yjry[!⃕I$qah/茅 pt]ghtUsB@%)tF kH8*/.(p(C {[vi ;.l WZТ?9D22&=lp~Lvº,rnK.g{0z:/ܒce3m-WwabIs΋/󴾱Bi`w~԰"  Ͽl ޟnRI dyp.@oIqOC'uaqGX µTpx*-#Eъ,jr+f J-zHYvdL[H~C*J,pefB&K OZAH؁w+N /i9Ѩ sN s::f4:``9olbI Dhӂ]8¢^=cgi=4JF-N BFl!`sYC32ƀd_R5$. 8`r6o]3 [+r9]o+^ef`Z/]Ǯ!׮Ϙ2޳Ē85 qO:UjX\k!k:8mjw/%WN댇Ş# 9Qs))nb9$5K8LtJShJ3q#RW)r9Ѝ?߉ uQE,WE2jD$IK> _F$Ut" Ƨ>eHKF8c\cÈ6&9u@5>`sND`4uQ2F4(zDGME,3kj=Lt-KJĴfontas.Ol]KB_ (-.%Ύ SFףZ!%a B[ `C!3KĒUͧMVM̙DlYցeZiTgfαټuj 3=թfc[uX-ؒĒ8r{q+J+E%XbCl {F-b{'C☈br ~RI`A&:8|&8ϒ0 Nq{~-I`=zp~G q%I}IU7|:ŧ"IuEMwR<~ uǽlG.)/E)yP yE n{] V`sĒ8NjvU'u׫ZNt̋X\jYP1W8G0VCj.*9y+|T[EQXĒ8!!4wg6LY zi6\ D6D>; dh -Sw@c @pZB$v?yT%ixPJ:us.'w.Wf78Üoёexte{m~J\[30WL W֪wqtF!3]L,žԎ-{a(,)(* >QzX4Obې| (R1 0 U=Oa,9EiT;E9$hCU|PSG80nHD6=j<<.N*i1h$p 핏K=8ahة@ǻG0*㱙I$~\elV0nI#~Y80) 8o|"]`%OZ]*^ҷj7Z}`}7&AgŋNC3[> ]fƯi+v>oʚmc&-薓pT?mV:eRI\bG @k KX3E, vf%8J;fE*w8L pp 5!i[ߛXP>h.7lds@Fz*e\(8tՎe ?_Qt8trpVvgΪcVL7y!xZ <+^2Ǎ_劭&"Y7h !G/-!Vh5[l敀'y,?1nq66ݟLRݨ{o6fZR:p.I|B#e _ƬOp*p9aw BAO/`ap| >7( |G&Y|7Uj+.Ombz'pYa: TD؃{ʋFM3< s*L얛ŇV2[c3.Λ2 j =fJp߭{r z82\{y1Y9 Tx^IL GvBFf>ۛ.GKIYAHl kf>m)H;WߺkSqۙY;±vLF&;x/<$"qg^rNSGuX!:/4yAHy7B/xwǯ~~Jo1b!-5_:Q-iT%gOgbg"uyݐbJޱ[X2(&VG fýoE"9'[Œ#Ad"|`\oRbɅؒ+Gq_wnr]s4wZ],"znL[;c۲ͮ[7Y9u?je 9,rv|փoly%g,e钶p"HKi û}uG`´u"z t.uHPJSbfa,h M5m!d{ ODz2QϜ}`lV$^`!s+#}ޫCobcTtc/0+QEZX*vP4UXXў"ɦ/m_i%[{-\vUmˮ+;PgjdkiI^vcI ~!R&br9uyw\;#oȑXAk݈]yŽ%'$_Z/?Y_H˕ֺ\^kK6`>K)bb> G"rRgiH7fƋ<ϝ)$w Ά&\2AKL.MHB E4E)NoL(N!s|&<l|0xÐ'HAؿ9&9#Zd'vZY^0~% e }_IU%e!<Rl Eb++ F=gIZ~Z^#%#ɤOLbrm!d̈r& pClGlЄB~w*J4eP8MCˆfUA74XgLקwтF[u*GOel÷7ZhZFѦq[> ]ƴB7 BSWhs B2:-3adEReʔ^}0 <R7L-5D"4D-f68]qV07MW10cB7p˖eTd2c0i\׳tPmy&ޒݛM R./1I+dinn:~cqY͕uK׉rOXYZDmU=Aoo bz1n[*0!I(1I Z^C+qu_ϋ Oa~m og6%^"rd fϦY:z/ȥRD5>mď'8o%7'>}qb Ǯd w5(r IuJ{ۥXςSX-fԥX$mDjI#S3uxF#]\%k}~0QgM RK|&RWF Cm\T7 cD5/UX`S8b׆kj^DxcrAp3B37_Ǿ\G;Έ53rBlz=s.3mn4% y/MX֐]rqسB(TH9_~:ìL(,5֤̺bTT?O KWL:/$^hb9DanfGb6#LJtuWʛnz&gA3cMjlZX֡9ݪ^Z3pOM &pE,O돪 t<:c^tde_cdZ'e:ySvR{S={_kC}xa4N}%}Qk~\U<υbXoQ0OCT>EdIJXkEBǕ8 ,0Qԇ'&~\? >f4EvLUz}}8:5= Com̕I|xB?ǍRF dzǝdI~:8FGJP Hߕ#ibMʝ|(Q$T եx(I_ÍS 򷒴H^dI$q3_{E#yZ~m+.Zhәv,:Fye cEK,wh] CȪv۠I^xVjWպYin 0$B@@U=1ƌvfBY|H/P@y Rsvp~DE֯ l z H($$. $6H!@4b /BUUtopz_Q\|yUsug/:X/38Vڲx$bqZ9`yC˺q(ZT%ŐrI!X"ҸXw7R1$IWxjRQ`{KzFL`(E\r` VY>F߈a U=!?o+qۆƹ~x-{HݶtUܯx*|=Ei+ߎJCpۊQPq۔IqIYS@xO sGժy3T?~V:K+^u X{lJ*i:Vf]֘XU͛8o3,myz|$NO_|-mf;i+%"= ߃ #S%bV(lF ~KEd"o ϽN zHx+!dm2 ;:O@#$$JzPz+3MP ?(tM`:NNcAȝq` hx㛞4^:4Zcl4tF]]VŽՈ/6w`u.i4*Za؃Q?.Oץ"E|oFuے(I` Z?YHF䛸^14Ut+JO b z^ۮT#Ì%1[ca'&'Hp&8Ƙ=0˄} ."+l3ԁVS%QjzhO<z&Wt},mUU쉍Fc-ȫH5W =b#;dTFW}_ |`4?kqb҉_:$6䃢wꙒDU}nH\{8W'}4Cr^kpixexdΘf|֖0MׅnOf qDywC2u3]~kyt~Wv8~嵾ΠwZ+4y?5jf3k'}ګP`kliBKW&cd4CdI82kSO)ɾVҵwUJRPaBD1,:ǘ3E5^@sp awr7:s"ǿ)͙bᇱ1CAT[jTA4.^?LKs7SsI ⺪]ͮȱ c_t_Zzܔ岼L#3/-?xh^v(VYwAʹҒ˿2;-"//+?y-"?f^omܸƴ: `Bi:ZB>evڗ7KW4?1"P}JyƐ@P]fg>DoA5MOMzs茳Cftr. M<(Mo_2s |_ECצ!f w_U0>{!Dw*Be ~$LgMb\,⪶ZY+llV[9Eywk7Xu/&\3Ǔub+?}wZqzLʭXRrV/?2&>2䊯Ox=?A߄v"ѧˋ_̋@-#RѯBQ5\C-)C~tV٘QUTMU)*LQ"ĥk6ȉ4Od|`|թ@`\N0?$r$d9 t o ؒ$#YE$cL}y%|C-"òŒEb`%O-X΂ulwեX+&qZnձm3ρh*cX.SoHFfSF4m/y]P $ٰıV`!{I\}fV(uA(١&لcW`w37DĴ ̟P0+t^a=ؒ$ah̒PA\Jq[0g|R(ټ#*$zf",kR+.%f`,Iy32$ΎGE|T1h;O(D{HCd( Gx^Ll]RH.-Hp(Rf%^)"g-@h?+ [ԓ5*82ȥKկA*.DPadL*Irqr9FǫP:Ze*젚A6싑Tslg\g1 :.Іy8Qguxr^*IQ ~ RѦ`B6<;ׄRiHdv`&f^(e2]/%Ic3@fBMA$ނ3$δh{Xki0=J/Q'[9-jιGUYV7L7oU60rVOYQl'gZ[*T9i:$q>kmE6z⃂_o_5L0m>_|s b/)^p[%}4o^0uIa1O~}}3X҇epxؚQ1AQɂ?e{ș+ Qq 'R㣍xpprIG8kT* \i(F-qb(P.㔺A!q ťTjO,H[NoՋϩV_s8W -(x{P9<4s?yT3F#DsՉ%q¯&&{Jo'^/- r_;B4QΔv'PFy+#hP%3M> ¢MQ"Y@kĒw\E+^Ђwdoua5+% h:w0: BȋV,7MF^gZEq(L\`bIŠ,.#O@JA-"/2m{XpH+؇E0Y'Pkn"=u`#;Gh?;5ޣaI$="#R@2ݟ`Μ(L}RfO$+x(mڕ%+<6Tj$boNU^Z@ĒgͼiBvl)¼Vr3fz;oêlekRudM7-碿 Rѐi~6}DU3~y:$. mH&vL׳X䄄(_ R(GM\Q:O,SFlOv+(͞NL,‘kli%hrB8iMXafTBz4G. A uFNilαv;x_>sV6wʼn%qD"1|b!2p 8#'Ջd( 1zY ؏I"ڧ^TZ?# tFR}ٟX#&jg\<~ G(.Na:?'Sc ⧒&ӡ~b쩒T:U~IU"n`X"JpZ6z ?Ru\ʏ?!'{D2u)"zM*3ݭ-sRhi-+|yU&72\4drκYnYϦ ݗ\y;2)Ē8{BiB=֎RHl+Jg[Ѯf%dJktZ`ZFc׀$Mc>vٶ0$e!z1VR0:cs~izjE Jt.0 ==y^łbICwV5jOK[{c֊gb.ʭ;ۊ,'#%pnj_rhe9ҏeWWH.R,"K2~DKȠV8v((S0_~Q)Btq mA숿)Z0}bI?Ӝ}k8UG|T+K1[K ")!lٚzH1BDo"oy~bIv-"ϸn-r kݖHy܊$_*˭%jtz[vZ Qٙ\h-X}q,.rr=̑\,/N,b/@]fvYu06GvnOTwӴv%+x641Ja藿,ЬJJ!4 ,l^VP%QQ=5! T'*#Bl$FgPZ/1 4^N,s $lv;.G+PvqK[2=(.宬'wn䬹K(Ւ,t wv3eƋ5y9}ke%W&ĩq>,/+6xTaTWGwi m)o'VcM bqNSPp&3!Az 35@Xs.8#[+)B 6~Z.g0tD?? 0`_[k'(",ΟXXK%خjTZO. #Z&P؋/b+2-.E\Z-^Kg *0b>=eVӑd2Y2~dbImp.clzCj0*8*\2 MXCv:FϢT977FЮM,-h>g3}2oK:=\jJOCj;BδkBB28.vtM mn!p(d3$76lje]Ӵ˖O ˯4g\Twٴ5Gg΃i:<Ȧ͛GW$3Mr~bI\8Խy2qzT7|P~Ƴʟa7$ex #xO{_{]*UaKz g|q?M/=I_ q ~9#c(g=SQH馨p񱸑-J@G8?>CҒ$ŋ=hnq(@# J֖Sq>KjQ n_'4j 321W(MfX`_F݋IENDB`Pylons-1.0.1/pylons/docs/en/_oldstatic/default.css0000664000076500000240000003175611645401275022050 0ustar benstaff00000000000000/** * Sphinx Doc Design */ body { font-family: sans-serif; font-size: 100%; background-color: #11303d; color: #000; margin: 0; padding: 0; } /* :::: LAYOUT :::: */ div.document { background-color: #1c4e63; } div.documentwrapper { float: left; width: 100%; } div.bodywrapper { margin: 0 0 0 230px; } div.body { background-color: white; padding: 0 20px 30px 20px; } div.sphinxsidebarwrapper { padding: 10px 5px 0 10px; } div.sphinxsidebar { float: left; width: 230px; margin-left: -100%; font-size: 90%; } div.clearer { clear: both; } div.footer { color: #fff; width: 100%; padding: 9px 0 9px 0; text-align: center; font-size: 75%; } div.footer a { color: #fff; text-decoration: underline; } div.related { background-color: #133f52; color: #fff; width: 100%; height: 30px; line-height: 30px; font-size: 90%; } div.related h3 { display: none; } div.related ul { margin: 0; padding: 0 0 0 10px; list-style: none; } div.related li { display: inline; } div.related li.right { float: right; margin-right: 5px; } div.related a { color: white; } /* ::: TOC :::: */ div.sphinxsidebar h3 { font-family: 'Trebuchet MS', sans-serif; color: white; font-size: 1.4em; font-weight: normal; margin: 0; padding: 0; } div.sphinxsidebar h4 { font-family: 'Trebuchet MS', sans-serif; color: white; font-size: 1.3em; font-weight: normal; margin: 5px 0 0 0; padding: 0; } div.sphinxsidebar p { color: white; } div.sphinxsidebar p.topless { margin: 5px 10px 10px 10px; } div.sphinxsidebar ul { margin: 10px; padding: 0; list-style: none; color: white; } div.sphinxsidebar ul ul, div.sphinxsidebar ul.want-points { margin-left: 20px; list-style: square; } div.sphinxsidebar ul ul { margin-top: 0; margin-bottom: 0; } div.sphinxsidebar a { color: #98dbcc; } div.sphinxsidebar form { margin-top: 10px; } div.sphinxsidebar input { border: 1px solid #98dbcc; font-family: sans-serif; font-size: 1em; } /* :::: MODULE CLOUD :::: */ div.modulecloud { margin: -5px 10px 5px 10px; padding: 10px; line-height: 160%; border: 1px solid #cbe7e5; background-color: #f2fbfd; } div.modulecloud a { padding: 0 5px 0 5px; } /* :::: SEARCH :::: */ ul.search { margin: 10px 0 0 20px; padding: 0; } ul.search li { padding: 5px 0 5px 20px; background-image: url(file.png); background-repeat: no-repeat; background-position: 0 7px; } ul.search li a { font-weight: bold; } ul.search li div.context { color: #888; margin: 2px 0 0 30px; text-align: left; } ul.keywordmatches li.goodmatch a { font-weight: bold; } /* :::: COMMON FORM STYLES :::: */ div.actions { padding: 5px 10px 5px 10px; border-top: 1px solid #cbe7e5; border-bottom: 1px solid #cbe7e5; background-color: #e0f6f4; } form dl { color: #333; } form dt { clear: both; float: left; min-width: 110px; margin-right: 10px; padding-top: 2px; } input#homepage { display: none; } div.error { margin: 5px 20px 0 0; padding: 5px; border: 1px solid #d00; font-weight: bold; } /* :::: INLINE COMMENTS :::: */ div.inlinecomments { position: absolute; right: 20px; } div.inlinecomments a.bubble { display: block; float: right; background-image: url(style/comment.png); background-repeat: no-repeat; width: 25px; height: 25px; text-align: center; padding-top: 3px; font-size: 0.9em; line-height: 14px; font-weight: bold; color: black; } div.inlinecomments a.bubble span { display: none; } div.inlinecomments a.emptybubble { background-image: url(style/nocomment.png); } div.inlinecomments a.bubble:hover { background-image: url(style/hovercomment.png); text-decoration: none; color: #3ca0a4; } div.inlinecomments div.comments { float: right; margin: 25px 5px 0 0; max-width: 50em; min-width: 30em; border: 1px solid #2eabb0; background-color: #f2fbfd; z-index: 150; } div#comments { border: 1px solid #2eabb0; margin-top: 20px; } div#comments div.nocomments { padding: 10px; font-weight: bold; } div.inlinecomments div.comments h3, div#comments h3 { margin: 0; padding: 0; background-color: #2eabb0; color: white; border: none; padding: 3px; } div.inlinecomments div.comments div.actions { padding: 4px; margin: 0; border-top: none; } div#comments div.comment { margin: 10px; border: 1px solid #2eabb0; } div.inlinecomments div.comment h4, div.commentwindow div.comment h4, div#comments div.comment h4 { margin: 10px 0 0 0; background-color: #2eabb0; color: white; border: none; padding: 1px 4px 1px 4px; } div#comments div.comment h4 { margin: 0; } div#comments div.comment h4 a { color: #d5f4f4; } div.inlinecomments div.comment div.text, div.commentwindow div.comment div.text, div#comments div.comment div.text { margin: -5px 0 -5px 0; padding: 0 10px 0 10px; } div.inlinecomments div.comment div.meta, div.commentwindow div.comment div.meta, div#comments div.comment div.meta { text-align: right; padding: 2px 10px 2px 0; font-size: 95%; color: #538893; border-top: 1px solid #cbe7e5; background-color: #e0f6f4; } div.commentwindow { position: absolute; width: 500px; border: 1px solid #cbe7e5; background-color: #f2fbfd; display: none; z-index: 130; } div.commentwindow h3 { margin: 0; background-color: #2eabb0; color: white; border: none; padding: 5px; font-size: 1.5em; cursor: pointer; } div.commentwindow div.actions { margin: 10px -10px 0 -10px; padding: 4px 10px 4px 10px; color: #538893; } div.commentwindow div.actions input { border: 1px solid #2eabb0; background-color: white; color: #135355; cursor: pointer; } div.commentwindow div.form { padding: 0 10px 0 10px; } div.commentwindow div.form input, div.commentwindow div.form textarea { border: 1px solid #3c9ea2; background-color: white; color: black; } div.commentwindow div.error { margin: 10px 5px 10px 5px; background-color: #fbe5dc; display: none; } div.commentwindow div.form textarea { width: 99%; } div.commentwindow div.preview { margin: 10px 0 10px 0; background-color: #70d0d4; padding: 0 1px 1px 25px; } div.commentwindow div.preview h4 { margin: 0 0 -5px -20px; padding: 4px 0 0 4px; color: white; font-size: 1.3em; } div.commentwindow div.preview div.comment { background-color: #f2fbfd; } div.commentwindow div.preview div.comment h4 { margin: 10px 0 0 0!important; padding: 1px 4px 1px 4px!important; font-size: 1.2em; } /* :::: SUGGEST CHANGES :::: */ div#suggest-changes-box input, div#suggest-changes-box textarea { border: 1px solid #ccc; background-color: white; color: black; } div#suggest-changes-box textarea { width: 99%; height: 400px; } /* :::: PREVIEW :::: */ div.preview { background-image: url(style/preview.png); padding: 0 20px 20px 20px; margin-bottom: 30px; } /* :::: INDEX PAGE :::: */ table.contentstable { width: 90%; } table.contentstable p.biglink { line-height: 150%; } a.biglink { font-size: 1.3em; } span.linkdescr { font-style: italic; padding-top: 5px; font-size: 90%; } /* :::: INDEX STYLES :::: */ table.indextable td { text-align: left; vertical-align: top; } table.indextable dl, table.indextable dd { margin-top: 0; margin-bottom: 0; } table.indextable tr.pcap { height: 10px; } table.indextable tr.cap { margin-top: 10px; background-color: #f2f2f2; } img.toggler { margin-right: 3px; margin-top: 3px; cursor: pointer; } form.pfform { margin: 10px 0 20px 0; } /* :::: GLOBAL STYLES :::: */ .docwarning { background-color: #ffe4e4; padding: 10px; margin: 0 -20px 0 -20px; border-bottom: 1px solid #f66; } p.subhead { font-weight: bold; margin-top: 20px; } a { color: #355f7c; text-decoration: none; } a:hover { text-decoration: underline; } div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { font-family: 'Trebuchet MS', sans-serif; background-color: #f2f2f2; font-weight: normal; color: #20435c; border-bottom: 1px solid #ccc; margin: 20px -20px 10px -20px; padding: 3px 0 3px 10px; } div.body h1 { margin-top: 0; font-size: 200%; } div.body h2 { font-size: 160%; } div.body h3 { font-size: 140%; } div.body h4 { font-size: 120%; } div.body h5 { font-size: 110%; } div.body h6 { font-size: 100%; } a.headerlink { color: #c60f0f; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } a.headerlink:hover { background-color: #c60f0f; color: white; } div.body p, div.body dd, div.body li { text-align: justify; line-height: 130%; } div.body p.caption { text-align: inherit; } div.body td { text-align: left; } ul.fakelist { list-style: none; margin: 10px 0 10px 20px; padding: 0; } .field-list ul { padding-left: 1em; } .first { margin-top: 0 !important; } /* "Footnotes" heading */ p.rubric { margin-top: 30px; font-weight: bold; } /* "Topics" */ div.topic { background-color: #eee; border: 1px solid #ccc; padding: 0 7px 0 7px; margin: 10px 0 10px 0; } p.topic-title { font-size: 1.1em; font-weight: bold; margin-top: 10px; } /* Admonitions */ div.admonition { margin-top: 10px; margin-bottom: 10px; padding: 7px; } div.admonition dt { font-weight: bold; } div.admonition dl { margin-bottom: 0; } div.admonition p { display: inline; } div.seealso { background-color: #ffc; border: 1px solid #ff6; } div.warning { background-color: #ffe4e4; border: 1px solid #f66; } div.note { background-color: #eee; border: 1px solid #ccc; } p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; display: inline; } p.admonition-title:after { content: ":"; } div.body p.centered { text-align: center; margin-top: 25px; } table.docutils { border: 0; } table.docutils td, table.docutils th { padding: 1px 8px 1px 0; border-top: 0; border-left: 0; border-right: 0; border-bottom: 1px solid #aaa; } table.field-list td, table.field-list th { border: 0 !important; } table.footnote td, table.footnote th { border: 0 !important; } .field-list ul { margin: 0; padding-left: 1em; } .field-list p { margin: 0; } dl { margin-bottom: 15px; clear: both; } dd p { margin-top: 0px; } dd ul, dd table { margin-bottom: 10px; } dd { margin-top: 3px; margin-bottom: 10px; margin-left: 30px; } .refcount { color: #060; } dt:target, .highlight { background-color: #fbe54e; } dl.glossary dt { font-weight: bold; font-size: 1.1em; } th { text-align: left; padding-right: 5px; } pre { padding: 5px; background-color: #efc; color: #333; border: 1px solid #ac9; border-left: none; border-right: none; overflow: auto; } td.linenos pre { padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } table.highlighttable { margin-left: 0.5em; } table.highlighttable td { padding: 0 0.5em 0 0.5em; } tt { background-color: #ecf0f3; padding: 0 1px 0 1px; font-size: 0.95em; } tt.descname { background-color: transparent; font-weight: bold; font-size: 1.2em; } tt.descclassname { background-color: transparent; } tt.xref, a tt { background-color: transparent; font-weight: bold; } .footnote:target { background-color: #ffa } h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { background-color: transparent; } .optional { font-size: 1.3em; } .versionmodified { font-style: italic; } form.comment { margin: 0; padding: 10px 30px 10px 30px; background-color: #eee; } form.comment h3 { background-color: #326591; color: white; margin: -10px -30px 10px -30px; padding: 5px; font-size: 1.4em; } form.comment input, form.comment textarea { border: 1px solid #ccc; padding: 2px; font-family: sans-serif; font-size: 100%; } form.comment input[type="text"] { width: 240px; } form.comment textarea { width: 100%; height: 200px; margin-bottom: 10px; } .system-message { background-color: #fda; padding: 5px; border: 3px solid red; } /* :::: PRINT :::: */ @media print { div.document, div.documentwrapper, div.bodywrapper { margin: 0; width : 100%; } div.sphinxsidebar, div.related, div.footer, div#comments div.new-comment-box, #top-link { display: none; } } Pylons-1.0.1/pylons/docs/en/_oldstatic/doctraceback.gif0000664000076500000240000007446011645401275023005 0ustar benstaff00000000000000GIF89aP  ,5"4, %'/!.-0 K n*J-v/Q(i15H.5j>y'4MgNZ/I(M5.xu'k;t(/d(UeH1IIICETGSYWGDULVVRIZZZMSl\e^PbuoTJoMjucVhhhefwkskguywhf|fy|ugsss0)N2ck,FYJHSqPtwNsNkyjq^rKVioy '$$$%74!46&%%55$461 81Km2L2l:I?mPH2n c3GM4d9JQPnkSkoRLUohSnre:u[.PGkrQ\uuot\uYrFxđ-ӇWΎrѦJץxYpwxρ㏯΋貕͵⵴ѹ˙ۘرɘ̘ԭùIJ¾Ӳ⟊緑溯°ͶȜɳ͗в!,PX*LpÆJHqŊ/jqǎ ? Irɒ(OLr˖0_ʌIsI ? JѣH*]ʴӧPJJիXjʵׯ`Ê땞;{.hׯ۷pʝKݻx˷߿ LÈ+^̸lj ];="^\y ^q86|9.?{M۸sͻoǒI;v - c1 n>[17IƷH}w}ɝ0&ȱaODpH[~,Y?xw'I' ߄Vhb(%eĖ]x 6@,s'%N. <:BpJ,֖< BD>IL' ' E2$?l:#1'q-/h;ڳL6Ie7q !4>lD 0[9:h" 88u#1gt>{Is >'Yfh뭸rI ıu܈u B C -QZ=G&13G_0~Ls|hH0"Vdo&oO?~cI?Р%<߀.8bP#xxwI0+ +t AD?;+m#("-(bL D0)M<7 N+H#M0-ɜ- R ; s|Đ % 0q9'lz- 7t"V8ti/E71NxBІ&)Aw9cmxA6~,&R"+]!XNj a 0Rn~l၂<`\n6aĀqYJi4r:D\8@Xxpp;FX;p qp'*t\xCa {pG/5 6/%"g>㸀ێHQb]q# G Q (<1 H"I?@G(#TJh@F֥|x#G3QR#-v ^o.bZG  bg#ː8HQv?رIHG6qa/!b9 D!4l p"pZ9 8pkD&!Z9FuQ p, q1ސ9h=ċ4 #@w[Aear v3.pMݒ_Fa\].T>. =wa;ؐop0.;p h 0UۂˠUpl.QD 6b]@ s 3؎t!2uAvX p@P U,MmPp  %kn fd 50 F 69 (w0gpqxP1G"x1 ]L !@_0/ ݱ p ?ۣ3 D @U;:(r9tun[wu 2P/-P7Lp . 6cr!1: 0#p14GMut)~86S~%/6 /qyy}!P ? qZJw : p",-+p-GĐB;HФpQj2 2t < 6n:6/c .K=;` J!@ 9P (@9 *k @ *`wE4_T JP.,'r- >K $)j 3cd5 5;4BU҉t蜀%# 0; H: ?~ @N.2 U# " H[. n@s ~dqtv +@y~~qx)3P{;ȼ9`#^ p@dNە ) `1 )R~TM bʍ c 7na@#޳` M̛Co]LPpn!cp ǯ=E:^~b x pWupL,AD%|4bq-_!&u8Ʀ~=J! ~4WEAFaDzMB/\ &N# !8QD"VG1 PtK<6E5V`9䨴lFI9MLҤW &h,GG#B fXOƫ?9QO=cd=ET-em8#ӨO>}tխ_Ǟ]vݽsogGA;(mK(M(\\:HC ۈxH x𣎗Z`x1]Xpjl>bilꇖ\M.J̖J: (,),H{oxEBL'xds$yFr&*D)AbQ:P z6!ZǖS";HʜjgJ)LchrGP~!ÍG`P~I#g'bEW1&mlao$s6eUlhɡ k|xT`0~bEA$$! ~"Q s=tMX!TCA'{a¶[V@6=Q`ṳXb~qC -HDcly×9ZO8䒚'.gwg+ |ͱ=zEJ~GGwlk{jJPP#}B;dK6q{H  dp;GjflJ&0;ٺ˧uXƂ7#;g~ !Af O~ӟ|)K3;@BP6ԡhD%:QVԢhF5QvԣiHE:RԤ'EiJU T<ܣ1P7iNuSԧ?jP:TըGEjRT6թOjT:UVժWŪPI th0dҰlgEkZպV &*)ꐕwk^ Lt @#(Xs9SuElbKI1=ha;YVֲH_LbM!Y/;ZҖִi,\sTԱı l(%cO/)׸YfjΪ "fSDs"L9+Z׽m+W+"'=HX dj+Îx`^!c$g;a #Wpjs Mx=vXW/ *1 Y8hGzRh @`?H7hܸ#lhBJ#é+x' X@t@2@ wz;dcC ,+x ;!X&"C "f2Q|ȋR!<7RoG8KTFa<[!,]W#0R>5r<Ӌ4 ч=ጧ!JE@RyJr,&ocȺr˵4B,!D' ! ;R8 ic!# m< k!'hmb!ҩ(<[?쉱IK.Ô·)B$\A<R`; .$Hpn ww%a d{6RޙE1%PoD@+z:5Z"S?1-9J @??9:>t8zTA*=[? @$K7#DBA-$(& 4B)- %̙A1$^B&hB"$|@6r<a@>;Ɉ18C=~X@@ DЃ7^@A{-D 6C8 1J9D9FDȃN܎rsCK8`cښ{H?D]_lLHFE=LSaiZ!/,,+'-P5EAAyr,'0G8-hw~~yxÇG0X@MЎ| ~!8GPziV^b87o!M18(Eȇ0@IH,5\rzЂ@ D ԛ86`z)0̑T H,5؆zŒ]86}DXeȄ}pLKxp$3B+45,<Fh󆣴b 20PJ?@8ӇZIC5Xΐ8^ 0C7pp.Mh]Q/1p{8-8Nb8N@zhPzp=)F_Z;r5x=^mE8N5`JNfO$`/@} 4 +:"R6Pi(4;,8(P@/HO} (PcM)``B8P6^908TPo-c~= ,/rp0M4w ,P,_pFX];bhҤ0p?eI*Iyp1G+CQJ~HL3U4PC0lP+~ =.bdP>9g?Zݎ]e@*9lO`XU/Hb/OE@px(hc`dz;h-Ѓ^ i(̤"iV*X9X{OjLhTWه}4|Wu@8ͭB.@XPZLwExLXl]0rfh)X03tHNaTP:A(P~M;HrU>0xr(MT:RJCz@PGvJ8p:<bMљsp>ZNx؇z6l5hk7h5`%2oӇ<3XN;6oM 8`8Є1N9*5`Zo ]=j}V9ݎȃ`P9+Ɖ7es6؄8{bHP1[b9xG9`sZkfT;ń= ^xE|20(l$7В0غ*J)k0P]!M&t'̑P+0D`aJ7ȆAEP| ?r0b~l(Dl)؆]0վt`1/0HȇCa]|\8boxw|X[~νr{UDs ܅:^GZ .|μcg44HaRKDɼԎ .zM`k'v.݇D2~R\ro(]~@PFf@k0*7~XpȂ%_T%%O4~cSO@m(/Fކ} Asaf+-pTTҴ?Ax*843@Qb+C)(9(Yrp)DLx8^x5@<0DSNph8PeQ*q09քqQ3d,PnCքf@(=-ЁĎ.`ViO8,HNKj8hxj)r+ㅒ2Ƣ307.;4m餂Ql`,p~؅;3-{@)P)尾5u|ގFEc5 0.4XlظVh'HA&'h+,^N6T+hRy=ʎhRh¿H5]2AzL}yx_pr ].oppXyn(vyqyt38ozxo{+yp|@^`j],phpL4HUwqyqrcA'D qh!{8)wsqʡ /y8$-}s*ryl(*Av'9zȆ~8Bޙxoz?uw X27s[4M5L0Lx=88Q΄8Xvh7vF]Mi78LP/no7=,^=0s'!b?d_o0evr[$&q_xGwu3w?vx8({)lT~0iGdIRKvd)p}w|yc2owcgƊ׋a@G=/9rZzZ(v?ZȄMz?L PRU]7qyg{??z腵L{Z{?PPz/{{?{e 쨇ŧ=|`4|ͯ Io|N/=p̟{}w̷Gt'{w|F+nPGҡ~!o~xt~׋$!KVJ2^'~~,h „ 2l!Ĉ'Rh"ƌ7r3#QC7FҬi&Μ:w'РB9 c.xtej*֬Zr+؆ v,Ө1 -ܸrҭkaQ8+iKިz0Ċ3n wH(U>}I`L68Q$ ptC^`c,FEo PaFwK|㆑kF179$ \٠6!B]CP0qd&?=S{9q!&Fϥ~O/{vC0>LP=*"l!n1BSb P-9lC "Yxҏ"d'qNHȚ"YF6E `"_D2ԮC9{obLSk&=f&72(y3(,O=phʅ .0K{ cKNkۉð S:Y_]>%aAUށm&ݠqG0ZHٜ"`'j\A2R#]Fd2WFA_t`C@:su!ZaC0Њ~"7MTPý 3 !T&eCp`L!U#`A&vA b4h@Pxzp%2\AG9Na !!`5xOUzx{p!iP1 )$R< }30'Aʛ)AKKԒLoP!8! ecjF#/ppƕ$:"L1duހ Ex0 0 7DF/.UbEѢG,c a3  2qR|wh`?Zd ҢrkA vAFE]پcp(DNdz!soc]Qu";PpT˸ns6sC? )0b F4,<-D!zQVX(XFpҨY Id/]f"xఇ Y2+\Az8ǐ0i0" QB7!r!Sg0A61e5BȚ$b .fdj[52Ð0V#qQ>4 t QB,+LA l?nLs P9ΫEYϭPẃ ?9M !3F(d!DTI-ྊH5ؑWә65("!D4 ۶_xsސ C|GpYO":~x#p#ñ#JoX&GؖDJؑKAM&(B&J̸ ACDfD`F`&,@F -`J!xB fXA17d҂ fB&)DUDh`兠fCC !-B`ÕHUnS -l_Ax~ Dq?fBH`J9 A|``@1 JF J.@!)z!BR^тɝ8_xTU5 "BN`c&1fB<6D=9śFH6nD,1:#6b{y:fB72cLC&:2#9/ G;1A6##4bE8?^ 7 !pT6 aQ$!FQ YaDqSJN΋(%BS&MG FUZ%rVVȘPieG^\O#W:__%`]FHVO &c6c>&dFfbY<]bԇdn&gvg~&`Fd&jj&k]]zI^ff0m&nnΑR%&o.nq'r2kepU9bGpR>9 u2D/hM.1 >N/dL -\!CaB, / փ"lεCbBdeA%-(C!UD9PgCLg.ڕI*:7l€J&(@2$hr^&O:iG~tD>0B=ģ@6DP>WC A4.. I#D41Dn%A,ɅZMD)z!@Ta("h-e2-XBCR-DB䃗׈A6 1A~(D,gFE/M~~J/hՈsC'L(A >@&C4).`MJ =C;o<ц9C|6 BCC\R.lF>< L1Q6`.PKfy@Anxe0D`%ƯALCF ]-. _"$!t-T>šUT/\9+7!n-m*eEsGTULB!܁(; ඊ(k?T%1D/PACN H1o975C8 "?[@ 317l lG9 5h ȁt&&*>4CqI7h'(ECF9|B-#dB3HEӯB m<,9<$|2:qQDA xơ2#AC0x"A+y1HAA0 @!B7O1}h(OE#Htt3C]$X ; 'M4]$<(5fB=CJ—&XTByB1P=15%JC!d $B(|I#xVlaC 5D<9l)T5kii!D8*&A(Ts6gB0H4A%*dPR0,Cd̨EMB>42x-TCݮ˼C7?L(pB Ã<6|;q1` 3B @kT6A |XYF{BsB5-y`Î?)ŭC,’AM*(!ѤtPX\<HXi@ٙÏ]X)<PğC@P99H`I=N!|A&|Iɹ,@ǙN6PeAeAHAɩ(]s\.j | ^ԀVW2X->AdA⩧z/Y6+#xAI?8o" =8C9o/Ђ1B470BW=*3g/Cџ>ݿ;.8?C .t -_99,CA/-X>->,/9|8BJ.,҅k!Һ4@-|ͤ)l|<8=<.D=s|:фɯtB<3TCpC(y=ͩC <^D8sN8#}-͛a@]~3A(/e+h-?s\"~A0,@¥V~&T؏X/.p_?~j .bGedD^L8TG! =Ȗ$f^ءuTNbB7g& !mɅG*iN: ޽X`/ɜ1q,9}GaNfJ_rY!&rLAHܴ4&P.q"6(*;a#Kt%!^bk[@rNx驯/b$JkXBhb"ypۅ ܃NOnc[Z*^!hPchnJBg xd |Lz3 Q'EkJ,K̰e !WV.T;CЀ lAJA3%/Hp(,nu`e F0_@q Bm55%tgVIL!Id|`2+%K@;D%\cGPD5 h!FDsoL" z]g@/tEPHq HpBx'jNYN=p?*7Vi{vEzdˆ/l_@}>DDPX4hF%P'f 5@<1adA Q@ZA!J W9Xa #7@VGB!6&l[h"לcTG+yIpj A&nRkJʡdDZj@\+`h "s !Gqb+4yp 4&KVår6`#8!DPa25&B4XA3VYD  ޠB! N"!b% b%A "4 .b a @!! 0@ z@ M֠./z! 8-ġ#  @ q Z p8@3x @ B`n  kaV#@ $0vA a vx tapܠaӈP@ BA @ Vi A9a #DlǸ^L : ́ ZACAbo՞AlaA2a 44Jиo!!( `@  a no!x&D 2aƆl 1@_\`f, ݬ  @ A l! [ M+Q ` 0ͨ@n~@!' @ peAv 8pa p!ti rA  @%vkK{1aRpEztA̼!@NWD WA h!P!ob R2AXmln]liA Mt@!ʡ@,\c?"fH >& !@ σ b܀ W܀u'yL}/z @l5 rB t&)aASA>mf `ƈ@4! 6!p  -rx%z3`II-"/ yA% u@#c/ -%v!!B] &x! D0ΰ a!u1 ` rhVRQ+[*͐/` U ؎͐9=ӌQ @lKv&y1 C]Օ;Y Σ=!~6p"X[O"YȲvd" h8EQ!%:H#:2a< ='"ޮ;"):cd" /&bZQ@;'ڣ$:†:=&:$C;;⩈$ƣ+:LZ>FT+JԑNԴt 8qMN@  ?:aU ;`2P!pa-$˭΍INADUWqJQ{u:tx?tKPP +lzuD@T븝i |;zDEj{[OϪٻ}EI+ݻ;K{۞<<| <|!<%|)-1<5|9=A<:j x+]a~!>%~)-1>5~9=A>E~IMQ ^[#(!8isDI.+b~m灞DpjIBz^~~>! zCƢw#^~W$adkCK9A>>$U~;B;"#{> #־_A!?a?Q 幾Ba:!iG_]kj_x@????ɿ?_ao?Zr#A^?,`?h9LĈ'ZHÍ;z2ȑ$K<2ʕ,[| 3̙4kڼ3v\x$:{#i^L:} 5T(qT:5֭LAQرd˚=6ڵl۶m'PD +޽Pyp70ԤO96Ō;~ 9rc.n=6߂# ȏKݘ)|&];ݼ{A3E]fp@,y`Q!YE][spb ?>U<=' #r CakN #S_6ވc:qtc^),(ʀK,3$4-H`Ce9THvb;NJi^eQ!7ȃ>dX0 r  0: lM9$<?#OS3Jio4 qYS*09'hÅ401$E3 ,L ů$g]L-0O='LA ;DJ9C,?"לs$NuZo|s S4+HCe#O!ʜ@FݼB 3(hwNYx)(s0f0s,l&ڽWs {[$RCvp͛O@'7 4GlJK{Ϊɋ߾_.CBO DB{4 By4Ne}O 0!VM0p,zA+$E da<@(] ,Y30 \ @tdc, F[R\$*qLL n69K JT#'q@ հ\p'E6 Q/z]G!Ol" *'A6O`V;Є4 @x՚P2^OQ5@aR cJ :A5=@"0 x8 P5ށ0dD)6L :ecw:!? ``;PmCǕG';lcg444:ʜƧ\g|@ib'fZeZw' 5  @g` zZ>F s@c@s@nP sp  0_` - T@` _ m$TpPn@u`d`~kxD ?pN B'kȆm(_^0T#)(p z8>]IT @ E p0Z@P"Um ``d i@Y@@R0j `A dd uvR_ Yk` x i #0 I@ CL P > ["6yb)?q' f0`)p f!]a ` Ȱ @ Ƞܐ p@| @ `݀ `C ҀD5dy p  Ae` 0 ? AYpH qZ:Z5^}Ɣ%^ܘ[5  $~ QAOR *kyj9qP ` 2{s ppK {0' ˠ iJ pP } y ݚ  ` PP Π op @ ~p!{ P@ 1I ۰;DPr#qƲ+0 6 0oQ$]^0 PT`wCqwۧ` ov\dP0OwpĀs~ @{0}Zhd@"bSSG T 0P\Y0 VR`0lW\P 0j` d0vxV6:˳k?[J$q%:$#<th@Hn k3 0hp0l 9K@a j`@0 uPg0 %1qup P#` ` qӐb P" }{PpFְqr| 0 s P~ ȫM !HFiPFcSFo཈q[H "0}Kpj;wP[ n pw"b K 0k X p!y, `Pb~0  %+~ö$LJ+&q<< $bp qЋgp[P3P` m΂ k&&`1 SƘ P~ g {#,kϥPmp``t"phn@pY@[0ЙpxsPq l) & ź@ ~pǴ!o 0qp qnPԶ g}pmMn *{ qpFzĚ j  P n֚`G 9¬z$""aL )rA"Pp̺o  ax  ߳Ľqb[- 1[N-Rt A@X.~í)O] N%>Jn)c+/;}0N5^#"ޫ6;~㳹r3A.CnG2K䏁JQ.fSnWE[1]aD̫P.gJmZq_.uOny~U}p.t.腾xnn| uuY)`Nb"`{b} =Y @E V@ p .YJ̠J`$ ٞ8 0J"` J0 =@ΐ +`ސ̀ːN[&0/A P! `sp wpPZ>+.خM'ݮ3G8 =@eP`PPP@c >k6  0 J&P"P 3P@ n` ξw_9c>,Y#= !҈8 >˰P >'q0 T$`F`lPPC0:p ? +֐w /P .p \ )鯔$qȠ@ @@5A` = c* -dp؟?-L4 _?*P2(#ɾ~ˌ !(%Ưx m8Ő_(V P àP WaŎ%[Yiծe[qΥ[nv\x$:{_+ w T3>0Eor\13_eIsTPFx]Й*01q! ILPWB }9d"1 @;C&(\"  2׫~5{ϧ_}m`o߿3J/x8B %!LF>4%qŞ~)đB YG)|YEY #H~d"d$ C#Ȇo$%#EMHTg SoL24L4TsMrᆾc}Gω+~|'@}j()'&pDK4:-S[;4;CuTRK5T?L,cǞXeuYeEu(os-u|v5XdUv2^ vЩZj[mEYpw\r5Y u]xw^zrNQ z_MUY]WځVxavgt·+b3&?lWcCyd79-ye[v՝`9[_gZ(bȆ!rvpb'BpH+[V@"j)$J *hc$zpDaj*"HF,}rĴ~n |"d'Uɇ^!P72}ndhI|@aelkgK6xO7eŭ'`sv$g$ ),bAchJ&x艜ch%APA&98g:ސT  T\< LL$9@ 0r0!,wBV,fVu0!pG!4 `LQ \?+4 }lʐF>e0)  9f #x9)D@ E1 qrQXsҋxJ!/$俆v0k$` A Dл >YF,Րz Ͱ) ,D!9$4C {, Jy% xcEX#^ :#$QS,D<2@@*{H CʁBS 57rc N |E96H2 (MO 2`|B= Dg8A&Bx,, e%\,xEw+ B?ц( : #[d 8zq)O_tJ$!9 jP|<$A&Õ @5(**.*1rNi.=P`JD vPKl0\`X4+1 n@*RM{]hs"UiP`3KdGA+{Q?ܢV]!g`z.j]Z񀹴} =|VQn}I]LV#/6y8H}]WhzRU&_WR-"_8Tm |` o`E̋p-|ap!Lࢅ qM|bX+fq]lpX1Llc;[1tz r|d$'YKfrl!I~" aAGC!\+c&sY&2Sfsݜdal[-La$p+Ld`ya :آ[.0h"(s- ,C~s= =00Е1!ft x\ ]ZNrt?\C?ёv3; ѷ~{9r^8 ߐP`|xG^|z`|=x𣗯қB?Yz؟ }m}L_q}mB_/T˜~___}'gV~__ @@,@<@L@\@l\0 @0 @ @ @@ AA,AOӣ ]ݑ"ň SM?83E,%?51g[ gCw ϯj~て xvץiC evNg_PraySQoKM-GףյVZZ/%E͵- P,mӜdj.rtUn>pݵ][R#@@@@@@' ֿucN cά%sQm݂&1ؠχOupw_dCӿ>} gR[} -pM+~!I4Cޘ9@vDGeoKzh, 4Tue݃4 IT\b˜_(#VP(URb9$,"'Im9_/n)44 Ց}aY.C%%]yWM~បW[l iZJL2qCڦpXQa8upO֧΄.WwD/J|w/G˕hc>Ke)m_Rێ{'m mllU|g9sݽЀ:uWb[w,\iYb^;g9sv3H\~ML)wWYWs\7̊hw?Q\f;idGbxnJu1S=]^ t MbXP*B}6!':9HϿ|̈ms5ͶB!4R[sJ_:ՆBSPA 2MxSS&D|šͲ t Xg~ kCh_'㷏t$>F\_xnù\LJ2[qsVWJZemRAM[]=Њs9X{˂H>MI@6N7DSVu|U D־ E*I͍zID3a1B\VXPDs$G-jklL gSgpŌjds84ait f 4ߏXZC!IE%ueߕ}ea}ǜY}S#+$Qgf(B\}e" /Z< 2^њƝC ȊQ+HzN55b6T}oJoy\W;a"lM}"33?IG03s202U%x ,ָH\a^dOcۅ Sg~:ܐߴ熦եfHD$ Oa^8P#/㚳=ђLHҚ[M1crLT--%DO_\k^CQ+o#Vr\+G鈦TG*˸bd QVfpgfojJ̩(CS4;kS{'>&"͏LVLT4;9kP5gn 3n/牰Mg)q}^-L`XeJyMV]Z1 3bto%kƈ0q$3LTG3m-MEUIjb5""Js΄pHd]ΠVP\aL1D!Nf%RM9݂8 {bbj 9z%ݒ7u3 6fCv}nH0N[7feMNM|0GT7Wپ^Zim{MZ1"҂LP ?rGь`ęmSW,ވfͺ/*V X#nhmǚH!z!%A RLL~\+&G`6Ch#٭vv HqUR5ggU˳BkF@jͰ&dC&Y5_D[cC\lM;2HY]̼2s{!ZWw羖k4bv1e}ڥ_+,]cڃ Afw$TcmXX@E^ Ɓ~ GΙqF=Sn߲_/VҜMPQCEl>Dv8QĵW\,ONMttqDm׬7 >^#O4UqVà}G q?Fys_m p݉y'E6I7-'PW"uTc&>_[PBn|ǁX0l\qïzp) (痭'Dy*&?(=dr7n " N4fm#.Q7`F] `Z#DY):QR.k"I׿^6P11<=YE1`.w@a>4c 1~ в&XXt.p7./86_f1id@fk?֕߯Հ0n5NԀ"8ZZt$MlMZsaєi8'Jk\7#|)A'nl=bfK[͚QLtǰf1TfAlK]A0nW6zka5k/ :<*hU_0AێSjmףnc&FXvS~ ?Gl]u凛:e1R}qgP{Ư'h~??6%Us\|Dc0P qڣM?_=˭Q @^/Y[ƥeF Y(1fi3 c.caH Zd_.w8LԕA5We[2vg ?][~=o@,ұ A f!ɬւI㿈[8hʲ@Iÿϼ:iX ˈgj9N€5p֝S] ԀMA"?: +K;YrΔգũZ@u ~CCu- () ӷ@_0}91%M61r&A~?/=10SJ3bLHx@+[6aHG_;zm"mc=+`Ȗ-JC*Cna~ż{G;ߐ)D[N^|ڴ3w-5q NّT瞵S5fOwCIVR%dnl@_mÀ4,,R=hAl˔`,=-5{9}"JP vEZ=M$̰l #bz4nչf>&KrMGgYNRci~?ݢU}հ+a,GDUy$++ދuԒM(OPic;a4A'>}m%Æѱ Yce☃ PQM!dâC YcYO8dTFZ jr9 )56JT{JLʌ Ìך{n E=y[Z? WE9։{'>9hBF\)-Hks;JBҴՏr5jQn^\2CR7ºMej77W+Pkt=dQyؐoyᔕhY/g)Mzv?PX!`vg U )} 5) Ԣ֢{bFaM1崥[rwj~XV(jЂh<;֪37rfiq;Fht,aD%w.ge6Nыa؎DZq;lǕ;b6~XYrnL/u7mo eYE=i-fW[ [>q 1gWWxR+x`82*EWY^Ns:KW`a^~ݲꤏ{'aLsmX&{|9>]:ZUWg7,NWx;;q,:V7f5FE4 {9 =ʳ/ZZ٢U ayv^ǥ!=u OZxƸІf ,a -5gDzFFmZ|BjD)H O?rrr6n܈JY1M:4Fǵ+:|ydg<ӘZr/e2YV:rkBO=nƋ `m?{$>\En@an<xOt?gͪBZܜ[c{Zzpt5+ÿŰ^IPF VݫzCd0^ndJ"fNt1 j,u߬ZpTSX1aϬng쟾.Ո޴ll8DQcTGK)7Vr< p 9p']:UyRБ Tdۦܲ?zil%T Jr }&ڥ֒; #v#hp s=YׅH{^.NnGpni} V O\ 5~>xu}[ss19oLzv8 :[SBqԔT0 ^;O_y:L~s&vd+:yY*DYUV^xd;%f0䱆2å1]%K˳@/l~=ƴ58 r(ˈ`u]"moB%sW64~_ftZQrBD \7"@)Ѩ|;>JaL6bFu5mnˌ Wx h^Fdx5wc{nbQl9`CwHZs_9"r|Fl*<)ɭ*f;mI֩[h6jI9 4sXSrlT>QwXkwXd1K&{TH(V_-y\RH:NԖd fxuU/)t~&t<=3$R%|OR+R ŏrkS8~fTeYҫbؑlƕ_=SYh )]fu4 0>B5ˌz@֘w>R$gy+o*4*R/\Ц~\0!;@>"TU }gN@GLi/-rN8y}9~_q.^\s\u1g;Ǐ'D4'uύνPYNM[AŰw#.N9] cKN*ʠoݷGXs礇Mos8+9~M" N;+r6Z1/?"#hrOX KwqgfY}ս:~ڦ-wX66+.1ߴ\=NeL0"@_7™@ ˖€(kZp63nˋ inhS kܒ}0Ty/g|ʍM{ZH"hgLJ[3Y6'6<8yKkż5/;|ç,!v0?ta$&!|ͅ[Prts66DEJu F,`cŧMyQAJO87fYuX.) kev6áP*9;7BfDėd^wc1u3MY쥹+P;aKj\%&aŢ'oɉsn}sN@x׆-jo34قkܬLׇn(*sk„75j'SF|f[o_ 6̹P)8:B9WWl+(?51zs_vL#5D Eѹmec<g|-O4*9K:8)G,+NNO:TV^jiVۤ<W?IJ Zyf%J[RK :J0ܝ.}4IUF9oy0wc dK9>U@ITʼ_ꚬqzJIZR}S60FW]ty2J"tÍgۻ~ 05sZQl-IڱI$HܸIjDCrK,1:;J[%O@tKɐcJ5vP!)_ڌk'^cGY$TaIKqqsEQO`!GRwePD1mUܢa\I(}`b[fvD[>3> hu9{[p^ YN޿"kg 'ԁ_Q Iߚ/Y]E @v'SZQ=M1IaH|E( UeW.,qԸCۭZ>‘h%yx0=`GqN 2]{e{Ir B;V7W?ɯtlN]p!ٓ@Nq5n\:Uf'RoUQtɡBJJcõb cPɨ1yx`qǥqD?X֎Ce`[9vYQR[/~ƛ>-܇_PuSOF;}ƏGTs|V&nP-u#;Z+l\ uC)k㒊F 1Ǝq$rw.@tEvt!JW_gl5%&4s"yQ%i'\7k*/7x~5m; Ɲ'Ph K LJroGLJ~|pZ' (yʺԪ*BԵC\Gx$ Hx’a&o 1R3p;CWI$OtF"dѓm@!.Z i[aR؎]@@~Ύv{yuw|}=GPn-Rm7lVW)rb, ѕ]5`gtT@5#{0nT\082ZԌ4r䶵U% |41r/gdO;riblpft"P77H0`X̢PF$\F9cp8@>TZ[q⪆x;֘ҢuyD^Q c0D,D)Uz;?ISx'oXօ <>IZAvm^Qq4I~r#H4T3C3!&F `D: MBFnkqՃ::b @.a)x" 1,"G, HqVU$`LbP06-E;u݋3u=E+pD24"ond3ݐiߋ-K[\E(0 s-[xu1ͼѴdaaC`aV p#zeiscA~=k~gNѴil&LgU<«b  t6Ѱ̦↲iŀG5"q\| Xc;l%^L ϒ>?҈zF s6Ml-Il;ڊJ60ߜ)&ta`s@u_<ɎFugK:-uB[G݄)L2O$7s8|7&D4?MR [+:v{ 4uO;xˡWo߄Ղ|d' kgB:k $+~ gXX,F$ /<[;x] EjT/!eC=9]ܨ3lIayNjs;ν&ND G:Nx:A,ɋeCdz]mXH4z<7h8M\vF,Ow|GEak5ᣖp*🟽.\ٳJ@x$B=yaTT}X 'D:Hɡ Ox~uAWC&AMAH5| b!qͻrvLz![ K$3MyWdp. 6F6u :=y[lWcI5R0;_LbKA mA:@2a4 O^=>ǨMjJo~`4,Ss2N)m@, oy\*4lߑ?BOOϣG.Z蟘ʴg_N["7w?+KxEc&h}uAHoG~#et3b'. qUӗ:U#.rv46Sgۜ|55s:y1L}'Nܵ!`zuݓ+׷6*_X6n|<^ 0VRaSDDC7:˄13LÀYQqwvp.:2vI eSC=ې##T]2Vҳ˓u#9]YWPQo08Ɇ)y1NFmYgg=9ajdq~/E @),8Է[|Űsvd ?$A`B@@@@@@2H*2H*2֫u0 :h uN_Uint;z3FO:]_hzHtw>1#oה|;rg(SY+ǑE#kEH J)(l3R 3weY󋏄7/F'Ayo"^eXm\ zO]\^R"_)M}Aٕڔ;W߃\-R !/~N񗳹$Ȍ J(T)=EDkݹ׌wΏE`ts7ݯ|O ۶#;=O{!Ѩ'xs({U4ufwU[?޾~߱jޓ#{RԞُ?QJ&^ZS'C46D9mnQ,*OL{Pkvlo;Q{´{]/2H$Euy{o$()9oG 蚢KEli7Ս+^q4:⨜CZ+|#ߔgV(#oDA`l=&SsyQw~|)E/:zWѥHf$ӵc)@ˣn>^D܌°FOY2`Ŭk!X'g-BO6/|򸑠+V /rˆQ諎UF ePNy^l+G_?3灡jF\RV BgJHd N|֢_WU9=SV[{c݂6 mm~s݇O"ov+BpPlEDL :URRr,5!A!ӱ8C ',_Q/#y}"%/:!R܆Ў24tUQ HtVALف>7=:q:>#bxLaU-4TtSưKz}K_imGoY¢mRn\S_$MIÏ5Q'Y Rl|mc&, JlR_ ~Ņtek"`q k*hZVmlndNw>'~*M,ύ}hE5ʘIFzrAGj)hBqSCAõ#F{ȎuL~0gnj~@Ӽn^MC1?Ru;s@ )AxHa~Է0ZҞk"-u7ZЀ]\&]<=mSy^D` 3㪚\ D|>ng6j5Cg?7c1| /2׉pO/scZPk:h/kxiM|CVl0kSL:wN$&mU Skwx2}[O28 6t ig͒W ^oU\C)Ǣugb2{D sA vCNNvW4E'A.lOC)zJ0gkLX)Ӵm2kms# hogW=~ʢJ/F, _,ZYm<eJ{De8M7o(֖N&X+aTX 6ۅo^ޣn/Hܺ\F2X-/mr Eumc:zWI 7 Xػ( Sw+$@APRTD@B"vQP&EHB {6e7| %@PP{?M63gΜyDsLS֚4o?ѵDv$*;#6=Yʥ##ܿ?9Li@4r~剨.D2s<nnۘ9ḏy-[Y_&_6Ϊ*D#G:ɬ[4]ixpIAѕ%X/K㯭jE\q|76FEv}#ӕQN rUT[{@x/[O]%F-1vJש8%skŢ(GqqȾC"]ka,g#.Egу{/cA~Z[۹(kE,3qהdJۇID9MgJUs*h$z:"u͖^!tZz{ +4A7 \<7׷Eb$ Iǯ\B^#b{__zeً}IplO~qxa:\6:.qbNm[Ƕ#w1'b@#* qѾ]9咠cgPjgo3dH}S3 C#l2(K.̙h-u=5(LHG翉?jn;G/^^{lǹs6d904ȽZAOD9{{R3Ξ{C! :j(E^3<ؔ&.5(ž?vb*.) *ȻSr`O:/77O 4iXLT\~r0}HU7fDym {.~[-e9MGXܱ:N!j.%e#}Fnڻ{K~lk?W5e ]{#=1]u@>ss;&ݭ1<};=voс9֞2L._;ǁsN8=%s \m=~c f;ZQ}uɒl Ly$M\{P2a֫& c%"p _.>Ѥ=#\80OuTe~.eYKΖڄzSI7s+S눖F0H.p4^FKҴkmAz>r:Νݘ6v&MT8UWvdsEkc=/kWr|j 1W(kwu?; )hKh̾u&m97s^~Y_NWޘdcfGҿ8o$Tn0Ԍ¹S?v!.[f!P$فAľRJ,")re|91gžMؐzc 7ͺCCL镼p Ňwhu~j[y-B%{لע&=M'z%e@c#3{M,~ǯ+iKϽ=9>;);K3RW|:cXNG 갴F\B.f.Acg|LQ9N66U9hTKmT7N]G4z3v(D+VG۴︞C:1֦?8+["i[,vu:Fbfm#Bw| }5 K2߳jI`7nRv{}լFK>hĜ +f_W zzo7)vWM;>7=Ou0 YǎM۸F.-{vo{#Y^YuhćW93'uvmκ*w!O'kR%kxH“7fH\o׶~1#2m];JL:0Zi7$1czNNod؁TAv.zEg[.@(nn̷ܺŚ_+4cJw|a`ܺHs' v[=]h-vBL:CqE(ѷOc!zT\N<^yf)襌sN$S y]1-ҫLX510*#:>-$GFƫ&^.K2cy\Qb`.] |q^N֮+СofD+~LEv.tkצHo42cYǾ&?¤LOQr mDW~c[Kcܩ`^q|pcoisƆzn;Y:`ٽT+]YtXƂ e]ZᇵTxղ {8hC_"_fD}gu[I7j ĥRs37`035EN6_xZn>g}ԃanAT&aޞA&oLtC慅eUWLQ,ui LzkŻ~t9_x1n۵>9]o䕔CF-yw oCU(5:f͑}gY΅_ϺVqS3a>{.aΝ >9b,ʨPI|7Ka ҲzaVu&_.RsZ>mʀ3pUT~șٹ\p] 㸱bAy62RpBc$+68Y_} 2Ay~%.O[+.[o-S{٧L2):}P;Twp9'WjF#zzFK? KOjվNooU؆`$OeC9#:@}ξ=i/*]O% z3wYqmҊ_[ũww%0nV;0%a^[㕟my]=x[}DWNU_N⨽Æ}pO2*q '?* mmE)nsxEY|8 G_rv\n⍿oNטsZNiPtq/8oץueW>PYRo9n{/|cţ?/kJQ]k|tASc,#Ɗw;uC]U{v=W,e ҝK&{{"_oű؝yĘ.vҩBq׼g;XnIЎw;ki gW$W'q0tΣCb'ϸwYQGOu1o¾.rݧ4t?əS{Oe(]O.+x3cه'% UӨ}?5SCDEG_)7+ǧv}]Uiu~V٤!nxff/hw9ϾXxHv#[9Q}N8|LʴdwG"nvE!g nd[xVy;d}ʄ$ʎ:8ULXnUgwxp@XD2Sxm֮:1=>vh Lɤw8Szq]g9A-S/;Lrmq/0uɡ|SV\c!"]a/shq=PuZ-ɟ'16|?p"f'c_֞E!_/N'qg͊k+f}]O" m{6uKi.?Ķ]cOU}Ϋߌosr(#Wou[Mve4d #Ww} NoW*ycp]u-'[}W⎎'n:OX;XSI|.Xg=q鯮^x~G֕e&N6fǓRٕQcw(EZ=C8xJ)SwB)ӛ~!mmIVYj.)yzmp({lV^McmNM7Ԕ ڸFE'u7 .ZFC楪ݩs!=T]MlBrF)˯J[LF$<ƖLI3uiJVͩk.U襾mPkiVWqS IJ4=ʧ:].M7pgws C5V,6d]}ϫ}[1 ׷vсx,G;QXWTfqU,έo|Ebbu$\y vХip lC+؊q_YFsWgeڡ#68-di3 ];#.~.Ѝ;G#Km}DmGM\x_u͋wfwd;9{)NH~kDpOې`[3iT]C幕Ḏt}(8mݰ1=^x_g2(O/̬㴨%g~߈2,d '{_ gﯪ؆xF=(C:t[VmZ\Ү-`Ouq(yƻWU#yG }ljq3jD:j/κVޢ1sǝ=A48k-UE3x\ySJbwkZ0RP׿b{Ùw2vCH]ڙ]^P " vFVȳ&ȥO1FU銖~eP{oCt5=~>b:¨^O}#&RG'~ѐg>x2I | beQ D@I_S[꫕ CӔyzU]]O MeU|)m}ZkQ+%xp7HZrw1kcj[4Jt._TwPjqXWYQV/gy7i*s/(41oE 4е-^}ې m)Mܺ\ͭYo0`!,ZXǹw:/[7gZl1Sԭrv?E[3ܓh27w7iO0ԼhMKw31D>kʮ:Oł_+l}W^)ڿqf?8A-Ŧ׻c6Njν75; Hk^?#hܿȪNt^Hz^¶Q߶= Szfٕh`EmHy8w;[/?!K4* Yӛ,?H󚺩]tM?T<+ ϣCMPӉQC+.bמr`"hK]$TMAZc޲+?Lu@rFN-";+3NB1Ypk>-J$pB޷"az3Op:8`iyN%Bo0CS5'OUs>f>gF8^"xO;cI{}ma.7d#ڏŝg6f$ 9/bh5 t#wӌHuޕsqF5MP@1fMz$sw\ 庄v ol~\f1zereN2Ҕ[qDvy׺sh(b:WWIm,o%FIpWs5yNqQIxj^c{oyLB /@CjRϩ jWaJH޽_Lp1CGy̞w^D.{h$$yrÜM^JɮL qQd_P^3`޾:xқ$!‰zwEq]~p|Fa܂^Qԩжb~?7"_wbפTkPYz]):h)FTE}2{egA:o a0^Uo֛FSdb[0j)۷(=qdرۂecV-l;s"3MR7WZ1iʊ)3_V=lvɇ<>t#PX)_oi+:I_WflP!2ueo/5^o`l0Kt-e++tPz˩UXu!Ef.NKv$Ru$_ N0S_wKU*OL7Bp5;EO%*; hj,b2ik4Tf]_Qsbke>"QCV;p>\6yW𨪢l~ye ۼs~=po/ȥVmNb*^sꋣ{y: ΩcOz^~tmgY?}(W?r ]yǢ\e@G/2loKrЙC6A>+ c6z䘠/.^v4-\Kת ?ua;<^܀J~`NyOL_g²Fv}r}bP+R~~{Be(1N{gm.̞Q Yb%6Vf!ks>Y[4/FCo>c̨c6< /7GƦMZ? 0(B,b4c30G(*eg#pʌs\66VUSW(qʠ,)D)22D=p1Wpt҆|c1,zQGyL<c$j;ڡfq0@Q [i,^m"%bJhAca?dP8W4' JSUa'Y{Uzʨ7L;K)s.k\ֹ;_r͍5!F!qz1Gf`n)t%Pk4蔍j/lzbO>ۘmó2g928BG;2y's%/Io%tpY'(s2Q~sE .澗1Cp\y󒈚O~[S"qq[~iMwJnE#&up@?9F9B"~7WeqYçy)%;M %?/Sj l6^)Tcխʻyc7 Dy'9_Byߺ7ҩôň"3C۶a(9oFEnap &p\D2eQ D*mּ<uahcqEa2MU*4oR*uϠ( 2xG1?NƄO3WHwO Aߜ[kZCB9H|q5厉~oNvMĨ,(#Yo.NIlyֱ/.Sq}v"mT\Td!v(L.eP`gTW:oS5d\.(E}EjHӪJtsj[+WC%''/[ Amt%+ys&,btrG_T)lwIs(!6VaHobԟZb:d@6wSږ_CǴ޸'9 rdO}/1Zw8 ሦ՗wl#&xXh,9qʚ{.Vx YmgߦzⰢgGP|C|z{etԵY?U֋M/&'޷]zzWvf~}BEOFƋa6ܪQ~vt`ֽWdA(E2cAN|-tP/6~kԠ)ICl;3Ikf$]uܺ-o옴{s*_S~ti/\8b5K0uO}X+c ?ct'}~^p.oe/~:O֠R6Quejg>įX#3rZDY*AʏoKڣv2YytBjb+/+~i;ʂ7O$ci8:6.h4'܍S;G ݺ/~2i=0acI`c$O9;g #|n8__am9y ^@Lb\>f\ $5btb.sdDć[ n=K=b +RUx;Fei Q/2 sKӧO߶m^xPAx\[n}מi(2e D24h˓*gdjWC en~ Rk~3d}o{(@%2t"E_ +JG Ң2Q&qGFD'ǰ&Ne.SjL& DWFρ @QTZA`)B>WظBr9f&v!!!fǎ-PTT1cDGE&āAo4ZP + ]"ݍ:E66aÆmݺu߾}s΅F?qSN:ޫKd#1ق\Q⒴)#MpFpp1f\>o~B, ;7T_WvE wƾܹs^^^~~uuuF5a ~cr_!#rl^[:ab$AM(:Mpk]<'9Ds9m-H./ԙϷd6QFc=8xzeجJFa3 !q * y:.ה׀@WEٛjy{]yw q˒ *a[L?LU̒O ,?(c 6ʰ!!!gϞ-++o.ѥKjFЈλ׎M6hu߾q8.ЙWxu$S֚M7bS긃FMp`9wɿ}U~Z ĞHp2gПKR,?Xd6ւ99899%'')(f[LBY0 J͔Οw/}c߾]M{qb`&fbqK|V" k4+IqDжw@wV}` $lk'45))ۋbJul|p8fih0qF̌mRfG~Z?L/sςv.N;PvyfsϟmVɿY4.]ֶl;nLۿע#o8zqy...lcS S<'nF@  $I,1 1A*uF3MQ5mnȀC{sv򩭉^xf' r͊]zvZ8Aih'yeLSÙ,!ٰl9#H(6f2WW7G`-#p\XU[=z;]6a^?-0V;xh6f=~?ôuCCWn5\6`D lb _^a\. EQ Lrghf0-Z IP>:*fǸ.[)\x<`Dʡj^p6pq(  ebƀ$Y-Ec֛- =3ʝaMăcfL6fŬAHb ߎ/ HݼQA WR׶u'v:bB0*S"6F6X'I 4}kd}D^s-A( jlbp'кM?&H»;ڞGOKG/\꼲ߨ?]mLX ϛ}5;1:zbd6?r٬=d{MVx<ޝ#[[ÖZf3%+W7. Kgyn|HNv-KG^IQ- ;Gl0ؒxN+WlQ(lqvv^iB8yz 1l\-.O("Y _ uİ}]]CwhPT(`6w@w;3;؀UZZ}ҥH6+4wXdz :NBSTӀMބ{hWvwMY_+8l1ccce2YϞ=;c/X%$$%޽˝kL-fܝgJxFwo~E#w6= :b{:CU/hLII)..0`c<n]+AQãM6iiirzrn$qolOÉ;tli۶c-%ATVV޸qM9/B[ŸB\ [z\s쇚o׮ݟ=mhhzj]]3+F^)++KLLdkmllv,KUUUaaaii)ڷoG}?2,ξnkk+ 3TL&6EiZ6DFFIR*ׯ_xrO#466sd+MWlkz(4 TSSSZZk}o<(gsk6SUUV?F"IR"899K&A[QqRV>i@l1AOEcO% |||Zmee%܀(rqqy(4}#E[°ң_{A/w $7%È!IxsdDpմVY2!2)ǡ;IyWpc E.]*X(Q)I_&F78J1W':ǦBeܭ:'j~_CCb+nz<6swYךu AV3(ή~:bgϮ Veޭ_ٳ6$EpmnO =d;bc1krOd~Xm?lPӢ.Q-u۶6BYYts#le%wmݓXW3n 'LT۵$1bw.+̓Kvpkrthvxտko{>_1Z}3uk G q_̽H޹l*5ɑY?oQ_Z[x"t#%q֔߸Vz3L vbEPЕ^K5s$Î^k߽Շ\$wjZ+NSXYBN;-UJ2,(Oh+QaӾwÎ ,1ĕ ĂpwV*z;먩8?iȹ|nuİԚ~?ߚa[-R\7BG[a0n,,ҨewgaL:SşZ_G裬#ut<)<8 DS>0U$ƕfҤX(пLeFꢢk鸭={2|Q埯q " `|iӏm,29p9hkC(JӠPB1i=")]k$251kWJ6.?b܁/ꔔF*aQS[Yi5j=l9$} ,Hr?w^˞ԕd*pPKeInjjZ~qiV,oh)]fC :8͑mspDR5(bOUYTK?LN6HtR>Nė~M]Tٗ`CLC`"1#P$%Rv:i?+y="GZY9|DB 2Zō/?#"w8W[4%9_|WN\H.N ؐBfgˑ1aK(re_HbM(~}#. @ 8Od-qnTBHz)゙RXb_2(_tyOg)i'!)[d]. :[ya9#BG$x:GSvև\"lIM LӢb b)A{WRafUEɝ7}V8Ҵj9b1~z\0<`vx۩y4!x(_ 4_q&:7і_5 jBp)!&r9IX:؋/7&]EwYHʵOkm=$Sq,@i"0ܬ8 7֭Kxehx#QG ԐuArXui &IhIdx#z|jL~,a#_??7KĆ܄s :3:ps LE{m;*tYQ⮗# @p/RS4@ !BBKP(}n;;{o ˍ{o6uI<@LS/mKR1L~0CڨF)¹.LkBwji^|oڥӗjvbrR.!PRjgW8.}lQ*lԌSn$(s07#oYT_tVQ^~}(_]{B-E0 { w 6Z+Wv/IOqSGDVB-JRMߠTRLnj:MUs0h}Tf©Vbuod^}.}i Jc> $]}96ٺcfrj?F 1i{~V 7}|ˡYcˇowԵʔ)Ke:r;:I*427(Pzm[ șKu6Ӧ ȮJ:g~_7lAŋRL}E MR# Oc@, B.L3r5wF ~U*B/Iɲj=-GdY g`Ïyֳ^zGrWUkTd^Ջq{X:2qeFhqm}&=fGK7(5O$_ڼΖn6^ryLU6ƌy ,x1D Nn)A*UC,&-M[ʞ} abwI4,+څY#dOG[ktqS'WvmI IJdG^9T|Z PΚV̘dqx+ p1{TiVo:㢲-A\v :+oEI!75CޣS/YZul\G;а)Cm.ÇLxo7,70#..)zұ­Gʥ5v;z(`W?go ѺtP_wuY'ӣr"-{K-34SF*/K{mVs~['^:Z^`= @@~Ggۆ}ݍ_~i:;p5_@ҼcR(w,>ʤ>j~2tcNni}c;Ѵ"*.$vͣ559ldVleLD4+BBjYʾ6ј䑻k;Us-6g_U|݉ Xe0̉wRC(ož=7QA'c9?wf6m=[SURojB%w{MwjYϟ9_|*Ct}7w/?;Գ6Lt2' N86ym N7^v1 \׍bs]VFd"DGHXbHj w֢ONeΚS_z /pVp%ۺU_ԡ!bŽ FA<{hn2Feubv_;m}Pćonzd]O[r:ξ[qToS/O~ Tcv`MY :kˡ1}wwxn"~Au9K1LGyo;pkn*<,.e_n!O7XJi`Ogyպc/Jgn:}~ynAܰ|S8((szhe9ؒtC+ֿq/S۰g}xOKE[C_^pX[C ?2bV5VrA5]A&YhZւ "3 -;jٺty<8)aGzݢ$95.^R-²tIMu 3hZժ4E֐Yw~Q}? ֝i 2SXaE~I3S1M"[{}Td/\$ThfEQȩ#S|sSEǴ8/x0fyVJ`yx^&ݟs_?ǶjWY2._y ;-ei  Sw=-/h7Oq||OuQx|2'?:sW'${I{W3( XAyDbFCw~º.\pڢ>YRtVt4yY/T& _I>{.cJ;vz$-JʘuTuڻ?JVA+v㞸i/E.n}ǗOd FxS&w\UI 2=:{YFzD7;3ܒw;c#!Zx!s/>'Nzq@=r.ʛ'g*+`/ C*#czvaI iFBH"9ۉ5͹w=3qkyn)PՃWaZEӭ뱱vaQ X۵iw#z1t3W=t}>/<Ne?]}M%҈#,qYW q~ya򢄎uްo04z%y;;A\r+mhA&LJ:/3?4'Bt86}W7=aԤꣵp el}H[+.͹Ί_:29&tT6VfCf }F$~}םS&NGP߰NsַmW圞oZn~og2T%H4P Qm;yx3xIg_uM{\Dњ5 #HdLg!˟_{Վ9|3bBgfN>ިd!YًS .xJC~H8|$L>!v%ڝMktӖ78t@ [)#iK'֭6ZCH)F>˧ӈ%->t擕[+71g---n燯JuMy8\'(bZ-@%ˊϟm9`iq QFY0$TQAuE@;$"rDdT|^&zMN蕱MIF2YQ㤔36>)$ɂ:hdeMH2yAaձVer{PէqMhPlRYY%hLBP7h<@JVI&T eLp$) vhy3kC4 @$>+oXREE%t$aFq %LC^әsf$=NkpMxW4HZc̹U @G^jV5,E(uo,'LmFPA hg0 V2lѡ7/rdŌ8ScFiI(-! dR +rMM3i9`(F{M&vՇ` 4{Y32dJr,I 8tY4A"0@YT>2t+OJnK9ì{M=(2FPH_*sTkTF2ZFkeG67yIJD%q#q(J8}>YpV]/Cj,pд gH&"yDGbDhuh6. Á"2,eV%.. ڥ>#_ 1Q$Nɑ Ͽ42WIœL*]ШSGX] ^ug{uͲz&0ݷC X!,YrFu#DTPcpN`X?k^N+%6jkp}x s^y=vo~T Swkl_vRJM To]VO!QWI(YdD?ײ[meMc H'dP#> ,l"#S"^TU/:D#;+zjNc{ljsNsἱޮƢ];߻髃3YkkiBwgJO;oTn&JttdV.{~E.JZz_ݞҗlo'3H}rVdLܹO=FFM~&"bX=foؖMաsw^ɚZw}e!zW~noo]{CoԭuVԋdKԫo7lSVkR"㈦= 6$Gi{JN CSSǝ. #Č v:dq#^Ղ1IuM7GU7+#ב]ͥ9ehZr\Wmjkr6NHV{k?Yn9\* WY 7c[ח^H훊?ݬ63~HTM^kn:xѦ% U^/m ݭnbQ_vn~Kfus|]Bxٛoo?;02$DОNou kecl'2rq4f%wV4n[_w>;"jfڶmսgK3ts}O2  紂[)\ĄpNo6MMIJ&9g^V` 7$;5ZoeeSC .z(&, f=E[-t@GDe\:B;[n$ad=M`f%- z۹ICSBp$Ę>|tX(B9yClI汐Iab,3Y!*хd}]F1SH̺|-mdDz$L$ CŮN"|H֕ʳert搈#Ta6Qw3N!lyw,JuD=:FZJ"en5Q61MiQC@E.Zb՗ӧF'KkC#@[jJ;끸 +oruX)-` ٱc21YbM57>:NԡROOIZQYg\| P͉̙8iF.e ĥp@Z 7%͚m^rْDK`αIDfJSD") pbɊ9L~[;rwDтCBM9 f'Z1wB꣢iK%6'$9Β5*./)TuyrYDcGLĥXlg=˘:Re7)f\dk h"j&kL4dܰn6i5&(93Z4hH bxsB8ǘbbuV>&u 2=! lG+>1n 2bf",'lO:svxFsFc-!b`@$dF捌̎Z =1cbΛd,$>432Lydu 3vH;wcgyE:*tU|;l 6jAS\E R"#,@[&2c@~ESf%B}o )')!H2|V)BgJ1eZ$ ˝`LH2<( nʝA1Nl&\;%QHB]=P@YyV4F`2CPxD ZF+򲺝mZd1bVdv)'#*r2~zA(-%Յ<dC0rD[u^QLPuk. ,~IRyxNusrT&PeuCZ Є=JD%({`@%$#tJM*ŔjutH<&t3U \CD3JU5̪sr^01u],*RIN=B,I~2iZ*y)m$)9R:()Ĉ"J ٔi~#AI-NS*)")M 1~e D(9xDLӿYz8:T]((ad2 Cc$hm3A#)Qqz+ɸd_o6,VH2ZZҎ>~`2E]Lz}Ǖ[ˌI9TN8_m\nNTRo:ըTIQF|%1ҠrJ(DUxn,!3"*IVAP#9[CMDt<@XuOtpOI]QVf9 /(ܥLs,nj7UO_β#?)l+^?/UIw:k$527Вkv_~HT"ec'NAi;k׊WW͑{k_E)7E'MU̒S3¿luՒ$H A]gS@~ ̿si p @ ȿf~o"@ &PX@@ R@ J@ RF.9v@ ߿8KQdF(5ȉnՅӢxpRK(5@~3)#ۅu&F{ q'zkKG9{yë{/-yw! @ ䷒2<݊ͭuq&mleVOG/<&XqQ(1/NIfVdn "/lt]_zxz5sӵu¼mi@[y2d'e;bga7tVV%@ L@ݱ(dɇUfiL3AJS9 =%ECfnɣaku¥)y1@~J]gK^9#D'BϏ_X5'Z 8$3!R@ =&6LN͉?Tsάa:oQq=&hCk4hs>txxz@ ȿ@ .>.$!*k^U=p0rPTGΟ p @ Hl6^xhV!(Z9sEEEat@ 1`10&Qy?۲= ?s8@ _~2 ~9?y@ A$QƔ0/@! 3᾵J d  @ E)PXzP q% g)@Q@Ep!A(E"$.)EF"H UJA*@~RF5? ?z(Nxm{q'N8Pί=sח7޲OV:cW>i|c rGbVӷVDA-w>՟_VSymE]"p @ ߓAT $sE9$L-$AZk8HC`oxՆGy }_8 v5@~( 97:Plk}},uOd_y_>GbI]` QiN`d "~DIw݄G\()x+DDʀS$$Q]Jp -Y̲)\zaR`х Fڡ*ˢ@%.MLl[y[v8HJk罻 A%I`y %(VA_@~+)#IRb?}I֑K/hyz5OzQwn;J\}e$ I]@vwëYN Gnu7W("gXIn}cB~"D Dc{=%؎`T ɚ/]x(wL?%} E׹gEE䜻r_^7L6a32o4q"O]#B=Zl&oyO& J@~~ڔ,qqWG/ȹ׎IEQ\=HyKuYuE[-+Ѹ9/./ì!"hՋܷ(''D&N?>Ngg22H'@( `2%L[(~58,˕CI0QĬlbׅI#EȪWED5|,vr횷p5/W&cWm~h|#^LD'& @Py,#Nj\Wޘ~(,@ ȯ+ɗ67E$ITK2gE H( W}QdA=< 'q%Սa=˹A| $ XoX]V- EL<2h3$1%&uUqp")vdž헍 rp@80 IU2,Q8.*AC3uRc`)y;Y~lT%YٹG"wN*EcfoD d  #%E(ɲrr\~vg|vڳS(#b"ڊt*g' 2Tռ=s,,z'Pǻ_r<][TV2ܹdm,mb[W}^ psvo߹Ȣ/ W_9 [DC>|uUobH(߱T7-3$\SKƚCEXBytC~gOQ'wu wdinz׃(b7Dt;?:mzQi0zk7rT# &e\7@L$)u<`?l 5Sl}eGxu.Iul;+nf0n,sZ'djiy#C$Wg[~;F% 3Dg׶{"+21-bH>f $NW6;8qՊq}AyßC!= 3>BBnmK%c7:gcSe]Ó7ܴx}zّ̰>?vhޯ1$Ṉ_1_x:rEC2%ZOGjE"5,pt|ޗzF륑OZv0uŎJ|woyǪ˻'mCRR(.`ew pL;ٌIc*SىIeGz>v{ :}':ՏhZ024DU5NCPbʉ#QmhjDH]mmD]@;3s65ol,~zÚd qU^+*=<T=|g76)" CF.;짭cL/x;ETk*v]eK|ׇSt}2).cBhRc eK7x:ĤƓM%7os1ʯGfgEb8AEö 1rpZfk.78T\\muNfBrÆ\c̛_w)h׷4bds#' K{}I $a"CMhHK Jtft0Æ!5,;\~#C-21([|~g[p֐?2i'/ L=#h&Boϱth(#%'g];/:1|=݌ ];DDQ}?˨h yb;{MƄ[\Nً &Ί.#s[\WWMnuvW~mۻL7]GS C/-L0kڸ5(^}p:=㰷0?QMRۂ$Z361Zh D^i4 -FFC<V @ W$Dq0)o(S|wqW MH6] #@ƈ#ϿKn[GGnXt}( TkF|$A ob0%{qy1HT/ʢ&hQdxQɒrU ,QBP18i5a z!XhH#aE"ɼ4D!Hm8鳋_P(jD)Y=:cyKIqsFhPTGhbp@OW6,͐7tb?Y]^FET˝jqth>5҄_ajY$%* EiBBa8w@SӉbe;^ CZz[&t u\)rp @̯W$Гʐ:e =r{=ܸ4ZӒD(Avzr|a֏\(Ql#}G::a3j\ vZJKK@Ezhk(ttJb9dݼl:,DpBp!0}vdK;H*[a (ӔD'5D=:5.̿.uE\4:"fp”~S?vӳ?,yz95;WB@N&Y3n^+Y̰DR"} EB)p:%׬%E'kUx,T^R 1;@ ?ϱdªH56vSU*dAqM۾Wfџ<xV&4ik|LfqNLB`6Dj0Ȓ, 9 q"N^ɛ;JHJF̫OGY^14{Qm0:nʐ /7QJdIfK{2wץQ<{@~E~~ 68mJ#yz[upTQ :ōZ}|̳^O`ps ]wPA@*uI4>"89*`NF!gAll1p+Ly06@0]r8nZڕݻםE g2"+?ɡ$p)!}?rOL}~uӇ'Mg\3 ?S(NP*l NV gΠ:iF)!=_蘁rhA[Cɛ~ֈqʵ~בS T!(rE<\Jx܌+ IW\b+A@ Ve0A~~΁,K/I/DeNu@=T8.Mq>Vŀʼy mITe9:I Ze 7 J.R^J8;/-D`B+ɿy8A0xm* 14aF__A# @ (eh!@ x`@ R@ 7`u@ vf.Ĉr:GH|nғx%yڠj(ݵa~fPw|oMQsg<Br._ a9VVlu?' vb/szuuٳgMÚ{ GHʍ! #/5{z=󇧄uTt>ɚ4ʹcHw]JK*s\pi OUIJ0g bbt=_KZxّOOGuIBgYaS`¥C%k˪H|ngl>z5Ɯ+>< s(Egj(ZS˳+*lrILqə(oIs c]՝+fofdOlojRc/;QϹꆱJHl~ڜ1ca|;nkj݇pՠ9z6g3+ت \BY\[pm΍Ub30vjÆl,|0knyH ;̼Œl" jntnunKin7 %+u]̴@LHHqPS@ ؆afΫi=z/<3}Փ߾QמMkJ a]JBnއ) 1WW6fz"Notv4ۤup?ǖx[&%pT?1w;wIec.걺1׭xgҚ8pSc,r>u ?~)jç-+ Op ([.9\Z}H<ŪSe(ye;v}faQ߼XȡÆ O]YRxN_j&"'Q*"Y< :q6q7.^[x8wx̓gϘ}ms&Oh;Kwg.Lzi]k1 :=%|}k{[yζ&m/ OuEJqzdթM7 (9SH? H$0,8bңy;^kqNCzޱ)Qވݓ/򎝳lr{ v'9uѓl\2~ѝ;1#ǍJzoWڣsgnX;Dm;ŞF7 `rMe M7 cRds˯٦P^QUy*5NCr/[EF@׶_q 8_j}DcG|WFY4ao~*qQ+kCG {~ICzLACB'r{pk~U6_\L@(*֢|PYd6'-VmIFPDΓL|pۭr_崊h2|GO8]^3?"Rk:<~5'=s=rw;eYk}5!*+r`X8=Ȅ9m߬x5N} ҫdC5B̀¼%[XhuHꚀC S (#J(iXL? "QEB]W/@Y'!YD{:ɢ_pD?e`5{-et|hzP?=W)x.ˏz%)=`I |pôF$%aAp1Q y)f]7|)Ò >a>?2JQiѲo.q4kGQE fg#x(XZ~0'0Ena {fZ|㹊v# 'ͷuబӇ 9]S0mcz_xluE,/DE͞8V_69|@VֹcM8ɰ?$Y$ENi[-/*zkH}u9l_MSYSm˼)3-r2ԋ 0H$r|]/K.8ٌMlUh?`e(ySx7I$sVUٞ2%N%^"]eʹWόQU{/Lj26\YM!ls]bǿ;w"Hw`ύk`fll`ڪשk4B%r|nWSkU0_wz/m#2 ի|%Fמ*sQx *}$Ge@hۉ0^<~YjX7:ue1~KEk)\yJ($r=7.4qjRCWe׺nf@J +Ɉ0uf;V#U>qM 1Ddba$?mmINzvjl(/V\35( (_I 2  ȉ.)IENDB`Pylons-1.0.1/pylons/docs/en/_oldstatic/hellotemplate.png0000664000076500000240000053731411645401275023260 0ustar benstaff00000000000000PNG  IHDRD{ iCCPICC ProfilexV7~ƾ$Z5 I 1)jLdikdmSd"-?y;{N_=s>ys9柡<\8lMhieM2 RT:OOUif&zIoy{n?Q'RƶH:f$mbGl3>@"f }' ؚ1x i$l P ( ttOxgPe +p}@wub . ;DP@2w_ 6v`el4A j a-  c%~Zda` ؁# P||Np?v01Adhc+A,M64b-?na7B$fsaš= !i(BưC(R\\\6\p}$KnYܣ<FޥU|2|f~U%rтXB4 uy.E+[#V@oA>9RzR=Ҿ /\mqڒK&eRdd?/|jbԲ(L)(0Pܽ2[wZR?)JFfVڽt+.0o#Ư7SGF􇷼53@unvIcy;t{FܮjݳK6Z97g_6MmCyWNc.+\n},,θOoT3 ;<4;l6|ѼHVTq≰Ssc&ٕڽgV7ԑc&Kg|MΚU녿^녿^_/΍O,to&kdwxl8e0QU2P_H$A(x ; ;@~ )MB"!b$ۥ.X,)앂v%c*VYZ]EJ&٫{S"55ʵ+An#yu3j 0mIS3Mrw,5dT5k0ojnimݻ}#jc)٫9:Ҝ9xE{>>͉  ݃\Bh aWG'=fAj>qqdǩ^g ccJF[$('|9Ww>1qo1i0څC)kR/_OݘFHNl ŕLZWeeQ-z(O"[kg * Êhn/N.)U*++(X[N]{f=Tzȣ\5QWsVAz '6[4OܝagYfUeݴkྉ_mx0װ,98;e992]C&SEVQ]'//A!aG591y?Bqj1bFO֜:NplO܍; ?h̟vREK\SXok3TɜzZD֎lޜ׵ݨ;}HvF᧢źų%Jm)+8~ݺ{aߟyWpÞG U;jNԥ՛>&<.l`=zRӤݢ5)ӲvŎgitv9{}eEo-}} ^~0jhbhwrc5'>Nҧԧ?욹$ytB,_4":Edx.S%,P8Mys*AEjvd7e^DFMZAziU[3*aMgc[;/M̾XhhEݿe(3m N ^GY'!oדnW=Zg9R^^xyW_x>(:8 5@%G돥EDRq1{N:Xq/f{%P;u>3p҆d ))̋+/~Tf.v9)ҕEWg g=NαUɝ^~H޶7_ܺ\^0UXXyr{ijR:]VXYQN]=ҽTJU6?z{UqGʚڋu{54zrqk㏦fcm:mO }:tYN.g/.tY3zWf}Kx4x!aF{xsɤTt׌ClmliOQL–o܌ }כ 2ZR pHYs   IDATxwUar!HfsN .YWWŸ"("$$ArNC9Lw4AUsTOT}{ @ @ @ @ @ @ /@K<&@ zAMwp'@ s݊Epԏ8@ %j*t~vs P+ڟh_/셽^ {a/}E> RjS6@ :(VSB&'9@ C0gGu%*+fC:C^Ia/셽^ {a/*ڦֶօQm @*G:wx {a/셽^ {a=KAp#jMզ Iԧ&b&"I @ '\qR]SѤ  WT>p @ $N}:TT7h;pV.@ |ITǻK"$ jnԱ^ {a/셽^؇c}8QPچj__z(b(. PFp^ {a/셽*T8 `-jKU'36v\59q@ 5E(G36vP#CnW'9*<\U.셽^ {a/dR U~E6Oe{6l$\A 7*lo](BJ)S (OpOa/셽^ {a/ot@֕b[ &6 PP q[)O N  '셽^ {a/`Qڹme޶J`EV㧼ڄ*:׃ .E<ڏjeJaU[ {a/셽^ pDE2!mѣ`!C٩oqP]AT1V篍 u(]2uoNpN:a/셽^ {a/oT{ɫ̟Q~ ꬫ ZDB!/;T@)Ԅ2=s" {a/셽^ {a{PQMďwy0q\NT"Im(^ER)3W->[ @ _DM8R:6([bSY#WP`CMpM@Y'|-2QF,Kj,@ ~ϝ?իW3g~ (Z&&TQMA EAn64νO &)˒xff@ zAb2l/^u"$I"E7sHMO@ zE6/ .BJʍw(ܡR3\N,/2*Kߴi7$ ƾDL$%'X>${"YYٔVV t6Pl<~->d$9-7FCd]LYNa!~7,}̑' 32*sНeH[)ajh5yϲ@pSNӉ^q_nGӉ@ ߿-1!wDH,7(Pn|z{lxsd|FaX"2Uv8kEaHj'瓝O@p ^1+++Wے$q)j͇?jG ~B{Zō@IBCIhh5 6:􍊤EXĉÇєcԀ1"\͠Nuˉ:ԫ3(-z-q(Ep떓01}ټI;g`qeowT9m貱HzbG@ $I~QaÆ>t <1c0w\vaشivwӧĉ:uls!}Qn6d߾}|7Hİa<8;w.|/۷ogРA>:B}yWѬ_\G[O;Ql+%`@Q6$Tg0sarʽ|C:@o :X4jIjE"2?]~ȂbDZ-V8q"`̃tj%9 KJ4 U1Teǒ%% Kru(`sӴ[) ∎$2ʌXA-"-DE\?&]8s8`bX-n-Zѣ2e ~C}{aժU7-[? q7ƍcϞ=`P'~N֭[}o>ZnV۾};)ĝEӻ.;;BJKK+..KJJ&;;+Ws1uTf~zzEYYeee8N:vU޽ڴiCii)o{r»ѣ7aS\\Lnn.C(>[>}PTTDii)ݺuӜ:u7;ڵkH$I3sL|Avto/3j(F+BQQQ󪰰[ng"Ik׮婧bϞ=L4ѣGdtpBƌŋemĉyꩧG$4iW8?QUU"8_-P=鎰R(ߘPکE꼢`_T8(Kd$(  SL4("Y̤ D3VWLrXIQ1'FcLbcbbNZErXb2R(^x"#DY-b&Ҥ'ʢ'*Z i<ŎXn/y摚$ISN~w^7Z x8q"׿())?3vX5k;vЯ_?NO޽G ?~o^~ҥvmbCdff(pHVVj,rYll,.]R=FqKMMeĉu Ň`#כfzȕ$CѸqcL&SH$IK$&&ΝsN*ו/,\ K/rfСC,\/L'Nj ]իWpBU,XKEEKJJ01Ln UUUl6 !111z뭔-رcڵS!CCR5_p`4)//۱c;.]ď?ϡCh֬gΜ!77xB}\|]v1{lbbb;vLIImWʾF#gFҰaCl6gΜu֬Z}Һukye_֭[Gbb"III9r;qF9׫W/F /@FhժUH@ޝnڂ.҂b@c]DUNtz=huPgLr>Q^PYoĬc54̀Dֆ^nԄzB aаaC <ʔ7$7nqt:2w;&zꑕENN IΞ=b!66ߍ?姒UVxb>Cfjϧ_~4i$MjRR<$MQQIIINHHi_XXHՇO7DC)nbbbӧ "??>C(pmۇ2=۶mc֬Y>ʾgr:p%,I+*ШQ#ydƍWd@RnUUUr˗>||>xKqq1 ZC83qD>3 yװlA())EXRS4-p4~փ o_(IBDq:qaZbc0B\ǣv5() H+ubnlԑs[l2ј`Ԣ1hA#!iѢEdsp.C^l߬+ۏΡj6a0i4cљ]aIr}5 + ~DAŎP!U~z].;qℜ~vm۶O-{oڴ Ga6U>y$| s zξ}dddЪU.x "57eee||M0 5j$GK:nIϕ+Wx|ρΩTLB޽eB*++Um܋;-'4ǎjZw5mڔDܟiiit:,X H$oI9x}زe O&//C 9sp98z\qFv͋/kƂ /^ټy3<ӦMK.L0~KsC.\q(..&=='xB{y0`vvE6mq?WʶaΝKUUQF1`~ߑAQQl3пy{׮]r-0)%Ν/dɬY>}:iiidee1w\/$**]RYYK/?֭[{gϞ.ᘕŘ1c`رr⡇h4ӧO?UV(((7 7&;;ݻu0BqĈ;v &`6歷[ر~sno+'P*r8̚5~Z7o/,w~O\տ}Qxg=EGG3gfΜɧ~JTT{+W0g}]l6-Z_w+%AP !k!P8&PFF-$PLp)?t@zQjDFFRp;wQq#'$ Eee\s$tDl۶3d[B4mLl+QCa~gNesx &e5l;lV+111\|pMOHH ;;VKUUL&JKKeѣGf͚Q^^Ndd$o1--By.ц 8z('O_m۶>uVX4 IYYL&|lrss}/>s\"""HmXZ9sMû_>EEEwHLL$##dZKOtdff}$I(o`4INN… V%''-[b),,+̇`qqqR^^Njj*999p(++x `V%>>Iqq1RYYIDDwݗ^'>>t:<V^z0?4hЀ,*++j$&&RTTDLL EEE=d2G~~>fLff&:rrr$**Jޟ> P[Gq !wSYj#qmޑ'mʺSH_&:zM6iӦ1w귬hQ%Fk IDATzL|NjM|Vj匂JÞ={0aBs(\RJ.Z6|rm= 暈qvEȮhH^6)Z5A& 4/H!R VVZGZ-("""]vy=! A$@ (p-2b[UYO)EMyjr Y@  \"1!sj#8W-j"ƟDu{]((##{RXXxCfsh4бcG4iM]vYf  ZC P_W_yy9dggSZZn ~Sz"""HJJI&X,vJ-jl,U/ATj2=x; ay%^!СCL6mۢ.͚5ԩSuҷСC̙3Id1 jןN:ѨQ#Vk!A(qZy@o>\Bƍڵ+IIIDFF !I9<7n$55:T[b_t`sžO V;%ԣJeaǻ~|IMuM~I۶m2e o678fOӪU+ڷoOlll!A0 X,ԨR^=FMzd2"IvFqq1.]bl޼vڅ{_v-Z|)^NgeyDЖZW4瓊;ػ@HOOu- ꘅ?F u:,,,ȑ#t҅Ν;j`0j5$I8NbccIHH --ݻwgZnMLLL]ygNvʗP jS;u~uCu"D1v:F} 3.eA߁FQ}x7iӦM䐐2RSSkΙ3ghҤIHI4Ξ=KBB!_YYIEE5򳰰b4h_+W={6JX>zږ-[8|0o %Y-:$ǵ;w| BCdy׫Jl6]v%>>^C+V/p𲲲ؾ};1Ƒ#IAA::D}vZh4hZL&tڕ/͆h fQ!7eY(6nL<:獷P )5_/Ju?TUUU{ټy3]t --]ta5' 瘿 M7DDdFӧ_:ŋSUUEqqqX/^ǽDEEU'/%ٛ9cjFBb,NCr-[pr{2%Ni8|G7|N<ϳvٶmw}j])--y:vHrr26M.Φsvm5O>#QTuhٲ%IOOgǎ~ΦW^k׮̚5+XAe}1 DFF!$IbӇ3dB+c6m>Y oka̙7.>vͧ~Z-[Ǧ`l8@QGWTClZjEZZfVˎ;Xd 3m4MX,,Y۷W+++Yf Y|9_~%?Xvm RmV%Ef4ZjEvvv(B?B}m9GM@yOzR;PD _P]EK=9r1hZ6hܼ<>Zn믿NV jy/_l&.>կl6sQ|M׿֙?g&##ģiӦ{^bL:U.OIIO )s._eE< Uٜ,!>|kbwHWVQ0r,V}F!clڴ%KCzz:5~ʕ+>|Oi֬r}}~ѬYFM<_~?xOn?2fZn߲2ƌ_MnXv-GԩSC ?ү_?^ui۶- O>ۮ];>sn_X˗gf3&M㭷 W8ǸffΜu0cƌ:Or"9 ^n=iqp#DC~m;2k.v;={dĈrԨiӦhZ֬Yî]ѣZm(=Yz5999L2E6KMhtXV5jC= h6޶pjm>QgRR,lh@FF?0w}7/^$>>ȠvnA0I||</^&##g\uѠA̙m1  |A֮] /Pf~m^u/^LAAGs?~<?0^q,Bd20Lu!v<mj*q*\n=ml &@l(31f)l;>cǒ{oK/7|Czz:+V`ԨQl6ڵk' ٳg?Tڷo/G`;wgWVDjB}L&&IC 4ؗVU^~;f͚e˖Ln6l_ާmYY/ ** uӸqcsx ͛Vɂ {1̀K8̯PɓQ{nzA/SNѯ_?bcc{()) X-[F۶meС#_oޯ_UUU/@rr2F$I;v I޽;QQQX,f3QQQt]nS ٻw/Æ h<=zwyW_}E'ꫯ2w\:$v/_믿μyXn`ʕ;\tZKEx!F?2\ =2Q8;֪ԩ)R>'CQAw߹޸h4A۸ov"#"8z(#GdL>Fq_|111̜9.]PZZʈ#?~<ɔuʟHΞ=K||Z*Gyy9| 'OVh4;V>jԨOi{<^۸qcVXwqɞcWZ}ȑ#1O;oQQ+c\j(L6^{;v0sLy)S5j˖-cر,Yz(1>|1c0|~_ /0b<1|l6>ׯ ?cX7n5//)Sߢ۷/<QQQSNe|w~EEFFb6C 8dMQjܮQ(Ԉ tKEр@\x'IKKSWC攂l͞={=z4WTUPk̗z=[N62UQu]tr***8|0+WD+0tPElݺQTqw>(z'Ҟ={hӦ L&RRRGJJǐC&}YKEEf{gCҼyp]0'MDUO|ri }"GVBնz7Em(Wؾ뮻ٳgozbNhXd1Z^{?&Mƌ3-[믓K^ >Ase۶m|P`0vZxyѣꫯ9إKkٲ%=vmڴW_etЁSH p1{AQ򍯃1ofk } ?7q9;KW6m*qu{{۷gĉ- &!pE O_}W`0;wr w}DDDжm[9^ZZǎCu~YǎYfӰaC[NgRh4zL&S8B~ r:z1k Kѹ(T-sOڈn:֯_G}P"Dj3f3SLaȐ!TTTͪcZRTT$ \IeĈ |MSYYG1 \t{^|EZl4h~- y뮻XtGy(oGuhi;G[ lAo4jylDf 8+iX=Y-֪U+***8}lbVO5k|A(L2r9 7fbРAo)))Maaj:H~k[8p ^zL2^z DjjqOX1rI:tNˑ'9"I=UUU<#rPsرLz< `~)Y~= G5W^aǎ|AG o&稄&ڎr $ /@J[U?[n{h4RYYh= ٽ{77nDvw}OnԾ}{yϟτ d!FttFyժUTVV2j(DFFRXX`d2ypHMM={6v=O \!WBHTCET8>rx`mMdߟUV"C#Rt:Fj|\ܩS'oΊ+NI_53﮺TUUocX8rgy+V?C2~xI޽{WNzmDyv :+lDGCTD&+|!ҤEH*;=pT68~8 ~TUUs>Yr%Ǐko&gÆ 233ywӶm[~mynsIUQW^=8~8ݻw\"t߾}deeѰaCڶm رc4jԈL&S@B9 60xKLLntҠQk%⬨+Wbw>x… ~nٲ%7nT;w.-Zȑ#vf;຤q/Wjm .QCpZWQgVj˧ d2q9~8&rRyVgϞ\|o%Km۶1p@9f탊!pCqQ/J"##=6"""0 l6JKK|nn.111+GZtM,ŝp_T'{2,SScpZKPYYI~~> >s2|pyvm$Up쿸|*++Ҥ CE׳l2>3yhg}Ʋe\cS>#&Mģ>̙36m;w_dlݺG}'NPUJN\)*z4ˆ-hQAD\l$q:'îBpJ$Q,6nނphܸ1Gl:Dnn.Nŋ3dy(?*{g￧w%ܹs̜93fPQQAaaτ `4}Ƴ[raÆt:姒K,aÆlÆ <+*첲Xr%o׸/ 8y_xbRRR M0%K WcѩS'Zlk&2;dΝ>|IXhPСCK^^wߕ>l7W#ے$ˏ=k'||)S2$ܰ 4N|k ?uK*M۷O?{RVVsr8p8$ FCDD#GdرiшhM6u]py{ &Y~$\tINo>V+ 4 --hߏ$IpyP۷sA6ms'rGDLjGBWQ)_ Qjj($TQ 炅żUVHfCsw3l0ꫠ}b־}2rH(** 9i7qIII?O>UVh"5!>q>HBbMomLUUyyy,]ѣGFs||g< :1cƨJ-ovU4؄:kHNu+q`,fdh~1|p^y7o{\x^ꫯҿZl +œ9s'䩧bϞ=0}twΌ3xYf x/^,?1ӧ&LSNƒSO=%ȯ`|Mz>xzꑔ8 IDATD-Xre@3еkWRRR??:BG[o%--m2zhy.aΝy=z4 l6}YyƏoA_>> <7oEuO;]/]2qv\chy+ >>I tdffҴiS9ӜN#**~ѽ{wv;$əA;wܹs9}4o>0tPt: , 66@aa!]t\Ǽy󈈈t_Z^s=,Y;vPZZJ޽!={m۶ѴiS:vWxߟb~m`„ bU$ILt:]Cdsm^ Ed_{ދV*_]]emtm2Jh`Y /^,XS_U$9tuy뭷>jŘwq>? (|QAǏGӑ("54 &Ic6CuEͱZѥK6mb(''Ǐ& }Zb6{AZ_}Pj#˜ն*~\p!KjFS.^H||usŸz$X$C g$If͉'8{lmxp)} AN;$ @ eуZgQDN+Wi& cԮ?A@PuH$222(**Yf$&&hyy$Iv*++)))!''SNﵬi^ۡNqZ EL/gyf3eeel޼YNx/߯_?VkP,]5jDrr>@ ~JٳҟF!&&DbccZ"/AYYPXXX{I&*%SP&ZNTl;rI "|yj(H)j0X7o^,s[~J]Qaߊ BQ,]@ W4i R)3΅"Cj-\ P˻](CB2WZZ?혅?@ G?Bs27a'@ )ϕ D"H$Dr{J2- (j;wCD"H$G:DWxD r׻-qgz%D"H$Gj+Fnkvj"D"H$Drb?dN~tBjr~mٲ'NMb41呗WB233196`0>^ѣGKt@:uhذC,bccX"+V|uiҤ .\bPjU%Giڴ)Ǐl6sQz= Kd@ӱ{n>S-[ڵkp/_&??5j8A2La00 17no>N+yɤs)9uTOY`1 4`J9vޝUh"V\I׮]Xn]vʪUOR w}7Bt:Ç~>͛1Bka6y'/SL?W9~8`駟*v?~׫A"H$DVPi~;vZmoqGK/4SΞ=K9Ѹqc_˗)W;we(/[CVV̛7:0p@*pΟ?Opp0\tLvM hذCϟwņcիWNVl6+*ъ5>}0j׮͵k׸vrNxx8 \ztBCCQׯ_'**k׮qWR%*WNS\a4"!!L9?5k$//p /_VPJBBB((( 44;(q_pAkSQZ5L&:NǩS #!!ANS?!!,_^~8qDTT*T 55Sul6sN[D"H$wf͚p 0&/fmKoo}v߮>8+E89m{B^х ; tGZXm !7omڴCγĉ.x"*T\r%_0L^{OԞ FCPPFm\:Ӷ0mΖszw>w?ǁI$D".̚5E8GP\ً {q թ3j"8w9{-zBm[[oGvvvڑSYzh4>QhB+g\-nWv+5#BD"H$my@s ɂ*} S+\sADQl@! $$b H$.(^88}D"H$m+]JxZ(Dή}U^T`@*ɪUDx8H$D" QQ#xKU~Ԯ]ۛ}D"H$%P[xT@O\иj[:D_~6I$D"H$[{V? _"!y;׆"y%H$D"HêU0DEEhDJpp0AAA+u:f|ڴi96еL!(7{-H$D"Hbz=jբvhZ !//VKpp0!!!( \U"oȗtj2P'H$D"H|G)kEOry&999jzt:NZ7ARc/uI$D"H$26 N( %peVl_Z;/A >Sg-$ED"H$Dr#P- deeX,PR#:LΞ@ "O\u{rD"H$!" r h4BBB0jud:ujVAm-ZDtt4˗/wyܟʕ+^:s+WvٗWґH$v`0pl0!!tiWIQ /GrDFP)*j$//ׯgb?WH𹀏}M*kkiǎL8ٳgӼysF#saL8;*psox+jժQn]J$Dr[kVQh:4j>COL /=<&Gy Sсظq'??/Ě5kXlʕ###C+صk /#G$%%۷  KII_f͚P!CNe˖4hЀMҧOSC;v`Æ ʼ*Fý5}_~+VTF)=w9v<O63bZh@dd$ǎsk_-)ÇӣG:vȬYHMM,fgi^+\KkfРAʾl:8x',Vν x +J$Dr[`6-닼a`0k4wS5JꑺTFbvjYw+ù{-[a{׮]S^=իǀ={upJжm[*:u2\dd$=z`ŊbܹY7xï[՗FqOr(((P6mJ֭i߾=))){qɣ7dFaƌ8ps!rrr<}ƒ\;1W=&yj;W`08p C aE]q/OSD"vDh0[/FXbF0@hB ^"o:M\(CT\)}؋vv6ʄ|g{Q θܹsܹ|֮]Knn.FⲼ--6~GJFZQ۾- -[dԩ?}Vu;-ZW^ԬYӫ]-oef&N2]D"HnK4X 4`i( .2<+F,kdh %-:(BP E( ՀxM;@= 7 ^^XzhѢDRRX~B+W' @h4믋7o !OEXXDllBJ\۷ow.((GM63g4h8}73B|bݺu?.^y{Jk"<<\ʼn/ҥo">>^GOtA,YD!VZhm?쓍BO?hQZ51qD1fѭ[72pW_7ojժ_~u"%%!M6za߯*ڶm+1gh"xʣ/68ʦ<ѢE **6n(ŀ\眇7n _XX(|MѨQ#1}t1c 1a~ܕ3zk/[LDDDsNq!bbbDrr8|HHH ,Vcǎ&ɫ]۷ow(KzLSBNj*UL["H$ۉ˗ گ/~~FpII$$zλ SB<#p0 g;4@"MвH#4iD HST/qEPH/&aEZ%Hi)&\)-~\ֹ ۶n$F1?ZjmϩStGppDrm icX~:111 BC0o޼Irr2SNu… 5|LXXFѧ9<6/ )QX|)??0W\!&&FUYRrX,hZnܸAPP> @`PZ"H$ە+V0`n(/mB*B-;OS)J#YAA.zQˀ^Q4ͷ:DŽ\t[-|p e߮*o2 S󅒬=r'1TҴjC|_ aÆ |%188X]1d O}~!\&쒔qqq*k$jsYb+@H1$H$ :tZt:닽^FT~= p Ry7իW9{}…HF$䐖{_׽3|<.2뢶u\q%~'_ DaQ_'555&999?Da}?o9g Ҵ@ٌ`6Y0̘L`2B D1?nnQ@Q#ܩ8 aqGYfرc.H#`4hFCn>|8 cƍemj-ZDtt4˗/w{Ι3ghݺ˚#Gп[L¤I|̙3=رGrӿVʸqTWS?3=z`Æ ̜9!CVoeΝ4nܘgOk$\ի3w܀[XUxb-S/tK.{|ݛ]ҿ5kйsg4 Fr{رch44mڔosoinXj>-hs-&dP5O?>Da}?WٳƍSjU6nȜ9s>}:={v-* ۧO&L^gɒ%\z97n`ݺu;W܎8<|W\I޽<+;={<8a~mر#Tvƍԭ[Ag߾}ٓƍuVGUU)W XUUcX&n'|´i0L?_|k###ԩl.խ3 ))I&)縋=wmқ]f^}UiҤ OVU*JIŞ>̰a];O:кuk,X3mXX~}'[7mĠAxXp!4hЀ3gΨaxgٳ' b̙l۶c^Զ9P,VsFb1c4Y(410 Dc)Gꀏ0󔐶;BP @E *U@<&@s%ht tz/ hxb222Bo"::Z4o\^Z<3ԩSC/Ba4EEϞ=5j3fP{) l'$$3g*{%rrrbO=PlR /\޲Ӿ̄ĠA~{zQQQwߩܝ;wŋŋELL8pC,K٩6McQn] ENNضmڵkݭ[7{n!سgO<8c0DժU͛B.LRRC~b߾}۷oBe5kֈիW绌kѢC.;wN xĺuw% !믅V)7nӦMQQQgϞb۶m. 6)څڵ?~B狯J9)^WӧO˃6.Om;wyضmthܸxǽ\޿e^y >suSVnܸQ$''%K@,\PIs͚5bܹbΝ}W[EÆ EÆ EJJHKK5Rd !8zĜ9sn/X X|'ibo/fxbYQi q!fGIEw/zTZi@"PH,5EU HsDi"MQQB4Kpi)֣䭇$˕s5.-Z`zYmg˖-iРM6O>$''s1vŀkȑ#IIIa:KVKԶ_`2Xf ˖-\rdddm69t2)'t٫UvڗOpNq][ū]6 Ry=N:qzjRӖ>:uD*Uҥ Ǐjs{z6?(::m(k{HժUyg'|ˆ#|5::ڵkӬY3zAjҥ 'N`ɒ%ШQ#0ԨQOxق0ZBLf0sXdz7Kj|/fT=u9FyM_AϞ=ڵ+ǏB  uٳXQ8pN:y3jݸxի@z0`DEE1|pȐ!CX`Aq÷駟ǡC.[%?CϞ=SNѿ>CjӶcޮ];e-]F1+q۰9p΃͘1~z:T̽ժU###a͓e}GqjZ*ww999Z'Q䩌{9ҥ &Hjժ2.y/O3`xV\voy?ܶ 5uzj P/֝ رctgp###!0dz;wm+K{3f ֭N:QbEl\r ?lGGG+Cm/X Z-h5& uZ4YCZ<(=5soWz(+F|;Ô)S7oOF#W\ƍݸqczOm ͛!hժ>c֭ԩS9p۶mSTˣ>Srw3sL{׏'xyѥK{KYWNTRcNOOw)1ciii||GWOa駟eeeh^" +Wf֬Y99@<~yts.+އ4oޜg}ceBOmғ_N IDAT]jڲ;-5|]wѱcG>3._2>[qĭV݋> uq۾w^7oNJJb˖-dggs1N8>@TTNRݼy!Cʉ'xiݺ5YYYX-ZЫW/ŭn^^cǎɓen3k֬aĉ5$${ӧOs=ЧOQ;=׮] ""KÐ!Cʲ}IV6~Gfϣ>6CСCٱc۷og>kxΝ;gڵb4X,уDK<]ohӦ իWwO?eǎ򗗗WL޼y+W*)য়~bڴiR{a…|w+WNٟb!;;[U׮]K֭yׯL2H_c=zBwy.maa!-[2uTƏC)^=CRSOmғ]ؖmNQf=z L8ϟOXX "==!/_l63Pz}j =չ`l9;;[y ;qD޽;m۶u\b?9P4AՀVE@@@ iP^RSR.2Q\"2˜BiF̙3ŋp'Ke#GDӦM̙3/ 䧟~ѢZjbĉb̘1[n"%%E!Ĕ)S *222ħ~* bcc/N bbժUbرd2 !S4NgƏ/Tت+W~ZKeS_ڵk @tM%3gի8rH5i曢QFbbƌb„  >^ 6L<3}bh4_\x{}Q-mܸQtY~믿h DddZ_E:uDppHII &/bĈDřs_l^^\`%1oU1kUň7 1!B|p܋2׮Hx2_-P ^)+oG,lv}v:7BraK.o StԮ]رBf3aaaF;I1?Zj)- Z7nDDDC׮]S5破tF`p&v*?rWkOYk`񊉉)Waa!!!!޽[GSB^J\\\4L~~Җ[Xb8+_u5to*B~gZn+WyVsm۸y&L:U xnuSdp9oY/^XXѣGtԫW˲?u.[oC=` ;;7n_sw,/XIYb2i\jWd`0' *GTH5T"ۦ=J߾}0`K1y6mp[ ?,O8!O> 7x p=%IِEŊʒm'|B6m܎ŗH$O,\7:OII!11ѣĿsLDQj!ߨF+U)(_"*! Aȝ K˜~P)Syh׮ݺu+I4/[noߞ 0jԨ!O_~֫&Hnڷo0`Z"??+Wлw2CaNX^CNg8'szc`jv<"gG > R;ɝ˼9Tj >$A%Iƍ\2|AY#)%H$ЬY3\¶m۸|2]t)s!d ҁ@"0,U$ٺfL&0:$n읮;Wq "̋Z0c 3 F Ί!P[x5ׅYqն ȑ#ߟo)S0i$8s Gs_PP@ll,jU-z{n&OڵkY`=X<1o<[vIƍٿyıc j޽oߞ$UV<ʾS㉕+WRzuΝxogn!^;))?We^|Ac!4-`IXfK^Ľ.s (OƝ=?O:/%b0g4 ,3FBS @KTP1z3 RUw1.]`{U >[PrѼysjժFd^C:u^:իWg׮]kە}7n 22R]l6+6ڵc^_}U=*nwҸqcDŽbeJb?2x`~7•NNCej=g{=ի'Ow]\ tUj󦆒WM\%]ʮ@%Nqos)Ͷ]UZ->- dlʳ_ْ݅q+7ng}޳W}_:,@&3`AQh)4EHvx{i~o%^9W PGqF֭9x ۷={Ҹqcnʾ}h޼MW7+W(ۗ.]矧k׮lRy iZyf̘ҥKٻw/⩧O>aڴiL&Əϋ/5tԉBҹsg٠A.:Pc:5.>&Mpiv[{K/8Ǖ˄ e˖>|X9)O8p$&Mk:˰axgٳ' b̙l۶cpw/3~W~芟.]0j(jԨNyjω'xxhٲ%Z|W^Epp0_֭[97;n+ݴiavPFmիWegڷʊP)btTL.9 ybq7~. Ah,W%`@޽ѩS'ԫWݺucC%:oh0kٳ':vŋ#;;쓐.0Ɗ+иqc 8Mغu+<==[.Z-6l(R' ylҥKqnݺR{3M˝;w>>>h֬5kdddcǎ˫;222˗vZWY&fΜ۷ozB~dQπN: ǎW5ºuO?ˋcu~ =cEꊲ2z>|p">>P*۪V<<c>= 6E`pJ @ƒ!L!dȂ\7AZ JG$iI{ |VTS/^QF !77o}1ڵXfؼy3yp]l޼'O-km_ HMMܹs9s`ĉ2zkիW \\\I?-¼yRxFj塰UZ96m9sUPh[:srr"2{ᶄ"33Sr0 ֬YK")) +WoX5\f ֭[ǾT>[yCRt-t1byRm՛ 1*,,ԩSѧO 4jڍ퍚5kvڢ}?#ƌݻw̙31p@;v ժU.~9Ғ~ Y,СCAD3gz聅 bРAc,'߯Rz>+-AP𖵥}y.`@(J 8(89JF-% c;C`قlHrH8/!W\App0WΦ}8~81}tڷozJ۴iS]fQ~,US={D&Mc6HNNfكx{{cҥ/-jxݻw/gc!;;YYY2e QNl;w 44eѣGt(**TcĈׯd`,((#pqF}DFF"00M@\\ك>}pʖ\lj@ֵJ(WQQEɓ'm"22*=ƏF.//lאvq իuwwǍ7@DB3WJ"33999Ȣ"@!>>5j@||x IHt:C!((sAbb"Ri OMuԩS7|:t|_HWO WFYTvm*--5k/իIC yi֬Yt ѲgΜ0@&Mb5,,,YBEEEuR(Ԯ];ѱm߾=mۖf̘A|Ջ 򥧧9igϞmZjoFpBhlߎ?NnnnT~}:s ]pɉKk׮{Iޫ0W_і-[Ņ֭K;v`j'jРM:ƍGᔖFDDIII)??wBtaϞ=F>>>E0ںu+={:tzO*++T[.&MPFF[)HLLzB˖-Sj۶-UVѣB111T^^.4UFVL!_1`ʃÇ!S"~ EwCμKeݘ}h7N,X@'O<$ mF5j ___:}4ݺujԨA,X/Ou>ɓ )@5jԠ#GRYY`DºB]3/ݒwߥ3fTy+?bzgΜzQ:u￧[nQdd$ٳgyPݻ/bc!/ٴD=>9 ,|]H3ӈL:і\ne/,{ e/s2 s/sn9>ˋ1mp25J4ka| h-ѣG6f * B@aa!9[௿tBrhZT^j>䌁%މ)J(3 "{[y&Y)cEUVؽ{7bWh\:H8W-WԪڵW^\kx뭷35T)o33&4Yo7 Ad鷱cjF ";cƍ l0 ˹(**3]v#BBBx) ={R# sڵkqM3:p !kß\Ad[A$˜)AŽg~t:p".cڵHHH7 1$C-HJJ/V\7xϛ$; e^uÇ8~EcߖP$&&"&&ڵCii)ЧOYߩCK`F )h5PX ,[dSH1L]mu`ԿR[laAرqqqWo4hP%t|P(0|Mk0Ǝ+Y6Zn<֭lC; T,0 htNtCjLj"?! [kUi/^1nܸgDvavX7vRH %t 4 t:ABjL-[bۓlc6ҵMavava@ĠLVhuZKt*oY#0X-.T^ѓ'OWTrKF~~>yBVk׮I_VVӧO۔F;lErssߣŜWBii)m^S.z|222$QPPH*JKKmD 1smo;KHGP :jj-4h YrZLϩf0XnVm'Yfaڵҥ BCC/H).sAttMڿ?:w a0zh|Ǐ0={Dpڵk1cHPˎ-Z\pijՊ`R 6m|76o7/_nz+<î2_R[,9oh?ARRM&[naرݻ7' ^^^`P(DzggFjj*֮]#FÇ JZ@`jR\ 5@y*M!fYc}Y,mRVzj,Y'N믿;wH).{Okɓ'[nŃ#Ftm;wKdz}:t-?N?kPTT3f`={6,#Gs+lz9^& A>í[oVtի~m;Xx1Ο? 7_ ͛{.޽o;::ልQ^=,]Tolo;-hWJ]1F 1H%z3\'eYLoQ^_c˖-CaaEI1Mwqq fh j֬hT*]MCJ% swpprs9|(//ǠA?Wy[BeZj4o\r٣G⫯`y$O/ x<îx/)jܸq.GXm۶ARشÇ믿L+ѨQ#~FFF' ooo;woh:j'Od &.!ވ_\"X,O'K/C7b޼yh4HLLE~Gt GFÆ L<uEPP._,i ڷoiӦyEcdeeǤIo>]vqE 0G}>OazZƷ~>}Â63k,,]  @NGEӦM9C&MpE"33hժ~dff"00[lo?k1Q(2d,Xm۶!##.]„ D%ވ :uBtt41)%/ @Bo9Pdneb,=ӯ m 3j\P[ş;OuFh@6 @Wo@$EEEԳgO@kצos_VSdd$N &Syy9y}j@DD(,,oζJDDCjٲ%lْ޽{Oo6[ѣG)99nJhÆ ֭[GDdFQDD޽aÆԣG?SWӈ#ز4|pݛ7o&""JEקǏܹs)::~g@JII'ۖdzʕ+-[Fw/-\PR;|2˟1#"ڵk) IcAN| T*^Æ ) ԩSԴiSr1'"ݻSbb"ZkPd͛dggSϏRRRqƴl2*,, ϷS#)zEHSzz:T~版… ~'"bEl9!"$tI"":qSJJ Zb]cǎ0 ~:5mڔJE0 RIIBB7oSDDGJ;?B~wrrȑ#Ѷm[AW^E@TTqYb֭nݺjhذh? c%|2"R꓊˗/#:::uB6mpML<ѳgOt/Fvv6>,8fBd+Vq8p &T%Y٨Q#np]L2nnnHHHdggzT§jԨ:N=|0^`믿[rt)J2; ftÆ ̙3sN65ػw/g,8;;#<<m۶ŋ$,)vssCRRѥKp!'J%o:ֻ O(6xO2_ ,yrttĸqpUH3gpuuE^Я_?yx0P2  Fo(pP(T_B)F>@BJ`ٵm F|ʂ_ݻ1tP<~DvY?GӦM1g/HOO'o1j5PXX*VZcƌ |rlْ,䀈8 [)Ƭvڈ–-[PfMPzul߾=b:`ܻwk֬u8ܶb̙8p ;jժLJURڒsג7ɟ-:t(sA=pB 4HtQfMԮ][tG1f޽MlRSe5oCdff #4Gƀkx0 YRTS/^QFKVK۷9gzjl޼ `޼y{.6oތɓ'֋ƼoRSS1w\deeaΜ98qUyx P*)@!80 g| ͍"[:U&RW?~l:200~~~lȦMx G 55wAvv6f̘gؾ};o)@D8gUʕ+Fٴ>Ǐd4طozYa ++ 5j`h41o СCѧOdgg?R@J%P0ppPAұ␎) G4:Peի9x IZǸ8dgg#++ SLApp0d`{_2,A_z tٙj<}T>mPjBcf@DD\]]ၚ5kk׮Bf8?pi"55%%%Pt(//lKkӧ?~(SN;|MtЁk7n㓙]!GAӉF;wvvƤIpM QQQ< >>E0ںu+gR۶m ZxSN7nIIIf>}Jm۶jժQ||<=z\\\(&&6mD...Tn]ڱc(Jxɓ P5hȑTVV&VRRxQ/w|2#?K̙3FhҤIfB^^4c ""?>G}D ,ɓ'Sii)ōi۶mTF ӧOӭ[FIɂnٲŢ,ۙ3g^zTN֭[Ih٬$ԿJIIӊyj/M!4D2'vjj*խ[P&M(##w>.4σ{Q߾}iٲezjZr%{رcE/^$"WtY"{ꫯ^z䶏 IDATH[l1kj׮)̤!Cмyh4k,LPhɒ%TTTdF=ݣhaDy\`,{Sas˜ 2Ƿ71mp25L+yDb 4rPPPwww<}oFF:e;wQF[NBB8::K|BqJ%7n,PPPOOOT*TVM}SX3cq<^]BWpttOJ׋-€RPTTBڵ f9 C3 &3mWUh88!$^K#oR2S/ -AlAyy9qyvBm"ƒ,Bc yѣ*RX/Ə"8::Z)BoS}o Rc$''cΜ9a[޽1˫aVb֩()q2xzԄ{-7Ԯ t^C[o!&&f4~& &H3õ "8{aȎ!!! F]vѣ{iiihҤCֶuYuav!O}2evamPhGC/9gwH %t 4 t:ШP`j1~+oܞdnߖm;,uCzz:߿nݺ6;x>HNNѣGQNYycsz1-D ʴ huVhH_տvW* 2*+%RVGvTnnnzdav![F֭7va1tzsj5iPBSWk#` R,7cOh;;;ʵ0F h@%Ԥ@PkU$#-ȱdC dYJgxDw5K{ z**{81 _6|8bbbлwo^"##0 Zhx0 """0x`#** 'NG~0tP(J4iFϞ=͛7 86m@PoܻvF a{YcРAz{GΝ0 ')Əa={`x0 "##1a?#GD`` єB0km99v"""?V^:7t:/%%`;v-v B{ߗE].GeԨQ D^8(E++S0m4l۶ ǖ-[$e Hk96m1g Ю];3ƪƨ[Ts0Õ+W{O>Œ%K0 }]<}Jh`M{Rz )nc>ǎi @IAG%d蠀#8{w{c?HMVf iY@\5K!d`PƍzbbbkNG]viϟZj{ HD'Ps6MХ7oj*@gΜa8q")J:rPAAZj4bz׮]n:a "ÇBW^y]ƹj^-{ubƏϛo%VZt)dPTTD&"s> 8VJ222ɉ(??ZjE'/ sN3zZ-ZE3|q^k[)}(++Ð!CСCG?Ǿ}5/ 6l(@|RR.)45kKƍ925F={6޽{_=K~¢Ê!66֬ot֍-瓩3Ω*K%].W7n- ;v(M4Mp;{|OӧOJ¦Mx Cpp0֮]p!Yc2m4΋1͛5k[ byָv"##-ѣ`۶mRɕa:brWUrak: ʫ[J/)) gӬ~Cll,-]~$G['c]g ):x_X_0c Y%Hطog[Vſ/^͛7{2e w YgƍWV-4V\;v &MBll, ӧQN 6Lvy)ׯ&M+VC4i`۷#66[o5k 11?qD 2[la~jj*"##;c޽x"Z-233ɹo  2kb"KyV 7776_e 6b*PUr!/^D9iO>\ۚWuԁN<ɦY#φ5jdƍ(--e8_m5O::G*𾲐_ |)++?fX#H8wVX^ٳ~)}]cѢEϡh0j(޽...xwѷo_dee]D^z!!!qqqh4ܹ3o9991ҥKtz쉓'O7…  ѣG "i ¬YеkWɓ'=z4;fBa Ts)&&'Oڵk1~xsmM65 UE+^9U^ G %ÀQ*P@Կ;(5|6%/UV[,AҘM:e]]] Xd {CV3gD@@ƎSNaΝOnݺ!44͛7ӧUK,Ahh(Mtbj3xll,ׯ+V6n܈#G ooox{{Afgwy_5o]y| [> ERwuu9U _pQΟ!H^^^fglxzz)((?Oi_|;b+;::G*_R~}FՑ/^D֭9g޽ѩS'ԫWݺuc=m߾]ܹs'\]]/O@y9o5j؏ƴԮ],{xxqhݺ5z [n:u Ga3 cK.6lfΜ;w1cHRKNNN=z4~7vm?ښ)ګ mMr#f@>5!( (8%(@P0pttq[ lk,UIJ%fΜ 03f@ 0tP{?7n@tt4>3$''*dtAV;wD۶meNVZŻ4q>燺uZ\Y3Fǎ1۷/ju%zh;P ez:yyyhӦ=ӗ[>RRhT^>|ܹsݼys ԦZ.kˍ%l,D ?={oE_b#Rxo Hկ/ј5kˠۇ}rҌ#777v[۹sf͚5kO?ˋ_~:u2a-׮(++ߟsŅ/KyO[A:O<Ǝ%K`͚5ڵ+Ο?  H3r,3BJ@cࠄc%`-W:L:ʼnĺHݽ{7/rЯ_?;Xr%܋W_}[lFcgHJJBǎѱcGt Æ áCcC3X|9V^-\Pv5AW FkP|F 4MyPUo֭[7jgZ/_x""Z׋4ay EZ/A!=zo?JBv8^^^ej58Zj[-ANN$A$vJ:u`6SY}+4O>6lz {Ş={DT P{U5g+=Yg #t78*P*WLIoHQe "+?hMc,]???v9K.ر#+`)=*d4o#GuU@՚={ꅙ3gf/ 22:ubOXz5ouA\\;[nUƍ-PY`胿?۷[W_aL8M X,YYY2lE.Ѽys Zjh4eÇΛ7]t1K_~=gM6Evi&C޴~Ë'f/oߦ{; ((Ȍcԩ;*1Ǐ+Rl28;;mW~:V\e˖qggg۷oh4;w.W^Rq[ 1:-a@IIYҥKAD?>4ibF\5 ϟǎ;xʑ/5kD||~ h k擐s,bհMm2h 2ei\qq1Msqq1F|Сx1␝,L2rffzݿqLgdd 00oEZPRRºVTp0O>X999x({AHHtR|8uq*Ry*d]" mڴ=\4X =k猘[Hk5`0j(e1}gZZ-FF Шr @k=\X ,ȍF* yYA9A^>R[ 0)ZlI:u &e˖4aYwܡaÆĉ)44fϞCܾ};5nܘPxx8{?Ν;y_iȑj֬I1=~Xr7oL͛7:uիPTT{qFruu>}͛79y:wޔ[СCٱ=z(uܙPi׮]sNj޼96`0`uޝ\]]͌7DDT^=pR(Ԯ];|rx+K}O?};󸨪   J.h@jOL E255-Z暦h$R`Kn!b ,insgsg_ysssg9MCyy9Qf_zbbbt!tԔY[/LəJm۶%ԡCڷoД)S1 C}'߽{(66^{5ڷoO;vsB(00 DC }ĉ)77BzߟN ,#Gҋ/H˖-c-Zu:<}Ҿ7goZlIst!թh>{eH$ԲeKΦӧOS@@IRׯurwwgcfddmtR:z(縲.^H4|ڽ{7 8o]Y222SNiD 6'Oҙ3gחlmm۷o''''jڴ)P~(<<6m+ݝ yedԤIk7Ody+td+Vкu ^{R2h#`3B{+=ܲ)88H}.]=sj\oyz%G,ˣaDsO-D6ҋS#Y[m;A j 3k8i_#F GsFXo }b@F?͛7ݣ .]T*E-7P\\lr{mPQQam(>Ē%K0k֬L8 .d;ddd\P(FUu ~wxxxV],g" /)jxTj թSNYM.#77ݵk J9-EJ"B{ky{~sry)d۶mCܢ:N  IDATC W0% n.puqS}3`ˁCѷo_MpBv?+5 Y:Amh/53,6UD$ 2224u֡cǎb?D8::bڵz"w"iIjD!@*$ V H )V_\!!RMX 7dhj._zٻw/BCC0 """@lƌ`R ,@II 郆 _~:t(R)0dDFF)))ٳ?<ATT =z &&?SNe_RoܸQFwBm4v{v碢[o_~eЩS'Y wH$xp]l۶ Z0Ƙ1c0zh$&&"$$ `# àGHHH@\\zpdMKKC֭0 |||^믿0m40 q "`Ȑ!|rtaaa8{,s aUVaϞ=hӦ $ ~GN+W 11 `ر/тǣK.HNNի1`K޽;oC;mum64l7n|ڢk0'5u4++ aaaJyOYf`|oo6?۾k￷ZAO;$`$ $2 6RHe $2@"QIVzݕc]jB[BȜ>'0kK-@|#Pݣf͚k׮%eԺuk8..:uаa[ʕ+#"Zt)'OJǓT*t6\.""z={zEaaa̛^=MEzD )((F9JBBB8璒8m]!C1`͞=A4Qͩ~r͞=ϟzۗcJEC [p1G!4{lI"Pʕ+JZj9I4i$p7o ǖIu&(--kKKѼy%39kθyX[G-ZDV+eeetݧ(x~w{DT36OOOZxUˬid߉TM`7ޠ/Т4wwy.RDS1%V >LfmfY͝!T Sf x#yȼh۶te;@Tr~9z(:w ppp@HH||m>VVV_GNI₹s⫯Ν;|m-Hиqc9ݶ`cc+Vȴo>N^gggl߾_rrrpL> y&~wTUU2$''p1m8f0 XrrÇ;,X=pРA0`{lXO"?r״UUU!>>O$6d2Aᅩv 挛':j!] {{{xxx-Ӧ&dzfeT*D~e2G8p6l< շ&y}'b%RB&a eTDTb/q23!ScVT.],{;vwxyyv.6洇&mVV\hz o-6uTF6ϟKZ֭1c ٳ))) "L4 ɂe0x`?=z@~~>#G \g,!_ҥKznwϞ=x" eZs'gFʡJKK1c L2hܸ1gczz:dDDDܹso+WDrr2K.Ezz:v܉7|eeeǤIн{wk~CyZ?M6EVpux#GČ30g!33%%%;v,NcرlY;v쀛bccQ\\#22-wҥ agHu֙-zjuH1t K.lٲ5jvP>}\paaa_ 1yd^~~~7]SVV> .D||<>ScիX`^xGNN&O &`Νh׮ڷoǏܹsxаaC̝;cϦ;?>ƌ_#9O]?nݺaȑ0qDxxx]vp y{1"LW{߉TbF,N$ A66=F6­ c'ߒ9;_2 K| 0TczI[Z`>|iԨ-Gw%֯_O(##K^z%z͛l^xT*'QxXz0&UmذhZ''' b5mw^9^|9iӦѪUh4bj׮'ݢE9sܹC7n$7770`)J`rvv9s.LD冱D[m>>H\NTZZJ*ƌCFKDԦMzȑ#OAAAoӧՕBBB(55ƏO׮]pڼy3{0b G=(!!=޵kjKoΝfl+WmstHc_N7,bQ"nݺQnc\N{_'e˖ԲeKJKK< duO;Dj;u9sЯJD1PTTDcǎ%777o[nQחRSS D͚5d*..y*,,4gSu#Rضm7={-,&Ϩָqc 4:vUUU o+S}Nr4K~{V\@ߣECoWLӈ&Z;|5W^2%s͡^2K7U#4;{,8:֭ТE 8q]t9@M`=L8ppp0*^///4jTQFرcزeѴ666Xf m6;"w^̟?eee0`,*K90FRR0uT9rDﺦ_᭷B6mvZv1}kDиqc+ /y!//lmm.rrr˗?]rosi͛P(k.lٲ(,,4^y5;w'uz&j׮,Y/_Fff&y >iii8z( 11RKHMMed߿Ԗ|3$+b̆qww7 uUݺuQ0a~g~ݳgo[Yfhݺ5"##ѨQ#t֍-۔k;˗ xi&5@Օhݺ5[[[?ĤI>oݺ%gSu;vٕ 9ƢshӦ _'Ύ.!!'|[na&;FL>K}'R}RHjs1Ԏt ) VYNW]Hp鴗 o6 ;w.ZbÇܹsXjk;w+d/tQT(((@ӦM`?""{+?}p駟⫯BYYg1^x! Z녥R)O'OӦMsalٲNNN0`ܹù޲eK0誴cǎxWo&[0 Ν;07on޼O>)$$$`/iXr%`׮]F ika8:.|cرc=5 2 4_s\]`(6BA,t<ۑ#GioooяׯGHH222py$%%q_㚥ׯ_+K_;HRJAPAAj#I˽Bȫ8 BBY~0Bo1r?0uԧ-6mPc|( :iel֨QF=|#F?Gnjl^ʾk?#yl۶ ClkԣI&ظq#z8?$$8kεѤ$[.Y4Xr%?ΦꫯYf_z0ÇADh߾`%)QPPb'((2쌘lܸxQn]l޼<<;XV?Kd6_?m.QDѣGc={6***d0mv76v߿l{֐\$AH? ϦvܹsDdT :DYfgϞ?>MGGG8;;ݻ5֨w"<( TP(")  % @!@ݹ.CY!?b,x06[0u\NO@7o6ݰasaghck׮a͚5pɒ%hѢ.\>| r΅W/[R B9׫W/L>'NV GTTRRRfj+.]Bqq1:ulv#Wnn.nݺiӦ!##͛vO?B޽{PEpp0NbAPpb 6 ?/_aÆ!!!طoY*,2kccA5:a(//رc9t|coP"qIFH? ϦR)qU7ƍCǎ &(--E1b k־1Z$#Q/c$P _.**)4յ?xb1us]WyǺǏsRVVf<(((-T:yc&|?~lc=Z/aذa8|0o:HNN̙9?Grr2ȱC޽yfNpPBap)urbĈh׮P^zoPZZAELh˖-xѼ BaHo߿oٳgk׮z׮] GGG <\ӌ cڵ SLMcs GO@|A֭[IH;o~~>JKK#VR*q J{.** puu#^z%yfj9tPg̺yJJJ6BuԸ1T:ƣGpe{MtT+ ۷O>2$!m]QQ/4veza8v=QFUVGPVVJUmPYY`NPgsƳ 4vvvƝ;w >K辝&LׯW^ALL Pz(/ƈm "%TJJErr@*Z ֲLr?AXeNH`Vm/sma%/sRSSm۶:t@#"2e  a裏>~7JLL$H~)t;v@@]t~Ih>\EEmذ<==Ɔ6n`s%bg*6gΜ!DB۷Ԇ4`ӧ}4yd ֪Yf[oE111tqN-[P-hт^{5zר{@NNNP(hԬY3@=zGe̟?Ptt4]xQƍ#TN?> 6-[Ν;Ә1chΜ9ԲeK3f ) N:S`N=~'޽; ___ZbP-瞣e˖y;_XXHo6i4rHziٲez 57<==i sCԶm[6m^z:?~Lm۶:udooOqqqt˗ӎ;hѬ3g$4x`*,,Sݺu s#k׮%DB-[l:}4T*;vƍޞ<<<8cŋLϧݻwzu2e ]v=9st0V?CY"<.\0!SƘ̇"WWWjԨM2yѣ tT#GpIedd?K.J޶>|0999QÆ ɓt%[[[JKKmwm];UUUw^ GYYYc --:uD(99ɓI=:tnܸAf̘Al ӟg"cwDM6ׯӦMb󳠠}]6m͙3iܹ4o<8q"M7F9}NU@QnӐE.?-˜'j 01ތFReZDzhkmIDsU8uoc_pww>Ē%K0k,y.\0MP ''52a@QQ\\\cܼyO )PBD?PQQ[rկPtgFyy r666PTH$(.. իs}NYr֫8k)׮]T*Ef ^x=6)5j !!TUUATnݺnh.QXz5|||)HvmveCcG޽{ _S%㙯n* EEEpssCEEѥ}BqPPP븄O^ScBk)Dc۶m[TSG=*@8{%\.28:ǏE߾}7 eW)(u+U_9CNk47킳`1۷o7k6L2~~~HLLDdd$֮](e2U"w$|m/ IDATHRgV Oa-,a,~5WիgZ[͗뗱~ذ?tGr Ə!cH~3S2k7z:$[[[C/z|b-}쐞[ .Oh[kcuu0Ac6,_> _?[2&H2^O^ScBk)D,C JI@`rJ @ PrM(gh)vm1e7J c \z<"f狍Enݰ}v[k ڛ0ERTs'ڸQ?kk1vXxyyaڵ*,"R P" % W)V=ţT{CS SO|?چ7;b1ŠkkWBIT*qc 8t}WZZ\tXS2Ն>OUO/JKK9 eqP'IQQYq O7ܿrssź)..fFzQ 0HA A&lm)psD{KEQuSƑݻ`HOOp9c 0 T p$"++ aaa5x,|ǣ[nXx1Kݻw7Zc֬Ywoo1??N8 6Pmۆ bƍfIOu1%Sm6=k7ƍ ipE~̙31uT˸qF޽{];uf̘{b6l'uff&z&M &L>ǏGdd$1| 4ȠW_}6m3]RRa?~U/"bURB&aƏTDTb/!2 YAځY׮]Kh˖-z<< Z;QʟDs o۠ 6D f"CD.sttսf1d2ǝ1rÇ+.\xlĉVmSUUx>}ZTB7W* JxO .@TѢE y8 6^tXc2=>cGڤ73rrf͚UK&sJwɗ| ***/w !!!֫J\.ѣGsprr=/?-[DVV`׮]x"""شiT1==|onpՐv|||кukԯ__P?C\tB҈DR@"a I!2Hm8s^*P*#99gΜAqq1-[pAyKJJׯ_GÆ z!-- .\lMúuuA^M4A-L~ Xt)qܾ}o6m?Ǟ={hiSNa͚5zԩ7//)))عs'222L P2e sq';;ӧOGnn.VXGGG$&&b:t}n:|P(7n֭$uq̘1nW_}ŞW*qF8::"55~~~u_v؁#FK.lI&m۶XbxbHOOoy\S}KYY͛ggg>}ڵcg:j(++ĉ7 )))\.ݻvZ7}gl_|WtdggC"`ǎX|9BBBL=p9Ν;r\|g6:͛???>22R/O-@HR;44J5j7x())%K)w۶m8v;xyyaŊT'''t]vŇ~+$9HEe26Rdj :لm+5䊮#`Β9_2d dn֭,X@|5jDlZ\NTZZJ*ƌCTXXHDD_|yzz鵏U*͛ٲ(**S(%%Ț̌ʺ>lْZlIiiiGoeJ!!!JǏk׮T}_ΩcQQ;)**mƶQƍgϞ&k.JMMKZDjH$&zRMVVEGG }gTQQ^kӦ =tϧ 5DD4l0GvbTy\WF>4D=ԩSDDt@39F\Bڵc˚|>c5κtAO7 =z?GUma 2J%5mڔΞ=KDDΝ#O?i233 ޽^JK._̙3N:4j(Nb rpp pٳŅȑ#zr I#"b ͒ޢ/вha="Fm}D'Z^*1w\$K^?KBϒ0d9Բ%sB't QmΞ=p>7o B]va˖-ppp@aa!9b={ 33qqqK4=ztZ\]]ѬY3nhԨu놜N9_ڵk#&&K,˗ya 2t?,gggKLرcHOOGϞ=ٺi/0w]voӧc˖-lEK_(.\@ll,:w6m8q"8zΝ;ݺucդ>@bb"R x饗*ѿA sS}qeylڴ qwwMo6ҹ7+/|'uߏz3ND+Xm+]lmmmPX\|`;RQQ79.((`޳vvvѣڶmsa̙F~xhӦ xb)))VZK/^aÆa٘5kV\gϲ6nFBff&\\\pBwrr̙3q-tڕNڷoGH( TP*   % @!p1dJȪ1t4w:X~/KHHܹs9/L4m͛7G,_cpww<4_&gϞej6A˙:up+|j+B|u:rٵӀz&[p!rssѺuk}+mX~=BBB.hРv䄲2uN:to iii 3Pcǎ-2d4hL$$$` tR\zYYY9s&-ZE믿{n{L&C0m4( 899ۛuݬY36}~O ϟ7O7ozbeNSKF^>HP*@ \Tr Cd,}u^!26c溮tu?>|"h \.GAA/ d2rL̓:e o#luQ;wΝ; "=#J<x'`pww7?tPf͚={b7ksrM#a⋨[.6oތCB3>ζ~Bmc䫯?f͚gȑ#pssjV> glGGG8;;%XVC^^K\ǏiӦ:JJJ0 gvJ˖-CJJ ٳ"%%'NdӨT*_|7cӢE v?%!$$a7omLf4Cxx8;,݋?9995kƏoQ>P J"@@P@"3Dr% WAb`*vбU5i~/CP`޽&p)\^^ ѵkWDDD`Æ {245UP^{T,< ,> FeJHLLիW1n87;v?,(:UÆ ?HHH@jj*ۇ.]]P___ܾ}^.ɓŭ[0m4ddd޽{ؼyXz_m,L^STko߾Rt,yƪcm3f`Μ9F cy_{5ܽ{c<\t g-Bܻw999G … 8AX{q 7n蕷tR`:A/zP(hݺA222XGBgtCE>}p-|GWH!0*@IJJT RU*/T$f 1kD_PٚKZYYСCC 4nBNN&MĮ.//JRPYxW?\v D|TUUq!_}M4}1zh\zuWA}lܹs?6)ѱcGxyya…X~=;Ci@RF.'LׯW^ALL ~wKKKvi}(888x饗͛s^Ngϵe2ՇWGza8v=QFUV)))amhҤ^OWoteCt @J'N{EYYr9T*oHoaɒ%gǏ9F棠}]6mmٲ$ lْ@RvDhʔ)t5x̙gue4ه:BDw^ GYYY7 .-_vAGfjmYglCj9sP`` ͝;͛G'NrzUUeǪv[iix1mۖԩC=QUUo^"yy!dˋym9s&1JJJWT4sL?~<}W4p@}6{o{{{jܸ1}G4{l\pJJJGל4DjρڷoϛN俋uӽyɞ;4;[Mئfg}vh~Tf &s\I׈HRctےL\\x{{nj6Ƶk J9%u¥K JѼysԩSⲌq}Ass꯿2k.* EEEpssCEE^UtNP(JѥNLauup=A|1R HP\\ X-掝ԛc+kĒ%K0k,AE[l۶ qpr%PQ#kzpqgW[wGeCѷo_Mpj UO:k~9b 5LD ƌqdi5f'FEDDDDDDA())1B/n:tѬ}v"4xJX+.Npn 3X(/.&s KP-\缡34D~2P|DDDDDDDj=z ,, 9rh P,d "@*$ V H$a VS_\!c{t;d-/sӍ7$t9iDDDDDDDdɒ%puus=/i#RK!!02  LjockR HXBh">A>,̝!"_fg!CHq$[6YDDD`@0 $R( AL27I !oufEUH1eVRB&aƏTDoR@"G1UffcJO8q ĥK ]ܹsl 'r_>=`k JKKW#eĉ'fQXX 5[@OQ?viqJC A"@¨I@!FFa*X $R+ue=o(Gnݰxb|ӧwXQQQx뭷/`ҥر#VZ۴iDSƕ+Wa0vXO>hذ!뇡CB*C Add$쐒m۶UV`3f FDo߾5zSh׳gO-ZYYYdkkh'DBק+Wp)Jjժ{GEEEq:uhذa\ IDAT[iʕDDDɓ2=zDC B#f=233Օ&M HDyfjР{lN׮]Kh˖-zu֭[ǺzƇvS&M8 vJ*xzzŋk-"-/=*++wZ-k [? !:gux}` !ƍRuz?E4Y|{./Тh|#NYњo"YY;h fY;C$tǘ˼j#((:ꊅ 8q"Zj@=믣SNsqqܹsn:ܹ=/H0f0 XrǏꫯm۶GGGuuLiXo |A$f=4} 4h [u>gN7ߠ/2{=!!}]ʵ62LߞU -[m'>ӧO5kցa+HĥOM"0~EH[ա6)mfͪۆm >6')@*@"(*(H[HUl|3?{,ʳDBoΐ ҥ -- .\oa4*uï\hz شi缟k\t #F\2ؠcǎiN$o-S={ŋ0`ޫVbzk fϞ:L{ssΡ\\2رnnnEqq1RRRH\~xbtKI'Mݻ]vzk0qDxxx]vp{XSNaȑ1c̙777[N\ff&JJJ0vXL:رcQVVfLc޽Dhh([_8p ==IIIXd """p9l>وBPP~dgg#$$7n| ">>~r0p@̘1SL'7n4ҥK;w7իW` l|{A 8'Oի燀ܸqCOѭ[797SOPoB_jhrӧ[w6ӭ},$*(JJ  U Br0dJ]2'wɜL/ky𒹶0d7.#R/q#g:;%%dUVڰa4NNN8p,YBDD&L h"z>}tK˗6mZ/_N#FvqM/##CP:kcܹ֮]wWOii^zoݺЂ ÜOF(<<^gDDk֬m M:PTTZvv6Gk у]vcA.Stt4J1cƐ+[^ƍ)88رcO>>>TUUśJ!!!JǏ;wꝻv͛Yyض1T9u7UQF]RQQA 6ÇLl/<=3zΰ" n➡_45憀 n&/ rbj(K\3 PT 1ŅL#DpYܹsg~s=sν=9OSQ9v_M)))|0Ξ=KDD?3Q0?\]]ӓΞ=KO=z;n֭iҥDDt}>}:5nܘT*`޽{:t@:tL*..;ĉye˘|kͥ`rvv>d2{"KEݔ{/ǏӍʵ:-.X(}4&s;~٥p)%eb R.mIrd]t&sɜ L0󿮣%١Z/rvvv7FٙL;]钒pǣG&}7 ݡT*qm 4_We97֋{}̜9gΜ̙3߼<vFIfd2Jqii^D(JHRkQSSdee?ܹ {>|8)_`` ?Dhh(p=۷ !C޹o999:ɓq 𦣍2L6 ׯӧ닌 lll͚K:99ݧo߾7nΝnݺq6'BAA||| >3mh͛7G@@wɒ%ƅ X1Ɔ cǎ̡C֯6ׯ.\+[_~ ~vB 8a,iϺOC{Ur6`<{6*:`NLHP J"@@P@"+ C]kOacVc0;s?DhX///lɭJBii)x[[[#-- ǹs_СCym늺,GEEEzq{Ç̙38qr+1h ι4Mo[*ɠDDDwѣG1p@\p555dw޳e˖h׮]v C˖-5f+\"N#...P##yyyMGceҥ |||}v"33+W~-Yyyy@~~,>b xyya̘1H<>y$[. QQQeV@@lll_s,~)lݺ'N+9/%X"B>=oM'o1v^,{JJ:.+bآ1VJTJ _RTO} E](D^eń fȤ½|a5Ǎ7x@PnEۢE رFXX^z%SkK ^+jSnݺg6-[ѣs`X6l!C`ǎpttĿ/ԫW;wă0rH6G@Dѣ舆 \R<|Iԩfm#&&Q~}κ%Kk֬?}L&M?d7w8aj=֫W6஋رcADXp!K"""B/o"O_>7uQ椧ou*PiRjE!2@*\TJ*ȕP($+v-Qu`*ф^duH榭 U۷/m6ܾ}7Lyy9pܹn۶ vvv5k{NT94hΝSN=/&k׮Μr!((۷oǭ[4Duڗx ۷9_.]ԫWO0{ڵk1a?_52228m۶ŷ~?( {M<~={49.]tٳbHd2İf1zfA,X}͛79 \.ӧMK.Ç/d.W,RѸvf̘3fW^8v^X|Zx p7@Ի9i[].Tg [L?wR5J@`rF @͟HZ{76ib`2"sO3{*ΖRRRP^=5 w\âEsoŊ ",^ʕ+Xz5/^6mڰ޽ˮ&11}5'Bj޸pV?~I&{OOW@LL ;5ʱi&8::bzm1?X5q5֦"..u hӦ vުUx߿&L.((hԨkڵ cǎţG7nի={6k ѣѱcGqkjjLtύ98t{.77ݺu믿n0*L:׮]U'''_|0YRgggPRR TVVBR_LƎ}+Fmmm;_ŠAص5W\aX"u%u Urjh#&=pEBuWnmP\ Q)UD+(VjD˭cFe5u1뫨.sQPPlْƍG3g$___7ocϲ2 POwߥ=z9oN^^^ԤIJMMջ[hȐ!z/\@i#zZZyyyP 999Bxj7vtBFaÆQ>}ޞ\\\HR=rܻwLBm۶ZlM<Qjjc7cۛPϞ=)##JKK)..0h"1c5mT/4tPJNNTZz?3I$ѣt5Qaa!{<|nJ#qFxbر#}d5k=yh;v=]xtBK.oFPK.0nBeАM˖-㜫"oooѣGӑ#Gޞɓ,Puudgg ? ʊZh˜NڴiCڠgϞMs̡ РA8NϟOhєI{&LՂwߑ5k֌N>M?3yzz effա)򭡴~m3gE>X<Ԯkϛ?\=mPzDmMM ˜ ՙvuwmj㚚awTH()-+S7}Cuf^zjS^a ֥tׯ^ЮfyAwy|cO2M60'=Cd`cB'Tv:3Vn6(CXIHH6֐ZK!RH+k@T{s6K0U!29c62n ‹#D+OT*ܺuݎւ |>Im0`}QVN2x,۷o4r(9cBeeI {V<~EEE syQ]]K. gL Fseņ #+R)@B#++ :$mhHQm"3?AX|A.^ݻG||)ׯ_Gll,9_]] 0 I$QNΞ=y!==֮\tػw/N:N:`~ꪼBaÇ0o<0 Te˖o5k#F`رJhӦ [[[l߾]tCW^0 BTT !Cرc_sʠH3f $ ov{k׮E߾}닼<';w aiӦaԩFn0l0W_}ۃa 0ǏGXX#GԺ"""PPP ӧqF^Cpbt!ːH$طo^/_Ftt4Q\\,a<>}aL<`Sat{u!.\j*III171رc|.u]ϊݻwYfرcYKDpp0Aaecr. ›o)))ի6lJ kllѣ bׯGyy9̙3ѣ6mTAei?MBdeeq](**۟w6,Z 0P R+I @eNHq^+$|X1kcs 9fE-޽{Zhqշo_JNNhhРA˹uVڰaA_5Jݝ='$$P||<{\^^Nvvvc+W.k2`7mD(--M/+uڕ= 8 &_~%_^t8"@O&""JE3g$TJU&2(J֭ܰa(,,=VTE_~%{.))/ ?!>"DQ,W\!ahԩPFhzNwI 4[,H$K/˗9aJ%uܙ=ֺr'n}Qii^P֭ XB=QYYIof?cruu5xl \NDv&8vXg*;&[6n?:ԭ?c<~VECNhɒ%f7u,1 %&&cJ]w%["3N:QLL 缘YRIuMGG`3ٔ.ݻw) 5jdrׯSllu /ǬfZQFSh·N4Q%6^s:Y}cVw<%Ǭbf iqb1Nl>sd2fύ?_|4Э[7j cpp0|Mxzza R q Ç/P*}c>.]$|SN챣#63g%mN`oJ%+Qe*D"A9~7\r555=C4u֭ >6mڄ3gbOmr9bbbe˖Dxx82I$L6 $$c HкukXl[ʝ|2Lk߲e F)cmİԛC&5'N@@@`ƍ(,,D֭ѵkWKo޼M6qfj[ ֟555O?d= XLKiWCuaϺݵƘ1cлwovL>7oƁbf]$ n݊;bĉ>jjjuq+>jL)]>'N|?Kt+) IDAT6l(nP`$j9FPVpCd(|mA(D Iw|8{\RRٳg޽;k-H0f,Y9rssiӦ6oތD( ̘1 .b˃>}_𺵵5z%:!4(gѣM64+o;??0h [UU"!!2 [l s!\x 5+S6me\t &M\ӮOSZ[ѳgOte>>>Xv-g=JBFFo]c鈏ȑ#1}tvMͭ[гgO̘1>"##ѩS'dee˖-ë*X6m>$Z 8<-w_|t41y!44T9u(TJ{Xb"""|rЫl5 .6n܈6mڠ}~: %%Ɓ0qDTVV ڵ ׯGrr28yV*xѲeKtܙ%55ڵc_MEw,15=s3H,Ϫu˗{}>=g\~}l޼%%%x7z ۷g s.wCرÆ 5c2hH~"_}ݑHKKCˆ7o  "%TJ BԦrr@*j u?/~z 77HՉ/)駟н{w{(((@EE1yd;֬]z555ܹ3@P &&Ά.^t)뇱cbҤI8r;C0 O>III.o||<_ooo"883C%\8<;UUUvm¢EФI7cڴi ɓ'ѹsg޽`cƍXn&O'OS*())g}X|0Ν;MbذaXf׶/Zj.\` ŖiĈxw+WUmM:Μ9w|HOOGpp0RC" A˗#-- Νȑ#OO>ŋq5899a7Ibuu5Ə޽{#..AAAHLLA޽gn:¬Y A!+qƲz6lh3*sr9ARBPFF%MrZxbLp*Fs*XzmbϭX^^^.@o>@-[]vv!,, -[6ovrsspB,^b R͝;o60h >\og0?^t"--ͬ!))0z Ts"((3gf| :ԠMQXX[V2 NBII R`ccNtxի3g`ĉz/$bMp;wάrx뭷`|􄫫+4h eFS漼{ݔ1P Y1uIʼn]ֻ ƏpDFFbڵA899)cRƞAbyVF> تRPZZgV%vl֥s֭[1a̞=L0uINNFtt4555RԨ"nL~d… {ٹggg ] EA FI@`rF @͟HZ{76iΔ"c#97LQ˖-/0 狔L&C&MqGII ~7#d2уsqq,rLLLDttt[^ 0`Μ9 bf'՝777WrpݻwgH1B#FIzjBaSذaϟ# ƍCFFǯKn7CBgsPEرc\L[[[|HMMyrrcw VVVpܹŋk%K`ƍHHH@@@%ȑ#x 31cBf@p[B{n+ǚŴݧ~e˖aϞ=sw`.%OM]{³n]nܸ{ 5akkcΝ(..?~diqcr>L?~I&4ׄ_>>s<~&m[aڶm=z`˖-edӦMpttѣm!LwmD`vg4_~fΜ txȑ|[nxסR0m4k*{d?yR}QN:'O ==طo\իضm#ԓ'O?s>TUUaԩv효1Paн{w=Ȝ:*WDDׯѣGɓ8qbccٗldPj ggg'v3oooEԲ=>~cI&LKĤ7RAAAA\]+Vf`\իWchӦ c..\@RRg www̘1;wژL6.+7o7n T͛}!z"={ıcPQQ\zo&1J___Q`+`J CBd @Ja_͐11AD Y@cV"b:t(%''Sjj*^M...Ŝ-ZЙ3gH&ѶmۨiӦdmmM;v{qCjذ!=yD[nzrqq8h;w3iÆ {Qaa!>};믿ʏPy())***&DB=z _7={NJKK)..0h"# .Ptt4 GGGZ|99cO;v$ԧOo+ē'O(,,<<oݺEC ;/V&4̘16mֹ! gرl#GP>}زi8^xtBK.oF_@`;w.ӂ ̙3Իwo@t ?|ΎFMG!{{{ @{.sΑ=5oޜ-ZDT\\)Kaڶm |deeQhhh밪`jjj(==\]] iӆrss/++Yftiӓlll(33ϟOht=_uִvZڿ?M: D":йs觟~ۓT*y6裏 ֟)cPz~-ߟ'[;3̙39Y!($$BCCO>w}z6f]nJJ{e_xƎKPloMeeeil 1K73&ӆG,qQjԨQ\\[4`475lڴ36Yx8fM~V.JeH h^,X0 yg)H$`@*$*VVRXIXY1Zi:&:h5%Qr9FPYYiR:+O<1Yܺu %%%#ȺrZ֖}YQZZظq#kNy.**:t[0ĥKkUUUۼqkؾk*~% :!!!h֬On4P_EX({Xv- ___.իw^:u :ut\ʇ:^㣱.^ݻG||2jÂ;j}Zcp+a( 0C cDGCII """Я_?\k֬oEAAoGJJ z 6N/C"`߾}4._h0 ӧψ`L6 SNEtt4uVL}ff&0 ڷo 6<1WN3`$j9FP\TsψlM(|m11k6cP;Ujv_Y_c֡U+W04uԺE?&WWWQag͚EիO>PVV'lvv6ʼnJiӦrJGh͚5_vJ?^J}6{cY""\NDDTUUEcǎ|q ~***hժUΝ˦% ˣAuwww:z({@#"Znmܸ=66mD(--M+uڕ= vvv4a/׳";;;*--KԺuk@+V`'%%,1t[W6߮=4PFh$9vI 46ׯ_X։-ߺu㛋n.iy IDATTUUEDjxc}U1c.Æ 0XRQTTldggǶŕ+WDӆΟh,wR-8y߾})99`ڰ<<\]vqݻw:uD111YYY$H襗^˗/s)Jܹskk(hJ?~Pbb3i]>ihm/#%q-JJ/Iߧw!Zt D#Jq̚ÎY_c֎P;faǬ //Ǭ01k]n2@׊M6a̙ؾ};ˍ'V [YY޾߆D"|a0am6N={`̘15GGG߂DFFb޽^x{{{ց^MM """O?qœ8q3]rhݺ5v튗^z zVe͚5󃃃fΜ: 77MK(>֭ZjWnJ\'N>|(͛7i&,u^3g 7|px{{qCBB ɰvZ[lѣT'ʖlul*,[L?Fdd$k}y@Æ @`` ^}UlذAls׮]>}zԛ>ud27S닗^z -Z0W"f~Õ+WPS6Ngx^X>_~J͛`x>y!3~x|'Ԇ...f}cc+L ୷ނR4cVFb =fBΝMƌ޽{#""|6oތ% Ma1QH$zNM [~ ֬e)e456rZW8!{0*@IjJT RU*t$ f˜L](D*(&ILUU>|d2lٲE/Lff&Fy!..M6E͑):%%%={6ݻs_nP^^\}/N xE ׾̚5 ޽;~;wƍî]8 XlJJ >`ĉw_|td ^^^h۶-{,T$ ƌ%K?Gnn.1m4q͛P׍ՙ ^8󃏏֮]YRA:ObЕ ]гgO˭Cŋ7]۴Xڕxb DDD`\^^ӧ#>>#G֖EDD`޼yk4Orرso5I+ٳg1yd̛7/Fƍ]vaHNN*Kvv6Fw}7nD6mо}{\~7M_wppmذz\Č=0`iӦFRRVZ7oތD( ̘1 }y;rڶmykӦ Ο?o/mL"Ŏܾ}z zcdff_~q :8ݼy3˗n>sM6زe .]I&q񽤛xVY2gQ?ڲ={̫!95g9/4*sr9ARBPFF%]KT]#;RL."1'TdΝGӦM1l0YFO ҥ {ڵ 8p6m'B@LL  ??? :0""7n_~%fϞ*޽E_7)]v!88{EEE ĉׯΝ OOO2֭[_gFfM63999ݻ7nQQ֭[Gaȑx"o* yyy2e '_baҥׯƎI&ȑ#3D0h_,δ9<;:3gΝ;t}{Zʆ.'OD\\/_nݺ[ nժ޵B\pUVVM{ذa1b0g$$$4晈0h cHKKùs0rHNN:͛aaahҤ gfh۶-;o+++۷| ^y3 4@rr2bccT*1VW^y욧'N@*bҥrhu@*22 8voeڴi ɓ'ѹsgv P]]ǣwވCPP1110O$-7o'^Q7%GGGr=+辈iRUUEI&7n𚵁4h_[y988ɉ]GwyiiiXr|~ظq#֭[ɓ'ɓ5SXEh˞C2m3N蚩/:R5J@`rF @͟HZ{76ib`2"s/> ϔeddLk׮!##͛7СCW_}K,Aqq1.\`.;wBܻwU~ k"EE)_|H?~<?7n@VV'Ν5M"zkذ!:v쨧4352V0wlKJJ/yڄwqq;WASXEhޤIDg5S-_tTJ$*A % jEkPaL?d>ԼeP|8HO:R`cc="a8@@@lll>Ԅk-[]vv!,, -[d899!00w;777"22+V+WP\\"#&]m{kW˙3ge˖8p 'O@ti8pP99r$N>wΝ;oLKJJ ]\,\/;f͚~6bLd,--h[o o'\]])_ Lg)Fn5tx^za8s &NSRR83%*?#\\\8/u!_")) k֬kgb&ՓǏGxx8"##vZvP}ĔE=8f͚a\~Ll  2"2@ '\+$EX*7m -{9tܽ{DDDcǎp`vɒ%ӑ'Hz&M{nF;Fd޽{CTٺukj 'O4] 5^oFaa#F`ܸqرc&NCOff&jժWWsQ@jjٛ{Xx ##]-&&.\ 5jU 2`KKVe]vmq{_vWcTZׯ?u݆{XnܹcbqJVsު 900D'OnYYYqNN5cƌF#x&Xۿ333q-L2ƍYX녅S[ԱѣGf[ǂn9}4A`cS*(_TTo*`zz:BBB8ڞO[ܹ3:t耵kײL1退 07n}vZrv1z聩Sرcf+}ڵkꫯʣ=<[8kug:`͚5T^EQ1S预\)\@d2*+eHC$&?"&XM\F8<3\R@&Mжm[YƬdeeۇn%%%2d|Njߴ.Lܴ̞(_xx8i&6޽{hsci<1p)՟ݞ/FժU1p@1ٳ`ٖ+W`ѢE5kYwӱ@||<:wlnC*,,Yр-e_c5/m=+ c#92rE "GjldaV/c\ìf S(0̺zjH~:ڞ={qzIw!"vQpp0M2>#ѣǸT &xb*--oVJVZfM ,_vq|2M6׿Xf͢-ZЧ~JgϦ &PII ޽BCC jՊ~"":wEFFx_EԾ}{@ .R1cXڵ+ݿӧ͍ׯO1SVV{_~!BA7`CZbx"tb֮]KDD*֮]KޤT*iIoArJ6m]v\ޢ֖?̶vў={ݻ4qD1аaUVϟϹn: ڵkӒ%KX!CO:u"@[l͛7S@@@8p Ӈ:uDnnnTV-3gH&Q۶mŴ}>|66l@Kǎ7n;yyyQbb"[>rsswޡ&MP\\͝;FAGK,3;99ԩCߟ҈h|E 9sΝ;if7|i3X|9^ZP^֯_OnnnTN` ח-[FIII4j(h4}W,/$OOO[.?~Μ9C~~~B)))7oޤڵkSݺui锘H7oھjXGͩcǎ4zh5k5oޜFb &WWWEGGÇ),,׬YcVeTG)eE{ Ғ%KhѢEvա1b15fJD-Z ԩS'233{԰aCz7iܸqJӧO730C(/>mRRRǟoΝ;ԫW/EQQQԵkW OOOVkhwM]v%G˗//1eرmfh)<$vҳge`uw7ilZ/%P/3i؆>%%%fZ,]CV#335T\\\ U|s {.E 兓'O(,,DNN4h hCF )ݻg(J+"##dI[5=zD̜9\L!"PThҤ`89996*vr9>}`ܹV٪T"Gj9t:d2ATJ2+!:_,fm_o7oDFx[jqZ*CHIy'2C.iӦF+WPNI|YTZ|XG{(!"T*mlY+&iܡ2PiWKQj<5XXnRhFHi!mK:B1!yR29Y@bʕGbbKٺuG"?0 M"kfƮ>!t|0ada H-'f"knl90/dDђek=] iqsscDaܧ%7PG1 Iy'O 12 7⋒V(U 7HjMˇabcqݚg Lr@cPȡ3P(ȕWE 2r9 #" -8~+&$c IDATT!BG:hI su:oSj-Tbp`)a"[d.~n3gK.I?1m4,[ ;wFhh(Ξ= @ְUV`=z4FaÆ!((5@?Yf`ݺuСC={b4ڵ `111HOOg#!! % صkZn Lm۶q]|Æ 03f Ǹ1 ¥Kxر:u0#5 00[n\/_~駟0c L4I4ok>i+R:5N_/^^z +Wd zuE߾}1drcG*Un:^z à}5j}7 .4{ֿ5ugO?7n`ȑٳ'N[nhР|||0~xgii)jժa8Lff@y#[N7/> 8jn,Z?;-[blkJOO />klRqd>?k0:@KR Zk|QBX.r!Xk9H7fm!luF>sSo{jܸM~CNG-[n ?ΉO;wu'f1SRRM8,wܡ:p`G,w^ds˗9״Z-jJ0+WXBl۶ ݻwͮ?||}} -XuRS 8eչsgZp!oاߞoM[lӴ4rqqa nͥ-[R\\1Jo˖-b m Rի ڵu+,,Yf'_j> ٳԣG }!EGGѣG M:W\Iׯ_5{GcO9ً,ਹO}lk8p EFF:$.{pd>?+ NZ}Sмww=zw$F8(wQìaPp 0k },kԄ :bHf,(|[ #EnnnSV-6IL޼yW\AY^0Xp!X?{:wR˗4h`Ϟ=x嗱rJpmڴ cƌSiL&ѣ0 B51#| ƍu!??OjЯ_?T*,[5kɗoMlذ* Ci[Viiii)x oߞ5jO?ի}vqD5i* mӧOǐ!CгgO6ZwQFfwI,]aaaqмys"""~~~񁏏N8!*WR~)'cun:/: [(5WT.\V[@@`f͛7ꫯJ˖ c,@h- d(j PxK| K-tGo>$$$ 11:tsxeeeaܹ dx{{#$$ )4jԈ]vE6m8;u$%yf~cccqyt֍-I,=<Gfƌ|_sNyM%fckBxqq10ydT*YF00`ٲes[:{*ͦea\h׮`XI&ܹs*[>ֶgmˈk:tMR5(n)XӶ1c4 vPBugK?DxxЀ-ҶmWH  8ӧOĉ#%%ߣe˖ĕ+WCCCoƝ1c`ҤI߿?ƌ"0p@|XjѬY3ܸq i&X .DXX`SK4W'OĈ#0}t̚5 ^^^8qDQQM `РA?CxՈFرc1yd<oC1p@̙3`]4 $%TbOBajo]RNAA@#4Z@џ%Ғ^F6g%F KҗTXsX-޿CE1qDt~8o߾x!/":vW_}qqqǁ޽{`.ѣG#<<GAV? KJJªU|r1Gj#GĀxQvmΛ˗/I&V)Ǐ͛_XqF 0ӧ.]*jܸqwG0LNNFDDr`8Kea\c0s=ǹVZ5jf*[۾kڊgM^xP~}޸<<<鶄mڵkVZ8|ԝ-Zt:Ξ=wyzFFЪU+ݏ`K? oM6aؾ};oЯy{{͚54oGΝ%":tyf>}ϟ?ϞC=|0r9̙@3c…9r$&N:pO-\m:+ l۶ ;wċ/7x^^^vS }A߾}1qDL2'OFZZe80 / fy5kĢE-[J*!rJ7nf͚f q տX} r7ͫiKY8B2 c"gPȠ 9B%7ZjT(Jb^=*O WkÆ cxzz <^:Zhy=z4_Ǐo1%ݼy3<<<˾mQt@rr2̙" 0 jժnWd2*:u*1rH9r7o#Fŋv 67L bҤIl gt;ի u/`ի1l0X* z>|v_Jݻf*[۾kڊgMg[nKX۶s-K;[lڴ QQQ ⽞$]H #ԯ_{FHH^~e̞=YYY?Ǐǯ og̮]p vS(CJJ >5kqxzK.l8<~6'ͧզs{6mЬY3W^HLLĥKʧ%݋K.!$$C&M.c>g;xyyZh:u@ղ/~闀~ wnvPշP!wӼ:<- '&02@\RO{bvK妈Qع!e/mcg͛71o<8qsϿ@`ݺu lj'аaC4mM6Ett4,n\.ԩSqqbʔ)fV={wOح<̟?_5,S9r$ .] @GT*yfxzzbscǎ!;; 7oN:,^X4w}.]ݻqeԩS?h5ԫW}@7`Pۂ5mEj[S|it{.Vli|j\z[ۿ-ܻw;w|o*fA{;5Š+1 i:ujժڷoSyCŀ ///UvK=/+ge|Zȑ#l|m Ge׬YӪmx._lUo0bm8]N,(d`d d }+]++L_%s vSV  _bM "IgϞUVaرՇEyfܻwP*GARm۶` ΤڦMVŴ9b}ñh"08G>}[Z-9" RiР֯_DGGYr%f̘:Cر#|MٳGn;#*U?ǒ%K0fgv !6l[~~>]Ưhmֶ"VR^lh4fڶMtjsNR;[NG}/l@vv6n޼)z [Z*@fԨQoQXXJOOOްjw(iٲ% d[K_5Ν[",, 7Th#)qroSNř3gp=z 6䜻 0Xt)nܸ3fXW[HiKO< 212A A!\,b|VYU$k"{, GVsiभZsbbbR.@&M{nV'Fd#,X???s] D`ذa?3f 4 F!]oo>- wwwȑ#8|0FVZ9>N0ĉQF h߾ ^zؽ{uo0bm8K[ƨ;drd~[d J#t)CHq -XkzH!lzJ-`n5†Y'[2U\\LJ~rssh:rZx1>|ڷoOh…TZZs;wY~-UZPZ 9sd2mRyԱcG=z4͚57oNG&FCDD7o@EQQQԵkW OOOh4qFjܸ1nݺÇ{̙3PDD]x7˗/իW^{Ri0fݺu@kצ%K]sՋzjH~:={tܹٓ#!Cز߿?uԉ-[$)cǎ%oookdeeQ޽i…dZhzzz:1 Ck׮i+R:5C(/>mRRRo6ljժѣGu[ۊ)ֶ;wRPP-ZPLL tcTܾfrss:up /ۓO)$''S:uSZZC}q #4~x~YKKKi„ NÆ </_z%Qb/TBaȺfftVz̡ޣwhj т߉V\!ZMUQìB0kc) zAo0*$y1&M?2p'S!y-7r3oHзw "ǓF3JJJm jڪJKKQJ3wZL4jHT%G3gQqM4jHTUyaxCȗJ^^E"Jj;Ç ޻wloԶ_Qh4r ԩjirlR ^H*RQHH:uxUV5r4nXru:d2T*ιnZRS1jؒOrrrΝ(T* //[l͔H헝;w+O>o0Ǩ̏?]1q h]Ju2A=^x9:*L>} ::z2xlH[[3'#7}`^LL5HX ol0 J/֭[Y=b= x00d뽥j*8pSN Re׮]l2L8ŭo0Ǩg @`44IDe`b瀌 I>'&?t^HbODo߾ tll Nҏt:ANc-[1c|ʆp}644cǎEtt4ڶmܽ{v 3f̀/-Z_~ݺus`TZ:hZ Qel \[nC"3!)\Dh 0 >}^zN'^xwšCK.Y=d:tRYB#F012htNg@)WT;DB?D" XLmSXXȱdE)33+g۷oegg_~EG_ A&tZ5:Дi%gJDc1}Ɨz<\v9B "K}b`)n3.]Z&^f j֬~R0ضm|||;4'̙3ѯ_?e\k ?#֭[|8?8ܹz˦=lgiii uXyRO?r%%%x"Ο?~-[^/(()S0j(L>۷oG>}V@DhF FB^P*.Y`RZ~$Y+}Iތ5IYVZhٲ%_PحfoTT>DˠBaLD#Xi;ʯkmw{QۚOe2#V+Gԯi鶥O~]V^ReJYY u3-Zja.Z'Q6jqqqY&,X`ftu„ WO3.)۸qctߖnذ* XCᅲ>QFftP8|0떗OOOգK",, 7n7o4;CtЁ ߡC|wVUVAVڵk /{hZ6m'N~tA2 c"gPȠ 9B%(@yP(MRRS+=Jwԉ󿨨&L@:uЦM\p]vE6m8]CBBѡC;w~gϞEv0i$֏P'OĈ#0}t̚5 ^^^8qY6mŠ+pBIJP>,̝;/2/??cƌIп3EEE`j*Yfq`a취ӦM 0h ̟?&Vb@?DÆ ѪU+r4N[||<ڵk')4UVN.! 8ӧOĉ#%%ߣe˖ĕ+W'Poq_1)S=.]`Ĉl*Kŋ6oތf͚aȑŋc߾}ؾ};~m\zlSa&%%.\o _իr-**cN>ݻe˖pi[|Ⲧ j۶mCdd$ @|<gShvhҤ GǹsPRRb -!o`ذapy=nf7 U~}t:CBBjoѯ_?h;v`^h4;v,&Ol1Ϟر#  2"2@ '\+$EXzo%@/uP@C@ x @(^*z`2I 77]~} :r5i҄|}}j5EDDPaa!t:=z4լYrssIRQݺuDD'P~xvJcǎ%"ŋ^5kRPP4n8~:'eeeԦM|@ZV4^0B<1cƐt: 7y ݻyԼysJII,jѢۼnMu֍N͞=߽{wfҜ9satJMM%""zWvt S6 ֭['믿ڱcϴxbNz6DsAaa!:tPrrŴb4~m׮'?DDO&taIeh`ȑƛݻ0DEEEቈZ-5lؐΞ=KDDΝ#{nω'ܹṳ˗)Jp{m˖-$ɬs^^S5{t!4[;hh_6-Lɦ}_4xC:3Do%^ z7Iz?~2@cc!@Dz?2cc:!&U*U.DzH1]!$6S{Ch,:t(ѡC̛7n޽{qFh4ر7orssq!`ذa%{}hܸ1ȺۦM4k իljϟg?; "xW^-Z`8ڵ 'N@tt4\\RRRpaԬY7 /pԫW]tAFF`K{ҥK ФI: ggϞر#ѥK\|bc*{[o\۶mý{C\>>>_>z˘={67Ǐǯʶ~}{P42ۚ~s;vD֭quL0UTt6Օjժf[ Mak{@GԺ0ȑ#} <?h3`VOOOv[*KGFFb׮]Xhf͚%O a 3u...8pרQ#X~,{X|V-ķ~ HHHഛg5ߦy3mYl ,F_`)VYTV իWǣG@Dh۶-_ɥKbŊ8z(kGw?Ⱥ[W _54i3gٳ8txxyy Vq]屃m˖-P(UqiBu`))TVY?//'NDdd$ d}MZ*@}ԨQ;w.RC8HR 2D3g^Ü9s0h BAeϷ1$"M֭@!ԑi)W)cJBڵ1o<řY#[j<"V)X[4mذ!~[~~>NY*C1,Yuցa㯿ºu0a֏NG}/l& ՒGD {'0v=y6O>9s&ƍ'9"drdZ"9@1@ԟ1RJ T`r?um]vhҤ vލ|FArr2N>F`UV?믿fBff&nݺ)S 55999ظqhBaM ɓ[VV4M}۷9j5?.Zb,aoH2RWV;#`g-㼁CII ƌ] HR r 6 W^رc1vXKT|[2i9k>ܹ3:t耵kײJL1 e#e裏pAԨQ'O[j<"V)P:+BasVUnPdddݝu 8}'!!G2Va`Ÿ{.>{ *Cy׮]x饗0dDFF֭[y2B!B@` W>>#l|djC#G Dbx++4޽{-Z`Ȑ!xbbbp-dddGHH1 99EEEPt(++NC6m0sL;}#!=K5j^|v}pp0"""РAxEEEt߿?8v JPTj7b<[oe\ll,#G9r$Zj%Z  [.,,dRcL8Q4TVѱcG3ẁ}!""ݗ;`֭-))a'K{X4ʔnc*U`~:z^zW^fʒoj׮~WҥK۩Q]ƞ1M}~wj֬rJJJ-GSƎKlQZE/4o<3wkYv(88LB}у|8s~irssL񔕕^?~8?~<[wby *((0++c ZmEKܥ%rhAJ_E#дD ҈Vei̅eee.豬@SkXs-snA˜l/qTth4P(*ߦ ZUV߷iRec hڴ)\]-4ښj(-i PJ|\@T >pQB"'' 4j.l`ͳOeD箘66kBJurZ PyOTT{Pf A>}=%Zoo76 J$ * ? ;6Ri؀nmÄg§yI(^0-lݺa:pR? XPWښZ{n\rw`];wwwއTRÖ-[$gK/~+C o >tT|֗ /[Za"j(*46T*0 B'VqR:o)y,1.],g`,)#FGR PRI)+" iŎHoF࿩JN߾}U!g+VѦM^?RڙNÝ;wX,[ Lj#] T*kߚoG,Kn0}tl߾#FICtВihF ZSQRgn3"'O'v3rH~׳7mڄu>}^z%鶗kl*.ؿ?j׮K>8)'>@ĠT+VhuZ!H/(!,XZ92 o8Cd|~"9d8+$Dĵĉ'N8qĉ' Ѥ-P *5fuxxk(PP\"3C|gt?C]gv[f,'N8qĉ'NreZ;󸨪 *.Dו}E 5ejYdR FRY.i⊸! 6sgΝ5/{ss CJ"T ~6]mZJ~04 2eI Y۷(~C,AUU~Wɥ 5)35-r5aw|j#:q}Lʽ{p-&lejI2WN\~b=폩p6sss.ŋ#Lmtɓ'l;PZZJ7SUUK.n]\@DL-MȁjM ``Ѐїћu|BL???N>f;w.,_nn.BCC-'-[qXn]!cL=lMo\y៘/Smyk׮5YK.CXh>}jdZRFn\yitoTغ۷Ք-ӿGnܹѣG#66V+)m7?#F|48s .ڵkaI&aĉ3f 1p@͛Ѻuk0 0"::}5dصk|||0 K.מ>}$0 wyO> k.K`1bп>|XK?/HMMEΝrJ鲱7ƠA0rHbaĈ֮]\[1D1 3`(vڻ{7f 㘵9fҹ1k Η:LǬݣ-ZԜ*=ӟi8/^LK۶m)11F01e kH2 'w㚒 Oɗ:iժU_N&L BaL111ԯ_?EM%7.s|wO>RaŘ6Tܾ͜&mќ< IDATʓ\.ƍӑ#Gp8p EGG FA?#{.))5*--p;o<:m%"JHH ZvAhƌZ2޹su릑i* 2e b$"\pNDT\\Lm۶cj*_tt3zѣVXQgD9f*dܡwݡE' MIN Zp(2ѢszF@1k(h;fmڎY=`aǬnH״Ŗ˹m۶B'Fwd,H$&mOFKaI)3nX>1tP:uJ1̑TK\L͗yJMO6r-|7?~<-Z7o6Br%7n+qNƒe K7]q*-X,f}XR.K5CmP9PMڂ9rG]yDӹ67 ̄… QRR†Q ˗/ 7tP޽{5 G.]rJj\۸q#&OOM`n\ ߆\.͛QUU7x/2 |Xz5on|SLݱjHD`D Dellm C,a "rH4 C7~70 c[q}ۭ{͘VGm۶ QQQ())ڵkpֿŒ%KУGTUUPV+V`…ڵ+gyy9F{󑕕B|gҥNy6o ///6mڄ֭[[ `񈋋'|777dgg . |1tP|r|h֬ڵkӦMC>}6Ɨ/_cFǎq1={C Aƍ駟 !!:uқO|򧦦"33۷oǛo jo߾111Ì3 oooIܴxɓ'髏5a *L`HG^}:ƶ>ΝCXX/^1sLUϝ;x״M<Or9{GDD.]"pB*((ɓMLSSՕ)==LB׮]/<==dW0!"ӧO:y$K/QVVQ۶m7$""TJTVVF &MDT\\L7oޤN:/SUU 6ZhA .JLL$T\\̾+ћW|u߾}<<<חrrrԱcGҙ! uڕ6l@D "og|ipիWy%"rԦMjӦ eddPaa!h1yRYYI7Cr9CTT:+OcAZ;t#RVk) J֭ӺO7Dm _U!en. ٟ*.Sl/""lۛ^}U6_|Ç ر)55Ug9A=r۷L_} [ 24GCCŐ!Chڴi:elii)rvv͛7kOKK#4{lZr%Ѹq4:"@tis[_gAuQFԮ];\~~>?d#t "R.ի5jԈnܸA+W$fq899Q@@q̩cL$%sߠehi=Z|_Bv}zhD~d˳1w\gcd9]Ț1c`޽?իW/S(wU9w;[ooPׯ_777@@@<<< ggg.W={֭[}߿?RRRkTɾo>#$$K/ag۷/wOOOݛ!iÆ dرc6mGGG#++ ͛7G۷1m4899a7o-q~ЛW|N $$]tAbb" qyiQvk.dgg#::rرc#G34#??7]͗+Zh: <<M4A޽qe^ccƌAPP zkHg|)Oj,uND"N ZTrFHۢL ٪270dG"33} 0 jzQFaΜ9شiVW W.л*|:WkT?P9bcc?6@=~GGG޽Gyy9^u$%v///xyyI&zΙ3۷DŽ pQlڴIgX[[[?/^d7*1j([Z!̚5 {Fhh(Zj_>>>(..ԡ>Ϙ:PCE1eqb b  u,9 !eqB:t(=zΟ?jddd_Çb1 ǎcuuu՘dƬoqիWWW'ѣG/k1b6l! '''V/h֬Zl-["::4.7Au\\\l0.s'ca4ݻ0K'O*{nAP\qIWr;vttdnq,Xll_y ƍ^x: 4իW MDǏo]oX>۶kʼ0Q&lx!^rr2 СC|{W.һuKtfn_i,|~a׮]Xt)>B]b̙3ǏfϞsnݺo߾0`͛Ǿ 믿Fyy=0a$ -[@4?5!!p!={+WUV.5P(p]nݺFsD"0 "D D@ll F \#{Bb8`2PksvvFn:4h`oo 6ѣG[z_51w\9sYYYpssÜ9s^zh֬o ]?xyyy&c:v((H$z05.K7 boovb*uawRwEII Pڶm[H$͵mSb s\lVX11%=})ƍ߿vΩSYYw0XlKק!m25w;w@D:>!^ee%5j `رT!KmUsӨ˾̑T`ƌׯ6@˗/ՕdK/-[`ȑϟ?_AaܸqXt)z ooo 8۶m֭[~Qj LC+atQTTLw[욖 Hl 6b1"@D#D6!Q!\n`4澞:͜!͚9=z4~'{c޽o pM̞='N{a@hh(~m;w4Zc?x6}֭[pV*Ǟ={L&ݻϒq w)#K.D )ԶݵoD\aa!ocllk!//H[蠌/=JaooQ9uݻAlV–-[x(FHۢLMUsyx葆}G8t\\\0k,e+K靯Fms4UGW\.[o'''ƴ*?~dsչKW^W_}@6RRRЪU+38&O L.Ita_jժ^ulذA`v͚5WN7Ns{^ L$2 ָop隐s?; 07$,FDD W^pwwG˖-5:'O.Mf̘+x嗵6ӧ8q"SN8|0JKK˗/k>}JAAAT^=>|8߿(::[uW}ѐ!C #"o4 Ν;… MMuu޶L C 14d*uJmݺYfԿ4huڕ֯_OD;1??$ 5mڔJcr1W|rnvN?XPPZ`kDDmڴݻӤIO>6mФIXnڴZjEUV4d2dӇɉd2mذZhA(,,LÉ EFFŋuʱ|rZzk%:۶m@=z={ {=!C_|AӧO;Ο?Ocƌ!ԠAze e XǬnPځ4.%G,g̥^"QE]f1+w6]8Ǭ0b9}70?4N$:W HS]Q;V@D th*=D"g}g2d*++QZZ1b߿rJy)(hݻgAT4oMPYY {{{R7ԏCBBУG$$$w?FJJ Ν+(;@|@,EeזMIאsLՓ:|酅EB_~/5ޘ:7p@|gjϞ=ѫW/̛7Oo_7|m25V!D5>|nnnDz4[ 51曣wu՜4LYmۂekڷocʔ)ZLml >}7ny漻4nwB&X-[ zq=x;͛G 1r5\N//8Ȟ?DttldR(WɞՎUtZ,9ҷLN9oLWS-{Q% VZ`Μ9 5bH[[[c`-]D"8q*1Kۀ0FIW#U~}lݺUkC>hl}̇4~͗!70uGꧡ'!vrJ$$$ %% =Sjy*b}AZZf̘ħEH U>Ҝ"+w0Jm1폡6 aj-[:ڳg~wKilvpp`=7D"S@ĠJ.\rCj\QBo_]%fggC,6D{s AѱcGTTTݻׯWX M6EHHm&Gٹ%SRvOCmWXX ;V뜿?lmmu'V ֭[۷oK. V,Gm?VVXW^ZQgeeXbRRd^WgG4 /OKKftqgОA{V"K/5RS_k9sy1wyinYf n߾ @aaX"mj ]y'̊+VX1Հh8{CA ʪ#Wа/8Uev@4 o?R q˩t-3{@dh%mӵNԖY_UVjغ awۮ<tfŊ+VX\*LL9*G2rnsjO?!Wh ]+YbŊ+VXb0$"d6b@"f`#Q:dڟX{7f )2.Ϲك2(}ܺuKÇy7!YL k*W/ɒe()tVI.~E,K]?n,-[aa'k.2 lͭQ'P-u>}<~ WWWl޼Yoׯ#$$DsP-ׯc„ ۷ֵaHKKѣzvv6дiSxyy;v 1l0l㣱k94VDF@$Q>@l#X@$D",Xsa蹞rLn|:f/ǬP:;21rJgKP:_ pz=jѢ{S9r$;wZ=x6m gϞBsse1FnsYx1yxxX,灲2\Ջ9ztmۖMגy) ;P>}jQx'omڴI뚇uСdɡ {ァpѢEԪU+ql?*<==iɒ%a_N ¬t߽d!ҙ3g^P^^^tAx֬Y4sL""zEGGӱcǨRRR͙3U A(66V#$jѢZLcŊQ9f:},t IDATy+Owޥ.-QkҔt9;JrhM-Ǭ`1kr6601pj SU>2wwwWZTW:t /QYYlXΕ!2~p+H0I4EKP]]CԩSfՋ9z2|ؿ?֬Yc<[MO&B@Gǧ6yKCy h^u&dJ;v,\]]4sԩۏEfdK kO#Ѽys|* HR9r=WRR'''٣e˖k׮pttĔ)SЦMv؁G[nݺu٥uV~yq%bE0 1@̈!13X,D$X|>U1 8_#v̪1dG[lѣG? ˗/gwڿ?5=???={f_אEXz5Zl*]666o~ ŢEкuk\pǏǂ гgOv7n$ԯ_UдiSj IIIH$سgpnƍx1JKK?]^^^D8;;ԩSf͑!55snݺQFa.]]v! @oB(**… qi/D׮]J+=MHH@zz:رc͛7_r9>C[ 4@zz:xmۆqơGXz51m4aÒ%K?#33vvv2̘1^^^(**ٳgyP7vc jJ \p̓Dk[z/ ֗rL:=vZoR;w7|w}eru_h?33yyyDضmh^C}r~~>̙,_ 41c0}t9ҠE"x $&&[ƹs琔tuOV@]B@YY+wHHr9Ο?&M`ԨQ֭}:ry "":}4'O-͟?N:EH4ez*o\pR)EFFRYY) 4iRqq]Q_}.\5rss)22\\\hѢETYY^{饗^,***m۲:P 韈($$FQK9vAk׮>}qe-[qz{{ӫWw&׻.?#>:kҤ uڕ [%%%f'ϵk׌#7oߞ222ѣO>>>T]]MeeeEhN_]Kee%5nܘ:DDDͣ(z"O>|0;vPzz:k„ ._DD1 CT^^~""\N͚53gٳg ٳ MhΝt@=zo^z4axM}!"*))rqq++P-&8|ݣEӐwJhNQ)+"K悡d%K|ɜ`|Y5 coooL0pqqArr2R͡ݻf_% $$]tAbb" qyᅬÇ_~Ec\]v!;;ѬcǎEFF9WWWh:t@xx84i޽{qܹsǶo%BBB/֯_ePz֭[}߿?RRRϛ!6lL;v`ӦMpttDqq1tQƍ]qDEE{xq5L:vvvݻ{fw]cƌ޽{!zBzz:(wӧ/u=LeφU]PSQWv3g`?5)j79WWW; -X[nX`n޼}~WWbkk1c ((W~~N=s'Fœ9si&L8G!,, AAA8{,ݸq# @/,Y(++ڵkڵc.YGFBBΝ+V̙3l>J}͛ٳ''ݻ(=XP@ b X)g$ ۄDoHYNgHppS]B7mb8wI&(.. UVf_7a4޽;lmmqʇ͛cŊkFtIk4MȪvQ航*ʁZll,^u >nnnZ.wƈ#аaCeP׋zi<Il4k -[D˖-\v77=c'NK,6l3zP^^.H>>fСx<8< 8>CB@@]} wdMGll,>SjR6Հ?H>ncJotvFᕇWAbb"nܸ  ;;eeeZat!ONNNFAA:t`7r rssŋcZ߿;wTڵ :uٳ!͛xhт ?h b3: 49sp 8::^cӲbXl) ) # IýLH5n+$d~C$4an8FyӵkWif؇?O<07%@*0qD|gHHH@ee%a'Twڶm D"O_ ̝;gΜAVV4j'D7߿? cÆ x;;$4>CܹswiAN%D*,׺Maќُ{yyApvv6JOW˖-Ê+p1A +++ѨQ#,Xcǎ;|Xv-ABBn߾kbԩlB>_|֌MV)x0 ;qs???H$ ci޽˗1w\L2EX@N`L!) !2)P-qz45.oED(N(N8~9d ͥK{{{[K.DرcQQQɓ'O>zm߾=999Bd2A~t pM̞='N{apu.\J8~2[2dnسgLݻw Obcƌ+WwEΝqaq#P݌=?_#66ػw(͛ѣGǿ;;K)yamֳgOt k֬3UDDnBYY:ud<|uU>]!..|ށ{}:̚5Kg\w._ðap 'IIIx4Zׯ_׊/55w:uBÆ 5v+..L&Ctd3]vs9r$뇛7o?9bEJH|A |U,?x2 7c(qVycy|2֬Y~QQQӧO `xx8qF}!%%"׹<|GNcxff&"##ٵȀrmaðuVOފ QcpK@ٟ >ZWWuJ_ؽ{7!JP(x'oݺ;wwѣZ{ 5jٳ=WPPPv&諯Bqq1._;v`۶mD'OĪU}v8::^x̚5 ;wdeggcǎѣ4*ɣGƠApMk.1YŊ"9BLK夀TH,5~0ta.sB2 2"//ۛ>cJHHB04`Zp!}嗴tR^W$cǎeԩٳ飏>^{>|.++FqĉD(55ŋԾ}{?>ܹbbb]:DNNNԸqc:~8>}|}}֖222… Ciiim68q"ҥK0 YvM(77 >/_NA7nW/Gw}GYw֭ә:.yzzj9ݻ;ٳiӦM$M6GN֭[X,m۶OHtΌ3իq||p|җ.ܺu+999Qfͨ4h ڵ+_%յݨ˒ߩS'ڻw/k3f 0 }Ǭ3ɚ邂f͚ѨQhʔ)Jqqq$J CO( >SJLLSREE{e몺;>}^z4|pڿ?988Ptt4UWWK'8pٳDDO6mJ'N ".rk֬!OOOuiGo%$$ʕ+>`˃D"Q- b^^^nݢx7n=yDK~BA4e)&&nݺŦm3M׮])))JKKUǘg+n]澻JK3hQF%Koш;;%!Z~(Q̅@{9cV˜'j1ܟH_Acɳs6j(++ý{дiS #bsx1RRR0w\p!!!ѣPQQUVG]\zbXMC( D"Fg5ݻө2xo(IC*͛7 Ҥ2LKɧn4v! >|777TVV^zelT˳Ԧl*q%blRΌKϓݻwunQ]] ;;;3S|UCRS ѳ>TJKKacc׎tQ]]cǎ!$$GUUJJJtg31g+nlق0s|x9R Tʁ߫7pvAi)p~H 8ѳCN'W;U]+dx_眮8̀oP>8Rq>EzjtqՀHKii)0b㏵܊+Vx 6l'O|F賊7ќpUGV8;;aC^p7ʀK)hߠ>@R(j?cD^_k[y9d20? i`֭[:۸q# q]]ѤIӊ+VX߿5²eZ+u0dH$D l$ lĀDF" tjg (W{7f }x\?DЇ>JA^wqqo]KXbŊ3:tл+V$X)D6jeWH`聎Ps٬]q 0k(N+VXbŊ+VDF@$Q>@l#X@$D",Xs! (KD k ݾ}[h UUU_Z (..f}X4J۰gwԻ:u]Bmnn瑇jM2 I ׏",%򫏺k Յ+sk` A 6Q42'5LZyfmGF%77kQbܹy.oؼys]R'XS-[]v`4i&N1c 004; k#MKSe`! yX^xQQQ駟3g1aW|UU0O$i9MENN{naZt.]~ +ڶm*X*|U_c.e]y_+@03bHDr#A"A,V>KĀO&BԘٙrssR^^ԩFYb?HܵQ2f̘Vj 2V?ƲeːoǎC NH\j !xWJ˜>bkx71n8,X999z9B5{R?D\v o۷N:q㎊BXX^u̚5 HNNfb٘8q"␕TWKu ]WyDbDrYD lleXla8}m۶"-u1tP:ut!D~k]zspp\Xߏ5kX@"MI) ,_iPb-Z0˶Sel˞? X>GGGyZ^^^BvvFBT#GJJJ_prMUV~K. λ.,{wP]0=kw҉1"D"D@"a yT TɞeF3ףG@FFbbb3f`fff")) )))֭Ξ=^۸q#VX k׮Tdffbx7Q^^"L6 }App0}}aw OOON<͛o}dN^^"""жm[/C`` ֭[[^^>:t(>s5WoW\g}.]q?y'O̙31x`L< &&ӧOǪU֭[Z ԩ^p9vz۶mPRRkl,Y=z@UUn:uTxxx 88.\0ל?qqqOիWk՟x`ϚO̜9XZB7_|yUoR)~g;t)\{Ξ= Ae͇c}:Dx78w&M@4!!2 .f͚ePCurrBeKMU_cJ?PǨQ{!""111?>PXXU^7T ͛7 M6u֘0avgNkA)H900;ΑrH"QnMHfLXt9@I@ 6l@}4 4@+x@0` n߾MK999tqf5 IDATر#yyyQee%5nܘ:DDDͣ(""`6ӧ\.'""?>IR2R(4i$ruueePP &FaPV"/<==sa@;vtJMMՐ3,,rrrN<!]sCGK2Ѻ"7xCy0ٳ}_Ϟ{=t X!@K~͞-hll óݳͳXm|5we 0n8];Hj-1`K.HLLDaa!Ο?[[[3AAA'''P]>wA[o1zad2ر6m#%&Mµkpq޽{ NϞ=1j(̙36mb}K/ߟ7^CNwڅl6cǎEFF9WWWh:t@xx84i޽{Zƍ]rDEE{xq5L:vvvl1c`޽^z!==լ,bccnݺay&{opp0ZnۣHIIOWͳO}ˍ4iHލIPS֯_/2#錛o.BX߽H4 ޽ e۶m u;;;!((gϞE||ixܼy={d{ NG1{X~=\.V]½n.Ӱ+{{{-;S?6DN`\. ) !2)P-;ףq|~,W@c_#DvQѽ{w`q,XlPVX>|8 5l4k -[D˖-\tMKCa۷o]rZ[OVcdC9z(ɫ1b6lh0^>]s_u|Iktf*9Μ9PmW-C08qΝ;$4lP+СC#>/ŋMN_h~eΙy\UsY eEA7}ݒ@ܷ-555PLPRsIͥDK\wLĴ}yn3wrq~?9ssΙy,|ܹs...۷/,:M1 ~N>3 MG -IZj< z#BEP%|P Wؚ9c*q prrbȚ5kn:ahtN<~(BBBL-${!..ΰg%bӑJhР>C?"==x/k[r塸$$F"Bll,^}UcСկ_ mPn]?#v؁" l|||Pn]ԯ__ưDY'78gr^ħn;_i\c{}}}َR0 3:Ubŝ;wtŘzV^[a᯿֭[1sL!99/Fff&bcc1}tiyO#::ǎ|}}9 ڢ) DJH%bP(R"o1X~0uvzm Kopo"~Lbt "swb޼yHMME~~>vMhBii){MP 99 m!a TdzS9jN:>N8777Ū͛7_.ٳ 薵!mۂpy\NN `ܸquMiӦ!44?Aرcc}d3@JJ;e:t}1,Q~x> ++ _~%{lr^ħn;_iʷ:722@ǎȞk1߿u+|dffٙ6l0\vlGB{AbԨQ߿?޽E5t =ׯ äI T~,YX[4U\ϝ P@ĠZ)R(UJu']`jXX BwYO#GЧO?9sUUUHNNFEEr99ӧ7n @=읕"Bxx8JJJ0l0ܽ{5k;W'Oƭ[0j(ްz~sDDn߾UR} JoEhh(||||rl޼N >>|8N:_~oڴi#H~/\* :7oO#-- AAAT󱹾~={6saoo3f۷/ ͛lpuE鉖-[tNfN9W>|pW&L?'c}>]@UUNc„ h߾E]Ljh#$>×w23omL1߽{vܩ+W|uMee%o9))Ig2iР6mCᳳNc,**JBYY yL799;vرc1x`ܽ{111:[}@aa!Ǝ+Dii)gbpss+N:L]n kB_[С~'ƍy;!_+*sr9ARBPA&WB!S@I`Uxc1wGG2L]pe ;HzG2M(88͛G>ۗ NG%'''/RӦMiڵD'O&BADD111Nyfrtt$I?~FF1 C[l!" رcl2s|:u %&&Ruu5g:ǎ#OOO|2ݸqlmmqƔJDDEϏX9+kr;|0uԉI_Nm۶x(:: ĉJtYx"5oޜԩC6(iӦQÆ :B^^M:͛s~ٔL͒%K( >Zt)͜9L޻m6rrr"///ڹs'9"-?{{>z׮]Oߟ"##)22zI...jִܷo.(gዏtd.sWfu,x%"ɡҊ+hմj*gT]KRڲe 5lؐh۶mSuF_ȑ#)..֯_OkϞ=K;w&4c ^L×Ν;SBBȩŋI"PHHo8m']ٯ9sf9 ggg7nUWWSjjA['GmT[<~8SFh4i$ի{?sgӉf=Z=]zBWI%K%74]]¡\;O22 2VD'oDI$ 1mMD Fdcǎڵ+PUUŮҦN尳JD"Aqq1tpr9ѤIWY9|a5TWWx'+BႈoWBZ܌4kLKRiBQ(: 낫negA{"?_bD[̉d2(sWfWBʬ)aJχzYY`1W_QRR+W"66VPx! ~Ųe T2c1bMO!mQ&ATѨ^zjtw^D}‹[UJ@*~ʔý3?u\].PUdA!**jPﻠWJf?ӛ*7NȐs  ڍV5v` 1֠jp !p0 kS򕵩6_0X_\u.>O5/mĖ~>kb )wKց9qS*a)t|y+3Sc!eV[v.L=;Y cj ꩄ"!=կ/p1̟?_)oua7W~:h߾=߿M߮+O&r SNEzR0h =wxڢKFF:y@ )elg'8:1ppwjZn={LoOZ(ĎiOuӆ]#$!zh̘1bob&ֲ$c}>?RkډbQ\]]1`GֳO>yl2Z }Μ9@,\ԝ0&|WpwwǞ={8ر`v")_|w9sD㭷B~ ? .Drr2iÇsΡW^hܸ1|||0c &##DDDoiGA||< vԑ[9޽{m۶(K77n@۶m㨒atG,\ ˖-Cii)ooo <F 0bغupċ/a#FW^0`~'Ar?HLLDhh(֯_:bĈxvZt aaatίvً' |혯VWW $SM bCs[#!!AG N&ͭ7!%SGddd]vukرc "a@"a`kk[ l` :fY 1acG/LSN5rN0RZZJR͛TQQAg|'ev4lؐ>S0;+Դ\9}!5nXznhŊ/++K.Q߾}),,ຏ?~=;w.͙3(**N>MeeerJ@'""\N6mJ""JII!tV~wwwǘ1cư|udN-Biҥfg6E~~>5k֌=޸q#]vvڱQQQ:hرݻiݺu%&&:{,T*>}:Б#GILҨN::N (00Əs~РAT*1b޽[T=aڱvyfZ~=ݾ}/믿ԱcGi}ynM%}*++iԨQtWRR"(^I yCMO } T*ۛ~嗚̢q:{]Z{"ˣOI&TT_spuu=Zf :w L>[FZZѣG;2Cƍ=ХK6.]믿fՑ9s0Vw5MT~,X ԾKcc`֭s~[kN;]M1 I&AT .&9r$:uꄡCuss|M6a;w͛d+V@qq1_|kǦi>}͛7|||p9 4hb۝9/?/ ˑM]vx_57K#cSoŜ>=(5ALis͋%  ;TREP(TPznp  7VH955&ѣ&NsN[+V@Νٰx1gxQQQ^{g˗cС裏y%ts˗̚5 ={DF#G`x7t¦MBiӦaܹeK/q%rД̙3ڵk{߾}߿?~GiqryZ|JcǎP*z:2!pcw}_|ЪU+:r=x}^W_5{nr zN1kذ!&N@xe:p'LSc}^3vgv~ݻ| """^p5k3azo#qyL8 .Ē%KsGⓗcQBA?֊*(JJ  2@` [TO9{25)s2fLKKK>}}$JH&Qp.)JRTԹsgڱcQxx8W^ty""x"_zIӦM#"4oO.S>}T*M2ݩ6mJbݻI"Džo{> GH9<Զm[:|0:uZhAM6%LFtI@&W|)JIa IDATۛN8ADD/:߽:tQzz:`'@=8p[oQΝN PPPUTTH=ח.]s?C04~x""˗/:tܹsWGBÇԺukjݺ5>|rrr( x 6+W;CDDVXADdXw/tIͥ@6S.]8[\\LqqqFtIBLuZl8qBרQ#όaۼy3T"RO޽;5hЀܹ#(?b~z@[lՕ㲲2ݻ7Ӟ={ίvvX \Xv͛ԢE Ŷ;sک+lŅڵkүu"uvX>ƧL7o\p)((8@ӧO۷oG⋗}Ss!ZL"""wwwڶmgH5ko /-ZO?EnݠT*YڴiUGBχv׬Y3iCg믿fg@@T*ّf>{=z`޷kC 5((HP~]]]wyWFDDZn pzfpҥKuΝ aPXX^z 6l@ӦME!$...(,,9NNNG}EaȐ!XlΝ+J>@'L & +v!))s L$?z ]vEϞ=|rl޼d5 \S? 4{0ѪU+4k  0o׮]~EܔӶuAxx8g1c`;w( RBE*(BS\ Uз,e?_;=6XǬ`87vl?D7oo///\rXԍf̘12d k+<==u|%Lѯ;cWWWvGXXxߺub:u*зo_kطoo\3}9k.26&!yД#j* yyy:S~Gxx8"##1o<4jF̖jطo/_y]li;K`` ^u={VP5^S͛79 sG⋗>7BDGϞ=okьѿhV=bbbDoQJT+%P PR+£]/WY!a5!2QFW_}:tAeÆ hѢbccq%3k3P;pY !펏#::ǎ|}} m'Forr2/^Lbd7Ӯ];ᒛ Bnᛙ wwwپ}{۷/"DDBinn.ܹc`i#9i;5Ν;~~M[mfJ?zoԤa c}$SÃ6ͅaY˗/GLL VZgF 6a A.T*% dr%2dˮ%bM8Jf` ?DB,7mLm ƍaڴi6mBCCu|Zdggݻ7oRSS;vm۶ "? þ7o?Ck\.gR#mۆ`Æ -ZСC:~0 ) xg >yL1]ȗ2*Etv+WHܿ_+XFF:v>N8777Qx󑙙 gggܰap5 xwt -Ŭڔs.2OLLD^^}]NHh äI T~ vqFٓ QF{.-ZĻRVbǐ!Cc-[ PRRb0͛L{Nߏ~$mw5m搚uүuKFM|p庇>kB˖-_`޽ i&(JV  S %l ' dJ@d"iaojD S9o.ctudoo3f۷/;W͛(--e F>}иqch޼95PHW^yÇ3SN_~[oŮdPTh߾=bcc1m4vTaԨQ())ap]dffb֬Y777deeJLyL?b0/-Se_.<-r3gΠ ɨ\.J⽷wΝ;urJoEhh(|||9N2_ee iӦ8t{.;;aaa/$,X;JJJo>cID8~8 __`7HH5~YYN'ypss+N:t"뮼\ \/^ TKHH0_ұcb{.bbb ^ԅ;v ÚA<0VQQa<UWW\#b*|~~IY˗d7oĪUd7oիW_ei:y-@-ٳMgP co$%%]N#$hMff&lꉪ*\xc*^GL~2ިIC&LӮ>_\pt(B6BVFt߿~gYGTA@"J@PBP@IjCIM0B!X_Mpe-N4Y_v&//NJͣk׮QӦMiڵD'O&BADDׯ_mR||<Krr2yyy󣴴4""ڵk9;;SӦM̙3ᅮ3yxxʕ+H# OOO'p111NA ٳԹsg@3f̠۷oSjj*uԉ_~`@T]]+rXd |@K.3g;w߻;W+}9+++)88htQrrr(d&󘓓C+VիiժUcǎ']|nܸAԸqcv.TJ[l m۶M't9r$ޣ,"":~8jٟ)Js5hЀi…rJ &PiiAL_IMM8q\]]ۛΞ=K/^͛S:uXG3gɷ37 }ƍ$Hu֔N.\VZ %%%q,;wL TVVŋI"PHHoաCJII!"={6 ahѢEL"WҸqխ[>#B%%%Q@@]F(s󐟟OI}bZnM/2M2,YB[)S aڴi԰aCx׎MS T~}Ac4)]6D?<-Z(''G'~S6Biƥ۷o7m6rrr"///G⊗}j}ж@8,,>CbgvY"%$ߣCWNs-@ѲK:0w{ ;fw՘Ik8QkjlM (BDDbLҐ4k!??,brhҤ@NE{^j}W>yr_w=<< dٯR|i~i~!agg'*EEEfMJYY B0d2>};v # 5ɿ看e˖!22Reee(..ݻ1b_3cU(&pi())ʕ+kqٞ% n޼ ///z<ߕs4ibyA*ڴ2}R)u6;Y"<eS^^|4nXGwcJOO')=MT*>x11Lυ mu ݻwŋ^o۶-&Nht}UǪE}  JdV5]ԫ8*Q4hS@Uȑ$KD@mhjB A4P" 55J#RԫW8OV=_|vލG?|0jmشiBCCkeiV}ogXv-n߾m8tsΡ}Z f }6L<]^zj1k "mHWc3ǸQA(eekG9sr{t[=ah/2|իЪU+L8529<>0m4DEE!$$UUUca}*&góҾĠiӦXj^z% n:<|'N0j gEk%"RJ  z97o"_mgm z XF)Sʕ+qQ4hk֬ypiѮ];ɓ>zTB/j+Vjkz6H$3fzgo VATR&R er(P U eۥVJcVmL \c'JV?ڵc|<<-rZynŊ+VۑH$p?2z9 WCV-6v`/p\A\3,n?X 2utȊ+VXbŊ'a[g/n١ S* VAj'AT0*ȥv(sPb˜Y5eV3 (((3TWW̙3fS^^$J0<4B琲~\{D,)vb-Mg.<"(BϹ^j r9(/+CYI1 @{5s=s \18A$tG?s 9qc#66$4'޽{m۶Ֆ\x!!!x7ƨQ`cc???1{=nZE;Ǚ àK.8rɅ a`ٲe(--'<_| <<#F@^0`O򕛛CGOf={}7n8new^i àO>2e &Oq!((ȨMKƍ?HLLDhh(֯_:F^D"}t0n80 ~999}Ϟ=hժA^0fDEE_~䉕Y\_}U;v3>mq'ׯ#""}bbb0ge,!m,[ĄWYhYۇDЮA%rP\@i ErVEx4qBӦM5 BB=g5qaYc01k~~>5k֬P߿Oˋ=.//q"/@ZtVSRϞ=H\}EEEQaa!{@cǎewM֭ƍ ڵ k׎='1yOLL$tY""RT4}t#G^z;8}7o$ah[LY%$$]CYY1SȘFuqrHDTPP@4~x?#I$z~ӹT*M6챘z_x1`o̚r=vq!-?.=CjܸNt֍uY2}6-b +,Brr2P{ݠ)$t\GBS)pV,HEb>{իW)''Gu ;f  !uEyzz"00뼓YZVm!d2 .u-)4_mllFywuy,BZˠuզnݺ:IL5kaL4 J{1\˗/7p7sLi7nӱuV8n1eNٶΕeeȑ#ѩS' :T'>lڴ gK$L2 "":ך6mפ2̑Y7SE1mRzOX:>._oT1coP2}>-!SzTڇ+D":0b+e%-۬6mִH_@^58?o6]v$%%(..֭[޽{O?]vEuu5`ΝXnVXΝ;qVTT`xwhɓeK/'33.f̘} ӧqeDFF|`Ϟ=Abb"`׮]hժ68rߏ7xnґGzEEZ mڴa8q".\%KΝCnn.f͚={}:k9\]t˗k4i1eF СCҥjTxeʗ?ShA B$4øvF [[lڴ\ee%1w\HR|W̙3hbdLKKo>} ꫯk~~~ꫯ &\tմޯ\۷/{\ -kn}pFzz:LN_|8z(ZhS~~~|2tIϒҺRzH^γӖXyH$888u OLn/z!iG*b+fE_0m 6棸Sk5 `m[k!>>WF[QFl'N=r9VXCRA"`Æ pwwǧ~7n 00h޼9p=֠?3 ѳgObر5jL7b͚5X`&O(̜9eeeh|W##ЬY3038c 2 6ĠAfL6Mgnb2)) /_RDzz:9#Fׯy\\\ʆf1c>St 3f,#J8vf̘!C?5bڲ&Xȧoڷo{ݻwGYYJKK1qD5Sj^ŧ޽{y4:pww9_n]r\pSeӪn1W+5ɳߋV5C:u`cc[[[ٱ4J:Uhm9ҿ,,ai{V"A7qqqP*A'@&N:pٳQQQx7i_5^{5@@@T*NE@@甊&M]vg} 0{ŬYo6,Xw :7G~_.]oZBf0` 0[nB@i*((ɓ'1h 7*.|=u9ݻw2ŝ;wׄ DuaL~ecicFӥKtC`> Ν aPXX^z 6lЙŅf%)RRRة0o&z s[Rg[bd,((~^pqqT̙3!!!ff8鉰0|7j@kFo4TSV=6tzH^iXysDD?675hb~E "1?YxƦՊcضm֭?pttĎ;PTT_]' ТE ҥK8y$<<<0|DGGرcppp/!!h 0 CII !!!F/]999Xf ֭[v ݻ{,_Kb*&^x?~ظq#nݺv͉ +Fv޽kznn. 7ƶmЯ_?DEE|<0c„ Xjz衳%dmLG.}A*A1~xxzzJKKqM6=_||Oo矼d5j___?~\|ii)N-Cb+V 0j?A`jSX?چa1ь;}֮]cb̘18pRRRtFyq]̛7ǎ;aaa4irss!J?#( vA.I-ZCtvQ(HNNFzz:~ǥI&(**µkNےp)_RQ=u.]`˖-`}(,,D>}/sV^mvܖ,ˬ,|&ÉC ;~-޲e 0sLR4x̙3fʕ+q| 7Gf>vZd6>}lj'> W_}j2>>ϧ76n܈={r>sDFF>z}Kǎzr7iC@zm܊F#~hY\Cpqq;֭ݻ-[y۝O>hܸ1`pss+N:L***؅b|sҥKXh;x:khѢBBBW_t-,5k$1ao_|9K, wMZ K,a7q8t֍S&)gggl߾6l#VfM\YYƏϮEFh[G>}R"44>>>X|96oތSNqm*>>ϧ7/^ TKHH@޽燝;wq5Pm1a1yZ΀dSWoPYAD ӎY@cV.fϞMYYYqLL ݾ}['̵kרiӦvZJJJɓ'fΜYEٙƍGՔJ:u"b blBgϞ R S>}-\Y:_tqrwwFٳiҤIԫW/:|0Rpp0D@ÇÇȣ}}ƍ$Hu֔N.\VZ %%%Ѷmɉt7n޼ yzz+++)88htQrrr(dߒ+ҀhԹsg iڴi԰aCGy\zƍGnݺGQII {K~2ŋI"PHHsvn:t@)))DDGg&0 -ZHGfSy.))uڕ:+/N4zh>}:… I.ѦMŅoОRRRYfGزܵkH={ >W_C~~>EDDPdd$}gRHH%%%ۺu+S hi޻w `pTر-^z/^'ԧO~h˵m۶M ]yzzJ2YH[&"֭[:qRƍ)55h'BɡҊ+hմj*ΰ&=TELXzELmɊGMJJ OJW^[n_E<$LFr UWWSyy99wm߶BkvZYacVcuA/2cF[cۿik hj#(-agg3gyٲeT*EYY{n1ۡσع ɠT*\;;;>ׅ ˑ&M8by˫RPXXHR888 Jk<] Seʗ\"ۓL&CFFlllвeKκ{bdT(y&nkF-,!1j-K'D :oCbnt=TmɊs9|0ggg888S`kknT*!!Q~ynPPpPOG*Uz74?s "!Tc&|ؽ{7=s.~i&>斀qD"Ajj#oϿ<ߪXPkBƏ漾qDD 2fi=QիWѱcG 0!!!B^^?jq<&~bʳzȊ+O `H]#H?*dQ~4`ڋoڵk<>>:u^l̽׮]5lCԡU`hM68q"v{MctKP+n{O 1zhۘ={6V^/_ǒ%K0k,|種ܹs9Z#).j ?x ,[ ;vĺu8o2T"1طo^xXv-f͚)IC| ׮]˗͛7~3TPz1ӢCn.ԐS@AЧOM</^lLy9sC itl(*Bv^ޖpttO.66$_! 6/Wk Q,EByڣ/~Gd2̱ӧ㧟~b(..cƞ={u}K>G%l1).jBZ9s9VRR{諌|1[(^s]"6-[PZZ'O㰷ǦM8s>7ujkkq t}s=@?!sb|>Dtҋ{С(x!Jq},^#F@~@>}piˋJ–&L]'$$ 88K,m^z͛jlDI]]>#t?|XSKCg31h.js,Xh @;t px`?C `$cDPXXlwޝ"## dgg\)@CQTTZy)y饗HP#ruuCQuu5M2\\\hTRRBo;Q&QNɓDD駟RPPݽ{ՕΟ?OԿrrru^EEE4|g版(##Ѕ xԡf  D{eGDDcݻ7ݛbcc)??<<<6b"^x^|EJLLS>}SW6!TTTu9HM[߻v_$ˉhԨQ?3ǍGDDuVy-mI'm.O8>is>i}@АYfwa]\\`mmQF&OM31|p\tU^}ې#26uWSNe9y$믿2]\\p} :L&KC4/ݱa 6 uuuΞy{5= Uf]-m077?=ztq~WYF]ۛ76ٳpttD]]k.^?ծBᓅ eO?GGGXy8 t}k pvvƜ9s0tP1֭Î;hh'ĶĠsPH_ubF 𩩩ڵ+c=0i$׭[={⭷ނB1n8|镳(V;3#D"ADD.]cǎjC@$ 333$$$0A<'%%aj|MfO.e^l^pjARyK.aȐ!:f 6&0CU_>~G/Ԏ1ۋ-b^ƚˏT'n559s <<<жm[ǛGΝJgϞih"`就An8\%9BSmpuaժUPŔQUҟ=Ξ=1ò@W نO>͛6W|C>}`„ HNN@_DA+bghhOO*iii)V&CXz5fּ͚1D WH+BDDS ilyU?~UZ<|%%%h׮gbb"zM&Wk |vņԗuРA8~8Gi#nƔUwmΝ;k׮8q2H$ٳ'3 .䕽!t9RٴivDpܽ{vl !|[b tڕ^IkWMdძq%HK& !Z׀l?4ɷCeM8~,5 tѣ(++cr01N< [[[,[3;wjt\},h"=+n߾W2jkk,J.%D3!E/`ɳc.yu >>>x{{3]tћ̺ҜqK, jok1bߖ-[0qDs 8զbbbё ʥX|]FIG`%"'O uԉ)##\]]̌bcc)00`&'###ݻ7ŋW^dllLV=++$ ܹn߾Maaa4{l*++ʯA[())IIIju9..QMzz:[N[n?nܸj2&&&ׯ_獍/@VVV4sL&npfP%"AY4}6hiHOO'KKKrvvO>)??3o]a;vNi[tD2džD ) ""z~MM 2G6$ԆhJJJO>a+++횚fLJBCCBb΋APЃXqEm6_N7oIM4T?M?jMqK>}4cKKK̙)ӕQuu58q-e+-iUʨzM4.EFFRNN]|Ξ=K4}tS^eWU"V/ -唛+'9v8qΝ;GEnݢ|z1T**"TJ%%%TPP Si jiuo^mk!8p&L`Uښj]oee6[|H$Ҵb?T`g&b}"}$Ģoߞrb333 >\0.q@(戥m fhڦo۶mHHH+Ԯ566~/*+X4$߰O}vCP(PWW)'5')(PE "H ?7xy=fy] M 1~OK.ʕ+(..}]h {t0o`L4 GUU>|^{MkW4^PY-I]]FN]]r9Q[[a$Q[[>N?׬|+1 Hm?#mchcVvWkhl -ܳΝ;)/]]]1e?0 ̏?<3-+P3ӚhR$&&>|xzU_4Ϣo'::ư,,,`ff333&&&Lèi- @-9ǾOxljtȈeAd24 0` h%@"0779`bb4=L{VmYk644Bۍn2:r_4ot 0`TVVrR(wF555(-- ~"%\tu4@C MEaa-h.RֱQTT&Rt%hN|ZKhJZs+**օa#--I7lQWZU>N8"؝;w){ Ox!Zͩj;wOUUUJFMM Q]] LjHRTVVH$~JDt]U 6۾ OOd VZfoSP]:u ͛71g3F缮] o |svڥS~--Es峦W}R1_~A^ HӧcҤI3f ?{__~͛m ;Gcʕ͛1c <~XtzoܹsӧN>2e Әc}gE+yH$wży0k,xyyaѼg{#P(ԩR)PTTT HRǸ>ݻTݻk-,̂b|]!zf u~1&u>\\\puvR)/O -[h۶m~yy9]tFM~~~:cҥ Ѱah͛7iΜ9P(DQQQ&sK"+sK;]ymƧ~JDYRj2 ѱcGڰa57o[hLҊBg''':ql2D/++# F)))dgg,6JD4~x>}:g}YgUk֬!vW訳ꉋL:{,m۶6oL;w~۹s'mٲ8@Pqq1:D`_ ^z\H=DbZn>)}L"{\---9iJ4ѧؾ};y昵5Э[7!ꫯ2ǦO~wqqAyQTL\;4C5]MM &O/G_Y_عsqm+r:9ydctί5QՙpqqiºMӏҊBgBZ9s9VRR"^:\vv61x`cϞ=09>>BVVC6t?[,sssj؞\17FFF022^z%١}6=zFjrنqoB*hN  ؆m=C~w̞=C?CaƖ-[ 6ann}nj-J;w.ڷo?ڵ v%OLL f͚.]য়~.\'b9r$߿###%%%شi ?annѸy󦖜Zr?%rssѩS'YVVVHHHmХKk֬ =,4%СCHKKcʕ+1qD1&ܐ*f1ɓ'cĉ 2~@=P]]]v۷oG@@ >>022͛7 X}%** wn߾oeeeՄ]vL_yڴiسg>WWW|ի^wyWưatMΞ=+W"//6z._ ZLbSk/#_S"JNNNصk<==Q[[#G`X`F%o/^D~梜\~,V(>fggcŊslقmb̙Xd N*FFFx뭷777 /_ƚ5k?_~r ,@6mB ,Õ+WZsE6662d >%&-o{a1|p|wB4^q11|rlذB.,\ݻw5Rm bbK W!s6{Ȝy~ 7dn.Bfחf̘u>|vEDD555ԯ_?ܒ%K6nH .$",@ׯ;wPQQ͟?9e3g1555oQmm-REE) zwΎ ŋdggG^^^t!z?`SSBA {2󣀀"~лwoݻ7R~~>yxxoͪ?Yƶmr3g 43->>>J 9s9V[[KfffZ]\(t]rtt$WWW:<%''Sɉd2uԉN?J+&>:uÇСCŚW|d@H*&###f?33ѣGcjC5"%%%N@2!ꄳ3EDD0ФIH}?p ˳d/_N[no&LA}7ԱcG"⶟.ϊgx|2QUUUVVRAAݸqn߾M<"JT[[K BsX=dn$2ԇy}\g=dlȜ*bghh[[[f{̙8v/2:̃ &qef1ݦ{쁽=3ڷo.w}HNNP?,eҤI{B.ؿ?QXXDz'Ǝ7UNM9fBll,Μ9;;;0];wÑêٳgsx/ɴz|>T;־}{5P 7n|}}K/!""r 0sLx{{lll Wl SRRxbef-©S=>}ZmX_aȐ!xPlbŊĜ9s}*ZFاd5jիW#//qqqC\\ xg3PZ1qذa6mVXc޼yyqannx{{#33aaa:^;6l؀*TTT0ܠyv///0Cpڵku6MokᅦT*Ŗ-[?e?^z &D"CRR7|Sͧ |~,Vl|\nܹ}I(\~iii W_}J<4 ||||rrؠ[n5\vb ܺu =z4ƏNј{cꅮW Ƙ1c(12 1%\k yIhI1k)UA:D|M:!faV͛ wLhL jocǎݻѶm[_B6mw^3(UVҥKHLL=VX`$$$]veXf͚?ᰲ)Dxg.9UÇQRR<ЩS'GL k׮CHIYY$گ@hiN+S{@Yb[Ubd_|pd2_2uTVZW^y±c~s|r{aܹ>d29SLL&ìYnhpwwѣGQVV刉a͇ONU<==AD8+FS-zث b.5O3-["ӓ$rN6ACG錾!RELX* ְC۶m/=zP3LYY3Vҥ `ҥȑ#1p@JP(͛򴍍 Н:u*JKK1e!''/fԨuɩ*DŽ /D兑#GP96ZןÇcҥ$ d EEE1c⇣Fƍծ{ dCuUxˋy1#Z;[SP^^l.wMW/*BEe,DUUU1 l. ɫ?`P휲Z %⏏ ,M&&&ԥKJII!"No֭[?T{ONNAZh۷oSXX͞=ʴ$d24֬YCZ3BIKCpş'Nuܙ.]Js%Fc_}RYo>ݻ7!C-"%%%7('oCǙYd2UWWѣGi̘1O /TQQ5˜¬i.̪efU2g=2FcV6:{! zl)'"fzbP;I999te:{,EGG)..dQRSSC/|rrquykP(TYY{͘1c֭[:[RRB| 5a6ƍǼ'QKwhh(UTTУGXQ-sMM  @3/>r2suV_ᢶ ᓙ >ۈ) OK}<`}uu5` &BA<`PXlZ"S6j:q`.JʬbPҚ!TfGwEcꅘw>?3b| 86|LRF6bR2 DmH$μbQ_0|pQ -Vf1 s+њ!TQ]Rw0`9###bW/ļ4Y _S"՟I=xL\}sL ym?#$i*ins )Xcr |}}1vXUUUx!^{5q*ŬYD]_\\ܠzbb"XgB@.]]4闛7o۷cԨQz_mܶQO-?ЫW/$%%a֭Mv/-GC; ϧ95qq8::̤ r=9LMMann A.C*}d gS&m6q "FrDQ3yAO`zq1вܹwP?#Δ)SZX"i.,**믣sMrU OsFb\ǏO>ש. 4A nWn+( R<[o "]zmՆf_èD 0`  {jQ߀Q6|=D=C:{m 6~Cd 0`oĶ}4tx(ViN jĉ(**ҲOuu5Ν;נ|Kwuuu?^&hSAQQ@YC+**~Bs,o=OhN{6&0`|cjOByk ???]WVZӧOʕ+z߆R:jNk!!!?~YYY7KcuИrM9dϦ?B&W_eM>?h٬nݺo||<>C8p@+?_J/ƿxVⷪObc]\H?c忭Eg Ђr~/|M9&\+5CC~w#((%%%صk0j(6l؀Co>|wX~= )J1m4,\Fdd$/u=%ŋ1b׏|y;Xr%>3~:2̟?|&LC*r據Y <<>>>{Y >WXcʕXt):vggg '!!Xd m777 7od~@xx8r9,Xe˖5>lNnlxtxyyaݼvPBD6m2lܸqqqD*"44ׯ^**(o]_~G^0g5jO/TפR)>C['OVWϸtǑ˗wcK&]w~o\&GsM!1Cl=d3껷A{ 2721]x̶/͘1ӧ3]vQMM ׏9d#"7… (++Ν;TTTD'{{{Vyjkk)00***HPлKvvvTXXH/^$;;;CO:v 4hݻϏX?8ˣ?,״4 $[[[/I&BݻHtyJNN~?~L{޽{Sll,瓇ۜrdddo; ޟ \ݻSdd$s. ~WF+(ևrss֖(11QT#ruuCQuu5M2\\\hTRRB 1:.qO2:uD'O$"O?Tm(MUQ++Qzz:3gѩS>|:DQQQy͙3 vJ),,,,,hΜ9LKIIINݻwQ-~J=FDD0yФI}C7O/PDDA… K|Yyf@˗/[7|C&L`t'TT%qĀ4r7d'm2CQٳy\zAAA2d^x"44h^ٜq/"""+W...۷/FΝ;c O IJJB||<^y$}+lll< 6رc[n۷/<<<0vXaر{./^ ̟?''сt|:033̙3 Avv5\Cd2" iӦaŊؿ?͛ǚ^ 6`ƌǪUwҥK5jիW#//qqqҋ/!Z[Bڴi#8DWy^SVqqqΆ/_Ğ={[ϸţ{]5J'''tԉэK&] 14Р^$]Dj5ɓ'ʕ+All,3|@}>}:x {{{={Nm(r1*6RSSѵkW=zIx٩?o(kޏ/~?/}%o&ڵk[ϸtg*Ƙ1c(1zJdjL1`;@ۇcĉ5kNl߾]ot4 }LͅM2]^1vX޽m۶ſ/i{EqqگVb^b #!!ڵ+7)п>DII ݧOUL:DUVW^Add$&Onlmڴ%,-- oý{@DZ/B|U7:O###Va?iJP:S{,*]v՚& 1L:`՘5kD uڷoTWW*NNNh۶-ڷosz}WklyC%ɆP]{1Y 3.7YGdd$-Tdm4T::N8Ǐ3ǬkjpIR|5c oؼy3f̘ӧСC8vگwA^^/_`޽???̝;߇L&Ñ#GDGEYYsL.#&&Ft "?9\OOO4|1fΜׯcX` SN5J,`zOchF@ҭ[73KF61`L:'0/M4>ә׹;ׯ`'Năz7ˬ1N< [[[,[L\vکMhPXX\}*oFEE|||D׷tn(r\uT5~!T\]]qmV[[dzƥc}ƍ "1/uuuHOOǽ{PYY/f̘#//aaaMlaƌ8y$j?L\V\.)S4JB|_sΡ 111JBPҎ5 nnnطos,..7nd8 ֭Î;%Gee s=e˖짦:tLy>$$OiρSP^^lj7Sy]!!!BHHp̙3?gΜ!ooo@QQQT]]y> B:pP׮]iر4~x4hٳWGb}hРAf*//] 222cǎԡC:qݼy \q M0޽+' ՁX>*++ۛ,,,($$?N4i$Ѳ&4n8Z~=mڴk\BB988Pff&egg u҅RRR~;wRǎԔvޭvBAaaaOtmQ'"Ã>sP^-'N ;;;ܹ3-]ΝKK)))ZGobccዟ y^Đ# 777JKKcq3.Yo>ݻ7!CЉ'IIIjz/4? xVL*++SeڵkOOǏSee%-: ̽Y=z}_UYI45plDins ,2 R]]ŶԷtPRRSSSXYY1 L82 ())?7|KGŝ;wЭ[F}pz }<_yTQtkwmDhBB2"$! d !\ ?/a!BKk vk̙sgf3Z]]OOuo{&%ya8lh4yq7j/,|rxx-_YUh4`P3b2ݻwgʥKVFj޽{|ۍ(=çyZ~pxx8#ޞ?S?T(_YpX|1<_}uݗG/Vj~lts@ʐew|7/W^݈Hׅ>L~W9~-'MOXWKyewwWvvv:I)ɽ{#.\K.M̍c 27!sD: @NN>`?8m |`0x 3@_˗m  H:yd6;D5jct}U;)vFOr]9<X\"'?лhCl"o-qc'`l~8٩WJ y^MD6{J (zTV5!l"sωsFkVXd }ѲQ.^`888oV^u]<7嵔3A.=G+ey.֟K á|w'򋈟c{ha70ږc Dp8ׯ;#oևҙr~휽Y6E3$Uk>û"o9 Qp/*zDm{-a"^@CP.g h (96PY5"2L>>>>>>>>>:-;Ɂ 6D%/?l ldߦQcmH4\./''B0%26/ vkEOL$HǣH'"AE^9-gWi}[Vd)xۥņ4l/T=[fϥdۥ,D7o9>>>>>>>>>ճ=6"qOSI/u3^w/au'~z$Sݩc9T|]^c2utS㯻LT9Ifeڱϧ{-z^eѱ:-0YDcKIP>>>>>>>>:ޱ$~Q2m8zb9fcuxoO 752}68I=9s&C75pέ'Rcq?g{E)(q>]n׺]64ѷR|uƆN-Q9::S+F.|||||||||MYt@DC̆| ;vrOzZw~}43}7肳]{wpWzg^i)~)x0d}]{w("r֦"XJkک +mm3!s `_qڬsQxSgGA%9u&Nz.-( C^헩ic H!𹼌]ۢ>>>>>>>>>l鰽=B޷ǽ Sm{Dt:iiPNf/_u{zzא_O_g?u޶C/Qzasv7<{{k[t :EdiuRzˍ, s!6pq6>>>>>>>>>~֋loOm>E!+ :MvԘ>nʲQ6eD=>(Q/nkuzhWۿd}W"h99i BpT D}~&ِ &r4AHO-rrtLyfKmpˣkڄon{>w:\kjw3MnNoz["g{yg0dmlOѢlڃc] EI B^[^!m/~9=ڒi$ T=omo[zam"yyU K}'Ua&pDf:$H2VG.˦$~||||||||||{a"G#73$2;CѻG6Ҵ"{t y(R;sthҽB:@SkwNJžW{]o{wl]/NymXtm(K3e^>2g( yd@;Dߢ2/ yaH*yGkdʪ@ueMGl$ʽDz?<trG*OmN2 Cdjx](wrrӼz"!lEZd?9 q,>\-{bI鱣 SG$XdsH%oELx=d;\'CzEǽ }8~- EEl},UfQSkw2ۃϓ'SоEgO>g-iT?m]_۞,"[?jw,dY}Qe-== Z;g LNufC!hS|v1mE懸T 5]0dۜ9l}E̕nFu{DD_&}{M0X]}/4v-շNDS,Nh{S:wHAHBcRrHr)l{^9>>>>>>>>>&lZ[WEy_ԾH[a.D-npT?ow#/6vjc>׶E?o~7֋B 8Q I水h7Q:Uv.o8sr]&%9^|owRjSru0%}hCcm{ޱyAa{j) ~Gߢ&oǤq^hҍ-r[;`?[+ڐ?t-%j>>>>>>>>>yKe6 ٲZ<;WM1 ߬(Z8KA'mЉFmy7>>>>>>>>>&6@Xz:*|>,ڟyۥuW[eZ6|||||||||MK.J$:V LyjLW7/Zu溶̻>̫?/~KHBOINк)ee@dˢmXr:.tYIs(LcuRW @uzQ}oN-(Du|N;{u>=@-=AMaHdҧ_ ?Qys-RZGpZJz2>=Eo/aMTOX&ԂҢ*Ye KpƖIQ +-0TkV_ݴZ&:nob^_Z</OSڟ+ BeRd}"|.>d@rZyeJ!d^L}'.>>>>>>>>>mkӧXM>{  }ꯪg 9prEShi :+ C"0 G},SFљ Y,P^rV5"MXo]?sֱGe>5l*kp4UT}IENDB`Pylons-1.0.1/pylons/docs/en/_oldstatic/helloworld.png0000664000076500000240000012066511645401275022571 0ustar benstaff00000000000000PNG  IHDRD{ iCCPICC ProfilexV7~ƾ$Z5 I 1)jLdikdmSd"-?y;{N_=s>ys9柡<\8lMhieM2 RT:OOUif&zIoy{n?Q'RƶH:f$mbGl3>@"f }' ؚ1x i$l P ( ttOxgPe +p}@wub . ;DP@2w_ 6v`el4A j a-  c%~Zda` ؁# P||Np?v01Adhc+A,M64b-?na7B$fsaš= !i(BưC(R\\\6\p}$KnYܣ<FޥU|2|f~U%rтXB4 uy.E+[#V@oA>9RzR=Ҿ /\mqڒK&eRdd?/|jbԲ(L)(0Pܽ2[wZR?)JFfVڽt+.0o#Ư7SGF􇷼53@unvIcy;t{FܮjݳK6Z97g_6MmCyWNc.+\n},,θOoT3 ;<4;l6|ѼHVTq≰Ssc&ٕڽgV7ԑc&Kg|MΚU녿^녿^_/΍O,to&kdwxl8e0QU2P_H$A(x ; ;@~ )MB"!b$ۥ.X,)앂v%c*VYZ]EJ&٫{S"55ʵ+An#yu3j 0mIS3Mrw,5dT5k0ojnimݻ}#jc)٫9:Ҝ9xE{>>͉  ݃\Bh aWG'=fAj>qqdǩ^g ccJF[$('|9Ww>1qo1i0څC)kR/_OݘFHNl ŕLZWeeQ-z(O"[kg * Êhn/N.)U*++(X[N]{f=Tzȣ\5QWsVAz '6[4OܝagYfUeݴkྉ_mx0װ,98;e992]C&SEVQ]'//A!aG591y?Bqj1bFO֜:NplO܍; ?h̟vREK\SXok3TɜzZD֎lޜ׵ݨ;}HvF᧢źų%Jm)+8~ݺ{aߟyWpÞG U;jNԥ՛>&<.l`=zRӤݢ5)ӲvŎgitv9{}eEo-}} ^~0jhbhwrc5'>Nҧԧ?욹$ytB,_4":Edx.S%,P8Mys*AEjvd7e^DFMZAziU[3*aMgc[;/M̾XhhEݿe(3m N ^GY'!oדnW=Zg9R^^xyW_x>(:8 5@%G돥EDRq1{N:Xq/f{%P;u>3p҆d ))̋+/~Tf.v9)ҕEWg g=NαUɝ^~H޶7_ܺ\^0UXXyr{ijR:]VXYQN]=ҽTJU6?z{UqGʚڋu{54zrqk㏦fcm:mO }:tYN.g/.tY3zWf}Kx4x!aF{xsɤTt׌ClmliOQL–o܌ }כ 2ZR pHYs   IDATxwUardHJd@Q]pQuYwUqw}QD@W (HPI3sP?.;TwWOP>O=]U[znOէν@ @ @ @ @ @ @ \h~k+@ v.@ @ e+.Q[?.@ HVB6>b+X^ {a/셽^_.DjUWuF @ SƦԚ 8l@ . 忩8/QQS1_yC=SHS {a/셽^ PEG0{"E^MQ DS+jF25@ j#NB)83aT"Q5^C${R^ {a/셽^_.#5 jQ( AJF}(@ $j3-Py (  f=@ ʦlڈCJDw=WM0R JVk34O {a/셽^ ^MǻnJjv R#}8/[&r tu%q -셽^ {a/}]?ݷՈ@uvPjET *%BW @ BC}5F&BjPQ@BȟRER^ {a/셽l,*t'h\u PEu&RCM0qt,2>)@ LS^ {a/셽UǟQ*'˔𑂔{"~AF )TW?$핎OlgP:t<5{a/셽^ {a9FJ#W_I$Zl]i[ PĐv0Q]>5\-셽^ {a/}MEp7:j>C@PMD*AWS _bh?q/~ꨐZadH$yC<^ {a/셽^콷^s&b}۵}ۻ̽ݷ]lEjQ0(bȟxQC& m}(@%P ]Zwz.d\6bLI{ׯ5DG 1o=Xna@ƍY,F5Y @  >{+V~w@bo@Q#E$yFMD)⾮$|$@?В1bDԱ [\ @ Vdb>cڴi[l^Bri/|^%'y}UUT눘@ @ G$IfcccK=@bofޓM9D+-~Sbbb_VOn @ f_1.=<ε/qJ"%Np}'T%ZF(XdȥBs/^Ew/U#"Hmߞ. %.%F\8a2 WWdYXMFSn4 Ο%E**iX ՛V01oObB̬^Vkڦ@ ݎVE,6}tt:nt:q}}8/$u}JdN+](44[u- `UU{Vf =4f2tzR+fgQYZM[0őд :Si flF;ox`:Hvb+,ئhi4hk6dLǾi;x~b+QTR¦Ij6/L4 :vpq222)l6駟صkO:Yr%$q3w^nÇ=^OLLv5kv͂ 8y$ 6d2oٿ?=-Z`0|r8 E4iʳXp!7o&""8E_Y~ԦO-\^{aÆպ-~UYYɲeHIIh4h߾=)))5P?Pk%AAY(m+*{&ۧlv||'쯬7j֬Y_֬YQn3i$N>M裏x'<۷Kz,.wߋ/Ⱥuh۶- ,w x>Vbԩ4oޜL{1֯og̚5̘1UVqF6nȮ]B!Xyff&<z)~gE_~'6n(oS0rtmJ>S kԖ?@+ZtCa2%BuQ|!yB r(}K#wD8 ,.²oN8aaowXm^X4eE~Gh/`5g8j1q Kt1f &ive欤D%@RX[Ll87,w=H75j#<TX3iӦǶܹg}LJΝ;c00bf̘֭[=lt:ׯ N>}[8q;v,'NmC=M7ݤ޽+V If :'"a{=NJΝǗ-[п)5Զ-~իp/U  9EJvd5o~R~sOѣtZiDx~m13D:-Z:Xph6.KbH,Ia#l'0Taǒ%)Kb?`'rм[I c '<ŒXA(-#-DƄ f]8s `bX~Y\̝;Ç3a ͛7;wl2Fƍ?ϨQQFsN1dy8'NdӦM>߽{7mڴAmٲ>}ĕEӻ,;;BJKK+..KJJ&;; {9&NlV~V^5\CYYeee8N:vիرڶmKii)o}r»СC5 aS\\Lnn.AVW^QZZJn8qǏpuVvOID~~>SL[ncǎAkW^yaÆ1l0^}UBzN>$I\'|;w2n8΂ d{ɜ9s;1bϗqٵkcǎo'$??Icܸq|w};67͋E,b,(B|tPDjW+Cf(l-($٠'l"j)2łj%20+13Faی0sBHb/%D0(})v Iԩ7|3k /?Z-s2vXRRR'|"gȑ֭SewU|W_ѠAڷoXpBn&dff/pOVVb,h.\x»,99cz꫼bC (++#**J.7z+IiӦL&U}J$^~e3f/2̙39s搗/_\YY3g??~<3gΔeoyXt<;~'yGYz5foIeܸq;=zz-z!t:oXYP JH̩=j"EåQ tz&L&:MXX,@E24WTbsE3ptV#Z ݉ҎƨBQà ئAl6n6ci1tX:=;6;vɈ^ئ@ {L.^ۙ6mQQQ9RF&%%6{FiӦjiԨ:u6mڰl2zM6m(**{a/V">>|8/M4ᦛnu֪ .ܼ2N|y.su;QgzC:R}_u1 U( 0R!:mXH4 Ri)EEJJ(XE%R}]ŀƬEٜz; ΨĀmĥR^PYoĬc5 7̀DFNyT!hԨo%Iox]t\*++eqJVV999)&a8}4hj7l2ϟlVlc֬YӇf͚IMHHd(**"!!Aqqq> )&p"ETTz3o< 5PCeee{^6oԩS}_ʾgr:p,IRuTI&ɦM?~ݺm6ܞ+sE "璒_rss)..W_@zrƎ˗_~Iaa!:Ax'Ksv ;\O!rjW "s '܅K=D1:qnJlQ!&bcDFVW() шMo|F&1;tL&: h-F4f=h ZHHZ-hh U:8]5l֕-GGa5 3 7aIJ' 6F!ĎP!uѣr*kǟ~}b}6oO?]~z̙üy0͊m;v+V0cƌ7޽8ǎ}hѢ ɓ'iݺuHx "%\7eee\}㏲M0 4i"GK\:ƍn=SL0kV),,JƵҲ=zTN}aԯ|y={'RLIIA1{l9E$Iz-wξ}T@"{{萄g2qQ#%!%jkR~qHD*!sO'%1DL DFBTDCl,Θ9hi06{Ji]2A5Z :0s(2lc5X9"zրAkDգ1h F 8 };ME,,.m7lؐÇzdz%Yj#I׭[Ǎ7(uyҹkٲe ={)''5jwBMwAii)YYYRYYQo…Ѷm[68Onn.$1tPlj'$m۶ǠA$ }~'$II&tԉ%K IEEEXK>ŋ={HRu"($IIDYY};v˃t2b.]*E1h "##㸢xމ$z|޽{rdJ۶mY|9|r*@ܻW^lܸ'NRQQ˙3gСCruرc/:gE,b}tҜ!o}4|N;%[깧S!F1?gDGٌd4V!r:Yr94V$Ұ%3=0džquƿHLz)8p"=i0lӠ5q[11Ǣ3ccZ':ɉ)atrtE.gX1hMgx#ofÆ {L4.]0fO… !ΝcԨQΣ>*=<#vvy7oq=Wʶff̘fp0l0?ɓ')**>>my+oo߾믿^&Ι3go2d1113uT&OLJJ YYY̘1Cl6| tڕ*^~ey6mDNNwy'={YYY1 F)G)~F#9'N;˖-CQPPg6mJvv6ݻwG`>qС>|1c`6w[mݺx>eyyIJJg}VN~nޖ`ԩ<բE ^y/_V:$UW_b=<Y"##yw2e _|X,>222xwye˖<ü+s A psi=*@YxG?OES^C p>4 '77W-PXX(%Zf b>>KqkΧjFAt:)++DBBMnn|򥼼g @XX111- VSNѼysyxTG4h@QQt:9y$hZǣ̔HIII4h$11sZ-999j Naa\`>+rɑCYYF_n%1%:ތӆ6Ah2͹p$EEE1? 1k,ڶmp0i$f̘qY5 z^1^ IDATt@ʵZQН;wsNƌS{ׯjV ?_tM<.q-Fq^gHI{i˖E4&o*olٲ~|@b0 ,, z4nhl.X6APUUπWeMEEbd233 elb[A~%7 g#DJ]y "EI GL(s@Y@))aR.-B2pp8򹰹s$~/m h4sHV ._=!^.\nM jwmy?\%Up4㩞?QLEwj=J'UK~/m !I|@ }_Gut(PJZD  5BdR:=9H#D@ ĕ[gs /\H*-D2Ȑ?s/H @ ]` |_/J wjHQyC˅gȽw]@yGnR!s.G-R>T'xҠR]'wMFFM6k׮$$$N B$%%%dggsY֭[Grr2:tIA} BrQk!R:s}Svc]={x7W6%ڵc„ L>Mkiݺ5۷':: X,rrrjƾ}HMMeᤦdB 1t"IvJp;v`Æ \uU5& u-QCP{AV[ygpkI] yyy{ D}ɯuŸG #o:TwrAtBΝjb0jw#INhHIIaǎܹ6m)˸fJ#\5,ZAo>m4JY#\_?Aw]cv{Г ޏ:Ÿ߇?8qc#dfW&91սMԥ@ Sѣݻw'&&" !!|Z-:шdjb4ٹs':uRی|ZSs~i ŬN;aJKФ ֍Vlnkz]w , ..WN-((ѺK2 5Dv+vҬ1]{%AfN 0;w[V@  :~8iiit֍xL&m۶k.= @˖-ر#=zk1.hZt:uFQQǎ#--MU3*W=s! "{U>$|(xs:{J}h~〺X5tؑ_W',, ***(..Pn}|? dggdw.{iݧ/noKtͥ&,fmT7潯kX_6|Mnfڶm6999} /s~gXx1f4Z̡Cx뭷׿UoL6'Ob2xhC4o\v׮]:&N(OJJȑ#uO \)kҗByS@CnJ' ~ʢWz4]U6FΗEҝoD1MY`PuHOOBZt)C ٿg }݌=֭[{ԍdrTn+|{}r#FЦM㖕1b{uʕ+>|8ǏWjOЧOx i׮W^{UWW_q7r>g%KXx1;wl63n8{9y睠~r˗/gʔ)|OSO=UINApB9۱ٓCQ͛jY|9۷oGhJwߑÄ k$I-NjI&={VmRJ/jnS8U'/ +@("C\u 8y$<wqϟ'66v.A,jgѢE,]$BtRVZEÆ ywٲy }ʕ+yy7?>gΜa<鮻xG"""ۙ={O]M6;Ge̙~mݙ={6wufNK9;vX1;vGhтZqCtt4wy'%%%eѢEk׎h =~!/G}~l<ӭ[7IKK#99?@w / כ3g&LPuNkS^^K.婧bҥ\  4 $qa$I{DDD`X0DDDн{wNM(,,d׮] <FJ|!{=^{5ΝK^^\VPP'|kƌ3ؿ\fYx1o3gdժU~Ko{q…ӕF!F\J ^Yh(*}E⬪ Z'//7xkVq7>ƣkCѨ:TIDff&_5 6[nP0✿k2e ]tC2zh)//ԗ?>}XFɺu4h{|tڕ+WKEEM|*wtݰA_}ozPɮ "1( Ng>C4}nMAr2=z9m=<3L4>}0n8:w?㏉"99nݺzj"""y=se|wuϝ;fxnӦMYdI~r-$&&z[lw}7z+s<ĉr--**"77܀~=e˖RΤIxٺu+SL'NdϞ=]菈+lVs/hȚk4+dZ7 6ȟQ )E|`_+3vXz=)))bȜ{7-:[)T'/999zڴi#?4ieee">yq:;w 8ҥKt 4ȯ8kٲ%6m3ivhv!@L(#r%ظdɖ\hԢڡ\y?C=TiΝmۖpL&IIIr#))c\߾}!>,{?s<ѡ|rssiѢ/ƍ{OxYxɴ>#Jaab]W ŢXW 7p._'OΝ;y7' -S0Ԟex}i֬)))إKkժ?#7tm۶^ctЁ'|$ap^7nژ3ΰvZKW7o.iӦe;w{۷gر-1c(! 1.4 w&11/=ׯ۶mܹs 233 ]vr6>Lc6mF>LZZ4jԈ~YaW*^d ^Hi X rvMxM}_v$P"E4 ))UVzj͛PF("wt::u"--RUm9[VJKK)**ՙT``OUUO< .\?LTT/Zs~ӢE v ~,\cz":b#DGa7jҾydxkԥpVӰrf-[*>uTTTp Ė-[O<>@ &L\NԩS߿?={FRR|vQXXu,**_քx::RSS0a/2&dZOJJK9r1:tQOˑ'W$ƃ>(U#hϜ9CǎDRSS=<Xz_^{ʂ #OP=W_e֭|WAG ~뮻0TUUa4}gJjvu0m۶vZ@۷d֬Y3F2JDFFmG,[* /,,p 1 L&ӧON ~Iaո!F)+w lEu@Ce}l}uv뮻}l29]6Dh4nݚtN'o;uĖ-[Xd vGOzz:={TuN5f1}t, p3ϰd1h F-? ڵkP}q& #' &DEEDX&Su4hBIGD31Tepmȑ#$@pa9,]ѣGtz={fD|i׮ӧOv;ǎSupwTCtҽ{nEFh׮GÇӤI0LRsk֬anpB!gEEEdddbjq9~jՊu)Ϙ1-[rA>gTܯW&Α#G0L{w8# Z-={ŋX ͛7su6۷oT A+0t:xNxxǵ0 TVVRZZ*Gsss %%\9܅j[ne/dCMZt[ɜ))0yUBiQu5|2d3f`Ȑ!H"--!CF~~>TUUI ^gѢE|М/EU4^7oƍ㡇bʔ)L4Ν;K/1yd6mC=ѣG٪lRmI&UzmKUf2NLD-IrDDYiӦvbb"fxۿ?8Nϟ?G 6p cp:$9s)SSOQQQAaaτٳgc4}Ƴ;rt:姒 ,QFl͚5<@uTeeetR?*f6Tرc~IJJ74f,X G}$7_gGNhժ|f(mƶm8p$1w\e\͠AcϞ=rwƍYq)-IСC||GL0'OJT^^ݻ/صkeee>/A~~>Ih4q뭷2rHڶmhh4Ҷm[nv8{,op`b~!W == .ȩwލjaÆɞ={$Ξ=Kzz:P}eٳg!pdCf2PAhCW[(i OF}r]szϐgu!r^woU VQFi^Oaa$T=z4~ ˖-cܹ@ָXFwq7uObb"6<.\Gйsg>#K}Y Ĉ#S%ו?p7T;h,k}u1DEiNZ'bgJKocZ4N ްC W_E| 03p@y9ۗd믧ŋ|=zxm۶ѡClr^{-ǏYfу e***[W]u{W^ͭު8p֬Yt֍;NW_}i޼9gΜ㏼۲(z嗹իϟ矗#-999kۗVZꫯc=ƓO>Ν;IJJbtޝz ~˗p8e^z1f:uDtt4<䓲 v뭷/{IMM%!!-[tҀvgk׮$%%a乑Zz!nFRRRh׮Çvܙ>ÇGee%>,> G7ߤA4hЀ{w 6z@G T̤yr9NGDD}{v$I3vܙ3fp |M }0h t:g&::@aa!]tӇ3gO|;Y`[nkVb޳gOؼy3͛7cǎ~W߾})..fQQQ1cĐKHDYY6;=r IDATtf?r̟4νn@ =J\Z}KK ҺmҢgϞ;K؍)k` ::l.ytU"!!AN-]Syw(e:t+2p@bcc=^ Y۷m۶a05jӅN#::"ΝKlllйuzoNmiѢ۷'**9\*]8UN|$7$2LWM%e,>iEӽ]SR#IW1qE||ٌlfʔ)L!OJ\uU['s=GÆ 7n\%v'NТE U^O?캧g.w wd%rZh!"%t:}J.\3L(zyț;rKJJZG̝; 0p@u\q9v;vP$p_Zn6~}u;{ȵڧ"% aNqYH{̬Z6qj2D:\, s䤪"dOnݸk$hh42~x***T>qԩS NUi /!t쐴XzU"&f 4DXk;%`b(//޽{+oF%z^=u]aX_NLL 111~?. ! du4_1*OIIq?5yo8qQQQ$%%h4-8f3 4`ĉ?~6mBA}T?T PKl޽8pN>MNNÆ kHPlN8J н+˜{R-zmBDGMR:6X}?%h4^jps...V'??_qv;eeeO]?.­F:^J0Ghi뒑#Gbcc)^)peHA 鰦,9N#>>^EJh4L&/G|jEmQ ďw'˹sī.h4>^6,.GE2@pQɓ'q:lْL&P9w\&b&Q>#IdggsQN>jRMMP,B @m@'0+]/G]}\oQDN ֯_O~v>gO/@ uq$'ORTTDZZ񄇇c4}^*2$ NUU%%%pqHD~vI\IunzuW :̙3_ tf26l `/ߧOVkP,[4iBbb>@ ~MuҞF!**xZ"ᠬrrr(,,=ոqLߧ`<}IRgs8.Be6 w ++K>gO#@G%A$-E>CueNi]my(? .s@ ;Һ' %TtJC@ |. @DB(kzP);@ G}w{_MPeJ(QW3TγA!@ TE} >oVa!@ + -WH!{j@ @ \~d2u!rǟ7)*222{&\@ Sץ~PR}j#>jIӧOPrr2} XG Y~@ TBV B7rP=p01mٳg@N:\  @ YvjrKF8A]!R:@ΟZ)@ +%]PPC} "w@ ?&Jh~UPׂ(P9I @ W.s\T*ϾNQmQi@ @pR[q־FDj$+ d_!Zv-Gm3ff/++VmKD~~>NVP,Xp5vZصk۶m @ "JI֔^Zݮ*fR=D9$Il߾]ҪU+:6 ovZ-Zm͂g%%%̛7Gyħl̙1(~{U}Cnnk(TE*Z:"Rtzx-֎c::*mĢtSZ*RqFD !JBH'7r!sG^>gc<3g|g>_y@6l [l׽urꩧȡZŋ/}Oɾ}dr5ȝw^6l:6l +Wb}#y=#۶m t,Q[pxr'< Yjs=tRue'"rgg1&"gh"9cc ȡnׯ+W< rI'ͼ׺udɒ%""i&Yj_^dݺu266&˖-{G#<"<@7?._fr+C,7N.gq<9ϑu\z2|yS*z׻#K.DDDɳl9;g>r.w},X@<̎@sAyq83;vء믿^~ )Rϟ/Ӳo>YpLLL裏}̬L (:3kEDn9c}r-t]+{:OYi$%5YZ<9?_>l}E2={HY2==-"BPT>gDXCz!Z}jS(Rv130::: ʲə"fhp$r]f[pd9ce֭d9묳d޼y>;w WSSSCwػwܹwZ,,Nm3kńNHy ^ wO~rA93嬳Β뮻N=qe)]w]V99rwΌ{zzZ6n(rJ3|+/YD5)[oU/ʚ5koۺuO{O}Srv}_峟?<)O׾3_,'t| _뮻N.袙|r袋믗OsU??9sȧ?i{җdڇ_^D/~q<֯_/MbMC]}ON^~FG*ψS|6n(\pAWS9#;w[QG%K._3]U0LLLȎ;䪫 .@^׈ȡi&3guYʮ][o>Z>ߴiqҗk9֊+dttTFFFdjjjfVIOzL׿̟?_8 ٶml۶m Ȳed||\o.͓SO=Uv)l۶Mvޝ}q'/љ{6o,,-[&v?~fŽN{ʂ d߾}u֙k8eܹ~7olڴcNh9ꨣϯ#8B&'''b#8B<[:Ym[ݳ|ߢj ۺh޽cG>KBOTYQ/R7f (uoP >19p@@^E!e޽#~a]ٳgOW+VHQgϞkʺh6-˲sia J3[)8p`@K--nmЯoa OyMܹseǎ]{JY2wܮH5u@|/O ,\g\h-v곖9k>kk.f3ZF<i^R5{ :3ߞST.Tp41}-b&;k}Pd Du;֋݇[nUQt|ךDksHnt#mm${Î?ARx?a DwZCn 6{^W`04VX0 D)op0\B* Z]Kj `(Xc9L)(BԦ aN1X^ի oThز8OUg D4RH`5uzv ; ulȲn:cY273DׇNMMgr9KBCc!cSv1ژuoP >oQ;<)BM7$""OQ?,n>TW\q̛7OFFFDDss1R?l۶MDDm&o{dΜ9r5d_|ӟʳ,IBMG~,߸.ՅN<%D/RDDwʋ^"Yx|C%Kʕ+裏[~o|cuWWR/??}C""?_-Z$""-׼53ד*v;#^xe}Ǵ\3+_kxY… ;i!cccREuw222"_җfOT,X q7 yސ^"󝞞Q@vMSR9f'<\~ӟ?,W_}\pډ y{+ ,_rI'ɕW^)GyzeK./rWHQ211!뮻NyYpLNN]w%OMu뭷?yYd̝;W*7{쑿SN9E|A.tuKP~TAjr+cz~w󝎟{v399)W+Bnf e/{ܹ3˲=O>яʚ5koWu}keÆ }ODD]w޽{koY.b{u]'-{ oY~zի^%_|}Z6nh H 7ߥg׳}~vSȪUSy@n香%Dkf~Ȝ#K&/mm`!z,/~;֬YG?,]TVX!""+VWղt,-hJpȡ0{{j1#\r\{wKN>d;w\ve}L~_͛3Hzyɓ~{ߓ>$,X I=&{Ӧ )+eݻw˾}YzVǏwAy衇;sdllLOԔ~e˖f@b=P4K28{xGğEj 7 W^ylݺUx9e2>>.eڵkO IDATk.y3)'t,[Lj?.k֬wrʏ~#+N8A8 f^?ϖK/T>ݻebbB>99>*{d3cK,lZE,eƍrꩧʪU /=irW5\#w䨣… ;Z|~f.tqJhPz(σte @~qƜQz>Ĝ#inI=NsD/! O\!=b!v|V~ Dզb `ٳ(*7vE`p){:OYi$%5]Gm},}@z!Z}jSK0'Θvll,TUS7m`KlYFg! $?'eJ(섚*>#`ž[C_"˺=댏e3D`Y z Ƭ{ Zђh.X2q] A~Z.ș DX =F3ׁ(6UU*0 /Kπr} GMQ1ëig>D@;hMYԇs55M^@!͟ ) s=D)+1;G,?ĎrtXy]=X!,{E7N.{T)+͒h {?TR/DOm`xiӎUj`]Muv-h>D14R`"]䇺dl] PS:g ~k~@dYg,cl9KBCc!cSv1ژuoP >Zr푲PѥK7Ku$O9B_kDz8hf5?:ŦJfePTi J=B9"`x5 7,@s؇hɚ;KT:sK[>D@$;Ab3%s-g)\uh,$zlj .F-jGKn=Rj?cɜu.t!`i gV(;?+b-Xvͬ^TUl0,=55 D'W(0C ZrnR^5YsgJgRb@4yikهh7s'H9Yzl;>+?"jauSNcX~YRL;"0`b=P4Kߣ6>>DXS}J J>ugL;66Wu6E0%,Nm3kńNH}viv%vBMp0b/ReݞuDzd"`, DM DhcֽB-h GBMG~,߸.ՅN  ?- e~"Wvn@*c g@R( f4XXQMJ֋c"&k,Q[C9&/mm Oc9G"K͕#bg@d9Ym:,`i=rQʛi'\ RfIRQ{߇aO Dէ6U0siB^5U.ӦF@Ėim}fmЉX).MC]}^ݮNB3[{5?Ej ۳X1C pס豩Hm̺P-H[Iҏ%sץ 傜YЯ@䊵cYNm4zbSUr A [*p4\ 0k}k ʹIzqCd͝%*qK}9GXQ䥭 d" {̝ 1^CdC@{C,'MŞL9bgQTn Jy3턋8R@u?,IJ j~v@Xc9L)(BԦ aN1X^ի oThز8ϬC:K#!ڥI~O˶ەP 5U}F`}懾H Du{˒9f.:4=65iY %7){ 5]dT:A0\3+\z,IfVCQlTa6^uKԓ+c!Wpcb D97)Y/}vКD3n1k jC?ARx${,=S6WbvhX~rdz)B,?X, D)op0\JSV%I DMnh~",>%^VT:̉3 իzTM"[Ѷ}bB'bi>D@4uzv ; ulȲn:cY2 0r…^BǦ"b1B|#eo&K?o\B'H rfC+Beq@;ij~u MU13n\_Q@zrr 3DjnY(&%űZ5wt-!a DM6}v'H 1wĜ#zygxJCn 6{^W`04V˞EQ(ʹ.K)xJ$)=mcC0է S*^Z9qƴccczU*XiS]#]b4ڶ>QLD,؇h&>Y/nWBa'T-ߚ"5YYg|,K![RXH@]6f[(Ԃ@{-$tǒ9R] BrAάPv~W rZ,h'6YDR9 `xYz-k8jROPa^MÍ>5ܤd8!Akθ>Ĝ#inI=NsD/! O\!=b!v|V~ Dզb `ٳ(*7vE`p){:OYi$%5]Gm},}@z!Z}jSK0'Θvll,TUS7m`KlYFg! $?'eJ(섚*>#`ž[C_"˺=댏e3D`Y z Ƭ{ Zђh.X2q] A~Z.ș DX =F3ׁ(6UU*0 /Kπr} GMQ1ëig>D@;hMYԇs55M^@!͟ ) s=D)+1;G,?ĎrtXy]=X!,{E7N.{T)+͒h {?TR/DOm`xiӎUj`]Muv-h>D14R`"]䇺dl] PS:g ~k~@dYg,cl9KBCc!cSv1ژuoP >Zr푲PѥK7Ku$O9B_kDz8hf5?:ŦJfePTi J=B9"`x5 7,@s؇hɚ;KT:sK[>D@$;Ab3%s-g)\uh,$zlj .F-jGKn=Rj?cɜu.t!`i gV(;?+b-Xvͬ^TUl0,=55 D'W(0C ZrnR^5YsgJgRb@4yikهh7s'H9Yzl;>+?"jauSNcX~YRL;"0`b=P4Kߣ6>>DXS}J J>ugL;66Wu6E0%,Nm3kńNH}viv%vBMp0b/ReݞuDzd"`, DM DhcֽB-h GBMG~,߸.ՅN  ?- e~"Wvn@*c g@R( f4XXQMJ֋c"&k,Q[C9&/mm Oc9G"K͕#bg@d9Ym:,`i=rQʛi'\ RfIRQ{߇aO Dէ6U0siB^5U.ӦF@Ėim}fmЉX).MC]}^ݮNB3[{5?Ej ۳X1C pס豩Hm̺P-H[Iҏ%sץ 傜YЯ@䊵cYNm4zbSUr A [*p4\ 0k}k ʹIzqCd͝%*qK}9GXQ䥭 d" {̝ 1^CdC@{C,'MŞL9bgQTn Jy3턋8R@u?,IJ j~v@Xc9L)(BԦ aN1X^ի oThز8ϬC:K#!ڥI~O˶ەP 5U}F`}懾H Du{˒9f.:4=65iY %7){ 5]dT:A0\3+\z,IfVCQlTa6^uKԓ+c!Wpcb D97)Y/}vКD3n1k jC?ARx${,=S6WbvhX~rdz)B,?X, D)op0\JSV%I DMnh~",>%^VT:̉3 իzTM"[Ѷ}bB'bi>D@4uzv ; ulȲn:cY2 0r…^BǦ"b1B|#eo&K?o\B'H rfC+Beq@;ij~u MU13n\_Q@zrr 3DjnY(&%űZ5wt-!a DM6}v'H 1wĜ#zygxJCn 6{^W`04V˞EQ(ʹ.K)xJ$)=mcC0է S*^Z9qƴccczU*XiS]#]b4ڶ>QLD,؇h&>Y/nWBa'T-ߚ"5YYg|,K![RXH@]6f[(Ԃ@{-$tǒ9R] BrAάPv~W rZ,h'6YDR9 `xYz-k8jROPa^MÍ>5ܤd8!Akθ>Ĝ#inI=NsD/! O\!=b!v|V~ Dզb `ٳ(*7vE`p){:OYi$%5]Gm},}@z!Z}jSK0'Θvll,TUS7m`KlYFg! $?'eJ(섚*>#`ž[C_"˺=댏e3D`Y z Ƭ{ Zђh.X2q] A~Z.ș DX =F3ׁ(6UU*0 /Kπr} GMQ1ëig>D@;hMYԇs55M^@!͟ ) s=D)+1;G,?ĎrtXy]=X!,{E7N.{T)+͒h {?TR/DOm`xiӎUj`]Muv-h>D14R`"]䇺dl] PS:g ~k~@dYg,cl9KBCc!cSv1ژuoP >Zr푲PѥK7Ku$O9B_kDz8hf5?:ŦJfePTi J=B9"`x5 7,@s؇hɚ;KT:sK[>D@$;Ab3%s-g)\uh,$zlj .F-jGKn=Rj?cɜu.t!`i gV(;?+b-Xvͬ^TUl0,=55 D'W(0C ZrnR^5YsgJgRb@4yikهh7s'H9Yzl;>+?"jauSNcX~YRL;"0`b=P4Kߣ6>>DXS}J J>ugL;66Wu6E0%,Nm3kńNH}viv%vBMp0b/ReݞuDzd"`, DM DhcֽB-h GBMG~,߸.ՅN  ?- e~"Wvn@*c g@R( f4XXQMJ֋c"&k,Q[C9&/mm Oc9G"K͕#bg@d9Ym:,`i=rQʛi'\ RfIRQ{߇aO Dէ6U0siB^5U.ӦF@Ėim}fmЉX).MC]}^ݮNB3[{5?Ej ۳X1C pס豩Hm̺P-H[Iҏ%sץ 傜YЯ@䊵cYNm4zbSUr A [*p4\ 0k}k ʹIzqCd͝%*qK}9GXQ䥭 d" {̝ 1爱7XzlT/hrNC(?B%D"mPt؇?pxxs+X!TrQR6x;fW(凞H D 30,,>%^VT@ qYxq찺Y%tucn}4LiMfD`_rв:Z[z,TZ~@ zHYz"iঽ}[yzzvo$sw|964UC/KeƍpR"O(= 2Sֶ#[ʝw)W7YoBh$eƩi^ S=Dau[ٰa/K袋DCM]6s6[Timǒ+n pںu[NV^-w/&XᜌY*h39 _?_xWC:Ą6SO=SO=~@N3G~*Gr8{_GmH#~t IUaHŌxǥ|Sr(UL!ԈWSxc,4_cuPO=SO=SO׽fJw~pr -a+V\]1VGj6BDpn{ϺDgk*s֩={~ޟhpJ .Lϔ73<:xt/*T3O{S#y"H5& Zrqmyv-BE=SO=SO={j 1nqUAHkݏ2熣@TNqo.}ЅkskM]WkISO=SO=S?HgwQ1Ҏs/bckԮ?SLMhm@]ﻯ9 ,qSO=SO=S?(7xҺU8&hR9.4;k Q)Q 8DP(i}^Jgm?Vw SO=SO=Z;&n^֖˹ݟji\(ia=~wC:gm=ou%s':iSxǻKܥs"KcFЇU}^hG B+]*nq{rpGmvwg俿gRU D~KMSO=SO=S?hk?HpfuqB=n,ŽE ^`3i \C7hsczꩧzꩧAÆ-*Gk0~vb= W3HnP)nW~nU,L?3"wW] •Dk =ҫ%s~XEHg' ^8U{ XPlѠzꩧzꩧz꩷ևfVBCsV]wu{_t? Mj17cGw]Wʡp&j֧L8Ώsi]hYw AwlO(UQ$:CǹCձMZ#1L;$s7xcո;$#-~8,?tn Ph= 8Zze Uȉtvk݀S4*IH$ܔA;YеRO=SO=SO^Fܿ/yR1 v9BУ8ljtqnhq;ȹ3Cnm5^=wg{rri םur_9~O=SO=SO={}鍗5]J'RjB! v=ם_ӡMDcǹqҹ)V;Vc٨?;F=SO=SO=Z_z{yiWzk^⍉{Bc HtgܱB:gPou.wοuPO=SO=SO LBRO]:=qƂr̹ 1uR?X]{q[!qQO=SO=SO O+-'U}cڬNSN߉(ת%s}B?4ܱqg8sXȤ;,kzꩧzꩧzzzX}DF( Sr5H hBy.\и|csC 㢞zꩧzꩧA/q?Eױ0TkMWc.,<DygBYοnLðQO=SO=SOX Z.ił7PUY?Pؘvܿkw\Z*?pSO=SO=S? u&ӁzoUW~i r׍i_B 7AH;_ S!RO=SO=SOP_FjRx]}..t\1<4VBϫxuZ;?:SO=SO=Sk ?ccAH],0N,J Ҏ %pգ__"`TgaSO=SO=SO}n@ Zk-GmI}CUM?VHP1cAGK=SO=SO=?''VoUᅂAj%4^?ԅi_wξ"SO=SO=6P֧R)3@;Q끎5KP)oTzꩧzꩧzz{{o硍ʸ%X%}Ҳ$Rfb [HT  ,uj2i)IlNL6:]H=SO=SO=m͜ 8)!+^uA9K\"m, ՗ޏ6ꩧzꩧzRhbsBVh̤KƬEXf,KɝI =`CɝEr$ %p䄕^4yXUI9k a!#^4B~6px 3Mf=ڴF-w֛rQO=SO=SO=ufĎ23.\״]n0i~{~o{V+*s2 cTU3|$ IENDB`Pylons-1.0.1/pylons/docs/en/_oldstatic/pygments.css0000664000076500000240000000606311645401275022263 0ustar benstaff00000000000000.c { color: #60a0b0; font-style: italic } /* Comment */ .err { border: 1px solid #FF0000 } /* Error */ .k { color: #007020; font-weight: bold } /* Keyword */ .o { color: #666666 } /* Operator */ .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */ .cp { color: #007020 } /* Comment.Preproc */ .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */ .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */ .gd { color: #A00000 } /* Generic.Deleted */ .ge { font-style: italic } /* Generic.Emph */ .gr { color: #FF0000 } /* Generic.Error */ .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .gi { color: #00A000 } /* Generic.Inserted */ .go { color: #808080 } /* Generic.Output */ .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ .gs { font-weight: bold } /* Generic.Strong */ .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .gt { color: #0040D0 } /* Generic.Traceback */ .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ .kp { color: #007020 } /* Keyword.Pseudo */ .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ .kt { color: #902000 } /* Keyword.Type */ .m { color: #40a070 } /* Literal.Number */ .s { color: #4070a0 } /* Literal.String */ .na { color: #4070a0 } /* Name.Attribute */ .nb { color: #007020 } /* Name.Builtin */ .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ .no { color: #60add5 } /* Name.Constant */ .nd { color: #555555; font-weight: bold } /* Name.Decorator */ .ni { color: #d55537; font-weight: bold } /* Name.Entity */ .ne { color: #007020 } /* Name.Exception */ .nf { color: #06287e } /* Name.Function */ .nl { color: #002070; font-weight: bold } /* Name.Label */ .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ .nt { color: #062873; font-weight: bold } /* Name.Tag */ .nv { color: #bb60d5 } /* Name.Variable */ .ow { color: #007020; font-weight: bold } /* Operator.Word */ .w { color: #bbbbbb } /* Text.Whitespace */ .mf { color: #40a070 } /* Literal.Number.Float */ .mh { color: #40a070 } /* Literal.Number.Hex */ .mi { color: #40a070 } /* Literal.Number.Integer */ .mo { color: #40a070 } /* Literal.Number.Oct */ .sb { color: #4070a0 } /* Literal.String.Backtick */ .sc { color: #4070a0 } /* Literal.String.Char */ .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ .s2 { color: #4070a0 } /* Literal.String.Double */ .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ .sh { color: #4070a0 } /* Literal.String.Heredoc */ .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ .sx { color: #c65d09 } /* Literal.String.Other */ .sr { color: #235388 } /* Literal.String.Regex */ .s1 { color: #4070a0 } /* Literal.String.Single */ .ss { color: #517918 } /* Literal.String.Symbol */ .bp { color: #007020 } /* Name.Builtin.Pseudo */ .vc { color: #bb60d5 } /* Name.Variable.Class */ .vg { color: #bb60d5 } /* Name.Variable.Global */ .vi { color: #bb60d5 } /* Name.Variable.Instance */ .il { color: #40a070 } /* Literal.Number.Integer.Long */Pylons-1.0.1/pylons/docs/en/_oldstatic/pylon1.jpg0000664000076500000240000014372211645401275021633 0ustar benstaff00000000000000JFIFddWDucky.BOLYMPUS DIGITAL CAMERA !Adobed -o      )))))//////////     ((&((//////////"!1" A0@2#43P`B$5pD%!1AQaq"2BR b#3r0CS$s4`pc  0@P!1A`Qaq"!1AQaq 0P`p 7#_wJB]ZʹusNS!eǫ\جdm 5 κm yρ_1K:4\:w@,UDR] K%YW"E`kqs"F ".O;vrx:`;츶D3T ZeSrVy}75a% kvm1$Oxo}^^m~}BVUZEo͋B[ZKb]93MކSw˜{珯pؘWCTT卣 XAB(jVR 1ȶծP o}:8O;ы( xi5g8A pd7.M%жB1*Wa~\wѰ UUurۗv{3oU*ceؒ;\_F7tUsu6tvM\!UW ՉJ1T@(ZJ,aک%-LƬyVmM~3=x\rf!4j3*69CFyb|fƒU+8ywfeU=6GS#Ko7r2/5yv{'4G }R5v( cirwK+(uJ5Ma\=jT`4$iUe"3G=xNπO=ˑ&jUui]ցl6cPk͛yX'H0#tSBj\:|%1pM]7WYOc=8ǣݎǭtsbM2 0\|W=#{X!:g1<t$qv-P:]eq@Ffe'R/E iξf9exv9Cը峠u͗ |MEKVmknTm.<DTv8RfӼԩU"1 JeԥN7SҮ'[Ş磷}ԓxgsO;& ds֫|;^/[;ymqȾ`Y"W&<6.PfDٵtWNQ@ZÌS]uTy7to<4\ž$Ip;F$#(8nez]AmQзJC5V!WukhlԃfvyY|G^s5 `:1}s<3>t|Oy(HΙš3=fj C+h3I!ʊNW~K.s+pYiRIv6 Rmq(#TR-v<#bIu)p%1XB3+ANNie`Mk_BtZifE7^r^rw輽Xry^`;/AyҢ5Lz3vdq՝N7g+Zr|=>yx5?VSOԐHK3\W7:3QU,yR]336mY:ffǤ$58Sƪo`+3%.F|yom~Yu푝zZisWFrdh}kIO)1e֗ Ϡ^iv,eB@E=UJk7SǗ?fP4FwEsͯ*gd j]J^m\Ͷx<;@B53Y^6ul"+iO%ZIB5Tq,UJVPY啲SEVJd6?-6yݜΞC<zcɰ|uzv㽇B *;ίr#1U`Hshnj$4=Z @Xhnzf׹|^=x{|9|Ο( ^*驵fA'BpɪU0ŵp+dH)5w7c)D6Lh.3K_u==>6p1Ӧ##RYml]ɘKiˢWs ʖѭqӧ1*/E\g 5#D h܋Qp cSVѪLxh'MzVT|1D3 t5yLtO{| D3oL3M0= 0EC4 )C|8rutoig0;! $g ΁( YϢC9:&stj9^VM=M;~b9҆1nAK iC Pɛ $$BI $$BI $$BI $$BI $$BI $$BI $$BI $$BI $$}nrC>1m13A)_U ~>јfg^GubcӧՏCΓ}W3cqA)_UɿWbbc333돣B66NmןcW03Bs1?oA k7=1=k,@:33:/o&\Bao>{=%{} L~=h?W>oٯo1~3>>"bcLb`zbbbbc;c1:@ps3V~;XGG[310=__>1>Ag3tcԎU:L O 2=3X33韡 N+_Չ:LP}-j> xzfg?WI:zgMT# q2bq9щg?FGCObNF~Lzt}c=3q>}L0~>FLE}#GcٟhB=?HOF`tA1Xǡ1md̙\CϯՉF9Boɇ+lu}`&ZϥCWǺ_6謦?cJ~Q~3Ǯ"Mc3>oOb l&u3 q8WIșX+<|bL?Y;$9ɈUk,;b@6sΰ z:,UkU 1)Z㈄a330pNs&WQ̰knY'>5^֩Ӂy)]jqQ2ֆhVh!Γ8Ա9my?WpMZி=R|ygըXVoWE5 AqO,~"dγytɘh+$M $s2yθ FLhYY}"=زU.ە'22LES2x &#-LD@[r612}m8BqQ:O(:4ݷ͗\ 1R5G;!;wWkmSiO[]~CyL3tb03{+W!"f!TpUr_om)e+JE+qW&LOӌ&|9ݡBoj h5D~$6#Z 䭙hh#8Γ1'9}=A|llݍPѣEAZ9LgOA3Oh> CqQ <՛9R%[ڷҼf^-k]d2&b/JoS[~DFBy ^SGTm(|8&:rE6[s339";vnko/"-~x=_"</=̹^ ,sz>&}312#brLf81L~g36>°C+F wԲ~_JSs&6 A`} Fc#[hDœdܟ3a"9d^\#ˎF6r6NDx5%[3l6Ym!hԢqT3O!_0& k*LOjOgYӃ>Fbc$vIuue-w^yYP-6~8J5iE6X!J BH/)>rV&P+˃<=fwJXROvlACQ33eަͭ_ܾ?]lu{ldN'zySm6]˔["h8fZG2g&g L̬!>똄yveEa /,QXaG.CqIzs&9A aQb2BlpBEGx¼a.|ŷdmXWJ%6d3u~ӷz*G$rv8v"\ŶE6KBvBʰn/l^=5VMTQ&6r-f,տvUxlrgvwrMf21V &sz fz)'2pT_dw}b6ŏoyc(ڝ ZR]M@/ l*:m@xk?Kg]qmu%yܾۢ{zgӺ3|g38<[8b1z`GJm51~>b8N Nh|W!fYɬEU5:~ETgufs2Ũ 5Y%LPC֮N_9ngu'o"!J]Aԯ q0IIN.bՀ"6V^jk-b:7cu[{ۘeMy¡`2a6{l%Vq٢{g}\7Qٶy{go{.<_YRˑ`F}~8ϱ0b.2wXg5,j\!Zr}M_Rx.yrD6Yh?^J|v0(#F/c*0,.šq^1ϫc#ܬYdooUu*\5 8M G]{6Q_q~'8g$BlVsp=>@=jj]ܭO ]~!|7kQH5akeʒz)n*gf&HRFI=&[3@HJN@6XNP: <Sڕmv://jփ1b_-H333@S5ˑ[e6-AV*<:mϧh:{Em]mٱ,EI=uvu=R'eaZnum5ݮU[]Tn[_P.DSP*j?DCa]'l3/y<7ر[٨ansN"^|+m"p3CWnwNI2rt_.M?)~~> Z@X3u&}ØU[XPNMl%UkTFTo.LgX 3k׶ CVp\T ?N*qkS۽7]Y )kJ6uM}HRubg1ؕUhB㕧1fs|u0F,ѷ5 m N-hbeſ/c9n]Sv-s:5~?C^SUAW)coNeZ)Svngcyq0`н0 A9w$XqpkXxkwxE5-axU7/Ty ,e,VϊKV͏OyNf&1~Z_RK,X3"ArulY46kaޟ/!2r$!X,a;~W^֝q?e\~hS<;h2Nbzec3M U{, E89NK]E 5]pWՕjmdOhZr9hmfBwk_Sϟ-hՍC] F]6-5VǖJTcfZ&|?qG]}_L.Ng SX),آz N]??fj#9]{ti/р=aw!( W]ږ7 YmNvvvdjte6]rYtIr[Zcg +Po=x퐕I[2@!B8VMñX:ϰӑVpM-أ1s6E32:_U;:S6UjT4_В:Bxpa Ghnig;&W5Z-[1Ko#mGH|O6_]~?W-vYnةv|NǑ}F{jլpUKQjVrŨCb&&p2UXovK:y C"Ukm:V+V'%py1KX\}}˃vMGd,f*W} hhҵUSO!f8|-cE9 t*R ;vK1ޭt*LC,?ql |7%­w{*#ѣO j:ƾ?QJ}o)L1kMX?v`ſ-F\Abc6ri㐮+36I>BIo6ns O3"3Oyfzt%b؎V0(&g3"bO W(JCJ*^ U[v9|lybO\WAbZݫtukvzuVG36K"Ӊ2aɕRa:;V'eQ) vE::Ya3G#zn1/^Qs>#3A*xUuD rK\ۣSKQlڎ;kʤsz-Hc X&~* V$zEYΫZS4:sp|@<960*b;maX 6 .s;mkk+v֎^B:VcQFHz)I0=2H5 9VP' jυ|g)%U^OJQfKGoWz:k3_WN^'lA\bbq錉I썰[GI#%eg# Ŷ{ծ96Wlf[WtfΊ絫]XֶYnGjʔ ]+;T081B Ǒm=jT@8UWm[  M%t-ڷeϒagqޓߪݛ J6T JE0ŀR=1Kowhu,{Yc6ܜl৸xjܮ'\AQd_KWfbF!WXmvqV$~ޚX?a} ʼEaIJR*VKkS|?\7mxq+T5/97Yr0YBj@rmIhurx0~" w}71'aDOȭOP4ML;P! q##seVvji6=btM_#6`cQ9}O[%UVrOe4Pp{S Uu4!ת6K/ ]DE ftD= &G[ WLȳY$Bܧ)vg":!#-b+ lc35pSK2O ۙRCE >x#qq}9bE:nEzrDK8:Άc$OLUV/gxںcYZBi:R @Tv([Ԋ+&u|F"NTLNPA=AH㠜#G#'fB2Vj{Te+7q[y?O#eully0WvY. E4꫺ף.IVȨa` L`̬qDZ90)01mAÁ !zX́k[*KYW-Gyb7IکbX PȦ:'w\|_:x,4ќ,mJN L 3j.k$M~V mAQ aצIRzSes9tOs3q98tʙVfY/l**g_wiN#W{AO͟-_ %PLLW`|}|_?%C4U.j׳`m{4Jv[&5`]P즃1jjcئv(;5N0*ULW;ujs\*v띪VTW;UNST;UNSTU;UNSXa;5NPIgf٪vjQCq* 3LMMJbؠ٦~>}yN3F3TU;UN3LS;43LQ;N3DS;4_^]}u آvi"vjgj~=ii<Ybj$}x5oNjxBtWHz}y蝊'?^ M@^-wAzeE\c]~S3[u,Tl",Ze"һaڟ\6wp6NRZKo(ն]k.bl=\lJ6;C]]'arv[f#WWkeзWK/aE\u'n,YkG[WpJSUksVhV^KF]KZţ. wFp5ik+]nThwkW^!=V?MPsζ\=סΫv-Y_?6`8m m҂qPOf{rfNRLpMd5ǘ3K۶Ԧi-wX Й $0z?%t9mE)mRu;=yKJvS150Smzl;uME̘S̈́0M֋Yx恓?W;{˦dTfc@dNBv"9m;wOq݂;*xferɟON0{sr6e)5:aNM 򡭜>J{͙}${c+J [pY?PU~ |ZÜPl;#1br_ӎ(B._mDk r,O:ʁsCw%$O@}#S;ݙ@`R] le.F$ FXLR7=i TMn1;m=;Us=Ewr>hV1nhe wi{DOoԻpHL0MnNq=apG0)yu;(R!mmv<ޏ)NjbLNF8T,8=-::IҘTLsg?0jFЖ H pObcꔾ}RٓFF",P&戌cCZJry R.ܵKdPh5/ǰp]BnWa9/6=p2?gN(3Ut#Z_0F!}!լ)|P\GEͱԇC1#kVUbXQaUN=;Zmw#W8ƪOPL\S@VĐTT]nИ(Sa+rLzL B2D Z֩OOT_A] w1\&Kڪp=݂p:WpCSWCL3T5V[\1ۍۙeW'O9lD}MnE߼)e5 ”fZ#,uN5Af6)*˳.h =H E!W܍l:sEK:M%2-rJ7VW+bm5F2,$ Ozf.ޞݩn/nDc8d [lr|!j5>լPw&jܶ@{0K| HԵ2F4eBmZ.Stܘ3ܨ0Uϳe|ɁgG"6~u:q&ĭR?/;(ϥp˖,ŏ7J1QXSLnwh[׹rQ;>AF8 uu_vG_#Tk~-{C\Ј:]Du*sbL*w&,OMBHۂ׃ў؎[ eyRۃHwnQK[arrc9Pư 3+e g**vQ9CyZF)Ĝc=8"#[kU}a)0C"2Nނmŵ :4jY(4SNA]?Rha/JrD5Te )eGt| ݒ(# #݉M8?RY=<;-3|L|чIdӹ DDX%YWT(grY9aOjv"DvC/5?qS'r4fd"׆WcQ\|?j}OQxz7cJ0r'ޥya9g!Gsh40a 7L'ifڳN<Ҕ?u@ޟ1ٓ Z ā_+Ӗ6LL5Πjgg-N(nQX $i£\Ol-.EKx1q'?uu1TMTLnv-JTb1\a ~2wX0 w gDd-I?]8)}G>!tL%7DaVxv7mƾAZqSd$;D%PHCNޛr"#ZFb!?1y98tTEUVOi' m`UŬsDO <1C40< 9q7/6vWǰ[KRTvn^*QtfJmtpMBA,0;G~j1'ftRbc;e*DP{iS;;[|yҝ֓MMiͪ2=UrO>(~J@h?bnf:b6m {U1 O)*晝1]0bCܩ@;Hi"3-7 'rsF~xBߒQ;{ Jf44 VpBz*z$LaudGW_ED-NsN$ #CQ~~@qQg `bvFA ͫog7۝?յbu\ ]JѤ"6nE6rd'G/lZFPAI 8=c2$1}zUNOWslO$%,KʑlF$SdvxT:ޱ3*fJ-6eH8 IBb:ƀmZT7I'X>l;rvD^oAQ ,U;#hY ܹ:kV'Q0+L&.쯽zW"c+'څf}Dym@>=T02r="^]%`9N}8Z;TG'#闎4$ӁQ&;sq lSؤV 1իCF37C锤Xp d[k08mT?&5ۖL`HZ@,E&5 աAJmX&LX~a91.I_Tp"{nw{^bRie#[Vߥ,`cXBs!Jg/ ťŵ@8)m(>W?'ʖ[|+p:zBaJBQ}8<) k~Z-ZR u6A2o[Nqܴ[.\g'Rf4$!rMlD/jr}q<-p<5Le0D#HbL "t|M,2@r{:5}' G!@l1j7ci#/YgM8pwU~gMj\a*zx{PbN‹= w7}`H![Sƺ<Kv֩y~ /Wv\gRvr3%Uh(jN}̰C]BG RȖF+X/4plm%^< zlN:CTa99hx"£Pl``>+L`cAjyKVKf5K uaj`ʃb}D1*ՠ\s,*@j83K##\{!ZetpE͕0nɌynKVמJD8d\E;x"]j T*X;p9J VN#J5րg \^ ȁNo͹Gn5q!)ݷٓ5[@`Z}"=ke -F Q:Y棎|u .ǷY?2Zpbr埈ZI>(NMA܁&`ܫT69 -ۗ.wQidzQnIƽ"be۹q=WeޜN`aùF Gz;6rIr%|{ItlQa;PP+q$5Tq{ޔiHm'ةjmCusE bsle_]bOަǛ"[wvjsTZQ"}6ZlMS.GJoG,K cbN͐:pp/DĞYs9R d I%1pK1չZyhN@JԢ*9Olöva UW L-Kzڴ8F9eLd شQ[9cv&rfOj.F8?BژIlGfxwQQ;pOrB;]97D߸bLy CMbzm2 Kcm_2{k%^ug*jT{[GGv>ASj,NJS5cPKx*[;p ^FyNcmSK TةYmp TU]O)JDpv5 $o8&#^팱Ye)@,j kmG3rJr Д5YfbUpmF* <ӶO,78dyX T5D}8w)zPKrNIu[}{zC{ ٔtFZE;wcD-뫜c܎ _V']&q\Վ]FJ^ot#\26ƧO MS,ugٿze\;yAvǶs3i qQYz9Sk|8)[#H=(Tw{б؟DZFC 8f0E*e{֑G~́8Þ7x+X e/ᄏ=$3"!rC3Osџp? |cj!Kw-}nۉBqr$_+Fψ,Ubj#=:eq_ʐ'O/s!Foȭ">rN2bػzr$j&ŝ"nG(ڻFɁ 6(zp2W-W4bn8ͪU>(DK=N}A!lѹC㴩[1a?kz8H7+pDN V@C`Rü.ZQG޴-85 9ڜ2T ;ٝ.(φ;Q/)'2FlҖ%i&< F69_m:`czu(c1m=/G7x`$76!tu55٦)Ʌ=# UJ֠m͈ȍrs~28`<{+UBGS[\w>F鏧0tY /\간0᎗^UPqZλ c^G+kTMDFQG2$t}C\lj nzD1+2=`c @=)=Lu01Zu*##k`f.v3>ŧi!cT1b8-L6Fr-KIGP|lݎj R4yS^Tm:7'"/xN9>PaZ%HNڨD])T$*&^q]T!IFznKȒ@@n {*R_RHb>)Mɘwf' حu6Z V㌡O,ZJsalصNQj$ֻ!nz%ϴZ\ `s#ںN b@ )V)[pL(۞m eP-MBg;$0[&2>ص+[,aM4Az1FŢ12=ҼډڈtD/=50(Ĝ> $4@zed4gj3z'pSrr2HD˗C{N$у2ڰ#\pFoՁ2m|dD00hDXpЈϱCx܎ gQ6BZZ.Ԫ @FWS*DDc)V|bX;Drbҧzޣvq2Ž(6ZWhR\c%&uv35x `fl2?fPm6`k4M[y\#jWIwKoɰ׀U0<|٬k>%KECK#6mtW!˲c؟ьS<{bCFn$mFw (w`.|!DIQҝ0 2M}ڄHjw9DsPm2u%0)rk"6hSprU{qzȚ#upCVz2Oi?TIubfC B_W(a<(j3\up,]If3L3Z;~OS>88btTSw+^Cj`d0ޜ\9EOw1 [mJ֠@vzj jxjCl%3VQ2 G֕џ9ֆNtڄj!rW\R\: -c^(ypz-!s;$a81k -YOV:~)#;J>)]Lӎ#j|?xF˟oVtW`UKxa$qDl [MQŤޅLij8vW|$s4DSĮFv\,t;GKĕ U\_Sص"3zGp3D6H=H)gZ+;* 9"̄oH?r:No,SYmuv1Dv+'p  #Mk\HTVv"1$=-Oa/QoӜH1\?#/?CԳO،1)Sb۱ m-Z̉iT#f@}bbvΧ-=oc ]z:D\F1Z&W6.^On6 He#U P5|4V zrfB[I;cC[J/R#. QbcL-PyIGڜnMm^rX@K{PӬYO߈Bܷ?ON@PVb;1&ANQWyrizC X*Qy|ބeL{Ԯt=LrXuh^nR5[^芕Gr8')Hn؁wd& \S ؈uާn_Tg;ʟQ82-W2AkcSF?{np{b#vU>x/{Y4 Gӟ͟n"'ͪOOR"2"=jzgG#cMs Ft'sY-?1UVW\Te_PiC$Iz2i2Q/EAfploQr ҁӅB74>r!Il{arrcyoQ.j&#l7|qQ(P?Ƒ=FX[e\7#rv NGq_N(O46HsRvr@a!n7y>[ؓ#vj.N͔QJ-9yR,jIBx:yUFԏ|B1-m#}C D6)3Bq\`¿0`aR"&aTdϣ*!ystFAC3 `ON.]oP.H0ekYr b.31&/~eW40%)N]5Ѫ BD(f Fw!pp"ۓ޵CLv)>rܴ.j[FXSQ@Ȟ b͠p=jȟy#)i2ȜC9&1ݚpmLN,)y{j r؟;r7.\.muLڇޢ@m:sӎ>Sa$!޴*~0T/b/ݽj<#&òݟrxN̪Dܥp4m& VLT? ]1n--9Hɳ`קA\-xm3g\֬rFm/h9WAH I&kV#:h*OdR3(jFOz~@ 2,^.=1@5veB&-gQ#@NOzxDo)UI=`C EDkZv+rQVʻn vlJ-w] w4#Qtp-BপD6bY<>in*qyKN;hE1t䮬-ݒn!?yBࡵL ymj/'!y1"qdOdїw{-ݷ))6vwb\(DFR3xvuչ^%֑M9|2ޱƪu{<y{vRCIkoQ:Ŧ WtҼ A1u79f;TR`e2\"@0"}"haCA*i?l'>IoM؟e|4ݡ<YTܛF( \K>ڠ<ȈNք9Yk Fίs.lv1.nLMOWpO,#SmBY57Oh6W:{ca&G1B8L82u~1<).~B\3Luiv0(J/A^5f*D"&9K }eJ%j3<7F_{g Kc)8`;r`A~PluK{Jr-IL#Qܜb?.&Gi*R L_*,)BrX✀{1Xṭze3Q'=o^ʶb21%Ͻk1mϊN#@ GHPGԅni=6mL: Aq*VĆ{$B0Md䵏ry 1v`Wb<ǫokl`-ʉ#0ž)]!-%iF%]no$oRQ򟔎~Z?2ڡ{dԘ1`w 0;-mFUHPZ-6[Y&醣:oO:q#`P.mz5ܧz~ϰCž`Є+Ur% gѶ$>R ] Vq.lvıW.DD݈CbW!P⥪":xZ.OOޥvA1q䌩jnMd]=9B/1eUJ24Xbw3eD\hR|? z>>m?4%Nmu;0Sm- q XlM,XDe\;5( /H@A |g"䜌p y.U. 8Dӂ$23qZf4fGbK'`.pQd.`) lGM9 +7-JHAwOqo;CV 42۹?f⽩ön]:l)@eV-\qe )l SST0'! M/!"%&4jQbMJc@Paj'͠?2B.D_Yyjv婹Z$S9;y%3*u湟1}Ոc8S C)MK<v[Fv%n4kkVsVL5st<4݋P'{YmS7W6q"TWVUZ8ےqTrN,CWrhp䎫|yP==n(u ~mDSQ;]٪yFjz_ #tQ>Q) {k,[\"FxE$] bu $Q0_nHdž`3aprκGObfg{s-QW#lrwνł78^1o^Ko#ߟ.Sq[U*:"z` 0܀HԶŤ@JjS$%nMlE&ރ]՗M_< = u*=h J'Ӟ*0D 0u+Mw:ꅩK+(ۋ#ӽ"%"q\k}5gP:F;$s8jbar,{-#aܭj_t 3y(XU \fBfU^_QS+S ([I'>O 6d[r*{{%("*!-1G|bxO5HrjJl{e \FGp'p9r2'HVV݁Snj`Z}]Vs%Gռ%~lV.ɇ$UJ=%9iǼ-ZO"RCVi9g?[.pL?ƹ3o:jU@ǧ1EmP( _qb4gr< ً-J,.\jLIa_tvȔ"pZ6Ъ rCXqBCkNūgepQcO.=˗8g#+s"؟BjK3x-'w P>]}0iȄ[!Sb}: t.K wT&dnNB:ҁs^t^^=W.h2Vϣn5`"k"F vBպHܕ@2ݬr21_F"a vƹJ7؀ <ùJ\r`_ hO=DɼWEwe-Pn&8iDHC6=G۪P;H zql|RGp^Hq & TNaF༣yG <a 苜h>  G/ӏ^H䏀^H䏂G/$|GG*4y#:" Nj >,N>y#>y#>4Ċ1 1J2 MܚՋp#p^kF͸0/ӏ_Ӌpv-Qy4s_ 7m 11 J28PJB8HMŶi q  N5Ɓ~|8q B8H_ B8_MAH^Pl DMrڀۦNmޜ[B8 䏀_ >~|mn~?/҇ڗDRrXJpB7.tg9VRxǣP,j8N?rcY#grtcGiOjQa=ȋ]=`#pT !~?/҇qJCB2-*EPFc!v^ GN#We<4ޅ&NCk 6"1ӣs7˭B -Y=C!nB$Sʇ!u5Ory2W!.6ɣ,UbљiK%EJ#kς3{+Mg~`6Fԇ,u0O]j *jMCQCXi!Kkm 3lbnz[c@oAs z@r$ ׯtiD#wKJ/#:kGpQ" LN 6oBry"\98ܢt 2L8(喚͉e~.إwC鞍 ];DjW-#t|+-'ƪ #p'lF< ͝"FސɅ6ѽ- EĶU(H2](h 0Km#кMb_)!feKbhrx%8cP"/25~9D6F嶃 3ya8P$% .RZP)vE[cx۔H" ^$Bw:yUqկT0oz֤#6 C19=ˣK@*ހ8 H >F06$,JtsF ۹ Xje)> ([7^dSSaU:n{J{*.+(O2_6ECxgSeT {a'P!7Yފr֊3S; Ҟ=r˗qxܴ5#\z"_+Kp QU~6{'rNBjh #q|Kģ̯cRn7-)75ĹLW6 (Dpe~JyBmCU8/q 7_4~XFSFPqjgGfy^%Nsԩur̺/w?ϹBW*Vp2Kes"?}7^cTu:9Je1ru;,#̦kKfzXJ%"E7 _dd9JϬ~,b\@OGS1**5̈ q4&:. yZ.g#be3'R*γ/2Υ1?1qs/L?\{q<@f`\*qHhOOf*Ļ_N#[%b{2׏|Jq{r*񫕝C: x{~j+^嵒fw+Rm|.Sǿ3>&yw 4y>uRqs]LgoQ{6-a_$kQq+.`-Ya-"3]KqW[Pʸm%Z~w))(tJ:%J:%GDQ(tJ:%:%GDdSQ<DDDQ(tJ:%GDDxGDQ(Sx AQԦy??`[P<'DZ92Tn%eXg99CkOlM8>&j0.Ub\oܾܥ=?CTrz`6^?f[%˗̩ee Lp 5aY?nT.TSR '0 (}ŮK]+~q+p+ %),A4Y1]DQ~%/4nT^ /-Q.6~4z5 N_OnR\|Kv\[Ķg|F__Rs}0~\u~Q)GZ-+?.$ī'_"NߨD|_ŅM@da:!+>? * {:.1,RY#WW*g"Fŀ~+!zŇ^SNރ->eYZ8J߆q/9J?,. ?V,4 +`9Se[ Ӳd@~1[1krڸ2g'RW|bVf;_0=J9eKb{\Pj֌uLKw>%Aܼ_(9zMry@<D 84ffMj]e"uQ7^YG)G2bf6B嬩2++>"u_D&eJ^cHK!W~ !JJ65}0S~|Ac߂SQhZbe!NX+pƿ77iP"B/_Zb\W_?OwԲ-U5dpmZYsebT ^R5/".f-aB#1LC,+Yb|V.\GeY:_pYWX^\ˇ8%\.W,fgHnC+va{GRK]Je.k2a".?mUq. 91bTWvcƓS2X 12z !1 }Ww=KAxq94>g<pEpJ6*>e{ 񈟒*|g5\̦TjT\fd5~eX$p9YmuTe.[-[-eorore{-[[--{eolorol[-{{-[]IT3p5v;CnEW\8m/>ƣ ௖\fmuMwFj$VG16BAkoi{'n<`0Akq␾2r KvQ13:}CK._Iə6gp 8Q&ZP񵵀"T/<B#>c /~ǖSQ[˜߹oljS5"hy> nSsDAS+8 w\W0** pqy1`+yqeT[ĥUG!@̦"쉂G7^}M%|W솠f+RSkS2iۓPOCŒܮ=VHmJ]` ƺ+蕲PTʀ$vDV`sV.*Rbi^Rh* 2Xsr jP)"y>f1 2j^@&w[WsdJİQ 9Ơ\B<gz#X4\@+-Mo|0S'$u[an7 [;eqneW(E֟ZNfRrSC,]/j̺QL>aO1Ջw̠2\Q1\.b :u  7K,a/J 7g(UCk1 I4]@ZqP@XϢ,ҹp}T,e%*%]u`ǹԻǂ+yKU. g5A~[?o<=Tı ȕn faA/ .P2@hϩ`-_Xctm ]BPƩUB`/y**R z= `1.$8mcQC #-[(D,]Ne-Bϓ (JxOŽ2fA- Ʉ< s fNLD6sĽTQr=M™ ?hGCB  [jS1JCX yO{2E]!s%e.ibpր@KTZʲ#ܴr2;.ZEGJ ,y~e,2A?yk U o+r7q u旈N1Rp%}uV(h>(Ap;w0MsCM>&dVĴmh5=}X!xڌ*Ox*`#16++Uj!Q2!Z9YYʵV]M6Qns]߬gQxyF:,E/4,S|D|JM/= Xd ^+`i淈q@ݵ)ah̥ \"Κ<_Pe䨋 T@'+)_va cOqýFvZ۱3Qu q%ݰT,H)^GCR.k$ xR'#l?ut 6,x+b!fVmΫCds6 솢4#=JFs-&G kZ =(B icIEνªӢ䶛EFk^AKp~8.QIZk5WELpw-R2ʡ4*mKs%1"XQ˹E`&8Mgurj"$U3z|P]xۑ#Ү^7kpUub12()཰YlDBCP `̵ FB <%_0p)b 4%(yp4V4`e_3DEǹjФYn/;ܪ%>GχJU2mMW"0H͉QȽp<*j(7R b|LGJ[S#RLC#s$+nWH2.># mωDpㄷD^DpTLeGY9GpK PV6P3p绎"O&@j\<`(mHo20x4 SV2[34*lCɨrsKi%.V+֣b俥KrӔ%O1q }&81;Ack\a@ ׈Ern``teZ(y/v<5lRP0pQl4 -h yKNa]l^ōiQ-oPe]8`RjF{&x%=2TZLY譃V-X ۰&Ztͷ)uFAu,,z-!qREj4f۽8֠e:*9HM[QuQ(BŷTes},X荿>9 l\#䶳ϩQ,AEWF0]0HTAe6b? J6;UXRΘ\9FzuP0i0m;GmsK@yԹvq0^ 42ۛbCgK?03 Doa7dcbx58K3iԤQ} ["uAG*dԥb*kA% {*S'=Ay%,_{PJa_X0\L~#ۨVnAMPwLmYZnzqҙ{`K)4Sڧό3mM l F걼^@[LWkFY jJq؋ ?ܴT[k*kTs`LĪ?ʆ~/Q51:kS:¥}G;a)MPlK%JgBE]KO:^BEu 1̯?S-F9jFwn^èCopK=l?p u!wn!+k,JE.Z.nk rƐ( K)uMM.BiCv CiK eWmOjիc,"2~e(u2]͑Z058V5 o9Q_pZHF1 #n&D3gnDY6mPSm 2bM*46p0m%犊iN+#5]tC\-]zVc1ӆ凓.[HR@|ԡbȋLCTV9 SGC4S^ѩw&7؜+, 0`p;;RD ͦX,ڟQpo x[sتոa7 UYBf6 \~1 7IZUnxZD%JM-ş/v5L0zE),]Ŵ*]Zu,)a M&+fwSA2qz+DEXTWs,lؼk% ˷) kq\PlաX QeP!ЅDP@ d`O/0a+ī-4N(u719dn+Afϸi(bˉ*X.ly1N ni kU(;N0ߨp>՘PnF*Bu>#b=Av 3 ʈCPI]. Wu,j+e˺8Q&+ޡ_FdQ-'P*s6&R+Pe8NS- SsU}(']Ea+mq*Cmx nYmp22Ѡl@Ѭ & cIM4[`*'pPi_sڠ0=N_4-D>7 %_#|@JbʲlyYN&gƥ  /\Y+&.V5)آ^aE |( '\dL4f؁Y8%@D:-(<5٠B1|Pbb0a V5JHrr18>iFF gܫlL7p<55-.*j'XT[T[XCP<%u@7)ːMfbKNoEMtOu}/k 6O ^A3 :=ZbCTzc Cbo*Qӗ! vX\r+`/O4l0m6=A !D})]LOb ˦ 5Rt}P <7t8. mbaݯZa*p؛H%u_-lݽ @߆(23KZ Z]# \b8efzj 4!UM@_s 8AT4uK#Z//.  ԃ7s2&5@8Z2)q,H)@}]$ ye)#g86'SQOrmn A_ęPjMSj[K7LszN{!Lѣޅ2ТӢPŠxbF\NeaīD{Z/=бiPsu1TG,M"J@yj2 7Jh{j,3@ _Hh"ͷ19JuZmjܡ6$/^DRA֩;L)=fux-ʣLURFX5'Fvq/l&^_O+FvU7pfsMӅPjn y=GY@bJ^|ѢV(vv\E_0]{6'X`z*ŷQO˨vb H6Cمl0^_EGǫ,%8M s]dsTVp  Bұ!Ʒ*3^[na{q0xtx `ΝB[&Yb#CyƉ\0##f`4݊O({1›!R6!χ;|v\9gKIS ]XX#Jh%\xP ⺔U.!ڿ}NQv`!]ʇX8c{ (; c0}A)1wf{RH;~W\`m ²ht44= s([up12˂!p :qJX7yөC6A&/|tC-X7dJ3,Œg zuXIXJz\YkR~fp# 1o쫯e@B|\(c Rl&;^ {ƒnvp7A5YuV×\3EXRZ.Nq6BoW)t1uD)_2 y;- H֯q5꫈r_-<1-hڭ-䖨!fa^CI6cԥ4^%(*R,O UnKgPFܥ!I6gxy5Uaֳ1Ħh薆1T=0{t+e6Z1Esvb s6>b[|m9d|C8  {f} aAW_5DPӢsֺF%&X. .iy(BCo!!w-Tr+~GM֗oܨGҘ qqR@ϙ@[ko(9iڵuE11W!=^ౘQ[L[a%:KmnfH` -/3`QR $Q$ꃲtWS!^9mC(}iUK1BQ Kv!/ ~B 1qķZ()$:k/"=пqse×!~e4t-QT=1E]`KNP^V 'lUKJ V>>kˇFfl3W( `Y\f%\`:EVajaޥ.98(} oBɆɡ䋍{eQ"s\L2}JR#?fV䢏stI^JIU`UĥlB_iJڥ5K [kX@ DͿ "7(/y_y-.fEnQBǜ[>Y|nP`2`FڦGIJXc(h匠d!LB?!;M* Pic{eblѲ5+.&+}lO*Vu5-MOěEVm@,ψ xQpAhklri t ZY|EBц(;yO9(9VgQbϒS^f@̚ "4/'t 2bBe3Iu ua:a2d*s6Y%ۚRiίt _u;щ2g7[if$Sjobdk 9ے{2mu8/8"r) 1+9+s@>"yhjL*K^]^?%70!i)Xa) du"צQ*:ĔH*V;XJ0z%V,bP12 Ѭ g"f}ԩvT~`1˗`jQGj0fYuW[5EZV`Tpn?i@)rw;M/ T̄;fo,fli/jh6"E88 '~`w 9\ Bkg)@YVCDr1 p@vh:կrdx9T)G{3W&:~JYEYίdZ8iġ~u,c6+qӞHPE(-2+q\VXXX)AAG\A$r tq7 j,5`$ a*5h]LS̑% ȭ(dJS#5S3p_*PiwfZhpqu4? BVbP)pف/Y?IՏuZ mE"-)݆-c%-inLv( xqÚLjFӵ3r S6tZSVˌaa.L.Mpˀۅ`ƢGYx|Jv]2v{WE2Yܽho/pd(NhMC4M0dp^LXZQtC,T+|*/:ytS8߉*e{B^hrJbHݴ1mŭ npNwV-]AtQ-\yH8Z04YX05Q$P$`iq X%7cKD+m~PV*(`9QN |~gj@1{*U"ʆ<4@:䂔v7gn%iQEX:Obh^U 6?av[yj3t oQE8@/7%J䩜4W͞k)B,wRqXZP:іW"AZk/5-zL B[Ak X W'(Vt:2iƛ wV誏|6ΨJ0ŗW$ӗg._ IAxT" VPF1PPbhLX aύL#Ʒ)Fqy퉳\nLN3yi$`R" -AP.` ^K^ImViEK5* (RQYY#'@0:h~j/E ۉiB jS)f2ھir(KKΡ\C B:z@]͹%xJ !g6,Qe.MϓIvH5hcĦ;Mw033pk5 V6(U."/ r$\Uf<Nb(8Iu 2򕭓?R u\ frnnUyH!Kaxo'Qąb"6rUe`\JM}Jа ,$=ŸVn 7qC-PzQN& y$Y`UT69@ģ9BARh/t%){e %?H5kh6̹0 a(wKU$F4E!&l| ]+-~'eoTDtf:|T̂Z8#rTU Fߨ1S "pW*%fdS &nKR!.HX\Q)Go!I2nlڎ2@6c%(nEl ٝ =@{K&*4ᠠ4utg%TepD+I(,nc,PvPj·7g-7l,Kq,=bWMƁ0tuETһ <֦Š %" ]>B(XaEJ9aS hQϖE2\W-E ӮAX_'"XmbJ乛ͮ6]K'bae5ǥe cjˬf@y  Q" X m1ڼF'mjR)kRdSP (P_:r\pZ&JhP|w < ߌ26ŢSNR&ڨuоP:Uđ ɜJ%0ŽƤʨE*DLQ霪Q~эʃi_u0X՗ÍȷFEyk-5*˜Q ) k f=SS'`W?"Qs5,rH !Y2 > 9î ߇Yqj6'D D4TFia H] zxd%洿,UBKf),8U' amCZ@еxҾaJ7C_\?mubҬ23P*ݞiv>#-p xL22GZ;!sz#`C(Ő.J36ԭ|#v65Qb#2'4$2'ܴ߆pLOeK15e=UTeE84s,&xT/[,RhľE}12%\@Dpg#p62R9x+ ѦWo.dRe!, j~uƂcuIt|,ǀy?,A,^UDiMҍ(Sʷ.n6*8˸ ܨaA!Uб M ZùCx𔓷(͜X܈+n4nFsE}X([CQUskP2e]UV R1\wּ^ImQ؜nŬ\MO sUpܡšg7`_RO7@> Vt@: F9Œ.W= ˳|@pʉ%C3|p.aɯcQF ډR(O 1MD1lc3pr5A"R `77Pj4  gQp[tp ?gDT>n]Z_·,X-U!B>.UI[.[64/nK,"vFaFQgf}=K#WŖgaZ`*A80@ZieӔ҂?L;lҽBC((\eIݒZ9 2ɵG Ǥ"|.(,000#PI@U`doŶE(W J[ v iN}AQ{¸@ zmp+[U׉XqTUJ[5QU+Cw v (4iyV@@@ dbdGO56¸0͊2-nҦ0N(n醺l6` K:bT^ JA*`:x4%tr ~#T,>FxKE )R w[yk| MV>r)̌1Eh1^u.AcYafLUV>⇊dc#aE|Tq!ԜS!B""·Fߦx`@ҁY}^#j5ȸ.<Q ]e_ ( y[ s\TBUf8e^ >8Nۊ7VtJ+?O:- 7EVn`]Yߨq娤Ì1Y |H( f:_0 f dZOӁcz"V`]שgjKRvШ}tW]T`S.dB!Aw*= 6[OUMC:#3SPTVaq`<Y`6%ʰdrQ_)VE48?kp~.œ,gY]Ƭm%\E \)ړUr& rBj'`o ]VĒhpM5q22< N1_S k2@dxX9yA8R !☔VEPF1J }!%?b [L |u4d&8 =̕t^q\H^"0JWY`eu)qpjP +!Hw+P? i fa>l@q̓znȭ-å6*^Qr!FW cwflFe,P(.79v& Vd`UftcUn5'$^t>`2~%p6 cA U%8V.e ^+̣N -pUlK,ty".Q_rtı XfP\ "ZK/k[C^cOr2NvZP@Z,`kŚSm Wd]U*9]ybsjyU m!_(_6sh1uʳrP_w)vk0T^υH*W #qF`Fp zg C-RYq/PԸL3CVV0XVK Y J~cd1PsH \.+o"471,(Y^EG D9L$Q1$*cE|QM?˘`ic&B;qAn\D(Vcb&BӣGAt.UUT5x?9XR`7r$x ,WZ8˰M`+ԏ݇kSOXۂf`T0w ۲9Jè/(,\պPn ޠ-raK_LE7}F\ EvV29YW<&i,Ud)7Ѭ)\"aCFےLjx0O<*h#CR"V]-w, ƀ:O"Y߼,_~C;3 e\ Qyq w˖PKps/(J"}.a嫆P7N"bЧqYh;{E4BԺxIR*P+8eS*ؿģVP# ;f3'9 cXo1F5g^ ߂# o.}H*o%~e%OkIYcD{b3 3_Z zbr86,1F3³R^9k1b⌝NDkuƿRAx_b̄4gʩmCY*k3 g"!N[K; GF8Zm  74 +VLX YncƺfUx* c=G6`ـKZ[UX?Q¯~>p.O(@s0.&y ҙNpD6CRhuQ ] L:Vջ(;nպoaOJ: 1f oANwهĬ: ؀b՝H IKiKAhq0(c)M @w*@ 'jxV⁵Ey}ƉbC ʶIi,J1QtY@ !%~;\M k騍{ait|&?ԏ iFBOV6!?)瓵9'S]ʦDFmQZhxaIT48R~VQ{pm 25BZxB;TnT2M]0p#H6YH.&x62'qUG#fy2G&v|" jѭGAR h_Y#0CY~\%n@%"P- Q):`ֈK"* `x˄ tn Ee*\hNc3zez_'STӅ:8c+*:*q]D oD733`s۳4e.kF NTf3PVϵ)V8ΏpU/>6*f2WSj.vj-u*2EVws^zԪHXI:,Tٿ(ҦTpATj1?n-{UA/`.%9cF< k4S0;PQί̵1pPS|` h-R)\m P.MU`ƘwPQiy%~}gAx"8+ 0WWp}v/2صF!F4Y yP 5iWH*uqX~Ħ4r+:D2E;P2d9:0`3%mRjA* *q" x% nC5œ/4yGOVP82T,9H҆Olj6V^Z%K%ۧٿlVJ^ዡΊ\ F/pH6k,=rBfQS*Af`Jc$ A."^N sUaa_& ƀ r,o`?+L".)ԫ_[EIsPQ:ϼ%QP!ACG0?"*iwy@7"?ȿ$_*S @ r7r5_X_˒mf^Dk#Vg6_[}ORw)J &!|4;f倫d1O~"^lN?(94UnQ__Zu*궬rJ) %ZAPOOfgR#7OoSO PAl˻%)[}qYgS}7JP A=E*I (h};BvYL^ZW(yD905,Rq9a}eYXH =8"P}O(N'=18CSq?? Z; km_H(V](h^0 f 1w" wjDw0tJB2t”J(-c%pӲy,e!V}H^qqY(*k)-@SF0Hany|ww%=6 zj*xaU 64d±%hm@ $oit\Y%)xl 3vd4 fզ,\ a!Nt`*Bh#U@q]GD,6Un!:[P&!\Jmh`<~ 7 2-ۄ+k83NmI6%p֖Se ۤS8eP8^5\!t bu >MxMkS'[ueK{V,@%Պ H3}Zp"WF:nٛjǰ"=qHS!^V奩Q3 Cͅm0gi'w` Yahh/za̋?Wn0̺0!0/5P,V\ \_n*BNV<|W Ω)?^RmhITnOKK6}*C) QTm+G1vԲ:B&UFJ޳WCL-h]LjWRυc4F nEGU*^yMYYNU< AbU7 fKVLSYT~b{;BՌ 7IfYV|'l'YQO5ػ^LJ=űm4E?m 9\V+vqY hDq8xodzZˣ*-DdUy dY(ZGGyzw8kۖroy~ jufjՕ:gu2q+-Uuzβ@Љʹ-l cjiS5)lF4<Ν YU;PPW>ijVcՍ&*)$Տf h]YҶwΤ5lpލ8=Y hDWe*&K&kұ~9wewVSX*3=pf>-/5&sp7r9ӻXZ\wjz,.F:ϩ4AG;$  ϧIlĨxUZVmseKeΩ "&u&~iQOCG)F4,[jjNVaQ.s^_Fa﬐4"`"x,CkoO?*z*w>ܨc[DSM=!JzΥsMҿOߢMTQgdW]Øi쳏;<2Lvs J5Lb}0^zܻѭ=|3mn㡨h I4I<^91&^Ϝ}gZquzWaN/lYspmt:$ "xsփ~#ySgz0ob*_Gכ7.p]*i"ʹ;;DǹM}Dsjhh~ 5xhC4"`Zm|Wɏ7`z; v7յQt5 īIϢ1O뼨C,gZgӱ7:=]35Lnc& smC5k/fU6%0[Lz_.уٶý,= ̻!HA!HA!HA!HA!HA!HA!$~90?s9hd?qgs?oO?w?O=3q}]vϧlӶI;g89 qvss B* vNOجݿ֩Z涸v~Zgc4@gE&sE0֦x 7dY / eqrSů|MWJ?t{šgd1_ V0~(n8[ gl*ҧ ]]15OX{CS$H+g^@p:3y}}Hy}|e"UxM&6g:;2|܍!9r'lC H_Ӏs_u}p[暀? uwږ|65S<Ŭ?O\M|;d mS'\:ҟ>εuP_u8 jβk {_䩜\Nq?~*z6.mg~=4_s,Lg96W=N{f֑:s+>Xߎ~1Yp#>llJrIZafoeueu{56:緆I֍!89ͪx>/k19/+fV|WFeGmÅ ϫ:Lcxdoi^6@.q>BH>{([݉b9 jFZw'N78;o$>Gsmk6fQ O1 98=xy8_K%q-O{a66>MfjuR/YqgU⚵ؼuJ,/*2gpa+=f8 *s,W;0? *D=i"gHlCN֖&,ۣͬBZA!DlƄF\k4\Y+]VEdf49 IhJ 0 OAmr=m{5 ¡\k5%IWY'{&_`#=ga|Ycps@=:+ばBoHFdKET3y'fĦ6!Z{t}WcQ[jo?6974{l97[6W={j'vҴyGQ0t=@Q%8v=E[g&ҢxV׿Yh>8փg}yMzzuAWAQY.lPv"p\mr HH\uqW9bȊO-Xbۗ^N: u f132#Í62~VnL3O_X( vL'IZOZ 8'w$YC˿(d\µ'^3! &(=˃o0ɥ*g' ZKv&,XoaO]tj'S? (:`@H ei1JtB'.)=ke(g)&faWU >< LJld8:||jL.:G6Ӓ#GZEu5ζ*F,2!Tfo /pг:ثȵel]gP h|t%@1v`|b < %_ceoӾjQ[@K6;u=y9=i%9:uGP&%.Qfl&7;hq=8^giQ_{:OG;zyhy:%[g9Z_C.; ՄQe~Ӫ~Xge)Pԋ=C.ќǟ `}y ]wfBq^W5GMtDD0;A /*Glk^swV㐣czbq&Wz=ih8Zc]3n/!SiZ֒S9e" ɭ˷q`Ā, m:a QS_&Ӫ@xDUuJso45l&֣l g+xằUiL{D5آWKFfu{P(|^knUPykVڊ&uoIiԇ-\  ~_!5,3#?0p֛%kNG7 _83bOPįtt2m]opxBݙuSsAGR&ʊVq[]zsߖuY]WxVL@*ʀ]sJ9VQnڥSpYۜnu*"09ۡ\?Lg3tN{M^=i^ [6%/s7URnKsV3)9M'UqTs 1W(G,an0MEE :Ncr pg1\C>-c|[u MU4:r V* Nn opo wyd֤v?/`8Py]DiqVWl!a.?_j"c{NOkmUflqeAVmbz[SzI,"YDa3:q>=T{=l3lT&7-HUVZl(u5_b΢idYD2tywv̄f,ƌ!Ǫ{Xy{_/6Wl A]Sf4 @kkzB ^4"^6 .G!vd*}RH bUx[ VUPy uތlq7o61K$`ccI4NX15fmn` EQGWLc혳guϻvE;tʱ'{e Λ;Z ]25١ow®}'835ӊ ˗o\䢧s|v41%#X2 #8 nxH[462Nfxqs0VvBLv5 [*'y<q##̛~n&[fu:uz y (T/r19v| _z]fUNd=CYss[m+;jZS%eF#$yM(ȬnZ[後6g7vk(*9*N3 8!Y'sI4I<#tN5tg.ن &^ JP U ZVlep]q9/8_5β_k~%F9#uxWv`>K{8#d1chdJ 0Nƞ/%[N Y 淛*Sx%|;rm3)%uq@v+ƚiKLziS'i:\JI5 s\!IgOɽ槩Il#a8Z46rLA s̀1!AG{ffYz*"⧍IFY6S[^Hu{~HI4On)x|z'=l\WagީȭΛ,1lT'ӚKO! v#UX^A&U۪;!SgE{YQMצyzΌYvJ2Ke6&|O fM&nՍu'ǿ^.hƕvwZ'toGENRԔȾHu=Pȡ*k{z@~L y2 |w}z,u^k}tb{:x"ɩJr7%:Ģ݅z1Tܐ՘"Uq.M&B94`¶tvlՌ+ \J+g=ٌ6v?~MXqV8"~ҁ+[|uTCb<4EL?'tg-TɲZ6ҵ;LoVetd6m ^U+I.좚>5W0Ms"TL  Ju.;<=E<#)Y *I=8K2(oꦱ ܽD/H)9o*c9~ױQg]ŸNĮJH%689f(l?Jʼ_%fWAm.=ٚW6WZn-㓷 y_vmOnQ5*`xMڲ);ɾ3\џ^; On3<͓¿SWr>+^QkNH"%/p!s4[v-u6L'=~S.˖juOt(j ~9ʪk{IY֔,8Yn7XIvQ85c7 IH"垪1IڳpE,_f |:)*cp7eb^XgBLْ5>J5N~?OFs0jW4S_s]Jo3S8h3J!J˯^cV/wYʫ Y %̓ [@99>4Y+iLWfR`)-ٓZ3ђSa|$ /<}$I퓞ϒTBSJ}Kۏ%-0ݜK^؃SV4'_`wJ8 LnRIYSW䨕ؒr^OL.|ZFz=M1+WT+Q=_f%?Z>+€yIIan(gF־Ob3j֕<:ZJG6zF)+0JUdhST֫jçӉcY^ykt.#/ GDb$)7+$emfsa}ڸOqlkV UG\#xwVnSq/%'ZOw~1g[vM;,ԕTtm tڎ7`ZpÉ;pZ[]YV1e(}ϐ\ "=X}>C5'in¾*_צ-$8sP9νV/plƁ(UHM+Hiss՜ӢpF)A8L8wѯ?^_7Nz!#?ĹM̈́/w' 19V_G|,F7$A1 WߓXV=7}xnFvޕTE(2M[8?_?Ӷ3mL4v]šEu'msuŒ\V?<>H FaWǫ2Jx 5n޾/xӫmISOgԥv47YŖ?gf`?3?⌱R=Lp?>ʳpT ]MZ}*/JMPRxN_uN=/];B~ނIMGLp7 N'dƼgŷN ^z hMմ{l$pI%@sKځyIOokǼWh:IVڱ~*6;ot<}!6ĶԿNZN$Eu^DZ8EDcD7.wXH&&x wEk `Oqp";'Z,$b$X;bgVԞC Df=a$}N TN$q2 `A7E, ~ƢqlJͤPPL l'^<8Qd WecC=nH MX2-dIҙ7L'Ihf^M@r+]>./#=E_HV aNqP?H53<.߱_5ѴGE'TrIv{DPbH  Sj]MAba&ܮ-Mm>Eν%w8)FY=*〉ăF&Ğ{.Tw PmSxD[p5mJs0-#֬ 'VMtZ r`P$xJ3V*,?9~@΢T/Ł"}5;mw~c}WYZʼKW%?2n3EP Yӣ!rxk5'3sjAi[[z^ugƸMA6㎴|ui^'3B.#Zʧ_}BbE2LxS&s> 0G <{ oDC6z)plpRBN\ ]9ל4$\wZbxRòg nfƥ2ku`sZ9LP{R6CxuMۻ=?[rj={O^6C72f 9{0 16rkqZaψYmHPt,3vT`'Ad֝ Q$iA'O Z0Ɏ Z45f]M{fDP 5W㐏ߺ*̐75jNqijDs鷶rL}Y>ߪxmM( AZ )@@S#-y*=_mq}wkV~VT9HuYЊc(װT(z"kjDV҆ɨ"K,d?8b9LYYgԖ c_}D6QM􍻼@%Ad׀hJ_;6Cglj<.}i$2n}XTGtkK1Љ %:mt=ƽ8`InV% ?˝?H!WjPDVO::&Ҁ4?0=3KiA}?Sp|pnX`[򏴑QMc>&EBؤQ}Ƅ&߽:tm=7\7Fjr弓~b}P~$"Lut<oS u^oj7'XbxTŧ]SlbT׫JőLl4˰v2 ͎GszɽdļXwE4:Fif8K);E@! 84ˇAmHxR./\PsV&tQ6PtM).C7r`VRجIȇ/dMoqҦ1x^hN^Wu>AGQD |(`+L8@1:oǶʵ8я9)/XrVQIIF}=>Q)`40?ۿ(nu_(@a67tPαzHˈ`>Y5.":/yucf&)c vŇ8jQ2؏{eBwuoMmdKq&Sx9  ?W.MQtJ,r[s2/Yڸ?0E'ק)1$z)m0-\`=+,r?+];dP%9jZ1]['ﮭHs*̏wэSZ)=Te]l4BmC,>kTv7{zѕ+}'S#D %I] eq_fuqY AGKi~Ǘmn))#_ƾT9m\/?V;Dz{/E:ϦxtĜHj>GJ裲$WZ"+n|Gmm:Mj[?> ;[ \:̋CJ~}"ʰ t o3st![m{y{mՎMmݼTnf`kQ@}4?6^ NÀo{IPGc.ЋX,-;j] M,8cĐ5T VX(j r+4qH%:"-i6_YG#kxQ{4 vDT*A'lѿSz:WmuiQpࠞA򱵴{b6ot|*N^&8FSemNo+Y'O)bt{? 84WmJAC9 wEչnf{w{|*U{3}C.&gm[A(}m $Xa LQked7{j=9"kIw 5mf,/M]hY?|&,}5A7&B۰ɨv ?ȟ}PF~4gu6-H۝#/N;#j}Ղm L8Me@: wKT~qnQY0z^m+:1}Nʙ}wmщiJP"divav·^~玔ʛ&y%E}Eu؛;c=sLwT?-eV|]n84b6-ks"XYV[$1P[I5n&Gw*Qm2 K=[c50L(s`/Ph =2u4'ۇ}N!O*ˠ=>6lyJUDdV roC<3H jAU'nNt𡒎DJ` %n9fud Na?1];Z! 8mʿY:>t,t\ YlW)z=9hFQ5Qҍ0ϐ? 77uBTw@!`@diVQqqU|uE"8۶ۛb)}"=H$Zl9f$wblboUVO9 =ai>d^#Csu`:X3r"M 1 OcY2^þqUYOe] ;feT6ˁl[X tpB`$$iAy1oA2m iשIhWG.!`x3PGMyV8j&XԺ[he:v42ˊ|F@S{yoStS! 2]9\QN:ͨ[O\OMt^ W-ʼΥd:-JxAi/ i kX* nz0 c1n@t"u2Pن3۝zdv8¥WV5AA3?Ukb,b@Cq׳ďb?(=63oiAwņ!PEޟ)a ggNRf*P6͠8ƁRA$ؚm'y?e F &L_sΊ-&}H9Ś YtroT!Mq4TÝ:3:@#^uPof ? ۨH"϶nΠfd""@<`^1졵ŹWKRz;nT;^}9,@xsʊA63 Wc>GqaTT+|5TmO#ӨP?^b qH{v\1{5cf(u*Qַ1)2\ţ/@dGHUܱvZdfX>Ԣ':ؐ?sWR2[p=豇{qm|r[MHeI&(m[Իvt}ͷqG"v6K֟uڿM?SC0cJ;dIX?p Ҳ4Ȱ6:8%Q'JWچOAD 7%M@aߌ8`ocN|V&`ީ_ʁaWҞxjI NoZ+ 0m&m4ϵ$ a^LeZ<ci wۍ~8?"v$ 47"Irdiz;5?4n71UF`I@{a0h1Me\WN)\X8JW;xm-(*4 p3>n#>81[ +h3)qyyQf&X;ߍlQu@o;8;NISs.@HdV11ϺprӺB|ŅƳp;JLd3nJ)K3`rO҈ɷ8n+dʐupa*S?  5bk-]з#C f q{k8/'jY8S,b#ZBٕQ1(zh e'qB3[xIaDΓbL@Ӎ/\u!eLSV1,( ۽w =D^k=öAWP8IU 5ӦoZDJC@Lw"5=[\Z‰(;wh3SdZR7Z1=& Dl)c :Sݧ3jHfJj6S91[m39^Wi,I[h<# J>U^'un,;{kԂ`όiOC~]Vp ;8uPV}LL+Ӄ@gHi:@1xq˓Ժ^lE <֙@vv-uCt |u4'ڟEl,5<|o4|$Z!OVbkpuڊ!7O@{^$$XՖˆQq== ,ukp&mC`bZD=&W@˲DiC@?XĞ9ԁ+D ɬ?^UџTQV"knD.IOq=vReēJ-a?} [Cήw%<^oJ{'BAmf;(.҂M8@DA h5yZHG`Uz&FMϟV:,GhhafǤt-kmct6+"bYb4SXxQ|r@4mCÇT{yG:9NV E!S-z1v"YSXFpFT {|iFyI;)ccdI39_I`pmmA 2"m ,bA 2 `fz|WcGos S `6^3Ah0/i4ǰm`6A#Otp&>m,!Acy$>sfW q<-L"FGorGmWYoR>[Qi|OD kn?+PT5 P5 H#Zss{sLJ5;]Dve$Q<4bUWEN%.i_7L3"O*@I#V8kl(,$V4/Ʋ&1D,, tEAˇ @FD |(崏z 1N6'P(vzGzp6k1\6 (,gOR|Rmn!fIU[fm+ָhĝec>]m˜\8 G&3d%68/!Wl[ ַ`6؈SvŒկZDp'"[AXiK}{>ujtg bx\tg=,I$ ނC0xSq7|jfVLߝ˯o( ExT׌lf{bX-CxQɞyNiny@L3].X`sV/KzmK`2^gE!`ڕv2o4xgvT|{5SX쵤`u٩6Ȱ<W&lhKd&BTw~ Ge7xm@'Bۇ=cϰD|Sn*8ň6ʗL^WgehA:(I`UXXwL+&PD|qh˅ƃm:83w'=X*H2{p Ӳt"D=E2FRLDюt^4%[?i׺imfvOtA7dڛopcԙir~LJE׀t IfiB^ϲ(P/},zb+,Z+:GU$~dxUnZHBE6_Pyq>yѝ;#OH֔o6G=ə$p eKY=1M";m[4(eҁQ,d@P~.S¼{6CEʶdXo @#R5Sj{so.[nzUh㱿D(BƂ,oLY19\v611j_,F Go5/KsrmziRN{I@Ў'lyT.Ddx*FCm ݸ$,s-#Ʒ <j2=: -Mf'l$ μZ6(|Hu4i^o/+C=޹H+O:Yq:M7 y2\OL3%-coʗvwV!k2LD /Eݎؘ p¶Q]z F6h J_#~m -^S_؜V'A&CnZ6\o _mZ45"攞 ~ɃbS!F3Tjv67? Wlpl.``&҃oOwLQ[M+u7/,j@244q"O͏7udvL?}!H+W0EU޺tgPr&V\>}e46$^`zeF:F#qb':HG;Σ| F(zxWҾ2ܷW,u-|ۤ"BW ~Rt3+ _^tL`!4jYrM;YJ74UYk;l 6Xƴ dsJGƹ0(4T3uS?ӝ-hlS*ǀ;W/E穼*mb6&#%`\>omJ/S5?QA2;LVCq$j5l6;њNf 4DHj (W^t-t`TPl9k{שq|X=./C;[ _mn~@" CN`]Vz2ӮZ1u-QI G))_tnndr ^bT_2'HkFZv %!$Â13QbB7K ML!a3M`ݙ QWlZLSXU*PÃMAɃ'2t(IA@ӆ`ۀҤ hL-Á։HL-"2&& ɬDB5B0*e>ܨb {][_}T=xT**8閑7gmu 'uv!ٕY^ozm%b8vdc ni@`2~֓$7ն'XtݵV!ojf/K] Ge*6,Y&SJ[p2nb΅ iʷN@״Sks]| A!lb,bFH>p|O$E[H'[Reaޫo@bI$AZǿuneQ˭h%Iim(!u|sG0OK.Zv$ dikE|WZ(CL~ڜ q(79v{@9<*1VӆRviX,c:{qe}wS'^ho(Ӵ,E_p1^I4σy@`dž ;;Nj'P)+tLJ 16- uZ5<'؈ 0t־wWmbq[JΟ˧+9^L7lw >'>ʄ[& vRHx4pqȶc8[ Y4qDn9i`T+A474wp@r'N>b;(mo5H0T&Ꞓ:cbĐjBYaJ'K*iŽsB9W0;Rn[ZyM>q,4ўԬ8+$7gp ŠGkFH!8RV}*+T2^D,I"{."KXDikKʼnmu1ʊ#]e葤[><:<!Cmuh9hyul~6 @Zh *w"'k;NBǔNҁ T#_}gdZn 5ոG;W;욕b%H]DkBuў>R}ⷦlYQ]m21vrP^zMIߎin60 a"p2Q|E)>m7/sLI ӝl8D>S[Q puXozu_hl(oF8r]*i~jTqwYӈI4 ޕ 8<*^݈i˷]+uaF Σ?"ӋxWl⩷LA!z p#Ɗ8y@4Tm>z+4yn? sA;È>776!!muHP+sk5;RoG]/iZdžӋ)yPVu֗=LUn%tOKe|T)Qb٠M.?K1ӗRf'h 7kO´_Eame`8DuG`ҁLT$` s2iQwqCLKQ=tvƕ+ H+oQ@9iӭ6jn҆ޏ( p}S&AXf/3j{jRxq;D)ob9<͖a0m9<1 Am(壘vC u˙_Kowzu\xVN1<@|Ñ]FٲQne x/W8V s*LqJ&iv> Ԏө*ꧨ/cl3ѢilO &vh8 fvu-mR_b8R'șh&1@vNJ9_Ymmf[TS(_u#[siccJ$Z-ȟw$  NlL$tPٱGQuUp2`˛Í >ӸW]B v}I8-o[qya &HuyYK \n#A&2+ _NHZqpֿOqr2dODDs#Z%/inzR<6r/=ۭ5 lP(AFQ΁|9N,oȬe[¡/3mtQK CWf`:Drӝ7ȴrפ؍p6Jw4㍩Y nvw?+{dRUcPWmk[## >;8Q3G:> &7%tbxr~#(3n^g77"9[^}un!$['<ki8ZO,xn,VQ<4EuZ.R1˕n#F.˯*22 o& iC]nxRmxQmD.+b2Kɝ}nelœ5I*cxMe*4u]sqz9jׯX #cA&9cF8'?+¼ll;NtJ7o")@CԝCHmBnl0')FGYnTp8VW æbԸ4#/Eq49͵Ph4kiuAzb)l.$v>`7ęLpUdLVL3mɂi`6eۙH6DNq:mGN &*7{xzH, b X G!or"Cm&aiI/[{O+ݛoR7w(q+TA"U3nb@1icwX! Y\ a1u-ј cŒ}S4<[(IM1gaKk7RøȌ|% \*yi~ `cm,푣 o"x#Ś9AjWjd?,K,QŏV H6v'awP8ZS2# mea41Moidy Oy@cdp3ϝ ԸɀLSzg$| ը]u\Z8Mm.2 09`Zd{b Bd|z |@GRxE/#_{)!I"I^hԷ/>oj^ĂM&!ql24=yibdzmc|4WiRD W.b I5aOPQ-Lbr"4u*4a͉Z%Df 0&"c4"bU۶쨉:@^Be .D.ʆ<W0AR;Dz`HQ+ Hy_7(XK'CB!<-MkvMf ([~h'Ӓ45 l1~q5nE$7l\x0U09h$4 zgpZ!P,5E}Dh{& R|RS"DHm8ҏL/2Zj V=o ?Ip,hTS?頙Oe`>5*4Y˸e-2uTOQ@ezMriX63e&e[l[ȃC5bbRmH"TʊJM@<'Z˟dM9rp''kHR?06pcHs\~^].W_ ҅dvD^W'&mS{GspЪ8]p} *X)E}96{jCx@XXO<4SkhȒט2BfuE5iTv t6熱u'ĂZ'M7^z ;Gi>6qˆbjg:Qa԰zPw?Ǝ W+uXjҫ4osQoV`{fEHjIiN.sl-*H$itA&>cV[[ T>0ڼ~"ؒÃX R &LBxhma?Kkf*hάHnd{Dڡ~2x_X>NtACl: O35_FQI 8S@9Vcr#\VfwgiEXky(fkrr"@i7'At&CA[CR m_X")vqxפCs-w~^R<QC͡:ִ\c`ѓ}v~a;Gji-'bLLy1{eMzJpFfSI(3MRڐ'-$p_qGcp˜,T{(9cǤ(Yp.-f\<ELytmhޟP?:x׫JI)V.8F\ma[LKؖvYd تo}/'T7(ɶV׍cIS0A[ơey[h$ OlԄ̋@]F5醐U1aG`+&$\^J8f?iU~P#p!i3xՁGƃN$;!nF^nw8c^:4I"O3[U'fP[ a5ȰT~ɉ{&)H&cž\|}ՑR}Jʸp*EfYU.&>O^ X+/)6aP?QJLO]:1dıxPN'vic/[{PX!5DW?(r$%^oѠqB`2Oe vSlDmOL Q>76$U+5fߺMRQM % ʬ5OH^]TB{{d&d6@E1(~u :᯶r@vbe.9M[ GU\K7ho '[[[Rm})$5adH2#AW[vɎ۔*"E7CxECTuΒ Z_hM:[ZOH$ u<\,27+2_oFn:s /l7>I=u*P~mli4oMuI= pKEJ4*FcTDQݑ EfH M["6(ۋ?׍.Q6?*?me9al&yfY]{B$6 };m$ Y:TrR"50)*}n,5pA1Gq@Am5xoDuLfꬾq2ź{n+`R55-_LrWRx6! PNfl<쮝{Ǭvd?EnqGee~Ta)ǔ+AVڛ,j}"Wb׹Z^G, [Q q#GbDO3Cm P1˝`? iv`$K cENל |G.Л^y7SJ$ &Đ?=5U@F6Vz+suS&'1JvLd&&pM> 2xc"$DV-ͭ[)7r92X^L?cBCgBLصzۢTʰDV(X?m37\0-},ZaP7>mbH!}<`q"D車#/՛oyNhLNr/G:0MBIt{ QZ{jsm5e4qiF juX˜Dv J!*m*>UQ?Ρ10#J)oXΣM9PbIƾ?u75}Ńou;hǩX Q{h-g/u}ЩE7QF>Wk| ˌE>+w͂1h-¿udH"z|+`X/p [e@?9Dˆ`8[ba*)8mi7 wræ4+j#N{ Q(vߵ^!cq5"bu֧꾯4BF;b6T *牫^:-xՈh6'V"JʹA[%gPǸ ]ø0'A";@`DZHPqŦ(,cnt* FV%v^4)rUrn m#O^LJ jʾ'e/?u Nq!`Oq҂ *mGP-xj v̶#J{nT7¶>O-J>wˍyRgD{)vB9'ʣn'X^$xҘ~#ʹI=]}77nim <~r#ryrz˯m w=ߨhe$kpG3h9$R@woL^E~"#Fl3?dtSoH]7{k Ż]7y}:<:O=M.rSn4H^)ER0&;is` $0] \ܙOhnI.Rn>nlcI=S7K)p졾ug{5?tϧ%w1Dc)>F'nmCpul'BEVE+4OmB51zvaDcN^_)\խRbvpӍaf)B#A#B ?) zk) 565nEA@Ǎ\_1m"e~67HG#˜9*XtʬD~Xk/EI{dz#P`֔Jf4K6[ۛb 82<4'2R DpK (I̍4C@ =y-i?O9Ǝ?Qڔ0ˣvn$G ;S>Q(w0γ2(ycaC|䇓/:kvVphM4DZup-ԏ-JLA<(hI[DԾQScP)GN `t7ae7_Oni`pv0>]&&&klbatJ玸OTxV2 bܽHw]<̮O[cޜnNQh?n dG "n,͗C:m\smv[{Lf-EoaPRṸN>fm͵mk_xi@7_3×:FIuPݑKg ?Ĥ[9R ž=< Rҟ5 ԡwo _EHO ,{B6 _(h{)Fqkξw6aDFZ2 -#1Dž}6DpX\w hH>?+?˗.\r˗.\r˗.\rL~e f8}xo޿a_Gq6z?a_GqsUÏU?SƿCON}^ï^s8O++W+~Ã^rwߩsA_G7&?Xsy}5P옒f?L&Hnucxw}~Yy휧>r~~8x<ּ+6 5q@su3{GLG59>H.kY} ~</]N+W9iǜzu3_a> ӏ9ξ~:8L]o9~xß9Ï0{u/ :OP)/uq{ɪz|'~ϺGuOyuӜAO_is ؿN8>ל~~#_G민?@d8?믡G&L;quǛ8>rY5?cW1&y>ۯ8}8>9y.{72>28cGrbg,%p+;ß9r^1)'CC&9292|d9d2c凶!oMd,G'~WN]=hCgaKG1wU2@S)@}:Zt<yBs8u4e?$5p>ovѦm3.yq_$ef&L2dɓ&L2dɓ&L2dɓ'?Orq\>_I&O}G._\Q>~rf&L7l?ϮV}W.o+ϩquV>;k@2ܿпIws?῱>k7Oc~KOpi>}p}.?C;_ 0.m8ep虻>ٓ M}7.98&Mɓ&L 12`\2dɉ?[)LOJpy* 9(pcHr;fsH;`ߡ Ϋіuρ8VGk†S~p@ުa@!4(%YaM>^>rEi߽p0Tb8U}rW{7>7߅(-W]qxDXj1ؿZLf@Vr *4: U|ĴO8['|ݸPވ)}`T kX78_QC<Q5ÃTI5~p;7cQ{wȯvesZ$-KJ~򸞭F>_el.4J߆a(0z^X 5,6jYxIDv;Ƒ:o@}qB Sj]CRn+ROJ&Dg0*Y `FZMD5w=2To$BiuzrTKxf5u QBGw&?=g]L;J 'AO<805#S7ф116(gY--B+C^%PP($a n6]9$&w7Og9c,xP@:ȧ)MfAȁcz0' e3QBlx7FC=yȐъ2P^ޱDT`Ij#yÀDس˗ lSMLCCуްC,a@{b  }b QKG7dĶoJ)<6 x%]H^D(JyEu$2>:dWJ3d?cF7袊hM/n2@@Tx.-jH&Zlmŭc>yk dV.c)(Gog ١)0D b(!~կa_F-Ȃ}~F×4 ( z1"CMLq=` iz]`r) R,DC8t7??&A^Swbᬱ`(v 3њ 9X)vB38٥kLbKrH飬9@| Cي308`|2͊?$b^Wy\[n `+NljM;)n<.P>LGhè#盎+ p B Mb2 'GkY (jP~~B8|ȿDyp00(Aף6~ V!ׇbrrɣgBg'\*5ӈhDtE4=%'%k Yf-Mx%'8yCQD~289Vÿyɛ現g (}m~8Kiy HdtpmЍ9#ڀkLu sKQds4Yr`MB?q<#"D&+U0p8 %'H)~IĨ_cB Isuௗ%?!~qm"ft 0v!JPߌ@/P4;?78}\S N"v{>x!`xkD cђ/ܜ<@=02 0=Ep%8lMXd|S4{~Uzv!˰6n]QգxdnЬ|Sf ba P򉊃!R1׍\q1AOq<{ɴvF&Q(H? tHڜ#b|d_͇]t<_4N^D.9̫BUu5~˛E { ] N1"7`k F g%yA'2@јԏcLVVjIJtmC6[鎤"'~ '"}vx *= x0 bj[Do @ [ ={}@@pGq04WF|ddI4S7@ D yJ>Ob7/1l1)op9p(c Tq&bKֿ7QLJ{A~:a|p'\vh9YbF+~7E&iNF#أBP8 #XUsyGDb HdhL]9e:Q AEIX3[i|@MY0t<ʠiJ w~. T? cIVo![*{"]a 3 |`q$Z/) 4J uJCOC7;K`r% /S@Qt\BRDe/Zi mzCj7 $S醬$vG(qP$°X_gɲT`^E֟\jCf4VTr OeBja.By$ނ iSAx|L.HJ(Ⱦ\9jS[A-nitw/nPcO0@Rԋ${c }ף{crՊ&۸ޖfU1ІĐ;mŪ*Z*8gY4 H{uE" 6 @)U}g EͰ!#:qJi$:,0'03(UIy9[$ 9ۘF+d芷&T?5DM~rs۵P07󌨔8Bn<̤ jhԩּ(O{M< .ߒG6ӣS!=Ì ZOAUXny?k`N-aRd."\$@vl=2ݼRRbt%Y"=Um ^1)T-GCx2Z~rA߽3Yjz{`:~`|2lh#A6zO&dF!QrA6*vo{ 3tg֏*:y6C*%p$Ѡ0(MP hG4Oḋ+񀈦u58=&TaHNӧAQЍ`SV ޿z #@9/ct1lAFTU݋ ^”AB)K/yE U) 6l5$:v1 ;daڋH'~NMJҾۗr2'KrfӞ;bG )]F7<1ӬRbfץ 8X\~4Z٧U0b6HM?c%%%YI N]/!P~diʆU,!h`)߮AD-0WQ`󏊡GC (F6yD`<2y @4}-dQ. (h^缩32"ãasIq t9+%'My\*~ l4Yx9|8*qe<]l?w ,tDB6ZOi2j4 $%]׷72sֹlvkLG9[-a:oX8U]ա؜c$EA//%)*zL|73J t${M>Lz4Roh}V`G3|[WJr:[WDE,/;M'tDho@PQ="4:n3M_!IyQ9Y*AV4!9\g? c/]NUbÎWq VƎ>v}6AϮH,aa3٘E#!C^V+a> 7n<6uN 0N f1GY+Ys[8VM(qI:fxu0KB-mjUQpN8P(Z< %Dg\Dn #2[;03 u3FĈH`kx}U9؉sX×&Bv@Pzl0\q1ZהG*KKTG& €čdQr=z‡0&bq D Շn \\isT4'x?9 h"]3tXbI/Amui{,M A*2A:t?5Q'|9Z :|WVggɞp ġKPDwr[4L7fm>G/_x OO G%Ӗ9nQmf~I@% CMTB_9GEZ8dpmqkP ]RI庶oF⃑x8׎ lKB~ڐP!1~s@g$(F4yuM&F;çr +}˜'; iEEhGdN(aNP"듳Yَny,Z!7r1Nx„j5AJehaAhPMm1c: XB`B(rtbɈ`P$ZI޵;CԞndǶlh'ZvS*'%Ap+U6D@+]9E@ڿ6m CnpP(]<|MeM2@M:@`.BQ!'88 6LP(cL=U|bxM2/9}xS{`]}r.dfhD8E9l>׌` Dˆ Mw]/5Mۂ*>~ aAlz.߬-Biƕp(,g 4506  }_E 4f=6:qPh(#U<`IGqe c T'cÐ3yjx !n[S@?9zsj]+ I8+D5Wei] 2j EXt =]P[3[ 2Kb|WQ nyu m+va$>G`У0.ڟ4~t@Qk?9a$T` HP&!L-" ]`G@a#Cn7cm>EE'2P/8k Zx||>#8&QD8(R0mba5pb';ǔr9f, eb_9+6o,Vo֜ܵ%T/MT:kW#x"c@wd-X`CaJZ[fR35'iEAUAŒ[x٢Pۅ]mɇ*]3Of ,Xւmt+G ?>ì[gI@;dAG&sn>>g@tt[M^㖸b2"({kAr):+*b挴;578-~xwjv>\ѭMI"LIbjSGTYS2/xT64yY*6!Z Ay ߜ ܮv@S'o;U #Jfl x!ZؓU.9΀?@qn|;k1 q1]*Q@0L rdFKZx ܁1,7-uһː}֍℁L-N[D>NzK<6?8qؼsjѨGAgޔ声Iz^2#Gyԡ#h%X<+ݘ QGFԦqXBUAX[;jp0 [;:e;aXBk<|Xj߃ tw\n,MV'B Uhk)Ͽ#SQ{Mx-xyibs8OPBopRXµ *K*u8ȾNHEy"D 7 _8dK01[`7Gj a:ڼfCB^uR |6*׳+EKXzr94N^f=Y#C©&(eT0;jb`NSgӵ+UwpRmIbE逇BZ&|2 ;pZ&4)ĸ9ݛ7r561g@8o /^,XN#`8HI驈ޮ]^ 1f6ڸ гʚ~>׌i\aCR"Y{'x'8 眘w/ۅ p7+!*)=,R8!1]Sc2$-Ǘj'(1U ^(PVYEH5HWmCΓ:tJr7dvc͖1և`_t͋72/dƔ9x81qj`u_PkM4yלݣ> ̐f:= .2gƽ`^ɬSi=󁏇S]Ǭ;ng$J`LZfmnTqH 0K24?L%b+ 7lVq90#yDtGh@̻Rޓ#zq :,>Q9?kW_! M: h65Tz0@Me'l~$)z~rSi']kŌECYHN KHTF8W%Aj]:.<,HPWo`XPѠ]X ӤKkSI8eaX1T`0!Q5up^#H@ %: qvb5D'a&g+SeO,;uFLD)$tM/8(Q&)`"z$ * 0k$C>3 bi4$!q<$ wa1ǔZ 6]& W!闳CTl`!pm-xVOOeTP(44\ 5A%7N`owsX޲p '54Bh5N-ٰAA)qE@+|\{86Q3TF(h]mX6 CohBMgxͦn?ͥ|3^\}ӀXԼ#->h@ll~AhFH}kٿ9g"yêE.M7ڍ"NJ(| 7LM/)4ę0mr)d=cdҴr\gn$W 2Bǹk+C(aA!r+$d8_T.owv),Ym|[iŘ@8s#BF%.٫mDQ.eoL%v[1C83eu P]q5 ?!8MJiq0ס6W$(``D sB"voZ4Aߌ9Sf̘k!8r!2$s m~gu e?Y,iL!'ڠ`-2EtȻ/&ɑ̖_7QfFpRס )݉ $ܴKԓՅ9b$[OG hוdcĊr=:>95ˋx#تRpPP[dIk1T KϜ`E.ӧ-zphGhL8Pu1|ڍ1WMG`8Y!\Y`ĐlgI>?Rv\: qsE."?8#&}3aiF{ 6]U7gDP3AT~tdSy;kZ*ڻ7E'Cgu(@MH^FN:n1!IT]G"r/p?ez.- Q#/(wjyJHj8rd0Қ0PryHg^=ĊkMS:S6[MKoc+(ND$W$UHCG[Ͱ'&f/ |Wd5HZlGM@% b twk2 WdzU5oXH4qjv@Om͓Q8"Y5p⫖qC8@q8'0iׂ˃xZ~7||vƍ~@rQ :0PI6vSQi=LZ;đ2]i:E=x#͸>]Cz4WǻM(pX$(vWʜPx`eBiONn4v\2''Fcrb<}i }8]sr*"G~AdE?L\y~*!mkudb _lhqc :, SD".Gq)SXSx @lM`G3'8H9~26< A:A]eͦAR<⩕*9#,7m` DUz5%Ȥ\c3La]Gm!#Acn ;_y@[bҮZGˣx> mFֱ%u <%ChS.) ֛8q&Z .q\-ZU{DKcrDx0I.,+mS@D'ƃK/ Tc4{qU ".81@q6j`B. =zڊq~1_/fLKO:! n?:@d}GY(+(sjdobQ huM1OFyW~k`G P:1gAh{ ʝO: ]#fE+cPF<"+ '&3 2Z4h8ltc 3Kל$rB %A{D\ )Py!iq;&rޒv yƢ7d,;0TrǺ:Q})EۧğHQ]PA951[xSL zIBoi7'P ]t guӳ)Y[ɤw! E:][Q)|LG% v047{)$#U^" J%d<4$hg?M._9$p1 k 8Dw(r'JxLT5`nJrMfSCW 9@|zv&zr2eR5VXv-6lT:= ;qF~9 YkI5HαIj9Շ`OfM:-K&Qbg_`aUI!T">:a{uόRWWno ƻE>~N< ~, 4\4(VxYR6\b捩n!_+!/\PnHsEHtM+$Tc' yBF*+x/JETvQ\~{9쯖IUͲIe]HKDo4fF.+ќIT"NC`F?Y=;sQ0%hc@JVֻȆpH:Bp ;CǼ 55:_!uF()VS^3FJ e6\yWӂ|a2+c8  (II:]0}},>"I< RC>4Dp~#:$Vp@}Ph#\O Vcf@p&F U պ/G\`49 !"s.+"ѻAq\h ưRl[9 &h ɱAo(l1$pLjKұ~b6T/,hn1GO".r A+еT`Lcd#צ yZkN/SB.z6#?dyG+℄#B/D^NR;fKۡ%\~aqCiyd8Ӗh`1yYD!ҍ[4=-YX`f kG7}q ?'^0S\;* RAl~D or.! +3H zQ"ӳ>1ۃMoHB}`Y4ƶR)8':$0@MW#OSjE6]ǜGQTd(j)]D#`AK]tNf*셢'Xr:O<ܐ L@ [bB'/+Aߓ]bt gg9nҜ"M)5Sʌa4P{Dx @]9Mj0AiZ{b.ApP2h Uѽ7! k$#NBF|H@Ml4iPàh\rv20cO!4^XX9L-ֲX-N8& ^NA;%2@;m3|pPpBTg<ҩ`´;Yh)H>"G4k*)y;rhABBr?7]•rN;S'1ԪzJQpk}`"5QT\W=qЄ/E7!q͂fK7XQ8g+Tx6b!񭟾GHߪ|v`Cil$ytMiPގ刄HRi&6j#Q6yrR#zPE.lf1T@(Je@Mި(xjhj4Jy/iphpExC^Q, %68ʲ=O+F2 V+'I*f^("G$NM$m3Vsqu6g*.bTR f ;WwbB(K+reā.r%GwfSKGͺ14ο,+t ><|;w\"-Qnw.Mf!O2hsbQ?8SboF^$0F ak i n}~0%*TH`9 (lx DS~dԂDnkQ / (5Dz jƸJBu,2`T\) оrKI (@h"(ih3J˥JΟ Ջce~lgwObdž ʋ犀pA`0h|p?84;v?qI%ťt3EHA=>2J'{>qQ'(l2f)B'RTщcϲm+*bYMlk1@vq_ +;ũR;c ]Aϼ5*69:˭:%g~t-#^1kHtT? [#YF),Ŕ}-CS+4 ʈ8D q#+:'c6L<޻9f**P+]Y1 @X`'LW2+4EUTȅp|!sv)u&U"AD46aK[rj۞8X HV{;ibi-IcT{iLD”oFyv_ )Ay ep\Y66 dŶ@PW00}c E@ "%0FńfnIB$^ Q$m " %T[ ``o~\6G'&bU)9j#<1Gn8DJjl~N痢d'2;*a_ A7UhB8[ERd7)yP,/_l `Q GX-|<T9!М81;>0w {iw \Q1-vU.j*ƪ_r}`f%oAbmI |`jPɿ}!+*PbKpybE` +P`ڣK/?avf_dZċi|bmE.-do|˒B!Har ڔN@^6`m.IccXCz/7$dJK.bE#zv-I]D>A?.4`A40ʞ%(u$_c -b#ôx(~'mlZK? /QwxL_됒#)D5G]mv羱f[̜nx2 ZUwCFu M<bBߤ|'!=:7qϠDC^M :uЫ&rΰHAT4[6zb*::PfɀKvvb X-gf)~]af؄o7[W=cioս<ܼsg`T McljitOX"%aɓ={] ""m U6]$y5-[[ T$`Uj(`B#EaF~}1!g4 8*#jŏH8ЕJ1>-:qc8Owe'h~ Oֲzr*i&-(/GISɚor -WdHu@Jz@=S</xH3fB8z}a mE\a 7>r? QrAnvK\]81բJyqQ4A{ˆwi1H[^y@znK㣂*-VX f#Pq'h g(8OB '0qZ' 2nƋV:tm}_@)| \3w.@-OpQA> 8P"a669x"lNkupbVNzѽ:ߌH.=du<j/:[5x݉q{ H&lqr`3@|{cJ( à죿4 Vx@{p`J^TL42~.M3{nhL:h`lX pSxovз͆Ì܄ ˠ %9,cBHD]ofSPwzڛCKqcHy? KGqAxXjt"#v*ҡ([~Bÿ5>ڰɎqǬOͿjH~ ]' l|ihF3}X5M?yʥE`ST*9^N^nO;9jh`F+?"5o;%|Vu t!GwAP68p1>Z4n8Cfid(S/ 4{hio/ n^OΠpzSuFمrLksF3`;a忩3O˗9ק>S}fryHxzgq"pܚLPP.lr·ɌDo> '3y.C37'j=&Cdɓ&L2dɓ&L2dɓ&LxeĉA>h#F(|%Ym db8bB]:#@Wx+MUm:hiu@!L`8^uB`Qք:ءsiBpz4Tw ft.n*I~2h1EA(kU,*%/g7 Hu^&SDLvWsB,D>r31vnx_)^%ĊG!K]ڙ8iT]N^p҇3MrS|`$JgӃZ ~]GǓ} #TtvG}Ld9_xבh/L!@hPdW<}Pylons-1.0.1/pylons/docs/en/_oldstatic/pylon3.jpg0000664000076500000240000012262211645401275021631 0ustar benstaff00000000000000JFIFddDucky.!Adobed '^6      )))))//////////     ((&((//////////"! "#01@23$A4`B!1AQaq"2B R#0br3@Cc`$4D!1AQaq 0@P`p 0(; : P8t@  w(Du{tÙdQe@2jD3DC!N dh@PaYŢd=6,-|:veS5Sm̹nX)^C5uq;Jޏ}@V({:H0]aQ0uP8΢vET3Q ʈQM_E]@g@Vb֣eT!({X\_ʤv[3J}1 ā|:-΁'X7"Ɩ"FLZ}'awzZ2D!r:3q>EsX4i=-`@Z}mq/E4ѺErbQ>; Wyj*KdR4qvZ@;B'?۹:;eQvxTgr ^}߉Hz ^hJZo9i_Lī(hӛuKmNR.Uܰ3\uHi}gbڌtHu뼧 ìW:9'_7g玻jv8k8($h,[Bbܡu.-^BzVihҋ-wp(ԣ%[5=W4O7v՚7EرMp %DYOu"ܴRƠeDZYI.Aul )3Qj;<(JJRU]ɺ dQ-ӖfV6!ZKTŧxeX‡jY 6yUnUⲝrGDݳFd'OC7tRTSa;t}Fxm]i[l(/#)@y\vpbU14y=}tH%+bQ)VgP Vh_93`}kҌ,FqHp>,Cyb$Au^)U`OETͭ]yM@ Y=e>aU ,.zU MɬΧdV;V[^J6zfۦ&8RHf/ؤv@ٜ]J(ѤP4١"z1% `;eV`ob5ōkPCСop6)R˩@ Ɗ-fIy]b))y 5E+$#k(խ#[v/844gիA! .\f%9݋@nZJ残\r(oB iaSYg{FEz`S~x]\k7/0&O U{3ŋO_Ji'6n47P+Zwz-#ZRˊmuJke=-sjEhT8yOK[h28^J`TXz[ڳ* <ש9Tǚ̉4B-CDÎ 50 )[\Տ#$o[zLE~2s"zi*mULg y-_]yUm,g/5BKM;qk+J(le7j/) 3\\N 8]3 \yb)Jy*5azdܵF˲ 4vbPZ)mٍ g5jA5tcΐ=%}sf[Y\*q))Yߎqۢ9kH顳[(zZ^ =(?7b5-:(KhK/IF|!ڻPKU9N(1uLW/b ]n>Gi/ D2/]fhI}u8 yj>I!DVJ9+|jG[7U|>dSz_8!u.2ŭUt&WP$ٺF_SqL]F?Hs7K]ĝo ffI.G|Ǫ5=-֦uxt$0{mzD58pr'f0Pv,B0}n qnz{Qsޜ8k5]09u fG{aٌWc8+ۊ˸͹\ 0pSVb&;mUrTEmÂ}gWg\*`8_?)]Ol9Χ8lTˆOO )Q#?q'\# UC\0 0ТQ~C…3ZÜ|đLWlH'_B~3prf]f#pNX%DPtgx;Ķ4mO-\=Hv=盶uWu8}G# \!L(X80$V<<̕X6v9> S.iI?9lf9\$-1r?`^T(粗Y 8YuB1UnG Ɖa< ZU>z>SbH8cNMӓ/$fÎKrpV7=@" O= \.r3+s)qf3̹ۆǥf@>O\#Rn00^aӖ4'O64Ō҈xOTՀ-& CALg11LUƕ{@mNm6Y%v[NFm궻q ^?Lq${lѤs`'N8{ҁ\~ 7<ٱs3Ϯ6UD8;ezcp3aPx Α>MKI>)nk)"X`8{q*uӌWm0\`Ttm[6^U۵NkJT#{j+9#ʖsw\mV_3GD$݋zyQ94gK.|9U2(ށxO2,Ds7 !m%Rfs>sDyGiU[iC#$}>PǢB.A#N@o]z2N^g r jZ'KkIpB˯%شubVL%)l=*xC5ˑ5Ċ [4%yW\,젵u/;цqEX`|F+ݘOؒڞo3"Uݼ'֩[8{{YC(Q* }')$qO?hn`Y@z2OJ6Z6$Aủdwo,;b1v5 {!=56r'z\fX:r +'_CXWVI%iDd4>X):J xת(i) < <>-O5#xcTf _'EEb}4`Gn{5j YuiW_rinyV4dWjn^va]w۷yvxQ\ﲸc.ǓS߷&ΛNYin'¼8+YP}tU;&ӌ?zP}~zl%~WiOf5P{pcZ+*(> >@ƠY~]yJ7U%Fa֏c@Ռǎg^ = 5pPKiH#1$h`@ \#g<.R ݹL/\}U]E͇`lהp=Szd;W]!,E&d5*X_.ȢߵaU*7A*rqsA;p3cR!%8'1'e##(Dʐ}q5Jbo5;O̧;tntua9O:~_P5 +Y8 'B^-Zλ'9vzL<ea9>(W I|AZHq4{ rN̽b)RXZ|WnkWsYA@lJ{w5>Ĉ_M;Sldb}}VU+JFʸBjֳgC !]^M%ε*y^s]y{#?u?"kk c]]_mOTkޡjxq>4Jz/v~:f׬ґ㣱]a 0ðEJ^7Dy2=WsӬoias\)hqf5_9K3KFtfxnO_k; j/pO_Sej$QnO#OǓ)п NU]s(;Ir4a5L,@f6<܌@˞YcBxSu  ގK\bArVͶYheӢiъ͗~~kK6* UqRN»5Smӎʩͩ,n^gQ3&ָڜ9"ȝ]ƾ#+\Pv!'[NW1CZi2smؠKؼqx4xׂ 6X:eSm XxVLy)9T> &wL1VSo"LN ϟdBȺe963KrL;[Z;ǓI(,ϧsD,azmmUB%2.Y66#:.55 9[+9 xfBrS^Q_kR n2 UˍAQv Џ6oC.zMU?'Rnh{}ݱ6/4;[rw)j,Dz2*x6ؘs#g_f8R+Zײ^WÈ8P~ur+Y-5L6tɱ ֋ŵm=ZN3Lie%69E2|P!D3W(u)d@8qr_E 1םmw 0__aifb}&yydHB}JZV+9o0Qq7K_=d1֣|Kq'llン 2mVT$u$S}i?˻/Jk|vB['F>664e)nƞj9B yOkbEyX,ٝGY_r'6G0B5R"_2N!HOZl27J'&+KE|d&5ݣ6ևa'Fy2'#-|rlhE1uROM)s9|QEIڍ5Kmz M(~_+v?CSc7,g4O ݕ8@xŽr<=&)D5.&<^QZ3* YWo./}5ljA rl|&޵VV"0D+gQJfk])+jOC>ëÉl0]6lSNA}͵~1*t߸/UW/huQ6wf˧yTd2VB<Ҽ SSdfl漖>f3{ߎNTHki,-@;EYv"CvgE%rdd=CsXׂ֚v+~N=[O,xip#T^ѲO?$>Q<5*ɿBdC~*Da=qݎvs-^Rjk\֝f⨬EX$; S鞼XKOWRvOJ;6l(usX2ԏk ?f;HϧWbOk9w.ͭwI2k[원.@ WbS"%OaU\{iyv{z>$i֌A!͵:s#DoMm.\sO#ic_8[mt3MGoh`n"epimT}JSNX4EWOiWk|b c䊥9]zm_^ vfN)LqU_v}rܝ|_"Ozmo;_cY+ЩȠ涵쎀0Mrf͹aK3U=W8-Z>V,҂Kr.65X J~e[43'8k)^e#.cT}=͝%6z-%\}U??=K66v76i\LkiO kD͐qiqR;Ljlz7qs5ܭǨ<凪pe!/b<Yg!{`# 6z}/#)vtZjٵgMYG\ -fD'.=0qxS׭vLAQXs_@i39ӌ+먄]H`y"xwQXZ{' v U8P>ɇmTY:0˜s;[bETh]+쮼^@b.9GE;ǐs0"ZR,F #^\f?mыv?d,j:A0l]Pfqq gƨz&IW:AQu°IŒH< loo?ۿL3x3 ^3:!ŁV`VLX$gTEqg8@p~Av Fp38`C׆嗁5<#;qut\i+綖{H紎{H絎{y 3Σ:9 ѳƹ\qY:^3s qasΣ<`\ \80>@V!~AwR58e-c \7s*؟+CB??0$’QUuW>*nмU/!"cGPrXK|+i.bpy{a"c(A5bG"*)828SfzQ^pBN`/q귇4rF4n<ԈŠ;ĈJ_+;hx L Z+U^F4BEU?Q@lGFF%F_.Ȗ% ء Ix{.2uߌje PvN$A+ FB/@z]ؗ"$F聠-_㘿L!#в-몸OD͆,ufa{Gj3:3c橹6Ҋwȍ ?aj'1BEbDLBp?[6'P PcU\Ќ"~HOh/hTidnj;Ce#Ls=mR{"@9႖ᇩ\Lv`p)"b/&6n m*`9[$H~p͹L0s^p PJ!FV !Ъ܁j*}7R1lHO5p4lP}2$&8rMC>=<ѐ8Fv6;$anÎ &UwbjS<{p, ܓj;m1 7lWM+d3oN[qzƋ޷;Ψ]^ŷ-V[$gtDF֌r!Q,Mջ;OTA UcTU̠dEa<+k:vŁO)sT W"#ĹGk_a/jUm?{PݭQ=Cz$?\>JتEFtO) aUnQ`FC͕ TDKNo$: mZO sn4y(Te x">(ms6#Aܥ$b)GmƯm meRW d?W&^tOTe\}wFhn3"juP5ó50).Mm炌h5.Hqa`œ@jJth9J=-W #-%+"3>k]< EҵT8 h_)،\0ÏBS*Єe1>ˮ]:!_O zD"iB3\>X, Òqް Dms: BAג,NX@#S!_$ޘ$oPRܱNC],1x&lc-xrVN7ZHFTQ, uF$rt9å$­nm=C|Cueӻ6 Jw7}F\މ3V4XJ $7il˫.bd.4H؆};ѓ_ŐL7_"/2: සDpcTW\ e9ʇeT;_'Nm$y~J*S_`'qF P|xU\2X%[wQA;wPhݖƺ5!w buR^x`(ciij3?7QPtTƺ"9g]XR9PPx niKyi;.DZ9@19JOQ| RКx&d`慚*޸Y5&D]oY1!D 뒿הn[$$7 #5ZZ"w'Ӧm؀ڔ˷ /1gcjGt}XAYQxT5gxw!Gls֭h]6 lFU x N[v9 L*A䁔[Z6;B@qPّiBiįVHȹ PCF^WʠGN# UAܮ@F$j.Lߚ F$]Q2ʸLqGr;fgS(S~ |6^n>tK7cCWAB \Q0댵 JGˠvUK;aARnл3FsOV+Hmgwep6}c4RjwzYGwIc@dVBAR<q Ϲ_EEB{4ô+)Sx1"(Jb5Nx'yHˏbl[DјV r)T5:hTRS+NtVYgQb዗Z/P̦?(qLhuhrRl=G<F1鯁tS[2T0,{LM cE1:s&]]M#rK{cӐ}'s#y)l闹IͲ RJ/5D1D*OrhD䏩9W9TfzdY?ҥ*Ur鯂Ip#.H[?Nr4q:+1,;о!Wۓ SM-'WT'W=RC,;M\j>zʞOp8THyUNRu; "jn6B"AzjE|-ܣgEyCjJ08D-jam5zh,:frЧxVgp$Rj]HnG'}M%3@F2m(ƃLB9㪶Q˸QF 3J UhأFonW*#785L&^R|WQ"$ D6>%-vet}A#*><*euYFS!͠4ێ{H0ӆeHJ$tUU-H?SehKڭ_" ]^Haخ"3f3GӴ]1Tb%vzxDt_ PDq01.8()D͋qFJ378ԇg/ nn$ n#܄.?PQue# Y/LHN`Q2@jhz*،c2 ,ÂqI( y1$uO ?(DptRQrGm/Rt*'bQ9f0Fgbhn *܌Em2&onyFvIGly816&\sea7-g=F$Y6uD`ȯRNt8p)FwSdx}Qz4quoclpWM$@J"ۀz!(S-!\KvU0qz*7 Z#hե ҁ#FCހڔv2ӕ898 pNqj'mzbHF^brhRyF29IWp>]a$%B@?&b_MmL[psw5;mSL9+I\Oyn7bv`Np.N:LaHf"q-VgJs`#_B$S=xGjįN 9d낏ætu5Ff&t~mڍ-9!&[eĮBZ$ pS݉eN]1֋> h>{Q֎'l2^|snnbƬ}W\;PHd N]U# HY9Ax&ݛplPtNjaJT+vGFxHuz9U0rr}-wc3hdT0$J\9(]>G+cN$hnKF a棺Q ױWDGu38D9#7Rn"@w'hݞGSýCImˬx ͉6LYޮ嵔|[z耨˂7|?tvQ0VOv9, SLB@)^X6}a^1#؇ÖHͳ7{ljNqގ%;hd/SF?S*Ϩ'?5?ҬI+~{ȸ5R72QȠfxȾY:%7!Kd|ԖQ?O5ByKv!"0jvEJqy~QڧLhUl>ubIlTg S.j :Ht,rb]/∌֬$zԣ9.u}O,$k"O(F q2@uLn|xoEٌ.$g Pھ#wsrDT9ޑc/dJQLU%ډN Ԝve S[E"%dwU<&j䝩ih t8Wj}ZoѽHOQ9k޽8];;'p8ەЃQU$'#XhܜXw_^H=DѳqeҺ ӵ@%gh0kE;KLj2zߔ̪DcJ!)9#R }^@>չ#M05'W`-Lz]_RiӒ}-[\im?j'*x):>N;#䈑x12yw-2 u{XZzTjpC0O. !\#؁aNXdsßD j՛սO2xk;b25:grH-`S>m`HJpVm$G3eۃޞ1/b~ Jn2'Clb*xAצMaUw/'fb1,8ۛ6/ lYVz5BErhzER"BlI|IR zqE]S (\ɐ55"!.ׇ4'#91 0'jUrȼѰ]u >gEa#DQu::& !U3`"?d@Q )f#{ILVN&iÁ"r8Ց\vƽcW~!nHǦRǚݘ%޺`jGt1!k֡dgW1P|]=SiO`ZrBan f½_ݸytz~؝222xJSܤǂw'dӈuLZq$6S(cLqrI_>"!/ Q3˶@ }IRO!H iz\UF17лw8XsQ/9WJFFB4-+CsNL_UqR|j{Ԝ~3Q-QЎRxTrc%(nt5[rx(a qD@&mtFry Ao-!irĿJTu@9btv (HJ҈1cTnmn0j/Re=Ԑ7wYڢ7A%!Gwc-I v"v ms3'4S#ӎ۽Fb3Km'jؕs&(Z+b>%F?t]@(BpO-Qe%"K#O]UN&!V.݉wY4$>4^߀s[{XK^< &=BV=ruF22uoQ/!_q3L{Cpc"¯QmR(ۃhnʷdp&@s3F9cLiGnp C 8A8=JFrbK/;"܎AۍL)E哘>r[\M Ik"_O4VNLo6j&\F<.sƊG }Gh [%7Q5nDp_ObH9뎈*0cafxm8lA׹FpG y_bڷ 6+l`Ưެ IjnRfnBnpڣzxdܲ^2܈3fFa1. ۙ1xԱ gpfoW|JWJPBcr(\ݏ5`-!s0@[p zy$I _Wռv`c*1_O\d%- cCt W4H$Cj2z'5q=Q/QxK?98ļI-/e8W߃-GfPCѪnS~Őyw AbQQK M2.Jd;3ܑ`" ?rN=Ƃ}DR~$ c/K-#pSf;spɧ$mۺ҅ 8+X@A" Rf%ݼcIr'܏W0₟ܐ*tr}>$ޤ7 l]o^rYaT6cvQol1Mu|XiTw VR#NyWBr}2TM9h@$)v{dq cpp[/!:[Gu-c?+qJ`{*ΊUWrhѼK 6vɋ',Ԍ 74#W%#_Ƌtʼn /,=v fjF# 8Tck~(⩆ (B5(aa]_L#A{(mk}6d;Ӗ::jGV $n 2d@$$ϧj_//SBZ=vd v/"R$֯0mP|M6wcs| ˖kkr9@TDfm8YndJr'+p;]u殞@xm\)W¦TR۲rn %'$d`cP|WHvXc# ?.* Jy%Ӊq?vl7BH77[RWв)M5"vb웫>DCpnPY%S>UQ qoc)e BCG5eܭ2gcP[ѹ gςf:#-2Z"GkM\x .C~z y~4bk`{,#[;w7_=Jdya2GVk;2-WR"dF&gU%F6\[4FJc'NJ S^QvT8ʩU/1ՠx}vc޶aCn&lZ*W4r-FpNx! * 0EGGkP2n>[pC"ő6 ٦ی#!?} P^ rsSlˎܓGk"I dZ-B[5d.f[t6b#@$MpJ{]rfaPwG7r(j0,Mdt Wq%mm@ ŅujȳήŇ(msbcUGoo\)f< 8-XW+n5nxzP>-neUHb?Rgw'UrF;!|ډ`#&'/S˘:c< e@n Q9KޭEv8v! "D8dܜx#|!bFD`w@F)}FG3Cא]$gm[XTG$8|TAr 꼓bN-O^iॷe/r\(?O[TRϒn\ a_b}̱obك0t/ƒfzӾ&D勡rm +j,H;q`/{T~ v">CZLwnvD6 b=_½0}tV eX9.z{uBa]旸p8+<>ĕi8Vk31ˊgsuc@R؋cpgŪcRbڕVH!Vfc#.)GWxʴ[EE?Tt!"A2Ⱦ h, nH"4?e7`)أsfX2l_pT:2ԔKn^GT7.0/^|Cbd7%ԝ>oO*@ U3Òg)ⅽ bFoފg7ɵ!O8\V.#@B&LBH /[?w=D>J"D!2Cdޥq!|6`rV#bCDè:@DN/L2^>c07nH`m]~8Q㪼6#Wfc!)rZ,IX*Ή|KCTkN ) \na4^RWL4UۄsM0ɰ"jHH?j@e,>J:q{pS2dݪ5Xa_?Q8hX_}~ʬ>;.p #t7".Q1`#u UK\Y c,Cɑgqcڣ%O]F8qz[&z*L) 脵a&ʨCSC6&,y1hP"9S(/rꍽ#qQ1?>x(ubfc Elq@F0{h4t K0#]ᕜb*20{Uv|G% =Ry|sQeWF0Ub =3k>#0ޘ-A_B8 O{!i)JHj-F?8p14'("5) Hv섲Oz[Hwzۙ7B2|8)8yS`VmÊNܨ)tE38`>*SvnT aspzD c(E~AF$0+l3 ɓ 1`Al)QDڔINFªEK}S9) HkK >OܻnR?)lAz' c(F\](SOj+YUN2lȫ;RqF{XF@ܗ:=㒗Id\3xH3< F-??>˗.\r.W.\r?˗.\r˗~s㟡s?/w`??W?W??8?q\'s8~?CqO8YCyy8WWO?2d&Lq&L2dɓ&LG#&L?]}+YoY+r/c6eWyYo.]W+r;?2I&Lrq L?Cn\r/̙2YO?gDO?_2gq_~/m&O؟?̮mA#*GpV9yHÅaM\*(zp-z9:oZ ʋDt~D 1+m~%oR(TPsbj1%D fYnO6ztZɃMmR/ mH^̰(yOWIpf]_ruֲC _W$:.X(֑87^0u3D=]9nPI颗J~׃hh kphFx@6YcEӕ7Fos)J׾2pZu Z+79#zWq 5@cv6f'(k LN|tTuixl3^T7 2 >|AGwq2 K[8AF)|ωÀ4LӨr2=lsJrQL ügyl7Qq/N+?U 5ƲPC2h([}8K  jeeK q@Mz&Ѿsd|4cSYBjrRd;Mcc30*|o7̰DV"Ѷ;ߌH;z83r+:o)ʚ,0PhppE$^҂ 9;0ѲP{&/|>*e`Q~KD~n|r'. *?nKXZ(/70wbr D&Ȭ#dX_# hOxUD lS]b7,$u3gHos1K`ix"/%qkQ PtwsElP%s|>2Sf#R;:ޮ4Dr|r`݃MO(-?֨kCvCZ8N]znbǦ^;\.\q_ ŇmKWCL v>7U68?7X#:͢?csX䦻o EtkH''''2o rOnxɸZ4ֶbЄ)9P~cm8g0Y& (2gXŜG+߬9s+@_,Crv3}?8 VDd,Qtp .Y%5yhbAQlbB\^6|.LMbb^7B[AD*ViFv\"r,52ELESV߻9)_D%u )sxQ ه)IVp!uU0(Y׍~L0%=KVkRSZ 49Xq@MP&P8ڨNN1jJ1ȆeVуyp68 ׮qC\wx9x{ӽս$U$C-}'Y~hPkЋBIgF uvB>",ruW|`*Ump =]8fcV57Qуvyc2]oUTo%WѼegp@~ &0wԱ2ƹ =YgTZDYg ! ɜ)G\5\;ͮplCčq\ K'ˋDP>A.@@DzއyQ!w#Dٚ zi4v+R%ɊXξq"^[燳d4g1B@i)w1\0tA{ r)yn,]?Ed<\z@ 9%6iX1]QǃAӃ>'TƖe"l`_7XGclO٣996Fe ٜ<~̵{&738XoQBB @&BYA{yxRWu╶_oJ&@7,~7rs0h~U`- U{7 /j+`:zG0F0' @chjBFĩZK]bQ^q|R)dcM(5C徹2aDQ*" ywNN$>)@Yq44H&?`U #C' !0y*]Ѭ 'j@W hL )  6+ӷ,!7~<`| 7RXLFSP-ȉ[`w9|f`u[qS4Tt!qK(VM㓪1u^jňJLu"۽_YXݩf}Mo*gр'L ¨^u:0@z1:D5ߌP,T:͍\Iqr[N13΂S~/`kf@غM.P6h"! Sx}੃ZGgY.)S|th <8d iõLDh(6"6ӭ=~![ Nb67sMXo[xp#ѿ5n*1<~^Ā Ni^sj-_P ӊ5o)5'zpDwH 3J 5Tvɼxa 4[Xù&\+pD8\4X8j J G#u O5T> ~j;Ps;YU%! tfqD:Ni1dKꢀ@rxӂ!e9[ʗXjK-] "*86 E;:rĄ14@Lg/9 2:u9w b&@ mW٢N*rIX!iP.sAJM䒧ofΗu ᢏjqhT!Bw @T0%; L59a:}cVoFpA#CS3,(ɡ0Jg]؇8^N1hGoaM&DG,nLqfrN%Tx%("VhjW(JąL38R05du>4sH"S NO*v*G/8J`B2"('j|/\Fo|๹6V& &? cp*dP(@YަKbyrscL@h)ˌ+oM%HƍDc|~s(cۉYzUˣ_ "d!`n3 Q)Uho)8) "`^t?'jـD(& ʧ~>dJ2g). ȁ9$L0IFL 8rZ и9TN $?{KZ}1@yX >/6yhӱ d54<@g(;́1 UN<'zͥ%TcnldbJaݹcarS5;M8a:>1 ;Ȓu΂|]#Mn¹/V5G(0BhO8Ԙۭ MZy$Q:6~8BWS9rCFE@Ch\3#3\xCgIFMAe}<Xh,}qsn1Eya*E:_nn6Qw4Eyy@jnj2PS);A=AUo;}8&v:9C`uO?Oҥ]~0U!$|E~0ϼ9(IoS|b 9ߟX+f3qNx+G'ް&fUe]@ƒE_„eaREN$D%jqFCfp u~p ~uQq(8a+JS ~L3 +$@~؝R=TaW.!_i3)ʾP;Q3DG>ElvP=펴RlƏU#n^7=~bSw4MqBINNnPY5Zkp7X0#UD\DiGḥ+f#I[Ac>p|0GPA^X˧E^B ]ފ\Ixe]k 5PM%ž+ؖ~& (p#6ou\Y8IdmQxD3LQ]t0 A`n#Q) r;g1t QO?Bi-xඡ6q@ܟx3Xc@u3@)Aѫw~ߦT>9M8.'q(UQD2 <ɽa/5nxml2iL@vOnj2  @5:x^rUVpP7J@@h{㔅VɧsVнQJHЫ! CF ӔPZCǫqaZ4ҧA4NpHGS( H\PEd2`5}GY񒨃9VȋˆP|^X8yqΖrū MVqo 9xh&H7'몜&{H'qGw}`BT{uE[}`BлbբfHyx1^S?-~`\ [D 'v^uT{ sĕ۝7KMaI8K5wAP.bӚ玱e yqqK˯%fD1;WFe}RDG8A^ii 9 1ZgNQҀ~2#_8krB?l3RhH;kXEW9qI|ct)J*!gxFRtBks( (/oU{'Hw 6;i7S|F" xy$)Rȸۊ=y8͙ vؤ$&|&/(VͱMsV"n@5tC۰?>iȕ(TeاV`"$#qq08",0N1`FQ#`Tǝpfj~jC M ~| |  vE%cF}Gca,^_Ue*?yuXX5^P<~\a4vt \+*C8 )ҔU L ܺ%=3t~7 D{7;meFN4Mp4lr8 f@'.ToXv1YTkl 8M8 FG-OFxj|êAP1gl%YKZvq4`$4zV`A+ʴnj@8jW 0"k@Ɂ GTT]b:=#tpɫGI\'uZ٣@Z0v=Ť b?90 =>C['J>PWYG@Cš]4}9cf 4:syqtjdOҹUC2z3 t+vG (:'1*Xo6Wh:P"b4]_#+ $'],-<4e@ۭx]0rH7kȲ4g8^4CHjW8XxGAЖB0=o9f+نH]DT$czH4c?8-3([AFez/WyeZs 9.ólBRU-/2bʵ[T;Ƶ_ Rԧc\JBՋEym(VA$׌uuDRX`m7GR5Xh,ɨ#9-fw<‰!5﹬YK$CB/));ͳ6oJ}bJ]  N^Φ]ndFGRw4Wp({šFߟx D*r xqSb/Ap)J8@ApDD |.PQa:/ /{ v1ŹXIfRbMs/Ylhyf]W _)PTAe46  GkpI@(:r/8ӗJɒY fҒbk*yrvGF^Nvp6/wi>q,b(Z(:AG#$%Z iԙ:'A1ۙ"raזb( 9|ߘ8Ù7}JٺO)4j$ 2AAodo^oڄAT lm*Wp y{aؠt5wU&/n@Yujw~VkTB45S8 {>XPfcq5(^=メv=cӘ]b#ϙoO>C6Pս8n<X}# :PULUD/wʤ!k⺹Dpu77{W4d$9in=lxnX= ) ~PK ~W-I95 7])u Ԁk g.G2 S+\\s+U⋲tx{ -ӄ\W (4g @(1ZĺX/NiMpl?ɻB|F/ɂ@U[_ΜQ6!PJ W:eI~Y*댇$4#u8,@ ҼbC :eEsf kf&h}j)V*osȸBu4;[gyT9?_'s% tHMZ KJt'T|=j[р͉\@B`K%H\mW-&9'sA U9LϞ K{ "h#5IIӒi M+rDhS4xL V8.3?+ʅ 722P(Uw Z5^fe6@_Y-m7ڗI$uן\ 6fHSPpc) Ӓ@ èF@*No'0!3A]N2<5r +^09q]բ*Po 1rql(Tzm1Km_J(=iA A7 T- bdoy%b!GR aM.a@"^Ac7iX9(C#BfTJ.PBAp{ۙգ\8FUqS4F$]1Lo Vcq;Vμ5B4icB+GΦ;Oe+c/K-D;X x =!X{\-§qj排oHנȅ2BIA(.F=":VʝcIL8}xBpI]Q8NϬDCfƐވAyM7n2j w$7CFvJaBZp;ʖ Ƌ(:"<\imQN%JkI`mt:u/1CWCM8>IQzIo%2F`.f(y no Lj:&TRB\w 0^6x|k|w`çxzi\p'D4!D?Ȏ1{1M8J@BЫv_I]CE0.~nRSuF>Eea/;9X"@T? P)bO)_@GY.]$G]g풀i쎼E$ja@aN܌E"=MA!=vt)B¯VfZg" wf ˠB0 єn^?>LD  Gl!!B`oib#8\BI_w%]) a#zR>48`y |0ɀYH|@uM yOxOeqV$Wۏ<ٿ0_|aua 8Qx'bCvY|+;vXJvD`wKC)xP^8RbI5>I9D(vj2^qjůI۶Ϟ+`h>_-n8L(I8w(YnAJ(^1TH?v! 3 4AWP5gCGGF-䮴a-ؽ/*avl^08N(qܪX2e ,VBs=Df2)@x4cZ; X8F5 _ݬ Ea44ӧXCt'(^=# % HY2nX*`\0G\݄Ҫ&7W{0Yi {蚮e Q+RGECx iy EU.>E6PGb(>]⩀V*B{_LyQ%(|D 崨F? mɼ-ٍu3nj !'~_'Gru|@Evu"Tz^Pu33N~ eA*7y<_&So"q^Sk/.9)WDBԼVlγey+q2q*|O ӎ,6Trq׌wbh !|EiA #&p@$]O^TmkJXaS2 )7` *{j`7BKT{ƽ:OMZY%Ƞ~3H H%/ԷNmzӬaxy]rRwpMc[W;;~1r _Hk~pN>1Ƌu/;(v1U<iAEAN;ǀvQW(:Zy8H7)-9Q)^! 4n M2::VT Mx£]ҡEJ**;U(Vp"zE0SrE.ShLm}I)\H9uA\ɯӃm?NOblvE pQwETNрU5rZjC7M0x5z3DG7{0(NWt6'G.ջΦ ԇ^NB9'7u,W^W4`h󋀨tnۋ ݚUxCuXaZAdŮZmfbD(+Re@uG#KH4jO&=>haq+{dLJ.U ["!_8'Nys d;Pj |}aX&QwqVt@d7l;q6WD? pMv Hko~/ü:z ,ƥ J?-ε2qLd֞jy¥͐g-XҺvqOg2:4kʿxo>5C|l\!9sT56Or׼^/5"sǤT o$fP|u06r9zCr_x`^?8q]+QH\?m/>N@0̈́y@rox-S PsMV!, 9RxRUNamsV}D^M%8FֺGKER}cH( V>.Z` /T`"D|HH.˙JJ#QyɄ4a[ mՄUV{p/ <)B)yڂE æBlQA(l9;p"*bDsky *;zq TUݜ/Kn\)ҴYAHxky!5NN*{ *А ]+Z8hˀxh5шf6}oMRݙTEm!cE0 DFİpLod +حW)ZtE+'vl@z5jV`B0Kd@t![4b McPlh4 y&R@V[Ά@N)@ߋ}:.89ixUcT$]Q]&p1^~qΉm&h VF_q?ݿxcP [~\pQ;(ۏ`"y {KhR" æ 㛃g]Qaf'O X_D?lB1sB ol_.=Rz{0΅*;GEQS 'Pylons-1.0.1/pylons/docs/en/_oldstatic/pylon4.jpg0000664000076500000240000006435511645401275021642 0ustar benstaff00000000000000JFIFddDucky!Adobed %4h   #%'%#//33//@@@@@@@@@@@@@@@&&0##0+.'''.+550055@@?@@@@@@@@@@@@"!1 "0@A#P2$%`B5!1AQ"aq2B0R# b@r3`CSs$ hC@%" DX b6h@h*J  iB114 LLQtXeLM Q(JȢr@XJQD@ @ 0Q`@LD Ӧ&J.FY Іh``L# ؘM +I:tDTV D& BC"ʦkdQkez 1 0p @L LR>5gtKHިZؒ @U +] 4` MM@Dtbc'G%v./-DeM$u؃lz7N04F2D,[S*[R%$~-FrC&$TDd0(u1ECw; L 8ʇSDc( ˣUPY^8mW:#l,DA\KFq 4X^lYG_;LLeLM Eh7J5hݏ^B9/Qb-sFB9tvÃ_G}pG%Yg32ǟg8SZuLn.tГDF#$cWY&Fs*SU= t\m;]MѸ,)1!Ҵu^Kd#)"A +oד\ 0'FPRdΈmvNuVQTJtL\ާ(3tnʱ$,R2>Jdg&Bm( )z04*vyU#©ѨہĜ3SNR=>|ɋt.ESJI]g+VVJm^l߇t 0'BFQ(˫ԫ3X9im*[QN)BP+ݝNnv9 +suH5ntapMpH8I^5t0n=W̑+  y{I~goλq\\,F3L' Wd v&S8N 8DlO=:eЍ'C,4ûT,AIY^Q3L^_RL']04 yF}!fΙ|Dď+g3- C-$v)}eF*e CiҜeRA]t2E:)~5:q9T'z}>mj/xs,7YJP`ç5fM5aӛ#unl:~I w''è'eit_}v`M +$l` JzFRt3)S.ݓq!auPt9UD! ʎfbP-xBfͷY mVרVwZ!Fn2w+UYd`ˊMf5TcAU_O UnrzKEkG/ͳ,,3D:ܞq8ע~p۷AqYUR-rzGVy. Wd8œLtWr&96(;fW.^%2ؓ=%|/@klQT "իLz҉Σ5E%i2')[ Yy}|ö0qUgqrc5Y]U,] djk9#Y`]nԐ{CЩ4&9mFNQsU]@jYaaK,c2Ԩ_Už x:yfyL39٢5ĽFcamzN޼ƘSu&.__݈цL7^[M&i䉻 ^:Yȕ@KFkKݦWTsn5(hۈQaKY~m56Ъ9ǜ^9?@d旦1/Jd'+KӇёg^5yG<ߑ矢>5^<= yz*Ф9FTГ")sOtLZKsl7^Q!3m0ȅv19t\*n1GHn)1%SB%" L L+, *- 0m hTZ+਴)v*)+aAʌ`9s9@?~x?|<Ը38383g3839<9s9s?9sv;gl흳9s9s^==s=s=s=s9Ǟs9'9ONrs'99sl9=3gxqoǾǃʪn(sȡ?y=) |^2׏>,y@8pS| ϟCJT`@^|?8cަR{am'%t C'_=W$/?OVM`n,f˵,kI2آOn Pǁ:_Ufe(7/e>i?qFj"9=<-?T<PѩDbwU>`g7B +77fUCF{^R&'V0UU܃-ç-1I fEYo\;5'6[-@#CM\([ N./8|m,M[Q\4ƢK@1,8 =Sv E= ꫎@u$CMқa-ʊR (:LAP$}I__o:\R{O8RLR#R+!mi+I>z sgc\ B\,Ǩ>}G7UnM >@XZ}R,c&3Q`]BICEzWA!_f0)܈c7k \/7e!}Jmv!N3GgHZ!6dD:𪧨PrkOY|× 4,;8=,]{UԳL}# Q >{hЭ6ꒂ;?|WM.Zӄ .OaΙ'+BoS㛀l]!&a봪c>)B^%@ZˮX]%\Gzꬪ߃ۍ^ItS#Kr.e7KϦn6Aۺβm~˴<[܃vn/]+BK(e@5خr}{3^U?m{x>vOGa)eYk6я;ٺ;9}qUioYK5Ui&dVGY8J֒SPsxbsJ$˝ZXYPm|k܋3ACfs+'jYF|H>M-ۆ ߒ18Zm:g)ZŹ@ ;r~Fd͝nkq>>TlkP͝/-kmo;v|m63P?^]nR?- p^f9tP-.V?32gG3tsJOU&gnCUyv!`S23B~FfOT{]1z>*B X N؃em`;&Tx>ڣuۦ+~ Ru)ZMD`.Z36NZN` URCYRJ8{}4&l(ӰWpl#[2?ȩ U6|7[WmS^~4P`{6'K@ъx*# o8~Bo?IRp)?f?u~r V%DlݲnDmr>Oip[6ց/gvɇi L啕ctvY7V{gkWvߩ9sUv8HOW;Ju=A$𽺔6\Xj|<E6}}fcMP"jz9o:j.VBέLԶU*899m*(oQQP=88@*kZUK&[v!mۭ-+*])YQHa(}y?OlTn16F{ĨG 3 ND=om˱UtEn옹Z5 a}GJ7 lVuĂ!ӡ`zre"KhL`gcn۪uxp{x>)@5 ?bΣi~WWJIY}e%Em-j6]wI+ت!v[+ .⌔m8E6n+"QTxO [d/՞6bY9Ã_m\'#qYhHfZپ"1<Վ{IFQO >ZHi\kYw*O+'UR c*I3jP"ʞx`a^PrXC 0'~: Ã_mw4cO^ʺ· PpT(B8s韫Yu?w!9+t:S sܽ]`vP gkF2wg4*ePj[+=f8p{x>+Rp8Kj~2UKmuuit;(`0Wf״)MB6bk4+O a(qvLu&EՆyOfS⓴|0]=V2z}5[[)ّ $< $r~3?$sѾzWg sXZ Y> t LPUªPw  yJ">K{tc i s=Io]_|lRo1ãxOa `3ik;2::pJevmIEm[^jM+[T7\W!J)5{(C8/7;'7Tіp Ѧ4uH Mgg3<`ItٛJiCaת: 9(ih"u$/lY}x\FI ٶ7o$+RLK6 Gn^s̒ݕJ܅' vRo[I@dǞhM3R$P=똳lnqޭq!Ѷ J{qVWHˋJӛno)خ#SnuSQ*)(#jk{s收Խ֍[1M,-Y/?E:B)9|PYΎU蘪_|vO]6R[jJe^krVO GgUv[ gV쐩c7 BuRNT9 :=䶤vTZkky.1$|PmYAVW[依SX'/pxV`q25_eTDlSL"TM@57Ms/d/PkTH{Vw jV6jJ[g ':he^j: !Hh-{9{rZqgmbO o7f ^B]j1$8(.IU-TT65gGBXOD 7tUހ3?bL]% 3dJv1Zt~Zkδo/,"[:jLsnnȶ~X =c|S\Z]o] gLk=*vY):P:21Emޓ)QJl Z6MvxGW-}!YR1A=Z[6l:[Jp 8yO9Aq>@A:U|7{dڨ~gUVO )tp"igvf:V)c. ?b2Ymj:Qes@ 5B:Ul^R׺kT$j؅l?]7E킧WXjZcM#Ãm UɥmPvw<aAz=D%lް CIQlOJ>xU]rU0GIrPbYʣeݠ)o"=0s_vT}H u?g5ֆv(I9]M'Km|OGtߧQKjׁNZ?R5*TƄ {`h=IYa#AVةmy>T2u[>RTqVhm::>a-0jrzlڷɦuv3Z P!YAp{x>8s~^xpu\3gU3Ίp?[[?0JC qF|2φXu~~'>=HZ'bs嗎geNPy=Czx8}3gjfO=s/tא {x>HieUJģ+դcg:kNB_hf dYjȃ4etkIo!C?eoز[Q4cDڢC].Q[EҷY@لÉg3ÌǮqsE+P :&u\"SOUTuR~4 (PQRώy ^?^,q8p3 3Σ:3ΫW:u\sUΫW:t\gUΫW:t\sE΋:.t\sUΣ8p3?g??g??^YEɠPH:j$<)iWq緑v-CDȫQD_IAD^b ƧRìžRT7+6L 7/c}kD0PoO(S6)` h@t&O]**wNQZQ jM@$IX>‰kj"AJ|񾆧`:-ᷝIi뷕\OTŎ5Xkm-Pj5X&XϴԴ{:,Vc 7"%4cZEu.}0 В А"0/ =* W5/᧝sh%H1Ң/A;/~ZSE@=h*XVc&5IiWA0Ll$^We"n5&0־.GPv~#ʊ{ڠiv=#9 {(1e6折OqLX*xh5>625Bg:b_Zּ?ev3goF_VUVFyd>ٰ9xۘV" ?*呭%1)fP;i/ A6C9mT4`FL-i7P.gz'HڄEqӨ5$zPAzԍH-& kRFF#Km1R4ePk&h:,@;zNrf-#> M ```1T^_ ǎ 1@62 qC!$oi'3ӬXx,IJiY7^ ]&~Daªx C֔A|ɣmP9"W_ G5ܶjt&g1Nݼb="Xjq!Ŕ -hHFbuΔİ,M}IS?1XX#'MV|f6QoG1el϶`@<}^N0PHϕ:& :~%A8J D|\i4נAޫ2b k^Ā5)fU^K4L{/X)C[O0HaȚeϼ ʃ4<@ WӬ4~5|,b FKiRr 3u²'qe?(Sr8> vfOEH`GZIe5񀁱/uhaoo_lcd e΃RfT%Bh?P/{ץRT')r*_PG t P7*gƫ@A޲-4UdXNLH?Ɓn)yYu|xl(G'[LUq[UՑ dg:O >0~,\++* f=)}W9Q:޹*Vn@n@] & _ƞMȴ^*C0vsWȦ3%kҜy򀼋#E}6*"߅8ɛ™W5%;H ˌ8 5pIoJbL6Q)rMfu" 3_JXP$WO&Ax' 6:5X#6t;[C:^{%X죑 IoY%coaHmED !m-XU;qEQ<B~ @OkSajzPOsI2=Ԅhr}(@< $N-eY h*I7Z{MG+4BJG>+!Iϩ 9xR ՈKmY˅$|x3rRX(FR`x}hܞwU3=mL V t*2"fQnj t=U[/$P6P7±"|wOpe ;V'ƶ[yޖ@7s=:+62i ua c°a:RNB%:ٿBNݲFт(ff/!޹y?Y$$u$60cNVǑ??w=5` 1#75[)`fBb56K[Ē1&%.ԁ;RɈq*I 9LM.Ve ,Q;u}mc~$>{E^R*XLӋ=c,D91ҙ'Bv40cZAWjIA#…Er&S`: R&"1h}*WCRYab'XR,mf_ҏDeD09< I8hƂ?|QFSӬRjt"̻3Y8˔{#c-6b ]ů=mY_(Cs*X:N;qO"}P4Zx~R-i~( jA5H11X.RYyWei(d86ڞ$Ln{*o`mFkWzyЍENZP 묊+y|G 5s?SgUv HK x 1h,!|yzwu/E"g,G#*OukPH&o?zGXC/kظ1T}E[QֲQ,Xk֜. ]`B`ʱ!%!x>Lkx>\rSDLnKR#98|FIzIj;AJ;?QLyWċRNFҖ,gNh. [+v nLnipzYn+BI[8&9 CveXY Qn=T$oX [Z kSDIھ{ƳjUTzʱ\\LC$[W+琢.'NkTqrA"qj]Kjxlu(1TyN)VQj叵e zm\AU ; )Ëbp[05?zév5y7@$ b$,ش1ErI'Jȫru5< "iO0biTq,Hb2L҉X/emDiA@d: /D-2<1cfUE U +c`(4SX h =uiޟ؁ h}lEC1K7e`)(Nx G\<hcÈ.p rbjBHxW *;N5fR#//)T0a[KYS}ՈaL'M~1<@t&MԚA.5ird5̡Y|@Io1LǸL48(3RP{^CKR Įаz~ &Y3r &r@DB,d3﬙ 1E^r@(@x $ b*b@W9O~[OȪ!ĞlGUy)̈́%d/FV N)a5җ96ʔ E:2J[mƁ޾@SS? 4Ұ pR:Ebd9~aOh$qVcD N_íb-,T7/ +3UV#"Y=-z% |H1RuR+-~BOX+ƛn"7Wf$S Uxӵ!slG-)<~ϒ;t>e3}XԨ/0[,K,.U 642 Z"c ExlҬJb'ʐC!. P,du3v+ ;$x\QfGnu 9/+ VNRMFQnw"lbF-$M A;)z@>MLEKkY\E<#-BCq3— }TxڰSr.A)P|%PAk{fi%Ay&{$NK!,+hF 7o[,~Ώ0_E+FۡIŀN&\.l|kSU凸1>t%U$U r%m-I9DB&+6.Y"09 {S<ܲdS {h#d#՘]k4ԛV @`n&Ew @"_+K~j%6 Ic,qT'0&:]>2xҊjM2At{ eĆFOljNDqP Jegd5tca8.#O@I|39me6%Kw {7$Cƙ?)NVYˆo3ײYָ3 u(E@=boȱPc/``,4Tc4W">ƽ=^Ks$ě(JJw oj\9y6M9bF[~8T:H,asM".Rub< &]dE"#r54zd8Bfa' ڠic$w8P-)le \ÒS4XX{c3JiDwJ##3$j@.UON r 'E]Ei;ǐ˅(0ӭ>%qP c= Y!OƧCBd`EMh2H3: +bdRF0W1'KrD`~Lw4]SVFЊ C1R~ l "$dU4bb_ϭ\ŗAn$* %CH[7_O`A$"(\&_eL Y,uoJ(W`z[QbIo#޿ p6 RnToAVdP rXR{CxP=>f:DQJ:kcJ#DLaq4i0v_C&F~,j;(b{.Њ`HN'O~':lyrrO;@U =d'`hΛW xP{Uf .N kOd)`RI J$4 ±%x-qىam$Gq6{؞m;4Q{RYuڳmN&؞Z X>ט Id3P L8') 1>Xq hMUuJʝ$r0mz¥t:%j^4Hm: ߭VN`+@F8Q;%#' 9<0 PUȷ,pKL2<+2ktž"E t_刁qЃn}Eb7 7l&+M(EvbS&+n"n@ޕL6PT"g z rҬoO&hʸBOēu~s<;j\MB,Eߝ?Vo.vY#XńVh"I@7_\Afy &d-@M*S,X˒I޶>,`ŀ+<466*iždH4 !wD{ywb:XUCoʨA=NUU9B}2t-s;F+9|)IՏei2|#TNޔC̊ )vL=ġPԪ+XoM$F xP3 Z 1?\rvK(#Yt ]Yx2z'x1$OQD3}9NI3e&'@@r$\M3fP|jNJ \PKi*+WI׍C-&4M'ycO`~Xx׷k4ʁR L|\@~bGt q c&Ayub7crxkJp~b:QPH;Xk:Dl:Uo*:ҭ B+ ('C!r❈ +{yJx If4-eQ$Vmpa.vukąic0'oV2ro:/i Ղ{YO[4 XA+ x\^ b󡕠D؟J O7E|ܖgXN98\z8.TATޖ`H \`cƲ*,<$P#˶3kn 1Q|G\IBlŦ/ğ >AlE;VLn@ŘW>tV`x7΂#1H=W X)a3 XAfMr$"S3j.GEz1Qj=$Nk}=^MzY'!ک͕b8(Н'j8 z.OwaǍr$DLC" QO/K,s:ҙ 7Z~K<\rM#}hfcSKV 7M4EcU2M^@~DOl-#48<Z *bp._S7z,Xzft.)gvlg?prEd1 0$֓(beK ѥC"XےcN%i$$q3S\gfXͣ(>4bڽ\ ˉ7@~_P}l`3 fLyaWJepo_@i* z),=5œa0`B ӜͲ^K C'>(n%ry2ZoD64 6uup+b? 2W*UQD# z?ӱv ,ŁFm'ε^ KɆf:|X#jĹRsq>(S'ˡ@ &7:ע񖟘4YG:G62AtJqK'CR2&81q[%Hb8si#+-򪍔i4TpׂcPȇ^0㜬3j6&qKb%G iSԎzeD"9iW3d;w|s%u=-J=> vȽh.GTƷɐ:\>>{"$|+$H{PXQ1VE8>Bȝmҹx !;uh1ά-#˭ W7ݐAdz A.'PiyA bENI:4ct&O Ft0LGJ2v6\`3đ(f`wYDnz4Ŋ7`4`Ҕ!Y*7H&"5ޜ o-x?PgWfeN֝hB2'™9A+7VjraA/cra׏ZrX :`GQLW\N;cvGr Cǯ1 ]M誎hADKco7?, )_ h 5D$@hM+ ۡiȰ~tLm6kʦѯYUDGK3J2Bq qnk&=dLXLe[@35#¸/iE">l|x4hu<m>z\1)qHyT aQ  bEWK~tw`v F8L:a m4Vg ]ؙuȱI?؛ = v Fx,IIeUsAG@cI 7*e=&<(&#I")>/מ8U@.~+P$&IG L8XMZD~Sbt`Htm\r szM?2éڊLo (N6aMj%")ҹ@h $ !!ܷ-rOAUÉ׶E@D&rMuϑx%H{6$Im]U0GFHK]x|{nO$4Ɂ$AC7UF>Dzh^jU2M[t+S%I0U0PcYTEZx8͢p SƝ 6)" MePmS#HC;VNp`OO*ejw&˔v4yrA$rN\*|YJd*$ޱ /1Jݽ@nKx@`b& |gJDϜ6*cC^ % ]â8mx,|(gQn^'h;I(؏ꞞT2 Q̣Ó%$sQG8}29Jͦ \,a(&wŏbd4ɁJYfqH+Y`7.UPI6IL Kd`bHƁ dAYD[b`^ Y߄UŸC۠:S)J& uk1a?J ZP>&  Fİ*%nC,ޤ\aua"F@$ݸ;ZgQ};+#Awn""$'Y9Xv3"!!j0%ՕJǵHLfԹu}Ih %&wEYU6RqmH;1ʙG< OjLlD$M&oZ$r{`_MBJbb h ݀&͏vs"Ehа|3}L=2),|jdĎٲ@T{Q鸓Tmr ) _1, j`T3/z1}DgҴh=p=p{X V*N5>j+$hF`*=$E@E@WPؔ?EOӴUE| Wħ+ha_haOGTq<+갏` I„dS:w Ʒ1 gƾ_o6t2 i:,:kQ?AC:11{P0ox?9H(ĝC"V.IhhDo۾7e "WK[JBrĎ&3!l~a)NJ*c>"$OWÍv,d%`_U $)>U2rsrE~_̇IU-4ؠ ˖HӖ#xǑa?P90oY~Cx8$y:XW-WPWZ T2$O_[ GPxT@*tGbĪP,*`O]8:EZ16ҏb[ F(5.>*#X'ZgE w A$uѥiZViZViZVi4+JҴ+JҴ+JҴ+JҴPylons-1.0.1/pylons/docs/en/_oldstatic/pylons_as_onion.ai0000664000076500000240000064046011645401275023434 0ustar benstaff00000000000000%PDF-1.5 % 1 0 obj <>/OCGs[15 0 R 24 0 R 28 0 R 32 0 R 36 0 R 40 0 R 44 0 R 48 0 R 52 0 R 56 0 R 60 0 R 64 0 R 68 0 R 126 0 R 152 0 R 161 0 R 165 0 R 169 0 R 173 0 R 177 0 R 181 0 R 185 0 R 189 0 R 193 0 R 197 0 R 201 0 R 205 0 R 263 0 R 289 0 R 298 0 R 302 0 R 306 0 R 310 0 R 314 0 R 318 0 R 322 0 R 326 0 R 330 0 R 334 0 R 338 0 R 342 0 R 400 0 R 425 0 R 429 0 R 433 0 R 437 0 R 441 0 R 445 0 R 449 0 R 453 0 R 457 0 R 461 0 R 465 0 R 469 0 R 580 0 R 611 0 R 615 0 R 619 0 R 623 0 R 627 0 R 631 0 R 635 0 R 639 0 R 643 0 R 647 0 R 651 0 R 655 0 R 766 0 R]>>/Type/Catalog>> endobj 788 0 obj <>stream application/pdf Web Adobe Illustrator CS3 2008-06-01T12:30:09-07:00 2008-07-18T18:27:25-07:00 2008-07-18T18:27:25-07:00 256 180 JPEG /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAtAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F XYq7FXYq7FXYq7FWK+avzR8jeU7+Kw8wag9jdToJIFNtdSK6kkfC8UToTtuAajFUnf8A5yA/KVBV 9bZR4tZXw/XBiqKsfzv/ACmvZRFB5nslc0NJmaACtOpmVAOvfFUt1f8AMbzqlxNeeWNF0zzdoMZP GbStTElyqjassYjfevaLmcVQnl7/AJyH8pXl0bHX7a48u30bCO4+tDlbxOTQLLJRJYfnPFGPfFXq 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 uuid:D1901A446631DD11B693883DCB3DE232 uuid:8b042820-52bd-2b40-8c3d-932332e9814c uuid:CE901A446631DD11B693883DCB3DE232 uuid:CD901A446631DD11B693883DCB3DE232 Document Web 1 False False 14400.000000 14400.000000 Pixels MyriadPro-Regular Myriad Pro Regular Open Type Version 2.007;PS 002.000;Core 1.0.38;makeotf.lib1.7.9032 False MyriadPro-Regular.otf Cyan Magenta Yellow Black Default Swatch Group 0 White RGB PROCESS 255 255 255 Black RGB PROCESS 0 0 0 RGB Red RGB PROCESS 255 0 0 RGB Yellow RGB PROCESS 255 255 0 RGB Green RGB PROCESS 0 255 0 RGB Cyan RGB PROCESS 0 255 255 RGB Blue RGB PROCESS 0 0 255 RGB Magenta RGB PROCESS 255 0 255 R=193 G=39 B=45 RGB PROCESS 193 39 45 R=237 G=28 B=36 RGB PROCESS 237 28 36 R=241 G=90 B=36 RGB PROCESS 241 90 36 R=247 G=147 B=30 RGB PROCESS 247 147 30 R=251 G=176 B=59 RGB PROCESS 251 176 59 R=252 G=238 B=33 RGB PROCESS 252 238 33 R=217 G=224 B=33 RGB PROCESS 217 224 33 R=140 G=198 B=63 RGB PROCESS 140 198 63 R=57 G=181 B=74 RGB PROCESS 57 181 74 R=0 G=146 B=69 RGB PROCESS 0 146 69 R=0 G=104 B=55 RGB PROCESS 0 104 55 R=34 G=181 B=115 RGB PROCESS 34 181 115 R=0 G=169 B=157 RGB PROCESS 0 169 157 R=41 G=171 B=226 RGB PROCESS 41 171 226 R=0 G=113 B=188 RGB PROCESS 0 113 188 R=46 G=49 B=146 RGB PROCESS 46 49 146 R=27 G=20 B=100 RGB PROCESS 27 20 100 R=102 G=45 B=145 RGB PROCESS 102 45 145 R=147 G=39 B=143 RGB PROCESS 147 39 143 R=158 G=0 B=93 RGB PROCESS 158 0 93 R=212 G=20 B=90 RGB PROCESS 212 20 90 R=237 G=30 B=121 RGB PROCESS 237 30 121 R=199 G=178 B=153 RGB PROCESS 199 178 153 R=153 G=134 B=117 RGB PROCESS 153 134 117 R=115 G=99 B=87 RGB PROCESS 115 99 87 R=83 G=71 B=65 RGB PROCESS 83 71 65 R=198 G=156 B=109 RGB PROCESS 198 156 109 R=166 G=124 B=82 RGB PROCESS 166 124 82 R=140 G=98 B=57 RGB PROCESS 140 98 57 R=117 G=76 B=36 RGB PROCESS 117 76 36 R=96 G=56 B=19 RGB PROCESS 96 56 19 R=66 G=33 B=11 RGB PROCESS 66 33 11 R=236 G=28 B=36 RGB PROCESS 236 28 36 R=0 G=169 B=157 RGB PROCESS 0 169 157 R=102 G=45 B=145 RGB PROCESS 102 45 145 R=139 G=146 B=152 1 RGB PROCESS 139 146 152 K=100 GRAY PROCESS 255 K=90 GRAY PROCESS 229 K=80 GRAY PROCESS 204 K=70 GRAY PROCESS 178 K=60 GRAY PROCESS 153 K=50 GRAY PROCESS 127 K=40 GRAY PROCESS 101 K=30 GRAY PROCESS 76 K=20 GRAY PROCESS 50 K=10 GRAY PROCESS 25 K=5 GRAY PROCESS 12 endstream endobj 2 0 obj <> endobj 15 0 obj <> endobj 24 0 obj <> endobj 28 0 obj <> endobj 32 0 obj <> endobj 36 0 obj <> endobj 40 0 obj <> endobj 44 0 obj <> endobj 48 0 obj <> endobj 52 0 obj <> endobj 56 0 obj <> endobj 60 0 obj <> endobj 64 0 obj <> endobj 68 0 obj <> endobj 126 0 obj <> endobj 152 0 obj <> endobj 161 0 obj <> endobj 165 0 obj <> endobj 169 0 obj <> endobj 173 0 obj <> endobj 177 0 obj <> endobj 181 0 obj <> endobj 185 0 obj <> endobj 189 0 obj <> endobj 193 0 obj <> endobj 197 0 obj <> endobj 201 0 obj <> endobj 205 0 obj <> endobj 263 0 obj <> endobj 289 0 obj <> endobj 298 0 obj <> endobj 302 0 obj <> endobj 306 0 obj <> endobj 310 0 obj <> endobj 314 0 obj <> endobj 318 0 obj <> endobj 322 0 obj <> endobj 326 0 obj <> endobj 330 0 obj <> endobj 334 0 obj <> endobj 338 0 obj <> endobj 342 0 obj <> endobj 400 0 obj <> endobj 425 0 obj <> endobj 429 0 obj <> endobj 433 0 obj <> endobj 437 0 obj <> endobj 441 0 obj <> endobj 445 0 obj <> endobj 449 0 obj <> endobj 453 0 obj <> endobj 457 0 obj <> endobj 461 0 obj <> endobj 465 0 obj <> endobj 469 0 obj <> endobj 580 0 obj <> endobj 611 0 obj <> endobj 615 0 obj <> endobj 619 0 obj <> endobj 623 0 obj <> endobj 627 0 obj <> endobj 631 0 obj <> endobj 635 0 obj <> endobj 639 0 obj <> endobj 643 0 obj <> endobj 647 0 obj <> endobj 651 0 obj <> endobj 655 0 obj <> endobj 766 0 obj <> endobj 767 0 obj [/View/Design] endobj 768 0 obj <>>> endobj 656 0 obj [/View/Design] endobj 657 0 obj <>>> endobj 652 0 obj [/View/Design] endobj 653 0 obj <>>> endobj 648 0 obj [/View/Design] endobj 649 0 obj <>>> endobj 644 0 obj [/View/Design] endobj 645 0 obj <>>> endobj 640 0 obj [/View/Design] endobj 641 0 obj <>>> endobj 636 0 obj [/View/Design] endobj 637 0 obj <>>> endobj 632 0 obj [/View/Design] endobj 633 0 obj <>>> endobj 628 0 obj [/View/Design] endobj 629 0 obj <>>> endobj 624 0 obj [/View/Design] endobj 625 0 obj <>>> endobj 620 0 obj [/View/Design] endobj 621 0 obj <>>> endobj 616 0 obj [/View/Design] endobj 617 0 obj <>>> endobj 612 0 obj [/View/Design] endobj 613 0 obj <>>> endobj 581 0 obj [/View/Design] endobj 582 0 obj <>>> endobj 470 0 obj [/View/Design] endobj 471 0 obj <>>> endobj 466 0 obj [/View/Design] endobj 467 0 obj <>>> endobj 462 0 obj [/View/Design] endobj 463 0 obj <>>> endobj 458 0 obj [/View/Design] endobj 459 0 obj <>>> endobj 454 0 obj [/View/Design] endobj 455 0 obj <>>> endobj 450 0 obj [/View/Design] endobj 451 0 obj <>>> endobj 446 0 obj [/View/Design] endobj 447 0 obj <>>> endobj 442 0 obj [/View/Design] endobj 443 0 obj <>>> endobj 438 0 obj [/View/Design] endobj 439 0 obj <>>> endobj 434 0 obj [/View/Design] endobj 435 0 obj <>>> endobj 430 0 obj [/View/Design] endobj 431 0 obj <>>> endobj 426 0 obj [/View/Design] endobj 427 0 obj <>>> endobj 401 0 obj [/View/Design] endobj 402 0 obj <>>> endobj 343 0 obj [/View/Design] endobj 344 0 obj <>>> endobj 339 0 obj [/View/Design] endobj 340 0 obj <>>> endobj 335 0 obj [/View/Design] endobj 336 0 obj <>>> endobj 331 0 obj [/View/Design] endobj 332 0 obj <>>> endobj 327 0 obj [/View/Design] endobj 328 0 obj <>>> endobj 323 0 obj [/View/Design] endobj 324 0 obj <>>> endobj 319 0 obj [/View/Design] endobj 320 0 obj <>>> endobj 315 0 obj [/View/Design] endobj 316 0 obj <>>> endobj 311 0 obj [/View/Design] endobj 312 0 obj <>>> endobj 307 0 obj [/View/Design] endobj 308 0 obj <>>> endobj 303 0 obj [/View/Design] endobj 304 0 obj <>>> endobj 299 0 obj [/View/Design] endobj 300 0 obj <>>> endobj 290 0 obj [/View/Design] endobj 291 0 obj <>>> endobj 264 0 obj [/View/Design] endobj 265 0 obj <>>> endobj 206 0 obj [/View/Design] endobj 207 0 obj <>>> endobj 202 0 obj [/View/Design] endobj 203 0 obj <>>> endobj 198 0 obj [/View/Design] endobj 199 0 obj <>>> endobj 194 0 obj [/View/Design] endobj 195 0 obj <>>> endobj 190 0 obj [/View/Design] endobj 191 0 obj <>>> endobj 186 0 obj [/View/Design] endobj 187 0 obj <>>> endobj 182 0 obj [/View/Design] endobj 183 0 obj <>>> endobj 178 0 obj [/View/Design] endobj 179 0 obj <>>> endobj 174 0 obj [/View/Design] endobj 175 0 obj <>>> endobj 170 0 obj [/View/Design] endobj 171 0 obj <>>> endobj 166 0 obj [/View/Design] endobj 167 0 obj <>>> endobj 162 0 obj [/View/Design] endobj 163 0 obj <>>> endobj 153 0 obj [/View/Design] endobj 154 0 obj <>>> endobj 127 0 obj [/View/Design] endobj 128 0 obj <>>> endobj 69 0 obj [/View/Design] endobj 70 0 obj <>>> endobj 65 0 obj [/View/Design] endobj 66 0 obj <>>> endobj 61 0 obj [/View/Design] endobj 62 0 obj <>>> endobj 57 0 obj [/View/Design] endobj 58 0 obj <>>> endobj 53 0 obj [/View/Design] endobj 54 0 obj <>>> endobj 49 0 obj [/View/Design] endobj 50 0 obj <>>> endobj 45 0 obj [/View/Design] endobj 46 0 obj <>>> endobj 41 0 obj [/View/Design] endobj 42 0 obj <>>> endobj 37 0 obj [/View/Design] endobj 38 0 obj <>>> endobj 33 0 obj [/View/Design] endobj 34 0 obj <>>> endobj 29 0 obj [/View/Design] endobj 30 0 obj <>>> endobj 25 0 obj [/View/Design] endobj 26 0 obj <>>> endobj 16 0 obj [/View/Design] endobj 17 0 obj <>>> endobj 610 0 obj [766 0 R 655 0 R 651 0 R 647 0 R 643 0 R 639 0 R 635 0 R 631 0 R 627 0 R 623 0 R 619 0 R 615 0 R 611 0 R] endobj 5 0 obj <>/ArtBox[6794.06 6962.0 7506.0 7463.48]/MediaBox[0.0 0.0 14400.0 14400.0]/Thumb 787 0 R/TrimBox[0.0 0.0 14400.0 14400.0]/Resources<>/Font<>/ProcSet[/PDF/Text]/Properties<>/ExtGState<>>>/Type/Page/LastModified(D:20080718182723-07'00')>> endobj 782 0 obj <>stream HlWˎ$7WZ(Ji` |49AUy]CIۯۧz}}m?q~jo~]ݳ^F_c#o~feG܏UGqԺZznxpJk˽Ǿ|zqW/޵4UYJ4U'dWMbw~%Ԯ5ly&tCPQƺLV%˞R%E|=~fq;!P`H-,BxG,SPq,nOB{N!"\!qP%,Ң( :CS[Ui[dڲth2Y ,YK(jƂ,:K6U`iJ|gש^S"'7g+Ԉ+n\$ XP!Hmo4"jؓ UEhce(SzZ{Vhm6r5piR`[^hZU#VcEBEVX@ p| h(lC(8/yA3ȶ .)*baA*dH uaM .<"6kd h\oƆlʑGm%vzd ݘ1N.FVԃ) $gW&/&3OWOmf/P-,|uh.{i8WUܰ] cr (!dяE= KܲPٖ&Q@e rBUL B`Fjw|bc(|l9) Tc˦Qss6}NS]t(bSWqO_758p<٥ٔP~r5h-(9DaK7lp+''#Pֳ1t)- &v|?>c>;FN2nX}\!4yʴďNU dAOif{"=/Nç=BͩiKIጰ1SCD "i6L]NѬ7kNBDn, := $.)M;piiGsI?.r  ǢM$9f838379qҶJ>6D!X)ΤQic#^8S_ ]3扮1tx 1Dꑃ"KBfQXԢ=¨"r8ܪ1 #9KZdkxFg}1t J5ՆR"G sHE]Ŝ^ц@xXX}/2#^A%P{kA1nAm|μN H%X&";?@K:VgWhZ07w_IFŀ|qdhM!C/.5MyUr 4nXjMږ2b;B|ǛA1y՝(0LŸ>M 6ñ"4;а:UՈi{NMj*Ho{5_eBsMb /jƗA Жp\|yFdEk8 475!J0ZP)a|$%Rx%C-ڦobTv\'ڻnQrbg8 ǑǰaNUk1z%Ri[ 0PIQ"Z&tԨXNTDIBގlX14#Aг3Gt! 6ަu)n&:n]AlTL'⇠-X3[+(^Í!ZѢWaY.Wlƕ ]u2a7P۶؛;^NvfWD\l ;]5 l1h^TLLE11:2ms1Kkq{~ +Ks.%xVK2YZ JF~MtHKZ=)u P׌qLuw!-]]=Fg..(}$tL>ƃ JI `*KhqM{[j8a:tW!)OxJ$v"ae0&[ WhrXp)uDmֽ)HkR*kmD95.viI*cװ!-lJՖb|Z| _ +\Y*A7q]ta+ݾM@}e2V]`yC2 xXKfqbo ء &Amz3uKYх!.{֗gbA7FfYw,uF~b #J8Ń!I~ .>DN'nwX\G@b]!9>6,:uhN69iI4z U 6Cؓt(K'VcG@cӀM`sU&.mrUAC>&jyI8=QE8䴼1VAǂM_$l5&bAs2 !gnsxi@w̜BEf{䱨U̇ dj`\ubҴԀl7U5-Mlp˯& -5:Dž)vl7E9s3 :HjuվHT엎f$R}?H> /f M6)jW|}aU@֟Ϗ=yǷrkyHϏ}|{}IO_Ϻ']]lRշfE'6 ݃$Qؒ+'H;q c{ޢN4L~/UUA# fkT`c/"8W 2G3 % :[r 9IvdMP0O Wu}z]߫?WObX;e3Y=hM,UMVk?&w*9m,쟳)Jy\, PAOkFmЌ $A %N~{DU?1~[ sD/ʏ9ٲVH"qkZ ק#qR6ߍ3*r$GfX,[E_87rxI^ WQƀޔRT+,6pZ-W&;dDv`~q;bʁy1 { H@˂OU.R gU /Fbzj5Y5e=*VHofk"BIĹ֕'/RzM[ad'irA $upV;| )i1e%kQΰ|ʛ+>*}HK?MY}.L*l'ۿKJvL]Ran66e'+o{=G6@O9d1yT/e;G8ĦzslfiL z|l9Zy1, UhSpJYxu d#sO0Զ$مjv(-_9gϡ]Krz("\k`;3|>*:@{\p@z@twwaU&;n?_;H'>3.HvrF]-m\h(јu!bpu^Mº5G+΀yPHU@@5!/'y(y^FϳU\ͱ2;|m<υ*z 7죭 ˑ"*G]\Ŗ;ؐ@K\DWDw\!݅Ir=wЀPp*R(7rfςsͭ oBWgl.7#ΥdTk.qd}ș>=(%~]G8pZG ;\jAh )B!#3[ A4 Sd5ZXr'XoLWj"hHG2>*lń<$rw)# Mɐ F9U4cg endstream endobj 787 0 obj <>stream 8;Z]Z0bFC>$j/6U$%FM"'+1;C<$Li+])Vg2!!#5UC8"O>17_8/#QOi)!8u620E=qg,^f~> endstream endobj 614 0 obj <> endobj 780 0 obj <> endobj 781 0 obj <> endobj 784 0 obj <>stream H|yPgƻ٥N[g;M/QAQ9`C$ ܈@tpTD#J,\mtk{jO8fk8>~vPȜ)˶bʨ8ʺ,Ώ'at;_C.OMc68^U;7!Q$s6mw}|x̎LWʂj "I)͎ZeJRb] eIy.ޮOhL!S)b52RRD*M VlMTʼeʍ a_ad s09M07alE62 c1,&. ~X p/op"WZdB Ÿ("z-^?t.v9#sHG4 ~!d=亏c9_d#dQԵ) ]=4Vh&Ob"~$]MTt2_76;c'E(]߁ViM紑?I֮d[s\6eS X‹EJ (_ w Ƅ78B 5>x򟛐~}"?|4z2jQ/Ԋ)(l}d8艹.LJЇ;Nإ n G܏ѧGw>':pw|>3"vO.1ZvEǚ :0;pPydmEsfrҺJv?)8/SPZ_Ͼj*_zf~w*G s ޜJ~BS2pz{]qͫ*Wo J.9*WYߝ?~LAтFyn]2+`\JR˴&N[΂[ϳ7_A9N^~MrV&JJSRE_Ϝ6ܳ(_Uk]+#m{l jݾaQ m(Rb$!g&V^tj#SYFؤ@8ʠFtrHlvtByr|zo4\>" ^D/s"嬄,v{_dfdI˚GgaA\6/C+Fi6 D|80y{%Ap}h2<=KI3ڈX֗u>qymLӏAUFxFڏ92C|aG7Y$==БgR H&GHdwpZvHE&i"b[ΒsM\ScU'$0Х̐ ۛ*VqYy2$Ԯ)&LdEdkYWH\f8sYV[U}4;R+Н)#ָ֠#',tY/-( 0Kh÷gZHڰ!1̏ P;Ƞ?2H DS0 aq̛osë7U槀uYiPgL(1C\Ss5 '0^Q>Q(!aesS__(:ʯɾk$ N5ꊊ%/Cu6]V(IJ yP9֊hRF@sg \o>IlegI4сa),c9gfI(*XhNd^bA:pgCqηzsI]ыҪ[DY→Pw kq\PBi-BQ$iMOD/.EuR`qs}~}sZzbvxw|rx3{{~d{bbP;o3>aιx<IwSx&xzМR[U{0x4F{R~XZ}y@A<{V{WZ~}K7v w[xGRw^misxqun}uAǿ:.+hfn!6^/tJLo`E h endstream endobj 778 0 obj [/ICCBased 779 0 R] endobj 779 0 obj <>stream HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 N')].uJr  wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 785 0 obj [/Indexed/DeviceRGB 255 786 0 R] endobj 786 0 obj <>stream 8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn 6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 603 0 obj <> endobj 604 0 obj <> endobj 605 0 obj <>stream %!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 13.0 %%AI8_CreatorVersion: 13.0.0 %%For: (Kelvin Wong) () %%Title: (pylons_as_onion.ai) %%CreationDate: 7/18/08 6:27 PM %%BoundingBox: -7 62 706 564 %%HiResBoundingBox: -6.44434 62.5 705.5 563.9785 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 9.0 %AI12_BuildNumber: 406 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_TemplateBox: 400 300 400 300 %AI3_TileBox: 111.5 -55.5 687.5 678.5 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 13 %AI9_OpenToView: -94.5 634.5 1 992 699 2 0 0 50 75 0 0 1 1 1 0 1 %AI5_OpenViewLayers: 3323333333333 %%PageOrigin:-66.3003 -266.2988 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 606 0 obj <>stream %%BoundingBox: -7 62 706 564 %%HiResBoundingBox: -6.44434 62.5 705.5 563.9785 %AI7_Thumbnail: 128 92 8 %%BeginData: 8930 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FDFCFFFDFCFFFDC4FFA8A8A8FD7EFF522727527DFD6FFF7D272727 %5227272752527D7DFFA87D2727277DA8FD6EFFA8A87DA8A8A87D52F82727 %527DA87D7D2752A8FD6AFFFD04A87D7D527D52522752FD0527527D7D2727 %A8FD62FF7D275252527DFD04522752275252FD0627522727275252272752 %FD63FF7D52272727522752527D525227272752527DFD04522727F8522752 %277DFD65FFA8A8A8FFA8A87D52277D7DA8A8FFFFFFA87D7D7D5227527D52 %7D27FD68FF7D5227527DA8FD07FF7D272752A87D27FD04527DFD63FFA852 %52275252A8FD0CFF7D2727A87D525252277DFD63FF7D7D7DA8A8FD0FFFA8 %52F85227FD0452FD79FF522752527D5252FD79FFA827FD045227FD50FFA8 %A8FD28FF5252527D5252A8FD4FFF7D2752A8FFA8FFFFA8A8FFA8FFA8FFA8 %FFFFA8A8527DFD14FF7D27525252277DFD4FFF527D52A87D7DA87D52527D %7DA87DA8527D7D52A8277DFD14FF7D52527D52527DFD4FFF7D2752A82752 %5252FF527D7DA8FD0652A852A8FD14FF7D27525252277DFD4FFF52A8527D %527DA8527D527D52527D7D527DFF277D52A8FD14FF27FD05527DFD4FFFFD %05A852FFA87D27FF7D7DA8FF52A87D7DA8A87DFD13FF7D27FD0452277DFD %58FF52A8FD1EFF52527DFD0452A8FD77FF7D27FD055227FD77FF7D277D52 %52527D277DFD74FFA85252275227FD0652FD0CFF52277DA8FFA8FD05FFA8 %FD05FFA8FFFFFFA8FD4EFF7D7D52522752527D52A8A8A87D7D527DFD0CFF %52FF52A87D7DA852A87D5252A8A8527DA85252A87D7DA87D52FD34FF524B %52FD10FFA87D5227272752527D7DA8A8FFA8FFFFFF7D5227FD0CFF5227FD %0652A8527DA82727FF525252A8527D52A8275252FD33FF52F827FD0EFF7D %522752527D7DA8A8FFFFFFA8FFFD04A8FFFF7D27A8FD0BFF52FF5252277D %A8A827527DA85252A87D527D7D7DFF5227527DA8FD33FF52F8F8FD0BFFA8 %7D2752275252A8A8FFFD09A8FFA8A8FFA8277DFD0BFF7DFFA87D7D52A852 %A8525252FFA8527DA87DA87DA852A87D7DA8FD33FF7DF827A8FD09FF7DFD %04527DA8FFFFFFA8FFA8FFA8FFA8A8A8FFA8FFA8FFFF7D27FD14FF7D7DFD %42FF77F8F8A8FD06FFA87D27FD0452A8FFFFA8FFA8FFFD07A8FFA8A8A8FF %A8FF7D277DFD13FFA8FD43FFA8F8217DFD05FF7D52277D52527DFFFFFFA8 %FFA8FFA8FFA8A8A8FD05FFA8FFA8A8FFFF5252FD57FF7D21F87DFD04FF52 %2752522752A8FFA8A8FFFFA8FFA8A8A8FFFFFFA8A8A8FFFFFFA8FFA8A8FF %A8F87DFD15FFA8A8FD40FF27F852FFFFFF27FD04527DFFFFA8FFFFFFA8FF %A8FFA8FFFFFFA8FFFFFFA8FFA8FFA8FFA8FFFF7D27FD15FF52A8FD40FF27 %F827FFFF27FD04527DFFFFA8FFFFFFA8FFA8FFFFFFA8FFA8FD04FFA8A8FF %A8FFA8A8A8FF7D277DFD13FF7D21A8FD40FF52F827A827FD0452A8FFFFA8 %FFFFFFA8FFA8FFFFFFA8FD07FFA8FFFFFFA8FFA8FFFFFF5227A8FD12FF27 %27FD41FF7DF82727525252277DFFFFA8FFFFFFA8FFA8FFFFFFA8FD09FFA8 %FFA8FFA8FFA8FFFFA8277DFD11FF52F852FD41FFA827F827527D52A8FFFF %A8FD05FFA8FFFFFFA8FD0DFFA8FFFFFFA8FFFF7D27FD10FF7DF8277DFD42 %FF27F8F852527DFFFFA8FFFFA8A8FFA8FFFFFFA8FFFFFFA8A8A8FD05FFA8 %FFFFFFA8FFA8FFA8FF7D2752FD0EFF7DF8F8F8FD43FF52F827277DFFFFA8 %FD05FFA8FD07FFA8FFFFFFA8FD07FFA8FFA8FFA8FFFFFF5252FD0DFF52F8 %27F852FD42FFA82727F827A8FFA8FFFFFFA8FFA8A8FFFFA8FFFFFFA8FFFF %FFA8A8FD04FFA8FFFFFFA8FFFFA8A8FFFF7D27A8FD0AFFA827F820F8F87D %FD42FF52522727F87DFFFFA8FFA8FFA8FD07FFA8FD05FFA8FD05FFA8FFFF %FFA8FFA8FFA8FFA85252FD09FF5227F827F82727FD42FFA8275252F820F8 %A8A852A8FFA8FFA8FFA8FFFFFFA8FD07FFA8FFFFFFA8FFFFFFA8FFA8FFA8 %FFFFFF5252FD06FFA87D27F8F827F827F87DFD42FF7D277D5252F82727A8 %F87DFFFFA8FFA8FFFFFFA8FD0DFFA8FD0AFF7D27FFFFFFA8A85227F827F8 %27F827F84BFD43FF5252527DFF52F82727F8F8A8A8FFA8FFFFFFA8FFFFFF %A8FFA8FFFFFFA8FFFFFFA8A8FFFFA8FFA8FFA8FFA8FF7D27527D2727F8F8 %F820F827F821F8F87DFD43FFFD0452FFA827F827F82727FD09FFA8FFFFFF %A8FD07FFA8FFFFFFA8FD06FFA8277D7D27F8272027F827F827F82052FD44 %FF2752525227522727F827F8F827FD05FFA8FFA8FD04FFA8FFFFA8FFFFFF %A8A8FFFFA8FFA8FFA8FFA8FFA85252FFFF7DF827F827F827F8F827FD44FF %7D525252A87DF8F8F827F827F82027FFFFFFA8FFA8FD05FFA8FFFFFFA8FF %FFFFA8FD0BFF5252A87D2727F827F827F82727FD45FF7D275252FFFFA827 %F8F827F821F8F827A8A8FFA8A8FD06FFA8FFA8FFFFFFA8A8FFFFA8FFA8FF %A8FFA8FFA852F827F820F820F827F8F8F8A8FD45FF7D52527DFD04FF5227 %F827F8272020F87DFD0CFFA8FFFFFFA8FD07FFA87D4B27F827F827F82727 %272027F8A8FD46FF7D275252FD05FFA87D27FD06F852A8FD07FF7DCAA8A8 %FFFD05A87D7D52522027F8F8F827F8F8F8277D7DF820F87DFD47FF7D5252 %7DFFFFA8FFA8FFFFFF7D522727F8F8F8277DFD05FF7D21FD0627F827F8F8 %F827F827F827F8F8F82727A8FFFF52F820A8FD48FFA8275252FFFFA8A8FF %FFFFA8FFFFFFA87D5252272727A8FFFFFF77F820F8F8F820F8F8F827FD07 %F82752522752FFFFA8F827A8FD49FFA852527DA8FFA8FFA8FFA8FFA8FD09 %FFA8FFFFFF52F8F827F827F827F827F827274B52527DA8A8FF7D5227FFFF %7D52FD4CFF275252A8FFA8A8FFFFFFA8A8FFFFA8FFA8FD06FFA8FFA87DA8 %527D767D527D7DFD04A8FFA8FD04FF7D5252A8FFA8FD4DFF5252527DFFA8 %FFA8FFA8A8A8FFFFFFA8FD06FFA8F8A8FF7D7DFFA8FD07FFA8FD05FFA8FF %7D5227FD50FF5252527DFFFFA8FFA8FFA8A8A8FFA8A8A8FD06FF52A8FF27 %52A82752FF527DFFA8FD04FFA8FFA8A8FF7D5227A8FD4FFF7D277D52FD07 %FFA8FFFFFFA8FD07FFA8A8FFFF52FF7D7DFF5227FF277DA852A8FFFFFFA8 %FF7D5227FD50FFA8275252A8FFA8FFA8FFA8A8A8FFA8FFA8FD07FF52FFFF %7DA8FF52FFA87DA87D52FFF87D52F8A8FFFF7D5227A8FD50FF525252A8FD %06FFA8FFFFFFA8FFA8FD06FF7DFFFF7DFFFF7DA8FF7DA8FF7DFFFF7DFF52 %7DFFFF525227FFFFFF7D7DA8FFA8A87DFFFFA87DA8A8FFA8FFA8FFA8FD3B %FF7D275252FFA8FFA8FFA8A8A8FFFFFFA8A8FD06FF7DA8A8A87DFF7DA8FF %7D7DFF7DA8FF7DA8FF7D7D7D2727277D7DA852F8F82727F827525252F8F8 %F85227F827F852FD3CFF525252A8FFA8FFA8FFA8A8FD08FFA8FFFFFF7DFF %FF7DFFFF7DFFA8A8FFA87DFF7DA8FFFFFF7D275252FFA8FFA8A87D527DA8 %A8A87DFF7DA87DFF7D5252A8A8FD3CFF5227527DFFFFA8FFA8FFA8A8FFFF %A8FFA8FFA8A8FFFFA87DFFFF52FFFF7DA8FF7DA8FF7DA8FF7DA8FFFF5252 %277DFD0BFFA8FD47FF275252A8FD04FFA8FFA8FFFFFFA8FD05FFA8FF7DFF %A8A8A8FF52FFFF7DA8FF7DA8FFA852FF7D5252277DFFA8FF7D527D527DA8 %7DA87DA87D527D7D277D7D52FD047DA8FD39FF7D275252FFFFFFA8FFA8A8 %A8FFFFFFFD05A8FFFF7D7DFFA87DFFA87DFF7D7DFFA87DFFA87D7D522727 %27A87D7DA8A82752F852F8527D7D275227527D27F852F852275227A8FD39 %FFA85252527DFD05FFA8FFA8FD09FFA87DFFFF7DFFFF7DFFFF7DFFFF7DA8 %FFFFFF527D27A8FD55FF52275252A8FFA8FFA8FFFD05A8FFA8FFA8FFFFFF %7DA8A87DA8FF52FFFF7DA8FF7DA8FFFFFD0452FD05FFA8A8FFA8FFA8A8A8 %FFFFFF7DFFA8FD44FF27525252A8FFFFFFA8FFA8FFA8FFA8FFA8FFFFFFA8 %7DA8FF7DA8FFA8A8FF7DA8FFA852A85252272752A87DA87DA85227275227 %A82752272752F82727A8FD43FFA8F8525252A8FFA8A8A8FFA8A8A8FFA8FF %A8FFA8FF7D7DA8A87DFFA87DA8FF7DFFA8FF7D52275252FFFD06A87DA87D %7DA8FD057D527D52FD45FF7D277D527DFD04FFA8FFA8FFA8FFA8FFA8FFA8 %A87DFFFFA8FFFF7DFFFF7DA8FFA87D527D52FD08FFA8FFFFA8FFFFFFA8FF %FFFFA8FD47FF7D2752527DA8FFFFFFA8A8A8FFA8FFA8FD04FF7DA8FF52A8 %FF7D7DFF7DA87D522752277DFD07A87D7D272727525252F8F827F852FD04 %27522727FD39FFA87DA8FD05FF7D275252527DFD05FFA8A8A8FFA8FFFFFF %7DA8FFA87DFF7D7DFFFF52522752277DA8A87DA87DA87DA8A8A852FD047D %A852FD057D527D527D527DFD39FF7D27F82727525252FD052752527DA8FF %FFFFA8FFFD06A852FF7D7DFFFF7DA8FD045227A8FD59FFA8A82752275227 %7D7D522752527D7DA8A8FD08FF7DFFFF7DFFA8FD0652FD0BFF7D7DFD07A8 %7D52A8FD047DFD04A87DFD3AFFA87DFD052752277DFFA8522727FD04527D %7DA8A8FFA8FF52A8A8522752FD0427527D7DA87D7D7DA8FD047DA87DFD04 %27F852F8A8F827F827F852F827F82727F87DFD38FFA8522752527D275227 %522752A8FFA87D525227FD06527D5252277DFD05527DA8FFFFFFA8FFFFFF %A8FFFFFFA8FFFFFFA8FFA8A8A8FFFFFFA8FFA8FFA8FFFFFFA8FFA8FD3AFF %A8FFA8A82727F82727522727277DA8A8A87D525227522752275227272752 %277D7DFD10FFA8A8FD07FFA8FFA8FFA8FD43FF7DF8527DA8527D27522752 %2727277DA8FFFFA8A8A8FD047D52A8A87D7DFFFD0FA8FF5227527D525252 %A852275252522727FD05527DFD3CFFA8A8A8FFFFFF7D272727FFFFF8FD04 %27A8FD07FFA8A8FFA8A87DA8A8A87DA8A8A87DA8A8A87DFD05A8FD06527D %7D2752527D275227522752527DFD42FFA8A852F87D52FD042752F852A8FD %05FFA87DFD6DFFA85252A8A8FF2727277DF8277DFD05FF52FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFFF7D52A87DA8A8A8FF7D7DA8A8FD54FFA8 %A8FFA8272752FD04FFA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8 %527DFD0527A8FD0427FD59FF7D7DA8FD19FFA87DA8A87DA8A8A8527D52FD %FCFFFDFCFFFDFCFFFD2AFFFF %%EndData endstream endobj 607 0 obj <>stream %AI12_CompressedDataxis%Ǒ ?`?hCf,%DiZ1TR5]9~xGª8Eͷ_n^ݗusvn?{+^O>G/~U OC_MɃWD<޽˫W_\ wzn?|-|^uo香_v7o}zW_WCw56U"yۻuu'zؿ{ۏ߼Çݻ۷Wr{/w_u9{O_ݾۻ>}˻*}w|Vǫmn뗿OwGFݯۻa\~Gx+FXw7?զMs?.Om}pi:Sy-ͻw<߾_06b?巟^߽WB4͙w/^[6wa߽p72~unkwsi{50W 5WcW:v׎ ؑ߿_~9 װ՗ĻO_̛6vWGܿYa!>~{+kȲo_޽gv- w?g |ӏᏡoӻwwWpۿ]ty==fׯoo/>}Gػp{-?rKܾxw~sR/;d޹G_qWW[>ܼgܳw޽pQO^x{\|xs^* yG ? Зwon ^wǗwl7_x}@?}~~͛OKpX=߽tËO}t'_׷oGW/n_Sé~v=ֽ{.?x%gw7ތ |;ܼCyts"S Ie8_+D[4[;zN~`‚=^"^sw6@w>CуyØqxi~_yt=+~k~kןk~}7?ĝՍ4oě߁c/@n?y}#C"-|.@5~.|:}_^}K+o֏ݬ?wh]c;rƯڱO|ɝ@\z(p3Kh"n_|707tO/L?"7w?^vN7@P]xs#|et{ JFd8wW]l׀}ӛ?{ x56 qx߼>߿ `ۏƿ^'ի1 ػ8x >,ӷ^}o_ jӇ?_ݻ6O6Lx7_^IX ӧ{}w ]ݯ^^P{.~%Wdltox}Or e#_^ pe]u%:y߽Eo| 㟏۷@ n]"zV$Y '}_~y&v?!]DZ'x; u0j;4f=Cۀյ=&yFhsiv=vMv]wKЍݦvn|cMw?$S縉۸xHMjSSJcҜ6ifh~Caa3l]GL 'Si`*Iڷj81Vyv詡 j qynd0xę~Á'ShmQ&S`[36'S ,PRb`8ʶ_[m4c{l~9̇0C:z@6?~>w;amwݼvnإ]lv~nvئmNU9nfn6y3mͰIa7۴f>·y??~mn g@813N#5>i!X#Œ@X,pD@?@ G؇uP"@%@-@7&! hI׷䞨(ԍHQzq*jT P/{h!mQw%w*;3DC4V|cVr0sFA@k pnܛ {ر# H x& px>쎀D->N a 8q<}hwzSy(؛w!Z.}xrVm9y3xgbQ;Ij|KX!b%ʗpa)-".y f>.`!zb + %WqZ2 [" DDfZ$^ cU⯎?z%؂mk^̺$a]x6%W-R0`%mK:[ [`2VbK+̳mpFY7XFWB98\u`ܡUiDhFZeDB|`m/mGn0ljmmpwӍ*Ote^t8zg*_{t_jsz5f[XpAz8L1-TDcW;Yd-NaI(BW v/cH|Kq߂#w]GpGql"h`$ TBS򱆙y8xS VtaxTǺC2\r-厹%L ޔVc&s-1sF+?0*ߛgS&\geo]BO c1VrOch!LFv~cj86 Mx5io?|=n?v꓍ܘy*zIu*ױ<'w!N=8,ۑ Mӥ#v'qa ½{^{ylO0԰+XJԫPAV숭dk,>UuPJ׬7VYT`6ymCԷ zag[عo]L ~O ?JA/yb'Loiwrۄ1\"obx]g{G|ո_d/.<fx3ir"y7 M%IToW!7}RN$ؾ";)L*&.DlIX!һoLR*kɴc<[A̶WQk[ȿ3/k6 ];؋E )5Rd=<<šJf邱Hc@%xuw {Wr,ְQ6gT%i9%J&P*Tb٭́&gs/g@Q#ϖ<Ŗ')iF+ E#k=D%b&uARHm#Z«^0kCqٌ]{'Q/r 0zuGŬFuV 2nmHEn t2i?L-eƖ6BaQ@]F qm qʩOZYcuiA_9KXhҢ EiӲ5Hn޲mNmق|#17#?Xv~q6q 4s .JڢZg߅fҖvֶm\qmtmp--ύ|+YlmvU}mOMق|#sI}S~RYVi@N&"$B2d터JUbDU#a+HXEJqKdm4 OiJOteVaCWDsE:|[fsǪ7~N/Xeۃ4Z6 T_~?|ՅSvgH3V XC:!d`eHP D]5E! ?R8=dWHgo]uD[ծPq^;X/Hs.߼?J^7'9/<;8ko. ?nNJ3oūOጫʼnS4g;| 0o sgVϫA)Q> -u{Ђ&8;XC\kwuК%YJZq0F8 y 5A*c?^?DԡH2tQh7n| oH&pY5$8ѢZ~􋞿S`*%ZL[cU$7EbՋ֩lj*Q soᒇVW8Nje Kc[g5 [7| >n~0 Xm\tAA~khs^h ui òo6, #+8R2ՑKkT$j LcSI֕g\Slzl njtU[\uA*eZtƾdy*X(%ÌMU1a UaEO-Z8"k`'";l9,s>L\-炥s><η ؖt`1Np qrvщdayJI[;ӶB?|wolO!v<שmaݣ1hC[1\mŮ dt WrP|^=|x׳n:x}}}}}}}}}}?K#}׳5ﶯz}WH}RbSSr~]\YLĥaQ]/]6b%j$Uɰ6S Evo8e# 1,Z2Y ןk.9frLlQCjx:Ξ:x"-hl)[1q9NcMa+& 82 ̀BlhjQ`"{Ș-:INpK Y4#n{uWwo^q^bf Oi|=ȩDjSv5sB'tHc:B>aJUlM7NcQn)uLPW%z=;*kWui8m{(bw̜iC(XM:KB ۔Tm P)kDɜ|7JGw ސxp=uo.3;]Qi:bQHTK?gd"eh_Vb0ޕԬA~'P8T\w.d(:F 6 7w@ P[c!/.Ň8{D5$_NX@e <`cvmD4Q zn[+/εihAxj ;Ґ9%z3Y$f% hnْu҈j|TvI|ȏ{;nŋ{0.:ȮE\-XPtiAlE7T{ZY:]-- |撐Vǚ+&!sIGə%"{goSnYCeUЃD/ɜ{( EDQKwAA; pte=9? O]9l2&A]ENXkfm4J՜ƅY0Bay;{I:H㼆yOy_z{wm^pM߈u&DJבܢx%$xv$|ZPT5jq=|.ع(y~:;{pU/>b 'ǟ%㳨YukQU)e+u43.)EPM:e1Ҫ * ":>Cf7ˁy` +Eۃ mP=gjGsw!n{צŢaۣ0hu:hٯ٦7qE\/e,sedΖ2@ՎX^ʒ,2kgH`np墮Oq\^bI tMtCіnCXY׊ցYT;Owt߈l tG2JW9DAډOl2L(=:z0ڑ.yԑ9ֵ`tJX+<믌 &'$]d]P!WSu øH28w#GVGoƒ4^x^l9Ԝ53[ꙛ(sc.f:hP̑Q4ZH}((A7ჸvl1B 3^sC5~r'+,3Fѝ1J->!<\*&!'(G5q1=5#<5Oc1-<oFTkBytmfz!jkf:HDZ}xWS\ qvhJpA–X*n1yW超70T2xxym.td%1Ano٠r?ȱnf93fNjVUq&(H jV*ԲmIeʪJc9ida yyuW05&Bo*̻}pŝFI ˜*gj˳X >y.fj"K Ls;c#wFrbe CRg|]Zt]P ]9P͜JZ~QNLӶEy |a@NNya;zs2-3o/_X2&&$#ME"ً3YMNv؅_Y/^OnSOms}8OU"!d*6чWpIx=V%OSvY7S.3[]!iuΫ, /#ָ.^h4"ӣ!`䎝%%j,æIŒ/p^e]iZk^|ak.sM3pY<_&59;c#OˑkRLj4ܩf6Fagx . 9K$oE(7=!"aR͈cjp /LKs 8 b.UҐ.RC W'6ʹc˜4Ϧ\Z%rFMvVVYN>]t܎\&7 y\ YҬR[+'C~2Ia3YLYG+*v"<;i<:YVi,&tZi`mYȑ<2x}6&霂*["Bvpr^,V UGZq: *. Z6*7lh.[V8_Ҧ-2U8ԯA%V=u8W9#:lAA؜Y{~Jn{  zP]½BάD(.Z:qa0}6{J">{,WMai%/J%פG_7}?} }2S3a_]xC2a?硫yJO [!| (9X{5^P  ~٪]E*$&qK,K-vr.ЌT)S fɆAږ*&py'z3 ,3"Qr$ԱDc׹mB]pY  vcm\ʕgISYVIqNdֵ ul=3}:qgtδ:Ö =,i;"^N~REN &\D9%/r[, 16`"/Yr[یݗrbO&%eCk"'m3$ˀl+:? 5(N>T[Y1Vq-@ӨB˲ z.Q4VP5(@ddd Y3T=P5ig띲oI{ Ekh*hZ QȎQK?=jXP .z )jN'mO+e.kVM8֜nB,AV_ˋh[Ui 륉eňâ䰻JV, ODMc,MY\gISV=ήT- 9H `>>EQe NU6iQc}%yuw5שUG\ 'ꐴ6kXn,'k#)'{]E2i{V21=IӸ.}e* a>dOޕsh,ggY"zK9 ФsxRNJTeIЃz4ds '4O NK _zs4P Ӡ~}bIWt|5&~7i:Յ7n+!`-oa}F_7Z-.Vm0\x`r]ZE-FݣYhK\ %!S*sd`*F9 [ zrêř6RSA Y*aQpR O1{*N's꜕F5=ߓo¤vֶPz\QQ OfjnX6YlWfmecF-y,_d g}S|o&W5qۇl3Q(fľkOMYʎVF3J?v&UQt n؉wwg[ b_ g.CmCPEӈ[W@V(Y6X|@RSi$;03}yIJr(Y( e&nc[sfJi?wr/^\`&O6AK)@K|+^[GNz-dԓ$- ^+CG')֡ h^9N}3_wխֲ#|h7' Nr`2嵗a{:LVײM .CYmsr+7/>1Vf3[Caksf8[ 593+RrKyWmϹDPpD) fAsJjs֕zQ -R|rtu%i--~K/2][iFXVYՄKU)' 0ןi.H秳k?ť[_lV3S3^'2u?EgWYsvtEd,r%{, +5KzE0Ro -+.|Oq}ibg<{3CV&Hz̓/.nV)[@ Dxrq=_n,ݫu`\ENq$X#m~*RhzɈj@E.Vc 8V?W'vlVFy,ry9x\(Gz=2Ť &.ifi7ę 9WL[$)>RK'Y״V"jLjYe#LHE.$?,Px%ˢ@׷x%n\$JD{K.SٙvDz|| ar7ou+,q5$ZvpډfXy%*o{*wUyɻ ߘUId9Sl*K\KO+\$g&p]UNbYm[)Q=%5òe> +)`.s|].# y',Iq8Ն.fi( ɜj(,ueiX^5]0`%rS"՘_V&w6dIJ(JEXiX 4;G}ZT7P/I}'xEB<I): zҗ9)(i]ũ3Ҽ"CY4dyъ r&]NpkA:/YSq7ʵIb._ z <ߒquܷ]WgQ\(c2RsDw67;Nf[\eK*n)\r-t)3ƊrI#ʂH{Wt6&{®#3$sf`eEN -g Ҧ.ZCj RűIXYm:.z rZ'sǑbGu*.K=QD\5_Ӥim;ZpT8͏wl%\"o2~my\jX}x|C:U6z H@AD MZpW^xӣb DR32.*sPz;v .cc.BQd0m,ఆUTWV̂rKFBm9Yvڗ^ '} )$qArXx(w.a;/3oT!iZٝIIi*fqؗ\k\>k֬WD'5L;Mnɒdb[̓Y;W^50F]Q~JV¼[R ,Ut7b/:pq+ .Ny =EgjSUMEj:j@e*>"x%R"PLzA5k]|=C68䋒#E_pu)%ܣZVb}tmXqѦU2>mmhc=Vryo ɭA:]ϘKU|/>Ukwm}_ wK$}~ce l?)oEP)DicF ߊAzh}b1{Zc<$POcf'c,5\Ͽ[r0~>BtFH?49V>>H@Һf{[I$0nbG, >JilQ}ڭX#Y8G}Js6bj\,t0 m' Y.l"jWl=kEi:;verm' ѳ`,]uA-N$ZX@Z4r;J^j T^D`"["{pk"5)"%GEL,j(jIQHˈ- JOߑQf>LzD-akm +O[YK)V0q&-P*|*Jۜl۲FLRi7}ٻloLW_K-kڄ94ޙEkUXXE#_p&詐2ˇ~)D-ba8Ř?,$:q?c f9Uk]իZg 4>QKXWJuJj_QUbMU5V%E;V,ڶ\~Q`۞L*l*x$#u\`f=|q ";*rˆwBe]8!6uOBU ZUիf@֮~5C 8Qj%Eh*@Ma0two"۬l!>/Ez[^Ktp>wX}wnw[i|-jl_Kpb87[J{|kx>xwg:u<ٹ,i:v$10otv3U ǔ(Pބ=nhAV!`õ;mh͒Ah%-TuD8N@#`[7| њm\tAA~&Cb 9ڋ3ל?},OlBW x?/m*iCa \O.F s2O(D(Փ]YPcQWuvE}^BG.{@Y:%Bm.$ Rb]A0A.Y{'vt=A Jz4ר۱(YߋzqzV0Y& P22*MܖA|.h/n}\jek-Ԁ`.h%BӃ4]hj eX^^Ғ\zuoJU^ep˥z Zj/K;е+Yi0Ta̙EZ̳z̬ +Ml̥j4MiL1u,5b Y`*śCV 2JaOxWFVqeU NO.46d]y5ŶǶ 薭&Ng^Ÿ5X@"^F|{Iк5S t%dcPsasᏚ_o5 "ݎ=}[v;6r|.uN8-%<|GZp CwbGt"G9W܍G  ~SO!v<שmaݣ1h1ڄ+`N,0 3.St(ּ C{xLd )GTOL⺚ Y5$f,YJ!sf UGH,U"rhI_mDTۙ#k u&'wDZP)&Q)JESEV1X_VljűT+dlt;:.]A310{g>#G\cښ b!22xtSS)}; <[2Rdt4 G$0S'S/b"q~BQ_,UqmxY&Du6*o=2fVC{b6emPQU{dqlo[|T+٪wx1`|}f'hbtO{ c&jԕZ$~]"DN .z.1rmaW+\Nzk^0<.V^Sy"h>AU!5f.?OKR .q[xՙs2*KuahC{}w/Px]^32gԗ} .}՝]Wnu%E&(+g@xFUO[vVkzZCR.P+prݎ~wr;L|bw˽Y9e_)U; Y:q9/y+{Zj!FF_UL RQӇEM%U´\^4ݱ=K`岗M&[*=E{zXͅȏʋ a Y>IqVC!'^,%OR 9 "w+1CH<8$š\ˊ2,EqCQ'X8'"I >vr~Kq%=xP8 IMX";FQ6&!qV$0D5_m"d#Yxe_$ϗ5aNa>Uf8ԕLi"z )$Q*P/QRMx+q+Mu/)1L˃Nd[igvbl[(HDzӒ JJǎ4MwlѴD'UvҔ4zדH \FK\Z«ҋ~ān-H"f9'3&Qmhj 0XIa;"û nN)^&=2G>Ә{bZmS.·Ò5v3 @25KZ{,FG5[akrkħcЯ>K!s.BE5q캱g&_[q̽&xM2 'yLeŷmʲAEmgtik#YX0ى׷+r^%5,VuIՂ!}2*;lBg@y Rywb;J1`mF"+61S|gjMeꦖzp~7m&5TrpE] QbK NZCkfD{VIA4juāE $xzcXc$8BٰGu;2[% W0VvEqM;/ : ʪD)͟ҲF;q$֦҂|{Vz@Tc0lrpO`RTKG]%-CۊK\KNqW_;6#_s\q?ڊB`/LUq=ۖe:쬐;{ݧIYQˌ3{oJO1{z j8_EڔUl $ J@=bJY1 "*%[GA~b;kͳVg] eI#{$o{SmЦABOEkkݢ9#ioXRm?UG7ߝP֦tgݟvW޳sjyA45U}ٕr6,rˊ;dac' ML "E5G0<[/Ho۲r/ck>*r9QDcs ,`='ؼ>[ɎᜟT}b;(>7_0l]+P c9FKuFIڻ/0lMQY洴JGMg,.IӋUr95;Inz ^D3h{_VE|%'$kr,&vERR/ta pQtpCf`#؆h )3cm$xTg: /.۫#w[a8]$<D{豖Jl<ٓ{#Տ-f, *J$UWq_遍$0eGeR~ZߞC/uv).JdJQ֬XeJ 9%l_#U>:6QQ\;W+h0dE`H1s|itUDŰPRj(C-88@.麤Z Y$j,OPSs;:; ^\|f> FHΟ1hU5w}W2KG&?A_:\urJ}ɏj6d=[3+v b[tc: Η(* <{ jɺ" HկQ tUd'Or6Zm.sQmI|DQq^O_TG4x'\T:a)ΗP ;\/r`,\P9[&=͋z(IU^q$pzX|O[PCF2I 3<46c\JnvXp8^c O2L ]&b]*f!%pa |A&OG)G&爋*̘}m`ջG\gp,G~<Yªrݔ(iz`t_ yWHq-`gyP|-N^ ؊Y%_&,K?BN{ <15~`aBSL?U?}Á"/EY}ß_?/Bsk =I]KB:/Qj bF¾*ac˛l &}K-,j?2hQbJ:Ϝ3SVp3M|Xnvv`0a9<iO 'Wlܿzջ%~%^ͷavyӛ߾x~q“ /?O2_Ѣml-03iL> i&4ξ.Ձ-on58`P(1H{X 1`x24h`Az<d87D\_(C&z}PZ ע@+?^TOpbNŮ?`{` _SكZvێ``aap׶b0AKUS0(<,N_ 3LA0 Q65Fц7q8įzam'X+*ua#DXa1D uR I1FǀyYthUGuN^FM+qJ ƽ5 OeX}!@ #+61 F['oQ]Gyt-Ò#6=$y Mq FeW2 ECK~ tHJ`@ep2fIM:f̽ ꠿^[A= NK5:)7c?Z;}I?OM(),tx?'C  ^h`36)P NdĢ1|<`'S vyVD&7zul? 쬰6rp$<0K*OAאA=v>RM:pXaR4tt괒{*=@At im+]DӴ$HHcwz]luG}c+vc([[5z]ہ_.8iJPٲFt> 4ƨ0$NN3+;2v&0CCR`7v +=bE(MF`ǾS;4FM{#q:Ea<fȤ|vN;&b29MQ AGփH1s PN:bxņ/;x1l3o vfG>8y81i{#NȥȢ@2w`ۚT0F #&~mpSCwAqܳ AC5I;K6zfAǟG=hK h _3PS5 1!pl9RGO@0#\Eg c*gYXZS+hW@ut,q6IiKӷd!A er9E<+޶;eFZvxŢNLf0ĴEM4ujeE? *I2\ۀ&hqRLUz6@ EiޱP4yZmeJɓ"m'/]uS'"8u1o*(H:'9H$(PaݦzS&K+k1UA:tt}!=(+?E>B$%b`6 ~ Ct ]G<*;MQ&[$wЛ8CG/{:.V! ):(;0ķ嚕 ˳cP[Qvu }y4:8B6gƒϢIJaI֝weP`.!6<!" ɮ+6.UׁB/c , "cԗg'.$I l&}R?93h98klea0aTtF$Ӵl0{;r®0p Ӌ`UNn: |EU_0$ x,g؁wwYG`u$ -bd)&Nxxыޯܷ?D&L8S`B;Kx:+1!*"N t.PsdU1JKH2FIMonGх@i0dcYFeBlt ^ؤ M1E N61GM%81?ƓXPD!3_X'dE&]n$ҏաTk6g|hDXcN"]IUd'uoAh8f])! plP}Fv2+ af)&6[Vـ4Nz2rQP dZp]X-04@JuFt:Ez#Se2f˦4vFy(XSmto@lbdȚikZV2,f:!69|`2B+UUJD݆,ypյ gW=~:6 @*G8vss3b,:ԋ)kM`<0b0vQxR8W;zLېq4hYTi5N>J;znC?9n^֧4@cN25I wLȘg`S%;zBXoS>}_jfX8U۝^=:Tقd8B -"]$c{`If1#tʮ(gGjEe^F3IP4C_=A3":sw@/UaH~`NW(OϱqN5bD=SP~g(dlɤ` NCT^Wr vJ+^*u B ˴.<$Lb:! w0V-PгQO}#"4謈лz?sDKyv}DˀE:cdAeѮ<A \,aO*ޑB`Lٮ!wN݅&Pal<0rX;~IyhGeli;)&=z}Ǝ7';DyvKÌv.ڭ[ݓў,AfWF|ѝ1uyR3ȳiPg*מ^:d<0&--+İQw"MC+3|/E촷 4MB*禍,v `8dOa\gEO@`]gv*2+:HPز?mbDM,o'l.I];8*1t 8*[S Fa>x&foC7cb]EU0@q0tu3SzTH }/ѯE&$F.C̨!R<9ϊD]Z`67E< Gri$ 6xrceY^2p= 9¤gTDZQ9QT&-*EbRVb@77IhTR;UGhUSVO"9hgT(Lc0pcII:F736SoM*;xhO<*^HMEΝv7{T;nK'b,%p,>?I燹5sq|;.JNZ E |%`0blԈĠhݒ1^FNuJ:e`3)E!Aj# J&GQUh6_m3ԡ'bBëV/Z(vSzFm;ME#P\(ZCzVE`hu1F#u>P~)QBJb yK2$Lʐ#@`uH=ʂ}Ȭ/CZg%L [FySgg4vjAyDg \>%Tqh/!nyᎁ$~f; R;: "F2'E{ebIQ%I`s2XWBvR3kHD2J)f s^APԢw"82pL0vJTfUYMA : pغΪoEݭ !$#@`^ yz0r-:djϬ$#gQF9jI|r"p48 x˜bЙWGj M\Hţifvx@iQs*%<;Y`<:UzIg; 0} 28Dgl#Cd@fm2oK*~`qGi=Q%-4Yn5zGSH1L(%@7z(ȑu;8{u!3vF~Tw0:AqR+ܲ:- *Lfvb=F1j &Q? 3z r D(3cÑ8bYz(yPG[VN \Gu(lɋd[x}Gh/6E%A#sgq/ 𿄄@0[ YI 1>0!?;$|I 6qleTթ[{gmxtUSUgSr> K;XE 0_X h p5_o]@p[:4kx@)1)LVĊ4n;4GAؽYaq82 S ~LxB{ {nA =a3`g܉$@by!{iF?Щv҅m g !eh=@)R2mU ܫr'LJU8&ѫHlIw|?cwt<z v@g(nҘCR"gcOJb N<@ZB-͹*  XA {ht;"bEr4lOr <aw9&vE杊 Y<]TxzRdbr -˟d`1@`@k6A⻰agGY5"?:w9%IQ;`[ޔT'uդ&v&N@KTф+@`&6<@ք`JuLɅ!6l1MEҵĸ5Z ǥ|°XAqEXz#x* "9pH)ksxqp>34QXg|03PgqF4.H11[M0*OeTy : 5; @Man?'wಢk :Ty=aG*it0LfӋ($'H4겂6t;@mjɀ)BT 3VCS#(K/é0E&bhHf@C-7 k8E@ύ =ML\-d.M @AW8Qg&*1zBa6Jq3#9XuZ~yz,("k UϷg\1UV0&ngM dgСqK8D}H\~Pzq`N(sD;d< 8`uV(%HP"cDj"D=U4kaS.˺ 8RvuV6<$]M:@xT *X:PRA(Dap(+craR7' "JX_U"NXs c̀dqj Yxku4˨<Ulk6ΌxA^2aE+5{ΣFp9Mӻ9+ˈ1(g 9+8@!<\f|墡K)2K54䷾hxmM4ċ~П(qj OeUb<O4 W\qoWRp O0u3]2_)\s{n#h<%xº4'1m[Ʌ;Y-STiW@PZxw7ߨ5uikw$e m)*!d Z$uQ+~RmG-39T:0\˂XKL9 i\^ #|m gPiZxֱ @]UFnMzp9\ Ad`( Q<0;qp&B<.2A[ľe\{,B_ !=k!=G< SC &:&򸋁B2I}L[c@#OQ7].(u0X6-T2H=Ӳqʼn^3tXj8\|P/=9' SgnPE|@-nb,x% iĆÊ*[l$"8҃j. 8]9XL߱u0mW icH87Htf'xa'LOrA] &Qǣ ⺸Gp֟a\jDȑs8m@qnpȀ =4sVq<$ Kq 3+ns/H@5uYFHɨHioBA\7 9[3!&5 l"/0?qdXaNb ̂Ov%Xh4Đ,x@!?Rdo/S/u`T]{vgsd>񫲣 >:͔|x;ӹG.8r 9_bp[YSWf~ .Tri$h\)/2MV|%wB*QP]9,BBn_a: -/I>\qr6z4-I'itB!7PG6I~k˲xc]ԍz2W4m﷍gsG/g d}>H,bhW1 a%bMPo'JƹӮҧk#=I\_>@۲o־lw!:50[4^h"WZ̝MtłXtѸ;}58ܨ3|K}8ihʖfr?3*dC,T)5j_#Iaoavq;Y ;&2w7cvTqm)?ځm_ʏƽ7AVCpD|l.+;$ }HAKxkH(k稹Sѳ RN1k؆r!Xh0 kԆ"mXôՒ_9x=Z 1L2]ir .EjۂK+y?}? ebK-QZv{I-2tZ,-&i-@=i1p@Ѳ`eh[4#:A$/K!pC6OXڢ}!2uI"D,!G>fDwL3!POR~'B'B)DqaBE։dr%뾐:`=+=:D]Ph1v/_L 4\@gu"V ]EH D>T>@xJS}OxJS"N<G sTCrsVrH99d${ύҧv],KU6a⤱IM|2+.+#]aBv~Pfm$6A+LX0 Zahx|2l`ĘÔ+I[Y,DH@G$FV۹'6 H@*$D$0?axAMәr:wzE3,dR:L2}p8WK>|a-geL)xS^S`%w31Ӫ$CSyDMEW/bB )qD0 h%MJD&)BKeTBYJq#Ia8~Tˤ\!ֵ6vjQ 5H]9Dq 9D*=:tzu)GJ?yt~$7:$ 4C$7fϔLfG3-0T56 g0id-)}5kޠij3OiJ^sݦXd-):qP,cHk0iTwӵ]syܸ'm{>+Gm$&rjd1KgT0d˧vĉ@ʧb5[{^ٶa@^!1,zmD v6C/LbKmIfmĵ+[ǝ@rtERHgL:j91mWKnq똄sBp2 yrՌh&Wwp;y@9_-ֲz{W=Z{^NlHlΰ)Kb$(hmj,ee%3w`c7!nqQu=Wi2)O9W;_Դ}Z/UU@]uY IжUcs+UVΉ&oj}X xt/ %=e":HI'/Rh0KS깊vi؆#`3e"XK5S:U@#e:ǭYᮁ1Bv=wDƕbz$XhBP'ZZdobRWc?Y65EbFK^ELEٖD"L.0Aȗnt/b9y%b<ϖ"YP {L’_'C8 4rH %0: ˅?í#X'Ѡ _gkx:>qژ .y(wDeSRc nں'6U"tqcQ-5`Vlb^Ҩuր1=^{˫Y-&u=j*U) j8WKW -ԖtN65Q%`x =Mβlj8!+ VLp:5X'bv Q Lյ@4"]\:T?S&Ɠ\X *(+%zރ- $E4.A`S)Xs1f9&\lHD!{ tUΨC<]`&)Wza* @x &{Iqkdfc|b|mWc.,U3 vKoB~T&""3IJ(U%P?J ن=LA#==3H@ŠP(DNҕ{oGN%6@h#f(]NP gE;npP/+wz[WȽݧ}3ÿulB f}⟾>|~[G6|<_<7[J6ځz~k{}s{k^r{}ᑿ7Bn27om$Mg}{Ms[s`k Ds; *]ִݕӧO)@}5(XG&9z6/mF (,~\egfPo7ʖwRV LMb"صeHTh4 F-)9C3s+i%B>nQ V짫I$+(cXiNsv1Yb Jq>9mRI>'$PvSsi$(E~ngMjoXŧX5%XEXgɰ>KYTb 6dEf-2Bo]!>q`Ŋ{{N5sE:ͺ@k.n\{\|/7;wfjr]tY]Wߴ}ecؑn7tcŹ\|ڭG M{ɻow έU\w##[^}Φk/YUcŹ/wo?׾׿O~}ށ/[j{W?}?}g?{?~߿اjkC=>ՇcO=O>٧<}ݱa}eV+V^pɍ}ooNM> ?~ï6]ɧ}zѳigGX79{U[=Ɠ<_ݜvy'?|*Ŋ~?~,O?}w]X ow~|x%'ս^/>_ubH=zNEי/}?t8W ]⼋op3}?},~뎘]ܸc⭏|G>~?r37诿s{깺 {{{﯏^LpІɇ+,C.,zYԑ?'kO~Oq9Ceʎ#ygúb^sdrJ]xU>o3A} >. TɚRCLT>ezñ}j W?g\0V%kU*?طyKWU+KB׾#ܗװBtu b*ȃy˟|ojRto{_F)EvZYu#cvuuhHλ+^DlMe_u!Nb'?Sc+@pJB@&/#ԔaM6B_"۳jSjѻOnJhNT=߂4g{̙{'#<_~򌬅<&?Ug~?n?OW)}}~XW鋍 ?^lևh/>sسN9Ku>d5A^x>F_ɷKh?R}ϯ~/g[ހ}%v_=! O۟E'^:1q~#v}{uһ̜:%9.ó'\YQngC{Or2g1?3d7 vN?ϓ iI<. s?G,Y9'(4\XS9͟)rSUm7R>}~9cojMmdgeu[>ǟz?3?}KxCLCwz׻G6ec\ S %tX%<=dVd eX ¦f⁚-oPuxuW3Ɇ|c&k,Xo qq6w^ W^u[}]\z饗\ W7hW_˯]}W\vɚ W_'~ .\sW_sp]{՗_ [YpE]_}7fE7^Ov]hoR֭@>)7bp~æ=yӆu!MCΕ_ 7lٶw=6tt5\)={_tM6n޶=\җھu3iz._#=]zuk7lKiA>׻4]{՗^(!Fem)U7@&X)T2(b /<{^U7m"L\DZL]ݺiM]ypaȞ}А4sAoxe]/Ѫ5W\ vIϱ 2'h^ru7߼ xN%w>Oo&!ICҔ j}6DEK[iKK'ze1 ij}WUv¶ `q7㯼6VWY-+]ue-Rz6RZhoH6#|9R20ǥ7۰y+z6oXw3y+[}1iJc=[ɧg9ҋC,k.#Mܽ~Fٰfp0Ӧ^H[|B6>8ŗ\"nkrDF]ED*]s\s5iGS=FEEk.˯.ZP ;ȄXH:tJUL6ʘqnD3l7c̸=8 aKL%Fpnje6U=Oר+TS=heԪqF:e V\5Cm .)ñШ1`{r^꺬0N2[`+ZVB}Ă5?֯V#c?cXj,{٨\QeJF޻_ݗ]{9WkusWq{]S'Cwԝmkz+w؟;=kط7koyϟ3 _?ͯ@h?O~Kկ~勏~#t-І'_?o_§Oa u7_} _#7Ͽg+gW>xoW^{;?̣~wmrľhÎN|_~zoٱ~ Nfkߑ_7moSݼ)Xs.;S ƜY 41+d, ,%MYz4"*4 sکE`rN;Ui4i'LOI>' &U61Тn+U[L#L&h,%2h, 21Xldf!34ఀ,gaV 3+'"!tsW_rUs%Ԁ%l厃#s[6_s4}YʍN?>5ub]n0Ї{3kz{_}'Ϟy<{֜[x~gub~?=t_OUshy4 ?ⱇ_%Ԝ5Y;<Կ;ԼIcgy5=M߷nmj}7iL?CW2\νrǞjznZM+ژ/ ٯm|奷>gFb?FkF?x_>Շnt9+Vo~'EL e7\X$>1\KumDk=Xkwޙ_oo;^Л;w|+L^G_[_ iΗ4CdTS CYͰP4lQ5KxUHpi?t7E}\S=U಄iMm fYdk ,^ nF3Qm]ǡ.\%4 ..SR n,ݐ0a`-eh\{&c)&`;K4Ѽ&`yW#[ak2uvXF2(C3.zLp>wfb*Ã4L]PdT=4Fi$ΖugJ.](dzp3e],\/Nc@Why!Cn+А [X9 h>q-6d0)۲*"뢋LB-0Z0Fq4a!33ϭsQiL?Vw e"Ķ]֖+%x )@5`LVu$V6GxRшYu:[BϳFVSse ZFU[HC~X{le-䥦Rid^D1m|-ϓeᶰվi hIl<ÖZp  !И %8Ex4#@5B5#OD>cS$Kɣ:Ft*a֎XIn/Eb@TaVЙC cS~&v]K5 ]ŰF- 6Zl!4l˴,:!'A PՓ(YF]02ɂ30 1 R=#D6?Jo|HX^&QLSP3/l-L׳,n.1;u =1ON6@qlbƦjS d Fi|T`H|G3NLuYkXxۘ KPt8Όb:sT\ [Pvip-,D'\b;*y}Jٵ5SkS[V4ԋD<7{4yb Mѫw嘑暭er̵tQ*fnf'A:feߕ= !)ˇO51?lrr}AY[ٜ_\axA*&b@@u"עaFxn] 6qanLׂcd`[xuFj0& glQe5_eGȂRh5-oH| !\;^G#lOJ/q:0߸웑\<8)w +)e:_;}9ĮfxD )2SN)M(dմ}A!vl:M?aȱNmpj=8.f i+:DM?^T6|ԁ4"'ۣE5VtiX85&"^cۢQ*v#$(nxBRܦhkr5?ÇPJ⩚KVxba$[쇊jD]:U\䅤z,R] >Bvbр )6ǵ@ȐZP6/0c6ZEDmֆ4WN M>xY#]?[8|•!f )}0 )*4>6pl7XХwGp"O &*JlQܔ]}|=}xH& ,򇲥\¦NG՜m!D8@{, RTQc!2J4xL4tL);WIJABd2B؉l*/s(  ۂmɅ"aBOEV8M J܀t:iNærgu2(@AAY ܧGvAw7/hz"p㒥YYJ.#Tq2Ϝw0wsv2gEѸ#ҳO؉IdMKdMc<IN%͝jn_wo:]R_t[2+Btȟ,>~:*σE+Ӄ~tё2{C~tw:S.!ui:Fv}p@:͏=I\ʖgr$=/LnNj&:-tzg< CŒ2:/u'င˜ttBAQY<*ay:U({dJ m.6)̤3 lܸ Te{o]vcHZaob+ jB8q=âGQ$Bda#/$r~-DOm|y`hB,`mDQc\ TPCEY"#kB[A8lY}蛖֫c1kR TI&?oSxm#o;ˤ{=!+f|rw8ӐJzCkVJ* ,\!ܡ ]_BwB1_47|o^ărD/GamQgW/3Np莧45U4z%dY k-P^5N n$?-=uv2In*&7MYvL>i^Zv¬vK5MH$ YI`4kzaŠtW@|;(̇:0RkGd:siÅ`!>bKyTlkbӥA<'M8[䨫&r4=娙O0QnCIzC7E rhùfX)Z\K,J_"(zpb䗡NT\wUéo:ʔj[$J&JQl2zMJϺ.U12u袈j[LNhe.Ʌ$vAr8h TjdaTHHf`-89HW7,]mG9-H oFjm-|NoKFO.P f,n}kUcO1}J8 2Y=\ILN?fkUXmyrcAumP;1%16MoŪ[fG.EƋVc8V _ǖ^9G"d{ o,VC}!O_+? ':#x!6}d,>=˯=N]L=-Yd;:!F&3V-hsĶZYby3KQ5%O>cC]l%X l<^YcgъH'5>fsjt67UUc#|s).zQUxtgbt= iC B̜@⍼4f— klp H#?HT% ^N[q Á[,׊Wƀ v]:ˆ#H]%v3x%,Aoaj<%FlXYgs20Uن`L|-m ÷K\l$y@=*gUɟ D2am\l)U,/f ɭ3&Sa,s.X2Pġ*Q SnrqnTS`#ߤkO9H/5bod&㘌(#]q,!KV_BD3ŅUʥ$496D0 ɸ&b.^ {Axp`#r$r@S* XV.A*#8~ 7$lSAXBQخ 8(D5 :pKG(fr@0WO&hQu|!Aǵ'Η*$չj/gA@PW쿜,1y%U<Ώr@{3-0)':BqRp>HB0dCl+F/GڲJX"o.d)V, /6BJBy!vtWŖ50=@B]UN`<݀uԝHH<3j>73|x8|Kh~i#LmV`Jaڴ^8c14<*]=wHR:ſ Com6o¿q@Ȁٞ m3- D~`srksyFOMr09p\o_JW}䮞1:"YeN4goΤإHafn_LLm7_BWtƣ}%=dzi_**X;j"oP)fj' (L8拇7O<֏0KW64MlK}e ҆x1`A:)+)tcy*eeX̰`HX;9NEdj+h #kx=%_S)JY\ &'5689̉2ЦLŘd@fe94)*=,tB=\0}.j"ԶKZf5^-C3MyC@@xUe:3SLac6Mn'}װE{dƕSP?(qg>!d=RL&Ɉ[ڈm渁 V;`&!VO6khu+z9NJlw L.s16|ْ6lNurrX!֘?&C(O˩\hK)ʨR*#k6Al(C"z8פMNPFT+MaYYXSr3Uo H#Nf2&S +MS&ݛ3pqHu:$vm%3Ӓ35RLj#Fָѻlr\of-[ՆX/~uO+;?G&؀>UI!恥r5 5xX]8,e.؃}=4NӗHrecg6oY c5T¬-E*-NյRv2/%#A֎_iCKƲt!MYbmXF'!B2PT MZP{2xpTHu[Q7DYA0̥gޮ@կIL `m C9s׺f`葡GT0K;xb5@x:_1N2뒃貼 7MzWź.Ca7Vw7r|P<6,Xs4eV=H=!;X:!z=H!Ewv8Hr##^Ov1A9 57qgr 2yb,@ÅYq&qى,ʒl3T'q?dW͖q:RG1WZc;$lXKӧbSU+0WSƬպ닓'$,Y0faf%HhL*q>uFKOW2`zf&jSp8'0iq<+Ktxn ABJsm|bvz?M6?JխfzHnی?* {J崠Rx2=Ogsl^1,=#òPrY4Kk4{bzfF2`6-b!5 ;q 'Fֳ(+hVLs'spw</?ݗ3䗞u0ݑ&o[n?wmܳ9տ;gmk0[:RDԡWŸwŸ^q=K}jHsf5|{p-왩]cu_wln-B};GߖN6:/5E%ή&vܶf:kwVaw+wܻ~z?w|殍r@88} ٫m;X}ÅJԶ]Ğ~ػcnojDˌoR) ^E^ߗ^7~Cwf/W<ڲȺ-y{o+q؞#=W=mݛv[iˤ _mwo^ȎۇtoзuotnEhuOwKrwo5ZzT-q%'`r09眡Mi9k}%9ۘ{|CcSJUJ(Q[i֙Š}J|[+'BT5JQcV^N?)-H; k;^e$R*2g7)cJʴQfj2|uV-4JdPִ>|٥lݖ}Q);sZ9(n˫ImV 弻(HIMʍ)AZW<92?DYM*RQ\e9a^UN{yT@A`o!U;*3*TaWU䪪R}Ts Rʱj#/yjP`QGZ늮Ԇ4<9ZINO$T>~>թJ5لյAݥn-ڠS{zZՋV((0Gr>iU5oi]i`GV`|D{&49gܢ):n͇tf`k4ӀY+frhS/aif2< U,/XvU_ab؀5Sws?k3԰kUΧ.n3k^@qf=iZsXYδS|~/}_c^,N{XtsV]ŝK6 untYuKOϤۖcyz{>;ә`W_RQkhK?/KџEAX|lIS-"d5df BcE:>KLF6z1sm9fakwScogӁqݸo2&o76s)59kꔻGTuL?etV}xY?V'̎LbYv}sY_'79_gڼm:_sc`-ʡc).w{LecXY.ߟՔ藭[(b[߱K!uZl嬿_ ,3ovےV VadjCQ455NuYv,/)0b ʞe{kugaw8:#K:Q5Z`zZ4N0q&ݓMC&)}\NW`.9irC^3\]Z4'ɩ9MxUl2[e1Q>y2 [h=_iƁϲbێ86qgP_(Ʉ V|bǯ~ǢX'^/d׽z Q)̊fjX7)wAW2 RSNA:ѹ./u_fWzL՗&CoQE?Va[h[cU R505}hY r2~խDh}6bֱܴݣ]^E61$.։/[Otדt&})LfaTNlmPۗ'cYd`)Il9rh*a [FikzGG=*?[[8{_ݕibp/}3_SM~6Fc3VkL/Z}fy6;g_ʹ'{kWOϼv߰ppL,~3wZV;r9gЎ7rW5۶k\[R珧i L۟w>kv*ݜ~P]십lcv;rd :__6<3{]!VHh}1w&eA|OUGӺ8ƬqlfOlT 8! ^睙TBky=v{tR'ү)6&h' !OgG@|w*O~Lv++zu 0U[91a޻7vK,ȄY\Z">&!U]'k; Q6Z`*s$:Wɣ[ d3\["E&]-ÅKszvyjVҌh-pɍ8Oݘ=u\d+z~Niia7ήNR@%WB.8 NmՒUOY(z]r=4V.QblJ]9v|y3iGه].5R?o3GVc,dޟbæbHT8'sR,Z4p+e꾯*{`%Gߣ=e1t~Q`++8cN)Q1OC+\\vA ~}M7ڔ^Vv6ךI`=*XTg9x=bʩ<0mMrkqGNCJNm6n8y`MażHzk[bKCNwuě܍LpC6E_Zwne"5F'R.ϧ+LRK[Nug֪rq$\}5W9t8ǽÞfNErta~a]jH>ةQ;A ,= W+PDllJ#>* g }&kOwggUY8_QIީ&c:ÿ{CrL18!A# vDm!$9hMS 5b:J3eۋy&9؃l0=R3kü9(00E5` 0T=N"e-/|U3tUx Oer}Z{k:cV\[H^eSY9O1{ϷƤ `y;n槙U`!اͻ#`/栥@ ;%+?~F{i?2Z^OD8|kzdдsTQZu#d -ܿ`)}|4_W`՘"a=%O9\L9K&vSoz ]]٨wjà%d)?Ebd.!D?P(&џFQOI]Y2^%uE*_0pQx\1zA M M S$ 'ӄ0f"8eAџ$ 7A-#ʠxNwNIbټ6(0Fb`e ؞r*> E 7j2Q6 i]m9(¸+eW#>Rq" bdrf-l=UG+y@m`=h]PbjY?5lZCU_ub(.j&'?[pž}kD&^|'ga#ҌmPI`MH"o!J PwF&P+S/i[Grx"@ 9ރZ TAy8Ys*~g\5QfQLM8Oe{%pܑu`JÀ4S˖) t&0"O?!F!FШΤ.5U*$XKo[!K+v&eSbiq2ls%(Hv<(kh;h-&6e0kKg02Jla%JD;'0G&, uֺ)ڞXSq®ؗk)h=r,:]&@QFSyJY,YYA2W\^j?fk~ Yh`(0of;f^60dGwx̵h^D ~JjL0EzC5D^> lŽx %)\R֏eF*QedheحSn0FS 牜\6&%h'jޑV#@q +Q8??Niѳdi, )y4/en t3lP&|wL!2<97q=_`>žZBG]rwTYV1{ۿ&PtQMz Sfj]wW37կlvYA6['ǎ%^ o vc2ou)2he?#r؂MV%\L~cM#w0 h \$~ T{o^WE_BOK 2ɅgoįO:ц$W&U4ckPp d'fd;J[RxC~*QK:ƏJXQo Ko;ήbDB0oՠΤjFۻp,cħE  Ž u2BAp6 RycMܥOl,dD;QJ8 ˦ 0.s1[UlISS$>:{HMA}^6Rfv?A:v'VNYj#.c4= ra&<{Dԑ UEcl/3bdD>7f%-:r5az:ɫ[)cYJun⻫BMW(Qh/EuIOx,??X*?S>AĹQwEQ+ `_%! 4c9;sn qrlZ TFKf2rl!9O6) |N7}RW{s838Go'7025y/NßiܥNeOg6 ;T0<0dO\@E/@| lk[?prsBԮyD lW)< 1%&UWz~p-߭ӣEh> 'VC]`3/Cܥ<wl0:]b9bg}ia>pCq R =z!;-4c88 l©ầføPsLp֓ܒ&;]|dC)>;91oL]Х.5v3g?}P͑l!T?֩?_TYLCdA\ɑǣ`X""IiohD kz(+epɌGPGrXK[9\U3`v.Sg. n_]=YWtmnjGSN7y{̆Le#0JN NA9|&O݋Og48saŦVلʧ_i^Ҫ4] M)-xف==ޭLꮓTKm58>e cc$t kRO:(42c}?fP0 wW51(<73܇JUS A5_*"kuXUdJi+3ƨ7,A{_kɛ葃,zޠFi&M6J?cxv Nݨ4,в4'" x#8AEp2(ࠍq4(:he+$Om]'`UI}i|>A%NtV֖E*04jh:ࠝ(4(p8~ x‡զAxJ u4(/kLڮؠ|\? ~ FAæ,rN/NU,iKFp\>:1~hA7~#Ohrōu"wP]PA-̠`R@ʁړNWpFi3x#z -S0.QkQز[%4sz\G 䠁\+iChPgU*A(Z{֯A+WZU\σAWL3$42* /SeLg}zȘXBO$Lnf4vlT՞ReBO0=w?w>OZeIE|A}~Zć d2/"=J,rщ<-.ko"WSaX {i~ѶtDiHN:1Sc9"ΙIOs  N?q$ulβY5BVcCc_mJ ޞC]Jer^a <q:7ǷGB*i~sZvͼB۳wٕG% ϤR[?w0F njl+t^eVm[g`ݱqQЅk*8vB_La}.@|PUfd$x  xbxrO.XZc3v?g,?sA^!m(,k!KX[ rg/u\bvF bx14g'i+==_={z\ѣn(mOOYS٢42=%dg]ptQHlsAtiNMXki\-Fzj-CbqY82hѪhϼ窉 0Aʑ04r_ԬZަHvp@hɏ!fi:M4f%$%}A`#3ǎwSU 魯Q4C$洙+0Y̜*턖wC?DAlژvQڰv0o^9ħ HsB/`s-n%e\ѓXMQLlF-γ\RK .[O¼&?SJ# vsJ~d#äbS/wEM:RȎ/:IL:wUguӴ\`yq01Uq%J1FFHBs$= qAVIo3sEq~8s`r;'j^++[V=';^;e4z'Q ߏn i[^a'[ #%rb&)7R-) g"|!b{j" ,)JtǮ|rHqsrH&tHmS jCAkR X,/Qԙd38<;V`+@XOǗvUO}*n`,EKr?=[dLgC9f/\dxݷK>EHb NHF~85($^nxJ~a%TR7|qtHLB 1:ō(S?"F-hX`G,^ådD4LMƹtoJsd endstream endobj 608 0 obj <>stream qGc|ϤnY\5bw)@RޚNEƫ 0~!hL: $c˓vMBn:w̆9Gp@eٳd=p{,_.%9Dw)w:a@{I7JJKs]kz jB |֬{b2eTՕNq`9 W-2Ĕ[x۷e1~vt&g ; PhX,mNS'}u6?7pbrЮ'rG#Si˰NإrɈ#^voCG`ݫp RKNyvcxYvdVU,Q1$YCUr(KI@N@WD C&7lAcx:岫tNqcRr?Ua'nUƉNW HLy.(NbJ;‰qj>L^T=Vn 3n{Q"2Lv2#2Ղã 콺H}>H"V,J%\yr}5і]:c@ADኯ ꠥ er52$9~e.,.U ު/Q0C(7_Oq·DPq%UlJFVxi;tF7|E=s#,t=#_'z2TeP}Q=Osz8AEgCQw{q=[^PvJߋ|1cIyW/& 9+mK99WY~z(dfBބ#,9̆gk (~pm֒ IޗdC[*hK,ׇD{: !/E‰ʱA{fFw‰kKដ[.ϯ|wR8Kc23?Onc] Ψ݃2"'lى{} j&G"uV]أ(nMI&EꁌՉqL~Aw_zSv#f;'J(<7SK&lNJ(4RQSML)[o꒙ 3w"ap/+(vDٵX`$Rnv_qJ"d'V:vȠ5l=+vQaw j jbvb[ZMӃ`_ ;ANZE3PMdP؏sURbT#>hdLJUؠۢ9N2]Pnvc&=gG M|b e@4v4:{.!xI:ʹr˷`ZQJFҞ0Vg~I_%~s%>|R<{}Y'9>rwo2suoNfHJɹKqew|tWy nEzﯦ{4s_5D^UM'TK'|?3tB1A~yN;E3㡅_[j:!P7oNȩ辶:aU NF^PM'g j:X;㽾N➫V qsG_QM'NhJ?vy*Nhut+tנ]j{cU yXW @/xy5iUtBt|j:1+jj:!dpeNF% j$=F#ryžo2 Ĕ< W$[Zū MIҺx_u!O7;rNw61t!Ý'2^27+SdSJwUVNG=^Q2S )%uIb=^WuIrMFWu v;$vޫکj|V!v d8BsE7%tGZJtnZúRsW}G﹧E OǵX}/2Gb7˘*}uܻO'c++L-i|SnSZp]!Qj[$0LZ-<%2 Þa.qMtW75YO.Zv-{bC`ߣ2%|Ć߸y [vRyoK SgW{q[fl*3[$Ǩ#JQoO>3f3}sf!~% [q6~#K>lo_NⴾDz&%N=)U+sXHcdnxID3D]hPFacWHYrĎĊ]ݹRPO-M;^&v"<1Pp9+u㮴/Uupbڿ]):X] J}U]QJ?+2/i^eid5bMrY}؃,.CxT%I1n{I2NvRi&v9^3Nnn 񒤃)+F ʱVSUHRMOAuBYR$ 7O>^v+C̃EO;q>ۓ'e֔)/.?K œJwDVun,W\YwW=3_p%nw5*)lhGȺI):IMpo'eM|)''Ur D&Um* `_Trnq/lz VtTH꡾~׏"7c}˹x1<Տ}tw͓TW?['"H3J=O:*`_?8-ɯy q}+\W]d ﭾ~҆!}d_?XF#?O=P_?)#a^O \_?NIVOZ9ܨOZ9<^Kbʄ^+76BBSe<92pOoo!/$ L* "X Ŧ+[%zt:},X@qtZmT[h_Re<eR4 XebXX-&|ז=&8l m?,L*(!dXTK$}&/' 2ޚ`h6^Jwvv6L~̖H;r1][x3p4|̓Â:VHLiѩJ$OzSʌ]2\>oO!\Omv9ۺcq`:^3",@awg"lW3.`,LOtk|CptŒ>95$36rK#w=Q37،~3YZ9~^p&T hlI53zvdYXp*]a֞O{6hulot-,ĢaV/O©xW$~}MmVnliӌ: 7h|㷁~(6IITa^{mBqDM} Z'rU\Op᳡T`$vW:ŋ΄!/2PK srah vv>vS_U7@%.bvG0_i>X=b{+E1=X ݮ*l}~2Uٞ5–pH`6eU0D>&6[|j3Dcv&  .4r/k% yH "s C"@ Hfl"+g-)`$:zMm{VR m璓M|,}|%0)7>;qƧg[z*,M LOpD [ݘn/Ԇq uVX8%"VJD+˿,GrQ2uk)S *~a,a(PnhUm&jT=SFupWi$0?:gLm wʃJ,`԰Mv,KԀѠ !pK m): .l&"G bΖ&pL 3@ zr"DHIa B aq4?}0? 0WJ޵ cedH ި#B d`̆g0@_%,Bn-s x_zVz4Z)'ʌ$AeRJ:$MM;5ƻ`~!R54&*ۍAc6듛c!2H?ɮ6;Se69(0Y8xa{S##g8>1tX" 4/:#>y繸L7T`v+ ʁ[`40A3f,f2Ncow3Q#M&=Fbfٰ!Ӄvt~ꣃqx1 7'CuCRi?vJ#gYoEnF࿴#kA5UM(@xS#`O94Wg =JgB݀`$}imZ)v+C@"&NTˍ1tu==t$bKSw$,π "ApRy\gV G&$-^yԃ~0Bz @ fo#gfټ`Dwsm) br$쌀 A| mW6af0Alr[ˈdD `^Āq%e?]+J~xx\gQ LB| D"xl&[4SyXI^No"~j*=u kVEH3@ق YJyԷb}6rDyثԉ>!l /wy[4E!^ q oF^nus>.c^cVxnowb\sju.|N-v?Kө/Np>#UH-MNx/3/g. ?لʧ_i^Ҫ4] M)-xe`z=g2'>7qO.`D!J!V"\c>]q{љ.$_XqW?]=JwJe+JKY֎oDi/Z[+,ṡf; ty 莑̴P?$whf5PI]U苤Zr9+C34ҳT\PF^gԃ%l(EG+2QJ,cQ#gcF ;aDJK6R@e8.&Rd[ks5iBB+d%ԓ.=??px3v _aX hh{U+9 aw.FerT>Ehk!3ܔއM{b gqe+H[$fCD8"->᫻|4yM;+Y*߳+҃4U P@:uhh)|n [21=}0CVry?4Mٞ@ E RB\.=sQ29r4G?2G{;"M¡)dCҊn7 Yul% ( TLHUf%Z־^Õrp-[H jlHv )Eb(J>ž2PP[*4ͣ0;&hɞK©"gW'DTGZyh+K\5W1GjʍTgaҏQf\p׆+,bo`Ƅ (qޘs'MH711kiǤl"xыv_&CR)#pzmN0) !A*xvdLYBy :b>cϒnٶM0 ϓF(=n7F)b0^cU?<@I%vj;ـ#egB/cO<^t2U)`i/1X|f\fHCƉfQ!0oо=kaLۿ>ĮL;,a^d \,|^qjv%NJUXeuS]]&-^4 d`3ZZ}6 ? t 4aSt`^zف7`4FZgcOԞk*(m+~ľQuB>C-ԦQ"{RO:en`:|Dw\̲,%+}r~;==>Y#*u6vr(aθֽmz"X΄v` F"Lsb֊CB//nݟbR]6XRt)H-tjgMױ\*0!E}5dM=q O!%(On58 џmPA)Հ#^6 O9&Q5V'8z, D~9fFSƜ`{pqh\9ü2wٖ5d=FenW0䫛hvAJäAʸgPo4RP `iirjvm+Nӡ*~ u#H;2WX ~pqa#q22f*wL>TD(vtV%Sa^?U}*,$#v]9:H -H$|Kx>a|^ i w?VAJ9Rt(lgCJ1RCw<=Q.ĸv~n33cw/cuxZ@*:H鎲r/O9 S (ٻQU]-NO?Ej(a+0y\(wƄ\ިEWoscM;=l0ǹ7Ә0Kxɫ[<IXo#]\Q\dȤE}*'9~~P9;A䰫Fޓ N e_V,n9?a%d922ًA&3&Lbfy;c+D]/41d̂*'T;nDjIt'P"ɠP$[hD }] [r# /ȡ.0yṮO8ϫsJvp<":hqͮbθҢUaOUi;\8+f$`'* ܕH.D>:+W:9J(MN(ǶZZ(qǞhCɖTVG7GtGV^euu QBg+0Y? U״|idωᗜC/n[#} S m 3k=jtUʢ,L2(+wQCW }Eg]ػ(9ʊ¢=(2my{P/==ȋ1 㫺>(*!.@VsfCEa1յ I='BqrF.#u_N Q(edNE: i2B|i2)NA&x ,.M[_/ iEFJ/ iEū (=xenkaqY\Aʇ,Jbe1t;ɿⒶrՔ%Ǟ-Ҷ,5 e]6}xHY,`ݻ(+"=o,nӁ7&^CY]Yl"e1tE6bs)+=Uʺz+J2E~ ]k\7QQCWCY ]ў7PIWjՙ2k I,=bb .b芎\9,}^HY|+DORّI)M@ch,/1O2Z38Zi{xy~ze1tԉ^z1t#k26*e ,*-.x(3ߘAzyψ04k3"dxp?!#)6##¼?x^.;A 邷N~(O$/ƥxJN~ؕ\bgQE(+U%xHF~ e1tŜDQFl2EY2NV&6O/,{(+{=eOyGY ]!]&b!@Y);8BY ])HY ]7辅7B\}ۍ28ߋ)+PCWs(+>b8~e 1e`@> ӷr4f1£4f{-*+->,V'Ch{ ycx=Mhʔ7uuq#4ꮛ׉aOam" u66NaF a$XTa.U[*|e1tE;(+]Еc%@0es{GĽa;"lFi]W]qGYB'uczyκ\uy݈ޟuHY7}Y7RY7(b`7wt403"K/FA*W e|x卿NF+[g_HY ]WCW_)*J!ʲĝgCb2#!3'Gc'$?$ѠIbߓOazXeCCmB!%9&91W%UgB06D$Oc{q$\ |۲h ARrPc;`Y9\Wo t{o{ [IPUoU0aumӍ!7LE=?1{bϗIsPVk'sȗ|od14K=p3uٸ99|q=wG%u]uӸUj'Lƪɠ5֗ޒR_;i?-M(~_V{}[yDEvϼ{yW/wܫϻzgs {y^}7,׋c ׿Vg7yP?d@{{y>g&Rno?Yq,OYq,<=/dzXoN49?:0c' +'|BMs;P]9ioNs}ۓ?aΨI?s[7' 9Ã9IO3#v_Yxp|+VM9mڬ^ɷLʽgЁ3Rl Z*&<6t96x&Dr7Vލ79o=۽w ,< (ۙ9̺[HUԀv0eWv#sNOxdW*"FPmcc˗/qc)~{``dl>Vt;_oVJˋ-k`Om#D^6/c ^{7Vf{5ɡo_[E~I yp2e<'Q쥌S(NrGuOb%\u~)ˬʙ6wVpѾ_iDQ3*,;G6;Hl:Rj\ukO͠hueg4>Xg,݈,Qskt%?]F=6D?ڣG'h/oHҖptZjGލH)²ݴ+Ul-[-j/-a~Z!@N۞2'mT&*V5I4p{k<-mVQACE!ṳi%s WHҬSVZFiߣAt׺Eݚ#YHv=USܑ4.xmAM#h܄H{4AR߄~M:` h=\/Qvz ([Bd k|η^@^B5 "UD= h>} ^:=wԧpU4ӾZ4o[JuG6Jz5EKuc22eYnEn%6P"FJYe`XMVX Ȁ8~wD~{}Л Gx!.b|/~Ћ%Ǹ 1~B/~͏z\_}[-qCS_I*I*I 2bQ6"5V8 "9x`)ي @#יaaE-p.Q>a*S,RHHjZx/D\|OP$P=Aͱ%*7^s![8QKţfdXKI^cvh{\/5Z^K$d n-ѢθOWNO0;5؁R*F PU D(2ϸˋWhs \w0ʒN-604*,s,H*QD\ۮaL "2s,'ъ`9$d$ R1䏀R]> %f6e-rx#!%YALh}̭ $n& ۰+&2@ŏW2uT D0RhˀaM 2̚lTʠ2maR(.00u*F`5G ܱy^XN1C;iz05 .p=@ckjD}H6 t&4:`b̋J0@ppIh Bw ɀ4 5K%ƴXY=W:B; 7;Pny0QAkf_ 0_4TH4U᳴c\\(JD, <<3.& wn'?@ğM&qBQ &%Ĉ].QpIO_*FS`9T-YAR\sa,,O_hB"Hz̓(}W,lK5j%0&Sh)bG+קfkP)ڇy* (Q&qO<蟛I0MP+b&Rwo[n*x@61mGv {bq$i ht^IĵJ,C2 SD'+yϬ_R1>!q@PZ (Xڂ04ǔ (̘`k>i"b)X#ڈsȂ9$?-2Tb $c!\AP=`jɚ:d*kUT(6Иo,phZ[)f$6SXtDqR7i.AE h0_4=Iznbx 8bvF]IQ5:r&1 D`K$4!tjP&]8M&D#Kw 7_}xѾo ;YF|pBd 0JiDCf層2PYO8v*\jD X7F0CR,%) .*i#7Ͱze[6Kh7} 5HGBȟ#r7y $Er>ݣ226r|^.!&hd \Cf|b1P3c(ǵU<q5`z5&&á`Mm8$YL% _8h&e  fJxm 3%A`bh8}_%\ ᄈ׾фQ5h'^Qq,#.>XQ\bfDhH# X0f V * fm0r o-5:0%2猝5a"@!- Q@$qAؒ@J2\`pq<3s&֞Z7i # QÊƘHYA}Z2 ΊD): s}81. &tc)s#y.ilv[ebv*R I8=H]N%, H6l A4c` %lij,Kdg\HS%+ &X\Pϳ ai0#Ycl5AװZXf$Me  ABږ2xZA73tl@TBL@Iׂ2i}B#yq' =(# s("HD=";}?%Yϰ " (@}d\ F#Gj2vp)</067,[`ô&,p(I|+j S9=AhNY"e8*!16=el#x@!&`1\k,K00+u|c>)<OkHkdgk7;bT{j^/G;cG!AK%Tҥ%U'O g[R$~-q?AjY]!D"y?:tu5-?^4k/nvF,AA r[.t : ?޼ݎNjw/OMÛ 7;$}w/;:%ͯo?wL2e&<_jRvX:[=|H~?+ߋ+>7VYeW &|ЯTo1vO_wh0~gԖX4Ww2P.rbn@(t`#! lc⊘ uPrmxϠmB4x9uy lZYW( V {bʼ&xrgߖMhUl5i`GBECI 3z3#ǖ!vcxxeAxAYLa1!E3(ʅ'Yb]R}X˩kN f#)ze.nK0bI}fQEaach(7[iibl9hMA*@F0uf ^NTj" \4pk`Fp ׁ>|9ļ9ol&g1h$m۔ +0u>2|BcP8D9~RQq,¸-\^uEs !A‚EV/!1mɎ]ֶ6`|8fӖ%G'gb̄@.!&Z|&b+IW{ĺ Ĉ@AOQq{56Sk ^3g+hXjI<@V<(%vNi6hƞ !)!YM6+w1Rhq|ZBﱻS!}0_hp-ћ1"Q+YdQ}]{Υs 5,bqo)CׄKZ>h|lD}67S ~F-@B`N"܁7cYB0ẊHPF& 4A_3Y-xĞz KO|6R> 32po;7u J0gA k/SK[ ؈3")>*B 2eъxNɕBQB]r-ce2qb/pE;FsQC@Y-0hͶl*%:JXzCzƃ%X`;f)XC$ٍܗwlAWGL %@4ݢteַ2P>+ƞ1xP;A$,X!5Ӏk( 5Ɨ2Q;Tzg^#.K0<.~W(@axp j큘4 -HpA`U.S>댮歇XvMu"Da ,3\[Ļ9 ^|p`\uT,I3fdq 6 ,% *du llrͶClArqJwa3eNqh2 6o%lO#, 9ۨ<(La۠b^`U b.#KgŪ 3\苼E\7AlF&֧ P bDuo'(>h͆.1,k}DIԁk4:bvW6\M̂CYmlaW3O 3PE('4-lQp4B;CyX׾, tZ<8c X VGFIlsh%6B_dU AhH<+k*nL% %Ba5ԉ#|a` nb3I" :h`5 o Iޔ NgH`8F)b!,lFKFgP:.NI0~ װn` L8ۇl(oQ&YmX!C$uֶ}]1o%ȇ0dp-Yl.3 {l@Lj$c0L.|6hzѰ"Tɛ8W.plTL cM L$|Y\)y5:)F혰c',a;'.nspk6_w*Ӈ R3e[c ylVk=jm޷m6HJkĖ}xXF7ƐD[aV@L/_R2 3𐋎fmg" 1Ya E,hYlbs V^ogfQ2=yv`6;FTWtEU$#J*wlc0F)Q c!(}#tld2/t4wl5NnNФ8h+웬Á+c_]8Ͽ-IY{Et4_7cŞB;4qFUP/MAzy W yύ]z6&Toƒ:I^ޟg*|ha+|taos۹۪.F^;clG?6\Qd+JۿG^GЗvH}ӻfJhuy"=~?:Owط7מhFmd ƃ~t3=; F&DWn-tͯjNJͻ=2;y?_.|ٜ]Jji~SW:ѣDyl*7j }땙rf$::t,1u^^y)H.Wre/ v{Ǭ&,8>&Ƿ}ag$[wqD3ѸuX)U%7zCUr*D1BcBz{h6)3 8ҙ:ةZU^mQMnZ=g'e'R}Tݔi6Nix漣r3EzMMҧ'bZsH)}>0v_ !ݘO1ɽDr})*7rP?dNgssmsrٳԸW[b,;K% JSOɻQon뽆(߇]rI:]Y?.O&GR:'ZZ08܌Vٌ9쭲e%x}.M1ݹ3Wru[BK] 1n{\KX{jꗕJZG@dⱒVˇăzJb.{k'n[gȗ}esL]N5bYqk%c4s/Gt+M4=sNDו0o܅ WJ|^ƱSRe7c.ES$ y֨8@=%՚|Lp1E|^B7\+YZxDhFK|seu2g.S0w9/dJg.mKLxN[OwӥH4|^l_gݍZF/lcg3%:k_`D b8Rk)/eۗR1w)zaKs7wTrvK%-?Zr(I_ڈ6sR5Rl_H,Hlӫ'"˵D+Tږ5-ܩJ>1ͺ$ʗi[>)NL:Q;{*c,Um^~Ew'}e\& [uR1rec\vy̮0.ƨ] ͂;ur$JAR{ݖvsrFgkihpnd! v"9V=9Ǚލg=.oA챨/^ .,/qo6 n/ͯ. Xo- }$net4S pS{oQ+<2Q|c~'\yccbzeQ+-EZ1\'[;L5[y[VNSV{sL&M.{v7=_[U;>iDUaһw뢾SS3~:GgʍB~+VHùzM>_wܕ77?fQ>|<]\7;%,UXo^_@gG}'FF{5s-էKCQQpiX/ue9Vs>G5gBrGrpU2Q! qTBG8*Q&sjB-|MNJ7Y6%!ӟ;Q2~kp,k:Q! qTBG8*Q&EY^*:{,۱{%x&k]h&B?tK#CQ,FSPƢM}QWa([)/ .B?HMXɋ e*i!% R3R@5R+K{ޙD*e4^N0ٳgju1-\tȇ\|ʜ?W\~z/Vś%S9Z;=ϞtRkR+'KElsotVZ[*7nFKߞlu K"߯L:VN& I~ama$CavU^6 Z/ϐ/J̺xIj1%RG&&gI_=*[@4_c-@46g*a@JVlxDžduRQki+b<O4V/ >'PCT }RO*I>'BԿ蓪Dee;hG]mXiZ˱繹>;ԕWEs-ɩM܏Dմ.^vrۦ9'[nBvxΜR8+sI@*=}53M|Z$t:@*ue-JG\B H@*R! TM u5&Nikykeɚ-˶ζ<ߟ1lxjK4r{l"_WM5#Ϛ{RR6 ]ib->#&!xdHe#uwT5uH@*R! TB HvdڽT3_ 4kV4S' zL( y\$WB:^۹[Q,$iVOHWCRR h sǥrKJO HUr>aF9`z4~yZ)Ҟ㎹B#YڇFU0o̅?\mB-H<$8)eηe9:f9C݌KWF'\HG?,&"w b" y4ۜD/cMmS=T٦eWieɣbcS;$SYCcGHETf!C"\iVПmI̥.}oz{;wJ,}ZS6vIG\m1Dq]u|;X%~GXe=>Rơø?S_SRґ.%T+RM_S}R9:BT Ss*tNΩ9o:^eſiY+MlڗM\ƣ2t#z.?⑚9 CN@p>]6z7v.Knr;CN> } G} IDJ!'DW!'D?CNn(9>Wj_9qdr5!:3#QN>#QECNΑGCN>CNڥ!'DrJ&Dg}HrE/|[+ne%DNn%$DrJMnVV+2Z+Nڤ*eisoGg"{'"/D9iB(\w#w֣<ώNBg[)BO~[? O:UT3SɩySa_1%۟HFNɹo]MMM^N) aoT'g殩+)L+)E}^N+)2RR4RowM kTpJw6ެ!"n9RRA>RRgTӀkTHtx{;6RR#^N) k)=~O+yc{_a핂MTѽRةTQR}|y>rE#)ůrR-55{CZMv43~ֶZȒX3IJU}R;)L 'aP*5}%s4J͑qYa#EIP7K=t*ga_1~a_1~a߿W[x)+sSi¦m^,\ܸj߷e¿iT,Bo D'MIgG-ǻsH !O0@#;l\,5)ڵ>d>#ƏQ^>)>ժgÉyHE  @ ՀB*>,HR R/b A*| zLjxxB:LUÃT=.\oCT#w}D F}P5&c;kXrv2<}$_Ţj߇TR1 Ҏ;JN_9+[s3ɇg̞p>5Z;LٗI%󛝕oW-]䛴P賝[qzuBrPL|-oa~a_a~a_a~KJx߼#Ua2{&Km]#ss*+'UhbvaNb N>yj N>Af'CN?C oPOpSCM?'B5lV N>AXL?'7DpՐOp pOp R~O5' 05&C*iZ#c;_Y_)ͅe_Op菦;vUk]$NkO4eel7]kÉ3o=8OW}hyOƢUwt{wO<ɣljÏP%2I@)g*6}R3Li^Md$/Y@!Sa:0_/L t~a:7>F:__oEc|&TV\~~h:w-k~TPbZ.J!{!cا%"$==ro*9}#$Vz}E?7Ka='z|L`*S! TB0L˹/^UC$3Ro<yZ9r]FoF.;ͱ[Cy2~-#WW+j2v?`J`KK0TLyvZDYx*Ax*3'5uT"be$&  „~aB0_/L&7=~QŅ̝96Y:۞HBKvMR7ϨڻUBA"j% ռҝݖUÞ76)|-ʲzmt,GMGNM֢ A-LnBi_Y*6}5WCgdHܩqBC3 z}*tBN :B'T P<יu^;Yؕm9Ob!}~eګ2z@nKOVd}<іeB4kOsuzqt 5u4 '[(J[RPS Z_)K2̏eӫ~F0*Q! aTB¨Fa0r՝tYMWYKOZ|ۋS8pqW46Ohj軥_:"U<rF9w{ lD9N iڹ(O,.<"80 ˞;_\(^{WF %!oGBmt/ؾ17>6: F %dJl F %τ?D % E %Ϭ辡1 F % MtPb8o0o(}#ѿ@6辡aD %fmtPbDJl_^ߏJly?#}GB~C/b+7&c,kśnzgX+O}nTĔ=Z:#zYLH Yի#-z>ObOQJkmQiWRYiRW_"5>Ph9' $\J$iTzTBT RW*J^+zBԿbI4SPWu&"+ۈ|&i]4֊Ndx$$ӪxX|ޚ~W-Q&G XnZHH9"$*iW맥<''E-ҝ5w(6ft&e.7.h"^)eRR1. ׹ʤAze9eUӞݑhPИp5xԡ%nxyTgQ[ʞVP/底|M?#MrZJwgy!8)\xu vӰl qZ [G}0V1m0SؿA\nlPwbWY7fpva8Qs#Sw*`JY߭<{Xjg=;@,M-|/:G$ٿXtL,K-YlfZ;Z=י_܍خXwdez<ُsϙI%>EEl"W]EDANH{RK+Ox>>Ga0Etq߂Xl~}Ԑ=j>Z:q}sMҺVS1kvOMvp͉+Ѭɶ,7 ZV̥׾:O+gUZbUS\=VũSVkwPG8))S3,+ue,:f-ﶱ>Wݍx:?! /D1BSA3Q{{)?(-aek̗X BsV,D-oaT6I=w%Z3 xQAb*JQPIg{W`ۭ7V!yۻvQN]>Wϕs\>Wϕs\?+'zJi\up"B޵Zz,J_+ܧtQn0;*?ZψlRLS j+7Du)-1} ퟐCK}4%58KIKIKIKIԟ4/Z|(3r*D=!m&SR8_vHQґXz8y{vDj 8J'B )&K.<qKll ؾ*F ǐRPMdpnspJ\R%\R%\R%\R%\RϒRܑxWLaQEw(=yRz"ApT.֝t.,=h@ٸe؇RgS6z" xr Zx51MLE.1S.1S.1S.1S.1'-4\xjB$⻹hC#@/h@vq}սE#X-ZSw O 6 @Jjrk)׶gIq^l:; ?0;6SSfb)&et² ',;I~av RA~av&f٩xq)avj=eq$d<>@8NA!?0;%!sB;NAYrOβS8w;,*i[*~O)-S0TC)WϲSPcO;O K\SI+f\BUN'Zԫ{I k8 exKjtYakQ:Xo29:KIa-c/ڽ]v}JP%!.@犦k*ibj%{qeb*=0T"`vJB;.;S.;S.;S.;S.;'٩?+iIf u{x6d [46+y :'BhnV vϕJU o v~J iXR"_Lmʵ-Cv@ zC?0Sݩmj[qoo3k\X ̚nG͊T&b>T0@0{5qvN|RG2ήo%EepD t#х%1X][1^8|hama-.9KɣONrc"@i uۛH͔?I%GxX*x3`o {%HDB(`m <`zMUSt8/_1: O]P'@8[݀ػZX֣8PL'<ЧwpۡQ O))<]NO)ilFe]]~b^D5I@<=XxOb/LfNb)/Ȇ¸U6.|C*xMUYclE䝣GdK, NDBWޒ] MۖM@ؼKiX>"kD"eb ),en =}m]T4tK9/"eý8r:~NI,'oph{p5Zu6' D*%\2A( vPK,=;Ҷ*ΡܑyhΙn7 $\fkva1ωyi;l@7[Sw}fk|J%_oYDP<L-d;/a w$q} h7DS׫1>xVg$2 Eff[${:"܀=V>s]^?krT)jɥ;cT ГˮwHxwb 63G@VMA6 D [6OgˍZ[kfp&>,ѦhKs0ʻؓ9ƾ㻇O!&wRi?<Վ$bq'{U c3 A0,&HpǙN in\op#^jcqFCzMKN/GHP-|p T1WY:zF8lK*o>-D ߀SS) |Zp~ca?iaZ|_ {wulgI/"gRq)4.e yM:U п.([yIlX/E0NÙq/>)ݮGKuV` ӽt,.u6G<x]Zۗ8)_Q%鬔 sPmpx Rqf,/Sd $}r Ie[zWk'j)仑oWvUʯ^b\&\Y>¹o 18rbRfV./M^."]z |\H#[p(]%SOп|#eL2C2,e@a@hֻgR6 [k6pO.Ҙ߫w /  .Ү#\TNլ- t%a݋jr.O)sk.6`#؍6ū M8\eĮ -TUKmT :Bʸ[ypAoB=1D,7]wbY9PpdO&"l{]w-m6?Ef{t ,GJwɿ^*#C[vH9^ٜIБ7I|ddc@n(p˻Ne)J>)(nJ5C1DLY80) >GGהwLymD@'ή'1f٭?NW?'םl,}ew8w \. |֊S|C^ߘ#\-65Kˤ(`s | nwy4\6v&4%6'W*KvO'ŸH?s2(?(^"alI8w,KE˓ȒII]YGeIk3#?AL|ܕqN7Aoom ytշ [ BtNsj쒥Z'uZɭ=ssLC-t2j+~7Oq4w nvi.ĒaH+ק2>% a.)Z`O7۷92X#hEK;3ΉV7\oDSV&/֍INR0ugxU^J,a^jFI9Ka*ԌqTnRpy)Ld[䁱INR%楦5R߷ ^ y)T/,7}$/)y)L9Kt|/eyזTvYRd~Z5xmB|p"N䎆60oH34GջKyWd47=ZKQ?ħDSvbh+TBSRS*WҔM4'>MYzaY>\4)MhES.rє\4T%:GE64(P(=66]*_®ÍNh갪N.a.9g9QC'h @CkS4䦪I4h  _lX] tpSp߷h*2)kvՃQ/R'gɞ_Efn׏ح ]A۽(>aG-?_ujx5~DpO zS: /7GbV.Ƈz tw [|8ޔ.\)Wo՛r\)Wo՛r\?7ؼE +uY-I lkh80^Qg1|X:ly9t&)h;6ޔ)@' ~NX̯6X2, !wGi?a !~P;:߄z^D›4/TߜrbS9Rb7NnY*v}F8R񲰍t UfvgTbⲄv|<ӶI_ze‡1KaɕJ90ϊ@C~J0Љ2Q+VC2Wg"؏J7B<-08=jk;JPIz `rԨqHIJ?rœ$$=%uΜ$eTX* A%)tCG <> *IOA8KPIz kQJST&؏9KPx$YNA] *R}]ԨN~IeJFqU4w{xwqC38M7Ic{+cuj,ү\-h_2kBC.!"SIE0оحV'~r *r *r *r *'0̟[Tk G`@Ge>@O⨈uK(6)aSZpv?5 _953<ͩ95IS"4)iqJ6ũ-lNIS2'mN#lNI`4u攴8erYSx|ۜ`w9ksJT9%-Ny|ۜaFdlN=؜Bm\ ڜ21`?.ۜi,iPvct6ZɎ/dOtY7l&x!衫j.Wn'wF-[]nst~)12stT nj_ Fm<n}l_*-"{R 0,Nэ'c] ȹ\S)kqʵ8Zr-Nũ-}Žq<bDV2}!8^=s#jj;kWQ X&#A`& @|:PbF0R[$"Grs`9}\N\N\N\N$'u*+A"Z}ko{zG葋++7HTW[tBxoq^77n >|#J(gÎw F3 7/ԕGU;Un^I/`2j=/ᯢ |ɨ!*߇Dۑ3SIVAx!u9.S> EBs!>8K(‰Y|5 f]mh\g]LTL3fQ̽|3.pԜW|fVfAd6KY|5*SJUWh̭Ƨ>pnjn,g8KOV@o`ʭ|֬T1-\ZcZ>p̎a: 3z&f}'sk`3+Xơ]iƴYœv ecYn'1 gͭQ[7M$S:ߴg/蒩΂cgybG[s8P8_80!4=/ W}@-a.WȾ Jǿ3o#0Q\|ʚ="SVe~h0MΈV\8vUlnҨ]./Ӓ.Ǔ=ħ)ijaôr\,s[˞9诘1(VE"T}o8[><Ctt5fOVFp2nV/#fIwR6X.dV+@@MM @1qy] t-DC^kE[9\WW[UX=W*NEA4q<(^u3UD&,CD͏`0_q"I?Q0@ftԆ0! :ͼ K8nA`z&\ًJ}V/C-VNj%/*w}pB&O!l 1?-s~Z6h~̑ bY ڷFT֬Eѻ#w:ܚ!۲bL/b4,z0 aɆZ8bö!wV'Rc :nE;A@,sǪV9 ]!dZ]V;w$I vmپݬ nbsj/Al}M@HJ,v-/[ lNÆ0K::Rwscz?\\!{8_,~lDBט\/CSŤ#OdHh3\ eZ>IGmmgH%#B,)f =2z9oF׽o$_dc ӂJv&DPK66tg`e{هm؈nmLJKQ.F`Id7rxZmK~;1]D 2|^I1:4S fiuy|B/D_P$hƹt1[`<" a%~S{!:UTBDQ]Sn/` y-լᶧDmSbG^ v9B 7&Xo3oݠ|x9)w ]8#w7܍ DnۯpRf& "َHwXS0nd[&IK9,w3x|l ݠ̿5x|N6%o䍣r7=ݾ#nLsMkKSA0K+_ |+L K><bݐFuZm=Kt+$x8Xj#30x\z_!C/!+-,1*ڿa1>gyaH fB e\e\e\e\e\ţVr+IeW v@jNho:GkZ=߿y]Dmޟau3Lק4t@GmsJ/HXN56[3 p,ew7W''}qdj4(VA3+\[弎Il"efHo\jxܞ[@`M7֢fP2쎌vJy=漪, 4IC fmlǽOqFΣ&j2zȓ7legX_޶c^T؆2O*rIy|}N!DBFR9,,Ga$uR#)ܮA8DrI!ٵ: P9⯡;`_/!$I,08vKÜERhHX9$%a=*1I`KR$<'Y$k?]$I,H VaF{~6ܯ꣇K'Hօ4kd2D5|  X7?<dAxus2,Ni\@w AUF`E cU]Esͨ^(o61' j&g#*7/o&_ˉGhDsz',ydk70 =됌PP<#J:~J4UI'T!4NqLpE6Uq`͉o _j֓s0UfM(xk#dL;%` .X|9e P3kiD[ѡ﯀( UX40aCa4bz0ݨ&L`8pD;fq > :ʲcZ3̓'c[m$)SLdz /@!4+0d4}'v|T>7G?͕`R4e=ja3\w7d< 'l endstream endobj 783 0 obj <> endobj xref 0 789 0000000003 65535 f 0000000016 00000 n 0000046524 00000 n 0000000004 00000 f 0000000006 00000 f 0000059667 00000 n 0000000007 00000 f 0000000008 00000 f 0000000009 00000 f 0000000010 00000 f 0000000011 00000 f 0000000012 00000 f 0000000013 00000 f 0000000014 00000 f 0000000018 00000 f 0000046575 00000 n 0000059428 00000 n 0000059459 00000 n 0000000019 00000 f 0000000020 00000 f 0000000021 00000 f 0000000022 00000 f 0000000023 00000 f 0000000027 00000 f 0000046646 00000 n 0000059312 00000 n 0000059343 00000 n 0000000031 00000 f 0000046718 00000 n 0000059196 00000 n 0000059227 00000 n 0000000035 00000 f 0000046790 00000 n 0000059080 00000 n 0000059111 00000 n 0000000039 00000 f 0000046861 00000 n 0000058964 00000 n 0000058995 00000 n 0000000043 00000 f 0000046932 00000 n 0000058848 00000 n 0000058879 00000 n 0000000047 00000 f 0000047003 00000 n 0000058732 00000 n 0000058763 00000 n 0000000051 00000 f 0000047074 00000 n 0000058616 00000 n 0000058647 00000 n 0000000055 00000 f 0000047145 00000 n 0000058500 00000 n 0000058531 00000 n 0000000059 00000 f 0000047216 00000 n 0000058384 00000 n 0000058415 00000 n 0000000063 00000 f 0000047287 00000 n 0000058268 00000 n 0000058299 00000 n 0000000067 00000 f 0000047359 00000 n 0000058152 00000 n 0000058183 00000 n 0000000071 00000 f 0000047431 00000 n 0000058036 00000 n 0000058067 00000 n 0000000072 00000 f 0000000073 00000 f 0000000074 00000 f 0000000075 00000 f 0000000076 00000 f 0000000077 00000 f 0000000078 00000 f 0000000079 00000 f 0000000080 00000 f 0000000081 00000 f 0000000082 00000 f 0000000083 00000 f 0000000084 00000 f 0000000085 00000 f 0000000086 00000 f 0000000087 00000 f 0000000088 00000 f 0000000089 00000 f 0000000090 00000 f 0000000091 00000 f 0000000092 00000 f 0000000093 00000 f 0000000094 00000 f 0000000095 00000 f 0000000096 00000 f 0000000097 00000 f 0000000098 00000 f 0000000099 00000 f 0000000100 00000 f 0000000101 00000 f 0000000102 00000 f 0000000103 00000 f 0000000104 00000 f 0000000105 00000 f 0000000106 00000 f 0000000107 00000 f 0000000108 00000 f 0000000109 00000 f 0000000110 00000 f 0000000111 00000 f 0000000112 00000 f 0000000113 00000 f 0000000114 00000 f 0000000115 00000 f 0000000116 00000 f 0000000117 00000 f 0000000118 00000 f 0000000119 00000 f 0000000120 00000 f 0000000121 00000 f 0000000122 00000 f 0000000123 00000 f 0000000124 00000 f 0000000125 00000 f 0000000129 00000 f 0000047503 00000 n 0000057918 00000 n 0000057950 00000 n 0000000130 00000 f 0000000131 00000 f 0000000132 00000 f 0000000133 00000 f 0000000134 00000 f 0000000135 00000 f 0000000136 00000 f 0000000137 00000 f 0000000138 00000 f 0000000139 00000 f 0000000140 00000 f 0000000141 00000 f 0000000142 00000 f 0000000143 00000 f 0000000144 00000 f 0000000145 00000 f 0000000146 00000 f 0000000147 00000 f 0000000148 00000 f 0000000149 00000 f 0000000150 00000 f 0000000151 00000 f 0000000155 00000 f 0000047578 00000 n 0000057800 00000 n 0000057832 00000 n 0000000156 00000 f 0000000157 00000 f 0000000158 00000 f 0000000159 00000 f 0000000160 00000 f 0000000164 00000 f 0000047652 00000 n 0000057682 00000 n 0000057714 00000 n 0000000168 00000 f 0000047727 00000 n 0000057564 00000 n 0000057596 00000 n 0000000172 00000 f 0000047802 00000 n 0000057446 00000 n 0000057478 00000 n 0000000176 00000 f 0000047876 00000 n 0000057328 00000 n 0000057360 00000 n 0000000180 00000 f 0000047950 00000 n 0000057210 00000 n 0000057242 00000 n 0000000184 00000 f 0000048024 00000 n 0000057092 00000 n 0000057124 00000 n 0000000188 00000 f 0000048098 00000 n 0000056974 00000 n 0000057006 00000 n 0000000192 00000 f 0000048172 00000 n 0000056856 00000 n 0000056888 00000 n 0000000196 00000 f 0000048246 00000 n 0000056738 00000 n 0000056770 00000 n 0000000200 00000 f 0000048320 00000 n 0000056620 00000 n 0000056652 00000 n 0000000204 00000 f 0000048395 00000 n 0000056502 00000 n 0000056534 00000 n 0000000208 00000 f 0000048470 00000 n 0000056384 00000 n 0000056416 00000 n 0000000209 00000 f 0000000210 00000 f 0000000211 00000 f 0000000212 00000 f 0000000213 00000 f 0000000214 00000 f 0000000215 00000 f 0000000216 00000 f 0000000217 00000 f 0000000218 00000 f 0000000219 00000 f 0000000220 00000 f 0000000221 00000 f 0000000222 00000 f 0000000223 00000 f 0000000224 00000 f 0000000225 00000 f 0000000226 00000 f 0000000227 00000 f 0000000228 00000 f 0000000229 00000 f 0000000230 00000 f 0000000231 00000 f 0000000232 00000 f 0000000233 00000 f 0000000234 00000 f 0000000235 00000 f 0000000236 00000 f 0000000237 00000 f 0000000238 00000 f 0000000239 00000 f 0000000240 00000 f 0000000241 00000 f 0000000242 00000 f 0000000243 00000 f 0000000244 00000 f 0000000245 00000 f 0000000246 00000 f 0000000247 00000 f 0000000248 00000 f 0000000249 00000 f 0000000250 00000 f 0000000251 00000 f 0000000252 00000 f 0000000253 00000 f 0000000254 00000 f 0000000255 00000 f 0000000256 00000 f 0000000257 00000 f 0000000258 00000 f 0000000259 00000 f 0000000260 00000 f 0000000261 00000 f 0000000262 00000 f 0000000266 00000 f 0000048545 00000 n 0000056266 00000 n 0000056298 00000 n 0000000267 00000 f 0000000268 00000 f 0000000269 00000 f 0000000270 00000 f 0000000271 00000 f 0000000272 00000 f 0000000273 00000 f 0000000274 00000 f 0000000275 00000 f 0000000276 00000 f 0000000277 00000 f 0000000278 00000 f 0000000279 00000 f 0000000280 00000 f 0000000281 00000 f 0000000282 00000 f 0000000283 00000 f 0000000284 00000 f 0000000285 00000 f 0000000286 00000 f 0000000287 00000 f 0000000288 00000 f 0000000292 00000 f 0000048620 00000 n 0000056148 00000 n 0000056180 00000 n 0000000293 00000 f 0000000294 00000 f 0000000295 00000 f 0000000296 00000 f 0000000297 00000 f 0000000301 00000 f 0000048694 00000 n 0000056030 00000 n 0000056062 00000 n 0000000305 00000 f 0000048769 00000 n 0000055912 00000 n 0000055944 00000 n 0000000309 00000 f 0000048844 00000 n 0000055794 00000 n 0000055826 00000 n 0000000313 00000 f 0000048918 00000 n 0000055676 00000 n 0000055708 00000 n 0000000317 00000 f 0000048992 00000 n 0000055558 00000 n 0000055590 00000 n 0000000321 00000 f 0000049066 00000 n 0000055440 00000 n 0000055472 00000 n 0000000325 00000 f 0000049140 00000 n 0000055322 00000 n 0000055354 00000 n 0000000329 00000 f 0000049214 00000 n 0000055204 00000 n 0000055236 00000 n 0000000333 00000 f 0000049288 00000 n 0000055086 00000 n 0000055118 00000 n 0000000337 00000 f 0000049362 00000 n 0000054968 00000 n 0000055000 00000 n 0000000341 00000 f 0000049437 00000 n 0000054850 00000 n 0000054882 00000 n 0000000345 00000 f 0000049512 00000 n 0000054732 00000 n 0000054764 00000 n 0000000346 00000 f 0000000347 00000 f 0000000348 00000 f 0000000349 00000 f 0000000350 00000 f 0000000351 00000 f 0000000352 00000 f 0000000353 00000 f 0000000354 00000 f 0000000355 00000 f 0000000356 00000 f 0000000357 00000 f 0000000358 00000 f 0000000359 00000 f 0000000360 00000 f 0000000361 00000 f 0000000362 00000 f 0000000363 00000 f 0000000364 00000 f 0000000365 00000 f 0000000366 00000 f 0000000367 00000 f 0000000368 00000 f 0000000369 00000 f 0000000370 00000 f 0000000371 00000 f 0000000372 00000 f 0000000373 00000 f 0000000374 00000 f 0000000375 00000 f 0000000376 00000 f 0000000377 00000 f 0000000378 00000 f 0000000379 00000 f 0000000380 00000 f 0000000381 00000 f 0000000382 00000 f 0000000383 00000 f 0000000384 00000 f 0000000385 00000 f 0000000386 00000 f 0000000387 00000 f 0000000388 00000 f 0000000389 00000 f 0000000390 00000 f 0000000391 00000 f 0000000392 00000 f 0000000393 00000 f 0000000394 00000 f 0000000395 00000 f 0000000396 00000 f 0000000397 00000 f 0000000398 00000 f 0000000399 00000 f 0000000403 00000 f 0000049587 00000 n 0000054614 00000 n 0000054646 00000 n 0000000404 00000 f 0000000405 00000 f 0000000406 00000 f 0000000407 00000 f 0000000408 00000 f 0000000409 00000 f 0000000410 00000 f 0000000411 00000 f 0000000412 00000 f 0000000413 00000 f 0000000414 00000 f 0000000415 00000 f 0000000416 00000 f 0000000417 00000 f 0000000418 00000 f 0000000419 00000 f 0000000420 00000 f 0000000421 00000 f 0000000422 00000 f 0000000423 00000 f 0000000424 00000 f 0000000428 00001 f 0000049662 00000 n 0000054496 00000 n 0000054528 00000 n 0000000432 00000 f 0000049734 00000 n 0000054378 00000 n 0000054410 00000 n 0000000436 00000 f 0000049811 00000 n 0000054260 00000 n 0000054292 00000 n 0000000440 00000 f 0000049880 00000 n 0000054142 00000 n 0000054174 00000 n 0000000444 00000 f 0000049949 00000 n 0000054024 00000 n 0000054056 00000 n 0000000448 00000 f 0000050018 00000 n 0000053906 00000 n 0000053938 00000 n 0000000452 00000 f 0000050087 00000 n 0000053788 00000 n 0000053820 00000 n 0000000456 00000 f 0000050156 00000 n 0000053670 00000 n 0000053702 00000 n 0000000460 00000 f 0000050225 00000 n 0000053552 00000 n 0000053584 00000 n 0000000464 00000 f 0000050294 00000 n 0000053434 00000 n 0000053466 00000 n 0000000468 00000 f 0000050363 00000 n 0000053316 00000 n 0000053348 00000 n 0000000472 00000 f 0000050436 00000 n 0000053198 00000 n 0000053230 00000 n 0000000473 00000 f 0000000474 00000 f 0000000475 00000 f 0000000476 00000 f 0000000477 00000 f 0000000478 00000 f 0000000479 00000 f 0000000480 00000 f 0000000481 00000 f 0000000482 00000 f 0000000483 00000 f 0000000484 00000 f 0000000485 00000 f 0000000486 00000 f 0000000487 00000 f 0000000488 00000 f 0000000489 00000 f 0000000490 00000 f 0000000491 00000 f 0000000492 00000 f 0000000493 00000 f 0000000494 00000 f 0000000495 00000 f 0000000496 00000 f 0000000497 00000 f 0000000498 00000 f 0000000499 00000 f 0000000500 00000 f 0000000501 00000 f 0000000502 00000 f 0000000503 00000 f 0000000504 00000 f 0000000505 00000 f 0000000506 00000 f 0000000507 00000 f 0000000508 00000 f 0000000509 00000 f 0000000510 00000 f 0000000511 00000 f 0000000512 00000 f 0000000513 00000 f 0000000514 00000 f 0000000515 00000 f 0000000516 00000 f 0000000517 00000 f 0000000518 00000 f 0000000519 00000 f 0000000520 00000 f 0000000521 00000 f 0000000522 00000 f 0000000523 00000 f 0000000524 00000 f 0000000525 00000 f 0000000526 00000 f 0000000527 00000 f 0000000528 00000 f 0000000529 00000 f 0000000530 00000 f 0000000531 00000 f 0000000532 00000 f 0000000533 00000 f 0000000534 00000 f 0000000535 00000 f 0000000536 00000 f 0000000537 00000 f 0000000538 00000 f 0000000539 00000 f 0000000540 00000 f 0000000541 00000 f 0000000542 00000 f 0000000543 00000 f 0000000544 00000 f 0000000545 00000 f 0000000546 00000 f 0000000547 00000 f 0000000548 00000 f 0000000549 00000 f 0000000550 00000 f 0000000551 00000 f 0000000552 00000 f 0000000553 00000 f 0000000554 00000 f 0000000555 00000 f 0000000556 00000 f 0000000557 00000 f 0000000558 00000 f 0000000559 00000 f 0000000560 00000 f 0000000561 00000 f 0000000562 00000 f 0000000563 00000 f 0000000564 00000 f 0000000565 00000 f 0000000566 00000 f 0000000567 00000 f 0000000568 00000 f 0000000569 00000 f 0000000570 00000 f 0000000571 00000 f 0000000572 00000 f 0000000573 00000 f 0000000574 00000 f 0000000575 00000 f 0000000576 00000 f 0000000577 00000 f 0000000578 00000 f 0000000579 00000 f 0000000583 00000 f 0000050521 00000 n 0000053080 00000 n 0000053112 00000 n 0000000584 00000 f 0000000585 00000 f 0000000586 00000 f 0000000587 00000 f 0000000588 00000 f 0000000589 00000 f 0000000590 00000 f 0000000591 00000 f 0000000592 00000 f 0000000593 00000 f 0000000594 00000 f 0000000595 00000 f 0000000596 00000 f 0000000597 00000 f 0000000598 00001 f 0000000599 00000 f 0000000600 00000 f 0000000601 00000 f 0000000602 00000 f 0000000609 00000 f 0000074725 00000 n 0000074801 00000 n 0000075002 00000 n 0000075965 00000 n 0000085088 00000 n 0000150677 00000 n 0000000618 00001 f 0000059544 00000 n 0000050604 00000 n 0000052962 00000 n 0000052994 00000 n 0000068138 00000 n 0000050676 00000 n 0000052844 00000 n 0000052876 00000 n 0000000622 00001 f 0000050753 00000 n 0000052726 00000 n 0000052758 00000 n 0000000626 00001 f 0000050822 00000 n 0000052608 00000 n 0000052640 00000 n 0000000630 00001 f 0000050891 00000 n 0000052490 00000 n 0000052522 00000 n 0000000634 00001 f 0000050960 00000 n 0000052372 00000 n 0000052404 00000 n 0000000638 00001 f 0000051029 00000 n 0000052254 00000 n 0000052286 00000 n 0000000642 00001 f 0000051098 00000 n 0000052136 00000 n 0000052168 00000 n 0000000646 00001 f 0000051167 00000 n 0000052018 00000 n 0000052050 00000 n 0000000650 00001 f 0000051236 00000 n 0000051900 00000 n 0000051932 00000 n 0000000654 00001 f 0000051305 00000 n 0000051782 00000 n 0000051814 00000 n 0000000658 00001 f 0000051378 00000 n 0000051664 00000 n 0000051696 00000 n 0000000659 00001 f 0000000660 00001 f 0000000661 00001 f 0000000662 00001 f 0000000663 00001 f 0000000664 00001 f 0000000665 00001 f 0000000666 00001 f 0000000667 00001 f 0000000668 00001 f 0000000669 00001 f 0000000670 00001 f 0000000671 00001 f 0000000672 00001 f 0000000673 00001 f 0000000674 00001 f 0000000675 00001 f 0000000676 00001 f 0000000677 00001 f 0000000678 00001 f 0000000679 00001 f 0000000680 00001 f 0000000681 00001 f 0000000682 00001 f 0000000683 00001 f 0000000684 00001 f 0000000685 00001 f 0000000686 00001 f 0000000687 00001 f 0000000688 00001 f 0000000689 00001 f 0000000690 00001 f 0000000691 00001 f 0000000692 00001 f 0000000693 00001 f 0000000694 00001 f 0000000695 00001 f 0000000696 00001 f 0000000697 00001 f 0000000698 00001 f 0000000699 00001 f 0000000700 00001 f 0000000701 00001 f 0000000702 00001 f 0000000703 00001 f 0000000704 00001 f 0000000705 00001 f 0000000706 00001 f 0000000707 00001 f 0000000708 00001 f 0000000709 00001 f 0000000710 00001 f 0000000711 00001 f 0000000712 00001 f 0000000713 00001 f 0000000714 00001 f 0000000715 00001 f 0000000716 00001 f 0000000717 00001 f 0000000718 00001 f 0000000719 00001 f 0000000720 00001 f 0000000721 00001 f 0000000722 00001 f 0000000723 00001 f 0000000724 00001 f 0000000725 00001 f 0000000726 00001 f 0000000727 00001 f 0000000728 00001 f 0000000729 00001 f 0000000730 00001 f 0000000731 00001 f 0000000732 00001 f 0000000733 00001 f 0000000734 00001 f 0000000735 00001 f 0000000736 00001 f 0000000737 00001 f 0000000738 00001 f 0000000739 00001 f 0000000740 00001 f 0000000741 00001 f 0000000742 00001 f 0000000743 00001 f 0000000744 00001 f 0000000745 00001 f 0000000746 00001 f 0000000747 00001 f 0000000748 00001 f 0000000749 00001 f 0000000750 00001 f 0000000751 00001 f 0000000752 00001 f 0000000753 00001 f 0000000754 00001 f 0000000755 00001 f 0000000756 00001 f 0000000757 00001 f 0000000758 00001 f 0000000759 00001 f 0000000760 00001 f 0000000761 00001 f 0000000762 00001 f 0000000763 00001 f 0000000764 00001 f 0000000765 00001 f 0000000769 00001 f 0000051463 00000 n 0000051546 00000 n 0000051578 00000 n 0000000770 00001 f 0000000771 00001 f 0000000772 00001 f 0000000773 00001 f 0000000774 00001 f 0000000775 00001 f 0000000776 00001 f 0000000777 00001 f 0000000000 00001 f 0000071475 00000 n 0000071512 00000 n 0000068252 00000 n 0000068648 00000 n 0000060267 00000 n 0000197228 00000 n 0000068910 00000 n 0000074161 00000 n 0000074211 00000 n 0000067924 00000 n 0000001203 00000 n trailer <<218D9257ADCA41849C96DA42A790832E>]>> startxref 197363 %%EOF Pylons-1.0.1/pylons/docs/en/_oldstatic/pylons_as_onion.png0000664000076500000240000005357011645401275023627 0ustar benstaff00000000000000PNG  IHDR*utEXtSoftwareAdobe ImageReadyqe<PLTE>;;LLLppp@@@,,, 000PPPfffnmn```XXXxxxֻhhh1-.hef# (''888___ߠǑZWXZWWȃ][\?;2=RCkE\GV?/5w{n׊y,W}N*2VZWB2kBO%јK-anRԙ*{x:rȸIzszW//U֟@Ѯ K7|cEWo6ߧo:>LKN`9oAwY|%xY;. k1^ :Ujw^^C-P%ox_vtԶ.Ӓ4{iWV$]gEGt_žw-BZ] Kw]=}Wk {lxC&w8`︨uGTm=FF;?s܆7_|Đv{WdwVx+q 7GFwxȭ=^}xuxi_$0jF( /~aپNsr{0ܿ CzQ9)_ru5})T5|:x[+wRWS%ty_äo*=Q6c~\/w a hEB7$oKP)YY7۲VoxxLgƒT5KGĤ'WSMj6lN۬B㚌GΌr 幩R[%/j &g9! Zb^i>Ivxa@)FeDҔ\w"Ƶ .9c6JR$^o=xk9֏<{գIQg By-x3WbsV˘xwL=^ Qbk`~X7u>I孑 ds9; FV M@5SP6u69~{A[+߈;°vUKI^Fcċjo~ B{M1SYy_Z4\z.NJ%{|SXgob֒_:/o0;gDP_=iWz㜌N+`\+e2\n}c›$)-~~gLƀM`CfAȢ<9dJ~Z+r:P&%ya\Տ4h .(^!&;Ȃ8.+ b{Er> /HG5aO~](El¨X!+ӟى6co}*"RS"j*WY(v.d|^U~^BlZN#H'.:ehPdgJڕ@~ _0H#x &9nsCjeq_>{%vYWm5ȫ$: \x˥ xlZҹuEl(\$\.ezOc-WIcx8RyP3׺#g7D.+G.:ތ2W~/򷡙|al9 7;Ю)"46O[b[OA[QNyşJ-_-Oh[۱V3 V,7)$(X@U=OOvYWȒ4=J恺?[x21&qx S0lgom`tez E'xW)R)B%\h8ZsC; ^&J-3`iXnBLaIXTỮw~Шӊa-ZECe:h[aрhY(XkxB2o&K@ &ɂ7-wÓ+r,&2Z-;s2$W O ƀUn G|T'u?ńi}OeZCE!Y~ф^XWGD᷄w&8ӞKj{7^:5htڹˊ?6qT\m Jvaf*ޠ T#O)饁~mHMMn]hW3oOG=T??m}j ̸GyVtx?f_t QjW &ֶ)d2+Ǫ#*g\`~XAP)lr(]"`!\Q֖E/>HV!\oxO׏n4htbS![OX ֲK6Y Nw/c69[TҥPɳC&PiQ(4Z/*;hk;{[xjx7or]pJَl}Z2_j{n | poZeض/>sk1 5E`W]G ]MƷ.3 Hxa):V\YNV.*8.8Dx]eNLYYgxZ_wwӁOx.>zx:o+h`855T|¡U_tiƒG5w7vp_48:|jx"aQF•ZZfNn\9jtm\68'_w^#椹5!FVRidժP#'NTeeU;ž5/K;%LjV~&@%^t 5Պ _Tmd29ޟz+RE*>TکT-]+,cHY`o?}2=xvjL0^OCw夻Bir ]3;8ɰt﹛?~>rYt_tæ8-*>d\x͢>AūZ9f0tqVQ|?Suλ;馣1WؠR33WԀQxM_]dvtOIG5:6,w ?kbA9ה]xMu[p3]k9qkg (,A'lkNγŮT' Nt"ڽ&usl1zw6ݪSԙؖsXl4xͼsG ݾ!kIbnk2Cm{bD=$|Cdu`:DN^Aw[^#<=!{ nLޫd޶~+q; 8-ק[ /url5`IC ʕR aҹkںo'Y˂67UEcjgCUY:^#P${KzbUOסڹ# ߌ{k[D67"ۓVMĆj|ܦ+=R;l]7ӀUq`[y2ɦ=|+)6;QW8J;?~W -ުax5g[vvK7aS$Ńv~Ƨv=+ÞSߤpL+5#wppvϣ$G HM{W4ĵy^L0ixAݍTVJ pn1YQ%2Y4i^ucooɱʸV!ݳK M5l+u-ՙ qmj{;eC/Q:3yGxf *V͵U n0ɎvIh }I2iUߪ^Y\YIxNjqԳ]J()$h5]7;fd$edyxgރkwBYkHy4Ui1Ĥ:giYp+W -VGȳ5obc;B#)->+PZKdռ+Z&:v_m͉9tfa%_5A5*d6l=WT!j ]r{]n /Yu$uׯ9cLtSAL1^:dZp=,sM:ts SPϓJ0tt_7jA6mE_Eh[?^[7Sr37* !:n4?u^v+نRRni1^MaTw.ujcw^cͲ۴I[^CZjjlReqt}o /p[Q!2֎h6 ¸!:OjN5qN>*Ο' _u0^Lôy:RT`?ʚ2k }+LI%E6KTV?z1ou@@?z!XZ][ Vu:{eZ:X8.ԟCQhrkxǎ呃g-L?o5Y4X ͭ 9÷Ćx˺`x'滴֟M*.&UΊ"'-y^O[ Mo2&:o +?{,/`i$ ]ܙ%"oύ~:zBI8?:ηa)Kglku($n뭷K> {"ϰRx8?7ovQp9&؝9"G{~{FB@jk^|=^}=6qf\+71>VVѕp3Q(+$SCtjvvKV?~CyvdxU!Q}x}O--q=~3~\=y$^܊׽ChoEx6}"ja}ڞ+G]FfŨa7#_ȿ};|'ޏ[G˯1DrxAx=/f޻O~zT]zaRV-3<ԕ~.ܟ=t1^ VV,>t[AC__;_4Vkq[%,Luou;n"= /iNUxeWA܈|DƫޮnvSZ V5*FnʮXva>֥LVvܮ؊[B#&|Ϗ_ x7]gQD1& 4u[𗋱 Tp8rG-L "^ndW'}/U"h߾SFЌQ7_7=C[dUV"ۏ9[Cd|xQ22;u֮#/*A>S@VEt[ l3޺hwBO^(-e_lmxii.@Z;=ş>>Or-ϳŋk%ˆމݯ?}#pkk5罹)v0zւ׻Gf^C='C};– ;1{7"zM<] GD[XtĻhx{kzA_݆l+I8Hyx.c5ֈe,νt Y{kEFϋPmŻSx o ;uh(yzx3J_:] ډ^`s{H1Ǯss6C0zH s7HV%= .'+xAyl͙2ec$`#^$hl_)oT3^KzIRUεC7k*ܘ4"(o|x)[)\g״4Q ڡRq63WVCerF) UJ)ݬ?d8mZj}⵲z?eq};J4JB1|pP׋FQ6ikޞ)^nJRe>f\ 㥤B EzyX7hh_9f 'j056JUֆcmElNWƘ5#.vO"u#H&SY$W(#4MsRUŢُƯo=wFV suI眳]"+RV4SuM7|*ma;1zdž|u`gUH6e"8ʪ> #"§ ]M#+M ]Yf- $wwhjǑh)<5-p֝mSFoiNsRQWZQk@o44-ǫ+P,`.71?%*X3EhB!QZ03jT0x{ L%j.ye˨xZ^+iehGI&<ţ*"l\dpAv~@RlA}ڹSFqt}ԷҎfe.Te]/-itV^ ^[;VΔbg9T.pvÌڹϙFqtJ*Kg}k0JWdWݜ|gT; 4X\و:סrMTgIRm3p'-y\L5亹{^WuNRoD3 GSu,կ +GfUQH.Զ< tF"R.9iUz5g@KZkl,UrAfٞ"}šy`y{"œ2jHkqΊH/ 2vv#4 ]יK|A$U#+D}1]#ɡ֌]g6dN%=xN<ԏVjP :@& z;F{GZ:^xx }ssflI;o1\Y 10lX*YE-.7tk`n6Hvޠ{]U4uN#/Y49Mi剢y$*%4U3,?0S֏t:fEr;gOb{Vd81s-hB_g1G]d1x¤2x%F*C,r9vѨ/rM eՈ @#@65xnLgFgZTD'8! <A /(O FN {0ط(F8(Ŀd\ɀW&aٞMtS|`_{{~l3.0kg422#$߅)4e5(£|8d3!K M$b9Al%*#^'/#FVKʜf*No~< ݛq*&&HRd>hi%oڧ_h KL2A1SLrxPG-@X{!v۰'q#YQ9<RM-B#<eP!SE*H]^2Xqp[^̊Gĩ1~JI_˼hڙionB *BA-2 TK;ȩ?M@=x~?eKcdR[8Y?=5MWޥFw!]A%46@LkhVJ sUxanz e-rl/S/K-l.T˞cP^ᥱQ0dFSfT2M*~\Z*AW&@Gjl-zn@EL}*3 s(f 4"+3$0oܵ,1^of6HJ4bj{mu(M kNgym>иv.ۍ" ] ?Acqכd><՗[F]*# J%8mP 1JYTyAo;ytΥ(+=б0DŽ]Iaj~s,Lm],\R;Lph%4N]w ]0 WZXz^r\Y y䮨⮫c|x >1ʾ;ŗY\!ˁR/y-:#Hi+e\jدݶkOAzoYaАmޣl9o-4K_-, t~e?~h &w_`:SS{6[ZhnGw ^ʮt.ڄ*3lVDYgJoW˾vwZB4bЪq L|AJ`R2g7u,3UHSmTXhN<4Z*U`)zeR (o@‚H"{,cOBz>VF0R ߸vVB< ij@9 VR|bLIا`V'FX/rh<3;V&Q{c$ZwtYU:ظczT;YɳVZڢF_-Hٻ0^[|||C<;c'حv5JkTxKFmH?[O HFhCD(hRՇOZ )i+pu3e% L-pQFMP C8  Qo>aTxyLrk}YF_>.k̓H5HS,lBѦk/Ek5 luj^[\M宔jQx\}G!C~17|KmQ>rdHtE=ikx¦~4r,4~е ):֣ fk,$2.9DP[q7(+cX PpqL%u~U/;7^[|uJ^̽ܨc$#^ um^hTX}v`ug.!D@ oJKl(VcQ8'a5|^=TG 3 ,}3 NƊ@QAFnѨZ[ GN a;Oe}Hr]Ƹ^)ט혻eü!e_']nzL4N0}jk*_ʻX/ DfƕNd ENUZ]KwLL]htkm]j;uRc:IKq{ABp2|k3RKj{}ld 7J׊I'PQE?xCxm}Ы=UnbcJ[GY55t(Ukg=fsF*iTǩL}0sdJ+}h]o }%?cA7(_aYکxG~gx½ͨ>+47rg2[ճ6&Ub]In p{'cHN2itESYkvS&##LxxI=oqʕATdЦ[9p Fr!D}3ˈQg䱒S)s2C$l /~MV殜82kSV0,dui̠ /,^%^{d!!nڊ.\֞z)u ې=J*I"`GE4*Sv֛^x LrfR#Mބ{wL֡ ı$GOy{Ͷ_5$=-^;A$Ռr"`X%у1q%B$&et7@ȈMwiDOhc; o?=P^.܉3viFGF#w]6•bs,'I?IKFX&{tW E"u-;f>@UsxxU 8WX*'ÒW,4#5-PەY%tkf6ycCý\:Ԋ~ jT<3 fJamEZw FfAXtHXUhN y$ge+2'IΊ'^rD|8¥> 9cg=Rڌz# e7Xb8e>^s,|̻aSqn #w?U-U/z9 t7{χ jD})[SK\}vO&p!/81\SJLfUSU0K0Tuu:w60cݜr+K=GV;d_Ɯ`cnW!&VhC0F3Qcy9 mm#T(Tf)_uRqhs~UYQ޿3 %Q;xc#e7eIw^o-t7wP5Zyk\- AbbܤL}Lשz,v沇(mSk⍩02G9c_F2~o7IV+yzh8"7rɭ"{$3zՈIT|] ҳ-wN@%^v$e97yϠ_*O8sf3K7S Op]QOeARߘXRZwdDKElۗ1x~~NtڙkQX2| =rn4u~ݵ4&DXFfH}sOtچ^^2(Jĩhnv#^o‘Hu}}`12!Q xëFԽruVHHT~^>O)8o*%p4 kNMu,YzƊt/;ጏ؛-JȂZ0}W:5!2OsӍ[^y]o{ޤ_\i4+dS+U-jsm񒞓6?:j}[w0o}rew kMs-:}{v jrxJB(]y,R,a 6"$ː{<{3"<4Kt;9zMO.f'<̷101:?PeCʏ졀6ڋ 7߄qbkmFHչ>|t؍ $h_Yt|Iդds$x)0?#^ʏ|TSNOhFB)t]/}is_kܷvNOЈg<4;* k4\<ݯyXL+_m{ {xe9l M8YIh3_/z3vz9#z(TG^o;*9*\yUTFܰxY_>dTI̺Ɠ7ooR$rHFGK hϓ®_ۑ#5Wuq˫&6wR/ pGPI+C"B xUp:۱^KJVhOZz]UϘˑpf4v7P#Y=lܘ#fV@جϺD"j=B;fs፨%2?l0Ckbjsۥ}!ߜ6q2/Y ڋ-1"30 ֨TM|o(;|نH@ˏev7/rnIr{:~(/ʘqN3{Aһ8)Nu)~0:0"05ew: 8ϊWm{<ʺ\>f=axoMeyrlc_ Y! XUdA~</1`~ׇ&k> /BΛ$)!/g`c-tyɪj5hTax[VE&lM+?|0('ciFQ:"|@3œVc%B_"Pox]L-!?8Ik8>>pny>A-p|\m/" e<C#( Uҁ|¦S h!Imv3r0aNSKI<>-,Uq|ٔsbP+HpU> uR]7n1tl|dm9)^ ԧ&1deji=Z u2bCASxj]lanKϻPSIR}h(P5;dJ6iUY:Dk^ʝc&|ӨQe04$jďF8*{ss7oCEj!S=[L9RړD#2 r*k8<> B˄6/¨)ݔs ;"T=zB( ލLy(ckWaWAJjΪ<ʅ getM9Nwئ0'T6JL޺hlFo)4b}OC05O8ə.°n0UX^T.SvYlyw"X SZ̘z]E~96,+UHry:C\=GJ/̲]7_"OM9^.pd91>??v{A!zt%2( j[\q ]ETCU2`,(Oiy1/7G."I=Dm4(kb?!sdj聺ͷ=RtS*1ajB :j/C n0My䧩^>xx(pjAm55ψ0ē?a9߄f[@sh%&A_ΌٚxeFJ%b~+N!"OeEȏR 1ө|<]62P@<>;)081(1B**rX7Vm8LPИ%ktN؇~68@]*<;DeBcj WF 1 ?1%DCWNfq Ft<+24b{u#χ_>jDl4y}~W\L^BdF_Jz!Z^~@3mG0x#2*YTa"y I'Ͻ[iC Į): p~r? x긛~SڨR8}B͈²#qA7ȰZц>8<>"WVcPY(@sť.Y)RbWh4J>?^ۜA3.Ž=C lеN?kX;0󣹩Rѐ2aZvHL~,c%f+Ʉ}+RŻ;I>>Ȭd/"4r?kU^B بfXdd * U^>KQ7*G 8t ] H- x̶NM>c@xox]_HD6f;' (3-ɝO/=Z໇Fox/˗ )ۉ%QpQ5q{} /s}NJX)ѐ0+E9|ʘ:eLS_/4zàҿ*w)u2!ڕk/!>|ڭFox+b_y=b;KךyVw^,oUHpDACDĤof; B#_>/sy-&Ly~+,+! <']RP>X-w0eJ"w b^wA "F `m Je QXFfCiOu.S vFQ|ѫnơB2Fác̈:u۰Rv\@]~/ł%VN.{^Ka *n<,=)\gu#mfi W|z?Unqv%^r1.Wrp /!:hXc!_f])52 ŦSq=ތxbzrxC+aVD!5"Uo.m=ksW ]> R e g ist r y M anager S t a tus C ode R edi r e c t E r r or Handler C ache M iddle w a r e S ession M iddle w a r e R ou t es M iddle w a r e P ylons A pp R equest R esponse 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 aHX/wicQZRg8EEgfZHz/BYY51Qo= Pylons-1.0.1/pylons/docs/en/_oldstatic/Pylons_Stack-Chainsaw-OSX.png0000664000076500000240000103675511645401275025240 0ustar benstaff00000000000000PNG  IHDR!*ntEXtSoftwareAdobe ImageReadyqe<=IDATx]|߾{]w:Sݲܻml1B %@@h!bwc\q\*Yt}$iooyyf&['Ne#A( > ^@P8n qj0eC>Na]hሩo=(R>^/N&Iz 0' >H(I(PMhg u! V+c0 GLj;~{cn^V{{'hxٹ{ouuu8~VБ#4Kn]d \`Cl 7X$wقhAw ~h\^1*aEɀ$'U9- yYEо;U8z9 /IA QkH @;v{izmףDRԾ}^|ϗ̞=ul…>~')8@Sl[_yg"I]r &AR?&OSɛ6Gh )B嶊uϛG2IsH1:$8_FP^J/)XX $ H$Cy%:W~Ge{O3_W_8Yx u .8IQTYT?z?S/88ক+y"B1rRDRDz!b*s~ID9a+iJ 8%/ܒggGS 1Mko[TsxGɶ&J-_|>5}e^9Bk_ݾ-) >_:=j*&r  9Ï(( :(eP ? .hiwy[/㈘уذyĸis\ºڛTVf[g΃#&NodN+ȏ1q>֮TVR) ʖWu=qs\7wX '6ԠVx.O(xWKJF-vMcRq=.^bF+c)"5x`|7eye]kh[lʢ5% (AzEAQR@+4#Zo$Ү6=~Q4t?N Z tXĠ(kk.+Q@ۈ *Je p `li0a1 BgZ_=._{ly[+Hc=;lҰ%kzʧ}`EEyo1q:'3+y ۾|ޏ>Z}([^$gj7K2**9^-M 9$**Ʒ>3IoyYW1qpw^9eI~'VƤg_bŻTTyWa3bSpf}m̸х,2 C@!+,+D(t"- ,}J?&& R |WI3ť3rTS4pHG]Cm2b Ɯ4&=1;ɋ|KgmKI%@C@TAUD.K*ޤW[%^O+H(zX_ޔyfsX^¨N2|R'Ms௾j-(ϩI ?UOTl Q4ˋC^dNU ϻtJah @&0dU/or4PO?ȮwŽ_$,Is?_͛o8AltbFB;jhWsH{_ fM~/Oxz:nr" NH]è A3gt%!C$Y#)MMMcIf:=*sEfh0ejgurRR$f9-9-bgMb~b]uuIDI}ω ?|W:3Dqެϫ޳fd~?kOr(ʮuID"^yuώCӮJ'޶fԥwCDN'OܵO\s~]DhkΒ4(+>mpVw_Cj{u__ǎ^3:2axVd"DA@2н{EFGrȋuM-SS8N[+FUXekQ%"D^ZCќ\MwG P M(+j2ǏJIOL./YA͘>*!401fӟhiHNI*Y1N9MiXPdlcU:*-ڴeРT] ʽ%DtzZq톍].L`a8w4l*#r\,j]#3ʘm_}˺3fP({vƠʺĴyhڝnjkJ:OnXz3jK0,-+2\ ׃a4CKKKC?&z%ISRdT QvvԉB͖lA'$ P+6!."a^`c8p'( :IQ(c" P- oڴiW]uULLL} 4'y7RSnz+ٽrРTA~U` 6mZO6/w7d|駇kH̝²l(1Hr/XtE5mxAAAnApQK,X,K.=zUW]q~`Aꝱ{z5kրk XK`vUUU|5 +I\|J}Es @u'~d2 4(** T Eg8ǽ2+Z8^s@Wk9’F񫯾2eʓO> m뮻{o뭷LOWUn*A8۶֖丮7pef~?p}v!]|7mZK/rHzX2^?^66u7>}6Y>B/YhQg;~/j Z~wuvF|4S~~ \R^^jժy^}`ժR@ny@1?XKFGuuu`0(-KIt"&&$i$ =A*\QQw@)niiѱ|򊊊 NܼR}c2𒒒 FfgEɏG0 As~`'n{< /vadqܒѣGϙҮ :߿cǎ{ykT8< _vT`4|_ZZ9θ89 QT K1i6;XЩSF>HVap $wbcuw}SKK;|_rz}eeH }zzP ~'&N*&AP+++Z|` Q7(d4n,h끡l`Ӧ ?"I&#""gϞFfMCѥn+ `Ȃca=gD,(}A7@EšsvC7@DZՅ >Ej!-\P{{e,SWWs3*+ /]m6M@>djk6j$964#|_sͣ\s X'X\;<>䶲2## Nd!j,1ReYaha w,"PޢE& 5MV;t-\f+~uE|EUc_}u $W$7644>M7T__j~bb"byeTQ"|{х͡iёF٨WD?В~رo60cEE'0o %&&,Y A#Gid' U`{չ l)ޱcՅVQ뮛~(%˲'O^U"qpu7=ᓘt:k{\d>Xk>?3ZHM`ގo]~͊`3@\rrtc򔝝z)زjŊ҈wN3Xi0z<&M8lj>*61"N;bM&c֮ÿ$I}7h7W]uՀܹ3%%qmt Ā3L;0xXS/`0w{CqAHJJ+V,^Ų漼qAtvv655QsF+m8l=B OVWN7~90rȓr7}>o|5n`Un;yzȌ=M*bEGJ3r &e{ۭ[T F;PUs| {OJgTrРAQsh- hC>{`<m` ^VymR7j4{Cze` #ozwE.[t,o9R:Y7Mg9" ǥ^s^зtM >wI͇P `6=O---iiipSEE6(\{@c9x^'M&(&mFl`)6my 9)Nxdy靬PiN4?Fiy#N)O_z졊 Z[[{UCr|6EH\9E-ڟt?7# 1 #p8cbA)uVfY,-! NӉ_Hc OKe*-0$ϩ{l[P)!uvv"tkdamiBZʚC끺MM' {7 rj?VP,qz<zUsֶHup9]wA4fMլ2 DQ@op@#_UUXWFX*b0eKKK͛+ *vWhmm'S&L(JJJ4Xpx ѲBPПӧ9uttGXv[La?]:nJ^aS5fG$%ѣ`mȜlPS;1qBISϵ`$҉ϿW /dHe@gP#^, q. nj$kkkL?hH[[7E+|w`;8iMCޖVa,`1R%Y#Q\Uc?. m32`mVޟQ|>p .l=\],[|RZb\$ԓhdkzNk_1߽o^(Nw4Fee^^ҙlY *9\vm$W\Mn9?7VQHѣ1)5ӑDk1<\])i#R8ش")=#c&K˚F,ЄgC;6}GzzYA.h>UJu?k'H<*!m¸Q$=σB4v"T+P^p4~[w'E􅱦6;RTEjIxPDcը-;!.T4F~=Z|5ۣn#Z '$,z0⼂H*ʆ]l6Ԩ̾}{#:Nl,E=7ˊ惯/n,z{ WDV}][T\YߖlSgRjzDc3qb{/&jEn+1QbؾJB':p%X/9mnAr R/q7I%!i|]_lpX`YWyCrwi`DLE'h*,ƀEU$(Eb@;4,^koi߱u]{ase5 gwݑDj#(jjp Y&#$XnOovr%66+ȬFUYOB0=h7Yψ>:D'D8I5u.T'Doy:ϛZ[ㆨ`!K:LoKtU&`9[^%!1Vd9@k::th[{.(qu`8 _FG hLrhlhQq-9 $nQz;Z[4 (n ! $U7Y&)iLgS"l]L&"H0tT0H`z@ h*5G23@ ;ZعMJ[\.'jv~Vo\yl8=lO uY7_hhͮ޶)yqlZv# i8iBqCte_5<'޾n1}E@W;ׯ)8zDF|bᔩ 6ކ ц_!"@˼][6;=8yGY\RWd'0ۥ v³`Gٶ# i\zAaVBTЧJ9N-T}Ky[-/s ssKj\\tqʵm۞8f'wzթ3=D2K2O>OAlQo$c]q;K'HEN}Ș \ЈrtⷞynLЙ|ZQeBf\;-Uo|^jiSi6uޗ~GуOƭKvDex7U SnyՈGɏUW+WWptVƚ3箻0ޯ j[1V(11324g 8zpt$iRI4K/bqf$>2< 0XS#>q-wnxL4U=s^jK/~6?o/7tn'fȜ2=OS<%?n lg򑍴$ )>>*uAM5f\WarV *<\V捌z-H pI-OAH.9#B`[89ZzT]'%aICMAY>;0g'ۭ1le4n~_Ɖ8xos[{#ف;& fcYBnVlT$J0fJ5^xM I8i\ ckݥh`T]Z h޹oob|<Y]U퓌= *SS<`B|$!:H}[*hC=үu<$R&@𞫲bZ z#Z|4ݙ̜+Wu0(pd@s@LF%puXxd[[݇-={Ñ%8GM٩i7R=?_)Ҩ~!j|g~Ý?o^\{{|YaU28ނ/Ie;X0q+C n,ebKffb2r}SNGDbވwdf;4YlQ]KP\7Q@7lڸyĨInu󦒨@K;L?4Z;ItUJoF:Lپ$i3PP{S3%u]_+phQ$Ie@FETsɉlIJK͟8UuR3q>ܖ3hP\ CL&NMT !c\5UكtzEBTbJQjʌW^x6ky}]y1FB~kS/M+/ohxſqCd-G)(ZFT TDV@$10H"pIRBφ)OED`]E _zÎ\^;f'MNf;-V\Q bl`(O/~Oh_X i`pbTTTTWWgff5qQ̑ =[BTqm4HOQ4\#un|O7 =x?{xdhxj\g*8Iv[ь_ x{%R${r>cڣ͌0Bñ;,?>sΔaYmM0Jre+J,--t0b\ .,ސZQݮm/<0~! }(A&$*K(iCF}y=a\ +$ITUa<IȒxvd%N X; u"N^&B vd,ĸYY IAh"PF ywokLeIM*%QAi lA.R R<ljB$#2/,䴴4Ā@[C lUo}E SYhЁlzN9iAW xDfrng\tyPη1*"9W}Bڻsy5mάx3UaѮjy$%K]Qt^0xݒuO>^V|ľk6:vtT^=tpA{] #DD v9*Ӷgq3[:ېT 0 +ĹUqbKTtSyE$wAjI:2zR;fb4~ ǤOx_o'9?.=LؿYgwS϶7.0U|O\?wv~id]?YOUs=%ysї\w~4IZ0 詗}u[{2AV/$xr3P$E#xv%`.ʄ 2HʾEfrW}S[g,)QCGL0cT!M ƴַl^QӲG + Ĥf϶\z=DN[oV|ǟZuOjFϟ39[rnϽG.?H&g<(aN| l2 7s*$c w]4ףsPGL{ig#H~;Ű,+(Idǧge QTNŧreq}zNvVvޠv=%'?%-%3 %519- ;spѸ#3\]nk|jvUdGde;1pTw҄1EC|^)>)mܬ)QQ3.nތ15XTΝwޝmX.:`ˆNro2<=&5'95!5#kH~N눳>$Uzp267u9){DM:PO#zaQ5)A08RdY%7S]SkѲ.K<@BM`*3eDס NG2ȱ8` )We{a:^Gyϋ2脁%䛖DEU@QkQȳvGt̫(# '?999B@@@@@ 7۪PqF\V@AUDբcb 2qqqG~+f0Lڶʄf0 |nv-N~/{,yGӻCgY'[CC)e#w `N+@@@@@@@(n#Hh9@TDjy;ҡ 5hTf0ihJ463@#NB?f@@@@@@ ˍ( O\t+gNHFsp +Mh9+3xD$QPr# hJ~bbbs.24%K( Cˢ *\&||>"##@wH2ԧUdDOԮZxAr7v{"@w\%'$쵺& Cx^l8i4} -3)E<ǡ8I8sp#"(IsA #)uQ'WfwQ\Bpkk@J@ˢh>f0i5z{ݪ] &Gn5ʑmPdFY%h9H"P$ /i !úLEiR G(Oj@.[2ryv.+jdͥ=Nd.AQݽs{R0"8P$:(:GTq,$M@Q(^~梡^gvPɈBq[lcQmcgY$#0+`Rx$5P(-O ?ϟP \m LA?s8XQE` g {Z~M`Ay4Qɷ+} =e݃FOK:=~?KiWO,B_A18QWDzӺZk[l^A~p--'qc:5vxx㸧zGY)#WFi"{GI@l_MNn l.C$pDbWҍ3f9* B  śp #-90;cY <@pZG dN gB'+;!zŒ)p>\ 9qD/EȢwul(-><MS/Tn_|l[#3[6+즭%= s7.[ޞv.[p|_hψ7aH&P5*]FHPF}`W-3eD\oݰMr^da_hXa[bjܗo|Q4B(iAGQMs|Չ?LzV⥂1:n޻y݄GV,^r-*.m]cqLRaΝj 9Hd' v >uoE_x%ɇHƮWwv&%D,^)9)xӮɩe%m-KNSM}';bkJlS*q :4{G8۹oȸhÚorGeL"n/)i]|=1Ywُ fRذ?]iMjxl<Ef߭4'_Ic2#|<1/t#zז'''URc#)s֨ ddt?nsݴ)c:k]Sᖔ;6l?HJ‚ ji! 9u o{C5?_~ ˖1'nm}~=!Uv5|m-۱e/ϟ=Xӯ2u>)n9|/77}<ޮG{Mݦ떗9H].jLr׎=fUPURD~SK>ejh6dE8;^s=~e x>M~WϻnDCީ_=r .kxա3Əڽa` 0;wD٥Hh#!7 "un)=|Jkn*zUD 0 t|N|CT0ϲ "!z[r{,ھg-\`#U ;5Vf^~}ш\zFRbg8W')ǁM|colxޘ"r-קqÂ%Sb+l,ٻfSiv:chir[fb P羨;J߻FzUW_`dy)_7ml޷,I+]meUm.4/6VϦz'9d5y!(vpGqIE(Tݷ\ov]Wo>PxߢNR (JDri) UM7ݚ pOeX xj^"Spޘ9/ >2yBQ!Cf^` ut[ݽscųݪ\[hAOBu A,vNS6D&q˕*c/LOlH𫕂wXpv{ z%RKOQZKo5;5Np1LW&|`$I%" H7#$\\`h%)oiklSQDZ8p++3uMմsnY!&au\Eʂ&ȧ76>ۏɳm.x]Otݎ 70ӏ|fCʬ\8᧟luy\Ŝnkqt¼Դ(+ARm{ H*y8=܋UEvgR3Hͽ+޲egL}J2zRY5wiKЋ/o&n|Ť͛7_K <b͍^3v3h+urjr Iv{UL*w l=+Z:Hcra{/=#{gh[icLya?13Rzǝ]W]]ᬩ !+?Rلb^ R;'v3 ASf7o4 QmN5 fc\ްFF%57-f=:nt+_a uDGbd~q/?ԣ/G_KG' $F0sBr<(Qɲ,2[(=oK/?:{bJEZO/n}ucyߖ͛d W p[`8mr<-p8@Z,XhaYVp‚">/FҘ* jbyAA ~pGVܮ h*S0 "B=1Pdjx3y. h9%3*z<9ǚN#O~o@Q e`$lg/aDo}9zGW5>"y|Nǀw 'A1>(7nĢ $:pH>Ay,#d.ŃITkNq`0W 9%u:LVMMMfq < z9P<Ѹ8,I=c ǀ$`(n J'dbAьN;~=Y`돓x>|:!n,rɰOhooL@ۊxi4pIJk%ȳ3 KY^6zD:=)PL݀6epݺuhYYYo*ޫsD-c3*teQ& b9Q(b"' =2:w%q%ڈ8gWE>j~VַNO>};(DNzОOz\^.2: ,H9B@1=ew9ڻ EZ"$ÜʳhRz #r|1oimNw k{ qFh) -80}2K! c¨z巻Q6#CܲB0Ȳ킓Z)p۲kA" 5xg߯T&`OMr~y۟uMr:FAF[^T壃JSObdQy@,)g̉K Bx2js6s gP02nwN븍FyPb,p*O=R*Ky:%{zUG4:NJ*uuzUF{&xFD7r # <2TX94sVaU1Ⱦ׍nhP考`.OʗmV-3]Wq<~$wʵY'Gb;s)"t!-S_nh@;I$_O4^SI1&}0N>!bi- {sr%^5 +Fu~w:yYUWQq۬iX+ SGyQ= -}  ,&7SN$dcanFF Iw2ӪO37m#Rt|7M93˽"C9zAfvLGS/*zU 2t]#e(_[KRR+.4LʼnfXbL>&? y sE[[SXBUp :mde }(x1ga&XҠpkD&B~|| Q6!2BM|kTpփ\n3)BL` %$ N B&՚"*b χ^UDRBLĨBO8F. z YYN#L@SqM 1ŝ.9]KY"),F5-VO /&n*q|8/+B,h a)FT+ZRMyx" sCbv657L 燸:@Zf0A!lzB\bWImnCU0f\W6/ /]q Ώ1kbl wŻb411C$LfDԦzQ*PKX&asXUQnCod8-UIJ,xHJb>CD-QZGR kȰ$I6#^6ÆKi1Θ]%axB2Vۚc9}kZF[%dx,CH[` ؙŢ\ )Eƺ2fN!:dW 6xwX(,Fm#A -:ix1Qe( nagqaEyVaGcWx/֤0DsՂvW$IRZy$w*IVM`"6G"agMK@-t͔epIL acH[X*hH:2&KMY bir*szpYi+ L+xG`TY<lV4QO06~< mƁ$Nn S3gMxllˠ,?+ RW+E4aq7uPBZ|?O >t!RW1PĊ4.j2HEq0)B>HLqgGIQ  BX&!tcie<:lLsML6yMGxW70Ňy MͧElu ot-\߀;#PFBBþ=yt\CHؘGRaf&KDR'4el"m Ps  1Ï)l1G4#&!Y9\[WK\&v+5Зý>T, f1&D~y be?V6$ OOÎ >ʊ ޒ,Fxhz=\D̈gv XAD¬j}`gL-mf"(reĺ,6 srb^\z0ŏF1R۲2c\[O3\Gh-XFICog v: La!N2E/@Ԅ,ăe)Lidp hTSlDIL!_XeiDJ-j:MN海mݭiZ[[۔)S9/`8nҵ0y!Ym<0.EXED|m^!4`*Swi)I0l:|*Ce~Hr U܋?:U4#hAM^B}Y^?e3 frZU٥!1UERx8&-qO:k 6 zRJ n9,c¦34QbDs\wBP@ BJ4#,u&JYǚ|$f*ts}KCq\ĐG-4y+qx;^30f$.۷ d2oڴi͚5bf͸%"ˆmm؞Afj.$)d320X{8R9u Z$^тjK+I+&,MH=_>8xA[Q40="`}EwX?s#'$jd?7ٳW-ݥ uh> >xF]U2acԫ6L4{[-@/E$nA%pS3C E|s},R%m4ۿDn7ZƑ82s"xOlcu9Tg7wnx+y1~m. Q.|}3. `gM(1xi5 &7"[aw(L{'2>D8% @BQQv<6 lR"jQHZZme~$}S snlc"ΎvġGqп^ˮ zole yeS8hLa$SB=j#g5 p|gse# c['a~vF^ᵾ WΞ!fL\IDEdsu?Mu>8 in I׶f^Mzd~ sBf+EB!>%;|Yy9f.H4g,ݭph.X \ ~O"i5pC+. brLטe8ѤF9On[pfT2zW()#*H?揃pS;w'{;TPkL9J=GY*i6H忭Y_`IQ`Ufa B?7hc?󉮚,ohM)^( -!+Qλm`?R( - dJoaG>[,D>cs ~ĂX7N_2!f& ~|D]&fޞK-l v7DW?ITd7V# ?ȔB0cƌO%fch59ƃ|rPs{?7 Yz %z),&@aӏ>a%GTbP>*g* 5_e3}l(F&`Aw{83IX7x ޹*< c@'PhCx2͐Slߐp3Ju+q~_ m];"-R1iOaT~ͪkOa 8]ǽ$ "IDͱġ]w:nKl4NdRl-+ Gr$!X4ux ~sgTD.KU M9.,eNSeg&U?+8K*C  F* ShM$&SEt##aQ] (1ܘ"w8Rƿqu)~I=CO-2똃%4z~7BCp8{2߉BȔ@_Ճ"H7,'!^bmG*+ e9^Brs2ȢXgw;$|n/WŶ\%x 8?وDvoVbEʲMʮCn<An; R9szUYS&ungEIfyD*UByjԏA&>A$;Jo`v/ 1"9KA<[`ո,+¬c¸&yL#aiفA'M4C'(ӳYy t[8wA-M:O26`Y~R#)ܙbG}kQs<㴳q^72"Ϯe;u,}A6y, ?9)K1(LTnev}V-$45B6GR|$VeTU >Zb*H7% ƎdЇ? 1H4 9c&hjj?~#GG|s Bq$WëI%wKy9yA6L,艆٠LZa4|)ɝ ~:A$7id]Ȭa YC.%giAC?sLRj(Iat4/ MսͽyYt2Y$j$^E^hxBu!i&AA!a#/},7Ľ7`^,1"ޒG1'6dx^'&'0ҝtyIп`gFyyHƚ$T%.2OYLWAD=Z5F*0;5t8h똘=#گ Guv F{f9OsB3Oh_D40ryF%suo1aMZ iS/x nH31d㗱4tKKXL lO+Haҷz4ح6O[Ϗ3b& U,cpѢOY=Ơd~WIDKf 8> ){c晡Taٜ".">F:;-# &*]`I<'&PL{HqA&D Yh-HbYq=ӘDV<ev# pysDu&D1^AN:1POFy#Uy!(YՙBt^!z[E+OfΖ(IqICS03DN#%=Zg~{j8-A4!4Lg%HsRֈ,y\CZD4pp2$ePdN=Y(Um݅\/z=+}I"z^%DQgg ͏0`iIi8"($[@=euYB)ij B1GZqbAS9vv#/ q*-A Y9؈+>NKƹEͮTSM2\#4M$|Qbi]S8?C4F$D)hHŬ*x筊nAƑkbP$p" $Bv袽 ~7GgSx.[ ,h4bpݍl~ ^1bޒ3Y΃;}`ˇ87Δ^P7S q|>g?vU\Np8-J*\W0*)ىP!f NZ-"6NI$mgnhy_OeԓWUrMyClPnLprW+k[ޕ3qƵ]t9v7[b,[&F?I^$'|kuzUoĉ;)2ũ^9sx\O;Uw):U1 Pvasb㌈R9'}vlލx3?e]JnbNr {5-8;Hv>,V>eVmPsX5EZ#)K6gKlQ\̛Y.]:W@aFoFr#MlDq'sXoR^nvvCk,(po5klCs N:nZ]9hGNt򲝯 E8iGm$!#ڙ2H DM6ZN~#ԫ*#d9!麜q_Arc" `YSo q# Ȱiq#Z#5gǖVӨyUY'pXU-]#ӧe Itfַj >wGrEqBLj#D^GjF1[*֩dfw]}6fC5˻!{\E J9"2֮UKsnE8~vN?y&ofd?bOD >R!y[6[Z=8IW6C\Ϋ|GOW0OiW~įpk ӋVv O^5ީ2Y}IW7]·0ZBE99󞴅Z*+ι~wF|5-DTN @N?D'/Ͽ~s">*ӟ'Nr5,k-.e;4$mv]P4"'/;LgW*y,0? w|?UO0(mѺ+d=ɥPǿ/=C9FǧmVAzDŽs}NdpJa /znbvkLTI-[nE:׋AIeگMčut8K\Lo}b`Q~G1bӶ|(嶁y̆؃駻_M7sOG[O?.Ψ!t3+GK8!8l_ȟ ނ {KH%[Zⴵ6#d}'+Db}Ps"Kd9oq+#pgKB\*+a}%7Eָ䂿nE a'Hj >U`,ի &ʤU 4VOs% '#"J-)J;qStb 2,/6Ca\)q`tNa@}@QԘ`s'xy gDIQd ߬1Cu1%Kÿ֏.2Q ´ܪ0'(Ŀ}UγȠI$͢bDDUNCbv_e6b{J;IyWƋYZ 'e)LNVD=b[ƤW32%2PFQI"6J-TvVYԓF֎Xv2 A928^ݛ\R7CQ·`])~}klc؀eu>6i?ؚb4ǡ)̟`MOdYs{q{wr}0~*Ԁ *X9ŲK{*n }p)Q&Q)!l+V t>DŽ+ZsHBXW,ixu>S<pP pNxюԄӯiUZ<߰BsqTܼBF>ۛ/yjp=_労и(b97~/K 5T쌰3; :'ܹW 08PCc,,3tv$9$F& )'wW?=eU9ҹ &|SI8ǒ(q +b$˵-XHH\$ƕCr1{SdCSO_swd2&':zjw srHR>q5D.ޖB(#*)5^(D`bZ'xp 'ADtnLʫ&sv>%cb!EL`_&6aL`mQ}-ȗ>MZ,v TsYFWyW73-BfTB#`UƍXߏu%.2tCU.%G'DR0^–24*~/Oe7o1uC,@ȥ>6:M6Ms~zs6\FvP^P\aD\Rp'h]\-~骆Ov0=߲y*Sq(nhJ x}YQX1߉0~|Fצʲ:SC1 j\ҊpQ}uq m q-aKL:˜(1/\)tU >/e1{IC_v^\@UaDg1wcO L Bɘ;Wm`5*$]~\d~_eOA̲LZljJ6%f}ﰩp*Q"鐙#^2H>c^SKđg-^v90(XC:${\;Į`.XvtIv~ۇˉB'"MJ=X9Ιg򧎅žY*^Id.)W\` K©BCT h; AP1mpe|v. ؟QQX6py%J):Ey7v\¶P^v;|:#YKipC\&&a>Džf.n'Q!ʕ: :g|:3dX;D9q:+9Pa/eW8/ʇsn3>߈R\]혢=Î+_he1JؒRqq=ӕiqgiMC87]x R-~|k<&ǰXWnh@W xgST\rW40񌹻,o^,Θ$yv.]i<:$.2Iwϧti9p]6zAr(2O 8gU<_Wae}z,ļSFhB3_MwQp}e &KоwHq/ LX]0>ȕ>̧+s٢(5gH0pCGpwY6- 'Z+\CM| ʺ!,nE<O1 v,ԩB^C7HtҜ ak]h2֧(v]^4LZp+| c>Erj=z](f!fEf[3ũ[: +b4{JXЌ˽`k;!Y^ GMt-f (z)6# KAc$̼fMqQ4r0hKX@; L"ƖRoB^c?Nr@efAa@߽yvXB1(KM'cL0ĥm8eC\۩0N8"x,aSħum|zZ(amιY8tNkeG%fƛ8Tqj :UěN|9pjHT.گcaG|O>W61SMrI pGF&W`$MZ% h%zUqv#! bZvžy.R19d;36#_N{D2gzV`ڋW٧蹶3tv4z-\"$e>zj+:`u$q _Nֹr9s\qx"..WQGX(, _@3BjɑNwaj3cSH`ݤs. 1Q)IǏX)bm9!8KI:;H*TeN&ȃPQoXGe<Ƥ Mv,E+&l/='tjL9 x%:ZwїLIXtjqCkMEY__mFFIUq |uxٶ[)Դ4Fv>!jzN}"+j@k<$FTVcD0#=SEc7d8<0ĵ ݗT[C|*> 2jEnL-SH26Ej%՝JNX\uHtknlS݌ojmIlO aʧK6S; z.nҺ vmHB1D}p9Ѫ4nMbJuj-c=pD', r4ouS3g%>ahM;1O!*zu^"E։H8[x]% >.5$ ߉ȋfqjT;%5IpB8^.@݊Z]]'` ЪݢऺJzV)-vY FDPվ,|]*.+BClZt}Vk.g%&&KckUJ()]]6yg_!Ν܈+R NpbT<}?jmjy['1S+s᰷5y$Nųj'(%0E4,Jnv6ʵp&Vql85v»A^ӪVMw}ڠ)Bx'""檳VԪ%**vK" VҎ\#uYe,K󹕊&5jUk,H ]C{V f/YnR}G؈ uy+r ;L\eҜbҙد_$po/n/VuQs`;BL{1E,R8l$*,U+5:U8 jjU!G:0!J!B&ɝ%ZQi8IĒ+ nw1WO!oJ:uKz0B=:pq]:sy*~}쭬x3iި ^3O-}z玭\Qc'(=(t6ʵ2ʆ]N'S?-qAvN?}:v0 8I׹#x<厩KfjQ@LsH. Wg(_V~ʡ`P;gW+\ZpKBrWs}UٵGjHݸ;p0ւ1)z]ˆZ#{u'-jirO#J K*ȱ1{ŬqT1kuRs%ʢ.^hЖbaAS2U|K# Gyiq((tvV 7NNBRlV'LVW~5JlL2gMyzYY֦z ˺2)E:#eOƕ{¡oAg*0-ڋHbe֛vf^W¶}&73x"+#%)}}VުvH}i ȧKc\-^hs^Gkt.[K^^檃?IU58(/Yn" )nK"!6DթIh릡h}\qIg2]_߮kUtW-ƶf~)6Oܚ4"Cu:U6qۦA-׽u8i7$%XpZޒ}U;\< žK?kvKڷH@ʼn& (cc2ί`qs` Fvս̘m!l:N*RA m\ 7V"7 yOX/`E۔wʞcJnk@l;}x[&z.zg w&ۼ]F׶2;8_VҲJ {_9W>%'V8գx"l+]I^X%B kn^KX}kf$Kr6MKzվ"fpX0pa A}rS_0:m⑻* lKĪZykZ㱚fd];>}Ϩc, -b_ v4f6ܕܵ;EW$_BU5KqVqOvGg=l+Y3ݙ1DvùTqr_kJ:"؞0Da]МY3 E( r oY{$AdLڅbnӾyWhȿ,([ϬU$K+k7?k[h˞;cfrE N1+|dS,$iGc ŝ:.{|gAаC?hb&<VYtIN"GO[Ըj@yS_oHWZ쓷٣.L;+_f>X>E,=,~AgkbOy7"wXMK3ǛbϖqP*>%Z*gUAv>DJdJ9ڹZ;/oClnd[RqеMk]rѵ? $!.Qu[xW-A5>j"֩)DžM?7+0a 1,3e?];ĶKjmg74g㬖t nt*lznlyU.G0_T5η(Kڟ.BÄ*rӕ n8YKc!DGb# 2*e*^.MIVMGTάPFNˆʞa'uīS#Z Z+SMY;†Hm5~dbmz3 t)Wq}O@r/ƵSKx:onY9 =2zއܤms0J>w {ޏrp-6i}rZ`jW \yw'^Zo˰Fv>mJ_Vؿ5u#[iSxnUhãS{[yp腇 >7*;&_hh5ml)B՞5H䡁5?W6wuq㹃֘>a~>U9#5^ހE3/b3TI?|FoeI%:"dq%caǪܡ4¿JI!n{ 1IiZ?AŠae;T?{ټ?YvV)LPUK>[yOO{C\keb3+R:;yeI3Xw_pa Jǟ|483G|#gVrxt9[&(z+>?ۙMM [!TI~l>}Wj?OcR+_S*=UN?sj>+̦d_j^'KmɕDby(ιg3 ٿ-w\~YIg7Z <ҿqS[ 7/wՅÛ3{ -_K/K=toru_)-ڙ;20CjzvC|^%=d #Sgd^|ZEқLzoY~ORK>﾿۞?"gg7-oQ)!r 1iutXoBbWrMI{m4]9?*;r9,u=f6z9'~PT.(dWkh5/B_ 6 {y1 rR{h$%/D+C̾OגYsk1Ql3rh_T˺y6Ǝکb= 1l;#3OjC󥟴6e=^b~S=Pp/:ۜKp[7xgԾՅDx#)3W]\  yo<=*Lp.[m:2pjw$Ek`dE)ЀkԂ`rv`LT)mϧ ;_{ =KLHg益b{B7kQT,)<LMemOAn^hOlۜ}VH6+wC +RW$=76ߙX;Cj76S]x<#w3myȚijS1_+26}m==7lV`/_\wOֵb?JoDWOJylظD2^5\tW62ynjݖi?V8TY?57δ^YK1m'L\{{a-j㏩9~PNSz.}'vWX ;ԢZ{B n.'zz~p{KryoRYf <6C?s?wޗ;w+C(\W)ѓ;^\m̥Q@id够e<6Ф'>AخĶآsnTF?0vn~RjbUq 3׫2+P)}e6ݕ'/ʚꞡEˬ{嘆-?]]MG|F@f;SÏJW*w=LO2/쯊d|UKzt"7je?Lϊ_Z?f^i}C'-^moوwgv|/yG*yDm2V%{d>h`WxҌ{SS[}BJo*%^7k`/ &]\ߥtI5ߘT٪-U磗~=4Ib;1K4 Y}I*k{`wp̌:țv9瞮>ڿCIJpWІg8@1f+<#U0ֱx܍?+ﹷ\o\q+ae$lT:}mfmL()|߭1Q0i~ɲwf𢏶^Mmmʦޝ'|`!5Ȧ;K"܏S6VBι>9*,㗤 #f>.GG.CrPdfJ+k=8go[c]W_<! ^_# ۹]+2]8(bB%=L ]ԅvf-M?U(ms&~Y9oU 2a}x"ގ6>S02>AݘyQɓŴonej:zaTjzPIo윏njlo;WX9I-=-{E UȂ|M Ve0mm&|%0ez9L(9Emy7z:Dg_.j<ٸ̈́j1kL+CmJ /Ѣ(rcgccD \Bm0Rjxf_ R={vKʅ͒rV?B"+8$-%];DǨhoS9Fw4/~f١WL~S' R0mXGCeW4a{uPq"|\?/d^j"'_,y"2ix# >s q[$3_*GMn{ѶEK%Y12[U)4 +Y6&UAa*y!NKvâG&LW}]/t}\z;81M.<'>y#z2WZot4.ﱿ%.ZyߺL׵_Hh솯r9zT= 'r39)kRft.=fEz-UW:0?u;k*wh~D?V^qӠHF_٦k? JwghKiwpeoa[ɓJeVe]t<-eۚ'#=.r#}f'iz#3gKeڷ,T$(VD_rw~ڱ*F/*L z86*uWRBoΞrwDNq\[L??N7R0XʯsW0]QpDŽL R}% 2+;يdx/2mTi@!b$:V a~K|{ (]rH T6n/Մ)yr jkck<[pil]+O]m7>Byn1Jg1%{ՈBlS|WSbKz5aFM2r 1.r< ^. 챾w A:PO!hVvAa$~J뀛M>twrD!1>3@3Uꠄ>l:wb'O*c~ xƮ5A~0tcaBS S(ʕ"jJ$!*cQJK\ZPiW]rNaǛKوg`ə kҽz)JjjbFIE1Wi]E)-m{䒎C([JT5dD m捜򺤮ۂ^{c'SQNrv| 9 P)4"JjKN'zEk(J+M2d)ډ~&20ԅjI4MyH -f*7kj%mc$ kTUPeI rQe:.8>cGpbX* |5y\tGydLE*/F{:[gђyK64RKv2ں>M_Ah];cMWPm>7 ܽ[3RI8! 빨˧@eLͧPzY]9|q6hњO"CyBWiHS Wo| JсUC(q/ XJh|@d'fí~4]Ӗсjck @3J~'(0Y$K wv4z:&×e8wY~?\u Te E]_4,PB^H^pIad+saDl8I,$h埜 muXx#z+{lYF._nD~Q z0r<_Yx8T֣[)+)N|xh/pt5187U bx1,ACe1  >QEIv!< G1gE1oGAQ NZ)M7棗UcƊUE28tt QZlDv}m8Mo"jQaz.Ʒ7R[.0`016QB`6ȰpCP/Nso J0E[ 75@O!"vk8, htsq  %>svKw,.S[3eey&ɴUG\jXpT"![Jjޢ%Rapec J4Ҹ̊OżӖ>ީ9t~U:,a__$i*6nzdl0wy 敃6n* <\91.z(q^M` yb,XpB\,UA,A1Ac*^+Nv񺳙X൦d|Q>tѕs}gϷMAXI g> U ^Y҃)nY|?uD(}wOdkշ.unTqu "{ H!ެ6]*Ljƪ /ܹ yowv#< K2E! =7OsV@U|0\ȳ`.RMàM"$bDض6ySEe><@ϛ.kʾyCDRųO/BޝuY2\  5 \0MF.!VNr$7"C9.DA5mKIWӥL$QZO9mCyFU9O5y"GQH KP h̑Ddb"QM7=WPz|lx14*Ϝ9Wc'cvڷ6^fwbsj#AB(WM,iUt&(dfEa 0~<66Q.dRD(1FQc|ZH =LsANQ %2'/-T]-.Bѿm| FKgd#`xP^;u 9ޞꀘb/Fn!F]5T@2[d37Tt -32Pw5!JǤJd. AfsR:g_Fd_BnE9SRfi`Xl0\*aX*xQ@>$^{=9?e>1(4aZȈU̔'Q@6ijv`#8OU! }"3\U- ILIoSRcَl2ŝn X <= |>:>nR>03m#3cKO>o|7WZi>EU=Wa!v{f:6~*f↦{#mܵ2ߵ~h* G"J._c(;7UӆjO B\S| ?A;\>{{'vfZzI$>\{[%-K MुC~jJ6i _c47gc|! RϵYRL $Z6F9/% hBJ8|10o ·{n9܆㞍z.}ϡ,Pr]VDŸܕFMVAh~*?a**/h|X>=Ty€2‚d[E!{͐bjQA#{֛`r=(63Na|.q\dMȊ\Vxipd>e@|&BteصMt5m=5h5= ̠*GSRNt'5lo'\أ)Xyd땡MOWN]D'fsm{low /7ϷwА -sSMۚ(G\W=K$1'2JSYjR&ľv)h?꟤tTM-*yPe%)@Mg[f쁒kZ&&N{$}ŇCwR4wĜX+t>ah!d5 ouQ<ԪlQ+AV}&4<{grC7SuHCCk~% }-)RjdP6e.Avrw//;rMhɓm|i`${PzXFm|SOߙlRczn`ެs;ߠ-)=1#$b[W|W8(eUSPiVl>y'س c}q^U Z _9b|uGTtyMMRwҼ/zfBs}u+34\춟)X C?x- 7-qtO߀tz$2op naBAn&7܋\%FUuS^XsNRV*z;պgbM-۷gBn]S-y/jn6>k+5?fgyДt鱓{xwTNb͎[T+DdOöjU、\Õ5 kMk)'w>G]/JB:\Xߟm}?*GM H+vTĨ>{=כ=P|?Exݾ|MNv:/Y_(ORKe\,IcfV|{g'dA ְbנ\N}D}G7=]ԦUdbS{LJ:pgz>QqWo{lp5moc2!_J˧0wC$Yܰo49obWJ@TŲon9p_w](qb'Jpj:9]u!~GS Ws-{f?S-?f\aS9p^x1u>s "EC+%-%hB"IA]ئ3w={SO8C1kX@W܉wtc܄~*f{]߻.cB_B=euz>fCN_Jh?[Rj|(̣dn(Ȣ 7`V1g3ڈ!誮"[5_BH:$K!'q6sTk#YYr}C\eJt.ʩBy ^&D7?=~.$ Ƌu(k0MMK5L5m|ӝ joNxwRjM2غK%~MZ6a6*8[?I1mlrwΕEkwJpok|a!@ԁUqB=}`8 ;w 1r\'+-s%]:Y5rh/qX!Ф̺vU {;6O|!5p̺.6=0b>_pTϻdҴBL3M7t: Ym74%3k=Af5C+3ݞ xuйKyFHzDU9ڡ䄒+h,:&GڥX7Žcprb|E6\3>~lx(pv1iu5W=T`cDRb6[5*i!lʹe_zD(QGkbb>Z'WډlAaJCY/QLp([р1]5"lA& ETx$\[ܣc~ǸiJMA|6|nas#4 G]NG@AGq zELo~{B=ՑOg{ʥ gURl\>KTzM!] +}6^)~cY3>O!E^EDr &v;|la7eФn'LpHt k,s_Eܳ| Ah_n)[9zp;Y2 RU̲ U%h&I$ Fp8F.L@ _auN35U1YT3c~҅Hl+ѥbU̯.NB &/|1l,;;)[q섕bVIVH}7:ӯd/<{)h w{Rool875SP벣SHC.8,FIw5i\Iz̞P Tߴ 0Z܅S#PZfYx9ifoO!J*( J@`T1 y$LMPEgtZ+9>S,Һ)+a!ݴmma|x37Zf-lw:R)&MV 2О.4Dt8 u-ALKf^`7η$ ̱ wE'a7iI#ۇYlز:ʱsL1wkVl7;ޣxe C/ 7ә;]0R9_gAl hbg,gPBI'Y\Aߊ02ҏ V9H #"&LɳdgjB,an U5+Om?v2na)|(^AC_ &MWI>jv Ög~eP\ op]dS /kAw)S_G7_bXP,$Wz1~m$PN+[X՚ ΞBF? =MDbsh؍XźdN5ؾy?uBl27Ћ5qVA2q۞&.*xQrDAbtaUM,tM%*Y T/wP){v( L>;8ؼ?ϲ{2F? (M?r _{$u|Urb2ΕF^QLf"4#o6.s|YrR#Eg ZrQZ)kɍn?se>܅#Xu;3qFA(Ka% 0x1JGeUpndk|:b7_ HfV2 PُpxXe"a#[1_Nmо鐼;^dS&goyDu{3q */\LPYрQ ]d,0' :,+Qb MNA)JϦQd-l-]?EV˞s< Qp;6pL]i^{~MaT<f?f0H]TIqeCLteY6&ytJKv9#ss/InbfԶ~ \1clI# >FDe7mSh2'ag+H%f{_UH[N{5LT(o'k%&C8/qr2Y[ ;Ai|AV6ӺߠJyAn #?'b&\'w-\HڨsS1UJeZ .>"SW&eUخlC$ux"b U ozuOKao; evx`aƆǷ#+n#ifH806 p** 'M4;Śp?2AEs?L٠RWaA jm"ҙnm5ť,L<ë1Ħ~) &wܙOcpjpU9[kDfe6w+?M7C6le7? ؐp莞ݽ\_8D^l!>(˿5Ӳܴ`0;/=/cIOFw> G7=:\lSQ;[Sl,㑝/x{;[= ˩wEoKǟ7y =~1f:zi':)|Ϲi`Hz4_E>S H&H:mkWPP=/`7>Tv9MSOT1\mqTg<w2&Uw?.ߜliHh]7O|g˂vSY=k_bJw Y͵|SHqVI |+ 푵'T_ǿ^SqMYsm?)ВNLG|tx[ܔ-WHl=/cEJ}Rsyb]z8 gNP(On{Iˇc[ (Ommn:8v>b/懄Hz(ub,; m vY] )@1jnb_X쉽xEڪB2!g{ߓuW49L$:W2͵5sYuBBa\+#[ B 1#jLcƇļyA) ̞@|9bTO֯b]ܵ]H;( PSZ~\U's<0me~SjG'#l`Bb#;Wzx{oC;H 1ݿW$w)ҸO3b D {id-|L볍wGKfQ6 ]TUzK5,E+1aY8t^Ss)mnA:&&4Ƹ*HWNb lRNs"c7=7ޥj1T>CJ@2TUBV61T¡Mr5fn- ageOD>3d=܉͛t ]?9Rl߲MOlv=CW'>@ڹŌ"u@,ۧ @}KݵэO,fi㛟 'u|SIܮ9yΟZ4m-]_ZV27vh__ڜeݪ?Ntg|$ײ,wڧ gqK'nQ:Iu`$jH"6P{53u1|ر\fꮹ)&?8~?Z{.ᒋGiTJo?5uhp 8D=jʩ"B=3gVR[Lt$vJ6spݝ85>; G9p vλs)Q7QO%7ewL[+9!qY᨝g~Mhkc!E_WvZ o:h]K+~bwk@e55+z!qԽʋf\˸2A/>r 3Y7mPGkR$C[-]~ ?~@JqhzMEvo͒^} j1iyj x[/噵ԐꮇHu5:.Jj CzbTvLF-fn]Aq782AYK.>s]BĞ ғ)wO P  HHjk5mU7>DЖc-T;pgbsܬ9'OG1Ckxy"d:nݧ%ҋoLnyXNt%K[)$D=A0S%f'xxw="0z<ڡgP1\|ce`8*$3ٱ޵'qk?k9$4?@m\|jیjK2Z4>U'c$z;GRBf:}ڢƂ\;He쑐CSj5{1g#0 @)8s13]l X g|LDU>C$סP|a z6</1Tͱ+eK>AnxNw~FeAAG!K`@7P[9S;lRyI_ꯠl.Ea$f Wp:+H-+YEV5ek)"@V܊DW|.8_L(I[#(pAv6iwUr>LM_'()_T'2. p;&'9BᓸO`4 UBn5\$@0-*&$ MZ8 joM53\Aו̚>iM/a>"M`]H#* b*g L>FKD[R%ޢ/A*<~ȱó(BS6&5l(9 ),i­ѕ0e0 e R%T5yш1!;t9y4)vDi>}/ުʂ蚂.\JVbvj8&-) yN*'ZCMD8MC }Q>n>? h|\ЊߊGډLu@t@&nC%(6/.3wt 3ˌJ( 9ꪈˎ³'J ]#o  3L6@e\ 7**#wUzo$:i^]멎>J2mesTj6eǸenoY0@NK!2b۫{lۂkyl\]{Yr̬QwjZ{2s ݁];]s0hАqvHts#e&^㞶0WPk^q>ypGrȲ9u;8u[2:0,d 8#K'g=꘳gBNrOb,Jڥ`%۬C,:`y>(1T]r\S=l[ዦCQ띴 {LNgء#x6(n')-!Q7pdľ#@UF̑k68Y2 gԱG 1J״Ÿx_'9&/zV<|(6L}MVݯшH' -~xp۳)"};aN-+*\\%H|0~晚·oBΠ9: d=ͪB4n?܈{&nG7OL$ڝt[8+W#':}^=UY߹؂mGtk}/O?y8(s5}15`τDp1UVDH[f@I'wxn0Ti-t_Z,ܩGٻŽ Yc?Z;gɯ<O}}ߣ6Ϭ@H d`jBFD 1G{/BuR"w p2dM/?pG?Xw@2z. L&^NrLY쨭[м7$E=Z[3L_sWՏ TԸivvgrmXרo9HVZR͏1n(7u1d11RO.m>dI]>O\qq٦mjb eZ=d;ZM]~=1rLj oxL'!I CM(8'n|rV1і!z>4kGfbrKBK꩎rW?x/ч`  uGMy_DISܛ:6~ΕP]Ov=[hh2Bg=ϣ2])v=yc'(%{g@RmBo yyYbD-+++ȤR)I0!ԤݾWyQY&pTWE6,z啎I(Eد 0ܽnQPX UTT>N>ꢙ$&Xkj6DLŔ6'f3լl'3`Ha\=(^@:RMR?:HK-ءU >-uHF`zysl$ihJdbpTt'Ƥ5Ymf~&dM1౭FH\rP$鲀=kqf($C>PvhHA&^WHX.a5S*ݠfs82ppTPRTW+H*n&LSzS,r66`z5HI6&dM$KBBtB3ƽwJUb;$۲ '4w-9swX#QbXb)M!E_Eəu]8R<l&wp)vȅb[V\?^!B۹,pϻQZRDap]?.[exxɬ>ouLqgd:;fޥݗD8dEȥ5ֻN&Al*.7"+"piQJy^5Vl\R>3izlnyqO%gpEXGF#cvj'GyI XPj1xe1{;F:|gVeœ,n=\wfUE\u@gS=( CÃ8UC12D]S+\pyWqFɈk ЦkXHU.B`fp<3ט_)WeX|Ҵ쪌$I2Z8z \n"*`jSG M-~5>1" ?I NAr(.3@/ϻ~/]~#lrÝ_EV4j£ee@\2ȄDiɡŒZ}$.؂7xsD1 XXve~ϣt~E@-8թפ}q1`EJ%.`%H“!Caצ ^{N~_G Ŷ!RT.1a`KCc%6 f.^<~G}9 [AНK:«n*FGu&IakJfr z#_#2`PEa<[،50 Yp"zmYP}Isk,hڦ^C=< ͨw (wEd>7=z_ff|xS -4Z[?Vn*1'ao,$#򉯇kFv32(PFl'ndo6ͿA 02?aـnþq.Ωʘ!(̀$, j#|#1)aJΊ0R_X@]>FQNLzCrUb$d]z0s /m KQyD骫-/Ď?+kY^rG_FY *wSe i&(L$(YhiuwG61nl*9,۟/_̦i/hdM&60ytpӀo.l*X!͓#G#F+Z!=/rM8_W 4*YBR@:'z`;-3MYR6.z 4*؇'{]͵mNw 9N;UWIֵ>Iu= fg6Ikf5s->rgJ!ܥ@4\4@B 6ۼSK<5fh3==tRGtz@&0+(kQB1VNA}Ѹ@ą_ VwLM].6o<)k:['i+ a+kH*3i{ -MMP)q#o,@G, `Dcr`S:`@-q8\ o8f݁F4Z=g (/BM)lWm09Ρ%󢏱)b6V9i+v ] ͂'YMz߁J4M+>x]%,} ql8ᙷ&x\?W/­. !'yaRۉ^6.ʒN%)ٟ;b)o-j>iۋǣb$qm,!VpB^8؁ڼR_aɆ > ԑ7d 1܉9ܩoH"CyRƅSTI }='jb=(5~wzkpw`*tSHY4 B1ق]Co}K(u_MJ' ͯ .IOkyK#tOd*1:dfz)'#oPSu;#WloKS#E{r=5-uH 0$}/T#PA7Mjx؛԰bdAh"F\BJ|Q2 r(5d^3#\` ۓuDl~5՝iۍ0NxKObE}Er|;F{rQHCQ2s'r}]'D5.' }ZOw9u!|klW撈v:4s~6]Ldr b/:f܁[ǧڒmqG8h9BOBunc[$8Ԓ;ل`,. vN]k\ZI4ԇjrE048MPG49W8ƛ aX;[Mܦ+k@kGgR젬sius.)Z~ĦLgRR) fL]!jɴnR}@_ Eط6nLIeNk*}OQUAЗGSV3SnUC{߲6Pb]d[7rZ֭FVh{~`˳tb%r,ٸEw$YTUi}@Whzzza<`0όh:}m>cMnt/_E։xބ7C͝j).H?+Hh]H0O\S,CW/Y|Sq\tNYt5BpDq XNL㈻`%[myK>6^|OA |JhO=sn{N`i>" I{b3 9k +U܎E5C~Hω5w_ChӓY2ZbMz",+B[u_績zRoCk_;ׂ0 :聣Y{!s ;T߈@V,˺S"xrCD&7{ˏ\b(D3E6ȆBҟM%n}lX,@I6?D ؤ2Zn&D#!9s#V`6/PZnk&"u+S.t{bC;E^h%-:ZL+Z6=st+BZo7zuqُ={w㛙;z.KQ?eYzsHrS]Mn|r*" _Ԫ>kZ?:rxp=ru߭+26w>xwV?("T\1񉝿|)v%`f ImRA+HR5UoFSsGs O)9)|7}45J?bcȵ%n'dWb7IU,>Z~H=غeU\_0{%w\_vXDue,1=(a&KBl_tlw药W@Wek'2l(wm]6@|N@H~O=?Ðv[Lf<3ےqdH'.G ֲbϼ"so %Ʈd[s?_z͗l?35ƅ`:4럶%6Q2ӽV9|7q)" I)-ӊQy e%w>TQ.ܯd,e}mQL3>[~C0; g,R 'Ux T_]ELmߤH1ڥr%[~$ÞlɆz҉V3(Q* Cb}?*2h\SUe)%0并 Rf8( ,F95Q}=e7EPO%^SMi-5+n 9M"%G"lKd7k+opୟqɴjxQ6ɀwecb >]~?iٮ fW}ͪ|jM Uџ!B2n'F .Ee+E#j5x_GePXyw]6l"UT6J0AV9^3 tr>e6MzܳW Jug;( I_WzH,){|- EetxyPɝؕt6u9AsΑ>IJz ն7۶VJݿf&[s6=UYbo[ gx&v ~Wo{, #ßk]ϙAI㦺խθ⨵׾ĥUKqBT)*,n)l=lСCΚickKR뿍yo"(Z:me\T"HN1\l}Auh?jt iu@Ub6jک+ɍk1PeQ;x&9nDAS]ߓiil^1کDuOs%սyh2Sn-BʨΊW ۤZ\6>6B3;Џ5/⬵4E♞-CkPeT^A.vd&eD돮ytu5YKr$H+m\}ɸ|ʷTt`2#k2~Jb`!}V] ٔhZ+;6*ŝ%cYY9A7+ojQv5p)/pVk@4♀qO^{ 1 !$cD6>tUEDlSn5"$F OGPQҞIj,ݼT o!'!&Hk~1zB&Z(AC\/ܱ^TƷ.9t UZmc;h~iGQRuk[$YɅyG:<X L׆6bqxr"=/^ڜi9UiQ% _y_YgctDqޠWﱽKLZ9e@jz1Gr-َyf\fSJX#AVE ?F}ǣşurǸIo1.eJPhu1D[y>嚵O0SnsOJfn~*[rL㎷0kmMɵjO?<Ȓ9.{mx"`f]~?*45 +,eURF{/ڤH/lnUͱVd:i.OlSIuҍޙue!`N 8˧ t̼f GW;ZJkx%n euxKqW%魱.'@RLg)$  ] pg%DpLw [z[⩞a匧tc (&/#Etp:(+ *鞽r-P ũOZJJJ>܉*(7P|5,\ńg|X븹tp.q[j xYق\!fҝIdR;ɢwfEQ1# O2Z W81pӁۯifrIHZ9K˥-RjW 9y,% ^H05WYr |e<h,blH_>%, گKJ%d8K`x]x*6r'v~-^[qP_]a]eI722K<-)x%U8LQ+.xn p9OQ%Hw)fqʧv@8j!J^JW+>U0hrѽV_3I+5әEy̱^׼TWg-tpe0uz%|K?fr] DdϢOvv2c,: 2:P8B]EF{]5!|hp7E,UE=лفy[h}u_vlNȨo5XA]2Uv=X"&bT\?PM:"*9N6< ʮ`>O1)#.A2dăSB ީʅmםȻ_GA>=NZ>D ã j_w8Y{k.״% .Y]=LL?ȌьC;2^4=sǶgN6D0x%0CNx}h\C( / H2 |B+9Fȃ{ü81``ҜEBX+i GĜl4A(?Z>@ > D9P G({MF*i$KWbZG^sRaJ󒔊஠IG g46R> vj<i 7|#55Q@h;<[ '/jK^nH!NBe 04Y)#r0 Mc <Ό~G|8ު`ǀь4&s~)#Σ4fuxY"6u<7F;Z:(l_ 4\2Jd8[Ld.z @( " 9."aC<2K"8Мm Œ_[Hb4!+'ʱnIl\TG=BX >`͠!OY0z:a6b=eJ!gTYnFFGLRkpꟴyE_`$ 8"=gGbB sk( DzK#v!cCS?BXU'\~0戀BW2)]r֮>iBazLZE{hjR3dC HO (@a^ f:"0wdz){ʥG(ح"t xpƦrIp eld漅t5Ic}…ߍj.&s*EL٠i Ӕ\u1TSd6שvUrjH(DB)]c! J{TbMF"8v_$F d .c}N9xF ;&F{qg X5UwA(0cD:*޺b**2i.됝9ȉ!KD>qdSϓ5V tA.ҥ$t ݁?5c8WRm{O#\A1ԑ?ޛf֗}C!j6^x۩DYNL?;Wg(smt>B_b]˘oz\ZUQ+^U+ :eaۨCp X^:j\b}]txo3@ɪ lǾg&1֒N<d"#S6c*/+z}ʹmxj_QD}OQz9 7CQ3q>$:{UQE3MkƾSC6@6nmyp~s4ЪT40ܽ~}]__X?F6ߝ{$r+RsGɢjP; ;P1%F3 m}\yϪ9iXӲx\*c]o|˱=/%O+}TWwg:=v=ƃC7ytjS=φ7OEnyg`w2Yw|& ~ >?ɡq݇2^W僘JD~g|FS|-kx6z B _l?=}<RX5EV1hB} X(*1b |)B.RMxg簩ѭXk\(sϧ798@+ٖ:Ru/*.!Y28+-#Vaa dU}ͩΈ4?gsz_&|)蚾H$hjR7 >.èmqJ׼ccɎ׼[m킮v;=55=v;C&۪HmIW1g.JZ.޼{|h:M\R+96l)D 8ȱ?*H x緳;kyOG~uk,ŚuRdˢqwE0Dt`B( ` `5InUM?sYwJoNd;\U=W}KlKEo'G\usгbF,* Th?./? S|XJ뿔iw浨 c;u [?b%w _NE2e_dWVό%_D#e>Y+Gdcپ`*wJX=I!İDBMuX}l|ϼ_84b5Ɇ׀k~Ϥ6|';)< yP-a62cpsdOLm_!iRKtɧm/u0E_&ܓjȒZq&۷Ŭ+n \O*oF\%!)Rn\4Xm?叨.Ⱥ5ӹ \_t[t̓RVrw(lj -:p,ou#t w uWqh2K))pOJDzr/~}ݗ'~Q; wOId)zg.3.Z=* WЃh\ÞkjO="eYfֿO.\1‚wBp^BnjOJiwlԛ9)DE\΄e‡[Oh$껡GM\ծ +?\"nͿUn{8Q4x'3QR2 "oEWʘ@0(-Ʒ mGIP #-p cl$mh;ȥ\Gd9ǓL1JҘ>Q%0\KIPLjytr-cո!])# ]dM$I@lv(2l­3鶓*;ȑdw|gv&t ][ +Ydza@GɆmښet?bdh-+x>h&Riu.̛8T$;,Ӿ_/lUt͒l%'lK.%KkڻUdJPÎ3rQotm'2 *mǒRz}ܓ;^o8O\+~5Ǖ? B׎\(`R9]Ĝ*YJ'+\\IEg&-Uߙ#*ƖLov]ԎWUSW *huNz_uu8'թn5+xBD&'^/}llt=F35-`*Y28F34UBH.&POagþW;7 .=~Ϣh JKySlv|UTZ6nyd;pg 4Ե&z5)Qc#e/jBmY(ZMSg;ћ$G,A(rKi%ÊH~1w';IFHws<RGDj">M%J˿v%kch)Rfʰ&§UYd ή5;܍eT!p+mE\vCkBhE5THgZ2=g*'԰(ʑؔCWND2nFFzoߛRF1 3f=/+@|2l&. vH"”y\3Č[RT 50*ktpiwu_ +1gu֗%qٽWbSHgӍ4X6rGwn=/xh׋dōś"Ij3>iQ$s,=;'̒%޳2y֭i{UɃkd+3a9eepubv+᭑C[b[d_w>CIw(8 BLeۿ.qMCǁͫk`ˋ00^+jDl5Lɶ[k{:*QSw+- +N i;!=CvD%3_YeQcrq*jn PW7l#`TDeHkxCT,9rGWqcH>b8R6ϼe̾IItQMK8˯KlYUs[* O*x0xۿrOh|:6[%)aINqgILIuag }-3H Y,nc?л.L]?$o>'C\rTFpYAp3h1.ռ GiO,LyF!Ae ܜ9hdXpiM{6DlY5vThr,IC7}L1a츊(o9f![Q6m}1Ied`6OT.)+| rSEr&A:JP#T!yHV=yuzk<1'P {^D=T-QQd^td*ny;T5(]Xt٭b߾L!+&a<Ф}{@;.zK?osJ=OfۛiqOG sMJ6x5׭dO*c1x6`D~=Xଚd(9Vi\fLM2ݰ IM'r,RCL5^lAΌ6~L&4\ c3)J-D|r>,Dj|0DT+͉#SA4vئ:\E& \F‹(EmBV@IWWg}Cp,ϒiӤԔBLo9JjhNk?'kgq<~5'^5E镤6>Tf,5/Bss*/}W3^j`HtS7dEW *oZ*l.*|l?R.LTB3jr=#_AFg+43g>[>S$?[z!ps7lSwԔQGGbVf|Wy̥rz 7kq lDGȢ!<ۯ1@^D`"kXBLUAdp ?rBHgcFOu>}Al>H/:A), R*ئg89FMXQ M;mteK:p_u7 Ha_@xhChy$Aǒg0'R8kʃ- ˕eA8]8ss7~>swts 1>j!Yywqӫ2: ` 7gt>/oar_ @Hx+-3]^3 M2,LiYY ˌz6knb4g_X| %gQr4Q`ɧ IE"_-X/ܜ-?pW A=/0M]TeL|836(D0᱀?EГ ݼ`k}+2ݏb'$_{2@sKEZׅ͜pSCvKRTΛ9]Y <4%]u3˜8l cp!ae#wѵ ~/l/B^@LdNʘꭏ٣0q+A{zM 40}u9 `&m] %. WU׋?{/r^͓{ !geopowGg#,LK\Úl\܏PwyVR ڕA- 3\6X%[kp:JyPflWNQ@ ,,!hÙ/ IRqWe ]_*%w2av GD]Da)W/Nt.«'ܡU2S%4cay@=;ʮw7e>n+)(`䎽y~=i:ޚafLly:Sǘ]0] ԂqߖS]+nmJr}&"i05X/KY&LH,Ed܍ lĚegiTyajaEN~)oZ״)^PQ͆ 두MX5z?u^D)Ԧ~c=fe|EՏWKͿӒGB J")!͢Z8պ a}K>NZIK]WȭE18*^rkL_/장S{Ӳ/ iѳj  ^͜i&R U۟fjI>ג}G F$7u,}eAp0@rZeY&&>:IV\}m@iʯ"IKʇ6zW׽oyO&-5ҤwGWdI k"hC8!Lbx07"0Ŋ@Guh%a[1fS}Cn|䃱ly3$ Vu}v%=66@ 聽9K-:BpO Tv/!ldJk׸X>{t2F#p _/K*p-[^BSMnPgB )U}1VlcF)tpe|dip-nڸ؉\O;U2(۰WeMuP^@˅=㔿2ײw 'kjǔF:ŭ%ȡn7T__yh.5L%ЮM`Qc+l?ix#v`%=#ًG6/rI'1!ٖ9YrWK= BpeMACŶk󔌖.۶)zwbZ\(ם/Zz%-o'USc'#^}3\n}4ajDajꬪʧ\rJlCdE 4{{ umzF4D+iC9hQRKK5{93~>>[y5J2n tWFszv%8Uɣ9%=L[kV1 5g-G'ak|U!\azUuc(k,&i9ك( nzw@U΀ǜExj4ԯ4Q\S\o^|k,⮠o rxB;hB?Pls/J^x#4ܩ((W[W%>$~ߩ֍]Ojr6qxӲd[1inaڞTȣg}#srM'b%޿ r"Y_sHtd&gbUlԿ}g-5Pmp̸)L_VD梃}\0}XG>l[.7*_KutP65*eKrl=+cH%Ϫa\{3#58{7K}83&RKY0淈o*d zC=g(~Tk 9]mw~ SJ葝B[f L n\WZd{Qߙ]n[{rI@R. R%!.$iޫ"V]ZmߝeBqrN;}O<۵󕾳u<-@-9pWԭl9qChw[8QzFMO#b~uߩ5}N,u _{dnO|ss2?:bLs* 2'dyNyAi>9ul|9)-URiѣ5TK +tI'>ۗ%uj|)*kh)8LJڔIzMc^)߷fd&LF望s]{H;IS7˽{y!}yhu϶_=;v$h E 3Yrv8]xyjkj, Yފޮ Q$O6(5`5\d YStj{2_Tm;6.wBlU zO ±x[SNhd %ឣ{^D.m]V zeb$!ۜ#D E`.гklK[DZ'dv$Cȿ4yIc3"԰!ulՠuW%Eق#(7[sd?Pö+~gf.(m⸉7ht qr7\e+npӡ^h7|5XK[WXɜ`INaMf]kiĩp:f> 8POYwIpbsdI6g'&μ9鱔ܖ4.0.P`CL!K?k魶CJT냰E?=al6X -4[g̔d!?'!gA&½g5gÅdkE k ƕ]o$$ *ZLtrMG%L\ w#!)k!&AeLISX0=q;l^Rɭ̘amӽU52R>51zg-+[p@%iЫZB._ꮣ37?ռ=}XWڐ3MRh;J!X{мc -)+:{l$ClI"LqJ=Z{zn']duwӊ?6]߄8kFpˢȞ:cL履ت}u u`WCP(L;AsHǮO!qN \!gG;qw#>,x:cFS\{4!"b.&gh[[gm#r Ö3Gˆlav!gŧyF  خJ8hJbjb29xٻ!h3-oKuV \cЛBBVMB}NQr_>ֱG]eYg->_e5ѵg!*,T,RtgNŨw׭KAY3Eᓴϕ@#  {8wڒ6U5Q1͛68ŮOn\5ƴ sbҵ4K\LOt=!b]WîΠߚ;ս?[7T 6]T?YTvxȜpT[7 *pT_Y%>ΜhKZ.]]&F䆔z{~lȲHpXkJJ6 %ә&tx;MZ1' 6שKdFYGi'6&ŅSrx$,u$a vC$ օ"zC|hG,Bs) "nʞ mz}j aW.6̓utIeظ_kOdƐƞwkL(!6iLCgAo<&G-Uzp?7@'S<&큸 %/z}FatbPoBk"*DGcO w v&[BLˆ4K8ӫ0Z)ӭBcFNݺAxkIDkV°& F!-^ WkxlV| '5%XoIق=G1:{-(a:3bΚļG'aG Z4E#ڰߧ1{*ShB`>63{#hq6{OV\\+ 鉀i\QQXGyzPJN1g1k@Y:9(XsMII#5/a#m~ْQl;+Xk3!OTW2EEUG"oݾCbuo]ġ ]^W]h| :vDyo! ّW/v7խTC_vKC Vƨ,lI Ecbʉ}{YL@ Os']^qC: T QMqK R"xўЗ/I]: Ai͔ t>ˑ!`rbEMOP҇Iє"_>Mai;ܰm&~)%o? ODz2Ghp+95 3'ũt }'Nk]-^ SPWO1(ډ/!$ G |DŒJ&2D#+J{L'ѪQ(7/_lUB'&)ͩRA>Ķ1`4) ѱ6[`Mƾ UF*qvk>Hʈ@,CJΊKq}E/pS'i \얡e ')Y';(J@p0.'r蹣 rSUȍV@sh9Vq]LϽ2 ^,^D.$MB-jg Kdd07&7e2?'d^ s0%>.`U#PdՆ(qGyR䊂p0=S`MKӎoh4aQﭡC.Rϗ]$kQdv@x"+]WQHz*/hx/GJ5f_:"]4 CD\Qy.M-&ή#ʄ9IUKDx< ӝj!;EU^V#>^lj% p8}ar85\qcʀ5ֵPÓ_lշ1CrmZl$ 5R;koXAg$3+x$ Ge_@Zt֢ۃ،CFk#q W"`|2x+z܏2É  QL>S 4p,fLD}+*jQ<%8߆ٳQALmpv}(HaO3\B3FN/EN # KUX e ܅䈄cU0#e .A<3*Sd^G FBFL2=@fYhj!LJ(ZmTbwy%

@\B?jF@T2%4#J~-.lߏ(6 O_|A%+‚:[-6q6p OY@W;t}矱 ) C]L`DttBkB^6lGcc u0T-1on!4hDjSsSJcDc^09A q$qd%J-rO]z#:3F0Յ6 -XX ha[VBu "FOiQ~~`7L 0%rJ2F&!ΰ`1cm()Y;48{وDH`=$pt?U8Wڤ#6b*Ws]=jq$vx6 6F;⿞$oD6]xi9jS CQ[h@'Hؙ꫱s5~_8x  8}}n8U>e?4؁$(6O"{W ^EBg;Jv!~%v֊8 "Ŏ67ۚ)Օ4('!z c (?%o $\EnX&/=l$8mh|KOf`Z; ^e8jTFmV3 3{bU SE*֙eR8ƍ79ֽdtcpFďT_8S]53B$_y|bY2dKEb V|*}cB 4b{Gd ]< އwa: &+waПGÆ <<'֯`ESQԥ&x Tl߂z_@#o&'wϣZw >UL1*F1Sދw `N,!iVdx^9BǢ/#t6 s~( 2kR T?z~ɸ"Y|f\81{©$މ3H IЧ.mEZ,ʙpMJz#QHË.ЍQz7 (4- xY[gFLCZ)g=x+8~1a}i`Ew3G@G>|v3錞:<" taf5HK# PX_ԸaKyčb2qg!Ezp^n ^ܹ )d=GqC2czT_#@:G-p2zՃxd bq RP.l`[Q:+fƠŋj#GY||Z4{ƻ;sd{}kEm' /+&5pqV 3!7|=L-ڂ8s L;&ҧȱ}ahQ^Byn,}iyeַBſ܇wE_~Vߋ%aWxsps>^[ً 7\;K\9<- [Px)3'݀9a|d'.ފq&+>w3VqWa)؉015bɻ0fF sBsx[ W̘5pAoF/3bomN~KƫE};c8 {!&PFȆwpǗnwWl YuWIø2ChTF;t؎'e ߍ'˞0fހl|y`2,#N;(08cXL> @m] YJYCnYP܏Y9Xۢ>'nl=0#&n촘FXx薰h6Vo @ֆF&F7Oq6aB<0 -ݘ?_O=37KԪwsnǽpt?P$cr\S,vE"dd,XsXg ä!Dܿ<'wpT_z`DVbINn+~+qF ӦE`SP"i(,DU%ĸ(+A~BF EZE&Ѣ/~!ᰐ>y1's*5Xxw#oÜ W5'vQ|~oΈG 8q4ɩޢ A|9 j4t#f-8|G"APK&!+ӂ:i?KQp=> 2M eq{tAC]7a!y4vA0yj5aTP݌"}y ؃~Ln!#2bG1ڈ1?wdƑ3¯Cf9ٵq'#8Ս'|0p5od ;;Py'?4%$[kz}d#Ecܲ2\LqM Ex~{sܾo@]SIۍUɟo S9iP,"XWGg$Gfsi1~? b2qthiq5xwV""jG6F䰙8S=g6h%3,.TT Y L1ˎ&:G&/ Ihn0[XO D3kQLIsǥ@FQTlCxg)| ir7V3%daIļ}?bziNŽM_|/Xa5BpPZT]Ӊ2hr=oCyT~b1Üoj11A igG|3InˮPza63g Q?1BI/@o <2 x:_AWzxRQce NzZ{Y1RFXesNBO?߁iVK*seOG$Sf{l"b&: p|bgv#fsB"0񘀯?LLƋ'`(J16Xd O&9X+Ohp+(lcbfbäQQҢ~Vp,\>%TUgQI@ @:ekp.g$D,LIxKR2d%LeMSf1 izf^\ [ mJ5 \eN! ؼU2؅d92%dláfB98kQ0ör[98vd(}8pY|&ݔ=Ձ93@3E;a/&܌IM[,ce 7I12E2Ti#s<6mE8o2۰ckg8FB=}ǝcT.э c|gGi*Q8Ӏ p:|SL99 6mō y+1z{Na`xXDYY ["LqM bFa:ỷ"vԎع;O֢dk̿&C/#c4Fh WcΌD1̞rs 50zL;pf"YDQ ъ 6d$ȘdfR$.ƙgNQ8| >r)4it(}.$e !p(A"#fl݃l$4Й>?:d^s@q )h;Kĝ`k pm8 gZ[SQdVhEj:RgAr6jauK(ğ)1 6΢Mm2JGg7݀J 8? cņ=/&;\\dUEWv"xuq!l$ gQ {J"i@zj zʂ#,cyٌ޴:5#9U'rơh:fT;¼-I`Rr*u5z3{lzwA*9 tԽ,{%blQm޵Ǿ*?pWEcJmmO"#@^81->-;ZMu#¢(3ӃsϤ\)>E̽+(Q<0`r7~ /3_pZZZ[/P0ʟjyMG,U ޻Em8LZF4̋_A!8C78̕>x_1#7H("C4!_ Nh̉- :Gqބ*  Hܬs푡ux.2Qk] xg=4h_FEVcf}' ȥ^qFg_rCx;z=ި|h㯩:a҈aS/96=,}AP~8ʛ4ī ./>q )m2g -8sϏFm+CYžZc:SX_DT qt\1h$ ._duI#yz^M(Ux*B/KpH GV~ģHA~j|XQȡWwF|(F-9`8 oďQ/)~Z8oWF%%]Mj3o}$l:]z$jHgWD\Y7ȐP La2 2er^x .mm8vvp*aGFCX*NiIE^;xC3 "i<@d[?0c)o?lĴԟ?I(T9es+}ztobMw7f)sO0M2vu]֩Sd=.Nwud6#o-ZMO>^湰wLO˵&G<Q 4#'^_7D-ᨌ?ItGqi(`" | jv\Ifܫ5 aiN GS@ fЍ4Ƨ@A d9}M p%JhzzToGdixSlȧޔѪn\0٨C%KdFO oy4AP>^(ku!| 3჆upfe$4:j ywd4 jId|2N]ZV-^!!!̾)PqQ U"T.GPTˑNP(Ǚ^b4LF8Vɑw?ŗCO($|V.Fe>a'cG~(߁Go#^ QՁXt/\1~!nW,֏Gd;'0ygq׃R#$ UoNO=Xyc21|#ZI4 G/CamQ2 ^(VL.L71^SQBEJ1id pΉDo-X;UxFj˜}0:F, uxMc9W#jp͵4A^>bf{ HkKa|<.,oނ)cʙ)"Zޚ*x{CT"wpzAg.ƍIRoLu|"/rakxPqe `e!n%-Ѧ)RTԶ`1jbfءh5ѪȐEʼvu LM$c,z%z^~yɼYǽa$T. #Sm,{ތ:U-fu~TmHwj |j2TO}/ym8FT+pn|ٸv*-FUvV`i,z`9X\CVoS%%:݌d \.nm1;5qH0h/ѷ`? 9sKL#*&jUedjO%m'&cƵyr]XE 2(4&h;&27~{Qj$RꥄYq:Q8P n{ٙF6Zu~4̖y94GI &7<j>+TƧLDhh0;ᤂ/-6pytvD\6R1޽! bup0#!?*!kRm5$D[rw=~w)`(o`6kk{ &gps>}?-ɱ0gRK].2 kF|7}ݑrC<n67?zg!A`f&tl[푳]0R;^[Fa:){#ݎ.%@~*nĖT\0CaR;@6a*$"҉۰acOi>,[N]&3{;a^!kT3Ft&&vnE/=#ZJq0m 6"< `ʂŃ^z۱e.T#MxMBzt+oPk%[f E+BRDHq$B{v`Vd}mn]#0g 5gJPoĦBI.oo”XA{;2Ax?uw!:k8ӉQE88&1HovKpMx-8zRD><+EJR-CNUBIe,YoUcD %Om' h9}_`Zxqt6FA>"H㭍4k)ol/'\ &LEV$+޻q T "ٙYryQaz &_}_} 'kB5dB1oh`MGm1$z| nE<Îè8U}H!B] m^چ ʥl=g6HEkV"eR,܉>'p@v{(asx;~ZR}N(RQSd1YǛc<3e&ikOGQz3m}4g<$hQfc12VӅcpl،J:¯{ڇ# )bhLJ(1@SqU4d|6_BWV@2`tÙF{ cK%}N2sݒI[f,{ދ| ^^E!lۏCQR{',r`':4 {Oo z5X.{ic迂HZj᭝a>:aCPǪvQ@;Vu GPh BA0m&!<&8]!b{r z]>6$sD qZ+325Wu›! +$D,f:P*o[<+ x /*wP;k.=-B- -?sfބ?{q0uDߌ804.ۀn$@̤LOcjOG_%֝@l:V>}'M|pI?cHT< a8-ֳG &0l"^JّCg0zL.C7acćqPOsj"m,%,i A֡( DN>6Ҕ ` ={P:`4iPu7 ;i9aw`CBQT||' LHP>Em+x7g:Q8LfeA 3k =G>o85#| ڴ+Z3J~$%G0= `*͟gArq;]X'ѓAŤXͬz y)ە#+-Ȝ@ckajQ''H][C-&%$hQE4Auu&JVb'}r s-u#HJgQ]4u~e`^^| Ev:'ar"YX2nM@FfNy<i#,0*C0ǹבp{oAI3(zJ\yisOَ adBM᩟bx ي{ Xj L}gan m?Ay/y r=U, OQɷf.7pwc~#:k' P ۟YgDI~AN-s((w"e.O厂Djb~'ҟU.Ͻ/Bxa)z0=9y4Bv 8 @s6 H>7_ nuI3-r1¦ginCa6fPC&}LfsUpsǠi26i,eO5AC%^Zp`]DiBTKQ0dcRE8k^p+]':t Evf?kf#unu plI%Z`":äo@ pudVZ@˜Q\R.ہ_=6C~7 d$#-~qTg*i,ɽ)cpBBBIH IH !/By)qw{%KZm;}Yr–||FZ޹s߁sσa/eکYFRW9ЏR4k_&;c=] S'ÒMTn[3?]S9NCLm#dg"̷z/b jAA" hx=xw ˰3Lr/cGe-kMf555Yh"5 |x1S=¦(@3iڜBT鉈l u.+f1OC4PRj{1DΦӠP d )Z,>[>76knw%ԆhhݍjxզDf&DĴ@jp  1mD#.'v~!k[Ģ'. OLT 4c plCQQko2}EjQP\U&yf#!c1@: Er7lu8C *W%Y") 8*כl.uuؐ44*[uG`t< 8,pKM4ƌC۝u5,߈5bpR\GCs64tY^W& ,HumK;\D Pl6(NE(Oɘ&{ @20ytõatv6M<$ڨDOFx Wh[[ GN08mn|d *Z[S2gsN~reW7o*X. 1-Ptr| KA< lB6F` `pSyl<¶rli>!uhpE#TN4"4BOAdApB~T.;Ź.'1_@H92u?Hg_2{GW~tY1xjEt^c-ψ^.|O@H UNAf00fo.?;FDykЖ}ğS|]eG!Tj0`"|:~*[_a! dqa/ĔVV Bta`ą"ٛV-JUږNr٧55u(c= YrAUk h͍`[cTKq%9ŕf:,š*J\!n>wS[;.L>CQ!h;[u'SU'$O g|w!r ]+`Ove盛e0G#/S3L*  &7vu"v{y۬z۫vKU۳܌] 18VWʠY W)/HX-uu"x5_Lzz< E3`l6 eDOZ4g\4Z>'nЉJv`hDމJ_4>LmHI褐(rWf0H([ Ѕ]I塡=ɯ-9O5|b՚%{$)HކI*M,}[0˰=qŠbYѷڕ)zjIUE7- a#Gef}cƥВ*ٺrY.PzU#$3&NȞ^[#0,LJE`Jl1C"6E P7?W`R3! >`B_X.aw }6w`FlۖA8")8IQDZT2 *h/𑘟K<Aii%-Ap6 f#V{2&t.,z4P_"2fD+J٥1@ c'|LVdiG^ a.L76TO E]5P@ф'A.D3 xbx zJ|4)wA!>n^4B:'##^p9( [/X ytNذоVoe&>[ĪZN"r^# l@ylMnS0_iz=Ө^Ȇwt`b5}m!]-(@qleN[[;,|. 6?\ĎuUbahv!Ŀ> m'HB^ ׂ o5UX=@vhDC#{4ilg/;'f,X1Oym3B ] #,1ZJس/\ ܍zeX1͐CfCjbB .2򲝭v#6zQX "R kr}xcCf ,B&:&68v"̓jFhs3 _1,4[!|Bz:f` iܺv9lډVZ6[6fԸDn_>R/Xx ע{O% *5%Dn O4Jt)52ز Qlr.<2bՊ;kʰr9%GHZԾ-9|vصoړ(q;)Hfa%F1[V3qIkr9,JC%0e/ٗ5`(l+ ou SR- I`qJ .2,?-f!J>>JIb&Z‡2< `]6mׯB {AcQR ػ"aFˡ ! &kW#0 1@ UtV rEX{H bB~زm\ +vt G#c7|ڋ/b,~.Z,[Kg"gB1 z͛Gv?>r4Z}́M+kk 8`(kW t$q$ !NEFxd&dd$!DҠI ;[D: -9z':V,NT9؃UY%5:8T& ,yz{/JlbߴC+25Gˑkd̳ұ}}4E33>փIK)X ޟQ8/,Ұe%YCl$0mA,_$H| siI5IS΄bm0hXZbVCظF͏0tXNI-XEfV͂y[fKaRH> W| KfM-|j oỏq3 =HA P 6r#p͠g߃Sk7ioVlsb``)h"8炭`Vq䊰})ͼ(m|~<[r1  >M0? G@^!탶0m57]I sa_. orTݻa;^҄ )5H쀆qyXG[@ Z9q {Nh_?|>xF!`41,¢pw?CGfH8m;L"L&WBۡP }GBMaaw`8AG V4:=Ɯ "YpPxi6bx B7Sͯw,پ6 -='aMaж6Go@*KADA*D h@sm[`ŗw 6 VA.x`@x ذJ+a|/H9@kY."xYBh}`l۠ޏ3+nwfb[K]K0ݰ =&GGphCSX&fN"L kwWga1> 6 k?#aKGw]_WgEH-o 3:/5WAn4fNa5Sოpi{$@~喢9س@],:KIuS`/ptJNH9·A^xx&o¦|w>r0'.Ӝpg_QgҺ8R S΃΅!#+7Bn מX3nOހe:̾ olLߺ I7t8,ssv n1R,b7La`hh+/ʠ+ӜGqn#-w0?triؼ\?6܎Mm欄3,HpTԯwaRn|BX45pFزyp&`L,.KB!G3f@fwq90n:X@*K7_6 CLHNj lkusA"6!H?d &x= E␘-N F`{khh0rhq5ڄO (b aD=v+\q3\7 f0" a{3S{k0,cIŸNXlʨ!u>& ,ۙB$A=>yvEd3ؾٶy WA7MN69z }ltD]& ԍ_?>-DDg7 <{v(!2*T3n*7ҰBDK!p7! Ϟ53h*R 7}6]#p-зT /`H,L{5`Qd2J91&%!R{͸N hbۖxw6T!5gO\c;}NX 7 pJ".j$ӆSшn L_~q^]W(e ]ĺ1z\9@͋{`ز);ډ|61-<[av`d?`vdlV ی{6+A!;p*$O`JB8ld9b(҂ bCF8}<$>7^O <x6zldL'hutڠ\%T`}؍#epɩ((  suԈxnDҍ> `x}X8%o[aFe2Yh52#=rXЈgai5OmٴۭeU arB/PlWw X Uaؾޞc.Q0怫.ĊXz9yp{6hvWFD w^@кbZb 6%0lޫh~ZNG_ Xoτ!4>ͦm;a_cZ 6B%`s!u( ͤ!,Xx|D:hu`hWY<q6 odxh[he -ip?BSpؕSb? B 8Hof<X!vxExV漈J豜v!L臉3O0o.BN^Otco<4҄ %k¶âa XZr o ;0~ CvmsY8u<|FO>^lA+'/]X̴5H& .xyc>'!YB<6;q ڊ`!/J*@Z4US[ da,+,9 U)Ӟ릃E_D]υ_~`bFe5且./&ka]3L^[t/ cFBЃpcoc !`\551gV8m: cSwMIQKp-䈘(tư-:D1.꽰z5b^t6|n< F#w(zع 6|mmY1&0BdD=l  N?[C~qTBJhb vm.?V/Ğ&Ô{Zad4aKq{.> g#bѪh^{vYpdaꕠK_!y[oți|\*f8ĕh99Jl09LQVٹS\ǍJ0Di{2#ni7m`HWQä |H= 2 ,V5k Q "ECDFbq'RpH4y2wX,nfl67^DC( +2/+ e'_*É r'0 `Y mv|ĸ1jUґ,;H2 lrQh58~X^2-d+kQ+Xemt;6DN=IqTn@?e/c5B#qJgNtN CLN5Q9!怳·-8? \6Gk\`v7.p:w}`=qA ּqݝR=yz~r_WPlÏ|+-ftg!=p:QfG_aw;ҿZ_H1f~jj/5摶-1<d6 @r.s^3tΆTySAFdiy-gz<OQi:U򍅗Tf(w0efz1<+P 3Q"la[m?1nM?ݽ蓭؜Iw'k=ooJj,O'`iòb8pw{w̧zyǚ׳%eAGT(]?39i P,d:-š Mͦ*[,Sn󻼕+CMcpj\^ łR9 }cʱ#O-0'Wgp'kLPw&VCdxv5V<**;rB/B,Q, 0h bv {{#d~4`}H ;{tIJvfy8h+o](+^GΟU*2wz*_Lf|wtXhx=Q1 r#XmlG a0LN HcÆ^'R2NjNs3*VK9#m̲=i?p:b:8tK2P #oB+yDg7螕ưO蝨vٖͿc_l<Ô D罱-mi8d\] )Uш M"fy6,s0kwȒ/ oeslOF1ge,߃^W}{XVS]ig{Rk&tz?t4f`]lqpG. ڔ<+z:%r5jm4EtL0;d)p]++,4Ӏ&AGA.YrۃHY0:H̀|uA,&wZѸKOmh'35un4JH(i1U)e 6ہF4E@1B@MUViq0YUʘ\/`1޺,]b&@ 'uw5Htj&{eExNl ^X{tjٙ#n٣Ly2fyX9XajAv)7ğVrW8eVyMůwPSm5e>G!2H\)iPGXƃ( 3ԙg:N\`W+#Ý+p[Hj(+CպYԛB }c:Cue?*K21)DT`M\c$#zGK락zmNWJ79|f L"tN%uJahqt|ƖDKJŭ1'bx,zpbٵp8vA8?jj<ǫoWjq  $ز"M3ɷ/Y:,ۯwG>lVVQ8|wwXSWVEwu`M:w2GA-:v+sJ^7+\rfN!7M4=Ax5''UQ3Or4VWr)ϕF3lPhә!Fbœ JTojOS4=LƯ7 e:b[5!%2ű97{%SB;ҩ%BYM'յ钊ɜDbj4RTPR*+%gKkNjw*6Xl7TQu9͉mu"J%pś&QU5P@cYɎWܕUuڌ@imT\pFy8pٽܸzԄ/WxFQХv1`I@]B:] _u7 sTW?wTxG@Qծ*#ܾ>Ƙ\Xt;ύn z)ѻg:ښ1)s:{W+41\U?&S/GV)C,D}915dMg"%°kLaT\%)b.eсdԽk3JҭڡHAnpP:DzVXsjO%J'5;ӱfr62Bcfcj/diV]SSz+[9\3J0Țlo4=-Lj/EyTBaToKǞ ck*NǙ+"3PC|P4Y5QW3{A uVgBj(oԋ6t=zfg*/:ؿM3+Dtl"p["Y7N2%:Vh` ~ƖbQjUM%펚ڠ^|:ޣ`Z\]WN7|Bw4RQSן7k}jhv46W9#ߖJTZD29<䴢M[h_J$;B#o$/^MJv+6*M"էlnϻ#ޫK%l֥]DM(w5x{?v+k@GສL\-걜r2x2}eUd^}*[v_F*oU[CUugMV3R<Ʋwʅf2K"]J㧸"6ӝ9%:/8Fpk%U*jlhEllxENa;LU\b<+~40#\N:Mphy&4.ϧǿLtI0 X8xc1s}9h.dMTr̟(rSr#Iz&9?TsE8*}*߫{gG+0 m. t)8/78\.*s%<;&N\>}N&!ϯvbpgu kTkئǩ!+%+yODe=9ţYN.Hѫa۱@[ .r9h$u`sC0Pcfe%0Ie椒$ 3``2fs!LbXPH:oMM>hb 4ahV6Uf9Ʋn,cTpئў30㘲m_WDMF5 mN|3W n&hf<|^œ*V L+5aGS-=f! yYX4&4|?4cc~6ߴwNǸv"8&&deMu_=#E{\UԄftYΫ&rQ7BUՄkDjŤUDTz5O˦_J.j4Bu;gWݒd\!i%g'C,iju Pɱ3fav:]k9a{!ExM}R ]+ GKL%#߬ &hr|!Sy1gi-D"͚f;KjUzbI-=K=V4Yj⯢񼡓&yvA2:G>csrsqWݮzA80-Yec$,% OJtEm߄mĺDD#Eո0Tu~[ĔW쎋Ϥ2OT4ɀEj+g9vxQ Yr#46.K$L`1?̕:u$X:yJWbaDɺUno[XT4UĨ#*ma( 3g+iimL^ukSfr~8 G05X#(VbbM !۵DL@US -i+j}NwQR~??Ma nCc4Uoq*ʉ.Hۡ ring'c̬aXnxV!; _^3'ak!ANIuU1l{SÔ c9aw1lne_UeK.' :B9Vّ J[Wd bp&=MIQ&}{*͘(o8OtTV^̍$5>.~=\ݏ3(3ȟC /̪cDWWer:}0Gтkf-q;{tˊ گwwE5M{3dbn@ӝ:O}S܎qd݊2dPUNyVOgW*O8۳'^'G* I--i/]6T x/˒->HX\,$H1RSS՝FF4tU$'ݾ~!l{Qqb#zf@47DCFpK  n2<A6Eӧ= ɯ˥KywK.vI^Jא_OS LqMjJ#=~"մ^vW@a %K &CY\Dlr,|˱,˚8B"]|uᕤ&Ѷ]Qo&b2^^u3.MA24Ω(NXbܸ`txKW^˕BF1ɾIsI/6- Q0|/E cҌڳ^&MPCqa6ۢJ[4nwizEr4yEЩdqOe'8'=씊KatfcdϛwE|6z(%NNL4@4YR(8[SS d4 b6M3dwN'fMtFJq%}9Mkr:gB[q9Y"]t3T""D`.IfN4ԢLz_ %S*/(^S+y`V.ӏc?(ξ$ߧ(ϛ$ı]wʬ-+FW6%bAU$9=`C \EB Nt;%yb`gtV*`HJ!韛LT%l1Db38)330m:2pylr8W`;seU#XXbn67W9 3Po }^7oœL8UH5mչ•} Wn+j`Zl0 6njL^Ld)^G^,u~A>| ۟y%UTLA4;6f r/m(lӸ[*PDɴ`sb[6j:ImV4:c5kpC[(n^ `!N72B11(N H֔=:rޯ}nE7]@?|+6v1kֵ.dk9RGـa@¸o{%MAT&r1+ɪp]0hS半Łg^Dј1+_T@c )( Wl=y"m JZq)>T{,Q&Ye f'(?$R,/6ڣdd/ 2&:Y6,+*1@ r86g2L}ǧi@ t{C<Qõgy{neת&v!\D9dڻR gzaB{K&DԻ24-aK`!v}9pV6A+_\udQsϒ1M3vP*ァ:N<&V˂hns{MPP k1 d :1Yy,]AM-q/RZƜ8Hb㿪+ ]Nwr!F8@6`"HO@Ikkeٗ5z[zyX5AE_xxNjtdo!K3ȇS')5 'gkz]Qu`1F@MDB`vZF4JWe}sIrO݊ v0 醍Ebu0Xt("zIA$xQB 1~Ut;%rS| kj&~5ڇ^ hRV3S]nCcJ)/qck$#1)ZZ0p01fv`.%r3p .rDV)[w+?\S&ycpE^G&Ѕ  aR{am `L.Cp=!ʺq7U!o,رH躛D="wjXd++"9v!Y%ˊ=7kC?v`x,OyY.{9}j-Ve7aMs( 2"q?QN͸+XFl=M:ů~`#26Pț-vf>`eo dP_Iܲh3O&TZXڥXt!aykv(dg| [h;d|ݚveL\rMՎ O-b!Z4)ru"l`#6nJLr땾ĄQ*la574J@"a621B8\%u+o,]^vAbnrkY:_#Upl[S`ug:MH+5x5paK_37_Ce+⸢O6# BUaZ?{cBeU >ba\CAc>WƫyԊ9d Bڡe˾dmبJΘmq1.t'nK|3߸PL NQ>GDi)4SSP:뭲2O$U.||2̐RUxسf5͜i[^ا1dz:[gkW,Y=$][{yMfd{hwL;ط~t{qYqUtSg.]לR |oT}!!Φ^/r-57 ,zs$,+>V{,Fr17 |\OP$j8cudjxcJ홉q@H)'sWifp/|;QX@ b>7WIn3!Ҋ?)V9>Ņ W:qCP{Ԧ|OGB[cn>ϡ:ޕ1j6[BN:\C&;?o\V߼-~6''Wpwn3MF"` ϭij492q~Off־؜#·BAQq7%7Q"KTͣ6czh`Jvu,ٜ}-&!t+ԪhaVbнD|jnc -Q8$P5]و2z7*(p;,`lʲS0=A9r"-u8YO͸A90ɏdH5;[g.'\HV2"mD$tsD쬌a6PdE5u[8)Y89N)GTRLvNI/n04Ej-.;.:†0fO&de3igPiˊ L{Hu yWGN1S@pr^>[GPQv2Ӡj2wTN@{ff=nB͐kr=@{jlsYctzvpXgΟ\Qy','yMvFq!B!ߺh"?&F8L^'K_ cCsdzuxrUnY Y.믫?wsjqMˍS*ƕ`zY> ɫjT,TeNcPē y}ID&OYODC ¦3)]OkZl =o?Nh=GQ!#A<_ ]|mGIK409&76H0WywF{fכkeU9.ln:HVx)I}|iO8l4\ݬ9FJ:umfcH,U!E_y?6S?{ZN-U[ᥛ]_zCfI%>\/ˎw9<_ 4.cpܹX~{,U]$Th8.t2՘3YܜצP2YO}V.UZ.pC!"_7gS =luutLeOL} 4y0>Y;Mgch 1s[!v;6&egͭ~DKY~V~X~#MM^ :^Wc5'BR: &r+MO,nj*.O2:!E~3 2f~* fOkX5CJ’Yb UZU+.H*N圜Xȧ`tFVtl39'9J59C4NBAT&wZZ?=AxqUS4ӬgilY6UU&$dH/x+]75+H,zZ=Iz&%zT9︆ov"87TMvfOZ`opiyѳ A3|Pf6LEjJ7m}9d8q **A[EtxNjLS' fY O%d']H~]WfO2_V/_ #A]]kjw|7mԘLdu~4Mj}f:uLW=f0y]Vg:B1f(ZtjC{oYE#Tpr%J6M!23\P"q6W}ImVFM7r_/Gִ)y Lٽ8n>QNO[wG/]:ܙ5%mRS+3ONuqehKd0Xl|@9*3&Y]yv, GYS`fʓ&-GεͮIVRp0!+s1pI&iPT5ÝYy&mfA*3۬Zٻ.lQ3 ,p dTawu2Ͷ O955w)HC2+LŢb(V:Ll;~lkremMA~. нWY:Uԓ[Mؔ渔#jϸ'GWF UpTȽzy 2HuSd,/6ufI!6IŅK‘N̑EtgIR_g@(UliTPⳲ0Mďg Nsy#l&[~vMpqQPt_G#x=X{k@GddQJJ_la엷fWJM &h閌/ "&It7;aNUyAyiɒp 7c322X,_D歉F. DzEYwRF_y)mrhN8Eh(*FC{!' Z@8Q[[/)풱Y0~dl#t>Dފhj¦Mm^YC{F?$$׮%\OP pCoJ"vFvxs"z*ggvP wr,NhƔX-ȱR[V5=ֆYnjjC*pKHy8&%ut\*:hF@^xJ6l',1ո4la1y[?ׁ\Re%ԂXtV&fZgƦ bjJ%_ĊV'W„O㷿Ŝfa*ΰuvꔑqܥ_165XϴڥiDZMVB|֔VJObIWD Z-WnZ2TS(L1Bb((% }bV؝BNV%hw6N}e<~"?98+DyzLgl׫%(R!M?qR1K>#>"(3m g\C Rߩk(?l'8GKxeze4WƸsEjg\羅O'TEmzS5!5MU7 WvtFvv](IBhg!D'Ke><'\PSn*RO/Ë3)R eעTӱ2FiVMG/MʧdWÏeB= OI-^@㾥=¤c F{,/)wYXud*AIIL% 3dE!dݩ*@h0mxtOk6Bnh+3?i[kH-pKa }2Ctxt%$drz*גȸTnexܛkcm0sR:4VdGj`tlAh1Fml\Vې7UniGNc t:3TTW8w5UR;{XܫTR،gCD;;|(!%[ Fx˂/jH'T>FqVao0Ypz}sri^UraȆ;XKEKKt*j2Q}IŅ>l>7BNIfZZV[ނ"PMCHB oDD^B-4̞{WaHiC(Ln3ko"@In: 9pY$ox xW'TA^}-T ϙNH2ʥڃҲ}N#t++%nl/Pvph`΂㺨2']@ k-^  nĖf(;SYlķo<ؿk3Axau ⅿa9HIh^^} "b+X{j3}-j0ob%*+pʒx[P ?شWdSشK`tC4Ũ.źeG"HsXXhvԩ3NL! ^R4B`O3p*q[I"vD!س>'^B gӦDЯJp➢ ͧ~;gq> SW쭂U?9E$LfD8'16tY:u"y˱x>N^2Hҝ܍EcJ .Q(ȌOO2l%S:ˮ:H˜ m\J`'mFQɑF~HQ-#0öe|V4*N NS1:Mǒ3!yǔ/}? kcDT"ůa"+8T/`ۂKW Σ~} Rt?~]aU2Մ9o͹xier5; j6*`&,Xu? ؝_߄Ͼ86ohnk`>.z lގDٙ|qfB=@ 6 GjN`1o%Ν郣#"KS# Ә~$%R>oҽm6ƚ1Ȓ{$jʠЍv0٨.ÁSDpd +h^D#wfq| Pūr#y;8̈́tx vA06 gf'3zkUZ hK2F oxq|f@Q4}0qpX AImE~8 }v'gµ;W?Ӈ"ZM0*YVl'Y,lt5p3v dN'ht2b <5Hx %x݌M0L⭗y1,W<> >9+>3}U, O މ~-tJކ =!K8>4Կj*1v /`R7LcPd:D~qM`ɛ°;0̊W׈H~ xs1}𽯒Nnb[i8UP<LDRę]X |I'~a뇡b[+!a~YO`DW]HD3WGJ1;qd>JW(ꃙpRn<mB8c_ ^_N#OrkDWqCnf -%,Gbx1tˣ/=_J=F/'m\8ǃŀ~H$m` "Աas"bcA~Fv/ iLkKg0( t d("FcnUTdYy5rF|tFp+!*mQrpXsTE(66`F~.^9.AJ9>ع6Bb/ҼXɸwf`Ă"vQ>B7[6!s;?x~m݄}4՘<w݆ld8 }\7w߄t'&lޅXR<< X-S̜}2`fLsXxaJX1q,!ßGb,^{Bi18=,.Op Dn<$|3y9ty(YP8OF]lH ݃зwǽg1 p.Vbe9h\ ct?r~i +~eBs'^ sGqc85( UXw fEg qOَ|dJr*.r(%/rpme u`xl \"7yx:^qaTEP '=7@'ΚtGw lj}mDh0Јkpx?j|z8^!7ض e5$Eؔ '!nAQ>`pXD|tWދpz s4vd&YdErzp&3D&o50aC!X\0 g 5⍹;h`l"y_ZͰO%Fn68vv4 Z3Xpnt2\ހd#\'U$э*OZϛh$䮿[nBIÉK,.BLpҥI.u;̺[|=<_dnAҭb<E/n. N'DQTHЭ$DVYGlF Bl)@&ԛojI<#?nn#~i4"fܴQbuX+ӸpNlkh۝.'g1Kb%Yԝcl=\)L;bG2*mSᶾ_͌ǟrɊWe#$LW~[qx%W` ?V3S( 71*/A9WQo"dz~#Kx)ܝLXt B4A aJJ Q8ixd -BaC<?j3pp&Mf` dPOp0NI:3řpg`8quQ䖠O EW7ӜCav+x*3<[滖6'ԝ_|nf[6o_'!rt3>x wU]ߖ\r&n_g"K|pnV[mff+&24RG@|ػm'=7PWA̜B'\I!#1RfmN? ^ j$Fҭ+U=Ĕ~"f^2Ml:Y H]x󤊕mwqĸjP[OI@fw|)tݜ(O!5iGC5*鮵j{,s1rУ(OKv ]DHXmĈIٛT&,]OL^9F wq&'F,ǔ[Q+w0"'0w%zOĸgMT5R{kc7*c䝘5FlڂtkذxIxw){Ǩuh `$>yܙ7rp?EANi AG^P܃[ObTY1 8VnÔY℘ FہQ E v%1=b0 ;{."ݓt;s|GIbT0H Gw vs2!yE94qðd<K!Bĩm2@8 5> 7@ B]0Qb;iNLo`Y&0[!ΡO)b2 }QABl؂l2aEIw؁Y,\ {x%ڑqFaWR[H:NЈ}pxBV`6D$YX62]؀{`̀up!7y\h+LVTЧ/]2i?flރij~f{ jl5C .&MYLdj-ϧM@ǛQI܌5=J,ՉAݰlk0r8bXV掉8q 0|7QO<" } 07}Ab^n> ^`(dxm @fQA 'w+_[w| s LB]bd@2RhZF/S8¦C!O+]GZ Ď1}:eFhQ1&ƥuZ,B4z!HTcG`Σdh!f ~=PPHLR̉Md>VSjB´Q2) ;5>82S l@4qt:6S AvA&'췊Z\ 9y?|9Z4i:Y e9 2Ɩ>};6|aϼ p,]0n(uIC:'?|썉ĭnl6lkEQbK&rB-,,4be _D֩k>;FF4L 2×|7tK@u= 8)ҖL $ursM̜ճH!eF*/{%$sB}PS D$*7s#&Aɵf%ME11H%f6GJi${YBWhIjyȚLVX^wtnG/)+d2jIq(8|Ӎ/G)zm phZ3 WK$1tIB+7ґ+-1lXv؟i/CIo踤rcfvGco18}1$1McZ 71͓T:#u^J"1$[梤:ЀqsmHtt&Ӷ:.U$a9^o]9V;_.k0"r;nύuƘ^v:[d5dr7?'pm#=&%3U4-eC KO{o|8doGJ>vg)d>`7MMm[^Eml<^;oFD 4)_p¡ȂM.JF п寗`J[_$)'4X6U ;S{iI}3WTWyJo+cs&R^ɴ%i#9'a݅|- 0yK[q; i)99Vq~o0qVMߪ1/sU! D=UJ.wzzvo"4i: (>lΟلm97uԴ|M2drÛK˺j,- gPץ^G% f4ĉ+@[RVa7{7lg)0@ r2!ᆤtXvNod`Xb0zK) #}7ɨ{|:SRtT5L@0SB4Da6;¤>*ْؔP~/TPWGPMڮZ+ #n1=s:;ṮiIrs 8$GUY1nAx6 tufâ3J^JER[B )ZptYңX?aDN:5LQt/듽ҵP{i1&o\~"L4B.R*}!)+s㹶_CFq2i%i{,ztZIYt|qඵj]-]*+sI3~9 Ⱨ!b[8^c0~Dh+oDBш5<[GT|{JQkwkLDJk05™@Noܽ(ðq8`qb(>>Cp w~wW(L} #{c| Ȫzx8tOAXr$kZRY(D'I+TJt]}T| IǤ:]dRFCqhX;'az8,zc1+=c&cʊmtXzH^W)}jl|'& $dǨ&QN_h&;>t 0!P(7n=PA2&qz I".LkNBzv3U[ҡCN.a+p<%EAzx" R( c%#h݆9J: K$XWC0=<Otr]O1g6`ƸtF8+/LWWr7OҚLjS4zP;oSEvz\H$<>Z豢df^:zmHRpeD&D fF]B.v!2*^S8V7c3M;PÑ(a";C=xcִw=jzV2"^4h:{lI\6"*SCH1᫲F aWf8[=`#^5ZT'nXGh B'ȯp Al|;鸹^}}'cp!1vOcL{|:!/x)I"ϙxx31|Χ*%[2!:CF &EHaF  lڰ|-&L‘PmpY{+fL7_F+A/՟ĺ*1nB<:FMs,iHmЙxlQL=,&z GB]؈Qy> ?C #Jlܽ8| 59hRѣ[WajD5quKxGHDC۱q/riR5 PGOފw&J]yPAp)Oi)w`.K(sW LQlۀУb2v 2} JU|9 EYNb|.%E=yuE+c<zwC^Uxc.&g'Vn";/{w 8&&U+v=HXBdص {O3I0[г j5$,γUpf"NsaΦy]6-rAT_%̕spڋ^(w,6oD3o c:#`Å#䡬BF&x+ng.$/.8kOXXfA6\tM prL]biB:Hy"| Ċ5>݁kb,K5t"x W`*8)x^0AYZ;alItذ t9p%af؉gå{eޜ{!rxg6D>Pм{3\.JygfR`awc'w_}Pm$*<\މMs&(ܷ 1Mtoel܍"굉[ee-0d ,X ܏sk(W 3TE+uD6{}d7q4J=l`څ6N_dlQgdfeIII;OMW`dYv'~$qժ5I|ęE'[(KfIW!]98@g2\ }\EPv .0]NBP=oǻ+ LfKOF|ۖ93S"W = uMO=U8dd0S.5L#XqKҍg_g/ioDRB$t;W02 vcnԫo;@[*R+82IEiB!/P+0{>Y_H=Avᜊg&̘у ww|=-D+JksȂg\7 #|` Hy v-v A[ɏ7`p#ƪ]f+6 qk¥Ԓҳ\+W7>{-D|XpklO |Х{B%ZrE0WE@A-8 `8c+"> }%F0pr4ŠD3ȵ;y7 ŽU ! <,_@#b;G33.&ذmQہy@F+}G`X ~= KШVw`/^M(ʦ*`s_{4`Bڦk=8%¯`KX3R0-Î jv*xe H;@jg/λP oDND KVZ͈q.%K)^]Х s%2UTi \ȠZUu5Φ2,xVQ\Tmt~ v#ňltreYiH/AX]N$ĩ,H`Hǎ?owlB84Ră5x8^x`ĦX`?qW;bRԇO5/'n x8E5b,u 2[1}a֋-P|)p=^[$aOjiX&NUbzrG1޲)=u(`@ݧ=/%RZJVeAq^ |CCW'PRo>OZ5Bwɑ%Xyr3IǬ" K($XtiM 5q8y cFM {P 8Re=3ӔLݻ8 oŅb QGTѐbXZ,سl]p 7[2iƀ0rKL p׽8.WnTca}PLc ƭaD7Ű |+<0' <``MX{(cFeklB2;o©:٬"ω>eٍ„H}`p\8#M.XD,ٹoկ`[/QwAz؜C m;fh HAdҹaJmȘ: cRR{?9h%ɰat%e =i#džҞ뀳*nH!N("ӧOE@, QIϦll/ْB_~pww̙3_/FLP I̛& !:9On- W^1a{4 oiU x[N(/t0,1"˵f @M%<|b"d2xyhA2l܍-{S>跀G8rCv-2gWg֎GU W\38[0Kpꀙh6mxW^c%`,d+cMӚ4;m1k.?ܻ33&cxª p=#fb <:<*ל"#0n̬ʼn~|ɚn ARѿfE<v 1X;,3#r8v <;ᆥ:.6Psfp.,]Eq8y¯5X?2(;#Xd.^Q~ 䃚8O<+aLnS;{lEC$T\zf܂ RڎCI_xd5\<Ǧ)8q vo0- uB((cn&8MEcE/ fD1j˄Ui#; qBQ<<\xSᩇAD2q1S{?- ap߃)KwdMxUKÚWA> Hr4ek!3 Ajhw_ n7p@? Sၻqeݍ&%`{i5sG{;+_^ qѣ͙{1~o6#gc0V r=<PrpJ T >OIOucC0H6 bs_0]8-r m-u vB[,"$̆BYY1{ͰNe7ȸ!COg`l(_Yyn0:YY5d_{,L xV}$$:af vHd1q pj->(`o⊴y `θ" L˗O@_D,L0̮N$UU@ |I?C_ r 4u`<"*6gsV/Œ]]XOchSm68#k$1cgc~-$eu@ ><$4xaPGh⅀}^X ,^Y3ȥ{~t,FYsn 8R,~CP`[8pҶ Ā3V`FR!1 J\`N(ZE FBK7,uÂq!5[`QQ7[~&x[cZyy:I`O|?8k7KT\\b1TiK'wvb@p8 );ǽʼn>l~Mǀ7jd""T`axqL2XGIL$dۯb9(tț;lq*ЄkSjs60qE $Oj}]_/i㐠ahChm{x*`vb4XZ7&lWM5 2fV8NFxp 1: C},4W1N"j([^kxD!, h7p' VlP@n<ˍ B`-x@I""q8\ ǁISX[lNJas=MZ<;&F0m, L{cC_ F8nCXλpjD2'J:Bx:z x<5; ao&*0"P[(Xڻ 6-"`1pdq. 5bJ㚛C=0g%)Ǝ5pRhS%hnKla "PE:c+<AG+;'|-d, yzN/߂v3x Pd,O))Ae ? :## *}\h: )(bSbʀÍEP3W68h-ֆk&!' vF<Z  h>+UcgIpu0cF8b8N'i8irT147a"/8 ZRU5.E()V<\ߎ|5JB Th3J0`?]8ɰx,Z~h&85e2˾sDGM:Ou851#`:Nry-A4a"ٵyot@(Ѯ1,_._)j8گo4-Z㱠z2}GI~:7S`x'f\-^5b0Oeh `ZC>U5\sZGBWa\6V_0Z /I B5SZo zihu|J60[h3HWVQ dN۝pV1'|bw~G/ N_3w+׳ZSo0f!Q2NҸ;|8wkZuDQt4iq:ac uQ0eqeTm岤 ދ$%Ѩ4tZ@T_ <ɜ AsX4kӼb$Fdv@Q>4/M HcPC 3QPxhCCX-sF1NCjW#_3(q_O11Cg::ƛ 3=}bo[1Y1D[z>tNMc<ɤŭL#d" hSAaH0j 8΄!hpt {gCYqNbt5Ki oNɌڃ78]b3O<PP\|EKfjʾ&ݺdaPl4 ]?g$pm͡;`4,>ߔ1seW7ve8kk-fzOj :RRR+Y,o\CK򗞻Xaf(rsijT%ga]4lԖ/*yPS845Vt ,";%ESԳ#Fkj 8P!8<'TL4SEߕfrQd4A0vKmir=DE^A]q7jz ̕* 1̐fL81*к^=gۚ`An :E9jsq!߻6ddxy~3R;llc-l4LGhcHXQ#/0+Qp"xKOhM}=R$XMTZ3F !Ӱ', ୃ tc}7-(ۍ٧1/P R Ũa2x(>=U`lAIт8 F %Vj³F~7omÅgZU=Q;%a|>v|=O$iCjR >~h[&Z[.H;wKj!(#6ƀ/;ːA [Zn1ƌkUzƃ:miPt5B'yp|aA5I$_dK$~#G(cV/AbG CQC;#%@@S 3lR-!]"NMBD܉-(d:XImAcGJY}bRW]hMsqbdܕՌ?ۺCaK#uɎ^{,GDdB#RX GJIau׋^irlha`l㯐==暋yL <ϥ-GݭEW\kBS{OL)/ *"T]R2a6:OؘS$]]KF%uzUA4fiԉߐd9,4:gZb8[>C'2/О#3`h^*"-RH,E:C a|݄jeNFN&tAY& %h}iA팞C1e4J*HD*R>H%馌1Ge(A6=p5*\d_*{KS Rz=XiBI*m{4q)Xl/aB鶲k [e=i g[ ?;`A?nm~ x`i+Hjh*b4 ,eSllIfmdA\*k58&)5y (du:ljRLJ\p#@Dv ❙NùcGS | 1#`agP"*2}ƌ*&Rm/J&vWz/Y:8HfO>[2f=s0IɃF#r'۬koH.i)] D;?yHxL};Μޜh=.N $H9"$tS!ܘ::rr7\8vIDp}֣W eIrNEsMT4H | 푌#}tu.)&j||!qOSf냻UvݧAw5=hb3ٌ"+|ӌ~xoԱ%Bl)}v&;G'^mbV 16 `\J1#D5۟ub䂽hUq㩈k< -՟jRTxCn|r ɖ u*N k?A2z7Ҳj08F7VH Y tQsrLзU}Ƀw]oO-}[$h%ȡ-@ǻ@R2ݿ$RBwhWkcF1E"E;7 T^e< vHIC1%JEJo6;ꟑ>C2X@  ?daey0*weB8&_)JXYU?uH+ֲX{b G=K/:nIԻ|K6=0!ϊcga.@::q*9X8=Lh^T ɂ+ﵖPK@Ĩ8n]]5W~/qET}TN"HKYބ p4heE粅ЭU|=,;E4Ip]pO6'LST|ObK(XܹXGLfu5iY4^Yn#Oo.T>X+Y{m֗l{s%MTA:I"ދs5R'M(Z4)8Ӿη)&)9fMNhVm lg8o n ΢ . JP>-Wk?m?tbGעejY7G<th_Q=/߭PvӨOXP]VaF A$o$!ٲk[E$tLb!vMZz[w^4 eRI9-l^(渱]4W[t.ҤJ|!u}A;(vH=XDhTΟ)Vܳ>ʮ(>'ݼ!Tx̓ɧ#])sޥCalO)ӿߏ zڋ3{6zmŁ56Mk~)۠Mܳ?JlC;ӺGyէ۞\,jt[H"CdY~'m~5t(wOqK7Cx>uW17:'HgTWg5bp`,^i$GzW*1 ];wY!GL_+cTRt3/& GSѤ_PٚO7'Kۢ\sUw,t|+v_ "t?ɎւU(ԩ 3Xp#_sU7cuC2TS{< WNVՎ%HQLLQf?"1+ﵘ:J9Lq\F$;TqdAJSYr3&:kd62"idR&mbYL|!4p聙A|t_NI i |IKl~#Ѷ))Q`ZZ?EYE& Dq6˹p>3l̯I~7K@(Rlk%qt'`/@3qo@^cPjeMRc#P鸐i2$i۸yпhs[$}$潄E muJb\΂[Bd~%AEEk9aUka`Wm+ Ď RdT$фH6y1YH $PJ)Y|E#Ak 4g:[͉S;Tir9mRE*#G T*؜!-%XǬ?FZ#$mvIɦ]c(D#NI~1 EU) RHn;N)p(77W/&34 I2eFI Ē%1"W_.M)JdӛdxleIJbXiף2màbpp6V"g(1VAJ*NVeRڥ9 1UϿ$#o-h?9;* Җ2+)X nT($ɱ$㤸&㧶 G1f)߳Z֪?-ɖ6XKKfC]pwq or M?υ:gˮ1zՈ*vv;bZ1ˬ9F=?zǞDB _=8y'!?m.p<%L gؾ5\q^9d -HSpR d'(&J e1\ҋ?dg\h>ռ5~j2̕ /zŷY m'GY \omSF)u, 2Nf je)Vu~Hv>GS\Qy3vbD H 4кdh ,Ƿ&;OЪ% oN>!j=g /QR5UȑS&!Ed@=/{XAw0֑:B ڞ'gbHb ky,.vziт#2_WNi#)żמhܬ"כ,%5}ZOf/HMƨdwfiψL]+@S:sHߓ,\TE&'v;fb+bx%$R4ӐCvV:mS.Oכ*zbmww[d)րps*`c<&xQ3g- D=oHUfZ]ȑ vU8 AڲјgMdOQ+aO*I_ࢯ2&vUa'hKyi.6p$α8/No%ysDQJ4zpmtWm%Nz  ?稬"X'.1TeZ"g)sJ`/+brT4~w7cW"){(aEvWR$p96jT8pMT^S k](':~Hd:A6]GQY+Z=-n]DnQi-XGت9,P3N&F.>GdeUE̡"%-+4&^mg6r!ƄX2b,I(mjh'ck Q e-vYI&%zEV3drVR,xJT YTPl8^@rQS_GK8*o"ѼK!!)ҁ{shUzSR}2t2!C _MTQV몝nڀle0Wx/v n{B9R\< xzH9VCVj @[' Xpf2e=3z6Ө+}#TSk4=HlV\eG=cϧnYm.ɶl㳄|I#jћ^_0sy#YRo(a<%&+yM*tTF8GMK_CCLarP&e){TC]3d^riVROkݣ'ecܥڪLu)Ű;<@no3|ƃywXdͧ|v6YaZ9tt4ZXNًm*fP MYי%QGV" s(7vY*)ӤkO &pN/B:b:z:o>bLu;L5W*sCh)WI(u"];L(m**DVN:8~ Mi>[ 0oۈ~\R'Va. `s)ZoNkiaV$~6Uz.3U뀛  [GDT1~rM0klW3U9{r?sRw*VUF3hqG\[(#jOA:2~YK1iW}W}IHI1$|q*+}0LZ6Zr(R}ɲQدwLۗ6\Ro_YHJ$^~#bﵗet|P`3 Uz_UQ'-L:F+Xp@ş f f-2:3)Xp@|`e^ 5[tA/΄:p=9=K |} ^O P50[v;@YYК…7HqqJu~y3 %u`u2a~F@YKҟ]:sρہ䈙zpg.z_o̰ rXYA #*bp(;F ˙hcx4`ؕz4O3oK32o"}"Z egѬ ΀_h {pB{X;"<(^>Tt`* |l{Qo:;*L ṵ 2vƮ@=B +.QxKc~JF 0Q%Ea!RDNJ ӣfDqL'XzGը 1`.ߺRC * p}S"0Rh{͒錄[YHdȳ5:zBwzS[OJ OYTKNˊ$ݐ 9턢fƢ"o*+{.!0s)ězޚ9T%X0q 2P&? }4.sE2S9F̠/Pjm8oǒ yuT%S+菬)צG@DWwA{F|_> ;o8`#郌 jgØDi-="Á+ [f0?)4$!|4t&6:oƅ-pc|'obh{X*Y޸'8xGjnތK+Hdℷ~?5ؙ'*oUcX{~*vYP<g%{R5ٰ.x6ek"TQrFR5T(iET%}fG2HƘc@y)OيIz؜M|$,"˾@F&VdS.cI8O[dh@Pu7]Uz<,i:R *fI\WmXoz㖳:_ -OsNK_ H3$>J/2aSDx|!#92YR0h- G}SQhFUCzsuI$@}񮞼%WANy o{g9cTM)㦤A*2DޒpA*HuPɆv+.Hd.2O!Xw\5Gl\jk=RzgA<$'{FQ-qxlS-(Xz÷nOyΦ|vxzKk~!e)|8cЮC*F{ " QRlewJ\xw|ͳB[ *A@bߓ0x>ZM$~_t̓Y%t;lo}g>tMUdQ*>Mse%tP WsUqBkqW?M<ΓM 3gVo,1+\{ލN &[3 S篮ce:i>'+ c)Gr<5w-_ۣN9떥"^X4g9 Mj^M"3xdcʍroh{yuw Hd:^ŹK&wwLص:}Oz#r7\m]nlQW41dmؑsv9 {7לּ)"n+ s#僛cgȵ$9?Y2{"c[~nyz5MЎZf^ NlMdѪ3}[$) ;Nd{/&c]] 2)}C%b\8- {.oߤwޗq.eKnu=k{W9_o,p!P߷Bw7.UC }&3aՂ RͿ[y~ɝ߷:޺͏)bN 6p^StC)".ZUZ"{_K4}'r..&2c /ܹSKⱲ?p;LпapLlo%h՗T%)E |,{ W"Yc0p3%Q?&XR57.l*F i񘼕eKhS%b>4{& *(Q3x}ochg|!.7;.P2xGbo6EI5{"[96wB)c5QTɜxڣ'NdZ7&NǏ즜eJX`n2'5lLH6MbGX 8Č/]qcT]0sR`SMH,#;%?g];WOo|L&-zd_H%p }4j)8sV.U{J㱆H5v&kp+\^9P|6WLW#]Z^$mϒE Ա?#+37 cU"k>jLKyKI_VTR =(lgq&O?":tjOsD3Rw*b[d52}8K,e& \%ZΜۤR- >iUIjØL\00֚%e~#V*.K'̒"c|<}~)R뚸 -_'{® Pq&.gě{'~wk MȒ*⸼mgDM[G)rh:X;T@G\,jzD 8MXeaLyps= Gw@OvqlE|ZQ-sU n[;x*Z_5nuS.#2& XV&lVmߘAI y(`I@ K>hh40ڣl쑟o~AWXC  sI9ׯr@ZXd1ӧ ̒ ~' !)&gXPRUVo-4%ߛMFvYB eƚFJ*=yvOۻvrE&E&KB4awjYϲo1JNYI<"lAu85!|k0J*SVRwcXYru!PE- )d^޼/&qowu׾/fr2YTi./&,D}fG `)Xp#Eh!q7c ׅGJСuT#'"cqO^ƹb*JBɴQZbHAwTM$$ьɌBe&=s`vslamWOKt"T&ce&W}rXEĜDλ'mϣtn>JB7Nb= ebX]ǚo{n/;߷1ELWIꋝ5HdPcA@q""鞐?ksBWOb߽::: ؂ZkY \kbR\0$U Nw&ZWmW fŔxʻup5C\|Ϥ+3MMLucb! q̦`©8`>g9+*4*\|{\s -/fcLn =6&)E\gl~9J.Twx=]c~ )ɛyDnnȇUdEMe Ќc╬$fx;hSFz5XX>"D{h/J|d長HzK,#pmA2ZH>KaڪnbLćaTJT9V xS$i=)ZAlm|Km#!- $ю韱D2WOf]aXO9r Zp#'XJ7  i%$H` @gl[uxưt~'"WgzFAFdO{>l*OeӲ,|l{);;3/v]ӮQWwK۸E&_G,63Jp B.mQ.,3 uVd# QkRϼOwBZl.(k[A(m3V䒤}#vLhdѳ UaY?%cTYVTs-3L+C{SIn?G^,x}l/glV4xyp]=OB'3 5!F8b[1Rjͷ DcDX'8Gw%bMG$]Ӯ2;: ӥTƉ&Ƭ}D8e-'sF"Urؐ.„Xά^Qjkyaov$M+T )`QwM`?gJ`gfuq@Q 1o<',o z/-td4صBk,1*\2 iUmۑj%93̔٥#P3'[C';'/b,Lyl6sU6UZfتq SړW&"\L﵎'6hRPv9"I^q|AhbHg2M s>Ő7Υj>m@Q'YET>!>_e([Įv?{w돫Z1[u%(\2˜?\6Z=1"W$&\w42^'m-:״?T4]yg\WJ񘣑6qR1c+vD5QG(CYfY؇kn^.-r089V{p+g-hM-%1S!VOƖ4'Ҏ];9ɗk ʇj.\A%\[]&wQIM L5HIH$)kFoXr]{Ԕ۹Mz:q@yOI˳{X ?-d " 0&YԸ\Ap*@=C?aԩSgb'nS"".]%iSwI")+$9CwDz2R9ӆlyE!hIIŬb§xͯ$5L p'85.r$A$$E9$9uRrjBi>C7-c m[,y%ķ>X|w QDf6v#~]iSEǥz*$efDP[q:VUUJɼHY9NF䔯 )1HRi C' 2pi#sBGP5nA|0yYUI_U2C"-?#m3`StGD%%|KBp;*֑ 2Qy a43`}*aZ6OJS~&8FOglNl$2#pJCNҭ[s~Z}d#Hu`q׶I23^>;1f*,_\y]YfY'/7~EQDvf鎯2%zAܡwb``@Pv3й7O`uhH0î3x!+nG?"S:+>d䑚g]9bإt|#QGzcW~A_A`ILxMk}|]ՑSdɖ;`jB aS6$͗͗d%ɦmMw[,K,Y=^oιI93sf˹z}}9=2HN~rOh$0zSfZ.E 8C.C DZePcP12 ],)A>|;o_"Mr\MPAP lhy?U>)@R>w3M 2O6 RMK{(iAYH"2Ii~+Dڸ2'bL ov1e65tS*4.w_@ wO̡$+M PBih+w0(l:ɉ5{q://cbO5Ns>asDB-L_^Q(Ok5:aoF^h_De>aOW'^O`5RWqw~"TS^QatxVĦ/KlWJH.=9C>MW\ƉZnhk$dꆝREt~Y;ci+cuO;S&-V?tB0 KJryihQTd2GOVNz3BFW}W@1O&:n!޵qauчLf&+%AѾޠ𻓔D3QZSf4.Mqsڅ41` *gJڻ@LUްsLCUb}fwqFՇM)*撔qc9Dk+{}Ro>!gsxAhd vy5*.ȼNcRӛNp?ۣgwE7~ 3ڜ|#W`G&(|[~>3HnS?W L75yNj2ޱ}{~ Q~{e^l8iݭƨ h7.5aeV5c.(c tZSRN>t1LrJJǦL򮷦ؒih`F.cjiۥ[s3 <0.3X \ t 5:*RsJ E>Kp1޴L]G-5#vfb)Q FG%/ ?Qj/ K>t&oTǨg'9' _Dv9:LFgwj2^ )Ѷ% S^ ֔dupf J50^JAYKz)+  諉-hwpH=J_S>z#kJ6.hׂѾn]j `,3 qdo9+7`5(o<ĹJS*fǛyw+lX/xnJZ̀.dݷ-.MH3&k(k7psE!ND&W;zvLt ;5Jp$A& 2ڏȲ+rQ1 ?U v{Cw#cDbGȜywxRw{tu7pBv5m;ƨhYYwx8J7x "%<]g=MqoW56m {"`t܅xD+u5K!IoQ, ՃR$9 X~ZP,;O$B1s29mXxjoc!~ VWNj{/&M "yiӫ/q(ֶbHwF OTQ-u&ICDiM2C ͇cUш> u=0r o B$?:VRO^k'Č6xW:@SC/G~}_@ }'zjHrBj6j7"a--~F D H-sJ+ҟyפ`fXHWi_ ˧Fjwk49n2:iOkXdISMʠq_E'{Ss@ɿtLxL tmU;@ZV|+9rfY\yՔwϟ=V ):]mBt)ҫD(pX{X_'wƋZ-zv}?D)v<ѩE|7Vg  ֮|9GjGֳ@tP*"17N8 C!"UdCk$ow`n wv2o`2, xzϱcOXKE~Q2M!'W$";f|=D0Bo[f}W&CC)+u=Gz6 |h\`X򇘆…ZU\bޡ$zɝ% ]8I TʞjּiHKʧ29S߳XJOXK~y^0&k]mX憼_~KLFEk}_Xdĉ"۾l?'PW k 6.СUޭq+7.wlxJ %O=}5vL۾MӔpKߡ#Zzr}7S_~w 쯳fwMy7, Kh}A5#pRƌEδOλ=Xu̹;)5wPlS zܖt7r:w? XswX!߹dl "w ]LrCv+6,>,R_9sOJtTfגPAJIiQٷg͜K8DŌ30;ݶяu&lDY6ܹgq_4;SDisCYbPf>XW'{ۮ<5鏴'_pLv3/5s}޳{iX֬)zHpEr0b6BOCbts%N[z5Eqr1ap=Xps?=O򑕟g͏!mU̾&2̅s"^v\@c6d"RWM9s kCo]#ᑺjquMsn/wϑ[$5P҅PI6.Pv Dqi9i?n=j)nU3{E Ev&" wYϩ]RWQ26zW\۰I&'XžΘUٽ)Ou{\5/%"J5L]ey)kl?ϙ.]d񽾣+@RA=WrBNM3L.ҳs],(YR(BV䰘>ƞaVm>)]#t}^RNHsMϖ;d{{L }sN$V<"&ߡJo9ݔ[%Acv%Xfwr6X<سk[f!ޑ'y΋i%K{d"1%4՜6sҦ/Z9w&%:{84P St85~E՜cAY_?j)*S@e' )!+mڽfw0{ dο(D,=,D![ř̅`O.w Ƕn9lxOwo<ͻgϗϋű3kzvy<-%+ s(Ha19+v.;Qjf !6AA_ٹ+6)޺ʧb~=&+|{x948DQ:Gi0OMm͟m^@־>-ц8jd沅Q;Fv 7krUq M7˧/sLQQFLV&~NgeXoŞS1aO|xՈ)Y"Dpͦz#/Zkջ[R[YE,+Y1߯xɟ!Z*șH4~D3rG 4ei)n VI"(1֑zV[Գs3]Aq@ewҒ1IU|QlZgyo~̚w\eSTKɸͰSykqϏO׬Kd5mvD9`1هJoM1VEhq;qL(d%&B YֆdSABY%|܌I#_U(|Y~țlTp:}<+B礨D2L9޽cKv^ޑ/7^ٳw_%&E"*ŏ3DG$Q tJAe9%cͳsrVh.F8&|HɽNjmv+:ba7KRmh۱*9 ۳:n.kqQS4ww ͠) b{HO+sE4!O\.ʲxg ²ܹn(6lzis7;fUhcDOe>C<¤J|N$Y2f="dD(9_ CK Fg""lvաUX3ogk\Z+}c-'[uLy$u-fgj)S'L6L3[Hs15GQΕ`lқƏWq?}g9!fOΟvNcΖ;"-ؕ鳾TsF]'S]e3ES=B8טS2SVzj13孩3Ot^SLёf+!wLW=9'd gMRrN=;G,El鑎::Ԝc/CdC1Op)}oK;!ɜ;ثD9N#h9wxJ9#̔1kt3#ްU\Q9*`Ms&͵Oмgx-355{˱de-S%S,ŜMz8Kn9oS D L˨TI5xf0e[2v8&~ۚ|!5ZӭюB [M5Ys XZՔ?ْYٳ[sB. DLrM1Qo+^0V:]Ń1Sѝcof+(3O*ff,RH(y)Sh?<UH]Ub69R YeԐ>$Z#W(BJŝe%$ɕ#eюdjeqz 0J$"XŠ1g~ĚKJXh2f*yh*w5~.cgĂ9wrw |¢BJ)8޾;"8slcd+\fڌ;%gNtq\M+wL"rHuߗ[*wn8i-gBBT;͜3wІYPc}-2FΉrnLO;\<LjnA4K5XL/'RDS?1M믽~_\RM8k_kɲ4泂0/ȿ%Q6˜]f)g/) >>s 73+\cfpZ[;~Yr3p&Y,[<[^B:%I9d/dm6' p<'Qt/.^Ydph.95D:J&&;m"Cm598Ģ129hNdIXg?ۚbҬìx\0Ŕ^D`u_KN\hlqZf}QMt:JWе1c7p$ȉ)I3wf}xd4Ԅ ה9҃V(lu򱖼qRIYZ_'+kMDa>5-QsGƗҲf:vQ6L~eY6~%I" X=@3̉$j):WG 54Jhoi=n_x`,uVKީW$<ɇFmh:rDeUo&J츎Cр5+Շ-  @q&FNzQ+Lzi}ɨP҇ޣ$h_h!^!hJ@eFP __hˤ4{ZuNWNnTs-BJVr25WvBtsD6: >ˎ8-RLf8qEdc0^@ e1M*=g1dIF<_-5 ,Zm~K-8ƨ1[oMEl7v S":#¯74$(Y6^0XJV$ FaPzR,) GgjI2nj8u6Fj-G0pV$OJʘ 11*_*fS)w"Ufgd{p%{I$\Q1XAf@@e 4t,jsq#RI8^ `P-,2]P促7fwP =$ozKʴ.Ғ+:%Y"ZRK?>  ^P>O2ڏ&_r %mACfiL1IR< O˒ 1!kvX&D%>D$.~)ƞnv1SFpX y>zFjt_(OĈQW52hR N4֡[eҠMÄ Ŋs +[978iAlqfv:Jx|c|]{ˑt?AEſ3>$$ 4EkQ!y^xݙ)lz,1;/hY=_<%s/nyQ~)㽖62i@w'ݦQ ]nzWpDFf9~eQN >Akm˸ J2/x/$;%1eR,=!ķM|gLO8W oW»1cjCTʾ,=/LҢ^-^׭l&mHK WVVBHπT5ŒFv-26fpnܩc#_b]uYW8n\JXs(d.>Mp-2ڄfw;L{_9/iK ꫻;ogMk&I U$;F/-R̙GeMOԁF0fK mxؐmn'zGEy$u|M&:z,A IdY@,PQ=3bH"}Z4JӛT5aM ԻT$g?B(aU#w>j0:~̡~Kp٩1T/Pd1HsV?_SX"[J$ޑu|4I81>饿=)~uT,։W i54C[ih 6d]?8]/b!'sl7Kb1?FJd (,sEZз:E|_;2f3c:М$Hs7V45\*cT0%2ktNY <"RSuzq&'i$(8Q OyY;/ڨ2b4rӊFr s()G^@/|1 /E =фi< MA/DdJS ݐ_AjuX3uEPߌ|HTumHGIz\=6Yq5CUX$_~X&a0zrt<ﰬ^&m vP:h͠2;"\7olňrp* ѧ8.3Y]6z`m,ࣘv3 ~ȴ|]yhPwwǰ%{`wcЮt_Ey}JMGCB^:Avy3MAnE,FE&4LZ*zK?\N 'G[Q8]kc"F4E8"p)sB~K;534'HP=c.jȠ6݄tibP +9SSmJ7 )vgR>Nb65wH\e#xdY*k q6_4]I߷n~=1ܹK!,tIhAC~ꪇ⑋TkSIQq4E8;h-GTMuoiNh/UjjzXjЍNO٭PVzgr\Bv<#yk#|Q06ڌF kFۊ ڎ>2y9_S | zطO??qt{Îغ %9Fc˱{^}|8Coh b0 *)v;ciaR,_>j^[ې_dŐ(HEGsX&lQނ`2s\+܉r_\wcdo?) -{02X{Nc8߇ů;'~ K6l¦S5 ěv㧣ieT秐4<'l".Ho.g"R^:Ah?-|xUg1_śEqe+:qÇ=d:Ml7௥GQu/!հcT*onٍvx5Mށڝuw~Oc~ӽ1bE%bi>@Mӱ~)V;q=6.H쫨:fszc(Re:B2{0fRRj˯à8Y"q*fn7Þ8 ; 1tWQ43X:rf bvd 7CwÆ(rtoWn;NƦU`ŗQۃQ#aQi fqVŦ(p32Nz[M7ƌĶeX. swgf\طyQ ݀Ï}}s!Ê簧~vP-h+q*ףA ^䘱bDlTH7jL(zjǯڌQȵ` XEx?$1T3Z`z9H JV8x P\>TiTEWut9^?QES8\Mh2;YcG0gh6 Y:gҨҚ Ƌ/t Zx٣D+0at丱c bku|\A/8r/ǚh{՛bpT5r(4F¥blُ %~ F,Y~u1k=Mş0spuT q|TȲ-GOoj8yO ܋Lx2$ëv믠 &Zc:Qb}kbHC]eĶ+籯?! ZEd5j᭗VnFc#nm s1Dl^E8ۋIc>ywpwǛ>i Eg[a?wi/$ L!v/繍\qLN,Nv_'֮5qӐ{I,br/<'n$R 1y,KA\w/Zb4̳/mJ ZOv5Ex}-rb H-x> Z0N u,l߈*Z{|(,3#X n^G[7n9.$H~^N?.U%X0Ս;gn> 3(ax:ь1pXQ"&ܳ]k3d}8َ ΦԌǙh Ǫ(֬ys1{4WSݑfBkn}y2Uk"_Îjr#ތYpLkzgm8 +6P> )fT?؆o3V`jaVɃEst,B:|Uz7F׎݌@IMH M c1yi_5ؾ~&֯CZ>"x,n]hnPQw9F_+J`|hju+N_ni917`uL@ڀƍkvbHGYSqMCI.a0"_t̬; 6UV`/X V3c " ArQYiTl3(-CV:Xiv|(@cr$\'C3$T;eIM9Lا`vcRڻPD^4_GwQ%7C^gLazP6+iz0#?|LMINDG]J!tѲ5CO1=NafCqѣ !"Bc$3ߗi^Az!fjhz:Uz9==ׁ^8=Dav#@O#WQPYg?EE> j[Dzec=m aMAe&:AY7yXSI?/M%bH5g8)g _ R~No0qL}0FlcTBޗ!ۄ~F|lCfhJgq>lnhiJpbQO!^ 1_x=P 4tQCbȦ0v,"n׿T_]jqZϡ |1;QzJb?D@TxLDz! dÇ U67;mn8swZƠyBϔ _á'mQ 2WS?x5&cb܌i3[C˄K=3b2]Sx!D\XEʞX1xۍ4Qon y݌fq87~ VVl܁VL4sDUUckt BN`Q&M0'vbtbp4k-;Nb\tMM(=G3!%o7EKsFZqa.@f2Sksuc&?s}be(Gih FqM#C)D\?'cvDCph@> MP`b8׎Lh"$0w6C{?JǢaV\7;*6 ,^IS d</r/۩gscX a  Mu d/)ƾUh95> kQ4x~j0en㛱~7f߆QٔƌƮI3b z0g=(q #s8 ՔO8@wGpgIވ >M02UG30p¦!̠ZC}:S)& \a<  CrLCQرbx6m?#cKo+/CY;P0l<=5QĂjy r1x@ 9;7"܍Щ3!4vP͐YLU@݅D>V3G:pP+9 ٲYgJjZ()4$@ \ RtTZ70 ;Waqy?8lGO*wl w{M#91,dUyl{%ÝnDvJt;[JoouXm=%zf+{1{L!_d 9zNZg7iHoI}.Q͉ WǎFyݍTN0PtohdnXLQZJ-M/+zC6[ Bx spL#ɢ"l#Tzzl2iԞtT&|2=-x,)ۦO";& X:q".ܻ3yɾs=82lC +p|4T9"܇}t5cΔ @L:'~Ǎ6ydLfK'ED"AL گ 7h999h>AqF:L E:"1%TAHDWA:IP0Ls'LF%FSJe =)ǒx+Ot(١zDX ZCzz)B%QOlҋz^J%9n4!6cՏF:o8'Mb15{\ ?HKX=JBJyj,FGbA%P^Sk^BgQLF4Eu*|1sxu5CGsh[_C@bA*D#'J2?g"CQӃ~]JvMO&']&^^u֊%3MnI`MO5Gyb]4ML &F?5FH CJ ePDό%Ľxi9܈I%>cQZÂ^/< `9N+f xDV S,D FFe6r !zX:AVߊ(J7Cb]BR-YHuID*L {T>{iž5X~XEBԓ&cT" =F Ӳ`+^߈GShӔj*U6ԡ]ihكXƊ^ ÔtԒ\XeCc^ @iIgW"sbpHgx .dAiEIJ%aD./QF-yaEf v_Ln1|=8:To\DQ'\cr Mfc>&!|Wd]}]$z6=a32xBI)J K }8XȐ/&)))vݤJB!n1*Vw|d`S&S&Fp2(2S.3a{i <-#Nbxa _9FGFF]FZaļWG,-zl'g.F=4J ; q}4tl}fڀO"ҒU.>ތbx!v Hjb ߆Iz%/}| dxsCsy'zV((NkX5{B$4'mmzچ1?>hJ稷knɢO|>|w`&L5eB~5L.t߽>{ZJ璬DF]b%__\ϗ?L 㰂9`\*PB}ʉ}ʇ'3ČanwW[~Uu12+A)Zї?3UWlvX]3lVṑh.֭ݕ{F/mV~NVkjyygܗwZ;ߦZo ÿsћ|)O)ބ_v ,9{/ʳ@bjgVkoQbJ(9 kg[rS4~K#+ݔCn "ܜ-DZܮN^qp_X/$@WYϠ٣:͵\> l eD)T5OQ W9u_@\z Fwtu#_a/%zk=<4dgщȢ\@#! _2Ưnpuvwg?aSꒂg|,sؿ\14!KG~U,g*,Dxxdf==O jBYDNeOnxqg,DW&B d_鬷믲A~plu(̣2B"R t:-nc1RkEW(]b7gbP[>Gd793txǨpi;pKPaMC0=hd܂bn_:r# Q*21.GH4sƋOg_Oxqi3#n#YN6S=BG, (j'XgÉ$Q=fS<fTؗ"iMTekx+ͺVgдW00nbM-TjY*H%fb4X SQ V˄'ʂJ@zg3~&JOVAi Vu͕acɤpŭ Ǡphdk6z9`+xn-" .|*acAY̸M&Yt#Y5!Z$ }4Ҭ+{⎋=,z|ؿt2k{cTUH/$wcJ F3_SZn1[)@eB3 A|t=ݲrŸռT -aC3'QeJRb̈́ɨC,SB66yff@W 0{+&Nr`oYk勗dxӖ"LAO(ҟR7˵fتR1`2Aļ״pFod)׫Yrs V{ЎK=*p v 9!iİtlr^U:33P܍yX%ɢYpBm7RF#[*ұPrھ%kKӎ]Q^C)q}n*CY3ƏF^h#'Xz?Y.^ F,z}Xb1U4OPb)饮*̩Q('ł)TCԆ eMiop;LL?6gP+G[咷9UU'ȻUWB8qcӲbm_۷$/lfȦWB~`=9ތF k!iR䅂*%ąR^)O[ ۢ뷜#wg%|;~ ?2Ҍ0LZVҌӵ8+*Z;idd50/ي6 NU6ëy-l߭hD9l$g`T}1(~>*ڌ,=~#»'Uz~8f#ɘ,(nBaT71uͱxyiG4ĎmlTKCL"*KVVCƭ[`E@Œ\g̝{A,vlN`?&܈z=Œ8#D/wD|"ĉ<QyqC"03BZ_v \m8y%jv?(eA hw`0n.1( q9۲|![leo#6 ǎ1k8a‚jNO- =8~%Ɂ| h 8ğ{FF:Yt!Q~G bh(S + a±T`"9E,1[R I 0ڱ|#≧Wւ{p$bdg 8Y@HNExmXpaBFCvD@.B+ Ϭ?%ghXA&YB Q8&<7X Y&<i.Tiec*DT 8-8j[p qڐB"Ţ`oCv=|Qt&A`8.-621~+kĽ%Z|>pxB7aL":,DَySQxkK(Qрa67^JI8EڦP$C  'f'w߃@7Ngת9߼~lڱΣ {R:|0}$ N ՈK{3<[Uغa+!mPwp: 8kF(KaC"Ŷ1""<6b~*_vgL5T1k6n -\ *.k{G`=EMH?+sgDG/'S.~P~4c{yfhK QS }r^~G2dv ztG`NQ 3f`DT0!B"$ j&ͩ*N DjzɚE]12Ε9lX` QSAqʃs˝{#y dV$cܫ >BE-$v†&т=nQz킯F!`__# tQ~s3ck3bs] 2[W5FP;O!/c>j떡ޅ=8;16ki#djs()%=]݌iZ6VK ;hp;Lwa=: aX6oul7ǚ[~˅Rk"ގC<4xڄǚPm*lA & yX|X>z-DQk{;N!}?wb^̬XOUjhȭ *"sXt<7xkl@|Q4$e%r4Մ#T5`668tv`DŽ;ؓGVxnFlXVt%^ t5P]_h@̾|K`;현ѓɳ7QZNGSȪ0[1lJchrb2U@2#jsDue13gpxwb· 7v(UH.X55ܳQM;m#>[l{`5d%j+tVraT.ل:݀uvڜ6ӢaHTD-09_.ŗdPqd NCQl?=QTkasi"YQȳ`O:-GI=m;cQJѹh^L|D\MݍӅX$F Ŝԓz4ueG@Djq!qK89`M~C'aX|XJ@l"Yft!Ȁ v )Lu5ËcP΍gì(6 ahzI{bЃǟ8#s!j۸k-/Ʃ,ԋggbj9g%g̙D<c)3X5 ^yz>}cb*Ξ0/xELE G!K+aLG1.9q3Doo$oAGυRJ`:h{ L4L#oa|ʋp$Ę0/= ?w{s/A\S!7T+Lח>%gᬤs6})x&|9Ǹİr)m&]TAp0WeUT^-BK/|'czx3&_ od{£Pg'}/&^ QNI %Vۤx5voȯ,_[ P/>΄ qbܽp֠5qH闕Ow[4^z[e #[ނ'_sO>@C_M%7xAqO &PKx dw3R2Cct[c-*0)usNIq|3xעӂ^ϾotI[7p#9]W(+wmڅv'$Ж&G:=[Gk' ]! On=Nv.WTMx'V$|@6_y9Ә1/= AaX8-(@nG.dƎRxo%vaN& ұ{Bط_I]IFhSGWdem̐O՘4w9{\Sšy<},@S V$)p$Ʃ#Xo^zنDD;قEm\.:  -!eqHOVCk 77#o+x;S@@՘g梪E~b~Gж~Y uĭ;Id?9ϑD#Q LǠ$U! Kx{# GV(;rqiV-aCPnb65E. %ڹ%Ghmk>Nlr%oFF2(엫Fnx;б+݈[eHˤi%aN%1??.&LĐ""6T4Dݷ|?m;~G4b=ع@unKXI5oӒf؞J9~+b*Ôh&ÈŃHM` ΍0-Cu#HLS~4}_W8&܇I%x6b;m$0*į͌GbA$r9Hۋ PӱLna1&z!#cLEPԄW':.(d 3$3jD~ eџY1\"*7 ;dz{2CB{t!|ZVB=6AqN >aG9tQF/p' Cd_*('&9:=& s+&WMHahbX"%/G4qR\!"wFARSfko G1z0#k+M:$*OsXuK~;BWwҋ6TO+%>o~QS05Bw/(BVcqZ+ 5 sy>roj#hkM [c>>#m` OǞx߉MYi6Q HDP)ze% &'sNuQP&-5nWպfKVV}Yung9.EcP DxK84R)6^Ð#g m%~L(=1o2;`A Q$"hPncȤyvxR(0~'膐F| cGSy\kVt4E `@TAoY6|020gc.'1*j:]ݶ#F->"ԃKlr)Cn7r0Mdֱ ֟RݓyX>Dx޶4Z#"m'+F3eǏ.5AƔ"Vnn9%hS#26brB=<0٣ŰH@@.YuCFGTb{`h 4v*#`{@aiS$ihR'iz\,8nk&ľ8lt)ȀX o2,yj)7~&&dx_3:IrFAd`pcZ\h:o1Q,q$LL"}}K&O3*z`f~QIoD_~p_"ѨQ`\L' KaQ,p2Sq8ߍ1MihDD˗B"<νF\<4C_Q|K``>4܏̯CEw A-8DSޠChz1Ip> pc>,2G[ #$FCcV$5b}w!Xc2? "H8øt8 305"Z4k|\C̹2rc|1019q!HN{#Vw DZ4O5$<6pJ Ly!6P3BOwmT:çp'8/8hh4cpIu͘ClӨ1v)>0!&bYDXuC&Ʉ3é;;jh#0{2ZZn0Nj6sט2` dwq2 F+:nxJH9;EH~aWU}xヨ3 n= x4*"Fx(" Zkե g-6 HOEcd&o@vۊkYe:/zZVϋPrs\*vS@]W THI(OO+$}G.xf S86pyN O\ID(1J c%ebR ?_ ݁4f|5.z+eT65]5E.IV`Qof.zOQ߅{}Vۍr>1VC"S,OEб+Э+BF9 hZܪDDW)QWn&t֢F呣SBͲ[6@̊{zWC~y"]-Nz}1*Ej75|AxֲX{pN, ,6ҨA!C J^I$1,5vBK$` H|m/K L'rUȈ+pePd[{VgQҬ P}>ŝkQVz `11in1..y@/I-tVVvՆ_* #2Die+.^%ƴ>)IzkvLLKt1mt.Zzg(ޮ)7cη G&ӓ_DEE)Y2~uA Φ[qh ;olPXpn{7md+n~v6&ĎŵaZ.3Jt,Z Je^@O u_87m.v;(]un ϜOWWԾk'e]@lA5D/aF㠖h!!OuvkAjƠg?3v{|w0K5Y!!WteFe=}Yv_Y\a0R>T1L ĕ1n-߼+ ̏@Y-~? KD+21U71|I \ U61L@t3LM_m07AC,` 4Ƅ&.邍57y{r W-IH\į?5ں\3\LYŘC߈8K <7Uz$)),jm=) I3v骓| OH$^6K0~VCqHZA#鎝0f!\oZjи$\j M<|ө[hj_x&sazY,EORu:u^͑2Tn嬉Ȼ9nfVƙ4޳!krg]#{MQ|q׿mXխdhU5Y!V&EaGW cqPکJ+|a7NKQaZޒ^*Gf@V8m--?WmC.S~!~97TJqIjk]daKLpRklvrdEL<%UWF+ 2de&  ]A!BK4ӫZ%USK-\ե鍏R;QӆDi(*wkBKKD(&Iy;Ŷ* D5 (X"V`i.j)RI$w1|ASɩػP2,X\"vႦVuz}:2+J8"SV%sho+chLbNN7w !Q^LyGAS;  =Jާ ewV _ޕh WQK2WF<`L>766[e =B,'jo;((,'p;2n<Ȯu q#86= x *rqIl;tP\¡TG"a،?,y(%#EN͠.67^lKyәt'O('\1VF Ha;Y豣 ;Z۸U>@6[j6!/ub$w}/q'%T 6átvrpkY١Q|;G;DSvu-&>m2uZtVH=Dx t8uhiJz47pKAZCVDR̝sH=AHy=="UHZaESzpS+m_ED-;KԺb+EV46zh6Tc6 ih?I),9YGXݮ8e, 4:8 y\n蔑'rszTP̠gk'H#"X˞3ē=S1׫1a5#k/!RX]LP9RSmKwmM>i(I%vgܙ<+4jH#"V\s_MGAt,ػ $^yq&% ALWN߀𜔄&˗ u-EqXo]D%ar?)⇞fjyn4te.5U8bkPGA^NYY,%p6 N7lj Bǻݷ|<%xo%wQkŁo~O%#cU ƻ[ۭ*D*b%\hWMeIlZ ;( V|2L:]YH\y)=;,VRGL$STVMyx=#,c8/ͯ>g_FAL a8UՆ[HOVlO$5'S)_8}^|dDӏ=AmؓxAj}O`, Pہ!JDk܇G1+{`\ Y/SϾ4w>DTن.zؗt̅(MmZ 3ܖ?H).W-v"3Ob(F@80p&"/^~xn:LsJ6=qkՈ%F[]Ŋ SD֙<8֍)8X7)ۗ!6^{n3ޫτkd{k0V}F?f kWoC0L'ӊ`6YU㛰ރx #CV"pX| 0 }zK8Uvo2ﮠe`sou>~4&?"LEk'Ф?aU1r`"eUjdǀIxjz+`1 6NnDf9/{t*'Ӂ?@K~g=4"?HLMkx89F`݊6|,$$"ڰ,qxqZI?l^:™H΀%? Dbڽ¹FUݘ7y+8 [40l1o,xcn$NןDU.CSWy.h0kRWx ]mnZC\ëp^^6oA?|+?t,B,(nƔ{p4er3,m'TiǴGv k3LZ\@A(|NzmFS5zC2k˜E?}ظ A?}$^x2=^x^,zNA7ػE`=+7aݰ#q:iK,6L\yZ|;hd;n;V/IגDnl\M/mdtfp'~,z?.2ނnZ9F*Qe _' -+a7D 2.4c`Ήֆ Mc1:#S;;"Beukq39e1Yh頒j@ZiJ/Alq즽IdjѧW:uEe "`k (1V'OT]|A~$ |]*@ןbK1b\<D}hd+ k*%/L@M "0"(7TO,Z΋^#dU8bk0926ԫhL˄o @BLD c;FLla|T WHMtY'N zL OcXW  U9;EB oo!(uq"{hԽ65 %3ycbp|Z1o1wh>&݅(:1<!#D(&-8eHדGX_a`~ $И)r/jPOم a9>̏GyaZ O$||(*H$pva *϶"OdW.%0c~:̙ /IX rp0"8&4: &>DwA$׷]GUոZY1w9SqBDp4ePx?X4sih73pCbMw`> e s ;' bJ8xd1r<pVwaza vƓq$L29H C ,}%8݄gz)9qxP!4KNGN)PX Bu.‡CIBB@=e6*OH}TAxl7č1 FFՈ69 Si6c4,@e# U213WGl7gd+߆ԫ^Y\z҉ M7h".t4gJJ*6a{zz1t2X"x0z4)fg 1٘.JA{ug |0>붑{dX]d:08 '1(MD&|(띃Z0]UGnuh{Δ2t0ֵ8]zGk>> >a" Ȣ4໰h *bm{/*p3s(F5 }~Ҿd4[־@SGmvߝVyTن3T!P_`Br!Y"jգb>pԴXU`^IzA].M#إTKrXs;w@P|$K2zJ4Z䫕د.ɿDA6,B7Q+LQblȃ8v@8U_zQb_Da~5ctfd! rHM_н?]V'aa%]ڍ0 Dxp3зy+3&kp&|y z"SitꭔFSKuIhTyT8fEdS53.Ό9a|/$CU`XYY%M=ؼ%n '2T~ TQKVdP w;lŸYWPP0ShA%HRk5@X|QIA$xPiDYVj0qśڭr!$٫Z  Vv7Oph4nUzɃ(6?®ıRS=@Tӭb.+rX59S;f>$N?_徫)KU8B9]rJMpO= $RzٜS4VkP_ K9cwc:Jĺ5"Fj; <1%|xAPvsF7`=(خ^r7YU0Pw/ڸ9i_)*v.~k21ԕ밫`@r;P}+BbXXzY1GhHg|mz_ mls0bfr(1uMFgkeR\p]FC/ί4ZCK aK^OSDO~aNivW⥢ֶ)^^E*S.Ro߆n^#o?g_֖r[:b4>l گ[_kل+cz b)w yTx--0S$숌iulp4$LRW7i in&#~> $7pAEo{QD{}3/Gd9;KL{>"_ éE_su>oQ2+SWNly$+cݱy"ȏx͛teLOO ݡn~mέݝoʕؗ2EQ~\73c{ԏ`W5R8 n گ0=h||fFi~~m+br+f/*Y0owthzo?i_ᘚLCΦ%Snϝ2Spw1,N+F~5Gp445v_\}9/[_gO4:J)щ¦@i)rbxDMaT2mmW7C ۃo?127LFp?W)47')vSM';GJw7p/5RK'%kݝ% QRFY{df+y}-fWXղ"ύ ^skr?*R<c0q]+YQ+`0ܫ֗uç( =]RG\D'Ls%cd2M ,B2]{6YaWU{#K4<}LI:TYrw%ѹ-fu%\Nr[m,aAVL&-ߕy3:5+~6f(FQ إU5%|UBB\FY(l*ˉYV hTM3eЩn11֥rH6ʭbatYOk?U 5M$RgrT1ZEH fuн器k.ވ qEYF84{6V`Vd$p &*EN+ckl'ʎEYH$D 3U0@L,-[vqk8T; }'v`|k|n0b,HوQE0NSOCFɲe-GV1}8!~jިJCN]NY3kѽh )IwzVktkU,)ȪW+ACS,.*3 #L>>;:R@Dag|F_#6/;f+LX hIQR6HLy )FjInsgw0n???%7#W&jUZ\.qEݶэG0n ;9"39Go6#!V|0kV!~\cH#3>Cr5/d7Ya9bx!ۄ .9N+-q"/ 7l#0 Og ̟~rwqv q$ ԤZ'!u6]pעFl8_-V~V="g4XmG}(TN#Dटo Cؓq! oGPVbbf4' GC>v#BcÑJ25|+6|Fp8ݎ;>]Xk f(|=A~jm"m,(%8X9>CWHk>]J ϱB.Rë?/xKR28eC_|Sl N)66o[v.l[J6~g&޼PPxF,~~GK X8GSg?h8*2w ېG1d$ ӱqNcc#i@ZOBN1eј1Gcp8C{!5wݍ4x!@^]{^ue^S"M w';vM2N$3I&q1 K:.=Wν`;$0>ս瞳>7(fJǠ%[Ft * g &тV#Ke>woy=T`Tv!-[BpT r;;a^bΚF`8Vf#pvf4)!xG,jH6 g⏛ pLĔ ïr{GEI.a,8z&EiBt<~N"|kH`܎v^s/BՆ6AvzpqoB qA OP4<`7E,8WN]8ս0N@uqF(1p8sp 3$ 3r5#pZOT!ZЀ>};8oޣl'BU5 ؾ ٱf 0Ð{'ۥ)5`0 lZ_)r?.MY u@ Bu8~9yh Fib=G[Mi8ݢ\o0;\4$B"$9[z 5Xp|n|*+K}QStQ^E0“Xĥ>7X^ɡsl'XG4atx#1bMG'XO-^V+CWmPl@efu^lO^' ` h" ./}PeaTDno"ܣP$$;!PjkBiAkx 0YmQo/x|>8*a=mԘ~֢ ˖iB:oD"!ד,5b:Kq-$Uj.q4/Qځ"R>Dplkyۋ|mݤBZ2vnQr6|nB'1񂂐`oN!w'Vڵh7"Bgu !lzlĺ71`ƲAw7d&: hGE+i4g7oEbLxsL^]V"v6 CD*َr1al`𮳘8BڏQc~nƂ;)޴H"|'h'؇]H4e&C}Q|UPwv,LoPE \zUo%da|vX8V!<SRJfŅx^83p6\a܇=i;A$Á0ыոR^QN8f{|Ή:d':i" fD'" M\8_gO`>|CyjEά*bGc,5VC^n1?ƭp8L&L`d/&80gm28K_ 2ů~r!\}x{+z}cT!|$>܀:4 b@aDIȆQӊ@_3ׄnkaǞ,O0lB#I1' ɉ,K5]HS(QX~{1;H: 2f8+03Og œE|z)1^Ƈbr2d'˜ D&TSܩ< B"rRBGU0!r$"&ߋ`T7JqqE]Nv#'`03P؄zZG ZBB^~:HEӨf/칤#~|}̟/ &KNN)P˅aw 2c9QFމ;uY\1kmi™3wG$^>im,Z`O= ֗J̜}gs"\])UY1gC 6- qdӵ7^Y)ܼ8z~xAH ߱x g#֟n ,/0g8ܳ0¦aMxnt buXǢ9cKe" r7 '!Q&?N($'ͭ2eX>pguyDa|sFrc>=Yxl}qP8ܻ [ݨqķs=9%4kkBv dq]usYUe0g4M&1?RVNh {$KC"F! }1O5V eG63\Ӥ jsx*Vʑv61rϛbOYy0Mdˊ2§b9xc00JX4zdvhx=!{I |Js7Ln0 w گ۳U3qXAT25 Z)LݫAȽDю E{]Oq q70(2'ݝ5؋6H׃fF|%gaK;SCۆr#1JZ\58/r{j4ςDaC!h:~I!NYil#IE F&mg>@KDZ(,T 0+p:$ Ɇ<I8>V&nqt~L֌ۇI1=v}[kajzxs;Xv3DC b86#׺ºZ[)d;%~vrW?/*Gį k·LRANk7[_.~]fr$q4&h(:8LLA| M2+&"@*"PN$TbgPXhFbyT^€2Jg+ЛQkJI+.WML P`4+~&+*ߎI󵴚 qHA`R ?rQ9K>;_\= h= Ù:<58p߁wotq7X֎˗Ba z#c0ZXB 3$W0$gEbyhԂP&oPU`r]90yZ5h1dy= ͢4=yg'/zm闳MDJl7aI }X=}|0>keLǓ>8f"FϠOlgP3xVs3,U6#tA_74!6 j„Ƅ\Sv oUj/BXS.1c^^;t*F7/{=PNR^RBQ)L nQcHv 'FF{co[ey->(.GX,FN!WG\jO\NոU{C-Ի7J@EfZUd@'G(TS090b`JGȪS鯔p)BJ7y`LF҇lѪU +M.@ 0+B̪ӡR z!8R)=UPDK|qjXa3*\N npŘN U"NڜEAzb=m e#L;VQ#H3tE5[\.$U nvRQUlP[\CmPƣt+w&ɉ]j@4F"[ 53 jԽUzCq8T>e+$^z:UE4|X].Ҩ2өG2P)z.u>)Kp y}ު?*=WV"F L>q7Ô˵?9v;x## *Ye^mH*lޣ4j_/ 铯2+O֌l2NgeXޭ)w7e\~1Q}U Idžt:mtv7M?;:Ny;MiԏbКhTFt~u퍬LJIKfv䪰 ?A z"&ǔR9J`LVruX.QƌMMZr*ؒ Qz<=-ExLEA5QjPeؼݻ):{yCU$eSu⃥22cZ(!ZY_Zi1+D!@NaidYͦϫ컷ۡ; CTTNӭ΃~D]""G 9QVV+hYUׅ a/%)ZzE:d^Β"FiWi6 SRelj%QIww,-tĴ;& -ͰHz/ $CL9Ѩ35 Q:vհVxX$a,8Yʜ^F+,ǞLNA|(_k¥7)kurcI]SjTQ Z]#"~LF0q$7Thľ={b$4W#( Wa.tG$M6Uc5T1< ³kKz$gma䎽*Z%k769 i*u?] ApXQـH*9vՔ4T9ݪd-|"ʄ˔?{=khA*@R&j\XB)H sj6 ef5kE=<A\8:cǰ v55;aI,X̆8BU>1~290utW*ϔ$|x<&="ՉD U nu2b4Ɍb4;q}K5+r+xY~HlyEJ#$ a|m"6YJROioV^FIAqN%Rs7}@BTB/E%T/Хv̫Dn̻*PTLFV*<61 tBJ %l39ph6u.A2冷{X;)ϾeLt2ÅYQOB_pGbnWQ"}N"k[ۂs`u% 5kb.^VXubc..)ņ6ЬǹNӋs@mkip>=elH_-ljGa!)KylBn4Ԣzc51ugi٥+j9HqA]%'A\ &$vgFNu[JiTAtrih䡲Ne]M.^\6հLNM9[,a_FwSKLHE)NǙ t]+&y]t=cS u/mi@ tԣRr*:]f K s[eTM\V[9BbZL$fCr5+ :Bա$J+ D)l\a^, èՄj[W$+l|gNYkԉ7"(Sbu,}o?*ù!(Zh 'q,B.{vnLu96R.;.WQ,-٘f=GX2Ң lNҪR ^I‘+DW#Ce3PQAXZ6T6Ʈ pV x}Ͽ>dgJN+ ߠ]obwQw\LTRNTOMb&v} nkEkl=l gi!Ğjo 9issɉQ*pj?E (+(FW?/Eq>{mڛ`7$`ֿO tܷ )ȻHTG;V M̞0qm\%?#-NRqY2\/Ĵ~?%Nh1@˗MH#)Db9L DY:=/_Ņ04_8W4IJٓL!`fgCeovk3l-iv=rsH#Wv_1giwh)x2YPӋi~kB` ?w8<(mÛHQv|4}EKo&z{_2j|0q;T nq`-? +6nwBo DEt9ȗQ\i+!(DdG-mPTsbv61܊i*+;>MdO씅O M?[ܪ_ڍ/܃NBZXL0!E-1`ƽE]x/&^'͏"6B'ZN`x6o,\J2L2cl_p?ʏo"g#Q0܇lC [pR!^ j l,,xu} )"8;‘<,oIR0+chl~q֠0 sD.HFy&?_Hf8F boӆĦ7BӹτgFG("cZbñL$%?ovbe67c5IW.aX4,ӽv&w/R%b[= §j跑.$i%-_N6N{5_.Ԡ8,֡K[_Cwhm%_y]k02 Q݀%hyw17k}f^| 8\H\ȦVz{o/;FEOBPPSAm%d0T ΁Q᪊O0Gp '|YF䮅|!{> {Ƌ/aYLWr~蒚amGQ^0xEik*C-nd5T{aǓ+{!9qx}/Pu/}Oyb\zͿ~\+ ͡тKU$*iklXھ'IsB_[I`7Z[p2uD$ OSA5$"j%E/!(sqU!.5 D 5T^Ki#D@.3}|gKp,.xAXވU5 <*YfQ\NOC,ĄS ;R(.ҦAxb& }8cF\sbDU)L 1>űj6#(UxMFU$dZ=OIql!K1=@윓8_ˆ]c/N@Uꉠ|>zˊx,-"? cX]:Q~" (niClvN;qx>NZfVcB:Wd ֭Kq!6bl0;c zPQS[,22SE9x`SB\̓1[ ӓ {ETB`btz?|#[Q ZLd!q2sc!&ʋK~`|]O)=s0. |T/ͤmwc6ZJ!!!Ej/yXqS{%玛!D}(Ǐ_o $a5ydBve;6fjjX)h6:샔;©Ix{&މX/.WaQhخRj ]v+ ܆y#,_{piF1$,p+S+O駑7~DOu}`mlbx9.ۈ@ys)A3HJAz1*:DO?xN3&}2/0EPTށ1H! 7}4 Qxz%KM8ym. dU|̰ݢDet/l[^puNmuN. H~_X"C4 S&,z=$܎h$-# .v\̼bx,]޴UWWMOajJ:_ aE,\G<]1ljӄP;fqHk-\^|wF{ BHYBxĘdrG ZM=s <{XwA38A MBqA`C 0),́IM>AK08%:i$Tʬ51XRa(bf: ϣA,{/RclT!~"/@|(Uph*V,@'$ikǘ4jqO?x`J*J `):d,r:Cإ3HBBN< S2X¡HgGg oD"Ei A8l8: KLL*q߃H㑖6!p@uPz 7.CNx9 /nLI-]{AE#j{I9s OX84y`0&,1< IxF=&M@.74Oߍ~Z)6T'V>`5B#EH ld dNv4@ ϣɀciԣw?LXs  X?ee 06 0o6KFt<> _9Լ4!8_c|p KfϲZo$LY ,ltVOHTV= :79YkN @/s_s H@_ZyL.pܽ+'gL,| =oNb1-b]$gYϠr4&b޼O)ɜX;&"!Z OmBn>/FrVm/&rhI'餉*E0O<_`>{2tzxisG@^N DuM L1 qr5nJ`P(MP$EX1@̙gI0jFvFw'ˆ1* ^޳EaF˙\dcvDUIQOIcoB*yBDןQŢtW&G<'fղ8 bFFRLMJ,(b}b)Lv%d r͒yCus k8R)Pv *trBMWeBpmr6b^7M*d}t?ttltk-$􏘊aQwHj^k\krXo&%//׿,~&~lf Onck}Ip6an4 m[:|:wue"₟}q0_Fxz)22Sf`i49[DsPCGswO_p25#nUУ? y_]Y?]cBaao ׫ (/=??:7:jȊ`ί^s%V)}UGd ?F,{>9,6 ۯBh~rΛ~V%2':9ES,J&m^77z]-H8~Ok3bs4V#/ںv͊|bl+9n߶XYZOu44Sgw ;j-?vs:DSbpOPcMx w^`/E~9fsM!.vۘf{P׋(߿vR[Riԓ0I9{ӭg*>q,cͣz{mA\0`?^mo9>Vh;͟0vB򣣿ѱ:"╺^3O9Nye@fyV}Fη$ɔ"ck3KeǓ/uJA ,yNbr-JPZ=)%vf[ Q5l&րQI3-v묨oC({FL>$Zp ! 5YkFúA#FmN890j\q ;.i\ĸI3$b?|X|N?D)LU}VV}tZ\6b `!4(KyRWx'eu߮BĦQD17nq(qO9ϰn`IL'1K=7ЛOFY!,#IOiaFul%ऄVl\XYO]*pVjJoб_%W(ݲJ<Ӧ=(Dz9ăPo,Bx7hfzQ.e:]FI0Vͭrso:>>r [NpNs};4>z^ݙ-?N]MS?`S-FĚ7^xE %`>!5Y-Tj5ͫpr"N1}.y]{bbge"܁|1h)g$X3^fN#8Q´N^'QN%s$^:Xz^&֑—lLf@ormE~RSa~J1tĢͯ8&N 9mdbb(S'N^btuArȱWq˄tDlv]Ȃ(v&+NVWIdtʵ*or c&,gAFJ#̦ÇS7쀫]V6:Jm 顕.]m" DŨl'^v. 8*7 JDPSR?Tx}=Ą;c\^⧠NcT4!=Ax8BP]8~D -+v"Z:JF1ڽkEѢ$IPȿ5ܮ|\y :Jxʙذ J1n<}|f[E:E' $\كV7!p|&qTQha7/=7Sw}bXH>;|ftmf-]}FKtop0ҦCHmB\p;w0)y$___%$c4Io}[I;_NjᴝqD1Nh&ܼ x5.d/BPWB7[w!7cbL`EHdmحQq ,2/ރPoQ@6.Zh!S"|˘: a~`Jlˎ6-)JbT58{;D`F g?zH觸${QѯAR-5Mug!$? jRhǻBH^I䱸|k3>}` 1n [nS?`~,%`oq an}v;OWf&qh-q4ذ cR鶶6jD)t92Fp:c6oƇ,\B@-QağhǫH6 8*.D\E|/BWlIW?ּCyZ8'3q0a 1éBűLPPX2>Apx_p >L 㠓1y _(>w6^ض 2mؔBh$TNta| Ao'dC[:5c׉qeǡ3ȯX6Et Z"u<vISFWpx 6GP|j$y937d"2&A)DOGElJ:q%NY`z K/.hۍu; ՍGWCJ}GHHEy.;Sh"ȁk_% )HzNz8 qc üٌhy}= z/oQy SuflIEa(kdy]-]ظ`;s!k9ڌ:(4L]M#˨ x\A)rܶ~';.%oA'#bGݑރ?"g@]7O[q2D߿flgr(j?/NiDO֬,F $ҨBX@0~@]JTFژFA%k68 o't&DFFPĸgTC;A-cؿoN"JET8 Y1-oM۝HSP)hn4?x(!8bLE\2ӳd(@c|q;n% e;mf-!hHOd,Gpp:@`Z&O"cH/ЄljG; )`6Ƨ#2p yX0B\/"؉T ,ݍx,wV]زGb9KhEy'a30bqbj{GL{'/Ƒ,CN\i(G_}q0*ظ ~aXhv0wbzԹ蝸Td쩃`I3iiCw@׋1y&Q[AzF7[RiKs&=k 8ZEvl#O}30_&V8a6է9=i0 %paĪ<lbsB[Q)t1N,M8uּm˄QGj\0~O#& īh4B&!ހ[pz3q ZK>\WmܱF[{ {XZC' *tڵ,ܽ!%!样p:9GQX#GN/9ƅ{w(~j#L> ?3 C%ArVav) ֔aAdn2R_գ oQۆ_J1ΟBh4, ez1$Q&:.E0YƥϘ0ߛ0z0:օPip*O"*^>||~#^]:ܻ(tlB/{frM~ߤ$5P~3OJ{DF"hedhgAC᛼Mj4dSrn/tX֧#Sz:Di*/Kl{7!ƹg݅>c酯]8G0Z"Nky^{q4 q֌1 6d=%xtcBCmd7cO< o :Hxk"rk(ZivaI㡓sA6ٰN 3#+3&jBf-'(&1:*"'DJO}xǑټ ,X sY,YٖlV-?K>>ʲL(R3A$ rFlޙz He i(БA?&!7~Kq>~~ЩJ_lаOҵ?ЂgW*L"@c@ kMP;,|MO LlK7H(,8n/i;+*rq.C*(UN)1PP MљFCmC\`=?0I\BtBjcn8_!|ĸMH&AY!O$8W:WH˖T[27!KX'M|G@N e Wf'Y*}:&p8m+킳g,~η0 )l0uJ0a" uo]E!M5 LPR8{[L\wa̜DYZky>a-$ByCA A_1=?Ǝ|t"FpG(F| F cރh>0cddو0DYlg[oi&:GXGȻX`4ӧ7Lp|)3nfhd+{æ%#஻1)/'cطȣ>_ DiJظ d<{̶)k# "Bf\{5zb(h(V<0}8Sڏ1u:2lDx00cꢸĄp#lmM?APSC6dޙ 'ap6. / [֑0`R b°`&$ i" gQLᨫ)\I'?gVhM ')G!1k4#0%K9Ҝd挋ЪX.N0|r,ذ~4a6F8]/<+1k)1c6&NAy 8Ơ<4 AGo<_Sy$2Lx_bALB wލfW!ɈZ\J8f44^!뒛0s(x.#^Vʜ`=k[KкwPqo)'u/iCeӚUPDd#8sElVqM V_AqmGM-2G0ڇ [(?)ܹD0Tt$êwޜg:sCܵ?vi7m`:fP Ł([d7IfztX0 ox K$:o!G(,WBY} 8ov|%]$agub|5plko?1G6ǎYq` iJf̜O>5hW$c$`a Z>sQ@a1x{\.Sa "{p(T(53.: خ[!c{BVT2{- EԱqcvd#hӘlHm)d!9 q4ԟDg7- b^x5M!= -OVfQm#ltT%OY̟Qz1y2%!NNF{IP QuOrƢE0+k"p 1(ȥԽS0&'Qh$z) N4S fxOxUZ!42^fdϘ,xʋi&ZlV4_?y [;Ro.٘~r!a`oQ2 _YOL,ϿE؉LUZ7y ld)SC1vNc3?~E^uՑ eaq%>g9t2yΙ`30el 0k-lы˄B t\'=J!=&W]Erk <cu#`Ҁ%ucV9}ӣi|`zs3qK}t뿤K "gbcFhY$GX#/ɞޚYHGɿ U; λFɚFJEKS!zצ'@apV[[hyz> Ł OTI}}I%ŖHNv$F1y{bNayFqL(Iㄈ=;ZPcrrxN-ebBOPYO;OceuP)Nd#D|S23(A{ ?En%E`׋HlZV6bR D?;+:N ԢLJY4˟fGHͥկT  K~Uo¢A!(N&"PWͬ#Pcy ^3F^R'/\Db!2&s0765밫 v*PMd.8qv!-fʗ5eoZA#Ӫ> r^ة{a$H/䐠}A`X8ͣ(#yȰ'yxz# 9F&$ݐ,Jn(& ˘3F-Ia*^&lx=}xFDɪ*D&CJ"0Mμ  #ڸ _,z{Ȗ>u)K+TwMM*_A1EG Wd&h?g D)3IFaoڎKO\ xg 11tQ4 !GV.Y7[>7GTR3yE gf`!'1|L,HX4N2E^GTAŦXT'!R0R C~&.pa`"c+se6Ȭ,RnKIt'O8{)iN6998m48C&fv&i]&TW)H10lqjHWdiG8F+nv[$nh*S;}WHC7H5}%0$ rlneCU诬;kGNkc ;RIjvk՛ pU(L./g׻E;~|hm7 @υϵ 2]a`QSnNX ~G1ssEMV~>"(IXOMIg5xMdSgDK(I˞CI 8Mz8 po}]'_(p l+JvsrY}N#F,CU=s80_@A<ѧK?AXl4b&TkqZ2E,.ɶ=#Aer50Zk ~v"{WP 2}wX(|oO<5 }29Eɇ|6~t(P1~) % P4\[<b1_W(~Pbqj 1]YlmujrkDH'i;t<#v|5CK)Row/Ŕ 2q:MjzI~oNG$0KCf^mםHY3ϸ1yhX2'?ﶿČ.ئh^E)5 kĠ=oxߦDkorOߠǡ]ΰ 3 >Tw%CNϭ۾PϒeW8@1ŒVMY%g~ݝ:RQbtLg|x[:D"\1.ro0{AjL\8Wyoצ' dr|}}}5k" Yk6WjKRl0}~MF63qɔ nFqwv/ÔefُUs&۟#~U@+NljsOB%OqLHl$2㨻 \N ‹ؘ͔gk:N.skY8IWkW`4~tԺl!;PNuQ2ۧ@F2zjĔiDfnIщ-xo |ys AƚeX| ;I~;BNC3|x-DtqIcypH tܯ-A3/b&l'I8|%)ì7CpG#@ܹeZD3B"ڭT6g)kb)"vl&ȤPuXgn@lhEq[&2'/cG膒BAi#,Ԁ 'ObM4Ob^83qcTƮ#(("ڊG= xo 0p-a S=O=LUqVfA:@wФ,TQȰ,][QAxh4 nC><8RG>7VP}{WbvNnűz*ڊLP#;pІ\7!ICjcxu/@%-_p7")1 Fc7$bx[{76YpHT`ɍv7s75QsXEO\&LN,w^T=^9`И)=DtD) +9f|<t] jd. dcE^v ЮG}2m݇ -9f2)r WNԻZ\l2 /NX7{6xP66p/".`]vQLdNQO zEX/HbD1.D3|^eBe qƁ|Ӏ9=7tEd61g*% p+ u`TPeB|B4b"w>qčq-dEXz +gaQ1^'^ˉMw ɰ&pf23Zԇkf~o-65em qԋkϗ\o RmGh,c؛0g!!C3+ %cpGѧ(aD6y<]HGpZLp2aQ\kf @+^'sGmi﷧Q@H!eTEp lL&l ?64ᛄv#\TM( 9Q1<$9(BIǫA_>*#:0T1Z<Ƅ7v,[^ÎVA9luwN,AQ. ưB&'7/` !_y}2WKOOݏ ?1V< <$&e6j0}@| F 6"{$\މqC${Wa[ "0뭰>f"(x LـcŃ(KH'F!Irbw"l! cSɋ'&UG]-qnmF3Y|aX-Ծb,zyK 47K806""W 0g55⍩c^`ǿ,?G Hz .uc+ϑm&AϜ5~~7߀ >*3`0křwY܍hÂ;쥄&"%:Srat:Eiuz5 7߄ԛ;-gGO 0AFqG&;YA&Ě YM{~e2r}.*oB(A (:o> cl)J7Z ϰ%w^|^Mݷ#؆..!iSdZd(`b&E)7ҰX͔f4{.^ϛсi8@Ζ3+1#F jXH3.߻ U;n|tX# pB M7cJvBb| u<shq8w2@Vҙъ 2e;z)qsU8ѕ8vpo/ÄJ,_JpCFXGJ]kEO#kVQ݅kn5pK.MWn >b8?:P: \q`p9e(*D] ႌHl9{wL`bƗ#GSD7u[9TU0֛5Ǯ㜯QG9b,>Db}{ϲww#AMϥO*+iI~IeXN jl!,Pu 2N-8Ï r :3!Ȩ ٍ?zSyd=yě36EF9Y[r1†> PجEOItgw1sVǞ/%=)%sZA$\.|u [Vk%HCna6N:dN؏ ?h'٬V)YKq (16#g 9BL@7|&LuQO$cqR+1{8%x'}~t pBX 8ZCv<4 8z w‰NwA{/-'υAf %fBM‹gkT; n&lEs M8сX9#1ϭ 7̠Tm.p #'u8ɸ(RIk}hirxI_|3!.H$j[5Gpa^c-.Lt@[a/`k&t7cD:/ذz˰Kn 6``sM}Xx+=Zhı:pj&DH'^zV)x X WÒa_{xUl؃ BЙq"$iad1 quPZj+>% h>쮕D2bNCW5z&'2p8FX.j5 v:7;0ĉ7< H@yx ck%E6rNB@x! ,6,l_Wah%-337'Wx=־IJl{StPQr {u!ǏDK\6Lun d Q1㇢,ݥJ ޛ'| 68k3{,*kJ N ]yFJoLkW#]8bdn&f(5TyES**,54ncF$1gp`©c"AHFG}n9ߦ8)8bZG[D4z,7~l˰g:Ԣ2Ll0G' ҍ ǝemǟ'#&NS,Md@zxm$c#V1`+(w쫣^ًCEA Dw6nFl^Dl 4_2)F )(0Pj~z;6;Te`4MwdʦCr_~ F_F JI:JaPF@Ĩlx OYεx!9__) 6Z%h2vB˕azYVu:ʕijL h "N;i+&ѱc԰ydxeMQ\v>q ."%'NEcNF\]T筗Ɉyc?\,ZHl/'P<Kfh(Fde5,Q7Z#niVh7Eǎ#CSF"@g$%afNRˬӈ޹̓)P`A{. /,"Ds&̵UW"~pҜ:d -#'bڂ;umܺg!H)`"9́ %;lRòsIg`\jIYz0sjat.BY(ʠC\'Q^!gdP>l \42ZP,CEheÙGI˷9i>tQ<Esٔ\r:;QDP>^N\NL53i&VG^rIdgc:mo6\)0ʲ=q7 (qEd,ޱto&b{XɂaMNdZGT@lJP$rd7+\*X30YNct$z" 2+JI-l}94V`b,TbּpLtPŚbKC@Ww[(*g=9L\NpYS'ZV#s۠*U$=/e0ԎK**f^nc8s8QT}~I}99\rKon+JHC馒x^J"Gk]‰&xe)/MJPT=?3< /$Z Gx*ȩAHr2v6,2T~#ɎQSt نCش4J5L^%IcȡɌ&; C2/ :%4[+H$ daIe V\ՆVLM(28؁$~Lh1{k8B(3 H|ry*//[M8؊!.CE])j]ˇx; a;u4}"ϑys8oW"Ϟq>;~?(?m nFKL3OLˇ2F}?[ a6Ѡ2tQU?/cf.W}A< 뤄ZV>Mf 4~_S~}}}}3 bfB8Zw1-=ݦዪWUDLwx~vXӬ_?=g$Bs_>ꇏDc?cz,oj Syf ?ZOO?T`GUa]>wk Q 7y|:/߯_ O(~`eTtW$B]"s?(ZȧsA:ZjSا?>__1NEW7K8S3-}5';^_^xEܿWV?xbTlm׺(z}%#wg~z8 >2ݢ˨/3_&Uh{*?KjB&dŘ;hF%tFA'2w:fQyx%'G%I=m١G-zJ3;sOMYexg]kR6s Y#⡲EEM-}u:k1&,vtUEjUqjW?`aSj4 8AI|=b Y{j,$ÆY1eKptcW+t}j lSl*c2IC1ɶp&3qِ<ӌRLXH$.&CJ)XS?EFJ=`V%1{rO;0|Gj'$Gba}]OtԠYOiV9$=%]o%}Φ[D~d ͐93MOT: TD4ODh0iT"^EEȒ7%btчQf˪j/e3C!HZZU,EP9iOcʰJĢ)M4U9‚&L_6oC96x6SRLfC]שD_z&ǝZk!AQ4ZT G`'U%ko;[A&X'G}FoCy][h{pol|oNu{_;ӭ~B@Lv|'}TcK;wsߡU;WfDx?s+u_y(}@p^`r`1%8(#K(ڟD7Hu̒S6 &QWKXҳd V#־+3L&ǚq%Gv R|"FofLT}M bMuhf0E;^k1UWG1ֱQ-`͎PGwzKZ#Z5 5A䨉)^N#$BrˎCF/&D i-ٌ A{"`X-vlU~*Z8Pߧ%+H@to',]l}G {%}QopԶEaaE\,p2B`_#7U&zq`6ϹMwپ6?PgLîd K5UIlve_{Mס݆HnF7J4Yc1|Gӧ\l+>Z %u"fFQ :/u1zC Tm=Ge {uC2Ͻٻ񥘧ے'y6<=q\$sHE~Mw;ٷKQ{]Lqd/Z7wn^auw3=gÏF3y>W.۵} /t}EQ螪^8F/ }V,=?ge[ < oW{ywϿ۞xrJ^5-0,pL͙^'J6}KɥW1ަoLuy :f>SbzwlS<^h՟U]+]'z6?F6iNwse hiz!Lɘ2^z뿣x[c1ΊHMS&n.ioI%Ϻ'k9Y;ϖ\Ӌa=kҨο1ѶzLۿT;wpƤ}q̾+$ әn U=u~i+kC.6fۥ9,rj@=ȔʉJ 5"R֢LJ+sJhܽ#ڦݝ9,wq[ ]$è!JU[R|=bnx6Լ0ySw7de9!_Xp5jkƐaź7=3Y( Ž?F+农[C޳EdWsy_sK.AWGLzɽ?=Ywڻ6="X ٓsf-]XZS1[St:VtJGosDc~dW&ܔQVz{ɽJ7]-3D}rU%!e⭎ѓ\ T`{3^iL/w[ɔ9yԳ#ΡE폩|`qldU5)jYgޕ1bħZt4a; ud ^D>ڲ&zxP4k𦧮/~(=:{c'kxG]/8f.|o߳_c=Puo~#{_ /Ҭhreh;u(eIV`|MHїmzS*̱L-v% A!w}95Zsu&N֘!19,'kh5$oIȢrozP֥zd&Aսh·pH+i :ͻ/-w)>9.b.z =߾_=Y1dλ1ڰ>YsFxisW+1x>]W} ǒ(\|wϋ)wNٺ"iN~SJA9|UtRfϽ:X*u9_kƜ[P mwRFl TpL/Wʶ7':XBHծ #YM gվqбljL}cxǔSrUmrsHw_b5&)J%"KE7Kͫ>ꝁ+1xxmȚ}+o##^Ur9 xQ_~y7n!uT'LY}ގ_< 8cHno7^& y?h mw=V't:ۿ6pŬK2+9zSU37gҢ`FU8U_dzwG.{СsNT?<\{Lhظ* bGJ߫1xҀV<={z}pmNg iS .ypkm=xkjKm%Jü߰Yku8s w[V9Ȝ=s齉:6OdʨϲI5:ٵ=J֌&ڇXR|%zXm}G= [G Ӥ17Oqy}t^ک22o+}7ݾa;2wKs̎#>N igm.Ycc{hcX^zɽwjX&&<Ց&oզʜ߳w]̸N7%}o?S#Efu3Ab6\)96RI XN'ju4Ks$jLd=ϖ71 1cg泧H`ε{Yє ̞yT3mJFHѦj\j2zw'& ]J: [c7N!W%R8ɘPHƢZ->"bJ1ߪ$AgV1 6 LJT(ޒg-* T=筭כlDHˢ1"}[MzlTS ʣӽi`rP!Su2{Gy̳jSM%:Y,Sa~R '7qGfK/I| эt^!Rl^0!Z ,)0O09 *R`i +ӜG]JzI68ЛĚ7ܦ333ɦ*RVycML eDh'\&48N-|HZT8=hl AfMQ6I!"HR)lthqEeZfsuδi/ E>45?SUN˨z1lA]yI'{߸E)cq:|QPf&LRܒ9j$5CLi}mx2mNQ#jE1wg3JWNg"6m.ρE,״/ltZ`ݴ9taH+b$EcYrX_9ʼ-29%oL+,myیt A/RKMS"[#2㫱)kY ؑXrn/):$_"+LshszP_NKHyVk?ׁ$%õ ~ҜY eRGزRh15}CC':mٓDNlW q2S%EmœvǼfZыD͈Of,^RJ6Kɋ:gEB^(:kdNItԠtpE hd*Tvw?n=*F[q{]F_i/Yv-92Ϧ9oP=Gq=s|\^cIR^)~ҵwtsэ ͞1UX۪xj蜖컪k[ε5s5iæWx6=~Ĕ $DgZpɪڜuBI̞bB/3~ K2*'dhϔ1)ݜ2R1PM`,1uoz?n3dO Rcf!^; Hw`O-ρ- f/>BɊ{zC{Q{}kj1m(zk4@rL&Z1RcfIq=?Z&Yaԝ[sq8QtouY<3#pͺxXܞЧ>bAjiƌ,bWlI=6 Ok&a_ JF8F- ׬GTې5U,5I!L%e5C ΊD%I?ki3g &cS +CGcx3]t !޳c2"-7gmx乮j0cqj΂*R䘐="m蘄9/bk.ZcL;JFȲVXL\ӕhb!hLEQ/L;d-Jǣ!ӂGHm eb'wʰ<'R[> Gu|>jmGxuol̙tm rŬG#}.k[n+}vZ&]V']Ɯ c)-;ů).aO#?=mJ54gd'ptfL^C. yw盺Yo7r']$|۽hH9%I 1`3e묺/5*%5XQ `1"La$QHĘ].3g SN^|[%t` 'Ԅ|qji9ܜ[3}[WHHl" sѬy<{傻Nֱ'|m%ѽᢨĽ=._ [&/&Lu?2u99'fC*LEn=:RJ >{9LnqNj㑾hT̅3T_m+:T!S/yFN E ن̋lnm+Pu)QVJl|0.S+>A؝[_s'tƌۇv&o^^yo}?_=jB+cNgiP6?ЎKMVG\{k'E^3壈_i[ BO6d ġ ktH#>pQ%w5u k'[s_PJ\ VѴRU$wVd;ppV|KI[bSpd8eq 't{VQ/&+x āZw50َ!*({pBEK$i]0?NG wXm [EO To ˵B,//?{hB5ok}֯?Ƅi咏/벲!]5kNȒ _ڬIcӧ\}64tߊWno+]zE2a*wWKʫNتH0)s%s%:R.V1ۖN/^v06oWU6Y"g'sJ_XRa@ݺ]H+\3uy:&DJf/mljFDzn)i4V(87-6Wl߰fs"u[V=% : kv8|tNAiA&旫?ɥn2RyKىQBXwRDǵ~C'圬Hqb2{j׺jR2wh B#B5B nA#ǯ2*M=P^c%\\#ޜ7sƘ˅9H;VYGXF0!݆ˇ[e;Z>4k9;3=U&]ӧl?9bǒ-A W1'מ~0J:t7ybHȯnΜ2b: ';ee[K l/µ>ᒋgQv瑈.WFJԢm)o[% \g<~&,5Sly<==wl.6~X]R S'Uvi 'w}25|X8?RX5_z- n)?y1B_iq,7O+9cǑ~6򎺪AvJG#UgO+䉕lt䐗-[q (4ATWSYHe9L"MV)3́-_ {OGIh++@eQޱ#;|K6LVvӆS+Wb֬pb$#RcJ Vͯp 2LWȾH˕_h*fQXފzbʤY3FeV3$)B?sr٦#۷8D8\>#,|N}]Eo[bnKC3h`*tF `q?"pP°Sn9U,~EW{~4w{.x4G>BVnٸ?vvt[ёmNF;l7E*<+-޼lؽvU[s:dVt;lx̌7l;̯;pB@jxxoܜ Y r]eo>_\mt _<>q]5CM|!2!Qx/~wX[Z蝥C?a%6")m*_P]VU-Ê6W}|K`|WSgWUwrr,KIN)wd8 D}M\,,-nkI2lF"&!_/65-[cjo~zB_WlѢq| MJ2ӓ#˵6{ƍNX7[-6s>s{V-[DD<]>"ӆ*M%KGk YtGo[f=i՟w1psAV)P&.U,Yamܴv_=Z󭆩*-xqfK!-Aގˍ-[զoذyݢVAXBhT/]Ԇ '7F01Ixr8㘇(T!cxqӹÍm @\O1w̸Ή =JJ:.Qxrg;[{g*ROKմBC_5,-Ybcci111F㨣z><0P1|<;M;m85<)_{O#OsߴjȣgC]0܂1YA~yz?x;,ރQò0fơSyFS`C$@D>eƘJ?C[i5&OOHQ՗WYQΚ)l47pNcЉsxB?r iΝyϨT V'y'#`KqsCחtxy]{ HLJw> _҆4ǟ%j=_w̸g$.Yax*EK\Q.$F]ק~ _r,8rt9?*hm&E=V'3HַsaJr cM6=&Su+YZl0(do~F8G>1UɃ_yꙙ+;hssgW=:6h W]cC0 Hˑ,@ʍ ʰO=WYӻv?]%(d]g';axpOfܴjp6נ!c O\ņ}Fx{7-olySy 'n@9&)G%+ Q܄p1J-[HPlkc8%sFnܴA;wnzٺF 9ƿI.,6LTVvv廙y ~0:_hx4y/joiyNٯpϐa . E$عl|s Fº?Yr+K;x#ִUe h:^|59|4%' %HiªvxY}{}s壆lCG&߹zoeebk78qB|:oCE#d0ф;3ϝ<5ii J@2P\HACBd((@(`Ĵ LTXbHfCl듭8'cXwxٲgլCdw/-G?-Ub1ytOi6ixEYfc F:.Z_t('|16~Ov3 2cbfG2>7GU k<#(? t6~`ê}-{K&`/H^v- kjjZ-c;C~o"|M&GDh+KN/GRd'GMҘW_\`rjRr[;:+cַ(MGeaƊZ4|Ȱ!~;FB>ƤHL!.\?3YZRXete'EMaR^c)sԘ4c12 K6rѴZXҘ?rmLLX*fv!b֮oqo?\ʜpT6 wGt:i҂: 40Ar(T26tBB C@8L0gӨ*ui # e'Q;^(i6GD$ ,f֯Op[N%kOjjnkoi${/m/)px.Cia̤IFRQ|ĤXjyL0\i5_;iީ8NJ%BšΜWFDFEł³vzȰv#!!bTb>J끌~YIaBʄ붜k2Dl̈|N/V5cR +IP>FFuDX[Fc\ưX!BM() K&7TFA[)IӦwDGE4vd3$k5ô=E@D xmN\)7< HH:' d1CyJH"Or#"e+ Aڪ+ۭV 2L{FJX ?AKs "=Ttf,1Vp88PyʌgZD|V*.*..nnn p81ry@x+/~ ḍ_MjU?V'bɓs5T$ MTuEv^8c(dE=M#Hc_޸WF.i#zh{zzz闣JF;;;dT*׎WA9=^ʼk.l `Ij![j 'hM%d Vty{0Dр\b.^JoVcGڑ~-Ok( uQ1qƙL&#Ju]' !$ ͹UE%a%  %`4`Kt$ 쏡OxO=0 UJ( <(P4Xzy+L 8[|W |;oA@]0r?-V#XuɌoaM t8.vYP`XW`$?;猪eV " ֤v ㏚(X+Mx0ON5]gi9!U˅ 'XY _əe8 sYf.T (MK Q 5(e],`X ~ȦfXUT(>TA=$c!%b92XoW: 4|pD4[;&#_Q\vɠ̲-h,BV4 c\Ţ/uedBDVv (H0 2˯ aMW&tYt⪈pD/dn[jԢ X0A.=YbyNUVá +ũ`Ygz)cFE`Da\tc:k2q[ڠ)e|4\…H6Ωk:_. Y(%66 A)aU~DBD:P躧c.JqQW. A( a7uFFWE:CSEhe}n"KI@`KC5,R'̖ZF&7"Z[kVwLca:uEBՄMurA)*N~WKH048iI\KAaevԵEIx84`ҲeHZ:.B$r 5jm %ŐHݬr-mBP+>dPBJk"`+(@7Ch W!«j$g)Y_ʰ3A 999sνiD,xe޾R)81r8A ˏMGk*(8h`qQ_g?2("gjp OP~cن՟6\2鉲?40#bbRgM/vגQ>.vQE'Fqn[˨ &wdD RR.dBhjohO6X#j9b48(&ccccqB>15:E2 Mqt6/Y 0O@8ˡ0 'i8\ij`!X]n\$>G-UNFZqHppj bF읝&J-,?Q8N7qFpU*l p6!{1 ӷw0Ӆ{=eԵEEv13Dw45 @gi?sTF],cIp7vx"9M@\a$$?X:kp@(\rÆ gqAr0?9|+`b^{2r ȜpaӠ͚:ߵk'bX™]&ǧ>A 7;cK]J7Zx?>9bѲJWqUёxQoiE8 H"r/WTH ybR5 ἗z!)>#D\?jcn? XlS>u1Xpcu Q@9nz\b\/Ⱥ9Ĵ 1+\xl[F>/ksgf9抳k}-0x˜'wvԱwQ `յ %HxТ 8yo!sf͘t?]76Z)Eː[r}o[=U({3odžz5}^Usf͞gXl ,rݏ,8 >|[]FɸC7}9KH)Ζ>pʸ t ŴowIc!#~1V_!7% C/^P܏,*rW}|4<ڃĻ19\dNUk) Tܿ&Ν=eךQ! A7{X@=Ԅ'Mexo8n[WSGOT% wTHM1'--€l*4vj9>rT26{}S>hW 7. ٵ9g&zp1Bwނ'~rs`=[. y|7h1ۓ&<;}tF u-+bc''+.H|^}gbpK3ǎI"pꢢ":ލL:`(+/( ]un0O@0)v-iaiODEEp5Ơ}qq+S9 HxBr;:}pvCf_^'WSyxN3fXm3 mԀ=(u=!C0'-9]PV;oN(9_6q}<>bigx*]64nϼ:|vOvXE2LE#^|ſ*̎R1ֳY`a7\8y7, da.[G䠉bꕻR2V|LH(H%x;&?7e;w2jS}??tШY>)N4س;Os#54 7i~P!S>wtl\Ǵ742A9un߸ >oѓQ \>uh[8woݰ52CVUm ^y=Аwl>K DXYbZiTq¤A|,x_rG[KO}_QrQ/beTڦhXtyϚu糿车v;B;W/k< ] {u,YqMRHH]m9cI lE\SUY Vh@5YOO;ip5?^19KgдAY-jrqX'{e8z8_(*p^;dt7zƴ[<哥Ff:@X:w=]5@l~N:syT.k)iˎni*IclfVX#we ℲNzBg~NbYVA4|Zj`3x1FG1aTuيiwX &WlLIUH} @`>d-|3;1z8ϓ0ꞧx>!>:R"=cԱ yz &=Scn4W50€25rJ$^A(xMeHA :zs0& %$8~='?bl\ST F 60IFF~D(t6`2p 1>*U($Gy2.˓Gk,T]g8n쨯FF]S.}MD,g^Ξ鴹P|=Ϥ&h=.J!#3.ˡh¢QFYo3_o6***B媘56 biDS/k5Z 3e& Z Юv PV*-"Y[k+^\2 "\.Fa[`iOxqߒ҆v 19 V%=u[&utnj;,cF@8ʛHjaXڼ'qE]眸ާf)tl  FM)I]CN)KlNrMV F5Q<.H!?ZsQ{:'a6uWe[8,La<ʘ/c4/,x˩d:́>0sرc.'#8`oHⱴr2aoA"*wgD"\&b,P,`x.>Ju+Ano` Qۖ[lڲj1򾗟_^J=ҨcK6 Mz]%Dh%:f jyƼSS+qͽ{+2}'Eeai1,*&q  #B*lଧ? a+ =>:2yُN=/6Z_/&{]N~p]ZiE=M6[0 ,cʓwOxwV@u 6WڸB65Z pp,Z$J$HJ|𘪫-67/ !\I' /ϹsqCI2}YM#*Ц X<ΗbҢ8ɑP(TTP(ZLn2~є ;Ȓamm((,!6yܰ́Jkb}pryg؉3潐DU>6)q8֧H#Jy4*J?DV+"EkD, Dc>xtŃgs}ݕ`&2z)Qs'0G:!E+i kI ɣ2 0O5HcamFj.8f e29KEMͭ1Q._r[㒢bU4O)WZVndBD&%FBkΜ}W{QnYYj+JTU(Ó:+J/r4iST퓑Fx|ub匀Eg/X0hT˙² sNJ2grf|茱ƚ"U\_[%,naò.foi8飕ql.U)gl|G aN%%TZ,\,rIĔZIsêN0|p3}ҤISg5o..F ~̾ >64u(yK!!5EA2RIBҡÇV5x qU玕QB&H6>7|djjn'FO ݷ &?NGLp^CmƜڊϺk$Ù1Q'<UF0Ppmi]O=ewq'?d>{k 3y9B+PwKEq)xO N%~gZ.4Չ$nk}y#5*2$n/=QToIIFDׅN"VhRjF=5;Ze:u2]c;7pϿ/]  uX.B'Eй E*c `W"cW@*"R֊x.qe8<2++-UtZf˩Pʔ .n--ڸ|T/7U I#u%6XTKRe} f̒㶲K,1.gfJ1`2YR=[[.AQDCv;~D-0޼|>)M]|Lv*rc_tb{}Mҧ}c%aIYNwV⾙qKQy}Mխ$D! M:RK"Rjѓa*_ {Υ}^d2 /@q\}WE9f ]:E1EpXhI`lh4'c e,P rt0>= ن峎;V 9{7;܋c~~bv8bcM<16C=Q$Lk2PN0d"d˖vec0 Z he',CG#uWFxBhG9*;7${x@@1vzE3nWO{2vy bѡ`9 ,0} #l`˾a:#60"3frCtL f?cy~1%R<q{bS0f\! IۀP $ăa< ن:Xi]Y}< u#vp?; 0Ϗ03 CBôݡFdt2^Sk{1]Vv,c)è-}2B x읞M8g`Ohkbb׾VafD u3j@&E>5f*?qebֈ#2Hp8f&10=cjN,jH栘̓u,3˼yk>bY]{|64m!l%&{c<yAA8PT3N}5!lɐr)]CBN` i`"4|>XAʨS"}f63ܠb#q`TPccޣؿˈ0)j6_w1)@ ~Q bx ܣ3 3@u'0+fx&o( 8 39*kqIQXKC!F88ol7hvc`; "iT[:/{uE=)0 c`H$b QVa4Z6l)`+@wzuK՟\ /ӱb @FL um;]SO1`^OpΰAWDuoa8[=d#'=s]ޭ;sen9Pe Bƿco2tnنݱa6j^+M4Vhඛ .B  s\hiiyG|% l4ps $@ pCOِkʏٓ=to.\Jt81MrQ W',N A+= FRlk7@foD g vC4"~+^!o?##` ( zM/үw!jٿ/ԝG@ ސqWv4nѥF52":.c<F2 a#_ʤ+HB|J{ZD Mͬ/)1,>>~ܹv7o^(]W&D!("[ye& lMnH E%? gݘzH. ?y;m0 :PuzCF= pn__ yF}p>"'#1fʡyY<~Xܯ,#ż_b u4yiBSP8檕K y']uzXKH{N_nЕ`w1:N= [B-&*'^+mO(ϟ`Ah/%i5{9LB)m>R-OǹIܧo^_ff7(gŁgI\qPD_; kYHעmF[Wੰ0۪,:x2L"ݗ+UWh Յ;:; EqŢvw&X *|ڣKNc]Y\ܭsV7 ^T)!H|<'2 -*@_՟+_x)@iѻpR3-k׷PމYuڈa|UU!ɧB^k@Hu!1E&/q88\~afs=Rg}6 Fg1Xh ]bz0Y_JOT/$Mdی0XopxҨ5vJ0ddb`d?0Gh;jsJSx睝$)0mg<|`\3F9[ \P4y-zmI/үdO :BRjqX 8X#5x,5dK>qk"yY<@Ix<<<'@Eiv '96 bD99*T8EJu>r_ bv~"8A0K3y:r닖waT r,;ZxJvfTPxsJ^h3ԉkfG ё}RnuxÇqrujIU{PQӕx:pG? p&_:_.wڿ9'*#78~ Mȸ8ʻϋWSB4EiP󀏢-Jz{CA 6DQ( Q UI/һH( ';;C<0;ٙߜ{91 D (Q3R^4hj]SdDL\8uaOD]aX)8pc L*ψ^7A/5ä[Q)2a7p:'Cۙ mj=&;=`DLU%p+k:c94 X{m+Ԙ}>˱;<2T𮨡9)Jgg~k?rai?e>l}4,aݵ,\WS %&sj YEFN9!mWCs*,qySezxSjyu:n4b! .V$bop,+Dm?ډ0n }#tȕ*KPyh$ q8ΣV_NG^^/:w C2ӋeJ[S9QrQ~sQE$2z-:vC,8qktqzEuTe| 19짴Z0{P] pDE|m5R 8,OpIh(9$@C*B3 ,~ "LD 290F\ ЪQM&vt6C0U-Oq8}qI*hyA@-N A+l gaBVbH4bIkhIqxi# ~boHI'ܕ3*&&` hYNl8 HMӨ._ RjGf5BB۟!P ]nBS4LgFP"כ&ś#A^#njYNBL.*śxoq@.Nj:=c,y|M9R>r #TQ N^PO-8F| y hFW 8r'ok \~7X(cs[%^'@+.74dAPVS`LwLjjG)=|5"0B1p,X$}; _ABD9_8-T*ŽO Io444zL&E ZFc0PQQWWT P6@yiD}Lg3&ߺ/6Ġ 3i3.J_(,dYa0C_($P_xҼ)h Dq=I>0Bu<#-Ha^/A:,**ϯnݺuEEEg 4.@idggoܸqĉimmB.]j ϠHD&Ф*RG!G0G(.׎@{j%JȭHL:r95`fcc+V\ tX $Bvѣ6mڴi`sWS\/Wn:v#zK 7)L. b B1bCLX1KrObW+GA =()h kJ (wZRr+p'(iZ h&NpqTd2RR\o`}hߊ5f0SĎƇN/~.b&f@(} 9!FYˈ?9-DIL,"c┲˛}{))h n)L|xi[jܙ]j1l`)ȟʴΝ;T*)殻:t(2@L&4͐!CFJQעo 5` E?Qu&֗B[ˁ<9c!^ ?K_Ɉ^/4MAS4HEg<IMIV<ܢW( &222F#MӒv}Rw$bmgҝhi 8 i#{/!CE|h )h6|0rRTKI E ^o2鼡(L[e6 bxo~&LcYVJw+#ι2 ce UV)J]S2^H>NcW.kȐ!ϿݻEN'2R$Z$)25@ +zNZ\BW 82ht8׋ $Ϝ93c WBѣoiӤ"mMm^k@ _@ [(=w޻55-Zr:xH_YVO>hѣy799*i/`%@ 4M[<ڣyC8I0a'M7mtq,@ye 1@" IAԎ]te^ WzGvңG~9)Vz[^@ A|a<ϵvM{} +."@P\@ @stm]PP WU2tiT0Ap]`8(NFHstq)GӬ@ò\%۫T)iG4bj&e <T@'%i$gY644$ɶQ("uHGJ_hwd?ػnE7j*[xa+ӛj/^8d@uNUq=h.;{L9fh3OvsܺpA#t/Y @ ---@HP2 ri6r9r1s` 8S}{e.yɏ 2\׮wׯ{|smMrj܅^|3/C?%mrPZ#SG<7t6{Ggį?;jz&/@ =J`hmmDөjLn锊JJC2 l6M@y<^ZYNofV?WS5=4ieu.w);'UV$u 0sĪ9rvKrsHtRLfC6W\JFo@8d˥haY|$IaI(_ JmR ~ ئ@nCBJR  TnA|L@L.@Q\`X`ն9>\/kkc}UsMs;Un=WݫL>_g/[盬ŖW7Uq~߇_8l'sL͟;q'.T;@ xֻc_]3wQ[VowTT HG;łSLl{C鍁qC!žK[Jk"S4j)=՗ߝTrtӊumݲM2S}Dyn^{mH6:a~ڃ PfqV}GP˰1 NiVÙniw:|a !v+Sj9Y2 `G9~R}dWmt9uHѽ9#PI#9E%g|̊E|`y/H2$kO~'ߺqQ \]gW$؛s/zyix1̤ܶ+zgnbsYPl KM?>}z , aBlB➹Rڸ@m{wi%uԻKzRZNjO^e`Y\~xilf=~~!M5gl?XGjp:%$:,xp;łpא;FimmjtI~h#;ڥ+{Dc]3}`yuzFjbZGEy fdj*6Ct= e[,M0R4Z,)AwW64(pX|_gƝ&ZI=L ߋFc#*I18m+}ph{NVKnTynX@OgFϟ?ѫƶnaf{_lL̾vT >< =7w8]b4T^& =so.:QfT2vOE=C}65dӕHjp\#p5"la2r谺ܜޣ;F-Smb?pO7;1wFϨUD+6 F9[p++DZ9|&MZRV\ɚcceWcZʓ[P*;K#}Տ.f4FK)ɑ# ?=.$ƅm^,mȈ3:}:Ǩ3Gqn?9EK>X8Μ+G ՝wٷvBM@ RWF6f\&I@HٵkW&$$- EQ$InF2 (ex4:2sZJxf &.տe׹5sSeL;md|YUKTd. k.lh-߿iƠώBD\A<"`2Fa2QV-~~Q*c9ʲIC r>o:nmnT9{cECpNӎ?|qPpMM**-IG6K;eZh 'Q%UAʋN\! #.S:sZN9(^S郹+%6yD`B)yN# ֖2*ST_sc9 ek1Qfkm cX\-^AaˊPQ7W5{bP&|͑GǞİ!1^PѮ s V(/0hi mQR:1&%']3Gbu޹۫wY&'D򰠐i* $*DoS f3\%¢ /3|U6 w6/~:g! Q A͗ǖ4p醜{ 4ە4-OL҉ 瘸YC +M ~zBJ--3}0Ǡ!}HX1`5H6!2sC.EF_>$?C08cAjH>^)t, XiSpm#owh2ǥesDQ5+%u\wlѼ)crC0W"Ɍܾvuë35J{6Tܛڣksgs+ӻXc'{r9t=fE:wک0%EV8trc҆K}=d{ݜ2|tU?=Խ{gQ߷! л3"uDp,s.MsˆVWp2':kШ SeyaJ! J9Rl^]iqpaLWA#' ZXtyG^[R?mڻuf;ƝP{Ō)o^f9Gű_7CBg•k7(Kz}cY&swۣO?Y_i+`̂? }#-cjb+Yq,w'>0, QKufOc2-1مSwpG-p@B”k[SݱdO.}=J=/M@~,vl^45Gw232=vPi0E5ĵ9džeT(Urh 1%hU a u.f/ȟ g/mU(5v=:9hnu3V}XIHcUNuR8f/t.9yqa4{iA0<`iug+:G}i <&''jq~~f *S8]VeBCu:cD(VǓ! zw8&LK@ ca J|tdFMW~I-@muAIŵq,u>V:\Ū+.ƺ-v~F /֥gc2y.]Խ|I끅|"ǒ;$ !HB Y`ߟ1~blw_|9};ffKLU}F(e*CONs^I.mt L]8[ZZxg^5|f̖1?}J}̙N&?;}ܥMn4iOa&n/@!@ 4$ IFt_Wv `cXCyDZ8NH(WTĈe;XˡJ#CݤJth[it0LHH$? K/z+0H7J$.?+5 _c$5Is K?hTWI75iS`y{3)%,㗝T2RA3o9q9oSzcĕ]]A^P@ rbD[p/O{ktW;VilT/D. S&+M/a2A&Fş>qԛLiF&pRu9F?<\ױYwOu0!(څcƌ+>$2o_wRhD#O\  yI%ZcrL rܨuصP-_ऄ Q8҅Ƽ' @ ȟz"HyeBI:DN ^qsz/aÂ󊫼^Y/,CbMsC}V\}Roxŧt>xG],m[p}6X =oe{NRkAHKɚ&>5mOqMFa'/1}HT%q-/Q|3ք h(~vHrgG/ݾw8snttblz׮^~gi=e8il? cOjBCAڀ^(r;O>.,oȸmpixnFnڔi*MZVuOg<2yÃBӺwDZt_~bӜ3_}-e}Z5kOoqwά1.+(D ZsbEF%y}GMx^m"_g_QZ`"uJOxڦKVA<)gg>۹tUdHql[~ؑ͏ӱ* R BpDn.]ds^nT7iރ6naBz ][ =r}+"e `غ/o[B^LͺʝOz؞Uep4≗{󥗞 VM|~q&(MyC3{L}ʒ a<}}gNbN ۽/֨--fc,%ɎH@ G\ 7xkSi2Oy/4X͚cD7>ٻJm,sgUfL3}Պʅ?x<NqQo4zDJ<LǨ kﴀw||"\Ek{i^6)&bؒ;6\HY}Ԧ;F=CZt}P׎I^\y=óԔǤ -.Д@rPgPVhGzD˖o!5zMylK+k<95CtG1/޳W\W%5Czw޼zsM{-.Wt Q@~Z- UD2D4J-R<`w24M$xļ2!!M!6N:U__o2jJd@x^ n_ǁPi+R)_zUf @n3@l6 jK~vU$+i@ یL& -//$KlllTTTKK rpTt$2@S2%...<< Țh0r+$%)#imr+#MCB+4*߰ojBh`";\e6Q(I m+Wq^cRuliMfn.lvV1r`LA;nݗɬ/̳9b22RnHeM>6x)cg*{;%@CNvT=tG߿iVgJ줗F~{&H ^U{z#6MxsVѧ:{YI  ftK%"^2RXMRA܏IZN9i~]2eW=2]e-ytNۙ}#O]~R# :ö'2E_.3=wop6=_Peg&M|?c*)N=q&2# TOݰR|9Qe=n\j|tdei}0v=՘QGvҭS쟶Q@w֭Ze1ӞG[~XIB?fH{]kU65^*8?fΛ'?6}jG_W%*E/VƗl@\A;1FFmL7@^x{<22"tw?4„7åϤ0hc5WU&K>{X%2yM?wx95.תW&R}uKck]Y"7"sFvZpƍ۫iKte_L;k1|gak,+:U\v$S.25O޽%ƹ|՞#-WPuKuVnOYvdUX}93+ΞgPesw ӦY)f[Rϻ䰴Է8UE끁3')d]pb >zߣ0z0\dʰ`Ο#Xp`D^ر) wjyɒ%޺uZmBE-X+^) +yeP Giήlңj8ŶAw&<LY1apj '*6 A* ͼdTSo 醦MV`䢪!Y:Pwi ?Id`ŏߞu4q1L i#F?s️ty~t/ǃP6F끱Nl]^_=?~Os~ʭ1oNqk̘x0h!{nng~(񚢢K =C/OpU 95}gUsnZWe&u0a1C fgR{vS3^34ٿkD$tنc8"7 Z-Uű*pYOU^8LpuǶs9]O?&]iQk2U:/ @ imm۷oFFBʤMH)yeHX @u g^ Ί? dQkT9\^VM)SPhG=B͒JbNQYt6=[W9I)=?}BIcfj\e@˅=\k4_ye/a\> D=nܨ/>z:P'8?_99tڿ{ˎ1OܦJ=.5̯MT_у7ڣ'WX5I);/cazs76Ϳ*Ը>vp:WM)*BUtP6Ezܻ~[]8LaXʃ`hk٩ƍG{r5t4rϯS|v+/vJ%g٫gZ6&5 DKϟĘp A$S)Iq-J!\gHbFGطsMųtBXVaUkZh}}33:ƃTpJ]ݱ2sxtI0hQ6Zrs)Tٵq݇c?4ydgf. an*2RcZ*JtOʽS^bƼyQ0V@ Ν XVZxohhp\@,=Jԗ\Sm65njW덵s |c>qhޙw{NZY~oۋ64E2ǹ.1,'wi>[H9^X?xnw?^j>~|Ro:xWwW{ :jB#G86lܪ@iPw L; M{kV_QE :L 2~@-ŕ \m,,6HnבS.1r9e]N4ĀP40@>FaY6**a܄sr5b+&sn26F&t+_{V'3Ց5xtD+ S_S2b){Ndz2Յ /'*zuqrK.'ELܣ?UcRRc;L3-1PӢ`XuCGo3U,C#8<[Hm\53p%}j,@  P#J뮻z^Ws+cS.nЫgd;=b52Ɋr62/ճ'' #.;0܉}LDORe id?,2R9|BQ]=ᯏ1?{sj7U'ΜIǟ;s|M'[-S}+,Jg`uAB[ I 8.--d2)ܿXڧ啡($Ic0BBBx/M J9z)ZR!4J8dLrdX14xv'kIs N8.7]lZ?)fiIe(BTy֭a}}nePI//@>Μ9DVk4RnW`_z 6fPL!edS41/.D .KA7vۊ'?!4:J_P??iAF:Q\5|8Q''# x}A wmlllmmx<2eYa*m+\*cu9Àq87s;O"ۅ[5xs.` @  _zJ+---oۘ$$t:z=EQ]Oy + MY,ǣP\(_:zR`\.k @ ? Fc9;`<TlV@ hd2P) 2UV!ы\+s} @ ,#o蕁@ ϗ2&+#҃@ Hs+# @ H"AQ-@ 3u<_k)U I{ ` s8 QKW2Lр_yPJjVitU{W fol a.`_`4)hk$44l'<OnnnPPL@ H{3ɓAyѾjCk׮Νs` ,ݻh50>##ho_233q^H&nݺ'l6 HN s;. b|y^}'L!!yQػ(L 䄐@ #A@QAD"*,* ,^("?P\Pte=P9>EP $HH c2wmtf2Lo鷫zRo]QQQQryƌ='O$܇(ɲ5MӈU144S}fyX&DFHEQ*OtE6&pUNMH?S(%@{%5^nwqjVhkMyc!o`ZB^źeK E䑪+탲L/,R]~>PTVvݛ%δ5HA;Z_f&MkC30,سNfUX}ގG =@wIw'WΜ/K>y忟Dݞ}Թ3//ETi D™W4.}Wv:fo*G^o9oŵ#ncZ9lTTwnk;~bm 츇Ǫ:81Ѧڹ$>U֥Ӗi#+>gOzwjXUv~A8qo.8/nvʼngk7::Xͦmj!?=RQ;).~v3Tv]>qUq}_ 0`^F϶b|}$M[W=ipP[{e|')._G)!)(ou-(ȲoZ~Z[NޚC~|H$C@)I2!Ovÿ܏uU}Ynh;kdb+*;?b0Re͆:[?XhER//Ƭg^ afF V_W/c͡7;WO@H>@,W2>Kظ{nҀC*2&qIu,SKܾU5bvpź=r& ?lkUp^~ܱf[ʔ 6 X-&ȜfVtW єxĨwK e،e}vbVxLU8| vL:и [U/U'_vgkO6͞?)¬A$ nqT{gyߙ;o^$m5E<1!ts;*$Eh1`^ N+++ Ĕ,>[xE[=y;+.7Fw}P_ѿ]3im+Gvf1U*TH{G ->rs^wu8H2-k]:RypyQpnʷ*7 FNxelb?̏hqoBa/=svңE֕*Խiv}j^<6e2~ɷZE"آBxT#JdY12`>*8QWצz(8,AkSzߏ7*8M%QxQq+/wɳX+ڝ/M<K1*Vx^tBEЩ96͙8-g}u%apI/De Ba!Θ]&A&UXO1 &jk g:uс?M_7 0Wj4`+anmn_*HQ׭+h%tJ6W];Yy]%E}FIKw_S.m2ޣ$m**خ3Up=LS{E&,"YIsTh:Nk`UԹb:xI YVR^%_"亣gI]7֔UHԤߋm4%>8k4k6}=de׳6+؀A!XWM/:tq:44wCּftd\[_X~S3b̼(;se0Աӧ-_o),Yy?,',OOzr_^ޱҾD-Vm-b EmŶ($Eŋ nFES,4K8UU0Tũn6qp.˚IsqNҊ$ (LqN6"GLdUDCr4) )B ta8Ų e^HDM8 &E8N$Ӏ$,)2Rѵw(ŵ{L(PB 99V0ɢ(H"s-M6hl7)H%UIF0!/( c9W Bf-b)mq8d#qB:4?S9rUy^En):tPrr22oQQʫ144E. cCCCϞ|%DdAtOQe^hE9eISW\wOjqq(ETd f E*[ZpJ*sf3! Pc˛Q~ê9.T9CH%+'#yUࡓ-b&e.0` 7A{b,+ְD] #zM7!4{s=-& '@ Q]Mw^&֢HQ;Ak"a^0?YͫJH $+ ,#pNSdԜn*B Mh;XO{ ߰ݩSv{tte8*'p8._FЀ  N>c 9J]ڼW^U#O۟{, e1 \sOPbAvg)$ b)555VU1 TVVq= RIŽUp 6˂͒l?σu"[ZqFbe~S,ޢZ=9\MEo[geVE׺+KK@/nQϥ'I*56G>466f!~ҥ;(PX+**~4HUJj ER%%%mxU$p"55eq K2TN…ҔK7l ^zMsϦ+ʧ`熽Sn Fz۩_wufoh !"pA1](ɱ5gU+aJtOw#AJIouG;mh͵~2-ǫn>V1{FTէbU x@uޒ/cSM!i/Z@:7WUwޓ% ]UZjv76=Y_ iW{hbNڔ VU[?i]`O;3=aeIENDB`Pylons-1.0.1/pylons/docs/en/_oldtemplates/0000775000076500000240000000000012012307216020372 5ustar benstaff00000000000000Pylons-1.0.1/pylons/docs/en/_oldtemplates/genindex.html0000664000076500000240000000335611645401275023103 0ustar benstaff00000000000000{% extends "layout.html" %} {% set title = _('Index') %} {% block body %}

{{ _('Index') }}

{% for key, dummy in genindexentries -%}
{{ key }} {% if not loop.last %}| {% endif %} {%- endfor %}
{% for key, entries in genindexentries %}

{{ key }}

{%- set breakat = genindexcounts[loop.index0] // 2 %} {%- set numcols = 1 %} {%- set numitems = 0 %} {% for entryname, (links, subitems) in entries %}
{%- if links -%}{{ entryname|e }} {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor -%} {%- else -%} {{ entryname|e }} {%- endif -%}
{%- if subitems %}
{%- for subentryname, subentrylinks in subitems %}
{{ subentryname|e }} {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%}
{%- endfor %}
{%- endif -%} {%- set numitems = numitems + 1 + (subitems|length) -%} {%- if numcols < 2 and numitems > breakat -%} {%- set numcols = numcols+1 -%}
{%- endif -%} {%- endfor %}
{% endfor %} {% endblock %} {% block sidebarrel %} {% if split_index %}

{{ _('Index') }}

{% for key, dummy in genindexentries -%} {{ key }} {% if not loop.last %}| {% endif %} {%- endfor %}

{{ _('Full index on one page') }}

{% endif %} {{ super() }} {% endblock %} Pylons-1.0.1/pylons/docs/en/_oldtemplates/layout.html0000664000076500000240000001741311645401275022616 0ustar benstaff00000000000000{%- block doctype -%} {%- endblock %} {%- set reldelim1 = reldelim1 is not defined and ' »' or reldelim1 %} {%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %} {%- macro relbar() %} {%- endmacro %} {%- macro sidebar() %} {%- if builder != 'htmlhelp' %}
{%- block sidebarlogo %} {%- if logo %} {%- endif %} {%- endblock %} {%- block sidebartoc %} {%- if display_toc %}

{{ _('Table Of Contents') }}

{{ toc }} {%- endif %} {%- endblock %} {%- block sidebarrel %} {%- if prev %}

{{ _('Previous topic') }}

{{ prev.title }}

{%- endif %} {%- if next %}

{{ _('Next topic') }}

{{ next.title }}

{%- endif %} {%- endblock %} {%- if sourcename %}

{{ _('This Page') }}

{%- endif %} {%- if customsidebar %} {{ rendertemplate(customsidebar) }} {%- endif %} {%- block sidebarsearch %} {%- if pagename != "search" %}

{% if builder == 'web' %}{{ _('Keyword search')}}{% else %}{{ _('Quick search') }}{% endif %}

{%- if builder == 'web' %}

{{ _('Enter a module, class or function name.') }}

{%- endif %} {%- endif %} {%- endblock %}
{%- endif %} {%- endmacro -%} {%- if builder != 'htmlhelp' %} {%- set titlesuffix = " — " + docstitle %} {%- endif %} {{ title|striptags }}{{ titlesuffix }} {%- if builder == 'web' %} {%- for link, type, title in page_links %} {%- endfor %} {%- else %} {%- endif %} {%- if builder != 'htmlhelp' %} {%- for scriptfile in script_files %} {%- endfor %} {%- if use_opensearch %} {%- endif %} {%- if favicon %} {%- endif %} {%- endif %} {%- block rellinks %} {%- if hasdoc('about') %} {%- endif %} {%- if hasdoc('copyright') %} {%- endif %} {%- if parents %} {%- endif %} {%- if next %} {%- endif %} {%- if prev %} {%- endif %} {%- endblock %} {%- block extrahead %}{% endblock %} {%- block relbar1 %}{{ relbar() }}{% endblock %} {%- block sidebar1 %}{# possible location for sidebar #}{% endblock %} {%- block document %}
{%- if builder != 'htmlhelp' %}
{%- endif %}
{% block body %}{% endblock %}
{%- if builder != 'htmlhelp' %}
{%- endif %}
{%- endblock %} {%- block sidebar2 %}{{ sidebar() }}{% endblock %}
{%- block relbar2 %}{{ relbar() }}{% endblock %} {%- block footer %} {%- endblock %} Pylons-1.0.1/pylons/docs/en/_oldtemplates/modindex.html0000664000076500000240000000454411645401275023111 0ustar benstaff00000000000000{% extends "layout.html" %} {% set title = _('Global Module Index') %} {% block extrahead %} {{ super() }} {% if builder != 'htmlhelp' and collapse_modindex %} {% endif %} {% endblock %} {% block body %}

{{ _('Global Module Index') }}

{% if builder == 'web' and freqentries %}

{{ _('Most popular modules:') }}

{%- for module in freqentries %} {{ module.name|e }} {%- endfor %}
{% endif %} {% if builder == 'web' %}
{{ _('Show modules only available on these platforms') }}:
{% for pl in platforms -%} {% endfor %}
{% endif %} {%- for letter in letters %} {{ letter }} {% if not loop.last %}| {% endif %} {%- endfor %}
{%- for modname, collapse, cgroup, indent, fname, synops, pform, dep, stripped in modindexentries %} {%- if not modname -%} {%- else -%} {%- endif -%} {% endfor %}
 
{{ fname }}
{% if collapse -%} {%- endif %} {% if indent %}   {% endif %} {% if fname %}{% endif -%} {{ stripped|e }}{{ modname|e }} {%- if fname %}{% endif %} {%- if pform[0] %} ({{ pform|join(', ') }}){% endif -%} {% if dep %}{{ _('Deprecated')}}:{% endif %} {{ synops|e }}
{% endblock %} Pylons-1.0.1/pylons/docs/en/_oldtemplates/page.html0000664000076500000240000000067011645401275022212 0ustar benstaff00000000000000{% extends "layout.html" %} {% set page_links = [ (pathto('@rss/' + sourcename), 'application/rss+xml', 'Page Comments'), ] %} {% block body %} {% if oldurl %}
{% trans %}Note: You requested an out-of-date URL from this server. We've tried to redirect you to the new location of this page, but it may not be the right one.{% endtrans %}
{% endif %} {{ body }} {% endblock %} Pylons-1.0.1/pylons/docs/en/_static/0000775000076500000240000000000012012307216017164 5ustar benstaff00000000000000Pylons-1.0.1/pylons/docs/en/_static/akhet.png0000664000076500000240000000222111645401275020776 0ustar benstaff00000000000000PNG  IHDR4"') _gAMAOX2tEXtSoftwareAdobe ImageReadyqe<PLTEHCH|PPGPFB9tP͇72*=2<]WGgFbi9,6]klܑU=Tʂ`aU8RPPʳsٌl}Չł{{zr\{nKҺwmmmB:,[Q8%""20&rkruNswNUL6,%+E4CُsfC`{SzfL9^ݚXF䥁 C-^?d9Z{@Kb,+q}ȵg>SÑ_Cz\LQr Af`d+@GL̫fGp]f![)Rܡ=z}tzb3I+F烉3\Q71tb+:KY:_"ӹ+ ~-w{VA eS䑢sצ"8),b*=AtdYntnMSQ˜ʅkV A#\ o[~M8_H2yqރvJaҚۭCEP-=\i@:CZ(U1iOg(B+~9Á 4O1QXϺ ]"R6t)}d;'L9 +RgwIENDB`Pylons-1.0.1/pylons/docs/en/_static/akhet_rev.png0000664000076500000240000001470611645401275021665 0ustar benstaff00000000000000PNG  IHDR;T gAMAOX2tEXtSoftwareAdobe ImageReadyqe<XIDATx]ku>\V<-m0Z 1MlDŽ SuH\[+0ZrbD$U,W9?‚!c`d;o\w=_թ߹scJ"[Vq|f=ֹ/&W2XFR("DWCV:Dss;܆B8o>LS(JvnWOUj\=(>raQބեeN;n\YA@pe_F؂ BnBt rElr y{ZMn<~R-P?P OP7vNf1I9/^_6v ۫l.BB">@\DŽ'LjR4ǯzcaQe˄& Cs<~}7؎kXBɎf:-&6^Ȅq6o_p]ӆ xߴd'^q'?L$avBd%hh(Ae. 92C\Pv'~Q/QCx ~;qϰR+HF37XNPk[9z l_c[6 ŭ4:G%&J GQv oog_\8W,WS(ZE{Myl7:pY*o3=>$uy&nl?;*pVNPkLkR3/zm'{'y;پaS ))׍a(ەlI2 !- ˁ~ 9qqJi`vUS(槲3du-dr˵ [.+J_!{@QvodP(5@pmD3DUTTjfI|b>.LN?BVˤdPOK 64ۗv+W 4;IA/d2H q|v1#p@-))sN͍9~oa68=d6_GX(Sű-8O1slȞr[2GRP LbcB@P/oI/S楚DcҠOTeP3LtwJeDx_b}2@қU(Jvo,S2%0cK$J>(ϛ( Rug %Y0PDkY֏ND9aIW}&YUrSSSVR(x*gG,f{Lx#lWBd7fe5) $e_,Bd,~,_&;&OPcYAլ"PuxUTc,P.dX˶]If0s( "d3S3 &Y gX!C\ TLͰ`rV\r2!9^cկQV# xĴÕ$A`oʧ],P6t1ɵoFz0mCqv.C##Ix*!^6vWd!Q>P}s}?)[#{մHHol/=f|8kz!)i,M Nۡ^@p';mTԳxݘYy% 759I ;a?oo獊jAdgToxHN*Xa;%*ce4; O3 -eR_G۠<,?#Ɗ"bvL ̳Ed$8'uh~nLvTvGbp<\ՠR#o"s ѠC`E/CJGqnH$G仧ƍ.r?gŽQ"!CͬYv(`1ZZ5HI,FY~?7游ë\LM.oQ*P5Q\\ٶfUX >CCC螐~)ߓoeS[mbb0:ù\z'eDX% / *R|-?SK^~oq]Og8+x8Sz[|Wn}_Q 7񣾼x˻&"5!d^9א0>(OT(]җtT${l}2-*)nJy%tWnEk;Bx$sUz#g6R}x$o|}WWnl06"Y%ܔ6ݮ:=q̣b}z䳄ICl&?{¸ ~/q99 ˲6p^@Y <^@_',ƒ[&dPWz)Zx I fq]ys>]C-a֨pv]]r~SP.z#7vSYTwNEg2쪡c5X/UL͈فz-j\aE w̮(Ga~8\o7mIժF U Ȣd CAO F[ƌBA=nڃ'Op@fRpFɟ]CX22 R%)@FqBvpeUj[9N{lZ~^9OhЈ 7jfYcp=>7tz{AKH(Ok#j3#Mqq[U\~I2&΄0>JoEvy&lG7:L^HWtM["dȡ\Ǘ_uVG O1*` )@=L~g4B Ȯ@0 ysfts@I nQ|(^dTTwL`}/hl0h,ۄ"n 7&u7om \h/k!gy4nT L/ˍ9{7שHM d511I]UwT*e;tN\zQ`k=nn.L(?IބG#;pW97lPw?!)EXɘ&|XT!Bqǟ5;{Y.Q7`Nnu^;މcᵅssGZ}yƩbHQX} sHCQj,ڐCfJ|ۓTMSPN.TOMp}wĶ^ʮ>2}|;zIe.&VB=kΈ3.3Mvb!DŽ;Nֆ"nd+j9MF#(iK?\V"APs;_N6p*B7q|32#AB:E3ۃ_eK1͔}C dFY|A?`tQdEGgt)!㛙~ceiqnH5#:#ia4B6$72*~[2gIn>ȄJ~JԀr/dE ~+2Q?.f!xkL'67tXoAsT"*84b4: +|Fb@vS4AJk0?d.L #70+am,^AْRq!@p(J}&Ό0-g :u{P1?pٿvՌ2ͺ8#QoZ8g[[ ;BxjeNTg5 eRSN}W"ngm 0ۭ$hRl \#~fcnʢ D;}P(d3.j.ٙzr ˕T]df:+uG'.RFބ@3 < p7qMqxҪUNWPp yd+0p0dokXVrv&6H1Er Bg}M$Fp:>ݍ ѣ` h,[cXTO`YcAY[%rqjęЦTm)2,s|Oiqw*J:5+hNJq/.&Yk8ر]h>&!WXeyGDOAk}_4 ΃=nBQ)2oX8rk+"5?zŏg6㫆WMR<MNjcKWSk,EK59u5)HnGN'=ޡ"4S/+l( ΅]e{ vOĖ5B{u 5#ҵTׂl驑^*%6򴐕96[v ֟c{=*?\FiԸ'>XdA kY~[=wC%isph/OTz{fĪp֔rB6^5<ۼ֒G9>l񕞊G댸.]ɕT58UY۲X#aKxK30#ȏi$Y̅*|=WDi KRL}¸)vc?*(ղg%⨏X銥quY*AP{SYXִW<3dg%ʺ's’+0"dL2&Dș"dNBr"dNBdL2&D>D8N83 8 vjvnvjagVp\'A;;;ww&}Ia;w ɠ&A>:"ct33˃T1\OZb!_>z aI^L 'f039c3# `=7)>gJ,@0`C1=UGWz94444IoqHG>V\z)> \O~>r1Jbdd,fϡֿѽX2#1#/HINn=k=u>}zdzuoE8Nb1`Lт!RG>mŰ({t@g#g3q3`&q33L3q3q3`&`Qw'9s9w!yw'rsܝ3s3cP{q3 ;s'hB8O?sfcbщǩ _FG+r" ^Wcp.9Bc~^Q$sO13дo)e$*g(!H=+2Ÿa{2b~?S1ѽ"La0&qYgqXI Cɉ0{ELzp(={oB209 _aރ(=NL'HgяHc>6!3>} 3A O" 0f? UkZfar$>38cq|iuן'^|yu֟'^|iu֟'Z|i֟'Z|i֟+Z|y5ן#^|yu֟'^|iuן'^|yu֟'^|yuȢ|yuן'^|x]פsÉ zg\Lt=D=2'$ʧr;ݪwk;ʄ}`Z\r1Nuv._5Wr6uIXdj3O~[BKf6Пb6i 'ǨG^pj?ى; 9ly[wCN0, VA=!4>4˴t+ܻxmU"F:޶Iv, 6n֏>=X:gڼ{:|}n&b>=|}LƘTkdk,>Bϟܘ*VpL;>N <LL0^B_GJZt̲*oWUuE|Z׭]Yew.n E:f|-<,=5Nmxu4" 5@ݭIqp{9*;6MM }x S{NҭcM<Ȩl}o/O={b*Rf^r? EOݬ6-{Om 1rTqR%YUI]{\jÐn븢ֶAV.7U5ۺQ&͊|B;4/V]yFGر\"EحC{[* aF==_,5y+fbYr/6n햨 Yjۊ/=;L_avk$³5$wZſ=Wu;]{tJ#eCZl[ۉh vyqrO^^Oً J6}m&@?fZjtڔ^S')M1pگ3;8-{> V6w7_E]aܫˊ[}ו2 k9tej*PRV!l׋8 bٮVK%@X@$%h͌g U]5HF ;z[M BsZ{Y ݧ`r_Rc-:o,|MUuLؠmbWRPe3c50ʺ`$Vj~ZG4 iKצrłlWr**Vua3WRԩ+YoASIXJZeEuͅiZYgO_!hS1s,scT )޿h3/yJM+kʘugditZI}g -O[]oֺrA=Wݲ8:BTK5~Y/e~?~K<o7!dk]UҞob!n[%oEq~mn\,5],"{i6~2a ijWoF2&zm M7\.],uume0&-ߝ%qG'oC#Rm׷W]Rumƪݝ{LE[\BR}4z1n;v}UʫM[VpX+ysY]kɒwFX&YȂݻMqSkM[W^Vuj ߷`Wug#NrfO7SGFn=鱏"þ"YmV!߲uLv ٚl[{쳽_i*<~b=FMPUZW7*\HISqdg'XzWa{S[0\9Te PEz* xKٷk_Y* BvlJuBK1}sic]BRPjT5l臚ɘ'/ۢ1O~<L偞LJFVc6"c,lon)KuQ{67_~Fe"{-{+o (X=evMkh`)5]lg8P마%uE nݺ3]X@8\dzرQݩj(A`dQ-af]g>Kn55ǭf`cMkj){LtɝJiƟ ߷w蚴k "raKVn+3g.0OOd5U+WWZl{jVkoby=:)Fk '+W=ׯ^Ydwl+>czdy$6zTxۓ_sKYv߭t jVܕZXyL^kX: *Ek((J25]F})háFYb.^Ni[lO^N$u1fw:IݮXevYky (ZlbQS5SR@(WH}CYu+ ^ N5[Q5#8K+׶4nuNMc]VA:c޼>9`tGA|t>>A>33Ο` 'ܟHGfip匷Cy6W|+Gʲ?,M:S^υ|o_< x -B2eōj| (( Gpketth.6.;#q aɱu/rº?"ض-bΓ΍AYegC_?Rp3_5=_5=_5=_5=_5=_5=_5=_5=_5=_5=_9=𯚞𯜞Ox{k槼+槼+'=m||||||||||||||||||||||||M 7>w7&Σy&<ՅcESPk9Fݕ:>ٯ]Rk1YAu(鸹~%֯}Qa_5q§XB?$aS'*MaPn=U q=Q+":Q„2E1Լ]hCW0 04pKqnn2IA+ciCO6Xʾ2C'0 70;mʹ5s wiE^Ǚs9`4v"78qSt'9$V<7 g |f~ VqnGi[TY܉_NPW;johXXOE(+D"=w×8(6mge@4iZX_4V @ꓶ1ZLB11ʳ LD8.M3M꡷"6^ʞοW&"QD.8z'2n]kns^l@mޫ*Rނ4N NtiѮZA *ad3aX՘򊝃.Y^p kJ'T:o>;)Y+e$lv!<@P8V3`P{g0hNbG 鰯 h{erE;6jb8VfMsOO>j7{<43AƖ&ۜnmK 6I`졧hǴnhT<*-AHS"%#ِ c^8ɦ}_Q>}NVbma'Z{SA4d[^/#vJ\&11ŧfI ؔfŀ"( "&Falbg*B܅Hn,љ|ZGrD r;BB;6B 3_S #´t10 a46es )=(WhDCk9z:,PNhVJb[ˋFYBaWc[0={: qeRӑ8 TXl7 c~dRPƠl=AB󗀿 /3A®mڶUaLאocY:PM10V#xnx[YՉV )o\&#|Sm=P{g ;ȄqMj.OS+PG7}8q97(G|Y aBs8F{|6 qne+L5,gLs6ŏ ջ8$n!8{8&e'=7n#f+Zg E%cmp]̸Kw, PSQ*X7g o!6'u\F*F}"{Di[̻MdGaV>yF6l^s!5i@38nK(m ~?bh (b\ÈRs߻eva= 3Ƹ5v  Xց3gmx!-_C%V~ߍ:ON8з'e,a;Z[K8׶_)1<% \" peIRtj ETm?Cc>j Z=9̫Dq:*SFL(:M1r9S2ƄS̀C7@M-LP:Iaz vx0t /X  ܰ|']S1ʵ8,}湅ԙٴvnpZEdꜶTԱ IMڬ):!?Gy:DcW^bv(p^u%Q\wŲ{ͱ׮j=ͻS7 c@-X6m>#-nV[PǏ6Vj;FHs6aםJ( :8iĎ*K*ghت$.B <5`kP0s l >zgLa諎Inj .,GU8RIF#oTSnoZu#gmqg:Vk* yip11+Z6`"Eg3v-2tP""NZ1WGy:_=G0(@ˑ8.FÔiYMKLpg}q^*i~((Y{)w.z6HQ1V.4n'%tC aT^j[Ϗ9U6(LZ%skoUNӳZuqno3?Qw|3q*m4y.`e.(m5gg뭋`$Dnf㹽z䥱mL{564PLA(ypK`aA&͡sQN]Qpb֐i-]RN{ŷKq>OPhnf{쇏4m1<-!) Ռqq4$_Xۤ1]&#ooM@;1gYTNuI8 g D$x$!woiJ',rźX{dqNDqK ʐf7 2 Vc$w I8uU1BuzN1_,V1vE C12:)9;:bۘ,Um8ߋ@$ hrF}@W 1Fj[`$gSMzpM`/+/EH1= xˏ40UN-ᶞ 0W%A.R0#nt"BH۝Hgb]zx\َ֬5Ur~Z kl9$"fvXY립mu,&3=74>6l5s:xXponOvj5ل~Qa{GUn;NGYCFdc=|@Ttg=,8Ieq\%t̅S48@2LHHVj NOR[ KW,bYcխJYbA\ ճTN|%XM?+#j 0KwfCl'FX^5֐ ז4F5CyoPNF1dV2ОtY\@0X ?3IԻVհ*AٶnONl6ĩh08b'$ >cV3&2=5 QkL1jf ;)SOFGlme qxS jՆJ׶Ck#=*~#vg vWB s-s.-a{(_ vDpqV'8A k8LOLy)Zhą}*[5;8HNC! `>];kk^n!'}|4<(;s16ܟt Wf zt=g47Wc9$uWip&H%KAE$Cu|tGcE9Vd7x|u|^y1A#0nH%9SndՖߝETn=տn7̝>v\J\Xk1#K$./e\RgF֒ӂeEFpωös!)zi p[u<."~jGEjuaq cXEG]aPsb| ocE3mwt9 EvtK1-ltV+p:kUZH{g궹c ]eba\pL̢*L;Fwr0pHKqWFR@TjdmZvzU<֬ڕPdcGo{3;\+ɡn-G(os?MXG@N8EQʼnDTU-\2( w:ս  58e-F ݶKv-).i+5JpQ8#-: r سhI iò4f*AIDl_-7G:6چ);~q;4ǕSmWxzV1qK1;&>^.ԫg^>JlN'j-686"7.;{QNnPT GȡH:L[Q!T'1M 8p|ejWh[`azLPQ^ϣ]S)kݳ"fvsZ&}@;(q$[` :Y` 8VնF7εȄ* bsY<ՁZcc{1HֺD›4\oQ !dmf6}bd= '#gӑ[S>3*$BxUS~)m<%l0A #1Ƒx|}SSX8oc|U\0էC:xĸ%5;wExdXׁIW,:+'sZ9H6 љv%^Y-/9fIqmZ# `j@]a]>˸,e> U[k@q^0 {eFl+H,T`N ^q<?yXo砻u4;hԾNoW~t2k:KqXT {/ʀ[YX);qd'kb}&McXhJ՞`(_\l"03^ܫNZ#VzVwspAGy$e\?>\S\7˗8~YJmn|5lu7c7sk7'~Z޵yfEXO.Dx'Ŵ޲xzRg, KxQyj~=czԿou(C>a5B6 3MtjBqn )q7J0neޭiXP:vq#z+K ?sA%:P YPtDdNuWsy8;o6ی|GHuxv )oX9=ཞz֘ꂾ>َPDfj_W2WS~VtF"}]5 "gvC?&3j~Ӱv}◲驫`>-htO騸RCXWɆ !6P0N=OWn\)£ 31:*#?u6skưڂ PN}BaN7U8 ;āQ!4i]]mۅUS9(ζD.l_Slj=6ԁubBټ7Gi?r5 c}6=O*u\Nz'XVuJZٲِͪrƴ,,6砓h{q\~+IJ+` I#dWJaDd+RK~6m4 $@֡r+N{ݵZ»(F۲]R\KHa[i,`K}dC#VjWPˁbϋ$;KfEi7Mø(2BfL(o+1>%e[f0UM[ v-R.m3CeӬŀQo52? jk kn'× a*tE[q-ߓj [KKAV4۹g9@$wj(0.y \iRoZZwrȫQmMU++O3+W 9fR6݁^QF,\<,\Oeaj<_Q݌zt6.Ӭ֮\ZgǴ Ok#ܸΆ@A-,t:0"\ zq=!vdq֯2jka\o W-s]T[XѾmu 4hAIpz/2FӎTՄ ~U8LI\cjmC18տڭ *ʸّMsVlbIhKxR )(ܻr RNePB`eyq50L9sYၳy?']AQ^L GL% ,@*1Fʼ%L'*y;L=_ 䗥Fl(xW)÷<;9VV`+ʟo.x"R0st.Jibl<E"^OP){EWRY#BPoi: U~?kD!.K}&0ܶk^? "{KK%U啼cqgL ?uj/aW7J.;Kq jG%5("@I7s)+AeY@|Ki_SŠB_}"ه'i_a?w󾧕<}O+y_Sw򾧕<ϩ}O;y_SW󾧝<}O;%o~ JJJLe: q%%`?xP#L Y)naO$?K9DR g~?x]KQ/M|q+GL0F?PrYcH4 A_281 5W Cxs`}g1KE+O؈rGP.K}uOQ~c??8F6u = y;ej+ }WKMUyİ9k>b%v4y] w^?sܫ-έ?rIK+|ܤ D/-7I4kԤ#Րx Kw+'b*2y0lk9цD^1*X̫VW6LFeXMȱagZօXEW)b:>[kU-DDVGܠ,tE8l-1b9 Zq ;ܣasuiuUr}g(WXN=r~ E.ud]`R)UTG;8UEp"+7\2KT]Xq»sk%t^"؆6.h? Z(b tWZjt @͸nP%IMP$fRcZ{V@D k0 [0 ݋/Ĉ6NB:WPDn3, `Q5]AjGޕi +*͞b bMk8+T+B0IuCw d9G􅂤>FG\K:cu/QD,9,D|;~Җ WQkLYXŲ<W0{E4'P+8mJZpzTg:ek\Ì$kGZzs@L^<L[ [^g70h {e*F,`eA,ȭ 1żT _5joYCȜڦi8sm@m[ רQQlT_i*Vm4u@\ 醭ؿ%B2ҖKWjKNNfDU7lsPXo̦!ح 5J>0/FG.h/y.1`{A(W2nʁdcKnDJ) QWqsUŮS0fX4w`QR5ء\t.IqA)irzsk,HZl?Q)Ԁ l4ng"$:Y}AU4b0Y!45 *w$t(iRprY YȽYq -Eӹz(Kh(ͽ(5K4fw̼siQU@ cB|nRVF )KX&Җ$xZ^xQUX4Yʵx+(~",`(lŒ)zw,PЮVJur38Z`4s԰DePmR\9,M2ɓKY'm4n dQTHc#U!R7BE16s+7!3B/^& Jq <75 PBS&V: t< ml_ VA W^ۀBUp@iAn #a1:CBqrfGa娮.pq,¼`I 6ct^[Nd$E]GJ@_\N6Y k?mBpes* ]Ne36B% CEiYFԭƺF:'9&lm-Q5arY^*®&~amBXXuc`</n91-!+0u鯶2a);ѢM:jh,Pܱ׻ zu=U+@m(l*%h!# {|;*"ΉR@/5<\BWE]RDQ5-B@2kb'')>` 8ۚҹQɖ+Y w&Cy%}].1E!գ-SSFA[ 7w]DZ.JܰEtcXW\mʱLG1[#'$SE(:l)+ɫX p+Fpd-GiC,Y !vM£UԕX\y]#Z(-<E-fV#y9a@UMOo V_ KC\q ι#sVҩHaB'.N2\Gف\kIm.3b rTSoJ mmJfSoJ^$.RcEmhW#8lԫԶCnP\% *Q@}\Ҟ#B' siLdl_@F VYZ!㠂Pkҕd )PqBvk&|^<\Qj5H,ZZA)#E }N >LbpHUld.Xg>.(J,T7(M'jc%k 8!@3- ]q,]ѕ"VSn44o㸆y)_O^E.k|\j Esτ ThShMUsp`em0TEF *}b ɰh[Nfi m8EP y4,9^CPdhwS#B`3G7!+fVY>nL +Ad[}Oh ֋U=1i.8YimDwrolԠ;)( ah^qUŽ"X:K'6j *zf3C =` ✰4RSpN0)wEҊ{9RJ&D٣bQڷ!AJ4f! r  }Ѩ5 1"gVi,#+cMyi8m' GnLfeAJs]5̸L N ]&2(P”ɶŭ  8Qڈ דrnsnVWBdYDxmQ[e9 ȷWyƙOvȞKX'21̵k,CB%uӀx I&)9b"-V-E9#'6!P@=$.ݐv FO6umvDBq9fS}M08`V8Ffs]NdP՚382VRDȁ HمtiWb`_f ;!Umy=XJ'杬%{hen*Y \  T`͘7A{ e%[Fh,qr8Jq*r2Mq$ʖ] (־DX{KXږM#!8EP1Tp6P:Sk7w*5}u &Mv|@Ħ*PK}(`\WKT5TAX4(ƅ; . .X$7vOj²pk̲jH9UdS&ʊ-E UqR_S`+ Qy|rZ5e0(.|@ O-5XRj`: fBRX8pK{jV&\O +o5S0*lSx_R 0;tH]o;ʢ@JUiŖtND6h7Ҥ!j*;b^㸠ip8[<]tCTgbH#hٷ XwbtLg lbLlE010U2@}U1#N%\+6.A+a٧@$s3:3Qrg"8G6⥥Mu`q 6͙.ka #VMP&.*>I. -Q"1 Ik tw2G:lEOA@ _%i3 Ձ\ ~Szv^UfTpĔrbUpkT#"`p.":Ou:Y \631|#.+Ѭk6b(~-C]讐znYf6!K@UY#0;am@֝d:1Z)ePc}n$ k4xͦԹ[f%#th wq b6t ɔe"ݭX,,ޥG(խ2D%h#U@B!xkH%"hWNu;C@Qb i,@ @bcEb, w* :" `Wb-ZTT] N9ףB V9Vqgn+ lBs F9l5.uEx\Q1e\pFmV[CP#rHXՓQP>RJ%PP7,J~yY"kAk "2v|PZqQ fZ̺(ɮS@x"])<9^ݣa}P(0Nl~B" 99k%Ud{HQ%JMMCi/ x7kDa*mգfQÞDde QϘ!ʔ)P%Ή,%Wmk[RY)cP5_&yO0$d`%4(DcQsP^.X1ZB,a3ER7PR #-qgح!A`]e%:7=KغU8pi08+ q"+t*6ه5 ixF>)f ٔZj1eehbRۙA L ZRQcX f5Ia^F,kWj0l:c4qfVÀoE< w78"DzPڏJ[wF_# q!4WOL¤댌4Em*rjL0 Mc L69ZO_z*\c# _1if~t(VdIzBN#woh4MU Հ%Tjz%"V;: D~:9ÜEeޢyWt|*&ur{ۼi%m,Pk> 1Mճҳ|.!L6mOqY44D Et@xfPE?1^`Uʐ>kN^mɰ\ CjfU CCOAd1nfPJ Q<` i[p"* LR@s 8aVp t;ö }&3#(Ld`, 7&t @1~<0A{ o`IlKT3Lb`"IY wi! B;MFܚ @9YݣyI5tвRЧ 4h@88), Ce (>Z  U ߁Qg.l@\Sᶈ. /~'*iJ ?FDSq8 38:Pa2KXj;`bxACaIA@˝^t'j dx1AuUG^=e`P  hS`1B/xJ6]e 3 = Բ 2|3STC?0)dџBI#M"!&ia AU Z&YP"$Q63b>syϹ qn:Ou6RݿYp)x D<S xI(_<`Z8.?AfD+lX#M;UNdMt ð*Hvw_?9W|+KH Ms$~rMGB):r;H.[+wker*mJ ("ߘKPoZ2 ֹcǝGS['޺XSs:95rHM4WFKnO"eK>OGW'/UarUcaX>arW դnrq }gq{3dLtL0 7t)\ec*㺮sDc*3kڃ@78oo*w0>dF[e%fs:-0 w$S +t6N,+eǶ@lF WZ@VJ;?K %vZZ7;z딋d0+?k/լG+?%ީGtk G?Hrcb=+ E9վ B)cA=9!1O}>*gӠX~,cV8!Y*A.yJ:#da$!+ݓOAQք3ru$@`³ѹ4!n+y>.eCjgzsXQgCHVeBrQ(z-b0t,!Uŕ#:Dˤ:Ht Cjb `$hNJ=ρpc|!` ?S4a,)GVtW~k,;3XROv5 -T#k2OEXLa@=-S$d"x:%3u:&$\.M'tsd`#Ϯ۲.ÞvJbn=.^rqմKsJǶJN. ab=Euam^KJϝ-~`t1ΝfdC648*K|z b5:5ɸbdG 3D6&Gl\1ZdRV(tdDGway')d@(c={X[='U!@1}AMg!WZ/Fl4_i5>߯g񬋑Cal\;#(~SC۶XQ .Yqi "@H >t|-תFy: LsN%+١trQRPٳM xv7W=r{ɴF.fbH[² 99ȥr:[yїrtWL'zv!hÑq@7_4r &͗ o[xBzPg"^wѷc+YcH+F*48DPWI0ݤx02`()bQ?g' $%+MēlUOC0@ _pveC.KZlQ=!QJ5CVฤ倖鏾A$s;n2=90R*#[׏7?Y ~Ja8* +ƂlH(w~A.:hSz  QՕXPMi L5p$}ʚ `X1U.  A%$(@E @ĄQ%{Dd&7Ǝā!{߳ w]58? Ԁk.bPٲMZnfB"|o>䘂pV%L律a ~ĭuz rs,^bލQGB>ٌ :wCIS;!U(L#ufj*&(+Ȭ(A%ʑ8zWnAe)Cΐ`9:śBD{*(i~:8<`{T+O,S0F p 8f<_ڄ6o,ɳnLfuڸ'X{ od6Hͭ%|)=87""ѩAjuj(t1ҪFR =Pwjy ~;zťmt/2hFpfo-/nڰx6 ,d2KWf@s.o|3kڅdu`+UHT6j6mKV UW[p6f9zKaRf~ >YTB?A8UmHFz=լZ]lh!P4O}wsdong65.m jQ孭 9%Ff%\;k=uJo|PYM iLrUjМpVs;L/$<yYAbuM.nZ pG M֗WH^03p/MD~/e^}|*"{|呟 jŸXL^ae1oRn{eFV0g9IYJ[n|^`:"АF}/s'߽k1ysfAB8"ɇ1O&bFt?GZ[r/\mw|ߣ} V9:_Yjry[!⃕I$qah/茅 pt]ghtUsB@%)tF kH8*/.(p(C {[vi ;.l WZТ?9D22&=lp~Lvº,rnK.g{0z:/ܒce3m-WwabIs΋/󴾱Bi`w~԰"  Ͽl ޟnRI dyp.@oIqOC'uaqGX µTpx*-#Eъ,jr+f J-zHYvdL[H~C*J,pefB&K OZAH؁w+N /i9Ѩ sN s::f4:``9olbI Dhӂ]8¢^=cgi=4JF-N BFl!`sYC32ƀd_R5$. 8`r6o]3 [+r9]o+^ef`Z/]Ǯ!׮Ϙ2޳Ē85 qO:UjX\k!k:8mjw/%WN댇Ş# 9Qs))nb9$5K8LtJShJ3q#RW)r9Ѝ?߉ uQE,WE2jD$IK> _F$Ut" Ƨ>eHKF8c\cÈ6&9u@5>`sND`4uQ2F4(zDGME,3kj=Lt-KJĴfontas.Ol]KB_ (-.%Ύ SFףZ!%a B[ `C!3KĒUͧMVM̙DlYցeZiTgfαټuj 3=թfc[uX-ؒĒ8r{q+J+E%XbCl {F-b{'C☈br ~RI`A&:8|&8ϒ0 Nq{~-I`=zp~G q%I}IU7|:ŧ"IuEMwR<~ uǽlG.)/E)yP yE n{] V`sĒ8NjvU'u׫ZNt̋X\jYP1W8G0VCj.*9y+|T[EQXĒ8!!4wg6LY zi6\ D6D>; dh -Sw@c @pZB$v?yT%ixPJ:us.'w.Wf78Üoёexte{m~J\[30WL W֪wqtF!3]L,žԎ-{a(,)(* >QzX4Obې| (R1 0 U=Oa,9EiT;E9$hCU|PSG80nHD6=j<<.N*i1h$p 핏K=8ahة@ǻG0*㱙I$~\elV0nI#~Y80) 8o|"]`%OZ]*^ҷj7Z}`}7&AgŋNC3[> ]fƯi+v>oʚmc&-薓pT?mV:eRI\bG @k KX3E, vf%8J;fE*w8L pp 5!i[ߛXP>h.7lds@Fz*e\(8tՎe ?_Qt8trpVvgΪcVL7y!xZ <+^2Ǎ_劭&"Y7h !G/-!Vh5[l敀'y,?1nq66ݟLRݨ{o6fZR:p.I|B#e _ƬOp*p9aw BAO/`ap| >7( |G&Y|7Uj+.Ombz'pYa: TD؃{ʋFM3< s*L얛ŇV2[c3.Λ2 j =fJp߭{r z82\{y1Y9 Tx^IL GvBFf>ۛ.GKIYAHl kf>m)H;WߺkSqۙY;±vLF&;x/<$"qg^rNSGuX!:/4yAHy7B/xwǯ~~Jo1b!-5_:Q-iT%gOgbg"uyݐbJޱ[X2(&VG fýoE"9'[Œ#Ad"|`\oRbɅؒ+Gq_wnr]s4wZ],"znL[;c۲ͮ[7Y9u?je 9,rv|փoly%g,e钶p"HKi û}uG`´u"z t.uHPJSbfa,h M5m!d{ ODz2QϜ}`lV$^`!s+#}ޫCobcTtc/0+QEZX*vP4UXXў"ɦ/m_i%[{-\vUmˮ+;PgjdkiI^vcI ~!R&br9uyw\;#oȑXAk݈]yŽ%'$_Z/?Y_H˕ֺ\^kK6`>K)bb> G"rRgiH7fƋ<ϝ)$w Ά&\2AKL.MHB E4E)NoL(N!s|&<l|0xÐ'HAؿ9&9#Zd'vZY^0~% e }_IU%e!<Rl Eb++ F=gIZ~Z^#%#ɤOLbrm!d̈r& pClGlЄB~w*J4eP8MCˆfUA74XgLקwтF[u*GOel÷7ZhZFѦq[> ]ƴB7 BSWhs B2:-3adEReʔ^}0 <R7L-5D"4D-f68]qV07MW10cB7p˖eTd2c0i\׳tPmy&ޒݛM R./1I+dinn:~cqY͕uK׉rOXYZDmU=Aoo bz1n[*0!I(1I Z^C+qu_ϋ Oa~m og6%^"rd fϦY:z/ȥRD5>mď'8o%7'>}qb Ǯd w5(r IuJ{ۥXςSX-fԥX$mDjI#S3uxF#]\%k}~0QgM RK|&RWF Cm\T7 cD5/UX`S8b׆kj^DxcrAp3B37_Ǿ\G;Έ53rBlz=s.3mn4% y/MX֐]rqسB(TH9_~:ìL(,5֤̺bTT?O KWL:/$^hb9DanfGb6#LJtuWʛnz&gA3cMjlZX֡9ݪ^Z3pOM &pE,O돪 t<:c^tde_cdZ'e:ySvR{S={_kC}xa4N}%}Qk~\U<υbXoQ0OCT>EdIJXkEBǕ8 ,0Qԇ'&~\? >f4EvLUz}}8:5= Com̕I|xB?ǍRF dzǝdI~:8FGJP Hߕ#ibMʝ|(Q$T եx(I_ÍS 򷒴H^dI$q3_{E#yZ~m+.Zhәv,:Fye cEK,wh] CȪv۠I^xVjWպYin 0$B@@U=1ƌvfBY|H/P@y Rsvp~DE֯ l z H($$. $6H!@4b /BUUtopz_Q\|yUsug/:X/38Vڲx$bqZ9`yC˺q(ZT%ŐrI!X"ҸXw7R1$IWxjRQ`{KzFL`(E\r` VY>F߈a U=!?o+qۆƹ~x-{HݶtUܯx*|=Ei+ߎJCpۊQPq۔IqIYS@xO sGժy3T?~V:K+^u X{lJ*i:Vf]֘XU͛8o3,myz|$NO_|-mf;i+%"= ߃ #S%bV(lF ~KEd"o ϽN zHx+!dm2 ;:O@#$$JzPz+3MP ?(tM`:NNcAȝq` hx㛞4^:4Zcl4tF]]VŽՈ/6w`u.i4*Za؃Q?.Oץ"E|oFuے(I` Z?YHF䛸^14Ut+JO b z^ۮT#Ì%1[ca'&'Hp&8Ƙ=0˄} ."+l3ԁVS%QjzhO<z&Wt},mUU쉍Fc-ȫH5W =b#;dTFW}_ |`4?kqb҉_:$6䃢wꙒDU}nH\{8W'}4Cr^kpixexdΘf|֖0MׅnOf qDywC2u3]~kyt~Wv8~嵾ΠwZ+4y?5jf3k'}ګP`kliBKW&cd4CdI82kSO)ɾVҵwUJRPaBD1,:ǘ3E5^@sp awr7:s"ǿ)͙bᇱ1CAT[jTA4.^?LKs7SsI ⺪]ͮȱ c_t_Zzܔ岼L#3/-?xh^v(VYwAʹҒ˿2;-"//+?y-"?f^omܸƴ: `Bi:ZB>evڗ7KW4?1"P}JyƐ@P]fg>DoA5MOMzs茳Cftr. M<(Mo_2s |_ECצ!f w_U0>{!Dw*Be ~$LgMb\,⪶ZY+llV[9Eywk7Xu/&\3Ǔub+?}wZqzLʭXRrV/?2&>2䊯Ox=?A߄v"ѧˋ_̋@-#RѯBQ5\C-)C~tV٘QUTMU)*LQ"ĥk6ȉ4Od|`|թ@`\N0?$r$d9 t o ؒ$#YE$cL}y%|C-"òŒEb`%O-X΂ulwեX+&qZnձm3ρh*cX.SoHFfSF4m/y]P $ٰıV`!{I\}fV(uA(١&لcW`w37DĴ ̟P0+t^a=ؒ$ah̒PA\Jq[0g|R(ټ#*$zf",kR+.%f`,Iy32$ΎGE|T1h;O(D{HCd( Gx^Ll]RH.-Hp(Rf%^)"g-@h?+ [ԓ5*82ȥKկA*.DPadL*Irqr9FǫP:Ze*젚A6싑Tslg\g1 :.Іy8Qguxr^*IQ ~ RѦ`B6<;ׄRiHdv`&f^(e2]/%Ic3@fBMA$ނ3$δh{Xki0=J/Q'[9-jιGUYV7L7oU60rVOYQl'gZ[*T9i:$q>kmE6z⃂_o_5L0m>_|s b/)^p[%}4o^0uIa1O~}}3X҇epxؚQ1AQɂ?e{ș+ Qq 'R㣍xpprIG8kT* \i(F-qb(P.㔺A!q ťTjO,H[NoՋϩV_s8W -(x{P9<4s?yT3F#DsՉ%q¯&&{Jo'^/- r_;B4QΔv'PFy+#hP%3M> ¢MQ"Y@kĒw\E+^Ђwdoua5+% h:w0: BȋV,7MF^gZEq(L\`bIŠ,.#O@JA-"/2m{XpH+؇E0Y'Pkn"=u`#;Gh?;5ޣaI$="#R@2ݟ`Μ(L}RfO$+x(mڕ%+<6Tj$boNU^Z@ĒgͼiBvl)¼Vr3fz;oêlekRudM7-碿 Rѐi~6}DU3~y:$. mH&vL׳X䄄(_ R(GM\Q:O,SFlOv+(͞NL,‘kli%hrB8iMXafTBz4G. A uFNilαv;x_>sV6wʼn%qD"1|b!2p 8#'Ջd( 1zY ؏I"ڧ^TZ?# tFR}ٟX#&jg\<~ G(.Na:?'Sc ⧒&ӡ~b쩒T:U~IU"n`X"JpZ6z ?Ru\ʏ?!'{D2u)"zM*3ݭ-sRhi-+|yU&72\4drκYnYϦ ݗ\y;2)Ē8{BiB=֎RHl+Jg[Ѯf%dJktZ`ZFc׀$Mc>vٶ0$e!z1VR0:cs~izjE Jt.0 ==y^łbICwV5jOK[{c֊gb.ʭ;ۊ,'#%pnj_rhe9ҏeWWH.R,"K2~DKȠV8v((S0_~Q)Btq mA숿)Z0}bI?Ӝ}k8UG|T+K1[K ")!lٚzH1BDo"oy~bIv-"ϸn-r kݖHy܊$_*˭%jtz[vZ Qٙ\h-X}q,.rr=̑\,/N,b/@]fvYu06GvnOTwӴv%+x641Ja藿,ЬJJ!4 ,l^VP%QQ=5! T'*#Bl$FgPZ/1 4^N,s $lv;.G+PvqK[2=(.宬'wn䬹K(Ւ,t wv3eƋ5y9}ke%W&ĩq>,/+6xTaTWGwi m)o'VcM bqNSPp&3!Az 35@Xs.8#[+)B 6~Z.g0tD?? 0`_[k'(",ΟXXK%خjTZO. #Z&P؋/b+2-.E\Z-^Kg *0b>=eVӑd2Y2~dbImp.clzCj0*8*\2 MXCv:FϢT977FЮM,-h>g3}2oK:=\jJOCj;BδkBB28.vtM mn!p(d3$76lje]Ӵ˖O ˯4g\Twٴ5Gg΃i:<Ȧ͛GW$3Mr~bI\8Խy2qzT7|P~Ƴʟa7$ex #xO{_{]*UaKz g|q?M/=I_ q ~9#c(g=SQH馨p񱸑-J@G8?>CҒ$ŋ=hnq(@# J֖Sq>KjQ n_'4j 321W(MfX`_F݋IENDB`Pylons-1.0.1/pylons/docs/en/_static/doctraceback.gif0000664000076500000240000007446011645401275022306 0ustar benstaff00000000000000GIF89aP  ,5"4, %'/!.-0 K n*J-v/Q(i15H.5j>y'4MgNZ/I(M5.xu'k;t(/d(UeH1IIICETGSYWGDULVVRIZZZMSl\e^PbuoTJoMjucVhhhefwkskguywhf|fy|ugsss0)N2ck,FYJHSqPtwNsNkyjq^rKVioy '$$$%74!46&%%55$461 81Km2L2l:I?mPH2n c3GM4d9JQPnkSkoRLUohSnre:u[.PGkrQ\uuot\uYrFxđ-ӇWΎrѦJץxYpwxρ㏯΋貕͵⵴ѹ˙ۘرɘ̘ԭùIJ¾Ӳ⟊緑溯°ͶȜɳ͗в!,PX*LpÆJHqŊ/jqǎ ? Irɒ(OLr˖0_ʌIsI ? JѣH*]ʴӧPJJիXjʵׯ`Ê땞;{.hׯ۷pʝKݻx˷߿ LÈ+^̸lj ];="^\y ^q86|9.?{M۸sͻoǒI;v - c1 n>[17IƷH}w}ɝ0&ȱaODpH[~,Y?xw'I' ߄Vhb(%eĖ]x 6@,s'%N. <:BpJ,֖< BD>IL' ' E2$?l:#1'q-/h;ڳL6Ie7q !4>lD 0[9:h" 88u#1gt>{Is >'Yfh뭸rI ıu܈u B C -QZ=G&13G_0~Ls|hH0"Vdo&oO?~cI?Р%<߀.8bP#xxwI0+ +t AD?;+m#("-(bL D0)M<7 N+H#M0-ɜ- R ; s|Đ % 0q9'lz- 7t"V8ti/E71NxBІ&)Aw9cmxA6~,&R"+]!XNj a 0Rn~l၂<`\n6aĀqYJi4r:D\8@Xxpp;FX;p qp'*t\xCa {pG/5 6/%"g>㸀ێHQb]q# G Q (<1 H"I?@G(#TJh@F֥|x#G3QR#-v ^o.bZG  bg#ː8HQv?رIHG6qa/!b9 D!4l p"pZ9 8pkD&!Z9FuQ p, q1ސ9h=ċ4 #@w[Aear v3.pMݒ_Fa\].T>. =wa;ؐop0.;p h 0UۂˠUpl.QD 6b]@ s 3؎t!2uAvX p@P U,MmPp  %kn fd 50 F 69 (w0gpqxP1G"x1 ]L !@_0/ ݱ p ?ۣ3 D @U;:(r9tun[wu 2P/-P7Lp . 6cr!1: 0#p14GMut)~86S~%/6 /qyy}!P ? qZJw : p",-+p-GĐB;HФpQj2 2t < 6n:6/c .K=;` J!@ 9P (@9 *k @ *`wE4_T JP.,'r- >K $)j 3cd5 5;4BU҉t蜀%# 0; H: ?~ @N.2 U# " H[. n@s ~dqtv +@y~~qx)3P{;ȼ9`#^ p@dNە ) `1 )R~TM bʍ c 7na@#޳` M̛Co]LPpn!cp ǯ=E:^~b x pWupL,AD%|4bq-_!&u8Ʀ~=J! ~4WEAFaDzMB/\ &N# !8QD"VG1 PtK<6E5V`9䨴lFI9MLҤW &h,GG#B fXOƫ?9QO=cd=ET-em8#ӨO>}tխ_Ǟ]vݽsogGA;(mK(M(\\:HC ۈxH x𣎗Z`x1]Xpjl>bilꇖ\M.J̖J: (,),H{oxEBL'xds$yFr&*D)AbQ:P z6!ZǖS";HʜjgJ)LchrGP~!ÍG`P~I#g'bEW1&mlao$s6eUlhɡ k|xT`0~bEA$$! ~"Q s=tMX!TCA'{a¶[V@6=Q`ṳXb~qC -HDcly×9ZO8䒚'.gwg+ |ͱ=zEJ~GGwlk{jJPP#}B;dK6q{H  dp;GjflJ&0;ٺ˧uXƂ7#;g~ !Af O~ӟ|)K3;@BP6ԡhD%:QVԢhF5QvԣiHE:RԤ'EiJU T<ܣ1P7iNuSԧ?jP:TըGEjRT6թOjT:UVժWŪPI th0dҰlgEkZպV &*)ꐕwk^ Lt @#(Xs9SuElbKI1=ha;YVֲH_LbM!Y/;ZҖִi,\sTԱı l(%cO/)׸YfjΪ "fSDs"L9+Z׽m+W+"'=HX dj+Îx`^!c$g;a #Wpjs Mx=vXW/ *1 Y8hGzRh @`?H7hܸ#lhBJ#é+x' X@t@2@ wz;dcC ,+x ;!X&"C "f2Q|ȋR!<7RoG8KTFa<[!,]W#0R>5r<Ӌ4 ч=ጧ!JE@RyJr,&ocȺr˵4B,!D' ! ;R8 ic!# m< k!'hmb!ҩ(<[?쉱IK.Ô·)B$\A<R`; .$Hpn ww%a d{6RޙE1%PoD@+z:5Z"S?1-9J @??9:>t8zTA*=[? @$K7#DBA-$(& 4B)- %̙A1$^B&hB"$|@6r<a@>;Ɉ18C=~X@@ DЃ7^@A{-D 6C8 1J9D9FDȃN܎rsCK8`cښ{H?D]_lLHFE=LSaiZ!/,,+'-P5EAAyr,'0G8-hw~~yxÇG0X@MЎ| ~!8GPziV^b87o!M18(Eȇ0@IH,5\rzЂ@ D ԛ86`z)0̑T H,5؆zŒ]86}DXeȄ}pLKxp$3B+45,<Fh󆣴b 20PJ?@8ӇZIC5Xΐ8^ 0C7pp.Mh]Q/1p{8-8Nb8N@zhPzp=)F_Z;r5x=^mE8N5`JNfO$`/@} 4 +:"R6Pi(4;,8(P@/HO} (PcM)``B8P6^908TPo-c~= ,/rp0M4w ,P,_pFX];bhҤ0p?eI*Iyp1G+CQJ~HL3U4PC0lP+~ =.bdP>9g?Zݎ]e@*9lO`XU/Hb/OE@px(hc`dz;h-Ѓ^ i(̤"iV*X9X{OjLhTWه}4|Wu@8ͭB.@XPZLwExLXl]0rfh)X03tHNaTP:A(P~M;HrU>0xr(MT:RJCz@PGvJ8p:<bMљsp>ZNx؇z6l5hk7h5`%2oӇ<3XN;6oM 8`8Є1N9*5`Zo ]=j}V9ݎȃ`P9+Ɖ7es6؄8{bHP1[b9xG9`sZkfT;ń= ^xE|20(l$7В0غ*J)k0P]!M&t'̑P+0D`aJ7ȆAEP| ?r0b~l(Dl)؆]0վt`1/0HȇCa]|\8boxw|X[~νr{UDs ܅:^GZ .|μcg44HaRKDɼԎ .zM`k'v.݇D2~R\ro(]~@PFf@k0*7~XpȂ%_T%%O4~cSO@m(/Fކ} Asaf+-pTTҴ?Ax*843@Qb+C)(9(Yrp)DLx8^x5@<0DSNph8PeQ*q09քqQ3d,PnCքf@(=-ЁĎ.`ViO8,HNKj8hxj)r+ㅒ2Ƣ307.;4m餂Ql`,p~؅;3-{@)P)尾5u|ގFEc5 0.4XlظVh'HA&'h+,^N6T+hRy=ʎhRh¿H5]2AzL}yx_pr ].oppXyn(vyqyt38ozxo{+yp|@^`j],phpL4HUwqyqrcA'D qh!{8)wsqʡ /y8$-}s*ryl(*Av'9zȆ~8Bޙxoz?uw X27s[4M5L0Lx=88Q΄8Xvh7vF]Mi78LP/no7=,^=0s'!b?d_o0evr[$&q_xGwu3w?vx8({)lT~0iGdIRKvd)p}w|yc2owcgƊ׋a@G=/9rZzZ(v?ZȄMz?L PRU]7qyg{??z腵L{Z{?PPz/{{?{e 쨇ŧ=|`4|ͯ Io|N/=p̟{}w̷Gt'{w|F+nPGҡ~!o~xt~׋$!KVJ2^'~~,h „ 2l!Ĉ'Rh"ƌ7r3#QC7FҬi&Μ:w'РB9 c.xtej*֬Zr+؆ v,Ө1 -ܸrҭkaQ8+iKިz0Ċ3n wH(U>}I`L68Q$ ptC^`c,FEo PaFwK|㆑kF179$ \٠6!B]CP0qd&?=S{9q!&Fϥ~O/{vC0>LP=*"l!n1BSb P-9lC "Yxҏ"d'qNHȚ"YF6E `"_D2ԮC9{obLSk&=f&72(y3(,O=phʅ .0K{ cKNkۉð S:Y_]>%aAUށm&ݠqG0ZHٜ"`'j\A2R#]Fd2WFA_t`C@:su!ZaC0Њ~"7MTPý 3 !T&eCp`L!U#`A&vA b4h@Pxzp%2\AG9Na !!`5xOUzx{p!iP1 )$R< }30'Aʛ)AKKԒLoP!8! ecjF#/ppƕ$:"L1duހ Ex0 0 7DF/.UbEѢG,c a3  2qR|wh`?Zd ҢrkA vAFE]پcp(DNdz!soc]Qu";PpT˸ns6sC? )0b F4,<-D!zQVX(XFpҨY Id/]f"xఇ Y2+\Az8ǐ0i0" QB7!r!Sg0A61e5BȚ$b .fdj[52Ð0V#qQ>4 t QB,+LA l?nLs P9ΫEYϭPẃ ?9M !3F(d!DTI-ྊH5ؑWә65("!D4 ۶_xsސ C|GpYO":~x#p#ñ#JoX&GؖDJؑKAM&(B&J̸ ACDfD`F`&,@F -`J!xB fXA17d҂ fB&)DUDh`兠fCC !-B`ÕHUnS -l_Ax~ Dq?fBH`J9 A|``@1 JF J.@!)z!BR^тɝ8_xTU5 "BN`c&1fB<6D=9śFH6nD,1:#6b{y:fB72cLC&:2#9/ G;1A6##4bE8?^ 7 !pT6 aQ$!FQ YaDqSJN΋(%BS&MG FUZ%rVVȘPieG^\O#W:__%`]FHVO &c6c>&dFfbY<]bԇdn&gvg~&`Fd&jj&k]]zI^ff0m&nnΑR%&o.nq'r2kepU9bGpR>9 u2D/hM.1 >N/dL -\!CaB, / փ"lεCbBdeA%-(C!UD9PgCLg.ڕI*:7l€J&(@2$hr^&O:iG~tD>0B=ģ@6DP>WC A4.. I#D41Dn%A,ɅZMD)z!@Ta("h-e2-XBCR-DB䃗׈A6 1A~(D,gFE/M~~J/hՈsC'L(A >@&C4).`MJ =C;o<ц9C|6 BCC\R.lF>< L1Q6`.PKfy@Anxe0D`%ƯALCF ]-. _"$!t-T>šUT/\9+7!n-m*eEsGTULB!܁(; ඊ(k?T%1D/PACN H1o975C8 "?[@ 317l lG9 5h ȁt&&*>4CqI7h'(ECF9|B-#dB3HEӯB m<,9<$|2:qQDA xơ2#AC0x"A+y1HAA0 @!B7O1}h(OE#Htt3C]$X ; 'M4]$<(5fB=CJ—&XTByB1P=15%JC!d $B(|I#xVlaC 5D<9l)T5kii!D8*&A(Ts6gB0H4A%*dPR0,Cd̨EMB>42x-TCݮ˼C7?L(pB Ã<6|;q1` 3B @kT6A |XYF{BsB5-y`Î?)ŭC,’AM*(!ѤtPX\<HXi@ٙÏ]X)<PğC@P99H`I=N!|A&|Iɹ,@ǙN6PeAeAHAɩ(]s\.j | ^ԀVW2X->AdA⩧z/Y6+#xAI?8o" =8C9o/Ђ1B470BW=*3g/Cџ>ݿ;.8?C .t -_99,CA/-X>->,/9|8BJ.,҅k!Һ4@-|ͤ)l|<8=<.D=s|:фɯtB<3TCpC(y=ͩC <^D8sN8#}-͛a@]~3A(/e+h-?s\"~A0,@¥V~&T؏X/.p_?~j .bGedD^L8TG! =Ȗ$f^ءuTNbB7g& !mɅG*iN: ޽X`/ɜ1q,9}GaNfJ_rY!&rLAHܴ4&P.q"6(*;a#Kt%!^bk[@rNx驯/b$JkXBhb"ypۅ ܃NOnc[Z*^!hPchnJBg xd |Lz3 Q'EkJ,K̰e !WV.T;CЀ lAJA3%/Hp(,nu`e F0_@q Bm55%tgVIL!Id|`2+%K@;D%\cGPD5 h!FDsoL" z]g@/tEPHq HpBx'jNYN=p?*7Vi{vEzdˆ/l_@}>DDPX4hF%P'f 5@<1adA Q@ZA!J W9Xa #7@VGB!6&l[h"לcTG+yIpj A&nRkJʡdDZj@\+`h "s !Gqb+4yp 4&KVår6`#8!DPa25&B4XA3VYD  ޠB! N"!b% b%A "4 .b a @!! 0@ z@ M֠./z! 8-ġ#  @ q Z p8@3x @ B`n  kaV#@ $0vA a vx tapܠaӈP@ BA @ Vi A9a #DlǸ^L : ́ ZACAbo՞AlaA2a 44Jиo!!( `@  a no!x&D 2aƆl 1@_\`f, ݬ  @ A l! [ M+Q ` 0ͨ@n~@!' @ peAv 8pa p!ti rA  @%vkK{1aRpEztA̼!@NWD WA h!P!ob R2AXmln]liA Mt@!ʡ@,\c?"fH >& !@ σ b܀ W܀u'yL}/z @l5 rB t&)aASA>mf `ƈ@4! 6!p  -rx%z3`II-"/ yA% u@#c/ -%v!!B] &x! D0ΰ a!u1 ` rhVRQ+[*͐/` U ؎͐9=ӌQ @lKv&y1 C]Օ;Y Σ=!~6p"X[O"YȲvd" h8EQ!%:H#:2a< ='"ޮ;"):cd" /&bZQ@;'ڣ$:†:=&:$C;;⩈$ƣ+:LZ>FT+JԑNԴt 8qMN@  ?:aU ;`2P!pa-$˭΍INADUWqJQ{u:tx?tKPP +lzuD@T븝i |;zDEj{[OϪٻ}EI+ݻ;K{۞<<| <|!<%|)-1<5|9=A<:j x+]a~!>%~)-1>5~9=A>E~IMQ ^[#(!8isDI.+b~m灞DpjIBz^~~>! zCƢw#^~W$adkCK9A>>$U~;B;"#{> #־_A!?a?Q 幾Ba:!iG_]kj_x@????ɿ?_ao?Zr#A^?,`?h9LĈ'ZHÍ;z2ȑ$K<2ʕ,[| 3̙4kڼ3v\x$:{#i^L:} 5T(qT:5֭LAQرd˚=6ڵl۶m'PD +޽Pyp70ԤO96Ō;~ 9rc.n=6߂# ȏKݘ)|&];ݼ{A3E]fp@,y`Q!YE][spb ?>U<=' #r CakN #S_6ވc:qtc^),(ʀK,3$4-H`Ce9THvb;NJi^eQ!7ȃ>dX0 r  0: lM9$<?#OS3Jio4 qYS*09'hÅ401$E3 ,L ů$g]L-0O='LA ;DJ9C,?"לs$NuZo|s S4+HCe#O!ʜ@FݼB 3(hwNYx)(s0f0s,l&ڽWs {[$RCvp͛O@'7 4GlJK{Ϊɋ߾_.CBO DB{4 By4Ne}O 0!VM0p,zA+$E da<@(] ,Y30 \ @tdc, F[R\$*qLL n69K JT#'q@ հ\p'E6 Q/z]G!Ol" *'A6O`V;Є4 @x՚P2^OQ5@aR cJ :A5=@"0 x8 P5ށ0dD)6L :ecw:!? ``;PmCǕG';lcg444:ʜƧ\g|@ib'fZeZw' 5  @g` zZ>F s@c@s@nP sp  0_` - T@` _ m$TpPn@u`d`~kxD ?pN B'kȆm(_^0T#)(p z8>]IT @ E p0Z@P"Um ``d i@Y@@R0j `A dd uvR_ Yk` x i #0 I@ CL P > ["6yb)?q' f0`)p f!]a ` Ȱ @ Ƞܐ p@| @ `݀ `C ҀD5dy p  Ae` 0 ? AYpH qZ:Z5^}Ɣ%^ܘ[5  $~ QAOR *kyj9qP ` 2{s ppK {0' ˠ iJ pP } y ݚ  ` PP Π op @ ~p!{ P@ 1I ۰;DPr#qƲ+0 6 0oQ$]^0 PT`wCqwۧ` ov\dP0OwpĀs~ @{0}Zhd@"bSSG T 0P\Y0 VR`0lW\P 0j` d0vxV6:˳k?[J$q%:$#<th@Hn k3 0hp0l 9K@a j`@0 uPg0 %1qup P#` ` qӐb P" }{PpFְqr| 0 s P~ ȫM !HFiPFcSFo཈q[H "0}Kpj;wP[ n pw"b K 0k X p!y, `Pb~0  %+~ö$LJ+&q<< $bp qЋgp[P3P` m΂ k&&`1 SƘ P~ g {#,kϥPmp``t"phn@pY@[0ЙpxsPq l) & ź@ ~pǴ!o 0qp qnPԶ g}pmMn *{ qpFzĚ j  P n֚`G 9¬z$""aL )rA"Pp̺o  ax  ߳Ľqb[- 1[N-Rt A@X.~í)O] N%>Jn)c+/;}0N5^#"ޫ6;~㳹r3A.CnG2K䏁JQ.fSnWE[1]aD̫P.gJmZq_.uOny~U}p.t.腾xnn| uuY)`Nb"`{b} =Y @E V@ p .YJ̠J`$ ٞ8 0J"` J0 =@ΐ +`ސ̀ːN[&0/A P! `sp wpPZ>+.خM'ݮ3G8 =@eP`PPP@c >k6  0 J&P"P 3P@ n` ξw_9c>,Y#= !҈8 >˰P >'q0 T$`F`lPPC0:p ? +֐w /P .p \ )鯔$qȠ@ @@5A` = c* -dp؟?-L4 _?*P2(#ɾ~ˌ !(%Ưx m8Ő_(V P àP WaŎ%[Yiծe[qΥ[nv\x$:{_+ w T3>0Eor\13_eIsTPFx]Й*01q! ILPWB }9d"1 @;C&(\"  2׫~5{ϧ_}m`o߿3J/x8B %!LF>4%qŞ~)đB YG)|YEY #H~d"d$ C#Ȇo$%#EMHTg SoL24L4TsMrᆾc}Gω+~|'@}j()'&pDK4:-S[;4;CuTRK5T?L,cǞXeuYeEu(os-u|v5XdUv2^ vЩZj[mEYpw\r5Y u]xw^zrNQ z_MUY]WځVxavgt·+b3&?lWcCyd79-ye[v՝`9[_gZ(bȆ!rvpb'BpH+[V@"j)$J *hc$zpDaj*"HF,}rĴ~n |"d'Uɇ^!P72}ndhI|@aelkgK6xO7eŭ'`sv$g$ ),bAchJ&x艜ch%APA&98g:ސT  T\< LL$9@ 0r0!,wBV,fVu0!pG!4 `LQ \?+4 }lʐF>e0)  9f #x9)D@ E1 qrQXsҋxJ!/$俆v0k$` A Dл >YF,Րz Ͱ) ,D!9$4C {, Jy% xcEX#^ :#$QS,D<2@@*{H CʁBS 57rc N |E96H2 (MO 2`|B= Dg8A&Bx,, e%\,xEw+ B?ц( : #[d 8zq)O_tJ$!9 jP|<$A&Õ @5(**.*1rNi.=P`JD vPKl0\`X4+1 n@*RM{]hs"UiP`3KdGA+{Q?ܢV]!g`z.j]Z񀹴} =|VQn}I]LV#/6y8H}]WhzRU&_WR-"_8Tm |` o`E̋p-|ap!Lࢅ qM|bX+fq]lpX1Llc;[1tz r|d$'YKfrl!I~" aAGC!\+c&sY&2Sfsݜdal[-La$p+Ld`ya :آ[.0h"(s- ,C~s= =00Е1!ft x\ ]ZNrt?\C?ёv3; ѷ~{9r^8 ߐP`|xG^|z`|=x𣗯қB?Yz؟ }m}L_q}mB_/T˜~___}'gV~__ @@,@<@L@\@l\0 @0 @ @ @@ AA,AOӣ ]ݑ"ň SM?83E,%?51g[ gCw ϯj~て xvץiC evNg_PraySQoKM-GףյVZZ/%E͵- P,mӜdj.rtUn>pݵ][R#@@@@@@' ֿucN cά%sQm݂&1ؠχOupw_dCӿ>} gR[} -pM+~!I4Cޘ9@vDGeoKzh, 4Tue݃4 IT\b˜_(#VP(URb9$,"'Im9_/n)44 Ց}aY.C%%]yWM~បW[l iZJL2qCڦpXQa8upO֧΄.WwD/J|w/G˕hc>Ke)m_Rێ{'m mllU|g9sݽЀ:uWb[w,\iYb^;g9sv3H\~ML)wWYWs\7̊hw?Q\f;idGbxnJu1S=]^ t MbXP*B}6!':9HϿ|̈ms5ͶB!4R[sJ_:ՆBSPA 2MxSS&D|šͲ t Xg~ kCh_'㷏t$>F\_xnù\LJ2[qsVWJZemRAM[]=Њs9X{˂H>MI@6N7DSVu|U D־ E*I͍zID3a1B\VXPDs$G-jklL gSgpŌjds84ait f 4ߏXZC!IE%ueߕ}ea}ǜY}S#+$Qgf(B\}e" /Z< 2^њƝC ȊQ+HzN55b6T}oJoy\W;a"lM}"33?IG03s202U%x ,ָH\a^dOcۅ Sg~:ܐߴ熦եfHD$ Oa^8P#/㚳=ђLHҚ[M1crLT--%DO_\k^CQ+o#Vr\+G鈦TG*˸bd QVfpgfojJ̩(CS4;kS{'>&"͏LVLT4;9kP5gn 3n/牰Mg)q}^-L`XeJyMV]Z1 3bto%kƈ0q$3LTG3m-MEUIjb5""Js΄pHd]ΠVP\aL1D!Nf%RM9݂8 {bbj 9z%ݒ7u3 6fCv}nH0N[7feMNM|0GT7Wپ^Zim{MZ1"҂LP ?rGь`ęmSW,ވfͺ/*V X#nhmǚH!z!%A RLL~\+&G`6Ch#٭vv HqUR5ggU˳BkF@jͰ&dC&Y5_D[cC\lM;2HY]̼2s{!ZWw羖k4bv1e}ڥ_+,]cڃ Afw$TcmXX@E^ Ɓ~ GΙqF=Sn߲_/VҜMPQCEl>Dv8QĵW\,ONMttqDm׬7 >^#O4UqVà}G q?Fys_m p݉y'E6I7-'PW"uTc&>_[PBn|ǁX0l\qïzp) (痭'Dy*&?(=dr7n " N4fm#.Q7`F] `Z#DY):QR.k"I׿^6P11<=YE1`.w@a>4c 1~ в&XXt.p7./86_f1id@fk?֕߯Հ0n5NԀ"8ZZt$MlMZsaєi8'Jk\7#|)A'nl=bfK[͚QLtǰf1TfAlK]A0nW6zka5k/ :<*hU_0AێSjmףnc&FXvS~ ?Gl]u凛:e1R}qgP{Ư'h~??6%Us\|Dc0P qڣM?_=˭Q @^/Y[ƥeF Y(1fi3 c.caH Zd_.w8LԕA5We[2vg ?][~=o@,ұ A f!ɬւI㿈[8hʲ@Iÿϼ:iX ˈgj9N€5p֝S] ԀMA"?: +K;YrΔգũZ@u ~CCu- () ӷ@_0}91%M61r&A~?/=10SJ3bLHx@+[6aHG_;zm"mc=+`Ȗ-JC*Cna~ż{G;ߐ)D[N^|ڴ3w-5q NّT瞵S5fOwCIVR%dnl@_mÀ4,,R=hAl˔`,=-5{9}"JP vEZ=M$̰l #bz4nչf>&KrMGgYNRci~?ݢU}հ+a,GDUy$++ދuԒM(OPic;a4A'>}m%Æѱ Yce☃ PQM!dâC YcYO8dTFZ jr9 )56JT{JLʌ Ìך{n E=y[Z? WE9։{'>9hBF\)-Hks;JBҴՏr5jQn^\2CR7ºMej77W+Pkt=dQyؐoyᔕhY/g)Mzv?PX!`vg U )} 5) Ԣ֢{bFaM1崥[rwj~XV(jЂh<;֪37rfiq;Fht,aD%w.ge6Nыa؎DZq;lǕ;b6~XYrnL/u7mo eYE=i-fW[ [>q 1gWWxR+x`82*EWY^Ns:KW`a^~ݲꤏ{'aLsmX&{|9>]:ZUWg7,NWx;;q,:V7f5FE4 {9 =ʳ/ZZ٢U ayv^ǥ!=u OZxƸІf ,a -5gDzFFmZ|BjD)H O?rrr6n܈JY1M:4Fǵ+:|ydg<ӘZr/e2YV:rkBO=nƋ `m?{$>\En@an<xOt?gͪBZܜ[c{Zzpt5+ÿŰ^IPF VݫzCd0^ndJ"fNt1 j,u߬ZpTSX1aϬng쟾.Ո޴ll8DQcTGK)7Vr< p 9p']:UyRБ Tdۦܲ?zil%T Jr }&ڥ֒; #v#hp s=YׅH{^.NnGpni} V O\ 5~>xu}[ss19oLzv8 :[SBqԔT0 ^;O_y:L~s&vd+:yY*DYUV^xd;%f0䱆2å1]%K˳@/l~=ƴ58 r(ˈ`u]"moB%sW64~_ftZQrBD \7"@)Ѩ|;>JaL6bFu5mnˌ Wx h^Fdx5wc{nbQl9`CwHZs_9"r|Fl*<)ɭ*f;mI֩[h6jI9 4sXSrlT>QwXkwXd1K&{TH(V_-y\RH:NԖd fxuU/)t~&t<=3$R%|OR+R ŏrkS8~fTeYҫbؑlƕ_=SYh )]fu4 0>B5ˌz@֘w>R$gy+o*4*R/\Ц~\0!;@>"TU }gN@GLi/-rN8y}9~_q.^\s\u1g;Ǐ'D4'uύνPYNM[AŰw#.N9] cKN*ʠoݷGXs礇Mos8+9~M" N;+r6Z1/?"#hrOX KwqgfY}ս:~ڦ-wX66+.1ߴ\=NeL0"@_7™@ ˖€(kZp63nˋ inhS kܒ}0Ty/g|ʍM{ZH"hgLJ[3Y6'6<8yKkż5/;|ç,!v0?ta$&!|ͅ[Prts66DEJu F,`cŧMyQAJO87fYuX.) kev6áP*9;7BfDėd^wc1u3MY쥹+P;aKj\%&aŢ'oɉsn}sN@x׆-jo34قkܬLׇn(*sk„75j'SF|f[o_ 6̹P)8:B9WWl+(?51zs_vL#5D Eѹmec<g|-O4*9K:8)G,+NNO:TV^jiVۤ<W?IJ Zyf%J[RK :J0ܝ.}4IUF9oy0wc dK9>U@ITʼ_ꚬqzJIZR}S60FW]ty2J"tÍgۻ~ 05sZQl-IڱI$HܸIjDCrK,1:;J[%O@tKɐcJ5vP!)_ڌk'^cGY$TaIKqqsEQO`!GRwePD1mUܢa\I(}`b[fvD[>3> hu9{[p^ YN޿"kg 'ԁ_Q Iߚ/Y]E @v'SZQ=M1IaH|E( UeW.,qԸCۭZ>‘h%yx0=`GqN 2]{e{Ir B;V7W?ɯtlN]p!ٓ@Nq5n\:Uf'RoUQtɡBJJcõb cPɨ1yx`qǥqD?X֎Ce`[9vYQR[/~ƛ>-܇_PuSOF;}ƏGTs|V&nP-u#;Z+l\ uC)k㒊F 1Ǝq$rw.@tEvt!JW_gl5%&4s"yQ%i'\7k*/7x~5m; Ɲ'Ph K LJroGLJ~|pZ' (yʺԪ*BԵC\Gx$ Hx’a&o 1R3p;CWI$OtF"dѓm@!.Z i[aR؎]@@~Ύv{yuw|}=GPn-Rm7lVW)rb, ѕ]5`gtT@5#{0nT\082ZԌ4r䶵U% |41r/gdO;riblpft"P77H0`X̢PF$\F9cp8@>TZ[q⪆x;֘ҢuyD^Q c0D,D)Uz;?ISx'oXօ <>IZAvm^Qq4I~r#H4T3C3!&F `D: MBFnkqՃ::b @.a)x" 1,"G, HqVU$`LbP06-E;u݋3u=E+pD24"ond3ݐiߋ-K[\E(0 s-[xu1ͼѴdaaC`aV p#zeiscA~=k~gNѴil&LgU<«b  t6Ѱ̦↲iŀG5"q\| Xc;l%^L ϒ>?҈zF s6Ml-Il;ڊJ60ߜ)&ta`s@u_<ɎFugK:-uB[G݄)L2O$7s8|7&D4?MR [+:v{ 4uO;xˡWo߄Ղ|d' kgB:k $+~ gXX,F$ /<[;x] EjT/!eC=9]ܨ3lIayNjs;ν&ND G:Nx:A,ɋeCdz]mXH4z<7h8M\vF,Ow|GEak5ᣖp*🟽.\ٳJ@x$B=yaTT}X 'D:Hɡ Ox~uAWC&AMAH5| b!qͻrvLz![ K$3MyWdp. 6F6u :=y[lWcI5R0;_LbKA mA:@2a4 O^=>ǨMjJo~`4,Ss2N)m@, oy\*4lߑ?BOOϣG.Z蟘ʴg_N["7w?+KxEc&h}uAHoG~#et3b'. qUӗ:U#.rv46Sgۜ|55s:y1L}'Nܵ!`zuݓ+׷6*_X6n|<^ 0VRaSDDC7:˄13LÀYQqwvp.:2vI eSC=ې##T]2Vҳ˓u#9]YWPQo08Ɇ)y1NFmYgg=9ajdq~/E @),8Է[|Űsvd ?$A`B@@@@@@2H*2H*2֫u0 :h uN_Uint;z3FO:]_hzHtw>1#oה|;rg(SY+ǑE#kEH J)(l3R 3weY󋏄7/F'Ayo"^eXm\ zO]\^R"_)M}Aٕڔ;W߃\-R !/~N񗳹$Ȍ J(T)=EDkݹ׌wΏE`ts7ݯ|O ۶#;=O{!Ѩ'xs({U4ufwU[?޾~߱jޓ#{RԞُ?QJ&^ZS'C46D9mnQ,*OL{Pkvlo;Q{´{]/2H$Euy{o$()9oG 蚢KEli7Ս+^q4:⨜CZ+|#ߔgV(#oDA`l=&SsyQw~|)E/:zWѥHf$ӵc)@ˣn>^D܌°FOY2`Ŭk!X'g-BO6/|򸑠+V /rˆQ諎UF ePNy^l+G_?3灡jF\RV BgJHd N|֢_WU9=SV[{c݂6 mm~s݇O"ov+BpPlEDL :URRr,5!A!ӱ8C ',_Q/#y}"%/:!R܆Ў24tUQ HtVALف>7=:q:>#bxLaU-4TtSưKz}K_imGoY¢mRn\S_$MIÏ5Q'Y Rl|mc&, JlR_ ~Ņtek"`q k*hZVmlndNw>'~*M,ύ}hE5ʘIFzrAGj)hBqSCAõ#F{ȎuL~0gnj~@Ӽn^MC1?Ru;s@ )AxHa~Է0ZҞk"-u7ZЀ]\&]<=mSy^D` 3㪚\ D|>ng6j5Cg?7c1| /2׉pO/scZPk:h/kxiM|CVl0kSL:wN$&mU Skwx2}[O28 6t ig͒W ^oU\C)Ǣugb2{D sA vCNNvW4E'A.lOC)zJ0gkLX)Ӵm2kms# hogW=~ʢJ/F, _,ZYm<eJ{De8M7o(֖N&X+aTX 6ۅo^ޣn/Hܺ\F2X-/mr Eumc:zWI 7 Xػ( Sw+$@APRTD@B"vQP&EHB {6e7| %@PP{?M63gΜyDsLS֚4o?ѵDv$*;#6=Yʥ##ܿ?9Li@4r~剨.D2s<nnۘ9ḏy-[Y_&_6Ϊ*D#G:ɬ[4]ixpIAѕ%X/K㯭jE\q|76FEv}#ӕQN rUT[{@x/[O]%F-1vJש8%skŢ(GqqȾC"]ka,g#.Egу{/cA~Z[۹(kE,3qהdJۇID9MgJUs*h$z:"u͖^!tZz{ +4A7 \<7׷Eb$ Iǯ\B^#b{__zeً}IplO~qxa:\6:.qbNm[Ƕ#w1'b@#* qѾ]9咠cgPjgo3dH}S3 C#l2(K.̙h-u=5(LHG翉?jn;G/^^{lǹs6d904ȽZAOD9{{R3Ξ{C! :j(E^3<ؔ&.5(ž?vb*.) *ȻSr`O:/77O 4iXLT\~r0}HU7fDym {.~[-e9MGXܱ:N!j.%e#}Fnڻ{K~lk?W5e ]{#=1]u@>ss;&ݭ1<};=voс9֞2L._;ǁsN8=%s \m=~c f;ZQ}uɒl Ly$M\{P2a֫& c%"p _.>Ѥ=#\80OuTe~.eYKΖڄzSI7s+S눖F0H.p4^FKҴkmAz>r:Νݘ6v&MT8UWvdsEkc=/kWr|j 1W(kwu?; )hKh̾u&m97s^~Y_NWޘdcfGҿ8o$Tn0Ԍ¹S?v!.[f!P$فAľRJ,")re|91gžMؐzc 7ͺCCL镼p Ňwhu~j[y-B%{لע&=M'z%e@c#3{M,~ǯ+iKϽ=9>;);K3RW|:cXNG 갴F\B.f.Acg|LQ9N66U9hTKmT7N]G4z3v(D+VG۴︞C:1֦?8+["i[,vu:Fbfm#Bw| }5 K2߳jI`7nRv{}լFK>hĜ +f_W zzo7)vWM;>7=Ou0 YǎM۸F.-{vo{#Y^YuhćW93'uvmκ*w!O'kR%kxH“7fH\o׶~1#2m];JL:0Zi7$1czNNod؁TAv.zEg[.@(nn̷ܺŚ_+4cJw|a`ܺHs' v[=]h-vBL:CqE(ѷOc!zT\N<^yf)襌sN$S y]1-ҫLX510*#:>-$GFƫ&^.K2cy\Qb`.] |q^N֮+СofD+~LEv.tkצHo42cYǾ&?¤LOQr mDW~c[Kcܩ`^q|pcoisƆzn;Y:`ٽT+]YtXƂ e]ZᇵTxղ {8hC_"_fD}gu[I7j ĥRs37`035EN6_xZn>g}ԃanAT&aޞA&oLtC慅eUWLQ,ui LzkŻ~t9_x1n۵>9]o䕔CF-yw oCU(5:f͑}gY΅_ϺVqS3a>{.aΝ >9b,ʨPI|7Ka ҲzaVu&_.RsZ>mʀ3pUT~șٹ\p] 㸱bAy62RpBc$+68Y_} 2Ay~%.O[+.[o-S{٧L2):}P;Twp9'WjF#zzFK? KOjվNooU؆`$OeC9#:@}ξ=i/*]O% z3wYqmҊ_[ũww%0nV;0%a^[㕟my]=x[}DWNU_N⨽Æ}pO2*q '?* mmE)nsxEY|8 G_rv\n⍿oNטsZNiPtq/8oץueW>PYRo9n{/|cţ?/kJQ]k|tASc,#Ɗw;uC]U{v=W,e ҝK&{{"_oű؝yĘ.vҩBq׼g;XnIЎw;ki gW$W'q0tΣCb'ϸwYQGOu1o¾.rݧ4t?əS{Oe(]O.+x3cه'% UӨ}?5SCDEG_)7+ǧv}]Uiu~V٤!nxff/hw9ϾXxHv#[9Q}N8|LʴdwG"nvE!g nd[xVy;d}ʄ$ʎ:8ULXnUgwxp@XD2Sxm֮:1=>vh Lɤw8Szq]g9A-S/;Lrmq/0uɡ|SV\c!"]a/shq=PuZ-ɟ'16|?p"f'c_֞E!_/N'qg͊k+f}]O" m{6uKi.?Ķ]cOU}Ϋߌosr(#Wou[Mve4d #Ww} NoW*ycp]u-'[}W⎎'n:OX;XSI|.Xg=q鯮^x~G֕e&N6fǓRٕQcw(EZ=C8xJ)SwB)ӛ~!mmIVYj.)yzmp({lV^McmNM7Ԕ ڸFE'u7 .ZFC楪ݩs!=T]MlBrF)˯J[LF$<ƖLI3uiJVͩk.U襾mPkiVWqS IJ4=ʧ:].M7pgws C5V,6d]}ϫ}[1 ׷vсx,G;QXWTfqU,έo|Ebbu$\y vХip lC+؊q_YFsWgeڡ#68-di3 ];#.~.Ѝ;G#Km}DmGM\x_u͋wfwd;9{)NH~kDpOې`[3iT]C幕Ḏt}(8mݰ1=^x_g2(O/̬㴨%g~߈2,d '{_ gﯪ؆xF=(C:t[VmZ\Ү-`Ouq(yƻWU#yG }ljq3jD:j/κVޢ1sǝ=A48k-UE3x\ySJbwkZ0RP׿b{Ùw2vCH]ڙ]^P " vFVȳ&ȥO1FU銖~eP{oCt5=~>b:¨^O}#&RG'~ѐg>x2I | beQ D@I_S[꫕ CӔyzU]]O MeU|)m}ZkQ+%xp7HZrw1kcj[4Jt._TwPjqXWYQV/gy7i*s/(41oE 4е-^}ې m)Mܺ\ͭYo0`!,ZXǹw:/[7gZl1Sԭrv?E[3ܓh27w7iO0ԼhMKw31D>kʮ:Oł_+l}W^)ڿqf?8A-Ŧ׻c6Njν75; Hk^?#hܿȪNt^Hz^¶Q߶= Szfٕh`EmHy8w;[/?!K4* Yӛ,?H󚺩]tM?T<+ ϣCMPӉQC+.bמr`"hK]$TMAZc޲+?Lu@rFN-";+3NB1Ypk>-J$pB޷"az3Op:8`iyN%Bo0CS5'OUs>f>gF8^"xO;cI{}ma.7d#ڏŝg6f$ 9/bh5 t#wӌHuޕsqF5MP@1fMz$sw\ 庄v ol~\f1zereN2Ҕ[qDvy׺sh(b:WWIm,o%FIpWs5yNqQIxj^c{oyLB /@CjRϩ jWaJH޽_Lp1CGy̞w^D.{h$$yrÜM^JɮL qQd_P^3`޾:xқ$!‰zwEq]~p|Fa܂^Qԩжb~?7"_wbפTkPYz]):h)FTE}2{egA:o a0^Uo֛FSdb[0j)۷(=qdرۂecV-l;s"3MR7WZ1iʊ)3_V=lvɇ<>t#PX)_oi+:I_WflP!2ueo/5^o`l0Kt-e++tPz˩UXu!Ef.NKv$Ru$_ N0S_wKU*OL7Bp5;EO%*; hj,b2ik4Tf]_Qsbke>"QCV;p>\6yW𨪢l~ye ۼs~=po/ȥVmNb*^sꋣ{y: ΩcOz^~tmgY?}(W?r ]yǢ\e@G/2loKrЙC6A>+ c6z䘠/.^v4-\Kת ?ua;<^܀J~`NyOL_g²Fv}r}bP+R~~{Be(1N{gm.̞Q Yb%6Vf!ks>Y[4/FCo>c̨c6< /7GƦMZ? 0(B,b4c30G(*eg#pʌs\66VUSW(qʠ,)D)22D=p1Wpt҆|c1,zQGyL<c$j;ڡfq0@Q [i,^m"%bJhAca?dP8W4' JSUa'Y{Uzʨ7L;K)s.k\ֹ;_r͍5!F!qz1Gf`n)t%Pk4蔍j/lzbO>ۘmó2g928BG;2y's%/Io%tpY'(s2Q~sE .澗1Cp\y󒈚O~[S"qq[~iMwJnE#&up@?9F9B"~7WeqYçy)%;M %?/Sj l6^)Tcխʻyc7 Dy'9_Byߺ7ҩôň"3C۶a(9oFEnap &p\D2eQ D*mּ<uahcqEa2MU*4oR*uϠ( 2xG1?NƄO3WHwO Aߜ[kZCB9H|q5厉~oNvMĨ,(#Yo.NIlyֱ/.Sq}v"mT\Td!v(L.eP`gTW:oS5d\.(E}EjHӪJtsj[+WC%''/[ Amt%+ys&,btrG_T)lwIs(!6VaHobԟZb:d@6wSږ_CǴ޸'9 rdO}/1Zw8 ሦ՗wl#&xXh,9qʚ{.Vx YmgߦzⰢgGP|C|z{etԵY?U֋M/&'޷]zzWvf~}BEOFƋa6ܪQ~vt`ֽWdA(E2cAN|-tP/6~kԠ)ICl;3Ikf$]uܺ-o옴{s*_S~ti/\8b5K0uO}X+c ?ct'}~^p.oe/~:O֠R6Quejg>įX#3rZDY*AʏoKڣv2YytBjb+/+~i;ʂ7O$ci8:6.h4'܍S;G ݺ/~2i=0acI`c$O9;g #|n8__am9y ^@Lb\>f\ $5btb.sdDć[ n=K=b +RUx;Fei Q/2 sKӧO߶m^xPAx\[n}מi(2e D24h˓*gdjWC en~ Rk~3d}o{(@%2t"E_ +JG Ң2Q&qGFD'ǰ&Ne.SjL& DWFρ @QTZA`)B>WظBr9f&v!!!fǎ-PTT1cDGE&āAo4ZP + ]"ݍ:E66aÆmݺu߾}s΅F?qSN:ޫKd#1ق\Q⒴)#MpFpp1f\>o~B, ;7T_WvE wƾܹs^^^~~uuuF5a ~cr_!#rl^[:ab$AM(:Mpk]<'9Ds9m-H./ԙϷd6QFc=8xzeجJFa3 !q * y:.ה׀@WEٛjy{]yw q˒ *a[L?LU̒O ,?(c 6ʰ!!!gϞ-++o.ѥKjFЈλ׎M6hu߾q8.ЙWxu$S֚M7bS긃FMp`9wɿ}U~Z ĞHp2gПKR,?Xd6ւ99899%'')(f[LBY0 J͔Οw/}c߾]M{qb`&fbqK|V" k4+IqDжw@wV}` $lk'45))ۋbJul|p8fih0qF̌mRfG~Z?L/sςv.N;PvyfsϟmVɿY4.]ֶl;nLۿע#o8zqy...lcS S<'nF@  $I,1 1A*uF3MQ5mnȀC{sv򩭉^xf' r͊]zvZ8Aih'yeLSÙ,!ٰl9#H(6f2WW7G`-#p\XU[=z;]6a^?-0V;xh6f=~?ôuCCWn5\6`D lb _^a\. EQ Lrghf0-Z IP>:*fǸ.[)\x<`Dʡj^p6pq(  ebƀ$Y-Ec֛- =3ʝaMăcfL6fŬAHb ߎ/ HݼQA WR׶u'v:bB0*S"6F6X'I 4}kd}D^s-A( jlbp'кM?&H»;ڞGOKG/\꼲ߨ?]mLX ϛ}5;1:zbd6?r٬=d{MVx<ޝ#[[ÖZf3%+W7. Kgyn|HNv-KG^IQ- ;Gl0ؒxN+WlQ(lqvv^iB8yz 1l\-.O("Y _ uİ}]]CwhPT(`6w@w;3;؀UZZ}ҥH6+4wXdz :NBSTӀMބ{hWvwMY_+8l1ccce2YϞ=;c/X%$$%޽˝kL-fܝgJxFwo~E#w6= :b{:CU/hLII)..0`c<n]+AQãM6iiirzrn$qolOÉ;tli۶c-%ATVV޸qM9/B[ŸB\ [z\s쇚o׮ݟ=mhhzj]]3+F^)++KLLdkmllv,KUUUaaaii)ڷoG}?2,ξnkk+ 3TL&6EiZ6DFFIR*ׯ_xrO#466sd+MWlkz(4 TSSSZZk}o<(gsk6SUUV?F"IR"899K&A[QqRV>i@l1AOEcO% |||Zmee%܀(rqqy(4}#E[°ң_{A/w $7%È!IxsdDpմVY2!2)ǡ;IyWpc E.]*X(Q)I_&F78J1W':ǦBeܭ:'j~_CCb+nz<6swYךu AV3(ή~:bgϮ Veޭ_ٳ6$EpmnO =d;bc1krOd~Xm?lPӢ.Q-u۶6BYYts#le%wmݓXW3n 'LT۵$1bw.+̓Kvpkrthvxտko{>_1Z}3uk G q_̽H޹l*5ɑY?oQ_Z[x"t#%q֔߸Vz3L vbEPЕ^K5s$Î^k߽Շ\$wjZ+NSXYBN;-UJ2,(Oh+QaӾwÎ ,1ĕ ĂpwV*z;먩8?iȹ|nuİԚ~?ߚa[-R\7BG[a0n,,ҨewgaL:SşZ_G裬#ut<)<8 DS>0U$ƕfҤX(пLeFꢢk鸭={2|Q埯q " `|iӏm,29p9hkC(JӠPB1i=")]k$251kWJ6.?b܁/ꔔF*aQS[Yi5j=l9$} ,Hr?w^˞ԕd*pPKeInjjZ~qiV,oh)]fC :8͑mspDR5(bOUYTK?LN6HtR>Nė~M]Tٗ`CLC`"1#P$%Rv:i?+y="GZY9|DB 2Zō/?#"w8W[4%9_|WN\H.N ؐBfgˑ1aK(re_HbM(~}#. @ 8Od-qnTBHz)゙RXb_2(_tyOg)i'!)[d]. :[ya9#BG$x:GSvև\"lIM LӢb b)A{WRafUEɝ7}V8Ҵj9b1~z\0<`vx۩y4!x(_ 4_q&:7і_5 jBp)!&r9IX:؋/7&]EwYHʵOkm=$Sq,@i"0ܬ8 7֭Kxehx#QG ԐuArXui &IhIdx#z|jL~,a#_??7KĆ܄s :3:ps LE{m;*tYQ⮗# @p/RS4@ !BBKP(}n;;{o ˍ{o6uI<@LS/mKR1L~0CڨF)¹.LkBwji^|oڥӗjvbrR.!PRjgW8.}lQ*lԌSn$(s07#oYT_tVQ^~}(_]{B-E0 { w 6Z+Wv/IOqSGDVB-JRMߠTRLnj:MUs0h}Tf©Vbuod^}.}i Jc> $]}96ٺcfrj?F 1i{~V 7}|ˡYcˇowԵʔ)Ke:r;:I*427(Pzm[ șKu6Ӧ ȮJ:g~_7lAŋRL}E MR# Oc@, B.L3r5wF ~U*B/Iɲj=-GdY g`Ïyֳ^zGrWUkTd^Ջq{X:2qeFhqm}&=fGK7(5O$_ڼΖn6^ryLU6ƌy ,x1D Nn)A*UC,&-M[ʞ} abwI4,+څY#dOG[ktqS'WvmI IJdG^9T|Z PΚV̘dqx+ p1{TiVo:㢲-A\v :+oEI!75CޣS/YZul\G;а)Cm.ÇLxo7,70#..)zұ­Gʥ5v;z(`W?go ѺtP_wuY'ӣr"-{K-34SF*/K{mVs~['^:Z^`= @@~Ggۆ}ݍ_~i:;p5_@ҼcR(w,>ʤ>j~2tcNni}c;Ѵ"*.$vͣ559ldVleLD4+BBjYʾ6ј䑻k;Us-6g_U|݉ Xe0̉wRC(ož=7QA'c9?wf6m=[SURojB%w{MwjYϟ9_|*Ct}7w/?;Գ6Lt2' N86ym N7^v1 \׍bs]VFd"DGHXbHj w֢ONeΚS_z /pVp%ۺU_ԡ!bŽ FA<{hn2Feubv_;m}Pćonzd]O[r:ξ[qToS/O~ Tcv`MY :kˡ1}wwxn"~Au9K1LGyo;pkn*<,.e_n!O7XJi`Ogyպc/Jgn:}~ynAܰ|S8((szhe9ؒtC+ֿq/S۰g}xOKE[C_^pX[C ?2bV5VrA5]A&YhZւ "3 -;jٺty<8)aGzݢ$95.^R-²tIMu 3hZժ4E֐Yw~Q}? ֝i 2SXaE~I3S1M"[{}Td/\$ThfEQȩ#S|sSEǴ8/x0fyVJ`yx^&ݟs_?ǶjWY2._y ;-ei  Sw=-/h7Oq||OuQx|2'?:sW'${I{W3( XAyDbFCw~º.\pڢ>YRtVt4yY/T& _I>{.cJ;vz$-JʘuTuڻ?JVA+v㞸i/E.n}ǗOd FxS&w\UI 2=:{YFzD7;3ܒw;c#!Zx!s/>'Nzq@=r.ʛ'g*+`/ C*#czvaI iFBH"9ۉ5͹w=3qkyn)PՃWaZEӭ뱱vaQ X۵iw#z1t3W=t}>/<Ne?]}M%҈#,qYW q~ya򢄎uްo04z%y;;A\r+mhA&LJ:/3?4'Bt86}W7=aԤꣵp el}H[+.͹Ί_:29&tT6VfCf }F$~}םS&NGP߰NsַmW圞oZn~og2T%H4P Qm;yx3xIg_uM{\Dњ5 #HdLg!˟_{Վ9|3bBgfN>ިd!YًS .xJC~H8|$L>!v%ڝMktӖ78t@ [)#iK'֭6ZCH)F>˧ӈ%->t擕[+71g---n燯JuMy8\'(bZ-@%ˊϟm9`iq QFY0$TQAuE@;$"rDdT|^&zMN蕱MIF2YQ㤔36>)$ɂ:hdeMH2yAaձVer{PէqMhPlRYY%hLBP7h<@JVI&T eLp$) vhy3kC4 @$>+oXREE%t$aFq %LC^әsf$=NkpMxW4HZc̹U @G^jV5,E(uo,'LmFPA hg0 V2lѡ7/rdŌ8ScFiI(-! dR +rMM3i9`(F{M&vՇ` 4{Y32dJr,I 8tY4A"0@YT>2t+OJnK9ì{M=(2FPH_*sTkTF2ZFkeG67yIJD%q#q(J8}>YpV]/Cj,pд gH&"yDGbDhuh6. Á"2,eV%.. ڥ>#_ 1Q$Nɑ Ͽ42WIœL*]ШSGX] ^ug{uͲz&0ݷC X!,YrFu#DTPcpN`X?k^N+%6jkp}x s^y=vo~T Swkl_vRJM To]VO!QWI(YdD?ײ[meMc H'dP#> ,l"#S"^TU/:D#;+zjNc{ljsNsἱޮƢ];߻髃3YkkiBwgJO;oTn&JttdV.{~E.JZz_ݞҗlo'3H}rVdLܹO=FFM~&"bX=foؖMաsw^ɚZw}e!zW~noo]{CoԭuVԋdKԫo7lSVkR"㈦= 6$Gi{JN CSSǝ. #Č v:dq#^Ղ1IuM7GU7+#ב]ͥ9ehZr\Wmjkr6NHV{k?Yn9\* WY 7c[ח^H훊?ݬ63~HTM^kn:xѦ% U^/m ݭnbQ_vn~Kfus|]Bxٛoo?;02$DОNou kecl'2rq4f%wV4n[_w>;"jfڶmսgK3ts}O2  紂[)\ĄpNo6MMIJ&9g^V` 7$;5ZoeeSC .z(&, f=E[-t@GDe\:B;[n$ad=M`f%- z۹ICSBp$Ę>|tX(B9yClI汐Iab,3Y!*хd}]F1SH̺|-mdDz$L$ CŮN"|H֕ʳert搈#Ta6Qw3N!lyw,JuD=:FZJ"en5Q61MiQC@E.Zb՗ӧF'KkC#@[jJ;끸 +oruX)-` ٱc21YbM57>:NԡROOIZQYg\| P͉̙8iF.e ĥp@Z 7%͚m^rْDK`αIDfJSD") pbɊ9L~[;rwDтCBM9 f'Z1wB꣢iK%6'$9Β5*./)TuyrYDcGLĥXlg=˘:Re7)f\dk h"j&kL4dܰn6i5&(93Z4hH bxsB8ǘbbuV>&u 2=! lG+>1n 2bf",'lO:svxFsFc-!b`@$dF捌̎Z =1cbΛd,$>432Lydu 3vH;wcgyE:*tU|;l 6jAS\E R"#,@[&2c@~ESf%B}o )')!H2|V)BgJ1eZ$ ˝`LH2<( nʝA1Nl&\;%QHB]=P@YyV4F`2CPxD ZF+򲺝mZd1bVdv)'#*r2~zA(-%Յ<dC0rD[u^QLPuk. ,~IRyxNusrT&PeuCZ Є=JD%({`@%$#tJM*ŔjutH<&t3U \CD3JU5̪sr^01u],*RIN=B,I~2iZ*y)m$)9R:()Ĉ"J ٔi~#AI-NS*)")M 1~e D(9xDLӿYz8:T]((ad2 Cc$hm3A#)Qqz+ɸd_o6,VH2ZZҎ>~`2E]Lz}Ǖ[ˌI9TN8_m\nNTRo:ըTIQF|%1ҠrJ(DUxn,!3"*IVAP#9[CMDt<@XuOtpOI]QVf9 /(ܥLs,nj7UO_β#?)l+^?/UIw:k$527Вkv_~HT"ec'NAi;k׊WW͑{k_E)7E'MU̒S3¿luՒ$H A]gS@~ ̿si p @ ȿf~o"@ &PX@@ R@ J@ RF.9v@ ߿8KQdF(5ȉnՅӢxpRK(5@~3)#ۅu&F{ q'zkKG9{yë{/-yw! @ ䷒2<݊ͭuq&mleVOG/<&XqQ(1/NIfVdn "/lt]_zxz5sӵu¼mi@[y2d'e;bga7tVV%@ L@ݱ(dɇUfiL3AJS9 =%ECfnɣaku¥)y1@~J]gK^9#D'BϏ_X5'Z 8$3!R@ =&6LN͉?Tsάa:oQq=&hCk4hs>txxz@ ȿ@ .>.$!*k^U=p0rPTGΟ p @ Hl6^xhV!(Z9sEEEat@ 1`10&Qy?۲= ?s8@ _~2 ~9?y@ A$QƔ0/@! 3᾵J d  @ E)PXzP q% g)@Q@Ep!A(E"$.)EF"H UJA*@~RF5? ?z(Nxm{q'N8Pί=sח7޲OV:cW>i|c rGbVӷVDA-w>՟_VSymE]"p @ ߓAT $sE9$L-$AZk8HC`oxՆGy }_8 v5@~( 97:Plk}},uOd_y_>GbI]` QiN`d "~DIw݄G\()x+DDʀS$$Q]Jp -Y̲)\zaR`х Fڡ*ˢ@%.MLl[y[v8HJk罻 A%I`y %(VA_@~+)#IRb?}I֑K/hyz5OzQwn;J\}e$ I]@vwëYN Gnu7W("gXIn}cB~"D Dc{=%؎`T ɚ/]x(wL?%} E׹gEE䜻r_^7L6a32o4q"O]#B=Zl&oyO& J@~~ڔ,qqWG/ȹ׎IEQ\=HyKuYuE[-+Ѹ9/./ì!"hՋܷ(''D&N?>Ngg22H'@( `2%L[(~58,˕CI0QĬlbׅI#EȪWED5|,vr횷p5/W&cWm~h|#^LD'& @Py,#Nj\Wޘ~(,@ ȯ+ɗ67E$ITK2gE H( W}QdA=< 'q%Սa=˹A| $ XoX]V- EL<2h3$1%&uUqp")vdž헍 rp@80 IU2,Q8.*AC3uRc`)y;Y~lT%YٹG"wN*EcfoD d  #%E(ɲrr\~vg|vڳS(#b"ڊt*g' 2Tռ=s,,z'Pǻ_r<][TV2ܹdm,mb[W}^ psvo߹Ȣ/ W_9 [DC>|uUobH(߱T7-3$\SKƚCEXBytC~gOQ'wu wdinz׃(b7Dt;?:mzQi0zk7rT# &e\7@L$)u<`?l 5Sl}eGxu.Iul;+nf0n,sZ'djiy#C$Wg[~;F% 3Dg׶{"+21-bH>f $NW6;8qՊq}AyßC!= 3>BBnmK%c7:gcSe]Ó7ܴx}zّ̰>?vhޯ1$Ṉ_1_x:rEC2%ZOGjE"5,pt|ޗzF륑OZv0uŎJ|woyǪ˻'mCRR(.`ew pL;ٌIc*SىIeGz>v{ :}':ՏhZ024DU5NCPbʉ#QmhjDH]mmD]@;3s65ol,~zÚd qU^+*=<T=|g76)" CF.;짭cL/x;ETk*v]eK|ׇSt}2).cBhRc eK7x:ĤƓM%7os1ʯGfgEb8AEö 1rpZfk.78T\\muNfBrÆ\c̛_w)h׷4bds#' K{}I $a"CMhHK Jtft0Æ!5,;\~#C-21([|~g[p֐?2i'/ L=#h&Boϱth(#%'g];/:1|=݌ ];DDQ}?˨h yb;{MƄ[\Nً &Ί.#s[\WWMnuvW~mۻL7]GS C/-L0kڸ5(^}p:=㰷0?QMRۂ$Z361Zh D^i4 -FFC<V @ W$Dq0)o(S|wqW MH6] #@ƈ#ϿKn[GGnXt}( TkF|$A ob0%{qy1HT/ʢ&hQdxQɒrU ,QBP18i5a z!XhH#aE"ɼ4D!Hm8鳋_P(jD)Y=:cyKIqsFhPTGhbp@OW6,͐7tb?Y]^FET˝jqth>5҄_ajY$%* EiBBa8w@SӉbe;^ CZz[&t u\)rp @̯W$Гʐ:e =r{=ܸ4ZӒD(Avzr|a֏\(Ql#}G::a3j\ vZJKK@Ezhk(ttJb9dݼl:,DpBp!0}vdK;H*[a (ӔD'5D=:5.̿.uE\4:"fp”~S?vӳ?,yz95;WB@N&Y3n^+Y̰DR"} EB)p:%׬%E'kUx,T^R 1;@ ?ϱdªH56vSU*dAqM۾Wfџ<xV&4ik|LfqNLB`6Dj0Ȓ, 9 q"N^ɛ;JHJF̫OGY^14{Qm0:nʐ /7QJdIfK{2wץQ<{@~E~~ 68mJ#yz[upTQ :ōZ}|̳^O`ps ]wPA@*uI4>"89*`NF!gAll1p+Ly06@0]r8nZڕݻםE g2"+?ɡ$p)!}?rOL}~uӇ'Mg\3 ?S(NP*l NV gΠ:iF)!=_蘁rhA[Cɛ~ֈqʵ~בS T!(rE<\Jx܌+ IW\b+A@ Ve0A~~΁,K/I/DeNu@=T8.Mq>Vŀʼy mITe9:I Ze 7 J.R^J8;/-D`B+ɿy8A0xm* 14aF__A# @ (eh!@ x`@ R@ 7`u@ vf.Ĉr:GH|nғx%yڠj(ݵa~fPw|oMQsg<Br._ a9VVlu?' vb/szuuٳgMÚ{ GHʍ! #/5{z=󇧄uTt>ɚ4ʹcHw]JK*s\pi OUIJ0g bbt=_KZxّOOGuIBgYaS`¥C%k˪H|ngl>z5Ɯ+>< s(Egj(ZS˳+*lrILqə(oIs c]՝+fofdOlojRc/;QϹꆱJHl~ڜ1ca|;nkj݇pՠ9z6g3+ت \BY\[pm΍Ub30vjÆl,|0knyH ;̼Œl" jntnunKin7 %+u]̴@LHHqPS@ ؆afΫi=z/<3}Փ߾QמMkJ a]JBnއ) 1WW6fz"Notv4ۤup?ǖx[&%pT?1w;wIec.걺1׭xgҚ8pSc,r>u ?~)jç-+ Op ([.9\Z}H<ŪSe(ye;v}faQ߼XȡÆ O]YRxN_j&"'Q*"Y< :q6q7.^[x8wx̓gϘ}ms&Oh;Kwg.Lzi]k1 :=%|}k{[yζ&m/ OuEJqzdթM7 (9SH? H$0,8bңy;^kqNCzޱ)Qވݓ/򎝳lr{ v'9uѓl\2~ѝ;1#ǍJzoWڣsgnX;Dm;ŞF7 `rMe M7 cRds˯٦P^QUy*5NCr/[EF@׶_q 8_j}DcG|WFY4ao~*qQ+kCG {~ICzLACB'r{pk~U6_\L@(*֢|PYd6'-VmIFPDΓL|pۭr_崊h2|GO8]^3?"Rk:<~5'=s=rw;eYk}5!*+r`X8=Ȅ9m߬x5N} ҫdC5B̀¼%[XhuHꚀC S (#J(iXL? "QEB]W/@Y'!YD{:ɢ_pD?e`5{-et|hzP?=W)x.ˏz%)=`I |pôF$%aAp1Q y)f]7|)Ò >a>?2JQiѲo.q4kGQE fg#x(XZ~0'0Ena {fZ|㹊v# 'ͷuబӇ 9]S0mcz_xluE,/DE͞8V_69|@VֹcM8ɰ?$Y$ENi[-/*zkH}u9l_MSYSm˼)3-r2ԋ 0H$r|]/K.8ٌMlUh?`e(ySx7I$sVUٞ2%N%^"]eʹWόQU{/Lj26\YM!ls]bǿ;w"Hw`ύk`fll`ڪשk4B%r|nWSkU0_wz/m#2 ի|%Fמ*sQx *}$Ge@hۉ0^<~YjX7:ue1~KEk)\yJ($r=7.4qjRCWe׺nf@J +Ɉ0uf;V#U>qM 1Ddba$?mmINzvjl(/V\35( (_I 2  ȉ.)IENDB`Pylons-1.0.1/pylons/docs/en/_static/hellotemplate.png0000664000076500000240000053731411645401275022561 0ustar benstaff00000000000000PNG  IHDRD{ iCCPICC ProfilexV7~ƾ$Z5 I 1)jLdikdmSd"-?y;{N_=s>ys9柡<\8lMhieM2 RT:OOUif&zIoy{n?Q'RƶH:f$mbGl3>@"f }' ؚ1x i$l P ( ttOxgPe +p}@wub . ;DP@2w_ 6v`el4A j a-  c%~Zda` ؁# P||Np?v01Adhc+A,M64b-?na7B$fsaš= !i(BưC(R\\\6\p}$KnYܣ<FޥU|2|f~U%rтXB4 uy.E+[#V@oA>9RzR=Ҿ /\mqڒK&eRdd?/|jbԲ(L)(0Pܽ2[wZR?)JFfVڽt+.0o#Ư7SGF􇷼53@unvIcy;t{FܮjݳK6Z97g_6MmCyWNc.+\n},,θOoT3 ;<4;l6|ѼHVTq≰Ssc&ٕڽgV7ԑc&Kg|MΚU녿^녿^_/΍O,to&kdwxl8e0QU2P_H$A(x ; ;@~ )MB"!b$ۥ.X,)앂v%c*VYZ]EJ&٫{S"55ʵ+An#yu3j 0mIS3Mrw,5dT5k0ojnimݻ}#jc)٫9:Ҝ9xE{>>͉  ݃\Bh aWG'=fAj>qqdǩ^g ccJF[$('|9Ww>1qo1i0څC)kR/_OݘFHNl ŕLZWeeQ-z(O"[kg * Êhn/N.)U*++(X[N]{f=Tzȣ\5QWsVAz '6[4OܝagYfUeݴkྉ_mx0װ,98;e992]C&SEVQ]'//A!aG591y?Bqj1bFO֜:NplO܍; ?h̟vREK\SXok3TɜzZD֎lޜ׵ݨ;}HvF᧢źų%Jm)+8~ݺ{aߟyWpÞG U;jNԥ՛>&<.l`=zRӤݢ5)ӲvŎgitv9{}eEo-}} ^~0jhbhwrc5'>Nҧԧ?욹$ytB,_4":Edx.S%,P8Mys*AEjvd7e^DFMZAziU[3*aMgc[;/M̾XhhEݿe(3m N ^GY'!oדnW=Zg9R^^xyW_x>(:8 5@%G돥EDRq1{N:Xq/f{%P;u>3p҆d ))̋+/~Tf.v9)ҕEWg g=NαUɝ^~H޶7_ܺ\^0UXXyr{ijR:]VXYQN]=ҽTJU6?z{UqGʚڋu{54zrqk㏦fcm:mO }:tYN.g/.tY3zWf}Kx4x!aF{xsɤTt׌ClmliOQL–o܌ }כ 2ZR pHYs   IDATxwUar!HfsN .YWWŸ"("$$ArNC9Lw4AUsTOT}{ @ @ @ @ @ @ /@K<&@ zAMwp'@ s݊Epԏ8@ %j*t~vs P+ڟh_/셽^ {a/}E> RjS6@ :(VSB&'9@ C0gGu%*+fC:C^Ia/셽^ {a/*ڦֶօQm @*G:wx {a/셽^ {a=KAp#jMզ Iԧ&b&"I @ '\qR]SѤ  WT>p @ $N}:TT7h;pV.@ |ITǻK"$ jnԱ^ {a/셽^؇c}8QPچj__z(b(. PFp^ {a/셽*T8 `-jKU'36v\59q@ 5E(G36vP#CnW'9*<\U.셽^ {a/dR U~E6Oe{6l$\A 7*lo](BJ)S (OpOa/셽^ {a/ot@֕b[ &6 PP q[)O N  '셽^ {a/`Qڹme޶J`EV㧼ڄ*:׃ .E<ڏjeJaU[ {a/셽^ pDE2!mѣ`!C٩oqP]AT1V篍 u(]2uoNpN:a/셽^ {a/oT{ɫ̟Q~ ꬫ ZDB!/;T@)Ԅ2=s" {a/셽^ {a{PQMďwy0q\NT"Im(^ER)3W->[ @ _DM8R:6([bSY#WP`CMpM@Y'|-2QF,Kj,@ ~ϝ?իW3g~ (Z&&TQMA EAn64νO &)˒xff@ zAb2l/^u"$I"E7sHMO@ zE6/ .BJʍw(ܡR3\N,/2*Kߴi7$ ƾDL$%'X>${"YYٔVV t6Pl<~->d$9-7FCd]LYNa!~7,}̑' 32*sНeH[)ajh5yϲ@pSNӉ^q_nGӉ@ ߿-1!wDH,7(Pn|z{lxsd|FaX"2Uv8kEaHj'瓝O@p ^1+++Wے$q)j͇?jG ~B{Zō@IBCIhh5 6:􍊤EXĉÇєcԀ1"\͠Nuˉ:ԫ3(-z-q(Ep떓01}ټI;g`qeowT9m貱HzbG@ $I~QaÆ>t <1c0w\vaشivwӧĉ:uls!}Qn6d߾}|7Hİa<8;w.|/۷ogРA>:B}yWѬ_\G[O;Ql+%`@Q6$Tg0sarʽ|C:@o :X4jIjE"2?]~ȂbDZ-V8q"`̃tj%9 KJ4 U1Teǒ%% Kru(`sӴ[) ∎$2ʌXA-"-DE\?&]8s8`bX-n-Zѣ2e ~C}{aժU7-[? q7ƍcϞ=`P'~N֭[}o>ZnV۾};)ĝEӻ.;;BJKK+..KJJ&;;+Ws1uTf~zzEYYeee8N:vU޽ڴiCii)o{r»ѣ7aS\\Lnn.C(>[>}PTTDii)ݺuӜ:u7;ڵkH$I3sL|Avto/3j(F+BQQQ󪰰[ng"Ik׮婧bϞ=L4ѣGdtpBƌŋemĉyꩧG$4iW8?QUU"8_-P=鎰R(ߘPکE꼢`_T8(Kd$(  SL4("Y̤ D3VWLrXIQ1'FcLbcbbNZErXb2R(^x"#DY-b&Ҥ'ʢ'*Z i<ŎXn/y摚$ISN~w^7Z x8q"׿())?3vX5k;vЯ_?NO޽G ?~o^~ҥvmbCdff(pHVVj,rYll,.]R=FqKMMeĉu Ň`#כfzȕ$CѸqcL&SH$IK$&&ΝsN*ו/,\ K/rfСC,\/L'Nj ]իWpBU,XKEEKJJ01Ln UUUl6 !111z뭔-رcڵS!CCR5_p`4)//۱c;.]ď?ϡCh֬gΜ!77xB}\|]v1{lbbb;vLIImWʾF#gFҰaCl6gΜu֬Z}Һukye_֭[Gbb"III9r;qF9׫W/F /@FhժUH@ޝnڂ.҂b@c]DUNtz=huPgLr>Q^PYoĬc54̀Dֆ^nԄzB aаaC <ʔ7$7nqt:2w;&zꑕENN IΞ=b!66ߍ?姒UVxb>Cfjϧ_~4i$MjRR<$MQQIIINHHi_XXHՇO7DC)nbbbӧ "??>C(pmۇ2=۶mc֬Y>ʾgr:p%,I+*ШQ#ydƍWd@RnUUUr˗>||>xKqq1 ZC83qD>3 yװlA())EXRS4-p4~փ o_(IBDq:qaZbc0B\ǣv5() H+ubnlԑs[l2ј`Ԣ1hA#!iѢEdsp.C^l߬+ۏΡj6a0i4cљ]aIr}5 + ~DAŎP!U~z].;qℜ~vm۶O-{oڴ Ga6U>y$| s zξ}dddЪU.x "57eee||M0 5j$GK:nIϕ+Wx|ρΩTLB޽eB*++Um܋;-'4ǎjZw5mڔDܟiiit:,X H$oI9x}زe O&//C 9sp98z\qFv͋/kƂ /^ټy3<ӦMK.L0~KsC.\q(..&=='xB{y0`vvE6mq?WʶaΝKUUQF1`~ߑAQQl3пy{׮]r-0)%Ν/dɬY>}:iiidee1w\/$**]RYYK/?֭[{gϞ.ᘕŘ1c`رr⡇h4ӧO?UV(((7 7&;;ݻu0BqĈ;v &`6歷[ر~sno+'P*r8̚5~Z7o/,w~O\տ}Qxg=EGG3gfΜɧ~JTT{+W0g}]l6-Z_w+%AP !k!P8&PFF-$PLp)?t@zQjDFFRp;wQq#'$ Eee\s$tDl۶3d[B4mLl+QCa~gNesx &e5l;lV+111\|pMOHH ;;VKUUL&JKKeѣGf͚Q^^Ndd$o1--By.ц 8z('O_m۶>uVX4 IYYL&|lrss}/>s\"""HmXZ9sMû_>EEEwHLL$##dZKOtdff}$I(o`4INN… V%''-[b),,+̇`qqqR^^Njj*999p(++x `V%>>Iqq1RYYIDDwݗ^'>>t:<V^z0?4hЀ,*++j$&&RTTDLL EEE=d2G~~>fLff&:rrr$**Jޟ> P[Gq !wSYj#qmޑ'mʺSH_&:zM6iӦ1w귬hQ%Fk IDATzL|NjM|Vj匂JÞ={0aBs(\RJ.Z6|rm= 暈qvEȮhH^6)Z5A& 4/H!R VVZGZ-("""]vy=! A$@ (p-2b[UYO)EMyjr Y@  \"1!sj#8W-j"ƟDu{]((##{RXXxCfsh4бcG4iM]vYf  ZC P_W_yy9dggSZZn ~Sz"""HJJI&X,vJ-jl,U/ATj2=x; ay%^!СCL6mۢ.͚5ԩSuҷСC̙3Id1 jןN:ѨQ#Vk!A(qZy@o>\Bƍڵ+IIIDFF !I9<7n$55:T[b_t`sžO V;%ԣJeaǻ~|IMuM~I۶m2e o678fOӪU+ڷoOlll!A0 X,ԨR^=FMzd2"IvFqq1.]bl޼vڅ{_v-Z|)^NgeyDЖZW4瓊;ػ@HOOu- ꘅ?F u:,,,ȑ#t҅Ν;j`0j5$I8NbccIHH --ݻwgZnMLLL]ygNvʗP jS;u~uCu"D1v:F} 3.eA߁FQ}x7iӦM䐐2RSSkΙ3ghҤIHI4Ξ=KBB!_YYIEE5򳰰b4h_+W={6JX>zږ-[8|0o %Y-:$ǵ;w| BCdy׫Jl6]v%>>^C+V/p𲲲ؾ};1Ƒ#IAA::D}vZh4hZL&tڕ/͆h fQ!7eY(6nL<:獷P )5_/Ju?TUUU{ټy3]t --]ta5' 瘿 M7DDdFӧ_:ŋSUUEqqqX/^ǽDEEU'/%ٛ9cjFBb,NCr-[pr{2%Ni8|G7|N<ϳvٶmw}j])--y:vHrr26M.Φsvm5O>#QTuhٲ%IOOgǎ~ΦW^k׮̚5+XAe}1 DFF!$IbӇ3dB+c6m>Y oka̙7.>vͧ~Z-[Ǧ`l8@QGWTClZjEZZfVˎ;Xd 3m4MX,,Y۷W+++Yf Y|9_~%?Xvm RmV%Ef4ZjEvvv(B?B}m9GM@yOzR;PD _P]EK=9r1hZ6hܼ<>Zn믿NV jy/_l&.>կl6sQ|M׿֙?g&##ģiӦ{^bL:U.OIIO )s._eE< Uٜ,!>|kbwHWVQ0r,V}F!clڴ%KCzz:5~ʕ+>|Oi֬r}}~ѬYFM<_~?xOn?2fZn߲2ƌ_MnXv-GԩSC ?ү_?^ui۶- O>ۮ];>sn_X˗gf3&M㭷 W8ǸffΜu0cƌ:Or"9 ^n=iqp#DC~m;2k.v;={dĈrԨiӦhZ֬Yî]ѣZm(=Yz5999L2E6KMhtXV5jC= h6޶pjm>QgRR,lh@FF?0w}7/^$>>ȠvnA0I||</^&##g\uѠA̙m1  |A֮] /Pf~m^u/^LAAGs?~<?0^q,Bd20Lu!v<mj*q*\n=ml &@l(31f)l;>cǒ{oK/7|Czz:+V`ԨQl6ڵk' ٳg?Tڷo/G`;wgWVDjB}L&&IC 4ؗVU^~;f͚e˖Ln6l_ާmYY/ ** uӸqcsx ͛Vɂ {1̀K8̯PɓQ{nzA/SNѯ_?bcc{()) X-[F۶meС#_oޯ_UUU/@rr2F$I;v I޽;QQQX,f3QQQt]nS ٻw/Æ h<=zwyW_}E'ꫯ2w\:$v/_믿μyXn`ʕ;\tZKEx!F?2\ =2Q8;֪ԩ)R>'CQAw߹޸h4A۸ov"#"8z(#GdL>Fq_|111̜9.]PZZʈ#?~<ɔuʟHΞ=K||Z*Gyy9| 'OVh4;V>jԨOi{<^۸qcVXwqɞcWZ}ȑ#1O;oQQ+c\j(L6^{;v0sLy)S5j˖-cر,Yz(1>|1c0|~_ /0b<1|l6>ׯ ?cX7n5//)Sߢ۷/<QQQSNe|w~EEFFb6C 8dMQjܮQ(Ԉ tKEр@\x'IKKSWC攂l͞={=z4WTUPk̗z=[N62UQu]tr***8|0+WD+0tPElݺQTqw>(z'Ҟ={hӦ L&RRRGJJǐC&}YKEEf{gCҼyp]0'MDUO|ri }"GVBնz7Em(Wؾ뮻ٳgozbNhXd1Z^{?&Mƌ3-[믓K^ >Ase۶m|P`0vZxyѣꫯ9إKkٲ%=vmڴW_etЁSH p1{AQ򍯃1ofk } ?7q9;KW6m*qu{{۷gĉ- &!pE O_}W`0;wr w}DDDжm[9^ZZǎCu~YǎYfӰaC[NgRh4zL&S8B~ r:z1k Kѹ(T-sOڈn:֯_G}P"Dj3f3SLaȐ!TTTͪcZRTT$ \IeĈ |MSYYG1 \t{^|EZl4h~- y뮻XtGy(oGuhi;G[ lAo4jylDf 8+iX=Y-֪U+***8}lbVO5k|A(L2r9 7fbРAo)))Maaj:H~k[8p ^zL2^z DjjqOX1rI:tNˑ'9"I=UUU<#rPsرLz< `~)Y~= G5W^aǎ|AG o&稄&ڎr $ /@J[U?[n{h4RYYh= ٽ{77nDvw}OnԾ}{yϟτ d!FttFyժUTVV2j(DFFRXX`d2ypHMM={6v=O \!WBHTCET8>rx`mMdߟUV"C#Rt:Fj|\ܩS'oΊ+NI_53﮺TUUocX8rgy+V?C2~xI޽{WNzmDyv :+lDGCTD&+|!ҤEH*;=pT68~8 ~TUUs>Yr%Ǐko&gÆ 233ywӶm[~mynsIUQW^=8~8ݻw\"t߾}deeѰaCڶm رc4jԈL&S@B9 60xKLLntҠQk%⬨+Wbw>x… ~nٲ%7nT;w.-Zȑ#vf;຤q/Wjm .QCpZWQgVj˧ d2q9~8&rRyVgϞ\|o%Km۶1p@9f탊!pCqQ/J"##=6"""0 l6JKK|nn.111+GZtM,ŝp_T'{2,SScpZKPYYI~~> >s2|pyvm$Up쿸|*++Ҥ CE׳l2>3yhg}Ʋe\cS>#&Mģ>̙36m;w_dlݺG}'NPUJN\)*z4ˆ-hQAD\l$q:'îBpJ$Q,6nނphܸ1Gl:Dnn.Nŋ3dy(?*{g￧w%ܹs̜93fPQQAaaτ `4}Ƴ[raÆt:姒K,aÆlÆ <+*첲Xr%o׸/ 8y_xbRRR M0%K WcѩS'Zlk&2;dΝ>|IXhPСCK^^wߕ>l7W#ے$ˏ=k'||)S2$ܰ 4N|k ?uK*M۷O?{RVVsr8p8$ FCDD#GdرiшhM6u]py{ &Y~$\tINo>V+ 4 --hߏ$IpyP۷sA6ms'rGDLjGBWQ)_ Qjj($TQ 炅żUVHfCsw3l0ꫠ}b־}2rH(** 9i7qIII?O>UVh"5!>q>HBbMomLUUyyy,]ѣGFs||g< :1cƨJ-ovU4؄:kHNu+q`,fdh~1|p^y7o{\x^ꫯҿZl +œ9s'䩧bϞ=0}twΌ3xYf x/^,?1ӧ&LSNƒSO=%ȯ`|Mz>xzꑔ8 IDATD-Xre@3еkWRRR??:BG[o%--m2zhy.aΝy=z4 l6}YyƏoA_>> <7oEuO;]/]2qv\chy+ >>I tdffҴiS9ӜN#**~ѽ{wv;$əA;wܹs9}4o>0tPt: , 66@aa!]t\Ǽy󈈈t_Z^s=,Y;vPZZJ޽!={m۶ѴiS:vWxߟb~m`„ bU$ILt:]Cdsm^ Ed_{ދV*_]]emtm2Jh`Y /^,XS_U$9tuy뭷>jŘwq>? (|QAǏGӑ("54 &Ic6CuEͱZѥK6mb(''Ǐ& }Zb6{AZ_}Pj#˜ն*~\p!KjFS.^H||usŸz$X$C g$If͉'8{lmxp)} AN;$ @ eуZgQDN+Wi& cԮ?A@PuH$222(**Yf$&&hyy$Iv*++)))!''SNﵬi^ۡNqZ EL/gyf3eeel޼YNx/߯_?VkP,]5jDrr>@ ~JٳҟF!&&DbccZ"/AYYPXXX{I&*%SP&ZNTl;rI "|yj(H)j0X7o^,s[~J]Qaߊ BQ,]@ W4i R)3΅"Cj-\ P˻](CB2WZZ?혅?@ G?Bs27a'@ )ϕ D"H$Dr{J2- (j;wCD"H$G:DWxD r׻-qgz%D"H$Gj+Fnkvj"D"H$Drb?dN~tBjr~mٲ'NMb41呗WB233196`0>^ѣGKt@:uhذC,bccX"+V|uiҤ .\bPjU%Giڴ)Ǐl6sQz= Kd@ӱ{n>S-[ڵkp/_&??5j8A2La00 17no>N+yɤs)9uTOY`1 4`J9vޝUh"V\I׮]Xn]vʪUOR w}7Bt:Ç~>͛1Bka6y'/SL?W9~8`駟*v?~׫A"H$DVPi~;vZmoqGK/4SΞ=K9Ѹqc_˗)W;we(/[CVV̛7:0p@*pΟ?Opp0\tLvM hذCϟwņcիWNVl6+*ъ5>}0j׮͵k׸vrNxx8 \ztBCCQׯ_'**k׮qWR%*WNS\a4"!!L9?5k$//p /_VPJBBB((( 44;(q_pAkSQZ5L&:NǩS #!!ANS?!!,_^~8qDTT*T 55Sul6sN[D"H$wf͚p 0&/fmKoo}v߮>8+E89m{B^х ; tGZXm !7omڴCγĉ.x"*T\r%_0L^{OԞ FCPPFm\:Ӷ0mΖszw>w?ǁI$D".̚5E8GP\ً {q թ3j"8w9{-zBm[[oGvvvڑSYzh4>QhB+g\-nWv+5#BD"H$my@s ɂ*} S+\sADQl@! $$b H$.(^88}D"H$m+]JxZ(Dή}U^T`@*ɪUDx8H$D" QQ#xKU~Ԯ]ۛ}D"H$%P[xT@O\иj[:D_~6I$D"H$[{V? _"!y;׆"y%H$D"HêU0DEEhDJpp0AAA+u:f|ڴi96еL!(7{-H$D"Hbz=jբvhZ !//VKpp0!!!( \U"oȗtj2P'H$D"H|G)kEOry&999jzt:NZ7ARc/uI$D"H$26 N( %peVl_Z;/A >Sg-$ED"H$Dr#P- deeX,PR#:LΞ@ "O\u{rD"H$!" r h4BBB0jud:ujVAm-ZDtt4˗/wyܟʕ+^:s+WvٗWґH$v`0pl0!!tiWIQ /GrDFP)*j$//ׯgb?WH𹀏}M*kkiǎL8ٳgӼysF#saL8;*psox+jժQn]J$Dr[kVQh:4j>COL /=<&Gy Sсظq'??/Ě5kXlʕ###C+صk /#G$%%۷  KII_f͚P!CNe˖4hЀMҧOSC;v`Æ ʼ*Fý5}_~+VTF)=w9v<O63bZh@dd$ǎsk_-)ÇӣG:vȬYHMM,fgi^+\KkfРAʾl:8x',Vν x +J$Dr[`6-닼a`0k4wS5JꑺTFbvjYw+ù{-[a{׮]S^=իǀ={upJжm[*:u2\dd$=z`ŊbܹY7xï[՗FqOr(((P6mJ֭i߾=))){qɣ7dFaƌ8ps!rrr<}ƒ\;1W=&yj;W`08p C aE]q/OSD"vDh0[/FXbF0@hB ^"o:M\(CT\)}؋vv6ʄ|g{Q θܹsܹ|֮]Knn.FⲼ--6~GJFZQ۾- -[dԩ?}Vu;-ZW^ԬYӫ]-oef&N2]D"HnK4X 4`i( .2<+F,kdh %-:(BP E( ՀxM;@= 7 ^^XzhѢDRRX~B+W' @h4믋7o !OEXXDllBJ\۷ow.((GM63g4h8}73B|bݺu?.^y{Jk"<<\ʼn/ҥo">>^GOtA,YD!VZhm?쓍BO?hQZ51qD1fѭ[72pW_7ojժ_~u"%%!M6za߯*ڶm+1gh"xʣ/68ʦ<ѢE **6n(ŀ\眇7n _XX(|MѨQ#1}t1c 1a~ܕ3zk/[LDDDsNq!bbbDrr8|HHH ,Vcǎ&ɫ]۷ow(KzLSBNj*UL["H$ۉ˗ گ/~~FpII$$zλ SB<#p0 g;4@"MвH#4iD HST/qEPH/&aEZ%Hi)&\)-~\ֹ ۶n$F1?ZjmϩStGppDrm icX~:111 BC0o޼Irr2SNu… 5|LXXFѧ9<6/ )QX|)??0W\!&&FUYRrX,hZnܸAPP> @`PZ"H$ە+V0`n(/mB*B-;OS)J#YAA.zQˀ^Q4ͷ:DŽ\t[-|p e߮*o2 S󅒬=r'1TҴjC|_ aÆ |%188X]1d O}~!\&쒔qqq*k$jsYb+@H1$H$ :tZt:닽^FT~= p Ry7իW9{}…HF$䐖{_׽3|<.2뢶u\q%~'_ DaQ_'555&999?Da}?o9g Ҵ@ٌ`6Y0̘L`2B D1?nnQ@Q#ܩ8 aqGYfرc.H#`4hFCn>|8 cƍemj-ZDtt4˗/w{Ι3ghݺ˚#Gп[L¤I|̙3=رGrӿVʸqTWS?3=z`Æ ̜9!CVoeΝ4nܘgOk$\ի3w܀[XUxb-S/tK.{|ݛ]ҿ5kйsg4 Fr{رch44mڔosoinXj>-hs-&dP5O?>Da}?WٳƍSjU6nȜ9s>}:={v-* ۧO&L^gɒ%\z97n`ݺu;W܎8<|W\I޽<+;={<8a~mر#Tvƍԭ[Ag߾}ٓƍuVGUU)W XUUcX&n'|´i0L?_|k###ԩl.խ3 ))I&)縋=wmқ]f^}UiҤ OVU*JIŞ>̰a];O:кuk,X3mXX~}'[7mĠAxXp!4hЀ3gΨaxgٳ' b̙l۶c^Զ9P,VsFb1c4Y(410 Dc)Gꀏ0󔐶;BP @E *U@<&@s%ht tz/ hxb222Bo"::Z4o\^Z<3ԩSC/Ba4EEϞ=5j3fP{) l'$$3g*{%rrrbO=PlR /\޲Ӿ̄ĠA~{zQQQwߩܝ;wŋŋELL8pC,K٩6McQn] ENNضmڵkݭ[7{n!سgO<8c0DժU͛B.LRRC~b߾}۷oBe5kֈիW绌kѢC.;wN xĺuw% !믅V)7nӦMQQQgϞb۶m. 6)څڵ?~B狯J9)^WӧO˃6.Om;wyضmthܸxǽ\޿e^y >suSVnܸQ$''%K@,\PIs͚5bܹbΝ}W[EÆ EÆ EJJHKK5Rd !8zĜ9sn/X X|'ibo/fxbYQi q!fGIEw/zTZi@"PH,5EU HsDi"MQQB4Kpi)֣䭇$˕s5.-Z`zYmg˖-iРM6O>$''s1vŀkȑ#IIIa:KVKԶ_`2Xf ˖-\rdddm69t2)'t٫UvڗOpNq][ū]6 Ry=N:qzjRӖ>:uD*Uҥ Ǐjs{z6?(::m(k{HժUyg'|ˆ#|5::ڵkӬY3zAjҥ 'N`ɒ%ШQ#0ԨQOxق0ZBLf0sXdz7Kj|/fT=u9FyM_AϞ=ڵ+ǏB  uٳXQ8pN:y3jݸxի@z0`DEE1|pȐ!CX`Aq÷駟ǡC.[%?CϞ=SNѿ>CjӶcޮ];e-]F1+q۰9p΃͘1~z:T̽ժU###a͓e}GqjZ*ww999Z'Q䩌{9ҥ &Hjժ2.y/O3`xV\voy?ܶ 5uzj P/֝ رctgp###!0dz;wm+K{3f ֭N:QbEl\r ?lGGG+Cm/X Z-h5& uZ4YCZ<(=5soWz(+F|;Ô)S7oOF#W\ƍݸqczOm ͛!hժ>c֭ԩS9p۶mSTˣ>Srw3sL{׏'xyѥK{KYWNTRcNOOw)1ciii||GWOa駟eeeh^" +Wf֬Y99@<~yts.+އ4oޜg}ceBOmғ_N IDAT]jڲ;-5|]wѱcG>3._2>[qĭV݋> uq۾w^7oNJJb˖-dggs1N8>@TTNRݼy!Cʉ'xiݺ5YYYX-ZЫW/ŭn^^cǎɓen3k֬aĉ5$${ӧOs=ЧOQ;=׮] ""KÐ!Cʲ}IV6~Gfϣ>6CСCٱc۷og>kxΝ;gڵb4X,уDK<]ohӦ իWwO?eǎ򗗗WL޼y+W*)য়~bڴiR{a…|w+WNٟb!;;[U׮]K֭yׯL2H_c=zBwy.maa!-[2uTƏC)^=CRSOmғ]ؖmNQf=z L8ϟOXX "==!/_l63Pz}j =չ`l9;;[y ;qD޽;m۶u\b?9P4AՀVE@@@ iP^RSR.2Q\"2˜BiF̙3ŋp'Ke#GDӦM̙3/ 䧟~ѢZjbĉb̘1[n"%%E!Ĕ)S *222ħ~* bcc/N bbժUbرd2 !S4NgƏ/Tت+W~ZKeS_ڵk @tM%3gի8rH5i曢QFbbƌb„  >^ 6L<3}bh4_\x{}Q-mܸQtY~믿h DddZ_E:uDppHII &/bĈDřs_l^^\`%1oU1kUň7 1!B|p܋2׮Hx2_-P ^)+oG,lv}v:7BraK.o StԮ]رBf3aaaF;I1?Zj)- Z7nDDDC׮]S5破tF`p&v*?rWkOYk`񊉉)Waa!!!!޽[GSB^J\\\4L~~Җ[Xb8+_u5to*B~gZn+WyVsm۸y&L:U xnuSdp9oY/^XXѣGtԫW˲?u.[oC=` ;;7n_sw,/XIYb2i\jWd`0' *GTH5T"ۦ=J߾}0`K1y6mp[ ?,O8!O> 7x p=%IِEŊʒm'|B6m܎ŗH$O,\7:OII!11ѣĿsLDQj!ߨF+U)(_"*! Aȝ K˜~P)Syh׮ݺu+I4/[noߞ 0jԨ!O_~֫&Hnڷo0`Z"??+Wлw2CaNX^CNg8'szc`jv<"gG > R;ɝ˼9Tj >$A%Iƍ\2|AY#)%H$ЬY3\¶m۸|2]t)s!d ҁ@"0,U$ٺfL&0:$n읮;Wq "̋Z0c 3 F Ί!P[x5ׅYqն ȑ#ߟo)S0i$8s Gs_PP@ll,jU-z{n&OڵkY`=X<1o<[vIƍٿyıc j޽oߞ$UV<ʾS㉕+WRzuΝxogn!^;))?We^|Ac!4-`IXfK^Ľ.s (OƝ=?O:/%b0g4 ,3FBS @KTP1z3 RUw1.]`{U >[PrѼysjժFd^C:u^:իWg׮]kە}7n 22R]l6+6ڵc^_}U=*nwҸqcDŽbeJb?2x`~7•NNCej=g{=ի'Ow]\ tUj󦆒WM\%]ʮ@%Nqos)Ͷ]UZ->- dlʳ_ْ݅q+7ng}޳W}_:,@&3`AQh)4EHvx{i~o%^9W PGqF֭9x ۷={Ҹqcnʾ}h޼MW7+W(ۗ.]矧k׮lRy iZyf̘ҥKٻw/⩧O>aڴiL&Əϋ/5tԉBҹsg٠A.:Pc:5.>&Mpiv[{K/8Ǖ˄ e˖>|X9)O8p$&Mk:˰axgٳ' b̙l۶cpw/3~W~芟.]0j(jԨNyjω'xxhٲ%Z|W^Epp0_֭[97;n+ݴiavPFmիWegڷʊP)btTL.9 ybq7~. Ah,W%`@޽ѩS'ԫWݺucC%:oh0kٳ':vŋ#;;쓐.0Ɗ+иqc 8Mغu+<==[.Z-6l(R' ylҥKqnݺR{3M˝;w>>>h֬5kdddcǎ˫;222˗vZWY&fΜ۷ozB~dQπN: ǎW5ºuO?ˋcu~ =cEꊲ2z>|p">>P*۪V<<c>= 6E`pJ @ƒ!L!dȂ\7AZ JG$iI{ |VTS/^QF !77o}1ڵXfؼy3yp]l޼'O-km_ HMMܹs9s`ĉ2zkիW \\\I?-¼yRxFj塰UZ96m9sUPh[:srr"2{ᶄ"33Sr0 ֬YK")) +WoX5\f ֭[ǾT>[yCRt-t1byRm՛ 1*,,ԩSѧO 4jڍ퍚5kvڢ}?#ƌݻw̙31p@;v ժU.~9Ғ~ Y,СCAD3gz聅 bРAc,'߯Rz>+-AP𖵥}y.`@(J 8(89JF-% c;C`قlHrH8/!W\App0WΦ}8~81}tڷozJ۴iS]fQ~,US={D&Mc6HNNfكx{{cҥ/-jxݻw/gc!;;YYY2e QNl;w 44eѣGt(**TcĈׯd`,((#pqF}DFF"00M@\\ك>}pʖ\lj@ֵJ(WQQEɓ'm"22*=ƏF.//lאvq իuwwǍ7@DB3WJ"33999Ȣ"@!>>5j@||x IHt:C!((sAbb"Ri OMuԩS7|:t|_HWO WFYTvm*--5k/իIC yi֬Yt ѲgΜ0@&Mb5,,,YBEEEuR(Ԯ];ѱm߾=mۖf̘A|Ջ 򥧧9igϞmZjoFpBhlߎ?NnnnT~}:s ]pɉKk׮{Iޫ0W_і-[Ņ֭K;v`j'jРM:ƍGᔖFDDIII)??wBtaϞ=F>>>E0ںu+={:tzO*++T[.&MPFF[)HLLzB˖-Sj۶-UVѣB111T^^.4UFVL!_1`ʃÇ!S"~ EwCμKeݘ}h7N,X@'O<$ mF5j ___:}4ݺujԨA,X/Ou>ɓ )@5jԠ#GRYY`DºB]3/ݒwߥ3fTy+?bzgΜzQ:u￧[nQdd$ٳgyPݻ/bc!/ٴD=>9 ,|]H3ӈL:і\ne/,{ e/s2 s/sn9>ˋ1mp25J4ka| h-ѣG6f * B@aa!9[௿tBrhZT^j>䌁%މ)J(3 "{[y&Y)cEUVؽ{7bWh\:H8W-WԪڵW^\kx뭷35T)o33&4Yo7 Ad鷱cjF ";cƍ l0 ˹(**3]v#BBBx) ={R# sڵkqM3:p !kß\Ad[A$˜)AŽg~t:p".cڵHHH7 1$C-HJJ/V\7xϛ$; e^uÇ8~EcߖP$&&"&&ڵCii)ЧOYߩCK`F )h5PX ,[dSH1L]mu`ԿR[laAرqqqWo4hP%t|P(0|Mk0Ǝ+Y6Zn<֭lC; T,0 htNtCjLj"?! [kUi/^1nܸgDvavX7vRH %t 4 t:ABjL-[bۓlc6ҵMavava@ĠLVhuZKt*oY#0X-.T^ѓ'OWTrKF~~>yBVk׮I_VVӧO۔F;lErssߣŜWBii)m^S.z|222$QPPH*JKKmD 1smo;KHGP :jj-4h YrZLϩf0XnVm'Yfaڵҥ BCC/H).sAttMڿ?:w a0zh|Ǐ0={Dpڵk1cHPˎ-Z\pijՊ`R 6m|76o7/_nz+<î2_R[,9oh?ARRM&[naرݻ7' ^^^`P(DzggFjj*֮]#FÇ JZ@`jR\ 5@y*M!fYc}Y,mRVzj,Y'N믿;wH).{Okɓ'[nŃ#Ftm;wKdz}:t-?N?kPTT3f`={6,#Gs+lz9^& A>í[oVtի~m;Xx1Ο? 7_ ͛{.޽o;::ልQ^=,]Tolo;-hWJ]1F 1H%z3\'eYLoQ^_c˖-CaaEI1Mwqq fh j֬hT*]MCJ% swpprs9|(//ǠA?Wy[BeZj4o\r٣G⫯`y$O/ x<îx/)jܸq.GXm۶ARشÇ믿L+ѨQ#~FFF' ooo;woh:j'Od &.!ވ_\"X,O'K/C7b޼yh4HLLE~Gt GFÆ L<uEPP._,i ڷoiӦyEcdeeǤIo>]vqE 0G}>OazZƷ~>}Â63k,,]  @NGEӦM9C&MpE"33hժ~dff"00[lo?k1Q(2d,Xm۶!##.]„ D%ވ :uBtt41)%/ @Bo9Pdneb,=ӯ m 3j\P[ş;OuFh@6 @Wo@$EEEԳgO@kצos_VSdd$N &Syy9y}j@DD(,,oζJDDCjٲ%lْ޽{Oo6[ѣG)99nJhÆ ֭[GDdFQDD޽aÆԣG?SWӈ#ز4|pݛ7o&""JEקǏܹs)::~g@JII'ۖdzʕ+-[Fw/-\PR;|2˟1#"ڵk) IcAN| T*^Æ ) ԩSԴiSr1'"ݻSbb"ZkPd͛dggSϏRRRqƴl2*,, ϷS#)zEHSzz:T~版… ~'"bEl9!"$tI"":qSJJ Zb]cǎ0 ~:5mڔJE0 RIIBB7oSDDGJ;?B~wrrȑ#Ѷm[AW^E@TTqYb֭nݺjhذh? c%|2"R꓊˗/#:::uB6mpML<ѳgOt/Fvv6>,8fBd+Vq8p &T%Y٨Q#np]L2nnnHHHdggzT§jԨ:N=|0^`믿[rt)J2; ftÆ ̙3sN65ػw/g,8;;#<<m۶ŋ$,)vssCRRѥKp!'J%o:ֻ O(6xO2_ ,yrttĸqpUH3gpuuE^Я_?yx0P2  Fo(pP(T_B)F>@BJ`ٵm F|ʂ_ݻ1tP<~DvY?GӦM1g/HOO'o1j5PXX*VZcƌ |rlْ,䀈8 [)Ƭvڈ–-[PfMPzul߾=b:`ܻwk֬u8ܶb̙8p ;jժLJURڒsג7ɟ-:t(sA=pB 4HtQfMԮ][tG1f޽MlRSe5oCdff #4Gƀkx0 YRTS/^QFKVK۷9gzjl޼ `޼y{.6oތɓ'֋ƼoRSS1w\deeaΜ98qUyx P*)@!80 g| ͍"[:U&RW?~l:200~~~lȦMx G 55wAvv6f̘gؾ};o)@D8gUʕ+Fٴ>Ǐd4طozYa ++ 5j`h41o СCѧOdgg?R@J%P0ppPAұ␎) G4:Peի9x IZǸ8dgg#++ SLApp0d`{_2,A_z tٙj<}T>mPjBcf@DD\]]ၚ5kk׮Bf8?pi"55%%%Pt(//lKkӧ?~(SN;|MtЁk7n㓙]!GAӉF;wvvƤIpM QQQ< >>E0ںu+gR۶m ZxSN7nIIIf>}Jm۶jժQ||<=z\\\(&&6mD...Tn]ڱc(Jxɓ P5hȑTVV&VRRxQ/w|2#?K̙3FhҤIfB^^4c ""?>G}D ,ɓ'Sii)ōi۶mTF ӧOӭ[FIɂnٲŢ,ۙ3g^zTN֭[Ih٬$ԿJIIӊyj/M!4D2'vjj*խ[P&M(##w>.4σ{Q߾}iٲezjZr%{رcE/^$"WtY"{ꫯ^z䶏 IDATH[l1kj׮)̤!Cмyh4k,LPhɒ%TTTdF=ݣhaDy\`,{Sas˜ 2Ƿ71mp25L+yDb 4rPPPwww<}oFF:e;wQF[NBB8::K|BqJ%7n,PPPOOOT*TVM}SX3cq<^]BWpttOJ׋-€RPTTBڵ f9 C3 &3mWUh88!$^K#oR2S/ -AlAyy9qyvBm"ƒ,Bc yѣ*RX/Ə"8::Z)BoS}o Rc$''cΜ9a[޽1˫aVb֩()q2xzԄ{-7Ԯ t^C[o!&&f4~& &H3õ "8{aȎ!!! F]vѣ{iiihҤCֶuYuav!O}2evamPhGC/9gwH %t 4 t:ШP`j1~+oܞdnߖm;,uCzz:߿nݺ6;x>HNNѣGQNYycsz1-D ʴ huVhH_տvW* 2*+%RVGvTnnnzdav![F֭7va1tzsj5iPBSWk#` R,7cOh;;;ʵ0F h@%Ԥ@PkU$#-ȱdC dYJgxDw5K{ z**{81 _6|8bbbлwo^"##0 Zhx0 """0x`#** 'NG~0tP(J4iFϞ=͛7 86m@PoܻvF a{YcРAz{GΝ0 ')Əa={`x0 "##1a?#GD`` єB0km99v"""?V^:7t:/%%`;v-v B{ߗE].GeԨQ D^8(E++S0m4l۶ ǖ-[$e Hk96m1g Ю];3ƪƨ[Ts0Õ+W{O>Œ%K0 }]<}Jh`M{Rz )nc>ǎi @IAG%d蠀#8{w{c?HMVf iY@\5K!d`PƍzbbbkNG]viϟZj{ HD'Ps6MХ7oj*@gΜa8q")J:rPAAZj4bz׮]n:a "ÇBW^y]ƹj^-{ubƏϛo%VZt)dPTTD&"s> 8VJ222ɉ(??ZjE'/ sN3zZ-ZE3|q^k[)}(++Ð!CСCG?Ǿ}5/ 6l(@|RR.)45kKƍ925F={6޽{_=K~¢Ê!66֬ot֍-瓩3Ω*K%].W7n- ;v(M4Mp;{|OӧOJ¦Mx Cpp0֮]p!Yc2m4΋1͛5k[ byָv"##-ѣ`۶mRɕa:brWUrak: ʫ[J/)) gӬ~Cll,-]~$G['c]g ):x_X_0c Y%Hطog[Vſ/^͛7{2e w YgƍWV-4V\;v &MBll, ӧQN 6Lvy)ׯ&M+VC4i`۷#66[o5k 11?qD 2[la~jj*"##;c޽x"Z-233ɹo  2kb"KyV 7776_e 6b*PUr!/^D9iO>\ۚWuԁN<ɦY#φ5jdƍ(--e8_m5O::G*𾲐_ |)++?fX#H8wVX^ٳ~)}]cѢEϡh0j(޽...xwѷo_dee]D^z!!!qqqh4ܹ3o9991ҥKtz쉓'O7…  ѣG "i ¬YеkWɓ'=z4;fBa Ts)&&'Oڵk1~xsmM65 UE+^9U^ G %ÀQ*P@Կ;(5|6%/UV[,AҘM:e]]] Xd {CV3gD@@ƎSNaΝOnݺ!44͛7ӧUK,Ahh(Mtbj3xll,ׯ+V6n܈#G ooox{{Afgwy_5o]y| [> ERwuu9U _pQΟ!H^^^fglxzz)((?Oi_|;b+;::G*_R~}FՑ/^D֭9g޽ѩS'ԫWݺuc=m߾]ܹs'\]]/O@y9o5j؏ƴԮ],{xxqhݺ5z [n:u Ga3 cK.6lfΜ;w1cHRKNNN=z4~7vm?ښ)ګ mMr#f@>5!( (8%(@P0pttq[ lk,UIJ%fΜ 03f@ 0tP{?7n@tt4>3$''*dtAV;wD۶meNVZŻ4q>燺uZ\Y3Fǎ1۷/ju%zh;P ez:yyyhӦ=ӗ[>RRhT^>|ܹsݼys ԦZ.kˍ%l,D ?={oE_b#Rxo Hկ/ј5kˠۇ}rҌ#777v[۹sf͚5kO?ˋ_~:u2a-׮(++ߟsŅ/KyO[A:O<Ǝ%K`͚5ڵ+Ο?  H3r,3BJ@cࠄc%`-W:L:ʼnĺHݽ{7/rЯ_?;Xr%܋W_}[lFcgHJJBǎѱcGt Æ áCcC3X|9V^-\Pv5AW FkP|F 4MyPUo֭[7jgZ/_x""Z׋4ay EZ/A!=zo?JBv8^^^ej58Zj[-ANN$A$vJ:u`6SY}+4O>6lz {Ş={DT P{U5g+=Yg #t78*P*WLIoHQe "+?hMc,]???v9K.ر#+`)=*d4o#GuU@՚={ꅙ3gf/ 22:ubOXz5ouA\\;[nUƍ-PY`胿?۷[W_aL8M X,YYY2lE.Ѽys Zjh4eÇΛ7]t1K_~=gM6Evi&C޴~Ë'f/oߦ{; ((Ȍcԩ;*1Ǐ+Rl28;;mW~:V\e˖qggg۷oh4;w.W^Rq[ 1:-a@IIYҥKAD?>4ibF\5 ϟǎ;xʑ/5kD||~ h k擐s,bհMm2h 2ei\qq1Msqq1F|Сx1␝,L2rffzݿqLgdd 00oEZPRRºVTp0O>X999x({AHHtR|8uq*Ry*d]" mڴ=\4X =k猘[Hk5`0j(e1}gZZ-FF Шr @k=\X ,ȍF* yYA9A^>R[ 0)ZlI:u &e˖4aYwܡaÆĉ)44fϞCܾ};5nܘPxx8{?Ν;y_iȑj֬I1=~Xr7oL͛7:uիPTT{qFruu>}͛79y:wޔ[СCٱ=z(uܙPi׮]sNj޼96`0`uޝ\]]͌7DDT^=pR(Ԯ];|rx+K}O?};󸨪   J.h@jOL E255-Z暦h$R`Kn!b ,insgsg_ysssg9MCyy9Qf_zbbbt!tԔY[/LəJm۶%ԡCڷoД)S1 C}'߽{(66^{5ڷoO;vsB(00 DC }ĉ)77BzߟN ,#Gҋ/H˖-c-Zu:<}Ҿ7goZlIst!թh>{eH$ԲeKΦӧOS@@IRׯurwwgcfddmtR:z(縲.^H4|ڽ{7 8o]Y222SNiD 6'Oҙ3gחlmm۷o''''jڴ)P~(<<6m+ݝ yedԤIk7Ody+td+Vкu ^{R2h#`3B{+=ܲ)88H}.]=sj\oyz%G,ˣaDsO-D6ҋS#Y[m;A j 3k8i_#F GsFXo }b@F?͛7ݣ .]T*E-7P\\lr{mPQQam(>Ē%K0k֬L8 .d;ddd\P(FUu ~wxxxV],g" /)jxTj թSNYM.#77ݵk J9-EJ"B{ky{~sry)d۶mCܢ:N  IDATC W0% n.puqS}3`ˁCѷo_MpBv?+5 Y:Amh/53,6UD$ 2224u֡cǎb?D8::bڵz"w"iIjD!@*$ V H )V_\!!RMX 7dhj._zٻw/BCC0 """@lƌ`R ,@II 郆 _~:t(R)0dDFF)))ٳ?<ATT =z &&?SNe_RoܸQFwBm4v{v碢[o_~eЩS'Y wH$xp]l۶ Z0Ƙ1c0zh$&&"$$ `# àGHHH@\\zpdMKKC֭0 |||^믿0m40 q "`Ȑ!|rtaaa8{,s aUVaϞ=hӦ $ ~GN+W 11 `ر/тǣK.HNNի1`K޽;oC;mum64l7n|ڢk0'5u4++ aaaJyOYf`|oo6?۾k￷ZAO;$`$ $2 6RHe $2@"QIVzݕc]jB[BȜ>'0kK-@|#Pݣf͚k׮%eԺuk8..:uаa[ʕ+#"Zt)'OJǓT*t6\.""z={zEaaa̛^=MEzD )((F9JBBB8璒8m]!C1`͞=A4Qͩ~r͞=ϟzۗcJEC [p1G!4{lI"Pʕ+JZj9I4i$p7o ǖIu&(--kKKѼy%39kθyX[G-ZDV+eeetݧ(x~w{DT36OOOZxUˬid߉TM`7ޠ/Т4wwy.RDS1%V >LfmfY͝!T Sf x#yȼh۶te;@Tr~9z(:w ppp@HH||m>VVV_GNI₹s⫯Ν;|m-Hиqc9ݶ`cc+Vȴo>N^gggl߾_rrrpL> y&~wTUU2$''p1m8f0 XrrÇ;,X=pРA0`{lXO"?r״UUU!>>O$6d2Aᅩv 挛':j!] {{{xxx-Ӧ&dzfeT*D~e2G8p6l< շ&y}'b%RB&a eTDTb/q23!ScVT.],{;vwxyyv.6洇&mVV\hz o-6uTF6ϟKZ֭1c ٳ))) "L4 ɂe0x`?=z@~~>#G \g,!_ҥKznwϞ=x" eZs'gFʡJKK1c L2hܸ1gczz:dDDDܹso+WDrr2K.Ezz:v܉7|eeeǤIн{wk~CyZ?M6EVpux#GČ30g!33%%%;v,NcرlY;v쀛bccQ\\#22-wҥ agHu֙-zjuH1t K.lٲ5jvP>}\paaa_ 1yd^~~~7]SVV> .D||<>ScիX`^xGNN&O &`Νh׮ڷoǏܹsxаaC̝;cϦ;?>ƌ_#9O]?nݺaȑ0qDxxx]vp y{1"LW{߉TbF,N$ A66=F6­ c'ߒ9;_2 K| 0TczI[Z`>|iԨ-Gw%֯_O(##K^z%z͛l^xT*'QxXz0&UmذhZ''' b5mw^9^|9iӦѪUh4bj׮'ݢE9sܹC7n$7770`)J`rvv9s.LD冱D[m>>H\NTZZJ*ƌCFKDԦMzȑ#OAAAoӧՕBBB(55ƏO׮]pڼy3{0b G=(!!=޵kjKoΝfl+WmstHc_N7,bQ"nݺQnc\N{_'e˖ԲeKJKK< duO;Dj;u9sЯJD1PTTDcǎ%777o[nQחRSS D͚5d*..y*,,4gSu#Rضm7={-,&Ϩָqc 4:vUUU o+S}Nr4K~{V\@ߣECoWLӈ&Z;|5W^2%s͡^2K7U#4;{,8:֭ТE 8q]t9@M`=L8ppp0*^///4jTQFرcزeѴ666Xf m6;"w^̟?eee0`,*K90FRR0uT9rDﺦ_᭷B6mvZv1}kDиqc+ /y!//lmm.rrr˗?]rosi͛P(k.lٲ(,,4^y5;w'uz&j׮,Y/_Fff&y >iii8z( 11RKHMMed߿Ԗ|3$+b̆qww7 uUݺuQ0a~g~ݳgo[Yfhݺ5"##ѨQ#t֍-۔k;˗ xi&5@Օhݺ5[[[?ĤI>oݺ%gSu;vٕ 9ƢshӦ _'Ύ.!!'|[na&;FL>K}'R}RHjs1Ԏt ) VYNW]Hp鴗 o6 ;w.ZbÇܹsXjk;w+d/tQT(((@ӦM`?""{+?}p駟⫯BYYg1^x! Z녥R)O'OӦMsalٲNNN0`ܹù޲eK0誴cǎxWo&[0 Ν;07on޼O>)$$$`/iXr%`׮]F ika8:.|cرc=5 2 4_s\]`(6BA,t<ۑ#GioooяׯGHH222py$%%q_㚥ׯ_+K_;HRJAPAAj#I˽Bȫ8 BBY~0Bo1r?0uԧ-6mPc|( :iel֨QF=|#F?Gnjl^ʾk?#yl۶ ClkԣI&ظq#z8?$$8kεѤ$[.Y4Xr%?ΦꫯYf_z0ÇADh߾`%)QPPb'((2쌘lܸxQn]l޼<<;XV?Kd6_?m.QDѣGc={6***d0mv76v߿l{֐\$AH? ϦvܹsDdT :DYfgϞ?>MGGG8;;ݻ5֨w"<( TP(")  % @!@ݹ.CY!?b,x06[0u\NO@7o6ݰasaghck׮a͚5pɒ%hѢ.\>| r΅W/[R B9׫W/L>'NV GTTRRRfj+.]Bqq1:ulv#Wnn.nݺiӦ!##͛vO?B޽{PEpp0NbAPpb 6 ?/_aÆ!!!طoY*,2kccA5:a(//رc9t|coP"qIFH? ϦR)qU7ƍCǎ &(--E1b k־1Z$#Q/c$P _.**)4յ?xb1us]WyǺǏsRVVf<(((-T:yc&|?~lc=Z/aذa8|0o:HNN̙9?Grr2ȱC޽yfNpPBap)urbĈh׮P^zoPZZAELh˖-xѼ BaHo߿oٳgk׮z׮] GGG <\ӌ cڵ SLMcs GO@|A֭[IH;o~~>JKK#VR*q J{.** puu#^z%yfj9tPg̺yJJJ6BuԸ1T:ƣGpe{MtT+ ۷O>2$!m]QQ/4veza8v=QFUVGPVVJUmPYY`NPgsƳ 4vvvƝ;w >K辝&LׯW^ALL Pz(/ƈm "%TJJErr@*Z ֲLr?AXeNH`Vm/sma%/sRSSm۶:t@#"2e  a裏>~7JLL$H~)t;v@@]t~Ih>\EEmذ<==Ɔ6n`s%bg*6gΜ!DB۷Ԇ4`ӧ}4yd ֪Yf[oE111tqN-[P-hт^{5zר{@NNNP(hԬY3@=zGe̟?Ptt4]xQƍ#TN?> 6-[Ν;Ә1chΜ9ԲeK3f ) N:S`N=~'޽; ___ZbP-瞣e˖y;_XXHo6i4rHziٲez 57<==i sCԶm[6m^z:?~Lm۶:udooOqqqt˗ӎ;hѬ3g$4x`*,,Sݺu s#k׮%DB-[l:}4T*;vƍޞ<<<8cŋLϧݻwzu2e ]v=9st0V?CY"<.\0!SƘ̇"WWWjԨM2yѣ tT#GpIedd?K.J޶>|0999QÆ ɓt%[[[JKKmwm];UUUw^ GYYYc --:uD(99ɓI=:tnܸAf̘Al ӟg"cwDM6ׯӦMb󳠠}]6m͙3iܹ4o<8q"M7F9}NU@QnӐE.?-˜'j 01ތFReZDzhkmIDsU8uoc_pww>Ē%K0k,y.\0MP ''52a@QQ\\\cܼyO )PBD?PQQ[rկPtgFyy r666PTH$(.. իs}NYr֫8k)׮]T*Ef ^x=6)5j !!TUUATnݺnh.QXz5|||)HvmveCcG޽{ _S%㙯n* EEEpssCEEѥ}BqPPP븄O^ScBk)Dc۶m[TSG=*@8{%\.28:ǏE߾}7 eW)(u+U_9CNk47킳`1۷o7k6L2~~~HLLDdd$֮](e2U"w$|m/ IDATHRgV Oa-,a,~5WիgZ[͗뗱~ذ?tGr Ə!cH~3S2k7z:$[[[C/z|b-}쐞[ .Oh[kcuu0Ac6,_> _?[2&H2^O^ScBk)D,C JI@`rJ @ PrM(gh)vm1e7J c \z<"f狍Enݰ}v[k ڛ0ERTs'ڸQ?kk1vXxyyaڵ*,"R P" % W)V=ţT{CS SO|?چ7;b1ŠkkWBIT*qc 8t}WZZ\tXS2Ն>OUO/JKK9 eqP'IQQYq O7ܿrssź)..fFzQ 0HA A&lm)psD{KEQuSƑݻ`HOOp9c 0 T p$"++ aaa5x,|ǣ[nXx1Kݻw7Zc֬Ywoo1??N8 6Pmۆ bƍfIOu1%Sm6=k7ƍ ipE~̙31uT˸qF޽{];uf̘{b6l'uff&z&M &L>ǏGdd$1| 4ȠW_}6m3]RRa?~U/"bURB&aƏTDTb/!2 YAځY׮]Kh˖-z<< Z;QʟDs o۠ 6D f"CD.sttսf1d2ǝ1rÇ+.\xlĉVmSUUx>}ZTB7W* JxO .@TѢE y8 6^tXc2=>cGڤ73rrf͚UK&sJwɗ| ***/w !!!֫J\.ѣGsprr=/?-[DVV`׮]x"""شiT1==|onpՐv|||кukԯ__P?C\tB҈DR@"a I!2Hm8s^*P*#99gΜAqq1-[pAyKJJׯ_GÆ z!-- .\lMúuuA^M4A-L~ Xt)qܾ}o6m?Ǟ={hiSNa͚5zԩ7//)))عs'222L P2e sq';;ӧOGnn.VXGGG$&&b:t}n:|P(7n֭$uq̘1nW_}ŞW*qF8::"55~~~u_v؁#FK.lI&m۶XbxbHOOoy\S}KYY͛ggg>}ڵcg:j(++ĉ7 )))\.ݻvZ7}gl_|WtdggC"`ǎX|9BBBL=p9Ν;r\|g6:͛???>22R/O-@HR;44J5j7x())%K)w۶m8v;xyyaŊT'''t]vŇ~+$9HEe26Rdj :لm+5䊮#`Β9_2d dn֭,X@|5jDlZ\NTZZJ*ƌCTXXHDD_|yzz鵏U*͛ٲ(**S(%%Ț̌ʺ>lْZlIiiiGoeJ!!!JǏk׮T}_ΩcQQ;)**mƶQƍgϞ&k.JMMKZDjH$&zRMVVEGG }gTQQ^kӦ =tϧ 5DD4l0GvbTy\WF>4D=ԩSDDt@39F\Bڵc˚|>c5κtAO7 =z?GUma 2J%5mڔΞ=KDDΝ#O?i233 ޽^JK._̙3N:4j(Nb rpp pٳŅȑ#zr I#"b ͒ޢ/вha="Fm}D'Z^*1w\$K^?KBϒ0d9Բ%sB't QmΞ=p>7o B]va˖-ppp@aa!9b={ 33qqqK4=ztZ\]]ѬY3nhԨu놜N9_ڵk#&&K,˗ya 2t?,gggKLرcHOOGϞ=ٺi/0w]voӧc˖-lEK_(.\@ll,:w6m8q"8zΝ;ݺucդ>@bb"R x饗*ѿA sS}qeylڴ qwwMo6ҹ7+/|'uߏz3ND+Xm+]lmmmPX\|`;RQQ79.((`޳vvvѣڶmsa̙F~xhӦ xb)))VZK/^aÆa٘5kV\gϲ6nFBff&\\\pBwrr̙3q-tڕNڷoGH( TP*   % @!p1dJȪ1t4w:X~/KHHܹs9/L4m͛7G,_cpww<4_&gϞej6A˙:up+|j+B|u:rٵӀz&[p!rssѺuk}+mX~=BBB.hРv䄲2uN:to iii 3Pcǎ-2d4hL$$$` tR\zYYY9s&-ZE믿{n{L&C0m4( 899ۛuݬY36}~O ϟ7O7ozbeNSKF^>HP*@ \Tr Cd,}u^!26c溮tu?>|"h \.GAA/ d2rL̓:e o#luQ;wΝ; "=#J<x'`pww7?tPf͚={b7ksrM#a⋨[.6oތCB3>ζ~Bmc䫯?f͚gȑ#pssjV> glGGG8;;%XVC^^K\ǏiӦ:JJJ0 gvJ˖-CJJ ٳ"%%'NdӨT*_|7cӢE v?%!$$a7omLf4Cxx8;,݋?9995kƏoQ>P J"@@P@"3Dr% WAb`*vбU5i~/CP`޽&p)\^^ ѵkWDDD`Æ {245UP^{T,< ,> FeJHLLիW1n87;v?,(:UÆ ?HHH@jj*ۇ.]]P___ܾ}^.ɓŭ[0m4ddd޽{ؼyXz_m,L^STko߾Rt,yƪcm3f`Μ9F cy_{5ܽ{c<\t g-Bܻw999G … 8AX{q 7n蕷tR`:A/zP(hݺA222XGBgtCE>}p-|GWH!0*@IJJT RU*/T$f 1kD_PٚKZYYСCC 4nBNN&MĮ.//JRPYxW?\v D|TUUq!_}M4}1zh\zuWA}lܹs?6)ѱcGxyya…X~=;Ci@RF.'LׯW^ALL ~wKKKvi}(888x饗͛s^Ngϵe2ՇWGza8v=QFUV)))amhҤ^OWoteCt @J'N{EYYr9T*oHoaɒ%gǏ9F棠}]6mmٲ$ lْ@RvDhʔ)t5x̙gue4ه:BDw^ GYYY7 .-_vAGfjmYglCj9sP`` ͝;͛G'NrzUUeǪv[iix1mۖԩC=QUUo^"yy!dˋym9s&1JJJWT4sL?~<}W4p@}6{o{{{jܸ1}G4{l\pJJJGל4DjρڷoϛN俋uӽyɞ;4;[Mئfg}vh~Tf &s\I׈HRctےL\\x{{nj6Ƶk J9%u¥K JѼysԩSⲌq}Ass꯿2k.* EEEpssCEE^UtNP(JѥNLauup=A|1R HP\\ X-掝ԛc+kĒ%K0k,AE[l۶ qpr%PQ#kzpqgW[wGeCѷo_Mpj UO:k~9b 5LD ƌqdi5f'FEDDDDDDA())1B/n:tѬ}v"4xJX+.Npn 3X(/.&s KP-\缡34D~2P|DDDDDDDj=z ,, 9rh P,d "@*$ V H$a VS_\!c{t;d-/sӍ7$t9iDDDDDDDdɒ%puus=/i#RK!!02  LjockR HXBh">A>,̝!"_fg!CHq$[6YDDD`@0 $R( AL27I !oufEUH1eVRB&aƏTDoR@"G1UffcJO8q ĥK ]ܹsl 'r_>=`k JKKW#eĉ'fQXX 5[@OQ?viqJC A"@¨I@!FFa*X $R+ue=o(Gnݰxb|ӧwXQQQx뭷/`ҥر#VZ۴iDSƕ+Wa0vXO>hذ!뇡CB*C Add$쐒m۶UV`3f FDo߾5zSh׳gO-ZYYYdkkh'DBק+Wp)Jjժ{GEEEq:uhذa\ IDAT[iʕDDDɓ2=zDC B#f=233Օ&M HDyfjР{lN׮]Kh˖-zu֭[ǺzƇvS&M8 vJ*xzzŋk-"-/=*++wZ-k [? !:gux}` !ƍRuz?E4Y|{./Тh|#NYњo"YY;h fY;C$tǘ˼j#((:ꊅ 8q"Zj@=믣SNsqqܹsn:ܹ=/H0f0 XrǏꫯm۶GGGuuLiXo |A$f=4} 4h [u>gN7ߠ/2{=!!}]ʵ62LߞU -[m'>ӧO5kցa+HĥOM"0~EH[ա6)mfͪۆm >6')@*@"(*(H[HUl|3?{,ʳDBoΐ ҥ -- .\oa4*uï\hz شi缟k\t #F\2ؠcǎiN$o-S={ŋ0`ޫVbzk fϞ:L{ssΡ\\2رnnnEqq1RRRH\~xbtKI'Mݻ]vzk0qDxxx]vp{XSNaȑ1c̙777[N\ff&JJJ0vXL:رcQVVfLc޽Dhh([_8p ==IIIXd """p9l>وBPP~dgg#$$7n| ">>~r0p@̘1SL'7n4ҥK;w7իW` l|{A 8'Oի燀ܸqCOѭ[797SOPoB_jhrӧ[w6ӭ},$*(JJ  U Br0dJ]2'wɜL/ky𒹶0d7.#R/q#g:;%%dUVڰa4NNN8p,YBDD&L h"z>}tK˗6mZ/_N#FvqM/##CP:kcܹ֮]wWOii^zoݺЂ ÜOF(<<^gDDk֬m M:PTTZvv6Gk у]vcA.Stt4J1cƐ+[^ƍ)88رcO>>>TUUśJ!!!JǏ;wꝻv͛Yyض1T9u7UQF]RQQA 6ÇLl/<=3zΰ" n➡_45憀 n&/ rbj(K\3 PT 1ŅL#DpYܹsg~s=sν=9OSQ9v_M)))|0Ξ=KDD?3Q0?\]]ӓΞ=KO=z;n֭iҥDDt}>}:5nܘT*`޽{:t@:tL*..;ĉye˘|kͥ`rvv>d2{"KEݔ{/ǏӍʵ:-.X(}4&s;~٥p)%eb R.mIrd]t&sɜ L0󿮣%١Z/rvvv7FٙL;]钒pǣG&}7 ݡT*qm 4_We97֋{}̜9gΜ̙3߼<vFIfd2Jqii^D(JHRkQSSdee?ܹ {>|8)_`` ?Dhh(p=۷ !C޹o999:ɓq 𦣍2L6 ׯӧ닌 lll͚K:99ݧo߾7nΝnݺq6'BAA||| >3mh͛7G@@wɒ%ƅ X1Ɔ cǎ̡C֯6ׯ.\+[_~ ~vB 8a,iϺOC{Ur6`<{6*:`NLHP J"@@P@"+ C]kOacVc0;s?DhX///lɭJBii)x[[[#-- ǹs_СCym늺,GEEEzq{Ç̙38qr+1h ι4Mo[*ɠDDDwѣG1p@\p555dw޳e˖h׮]v C˖-5f+\"N#...P##yyyMGceҥ |||}v"33+W~-Yyyy@~~,>b xyya̘1H<>y$[. QQQeV@@lll_s,~)lݺ'N+9/%X"B>=oM'o1v^,{JJ:.+bآ1VJTJ _RTO} E](D^eń fȤ½|a5Ǎ7x@PnEۢE رFXX^z%SkK ^+jSnݺg6-[ѣs`X6l!C`ǎpttĿ/ԫW;wă0rH6G@Dѣ舆 \R<|Iԩfm#&&Q~}κ%Kk֬?}L&M?d7w8aj=֫W6஋رcADXp!K"""B/o"O_>7uQ椧ou*PiRjE!2@*\TJ*ȕP($+v-Qu`*ф^duH榭 U۷/m6ܾ}7Lyy9pܹn۶ vvv5k{NT94hΝSN=/&k׮Μr!((۷oǭ[4Duڗx ۷9_.]ԫWO0{ڵk1a?_52228m۶ŷ~?( {M<~={49.]tٳbHd2İf1zfA,X}͛79 \.ӧMK.Ç/d.W,RѸvf̘3fW^8v^X|Zx p7@Ի9i[].Tg [L?wR5J@`rF @͟HZ{76ib`2"sO3{*ΖRRRP^=5 w\âEsoŊ ",^ʕ+Xz5/^6mڰ޽ˮ&11}5'Bj޸pV?~I&{OOW@LL ;5ʱi&8::bzm1?X5q5֦"..u hӦ vުUx߿&L.((hԨkڵ cǎţG7nի={6k ѣѱcGqkjjLtύ98t{.77ݺu믿n0*L:׮]U'''_|0YRgggPRR TVVBR_LƎ}+Fmmm;_ŠAص5W\aX"u%u Urjh#&=pEBuWnmP\ Q)UD+(VjD˭cFe5u1뫨.sQPPlْƍG3g$___7ocϲ2 POwߥ=z9oN^^^ԤIJMMջ[hȐ!z/\@i#zZZyyyP 999Bxj7vtBFaÆQ>}ޞ\\\HR=rܻwLBm۶ZlM<Qjjc7cۛPϞ=)##JKK)..0h"1c5mT/4tPJNNTZz?3I$ѣt5Qaa!{<|nJ#qFxbر#}d5k=yh;v=]xtBK.oFPK.0nBeАM˖-㜫"oooѣGӑ#Gޞɓ,Puudgg ? ʊZh˜NڴiCڠgϞMs̡ РA8NϟOhєI{&LՂwߑ5k֌N>M?3yzz effա)򭡴~m3gE>X<Ԯkϛ?\=mPzDmMM ˜ ՙvuwmj㚚awTH()-+S7}Cuf^zjS^a ֥tׯ^ЮfyAwy|cO2M60'=Cd`cB'Tv:3Vn6(CXIHH6֐ZK!RH+k@T{s6K0U!29c62n ‹#D+OT*ܺuݎւ |>Im0`}QVN2x,۷o4r(9cBeeI {V<~EEE syQ]]K. gL Fseņ #+R)@B#++ :$mhHQm"3?AX|A.^ݻG||)ׯ_Gll,9_]] 0 I$QNΞ=y!==֮\tػw/N:N:`~ꪼBaÇ0o<0 Te˖o5k#F`رJhӦ [[[l߾]tCW^0 BTT !Cرc_sʠH3f $ ov{k׮E߾}닼<';w aiӦaԩFn0l0W_}ۃa 0ǏGXX#GԺ"""PPP ӧqF^Cpbt!ːH$طo^/_Ftt4Q\\,a<>}aL<`Sat{u!.\j*III171رc|.u]ϊݻwYfرcYKDpp0Aaecr. ›o)))ի6lJ kllѣ bׯGyy9̙3ѣ6mTAei?MBdeeq](**۟w6,Z 0P R+I @eNHq^+$|X1kcs 9fE-޽{Zhqշo_JNNhhРA˹uVڰaA_5Jݝ='$$P||<{\^^Nvvvc+W.k2`7mD(--M/+uڕ= 8 &_~%_^t8"@O&""JE3g$TJU&2(J֭ܰa(,,=VTE_~%{.))/ ?!>"DQ,W\!ahԩPFhzNwI 4[,H$K/˗9aJ%uܙ=ֺr'n}Qii^P֭ XB=QYYIof?cruu5xl \NDv&8vXg*;&[6n?:ԭ?c<~VECNhɒ%f7u,1 %&&cJ]w%["3N:QLL 缘YRIuMGG`3ٔ.ݻw) 5jdrׯSllu /ǬfZQFSh·N4Q%6^s:Y}cVw<%Ǭbf iqb1Nl>sd2fύ?_|4Э[7j cpp0|Mxzza R q Ç/P*}c>.]$|SN챣#63g%mN`oJ%+Qe*D"A9~7\r555=C4u֭ >6mڄ3gbOmr9bbbe˖Dxx82I$L6 $$c HкukXl[ʝ|2Lk߲e F)cmİԛC&5'N@@@`ƍ(,,D֭ѵkWKo޼M6qfj[ ֟555O?d= XLKiWCuaϺݵƘ1cлwovL>7oƁbf]$ n݊;bĉ>jjjuq+>jL)]>'N|?Kt+) IDAT6l(nP`$j9FPVpCd(|mA(D Iw|8{\RRٳg޽;k-H0f,Y9rssiӦ6oތD( ̘1 .b˃>}_𺵵5z%:!4(gѣM64+o;??0h [UU"!!2 [l s!\x 5+S6me\t &M\ӮOSZ[ѳgOte>>>Xv-g=JBFFo]c鈏ȑ#1}tvMͭ[гgO̘1>"##ѩS'dee˖-ë*X6m>$Z 8<-w_|t41y!44T9u(TJ{Xb"""|rЫl5 .6n܈6mڠ}~: %%Ɓ0qDTVV ڵ ׯGrr28yV*xѲeKtܙ%55ڵc_MEw,15=s3H,Ϫu˗{}>=g\~}l޼%%%x7z ۷g s.wCرÆ 5c2hH~"_}ݑHKKCˆ7o  "%TJ BԦrr@*j u?/~z 77HՉ/)駟н{w{(((@EE1yd;֬]z555ܹ3@P &&Ά.^t)뇱cbҤI8r;C0 O>III.o||<_ooo"883C%\8<;UUUvm¢EФI7cڴi ɓ'ѹsg޽`cƍXn&O'OS*())g}X|0Ν;MbذaXf׶/Zj.\` ŖiĈxw+WUmM:Μ9w|HOOGpp0RC" A˗#-- Νȑ#OO>ŋq5899a7Ibuu5Ə޽{#..AAAHLLA޽gn:¬Y A!+qƲz6lh3*sr9ARBPFF%MrZxbLp*Fs*XzmbϭX^^^.@o>@-[]vv!,, -[6ovrsspB,^b R͝;o60h >\og0?^t"--ͬ!))0z Ts"((3gf| :ԠMQXX[V2 NBII R`ccNtxի3g`ĉz/$bMp;wάrx뭷`|􄫫+4h eFS漼{ݔ1P Y1uIʼn]ֻ ƏpDFFbڵA899)cRƞAbyVF> تRPZZgV%vl֥s֭[1a̞=L0uINNFtt4555RԨ"nL~d… {ٹggg ] EA FI@`rF @͟HZ{76iΔ"c#97LQ˖-/0 狔L&C&MqGII ~7#d2уsqq,rLLLDttt[^ 0`Μ9 bf'՝777WrpݻwgH1B#FIzjBaSذaϟ# ƍCFFǯKn7CBgsPEرc\L[[[|HMMyrrcw VVVpܹŋk%K`ƍHHH@@@%ȑ#x 31cBf@p[B{n+ǚŴݧ~e˖aϞ=sw`.%OM]{³n]nܸ{ 5akkcΝ(..?~diqcr>L?~I&4ׄ_>>s<~&m[aڶm=z`˖-edӦMpttѣm!LwmD`vg4_~fΜ txȑ|[nxסR0m4k*{d?yR}QN:'O ==طo\իضm#ԓ'O?s>TUUaԩv효1Paн{w=Ȝ:*WDDׯѣGɓ8qbccٗldPj ggg'v3oooEԲ=>~cI&LKĤ7RAAAA\]+Vf`\իWchӦ c..\@RRg www̘1;wژL6.+7o7n T͛}!z"={ıcPQQ\zo&1J___Q`+`J CBd @Ja_͐11AD Y@cV"b:t(%''Sjj*^M...Ŝ-ZЙ3gH&ѶmۨiӦdmmM;v{qCjذ!=yD[nzrqq8h;w3iÆ {Qaa!>};믿ʏPy())***&DB=z _7={NJKK)..0h"# .Ptt4 GGGZ|99cO;v$ԧOo+ē'O(,,<<oݺEC ;/V&4̘16mֹ! gرl#GP>}زi8^xtBK.oF_@`;w.ӂ ̙3Իwo@t ?|ΎFMG!{{{ @{.sΑ=5oޜ-ZDT\\)Kaڶm |deeQhhh밪`jjj(==\]] iӆrss/++Yftiӓlll(33ϟOht=_uִvZڿ?M: D":йs觟~ۓT*y6裏 ֟)cPz~-ߟ'[;3̙39Y!($$BCCO>w}z6f]nJJ{e_xƎKPloMeeeil 1K73&ӆG,qQjԨQ\\[4`475lڴ36Yx8fM~V.JeH h^,X0 yg)H$`@*$*VVRXIXY1Zi:&:h5%Qr9FPYYiR:+O<1Yܺu %%%#ȺrZ֖}YQZZظq#kNy.**:t[0ĥKkUUUۼqkؾk*~% :!!!h֬On4P_EX({Xv- ___.իw^:u :ut\ʇ:^㣱.^ݻG||2jÂ;j}Zcp+a( 0C cDGCII """Я_?\k֬oEAAoGJJ z 6N/C"`߾}4._h0 ӧψ`L6 SNEtt4uVL}ff&0 ڷo 6<1WN3`$j9FP\TsψlM(|m11k6cP;Ujv_Y_c֡U+W04uԺE?&WWWQag͚EիO>PVV'lvv6ʼnJiӦrJGh͚5_vJ?^J}6{cY""\NDDTUUEcǎ|q ~***hժUΝ˦% ˣAuwww:z({@#"Znmܸ=66mD(--M+uڕ= vvv4a/׳";;;*--KԺuk@+V`'%%,1t[W6߮=4PFh$9vI 46ׯ_X։-ߺu㛋n.iy IDATTUUEDjxc}U1c.Æ 0XRQTTldggǶŕ+WDӆΟh,wR-8y߾})99`ڰ<<\]vqݻw:uD111YYY$H襗^˗/s)Jܹskk(hJ?~Pbb3i]>ihm/#%q-JJ/Iߧw!Zt D#Jq̚ÎY_c֎P;faǬ //Ǭ01k]n2@׊M6a̙ؾ};ˍ'V [YY޾߆D"|a0am6N={`̘15GGG߂DFFb޽^x{{{ց^MM """O?qœ8q3]rhݺ5v튗^z zVe͚5󃃃fΜ: 77MK(>֭ZjWnJ\'N>|(͛7i&,u^3g 7|px{{qCBB ɰvZ[lѣT'ʖlul*,[L?Fdd$k}y@Æ @`` ^}UlذAls׮]>}zԛ>ud27S닗^z -Z0W"f~Õ+WPS6Ngx^X>_~J͛`x>y!3~x|'Ԇ...f}cc+L ୷ނR4cVFb =fBΝMƌ޽{#""|6oތ% Ma1QH$zNM [~ ֬e)e456rZW8!{0*@IjJT RU*t$ f˜L](D*(&ILUU>|d2lٲE/Lff&Fy!..M6E͑):%%%={6ݻs_nP^^\}/N xE ׾̚5 ޽;~;wƍî]8 XlJJ >`ĉw_|td ^^^h۶-{,T$ ƌ%K?Gnn.1m4q͛P׍ՙ ^8󃏏֮]YRA:ObЕ ]гgO˭Cŋ7]۴Xڕxb DDD`\^^ӧ#>>#G֖EDD`޼yk4Orرso5I+ٳg1yd̛7/Fƍ]vaHNN*Kvv6Fw}7nD6mо}{\~7M_wppmذz\Č=0`iӦFRRVZ7oތD( ̘1 }y;rڶmykӦ Ο?o/mL"Ŏܾ}z zcdff_~q :8ݼy3˗n>sM6زe .]I&q񽤛xVY2gQ?ڲ={̫!95g9/4*sr9ARBPFF%]KT]#;RL."1'TdΝGӦM1l0YFO ҥ {ڵ 8p6m'B@LL  ??? :0""7n_~%fϞ*޽E_7)]v!88{EEE ĉׯΝ OOO2֭[_gFfM63999ݻ7nQQ֭[Gaȑx"o* yyy2e '_baҥׯƎI&ȑ#3D0h_,δ9<;:3gΝ;t}{Zʆ.'OD\\/_nݺ[ nժ޵B\pUVVM{ذa1b0g$$$4晈0h cHKKùs0rHNN:͛aaahҤ gfh۶-;o+++۷| ^y3 4@rr2bccT*1VW^y욧'N@*bҥrhu@*22 8voeڴi ɓ'ѹsgv P]]ǣwވCPP1110O$-7o'^Q7%GGGr=+辈iRUUEI&7n𚵁4h_[y988ɉ]GwyiiiXr|~ظq#֭[ɓ'ɓ5SXEh˞C2m3N蚩/:R5J@`rF @͟HZ{76ib`2"s/> ϔeddLk׮!##͛7СCW_}K,Aqq1.\`.;wBܻwU~ k"EE)_|H?~<?7n@VV'Ν5M"zkذ!:v쨧4352V0wlKJJ/yڄwqq;WASXEhޤIDg5S-_tTJ$*A % jEkPaL?d>ԼeP|8HO:R`cc="a8@@@lll>Ԅk-[]vv!,, -[d899!00w;777"22+V+WP\\"#&]m{kW˙3ge˖8p 'O@ti8pP99r$N>wΝ;oLKJJ ]\,\/;f͚~6bLd,--h[o o'\]])_ Lg)Fn5tx^za8s &NSRR83%*?#\\\8/u!_")) k֬kgb&ՓǏGxx8"##vZvP}ĔE=8f͚a\~Ll  2"2@ '\+$EX*7m -{9tܽ{DDDcǎp`vɒ%ӑ'Hz&M{nF;Fd޽{CTٺukj 'O4] 5^oFaa#F`ܸqرc&NCOff&jժWWsQ@jjٛ{Xx ##]-&&.\ 5jU 2`KKVe]vmq{_vWcTZׯ?u݆{XnܹcbqJVsު 900D'OnYYYqNN5cƌF#x&Xۿ333q-L2ƍYX녅S[ԱѣGf[ǂn9}4A`cS*(_TTo*`zz:BBB8ڞO[ܹ3:t耵kײL1退 07n}vZrv1z聩Sرcf+}ڵkꫯʣ=<[8kug:`͚5T^EQ1S预\)\@d2*+eHC$&?"&XM\F8<3\R@&Mжm[YƬdeeۇn%%%2d|Njߴ.Lܴ̞(_xx8i&6޽{hsci<1p)՟ݞ/FժU1p@1ٳ`ٖ+W`ѢE5kYwӱ@||<:wlnC*,,Yр-e_c5/m=+ c#92rE "GjldaV/c\ìf S(0̺zjH~:ڞ={qzIw!"vQpp0M2>#ѣǸT &xb*--oVJVZfM ,_vq|2M6׿Xf͢-ZЧ~JgϦ &PII ޽BCC jՊ~"":wEFFx_EԾ}{@ .R1cXڵ+ݿӧ͍ׯO1SVV{_~!BA7`CZbx"tb֮]KDD*֮]KޤT*iIoArJ6m]v\ޢ֖?̶vў={ݻ4qD1аaUVϟϹn: ڵkӒ%KX!CO:u"@[l͛7S@@@8p Ӈ:uDnnnTV-3gH&Q۶mŴ}>|66l@Kǎ7n;yyyQbb"[>rsswޡ&MP\\͝;FAGK,3;99ԩCߟ҈h|E 9sΝ;if7|i3X|9^ZP^֯_OnnnTN` ח-[FIII4j(h4}W,/$OOO[.?~Μ9C~~~B)))7oޤڵkSݺui锘H7oھjXGͩcǎ4zh5k5oޜFb &WWWEGGÇ),,׬YcVeTG)eE{ Ғ%KhѢEvա1b15fJD-Z ԩS'233{԰aCz7iܸqJӧO730C(/>mRRRǟoΝ;ԫW/EQQQԵkW OOOVkhwM]v%G˗//1eرmfh)<$vҳge`uw7ilZ/%P/3i؆>%%%fZ,]CV#335T\\\ U|s {.E 兓'O(,,DNN4h hCF )ݻg(J+"##dI[5=zD̜9\L!"PThҤ`89996*vr9>}`ܹV٪T"Gj9t:d2ATJ2+!:_,fm_o7oDFx[jqZ*CHIy'2C.iӦF+WPNI|YTZ|XG{(!"T*mlY+&iܡ2PiWKQj<5XXnRhFHi!mK:B1!yR29Y@bʕGbbKٺuG"?0 M"kfƮ>!t|0ada H-'f"knl90/dDђek=] iqsscDaܧ%7PG1 Iy'O 12 7⋒V(U 7HjMˇabcqݚg Lr@cPȡ3P(ȕWE 2r9 #" -8~+&$c IDATT!BG:hI su:oSj-Tbp`)a"[d.~n3gK.I?1m4,[ ;wFhh(Ξ= @ְUV`=z4FaÆ!((5@?Yf`ݺuСC={b4ڵ `111HOOg#!! % صkZn Lm۶q]|Æ 03f Ǹ1 ¥Kxر:u0#5 00[n\/_~駟0c L4I4ok>i+R:5N_/^^z +Wd zuE߾}1drcG*Un:^z à}5j}7 .4{ֿ5ugO?7n`ȑٳ'N[nhР|||0~xgii)jժa8Lff@y#[N7/> 8jn,Z?;-[blkJOO />klRqd>?k0:@KR Zk|QBX.r!Xk9H7fm!luF>sSo{jܸM~CNG-[n ?ΉO;wu'f1SRRM8,wܡ:p`G,w^ds˗9״Z-jJ0+WXBl۶ ݻwͮ?||}} -XuRS 8eչsgZp!oاߞoM[lӴ4rqqa nͥ-[R\\1Jo˖-b m Rի ڵu+,,Yf'_j> ٳԣG }!EGGѣG M:W\Iׯ_5{GcO9ً,ਹO}lk8p EFF:$.{pd>?+ NZ}Sмww=zw$F8(wQìaPp 0k },kԄ :bHf,(|[ #EnnnSV-6IL޼yW\AY^0Xp!X?{:wR˗4h`Ϟ=x嗱rJpmڴ cƌSiL&ѣ0 B51#| ƍu!??OjЯ_?T*,[5kɗoMlذ* Ci[Viiii)x oߞ5jO?ի}vqD5i* mӧOǐ!CгgO6ZwQFfwI,]aaaqмys"""~~~񁏏N8!*WR~)'cun:/: [(5WT.\V[@@`f͛7ꫯJ˖ c,@h- d(j PxK| K-tGo>$$$ 11:tsxeeeaܹ dx{{#$$ )4jԈ]vE6m8;u$%yf~cccqyt֍-I,=<Gfƌ|_sNyM%fckBxqq10ydT*YF00`ٲes[:{*ͦea\h׮`XI&ܹs*[>ֶgmˈk:tMR5(n)XӶ1c4 vPBugK?DxxЀ-ҶmWH  8ӧOĉ#%%ߣe˖ĕ+WCCCoƝ1c`ҤI߿?ƌ"0p@|XjѬY3ܸq i&X .DXX`SK4W'OĈ#0}t̚5 ^^^8qDQQM `РA?CxՈFرc1yd<oC1p@̙3`]4 $%TbOBajo]RNAA@#4Z@џ%Ғ^F6g%F KҗTXsX-޿CE1qDt~8o߾x!/":vW_}qqqǁ޽{`.ѣG#<<GAV? KJJªU|r1Gj#GĀxQvmΛ˗/I&V)Ǐ͛_XqF 0ӧ.]*jܸqwG0LNNFDDr`8Kea\c0s=ǹVZ5jf*[۾kڊgM^xP~}޸<<<鶄mڵkVZ8|ԝ-Zt:Ξ=wyzFFЪU+ݏ`K? oM6aؾ};oЯy{{͚54oGΝ%":tyf>}ϟ?ϞC=|0r9̙@3c…9r$&N:pO-\m:+ l۶ ;wċ/7x^^^vS }A߾}1qDL2'OFZZe80 / fy5kĢE-[J*!rJ7nf͚f q տX} r7ͫiKY8B2 c"gPȠ 9B%7ZjT(Jb^=*O WkÆ cxzz <^:Zhy=z4_Ǐo1%ݼy3<<<˾mQt@rr2̙" 0 jժnWd2*:u*1rH9r7o#Fŋv 67L bҤIl gt;ի u/`ի1l0X* z>|v_Jݻf*[۾kڊgMg[nKX۶s-K;[lڴ QQQ ⽞$]H #ԯ_{FHH^~e̞=YYY?Ǐǯ og̮]p vS(CJJ >5kqxzK.l8<~6'ͧզs{6mЬY3W^HLLĥKʧ%݋K.!$$C&M.c>g;xyyZh:u@ղ/~闀~ wnvPշP!wӼ:<- '&02@\RO{bvK妈Qع!e/mcg͛71o<8qsϿ@`ݺu lj'аaC4mM6Ett4,n\.ԩSqqbʔ)fV={wOح<̟?_5,S9r$ .] @GT*yfxzzbscǎ!;; 7oN:,^X4w}.]ݻqeԩS?h5ԫW}@7`Pۂ5mEj[S|it{.Vli|j\z[ۿ-ܻw;w|o*fA{;5Š+1 i:ujժڷoSyCŀ ///UvK=/+ge|Zȑ#l|m Ge׬YӪmx._lUo0bm8]N,(d`d d }+]++L_%s vSV  _bM "IgϞUVaرՇEyfܻwP*GARm۶` ΤڦMVŴ9b}ñh"08G>}[Z-9" RiР֯_DGGYr%f̘:Cر#|MٳGn;#*U?ǒ%K0fgv !6l[~~>]Ưhmֶ"VR^lh4fڶMtjsNR;[NG}/l@vv6n޼)z [Z*@fԨQoQXXJOOOްjw(iٲ% d[K_5Ν[",, 7Th#)qroSNř3gp=z 6䜻 0Xt)nܸ3fXW[HiKO< 212A A!\,b|VYU$k"{, GVsiभZsbbbR.@&M{nV'Fd#,X???s] D`ذa?3f 4 F!]oo>- wwwȑ#8|0FVZ9>N0ĉQF h߾ ^zؽ{uo0bm8K[ƨ;drd~[d J#t)CHq -XkzH!lzJ-`n5†Y'[2U\\LJ~rssh:rZx1>|ڷoOh…TZZs;wY~-UZPZ 9sd2mRyԱcG=z4͚57oNG&FCDD7o@EQQQԵkW OOOh4qFjܸ1nݺÇ{̙3PDD]x7˗/իW^{Ri0fݺu@kצ%K]sՋzjH~:={tܹٓ#!Cز߿?uԉ-[$)cǎ%oookdeeQ޽i…dZhzzz:1 Ck׮i+R:5C(/>mRRRo6ljժѣGu[ۊ)ֶ;wRPP-ZPLL tcTܾfrss:up /ۓO)$''S:uSZZC}q #4~x~YKKKi„ NÆ </_z%Qb/TBaȺfftVz̡ޣwhj т߉V\!ZMUQìB0kc) zAo0*$y1&M?2p'S!y-7r3oHзw "ǓF3JJJm jڪJKKQJ3wZL4jHT%G3gQqM4jHTUyaxCȗJ^^E"Jj;Ç ޻wloԶ_Qh4r ԩjirlR ^H*RQHH:uxUV5r4nXru:d2T*ιnZRS1jؒOrrrΝ(T* //[l͔H헝;w+O>o0Ǩ̏?]1q h]Ju2A=^x9:*L>} ::z2xlH[[3'#7}`^LL5HX ol0 J/֭[Y=b= x00d뽥j*8pSN Re׮]l2L8ŭo0Ǩg @`44IDe`b瀌 I>'&?t^HbODo߾ tll Nҏt:ANc-[1c|ʆp}644cǎEtt4ڶmܽ{v 3f̀/-Z_~ݺus`TZ:hZ Qel \[nC"3!)\Dh 0 >}^zN'^xwšCK.Y=d:tRYB#F012htNg@)WT;DB?D" XLmSXXȱdE)33+g۷oegg_~EG_ A&tZ5:Дi%gJDc1}Ɨz<\v9B "K}b`)n3.]Z&^f j֬~R0ضm|||;4'̙3ѯ_?e\k ?#֭[|8?8ܹz˦=lgiii uXyRO?r%%%x"Ο?~-[^/(()S0j(L>۷oG>}V@DhF FB^P*.Y`RZ~$Y+}Iތ5IYVZhٲ%_PحfoTT>DˠBaLD#Xi;ʯkmw{QۚOe2#V+Gԯi鶥O~]V^ReJYY u3-Zja.Z'Q6jqqqY&,X`ftu„ WO3.)۸qctߖnذ* XCᅲ>QFftP8|0떗OOOգK",, 7n7o4;CtЁ ߡC|wVUVAVڵk /{hZ6m'N~tA2 c"gPȠ 9B%(@yP(MRRS+=Jwԉ󿨨&L@:uЦM\p]vE6m8]CBBѡC;w~gϞEv0i$֏P'OĈ#0}t̚5 ^^^8qY6mŠ+pBIJP>,̝;/2/??cƌIп3EEE`j*Yfq`a취ӦM 0h ̟?&Vb@?DÆ ѪU+r4N[||<ڵk')4UVN.! 8ӧOĉ#%%ߣe˖ĕ+W'Poq_1)S=.]`Ĉl*Kŋ6oތf͚aȑŋc߾}ؾ};~m\zlSa&%%.\o _իr-**cN>ݻe˖pi[|Ⲧ j۶mCdd$ @|<gShvhҤ GǹsPRRb -!o`ذapy=nf7 U~}t:CBBjoѯ_?h;v`^h4;v,&Ol1Ϟر#  2"2@ '\+$EXzo%@/uP@C@ x @(^*z`2I 77]~} :r5i҄|}}j5EDDPaa!t:=z4լYrssIRQݺuDD'P~xvJcǎ%"ŋ^5kRPP4n8~:'eeeԦM|@ZV4^0B<1cƐt: 7y ݻyԼysJII,jѢۼnMu֍N͞=߽{wfҜ9satJMM%""zWvt S6 ֭['믿ڱcϴxbNz6DsAaa!:tPrrŴb4~m׮'?DDO&taIeh`ȑƛݻ0DEEEቈZ-5lؐΞ=KDDΝ#{nω'ܹṳ˗)Jp{m˖-$ɬs^^S5{t!4[;hh_6-Lɦ}_4xC:3Do%^ z7Iz?~2@cc!@Dz?2cc:!&U*U.DzH1]!$6S{Ch,:t(ѡC̛7n޽{qFh4ر7orssq!`ذa%{}hܸ1ȺۦM4k իljϟg?; "xW^-Z`8ڵ 'N@tt4\\RRRpaԬY7 /pԫW]tAFF`K{ҥK ФI: ggϞر#ѥK\|bc*{[o\۶mý{C\>>>_>z˘={67Ǐǯʶ~}{P42ۚ~s;vD֭quL0UTt6Օjժf[ Mak{@GԺ0ȑ#} <?h3`VOOOv[*KGFFb׮]Xhf͚%O a 3u...8pרQ#X~,{X|V-ķ~ HHHഛg5ߦy3mYl ,F_`)VYTV իWǣG@Dh۶-_ɥKbŊ8z(kGw?Ⱥ[W _54i3gٳ8txxyy Vq]屃m˖-P(UqiBu`))TVY?//'NDdd$ d}MZ*@}ԨQ;w.RC8HR 2D3g^Ü9s0h BAeϷ1$"M֭@!ԑi)W)cJBڵ1o<řY#[j<"V)X[4mذ!~[~~>NY*C1,Yuցa㯿ºu0a֏NG}/l& ՒGD {'0v=y6O>9s&ƍ'9"drdZ"9@1@ԟ1RJ T`r?um]vhҤ vލ|FArr2N>F`UV?믿fBff&nݺ)S 55999ظqhBaM ɓ[VV4M}۷9j5?.Zb,aoH2RWV;#`g-㼁CII ƌ] HR r 6 W^رc1vXKT|[2i9k>ܹ3:t耵kײJL1 e#e裏pAԨQ'O[j<"V)P:+BasVUnPdddݝu 8}'!!G2Va`Ÿ{.>{ *Cy׮]x饗0dDFF֭[y2B!B@` W>>#l|djC#G Dbx++4޽{-Z`Ȑ!xbbbp-dddGHH1 99EEEPt(++NC6m0sL;}#!=K5j^|v}pp0"""РAxEEEt߿?8v JPTj7b<[oe\ll,#G9r$Zj%Z  [.,,dRcL8Q4TVѱcG3ẁ}!""ݗ;`֭-))a'K{X4ʔnc*U`~:z^zW^fʒoj׮~WҥK۩Q]ƞ1M}~wj֬rJJJ-GSƎKlQZE/4o<3wkYv(88LB}у|8s~irssL񔕕^?~8?~<[wby *((0++c ZmEKܥ%rhAJ_E#дD ҈Vei̅eee.豬@SkXs-snA˜l/qTth4P(*ߦ ZUV߷iRec hڴ)\]-4ښj(-i PJ|\@T >pQB"'' 4j.l`ͳOeD箘66kBJurZ PyOTT{Pf A>}=%Zoo76 J$ * ? ;6Ri؀nmÄg§yI(^0-lݺa:pR? XPWښZ{n\rw`];wwwއTRÖ-[$gK/~+C o >tT|֗ /[Za"j(*46T*0 B'VqR:o)y,1.],g`,)#FGR PRI)+" iŎHoF࿩JN߾}U!g+VѦM^?RڙNÝ;wX,[ Lj#] T*kߚoG,Kn0}tl߾#FICtВihF ZSQRgn3"'O'v3rH~׳7mڄu>}^z%鶗kl*.ؿ?j׮K>8)'>@ĠT+VhuZ!H/(!,XZ92 o8Cd|~"9d8+$Dĵĉ'N8qĉ' Ѥ-P *5fuxxk(PP\"3C|gt?C]gv[f,'N8qĉ'NreZ;󸨪 *.Dו}E 5ejYdR FRY.i⊸! 6sgΝ5/{ss CJ"T ~6]mZJ~04 2eI Y۷(~C,AUU~Wɥ 5)35-r5aw|j#:q}Lʽ{p-&lejI2WN\~b=폩p6sss.ŋ#Lmtɓ'l;PZZJ7SUUK.n]\@DL-MȁjM ``Ѐїћu|BL???N>f;w.,_nn.BCC-'-[qXn]!cL=lMo\y៘/Smyk׮5YK.CXh>}jdZRFn\yitoTغ۷Ք-ӿGnܹѣG#66V+)m7?#F|48s .ڵkaI&aĉ3f 1p@͛Ѻuk0 0"::}5dصk|||0 K.מ>}$0 wyO> k.K`1bп>|XK?/HMMEΝrJ鲱7ƠA0rHbaĈ֮]\[1D1 3`(vڻ{7f 㘵9fҹ1k Η:LǬݣ-ZԜ*=ӟi8/^LK۶m)11F01e kH2 'w㚒 Oɗ:iժU_N&L BaL111ԯ_?EM%7.s|wO>RaŘ6Tܾ͜&mќ< IDATʓ\.ƍӑ#Gp8p EGG FA?#{.))5*--p;o<:m%"JHH ZvAhƌZ2޹su릑i* 2e b$"\pNDT\\Lm۶cj*_tt3zѣVXQgD9f*dܡwݡE' MIN Zp(2ѢszF@1k(h;fmڎY=`aǬnH״Ŗ˹m۶B'Fwd,H$&mOFKaI)3nX>1tP:uJ1̑TK\L͗yJMO6r-|7?~<-Z7o6Br%7n+qNƒe K7]q*-X,f}XR.K5CmP9PMڂ9rG]yDӹ67 ̄… QRR†Q ˗/ 7tP޽{5 G.]rJj\۸q#&OOM`n\ ߆\.͛QUU7x/2 |Xz5on|SLݱjHD`D Dellm C,a "rH4 C7~70 c[q}ۭ{͘VGm۶ QQQ())ڵkpֿŒ%KУGTUUPV+V`…ڵ+gyy9F{󑕕B|gҥNy6o ///6mڄ֭[[ `񈋋'|777dgg . |1tP|r|h֬ڵkӦMC>}6Ɨ/_cFǎq1={C Aƍ駟 !!:uқO|򧦦"33۷oǛo jo߾111Ì3 oooIܴxɓ'髏5a *L`HG^}:ƶ>ΝCXX/^1sLUϝ;x״M<Or9{GDD.]"pB*((ɓMLSSՕ)==LB׮]/<==dW0!"ӧO:y$K/QVVQ۶m7$""TJTVVF &MDT\\L7oޤN:/SUU 6ZhA .JLL$T\\̾+ћW|u߾}<<<חrrrԱcGҙ! uڕ6l@D "og|ipիWy%"rԦMjӦ eddPaa!h1yRYYI7Cr9CTT:+OcAZ;t#RVk) J֭ӺO7Dm _U!en. ٟ*.Sl/""lۛ^}U6_|Ç ر)55Ug9A=r۷L_} [ 24GCCŐ!Chڴi:elii)rvv͛7kOKK#4{lZr%Ѹq4:"@tis[_gAuQFԮ];\~~>?d#t "R.ի5jԈnܸA+W$fq899Q@@q̩cL$%sߠehi=Z|_Bv}zhD~d˳1w\gcd9]Ț1c`޽?իW/S(wU9w;[ooPׯ_777@@@<<< ggg.W={֭[}߿?RRRkTɾo>#$$K/ag۷/wOOOݛ!iÆ dرc6mGGG#++ ͛7G۷1m4899a7o-q~ЛW|N $$]tAbb" qyiQvk.dgg#::rرc#G34#??7]͗+Zh: <<M4A޽qe^ccƌAPP zkHg|)Oj,uND"N ZTrFHۢL ٪270dG"33} 0 jzQFaΜ9شiVW W.л*|:WkT?P9bcc?6@=~GGG޽Gyy9^u$%v///xyyI&zΙ3۷DŽ pQlڴIgX[[[?/^d7*1j([Z!̚5 {Fhh(Zj_>>>(..ԡ>Ϙ:PCE1eqb b  u,9 !eqB:t(=zΟ?jddd_Çb1 ǎcuuu՘dƬoqիWWW'ѣG/k1b6l! '''V/h֬Zl-["::4.7Au\\\l0.s'ca4ݻ0K'O*{nAP\qIWr;vttdnq,Xll_y ƍ^x: 4իW MDǏo]oX>۶kʼ0Q&lx!^rr2 СC|{W.һuKtfn_i,|~a׮]Xt)>B]b̙3ǏfϞsnݺo߾0`͛Ǿ 믿Fyy=0a$ -[@4?5!!p!={+WUV.5P(p]nݺFsD"0 "D D@ll F \#{Bb8`2PksvvFn:4h`oo 6ѣG[z_51w\9sYYYpssÜ9s^zh֬o ]?xyyy&c:v((H$z05.K7 boovb*uawRwEII Pڶm[H$͵mSb s\lVX11%=})ƍ߿vΩSYYw0XlKק!m25w;w@D:>!^ee%5j `رT!KmUsӨ˾̑T`ƌׯ6@˗/ՕdK/-[`ȑϟ?_AaܸqXt)z ooo 8۶m֭[~Qj LC+atQTTLw[욖 Hl 6b1"@D#D6!Q!\n`4澞:͜!͚9=z4~'{c޽o pM̞='N{a@hh(~m;w4Zc?x6}֭[pV*Ǟ={L&ݻϒq w)#K.D )ԶݵoD\aa!ocllk!//H[蠌/=JaooQ9uݻAlV–-[x(FHۢLMUsyx葆}G8t\\\0k,e+K靯Fms4UGW\.[o'''ƴ*?~dsչKW^W_}@6RRRЪU+38&O L.Ita_jժ^ulذA`v͚5WN7Ns{^ L$2 ָop隐s?; 07$,FDD W^pwwG˖-5:'O.Mf̘+x嗵6ӧ8q"SN8|0JKK˗/k>}JAAAT^=>|8߿(::[uW}ѐ!C #"o4 Ν;… MMuu޶L C 14d*uJmݺYfԿ4huڕ֯_OD;1??$ 5mڔJcr1W|rnvN?XPPZ`kDDmڴݻӤIO>6mФIXnڴZjEUV4d2dӇɉd2mذZhA(,,LÉ EFFŋuʱ|rZzk%:۶m@=z={ {=!C_|AӧO;Ο?Ocƌ!ԠAze e XǬnPځ4.%G,g̥^"QE]f1+w6]8Ǭ0b9}70?4N$:W HS]Q;V@D th*=D"g}g2d*++QZZ1b߿rJy)(hݻgAT4oMPYY {{{R7ԏCBBУG$$$w?FJJ Ν+(;@|@,EeזMIאsLՓ:|酅EB_~/5ޘ:7p@|gjϞ=ѫW/̛7Oo_7|m25V!D5>|nnnDz4[ 51曣wu՜4LYmۂekڷocʔ)ZLml >}7ny漻4nwB&X-[ zq=x;͛G 1r5\N//8Ȟ?DttldR(WɞՎUtZ,9ҷLN9oLWS-{Q% VZ`Μ9 5bH[[[c`-]D"8q*1Kۀ0FIW#U~}lݺUkC>hl}̇4~͗!70uGꧡ'!vrJ$$$ %% =Sjy*b}AZZf̘ħEH U>Ҝ"+w0Jm1폡6 aj-[:ڳg~wKilvpp`=7D"S@ĠJ.\rCj\QBo_]%fggC,6D{s AѱcGTTTݻׯWX M6EHHm&Gٹ%SRvOCmWXX ;V뜿?lmmu'V ֭[۷oK. V,Gm?VVXW^ZQgeeXbRRd^WgG4 /OKKftqgОA{V"K/5RS_k9sy1wyinYf n߾ @aaX"mj ]y'̊+VX1Հh8{CA ʪ#Wа/8Uev@4 o?R q˩t-3{@dh%mӵNԖY_UVjغ awۮ<tfŊ+VX\*LL9*G2rnsjO?!Wh ]+YbŊ+VXb0$"d6b@"f`#Q:dڟX{7f )2.Ϲك2(}ܺuKÇy7!YL k*W/ɒe()tVI.~E,K]?n,-[aa'k.2 lͭQ'P-u>}<~ WWWl޼Yoׯ#$$DsP-ׯc„ ۷ֵaHKKѣzvv6дiSxyy;v 1l0l㣱k94VDF@$Q>@l#X@$D",Xsa蹞rLn|:f/ǬP:;21rJgKP:_ pz=jѢ{S9r$;wZ=x6m gϞBsse1FnsYx1yxxX,灲2\Ջ9ztmۖMגy) ;P>}jQx'omڴI뚇uСdɡ {ァpѢEԪU+ql?*<==iɒ%a_N ¬t߽d!ҙ3g^P^^^tAx֬Y4sL""zEGGӱcǨRRR͙3U A(66V#$jѢZLcŊQ9f:},t IDATy+Owޥ.-QkҔt9;JrhM-Ǭ`1kr6601pj SU>2wwwWZTW:t /QYYlXΕ!2~p+H0I4EKP]]CԩSfՋ9z2|ؿ?֬Yc<[MO&B@Gǧ6yKCy h^u&dJ;v,\]]4sԩۏEfdK kO#Ѽys|* HR9r=WRR'''٣e˖k׮pttĔ)SЦMv؁G[nݺu٥uV~yq%bE0 1@̈!13X,D$X|>U1 8_#v̪1dG[lѣG? ˗/gwڿ?5=???={f_אEXz5Zl*]666o~ ŢEкuk\pǏǂ гgOv7n$ԯ_UдiSj IIIH$سgpnƍx1JKK?]^^^D8;;ԩSf͑!55snݺQFa.]]v! @oB(**… qi/D׮]J+=MHH@zz:رc͛7_r9>C[ 4@zz:xmۆqơGXz51m4aÒ%K?#33vvv2̘1^^^(**ٳgyP7vc jJ \p̓Dk[z/ ֗rL:=vZoR;w7|w}eru_h?33yyyDضmh^C}r~~>̙,_ 41c0}t9ҠE"x $&&[ƹs琔tuOV@]B@YY+wHHr9Ο?&M`ԨQ֭}:ry "":}4'O-͟?N:EH4ez*o\pR)EFFRYY) 4iRqq]Q_}.\5rss)22\\\hѢETYY^{饗^,***m۲:P 韈($$FQK9vAk׮>}qe-[qz{{ӫWw&׻.?#>:kҤ uڕ [%%%f'ϵk׌#7oߞ222ѣO>>>T]]MeeeEhN_]Kee%5nܘ:DDDͣ(z"O>|0;vPzz:k„ ._DD1 CT^^~""\N͚53gٳg ٳ MhΝt@=zo^z4axM}!"*))rqq++P-&8|ݣEӐwJhNQ)+"K悡d%K|ɜ`|Y5 coooL0pqqArr2R͡ݻf_% $$]tAbb" qyᅬÇ_~Ec\]v!;;ѬcǎEFF9WWWh:t@xx84i޽{qܹsǶo%BBB/֯_ePz֭[}߿?RRRϛ!6lL;v`ӦMpttDqq1tQƍ]qDEE{xq5L:vvvݻ{fw]cƌ޽{!zBzz:(wӧ/u=LeφU]PSQWv3g`?5)j79WWW; -X[nX`n޼}~WWbkk1c ((W~~N=s'Fœ9si&L8G!,, AAA8{,ݸq# @/,Y(++ڵkڵc.YGFBBΝ+V̙3l>J}͛ٳ''ݻ(=XP@ b X)g$ ۄDoHYNgHppS]B7mb8wI&(.. UVf_7a4޽;lmmqʇ͛cŊkFtIk4MȪvQ航*ʁZll,^u >nnnZ.wƈ#аaCeP׋zi<Il4k -[D˖-\v77=c'NK,6l3zP^^.H>>fСx<8< 8>CB@@]} wdMGll,>SjR6Հ?H>ncJotvFᕇWAbb"nܸ  ;;eeeZat!ONNNFAA:t`7r rssŋcZ߿;wTڵ :uٳ!͛xhт ?h b3: 49sp 8::^cӲbXl) ) # IýLH5n+$d~C$4an8FyӵkWif؇?O<07%@*0qD|gHHH@ee%a'Twڶm D"O_ ̝;gΜAVV4j'D7߿? cÆ x;;$4>CܹswiAN%D*,׺Maќُ{yyApvv6JOW˖-Ê+p1A +++ѨQ#,Xcǎ;|Xv-ABBn߾kbԩlB>_|֌MV)x0 ;qs???H$ ci޽˗1w\L2EX@N`L!) !2)P-qz45.oED(N(N8~9d ͥK{{{[K.DرcQQQɓ'O>zm߾=999Bd2A~t pM̞='N{apu.\J8~2[2dnسgLݻw Obcƌ+WwEΝqaq#P݌=?_#66ػw(͛ѣGǿ;;K)yamֳgOt k֬3UDDnBYY:ud<|uU>]!..|ށ{}:̚5Kg\w._ðap 'IIIx4Zׯ_׊/55w:uBÆ 5v+..L&Ctd3]vs9r$뇛7o?9bEJH|A |U,?x2 7c(qVycy|2֬Y~QQQӧO `xx8qF}!%%"׹<|GNcxff&"##ٵȀrmaðuVOފ QcpK@ٟ >ZWWuJ_ؽ{7!JP(x'oݺ;wwѣZ{ 5jٳ=WPPPv&諯Bqq1._;v`۶mD'OĪU}v8::^x̚5 ;wdeggcǎѣ4*ɣGƠApMk.1YŊ"9BLK夀TH,5~0ta.sB2 2"//ۛ>cJHHB04`Zp!}嗴tR^W$cǎeԩٳ飏>^{>|.++FqĉD(55ŋԾ}{?>ܹbbb]:DNNNԸqc:~8>}|}}֖222… Ciiim68q"ҥK0 YvM(77 >/_NA7nW/Gw}GYw֭ә:.yzzj9ݻ;ٳiӦM$M6GN֭[X,m۶OHtΌ3իq||p|җ.ܺu+999Qfͨ4h ڵ+_%յݨ˒ߩS'ڻw/k3f 0 }Ǭ3ɚ邂f͚ѨQhʔ)Jqqq$J CO( >SJLLSREE{e몺;>}^z4|pڿ?988Ptt4UWWK'8pٳDDO6mJ'N ".rk֬!OOOuiGo%$$ʕ+>`˃D"Q- b^^^nݢx7n=yDK~BA4e)&&nݺŦm3M׮])))JKKUǘg+n]澻JK3hQF%Koш;;%!Z~(Q̅@{9cV˜'j1ܟH_Acɳs6j(++ý{дiS #bsx1RRR0w\p!!!ѣPQQUVG]\zbXMC( D"Fg5ݻө2xo(IC*͛7 Ҥ2LKɧn4v! >|777TVV^zelT˳Ԧl*q%blRΌKϓݻwunQ]] ;;;3S|UCRS ѳ>TJKKacc׎tQ]]cǎ!$$GUUJJJtg31g+nlق0s|x9R Tʁ߫7pvAi)p~H 8ѳCN'W;U]+dx_眮8̀oP>8Rq>EzjtqՀHKii)0b㏵܊+Vx 6l'O|F賊7ќpUGV8;;aC^p7ʀK)hߠ>@R(j?cD^_k[y9d20? i`֭[:۸q# q]]ѤIӊ+VX߿5²eZ+u0dH$D l$ lĀDF" tjg (W{7f }x\?DЇ>JA^wqqo]KXbŊ3:tл+V$X)D6jeWH`聎Ps٬]q 0k(N+VXbŊ+VDF@$Q>@l#X@$D",Xs! (KD k ݾ}[h UUU_Z (..f}X4J۰gwԻ:u]Bmnn瑇jM2 I ׏",%򫏺k Յ+sk` A 6Q42'5LZyfmGF%77kQbܹy.oؼys]R'XS-[]v`4i&N1c 004; k#MKSe`! yX^xQQQ駟3g1aW|UU0O$i9MENN{naZt.]~ +ڶm*X*|U_c.e]y_+@03bHDr#A"A,V>KĀO&BԘٙrssR^^ԩFYb?HܵQ2f̘Vj 2V?ƲeːoǎC NH\j !xWJ˜>bkx71n8,X999z9B5{R?D\v o۷N:q㎊BXX^u̚5 HNNfb٘8q"␕TWKu ]WyDbDrYD lleXla8}m۶"-u1tP:ut!D~k]zspp\Xߏ5kX@"MI) ,_iPb-Z0˶Sel˞? X>GGGyZ^^^BvvFBT#GJJJ_prMUV~K. λ.,{wP]0=kw҉1"D"D@"a yT TɞeF3ףG@FFbbb3f`fff")) )))֭Ξ=^۸q#VX k׮Tdffbx7Q^^"L6 }App0}}aw OOON<͛o}dN^^"""жm[/C`` ֭[[^^>:t(>s5WoW\g}.]q?y'O̙31x`L< &&ӧOǪU֭[Z ԩ^p9vz۶mPRRkl,Y=z@UUn:uTxxx 88.\0ל?qqqOիWk՟x`ϚO̜9XZB7_|yUoR)~g;t)\{Ξ= Ae͇c}:Dx78w&M@4!!2 .f͚ePCurrBeKMU_cJ?PǨQ{!""111?>PXXU^7T ͛7 M6u֘0avgNkA)H900;ΑrH"QnMHfLXt9@I@ 6l@}4 4@+x@0` n߾MK999tqf5 IDATر#yyyQee%5nܘ:DDDͣ(""`6ӧ\.'""?>IR2R(4i$ruueePP &FaPV"/<==sa@;vtJMMՐ3,,rrrN<!]sCGK2Ѻ"7xCy0ٳ}_Ϟ{=t X!@K~͞-hll óݳͳXm|5we 0n8];Hj-1`K.HLLDaa!Ο?[[[3AAA'''P]>wA[o1zad2ر6m#%&Mµkpq޽{ NϞ=1j(̙36mb}K/ߟ7^CNwڅl6cǎEFF9WWWh:t@xx84i޽{Zƍ]rDEE{xq5L:vvvl1c`޽^z!==լ,bccnݺay&{opp0ZnۣHIIOWͳO}ˍ4iHލIPS֯_/2#錛o.BX߽H4 ޽ e۶m u;;;!((gϞE||ixܼy={d{ NG1{X~=\.V]½n.Ӱ+{{{-;S?6DN`\. ) !2)P-;ףq|~,W@c_#DvQѽ{w`q,XlPVX>|8 5l4k -[D˖-\tMKCa۷o]rZ[OVcdC9z(ɫ1b6lh0^>]s_u|Iktf*9Μ9PmW-C08qΝ;$4lP+СC#>/ŋMN_h~eΙy\UsY eEA7}ݒ@ܷ-555PLPRsIͥDK\wLĴ}yn3wrq~?9ssΙy,|ܹs...۷/,:M1 ~N>3 MG -IZj< z#BEP%|P Wؚ9c*q prrbȚ5kn:ahtN<~(BBBL-${!..ΰg%bӑJhР>C?"==x/k[r塸$$F"Bll,^}UcСկ_ mPn]?#v؁" l|||Pn]ԯ__ưDY'78gr^ħn;_i\c{}}}َR0 3:Ubŝ;wtŘzV^[a᯿֭[1sL!99/Fff&bcc1}tiyO#::ǎ|}}9 ڢ) DJH%bP(R"o1X~0uvzm Kopo"~Lbt "swb޼yHMME~~>vMhBii){MP 99 m!a TdzS9jN:>N8777Ū͛7_.ٳ 薵!mۂpy\NN `ܸquMiӦ!44?Aرcc}d3@JJ;e:t}1,Q~x> ++ _~%{lr^ħn;_iʷ:722@ǎȞk1߿u+|dffٙ6l0\vlGB{AbԨQ߿?޽E5t =ׯ äI T~,YX[4U\ϝ P@ĠZ)R(UJu']`jXX BwYO#GЧO?9sUUUHNNFEEr99ӧ7n @=읕"Bxx8JJJ0l0ܽ{5k;W'Oƭ[0j(ްz~sDDn߾UR} JoEhh(||||rl޼N >>|8N:_~oڴi#H~/\* :7oO#-- AAAT󱹾~={6saoo3f۷/ ͛lpuE鉖-[tNfN9W>|pW&L?'c}>]@UUNc„ h߾E]Ljh#$>×w23omL1߽{vܩ+W|uMee%o9))Ig2iР6mCᳳNc,**JBYY yL799;vرc1x`ܽ{111:[}@aa!Ǝ+Dii)gbpss+N:L]n kB_[С~'ƍy;!_+*sr9ARBPA&WB!S@I`Uxc1wGG2L]pe ;HzG2M(88͛G>ۗ NG%'''/RӦMiڵD'O&BADD111Nyfrtt$I?~FF1 C[l!" رcl2s|:u %&&Ruu5g:ǎ#OOO|2ݸqlmmqƔJDDEϏX9+kr;|0uԉI_Nm۶x(:: ĉJtYx"5oޜԩC6(iӦQÆ :B^^M:͛s~ٔL͒%K( >Zt)͜9L޻m6rrr"///ڹs'9"-?{{>z׮]Oߟ"##)22zI...jִܷo.(gዏtd.sWfu,x%"ɡҊ+hմj*gT]KRڲe 5lؐh۶mSuF_ȑ#)..֯_OkϞ=K;w&4c ^L×Ν;SBBȩŋI"PHHo8m']ٯ9sf9 ggg7nUWWSjjA['GmT[<~8SFh4i$ի{?sgӉf=Z=]zBWI%K%74]]¡\;O22 2VD'oDI$ 1mMD Fdcǎڵ+PUUŮҦN尳JD"Aqq1tpr9ѤIWY9|a5TWWx'+BႈoWBZ܌4kLKRiBQ(: 낫negA{"?_bD[̉d2(sWfWBʬ)aJχzYY`1W_QRR+W"66VPx! ~Ųe T2c1bMO!mQ&ATѨ^zjtw^D}‹[UJ@*~ʔý3?u\].PUdA!**jPﻠWJf?ӛ*7NȐs  ڍV5v` 1֠jp !p0 kS򕵩6_0X_\u.>O5/mĖ~>kb )wKց9qS*a)t|y+3Sc!eV[v.L=;Y cj ꩄ"!=կ/p1̟?_)oua7W~:h߾=߿M߮+O&r SNEzR0h =wxڢKFF:y@ )elg'8:1ppwjZn={LoOZ(ĎiOuӆ]#$!zh̘1bob&ֲ$c}>?RkډbQ\]]1`GֳO>yl2Z }Μ9@,\ԝ0&|WpwwǞ={8ر`v")_|w9sD㭷B~ ? .Drr2iÇsΡW^hܸ1|||0c &##DDDoiGA||< vԑ[9޽{m۶(K77n@۶m㨒atG,\ ˖-Cii)ooo <F 0bغupċ/a#FW^0`~'Ar?HLLDhh(֯_:bĈxvZt aaatίvً' |혯VWW $SM bCs[#!!AG N&ͭ7!%SGddd]vukرc "a@"a`kk[ l` :fY 1acG/LSN5rN0RZZJR͛TQQAg|'ev4lؐ>S0;+Դ\9}!5nXznhŊ/++K.Q߾}),,ຏ?~=;w.͙3(**N>MeeerJ@'""\N6mJ""JII!tV~wwwǘ1cư|udN-Biҥfg6E~~>5k֌=޸q#]vvڱQQQ:hرݻiݺu%&&:{,T*>}:Б#GILҨN::N (00Əs~РAT*1b޽[T=aڱvyfZ~=ݾ}/믿ԱcGi}ynM%}*++iԨQtWRR"(^I yCMO } T*ۛ~嗚̢q:{]Z{"ˣOI&TT_spuu=Zf :w L>[FZZѣG;2Cƍ=ХK6.]믿fՑ9s0Vw5MT~,X ԾKcc`֭s~[kN;]M1 I&AT .&9r$:uꄡCuss|M6a;w͛d+V@qq1_|kǦi>}͛7|||p9 4hb۝9/?/ ˑM]vx_57K#cSoŜ>=(5ALis͋%  ;TREP(TPznp  7VH955&ѣ&NsN[+V@Νٰx1gxQQQ^{g˗cС裏y%ts˗̚5 ={DF#G`x7t¦MBiӦaܹeK/q%rД̙3ڵk{߾}߿?~GiqryZ|JcǎP*z:2!pcw}_|ЪU+:r=x}^W_5{nr zN1kذ!&N@xe:p'LSc}^3vgv~ݻ| """^p5k3azo#qyL8 .Ē%KsGⓗcQBA?֊*(JJ  2@` [TO9{25)s2fLKKK>}}$JH&Qp.)JRTԹsgڱcQxx8W^ty""x"_zIӦM#"4oO.S>}T*M2ݩ6mJbݻI"Džo{> GH9<Զm[:|0:uZhAM6%LFtI@&W|)JIa IDATۛN8ADD/:߽:tQzz:`'@=8p[oQΝN PPPUTTH=ח.]s?C04~x""˗/:tܹsWGBÇԺukjݺ5>|rrr( x 6+W;CDDVXADdXw/tIͥ@6S.]8[\\LqqqFtIBLuZl8qBרQ#όaۼy3T"RO޽;5hЀܹ#(?b~z@[lՕ㲲2ݻ7Ӟ={ίvvX \Xv͛ԢE Ŷ;sک+lŅڵkүu"uvX>ƧL7o\p)((8@ӧO۷oG⋗}Ss!ZL"""wwwڶmgH5ko /-ZO?EnݠT*YڴiUGBχv׬Y3iCg믿fg@@T*ّf>{=z`޷kC 5((HP~]]]wyWFDDZn pzfpҥKuΝ aPXX^z 6l@ӦME!$...(,,9NNNG}EaȐ!XlΝ+J>@'L & +v!))s L$?z ]vEϞ=|rl޼d5 \S? 4{0ѪU+4k  0o׮]~EܔӶuAxx8g1c`;w( RBE*(BS\ Uз,e?_;=6XǬ`87vl?D7oo///\rXԍf̘12d k+<==u|%Lѯ;cWWWvGXXxߺub:u*зo_kطoo\3}9k.26&!yД#j* yyy:S~Gxx8"##1o<4jF̖jطo/_y]li;K`` ^u={VP5^S͛79 sG⋗>7BDGϞ=okьѿhV=bbbDoQJT+%P PR+£]/WY!a5!2QFW_}:tAeÆ hѢbccq%3k3P;pY !펏#::ǎ|}} m'Forr2/^Lbd7Ӯ];ᒛ Bnᛙ wwwپ}{۷/"DDBinn.ܹc`i#9i;5Ν;~~M[mfJ?zoԤa c}$SÃ6ͅaY˗/GLL VZgF 6a A.T*% dr%2dˮ%bM8Jf` ?DB,7mLm ƍaڴi6mBCCu|Zdggݻ7oRSS;vm۶ "? þ7o?Ck\.gR#mۆ`Æ -ZСC:~0 ) xg >yL1]ȗ2*Etv+WHܿ_+XFF:v>N8777Qx󑙙 gggܰap5 xwt -Ŭڔs.2OLLD^^}]NHh äI T~ vqFٓ QF{.-ZĻRVbǐ!Cc-[ PRRb0͛L{Nߏ~$mw5m搚uүuKFM|p庇>kB˖-_`޽ i&(JV  S %l ' dJ@d"iaojD S9o.ctudoo3f۷/;W͛(--e F>}иqch޼95PHW^yÇ3SN_~[oŮdPTh߾=bcc1m4vTaԨQ())ap]dffb֬Y777deeJLyL?b0/-Se_.<-r3gΠ ɨ\.J⽷wΝ;urJoEhh(|||9N2_ee iӦ8t{.;;aaa/$,X;JJJo>cID8~8 __`7HH5~YYN'ypss+N:t"뮼\ \/^ TKHH0_ұcb{.bbb ^ԅ;v ÚA<0VQQa<UWW\#b*|~~IY˗d7oĪUd7oիW_ei:y-@-ٳMgP co$%%]N#$hMff&lꉪ*\xc*^GL~2ިIC&LӮ>_\pt(B6BVFt߿~gYGTA@"J@PBP@IjCIM0B!X_Mpe-N4Y_v&//NJͣk׮QӦMiڵD'O&BADDׯ_mR||<Krr2yyy󣴴4""ڵk9;;SӦM̙3ᅮ3yxxʕ+H# OOO'p111NA ٳԹsg@3f̠۷oSjj*uԉ_~`@T]]+rXd |@K.3g;w߻;W+}9+++)88htQrrr(d&󘓓C+VիiժUcǎ']|nܸAԸqcv.TJ[l m۶M't9r$ޣ,"":~8jٟ)Js5hЀi…rJ &PiiAL_IMM8q\]]ۛΞ=K/^͛S:uXG3gɷ37 }ƍ$Hu֔N.\VZ %%%q,;wL TVVŋI"PHHoաCJII!"={6 ahѢEL"WҸqխ[>#B%%%Q@@]F(s󐟟OI}bZnM/2M2,YB[)S aڴi԰aCx׎MS T~}Ac4)]6D?<-Z(''G'~S6Biƥ۷o7m6rrr"///G⊗}j}ж@8,,>CbgvY"%$ߣCWNs-@ѲK:0w{ ;fw՘Ik8QkjlM (BDDbLҐ4k!??,brhҤ@NE{^j}W>yr_w=<< dٯR|i~i~!agg'*EEEfMJYY B0d2>};v # 5ɿ看e˖!22Reee(..ݻ1b_3cU(&pi())ʕ+kqٞ% n޼ ///z<ߕs4ibyA*ڴ2}R)u6;Y"<eS^^|4nXGwcJOO')=MT*>x11Lυ mu ݻwŋ^o۶-&Nht}UǪE}  JdV5]ԫ8*Q4hS@Uȑ$KD@mhjB A4P" 55J#RԫW8OV=_|vލG?|0jmشiBCCkeiV}ogXv-n߾m8tsΡ}Z f }6L<]^zj1k "mHWc3ǸQA(eekG9sr{t[=ah/2|իЪU+L8529<>0m4DEE!$$UUUca}*&góҾĠiӦXj^z% n:<|'N0j gEk%"RJ  z97o"_mgm z XF)Sʕ+qQ4hk֬ypiѮ];ɓ>zTB/j+Vjkz6H$3fzgo VATR&R er(P U eۥVJcVmL \c'JV?ڵc|<<-rZynŊ+VۑH$p?2z9 WCV-6v`/p\A\3,n?X 2utȊ+VXbŊ'a[g/n١ S* VAj'AT0*ȥv(sPb˜Y5eV3 (((3TWW̙3fS^^$J0<4B琲~\{D,)vb-Mg.<"(BϹ^j r9(/+CYI1 @{5s=s \18A$tG?s 9qc#66$4'޽{m۶Ֆ\x!!!x7ƨQ`cc???1{=nZE;Ǚ àK.8rɅ a`ٲe(--'<_| <<#F@^0`O򕛛CGOf={}7n8new^i àO>2e &Oq!((ȨMKƍ?HLLDhh(֯_:F^D"}t0n80 ~999}Ϟ=hժA^0fDEE_~䉕Y\_}U;v3>mq'ׯ#""}bbb0ge,!m,[ĄWYhYۇDЮA%rP\@i ErVEx4qBӦM5 BB=g5qaYc01k~~>5k֬P߿Oˋ=.//q"/@ZtVSRϞ=H\}EEEQaa!{@cǎewM֭ƍ ڵ k׎='1yOLL$tY""RT4}t#G^z;8}7o$ah[LY%$$]CYY1SȘFuqrHDTPP@4~x?#I$z~ӹT*M6챘z_x1`o̚r=vq!-?.=CjܸNt֍uY2}6-b +,Brr2P{ݠ)$t\GBS)pV,HEb>{իW)''Gu ;f  !uEyzz"00뼓YZVm!d2 .u-)4_mllFywuy,BZˠuզnݺ:IL5kaL4 J{1\˗/7p7sLi7nӱuV8n1eNٶΕeeȑ#ѩS' :T'>lڴ gK$L2 "":ך6mפ2̑Y7SE1mRzOX:>._oT1coP2}>-!SzTڇ+D":0b+e%-۬6mִH_@^58?o6]v$%%(..֭[޽{O?]vEuu5`ΝXnVXΝ;qVTT`xwhɓeK/'33.f̘} ӧqeDFF|`Ϟ=Abb"`׮]hժ68rߏ7xnґGzEEZ mڴa8q".\%KΝCnn.f͚={}:k9\]t˗k4i1eF СCҥjTxeʗ?ShA B$4øvF [[lڴ\ee%1w\HR|W̙3hbdLKKo>} ꫯk~~~ꫯ &\tմޯ\۷/{\ -kn}pFzz:LN_|8z(ZhS~~~|2tIϒҺRzH^γӖXyH$888u OLn/z!iG*b+fE_0m 6棸Sk5 `m[k!>>WF[QFl'N=r9VXCRA"`Æ pwwǧ~7n 00h޼9p=֠?3 ѳgObر5jL7b͚5X`&O(̜9eeeh|W##ЬY3038c 2 6ĠAfL6Mgnb2)) /_RDzz:9#Fׯy\\\ʆf1c>St 3f,#J8vf̘!C?5bڲ&Xȧoڷo{ݻwGYYJKK1qD5Sj^ŧ޽{y4:pww9_n]r\pSeӪn1W+5ɳߋV5C:u`cc[[[ٱ4J:Uhm9ҿ,,ai{V"A7qqqP*A'@&N:pٳQQQx7i_5^{5@@@T*NE@@甊&M]vg} 0{ŬYo6,Xw :7G~_.]oZBf0` 0[nB@i*((ɓ'1h 7*.|=u9ݻw2ŝ;wׄ DuaL~ecicFӥKtC`> Ν aPXX^z 6lЙŅf%)RRRة0o&z s[Rg[bd,((~^pqqT̙3!!!ff8鉰0|7j@kFo4TSV=6tzH^iXysDD?675hb~E "1?YxƦՊcضm֭?pttĎ;PTT_]' ТE ҥK8y$<<<0|DGGرcppp/!!h 0 CII !!!F/]999Xf ֭[v ݻ{,_Kb*&^x?~ظq#nݺv͉ +Fv޽kznn. 7ƶmЯ_?DEE|<0c„ Xjz衳%dmLG.}A*A1~xxzzJKKqM6=_||Oo矼d5j___?~\|ii)N-Cb+V 0j?A`jSX?چa1ь;}֮]cb̘18pRRRtFyq]̛7ǎ;aaa4irss!J?#( vA.I-ZCtvQ(HNNFzz:~ǥI&(**µkNےp)_RQ=u.]`˖-`}(,,D>}/sV^mvܖ,ˬ,|&ÉC ;~-޲e 0sLR4x̙3fʕ+q| 7Gf>vZd6>}lj'> W_}j2>>ϧ76n܈={r>sDFF>z}Kǎzr7iC@zm܊F#~hY\Cpqq;֭ݻ-[y۝O>hܸ1`pss+N:L***؅b|sҥKXh;x:khѢBBBW_t-,5k$1ao_|9K, wMZ K,a7q8t֍S&)gggl߾6l#VfM\YYƏϮEFh[G>}R"44>>>X|96oތSNqm*>>ϧ7/^ TKHH@޽燝;wq5Pm1a1yZ΀dSWoPYAD ӎY@cV.fϞMYYYqLL ݾ}['̵kרiӦvZJJJɓ'fΜYEٙƍGՔJ:u"b blBgϞ R S>}-\Y:_tqrwwFٳiҤIԫW/:|0Rpp0D@ÇÇȣ}}ƍ$Hu֔N.\VZ %%%Ѷmɉt7n޼ yzz+++)88htQrrr(dߒ+ҀhԹsg iڴi԰aCGy\zƍGnݺGQII {K~2ŋI"PHHsvn:t@)))DDGg&0 -ZHGfSy.))uڕ:+/N4zh>}:… I.ѦMŅoОRRRYfGزܵkH={ >W_C~~>EDDPdd$}gRHH%%%ۺu+S hi޻w `pTر-^z/^'ԧO~h˵m۶M ]yzzJ2YH[&"֭[:qRƍ)55h'BɡҊ+hմj*ΰ&=TELXzELmɊGMJJ OJW^[n_E<$LFr UWWSyy99wm߶BkvZYacVcuA/2cF[cۿik hj#(-agg3gyٲeT*EYY{n1ۡσع ɠT*\;;;>ׅ ˑ&M8by˫RPXXHR888 Jk<] Seʗ\"ۓL&CFFlllвeKκ{bdT(y&nkF-,!1j-K'D :oCbnt=TmɊs9|0ggg888S`kknT*!!Q~ynPPpPOG*Uz74?s "!Tc&|ؽ{7=s.~i&>斀qD"Ajj#oϿ<ߪXPkBƏ漾qDD 2fi=QիWѱcG 0!!!B^^?jq<&~bʳzȊ+O `H]#H?*dQ~4`ڋoڵk<>>:u^l̽׮]5lCԡU`hM68q"v{MctKP+n{O 1zhۘ={6V^/_ǒ%K0k,|種ܹs9Z#).j ?x ,[ ;vĺu8o2T"1طo^xXv-f͚)IC| ׮]˗͛7~3TPz1ӢCn.ԐS@AЧOM</^lLy9sC itl(*Bv^ޖpttO.66$_! 6/Wk Q,EByڣ/~Gd2̱ӧ㧟~b(..cƞ={u}K>G%l1).jBZ9s9VRR{諌|1[(^s]"6-[PZZ'O㰷ǦM8s>7ujkkq t}s=@?!sb|>Dtҋ{С(x!Jq},^#F@~@>}piˋJ–&L]'$$ 88K,m^z͛jlDI]]>#t?|XSKCg31h.js,Xh @;t px`?C `$cDPXXlwޝ"## dgg\)@CQTTZy)y饗HP#ruuCQuu5M2\\\hTRRBo;Q&QNɓDD駟RPPݽ{ՕΟ?OԿrrru^EEE4|g版(##Ѕ xԡf  D{eGDDcݻ7ݛbcc)??<<<6b"^x^|EJLLS>}SW6!TTTu9HM[߻v_$ˉhԨQ?3ǍGDDuVy-mI'm.O8>is>i}@АYfwa]\\`mmQF&OM31|p\tU^}ې#26uWSNe9y$믿2]\\p} :L&KC4/ݱa 6 uuuΞy{5= Uf]-m077?=ztq~WYF]ۛ76ٳpttD]]k.^?ծBᓅ eO?GGGXy8 t}k pvvƜ9s0tP1֭Î;hh'ĶĠsPH_ubF 𩩩ڵ+c=0i$׭[={⭷ނB1n8|镳(V;3#D"ADD.]cǎjC@$ 333$$$0A<'%%aj|MfO.e^l^pjARyK.aȐ!:f 6&0CU_>~G/Ԏ1ۋ-b^ƚˏT'n559s <<<жm[ǛGΝJgϞih"`就An8\%9BSmpuaժUPŔQUҟ=Ξ=1ò@W نO>͛6W|C>}`„ HNN@_DA+bghhOO*iii)V&CXz5fּ͚1D WH+BDDS ilyU?~UZ<|%%%h׮gbb"zM&Wk |vņԗuРA8~8Gi#nƔUwmΝ;k׮8q2H$ٳ'3 .䕽!t9RٴivDpܽ{vl !|[b tڕ^IkWMdძq%HK& !Z׀l?4ɷCeM8~,5 tѣ(++cr01N< [[[,[3;wjt\},h"=+n߾W2jkk,J.%D3!E/`ɳc.yu >>>x{{3]tћ̺ҜqK, jok1bߖ-[0qDs 8զbbbё ʥX|]FIG`%"'O uԉ)##\]]̌bcc)00`&'###ݻ7ŋW^dllLV=++$ ܹn߾Maaa4{l*++ʯA[())IIIju9..QMzz:[N[n?nܸj2&&&ׯ_獍/@VVV4sL&npfP%"AY4}6hiHOO'KKKrvvO>)??3o]a;vNi[tD2džD ) ""z~MM 2G6$ԆhJJJO>a+++횚fLJBCCBb΋APЃXqEm6_N7oIM4T?M?jMqK>}4cKKK̙)ӕQuu58q-e+-iUʨzM4.EFFRNN]|Ξ=K4}tS^eWU"V/ -唛+'9v8qΝ;GEnݢ|z1T**"TJ%%%TPP Si jiuo^mk!8p&L`Uښj]oee6[|H$Ҵb?T`g&b}"}$Ģoߞrb333 >\0.q@(戥m fhڦo۶mHHH+Ԯ566~/*+X4$߰O}vCP(PWW)'5')(PE "H ?7xy=fy] M 1~OK.ʕ+(..}]h {t0o`L4 GUU>|^{MkW4^PY-I]]FN]]r9Q[[a$Q[[>N?׬|+1 Hm?#mchcVvWkhl -ܳΝ;)/]]]1e?0 ̏?<3-+P3ӚhR$&&>|xzU_4Ϣo'::ư,,,`ff333&&&Lèi- @-9ǾOxljtȈeAd24 0` h%@"0779`bb4=L{VmYk644Bۍn2:r_4ot 0`TVVrR(wF555(-- ~"%\tu4@C MEaa-h.RֱQTT&Rt%hN|ZKhJZs+**օa#--I7lQWZU>N8"؝;w){ Ox!Zͩj;wOUUUJFMM Q]] LjHRTVVH$~JDt]U 6۾ OOd VZfoSP]:u ͛71g3F缮] o |svڥS~--Es峦W}R1_~A^ HӧcҤI3f ?{__~͛m ;Gcʕ͛1c <~XtzoܹsӧN>2e Әc}gE+yH$wży0k,xyyaѼg{#P(ԩR)PTTT HRǸ>ݻTݻk-,̂b|]!zf u~1&u>\\\puvR)/O -[h۶m~yy9]tFM~~~:cҥ Ѱah͛7iΜ9P(DQQQ&sK"+sK;]ymƧ~JDYRj2 ѱcGڰa57o[hLҊBg''':ql2D/++# F)))dgg,6JD4~x>}:g}YgUk֬!vW訳ꉋL:{,m۶6oL;w~۹s'mٲ8@Pqq1:D`_ ^z\H=DbZn>)}L"{\---9iJ4ѧؾ};y昵5Э[7!ꫯ2ǦO~wqqAyQTL\;4C5]MM &O/G_Y_عsqm+r:9ydctί5QՙpqqiºMӏҊBgBZ9s9VRR"^:\vv61x`cϞ=09>>BVVC6t?[,sssj؞\17FFF022^z%١}6=zFjrنqoB*hN  ؆m=C~w̞=C?CaƖ-[ 6ann}nj-J;w.ڷo?ڵ v%OLL f͚.]য়~.\'b9r$߿###%%%شi ?annѸy󦖜Zr?%rssѩS'YVVVHHHmХKk֬ =,4%СCHKKcʕ+1qD1&ܐ*f1ɓ'cĉ 2~@=P]]]v۷oG@@ >>022͛7 X}%** wn߾oeeeՄ]vL_yڴiسg>WWW|ի^wyWưatMΞ=+W"//6z._ ZLbSk/#_S"JNNNصk<==Q[[#G`X`F%o/^D~梜\~,V(>fggcŊslقmb̙Xd N*FFFx뭷777 /_ƚ5k?_~r ,@6mB ,Õ+WZsE6662d >%&-o{a1|p|wB4^q11|rlذB.,\ݻw5Rm bbK W!s6{Ȝy~ 7dn.Bfחf̘u>|vEDD555ԯ_?ܒ%K6nH .$",@ׯ;wPQQ͟?9e3g1555oQmm-REE) zwΎ ŋdggG^^^t!z?`SSBA {2󣀀"~лwoݻ7R~~>yxxoͪ?Yƶmr3g 43->>>J 9s9V[[KfffZ]\(t]rtt$WWW:<%''Sɉd2uԉN?J+&>:uÇСCŚW|d@H*&###f?33ѣGcjC5"%%%N@2!ꄳ3EDD0ФIH}?p ˳d/_N[no&LA}7ԱcG"⶟.ϊgx|2QUUUVVRAAݸqn߾M<"JT[[K BsX=dn$2ԇy}\g=dlȜ*bghh[[[f{̙8v/2:̃ &qef1ݦ{쁽=3ڷo.w}HNNP?,eҤI{B.ؿ?QXXDz'Ǝ7UNM9fBll,Μ9;;;0];wÑêٳgsx/ɴz|>T;־}{5P 7n|}}K/!""r 0sLx{{lll Wl SRRxbef-©S=>}ZmX_aȐ!xPlbŊĜ9s}*ZFاd5jիW#//qqqC\\ xg3PZ1qذa6mVXc޼yyqannx{{#33aaa:^;6l؀*TTT0ܠyv///0Cpڵku6MokᅦT*Ŗ-[?e?^z &D"CRR7|Sͧ |~,Vl|\nܹ}I(\~iii W_}J<4 ||||rrؠ[n5\vb ܺu =z4ƏNј{cꅮW Ƙ1c(12 1%\k yIhI1k)UA:D|M:!faV͛ wLhL jocǎݻѶm[_B6mw^3(UVҥKHLL=VX`$$$]veXf͚?ᰲ)Dxg.9UÇQRR<ЩS'GL k׮CHIYY$گ@hiN+S{@Yb[Ubd_|pd2_2uTVZW^y±c~s|r{aܹ>d29SLL&ìYnhpwwѣGQVV刉a͇ONU<==AD8+FS-zث b.5O3-["ӓ$rN6ACG錾!RELX* ְC۶m/=zP3LYY3Vҥ `ҥȑ#1p@JP(͛򴍍 Н:u*JKK1e!''/fԨuɩ*DŽ /D兑#GP96ZןÇcҥ$ d EEE1c⇣Fƍծ{ dCuUxˋy1#Z;[SP^^l.wMW/*BEe,DUUU1 l. ɫ?`P휲Z %⏏ ,M&&&ԥKJII!"No֭[?T{ONNAZh۷oSXX͞=ʴ$d24֬YCZ3BIKCpş'Nuܙ.]Js%Fc_}RYo>ݻ7!C-"%%%7('oCǙYd2UWWѣGi̘1O /TQQ5˜¬i.̪efU2g=2FcV6:{! zl)'"fzbP;I999te:{,EGG)..dQRSSC/|rrquykP(TYY{͘1c֭[:[RRB| 5a6ƍǼ'QKwhh(UTTУGXQ-sMM  @3/>r2suV_ᢶ ᓙ >ۈ) OK}<`}uu5` &BA<`PXlZ"S6j:q`.JʬbPҚ!TfGwEcꅘw>?3b| 86|LRF6bR2 DmH$μbQ_0|pQ -Vf1 s+њ!TQ]Rw0`9###bW/ļ4Y _S"՟I=xL\}sL ym?#$i*ins )Xcr |}}1vXUUUx!^{5q*ŬYD]_\\ܠzbb"XgB@.]]4闛7o۷cԨQz_mܶQO-?ЫW/$%%a֭Mv/-GC; ϧ95qq8::̤ r=9LMMann A.C*}d gS&m6q "FrDQ3yAO`zq1вܹwP?#Δ)SZX"i.,**믣sMrU OsFb\ǏO>ש. 4A nWn+( R<[o "]zmՆf_èD 0`  {jQ߀Q6|=D=C:{m 6~Cd 0`oĶ}4tx(ViN jĉ(**ҲOuu5Ν;נ|Kwuuu?^&hSAQQ@YC+**~Bs,o=OhN{6&0`|cjOByk ???]WVZӧOʕ+z߆R:jNk!!!?~YYY7KcuИrM9dϦ?B&W_eM>?h٬nݺo||<>C8p@+?_J/ƿxVⷪObc]\H?c忭Eg Ђr~/|M9&\+5CC~w#((%%%صk0j(6l؀Co>|wX~= )J1m4,\Fdd$/u=%ŋ1b׏|y;Xr%>3~:2̟?|&LC*r據Y <<>>>{Y >WXcʕXt):vggg '!!Xd m777 7od~@xx8r9,Xe˖5>lNnlxtxyyaݼvPBD6m2lܸqqqD*"44ׯ^**(o]_~G^0g5jO/TפR)>C['OVWϸtǑ˗wcK&]w~o\&GsM!1Cl=d3껷A{ 2721]x̶/͘1ӧ3]vQMM ׏9d#"7… (++Ν;TTTD'{{{Vyjkk)00***HPлKvvvTXXH/^$;;;CO:v 4hݻϏX?8ˣ?,״4 $[[[/I&BݻHtyJNN~?~L{޽{Sll,瓇ۜrdddo; ޟ \ݻSdd$s. ~WF+(ևrss֖(11QT#ruuCQuu5M2\\\hTRRB 1:.qO2:uD'O$"O?Tm(MUQ++Qzz:3gѩS>|:DQQQy͙3 vJ),,,,,hΜ9LKIIINݻwQ-~J=FDD0yФI}C7O/PDDA… K|Yyf@˗/[7|C&L`t'TT%qĀ4r7d'm2CQٳy\zAAA2d^x"44h^ٜq/"""+W...۷/FΝ;c O IJJB||<^y$}+lll< 6رc[n۷/<<<0vXaر{./^ ̟?''сt|:033̙3 Avv5\Cd2" iӦaŊؿ?͛ǚ^ 6`ƌǪUwҥK5jիW#//qqqҋ/!Z[Bڴi#8DWy^SVqqqΆ/_Ğ={[ϸţ{]5J'''tԉэK&] 14Р^$]Dj5ɓ'ʕ+All,3|@}>}:x {{{={Nm(r1*6RSSѵkW=zIx٩?o(kޏ/~?/}%o&ڵk[ϸtg*Ƙ1c(1zJdjL1`;@ۇcĉ5kNl߾]ot4 }LͅM2]^1vX޽m۶ſ/i{EqqگVb^b #!!ڵ+7)п>DII ݧOUL:DUVW^Add$&Onlmڴ%,-- oý{@DZ/B|U7:O###Va?iJP:S{,*]v՚& 1L:`՘5kD uڷoTWW*NNNh۶-ڷosz}WklyC%ɆP]{1Y 3.7YGdd$-Tdm4T::N8Ǐ3ǬkjpIR|5c oؼy3f̘ӧСC8vگwA^^/_`޽???̝;߇L&Ñ#GDGEYYsL.#&&Ft "?9\OOO4|1fΜׯcX` SN5J,`zOchF@ҭ[73KF61`L:'0/M4>ә׹;ׯ`'Năz7ˬ1N< [[[,[L\vکMhPXX\}*oFEE|||D׷tn(r\uT5~!T\]]qmV[[dzƥc}ƍ "1/uuuHOOǽ{PYY/f̘#//aaaMlaƌ8y$j?L\V\.)S4JB|_sΡ 111JBPҎ5 nnnطos,..7nd8 ֭Î;%Gee s=e˖짦:tLy>$$OiρSP^^lj7Sy]!!!BHHp̙3?gΜ!ooo@QQQT]]y> B:pP׮]iر4~x4hٳWGb}hРAf*//] 222cǎԡC:qݼy \q M0޽+' ՁX>*++ۛ,,,($$?N4i$Ѳ&4n8Z~=mڴk\BB988Pff&egg u҅RRR~;wRǎԔvޭvBAaaaOtmQ'"Ã>sP^-'N ;;;ܹ3-]ΝKK)))ZGobccዟ y^Đ# 777JKKcq3.Yo>ݻ7!CЉ'IIIjz/4? xVL*++SeڵkOOǏSee%-: ̽Y=z}_UYI45plDins ,2 R]]ŶԷtPRRSSSXYY1 L82 ())?7|KGŝ;wЭ[F}pz }<_yTQtkwmDhBB2"$! d !\ ?/a!BKk vk̙sgf3Z]]OOuo{&%ya8lh4yq7j/,|rxx-_YUh4`P3b2ݻwgʥKVFj޽{|ۍ(=çyZ~pxx8#ޞ?S?T(_YpX|1<_}uݗG/Vj~lts@ʐew|7/W^݈Hׅ>L~W9~-'MOXWKyewwWvvv:I)ɽ{#.\K.M̍c 27!sD: @NN>`?8m |`0x 3@_˗m  H:yd6;D5jct}U;)vFOr]9<X\"'?лhCl"o-qc'`l~8٩WJ y^MD6{J (zTV5!l"sωsFkVXd }ѲQ.^`888oV^u]<7嵔3A.=G+ey.֟K á|w'򋈟c{ha70ږc Dp8ׯ;#oևҙr~휽Y6E3$Uk>û"o9 Qp/*zDm{-a"^@CP.g h (96PY5"2L>>>>>>>>>:-;Ɂ 6D%/?l ldߦQcmH4\./''B0%26/ vkEOL$HǣH'"AE^9-gWi}[Vd)xۥņ4l/T=[fϥdۥ,D7o9>>>>>>>>>ճ=6"qOSI/u3^w/au'~z$Sݩc9T|]^c2utS㯻LT9Ifeڱϧ{-z^eѱ:-0YDcKIP>>>>>>>>:ޱ$~Q2m8zb9fcuxoO 752}68I=9s&C75pέ'Rcq?g{E)(q>]n׺]64ѷR|uƆN-Q9::S+F.|||||||||MYt@DC̆| ;vrOzZw~}43}7肳]{wpWzg^i)~)x0d}]{w("r֦"XJkک +mm3!s `_qڬsQxSgGA%9u&Nz.-( C^헩ic H!𹼌]ۢ>>>>>>>>>l鰽=B޷ǽ Sm{Dt:iiPNf/_u{zzא_O_g?u޶C/Qzasv7<{{k[t :EdiuRzˍ, s!6pq6>>>>>>>>>~֋loOm>E!+ :MvԘ>nʲQ6eD=>(Q/nkuzhWۿd}W"h99i BpT D}~&ِ &r4AHO-rrtLyfKmpˣkڄon{>w:\kjw3MnNoz["g{yg0dmlOѢlڃc] EI B^[^!m/~9=ڒi$ T=omo[zam"yyU K}'Ua&pDf:$H2VG.˦$~||||||||||{a"G#73$2;CѻG6Ҵ"{t y(R;sthҽB:@SkwNJžW{]o{wl]/NymXtm(K3e^>2g( yd@;Dߢ2/ yaH*yGkdʪ@ueMGl$ʽDz?<trG*OmN2 Cdjx](wrrӼz"!lEZd?9 q,>\-{bI鱣 SG$XdsH%oELx=d;\'CzEǽ }8~- EEl},UfQSkw2ۃϓ'SоEgO>g-iT?m]_۞,"[?jw,dY}Qe-== Z;g LNufC!hS|v1mE懸T 5]0dۜ9l}E̕nFu{DD_&}{M0X]}/4v-շNDS,Nh{S:wHAHBcRrHr)l{^9>>>>>>>>>&lZ[WEy_ԾH[a.D-npT?ow#/6vjc>׶E?o~7֋B 8Q I水h7Q:Uv.o8sr]&%9^|owRjSru0%}hCcm{ޱyAa{j) ~Gߢ&oǤq^hҍ-r[;`?[+ڐ?t-%j>>>>>>>>>yKe6 ٲZ<;WM1 ߬(Z8KA'mЉFmy7>>>>>>>>>&6@Xz:*|>,ڟyۥuW[eZ6|||||||||MK.J$:V LyjLW7/Zu溶̻>̫?/~KHBOINк)ee@dˢmXr:.tYIs(LcuRW @uzQ}oN-(Du|N;{u>=@-=AMaHdҧ_ ?Qys-RZGpZJz2>=Eo/aMTOX&ԂҢ*Ye KpƖIQ +-0TkV_ݴZ&:nob^_Z</OSڟ+ BeRd}"|.>d@rZyeJ!d^L}'.>>>>>>>>>mkӧXM>{  }ꯪg 9prEShi :+ C"0 G},SFљ Y,P^rV5"MXo]?sֱGe>5l*kp4UT}IENDB`Pylons-1.0.1/pylons/docs/en/_static/helloworld.png0000664000076500000240000012066511645401275022072 0ustar benstaff00000000000000PNG  IHDRD{ iCCPICC ProfilexV7~ƾ$Z5 I 1)jLdikdmSd"-?y;{N_=s>ys9柡<\8lMhieM2 RT:OOUif&zIoy{n?Q'RƶH:f$mbGl3>@"f }' ؚ1x i$l P ( ttOxgPe +p}@wub . ;DP@2w_ 6v`el4A j a-  c%~Zda` ؁# P||Np?v01Adhc+A,M64b-?na7B$fsaš= !i(BưC(R\\\6\p}$KnYܣ<FޥU|2|f~U%rтXB4 uy.E+[#V@oA>9RzR=Ҿ /\mqڒK&eRdd?/|jbԲ(L)(0Pܽ2[wZR?)JFfVڽt+.0o#Ư7SGF􇷼53@unvIcy;t{FܮjݳK6Z97g_6MmCyWNc.+\n},,θOoT3 ;<4;l6|ѼHVTq≰Ssc&ٕڽgV7ԑc&Kg|MΚU녿^녿^_/΍O,to&kdwxl8e0QU2P_H$A(x ; ;@~ )MB"!b$ۥ.X,)앂v%c*VYZ]EJ&٫{S"55ʵ+An#yu3j 0mIS3Mrw,5dT5k0ojnimݻ}#jc)٫9:Ҝ9xE{>>͉  ݃\Bh aWG'=fAj>qqdǩ^g ccJF[$('|9Ww>1qo1i0څC)kR/_OݘFHNl ŕLZWeeQ-z(O"[kg * Êhn/N.)U*++(X[N]{f=Tzȣ\5QWsVAz '6[4OܝagYfUeݴkྉ_mx0װ,98;e992]C&SEVQ]'//A!aG591y?Bqj1bFO֜:NplO܍; ?h̟vREK\SXok3TɜzZD֎lޜ׵ݨ;}HvF᧢źų%Jm)+8~ݺ{aߟyWpÞG U;jNԥ՛>&<.l`=zRӤݢ5)ӲvŎgitv9{}eEo-}} ^~0jhbhwrc5'>Nҧԧ?욹$ytB,_4":Edx.S%,P8Mys*AEjvd7e^DFMZAziU[3*aMgc[;/M̾XhhEݿe(3m N ^GY'!oדnW=Zg9R^^xyW_x>(:8 5@%G돥EDRq1{N:Xq/f{%P;u>3p҆d ))̋+/~Tf.v9)ҕEWg g=NαUɝ^~H޶7_ܺ\^0UXXyr{ijR:]VXYQN]=ҽTJU6?z{UqGʚڋu{54zrqk㏦fcm:mO }:tYN.g/.tY3zWf}Kx4x!aF{xsɤTt׌ClmliOQL–o܌ }כ 2ZR pHYs   IDATxwUardHJd@Q]pQuYwUqw}QD@W (HPI3sP?.;TwWOP>O=]U[znOէν@ @ @ @ @ @ @ \h~k+@ v.@ @ e+.Q[?.@ HVB6>b+X^ {a/셽^_.DjUWuF @ SƦԚ 8l@ . 忩8/QQS1_yC=SHS {a/셽^ PEG0{"E^MQ DS+jF25@ j#NB)83aT"Q5^C${R^ {a/셽^_.#5 jQ( AJF}(@ $j3-Py (  f=@ ʦlڈCJDw=WM0R JVk34O {a/셽^ ^MǻnJjv R#}8/[&r tu%q -셽^ {a/}]?ݷՈ@uvPjET *%BW @ BC}5F&BjPQ@BȟRER^ {a/셽l,*t'h\u PEu&RCM0qt,2>)@ LS^ {a/셽UǟQ*'˔𑂔{"~AF )TW?$핎OlgP:t<5{a/셽^ {a9FJ#W_I$Zl]i[ PĐv0Q]>5\-셽^ {a/}MEp7:j>C@PMD*AWS _bh?q/~ꨐZadH$yC<^ {a/셽^콷^s&b}۵}ۻ̽ݷ]lEjQ0(bȟxQC& m}(@%P ]Zwz.d\6bLI{ׯ5DG 1o=Xna@ƍY,F5Y @  >{+V~w@bo@Q#E$yFMD)⾮$|$@?В1bDԱ [\ @ Vdb>cڴi[l^Bri/|^%'y}UUT눘@ @ G$IfcccK=@bofޓM9D+-~Sbbb_VOn @ f_1.=<ε/qJ"%Np}'T%ZF(XdȥBs/^Ew/U#"Hmߞ. %.%F\8a2 WWdYXMFSn4 Ο%E**iX ՛V01oObB̬^Vkڦ@ ݎVE,6}tt:nt:q}}8/$u}JdN+](44[u- `UU{Vf =4f2tzR+fgQYZM[0őд :Si flF;ox`:Hvb+,ئhi4hk6dLǾi;x~b+QTR¦Ij6/L4 :vpq222)l6駟صkO:Yr%$q3w^nÇ=^OLLv5kv͂ 8y$ 6d2oٿ?=-Z`0|r8 E4iʳXp!7o&""8E_Y~ԦO-\^{aÆպ-~UYYɲeHIIh4h߾=)))5P?Pk%AAY(m+*{&ۧlv||'쯬7j֬Y_֬YQn3i$N>M裏x'<۷Kz,.wߋ/Ⱥuh۶- ,w x>Vbԩ4oޜL{1֯og̚5̘1UVqF6nȮ]B!Xyff&<z)~gE_~'6n(oS0rtmJ>S kԖ?@+ZtCa2%BuQ|!yB r(}K#wD8 ,.²oN8aaowXm^X4eE~Gh/`5g8j1q Kt1f &ive欤D%@RX[Ll87,w=H75j#<TX3iӦǶܹg}LJΝ;c00bf̘֭[=lt:ׯ N>}[8q;v,'NmC=M7ݤ޽+V If :'"a{=NJΝǗ-[п)5Զ-~իp/U  9EJvd5o~R~sOѣtZiDx~m13D:-Z:Xph6.KbH,Ia#l'0Taǒ%)Kb?`'rм[I c '<ŒXA(-#-DƄ f]8s `bX~Y\̝;Ç3a ͛7;wl2Fƍ?ϨQQFsN1dy8'NdӦM>߽{7mڴAmٲ>}ĕEӻ,;;BJKK+..KJJ&;; {9&NlV~V^5\CYYeee8N:vիرڶmKii)o}r»СC5 aS\\Lnn.AVW^QZZJn8qǏpuVvOID~~>SL[ncǎAkW^yaÆ1l0^}UBzN>$I\'|;w2n8΂ d{ɜ9s;1bϗqٵkcǎo'$??Icܸq|w};67͋E,b,(B|tPDjW+Cf(l-($٠'l"j)2łj%20+13Faی0sBHb/%D0(})v Iԩ7|3k /?Z-s2vXRRR'|"gȑ֭SewU|W_ѠAڷoXpBn&dff/pOVVb,h.\x»,99cz꫼bC (++#**J.7z+IiӦL&U}J$^~e3f/2̙39s搗/_\YY3g??~<3gΔeoyXt<;~'yGYz5foIeܸq;=zz-z!t:oXYP JH̩=j"EåQ tz&L&:MXX,@E24WTbsE3ptV#Z ݉ҎƨBQà ئAl6n6ci1tX:=;6;vɈ^ئ@ {L.^ۙ6mQQQ9RF&%%6{FiӦjiԨ:u6mڰl2zM6m(**{a/V">>|8/M4ᦛnu֪ .ܼ2N|y.su;QgzC:R}_u1 U( 0R!:mXH4 Ri)EEJJ(XE%R}]ŀƬEٜz; ΨĀmĥR^PYoĬc5 7̀DFNyT!hԨo%Iox]t\*++eqJVV999)&a8}4hj7l2ϟlVlc֬YӇf͚IMHHd(**"!!Aqqq> )&p"ETTz3o< 5PCeee{^6oԩS}_ʾgr:p,IRuTI&ɦM?~ݺm6ܞ+sE "璒_rss)..W_@zrƎ˗_~Iaa!:Ax'Ksv ;\O!rjW "s '܅K=D1:qnJlQ!&bcDFVW() шMo|F&1;tL&: h-F4f=h ZHHZ-hh U:8]5l֕-GGa5 3 7aIJ' 6F!ĎP!uѣr*kǟ~}b}6oO?]~z̙üy0͊m;v+V0cƌ7޽8ǎ}hѢ ɓ'iݺuHx "%\7eee\}㏲M0 4i"GK\:ƍn=SL0kV),,JƵҲ=zTN}aԯ|y={'RLIIA1{l9E$Iz-wξ}T@"{{萄g2qQ#%!%jkR~qHD*!sO'%1DL DFBTDCl,Θ9hi06{Ji]2A5Z :0s(2lc5X9"zրAkDգ1h F 8 };ME,,.m7lؐÇzdz%Yj#I׭[Ǎ7(uyҹkٲe ={)''5jwBMwAii)YYYRYYQo…Ѷm[68Onn.$1tPlj'$m۶ǠA$ }~'$II&tԉ%K IEEEXK>ŋ={HRu"($IIDYY};v˃t2b.]*E1h "##㸢xމ$z|޽{rdJ۶mY|9|r*@ܻW^lܸ'NRQQ˙3gСCruرc/:gE,b}tҜ!o}4|N;%[깧S!F1?gDGٌd4V!r:Yr94V$Ұ%3=0džquƿHLz)8p"=i0lӠ5q[11Ǣ3ccZ':ɉ)atrtE.gX1hMgx#ofÆ {L4.]0fO… !ΝcԨQΣ>*=<#vvy7oq=Wʶff̘fp0l0?ɓ')**>>my+oo߾믿^&Ι3go2d1113uT&OLJJ YYY̘1Cl6| tڕ*^~ey6mDNNwy'={YYY1 F)G)~F#9'N;˖-CQPPg6mJvv6ݻwG`>qС>|1c`6w[mݺx>eyyIJJg}VN~nޖ`ԩ<բE ^y/_V:$UW_b=<Y"##yw2e _|X,>222xwye˖<ü+s A psi=*@YxG?OES^C p>4 '77W-PXX(%Zf b>>KqkΧjFAt:)++DBBMnn|򥼼g @XX111- VSNѼysyxTG4h@QQt:9y$hZǣ̔HIII4h$11sZ-999j Naa\`>+rɑCYYF_n%1%:ތӆ6Ah2͹p$EEE1? 1k,ڶmp0i$f̘qY5 z^1^ IDATt@ʵZQН;wsNƌS{ׯjV ?_tM<.q-Fq^gHI{i˖E4&o*olٲ~|@b0 ,, z4nhl.X6APUUπWeMEEbd233 elb[A~%7 g#DJ]y "EI GL(s@Y@))aR.-B2pp8򹰹s$~/m h4sHV ._=!^.\nM jwmy?\%Up4㩞?QLEwj=J'UK~/m !I|@ }_Gut(PJZD  5BdR:=9H#D@ ĕ[gs /\H*-D2Ȑ?s/H @ ]` |_/J wjHQyC˅gȽw]@yGnR!s.G-R>T'xҠR]'wMFFM6k׮$$$N B$%%%dggsY֭[Grr2:tIA} BrQk!R:s}Svc]={x7W6%ڵc„ L>Mkiݺ5۷':: X,rrrjƾ}HMMeᤦdB 1t"IvJp;v`Æ \uU5& u-QCP{AV[ygpkI] yyy{ D}ɯuŸG #o:TwrAtBΝjb0jw#INhHIIaǎܹ6m)˸fJ#\5,ZAo>m4JY#\_?Aw]cv{Г ޏ:Ÿ߇?8qc#dfW&91սMԥ@ Sѣݻw'&&" !!|Z-:шdjb4ٹs':uRی|ZSs~i ŬN;aJKФ ֍Vlnkz]w , ..WN-((ѺK2 5Dv+vҬ1]{%AfN 0;w[V@  :~8iiit֍xL&m۶k.= @˖-ر#=zk1.hZt:uFQQǎ#--MU3*W=s! "{U>$|(xs:{J}h~〺X5tؑ_W',, ***(..Pn}|? dggdw.{iݧ/noKtͥ&,fmT7潯kX_6|Mnfڶm6999} /s~gXx1f4Z̡Cx뭷׿UoL6'Ob2xhC4o\v׮]:&N(OJJȑ#uO \)kҗByS@CnJ' ~ʢWz4]U6FΗEҝoD1MY`PuHOOBZt)C ٿg }݌=֭[{ԍdrTn+|{}r#FЦM㖕1b{uʕ+>|8ǏWjOЧOx i׮W^{UWW_q7r>g%KXx1;wl63n8{9y睠~r˗/gʔ)|OSO=UINApB9۱ٓCQ͛jY|9۷oGhJwߑÄ k$I-NjI&={VmRJ/jnS8U'/ +@("C\u 8y$<wqϟ'66v.A,jgѢE,]$BtRVZEÆ ywٲy }ʕ+yy7?>gΜa<鮻xG"""ۙ={O]M6;Ge̙~mݙ={6wufNK9;vX1;vGhтZqCtt4wy'%%%eѢEk׎h =~!/G}~l<ӭ[7IKK#99?@w / כ3g&LPuNkS^^K.婧bҥ\  4 $qa$I{DDD`X0DDDн{wNM(,,d׮] <FJ|!{=^{5ΝK^^\VPP'|kƌ3ؿ\fYx1o3gdժU~Ko{q…ӕF!F\J ^Yh(*}E⬪ Z'//7xkVq7>ƣkCѨ:TIDff&_5 6[nP0✿k2e ]tC2zh)//ԗ?>}XFɺu4h{|tڕ+WKEEM|*wtݰA_}ozPɮ "1( Ng>C4}nMAr2=z9m=<3L4>}0n8:w?㏉"99nݺzj"""y=se|wuϝ;fxnӦMYdI~r-$&&z[lw}7z+s<ĉr--**"77܀~=e˖RΤIxٺu+SL'NdϞ=]菈+lVs/hȚk4+dZ7 6ȟQ )E|`_+3vXz=)))bȜ{7-:[)T'/999zڴi#?4ieee">yq:;w 8ҥKt 4ȯ8kٲ%6m3ivhv!@L(#r%ظdɖ\hԢڡ\y?C=TiΝmۖpL&IIIr#))c\߾}!>,{?s<ѡ|rssiѢ/ƍ{OxYxɴ>#Jaab]W ŢXW 7p._'OΝ;y7' -S0Ԟex}i֬)))إKkժ?#7tm۶^ctЁ'|$ap^7nژ3ΰvZKW7o.iӦe;w{۷gر-1c(! 1.4 w&11/=ׯ۶mܹs 233 ]vr6>Lc6mF>LZZ4jԈ~YaW*^d ^Hi X rvMxM}_v$P"E4 ))UVzj͛PF("wt::u"--RUm9[VJKK)**ՙT``OUUO< .\?LTT/Zs~ӢE v ~,\cz":b#DGa7jҾydxkԥpVӰrf-[*>uTTTp Ė-[O<>@ &L\NԩS߿?={FRR|vQXXu,**_քx::RSS0a/2&dZOJJK9r1:tQOˑ'W$ƃ>(U#hϜ9CǎDRSS=<Xz_^{ʂ #OP=W_e֭|WAG ~뮻0TUUa4}gJjvu0m۶vZ@۷d֬Y3F2JDFFmG,[* /,,p 1 L&ӧON ~Iaո!F)+w lEu@Ce}l}uv뮻}l29]6Dh4nݚtN'o;uĖ-[Xd vGOzz:={TuN5f1}t, p3ϰd1h F-? ڵkP}q& #' &DEEDX&Su4hBIGD31Tepmȑ#$@pa9,]ѣGtz={fD|i׮ӧOv;ǎSupwTCtҽ{nEFh׮GÇӤI0LRsk֬anpB!gEEEdddbjq9~jՊu)Ϙ1-[rA>gTܯW&Α#G0L{w8# Z-={ŋX ͛7su6۷oT A+0t:xNxxǵ0 TVVRZZ*Gsss %%\9܅j[ne/dCMZt[ɜ))0yUBiQu5|2d3f`Ȑ!H"--!CF~~>TUUI ^gѢE|М/EU4^7oƍ㡇bʔ)L4Ν;K/1yd6mC=ѣG٪lRmI&UzmKUf2NLD-IrDDYiӦvbb"fxۿ?8Nϟ?G 6p cp:$9s)SSOQQQAaaτٳgc4}Ƴ;rt:姒 ,QFl͚5<@uTeeetR?*f6Tرc~IJJ74f,X G}$7_gGNhժ|f(mƶm8p$1w\e\͠AcϞ=rwƍYq)-IСC||GL0'OJT^^ݻ/صkeee>/A~~>Ih4q뭷2rHڶmhh4Ҷm[nv8{,op`b~!W == .ȩwލjaÆɞ={$Ξ=Kzz:P}eٳg!pdCf2PAhCW[(i OF}r]szϐgu!r^woU VQFi^Oaa$T=z4~ ˖-cܹ@ָXFwq7uObb"6<.\Gйsg>#K}Y Ĉ#S%ו?p7T;h,k}u1DEiNZ'bgJKocZ4N ްC W_E| 03p@y9ۗd믧ŋ|=zxm۶ѡClr^{-ǏYfу e***[W]u{W^ͭު8p֬Yt֍;NW_}i޼9gΜ㏼۲(z嗹իϟ矗#-999kۗVZꫯc=ƓO>Ν;IJJbtޝz ~˗p8e^z1f:uDtt4<䓲 v뭷/{IMM%!!-[tҀvgk׮$%%a乑Zz!nFRRRh׮Çvܙ>ÇGee%>,> G7ߤA4hЀ{w 6z@G T̤yr9NGDD}{v$I3vܙ3fp |M }0h t:g&::@aa!]tӇ3gO|;Y`[nkVb޳gOؼy3͛7cǎ~W߾})..fQQQ1cĐKHDYY6;=r IDATtf?r̟4νn@ =J\Z}KK ҺmҢgϞ;K؍)k` ::l.ytU"!!AN-]Syw(e:t+2p@bcc=^ Y۷m۶a05jӅN#::"ΝKlllйuzoNmiѢ۷'**9\*]8UN|$7$2LWM%e,>iEӽ]SR#IW1qE||ٌlfʔ)L!OJ\uU['s=GÆ 7n\%v'NТE U^O?캧g.w wd%rZh!"%t:}J.\3L(zyț;rKJJZG̝; 0p@u\q9v;vP$p_Zn6~}u;{ȵڧ"% aNqYH{̬Z6qj2D:\, s䤪"dOnݸk$hh42~x***T>qԩS NUi /!t쐴XzU"&f 4DXk;%`b(//޽{+oF%z^=u]aX_NLL 111~?. ! du4_1*OIIq?5yo8qQQQ$%%h4-8f3 4`ĉ?~6mBA}T?T PKl޽8pN>MNNÆ kHPlN8J н+˜{R-zmBDGMR:6X}?%h4^jps...V'??_qv;eeeO]?.­F:^J0Ghi뒑#Gbcc)^)peHA 鰦,9N#>>^EJh4L&/G|jEmQ ďw'˹sī.h4>^6,.GE2@pQɓ'q:lْL&P9w\&b&Q>#IdggsQN>jRMMP,B @m@'0+]/G]}\oQDN ֯_O~v>gO/@ uq$'ORTTDZZ񄇇c4}^*2$ NUU%%%pqHD~vI\IunzuW :̙3_ tf26l `/ߧOVkP,[4iBbb>@ ~MuҞF!**xZ"ᠬrrr(,,=ոqLߧ`<}IRgs8.Be6 w ++K>gO#@G%A$-E>CueNi]my(? .s@ ;Һ' %TtJC@ |. @DB(kzP);@ G}w{_MPeJ(QW3TγA!@ TE} >oVa!@ + -WH!{j@ @ \~d2u!rǟ7)*222{&\@ Sץ~PR}j#>jIӧOPrr2} XG Y~@ TBV B7rP=p01mٳg@N:\  @ YvjrKF8A]!R:@ΟZ)@ +%]PPC} "w@ ?&Jh~UPׂ(P9I @ W.s\T*ϾNQmQi@ @pR[q־FDj$+ d_!Zv-Gm3ff/++VmKD~~>NVP,Xp5vZصk۶m @ "JI֔^Zݮ*fR=D9$Il߾]ҪU+:6 ovZ-Zm͂g%%%̛7Gyħl̙1(~{U}Cnnk(TE*Z:"Rtzx-֎c::*mĢtSZ*RqFD !JBH'7r!sG^>gc<3g|g>_y@6l [l׽urꩧȡZŋ/}Oɾ}dr5ȝw^6l:6l +Wb}#y=#۶m t,Q[pxr'< Yjs=tRue'"rgg1&"gh"9cc ȡnׯ+W< rI'ͼ׺udɒ%""i&Yj_^dݺu266&˖-{G#<"<@7?._fr+C,7N.gq<9ϑu\z2|yS*z׻#K.DDDɳl9;g>r.w},X@<̎@sAyq83;vء믿^~ )Rϟ/Ӳo>YpLLL裏}̬L (:3kEDn9c}r-t]+{:OYi$%5YZ<9?_>l}E2={HY2==-"BPT>gDXCz!Z}jS(Rv130::: ʲə"fhp$r]f[pd9ce֭d9묳d޼y>;w WSSSCwػwܹwZ,,Nm3kńNHy ^ wO~rA93嬳Β뮻N=qe)]w]V99rwΌ{zzZ6n(rJ3|+/YD5)[oU/ʚ5koۺuO{O}Srv}_峟?<)O׾3_,'t| _뮻N.袙|r袋믗OsU??9sȧ?i{җdڇ_^D/~q<֯_/MbMC]}ON^~FG*ψS|6n(\pAWS9#;w[QG%K._3]U0LLLȎ;䪫 .@^׈ȡi&3guYʮ][o>Z>ߴiqҗk9֊+dttTFFFdjjjfVIOzL׿̟?_8 ٶml۶m Ȳed||\o.͓SO=Uv)l۶Mvޝ}q'/љ{6o,,-[&v?~fŽN{ʂ d߾}u֙k8eܹ~7olڴcNh9ꨣϯ#8B&'''b#8B<[:Ym[ݳ|ߢj ۺh޽cG>KBOTYQ/R7f (uoP >19p@@^E!e޽#~a]ٳgOW+VHQgϞkʺh6-˲sia J3[)8p`@K--nmЯoa OyMܹseǎ]{JY2wܮH5u@|/O ,\g\h-v곖9k>kk.f3ZF<i^R5{ :3ߞST.Tp41}-b&;k}Pd Du;֋݇[nUQt|ךDksHnt#mm${Î?ARx?a DwZCn 6{^W`04VX0 D)op0\B* Z]Kj `(Xc9L)(BԦ aN1X^ի oThز8OUg D4RH`5uzv ; ulȲn:cY273DׇNMMgr9KBCc!cSv1ژuoP >oQ;<)BM7$""OQ?,n>TW\q̛7OFFFDDss1R?l۶MDDm&o{dΜ9r5d_|ӟʳ,IBMG~,߸.ՅN<%D/RDDwʋ^"Yx|C%Kʕ+裏[~o|cuWWR/??}C""?_-Z$""-׼53ד*v;#^xe}Ǵ\3+_kxY… ;i!cccREuw222"_җfOT,X q7 yސ^"󝞞Q@vMSR9f'<\~ӟ?,W_}\pډ y{+ ,_rI'ɕW^)GyzeK./rWHQ211!뮻NyYpLNN]w%OMu뭷?yYd̝;W*7{쑿SN9E|A.tuKP~TAjr+cz~w󝎟{v399)W+Bnf e/{ܹ3˲=O>яʚ5koWu}keÆ }ODD]w޽{koY.b{u]'-{ oY~zի^%_|}Z6nh H 7ߥg׳}~vSȪUSy@n香%Dkf~Ȝ#K&/mm`!z,/~;֬YG?,]TVX!""+VWղt,-hJpȡ0{{j1#\r\{wKN>d;w\ve}L~_͛3Hzyɓ~{ߓ>$,X I=&{Ӧ )+eݻw˾}YzVǏwAy衇;sdllLOԔ~e˖f@b=P4K28{xGğEj 7 W^ylݺUx9e2>>.eڵkO IDATk.y3)'t,[Lj?.k֬wrʏ~#+N8A8 f^?ϖK/T>ݻebbB>99>*{d3cK,lZE,eƍrꩧʪU /=irW5\#w䨣… ;Z|~f.tqJhPz(σte @~qƜQz>Ĝ#inI=NsD/! O\!=b!v|V~ Dզb `ٳ(*7vE`p){:OYi$%5]Gm},}@z!Z}jSK0'Θvll,TUS7m`KlYFg! $?'eJ(섚*>#`ž[C_"˺=댏e3D`Y z Ƭ{ Zђh.X2q] A~Z.ș DX =F3ׁ(6UU*0 /Kπr} GMQ1ëig>D@;hMYԇs55M^@!͟ ) s=D)+1;G,?ĎrtXy]=X!,{E7N.{T)+͒h {?TR/DOm`xiӎUj`]Muv-h>D14R`"]䇺dl] PS:g ~k~@dYg,cl9KBCc!cSv1ژuoP >Zr푲PѥK7Ku$O9B_kDz8hf5?:ŦJfePTi J=B9"`x5 7,@s؇hɚ;KT:sK[>D@$;Ab3%s-g)\uh,$zlj .F-jGKn=Rj?cɜu.t!`i gV(;?+b-Xvͬ^TUl0,=55 D'W(0C ZrnR^5YsgJgRb@4yikهh7s'H9Yzl;>+?"jauSNcX~YRL;"0`b=P4Kߣ6>>DXS}J J>ugL;66Wu6E0%,Nm3kńNH}viv%vBMp0b/ReݞuDzd"`, DM DhcֽB-h GBMG~,߸.ՅN  ?- e~"Wvn@*c g@R( f4XXQMJ֋c"&k,Q[C9&/mm Oc9G"K͕#bg@d9Ym:,`i=rQʛi'\ RfIRQ{߇aO Dէ6U0siB^5U.ӦF@Ėim}fmЉX).MC]}^ݮNB3[{5?Ej ۳X1C pס豩Hm̺P-H[Iҏ%sץ 傜YЯ@䊵cYNm4zbSUr A [*p4\ 0k}k ʹIzqCd͝%*qK}9GXQ䥭 d" {̝ 1^CdC@{C,'MŞL9bgQTn Jy3턋8R@u?,IJ j~v@Xc9L)(BԦ aN1X^ի oThز8ϬC:K#!ڥI~O˶ەP 5U}F`}懾H Du{˒9f.:4=65iY %7){ 5]dT:A0\3+\z,IfVCQlTa6^uKԓ+c!Wpcb D97)Y/}vКD3n1k jC?ARx${,=S6WbvhX~rdz)B,?X, D)op0\JSV%I DMnh~",>%^VT:̉3 իzTM"[Ѷ}bB'bi>D@4uzv ; ulȲn:cY2 0r…^BǦ"b1B|#eo&K?o\B'H rfC+Beq@;ij~u MU13n\_Q@zrr 3DjnY(&%űZ5wt-!a DM6}v'H 1wĜ#zygxJCn 6{^W`04V˞EQ(ʹ.K)xJ$)=mcC0է S*^Z9qƴccczU*XiS]#]b4ڶ>QLD,؇h&>Y/nWBa'T-ߚ"5YYg|,K![RXH@]6f[(Ԃ@{-$tǒ9R] BrAάPv~W rZ,h'6YDR9 `xYz-k8jROPa^MÍ>5ܤd8!Akθ>Ĝ#inI=NsD/! O\!=b!v|V~ Dզb `ٳ(*7vE`p){:OYi$%5]Gm},}@z!Z}jSK0'Θvll,TUS7m`KlYFg! $?'eJ(섚*>#`ž[C_"˺=댏e3D`Y z Ƭ{ Zђh.X2q] A~Z.ș DX =F3ׁ(6UU*0 /Kπr} GMQ1ëig>D@;hMYԇs55M^@!͟ ) s=D)+1;G,?ĎrtXy]=X!,{E7N.{T)+͒h {?TR/DOm`xiӎUj`]Muv-h>D14R`"]䇺dl] PS:g ~k~@dYg,cl9KBCc!cSv1ژuoP >Zr푲PѥK7Ku$O9B_kDz8hf5?:ŦJfePTi J=B9"`x5 7,@s؇hɚ;KT:sK[>D@$;Ab3%s-g)\uh,$zlj .F-jGKn=Rj?cɜu.t!`i gV(;?+b-Xvͬ^TUl0,=55 D'W(0C ZrnR^5YsgJgRb@4yikهh7s'H9Yzl;>+?"jauSNcX~YRL;"0`b=P4Kߣ6>>DXS}J J>ugL;66Wu6E0%,Nm3kńNH}viv%vBMp0b/ReݞuDzd"`, DM DhcֽB-h GBMG~,߸.ՅN  ?- e~"Wvn@*c g@R( f4XXQMJ֋c"&k,Q[C9&/mm Oc9G"K͕#bg@d9Ym:,`i=rQʛi'\ RfIRQ{߇aO Dէ6U0siB^5U.ӦF@Ėim}fmЉX).MC]}^ݮNB3[{5?Ej ۳X1C pס豩Hm̺P-H[Iҏ%sץ 傜YЯ@䊵cYNm4zbSUr A [*p4\ 0k}k ʹIzqCd͝%*qK}9GXQ䥭 d" {̝ 1^CdC@{C,'MŞL9bgQTn Jy3턋8R@u?,IJ j~v@Xc9L)(BԦ aN1X^ի oThز8ϬC:K#!ڥI~O˶ەP 5U}F`}懾H Du{˒9f.:4=65iY %7){ 5]dT:A0\3+\z,IfVCQlTa6^uKԓ+c!Wpcb D97)Y/}vКD3n1k jC?ARx${,=S6WbvhX~rdz)B,?X, D)op0\JSV%I DMnh~",>%^VT:̉3 իzTM"[Ѷ}bB'bi>D@4uzv ; ulȲn:cY2 0r…^BǦ"b1B|#eo&K?o\B'H rfC+Beq@;ij~u MU13n\_Q@zrr 3DjnY(&%űZ5wt-!a DM6}v'H 1wĜ#zygxJCn 6{^W`04V˞EQ(ʹ.K)xJ$)=mcC0է S*^Z9qƴccczU*XiS]#]b4ڶ>QLD,؇h&>Y/nWBa'T-ߚ"5YYg|,K![RXH@]6f[(Ԃ@{-$tǒ9R] BrAάPv~W rZ,h'6YDR9 `xYz-k8jROPa^MÍ>5ܤd8!Akθ>Ĝ#inI=NsD/! O\!=b!v|V~ Dզb `ٳ(*7vE`p){:OYi$%5]Gm},}@z!Z}jSK0'Θvll,TUS7m`KlYFg! $?'eJ(섚*>#`ž[C_"˺=댏e3D`Y z Ƭ{ Zђh.X2q] A~Z.ș DX =F3ׁ(6UU*0 /Kπr} GMQ1ëig>D@;hMYԇs55M^@!͟ ) s=D)+1;G,?ĎrtXy]=X!,{E7N.{T)+͒h {?TR/DOm`xiӎUj`]Muv-h>D14R`"]䇺dl] PS:g ~k~@dYg,cl9KBCc!cSv1ژuoP >Zr푲PѥK7Ku$O9B_kDz8hf5?:ŦJfePTi J=B9"`x5 7,@s؇hɚ;KT:sK[>D@$;Ab3%s-g)\uh,$zlj .F-jGKn=Rj?cɜu.t!`i gV(;?+b-Xvͬ^TUl0,=55 D'W(0C ZrnR^5YsgJgRb@4yikهh7s'H9Yzl;>+?"jauSNcX~YRL;"0`b=P4Kߣ6>>DXS}J J>ugL;66Wu6E0%,Nm3kńNH}viv%vBMp0b/ReݞuDzd"`, DM DhcֽB-h GBMG~,߸.ՅN  ?- e~"Wvn@*c g@R( f4XXQMJ֋c"&k,Q[C9&/mm Oc9G"K͕#bg@d9Ym:,`i=rQʛi'\ RfIRQ{߇aO Dէ6U0siB^5U.ӦF@Ėim}fmЉX).MC]}^ݮNB3[{5?Ej ۳X1C pס豩Hm̺P-H[Iҏ%sץ 傜YЯ@䊵cYNm4zbSUr A [*p4\ 0k}k ʹIzqCd͝%*qK}9GXQ䥭 d" {̝ 1爱7XzlT/hrNC(?B%D"mPt؇?pxxs+X!TrQR6x;fW(凞H D 30,,>%^VT@ qYxq찺Y%tucn}4LiMfD`_rв:Z[z,TZ~@ zHYz"iঽ}[yzzvo$sw|964UC/KeƍpR"O(= 2Sֶ#[ʝw)W7YoBh$eƩi^ S=Dau[ٰa/K袋DCM]6s6[Timǒ+n pںu[NV^-w/&XᜌY*h39 _?_xWC:Ą6SO=SO=~@N3G~*Gr8{_GmH#~t IUaHŌxǥ|Sr(UL!ԈWSxc,4_cuPO=SO=SO׽fJw~pr -a+V\]1VGj6BDpn{ϺDgk*s֩={~ޟhpJ .Lϔ73<:xt/*T3O{S#y"H5& Zrqmyv-BE=SO=SO={j 1nqUAHkݏ2熣@TNqo.}ЅkskM]WkISO=SO=S?HgwQ1Ҏs/bckԮ?SLMhm@]ﻯ9 ,qSO=SO=S?(7xҺU8&hR9.4;k Q)Q 8DP(i}^Jgm?Vw SO=SO=Z;&n^֖˹ݟji\(ia=~wC:gm=ou%s':iSxǻKܥs"KcFЇU}^hG B+]*nq{rpGmvwg俿gRU D~KMSO=SO=S?hk?HpfuqB=n,ŽE ^`3i \C7hsczꩧzꩧAÆ-*Gk0~vb= W3HnP)nW~nU,L?3"wW] •Dk =ҫ%s~XEHg' ^8U{ XPlѠzꩧzꩧz꩷ևfVBCsV]wu{_t? Mj17cGw]Wʡp&j֧L8Ώsi]hYw AwlO(UQ$:CǹCձMZ#1L;$s7xcո;$#-~8,?tn Ph= 8Zze Uȉtvk݀S4*IH$ܔA;YеRO=SO=SO^Fܿ/yR1 v9BУ8ljtqnhq;ȹ3Cnm5^=wg{rri םur_9~O=SO=SO={}鍗5]J'RjB! v=ם_ӡMDcǹqҹ)V;Vc٨?;F=SO=SO=Z_z{yiWzk^⍉{Bc HtgܱB:gPou.wοuPO=SO=SO LBRO]:=qƂr̹ 1uR?X]{q[!qQO=SO=SO O+-'U}cڬNSN߉(ת%s}B?4ܱqg8sXȤ;,kzꩧzꩧzzzX}DF( Sr5H hBy.\и|csC 㢞zꩧzꩧA/q?Eױ0TkMWc.,<DygBYοnLðQO=SO=SOX Z.ił7PUY?Pؘvܿkw\Z*?pSO=SO=S? u&ӁzoUW~i r׍i_B 7AH;_ S!RO=SO=SOP_FjRx]}..t\1<4VBϫxuZ;?:SO=SO=Sk ?ccAH],0N,J Ҏ %pգ__"`TgaSO=SO=SO}n@ Zk-GmI}CUM?VHP1cAGK=SO=SO=?''VoUᅂAj%4^?ԅi_wξ"SO=SO=6P֧R)3@;Q끎5KP)oTzꩧzꩧzz{{o硍ʸ%X%}Ҳ$Rfb [HT  ,uj2i)IlNL6:]H=SO=SO=m͜ 8)!+^uA9K\"m, ՗ޏ6ꩧzꩧzRhbsBVh̤KƬEXf,KɝI =`CɝEr$ %p䄕^4yXUI9k a!#^4B~6px 3Mf=ڴF-w֛rQO=SO=SO=ufĎ23.\״]n0i~{~o{V+*s2 cTU3|$ IENDB`Pylons-1.0.1/pylons/docs/en/_static/pylon1.jpg0000664000076500000240000014372211645401275021134 0ustar benstaff00000000000000JFIFddWDucky.BOLYMPUS DIGITAL CAMERA !Adobed -o      )))))//////////     ((&((//////////"!1" A0@2#43P`B$5pD%!1AQaq"2BR b#3r0CS$s4`pc  0@P!1A`Qaq"!1AQaq 0P`p 7#_wJB]ZʹusNS!eǫ\جdm 5 κm yρ_1K:4\:w@,UDR] K%YW"E`kqs"F ".O;vrx:`;츶D3T ZeSrVy}75a% kvm1$Oxo}^^m~}BVUZEo͋B[ZKb]93MކSw˜{珯pؘWCTT卣 XAB(jVR 1ȶծP o}:8O;ы( xi5g8A pd7.M%жB1*Wa~\wѰ UUurۗv{3oU*ceؒ;\_F7tUsu6tvM\!UW ՉJ1T@(ZJ,aک%-LƬyVmM~3=x\rf!4j3*69CFyb|fƒU+8ywfeU=6GS#Ko7r2/5yv{'4G }R5v( cirwK+(uJ5Ma\=jT`4$iUe"3G=xNπO=ˑ&jUui]ցl6cPk͛yX'H0#tSBj\:|%1pM]7WYOc=8ǣݎǭtsbM2 0\|W=#{X!:g1<t$qv-P:]eq@Ffe'R/E iξf9exv9Cը峠u͗ |MEKVmknTm.<DTv8RfӼԩU"1 JeԥN7SҮ'[Ş磷}ԓxgsO;& ds֫|;^/[;ymqȾ`Y"W&<6.PfDٵtWNQ@ZÌS]uTy7to<4\ž$Ip;F$#(8nez]AmQзJC5V!WukhlԃfvyY|G^s5 `:1}s<3>t|Oy(HΙš3=fj C+h3I!ʊNW~K.s+pYiRIv6 Rmq(#TR-v<#bIu)p%1XB3+ANNie`Mk_BtZifE7^r^rw輽Xry^`;/AyҢ5Lz3vdq՝N7g+Zr|=>yx5?VSOԐHK3\W7:3QU,yR]336mY:ffǤ$58Sƪo`+3%.F|yom~Yu푝zZisWFrdh}kIO)1e֗ Ϡ^iv,eB@E=UJk7SǗ?fP4FwEsͯ*gd j]J^m\Ͷx<;@B53Y^6ul"+iO%ZIB5Tq,UJVPY啲SEVJd6?-6yݜΞC<zcɰ|uzv㽇B *;ίr#1U`Hshnj$4=Z @Xhnzf׹|^=x{|9|Ο( ^*驵fA'BpɪU0ŵp+dH)5w7c)D6Lh.3K_u==>6p1Ӧ##RYml]ɘKiˢWs ʖѭqӧ1*/E\g 5#D h܋Qp cSVѪLxh'MzVT|1D3 t5yLtO{| D3oL3M0= 0EC4 )C|8rutoig0;! $g ΁( YϢC9:&stj9^VM=M;~b9҆1nAK iC Pɛ $$BI $$BI $$BI $$BI $$BI $$BI $$BI $$BI $$}nrC>1m13A)_U ~>јfg^GubcӧՏCΓ}W3cqA)_UɿWbbc333돣B66NmןcW03Bs1?oA k7=1=k,@:33:/o&\Bao>{=%{} L~=h?W>oٯo1~3>>"bcLb`zbbbbc;c1:@ps3V~;XGG[310=__>1>Ag3tcԎU:L O 2=3X33韡 N+_Չ:LP}-j> xzfg?WI:zgMT# q2bq9щg?FGCObNF~Lzt}c=3q>}L0~>FLE}#GcٟhB=?HOF`tA1Xǡ1md̙\CϯՉF9Boɇ+lu}`&ZϥCWǺ_6謦?cJ~Q~3Ǯ"Mc3>oOb l&u3 q8WIșX+<|bL?Y;$9ɈUk,;b@6sΰ z:,UkU 1)Z㈄a330pNs&WQ̰knY'>5^֩Ӂy)]jqQ2ֆhVh!Γ8Ա9my?WpMZி=R|ygըXVoWE5 AqO,~"dγytɘh+$M $s2yθ FLhYY}"=زU.ە'22LES2x &#-LD@[r612}m8BqQ:O(:4ݷ͗\ 1R5G;!;wWkmSiO[]~CyL3tb03{+W!"f!TpUr_om)e+JE+qW&LOӌ&|9ݡBoj h5D~$6#Z 䭙hh#8Γ1'9}=A|llݍPѣEAZ9LgOA3Oh> CqQ <՛9R%[ڷҼf^-k]d2&b/JoS[~DFBy ^SGTm(|8&:rE6[s339";vnko/"-~x=_"</=̹^ ,sz>&}312#brLf81L~g36>°C+F wԲ~_JSs&6 A`} Fc#[hDœdܟ3a"9d^\#ˎF6r6NDx5%[3l6Ym!hԢqT3O!_0& k*LOjOgYӃ>Fbc$vIuue-w^yYP-6~8J5iE6X!J BH/)>rV&P+˃<=fwJXROvlACQ33eަͭ_ܾ?]lu{ldN'zySm6]˔["h8fZG2g&g L̬!>똄yveEa /,QXaG.CqIzs&9A aQb2BlpBEGx¼a.|ŷdmXWJ%6d3u~ӷz*G$rv8v"\ŶE6KBvBʰn/l^=5VMTQ&6r-f,տvUxlrgvwrMf21V &sz fz)'2pT_dw}b6ŏoyc(ڝ ZR]M@/ l*:m@xk?Kg]qmu%yܾۢ{zgӺ3|g38<[8b1z`GJm51~>b8N Nh|W!fYɬEU5:~ETgufs2Ũ 5Y%LPC֮N_9ngu'o"!J]Aԯ q0IIN.bՀ"6V^jk-b:7cu[{ۘeMy¡`2a6{l%Vq٢{g}\7Qٶy{go{.<_YRˑ`F}~8ϱ0b.2wXg5,j\!Zr}M_Rx.yrD6Yh?^J|v0(#F/c*0,.šq^1ϫc#ܬYdooUu*\5 8M G]{6Q_q~'8g$BlVsp=>@=jj]ܭO ]~!|7kQH5akeʒz)n*gf&HRFI=&[3@HJN@6XNP: <Sڕmv://jփ1b_-H333@S5ˑ[e6-AV*<:mϧh:{Em]mٱ,EI=uvu=R'eaZnum5ݮU[]Tn[_P.DSP*j?DCa]'l3/y<7ر[٨ansN"^|+m"p3CWnwNI2rt_.M?)~~> Z@X3u&}ØU[XPNMl%UkTFTo.LgX 3k׶ CVp\T ?N*qkS۽7]Y )kJ6uM}HRubg1ؕUhB㕧1fs|u0F,ѷ5 m N-hbeſ/c9n]Sv-s:5~?C^SUAW)coNeZ)Svngcyq0`н0 A9w$XqpkXxkwxE5-axU7/Ty ,e,VϊKV͏OyNf&1~Z_RK,X3"ArulY46kaޟ/!2r$!X,a;~W^֝q?e\~hS<;h2Nbzec3M U{, E89NK]E 5]pWՕjmdOhZr9hmfBwk_Sϟ-hՍC] F]6-5VǖJTcfZ&|?qG]}_L.Ng SX),آz N]??fj#9]{ti/р=aw!( W]ږ7 YmNvvvdjte6]rYtIr[Zcg +Po=x퐕I[2@!B8VMñX:ϰӑVpM-أ1s6E32:_U;:S6UjT4_В:Bxpa Ghnig;&W5Z-[1Ko#mGH|O6_]~?W-vYnةv|NǑ}F{jլpUKQjVrŨCb&&p2UXovK:y C"Ukm:V+V'%py1KX\}}˃vMGd,f*W} hhҵUSO!f8|-cE9 t*R ;vK1ޭt*LC,?ql |7%­w{*#ѣO j:ƾ?QJ}o)L1kMX?v`ſ-F\Abc6ri㐮+36I>BIo6ns O3"3Oyfzt%b؎V0(&g3"bO W(JCJ*^ U[v9|lybO\WAbZݫtukvzuVG36K"Ӊ2aɕRa:;V'eQ) vE::Ya3G#zn1/^Qs>#3A*xUuD rK\ۣSKQlڎ;kʤsz-Hc X&~* V$zEYΫZS4:sp|@<960*b;maX 6 .s;mkk+v֎^B:VcQFHz)I0=2H5 9VP' jυ|g)%U^OJQfKGoWz:k3_WN^'lA\bbq錉I썰[GI#%eg# Ŷ{ծ96Wlf[WtfΊ絫]XֶYnGjʔ ]+;T081B Ǒm=jT@8UWm[  M%t-ڷeϒagqޓߪݛ J6T JE0ŀR=1Kowhu,{Yc6ܜl৸xjܮ'\AQd_KWfbF!WXmvqV$~ޚX?a} ʼEaIJR*VKkS|?\7mxq+T5/97Yr0YBj@rmIhurx0~" w}71'aDOȭOP4ML;P! q##seVvji6=btM_#6`cQ9}O[%UVrOe4Pp{S Uu4!ת6K/ ]DE ftD= &G[ WLȳY$Bܧ)vg":!#-b+ lc35pSK2O ۙRCE >x#qq}9bE:nEzrDK8:Άc$OLUV/gxںcYZBi:R @Tv([Ԋ+&u|F"NTLNPA=AH㠜#G#'fB2Vj{Te+7q[y?O#eully0WvY. E4꫺ף.IVȨa` L`̬qDZ90)01mAÁ !zX́k[*KYW-Gyb7IکbX PȦ:'w\|_:x,4ќ,mJN L 3j.k$M~V mAQ aצIRzSes9tOs3q98tʙVfY/l**g_wiN#W{AO͟-_ %PLLW`|}|_?%C4U.j׳`m{4Jv[&5`]P즃1jjcئv(;5N0*ULW;ujs\*v띪VTW;UNST;UNSTU;UNSXa;5NPIgf٪vjQCq* 3LMMJbؠ٦~>}yN3F3TU;UN3LS;43LQ;N3DS;4_^]}u آvi"vjgj~=ii<Ybj$}x5oNjxBtWHz}y蝊'?^ M@^-wAzeE\c]~S3[u,Tl",Ze"һaڟ\6wp6NRZKo(ն]k.bl=\lJ6;C]]'arv[f#WWkeзWK/aE\u'n,YkG[WpJSUksVhV^KF]KZţ. wFp5ik+]nThwkW^!=V?MPsζ\=סΫv-Y_?6`8m m҂qPOf{rfNRLpMd5ǘ3K۶Ԧi-wX Й $0z?%t9mE)mRu;=yKJvS150Smzl;uME̘S̈́0M֋Yx恓?W;{˦dTfc@dNBv"9m;wOq݂;*xferɟON0{sr6e)5:aNM 򡭜>J{͙}${c+J [pY?PU~ |ZÜPl;#1br_ӎ(B._mDk r,O:ʁsCw%$O@}#S;ݙ@`R] le.F$ FXLR7=i TMn1;m=;Us=Ewr>hV1nhe wi{DOoԻpHL0MnNq=apG0)yu;(R!mmv<ޏ)NjbLNF8T,8=-::IҘTLsg?0jFЖ H pObcꔾ}RٓFF",P&戌cCZJry R.ܵKdPh5/ǰp]BnWa9/6=p2?gN(3Ut#Z_0F!}!լ)|P\GEͱԇC1#kVUbXQaUN=;Zmw#W8ƪOPL\S@VĐTT]nИ(Sa+rLzL B2D Z֩OOT_A] w1\&Kڪp=݂p:WpCSWCL3T5V[\1ۍۙeW'O9lD}MnE߼)e5 ”fZ#,uN5Af6)*˳.h =H E!W܍l:sEK:M%2-rJ7VW+bm5F2,$ Ozf.ޞݩn/nDc8d [lr|!j5>լPw&jܶ@{0K| HԵ2F4eBmZ.Stܘ3ܨ0Uϳe|ɁgG"6~u:q&ĭR?/;(ϥp˖,ŏ7J1QXSLnwh[׹rQ;>AF8 uu_vG_#Tk~-{C\Ј:]Du*sbL*w&,OMBHۂ׃ў؎[ eyRۃHwnQK[arrc9Pư 3+e g**vQ9CyZF)Ĝc=8"#[kU}a)0C"2Nނmŵ :4jY(4SNA]?Rha/JrD5Te )eGt| ݒ(# #݉M8?RY=<;-3|L|чIdӹ DDX%YWT(grY9aOjv"DvC/5?qS'r4fd"׆WcQ\|?j}OQxz7cJ0r'ޥya9g!Gsh40a 7L'ifڳN<Ҕ?u@ޟ1ٓ Z ā_+Ӗ6LL5Πjgg-N(nQX $i£\Ol-.EKx1q'?uu1TMTLnv-JTb1\a ~2wX0 w gDd-I?]8)}G>!tL%7DaVxv7mƾAZqSd$;D%PHCNޛr"#ZFb!?1y98tTEUVOi' m`UŬsDO <1C40< 9q7/6vWǰ[KRTvn^*QtfJmtpMBA,0;G~j1'ftRbc;e*DP{iS;;[|yҝ֓MMiͪ2=UrO>(~J@h?bnf:b6m {U1 O)*晝1]0bCܩ@;Hi"3-7 'rsF~xBߒQ;{ Jf44 VpBz*z$LaudGW_ED-NsN$ #CQ~~@qQg `bvFA ͫog7۝?յbu\ ]JѤ"6nE6rd'G/lZFPAI 8=c2$1}zUNOWslO$%,KʑlF$SdvxT:ޱ3*fJ-6eH8 IBb:ƀmZT7I'X>l;rvD^oAQ ,U;#hY ܹ:kV'Q0+L&.쯽zW"c+'څf}Dym@>=T02r="^]%`9N}8Z;TG'#闎4$ӁQ&;sq lSؤV 1իCF37C锤Xp d[k08mT?&5ۖL`HZ@,E&5 աAJmX&LX~a91.I_Tp"{nw{^bRie#[Vߥ,`cXBs!Jg/ ťŵ@8)m(>W?'ʖ[|+p:zBaJBQ}8<) k~Z-ZR u6A2o[Nqܴ[.\g'Rf4$!rMlD/jr}q<-p<5Le0D#HbL "t|M,2@r{:5}' G!@l1j7ci#/YgM8pwU~gMj\a*zx{PbN‹= w7}`H![Sƺ<Kv֩y~ /Wv\gRvr3%Uh(jN}̰C]BG RȖF+X/4plm%^< zlN:CTa99hx"£Pl``>+L`cAjyKVKf5K uaj`ʃb}D1*ՠ\s,*@j83K##\{!ZetpE͕0nɌynKVמJD8d\E;x"]j T*X;p9J VN#J5րg \^ ȁNo͹Gn5q!)ݷٓ5[@`Z}"=ke -F Q:Y棎|u .ǷY?2Zpbr埈ZI>(NMA܁&`ܫT69 -ۗ.wQidzQnIƽ"be۹q=WeޜN`aùF Gz;6rIr%|{ItlQa;PP+q$5Tq{ޔiHm'ةjmCusE bsle_]bOަǛ"[wvjsTZQ"}6ZlMS.GJoG,K cbN͐:pp/DĞYs9R d I%1pK1չZyhN@JԢ*9Olöva UW L-Kzڴ8F9eLd شQ[9cv&rfOj.F8?BژIlGfxwQQ;pOrB;]97D߸bLy CMbzm2 Kcm_2{k%^ug*jT{[GGv>ASj,NJS5cPKx*[;p ^FyNcmSK TةYmp TU]O)JDpv5 $o8&#^팱Ye)@,j kmG3rJr Д5YfbUpmF* <ӶO,78dyX T5D}8w)zPKrNIu[}{zC{ ٔtFZE;wcD-뫜c܎ _V']&q\Վ]FJ^ot#\26ƧO MS,ugٿze\;yAvǶs3i qQYz9Sk|8)[#H=(Tw{б؟DZFC 8f0E*e{֑G~́8Þ7x+X e/ᄏ=$3"!rC3Osџp? |cj!Kw-}nۉBqr$_+Fψ,Ubj#=:eq_ʐ'O/s!Foȭ">rN2bػzr$j&ŝ"nG(ڻFɁ 6(zp2W-W4bn8ͪU>(DK=N}A!lѹC㴩[1a?kz8H7+pDN V@C`Rü.ZQG޴-85 9ڜ2T ;ٝ.(φ;Q/)'2FlҖ%i&< F69_m:`czu(c1m=/G7x`$76!tu55٦)Ʌ=# UJ֠m͈ȍrs~28`<{+UBGS[\w>F鏧0tY /\간0᎗^UPqZλ c^G+kTMDFQG2$t}C\lj nzD1+2=`c @=)=Lu01Zu*##k`f.v3>ŧi!cT1b8-L6Fr-KIGP|lݎj R4yS^Tm:7'"/xN9>PaZ%HNڨD])T$*&^q]T!IFznKȒ@@n {*R_RHb>)Mɘwf' حu6Z V㌡O,ZJsalصNQj$ֻ!nz%ϴZ\ `s#ںN b@ )V)[pL(۞m eP-MBg;$0[&2>ص+[,aM4Az1FŢ12=ҼډڈtD/=50(Ĝ> $4@zed4gj3z'pSrr2HD˗C{N$у2ڰ#\pFoՁ2m|dD00hDXpЈϱCx܎ gQ6BZZ.Ԫ @FWS*DDc)V|bX;Drbҧzޣvq2Ž(6ZWhR\c%&uv35x `fl2?fPm6`k4M[y\#jWIwKoɰ׀U0<|٬k>%KECK#6mtW!˲c؟ьS<{bCFn$mFw (w`.|!DIQҝ0 2M}ڄHjw9DsPm2u%0)rk"6hSprU{qzȚ#upCVz2Oi?TIubfC B_W(a<(j3\up,]If3L3Z;~OS>88btTSw+^Cj`d0ޜ\9EOw1 [mJ֠@vzj jxjCl%3VQ2 G֕џ9ֆNtڄj!rW\R\: -c^(ypz-!s;$a81k -YOV:~)#;J>)]Lӎ#j|?xF˟oVtW`UKxa$qDl [MQŤޅLij8vW|$s4DSĮFv\,t;GKĕ U\_Sص"3zGp3D6H=H)gZ+;* 9"̄oH?r:No,SYmuv1Dv+'p  #Mk\HTVv"1$=-Oa/QoӜH1\?#/?CԳO،1)Sb۱ m-Z̉iT#f@}bbvΧ-=oc ]z:D\F1Z&W6.^On6 He#U P5|4V zrfB[I;cC[J/R#. QbcL-PyIGڜnMm^rX@K{PӬYO߈Bܷ?ON@PVb;1&ANQWyrizC X*Qy|ބeL{Ԯt=LrXuh^nR5[^芕Gr8')Hn؁wd& \S ؈uާn_Tg;ʟQ82-W2AkcSF?{np{b#vU>x/{Y4 Gӟ͟n"'ͪOOR"2"=jzgG#cMs Ft'sY-?1UVW\Te_PiC$Iz2i2Q/EAfploQr ҁӅB74>r!Il{arrcyoQ.j&#l7|qQ(P?Ƒ=FX[e\7#rv NGq_N(O46HsRvr@a!n7y>[ؓ#vj.N͔QJ-9yR,jIBx:yUFԏ|B1-m#}C D6)3Bq\`¿0`aR"&aTdϣ*!ystFAC3 `ON.]oP.H0ekYr b.31&/~eW40%)N]5Ѫ BD(f Fw!pp"ۓ޵CLv)>rܴ.j[FXSQ@Ȟ b͠p=jȟy#)i2ȜC9&1ݚpmLN,)y{j r؟;r7.\.muLڇޢ@m:sӎ>Sa$!޴*~0T/b/ݽj<#&òݟrxN̪Dܥp4m& VLT? ]1n--9Hɳ`קA\-xm3g\֬rFm/h9WAH I&kV#:h*OdR3(jFOz~@ 2,^.=1@5veB&-gQ#@NOzxDo)UI=`C EDkZv+rQVʻn vlJ-w] w4#Qtp-BপD6bY<>in*qyKN;hE1t䮬-ݒn!?yBࡵL ymj/'!y1"qdOdїw{-ݷ))6vwb\(DFR3xvuչ^%֑M9|2ޱƪu{<y{vRCIkoQ:Ŧ WtҼ A1u79f;TR`e2\"@0"}"haCA*i?l'>IoM؟e|4ݡ<YTܛF( \K>ڠ<ȈNք9Yk Fίs.lv1.nLMOWpO,#SmBY57Oh6W:{ca&G1B8L82u~1<).~B\3Luiv0(J/A^5f*D"&9K }eJ%j3<7F_{g Kc)8`;r`A~PluK{Jr-IL#Qܜb?.&Gi*R L_*,)BrX✀{1Xṭze3Q'=o^ʶb21%Ͻk1mϊN#@ GHPGԅni=6mL: Aq*VĆ{$B0Md䵏ry 1v`Wb<ǫokl`-ʉ#0ž)]!-%iF%]no$oRQ򟔎~Z?2ڡ{dԘ1`w 0;-mFUHPZ-6[Y&醣:oO:q#`P.mz5ܧz~ϰCž`Є+Ur% gѶ$>R ] Vq.lvıW.DD݈CbW!P⥪":xZ.OOޥvA1q䌩jnMd]=9B/1eUJ24Xbw3eD\hR|? z>>m?4%Nmu;0Sm- q XlM,XDe\;5( /H@A |g"䜌p y.U. 8Dӂ$23qZf4fGbK'`.pQd.`) lGM9 +7-JHAwOqo;CV 42۹?f⽩ön]:l)@eV-\qe )l SST0'! M/!"%&4jQbMJc@Paj'͠?2B.D_Yyjv婹Z$S9;y%3*u湟1}Ոc8S C)MK<v[Fv%n4kkVsVL5st<4݋P'{YmS7W6q"TWVUZ8ےqTrN,CWrhp䎫|yP==n(u ~mDSQ;]٪yFjz_ #tQ>Q) {k,[\"FxE$] bu $Q0_nHdž`3aprκGObfg{s-QW#lrwνł78^1o^Ko#ߟ.Sq[U*:"z` 0܀HԶŤ@JjS$%nMlE&ރ]՗M_< = u*=h J'Ӟ*0D 0u+Mw:ꅩK+(ۋ#ӽ"%"q\k}5gP:F;$s8jbar,{-#aܭj_t 3y(XU \fBfU^_QS+S ([I'>O 6d[r*{{%("*!-1G|bxO5HrjJl{e \FGp'p9r2'HVV݁Snj`Z}]Vs%Gռ%~lV.ɇ$UJ=%9iǼ-ZO"RCVi9g?[.pL?ƹ3o:jU@ǧ1EmP( _qb4gr< ً-J,.\jLIa_tvȔ"pZ6Ъ rCXqBCkNūgepQcO.=˗8g#+s"؟BjK3x-'w P>]}0iȄ[!Sb}: t.K wT&dnNB:ҁs^t^^=W.h2Vϣn5`"k"F vBպHܕ@2ݬr21_F"a vƹJ7؀ <ùJ\r`_ hO=DɼWEwe-Pn&8iDHC6=G۪P;H zql|RGp^Hq & TNaF༣yG <a 苜h>  G/ӏ^H䏀^H䏂G/$|GG*4y#:" Nj >,N>y#>y#>4Ċ1 1J2 MܚՋp#p^kF͸0/ӏ_Ӌpv-Qy4s_ 7m 11 J28PJB8HMŶi q  N5Ɓ~|8q B8H_ B8_MAH^Pl DMrڀۦNmޜ[B8 䏀_ >~|mn~?/҇ڗDRrXJpB7.tg9VRxǣP,j8N?rcY#grtcGiOjQa=ȋ]=`#pT !~?/҇qJCB2-*EPFc!v^ GN#We<4ޅ&NCk 6"1ӣs7˭B -Y=C!nB$Sʇ!u5Ory2W!.6ɣ,UbљiK%EJ#kς3{+Mg~`6Fԇ,u0O]j *jMCQCXi!Kkm 3lbnz[c@oAs z@r$ ׯtiD#wKJ/#:kGpQ" LN 6oBry"\98ܢt 2L8(喚͉e~.إwC鞍 ];DjW-#t|+-'ƪ #p'lF< ͝"FސɅ6ѽ- EĶU(H2](h 0Km#кMb_)!feKbhrx%8cP"/25~9D6F嶃 3ya8P$% .RZP)vE[cx۔H" ^$Bw:yUqկT0oz֤#6 C19=ˣK@*ހ8 H >F06$,JtsF ۹ Xje)> ([7^dSSaU:n{J{*.+(O2_6ECxgSeT {a'P!7Yފr֊3S; Ҟ=r˗qxܴ5#\z"_+Kp QU~6{'rNBjh #q|Kģ̯cRn7-)75ĹLW6 (Dpe~JyBmCU8/q 7_4~XFSFPqjgGfy^%Nsԩur̺/w?ϹBW*Vp2Kes"?}7^cTu:9Je1ru;,#̦kKfzXJ%"E7 _dd9JϬ~,b\@OGS1**5̈ q4&:. yZ.g#be3'R*γ/2Υ1?1qs/L?\{q<@f`\*qHhOOf*Ļ_N#[%b{2׏|Jq{r*񫕝C: x{~j+^嵒fw+Rm|.Sǿ3>&yw 4y>uRqs]LgoQ{6-a_$kQq+.`-Ya-"3]KqW[Pʸm%Z~w))(tJ:%J:%GDQ(tJ:%:%GDdSQ<DDDQ(tJ:%GDDxGDQ(Sx AQԦy??`[P<'DZ92Tn%eXg99CkOlM8>&j0.Ub\oܾܥ=?CTrz`6^?f[%˗̩ee Lp 5aY?nT.TSR '0 (}ŮK]+~q+p+ %),A4Y1]DQ~%/4nT^ /-Q.6~4z5 N_OnR\|Kv\[Ķg|F__Rs}0~\u~Q)GZ-+?.$ī'_"NߨD|_ŅM@da:!+>? * {:.1,RY#WW*g"Fŀ~+!zŇ^SNރ->eYZ8J߆q/9J?,. ?V,4 +`9Se[ Ӳd@~1[1krڸ2g'RW|bVf;_0=J9eKb{\Pj֌uLKw>%Aܼ_(9zMry@<D 84ffMj]e"uQ7^YG)G2bf6B嬩2++>"u_D&eJ^cHK!W~ !JJ65}0S~|Ac߂SQhZbe!NX+pƿ77iP"B/_Zb\W_?OwԲ-U5dpmZYsebT ^R5/".f-aB#1LC,+Yb|V.\GeY:_pYWX^\ˇ8%\.W,fgHnC+va{GRK]Je.k2a".?mUq. 91bTWvcƓS2X 12z !1 }Ww=KAxq94>g<pEpJ6*>e{ 񈟒*|g5\̦TjT\fd5~eX$p9YmuTe.[-[-eorore{-[[--{eolorol[-{{-[]IT3p5v;CnEW\8m/>ƣ ௖\fmuMwFj$VG16BAkoi{'n<`0Akq␾2r KvQ13:}CK._Iə6gp 8Q&ZP񵵀"T/<B#>c /~ǖSQ[˜߹oljS5"hy> nSsDAS+8 w\W0** pqy1`+yqeT[ĥUG!@̦"쉂G7^}M%|W솠f+RSkS2iۓPOCŒܮ=VHmJ]` ƺ+蕲PTʀ$vDV`sV.*Rbi^Rh* 2Xsr jP)"y>f1 2j^@&w[WsdJİQ 9Ơ\B<gz#X4\@+-Mo|0S'$u[an7 [;eqneW(E֟ZNfRrSC,]/j̺QL>aO1Ջw̠2\Q1\.b :u  7K,a/J 7g(UCk1 I4]@ZqP@XϢ,ҹp}T,e%*%]u`ǹԻǂ+yKU. g5A~[?o<=Tı ȕn faA/ .P2@hϩ`-_Xctm ]BPƩUB`/y**R z= `1.$8mcQC #-[(D,]Ne-Bϓ (JxOŽ2fA- Ʉ< s fNLD6sĽTQr=M™ ?hGCB  [jS1JCX yO{2E]!s%e.ibpր@KTZʲ#ܴr2;.ZEGJ ,y~e,2A?yk U o+r7q u旈N1Rp%}uV(h>(Ap;w0MsCM>&dVĴmh5=}X!xڌ*Ox*`#16++Uj!Q2!Z9YYʵV]M6Qns]߬gQxyF:,E/4,S|D|JM/= Xd ^+`i淈q@ݵ)ah̥ \"Κ<_Pe䨋 T@'+)_va cOqýFvZ۱3Qu q%ݰT,H)^GCR.k$ xR'#l?ut 6,x+b!fVmΫCds6 솢4#=JFs-&G kZ =(B icIEνªӢ䶛EFk^AKp~8.QIZk5WELpw-R2ʡ4*mKs%1"XQ˹E`&8Mgurj"$U3z|P]xۑ#Ү^7kpUub12()཰YlDBCP `̵ FB <%_0p)b 4%(yp4V4`e_3DEǹjФYn/;ܪ%>GχJU2mMW"0H͉QȽp<*j(7R b|LGJ[S#RLC#s$+nWH2.># mωDpㄷD^DpTLeGY9GpK PV6P3p绎"O&@j\<`(mHo20x4 SV2[34*lCɨrsKi%.V+֣b俥KrӔ%O1q }&81;Ack\a@ ׈Ern``teZ(y/v<5lRP0pQl4 -h yKNa]l^ōiQ-oPe]8`RjF{&x%=2TZLY譃V-X ۰&Ztͷ)uFAu,,z-!qREj4f۽8֠e:*9HM[QuQ(BŷTes},X荿>9 l\#䶳ϩQ,AEWF0]0HTAe6b? J6;UXRΘ\9FzuP0i0m;GmsK@yԹvq0^ 42ۛbCgK?03 Doa7dcbx58K3iԤQ} ["uAG*dԥb*kA% {*S'=Ay%,_{PJa_X0\L~#ۨVnAMPwLmYZnzqҙ{`K)4Sڧό3mM l F걼^@[LWkFY jJq؋ ?ܴT[k*kTs`LĪ?ʆ~/Q51:kS:¥}G;a)MPlK%JgBE]KO:^BEu 1̯?S-F9jFwn^èCopK=l?p u!wn!+k,JE.Z.nk rƐ( K)uMM.BiCv CiK eWmOjիc,"2~e(u2]͑Z058V5 o9Q_pZHF1 #n&D3gnDY6mPSm 2bM*46p0m%犊iN+#5]tC\-]zVc1ӆ凓.[HR@|ԡbȋLCTV9 SGC4S^ѩw&7؜+, 0`p;;RD ͦX,ڟQpo x[sتոa7 UYBf6 \~1 7IZUnxZD%JM-ş/v5L0zE),]Ŵ*]Zu,)a M&+fwSA2qz+DEXTWs,lؼk% ˷) kq\PlաX QeP!ЅDP@ d`O/0a+ī-4N(u719dn+Afϸi(bˉ*X.ly1N ni kU(;N0ߨp>՘PnF*Bu>#b=Av 3 ʈCPI]. Wu,j+e˺8Q&+ޡ_FdQ-'P*s6&R+Pe8NS- SsU}(']Ea+mq*Cmx nYmp22Ѡl@Ѭ & cIM4[`*'pPi_sڠ0=N_4-D>7 %_#|@JbʲlyYN&gƥ  /\Y+&.V5)آ^aE |( '\dL4f؁Y8%@D:-(<5٠B1|Pbb0a V5JHrr18>iFF gܫlL7p<55-.*j'XT[T[XCP<%u@7)ːMfbKNoEMtOu}/k 6O ^A3 :=ZbCTzc Cbo*Qӗ! vX\r+`/O4l0m6=A !D})]LOb ˦ 5Rt}P <7t8. mbaݯZa*p؛H%u_-lݽ @߆(23KZ Z]# \b8efzj 4!UM@_s 8AT4uK#Z//.  ԃ7s2&5@8Z2)q,H)@}]$ ye)#g86'SQOrmn A_ęPjMSj[K7LszN{!Lѣޅ2ТӢPŠxbF\NeaīD{Z/=бiPsu1TG,M"J@yj2 7Jh{j,3@ _Hh"ͷ19JuZmjܡ6$/^DRA֩;L)=fux-ʣLURFX5'Fvq/l&^_O+FvU7pfsMӅPjn y=GY@bJ^|ѢV(vv\E_0]{6'X`z*ŷQO˨vb H6Cمl0^_EGǫ,%8M s]dsTVp  Bұ!Ʒ*3^[na{q0xtx `ΝB[&Yb#CyƉ\0##f`4݊O({1›!R6!χ;|v\9gKIS ]XX#Jh%\xP ⺔U.!ڿ}NQv`!]ʇX8c{ (; c0}A)1wf{RH;~W\`m ²ht44= s([up12˂!p :qJX7yөC6A&/|tC-X7dJ3,Œg zuXIXJz\YkR~fp# 1o쫯e@B|\(c Rl&;^ {ƒnvp7A5YuV×\3EXRZ.Nq6BoW)t1uD)_2 y;- H֯q5꫈r_-<1-hڭ-䖨!fa^CI6cԥ4^%(*R,O UnKgPFܥ!I6gxy5Uaֳ1Ħh薆1T=0{t+e6Z1Esvb s6>b[|m9d|C8  {f} aAW_5DPӢsֺF%&X. .iy(BCo!!w-Tr+~GM֗oܨGҘ qqR@ϙ@[ko(9iڵuE11W!=^ౘQ[L[a%:KmnfH` -/3`QR $Q$ꃲtWS!^9mC(}iUK1BQ Kv!/ ~B 1qķZ()$:k/"=пqse×!~e4t-QT=1E]`KNP^V 'lUKJ V>>kˇFfl3W( `Y\f%\`:EVajaޥ.98(} oBɆɡ䋍{eQ"s\L2}JR#?fV䢏stI^JIU`UĥlB_iJڥ5K [kX@ DͿ "7(/y_y-.fEnQBǜ[>Y|nP`2`FڦGIJXc(h匠d!LB?!;M* Pic{eblѲ5+.&+}lO*Vu5-MOěEVm@,ψ xQpAhklri t ZY|EBц(;yO9(9VgQbϒS^f@̚ "4/'t 2bBe3Iu ua:a2d*s6Y%ۚRiίt _u;щ2g7[if$Sjobdk 9ے{2mu8/8"r) 1+9+s@>"yhjL*K^]^?%70!i)Xa) du"צQ*:ĔH*V;XJ0z%V,bP12 Ѭ g"f}ԩvT~`1˗`jQGj0fYuW[5EZV`Tpn?i@)rw;M/ T̄;fo,fli/jh6"E88 '~`w 9\ Bkg)@YVCDr1 p@vh:կrdx9T)G{3W&:~JYEYίdZ8iġ~u,c6+qӞHPE(-2+q\VXXX)AAG\A$r tq7 j,5`$ a*5h]LS̑% ȭ(dJS#5S3p_*PiwfZhpqu4? BVbP)pف/Y?IՏuZ mE"-)݆-c%-inLv( xqÚLjFӵ3r S6tZSVˌaa.L.Mpˀۅ`ƢGYx|Jv]2v{WE2Yܽho/pd(NhMC4M0dp^LXZQtC,T+|*/:ytS8߉*e{B^hrJbHݴ1mŭ npNwV-]AtQ-\yH8Z04YX05Q$P$`iq X%7cKD+m~PV*(`9QN |~gj@1{*U"ʆ<4@:䂔v7gn%iQEX:Obh^U 6?av[yj3t oQE8@/7%J䩜4W͞k)B,wRqXZP:іW"AZk/5-zL B[Ak X W'(Vt:2iƛ wV誏|6ΨJ0ŗW$ӗg._ IAxT" VPF1PPbhLX aύL#Ʒ)Fqy퉳\nLN3yi$`R" -AP.` ^K^ImViEK5* (RQYY#'@0:h~j/E ۉiB jS)f2ھir(KKΡ\C B:z@]͹%xJ !g6,Qe.MϓIvH5hcĦ;Mw033pk5 V6(U."/ r$\Uf<Nb(8Iu 2򕭓?R u\ frnnUyH!Kaxo'Qąb"6rUe`\JM}Jа ,$=ŸVn 7qC-PzQN& y$Y`UT69@ģ9BARh/t%){e %?H5kh6̹0 a(wKU$F4E!&l| ]+-~'eoTDtf:|T̂Z8#rTU Fߨ1S "pW*%fdS &nKR!.HX\Q)Go!I2nlڎ2@6c%(nEl ٝ =@{K&*4ᠠ4utg%TepD+I(,nc,PvPj·7g-7l,Kq,=bWMƁ0tuETһ <֦Š %" ]>B(XaEJ9aS hQϖE2\W-E ӮAX_'"XmbJ乛ͮ6]K'bae5ǥe cjˬf@y  Q" X m1ڼF'mjR)kRdSP (P_:r\pZ&JhP|w < ߌ26ŢSNR&ڨuоP:Uđ ɜJ%0ŽƤʨE*DLQ霪Q~эʃi_u0X՗ÍȷFEyk-5*˜Q ) k f=SS'`W?"Qs5,rH !Y2 > 9î ߇Yqj6'D D4TFia H] zxd%洿,UBKf),8U' amCZ@еxҾaJ7C_\?mubҬ23P*ݞiv>#-p xL22GZ;!sz#`C(Ő.J36ԭ|#v65Qb#2'4$2'ܴ߆pLOeK15e=UTeE84s,&xT/[,RhľE}12%\@Dpg#p62R9x+ ѦWo.dRe!, j~uƂcuIt|,ǀy?,A,^UDiMҍ(Sʷ.n6*8˸ ܨaA!Uб M ZùCx𔓷(͜X܈+n4nFsE}X([CQUskP2e]UV R1\wּ^ImQ؜nŬ\MO sUpܡšg7`_RO7@> Vt@: F9Œ.W= ˳|@pʉ%C3|p.aɯcQF ډR(O 1MD1lc3pr5A"R `77Pj4  gQp[tp ?gDT>n]Z_·,X-U!B>.UI[.[64/nK,"vFaFQgf}=K#WŖgaZ`*A80@ZieӔ҂?L;lҽBC((\eIݒZ9 2ɵG Ǥ"|.(,000#PI@U`doŶE(W J[ v iN}AQ{¸@ zmp+[U׉XqTUJ[5QU+Cw v (4iyV@@@ dbdGO56¸0͊2-nҦ0N(n醺l6` K:bT^ JA*`:x4%tr ~#T,>FxKE )R w[yk| MV>r)̌1Eh1^u.AcYafLUV>⇊dc#aE|Tq!ԜS!B""·Fߦx`@ҁY}^#j5ȸ.<Q ]e_ ( y[ s\TBUf8e^ >8Nۊ7VtJ+?O:- 7EVn`]Yߨq娤Ì1Y |H( f:_0 f dZOӁcz"V`]שgjKRvШ}tW]T`S.dB!Aw*= 6[OUMC:#3SPTVaq`<Y`6%ʰdrQ_)VE48?kp~.œ,gY]Ƭm%\E \)ړUr& rBj'`o ]VĒhpM5q22< N1_S k2@dxX9yA8R !☔VEPF1J }!%?b [L |u4d&8 =̕t^q\H^"0JWY`eu)qpjP +!Hw+P? i fa>l@q̓znȭ-å6*^Qr!FW cwflFe,P(.79v& Vd`UftcUn5'$^t>`2~%p6 cA U%8V.e ^+̣N -pUlK,ty".Q_rtı XfP\ "ZK/k[C^cOr2NvZP@Z,`kŚSm Wd]U*9]ybsjyU m!_(_6sh1uʳrP_w)vk0T^υH*W #qF`Fp zg C-RYq/PԸL3CVV0XVK Y J~cd1PsH \.+o"471,(Y^EG D9L$Q1$*cE|QM?˘`ic&B;qAn\D(Vcb&BӣGAt.UUT5x?9XR`7r$x ,WZ8˰M`+ԏ݇kSOXۂf`T0w ۲9Jè/(,\պPn ޠ-raK_LE7}F\ EvV29YW<&i,Ud)7Ѭ)\"aCFےLjx0O<*h#CR"V]-w, ƀ:O"Y߼,_~C;3 e\ Qyq w˖PKps/(J"}.a嫆P7N"bЧqYh;{E4BԺxIR*P+8eS*ؿģVP# ;f3'9 cXo1F5g^ ߂# o.}H*o%~e%OkIYcD{b3 3_Z zbr86,1F3³R^9k1b⌝NDkuƿRAx_b̄4gʩmCY*k3 g"!N[K; GF8Zm  74 +VLX YncƺfUx* c=G6`ـKZ[UX?Q¯~>p.O(@s0.&y ҙNpD6CRhuQ ] L:Vջ(;nպoaOJ: 1f oANwهĬ: ؀b՝H IKiKAhq0(c)M @w*@ 'jxV⁵Ey}ƉbC ʶIi,J1QtY@ !%~;\M k騍{ait|&?ԏ iFBOV6!?)瓵9'S]ʦDFmQZhxaIT48R~VQ{pm 25BZxB;TnT2M]0p#H6YH.&x62'qUG#fy2G&v|" jѭGAR h_Y#0CY~\%n@%"P- Q):`ֈK"* `x˄ tn Ee*\hNc3zez_'STӅ:8c+*:*q]D oD733`s۳4e.kF NTf3PVϵ)V8ΏpU/>6*f2WSj.vj-u*2EVws^zԪHXI:,Tٿ(ҦTpATj1?n-{UA/`.%9cF< k4S0;PQί̵1pPS|` h-R)\m P.MU`ƘwPQiy%~}gAx"8+ 0WWp}v/2صF!F4Y yP 5iWH*uqX~Ħ4r+:D2E;P2d9:0`3%mRjA* *q" x% nC5œ/4yGOVP82T,9H҆Olj6V^Z%K%ۧٿlVJ^ዡΊ\ F/pH6k,=rBfQS*Af`Jc$ A."^N sUaa_& ƀ r,o`?+L".)ԫ_[EIsPQ:ϼ%QP!ACG0?"*iwy@7"?ȿ$_*S @ r7r5_X_˒mf^Dk#Vg6_[}ORw)J &!|4;f倫d1O~"^lN?(94UnQ__Zu*궬rJ) %ZAPOOfgR#7OoSO PAl˻%)[}qYgS}7JP A=E*I (h};BvYL^ZW(yD905,Rq9a}eYXH =8"P}O(N'=18CSq?? Z; km_H(V](h^0 f 1w" wjDw0tJB2t”J(-c%pӲy,e!V}H^qqY(*k)-@SF0Hany|ww%=6 zj*xaU 64d±%hm@ $oit\Y%)xl 3vd4 fզ,\ a!Nt`*Bh#U@q]GD,6Un!:[P&!\Jmh`<~ 7 2-ۄ+k83NmI6%p֖Se ۤS8eP8^5\!t bu >MxMkS'[ueK{V,@%Պ H3}Zp"WF:nٛjǰ"=qHS!^V奩Q3 Cͅm0gi'w` Yahh/za̋?Wn0̺0!0/5P,V\ \_n*BNV<|W Ω)?^RmhITnOKK6}*C) QTm+G1vԲ:B&UFJ޳WCL-h]LjWRυc4F nEGU*^yMYYNU< AbU7 fKVLSYT~b{;BՌ 7IfYV|'l'YQO5ػ^LJ=űm4E?m 9\V+vqY hDq8xodzZˣ*-DdUy dY(ZGGyzw8kۖroy~ jufjՕ:gu2q+-Uuzβ@Љʹ-l cjiS5)lF4<Ν YU;PPW>ijVcՍ&*)$Տf h]YҶwΤ5lpލ8=Y hDWe*&K&kұ~9wewVSX*3=pf>-/5&sp7r9ӻXZ\wjz,.F:ϩ4AG;$  ϧIlĨxUZVmseKeΩ "&u&~iQOCG)F4,[jjNVaQ.s^_Fa﬐4"`"x,CkoO?*z*w>ܨc[DSM=!JzΥsMҿOߢMTQgdW]Øi쳏;<2Lvs J5Lb}0^zܻѭ=|3mn㡨h I4I<^91&^Ϝ}gZquzWaN/lYspmt:$ "xsփ~#ySgz0ob*_Gכ7.p]*i"ʹ;;DǹM}Dsjhh~ 5xhC4"`Zm|Wɏ7`z; v7յQt5 īIϢ1O뼨C,gZgӱ7:=]35Lnc& smC5k/fU6%0[Lz_.уٶý,= ̻!HA!HA!HA!HA!HA!HA!$~90?s9hd?qgs?oO?w?O=3q}]vϧlӶI;g89 qvss B* vNOجݿ֩Z涸v~Zgc4@gE&sE0֦x 7dY / eqrSů|MWJ?t{šgd1_ V0~(n8[ gl*ҧ ]]15OX{CS$H+g^@p:3y}}Hy}|e"UxM&6g:;2|܍!9r'lC H_Ӏs_u}p[暀? uwږ|65S<Ŭ?O\M|;d mS'\:ҟ>εuP_u8 jβk {_䩜\Nq?~*z6.mg~=4_s,Lg96W=N{f֑:s+>Xߎ~1Yp#>llJrIZafoeueu{56:緆I֍!89ͪx>/k19/+fV|WFeGmÅ ϫ:Lcxdoi^6@.q>BH>{([݉b9 jFZw'N78;o$>Gsmk6fQ O1 98=xy8_K%q-O{a66>MfjuR/YqgU⚵ؼuJ,/*2gpa+=f8 *s,W;0? *D=i"gHlCN֖&,ۣͬBZA!DlƄF\k4\Y+]VEdf49 IhJ 0 OAmr=m{5 ¡\k5%IWY'{&_`#=ga|Ycps@=:+ばBoHFdKET3y'fĦ6!Z{t}WcQ[jo?6974{l97[6W={j'vҴyGQ0t=@Q%8v=E[g&ҢxV׿Yh>8փg}yMzzuAWAQY.lPv"p\mr HH\uqW9bȊO-Xbۗ^N: u f132#Í62~VnL3O_X( vL'IZOZ 8'w$YC˿(d\µ'^3! &(=˃o0ɥ*g' ZKv&,XoaO]tj'S? (:`@H ei1JtB'.)=ke(g)&faWU >< LJld8:||jL.:G6Ӓ#GZEu5ζ*F,2!Tfo /pг:ثȵel]gP h|t%@1v`|b < %_ceoӾjQ[@K6;u=y9=i%9:uGP&%.Qfl&7;hq=8^giQ_{:OG;zyhy:%[g9Z_C.; ՄQe~Ӫ~Xge)Pԋ=C.ќǟ `}y ]wfBq^W5GMtDD0;A /*Glk^swV㐣czbq&Wz=ih8Zc]3n/!SiZ֒S9e" ɭ˷q`Ā, m:a QS_&Ӫ@xDUuJso45l&֣l g+xằUiL{D5آWKFfu{P(|^knUPykVڊ&uoIiԇ-\  ~_!5,3#?0p֛%kNG7 _83bOPįtt2m]opxBݙuSsAGR&ʊVq[]zsߖuY]WxVL@*ʀ]sJ9VQnڥSpYۜnu*"09ۡ\?Lg3tN{M^=i^ [6%/s7URnKsV3)9M'UqTs 1W(G,an0MEE :Ncr pg1\C>-c|[u MU4:r V* Nn opo wyd֤v?/`8Py]DiqVWl!a.?_j"c{NOkmUflqeAVmbz[SzI,"YDa3:q>=T{=l3lT&7-HUVZl(u5_b΢idYD2tywv̄f,ƌ!Ǫ{Xy{_/6Wl A]Sf4 @kkzB ^4"^6 .G!vd*}RH bUx[ VUPy uތlq7o61K$`ccI4NX15fmn` EQGWLc혳guϻvE;tʱ'{e Λ;Z ]25١ow®}'835ӊ ˗o\䢧s|v41%#X2 #8 nxH[462Nfxqs0VvBLv5 [*'y<q##̛~n&[fu:uz y (T/r19v| _z]fUNd=CYss[m+;jZS%eF#$yM(ȬnZ[後6g7vk(*9*N3 8!Y'sI4I<#tN5tg.ن &^ JP U ZVlep]q9/8_5β_k~%F9#uxWv`>K{8#d1chdJ 0Nƞ/%[N Y 淛*Sx%|;rm3)%uq@v+ƚiKLziS'i:\JI5 s\!IgOɽ槩Il#a8Z46rLA s̀1!AG{ffYz*"⧍IFY6S[^Hu{~HI4On)x|z'=l\WagީȭΛ,1lT'ӚKO! v#UX^A&U۪;!SgE{YQMצyzΌYvJ2Ke6&|O fM&nՍu'ǿ^.hƕvwZ'toGENRԔȾHu=Pȡ*k{z@~L y2 |w}z,u^k}tb{:x"ɩJr7%:Ģ݅z1Tܐ՘"Uq.M&B94`¶tvlՌ+ \J+g=ٌ6v?~MXqV8"~ҁ+[|uTCb<4EL?'tg-TɲZ6ҵ;LoVetd6m ^U+I.좚>5W0Ms"TL  Ju.;<=E<#)Y *I=8K2(oꦱ ܽD/H)9o*c9~ױQg]ŸNĮJH%689f(l?Jʼ_%fWAm.=ٚW6WZn-㓷 y_vmOnQ5*`xMڲ);ɾ3\џ^; On3<͓¿SWr>+^QkNH"%/p!s4[v-u6L'=~S.˖juOt(j ~9ʪk{IY֔,8Yn7XIvQ85c7 IH"垪1IڳpE,_f |:)*cp7eb^XgBLْ5>J5N~?OFs0jW4S_s]Jo3S8h3J!J˯^cV/wYʫ Y %̓ [@99>4Y+iLWfR`)-ٓZ3ђSa|$ /<}$I퓞ϒTBSJ}Kۏ%-0ݜK^؃SV4'_`wJ8 LnRIYSW䨕ؒr^OL.|ZFz=M1+WT+Q=_f%?Z>+€yIIan(gF־Ob3j֕<:ZJG6zF)+0JUdhST֫jçӉcY^ykt.#/ GDb$)7+$emfsa}ڸOqlkV UG\#xwVnSq/%'ZOw~1g[vM;,ԕTtm tڎ7`ZpÉ;pZ[]YV1e(}ϐ\ "=X}>C5'in¾*_צ-$8sP9νV/plƁ(UHM+Hiss՜ӢpF)A8L8wѯ?^_7Nz!#?ĹM̈́/w' 19V_G|,F7$A1 WߓXV=7}xnFvޕTE(2M[8?_?Ӷ3mL4v]šEu'msuŒ\V?<>H FaWǫ2Jx 5n޾/xӫmISOgԥv47YŖ?gf`?3?⌱R=Lp?>ʳpT ]MZ}*/JMPRxN_uN=/];B~ނIMGLp7 N'dƼgŷN ^z hMմ{l$pI%@sKځyIOokǼWh:IVڱ~*6;ot<}!6ĶԿNZN$Eu^DZ8EDcD7.wXH&&x wEk `Oqp";'Z,$b$X;bgVԞC Df=a$}N TN$q2 `A7E, ~ƢqlJͤPPL l'^<8Qd WecC=nH MX2-dIҙ7L'Ihf^M@r+]>./#=E_HV aNqP?H53<.߱_5ѴGE'TrIv{DPbH  Sj]MAba&ܮ-Mm>Eν%w8)FY=*〉ăF&Ğ{.Tw PmSxD[p5mJs0-#֬ 'VMtZ r`P$xJ3V*,?9~@΢T/Ł"}5;mw~c}WYZʼKW%?2n3EP Yӣ!rxk5'3sjAi[[z^ugƸMA6㎴|ui^'3B.#Zʧ_}BbE2LxS&s> 0G <{ oDC6z)plpRBN\ ]9ל4$\wZbxRòg nfƥ2ku`sZ9LP{R6CxuMۻ=?[rj={O^6C72f 9{0 16rkqZaψYmHPt,3vT`'Ad֝ Q$iA'O Z0Ɏ Z45f]M{fDP 5W㐏ߺ*̐75jNqijDs鷶rL}Y>ߪxmM( AZ )@@S#-y*=_mq}wkV~VT9HuYЊc(װT(z"kjDV҆ɨ"K,d?8b9LYYgԖ c_}D6QM􍻼@%Ad׀hJ_;6Cglj<.}i$2n}XTGtkK1Љ %:mt=ƽ8`InV% ?˝?H!WjPDVO::&Ҁ4?0=3KiA}?Sp|pnX`[򏴑QMc>&EBؤQ}Ƅ&߽:tm=7\7Fjr弓~b}P~$"Lut<oS u^oj7'XbxTŧ]SlbT׫JőLl4˰v2 ͎GszɽdļXwE4:Fif8K);E@! 84ˇAmHxR./\PsV&tQ6PtM).C7r`VRجIȇ/dMoqҦ1x^hN^Wu>AGQD |(`+L8@1:oǶʵ8я9)/XrVQIIF}=>Q)`40?ۿ(nu_(@a67tPαzHˈ`>Y5.":/yucf&)c vŇ8jQ2؏{eBwuoMmdKq&Sx9  ?W.MQtJ,r[s2/Yڸ?0E'ק)1$z)m0-\`=+,r?+];dP%9jZ1]['ﮭHs*̏wэSZ)=Te]l4BmC,>kTv7{zѕ+}'S#D %I] eq_fuqY AGKi~Ǘmn))#_ƾT9m\/?V;Dz{/E:ϦxtĜHj>GJ裲$WZ"+n|Gmm:Mj[?> ;[ \:̋CJ~}"ʰ t o3st![m{y{mՎMmݼTnf`kQ@}4?6^ NÀo{IPGc.ЋX,-;j] M,8cĐ5T VX(j r+4qH%:"-i6_YG#kxQ{4 vDT*A'lѿSz:WmuiQpࠞA򱵴{b6ot|*N^&8FSemNo+Y'O)bt{? 84WmJAC9 wEչnf{w{|*U{3}C.&gm[A(}m $Xa LQked7{j=9"kIw 5mf,/M]hY?|&,}5A7&B۰ɨv ?ȟ}PF~4gu6-H۝#/N;#j}Ղm L8Me@: wKT~qnQY0z^m+:1}Nʙ}wmщiJP"divav·^~玔ʛ&y%E}Eu؛;c=sLwT?-eV|]n84b6-ks"XYV[$1P[I5n&Gw*Qm2 K=[c50L(s`/Ph =2u4'ۇ}N!O*ˠ=>6lyJUDdV roC<3H jAU'nNt𡒎DJ` %n9fud Na?1];Z! 8mʿY:>t,t\ YlW)z=9hFQ5Qҍ0ϐ? 77uBTw@!`@diVQqqU|uE"8۶ۛb)}"=H$Zl9f$wblboUVO9 =ai>d^#Csu`:X3r"M 1 OcY2^þqUYOe] ;feT6ˁl[X tpB`$$iAy1oA2m iשIhWG.!`x3PGMyV8j&XԺ[he:v42ˊ|F@S{yoStS! 2]9\QN:ͨ[O\OMt^ W-ʼΥd:-JxAi/ i kX* nz0 c1n@t"u2Pن3۝zdv8¥WV5AA3?Ukb,b@Cq׳ďb?(=63oiAwņ!PEޟ)a ggNRf*P6͠8ƁRA$ؚm'y?e F &L_sΊ-&}H9Ś YtroT!Mq4TÝ:3:@#^uPof ? ۨH"϶nΠfd""@<`^1졵ŹWKRz;nT;^}9,@xsʊA63 Wc>GqaTT+|5TmO#ӨP?^b qH{v\1{5cf(u*Qַ1)2\ţ/@dGHUܱvZdfX>Ԣ':ؐ?sWR2[p=豇{qm|r[MHeI&(m[Իvt}ͷqG"v6K֟uڿM?SC0cJ;dIX?p Ҳ4Ȱ6:8%Q'JWچOAD 7%M@aߌ8`ocN|V&`ީ_ʁaWҞxjI NoZ+ 0m&m4ϵ$ a^LeZ<ci wۍ~8?"v$ 47"Irdiz;5?4n71UF`I@{a0h1Me\WN)\X8JW;xm-(*4 p3>n#>81[ +h3)qyyQf&X;ߍlQu@o;8;NISs.@HdV11ϺprӺB|ŅƳp;JLd3nJ)K3`rO҈ɷ8n+dʐupa*S?  5bk-]з#C f q{k8/'jY8S,b#ZBٕQ1(zh e'qB3[xIaDΓbL@Ӎ/\u!eLSV1,( ۽w =D^k=öAWP8IU 5ӦoZDJC@Lw"5=[\Z‰(;wh3SdZR7Z1=& Dl)c :Sݧ3jHfJj6S91[m39^Wi,I[h<# J>U^'un,;{kԂ`όiOC~]Vp ;8uPV}LL+Ӄ@gHi:@1xq˓Ժ^lE <֙@vv-uCt |u4'ڟEl,5<|o4|$Z!OVbkpuڊ!7O@{^$$XՖˆQq== ,ukp&mC`bZD=&W@˲DiC@?XĞ9ԁ+D ɬ?^UџTQV"knD.IOq=vReēJ-a?} [Cήw%<^oJ{'BAmf;(.҂M8@DA h5yZHG`Uz&FMϟV:,GhhafǤt-kmct6+"bYb4SXxQ|r@4mCÇT{yG:9NV E!S-z1v"YSXFpFT {|iFyI;)ccdI39_I`pmmA 2"m ,bA 2 `fz|WcGos S `6^3Ah0/i4ǰm`6A#Otp&>m,!Acy$>sfW q<-L"FGorGmWYoR>[Qi|OD kn?+PT5 P5 H#Zss{sLJ5;]Dve$Q<4bUWEN%.i_7L3"O*@I#V8kl(,$V4/Ʋ&1D,, tEAˇ @FD |(崏z 1N6'P(vzGzp6k1\6 (,gOR|Rmn!fIU[fm+ָhĝec>]m˜\8 G&3d%68/!Wl[ ַ`6؈SvŒկZDp'"[AXiK}{>ujtg bx\tg=,I$ ނC0xSq7|jfVLߝ˯o( ExT׌lf{bX-CxQɞyNiny@L3].X`sV/KzmK`2^gE!`ڕv2o4xgvT|{5SX쵤`u٩6Ȱ<W&lhKd&BTw~ Ge7xm@'Bۇ=cϰD|Sn*8ň6ʗL^WgehA:(I`UXXwL+&PD|qh˅ƃm:83w'=X*H2{p Ӳt"D=E2FRLDюt^4%[?i׺imfvOtA7dڛopcԙir~LJE׀t IfiB^ϲ(P/},zb+,Z+:GU$~dxUnZHBE6_Pyq>yѝ;#OH֔o6G=ə$p eKY=1M";m[4(eҁQ,d@P~.S¼{6CEʶdXo @#R5Sj{so.[nzUh㱿D(BƂ,oLY19\v611j_,F Go5/KsrmziRN{I@Ў'lyT.Ddx*FCm ݸ$,s-#Ʒ <j2=: -Mf'l$ μZ6(|Hu4i^o/+C=޹H+O:Yq:M7 y2\OL3%-coʗvwV!k2LD /Eݎؘ p¶Q]z F6h J_#~m -^S_؜V'A&CnZ6\o _mZ45"攞 ~ɃbS!F3Tjv67? Wlpl.``&҃oOwLQ[M+u7/,j@244q"O͏7udvL?}!H+W0EU޺tgPr&V\>}e46$^`zeF:F#qb':HG;Σ| F(zxWҾ2ܷW,u-|ۤ"BW ~Rt3+ _^tL`!4jYrM;YJ74UYk;l 6Xƴ dsJGƹ0(4T3uS?ӝ-hlS*ǀ;W/E穼*mb6&#%`\>omJ/S5?QA2;LVCq$j5l6;њNf 4DHj (W^t-t`TPl9k{שq|X=./C;[ _mn~@" CN`]Vz2ӮZ1u-QI G))_tnndr ^bT_2'HkFZv %!$Â13QbB7K ML!a3M`ݙ QWlZLSXU*PÃMAɃ'2t(IA@ӆ`ۀҤ hL-Á։HL-"2&& ɬDB5B0*e>ܨb {][_}T=xT**8閑7gmu 'uv!ٕY^ozm%b8vdc ni@`2~֓$7ն'XtݵV!ojf/K] Ge*6,Y&SJ[p2nb΅ iʷN@״Sks]| A!lb,bFH>p|O$E[H'[Reaޫo@bI$AZǿuneQ˭h%Iim(!u|sG0OK.Zv$ dikE|WZ(CL~ڜ q(79v{@9<*1VӆRviX,c:{qe}wS'^ho(Ӵ,E_p1^I4σy@`dž ;;Nj'P)+tLJ 16- uZ5<'؈ 0t־wWmbq[JΟ˧+9^L7lw >'>ʄ[& vRHx4pqȶc8[ Y4qDn9i`T+A474wp@r'N>b;(mo5H0T&Ꞓ:cbĐjBYaJ'K*iŽsB9W0;Rn[ZyM>q,4ўԬ8+$7gp ŠGkFH!8RV}*+T2^D,I"{."KXDikKʼnmu1ʊ#]e葤[><:<!Cmuh9hyul~6 @Zh *w"'k;NBǔNҁ T#_}gdZn 5ոG;W;욕b%H]DkBuў>R}ⷦlYQ]m21vrP^zMIߎin60 a"p2Q|E)>m7/sLI ӝl8D>S[Q puXozu_hl(oF8r]*i~jTqwYӈI4 ޕ 8<*^݈i˷]+uaF Σ?"ӋxWl⩷LA!z p#Ɗ8y@4Tm>z+4yn? sA;È>776!!muHP+sk5;RoG]/iZdžӋ)yPVu֗=LUn%tOKe|T)Qb٠M.?K1ӗRf'h 7kO´_Eame`8DuG`ҁLT$` s2iQwqCLKQ=tvƕ+ H+oQ@9iӭ6jn҆ޏ( p}S&AXf/3j{jRxq;D)ob9<͖a0m9<1 Am(壘vC u˙_Kowzu\xVN1<@|Ñ]FٲQne x/W8V s*LqJ&iv> Ԏө*ꧨ/cl3ѢilO &vh8 fvu-mR_b8R'șh&1@vNJ9_Ymmf[TS(_u#[siccJ$Z-ȟw$  NlL$tPٱGQuUp2`˛Í >ӸW]B v}I8-o[qya &HuyYK \n#A&2+ _NHZqpֿOqr2dODDs#Z%/inzR<6r/=ۭ5 lP(AFQ΁|9N,oȬe[¡/3mtQK CWf`:Drӝ7ȴrפ؍p6Jw4㍩Y nvw?+{dRUcPWmk[## >;8Q3G:> &7%tbxr~#(3n^g77"9[^}un!$['<ki8ZO,xn,VQ<4EuZ.R1˕n#F.˯*22 o& iC]nxRmxQmD.+b2Kɝ}nelœ5I*cxMe*4u]sqz9jׯX #cA&9cF8'?+¼ll;NtJ7o")@CԝCHmBnl0')FGYnTp8VW æbԸ4#/Eq49͵Ph4kiuAzb)l.$v>`7ęLpUdLVL3mɂi`6eۙH6DNq:mGN &*7{xzH, b X G!or"Cm&aiI/[{O+ݛoR7w(q+TA"U3nb@1icwX! Y\ a1u-ј cŒ}S4<[(IM1gaKk7RøȌ|% \*yi~ `cm,푣 o"x#Ś9AjWjd?,K,QŏV H6v'awP8ZS2# mea41Moidy Oy@cdp3ϝ ԸɀLSzg$| ը]u\Z8Mm.2 09`Zd{b Bd|z |@GRxE/#_{)!I"I^hԷ/>oj^ĂM&!ql24=yibdzmc|4WiRD W.b I5aOPQ-Lbr"4u*4a͉Z%Df 0&"c4"bU۶쨉:@^Be .D.ʆ<W0AR;Dz`HQ+ Hy_7(XK'CB!<-MkvMf ([~h'Ӓ45 l1~q5nE$7l\x0U09h$4 zgpZ!P,5E}Dh{& R|RS"DHm8ҏL/2Zj V=o ?Ip,hTS?頙Oe`>5*4Y˸e-2uTOQ@ezMriX63e&e[l[ȃC5bbRmH"TʊJM@<'Z˟dM9rp''kHR?06pcHs\~^].W_ ҅dvD^W'&mS{GspЪ8]p} *X)E}96{jCx@XXO<4SkhȒט2BfuE5iTv t6熱u'ĂZ'M7^z ;Gi>6qˆbjg:Qa԰zPw?Ǝ W+uXjҫ4osQoV`{fEHjIiN.sl-*H$itA&>cV[[ T>0ڼ~"ؒÃX R &LBxhma?Kkf*hάHnd{Dڡ~2x_X>NtACl: O35_FQI 8S@9Vcr#\VfwgiEXky(fkrr"@i7'At&CA[CR m_X")vqxפCs-w~^R<QC͡:ִ\c`ѓ}v~a;Gji-'bLLy1{eMzJpFfSI(3MRڐ'-$p_qGcp˜,T{(9cǤ(Yp.-f\<ELytmhޟP?:x׫JI)V.8F\ma[LKؖvYd تo}/'T7(ɶV׍cIS0A[ơey[h$ OlԄ̋@]F5醐U1aG`+&$\^J8f?iU~P#p!i3xՁGƃN$;!nF^nw8c^:4I"O3[U'fP[ a5ȰT~ɉ{&)H&cž\|}ՑR}Jʸp*EfYU.&>O^ X+/)6aP?QJLO]:1dıxPN'vic/[{PX!5DW?(r$%^oѠqB`2Oe vSlDmOL Q>76$U+5fߺMRQM % ʬ5OH^]TB{{d&d6@E1(~u :᯶r@vbe.9M[ GU\K7ho '[[[Rm})$5adH2#AW[vɎ۔*"E7CxECTuΒ Z_hM:[ZOH$ u<\,27+2_oFn:s /l7>I=u*P~mli4oMuI= pKEJ4*FcTDQݑ EfH M["6(ۋ?׍.Q6?*?me9al&yfY]{B$6 };m$ Y:TrR"50)*}n,5pA1Gq@Am5xoDuLfꬾq2ź{n+`R55-_LrWRx6! PNfl<쮝{Ǭvd?EnqGee~Ta)ǔ+AVڛ,j}"Wb׹Z^G, [Q q#GbDO3Cm P1˝`? iv`$K cENל |G.Л^y7SJ$ &Đ?=5U@F6Vz+suS&'1JvLd&&pM> 2xc"$DV-ͭ[)7r92X^L?cBCgBLصzۢTʰDV(X?m37\0-},ZaP7>mbH!}<`q"D車#/՛oyNhLNr/G:0MBIt{ QZ{jsm5e4qiF juX˜Dv J!*m*>UQ?Ρ10#J)oXΣM9PbIƾ?u75}Ńou;hǩX Q{h-g/u}ЩE7QF>Wk| ˌE>+w͂1h-¿udH"z|+`X/p [e@?9Dˆ`8[ba*)8mi7 wræ4+j#N{ Q(vߵ^!cq5"bu֧꾯4BF;b6T *牫^:-xՈh6'V"JʹA[%gPǸ ]ø0'A";@`DZHPqŦ(,cnt* FV%v^4)rUrn m#O^LJ jʾ'e/?u Nq!`Oq҂ *mGP-xj v̶#J{nT7¶>O-J>wˍyRgD{)vB9'ʣn'X^$xҘ~#ʹI=]}77nim <~r#ryrz˯m w=ߨhe$kpG3h9$R@woL^E~"#Fl3?dtSoH]7{k Ż]7y}:<:O=M.rSn4H^)ER0&;is` $0] \ܙOhnI.Rn>nlcI=S7K)p졾ug{5?tϧ%w1Dc)>F'nmCpul'BEVE+4OmB51zvaDcN^_)\խRbvpӍaf)B#A#B ?) zk) 565nEA@Ǎ\_1m"e~67HG#˜9*XtʬD~Xk/EI{dz#P`֔Jf4K6[ۛb 82<4'2R DpK (I̍4C@ =y-i?O9Ǝ?Qڔ0ˣvn$G ;S>Q(w0γ2(ycaC|䇓/:kvVphM4DZup-ԏ-JLA<(hI[DԾQScP)GN `t7ae7_Oni`pv0>]&&&klbatJ玸OTxV2 bܽHw]<̮O[cޜnNQh?n dG "n,͗C:m\smv[{Lf-EoaPRṸN>fm͵mk_xi@7_3×:FIuPݑKg ?Ĥ[9R ž=< Rҟ5 ԡwo _EHO ,{B6 _(h{)Fqkξw6aDFZ2 -#1Dž}6DpX\w hH>?+?˗.\r˗.\r˗.\rL~e f8}xo޿a_Gq6z?a_GqsUÏU?SƿCON}^ï^s8O++W+~Ã^rwߩsA_G7&?Xsy}5P옒f?L&Hnucxw}~Yy휧>r~~8x<ּ+6 5q@su3{GLG59>H.kY} ~</]N+W9iǜzu3_a> ӏ9ξ~:8L]o9~xß9Ï0{u/ :OP)/uq{ɪz|'~ϺGuOyuӜAO_is ؿN8>ל~~#_G민?@d8?믡G&L;quǛ8>rY5?cW1&y>ۯ8}8>9y.{72>28cGrbg,%p+;ß9r^1)'CC&9292|d9d2c凶!oMd,G'~WN]=hCgaKG1wU2@S)@}:Zt<yBs8u4e?$5p>ovѦm3.yq_$ef&L2dɓ&L2dɓ&L2dɓ'?Orq\>_I&O}G._\Q>~rf&L7l?ϮV}W.o+ϩquV>;k@2ܿпIws?῱>k7Oc~KOpi>}p}.?C;_ 0.m8ep虻>ٓ M}7.98&Mɓ&L 12`\2dɉ?[)LOJpy* 9(pcHr;fsH;`ߡ Ϋіuρ8VGk†S~p@ުa@!4(%YaM>^>rEi߽p0Tb8U}rW{7>7߅(-W]qxDXj1ؿZLf@Vr *4: U|ĴO8['|ݸPވ)}`T kX78_QC<Q5ÃTI5~p;7cQ{wȯvesZ$-KJ~򸞭F>_el.4J߆a(0z^X 5,6jYxIDv;Ƒ:o@}qB Sj]CRn+ROJ&Dg0*Y `FZMD5w=2To$BiuzrTKxf5u QBGw&?=g]L;J 'AO<805#S7ф116(gY--B+C^%PP($a n6]9$&w7Og9c,xP@:ȧ)MfAȁcz0' e3QBlx7FC=yȐъ2P^ޱDT`Ij#yÀDس˗ lSMLCCуްC,a@{b  }b QKG7dĶoJ)<6 x%]H^D(JyEu$2>:dWJ3d?cF7袊hM/n2@@Tx.-jH&Zlmŭc>yk dV.c)(Gog ١)0D b(!~կa_F-Ȃ}~F×4 ( z1"CMLq=` iz]`r) R,DC8t7??&A^Swbᬱ`(v 3њ 9X)vB38٥kLbKrH飬9@| Cي308`|2͊?$b^Wy\[n `+NljM;)n<.P>LGhè#盎+ p B Mb2 'GkY (jP~~B8|ȿDyp00(Aף6~ V!ׇbrrɣgBg'\*5ӈhDtE4=%'%k Yf-Mx%'8yCQD~289Vÿyɛ現g (}m~8Kiy HdtpmЍ9#ڀkLu sKQds4Yr`MB?q<#"D&+U0p8 %'H)~IĨ_cB Isuௗ%?!~qm"ft 0v!JPߌ@/P4;?78}\S N"v{>x!`xkD cђ/ܜ<@=02 0=Ep%8lMXd|S4{~Uzv!˰6n]QգxdnЬ|Sf ba P򉊃!R1׍\q1AOq<{ɴvF&Q(H? tHڜ#b|d_͇]t<_4N^D.9̫BUu5~˛E { ] N1"7`k F g%yA'2@јԏcLVVjIJtmC6[鎤"'~ '"}vx *= x0 bj[Do @ [ ={}@@pGq04WF|ddI4S7@ D yJ>Ob7/1l1)op9p(c Tq&bKֿ7QLJ{A~:a|p'\vh9YbF+~7E&iNF#أBP8 #XUsyGDb HdhL]9e:Q AEIX3[i|@MY0t<ʠiJ w~. T? cIVo![*{"]a 3 |`q$Z/) 4J uJCOC7;K`r% /S@Qt\BRDe/Zi mzCj7 $S醬$vG(qP$°X_gɲT`^E֟\jCf4VTr OeBja.By$ނ iSAx|L.HJ(Ⱦ\9jS[A-nitw/nPcO0@Rԋ${c }ף{crՊ&۸ޖfU1ІĐ;mŪ*Z*8gY4 H{uE" 6 @)U}g EͰ!#:qJi$:,0'03(UIy9[$ 9ۘF+d芷&T?5DM~rs۵P07󌨔8Bn<̤ jhԩּ(O{M< .ߒG6ӣS!=Ì ZOAUXny?k`N-aRd."\$@vl=2ݼRRbt%Y"=Um ^1)T-GCx2Z~rA߽3Yjz{`:~`|2lh#A6zO&dF!QrA6*vo{ 3tg֏*:y6C*%p$Ѡ0(MP hG4Oḋ+񀈦u58=&TaHNӧAQЍ`SV ޿z #@9/ct1lAFTU݋ ^”AB)K/yE U) 6l5$:v1 ;daڋH'~NMJҾۗr2'KrfӞ;bG )]F7<1ӬRbfץ 8X\~4Z٧U0b6HM?c%%%YI N]/!P~diʆU,!h`)߮AD-0WQ`󏊡GC (F6yD`<2y @4}-dQ. (h^缩32"ãasIq t9+%'My\*~ l4Yx9|8*qe<]l?w ,tDB6ZOi2j4 $%]׷72sֹlvkLG9[-a:oX8U]ա؜c$EA//%)*zL|73J t${M>Lz4Roh}V`G3|[WJr:[WDE,/;M'tDho@PQ="4:n3M_!IyQ9Y*AV4!9\g? c/]NUbÎWq VƎ>v}6AϮH,aa3٘E#!C^V+a> 7n<6uN 0N f1GY+Ys[8VM(qI:fxu0KB-mjUQpN8P(Z< %Dg\Dn #2[;03 u3FĈH`kx}U9؉sX×&Bv@Pzl0\q1ZהG*KKTG& €čdQr=z‡0&bq D Շn \\isT4'x?9 h"]3tXbI/Amui{,M A*2A:t?5Q'|9Z :|WVggɞp ġKPDwr[4L7fm>G/_x OO G%Ӗ9nQmf~I@% CMTB_9GEZ8dpmqkP ]RI庶oF⃑x8׎ lKB~ڐP!1~s@g$(F4yuM&F;çr +}˜'; iEEhGdN(aNP"듳Yَny,Z!7r1Nx„j5AJehaAhPMm1c: XB`B(rtbɈ`P$ZI޵;CԞndǶlh'ZvS*'%Ap+U6D@+]9E@ڿ6m CnpP(]<|MeM2@M:@`.BQ!'88 6LP(cL=U|bxM2/9}xS{`]}r.dfhD8E9l>׌` Dˆ Mw]/5Mۂ*>~ aAlz.߬-Biƕp(,g 4506  }_E 4f=6:qPh(#U<`IGqe c T'cÐ3yjx !n[S@?9zsj]+ I8+D5Wei] 2j EXt =]P[3[ 2Kb|WQ nyu m+va$>G`У0.ڟ4~t@Qk?9a$T` HP&!L-" ]`G@a#Cn7cm>EE'2P/8k Zx||>#8&QD8(R0mba5pb';ǔr9f, eb_9+6o,Vo֜ܵ%T/MT:kW#x"c@wd-X`CaJZ[fR35'iEAUAŒ[x٢Pۅ]mɇ*]3Of ,Xւmt+G ?>ì[gI@;dAG&sn>>g@tt[M^㖸b2"({kAr):+*b挴;578-~xwjv>\ѭMI"LIbjSGTYS2/xT64yY*6!Z Ay ߜ ܮv@S'o;U #Jfl x!ZؓU.9΀?@qn|;k1 q1]*Q@0L rdFKZx ܁1,7-uһː}֍℁L-N[D>NzK<6?8qؼsjѨGAgޔ声Iz^2#Gyԡ#h%X<+ݘ QGFԦqXBUAX[;jp0 [;:e;aXBk<|Xj߃ tw\n,MV'B Uhk)Ͽ#SQ{Mx-xyibs8OPBopRXµ *K*u8ȾNHEy"D 7 _8dK01[`7Gj a:ڼfCB^uR |6*׳+EKXzr94N^f=Y#C©&(eT0;jb`NSgӵ+UwpRmIbE逇BZ&|2 ;pZ&4)ĸ9ݛ7r561g@8o /^,XN#`8HI驈ޮ]^ 1f6ڸ гʚ~>׌i\aCR"Y{'x'8 眘w/ۅ p7+!*)=,R8!1]Sc2$-Ǘj'(1U ^(PVYEH5HWmCΓ:tJr7dvc͖1և`_t͋72/dƔ9x81qj`u_PkM4yלݣ> ̐f:= .2gƽ`^ɬSi=󁏇S]Ǭ;ng$J`LZfmnTqH 0K24?L%b+ 7lVq90#yDtGh@̻Rޓ#zq :,>Q9?kW_! M: h65Tz0@Me'l~$)z~rSi']kŌECYHN KHTF8W%Aj]:.<,HPWo`XPѠ]X ӤKkSI8eaX1T`0!Q5up^#H@ %: qvb5D'a&g+SeO,;uFLD)$tM/8(Q&)`"z$ * 0k$C>3 bi4$!q<$ wa1ǔZ 6]& W!闳CTl`!pm-xVOOeTP(44\ 5A%7N`owsX޲p '54Bh5N-ٰAA)qE@+|\{86Q3TF(h]mX6 CohBMgxͦn?ͥ|3^\}ӀXԼ#->h@ll~AhFH}kٿ9g"yêE.M7ڍ"NJ(| 7LM/)4ę0mr)d=cdҴr\gn$W 2Bǹk+C(aA!r+$d8_T.owv),Ym|[iŘ@8s#BF%.٫mDQ.eoL%v[1C83eu P]q5 ?!8MJiq0ס6W$(``D sB"voZ4Aߌ9Sf̘k!8r!2$s m~gu e?Y,iL!'ڠ`-2EtȻ/&ɑ̖_7QfFpRס )݉ $ܴKԓՅ9b$[OG hוdcĊr=:>95ˋx#تRpPP[dIk1T KϜ`E.ӧ-zphGhL8Pu1|ڍ1WMG`8Y!\Y`ĐlgI>?Rv\: qsE."?8#&}3aiF{ 6]U7gDP3AT~tdSy;kZ*ڻ7E'Cgu(@MH^FN:n1!IT]G"r/p?ez.- Q#/(wjyJHj8rd0Қ0PryHg^=ĊkMS:S6[MKoc+(ND$W$UHCG[Ͱ'&f/ |Wd5HZlGM@% b twk2 WdzU5oXH4qjv@Om͓Q8"Y5p⫖qC8@q8'0iׂ˃xZ~7||vƍ~@rQ :0PI6vSQi=LZ;đ2]i:E=x#͸>]Cz4WǻM(pX$(vWʜPx`eBiONn4v\2''Fcrb<}i }8]sr*"G~AdE?L\y~*!mkudb _lhqc :, SD".Gq)SXSx @lM`G3'8H9~26< A:A]eͦAR<⩕*9#,7m` DUz5%Ȥ\c3La]Gm!#Acn ;_y@[bҮZGˣx> mFֱ%u <%ChS.) ֛8q&Z .q\-ZU{DKcrDx0I.,+mS@D'ƃK/ Tc4{qU ".81@q6j`B. =zڊq~1_/fLKO:! n?:@d}GY(+(sjdobQ huM1OFyW~k`G P:1gAh{ ʝO: ]#fE+cPF<"+ '&3 2Z4h8ltc 3Kל$rB %A{D\ )Py!iq;&rޒv yƢ7d,;0TrǺ:Q})EۧğHQ]PA951[xSL zIBoi7'P ]t guӳ)Y[ɤw! E:][Q)|LG% v047{)$#U^" J%d<4$hg?M._9$p1 k 8Dw(r'JxLT5`nJrMfSCW 9@|zv&zr2eR5VXv-6lT:= ;qF~9 YkI5HαIj9Շ`OfM:-K&Qbg_`aUI!T">:a{uόRWWno ƻE>~N< ~, 4\4(VxYR6\b捩n!_+!/\PnHsEHtM+$Tc' yBF*+x/JETvQ\~{9쯖IUͲIe]HKDo4fF.+ќIT"NC`F?Y=;sQ0%hc@JVֻȆpH:Bp ;CǼ 55:_!uF()VS^3FJ e6\yWӂ|a2+c8  (II:]0}},>"I< RC>4Dp~#:$Vp@}Ph#\O Vcf@p&F U պ/G\`49 !"s.+"ѻAq\h ưRl[9 &h ɱAo(l1$pLjKұ~b6T/,hn1GO".r A+еT`Lcd#צ yZkN/SB.z6#?dyG+℄#B/D^NR;fKۡ%\~aqCiyd8Ӗh`1yYD!ҍ[4=-YX`f kG7}q ?'^0S\;* RAl~D or.! +3H zQ"ӳ>1ۃMoHB}`Y4ƶR)8':$0@MW#OSjE6]ǜGQTd(j)]D#`AK]tNf*셢'Xr:O<ܐ L@ [bB'/+Aߓ]bt gg9nҜ"M)5Sʌa4P{Dx @]9Mj0AiZ{b.ApP2h Uѽ7! k$#NBF|H@Ml4iPàh\rv20cO!4^XX9L-ֲX-N8& ^NA;%2@;m3|pPpBTg<ҩ`´;Yh)H>"G4k*)y;rhABBr?7]•rN;S'1ԪzJQpk}`"5QT\W=qЄ/E7!q͂fK7XQ8g+Tx6b!񭟾GHߪ|v`Cil$ytMiPގ刄HRi&6j#Q6yrR#zPE.lf1T@(Je@Mި(xjhj4Jy/iphpExC^Q, %68ʲ=O+F2 V+'I*f^("G$NM$m3Vsqu6g*.bTR f ;WwbB(K+reā.r%GwfSKGͺ14ο,+t ><|;w\"-Qnw.Mf!O2hsbQ?8SboF^$0F ak i n}~0%*TH`9 (lx DS~dԂDnkQ / (5Dz jƸJBu,2`T\) оrKI (@h"(ih3J˥JΟ Ջce~lgwObdž ʋ犀pA`0h|p?84;v?qI%ťt3EHA=>2J'{>qQ'(l2f)B'RTщcϲm+*bYMlk1@vq_ +;ũR;c ]Aϼ5*69:˭:%g~t-#^1kHtT? [#YF),Ŕ}-CS+4 ʈ8D q#+:'c6L<޻9f**P+]Y1 @X`'LW2+4EUTȅp|!sv)u&U"AD46aK[rj۞8X HV{;ibi-IcT{iLD”oFyv_ )Ay ep\Y66 dŶ@PW00}c E@ "%0FńfnIB$^ Q$m " %T[ ``o~\6G'&bU)9j#<1Gn8DJjl~N痢d'2;*a_ A7UhB8[ERd7)yP,/_l `Q GX-|<T9!М81;>0w {iw \Q1-vU.j*ƪ_r}`f%oAbmI |`jPɿ}!+*PbKpybE` +P`ڣK/?avf_dZċi|bmE.-do|˒B!Har ڔN@^6`m.IccXCz/7$dJK.bE#zv-I]D>A?.4`A40ʞ%(u$_c -b#ôx(~'mlZK? /QwxL_됒#)D5G]mv羱f[̜nx2 ZUwCFu M<bBߤ|'!=:7qϠDC^M :uЫ&rΰHAT4[6zb*::PfɀKvvb X-gf)~]af؄o7[W=cioս<ܼsg`T McljitOX"%aɓ={] ""m U6]$y5-[[ T$`Uj(`B#EaF~}1!g4 8*#jŏH8ЕJ1>-:qc8Owe'h~ Oֲzr*i&-(/GISɚor -WdHu@Jz@=S</xH3fB8z}a mE\a 7>r? QrAnvK\]81բJyqQ4A{ˆwi1H[^y@znK㣂*-VX f#Pq'h g(8OB '0qZ' 2nƋV:tm}_@)| \3w.@-OpQA> 8P"a669x"lNkupbVNzѽ:ߌH.=du<j/:[5x݉q{ H&lqr`3@|{cJ( à죿4 Vx@{p`J^TL42~.M3{nhL:h`lX pSxovз͆Ì܄ ˠ %9,cBHD]ofSPwzڛCKqcHy? KGqAxXjt"#v*ҡ([~Bÿ5>ڰɎqǬOͿjH~ ]' l|ihF3}X5M?yʥE`ST*9^N^nO;9jh`F+?"5o;%|Vu t!GwAP68p1>Z4n8Cfid(S/ 4{hio/ n^OΠpzSuFمrLksF3`;a忩3O˗9ק>S}fryHxzgq"pܚLPP.lr·ɌDo> '3y.C37'j=&Cdɓ&L2dɓ&L2dɓ&LxeĉA>h#F(|%Ym db8bB]:#@Wx+MUm:hiu@!L`8^uB`Qք:ءsiBpz4Tw ft.n*I~2h1EA(kU,*%/g7 Hu^&SDLvWsB,D>r31vnx_)^%ĊG!K]ڙ8iT]N^p҇3MrS|`$JgӃZ ~]GǓ} #TtvG}Ld9_xבh/L!@hPdW<}Pylons-1.0.1/pylons/docs/en/_static/pylon3.jpg0000664000076500000240000012262211645401275021132 0ustar benstaff00000000000000JFIFddDucky.!Adobed '^6      )))))//////////     ((&((//////////"! "#01@23$A4`B!1AQaq"2B R#0br3@Cc`$4D!1AQaq 0@P`p 0(; : P8t@  w(Du{tÙdQe@2jD3DC!N dh@PaYŢd=6,-|:veS5Sm̹nX)^C5uq;Jޏ}@V({:H0]aQ0uP8΢vET3Q ʈQM_E]@g@Vb֣eT!({X\_ʤv[3J}1 ā|:-΁'X7"Ɩ"FLZ}'awzZ2D!r:3q>EsX4i=-`@Z}mq/E4ѺErbQ>; Wyj*KdR4qvZ@;B'?۹:;eQvxTgr ^}߉Hz ^hJZo9i_Lī(hӛuKmNR.Uܰ3\uHi}gbڌtHu뼧 ìW:9'_7g玻jv8k8($h,[Bbܡu.-^BzVihҋ-wp(ԣ%[5=W4O7v՚7EرMp %DYOu"ܴRƠeDZYI.Aul )3Qj;<(JJRU]ɺ dQ-ӖfV6!ZKTŧxeX‡jY 6yUnUⲝrGDݳFd'OC7tRTSa;t}Fxm]i[l(/#)@y\vpbU14y=}tH%+bQ)VgP Vh_93`}kҌ,FqHp>,Cyb$Au^)U`OETͭ]yM@ Y=e>aU ,.zU MɬΧdV;V[^J6zfۦ&8RHf/ؤv@ٜ]J(ѤP4١"z1% `;eV`ob5ōkPCСop6)R˩@ Ɗ-fIy]b))y 5E+$#k(խ#[v/844gիA! .\f%9݋@nZJ残\r(oB iaSYg{FEz`S~x]\k7/0&O U{3ŋO_Ji'6n47P+Zwz-#ZRˊmuJke=-sjEhT8yOK[h28^J`TXz[ڳ* <ש9Tǚ̉4B-CDÎ 50 )[\Տ#$o[zLE~2s"zi*mULg y-_]yUm,g/5BKM;qk+J(le7j/) 3\\N 8]3 \yb)Jy*5azdܵF˲ 4vbPZ)mٍ g5jA5tcΐ=%}sf[Y\*q))Yߎqۢ9kH顳[(zZ^ =(?7b5-:(KhK/IF|!ڻPKU9N(1uLW/b ]n>Gi/ D2/]fhI}u8 yj>I!DVJ9+|jG[7U|>dSz_8!u.2ŭUt&WP$ٺF_SqL]F?Hs7K]ĝo ffI.G|Ǫ5=-֦uxt$0{mzD58pr'f0Pv,B0}n qnz{Qsޜ8k5]09u fG{aٌWc8+ۊ˸͹\ 0pSVb&;mUrTEmÂ}gWg\*`8_?)]Ol9Χ8lTˆOO )Q#?q'\# UC\0 0ТQ~C…3ZÜ|đLWlH'_B~3prf]f#pNX%DPtgx;Ķ4mO-\=Hv=盶uWu8}G# \!L(X80$V<<̕X6v9> S.iI?9lf9\$-1r?`^T(粗Y 8YuB1UnG Ɖa< ZU>z>SbH8cNMӓ/$fÎKrpV7=@" O= \.r3+s)qf3̹ۆǥf@>O\#Rn00^aӖ4'O64Ō҈xOTՀ-& CALg11LUƕ{@mNm6Y%v[NFm궻q ^?Lq${lѤs`'N8{ҁ\~ 7<ٱs3Ϯ6UD8;ezcp3aPx Α>MKI>)nk)"X`8{q*uӌWm0\`Ttm[6^U۵NkJT#{j+9#ʖsw\mV_3GD$݋zyQ94gK.|9U2(ށxO2,Ds7 !m%Rfs>sDyGiU[iC#$}>PǢB.A#N@o]z2N^g r jZ'KkIpB˯%شubVL%)l=*xC5ˑ5Ċ [4%yW\,젵u/;цqEX`|F+ݘOؒڞo3"Uݼ'֩[8{{YC(Q* }')$qO?hn`Y@z2OJ6Z6$Aủdwo,;b1v5 {!=56r'z\fX:r +'_CXWVI%iDd4>X):J xת(i) < <>-O5#xcTf _'EEb}4`Gn{5j YuiW_rinyV4dWjn^va]w۷yvxQ\ﲸc.ǓS߷&ΛNYin'¼8+YP}tU;&ӌ?zP}~zl%~WiOf5P{pcZ+*(> >@ƠY~]yJ7U%Fa֏c@Ռǎg^ = 5pPKiH#1$h`@ \#g<.R ݹL/\}U]E͇`lהp=Szd;W]!,E&d5*X_.ȢߵaU*7A*rqsA;p3cR!%8'1'e##(Dʐ}q5Jbo5;O̧;tntua9O:~_P5 +Y8 'B^-Zλ'9vzL<ea9>(W I|AZHq4{ rN̽b)RXZ|WnkWsYA@lJ{w5>Ĉ_M;Sldb}}VU+JFʸBjֳgC !]^M%ε*y^s]y{#?u?"kk c]]_mOTkޡjxq>4Jz/v~:f׬ґ㣱]a 0ðEJ^7Dy2=WsӬoias\)hqf5_9K3KFtfxnO_k; j/pO_Sej$QnO#OǓ)п NU]s(;Ir4a5L,@f6<܌@˞YcBxSu  ގK\bArVͶYheӢiъ͗~~kK6* UqRN»5Smӎʩͩ,n^gQ3&ָڜ9"ȝ]ƾ#+\Pv!'[NW1CZi2smؠKؼqx4xׂ 6X:eSm XxVLy)9T> &wL1VSo"LN ϟdBȺe963KrL;[Z;ǓI(,ϧsD,azmmUB%2.Y66#:.55 9[+9 xfBrS^Q_kR n2 UˍAQv Џ6oC.zMU?'Rnh{}ݱ6/4;[rw)j,Dz2*x6ؘs#g_f8R+Zײ^WÈ8P~ur+Y-5L6tɱ ֋ŵm=ZN3Lie%69E2|P!D3W(u)d@8qr_E 1םmw 0__aifb}&yydHB}JZV+9o0Qq7K_=d1֣|Kq'llン 2mVT$u$S}i?˻/Jk|vB['F>664e)nƞj9B yOkbEyX,ٝGY_r'6G0B5R"_2N!HOZl27J'&+KE|d&5ݣ6ևa'Fy2'#-|rlhE1uROM)s9|QEIڍ5Kmz M(~_+v?CSc7,g4O ݕ8@xŽr<=&)D5.&<^QZ3* YWo./}5ljA rl|&޵VV"0D+gQJfk])+jOC>ëÉl0]6lSNA}͵~1*t߸/UW/huQ6wf˧yTd2VB<Ҽ SSdfl漖>f3{ߎNTHki,-@;EYv"CvgE%rdd=CsXׂ֚v+~N=[O,xip#T^ѲO?$>Q<5*ɿBdC~*Da=qݎvs-^Rjk\֝f⨬EX$; S鞼XKOWRvOJ;6l(usX2ԏk ?f;HϧWbOk9w.ͭwI2k[원.@ WbS"%OaU\{iyv{z>$i֌A!͵:s#DoMm.\sO#ic_8[mt3MGoh`n"epimT}JSNX4EWOiWk|b c䊥9]zm_^ vfN)LqU_v}rܝ|_"Ozmo;_cY+ЩȠ涵쎀0Mrf͹aK3U=W8-Z>V,҂Kr.65X J~e[43'8k)^e#.cT}=͝%6z-%\}U??=K66v76i\LkiO kD͐qiqR;Ljlz7qs5ܭǨ<凪pe!/b<Yg!{`# 6z}/#)vtZjٵgMYG\ -fD'.=0qxS׭vLAQXs_@i39ӌ+먄]H`y"xwQXZ{' v U8P>ɇmTY:0˜s;[bETh]+쮼^@b.9GE;ǐs0"ZR,F #^\f?mыv?d,j:A0l]Pfqq gƨz&IW:AQu°IŒH< loo?ۿL3x3 ^3:!ŁV`VLX$gTEqg8@p~Av Fp38`C׆嗁5<#;qut\i+綖{H紎{H絎{y 3Σ:9 ѳƹ\qY:^3s qasΣ<`\ \80>@V!~AwR58e-c \7s*؟+CB??0$’QUuW>*nмU/!"cGPrXK|+i.bpy{a"c(A5bG"*)828SfzQ^pBN`/q귇4rF4n<ԈŠ;ĈJ_+;hx L Z+U^F4BEU?Q@lGFF%F_.Ȗ% ء Ix{.2uߌje PvN$A+ FB/@z]ؗ"$F聠-_㘿L!#в-몸OD͆,ufa{Gj3:3c橹6Ҋwȍ ?aj'1BEbDLBp?[6'P PcU\Ќ"~HOh/hTidnj;Ce#Ls=mR{"@9႖ᇩ\Lv`p)"b/&6n m*`9[$H~p͹L0s^p PJ!FV !Ъ܁j*}7R1lHO5p4lP}2$&8rMC>=<ѐ8Fv6;$anÎ &UwbjS<{p, ܓj;m1 7lWM+d3oN[qzƋ޷;Ψ]^ŷ-V[$gtDF֌r!Q,Mջ;OTA UcTU̠dEa<+k:vŁO)sT W"#ĹGk_a/jUm?{PݭQ=Cz$?\>JتEFtO) aUnQ`FC͕ TDKNo$: mZO sn4y(Te x">(ms6#Aܥ$b)GmƯm meRW d?W&^tOTe\}wFhn3"juP5ó50).Mm炌h5.Hqa`œ@jJth9J=-W #-%+"3>k]< EҵT8 h_)،\0ÏBS*Єe1>ˮ]:!_O zD"iB3\>X, Òqް Dms: BAג,NX@#S!_$ޘ$oPRܱNC],1x&lc-xrVN7ZHFTQ, uF$rt9å$­nm=C|Cueӻ6 Jw7}F\މ3V4XJ $7il˫.bd.4H؆};ѓ_ŐL7_"/2: සDpcTW\ e9ʇeT;_'Nm$y~J*S_`'qF P|xU\2X%[wQA;wPhݖƺ5!w buR^x`(ciij3?7QPtTƺ"9g]XR9PPx niKyi;.DZ9@19JOQ| RКx&d`慚*޸Y5&D]oY1!D 뒿הn[$$7 #5ZZ"w'Ӧm؀ڔ˷ /1gcjGt}XAYQxT5gxw!Gls֭h]6 lFU x N[v9 L*A䁔[Z6;B@qPّiBiįVHȹ PCF^WʠGN# UAܮ@F$j.Lߚ F$]Q2ʸLqGr;fgS(S~ |6^n>tK7cCWAB \Q0댵 JGˠvUK;aARnл3FsOV+Hmgwep6}c4RjwzYGwIc@dVBAR<q Ϲ_EEB{4ô+)Sx1"(Jb5Nx'yHˏbl[DјV r)T5:hTRS+NtVYgQb዗Z/P̦?(qLhuhrRl=G<F1鯁tS[2T0,{LM cE1:s&]]M#rK{cӐ}'s#y)l闹IͲ RJ/5D1D*OrhD䏩9W9TfzdY?ҥ*Ur鯂Ip#.H[?Nr4q:+1,;о!Wۓ SM-'WT'W=RC,;M\j>zʞOp8THyUNRu; "jn6B"AzjE|-ܣgEyCjJ08D-jam5zh,:frЧxVgp$Rj]HnG'}M%3@F2m(ƃLB9㪶Q˸QF 3J UhأFonW*#785L&^R|WQ"$ D6>%-vet}A#*><*euYFS!͠4ێ{H0ӆeHJ$tUU-H?SehKڭ_" ]^Haخ"3f3GӴ]1Tb%vzxDt_ PDq01.8()D͋qFJ378ԇg/ nn$ n#܄.?PQue# Y/LHN`Q2@jhz*،c2 ,ÂqI( y1$uO ?(DptRQrGm/Rt*'bQ9f0Fgbhn *܌Em2&onyFvIGly816&\sea7-g=F$Y6uD`ȯRNt8p)FwSdx}Qz4quoclpWM$@J"ۀz!(S-!\KvU0qz*7 Z#hե ҁ#FCހڔv2ӕ898 pNqj'mzbHF^brhRyF29IWp>]a$%B@?&b_MmL[psw5;mSL9+I\Oyn7bv`Np.N:LaHf"q-VgJs`#_B$S=xGjįN 9d낏ætu5Ff&t~mڍ-9!&[eĮBZ$ pS݉eN]1֋> h>{Q֎'l2^|snnbƬ}W\;PHd N]U# HY9Ax&ݛplPtNjaJT+vGFxHuz9U0rr}-wc3hdT0$J\9(]>G+cN$hnKF a棺Q ױWDGu38D9#7Rn"@w'hݞGSýCImˬx ͉6LYޮ嵔|[z耨˂7|?tvQ0VOv9, SLB@)^X6}a^1#؇ÖHͳ7{ljNqގ%;hd/SF?S*Ϩ'?5?ҬI+~{ȸ5R72QȠfxȾY:%7!Kd|ԖQ?O5ByKv!"0jvEJqy~QڧLhUl>ubIlTg S.j :Ht,rb]/∌֬$zԣ9.u}O,$k"O(F q2@uLn|xoEٌ.$g Pھ#wsrDT9ޑc/dJQLU%ډN Ԝve S[E"%dwU<&j䝩ih t8Wj}ZoѽHOQ9k޽8];;'p8ەЃQU$'#XhܜXw_^H=DѳqeҺ ӵ@%gh0kE;KLj2zߔ̪DcJ!)9#R }^@>չ#M05'W`-Lz]_RiӒ}-[\im?j'*x):>N;#䈑x12yw-2 u{XZzTjpC0O. !\#؁aNXdsßD j՛սO2xk;b25:grH-`S>m`HJpVm$G3eۃޞ1/b~ Jn2'Clb*xAצMaUw/'fb1,8ۛ6/ lYVz5BErhzER"BlI|IR zqE]S (\ɐ55"!.ׇ4'#91 0'jUrȼѰ]u >gEa#DQu::& !U3`"?d@Q )f#{ILVN&iÁ"r8Ց\vƽcW~!nHǦRǚݘ%޺`jGt1!k֡dgW1P|]=SiO`ZrBan f½_ݸytz~؝222xJSܤǂw'dӈuLZq$6S(cLqrI_>"!/ Q3˶@ }IRO!H iz\UF17лw8XsQ/9WJFFB4-+CsNL_UqR|j{Ԝ~3Q-QЎRxTrc%(nt5[rx(a qD@&mtFry Ao-!irĿJTu@9btv (HJ҈1cTnmn0j/Re=Ԑ7wYڢ7A%!Gwc-I v"v ms3'4S#ӎ۽Fb3Km'jؕs&(Z+b>%F?t]@(BpO-Qe%"K#O]UN&!V.݉wY4$>4^߀s[{XK^< &=BV=ruF22uoQ/!_q3L{Cpc"¯QmR(ۃhnʷdp&@s3F9cLiGnp C 8A8=JFrbK/;"܎AۍL)E哘>r[\M Ik"_O4VNLo6j&\F<.sƊG }Gh [%7Q5nDp_ObH9뎈*0cafxm8lA׹FpG y_bڷ 6+l`Ưެ IjnRfnBnpڣzxdܲ^2܈3fFa1. ۙ1xԱ gpfoW|JWJPBcr(\ݏ5`-!s0@[p zy$I _Wռv`c*1_O\d%- cCt W4H$Cj2z'5q=Q/QxK?98ļI-/e8W߃-GfPCѪnS~Őyw AbQQK M2.Jd;3ܑ`" ?rN=Ƃ}DR~$ c/K-#pSf;spɧ$mۺ҅ 8+X@A" Rf%ݼcIr'܏W0₟ܐ*tr}>$ޤ7 l]o^rYaT6cvQol1Mu|XiTw VR#NyWBr}2TM9h@$)v{dq cpp[/!:[Gu-c?+qJ`{*ΊUWrhѼK 6vɋ',Ԍ 74#W%#_Ƌtʼn /,=v fjF# 8Tck~(⩆ (B5(aa]_L#A{(mk}6d;Ӗ::jGV $n 2d@$$ϧj_//SBZ=vd v/"R$֯0mP|M6wcs| ˖kkr9@TDfm8YndJr'+p;]u殞@xm\)W¦TR۲rn %'$d`cP|WHvXc# ?.* Jy%Ӊq?vl7BH77[RWв)M5"vb웫>DCpnPY%S>UQ qoc)e BCG5eܭ2gcP[ѹ gςf:#-2Z"GkM\x .C~z y~4bk`{,#[;w7_=Jdya2GVk;2-WR"dF&gU%F6\[4FJc'NJ S^QvT8ʩU/1ՠx}vc޶aCn&lZ*W4r-FpNx! * 0EGGkP2n>[pC"ő6 ٦ی#!?} P^ rsSlˎܓGk"I dZ-B[5d.f[t6b#@$MpJ{]rfaPwG7r(j0,Mdt Wq%mm@ ŅujȳήŇ(msbcUGoo\)f< 8-XW+n5nxzP>-neUHb?Rgw'UrF;!|ډ`#&'/S˘:c< e@n Q9KޭEv8v! "D8dܜx#|!bFD`w@F)}FG3Cא]$gm[XTG$8|TAr 꼓bN-O^iॷe/r\(?O[TRϒn\ a_b}̱obك0t/ƒfzӾ&D勡rm +j,H;q`/{T~ v">CZLwnvD6 b=_½0}tV eX9.z{uBa]旸p8+<>ĕi8Vk31ˊgsuc@R؋cpgŪcRbڕVH!Vfc#.)GWxʴ[EE?Tt!"A2Ⱦ h, nH"4?e7`)أsfX2l_pT:2ԔKn^GT7.0/^|Cbd7%ԝ>oO*@ U3Òg)ⅽ bFoފg7ɵ!O8\V.#@B&LBH /[?w=D>J"D!2Cdޥq!|6`rV#bCDè:@DN/L2^>c07nH`m]~8Q㪼6#Wfc!)rZ,IX*Ή|KCTkN ) \na4^RWL4UۄsM0ɰ"jHH?j@e,>J:q{pS2dݪ5Xa_?Q8hX_}~ʬ>;.p #t7".Q1`#u UK\Y c,Cɑgqcڣ%O]F8qz[&z*L) 脵a&ʨCSC6&,y1hP"9S(/rꍽ#qQ1?>x(ubfc Elq@F0{h4t K0#]ᕜb*20{Uv|G% =Ry|sQeWF0Ub =3k>#0ޘ-A_B8 O{!i)JHj-F?8p14'("5) Hv섲Oz[Hwzۙ7B2|8)8yS`VmÊNܨ)tE38`>*SvnT aspzD c(E~AF$0+l3 ɓ 1`Al)QDڔINFªEK}S9) HkK >OܻnR?)lAz' c(F\](SOj+YUN2lȫ;RqF{XF@ܗ:=㒗Id\3xH3< F-??>˗.\r.W.\r?˗.\r˗~s㟡s?/w`??W?W??8?q\'s8~?CqO8YCyy8WWO?2d&Lq&L2dɓ&LG#&L?]}+YoY+r/c6eWyYo.]W+r;?2I&Lrq L?Cn\r/̙2YO?gDO?_2gq_~/m&O؟?̮mA#*GpV9yHÅaM\*(zp-z9:oZ ʋDt~D 1+m~%oR(TPsbj1%D fYnO6ztZɃMmR/ mH^̰(yOWIpf]_ruֲC _W$:.X(֑87^0u3D=]9nPI颗J~׃hh kphFx@6YcEӕ7Fos)J׾2pZu Z+79#zWq 5@cv6f'(k LN|tTuixl3^T7 2 >|AGwq2 K[8AF)|ωÀ4LӨr2=lsJrQL ügyl7Qq/N+?U 5ƲPC2h([}8K  jeeK q@Mz&Ѿsd|4cSYBjrRd;Mcc30*|o7̰DV"Ѷ;ߌH;z83r+:o)ʚ,0PhppE$^҂ 9;0ѲP{&/|>*e`Q~KD~n|r'. *?nKXZ(/70wbr D&Ȭ#dX_# hOxUD lS]b7,$u3gHos1K`ix"/%qkQ PtwsElP%s|>2Sf#R;:ޮ4Dr|r`݃MO(-?֨kCvCZ8N]znbǦ^;\.\q_ ŇmKWCL v>7U68?7X#:͢?csX䦻o EtkH''''2o rOnxɸZ4ֶbЄ)9P~cm8g0Y& (2gXŜG+߬9s+@_,Crv3}?8 VDd,Qtp .Y%5yhbAQlbB\^6|.LMbb^7B[AD*ViFv\"r,52ELESV߻9)_D%u )sxQ ه)IVp!uU0(Y׍~L0%=KVkRSZ 49Xq@MP&P8ڨNN1jJ1ȆeVуyp68 ׮qC\wx9x{ӽս$U$C-}'Y~hPkЋBIgF uvB>",ruW|`*Ump =]8fcV57Qуvyc2]oUTo%WѼegp@~ &0wԱ2ƹ =YgTZDYg ! ɜ)G\5\;ͮplCčq\ K'ˋDP>A.@@DzއyQ!w#Dٚ zi4v+R%ɊXξq"^[燳d4g1B@i)w1\0tA{ r)yn,]?Ed<\z@ 9%6iX1]QǃAӃ>'TƖe"l`_7XGclO٣996Fe ٜ<~̵{&738XoQBB @&BYA{yxRWu╶_oJ&@7,~7rs0h~U`- U{7 /j+`:zG0F0' @chjBFĩZK]bQ^q|R)dcM(5C徹2aDQ*" ywNN$>)@Yq44H&?`U #C' !0y*]Ѭ 'j@W hL )  6+ӷ,!7~<`| 7RXLFSP-ȉ[`w9|f`u[qS4Tt!qK(VM㓪1u^jňJLu"۽_YXݩf}Mo*gр'L ¨^u:0@z1:D5ߌP,T:͍\Iqr[N13΂S~/`kf@غM.P6h"! Sx}੃ZGgY.)S|th <8d iõLDh(6"6ӭ=~![ Nb67sMXo[xp#ѿ5n*1<~^Ā Ni^sj-_P ӊ5o)5'zpDwH 3J 5Tvɼxa 4[Xù&\+pD8\4X8j J G#u O5T> ~j;Ps;YU%! tfqD:Ni1dKꢀ@rxӂ!e9[ʗXjK-] "*86 E;:rĄ14@Lg/9 2:u9w b&@ mW٢N*rIX!iP.sAJM䒧ofΗu ᢏjqhT!Bw @T0%; L59a:}cVoFpA#CS3,(ɡ0Jg]؇8^N1hGoaM&DG,nLqfrN%Tx%("VhjW(JąL38R05du>4sH"S NO*v*G/8J`B2"('j|/\Fo|๹6V& &? cp*dP(@YަKbyrscL@h)ˌ+oM%HƍDc|~s(cۉYzUˣ_ "d!`n3 Q)Uho)8) "`^t?'jـD(& ʧ~>dJ2g). ȁ9$L0IFL 8rZ и9TN $?{KZ}1@yX >/6yhӱ d54<@g(;́1 UN<'zͥ%TcnldbJaݹcarS5;M8a:>1 ;Ȓu΂|]#Mn¹/V5G(0BhO8Ԙۭ MZy$Q:6~8BWS9rCFE@Ch\3#3\xCgIFMAe}<Xh,}qsn1Eya*E:_nn6Qw4Eyy@jnj2PS);A=AUo;}8&v:9C`uO?Oҥ]~0U!$|E~0ϼ9(IoS|b 9ߟX+f3qNx+G'ް&fUe]@ƒE_„eaREN$D%jqFCfp u~p ~uQq(8a+JS ~L3 +$@~؝R=TaW.!_i3)ʾP;Q3DG>ElvP=펴RlƏU#n^7=~bSw4MqBINNnPY5Zkp7X0#UD\DiGḥ+f#I[Ac>p|0GPA^X˧E^B ]ފ\Ixe]k 5PM%ž+ؖ~& (p#6ou\Y8IdmQxD3LQ]t0 A`n#Q) r;g1t QO?Bi-xඡ6q@ܟx3Xc@u3@)Aѫw~ߦT>9M8.'q(UQD2 <ɽa/5nxml2iL@vOnj2  @5:x^rUVpP7J@@h{㔅VɧsVнQJHЫ! CF ӔPZCǫqaZ4ҧA4NpHGS( H\PEd2`5}GY񒨃9VȋˆP|^X8yqΖrū MVqo 9xh&H7'몜&{H'qGw}`BT{uE[}`BлbբfHyx1^S?-~`\ [D 'v^uT{ sĕ۝7KMaI8K5wAP.bӚ玱e yqqK˯%fD1;WFe}RDG8A^ii 9 1ZgNQҀ~2#_8krB?l3RhH;kXEW9qI|ct)J*!gxFRtBks( (/oU{'Hw 6;i7S|F" xy$)Rȸۊ=y8͙ vؤ$&|&/(VͱMsV"n@5tC۰?>iȕ(TeاV`"$#qq08",0N1`FQ#`Tǝpfj~jC M ~| |  vE%cF}Gca,^_Ue*?yuXX5^P<~\a4vt \+*C8 )ҔU L ܺ%=3t~7 D{7;meFN4Mp4lr8 f@'.ToXv1YTkl 8M8 FG-OFxj|êAP1gl%YKZvq4`$4zV`A+ʴnj@8jW 0"k@Ɂ GTT]b:=#tpɫGI\'uZ٣@Z0v=Ť b?90 =>C['J>PWYG@Cš]4}9cf 4:syqtjdOҹUC2z3 t+vG (:'1*Xo6Wh:P"b4]_#+ $'],-<4e@ۭx]0rH7kȲ4g8^4CHjW8XxGAЖB0=o9f+نH]DT$czH4c?8-3([AFez/WyeZs 9.ólBRU-/2bʵ[T;Ƶ_ Rԧc\JBՋEym(VA$׌uuDRX`m7GR5Xh,ɨ#9-fw<‰!5﹬YK$CB/));ͳ6oJ}bJ]  N^Φ]ndFGRw4Wp({šFߟx D*r xqSb/Ap)J8@ApDD |.PQa:/ /{ v1ŹXIfRbMs/Ylhyf]W _)PTAe46  GkpI@(:r/8ӗJɒY fҒbk*yrvGF^Nvp6/wi>q,b(Z(:AG#$%Z iԙ:'A1ۙ"raזb( 9|ߘ8Ù7}JٺO)4j$ 2AAodo^oڄAT lm*Wp y{aؠt5wU&/n@Yujw~VkTB45S8 {>XPfcq5(^=メv=cӘ]b#ϙoO>C6Pս8n<X}# :PULUD/wʤ!k⺹Dpu77{W4d$9in=lxnX= ) ~PK ~W-I95 7])u Ԁk g.G2 S+\\s+U⋲tx{ -ӄ\W (4g @(1ZĺX/NiMpl?ɻB|F/ɂ@U[_ΜQ6!PJ W:eI~Y*댇$4#u8,@ ҼbC :eEsf kf&h}j)V*osȸBu4;[gyT9?_'s% tHMZ KJt'T|=j[р͉\@B`K%H\mW-&9'sA U9LϞ K{ "h#5IIӒi M+rDhS4xL V8.3?+ʅ 722P(Uw Z5^fe6@_Y-m7ڗI$uן\ 6fHSPpc) Ӓ@ èF@*No'0!3A]N2<5r +^09q]բ*Po 1rql(Tzm1Km_J(=iA A7 T- bdoy%b!GR aM.a@"^Ac7iX9(C#BfTJ.PBAp{ۙգ\8FUqS4F$]1Lo Vcq;Vμ5B4icB+GΦ;Oe+c/K-D;X x =!X{\-§qj排oHנȅ2BIA(.F=":VʝcIL8}xBpI]Q8NϬDCfƐވAyM7n2j w$7CFvJaBZp;ʖ Ƌ(:"<\imQN%JkI`mt:u/1CWCM8>IQzIo%2F`.f(y no Lj:&TRB\w 0^6x|k|w`çxzi\p'D4!D?Ȏ1{1M8J@BЫv_I]CE0.~nRSuF>Eea/;9X"@T? P)bO)_@GY.]$G]g풀i쎼E$ja@aN܌E"=MA!=vt)B¯VfZg" wf ˠB0 єn^?>LD  Gl!!B`oib#8\BI_w%]) a#zR>48`y |0ɀYH|@uM yOxOeqV$Wۏ<ٿ0_|aua 8Qx'bCvY|+;vXJvD`wKC)xP^8RbI5>I9D(vj2^qjůI۶Ϟ+`h>_-n8L(I8w(YnAJ(^1TH?v! 3 4AWP5gCGGF-䮴a-ؽ/*avl^08N(qܪX2e ,VBs=Df2)@x4cZ; X8F5 _ݬ Ea44ӧXCt'(^=# % HY2nX*`\0G\݄Ҫ&7W{0Yi {蚮e Q+RGECx iy EU.>E6PGb(>]⩀V*B{_LyQ%(|D 崨F? mɼ-ٍu3nj !'~_'Gru|@Evu"Tz^Pu33N~ eA*7y<_&So"q^Sk/.9)WDBԼVlγey+q2q*|O ӎ,6Trq׌wbh !|EiA #&p@$]O^TmkJXaS2 )7` *{j`7BKT{ƽ:OMZY%Ƞ~3H H%/ԷNmzӬaxy]rRwpMc[W;;~1r _Hk~pN>1Ƌu/;(v1U<iAEAN;ǀvQW(:Zy8H7)-9Q)^! 4n M2::VT Mx£]ҡEJ**;U(Vp"zE0SrE.ShLm}I)\H9uA\ɯӃm?NOblvE pQwETNрU5rZjC7M0x5z3DG7{0(NWt6'G.ջΦ ԇ^NB9'7u,W^W4`h󋀨tnۋ ݚUxCuXaZAdŮZmfbD(+Re@uG#KH4jO&=>haq+{dLJ.U ["!_8'Nys d;Pj |}aX&QwqVt@d7l;q6WD? pMv Hko~/ü:z ,ƥ J?-ε2qLd֞jy¥͐g-XҺvqOg2:4kʿxo>5C|l\!9sT56Or׼^/5"sǤT o$fP|u06r9zCr_x`^?8q]+QH\?m/>N@0̈́y@rox-S PsMV!, 9RxRUNamsV}D^M%8FֺGKER}cH( V>.Z` /T`"D|HH.˙JJ#QyɄ4a[ mՄUV{p/ <)B)yڂE æBlQA(l9;p"*bDsky *;zq TUݜ/Kn\)ҴYAHxky!5NN*{ *А ]+Z8hˀxh5шf6}oMRݙTEm!cE0 DFİpLod +حW)ZtE+'vl@z5jV`B0Kd@t![4b McPlh4 y&R@V[Ά@N)@ߋ}:.89ixUcT$]Q]&p1^~qΉm&h VF_q?ݿxcP [~\pQ;(ۏ`"y {KhR" æ 㛃g]Qaf'O X_D?lB1sB ol_.=Rz{0΅*;GEQS 'Pylons-1.0.1/pylons/docs/en/_static/pylon4.jpg0000664000076500000240000006435511645401275021143 0ustar benstaff00000000000000JFIFddDucky!Adobed %4h   #%'%#//33//@@@@@@@@@@@@@@@&&0##0+.'''.+550055@@?@@@@@@@@@@@@"!1 "0@A#P2$%`B5!1AQ"aq2B0R# b@r3`CSs$ hC@%" DX b6h@h*J  iB114 LLQtXeLM Q(JȢr@XJQD@ @ 0Q`@LD Ӧ&J.FY Іh``L# ؘM +I:tDTV D& BC"ʦkdQkez 1 0p @L LR>5gtKHިZؒ @U +] 4` MM@Dtbc'G%v./-DeM$u؃lz7N04F2D,[S*[R%$~-FrC&$TDd0(u1ECw; L 8ʇSDc( ˣUPY^8mW:#l,DA\KFq 4X^lYG_;LLeLM Eh7J5hݏ^B9/Qb-sFB9tvÃ_G}pG%Yg32ǟg8SZuLn.tГDF#$cWY&Fs*SU= t\m;]MѸ,)1!Ҵu^Kd#)"A +oד\ 0'FPRdΈmvNuVQTJtL\ާ(3tnʱ$,R2>Jdg&Bm( )z04*vyU#©ѨہĜ3SNR=>|ɋt.ESJI]g+VVJm^l߇t 0'BFQ(˫ԫ3X9im*[QN)BP+ݝNnv9 +suH5ntapMpH8I^5t0n=W̑+  y{I~goλq\\,F3L' Wd v&S8N 8DlO=:eЍ'C,4ûT,AIY^Q3L^_RL']04 yF}!fΙ|Dď+g3- C-$v)}eF*e CiҜeRA]t2E:)~5:q9T'z}>mj/xs,7YJP`ç5fM5aӛ#unl:~I w''è'eit_}v`M +$l` JzFRt3)S.ݓq!auPt9UD! ʎfbP-xBfͷY mVרVwZ!Fn2w+UYd`ˊMf5TcAU_O UnrzKEkG/ͳ,,3D:ܞq8ע~p۷AqYUR-rzGVy. Wd8œLtWr&96(;fW.^%2ؓ=%|/@klQT "իLz҉Σ5E%i2')[ Yy}|ö0qUgqrc5Y]U,] djk9#Y`]nԐ{CЩ4&9mFNQsU]@jYaaK,c2Ԩ_Už x:yfyL39٢5ĽFcamzN޼ƘSu&.__݈цL7^[M&i䉻 ^:Yȕ@KFkKݦWTsn5(hۈQaKY~m56Ъ9ǜ^9?@d旦1/Jd'+KӇёg^5yG<ߑ矢>5^<= yz*Ф9FTГ")sOtLZKsl7^Q!3m0ȅv19t\*n1GHn)1%SB%" L L+, *- 0m hTZ+਴)v*)+aAʌ`9s9@?~x?|<Ը38383g3839<9s9s?9sv;gl흳9s9s^==s=s=s=s9Ǟs9'9ONrs'99sl9=3gxqoǾǃʪn(sȡ?y=) |^2׏>,y@8pS| ϟCJT`@^|?8cަR{am'%t C'_=W$/?OVM`n,f˵,kI2آOn Pǁ:_Ufe(7/e>i?qFj"9=<-?T<PѩDbwU>`g7B +77fUCF{^R&'V0UU܃-ç-1I fEYo\;5'6[-@#CM\([ N./8|m,M[Q\4ƢK@1,8 =Sv E= ꫎@u$CMқa-ʊR (:LAP$}I__o:\R{O8RLR#R+!mi+I>z sgc\ B\,Ǩ>}G7UnM >@XZ}R,c&3Q`]BICEzWA!_f0)܈c7k \/7e!}Jmv!N3GgHZ!6dD:𪧨PrkOY|× 4,;8=,]{UԳL}# Q >{hЭ6ꒂ;?|WM.Zӄ .OaΙ'+BoS㛀l]!&a봪c>)B^%@ZˮX]%\Gzꬪ߃ۍ^ItS#Kr.e7KϦn6Aۺβm~˴<[܃vn/]+BK(e@5خr}{3^U?m{x>vOGa)eYk6я;ٺ;9}qUioYK5Ui&dVGY8J֒SPsxbsJ$˝ZXYPm|k܋3ACfs+'jYF|H>M-ۆ ߒ18Zm:g)ZŹ@ ;r~Fd͝nkq>>TlkP͝/-kmo;v|m63P?^]nR?- p^f9tP-.V?32gG3tsJOU&gnCUyv!`S23B~FfOT{]1z>*B X N؃em`;&Tx>ڣuۦ+~ Ru)ZMD`.Z36NZN` URCYRJ8{}4&l(ӰWpl#[2?ȩ U6|7[WmS^~4P`{6'K@ъx*# o8~Bo?IRp)?f?u~r V%DlݲnDmr>Oip[6ց/gvɇi L啕ctvY7V{gkWvߩ9sUv8HOW;Ju=A$𽺔6\Xj|<E6}}fcMP"jz9o:j.VBέLԶU*899m*(oQQP=88@*kZUK&[v!mۭ-+*])YQHa(}y?OlTn16F{ĨG 3 ND=om˱UtEn옹Z5 a}GJ7 lVuĂ!ӡ`zre"KhL`gcn۪uxp{x>)@5 ?bΣi~WWJIY}e%Em-j6]wI+ت!v[+ .⌔m8E6n+"QTxO [d/՞6bY9Ã_m\'#qYhHfZپ"1<Վ{IFQO >ZHi\kYw*O+'UR c*I3jP"ʞx`a^PrXC 0'~: Ã_mw4cO^ʺ· PpT(B8s韫Yu?w!9+t:S sܽ]`vP gkF2wg4*ePj[+=f8p{x>+Rp8Kj~2UKmuuit;(`0Wf״)MB6bk4+O a(qvLu&EՆyOfS⓴|0]=V2z}5[[)ّ $< $r~3?$sѾzWg sXZ Y> t LPUªPw  yJ">K{tc i s=Io]_|lRo1ãxOa `3ik;2::pJevmIEm[^jM+[T7\W!J)5{(C8/7;'7Tіp Ѧ4uH Mgg3<`ItٛJiCaת: 9(ih"u$/lY}x\FI ٶ7o$+RLK6 Gn^s̒ݕJ܅' vRo[I@dǞhM3R$P=똳lnqޭq!Ѷ J{qVWHˋJӛno)خ#SnuSQ*)(#jk{s收Խ֍[1M,-Y/?E:B)9|PYΎU蘪_|vO]6R[jJe^krVO GgUv[ gV쐩c7 BuRNT9 :=䶤vTZkky.1$|PmYAVW[依SX'/pxV`q25_eTDlSL"TM@57Ms/d/PkTH{Vw jV6jJ[g ':he^j: !Hh-{9{rZqgmbO o7f ^B]j1$8(.IU-TT65gGBXOD 7tUހ3?bL]% 3dJv1Zt~Zkδo/,"[:jLsnnȶ~X =c|S\Z]o] gLk=*vY):P:21Emޓ)QJl Z6MvxGW-}!YR1A=Z[6l:[Jp 8yO9Aq>@A:U|7{dڨ~gUVO )tp"igvf:V)c. ?b2Ymj:Qes@ 5B:Ul^R׺kT$j؅l?]7E킧WXjZcM#Ãm UɥmPvw<aAz=D%lް CIQlOJ>xU]rU0GIrPbYʣeݠ)o"=0s_vT}H u?g5ֆv(I9]M'Km|OGtߧQKjׁNZ?R5*TƄ {`h=IYa#AVةmy>T2u[>RTqVhm::>a-0jrzlڷɦuv3Z P!YAp{x>8s~^xpu\3gU3Ίp?[[?0JC qF|2φXu~~'>=HZ'bs嗎geNPy=Czx8}3gjfO=s/tא {x>HieUJģ+դcg:kNB_hf dYjȃ4etkIo!C?eoز[Q4cDڢC].Q[EҷY@لÉg3ÌǮqsE+P :&u\"SOUTuR~4 (PQRώy ^?^,q8p3 3Σ:3ΫW:u\sUΫW:t\gUΫW:t\sE΋:.t\sUΣ8p3?g??g??^YEɠPH:j$<)iWq緑v-CDȫQD_IAD^b ƧRìžRT7+6L 7/c}kD0PoO(S6)` h@t&O]**wNQZQ jM@$IX>‰kj"AJ|񾆧`:-ᷝIi뷕\OTŎ5Xkm-Pj5X&XϴԴ{:,Vc 7"%4cZEu.}0 В А"0/ =* W5/᧝sh%H1Ң/A;/~ZSE@=h*XVc&5IiWA0Ll$^We"n5&0־.GPv~#ʊ{ڠiv=#9 {(1e6折OqLX*xh5>625Bg:b_Zּ?ev3goF_VUVFyd>ٰ9xۘV" ?*呭%1)fP;i/ A6C9mT4`FL-i7P.gz'HڄEqӨ5$zPAzԍH-& kRFF#Km1R4ePk&h:,@;zNrf-#> M ```1T^_ ǎ 1@62 qC!$oi'3ӬXx,IJiY7^ ]&~Daªx C֔A|ɣmP9"W_ G5ܶjt&g1Nݼb="Xjq!Ŕ -hHFbuΔİ,M}IS?1XX#'MV|f6QoG1el϶`@<}^N0PHϕ:& :~%A8J D|\i4נAޫ2b k^Ā5)fU^K4L{/X)C[O0HaȚeϼ ʃ4<@ WӬ4~5|,b FKiRr 3u²'qe?(Sr8> vfOEH`GZIe5񀁱/uhaoo_lcd e΃RfT%Bh?P/{ץRT')r*_PG t P7*gƫ@A޲-4UdXNLH?Ɓn)yYu|xl(G'[LUq[UՑ dg:O >0~,\++* f=)}W9Q:޹*Vn@n@] & _ƞMȴ^*C0vsWȦ3%kҜy򀼋#E}6*"߅8ɛ™W5%;H ˌ8 5pIoJbL6Q)rMfu" 3_JXP$WO&Ax' 6:5X#6t;[C:^{%X죑 IoY%coaHmED !m-XU;qEQ<B~ @OkSajzPOsI2=Ԅhr}(@< $N-eY h*I7Z{MG+4BJG>+!Iϩ 9xR ՈKmY˅$|x3rRX(FR`x}hܞwU3=mL V t*2"fQnj t=U[/$P6P7±"|wOpe ;V'ƶ[yޖ@7s=:+62i ua c°a:RNB%:ٿBNݲFт(ff/!޹y?Y$$u$60cNVǑ??w=5` 1#75[)`fBb56K[Ē1&%.ԁ;RɈq*I 9LM.Ve ,Q;u}mc~$>{E^R*XLӋ=c,D91ҙ'Bv40cZAWjIA#…Er&S`: R&"1h}*WCRYab'XR,mf_ҏDeD09< I8hƂ?|QFSӬRjt"̻3Y8˔{#c-6b ]ů=mY_(Cs*X:N;qO"}P4Zx~R-i~( jA5H11X.RYyWei(d86ڞ$Ln{*o`mFkWzyЍENZP 묊+y|G 5s?SgUv HK x 1h,!|yzwu/E"g,G#*OukPH&o?zGXC/kظ1T}E[QֲQ,Xk֜. ]`B`ʱ!%!x>Lkx>\rSDLnKR#98|FIzIj;AJ;?QLyWċRNFҖ,gNh. [+v nLnipzYn+BI[8&9 CveXY Qn=T$oX [Z kSDIھ{ƳjUTzʱ\\LC$[W+琢.'NkTqrA"qj]Kjxlu(1TyN)VQj叵e zm\AU ; )Ëbp[05?zév5y7@$ b$,ش1ErI'Jȫru5< "iO0biTq,Hb2L҉X/emDiA@d: /D-2<1cfUE U +c`(4SX h =uiޟ؁ h}lEC1K7e`)(Nx G\<hcÈ.p rbjBHxW *;N5fR#//)T0a[KYS}ՈaL'M~1<@t&MԚA.5ird5̡Y|@Io1LǸL48(3RP{^CKR Įаz~ &Y3r &r@DB,d3﬙ 1E^r@(@x $ b*b@W9O~[OȪ!ĞlGUy)̈́%d/FV N)a5җ96ʔ E:2J[mƁ޾@SS? 4Ұ pR:Ebd9~aOh$qVcD N_íb-,T7/ +3UV#"Y=-z% |H1RuR+-~BOX+ƛn"7Wf$S Uxӵ!slG-)<~ϒ;t>e3}XԨ/0[,K,.U 642 Z"c ExlҬJb'ʐC!. P,du3v+ ;$x\QfGnu 9/+ VNRMFQnw"lbF-$M A;)z@>MLEKkY\E<#-BCq3— }TxڰSr.A)P|%PAk{fi%Ay&{$NK!,+hF 7o[,~Ώ0_E+FۡIŀN&\.l|kSU凸1>t%U$U r%m-I9DB&+6.Y"09 {S<ܲdS {h#d#՘]k4ԛV @`n&Ew @"_+K~j%6 Ic,qT'0&:]>2xҊjM2At{ eĆFOljNDqP Jegd5tca8.#O@I|39me6%Kw {7$Cƙ?)NVYˆo3ײYָ3 u(E@=boȱPc/``,4Tc4W">ƽ=^Ks$ě(JJw oj\9y6M9bF[~8T:H,asM".Rub< &]dE"#r54zd8Bfa' ڠic$w8P-)le \ÒS4XX{c3JiDwJ##3$j@.UON r 'E]Ei;ǐ˅(0ӭ>%qP c= Y!OƧCBd`EMh2H3: +bdRF0W1'KrD`~Lw4]SVFЊ C1R~ l "$dU4bb_ϭ\ŗAn$* %CH[7_O`A$"(\&_eL Y,uoJ(W`z[QbIo#޿ p6 RnToAVdP rXR{CxP=>f:DQJ:kcJ#DLaq4i0v_C&F~,j;(b{.Њ`HN'O~':lyrrO;@U =d'`hΛW xP{Uf .N kOd)`RI J$4 ±%x-qىam$Gq6{؞m;4Q{RYuڳmN&؞Z X>ט Id3P L8') 1>Xq hMUuJʝ$r0mz¥t:%j^4Hm: ߭VN`+@F8Q;%#' 9<0 PUȷ,pKL2<+2ktž"E t_刁qЃn}Eb7 7l&+M(EvbS&+n"n@ޕL6PT"g z rҬoO&hʸBOēu~s<;j\MB,Eߝ?Vo.vY#XńVh"I@7_\Afy &d-@M*S,X˒I޶>,`ŀ+<466*iždH4 !wD{ywb:XUCoʨA=NUU9B}2t-s;F+9|)IՏei2|#TNޔC̊ )vL=ġPԪ+XoM$F xP3 Z 1?\rvK(#Yt ]Yx2z'x1$OQD3}9NI3e&'@@r$\M3fP|jNJ \PKi*+WI׍C-&4M'ycO`~Xx׷k4ʁR L|\@~bGt q c&Ayub7crxkJp~b:QPH;Xk:Dl:Uo*:ҭ B+ ('C!r❈ +{yJx If4-eQ$Vmpa.vukąic0'oV2ro:/i Ղ{YO[4 XA+ x\^ b󡕠D؟J O7E|ܖgXN98\z8.TATޖ`H \`cƲ*,<$P#˶3kn 1Q|G\IBlŦ/ğ >AlE;VLn@ŘW>tV`x7΂#1H=W X)a3 XAfMr$"S3j.GEz1Qj=$Nk}=^MzY'!ک͕b8(Н'j8 z.OwaǍr$DLC" QO/K,s:ҙ 7Z~K<\rM#}hfcSKV 7M4EcU2M^@~DOl-#48<Z *bp._S7z,Xzft.)gvlg?prEd1 0$֓(beK ѥC"XےcN%i$$q3S\gfXͣ(>4bڽ\ ˉ7@~_P}l`3 fLyaWJepo_@i* z),=5œa0`B ӜͲ^K C'>(n%ry2ZoD64 6uup+b? 2W*UQD# z?ӱv ,ŁFm'ε^ KɆf:|X#jĹRsq>(S'ˡ@ &7:ע񖟘4YG:G62AtJqK'CR2&81q[%Hb8si#+-򪍔i4TpׂcPȇ^0㜬3j6&qKb%G iSԎzeD"9iW3d;w|s%u=-J=> vȽh.GTƷɐ:\>>{"$|+$H{PXQ1VE8>Bȝmҹx !;uh1ά-#˭ W7ݐAdz A.'PiyA bENI:4ct&O Ft0LGJ2v6\`3đ(f`wYDnz4Ŋ7`4`Ҕ!Y*7H&"5ޜ o-x?PgWfeN֝hB2'™9A+7VjraA/cra׏ZrX :`GQLW\N;cvGr Cǯ1 ]M誎hADKco7?, )_ h 5D$@hM+ ۡiȰ~tLm6kʦѯYUDGK3J2Bq qnk&=dLXLe[@35#¸/iE">l|x4hu<m>z\1)qHyT aQ  bEWK~tw`v F8L:a m4Vg ]ؙuȱI?؛ = v Fx,IIeUsAG@cI 7*e=&<(&#I")>/מ8U@.~+P$&IG L8XMZD~Sbt`Htm\r szM?2éڊLo (N6aMj%")ҹ@h $ !!ܷ-rOAUÉ׶E@D&rMuϑx%H{6$Im]U0GFHK]x|{nO$4Ɂ$AC7UF>Dzh^jU2M[t+S%I0U0PcYTEZx8͢p SƝ 6)" MePmS#HC;VNp`OO*ejw&˔v4yrA$rN\*|YJd*$ޱ /1Jݽ@nKx@`b& |gJDϜ6*cC^ % ]â8mx,|(gQn^'h;I(؏ꞞT2 Q̣Ó%$sQG8}29Jͦ \,a(&wŏbd4ɁJYfqH+Y`7.UPI6IL Kd`bHƁ dAYD[b`^ Y߄UŸC۠:S)J& uk1a?J ZP>&  Fİ*%nC,ޤ\aua"F@$ݸ;ZgQ};+#Awn""$'Y9Xv3"!!j0%ՕJǵHLfԹu}Ih %&wEYU6RqmH;1ʙG< OjLlD$M&oZ$r{`_MBJbb h ݀&͏vs"Ehа|3}L=2),|jdĎٲ@T{Q鸓Tmr ) _1, j`T3/z1}DgҴh=p=p{X V*N5>j+$hF`*=$E@E@WPؔ?EOӴUE| Wħ+ha_haOGTq<+갏` I„dS:w Ʒ1 gƾ_o6t2 i:,:kQ?AC:11{P0ox?9H(ĝC"V.IhhDo۾7e "WK[JBrĎ&3!l~a)NJ*c>"$OWÍv,d%`_U $)>U2rsrE~_̇IU-4ؠ ˖HӖ#xǑa?P90oY~Cx8$y:XW-WPWZ T2$O_[ GPxT@*tGbĪP,*`O]8:EZ16ҏb[ F(5.>*#X'ZgE w A$uѥiZViZViZVi4+JҴ+JҴ+JҴ+JҴPylons-1.0.1/pylons/docs/en/_static/pylons_as_onion.png0000664000076500000240000005357011645401275023130 0ustar benstaff00000000000000PNG  IHDR*utEXtSoftwareAdobe ImageReadyqe<PLTE>;;LLLppp@@@,,, 000PPPfffnmn```XXXxxxֻhhh1-.hef# (''888___ߠǑZWXZWWȃ][\?;2=RCkE\GV?/5w{n׊y,W}N*2VZWB2kBO%јK-anRԙ*{x:rȸIzszW//U֟@Ѯ K7|cEWo6ߧo:>LKN`9oAwY|%xY;. k1^ :Ujw^^C-P%ox_vtԶ.Ӓ4{iWV$]gEGt_žw-BZ] Kw]=}Wk {lxC&w8`︨uGTm=FF;?s܆7_|Đv{WdwVx+q 7GFwxȭ=^}xuxi_$0jF( /~aپNsr{0ܿ CzQ9)_ru5})T5|:x[+wRWS%ty_äo*=Q6c~\/w a hEB7$oKP)YY7۲VoxxLgƒT5KGĤ'WSMj6lN۬B㚌GΌr 幩R[%/j &g9! Zb^i>Ivxa@)FeDҔ\w"Ƶ .9c6JR$^o=xk9֏<{գIQg By-x3WbsV˘xwL=^ Qbk`~X7u>I孑 ds9; FV M@5SP6u69~{A[+߈;°vUKI^Fcċjo~ B{M1SYy_Z4\z.NJ%{|SXgob֒_:/o0;gDP_=iWz㜌N+`\+e2\n}c›$)-~~gLƀM`CfAȢ<9dJ~Z+r:P&%ya\Տ4h .(^!&;Ȃ8.+ b{Er> /HG5aO~](El¨X!+ӟى6co}*"RS"j*WY(v.d|^U~^BlZN#H'.:ehPdgJڕ@~ _0H#x &9nsCjeq_>{%vYWm5ȫ$: \x˥ xlZҹuEl(\$\.ezOc-WIcx8RyP3׺#g7D.+G.:ތ2W~/򷡙|al9 7;Ю)"46O[b[OA[QNyşJ-_-Oh[۱V3 V,7)$(X@U=OOvYWȒ4=J恺?[x21&qx S0lgom`tez E'xW)R)B%\h8ZsC; ^&J-3`iXnBLaIXTỮw~Шӊa-ZECe:h[aрhY(XkxB2o&K@ &ɂ7-wÓ+r,&2Z-;s2$W O ƀUn G|T'u?ńi}OeZCE!Y~ф^XWGD᷄w&8ӞKj{7^:5htڹˊ?6qT\m Jvaf*ޠ T#O)饁~mHMMn]hW3oOG=T??m}j ̸GyVtx?f_t QjW &ֶ)d2+Ǫ#*g\`~XAP)lr(]"`!\Q֖E/>HV!\oxO׏n4htbS![OX ֲK6Y Nw/c69[TҥPɳC&PiQ(4Z/*;hk;{[xjx7or]pJَl}Z2_j{n | poZeض/>sk1 5E`W]G ]MƷ.3 Hxa):V\YNV.*8.8Dx]eNLYYgxZ_wwӁOx.>zx:o+h`855T|¡U_tiƒG5w7vp_48:|jx"aQF•ZZfNn\9jtm\68'_w^#椹5!FVRidժP#'NTeeU;ž5/K;%LjV~&@%^t 5Պ _Tmd29ޟz+RE*>TکT-]+,cHY`o?}2=xvjL0^OCw夻Bir ]3;8ɰt﹛?~>rYt_tæ8-*>d\x͢>AūZ9f0tqVQ|?Suλ;馣1WؠR33WԀQxM_]dvtOIG5:6,w ?kbA9ה]xMu[p3]k9qkg (,A'lkNγŮT' Nt"ڽ&usl1zw6ݪSԙؖsXl4xͼsG ݾ!kIbnk2Cm{bD=$|Cdu`:DN^Aw[^#<=!{ nLޫd޶~+q; 8-ק[ /url5`IC ʕR aҹkںo'Y˂67UEcjgCUY:^#P${KzbUOסڹ# ߌ{k[D67"ۓVMĆj|ܦ+=R;l]7ӀUq`[y2ɦ=|+)6;QW8J;?~W -ުax5g[vvK7aS$Ńv~Ƨv=+ÞSߤpL+5#wppvϣ$G HM{W4ĵy^L0ixAݍTVJ pn1YQ%2Y4i^ucooɱʸV!ݳK M5l+u-ՙ qmj{;eC/Q:3yGxf *V͵U n0ɎvIh }I2iUߪ^Y\YIxNjqԳ]J()$h5]7;fd$edyxgރkwBYkHy4Ui1Ĥ:giYp+W -VGȳ5obc;B#)->+PZKdռ+Z&:v_m͉9tfa%_5A5*d6l=WT!j ]r{]n /Yu$uׯ9cLtSAL1^:dZp=,sM:ts SPϓJ0tt_7jA6mE_Eh[?^[7Sr37* !:n4?u^v+نRRni1^MaTw.ujcw^cͲ۴I[^CZjjlReqt}o /p[Q!2֎h6 ¸!:OjN5qN>*Ο' _u0^Lôy:RT`?ʚ2k }+LI%E6KTV?z1ou@@?z!XZ][ Vu:{eZ:X8.ԟCQhrkxǎ呃g-L?o5Y4X ͭ 9÷Ćx˺`x'滴֟M*.&UΊ"'-y^O[ Mo2&:o +?{,/`i$ ]ܙ%"oύ~:zBI8?:ηa)Kglku($n뭷K> {"ϰRx8?7ovQp9&؝9"G{~{FB@jk^|=^}=6qf\+71>VVѕp3Q(+$SCtjvvKV?~CyvdxU!Q}x}O--q=~3~\=y$^܊׽ChoEx6}"ja}ڞ+G]FfŨa7#_ȿ};|'ޏ[G˯1DrxAx=/f޻O~zT]zaRV-3<ԕ~.ܟ=t1^ VV,>t[AC__;_4Vkq[%,Luou;n"= /iNUxeWA܈|DƫޮnvSZ V5*FnʮXva>֥LVvܮ؊[B#&|Ϗ_ x7]gQD1& 4u[𗋱 Tp8rG-L "^ndW'}/U"h߾SFЌQ7_7=C[dUV"ۏ9[Cd|xQ22;u֮#/*A>S@VEt[ l3޺hwBO^(-e_lmxii.@Z;=ş>>Or-ϳŋk%ˆމݯ?}#pkk5罹)v0zւ׻Gf^C='C};– ;1{7"zM<] GD[XtĻhx{kzA_݆l+I8Hyx.c5ֈe,νt Y{kEFϋPmŻSx o ;uh(yzx3J_:] ډ^`s{H1Ǯss6C0zH s7HV%= .'+xAyl͙2ec$`#^$hl_)oT3^KzIRUεC7k*ܘ4"(o|x)[)\g״4Q ڡRq63WVCerF) UJ)ݬ?d8mZj}⵲z?eq};J4JB1|pP׋FQ6ikޞ)^nJRe>f\ 㥤B EzyX7hh_9f 'j056JUֆcmElNWƘ5#.vO"u#H&SY$W(#4MsRUŢُƯo=wFV suI眳]"+RV4SuM7|*ma;1zdž|u`gUH6e"8ʪ> #"§ ]M#+M ]Yf- $wwhjǑh)<5-p֝mSFoiNsRQWZQk@o44-ǫ+P,`.71?%*X3EhB!QZ03jT0x{ L%j.ye˨xZ^+iehGI&<ţ*"l\dpAv~@RlA}ڹSFqt}ԷҎfe.Te]/-itV^ ^[;VΔbg9T.pvÌڹϙFqtJ*Kg}k0JWdWݜ|gT; 4X\و:סrMTgIRm3p'-y\L5亹{^WuNRoD3 GSu,կ +GfUQH.Զ< tF"R.9iUz5g@KZkl,UrAfٞ"}šy`y{"œ2jHkqΊH/ 2vv#4 ]יK|A$U#+D}1]#ɡ֌]g6dN%=xN<ԏVjP :@& z;F{GZ:^xx }ssflI;o1\Y 10lX*YE-.7tk`n6Hvޠ{]U4uN#/Y49Mi剢y$*%4U3,?0S֏t:fEr;gOb{Vd81s-hB_g1G]d1x¤2x%F*C,r9vѨ/rM eՈ @#@65xnLgFgZTD'8! <A /(O FN {0ط(F8(Ŀd\ɀW&aٞMtS|`_{{~l3.0kg422#$߅)4e5(£|8d3!K M$b9Al%*#^'/#FVKʜf*No~< ݛq*&&HRd>hi%oڧ_h KL2A1SLrxPG-@X{!v۰'q#YQ9<RM-B#<eP!SE*H]^2Xqp[^̊Gĩ1~JI_˼hڙionB *BA-2 TK;ȩ?M@=x~?eKcdR[8Y?=5MWޥFw!]A%46@LkhVJ sUxanz e-rl/S/K-l.T˞cP^ᥱQ0dFSfT2M*~\Z*AW&@Gjl-zn@EL}*3 s(f 4"+3$0oܵ,1^of6HJ4bj{mu(M kNgym>иv.ۍ" ] ?Acqכd><՗[F]*# J%8mP 1JYTyAo;ytΥ(+=б0DŽ]Iaj~s,Lm],\R;Lph%4N]w ]0 WZXz^r\Y y䮨⮫c|x >1ʾ;ŗY\!ˁR/y-:#Hi+e\jدݶkOAzoYaАmޣl9o-4K_-, t~e?~h &w_`:SS{6[ZhnGw ^ʮt.ڄ*3lVDYgJoW˾vwZB4bЪq L|AJ`R2g7u,3UHSmTXhN<4Z*U`)zeR (o@‚H"{,cOBz>VF0R ߸vVB< ij@9 VR|bLIا`V'FX/rh<3;V&Q{c$ZwtYU:ظczT;YɳVZڢF_-Hٻ0^[|||C<;c'حv5JkTxKFmH?[O HFhCD(hRՇOZ )i+pu3e% L-pQFMP C8  Qo>aTxyLrk}YF_>.k̓H5HS,lBѦk/Ek5 luj^[\M宔jQx\}G!C~17|KmQ>rdHtE=ikx¦~4r,4~е ):֣ fk,$2.9DP[q7(+cX PpqL%u~U/;7^[|uJ^̽ܨc$#^ um^hTX}v`ug.!D@ oJKl(VcQ8'a5|^=TG 3 ,}3 NƊ@QAFnѨZ[ GN a;Oe}Hr]Ƹ^)ט혻eü!e_']nzL4N0}jk*_ʻX/ DfƕNd ENUZ]KwLL]htkm]j;uRc:IKq{ABp2|k3RKj{}ld 7J׊I'PQE?xCxm}Ы=UnbcJ[GY55t(Ukg=fsF*iTǩL}0sdJ+}h]o }%?cA7(_aYکxG~gx½ͨ>+47rg2[ճ6&Ub]In p{'cHN2itESYkvS&##LxxI=oqʕATdЦ[9p Fr!D}3ˈQg䱒S)s2C$l /~MV殜82kSV0,dui̠ /,^%^{d!!nڊ.\֞z)u ې=J*I"`GE4*Sv֛^x LrfR#Mބ{wL֡ ı$GOy{Ͷ_5$=-^;A$Ռr"`X%у1q%B$&et7@ȈMwiDOhc; o?=P^.܉3viFGF#w]6•bs,'I?IKFX&{tW E"u-;f>@UsxxU 8WX*'ÒW,4#5-PەY%tkf6ycCý\:Ԋ~ jT<3 fJamEZw FfAXtHXUhN y$ge+2'IΊ'^rD|8¥> 9cg=Rڌz# e7Xb8e>^s,|̻aSqn #w?U-U/z9 t7{χ jD})[SK\}vO&p!/81\SJLfUSU0K0Tuu:w60cݜr+K=GV;d_Ɯ`cnW!&VhC0F3Qcy9 mm#T(Tf)_uRqhs~UYQ޿3 %Q;xc#e7eIw^o-t7wP5Zyk\- AbbܤL}Lשz,v沇(mSk⍩02G9c_F2~o7IV+yzh8"7rɭ"{$3zՈIT|] ҳ-wN@%^v$e97yϠ_*O8sf3K7S Op]QOeARߘXRZwdDKElۗ1x~~NtڙkQX2| =rn4u~ݵ4&DXFfH}sOtچ^^2(Jĩhnv#^o‘Hu}}`12!Q xëFԽruVHHT~^>O)8o*%p4 kNMu,YzƊt/;ጏ؛-JȂZ0}W:5!2OsӍ[^y]o{ޤ_\i4+dS+U-jsm񒞓6?:j}[w0o}rew kMs-:}{v jrxJB(]y,R,a 6"$ː{<{3"<4Kt;9zMO.f'<̷101:?PeCʏ졀6ڋ 7߄qbkmFHչ>|t؍ $h_Yt|Iդds$x)0?#^ʏ|TSNOhFB)t]/}is_kܷvNOЈg<4;* k4\<ݯyXL+_m{ {xe9l M8YIh3_/z3vz9#z(TG^o;*9*\yUTFܰxY_>dTI̺Ɠ7ooR$rHFGK hϓ®_ۑ#5Wuq˫&6wR/ pGPI+C"B xUp:۱^KJVhOZz]UϘˑpf4v7P#Y=lܘ#fV@جϺD"j=B;fs፨%2?l0Ckbjsۥ}!ߜ6q2/Y ڋ-1"30 ֨TM|o(;|نH@ˏev7/rnIr{:~(/ʘqN3{Aһ8)Nu)~0:0"05ew: 8ϊWm{<ʺ\>f=axoMeyrlc_ Y! XUdA~</1`~ׇ&k> /BΛ$)!/g`c-tyɪj5hTax[VE&lM+?|0('ciFQ:"|@3œVc%B_"Pox]L-!?8Ik8>>pny>A-p|\m/" e<C#( Uҁ|¦S h!Imv3r0aNSKI<>-,Uq|ٔsbP+HpU> uR]7n1tl|dm9)^ ԧ&1deji=Z u2bCASxj]lanKϻPSIR}h(P5;dJ6iUY:Dk^ʝc&|ӨQe04$jďF8*{ss7oCEj!S=[L9RړD#2 r*k8<> B˄6/¨)ݔs ;"T=zB( ލLy(ckWaWAJjΪ<ʅ getM9Nwئ0'T6JL޺hlFo)4b}OC05O8ə.°n0UX^T.SvYlyw"X SZ̘z]E~96,+UHry:C\=GJ/̲]7_"OM9^.pd91>??v{A!zt%2( j[\q ]ETCU2`,(Oiy1/7G."I=Dm4(kb?!sdj聺ͷ=RtS*1ajB :j/C n0My䧩^>xx(pjAm55ψ0ē?a9߄f[@sh%&A_ΌٚxeFJ%b~+N!"OeEȏR 1ө|<]62P@<>;)081(1B**rX7Vm8LPИ%ktN؇~68@]*<;DeBcj WF 1 ?1%DCWNfq Ft<+24b{u#χ_>jDl4y}~W\L^BdF_Jz!Z^~@3mG0x#2*YTa"y I'Ͻ[iC Į): p~r? x긛~SڨR8}B͈²#qA7ȰZц>8<>"WVcPY(@sť.Y)RbWh4J>?^ۜA3.Ž=C lеN?kX;0󣹩Rѐ2aZvHL~,c%f+Ʉ}+RŻ;I>>Ȭd/"4r?kU^B بfXdd * U^>KQ7*G 8t ] H- x̶NM>c@xox]_HD6f;' (3-ɝO/=Z໇Fox/˗ )ۉ%QpQ5q{} /s}NJX)ѐ0+E9|ʘ:eLS_/4zàҿ*w)u2!ڕk/!>|ڭFox+b_y=b;KךyVw^,oUHpDACDĤof; B#_>/sy-&Ly~+,+! <']RP>X-w0eJ"w b^wA "F `m Je QXFfCiOu.S vFQ|ѫnơB2Fác̈:u۰Rv\@]~/ł%VN.{^Ka *n<,=)\gu#mfi W|z?Unqv%^r1.Wrp /!:hXc!_f])52 ŦSq=ތxbzrxC+aVD!5"Uo.m=ksW ^@P8n qj0eC>Na]hሩo=(R>^/N&Iz 0' >H(I(PMhg u! V+c0 GLj;~{cn^V{{'hxٹ{ouuu8~VБ#4Kn]d \`Cl 7X$wقhAw ~h\^1*aEɀ$'U9- yYEо;U8z9 /IA QkH @;v{izmףDRԾ}^|ϗ̞=ul…>~')8@Sl[_yg"I]r &AR?&OSɛ6Gh )B嶊uϛG2IsH1:$8_FP^J/)XX $ H$Cy%:W~Ge{O3_W_8Yx u .8IQTYT?z?S/88ক+y"B1rRDRDz!b*s~ID9a+iJ 8%/ܒggGS 1Mko[TsxGɶ&J-_|>5}e^9Bk_ݾ-) >_:=j*&r  9Ï(( :(eP ? .hiwy[/㈘уذyĸis\ºڛTVf[g΃#&NodN+ȏ1q>֮TVR) ʖWu=qs\7wX '6ԠVx.O(xWKJF-vMcRq=.^bF+c)"5x`|7eye]kh[lʢ5% (AzEAQR@+4#Zo$Ү6=~Q4t?N Z tXĠ(kk.+Q@ۈ *Je p `li0a1 BgZ_=._{ly[+Hc=;lҰ%kzʧ}`EEyo1q:'3+y ۾|ޏ>Z}([^$gj7K2**9^-M 9$**Ʒ>3IoyYW1qpw^9eI~'VƤg_bŻTTyWa3bSpf}m̸х,2 C@!+,+D(t"- ,}J?&& R |WI3ť3rTS4pHG]Cm2b Ɯ4&=1;ɋ|KgmKI%@C@TAUD.K*ޤW[%^O+H(zX_ޔyfsX^¨N2|R'Ms௾j-(ϩI ?UOTl Q4ˋC^dNU ϻtJah @&0dU/or4PO?ȮwŽ_$,Is?_͛o8AltbFB;jhWsH{_ fM~/Oxz:nr" NH]è A3gt%!C$Y#)MMMcIf:=*sEfh0ejgurRR$f9-9-bgMb~b]uuIDI}ω ?|W:3Dqެϫ޳fd~?kOr(ʮuID"^yuώCӮJ'޶fԥwCDN'OܵO\s~]DhkΒ4(+>mpVw_Cj{u__ǎ^3:2axVd"DA@2н{EFGrȋuM-SS8N[+FUXekQ%"D^ZCќ\MwG P M(+j2ǏJIOL./YA͘>*!401fӟhiHNI*Y1N9MiXPdlcU:*-ڴeРT] ʽ%DtzZq톍].L`a8w4l*#r\,j]#3ʘm_}˺3fP({vƠʺĴyhڝnjkJ:OnXz3jK0,-+2\ ׃a4CKKKC?&z%ISRdT QvvԉB͖lA'$ P+6!."a^`c8p'( :IQ(c" P- oڴiW]uULLL} 4'y7RSnz+ٽrРTA~U` 6mZO6/w7d|駇kH̝²l(1Hr/XtE5mxAAAnApQK,X,K.=zUW]q~`Aꝱ{z5kրk XK`vUUU|5 +I\|J}Es @u'~d2 4(** T Eg8ǽ2+Z8^s@Wk9’F񫯾2eʓO> m뮻{o뭷LOWUn*A8۶֖丮7pef~?p}v!]|7mZK/rHzX2^?^66u7>}6Y>B/YhQg;~/j Z~wuvF|4S~~ \R^^jժy^}`ժR@ny@1?XKFGuuu`0(-KIt"&&$i$ =A*\QQw@)niiѱ|򊊊 NܼR}c2𒒒 FfgEɏG0 As~`'n{< /vadqܒѣGϙҮ :߿cǎ{ykT8< _vT`4|_ZZ9θ89 QT K1i6;XЩSF>HVap $wbcuw}SKK;|_rz}eeH }zzP ~'&N*&AP+++Z|` Q7(d4n,h끡l`Ӧ ?"I&#""gϞFfMCѥn+ `Ȃca=gD,(}A7@EšsvC7@DZՅ >Ej!-\P{{e,SWWs3*+ /]m6M@>djk6j$964#|_sͣ\s X'X\;<>䶲2## Nd!j,1ReYaha w,"PޢE& 5MV;t-\f+~uE|EUc_}u $W$7644>M7T__j~bb"byeTQ"|{х͡iёF٨WD?В~رo60cEE'0o %&&,Y A#Gid' U`{չ l)ޱcՅVQ뮛~(%˲'O^U"qpu7=ᓘt:k{\d>Xk>?3ZHM`ގo]~͊`3@\rrtc򔝝z)زjŊ҈wN3Xi0z<&M8lj>*61"N;bM&c֮ÿ$I}7h7W]uՀܹ3%%qmt Ā3L;0xXS/`0w{CqAHJJ+V,^Ų漼qAtvv655QsF+m8l=B OVWN7~90rȓr7}>o|5n`Un;yzȌ=M*bEGJ3r &e{ۭ[T F;PUs| {OJgTrРAQsh- hC>{`<m` ^VymR7j4{Cze` #ozwE.[t,o9R:Y7Mg9" ǥ^s^зtM >wI͇P `6=O---iiipSEE6(\{@c9x^'M&(&mFl`)6my 9)Nxdy靬PiN4?Fiy#N)O_z졊 Z[[{UCr|6EH\9E-ڟt?7# 1 #p8cbA)uVfY,-! NӉ_Hc OKe*-0$ϩ{l[P)!uvv"tkdamiBZʚC끺MM' {7 rj?VP,qz<zUsֶHup9]wA4fMլ2 DQ@op@#_UUXWFX*b0eKKK͛+ *vWhmm'S&L(JJJ4Xpx ѲBPПӧ9uttGXv[La?]:nJ^aS5fG$%ѣ`mȜlPS;1qBISϵ`$҉ϿW /dHe@gP#^, q. nj$kkkL?hH[[7E+|w`;8iMCޖVa,`1R%Y#Q\Uc?. m32`mVޟQ|>p .l=\],[|RZb\$ԓhdkzNk_1߽o^(Nw4Fee^^ҙlY *9\vm$W\Mn9?7VQHѣ1)5ӑDk1<\])i#R8ش")=#c&K˚F,ЄgC;6}GzzYA.h>UJu?k'H<*!m¸Q$=σB4v"T+P^p4~[w'E􅱦6;RTEjIxPDcը-;!.T4F~=Z|5ۣn#Z '$,z0⼂H*ʆ]l6Ԩ̾}{#:Nl,E=7ˊ惯/n,z{ WDV}][T\YߖlSgRjzDc3qb{/&jEn+1QbؾJB':p%X/9mnAr R/q7I%!i|]_lpX`YWyCrwi`DLE'h*,ƀEU$(Eb@;4,^koi߱u]{ase5 gwݑDj#(jjp Y&#$XnOovr%66+ȬFUYOB0=h7Yψ>:D'D8I5u.T'Doy:ϛZ[ㆨ`!K:LoKtU&`9[^%!1Vd9@k::th[{.(qu`8 _FG hLrhlhQq-9 $nQz;Z[4 (n ! $U7Y&)iLgS"l]L&"H0tT0H`z@ h*5G23@ ;ZعMJ[\.'jv~Vo\yl8=lO uY7_hhͮ޶)yqlZv# i8iBqCte_5<'޾n1}E@W;ׯ)8zDF|bᔩ 6ކ ц_!"@˼][6;=8yGY\RWd'0ۥ v³`Gٶ# i\zAaVBTЧJ9N-T}Ky[-/s ssKj\\tqʵm۞8f'wzթ3=D2K2O>OAlQo$c]q;K'HEN}Ș \ЈrtⷞynLЙ|ZQeBf\;-Uo|^jiSi6uޗ~GуOƭKvDex7U SnyՈGɏUW+WWptVƚ3箻0ޯ j[1V(11324g 8zpt$iRI4K/bqf$>2< 0XS#>q-wnxL4U=s^jK/~6?o/7tn'fȜ2=OS<%?n lg򑍴$ )>>*uAM5f\WarV *<\V捌z-H pI-OAH.9#B`[89ZzT]'%aICMAY>;0g'ۭ1le4n~_Ɖ8xos[{#ف;& fcYBnVlT$J0fJ5^xM I8i\ ckݥh`T]Z h޹oob|<Y]U퓌= *SS<`B|$!:H}[*hC=үu<$R&@𞫲bZ z#Z|4ݙ̜+Wu0(pd@s@LF%puXxd[[݇-={Ñ%8GM٩i7R=?_)Ҩ~!j|g~Ý?o^\{{|YaU28ނ/Ie;X0q+C n,ebKffb2r}SNGDbވwdf;4YlQ]KP\7Q@7lڸyĨInu󦒨@K;L?4Z;ItUJoF:Lپ$i3PP{S3%u]_+phQ$Ie@FETsɉlIJK͟8UuR3q>ܖ3hP\ CL&NMT !c\5UكtzEBTbJQjʌW^x6ky}]y1FB~kS/M+/ohxſqCd-G)(ZFT TDV@$10H"pIRBφ)OED`]E _zÎ\^;f'MNf;-V\Q bl`(O/~Oh_X i`pbTTTTWWgff5qQ̑ =[BTqm4HOQ4\#un|O7 =x?{xdhxj\g*8Iv[ь_ x{%R${r>cڣ͌0Bñ;,?>sΔaYmM0Jre+J,--t0b\ .,ސZQݮm/<0~! }(A&$*K(iCF}y=a\ +$ITUa<IȒxvd%N X; u"N^&B vd,ĸYY IAh"PF ywokLeIM*%QAi lA.R R<ljB$#2/,䴴4Ā@[C lUo}E SYhЁlzN9iAW xDfrng\tyPη1*"9W}Bڻsy5mάx3UaѮjy$%K]Qt^0xݒuO>^V|ľk6:vtT^=tpA{] #DD v9*Ӷgq3[:ېT 0 +ĹUqbKTtSyE$wAjI:2zR;fb4~ ǤOx_o'9?.=LؿYgwS϶7.0U|O\?wv~id]?YOUs=%ysї\w~4IZ0 詗}u[{2AV/$xr3P$E#xv%`.ʄ 2HʾEfrW}S[g,)QCGL0cT!M ƴַl^QӲG + Ĥf϶\z=DN[oV|ǟZuOjFϟ39[rnϽG.?H&g<(aN| l2 7s*$c w]4ףsPGL{ig#H~;Ű,+(Idǧge QTNŧreq}zNvVvޠv=%'?%-%3 %519- ;spѸ#3\]nk|jvUdGde;1pTw҄1EC|^)>)mܬ)QQ3.nތ15XTΝwޝmX.:`ˆNro2<=&5'95!5#kH~N눳>$Uzp267u9){DM:PO#zaQ5)A08RdY%7S]SkѲ.K<@BM`*3eDס NG2ȱ8` )We{a:^Gyϋ2脁%䛖DEU@QkQȳvGt̫(# '?999B@@@@@ 7۪PqF\V@AUDբcb 2qqqG~+f0Lڶʄf0 |nv-N~/{,yGӻCgY'[CC)e#w `N+@@@@@@@(n#Hh9@TDjy;ҡ 5hTf0ihJ463@#NB?f@@@@@@ ˍ( O\t+gNHFsp +Mh9+3xD$QPr# hJ~bbbs.24%K( Cˢ *\&||>"##@wH2ԧUdDOԮZxAr7v{"@w\%'$쵺& Cx^l8i4} -3)E<ǡ8I8sp#"(IsA #)uQ'WfwQ\Bpkk@J@ˢh>f0i5z{ݪ] &Gn5ʑmPdFY%h9H"P$ /i !úLEiR G(Oj@.[2ryv.+jdͥ=Nd.AQݽs{R0"8P$:(:GTq,$M@Q(^~梡^gvPɈBq[lcQmcgY$#0+`Rx$5P(-O ?ϟP \m LA?s8XQE` g {Z~M`Ay4Qɷ+} =e݃FOK:=~?KiWO,B_A18QWDzӺZk[l^A~p--'qc:5vxx㸧zGY)#WFi"{GI@l_MNn l.C$pDbWҍ3f9* B  śp #-90;cY <@pZG dN gB'+;!zŒ)p>\ 9qD/EȢwul(-><MS/Tn_|l[#3[6+즭%= s7.[ޞv.[p|_hψ7aH&P5*]FHPF}`W-3eD\oݰMr^da_hXa[bjܗo|Q4B(iAGQMs|Չ?LzV⥂1:n޻y݄GV,^r-*.m]cqLRaΝj 9Hd' v >uoE_x%ɇHƮWwv&%D,^)9)xӮɩe%m-KNSM}';bkJlS*q :4{G8۹oȸhÚorGeL"n/)i]|=1Ywُ fRذ?]iMjxl<Ef߭4'_Ic2#|<1/t#zז'''URc#)s֨ ddt?nsݴ)c:k]Sᖔ;6l?HJ‚ ji! 9u o{C5?_~ ˖1'nm}~=!Uv5|m-۱e/ϟ=Xӯ2u>)n9|/77}<ޮG{Mݦ떗9H].jLr׎=fUPURD~SK>ejh6dE8;^s=~e x>M~WϻnDCީ_=r .kxա3Əڽa` 0;wD٥Hh#!7 "un)=|Jkn*zUD 0 t|N|CT0ϲ "!z[r{,ھg-\`#U ;5Vf^~}ш\zFRbg8W')ǁM|colxޘ"r-קqÂ%Sb+l,ٻfSiv:chir[fb P羨;J߻FzUW_`dy)_7ml޷,I+]meUm.4/6VϦz'9d5y!(vpGqIE(Tݷ\ov]Wo>PxߢNR (JDri) UM7ݚ pOeX xj^"Spޘ9/ >2yBQ!Cf^` ut[ݽscųݪ\[hAOBu A,vNS6D&q˕*c/LOlH𫕂wXpv{ z%RKOQZKo5;5Np1LW&|`$I%" H7#$\\`h%)oiklSQDZ8p++3uMմsnY!&au\Eʂ&ȧ76>ۏɳm.x]Otݎ 70ӏ|fCʬ\8᧟luy\Ŝnkqt¼Դ(+ARm{ H*y8=܋UEvgR3Hͽ+޲egL}J2zRY5wiKЋ/o&n|Ť͛7_K <b͍^3v3h+urjr Iv{UL*w l=+Z:Hcra{/=#{gh[icLya?13Rzǝ]W]]ᬩ !+?Rلb^ R;'v3 ASf7o4 QmN5 fc\ްFF%57-f=:nt+_a uDGbd~q/?ԣ/G_KG' $F0sBr<(Qɲ,2[(=oK/?:{bJEZO/n}ucyߖ͛d W p[`8mr<-p8@Z,XhaYVp‚">/FҘ* jbyAA ~pGVܮ h*S0 "B=1Pdjx3y. h9%3*z<9ǚN#O~o@Q e`$lg/aDo}9zGW5>"y|Nǀw 'A1>(7nĢ $:pH>Ay,#d.ŃITkNq`0W 9%u:LVMMMfq < z9P<Ѹ8,I=c ǀ$`(n J'dbAьN;~=Y`돓x>|:!n,rɰOhooL@ۊxi4pIJk%ȳ3 KY^6zD:=)PL݀6epݺuhYYYo*ޫsD-c3*teQ& b9Q(b"' =2:w%q%ڈ8gWE>j~VַNO>};(DNzОOz\^.2: ,H9B@1=ew9ڻ EZ"$ÜʳhRz #r|1oimNw k{ qFh) -80}2K! c¨z巻Q6#CܲB0Ȳ킓Z)p۲kA" 5xg߯T&`OMr~y۟uMr:FAF[^T壃JSObdQy@,)g̉K Bx2js6s gP02nwN븍FyPb,p*O=R*Ky:%{zUG4:NJ*uuzUF{&xFD7r # <2TX94sVaU1Ⱦ׍nhP考`.OʗmV-3]Wq<~$wʵY'Gb;s)"t!-S_nh@;I$_O4^SI1&}0N>!bi- {sr%^5 +Fu~w:yYUWQq۬iX+ SGyQ= -}  ,&7SN$dcanFF Iw2ӪO37m#Rt|7M93˽"C9zAfvLGS/*zU 2t]#e(_[KRR+.4LʼnfXbL>&? y sE[[SXBUp :mde }(x1ga&XҠpkD&B~|| Q6!2BM|kTpփ\n3)BL` %$ N B&՚"*b χ^UDRBLĨBO8F. z YYN#L@SqM 1ŝ.9]KY"),F5-VO /&n*q|8/+B,h a)FT+ZRMyx" sCbv657L 燸:@Zf0A!lzB\bWImnCU0f\W6/ /]q Ώ1kbl wŻb411C$LfDԦzQ*PKX&asXUQnCod8-UIJ,xHJb>CD-QZGR kȰ$I6#^6ÆKi1Θ]%axB2Vۚc9}kZF[%dx,CH[` ؙŢ\ )Eƺ2fN!:dW 6xwX(,Fm#A -:ix1Qe( nagqaEyVaGcWx/֤0DsՂvW$IRZy$w*IVM`"6G"agMK@-t͔epIL acH[X*hH:2&KMY bir*szpYi+ L+xG`TY<lV4QO06~< mƁ$Nn S3gMxllˠ,?+ RW+E4aq7uPBZ|?O >t!RW1PĊ4.j2HEq0)B>HLqgGIQ  BX&!tcie<:lLsML6yMGxW70Ňy MͧElu ot-\߀;#PFBBþ=yt\CHؘGRaf&KDR'4el"m Ps  1Ï)l1G4#&!Y9\[WK\&v+5Зý>T, f1&D~y be?V6$ OOÎ >ʊ ޒ,Fxhz=\D̈gv XAD¬j}`gL-mf"(reĺ,6 srb^\z0ŏF1R۲2c\[O3\Gh-XFICog v: La!N2E/@Ԅ,ăe)Lidp hTSlDIL!_XeiDJ-j:MN海mݭiZ[[۔)S9/`8nҵ0y!Ym<0.EXED|m^!4`*Swi)I0l:|*Ce~Hr U܋?:U4#hAM^B}Y^?e3 frZU٥!1UERx8&-qO:k 6 zRJ n9,c¦34QbDs\wBP@ BJ4#,u&JYǚ|$f*ts}KCq\ĐG-4y+qx;^30f$.۷ d2oڴi͚5bf͸%"ˆmm؞Afj.$)d320X{8R9u Z$^тjK+I+&,MH=_>8xA[Q40="`}EwX?s#'$jd?7ٳW-ݥ uh> >xF]U2acԫ6L4{[-@/E$nA%pS3C E|s},R%m4ۿDn7ZƑ82s"xOlcu9Tg7wnx+y1~m. Q.|}3. `gM(1xi5 &7"[aw(L{'2>D8% @BQQv<6 lR"jQHZZme~$}S snlc"ΎvġGqп^ˮ zole yeS8hLa$SB=j#g5 p|gse# c['a~vF^ᵾ WΞ!fL\IDEdsu?Mu>8 in I׶f^Mzd~ sBf+EB!>%;|Yy9f.H4g,ݭph.X \ ~O"i5pC+. brLטe8ѤF9On[pfT2zW()#*H?揃pS;w'{;TPkL9J=GY*i6H忭Y_`IQ`Ufa B?7hc?󉮚,ohM)^( -!+Qλm`?R( - dJoaG>[,D>cs ~ĂX7N_2!f& ~|D]&fޞK-l v7DW?ITd7V# ?ȔB0cƌO%fch59ƃ|rPs{?7 Yz %z),&@aӏ>a%GTbP>*g* 5_e3}l(F&`Aw{83IX7x ޹*< c@'PhCx2͐Slߐp3Ju+q~_ m];"-R1iOaT~ͪkOa 8]ǽ$ "IDͱġ]w:nKl4NdRl-+ Gr$!X4ux ~sgTD.KU M9.,eNSeg&U?+8K*C  F* ShM$&SEt##aQ] (1ܘ"w8Rƿqu)~I=CO-2똃%4z~7BCp8{2߉BȔ@_Ճ"H7,'!^bmG*+ e9^Brs2ȢXgw;$|n/WŶ\%x 8?وDvoVbEʲMʮCn<An; R9szUYS&ungEIfyD*UByjԏA&>A$;Jo`v/ 1"9KA<[`ո,+¬c¸&yL#aiفA'M4C'(ӳYy t[8wA-M:O26`Y~R#)ܙbG}kQs<㴳q^72"Ϯe;u,}A6y, ?9)K1(LTnev}V-$45B6GR|$VeTU >Zb*H7% ƎdЇ? 1H4 9c&hjj?~#GG|s Bq$WëI%wKy9yA6L,艆٠LZa4|)ɝ ~:A$7id]Ȭa YC.%giAC?sLRj(Iat4/ MսͽyYt2Y$j$^E^hxBu!i&AA!a#/},7Ľ7`^,1"ޒG1'6dx^'&'0ҝtyIп`gFyyHƚ$T%.2OYLWAD=Z5F*0;5t8h똘=#گ Guv F{f9OsB3Oh_D40ryF%suo1aMZ iS/x nH31d㗱4tKKXL lO+Haҷz4ح6O[Ϗ3b& U,cpѢOY=Ơd~WIDKf 8> ){c晡Taٜ".">F:;-# &*]`I<'&PL{HqA&D Yh-HbYq=ӘDV<ev# pysDu&D1^AN:1POFy#Uy!(YՙBt^!z[E+OfΖ(IqICS03DN#%=Zg~{j8-A4!4Lg%HsRֈ,y\CZD4pp2$ePdN=Y(Um݅\/z=+}I"z^%DQgg ͏0`iIi8"($[@=euYB)ij B1GZqbAS9vv#/ q*-A Y9؈+>NKƹEͮTSM2\#4M$|Qbi]S8?C4F$D)hHŬ*x筊nAƑkbP$p" $Bv袽 ~7GgSx.[ ,h4bpݍl~ ^1bޒ3Y΃;}`ˇ87Δ^P7S q|>g?vU\Np8-J*\W0*)ىP!f NZ-"6NI$mgnhy_OeԓWUrMyClPnLprW+k[ޕ3qƵ]t9v7[b,[&F?I^$'|kuzUoĉ;)2ũ^9sx\O;Uw):U1 Pvasb㌈R9'}vlލx3?e]JnbNr {5-8;Hv>,V>eVmPsX5EZ#)K6gKlQ\̛Y.]:W@aFoFr#MlDq'sXoR^nvvCk,(po5klCs N:nZ]9hGNt򲝯 E8iGm$!#ڙ2H DM6ZN~#ԫ*#d9!麜q_Arc" `YSo q# Ȱiq#Z#5gǖVӨyUY'pXU-]#ӧe Itfַj >wGrEqBLj#D^GjF1[*֩dfw]}6fC5˻!{\E J9"2֮UKsnE8~vN?y&ofd?bOD >R!y[6[Z=8IW6C\Ϋ|GOW0OiW~įpk ӋVv O^5ީ2Y}IW7]·0ZBE99󞴅Z*+ι~wF|5-DTN @N?D'/Ͽ~s">*ӟ'Nr5,k-.e;4$mv]P4"'/;LgW*y,0? w|?UO0(mѺ+d=ɥPǿ/=C9FǧmVAzDŽs}NdpJa /znbvkLTI-[nE:׋AIeگMčut8K\Lo}b`Q~G1bӶ|(嶁y̆؃駻_M7sOG[O?.Ψ!t3+GK8!8l_ȟ ނ {KH%[Zⴵ6#d}'+Db}Ps"Kd9oq+#pgKB\*+a}%7Eָ䂿nE a'Hj >U`,ի &ʤU 4VOs% '#"J-)J;qStb 2,/6Ca\)q`tNa@}@QԘ`s'xy gDIQd ߬1Cu1%Kÿ֏.2Q ´ܪ0'(Ŀ}UγȠI$͢bDDUNCbv_e6b{J;IyWƋYZ 'e)LNVD=b[ƤW32%2PFQI"6J-TvVYԓF֎Xv2 A928^ݛ\R7CQ·`])~}klc؀eu>6i?ؚb4ǡ)̟`MOdYs{q{wr}0~*Ԁ *X9ŲK{*n }p)Q&Q)!l+V t>DŽ+ZsHBXW,ixu>S<pP pNxюԄӯiUZ<߰BsqTܼBF>ۛ/yjp=_労и(b97~/K 5T쌰3; :'ܹW 08PCc,,3tv$9$F& )'wW?=eU9ҹ &|SI8ǒ(q +b$˵-XHH\$ƕCr1{SdCSO_swd2&':zjw srHR>q5D.ޖB(#*)5^(D`bZ'xp 'ADtnLʫ&sv>%cb!EL`_&6aL`mQ}-ȗ>MZ,v TsYFWyW73-BfTB#`UƍXߏu%.2tCU.%G'DR0^–24*~/Oe7o1uC,@ȥ>6:M6Ms~zs6\FvP^P\aD\Rp'h]\-~骆Ov0=߲y*Sq(nhJ x}YQX1߉0~|Fצʲ:SC1 j\ҊpQ}uq m q-aKL:˜(1/\)tU >/e1{IC_v^\@UaDg1wcO L Bɘ;Wm`5*$]~\d~_eOA̲LZljJ6%f}ﰩp*Q"鐙#^2H>c^SKđg-^v90(XC:${\;Į`.XvtIv~ۇˉB'"MJ=X9Ιg򧎅žY*^Id.)W\` K©BCT h; AP1mpe|v. ؟QQX6py%J):Ey7v\¶P^v;|:#YKipC\&&a>Džf.n'Q!ʕ: :g|:3dX;D9q:+9Pa/eW8/ʇsn3>߈R\]혢=Î+_he1JؒRqq=ӕiqgiMC87]x R-~|k<&ǰXWnh@W xgST\rW40񌹻,o^,Θ$yv.]i<:$.2Iwϧti9p]6zAr(2O 8gU<_Wae}z,ļSFhB3_MwQp}e &KоwHq/ LX]0>ȕ>̧+s٢(5gH0pCGpwY6- 'Z+\CM| ʺ!,nE<O1 v,ԩB^C7HtҜ ak]h2֧(v]^4LZp+| c>Erj=z](f!fEf[3ũ[: +b4{JXЌ˽`k;!Y^ GMt-f (z)6# KAc$̼fMqQ4r0hKX@; L"ƖRoB^c?Nr@efAa@߽yvXB1(KM'cL0ĥm8eC\۩0N8"x,aSħum|zZ(amιY8tNkeG%fƛ8Tqj :UěN|9pjHT.گcaG|O>W61SMrI pGF&W`$MZ% h%zUqv#! bZvžy.R19d;36#_N{D2gzV`ڋW٧蹶3tv4z-\"$e>zj+:`u$q _Nֹr9s\qx"..WQGX(, _@3BjɑNwaj3cSH`ݤs. 1Q)IǏX)bm9!8KI:;H*TeN&ȃPQoXGe<Ƥ Mv,E+&l/='tjL9 x%:ZwїLIXtjqCkMEY__mFFIUq |uxٶ[)Դ4Fv>!jzN}"+j@k<$FTVcD0#=SEc7d8<0ĵ ݗT[C|*> 2jEnL-SH26Ej%՝JNX\uHtknlS݌ojmIlO aʧK6S; z.nҺ vmHB1D}p9Ѫ4nMbJuj-c=pD', r4ouS3g%>ahM;1O!*zu^"E։H8[x]% >.5$ ߉ȋfqjT;%5IpB8^.@݊Z]]'` ЪݢऺJzV)-vY FDPվ,|]*.+BClZt}Vk.g%&&KckUJ()]]6yg_!Ν܈+R NpbT<}?jmjy['1S+s᰷5y$Nųj'(%0E4,Jnv6ʵp&Vql85v»A^ӪVMw}ڠ)Bx'""檳VԪ%**vK" VҎ\#uYe,K󹕊&5jUk,H ]C{V f/YnR}G؈ uy+r ;L\eҜbҙد_$po/n/VuQs`;BL{1E,R8l$*,U+5:U8 jjU!G:0!J!B&ɝ%ZQi8IĒ+ nw1WO!oJ:uKz0B=:pq]:sy*~}쭬x3iި ^3O-}z玭\Qc'(=(t6ʵ2ʆ]N'S?-qAvN?}:v0 8I׹#x<厩KfjQ@LsH. Wg(_V~ʡ`P;gW+\ZpKBrWs}UٵGjHݸ;p0ւ1)z]ˆZ#{u'-jirO#J K*ȱ1{ŬqT1kuRs%ʢ.^hЖbaAS2U|K# Gyiq((tvV 7NNBRlV'LVW~5JlL2gMyzYY֦z ˺2)E:#eOƕ{¡oAg*0-ڋHbe֛vf^W¶}&73x"+#%)}}VުvH}i ȧKc\-^hs^Gkt.[K^^檃?IU58(/Yn" )nK"!6DթIh릡h}\qIg2]_߮kUtW-ƶf~)6Oܚ4"Cu:U6qۦA-׽u8i7$%XpZޒ}U;\< žK?kvKڷH@ʼn& (cc2ί`qs` Fvս̘m!l:N*RA m\ 7V"7 yOX/`E۔wʞcJnk@l;}x[&z.zg w&ۼ]F׶2;8_VҲJ {_9W>%'V8գx"l+]I^X%B kn^KX}kf$Kr6MKzվ"fpX0pa A}rS_0:m⑻* lKĪZykZ㱚fd];>}Ϩc, -b_ v4f6ܕܵ;EW$_BU5KqVqOvGg=l+Y3ݙ1DvùTqr_kJ:"؞0Da]МY3 E( r oY{$AdLڅbnӾyWhȿ,([ϬU$K+k7?k[h˞;cfrE N1+|dS,$iGc ŝ:.{|gAаC?hb&<VYtIN"GO[Ըj@yS_oHWZ쓷٣.L;+_f>X>E,=,~AgkbOy7"wXMK3ǛbϖqP*>%Z*gUAv>DJdJ9ڹZ;/oClnd[RqеMk]rѵ? $!.Qu[xW-A5>j"֩)DžM?7+0a 1,3e?];ĶKjmg74g㬖t nt*lznlyU.G0_T5η(Kڟ.BÄ*rӕ n8YKc!DGb# 2*e*^.MIVMGTάPFNˆʞa'uīS#Z Z+SMY;†Hm5~dbmz3 t)Wq}O@r/ƵSKx:onY9 =2zއܤms0J>w {ޏrp-6i}rZ`jW \yw'^Zo˰Fv>mJ_Vؿ5u#[iSxnUhãS{[yp腇 >7*;&_hh5ml)B՞5H䡁5?W6wuq㹃֘>a~>U9#5^ހE3/b3TI?|FoeI%:"dq%caǪܡ4¿JI!n{ 1IiZ?AŠae;T?{ټ?YvV)LPUK>[yOO{C\keb3+R:;yeI3Xw_pa Jǟ|483G|#gVrxt9[&(z+>?ۙMM [!TI~l>}Wj?OcR+_S*=UN?sj>+̦d_j^'KmɕDby(ιg3 ٿ-w\~YIg7Z <ҿqS[ 7/wՅÛ3{ -_K/K=toru_)-ڙ;20CjzvC|^%=d #Sgd^|ZEқLzoY~ORK>﾿۞?"gg7-oQ)!r 1iutXoBbWrMI{m4]9?*;r9,u=f6z9'~PT.(dWkh5/B_ 6 {y1 rR{h$%/D+C̾OגYsk1Ql3rh_T˺y6Ǝکb= 1l;#3OjC󥟴6e=^b~S=Pp/:ۜKp[7xgԾՅDx#)3W]\  yo<=*Lp.[m:2pjw$Ek`dE)ЀkԂ`rv`LT)mϧ ;_{ =KLHg益b{B7kQT,)<LMemOAn^hOlۜ}VH6+wC +RW$=76ߙX;Cj76S]x<#w3myȚijS1_+26}m==7lV`/_\wOֵb?JoDWOJylظD2^5\tW62ynjݖi?V8TY?57δ^YK1m'L\{{a-j㏩9~PNSz.}'vWX ;ԢZ{B n.'zz~p{KryoRYf <6C?s?wޗ;w+C(\W)ѓ;^\m̥Q@id够e<6Ф'>AخĶآsnTF?0vn~RjbUq 3׫2+P)}e6ݕ'/ʚꞡEˬ{嘆-?]]MG|F@f;SÏJW*w=LO2/쯊d|UKzt"7je?Lϊ_Z?f^i}C'-^moوwgv|/yG*yDm2V%{d>h`WxҌ{SS[}BJo*%^7k`/ &]\ߥtI5ߘT٪-U磗~=4Ib;1K4 Y}I*k{`wp̌:țv9瞮>ڿCIJpWІg8@1f+<#U0ֱx܍?+ﹷ\o\q+ae$lT:}mfmL()|߭1Q0i~ɲwf𢏶^Mmmʦޝ'|`!5Ȧ;K"܏S6VBι>9*,㗤 #f>.GG.CrPdfJ+k=8go[c]W_<! ^_# ۹]+2]8(bB%=L ]ԅvf-M?U(ms&~Y9oU 2a}x"ގ6>S02>AݘyQɓŴonej:zaTjzPIo윏njlo;WX9I-=-{E UȂ|M Ve0mm&|%0ez9L(9Emy7z:Dg_.j<ٸ̈́j1kL+CmJ /Ѣ(rcgccD \Bm0Rjxf_ R={vKʅ͒rV?B"+8$-%];DǨhoS9Fw4/~f١WL~S' R0mXGCeW4a{uPq"|\?/d^j"'_,y"2ix# >s q[$3_*GMn{ѶEK%Y12[U)4 +Y6&UAa*y!NKvâG&LW}]/t}\z;81M.<'>y#z2WZot4.ﱿ%.ZyߺL׵_Hh솯r9zT= 'r39)kRft.=fEz-UW:0?u;k*wh~D?V^qӠHF_٦k? JwghKiwpeoa[ɓJeVe]t<-eۚ'#=.r#}f'iz#3gKeڷ,T$(VD_rw~ڱ*F/*L z86*uWRBoΞrwDNq\[L??N7R0XʯsW0]QpDŽL R}% 2+;يdx/2mTi@!b$:V a~K|{ (]rH T6n/Մ)yr jkck<[pil]+O]m7>Byn1Jg1%{ՈBlS|WSbKz5aFM2r 1.r< ^. 챾w A:PO!hVvAa$~J뀛M>twrD!1>3@3Uꠄ>l:wb'O*c~ xƮ5A~0tcaBS S(ʕ"jJ$!*cQJK\ZPiW]rNaǛKوg`ə kҽz)JjjbFIE1Wi]E)-m{䒎C([JT5dD m捜򺤮ۂ^{c'SQNrv| 9 P)4"JjKN'zEk(J+M2d)ډ~&20ԅjI4MyH -f*7kj%mc$ kTUPeI rQe:.8>cGpbX* |5y\tGydLE*/F{:[gђyK64RKv2ں>M_Ah];cMWPm>7 ܽ[3RI8! 빨˧@eLͧPzY]9|q6hњO"CyBWiHS Wo| JсUC(q/ XJh|@d'fí~4]Ӗсjck @3J~'(0Y$K wv4z:&×e8wY~?\u Te E]_4,PB^H^pIad+saDl8I,$h埜 muXx#z+{lYF._nD~Q z0r<_Yx8T֣[)+)N|xh/pt5187U bx1,ACe1  >QEIv!< G1gE1oGAQ NZ)M7棗UcƊUE28tt QZlDv}m8Mo"jQaz.Ʒ7R[.0`016QB`6ȰpCP/Nso J0E[ 75@O!"vk8, htsq  %>svKw,.S[3eey&ɴUG\jXpT"![Jjޢ%Rapec J4Ҹ̊OżӖ>ީ9t~U:,a__$i*6nzdl0wy 敃6n* <\91.z(q^M` yb,XpB\,UA,A1Ac*^+Nv񺳙X൦d|Q>tѕs}gϷMAXI g> U ^Y҃)nY|?uD(}wOdkշ.unTqu "{ H!ެ6]*Ljƪ /ܹ yowv#< K2E! =7OsV@U|0\ȳ`.RMàM"$bDض6ySEe><@ϛ.kʾyCDRųO/BޝuY2\  5 \0MF.!VNr$7"C9.DA5mKIWӥL$QZO9mCyFU9O5y"GQH KP h̑Ddb"QM7=WPz|lx14*Ϝ9Wc'cvڷ6^fwbsj#AB(WM,iUt&(dfEa 0~<66Q.dRD(1FQc|ZH =LsANQ %2'/-T]-.Bѿm| FKgd#`xP^;u 9ޞꀘb/Fn!F]5T@2[d37Tt -32Pw5!JǤJd. AfsR:g_Fd_BnE9SRfi`Xl0\*aX*xQ@>$^{=9?e>1(4aZȈU̔'Q@6ijv`#8OU! }"3\U- ILIoSRcَl2ŝn X <= |>:>nR>03m#3cKO>o|7WZi>EU=Wa!v{f:6~*f↦{#mܵ2ߵ~h* G"J._c(;7UӆjO B\S| ?A;\>{{'vfZzI$>\{[%-K MुC~jJ6i _c47gc|! RϵYRL $Z6F9/% hBJ8|10o ·{n9܆㞍z.}ϡ,Pr]VDŸܕFMVAh~*?a**/h|X>=Ty€2‚d[E!{͐bjQA#{֛`r=(63Na|.q\dMȊ\Vxipd>e@|&BteصMt5m=5h5= ̠*GSRNt'5lo'\أ)Xyd땡MOWN]D'fsm{low /7ϷwА -sSMۚ(G\W=K$1'2JSYjR&ľv)h?꟤tTM-*yPe%)@Mg[f쁒kZ&&N{$}ŇCwR4wĜX+t>ah!d5 ouQ<ԪlQ+AV}&4<{grC7SuHCCk~% }-)RjdP6e.Avrw//;rMhɓm|i`${PzXFm|SOߙlRczn`ެs;ߠ-)=1#$b[W|W8(eUSPiVl>y'س c}q^U Z _9b|uGTtyMMRwҼ/zfBs}u+34\춟)X C?x- 7-qtO߀tz$2op naBAn&7܋\%FUuS^XsNRV*z;պgbM-۷gBn]S-y/jn6>k+5?fgyДt鱓{xwTNb͎[T+DdOöjU、\Õ5 kMk)'w>G]/JB:\Xߟm}?*GM H+vTĨ>{=כ=P|?Exݾ|MNv:/Y_(ORKe\,IcfV|{g'dA ְbנ\N}D}G7=]ԦUdbS{LJ:pgz>QqWo{lp5moc2!_J˧0wC$Yܰo49obWJ@TŲon9p_w](qb'Jpj:9]u!~GS Ws-{f?S-?f\aS9p^x1u>s "EC+%-%hB"IA]ئ3w={SO8C1kX@W܉wtc܄~*f{]߻.cB_B=euz>fCN_Jh?[Rj|(̣dn(Ȣ 7`V1g3ڈ!誮"[5_BH:$K!'q6sTk#YYr}C\eJt.ʩBy ^&D7?=~.$ Ƌu(k0MMK5L5m|ӝ joNxwRjM2غK%~MZ6a6*8[?I1mlrwΕEkwJpok|a!@ԁUqB=}`8 ;w 1r\'+-s%]:Y5rh/qX!Ф̺vU {;6O|!5p̺.6=0b>_pTϻdҴBL3M7t: Ym74%3k=Af5C+3ݞ xuйKyFHzDU9ڡ䄒+h,:&GڥX7Žcprb|E6\3>~lx(pv1iu5W=T`cDRb6[5*i!lʹe_zD(QGkbb>Z'WډlAaJCY/QLp([р1]5"lA& ETx$\[ܣc~ǸiJMA|6|nas#4 G]NG@AGq zELo~{B=ՑOg{ʥ gURl\>KTzM!] +}6^)~cY3>O!E^EDr &v;|la7eФn'LpHt k,s_Eܳ| Ah_n)[9zp;Y2 RU̲ U%h&I$ Fp8F.L@ _auN35U1YT3c~҅Hl+ѥbU̯.NB &/|1l,;;)[q섕bVIVH}7:ӯd/<{)h w{Rool875SP벣SHC.8,FIw5i\Iz̞P Tߴ 0Z܅S#PZfYx9ifoO!J*( J@`T1 y$LMPEgtZ+9>S,Һ)+a!ݴmma|x37Zf-lw:R)&MV 2О.4Dt8 u-ALKf^`7η$ ̱ wE'a7iI#ۇYlز:ʱsL1wkVl7;ޣxe C/ 7ә;]0R9_gAl hbg,gPBI'Y\Aߊ02ҏ V9H #"&LɳdgjB,an U5+Om?v2na)|(^AC_ &MWI>jv Ög~eP\ op]dS /kAw)S_G7_bXP,$Wz1~m$PN+[X՚ ΞBF? =MDbsh؍XźdN5ؾy?uBl27Ћ5qVA2q۞&.*xQrDAbtaUM,tM%*Y T/wP){v( L>;8ؼ?ϲ{2F? (M?r _{$u|Urb2ΕF^QLf"4#o6.s|YrR#Eg ZrQZ)kɍn?se>܅#Xu;3qFA(Ka% 0x1JGeUpndk|:b7_ HfV2 PُpxXe"a#[1_Nmо鐼;^dS&goyDu{3q */\LPYрQ ]d,0' :,+Qb MNA)JϦQd-l-]?EV˞s< Qp;6pL]i^{~MaT<f?f0H]TIqeCLteY6&ytJKv9#ss/InbfԶ~ \1clI# >FDe7mSh2'ag+H%f{_UH[N{5LT(o'k%&C8/qr2Y[ ;Ai|AV6ӺߠJyAn #?'b&\'w-\HڨsS1UJeZ .>"SW&eUخlC$ux"b U ozuOKao; evx`aƆǷ#+n#ifH806 p** 'M4;Śp?2AEs?L٠RWaA jm"ҙnm5ť,L<ë1Ħ~) &wܙOcpjpU9[kDfe6w+?M7C6le7? ؐp莞ݽ\_8D^l!>(˿5Ӳܴ`0;/=/cIOFw> G7=:\lSQ;[Sl,㑝/x{;[= ˩wEoKǟ7y =~1f:zi':)|Ϲi`Hz4_E>S H&H:mkWPP=/`7>Tv9MSOT1\mqTg<w2&Uw?.ߜliHh]7O|g˂vSY=k_bJw Y͵|SHqVI |+ 푵'T_ǿ^SqMYsm?)ВNLG|tx[ܔ-WHl=/cEJ}Rsyb]z8 gNP(On{Iˇc[ (Ommn:8v>b/懄Hz(ub,; m vY] )@1jnb_X쉽xEڪB2!g{ߓuW49L$:W2͵5sYuBBa\+#[ B 1#jLcƇļyA) ̞@|9bTO֯b]ܵ]H;( PSZ~\U's<0me~SjG'#l`Bb#;Wzx{oC;H 1ݿW$w)ҸO3b D {id-|L볍wGKfQ6 ]TUzK5,E+1aY8t^Ss)mnA:&&4Ƹ*HWNb lRNs"c7=7ޥj1T>CJ@2TUBV61T¡Mr5fn- ageOD>3d=܉͛t ]?9Rl߲MOlv=CW'>@ڹŌ"u@,ۧ @}KݵэO,fi㛟 'u|SIܮ9yΟZ4m-]_ZV27vh__ڜeݪ?Ntg|$ײ,wڧ gqK'nQ:Iu`$jH"6P{53u1|ر\fꮹ)&?8~?Z{.ᒋGiTJo?5uhp 8D=jʩ"B=3gVR[Lt$vJ6spݝ85>; G9p vλs)Q7QO%7ewL[+9!qY᨝g~Mhkc!E_WvZ o:h]K+~bwk@e55+z!qԽʋf\˸2A/>r 3Y7mPGkR$C[-]~ ?~@JqhzMEvo͒^} j1iyj x[/噵ԐꮇHu5:.Jj CzbTvLF-fn]Aq782AYK.>s]BĞ ғ)wO P  HHjk5mU7>DЖc-T;pgbsܬ9'OG1Ckxy"d:nݧ%ҋoLnyXNt%K[)$D=A0S%f'xxw="0z<ڡgP1\|ce`8*$3ٱ޵'qk?k9$4?@m\|jیjK2Z4>U'c$z;GRBf:}ڢƂ\;He쑐CSj5{1g#0 @)8s13]l X g|LDU>C$סP|a z6</1Tͱ+eK>AnxNw~FeAAG!K`@7P[9S;lRyI_ꯠl.Ea$f Wp:+H-+YEV5ek)"@V܊DW|.8_L(I[#(pAv6iwUr>LM_'()_T'2. p;&'9BᓸO`4 UBn5\$@0-*&$ MZ8 joM53\Aו̚>iM/a>"M`]H#* b*g L>FKD[R%ޢ/A*<~ȱó(BS6&5l(9 ),i­ѕ0e0 e R%T5yш1!;t9y4)vDi>}/ުʂ蚂.\JVbvj8&-) yN*'ZCMD8MC }Q>n>? h|\ЊߊGډLu@t@&nC%(6/.3wt 3ˌJ( 9ꪈˎ³'J ]#o  3L6@e\ 7**#wUzo$:i^]멎>J2mesTj6eǸenoY0@NK!2b۫{lۂkyl\]{Yr̬QwjZ{2s ݁];]s0hАqvHts#e&^㞶0WPk^q>ypGrȲ9u;8u[2:0,d 8#K'g=꘳gBNrOb,Jڥ`%۬C,:`y>(1T]r\S=l[ዦCQ띴 {LNgء#x6(n')-!Q7pdľ#@UF̑k68Y2 gԱG 1J״Ÿx_'9&/zV<|(6L}MVݯшH' -~xp۳)"};aN-+*\\%H|0~晚·oBΠ9: d=ͪB4n?܈{&nG7OL$ڝt[8+W#':}^=UY߹؂mGtk}/O?y8(s5}15`τDp1UVDH[f@I'wxn0Ti-t_Z,ܩGٻŽ Yc?Z;gɯ<O}}ߣ6Ϭ@H d`jBFD 1G{/BuR"w p2dM/?pG?Xw@2z. L&^NrLY쨭[м7$E=Z[3L_sWՏ TԸivvgrmXרo9HVZR͏1n(7u1d11RO.m>dI]>O\qq٦mjb eZ=d;ZM]~=1rLj oxL'!I CM(8'n|rV1і!z>4kGfbrKBK꩎rW?x/ч`  uGMy_DISܛ:6~ΕP]Ov=[hh2Bg=ϣ2])v=yc'(%{g@RmBo yyYbD-+++ȤR)I0!ԤݾWyQY&pTWE6,z啎I(Eد 0ܽnQPX UTT>N>ꢙ$&Xkj6DLŔ6'f3լl'3`Ha\=(^@:RMR?:HK-ءU >-uHF`zysl$ihJdbpTt'Ƥ5Ymf~&dM1౭FH\rP$鲀=kqf($C>PvhHA&^WHX.a5S*ݠfs82ppTPRTW+H*n&LSzS,r66`z5HI6&dM$KBBtB3ƽwJUb;$۲ '4w-9swX#QbXb)M!E_Eəu]8R<l&wp)vȅb[V\?^!B۹,pϻQZRDap]?.[exxɬ>ouLqgd:;fޥݗD8dEȥ5ֻN&Al*.7"+"piQJy^5Vl\R>3izlnyqO%gpEXGF#cvj'GyI XPj1xe1{;F:|gVeœ,n=\wfUE\u@gS=( CÃ8UC12D]S+\pyWqFɈk ЦkXHU.B`fp<3ט_)WeX|Ҵ쪌$I2Z8z \n"*`jSG M-~5>1" ?I NAr(.3@/ϻ~/]~#lrÝ_EV4j£ee@\2ȄDiɡŒZ}$.؂7xsD1 XXve~ϣt~E@-8թפ}q1`EJ%.`%H“!Caצ ^{N~_G Ŷ!RT.1a`KCc%6 f.^<~G}9 [AНK:«n*FGu&IakJfr z#_#2`PEa<[،50 Yp"zmYP}Isk,hڦ^C=< ͨw (wEd>7=z_ff|xS -4Z[?Vn*1'ao,$#򉯇kFv32(PFl'ndo6ͿA 02?aـnþq.Ωʘ!(̀$, j#|#1)aJΊ0R_X@]>FQNLzCrUb$d]z0s /m KQyD骫-/Ď?+kY^rG_FY *wSe i&(L$(YhiuwG61nl*9,۟/_̦i/hdM&60ytpӀo.l*X!͓#G#F+Z!=/rM8_W 4*YBR@:'z`;-3MYR6.z 4*؇'{]͵mNw 9N;UWIֵ>Iu= fg6Ikf5s->rgJ!ܥ@4\4@B 6ۼSK<5fh3==tRGtz@&0+(kQB1VNA}Ѹ@ą_ VwLM].6o<)k:['i+ a+kH*3i{ -MMP)q#o,@G, `Dcr`S:`@-q8\ o8f݁F4Z=g (/BM)lWm09Ρ%󢏱)b6V9i+v ] ͂'YMz߁J4M+>x]%,} ql8ᙷ&x\?W/­. !'yaRۉ^6.ʒN%)ٟ;b)o-j>iۋǣb$qm,!VpB^8؁ڼR_aɆ > ԑ7d 1܉9ܩoH"CyRƅSTI }='jb=(5~wzkpw`*tSHY4 B1ق]Co}K(u_MJ' ͯ .IOkyK#tOd*1:dfz)'#oPSu;#WloKS#E{r=5-uH 0$}/T#PA7Mjx؛԰bdAh"F\BJ|Q2 r(5d^3#\` ۓuDl~5՝iۍ0NxKObE}Er|;F{rQHCQ2s'r}]'D5.' }ZOw9u!|klW撈v:4s~6]Ldr b/:f܁[ǧڒmqG8h9BOBunc[$8Ԓ;ل`,. vN]k\ZI4ԇjrE048MPG49W8ƛ aX;[Mܦ+k@kGgR젬sius.)Z~ĦLgRR) fL]!jɴnR}@_ Eط6nLIeNk*}OQUAЗGSV3SnUC{߲6Pb]d[7rZ֭FVh{~`˳tb%r,ٸEw$YTUi}@Whzzza<`0όh:}m>cMnt/_E։xބ7C͝j).H?+Hh]H0O\S,CW/Y|Sq\tNYt5BpDq XNL㈻`%[myK>6^|OA |JhO=sn{N`i>" I{b3 9k +U܎E5C~Hω5w_ChӓY2ZbMz",+B[u_績zRoCk_;ׂ0 :聣Y{!s ;T߈@V,˺S"xrCD&7{ˏ\b(D3E6ȆBҟM%n}lX,@I6?D ؤ2Zn&D#!9s#V`6/PZnk&"u+S.t{bC;E^h%-:ZL+Z6=st+BZo7zuqُ={w㛙;z.KQ?eYzsHrS]Mn|r*" _Ԫ>kZ?:rxp=ru߭+26w>xwV?("T\1񉝿|)v%`f ImRA+HR5UoFSsGs O)9)|7}45J?bcȵ%n'dWb7IU,>Z~H=غeU\_0{%w\_vXDue,1=(a&KBl_tlw药W@Wek'2l(wm]6@|N@H~O=?Ðv[Lf<3ےqdH'.G ֲbϼ"so %Ʈd[s?_z͗l?35ƅ`:4럶%6Q2ӽV9|7q)" I)-ӊQy e%w>TQ.ܯd,e}mQL3>[~C0; g,R 'Ux T_]ELmߤH1ڥr%[~$ÞlɆz҉V3(Q* Cb}?*2h\SUe)%0并 Rf8( ,F95Q}=e7EPO%^SMi-5+n 9M"%G"lKd7k+opୟqɴjxQ6ɀwecb >]~?iٮ fW}ͪ|jM Uџ!B2n'F .Ee+E#j5x_GePXyw]6l"UT6J0AV9^3 tr>e6MzܳW Jug;( I_WzH,){|- EetxyPɝؕt6u9AsΑ>IJz ն7۶VJݿf&[s6=UYbo[ gx&v ~Wo{, #ßk]ϙAI㦺խθ⨵׾ĥUKqBT)*,n)l=lСCΚickKR뿍yo"(Z:me\T"HN1\l}Auh?jt iu@Ub6jک+ɍk1PeQ;x&9nDAS]ߓiil^1کDuOs%սyh2Sn-BʨΊW ۤZ\6>6B3;Џ5/⬵4E♞-CkPeT^A.vd&eD돮ytu5YKr$H+m\}ɸ|ʷTt`2#k2~Jb`!}V] ٔhZ+;6*ŝ%cYY9A7+ojQv5p)/pVk@4♀qO^{ 1 !$cD6>tUEDlSn5"$F OGPQҞIj,ݼT o!'!&Hk~1zB&Z(AC\/ܱ^TƷ.9t UZmc;h~iGQRuk[$YɅyG:<X L׆6bqxr"=/^ڜi9UiQ% _y_YgctDqޠWﱽKLZ9e@jz1Gr-َyf\fSJX#AVE ?F}ǣşurǸIo1.eJPhu1D[y>嚵O0SnsOJfn~*[rL㎷0kmMɵjO?<Ȓ9.{mx"`f]~?*45 +,eURF{/ڤH/lnUͱVd:i.OlSIuҍޙue!`N 8˧ t̼f GW;ZJkx%n euxKqW%魱.'@RLg)$  ] pg%DpLw [z[⩞a匧tc (&/#Etp:(+ *鞽r-P ũOZJJJ>܉*(7P|5,\ńg|X븹tp.q[j xYق\!fҝIdR;ɢwfEQ1# O2Z W81pӁۯifrIHZ9K˥-RjW 9y,% ^H05WYr |e<h,blH_>%, گKJ%d8K`x]x*6r'v~-^[qP_]a]eI722K<-)x%U8LQ+.xn p9OQ%Hw)fqʧv@8j!J^JW+>U0hrѽV_3I+5әEy̱^׼TWg-tpe0uz%|K?fr] DdϢOvv2c,: 2:P8B]EF{]5!|hp7E,UE=лفy[h}u_vlNȨo5XA]2Uv=X"&bT\?PM:"*9N6< ʮ`>O1)#.A2dăSB ީʅmםȻ_GA>=NZ>D ã j_w8Y{k.״% .Y]=LL?ȌьC;2^4=sǶgN6D0x%0CNx}h\C( / H2 |B+9Fȃ{ü81``ҜEBX+i GĜl4A(?Z>@ > D9P G({MF*i$KWbZG^sRaJ󒔊஠IG g46R> vj<i 7|#55Q@h;<[ '/jK^nH!NBe 04Y)#r0 Mc <Ό~G|8ު`ǀь4&s~)#Σ4fuxY"6u<7F;Z:(l_ 4\2Jd8[Ld.z @( " 9."aC<2K"8Мm Œ_[Hb4!+'ʱnIl\TG=BX >`͠!OY0z:a6b=eJ!gTYnFFGLRkpꟴyE_`$ 8"=gGbB sk( DzK#v!cCS?BXU'\~0戀BW2)]r֮>iBazLZE{hjR3dC HO (@a^ f:"0wdz){ʥG(ح"t xpƦrIp eld漅t5Ic}…ߍj.&s*EL٠i Ӕ\u1TSd6שvUrjH(DB)]c! J{TbMF"8v_$F d .c}N9xF ;&F{qg X5UwA(0cD:*޺b**2i.됝9ȉ!KD>qdSϓ5V tA.ҥ$t ݁?5c8WRm{O#\A1ԑ?ޛf֗}C!j6^x۩DYNL?;Wg(smt>B_b]˘oz\ZUQ+^U+ :eaۨCp X^:j\b}]txo3@ɪ lǾg&1֒N<d"#S6c*/+z}ʹmxj_QD}OQz9 7CQ3q>$:{UQE3MkƾSC6@6nmyp~s4ЪT40ܽ~}]__X?F6ߝ{$r+RsGɢjP; ;P1%F3 m}\yϪ9iXӲx\*c]o|˱=/%O+}TWwg:=v=ƃC7ytjS=φ7OEnyg`w2Yw|& ~ >?ɡq݇2^W僘JD~g|FS|-kx6z B _l?=}<RX5EV1hB} X(*1b |)B.RMxg簩ѭXk\(sϧ798@+ٖ:Ru/*.!Y28+-#Vaa dU}ͩΈ4?gsz_&|)蚾H$hjR7 >.èmqJ׼ccɎ׼[m킮v;=55=v;C&۪HmIW1g.JZ.޼{|h:M\R+96l)D 8ȱ?*H x緳;kyOG~uk,ŚuRdˢqwE0Dt`B( ` `5InUM?sYwJoNd;\U=W}KlKEo'G\usгbF,* Th?./? S|XJ뿔iw浨 c;u [?b%w _NE2e_dWVό%_D#e>Y+Gdcپ`*wJX=I!İDBMuX}l|ϼ_84b5Ɇ׀k~Ϥ6|';)< yP-a62cpsdOLm_!iRKtɧm/u0E_&ܓjȒZq&۷Ŭ+n \O*oF\%!)Rn\4Xm?叨.Ⱥ5ӹ \_t[t̓RVrw(lj -:p,ou#t w uWqh2K))pOJDzr/~}ݗ'~Q; wOId)zg.3.Z=* WЃh\ÞkjO="eYfֿO.\1‚wBp^BnjOJiwlԛ9)DE\΄e‡[Oh$껡GM\ծ +?\"nͿUn{8Q4x'3QR2 "oEWʘ@0(-Ʒ mGIP #-p cl$mh;ȥ\Gd9ǓL1JҘ>Q%0\KIPLjytr-cո!])# ]dM$I@lv(2l­3鶓*;ȑdw|gv&t ][ +Ydza@GɆmښet?bdh-+x>h&Riu.̛8T$;,Ӿ_/lUt͒l%'lK.%KkڻUdJPÎ3rQotm'2 *mǒRz}ܓ;^o8O\+~5Ǖ? B׎\(`R9]Ĝ*YJ'+\\IEg&-Uߙ#*ƖLov]ԎWUSW *huNz_uu8'թn5+xBD&'^/}llt=F35-`*Y28F34UBH.&POagþW;7 .=~Ϣh JKySlv|UTZ6nyd;pg 4Ե&z5)Qc#e/jBmY(ZMSg;ћ$G,A(rKi%ÊH~1w';IFHws<RGDj">M%J˿v%kch)Rfʰ&§UYd ή5;܍eT!p+mE\vCkBhE5THgZ2=g*'԰(ʑؔCWND2nFFzoߛRF1 3f=/+@|2l&. vH"”y\3Č[RT 50*ktpiwu_ +1gu֗%qٽWbSHgӍ4X6rGwn=/xh׋dōś"Ij3>iQ$s,=;'̒%޳2y֭i{UɃkd+3a9eepubv+᭑C[b[d_w>CIw(8 BLeۿ.qMCǁͫk`ˋ00^+jDl5Lɶ[k{:*QSw+- +N i;!=CvD%3_YeQcrq*jn PW7l#`TDeHkxCT,9rGWqcH>b8R6ϼe̾IItQMK8˯KlYUs[* O*x0xۿrOh|:6[%)aINqgILIuag }-3H Y,nc?л.L]?$o>'C\rTFpYAp3h1.ռ GiO,LyF!Ae ܜ9hdXpiM{6DlY5vThr,IC7}L1a츊(o9f![Q6m}1Ied`6OT.)+| rSEr&A:JP#T!yHV=yuzk<1'P {^D=T-QQd^td*ny;T5(]Xt٭b߾L!+&a<Ф}{@;.zK?osJ=OfۛiqOG sMJ6x5׭dO*c1x6`D~=Xଚd(9Vi\fLM2ݰ IM'r,RCL5^lAΌ6~L&4\ c3)J-D|r>,Dj|0DT+͉#SA4vئ:\E& \F‹(EmBV@IWWg}Cp,ϒiӤԔBLo9JjhNk?'kgq<~5'^5E镤6>Tf,5/Bss*/}W3^j`HtS7dEW *oZ*l.*|l?R.LTB3jr=#_AFg+43g>[>S$?[z!ps7lSwԔQGGbVf|Wy̥rz 7kq lDGȢ!<ۯ1@^D`"kXBLUAdp ?rBHgcFOu>}Al>H/:A), R*ئg89FMXQ M;mteK:p_u7 Ha_@xhChy$Aǒg0'R8kʃ- ˕eA8]8ss7~>swts 1>j!Yywqӫ2: ` 7gt>/oar_ @Hx+-3]^3 M2,LiYY ˌz6knb4g_X| %gQr4Q`ɧ IE"_-X/ܜ-?pW A=/0M]TeL|836(D0᱀?EГ ݼ`k}+2ݏb'$_{2@sKEZׅ͜pSCvKRTΛ9]Y <4%]u3˜8l cp!ae#wѵ ~/l/B^@LdNʘꭏ٣0q+A{zM 40}u9 `&m] %. WU׋?{/r^͓{ !geopowGg#,LK\Úl\܏PwyVR ڕA- 3\6X%[kp:JyPflWNQ@ ,,!hÙ/ IRqWe ]_*%w2av GD]Da)W/Nt.«'ܡU2S%4cay@=;ʮw7e>n+)(`䎽y~=i:ޚafLly:Sǘ]0] ԂqߖS]+nmJr}&"i05X/KY&LH,Ed܍ lĚegiTyajaEN~)oZ״)^PQ͆ 두MX5z?u^D)Ԧ~c=fe|EՏWKͿӒGB J")!͢Z8պ a}K>NZIK]WȭE18*^rkL_/장S{Ӳ/ iѳj  ^͜i&R U۟fjI>ג}G F$7u,}eAp0@rZeY&&>:IV\}m@iʯ"IKʇ6zW׽oyO&-5ҤwGWdI k"hC8!Lbx07"0Ŋ@Guh%a[1fS}Cn|䃱ly3$ Vu}v%=66@ 聽9K-:BpO Tv/!ldJk׸X>{t2F#p _/K*p-[^BSMnPgB )U}1VlcF)tpe|dip-nڸ؉\O;U2(۰WeMuP^@˅=㔿2ײw 'kjǔF:ŭ%ȡn7T__yh.5L%ЮM`Qc+l?ix#v`%=#ًG6/rI'1!ٖ9YrWK= BpeMACŶk󔌖.۶)zwbZ\(ם/Zz%-o'USc'#^}3\n}4ajDajꬪʧ\rJlCdE 4{{ umzF4D+iC9hQRKK5{93~>>[y5J2n tWFszv%8Uɣ9%=L[kV1 5g-G'ak|U!\azUuc(k,&i9ك( nzw@U΀ǜExj4ԯ4Q\S\o^|k,⮠o rxB;hB?Pls/J^x#4ܩ((W[W%>$~ߩ֍]Ojr6qxӲd[1inaڞTȣg}#srM'b%޿ r"Y_sHtd&gbUlԿ}g-5Pmp̸)L_VD梃}\0}XG>l[.7*_KutP65*eKrl=+cH%Ϫa\{3#58{7K}83&RKY0淈o*d zC=g(~Tk 9]mw~ SJ葝B[f L n\WZd{Qߙ]n[{rI@R. R%!.$iޫ"V]ZmߝeBqrN;}O<۵󕾳u<-@-9pWԭl9qChw[8QzFMO#b~uߩ5}N,u _{dnO|ss2?:bLs* 2'dyNyAi>9ul|9)-URiѣ5TK +tI'>ۗ%uj|)*kh)8LJڔIzMc^)߷fd&LF望s]{H;IS7˽{y!}yhu϶_=;v$h E 3Yrv8]xyjkj, Yފޮ Q$O6(5`5\d YStj{2_Tm;6.wBlU zO ±x[SNhd %ឣ{^D.m]V zeb$!ۜ#D E`.гklK[DZ'dv$Cȿ4yIc3"԰!ulՠuW%Eق#(7[sd?Pö+~gf.(m⸉7ht qr7\e+npӡ^h7|5XK[WXɜ`INaMf]kiĩp:f> 8POYwIpbsdI6g'&μ9鱔ܖ4.0.P`CL!K?k魶CJT냰E?=al6X -4[g̔d!?'!gA&½g5gÅdkE k ƕ]o$$ *ZLtrMG%L\ w#!)k!&AeLISX0=q;l^Rɭ̘amӽU52R>51zg-+[p@%iЫZB._ꮣ37?ռ=}XWڐ3MRh;J!X{мc -)+:{l$ClI"LqJ=Z{zn']duwӊ?6]߄8kFpˢȞ:cL履ت}u u`WCP(L;AsHǮO!qN \!gG;qw#>,x:cFS\{4!"b.&gh[[gm#r Ö3Gˆlav!gŧyF  خJ8hJbjb29xٻ!h3-oKuV \cЛBBVMB}NQr_>ֱG]eYg->_e5ѵg!*,T,RtgNŨw׭KAY3Eᓴϕ@#  {8wڒ6U5Q1͛68ŮOn\5ƴ sbҵ4K\LOt=!b]WîΠߚ;ս?[7T 6]T?YTvxȜpT[7 *pT_Y%>ΜhKZ.]]&F䆔z{~lȲHpXkJJ6 %ә&tx;MZ1' 6שKdFYGi'6&ŅSrx$,u$a vC$ օ"zC|hG,Bs) "nʞ mz}j aW.6̓utIeظ_kOdƐƞwkL(!6iLCgAo<&G-Uzp?7@'S<&큸 %/z}FatbPoBk"*DGcO w v&[BLˆ4K8ӫ0Z)ӭBcFNݺAxkIDkV°& F!-^ WkxlV| '5%XoIق=G1:{-(a:3bΚļG'aG Z4E#ڰߧ1{*ShB`>63{#hq6{OV\\+ 鉀i\QQXGyzPJN1g1k@Y:9(XsMII#5/a#m~ْQl;+Xk3!OTW2EEUG"oݾCbuo]ġ ]^W]h| :vDyo! ّW/v7խTC_vKC Vƨ,lI Ecbʉ}{YL@ Os']^qC: T QMqK R"xўЗ/I]: Ai͔ t>ˑ!`rbEMOP҇Iє"_>Mai;ܰm&~)%o? ODz2Ghp+95 3'ũt }'Nk]-^ SPWO1(ډ/!$ G |DŒJ&2D#+J{L'ѪQ(7/_lUB'&)ͩRA>Ķ1`4) ѱ6[`Mƾ UF*qvk>Hʈ@,CJΊKq}E/pS'i \얡e ')Y';(J@p0.'r蹣 rSUȍV@sh9Vq]LϽ2 ^,^D.$MB-jg Kdd07&7e2?'d^ s0%>.`U#PdՆ(qGyR䊂p0=S`MKӎoh4aQﭡC.Rϗ]$kQdv@x"+]WQHz*/hx/GJ5f_:"]4 CD\Qy.M-&ή#ʄ9IUKDx< ӝj!;EU^V#>^lj% p8}ar85\qcʀ5ֵPÓ_lշ1CrmZl$ 5R;koXAg$3+x$ Ge_@Zt֢ۃ،CFk#q W"`|2x+z܏2É  QL>S 4p,fLD}+*jQ<%8߆ٳQALmpv}(HaO3\B3FN/EN # KUX e ܅䈄cU0#e .A<3*Sd^G FBFL2=@fYhj!LJ(ZmTbwy%

@\B?jF@T2%4#J~-.lߏ(6 O_|A%+‚:[-6q6p OY@W;t}矱 ) C]L`DttBkB^6lGcc u0T-1on!4hDjSsSJcDc^09A q$qd%J-rO]z#:3F0Յ6 -XX ha[VBu "FOiQ~~`7L 0%rJ2F&!ΰ`1cm()Y;48{وDH`=$pt?U8Wڤ#6b*Ws]=jq$vx6 6F;⿞$oD6]xi9jS CQ[h@'Hؙ꫱s5~_8x  8}}n8U>e?4؁$(6O"{W ^EBg;Jv!~%v֊8 "Ŏ67ۚ)Օ4('!z c (?%o $\EnX&/=l$8mh|KOf`Z; ^e8jTFmV3 3{bU SE*֙eR8ƍ79ֽdtcpFďT_8S]53B$_y|bY2dKEb V|*}cB 4b{Gd ]< އwa: &+waПGÆ <<'֯`ESQԥ&x Tl߂z_@#o&'wϣZw >UL1*F1Sދw `N,!iVdx^9BǢ/#t6 s~( 2kR T?z~ɸ"Y|f\81{©$މ3H IЧ.mEZ,ʙpMJz#QHË.ЍQz7 (4- xY[gFLCZ)g=x+8~1a}i`Ew3G@G>|v3錞:<" taf5HK# PX_ԸaKyčb2qg!Ezp^n ^ܹ )d=GqC2czT_#@:G-p2zՃxd bq RP.l`[Q:+fƠŋj#GY||Z4{ƻ;sd{}kEm' /+&5pqV 3!7|=L-ڂ8s L;&ҧȱ}ahQ^Byn,}iyeַBſ܇wE_~Vߋ%aWxsps>^[ً 7\;K\9<- [Px)3'݀9a|d'.ފq&+>w3VqWa)؉015bɻ0fF sBsx[ W̘5pAoF/3bomN~KƫE};c8 {!&PFȆwpǗnwWl YuWIø2ChTF;t؎'e ߍ'˞0fހl|y`2,#N;(08cXL> @m] YJYCnYP܏Y9Xۢ>'nl=0#&n촘FXx薰h6Vo @ֆF&F7Oq6aB<0 -ݘ?_O=37KԪwsnǽpt?P$cr\S,vE"dd,XsXg ä!Dܿ<'wpT_z`DVbINn+~+qF ӦE`SP"i(,DU%ĸ(+A~BF EZE&Ѣ/~!ᰐ>y1's*5Xxw#oÜ W5'vQ|~oΈG 8q4ɩޢ A|9 j4t#f-8|G"APK&!+ӂ:i?KQp=> 2M eq{tAC]7a!y4vA0yj5aTP݌"}y ؃~Ln!#2bG1ڈ1?wdƑ3¯Cf9ٵq'#8Ս'|0p5od ;;Py'?4%$[kz}d#Ecܲ2\LqM Ex~{sܾo@]SIۍUɟo S9iP,"XWGg$Gfsi1~? b2qthiq5xwV""jG6F䰙8S=g6h%3,.TT Y L1ˎ&:G&/ Ihn0[XO D3kQLIsǥ@FQTlCxg)| ir7V3%daIļ}?bziNŽM_|/Xa5BpPZT]Ӊ2hr=oCyT~b1Üoj11A igG|3InˮPza63g Q?1BI/@o <2 x:_AWzxRQce NzZ{Y1RFXesNBO?߁iVK*seOG$Sf{l"b&: p|bgv#fsB"0񘀯?LLƋ'`(J16Xd O&9X+Ohp+(lcbfbäQQҢ~Vp,\>%TUgQI@ @:ekp.g$D,LIxKR2d%LeMSf1 izf^\ [ mJ5 \eN! ؼU2؅d92%dláfB98kQ0ör[98vd(}8pY|&ݔ=Ձ93@3E;a/&܌IM[,ce 7I12E2Ti#s<6mE8o2۰ckg8FB=}ǝcT.э c|gGi*Q8Ӏ p:|SL99 6mō y+1z{Na`xXDYY ["LqM bFa:ỷ"vԎع;O֢dk̿&C/#c4Fh WcΌD1̞rs 50zL;pf"YDQ ъ 6d$ȘdfR$.ƙgNQ8| >r)4it(}.$e !p(A"#fl݃l$4Й>?:d^s@q )h;Kĝ`k pm8 gZ[SQdVhEj:RgAr6jauK(ğ)1 6΢Mm2JGg7݀J 8? cņ=/&;\\dUEWv"xuq!l$ gQ {J"i@zj zʂ#,cyٌ޴:5#9U'rơh:fT;¼-I`Rr*u5z3{lzwA*9 tԽ,{%blQm޵Ǿ*?pWEcJmmO"#@^81->-;ZMu#¢(3ӃsϤ\)>E̽+(Q<0`r7~ /3_pZZZ[/P0ʟjyMG,U ޻Em8LZF4̋_A!8C78̕>x_1#7H("C4!_ Nh̉- :Gqބ*  Hܬs푡ux.2Qk] xg=4h_FEVcf}' ȥ^qFg_rCx;z=ި|h㯩:a҈aS/96=,}AP~8ʛ4ī ./>q )m2g -8sϏFm+CYžZc:SX_DT qt\1h$ ._duI#yz^M(Ux*B/KpH GV~ģHA~j|XQȡWwF|(F-9`8 oďQ/)~Z8oWF%%]Mj3o}$l:]z$jHgWD\Y7ȐP La2 2er^x .mm8vvp*aGFCX*NiIE^;xC3 "i<@d[?0c)o?lĴԟ?I(T9es+}ztobMw7f)sO0M2vu]֩Sd=.Nwud6#o-ZMO>^湰wLO˵&G<Q 4#'^_7D-ᨌ?ItGqi(`" | jv\Ifܫ5 aiN GS@ fЍ4Ƨ@A d9}M p%JhzzToGdixSlȧޔѪn\0٨C%KdFO oy4AP>^(ku!| 3჆upfe$4:j ywd4 jId|2N]ZV-^!!!̾)PqQ U"T.GPTˑNP(Ǚ^b4LF8Vɑw?ŗCO($|V.Fe>a'cG~(߁Go#^ QՁXt/\1~!nW,֏Gd;'0ygq׃R#$ UoNO=Xyc21|#ZI4 G/CamQ2 ^(VL.L71^SQBEJ1id pΉDo-X;UxFj˜}0:F, uxMc9W#jp͵4A^>bf{ HkKa|<.,oނ)cʙ)"Zޚ*x{CT"wpzAg.ƍIRoLu|"/rakxPqe `e!n%-Ѧ)RTԶ`1jbfءh5ѪȐEʼvu LM$c,z%z^~yɼYǽa$T. #Sm,{ތ:U-fu~TmHwj |j2TO}/ym8FT+pn|ٸv*-FUvV`i,z`9X\CVoS%%:݌d \.nm1;5qH0h/ѷ`? 9sKL#*&jUedjO%m'&cƵyr]XE 2(4&h;&27~{Qj$RꥄYq:Q8P n{ٙF6Zu~4̖y94GI &7<j>+TƧLDhh0;ᤂ/-6pytvD\6R1޽! bup0#!?*!kRm5$D[rw=~w)`(o`6kk{ &gps>}?-ɱ0gRK].2 kF|7}ݑrC<n67?zg!A`f&tl[푳]0R;^[Fa:){#ݎ.%@~*nĖT\0CaR;@6a*$"҉۰acOi>,[N]&3{;a^!kT3Ft&&vnE/=#ZJq0m 6"< `ʂŃ^z۱e.T#MxMBzt+oPk%[f E+BRDHq$B{v`Vd}mn]#0g 5gJPoĦBI.oo”XA{;2Ax?uw!:k8ӉQE88&1HovKpMx-8zRD><+EJR-CNUBIe,YoUcD %Om' h9}_`Zxqt6FA>"H㭍4k)ol/'\ &LEV$+޻q T "ٙYryQaz &_}_} 'kB5dB1oh`MGm1$z| nE<Îè8U}H!B] m^چ ʥl=g6HEkV"eR,܉>'p@v{(asx;~ZR}N(RQSd1YǛc<3e&ikOGQz3m}4g<$hQfc12VӅcpl،J:¯{ڇ# )bhLJ(1@SqU4d|6_BWV@2`tÙF{ cK%}N2sݒI[f,{ދ| ^^E!lۏCQR{',r`':4 {Oo z5X.{ic迂HZj᭝a>:aCPǪvQ@;Vu GPh BA0m&!<&8]!b{r z]>6$sD qZ+325Wu›! +$D,f:P*o[<+ x /*wP;k.=-B- -?sfބ?{q0uDߌ804.ۀn$@̤LOcjOG_%֝@l:V>}'M|pI?cHT< a8-ֳG &0l"^JّCg0zL.C7acćqPOsj"m,%,i A֡( DN>6Ҕ ` ={P:`4iPu7 ;i9aw`CBQT||' LHP>Em+x7g:Q8LfeA 3k =G>o85#| ڴ+Z3J~$%G0= `*͟gArq;]X'ѓAŤXͬz y)ە#+-Ȝ@ckajQ''H][C-&%$hQE4Auu&JVb'}r s-u#HJgQ]4u~e`^^| Ev:'ar"YX2nM@FfNy<i#,0*C0ǹבp{oAI3(zJ\yisOَ adBM᩟bx ي{ Xj L}gan m?Ay/y r=U, OQɷf.7pwc~#:k' P ۟YgDI~AN-s((w"e.O厂Djb~'ҟU.Ͻ/Bxa)z0=9y4Bv 8 @s6 H>7_ nuI3-r1¦ginCa6fPC&}LfsUpsǠi26i,eO5AC%^Zp`]DiBTKQ0dcRE8k^p+]':t Evf?kf#unu plI%Z`":äo@ pudVZ@˜Q\R.ہ_=6C~7 d$#-~qTg*i,ɽ)cpBBBIH IH !/By)qw{%KZm;}Yr–||FZ޹s߁sσa/eکYFRW9ЏR4k_&;c=] S'ÒMTn[3?]S9NCLm#dg"̷z/b jAA" hx=xw ˰3Lr/cGe-kMf555Yh"5 |x1S=¦(@3iڜBT鉈l u.+f1OC4PRj{1DΦӠP d )Z,>[>76knw%ԆhhݍjxզDf&DĴ@jp  1mD#.'v~!k[Ģ'. OLT 4c plCQQko2}EjQP\U&yf#!c1@: Er7lu8C *W%Y") 8*כl.uuؐ44*[uG`t< 8,pKM4ƌC۝u5,߈5bpR\GCs64tY^W& ,HumK;\D Pl6(NE(Oɘ&{ @20ytõatv6M<$ڨDOFx Wh[[ GN08mn|d *Z[S2gsN~reW7o*X. 1-Ptr| KA< lB6F` `pSyl<¶rli>!uhpE#TN4"4BOAdApB~T.;Ź.'1_@H92u?Hg_2{GW~tY1xjEt^c-ψ^.|O@H UNAf00fo.?;FDykЖ}ğS|]eG!Tj0`"|:~*[_a! dqa/ĔVV Bta`ą"ٛV-JUږNr٧55u(c= YrAUk h͍`[cTKq%9ŕf:,š*J\!n>wS[;.L>CQ!h;[u'SU'$O g|w!r ]+`Ove盛e0G#/S3L*  &7vu"v{y۬z۫vKU۳܌] 18VWʠY W)/HX-uu"x5_Lzz< E3`l6 eDOZ4g\4Z>'nЉJv`hDމJ_4>LmHI褐(rWf0H([ Ѕ]I塡=ɯ-9O5|b՚%{$)HކI*M,}[0˰=qŠbYѷڕ)zjIUE7- a#Gef}cƥВ*ٺrY.PzU#$3&NȞ^[#0,LJE`Jl1C"6E P7?W`R3! >`B_X.aw }6w`FlۖA8")8IQDZT2 *h/𑘟K<Aii%-Ap6 f#V{2&t.,z4P_"2fD+J٥1@ c'|LVdiG^ a.L76TO E]5P@ф'A.D3 xbx zJ|4)wA!>n^4B:'##^p9( [/X ytNذоVoe&>[ĪZN"r^# l@ylMnS0_iz=Ө^Ȇwt`b5}m!]-(@qleN[[;,|. 6?\ĎuUbahv!Ŀ> m'HB^ ׂ o5UX=@vhDC#{4ilg/;'f,X1Oym3B ] #,1ZJس/\ ܍zeX1͐CfCjbB .2򲝭v#6zQX "R kr}xcCf ,B&:&68v"̓jFhs3 _1,4[!|Bz:f` iܺv9lډVZ6[6fԸDn_>R/Xx ע{O% *5%Dn O4Jt)52ز Qlr.<2bՊ;kʰr9%GHZԾ-9|vصoړ(q;)Hfa%F1[V3qIkr9,JC%0e/ٗ5`(l+ ou SR- I`qJ .2,?-f!J>>JIb&Z‡2< `]6mׯB {AcQR ػ"aFˡ ! &kW#0 1@ UtV rEX{H bB~زm\ +vt G#c7|ڋ/b,~.Z,[Kg"gB1 z͛Gv?>r4Z}́M+kk 8`(kW t$q$ !NEFxd&dd$!DҠI ;[D: -9z':V,NT9؃UY%5:8T& ,yz{/JlbߴC+25Gˑkd̳ұ}}4E33>փIK)X ޟQ8/,Ұe%YCl$0mA,_$H| siI5IS΄bm0hXZbVCظF͏0tXNI-XEfV͂y[fKaRH> W| KfM-|j oỏq3 =HA P 6r#p͠g߃Sk7ioVlsb``)h"8炭`Vq䊰})ͼ(m|~<[r1  >M0? G@^!탶0m57]I sa_. orTݻa;^҄ )5H쀆qyXG[@ Z9q {Nh_?|>xF!`41,¢pw?CGfH8m;L"L&WBۡP }GBMaaw`8AG V4:=Ɯ "YpPxi6bx B7Sͯw,پ6 -='aMaж6Go@*KADA*D h@sm[`ŗw 6 VA.x`@x ذJ+a|/H9@kY."xYBh}`l۠ޏ3+nwfb[K]K0ݰ =&GGphCSX&fN"L kwWga1> 6 k?#aKGw]_WgEH-o 3:/5WAn4fNa5Sოpi{$@~喢9س@],:KIuS`/ptJNH9·A^xx&o¦|w>r0'.Ӝpg_QgҺ8R S΃΅!#+7Bn מX3nOހe:̾ olLߺ I7t8,ssv n1R,b7La`hh+/ʠ+ӜGqn#-w0?triؼ\?6܎Mm欄3,HpTԯwaRn|BX45pFزyp&`L,.KB!G3f@fwq90n:X@*K7_6 CLHNj lkusA"6!H?d &x= E␘-N F`{khh0rhq5ڄO (b aD=v+\q3\7 f0" a{3S{k0,cIŸNXlʨ!u>& ,ۙB$A=>yvEd3ؾٶy WA7MN69z }ltD]& ԍ_?>-DDg7 <{v(!2*T3n*7ҰBDK!p7! Ϟ53h*R 7}6]#p-зT /`H,L{5`Qd2J91&%!R{͸N hbۖxw6T!5gO\c;}NX 7 pJ".j$ӆSшn L_~q^]W(e ]ĺ1z\9@͋{`ز);ډ|61-<[av`d?`vdlV ی{6+A!;p*$O`JB8ld9b(҂ bCF8}<$>7^O <x6zldL'hutڠ\%T`}؍#epɩ((  suԈxnDҍ> `x}X8%o[aFe2Yh52#=rXЈgai5OmٴۭeU arB/PlWw X Uaؾޞc.Q0怫.ĊXz9yp{6hvWFD w^@кbZb 6%0lޫh~ZNG_ Xoτ!4>ͦm;a_cZ 6B%`s!u( ͤ!,Xx|D:hu`hWY<q6 odxh[he -ip?BSpؕSb? B 8Hof<X!vxExV漈J豜v!L臉3O0o.BN^Otco<4҄ %k¶âa XZr o ;0~ CvmsY8u<|FO>^lA+'/]X̴5H& .xyc>'!YB<6;q ڊ`!/J*@Z4US[ da,+,9 U)Ӟ릃E_D]υ_~`bFe5且./&ka]3L^[t/ cFBЃpcoc !`\551gV8m: cSwMIQKp-䈘(tư-:D1.꽰z5b^t6|n< F#w(zع 6|mmY1&0BdD=l  N?[C~qTBJhb vm.?V/Ğ&Ô{Zad4aKq{.> g#bѪh^{vYpdaꕠK_!y[oți|\*f8ĕh99Jl09LQVٹS\ǍJ0Di{2#ni7m`HWQä |H= 2 ,V5k Q "ECDFbq'RpH4y2wX,nfl67^DC( +2/+ e'_*É r'0 `Y mv|ĸ1jUґ,;H2 lrQh58~X^2-d+kQ+Xemt;6DN=IqTn@?e/c5B#qJgNtN CLN5Q9!怳·-8? \6Gk\`v7.p:w}`=qA ּqݝR=yz~r_WPlÏ|+-ftg!=p:QfG_aw;ҿZ_H1f~jj/5摶-1<d6 @r.s^3tΆTySAFdiy-gz<OQi:U򍅗Tf(w0efz1<+P 3Q"la[m?1nM?ݽ蓭؜Iw'k=ooJj,O'`iòb8pw{w̧zyǚ׳%eAGT(]?39i P,d:-š Mͦ*[,Sn󻼕+CMcpj\^ łR9 }cʱ#O-0'Wgp'kLPw&VCdxv5V<**;rB/B,Q, 0h bv {{#d~4`}H ;{tIJvfy8h+o](+^GΟU*2wz*_Lf|wtXhx=Q1 r#XmlG a0LN HcÆ^'R2NjNs3*VK9#m̲=i?p:b:8tK2P #oB+yDg7螕ưO蝨vٖͿc_l<Ô D罱-mi8d\] )Uш M"fy6,s0kwȒ/ oeslOF1ge,߃^W}{XVS]ig{Rk&tz?t4f`]lqpG. ڔ<+z:%r5jm4EtL0;d)p]++,4Ӏ&AGA.YrۃHY0:H̀|uA,&wZѸKOmh'35un4JH(i1U)e 6ہF4E@1B@MUViq0YUʘ\/`1޺,]b&@ 'uw5Htj&{eExNl ^X{tjٙ#n٣Ly2fyX9XajAv)7ğVrW8eVyMůwPSm5e>G!2H\)iPGXƃ( 3ԙg:N\`W+#Ý+p[Hj(+CպYԛB }c:Cue?*K21)DT`M\c$#zGK락zmNWJ79|f L"tN%uJahqt|ƖDKJŭ1'bx,zpbٵp8vA8?jj<ǫoWjq  $ز"M3ɷ/Y:,ۯwG>lVVQ8|wwXSWVEwu`M:w2GA-:v+sJ^7+\rfN!7M4=Ax5''UQ3Or4VWr)ϕF3lPhә!Fbœ JTojOS4=LƯ7 e:b[5!%2ű97{%SB;ҩ%BYM'յ钊ɜDbj4RTPR*+%gKkNjw*6Xl7TQu9͉mu"J%pś&QU5P@cYɎWܕUuڌ@imT\pFy8pٽܸzԄ/WxFQХv1`I@]B:] _u7 sTW?wTxG@Qծ*#ܾ>Ƙ\Xt;ύn z)ѻg:ښ1)s:{W+41\U?&S/GV)C,D}915dMg"%°kLaT\%)b.eсdԽk3JҭڡHAnpP:DzVXsjO%J'5;ӱfr62Bcfcj/diV]SSz+[9\3J0Țlo4=-Lj/EyTBaToKǞ ck*NǙ+"3PC|P4Y5QW3{A uVgBj(oԋ6t=zfg*/:ؿM3+Dtl"p["Y7N2%:Vh` ~ƖbQjUM%펚ڠ^|:ޣ`Z\]WN7|Bw4RQSן7k}jhv46W9#ߖJTZD29<䴢M[h_J$;B#o$/^MJv+6*M"էlnϻ#ޫK%l֥]DM(w5x{?v+k@GສL\-걜r2x2}eUd^}*[v_F*oU[CUugMV3R<Ʋwʅf2K"]J㧸"6ӝ9%:/8Fpk%U*jlhEllxENa;LU\b<+~40#\N:Mphy&4.ϧǿLtI0 X8xc1s}9h.dMTr̟(rSr#Iz&9?TsE8*}*߫{gG+0 m. t)8/78\.*s%<;&N\>}N&!ϯvbpgu kTkئǩ!+%+yODe=9ţYN.Hѫa۱@[ .r9h$u`sC0Pcfe%0Ie椒$ 3``2fs!LbXPH:oMM>hb 4ahV6Uf9Ʋn,cTpئў30㘲m_WDMF5 mN|3W n&hf<|^œ*V L+5aGS-=f! yYX4&4|?4cc~6ߴwNǸv"8&&deMu_=#E{\UԄftYΫ&rQ7BUՄkDjŤUDTz5O˦_J.j4Bu;gWݒd\!i%g'C,iju Pɱ3fav:]k9a{!ExM}R ]+ GKL%#߬ &hr|!Sy1gi-D"͚f;KjUzbI-=K=V4Yj⯢񼡓&yvA2:G>csrsqWݮzA80-Yec$,% OJtEm߄mĺDD#Eո0Tu~[ĔW쎋Ϥ2OT4ɀEj+g9vxQ Yr#46.K$L`1?̕:u$X:yJWbaDɺUno[XT4UĨ#*ma( 3g+iimL^ukSfr~8 G05X#(VbbM !۵DL@US -i+j}NwQR~??Ma nCc4Uoq*ʉ.Hۡ ring'c̬aXnxV!; _^3'ak!ANIuU1l{SÔ c9aw1lne_UeK.' :B9Vّ J[Wd bp&=MIQ&}{*͘(o8OtTV^̍$5>.~=\ݏ3(3ȟC /̪cDWWer:}0Gтkf-q;{tˊ گwwE5M{3dbn@ӝ:O}S܎qd݊2dPUNyVOgW*O8۳'^'G* I--i/]6T x/˒->HX\,$H1RSS՝FF4tU$'ݾ~!l{Qqb#zf@47DCFpK  n2<A6Eӧ= ɯ˥KywK.vI^Jא_OS LqMjJ#=~"մ^vW@a %K &CY\Dlr,|˱,˚8B"]|uᕤ&Ѷ]Qo&b2^^u3.MA24Ω(NXbܸ`txKW^˕BF1ɾIsI/6- Q0|/E cҌڳ^&MPCqa6ۢJ[4nwizEr4yEЩdqOe'8'=씊KatfcdϛwE|6z(%NNL4@4YR(8[SS d4 b6M3dwN'fMtFJq%}9Mkr:gB[q9Y"]t3T""D`.IfN4ԢLz_ %S*/(^S+y`V.ӏc?(ξ$ߧ(ϛ$ı]wʬ-+FW6%bAU$9=`C \EB Nt;%yb`gtV*`HJ!韛LT%l1Db38)330m:2pylr8W`;seU#XXbn67W9 3Po }^7oœL8UH5mչ•} Wn+j`Zl0 6njL^Ld)^G^,u~A>| ۟y%UTLA4;6f r/m(lӸ[*PDɴ`sb[6j:ImV4:c5kpC[(n^ `!N72B11(N H֔=:rޯ}nE7]@?|+6v1kֵ.dk9RGـa@¸o{%MAT&r1+ɪp]0hS半Łg^Dј1+_T@c )( Wl=y"m JZq)>T{,Q&Ye f'(?$R,/6ڣdd/ 2&:Y6,+*1@ r86g2L}ǧi@ t{C<Qõgy{neת&v!\D9dڻR gzaB{K&DԻ24-aK`!v}9pV6A+_\udQsϒ1M3vP*ァ:N<&V˂hns{MPP k1 d :1Yy,]AM-q/RZƜ8Hb㿪+ ]Nwr!F8@6`"HO@Ikkeٗ5z[zyX5AE_xxNjtdo!K3ȇS')5 'gkz]Qu`1F@MDB`vZF4JWe}sIrO݊ v0 醍Ebu0Xt("zIA$xQB 1~Ut;%rS| kj&~5ڇ^ hRV3S]nCcJ)/qck$#1)ZZ0p01fv`.%r3p .rDV)[w+?\S&ycpE^G&Ѕ  aR{am `L.Cp=!ʺq7U!o,رH躛D="wjXd++"9v!Y%ˊ=7kC?v`x,OyY.{9}j-Ve7aMs( 2"q?QN͸+XFl=M:ů~`#26Pț-vf>`eo dP_Iܲh3O&TZXڥXt!aykv(dg| [h;d|ݚveL\rMՎ O-b!Z4)ru"l`#6nJLr땾ĄQ*la574J@"a621B8\%u+o,]^vAbnrkY:_#Upl[S`ug:MH+5x5paK_37_Ce+⸢O6# BUaZ?{cBeU >ba\CAc>WƫyԊ9d Bڡe˾dmبJΘmq1.t'nK|3߸PL NQ>GDi)4SSP:뭲2O$U.||2̐RUxسf5͜i[^ا1dz:[gkW,Y=$][{yMfd{hwL;ط~t{qYqUtSg.]לR |oT}!!Φ^/r-57 ,zs$,+>V{,Fr17 |\OP$j8cudjxcJ홉q@H)'sWifp/|;QX@ b>7WIn3!Ҋ?)V9>Ņ W:qCP{Ԧ|OGB[cn>ϡ:ޕ1j6[BN:\C&;?o\V߼-~6''Wpwn3MF"` ϭij492q~Off־؜#·BAQq7%7Q"KTͣ6czh`Jvu,ٜ}-&!t+ԪhaVbнD|jnc -Q8$P5]و2z7*(p;,`lʲS0=A9r"-u8YO͸A90ɏdH5;[g.'\HV2"mD$tsD쬌a6PdE5u[8)Y89N)GTRLvNI/n04Ej-.;.:†0fO&de3igPiˊ L{Hu yWGN1S@pr^>[GPQv2Ӡj2wTN@{ff=nB͐kr=@{jlsYctzvpXgΟ\Qy','yMvFq!B!ߺh"?&F8L^'K_ cCsdzuxrUnY Y.믫?wsjqMˍS*ƕ`zY> ɫjT,TeNcPē y}ID&OYODC ¦3)]OkZl =o?Nh=GQ!#A<_ ]|mGIK409&76H0WywF{fכkeU9.ln:HVx)I}|iO8l4\ݬ9FJ:umfcH,U!E_y?6S?{ZN-U[ᥛ]_zCfI%>\/ˎw9<_ 4.cpܹX~{,U]$Th8.t2՘3YܜצP2YO}V.UZ.pC!"_7gS =luutLeOL} 4y0>Y;Mgch 1s[!v;6&egͭ~DKY~V~X~#MM^ :^Wc5'BR: &r+MO,nj*.O2:!E~3 2f~* fOkX5CJ’Yb UZU+.H*N圜Xȧ`tFVtl39'9J59C4NBAT&wZZ?=AxqUS4ӬgilY6UU&$dH/x+]75+H,zZ=Iz&%zT9︆ov"87TMvfOZ`opiyѳ A3|Pf6LEjJ7m}9d8q **A[EtxNjLS' fY O%d']H~]WfO2_V/_ #A]]kjw|7mԘLdu~4Mj}f:uLW=f0y]Vg:B1f(ZtjC{oYE#Tpr%J6M!23\P"q6W}ImVFM7r_/Gִ)y Lٽ8n>QNO[wG/]:ܙ5%mRS+3ONuqehKd0Xl|@9*3&Y]yv, GYS`fʓ&-GεͮIVRp0!+s1pI&iPT5ÝYy&mfA*3۬Zٻ.lQ3 ,p dTawu2Ͷ O955w)HC2+LŢb(V:Ll;~lkremMA~. нWY:Uԓ[Mؔ渔#jϸ'GWF UpTȽzy 2HuSd,/6ufI!6IŅK‘N̑EtgIR_g@(UliTPⳲ0Mďg Nsy#l&[~vMpqQPt_G#x=X{k@GddQJJ_la엷fWJM &h閌/ "&It7;aNUyAyiɒp 7c322X,_D歉F. DzEYwRF_y)mrhN8Eh(*FC{!' Z@8Q[[/)풱Y0~dl#t>Dފhj¦Mm^YC{F?$$׮%\OP pCoJ"vFvxs"z*ggvP wr,NhƔX-ȱR[V5=ֆYnjjC*pKHy8&%ut\*:hF@^xJ6l',1ո4la1y[?ׁ\Re%ԂXtV&fZgƦ bjJ%_ĊV'W„O㷿Ŝfa*ΰuvꔑqܥ_165XϴڥiDZMVB|֔VJObIWD Z-WnZ2TS(L1Bb((% }bV؝BNV%hw6N}e<~"?98+DyzLgl׫%(R!M?qR1K>#>"(3m g\C Rߩk(?l'8GKxeze4WƸsEjg\羅O'TEmzS5!5MU7 WvtFvv](IBhg!D'Ke><'\PSn*RO/Ë3)R eעTӱ2FiVMG/MʧdWÏeB= OI-^@㾥=¤c F{,/)wYXud*AIIL% 3dE!dݩ*@h0mxtOk6Bnh+3?i[kH-pKa }2Ctxt%$drz*גȸTnexܛkcm0sR:4VdGj`tlAh1Fml\Vې7UniGNc t:3TTW8w5UR;{XܫTR،gCD;;|(!%[ Fx˂/jH'T>FqVao0Ypz}sri^UraȆ;XKEKKt*j2Q}IŅ>l>7BNIfZZV[ނ"PMCHB oDD^B-4̞{WaHiC(Ln3ko"@In: 9pY$ox xW'TA^}-T ϙNH2ʥڃҲ}N#t++%nl/Pvph`΂㺨2']@ k-^  nĖf(;SYlķo<ؿk3Axau ⅿa9HIh^^} "b+X{j3}-j0ob%*+pʒx[P ?شWdSشK`tC4Ũ.źeG"HsXXhvԩ3NL! ^R4B`O3p*q[I"vD!س>'^B gӦDЯJp➢ ͧ~;gq> SW쭂U?9E$LfD8'16tY:u"y˱x>N^2Hҝ܍EcJ .Q(ȌOO2l%S:ˮ:H˜ m\J`'mFQɑF~HQ-#0öe|V4*N NS1:Mǒ3!yǔ/}? kcDT"ůa"+8T/`ۂKW Σ~} Rt?~]aU2Մ9o͹xier5; j6*`&,Xu? ؝_߄Ͼ86ohnk`>.z lގDٙ|qfB=@ 6 GjN`1o%Ν郣#"KS# Ә~$%R>oҽm6ƚ1Ȓ{$jʠЍv0٨.ÁSDpd +h^D#wfq| Pūr#y;8̈́tx vA06 gf'3zkUZ hK2F oxq|f@Q4}0qpX AImE~8 }v'gµ;W?Ӈ"ZM0*YVl'Y,lt5p3v dN'ht2b <5Hx %x݌M0L⭗y1,W<> >9+>3}U, O މ~-tJކ =!K8>4Կj*1v /`R7LcPd:D~qM`ɛ°;0̊W׈H~ xs1}𽯒Nnb[i8UP<LDRę]X |I'~a뇡b[+!a~YO`DW]HD3WGJ1;qd>JW(ꃙpRn<mB8c_ ^_N#OrkDWqCnf -%,Gbx1tˣ/=_J=F/'m\8ǃŀ~H$m` "Աas"bcA~Fv/ iLkKg0( t d("FcnUTdYy5rF|tFp+!*mQrpXsTE(66`F~.^9.AJ9>ع6Bb/ҼXɸwf`Ă"vQ>B7[6!s;?x~m݄}4՘<w݆ld8 }\7w߄t'&lޅXR<< X-S̜}2`fLsXxaJX1q,!ßGb,^{Bi18=,.Op Dn<$|3y9ty(YP8OF]lH ݃зwǽg1 p.Vbe9h\ ct?r~i +~eBs'^ sGqc85( UXw fEg qOَ|dJr*.r(%/rpme u`xl \"7yx:^qaTEP '=7@'ΚtGw lj}mDh0Јkpx?j|z8^!7ض e5$Eؔ '!nAQ>`pXD|tWދpz s4vd&YdErzp&3D&o50aC!X\0 g 5⍹;h`l"y_ZͰO%Fn68vv4 Z3Xpnt2\ހd#\'U$э*OZϛh$䮿[nBIÉK,.BLpҥI.u;̺[|=<_dnAҭb<E/n. N'DQTHЭ$DVYGlF Bl)@&ԛojI<#?nn#~i4"fܴQbuX+ӸpNlkh۝.'g1Kb%Yԝcl=\)L;bG2*mSᶾ_͌ǟrɊWe#$LW~[qx%W` ?V3S( 71*/A9WQo"dz~#Kx)ܝLXt B4A aJJ Q8ixd -BaC<?j3pp&Mf` dPOp0NI:3řpg`8quQ䖠O EW7ӜCav+x*3<[滖6'ԝ_|nf[6o_'!rt3>x wU]ߖ\r&n_g"K|pnV[mff+&24RG@|ػm'=7PWA̜B'\I!#1RfmN? ^ j$Fҭ+U=Ĕ~"f^2Ml:Y H]x󤊕mwqĸjP[OI@fw|)tݜ(O!5iGC5*鮵j{,s1rУ(OKv ]DHXmĈIٛT&,]OL^9F wq&'F,ǔ[Q+w0"'0w%zOĸgMT5R{kc7*c䝘5FlڂtkذxIxw){Ǩuh `$>yܙ7rp?EANi AG^P܃[ObTY1 8VnÔY℘ FہQ E v%1=b0 ;{."ݓt;s|GIbT0H Gw vs2!yE94qðd<K!Bĩm2@8 5> 7@ B]0Qb;iNLo`Y&0[!ΡO)b2 }QABl؂l2aEIw؁Y,\ {x%ڑqFaWR[H:NЈ}pxBV`6D$YX62]؀{`̀up!7y\h+LVTЧ/]2i?flރij~f{ jl5C .&MYLdj-ϧM@ǛQI܌5=J,ՉAݰlk0r8bXV掉8q 0|7QO<" } 07}Ab^n> ^`(dxm @fQA 'w+_[w| s LB]bd@2RhZF/S8¦C!O+]GZ Ď1}:eFhQ1&ƥuZ,B4z!HTcG`Σdh!f ~=PPHLR̉Md>VSjB´Q2) ;5>82S l@4qt:6S AvA&'췊Z\ 9y?|9Z4i:Y e9 2Ɩ>};6|aϼ p,]0n(uIC:'?|썉ĭnl6lkEQbK&rB-,,4be _D֩k>;FF4L 2×|7tK@u= 8)ҖL $ursM̜ճH!eF*/{%$sB}PS D$*7s#&Aɵf%ME11H%f6GJi${YBWhIjyȚLVX^wtnG/)+d2jIq(8|Ӎ/G)zm phZ3 WK$1tIB+7ґ+-1lXv؟i/CIo踤rcfvGco18}1$1McZ 71͓T:#u^J"1$[梤:ЀqsmHtt&Ӷ:.U$a9^o]9V;_.k0"r;nύuƘ^v:[d5dr7?'pm#=&%3U4-eC KO{o|8doGJ>vg)d>`7MMm[^Eml<^;oFD 4)_p¡ȂM.JF п寗`J[_$)'4X6U ;S{iI}3WTWyJo+cs&R^ɴ%i#9'a݅|- 0yK[q; i)99Vq~o0qVMߪ1/sU! D=UJ.wzzvo"4i: (>lΟلm97uԴ|M2drÛK˺j,- gPץ^G% f4ĉ+@[RVa7{7lg)0@ r2!ᆤtXvNod`Xb0zK) #}7ɨ{|:SRtT5L@0SB4Da6;¤>*ْؔP~/TPWGPMڮZ+ #n1=s:;ṮiIrs 8$GUY1nAx6 tufâ3J^JER[B )ZptYңX?aDN:5LQt/듽ҵP{i1&o\~"L4B.R*}!)+s㹶_CFq2i%i{,ztZIYt|qඵj]-]*+sI3~9 Ⱨ!b[8^c0~Dh+oDBш5<[GT|{JQkwkLDJk05™@Noܽ(ðq8`qb(>>Cp w~wW(L} #{c| Ȫzx8tOAXr$kZRY(D'I+TJt]}T| IǤ:]dRFCqhX;'az8,zc1+=c&cʊmtXzH^W)}jl|'& $dǨ&QN_h&;>t 0!P(7n=PA2&qz I".LkNBzv3U[ҡCN.a+p<%EAzx" R( c%#h݆9J: K$XWC0=<Otr]O1g6`ƸtF8+/LWWr7OҚLjS4zP;oSEvz\H$<>Z豢df^:zmHRpeD&D fF]B.v!2*^S8V7c3M;PÑ(a";C=xcִw=jzV2"^4h:{lI\6"*SCH1᫲F aWf8[=`#^5ZT'nXGh B'ȯp Al|;鸹^}}'cp!1vOcL{|:!/x)I"ϙxx31|Χ*%[2!:CF &EHaF  lڰ|-&L‘PmpY{+fL7_F+A/՟ĺ*1nB<:FMs,iHmЙxlQL=,&z GB]؈Qy> ?C #Jlܽ8| 59hRѣ[WajD5quKxGHDC۱q/riR5 PGOފw&J]yPAp)Oi)w`.K(sW LQlۀУb2v 2} JU|9 EYNb|.%E=yuE+c<zwC^Uxc.&g'Vn";/{w 8&&U+v=HXBdص {O3I0[г j5$,γUpf"NsaΦy]6-rAT_%̕spڋ^(w,6oD3o c:#`Å#䡬BF&x+ng.$/.8kOXXfA6\tM prL]biB:Hy"| Ċ5>݁kb,K5t"x W`*8)x^0AYZ;alItذ t9p%af؉gå{eޜ{!rxg6D>Pм{3\.JygfR`awc'w_}Pm$*<\މMs&(ܷ 1Mtoel܍"굉[ee-0d ,X ܏sk(W 3TE+uD6{}d7q4J=l`څ6N_dlQgdfeIII;OMW`dYv'~$qժ5I|ęE'[(KfIW!]98@g2\ }\EPv .0]NBP=oǻ+ LfKOF|ۖ93S"W = uMO=U8dd0S.5L#XqKҍg_g/ioDRB$t;W02 vcnԫo;@[*R+82IEiB!/P+0{>Y_H=Avᜊg&̘у ww|=-D+JksȂg\7 #|` Hy v-v A[ɏ7`p#ƪ]f+6 qk¥Ԓҳ\+W7>{-D|XpklO |Х{B%ZrE0WE@A-8 `8c+"> }%F0pr4ŠD3ȵ;y7 ŽU ! <,_@#b;G33.&ذmQہy@F+}G`X ~= KШVw`/^M(ʦ*`s_{4`Bڦk=8%¯`KX3R0-Î jv*xe H;@jg/λP oDND KVZ͈q.%K)^]Х s%2UTi \ȠZUu5Φ2,xVQ\Tmt~ v#ňltreYiH/AX]N$ĩ,H`Hǎ?owlB84Ră5x8^x`ĦX`?qW;bRԇO5/'n x8E5b,u 2[1}a֋-P|)p=^[$aOjiX&NUbzrG1޲)=u(`@ݧ=/%RZJVeAq^ |CCW'PRo>OZ5Bwɑ%Xyr3IǬ" K($XtiM 5q8y cFM {P 8Re=3ӔLݻ8 oŅb QGTѐbXZ,سl]p 7[2iƀ0rKL p׽8.WnTca}PLc ƭaD7Ű |+<0' <``MX{(cFeklB2;o©:٬"ω>eٍ„H}`p\8#M.XD,ٹoկ`[/QwAz؜C m;fh HAdҹaJmȘ: cRR{?9h%ɰat%e =i#džҞ뀳*nH!N("ӧOE@, QIϦll/ْB_~pww̙3_/FLP I̛& !:9On- W^1a{4 oiU x[N(/t0,1"˵f @M%<|b"d2xyhA2l܍-{S>跀G8rCv-2gWg֎GU W\38[0Kpꀙh6mxW^c%`,d+cMӚ4;m1k.?ܻ33&cxª p=#fb <:<*ל"#0n̬ʼn~|ɚn ARѿfE<v 1X;,3#r8v <;ᆥ:.6Psfp.,]Eq8y¯5X?2(;#Xd.^Q~ 䃚8O<+aLnS;{lEC$T\zf܂ RڎCI_xd5\<Ǧ)8q vo0- uB((cn&8MEcE/ fD1j˄Ui#; qBQ<<\xSᩇAD2q1S{?- ap߃)KwdMxUKÚWA> Hr4ek!3 Ajhw_ n7p@? Sၻqeݍ&%`{i5sG{;+_^ qѣ͙{1~o6#gc0V r=<PrpJ T >OIOucC0H6 bs_0]8-r m-u vB[,"$̆BYY1{ͰNe7ȸ!COg`l(_Yyn0:YY5d_{,L xV}$$:af vHd1q pj->(`o⊴y `θ" L˗O@_D,L0̮N$UU@ |I?C_ r 4u`<"*6gsV/Œ]]XOchSm68#k$1cgc~-$eu@ ><$4xaPGh⅀}^X ,^Y3ȥ{~t,FYsn 8R,~CP`[8pҶ Ā3V`FR!1 J\`N(ZE FBK7,uÂq!5[`QQ7[~&x[cZyy:I`O|?8k7KT\\b1TiK'wvb@p8 );ǽʼn>l~Mǀ7jd""T`axqL2XGIL$dۯb9(tț;lq*ЄkSjs60qE $Oj}]_/i㐠ahChm{x*`vb4XZ7&lWM5 2fV8NFxp 1: C},4W1N"j([^kxD!, h7p' VlP@n<ˍ B`-x@I""q8\ ǁISX[lNJas=MZ<;&F0m, L{cC_ F8nCXλpjD2'J:Bx:z x<5; ao&*0"P[(Xڻ 6-"`1pdq. 5bJ㚛C=0g%)Ǝ5pRhS%hnKla "PE:c+<AG+;'|-d, yzN/߂v3x Pd,O))Ae ? :## *}\h: )(bSbʀÍEP3W68h-ֆk&!' vF<Z  h>+UcgIpu0cF8b8N'i8irT147a"/8 ZRU5.E()V<\ߎ|5JB Th3J0`?]8ɰx,Z~h&85e2˾sDGM:Ou851#`:Nry-A4a"ٵyot@(Ѯ1,_._)j8گo4-Z㱠z2}GI~:7S`x'f\-^5b0Oeh `ZC>U5\sZGBWa\6V_0Z /I B5SZo zihu|J60[h3HWVQ dN۝pV1'|bw~G/ N_3w+׳ZSo0f!Q2NҸ;|8wkZuDQt4iq:ac uQ0eqeTm岤 ދ$%Ѩ4tZ@T_ <ɜ AsX4kӼb$Fdv@Q>4/M HcPC 3QPxhCCX-sF1NCjW#_3(q_O11Cg::ƛ 3=}bo[1Y1D[z>tNMc<ɤŭL#d" hSAaH0j 8΄!hpt {gCYqNbt5Ki oNɌڃ78]b3O<PP\|EKfjʾ&ݺdaPl4 ]?g$pm͡;`4,>ߔ1seW7ve8kk-fzOj :RRR+Y,o\CK򗞻Xaf(rsijT%ga]4lԖ/*yPS845Vt ,";%ESԳ#Fkj 8P!8<'TL4SEߕfrQd4A0vKmir=DE^A]q7jz ̕* 1̐fL81*к^=gۚ`An :E9jsq!߻6ddxy~3R;llc-l4LGhcHXQ#/0+Qp"xKOhM}=R$XMTZ3F !Ӱ', ୃ tc}7-(ۍ٧1/P R Ũa2x(>=U`lAIт8 F %Vj³F~7omÅgZU=Q;%a|>v|=O$iCjR >~h[&Z[.H;wKj!(#6ƀ/;ːA [Zn1ƌkUzƃ:miPt5B'yp|aA5I$_dK$~#G(cV/AbG CQC;#%@@S 3lR-!]"NMBD܉-(d:XImAcGJY}bRW]hMsqbdܕՌ?ۺCaK#uɎ^{,GDdB#RX GJIau׋^irlha`l㯐==暋yL <ϥ-GݭEW\kBS{OL)/ *"T]R2a6:OؘS$]]KF%uzUA4fiԉߐd9,4:gZb8[>C'2/О#3`h^*"-RH,E:C a|݄jeNFN&tAY& %h}iA팞C1e4J*HD*R>H%馌1Ge(A6=p5*\d_*{KS Rz=XiBI*m{4q)Xl/aB鶲k [e=i g[ ?;`A?nm~ x`i+Hjh*b4 ,eSllIfmdA\*k58&)5y (du:ljRLJ\p#@Dv ❙NùcGS | 1#`agP"*2}ƌ*&Rm/J&vWz/Y:8HfO>[2f=s0IɃF#r'۬koH.i)] D;?yHxL};Μޜh=.N $H9"$tS!ܘ::rr7\8vIDp}֣W eIrNEsMT4H | 푌#}tu.)&j||!qOSf냻UvݧAw5=hb3ٌ"+|ӌ~xoԱ%Bl)}v&;G'^mbV 16 `\J1#D5۟ub䂽hUq㩈k< -՟jRTxCn|r ɖ u*N k?A2z7Ҳj08F7VH Y tQsrLзU}Ƀw]oO-}[$h%ȡ-@ǻ@R2ݿ$RBwhWkcF1E"E;7 T^e< vHIC1%JEJo6;ꟑ>C2X@  ?daey0*weB8&_)JXYU?uH+ֲX{b G=K/:nIԻ|K6=0!ϊcga.@::q*9X8=Lh^T ɂ+ﵖPK@Ĩ8n]]5W~/qET}TN"HKYބ p4heE粅ЭU|=,;E4Ip]pO6'LST|ObK(XܹXGLfu5iY4^Yn#Oo.T>X+Y{m֗l{s%MTA:I"ދs5R'M(Z4)8Ӿη)&)9fMNhVm lg8o n ΢ . JP>-Wk?m?tbGעejY7G<th_Q=/߭PvӨOXP]VaF A$o$!ٲk[E$tLb!vMZz[w^4 eRI9-l^(渱]4W[t.ҤJ|!u}A;(vH=XDhTΟ)Vܳ>ʮ(>'ݼ!Tx̓ɧ#])sޥCalO)ӿߏ zڋ3{6zmŁ56Mk~)۠Mܳ?JlC;ӺGyէ۞\,jt[H"CdY~'m~5t(wOqK7Cx>uW17:'HgTWg5bp`,^i$GzW*1 ];wY!GL_+cTRt3/& GSѤ_PٚO7'Kۢ\sUw,t|+v_ "t?ɎւU(ԩ 3Xp#_sU7cuC2TS{< WNVՎ%HQLLQf?"1+ﵘ:J9Lq\F$;TqdAJSYr3&:kd62"idR&mbYL|!4p聙A|t_NI i |IKl~#Ѷ))Q`ZZ?EYE& Dq6˹p>3l̯I~7K@(Rlk%qt'`/@3qo@^cPjeMRc#P鸐i2$i۸yпhs[$}$潄E muJb\΂[Bd~%AEEk9aUka`Wm+ Ď RdT$фH6y1YH $PJ)Y|E#Ak 4g:[͉S;Tir9mRE*#G T*؜!-%XǬ?FZ#$mvIɦ]c(D#NI~1 EU) RHn;N)p(77W/&34 I2eFI Ē%1"W_.M)JdӛdxleIJbXiף2màbpp6V"g(1VAJ*NVeRڥ9 1UϿ$#o-h?9;* Җ2+)X nT($ɱ$㤸&㧶 G1f)߳Z֪?-ɖ6XKKfC]pwq or M?υ:gˮ1zՈ*vv;bZ1ˬ9F=?zǞDB _=8y'!?m.p<%L gؾ5\q^9d -HSpR d'(&J e1\ҋ?dg\h>ռ5~j2̕ /zŷY m'GY \omSF)u, 2Nf je)Vu~Hv>GS\Qy3vbD H 4кdh ,Ƿ&;OЪ% oN>!j=g /QR5UȑS&!Ed@=/{XAw0֑:B ڞ'gbHb ky,.vziт#2_WNi#)żמhܬ"כ,%5}ZOf/HMƨdwfiψL]+@S:sHߓ,\TE&'v;fb+bx%$R4ӐCvV:mS.Oכ*zbmww[d)րps*`c<&xQ3g- D=oHUfZ]ȑ vU8 AڲјgMdOQ+aO*I_ࢯ2&vUa'hKyi.6p$α8/No%ysDQJ4zpmtWm%Nz  ?稬"X'.1TeZ"g)sJ`/+brT4~w7cW"){(aEvWR$p96jT8pMT^S k](':~Hd:A6]GQY+Z=-n]DnQi-XGت9,P3N&F.>GdeUE̡"%-+4&^mg6r!ƄX2b,I(mjh'ck Q e-vYI&%zEV3drVR,xJT YTPl8^@rQS_GK8*o"ѼK!!)ҁ{shUzSR}2t2!C _MTQV몝nڀle0Wx/v n{B9R\< xzH9VCVj @[' Xpf2e=3z6Ө+}#TSk4=HlV\eG=cϧnYm.ɶl㳄|I#jћ^_0sy#YRo(a<%&+yM*tTF8GMK_CCLarP&e){TC]3d^riVROkݣ'ecܥڪLu)Ű;<@no3|ƃywXdͧ|v6YaZ9tt4ZXNًm*fP MYי%QGV" s(7vY*)ӤkO &pN/B:b:z:o>bLu;L5W*sCh)WI(u"];L(m**DVN:8~ Mi>[ 0oۈ~\R'Va. `s)ZoNkiaV$~6Uz.3U뀛  [GDT1~rM0klW3U9{r?sRw*VUF3hqG\[(#jOA:2~YK1iW}W}IHI1$|q*+}0LZ6Zr(R}ɲQدwLۗ6\Ro_YHJ$^~#bﵗet|P`3 Uz_UQ'-L:F+Xp@ş f f-2:3)Xp@|`e^ 5[tA/΄:p=9=K |} ^O P50[v;@YYК…7HqqJu~y3 %u`u2a~F@YKҟ]:sρہ䈙zpg.z_o̰ rXYA #*bp(;F ˙hcx4`ؕz4O3oK32o"}"Z egѬ ΀_h {pB{X;"<(^>Tt`* |l{Qo:;*L ṵ 2vƮ@=B +.QxKc~JF 0Q%Ea!RDNJ ӣfDqL'XzGը 1`.ߺRC * p}S"0Rh{͒錄[YHdȳ5:zBwzS[OJ OYTKNˊ$ݐ 9턢fƢ"o*+{.!0s)ězޚ9T%X0q 2P&? }4.sE2S9F̠/Pjm8oǒ yuT%S+菬)צG@DWwA{F|_> ;o8`#郌 jgØDi-="Á+ [f0?)4$!|4t&6:oƅ-pc|'obh{X*Y޸'8xGjnތK+Hdℷ~?5ؙ'*oUcX{~*vYP<g%{R5ٰ.x6ek"TQrFR5T(iET%}fG2HƘc@y)OيIz؜M|$,"˾@F&VdS.cI8O[dh@Pu7]Uz<,i:R *fI\WmXoz㖳:_ -OsNK_ H3$>J/2aSDx|!#92YR0h- G}SQhFUCzsuI$@}񮞼%WANy o{g9cTM)㦤A*2DޒpA*HuPɆv+.Hd.2O!Xw\5Gl\jk=RzgA<$'{FQ-qxlS-(Xz÷nOyΦ|vxzKk~!e)|8cЮC*F{ " QRlewJ\xw|ͳB[ *A@bߓ0x>ZM$~_t̓Y%t;lo}g>tMUdQ*>Mse%tP WsUqBkqW?M<ΓM 3gVo,1+\{ލN &[3 S篮ce:i>'+ c)Gr<5w-_ۣN9떥"^X4g9 Mj^M"3xdcʍroh{yuw Hd:^ŹK&wwLص:}Oz#r7\m]nlQW41dmؑsv9 {7לּ)"n+ s#僛cgȵ$9?Y2{"c[~nyz5MЎZf^ NlMdѪ3}[$) ;Nd{/&c]] 2)}C%b\8- {.oߤwޗq.eKnu=k{W9_o,p!P߷Bw7.UC }&3aՂ RͿ[y~ɝ߷:޺͏)bN 6p^StC)".ZUZ"{_K4}'r..&2c /ܹSKⱲ?p;LпapLlo%h՗T%)E |,{ W"Yc0p3%Q?&XR57.l*F i񘼕eKhS%b>4{& *(Q3x}ochg|!.7;.P2xGbo6EI5{"[96wB)c5QTɜxڣ'NdZ7&NǏ즜eJX`n2'5lLH6MbGX 8Č/]qcT]0sR`SMH,#;%?g];WOo|L&-zd_H%p }4j)8sV.U{J㱆H5v&kp+\^9P|6WLW#]Z^$mϒE Ա?#+37 cU"k>jLKyKI_VTR =(lgq&O?":tjOsD3Rw*b[d52}8K,e& \%ZΜۤR- >iUIjØL\00֚%e~#V*.K'̒"c|<}~)R뚸 -_'{® Pq&.gě{'~wk MȒ*⸼mgDM[G)rh:X;T@G\,jzD 8MXeaLyps= Gw@OvqlE|ZQ-sU n[;x*Z_5nuS.#2& XV&lVmߘAI y(`I@ K>hh40ڣl쑟o~AWXC  sI9ׯr@ZXd1ӧ ̒ ~' !)&gXPRUVo-4%ߛMFvYB eƚFJ*=yvOۻvrE&E&KB4awjYϲo1JNYI<"lAu85!|k0J*SVRwcXYru!PE- )d^޼/&qowu׾/fr2YTi./&,D}fG `)Xp#Eh!q7c ׅGJСuT#'"cqO^ƹb*JBɴQZbHAwTM$$ьɌBe&=s`vslamWOKt"T&ce&W}rXEĜDλ'mϣtn>JB7Nb= ebX]ǚo{n/;߷1ELWIꋝ5HdPcA@q""鞐?ksBWOb߽::: ؂ZkY \kbR\0$U Nw&ZWmW fŔxʻup5C\|Ϥ+3MMLucb! q̦`©8`>g9+*4*\|{\s -/fcLn =6&)E\gl~9J.Twx=]c~ )ɛyDnnȇUdEMe Ќc╬$fx;hSFz5XX>"D{h/J|d長HzK,#pmA2ZH>KaڪnbLćaTJT9V xS$i=)ZAlm|Km#!- $ю韱D2WOf]aXO9r Zp#'XJ7  i%$H` @gl[uxưt~'"WgzFAFdO{>l*OeӲ,|l{);;3/v]ӮQWwK۸E&_G,63Jp B.mQ.,3 uVd# QkRϼOwBZl.(k[A(m3V䒤}#vLhdѳ UaY?%cTYVTs-3L+C{SIn?G^,x}l/glV4xyp]=OB'3 5!F8b[1Rjͷ DcDX'8Gw%bMG$]Ӯ2;: ӥTƉ&Ƭ}D8e-'sF"Urؐ.„Xά^Qjkyaov$M+T )`QwM`?gJ`gfuq@Q 1o<',o z/-td4صBk,1*\2 iUmۑj%93̔٥#P3'[C';'/b,Lyl6sU6UZfتq SړW&"\L﵎'6hRPv9"I^q|AhbHg2M s>Ő7Υj>m@Q'YET>!>_e([Įv?{w돫Z1[u%(\2˜?\6Z=1"W$&\w42^'m-:״?T4]yg\WJ񘣑6qR1c+vD5QG(CYfY؇kn^.-r089V{p+g-hM-%1S!VOƖ4'Ҏ];9ɗk ʇj.\A%\[]&wQIM L5HIH$)kFoXr]{Ԕ۹Mz:q@yOI˳{X ?-d " 0&YԸ\Ap*@=C?aԩSgb'nS"".]%iSwI")+$9CwDz2R9ӆlyE!hIIŬb§xͯ$5L p'85.r$A$$E9$9uRrjBi>C7-c m[,y%ķ>X|w QDf6v#~]iSEǥz*$efDP[q:VUUJɼHY9NF䔯 )1HRi C' 2pi#sBGP5nA|0yYUI_U2C"-?#m3`StGD%%|KBp;*֑ 2Qy a43`}*aZ6OJS~&8FOglNl$2#pJCNҭ[s~Z}d#Hu`q׶I23^>;1f*,_\y]YfY'/7~EQDvf鎯2%zAܡwb``@Pv3й7O`uhH0î3x!+nG?"S:+>d䑚g]9bإt|#QGzcW~A_A`ILxMk}|]ՑSdɖ;`jB aS6$͗͗d%ɦmMw[,K,Y=^oιI93sf˹z}}9=2HN~rOh$0zSfZ.E 8C.C DZePcP12 ],)A>|;o_"Mr\MPAP lhy?U>)@R>w3M 2O6 RMK{(iAYH"2Ii~+Dڸ2'bL ov1e65tS*4.w_@ wO̡$+M PBih+w0(l:ɉ5{q://cbO5Ns>asDB-L_^Q(Ok5:aoF^h_De>aOW'^O`5RWqw~"TS^QatxVĦ/KlWJH.=9C>MW\ƉZnhk$dꆝREt~Y;ci+cuO;S&-V?tB0 KJryihQTd2GOVNz3BFW}W@1O&:n!޵qauчLf&+%AѾޠ𻓔D3QZSf4.Mqsڅ41` *gJڻ@LUްsLCUb}fwqFՇM)*撔qc9Dk+{}Ro>!gsxAhd vy5*.ȼNcRӛNp?ۣgwE7~ 3ڜ|#W`G&(|[~>3HnS?W L75yNj2ޱ}{~ Q~{e^l8iݭƨ h7.5aeV5c.(c tZSRN>t1LrJJǦL򮷦ؒih`F.cjiۥ[s3 <0.3X \ t 5:*RsJ E>Kp1޴L]G-5#vfb)Q FG%/ ?Qj/ K>t&oTǨg'9' _Dv9:LFgwj2^ )Ѷ% S^ ֔dupf J50^JAYKz)+  諉-hwpH=J_S>z#kJ6.hׂѾn]j `,3 qdo9+7`5(o<ĹJS*fǛyw+lX/xnJZ̀.dݷ-.MH3&k(k7psE!ND&W;zvLt ;5Jp$A& 2ڏȲ+rQ1 ?U v{Cw#cDbGȜywxRw{tu7pBv5m;ƨhYYwx8J7x "%<]g=MqoW56m {"`t܅xD+u5K!IoQ, ՃR$9 X~ZP,;O$B1s29mXxjoc!~ VWNj{/&M "yiӫ/q(ֶbHwF OTQ-u&ICDiM2C ͇cUш> u=0r o B$?:VRO^k'Č6xW:@SC/G~}_@ }'zjHrBj6j7"a--~F D H-sJ+ҟyפ`fXHWi_ ˧Fjwk49n2:iOkXdISMʠq_E'{Ss@ɿtLxL tmU;@ZV|+9rfY\yՔwϟ=V ):]mBt)ҫD(pX{X_'wƋZ-zv}?D)v<ѩE|7Vg  ֮|9GjGֳ@tP*"17N8 C!"UdCk$ow`n wv2o`2, xzϱcOXKE~Q2M!'W$";f|=D0Bo[f}W&CC)+u=Gz6 |h\`X򇘆…ZU\bޡ$zɝ% ]8I TʞjּiHKʧ29S߳XJOXK~y^0&k]mX憼_~KLFEk}_Xdĉ"۾l?'PW k 6.СUޭq+7.wlxJ %O=}5vL۾MӔpKߡ#Zzr}7S_~w 쯳fwMy7, Kh}A5#pRƌEδOλ=Xu̹;)5wPlS zܖt7r:w? XswX!߹dl "w ]LrCv+6,>,R_9sOJtTfגPAJIiQٷg͜K8DŌ30;ݶяu&lDY6ܹgq_4;SDisCYbPf>XW'{ۮ<5鏴'_pLv3/5s}޳{iX֬)zHpEr0b6BOCbts%N[z5Eqr1ap=Xps?=O򑕟g͏!mU̾&2̅s"^v\@c6d"RWM9s kCo]#ᑺjquMsn/wϑ[$5P҅PI6.Pv Dqi9i?n=j)nU3{E Ev&" wYϩ]RWQ26zW\۰I&'XžΘUٽ)Ou{\5/%"J5L]ey)kl?ϙ.]d񽾣+@RA=WrBNM3L.ҳs],(YR(BV䰘>ƞaVm>)]#t}^RNHsMϖ;d{{L }sN$V<"&ߡJo9ݔ[%Acv%Xfwr6X<سk[f!ޑ'y΋i%K{d"1%4՜6sҦ/Z9w&%:{84P St85~E՜cAY_?j)*S@e' )!+mڽfw0{ dο(D,=,D![ř̅`O.w Ƕn9lxOwo<ͻgϗϋű3kzvy<-%+ s(Ha19+v.;Qjf !6AA_ٹ+6)޺ʧb~=&+|{x948DQ:Gi0OMm͟m^@־>-ц8jd沅Q;Fv 7krUq M7˧/sLQQFLV&~NgeXoŞS1aO|xՈ)Y"Dpͦz#/Zkջ[R[YE,+Y1߯xɟ!Z*șH4~D3rG 4ei)n VI"(1֑zV[Գs3]Aq@ewҒ1IU|QlZgyo~̚w\eSTKɸͰSykqϏO׬Kd5mvD9`1هJoM1VEhq;qL(d%&B YֆdSABY%|܌I#_U(|Y~țlTp:}<+B礨D2L9޽cKv^ޑ/7^ٳw_%&E"*ŏ3DG$Q tJAe9%cͳsrVh.F8&|HɽNjmv+:ba7KRmh۱*9 ۳:n.kqQS4ww ͠) b{HO+sE4!O\.ʲxg ²ܹn(6lzis7;fUhcDOe>C<¤J|N$Y2f="dD(9_ CK Fg""lvաUX3ogk\Z+}c-'[uLy$u-fgj)S'L6L3[Hs15GQΕ`lқƏWq?}g9!fOΟvNcΖ;"-ؕ鳾TsF]'S]e3ES=B8טS2SVzj13孩3Ot^SLёf+!wLW=9'd gMRrN=;G,El鑎::Ԝc/CdC1Op)}oK;!ɜ;ثD9N#h9wxJ9#̔1kt3#ްU\Q9*`Ms&͵Oмgx-355{˱de-S%S,ŜMz8Kn9oS D L˨TI5xf0e[2v8&~ۚ|!5ZӭюB [M5Ys XZՔ?ْYٳ[sB. DLrM1Qo+^0V:]Ń1Sѝcof+(3O*ff,RH(y)Sh?<UH]Ub69R YeԐ>$Z#W(BJŝe%$ɕ#eюdjeqz 0J$"XŠ1g~ĚKJXh2f*yh*w5~.cgĂ9wrw |¢BJ)8޾;"8slcd+\fڌ;%gNtq\M+wL"rHuߗ[*wn8i-gBBT;͜3wІYPc}-2FΉrnLO;\<LjnA4K5XL/'RDS?1M믽~_\RM8k_kɲ4泂0/ȿ%Q6˜]f)g/) >>s 73+\cfpZ[;~Yr3p&Y,[<[^B:%I9d/dm6' p<'Qt/.^Ydph.95D:J&&;m"Cm598Ģ129hNdIXg?ۚbҬìx\0Ŕ^D`u_KN\hlqZf}QMt:JWе1c7p$ȉ)I3wf}xd4Ԅ ה9҃V(lu򱖼qRIYZ_'+kMDa>5-QsGƗҲf:vQ6L~eY6~%I" X=@3̉$j):WG 54Jhoi=n_x`,uVKީW$<ɇFmh:rDeUo&J츎Cр5+Շ-  @q&FNzQ+Lzi}ɨP҇ޣ$h_h!^!hJ@eFP __hˤ4{ZuNWNnTs-BJVr25WvBtsD6: >ˎ8-RLf8qEdc0^@ e1M*=g1dIF<_-5 ,Zm~K-8ƨ1[oMEl7v S":#¯74$(Y6^0XJV$ FaPzR,) GgjI2nj8u6Fj-G0pV$OJʘ 11*_*fS)w"Ufgd{p%{I$\Q1XAf@@e 4t,jsq#RI8^ `P-,2]P促7fwP =$ozKʴ.Ғ+:%Y"ZRK?>  ^P>O2ڏ&_r %mACfiL1IR< O˒ 1!kvX&D%>D$.~)ƞnv1SFpX y>zFjt_(OĈQW52hR N4֡[eҠMÄ Ŋs +[978iAlqfv:Jx|c|]{ˑt?AEſ3>$$ 4EkQ!y^xݙ)lz,1;/hY=_<%s/nyQ~)㽖62i@w'ݦQ ]nzWpDFf9~eQN >Akm˸ J2/x/$;%1eR,=!ķM|gLO8W oW»1cjCTʾ,=/LҢ^-^׭l&mHK WVVBHπT5ŒFv-26fpnܩc#_b]uYW8n\JXs(d.>Mp-2ڄfw;L{_9/iK ꫻;ogMk&I U$;F/-R̙GeMOԁF0fK mxؐmn'zGEy$u|M&:z,A IdY@,PQ=3bH"}Z4JӛT5aM ԻT$g?B(aU#w>j0:~̡~Kp٩1T/Pd1HsV?_SX"[J$ޑu|4I81>饿=)~uT,։W i54C[ih 6d]?8]/b!'sl7Kb1?FJd (,sEZз:E|_;2f3c:М$Hs7V45\*cT0%2ktNY <"RSuzq&'i$(8Q OyY;/ڨ2b4rӊFr s()G^@/|1 /E =фi< MA/DdJS ݐ_AjuX3uEPߌ|HTumHGIz\=6Yq5CUX$_~X&a0zrt<ﰬ^&m vP:h͠2;"\7olňrp* ѧ8.3Y]6z`m,ࣘv3 ~ȴ|]yhPwwǰ%{`wcЮt_Ey}JMGCB^:Avy3MAnE,FE&4LZ*zK?\N 'G[Q8]kc"F4E8"p)sB~K;534'HP=c.jȠ6݄tibP +9SSmJ7 )vgR>Nb65wH\e#xdY*k q6_4]I߷n~=1ܹK!,tIhAC~ꪇ⑋TkSIQq4E8;h-GTMuoiNh/UjjzXjЍNO٭PVzgr\Bv<#yk#|Q06ڌF kFۊ ڎ>2y9_S | zطO??qt{Îغ %9Fc˱{^}|8Coh b0 *)v;ciaR,_>j^[ې_dŐ(HEGsX&lQނ`2s\+܉r_\wcdo?) -{02X{Nc8߇ů;'~ K6l¦S5 ěv㧣ieT秐4<'l".Ho.g"R^:Ah?-|xUg1_śEqe+:qÇ=d:Ml7௥GQu/!հcT*onٍvx5Mށڝuw~Oc~ӽ1bE%bi>@Mӱ~)V;q=6.H쫨:fszc(Re:B2{0fRRj˯à8Y"q*fn7Þ8 ; 1tWQ43X:rf bvd 7CwÆ(rtoWn;NƦU`ŗQۃQ#aQi fqVŦ(p32Nz[M7ƌĶeX. swgf\طyQ ݀Ï}}s!Ê簧~vP-h+q*ףA ^䘱bDlTH7jL(zjǯڌQȵ` XEx?$1T3Z`z9H JV8x P\>TiTEWut9^?QES8\Mh2;YcG0gh6 Y:gҨҚ Ƌ/t Zx٣D+0at丱c bku|\A/8r/ǚh{՛bpT5r(4F¥blُ %~ F,Y~u1k=Mş0spuT q|TȲ-GOoj8yO ܋Lx2$ëv믠 &Zc:Qb}kbHC]eĶ+籯?! ZEd5j᭗VnFc#nm s1Dl^E8ۋIc>ywpwǛ>i Eg[a?wi/$ L!v/繍\qLN,Nv_'֮5qӐ{I,br/<'n$R 1y,KA\w/Zb4̳/mJ ZOv5Ex}-rb H-x> Z0N u,l߈*Z{|(,3#X n^G[7n9.$H~^N?.U%X0Ս;gn> 3(ax:ь1pXQ"&ܳ]k3d}8َ ΦԌǙh Ǫ(֬ys1{4WSݑfBkn}y2Uk"_Îjr#ތYpLkzgm8 +6P> )fT?؆o3V`jaVɃEst,B:|Uz7F׎݌@IMH M c1yi_5ؾ~&֯CZ>"x,n]hnPQw9F_+J`|hju+N_ni917`uL@ڀƍkvbHGYSqMCI.a0"_t̬; 6UV`/X V3c " ArQYiTl3(-CV:Xiv|(@cr$\'C3$T;eIM9Lا`vcRڻPD^4_GwQ%7C^gLazP6+iz0#?|LMINDG]J!tѲ5CO1=NafCqѣ !"Bc$3ߗi^Az!fjhz:Uz9==ׁ^8=Dav#@O#WQPYg?EE> j[Dzec=m aMAe&:AY7yXSI?/M%bH5g8)g _ R~No0qL}0FlcTBޗ!ۄ~F|lCfhJgq>lnhiJpbQO!^ 1_x=P 4tQCbȦ0v,"n׿T_]jqZϡ |1;QzJb?D@TxLDz! dÇ U67;mn8swZƠyBϔ _á'mQ 2WS?x5&cb܌i3[C˄K=3b2]Sx!D\XEʞX1xۍ4Qon y݌fq87~ VVl܁VL4sDUUckt BN`Q&M0'vbtbp4k-;Nb\tMM(=G3!%o7EKsFZqa.@f2Sksuc&?s}be(Gih FqM#C)D\?'cvDCph@> MP`b8׎Lh"$0w6C{?JǢaV\7;*6 ,^IS d</r/۩gscX a  Mu d/)ƾUh95> kQ4x~j0en㛱~7f߆QٔƌƮI3b z0g=(q #s8 ՔO8@wGpgIވ >M02UG30p¦!̠ZC}:S)& \a<  CrLCQرbx6m?#cKo+/CY;P0l<=5QĂjy r1x@ 9;7"܍Щ3!4vP͐YLU@݅D>V3G:pP+9 ٲYgJjZ()4$@ \ RtTZ70 ;Waqy?8lGO*wl w{M#91,dUyl{%ÝnDvJt;[JoouXm=%zf+{1{L!_d 9zNZg7iHoI}.Q͉ WǎFyݍTN0PtohdnXLQZJ-M/+zC6[ Bx spL#ɢ"l#Tzzl2iԞtT&|2=-x,)ۦO";& X:q".ܻ3yɾs=82lC +p|4T9"܇}t5cΔ @L:'~Ǎ6ydLfK'ED"AL گ 7h999h>AqF:L E:"1%TAHDWA:IP0Ls'LF%FSJe =)ǒx+Ot(١zDX ZCzz)B%QOlҋz^J%9n4!6cՏF:o8'Mb15{\ ?HKX=JBJyj,FGbA%P^Sk^BgQLF4Eu*|1sxu5CGsh[_C@bA*D#'J2?g"CQӃ~]JvMO&']&^^u֊%3MnI`MO5Gyb]4ML &F?5FH CJ ePDό%Ľxi9܈I%>cQZÂ^/< `9N+f xDV S,D FFe6r !zX:AVߊ(J7Cb]BR-YHuID*L {T>{iž5X~XEBԓ&cT" =F Ӳ`+^߈GShӔj*U6ԡ]ihكXƊ^ ÔtԒ\XeCc^ @iIgW"sbpHgx .dAiEIJ%aD./QF-yaEf v_Ln1|=8:To\DQ'\cr Mfc>&!|Wd]}]$z6=a32xBI)J K }8XȐ/&)))vݤJB!n1*Vw|d`S&S&Fp2(2S.3a{i <-#Nbxa _9FGFF]FZaļWG,-zl'g.F=4J ; q}4tl}fڀO"ҒU.>ތbx!v Hjb ߆Iz%/}| dxsCsy'zV((NkX5{B$4'mmzچ1?>hJ稷knɢO|>|w`&L5eB~5L.t߽>{ZJ璬DF]b%__\ϗ?L 㰂9`\*PB}ʉ}ʇ'3ČanwW[~Uu12+A)Zї?3UWlvX]3lVṑh.֭ݕ{F/mV~NVkjyygܗwZ;ߦZo ÿsћ|)O)ބ_v ,9{/ʳ@bjgVkoQbJ(9 kg[rS4~K#+ݔCn "ܜ-DZܮN^qp_X/$@WYϠ٣:͵\> l eD)T5OQ W9u_@\z Fwtu#_a/%zk=<4dgщȢ\@#! _2Ưnpuvwg?aSꒂg|,sؿ\14!KG~U,g*,Dxxdf==O jBYDNeOnxqg,DW&B d_鬷믲A~plu(̣2B"R t:-nc1RkEW(]b7gbP[>Gd793txǨpi;pKPaMC0=hd܂bn_:r# Q*21.GH4sƋOg_Oxqi3#n#YN6S=BG, (j'XgÉ$Q=fS<fTؗ"iMTekx+ͺVgдW00nbM-TjY*H%fb4X SQ V˄'ʂJ@zg3~&JOVAi Vu͕acɤpŭ Ǡphdk6z9`+xn-" .|*acAY̸M&Yt#Y5!Z$ }4Ҭ+{⎋=,z|ؿt2k{cTUH/$wcJ F3_SZn1[)@eB3 A|t=ݲrŸռT -aC3'QeJRb̈́ɨC,SB66yff@W 0{+&Nr`oYk勗dxӖ"LAO(ҟR7˵fتR1`2Aļ״pFod)׫Yrs V{ЎK=*p v 9!iİtlr^U:33P܍yX%ɢYpBm7RF#[*ұPrھ%kKӎ]Q^C)q}n*CY3ƏF^h#'Xz?Y.^ F,z}Xb1U4OPb)饮*̩Q('ł)TCԆ eMiop;LL?6gP+G[咷9UU'ȻUWB8qcӲbm_۷$/lfȦWB~`=9ތF k!iR䅂*%ąR^)O[ ۢ뷜#wg%|;~ ?2Ҍ0LZVҌӵ8+*Z;idd50/ي6 NU6ëy-l߭hD9l$g`T}1(~>*ڌ,=~#»'Uz~8f#ɘ,(nBaT71uͱxyiG4ĎmlTKCL"*KVVCƭ[`E@Œ\g̝{A,vlN`?&܈z=Œ8#D/wD|"ĉ<QyqC"03BZ_v \m8y%jv?(eA hw`0n.1( q9۲|![leo#6 ǎ1k8a‚jNO- =8~%Ɂ| h 8ğ{FF:Yt!Q~G bh(S + a±T`"9E,1[R I 0ڱ|#≧Wւ{p$bdg 8Y@HNExmXpaBFCvD@.B+ Ϭ?%ghXA&YB Q8&<7X Y&<i.Tiec*DT 8-8j[p qڐB"Ţ`oCv=|Qt&A`8.-621~+kĽ%Z|>pxB7aL":,DَySQxkK(Qрa67^JI8EڦP$C  'f'w߃@7Ngת9߼~lڱΣ {R:|0}$ N ՈK{3<[Uغa+!mPwp: 8kF(KaC"Ŷ1""<6b~*_vgL5T1k6n -\ *.k{G`=EMH?+sgDG/'S.~P~4c{yfhK QS }r^~G2dv ztG`NQ 3f`DT0!B"$ j&ͩ*N DjzɚE]12Ε9lX` QSAqʃs˝{#y dV$cܫ >BE-$v†&т=nQz킯F!`__# tQ~s3ck3bs] 2[W5FP;O!/c>j떡ޅ=8;16ki#djs()%=]݌iZ6VK ;hp;Lwa=: aX6oul7ǚ[~˅Rk"ގC<4xڄǚPm*lA & yX|X>z-DQk{;N!}?wb^̬XOUjhȭ *"sXt<7xkl@|Q4$e%r4Մ#T5`668tv`DŽ;ؓGVxnFlXVt%^ t5P]_h@̾|K`;현ѓɳ7QZNGSȪ0[1lJchrb2U@2#jsDue13gpxwb· 7v(UH.X55ܳQM;m#>[l{`5d%j+tVraT.ل:݀uvڜ6ӢaHTD-09_.ŗdPqd NCQl?=QTkasi"YQȳ`O:-GI=m;cQJѹh^L|D\MݍӅX$F Ŝԓz4ueG@Djq!qK89`M~C'aX|XJ@l"Yft!Ȁ v )Lu5ËcP΍gì(6 ahzI{bЃǟ8#s!j۸k-/Ʃ,ԋggbj9g%g̙D<c)3X5 ^yz>}cb*Ξ0/xELE G!K+aLG1.9q3Doo$oAGυRJ`:h{ L4L#oa|ʋp$Ę0/= ?w{s/A\S!7T+Lח>%gᬤs6})x&|9Ǹİr)m&]TAp0WeUT^-BK/|'czx3&_ od{£Pg'}/&^ QNI %Vۤx5voȯ,_[ P/>΄ qbܽp֠5qH闕Ow[4^z[e #[ނ'_sO>@C_M%7xAqO &PKx dw3R2Cct[c-*0)usNIq|3xעӂ^ϾotI[7p#9]W(+wmڅv'$Ж&G:=[Gk' ]! On=Nv.WTMx'V$|@6_y9Ә1/= AaX8-(@nG.dƎRxo%vaN& ұ{Bط_I]IFhSGWdem̐O՘4w9{\Sšy<},@S V$)p$Ʃ#Xo^zنDD;قEm\.:  -!eqHOVCk 77#o+x;S@@՘g梪E~b~Gж~Y uĭ;Id?9ϑD#Q LǠ$U! Kx{# GV(;rqiV-aCPnb65E. %ڹ%Ghmk>Nlr%oFF2(엫Fnx;б+݈[eHˤi%aN%1??.&LĐ""6T4Dݷ|?m;~G4b=ع@unKXI5oӒf؞J9~+b*Ôh&ÈŃHM` ΍0-Cu#HLS~4}_W8&܇I%x6b;m$0*į͌GbA$r9Hۋ PӱLna1&z!#cLEPԄW':.(d 3$3jD~ eџY1\"*7 ;dz{2CB{t!|ZVB=6AqN >aG9tQF/p' Cd_*('&9:=& s+&WMHahbX"%/G4qR\!"wFARSfko G1z0#k+M:$*OsXuK~;BWwҋ6TO+%>o~QS05Bw/(BVcqZ+ 5 sy>roj#hkM [c>>#m` OǞx߉MYi6Q HDP)ze% &'sNuQP&-5nWպfKVV}Yung9.EcP DxK84R)6^Ð#g m%~L(=1o2;`A Q$"hPncȤyvxR(0~'膐F| cGSy\kVt4E `@TAoY6|020gc.'1*j:]ݶ#F->"ԃKlr)Cn7r0Mdֱ ֟RݓyX>Dx޶4Z#"m'+F3eǏ.5AƔ"Vnn9%hS#26brB=<0٣ŰH@@.YuCFGTb{`h 4v*#`{@aiS$ihR'iz\,8nk&ľ8lt)ȀX o2,yj)7~&&dx_3:IrFAd`pcZ\h:o1Q,q$LL"}}K&O3*z`f~QIoD_~p_"ѨQ`\L' KaQ,p2Sq8ߍ1MihDD˗B"<νF\<4C_Q|K``>4܏̯CEw A-8DSޠChz1Ip> pc>,2G[ #$FCcV$5b}w!Xc2? "H8øt8 305"Z4k|\C̹2rc|1019q!HN{#Vw DZ4O5$<6pJ Ly!6P3BOwmT:çp'8/8hh4cpIu͘ClӨ1v)>0!&bYDXuC&Ʉ3é;;jh#0{2ZZn0Nj6sט2` dwq2 F+:nxJH9;EH~aWU}xヨ3 n= x4*"Fx(" Zkե g-6 HOEcd&o@vۊkYe:/zZVϋPrs\*vS@]W THI(OO+$}G.xf S86pyN O\ID(1J c%ebR ?_ ݁4f|5.z+eT65]5E.IV`Qof.zOQ߅{}Vۍr>1VC"S,OEб+Э+BF9 hZܪDDW)QWn&t֢F呣SBͲ[6@̊{zWC~y"]-Nz}1*Ej75|AxֲX{pN, ,6ҨA!C J^I$1,5vBK$` H|m/K L'rUȈ+pePd[{VgQҬ P}>ŝkQVz `11in1..y@/I-tVVvՆ_* #2Die+.^%ƴ>)IzkvLLKt1mt.Zzg(ޮ)7cη G&ӓ_DEE)Y2~uA Φ[qh ;olPXpn{7md+n~v6&ĎŵaZ.3Jt,Z Je^@O u_87m.v;(]un ϜOWWԾk'e]@lA5D/aF㠖h!!OuvkAjƠg?3v{|w0K5Y!!WteFe=}Yv_Y\a0R>T1L ĕ1n-߼+ ̏@Y-~? KD+21U71|I \ U61L@t3LM_m07AC,` 4Ƅ&.邍57y{r W-IH\į?5ں\3\LYŘC߈8K <7Uz$)),jm=) I3v骓| OH$^6K0~VCqHZA#鎝0f!\oZjи$\j M<|ө[hj_x&sazY,EORu:u^͑2Tn嬉Ȼ9nfVƙ4޳!krg]#{MQ|q׿mXխdhU5Y!V&EaGW cqPکJ+|a7NKQaZޒ^*Gf@V8m--?WmC.S~!~97TJqIjk]daKLpRklvrdEL<%UWF+ 2de&  ]A!BK4ӫZ%USK-\ե鍏R;QӆDi(*wkBKKD(&Iy;Ŷ* D5 (X"V`i.j)RI$w1|ASɩػP2,X\"vႦVuz}:2+J8"SV%sho+chLbNN7w !Q^LyGAS;  =Jާ ewV _ޕh WQK2WF<`L>766[e =B,'jo;((,'p;2n<Ȯu q#86= x *rqIl;tP\¡TG"a،?,y(%#EN͠.67^lKyәt'O('\1VF Ha;Y豣 ;Z۸U>@6[j6!/ub$w}/q'%T 6átvrpkY١Q|;G;DSvu-&>m2uZtVH=Dx t8uhiJz47pKAZCVDR̝sH=AHy=="UHZaESzpS+m_ED-;KԺb+EV46zh6Tc6 ih?I),9YGXݮ8e, 4:8 y\n蔑'rszTP̠gk'H#"X˞3ē=S1׫1a5#k/!RX]LP9RSmKwmM>i(I%vgܙ<+4jH#"V\s_MGAt,ػ $^yq&% ALWN߀𜔄&˗ u-EqXo]D%ar?)⇞fjyn4te.5U8bkPGA^NYY,%p6 N7lj Bǻݷ|<%xo%wQkŁo~O%#cU ƻ[ۭ*D*b%\hWMeIlZ ;( V|2L:]YH\y)=;,VRGL$STVMyx=#,c8/ͯ>g_FAL a8UՆ[HOVlO$5'S)_8}^|dDӏ=AmؓxAj}O`, Pہ!JDk܇G1+{`\ Y/SϾ4w>DTن.zؗt̅(MmZ 3ܖ?H).W-v"3Ob(F@80p&"/^~xn:LsJ6=qkՈ%F[]Ŋ SD֙<8֍)8X7)ۗ!6^{n3ޫτkd{k0V}F?f kWoC0L'ӊ`6YU㛰ރx #CV"pX| 0 }zK8Uvo2ﮠe`sou>~4&?"LEk'Ф?aU1r`"eUjdǀIxjz+`1 6NnDf9/{t*'Ӂ?@K~g=4"?HLMkx89F`݊6|,$$"ڰ,qxqZI?l^:™H΀%? Dbڽ¹FUݘ7y+8 [40l1o,xcn$NןDU.CSWy.h0kRWx ]mnZC\ëp^^6oA?|+?t,B,(nƔ{p4er3,m'TiǴGv k3LZ\@A(|NzmFS5zC2k˜E?}ظ A?}$^x2=^x^,zNA7ػE`=+7aݰ#q:iK,6L\yZ|;hd;n;V/IגDnl\M/mdtfp'~,z?.2ނnZ9F*Qe _' -+a7D 2.4c`Ήֆ Mc1:#S;;"Beukq39e1Yh頒j@ZiJ/Alq즽IdjѧW:uEe "`k (1V'OT]|A~$ |]*@ןbK1b\<D}hd+ k*%/L@M "0"(7TO,Z΋^#dU8bk0926ԫhL˄o @BLD c;FLla|T WHMtY'N zL OcXW  U9;EB oo!(uq"{hԽ65 %3ycbp|Z1o1wh>&݅(:1<!#D(&-8eHדGX_a`~ $И)r/jPOم a9>̏GyaZ O$||(*H$pva *϶"OdW.%0c~:̙ /IX rp0"8&4: &>DwA$׷]GUոZY1w9SqBDp4ePx?X4sih73pCbMw`> e s ;' bJ8xd1r<pVwaza vƓq$L29H C ,}%8݄gz)9qxP!4KNGN)PX Bu.‡CIBB@=e6*OH}TAxl7č1 FFՈ69 Si6c4,@e# U213WGl7gd+߆ԫ^Y\z҉ M7h".t4gJJ*6a{zz1t2X"x0z4)fg 1٘.JA{ug |0>붑{dX]d:08 '1(MD&|(띃Z0]UGnuh{Δ2t0ֵ8]zGk>> >a" Ȣ4໰h *bm{/*p3s(F5 }~Ҿd4[־@SGmvߝVyTن3T!P_`Br!Y"jգb>pԴXU`^IzA].M#إTKrXs;w@P|$K2zJ4Z䫕د.ɿDA6,B7Q+LQblȃ8v@8U_zQb_Da~5ctfd! rHM_н?]V'aa%]ڍ0 Dxp3зy+3&kp&|y z"SitꭔFSKuIhTyT8fEdS53.Ό9a|/$CU`XYY%M=ؼ%n '2T~ TQKVdP w;lŸYWPP0ShA%HRk5@X|QIA$xPiDYVj0qśڭr!$٫Z  Vv7Oph4nUzɃ(6?®ıRS=@Tӭb.+rX59S;f>$N?_徫)KU8B9]rJMpO= $RzٜS4VkP_ K9cwc:Jĺ5"Fj; <1%|xAPvsF7`=(خ^r7YU0Pw/ڸ9i_)*v.~k21ԕ밫`@r;P}+BbXXzY1GhHg|mz_ mls0bfr(1uMFgkeR\p]FC/ί4ZCK aK^OSDO~aNivW⥢ֶ)^^E*S.Ro߆n^#o?g_֖r[:b4>l گ[_kل+cz b)w yTx--0S$숌iulp4$LRW7i in&#~> $7pAEo{QD{}3/Gd9;KL{>"_ éE_su>oQ2+SWNly$+cݱy"ȏx͛teLOO ݡn~mέݝoʕؗ2EQ~\73c{ԏ`W5R8 n گ0=h||fFi~~m+br+f/*Y0owthzo?i_ᘚLCΦ%Snϝ2Spw1,N+F~5Gp445v_\}9/[_gO4:J)щ¦@i)rbxDMaT2mmW7C ۃo?127LFp?W)47')vSM';GJw7p/5RK'%kݝ% QRFY{df+y}-fWXղ"ύ ^skr?*R<c0q]+YQ+`0ܫ֗uç( =]RG\D'Ls%cd2M ,B2]{6YaWU{#K4<}LI:TYrw%ѹ-fu%\Nr[m,aAVL&-ߕy3:5+~6f(FQ إU5%|UBB\FY(l*ˉYV hTM3eЩn11֥rH6ʭbatYOk?U 5M$RgrT1ZEH fuн器k.ވ qEYF84{6V`Vd$p &*EN+ckl'ʎEYH$D 3U0@L,-[vqk8T; }'v`|k|n0b,HوQE0NSOCFɲe-GV1}8!~jިJCN]NY3kѽh )IwzVktkU,)ȪW+ACS,.*3 #L>>;:R@Dag|F_#6/;f+LX hIQR6HLy )FjInsgw0n???%7#W&jUZ\.qEݶэG0n ;9"39Go6#!V|0kV!~\cH#3>Cr5/d7Ya9bx!ۄ .9N+-q"/ 7l#0 Og ̟~rwqv q$ ԤZ'!u6]pעFl8_-V~V="g4XmG}(TN#Dटo Cؓq! oGPVbbf4' GC>v#BcÑJ25|+6|Fp8ݎ;>]Xk f(|=A~jm"m,(%8X9>CWHk>]J ϱB.Rë?/xKR28eC_|Sl N)66o[v.l[J6~g&޼PPxF,~~GK X8GSg?h8*2w ېG1d$ ӱqNcc#i@ZOBN1eј1Gcp8C{!5wݍ4x!@^]{^ue^S"M w';vM2N$3I&q1 K:.=Wν`;$0>ս瞳>7(fJǠ%[Ft * g &тV#Ke>woy=T`Tv!-[BpT r;;a^bΚF`8Vf#pvf4)!xG,jH6 g⏛ pLĔ ïr{GEI.a,8z&EiBt<~N"|kH`܎v^s/BՆ6AvzpqoB qA OP4<`7E,8WN]8ս0N@uqF(1p8sp 3$ 3r5#pZOT!ZЀ>};8oޣl'BU5 ؾ ٱf 0Ð{'ۥ)5`0 lZ_)r?.MY u@ Bu8~9yh Fib=G[Mi8ݢ\o0;\4$B"$9[z 5Xp|n|*+K}QStQ^E0“Xĥ>7X^ɡsl'XG4atx#1bMG'XO-^V+CWmPl@efu^lO^' ` h" ./}PeaTDno"ܣP$$;!PjkBiAkx 0YmQo/x|>8*a=mԘ~֢ ˖iB:oD"!ד,5b:Kq-$Uj.q4/Qځ"R>Dplkyۋ|mݤBZ2vnQr6|nB'1񂂐`oN!w'Vڵh7"Bgu !lzlĺ71`ƲAw7d&: hGE+i4g7oEbLxsL^]V"v6 CD*َr1al`𮳘8BڏQc~nƂ;)޴H"|'h'؇]H4e&C}Q|UPwv,LoPE \zUo%da|vX8V!<SRJfŅx^83p6\a܇=i;A$Á0ыոR^QN8f{|Ή:d':i" fD'" M\8_gO`>|CyjEά*bGc,5VC^n1?ƭp8L&L`d/&80gm28K_ 2ů~r!\}x{+z}cT!|$>܀:4 b@aDIȆQӊ@_3ׄnkaǞ,O0lB#I1' ɉ,K5]HS(QX~{1;H: 2f8+03Og œE|z)1^Ƈbr2d'˜ D&TSܩ< B"rRBGU0!r$"&ߋ`T7JqqE]Nv#'`03P؄zZG ZBB^~:HEӨf/칤#~|}̟/ &KNN)P˅aw 2c9QFމ;uY\1kmi™3wG$^>im,Z`O= ֗J̜}gs"\])UY1gC 6- qdӵ7^Y)ܼ8z~xAH ߱x g#֟n ,/0g8ܳ0¦aMxnt buXǢ9cKe" r7 '!Q&?N($'ͭ2eX>pguyDa|sFrc>=Yxl}qP8ܻ [ݨqķs=9%4kkBv dq]usYUe0g4M&1?RVNh {$KC"F! }1O5V eG63\Ӥ jsx*Vʑv61rϛbOYy0Mdˊ2§b9xc00JX4zdvhx=!{I |Js7Ln0 w گ۳U3qXAT25 Z)LݫAȽDю E{]Oq q70(2'ݝ5؋6H׃fF|%gaK;SCۆr#1JZ\58/r{j4ςDaC!h:~I!NYil#IE F&mg>@KDZ(,T 0+p:$ Ɇ<I8>V&nqt~L֌ۇI1=v}[kajzxs;Xv3DC b86#׺ºZ[)d;%~vrW?/*Gį k·LRANk7[_.~]fr$q4&h(:8LLA| M2+&"@*"PN$TbgPXhFbyT^€2Jg+ЛQkJI+.WML P`4+~&+*ߎI󵴚 qHA`R ?rQ9K>;_\= h= Ù:<58p߁wotq7X֎˗Ba z#c0ZXB 3$W0$gEbyhԂP&oPU`r]90yZ5h1dy= ͢4=yg'/zm闳MDJl7aI }X=}|0>keLǓ>8f"FϠOlgP3xVs3,U6#tA_74!6 j„Ƅ\Sv oUj/BXS.1c^^;t*F7/{=PNR^RBQ)L nQcHv 'FF{co[ey->(.GX,FN!WG\jO\NոU{C-Ի7J@EfZUd@'G(TS090b`JGȪS鯔p)BJ7y`LF҇lѪU +M.@ 0+B̪ӡR z!8R)=UPDK|qjXa3*\N npŘN U"NڜEAzb=m e#L;VQ#H3tE5[\.$U nvRQUlP[\CmPƣt+w&ɉ]j@4F"[ 53 jԽUzCq8T>e+$^z:UE4|X].Ҩ2өG2P)z.u>)Kp y}ު?*=WV"F L>q7Ô˵?9v;x## *Ye^mH*lޣ4j_/ 铯2+O֌l2NgeXޭ)w7e\~1Q}U Idžt:mtv7M?;:Ny;MiԏbКhTFt~u퍬LJIKfv䪰 ?A z"&ǔR9J`LVruX.QƌMMZr*ؒ Qz<=-ExLEA5QjPeؼݻ):{yCU$eSu⃥22cZ(!ZY_Zi1+D!@NaidYͦϫ컷ۡ; CTTNӭ΃~D]""G 9QVV+hYUׅ a/%)ZzE:d^Β"FiWi6 SRelj%QIww,-tĴ;& -ͰHz/ $CL9Ѩ35 Q:vհVxX$a,8Yʜ^F+,ǞLNA|(_k¥7)kurcI]SjTQ Z]#"~LF0q$7Thľ={b$4W#( Wa.tG$M6Uc5T1< ³kKz$gma䎽*Z%k769 i*u?] ApXQـH*9vՔ4T9ݪd-|"ʄ˔?{=khA*@R&j\XB)H sj6 ef5kE=<A\8:cǰ v55;aI,X̆8BU>1~290utW*ϔ$|x<&="ՉD U nu2b4Ɍb4;q}K5+r+xY~HlyEJ#$ a|m"6YJROioV^FIAqN%Rs7}@BTB/E%T/Хv̫Dn̻*PTLFV*<61 tBJ %l39ph6u.A2冷{X;)ϾeLt2ÅYQOB_pGbnWQ"}N"k[ۂs`u% 5kb.^VXubc..)ņ6ЬǹNӋs@mkip>=elH_-ljGa!)KylBn4Ԣzc51ugi٥+j9HqA]%'A\ &$vgFNu[JiTAtrih䡲Ne]M.^\6հLNM9[,a_FwSKLHE)NǙ t]+&y]t=cS u/mi@ tԣRr*:]f K s[eTM\V[9BbZL$fCr5+ :Bա$J+ D)l\a^, èՄj[W$+l|gNYkԉ7"(Sbu,}o?*ù!(Zh 'q,B.{vnLu96R.;.WQ,-٘f=GX2Ң lNҪR ^I‘+DW#Ce3PQAXZ6T6Ʈ pV x}Ͽ>dgJN+ ߠ]obwQw\LTRNTOMb&v} nkEkl=l gi!Ğjo 9issɉQ*pj?E (+(FW?/Eq>{mڛ`7$`ֿO tܷ )ȻHTG;V M̞0qm\%?#-NRqY2\/Ĵ~?%Nh1@˗MH#)Db9L DY:=/_Ņ04_8W4IJٓL!`fgCeovk3l-iv=rsH#Wv_1giwh)x2YPӋi~kB` ?w8<(mÛHQv|4}EKo&z{_2j|0q;T nq`-? +6nwBo DEt9ȗQ\i+!(DdG-mPTsbv61܊i*+;>MdO씅O M?[ܪ_ڍ/܃NBZXL0!E-1`ƽE]x/&^'͏"6B'ZN`x6o,\J2L2cl_p?ʏo"g#Q0܇lC [pR!^ j l,,xu} )"8;‘<,oIR0+chl~q֠0 sD.HFy&?_Hf8F boӆĦ7BӹτgFG("cZbñL$%?ovbe67c5IW.aX4,ӽv&w/R%b[= §j跑.$i%-_N6N{5_.Ԡ8,֡K[_Cwhm%_y]k02 Q݀%hyw17k}f^| 8\H\ȦVz{o/;FEOBPPSAm%d0T ΁Q᪊O0Gp '|YF䮅|!{> {Ƌ/aYLWr~蒚amGQ^0xEik*C-nd5T{aǓ+{!9qx}/Pu/}Oyb\zͿ~\+ ͡тKU$*iklXھ'IsB_[I`7Z[p2uD$ OSA5$"j%E/!(sqU!.5 D 5T^Ki#D@.3}|gKp,.xAXވU5 <*YfQ\NOC,ĄS ;R(.ҦAxb& }8cF\sbDU)L 1>űj6#(UxMFU$dZ=OIql!K1=@윓8_ˆ]c/N@Uꉠ|>zˊx,-"? cX]:Q~" (niClvN;qx>NZfVcB:Wd ֭Kq!6bl0;c zPQS[,22SE9x`SB\̓1[ ӓ {ETB`btz?|#[Q ZLd!q2sc!&ʋK~`|]O)=s0. |T/ͤmwc6ZJ!!!Ej/yXqS{%玛!D}(Ǐ_o $a5ydBve;6fjjX)h6:샔;©Ix{&މX/.WaQhخRj ]v+ ܆y#,_{piF1$,p+S+O駑7~DOu}`mlbx9.ۈ@ys)A3HJAz1*:DO?xN3&}2/0EPTށ1H! 7}4 Qxz%KM8ym. dU|̰ݢDet/l[^puNmuN. H~_X"C4 S&,z=$܎h$-# .v\̼bx,]޴UWWMOajJ:_ aE,\G<]1ljӄP;fqHk-\^|wF{ BHYBxĘdrG ZM=s <{XwA38A MBqA`C 0),́IM>AK08%:i$Tʬ51XRa(bf: ϣA,{/RclT!~"/@|(Uph*V,@'$ikǘ4jqO?x`J*J `):d,r:Cإ3HBBN< S2X¡HgGg oD"Ei A8l8: KLL*q߃H㑖6!p@uPz 7.CNx9 /nLI-]{AE#j{I9s OX84y`0&,1< IxF=&M@.74Oߍ~Z)6T'V>`5B#EH ld dNv4@ ϣɀciԣw?LXs  X?ee 06 0o6KFt<> _9Լ4!8_c|p KfϲZo$LY ,ltVOHTV= :79YkN @/s_s H@_ZyL.pܽ+'gL,| =oNb1-b]$gYϠr4&b޼O)ɜX;&"!Z OmBn>/FrVm/&rhI'餉*E0O<_`>{2tzxisG@^N DuM L1 qr5nJ`P(MP$EX1@̙gI0jFvFw'ˆ1* ^޳EaF˙\dcvDUIQOIcoB*yBDןQŢtW&G<'fղ8 bFFRLMJ,(b}b)Lv%d r͒yCus k8R)Pv *trBMWeBpmr6b^7M*d}t?ttltk-$􏘊aQwHj^k\krXo&%//׿,~&~lf Onck}Ip6an4 m[:|:wue"₟}q0_Fxz)22Sf`i49[DsPCGswO_p25#nUУ? y_]Y?]cBaao ׫ (/=??:7:jȊ`ί^s%V)}UGd ?F,{>9,6 ۯBh~rΛ~V%2':9ES,J&m^77z]-H8~Ok3bs4V#/ںv͊|bl+9n߶XYZOu44Sgw ;j-?vs:DSbpOPcMx w^`/E~9fsM!.vۘf{P׋(߿vR[Riԓ0I9{ӭg*>q,cͣz{mA\0`?^mo9>Vh;͟0vB򣣿ѱ:"╺^3O9Nye@fyV}Fη$ɔ"ck3KeǓ/uJA ,yNbr-JPZ=)%vf[ Q5l&րQI3-v묨oC({FL>$Zp ! 5YkFúA#FmN890j\q ;.i\ĸI3$b?|X|N?D)LU}VV}tZ\6b `!4(KyRWx'eu߮BĦQD17nq(qO9ϰn`IL'1K=7ЛOFY!,#IOiaFul%ऄVl\XYO]*pVjJoб_%W(ݲJ<Ӧ=(Dz9ăPo,Bx7hfzQ.e:]FI0Vͭrso:>>r [NpNs};4>z^ݙ-?N]MS?`S-FĚ7^xE %`>!5Y-Tj5ͫpr"N1}.y]{bbge"܁|1h)g$X3^fN#8Q´N^'QN%s$^:Xz^&֑—lLf@ormE~RSa~J1tĢͯ8&N 9mdbb(S'N^btuArȱWq˄tDlv]Ȃ(v&+NVWIdtʵ*or c&,gAFJ#̦ÇS7쀫]V6:Jm 顕.]m" DŨl'^v. 8*7 JDPSR?Tx}=Ą;c\^⧠NcT4!=Ax8BP]8~D -+v"Z:JF1ڽkEѢ$IPȿ5ܮ|\y :Jxʙذ J1n<}|f[E:E' $\كV7!p|&qTQha7/=7Sw}bXH>;|ftmf-]}FKtop0ҦCHmB\p;w0)y$___%$c4Io}[I;_NjᴝqD1Nh&ܼ x5.d/BPWB7[w!7cbL`EHdmحQq ,2/ރPoQ@6.Zh!S"|˘: a~`Jlˎ6-)JbT58{;D`F g?zH觸${QѯAR-5Mug!$? jRhǻBH^I䱸|k3>}` 1n [nS?`~,%`oq an}v;OWf&qh-q4ذ cR鶶6jD)t92Fp:c6oƇ,\B@-QağhǫH6 8*.D\E|/BWlIW?ּCyZ8'3q0a 1éBűLPPX2>Apx_p >L 㠓1y _(>w6^ض 2mؔBh$TNta| Ao'dC[:5c׉qeǡ3ȯX6Et Z"u<vISFWpx 6GP|j$y937d"2&A)DOGElJ:q%NY`z K/.hۍu; ՍGWCJ}GHHEy.;Sh"ȁk_% )HzNz8 qc üٌhy}= z/oQy SuflIEa(kdy]-]ظ`;s!k9ڌ:(4L]M#˨ x\A)rܶ~';.%oA'#bGݑރ?"g@]7O[q2D߿flgr(j?/NiDO֬,F $ҨBX@0~@]JTFژFA%k68 o't&DFFPĸgTC;A-cؿoN"JET8 Y1-oM۝HSP)hn4?x(!8bLE\2ӳd(@c|q;n% e;mf-!hHOd,Gpp:@`Z&O"cH/ЄljG; )`6Ƨ#2p yX0B\/"؉T ,ݍx,wV]زGb9KhEy'a30bqbj{GL{'/Ƒ,CN\i(G_}q0*ظ ~aXhv0wbzԹ蝸Td쩃`I3iiCw@׋1y&Q[AzF7[RiKs&=k 8ZEvl#O}30_&V8a6է9=i0 %paĪ<lbsB[Q)t1N,M8uּm˄QGj\0~O#& īh4B&!ހ[pz3q ZK>\WmܱF[{ {XZC' *tڵ,ܽ!%!样p:9GQX#GN/9ƅ{w(~j#L> ?3 C%ArVav) ֔aAdn2R_գ oQۆ_J1ΟBh4, ez1$Q&:.E0YƥϘ0ߛ0z0:օPip*O"*^>||~#^]:ܻ(tlB/{frM~ߤ$5P~3OJ{DF"hedhgAC᛼Mj4dSrn/tX֧#Sz:Di*/Kl{7!ƹg݅>c酯]8G0Z"Nky^{q4 q֌1 6d=%xtcBCmd7cO< o :Hxk"rk(ZivaI㡓sA6ٰN 3#+3&jBf-'(&1:*"'DJO}xǑټ ,X sY,YٖlV-?K>>ʲL(R3A$ rFlޙz He i(БA?&!7~Kq>~~ЩJ_lаOҵ?ЂgW*L"@c@ kMP;,|MO LlK7H(,8n/i;+*rq.C*(UN)1PP MљFCmC\`=?0I\BtBjcn8_!|ĸMH&AY!O$8W:WH˖T[27!KX'M|G@N e Wf'Y*}:&p8m+킳g,~η0 )l0uJ0a" uo]E!M5 LPR8{[L\wa̜DYZky>a-$ByCA A_1=?Ǝ|t"FpG(F| F cރh>0cddو0DYlg[oi&:GXGȻX`4ӧ7Lp|)3nfhd+{æ%#஻1)/'cطȣ>_ DiJظ d<{̶)k# "Bf\{5zb(h(V<0}8Sڏ1u:2lDx00cꢸĄp#lmM?APSC6dޙ 'ap6. / [֑0`R b°`&$ i" gQLᨫ)\I'?gVhM ')G!1k4#0%K9Ҝd挋ЪX.N0|r,ذ~4a6F8]/<+1k)1c6&NAy 8Ơ<4 AGo<_Sy$2Lx_bALB wލfW!ɈZ\J8f44^!뒛0s(x.#^Vʜ`=k[KкwPqo)'u/iCeӚUPDd#8sElVqM V_AqmGM-2G0ڇ [(?)ܹD0Tt$êwޜg:sCܵ?vi7m`:fP Ł([d7IfztX0 ox K$:o!G(,WBY} 8ov|%]$agub|5plko?1G6ǎYq` iJf̜O>5hW$c$`a Z>sQ@a1x{\.Sa "{p(T(53.: خ[!c{BVT2{- EԱqcvd#hӘlHm)d!9 q4ԟDg7- b^x5M!= -OVfQm#ltT%OY̟Qz1y2%!NNF{IP QuOrƢE0+k"p 1(ȥԽS0&'Qh$z) N4S fxOxUZ!42^fdϘ,xʋi&ZlV4_?y [;Ro.٘~r!a`oQ2 _YOL,ϿE؉LUZ7y ld)SC1vNc3?~E^uՑ eaq%>g9t2yΙ`30el 0k-lы˄B t\'=J!=&W]Erk <cu#`Ҁ%ucV9}ӣi|`zs3qK}t뿤K "gbcFhY$GX#/ɞޚYHGɿ U; λFɚFJEKS!zצ'@apV[[hyz> Ł OTI}}I%ŖHNv$F1y{bNayFqL(Iㄈ=;ZPcrrxN-ebBOPYO;OceuP)Nd#D|S23(A{ ?En%E`׋HlZV6bR D?;+:N ԢLJY4˟fGHͥկT  K~Uo¢A!(N&"PWͬ#Pcy ^3F^R'/\Db!2&s0765밫 v*PMd.8qv!-fʗ5eoZA#Ӫ> r^ة{a$H/䐠}A`X8ͣ(#yȰ'yxz# 9F&$ݐ,Jn(& ˘3F-Ia*^&lx=}xFDɪ*D&CJ"0Mμ  #ڸ _,z{Ȗ>u)K+TwMM*_A1EG Wd&h?g D)3IFaoڎKO\ xg 11tQ4 !GV.Y7[>7GTR3yE gf`!'1|L,HX4N2E^GTAŦXT'!R0R C~&.pa`"c+se6Ȭ,RnKIt'O8{)iN6998m48C&fv&i]&TW)H10lqjHWdiG8F+nv[$nh*S;}WHC7H5}%0$ rlneCU诬;kGNkc ;RIjvk՛ pU(L./g׻E;~|hm7 @υϵ 2]a`QSnNX ~G1ssEMV~>"(IXOMIg5xMdSgDK(I˞CI 8Mz8 po}]'_(p l+JvsrY}N#F,CU=s80_@A<ѧK?AXl4b&TkqZ2E,.ɶ=#Aer50Zk ~v"{WP 2}wX(|oO<5 }29Eɇ|6~t(P1~) % P4\[<b1_W(~Pbqj 1]YlmujrkDH'i;t<#v|5CK)Row/Ŕ 2q:MjzI~oNG$0KCf^mםHY3ϸ1yhX2'?ﶿČ.ئh^E)5 kĠ=oxߦDkorOߠǡ]ΰ 3 >Tw%CNϭ۾PϒeW8@1ŒVMY%g~ݝ:RQbtLg|x[:D"\1.ro0{AjL\8Wyoצ' dr|}}}5k" Yk6WjKRl0}~MF63qɔ nFqwv/ÔefُUs&۟#~U@+NljsOB%OqLHl$2㨻 \N ‹ؘ͔gk:N.skY8IWkW`4~tԺl!;PNuQ2ۧ@F2zjĔiDfnIщ-xo |ys AƚeX| ;I~;BNC3|x-DtqIcypH tܯ-A3/b&l'I8|%)ì7CpG#@ܹeZD3B"ڭT6g)kb)"vl&ȤPuXgn@lhEq[&2'/cG膒BAi#,Ԁ 'ObM4Ob^83qcTƮ#(("ڊG= xo 0p-a S=O=LUqVfA:@wФ,TQȰ,][QAxh4 nC><8RG>7VP}{WbvNnűz*ڊLP#;pІ\7!ICjcxu/@%-_p7")1 Fc7$bx[{76YpHT`ɍv7s75QsXEO\&LN,w^T=^9`И)=DtD) +9f|<t] jd. dcE^v ЮG}2m݇ -9f2)r WNԻZ\l2 /NX7{6xP66p/".`]vQLdNQO zEX/HbD1.D3|^eBe qƁ|Ӏ9=7tEd61g*% p+ u`TPeB|B4b"w>qčq-dEXz +gaQ1^'^ˉMw ɰ&pf23Zԇkf~o-65em qԋkϗ\o RmGh,c؛0g!!C3+ %cpGѧ(aD6y<]HGpZLp2aQ\kf @+^'sGmi﷧Q@H!eTEp lL&l ?64ᛄv#\TM( 9Q1<$9(BIǫA_>*#:0T1Z<Ƅ7v,[^ÎVA9luwN,AQ. ưB&'7/` !_y}2WKOOݏ ?1V< <$&e6j0}@| F 6"{$\މqC${Wa[ "0뭰>f"(x LـcŃ(KH'F!Irbw"l! cSɋ'&UG]-qnmF3Y|aX-Ծb,zyK 47K806""W 0g55⍩c^`ǿ,?G Hz .uc+ϑm&AϜ5~~7߀ >*3`0křwY܍hÂ;쥄&"%:Srat:Eiuz5 7߄ԛ;-gGO 0AFqG&;YA&Ě YM{~e2r}.*oB(A (:o> cl)J7Z ϰ%w^|^Mݷ#؆..!iSdZd(`b&E)7ҰX͔f4{.^ϛсi8@Ζ3+1#F jXH3.߻ U;n|tX# pB M7cJvBb| u<shq8w2@Vҙъ 2e;z)qsU8ѕ8vpo/ÄJ,_JpCFXGJ]kEO#kVQ݅kn5pK.MWn >b8?:P: \q`p9e(*D] ႌHl9{wL`bƗ#GSD7u[9TU0֛5Ǯ㜯QG9b,>Db}{ϲww#AMϥO*+iI~IeXN jl!,Pu 2N-8Ï r :3!Ȩ ٍ?zSyd=yě36EF9Y[r1†> PجEOItgw1sVǞ/%=)%sZA$\.|u [Vk%HCna6N:dN؏ ?h'٬V)YKq (16#g 9BL@7|&LuQO$cqR+1{8%x'}~t pBX 8ZCv<4 8z w‰NwA{/-'υAf %fBM‹gkT; n&lEs M8сX9#1ϭ 7̠Tm.p #'u8ɸ(RIk}hirxI_|3!.H$j[5Gpa^c-.Lt@[a/`k&t7cD:/ذz˰Kn 6``sM}Xx+=Zhı:pj&DH'^zV)x X WÒa_{xUl؃ BЙq"$iad1 quPZj+>% h>쮕D2bNCW5z&'2p8FX.j5 v:7;0ĉ7< H@yx ck%E6rNB@x! ,6,l_Wah%-337'Wx=־IJl{StPQr {u!ǏDK\6Lun d Q1㇢,ݥJ ޛ'| 68k3{,*kJ N ]yFJoLkW#]8bdn&f(5TyES**,54ncF$1gp`©c"AHFG}n9ߦ8)8bZG[D4z,7~l˰g:Ԣ2Ll0G' ҍ ǝemǟ'#&NS,Md@zxm$c#V1`+(w쫣^ًCEA Dw6nFl^Dl 4_2)F )(0Pj~z;6;Te`4MwdʦCr_~ F_F JI:JaPF@Ĩlx OYεx!9__) 6Z%h2vB˕azYVu:ʕijL h "N;i+&ѱc԰ydxeMQ\v>q ."%'NEcNF\]T筗Ɉyc?\,ZHl/'P<Kfh(Fde5,Q7Z#niVh7Eǎ#CSF"@g$%afNRˬӈ޹̓)P`A{. /,"Ds&̵UW"~pҜ:d -#'bڂ;umܺg!H)`"9́ %;lRòsIg`\jIYz0sjat.BY(ʠC\'Q^!gdP>l \42ZP,CEheÙGI˷9i>tQ<Esٔ\r:;QDP>^N\NL53i&VG^rIdgc:mo6\)0ʲ=q7 (qEd,ޱto&b{XɂaMNdZGT@lJP$rd7+\*X30YNct$z" 2+JI-l}94V`b,TbּpLtPŚbKC@Ww[(*g=9L\NpYS'ZV#s۠*U$=/e0ԎK**f^nc8s8QT}~I}99\rKon+JHC馒x^J"Gk]‰&xe)/MJPT=?3< /$Z Gx*ȩAHr2v6,2T~#ɎQSt نCش4J5L^%IcȡɌ&; C2/ :%4[+H$ daIe V\ՆVLM(28؁$~Lh1{k8B(3 H|ry*//[M8؊!.CE])j]ˇx; a;u4}"ϑys8oW"Ϟq>;~?(?m nFKL3OLˇ2F}?[ a6Ѡ2tQU?/cf.W}A< 뤄ZV>Mf 4~_S~}}}}3 bfB8Zw1-=ݦዪWUDLwx~vXӬ_?=g$Bs_>ꇏDc?cz,oj Syf ?ZOO?T`GUa]>wk Q 7y|:/߯_ O(~`eTtW$B]"s?(ZȧsA:ZjSا?>__1NEW7K8S3-}5';^_^xEܿWV?xbTlm׺(z}%#wg~z8 >2ݢ˨/3_&Uh{*?KjB&dŘ;hF%tFA'2w:fQyx%'G%I=m١G-zJ3;sOMYexg]kR6s Y#⡲EEM-}u:k1&,vtUEjUqjW?`aSj4 8AI|=b Y{j,$ÆY1eKptcW+t}j lSl*c2IC1ɶp&3qِ<ӌRLXH$.&CJ)XS?EFJ=`V%1{rO;0|Gj'$Gba}]OtԠYOiV9$=%]o%}Φ[D~d ͐93MOT: TD4ODh0iT"^EEȒ7%btчQf˪j/e3C!HZZU,EP9iOcʰJĢ)M4U9‚&L_6oC96x6SRLfC]שD_z&ǝZk!AQ4ZT G`'U%ko;[A&X'G}FoCy][h{pol|oNu{_;ӭ~B@Lv|'}TcK;wsߡU;WfDx?s+u_y(}@p^`r`1%8(#K(ڟD7Hu̒S6 &QWKXҳd V#־+3L&ǚq%Gv R|"FofLT}M bMuhf0E;^k1UWG1ֱQ-`͎PGwzKZ#Z5 5A䨉)^N#$BrˎCF/&D i-ٌ A{"`X-vlU~*Z8Pߧ%+H@to',]l}G {%}QopԶEaaE\,p2B`_#7U&zq`6ϹMwپ6?PgLîd K5UIlve_{Mס݆HnF7J4Yc1|Gӧ\l+>Z %u"fFQ :/u1zC Tm=Ge {uC2Ͻٻ񥘧ے'y6<=q\$sHE~Mw;ٷKQ{]Lqd/Z7wn^auw3=gÏF3y>W.۵} /t}EQ螪^8F/ }V,=?ge[ < oW{ywϿ۞xrJ^5-0,pL͙^'J6}KɥW1ަoLuy :f>SbzwlS<^h՟U]+]'z6?F6iNwse hiz!Lɘ2^z뿣x[c1ΊHMS&n.ioI%Ϻ'k9Y;ϖ\Ӌa=kҨο1ѶzLۿT;wpƤ}q̾+$ әn U=u~i+kC.6fۥ9,rj@=ȔʉJ 5"R֢LJ+sJhܽ#ڦݝ9,wq[ ]$è!JU[R|=bnx6Լ0ySw7de9!_Xp5jkƐaź7=3Y( Ž?F+农[C޳EdWsy_sK.AWGLzɽ?=Ywڻ6="X ٓsf-]XZS1[St:VtJGosDc~dW&ܔQVz{ɽJ7]-3D}rU%!e⭎ѓ\ T`{3^iL/w[ɔ9yԳ#ΡE폩|`qldU5)jYgޕ1bħZt4a; ud ^D>ڲ&zxP4k𦧮/~(=:{c'kxG]/8f.|o߳_c=Puo~#{_ /Ҭhreh;u(eIV`|MHїmzS*̱L-v% A!w}95Zsu&N֘!19,'kh5$oIȢrozP֥zd&Aսh·pH+i :ͻ/-w)>9.b.z =߾_=Y1dλ1ڰ>YsFxisW+1x>]W} ǒ(\|wϋ)wNٺ"iN~SJA9|UtRfϽ:X*u9_kƜ[P mwRFl TpL/Wʶ7':XBHծ #YM gվqбljL}cxǔSrUmrsHw_b5&)J%"KE7Kͫ>ꝁ+1xxmȚ}+o##^Ur9 xQ_~y7n!uT'LY}ގ_< 8cHno7^& y?h mw=V't:ۿ6pŬK2+9zSU37gҢ`FU8U_dzwG.{СsNT?<\{Lhظ* bGJ߫1xҀV<={z}pmNg iS .ypkm=xkjKm%Jü߰Yku8s w[V9Ȝ=s齉:6OdʨϲI5:ٵ=J֌&ڇXR|%zXm}G= [G Ӥ17Oqy}t^ک22o+}7ݾa;2wKs̎#>N igm.Ycc{hcX^zɽwjX&&<Ց&oզʜ߳w]̸N7%}o?S#Efu3Ab6\)96RI XN'ju4Ks$jLd=ϖ71 1cg泧H`ε{Yє ̞yT3mJFHѦj\j2zw'& ]J: [c7N!W%R8ɘPHƢZ->"bJ1ߪ$AgV1 6 LJT(ޒg-* T=筭כlDHˢ1"}[MzlTS ʣӽi`rP!Su2{Gy̳jSM%:Y,Sa~R '7qGfK/I| эt^!Rl^0!Z ,)0O09 *R`i +ӜG]JzI68ЛĚ7ܦ333ɦ*RVycML eDh'\&48N-|HZT8=hl AfMQ6I!"HR)lthqEeZfsuδi/ E>45?SUN˨z1lA]yI'{߸E)cq:|QPf&LRܒ9j$5CLi}mx2mNQ#jE1wg3JWNg"6m.ρE,״/ltZ`ݴ9taH+b$EcYrX_9ʼ-29%oL+,myیt A/RKMS"[#2㫱)kY ؑXrn/):$_"+LshszP_NKHyVk?ׁ$%õ ~ҜY eRGزRh15}CC':mٓDNlW q2S%EmœvǼfZыD͈Of,^RJ6Kɋ:gEB^(:kdNItԠtpE hd*Tvw?n=*F[q{]F_i/Yv-92Ϧ9oP=Gq=s|\^cIR^)~ҵwtsэ ͞1UX۪xj蜖컪k[ε5s5iæWx6=~Ĕ $DgZpɪڜuBI̞bB/3~ K2*'dhϔ1)ݜ2R1PM`,1uoz?n3dO Rcf!^; Hw`O-ρ- f/>BɊ{zC{Q{}kj1m(zk4@rL&Z1RcfIq=?Z&Yaԝ[sq8QtouY<3#pͺxXܞЧ>bAjiƌ,bWlI=6 Ok&a_ JF8F- ׬GTې5U,5I!L%e5C ΊD%I?ki3g &cS +CGcx3]t !޳c2"-7gmx乮j0cqj΂*R䘐="m蘄9/bk.ZcL;JFȲVXL\ӕhb!hLEQ/L;d-Jǣ!ӂGHm eb'wʰ<'R[> Gu|>jmGxuol̙tm rŬG#}.k[n+}vZ&]V']Ɯ c)-;ů).aO#?=mJ54gd'ptfL^C. yw盺Yo7r']$|۽hH9%I 1`3e묺/5*%5XQ `1"La$QHĘ].3g SN^|[%t` 'Ԅ|qji9ܜ[3}[WHHl" sѬy<{傻Nֱ'|m%ѽᢨĽ=._ [&/&Lu?2u99'fC*LEn=:RJ >{9LnqNj㑾hT̅3T_m+:T!S/yFN E ن̋lnm+Pu)QVJl|0.S+>A؝[_s'tƌۇv&o^^yo}?_=jB+cNgiP6?ЎKMVG\{k'E^3壈_i[ BO6d ġ ktH#>pQ%w5u k'[s_PJ\ VѴRU$wVd;ppV|KI[bSpd8eq 't{VQ/&+x āZw50َ!*({pBEK$i]0?NG wXm [EO To ˵B,//?{hB5ok}֯?Ƅi咏/벲!]5kNȒ _ڬIcӧ\}64tߊWno+]zE2a*wWKʫNتH0)s%s%:R.V1ۖN/^v06oWU6Y"g'sJ_XRa@ݺ]H+\3uy:&DJf/mljFDzn)i4V(87-6Wl߰fs"u[V=% : kv8|tNAiA&旫?ɥn2RyKىQBXwRDǵ~C'圬Hqb2{j׺jR2wh B#B5B nA#ǯ2*M=P^c%\\#ޜ7sƘ˅9H;VYGXF0!݆ˇ[e;Z>4k9;3=U&]ӧl?9bǒ-A W1'מ~0J:t7ybHȯnΜ2b: ';ee[K l/µ>ᒋgQv瑈.WFJԢm)o[% \g<~&,5Sly<==wl.6~X]R S'Uvi 'w}25|X8?RX5_z- n)?y1B_iq,7O+9cǑ~6򎺪AvJG#UgO+䉕lt䐗-[q (4ATWSYHe9L"MV)3́-_ {OGIh++@eQޱ#;|K6LVvӆS+Wb֬pb$#RcJ Vͯp 2LWȾH˕_h*fQXފzbʤY3FeV3$)B?sr٦#۷8D8\>#,|N}]Eo[bnKC3h`*tF `q?"pP°Sn9U,~EW{~4w{.x4G>BVnٸ?vvt[ёmNF;l7E*<+-޼lؽvU[s:dVt;lx̌7l;̯;pB@jxxoܜ Y r]eo>_\mt _<>q]5CM|!2!Qx/~wX[Z蝥C?a%6")m*_P]VU-Ê6W}|K`|WSgWUwrr,KIN)wd8 D}M\,,-nkI2lF"&!_/65-[cjo~zB_WlѢq| MJ2ӓ#˵6{ƍNX7[-6s>s{V-[DD<]>"ӆ*M%KGk YtGo[f=i՟w1psAV)P&.U,Yamܴv_=Z󭆩*-xqfK!-Aގˍ-[զoذyݢVAXBhT/]Ԇ '7F01Ixr8㘇(T!cxqӹÍm @\O1w̸Ή =JJ:.Qxrg;[{g*ROKմBC_5,-Ybcci111F㨣z><0P1|<;M;m85<)_{O#OsߴjȣgC]0܂1YA~yz?x;,ރQò0fơSyFS`C$@D>eƘJ?C[i5&OOHQ՗WYQΚ)l47pNcЉsxB?r iΝyϨT V'y'#`KqsCחtxy]{ HLJw> _҆4ǟ%j=_w̸g$.Yax*EK\Q.$F]ק~ _r,8rt9?*hm&E=V'3HַsaJr cM6=&Su+YZl0(do~F8G>1UɃ_yꙙ+;hssgW=:6h W]cC0 Hˑ,@ʍ ʰO=WYӻv?]%(d]g';axpOfܴjp6נ!c O\ņ}Fx{7-olySy 'n@9&)G%+ Q܄p1J-[HPlkc8%sFnܴA;wnzٺF 9ƿI.,6LTVvv廙y ~0:_hx4y/joiyNٯpϐa . E$عl|s Fº?Yr+K;x#ִUe h:^|59|4%' %HiªvxY}{}s壆lCG&߹zoeebk78qB|:oCE#d0ф;3ϝ<5ii J@2P\HACBd((@(`Ĵ LTXbHfCl듭8'cXwxٲgլCdw/-G?-Ub1ytOi6ixEYfc F:.Z_t('|16~Ov3 2cbfG2>7GU k<#(? t6~`ê}-{K&`/H^v- kjjZ-c;C~o"|M&GDh+KN/GRd'GMҘW_\`rjRr[;:+cַ(MGeaƊZ4|Ȱ!~;FB>ƤHL!.\?3YZRXete'EMaR^c)sԘ4c12 K6rѴZXҘ?rmLLX*fv!b֮oqo?\ʜpT6 wGt:i҂: 40Ar(T26tBB C@8L0gӨ*ui # e'Q;^(i6GD$ ,f֯Op[N%kOjjnkoi${/m/)px.Cia̤IFRQ|ĤXjyL0\i5_;iީ8NJ%BšΜWFDFEł³vzȰv#!!bTb>J끌~YIaBʄ붜k2Dl̈|N/V5cR +IP>FFuDX[Fc\ưX!BM() K&7TFA[)IӦwDGE4vd3$k5ô=E@D xmN\)7< HH:' d1CyJH"Or#"e+ Aڪ+ۭV 2L{FJX ?AKs "=Ttf,1Vp88PyʌgZD|V*.*..nnn p81ry@x+/~ ḍ_MjU?V'bɓs5T$ MTuEv^8c(dE=M#Hc_޸WF.i#zh{zzz闣JF;;;dT*׎WA9=^ʼk.l `Ij![j 'hM%d Vty{0Dр\b.^JoVcGڑ~-Ok( uQ1qƙL&#Ju]' !$ ͹UE%a%  %`4`Kt$ 쏡OxO=0 UJ( <(P4Xzy+L 8[|W |;oA@]0r?-V#XuɌoaM t8.vYP`XW`$?;猪eV " ֤v ㏚(X+Mx0ON5]gi9!U˅ 'XY _əe8 sYf.T (MK Q 5(e],`X ~ȦfXUT(>TA=$c!%b92XoW: 4|pD4[;&#_Q\vɠ̲-h,BV4 c\Ţ/uedBDVv (H0 2˯ aMW&tYt⪈pD/dn[jԢ X0A.=YbyNUVá +ũ`Ygz)cFE`Da\tc:k2q[ڠ)e|4\…H6Ωk:_. Y(%66 A)aU~DBD:P躧c.JqQW. A( a7uFFWE:CSEhe}n"KI@`KC5,R'̖ZF&7"Z[kVwLca:uEBՄMurA)*N~WKH048iI\KAaevԵEIx84`ҲeHZ:.B$r 5jm %ŐHݬr-mBP+>dPBJk"`+(@7Ch W!«j$g)Y_ʰ3A 999sνiD,xe޾R)81r8A ˏMGk*(8h`qQ_g?2("gjp OP~cن՟6\2鉲?40#bbRgM/vגQ>.vQE'Fqn[˨ &wdD RR.dBhjohO6X#j9b48(&ccccqB>15:E2 Mqt6/Y 0O@8ˡ0 'i8\ij`!X]n\$>G-UNFZqHppj bF읝&J-,?Q8N7qFpU*l p6!{1 ӷw0Ӆ{=eԵEEv13Dw45 @gi?sTF],cIp7vx"9M@\a$$?X:kp@(\rÆ gqAr0?9|+`b^{2r ȜpaӠ͚:ߵk'bX™]&ǧ>A 7;cK]J7Zx?>9bѲJWqUёxQoiE8 H"r/WTH ybR5 ἗z!)>#D\?jcn? XlS>u1Xpcu Q@9nz\b\/Ⱥ9Ĵ 1+\xl[F>/ksgf9抳k}-0x˜'wvԱwQ `յ %HxТ 8yo!sf͘t?]76Z)Eː[r}o[=U({3odžz5}^Usf͞gXl ,rݏ,8 >|[]FɸC7}9KH)Ζ>pʸ t ŴowIc!#~1V_!7% C/^P܏,*rW}|4<ڃĻ19\dNUk) Tܿ&Ν=eךQ! A7{X@=Ԅ'Mexo8n[WSGOT% wTHM1'--€l*4vj9>rT26{}S>hW 7. ٵ9g&zp1Bwނ'~rs`=[. y|7h1ۓ&<;}tF u-+bc''+.H|^}gbpK3ǎI"pꢢ":ލL:`(+/( ]un0O@0)v-iaiODEEp5Ơ}qq+S9 HxBr;:}pvCf_^'WSyxN3fXm3 mԀ=(u=!C0'-9]PV;oN(9_6q}<>bigx*]64nϼ:|vOvXE2LE#^|ſ*̎R1ֳY`a7\8y7, da.[G䠉bꕻR2V|LH(H%x;&?7e;w2jS}??tШY>)N4س;Os#54 7i~P!S>wtl\Ǵ742A9un߸ >oѓQ \>uh[8woݰ52CVUm ^y=Аwl>K DXYbZiTq¤A|,x_rG[KO}_QrQ/beTڦhXtyϚu糿车v;B;W/k< ] {u,YqMRHH]m9cI lE\SUY Vh@5YOO;ip5?^19KgдAY-jrqX'{e8z8_(*p^;dt7zƴ[<哥Ff:@X:w=]5@l~N:syT.k)iˎni*IclfVX#we ℲNzBg~NbYVA4|Zj`3x1FG1aTuيiwX &WlLIUH} @`>d-|3;1z8ϓ0ꞧx>!>:R"=cԱ yz &=Scn4W50€25rJ$^A(xMeHA :zs0& %$8~='?bl\ST F 60IFF~D(t6`2p 1>*U($Gy2.˓Gk,T]g8n쨯FF]S.}MD,g^Ξ鴹P|=Ϥ&h=.J!#3.ˡh¢QFYo3_o6***B媘56 biDS/k5Z 3e& Z Юv PV*-"Y[k+^\2 "\.Fa[`iOxqߒ҆v 19 V%=u[&utnj;,cF@8ʛHjaXڼ'qE]眸ާf)tl  FM)I]CN)KlNrMV F5Q<.H!?ZsQ{:'a6uWe[8,La<ʘ/c4/,x˩d:́>0sرc.'#8`oHⱴr2aoA"*wgD"\&b,P,`x.>Ju+Ano` Qۖ[lڲj1򾗟_^J=ҨcK6 Mz]%Dh%:f jyƼSS+qͽ{+2}'Eeai1,*&q  #B*lଧ? a+ =>:2yُN=/6Z_/&{]N~p]ZiE=M6[0 ,cʓwOxwV@u 6WڸB65Z pp,Z$J$HJ|𘪫-67/ !\I' /ϹsqCI2}YM#*Ц X<ΗbҢ8ɑP(TTP(ZLn2~є ;Ȓamm((,!6yܰ́Jkb}pryg؉3潐DU>6)q8֧H#Jy4*J?DV+"EkD, Dc>xtŃgs}ݕ`&2z)Qs'0G:!E+i kI ɣ2 0O5HcamFj.8f e29KEMͭ1Q._r[㒢bU4O)WZVndBD&%FBkΜ}W{QnYYj+JTU(Ó:+J/r4iST퓑Fx|ub匀Eg/X0hT˙² sNJ2grf|茱ƚ"U\_[%,naò.foi8飕ql.U)gl|G aN%%TZ,\,rIĔZIsêN0|p3}ҤISg5o..F ~̾ >64u(yK!!5EA2RIBҡÇV5x qU玕QB&H6>7|djjn'FO ݷ &?NGLp^CmƜڊϺk$Ù1Q'<UF0Ppmi]O=ewq'?d>{k 3y9B+PwKEq)xO N%~gZ.4Չ$nk}y#5*2$n/=QToIIFDׅN"VhRjF=5;Ze:u2]c;7pϿ/]  uX.B'Eй E*c `W"cW@*"R֊x.qe8<2++-UtZf˩Pʔ .n--ڸ|T/7U I#u%6XTKRe} f̒㶲K,1.gfJ1`2YR=[[.AQDCv;~D-0޼|>)M]|Lv*rc_tb{}Mҧ}c%aIYNwV⾙qKQy}Mխ$D! M:RK"Rjѓa*_ {Υ}^d2 /@q\}WE9f ]:E1EpXhI`lh4'c e,P rt0>= ن峎;V 9{7;܋c~~bv8bcM<16C=Q$Lk2PN0d"d˖vec0 Z he',CG#uWFxBhG9*;7${x@@1vzE3nWO{2vy bѡ`9 ,0} #l`˾a:#60"3frCtL f?cy~1%R<q{bS0f\! IۀP $ăa< ن:Xi]Y}< u#vp?; 0Ϗ03 CBôݡFdt2^Sk{1]Vv,c)è-}2B x읞M8g`Ohkbb׾VafD u3j@&E>5f*?qebֈ#2Hp8f&10=cjN,jH栘̓u,3˼yk>bY]{|64m!l%&{c<yAA8PT3N}5!lɐr)]CBN` i`"4|>XAʨS"}f63ܠb#q`TPccޣؿˈ0)j6_w1)@ ~Q bx ܣ3 3@u'0+fx&o( 8 39*kqIQXKC!F88ol7hvc`; "iT[:/{uE=)0 c`H$b QVa4Z6l)`+@wzuK՟\ /ӱb @FL um;]SO1`^OpΰAWDuoa8[=d#'=s]ޭ;sen9Pe Bƿco2tnنݱa6j^+M4Vhඛ .B  s\hiiyG|% l4ps $@ pCOِkʏٓ=to.\Jt81MrQ W',N A+= FRlk7@foD g vC4"~+^!o?##` ( zM/үw!jٿ/ԝG@ ސqWv4nѥF52":.c<F2 a#_ʤ+HB|J{ZD Mͬ/)1,>>~ܹv7o^(]W&D!("[ye& lMnH E%? gݘzH. ?y;m0 :PuzCF= pn__ yF}p>"'#1fʡyY<~Xܯ,#ż_b u4yiBSP8檕K y']uzXKH{N_nЕ`w1:N= [B-&*'^+mO(ϟ`Ah/%i5{9LB)m>R-OǹIܧo^_ff7(gŁgI\qPD_; kYHעmF[Wੰ0۪,:x2L"ݗ+UWh Յ;:; EqŢvw&X *|ڣKNc]Y\ܭsV7 ^T)!H|<'2 -*@_՟+_x)@iѻpR3-k׷PމYuڈa|UU!ɧB^k@Hu!1E&/q88\~afs=Rg}6 Fg1Xh ]bz0Y_JOT/$Mdی0XopxҨ5vJ0ddb`d?0Gh;jsJSx睝$)0mg<|`\3F9[ \P4y-zmI/үdO :BRjqX 8X#5x,5dK>qk"yY<@Ix<<<'@Eiv '96 bD99*T8EJu>r_ bv~"8A0K3y:r닖waT r,;ZxJvfTPxsJ^h3ԉkfG ё}RnuxÇqrujIU{PQӕx:pG? p&_:_.wڿ9'*#78~ Mȸ8ʻϋWSB4EiP󀏢-Jz{CA 6DQ( Q UI/һH( ';;C<0;ٙߜ{91 D (Q3R^4hj]SdDL\8uaOD]aX)8pc L*ψ^7A/5ä[Q)2a7p:'Cۙ mj=&;=`DLU%p+k:c94 X{m+Ԙ}>˱;<2T𮨡9)Jgg~k?rai?e>l}4,aݵ,\WS %&sj YEFN9!mWCs*,qySezxSjyu:n4b! .V$bop,+Dm?ډ0n }#tȕ*KPyh$ q8ΣV_NG^^/:w C2ӋeJ[S9QrQ~sQE$2z-:vC,8qktqzEuTe| 19짴Z0{P] pDE|m5R 8,OpIh(9$@C*B3 ,~ "LD 290F\ ЪQM&vt6C0U-Oq8}qI*hyA@-N A+l gaBVbH4bIkhIqxi# ~boHI'ܕ3*&&` hYNl8 HMӨ._ RjGf5BB۟!P ]nBS4LgFP"כ&ś#A^#njYNBL.*śxoq@.Nj:=c,y|M9R>r #TQ N^PO-8F| y hFW 8r'ok \~7X(cs[%^'@+.74dAPVS`LwLjjG)=|5"0B1p,X$}; _ABD9_8-T*ŽO Io444zL&E ZFc0PQQWWT P6@yiD}Lg3&ߺ/6Ġ 3i3.J_(,dYa0C_($P_xҼ)h Dq=I>0Bu<#-Ha^/A:,**ϯnݺuEEEg 4.@idggoܸqĉimmB.]j ϠHD&Ф*RG!G0G(.׎@{j%JȭHL:r95`fcc+V\ tX $Bvѣ6mڴi`sWS\/Wn:v#zK 7)L. b B1bCLX1KrObW+GA =()h kJ (wZRr+p'(iZ h&NpqTd2RR\o`}hߊ5f0SĎƇN/~.b&f@(} 9!FYˈ?9-DIL,"c┲˛}{))h n)L|xi[jܙ]j1l`)ȟʴΝ;T*)殻:t(2@L&4͐!CFJQעo 5` E?Qu&֗B[ˁ<9c!^ ?K_Ɉ^/4MAS4HEg<IMIV<ܢW( &222F#MӒv}Rw$bmgҝhi 8 i#{/!CE|h )h6|0rRTKI E ^o2鼡(L[e6 bxo~&LcYVJw+#ι2 ce UV)J]S2^H>NcW.kȐ!ϿݻEN'2R$Z$)25@ +zNZ\BW 82ht8׋ $Ϝ93c WBѣoiӤ"mMm^k@ _@ [(=w޻55-Zr:xH_YVO>hѣy799*i/`%@ 4M[<ڣyC8I0a'M7mtq,@ye 1@" IAԎ]te^ WzGvңG~9)Vz[^@ A|a<ϵvM{} +."@P\@ @stm]PP WU2tiT0Ap]`8(NFHstq)GӬ@ò\%۫T)iG4bj&e <T@'%i$gY644$ɶQ("uHGJ_hwd?ػnE7j*[xa+ӛj/^8d@uNUq=h.;{L9fh3OvsܺpA#t/Y @ ---@HP2 ri6r9r1s` 8S}{e.yɏ 2\׮wׯ{|smMrj܅^|3/C?%mrPZ#SG<7t6{Ggį?;jz&/@ =J`hmmDөjLn锊JJC2 l6M@y<^ZYNofV?WS5=4ieu.w);'UV$u 0sĪ9rvKrsHtRLfC6W\JFo@8d˥haY|$IaI(_ JmR ~ ئ@nCBJR  TnA|L@L.@Q\`X`ն9>\/kkc}UsMs;Un=WݫL>_g/[盬ŖW7Uq~߇_8l'sL͟;q'.T;@ xֻc_]3wQ[VowTT HG;łSLl{C鍁qC!žK[Jk"S4j)=՗ߝTrtӊumݲM2S}Dyn^{mH6:a~ڃ PfqV}GP˰1 NiVÙniw:|a !v+Sj9Y2 `G9~R}dWmt9uHѽ9#PI#9E%g|̊E|`y/H2$kO~'ߺqQ \]gW$؛s/zyix1̤ܶ+zgnbsYPl KM?>}z , aBlB➹Rڸ@m{wi%uԻKzRZNjO^e`Y\~xilf=~~!M5gl?XGjp:%$:,xp;łpא;FimmjtI~h#;ڥ+{Dc]3}`yuzFjbZGEy fdj*6Ct= e[,M0R4Z,)AwW64(pX|_gƝ&ZI=L ߋFc#*I18m+}ph{NVKnTynX@OgFϟ?ѫƶnaf{_lL̾vT >< =7w8]b4T^& =so.:QfT2vOE=C}65dӕHjp\#p5"la2r谺ܜޣ;F-Smb?pO7;1wFϨUD+6 F9[p++DZ9|&MZRV\ɚcceWcZʓ[P*;K#}Տ.f4FK)ɑ# ?=.$ƅm^,mȈ3:}:Ǩ3Gqn?9EK>X8Μ+G ՝wٷvBM@ RWF6f\&I@HٵkW&$$- EQ$InF2 (ex4:2sZJxf &.տe׹5sSeL;md|YUKTd. k.lh-߿iƠώBD\A<"`2Fa2QV-~~Q*c9ʲIC r>o:nmnT9{cECpNӎ?|qPpMM**-IG6K;eZh 'Q%UAʋN\! #.S:sZN9(^S郹+%6yD`B)yN# ֖2*ST_sc9 ek1Qfkm cX\-^AaˊPQ7W5{bP&|͑GǞİ!1^PѮ s V(/0hi mQR:1&%']3Gbu޹۫wY&'D򰠐i* $*DoS f3\%¢ /3|U6 w6/~:g! Q A͗ǖ4p醜{ 4ە4-OL҉ 瘸YC +M ~zBJ--3}0Ǡ!}HX1`5H6!2sC.EF_>$?C08cAjH>^)t, XiSpm#owh2ǥesDQ5+%u\wlѼ)crC0W"Ɍܾvuë35J{6Tܛڣksgs+ӻXc'{r9t=fE:wک0%EV8trc҆K}=d{ݜ2|tU?=Խ{gQ߷! л3"uDp,s.MsˆVWp2':kШ SeyaJ! J9Rl^]iqpaLWA#' ZXtyG^[R?mڻuf;ƝP{Ō)o^f9Gű_7CBg•k7(Kz}cY&swۣO?Y_i+`̂? }#-cjb+Yq,w'>0, QKufOc2-1مSwpG-p@B”k[SݱdO.}=J=/M@~,vl^45Gw232=vPi0E5ĵ9džeT(Urh 1%hU a u.f/ȟ g/mU(5v=:9hnu3V}XIHcUNuR8f/t.9yqa4{iA0<`iug+:G}i <&''jq~~f *S8]VeBCu:cD(VǓ! zw8&LK@ ca J|tdFMW~I-@muAIŵq,u>V:\Ū+.ƺ-v~F /֥gc2y.]Խ|I끅|"ǒ;$ !HB Y`ߟ1~blw_|9};ffKLU}F(e*CONs^I.mt L]8[ZZxg^5|f̖1?}J}̙N&?;}ܥMn4iOa&n/@!@ 4$ IFt_Wv `cXCyDZ8NH(WTĈe;XˡJ#CݤJth[it0LHH$? K/z+0H7J$.?+5 _c$5Is K?hTWI75iS`y{3)%,㗝T2RA3o9q9oSzcĕ]]A^P@ rbD[p/O{ktW;VilT/D. S&+M/a2A&Fş>qԛLiF&pRu9F?<\ױYwOu0!(څcƌ+>$2o_wRhD#O\  yI%ZcrL rܨuصP-_ऄ Q8҅Ƽ' @ ȟz"HyeBI:DN ^qsz/aÂ󊫼^Y/,CbMsC}V\}Roxŧt>xG],m[p}6X =oe{NRkAHKɚ&>5mOqMFa'/1}HT%q-/Q|3ք h(~vHrgG/ݾw8snttblz׮^~gi=e8il? cOjBCAڀ^(r;O>.,oȸmpixnFnڔi*MZVuOg<2yÃBӺwDZt_~bӜ3_}-e}Z5kOoqwά1.+(D ZsbEF%y}GMx^m"_g_QZ`"uJOxڦKVA<)gg>۹tUdHql[~ؑ͏ӱ* R BpDn.]ds^nT7iރ6naBz ][ =r}+"e `غ/o[B^LͺʝOz؞Uep4≗{󥗞 VM|~q&(MyC3{L}ʒ a<}}gNbN ۽/֨--fc,%ɎH@ G\ 7xkSi2Oy/4X͚cD7>ٻJm,sgUfL3}Պʅ?x<NqQo4zDJ<LǨ kﴀw||"\Ek{i^6)&bؒ;6\HY}Ԧ;F=CZt}P׎I^\y=óԔǤ -.Д@rPgPVhGzD˖o!5zMylK+k<95CtG1/޳W\W%5Czw޼zsM{-.Wt Q@~Z- UD2D4J-R<`w24M$xļ2!!M!6N:U__o2jJd@x^ n_ǁPi+R)_zUf @n3@l6 jK~vU$+i@ یL& -//$KlllTTTKK rpTt$2@S2%...<< Țh0r+$%)#imr+#MCB+4*߰ojBh`";\e6Q(I m+Wq^cRuliMfn.lvV1r`LA;nݗɬ/̳9b22RnHeM>6x)cg*{;%@CNvT=tG߿iVgJ줗F~{&H ^U{z#6MxsVѧ:{YI  ftK%"^2RXMRA܏IZN9i~]2eW=2]e-ytNۙ}#O]~R# :ö'2E_.3=wop6=_Peg&M|?c*)N=q&2# TOݰR|9Qe=n\j|tdei}0v=՘QGvҭS쟶Q@w֭Ze1ӞG[~XIB?fH{]kU65^*8?fΛ'?6}jG_W%*E/VƗl@\A;1FFmL7@^x{<22"tw?4„7åϤ0hc5WU&K>{X%2yM?wx95.תW&R}uKck]Y"7"sFvZpƍ۫iKte_L;k1|gak,+:U\v$S.25O޽%ƹ|՞#-WPuKuVnOYvdUX}93+ΞgPesw ӦY)f[Rϻ䰴Է8UE끁3')d]pb >zߣ0z0\dʰ`Ο#Xp`D^ر) wjyɒ%޺uZmBE-X+^) +yeP Giήlңj8ŶAw&<LY1apj '*6 A* ͼdTSo 醦MV`䢪!Y:Pwi ?Id`ŏߞu4q1L i#F?s️ty~t/ǃP6F끱Nl]^_=?~Os~ʭ1oNqk̘x0h!{nng~(񚢢K =C/OpU 95}gUsnZWe&u0a1C fgR{vS3^34ٿkD$tنc8"7 Z-Uű*pYOU^8LpuǶs9]O?&]iQk2U:/ @ imm۷oFFBʤMH)yeHX @u g^ Ί? dQkT9\^VM)SPhG=B͒JbNQYt6=[W9I)=?}BIcfj\e@˅=\k4_ye/a\> D=nܨ/>z:P'8?_99tڿ{ˎ1OܦJ=.5̯MT_у7ڣ'WX5I);/cazs76Ϳ*Ը>vp:WM)*BUtP6Ezܻ~[]8LaXʃ`hk٩ƍG{r5t4rϯS|v+/vJ%g٫gZ6&5 DKϟĘp A$S)Iq-J!\gHbFGطsMųtBXVaUkZh}}33:ƃTpJ]ݱ2sxtI0hQ6Zrs)Tٵq݇c?4ydgf. an*2RcZ*JtOʽS^bƼyQ0V@ Ν XVZxohhp\@,=Jԗ\Sm65njW덵s |c>qhޙw{NZY~oۋ64E2ǹ.1,'wi>[H9^X?xnw?^j>~|Ro:xWwW{ :jB#G86lܪ@iPw L; M{kV_QE :L 2~@-ŕ \m,,6HnבS.1r9e]N4ĀP40@>FaY6**a܄sr5b+&sn26F&t+_{V'3Ց5xtD+ S_S2b){Ndz2Յ /'*zuqrK.'ELܣ?UcRRc;L3-1PӢ`XuCGo3U,C#8<[Hm\53p%}j,@  P#J뮻z^Ws+cS.nЫgd;=b52Ɋr62/ճ'' #.;0܉}LDORe id?,2R9|BQ]=ᯏ1?{sj7U'ΜIǟ;s|M'[-S}+,Jg`uAB[ I 8.--d2)ܿXڧ啡($Ic0BBBx/M J9z)ZR!4J8dLrdX14xv'kIs N8.7]lZ?)fiIe(BTy֭a}}nePI//@>Μ9DVk4RnW`_z 6fPL!edS41/.D .KA7vۊ'?!4:J_P??iAF:Q\5|8Q''# x}A wmlllmmx<2eYa*m+\*cu9Àq87s;O"ۅ[5xs.` @  _zJ+---oۘ$$t:z=EQ]Oy + MY,ǣP\(_:zR`\.k @ ? Fc9;`<TlV@ hd2P) 2UV!ы\+s} @ ,#o蕁@ ϗ2&+#҃@ Hs+# @ H"AQ-@ 3u<_k)U I{ ` s8 QKW2Lр_yPJjVitU{W fol a.`_`4)hk$44l'<OnnnPPL@ H{3ɓAyѾjCk׮Νs` ,ݻh50>##ho_233q^H&nݺ'l6 HN s;. b|y^}'L!!yQػ(L 䄐@ #A@QAD"*,* ,^("?P\Pte=P9>EP $HH c2wmtf2Lo鷫zRo]QQQQryƌ='O$܇(ɲ5MӈU144S}fyX&DFHEQ*OtE6&pUNMH?S(%@{%5^nwqjVhkMyc!o`ZB^źeK E䑪+탲L/,R]~>PTVvݛ%δ5HA;Z_f&MkC30,سNfUX}ގG =@wIw'WΜ/K>y忟Dݞ}Թ3//ETi D™W4.}Wv:fo*G^o9oŵ#ncZ9lTTwnk;~bm 츇Ǫ:81Ѧڹ$>U֥Ӗi#+>gOzwjXUv~A8qo.8/nvʼngk7::Xͦmj!?=RQ;).~v3Tv]>qUq}_ 0`^F϶b|}$M[W=ipP[{e|')._G)!)(ou-(ȲoZ~Z[NޚC~|H$C@)I2!Ovÿ܏uU}Ynh;kdb+*;?b0Re͆:[?XhER//Ƭg^ afF V_W/c͡7;WO@H>@,W2>Kظ{nҀC*2&qIu,SKܾU5bvpź=r& ?lkUp^~ܱf[ʔ 6 X-&ȜfVtW єxĨwK e،e}vbVxLU8| vL:и [U/U'_vgkO6͞?)¬A$ nqT{gyߙ;o^$m5E<1!ts;*$Eh1`^ N+++ Ĕ,>[xE[=y;+.7Fw}P_ѿ]3im+Gvf1U*TH{G ->rs^wu8H2-k]:RypyQpnʷ*7 FNxelb?̏hqoBa/=svңE֕*Խiv}j^<6e2~ɷZE"آBxT#JdY12`>*8QWצz(8,AkSzߏ7*8M%QxQq+/wɳX+ڝ/M<K1*Vx^tBEЩ96͙8-g}u%apI/De Ba!Θ]&A&UXO1 &jk g:uс?M_7 0Wj4`+anmn_*HQ׭+h%tJ6W];Yy]%E}FIKw_S.m2ޣ$m**خ3Up=LS{E&,"YIsTh:Nk`UԹb:xI YVR^%_"亣gI]7֔UHԤߋm4%>8k4k6}=de׳6+؀A!XWM/:tq:44wCּftd\[_X~S3b̼(;se0Աӧ-_o),Yy?,',OOzr_^ޱҾD-Vm-b EmŶ($Eŋ nFES,4K8UU0Tũn6qp.˚IsqNҊ$ (LqN6"GLdUDCr4) )B ta8Ų e^HDM8 &E8N$Ӏ$,)2Rѵw(ŵ{L(PB 99V0ɢ(H"s-M6hl7)H%UIF0!/( c9W Bf-b)mq8d#qB:4?S9rUy^En):tPrr22oQQʫ144E. cCCCϞ|%DdAtOQe^hE9eISW\wOjqq(ETd f E*[ZpJ*sf3! Pc˛Q~ê9.T9CH%+'#yUࡓ-b&e.0` 7A{b,+ְD] #zM7!4{s=-& '@ Q]Mw^&֢HQ;Ak"a^0?YͫJH $+ ,#pNSdԜn*B Mh;XO{ ߰ݩSv{tte8*'p8._FЀ  N>c 9J]ڼW^U#O۟{, e1 \sOPbAvg)$ b)555VU1 TVVq= RIŽUp 6˂͒l?σu"[ZqFbe~S,ޢZ=9\MEo[geVE׺+KK@/nQϥ'I*56G>466f!~ҥ;(PX+**~4HUJj ER%%%mxU$p"55eq K2TN…ҔK7l ^zMsϦ+ʧ`熽Sn Fz۩_wufoh !"pA1](ɱ5gU+aJtOw#AJIouG;mh͵~2-ǫn>V1{FTէbU x@uޒ/cSM!i/Z@:7WUwޓ% ]UZjv76=Y_ iW{hbNڔ VU[?i]`O;3=aeIENDB`Pylons-1.0.1/pylons/docs/en/advanced_models.rst0000664000076500000240000002772611645401275021431 0ustar benstaff00000000000000.. _advanced_models: =============== Advanced Models =============== Pylons works well with many different types of databases, in addition to other database object-relational mappers. Advanced SQLAlchemy =================== Alternative SQLAlchemy Styles ----------------------------- In addition to the declarative style, SQLAlchemy has a default more verbose and explicit approach. Definitions using the default SQLAlchemy approach ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here is a sample :file:`model/__init__.py` with a "persons" table, based on the default SQLAlchemy approach: .. code-block:: python """The application's model objects""" import sqlalchemy as sa from sqlalchemy import orm from myapp.model import meta def init_model(engine): meta.Session.configure(bind=engine) meta.engine = engine t_persons = sa.Table("persons", meta.metadata, sa.Column("id", sa.types.Integer, primary_key=True), sa.Column("name", sa.types.String(100), primary_key=True), sa.Column("email", sa.types.String(100)), ) class Person(object): pass orm.mapper(Person, t_persons) This model has one table, "persons", assigned to the variable ``t_persons``. :class:`Person` is an ORM class which is bound to the table via the mapper. Relation example ++++++++++++++++ Here's an example of a `Person` and an `Address` class with a many:many relationship on `people.my_addresses`. See `Relational Databases for People in a Hurry `_ and the `SQLAlchemy manual`_ for details. .. code-block:: python t_people = sa.Table('people', meta.metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('name', sa.types.String(100)), sa.Column('email', sa.types.String(100)), ) t_addresses_people = sa.Table('addresses_people', meta.metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('person_id', sa.types.Integer, sa.ForeignKey('people.id')), sa.Column('address_id', sa.types.Integer, sa.ForeignKey('addresses.id')), ) t_addresses = sa.Table('addresses', meta.metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('address', sa.types.String(100)), ) class Person(object): pass class Address(object): pass orm.mapper(Address, t_addresses) orm.mapper(Person, t_people, properties = { 'my_addresses' : orm.relation(Address, secondary = t_addresses_people), }) Definitions using "reflection" of an existing database table ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If the table already exists, SQLAlchemy can read the column definitions directly from the database. This is called *reflecting* the table. The advantage of this approach is that it allows you to dispense with the task of specifying the column types in Python code. Reflecting existing database tables must be done inside :func:`init_model` because to perform the reflection, a live database engine is required and this is not available when the module is imported. A live database engine is bound explicitly in the :func:`init_model` function and so enables reflection. (An *engine* is a SQLAlchemy object that knows how to connect to a particular database.) Here's the second example with reflection: .. code-block:: python """The application's model objects""" import sqlalchemy as sa from sqlalchemy import orm from myapp.model import meta def init_model(engine): """Call me before using any of the tables or classes in the model""" # Reflected tables must be defined and mapped here global t_persons t_persons = sa.Table("persons", meta.metadata, autoload=True, autoload_with=engine) orm.mapper(Person, t_persons) meta.Session.configure(bind=engine) meta.engine = engine t_persons = None class Person(object): pass Note how ``t_persons`` and the :func:`orm.mapper` call moved into :func:`init_model`, while the ``Person`` class didn't have to. Also note the ``global t_persons`` statement. This tells Python that ``t_persons`` is a global variable outside the function. ``global`` is required when assigning to a global variable inside a function. It's not required if you're merely modifying a mutable object in place, which is why ``meta`` doesn't have to be declared global. Using the model standalone ^^^^^^^^^^^^^^^^^^^^^^^^^^ You now have everything necessary to use the model in a standalone script such as a cron job, or to test it interactively. You just need to create a SQLAlchemy engine and connect it to the model. This example uses a database "test.sqlite" in the current directory: .. code-block:: pycon % python Python 2.5.1 (r251:54863, Oct 5 2007, 13:36:32) [GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sqlalchemy as sa >>> engine = sa.create_engine("sqlite:///test.sqlite") >>> from myapp import model >>> model.init_model(engine) Now you can use the tables, classes, and Session as described in the `SQLAlchemy manual`_. For example: .. code-block:: python #!/usr/bin/env python import sqlalchemy as sa import tmpapp.model as model import tmpapp.model.meta as meta DB_URL = "sqlite:///test.sqlite" engine = sa.create_engine(DB_URL) model.init_model(engine) # Create all tables, overwriting them if they exist. if hasattr(model, "_Base"): # SQLAlchemy 0.5 Declarative syntax model._Base.metadata.drop_all(bind=engine, checkfirst=True) model._Base.metadata.create_all(bind=engine) else: # SQLAlchemy 0.4 and 0.5 syntax without Declarative meta.metadata.drop_all(bind=engine, checkfirst=True) meta.metadataa.create_all(bind=engine) # Create two records and insert them into the database using the ORM. a = model.Person() a.name = "Aaa" a.email = "aaa@example.com" meta.Session.add(a) b = model.Person() b.name = "Bbb" b.email = "bbb@example.com" meta.Session.add(b) meta.Session.commit() # Display all records in the persons table. print "Database data:" for p in meta.Session.query(model.Person): print "id:", p.id print "name:", p.name print "email:", p.email print .. _multiple_databases: Talking to Multiple Databases at Once ------------------------------------- Some applications need to connect to multiple databases (engines). Some always bind certain tables to the same engines (e.g., a general database and a logging database); this is called "horizontal partitioning". Other applications have several databases with the same structure, and choose one or another depending on the current request. A blogging app with a separate database for each blog, for instance. A few large applications store different records from the same logical table in different databases to prevent the database size from getting too large; this is called "vertical partitioning" or "sharding". The pattern above can accommodate any of these schemes with a few minor changes. First, you can define multiple engines in your config file like this: .. code-block:: ini sqlalchemy.default.url = "mysql://..." sqlalchemy.default.pool_recycle = 3600 sqlalchemy.log.url = "sqlite://..." This defines two engines, "default" and "log", each with its own set of options. Now you have to instantiate every engine you want to use. .. code-block:: python default_engine = engine_from_config(config, 'sqlalchemy.default.') log_engine = engine_from_config(config, 'sqlalchemy.log.') init_model(default_engine, log_engine) Of course you'll have to modify `init_model()` to accept both arguments and create two engines. To bind different tables to different databases, but always with a particular table going to the same engine, use the `binds` argument to `sessionmaker` rather than `bind`: .. code-block:: python binds = {"table1": engine1, "table2": engine2} Session = scoped_session(sessionmaker(binds=binds)) To choose the bindings on a per-request basis, skip the sessionmaker bind(s) argument, and instead put this in your base controller's `\_\_call\_\_` method before the superclass call, or directly in a specific action method: .. code-block:: python meta.Session.configure(bind=meta.engine) `binds=` works the same way here too. Multiple Application Instances ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If you're running multiple instances of the _same_ Pylons application in the same WSGI process (e.g., with Paste HTTPServer's "composite" application), you may run into concurrency issues. The problem is that :class:`Session` is thread local but not application-instance local. We're not sure how much this is really an issue if ``Session.remove()`` is properly called in the base controller, but just in case it becomes an issue, here are possible remedies: 1) Attach the engine(s) to ``pylons.g`` (aka. ``config["pylons.g"]``) rather than to the `meta` module. The globals object is not shared between application instances. 2) Add a scoping function. This prevents the application instances from sharing the same session objects. Add the following function to your model, and pass it as the second argument to `scoped_session`: .. code-block:: python def pylons_scope(): import thread from pylons import config return "Pylons|%s|%s" % (thread.get_ident(), config._current_obj()) Session = scoped_session(sessionmaker(), pylons_scope) If you're affected by this, or think you might be, please bring it up on the pylons-discuss mailing list. We need feedback from actual users in this situation to verify that our advice is correct. Non-SQLAlchemy libraries ======================== Most of these expose only the object-relational mapper; their SQL builder and connection pool are not meant to be used directly. `Storm `_ `Geniusql `_ DB-API ------ All the SQL libraries above are built on top of Python's DB-API, which provides a common low-level interface for interacting with several database engines: MySQL, PostgreSQL, SQLite, Oracle, Firebird, MS-SQL, Access via ODBC, etc. Most programmers do not use DB-API directly because its API is low-level and repetitive and does not provide a connection pool. There's no "DB-API package" to install because it's an abstract interface rather than software. Instead, install the Python package for the particular engine you're interested in. Python's `Database Topic Guide `_ describes the DB-API and lists the package required for each engine. The `sqlite3 `_ package for SQLite is included in Python 2.5. Object Databases ================ Object databases store Python dicts, lists, and classes in pickles, allowing you to access hierarchical data using normal Python statements rather than having to map them to tables, relations, and a foreign language (SQL). `ZODB `_ `Durus `_ [#]_ .. [#] Durus is not thread safe, so you should use its server mode if your application writes to the database. Do not share connections between threads. ZODB is thread safe, so it may be a more convenient alternative. Popular No-SQL Databases ======================== Pylons can also work with other database systems, such as the following: `Schevo `_ uses Durus to combine some features of relational and object databases. It is written in Python. `CouchDb `_ is a document-based database. It features a `Python API `_. The Datastore database in Google App Engine. Pylons-1.0.1/pylons/docs/en/advanced_pylons/0000775000076500000240000000000012012307216020707 5ustar benstaff00000000000000Pylons-1.0.1/pylons/docs/en/advanced_pylons/creating_paste_templates.rst0000664000076500000240000002166411645401275026533 0ustar benstaff00000000000000.. _creating_paste_templates: ======================== Creating Paste templates ======================== Introduction ============ `Python Paste `_ is an extremely powerful package that isn't just about WSGI middleware. The related document :ref:`entry_points_and_plugins` demonstrates how to use entry_points to create simple plugins. This document describes how to write just such a plugin for use Paste's project template creation facility and how to add a command to Paste's ``paster`` script. The example task is to create a template for an imaginary content management system. The template is going to produce a project directory structure for a Python package, so we need to be able to specify a package name. Creating The Directory Structure and Templates ============================================== The directory structure for the new project needs to look like this: .. code-block:: text - default_project - +package+ - __init__.py - static - layout - region - renderer - service - layout - __init__.py - region - __init__.py - renderer - __init__.py - setup.py_tmpl - setup.cfg_tmpl - development.ini_tmpl - README.txt_tmpl - ez_setup.py Of course, the actual project's directory structure might look very different. In fact the ``paster create`` command can even be used to generate directory structures which *aren't* project templates --- although this wasn't what it was designed for. When the ``paster create`` command is run, any directories with ``+package+`` in their name will have that portion of the name replaced by a simplified package name and likewise any directories with ``+egg+`` in their name will have that portion replaced by the name of the egg directory, although we don't make use of that feature in this example. All of the files with ``_tmpl`` at the end of their filenames are treated as templates and will have the variables they contain replaced automatically. All other files will remain unchanged. .. note:: The small templating language used with ``paster create`` in files ending in ``_tmpl`` is described in detail in the `Paste util module documentation `_ When specifying a package name it can include capitalisation and ``_`` characters but it should be borne in mind that the actual name of the package will be the *lowercase* package name with the ``_`` characters removed. If the package name contains an ``_``, the egg name will contain a ``_`` character so occasionally the ``+egg+`` name is different to the ``+package+`` name. To avoid difficulty always recommend to users that they stick with package names that contain no ``_`` characters so that the names remain unique when made lowercase. Implementing the Code ===================== Now that the directory structure has been defined, the next step is to implement the commands that will convert this to a ready-to-run project. The template creation commands are implemented by a class derived from ``paste.script.templates.Template``. This is how our example appears: .. code-block:: python from paste.script.templates import Template, var vars = [ var('version', 'Version (like 0.1)'), var('description', 'One-line description of the package'), var('long_description', 'Multi-line description (in reST)'), var('keywords', 'Space-separated keywords/tags'), var('author', 'Author name'), var('author_email', 'Author email'), var('url', 'URL of homepage'), var('license_name', 'License name'), var('zip_safe', 'True/False: if the package can be distributed as a .zip file', default=False), ] class ArtProjectTemplate(Template): _template_dir = 'templates/default_project' summary = 'Art project template' vars = vars The ``vars`` arguments can all be set at run time and will be available to be used as (in this instance) Cheetah template variables in the files which end ``_tmpl``. For example the ``setup.py_tmpl`` file for the ``default_project`` might look like this: .. code-block:: html+mako from setuptools import setup, find_packages version = ${repr(version)|"0.0"} setup(name=${repr(project)}, version=version, description="${description|nothing}", long_description="""\ ${long_description|nothing}""", classifiers=[], keywords=${repr(keywords)|empty}, author=${repr(author)|empty}, author_email=${repr(author_email)|empty}, url=${repr(url)|empty}, license=${repr(license_name)|empty}, packages=find_packages(exclude=['ez_setup']), include_package_data=True, zip_safe=${repr(bool(zip_safe))|False}, install_requires=[ # Extra requirements go here # ], entry_points=""" [paste.app_factory] main=${package}:make_app """, ) .. note: The list of available classifier strings can be obtained from: ``http://www.python.org/pypi?%3Aaction=list_classifiers`` Note how the variables specified in ``vars`` earlier are used to generate the actual ``setup.py`` file. In order to use the new templates they must be hooked up to the ``paster create`` command by means of an entry point. In the ``setup.py`` file of the project (in which created the project template is going to be stored) we need to add the following: .. code-block:: python entry_points=""" [paste.paster_create_template] art_project=art.entry.template:ArtProjectTemplate """, We also need to add ``PasteScript>=1.3`` to the ``install_requires`` line. .. code-block:: python install_requires=["PasteScript>=1.3"], We just need to install the entry points now by running: .. code-block:: bash python setup.py develop We should now be able to see a list of available templates with this command: .. code-block:: bash $ paster create --list-templates .. note:: Windows users will need to add their Python scripts directory to their path or enter the full version of the command, similar to this: .. code-block:: bash C:\Python24\Scripts\paster.exe create --list-templates You should see the following: .. code-block:: text Available templates: art_project: Art project template basic_package: A basic setuptools-enabled package There may be other projects too. Troubleshooting =============== If the Art entries don't show up, check whether it is possible to import the ``template.py`` file because any errors are simply ignored by the paster create command rather than output as a warning. If the code is correct, the issue might be that the entry points data hasn't been updated. Examine the Python ``site-packages`` directory and delete the ``Art.egg-link`` files, any ``Art*.egg`` files or directories and remove any entries for art from ``easy_install.pth`` (replacing ``Art`` with the name chosen for the project of course). Then re-run ``python setup.py develop`` to install the correct information. If problems are still evident, then running the following code will print out a list of all entry points. It might help track the problem down: .. code-block:: python import pkg_resources for x in pkg_resources.iter_group_name(None, None): print x Using the Template =================== Now that the entry point is working, a new project can be created: .. code-block:: bash $ paster create --template=art TestProject Paster will ask lots of questions based on the variables set up in ``vars`` earlier. Pressing ``return`` will cause the default to be used. The final result is a nice project template ready for people to start coding with. Implementing Pylons Templates ============================= If the development context is subject to a frequent need to create lots of Pylons projects, each with a slightly different setup from the standard Pylons defaults then it is probably desirable to create a customised Pylons template to use when generating projects. This can be done in exactly the way described in this document. First, set up a new Python package, perhaps called something like ``CustomPylons`` (obviously, don't use the Pylons name because Pylons itself is already using it). Then check out the Pylons source code and copy the `pylons/templates/default_project `_ directory into the new project as a starting point. The next stage is to add the custom ``vars`` and ``Template`` class and set up the entry points in the ``CustomPylons`` ``setup.py`` file. After those tasks have been completed, it is then possible to create customised templates (ultimately based on the Pylons one) by using the ``CustomPylons`` package. Pylons-1.0.1/pylons/docs/en/advanced_pylons/entry_points_and_plugins.rst0000664000076500000240000002023411645401275026575 0ustar benstaff00000000000000.. _entry_points_and_plugins: =================================== Using Entry Points to Write Plugins =================================== Introduction ============ An entry point is a Python object in a project's code that is identified by a string in the project's ``setup.py`` file. The entry point is referenced by a group and a name so that the object may be discoverabe. This means that another application can search for all the installed software that has an entry point with a particular group name, and then access the Python object associated with that name. This is extremely useful because it means it is possible to write plugins for an appropriately-designed application that can be loaded at run time. This document describes just such an application. It is important to understand that entry points are a feature of the new Python eggs package format and are *not* a standard feature of Python. To learn about eggs, their benefits, how to install them and how to set them up, see: * `Python Eggs `_ * `Easy Install `_ * `Setuptools `_ If reading the above documentation is inconvenient, suffice it to say that eggs are created via a similar ``setup.py`` file to the one used by Python's own `distutils `_ module --- except that eggs have some powerful extra features such as entry points and the ability to specify module dependencies and have them automatically installed by ``easy_install`` when the application itself is installed. For those developers unfamiliar with ``distutils``: it is the standard mechanism by which Python packages should be distributed. To use it, add a ``setup.py`` file to the desired project, insert the required metadata and specify the important files. The ``setup.py`` file can be used to issue various commands which create distributions of the pacakge in various formats for users to install. Creating Plugins ================ This document describes how to use entry points to create a plugin mechansim which allows new types of content to be added to a content management system but we are going to start by looking at the plugin. Say the standard way the CMS creates a plugin is with the ``make_plugin()`` function. In order for a plugin to be a plugin it must therefore have the function which takes the same arguments as the :func:`make_plugin` function and returns a plugin. We are going to add some image plugins to the CMS so we setup a project with the following directory structure: .. code-block:: text + image_plugins + __init__.py + setup.py The ``image_plugins/__init__.py`` file looks like this: .. code-block:: python def make_jpeg_image_plugin(): return "This would return the JPEG image plugin" def make_png_image_plugin(): return "This would return the PNG image plugin" We have now defined our plugins so we need to define our entry points. First lets write a basic ``setup.py`` for the project: .. code-block:: python from setuptools import setup, find_packages setup( name='ImagePlugins', version="1.0", description="Image plugins for the imaginary CMS 1.0 project", author="James Gardner", packages=find_packages(), include_package_data=True, ) When using ``setuptools`` we can specify the ``find_packages()`` function and ``include_package_data=True`` rather than having to manually list all the modules and package data like we had to do in the old ``distutils`` ``setup.py``. Because the plugin is designed to work with the (imaginary) CMS 1.0 package, we need to specify that the plugin requires the CMS to be installed too and so we add this line to the ``setup()`` function: .. code-block:: python install_requires=["CMS>=1.0"], Now when the plugins are installed, CMS 1.0 or above will be installed automatically if it is not already present. There are lots of other arguments such as ``author_email`` or ``url`` which you can add to the ``setup.py`` function too. We are interested in adding the entry points. We need to decide on a group name for the entry points. It is traditional to use the name of the package using the entry point, separated by a ``.`` character and then use a name that describes what the entry point does. For our example ``cms.plugin`` might be an appropriate name for the entry point. Since the ``image_plugin`` module contains two plugins we will need two entries. Add the following to the ``setup.py`` function: .. code-block:: python entry_points=""" [cms.plugin] jpg_image=image_plugin:make_jpeg_image_plugin png_image=image_plugin:make_jpeg_image_plugin """, Group names are specified in square brackets, plugin names are specified in the format ``name=module.import.path:object_within_the_module``. The object doesn't have to be a function and can have any valid Python name. The module import path doesn't have to be a top level component as it is in this example and the name of the entry point doesn't have to be the same as the name of the object it is pointing to. The developer can add as many entries as desired in each group as long as the names are different and the same holds for adding groups. It is also possible to specify the entry points as a Python dictionary rather than a string if that approach is preferred. There are two more things we need to do to complete the plugin. The first is to include an ``ez_setup`` module so that if the user installing the plugin doesn't have ``setuptools`` installed, it will be installed for them. We do this by adding the follwoing to the very top of the ``setup.py`` file before the import: .. code-block:: python from ez_setup import use_setuptools use_setuptools() We also need to download the ``ez_setup.py`` file into our project directory at the same level as ``setup.py``. .. note:: If you keep your project in SVN there is a `trick you can use with the `SVN:externals `_ to keep the ``ez_setup.py`` file up to date. Finally in order for the CMS to find the plugins we need to install them. We can do this with: .. code-block:: bash $ python setup.py install as usual or, since we might go on to develop the plugins further we can install them using a special development mode which sets up the paths to run the plugins from the source rather than installing them to Python's ``site-packages`` directory: .. code-block:: bash $ python setup.py develop Both commands will download and install ``setuptools`` if you don't already have it installed. Using Plugins ============= Now that the plugin is written we need to write the code in the CMS package to load it. Luckily this is even easier. There are actually lots of ways of discovering plugins. For example: by distribution name and version requirement (such as ``ImagePlugins>=1.0``) or by the entry point group and name (eg ``jpg_image``). For this example we are choosing the latter, here is a simple script for loading the plugins: .. code-block:: python from pkg_resources import iter_entry_points for object in iter_entry_points(group='cms.plugin', name=None): print object() from pkg_resources import iter_entry_points available_methods = [] for method_handler in iter_entry_points(group='authkit.method', name=None): available_methods.append(method_handler.load()) Executing this short script, will result in the following output: .. code-block:: text This would return the JPEG image plugin This would return the PNG image plugin The ``iter_entry_points()`` function has looped though all the objects in the ``cms.plugin`` group and returned the function they were associated with. The application then called the function that the enrty point was pointing to. We hope that we have demonstrated the power of entry points for building extensible code and developers are encouraged to read the `pkg_resources `_ module documentation to learn about some more features of the eggs format. Pylons-1.0.1/pylons/docs/en/advanced_pylons/index.rst0000664000076500000240000000027611645401275022570 0ustar benstaff00000000000000.. _advanced_pylons: =============== Advanced Pylons =============== .. toctree:: :maxdepth: 1 paster paster_commands creating_paste_templates entry_points_and_plugins Pylons-1.0.1/pylons/docs/en/advanced_pylons/paster.rst0000664000076500000240000001122711645401275022755 0ustar benstaff00000000000000.. _paster: WSGI, CLI scripts ================= Working with :class:`wsgiwrappers.WSGIRequest` ---------------------------------------------- Pylons uses a specialised *WSGIRequest* class that is accessible via the ``paste.wsgiwrappers`` module. The ``wsgiwrappers.WSGIRequest`` object represents a WSGI request that has a more programmer-friendly interface. This interface does not expose every detail of the WSGI environment *(why?)* and does not attempt to express anything beyond what is available in the environment dictionary. The only state maintained in this object is the desired ``charset``, an associated errors handler and a ``decode_param_names`` option. .. _note: *Unicode notes* When ``charset`` is set, the incoming parameter values will be automatically coerced to unicode objects of the charset encoding. When unicode is expected, ``charset`` will be overridden by the the value of the charset parameter set in the Content-Type header, if one was specified by the client. The incoming parameter names are not decoded to unicode unless the decode_param_names option is enabled. The class variable ``defaults`` specifies default values for charset, errors, and language. These default values can be overridden for the current request via the registry *(what's a registry?)*. The language default value is considered the fallback during i18n translations to ensure in odd cases that mixed languages don't occur should the language file contain the string but not another language in the accepted languages list. The language value only applies when getting a list of accepted languages from the HTTP Accept header. This behavior is duplicated from Aquarium, and may seem strange but is very useful. Normally, everything in the code is in "en-us". However, the "en-us" translation catalog is usually empty. If the user requests ["en-us", "zh-cn"] and a translation isn't found for a string in "en-us", you don't want gettext to fallback to "zh-cn". You want it to just use the string itself. Hence, if a string isn't found in the language catalog, the string in the source code will be used. All other state is kept in the environment dictionary; this is essential for interoperability. You are free to subclass this object. Attributes ---------- GET ^^^ A dictionary-like object representing the QUERY_STRING parameters. Always present, possibly empty. If the same key is present in the query string multiple times, a list of its values can be retrieved from the :class:`MultiDict` via the :meth:``getall`` method. Returns a :class:`MultiDict` container or, when charset is set, a :class:`UnicodeMultiDict`. POST ^^^^ A dictionary-like object representing the ``POST`` body. Most values are encoded strings, or unicode strings when charset is set. There may also be FieldStorage objects representing file uploads. If this is not a POST request, or the body is not encoded fields (e.g., an XMLRPC request) then this will be empty. This will consume wsgi.input when first accessed if applicable, but the raw version will be put in environ['paste.parsed_formvars']. Returns a MultiDict container or a UnicodeMultiDict when charset is set. cookies ^^^^^^^ A dictionary of cookies, keyed by cookie name. Just a plain dictionary, may be empty but not None. defaults ^^^^^^^^ .. code-block:: python {'errors': 'replace', 'decode_param_names': False, 'charset': None, 'language': 'en-us'} host ^^^^ The host name, as provided in ``HTTP_HOST`` with a fall-back to :envvar:`SERVER_NAME` is_xhr ^^^^^^ Returns a boolean if ``X-Requested-With`` is present and is a ``XMLHttpRequest`` languages ^^^^^^^^^ Returns a (possibly empty) list of preferred languages, most preferred first. params ^^^^^^ A dictionary-like object of keys from ``POST``, ``GET``, ``URL`` dicts Return a key value from the parameters, they are checked in the following order: POST, GET, URL Additional methods supported: ----------------------------- getlist(key) ^^^^^^^^^^^^ Returns a list of all the values by that key, collected from POST, GET, URL dicts Returns a :class:`MultiDict` container or a :class:`UnicodeMultiDict` when :data:`charset` is set. urlvars ^^^^^^^ Return any variables matched in the URL (e.g. wsgiorg.routing_args). Methods ------- __init__(self, environ) ^^^^^^^^^^^^^^^^^^^^^^^ determine_browser_charset(self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Determine the encoding as specified by the browser via the Content-Type's ``charset parameter``, if one is set match_accept(self, mimetypes) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Return a list of specified mime-types that the browser's HTTP Accept header allows in the order provided. Pylons-1.0.1/pylons/docs/en/advanced_pylons/paster_commands.rst0000664000076500000240000001507011645401275024636 0ustar benstaff00000000000000.. _paster_commands: - Adding commands to paster ========================= Adding commands to Paster ========================= Paster command ============== The command line will be ``paster my-command arg1 arg2`` if the current directory is the application egg, or ``paster --plugin=MyPylonsApp my-command arg1 arg2`` otherwise. In the latter case, ``MyPylonsApp`` must have been installed via ``easy_install`` or ``python setup.py develop``. Make a package directory for your commands: .. code-block:: bash $ mkdir myapp/commands $ touch myapp/commands/__init__.py Create a module ``myapp/commands/my_command.py`` like this: .. code-block:: python from paste.script.command import Command class MyCommand(Command): # Parser configuration summary = "--NO SUMMARY--" usage = "--NO USAGE--" group_name = "myapp" parser = Command.standard_parser(verbose=False) def command(self): import pprint print "Hello, app script world!" print print "My options are:" print " ", pprint.pformat(vars(self.options)) print "My args are:" print " ", pprint.pformat(self.args) print print "My parser help is:" print print self.parser.format_help() .. note:: The class _must_ define ``.command``, ``.parser``, and ``.summary`` Modify the ``entry_points`` argument in :file:`setup.py` to contain: .. code-block:: python [paste.paster_command] my-command = myapp.commands.my_command:MyCommand Run ``python setup.py develop`` or ``easy_install .`` to update the entry points in the egg in sys.path. Now you should be able to run: .. code-block:: bash $ paster --plugin=MyApp my-command arg1 arg2 Hello, MyApp script world! My options are: {'interactive': False, 'overwrite': False, 'quiet': 0, 'verbose': 0} My args are: ['arg1', 'arg2'] My parser help is: Usage: /usr/local/bin/paster my-command [options] --NO USAGE-- --NO SUMMARY-- Options: -h, --help show this help message and exit $ paster --plugin=MyApp --help Usage: paster [paster_options] COMMAND [command_options] ... myapp: my-command --NO SUMMARY-- pylons: controller Create a Controller and accompanying functional test restcontroller Create a REST Controller and accompanying functional test shell Open an interactive shell with the Pylons app loaded Required class attributes ========================== In addition to the ``.command`` method, the class should define ``.parser`` and ``.summary``. Command-line options ==================== :func:`Command.standard_parser` returns a Python :obj:`OptionParser`. Calling ``parser.add_option`` enables the developer to add as many options as desired. Inside the ``.command`` method, the user's options are available under ``self.options``, and any additional arguments are in ``self.args``. There are several other class attributes that affect the parser; see them defined in ``paste.script.command:Command``. The most useful attributes are ``.usage``, ``.description``, ``.min_args``, and ``.max_args``. ``.usage`` is the part of the usage string _after_ the command name. The ``.standard_parser()`` method has several optional arguments to add standardized options; some of these got added to my parser although I don't see how. See the ``paster shell`` command, ``pylons.commands:ShellCommand``, for an example of using command-line options and loading the ``.ini file`` and model. Also see "paster setup-app" where it is defined in ``paste.script.appinstall.SetupCommand``. This is evident from the entry point in PasteScript (:file:`PasteScript-VERSION.egg/EGG_INFO/entry_points.txt`). It is a complex example of reading a config file and delegating to another entry point. The code for calling ``myapp.websetup:setup_config`` is in ``paste.script.appinstall``. The ``Command`` class also has several convenience methods to handle console prompts, enable logging, verify directories exist and that files have expected content, insert text into a file, run a shell command, add files to Subversion, parse "var=value" arguments, add variables to an .ini file. Using paster to access a Pylons app =================================== Paster provides ``request`` and ``post`` commands for running requests on an application. These commands will be run in the full configuration context of a normal application. Useful for cron jobs, the error handler will also be in place and you can get email reports of failed requests. Because arguments all just go in ``QUERY_STRING``, ``request.GET`` and ``request.PARAMS`` won't look like you expect. But you can parse them with something like: .. code-block:: python parser = optparse.OptionParser() parser.add_option(etc) args = [item[0] for item in cgi.parse_qsl(request.environ['QUERY_STRING'])] options, args = parser.parse_args(args) paster request / post --------------------- Usage: paster request / post [options] CONFIG_FILE URL [OPTIONS/ARGUMENTS] Run a request for the described application This command makes an artifical request to a web application that uses a ``paste.deploy`` configuration file for the server and application. Use 'paster request config.ini /url' to request ``/url``. Use 'paster post config.ini /url < data' to do a POST with the given request body. If the URL is relative (i.e. doesn't begin with /) it is interpreted as relative to /.command/. The variable ``environ['paste.command_request']`` will be set to True in the request, so your application can distinguish these calls from normal requests. Note that you can pass options besides the options listed here; any unknown options will be passed to the application in ``environ['QUERY_STRING']``. .. code-block:: none Options: -h, --help show this help message and exit -v, --verbose -q, --quiet -n NAME, --app-name=NAME Load the named application (default main) --config-var=NAME:VALUE Variable to make available in the config for %()s substitution (you can use this option multiple times) --header=NAME:VALUE Header to add to request (you can use this option multiple times) --display-headers Display headers before the response body Future development ------------------ A Pylons controller that handled some of this would probably be quite useful. Probably even nicer with additions to the current template, so that ``/.command/`` all gets routed to a single controller that uses actions for the various sub-commands, and can provide a useful response to ``/.command/?-h``, etc. Pylons-1.0.1/pylons/docs/en/caching.rst0000664000076500000240000003275711645401275017715 0ustar benstaff00000000000000.. _caching: ======= Caching ======= Inevitably, there will be occasions during applications development or deployment when some task is revealed to be taking a significant amount of time to complete. When this occurs, the best way to speed things up is with :term:`caching`. Caching is enabled in Pylons using `Beaker`_, the same package that provides session handling. Beaker supports a variety of caching backends: in-memory, database, Google Datastore, filesystem, and memcached. Additional extensions are available that support Tokyo Cabinet, Redis, Dynomite, and Ringo. Back-ends can be added with Beaker's extension system. .. seealso:: `Beaker Extension Add-ons `_ Types of Caching ================ Pylons offers a variety of caching options depending on the granularity of caching desired. Fine-grained caching down to specific sub-sections of a template, arbitrary Python functions, all the way up to entire controller actions and browser-side full-page caching are available. Available caching options (ordered by granularity, least to most specific): * **Browser-side** - HTTP/1.1 supports the :term:`ETag` caching system that allows the browser to use its own cache instead of requiring regeneration of the entire page. ETag-based caching avoids repeated generation of content but if the browser has never seen the page before, the page will still be generated. Therefore using ETag caching in conjunction with one of the other types of caching listed here will achieve optimal throughput and avoid unnecessary calls on resource-intensive operations. * **Controller Actions** - A Pylons controller action can have its entire result cached, including response headers if desired. * **Templates** - The results of an entire rendered template can be cached using the :meth:`3 cache keyword arguments to the render calls `. These render commands can also be used inside templates. * **Arbitrary Functions** - Any function can be independently cached using Beaker's cache decorators. This allows fine-grained caching of just the parts of the code that can be cached. * **Template Fragments** - Built-in caching options are available for both `Mako`_ and `Myghty `_ template engines. They allow fine-grained caching of only certain sections of the template. This is also sometimes called fragment caching since individual fragments of a page can be cached. Namespaces and Keys =================== `Beaker`_ is used for caching arbitrary Python functions, template results, and in `Mako`_ for caching individual `` blocks. Browser-side caching does *not* utilize `Beaker`_. The two primary concepts to bear in mind when caching with `Beaker`_ are: 1. Caches have a *namespace*, this is to organize a cache such that variations of the same thing being cached are associated under a single place. 2. Variations of something being cached, are *keys* which are under that namespace. For example, if we want to cache a function, the function name along with a unique name for it would be considered the *namespace*. The arguments it takes to differentiate the output to cache, are the *keys*. An example of caching with the :func:`~beaker.cache.cache_region` decorator:: @cache_region('short_term', 'search_func') def get_results(search_param): # do something to retrieve data data = get_data(search_param) return data results = get_results('gophers') In this example, the namespace will be the function name + module + 'search_func'. Since a single module might have multiple methods of the same name you wish to cache, the :func:`~beaker.cache.cache_region` decorator takes another argument in addition to the region to use, which is added to the namespace. The key in this example is the `search_param` value. For each value of it, a separate result will be cached. .. seealso:: Stephen Pierzchala's `Caching for Performance `_ (stephen@pierzchala.com) Beaker `Caching Docs `_ Configuring =========== `Beaker`_'s cache options can be easily configured in the project's INI file. Beaker's `configuration documentation `_ explains how to setup the most common options. The cache options specified will be used in the absence of more specific keyword arguments to individual cache functions. Functions that support :ref:`cache_regions` will use the settings for that region. .. _cache_regions: Cache Regions ------------- Cache regions are named groupings of related options. For example, in many web applications, there might be a few cache strategies used in a company, with short-term cached objects ending up in Memcached, and longer-term cached objects stored in the filesystem or a database. Using cache regions makes it easy to declare the cache strategies in one place, then use them throughout the application by referencing the cache strategy name. Cache regions should be setup in the :file:`development.ini` file, but can also be configured and passed directly into the `CacheManager` instance that is created in the :file:`lib/app_globals.py` file. Example INI section for two cache regions (put these under your `[app:main]` section): .. code-block:: ini beaker.cache.regions = short_term, long_term beaker.cache.short_term.type = ext:memcached beaker.cache.short_term.url = 127.0.0.1:11211 beaker.cache.short_term.expire = 3600 beaker.cache.long_term.type = ext:database beaker.cache.long_term.url = mysql://dbuser:dbpass@127.0.0.1/cache_db beaker.cache.long_term.expire = 86400 This sets up two cache regions, `short_term` and `long_term`. Browser-Side ============ Browser-side caching can utilize one of several methods. The entire page can have cache headers associated with it to indicate to the browser that it should be cached. Or, using the ETag Cache header, a page can have more fine-grained caching rules applied. Cache Headers ------------- Cache headers may be set directly on the :class:`~pylons.controllers.util.Response` object by setting the headers directly using the :meth:`~webob.response.Response.headers` property, or by using the cache header helpers. To ensure pages aren’t accidentally cached in dynamic web applications, Pylons default behavior sets the `Pragma` and `Cache-Control` headers to `no-cache`. Before setting cache headers, these default values should be cleared. Clearing the default `no-cache` response headers:: class SampleController(BaseController): def index(self): # Clear the default cache headers del response.headers['Cache-Control'] del response.headers['Pragma'] return render('/index.html) Using the response cache helpers:: # Set an action response to expires in 30 seconds class SampleController(BaseController): def index(self): # Clear the default cache headers del response.headers['Cache-Control'] del response.headers['Pragma'] response.cache_expires(seconds=30) return render('/index.html') # Set the cache-control to private with a max-age of 30 seconds class SampleController(BaseController): def index(self): # Clear the default cache headers del response.headers['Cache-Control'] del response.headers['Pragma'] response.cache_control = {'max-age': 30, 'public': True} return render('/index.html') All of the values that can be passed to the `cache_control` property dict, also may be passed into the `cache_expires` function call. It's recommended that you use the `cache_expires` helper as it also sets the Last-Modified and Expires headers to the second interval as well. .. seealso:: `Cache Control Header RFC `_ E-Tag Caching ------------- Caching via ETag involves sending the browser an ETag header so that it knows to save and possibly use a cached copy of the page from its own cache, instead of requesting the application to send a fresh copy. Because the ETag cache relies on sending headers to the browser, it works in a slightly different manner to the other caching mechanisms. The :func:`~pylons.controllers.util.etag_cache` function will set the proper HTTP headers if the browser doesn't yet have a copy of the page. Otherwise, a 304 HTTP Exception will be thrown that is then caught by Paste middleware and turned into a proper 304 response to the browser. This will cause the browser to use its own locally-cached copy. ETag-based caching requires a single key which is sent in the ETag HTTP header back to the browser. The `RFC specification for HTTP headers `_ indicates that an ETag header merely needs to be a string. This value of this string does not need to be unique for every URL as the browser itself determines whether to use its own copy, this decision is based on the URL and the ETag key. .. code-block:: python def my_action(self): etag_cache('somekey') return render('/show.myt', cache_expire=3600) Or to change other aspects of the response: .. code-block:: python def my_action(self): etag_cache('somekey') response.headers['content-type'] = 'text/plain' return render('/show.myt') The frequency with which an ETag cache key is changed will depend on the web application and the developer's assessment of how often the browser should be prompted to fetch a fresh copy of the page. Controller Actions ================== The :func:`~pylons.decorators.cache.beaker_cache` decorator is for caching the results of a complete controller action. Example: .. code-block:: python from pylons.decorators.cache import beaker_cache class SampleController(BaseController): # Cache this controller action forever (until the cache dir is # cleaned) @beaker_cache() def home(self): c.data = expensive_call() return render('/home.myt') # Cache this controller action by its GET args for 10 mins to memory @beaker_cache(expire=600, type='memory', query_args=True) def show(self, id): c.data = expensive_call(id) return render('/show.myt') By default the decorator uses a composite of all of the decorated function's arguments as the cache key. It can alternatively use a composite of the `request.GET` query args as the cache key when the `query_args` option is enabled. The cache key can be further customized via the `key` argument. .. warning:: By default, the :func:`~pylons.decorators.cache.beaker_cache` decorator will cache the entire response object. This means the headers that were generated during the action will be cached as well. This can be disabled by providing `cache_response = False` to the decorator. Templates ========= All :func:`render ` commands have caching functionality built in. To use it, merely add the appropriate cache keyword to the render call. .. code-block:: python class SampleController(BaseController): def index(self): # Cache the template for 10 mins return render('/index.html', cache_expire=600) def show(self, id): # Cache this version of the template for 3 mins return render('/show.html', cache_key=id, cache_expire=180) def feed(self): # Cache for 20 mins to memory return render('/feed.html', cache_type='memory', cache_expire=1200) def home(self, user): # Cache this version of a page forever (until the cache dir # is cleaned) return render('/home.html', cache_key=user, cache_expire='never') .. note:: At the moment, these functions do not support the use of cache region pre-defined argument sets. Arbitrary Functions =================== Any Python function that returns a pickle-able result can be cached using `Beaker`_. The recommended way to cache functions is to use the :meth:`~beaker.cache.cache_region` decorator. This decorator requires the :ref:`cache_regions` to be configured. Using the :meth:`~beaker.cache.cache_region` decorator:: @cache_region('short_term', 'search_func') def get_results(search_param): # do something to retrieve data data = get_data(search_param) return data results = get_results('gophers') .. seealso:: `Beaker Caching Documentation `_ Invalidating ------------ A cached function can be manually invalidated by using the :meth:`~beaker.cache.region_invalidate` function. Example:: region_invalidate(get_results, None, 'search_func', search_param) Fragments ========= Individual template files, and `` blocks within them can be independently cached. Since the caching system utilizes `Beaker`_, any available `Beaker`_ back-ends are present in `Mako`_ as well. Example:: <%def name="mycomp" cached="True" cache_timeout="30" cache_type="memory"> other text .. seealso:: `Mako Caching Documentation `_ .. _cache: http://en.wikipedia.org/wiki/Cache .. _Beaker: http://beaker.groovie.org .. _Mako: http://www.makotemplates.org/Pylons-1.0.1/pylons/docs/en/concepts.rst0000664000076500000240000002460411645401275020127 0ustar benstaff00000000000000.. _concepts: ================== Concepts of Pylons ================== Understanding the basic concepts of Pylons, the flow of a request and response through the stack and how Pylons operates makes it easier to customize when needed, in addition to clearing up misunderstandings about why things behave the way they do. This section acts as a basic introduction to the concept of a :term:`WSGI` application, and :term:`WSGI Middleware` in addition to showing how Pylons utilizes them to assemble a complete working web framework. To follow along with the explanations below, create a project following the :ref:`getting_started` Guide. ***************************** The 'Why' of a Pylons Project ***************************** A new Pylons project works a little differently than in many other web frameworks. Rather than loading the framework, which then finds a new projects code and runs it, Pylons creates a Python package that does the opposite. That is, when its run, it imports objects from Pylons, assembles the WSGI Application and stack, and returns it. If desired, a new project could be completely cleared of the Pylons imports and run any arbitrary WSGI application instead. This is done for a greater degree of freedom and flexibility in building a web application that works the way the developer needs it to. By default, the project is configured to use standard components that most developers will need, such as sessions, template engines, caching, high level request and response objects, and an :term:`ORM`. By having it all setup in the project (rather than hidden away in 'framework' code), the developer is free to tweak and customize as needed. In this manner, Pylons has setup a project with its *opinion* of what may be needed by the developer, but the developer is free to use the tools needed to accomplish the projects goals. Pylons offers an unprecedented level of customization by exposing its functionality through the project while still maintaining a remarkable amount of simplicity by retaining a single standard interface between core components (:term:`WSGI`). ***************** WSGI Applications ***************** WSGI is a basic specification known as :pep:`333`, that describes a method for interacting with a HTTP server. This involves a way to get access to HTTP headers from the request, and how set HTTP headers and return content on the way back out. A 'Hello World' WSGI Application: .. code-block :: python def simple_app(environ, start_response): start_response('200 OK', [('Content-type', 'text/html')]) return ['Hello World'] This WSGI application does nothing but set a 200 status code for the response, set the HTTP 'Content-type' header, and return some HTML. The WSGI specification lays out a `set of keys that will be set in the environ dict `_. The WSGI interface, that is, this method of calling a function (or method of a class) with two arguments, and handling a response as shown above, is used throughout Pylons as a standard interface for passing control to the next component. Inside a new project's :file:`config/middleware.py`, the `make_app` function is responsible for creating a WSGI application, wrapping it in WSGI middleware (explained below) and returning it so that it may handle requests from a HTTP server. .. _wsgi-middleware: *************** WSGI Middleware *************** Within :file:`config/middleware.py` a Pylons application is wrapped in successive layers which add functionality. The process of wrapping the Pylons application in middleware results in a structure conceptually similar to the layers in an onion. .. image:: _static/pylons_as_onion.png :alt: Pylons middleware onion analogy :align: center Once the middleware has been used to wrap the Pylons application, the make_app function returns the completed app with the following structure (outermost layer listed first): .. code-block:: text Registry Manager Status Code Redirect Error Handler Cache Middleware Session Middleware Routes Middleware Pylons App (WSGI Application) WSGI middleware is used extensively in Pylons to add functionality to the base WSGI application. In Pylons, the 'base' WSGI Application is the :class:`~pylons.wsgiapp.PylonsApp`. It's responsible for looking in the `environ` dict that was passed in (from the Routes Middleware). To see how this functionality is created, consider a small class that looks at the `HTTP_REFERER` header to see if it's Google: .. code-block :: python class GoogleRefMiddleware(object): def __init__(self, app): self.app = app def __call__(self, environ, start_response): environ['google'] = False if 'HTTP_REFERER' in environ: if environ['HTTP_REFERER'].startswith('http://google.com'): environ['google'] = True return self.app(environ, start_response) This is considered WSGI Middleware as it still can be called and returns like a WSGI Application, however, it's adding something to environ, and then calls a WSGI Application that it is initialized with. That's how the layers are built up in the `WSGI Stack` that is configured for a new Pylons project. Some of the layers, like the Session, Routes, and Cache middleware, only add objects to the `environ` dict, or add HTTP headers to the response (the Session middleware for example adds the session cookie header). Others, such as the Status Code Redirect, and the Error Handler may fully intercept the request entirely, and change how it's responded to. ******************* Controller Dispatch ******************* When the request passes down the middleware, the incoming URL gets parsed in the RoutesMiddleware, and if it matches a URL (See :ref:`url-config`), the information about the controller that should be called is put into the `environ` dict for use by :class:`~pylons.wsgiapp.PylonsApp`. The :class:`~pylons.wsgiapp.PylonsApp` then attempts to find a controller in the :file:`controllers` directory that matches the name of the controller, and searches for a class inside it by a similar scheme (controller name + 'Controller', ie, HelloController). Upon finding a controller, its then called like any other WSGI application using the same WSGI interface that :class:`~pylons.wsgiapp.PylonsApp` was called with. .. versionadded:: 1.0 Controller name can also be a dotted path to the module / callable that should be imported and called. For example, to use a controller named 'Foo' that is in the 'bar.controllers' package, the controller name would be `bar.controllers:Foo`. This is why the BaseController that resides in a project's :file:`lib/base.py` module inherits from :class:`~pylons.controllers.core.WSGIController` and has a `__call__` method that takes the `environ` and `start_response`. The :class:`~pylons.controllers.core.WSGIController` locates a method in the class that corresponds to the `action` that Routes found, calls it, and returns the response completing the request. ****** Paster ****** Running the :command:`paster` command all by itself will show the sets of commands it accepts: .. code-block :: bash $ paster Usage: paster [paster_options] COMMAND [command_options] Options: --version show program's version number and exit --plugin=PLUGINS Add a plugin to the list of commands (plugins are Egg specs; will also require() the Egg) -h, --help Show this help message Commands: create Create the file layout for a Python distribution grep Search project for symbol help Display help make-config Install a package and create a fresh config file/directory points Show information about entry points post Run a request for the described application request Run a request for the described application serve Serve the described application setup-app Setup an application, given a config file pylons: controller Create a Controller and accompanying functional test restcontroller Create a REST Controller and accompanying functional test shell Open an interactive shell with the Pylons app loaded If :command:`paster` is run inside of a Pylons project, this should be the output that will be printed. The last section, `pylons` will be absent if it is not run inside a Pylons project. This is due to a dynamic plugin system the :command:`paster` script uses, to determine what sets of commands should be made available. Inside a Pylons project, there is a directory ending in `.egg-info`, that has a :file:`paster_plugins.txt` file in it. This file is looked for and read by the :command:`paster` script, to determine what other packages should be searched dynamically for commands. Pylons makes several commands available for use in a Pylons project, as shown above. *********************** Loading the Application *********************** Running (and thus loading) an application is done using the :command:`paster` command: .. code-block :: bash $ paster serve development.ini This instructs the paster script to go into a 'serve' mode. It will attempt to load both a server and a WSGI application that should be served, by parsing the configuration file specified. It looks for a `[server]` block to determine what server to use, and an `[app]` block for what WSGI application should be used. The basic egg block in the :file:`development.ini` for a `helloworld` project: .. code-block :: ini [app:main] use = egg:helloworld That will tell paster that it should load the helloworld :term:`egg` to locate a WSGI application. A new Pylons application includes a line in the :file:`setup.py` that indicates what function should be called to make the WSGI application: .. code-block :: python entry_points=""" [paste.app_factory] main = helloworld.config.middleware:make_app [paste.app_install] main = pylons.util:PylonsInstaller """, Here, the `make_app` function is specified as the `main` WSGI application that Paste (the package that :command:`paster` comes from) should use. The `make_app` function from the project is then called, and the server (by default, a HTTP server) runs the WSGI application. Pylons-1.0.1/pylons/docs/en/conf.py0000644000076500000240000001244612012306152017040 0ustar benstaff00000000000000# -*- coding: utf-8 -*- # # Pylons documentation build configuration file, created by # sphinx-quickstart on Mon Apr 21 20:41:33 2008. # # This file is execfile()d with the current directory set to its containing dir. # # The contents of this file are pickled, so don't put values in the namespace # that aren't pickleable (module imports are okay, they're removed automatically). # # All configuration values have a default value; values that are commented out # serve to show the default value. import sys, os # If your extensions are in another directory, add it here. #sys.path.append('some/directory') sys.path.append(os.path.dirname(os.path.abspath(__file__))) # General configuration # --------------------- # 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'] intersphinx_mapping = { 'http://www.sqlalchemy.org/docs/': None, 'http://sluggo.scrapping.cc/python/WebHelpers/': None, 'http://routes.groovie.org/': None, 'http://beaker.groovie.org/': None, } # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General substitutions. project = 'Pylons Framework' copyright = '2008-2012, Ben Bangert, James Gardner, Philip Jenvey' # The default replacements for |version| and |release|, also used in various # other places throughout the built documents. # # The short X.Y version. version = '1.0.1' # The full version, including alpha/beta/rc tags. release = '1.0.1' # 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 documents that shouldn't be included in the build. #unused_docs = [] # 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 # The name of the Pygments (syntax highlighting) style to use. #pygments_style = 'sphinx' # Options for HTML output # ----------------------- # Add and use Pylons theme from subprocess import call, Popen, PIPE p = Popen('which git', shell=True, stdout=PIPE) git = p.stdout.read().strip() cwd = os.getcwd() _themes = os.path.join(cwd, '_themes') if not os.path.isdir(_themes): call([git, 'clone', 'git://github.com/Pylons/pylons_sphinx_theme.git', '_themes']) else: os.chdir(_themes) call([git, 'checkout', 'master']) call([git, 'pull']) os.chdir(cwd) sys.path.append(os.path.abspath('_themes')) html_theme_path = ['_themes'] html_theme = 'pylonsfw' html_theme_options = dict( github_url='https://github.com/Pylons/pylons' ) # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. #html_style = 'default.css' # 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 # Content template for the index page. #html_index = '' # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # 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 = True # If true, the reST sources are included in the HTML build as _sources/. #html_copy_source = True # Output file base name for HTML help builder. htmlhelp_basename = 'Pylonsfwdoc' # Options for LaTeX output # ------------------------ # The paper size ('letter' or 'a4'). latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ ('index', 'Pylons.tex', 'Pylons Reference Documentation', 'Ben Bangert, Graham Higgins, James Gardner, Philip Jenvey', 'manual', 'toctree_only'), ] # Additional stuff for the LaTeX preamble. latex_preamble = ''' \usepackage{palatino} \definecolor{TitleColor}{rgb}{0.7,0,0} \definecolor{InnerLinkColor}{rgb}{0.7,0,0} \definecolor{OuterLinkColor}{rgb}{0.8,0,0} \definecolor{VerbatimColor}{rgb}{0.985,0.985,0.985} \definecolor{VerbatimBorderColor}{rgb}{0.8,0.8,0.8} ''' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. latex_use_modindex = False Pylons-1.0.1/pylons/docs/en/configuration.rst0000664000076500000240000004360711645401275021164 0ustar benstaff00000000000000.. _configuration: ============= Configuration ============= Pylons comes with two main ways to configure an application: * The configuration file (:ref:`run-config`) * The application's ``config`` directory The files in the ``config`` directory change certain aspects of how the application behaves. Any options that the webmaster should be able to change during deployment should be specified in a configuration file. .. tip:: A good indicator of whether an option should be set in the ``config`` directory code vs. the configuration file is whether or not the option is necessary for the functioning of the application. If the application won't function without the setting, it belongs in the appropriate :file:`config/` directory file. If the option should be changed depending on deployment, it belongs in the :ref:`run-config`. The applications :file:`config/` directory includes: * :file:`config/environment.py` described in :ref:`environment-config` * :file:`config/middleware.py` described in :ref:`middleware-config` * :file:`config/deployment.ini_tmpl` described in :ref:`production-config` * :file:`config/routing.py` described in :ref:`url-config` Each of these files allows developers to change key aspects of how the application behaves. .. _run-config: ********************* Runtime Configuration ********************* When a new project is created a sample configuration file called :file:`development.ini` is automatically produced as one of the project files. This default configuration file contains sensible options for development use, for example when developing a Pylons application it is very useful to be able to see a debug report every time an error occurs. The :file:`development.ini` file includes options to enable debug mode so these errors are shown. Since the configuration file is used to determine which application is run, multiple configuration files can be used to easily toggle sets of options. Typically a developer might have a ``development.ini`` configuration file for testing and a ``production.ini`` file produced by the :command:`paster make-config` command for testing the command produces sensible production output. A :file:`test.ini` configuration is also included in the project for test-specific options. To specify a configuration file to use when running the application, change the last part of the :command:`paster serve` to include the desired config file: .. code-block :: bash $ paster serve production.ini .. seealso:: Configuration file format **and options** are described in great detail in the `Paste Deploy documentation `_. Getting Information From Configuration Files ============================================ All information from the configuration file is available in the ``pylons.config`` object. ``pylons.config`` also contains application configuration as defined in the project's :file:`config.environment` module. .. code-block :: python from pylons import config ``pylons.config`` behaves like a dictionary. For example, if the configuration file has an entry under the ``[app:main]`` block: .. code-block :: ini cache_dir = %(here)s/data That can then be read in the projects code: .. code-block :: python from pylons import config cache_dir = config['cache.dir'] Or the current debug status like this: .. code-block :: python debug = config['debug'] Evaluating Non-string Data in Configuration Files ------------------------------------------------- By default, all the values in the configuration file are considered strings. To make it easier to handle boolean values, the Paste library comes with a function that will convert ``true`` and ``false`` to proper Python boolean values: .. code-block :: python from paste.deploy.converters import asbool debug = asbool(config['debug']) This is used already in the default projects' :ref:`middleware-config` to toggle middleware that should only be used in development mode (with ``debug``) set to true. .. _production-config: Production Configuration Files ============================== To change the defaults of the configuration INI file that should be used when deploying the application, edit the :file:`config/deployment.ini_tmpl` file. This is the file that will be used as a template during deployment, so that the person handling deployment has a starting point of the minimum options the application needs set. One of the most important options set in the deployment ini is the ``debug = true`` setting. The email options should be setup so that errors can be e-mailed to the appropriate developers or webmaster in the event of an application error. Generating the Production Configuration --------------------------------------- To generate the production.ini file from the projects' :file:`config/deployment.ini_tmpl` it must first be installed either as an :term:`egg` or under development mode. Assuming the name of the Pylons application is ``helloworld``, run: .. code-block :: bash $ paster make-config helloworld production.ini .. note:: This command will also work from inside the project when its being developed. It is the responsibility of the developer to ensure that a sensible set of default configuration values exist when the webmaster uses the ``paster make-config`` command. .. warning:: **Always** make sure that the ``debug`` is set to ``false`` when deploying a Pylons application. .. _environment-config: *********** Environment *********** The :file:`config/environment.py` module sets up the basic Pylons environment variables needed to run the application. Objects that should be setup once for the entire application should either be setup here, or in the :file:`lib/app_globals` :meth:`__init__` method. It also calls the :ref:`url-config` function to setup how the URL's will be matched up to :ref:`controllers`, creates the :term:`app_globals` object, configures which module will be referred to as :term:`h`, and is where the template engine is setup. When using SQLAlchemy it's recommended that the SQLAlchemy engine be setup in this module. The default SQLAlchemy configuration that Pylons comes with creates the engine here which is then used in :file:`model/__init__.py`. .. _url-config: ***************** URL Configuration ***************** A Python library called Routes handles mapping URLs to controllers and their methods, or their :term:`action` as Routes refers to them. By default, Pylons sets up the following :term:`route`\s (found in :file:`config/routing.py`): .. code-block:: python map.connect('/{controller}/{action}') map.connect('/{controller}/{action}/{id}') .. versionchanged:: 0.9.7 Prior to Routes 1.9, all map.connect statements required variable parts to begin with a ``:`` like ``map.connect(':controller/:action')``. This syntax is now optional, and the new ``{}`` syntax is recommended. Any part of the path inside the curly braces is a variable (a `variable part` ) that will match any text in the URL for that 'part'. A 'part' of the URL is the text between two forward slashes. Every part of the URL must be present for the :term:`route` to match, otherwise a 404 will be returned. The routes above are translated by the Routes library into regular expressions for high performance URL matching. By default, all the variable parts (except for the special case of ``{controller}``) become a matching regular expression of ``[^/]+`` to match anything except for a forward slash. This can be changed easily, for example to have the ``{id}`` only match digits: .. code-block :: python map.connect('/{controller}/{action}/{id:\d+}') If the desired regular expression includes the ``{}``, then it should be specified separately for the variable part. To limit the ``{id}`` to only match at least 2-4 digits: .. code-block :: python map.connect('/{controller}/{action}/{id}', requirements=dict(id='\d{2,4}')) The controller and action can also be specified as keyword arguments so that they don't need to be included in the URL: .. code-block :: python # Archives by 2 digit year -> /archives/08 map.connect('/archives/{year:\d\d}', controller='articles', action='archives') Any variable part, or keyword argument in the ``map.connect`` statement will be available for use in the action used. For the route above, which resolves to the `articles` controller: .. code-block :: python class ArticlesController(BaseController): def archives(self, year): ... The part of the URL that matched as the year is available by name in the function argument. .. note:: Routes also includes the ability to attempt to 'minimize' the URL. This behavior is generally not intuitive, and starting in Pylons 0.9.7 is turned off by default with the ``map.minimization=False`` setting. The default mapping can match to any controller and any of their actions which means the following URLs will match: .. code-block:: text /hello/index >> controller: hello, action: index /entry/view/4 >> controller: entry, action: view, id:4 /comment/edit/2 >> controller: comment, action: edit, id:2 This simple scheme can be suitable for even large applications when complex URL's aren't needed. Controllers can be organized into directories as well. For example, if the admins should have a separate ``comments`` controller: .. code-block:: bash $ paster controller admin/comments Will create the ``admin`` directory along with the appropriate ``comments`` controller under it. To get to the comments controller: .. code-block:: text /admin/comments/index >> controller: admin/comments, action: index .. note:: The ``{controller}`` match is special, in that it doesn't always stop at the next forward slash (``/``). As the example above demonstrates, it is able to match controllers nested under a directory should they exist. Adding a route to match ``/`` ============================= The controller and action can be specified directly in the :meth:`map.connect` statement, as well as the raw URL to be matched: .. code-block:: python map.connect('/', controller='main', action='index') results in ``/`` being handled by the ``index`` method of the ``main`` controller. .. note:: By default, projects' static files (in the :file:`public/` directory) are served in preference to controllers. New Pylons projects include a welcome page (:file:`public/index.html`) that shows up at the ``/`` url. You'll want to remove this file before mapping a route there. Generating URLs =============== URLs are generated via the callable :class:`routes.util.URLGenerator` object. Pylons provides an instance of this special object at :data:`pylons.url`. It accepts keyword arguments indicating the desired controller, action and additional variables defined in a route. .. code-block:: python # generates /content/view/2 url(controller='content', action='view', id=2) To generate the URL of the matched route of the current request, call :meth:`routes.util.URLGenerator.current`: .. code-block:: python # Generates /content/view/3 during a request for /content/view/3 url.current() :meth:`routes.util.URLGenerator.current` also accepts the same arguments as `url()`. This uses `Routes memory `_ to generate a small change to the current URL without the need to specify all the relevant arguments: .. code-block:: python # Generates /content/view/2 during a request for /content/view/3 url.current(id=2) .. seealso:: `Routes manual `_ Full details and source code. .. _middleware-config: ********** Middleware ********** A projects WSGI stack should be setup in the :file:`config/middleware.py` module. Ideally this file should import middleware it needs, and set it up in the `make_app` function. The default stack that is setup for a Pylons application is described in detail in :ref:`wsgi-middleware`. Default middleware stack: .. code-block :: python # The Pylons WSGI app app = PylonsApp() # Routing/Session/Cache Middleware app = RoutesMiddleware(app, config['routes.map']) app = SessionMiddleware(app, config) app = CacheMiddleware(app, config) # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) if asbool(full_stack): # Handle Python exceptions app = ErrorHandler(app, global_conf, **config['pylons.errorware']) # Display error documents for 401, 403, 404 status codes (and # 500 when debug is disabled) if asbool(config['debug']): app = StatusCodeRedirect(app) else: app = StatusCodeRedirect(app, [400, 401, 403, 404, 500]) # Establish the Registry for this application app = RegistryManager(app) if asbool(static_files): # Serve static files static_app = StaticURLParser(config['pylons.paths']['static_files']) app = Cascade([static_app, app]) return app Since each piece of middleware wraps the one before it, the stack needs to be assembled in reverse order from the order in which its called. That is, the very last middleware that wraps the WSGI Application, is the very first that will be called by the server. The last piece of middleware in the stack, called Cascade, is used to serve static content files during development. For top performance, consider disabling the Cascade middleware via setting the ``static_files = false`` in the configuration file. Then have the webserver or a :term:`CDN` serve static files. .. warning:: When unsure about whether or not to change the middleware, **don't**. The order of the middleware is important to the proper functioning of a Pylons application, and shouldn't be altered unless needed. Adding custom middleware ======================== Custom middleware should be included in the :file:`config/middleware.py` at comment marker:: # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) For example, to add a middleware component named `MyMiddleware`, include it in :file:`config/middleware.py`:: # The Pylons WSGI app app = PylonsApp() # Routing/Session/Cache Middleware app = RoutesMiddleware(app, config['routes.map']) app = SessionMiddleware(app, config) app = CacheMiddleware(app, config) # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) app = MyMiddleware(app) The app object is simply passed as a parameter to the `MyMiddleware` middleware which in turn should return a wrapped WSGI application. Care should be taken when deciding in which layer to place custom middleware. In most cases middleware should be placed before the Pylons WSGI application and its supporting Routes/Session/Cache middlewares, however if the middleware should run *after* the CacheMiddleware:: # Routing/Session/Cache Middleware app = RoutesMiddleware(app, config['routes.map']) app = SessionMiddleware(app, config) # MyMiddleware can only see the cache object, nothing *above* here app = MyMiddleware(app) app = CacheMiddleware(app, config) What is full_stack? =================== In the Pylons ini file {:file:`development.ini` or :file:`production.ini`} this block determines if the flag full_stack is set to true or false:: [app:main] use = egg:app_name full_stack = true The full_stack flag determines if the ErrorHandler and StatusCodeRedirect is included as a layer in the middleware wrapping process. The only condition in which this option would be set to `false` is if multiple Pylons applications are running and will be wrapped in the appropriate middleware elsewhere. .. _setup-config: ***************** Application Setup ***************** There are two kinds of 'Application Setup' that are occasionally referenced with regards to a project using Pylons. * Setting up a new application * Configuring project information and package dependencies Setting Up a New Application ============================ To make it easier to setup a new instance of a project, such as setting up the basic database schema, populating necessary defaults, etc. a setup script can be created. In a Pylons project, the setup script to be run is located in the projects' :file:`websetup.py` file. The default script loads the projects configuration to make it easier to write application setup steps: .. code-block :: python import logging from helloworld.config.environment import load_environment log = logging.getLogger(__name__) def setup_app(command, conf, vars): """Place any commands to setup helloworld here""" load_environment(conf.global_conf, conf.local_conf) .. note:: If the project was configured during creation to use SQLAlchemy this file will include some commands to setup the database connection to make it easier to setup database tables. To run the setup script using the development configuration: .. code-block :: bash $ paster setup-app development.ini Configuring the Package ======================= A newly created project with Pylons is a standard Python package. As a Python package, it has a :file:`setup.py` file that records meta-information about the package. Most of the options in it are fairly self-explanatory, the most important being the 'install_requires' option: .. code-block :: python install_requires=[ "Pylons>=0.9.7", ], These lines indicate what packages are required for the proper functioning of the application, and should be updated as needed. To re-parse the :file:`setup.py` line for new dependencies: .. code-block :: bash $ python setup.py develop In addition to updating the packages as needed so that the dependency requirements are made, this command will ensure that this package is active in the system (without requiring the traditional :command:`python setup.py install`). .. seealso:: `Declaring Dependencies `_ Pylons-1.0.1/pylons/docs/en/controllers.rst0000664000076500000240000005741211645401275020662 0ustar benstaff00000000000000.. _controllers: =========== Controllers =========== .. image:: _static/pylon2.jpg :alt: :align: left :height: 450px :width: 368px In the :term:`MVC` paradigm the *controller* interprets the inputs, commanding the model and/or the view to change as appropriate. Under Pylons, this concept is extended slightly in that a Pylons controller is not directly interpreting the client's request, but is acting to determine the appropriate way to assemble data from the model, and render it with the correct template. The controller interprets requests from the user and calls portions of the model and view as necessary to fulfill the request. So when the user clicks a Web link or submits an HTML form, the controller itself doesn’t output anything or perform any real processing. It takes the request and determines which model components to invoke and which formatting to apply to the resulting data. Pylons uses a class, where the superclass provides the :term:`WSGI` interface and the subclass implements the application-specific controller logic. The Pylons WSGI Controller handles incoming web requests that are dispatched from the Pylons WSGI application :class:`~pylons.wsgiapp.PylonsApp`. These requests result in a new instance of the :class:`~pylons.controllers.core.WSGIController` being created, which is then called with the dict options from the Routes match. The standard WSGI response is then returned with start_response called as per the WSGI spec. Since Pylons controllers are actually called with the WSGI interface, normal WSGI applications can also be Pylons ‘controllers’. Standard Controllers ==================== Standard Controllers intended for subclassing by web developers Keeping methods private ----------------------- The default route maps any controller and action, so you will likely want to prevent some controller methods from being callable from a URL. Pylons uses the default Python convention of private methods beginning with ``_``. To hide a method ``edit_generic`` in this class, just changing its name to begin with ``_`` will be sufficient: .. code-block:: python class UserController(BaseController): def index(self): return "This is the index." def _edit_generic(self): """I can't be called from the web!""" return True Special methods --------------- Special controller methods you may define: ``__before__`` This method is called before your action is, and should be used for setting up variables/objects, restricting access to other actions, or other tasks which should be executed before the action is called. ``__after__`` This method is called after the action is, unless an unexpected exception was raised. Subclasses of :class:`~webob.exc.HTTPException` (such as those raised by ``redirect_to`` and ``abort``) are expected; e.g. ``__after__`` will be called on redirects. Adding Controllers dynamically ------------------------------ It is possible for an application to add controllers without restarting the application. This requires telling Routes to re-scan the controllers directory. New controllers may be added from the command line with the paster command (recommended as that also creates the test harness file), or any other means of creating the controller file. For Routes to become aware of new controllers present in the controller directory, an internal flag is toggled to indicate that Routes should rescan the directory: .. code-block:: python from routes import request_config mapper = request_config().mapper mapper._created_regs = False On the next request, Routes will rescan the controllers directory and those routes that use the ``:controller`` dynamic part of the path will be able to match the new controller. Customizing the Controller Name ------------------------------- By default, Pylons looks for a controller named 'Something'Controller. This naming scheme can be overridden by supplying an optional module-level variable called ``__controller__`` to indicate the desired controller class:: import logging from pylons import request, response, session, tmpl_context as c from pylons.controllers.util import abort, redirect_to from helloworld.lib.base import BaseController, render log = logging.getLogger(__name__) __controller__ = 'Hello' class Hello(BaseController): def index(self): # Return a rendered template #return render('/hello.mako') # or, return a string return 'Hello World' Attaching WSGI apps ------------------- .. note:: This recipe assumes a basic level of familiarity with the WSGI Specification (PEP 333) WSGI runs deep through Pylons, and is present in many parts of the architecture. Since Pylons controllers are actually called with the WSGI interface, normal WSGI applications can also be Pylons 'controllers'. Optionally, if a full WSGI app should be mounted and handle the remainder of the URL, Routes can automatically move the right part of the URL into the :envvar:`SCRIPT_NAME`, so that the WSGI application can properly handle its :envvar:`PATH_INFO` part. This recipe will demonstrate adding a basic WSGI app as a Pylons controller. Create a new controller file in your Pylons project directory: .. code-block:: python $ paster controller wsgiapp This sets up the basic imports that you may want available when using other WSGI applications. Edit your controller so it looks like this: .. code-block:: python import logging from YOURPROJ.lib.base import * log = logging.getLogger(__name__) def WsgiappController(environ, start_response): start_response('200 OK', [('Content-type', 'text/plain')]) return ["Hello World"] When hooking up other WSGI applications, they will expect the part of the URL that was used to get to this controller to have been moved into :envvar:`SCRIPT_NAME`. :mod:`Routes ` can properly adjust the environ if a map route for this controller is added to the :file:`config/routing.py` file: .. code-block:: python # CUSTOM ROUTES HERE # Map the WSGI application map.connect('wsgiapp/{path_info:.*}', controller='wsgiapp') By specifying the ``path_info`` dynamic path, Routes will put everything leading up to the ``path_info`` in the :envvar:`SCRIPT_NAME` and the rest will go in the :envvar:`PATH_INFO`. Using the WSGI Controller to provide a WSGI service =================================================== The Pylons WSGI Controller -------------------------- Pylons' own WSGI Controller follows the WSGI spec for calling and return values The Pylons WSGI Controller handles incoming web requests that are dispatched from ``PylonsApp``. These requests result in a new instance of the ``WSGIController`` being created, which is then called with the dict options from the Routes match. The standard WSGI response is then returned with :meth:`start_response` called as per the WSGI spec. WSGIController methods ---------------------- Special ``WSGIController`` methods you may define: ``__before__`` This method will be run before your action is, and should be used for setting up variables/objects, restricting access to other actions, or other tasks which should be executed before the action is called. ``__after__`` Method to run after the action is run. This method will *always* be run after your method, even if it raises an Exception or redirects. Each action to be called is inspected with :meth:`_inspect_call` so that it is only passed the arguments in the Routes match dict that it asks for. The arguments passed into the action can be customized by overriding the :meth:`_get_method_args` function which is expected to return a dict. In the event that an action is not found to handle the request, the Controller will raise an "Action Not Found" error if in debug mode, otherwise a ``404 Not Found`` error will be returned. .. _rest_controller: Using the REST Controller with a RESTful API ============================================ Using the paster restcontroller template ---------------------------------------- .. code-block:: bash $ paster restcontroller --help Create a REST Controller and accompanying functional test The RestController command will create a REST-based Controller file for use with the :meth:`~routes.base.Mapper.resource` REST-based dispatching. This template includes the methods that :meth:`~routes.base.Mapper.resource` dispatches to in addition to doc strings for clarification on when the methods will be called. The first argument should be the singular form of the REST resource. The second argument is the plural form of the word. If its a nested controller, put the directory information in front as shown in the second example below. Example usage: .. code-block:: bash $ paster restcontroller comment comments Creating yourproj/yourproj/controllers/comments.py Creating yourproj/yourproj/tests/functional/test_comments.py If you'd like to have controllers underneath a directory, just include the path as the controller name and the necessary directories will be created for you: .. code-block:: bash $ paster restcontroller admin/trackback admin/trackbacks Creating yourproj/controllers/admin Creating yourproj/yourproj/controllers/admin/trackbacks.py Creating yourproj/yourproj/tests/functional/test_admin_trackbacks.py An Atom-Style REST Controller for Users --------------------------------------- .. code-block:: python # From http://pylonshq.com/pasties/503 import logging from formencode.api import Invalid from pylons import url from simplejson import dumps from restmarks.lib.base import * log = logging.getLogger(__name__) class UsersController(BaseController): """REST Controller styled on the Atom Publishing Protocol""" # To properly map this controller, ensure your # config/routing.py file has a resource setup: # map.resource('user', 'users') def index(self, format='html'): """GET /users: All items in the collection.
@param format the format passed from the URI. """ #url('users') users = model.User.select() if format == 'json': data = [] for user in users: d = user._state['original'].data del d['password'] d['link'] = url('user', id=user.name) data.append(d) response.headers['content-type'] = 'text/javascript' return dumps(data) else: c.users = users return render('/users/index_user.mako') def create(self): """POST /users: Create a new item.""" # url('users') user = model.User.get_by(name=request.params['name']) if user: # The client tried to create a user that already exists abort(409, '409 Conflict', headers=[('location', url('user', id=user.name))]) else: try: # Validate the data that was sent to us params = model.forms.UserForm.to_python(request.params) except Invalid, e: # Something didn't validate correctly abort(400, '400 Bad Request -- %s' % e) user = model.User(**params) model.objectstore.flush() response.headers['location'] = url('user', id=user.name) response.status_code = 201 c.user_name = user.name return render('/users/created_user.mako') def new(self, format='html'): """GET /users/new: Form to create a new item. @param format the format passed from the URI. """ # url('new_user') return render('/users/new_user.mako') def update(self, id): """PUT /users/id: Update an existing item. @param id the id (name) of the user to be updated """ # Forms posted to this method should contain a hidden field: # # Or using helpers: # h.form(url('user', id=ID), # method='put') # url('user', id=ID) old_name = id new_name = request.params['name'] user = model.User.get_by(name=id) if user: if (old_name != new_name) and model.User.get_by(name=new_name): abort(409, '409 Conflict') else: params = model.forms.UserForm.to_python(request.params) user.name = params['name'] user.full_name = params['full_name'] user.email = params['email'] user.password = params['password'] model.objectstore.flush() if user.name != old_name: abort(301, '301 Moved Permanently', [('Location', url('users', id=user.name))]) else: return def delete(self, id): """DELETE /users/id: Delete an existing item. @param id the id (name) of the user to be updated """ # Forms posted to this method should contain a hidden field: # # Or using helpers: # h.form(url('user', id=ID), # method='delete') # url('user', id=ID) user = model.User.get_by(name=id) user.delete() model.objectstore.flush() return def show(self, id, format='html'): """GET /users/id: Show a specific item. @param id the id (name) of the user to be updated. @param format the format of the URI requested. """ # url('user', id=ID) user = model.User.get_by(name=id) if user: if format=='json': data = user._state['original'].data del data['password'] data['link'] = url('user', id=user.name) response.headers['content-type'] = 'text/javascript' return dumps(data) else: c.data = user return render('/users/show_user.mako') else: abort(404, '404 Not Found') def edit(self, id, format='html'): """GET /users/id;edit: Form to edit an existing item. @param id the id (name) of the user to be updated. @param format the format of the URI requested. """ # url('edit_user', id=ID) user = model.User.get_by(name=id) if not user: abort(404, '404 Not Found') # Get the form values from the table c.values = model.forms.UserForm.from_python(user.__dict__) return render('/users/edit_user.mako') .. _xmlrpc_controller: Using the XML-RPC Controller for XML-RPC requests ================================================= In order to deploy this controller you will need at least a passing familiarity with XML-RPC itself. We will first review the basics of XML-RPC and then describe the workings of the ``Pylons XMLRPCController``. Finally, we will show an example of how to use the controller to implement a simple web service. After you've read this document, you may be interested in reading the companion document: "A blog publishing web service in XML-RPC" which takes the subject further, covering details of the MetaWeblog API (a popular XML-RPC service) and demonstrating how to construct some basic service methods to act as the core of a MetaWeblog blog publishing service. A brief introduction to XML-RPC ------------------------------- XML-RPC is a specification that describes a Remote Procedure Call (RPC) interface by which an application can use the Internet to execute a specified procedure call on a remote XML-RPC server. The name of the procedure to be called and any required parameter values are "marshalled" into XML. The XML forms the body of a POST request which is despatched via HTTP to the XML-RPC server. At the server, the procedure is executed, the returned value(s) is/are marshalled into XML and despatched back to the application. XML-RPC is designed to be as simple as possible, while allowing complex data structures to be transmitted, processed and returned. XML-RPC Controller that speaks WSGI ----------------------------------- Pylons uses Python's xmlrpclib library to provide a specialised :class:`XMLRPCController` class that gives you the full range of these XML-RPC Introspection facilities for use in your service methods and provides the foundation for constructing a set of specialised service methods that provide a useful web service --- such as a blog publishing interface. This controller handles XML-RPC responses and complies with the `XML-RPC Specification `_ as well as the `XML-RPC Introspection `_ specification. As part of its basic functionality an XML-RPC server provides three standard introspection procedures or "service methods" as they are called. The Pylons :class:`XMLRPCController` class provides these standard service methods ready-made for you: * :meth:`system.listMethods` Returns a list of XML-RPC methods for this XML-RPC resource * :meth:`system.methodSignature` Returns an array of arrays for the valid signatures for a method. The first value of each array is the return value of the method. The result is an array to indicate multiple signatures a method may be capable of. * :meth:`system.methodHelp` Returns the documentation for a method By default, methods with names containing a dot are translated to use an underscore. For example, the ``system.methodHelp`` is handled by the method :meth:`system_methodHelp`. Methods in the XML-RPC controller will be called with the method given in the XML-RPC body. Methods may be annotated with a signature attribute to declare the valid arguments and return types. For example: .. code-block:: python class MyXML(XMLRPCController): def userstatus(self): return 'basic string' userstatus.signature = [['string']] def userinfo(self, username, age=None): user = LookUpUser(username) result = {'username': user.name} if age and age > 10: result['age'] = age return result userinfo.signature = [['struct', 'string'], ['struct', 'string', 'int']] Since XML-RPC methods can take different sets of data, each set of valid arguments is its own list. The first value in the list is the type of the return argument. The rest of the arguments are the types of the data that must be passed in. In the last method in the example above, since the method can optionally take an integer value, both sets of valid parameter lists should be provided. Valid types that can be checked in the signature and their corresponding Python types: +--------------------+--------------------+ | XMLRPC | Python | +====================+====================+ | string | str | +--------------------+--------------------+ | array | list | +--------------------+--------------------+ | boolean | bool | +--------------------+--------------------+ | int | int | +--------------------+--------------------+ | double | float | +--------------------+--------------------+ | struct | dict | +--------------------+--------------------+ | dateTime.iso8601 | xmlrpclib.DateTime | +--------------------+--------------------+ | base64 | xmlrpclib.Binary | +--------------------+--------------------+ Note, requiring a signature is optional. Also note that a convenient fault handler function is provided. .. code-block:: python def xmlrpc_fault(code, message): """Convenience method to return a Pylons response XMLRPC Fault""" (The `XML-RPC Home page `_ and the `XML-RPC HOW-TO `_ both provide further detail on the XML-RPC specification.) A simple XML-RPC service ------------------------ This simple service ``test.battingOrder`` accepts a positive integer < 51 as the parameter ``posn`` and returns a string containing the name of the US state occupying that ranking in the order of ratifying the constitution / joining the union. .. code-block:: python import xmlrpclib from pylons import request from pylons.controllers import XMLRPCController states = ['Delaware', 'Pennsylvania', 'New Jersey', 'Georgia', 'Connecticut', 'Massachusetts', 'Maryland', 'South Carolina', 'New Hampshire', 'Virginia', 'New York', 'North Carolina', 'Rhode Island', 'Vermont', 'Kentucky', 'Tennessee', 'Ohio', 'Louisiana', 'Indiana', 'Mississippi', 'Illinois', 'Alabama', 'Maine', 'Missouri', 'Arkansas', 'Michigan', 'Florida', 'Texas', 'Iowa', 'Wisconsin', 'California', 'Minnesota', 'Oregon', 'Kansas', 'West Virginia', 'Nevada', 'Nebraska', 'Colorado', 'North Dakota', 'South Dakota', 'Montana', 'Washington', 'Idaho', 'Wyoming', 'Utah', 'Oklahoma', 'New Mexico', 'Arizona', 'Alaska', 'Hawaii'] class RpctestController(XMLRPCController): def test_battingOrder(self, posn): """This docstring becomes the content of the returned value for system.methodHelp called with the parameter "test.battingOrder"). The method signature will be appended below ... """ # XML-RPC checks agreement for arity and parameter datatype, so # by the time we get called, we know we have an int. if posn > 0 and posn < 51: return states[posn-1] else: # Technically, the param value is correct: it is an int. # Raising an error is inappropriate, so instead we # return a facetious message as a string. return 'Out of cheese error.' test_battingOrder.signature = [['string', 'int']] Testing the service ------------------- For developers using OS X, there's an `XML/RPC client `_ that is an extremely useful diagnostic tool when developing XML-RPC (it's free ... but not entirely bug-free). Or, you can just use the Python interpreter: .. code-block:: pycon >>> from pprint import pprint >>> import xmlrpclib >>> srvr = xmlrpclib.Server("http://example.com/rpctest/") >>> pprint(srvr.system.listMethods()) ['system.listMethods', 'system.methodHelp', 'system.methodSignature', 'test.battingOrder'] >>> print srvr.system.methodHelp('test.battingOrder') This docstring becomes the content of the returned value for system.methodHelp called with the parameter "test.battingOrder"). The method signature will be appended below ... Method signature: [['string', 'int']] >>> pprint(srvr.system.methodSignature('test.battingOrder')) [['string', 'int']] >>> pprint(srvr.test.battingOrder(12)) 'North Carolina' To debug XML-RPC servers from Python, create the client object using the optional verbose=1 parameter. You can then use the client as normal and watch as the XML-RPC request and response is displayed in the console. Pylons-1.0.1/pylons/docs/en/debugging.rst0000664000076500000240000002061311645401275020240 0ustar benstaff00000000000000.. _debugging: ====================================== Errors, Troubleshooting, and Debugging ====================================== When a web application has an error in production, a few different options for handling it are available. Pylons comes with error handlers to allow the following options: * E-mail the traceback as HTML to the administrators * Show the :ref:`interactive_debugging` interface to the developer * Programmatically handle the error in another controller * Display a plain error on the web page Some of these options can be combined by enabling or disabling the appropriate middleware. Error Middleware ================ In a new Pylons project, the error handling middleware is configured in the projects :file:`config/middleware.py`:: # Excerpt of applicable section if asbool(full_stack): # Handle Python exceptions app = ErrorHandler(app, global_conf, **config['pylons.errorware']) # Display error documents for 401, 403, 404 status codes (and # 500 when debug is disabled) if asbool(config['debug']): app = StatusCodeRedirect(app) else: app = StatusCodeRedirect(app, [400, 401, 403, 404, 500]) The first middleware configured, :func:`~pylons.middleware.ErrorHandler`, actually configures one of two :mod:`WebError ` middlewares depending on whether the project is in ``debug`` mode or not. If it is in ``debug`` mode, then the :ref:`interactive_debugging` is enabled, otherwise, the :ref:`e-mail error handling ` will be used. The second middleware configured is the :class:`~pylons.middleware.StatusCodeRedirect` middleware. This middleware watches the request, and if the application returns a response containing one of the status code's listed, it will call back into the application to the error controller, and use that output instead. None of these are required for a Pylons project to run, and commenting them all out results in the plain text of the error to display on the web page. .. warning:: If no middleware at all is used, the error will appear on the screen in its entirety, *including full traceback output*. Recommended Configurations -------------------------- * For plain-text output or errors and non-200 status codes, comment out the :class:`~pylons.middleware.StatusCodeRedirect`. Tracebacks will be e-mailed to you in production, and the :ref:`interactive_debugging` will be used during development. * For programmatic error and non-200 status code handling, keep the stack as-is. * To *not* have tracebacks e-mailed, remove only the :func:`~pylons.middleware.ErrorHandler` middleware. This will also disable :ref:`interactive_debugging` however. To retain :ref:`interactive_debugging` but disable traceback e-mails:: if asbool(config['debug']): app = ErrorHandler(app, global_conf, **config['pylons.errorware']) .. note:: To only capture specific non-200 status codes, the :class:`~pylons.middleware.StatusCodeRedirect` middleware can be passed a list of the codes that it should intercept and redirect to the error controller. When in non-debug mode, it captures the 400-404, and 500 status codes. Altering the list will capture more or less types of requests as desired. Avoiding Displaying Tracebacks ------------------------------ When disabling the :func:`~pylons.middleware.ErrorHandler` middleware, a replacement middleware should be created and used that captures exceptions and changes them into a normal WSGI response, otherwise the raw traceback error will be displayed on the browser. An example middleware that just captures exceptions and changes them to a 500 error:: from webob import Request, Response class EatExceptions(object): def __init__(self, app): self.app = app def __call__(self, environ, start_response): req = Request(environ) try: response = req.get_response(self.app) except: response = Response() response.status_int = 500 response.body = 'An error has occured' return response(environ, start_response) Replacing the ``ErrorHandler`` with this middleware will cause tracebacks to not be displayed to the user. .. _interactive_debugging: Interactive Debugging ===================== Things break, and when they do, quickly pinpointing what went wrong and why makes a huge difference. By default, Pylons uses a customized version of `Ian Bicking's `_ EvalException middleware that also includes full Mako/Myghty Traceback information. The Debugging Screen -------------------- The debugging screen has three tabs at the top: ``Traceback`` Provides the raw exception trace with the interactive debugger ``Extra Data`` Displays CGI, WSGI variables at the time of the exception, in addition to configuration information ``Template`` Human friendly traceback for Mako or Myghty templates Since Mako and Myghty compile their templates to Python modules, it can be difficult to accurately figure out what line of the template resulted in the error. The `Template` tab provides the full Mako or Myghty traceback which contains accurate line numbers for your templates, and where the error originated from. If your exception was triggered before a template was rendered, no Template information will be available in this section. Example: Exploring the Traceback -------------------------------- Using the interactive debugger can also be useful to gain a deeper insight into objects present only during the web request like the ``session`` and ``request`` objects. To trigger an error so that we can explore what's happening just raise an exception inside an action you're curious about. In this example, we'll raise an error in the action that's used to display the page you're reading this on. Here's what the docs controller looks like: .. code-block:: python class DocsController(BaseController): def view(self, url): if request.path_info.endswith('docs'): redirect(url('/docs/')) return render('/docs/' + url) Since we want to explore the ``session`` and ``request``, we'll need to bind them first. Here's what our action now looks like with the binding and raising an exception: .. code-block:: python def view(self, url): raise "hi" if request.path_info.endswith('docs'): redirect(url('/docs/')) return render('/docs/' + url) Here's what exploring the Traceback from the above example looks like (Excerpt of the relevant portion): .. image:: _static/doctraceback.png :width: 750px :height: 260px .. _error_emails: E-mailing Errors ================ You can make various of changes to how the debugging works. For example if you disable the ``debug`` variable in the config file Pylons will email you an error report instead of displaying it as long as you provide your email address at the top of the config file: .. code-block:: ini error_email_from = you@example.com This is very useful for a production site. Emails are sent via SMTP so you need to specify a valid SMTP server too. Programmatically Handling Errors ================================ By default, the :class:`~pylons.middleware.StatusCodeRedirect` will redirect any response with the designated status codes back into the application again. This will result in the ``error`` controller in the Pylons project being called. This is why there is a default route in :file:`config/routing.py` of:: map.connect('/error/{action}', controller='error') map.connect('/error/{action}/{id}', controller='error') The error controller allows a project to theme the error message appropriately by changing it to render a template, or redirect as desired. Original Request Information ---------------------------- The original request and response that resulted in the error controller being called is available inside the error controller as:: # Original request request.environ['pylons.original_request'] # Original response request.environ['pylons.original_response'] If an :exc:`~webob.exc.HTTPException` was thrown in the controller (the :func:`~pylons.controllers.util.abort` function throws these), the original object is available as:: request.environ['pylons.controller.exception'] This allows access to the error message on the exception object. Pylons-1.0.1/pylons/docs/en/deployment.rst0000664000076500000240000005564611645401275020503 0ustar benstaff00000000000000.. _deployment: Packaging and Deployment Overview ================================= TODO: some of this is redundant to the (more current) :ref:`configuration` doc -- should be consolidated and cross-referenced This document describes how a developer can take advantage of Pylons' application setup functionality to allow webmasters to easily set up their application. Installation refers to the process of downloading and installing the application with :term:`easy_install` whereas setup refers to the process of setting up an instance of an installed application so it is ready to be deployed. For example, a wiki application might need to create database tables to use. The webmaster would only install the wiki ``.egg`` file once using :term:`easy_install` but might want to run 5 wikis on the site so would setup the wiki 5 times, each time specifying a different database to use so that 5 wikis can run from the same code, but store their data in different databases. Egg Files ********* Before you can understand how a user configures an application you have to understand how Pylons applications are distributed. All Pylons applications are distributed in ``.egg`` format. An egg is simply a Python executable package that has been put together into a single file. You create an egg from your project by going into the project root directory and running the command: .. code-block:: bash $ python setup.py bdist_egg If everything goes smoothly a ``.egg`` file with the correct name and version number appears in a newly created ``dist`` directory. When a webmaster wants to install a Pylons application he will do so by downloading the egg and then installing it. Installing as a Non-root User ***************************** It's quite possible when using shared hosting accounts that you do not have root access to install packages. In this case you can install :term:`setuptools` based packages like Pylons and Pylons web applications in your home directory using a :term:`virtualenv` setup. This way you can install all the packages you want to use without super-user access. Understanding the Setup Process ******************************* Say you have written a Pylons wiki application called ``wiki``. When a webmaster wants to install your wiki application he will run the following command to generate a config file: .. code-block:: bash $ paster make-config wiki wiki_production.ini He will then edit the config file for his production environment with the settings he wants and then run this command to setup the application: .. code-block:: bash $ paster setup-app wiki_production.ini Finally he might choose to deploy the wiki application through the paste server like this (although he could have chosen CGI/FastCGI/SCGI etc): .. code-block:: bash $ paster serve wiki_production.ini The idea is that an application only needs to be installed once but if necessary can be set up multiple times, each with a different configuration. All Pylons applications are installed in the same way, so you as the developer need to know how the above commands work. Make Config ----------- The ``paster make-config`` command looks for the file ``deployment.ini_tmpl`` and uses it as a basis for generating a new ``.ini`` file. Using our new wiki example again, the ``wiki/config/deployment.ini_tmpl`` file contains the text: .. code-block:: ini [DEFAULT] debug = true email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [server:main] use = egg:Paste#http host = 0.0.0.0 port = 5000 [app:main] use = egg:wiki full_stack = true static_files = true cache_dir = %(here)s/data beaker.session.key = wiki beaker.session.secret = ${app_instance_secret} app_instance_uuid = ${app_instance_uuid} # If you'd like to fine-tune the individual locations of the cache data dirs # for the Cache data, or the Session saves, un-comment the desired settings # here: #beaker.cache.data_dir = %(here)s/data/cache #beaker.session.data_dir = %(here)s/data/sessions # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* # Debug mode will enable the interactive debugging tool, allowing ANYONE to # execute malicious code after an exception is raised. set debug = false # Logging configuration [loggers] keys = root [handlers] keys = console [formatters] keys = generic [logger_root] level = INFO handlers = console [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s] [%(threadName)s] %(message)s When the command ``paster make-config wiki wiki_production.ini`` is run, the contents of this file are produced so you should tweak this file to provide sensible default configuration for production deployment of your app. Setup App --------- The ``paster setup-app`` command references the newly created ``.ini`` file and calls the function ``wiki.websetup.setup_app()`` to set up the application. If your application needs to be set up before it can be used, you should edit the ``websetup.py`` file. Here's an example which just prints the location of the cache directory via Python's logging facilities: .. code-block:: python """Setup the helloworld application""" import logging from pylons import config from helloworld.config.environment import load_environment log = logging.getLogger(__name__) def setup_app(command, conf, vars): """Place any commands to setup helloworld here""" load_environment(conf.global_conf, conf.local_conf) log.info("Using cache dirctory %s" % config['cache.dir']) For a more useful example, say your application needs a database set up and loaded with initial data. The user will specify the location of the database to use by editing the config file before running the ``paster setup-app`` command. The ``setup_app()`` function will then be able to load the configuration and act on it in the function body. This way, the ``setup_app()`` function can be used to initialize the database when ``paster setup-app`` is run. Using the optional :term:`SQLAlchemy` project template support when creating a Pylons project will set all of this up for you in a basic way. The :ref:`quickwiki_tutorial` illustrates an example of this configuration. Deploying the Application ************************* Once the application is setup it is ready to be deployed. There are lots of ways of deploying an application, one of which is to use the ``paster serve`` command which takes the configuration file that has already been used to setup the application and serves it on a local HTTP server for production use: .. code-block:: bash $ paster serve wiki_production.ini More information on Paste deployment options is available on the Paste website at http://pythonpaste.org. See :ref:`deployment_webservers` for alternative Pylons deployment scenarios. Advanced Usage ************** So far everything we have done has happened through the ``paste.script.appinstall.Installer`` class which looks for the ``deployment.ini_tmpl`` and ``websetup.py`` file and behaves accordingly. If you need more control over how your application is installed you can use your own installer class. Create a file, for example ``wiki/installer.py`` and code your new installer class in the file by deriving it from the existing one: .. code-block:: python from paste.script.appinstall import Installer class MyInstaller(Installer): pass You then override the functionality as necessary (have a look at the source code for ``Installer`` as a basis. You then change your application's ``setup.py`` file so that the ``paste.app_install`` entry point ``main`` points to your new installer: .. code-block:: python entry_points=""" ... [paste.app_install] main=wiki.installer:MyInstaller ... """, Depending on how you code your ``MyInstaller`` class you may not even need your ``websetup.py`` or ``deployment.ini_tmpl`` as you might have decided to create the ``.ini`` file and setup the application in an entirely different way. .. _deployment_webservers: Running Pylons Apps with Other Web Servers ========================================== This document assumes that you have already installed a Pylons web application, and :ref:`run-config` for it. Pylons applications use `PasteDeploy `_ to start up your Pylons WSGI application, and can use the flup package to provide a Fast-CGI, SCGI, or AJP connection to it. Using Fast-CGI ************** `Fast-CGI `_ is a gateway to connect web severs like `Apache `_ and `lighttpd `_ to a CGI-style application. Out of the box, Pylons applications can run with Fast-CGI in either a threaded or forking mode. (Threaded is the recommended choice) Setting a Pylons application to use Fast-CGI is very easy, and merely requires you to change the config line like so: .. code-block:: ini # default [server:main] use = egg:Paste#http # Use Fastcgi threaded [server:main] use = egg:PasteScript#flup_fcgi_thread host = 0.0.0.0 port = 6500 Note that you will need to install the `flup `_ package, which can be installed via easy_install: .. code-block:: bash $ easy_install -U flup The options in the config file are passed onto flup. The two common ways to run Fast CGI is either using a socket to listen for requests, or listening on a port/host which allows a webserver to send your requests to web applications on a different machine. To configure for a socket, your ``server:main`` section should look like this: .. code-block:: ini [server:main] use = egg:PasteScript#flup_fcgi_thread socket = /location/to/app.socket If you want to listen on a host/port, the configuration cited in the first example will do the trick. Apache Configuration ******************** For this example, we will assume you're using Apache 2, though Apache 1 configuration will be very similar. First, make sure that you have the Apache `mod_fastcgi `_ module installed in your Apache. There will most likely be a section where you declare your FastCGI servers, and whether they're external: .. code-block:: apacheconf FastCgiIpcDir /tmp FastCgiExternalServer /some/path/to/app/myapp.fcgi -host some.host.com:6200 In our example we'll assume you're going to run a Pylons web application listening on a host/port. Changing ``-host`` to ``-socket`` will let you use a Pylons web application listening on a socket. The filename you give in the second option does not need to physically exist on the webserver, URIs that Apache resolve to this filename will be handled by the FastCGI application. The other important line to ensure that your Apache webserver has is to indicate that fcgi scripts should be handled with Fast-CGI: .. code-block:: apacheconf AddHandler fastcgi-script .fcgi Finally, to configure your website to use the Fast CGI application you will need to indicate the script to be used: .. code-block:: apacheconf ServerAdmin george@monkey.com ServerName monkey.com ServerAlias www.monkey.com DocumentRoot /some/path/to/app ScriptAliasMatch ^(/.*)$ /some/path/to/app/myapp.fcgi$1 Other useful directives should be added as needed, for example, the ErrorLog directive, etc. This configuration will result in all requests being sent to your FastCGI application. PrefixMiddleware **************** ``PrefixMiddleware`` provides a way to manually override the root prefix (``SCRIPT_NAME``) of your application for certain situations. When running an application under a prefix (such as '``/james``') in FastCGI/apache, the ``SCRIPT_NAME`` environment variable is automatically set to to the appropriate value: '``/james``'. Pylons' URL generators such as ``url`` always take the ``SCRIPT_NAME`` value into account. One situation where ``PrefixMiddleware`` is required is when an application is accessed via a reverse proxy with a prefix. The application is accessed through the reverse proxy via the the URL prefix '``/james``', whereas the reverse proxy forwards those requests to the application at the prefix '``/``'. The reverse proxy, being an entirely separate web server, has no way of specifying the ``SCRIPT_NAME`` variable; it must be manually set by a ``PrefixMiddleware`` instance. Without setting ``SCRIPT_NAME``, ``url`` will generate URLs such as: '``/purchase_orders/1``', when it should be generating: '``/james/purchase_orders/1``'. To filter your application through a ``PrefixMiddleware`` instance, add the following to the '``[app:main]``' section of your .ini file: .. code-block :: ini filter-with = proxy-prefix [filter:proxy-prefix] use = egg:PasteDeploy#prefix prefix = /james The name ``proxy-prefix`` simply acts as an identifier of the filter section; feel free to rename it. These .ini settings are equivalent to adding the following to the end of your application's ``config/middleware.py``, right before the ``return app`` line: .. code-block :: python # This app is served behind a proxy via the following prefix (SCRIPT_NAME) app = PrefixMiddleware(app, global_conf, prefix='/james') This requires the additional import line: .. code-block :: python from paste.deploy.config import PrefixMiddleware Whereas the modification to ``config/middleware.py`` will setup an instance of ``PrefixMiddleware`` under every environment (.ini). Using Java Web Servers with Jython ********************************** See :ref:`java_deployment`. .. _adding_documentation: Documenting Your Application ============================ TODO: this needs to be rewritten -- Pudge is effectively dead While the information in this document should be correct, it may not be entirely complete... Pudge is somewhat unruly to work with at this time, and you may need to experiment to find a working combination of package versions. In particular, it has been noted that an older version of Kid, like 0.9.1, may be required. You might also need to install {{RuleDispatch}} if you get errors related to {{FormEncode}} when attempting to build documentation. Apologies for this suboptimal situation. Considerations are being taken to fix Pudge or supplant it for future versions of Pylons. Introduction ************ Pylons comes with support for automatic documentation generation tools like `Pudge `_. Automatic documentation generation allows you to write your main documentation in the docs directory of your project as well as throughout the code itself using docstrings. When you run a simple command all the documentation is built into sophisticated HTML. Tutorial ******** First create a project as described in :ref:`getting_started`. You will notice a docs directory within your main project directory. This is where you should write your main documentation. There is already an ``index.txt`` file in ``docs`` so you can already generate documentation. First we'll install Pudge and buildutils. By default, Pylons sets an option to use `Pygments `_ for syntax-highlighting of code in your documentation, so you'll need to install it too (unless you wish to remove the option from ``setup.cfg``): .. code-block:: bash $ easy_install pudge buildutils $ easy_install Pygments then run the following command from your project's main directory where the ``setup.py`` file is: .. code-block:: bash $ python setup.py pudge .. Note:: The ``pudge`` command is currently disabled by default. Run the following command first to enable it: ..code-block:: bash $ python setup.py addcommand -p buildutils.pudge_command Thanks to Yannick Gingras for the tip. Pudge will produce output similar to the following to tell you what it is doing and show you any problems: .. code-block:: text running pudge generating documentation copying: pudge\template\pythonpaste.org\rst.css -> do/docs/html\rst.css copying: pudge\template\base\pudge.css -> do/docs/html\pudge.css copying: pudge\template\pythonpaste.org\layout.css -> do/docs/html\layout.css rendering: pudge\template\pythonpaste.org\site.css.kid -> site.css colorizing: do/docs/html\do/__init__.py.html colorizing: do/docs/html\do/tests/__init__.py.html colorizing: do/docs/html\do/i18n/__init__.py.html colorizing: do/docs/html\do/lib/__init__.py.html colorizing: do/docs/html\do/controllers/__init__.py.html colorizing: do/docs/html\do/model.py.html Once finished you will notice a ``docs/html`` directory. The ``index.html`` is the main file which was generated from ``docs/index.txt``. Learning ReStructuredText ************************* Python programs typically use a rather odd format for documentation called `reStructuredText`_. It is designed so that the text file used to generate the HTML is as readable as possible but as a result can be a bit confusing for beginners. Read the reStructuredText tutorial which is part of the `docutils `_ project. Once you have mastered reStructuredText you can write documentation until your heart's content. .. _reStructuredText: http://docutils.sourceforge.net/rst.html Using Docstrings **************** Docstrings are one of Python's most useful features if used properly. They are described in detail in the Python documentation but basically allow you to document any module, class, method or function, in fact just about anything. Users can then access this documentation interactively. Try this: .. code-block:: pycon >>> import pylons >>> help(pylons) ... As you can see if you tried it you get detailed information about the pylons module including the information in the docstring. Docstrings are also extracted by Pudge so you can describe how to use all the controllers, actions and modules that make up your application. Pudge will extract that information and turn it into useful API documentation automatically. Try clicking the ``Modules`` link in the HTML documentation you generated earlier or look at the Pylons source code for some examples of how to use docstrings. Using doctest ************* The final useful thing about docstrings is that you can use the ``doctest`` module with them. ``doctest`` again is described in the Python documentation but it looks through your docstrings for things that look like Python code written at a Python prompt. Consider this example: .. code-block:: pycon >>> a = 2 >>> b = 3 >>> a + b 5 If ``doctest`` was run on this file it would have found the example above and executed it. If when the expression ``a + b`` is executed the result was not ``5``, ``doctest`` would raise an Exception. This is a very handy way of checking that the examples in your documentation are actually correct. To run ``doctest`` on a module use: .. code-block:: python if __name__ == "__main__": import doctest doctest.testmod() The ``if __name__ == "__main__":`` part ensures that your module won't be tested if it is just imported, only if it is run from the command line To run ``doctest`` on a file use: .. code-block:: python import doctest doctest.testfile("docs/index.txt") You might consider incorporating this functionality in your ``tests/test.py`` file to improve the testing of your application. Summary ******* So if you write your documentation in reStructuredText, in the ``docs`` directory and in your code's docstrings, liberally scattered with example code, Pylons provides a very useful and powerful system for you. If you want to find out more information have a look at the Pudge documentation or try tinkering with your project's ``setup.cfg`` file which contains the Pudge settings. .. _app_distribution: Distributing Your Application ============================= TODO: this assumes helloworld tutorial context that is no longer present, and could be consolidated with packaging info in :ref:`deployment` As mentioned earlier eggs are a convenient format for packaging applications. You can create an egg for your project like this: .. code-block:: bash $ cd helloworld $ python setup.py bdist_egg Your egg will be in the ``dist`` directory and will be called ``helloworld-0.0.0dev-py2.4.egg``. You can change options in ``setup.py`` to change information about your project. For example change version to ``version="0.1.0",`` and run ``python setup.py bdist_egg`` again to produce a new egg with an updated version number. You can then register your application with the `Python Package Index`_ (PyPI) with the following command: .. code-block:: bash $ python setup.py register .. note:: You should not do this unless you actually want to register a package! If users want to install your software and have installed :term:`easy_install` they can install your new egg as follows: .. code-block:: bash $ easy_install helloworld==0.1.0 This will retrieve the package from PyPI and install it. Alternatively you can install the egg locally: .. code-block:: bash $ easy_install -f C:\path\with\the\egg\files\in helloworld==0.1.0 In order to use the egg in a website you need to use Paste. You have already used Paste to create your Pylons template and to run a test server to test the tutorial application. Paste is a set of tools available at http://pythonpaste.org for providing a uniform way in which all compatible Python web frameworks can work together. To run a paste application such as any Pylons application you need to create a Paste configuration file. The idea is that the your paste configuration file will contain all the configuration for all the different Paste applications you run. A configuration file suitable for development is in the ``helloworld/development.ini`` file of the tutorial but the idea is that the person using your egg will add relevant configuration options to their own Paste configuration file so that your egg behaves they way they want. See the section below for more on this configuration. Paste configuration files can be run in many different ways, from CGI scripts, as standalone servers, with FastCGI, SCGI, mod_python and more. This flexibility means that your Pylons application can be run in virtually any environment and also take advantage of the speed benefits that the deployment option offers. .. seealso:: :ref:`deployment_webservers` .. _Python Package Index: http://pypi.python.org/pypi Running Your Application ************************ In order to run your application your users will need to install it as described above but then generate a config file and setup your application before deploying it. This is described in :ref:`run-config` and :ref:`deployment`. Pylons-1.0.1/pylons/docs/en/events.rst0000664000076500000240000000004311645401275017604 0ustar benstaff00000000000000.. _events: ====== Events ====== Pylons-1.0.1/pylons/docs/en/execution.rst0000664000076500000240000007467411645401275020330 0ustar benstaff00000000000000Pylons Execution Analysis %%%%%%%%%%%%%%%%%%%%%%%%% *By Mike Orr and Alfredo Deza* This chapter shows how Pylons calls your application, and how Pylons interacts with Paste, Routes, Mako, and its other dependencies. We'll create a simple application and then analyze the Python code executed starting from the moment we run the "paster serve" command. **Abbreviations:** **$APP** is your top-level application directory. **$SP** is the site-packages directory where Pylons is installed. **$BIN** is the location of ``paster`` and other executables. $SP paths are shown in pip style ($SP/pylons) rather than easy_install style ($SP/Pylons-VERSION.egg/pylons). The sample application ======================== 1. Create an application called "Analysis" with a controller called "main":: $ paster create -t pylons Analysis $ cd Analysis $ paster controller main Press Enter at all question prompts. 2. Edit **analysis/controllers/main.py** to look like this:: from analysis.lib.base import BaseController class MainController(BaseController): def index(self): return '

Welcome to the Analysis Demo

Here is a
link.' def page2(self): return 'Thank you for using the Analysis Demo. Home' There are two shortcuts here which you would not use in a normal application. One, we're returning incomplete HTML documents. Two, we've hardcoded the URLs to make the analysis easier to follow, rather than using the ``url`` object. 3. Now edit **analysis/config/routing.py**. Add these lines after "CUSTOM ROUTES HERE" (line 21):: map.connect("home", "/", controller="main", action="index") map.connect("page2", "/page2", controller="main", action="page2") 4. Delete the file **analysis/public/index.html**. 5. Now run the server. (Press ctrl-C to quit it.) :: $ paster serve development.ini Starting server in PID 7341. serving on http://127.0.0.1:5000 Pylons' dependencies ==================== Pylons 1.0 has the following direct and indirect dependencies, which will be found in your site-packages directory ($SP): * Beaker 1.5.4 * decorator 3.2.0 * FormEncode 1.2.2 * Mako 0.3.4 * MarkupSafe 0.9.3 * Nose 0.11.4 * Paste 1.7.3.1 * PasteDeploy 1.3.3 * PasteScript 1.7.3 * Routes 1.12.3 * simplejson 2.0.9 (if Python < 2.6) * Tempita 0.4 * WebError 0.10.2 * WebHelpers 1.2 * WebOb 0.9.8 * Webtest 1.2.1 These are the current versions as of August 29, 2010. Your installation may have slightly newer or older versions. The analysis ============ Startup (PasteScript) --------------------- When you run ``paster serve development.ini``, it runs the "$BIN/paster" program. This is a platform-specific stub created by ``pip`` or ``easy_install``. It does this:: __requires__ = 'PasteScript==1.7.3' import sys from pkg_resources import load_entry_point sys.exit( load_entry_point('PasteScript==1.7.3', 'console_scripts', 'paster')() ) This says to load a Python object "paster" located in an egg "PasteScript", version 1.7.3, under the entry point group ``[console_scripts]``. To explain what this means we have to get into Setuptools. Setuptools is Python's de facto package manager, and was installed as part of your virtualenv or Pylons installation. (If you're using Distribute 0.6, an alternative package manager, it works the same way.) ``load_entry_point`` is a function that looks up a Python object via entry point and returns it. So what's an entry point? It's an alias for a Python object. Here's the entry point itself:: [console_scripts] paster=paste.script.command:run This is from $SP/PasteScript-VERSION.egg-info/entry_points.txt. (If you used easy_install rather than pip, the path would be slightly different: $APP/PasteScript-VERSION.egg/EGG-INFO/entry_points.txt.) "console_scripts" is the entry point group. "paster" is the entry point. The right side of the value tells which module to import (``paste.script.command``) and which object in it to return (the ``run`` function). (To create an entry point, define it in your package's setup.py. Pip or easy_install will create the egg_info metadata from that. If you modify a package's entry points, you must reinstall the package to update the egg_info.) The most common use case for entry points is for plugins. So Nose for instance defines an entry point group by which it will look for plugins. Any other package can provide plugins for Nose by defining entry points in that group. Paster uses plugins extensively, as we'll soon see. So to make a long story short, "paster serve" calls this ``run`` function. I inserted print statements into ``paste.script.command`` to figure out what it does. Here's a simplified description: 1. The ``run()`` function parses the command-line options into a subcommand ``"serve"`` with arguments ``["development.ini"]``. 2. It calls ``get_commands()``, which loads Paster commands from plugins located at various entry points. (You can add custom commands with the "--plugin" command-line argument.) Paste's standard commands are listed in the same entry_points.txt file we saw above:: [paste.global_paster_command] serve=paste.script.serve:ServeCommand [Config] #... other commands like "make-config", "setup-app", etc ... 3. It calls ``invoke()``, which essentially does ``paste.script.serve.ServeCommand(["development.ini"]).run()``. This in turn calls ``ServeCommand.command()``, which handles daemonizing and other top-level stuff. Since our command line is short, there's no top-level stuff to do. It creates 'server' and 'app' objects based on the configuration file, and calls ``server(app)``. Loading the server and the application (PasteDeploy) ---------------------------------------------------- This all happens during step 3 of the application startup. We need to find and instantiate the WSGI application and server based on the configuration file. The application is our Analysis application. The server is Paste's built-in multithreaded HTTP server. A simplified version of the code is:: # Inside paste.script.serve module, ServeCommand.command() method. from paste.deploy.loadwsgi import loadapp, loadserver server = self.loadserver(server_spec, name=server_name, relative_to=base, global_conf=vars) app = self.loadapp(app_spec, name=app_name, relative_to=base, global_conf=vars) ``loadserver()`` and ``loadapp()`` are defined in module ``paste.deploy.loadwsgi``. The code here is complex, so we'll just look at its general behavior. Both functions see the "config:" URI and read our config file. Since there is no server name or app name they both default to "main". Therefore loadserver() looks for a "\[server:main]" section in the config file, and loadapp()` looks for "\[app:main]". Here's what they find in "development.ini":: [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 [app:main] use = egg:Analysis full_stack = true static_files = true ... The "use =" line in each section tells which object to load. The other lines are configuration parameters for that object, or for plugins that object is expected to load. We can also put custom parameters in \[app:main] for our application to read directly. Server loading ++++++++++++++ 1. ``loadserver()``'s args are ``uri="config:development.ini", name=None, relative_to="$APP"``. 2. A "config:" URI means to read a config file. 3. A server name was not specified so it defaults to "main". So loadserver() looks for a section "\[server:main]". The "server" part comes from the loadwsgi._Server.config_prefixes class attribute in $SP/paste/deploy/loadwsgi.py). 4. "use = egg:Paste#http" says to load an egg called "Paste". 5. loadwsgi._Server.egg_protocols lists two protocols it supports: "server_factory" and "server_runner". 6. "paste.server_runner" is an entry point group in the "Paste" egg, and it has an entry point "http". The relevant lines in $SP/Paste\*.egg_info/entry_points.txt are:: [paste.server_runner] http = paste.httpserver:server_runner 7. There's a server_runner() function in the paste.httpserver module ($SP/paste/httpserver.py). We'll stop here for a moment and look at how the application is loaded. Application loading +++++++++++++++++++ 1. loadapp() looks for a section "\[app:main]" in the config file. The "app" part comes from the loadwsgi._App.config_prefixes class attribute (in $SP/paste/deploy/loadwsgi.py). 2. "use = egg:Analysis" says to find an egg called "Analysis". 3. loadwsgi._App.egg_protocols lists "paste.app_factory" as one of the protocols it supports. 4. "paste.app_factory" is also an entry point group in the egg, as seen in $APP/Analysis.egg-info/entry_points.txt:: [paste.app_factory] main = analysis.config.middleware:make_app 5. The line "main = analysis.config.middleware:make_app" means to look for a ``make_app()`` object in the ``analysis`` package. This is a function imported from ``analysis.config.middleware`` ($APP/analysis/config/middleware.py). Instantiating the application (Analysis) ---------------------------------------- Here's a closer look at our application's ``make_app`` function:: # In $APP/analysis/config/middleware.py def make_app(global_conf, full_stack=True, static_files=True, **app_conf): config = load_environment(global_conf, app_conf) app = PylonsApp(config=config) app = SomeMiddleware(app, ...) # Repeated for several middlewares. app.config = config return app This sets up the Pylons environment (next subsection), creates the application object (following subsection), wraps it in several layers of middleware (listed in "Anatomy of a Request" below), and returns the complete application object. The \[DEFAULT] section of the config file is passed as dict ``global_conf``. The \[app:main] section is passed as keyword arguments into dict ``app_conf``. ``full_stack`` defaults to True because we're running the application standalone. If we were embedding this application as a WSGI component of some larger application, we'd set ``full_stack`` to False to disable some of the middleware. ``static_files=True`` means to serve static files from our public directory ($APP/analysis/public). Advanced users can arrange for Apache to serve the static files itself, and put "static_files = false" in their configuration file to gain a bit of efficiency. load_environment & pylons.config ++++++++++++++++++++++++++++++++ Before we begin, remember that ``pylons.config``, ``pylons.app_globals``, ``pylons.request``, ``pylons.response``, ``pylons.session``, ``pylons.url``, and ``pylons.cache`` are special globals that change value depending on the current request. The objects are proxies which maintain a thread-local stack of real values. Pylons pushes the actual values onto them at the beginning of a request, and pops them off at the end. (Some of them it also pushes at other times so they can be used outside of requests.) The proxies delegate attribute access and key access to the topmost actual object on the stack. (You can also call ``myproxy._current_obj()`` to get the actual object itself.) The proxy code is in ``paste.registry.StackedObjectProxy``, so these are called "StackedObjectProxies", or "SOPs" for short. The first thing ``analysis.config.middleware.make_app()`` does is call ``analysis.config.environment.load_environment()``:: def load_environment(global_conf, app_conf): config = PylonsConfig() root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='analysis', paths=paths) config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) config['pylons.h'] = analysis.lib.helpers # Setup cache object as early as possible import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) # Create the Mako TemplateLookup, with the default auto-escaping config['pylons.app_globals'].mako_lookup = TemplateLookup( directories=paths['templates'], error_handler=handle_mako_error, module_directory=os.path.join(app_conf['cache_dir'], 'templates'), input_encoding='utf-8', default_filters=['escape'], imports=['from webhelpers.html import escape']) # CONFIGURATION OPTIONS HERE (note: all config options will override # any Pylons config options) return config ``config`` is the Pylons configuration object, which will later be pushed onto ``pylons.config``. It's an instance of ``pylons.configuration.PylonsConfig``, a dict subclass. ``config.init_app()`` initializes the dict's keys. It sets the keys to a merger of app_conf and global_conf (with app_conf overriding). It also adds "app_conf" and "global_conf" keys so you can access the original app_conf and global_conf if desired. It also adds several Pylons-specific keys. ``config["routes.map"]`` is the Routes map defined in ``analysis.config.routing.make_map()``. ``config["pylons.app_globals"]`` is the application's globals object, which will later be pushed onto ``pylons.app_globals``. It's an instance of ``analysis.lib.app_globals.Globals``. ``config["pylons.h"]`` is the helpers module, ``analysis.lib.helpers``. Pylons will assign it to ``h`` in the templates' namespace. The "cache" lines push ``pylons.app_globals.cache`` onto ``pylons.cache`` for backward compatibility. This gives a preview of how StackedObjectProxies work. The Mako stanza creates a TemplateLookup, which ``render()`` will use to find templates. The object is put on ``app_globals``. If you've used older versions of Pylons, you'll notice a couple differences in 1.0. The ``config`` object is created as a local variable and returned, and it's passed explicitly to the route map factory and globals factory. Previous versions pushed it onto ``pylons.config`` immediately and used it from there. This was changed to make it easier to nest Pylons applications inside other Pylons applications. The other difference is that Buffet is gone, and along with it the ``template_engine`` argument and template config options. Pylons 1.0 gets out of the business of initializing template engines. You use one of the standard render functions such as ``render_mako`` or write your own, and define any attributes in ``app_globals`` that your render function depends on. PylonsApp +++++++++ The second line of ``make_app()`` creates a Pylons application object based on your configuration. Again the ``config`` object is passed around explicitly, unlike older versions of Pylons. A Pylons application is an instance of ``pylons.wsgiapp.PylonsApp`` instance. (Older versions of Pylons had a ``PylonsBaseWSGIApp`` superclass, but that has been merged into ``PylonsApp``.) Middleware ++++++++++ ``make_app()`` then wraps the application (the ``app`` variable) in several layers of middleware. Each middleware provides an optional add-on service. ================== ============================ =============================== Middleware Service Effect if disabled ================== ============================ =============================== RoutesMiddleware Use Routes to manage URLs. Routes and ``pylons.url`` won't work. SessionMiddleware HTTP sessions using Beaker, ``pylons.session`` won't work. with flexible persistence backends (disk, memached, database). ErrorHandler Display interactive Paste will catch exceptions and traceback if an exception convert them to Internal Server occurs. In production mode, Error. email the traceback to the site admin. StatusCodeRedirect If an HTTP error occurs, If an HTTP error occurs, make a subrequest to display display a plain white HTML page a fancy styled HTML error with the error message. page. RegistryManager Handles the special globals The special globals won't work. (``pylons.request``, etc). There are other ways to access the objects without going through the special globals. StaticURLParser Serve the static files The static files won't be in the application's found. Presumably you've public directory. configured Apache to serve them directly. Cascade Call several sub-middlewares No cascading through in order, and use the first alternative apps. one that doesn't return "404 Not Found". Used in conjunction with StaticURLParser. ================== ============================ =============================== At the end of the function, ``app.config`` is set to the ``config`` object, so that any part of the application can access the config without going through the special global. Anatomy of a request -------------------- Let's say you're running the demo and click the "link" link on the home page. The browser sends a request for "http://localhost:5000/page2". In my Firefox the HTTP request headers are:: GET /page2 Host: 127.0.0.1:5000 User-Agent: Mozilla/5.0 ... Accept: text/html,... Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7*;q=0.7 Keep-Alive: 300 Connection: keep-alive Referer: http://127.0.0.1/5000/ Cache-Control max-age=0 The response is:: HTTP/1.x 200 OK Server: PasteWSGIServer/0.5 Python/2.6.4 Date: Sun, 06 Dec 2009 14:06:05 GMT Content-Type: text/html; charset=utf-8 Pragma: no-cache Cache-Control: no-cache Content-Length: 59 Thank you for using the Analysis Demo. Home Here's the processing sequence: 1. ``server(app)`` is still running, called by ``ServeCommand.command()`` in $SP/paste/script/serve.py. 2. ``server`` is actually ``paste.httpserver.server_runner()`` in $SP/paste/httpserver. The only keyword args are 'host' and 'port' extracted from the config file. ``server_runner`` de-stringifies the arguments and calls ``serve(wsgi_app, **kwargs)`` (same module). 3. ``serve()``'s 'use_threadpool' arg defaults to True, so it creates a ``WSGIThreadPoolServer`` instance called (``server``) with the following inheritance:: SocketServer.BaseServer # In SocketServer.py in Python stdlib. BaseHTTPServer.HTTPServer # In BaseHTTPServer.py in Python stdlib. paste.httpserver.SecureHTTPServer # Adds SSL (HTTPS). paste.httpserver.WSGIServerBase # Adds WSGI. paste.httpserver.WSGIThreadPoolServer multiple inheritance: ThreadPoolMixIn <= ThreadPool Note that SecureHTTPServer overrides the implementation of Python's SocketServer.TCPServer 4. It calls ``server.serve_forever()``, implemented by the ``ThreadPoolMixIn`` superclass. This calls ``self.handle_request()`` in a loop until ``self.running`` becomes false. That initiates this call stack:: # In paste.httpserver.serve(), calling 'server.serve_forever()' ThreadPoolMixIn.serve_forever() # Defined in paste.httpserver. -> TCPServer.handle_request() # Called for every request. -> WSGIServerBase.get_request() -> SecureHTTPServer.get_request() -> self.socket.accept() # Defined in stdlib socket module. ``self.socket.accept()`` blocks, waiting for the next request. 5. The request arrives and ``self.socket.accept()`` returns a new socket for the connection. ``TCPServer.handle_request()`` continues. It calls ``ThreadPoolMixIn.process_request()``, which puts the request in a thread queue:: self.thread_pooladd.add_task( lambda: self.process_request_in_thread(request, client_address)) # 'request' is the connection socket. The thread pool is defined in the ``ThreadPool`` class. It spawns a number of threads which each wait on the queue for a callable to run. In this case the callable will be a complete Web transaction including sending the HTML page to the client. Each thread will repeatedly process transactions from the queue until they receive a sentinel value ordering them to die. The main thread goes back to listening for other requests, so we're no longer interested in it. 6. **Thread #2** pulls the lambda out of the queue and calls it:: lambda -> ThreadPoolMixIn.process_request_in_thread() -> BaseServer.finish_request() -> self.RequestHandlerClass(request, client_address, self) # Instantiates this. The class instantiated is paste.httpserver.WSGIHandler; i.e., the 'handler' variable in serve(). 7. The newly-created request handler takes over:: SocketServer.BaseRequestHandler.__init__(request, client_address, server) -> WSGIHandler.handle() -> BaseHTTPRequestHandler.handle() # In stdlib BaseHTTPServer.py Handles requests in a loop until self.close_connection is true. (For HTTP keepalive?) -> WSGIHandler.handle_one_request() Reads the command from the socket. The command is "GET /page2 HTTP/1.1" plus the HTTP headers above. BaseHTTPRequestHandler.parse_request() parses this into attributes .command, .path, .request_version, and .headers. -> WSGIHandlerMixin.wsgi_execute(). -> WSGIHandlerMixin.wsgi_setup() Creates the .wsgi_environ dict. The WSGI environment dict is described in PEP 333, the WSGI specification. It contains various keys specifying the URL to fetch, query parameters, server info, etc. All keys required by the CGI specification are present, as are other keys specific to WSGI or to paricular middleware. The application will calculate a response based on the dict. The application is wrapped in layers of middleware -- nested function calls -- which modify the dict on the way in and modify the response on the way out. 8. The request handler, still in ``WSGIHandlerMixin.wsgi_execute()``, calls the application thus:: result = self.server.wsgi_application(self.wsgi_environ, self.wsgi_start_response) ``wsgi_start_response`` is a callable mandated by the WSGI spec. The application will call it to specify the HTTP headers. The return value is an iteration of strings, which when concatenated form the HTML document to send to the browser. Other MIME types are handled analagously. 9. The application, as we remember, was returned by ``analysis.config.middleware.make_app()``. It's wrapped in several layers of middleware, so calling it will execute the middleware in reverse order of how they're listed in $APP/analysis/config/middleware.py and $SP/pylons/wsgiapp.py: * ``Cascade`` (defined in $SP/paste/cascade.py) lists a series of applications which will be tried in order (Skipped if static_files is set to False): 1. ``StaticURLParser`` (defined in $SP/paste/urlparser) looks for a file URL under $APP/analysis/public that matches the URL. The demo has no static files. 2. If that fails the cascader tries your application. But first there are other middleware to go through... * ``RegistryManager`` (defined in $SP/paste/registry.py) makes Pylons special globals both thread-local and middleware-local. This includes **app_globals**, **cache**, **request**, **response**, **session**, **tmpl_context**, **url**, and any other ``StackedObjectProxy`` listed in $SP/pylons/__init__.py. (**h** is a module so it doesn't need a proxy.) * ``StatusCodeRedirect`` (defined in $SP/pylons/middleware.py) intercepts any HTTP error status returned by the application (e.g., "Page Not Found", "Internal Server Error") and sends another request to the application to get the appropriate error page to display instead. (Skipped if ``full_stack`` argument was false.) * ``ErrorHandler`` (defined in $SP/pylons/middleware.py) sends an interactive traceback to the browser if the app raises an exception, if "debug" is true in the config file. Otherwise it attempts to email the traceback to the site administrator, and substitutes a generic Internal Server Error for the response. (Skipped if ``full_stack`` argument was false. * User-defined middleware goes here. * ``SessionMiddleware`` (wsgiapp.py) adds `Beaker`_ session support (the ``pylons.session`` object). (Skipped if the WSGI environment has a key 'session' -- it doesn't in this demo.) * ``RoutesMiddleware`` (wsgiapp.py) compares the request URI against the routing rules in $APP/analysis/config/routing.py and sets 'wsgi.routing_args' to the routing match dict (useful) and 'routes.route' to the Route (probably not useful). Pylons 1.0 apps have a ``singleton=False`` argument that suppresses initializing the deprecated ``url_for()`` function. Routes now puts a URL generator in the WSGI environment, which Pylons aliases to ``pylons.url``. * The innermost middleware calls the PylonsApp instance it was initialized with. Note: CacheMiddleware is no longer used in Pylons 1.0. Instead, ``app_globals`` creates the cache as an attribute, and a line in environment.py aliases ``pylons.cache`` to it. 10. Surprise! PylonsApp is itself middleware. Its .\_\_call\_\_() method does:: self.setup_app_env(environ, start_response) controller = self.resolve(environ, start_response) response = self.dispatch(controller, environ, start_response) return response ``.setup_app_env()`` registers all those special globals. ``.resolve()`` calculates the controller class based on the route chosen by the RoutesMiddleware, and returns the controller class. ``.dispatch`` instantiates the controller class and calls in the WSGI manner. If the controller does not exist (``.resolve()`` returned None), raise an Exception that tells you what controller did not have any content. This method also handles the special URL "/_test_vars", which is enabled if the application is running under a Nose test. This URL initializes Pylons' special globals, for tests that have to access them before making a regular request. 11. ``analysis.controllers.main.MainController`` does not have a ``.\_\_call\_\_()`` method, so control falls to its parent, ``analysis.lib.base.BaseController``. This trivially calls the grandparent, ``pylons.controllers.WSGIController``. It calls the action method ``MainController.page2()``. The action method may have any number of positional arguments as long as they correspond to variables in the routing match dict. (GET/POST variables are in the **request.params** dict.) If the method has a ``\*\*kwargs`` argument, all other match variables are put there. Any variables passed to the action method are also put on the **tmpl_context** object as attributes. If an action method name starts with "\_", it's private and HTTPNotFound is raised. 12. If the controller has .\_\_before\_\_() and/or .\_\_after\_\_() methods, they are called before and after the action, respectively. These can perform authorization, lock OS resources, etc. These methods can have arguments in the same manner as the action method. However, if the code is used by all controllers, most Pylons programmers prefer to it in the base controller's ``.\_\_call\_\_`` method instead. 13. The action method returns a string, unicode, Response object, or is a generator of strings. In this trivial case it returns a string. A typical Pylons action would set some *tmpl_context* attributes and 'return render('/some/template.html")' . In either case the global *response* object's body would be set to the string. 14. ``WSGIController.\_\_call\_\_()`` continues, converting the Response object to an appropriate WSGI return value. (First it calls the start_response callback to specify the HTTP headers, then it returns an iteration of strings. The Response object converts unicode to utf-8 encoded strings, or whatever encoding you've specified in the config file.) 15. The stack of middleware calls unwinds, each modifying the return value and headers if it desires. 16. The server receives the final return value. (We're way back in ``paste.httpserver.WSGIHandlerMixin.wsgi_execute()`` now.) The outermost middleware has called back to ``server.start_response()``, which has saved the status and HTTP headers in ``.wsgi_curr_headers``. ``.wsgi_execute()`` then iterates the application's return value, calling ``.wsgi_write_chunk(chunk)`` for each encoded string yielded. ``.wsgi_write_chunk('')`` formats the status and HTTP headers and sends them on the socket if they haven't been sent yet, then sends the chunk. The convoluted header behavior here is mandated by the WSGI spec. 17. Control returns to ``BaseHTTPRequestHandler.handle()``. ``.close_connection`` is true so this method returns. The call stack continues unwinding all the way to ``paste.httpserver.ThreadPoolMixIn.process_request_in_thread()``. This tries to finish the request first and then close it unless it finds errors in it to end raising an Exception. 18. The request lambda finishes and control returns to ``ThreadPool.worker_thread_callback()``. It waits for another request in the thread queue. If the next item in the queue is the shutdown sentinel value, thread #2 dies. Thus endeth our request's long journey, and this analysis is finished too. .. _beaker: http://beaker.groovie.org/ Pylons-1.0.1/pylons/docs/en/forms.rst0000664000076500000240000004316311645401275017440 0ustar benstaff00000000000000.. _forms: =========== Forms =========== The basics ========== When a user submits a form on a website the data is submitted to the URL specified in the `action` attribute of the `
` tag. The data can be submitted either via HTTP `GET` or `POST` as specified by the `method` attribute of the `` tag. If your form doesn't specify an `action`, then it's submitted to the current URL, generally you'll want to specify an `action`. When a file upload field such as `` is present, then the HTML `` tag must also specify `enctype="multipart/form-data"` and `method` must be `POST`. Getting Started =============== Add two actions that looks like this: .. code-block:: python # in the controller def form(self): return render('/form.mako') def email(self): return 'Your email is: %s' % request.params['email'] Add a new template called `form.mako` in the `templates` directory that contains the following: .. code-block:: html Email Address:
If the server is still running (see the :ref:`Getting Started Guide `) you can visit http://localhost:5000/hello/form and you will see the form. Try entering the email address `test@example.com` and clicking Submit. The URL should change to ``http://localhost:5000/hello/email?email=test%40example.com`` and you should see the text `Your email is test@example.com`. In Pylons all form variables can be accessed from the :data:`request.params` object which behaves like a dictionary. The keys are the names of the fields in the form and the value is a string with all the characters entity decoded. For example note how the `@` character was converted by the browser to `%40` in the URL and was converted back ready for use in :data:`request.params`. .. Note:: `request` and `response` are objects from the `WebOb` library. Full documentation on their attributes and methods is `here `_. If you have two fields with the same name in the form then using the dictionary interface will return the first string. You can get all the strings returned as a list by using the `.getall()` method. If you only expect one value and want to enforce this you should use `.getone()` which raises an error if more than one value with the same name is submitted. By default if a field is submitted without a value, the dictionary interface returns an empty string. This means that using `.get(key, default)` on `request.params` will only return a default if the value was not present in the form. POST vs GET and the Re-Submitted Data Problem --------------------------------------------- If you change the `form.mako` template so that the method is `POST` and you re-run the example you will see the same message is displayed as before. However, the URL displayed in the browser is simply http://localhost:5000/hello/email without the query string. The data is sent in the body of the request instead of the URL, but Pylons makes it available in the same way as for GET requests through the use of `request.params`. .. note:: If you are writing forms that contain password fields you should usually use POST to prevent the password being visible to anyone who might be looking at the user's screen. When writing form-based applications you will occasionally find users will press refresh immediately after submitting a form. This has the effect of repeating whatever actions were performed the first time the form was submitted but often the user will expect that the current page be shown again. If your form was submitted with a POST, most browsers will display a message to the user asking them if they wish to re-submit the data, this will not happen with a GET so POST is preferable to GET in those circumstances. Of course, the best way to solve this issue is to structure your code differently so: .. code-block:: python # in the controller def form(self): return render('/form.mako') def email(self): # Code to perform some action based on the form data # ... redirect(url(controller='home', action='result')) def result(self): return 'Your data was successfully submitted' In this case once the form is submitted the data is saved and an HTTP redirect occurs so that the browser redirects to http://localhost:5000/hello/result. If the user then refreshes the page, it simply redisplays the message rather than re-performing the action. Using the Helpers ================= Creating forms can also be done using WebHelpers, which comes with Pylons. Here is the same form created in the previous section but this time using the helpers: .. code-block:: html+mako ${h.form(h.url(action='email'), method='get')} Email Address: ${h.text('email')} ${h.submit('Submit')} ${h.end_form()} Before doing this you'll have to import the helpers you want to use into your project's `lib/helpers.py` file; then they'll be available under Pylons' ``h`` global. Most projects will want to import at least these: .. code-block:: python from webhelpers.html import escape, HTML, literal, url_escape from webhelpers.html.tags import * There are many other helpers for text formatting, container objects, statistics, and for dividing large query results into pages. See the :mod:`WebHelpers documentation ` to choose the helpers you'll need. .. _file_uploads: File Uploads ============ File upload fields are created by using the `file` input field type. The `file_field` helper provides a shortcut for creating these form fields: .. code-block:: mako ${h.file_field('myfile')} The HTML form must have its `enctype` attribute set to `multipart/form-data` to enable the browser to upload the file. The `form` helper's `multipart` keyword argument provides a shortcut for setting the appropriate `enctype` value: .. code-block:: html+mako ${h.form(h.url(action='upload'), multipart=True)} Upload file: ${h.file_field('myfile')}
File description: ${h.text_field('description')}
${h.submit('Submit')} ${h.end_form()} When a file upload has succeeded, the `request.POST` (or `request.params`) `MultiDict` will contain a `cgi.FieldStorage` object as the value of the field. `FieldStorage` objects have three important attributes for file uploads: `filename` The name of file uploaded as it appeared on the uploader's filesystem. `file` A file(-like) object from which the file's data can be read: A python `tempfile` or a `StringIO` object. `value` The content of the uploaded file, eagerly read directly from the file object. The easiest way to gain access to the file's data is via the `value` attribute: it returns the entire contents of the file as a string: .. code-block:: python def upload(self): myfile = request.POST['myfile'] return 'Successfully uploaded: %s, size: %i, description: %s' % \ (myfile.filename, len(myfile.value), request.POST['description']) However reading the entire contents of the file into memory is undesirable, especially for large file uploads. A common means of handling file uploads is to store the file somewhere on the filesystem. The `FieldStorage` typically reads the file onto filesystem, however to a non permanent location, via a python `tempfile` object (though for very small uploads it stores the file in a `StringIO` object instead). Python `tempfiles` are secure file objects that are automatically destroyed when they are closed (including an implicit close when the object is garbage collected). One of their security features is that their path cannot be determined: a simple `os.rename` from the `tempfile's` path isn't possible. Alternatively, `shutil.copyfileobj` can perform an efficient copy of the file's data to a permanent location: .. code-block:: python permanent_store = '/uploads/' class Uploader(BaseController): def upload(self): myfile = request.POST['myfile'] permanent_file = open(os.path.join(permanent_store, myfile.filename.lstrip(os.sep)), 'w') shutil.copyfileobj(myfile.file, permanent_file) myfile.file.close() permanent_file.close() return 'Successfully uploaded: %s, description: %s' % \ (myfile.filename, request.POST['description']) .. warning:: The previous basic example allows any file uploader to overwrite any file in the `permanent_store` directory that your web application has permissions to. Also note the use of `myfile.filename.lstrip(os.sep)` here: without it, `os.path.join` is unsafe. `os.path.join` won't join absolute paths (beginning with `os.sep`), i.e. `os.path.join('/uploads/', '/uploaded_file.txt')` == `'/uploaded_file.txt'`. Always check user submitted data to be used with `os.path.join`. Validating user input with FormEncode ===================================== Validation the Quick Way ------------------------ At the moment you could enter any value into the form and it would be displayed in the message, even if it wasn't a valid email address. In most cases this isn't acceptable since the user's input needs validating. The recommended tool for validating forms in Pylons is `FormEncode `_. For each form you create you also create a validation schema. In our case this is fairly easy: .. code-block:: python import formencode class EmailForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True email = formencode.validators.Email(not_empty=True) .. note:: We usually recommend keeping form schemas together so that you have a single place you can go to update them. It's also convenient for inheritance since you can make new form schemas that build on existing ones. If you put your forms in a `models/form.py` file, you can easily use them throughout your controllers as `model.form.EmailForm` in the case shown. Our form actually has two fields, an email text field and a submit button. If extra fields are submitted FormEncode's default behavior is to consider the form invalid so we specify `allow_extra_fields = True`. Since we don't want to use the values of the extra fields we also specify `filter_extra_fields = True`. The final line specifies that the email field should be validated with an `Email()` validator. In creating the validator we also specify `not_empty=True` so that the email field will require input. Pylons comes with an easy to use `validate` decorator, if you wish to use it import it in your `lib/base.py` like this: .. code-block:: python # other imports from pylons.decorators import validate Using it in your controller is pretty straight-forward: .. code-block:: python # in the controller def form(self): return render('/form.mako') @validate(schema=EmailForm(), form='form') def email(self): return 'Your email is: %s' % self.form_result.get('email') Validation only occurs on POST requests so we need to alter our form definition so that the method is a POST: .. code-block:: mako ${h.form(h.url(action='email'), method='post')} If validation is successful, the valid result dict will be saved as `self.form_result` so it can be used in the action. Otherwise, the action will be re-run as if it was a GET request to the controller action specified in `form`, and the output will be filled by FormEncode's htmlfill to fill in the form field errors. For simple cases this is really handy because it also avoids having to write code in your templates to display error messages if they are present. This does exactly the same thing as the example above but works with the original form definition and in fact will work with any HTML form regardless of how it is generated because the validate decorator uses `formencode.htmlfill` to find HTML fields and replace them with the values were originally submitted. .. note:: Python 2.3 doesn't support decorators so rather than using the `@validate()` syntax you need to put `email = validate(schema=EmailForm(), form='form')(email)` after the email function's declaration. Validation the Long Way ----------------------- The `validate` decorator covers up a bit of work, and depending on your needs it's possible you could need direct access to FormEncode abilities it smoothes over. Here's the longer way to use the `EmailForm` schema: .. code-block:: python # in the controller def email(self): schema = EmailForm() try: form_result = schema.to_python(request.params) except formencode.validators.Invalid, error: return 'Invalid: %s' % error else: return 'Your email is: %s' % form_result.get('email') If the values entered are valid, the schema's `to_python()` method returns a dictionary of the validated and coerced `form_result`. This means that you can guarantee that the `form_result` dictionary contains values that are valid and correct Python objects for the data types desired. In this case the email address is a string so `request.params['email']` happens to be the same as `form_result['email']`. If our form contained a field for age in years and we had used a `formencode.validators.Int()` validator, the value in `form_result` for the age would also be the correct type; in this case a Python integer. FormEncode comes with a useful set of validators but you can also easily create your own. If you do create your own validators you will find it very useful that all FormEncode schemas' `.to_python()` methods take a second argument named `state`. This means you can pass the Pylons `c` object into your validators so that you can set any variables that your validators need in order to validate a particular field as an attribute of the `c` object. It can then be passed as the `c` object to the schema as follows: .. code-block:: python c.domain = 'example.com' form_result = schema.to_python(request.params, c) The schema passes `c` to each validator in turn so that you can do things like this: .. code-block:: python class SimpleEmail(formencode.validators.Email): def _to_python(self, value, c): if not value.endswith(c.domain): raise formencode.validators.Invalid( 'Email addresses must end in: %s' % \ c.domain, value, c) return formencode.validators.Email._to_python(self, value, c) For this to work, make sure to change the `EmailForm` schema you've defined to use the new `SimpleEmail` validator. In other words, .. code-block:: python email = formencode.validators.Email(not_empty=True) # becomes: email = SimpleEmail(not_empty=True) In reality the invalid error message we get if we don't enter a valid email address isn't very useful. We really want to be able to redisplay the form with the value entered and the error message produced. Replace the line: .. code-block:: python return 'Invalid: %s' % error with the lines: .. code-block:: python c.form_result = error.value c.form_errors = error.error_dict or {} return render('/form.mako') Now we will need to make some tweaks to `form.mako`. Make it look like this: .. code-block:: html+mako ${h.form(h.url(action='email'), method='get')} % if c.form_errors:

Please correct the errors

% else:

Enter Email Address

% endif % if c.form_errors: Email Address: ${h.text_field('email', value=c.form_result['email'] or '')}

${c.form_errors['email']}

% else: Email Address: ${h.text_field('email')} % endif ${h.submit('Submit')} ${h.end_form()} Now when the form is invalid the `form.mako` template is re-rendered with the error messages. Other Form Tools ================ If you are going to be creating a lot of forms you may wish to consider using `FormBuild `_ to help create your forms. To use it you create a custom Form object and use that object to build all your forms. You can then use the API to modify all aspects of the generation and use of all forms built with your custom Form by modifying its definition without any need to change the form templates. Here is an one example of how you might use it in a controller to handle a form submission: .. code-block:: python # in the controller def form(self): results, errors, response = formbuild.handle( schema=Schema(), # Your FormEncode schema for the form # to be validated template='form.mako', # The template containg the code # that builds your form form=Form # The FormBuild Form definition you wish to use ) if response: # The form validation failed so re-display # the form with the auto-generted response # containing submitted values and errors or # do something with the errors return response else: # The form validated, do something useful with results. ... Full documentation of all features is available in the `FormBuild manual `_ which you should read before looking at `Using FormBuild in Pylons `_ Looking forward it is likely Pylons will soon be able to use the TurboGears widgets system which will probably become the recommended way to build forms in Pylons. Pylons-1.0.1/pylons/docs/en/gettingstarted.rst0000664000076500000240000002050411645401275021334 0ustar benstaff00000000000000.. _getting_started: =============== Getting Started =============== This section is intended to get Pylons up and running as fast as possible and provide a quick overview of the project. Links are provided throughout to encourage exploration of the various aspects of Pylons. ************ Requirements ************ * Python 2 series above and including 2.4 (Python 3 or later not supported at this time) .. _installing_pylons: ********** Installing ********** To avoid conflicts with system-installed Python libraries, Pylons comes with a boot-strap Python script that sets up a "virtual" Python environment. Pylons will then be installed under the virtual environment. .. admonition:: By the Way :term:`virtualenv` is a useful tool to create isolated Python environments. In addition to isolating packages from possible system conflicts, it makes it easy to install Python libraries using :term:`easy_install` without dumping lots of packages into the system-wide Python. The other great benefit is that no root access is required since all modules are kept under the desired directory. This makes it easy to setup a working Pylons install on shared hosting providers and other systems where system-wide access is unavailable. 1. Download the `go-pylons.py `_ script. 2. Run the script and specify a directory for the virtual environment to be created under: .. code-block:: bash $ python go-pylons.py mydevenv .. admonition:: Tip The two steps can be combined on unix systems with curl using the following short-cut: .. code-block:: bash $ curl http://pylonshq.com/download/1.0/go-pylons.py | python - mydevenv To isolate further from additional system-wide Python libraries, run with the --no-site-packages option: .. code-block:: bash $ python go-pylons.py --no-site-packages mydevenv | **How it Works** The ``go-pylons.py`` script is little more than a basic :term:`virtualenv` bootstrap script, that then does ``easy_install Pylons==1.0``. You could do the equivilant steps by manually fetching the ``virtualenv.py`` script and then installing Pylons like so: .. code-block:: bash curl -O http://bitbucket.org/ianb/virtualenv/raw/8dd7663d9811/virtualenv.py python virtualenv.py mydevenv mydevenv/bin/easy_install Pylons==1.0 This will leave a functional virtualenv and Pylons installation. Activate the virtual environment (scripts may also be run by specifying the full path to the mydevenv/bin dir): .. code-block:: bash $ source mydevenv/bin/activate Or on Window to activate: .. code-block:: text > mydevenv\Scripts\activate.bat .. note:: If you get an error such as:: ImportError: No module named _md5 during the install. It is likely that your Python installation is missing standard libraries needed to run Pylons. Debian and other systems using debian packages most frequently encounter this, make sure to install the ``python-dev`` packages and ``python-hashlib`` packages. Working Directly From the Source Code ===================================== `Mercurial `_ must be installed to retrieve the latest development source for Pylons. `Mercurial packages `_ are also available for Windows, MacOSX, and other OS's. Check out the latest code: .. code-block:: bash $ hg clone http://bitbucket.org/bbangert/pylons/ To tell setuptools to use the version in the ``Pylons`` directory: .. code-block:: bash $ cd pylons $ python setup.py develop The active version of Pylons is now the copy in this directory, and changes made there will be reflected for Pylons apps running. ************************* Creating a Pylons Project ************************* Create a new project named ``helloworld`` with the following command: .. code-block:: bash $ paster create -t pylons helloworld .. note:: Windows users must configure their ``PATH`` as described in :ref:`windows_notes`, otherwise they must specify the full path to the ``paster`` command (including the virtual environment bin directory). Running this will prompt for two choices: 1. which templating engine to use 2. whether to include :term:`SQLAlchemy` support Hit enter at each prompt to accept the defaults (Mako templating, no :term:`SQLAlchemy`). Here is the created directory structure with links to more information: - helloworld - MANIFEST.in - README.txt - development.ini - :ref:`run-config` - docs - ez_setup.py - helloworld (See the nested :ref:`helloworld directory `) - helloworld.egg-info - setup.cfg - setup.py - :ref:`setup-config` - test.ini .. _helloworld_dir: The nested ``helloworld directory`` looks like this: - helloworld - __init__.py - config - environment.py - :ref:`environment-config` - middleware.py - :ref:`middleware-config` - routing.py - :ref:`url-config` - controllers - :ref:`controllers` - lib - app_globals.py - :term:`app_globals` - base.py - helpers.py - :ref:`helpers` - model - :ref:`models` - public - templates - :ref:`templates` - tests - :ref:`testing` - websetup.py - :ref:`run-config` *********************** Running the application *********************** Run the web application: .. code-block:: bash $ cd helloworld $ paster serve --reload development.ini The command loads the project's server configuration file in :file:`development.ini` and serves the Pylons application. .. note:: The ``--reload`` option ensures that the server is automatically reloaded if changes are made to Python files or the :file:`development.ini` config file. This is very useful during development. To stop the server press :command:`Ctrl+c` or the platform's equivalent. The paster serve command can be run anywhere, as long as the development.ini path is properly specified. Generally during development it's run in the root directory of the project. Visiting http://127.0.0.1:5000/ when the server is running will show the welcome page. *********** Hello World *********** To create the basic hello world application, first create a :term:`controller` in the project to handle requests: .. code-block:: bash $ paster controller hello Open the :file:`helloworld/controllers/hello.py` module that was created. The default controller will return just the string 'Hello World': .. code-block:: python import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect from helloworld.lib.base import BaseController, render log = logging.getLogger(__name__) class HelloController(BaseController): def index(self): # Return a rendered template #return render('/hello.mako') # or, Return a response return 'Hello World' At the top of the module, some commonly used objects are imported automatically. Navigate to http://127.0.0.1:5000/hello/index where there should be a short text string saying "Hello World" (start up the app if needed): .. image:: _static/helloworld.png .. admonition:: Tip :ref:`url-config` explains how URL's get mapped to controllers and their methods. Add a template to render some of the information that's in the :term:`environ`. First, create a :file:`hello.mako` file in the :file:`templates` directory with the following contents: .. code-block:: mako Hello World, the environ variable looks like:
${request.environ} The :term:`request` variable in templates is used to get information about the current request. :ref:`Template globals ` lists all the variables Pylons makes available for use in templates. Next, update the :file:`controllers/hello.py` module so that the index method is as follows: .. code-block:: python class HelloController(BaseController): def index(self): return render('/hello.mako') Refreshing the page in the browser will now look similar to this: .. image:: _static/hellotemplate.png Pylons-1.0.1/pylons/docs/en/glossary.rst0000664000076500000240000002351711645401275020156 0ustar benstaff00000000000000.. _glossary: Glossary ======== .. glossary:: action The class method in a Pylons applications' controller that handles a request. API Application Programming Interface. The means of communication between a programmer and a software program or operating system. app_globals The ``app_globals`` object is created on application instantiation by the :class:`Globals` class in a projects :file:`lib/app_globals.py` module. This object is created once when the application is loaded by the projects :file:`config/environment.py` module (See :ref:`environment-config`). It remains persistent during the lifecycle of the web application, and is *not* thread-safe which means that it is best used for global options that should be *read-only*, or as an object to attach db connections or other objects which ensure their own access is thread-safe. c Commonly used alias for :term:`tmpl_context` to save on the typing when using lots of controller populated variables in templates. caching The storage of the results of expensive or length computations for later re-use at a point more quickly accessed by the end user. CDN Content Delivery Networks (CDN's) are generally globally distributed content delivery networks optimized for low latency for static file distribution. They can significantly increase page-load times by ensuring that the static resources on a page are delivered by servers geographically close to the client in addition to lightening the load placed on the application server. ColdFusion Components CFCs represent an attempt by Macromedia to bring ColdFusion closer to an Object Oriented Programming (OOP) language. ColdFusion is in no way an OOP language, but thanks in part to CFCs, it does boast some of the attributes that make OOP languages so popular. config The :class:`~pylons.configuration.PylonsConfig` instance for a given application. This can be accessed as ``pylons.config`` after an Pylons application has been loaded. controller The 'C' in MVC. The controller is given a request, does the necessary logic to prepare data for display, then renders a template with the data and returns it to the user. See :ref:`controllers`. easy_install A tool that lets you download, build, install and manage Python packages and their dependencies. `easy_install`_ is the end-user facing component of :term:`setuptools`. Pylons can be installed with ``easy_install``, and applications built with Pylons can easily be deployed this way as well. .. seealso:: Pylons :ref:`deployment` .. _easy_install: http://peak.telecommunity.com/DevCenter/EasyInstall dotted name string A reference to a Python module by name using a string to identify it, e.g. ``pylons.controllers.util``. These strings are evaluated to import the module being referenced without having to import it in the code used. This is generally used to avoid import-time side-effects. egg Python egg's are bundled Python packages, generally installed by a package called :term:`setuptools`. Unlike normal Python package installs, egg's allow a few additional features, such as package dependencies, and dynamic discovery. .. seealso:: `The Quick Guide to Python Eggs `_ EJBs Enterprise JavaBeans (EJB) technology is the server-side component architecture for Java Platform, Enterprise Edition (Java EE). EJB technology enables rapid and simplified development of distributed, transactional, secure and portable applications based on Java technology. environ environ is a dictionary passed into all :term:`WSGI` application. It generally contains unparsed header information, CGI style variables and other objects inserted by :term:`WSGI Middleware`. ETag An ETag (entity tag) is an HTTP response header returned by an HTTP/1.1 compliant web server used to determine change in content at a given URL. See http://wikipedia.org/wiki/HTTP_ETag g Alias used in prior versions of Pylons for :term:`app_globals`. Google App Engine A cloud computing platform for hosting web applications implemented in Python. Building Pylons applications for App Engine is facilitated by Ian Bicking's `appengine-monkey project `_. .. seealso:: `What is Google App Engine? - Official Doc `_ h The helpers reference, ``h``, is made available for use inside templates to assist with common rendering tasks. ``h`` is just a reference to the :file:`lib/helpers.py` module and can be used in the same manner as any other module import. Model-View-Controller An architectural pattern used in software engineering. In Pylons, the MVC paradigm is extended slightly with a pipeline that may transform and extend the data available to a controller, as well as the Pylons :term:`WSGI` app itself that determines the appropriate Controller to call. .. seealso:: `MVC at Wikipedia `_ MVC See :term:`Model-View-Controller` ORM (Object-Relational Mapper) Maps relational databases such as MySQL, Postgres, Oracle to objects providing a cleaner API. Most ORM's also make it easier to prevent SQL Injection attacks by binding variables, and can handle generating sometimes extensive SQL. Pylons A Python-based WSGI oriented web framework. Rails Abbreviated as RoR, Ruby on Rails (also referred to as just Rails) is an open source Web application framework, written in Ruby request Refers to the current request being processed. Available to import from :mod:`pylons` and is available for use in templates by the same name. See :class:`~pylons.controllers.util.Request`. response Refers to the response to the current request. Available to import from :mod:`pylons` and is available for use in template by the same name. See :class:`~pylons.controllers.util.Response`. route Routes determine how the URL's are mapped to the controllers and which URL is generated. See :ref:`url-config` setuptools An extension to the basic distutils, setuptools allows packages to specify package dependencies and have dynamic discovery of other installed Python packages. .. seealso:: `Building and Distributing Packages with setuptools `_ SQLAlchemy One of the most popular Python database object-relational mappers (:term:`ORM`). `SQLAlchemy `_ is the default ORM recommended in Pylons. SQLAlchemy at the ORM level can look similar to Rails ActiveRecord, but uses the `DataMapper `_ pattern for additional flexibility with the ability to map simple to extremely complex databases. tmpl_context The ``tmpl_context`` is available in the :mod:`pylons` module, and refers to the template context. Objects attached to it are available in the template namespace as either ``tmpl_context`` or ``c`` for convenience. UI User interface. The means of communication between a person and a software program or operating system. virtualenv A tool to create isolated Python environments, designed to supersede the ``workingenv`` package and `virtual python`_ configurations. In addition to isolating packages from possible system conflicts, `virtualenv`_ makes it easy to install Python libraries using :term:`easy_install` without dumping lots of packages into the system-wide Python. The other great benefit is that no root access is required since all modules are kept under the desired directory. This makes it easy to setup a working Pylons install on shared hosting providers and other systems where system-wide access is unavailable. ``virtualenv`` is employed automatically by the ``go-pylons.py`` script described in :ref:`getting_started`. The Pylons wiki has more information on `working with virtualenv`_. .. _virtual python: http://peak.telecommunity.com/DevCenter/EasyInstall#creating-a-virtual-python .. _virtualenv: http://pypi.python.org/pypi/virtualenv .. _working with virtualenv: http://wiki.pylonshq.com/display/pylonscookbook/Using+a+Virtualenv+Sandbox web server gateway interface A specification for web servers and application servers to communicate with web applications. Also referred to by its initials, as :term:`WSGI`. WSGI The `WSGI Specification `_, also commonly referred to as PEP 333 and described by :pep:`333`. WSGI Middleware :term:`WSGI` Middleware refers to the ability of WSGI applications to modify the environ, and/or the content of other WSGI applications by being placed in between the request and the other WSGI application. .. seealso:: :ref:`WSGI Middleware in Concepts of Pylons ` :ref:`WSGI Middleware Configuration ` Pylons-1.0.1/pylons/docs/en/helpers.rst0000664000076500000240000003104611645401275017751 0ustar benstaff00000000000000.. _helpers: ======= Helpers ======= Helpers are functions intended for usage in templates, to assist with common HTML and text manipulation, higher level constructs like a HTML tag builder (that safely escapes variables), and advanced functionality like Pagination of data sets. The majority of the helpers available in Pylons are provided by the :mod:`webhelpers` package. Some of these helpers are also used in controllers to prepare data for use in the template by other helpers, such as the :func:`~webhelpers.rails.secure_form_tag` function which has a corresponding :func:`~pylons.decorators.secure.authenticate_form`. To make individual helpers available for use in templates under :term:`h`, the appropriate functions need to be imported in :file:`lib/helpers.py`. All the functions available in this file are then available under :term:`h` just like any other module reference. By customizing the :file:`lib/helpers.py` module you can quickly add custom functions and classes for use in your templates. Helper functions are organized into modules by theme. All HTML generators are under the ``webhelpers_html`` package, except for a few third-party modules which are directly under ``webhelpers``. The webhelpers modules are separately documented, see :mod:`webhelpers`. .. _pagination: Pagination ========== .. note:: The `paginate` module is not compatible to the deprecated `pagination` module that was provided with former versions of the Webhelpers package. Purpose of a paginator ---------------------- When you display large amounts of data like a result from an SQL query then usually you cannot display all the results on a single page. It would simply be too much. So you divide the data into smaller chunks. This is what a paginator does. It shows one page of chunk of data at a time. Imagine you are providing a company phonebook through the web and let the user search the entries. Assume the search result contains 23 entries. You may decide to display no more than 10 entries per page. The first page contains entries 1-10, the second 11-20 and the third 21-23. And you also show a navigational element like ``Page 1 of 3: [1] 2 3`` that allows the user to switch between the available pages. The ``Page`` class ------------------ The :mod:`webhelpers` package provides a *paginate* module that can be used for this purpose. It can create pages from simple Python lists as well as SQLAlchemy queries and SQLAlchemy select objects. The module provides a ``Page`` object that represents a single page of items from a larger result set. Such a ``Page`` mainly behaves like a list of items on that page. Let's take the above example of 23 items spread across 3 pages: .. code-block :: pycon # Create a list of items from 1 to 23 >>> items = range(1,24) # Import the paginate module >>> import webhelpers.paginate # Create a Page object from the 'items' for the second page >>> page2 = webhelpers.paginate.Page(items, page=2, items_per_page=10) # The Page object can be printed (__repr__) to show details on the page >>> page2 Page: Collection type: (Current) page: 2 First item: 11 Last item: 20 First page: 1 Last page: 3 Previous page: 1 Next page: 3 Items per page: 10 Number of items: 23 Number of pages: 3 # Show the items on this page >>> list(page2) [11, 12, 13, 14, 15, 16, 17, 18, 19, 20] # Print the items in a for loop >>> for i in page2: print "This is entry", i This is entry 11 This is entry 12 This is entry 13 This is entry 14 This is entry 15 This is entry 16 This is entry 17 This is entry 18 This is entry 19 This is entry 20 There are further parameters to invoking a ``Page`` object. Please see :class:`webhelpers.paginate.Page` .. note:: Page numbers and item numbers start from 1. If you are accessing the items on the page by their index please note that the first item is ``item[1]`` instead of ``item[0]``. Switching between pages using a `pager` --------------------------------------- The user needs a way to get to another page. This is usually done with a list of links like ``Page 3 of 41 - 1 2 [3] 4 5 .. 41``. Such a list can be created by the Page's :meth:`~webhelpers.paginate.Page.pager` method. Take the above example again: .. code-block:: pycon >>> page2.pager() 1 2 3 Without the HTML tags it looks like ``1 [2] 3``. The links point to a URL where the respective page is found. And the current page (2) is highlighted. The appearance of a pager can be customized. By default the format string is ``~2~`` which means it shows adjacent pages from the current page with a maximal radius of 2. In a larger set this would look like ``1 .. 34 35 [36] 37 38 .. 176``. The radius of 2 means that two pages before and after the current page 36 are shown. Several special variables can be used in the format string. See :meth:`~webhelpers.paginate.Page.pager` for a complete list. Some examples for a pager of 20 pages while being on page 10 currently: .. code-block:: pycon >>> page.pager() 1 .. 8 9 [10] 11 12 .. 20 >>> page.pager('~4~') 1 .. 6 7 8 9 [10] 11 12 13 14 .. 20 >>> page.pager('Page $page of $page_count - ~3~') Page 10 of 20 - 1 .. 7 8 9 [10] 11 12 13 .. 20 >>> page.pager('$link_previous $link_next ~2~') < > 1 .. 8 9 [10] 11 12 .. 20 >>> page.pager('Items $first_item - $last_item / ~2~') Items 91 - 100 / 1 .. 8 9 [10] 11 12 .. 20 Paging over an SQLAlchemy query ------------------------------- If the data to page over comes from a database via SQLAlchemy then the ``paginate`` module can access a ``query`` object directly. This is useful when using ORM-mapped models. Example: .. code-block:: pycon >>> employee_query = Session.query(Employee) >>> page2 = webhelpers.paginate.Page( employee_query, page=2, items_per_page=10) >>> for employee in page2: print employee.first_name John Jack Joseph Kay Lars Lynn Pamela Sandra Thomas Tim The `paginate` module is smart enough to only query the database for the objects that are needed on this page. E.g. if a page consists of the items 11-20 then SQLAlchemy will be asked to fetch exactly that 10 rows through `LIMIT` and `OFFSET` in the actual SQL query. So you must not load the complete result set into memory and pass that. Instead always pass a `query` when creating a `Page`. Paging over an SQLAlchemy select -------------------------------- SQLAlchemy also allows to run arbitrary SELECTs on database tables. This is useful for non-ORM queries. `paginate` can use such select objects, too. Example: .. code-block:: pycon >>> selection = sqlalchemy.select([Employee.c.first_name]) >>> page2 = webhelpers.paginate.Page( selection, page=2, items_per_page=10, sqlalchemy_session=model.Session) >>> for first_name in page2: print first_name John Jack Joseph Kay Lars Lynn Pamela Sandra Thomas Tim The only difference to using SQLAlchemy *query* objects is that you need to pass an SQLAlchemy *session* via the ``sqlalchemy_session`` parameter. A bare ``select`` does not have a database connection assigned. But the session has. Usage in a Pylons controller and template ----------------------------------------- A simple example to begin with. Controller: .. code-block:: python def list(self): c.employees = webhelpers.paginate.Page( model.Session.query(model.Employee), page = int(request.params['page']), items_per_page = 5) return render('/employees/list.mako') Template: .. code-block:: mako ${c.employees.pager('Page $page: $link_previous $link_next ~4~')}
    % for employee in c.employees:
  • ${employee.first_name} ${employee.last_name}
  • % endfor
The `pager()` creates links to the previous URL and just sets the *page* parameter appropriately. That's why you need to pass the requested page number (``request.params['page']``) when you create a `Page`. Partial updates with AJAX ------------------------- Updating a page partially is easy. All it takes is a little Javascript that - instead of loading the complete page - updates just the part of the page containing the paginated items. The ``pager()`` method accepts an ``onclick`` parameter for that purpose. This value is added as an ``onclick`` parameter to the A-HREF tags. So the ``href`` parameter points to a URL that loads the complete page while the ``onclick`` parameter provides Javascript that loads a partial page. An example (using the jQuery Javascript library for simplification) may help explain that. Controller: .. code-block:: python def list(self): c.employees = webhelpers.paginate.Page( model.Session.query(model.Employee), page = int(request.params['page']), items_per_page = 5) if 'partial' in request.params: # Render the partial page return render('/employees/list-partial.mako') else: # Render the full page return render('/employees/list-full.mako') Template ``list-full.mako``: .. code-block:: mako ${webhelpers.html.tags.javascript_link('/public/jQuery.js')}
<%include file="list-partial.mako"/>
Template ``list-partial.mako``: .. code-block:: mako ${c.employees.pager( 'Page $page: $link_previous $link_next ~4~', onclick="$('#my-page-area').load('%s'); return false;")}
    % for employee in c.employees:
  • ${employee.first_name} ${employee.last_name}
  • % endfor
To avoid code duplication in the template the full template includes the partial template. If a partial page load is requested then just the ``list-partial.mako`` gets rendered. And if a full page load is requested then the ``list-full.mako`` is rendered which in turn includes the ``list-partial.mako``. The ``%s`` variable in the ``onclick`` string gets replaced with a URL pointing to the respective page with a ``partial=1`` added (the name of the parameter can be customized through the ``partial_param`` parameter). Example: * ``href`` parameter points to ``/employees/list?page=3`` * ``onclick`` parameter contains Javascript loading ``/employees/list?page=3&partial=1`` jQuery's syntax to load a URL into a certain DOM object (e.g. a DIV) is simply: .. code-block:: javascript $('#some-id').load('/the/url') The advantage of this technique is that it degrades gracefully. If the user does not have Javascript enabled then a full page is loaded. And if Javascript works then a partial load is done through the ``onclick`` action. .. _secure-forms: Secure Form Tag Helpers ======================= For prevention of Cross-site request forgery (CSRF) attacks. Generates form tags that include client-specific authorization tokens to be verified by the destined web app. Authorization tokens are stored in the client's session. The web app can then verify the request's submitted authorization token with the value in the client's session. This ensures the request came from the originating page. See the wikipedia entry for `Cross-site request forgery`__ for more information. .. __: http://en.wikipedia.org/wiki/Cross-site_request_forgery Pylons provides an ``authenticate_form`` decorator that does this verification on the behalf of controllers. These helpers depend on Pylons' ``session`` object. Most of them can be easily ported to another framework by changing the API calls. The helpers are implemented in such a way that it should be easy for developers to create their own helpers if using helpers for AJAX calls. :func:`authentication_token` returns the current authentication token, creating one and storing it in the session if it doesn't already exist. :func:`auth_token_hidden_field` creates a hidden field containing the authentication token. :func:`secure_form` is :func:`form` plus :func:`auth_token_hidden_field`. Pylons-1.0.1/pylons/docs/en/i18n.rst0000664000076500000240000006052711645401275017074 0ustar benstaff00000000000000.. _i18n: ===================================== Internationalization and Localization ===================================== Introduction ============ Internationalization and localization are means of adapting software for non-native environments, especially for other nations and cultures. Parts of an application which might need to be localized might include: * Language * Date/time format * Formatting of numbers e.g. decimal points, positioning of separators, character used as separator * Time zones (UTC in internationalized environments) * Currency * Weights and measures The distinction between internationalization and localization is subtle but important. Internationalization is the adaptation of products for potential use virtually everywhere, while localization is the addition of special features for use in a specific locale. For example, in terms of language used in software, internationalization is the process of marking up all strings that might need to be translated whilst localization is the process of producing translations for a particular locale. Pylons provides built-in support to enable you to internationalize language but leaves you to handle any other aspects of internationalization which might be appropriate to your application. .. note:: Internationalization is often abbreviated as I18N (or i18n or I18n) where the number 18 refers to the number of letters omitted. Localization is often abbreviated L10n or l10n in the same manner. These abbreviations also avoid picking one spelling (internationalisation vs. internationalization, etc.) over the other. In order to represent characters from multiple languages, you will need to utilize Unicode. This document assumes you have read the :ref:`unicode`. By now you should have a good idea of what Unicode is, how to use it in Python and which areas of you application need to pay specific attention to decoding and encoding Unicode data. This final section will look at the issue of making your application work with multiple languages. Pylons uses the `Python gettext module `_ for internationalization. It is based off the `GNU gettext API `_. Getting Started =============== Everywhere in your code where you want strings to be available in different languages you wrap them in the ``_()`` function. There are also a number of other translation functions which are documented in the API reference at http://pylonshq.com/docs/module-pylons.i18n.translation.html .. note:: The ``_()`` function is a reference to the ``ugettext()`` function. ``_()`` is a convention for marking text to be translated and saves on keystrokes. ``ugettext()`` is the Unicode version of ``gettext()``; it returns unicode strings. In our example we want the string ``'Hello'`` to appear in three different languages: English, French and Spanish. We also want to display the word ``'Hello'`` in the default language. We'll then go on to use some plural words too. Lets call our project ``translate_demo``: .. code-block:: bash $ paster create -t pylons translate_demo Now lets add a friendly controller that says hello: .. code-block:: bash $ cd translate_demo $ paster controller hello Edit ``controllers/hello.py`` to make use of the ``_()`` function everywhere where the string ``Hello`` appears: .. code-block:: python import logging from pylons.i18n import get_lang, set_lang from translate_demo.lib.base import * log = logging.getLogger(__name__) class HelloController(BaseController): def index(self): response.write('Default: %s
' % _('Hello')) for lang in ['fr','en','es']: set_lang(lang) response.write("%s: %s
" % (get_lang(), _('Hello'))) When writing wrapping strings in the gettext functions, it is important not to piece sentences together manually; certain languages might need to invert the grammars. Don't do this: .. code-block:: python # BAD! msg = _("He told her ") msg += _("not to go outside.") but this is perfectly acceptable: .. code-block:: python # GOOD msg = _("He told her not to go outside") The controller has now been internationalized, but it will raise a ``LanguageError`` until we have setup the alternative language catalogs. GNU gettext use three types of files in the translation framework. POT (Portable Object Template) files ------------------------------------ The first step in the localization process. A program is used to search through your project's source code and pick out every string passed to one of the translation functions, such as ``_()``. This list is put together in a specially-formatted template file that will form the basis of all translations. This is the ``.pot`` file. PO (Portable Object) files -------------------------- The second step in the localization process. Using the POT file as a template, the list of messages are translated and saved as a ``.po`` file. MO (Machine Object) files ------------------------- The final step in the localization process. The PO file is run through a program that turns it into an optimized machine-readable binary file, which is the ``.mo`` file. Compiling the translations to machine code makes the localized program much faster in retrieving the translations while it is running. GNU gettext provides a suite of command line programs for extracting messages from source code and working with the associated gettext catalogs. The `Babel `_ project provides pure Python alternative versions of these tools. Unlike the GNU gettext tool `xgettext`, Babel supports extracting translatable strings from Python templating languages (currently Mako and Genshi). Using Babel =========== .. image:: _static/babel_logo.png To use Babel, you must first install it via easy_install. Run the command: .. code-block:: bash $ easy_install Babel Pylons (as of 0.9.6) includes some sane defaults for Babel's distutils commands in the setup.cfg file. It also includes an extraction method mapping in the setup.py file. It is commented out by default, to avoid distutils warning about it being an unrecognized option when Babel is not installed. These lines should be uncommented before proceeding with the rest of this walk through: .. code-block :: python message_extractors = {'translate_demo': [ ('**.py', 'python', None), ('templates/**.mako', 'mako', None), ('public/**', 'ignore', None)]}, We'll use Babel to extract messages to a ``.pot`` file in your project's ``i18n`` directory. First, the directory needs to be created. Don't forget to add it to your revision control system if one is in use: .. code-block:: bash $ cd translate_demo $ mkdir translate_demo/i18n $ svn add translate_demo/i18n Next we can extract all messages from the project with the following command: .. code-block:: bash $ python setup.py extract_messages running extract_messages extracting messages from translate_demo/__init__.py extracting messages from translate_demo/websetup.py ... extracting messages from translate_demo/tests/functional/test_hello.py writing PO template file to translate_demo/i18n/translate_demo.pot This will create a ``.pot`` file in the ``i18n`` directory that looks something like this: .. code-block:: pot # Translations template for translate_demo. # Copyright (C) 2007 ORGANIZATION # This file is distributed under the same license as the translate_demo project. # FIRST AUTHOR , 2007. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: translate_demo 0.0.0\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2007-08-02 18:01-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9dev-r215\n" #: translate_demo/controllers/hello.py:10 translate_demo/controllers/hello.py:13 msgid "Hello" msgstr "" The ``.pot`` details that appear here can be customized via the ``extract_messages`` configuration in your project's ``setup.cfg`` (See the `Babel Command-Line Interface Documentation `_ for all configuration options). Next, we'll initialize a catalog (``.po`` file) for the Spanish language: .. code-block:: bash $ python setup.py init_catalog -l es running init_catalog creating catalog 'translate_demo/i18n/es/LC_MESSAGES/translate_demo.po' based on 'translate_demo/i18n/translate_demo.pot' Then we can edit the last line of the new Spanish ``.po`` file to add a translation of ``"Hello"``: .. code-block:: bash msgid "Hello" msgstr "¡Hola!" Finally, to utilize these translations in our application, we need to compile the ``.po`` file to a ``.mo`` file: .. code-block:: bash $ python setup.py compile_catalog running compile_catalog 1 of 1 messages (100%) translated in 'translate_demo/i18n/es/LC_MESSAGES/translate_demo.po' compiling catalog 'translate_demo/i18n/es/LC_MESSAGES/translate_demo.po' to 'translate_demo/i18n/es/LC_MESSAGES/translate_demo.mo' We can also use the ``update_catalog`` command to merge new messages from the ``.pot`` to the ``.po`` files. For example, if we later added the following line of code to the end of HelloController's index method: .. code-block :: python response.write('Goodbye: %s' % _('Goodbye')) We'd then need to re-extract the messages from the project, then run the ``update_catalog`` command: .. code-block:: bash $ python setup.py extract_messages running extract_messages extracting messages from translate_demo/__init__.py extracting messages from translate_demo/websetup.py ... extracting messages from translate_demo/tests/functional/test_hello.py writing PO template file to translate_demo/i18n/translate_demo.pot $ python setup.py update_catalog running update_catalog updating catalog 'translate_demo/i18n/es/LC_MESSAGES/translate_demo.po' based on 'translate_demo/i18n/translate_demo.pot' We'd then edit our catalog to add a translation for "Goodbye", and recompile the ``.po`` file as we did above. For more information, see the `Babel documentation `_ and the `GNU Gettext Manual `_. Back To Work ============ Next we'll need to repeat the process of creating a ``.mo`` file for the ``en`` and ``fr`` locales: .. code-block:: bash $ python setup.py init_catalog -l en running init_catalog creating catalog 'translate_demo/i18n/en/LC_MESSAGES/translate_demo.po' based on 'translate_demo/i18n/translate_demo.pot' $ python setup.py init_catalog -l fr running init_catalog creating catalog 'translate_demo/i18n/fr/LC_MESSAGES/translate_demo.po' based on 'translate_demo/i18n/translate_demo.pot' Modify the last line of the ``fr`` catalog to look like this: .. code-block:: po #: translate_demo/controllers/hello.py:10 translate_demo/controllers/hello.py:13 msgid "Hello" msgstr "Bonjour" Since our original messages are already in English, the ``en`` catalog can stay blank; gettext will fallback to the original. Once you've edited these new ``.po`` files and compiled them to ``.mo`` files, you'll end up with an ``i18n`` directory containing: .. code-block:: text i18n/translate_demo.pot i18n/en/LC_MESSAGES/translate_demo.po i18n/en/LC_MESSAGES/translate_demo.mo i18n/es/LC_MESSAGES/translate_demo.po i18n/es/LC_MESSAGES/translate_demo.mo i18n/fr/LC_MESSAGES/translate_demo.po i18n/fr/LC_MESSAGES/translate_demo.mo Testing the Application ======================= Start the server with the following command: .. code-block:: bash $ paster serve --reload development.ini Test your controller by visiting http://localhost:5000/hello. You should see the following output: .. code-block:: text Default: Hello fr: Bonjour en: Hello es: ¡Hola! You can now set the language used in a controller on the fly. For example this could be used to allow a user to set which language they wanted your application to work in. You could save the value to the session object: .. code-block:: python session['lang'] = 'en' session.save() then on each controller call the language to be used could be read from the session and set in your controller's ``__before__()`` method so that the pages remained in the same language that was previously set: .. code-block:: python def __before__(self): if 'lang' in session: set_lang(session['lang']) Pylons also supports defining the default language to be used in the configuration file. Set a ``lang`` variable to the desired default language in your ``development.ini`` file, and Pylons will automatically call ``set_lang`` with that language at the beginning of every request. E.g. to set the default language to Spanish, you would add ``lang = es`` to your ``development.ini``: .. code-block:: ini [app:main] use = egg:translate_demo lang = es If you are running the server with the ``--reload`` option the server will automatically restart if you change the ``development.ini`` file. Otherwise restart the server manually and the output would this time be as follows: .. code-block:: text Default: ¡Hola! fr: Bonjour en: Hello es: ¡Hola! Fallback Languages ================== If your code calls ``_()`` with a string that doesn't exist at all in your language catalog, the string passed to ``_()`` is returned instead. Modify the last line of the hello controller to look like this: .. code-block:: python response.write("%s %s, %s" % (_('Hello'), _('World'), _('Hi!'))) .. warning :: Of course, in real life breaking up sentences in this way is very dangerous because some grammars might require the order of the words to be different. If you run the example again the output will be: .. code-block:: text Default: ¡Hola! fr: Bonjour World! en: Hello World! es: ¡Hola! World! This is because we never provided a translation for the string ``'World!'`` so the string itself is used. Pylons also provides a mechanism for fallback languages, so that you can specify other languages to be used if the word is omitted from the main language's catalog. In this example we choose ``fr`` as the main language but ``es`` as a fallback: .. code-block:: python import logging from pylons.i18n import set_lang from translate_demo.lib.base import * log = logging.getLogger(__name__) class HelloController(BaseController): def index(self): set_lang(['fr', 'es']) return "%s %s, %s" % (_('Hello'), _('World'), _('Hi!')) If ``Hello`` is in the ``fr`` ``.mo`` file as ``Bonjour``, ``World`` is only in ``es`` as ``Mundo`` and none of the catalogs contain ``Hi!``, you'll get the multilingual message: ``Bonjour Mundo, Hi!``. This is a combination of the French, Spanish and original (English in this case, as defined in our source code) words. You can also add fallback languages after calling ``set_lang`` via the ``pylons.i18n.add_fallback`` function. Translations will be tested in the order you add them. .. note:: Fallbacks are reset after calling ``set_lang(lang)`` -- that is, fallbacks are associated with the currently selected language. One case where using fallbacks in this way is particularly useful is when you wish to display content based on the languages requested by the browser in the ``HTTP_ACCEPT_LANGUAGE`` header. Typically the browser may submit a number of languages so it is useful to be add fallbacks in the order specified by the browser so that you always try to display words in the language of preference and search the other languages in order if a translation cannot be found. The languages defined in the ``HTTP_ACCEPT_LANGUAGE`` header are available in Pylons as ``request.languages`` and can be used like this: .. code-block:: python for lang in request.languages: add_fallback(lang) Translations Within Templates ============================= You can also use the ``_()`` function within templates in exactly the same way you do in code. For example, in a Mako template: .. code-block:: mako ${_('Hello')} would produce the string ``'Hello'`` in the language you had set. Babel currently supports extracting gettext messages from Mako and Genshi templates. The Mako extractor also provides support for translator comments. Babel can be extended to extract messages from other sources via a `custom extraction method plugin `_. Pylons (as of 0.9.6) automatically configures a Babel extraction mapping for your Python source code and Mako templates. This is defined in your project's setup.py file: .. code-block:: python message_extractors = {'translate_demo': [ ('**.py', 'python', None), ('templates/**.mako', 'mako', None), ('public/**', 'ignore', None)]}, For a project using Genshi instead of Mako, the Mako line might be replaced with: .. code-block:: python ('templates/**.html, 'genshi', None), See `Babel's documentation on Message Extraction `_ for more information. Lazy Translations ================= Occasionally you might come across a situation when you need to translate a string when it is accessed, not when the ``_()`` or other functions are called. Consider this example: .. code-block:: python import logging from pylons.i18n import get_lang, set_lang from translate_demo.lib.base import * log = logging.getLogger(__name__) text = _('Hello') class HelloController(BaseController): def index(self): response.write('Default: %s
' % _('Hello')) for lang in ['fr','en','es']: set_lang(lang) response.write("%s: %s
" % (get_lang(), _('Hello'))) response.write('Text: %s
' % text) If we run this we get the following output: .. code-block:: text Default: Hello ['fr']: Bonjour ['en']: Good morning ['es']: Hola Text: Hello This is because the function ``_('Hello')`` just after the imports is called when the default language is ``en`` so the variable ``text`` gets the value of the English translation even though when the string was used the default language was Spanish. The rule of thumb in these situations is to try to avoid using the translation functions in situations where they are not executed on each request. For situations where this isn't possible, perhaps because you are working with legacy code or with a library which doesn't support internationalization, you need to use lazy translations. If we modify the above example so that the import statements and assignment to ``text`` look like this: .. code-block:: python from pylons.i18n import get_lang, lazy_gettext, set_lang from helloworld.lib.base import * log = logging.getLogger(__name__) text = lazy_gettext('Hello') then we get the output we expected: .. code-block:: text Default: Hello ['fr']: Bonjour ['en']: Good morning ['es']: Hola Text: Hola There are lazy versions of all the standard Pylons `translation functions `_. There is one drawback to be aware of when using the lazy translation functions: they are not actually strings. This means that if our example had used the following code it would have failed with an error ``cannot concatenate 'str' and 'LazyString' objects``: .. code-block:: python response.write('Text: ' + text + '
') For this reason you should only use the lazy translations where absolutely necessary and should always ensure they are converted to strings by calling ``str()`` or ``repr()`` before they are used in operations with real strings. Producing a Python Egg ====================== Finally you can produce an egg of your project which includes the translation files like this: .. code-block:: bash $ python setup.py bdist_egg The ``setup.py`` automatically includes the ``.mo`` language catalogs your application needs so that your application can be distributed as an egg. This is done with the following line in your ``setup.py`` file: .. code-block:: python package_data={'translate_demo': ['i18n/*/LC_MESSAGES/*.mo']}, Plural Forms ============ Pylons also provides the ``ungettext()`` function. It's designed for internationalizing plural words, and can be used as follows: .. code-block:: python ungettext('There is %(num)d file here', 'There are %(num)d files here', n) % {'num': n} Plural forms have a different type of entry in ``.pot``/``.po`` files, as described in `The Format of PO Files `_ in `GNU Gettext's Manual `_: .. code-block:: pot #: translate_demo/controllers/hello.py:12 #, python-format msgid "There is %(num)d file here" msgid_plural "There are %(num)d files here" msgstr[0] "" msgstr[1] "" One thing to keep in mind is that other languages don't have the same plural forms as English. While English only has 2 plural forms, singular and plural, Slovenian has 4! That means that you *must* use ugettext for proper pluralization. Specifically, the following will not work: .. code-block:: python # BAD! if n == 1: msg = _("There was no dog.") else: msg = _("There were no dogs.") Summary ======= This document only covers the basics of internationalizing and localizing a web application. GNU Gettext is an extensive library, and the GNU Gettext Manual is highly recommended for more information. Babel also provides support for interfacing to the CLDR (Common Locale Data Repository), providing access to various locale display names, localized number and date formatting, etc. You should also be able to internationalize and then localize your application using Pylons' support for GNU gettext. Further Reading =============== http://en.wikipedia.org/wiki/Internationalization Please feel free to report any mistakes to the Pylons mailing list or to the author. Any corrections or clarifications would be gratefully received. .. note:: This is a work in progress. We hope the internationalization, localization and Unicode support in Pylons is now robust and flexible but we would appreciate hearing about any issues we have. Just drop a line to the pylons-discuss mailing list on Google Groups. :mod:`babel.core` -- Babel core classes =================================================== .. module:: babel.core .. automodule:: babel Module Contents --------------- .. autoclass:: Locale :members: .. autofunction:: default_locale .. autofunction:: negotiate_locale .. autofunction:: parse_locale :mod:`babel.localedata` --- Babel locale data ==================================================== .. automodule:: babel.localedata .. autofunction:: exists .. autofunction:: exists :mod:`babel.dates` -- Babel date classes =================================================== .. automodule:: babel.dates Module Contents --------------- .. autoclass:: DateTimeFormat :members: .. autoclass:: DateTimePattern :members: :mod:`babel.numbers` -- Babel number classes =================================================== .. automodule:: babel.numbers Module Contents --------------- .. autoclass:: NumberFormatError :members: .. autoclass:: NumberPattern :members: __init__, apply .. autofunction:: format_number .. autofunction:: format_decimal .. autofunction:: format_percent .. autofunction:: format_scientific .. autofunction:: parse_number .. autofunction:: parse_decimal .. autofunction: format_currency Pylons-1.0.1/pylons/docs/en/index.rst0000664000076500000240000000330211645401275017410 0ustar benstaff00000000000000Pylons Reference Documentation ============================== .. image:: _static/pylon1.jpg :alt: The First Pylon of the Ramesseum, Thebes is approximately 69m long and 22m high, and marks the entrance to the Main Temple and the First Courtyard. :align: center :height: 255 :width: 780 Getting Started with Pylons --------------------------- .. toctree:: :maxdepth: 2 gettingstarted concepts MVC Reference ------------- .. toctree:: :maxdepth: 2 controllers views models advanced_models Project Configuration and Logging --------------------------------- .. toctree:: :maxdepth: 2 configuration logging Forms, Validation, and Helpers ------------------------------ .. toctree:: :maxdepth: 2 helpers forms Internationalization, Sessions, and Caching ------------------------------------------- .. toctree:: :maxdepth: 2 i18n sessions caching Testing, Upgrading, and Deploying --------------------------------- .. toctree:: :maxdepth: 2 testing debugging upgrading deployment Installation for Windows / Python 2.3 ------------------------------------- .. toctree:: :maxdepth: 2 python23_install windowsnotes Pylons on Jython ---------------- .. toctree:: :maxdepth: 2 jython Advanced Pylons --------------- .. toctree:: :maxdepth: 2 security_policy_for_bugs wsgi_support advanced_pylons/index execution Module Listing -------------- .. toctree:: :maxdepth: 2 modules/index thirdparty/index glossary For further information, indices are available: Indices ======= * :ref:`genindex` * :ref:`modindex` * :ref:`search` * :ref:`glossary` Pylons-1.0.1/pylons/docs/en/jython.rst0000664000076500000240000000507111645401275017621 0ustar benstaff00000000000000.. _jython: ================ Pylons on Jython ================ Pylons supports `Jython `_ as of v0.9.7. Installation ============ The installation process is the same as CPython, as described in :ref:`getting_started`. At least Jython 2.5b2 is required. .. _java_deployment: Deploying to Java Web servers ============================= The Java platform defines the `Servlet API`_ for creating web applications. The `modjy`_ library included with Jython provides a gateway between Java Servlets and WSGI applications. The `snakefight`_ tool can create a `WAR file`_ from a Pylons application (and modjy) that's suitable for deployment to the various `Servlet containers`_ (such as `Apache Tomcat`_ or `Sun's Glassfish`_). Creating .wars with snakefight ------------------------------ First, install snakefight: .. code-block :: bash $ easy_install snakefight This adds an additional command to distutils: :command:`bdist_war`. Pylons applications are loaded from Paste, via its ``paste.app_factory`` entry point and a Paste style configuration file. :command:`bdist_war` knows how to setup Paste apps for deployment when specified the :option:`--paste-config` option: .. code-block :: bash $ paster make-config MyApp production.ini $ jython setup.py bdist_war --paste-config production.ini As with any distutils command the preferred options can instead be added to the :file:`setup.cfg` in the root directory of the project: .. code-block :: ini [bdist_war] paste-config = production.ini Then we can simply run: .. code-block :: bash $ jython setup.py bdist_war :command:`bdist_war` creates a :file:`.war` with the following: - Jython's :file:`jar` files in :file:`WEB-INF/lib` - Jython's stdlib in :file:`WEB-INF/lib-python` - Your application's required eggs in :file:`WEB-INF/lib-python` With the :option:`--paste-config` option, it also: - Creates a simple loader for the application/config - Generates a :file:`web.xml` deployment descriptor configuring modjy to load the application with the simple loader For further information/usages, see `snakefight's documentation`_. .. _`Servlet API`: http://en.wikipedia.org/wiki/Java_Servlet .. _`modjy`: http://modjy.xhaus.com/ .. _`snakefight`: http://pypi.python.org/pypi/snakefight .. _`snakefight's documentation`: http://pypi.python.org/pypi/snakefight .. _`WAR file`: http://en.wikipedia.org/wiki/Sun_WAR_(file_format) .. _`Servlet containers`: http://en.wikipedia.org/wiki/Servlet_container .. _`Apache Tomcat`: http://tomcat.apache.org/ .. _`Sun's Glassfish`: http://glassfish.org/ Pylons-1.0.1/pylons/docs/en/logging.rst0000664000076500000240000004223211645401275017734 0ustar benstaff00000000000000.. _logging: ======= Logging ======= Logging messages ---------------- As of Pylons 0.9.6, Pylons controllers (created via ``paster controller/restcontroller``) and ``websetup.py`` create their own Logger objects via `Python's logging module `_. For example, in the helloworld project's hello controller (``helloworld/controllers/hello.py``): .. code-block:: python import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect log = logging.getLogger(__name__) class HelloController(BaseController): def index(self): ... Python's special ``__name__`` variable refers to the current module's fully qualified name; in this case, ``helloworld.controllers.hello``. To log messages, simply use methods available on that Logger object: .. code-block:: python import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect log = logging.getLogger(__name__) class HelloController(BaseController): def index(self): content_type = 'text/plain' content = 'Hello World!' log.debug('Returning: %s (content-type: %s)', content, content_type) response.content_type = content_type return content Which will result in the following printed to the console, on stderr: .. code-block:: text 16:20:20,440 DEBUG [helloworld.controllers.hello] Returning: Hello World! (content-type: text/plain) Basic Logging configuration --------------------------- As of Pylons 0.9.6, the default ini files include a basic configuration for the logging module. Paste ini files use the Python standard `ConfigParser format `_; the same format used for the Python `logging module's Configuration file format `_. ``paster``, when loading an application via the ``paster`` ``serve``, ``shell`` or ``setup-app`` commands, calls the `logging.fileConfig function `_ on that specified ini file if it contains a 'loggers' entry. ``logging.fileConfig`` reads the logging configuration from a ``ConfigParser`` file. Logging configuration is provided in both the default ``development.ini`` and the production ini file (created via ``paster make-config ``). The production ini's logging setup is a little simpler than the ``development.ini``'s, and is as follows: .. code-block:: ini # Logging configuration [loggers] keys = root [handlers] keys = console [formatters] keys = generic [logger_root] level = INFO handlers = console [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s] [%(threadName)s] %(message)s One root Logger is created that logs only messages at a level above or equal to the ``INFO`` level to stderr, with the following format: .. code-block:: text 2007-08-17 15:04:08,704 INFO [helloworld.controllers.hello] Loading resource, id: 86 For those familiar with the ``logging.basicConfig`` function, this configuration is equivalent to the code: .. code-block:: python logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)-5.5s [%(name)s] %(message)s') The default ``development.ini``'s logging section has a couple of differences: it uses a less verbose timestamp, and defaults your application's log messages to the ``DEBUG`` level (described in the next section). Pylons and many other libraries (such as Beaker, SQLAlchemy, Paste) log a number of messages for debugging purposes. Switching the root Logger level to ``DEBUG`` reveals them: .. code-block:: ini [logger_root] #level = INFO level = DEBUG handlers = console Filtering log messages ---------------------- Often there's too much log output to sift through, such as when switching the root Logger's level to ``DEBUG``. An example: you're diagnosing database connection issues in your application and only want to see SQLAlchemy's ``DEBUG`` messages in relation to database connection pooling. You can leave the root Logger's level at the less verbose ``INFO`` level and set that particular SQLAlchemy Logger to ``DEBUG`` on its own, apart from the root Logger: .. code-block:: ini [logger_sqlalchemy.pool] level = DEBUG handlers = qualname = sqlalchemy.pool then add it to the list of Loggers: .. code-block:: ini [loggers] keys = root, sqlalchemy.pool No Handlers need to be configured for this Logger as by default non root Loggers will propagate their log records up to their parent Logger's Handlers. The root Logger is the top level parent of all Loggers. This technique is used in the default ``development.ini``. The root Logger's level is set to ``INFO``, whereas the application's log level is set to ``DEBUG``: .. code-block:: ini # Logging configuration [loggers] keys = root, helloworld .. code-block:: ini [logger_helloworld] level = DEBUG handlers = qualname = helloworld All of the child Loggers of the helloworld Logger will inherit the ``DEBUG`` level unless they're explicitly set differently. Meaning the ``helloworld.controllers.hello``, ``helloworld.websetup`` (and all your app's modules') Loggers by default have an effective level of ``DEBUG`` too. For more advanced filtering, the logging module provides a `Filter `_ object; however it cannot be used directly from the configuration file. Advanced Configuration ---------------------- To capture log output to a separate file, use a `FileHandler `_ (or a `RotatingFileHandler `_): .. code-block:: ini [handler_accesslog] class = FileHandler args = ('access.log','a') level = INFO formatter = generic Before it's recognized, it needs to be added to the list of Handlers: .. code-block:: ini [handlers] keys = console, accesslog and finally utilized by a Logger. .. code-block:: ini [logger_root] level = INFO handlers = console, accesslog These final 3 lines of configuration directs all of the root Logger's output to the access.log as well as the console; we'll want to disable this for the next section. Request logging with Paste's TransLogger ---------------------------------------- Paste provides the `TransLogger `_ middleware for logging requests using the `Apache Combined Log Format `_. TransLogger combined with a FileHandler can be used to create an ``access.log`` file similar to Apache's. Like any standard middleware with a Paste entry point, TransLogger can be configured to wrap your application in the ``[app:main]`` section of the ini file: .. code-block:: ini filter-with = translogger [filter:translogger] use = egg:Paste#translogger setup_console_handler = False This is equivalent to wrapping your app in a TransLogger instance via the bottom of your project's ``config/middleware.py`` file: .. code-block:: python from paste.translogger import TransLogger app = TransLogger(app, setup_console_handler=False) return app TransLogger will automatically setup a logging Handler to the console when called with no arguments, so it 'just works' in environments that don't configure logging. Since we've configured our own logging Handlers, we need to disable that option via ``setup_console_handler = False``. With the filter in place, TransLogger's Logger (named the 'wsgi' Logger) will propagate its log messages to the parent Logger (the root Logger), sending its output to the console when we request a page: .. code-block:: text 00:50:53,694 INFO [helloworld.controllers.hello] Returning: Hello World! (content-type: text/plain) 00:50:53,695 INFO [wsgi] 192.168.1.111 - - [11/Aug/2007:20:09:33 -0700] "GET /hello HTTP/1.1" 404 - "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6" To direct TransLogger to the ``access.log`` FileHandler defined above, we need to add that FileHandler to the wsgi Logger's list of Handlers: .. code-block:: ini # Logging configuration [loggers] keys = root, wsgi .. code-block:: ini [logger_wsgi] level = INFO handlers = handler_accesslog qualname = wsgi propagate = 0 As mentioned above, non-root Loggers by default propagate their log Records to the root Logger's Handlers (currently the console Handler). Setting ``propagate`` to 0 (false) here disables this; so the ``wsgi`` Logger directs its records only to the ``accesslog`` Handler. Finally, there's no need to use the ``generic`` Formatter with TransLogger as TransLogger itself provides all the information we need. We'll use a Formatter that passes-through the log messages as is: .. code-block:: ini [formatters] keys = generic, accesslog .. code-block:: ini [formatter_accesslog] format = %(message)s Then wire this new ``accesslog`` Formatter into the FileHandler: .. code-block:: ini [handler_accesslog] class = FileHandler args = ('access.log','a') level = INFO formatter = accesslog Logging to wsgi.errors ---------------------- Pylons provides a custom logging Handler class, `pylons.log.WSGIErrorsHandler `_, for logging output to ``environ['wsgi.errors']``: the WSGI server's error stream (see the `WSGI Spefification, PEP 333 `_ for more information). ``wsgi.errors`` can be useful to log to in certain situations, such as when deployed under Apache mod_wsgi/mod_python, where the ``wsgi.errors`` stream is the Apache error log. To configure logging of only ``ERROR`` (and ``CRITICAL``) messages to ``wsgi.errors``, add the following to the ini file: .. code-block:: ini [handlers] keys = console, wsgierrors .. code-block:: ini [handler_wsgierrors] class = pylons.log.WSGIErrorsHandler args = () level = ERROR format = generic then add the new Handler name to the list of Handlers used by the root Logger: .. code-block:: ini [logger_root] level = INFO handlers = console, wsgierrors .. warning :: ``WSGIErrorsHandler`` does not receive log messages created during application startup. This is due to the ``wsgi.errors`` stream only being available through the ``environ`` dictionary; which isn't available until a request is made. Lumberjacking with log4j's Chainsaw =================================== Java's ``log4j`` project provides the Java GUI application `Chainsaw `_ for viewing and managing log messages. Among its features are the ability to filter log messages on the fly, and customizable color highlighting of log messages. We can configure Python's logging module to output to a format parsable by Chainsaw, ``log4j``'s `XMLLayout `_ format. To do so, we first need to install the `Python XMLLayout package `_: .. code-block:: bash $ easy_install XMLLayout It provides a log Formatter that generates ``XMLLayout`` XML. It also provides ``RawSocketHandler``; like the logging module's ``SocketHandler``, it sends log messages across the network, but does not pickle them. The following is an example configuration for sending ``XMLLayout`` log messages across the network to Chainsaw, if it were listening on `localhost` port `4448`: .. code-block:: ini [handlers] keys = console, chainsaw [formatters] keys = generic, xmllayout [logger_root] level = INFO handlers = console, chainsaw .. code-block:: ini [handler_chainsaw] class = xmllayout.RawSocketHandler args = ('localhost', 4448) level = NOTSET formatter = xmllayout .. code-block:: ini [formatter_xmllayout] class = xmllayout.XMLLayout This configures any log messages handled by the root Logger to also be sent to Chainsaw. The default ``development.ini`` configures the root Logger to the ``INFO`` level, however in the case of using Chainsaw, it is preferable to configure the root Logger to ``NOTSET`` so *all* log messages are sent to Chainsaw. Instead, we can restrict the console handler to the ``INFO`` level: .. code-block:: ini [logger_root] level = NOTSET handlers = console [handler_console] class = StreamHandler args = (sys.stderr,) level = INFO formatter = generic Chainsaw can be downloaded from its `home page `_, but can also be launched directly from a Java-enabled browser via the link: `Chainsaw web start `_. It can be configured from the GUI, but it also supports reading its configuration from a ``log4j.xml`` file. The following ``log4j.xml`` file configures Chainsaw to listen on port `4448` for ``XMLLayout`` style log messages. It also hides Chainsaw's own logging messages under the ``WARN`` level, so only your app's log messages are displayed: .. code-block:: xml Chainsaw will prompt for a configuration file upon startup. The configuration can also be loaded later by clicking `File`/`Load Log4J File...`. You should see an XMLSocketReceiver instance loaded in Chainsaw's Receiver list, configured at port `4448`, ready to receive log messages. Here's how the Pylons stack's log messages can look with colors defined (using Chainsaw on OS X): .. image:: _static/Pylons_Stack-Chainsaw-OSX.png :width: 750px :height: 469px Alternate Logging Configuration style ===================================== Pylons' default ini files include a basic configuration for Python's logging module. Its format matches the standard Python :mod:`logging` module's `config file format `_ . If a more concise format is preferred, here is Max Ischenko's demonstration of an alternative style to setup logging. The following function is called at the application start up (e.g. Global ctor): .. code-block:: python def setup_logging(): logfile = config['logfile'] if logfile == 'STDOUT': # special value, used for unit testing logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, #format='%(name)s %(levelname)s %(message)s', #format='%(asctime)s,%(msecs)d %(levelname)s %(message)s', format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', datefmt='%H:%M:%S') else: logdir = os.path.dirname(os.path.abspath(logfile)) if not os.path.exists(logdir): os.makedirs(logdir) logging.basicConfig(filename=logfile, mode='at+', level=logging.DEBUG, format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', datefmt='%Y-%b-%d %H:%M:%S') setup_thirdparty_logging() The setup_thirdparty_logging function searches through the certain keys of the application ``.ini`` file which specify logging level for a particular logger (module). .. code-block:: python def setup_thirdparty_logging(): for key in config: if not key.endswith('logging'): continue value = config.get(key) key = key.rstrip('.logging') loglevel = logging.getLevelName(value) log.info('Set %s logging for %s', logging.getLevelName(loglevel), key) logging.getLogger(key).setLevel(loglevel) Relevant section of the .ini file (example): .. code-block:: ini sqlalchemy.logging = WARNING sqlalchemy.orm.unitofwork.logging = INFO sqlalchemy.engine.logging = DEBUG sqlalchemy.orm.logging = INFO routes.logging = WARNING This means that routes logger (and all sub-loggers such as routes.mapper) only passes through messages of at least WARNING level; sqlalachemy defaults to WARNING level but some loggers are configured with more verbose level to aid debugging. Pylons-1.0.1/pylons/docs/en/Makefile0000644000076500000240000000422311674172351017212 0ustar benstaff00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html web htmlhelp latex changes linkcheck help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " web to make files usable by Sphinx.web" @echo " htmlhelp to make HTML files and a HTML help project" @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" clean: -rm -rf _build/* html: mkdir -p _build/html _build/doctrees $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html @echo @echo "Build finished. The HTML pages are in _build/html." web: mkdir -p _build/web _build/doctrees $(SPHINXBUILD) -b web $(ALLSPHINXOPTS) _build/web @echo @echo "Build finished; now you can run" @echo " python -m sphinx.web _build/web" @echo "to start the server." htmlhelp: mkdir -p _build/htmlhelp _build/doctrees $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in _build/htmlhelp." latex: mkdir -p _build/latex _build/doctrees $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex @echo @echo "Build finished; the LaTeX files are in _build/latex." @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ "run these through (pdf)latex." changes: mkdir -p _build/changes _build/doctrees $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes @echo @echo "The overview file is in _build/changes." linkcheck: mkdir -p _build/linkcheck _build/doctrees $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in _build/linkcheck/output.txt." Pylons-1.0.1/pylons/docs/en/models.rst0000664000076500000240000006506511645401275017602 0ustar benstaff00000000000000.. _models: ====== Models ====== About the model =============== .. image:: _static/pylon3.jpg :alt: :align: left :height: 450px :width: 368px In the MVC paradigm the *model* manages the behavior and data of the application domain, responds to requests for information about its state and responds to instructions to change state. The model represents enterprise data and business rules. It is where most of the processing takes place when using the MVC design pattern. Databases are in the remit of the model, as are component objects such as :term:`EJBs` and :term:`ColdFusion Components`. The data returned by the model is display-neutral, i.e. the model applies no formatting. A single model can provide data for any number of display interfaces. This reduces code duplication as model code is written only once and is then reused by all of the views. Because the model returns data without applying any formatting, the same components can be used with any interface. For example, most data is typically formatted with HTML but it could also be formatted with Macromedia Flash or WAP. The model also isolates and handles state management and data persistence. For example, a Flash site or a wireless application can both rely on the same session-based shopping cart and e-commerce processes. Because the model is self-contained and separate from the controller and the view, changing the data layer or business rules is less painful. If it proves necessary to switch databases, e.g. from MySQL to Oracle, or change a data source from an RDBMS to LDAP, the only required task is that of altering the model. If the view is written correctly, it won’t care at all whether a list of users came from a database or an LDAP server. This freedom arises from the way that the three parts of an MVC-based application act as `black boxes`, the inner workings of each one are hidden from, and are independent of, the other two. The approach promotes well-defined interfaces and self-contained components. .. note:: *adapted from an Oct 2002 TechRepublic article by by Brian Kotek: "MVC design pattern brings about better organization and code reuse"* - http://articles.techrepublic.com.com/5100-10878_11-1049862.html Model Basics ============ Pylons provides a :data:`model` package to put your database code in but does not offer a database engine or API. Instead there are several third-party APIs to choose from. The recommended and most commonly-adopted approach used in Pylons applications is to use SQLAlchemy with the declarative configuration style and develop with a relational database (Postgres, MySQL, etc). **This is the documented and recommended approach for creating a Pylons project with a SQL database**. Install SQLAlchemy ------------------ We'll assume you've already installed Pylons and have the `easy_install` command. At the command line, run: .. code-block:: bash easy_install SQLAlchemy Next you'll have to install a database engine and its Python bindings. If you don't know which one to choose, SQLite is a good one to start with. It's small and easy to install, and Python 2.5 includes bindings for it. Installing the database engine is beyond the scope of this article, but here are the Python bindings you'll need for the most popular engines: .. code-block:: bash easy_install pysqlite # If you use SQLite and Python 2.4 (not needed for Python 2.5) easy_install MySQL-python # If you use MySQL easy_install psycopg2 # If you use PostgreSQL See the `Python Package Index `_ (formerly the Cheeseshop) for other database drivers. .. tip:: Checking Your Version To see which version of SQLAlchemy you have, go to a Python shell and look at ``sqlalchemy.__version__`` : .. code-block:: pycon >>> import sqlalchemy >>> sqlalchemy.__version__ 0.5.8 Create a Pylons Project with SQLAlchemy --------------------------------------- When creating a Pylons project, one of the questions asked as part of the project creation dialogue is whether the project should be configured with SQLAlchemy. Before continuing, ensure that the project was created with this option, if it's missing the :file:`model/meta.py` file, then the project should be re-created with this option. .. tip:: The project doesn't need to be deleted to add this option, just re-run the `paster` command in the project's parent directory and answer "yes" to the SQLAlchemy prompt. The files will then be added and existing files will present a prompt on whether to replace them or leave the current file. Configure SQLAlchemy -------------------- When your Pylons application runs, it needs to know which database to connect to. Normally you put this information in *development.ini* and activate the model in *environment.py*: put the following in *development.ini* in the `\[app:main\]` section, depending on your database, For SQLite ^^^^^^^^^^ .. code-block:: ini sqlalchemy.url = sqlite:///%(here)s/mydatabasefilename.sqlite Where `mydatabasefilename.db` is the path to your SQLite database file. "%(here)s" represents the directory containing the development.ini file. If you're using an absolute path, use four slashes after the colon: "sqlite:////var/lib/myapp/database.sqlite". Don't use a relative path (three slashes) because the current directory could be anything. The example has three slashes because the value of "%(here)s" always starts with a slash (or the platform equivalent; e.g., "C:\\foo" on Windows). For MySQL ^^^^^^^^^ .. code-block:: ini sqlalchemy.url = mysql://username:password@host:port/database sqlalchemy.pool_recycle = 3600 Enter your username, password, host (localhost if it is on your machine), port number (usually 3306) and the name of your database. The second line is an example of setting `engine options `_. It's important to set "pool_recycle" for MySQL to prevent "MySQL server has gone away" errors. This is because MySQL automatically closes idle database connections without informing the application. Setting the connection lifetime to 3600 seconds (1 hour) ensures that the connections will be expired and recreated before MySQL notices they're idle. Don't be tempted to use the ".echo" option to enable SQL logging because it may cause duplicate log output. Instead see the `Logging`_ section below to integrate MySQL logging into Paste's logging system. For PostgreSQL ^^^^^^^^^^^^^^ .. code-block:: ini sqlalchemy.url = postgres://username:password@host:port/database Enter your username, password, host (localhost if it is on your machine), port number (usually 5432) and the name of your database. Organizing ========== When you answer "yes" to the SQLAlchemy question when creating a Pylons project, it configures a simple default model. The model consists of two files: :file:`model/__init__.py` and :file:`model/meta.py`. :file:`model/__init__.py` ------------------------- The file :file:`model/__init__.py` contains the table definitions, the ORM classes and an :func:`init_model` function. This :func:`init_model` function must be called at application startup. In the Pylons default project template this call is made in the :func:`load_environment` function (in the file :file:`config/environment.py`). :file:`model/meta.py` --------------------- :file:`model/meta.py` is merely a container for a few housekeeping objects required by SQLAlchemy such as :class:`Session`, ``metadata`` and ``engine`` to avoid import issues. In the context of the default Pylons application, only the :class:`Session` object is instantiated. The objects are optional in the context of other applications that do not make use of them and so if you answer "no" to the SQLAlchemy question when creating a Pylons project, the creation of :file:`model/meta.py` is simply skipped. It is recommended that, for each model, a new module inside the ``model/`` directory should be created. This keeps the models tidy when they get larger as more domain specific code is added to each one. Creating a Model ================ SQLAlchemy 0.5 has an optional `Declarative` syntax which offers the convenience of defining the table and the ORM class in one step. This is the recommended usage of SQLAlchemy. Create a :file:`model/person.py` module:: """Person model""" from sqlalchemy import Column from sqlalchemy.types import Integer, String from myapp.model.meta import Base class Person(Base): __tablename__ = "person" id = Column(Integer, primary_key=True) name = Column(String(100)) email = Column(String(100)) def __init__(self, name='', email=''): self.name = name self.email = email def __repr__(self): return "`_ and `SQLAlchemy manual`_ Creating the Database ===================== To actually create the tables in the database, you call the metadata's `.create_all()` method. You can do this interactively or use `paster`'s application initialization feature. To do this, put the code in :file:`myapp/websetup.py`. After the `load_environment()` call, put: .. code-block:: python from myapp.model.meta import Base, Session log.info("Creating tables") Base.metadata.drop_all(checkfirst=True, bind=Session.bind) Base.metadata.create_all(bind=Session.bind) log.info("Successfully setup") Then run the following on the command line: .. code-block:: bash $ paster setup-app development.ini A brief guide to using model objects in the Controller ====================================================== In which we: query a model, update a model entity, create a model entity and delete several model entities, all inside a Pylons controller. To illustrate some typical ways of handling model objects in the Controller, we will draw from the example :class:`PagesController` code of the :ref:`QuickWiki Tutorial`. The :class:`Session` -------------------- The SQLAlchemy-provided :class:`Session` object is a crucially important facet when working with models and model object entities. The SQLAlchemy documentation describes the :class:`Session` thus: "In the most general sense, the Session establishes all conversations with the database and represents a "holding zone" for all the mapped instances which you’ve loaded or created during its lifespan." All of the model access that takes place in a Pylons controller is done in the context of a :class:`Session` providing a database connection reference that is created at the start of the processing of each request and destroyed at the end of the processing of the request. These creation and destruction operations are performed automatically by the :class:`BaseController` instantiated in :file:`MYAPP/lib/base.py` which is in turn subclassed for each standard Pylons controller, ensuring that subclassed controllers can access the database only in a request-specific context which, in turn, protects against data accidentally leaking across requests. .. seeAlso:: SQLAlchemy documentation for the `Session object `_ The net effect of this is that a fully-instantiated :class:`Session` object is available for import and immediate use in the controller for, e.g. querying the model. Querying the model ------------------ The :class:`Session` object provides a :func:`query` function that, when applied to a class of mapped model object, returns a SQLAlchemy :class:`Query` object that can be passed around and repeatedly consulted. .. seealso:: SQLAlchemy documentation for the `Query object `_ Standard usage is illustrated in this code for the :func:`__before__` function of the QuickWiki :class:`PagesController` in which ``self.page_q`` is bound to the :class:`Query` object returned by ``Session.query(Page)`` - where :class:`Page` is the class of mapped model object that will be the subject of the queries. .. code-block:: python from MYAPP.lib.base import Session from MYAPP.model import Page class PagesController(BaseController): def __before__(self): self.page_q = Session.query(Page) # [ ... ] The :class:`Query` object that is bound to ``self.page_q`` is now specialised to perform queries of the :class:`Page` declarative base entity / mapped model entity. .. seeAlso:: SQLAlchemy documentation for the `Querying the database `_ Here, in the context of a controller's :func:`index` action, it is used in a very straighforward manner - :func:`self.page_q.all` - to fuel a list comprehension that returns a list containing the ``title`` of every :class:`Page` object in the database: .. code-block:: python def index(self): c.titles = [page.title for page in self.page_q.all()] return render('/pages/index.mako') and ``self.page_q`` is used in similarly direct manner for the :func:`show` action that retrieves a Page with a given value of ``title`` and then calls the Page's :func:`get_wiki_content` class method. .. code-block:: python def show(self, title): page = self.page_q.filter_by(title=title).first() if page: c.content = page.get_wiki_content() return render('/pages/show.mako') elif wikiwords.match(title): return render('/pages/new.mako') abort(404) .. note:: the ``title`` argument to the function is bound when the request is dispatched by the Routes map, typically of the form: .. code-block:: python map.connect('show_page', '/page/show/{title}', controller='page', action='show') The :class:`Query` object has many other features, including filtering on conditions, ordering the results, grouping, etc. These are excellently described in the `SQLAlchemy manual`_. See especially the `Data Mapping `_ and `Session / Unit of Work `_ chapters. Creating, updating and deleting model entities ---------------------------------------------- When performing operations that change the state of the database, the recommended approach is for Pylons users to take full advantage of the abstraction provided by the SQLAlchemy ORM and simply treat the retrieved or created model entities as Python objects, make changes to them in a conventional Pythonic way, add them to or delete them from the :class:`Session` "holding zone" and call :func:`Session.commit` to commit the changes to the database. The three examples shown below are condensed illustrations of how these operations are typically performed in controller actions. Creating a model entity ^^^^^^^^^^^^^^^^^^^^^^^ SQLAlchemy's Declarative Base syntax allows model entity classes to act as constructors, accepting keyworded args and values. In this example, a new Page is created with the given title, the created model entity object is then added to the :class:`Session` and then the change is committed. .. code-block:: python def create(self, title): page = Page(title=title) Session.add(page) Session.commit() redirect_to('show_page', title=title) Updating a model entity ^^^^^^^^^^^^^^^^^^^^^^^ Perhaps the most straighforward use - a model entity object is retrieved from the database, a field value is updated and the change committed. (Note, this example is considerably abbreviated as a controller action - preliminary content checking has been omitted, as has exception handling for the database query.) .. code-block:: python def save(self, title): page = self.page_q.filter_by(title=title).first() page.content=escape(request.POST.getone('content')) Session.commit() redirect_to('show_page', title=title) Deleting a model entity ^^^^^^^^^^^^^^^^^^^^^^^ This example of shows the freedom that the Pylons user has to make repeated changes to the model (in this instance, repeatedly deleting entities from the database) before finally committing those changes by calling :func:`Session.commit`. .. code-block:: python def delete(self): titles = request.POST.getall('title') pages = self.page_q.filter(Page.title.in_(titles)) for page in pages: Session.delete(page) Session.commit() redirect_to('pages') The `Object Relational tutorial `_ in the SQLAlchemy documentation covers a basic SQLAlchemy object-relational mapping scenario in much more detail and the `SQL Expression tutorial `_ covers the details of manipulating and marshalling the model entity objects. Using multiple databases ------------------------ In order to use multiple databases, in :file:`MYAPP/model/meta.py` create as many instances of :class:`Base` as there are databases to connect to: .. code-block:: python """SQLAlchemy Metadata and Session object""" from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import scoped_session, sessionmaker __all__ = ['Base','Base2', 'Session'] # SQLAlchemy session manager. Updated by model.init_model() Session = scoped_session(sessionmaker()) # The declarative Base Base = declarative_base() Base2 = declarative_base() Declare the different database URLs in :file:`development.ini`, appending an integer to the ``sqlalchemy`` keyword in order to differentiate between them. .. code-block:: ini sqlalchemy.url = sqlite:///%(here)s/database_one.sqlite sqlalchemy.echo = true sqlalchemy2.url = sqlite:///%(here)s/database_two.sqlite sqlalchemy2.echo = false In :file:`MYAPP/config/environment.py`, pick up those db URL declarations by using the different keywords (in this example: `sqlalchemy` and `sqlalchemy2`). Create the engines and call :func:`model.init_model`, passing through both engines as parameters. .. code-block:: python # Setup the SQLAlchemy database engine # Engine 0 engine = engine_from_config(config, 'sqlalchemy.') engine2 = engine_from_config(config, 'sqlalchemy2.') model.init_model(engine, engine2) Bind the engines appropriately to the :class:`Base`-specific metadata in :file:`MYAPP/model/\_\_init\_\_.py` - note :func:`init_model` is expecting both engines to be supplied as formal parameters. .. code-block:: python def init_model(engine, engine2): meta.Base.metadata.bind = engine meta.Base2.metadata.bind = engine2 Then import :class:`Base` and/or :class:`Base2` .. code-block:: python from MYAPP.model.meta import Base, Base2 and use as required, e.g. .. code-block:: python class Author(Base2): __tablename__ = 'authors' id = Column(Integer, primary_key=True) keywords = relation("Keyword", secondary=keywords) Avoiding the "circular imports" problem of model interdependency ---------------------------------------------------------------- Closely-interdependent models can sometimes cause "circular import" problems, where importing one model file causes a dependent model file to be imported, which then cause the first model file to be imported, and so on round and round in circles. In order to break the circle, define the model entities as globals in :file:`MYAPP/model/meta.py` .. code-block:: python """The application's model objects""" import sqlalchemy as sa from MYAPP.model import meta from sqlalchemy.orm import scoped_session, sessionmaker def init_model(engine): """Call me before using any of the tables or classes in the model""" meta.Base.metadata.bind = engine import MYAPP.model.user User = MYAPP.model.user.User global User import MYAPP.model.newsletter Newsletter = MYAPP.model.newsletter.Newsletter global Newsletter import MYAPP.model.submission Submission = MYAPP.model.submission.Submission global Submission Testing the Models ------------------ Normal model usage works fine in model tests, however to use the metadata you must specify an engine connection for it. To have your tables created for every unit test in your project, use a :file:`test_models.py` such as: .. code-block:: python from myapp.tests import * from myapp import model from myapp.model import meta class TestModels(TestController): def setUp(self): meta.Session.remove() meta.Base.metadata.create_all(meta.engine) def test_index(self): # test your models pass .. note:: Notice that the tests inherit from TestController. This is to ensure that the application is setup so that the models will work. "nosetests --with-pylons=/path/to/test.ini ..." is another way to ensure that your model is properly initialized before the tests are run. This can be used when running non-controller tests. Logging ======= SQLAlchemy has several loggers that chat about the various aspects of its operation. To log all SQL statements executed along with their parameter values, put the following in :file:`development.ini`: .. code-block:: ini [logger_sqlalchemy] level = INFO handlers = qualname = sqlalchemy.engine Then modify the "[loggers]" section to enable your new logger: .. code-block:: ini [loggers] keys = root, myapp, sqlalchemy To log the results along with the SQL statements, set the level to DEBUG. This can cause a lot of output! To stop logging the SQL, set the level to WARN or ERROR. SQLAlchemy has several other loggers you can configure in the same way. "sqlalchemy.pool" level INFO tells when connections are checked out from the engine's connection pool and when they're returned. "sqlalchemy.orm" and buddies log various ORM operations. See "Configuring Logging" in the `SQLAlchemy manual`_. About SQLAlchemy ================ `SQLAlchemy `_ is by far the most common approach for Pylons databases. It provides a connection pool, a SQL statement builder, an object-relational mapper (ORM), and transaction support. SQLAlchemy works with several database engines (MySQL, PostgreSQL, SQLite, Oracle, Firebird, MS-SQL, Access via ODBC, etc) and understands the peculiar SQL dialect of each, making it possible to port a program from one engine to another by simply changing the connection string. Although its API is still changing gradually, SQLAlchemy is well tested, widely deployed, has excellent documentation, and its mailing list is quick with answers. SQLAlchemy lets you work at three different levels, and you can even use multiple levels in the same program: * The object-relational mapper (ORM) lets you interact with the database using your own object classes rather than writing SQL code. * The SQL expression language has many methods to create customized SQL statements, and the result cursor is more friendly than DBAPI's. * The low-level execute methods accept literal SQL strings if you find something the SQL builder can't do, such as adding a column to an existing table or modifying the column's type. If they return results, you still get the benefit of SQLAlchemy's result cursor. The first two levels are *database neutral*, meaning they hide the differences between the databases' SQL dialects. Changing to a different database is merely a matter of supplying a new connection URL. Of course there are limits to this, but SQLAlchemy is 90% easier than rewriting all your SQL queries. The `SQLAlchemy manual`_ should be your next stop for questions not covered here. It's very well written and thorough. SQLAlchemy add-ons ------------------ Most of these provide a higher-level ORM, either by combining the table definition and ORM class definition into one step, or supporting an "active record" style of access. *Please take the time to learn how to do things "the regular way" before using these shortcuts in a production application*. Understanding what these add-ons do behind the scenes will help if you have to troubleshoot a database error or work around a limitation in the add-on later. `SQLSoup `_, an extension to SQLAlchemy, provides a quick way to generate ORM classes based on existing database tables. If you're familiar with ActiveRecord, used in Ruby on Rails, then you may want to use the `Elixir `_ layer on top of SQLAlchemy. This approach is less common since the introduction of the declarative extension, but has other features the declarative does not. .. _`SQLAlchemy manual`: http://www.sqlalchemy.org/docs/ Pylons-1.0.1/pylons/docs/en/modules/0000775000076500000240000000000012012307216017206 5ustar benstaff00000000000000Pylons-1.0.1/pylons/docs/en/modules/commands.rst0000664000076500000240000000040711645401275021555 0ustar benstaff00000000000000:mod:`pylons.commands` -- Command line functions ================================================ .. automodule:: pylons.commands Module Contents --------------- .. autoclass:: ControllerCommand .. autoclass:: RestControllerCommand .. autoclass:: ShellCommand Pylons-1.0.1/pylons/docs/en/modules/configuration.rst0000664000076500000240000000041111645401275022616 0ustar benstaff00000000000000:mod:`pylons.configuration` -- Configuration object and defaults setup ====================================================================== .. automodule:: pylons.configuration Module Contents --------------- .. autoclass:: PylonsConfig :members: init_app Pylons-1.0.1/pylons/docs/en/modules/controllers.rst0000664000076500000240000000042311645401275022320 0ustar benstaff00000000000000:mod:`pylons.controllers` -- Controllers ======================================== .. module:: pylons.controllers This module makes available the :class:`~pylons.controllers.core.WSGIController` and :class:`~pylons.controllers.xmlrpc.XMLRPCController` for easier importing. Pylons-1.0.1/pylons/docs/en/modules/controllers_core.rst0000664000076500000240000000045611645401275023336 0ustar benstaff00000000000000:mod:`pylons.controllers.core` -- WSGIController Class ====================================================== .. automodule:: pylons.controllers.core Module Contents --------------- .. autoclass:: WSGIController :members: _perform_call, _inspect_call, _get_method_args, _dispatch_call, __call__ Pylons-1.0.1/pylons/docs/en/modules/controllers_util.rst0000664000076500000240000000073411645401275023362 0ustar benstaff00000000000000:mod:`pylons.controllers.util` -- Controller Utility functions ====================================================================== .. automodule:: pylons.controllers.util Module Contents --------------- .. autoclass:: Request :members: :undoc-members: :show-inheritance: .. autoclass:: Response :members: :undoc-members: :show-inheritance: .. autofunction:: abort .. autofunction:: etag_cache .. autofunction:: forward .. autofunction:: redirect Pylons-1.0.1/pylons/docs/en/modules/controllers_xmlrpc.rst0000664000076500000240000000047111645401275023710 0ustar benstaff00000000000000:mod:`pylons.controllers.xmlrpc` -- XMLRPCController Class ========================================================== .. automodule:: pylons.controllers.xmlrpc Module Contents --------------- .. autoclass:: XMLRPCController :members: __call__, system_listMethods, system_methodSignature, system_methodHelp Pylons-1.0.1/pylons/docs/en/modules/decorators.rst0000664000076500000240000000031011645401275022112 0ustar benstaff00000000000000:mod:`pylons.decorators` -- Decorators ====================================== .. automodule:: pylons.decorators Module Contents --------------- .. autofunction:: jsonify .. autofunction:: validate Pylons-1.0.1/pylons/docs/en/modules/decorators_cache.rst0000664000076500000240000000034411645401275023244 0ustar benstaff00000000000000:mod:`pylons.decorators.cache` -- Cache Decorators ====================================================================== .. automodule:: pylons.decorators.cache Module Contents --------------- .. autofunction:: beaker_cache Pylons-1.0.1/pylons/docs/en/modules/decorators_rest.rst0000664000076500000240000000035511645401275023160 0ustar benstaff00000000000000:mod:`pylons.decorators.rest` -- REST-ful Decorators ==================================================== .. automodule:: pylons.decorators.rest Module Contents --------------- .. autofunction:: dispatch_on .. autofunction:: restrict Pylons-1.0.1/pylons/docs/en/modules/decorators_secure.rst0000664000076500000240000000036211645401275023467 0ustar benstaff00000000000000:mod:`pylons.decorators.secure` -- Secure Decorators ==================================================== .. automodule:: pylons.decorators.secure Module Contents --------------- .. autofunction:: authenticate_form .. autofunction:: https Pylons-1.0.1/pylons/docs/en/modules/error.rst0000664000076500000240000000017211645401275021104 0ustar benstaff00000000000000:mod:`pylons.error` -- Error handling support ============================================= .. automodule:: pylons.error Pylons-1.0.1/pylons/docs/en/modules/i18n_translation.rst0000664000076500000240000000101111645401275023141 0ustar benstaff00000000000000:mod:`pylons.i18n.translation` -- Translation/Localization functions ==================================================================== .. automodule:: pylons.i18n.translation Module Contents --------------- .. autoexception:: LanguageError .. autoclass:: LazyString .. autofunction:: lazify .. autofunction:: gettext_noop .. autofunction:: gettext .. autofunction:: ugettext .. autofunction:: ngettext .. autofunction:: ungettext .. autofunction:: set_lang .. autofunction:: get_lang .. autofunction:: add_fallback Pylons-1.0.1/pylons/docs/en/modules/index.rst0000664000076500000240000000055211645401275021064 0ustar benstaff00000000000000.. _modules: ============== Pylons Modules ============== .. toctree:: :maxdepth: 2 commands configuration controllers controllers_core controllers_util controllers_xmlrpc decorators decorators_cache decorators_rest decorators_secure error i18n_translation log middleware templating test util wsgiapp Pylons-1.0.1/pylons/docs/en/modules/log.rst0000664000076500000240000000030711645401275020534 0ustar benstaff00000000000000:mod:`pylons.log` -- Logging for WSGI errors ============================================ .. automodule:: pylons.log Module Contents --------------- .. autoclass:: WSGIErrorsHandler :members: Pylons-1.0.1/pylons/docs/en/modules/middleware.rst0000664000076500000240000000240611645401275022072 0ustar benstaff00000000000000:mod:`pylons.middleware` -- WSGI Middleware =========================================== .. automodule:: pylons.middleware Module Contents --------------- .. autoclass:: StatusCodeRedirect :members: __init__ .. autoclass:: StaticJavascripts .. autofunction:: ErrorHandler .. note:: The :data:`errorware` dictionary is constructed from the settings in the `DEFAULT` section of development.ini. the recognised keys and settings at initialization are: * :data:`error_email` = conf.get('email_to') * :data:`error_log` = conf.get('error_log', None) * :data:`smtp_server` = conf.get('smtp_server','localhost') * :data:`error_subject_prefix` = conf.get('error_subject_prefix', 'WebApp Error: ') * :data:`from_address` = conf.get('from_address', conf.get('error_email_from', 'pylons@yourapp.com')) * :data:`error_message` = conf.get('error_message', 'An internal server error occurred') Referenced classes ------------------ Pylons middleware uses :class:`WebError` to effect the error-handling. The two classes implicated are: ErrorMiddleware ^^^^^^^^^^^^^^^ :mod:`weberror.errormiddleware` :class:`weberror.errormiddleware.ErrorMiddleware` EvalException ^^^^^^^^^^^^^ :mod:`weberror.evalexception` :class:`weberror.evalexception.EvalException` Pylons-1.0.1/pylons/docs/en/modules/templating.rst0000664000076500000240000000053211645401275022117 0ustar benstaff00000000000000:mod:`pylons.templating` -- Render functions and helpers ======================================================== .. automodule:: pylons.templating Module Contents --------------- .. autofunction:: pylons_globals .. autofunction:: cached_template .. autofunction:: render_mako .. autofunction:: render_mako_def .. autofunction:: render_genshi Pylons-1.0.1/pylons/docs/en/modules/test.rst0000664000076500000240000000027511645401275020736 0ustar benstaff00000000000000:mod:`pylons.test` -- Test related functionality ================================================ .. automodule:: pylons.test Module Contents --------------- .. autoclass:: PylonsPlugin Pylons-1.0.1/pylons/docs/en/modules/util.rst0000664000076500000240000000043611645401275020733 0ustar benstaff00000000000000:mod:`pylons.util` -- Paste Template and Pylons utility functions ================================================================= .. automodule:: pylons.util Module Contents --------------- .. autoclass:: PylonsContext .. autoclass:: ContextObj .. autoclass:: AttribSafeContextObj Pylons-1.0.1/pylons/docs/en/modules/wsgiapp.rst0000664000076500000240000000036511645401275021431 0ustar benstaff00000000000000:mod:`pylons.wsgiapp` -- PylonsWSGI App Creator =============================================== .. automodule:: pylons.wsgiapp Module Contents --------------- .. autoclass:: PylonsApp :members: .. automethod:: PylonsApp.__call__ Pylons-1.0.1/pylons/docs/en/objects.inv0000664000076500000240000000000011645401275017706 0ustar benstaff00000000000000Pylons-1.0.1/pylons/docs/en/python23_install.rst0000664000076500000240000000362711645401275021527 0ustar benstaff00000000000000.. _python23_installation: ==================================== Python 2.3 Installation Instructions ==================================== Advice of **end of support for Python 2.3** ------------------------------------------- .. warning:: **END OF SUPPORT FOR PYTHON 2.3** This is the **LAST** version to support Python 2.3 **BEGIN UPGRADING OR DIE** Preparation ----------- First, please note that Python 2.3 users on Windows will need to install `subprocess.exe`__ before beginning the installation (whereas Python 2.4 users on Windows do not). All windows users also should read the section :ref:`windows_notes` after installation. Users of Ubuntu/debian will also likely need to install the python-dev package. System-wide Install ------------------- To install Pylons so it can be used by everyone (you'll need root access). If you already have easy install: .. code-block:: bash $ easy_install Pylons==0.9.7 .. note:: On rare occasions, the python.org Cheeseshop goes down. It is still possible to install Pylons and its dependencies however by specifying our local package directory for installation with: .. code-block:: bash $ easy_install -f http://pylonshq.com/download/ Pylons==0.9.7 Which will use the packages necessary for the latest release. If you're using an older version of Pylons, you can get the packages that went with it by specifying the version desired: .. code-block:: bash $ easy_install -f http://pylonshq.com/download/0.9.7/ Pylons==0.9.7 Otherwise: #. Download the easy install setup file from http://peak.telecommunity.com/dist/ez_setup.py #. Run: .. code-block:: bash $ python ez_setup.py Pylons==0.9.7 .. __: http://www.pylonshq.com/download/subprocess-0.1-20041012.win32-py2.3.exe .. warning:: **END OF SUPPORT FOR PYTHON 2.3** This is the **LAST** version to support Python 2.3 **BEGIN UPGRADING OR DIE** Pylons-1.0.1/pylons/docs/en/security_policy_for_bugs.rst0000664000076500000240000000556611645401275023433 0ustar benstaff00000000000000.. _security_policy_for_bugs: ======================== Security policy for bugs ======================== Receiving Security Updates ========================== The Pylons team have set up a mailing list at wsgi-security-announce@googlegroups.com to which any security vulnerabilities that affect Pylons will be announced. Anyone wishing to be notified of vulnerabilities in Pylons should subscribe to this list. Security announcements will only be made once a solution to the problem has been discovered. Reporting Security Issues ========================= Please report security issues by email to both the lead developers of Pylons at the following addresses: ben\ |at|\ groovie.org security\ |at|\ 3aims.com Please DO NOT announce the vulnerability to any mailing lists or on the ticket system because we would not want any malicious person to be aware of the problem before a solution is available. In the event of a confirmed vulnerability in Pylons itself, we will take the following actions: * Acknowledge to the reporter that we've received the report and that a fix is forthcoming. We'll give a rough timeline and ask the reporter to keep the issue confidential until we announce it. * Halt all other development as long as is needed to develop a fix, including patches against the current release. * Publicly announce the vulnerability and the fix as soon as it is available to the WSGI security list at wsgi-security-announce@googlegroups.com. This will probably mean a new release of Pylons, but in some cases it may simply be the release of documentation explaining how to avoid the vulnerability. In the event of a confirmed vulnerability in one of the components that Pylons uses, we will take the following actions: * Acknowledge to the reporter that we've received the report and ask the reporter to keep the issue confidential until we announce it. * Contact the developer or maintainer of the package containing the vulnerability. * If the developer or maintainer fails to release a new version in a reasonable time-scale and the vulnerability is serious we will either create documentation explaining how to avoid the problem or as a last resort, create a patched version. * Publicly announce the vulnerability and the fix as soon as it is available to the WSGI security list at wsgi-security-announce@googlegroups.com. Minimising Risk =============== * Only use official production versions of Pylons released publicly on the `Python Package Index `_. * Only use stable releases of third party software not development, alpha, beta or release candidate code. * Do not assume that related software is of the same quality as Pylons itself, even if Pylons users frequently make use of it. * Subscribe to the wsgi-security-announce@googlegroups.com mailing list to be informed of security issues and their solutions. .. |at| image:: _static/at.png Pylons-1.0.1/pylons/docs/en/sessions.rst0000664000076500000240000002423511645401275020157 0ustar benstaff00000000000000.. _sessions: ======== Sessions ======== Sessions ======== Pylons includes a session object: a session is a server-side, semi-permanent storage for data associated with a client. The session object is provided by the `Beaker library`_ which also provides caching functionality as described in :ref:`caching`. The Session Object ================== The Pylons session object is available at :data:`pylons.session`. Controller modules created via :command:`paster controller/restcontroller` import the session object by default. The basic session API is simple, it implements a dict-like interface with a few additional methods. The following is an example of using the session to store a token identifying if a client is logged in. .. code-block :: python class LoginController(BaseController): def authenicate(self): name = request.POST['name'] password = request.POST['password'] user = Session.query(User).filter_by(name=name, password=password).first() if user: msg = 'Successfully logged in as %s' % name location = url('index') session['logged_in'] = True session.save() else: msg = 'Invalid username/password' location = url('login') flash(msg) redirect(location) def logout(self): # Clear all values in the session associated with the client session.clear() session.save() Subsequent requests can then determine if a client is logged in or not by checking the session: .. code-block :: python if not session.get('logged_in'): flash('Please login') redirect(url('login')) The session object acts lazily: it does not load the session data (from disk or whichever backend is used) until the data is first accessed. This lazyness is facilitated via an intermediary :class:`beaker.session.SessionObject` that wraps the actual :class:`beaker.session.Session` object. Furthermore the session will not write changes to its backend without an explicit call to its :meth:`beaker.session.Session.save` method (unless configured with the ``auto`` option). Session data is generally serialized for storage via the Python :mod:`pickle` module, so anything stored in the session must be pickleable. The lightweight SessionObject wrapper is created by the: :class:`beaker.middleware.SessionMiddleware` WSGI middleware. SessionMiddleware stores the wrapper in the WSGI environ where Pylons sets a reference to it from pylons.session. Sessions are associated with a client via a client-side cookie. The WSGI middleware is also responsible for sending said cookie to the client. Configuring the Session ======================= The basic session defaults are: * File based sessions (session data is stored on disk) * Session cookies have no expiration date (cookies expire at the end of the browser session) * Session cookie domain/path matches the current host/path Pylons projects by default sets the following couple of session options via their .ini files. All Beaker specific session options in the ini file are prefixed with `beaker.session`: .. code-block :: ini cache_dir = %(here)s/data beaker.session.key = foo beaker.session.secret = somesecret ``cache_dir`` acts a base directory for both session and cache storage. Session data is stored in this location under a :file:`sessions/` sub-directory. ``session.key`` is the name attribute of the cookie sent to the browser. This defaults to your project's name. ``session.secret`` is the secret token used to hash the cookie data sent to the client. This should be a secret, ideally randomly generated value on production environments. :command:`paster make-config` will generate a random secret for you when creating a production ini file. Other Session Options --------------------- Some other commonly used session options are: * ``type`` The type of the back-end for storing session data. Beaker supports many different backends, see `Beaker Configuration Documentation`_ for the choices. Defaults to 'file'. * ``cookie_domain`` The domain name to use for the session Cookie. For example, when using sub-domains, set this to the parent domain name so that the cookie is valid for all sub-domains. To enable pure `Cookie-based Sessions`_ and force the cookie domain to be valid for all sub-domains of 'example.com', add the following to your Pylons ini file: .. code-block :: ini beaker.session.type = cookie beaker.session.cookie_domain = .example.com See the `Beaker Configuration Documentation`_ for an exhaustive list of Session options. Storing SQLAlchemy mapped objects in Beaker sessions ==================================================== Mapped objects from SQLAlchemy can be serialized into the beaker session, but care must be taken when retrieving these objects back from the beaker session. They will not be associated with the SQLAlchemy Unit-of-Work Session, however these objects can be reconciled via the SQLAlchemy Session's ``merge`` method, as follows: .. code-block:: python address = DBSession.query(Address).get(id) session[id] = address ... address = session.get(id) address = DBSession.merge(address) Custom and caching middleware ============================= Care should be taken when deciding in which layer to place custom middleware. In most cases middleware should be placed between the Pylons WSGI application instantiation and the Routes middleware; however, if the middleware should run *before* the session object or routing is handled: .. code-block:: python # Routing/Session Middleware app = RoutesMiddleware(app, config['routes.map']) app = SessionMiddleware(app, config) # MyMiddleware can only see the cache object, nothing *above* here app = MyMiddleware(app) app = CacheMiddleware(app, config) Some of the Pylons middleware layers such as the ``Session``, ``Routes``, and ``Cache`` middleware, only add objects to the `environ` dict, or add HTTP headers to the response (the Session middleware for example adds the session cookie header). Others, such as the ``Status Code Redirect``, and the ``Error Handler`` may fully intercept the request entirely, and change how its responded to. Using `Session` in Internationalization ======================================= How to set the language used in a controller on the fly. For example this could be used to allow a user to set which language they wanted your application to work in. Save the value to the session object: .. code-block:: python session['lang'] = 'en' session.save() then on each controller call the language to be used could be read from the session and set in the controller's ``__before__()`` method so that the pages remained in the same language that was previously set: .. code-block:: python def __before__(self): if 'lang' in session: set_lang(session['lang']) Using `Session` in Secure Forms =============================== Authorization tokens are stored in the client's session. The web app can then verify the request's submitted authorization token with the value in the client's session. This ensures the request came from the originating page. See the wikipedia entry for `Cross-site request forgery`__ for more information. .. __: http://en.wikipedia.org/wiki/Cross-site_request_forgery Pylons provides an ``authenticate_form`` decorator that does this verification on the behalf of controllers. These helpers depend on Pylons' ``session`` object. Most of them can be easily ported to another framework by changing the API calls. Hacking the session for no cookies ================================== (From a `paste #441 `_ baked by Ben Bangert) Set the session to not use cookies in the dev.ini file .. code-block:: ini beaker.session.use_cookies = False with this as the *mode d'emploi* in the controller action .. code-block:: python from beaker.session import Session as BeakerSession # Get the actual session object through the global proxy real_session = session._get_current_obj() # Duplicate the session init options to avoid screwing up other sessions in # other threads params = real_session.__dict__['_params'] # Now set the id param used to make a session to our session maker, # if id is None, a new id will be made automatically params['id'] = find_id_func() real_session.__dict__['_sess'] = BeakerSession({}, **params) # Now we can use the session as usual session['fred'] = 42 session.save() # At the end, we need to see if the session was used and handle its id if session.is_new: # do something with session.id to make sure its around next time pass Using middleware (Beaker) with a composite app ============================================== How to allow called WSGI apps to share a common session management utility. (From a `paste #616 `_ baked by Mark Luffel) .. code-block:: ini # Here's an example of configuring multiple apps to use a common # middleware filter # The [app:home] section is a standard pylons app # The ``/servicebroker`` and ``/proxy`` apps both want to be able # to use the same session management [server:main] use = egg:Paste#http host = 0.0.0.0 port = 5000 [filter-app:main] use = egg:Beaker#beaker_session next = sessioned beaker.session.key = my_project_key beaker.session.secret = i_wear_two_layers_of_socks [composite:sessioned] use = egg:Paste#urlmap / = home /servicebroker = servicebroker /proxy = cross_domain_proxy [app:servicebroker] use = egg:Appcelerator#service_broker [app:cross_domain_proxy] use = egg:Appcelerator#cross_domain_proxy [app:home] use = egg:my_project full_stack = true cache_dir = %(here)s/data .. _`Beaker library`: http://beaker.groovie.org .. _`Beaker Configuration Documentation`: http://beaker.groovie.org/configuration.html#session-options .. _`Cookie-based Sessions`: http://beaker.groovie.org/sessions.html#cookie-based Pylons-1.0.1/pylons/docs/en/testing.rst0000664000076500000240000002446711645401275017775 0ustar benstaff00000000000000.. _testing: =========================== Unit and functional testing =========================== Unit Testing with :mod:`webtest` ================================ Pylons provides powerful unit testing capabilities for your web application utilizing `webtest `_ to emulate requests to your web application. You can then ensure that the response was handled appropriately and that the controller set things up properly. To run the test suite for your web application, Pylons utilizes the `nose `_ test runner/discovery package. Running ``nosetests`` in your project directory will run all the tests you create in the tests directory. If you don't have nose installed on your system, it can be installed via setuptools with: .. code-block:: bash $ easy_install -U nose To avoid conflicts with your development setup, the tests use the `test.ini` configuration file when run. This means **you must configure any databases, etc. in your test.ini file or your tests will not be able to find the database configuration**. .. warning:: Nose can trigger errors during its attempt to search for doc tests since it will try and import all your modules one at a time *before* your app was loaded. This will cause files under models/ that rely on your app to be running, to fail. Pylons 0.9.6.1 and later includes a plugin for nose that loads the app before the doctests scan your modules, allowing models to be doctested. You can use this option from the command line with nose: .. code-block:: bash nosetests --with-pylons=test.ini Or by setting up a `[nosetests]` block in your setup.cfg: .. code-block:: ini [nosetests] verbose=True verbosity=2 with-pylons=test.ini detailed-errors=1 with-doctest=True Then just run: .. code-block:: bash python setup.py nosetests to run the tests. Example: Testing a Controller ============================= First let's create a new project and controller for this example: .. code-block:: bash $ paster create -t pylons TestExample $ cd TestExample $ paster controller comments You'll see that it creates two files when you create a controller. The stub controller, and a test for it under ``testexample/tests/functional/``. Modify the ``testexample/controllers/comments.py`` file so it looks like this: .. code-block:: python from testexample.lib.base import * class CommentsController(BaseController): def index(self): return 'Basic output' def sess(self): session['name'] = 'Joe Smith' session.save() return 'Saved a session' Then write a basic set of tests to ensure that the controller actions are functioning properly, modify ``testexample/tests/functional/test_comments.py`` to match the following: .. code-block:: python from testexample.tests import * class TestCommentsController(TestController): def test_index(self): response = self.app.get(url(controller='/comments')) assert 'Basic output' in response def test_sess(self): response = self.app.get(url(controller='/comments', action='sess')) assert response.session['name'] == 'Joe Smith' assert 'Saved a session' in response Run ``nosetests`` in your main project directory and you should see them all pass: .. code-block:: pycon .. ---------------------------------------------------------------------- Ran 2 tests in 2.999s OK Unfortunately, a plain assert does not provide detailed information about the results of an assertion should it fail, unless you specify it a second argument. For example, add the following test to the ``test_sess`` function: .. code-block:: python assert response.session.has_key('address') == True When you run ``nosetests`` you will get the following, not-very-helpful result: .. code-block:: pycon .F ====================================================================== FAIL: test_sess (testexample.tests.functional.test_comments.TestCommentsController) ---------------------------------------------------------------------- Traceback (most recent call last): File "~/TestExample/testexample/tests/functional/test_comments.py", line 12, in test_sess assert response.session.has_key('address') == True AssertionError: ---------------------------------------------------------------------- Ran 2 tests in 1.417s FAILED (failures=1) You can augment this result by doing the following: .. code-block:: python assert response.session.has_key('address') == True, "address not found in session" Which results in: .. code-block:: pycon .F ====================================================================== FAIL: test_sess (testexample.tests.functional.test_comments.TestCommentsController) ---------------------------------------------------------------------- Traceback (most recent call last): File "~/TestExample/testexample/tests/functional/test_comments.py", line 12, in test_sess assert response.session.has_key('address') == True AssertionError: address not found in session ---------------------------------------------------------------------- Ran 2 tests in 1.417s FAILED (failures=1) But detailing every assert statement could be time consuming. Our TestController subclasses the standard Python ``unittest.TestCase`` class, so we can use utilize its helper methods, such as ``assertEqual``, that can automatically provide a more detailed AssertionError. The new test line looks like this: .. code-block:: python self.assertEqual(response.session.has_key('address'), True) Which provides the more useful failure message: .. code-block:: pycon .F ====================================================================== FAIL: test_sess (testexample.tests.functional.test_comments.TestCommentsController) ---------------------------------------------------------------------- Traceback (most recent call last): File "~/TestExample/testexample/tests/functional/test_comments.py", line 12, in test_sess self.assertEqual(response.session.has_key('address'), True) AssertionError: False != True Testing Pylons Objects ====================== Pylons will provide several additional attributes for the :mod:`webtest` :class:`webtest.TestResponse` object that let you access various objects that were created during the web request: ``config`` The configured Pylons applications. ``session`` Session object ``req`` Request object ``tmpl_context`` Object containing variables passed to templates ``app_globals`` Globals object To use them, merely access the attributes of the response *after* you've used a get/post command: .. code-block:: python response = app.get('/some/url') assert response.session['var'] == 4 assert 'REQUEST_METHOD' in response.req.environ .. note:: The :class:`response ` object already has a TestRequest object assigned to it, therefore Pylons assigns its ``request`` object to the response as ``req``. Accessing Special Globals ------------------------- Sometimes, you might wish to modify or check a global Pylons variable such as :term:`app_globals` before running the rest of your unit tests. The non-request specific variables are available from a special URL that will respond only in unit testing situations. For example, to get the :term:`app_globals` object without sending a request to your actual applications:: response = app.get('/_test_vars') app_globals = response.app_globals Testing Your Own Objects ======================== WebTest's fixture testing allows you to designate your own objects that you'd like to access in your tests. This powerful functionality makes it easy to test the value of objects that are normally only retained for the duration of a single request. Before making objects available for testing, its useful to know when your application is being tested. WebTest will provide an environ variable called ``paste.testing`` that you can test for the presence and truth of so that your application only populates the testing objects when it has to. Populating the :mod:`webtest` response object with your objects is done by adding them to the environ dict under the key ``paste.testing_variables``. Pylons creates this dict before calling your application, so testing for its existence and adding new values to it is recommended. All variables assigned to the ``paste.testing_variables`` dict will be available on the response object with the key being the attribute name. .. note:: WebTest is an extracted stand-alone version of a Paste component called paste.fixture. For backwards compatibility, WebTest continues to honor the ``paste.testing_variables`` key in the environ. Example: .. code-block:: python # testexample/lib/base.py from pylons import request from pylons.controllers import WSGIController from pylons.templating import render_mako as render class BaseController(WSGIController): def __call__(self, environ, start_response): # Create a custom email object email = MyCustomEmailObj() email.name = 'Fred Smith' if 'paste.testing_variables' in request.environ: request.environ['paste.testing_variables']['email'] = email return WSGIController.__call__(self, environ, start_response) # testexample/tests/functional/test_controller.py from testexample.tests import * class TestCommentsController(TestController): def test_index(self): response = self.app.get(url(controller='/')) assert response.email.name == 'Fred Smith' .. seealso:: `WebTest Documentation `_ Documentation covering webtest and its usage :mod:`WebTest Module docs ` Module API reference for methods available for use when testing the application .. _unit_testing: Unit Testing ============ XXX: Describe unit testing an applications models, libraries .. _functional_testing: Functional Testing ================== XXX: Describe functional/integrated testing, WebTest Pylons-1.0.1/pylons/docs/en/thirdparty/0000775000076500000240000000000012012307216017730 5ustar benstaff00000000000000Pylons-1.0.1/pylons/docs/en/thirdparty/formencode_api.rst0000664000076500000240000000577711645401275023467 0ustar benstaff00000000000000.. _formencode: ========== FormEncode ========== FormEncode is a validation and form generation package. The validation can be used separately from the form generation. The validation works on compound data structures, with all parts being nestable. It is separate from HTTP or any other input mechanism. These module API docs are divided into section by category. Core API ======== :mod:`formencode.api` --------------------- These functions are used mostly internally by FormEncode. .. automodule:: formencode.api .. function:: is_validator(obj) Returns whether ``obj`` is a validator object or not. .. autoclass:: Invalid :members: .. automethod:: __init__ .. autoclass:: Validator :members: .. autoclass:: FancyValidator :members: :mod:`formencode.schema` ------------------------ The FormEncode schema is one of the most important parts of using FormEncode, as it lets you organize validators into parts that can be re-used between schemas. Generally, a single schema will represent an entire form, but may inherit other schemas for re-usable validation parts (ie, maybe multiple forms all requires first and last name). .. module:: formencode.schema .. autoclass:: Schema .. autoclass:: SimpleFormValidator Validators ========== .. automodule:: formencode.validators .. autoclass:: Bool .. autoclass:: CIDR .. autoclass:: CreditCardValidator .. autoclass:: CreditCardExpires .. autoclass:: CreditCardSecurityCode .. autoclass:: DateConverter .. autoclass:: DateValidator .. autoclass:: DictConverter .. autoclass:: Email .. autoclass:: Empty .. autoclass:: FieldsMatch .. autoclass:: FieldStorageUploadConverter .. autoclass:: FileUploadKeeper .. autoclass:: FormValidator .. autoclass:: IndexListConverter .. autoclass:: Int .. autoclass:: IPhoneNumberValidator .. autoclass:: MACAddress .. autoclass:: MaxLength .. autoclass:: MinLength .. autoclass:: Number .. autoclass:: NotEmpty .. autoclass:: OneOf .. autoclass:: PhoneNumber .. autoclass:: PlainText .. autoclass:: PostalCode .. autoclass:: Regex .. autoclass:: RequireIfMissing .. autoclass:: Set .. autoclass:: SignedString .. autoclass:: StateProvince .. autoclass:: String .. autoclass:: StringBool .. autoclass:: StripField .. autoclass:: TimeConverter .. autoclass:: UnicodeString .. autoclass:: URL Wrapper Validators ------------------ .. autoclass:: ConfirmType .. autoclass:: Wrapper .. autoclass:: Constant Validator Modifiers =================== :mod:`formencode.compound` -------------------------- .. automodule:: formencode.compound .. autoclass:: Any .. autoclass:: All :mod:`formencode.foreach` ------------------------- .. automodule:: formencode.foreach .. autoclass:: ForEach HTML Parsing and Form Filling ============================= :mod:`formencode.htmlfill` -------------------------- .. automodule:: formencode.htmlfill .. autofunction:: render .. autofunction:: default_formatter .. autofunction:: none_formatter .. autofunction:: escape_formatter .. autofunction:: escapenl_formatter .. autoclass:: FillingParser Pylons-1.0.1/pylons/docs/en/thirdparty/index.rst0000664000076500000240000000026311645401275021605 0ustar benstaff00000000000000.. _third_party_components: ====================== Third-party components ====================== .. toctree:: :maxdepth: 1 formencode_api weberror webtest webob Pylons-1.0.1/pylons/docs/en/thirdparty/weberror.rst0000664000076500000240000000353111645401275022326 0ustar benstaff00000000000000:mod:`weberror` -- Weberror =========================== .. automodule:: weberror :mod:`weberror.errormiddleware` ------------------------------- .. currentmodule:: weberror.errormiddleware .. automodule:: weberror.errormiddleware .. autoclass:: ErrorMiddleware :members: :mod:`weberror.evalcontext` --------------------------- .. currentmodule:: weberror.evalcontext .. automodule:: weberror.evalcontext .. autoclass:: weberror.evalcontext.EvalContext :members: :mod:`weberror.evalexception` ----------------------------- .. currentmodule:: weberror.evalexception .. automodule:: weberror.evalexception .. autoclass:: weberror.evalexception.EvalException :members: :mod:`weberror.formatter` ------------------------- .. currentmodule:: weberror.formatter .. automodule:: weberror.formatter .. autoclass:: AbstractFormatter :members: .. autoclass:: TextFormatter :members: .. autoclass:: HTMLFormatter :members: .. autoclass:: XMLFormatter :members: .. autofunction:: create_text_node .. autofunction:: html_quote .. autofunction:: format_html .. autofunction:: format_text .. autofunction:: format_xml .. autofunction:: str2html .. autofunction:: _str2html .. autofunction:: truncate .. autofunction:: make_wrappable .. autofunction:: make_pre_wrappable :mod:`weberror.reporter` ------------------------ .. currentmodule:: weberror.reporter .. automodule:: weberror.reporter .. autoclass:: Reporter :members: .. autoclass:: EmailReporter :members: .. autoclass:: LogReporter :members: .. autoclass:: FileReporter :members: .. autoclass:: WSGIAppReporter :members: :mod:`weberror.collector` ------------------------- .. currentmodule:: weberror.collector .. automodule:: weberror.collector .. autoclass:: ExceptionCollector :members: .. autoclass:: ExceptionFrame :members: .. autofunction:: collect_exception Pylons-1.0.1/pylons/docs/en/thirdparty/webob.rst0000664000076500000240000000276311645401275021603 0ustar benstaff00000000000000:mod:`webob` -- Request/Response objects ======================================== .. automodule:: webob Request ------- .. autoclass:: Request .. automodule:: webob.acceptparse .. autoclass:: Accept .. autoclass:: MIMEAccept .. automodule:: webob.byterange .. autoclass:: Range .. automodule:: webob.cachecontrol .. autoclass:: CacheControl .. automodule:: webob.datastruct .. autoclass:: EnvironHeaders .. automodule:: webob.etag .. autoclass:: ETagMatcher .. autoclass:: IfRange Response -------- .. autoclass:: webob.Response .. autoclass:: webob.byterange.ContentRange .. autoclass:: webob.cachecontrol.CacheControl .. automodule:: webob.headerdict .. autoclass:: HeaderDict Misc Functions -------------- .. autofunction:: webob.html_escape .. comment: not sure what to do with these constants; not autoclass .. autoclass:: webob.day .. autoclass:: webob.week .. autoclass:: webob.hour .. autoclass:: webob.minute .. autoclass:: webob.second .. autoclass:: webob.month .. autoclass:: webob.year .. autoclass:: webob.response.AppIterRange .. automodule:: webob.multidict .. autoclass:: MultiDict .. autoclass:: UnicodeMultiDict .. autoclass:: NestedMultiDict .. autoclass:: NoVars .. automodule:: webob.updatedict .. autoclass:: webob.updatedict.UpdateDict Descriptors ----------- .. autoclass:: webob.descriptors.environ_getter .. autoclass:: webob.descriptors.header_getter .. autoclass:: webob.descriptors.converter .. autoclass:: webob.descriptors.deprecated_property Pylons-1.0.1/pylons/docs/en/thirdparty/webtest.rst0000664000076500000240000000033411645401275022152 0ustar benstaff00000000000000:mod:`webtest` -- WebTest ========================= .. currentmodule:: webtest .. automodule:: webtest .. autoclass:: TestApp :members: .. autoclass:: TestResponse :members: .. autoclass:: Form :members: Pylons-1.0.1/pylons/docs/en/tutorials/0000775000076500000240000000000012012307216017564 5ustar benstaff00000000000000Pylons-1.0.1/pylons/docs/en/tutorials/index.rst0000664000076500000240000000025611645401275021443 0ustar benstaff00000000000000.. _tutorials: Pylons Tutorials ================ A small collection of relevant tutorials. .. toctree:: :maxdepth: 2 quickwiki_tutorial understanding_unicode Pylons-1.0.1/pylons/docs/en/tutorials/quickwiki_tutorial.rst0000664000076500000240000013043411645401275024261 0ustar benstaff00000000000000.. _quickwiki_tutorial: ================== Quickwiki tutorial ================== Introduction ============ If you haven't done so already, please first read the :ref:`getting_started` guide. In this tutorial we are going to create a working wiki from scratch using Pylons 1.0 and `SQLAlchemy`_. Our wiki will allow visitors to add, edit or delete formatted wiki pages. Starting at the End =================== Pylons is designed to be easy for everyone, not just developers, so let's start by downloading and installing the finished QuickWiki in exactly the same way that end users of QuickWiki might do. Once we have explored its features we will set about writing it from scratch. After you have :ref:`installed Pylons `, install the QuickWiki project: .. code-block :: bash $ easy_install QuickWiki==0.1.8 $ paster make-config QuickWiki test.ini Next, ensure that the ``sqlalchemy.url`` variable in the ``[app:main]`` section of the configuration file (``development.ini``) specifies a value that is suitable for your setup. The data source name points to the database you wish to use. .. note :: The default ``sqlite:///%(here)s/quickwiki.db`` uses a (file-based) SQLite database named ``quickwiki.db`` in the ini's top-level directory. This SQLite database will be created for you when running the :command:`paster setup-app` command below, but you could also use MySQL, Oracle or PostgreSQL. Firebird and MS-SQL may also work. See the `SQLAlchemy documentation `_ for more information on how to connect to different databases. SQLite for example requires additional forward slashes in its URI, where the client/server databases should only use two. You will also need to make sure you have the appropriate Python driver for the database you wish to use. If you're using Python 2.5, a version of the `pysqlite adapter `_ is already included, so you can jump right in with the tutorial. You may need to get `SQLite itself `_. Finally create the database tables and serve the finished application: .. code-block :: bash $ paster setup-app test.ini $ paster serve test.ini That's it! Now you can visit http://127.0.0.1:5000 and experiment with the finished Wiki. When you've finished, stop the server with :kbd:`Control-C` so we can start developing our own version. If you are interested in looking at the latest version of the QuickWiki source code it can be browsed online at http://bitbucket.org/bbangert/quickwiki/src/ or can be checked out using `Mercurial `_: .. code-block :: bash $ hg clone http://bitbucket.org/bbangert/quickwiki .. Note:: To run the QuickWiki checked out from the repository, you'll need to first run :command:`python setup.py develop` from the project's root directory. This will install its dependencies and generate `Python Egg `_ metadata in a :file:`QuickWiki.egg-info` directory. The latter is required for the :command:`paster` command (among other things) . .. code-block :: bash $ cd QuickWiki $ python setup.py develop Developing QuickWiki ==================== If you skipped the "Starting at the End" section you will need to assure yourself that you have Pylons installed. See the :ref:`getting_started`. Then create your project: .. code-block :: bash $ paster create -t pylons QuickWiki When prompted for which templating engine to use, simply hit enter for the default (Mako). When prompted for SQLAlchemy configuration, enter ``True``. Now let's start the server and see what we have: .. code-block :: bash $ cd QuickWiki $ paster serve --reload development.ini .. note :: We have started :command:`paster serve` with the :option:`--reload` option. This means any changes that we make to code will cause the server to restart (if necessary); your changes are immediately reflected on the live site. Visit http://127.0.0.1:5000 where you will see the introduction page. Now delete the file :file:`public/index.html` so we can see the front page of the wiki instead of this welcome page. If you now refresh the page, the Pylons built-in error document support will kick in and display an ``Error 404`` page, indicating the file could not be found. We'll setup a controller to handle this location later. The Model ========= Pylons uses a Model-View-Controller architecture; we'll start by creating the model. We could use any system we like for the model, including `SQLAlchemy`_ or `SQLObject `_. Optional SQLAlchemy integration is provided for new Pylons projects, which we enabled when creating the project, and thus we'll be using SQLAlchemy for the QuickWiki. .. note :: `SQLAlchemy`_ is a powerful Python SQL toolkit and Object Relational Mapper (ORM) that is widely used by the Python community. SQLAlchemy provides a full suite of well known enterprise-level persistence patterns, designed for efficient and high-performance database access, adapted into a simple and Pythonic domain language. It has full and detailed documentation available on the SQLAlchemy website: http://sqlalchemy.org/docs/. The most basic way of using SQLAlchemy is with explicit sessions where you create :class:`Session` objects as needed. Pylons applications typically employ a slightly more sophisticated setup, using SQLAlchemy's "contextual" thread-local sessions created via the :meth:`sqlalchemy.orm.scoped_session` function. With this configuration, the application can use a single :class:`Session` instance per web request, avoiding the need to pass it around explicitly. Instantiating a new scoped :class:`Session` will actually find an existing one in the current thread if available. Pylons has setup a :class:`Session` for us in the :file:`model/meta.py` file. For further details, refer to the `SQLAlchemy documentation on the Session `_. .. note :: It is important to recognize the difference between SQLAlchemy's (or possibly another DB abstraction layer's) :class:`Session` object and Pylons' standard :dfn:`session` (with a lowercase 's') for web requests. See :mod:`beaker` for more on the latter. It is customary to reference the database session by :class:`model.Session` or (more recently) :class:`Session` outside of model classes. The :file:`model/__init__.py` file starts out rather bare-bones. It initializes the SQLAlchemy database engine, and imports the Session object. At the top, add the following imports:: from sqlalchemy import orm, Column, Unicode, UnicodeText from quickwiki.model.meta import Session, Base Then add the following to the end of the :file:`model/__init__.py` file: .. code-block :: python class Page(Base): __tablename__ = 'pages' title = Column(Unicode(40), primary_key=True) content = Column(UnicodeText(), default=u'') We've defined a table called ``pages`` which has two columns: ``title`` (the primary key), a Unicode VARCHAR of 40 characters, and ``content`` a Unicode TEXT column of variable sized length. .. note :: A primary key is a unique ID for each row in a database table. In the example above we are using the page title as a natural primary key. Some prefer to integer primary keys for all tables, so-called surrogate primary keys. The author of this tutorial uses both methods in his own code and is not advocating one method over the other, what's important is to choose the best database structure for your application. See the Pylons Cookbook for `a quick general overview of relational databases `_ if you're not familiar with these concepts. A core philosophy of ORMs is that tables and domain classes are different beasts. So next we'll create the Python class that represents the pages of our wiki, and map these domain objects to rows in the ``pages`` table via the :func:`sqlalchemy.orm.mapper` function. In a more complex application, you could break out model classes into separate ``.py`` files in your :file:`model` directory, but for sake of simplicity in this case, we'll just stick to :file:`__init__.py`. Add this to the bottom of ``model/__init__.py``: .. code-block :: python class Page(object): def __init__(self, title, content=None): self.title = title self.content = content def __unicode__(self): return self.title __str__ = __unicode__ orm.mapper(Page, pages_table) A :class:`Page` object represents a row in the ``pages`` table, so ``self.title`` and ``self.content`` will be the values of the ``title`` and ``content`` columns. Looking ahead, our wiki could use a way of marking up the ``content`` field into HTML. Also, any 'WikiWords' (words made by joining together two or more capitalized words) should be converted to hyperlinks to wiki pages. We can use Python's `docutils `_ library to allow marking up ``content`` as `reStructuredText`_. So next we'll add a method to our :class:`Page` class that formats ``content`` as HTML and converts the WikiWords to hyperlinks. Add the following at the top of the :file:`model/__init__.py` file: .. code-block :: python import logging import re import sets from docutils.core import publish_parts from pylons import url from quickwiki.lib.helpers import link_to from quickwiki.model import meta log = logging.getLogger(__name__) # disable docutils security hazards: # http://docutils.sourceforge.net/docs/howto/security.html SAFE_DOCUTILS = dict(file_insertion_enabled=False, raw_enabled=False) wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)", re.UNICODE) then add a :meth:`get_wiki_content` method to the :class:`Page` class: .. code-block :: python class Page(object): def __init__(self, title, content=None): self.title = title self.content = content def get_wiki_content(self): """Convert reStructuredText content to HTML for display, and create links for WikiWords """ content = publish_parts(self.content, writer_name='html', settings_overrides=SAFE_DOCUTILS)['html_body'] titles = sets.Set(wikiwords.findall(content)) for title in titles: title_url = url(controller='pages', action='show', title=title) content = content.replace(title, link_to(title, title_url)) return content def __unicode__(self): return self.title __str__ = __unicode__ The :class:`Set` object provides us with only unique WikiWord names, so we don't try replacing them more than once (a "wikiword" is of course defined by the regular expression set globally). .. note :: Pylons uses a **Model View Controller** architecture and so the formatting of objects into HTML should properly be handled in the View, i.e. in a template. However in this example, converting `reStructuredText`_ into HTML in a template is inappropriate so we are treating the HTML representation of the content as part of the model. It also gives us the chance to demonstrate that SQLAlchemy domain classes are real Python classes that can have their own methods. The :func:`link_to` and :func:`url` functions referenced in the controller code are respectively: a helper imported from the :mod:`webhelpers.html` module indirectly via :file:`lib/helpers.py`, and a utility function imported directly from the :mod:`pylons` module. They are utilities for creating links to specific controller actions. In this case we have decided that all WikiWords should link to the :meth:`show` action of the ``pages`` controller which we'll create later. However, we need to ensure that the :func:`link_to` function is made available as a helper by adding an import statement to :file:`lib/helpers.py`: .. code-block :: python """Helper functions Consists of functions to typically be used within templates, but also available to Controllers. This module is available to templates as 'h'. """ from webhelpers.html.tags import * Since we have used docutils and SQLAlchemy, both third party packages, we need to edit our :file:`setup.py` file so that anyone installing QuickWiki with `Easy Install `_ will automatically have these dependencies installed too. Edit your :file:`setup.py` in your project root directory and add a docutils entry to the ``install_requires`` line (there will already be one for SQLAlchemy): .. code-block :: python install_requires=[ "Pylons>=0.9.7", "SQLAlchemy>=0.5", "docutils==0.4", ], While we are we are making changes to :file:`setup.py` we might want to complete some of the other sections too. Set the version number to 0.1.6 and add a description and URL which will be used on PyPi when we release it: .. code-block :: python version='0.1.6', description='QuickWiki - Pylons 0.9.7 Tutorial application', url='http://docs.pylonshq.com/tutorials/quickwiki_tutorial.html', We might also want to make a full release rather than a development release in which case we would remove the following lines from :file:`setup.cfg`: .. code-block :: ini [egg_info] tag_build = dev tag_svn_revision = true To test the automatic installation of the dependencies, run the following command which will also install docutils and SQLAlchemy if you don't already have them: .. code-block :: bash $ python setup.py develop .. note :: The command :command:`python setup.py develop` installs your application in a special mode so that it behaves exactly as if it had been installed as an egg file by an end user. This is really useful when you are developing an application because it saves you having to create an egg and install it every time you want to test a change. Application Setup ================= Edit :file:`websetup.py`, used by the :command:`paster setup-app` command, to look like this: .. code-block :: python """Setup the QuickWiki application""" import logging from quickwiki import model from quickwiki.config.environment import load_environment from quickwiki.model import meta log = logging.getLogger(__name__) def setup_app(command, conf, vars): """Place any commands to setup quickwiki here""" load_environment(conf.global_conf, conf.local_conf) # Create the tables if they don't already exist log.info("Creating tables...") meta.metadata.create_all(bind=meta.engine) log.info("Successfully set up.") log.info("Adding front page data...") page = model.Page(title=u'FrontPage', content=u'**Welcome** to the QuickWiki front page!') meta.Session.add(page) meta.Session.commit() log.info("Successfully set up.") You can see that :file:`config/environment.py`'s :func:`load_environment` function is called (which calls :file:`model/__init__.py`'s :func:`init_model` function), so our engine is ready for binding and we can import the model. A SQLAlchemy :class:`MetaData` object -- which provides some utility methods for operating on database schema -- usually needs to be connected to an engine, so the line .. code-block :: python meta.metadata.bind = meta.engine does exactly that and then .. code-block :: python model.metadata.create_all(checkfirst=True) uses the connection we've just set up and, creates the table(s) we've defined ... if they don't already exist. After the tables are created, the other lines add some data for the simple front page to our wiki. By default, SQLAlchemy specifies ``autocommit=False`` when creating the :class:`Session`, which means that operations will be wrapped in a transaction and :func:`commit`'ed atomically (unless your DB doesn't support transactions, like MySQL's default MyISAM tables -- but that's beyond the scope of this tutorial). The database SQLAlchemy will use is specified in the ``ini`` file, under the ``[app:main]`` section, as ``sqlalchemy.url``. We'll customize the ``sqlalchemy.url`` value to point to a SQLite database named :file:`quickwiki.db` that will reside in your project's root directory. Edit the :file:`development.ini` file in the root directory of your project: .. note :: If you've decided to use a different database other than SQLite, see the SQLAlchemy note in the `Starting at the End`_ section for information on supported database URIs. .. code-block :: ini [app:main] use = egg:QuickWiki #... # Specify the database for SQLAlchemy to use. # SQLAlchemy database URL sqlalchemy.url = sqlite:///%(here)s/quickwiki.db You can now run the :command:`paster setup-app` command to setup your tables in the same way an end user would, remembering to drop and recreate the database if the version tested earlier has already created the tables: .. code-block :: bash $ paster setup-app development.ini You should see the SQL sent to the database as the default :file:`development.ini` is setup to log SQLAlchemy's SQL statements. At this stage you will need to ensure you have the appropriate Python database drivers for the database you chose, otherwise you might find SQLAlchemy complains it can't get the DBAPI module for the dialect it needs. You should also edit :file:`quickwiki/config/deployment.ini_tmpl` so that when users run :command:`paster make-config` the configuration file that is produced for them will also use :file:`quickwiki.db`. In the ``[app:main]`` section: .. code-block :: ini # Specify the database for SQLAlchemy to use. sqlalchemy.url = sqlite:///%(here)s/quickwiki.db Templates ========= .. note :: Pylons uses the `Mako templating engine `_ by default, although as is the case with most aspects of Pylons, you are free to deviate from the default if you prefer. In our project we will make use of the `Mako inheritance feature `_. Add the main page template in :file:`templates/base.mako`: .. code-block :: html+mako QuickWiki ${h.stylesheet_link('/quick.css')}

${self.header()}

${next.body()}\
We'll setup all our other templates to inherit from this one: they will be automatically inserted into the ``${next.body()}`` line. Thus the whole page will be returned when we call the :func:`render` global from our controller. This lets us easily apply a consistent theme to all our templates. If you are interested in learning some of the features of Mako templates have a look at the comprehensive `Mako Documentation `_. For now we just need to understand that :func:`next.body` is replaced with the child template and that anything within ``${...}`` brackets is executed and replaced with the result. By default, the replacement content is HTML-escaped in order to meet modern standards of basic protection from accidentally making the app vulnerable to XSS exploit. This :file:`base.mako` also makes use of various helper functions attached to the ``h`` object. These are described in the `WebHelpers documentation `_. We need to add some helpers to the ``h`` by importing them in the :file:`lib/helpers.py` module (some are for later use): .. code-block :: python """Helper functions Consists of functions to typically be used within templates, but also available to Controllers. This module is available to templates as 'h'. """ from webhelpers.html import literal from webhelpers.html.tags import * from webhelpers.html.secure_form import secure_form Note that the :file:`helpers` module is available to templates as 'h', this is a good place to import or define directly any convenience functions that you want to make available to all templates. Routing ======= Before we can add the actions we want to be able to route the requests to them correctly. Edit :file:`config/routing.py` and adjust the 'Custom Routes' section to look like this: .. code-block :: python # CUSTOM ROUTES HERE map.connect('home', '/', controller='pages', action='show', title='FrontPage') map.connect('pages', '/pages', controller='pages', action='index') map.connect('show_page', '/pages/show/{title}', controller='pages', action='show') map.connect('edit_page', '/pages/edit/{title}', controller='pages', action='edit') map.connect('save_page', '/pages/save/{title}', controller='pages', action='save', conditions=dict(method='POST')) map.connect('delete_page', '/pages/delete', controller='pages', action='delete') # A bonus example - the specified defaults allow visiting # example.com/FrontPage to view the page titled 'FrontPage': map.connect('/{title}', controller='pages', action='show') return map Note that the default route has been replaced. This tells Pylons to route the root URL ``/`` to the :meth:`show()` method of the :class:`PageController` class in :file:`controllers/pages.py` and specify the ``title`` argument as ``'FrontPage'``. It also says that any URL of the form ``/SomePage`` should be routed to the same method but the ``title`` argument will contain the value of the first part of the URL, in this case ``SomePage``. Any other URLs that can't be matched by these maps are routed to the error controller as usual where they will result in a 404 error page being displayed. One of the main benefits of using the Routes system is that you can also create URLs automatically, simply by specifying the routing arguments. For example if I want the URL for the page ``FrontPage`` I can create it with this code: .. code-block :: python url(title='FrontPage') Although the URL would be fairly simple to create manually, with complicated URLs this approach is much quicker. It also has the significant advantage that if you ever deploy your Pylons application at a URL other than ``/``, all the URLs will be automatically adjusted for the new path without you needing to make any manual modifications. This flexibility is a real advantage. Full information on the powerful things you can do to route requests to controllers and actions can be found in the `Routes manual `_. Controllers =========== Quick Recap: We've setup the model, configured the application, added the routes and setup the base template in :file:`base.mako`, now we need to write the application logic and we do this with controllers. In your project's root directory, add a controller called ``pages`` to your project with this command: .. code-block :: bash $ paster controller pages If you are using Subversion, this will automatically be detected and the new controller and tests will be automatically added to your subversion repository. We are going to need the following actions: ``show(self, title)`` displays a page based on the title ``edit(self, title)`` displays a from for editing the page ``title`` ``save(self, title)`` save the page ``title`` and show it with a saved message ``index(self)`` lists all of the titles of the pages in the database ``delete(self, title)`` deletes a page :meth:`show` --------------- Let's get to work on the new controller in :file:`controllers/pages.py`. First we'll import the :class:`Page` class from our :mod:`model`, and the :class:`Session` class from the :mod:`model.meta` module. We'll also import the ``wikiwords`` regular expression object, which we'll use in the :meth:`show` method. Add this line with the imports at the top of the file: .. code-block :: python from quickwiki.model import Page, wikiwords from quickwiki.model.meta import Session Next we'll add the convenience method :meth:`__before__` to the :class:`PagesController`, which is a special method Pylons always calls before calling the actual action method. We'll have :meth:`__before__` obtain and make available the relevant query object from the database, ready to be queried. Our other action methods will need this query object, so we might as well create it one place. .. code-block :: python class PagesController(BaseController): def __before__(self): self.page_q = Session.query(Page) Now we can query the database using the query expression language provided by SQLAlchemy. Add the following :meth:`show` method to :class:`PagesController`: .. code-block :: python def show(self, title): page = self.page_q.filter_by(title=title).first() if page: c.content = page.get_wiki_content() return render('/pages/show.mako') elif wikiwords.match(title): return render('/pages/new.mako') abort(404) Add a template called :file:`templates/pages/show.mako` that looks like this: .. code-block :: html+mako <%inherit file="/base.mako"/>\ <%def name="header()">${c.title} ${h.literal(c.content)} This template simply displays the page title and content. .. note :: Pylons automatically assigns all the action parameters to the Pylons context object ``c`` so that you don't have to assign them yourself. In this case, the value of ``title`` will be automatically assigned to ``c.title`` so that it can be used in the templates. We assign ``c.content`` manually in the controller. We also need a template for pages that don't already exist. The template needs to display a message and link to the :meth:`edit` action so that they can be created. Add a template called :file:`templates/new.mako` that looks like this: .. code-block :: html+mako <%inherit file="/base.mako"/>\ <%def name="header()">${c.title}

This page doesn't exist yet. Create the page.

At this point we can test our QuickWiki to see how it looks. If you don't already have a server running, start it now with: .. code-block :: bash $ paster serve --reload development.ini We can spruce up the appearance of page a little by adding the stylesheet we linked to in the :file:`templates/base.mako` file earlier. Add the file :file:`public/quick.css` with the following content and refresh the page to reveal a better looking wiki: .. code-block :: css body { background-color: #888; margin: 25px; } div.content { margin: 0; margin-bottom: 10px; background-color: #d3e0ea; border: 5px solid #333; padding: 5px 25px 25px 25px; } h1.main { width: 100%; } p.footer{ width: 100%; padding-top: 8px; border-top: 1px solid #000; } a { text-decoration: none; } a:hover { text-decoration: underline; } When you run the example you will notice that the word ``QuickWiki`` has been turned into a hyperlink by the :func:`get_wiki_content` method we added to our :class:`Page` domain object earlier. You can click the link and will see an example of the new page screen from the :file:`new.mako` template. If you follow the ``Create the page`` link you will see the Pylons automatic error handler kick in to tell you ``Action edit is not implemented``. Well, we better write it next, but before we do, have a play with the :ref:`interactive_debugging`, try clicking on the ``+`` or ``>>`` arrows and you will be able to interactively debug your application. It is a tremendously useful tool. :meth:`edit` ------------ To edit the wiki page we need to get the content from the database without changing it to HTML to display it in a simple form for editing. Add the :meth:`edit` action: .. code-block :: python def edit(self, title): page = self.page_q.filter_by(title=title).first() if page: c.content = page.content return render('/pages/edit.mako') and then create the :file:`templates/edit.mako` file: .. code-block :: html+mako <%inherit file="/base.mako"/>\ <%def name="header()">Editing ${c.title} ${h.secure_form(url('save_page', title=c.title))} ${h.textarea(name='content', rows=7, cols=40, content=c.content)}
${h.submit(value='Save changes', name='commit')} ${h.end_form()} .. note :: You may have noticed that we only set ``c.content`` if the page exists but that it is accessed in :func:`h.text_area` even for pages that don't exist and yet it doesn't raise an :class:`AttributeError`. We are making use of the fact that the ``c`` object returns an empty string ``""`` for any attribute that is accessed which doesn't exist. This can be a very useful feature of the ``c`` object, but can catch you on occasions where you don't expect this behavior. It can be disabled by setting ``config['pylons.strict_c'] = True`` in your project's :file:`config/environment.py`. We are making use of the ``h`` object to create our form and field objects. This saves a bit of manual HTML writing. The form submits to the :meth:`save()` action to save the new or updated content so let's write that next. :meth:`save` -------------- The first thing the :meth:`save` action has to do is to see if the page being saved already exists. If not it creates it with ``page = model.Page(title)``. Next it needs the updated content. In Pylons you can get request parameters from form submissions via ``GET`` and ``POST`` requests from the appropriately named ``request`` object. For form submissions from *only* ``GET`` or ``POST`` requests, use ``request.GET`` or ``request.POST``. Only ``POST`` requests should generate side effects (like changing data), so the save action will only reference ``request.POST`` for the parameters. Then add the :meth:`save` action: .. code-block :: python @authenticate_form def save(self, title): page = self.page_q.filter_by(title=title).first() if not page: page = Page(title) # In a real application, you should validate and sanitize # submitted data throughly! escape is a minimal example here. page.content = escape(request.POST.getone('content')) Session.add(page) Session.commit() flash('Successfully saved %s!' % title) redirect_to('show_page', title=title) .. note :: ``request.POST`` is a MultiDict object: an ordered dictionary that may contain multiple values for each key. The MultiDict will always return one value for any existing key via the normal dict accessors ``request.POST[key]`` and :meth:`request.POST.get`. When multiple values are expected, use the :meth:`request.POST.getall` method to return all values in a list. :meth:`request.POST.getone` ensures one value for key was sent, raising a :class:`KeyError` when there are 0 or more than 1 values. The :func:`@authenticate_form` decorator that appears immediately before the :meth:`save` action checks the value of the hidden form field placed there by the :func:`secure_form` helper that we used in :file:`templates/edit.mako` to create the form. The hidden form field carries an authorization token for prevention of certain `Cross-site request forgery (CSRF) `_ attacks. Upon a successful save, we want to redirect back to the :meth:`show` action and 'flash' a ``Successfully saved`` message at the top of the page. 'Flashing' a status message immediately after an action is a common requirement, and the `WebHelpers` package provides the :class:`webhelpers.pylonslib.Flash` class that makes it easy. To utilize it, we'll create a flash object at the bottom of our :file:`lib/helpers.py` module: .. code-block :: python from webhelpers.pylonslib import Flash as _Flash flash = _Flash() And import it into our :file:`controllers/pages.py`. Our new :meth:`show` method is escaping the content via Python's :func:`cgi.escape` function, so we need to import that too, and also :func:`@authenticate_form`. .. code-block :: python from cgi import escape from pylons.decorators.secure import authenticate_form from quickwiki.lib.helpers import flash And finally utilize the ``flash`` object in our :file:`templates/base.mako` template: .. code-block :: html+mako QuickWiki ${h.stylesheet_link('/quick.css')}

${self.header()}

<% flashes = h.flash.pop_messages() %> % if flashes: % for flash in flashes:
${flash}
% endfor % endif ${next.body()}\
And add the following to the :file:`public/quick.css` file: .. code-block :: css div#flash .message { color: orangered; } The ``%`` syntax is used for control structures in mako -- conditionals and loops. You must 'close' them with an 'end' tag as shown here. At this point we have a fully functioning wiki that lets you create and edit pages and can be installed and deployed by an end user with just a few simple commands. Visit http://127.0.0.1:5000 and have a play. It would be nice to get a title list and to be able to delete pages, so that's what we'll do next! :meth:`index` ------------- Add the :meth:`index` action: .. code-block :: python def index(self): c.titles = [page.title for page in self.page_q.all()] return render('/pages/index.mako') The :meth:`index` action simply gets all the pages from the database. Create the :file:`templates/index.mako` file to display the list: .. code-block:: html+mako <%inherit file="/base.mako"/>\ <%def name="header()">Title List ${h.secure_form(url('delete_page'))}
    % for title in c.titles:
  • ${h.link_to(title, url('show_page', title=title))} - ${h.checkbox('title', title)}
  • % endfor
${h.submit('delete', 'Delete')} ${h.end_form()} This displays a form listing a link to all pages along with a checkbox. When submitted, the selected titles will be sent to a :meth:`delete` action we'll create in the next step. We need to edit :file:`templates/base.mako` to add a link to the title list in the footer, but while we're at it, let's introduce a Mako function to make the footer a little smarter. Edit :file:`base.mako` like this: .. code-block :: html+mako QuickWiki ${h.stylesheet_link('/quick.css')}

${self.header()}

<% flashes = h.flash.pop_messages() %> % if flashes: % for flash in flashes:
${flash}
% endfor % endif ${next.body()}\
## Don't show links that are redundant for particular pages <%def name="footer(action)">\ Return to the ${h.link_to('FrontPage', url('home'))} % if action == "index": <% return %> % endif % if action != 'edit': | ${h.link_to('Edit ' + c.title, url('edit_page', title=c.title))} % endif | ${h.link_to('Title List', url('pages'))} The ``<%def name="footer(action">`` creates a Mako function for display logic. As you can see, the function builds the HTML for the footer, but doesn't display the 'Edit' link when you're on the 'Title List' page or already on an edit page. It also won't show a 'Title List' link when you're already on that page. The ``<% ... %>`` tags shown on the :keyword:`return` statement are the final new piece of Mako syntax: they're used much like the ``${...}`` tags, but for arbitrary Python code that does not directly render HTML. Also, the double hash (``##``) denotes a single-line comment in Mako. So the :func:`footer` function is called in place of our old 'static' footer markup. We pass it a value from ``pylons.routes_dict`` which holds the name of the action for the current request. The trailing `\\` character just tells Mako not to render an extra newline. If you visit http://127.0.0.1:5000/pages you should see the full titles list and you should be able to visit each page. :meth:`delete` ---------------- We need to add a :meth:`delete` action that deletes pages submitted from :file:`templates/index.mako`, then returns us back to the list of titles (excluding those that were deleted): .. code-block :: python @authenticate_form def delete(self): titles = request.POST.getall('title') pages = self.page_q.filter(Page.title.in_(titles)) for page in pages: Session.delete(page) Session.commit() # flash only after a successful commit for title in titles: flash('Deleted %s.' % title) redirect_to('pages') Again we use the :func:`@authenticate_form` decorator along with :func:`secure_form` used in :file:`templates/index.mako`. We're expecting potentially multiple titles, so we use :meth:`request.POST.getall` to return a list of titles. The titles are used to identify and load the :class:`Page` objects, which are then deleted. We use the SQL ``IN`` operator to match multiple titles in one query. We can do this via the more flexible :meth:`filter` method which can accept an :meth:`in_` clause created via the title column's attribute. The :meth:`filter_by` method we used in previous methods is a shortcut for the most typical filtering clauses. For example, the :meth:`show` method's: .. code-block :: python self.page_q.filter_by(title=title) is equivalent to: .. code-block :: python self.page_q.filter(Page.title == title) After deleting the pages, the changes are committed, and only after successfully committing do we flash deletion messages. That way if there was a problem with the commit no flash messages are shown. Finally we redirect back to the index page, which re-renders the list of remaining titles. Visit http://127.0.0.1:5000/index and have a go at deleting some pages. You may need to go back to the FrontPage and create some more if you get carried away! That's it! A working, production-ready wiki in 20 mins. You can visit http://127.0.0.1:5000/ once more to admire your work. Publishing the Finished Product =============================== After all that hard work it would be good to distribute the finished package wouldn't it? Luckily this is really easy in Pylons too. In the project root directory run this command: .. code-block :: bash $ python setup.py bdist_egg This will create an egg file in the :file:`dist` directory which contains everything anyone needs to run your program. They can install it with: .. code-block :: bash $ easy_install QuickWiki-0.1.6-py2.5.egg You should probably make eggs for each version of Python your users might require by running the above commands with both Python 2.4 and 2.5 to create both versions of the eggs. If you want to register your project with PyPi at http://www.python.org/pypi you can run the command below. *Please only do this with your own projects though because QuickWiki has already been registered!* .. code-block :: bash $ python setup.py register .. warning:: The PyPi authentication is very weak and passwords are transmitted in plain text. Don't use any sign in details that you use for important applications as they could be easily intercepted. You will be asked a number of questions and then the information you entered in :file:`setup.py` will be used as a basis for the page that is created. Now visit http://www.python.org/pypi to see the new index with your new package listed. .. note :: A `CheeseShop Tutorial `_ has been written and `full documentation on setup.py `_ is available from the Python website. You can even use `reStructuredText`_ in the ``description`` and ``long_description`` areas of :file:`setup.py` to add formatting to the pages produced on PyPi (PyPi used to be called "the CheeseShop"). There is also `another tutorial here `_. Finally you can sign in to PyPi with the account details you used when you registered your application and upload the eggs you've created. If that seems too difficult you can even use this command which should be run for each version of Python supported to upload the eggs for you: .. code-block :: bash $ python setup.py bdist_egg upload Before this will work you will need to create a :file:`.pypirc` file in your home directory containing your username and password so that the :command:`upload` command knows who to sign in as. It should look similar to this: .. code-block :: ini [server-login] username: james password: password .. note :: This works on windows too but you will need to set your :envvar:`HOME` environment variable first. If your home directory is :file:`C:\Documents and Settings\James` you would put your :file:`.pypirc` file in that directory and set your :envvar:`HOME` environment variable with this command: .. code-block :: bash > SET HOME=C:\Documents and Settings\James You can now use the :command:`python setup.py bdist_egg upload` as normal. Now that the application is on PyPi anyone can install it with the :command:`easy_install` command exactly as we did right at the very start of this tutorial. Security ======== A final word about security. .. warning :: Always set ``debug = false`` in configuration files for production sites and make sure your users do too. You should NEVER run a production site accessible to the public with debug mode on. If there was a problem with your application and an interactive error page was shown, the visitor would be able to run any Python commands they liked in the same way you can when you are debugging. This would obviously allow them to do all sorts of malicious things so it is very important you turn off interactive debugging for production sites by setting ``debug = false`` in configuration files and also that you make users of your software do the same. Summary ======= We've gone through the whole cycle of creating and distributing a Pylons application looking at setup and configuration, routing, models, controllers and templates. Hopefully you have an idea of how powerful Pylons is and, once you get used to the concepts introduced in this tutorial, how easy it is to create sophisticated, distributable applications with Pylons. That's it, I hope you found the tutorial useful. You are encouraged to email any comments to the `Pylons mailing list `_ where they will be welcomed. Thanks ====== A big thanks to Ches Martin for updating this document and the QuickWiki project for Pylons 0.9.6 / Pylons 0.9.7 / QuickWiki 0.1.5 / QuickWiki 0.1.6, Graham Higgins, and others in the Pylons community who contributed bug fixes and suggestions. Todo ==== * Provide :command:`paster shell` examples * Incorporate testing into the tutorial * Explain Ches's :meth:`validate_title` method in the actual QuickWiki project * Provide snapshots of every file modified at each step, to help resolve mistakes .. _`SQLAlchemy`: http://www.sqlalchemy.org .. _`reStructuredText`: http://docutils.sourceforge.net/rst.html Pylons-1.0.1/pylons/docs/en/tutorials/understanding_unicode.rst0000664000076500000240000006464111645401275024717 0ustar benstaff00000000000000.. _unicode: ===================== Understanding Unicode ===================== If you've ever come across text in a foreign language that contains lots of ``????`` characters or have written some Python code and received a message such as ``UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 6: ordinal not in range(128)`` then you have run into a problem with character sets, encodings, Unicode and the like. The truth is that many developers are put off by Unicode because most of the time it is possible to muddle through rather than take the time to learn the basics. To make the problem worse if you have a system that manages to fudge the issues and just about work and then start trying to do things properly with Unicode it often highlights problems in other parts of your code. The good news is that Python has great Unicode support, so the rest of this article will show you how to correctly use Unicode in Pylons to avoid unwanted ``?`` characters and ``UnicodeDecodeErrors``. What is Unicode? ---------------- When computers were first being used the characters that were most important were unaccented English letters. Each of these letters could be represented by a number between 32 and 127 and thus was born ASCII, a character set where space was 32, the letter "A" was 65 and everything could be stored in 7 bits. Most computers in those days were using 8-bit bytes so people quickly realized that they could use the codes 128-255 for their own purposes. Different people used the codes 128-255 to represent different characters and before long these different sets of characters were also standardized into *code pages*. This meant that if you needed some non-ASCII characters in a document you could also specify a codepage which would define which extra characters were available. For example Israel DOS used a code page called 862, while Greek users used 737. This just about worked for Western languages provided you didn't want to write an Israeli document with Greek characters but it didn't work at all for Asian languages where there are many more characters than can be represented in 8 bits. Unicode is a character set that solves these problems by uniquely defining *every* character that is used anywhere in the world. Rather than defining a character as a particular combination of bits in the way ASCII does, each character is assigned a *code point*. For example the word ``hello`` is made from code points ``U+0048 U+0065 U+006C U+006C U+006F``. The full list of code points can be found at http://www.unicode.org/charts/. There are lots of different ways of encoding Unicode code points into bits but the most popular encoding is UTF-8. Using UTF-8, every code point from 0-127 is stored in a single byte. Only code points 128 and above are stored using 2, 3, in fact, up to 6 bytes. This has the useful side effect that English text looks exactly the same in UTF-8 as it did in ASCII, because for every ASCII character with hexadecimal value 0xXY, the corresponding Unicode code point is U+00XY. This backwards compatibility is why if you are developing an application that is only used by English speakers you can often get away without handling characters properly and still expect things to work most of the time. Of course, if you use a different encoding such as UTF-16 this doesn't apply since none of the code points are encoded to 8 bits. The important things to note from the discussion so far are that: * Unicode can represent pretty much any character in any writing system in widespread use today * Unicode uses code points to represent characters and the way these map to bits in memory depends on the encoding * The most popular encoding is UTF-8 which has several convenient properties 1. It can handle any Unicode code point 2. A Unicode string is turned into a string of bytes containing no embedded zero bytes. This avoids byte-ordering issues, and means UTF-8 strings can be processed by C functions such as strcpy() and sent through protocols that can't handle zero bytes 3. A string of ASCII text is also valid UTF-8 text 4. UTF-8 is fairly compact; the majority of code points are turned into two bytes, and values less than 128 occupy only a single byte. 5. If bytes are corrupted or lost, it's possible to determine the start of the next UTF-8-encoded code point and resynchronize. .. note:: Since Unicode 3.1, some extensions have even been defined so that the defined range is now U+000000 to U+10FFFF (21 bits), and formally, the character set is defined as 31-bits to allow for future expansion. It is a myth that there are 65,536 Unicode code points and that every Unicode letter can really be squeezed into two bytes. It is also incorrect to think that UTF-8 can represent less characters than UTF-16. UTF-8 simply uses a variable number of bytes for a character, sometimes just one byte (8 bits). Unicode in Python ----------------- In Python Unicode strings are expressed as instances of the built-in ``unicode`` type. Under the hood, Python represents Unicode strings as either 16 or 32 bit integers, depending on how the Python interpreter was compiled. The ``unicode()`` constructor has the signature ``unicode(string[, encoding, errors])``. All of its arguments should be 8-bit strings. The first argument is converted to Unicode using the specified encoding; if you leave off the encoding argument, the ASCII encoding is used for the conversion, so characters greater than 127 will be treated as errors: .. code-block:: pycon >>> unicode('hello') u'hello' >>> s = unicode('hello') >>> type(s) >>> unicode('hello' + chr(255)) Traceback (most recent call last): File "", line 1, in ? UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 6: ordinal not in range(128) The ``errors`` argument specifies what to do if the string can't be decoded to ascii. Legal values for this argument are ``'strict'`` (raise a ``UnicodeDecodeError`` exception), ``'replace'`` (replace the character that can't be decoded with another one), or ``'ignore'`` (just leave the character out of the Unicode result). .. code-block:: pycon >>> unicode('\x80abc', errors='strict') Traceback (most recent call last): File "", line 1, in ? UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: ordinal not in range(128) >>> unicode('\x80abc', errors='replace') u'\ufffdabc' >>> unicode('\x80abc', errors='ignore') u'abc' It is important to understand the difference between *encoding* and *decoding*. Unicode strings are considered to be the Unicode code points but any representation of the Unicode string has to be encoded to something else, for example UTF-8 or ASCII. So when you are converting an ASCII or UTF-8 string to Unicode you are *decoding* it and when you are converting from Unicode to UTF-8 or ASCII you are *encoding* it. This is why the error in the example above says that the ASCII codec cannot decode the byte ``0x80`` from ASCII to Unicode because it is not in the range(128) or 0-127. In fact ``0x80`` is hex for 128 which the first number outside the ASCII range. However if we tell Python that the character ``0x80`` is encoded with the ``'latin-1'``, ``'iso_8859_1'`` or ``'8859'`` character sets (which incidentally are different names for the same thing) we get the result we expected: .. code-block:: pycon >>> unicode('\x80', encoding='latin-1') u'\x80' .. note:: The character encodings Python supports are listed at http://docs.python.org/lib/standard-encodings.html Unicode objects in Python have most of the same methods that normal Python strings provide. Python will try to use the ``'ascii'`` codec to convert strings to Unicode if you do an operation on both types: .. code-block:: pycon >>> a = 'hello' >>> b = unicode(' world!') >>> print a + b u'hello world!' You can encode a Unicode string using a particular encoding like this: .. code-block:: pycon >>> u'Hello World!'.encode('utf-8') 'Hello World!' Unicode Literals in Python Source Code -------------------------------------- In Python source code, Unicode literals are written as strings prefixed with the 'u' or 'U' character: .. code-block:: pycon >>> u'abcdefghijk' >>> U'lmnopqrstuv' You can also use ``"``, ``"""``` or ``'''`` versions too. For example: .. code-block:: pycon >>> u"""This ... is a really long ... Unicode string""" Specific code points can be written using the ``\u`` escape sequence, which is followed by four hex digits giving the code point. If you use ``\U`` instead you specify 8 hex digits instead of 4. Unicode literals can also use the same escape sequences as 8-bit strings, including ``\x``, but ``\x`` only takes two hex digits so it can't express all the available code points. You can add characters to Unicode strings using the ``unichr()`` built-in function and find out what the ordinal is with ``ord()``. Here is an example demonstrating the different alternatives: .. code-block:: pycon >>> s = u"\x66\u0072\u0061\U0000006e" + unichr(231) + u"ais" >>> # ^^^^ two-digit hex escape >>> # ^^^^^^ four-digit Unicode escape >>> # ^^^^^^^^^^ eight-digit Unicode escape >>> for c in s: print ord(c), ... 97 102 114 97 110 231 97 105 115 >>> print s français Using escape sequences for code points greater than 127 is fine in small doses but Python 2.4 and above support writing Unicode literals in any encoding as long as you declare the encoding being used by including a special comment as either the first or second line of the source file: .. code-block:: python #!/usr/bin/env python # -*- coding: latin-1 -*- u = u'abcdé' print ord(u[-1]) If you don't include such a comment, the default encoding used will be ASCII. Versions of Python before 2.4 were Euro-centric and assumed Latin-1 as a default encoding for string literals; in Python 2.4, characters greater than 127 still work but result in a warning. For example, the following program has no encoding declaration: .. code-block:: python #!/usr/bin/env python u = u'abcdé' print ord(u[-1]) When you run it with Python 2.4, it will output the following warning: .. code-block:: pycon sys:1: DeprecationWarning: Non-ASCII character '\xe9' in file testas.py on line 2, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details and then the following output: .. code-block:: pycon 233 For real world use it is recommended that you use the UTF-8 encoding for your file but you must be sure that your text editor actually saves the file as UTF-8 otherwise the Python interpreter will try to parse UTF-8 characters but they will actually be stored as something else. .. note :: Windows users who use the `SciTE `_ editor can specify the encoding of their file from the menu using the ``File->Encoding``. .. note :: If you are working with Unicode in detail you might also be interested in the ``unicodedata`` module which can be used to find out Unicode properties such as a character's name, category, numeric value and the like. Input and Output ---------------- We now know how to use Unicode in Python source code but input and output can also be different using Unicode. Of course, some libraries natively support Unicode and if these libraries return Unicode objects you will not have to do anything special to support them. XML parsers and SQL databases frequently support Unicode for example. If you remember from the discussion earlier, Unicode data consists of code points. In order to send Unicode data via a socket or write it to a file you usually need to encode it to a series of bytes and then decode the data back to Unicode when reading it. You can of course perform the encoding manually reading a byte at the time but since encodings such as UTF-8 can have variable numbers of bytes per character it is usually much easier to use Python's built-in support in the form of the ``codecs`` module. The codecs module includes a version of the ``open()`` function that returns a file-like object that assumes the file's contents are in a specified encoding and accepts Unicode parameters for methods such as ``.read()`` and ``.write()``. The function's parameters are open(filename, mode='rb', encoding=None, errors='strict', buffering=1). ``mode`` can be 'r', 'w', or 'a', just like the corresponding parameter to the regular built-in ``open()`` function. You can add a ``+`` character to update the file. ``buffering`` is similar to the standard function's parameter. ``encoding`` is a string giving the encoding to use, if not specified or specified as ``None``, a regular Python file object that accepts 8-bit strings is returned. Otherwise, a wrapper object is returned, and data written to or read from the wrapper object will be converted as needed. ``errors`` specifies the action for encoding errors and can be one of the usual values of ``'strict'``, ``'ignore'``, or ``'replace'`` which we saw right at the begining of this document when we were encoding strings in Python source files. Here is an example of how to read Unicode from a UTF-8 encoded file: .. code-block:: python import codecs f = codecs.open('unicode.txt', encoding='utf-8') for line in f: print repr(line) It's also possible to open files in update mode, allowing both reading and writing: .. code-block:: python f = codecs.open('unicode.txt', encoding='utf-8', mode='w+') f.write(u"\x66\u0072\u0061\U0000006e" + unichr(231) + u"ais") f.seek(0) print repr(f.readline()[:1]) f.close() Notice that we used the ``repr()`` function to display the Unicode data. This is very useful because if you tried to print the Unicode data directly, Python would need to encode it before it could be sent the console and depending on which characters were present and the character set used by the console, an error might be raised. This is avoided if you use ``repr()``. The Unicode character ``U+FEFF`` is used as a byte-order mark or BOM, and is often written as the first character of a file in order to assist with auto-detection of the file's byte ordering. Some encodings, such as UTF-16, expect a BOM to be present at the start of a file, but with others such as UTF-8 it isn't necessary. When such an encoding is used, the BOM will be automatically written as the first character and will be silently dropped when the file is read. There are variants of these encodings, such as 'utf-16-le' and 'utf-16-be' for little-endian and big-endian encodings, that specify one particular byte ordering and don't skip the BOM. .. note :: Some editors including SciTE will put a byte order mark (BOM) in the text file when saved as UTF-8, which is strange because UTF-8 doesn't need BOMs. Unicode Filenames ----------------- Most modern operating systems support the use of Unicode filenames. The filenames are transparently converted to the underlying filesystem encoding. The type of encoding depends on the operating system. On Windows 9x, the encoding is ``mbcs``. On Mac OS X, the encoding is ``utf-8``. On Unix, the encoding is the user's preference according to the result of nl_langinfo(CODESET), or None if the nl_langinfo(CODESET) failed. On Windows NT+, file names are Unicode natively, so no conversion is performed. getfilesystemencoding still returns ``mbcs``, as this is the encoding that applications should use when they explicitly want to convert Unicode strings to byte strings that are equivalent when used as file names. ``mbcs`` is a special encoding for Windows that effectively means "use whichever encoding is appropriate". In Python 2.3 and above you can find out the system encoding with ``sys.getfilesystemencoding()``. Most file and directory functions and methods support Unicode. For example: .. code-block:: python filename = u"\x66\u0072\u0061\U0000006e" + unichr(231) + u"ais" f = open(filename, 'w') f.write('Some data\n') f.close() Other functions such as ``os.listdir()`` will return Unicode if you pass a Unicode argument and will try to return strings if you pass an ordinary 8 bit string. For example running this example as ``test.py``: .. code-block:: python filename = u"Sample " + unichar(5000) f = open(filename, 'w') f.close() import os print os.listdir('.') print os.listdir(u'.') will produce the following output: .. code-block:: python ['Sample?', 'test.py'] [u'Sample\u1388', u'test.py'] Applying this to Web Programming ================================ So far we've seen how to use encoding in source files and seen how to decode text to Unicode and encode it back to text. We've also seen that Unicode objects can be manipulated in similar ways to strings and we've seen how to perform input and output operations on files. Next we are going to look at how best to use Unicode in a web app. The main rule is this: **Your application should use Unicode for all strings internally, decoding any input to Unicode as soon as it enters the application and encoding the Unicode to UTF-8 or another encoding only on output.** If you fail to do this you will find that ``UnicodeDecodeError`` s will start popping up in unexpected places when Unicode strings are used with normal 8-bit strings because Python's default encoding is ASCII and it will try to decode the text to ASCII and fail. It is always better to do any encoding or decoding at the edges of your application otherwise you will end up patching lots of different parts of your application unnecessarily as and when errors pop up. Unless you have a very good reason not to it is wise to use UTF-8 as the default encoding since it is so widely supported. The second rule is: **Always test your application with characters above 127 and above 255 wherever possible.** If you fail to do this you might think your application is working fine, but as soon as your users do put in non-ASCII characters you will have problems. Using arabic is always a good test and www.google.ae is a good source of sample text. The third rule is: **Always do any checking of a string for illegal characters once it's in the form that will be used or stored, otherwise the illegal characters might be disguised.** For example, let's say you have a content management system that takes a Unicode filename, and you want to disallow paths with a '/' character. You might write this code: .. code-block:: python def read_file(filename, encoding): if '/' in filename: raise ValueError("'/' not allowed in filenames") unicode_name = filename.decode(encoding) f = open(unicode_name, 'r') # ... return contents of file ... This is INCORRECT. If an attacker could specify the 'base64' encoding, they could pass ``L2V0Yy9wYXNzd2Q=`` which is the base-64 encoded form of the string ``'/etc/passwd'`` which is a file you clearly don't want an attacker to get hold of. The above code looks for ``/`` characters in the encoded form and misses the dangerous character in the resulting decoded form. Those are the three basic rules so now we will look at some of the places you might want to perform Unicode decoding in a Pylons application. Request Parameters ------------------ Pylons automatically coerces incoming form parameters (``request.POST``, ``GET`` (quote GET) and ``params``) into unicode objects (as of Pylons 0.9.6). The request object contains a ``charset`` (encoding) attribute defining what the parameters should be decoded to (via value.decode(charset, errors)), and the decoding ``errors`` handler. The unicode conversion of parameters can be disabled when ``charset`` is set to None. .. code-block:: python def index(self): #request.charset = 'utf-8' # utf-8 is the default charset #request.errors = 'replace' # replace is the default error handler # a MultiDict-like object of string names and unicode values decoded_get = request.GET # The raw data is always still available when charset is None request.charset = None raw_get = request.GET raw_params = request.params Pylons can also be configured to not coerece parameters to unicode objects by default. This is done by setting the following in the Pylons config object (at the bottom of your project's ``config/environment.py``): .. code-block:: python # Don't coerce parameters to unicode config['pylons.request_options']['charset'] = None # You can also change the default error handler #config['pylons.request_options']['errors'] = 'strict' When the ``request`` object is instructed to always automatically decode to unicode via the ``request_settings`` dictionary, the dictionary's ``charset`` value acts as a fallback charset. If a ``charset`` was sent by the browser (via the ``Content-Type`` header), the browser's value will take precedent: this takes place when the ``request`` object is constructed. ``FieldStorage`` (file upload) objects will be handled specially for unicode parameters: what's provided is a copy of the original ``FieldStorage`` object with a unicode version of its ``filename`` attribute. See :ref:`file_uploads` for more information on working with file uploads/``FieldStorage`` objects. .. note:: Only parameter values (not their associated names) are decoded to unicode by default. Since parameter names commonly map directly to Python variable names (which are restricted to the ASCII character set), it's usually preferable to handle them as strings. For example, passing form parameters to a function as keyword arguments (e.g. \*\*request.params.mixed()) doesn't work with unicode keys. To make ``WSGIRequest`` decode parameter names anyway, enable the ``decode_param_names`` option on either the WSGIRequest object or the ``request_settings`` dictionary. ``FieldStorage's`` ``name`` attributes are also decoded to unicode when this option is enabled. Templating ---------- Pylons uses Mako as its default templating language. Mako handles all content as unicode internally. It only deals in raw strings upon the final rendering of the template (the Mako ``render()`` function, used by the Pylons ``render()`` function/Buffet plugin). The encoding of the rendered string can be configured; Pylons sets the default value to UTF-8. To change this value, edit your project's ``config/environment.py`` file and add the following option: .. code-block:: python # Customize templating options via this variable tmpl_options = config['buffet.template_options'] tmpl_options['mako.output_encoding'] = 'utf-8' replacing ``utf-8`` with the encoding you wish to use. More information can be found at `Mako's Unicode Chapter `_. Output Encoding --------------- Web pages should be generated with a specific encoding, most likely UTF-8. At the very least, that means you should specify the following in the ```` section: .. code-block:: html The charset should also be specified in the ``Content-Type`` header (which Pylons automatically does for you): .. code-block:: python response.headers['Content-type'] = 'text/html; charset=utf-8' Pylons has a notion of ``response_options``, complimenting the ``request_options`` mentioned in the `Request Parameters`_ section above. The default request charset can be changed by setting the following in the Pylons config object (at the bottom of your project's ``config/environment.py``): .. code-block:: python config['pylons.response_options']['charset'] = 'utf-8' replacing ``utf-8`` with the charset you wish to use. If you specify that your output is UTF-8, generally the web browser will give you UTF-8. If you want the browser to submit data using a different character set, you can set the encoding by adding the ``accept-encoding`` tag to your form. Here is an example: .. code-block:: html
However, be forewarned that if the user tries to give you non-ASCII text, then: * Firefox will translate the non-ASCII text into HTML entities. * IE will ignore your suggested encoding and give you UTF-8 anyway. The lesson to be learned is that if you output UTF-8, you had better be prepared to accept UTF-8 by decoding the data in ``request.params`` as described in the section above entitled `Request Parameters`_'. Another technique which is sometimes used to determine the character set is to use an algorithm to analyse the input and guess the encoding based on probabilities. For instance, if you get a file, and you don't know what encoding it is encoded in, you can often rename the file with a .txt extension and then try to open it in Firefox. Then you can use the "View->Character Encoding" menu to try to auto-detect the encoding. Databases --------- Your database driver should automatically convert from Unicode objects to a particular charset when writing and back again when reading. Again it is normal to use UTF-8 which is well supported. You should check your database's documentation for information on how it handles Unicode. For example MySQL's Unicode documentation is here http://dev.mysql.com/doc/refman/5.0/en/charset-unicode.html Also note that you need to consider both the encoding of the database and the encoding used by the database driver. If you're using MySQL together with SQLAlchemy, see the following, as there are some bugs in MySQLdb that you'll need to work around: http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg00366.html Summary ======= Hopefully you now understand the history of Unicode, how to use it in Python and where to apply Unicode encoding and decoding in a Pylons application. You should also be able to use Unicode in your web app remembering the basic rule to use UTF-8 to talk to the world, do the encode and decode at the edge of your application. Further Reading =============== This information is based partly on the following articles which can be consulted for further information.: http://www.joelonsoftware.com/articles/Unicode.html http://www.amk.ca/python/howto/unicode Please feel free to report any mistakes to the Pylons mailing list or to the author. Any corrections or clarifications would be gratefully received. Pylons-1.0.1/pylons/docs/en/upgrading.rst0000664000076500000240000001663211645401275020273 0ustar benstaff00000000000000.. _upgrading: ========= Upgrading ========= 1.0 -> 1.0.1 ============ No changes are necessary, however to take advantage of MarkupSafe's faster HTML escaping, the default filter in ``environment.py`` that Mako is configured with should be changed from:: from webhelpers.html import escape To:: from markupsafe import escape MarkupSafe utilizes a C extension where available for faster escaping which can help on larger pages with substantial variable substitutions. 0.9.7 -> 1.0 ============ Upgrading your project is slightly different depending on which versions you're upgrading from and to. It's recommended that upgrades be done in minor revision steps, as deprecation warnings are added between revisions to help in the upgrade process. For any project prior to 0.9.7, you should first follow the applicable docs to upgrade to 0.9.7 before proceeding. To upgrade to 1.0, first upgrade your project to 0.10. This is a Pylons release that is fully backwards-compatible with 0.9.7. However under 0.10 a variety of warnings will be issued about the various things that need to be changed before upgrading to 1.0. .. tip:: Since Pylons 0.10 is only out as a beta at this point, upgrade using the actual URL, for example: .. code-block:: bash $ easy_install -U http://pylonshq.com/download/0.10/Pylons-0.10.tar.gz Beyond the warnings issued, you should also read the following list and ensure these changes have been applied. Pylons changes from 0.9.7 to 1.0: * The config object created in ``environment.py`` is now passed around explicitly. There are also some other minor updates as follows. Update config/environment.py to initialize and return the config:: # Add to the imports: from pylons.configuration import PylonsConfig # Add under 'def load_environment': config = PylonsConfig() # Replace the make_map / app globals line with config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) # Optionally, if removing the CacheMiddleware and using the # cache in the new 1.0 style, add under the previous lines: import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) # Add at the end of the load_environment function: return config Update config/middleware.py to use the returned :term:`config`:: # modify the load_environment call: config = load_environment(global_conf, app_conf) # update the middleware calls # The Pylons WSGI app app = PylonsApp(config=config) # Routing/Session/Cache Middleware app = RoutesMiddleware(app, config['routes.map']) app = SessionMiddleware(app, config) # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) # Add right before 'return app': app.config = config .. note:: The CacheMiddleware is no longer setup by default through middleware, its now setup under :term:`app_globals` inside its instantiation in :file:`lib/app_globals.py`. Update config/routing.py to accept the :term:`config`:: # Replace the def line with def make_map(config): Update lib/app_globals.py to accept the :term:`config`:: # Replace the __init__ line with def __init__(self, config): # Optionally, if you decided to remove the CacheMiddleware # Add these imports from beaker.cache import CacheManager from beaker.util import parse_cache_config_options # and add this line in __init__: self.cache = CacheManager(**parse_cache_config_options(config)) Update tests/__init__.py as needed:: from unittest import TestCase from paste.deploy import loadapp from paste.script.appinstall import SetupCommand from pylons import url from routes.util import URLGenerator from webtest import TestApp import pylons.test __all__ = ['environ', 'url', 'TestController'] # Invoke websetup with the current config file SetupCommand('setup-app').run([pylons.test.pylonsapp.config['__file__']]) environ = {} class TestController(TestCase): def __init__(self, *args, **kwargs): wsgiapp = pylons.test.pylonsapp config = wsgiapp.config self.app = TestApp(wsgiapp) url._push_object(URLGenerator(config['routes.map'], environ)) TestCase.__init__(self, *args, **kwargs) .. note:: Change the use of ``url_for`` in your tests to use :class:`url `, which is imported from :file:`tests/__init__.py` in your unit tests. Finally, update websetup.py to avoid the duplicate app creation that previously could occur during the unit tests:: # Add to the imports import pylons.test # Add under the 'def setup_app': # Don't reload the app if it was loaded under the testing environment if not pylons.test.pylonsapp: load_environment(conf.global_conf, conf.local_conf) * Change all instances of ``redirect_to(...)`` -> ``redirect(url(...))`` ``redirect_to`` processed arguments in a slightly 'magical' manner in that some of them went to the ``url_for`` while sometimes... not. :func:`~pylons.controllers.util.redirect` issues a redirect and nothing more, so to generate a url, the :class:`url ` instance should be used (import: ``from pylons import url``). * Ensure that all use of ``g`` is switched to using the new name, :term:`app_globals` * Change all instances of ``url_for`` to :class:`url `. Note that ``url`` does not retain the current route memory like ``url_for`` did by default. To get a route generated using the current route, call :meth:`url.current `. For example:: # Rather than url_for() for the current route url.current() :class:`url ` can be imported from ``pylons``. * Change ``config`` import statement if needed Previously, the config object could be imported as if it was a module:: import pylons.config The config object is now an object in :file:`pylons/__init__.py` so the import needs to be changed to:: from pylons import config * Routes is now explicit by default This won't affect those already using :class:`url ` as it ignores route memory. This change does mean that some routes which relied on a default controller of 'content' and a default action of 'index' will not work. To restore the old behavior, in :file:`config/routing.py`, set the mapper to explicit:: map.explicit = True * By default, the :term:`tmpl_context` (a.k.a 'c'), is no longer a :class:`~pylons.util.AttribSafeContextObj`. This means accessing attributes that don't exist will raise an :exc:`AttributeError`. To use the attribute-safe :term:`tmpl_context`, add this line to the :file:`config/environment.py`:: config['pylons.strict_tmpl_context'] = False Pylons-1.0.1/pylons/docs/en/views.rst0000664000076500000240000003564511645401275017455 0ustar benstaff00000000000000.. _views: ===== Views ===== .. image:: _static/pylon4.jpg :alt: :align: left :height: 434px :width: 368px In the MVC paradigm the *view* manages the presentation of the model. The view is the interface the user sees and interacts with. For Web applications, this has historically been an HTML interface. HTML remains the dominant interface for Web apps but new view options are rapidly appearing. These include Macromedia Flash, JSON and views expressed in alternate markup languages like XHTML, XML/XSL, WML, and Web services. It is becoming increasingly common for web apps to provide specialised views in the form of a REST API that allows programmatic read/write access to the data model. More complex APIs are quite readily implemented via SOAP services, yet another type of view on to the data model. The growing adoption of RDF, the graph-based representation scheme that underpins the Semantic Web, brings a perspective that is strongly weighted towards machine-readability. .. NOTE: As much as I love RDF I think the following paragraph is too verbose for our intro docs, maybe we can put this elsewhere -pjenvey .. RDF model data is serialized into an undecorated, standardized format that can readily be processed and rendered by client applications of increasing sophistication, such as the MIT `Simile`__ project's "`Fresnel`__", "`Longwell`__" and "`Welkin`__" browser extensions. .. .. __: http://simile.mit.edu/ .. .. __: http://simile.mit.edu/fresnel/ .. .. __: http://simile.mit.edu/longwell/ .. .. __: http://simile.mit.edu/welkin/ Handling all of these interfaces in an application is becoming increasingly challenging. One big advantage of MVC is that it makes it easier to create these interfaces and develop a web app that supports many different views and thereby provides a broad range of services. Typically, no significant processing occurs in the view; it serves only as a means of outputting data and allowing the user (or the application) to act on that data, irrespective of whether it is an online store or an employee list. .. _templates: ********* Templates ********* Template rendering engines are a popular choice for handling the task of view presentation. To return a processed template, it must be rendered and returned by the controller:: from helloworld.lib.base import BaseController, render class HelloController(BaseController): def sample(self): return render('/sample.mako') Using the default Mako template engine, this will cause Mako to look in the :file:`helloworld/templates` directory (assuming the project is called 'helloworld') for a template filed called :file:`sample.mako`. The :func:`render` function used here is actually an alias defined in your projects' :file:`base.py` for Pylons' :func:`~pylons.templating.render_mako` function. Directly-supported template engines =================================== Pylons provides pre-configured options for using the `Mako`__, `Genshi`__ and `Jinja2`__ template rendering engines. They are setup automatically during the creation of a new Pylons project, or can be added later manually. .. __: http://www.makotemplates.org/ .. __: http://genshi.edgewall.org/ .. __: http://jinja.pocoo.org/ ****************************** Passing Variables to Templates ****************************** To pass objects to templates, the standard Pylons method is to attach them to the :term:`tmpl_context` (aliased as `c` in controllers and templates, by default) object in the :ref:`controllers`:: import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect from helloworld.lib.base import BaseController, render log = logging.getLogger(__name__) class HelloController(BaseController): def index(self): c.name = "Fred Smith" return render('/sample.mako') Using the variable in the template: .. code-block:: html+mako Hi there ${c.name}! Strict vs Attribute-Safe tmpl_context objects ============================================= The :term:`tmpl_context` object is created at the beginning of every request, and by default is an instance of the :class:`~pylons.util.AttribSafeContextObj` class, which is an Attribute-Safe object. This means that accessing attributes on it that do **not** exist will return an empty string **instead** of raising an :exc:`AttributeError` error. This can be convenient for use in templates since it can act as a default: .. code-block:: html+mako Hi there ${c.name} That will work when `c.name` has not been set, and is a bit shorter than what would be needed with the strict :class:`~pylons.util.ContextObj` context object. Switching to the strict version of the :term:`tmpl_context` object can be done in the :file:`config/environment.py` by adding (after the config.init_app):: config['pylons.strict_c'] = True .. _template-globals: ************************** Default Template Variables ************************** By default, all templates have a set of variables present in them to make it easier to get to common objects. The full list of available names present in the templates global scope: - :term:`c` -- Template context object (Alias for :term:`tmpl_context`) - :term:`tmpl_context` -- Template context object - :data:`config` -- Pylons :class:`~pylons.configuration.PylonsConfig` object (acts as a dict) - :term:`g` -- Project application globals object (Alias for :term:`app_globals`) - :term:`app_globals` -- Project application globals object - :term:`h` -- Project helpers module reference - :data:`request` -- Pylons :class:`~pylons.controllers.util.Request` object for this request - :data:`response` -- Pylons :class:`~pylons.controllers.util.Response` object for this request - :class:`session` -- Pylons session object (unless Sessions are removed) - :class:`translator` -- Gettext translator object configured for current locale - :func:`ungettext` -- Unicode capable version of gettext's ngettext function (handles plural translations) - :func:`_` -- Unicode capable gettext translate function - :func:`N_` -- gettext no-op function to mark a string for translation, but doesn't actually translate - :class:`url ` -- An instance of the :class:`routes.util.URLGenerator` configured for this request. **************************** Configuring Template Engines **************************** A new Pylons project comes with the template engine setup inside the projects' :file:`config/environment.py` file. This section creates the Mako template lookup object and attaches it to the :term:`app_globals` object, for use by the template rendering function. .. code-block:: python # these imports are at the top from mako.lookup import TemplateLookup from pylons.error import handle_mako_error # this section is inside the load_environment function # Create the Mako TemplateLookup, with the default auto-escaping config['pylons.app_globals'].mako_lookup = TemplateLookup( directories=paths['templates'], error_handler=handle_mako_error, module_directory=os.path.join(app_conf['cache_dir'], 'templates'), input_encoding='utf-8', default_filters=['escape'], imports=['from webhelpers.html import escape']) Using Multiple Template Engines =============================== Since template engines are configured in the :file:`config/environment.py` section, then used by render functions, it's trivial to setup additional template engines, or even differently configured versions of a single template engine. However, custom render functions will frequently be needed to utilize the additional template engine objects. Example of additional Mako template loader for a different templates directory for admins, which falls back to the normal templates directory:: # Add the additional path for the admin template paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')], admintemplates=[os.path.join(root, 'admintemplates'), os.path.join(root, 'templates')]) config['pylons.app_globals'].mako_admin_lookup = TemplateLookup( directories=paths['admin_templates'], error_handler=handle_mako_error, module_directory=os.path.join(app_conf['cache_dir'], 'admintemplates'), input_encoding='utf-8', default_filters=['escape'], imports=['from webhelpers.html import escape']) That adds the additional template lookup instance, next a :ref:`custom render function ` is needed that utilizes it:: from pylons.templating import cached_template, pylons_globals def render_mako_admin(template_name, extra_vars=None, cache_key=None, cache_type=None, cache_expire=None): # Create a render callable for the cache function def render_template(): # Pull in extra vars if needed globs = extra_vars or {} # Second, get the globals globs.update(pylons_globals()) # Grab a template reference template = globs['app_globals'].mako_admin_lookup.get_template(template_name) return template.render(**globs) return cached_template(template_name, render_template, cache_key=cache_key, cache_type=cache_type, cache_expire=cache_expire) The only change from the :func:`~pylons.templating.render_mako` function that comes with Pylons is to use the `mako_admin_lookup` rather than the `mako_lookup` that is used by default. .. _custom-render: ******************************* Custom :func:`render` functions ******************************* Writing custom render functions can be used to access specific features in a template engine, such as Genshi, that go beyond the default :func:`~pylons.templating.render_genshi` functionality or to add support for additional template engines. Two helper functions for use with the render function are provided to make it easier to include the common Pylons globals that are useful in a template in addition to enabling easy use of cache capabilities. The :func:`pylons_globals` and :func:`cached_template` functions can be used if desired. Generally, the custom render function should reside in the project's ``lib/`` directory, probably in :file:`base.py`. Here's a sample Genshi render function as it would look in a project's ``lib/base.py`` that doesn't fully render the result to a string, and rather than use :data:`c` assumes that a dict is passed in to be used in the templates global namespace. It also returns a Genshi stream instead the rendered string. .. code-block:: python from pylons.templating import pylons_globals def render(template_name, tmpl_vars): # First, get the globals globs = pylons_globals() # Update the passed in vars with the globals tmpl_vars.update(globs) # Grab a template reference template = globs['app_globals'].genshi_loader.load(template_name) # Render the template return template.generate(**tmpl_vars) Using the :func:`~pylons.templating.pylons_globals` function also makes it easy to get to the :term:`app_globals` object which is where the template engine was attached in :file:`config/environment.py`. .. versionchanged:: 0.9.7 Prior to 0.9.7, all templating was handled through a layer called 'Buffet'. This layer frequently made customization of the template engine difficult as any customization required additional plugin modules being installed. Pylons 0.9.7 now deprecates use of the Buffet plug-in layer. .. seealso:: :mod:`pylons.templating` - Pylons templating API ******************** Templating with Mako ******************** Introduction ============ The template library deals with the *view*, presenting the model. It generates (X)HTML code, CSS and Javascript that is sent to the browser. *(In the examples for this section, the project root is ``myapp``.)* Static vs. dynamic ------------------ Templates to generate dynamic web content are stored in `myapp/templates`, static files are stored in `myapp/public`. Both are served from the server root, **if there is a name conflict the static files will be served in preference** Making a template hierarchy =========================== Create a base template ---------------------- In `myapp/templates` create a file named `base.mako` and edit it to appear as follows: .. code-block:: html+mako ${self.head_tags()} ${self.body()} A base template such as the very basic one above can be used for all pages rendered by Mako. This is useful for giving a consistent look to the application. * Expressions wrapped in `${...}` are evaluated by Mako and returned as text * `${` and `}` may span several lines but the closing brace should not be on a line by itself (or Mako throws an error) * Functions that are part of the `self` namespace are defined in the Mako templates Create child templates ---------------------- Create another file in `myapp/templates` called `my_action.mako` and edit it to appear as follows: .. code-block:: html+mako <%inherit file="/base.mako" /> <%def name="head_tags()">

My Controller

Lorem ipsum dolor ...

This file define the functions called by `base.mako`. * The `inherit` tag specifies a parent file to pass program flow to * Mako defines functions with `<%def name="function_name()">...`, the contents of the tag are returned * Anything left after the Mako tags are parsed out is automatically put into the `body()` function A consistent feel to an application can be more readily achieved if all application pages refer back to single file (in this case `base.mako`).. Check that it works ------------------- In the controller action, use the following as a `return()` value, .. code-block:: python return render('/my_action.mako') Now run the action, usually by visiting something like ``http://localhost:5000/my_controller/my_action`` in a browser. Selecting 'View Source' in the browser should reveal the following output: .. code-block:: html

My Controller

Lorem ipsum dolor ...

.. seealso:: The `Mako documentation `_ Reasonably straightforward to follow See the :ref:`i18n` Provides more help on making your application more worldly. Pylons-1.0.1/pylons/docs/en/windowsnotes.rst0000664000076500000240000000543011645401275021050 0ustar benstaff00000000000000.. _windows_notes: ============= Windows Notes ============= Python scripts installed as part of the Pylons install process will be put in the ``Scripts`` directory of your Python installation, typically in ``C:\Python24\Scripts``. By default on Windows, this directory is not in your ``PATH``; this can cause the following error message when running a command such as ``paster`` from the command prompt: .. code-block:: text C:\Documents and Settings\James>paster 'paster' is not recognized as an internal or external command, operable program or batch file. To run the scripts installed with Pylons either the full path must be specified: .. code-block:: text C:\Documents and Settings\James>C:\Python24\Scripts\paster Usage: C:\Python24\Scripts\paster-script.py COMMAND usage: paster-script.py [paster_options] COMMAND [command_options] options: --version show program's version number and exit --plugin=PLUGINS Add a plugin to the list of commands (plugins are Egg specs; will also require() the Egg) -h, --help Show this help message ... etc ... or (the preferable solution) the ``Scripts`` directory must be added to the ``PATH`` as described below. For Win2K or WinXP ------------------ #. From the desktop or Start Menu, right click My Computer and click Properties. #. In the System Properties window, click on the Advanced tab. #. In the Advanced section, click the Environment Variables button. #. Finally, in the Environment Variables window, highlight the path variable in the Systems Variable section and click edit. Add or modify the path lines with the paths you wish the computer to access. Each different directory is separated with a semicolon as shown below: .. code-block:: text C:\Program Files;C:\WINDOWS;C:\WINDOWS\System32 #. Add the path to your scripts directory: .. code-block:: text C:\Program Files;C:\WINDOWS;C:\WINDOWS\System32;C:\Python24\Scripts See `Finally`_ below. For Windows 95, 98 and ME ------------------------- Edit ``autoexec.bat``, and add the following line to the end of the file: .. code-block:: bash set PATH=%PATH%;C:\Python24\Scripts See `Finally`_ below. Finally ------- Restarting your computer may be required to enable the change to the ``PATH``. Then commands may be entered from any location: .. code-block:: text C:\Documents and Settings\James>paster Usage: C:\Python24\Scripts\paster-script.py COMMAND usage: paster-script.py [paster_options] COMMAND [command_options] options: --version show program's version number and exit --plugin=PLUGINS Add a plugin to the list of commands (plugins are Egg specs; will also require() the Egg) -h, --help Show this help message ... etc ... All documentation assumes the ``PATH`` is setup correctly as described above. Pylons-1.0.1/pylons/docs/en/wsgi_support.rst0000664000076500000240000002170411645401275021054 0ustar benstaff00000000000000.. _wsgi_support: ============ WSGI support ============ The Web Server Gateway Interface `defined in PEP 333 `_ is a standard interface between web servers and Python web applications or frameworks, to promote web application portability across a variety of web servers. Pylons supports the Web Server Gateway Interface (or WSGI for short, pronounced "wizgy") throughout its stack. This is important for developers because it means that as well coming with all the features you would expect of a modern web framework, Pylons is also extremely flexible. With the WSGI it is possible to change any part of the Pylons stack to add new functionality or modify a request or a response without having to take apart the whole framework. Paste and WSGI -------------- Most of Pylons' WSGI capability comes from its close integration with Paste. Paste provides all the tools and middleware necessary to deploy WSGI applications. It can be thought of as a low-level WSGI framework designed for other web frameworks to build upon. Pylons is an example of a framework which makes full use of the possibilities of Paste. If you want to, you can get the WSGI application object from your Pylons configuration file like this: .. code-block:: python from paste.deploy import loadapp wsgi_app = loadapp('config:/path/to/config.ini') You can then serve the file using a WSGI server. Here is an example using the WSGI Reference Implementation included with Python 2.5: .. code-block:: python from paste.deploy import loadapp wsgi_app = loadapp('config:/path/to/config.ini') from wsgiref import simple_server httpd = simple_server.WSGIServer(('',8000), simple_server.WSGIRequestHandler) httpd.set_app(wsgi_app) httpd.serve_forever() The ``paster serve`` command you will be used to using during the development of Pylons projects combines these two steps of creating a WSGI app from the config file and serving the resulting file to give the illusion that it is serving the config file directly. Because the resulting Pylons application is a WSGI application it means you can do the same things with it that you can do with any WSGI application. For example add a middleware chain to it or serve it via FastCGI/SCGI/CGI/mod_python/AJP or standalone. You can also configure extra WSGI middleware, applications and more directly using the configuration file. The various options are described in the `Paste Deploy Documentation `_ so we won't repeat them here. Using a WSGI Application as a Pylons 0.9 Controller --------------------------------------------------- In Pylons 0.9 controllers are derived from ``pylons.controllers.WSGIController`` and are also valid WSGI applications. Unless your controller is derived from the legacy ``pylons.controllers.Controller`` class it is also assumed to be a WSGI application. This means that you don't actually need to use a Pylons controller class in your controller, any WSGI application will work as long as you give it the same name. For example, if you added a ``hello`` controller by executing ``paster controller hello``, you could modify it to look like this: .. code-block:: python def HelloController(environ, start_response): start_response('200 OK', [('Content-Type','text/html')]) return ['Hello World!'] or use ``yield`` statements like this: .. code-block:: python def HelloController(environ, start_response): start_response('200 OK', [('Content-Type','text/html')]) yield 'Hello ' yield 'World!' or use the standard Pylons ``Response`` object which is a valid WSGI response which takes care of calling ``start_response()`` for you: .. code-block:: python def HelloController(environ, start_response): return Response('Hello World!') and you could use the ``render()`` and ``render_response()`` objects exactly like you would in a normal controller action. As well as writing your WSGI application as a function you could write it as a class: .. code-block:: python class HelloController: def __call__(self, environ, start_response): start_response('200 OK', [('Content-Type','text/html')]) return ['Hello World!'] All the standard Pylons middleware defined in ``config/middleware.py`` is still available. Running a WSGI Application From Within a Controller --------------------------------------------------- There may be occasions where you don't want to replace your entire controller with a WSGI application but simply want to run a WSGI application from with a controller action. If your project was called ``test`` and you had a WSGI application called ``wsgi_app`` you could even do this: .. code-block:: python from test.lib.base import * def wsgi_app(environ, start_response): start_response('200 OK',[('Content-type','text/html')]) return ['\n\nHello World!\n\n'] class HelloController(BaseController): def index(self): return wsgi_app(request.environ, self.start_response) Configuring Middleware Within a Pylons Application -------------------------------------------------- A Pylons application middleware stack is directly exposed in the project's ``config/middleware.py`` file. This means that you can add and remove pieces from the stack as you choose. .. Warning:: If you remove any of the default middleware you are likely to find that various parts of Pylons stop working! As an example, if you wanted to add middleware that added a new key to the environ dictionary you might do this: .. code-block:: python # YOUR MIDDLEWARE # Put your own middleware here, so that any problems are caught by the error # handling middleware underneath class KeyAdder: def __init__(self, app, key, value): self.app = app if '.' not in key: raise Exception("WSGI environ keys must contain a '.' character") self.key = key self.value = value def __call__(self, environ, start_response): environ[self.key] = self.value return self.app(environ, start_response) app = KeyAdder(app, 'test.hello', 'Hello World') Then in your controller you could write: .. code-block:: python return Response(request.environ['test.hello']) and you would see your ``Hello World!`` message. Of course, this isn't a particularly useful thing to do. Middleware classes can do one of four things or a combination of them: * Change the environ dictionary * Change the status * Change the HTTP headers * Change the response body of the application With the ability to do these things as a middleware you can create authentication code, error handling middleware and more but the great thing about WSGI is that someone probably already has so you can consult the `wsgi.org middleware list `_ or have a look at the `Paste project `_ and reuse an exisiting piece of middleware. The Cascade ----------- Towards the end of the middleware stack in your project's ``config/middleware.py`` file you will find a special piece of middleware called the cascade: .. code-block:: python app = Cascade([static_app, javascripts_app, app]) Passed a list of applications, ``Cascade`` will try each of them in turn. If one returns a 404 status code then the next application is tried until one of the applications returns a code other than ``404`` in which case its response is returned. If all applications fail, then the last application's failure response is used. The three WSGI applications in the cascade serve files from your project's ``public`` directory first then if nothing matches, the WebHelpers module JavaScripts are searched and finally if no JavaScripts are found your Pylons app is tried. This is why the ``public/index.html`` file is served before your controller is executed and why you can put ``/javascripts/`` into your HTML and the files will be found. You are free to change the order of the cascade or add extra WSGI applications to it before ``app`` so that other locations are checked before your Pylons application is executed. Useful Resources ---------------- Whilst other frameworks have put WSGI adapters at the end of their stacks so that their applications can be served by WSGI servers, we hope you can see how fully Pylons embraces WSGI throughout its design to be the most flexible and extensible of the main Python web frameworks. To find out more about the Web Server Gateway Interface you might find the following resources useful: * `PEP 333 `_ * `The WSGI website at wsgi.org `_ * XML.com articles: Introducing WSGI - Pythons Secret Web Weapon.html `Part 1 `_ `Part 2 `_ Pylons-1.0.1/pylons/docs/uploader.py0000664000076500000240000000716411645401276017345 0ustar benstaff00000000000000import cPickle import mimetypes import os import sys import socket from os import path import httplib2 import simplejson socket.setdefaulttimeout(60) HERE_DIR = os.getcwd() BUILD_DIR = path.join(HERE_DIR, '_build') #host = 'http://localhost:25050' host = 'http://pylonshq.com' post_uri = '%s/docs/upload' % host image_uri = '%s/docs/upload_image' % host delete_uri = '%s/docs/delete_revision' % host def scan_dir(parent, directory): files = [] for name in os.listdir(directory): full_name = path.join(directory, name) if name in ['_sources', '_static']: continue if path.isdir(full_name): new_parent = parent + '/' + name files.extend(scan_dir(new_parent, full_name)) else: if name.endswith('.fpickle') or name.endswith('.pickle'): fp = open(full_name, 'r') data = cPickle.load(fp) fp.close() files.append( ('/'.join([parent, name]), data) ) elif name == 'objects.inv': fp = open(full_name, 'r') data = {} data['current_page_name'] = 'objects.inv' data['content'] = fp.read() fp.close() files.append( ('/'.join([parent, name]), data) ) return files def scan_images(directory): files = [] for name in os.listdir(directory): if name[-4:] in ['.png', '.jpg', 'gif']: files.append(name) return files files = scan_dir('', path.join(BUILD_DIR, 'web')) images = scan_images(path.join(BUILD_DIR, 'web', '_images')) http = httplib2.Http(timeout=60) basedata = {} # Find the metadata about versions and such for filename, filedoc in files: if 'globalcontext.pickle' in filename: basedata['version'] = filedoc['version'] basedata['project'] = filedoc['project'] basedata['shorttitle'] = filedoc['shorttitle'] if len(sys.argv) < 2: raise Exception('Failed to specify doc-key') dockey = sys.argv[1] headers = {} headers.setdefault('Accept', 'application/json') headers.setdefault('User-Agent', 'Doc Uploader') headers.setdefault('Content-Type', 'application/json') headers.setdefault('Authkey', dockey) language = os.path.split(HERE_DIR)[-1] # Delete this revision, just in case # del_uri = '%s/%s/%s' % (delete_uri, basedata['project'], basedata['version']) # resp, data = http.request(del_uri, 'GET', headers=headers) for filename, filedoc in files: if not isinstance(filedoc, dict): continue filedoc['filename'] = filename filedoc['language'] = language filedoc.update(basedata) content = simplejson.dumps(filedoc, ensure_ascii=False).encode('utf-8') headers['Content-Length'] = str(len(content)) resp, data = http.request(post_uri, 'POST', body=content, headers=headers) status_code = int(resp.status) if status_code == 200: print "Uploaded %s" % filename else: print "FAILED: %s" % filename for filename in images: headers['Content-Type'] = mimetypes.guess_type(filename) fp = open(path.join(BUILD_DIR, 'web', '_images', filename), 'r') file_content = fp.read() fp.close() headers['Content-Length'] = str(len(file_content)) resp, data = http.request(image_uri + '?version=%s&project=%s&name=%s' % (basedata['version'], basedata['project'], filename), 'POST', body=file_content, headers=headers) status_code = int(resp.status) if status_code == 200: print "Uploaded %s" % filename else: print "FAILED: %s" % filename Pylons-1.0.1/pylons/error.py0000664000076500000240000000225111671742121015717 0ustar benstaff00000000000000"""Custom EvalException support Provides template engine HTML error formatters for the Template tab of EvalException. """ import sys try: import mako.exceptions except ImportError: mako = None __all__ = ['handle_mako_error'] def handle_mako_error(context, exc): try: exc.is_mako_exception = True except: pass raise (exc, None, sys.exc_info()[2]) def myghty_html_data(exc_value): """Format a Myghty exception as HTML""" if hasattr(exc_value, 'htmlformat'): return exc_value.htmlformat()[333:-14] if hasattr(exc_value, 'mtrace'): return exc_value.mtrace.htmlformat()[333:-14] template_error_formatters = [myghty_html_data] if mako: def mako_html_data(exc_value): """Format a Mako exception as HTML""" if getattr(exc_value, 'is_mako_exception', False) or \ isinstance(exc_value, (mako.exceptions.CompileException, mako.exceptions.SyntaxException)): return mako.exceptions.html_error_template().render(full=False, css=False) template_error_formatters.insert(0, mako_html_data) Pylons-1.0.1/pylons/i18n/0000775000076500000240000000000012012307216014763 5ustar benstaff00000000000000Pylons-1.0.1/pylons/i18n/__init__.py0000664000076500000240000000014011645401276017103 0ustar benstaff00000000000000"""Internationalization and Localization functionality""" from pylons.i18n.translation import * Pylons-1.0.1/pylons/i18n/translation.py0000664000076500000240000001337011671741616017717 0ustar benstaff00000000000000"""Translation/Localization functions. Provides :mod:`gettext` translation functions via an app's ``pylons.translator`` and get/set_lang for changing the language translated to. """ import os from gettext import NullTranslations, translation import pylons __all__ = ['_', 'add_fallback', 'get_lang', 'gettext', 'gettext_noop', 'lazy_gettext', 'lazy_ngettext', 'lazy_ugettext', 'lazy_ungettext', 'ngettext', 'set_lang', 'ugettext', 'ungettext', 'LanguageError', 'N_'] class LanguageError(Exception): """Exception raised when a problem occurs with changing languages""" pass class LazyString(object): """Has a number of lazily evaluated functions replicating a string. Just override the eval() method to produce the actual value. This method copied from TurboGears. """ def __init__(self, func, *args, **kwargs): self.func = func self.args = args self.kwargs = kwargs def eval(self): return self.func(*self.args, **self.kwargs) def __unicode__(self): return unicode(self.eval()) def __str__(self): return str(self.eval()) def __mod__(self, other): return self.eval() % other def format(self, *args): return self.eval().format(*args) def lazify(func): """Decorator to return a lazy-evaluated version of the original""" def newfunc(*args, **kwargs): return LazyString(func, *args, **kwargs) newfunc.__name__ = 'lazy_%s' % func.__name__ newfunc.__doc__ = 'Lazy-evaluated version of the %s function\n\n%s' % \ (func.__name__, func.__doc__) return newfunc def gettext_noop(value): """Mark a string for translation without translating it. Returns value. Used for global strings, e.g.:: foo = N_('Hello') class Bar: def __init__(self): self.local_foo = _(foo) h.set_lang('fr') assert Bar().local_foo == 'Bonjour' h.set_lang('es') assert Bar().local_foo == 'Hola' assert foo == 'Hello' """ return value N_ = gettext_noop def gettext(value): """Mark a string for translation. Returns the localized string of value. Mark a string to be localized as follows:: gettext('This should be in lots of languages') """ return pylons.translator.gettext(value) lazy_gettext = lazify(gettext) def ugettext(value): """Mark a string for translation. Returns the localized unicode string of value. Mark a string to be localized as follows:: _('This should be in lots of languages') """ return pylons.translator.ugettext(value) _ = ugettext lazy_ugettext = lazify(ugettext) def ngettext(singular, plural, n): """Mark a string for translation. Returns the localized string of the pluralized value. This does a plural-forms lookup of a message id. ``singular`` is used as the message id for purposes of lookup in the catalog, while ``n`` is used to determine which plural form to use. The returned message is a string. Mark a string to be localized as follows:: ngettext('There is %(num)d file here', 'There are %(num)d files here', n) % {'num': n} """ return pylons.translator.ngettext(singular, plural, n) lazy_ngettext = lazify(ngettext) def ungettext(singular, plural, n): """Mark a string for translation. Returns the localized unicode string of the pluralized value. This does a plural-forms lookup of a message id. ``singular`` is used as the message id for purposes of lookup in the catalog, while ``n`` is used to determine which plural form to use. The returned message is a Unicode string. Mark a string to be localized as follows:: ungettext('There is %(num)d file here', 'There are %(num)d files here', n) % {'num': n} """ return pylons.translator.ungettext(singular, plural, n) lazy_ungettext = lazify(ungettext) def _get_translator(lang, **kwargs): """Utility method to get a valid translator object from a language name""" if not lang: return NullTranslations() if 'pylons_config' in kwargs: conf = kwargs.pop('pylons_config') else: conf = pylons.config.current_conf() localedir = os.path.join(conf['pylons.paths']['root'], 'i18n') if not isinstance(lang, list): lang = [lang] try: translator = translation(conf['pylons.package'], localedir, languages=lang, **kwargs) except IOError, ioe: raise LanguageError('IOError: %s' % ioe) translator.pylons_lang = lang return translator def set_lang(lang, set_environ=True, **kwargs): """Set the current language used for translations. ``lang`` should be a string or a list of strings. If a list of strings, the first language is set as the main and the subsequent languages are added as fallbacks. """ translator = _get_translator(lang, **kwargs) if not set_environ: return translator environ = pylons.request.environ environ['pylons.pylons'].translator = translator if 'paste.registry' in environ: environ['paste.registry'].replace(pylons.translator, translator) def get_lang(): """Return the current i18n language used""" return getattr(pylons.translator, 'pylons_lang', None) def add_fallback(lang, **kwargs): """Add a fallback language from which words not matched in other languages will be translated to. This fallback will be associated with the currently selected language -- that is, resetting the language via set_lang() resets the current fallbacks. This function can be called multiple times to add multiple fallbacks. """ return pylons.translator.add_fallback(_get_translator(lang, **kwargs)) Pylons-1.0.1/pylons/log.py0000664000076500000240000000502411671742141015352 0ustar benstaff00000000000000"""Logging related functionality This logging Handler logs to ``environ['wsgi.errors']`` as designated in :pep:`333`. """ import logging import types import pylons __all__ = ['WSGIErrorsHandler'] class WSGIErrorsHandler(logging.Handler): """A handler class that writes logging records to `environ['wsgi.errors']`. This code is derived from CherryPy's :class:`cherrypy._cplogging.WSGIErrorHandler`. ``cache`` Whether the `wsgi.errors` stream is cached (instead of looked up via `pylons.request.environ` per every logged message). Enabling this option is not recommended (particularly for the use case of logging to `wsgi.errors` outside of a request) as the behavior of a cached `wsgi.errors` stream is not strictly defined. In particular, `mod_wsgi `_'s `wsgi.errors` will raise an exception when used outside of a request. """ def __init__(self, cache=False, *args, **kwargs): logging.Handler.__init__(self, *args, **kwargs) self.cache = cache self.cached_stream = None def get_wsgierrors(self): """Return the wsgi.errors stream Raises a TypeError when outside of a web request (pylons.request is not setup) """ if not self.cache: return pylons.request.environ.get('wsgi.errors') elif not self.cached_stream: self.cached_stream = pylons.request.environ.get('wsgi.errors') return self.cached_stream return self.cached_stream def flush(self): """Flushes the stream""" try: stream = self.get_wsgierrors() except TypeError: pass else: if stream: stream.flush() def emit(self, record): """Emit a record""" try: stream = self.get_wsgierrors() except TypeError: pass else: if not stream: return try: msg = self.format(record) fs = "%s\n" if not hasattr(types, "UnicodeType"): # if no unicode support stream.write(fs % msg) else: try: stream.write(fs % msg) except UnicodeError: stream.write(fs % msg.encode("UTF-8")) self.flush() except (KeyboardInterrupt, SystemExit): raise except: self.handleError(record) Pylons-1.0.1/pylons/media/0000775000076500000240000000000012012307216015263 5ustar benstaff00000000000000Pylons-1.0.1/pylons/media/img/0000775000076500000240000000000012012307216016037 5ustar benstaff00000000000000Pylons-1.0.1/pylons/media/img/bar-bg.png0000664000076500000240000000077611645401276017725 0ustar benstaff00000000000000PNG  IHDRfmF,tEXtCreation TimeSat 26 Nov 2005 00:07:39 -000088tIME 0"5 H pHYs B4gAMA aUIDATxIR0ENێ 8(0d `QEUҫzb Zk ˭,ּ2_ɁU#V{Oz/;l9B}|ϖ4n90ͱk >}v~jܞU;d 'i|]*e}bHv7̀WwW<03- p{q)ۇq(KeO ׏'Y$)L#}+lyYk+%F)5GTV@48sa>{S{US/?2IENDB`Pylons-1.0.1/pylons/media/img/bg.jpg0000664000076500000240000002450711645401276017155 0ustar benstaff00000000000000JFIFddDuckyXAdobed  Yc  a!Q1qA"2Br#3R$tu6b457cs%!1AQaq ?Wl)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l)l`:YdhMLLn9Tg>EAo{^ø!`eZݏ88y~*enfb ܬnǵoeo"]2+񠻝6Oi {$Cxbe"۱ꐼ|(-0w$}q, D\m80su,tA 8!M= З+bϲ;s)Z#&Ecc|lG iF4%CE# ]&:3cz>pbv wQ>GH$3a+CD5B?u#B9ҒM:,ionNzy'`%͓:Yڟ+%i*`0d.ײeoC (O[tc^jUfўf 4tZ:F립#C⨿Ն2 ks.*kq6Bg3taˎ5(aݗ/t wLn8kꠇv.! 6k Z杆y1b# {0cTr1} ͷ>3Ƭ$Ƀ)ۮ_báE$<ЙDOwl]S0B>*;VmtR7ɒ?T[vow iВ᧭ZtQf4h%AB7:Pw R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q@E (P(Q@E (P(Q@E (P(Q@GRv=_ ^zyQ#GƪPun4xyYIX˾韲zӫu6ݣ]{sjMRas I^9P|1 <A]_̓ LJd|:2-w u# m#RY nle"Ǿ?#Cq>#O$bۼIa/#4|0BYbY{׈{y9̡ ɑW#TTAqa!tP-$ODWퟃMa5^+]!HOJ6pZyyBn3|"թcBbe_G"ѥ˄>]#ѰkBWJwDdcӛxvt/d63** GF/?,7$PƖʊY[1kâǽQ.vs#OAe3)ᰴaVΧ|@\J-B=P>a}>@E (P(Q@E (P(Q@E (P(Q@E (P(Q@E (P(Q@E (P(( !@( !@( !@( !@( !@( !@( !A598" (~KZ$hAc.pk Q{&X>!2'8H4#w:{k7~8џpe{~XGI` x>B'BG$@GTRa3kZj#l#xl8&n23/k924tS A}N{fCHng|IɴetrGFu:Ag52鰰ٮ$9ah hsX8bZKE 8v^ǭ@:䂵t,2ݱnSk;Ds~u$NL]r. )@ђ C$|]<°[lEԦ~wɆ>V'q<v:8m52\4xgUi-a3@cdcF駙g=ٽ?]$m䱹+# 4<|fܢ@wc6DZ:-.kNQ,zmldw$Lu05eh? :9\a|n)['S\4sLr0VkIݛO+eth5 3^ctf0鿲/ P)lPy{qw̼m8 uj[ us:{8ݒ\[L66N:ߪz 簖W&o)x ɣtofYLOw &(Gd ; Qv@(Gd ; Qv@(Gd ; Qv@(Gd ; Q:崎xcƤ{ ķ22SgvA,cϣh,z5өrAZn1һ L3'H<0~aF18pu Ѥ!h=J/TvP(Gd^DDl8H:5iGj`c2٧]J&$4yq$R.ֶmt_{ <3[()_SmZHن"y!v=9nU4C)vF~niZ֗COVϧr#1XˉVV+'H fN%(>d,H;\V h  v= Il^֖ۮc+. LKKk.̾%$\SKz;<6:(,FH?x _1pKwGG4v@(Gd ; Qv@(Gd ; Qv@(Gd ; Qv@(Gd ; Qv@(Gd ; Qv@(Gd ; Q-KbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKbKb͗1:'4 ^qU]kp2A~AKbZ:9C#y&htI4 c-gVR.G4ԟ&6.cB쥱Au-wr{kv3kG(5j_[nZ7t\nt8Sm]AW?'ᦊ̳3tt8:<4G%oq8n$:8?Iyy'udlS'm6Z[&|tZVd7_%-&1B_›\t5mpdñ?0gzz$k[lyl7qJۻ fZhaԽޡ̐} U#i83ť0NZ-t/-av)m},kK{84DCuܗYo\7]mwhH-wKii ^V E<&wtp׃`KC}w~WVk@=8,ָjH gbk,ݜLz:w :hRب((((( { W{l#Fţ}BtWxcm;uzCc/OXT>ên#B?!'2lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lP)lPI@E (P(Q@E (P(Q@E (P(Q@E (P(źDz屝ilw86y#+.'T (1 zPd(B/S]:W /|ّa㈏BEze{-ghˉ&6{WGh'U+g1ݥ0~l2vși|tIrw>.7L>@5i|Uo2=ml>)kO]Ed(Q@E (#h-bp)\j8ﳈU09^jWlH]d xj Vg>]mt؟$P(Q@E (P(Q@E (P(Q@E (P(Q@E (P(Q@E (P(Q@E JGE))))))))))))))))`X4F[R5%EO޸uc|x>Q :Y@dA/Tzi4DPrȳ1C]ܙF;gL$8Bf#kLe% z75sq̩QCE]ǖk-la`Ź$qqk ~#U{t8ՖCc+W6ats17Gxy)prg;&np1|m1Mqd/2G@?r {mclfk <j(_Krxt}؞'ncvMVFs8 袚[5:߀xP~!_#d~'R9YӵY$# R># R># 蹲mռj+H.`(4nb.Hp$G nIlnD.d_mz4:fsG܂BJG@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| G@| GA)G@GD >}( Q@GD >}( Q@GD >}( Q@GD >}( Q@̟Y{6<}m$ozG=H$kXM)xWj96{wUm[2rR[f\Dp~9S<dD;;cs[{_î|j`p+]܏&s|qv.ô[{7PIm ]q@-*k Yf]YnǧIPt; VIveC뼍YdėޗxooY Ƴ]iY6 GkYw^ӺձJ^u -C백9'qV&; / 'YgR&xia{k,L|eu`xK~6-Ǹǐ͉isA$cРYYdmwau崟'PGvYwpd?v2_#[=NV.ڌ.<\x|V?ErR짛4vIGF7]`?ܷl]ŀ"-&&28,}RD >}( Q@&XimE;> Xj*2bd%d"Jx9ڙ{cҨВN:]P|{.`]Z;MD >}( Q@GD >}( Q@GD >}( Q@GD >}( Q@GD >}( Q@GD >}( QA'HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`{uC.zC0Cw/Ӌn/d7v3CqglBX ziׇܻ5ܽ3+?k$֢#:[o65\y^tjHgGؾu'WsptHoH:uO;3ocNk\FR| Gd\yPyK\vatd/xs:(ȭFYE9٥G=1͜qqy!~Ǵ<=d|cڴ[8f"ݷxx݊ž6{YM{7OYusw /?غ&9ͷ-ϼkҞFݱ=\JFI.{@t:u+8<}Pcq}6lG, a:rZ"+kg9سۮ׫Fj@;oGe)))))))t%8PcXHo>j#K_-vFZ[>FxI:Xn~V^,<fCBCy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy t7Cy ·dv:ӫi,6z]{o5y8;#N ok!Ksc:%$[oe -PqP5[P^v g}wUC$Wkض-> Llri0h0kؽ6VA{Ѡs{AY켆~Kߝ'*KojO=BojY}76X4#:Fߚ֍Ug` =b夓t=a`hxvo\d`1xc% s27-};'H H H H .G2%w2#O@uA?/*(7)O6(3D`v7J%Pylons-1.0.1/pylons/media/img/bg.png0000775000076500000240000000052311645401276017154 0ustar benstaff00000000000000PNG  IHDR&#.sRGBbKGDY< pHYs  tIME2 ~p=tEXtCommentCreated with GIMPWIDATHǽUA0+?~o%@/% t~?_)}Rt1aNҤQtf Q\(E}Ւ%"R;`v]/. "mrGz%1Nƃԃtxm}*1(m?"|&5uqyO8ıIENDB`Pylons-1.0.1/pylons/media/img/favicon.ico0000664000076500000240000000545611645401276020206 0ustar benstaff00000000000000(6h^ h( 333333033ff33036ffb303fnf300ff0ffnfdnfd`Ff  ??( N^ Z 6R&6 "bZb~ v Vn~"B^j  ~Rf*jFj vNj  b""f  >Zz^v&>n~Vj& Nb ^:RbjfvVr**>^j~Nf "*n R~zVj f&j>^ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ RRR 494 RRR #,G??CI=??',' - F ?,'!A/6X& J?#1 573>XX7E.1ZZZZZZZZZ!OQ ZZZZZZZZZ X+ZZZZZZZZZZZVSSZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ  ??(  WpTk Tk Tk Wn WkNaM_ViWo Tk Tk Tk Vn!iffkVq !`Z}cjOkl ffh)gdiC_ y  w=]j df(giPeb uMd jf( oa% } +)\w m * i:Qn%^&?~ O$6 V K Y ] >[#j c S| Y {7Q v  G w i4=\ e gEh C-n"u6 ??Pylons-1.0.1/pylons/media/img/hatch-yellow.png0000664000076500000240000000030411645401276021156 0ustar benstaff00000000000000PNG  IHDRJ"+tEXtCreation TimeWed 2 Mar 2005 01:35:41 -0000Ja5tIME +_ pHYs B4gAMA aIDATxc0`b ,0H]KXIENDB`Pylons-1.0.1/pylons/media/img/header.png0000664000076500000240000000032611645401276020012 0ustar benstaff00000000000000PNG  IHDRM+tEXtCreation TimeMon 9 May 2005 22:40:47 -0000?tIME+ pHYs B4gAMA a.IDATxc bb`` # /$$0!@jIENDB`Pylons-1.0.1/pylons/media/img/highlight.png0000664000076500000240000000030411645401276020525 0ustar benstaff00000000000000PNG  IHDRJ"+tEXtCreation TimeSat 5 Feb 2005 02:45:25 -0000LCCtIME (b pHYs B4gAMA aIDATxc0`b ,0H]KXIENDB`Pylons-1.0.1/pylons/media/img/logo.gif0000664000076500000240000000744511645401276017514 0ustar benstaff00000000000000GIF89a4990 LLIeebzzJ{{z~~|NooErrH~墢333rrq,,(HHE??>``>fff]]APP:{{JttrWԨZ`QWnnmX"" vvGMM7T==<⒒QPPNiiAkkiEECbb?TTQBB6))&ppn[[>II9NNKeeB**'$$"[VV?fEE:R//,;;1M\00/``]GGDXX>9??;772@@;==922/..*YN00-~~I;;6??://+~~J::5XY_Ḹ_99444/c885>>:UçZK^KJNOTwwHZZ=33.::7ؓRǬllk[[?WW@WXX@ҥS@@5yyx11,ἼWW;b[Ѩ22-AA>!K,4H.9` NJHŋ3jL!*lIɓ;:ʗ0cʬV//3sif < 'PH4ӓLJj1*ի px`!4l]t6ZZXf%ǂRm fc' .j-|șFLHpB)eB$$8tg6 =13{l, wv2VLF%xxd1ct^HQgc^2H%q"qL#9gdx U|qyi y$@-؋! o66F"!wՂ*q p}-BG(Ap ,1lJ9 qDGTI.GZ Ԣ"KfPzd 8'&g]8BE'xD A  pژ !vpbGtJ/&E)!5 V"NZiZHk8Epgar&i&An gWX[p q@*@B ʊV d-U#Gi"z†\r*i nh&AF_}#yt&*nl-Jo*o#,3 o tXj<ٸa(/GڌyJ/aGP|PDf wΗ@Dе`f,,KVE7]p$6!Hޔhvƃ5{-:lPK ͺK:BsCScR 0 fDIGt$0oyt$m-eg9k!dLtA =2q" `)c]>A~7 *s)jD"Ab%@"kX+qj+lBIǛ <ؤ xE) tA[Dφ$!z\Y'ZMep趴:1"3ۃA,R\ "q78ac8= ݚXD7*dC#y"B5 0\jx%; Z4cS+*)!d*8IKъ3;X!rՁ3f.wi͕YhiH&YDt3q "Јt0`A 2ΔAl9R<8!A0WXlDH8Z!g& 6b!ZJF$H=R,X"Z4]B,ކ!Ǖq0-MEB9SG6*Q`bf5\dn в vӈW!RX.$ @jD"rp]|D@^DiD$aDxq$6 #a\1T8 %KjI%E,H8&B6\{ oĈH [,B2E\\Axib]-!x#fA1R`gG>qf)Q+1>Vʬ)0H>'D$. JH&@(<@%T@QJ8Z ƅ `Z1F4\mDD@{D @n @@$:G(D !msD!1qGKC!Qm<1(Da튐~ɽmM<"HD)I f'B8a("`x V@ ht!B"E!0B`!FnSB _BBty"Ns0!0l".Mj $ 6 !Lp BD &Qo4<E * MB!PB! B!0bh(D E lC! Ki0ʻQ(A6"dH!R (__X"+B$0AiE]Ri D@`E LQR@,D C~Ly$2r P,ZJ$!t K_7 xP= xo ~YP`~z ~>7rN)@ ܷx )pڲinWs- T 1 '` H6| & %P'Gr` zrn)PrwS&3}pY ~"r7 .7r ~ wX b` z1 F2Pg 'P`@ C@P nP P@ P-Ljz xy}ϗ zP py؄X gT yf0w}vϷiP70 Ө Yp W P}p0 iq ɀp gȋ7ЊhX.sI I3 NEf8P 0 ַZcvɒ`B}DY@,dOI@UIO"6 D.)0 gP da` 0 q P p0Kp z9 iy {9 vYp L 0 `I99 i|(p Gp iƩyI ͙‰^sigy;Pylons-1.0.1/pylons/media/img/main-nav-bg-on.png0000664000076500000240000000031511645401276021266 0ustar benstaff00000000000000PNG  IHDRUh?,tEXtCreation TimeFri 21 Oct 2005 03:03:42 -0000_2tIME \i] pHYs B4gAMA a$IDATxcdbFFF&2iBllvc\4|4/IENDB`Pylons-1.0.1/pylons/media/img/main-nav-bg.png0000664000076500000240000000036411645401276020660 0ustar benstaff00000000000000PNG  IHDRUh?,tEXtCreation TimeFri 21 Oct 2005 03:03:42 -0000_2tIME 4/̗ pHYs B4gAMA aKIDATxcqT2` iAf@iĘ.!ы)HU fߵ PǏfTIENDB`Pylons-1.0.1/pylons/media/img/plus.jpg0000664000076500000240000000055111645401276017541 0ustar benstaff00000000000000JFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222 "#"#4Ts! ?gnIe=%iȑ>󧼎n.sU1}\p7?/Z2Y?Pylons-1.0.1/pylons/media/img/pylons-logo.gif0000775000076500000240000000453711645401276021040 0ustar benstaff00000000000000GIF89a;Dzyu)))ZZZHHH%%%2!!!Yna(,<<;޾9{.©A 221(('LD&##"'''&&&"""  (((###$$%'(($##$$$(''***+++onn0!,;DpH,Ȥrl:ШtJZجvzxLl$͆Rn+4||2dC lezxq?=N v n? =pwӗ pڣŒb\eMY,[# ‹S&0܈gP0S6ȑG1 Cj;/*sQز/1e&f):ٳ0A@ҫ1؀hp ޼֖/ -w$% oΫw$x%AT^bd_5;RNR`[ =0 P{,f ""QVz +`Pi@O2,+u*P w@%2'@H" bwaUu.Md%i3QfE{H`L}jEQEAV^1(m UBKti@6T@c\D4-PD>+W64@64"N=xDiRExLY@!gQr/U᧍B EDdIj*: DI:U 5EDaN^[bD99N: :J}cR`kN)Gi)F JZ$a@:DJbgN{붲 A+m;bp.q-&;BXnO2WDJ;%6ZVFN D@JpöʂpxD˶JRuy"A/Zos| n3pL S@bW@]4< T26/k q(:7{F/xnKRYDfv-M`/@5?L$[76Q(#%A1_F(Պ)Ƹt&>w٠] w( y桼7(Gd 5{e x@cn\֋Xڢx|(A>(˞ ΄] pz@D>"x x?0xy#XS9z8]bq6$hGs~7EI@Ji'sяqѓ6X\?=z6 UUFdB&88y+툗@)_?d9|hkk-,,9,5@ P]O pA$ٳg׃?~իUV|u޼ynnnz KgjJw>+V #l+0={ G-[,--w \CW)c$d %`Yo޼إKI}!P&_B4ܹ[%#;(5ogd/&ZeQaM HfAAhRLKM* MX]* J&Xd} K ֐!7otvv2Ο??eʔ`h'N6DSHϢ"`!SWW#,C`Y g< &&u- L8mQQQ@GA샫`={.8T_,Q0}tv;iuv0m?l`!4X( :`i ^/ZZּ2?~$M6s(|.//@g [@@`ǎX00\F)U 2biw/~@ '%e5@/409Rlug %Ma0LQ,^Bi у& AK1IFЋ%"C4(h97;ͮ e{*_#ʟo{[DIjRвx@,Ǒ~vyvCjW5>%I Tsko8d< .X-<& >cq%3KP~l""э ɿ(UDV>@=ul8}i$vGYG]j-/骅GY_H[WmRc$311Qvih4V1/%Rm,EEаn> B0لL!O(&Z&t#epI{K^oz&kؾ9}߹9Tj`YP[TX ΝgYCZ]]Exx\nLO}wM]_n}]ŝxːDj9٫_8~Լ#xh0Ժsݝ$&D*/Đ1s{zzHOoo/z%+<΋Q%/ʞ,-$*4ʋCtF0QAA0W(ύ ]__ܱyp( p:Юi8U*Hw<JHw9+//bLNNA;ArQSSSؾ㠧f9A\(=8 +-B\4L瀳h2("тb_\\L AϗĄ d.1Dp$0$7T$}Zj$=i44###h'_;c# (F__ё|+(T-Krń4, SKD,u›״Ǖi -//ZP&h8X~ BhcDG=%1DuB&*TyAoR~mi"H[,xEV9Oݧ@DmV+2 Yq1:vFBQA q88JE~O:Miau]ickaFD(4M /l(EpV^(bdwE=rHp@||w/m˕?v?j)1E:%@)N2$@xo{{{ 333[RZzxc{1KKK\ OL>P`+g|̣'Ǥ"{FYp_H\6l62LCCCv]Tb훚H$:<@.k"HO?bO"#uj"?k{b?Zޛ?~^x ]ɓ,ZEf%SfF99?NIYUI*ݟ[[#|Q6/[n+H;7nܸl:Ju`@vU`INNBZ__o>H,߂\VV֘1c`NBaDג S(ogϞ"^6~'gڇ-.FIvK7tU_9RP]vJH?O5#˗[D^e!!qB ^PP3gzȬxpݺuHOO[0Hʕ+SRRE;v,ʕ+W̛7oܹ̅v ;1bڸq#޴iӸ8qaf3W)..?~|PPЋCgϞO?^|8XmxUQ1̙3GM<jt>|75._,9P!ϒc5Yl,UTTf陂+Bf뢷N?,Z=1=)%''G L`͚5 _nll|8_]tAD ?&&q epE1cƒ%Kҵ_;l_{n>gZ->lÆ v"爅rH>.… qIbCk׮h锩gԩ@ycǎSD3oj P`¯6ܹa-l]jvZvmioÃTzIXnWt8*ׯ_%}ҤI-$N:%28X]@t޽$q@qJ@ȁ[ @PͳgX`d\,[0";'$L GI}L_kGUS Z2KxAEe/GvQoܸD<::Zd3!&億QO|EtAAj2Luuu ǘ'p\QVG7k9`p! F}Qd_)ww:RTA~V/=DNj\SSs!|322C _{s[/)~Q?2xkuAߺwRU2]Qّd6Hwȑ$'z*?mEzpÇCEd3"N *(,,$֬YÝ_ŦM=H¯ u_$ n3$V;Vmj25yQFxfrh;ڝb3h~*VuH}y%(뵐7X)D=yߣ+wvdgv rQ3n=/S &yA6/EXׁL>]7a(n=KPRҝqyjjQ<{?KR,Pu^Rfk#M TLk# CRd{A(,bb*R%Ĭ*))! )زe =TnbݵpHG7N8qw?#{dզO~MQ+ \gWXlVNQkx)@ N|Rk/nRVm0mȅscNcD1BL!D1BL!D1BL!D1BL!D1BL˲3Ԇ56*M1b^@l݄07b"(lBb !&BD%_Q@qbC'b"!&Bb"!&Bb"!&Bb"!&Bb"!&Bb"!&Bb"!&Bb"!&Bb"!&Bb"!&Bb"!&Bb"!&Bb"K4}MsIENDB`Pylons-1.0.1/pylons/media/img/tab-traceback.png0000664000076500000240000000064111645401276021245 0ustar benstaff00000000000000PNG  IHDRPkʂgAMAOX2tEXtSoftwareAdobe ImageReadyqe<`PLTEѬDIDATxٕч: gi!u25~ZW׮z cz""A Q D$?@~( @Y! AQ 9" d("!B"D!B"DȷBF>V\wiP  kDrGDrB  @!B"D!B"D!|FZBIENDB`Pylons-1.0.1/pylons/media/img/tab-white.png0000664000076500000240000000074511645401276020453 0ustar benstaff00000000000000PNG  IHDR,^\,tEXtCreation TimeThu 20 Oct 2005 13:22:14 -0000 9tIME':% pHYs B4gAMA a9,tEXtCreation TimeThu 20 Oct 2005 13:22:14 -0000 9tIME 6 pHYs B4gAMA aPLTEB9BJRRRZZZZccckk!ckssJ{{քքք֌ބބJޜ!!!!!!)c) tRNSYjAIDATxJBQ@.L#V?\ &sf]'ðّjziZڱ~ղIcMXeylg,`ƪ{Lcuoz\xcG=><:cˋZ~4Vه7!iVՊ=ʶX[̎]4VM%iInqc 0`,Xc 0`,Xc 0`,Xc 0`,Xc 0`,Xc 0`,Xc 0`,Xc!qwg(rIENDB`Pylons-1.0.1/pylons/media/img/tab-yellow.png0000664000076500000240000000110311645401276020633 0ustar benstaff00000000000000PNG  IHDR,^\,tEXtCreation TimeThu 20 Oct 2005 13:22:14 -0000 9tIME*va; pHYs B4gAMA aIDATx1N0܏p $$fԉVο*qb//'|^^พs=cǀ!D1BL!D1BL!D1BL!D1BL!D1Blݶk=,!*B BXO"df dY"z BE`9̌ ̈zfqY?`'d m@!oz7ဝY,Be=wB3,Gz~ĉD1BL!D1BL!D1BL!D1BL!D1BL!D1BL!D1BL!D1BL!D1BL!D1BL!D1BL!D1BL!DNDIENDB`Pylons-1.0.1/pylons/media/img/warning.gif0000664000076500000240000000200011645401276020177 0ustar benstaff00000000000000GIF89a!!ZZsk{s{Ƶν޽B޽J޽R޽ZJZckBBJJRks{ΌJ{֌֔ޥޭJJR֔ޔޜޥJJRJ1J!1B)19BJ!,H A**\ J!B'bXDH! &Jx# 'ryFhbC"@BXY1b I!BE0Ҡ )> "B 40ac̞TH0"?vѐRaɠ?PPcC$5HpX   @p6!k3THB .8тo$F_1B8-;Pylons-1.0.1/pylons/media/javascripts/0000775000076500000240000000000012012307216017614 5ustar benstaff00000000000000Pylons-1.0.1/pylons/media/javascripts/traceback.js0000664000076500000240000001330411645401276022106 0ustar benstaff00000000000000$(document).ready(function() { var getProxyJSON = function(host, path, data, callback) { data['host'] = host; data['path'] = path; var uri = TRACEBACK.uri+'/relay'; $.getJSON(uri, data, callback); }; // Manipulate DOM to add the iframe, and move things around var newholder = $(document.createElement("div")).addClass('widget_layout'); $('div.feature-highlight').wrapAll(newholder[0])[0].appendChild( $('button:last').remove()[0]); $('div.widget_layout')[0].appendChild(document.getElementById('service_widget')); $('#service_widget input.submit_traceback').click(function () { $('#service_widget .posttracebacktab').html('Sending traceback...'); var uri = TRACEBACK.uri+'/post_traceback?debugcount='+debug_count +'&host='+encodeURIComponent(TRACEBACK.host) +'&path='+encodeURIComponent(TRACEBACK.traceback); var opts = { url: uri, cache: false, dataType: 'json', success: function(data, textStatus) { var iframe = document.createElement("iframe"); var tlink = data.traceback.link.replace(/\.xml/, ''); iframe.style.display = "none"; document.body.appendChild(iframe); iframe.src = 'http://'+TRACEBACK.host+TRACEBACK.traceback +'/'+encodeURIComponent(tlink) +'/reown?uuid='+encodeURIComponent(data.traceback.uuid); stuff = data; var full_uri = 'http://' + TRACEBACK.host + TRACEBACK.traceback + '/' + tlink; var reply = 'Traceback posted successfully.

'; reply += ' ' + full_uri + ''; $('#service_widget .posttracebacktab').html(reply); } }; $.ajax(opts); return false; }); // Hide the tabs we shouldn't see $('.posttracebacktab, .searchtab').hide(); // Bind the click functions for each tab $('a.overview').click(function () { $('#supportnav li').removeClass('active'); $(this).parent().addClass('active'); $('.overviewtab').show(); $('.posttracebacktab, .searchtab').hide(); return false; }); $('a.search').click(function () { $('#supportnav li').removeClass('active'); $(this).parent().addClass('active'); $('.searchtab').show(); $('.posttracebacktab, .overviewtab').hide(); return false; }); $('a.posttraceback').click(function () { $('#supportnav li').removeClass('active'); $(this).parent().addClass('active'); $('div.posttracebacktab').show(); $('.searchtab, .overviewtab').hide(); return false; }); // Set the search field to the exception as the default search $('.searchtab input[@type="text"]')[0].value = $('code.main-exception').text(); // Bind the search button to hit the mail lists $('.searchtab input[@type="submit"]').click(function () { // Populate the lists array with the strings for the lists to include // in the search var lists = []; var options = $('.searchtab input[@type="checkbox"]').serializeArray(); $.each(options, function(i, val) { lists.push('list:' + val.value); }); // Setup the search data var data = {mode:'json', page:1}; data.q = lists.join(' ') + " " + $('.searchtab input[@type="text"]')[0].value; var sr = $('.searchresults'); sr.html('Loading...'); var searchResults = getProxyJSON('markmail.org', '/results.xqy', data, function(data, textStatus) { stuff = data; var numresults = $(document.createElement('p')); numresults.addClass('results'); numresults.html(data.search.start + ' to ' + data.search.end + ' of ' + data.search.estimation); var searchlink = document.createElement('a'); searchlink.href = 'http://markmail.org' + data.search.permalink; searchlink.target = '_blank'; $(searchlink).html('View all results'); numresults.prepend(searchlink); sr.html('').append(numresults); // If there's no search results, stop here if (!data.search.results) { return false; } // Iterate through the search results adding them dynamically // to the element $.each(data.search.results.result, function(i, val) { var result = $(document.createElement('div')).addClass('result'); var link = document.createElement('a'); link.href = 'http://markmail.org' + val.url; link.target = '_blank'; $(link).html(val.subject); result.append(link); var blurb = $(document.createElement('div')).addClass('blurb'); blurb.html(val.blurb); result.append(blurb); var meta = $(document.createElement('div')).addClass('meta'); meta.html(val.date + ' - ' + val.from + ' - ' + val.list); result.append(meta); sr.append(result); }); // Scroll the window down to the top of the service widget with some space window.scrollTo(0, $('#service_widget').offset().top-20); }); return false; }); }); Pylons-1.0.1/pylons/media/style/0000775000076500000240000000000012012307216016423 5ustar benstaff00000000000000Pylons-1.0.1/pylons/media/style/black.css0000664000076500000240000000275611645401276020237 0ustar benstaff00000000000000body { font-family: arial, helvetica, sans-serif; background-color: #ffc900; background-image: url(../img/bg.png); background-repeat: repeat-x; width:100%; height:100%; margin:0; max-height: 100%; padding:0; border:none; line-height:1.4; } #container { color:white; background-color:#111; position: absolute; left: 50%; width: 500px; margin-left: -300px; padding:50px; height:100%; } #footer { margin: 120px 0 0 0; padding: 3px; text-align:center; font-size:small; background-color:#222; letter-spacing: 1px; } h1 { text-align:center; font-size:xx-large; font-weight:normal; margin: 0 0 20px 0; border:none; padding:0; letter-spacing: 5px; } h2 { font-size:xx-large; font-weight:normal; margin: 0 0 20px 0; border:none; padding:0; } hr { margin-bottom:30px; border: 1px solid #222; background-color: #222; padding: 2px; } #logo { background-image: url(../img/pylons-logo.gif); background-repeat: no-repeat; height: 0; overflow: hidden; padding-top: 99px; width: 239px; } #left { float:left; width:250px; margin:0 50px 0 0; border:none; padding:0 0 0 10px; } #right { margin:0 0 0 330px; border:none; padding:0; } ul { list-style:none; margin:0; border:none; padding:0; } a:visited { color:white; text-decoration:none; } a:link { color:white; text-decoration:none; } Pylons-1.0.1/pylons/media/style/itraceback.css0000664000076500000240000000544711645401276021253 0ustar benstaff00000000000000/* @override http://localhost:5000/_debug/media/pylons/style/itraceback.css */ div.credits { padding: 5px 0 0 0; color: #777; font-size: 11px; } #footer { border-top: 1px solid #666666; padding: 0; margin: 20px 0 0 0; } #pylons_logo { float: right; margin: 5px 0 0 0; } div.widget_layout { margin: 30px 0 0 0; } div.feature-highlight { float: right; width: 400px; } div.feature-highlight button { margin: 15px 0 0 20px; } div#service_widget { width: 500px; padding: 0; margin: 0; margin-right: 10px; line-height: 1.4; } div#service_widget h4, div.overviewtab h3 { margin: 0; padding: 0; font-weight: bold; font-size: 100%; } div#service_widget h2 { color: #000; border-bottom: 1px solid #0a0; font-variant: small-caps; font-size: 20px; line-height: 1.3; font-weight: bold; } div.overviewtab, div.posttracebacktab, div.searchtab { padding: 13px 10px 10px 10px; background-color: #f8f8f8; border-bottom: 1px solid #ccc; border-right: 1px solid #ccc; border-left: 1px solid #ccc; } div.clearfix { clear: left; margin: 0; padding: 0; height: 0; } .hide { display: none; } input.query { width: 350px; } p.query { margin: 0 0 0 20px; padding: 0; } /* Nav Bar */ #nv li { display:block; float:left; list-style-type:none; margin:0; padding:0; } #nv a { display:block; float:left; border: 0px; } /*** Tabs ***/ #supportnav { float: left; width: 500px; border-bottom: 1px solid #CCC; margin: 0px; padding: 0px; } #supportnav li { float: left; padding-left: 10px; margin-right: 3px; background: url("../img/tab-traceback.png") no-repeat left top; } #supportnav li.first-child { margin: 0; } #supportnav li a { display: block; padding: 3px 10px 3px 0; border: none; outline: none; background: url("../img/tab-traceback.png") no-repeat right top; color: #666; } #supportnav li a:hover { color: #333; } #supportnav li.active { position: relative; margin-bottom: -1px; background-position: 0 -40px; } #supportnav li.active a { display: block; padding: 3px 10px 4px 0; background: url("../img/tab-traceback.png") no-repeat right -40px; font-weight: bold; color: #333; } #supportnav li.active a { background-position: right -40px; } * html #supportnav { margin-bottom: 0; } div.searchresults div.result { margin-bottom: 5px; padding: 2px 0px 2px 4px; cursor: pointer; background-color: rgb(247, 247, 247); border: 1px solid rgb(235, 235, 235); } div.searchresults div.result div.meta { font-size: 0.8em; color: rgb(1, 116, 22); } p.results a { float: right; } div.searchresults div.blurb { font-size: 0.8em; } div.searchresults div.result a { text-decoration: underline; font-size: 0.9em; cursor: pointer; } Pylons-1.0.1/pylons/media/style/orange.css0000664000076500000240000002151011645401276020423 0ustar benstaff00000000000000body{ margin: 0px; padding: 0px;/* 4% 0 0;*/ background: #494943 url(../img/bg.jpg) top repeat-x; font-family: Verdana, Arial, sans-serif; font-size: 75%; line-height: 160%; color: #333; /*min-width:770px; max-width: 1100px;*/ } /* Layout Styles */ /*.top-bar{background: #fff url(../img/bar.png) right top no-repeat;} */ div.main-content-bg{ } div.main-content-bar{ } div#nav-bar{ border-top: 1px solid #fff; float: left; width: 100%; margin-top: 16px; background: #fff url(../img/bar-bg.png) right top repeat-x; } div#main-content{ float: left; width: 100%; background: #fff; } div#side-content{ /*background: #FFf url(../img/bar.png) top right no-repeat;*/ padding-top: 42px; float: left; margin-top: 0px; width: 30%; clear: right; height: 550px; } div.three, div.two, div.one{ width: 746px; padding: 0 12px 0px 12px; clear: both; } div.three div.a, div.two div.a{ float: left; clear: left; width: 204px; /*background-color: #ddd;*/ } div.a div.padding, div.b div.padding, div.c div.padding, div.one div.padding{ padding: 0px 12px 20px 12px; } div.three div.b{ float: left; width: 271px; /*background-color: #ccc;*/ } div.three div.c{ float: left; clear: right; width: 271px; /*background-color: #bbb;*/ } div.two div.b{ float: left; clear: right; width: 542px; /* background-color: #333;*/ } /* Logo */ h1#logo{ margin: 20px 5% 0 5%; padding: 0; float: left; width: 155px; height: 52px; /*padding: 25px 5% 0 5%; margin: 0 0 0 -2px; float: left;*/ } /* Nav Bar */ #nav-global { margin:0; white-space:nowrap; float: right; /*position: absolute; margin:0; left:380px; top: 0px;*/ padding-right: 5%; clear: right; padding-bottom: 20px; } #nav-global li { display:block; float:left; list-style-type:none; margin:0; padding:0; } #nav-global a { display:block; float:left; /*font-family:"Trebuchet MS"; font-size: 110%; */ padding:42px 18px 7px 18px; background:#000000; color: #ccc; border: 0px; text-decoration: underline; } #nav-global a:hover { color:white; background: url(../img/main-nav-bg-on.png) bottom repeat-x; border: 0px; } #homepage #nav-homepage a, #overview #nav-overview a, #download #nav-download a, #documentation #nav-documentation a, #weblog #nav-weblog a, #community #nav-community a, #code #nav-code a { color:white; background:#000 url(../img/main-nav-bg.png) bottom repeat-x; } ul#navlist { /*background: url(../img/bar.png) left top no-repeat;*/ margin: 0; padding:0; padding-left: 5%; padding-top: 8px; color: #eee; line-height: 34px; } ul#navlist li { display: inline; } ul#navlist li a { /*font-family: Tahoma, sans-serif; font-size: 11px;font-weight: bold;*/ border: 0px; border-left: 1px solid #49A200; /*padding: 0em 1em;*/ padding: 0 18px 0 18px; color: #fff; margin-right: 9px; text-decoration: none; float: left; background: url('../img/tab-brown.png') no-repeat top right; } ul#navlist li a#highlight , ul#navlist li a#highlight:hover { background: url('../img/tab-yellow-highlight.png') no-repeat top right; color: #fff; padding-right: 33px; } ul#navlist li a:hover { background: url('../img/tab-yellow.png') no-repeat top right; color: #fff; } ul#navlist li.active a.active, ul#main-nav li.active a.active:hover { background: url('../img/tab-white.png') no-repeat top left; color: #333; } /* Font Styles */ a, a:link, a:visited, a:active { color: #0040BB; text-decoration: none; border-bottom: 1px dotted #ccc; } a:hover{ color: #000; border-bottom: 1px dotted #000; } a.no-underline, a.no-underline:link, a.no-underline:visited, a.no-underline:active { border: 0px; } img.no-border{ border: 0px; } /* Paragraph Styles */ .last{ padding-bottom: 0px; margin-bottom: 0px; } .first{ margin-top: 0px; } blockquote { padding-left: 10px; padding-right: 10px; margin-left: 5px; margin-right: 0; border-left: #ddd; border-width: 0 0 0 1px; border-style: none none none solid; } p.first, form{ padding: 0px; margin: 0px; } .medium{ font-family: Verdana, Geneva, Arial, sans-serif; font-size: 11px; line-height: 19px; } .large{ font-size: 110%; } .small{ font-size: 90%; line-height: 150%; font-family: Verdana, sans-serif; color: #000; } p.indent{ padding-left: 15px; padding-bottom: 15px; } tt, code{ font-size: 130%; color: #800000; } pre{ /* border-top: 1px dotted #000; border-left: 1px dotted #000; border-right: 1px solid #999; border-bottom: 1px solid #999; background: #eee;*/ font-size: 120%; padding: 3px 5px 3px 10px; margin-right: 10px; } .go{ /*background: url(../img/go.png) no-repeat right bottom;*/ padding-right: 20px; } .help, a.help{ cursor: help; font-weight: normal; } .highlight{ background: #ffffcc url(../img/highlight.png) repeat; } /* Horizontal Rule */ div.hr { clear: both; line-height: 0px; font-size: 0px; margin: 0px; padding: 0px; /*height: 4px; url(../img/horizontal-rule.png) no-repeat;background: #000; margin-bottom: 20px; width: 770px;*/ } hr { height: 1em; visibility: hidden; margin: 0px; padding: 0px; } /* Form Styles */ .form-style input[type=submit]{ background: #87CD15; color: #fff; border-top: 1px solid #999; border-left: 1px solid #999; border-bottom: 1px solid #333; border-right: 1px solid #333; } .form-style input[type=text], textarea, input[type=file]{ font-family: Tahoma, sans-serif; font-size: 11px; color: #444; background: #EAFEC2; border: solid 1px #aaa; padding: 3px; } .form-style select{ font-family: Tahoma, sans-serif; font-size: 11px; color: #444; background: #EAFEC2; border: solid 1px #aaa; } /* Lists */ ul.large{ padding: 0 0 0 15px; margin: 0 0 15px 0px; } ul.large li a { font-weight: normal; } /* Header Styles */ h1.first{ margin-top: 0px; border-bottom: 1px solid #666; background: #fFF; padding: 3px; } h1, h2, h3 { font-size: 170%; line-height: normal; font-weight: normal; font-family: Arial, sans-serif; color: #000000; text-decoration: none; /*margin: 0 0 12px 0; padding: 0;*/ text-align: left; } h2{ font-size: 140%; } h3 { font-size: 120%; } h4{ font-size: 100%; } h4.asterix{ /*background: url(../img/box-small.png) no-repeat left center;*/ padding: 0px 0px 0px 15px; margin: 0px; /*font-size: 110%; */ color: #000000; } /* Boxes */ div.faq-box{ /*border-style: solid; border-color: #C6F27A; border-width: 1px;*/ /*background:url('../img/hatch-green.png');*/ padding: 10px; /*font-family: Verdana, Geneva, Arial, sans-serif; font-size: 11px; line-height: 17px;*/ } div.highlight-box{ border-style: solid; border-color: #cccccc; border-width: 1px; background:url('../img/hatch-yellow.png'); padding: 10px; color: #555; /*font-family: Verdana, Geneva, Arial, sans-serif; font-size: 11px; line-height: 17px;*/ } .box-top{ width: 518px; /*background: url(../img/box-top.png) no-repeat left top;*/ padding-top: 7px; margin-bottom: 15px; } .box-middle{ /*background: url(../img/box-middle.png) repeat-y left top;*/ } .box-bottom{ /*background: url(../img/box-bottom.png) no-repeat left bottom;*/ padding: 0 10px 11px 12px; } /* Utility Styles */ .content-padding{ padding: 20px 6.5% 40px 6.5%; } .sidebar-padding{ padding: 15px 15px 40px 25px; } .invisible{ visibility: hidden; font-size: 1px; padding: 0px; line-height: 0px; margin: 0px; } a.no-underline{ border: 0px; } img.no-border{ border: 0px; } br.clear{ clear: both; width: 100%; } /* Quotes */ .quote-top p{ padding: 0px; margin: 0px; } .quote-top{ font-family: tahoma; /*background: url(../img/quote-top.png) no-repeat left top;*/ padding-left: 25px; padding-top: 4px; } .quote-bottom{ /*background: url(../img/quote-bottom.png) no-repeat right bottom;*/ padding-right: 17px; padding-bottom: 7px; } .quote-author{ /*background: url(../img/quote-author.png) no-repeat left top;*/ padding-left: 20px; padding-bottom: 20px; } /* Footer Styles */ #footer{padding: 5px 5% 40px 5%;} #footer p{ color: #333; } #footer a{ font-weight: normal; } #footer a:visited{ color: #666; text-decoration: none; border-bottom: 1px dotted; } #footer a{ color: #888; font-weight: normal; } #footer a:hover{ color: #000; text-decoration: none; border-bottom: 1px dotted; } Pylons-1.0.1/pylons/middleware.py0000664000076500000240000001667411671746015016727 0ustar benstaff00000000000000"""Pylons' WSGI middlewares""" import logging import os.path from paste.deploy.converters import asbool from paste.urlparser import StaticURLParser from weberror.evalexception import EvalException from weberror.errormiddleware import ErrorMiddleware from webhelpers.html import literal import pylons from pylons.controllers.util import Request, Response from pylons.error import template_error_formatters from pylons.util import call_wsgi_application __all__ = ['ErrorHandler', 'error_document_template', 'footer_html', 'head_html', 'media_path'] log = logging.getLogger(__name__) media_path = os.path.join(os.path.dirname(__file__), 'media') head_html = """\ """ footer_html = """\

Online Assistance

 
Looking for help?

Here are a few tips for troubleshooting if the above traceback isn't helping out.

  1. Search the mail list
  2. Post the traceback, and ask for help on IRC
  3. Post a message to the mail list, referring to the posted traceback

Note: Clicking this button will post your traceback to the PylonsHQ website. The traceback includes the module names, Python version, and lines of code that you can see above. All tracebacks are posted anonymously unless you're logged into the PylonsHQ website in this browser.

The following mail lists will be searched:
Pylons
Python
Mako
SQLAlchemy

for:

Pylons version %s
""" report_libs = ['pylons', 'genshi', 'sqlalchemy'] def DebugHandler(app, global_conf, **kwargs): footer = footer_html % (kwargs.get('traceback_host', 'pylonshq.com'), pylons.__version__) py_media = dict(pylons=media_path) app = EvalException(app, global_conf, templating_formatters=template_error_formatters, media_paths=py_media, head_html=head_html, footer_html=footer, libraries=report_libs) return app def ErrorHandler(app, global_conf, **errorware): """ErrorHandler Toggle If debug is enabled, this function will return the app wrapped in the WebError ``EvalException`` middleware which displays interactive debugging sessions when a traceback occurs. Otherwise, the app will be wrapped in the WebError ``ErrorMiddleware``, and the ``errorware`` dict will be passed into it. The ``ErrorMiddleware`` handles sending an email to the address listed in the .ini file, under ``email_to``. """ if asbool(global_conf.get('debug')): footer = footer_html % (pylons.config.get('traceback_host', 'pylonshq.com'), pylons.__version__) py_media = dict(pylons=media_path) app = EvalException(app, global_conf, templating_formatters=template_error_formatters, media_paths=py_media, head_html=head_html, footer_html=footer, libraries=report_libs) else: app = ErrorMiddleware(app, global_conf, **errorware) return app class StatusCodeRedirect(object): """Internally redirects a request based on status code StatusCodeRedirect watches the response of the app it wraps. If the response is an error code in the errors sequence passed the request will be re-run with the path URL set to the path passed in. This operation is non-recursive and the output of the second request will be used no matter what it is. Should an application wish to bypass the error response (ie, to purposely return a 401), set ``environ['pylons.status_code_redirect'] = True`` in the application. """ def __init__(self, app, errors=(400, 401, 403, 404), path='/error/document'): """Initialize the ErrorRedirect ``errors`` A sequence (list, tuple) of error code integers that should be caught. ``path`` The path to set for the next request down to the application. """ self.app = app self.error_path = path # Transform errors to str for comparison self.errors = tuple([str(x) for x in errors]) def __call__(self, environ, start_response): status, headers, app_iter, exc_info = call_wsgi_application( self.app, environ, catch_exc_info=True) if status[:3] in self.errors and \ 'pylons.status_code_redirect' not in environ and self.error_path: # Create a response object environ['pylons.original_response'] = Response( status=status, headerlist=headers, app_iter=app_iter) environ['pylons.original_request'] = Request(environ) # Create a new environ to avoid touching the original request data new_environ = environ.copy() new_environ['PATH_INFO'] = self.error_path newstatus, headers, app_iter, exc_info = call_wsgi_application( self.app, new_environ, catch_exc_info=True) start_response(status, headers, exc_info) return app_iter error_document_template = literal("""\ Server Error %(code)s
%(message)s
""") def debugger_filter_factory(global_conf, **kwargs): def filter(app): return DebugHandler(app, global_conf, **kwargs) return filter def debugger_filter_app_factory(app, global_conf, **kwargs): return DebugHandler(app, global_conf, **kwargs) Pylons-1.0.1/pylons/templates/0000775000076500000240000000000012012307216016202 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/__init__.py0000664000076500000240000000000011645401276020315 0ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/controller.py_tmpl0000664000076500000240000000062111645401276022006 0ustar benstaff00000000000000import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect {{importstatement}} log = logging.getLogger(__name__) class {{name}}Controller(BaseController): def index(self): # Return a rendered template #return render('/{{tmpl_name}}.mako') # or, return a string return 'Hello World' Pylons-1.0.1/pylons/templates/default_project/0000775000076500000240000000000012012307216021354 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/0000775000076500000240000000000012012307216023075 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/__init__.py_tmpl0000664000076500000240000000000011645401276026244 0ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/config/0000775000076500000240000000000012012307216024342 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/config/__init__.py_tmpl0000664000076500000240000000000011645401276027511 0ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/config/deployment.ini_tmpl_tmpl0000664000076500000240000000264711645401276031340 0ustar benstaff00000000000000# # {{project}} - Pylons configuration # # The %(here)s variable will be replaced with the parent directory of this file # [DEFAULT] debug = true email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [server:main] use = egg:Paste#http host = 0.0.0.0 port = 5000 [app:main] use = egg:{{project}} full_stack = true static_files = true cache_dir = %(here)s/data beaker.session.key = {{package}} beaker.session.secret = ${app_instance_secret} app_instance_uuid = ${app_instance_uuid} # If you'd like to fine-tune the individual locations of the cache data dirs # for the Cache data, or the Session saves, un-comment the desired settings # here: #beaker.cache.data_dir = %(here)s/data/cache #beaker.session.data_dir = %(here)s/data/sessions {{if sqlalchemy}} # SQLAlchemy database URL sqlalchemy.url = sqlite:///production.db {{endif}} # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* # Debug mode will enable the interactive debugging tool, allowing ANYONE to # execute malicious code after an exception is raised. set debug = false # Logging configuration [loggers] keys = root [handlers] keys = console [formatters] keys = generic [logger_root] level = INFO handlers = console [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s] [%(threadName)s] %(message)s Pylons-1.0.1/pylons/templates/default_project/+package+/config/environment.py_tmpl0000664000076500000240000000524211645401276030333 0ustar benstaff00000000000000"""Pylons environment configuration""" import os {{if template_engine == 'mako'}} from mako.lookup import TemplateLookup {{elif template_engine == 'genshi'}} from genshi.template import TemplateLoader {{elif template_engine == 'jinja2'}} from jinja2 import Environment, FileSystemLoader {{endif}} from pylons.configuration import PylonsConfig {{if template_engine == 'mako'}} from pylons.error import handle_mako_error {{endif}} {{if sqlalchemy}} from sqlalchemy import engine_from_config {{endif}} import {{package}}.lib.app_globals as app_globals import {{package}}.lib.helpers from {{package}}.config.routing import make_map {{if sqlalchemy}} from {{package}}.model import init_model {{endif}} def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object """ config = PylonsConfig() # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='{{package}}', paths=paths) config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) config['pylons.h'] = {{package}}.lib.helpers # Setup cache object as early as possible import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) {{if template_engine == 'mako'}} # Create the Mako TemplateLookup, with the default auto-escaping config['pylons.app_globals'].mako_lookup = TemplateLookup( directories=paths['templates'], error_handler=handle_mako_error, module_directory=os.path.join(app_conf['cache_dir'], 'templates'), input_encoding='utf-8', default_filters=['escape'], imports=['from markupsafe import escape']) {{elif template_engine == 'genshi'}} # Create the Genshi TemplateLoader config['pylons.app_globals'].genshi_loader = TemplateLoader( paths['templates'], auto_reload=True) {{elif template_engine == 'jinja2'}} # Create the Jinja2 Environment jinja2_env = Environment(loader=FileSystemLoader(paths['templates'])) config['pylons.app_globals'].jinja2_env = jinja2_env {{endif}}{{if sqlalchemy}} # Setup the SQLAlchemy database engine engine = engine_from_config(config, 'sqlalchemy.') init_model(engine) {{endif}} # CONFIGURATION OPTIONS HERE (note: all config options will override # any Pylons config options) return config Pylons-1.0.1/pylons/templates/default_project/+package+/config/middleware.py_tmpl0000664000076500000240000000455311645401276030110 0ustar benstaff00000000000000"""Pylons middleware initialization""" from beaker.middleware import SessionMiddleware from paste.cascade import Cascade from paste.registry import RegistryManager from paste.urlparser import StaticURLParser from paste.deploy.converters import asbool from pylons.middleware import ErrorHandler, StatusCodeRedirect from pylons.wsgiapp import PylonsApp from routes.middleware import RoutesMiddleware from {{package}}.config.environment import load_environment def make_app(global_conf, full_stack=True, static_files=True, **app_conf): """Create a Pylons WSGI application and return it ``global_conf`` The inherited configuration for this application. Normally from the [DEFAULT] section of the Paste ini file. ``full_stack`` Whether this application provides a full WSGI stack (by default, meaning it handles its own exceptions and errors). Disable full_stack when this application is "managed" by another WSGI middleware. ``static_files`` Whether this application serves its own static files; disable when another web server is responsible for serving them. ``app_conf`` The application's local configuration. Normally specified in the [app:] section of the Paste ini file (where defaults to main). """ # Configure the Pylons environment config = load_environment(global_conf, app_conf) # The Pylons WSGI app app = PylonsApp(config=config) # Routing/Session Middleware app = RoutesMiddleware(app, config['routes.map'], singleton=False) app = SessionMiddleware(app, config) # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) if asbool(full_stack): # Handle Python exceptions app = ErrorHandler(app, global_conf, **config['pylons.errorware']) # Display error documents for 401, 403, 404 status codes (and # 500 when debug is disabled) if asbool(config['debug']): app = StatusCodeRedirect(app) else: app = StatusCodeRedirect(app, [400, 401, 403, 404, 500]) # Establish the Registry for this application app = RegistryManager(app) if asbool(static_files): # Serve static files static_app = StaticURLParser(config['pylons.paths']['static_files']) app = Cascade([static_app, app]) app.config = config return app Pylons-1.0.1/pylons/templates/default_project/+package+/config/routing.py_tmpl0000664000076500000240000000157111645401276027457 0ustar benstaff00000000000000"""Routes configuration The more specific and detailed routes should be defined first so they may take precedent over the more generic routes. For more information refer to the routes manual at http://routes.groovie.org/docs/ """ from routes import Mapper def make_map(config): """Create, configure and return the routes Mapper""" map = Mapper(directory=config['pylons.paths']['controllers'], always_scan=config['debug']) map.minimization = False map.explicit = False # The ErrorController route (handles 404/500 error pages); it should # likely stay at the top, ensuring it can always be resolved map.connect('/error/{action}', controller='error') map.connect('/error/{action}/{id}', controller='error') # CUSTOM ROUTES HERE map.connect('/{controller}/{action}') map.connect('/{controller}/{action}/{id}') return map Pylons-1.0.1/pylons/templates/default_project/+package+/controllers/0000775000076500000240000000000012012307216025443 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/controllers/__init__.py_tmpl0000664000076500000240000000000011645401276030612 0ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/controllers/error.py_tmpl0000664000076500000240000000321311645401276030215 0ustar benstaff00000000000000import cgi from paste.urlparser import PkgResourcesParser from pylons.middleware import error_document_template from webhelpers.html.builder import literal from {{package}}.lib.base import BaseController class ErrorController(BaseController): """Generates error documents as and when they are required. The ErrorDocuments middleware forwards to ErrorController when error related status codes are returned from the application. This behaviour can be altered by changing the parameters to the ErrorDocuments middleware in your config/middleware.py file. """ def document(self): """Render the error document""" request = self._py_object.request resp = request.environ.get('pylons.original_response') content = literal(resp.body) or cgi.escape(request.GET.get('message', '')) page = error_document_template % \ dict(prefix=request.environ.get('SCRIPT_NAME', ''), code=cgi.escape(request.GET.get('code', str(resp.status_int))), message=content) return page def img(self, id): """Serve Pylons' stock images""" return self._serve_file('/'.join(['media/img', id])) def style(self, id): """Serve Pylons' stock stylesheets""" return self._serve_file('/'.join(['media/style', id])) def _serve_file(self, path): """Call Paste's FileApp (a WSGI application) to serve the file at the specified path """ request = self._py_object.request request.environ['PATH_INFO'] = '/%s' % path return PkgResourcesParser('pylons', 'pylons')(request.environ, self.start_response) Pylons-1.0.1/pylons/templates/default_project/+package+/lib/0000775000076500000240000000000012012307216023643 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/lib/__init__.py_tmpl0000664000076500000240000000000011645401276027012 0ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/lib/app_globals.py_tmpl0000664000076500000240000000103411645401276027546 0ustar benstaff00000000000000"""The application's Globals object""" from beaker.cache import CacheManager from beaker.util import parse_cache_config_options class Globals(object): """Globals acts as a container for objects available throughout the life of the application """ def __init__(self, config): """One instance of Globals is created during application initialization and is available during requests via the 'app_globals' variable """ self.cache = CacheManager(**parse_cache_config_options(config)) Pylons-1.0.1/pylons/templates/default_project/+package+/lib/base.py_tmpl0000664000076500000240000000157211645401276026204 0ustar benstaff00000000000000"""The base Controller API Provides the BaseController class for subclassing. """ from pylons.controllers import WSGIController {{if template_engine in ('genshi', 'jinja2', 'mako')}} from pylons.templating import render_{{template_engine}} as render {{endif}} {{if sqlalchemy}} from {{package}}.model.meta import Session {{endif}} class BaseController(WSGIController): def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. This routing information is # available in environ['pylons.routes_dict'] {{if sqlalchemy}} try: return WSGIController.__call__(self, environ, start_response) finally: Session.remove(){{else}} return WSGIController.__call__(self, environ, start_response){{endif}} Pylons-1.0.1/pylons/templates/default_project/+package+/lib/helpers.py_tmpl0000664000076500000240000000042111645401276026724 0ustar benstaff00000000000000"""Helper functions Consists of functions to typically be used within templates, but also available to Controllers. This module is available to templates as 'h'. """ # Import helpers as desired, or define your own, ie: #from webhelpers.html.tags import checkbox, password Pylons-1.0.1/pylons/templates/default_project/+package+/model/0000775000076500000240000000000012012307216024175 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/model/__init__.py_tmpl0000664000076500000240000000037211645401276027360 0ustar benstaff00000000000000{{if sqlalchemy}} """The application's model objects""" from {{package}}.model.meta import Session, Base def init_model(engine): """Call me before using any of the tables or classes in the model""" Session.configure(bind=engine) {{endif}} Pylons-1.0.1/pylons/templates/default_project/+package+/model/meta.py_tmpl0000664000076500000240000000061511645401276026547 0ustar benstaff00000000000000{{if sqlalchemy}} """SQLAlchemy Metadata and Session object""" from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import scoped_session, sessionmaker __all__ = ['Base', 'Session'] # SQLAlchemy session manager. Updated by model.init_model() Session = scoped_session(sessionmaker()) # The declarative Base Base = declarative_base() {{else}} {{skip_template()}} {{endif}} Pylons-1.0.1/pylons/templates/default_project/+package+/public/0000775000076500000240000000000012012307216024353 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/default_project/+package+/public/bg.png0000775000076500000240000000052311645401276025470 0ustar benstaff00000000000000PNG  IHDR&#.sRGBbKGDY< pHYs  tIME2 ~p=tEXtCommentCreated with GIMPWIDATHǽUA0+?~o%@/% t~?_)}Rt1aNҤQtf Q\(E}Ւ%"R;`v]/. "mrGz%1Nƃԃtxm}*1(m?"|&5uqyO8ıIENDB`Pylons-1.0.1/pylons/templates/default_project/+package+/public/favicon.ico0000664000076500000240000000545611645401276026522 0ustar benstaff00000000000000(6h^ h( 333333033ff33036ffb303fnf300ff0ffnfdnfd`Ff  ??( N^ Z 6R&6 "bZb~ v Vn~"B^j  ~Rf*jFj vNj  b""f  >Zz^v&>n~Vj& Nb ^:RbjfvVr**>^j~Nf "*n R~zVj f&j>^ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ RRR 494 RRR #,G??CI=??',' - F ?,'!A/6X& J?#1 573>XX7E.1ZZZZZZZZZ!OQ ZZZZZZZZZ X+ZZZZZZZZZZZVSSZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ  ??(  WpTk Tk Tk Wn WkNaM_ViWo Tk Tk Tk Vn!iffkVq !`Z}cjOkl ffh)gdiC_ y  w=]j df(giPeb uMd jf( oa% } +)\w m * i:Qn%^&?~ O$6 V K Y ] >[#j c S| Y {7Q v  G w i4=\ e gEh C-n"u6 ??Pylons-1.0.1/pylons/templates/default_project/+package+/public/index.html_tmpl0000664000076500000240000001106411645401276027422 0ustar benstaff00000000000000 Welcome to Pylons!

Welcome to Logo displaying the word Pylons


Let's begin!

If you haven't used Pylons before, start with the beginners' tutorial.

Pylons-1.0.1/pylons/templates/default_project/+package+/public/pylons-logo.gif0000775000076500000240000000453711645401276027354 0ustar benstaff00000000000000GIF89a;Dzyu)))ZZZHHH%%%2!!!Yna(,<<;޾9{.©A 221(('LD&##"'''&&&"""  (((###$$%'(($##$$$(''***+++onn0!,;DpH,Ȥrl:ШtJZجvzxLl$͆Rn+4||2dC lezxq?=N v n? =pwӗ pڣŒb\eMY,[# ‹S&0܈gP0S6ȑG1 Cj;/*sQز/1e&f):ٳ0A@ҫ1؀hp ޼֖/ -w$% oΫw$x%AT^bd_5;RNR`[ =0 P{,f ""QVz +`Pi@O2,+u*P w@%2'@H" bwaUu.Md%i3QfE{H`L}jEQEAV^1(m UBKti@6T@c\D4-PD>+W64@64"N=xDiRExLY@!gQr/U᧍B EDdIj*: DI:U 5EDaN^[bD99N: :J}cR`kN)Gi)F JZ$a@:DJbgN{붲 A+m;bp.q-&;BXnO2WDJ;%6ZVFN D@JpöʂpxD˶JRuy"A/Zos| n3pL S@bW@]4< T26/k q(:7{F/xnKRYDfv-M`/@5?L$[76Q(#%A1_F(Պ)Ƹt&>w٠] w( y桼7(Gd 5{e x@cn\֋Xڢx|(A>(˞ ΄] pz@D>"x x?0xy#XS9z8]bq6$hGs~7EI@Ji'sяqѓ6X\?=z6 UUFdB&88y+툗@)_?d9>sys.stderr, ( "md5 validation of %s failed! (Possible download problem?)" % egg_name ) sys.exit(2) return data def use_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15 ): """Automatically find/download setuptools and make it available on sys.path `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where setuptools will be downloaded, if it is not already available. If `download_delay` is specified, it should be the number of seconds that will be paused before initiating a download, should one be required. If an older version of setuptools is installed, this routine will print a message to ``sys.stderr`` and raise SystemExit in an attempt to abort the calling script. """ was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules def do_download(): egg = download_setuptools(version, download_base, to_dir, download_delay) sys.path.insert(0, egg) import setuptools; setuptools.bootstrap_install_from = egg try: import pkg_resources except ImportError: return do_download() try: pkg_resources.require("setuptools>="+version); return except pkg_resources.VersionConflict, e: if was_imported: print >>sys.stderr, ( "The required version of setuptools (>=%s) is not available, and\n" "can't be installed while this script is running. Please install\n" " a more recent version first, using 'easy_install -U setuptools'." "\n\n(Currently using %r)" ) % (version, e.args[0]) sys.exit(2) else: del pkg_resources, sys.modules['pkg_resources'] # reload ok return do_download() except pkg_resources.DistributionNotFound: return do_download() def download_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay = 15 ): """Download setuptools from a specified location and return its filename `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. """ import urllib2, shutil egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) url = download_base + egg_name saveto = os.path.join(to_dir, egg_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads try: from distutils import log if delay: log.warn(""" --------------------------------------------------------------------------- This script requires setuptools version %s to run (even to display help). I will attempt to download it for you (from %s), but you may need to enable firewall access for this script first. I will start the download in %d seconds. (Note: if this machine does not have network access, please obtain the file %s and place it in this directory before rerunning this script.) ---------------------------------------------------------------------------""", version, download_base, delay, url ); from time import sleep; sleep(delay) log.warn("Downloading %s", url) src = urllib2.urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = _validate_md5(egg_name, src.read()) dst = open(saveto,"wb"); dst.write(data) finally: if src: src.close() if dst: dst.close() return os.path.realpath(saveto) def main(argv, version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" try: import setuptools except ImportError: egg = None try: egg = download_setuptools(version, delay=0) sys.path.insert(0,egg) from setuptools.command.easy_install import main return main(list(argv)+[egg]) # we're done here finally: if egg and os.path.exists(egg): os.unlink(egg) else: if setuptools.__version__ == '0.0.1': print >>sys.stderr, ( "You have an obsolete version of setuptools installed. Please\n" "remove it from your system entirely before rerunning this script." ) sys.exit(2) req = "setuptools>="+version import pkg_resources try: pkg_resources.require(req) except pkg_resources.VersionConflict: try: from setuptools.command.easy_install import main except ImportError: from easy_install import main main(list(argv)+[download_setuptools(delay=0)]) sys.exit(0) # try to force an exit else: if argv: from setuptools.command.easy_install import main main(argv) else: print "Setuptools version",version,"or greater has been installed." print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' def update_md5(filenames): """Update our built-in md5 registry""" import re for name in filenames: base = os.path.basename(name) f = open(name,'rb') md5_data[base] = md5(f.read()).hexdigest() f.close() data = [" %r: %r,\n" % it for it in md5_data.items()] data.sort() repl = "".join(data) import inspect srcfile = inspect.getsourcefile(sys.modules[__name__]) f = open(srcfile, 'rb'); src = f.read(); f.close() match = re.search("\nmd5_data = {\n([^}]+)}", src) if not match: print >>sys.stderr, "Internal error!" sys.exit(2) src = src[:match.start(1)] + repl + src[match.end(1):] f = open(srcfile,'w') f.write(src) f.close() if __name__=='__main__': if len(sys.argv)>2 and sys.argv[1]=='--md5update': update_md5(sys.argv[2:]) else: main(sys.argv[1:]) Pylons-1.0.1/pylons/templates/default_project/MANIFEST.in_tmpl0000664000076500000240000000020011645401276024152 0ustar benstaff00000000000000include {{package}}/config/deployment.ini_tmpl recursive-include {{package}}/public * recursive-include {{package}}/templates * Pylons-1.0.1/pylons/templates/default_project/README.txt_tmpl0000664000076500000240000000072311645401276024124 0ustar benstaff00000000000000This file is for you to describe the {{project}} application. Typically you would include information such as the information below: Installation and Setup ====================== Install ``{{project}}`` using easy_install:: easy_install {{project}} Make a config file as follows:: paster make-config {{project}} config.ini Tweak the config file as appropriate and then setup the application:: paster setup-app config.ini Then you are ready to go. Pylons-1.0.1/pylons/templates/default_project/setup.cfg_tmpl0000664000076500000240000000107511645401276024250 0ustar benstaff00000000000000[egg_info] tag_build = dev tag_svn_revision = true [easy_install] find_links = http://www.pylonshq.com/download/ # Babel configuration [compile_catalog] domain = {{package}} directory = {{package}}/i18n statistics = true [extract_messages] add_comments = TRANSLATORS: output_file = {{package}}/i18n/{{package}}.pot width = 80 [init_catalog] domain = {{package}} input_file = {{package}}/i18n/{{package}}.pot output_dir = {{package}}/i18n [update_catalog] domain = {{package}} input_file = {{package}}/i18n/{{package}}.pot output_dir = {{package}}/i18n previous = true Pylons-1.0.1/pylons/templates/default_project/setup.py_tmpl0000664000076500000240000000230311645413263024133 0ustar benstaff00000000000000try: from setuptools import setup, find_packages except ImportError: from ez_setup import use_setuptools use_setuptools() from setuptools import setup, find_packages setup( name='{{project}}', version='{{version}}', description={{repr(description)}}, author={{repr(author)}}, author_email={{repr(author_email)}}, url={{repr(url)}}, install_requires=[ "Pylons>=1.0.1rc1", {{if sqlalchemy}} "SQLAlchemy>=0.5", {{endif}} {{if template_engine == 'genshi'}} "Genshi>=0.4", {{elif template_engine == 'jinja2'}} "Jinja2", {{endif}} ], setup_requires=["PasteScript>=1.6.3"], packages=find_packages(exclude=['ez_setup']), include_package_data=True, test_suite='nose.collector', package_data={'{{package}}': ['i18n/*/LC_MESSAGES/*.mo']}, #message_extractors={'{{package}}': [ # ('**.py', 'python', None), # {{babel_templates_extractor}}('public/**', 'ignore', None)]}, zip_safe={{zip_safe}}, paster_plugins={{egg_plugins}}, entry_points=""" [paste.app_factory] main = {{package}}.config.middleware:make_app [paste.app_install] main = pylons.util:PylonsInstaller """, ) Pylons-1.0.1/pylons/templates/default_project/test.ini_tmpl0000664000076500000240000000077611645401276024116 0ustar benstaff00000000000000# # {{project}} - Pylons testing environment configuration # # The %(here)s variable will be replaced with the parent directory of this file # [DEFAULT] debug = true # Uncomment and replace with the address which should receive any error reports #email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 [app:main] use = config:development.ini # Add additional test specific configuration options as necessary. Pylons-1.0.1/pylons/templates/minimal_project/0000775000076500000240000000000012012307216021356 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/minimal_project/+package+/0000775000076500000240000000000012012307216023077 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/minimal_project/+package+/__init__.py_tmpl0000664000076500000240000000000011645401276026246 0ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/minimal_project/+package+/config/0000775000076500000240000000000012012307216024344 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/minimal_project/+package+/config/deployment.ini_tmpl_tmpl0000664000076500000240000000250511645401276031333 0ustar benstaff00000000000000# # {{project}} - Pylons configuration # # The %(here)s variable will be replaced with the parent directory of this file # [DEFAULT] debug = true email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [server:main] use = egg:Paste#http host = 0.0.0.0 port = 5000 [app:main] use = egg:{{project}} full_stack = true static_files = true cache_dir = %(here)s/data beaker.session.key = {{package}} beaker.session.secret = ${app_instance_secret} app_instance_uuid = ${app_instance_uuid} # If you'd like to fine-tune the individual locations of the cache data dirs # for the Cache data, or the Session saves, un-comment the desired settings # here: #beaker.cache.data_dir = %(here)s/data/cache #beaker.session.data_dir = %(here)s/data/sessions # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* # Debug mode will enable the interactive debugging tool, allowing ANYONE to # execute malicious code after an exception is raised. set debug = false # Logging configuration [loggers] keys = root [handlers] keys = console [formatters] keys = generic [logger_root] level = INFO handlers = console [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s] [%(threadName)s] %(message)s Pylons-1.0.1/pylons/templates/minimal_project/+package+/controllers/0000775000076500000240000000000012012307216025445 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/minimal_project/+package+/controllers/__init__.py_tmpl0000664000076500000240000000120311645401276030622 0ustar benstaff00000000000000"""The base Controller API Provides the BaseController class for subclassing. """ from pylons.controllers import WSGIController {{if template_engine in ('genshi', 'jinja2', 'mako')}} from pylons.templating import render_{{template_engine}} as render {{endif}} class BaseController(WSGIController): def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. This routing information is # available in environ['pylons.routes_dict'] return WSGIController.__call__(self, environ, start_response) Pylons-1.0.1/pylons/templates/minimal_project/+package+/helpers.py_tmpl0000664000076500000240000000042111645401276026160 0ustar benstaff00000000000000"""Helper functions Consists of functions to typically be used within templates, but also available to Controllers. This module is available to templates as 'h'. """ # Import helpers as desired, or define your own, ie: #from webhelpers.html.tags import checkbox, password Pylons-1.0.1/pylons/templates/minimal_project/+package+/public/0000775000076500000240000000000012012307216024355 5ustar benstaff00000000000000Pylons-1.0.1/pylons/templates/minimal_project/+package+/public/bg.png0000775000076500000240000000052311645401276025472 0ustar benstaff00000000000000PNG  IHDR&#.sRGBbKGDY< pHYs  tIME2 ~p=tEXtCommentCreated with GIMPWIDATHǽUA0+?~o%@/% t~?_)}Rt1aNҤQtf Q\(E}Ւ%"R;`v]/. "mrGz%1Nƃԃtxm}*1(m?"|&5uqyO8ıIENDB`Pylons-1.0.1/pylons/templates/minimal_project/+package+/public/favicon.ico0000664000076500000240000000545611645401276026524 0ustar benstaff00000000000000(6h^ h( 333333033ff33036ffb303fnf300ff0ffnfdnfd`Ff  ??( N^ Z 6R&6 "bZb~ v Vn~"B^j  ~Rf*jFj vNj  b""f  >Zz^v&>n~Vj& Nb ^:RbjfvVr**>^j~Nf "*n R~zVj f&j>^ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ RRR 494 RRR #,G??CI=??',' - F ?,'!A/6X& J?#1 573>XX7E.1ZZZZZZZZZ!OQ ZZZZZZZZZ X+ZZZZZZZZZZZVSSZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ  ??(  WpTk Tk Tk Wn WkNaM_ViWo Tk Tk Tk Vn!iffkVq !`Z}cjOkl ffh)gdiC_ y  w=]j df(giPeb uMd jf( oa% } +)\w m * i:Qn%^&?~ O$6 V K Y ] >[#j c S| Y {7Q v  G w i4=\ e gEh C-n"u6 ??Pylons-1.0.1/pylons/templates/minimal_project/+package+/public/index.html_tmpl0000664000076500000240000001106411645401276027424 0ustar benstaff00000000000000 Welcome to Pylons!

Welcome to Logo displaying the word Pylons


Let's begin!

If you haven't used Pylons before, start with the beginners' tutorial.

Pylons-1.0.1/pylons/templates/minimal_project/+package+/public/pylons-logo.gif0000775000076500000240000000453711645401276027356 0ustar benstaff00000000000000GIF89a;Dzyu)))ZZZHHH%%%2!!!Yna(,<<;޾9{.©A 221(('LD&##"'''&&&"""  (((###$$%'(($##$$$(''***+++onn0!,;DpH,Ȥrl:ШtJZجvzxLl$͆Rn+4||2dC lezxq?=N v n? =pwӗ pڣŒb\eMY,[# ‹S&0܈gP0S6ȑG1 Cj;/*sQز/1e&f):ٳ0A@ҫ1؀hp ޼֖/ -w$% oΫw$x%AT^bd_5;RNR`[ =0 P{,f ""QVz +`Pi@O2,+u*P w@%2'@H" bwaUu.Md%i3QfE{H`L}jEQEAV^1(m UBKti@6T@c\D4-PD>+W64@64"N=xDiRExLY@!gQr/U᧍B EDdIj*: DI:U 5EDaN^[bD99N: :J}cR`kN)Gi)F JZ$a@:DJbgN{붲 A+m;bp.q-&;BXnO2WDJ;%6ZVFN D@JpöʂpxD˶JRuy"A/Zos| n3pL S@bW@]4< T26/k q(:7{F/xnKRYDfv-M`/@5?L$[76Q(#%A1_F(Պ)Ƹt&>w٠] w( y桼7(Gd 5{e x@cn\֋Xڢx|(A>(˞ ΄] pz@D>"x x?0xy#XS9z8]bq6$hGs~7EI@Ji'sяqѓ6X\?=z6 UUFdB&88y+툗@)_?d9] section of the Paste ini file (where defaults to main). """ # Configure the Pylons environment config = load_environment(global_conf, app_conf) # The Pylons WSGI app app = PylonsApp(config=config) # Routing/Session/Cache Middleware app = RoutesMiddleware(app, config['routes.map'], singleton=False) app = SessionMiddleware(app, config) # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) if asbool(full_stack): # Handle Python exceptions app = ErrorHandler(app, global_conf, **config['pylons.errorware']) # Display error documents for 401, 403, 404 status codes (and # 500 when debug is disabled) if asbool(config['debug']): app = StatusCodeRedirect(app) else: app = StatusCodeRedirect(app, [401, 403, 404, 500]) # Establish the Registry for this application app = RegistryManager(app) if asbool(static_files): # Serve static files static_app = StaticURLParser(config['pylons.paths']['static_files']) app = Cascade([static_app, app]) app.config = config return app class Globals(object): """Globals acts as a container for objects available throughout the life of the application """ def __init__(self, config): """One instance of Globals is created during application initialization and is available during requests via the 'app_globals' variable """ self.cache = CacheManager(**parse_cache_config_options(config)) Pylons-1.0.1/pylons/templates/minimal_project/development.ini_tmpl0000664000076500000240000000361111645401276025452 0ustar benstaff00000000000000# # {{project}} - Pylons development environment configuration # # The %(here)s variable will be replaced with the parent directory of this file # [DEFAULT] debug = true # Uncomment and replace with the address which should receive any error reports #email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 [app:main] use = egg:{{project}} full_stack = true static_files = true cache_dir = %(here)s/data beaker.session.key = {{package}} beaker.session.secret = somesecret # If you'd like to fine-tune the individual locations of the cache data dirs # for the Cache data, or the Session saves, un-comment the desired settings # here: #beaker.cache.data_dir = %(here)s/data/cache #beaker.session.data_dir = %(here)s/data/sessions # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* # Debug mode will enable the interactive debugging tool, allowing ANYONE to # execute malicious code after an exception is raised. #set debug = false # Logging configuration [loggers] keys = root, routes, {{package_logger}} [handlers] keys = console [formatters] keys = generic [logger_root] level = INFO handlers = console [logger_routes] level = INFO handlers = qualname = routes.middleware # "level = DEBUG" logs the route matched and routing variables. [logger_{{package_logger}}] level = DEBUG handlers = qualname = {{package}} {{if sqlalchemy}} [logger_sqlalchemy] level = INFO handlers = qualname = sqlalchemy.engine # "level = INFO" logs SQL queries. # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) {{endif}} [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] [%(threadName)s] %(message)s datefmt = %H:%M:%S Pylons-1.0.1/pylons/templates/minimal_project/ez_setup.py0000664000076500000240000002276411645401276023615 0ustar benstaff00000000000000#!python """Bootstrap setuptools installation If you want to use setuptools in your package's setup.py, just include this file in the same directory with it, and add this to the top of your setup.py:: from ez_setup import use_setuptools use_setuptools() If you want to require a specific version of setuptools, set a download mirror, or use an alternate download directory, you can do so by supplying the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import sys DEFAULT_VERSION = "0.6c9" DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] md5_data = { 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', } import sys, os try: from hashlib import md5 except ImportError: from md5 import md5 def _validate_md5(egg_name, data): if egg_name in md5_data: digest = md5(data).hexdigest() if digest != md5_data[egg_name]: print >>sys.stderr, ( "md5 validation of %s failed! (Possible download problem?)" % egg_name ) sys.exit(2) return data def use_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15 ): """Automatically find/download setuptools and make it available on sys.path `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where setuptools will be downloaded, if it is not already available. If `download_delay` is specified, it should be the number of seconds that will be paused before initiating a download, should one be required. If an older version of setuptools is installed, this routine will print a message to ``sys.stderr`` and raise SystemExit in an attempt to abort the calling script. """ was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules def do_download(): egg = download_setuptools(version, download_base, to_dir, download_delay) sys.path.insert(0, egg) import setuptools; setuptools.bootstrap_install_from = egg try: import pkg_resources except ImportError: return do_download() try: pkg_resources.require("setuptools>="+version); return except pkg_resources.VersionConflict, e: if was_imported: print >>sys.stderr, ( "The required version of setuptools (>=%s) is not available, and\n" "can't be installed while this script is running. Please install\n" " a more recent version first, using 'easy_install -U setuptools'." "\n\n(Currently using %r)" ) % (version, e.args[0]) sys.exit(2) else: del pkg_resources, sys.modules['pkg_resources'] # reload ok return do_download() except pkg_resources.DistributionNotFound: return do_download() def download_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay = 15 ): """Download setuptools from a specified location and return its filename `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. """ import urllib2, shutil egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) url = download_base + egg_name saveto = os.path.join(to_dir, egg_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads try: from distutils import log if delay: log.warn(""" --------------------------------------------------------------------------- This script requires setuptools version %s to run (even to display help). I will attempt to download it for you (from %s), but you may need to enable firewall access for this script first. I will start the download in %d seconds. (Note: if this machine does not have network access, please obtain the file %s and place it in this directory before rerunning this script.) ---------------------------------------------------------------------------""", version, download_base, delay, url ); from time import sleep; sleep(delay) log.warn("Downloading %s", url) src = urllib2.urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = _validate_md5(egg_name, src.read()) dst = open(saveto,"wb"); dst.write(data) finally: if src: src.close() if dst: dst.close() return os.path.realpath(saveto) def main(argv, version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" try: import setuptools except ImportError: egg = None try: egg = download_setuptools(version, delay=0) sys.path.insert(0,egg) from setuptools.command.easy_install import main return main(list(argv)+[egg]) # we're done here finally: if egg and os.path.exists(egg): os.unlink(egg) else: if setuptools.__version__ == '0.0.1': print >>sys.stderr, ( "You have an obsolete version of setuptools installed. Please\n" "remove it from your system entirely before rerunning this script." ) sys.exit(2) req = "setuptools>="+version import pkg_resources try: pkg_resources.require(req) except pkg_resources.VersionConflict: try: from setuptools.command.easy_install import main except ImportError: from easy_install import main main(list(argv)+[download_setuptools(delay=0)]) sys.exit(0) # try to force an exit else: if argv: from setuptools.command.easy_install import main main(argv) else: print "Setuptools version",version,"or greater has been installed." print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' def update_md5(filenames): """Update our built-in md5 registry""" import re for name in filenames: base = os.path.basename(name) f = open(name,'rb') md5_data[base] = md5(f.read()).hexdigest() f.close() data = [" %r: %r,\n" % it for it in md5_data.items()] data.sort() repl = "".join(data) import inspect srcfile = inspect.getsourcefile(sys.modules[__name__]) f = open(srcfile, 'rb'); src = f.read(); f.close() match = re.search("\nmd5_data = {\n([^}]+)}", src) if not match: print >>sys.stderr, "Internal error!" sys.exit(2) src = src[:match.start(1)] + repl + src[match.end(1):] f = open(srcfile,'w') f.write(src) f.close() if __name__=='__main__': if len(sys.argv)>2 and sys.argv[1]=='--md5update': update_md5(sys.argv[2:]) else: main(sys.argv[1:]) Pylons-1.0.1/pylons/templates/minimal_project/MANIFEST.in_tmpl0000664000076500000240000000020011645401276024154 0ustar benstaff00000000000000include {{package}}/config/deployment.ini_tmpl recursive-include {{package}}/public * recursive-include {{package}}/templates * Pylons-1.0.1/pylons/templates/minimal_project/README.txt_tmpl0000664000076500000240000000072311645401276024126 0ustar benstaff00000000000000This file is for you to describe the {{project}} application. Typically you would include information such as the information below: Installation and Setup ====================== Install ``{{project}}`` using easy_install:: easy_install {{project}} Make a config file as follows:: paster make-config {{project}} config.ini Tweak the config file as appropriate and then setup the application:: paster setup-app config.ini Then you are ready to go. Pylons-1.0.1/pylons/templates/minimal_project/setup.cfg_tmpl0000664000076500000240000000022611645401276024247 0ustar benstaff00000000000000[egg_info] tag_build = dev tag_svn_revision = true [easy_install] find_links = http://www.pylonshq.com/download/ [nosetests] with-pylons = test.ini Pylons-1.0.1/pylons/templates/minimal_project/setup.py_tmpl0000664000076500000240000000227111645413275024144 0ustar benstaff00000000000000try: from setuptools import setup, find_packages except ImportError: from ez_setup import use_setuptools use_setuptools() from setuptools import setup, find_packages setup( name='{{project}}', version='{{version}}', description={{repr(description)}}, author={{repr(author)}}, author_email={{repr(author_email)}}, url={{repr(url)}}, install_requires=[ "Pylons>=1.0.1rc1", {{if sqlalchemy}} "SQLAlchemy>=0.5", {{endif}} {{if template_engine == 'genshi'}} "Genshi>=0.4", {{elif template_engine == 'jinja2'}} "Jinja2", {{endif}} ], setup_requires=["PasteScript>=1.6.3"], packages=find_packages(exclude=['ez_setup']), include_package_data=True, test_suite='nose.collector', package_data={'{{package}}': ['i18n/*/LC_MESSAGES/*.mo']}, #message_extractors={'{{package}}': [ # ('**.py', 'python', None), # {{babel_templates_extractor}}('public/**', 'ignore', None)]}, zip_safe={{zip_safe}}, paster_plugins={{egg_plugins}}, entry_points=""" [paste.app_factory] main = {{package}}.wsgiapp:make_app [paste.app_install] main = pylons.util:PylonsInstaller """, ) Pylons-1.0.1/pylons/templates/minimal_project/test.ini_tmpl0000664000076500000240000000077611645401276024120 0ustar benstaff00000000000000# # {{project}} - Pylons testing environment configuration # # The %(here)s variable will be replaced with the parent directory of this file # [DEFAULT] debug = true # Uncomment and replace with the address which should receive any error reports #email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 [app:main] use = config:development.ini # Add additional test specific configuration options as necessary. Pylons-1.0.1/pylons/templates/restcontroller.py_tmpl0000664000076500000240000000401611645401276022706 0ustar benstaff00000000000000import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect {{importstatement}} log = logging.getLogger(__name__) class {{classname}}Controller(BaseController): """REST Controller styled on the Atom Publishing Protocol""" # To properly map this controller, ensure your config/routing.py # file has a resource setup: # {{resource_command}} def index(self, format='html'): """GET /{{path}}{{pluralname}}: All items in the collection""" # url('{{nameprefix}}{{pluralname}}') def create(self): """POST /{{path}}{{pluralname}}: Create a new item""" # url('{{nameprefix}}{{pluralname}}') def new(self, format='html'): """GET /{{path}}{{pluralname}}/new: Form to create a new item""" # url('{{nameprefix}}new_{{singularname}}') def update(self, id): """PUT /{{path}}{{pluralname}}/id: Update an existing item""" # Forms posted to this method should contain a hidden field: # # Or using helpers: # h.form(url('{{nameprefix}}{{singularname}}', id=ID), # method='put') # url('{{nameprefix}}{{singularname}}', id=ID) def delete(self, id): """DELETE /{{path}}{{pluralname}}/id: Delete an existing item""" # Forms posted to this method should contain a hidden field: # # Or using helpers: # h.form(url('{{nameprefix}}{{singularname}}', id=ID), # method='delete') # url('{{nameprefix}}{{singularname}}', id=ID) def show(self, id, format='html'): """GET /{{path}}{{pluralname}}/id: Show a specific item""" # url('{{nameprefix}}{{singularname}}', id=ID) def edit(self, id, format='html'): """GET /{{path}}{{pluralname}}/id/edit: Form to edit an existing item""" # url('{{nameprefix}}edit_{{singularname}}', id=ID) Pylons-1.0.1/pylons/templates/test_controller.py_tmpl0000664000076500000240000000032711645401276023050 0ustar benstaff00000000000000from {{base_package}}.tests import * class Test{{name}}Controller(TestController): def test_index(self): response = self.app.get(url(controller='{{fname}}', action='index')) # Test response... Pylons-1.0.1/pylons/templates/test_restcontroller.py_tmpl0000664000076500000240000000317711645401276023754 0ustar benstaff00000000000000from {{base_package}}.tests import * class Test{{name}}Controller(TestController): def test_index(self): response = self.app.get(url('{{nameprefix}}{{pluralname}}')) # Test response... def test_index_as_xml(self): response = self.app.get(url('formatted_{{nameprefix}}{{pluralname}}', format='xml')) def test_create(self): response = self.app.post(url('{{nameprefix}}{{pluralname}}')) def test_new(self): response = self.app.get(url('{{nameprefix}}new_{{singularname}}')) def test_new_as_xml(self): response = self.app.get(url('formatted_{{nameprefix}}new_{{singularname}}', format='xml')) def test_update(self): response = self.app.put(url('{{nameprefix}}{{singularname}}', id=1)) def test_update_browser_fakeout(self): response = self.app.post(url('{{nameprefix}}{{singularname}}', id=1), params=dict(_method='put')) def test_delete(self): response = self.app.delete(url('{{nameprefix}}{{singularname}}', id=1)) def test_delete_browser_fakeout(self): response = self.app.post(url('{{nameprefix}}{{singularname}}', id=1), params=dict(_method='delete')) def test_show(self): response = self.app.get(url('{{nameprefix}}{{singularname}}', id=1)) def test_show_as_xml(self): response = self.app.get(url('formatted_{{nameprefix}}{{singularname}}', id=1, format='xml')) def test_edit(self): response = self.app.get(url('{{nameprefix}}edit_{{singularname}}', id=1)) def test_edit_as_xml(self): response = self.app.get(url('formatted_{{nameprefix}}edit_{{singularname}}', id=1, format='xml')) Pylons-1.0.1/pylons/templating.py0000664000076500000240000002667711671742375016767 0ustar benstaff00000000000000"""Render functions and helpers Render functions and helpers ============================ :mod:`pylons.templating` includes several basic render functions, :func:`render_mako`, :func:`render_genshi` and :func:`render_jinja2` that render templates from the file-system with the assumption that variables intended for the will be attached to :data:`tmpl_context` (hereafter referred to by its short name of :data:`c` which it is commonly imported as). The default render functions work with the template language loader object that is setup on the :data:`app_globals` object in the project's :file:`config/environment.py`. Usage ----- Generally, one of the render functions will be imported in the controller. Variables intended for the template are attached to the :data:`c` object. The render functions return unicode (they actually return :class:`~webhelpers.html.literal` objects, a subclass of unicode). .. admonition :: Tip :data:`tmpl_context` (template context) is abbreviated to :data:`c` instead of its full name since it will likely be used extensively and it's much faster to use :data:`c`. Of course, for users that can't tolerate one-letter variables, feel free to not import :data:`tmpl_context` as :data:`c` since both names are available in templates as well. Example of rendering a template with some variables:: from pylons import tmpl_context as c from pylons.templating import render_mako as render from sampleproject.lib.base import BaseController class SampleController(BaseController): def index(self): c.first_name = "Joe" c.last_name = "Smith" return render('/some/template.mako') And the accompanying Mako template: .. code-block:: mako Hello ${c.first name}, I see your lastname is ${c.last_name}! Your controller will have additional default imports for commonly used functions. Template Globals ---------------- Templates rendered in Pylons should include the default Pylons globals as the :func:`render_mako`, :func:`render_genshi` and :func:`render_jinja2` functions. The full list of Pylons globals that are included in the template's namespace are: - :term:`c` -- Template context object - :term:`tmpl_context` -- Template context object - :data:`config` -- Pylons :class:`~pylons.configuration.PylonsConfig` object (acts as a dict) - :term:`app_globals` -- Project application globals object - :term:`h` -- Project helpers module reference - :data:`request` -- Pylons :class:`~pylons.controllers.util.Request` object for this request - :data:`response` -- Pylons :class:`~pylons.controllers.util.Response` object for this request - :class:`session` -- Pylons session object (unless Sessions are removed) - :class:`url ` -- Routes url generator object - :class:`translator` -- Gettext translator object configured for current locale - :func:`ungettext` -- Unicode capable version of gettext's ngettext function (handles plural translations) - :func:`_` -- Unicode capable gettext translate function - :func:`N_` -- gettext no-op function to mark a string for translation, but doesn't actually translate Configuring the template language --------------------------------- The template engine is created in the projects ``config/environment.py`` and attached to the ``app_globals`` (g) instance. Configuration options can be directly passed into the template engine, and are used by the render functions. .. warning:: Don't change the variable name on :data:`app_globals` that the template loader is attached to if you want to use the render_* functions that :mod:`pylons.templating` comes with. The render_* functions look for the template loader to render the template. """ import logging from webhelpers.html import literal import pylons __all__ = ['render_genshi', 'render_jinja2', 'render_mako'] PYLONS_VARS = ['c', 'app_globals', 'config', 'h', 'render', 'request', 'session', 'translator', 'ungettext', '_', 'N_'] log = logging.getLogger(__name__) def pylons_globals(): """Create and return a dictionary of global Pylons variables Render functions should call this to retrieve a list of global Pylons variables that should be included in the global template namespace if possible. Pylons variables that are returned in the dictionary: ``c``, ``h``, ``_``, ``N_``, config, request, response, translator, ungettext, ``url`` If SessionMiddleware is being used, ``session`` will also be available in the template namespace. """ conf = pylons.config._current_obj() c = pylons.tmpl_context._current_obj() app_globals = conf.get('pylons.app_globals') pylons_vars = dict( c=c, tmpl_context=c, config=conf, app_globals=app_globals, h=conf.get('pylons.h'), request=pylons.request._current_obj(), response=pylons.response._current_obj(), url=pylons.url._current_obj(), translator=pylons.translator._current_obj(), ungettext=pylons.i18n.ungettext, _=pylons.i18n._, N_=pylons.i18n.N_ ) # If the session was overriden to be None, don't populate the session # var econf = pylons.config['pylons.environ_config'] if 'beaker.session' in pylons.request.environ or \ ('session' in econf and econf['session'] in pylons.request.environ): pylons_vars['session'] = pylons.session._current_obj() log.debug("Created render namespace with pylons vars: %s", pylons_vars) return pylons_vars def cached_template(template_name, render_func, ns_options=(), cache_key=None, cache_type=None, cache_expire=None, **kwargs): """Cache and render a template Cache a template to the namespace ``template_name``, along with a specific key if provided. Basic Options ``template_name`` Name of the template, which is used as the template namespace. ``render_func`` Function used to generate the template should it no longer be valid or doesn't exist in the cache. ``ns_options`` Tuple of strings, that should correspond to keys likely to be in the ``kwargs`` that should be used to construct the namespace used for the cache. For example, if the template language supports the 'fragment' option, the namespace should include it so that the cached copy for a template is not the same as the fragment version of it. Caching options (uses Beaker caching middleware) ``cache_key`` Key to cache this copy of the template under. ``cache_type`` Valid options are ``dbm``, ``file``, ``memory``, ``database``, or ``memcached``. ``cache_expire`` Time in seconds to cache this template with this ``cache_key`` for. Or use 'never' to designate that the cache should never expire. The minimum key required to trigger caching is ``cache_expire='never'`` which will cache the template forever seconds with no key. """ # If one of them is not None then the user did set something if cache_key is not None or cache_expire is not None or cache_type \ is not None: if not cache_type: cache_type = 'dbm' if not cache_key: cache_key = 'default' if cache_expire == 'never': cache_expire = None namespace = template_name for name in ns_options: namespace += str(kwargs.get(name)) cache = pylons.cache.get_cache(namespace, type=cache_type) content = cache.get_value(cache_key, createfunc=render_func, expiretime=cache_expire) return content else: return render_func() def render_mako(template_name, extra_vars=None, cache_key=None, cache_type=None, cache_expire=None): """Render a template with Mako Accepts the cache options ``cache_key``, ``cache_type``, and ``cache_expire``. """ # Create a render callable for the cache function def render_template(): # Pull in extra vars if needed globs = extra_vars or {} # Second, get the globals globs.update(pylons_globals()) # Grab a template reference template = globs['app_globals'].mako_lookup.get_template(template_name) return literal(template.render_unicode(**globs)) return cached_template(template_name, render_template, cache_key=cache_key, cache_type=cache_type, cache_expire=cache_expire) def render_mako_def(template_name, def_name, cache_key=None, cache_type=None, cache_expire=None, **kwargs): """Render a def block within a Mako template Takes the template name, and the name of the def within it to call. If the def takes arguments, they should be passed in as keyword arguments. Example:: # To call the def 'header' within the 'layout.mako' template # with a title argument render_mako_def('layout.mako', 'header', title='Testing') Also accepts the cache options ``cache_key``, ``cache_type``, and ``cache_expire``. """ # Create a render callable for the cache function def render_template(): # Pull in extra vars if needed globs = kwargs or {} # Second, get the globals globs.update(pylons_globals()) # Grab a template reference template = globs['app_globals'].mako_lookup.get_template( template_name).get_def(def_name) return literal(template.render_unicode(**globs)) return cached_template(template_name, render_template, cache_key=cache_key, cache_type=cache_type, cache_expire=cache_expire) def render_genshi(template_name, extra_vars=None, cache_key=None, cache_type=None, cache_expire=None, method='xhtml'): """Render a template with Genshi Accepts the cache options ``cache_key``, ``cache_type``, and ``cache_expire`` in addition to method which are passed to Genshi's render function. """ # Create a render callable for the cache function def render_template(): # Pull in extra vars if needed globs = extra_vars or {} # Second, get the globals globs.update(pylons_globals()) # Grab a template reference template = globs['app_globals'].genshi_loader.load(template_name) return literal(template.generate(**globs).render(method=method, encoding=None)) return cached_template(template_name, render_template, cache_key=cache_key, cache_type=cache_type, cache_expire=cache_expire, ns_options=('method'), method=method) def render_jinja2(template_name, extra_vars=None, cache_key=None, cache_type=None, cache_expire=None): """Render a template with Jinja2 Accepts the cache options ``cache_key``, ``cache_type``, and ``cache_expire``. """ # Create a render callable for the cache function def render_template(): # Pull in extra vars if needed globs = extra_vars or {} # Second, get the globals globs.update(pylons_globals()) # Grab a template reference template = \ globs['app_globals'].jinja2_env.get_template(template_name) return literal(template.render(**globs)) return cached_template(template_name, render_template, cache_key=cache_key, cache_type=cache_type, cache_expire=cache_expire) Pylons-1.0.1/pylons/test.py0000664000076500000240000000523211671742410015550 0ustar benstaff00000000000000"""Test related functionality Adds a Pylons plugin to `nose `_ that loads the Pylons app *before* scanning for doc tests. This can be configured in the projects :file:`setup.cfg` under a ``[nosetests]`` block: .. code-block:: ini [nosetests] with-pylons=development.ini Alternate ini files may be specified if the app should be loaded using a different configuration. """ import os import sys import nose.plugins import pkg_resources from paste.deploy import loadapp import pylons from pylons.i18n.translation import _get_translator pylonsapp = None class PylonsPlugin(nose.plugins.Plugin): """Nose plugin extension For use with nose to allow a project to be configured before nose proceeds to scan the project for doc tests and unit tests. This prevents modules from being loaded without a configured Pylons environment. """ enabled = False enableOpt = 'pylons_config' name = 'pylons' def add_options(self, parser, env=os.environ): """Add command-line options for this plugin""" env_opt = 'NOSE_WITH_%s' % self.name.upper() env_opt.replace('-', '_') parser.add_option("--with-%s" % self.name, dest=self.enableOpt, type="string", default="", help="Setup Pylons environment with the config file" " specified by ATTR [NOSE_ATTR]") def configure(self, options, conf): """Configure the plugin""" self.config_file = None self.conf = conf if hasattr(options, self.enableOpt): self.enabled = bool(getattr(options, self.enableOpt)) self.config_file = getattr(options, self.enableOpt) def begin(self): """Called before any tests are collected or run Loads the application, and in turn its configuration. """ global pylonsapp path = os.getcwd() sys.path.insert(0, path) pkg_resources.working_set.add_entry(path) self.app = pylonsapp = loadapp('config:' + self.config_file, relative_to=path) # Setup the config and app_globals, only works if we can get # to the config object conf = getattr(pylonsapp, 'config') if conf: pylons.config._push_object(conf) if 'pylons.app_globals' in conf: pylons.app_globals._push_object(conf['pylons.app_globals']) # Initialize a translator for tests that utilize i18n translator = _get_translator(pylons.config.get('lang')) pylons.translator._push_object(translator) Pylons-1.0.1/pylons/testutil.py0000664000076500000240000000604111671742433016452 0ustar benstaff00000000000000"""Utility classes for creating workable pylons controllers for unit testing. These classes are used solely by Pylons for unit testing controller functionality. """ import gettext import pylons from pylons.configuration import request_defaults, response_defaults from pylons.controllers.util import Request, Response from pylons.util import ContextObj, PylonsContext class ControllerWrap(object): def __init__(self, controller): self.controller = controller def __call__(self, environ, start_response): app = self.controller() app.start_response = None return app(environ, start_response) class SetupCacheGlobal(object): def __init__(self, app, environ, setup_g=True, setup_cache=False, setup_session=False): if setup_g: g = type('G object', (object,), {}) g.message = 'Hello' g.counter = 0 g.pylons_config = type('App conf', (object,), {}) g.pylons_config.app_conf = dict(cache_enabled='True') self.g = g self.app = app self.environ = environ self.setup_cache = setup_cache self.setup_session = setup_session self.setup_g = setup_g def __call__(self, environ, start_response): registry = environ['paste.registry'] py_obj = PylonsContext() environ_config = environ.setdefault('pylons.environ_config', {}) if self.setup_cache: py_obj.cache = environ['beaker.cache'] registry.register(pylons.cache, environ['beaker.cache']) environ_config['cache'] = 'beaker.cache' if self.setup_session: py_obj.session = environ['beaker.session'] registry.register(pylons.session, environ['beaker.session']) environ_config['session'] = 'beaker.session' if self.setup_g: py_obj.app_globals = self.g registry.register(pylons.app_globals, self.g) translator = gettext.NullTranslations() py_obj.translator = translator registry.register(pylons.translator, translator) # Update the environ req = Request(environ, charset=request_defaults['charset'], unicode_errors=request_defaults['errors'], decode_param_names=request_defaults['decode_param_names'] ) req.language = request_defaults['language'] response = Response( content_type=response_defaults['content_type'], charset=response_defaults['charset']) response.headers.update(response_defaults['headers']) environ.update(self.environ) py_obj.config = pylons.config._current_obj() py_obj.request = req py_obj.response = response py_obj.tmpl_context = ContextObj() environ['pylons.pylons'] = py_obj registry.register(pylons.request, req) registry.register(pylons.response, response) if 'routes.url' in environ: registry.register(pylons.url, environ['routes.url']) return self.app(environ, start_response) Pylons-1.0.1/pylons/url.py0000664000076500000240000000274311671742473015410 0ustar benstaff00000000000000from repoze.bfg.encode import urlencode from repoze.bfg.threadlocal import get_current_registry from repoze.bfg.url import _join_elements from pylons.interfaces import IRoutesMapper def route_url(route_name, request, *elements, **kw): try: reg = request.registry except AttributeError: reg = get_current_registry() # b/c mapper = reg.getUtility(IRoutesMapper) route = mapper.routes.get(route_name) if route and 'custom_url_generator' in route.__dict__: route_name, request, elements, kw = route.custom_url_generator( route_name, request, *elements, **kw) anchor = '' qs = '' app_url = None if '_query' in kw: qs = '?' + urlencode(kw.pop('_query'), doseq=True) if '_anchor' in kw: anchor = kw.pop('_anchor') if isinstance(anchor, unicode): anchor = anchor.encode('utf-8') anchor = '#' + anchor if '_app_url' in kw: app_url = kw.pop('_app_url') path = mapper.generate(route_name, kw) # raises KeyError if generate fails if elements: suffix = _join_elements(elements) if not path.endswith('/'): suffix = '/' + suffix else: suffix = '' if app_url is None: # we only defer lookup of application_url until here because # it's somewhat expensive; we won't need to do it if we've # been passed _app_url app_url = request.application_url return app_url + path + suffix + qs + anchor Pylons-1.0.1/pylons/util.py0000664000076500000240000001776311671742541015567 0ustar benstaff00000000000000"""Paste Template and Pylons utility functions PylonsTemplate is a Paste Template sub-class that configures the source directory and default plug-ins for a new Pylons project. The minimal template a more minimal template with less additional directories and layout. """ import logging import sys import pkg_resources from paste.deploy.converters import asbool from paste.script.appinstall import Installer from paste.script.templates import Template, var from tempita import paste_script_template_renderer import pylons import pylons.configuration import pylons.i18n __all__ = ['AttribSafeContextObj', 'ContextObj', 'PylonsContext', 'class_name_from_module_name', 'call_wsgi_application'] log = logging.getLogger(__name__) def call_wsgi_application(application, environ, catch_exc_info=False): """ Call the given WSGI application, returning ``(status_string, headerlist, app_iter)`` Be sure to call ``app_iter.close()`` if it's there. If catch_exc_info is true, then returns ``(status_string, headerlist, app_iter, exc_info)``, where the fourth item may be None, but won't be if there was an exception. If you don't do this and there was an exception, the exception will be raised directly. """ captured = [] output = [] def start_response(status, headers, exc_info=None): if exc_info is not None and not catch_exc_info: raise exc_info[0], exc_info[1], exc_info[2] captured[:] = [status, headers, exc_info] return output.append app_iter = application(environ, start_response) if not captured or output: try: output.extend(app_iter) finally: if hasattr(app_iter, 'close'): app_iter.close() app_iter = output if catch_exc_info: return (captured[0], captured[1], app_iter, captured[2]) else: return (captured[0], captured[1], app_iter) def class_name_from_module_name(module_name): """Takes a module name and returns the name of the class it defines. If the module name contains dashes, they are replaced with underscores. Example:: >>> class_name_from_module_name('with-dashes') 'WithDashes' >>> class_name_from_module_name('with_underscores') 'WithUnderscores' >>> class_name_from_module_name('oneword') 'Oneword' """ words = module_name.replace('-', '_').split('_') return ''.join(w.title() for w in words) class PylonsContext(object): """Pylons context object All the Pylons Stacked Object Proxies are also stored here, for use in generators and async based operation where the globals can't be used. This object is attached in :class:`~pylons.controllers.core.WSGIController` instances as :attr:`~WSGIController._py_object`. For example:: class MyController(WSGIController): def index(self): pyobj = self._py_object return "Environ is %s" % pyobj.request.environ """ pass class ContextObj(object): """The :term:`tmpl_context` object, with strict attribute access (raises an Exception when the attribute does not exist)""" def __repr__(self): attrs = sorted((name, value) for name, value in self.__dict__.iteritems() if not name.startswith('_')) parts = [] for name, value in attrs: value_repr = repr(value) if len(value_repr) > 70: value_repr = value_repr[:60] + '...' + value_repr[-5:] parts.append(' %s=%s' % (name, value_repr)) return '<%s.%s at %s%s>' % ( self.__class__.__module__, self.__class__.__name__, hex(id(self)), ','.join(parts)) class AttribSafeContextObj(ContextObj): """The :term:`tmpl_context` object, with lax attribute access ( returns '' when the attribute does not exist)""" def __getattr__(self, name): try: return object.__getattribute__(self, name) except AttributeError: log.debug("No attribute called %s found on c object, returning " "empty string", name) return '' class PylonsTemplate(Template): _template_dir = ('pylons', 'templates/default_project') template_renderer = staticmethod(paste_script_template_renderer) summary = 'Pylons application template' egg_plugins = ['PasteScript', 'Pylons'] vars = [ var('template_engine', 'mako/genshi/jinja2/etc: Template language', default='mako'), var('sqlalchemy', 'True/False: Include SQLAlchemy configuration', default=False), ] ensure_names = ['description', 'author', 'author_email', 'url'] def pre(self, command, output_dir, vars): """Called before template is applied.""" package_logger = vars['package'] if package_logger == 'root': # Rename the app logger in the rare case a project is named 'root' package_logger = 'app' vars['package_logger'] = package_logger vars['template_engine'] = 'mako' template_engine = 'mako' if template_engine == 'mako': # Support a Babel extractor default for Mako vars['babel_templates_extractor'] = \ ("('templates/**.mako', 'mako', {'input_encoding': 'utf-8'})" ",\n%s#%s" % (' ' * 4, ' ' * 8)) else: vars['babel_templates_extractor'] = '' # Ensure these exist in the namespace for name in self.ensure_names: vars.setdefault(name, '') vars['version'] = vars.get('version', '0.1') vars['zip_safe'] = asbool(vars.get('zip_safe', 'false')) vars['sqlalchemy'] = asbool(vars.get('sqlalchemy', 'false')) class MinimalPylonsTemplate(PylonsTemplate): _template_dir = ('pylons', 'templates/minimal_project') summary = 'Pylons minimal application template' vars = [ var('template_engine', 'mako/genshi/jinja2/etc: Template language', default='mako'), ] class LegacyPylonsTemplate(PylonsTemplate): _template_dir = ('pylons', 'templates/legacy_project') summary = 'Pylons legacy application template' vars = [ var('template_engine', 'mako/genshi/jinja2/etc: Template language', default='mako'), ] class NewPylonsTemplate(PylonsTemplate): _template_dir = ('pylons', 'templates/new_project') summary = 'Pylons "newstyle" application template' vars = [] class NewMinimalPylonsTemplate(PylonsTemplate): _template_dir = ('pylons', 'templates/newminimal_project') summary = 'Pylons "newstyle" minimal application template' vars = [] class NewSQLAlchemyTemplate(PylonsTemplate): _template_dir = ('pylons', 'templates/newsqla_project') summary = 'Pylons "newstyle" SQLAlchemy template' vars = [] class PylonsInstaller(Installer): use_cheetah = False config_file = 'config/deployment.ini_tmpl' def config_content(self, command, vars): """ Called by ``self.write_config``, this returns the text content for the config file, given the provided variables. """ modules = [line.strip() for line in self.dist.get_metadata_lines('top_level.txt') if line.strip() and not line.strip().startswith('#')] if not modules: print >> sys.stderr, 'No modules are listed in top_level.txt' print >> sys.stderr, \ 'Try running python setup.py egg_info to regenerate that file' for module in modules: if pkg_resources.resource_exists(module, self.config_file): return self.template_renderer( pkg_resources.resource_string(module, self.config_file), vars, filename=self.config_file) # Legacy support for the old location in egg-info return super(PylonsInstaller, self).config_content(command, vars) def resolve_dotted(name): return pkg_resources.EntryPoint.parse('x=%s' % name).load(False) Pylons-1.0.1/pylons/wsgiapp.py0000664000076500000240000003173611671742705016262 0ustar benstaff00000000000000"""WSGI App Creator This module is responsible for creating the basic Pylons WSGI application (PylonsApp). It's generally assumed that it will be called by Paste, though any WSGI server could create and call the WSGI app as well. """ import logging import sys import paste.registry import pkg_resources from webob.exc import HTTPNotFound import pylons import pylons.templating from pylons.controllers.util import Request, Response from pylons.i18n.translation import _get_translator from pylons.util import (AttribSafeContextObj, ContextObj, PylonsContext, class_name_from_module_name) __all__ = ['PylonsApp'] log = logging.getLogger(__name__) class PylonsApp(object): """Pylons WSGI Application This basic WSGI app is provided should a web developer want to get access to the most basic Pylons web application environment available. By itself, this Pylons web application does little more than dispatch to a controller and setup the context object, the request object, and the globals object. Additional functionality like sessions, and caching can be setup by altering the ``environ['pylons.environ_config']`` setting to indicate what key the ``session`` and ``cache`` functionality should come from. Resolving the URL and dispatching can be customized by sub-classing or "monkey-patching" this class. Subclassing is the preferred approach. """ def __init__(self, config=None, **kwargs): """Initialize a base Pylons WSGI application The base Pylons WSGI application requires several keywords, the package name, and the globals object. If no helpers object is provided then h will be None. """ self.config = config = config or pylons.config._current_obj() package_name = config['pylons.package'] self.helpers = config['pylons.h'] self.globals = config.get('pylons.app_globals') self.environ_config = config['pylons.environ_config'] self.package_name = package_name self.request_options = config['pylons.request_options'] self.response_options = config['pylons.response_options'] self.controller_classes = {} self.log_debug = False self.config.setdefault('lang', None) # Cache some options for use during requests self._session_key = self.environ_config.get('session', 'beaker.session') self._cache_key = self.environ_config.get('cache', 'beaker.cache') def __call__(self, environ, start_response): """Setup and handle a web request PylonsApp splits its functionality into several methods to make it easier to subclass and customize core functionality. The methods are called in the following order: 1. :meth:`~PylonsApp.setup_app_env` 2. :meth:`~PylonsApp.load_test_env` (Only if operating in testing mode) 3. :meth:`~PylonsApp.resolve` 4. :meth:`~PylonsApp.dispatch` The response from :meth:`~PylonsApp.dispatch` is expected to be an iterable (valid :pep:`333` WSGI response), which is then sent back as the response. """ # Cache the logging level for the request log_debug = self.log_debug = logging.DEBUG >= log.getEffectiveLevel() environ['pylons.log_debug'] = log_debug self.setup_app_env(environ, start_response) if 'paste.testing_variables' in environ: self.load_test_env(environ) if environ['PATH_INFO'] == '/_test_vars': paste.registry.restorer.save_registry_state(environ) start_response('200 OK', [('Content-type', 'text/plain')]) return ['%s' % paste.registry.restorer.get_request_id(environ)] controller = self.resolve(environ, start_response) response = self.dispatch(controller, environ, start_response) response_obj = callable(response) if 'paste.testing_variables' in environ and response_obj: environ['paste.testing_variables']['response'] = response try: if response_obj: return response(environ, start_response) elif response is not None: return response raise Exception("No content returned by controller (Did you " "remember to 'return' it?) in: %r" % controller.__name__) finally: # Help Python collect ram a bit faster by removing the reference # cycle that the pylons object causes if 'pylons.pylons' in environ: del environ['pylons.pylons'] def register_globals(self, environ): """Registers globals in the environment, called from :meth:`~PylonsApp.setup_app_env` Override this to control how the Pylons API is setup. Note that a custom render function will need to be used if the ``pylons.app_globals`` global is not available. """ pylons_obj = environ['pylons.pylons'] registry = environ['paste.registry'] registry.register(pylons.response, pylons_obj.response) registry.register(pylons.request, pylons_obj.request) registry.register(pylons.app_globals, self.globals) registry.register(pylons.config, self.config) registry.register(pylons.tmpl_context, pylons_obj.tmpl_context) registry.register(pylons.translator, pylons_obj.translator) if 'session' in pylons_obj.__dict__: registry.register(pylons.session, pylons_obj.session) if 'cache' in pylons_obj.__dict__: registry.register(pylons.cache, pylons_obj.cache) elif 'cache' in pylons_obj.app_globals.__dict__: registry.register(pylons.cache, pylons_obj.app_globals.cache) if 'routes.url' in environ: registry.register(pylons.url, environ['routes.url']) def setup_app_env(self, environ, start_response): """Setup and register all the Pylons objects with the registry After creating all the global objects for use in the request, :meth:`~PylonsApp.register_globals` is called to register them in the environment. """ if self.log_debug: log.debug("Setting up Pylons stacked object globals") # Setup the basic pylons global objects req_options = self.request_options req = Request(environ, charset=req_options['charset'], unicode_errors=req_options['errors'], decode_param_names=req_options['decode_param_names']) req.language = req_options['language'] req.config = self.config req.link, req.route_dict = environ['wsgiorg.routing_args'] response = Response( content_type=self.response_options['content_type'], charset=self.response_options['charset']) response.headers.update(self.response_options['headers']) # Store a copy of the request/response in environ for faster access pylons_obj = PylonsContext() pylons_obj.config = self.config pylons_obj.request = req pylons_obj.response = response pylons_obj.app_globals = self.globals pylons_obj.h = self.helpers if 'routes.url' in environ: pylons_obj.url = environ['routes.url'] environ['pylons.pylons'] = pylons_obj environ['pylons.environ_config'] = self.environ_config # Setup the translator object lang = self.config['lang'] pylons_obj.translator = _get_translator(lang, pylons_config=self.config) if self.config['pylons.strict_tmpl_context']: tmpl_context = ContextObj() else: tmpl_context = AttribSafeContextObj() pylons_obj.tmpl_context = req.tmpl_context = tmpl_context if self._session_key in environ: pylons_obj.session = req.session = environ[self._session_key] if self._cache_key in environ: pylons_obj.cache = environ[self._cache_key] # Load the globals with the registry if around if 'paste.registry' in environ: self.register_globals(environ) def resolve(self, environ, start_response): """Uses dispatching information found in ``environ['wsgiorg.routing_args']`` to retrieve a controller name and return the controller instance from the appropriate controller module. Override this to change how the controller name is found and returned. """ match = environ['wsgiorg.routing_args'][1] environ['pylons.routes_dict'] = match controller = match.get('controller', match.get('responder')) if not controller: return if self.log_debug: log.debug("Resolved URL to controller: %r", controller) return self.find_controller(controller) def find_controller(self, controller): """Locates a controller by attempting to import it then grab the SomeController instance from the imported module. Controller name is assumed to be a module in the controllers directory unless it contains a '.' or ':' which is then assumed to be a dotted path to the module and name of the controller object. Override this to change how the controller object is found once the URL has been resolved. """ # If this isn't a basestring, its an object, assume that its the # proper instance to begin with if not isinstance(controller, basestring): return controller # Check to see if we've cached the class instance for this name if controller in self.controller_classes: return self.controller_classes[controller] # Check to see if its a dotted name if '.' in controller or ':' in controller: mycontroller = pkg_resources.EntryPoint.parse( 'x=%s' % controller).load(False) self.controller_classes[controller] = mycontroller return mycontroller # Pull the controllers class name, import controller full_module_name = self.package_name + '.controllers.' \ + controller.replace('/', '.') # Hide the traceback here if the import fails (bad syntax and such) __traceback_hide__ = 'before_and_this' __import__(full_module_name) if hasattr(sys.modules[full_module_name], '__controller__'): mycontroller = getattr(sys.modules[full_module_name], sys.modules[full_module_name].__controller__) else: module_name = controller.split('/')[-1] class_name = class_name_from_module_name(module_name) + 'Controller' if self.log_debug: log.debug("Found controller, module: '%s', class: '%s'", full_module_name, class_name) mycontroller = getattr(sys.modules[full_module_name], class_name) self.controller_classes[controller] = mycontroller return mycontroller def dispatch(self, controller, environ, start_response): """Dispatches to a controller, will instantiate the controller if necessary. Override this to change how the controller dispatch is handled. """ log_debug = self.log_debug if not controller: if log_debug: log.debug("No controller found, returning 404 HTTP Not Found") return HTTPNotFound()(environ, start_response) # Is it a responder? if 'responder' in environ['pylons.routes_dict']: return controller(environ['pylons.pylons'].request) # Is it a class? Then its a WSGIController if hasattr(controller, '__bases__'): if log_debug: log.debug("Controller appears to be a class, instantiating") controller = controller() controller._pylons_log_debug = log_debug # Add a reference to the controller app located environ['pylons.controller'] = controller # Controller is assumed to handle a WSGI call if log_debug: log.debug("Calling controller class with WSGI interface") return controller(environ, start_response) def load_test_env(self, environ): """Sets up our Paste testing environment""" if self.log_debug: log.debug("Setting up paste testing environment variables") testenv = environ['paste.testing_variables'] pylons_obj = environ['pylons.pylons'] testenv['req'] = pylons_obj.request testenv['response'] = pylons_obj.response testenv['tmpl_context'] = pylons_obj.tmpl_context testenv['app_globals'] = testenv['g'] = pylons_obj.app_globals testenv['h'] = self.config['pylons.h'] testenv['config'] = self.config if hasattr(pylons_obj, 'session'): testenv['session'] = pylons_obj.session if hasattr(pylons_obj, 'cache'): testenv['cache'] = pylons_obj.cache elif hasattr(pylons_obj.app_globals, 'cache'): testenv['cache'] = pylons_obj.app_globals.cache Pylons-1.0.1/Pylons.egg-info/0000775000076500000240000000000012012307216015636 5ustar benstaff00000000000000Pylons-1.0.1/Pylons.egg-info/dependency_links.txt0000664000076500000240000000004512012307213021711 0ustar benstaff00000000000000http://www.pylonshq.com/download/1.0 Pylons-1.0.1/Pylons.egg-info/entry_points.txt0000664000076500000240000000102712012307213021131 0ustar benstaff00000000000000 [paste.paster_command] controller = pylons.commands:ControllerCommand restcontroller = pylons.commands:RestControllerCommand routes = pylons.commands:RoutesCommand shell = pylons.commands:ShellCommand [paste.paster_create_template] pylons = pylons.util:PylonsTemplate pylons_minimal = pylons.util:MinimalPylonsTemplate [paste.filter_factory] debugger = pylons.middleware:debugger_filter_factory [paste.filter_app_factory] debugger = pylons.middleware:debugger_filter_app_factory Pylons-1.0.1/Pylons.egg-info/not-zip-safe0000664000076500000240000000000111645401713020074 0ustar benstaff00000000000000 Pylons-1.0.1/Pylons.egg-info/PKG-INFO0000664000076500000240000000714212012307213016734 0ustar benstaff00000000000000Metadata-Version: 1.0 Name: Pylons Version: 1.0.1 Summary: Pylons Web Framework Home-page: http://www.pylonshq.com/ Author: Ben Bangert, Philip Jenvey, James Gardner Author-email: ben@groovie.org, pjenvey@underboss.org License: BSD Description: Pylons ====== The Pylons web framework is designed for building web applications and sites in an easy and concise manner. They can range from as small as a single Python module, to a substantial directory layout for larger and more complex web applications. Pylons comes with project templates that help boot-strap a new web application project, or you can start from scratch and set things up exactly as desired. Example `Hello World` --------------------- .. from paste.httpserver import serve from pylons import Configurator, Response class Hello(object): def __init__(self, request): self.request = request def index(self): return Response(body="Hello World!") if __name__ == '__main__': config = Configurator() config.begin() config.add_handler('home', '/', handler=Hello, action='index') config.end() serve(config.make_wsgi_app(), host='0.0.0.0') Core Features ------------- * A framework to make writing web applications in Python easy * Utilizes a minimalist, component-based philosophy that makes it easy to expand on * Harness existing knowledge about Python * Extensible application design * Fast and efficient, an incredibly small per-request call-stack providing top performance * Uses existing and well tested Python packages Current Status -------------- Pylons 1.0 series is stable and production ready. The Pylons Project now maintains the Pyramid web framework for future development. Pylons 1.0 users should strongly consider using it for their next project. Download and Installation ------------------------- Pylons can be installed with `Easy Install `_ by typing:: > easy_install Pylons Dependant packages are automatically installed from the `Pylons download page `_ . Development Version ------------------- Pylons development uses the Mercuial distributed version control system (DVCS) with BitBucket hosting the main repository here: `Pylons Bitbucket repository `_ Keywords: web wsgi lightweight framework sqlalchemy formencode mako templates Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Framework :: Pylons Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 :: Only Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Internet :: WWW/HTTP :: WSGI Classifier: Topic :: Software Development :: Libraries :: Python Modules Pylons-1.0.1/Pylons.egg-info/requires.txt0000664000076500000240000000044612012307213020237 0ustar benstaff00000000000000Routes>=1.12.3 WebHelpers>=0.6.4 Beaker>=1.5.4 Paste>=1.7.5.1 PasteDeploy>=1.5.0 PasteScript>=1.7.4.2 FormEncode>=1.2.4 simplejson>=2.2.1 decorator>=3.3.2 nose>=1.1.2 Mako>=0.5.0 WebError>=0.10.3 WebTest>=1.3.1 Tempita>=0.5.1 MarkupSafe>=0.15 WebOb>=1.1.1 [jinja2] Jinja2 [genshi] Genshi>=0.6Pylons-1.0.1/Pylons.egg-info/SOURCES.txt0000664000076500000240000003211012012307213017514 0ustar benstaff00000000000000.gitignore CHANGELOG LICENSE MANIFEST.in README.txt UPGRADING ez_setup.py setup.cfg setup.py Pylons.egg-info/PKG-INFO Pylons.egg-info/SOURCES.txt Pylons.egg-info/dependency_links.txt Pylons.egg-info/entry_points.txt Pylons.egg-info/not-zip-safe Pylons.egg-info/requires.txt Pylons.egg-info/top_level.txt pylons/__init__.py pylons/commands.py pylons/configuration.py pylons/error.py pylons/log.py pylons/middleware.py pylons/templating.py pylons/test.py pylons/testutil.py pylons/url.py pylons/util.py pylons/wsgiapp.py pylons/controllers/__init__.py pylons/controllers/core.py pylons/controllers/jsonrpc.py pylons/controllers/util.py pylons/controllers/xmlrpc.py pylons/decorators/__init__.py pylons/decorators/cache.py pylons/decorators/rest.py pylons/decorators/secure.py pylons/decorators/util.py pylons/docs/uploader.py pylons/docs/en/.gitignore pylons/docs/en/Makefile pylons/docs/en/advanced_models.rst pylons/docs/en/caching.rst pylons/docs/en/concepts.rst pylons/docs/en/conf.py pylons/docs/en/configuration.rst pylons/docs/en/controllers.rst pylons/docs/en/debugging.rst pylons/docs/en/deployment.rst pylons/docs/en/events.rst pylons/docs/en/execution.rst pylons/docs/en/forms.rst pylons/docs/en/gettingstarted.rst pylons/docs/en/glossary.rst pylons/docs/en/helpers.rst pylons/docs/en/i18n.rst pylons/docs/en/index.rst pylons/docs/en/jython.rst pylons/docs/en/logging.rst pylons/docs/en/models.rst pylons/docs/en/objects.inv pylons/docs/en/python23_install.rst pylons/docs/en/security_policy_for_bugs.rst pylons/docs/en/sessions.rst pylons/docs/en/testing.rst pylons/docs/en/upgrading.rst pylons/docs/en/views.rst pylons/docs/en/windowsnotes.rst pylons/docs/en/wsgi_support.rst pylons/docs/en/_oldstatic/Pylons_Stack-Chainsaw-OSX.png pylons/docs/en/_oldstatic/akhet.css pylons/docs/en/_oldstatic/akhet.png pylons/docs/en/_oldstatic/akhet_rev.png pylons/docs/en/_oldstatic/akhetcats.jpg pylons/docs/en/_oldstatic/akhettransaqua.png pylons/docs/en/_oldstatic/at.png pylons/docs/en/_oldstatic/babel_logo.png pylons/docs/en/_oldstatic/background.png pylons/docs/en/_oldstatic/default.css pylons/docs/en/_oldstatic/doctraceback.gif pylons/docs/en/_oldstatic/doctraceback.png pylons/docs/en/_oldstatic/hellotemplate.png pylons/docs/en/_oldstatic/helloworld.png pylons/docs/en/_oldstatic/pygments.css pylons/docs/en/_oldstatic/pylon1.jpg pylons/docs/en/_oldstatic/pylon2.jpg pylons/docs/en/_oldstatic/pylon3.jpg pylons/docs/en/_oldstatic/pylon4.jpg pylons/docs/en/_oldstatic/pylons_as_onion.ai pylons/docs/en/_oldstatic/pylons_as_onion.png pylons/docs/en/_oldstatic/pylons_as_onion.svg pylons/docs/en/_oldtemplates/genindex.html pylons/docs/en/_oldtemplates/layout.html pylons/docs/en/_oldtemplates/modindex.html pylons/docs/en/_oldtemplates/page.html pylons/docs/en/_static/Pylons_Stack-Chainsaw-OSX.png pylons/docs/en/_static/akhet.png pylons/docs/en/_static/akhet_rev.png pylons/docs/en/_static/akhetcats.jpg pylons/docs/en/_static/akhettransaqua.png pylons/docs/en/_static/at.png pylons/docs/en/_static/babel_logo.png pylons/docs/en/_static/background.png pylons/docs/en/_static/doctraceback.gif pylons/docs/en/_static/doctraceback.png pylons/docs/en/_static/hellotemplate.png pylons/docs/en/_static/helloworld.png pylons/docs/en/_static/pylon1.jpg pylons/docs/en/_static/pylon2.jpg pylons/docs/en/_static/pylon3.jpg pylons/docs/en/_static/pylon4.jpg pylons/docs/en/_static/pylons_as_onion.png pylons/docs/en/advanced_pylons/creating_paste_templates.rst pylons/docs/en/advanced_pylons/entry_points_and_plugins.rst pylons/docs/en/advanced_pylons/index.rst pylons/docs/en/advanced_pylons/paster.rst pylons/docs/en/advanced_pylons/paster_commands.rst pylons/docs/en/modules/commands.rst pylons/docs/en/modules/configuration.rst pylons/docs/en/modules/controllers.rst pylons/docs/en/modules/controllers_core.rst pylons/docs/en/modules/controllers_util.rst pylons/docs/en/modules/controllers_xmlrpc.rst pylons/docs/en/modules/decorators.rst pylons/docs/en/modules/decorators_cache.rst pylons/docs/en/modules/decorators_rest.rst pylons/docs/en/modules/decorators_secure.rst pylons/docs/en/modules/error.rst pylons/docs/en/modules/i18n_translation.rst pylons/docs/en/modules/index.rst pylons/docs/en/modules/log.rst pylons/docs/en/modules/middleware.rst pylons/docs/en/modules/templating.rst pylons/docs/en/modules/test.rst pylons/docs/en/modules/util.rst pylons/docs/en/modules/wsgiapp.rst pylons/docs/en/thirdparty/formencode_api.rst pylons/docs/en/thirdparty/index.rst pylons/docs/en/thirdparty/weberror.rst pylons/docs/en/thirdparty/webob.rst pylons/docs/en/thirdparty/webtest.rst pylons/docs/en/tutorials/index.rst pylons/docs/en/tutorials/quickwiki_tutorial.rst pylons/docs/en/tutorials/understanding_unicode.rst pylons/i18n/__init__.py pylons/i18n/translation.py pylons/media/img/bar-bg.png pylons/media/img/bg.jpg pylons/media/img/bg.png pylons/media/img/favicon.ico pylons/media/img/hatch-yellow.png pylons/media/img/header.png pylons/media/img/highlight.png pylons/media/img/logo.gif pylons/media/img/main-nav-bg-on.png pylons/media/img/main-nav-bg.png pylons/media/img/plus.jpg pylons/media/img/pylons-logo.gif pylons/media/img/pylons-powered-02.png pylons/media/img/tab-brown.png pylons/media/img/tab-traceback.png pylons/media/img/tab-white.png pylons/media/img/tab-yellow-highlight.png pylons/media/img/tab-yellow.png pylons/media/img/warning.gif pylons/media/javascripts/traceback.js pylons/media/style/black.css pylons/media/style/itraceback.css pylons/media/style/orange.css pylons/templates/__init__.py pylons/templates/controller.py_tmpl pylons/templates/restcontroller.py_tmpl pylons/templates/test_controller.py_tmpl pylons/templates/test_restcontroller.py_tmpl pylons/templates/default_project/MANIFEST.in_tmpl pylons/templates/default_project/README.txt_tmpl pylons/templates/default_project/development.ini_tmpl pylons/templates/default_project/ez_setup.py pylons/templates/default_project/setup.cfg_tmpl pylons/templates/default_project/setup.py_tmpl pylons/templates/default_project/test.ini_tmpl pylons/templates/default_project/+package+/__init__.py_tmpl pylons/templates/default_project/+package+/websetup.py_tmpl pylons/templates/default_project/+package+/config/__init__.py_tmpl pylons/templates/default_project/+package+/config/deployment.ini_tmpl_tmpl pylons/templates/default_project/+package+/config/environment.py_tmpl pylons/templates/default_project/+package+/config/middleware.py_tmpl pylons/templates/default_project/+package+/config/routing.py_tmpl pylons/templates/default_project/+package+/controllers/__init__.py_tmpl pylons/templates/default_project/+package+/controllers/error.py_tmpl pylons/templates/default_project/+package+/lib/__init__.py_tmpl pylons/templates/default_project/+package+/lib/app_globals.py_tmpl pylons/templates/default_project/+package+/lib/base.py_tmpl pylons/templates/default_project/+package+/lib/helpers.py_tmpl pylons/templates/default_project/+package+/model/__init__.py_tmpl pylons/templates/default_project/+package+/model/meta.py_tmpl pylons/templates/default_project/+package+/public/bg.png pylons/templates/default_project/+package+/public/favicon.ico pylons/templates/default_project/+package+/public/index.html_tmpl pylons/templates/default_project/+package+/public/pylons-logo.gif pylons/templates/default_project/+package+/templates/.distutils_placeholder pylons/templates/default_project/+package+/templates/__init__.py_tmpl pylons/templates/default_project/+package+/tests/__init__.py_tmpl pylons/templates/default_project/+package+/tests/test_models.py_tmpl pylons/templates/default_project/+package+/tests/functional/__init__.py_tmpl pylons/templates/minimal_project/MANIFEST.in_tmpl pylons/templates/minimal_project/README.txt_tmpl pylons/templates/minimal_project/development.ini_tmpl pylons/templates/minimal_project/ez_setup.py pylons/templates/minimal_project/setup.cfg_tmpl pylons/templates/minimal_project/setup.py_tmpl pylons/templates/minimal_project/test.ini_tmpl pylons/templates/minimal_project/+package+/__init__.py_tmpl pylons/templates/minimal_project/+package+/helpers.py_tmpl pylons/templates/minimal_project/+package+/routing.py_tmpl pylons/templates/minimal_project/+package+/wsgiapp.py_tmpl pylons/templates/minimal_project/+package+/config/deployment.ini_tmpl_tmpl pylons/templates/minimal_project/+package+/controllers/__init__.py_tmpl pylons/templates/minimal_project/+package+/public/bg.png pylons/templates/minimal_project/+package+/public/favicon.ico pylons/templates/minimal_project/+package+/public/index.html_tmpl pylons/templates/minimal_project/+package+/public/pylons-logo.gif pylons/templates/minimal_project/+package+/templates/.distutils_placeholder pylons/templates/minimal_project/+package+/templates/__init__.py_tmpl pylons/templates/minimal_project/+package+/tests/__init__.py_tmpl scripts/gen-go-pylons.py scripts/go-pylons.py scripts/pylintrc test_files/__init__.py test_files/event_file.py test_files/sample_controllers/__init__.py test_files/sample_controllers/controllers/__init__.py test_files/sample_controllers/controllers/goodbye.py test_files/sample_controllers/controllers/hello.py test_files/sample_controllers/controllers/i18nc.py test_files/sample_controllers/i18n/es/LC_MESSAGES/sample_controllers.mo test_files/sample_controllers/i18n/es/LC_MESSAGES/sample_controllers.po test_files/sample_controllers/i18n/fr/LC_MESSAGES/sample_controllers.mo test_files/sample_controllers/i18n/fr/LC_MESSAGES/sample_controllers.po test_files/sample_controllers/i18n/ja/LC_MESSAGES/sample_controllers.mo test_files/sample_controllers/i18n/ja/LC_MESSAGES/sample_controllers.po test_files/sample_controllers/templates/hello.html test_files/sample_controllers/templates/time.html tests/__init__.py tests/__init__.pyc tests/conftest.py tests/conftest.pyc tests/test_units/__init__.py tests/test_units/__init__.pyc tests/test_units/test_basic_app.py tests/test_units/test_basic_app.pyc tests/test_units/test_controller.py tests/test_units/test_controller.pyc tests/test_units/test_decorator_authenticate_form.py tests/test_units/test_decorator_authenticate_form.pyc tests/test_units/test_decorator_cache.py tests/test_units/test_decorator_cache.pyc tests/test_units/test_decorator_https.py tests/test_units/test_decorator_https.pyc tests/test_units/test_decorator_jsonify.py tests/test_units/test_decorator_jsonify.pyc tests/test_units/test_decorator_validate.py tests/test_units/test_decorator_validate.pyc tests/test_units/test_helpers.py tests/test_units/test_helpers.pyc tests/test_units/test_i18n.py tests/test_units/test_i18n.pyc tests/test_units/test_jsonrpc.py tests/test_units/test_jsonrpc.pyc tests/test_units/test_middleware.py tests/test_units/test_middleware.pyc tests/test_units/test_templating.py tests/test_units/test_templating.pyc tests/test_units/test_xmlrpc.py tests/test_units/test_xmlrpc.pyc tests/test_units/cache/cache/container_dbm/f/f2/f246b96c6e5bc523da041adfca8ffd3affc89fbd.dbm tests/test_units/cache/cache/container_dbm_lock/2/22/22b5697111b9eaf491d2f96c851cd9286eb5426f.lock tests/test_units/cache/cache/container_dbm_lock/f/f2/f246b96c6e5bc523da041adfca8ffd3affc89fbd.lock tests/test_units/cache/container_dbm/d/d5/d5fdbd7d787be89ce138c47e2928108a32299635.dbm tests/test_units/cache/container_dbm_lock/7/78/78de1e289b688271826294912a5be42267dc17d9.lock tests/test_units/cache/container_dbm_lock/d/d5/d5fdbd7d787be89ce138c47e2928108a32299635.lock tests/test_webapps/__init__.py tests/test_webapps/__init__.pyc tests/test_webapps/test_make_project.py tests/test_webapps/test_make_project.pyc tests/test_webapps/filestotest/app_globals.py tests/test_webapps/filestotest/base_with_xmlrpc.py tests/test_webapps/filestotest/cache_controller.py tests/test_webapps/filestotest/controller_sample.py tests/test_webapps/filestotest/controller_sqlatest.py tests/test_webapps/filestotest/controller_xmlrpc.py tests/test_webapps/filestotest/development.ini tests/test_webapps/filestotest/development_sqlatesting.ini tests/test_webapps/filestotest/environment_def_engine.py tests/test_webapps/filestotest/environment_def_sqlamodel.py tests/test_webapps/filestotest/functional_controller_cache_decorator.py tests/test_webapps/filestotest/functional_controller_xmlrpc.py tests/test_webapps/filestotest/functional_sample_controller_i18n.py tests/test_webapps/filestotest/functional_sample_controller_jinja2.py tests/test_webapps/filestotest/functional_sample_controller_mako.py tests/test_webapps/filestotest/functional_sample_controller_sample1.py tests/test_webapps/filestotest/functional_sample_controller_sample2.py tests/test_webapps/filestotest/functional_sample_controller_sample3.py tests/test_webapps/filestotest/functional_sample_controller_sample4.py tests/test_webapps/filestotest/functional_sample_controller_sqlatesting.py tests/test_webapps/filestotest/helpers_sample.py tests/test_webapps/filestotest/messages.ja.mo tests/test_webapps/filestotest/messages.ja.po tests/test_webapps/filestotest/messages.pot tests/test_webapps/filestotest/middleware_mako.py tests/test_webapps/filestotest/model__init__.py tests/test_webapps/filestotest/rest_routing.py tests/test_webapps/filestotest/test_mako.html tests/test_webapps/filestotest/test_sqlalchemy.html tests/test_webapps/filestotest/testgenshi.html tests/test_webapps/filestotest/testjinja2.html tests/test_webapps/filestotest/tests__init__.py tests/test_webapps/filestotest/websetup.pyPylons-1.0.1/Pylons.egg-info/top_level.txt0000664000076500000240000000002212012307213020357 0ustar benstaff00000000000000pylons test_files Pylons-1.0.1/README.txt0000664000076500000240000000212511645401275014371 0ustar benstaff00000000000000Pylons ++++++ Pylons is a rapid web application development framework. Full documentation is available online at http://pylonshq.com/docs/en/1.0/ Install ======= Installation instructions are at http://pylonshq.com/docs/en/1.0/gettingstarted/ If you want to install from source you can run the following command: .. code-block :: bash $ python setup.py install This will display a message and download setuptools if the module is not already installed. It will then install Pylons and all its dependencies. You may need root privileges to install setuptools. Testing ======= To test the source distribution run the following command: you will need to install Pylons as well some additional tools. .. code-block :: bash $ python setup.py test This will install additional dependencies needed for the tests. As above, you may need root privileges. Documentation ============= Generating documentation requires Sphinx: .. code-block :: bash $ easy_install Sphinx Then to build the documentation use the commands: .. code-block :: bash $ cd pylons/docs/ $ make html Pylons-1.0.1/scripts/0000775000076500000240000000000012012307216014347 5ustar benstaff00000000000000Pylons-1.0.1/scripts/gen-go-pylons.py0000775000076500000240000000245411645401276017443 0ustar benstaff00000000000000#!/usr/bin/env python """Generate go-pylons.py""" import sys import textwrap import virtualenv filename = 'go-pylons.py' after_install = """\ import os, subprocess def after_install(options, home_dir): etc = join(home_dir, 'etc') ## TODO: this should all come from distutils ## like distutils.sysconfig.get_python_inc() if sys.platform == 'win32': lib_dir = join(home_dir, 'Lib') bin_dir = join(home_dir, 'Scripts') elif is_jython: lib_dir = join(home_dir, 'Lib') bin_dir = join(home_dir, 'bin') else: lib_dir = join(home_dir, 'lib', py_version) bin_dir = join(home_dir, 'bin') if not os.path.exists(etc): os.makedirs(etc) subprocess.call([join(bin_dir, 'easy_install'), '-f', 'http://pylonshq.com/download/%s', 'Pylons==%s']) """ def generate(filename, version): path = version if '==' in version: path = version[:version.find('==')] output = virtualenv.create_bootstrap_script( textwrap.dedent(after_install % (path, version))) fp = open(filename, 'w') fp.write(output) fp.close() def main(): if len(sys.argv) != 2: print >> sys.stderr, 'usage: %s version' % sys.argv[0] sys.exit(1) generate(filename, sys.argv[1]) if __name__ == '__main__': main() Pylons-1.0.1/scripts/go-pylons.py0000664000076500000240000022504311645401276016672 0ustar benstaff00000000000000#!/usr/bin/env python ## WARNING: This file is generated #!/usr/bin/env python """Create a "virtual" Python installation """ virtualenv_version = "1.5.1" import sys import os import optparse import re import shutil import logging import tempfile import distutils.sysconfig try: import subprocess except ImportError, e: if sys.version_info <= (2, 3): print 'ERROR: %s' % e print 'ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.' print 'If you copy subprocess.py from a newer version of Python this script will probably work' sys.exit(101) else: raise try: set except NameError: from sets import Set as set join = os.path.join py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1]) is_jython = sys.platform.startswith('java') is_pypy = hasattr(sys, 'pypy_version_info') if is_pypy: expected_exe = 'pypy-c' elif is_jython: expected_exe = 'jython' else: expected_exe = 'python' REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath', 'fnmatch', 'locale', 'encodings', 'codecs', 'stat', 'UserDict', 'readline', 'copy_reg', 'types', 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile', 'zlib'] REQUIRED_FILES = ['lib-dynload', 'config'] if sys.version_info[:2] >= (2, 6): REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc']) if sys.version_info[:2] >= (2, 7): REQUIRED_MODULES.extend(['_weakrefset']) if sys.version_info[:2] <= (2, 3): REQUIRED_MODULES.extend(['sets', '__future__']) if is_pypy: # these are needed to correctly display the exceptions that may happen # during the bootstrap REQUIRED_MODULES.extend(['traceback', 'linecache']) class Logger(object): """ Logging object for use in command-line script. Allows ranges of levels, to avoid some redundancy of displayed information. """ DEBUG = logging.DEBUG INFO = logging.INFO NOTIFY = (logging.INFO+logging.WARN)/2 WARN = WARNING = logging.WARN ERROR = logging.ERROR FATAL = logging.FATAL LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL] def __init__(self, consumers): self.consumers = consumers self.indent = 0 self.in_progress = None self.in_progress_hanging = False def debug(self, msg, *args, **kw): self.log(self.DEBUG, msg, *args, **kw) def info(self, msg, *args, **kw): self.log(self.INFO, msg, *args, **kw) def notify(self, msg, *args, **kw): self.log(self.NOTIFY, msg, *args, **kw) def warn(self, msg, *args, **kw): self.log(self.WARN, msg, *args, **kw) def error(self, msg, *args, **kw): self.log(self.WARN, msg, *args, **kw) def fatal(self, msg, *args, **kw): self.log(self.FATAL, msg, *args, **kw) def log(self, level, msg, *args, **kw): if args: if kw: raise TypeError( "You may give positional or keyword arguments, not both") args = args or kw rendered = None for consumer_level, consumer in self.consumers: if self.level_matches(level, consumer_level): if (self.in_progress_hanging and consumer in (sys.stdout, sys.stderr)): self.in_progress_hanging = False sys.stdout.write('\n') sys.stdout.flush() if rendered is None: if args: rendered = msg % args else: rendered = msg rendered = ' '*self.indent + rendered if hasattr(consumer, 'write'): consumer.write(rendered+'\n') else: consumer(rendered) def start_progress(self, msg): assert not self.in_progress, ( "Tried to start_progress(%r) while in_progress %r" % (msg, self.in_progress)) if self.level_matches(self.NOTIFY, self._stdout_level()): sys.stdout.write(msg) sys.stdout.flush() self.in_progress_hanging = True else: self.in_progress_hanging = False self.in_progress = msg def end_progress(self, msg='done.'): assert self.in_progress, ( "Tried to end_progress without start_progress") if self.stdout_level_matches(self.NOTIFY): if not self.in_progress_hanging: # Some message has been printed out since start_progress sys.stdout.write('...' + self.in_progress + msg + '\n') sys.stdout.flush() else: sys.stdout.write(msg + '\n') sys.stdout.flush() self.in_progress = None self.in_progress_hanging = False def show_progress(self): """If we are in a progress scope, and no log messages have been shown, write out another '.'""" if self.in_progress_hanging: sys.stdout.write('.') sys.stdout.flush() def stdout_level_matches(self, level): """Returns true if a message at this level will go to stdout""" return self.level_matches(level, self._stdout_level()) def _stdout_level(self): """Returns the level that stdout runs at""" for level, consumer in self.consumers: if consumer is sys.stdout: return level return self.FATAL def level_matches(self, level, consumer_level): """ >>> l = Logger() >>> l.level_matches(3, 4) False >>> l.level_matches(3, 2) True >>> l.level_matches(slice(None, 3), 3) False >>> l.level_matches(slice(None, 3), 2) True >>> l.level_matches(slice(1, 3), 1) True >>> l.level_matches(slice(2, 3), 1) False """ if isinstance(level, slice): start, stop = level.start, level.stop if start is not None and start > consumer_level: return False if stop is not None or stop <= consumer_level: return False return True else: return level >= consumer_level #@classmethod def level_for_integer(cls, level): levels = cls.LEVELS if level < 0: return levels[0] if level >= len(levels): return levels[-1] return levels[level] level_for_integer = classmethod(level_for_integer) def mkdir(path): if not os.path.exists(path): logger.info('Creating %s', path) os.makedirs(path) else: logger.info('Directory %s already exists', path) def copyfile(src, dest, symlink=True): if not os.path.exists(src): # Some bad symlink in the src logger.warn('Cannot find file %s (bad symlink)', src) return if os.path.exists(dest): logger.debug('File %s already exists', dest) return if not os.path.exists(os.path.dirname(dest)): logger.info('Creating parent directories for %s' % os.path.dirname(dest)) os.makedirs(os.path.dirname(dest)) if symlink and hasattr(os, 'symlink'): logger.info('Symlinking %s', dest) os.symlink(os.path.abspath(src), dest) else: logger.info('Copying to %s', dest) if os.path.isdir(src): shutil.copytree(src, dest, True) else: shutil.copy2(src, dest) def writefile(dest, content, overwrite=True): if not os.path.exists(dest): logger.info('Writing %s', dest) f = open(dest, 'wb') f.write(content) f.close() return else: f = open(dest, 'rb') c = f.read() f.close() if c != content: if not overwrite: logger.notify('File %s exists with different content; not overwriting', dest) return logger.notify('Overwriting %s with new content', dest) f = open(dest, 'wb') f.write(content) f.close() else: logger.info('Content %s already in place', dest) def rmtree(dir): if os.path.exists(dir): logger.notify('Deleting tree %s', dir) shutil.rmtree(dir) else: logger.info('Do not need to delete %s; already gone', dir) def make_exe(fn): if hasattr(os, 'chmod'): oldmode = os.stat(fn).st_mode & 07777 newmode = (oldmode | 0555) & 07777 os.chmod(fn, newmode) logger.info('Changed mode of %s to %s', fn, oct(newmode)) def _find_file(filename, dirs): for dir in dirs: if os.path.exists(join(dir, filename)): return join(dir, filename) return filename def _install_req(py_executable, unzip=False, distribute=False): if not distribute: setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3] project_name = 'setuptools' bootstrap_script = EZ_SETUP_PY source = None else: setup_fn = None source = 'distribute-0.6.14.tar.gz' project_name = 'distribute' bootstrap_script = DISTRIBUTE_SETUP_PY try: # check if the global Python has distribute installed or plain # setuptools import pkg_resources if not hasattr(pkg_resources, '_distribute'): location = os.path.dirname(pkg_resources.__file__) logger.notify("A globally installed setuptools was found (in %s)" % location) logger.notify("Use the --no-site-packages option to use distribute in " "the virtualenv.") except ImportError: pass search_dirs = file_search_dirs() if setup_fn is not None: setup_fn = _find_file(setup_fn, search_dirs) if source is not None: source = _find_file(source, search_dirs) if is_jython and os._name == 'nt': # Jython's .bat sys.executable can't handle a command line # argument with newlines fd, ez_setup = tempfile.mkstemp('.py') os.write(fd, bootstrap_script) os.close(fd) cmd = [py_executable, ez_setup] else: cmd = [py_executable, '-c', bootstrap_script] if unzip: cmd.append('--always-unzip') env = {} remove_from_env = [] if logger.stdout_level_matches(logger.DEBUG): cmd.append('-v') old_chdir = os.getcwd() if setup_fn is not None and os.path.exists(setup_fn): logger.info('Using existing %s egg: %s' % (project_name, setup_fn)) cmd.append(setup_fn) if os.environ.get('PYTHONPATH'): env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH'] else: env['PYTHONPATH'] = setup_fn else: # the source is found, let's chdir if source is not None and os.path.exists(source): os.chdir(os.path.dirname(source)) # in this case, we want to be sure that PYTHONPATH is unset (not # just empty, really unset), else CPython tries to import the # site.py that it's in virtualenv_support remove_from_env.append('PYTHONPATH') else: logger.info('No %s egg found; downloading' % project_name) cmd.extend(['--always-copy', '-U', project_name]) logger.start_progress('Installing %s...' % project_name) logger.indent += 2 cwd = None if project_name == 'distribute': env['DONT_PATCH_SETUPTOOLS'] = 'true' def _filter_ez_setup(line): return filter_ez_setup(line, project_name) if not os.access(os.getcwd(), os.W_OK): cwd = tempfile.mkdtemp() if source is not None and os.path.exists(source): # the current working dir is hostile, let's copy the # tarball to a temp dir target = os.path.join(cwd, os.path.split(source)[-1]) shutil.copy(source, target) try: call_subprocess(cmd, show_stdout=False, filter_stdout=_filter_ez_setup, extra_env=env, remove_from_env=remove_from_env, cwd=cwd) finally: logger.indent -= 2 logger.end_progress() if os.getcwd() != old_chdir: os.chdir(old_chdir) if is_jython and os._name == 'nt': os.remove(ez_setup) def file_search_dirs(): here = os.path.dirname(os.path.abspath(__file__)) dirs = ['.', here, join(here, 'virtualenv_support')] if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv': # Probably some boot script; just in case virtualenv is installed... try: import virtualenv except ImportError: pass else: dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support')) return [d for d in dirs if os.path.isdir(d)] def install_setuptools(py_executable, unzip=False): _install_req(py_executable, unzip) def install_distribute(py_executable, unzip=False): _install_req(py_executable, unzip, distribute=True) _pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I) def install_pip(py_executable): filenames = [] for dir in file_search_dirs(): filenames.extend([join(dir, fn) for fn in os.listdir(dir) if _pip_re.search(fn)]) filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)] filenames.sort() filenames = [filename for basename, i, filename in filenames] if not filenames: filename = 'pip' else: filename = filenames[-1] easy_install_script = 'easy_install' if sys.platform == 'win32': easy_install_script = 'easy_install-script.py' cmd = [py_executable, join(os.path.dirname(py_executable), easy_install_script), filename] if filename == 'pip': logger.info('Installing pip from network...') else: logger.info('Installing %s' % os.path.basename(filename)) logger.indent += 2 def _filter_setup(line): return filter_ez_setup(line, 'pip') try: call_subprocess(cmd, show_stdout=False, filter_stdout=_filter_setup) finally: logger.indent -= 2 def filter_ez_setup(line, project_name='setuptools'): if not line.strip(): return Logger.DEBUG if project_name == 'distribute': for prefix in ('Extracting', 'Now working', 'Installing', 'Before', 'Scanning', 'Setuptools', 'Egg', 'Already', 'running', 'writing', 'reading', 'installing', 'creating', 'copying', 'byte-compiling', 'removing', 'Processing'): if line.startswith(prefix): return Logger.DEBUG return Logger.DEBUG for prefix in ['Reading ', 'Best match', 'Processing setuptools', 'Copying setuptools', 'Adding setuptools', 'Installing ', 'Installed ']: if line.startswith(prefix): return Logger.DEBUG return Logger.INFO def main(): parser = optparse.OptionParser( version=virtualenv_version, usage="%prog [OPTIONS] DEST_DIR") parser.add_option( '-v', '--verbose', action='count', dest='verbose', default=0, help="Increase verbosity") parser.add_option( '-q', '--quiet', action='count', dest='quiet', default=0, help='Decrease verbosity') parser.add_option( '-p', '--python', dest='python', metavar='PYTHON_EXE', help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 ' 'interpreter to create the new environment. The default is the interpreter that ' 'virtualenv was installed with (%s)' % sys.executable) parser.add_option( '--clear', dest='clear', action='store_true', help="Clear out the non-root install and start from scratch") parser.add_option( '--no-site-packages', dest='no_site_packages', action='store_true', help="Don't give access to the global site-packages dir to the " "virtual environment") parser.add_option( '--unzip-setuptools', dest='unzip_setuptools', action='store_true', help="Unzip Setuptools or Distribute when installing it") parser.add_option( '--relocatable', dest='relocatable', action='store_true', help='Make an EXISTING virtualenv environment relocatable. ' 'This fixes up scripts and makes all .pth files relative') parser.add_option( '--distribute', dest='use_distribute', action='store_true', help='Use Distribute instead of Setuptools. Set environ variable ' 'VIRTUALENV_USE_DISTRIBUTE to make it the default ') parser.add_option( '--prompt=', dest='prompt', help='Provides an alternative prompt prefix for this environment') if 'extend_parser' in globals(): extend_parser(parser) options, args = parser.parse_args() global logger if 'adjust_options' in globals(): adjust_options(options, args) verbosity = options.verbose - options.quiet logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)]) if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'): env = os.environ.copy() interpreter = resolve_interpreter(options.python) if interpreter == sys.executable: logger.warn('Already using interpreter %s' % interpreter) else: logger.notify('Running virtualenv with interpreter %s' % interpreter) env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true' file = __file__ if file.endswith('.pyc'): file = file[:-1] popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env) raise SystemExit(popen.wait()) if not args: print 'You must provide a DEST_DIR' parser.print_help() sys.exit(2) if len(args) > 1: print 'There must be only one argument: DEST_DIR (you gave %s)' % ( ' '.join(args)) parser.print_help() sys.exit(2) home_dir = args[0] if os.environ.get('WORKING_ENV'): logger.fatal('ERROR: you cannot run virtualenv while in a workingenv') logger.fatal('Please deactivate your workingenv, then re-run this script') sys.exit(3) if 'PYTHONHOME' in os.environ: logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it') del os.environ['PYTHONHOME'] if options.relocatable: make_environment_relocatable(home_dir) return create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear, unzip_setuptools=options.unzip_setuptools, use_distribute=options.use_distribute, prompt=options.prompt) if 'after_install' in globals(): after_install(options, home_dir) def call_subprocess(cmd, show_stdout=True, filter_stdout=None, cwd=None, raise_on_returncode=True, extra_env=None, remove_from_env=None): cmd_parts = [] for part in cmd: if len(part) > 40: part = part[:30]+"..."+part[-5:] if ' ' in part or '\n' in part or '"' in part or "'" in part: part = '"%s"' % part.replace('"', '\\"') cmd_parts.append(part) cmd_desc = ' '.join(cmd_parts) if show_stdout: stdout = None else: stdout = subprocess.PIPE logger.debug("Running command %s" % cmd_desc) if extra_env or remove_from_env: env = os.environ.copy() if extra_env: env.update(extra_env) if remove_from_env: for varname in remove_from_env: env.pop(varname, None) else: env = None try: proc = subprocess.Popen( cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout, cwd=cwd, env=env) except Exception, e: logger.fatal( "Error %s while executing command %s" % (e, cmd_desc)) raise all_output = [] if stdout is not None: stdout = proc.stdout while 1: line = stdout.readline() if not line: break line = line.rstrip() all_output.append(line) if filter_stdout: level = filter_stdout(line) if isinstance(level, tuple): level, line = level logger.log(level, line) if not logger.stdout_level_matches(level): logger.show_progress() else: logger.info(line) else: proc.communicate() proc.wait() if proc.returncode: if raise_on_returncode: if all_output: logger.notify('Complete output from command %s:' % cmd_desc) logger.notify('\n'.join(all_output) + '\n----------------------------------------') raise OSError( "Command %s failed with error code %s" % (cmd_desc, proc.returncode)) else: logger.warn( "Command %s had error code %s" % (cmd_desc, proc.returncode)) def create_environment(home_dir, site_packages=True, clear=False, unzip_setuptools=False, use_distribute=False, prompt=None): """ Creates a new environment in ``home_dir``. If ``site_packages`` is true (the default) then the global ``site-packages/`` directory will be on the path. If ``clear`` is true (default False) then the environment will first be cleared. """ home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) py_executable = os.path.abspath(install_python( home_dir, lib_dir, inc_dir, bin_dir, site_packages=site_packages, clear=clear)) install_distutils(home_dir) if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'): install_distribute(py_executable, unzip=unzip_setuptools) else: install_setuptools(py_executable, unzip=unzip_setuptools) install_pip(py_executable) install_activate(home_dir, bin_dir, prompt) def path_locations(home_dir): """Return the path locations for the environment (where libraries are, where scripts go, etc)""" # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its # prefix arg is broken: http://bugs.python.org/issue3386 if sys.platform == 'win32': # Windows has lots of problems with executables with spaces in # the name; this function will remove them (using the ~1 # format): mkdir(home_dir) if ' ' in home_dir: try: import win32api except ImportError: print 'Error: the path "%s" has a space in it' % home_dir print 'To handle these kinds of paths, the win32api module must be installed:' print ' http://sourceforge.net/projects/pywin32/' sys.exit(3) home_dir = win32api.GetShortPathName(home_dir) lib_dir = join(home_dir, 'Lib') inc_dir = join(home_dir, 'Include') bin_dir = join(home_dir, 'Scripts') elif is_jython: lib_dir = join(home_dir, 'Lib') inc_dir = join(home_dir, 'Include') bin_dir = join(home_dir, 'bin') elif is_pypy: lib_dir = home_dir inc_dir = join(home_dir, 'include') bin_dir = join(home_dir, 'bin') else: lib_dir = join(home_dir, 'lib', py_version) inc_dir = join(home_dir, 'include', py_version) bin_dir = join(home_dir, 'bin') return home_dir, lib_dir, inc_dir, bin_dir def change_prefix(filename, dst_prefix): prefixes = [sys.prefix] if hasattr(sys, 'real_prefix'): prefixes.append(sys.real_prefix) prefixes = map(os.path.abspath, prefixes) filename = os.path.abspath(filename) for src_prefix in prefixes: if filename.startswith(src_prefix): _, relpath = filename.split(src_prefix, 1) assert relpath[0] == os.sep relpath = relpath[1:] return join(dst_prefix, relpath) assert False, "Filename %s does not start with any of these prefixes: %s" % \ (filename, prefixes) def copy_required_modules(dst_prefix): import imp for modname in REQUIRED_MODULES: if modname in sys.builtin_module_names: logger.info("Ignoring built-in bootstrap module: %s" % modname) continue try: f, filename, _ = imp.find_module(modname) except ImportError: logger.info("Cannot import bootstrap module: %s" % modname) else: if f is not None: f.close() dst_filename = change_prefix(filename, dst_prefix) copyfile(filename, dst_filename) if filename.endswith('.pyc'): pyfile = filename[:-1] if os.path.exists(pyfile): copyfile(pyfile, dst_filename[:-1]) def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear): """Install just the base environment, no distutils patches etc""" if sys.executable.startswith(bin_dir): print 'Please use the *system* python to run this script' return if clear: rmtree(lib_dir) ## FIXME: why not delete it? ## Maybe it should delete everything with #!/path/to/venv/python in it logger.notify('Not deleting %s', bin_dir) if hasattr(sys, 'real_prefix'): logger.notify('Using real prefix %r' % sys.real_prefix) prefix = sys.real_prefix else: prefix = sys.prefix mkdir(lib_dir) fix_lib64(lib_dir) stdlib_dirs = [os.path.dirname(os.__file__)] if sys.platform == 'win32': stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs')) elif sys.platform == 'darwin': stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages')) if hasattr(os, 'symlink'): logger.info('Symlinking Python bootstrap modules') else: logger.info('Copying Python bootstrap modules') logger.indent += 2 try: # copy required files... for stdlib_dir in stdlib_dirs: if not os.path.isdir(stdlib_dir): continue for fn in os.listdir(stdlib_dir): if fn != 'site-packages' and os.path.splitext(fn)[0] in REQUIRED_FILES: copyfile(join(stdlib_dir, fn), join(lib_dir, fn)) # ...and modules copy_required_modules(home_dir) finally: logger.indent -= 2 mkdir(join(lib_dir, 'site-packages')) import site site_filename = site.__file__ if site_filename.endswith('.pyc'): site_filename = site_filename[:-1] elif site_filename.endswith('$py.class'): site_filename = site_filename.replace('$py.class', '.py') site_filename_dst = change_prefix(site_filename, home_dir) site_dir = os.path.dirname(site_filename_dst) writefile(site_filename_dst, SITE_PY) writefile(join(site_dir, 'orig-prefix.txt'), prefix) site_packages_filename = join(site_dir, 'no-global-site-packages.txt') if not site_packages: writefile(site_packages_filename, '') else: if os.path.exists(site_packages_filename): logger.info('Deleting %s' % site_packages_filename) os.unlink(site_packages_filename) if is_pypy: stdinc_dir = join(prefix, 'include') else: stdinc_dir = join(prefix, 'include', py_version) if os.path.exists(stdinc_dir): copyfile(stdinc_dir, inc_dir) else: logger.debug('No include dir %s' % stdinc_dir) if sys.exec_prefix != prefix: if sys.platform == 'win32': exec_dir = join(sys.exec_prefix, 'lib') elif is_jython: exec_dir = join(sys.exec_prefix, 'Lib') else: exec_dir = join(sys.exec_prefix, 'lib', py_version) for fn in os.listdir(exec_dir): copyfile(join(exec_dir, fn), join(lib_dir, fn)) if is_jython: # Jython has either jython-dev.jar and javalib/ dir, or just # jython.jar for name in 'jython-dev.jar', 'javalib', 'jython.jar': src = join(prefix, name) if os.path.exists(src): copyfile(src, join(home_dir, name)) # XXX: registry should always exist after Jython 2.5rc1 src = join(prefix, 'registry') if os.path.exists(src): copyfile(src, join(home_dir, 'registry'), symlink=False) copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'), symlink=False) mkdir(bin_dir) py_executable = join(bin_dir, os.path.basename(sys.executable)) if 'Python.framework' in prefix: if re.search(r'/Python(?:-32|-64)*$', py_executable): # The name of the python executable is not quite what # we want, rename it. py_executable = os.path.join( os.path.dirname(py_executable), 'python') logger.notify('New %s executable in %s', expected_exe, py_executable) if sys.executable != py_executable: ## FIXME: could I just hard link? executable = sys.executable if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'): # Cygwin misreports sys.executable sometimes executable += '.exe' py_executable += '.exe' logger.info('Executable actually exists in %s' % executable) shutil.copyfile(executable, py_executable) make_exe(py_executable) if sys.platform == 'win32' or sys.platform == 'cygwin': pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe') if os.path.exists(pythonw): logger.info('Also created pythonw.exe') shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe')) if is_pypy: # make a symlink python --> pypy-c python_executable = os.path.join(os.path.dirname(py_executable), 'python') logger.info('Also created executable %s' % python_executable) copyfile(py_executable, python_executable) if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe: secondary_exe = os.path.join(os.path.dirname(py_executable), expected_exe) py_executable_ext = os.path.splitext(py_executable)[1] if py_executable_ext == '.exe': # python2.4 gives an extension of '.4' :P secondary_exe += py_executable_ext if os.path.exists(secondary_exe): logger.warn('Not overwriting existing %s script %s (you must use %s)' % (expected_exe, secondary_exe, py_executable)) else: logger.notify('Also creating executable in %s' % secondary_exe) shutil.copyfile(sys.executable, secondary_exe) make_exe(secondary_exe) if 'Python.framework' in prefix: logger.debug('MacOSX Python framework detected') # Make sure we use the the embedded interpreter inside # the framework, even if sys.executable points to # the stub executable in ${sys.prefix}/bin # See http://groups.google.com/group/python-virtualenv/ # browse_thread/thread/17cab2f85da75951 original_python = os.path.join( prefix, 'Resources/Python.app/Contents/MacOS/Python') shutil.copy(original_python, py_executable) # Copy the framework's dylib into the virtual # environment virtual_lib = os.path.join(home_dir, '.Python') if os.path.exists(virtual_lib): os.unlink(virtual_lib) copyfile( os.path.join(prefix, 'Python'), virtual_lib) # And then change the install_name of the copied python executable try: call_subprocess( ["install_name_tool", "-change", os.path.join(prefix, 'Python'), '@executable_path/../.Python', py_executable]) except: logger.fatal( "Could not call install_name_tool -- you must have Apple's development tools installed") raise # Some tools depend on pythonX.Y being present py_executable_version = '%s.%s' % ( sys.version_info[0], sys.version_info[1]) if not py_executable.endswith(py_executable_version): # symlinking pythonX.Y > python pth = py_executable + '%s.%s' % ( sys.version_info[0], sys.version_info[1]) if os.path.exists(pth): os.unlink(pth) os.symlink('python', pth) else: # reverse symlinking python -> pythonX.Y (with --python) pth = join(bin_dir, 'python') if os.path.exists(pth): os.unlink(pth) os.symlink(os.path.basename(py_executable), pth) if sys.platform == 'win32' and ' ' in py_executable: # There's a bug with subprocess on Windows when using a first # argument that has a space in it. Instead we have to quote # the value: py_executable = '"%s"' % py_executable cmd = [py_executable, '-c', 'import sys; print sys.prefix'] logger.info('Testing executable with %s %s "%s"' % tuple(cmd)) proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) proc_stdout, proc_stderr = proc.communicate() proc_stdout = os.path.normcase(os.path.abspath(proc_stdout.strip())) if proc_stdout != os.path.normcase(os.path.abspath(home_dir)): logger.fatal( 'ERROR: The executable %s is not functioning' % py_executable) logger.fatal( 'ERROR: It thinks sys.prefix is %r (should be %r)' % (proc_stdout, os.path.normcase(os.path.abspath(home_dir)))) logger.fatal( 'ERROR: virtualenv is not compatible with this system or executable') if sys.platform == 'win32': logger.fatal( 'Note: some Windows users have reported this error when they installed Python for "Only this user". The problem may be resolvable if you install Python "For all users". (See https://bugs.launchpad.net/virtualenv/+bug/352844)') sys.exit(100) else: logger.info('Got sys.prefix result: %r' % proc_stdout) pydistutils = os.path.expanduser('~/.pydistutils.cfg') if os.path.exists(pydistutils): logger.notify('Please make sure you remove any previous custom paths from ' 'your %s file.' % pydistutils) ## FIXME: really this should be calculated earlier return py_executable def install_activate(home_dir, bin_dir, prompt=None): if sys.platform == 'win32' or is_jython and os._name == 'nt': files = {'activate.bat': ACTIVATE_BAT, 'deactivate.bat': DEACTIVATE_BAT} if os.environ.get('OS') == 'Windows_NT' and os.environ.get('OSTYPE') == 'cygwin': files['activate'] = ACTIVATE_SH else: files = {'activate': ACTIVATE_SH} # suppling activate.fish in addition to, not instead of, the # bash script support. files['activate.fish'] = ACTIVATE_FISH # same for csh/tcsh support... files['activate.csh'] = ACTIVATE_CSH files['activate_this.py'] = ACTIVATE_THIS vname = os.path.basename(os.path.abspath(home_dir)) for name, content in files.items(): content = content.replace('__VIRTUAL_PROMPT__', prompt or '') content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vname) content = content.replace('__VIRTUAL_ENV__', os.path.abspath(home_dir)) content = content.replace('__VIRTUAL_NAME__', vname) content = content.replace('__BIN_NAME__', os.path.basename(bin_dir)) writefile(os.path.join(bin_dir, name), content) def install_distutils(home_dir): distutils_path = change_prefix(distutils.__path__[0], home_dir) mkdir(distutils_path) ## FIXME: maybe this prefix setting should only be put in place if ## there's a local distutils.cfg with a prefix setting? home_dir = os.path.abspath(home_dir) ## FIXME: this is breaking things, removing for now: #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT) writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False) def fix_lib64(lib_dir): """ Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y instead of lib/pythonX.Y. If this is such a platform we'll just create a symlink so lib64 points to lib """ if [p for p in distutils.sysconfig.get_config_vars().values() if isinstance(p, basestring) and 'lib64' in p]: logger.debug('This system uses lib64; symlinking lib64 to lib') assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], ( "Unexpected python lib dir: %r" % lib_dir) lib_parent = os.path.dirname(lib_dir) assert os.path.basename(lib_parent) == 'lib', ( "Unexpected parent dir: %r" % lib_parent) copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64')) def resolve_interpreter(exe): """ If the executable given isn't an absolute path, search $PATH for the interpreter """ if os.path.abspath(exe) != exe: paths = os.environ.get('PATH', '').split(os.pathsep) for path in paths: if os.path.exists(os.path.join(path, exe)): exe = os.path.join(path, exe) break if not os.path.exists(exe): logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe)) sys.exit(3) return exe ############################################################ ## Relocating the environment: def make_environment_relocatable(home_dir): """ Makes the already-existing environment use relative paths, and takes out the #!-based environment selection in scripts. """ home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) activate_this = os.path.join(bin_dir, 'activate_this.py') if not os.path.exists(activate_this): logger.fatal( 'The environment doesn\'t have a file %s -- please re-run virtualenv ' 'on this environment to update it' % activate_this) fixup_scripts(home_dir) fixup_pth_and_egg_link(home_dir) ## FIXME: need to fix up distutils.cfg OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3], 'activate', 'activate.bat', 'activate_this.py'] def fixup_scripts(home_dir): # This is what we expect at the top of scripts: shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir)) # This is what we'll put: new_shebang = '#!/usr/bin/env python%s' % sys.version[:3] activate = "import os; activate_this=os.path.join(os.path.dirname(__file__), 'activate_this.py'); execfile(activate_this, dict(__file__=activate_this)); del os, activate_this" if sys.platform == 'win32': bin_suffix = 'Scripts' else: bin_suffix = 'bin' bin_dir = os.path.join(home_dir, bin_suffix) home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) for filename in os.listdir(bin_dir): filename = os.path.join(bin_dir, filename) if not os.path.isfile(filename): # ignore subdirs, e.g. .svn ones. continue f = open(filename, 'rb') lines = f.readlines() f.close() if not lines: logger.warn('Script %s is an empty file' % filename) continue if not lines[0].strip().startswith(shebang): if os.path.basename(filename) in OK_ABS_SCRIPTS: logger.debug('Cannot make script %s relative' % filename) elif lines[0].strip() == new_shebang: logger.info('Script %s has already been made relative' % filename) else: logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)' % (filename, shebang)) continue logger.notify('Making script %s relative' % filename) lines = [new_shebang+'\n', activate+'\n'] + lines[1:] f = open(filename, 'wb') f.writelines(lines) f.close() def fixup_pth_and_egg_link(home_dir, sys_path=None): """Makes .pth and .egg-link files use relative paths""" home_dir = os.path.normcase(os.path.abspath(home_dir)) if sys_path is None: sys_path = sys.path for path in sys_path: if not path: path = '.' if not os.path.isdir(path): continue path = os.path.normcase(os.path.abspath(path)) if not path.startswith(home_dir): logger.debug('Skipping system (non-environment) directory %s' % path) continue for filename in os.listdir(path): filename = os.path.join(path, filename) if filename.endswith('.pth'): if not os.access(filename, os.W_OK): logger.warn('Cannot write .pth file %s, skipping' % filename) else: fixup_pth_file(filename) if filename.endswith('.egg-link'): if not os.access(filename, os.W_OK): logger.warn('Cannot write .egg-link file %s, skipping' % filename) else: fixup_egg_link(filename) def fixup_pth_file(filename): lines = [] prev_lines = [] f = open(filename) prev_lines = f.readlines() f.close() for line in prev_lines: line = line.strip() if (not line or line.startswith('#') or line.startswith('import ') or os.path.abspath(line) != line): lines.append(line) else: new_value = make_relative_path(filename, line) if line != new_value: logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename)) lines.append(new_value) if lines == prev_lines: logger.info('No changes to .pth file %s' % filename) return logger.notify('Making paths in .pth file %s relative' % filename) f = open(filename, 'w') f.write('\n'.join(lines) + '\n') f.close() def fixup_egg_link(filename): f = open(filename) link = f.read().strip() f.close() if os.path.abspath(link) != link: logger.debug('Link in %s already relative' % filename) return new_link = make_relative_path(filename, link) logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link)) f = open(filename, 'w') f.write(new_link) f.close() def make_relative_path(source, dest, dest_is_directory=True): """ Make a filename relative, where the filename is dest, and it is being referred to from the filename source. >>> make_relative_path('/usr/share/something/a-file.pth', ... '/usr/share/another-place/src/Directory') '../another-place/src/Directory' >>> make_relative_path('/usr/share/something/a-file.pth', ... '/home/user/src/Directory') '../../../home/user/src/Directory' >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/') './' """ source = os.path.dirname(source) if not dest_is_directory: dest_filename = os.path.basename(dest) dest = os.path.dirname(dest) dest = os.path.normpath(os.path.abspath(dest)) source = os.path.normpath(os.path.abspath(source)) dest_parts = dest.strip(os.path.sep).split(os.path.sep) source_parts = source.strip(os.path.sep).split(os.path.sep) while dest_parts and source_parts and dest_parts[0] == source_parts[0]: dest_parts.pop(0) source_parts.pop(0) full_parts = ['..']*len(source_parts) + dest_parts if not dest_is_directory: full_parts.append(dest_filename) if not full_parts: # Special case for the current directory (otherwise it'd be '') return './' return os.path.sep.join(full_parts) ############################################################ ## Bootstrap script creation: def create_bootstrap_script(extra_text, python_version=''): """ Creates a bootstrap script, which is like this script but with extend_parser, adjust_options, and after_install hooks. This returns a string that (written to disk of course) can be used as a bootstrap script with your own customizations. The script will be the standard virtualenv.py script, with your extra text added (your extra text should be Python code). If you include these functions, they will be called: ``extend_parser(optparse_parser)``: You can add or remove options from the parser here. ``adjust_options(options, args)``: You can change options here, or change the args (if you accept different kinds of arguments, be sure you modify ``args`` so it is only ``[DEST_DIR]``). ``after_install(options, home_dir)``: After everything is installed, this function is called. This is probably the function you are most likely to use. An example would be:: def after_install(options, home_dir): subprocess.call([join(home_dir, 'bin', 'easy_install'), 'MyPackage']) subprocess.call([join(home_dir, 'bin', 'my-package-script'), 'setup', home_dir]) This example immediately installs a package, and runs a setup script from that package. If you provide something like ``python_version='2.4'`` then the script will start with ``#!/usr/bin/env python2.4`` instead of ``#!/usr/bin/env python``. You can use this when the script must be run with a particular Python version. """ filename = __file__ if filename.endswith('.pyc'): filename = filename[:-1] f = open(filename, 'rb') content = f.read() f.close() py_exe = 'python%s' % python_version content = (('#!/usr/bin/env %s\n' % py_exe) + '## WARNING: This file is generated\n' + content) return content.replace('##EXT' 'END##', extra_text) import os, subprocess def after_install(options, home_dir): etc = join(home_dir, 'etc') ## TODO: this should all come from distutils ## like distutils.sysconfig.get_python_inc() if sys.platform == 'win32': lib_dir = join(home_dir, 'Lib') bin_dir = join(home_dir, 'Scripts') elif is_jython: lib_dir = join(home_dir, 'Lib') bin_dir = join(home_dir, 'bin') else: lib_dir = join(home_dir, 'lib', py_version) bin_dir = join(home_dir, 'bin') if not os.path.exists(etc): os.makedirs(etc) subprocess.call([join(bin_dir, 'easy_install'), '-f', 'http://pylonshq.com/download/1.0', 'Pylons==1.0']) ##file site.py SITE_PY = """ eJzVPP1z2zaWv/OvQOXJUEplOh/dzo5T98ZJnNZ7buJt0mluXY+WkiCJNUWyBGlZe3P3t9/7AECA pGS77f5wmkwskcDDw8P7xgMGg8FpUchsLtb5vE6lUDIuZytRxNVKiUVeimqVlPPDIi6rLTyd3cRL qUSVC7VVEbaKguDpH/wET8WnVaIMCvAtrqt8HVfJLE7TrUjWRV5Wci7mdZlkS5FkSZXEafIvaJFn kXj6xzEIzjMBM08TWYpbWSqAq0S+EJfbapVnYlgXOOfn0V/il6OxULMyKSpoUGqcgSKruAoyKeeA JrSsFZAyqeShKuQsWSQz23CT1+lcFGk8k+Kf/+SpUdMwDFS+lpuVLKXIABmAKQFWgXjA16QUs3wu IyFey1mMA/DzhlgBQxvjmikkY5aLNM+WMKdMzqRScbkVw2ldESBCWcxzwCkBDKokTYNNXt6oESwp rccGHomY2cOfDLMHzBPH73IO4PghC37KkrsxwwbuQXDVitmmlIvkTsQIFn7KOzmb6GfDZCHmyWIB NMiqETYJGAEl0mR6VNByfKNX6NsjwspyZQxjSESZG/NL6hEF55WIUwVsWxdII0WYv5XTJM6AGtkt DAcQgaRB3zjzRFV2HJqdyAFAietYgZSslRiu4yQDZv0hnhHaPyfZPN+oEVEAVkuJX2tVufMf9hAA WjsEGAe4WGY16yxNbmS6HQECnwD7Uqo6rVAg5kkpZ1VeJlIRAEBtK+QdID0WcSk1CZkzjdyOif5E kyTDhUUBQ4HHl0iSRbKsS5IwsUiAc4Er3n34Ubw9e31++l7zmAHGMrtcA84AhRbawQkGEEe1Ko/S HAQ6Ci7wj4jncxSyJY4PeDUNju5d6WAIcy+idh9nwYHsenH1MDDHCpQJjRVQv/+GLmO1Avr8zz3r HQSnu6hCE+dvm1UOMpnFaylWMfMXckbwjYbzbVRUq1fADQrhVEAqhYuDCCYID0ji0myYZ1IUwGJp kslRABSaUlt/FYEV3ufZIa11ixMAQhlk8NJ5NqIRMwkT7cJ6hfrCNN7SzHSTwK7zOi9JcQD/ZzPS RWmc3RCOihiKv03lMskyRAh5IQgPQhpY3STAifNIXFAr0gumkQhZe3FLFIkaeAmZDnhS3sXrIpVj Fl/UrfvVCA0mK2HWOmWOg5YVqVdatWaqvbz3Ivrc4jpCs1qVEoDXU0/oFnk+FlPQ2YRNEa9ZvKpN TpwT9MgTdUKeoJbQF78DRU+VqtfSvkReAc1CDBUs8jTNN0Cy4yAQ4gAbGaPsMye8hXfwP8DF/1NZ zVZB4IxkAWtQiPwuUAgETILMNFdrJDxu06zcVjJJxpoiL+eypKEeRuwjRvyBjXGuwfu80kaNp4ur nK+TClXSVJvMhC1eFlasH1/xvGEaYLkV0cw0bei0xumlxSqeSuOSTOUCJUEv0iu77DBm0DMm2eJK rNnKwDsgi0zYgvQrFlQ6i0qSEwAwWPjiLCnqlBopZDARw0DrguCvYzTpuXaWgL3ZLAeokNh8z8D+ AG7/AjHarBKgzwwggIZBLQXLN02qEh2ERh8FvtE3/Xl84NTzhbZNPOQiTlJt5eMsOKeHZ2VJ4juT BfYaa2IomGFWoWu3zICOKOaDwSAIjDu0VeZrbr9NJtM6QXs3mQRVuT0G7hAo5AFDF+9hojQcv1mU +RpfW/Q+gj4AvYw9ggNxSYpCso/rMdMrpICrlQvTFM2vw5ECVUlw+ePZu/PPZx/FibhqtNK4rZKu YcyzLAbOJKUOfNEatlFH0BJ1V4LqS7wDC03rCiaJepMEyriqgf0A9U9lTa9hGjPvZXD2/vT1xdnk p49nP04+nn86AwTBVMjggKaMFq4Gn09FwN/AWHMVaRMZdHrQg9enH+2DYJKoSbEttvAAbB1wYTmE +Y5FiA8n2oxOkmyRhyNq/Cv70SesGbTTdHX81bU4ORHhr/FtHAbguDRNeRF/IB7+tC0kdK3gzzBX oyCYywXw+41EqRg+JWd0xB2AiNAy18bx1zzJzHt67Q1BQjukHoDDZDJLY6Ww8WQSAmmpQ88HOkTs 0SKrD6FjsXW7jjQq+CklLEWGXcb4Xw+K8ZT6IRqMotvFNAIZWc9iJbkVTR/6TSaoKCaToR4QJIh4 HLwclv1QmCaoKMoEnEniFVQcU5Wn+BPho+iRyGA8g6oJF0nHK9FtnNZSDZ1JARGHwxYZUbslijgI /IIhmL9m6UajNjUNz0AzIF+ag+oqW5TDzwE4GaAjTOSE0RUHPEwzxPRv7N4TDuDnhahjlWpBYZUk Ls8uxctnLw7Rh4BAb26p4zVHs5hktbQPF7BaS1k5CHOvcEzCMHLpskDlhk+P98NcR3Zluqyw0Etc ynV+K+eALTKws8riR3oD4TDMYxbDKoIyJSPMSs84azEGfzx7kBY02EC9NUEx62+W/oAjcJkpUB0c zRKpdajN9qco89sELfx0q1+CgQL1hmbKeBOBs3Aek6EdAg0BrmeGlNrIEBRYWbOXSHgjSFTx80YV RgTuAnXrNX29yfJNNuHw8wTV5HBkWRcFSzMvNmiW4EC8A8MBSOYQTTVEYyjgZwuUrUNAHqYP0wXK kkMPgMC6KoqRHFgmvqIpcqiGwyKM0StBwltKNNK3ZgiKbwwxHEj0NrIPjJZASDA5q+CsatBMhrJm msHADkl8rruIOO7zAbSoGIGhG2po3MjQ7+oYlLO4cJWS0w9t6OfPn5lt1IqSGojYFCeNdntB5i0q tmAKE9AJxg3iFAmxwQY8SgBTK82a4vCjyAt2gWA9L7Vsg+WGkKqqiuOjo81mE+mQPi+XR2px9Je/ fv31X5+xTpzPiX9gOo606PxWdETv0I2MvjEW6Fuzci1+TDKfGwnWUJIrRP4f4vddncxzcXw4svoT ubgxrPi/cT5AgUzMoExloO2gweiJOnwSvVQD8UQM3bbDEXsS2qRaK+ZbXehR5WC7wdOY5XVWhY4i VeJLsG4QFs/ltF6GdnDPRpofMFWU06HlgcPn14iBzxmGr4wpnqCWILZAi++Q/kdmm5j8Ga0hkLxo ojoh67Zfixnizh8u79Y7dITGzDBRyB0oEX6TBwugbdyVHPxoZxTtnuOMmo9nCIylDwzzaldwiIJD uOBajF2pc7gafVSQpg2rZlAwrmoEBQ1u3ZSprcGRjQwRJHo3JsLmhdUtgE6tdJ0Jys0qQAt3nI61 a7OC4wkhD5yI5/REglN73Hn3jJe2TlPKorR41KMKA/YWGu10Dnw5NADGYlD+NOCWelnOP7QWhdeg B1jOiRdksEWHmfCN6wMODgY97NSx+rt6M437QOAiUfuHASeMT3iAUoEwFUOfcXdxuKUtJ5taCO82 OMRTZpVIotUO2Wrrjl6Z2muXFkmGqtdZo2iW5uAUW6VIfNS8930FClzwcZ8t0wKoydCQw2l0Qs6e J3+hbocpq2WNwb2b+0CM1oki44ZkWsF/4FVQToESQEBLgmbBPFTI/In9CSJn56u/7GAPS2hkCLfp Li+kYzA0HPP+QCAZdQYEhCADEnZlkTxH1gYpcJizQJ5sw2u5U7gJRqRAzBwDQloGcKeXXnyDTyLc dSABRch3lZKF+FIMYPnakvow1f2ncqnJGgydBuQp6HTDiZuKcNIQJ620hM/QfkKC9ieKHDh4Ch6P m1x32dwwrc2SgK/u622LFChkSpwMRi6q14YwbgL3ixOnRUMsM4hhKG8gbxvFjDQK7HJr0LDgBoy3 5u2x9GM3YYF9h2GuXsj1HYR/YZmoWa5CjG87qQv3o7miSxuL7UUyHcAfbwEGo2sPkkx1+gKTLL9j kNCDHvZB9yaLWZF5XG6SLCQFpul34i9NBw9LSs/GHX2kaOoIJopZxqN3JQgIbTcegTihJoCgXIZK e/1dsHunOLBwufvA85qvjl9ed4k73pXgsZ/+pTq7q8pY4WqlvGgsFLhaXfuNShcmF2dbvWGoN5Qx SihzBUGk+PDxs0BCcC51E28fN/WG4RGbe+fkfQzqoNfuJVdrdsQugAhqRWSUo/DxHPlwZB87uT0T ewSQRzHMnkUxkDSf/B44+xYKxjicbzNMo7VVBn7g9ddfTXoSoy6SX381uGeUFjH6xH7Y8gTtyLSR L3qnbbqUMk7J13A6UVIxa3jHtilGrNAp/NNMdt3jdOLHvDcmo4Hfad6JG83ngOgBUXY+/RViVaXT W7dxklJOHtA4PEQ9Z8Jszhz04+NB2o8ypqTAY3k27o2E1NUzWJiQ4/pRdzraLzo1qd+eeNR8ilh1 UTnQW+jNDpC3Le7u/u2W/V5L/W/SWY8E5M1m0EPAB87B7E7+/58JKyuGppXVqKX1ldyv5w2wB6jD HW7OHjekOzRvZi2MM8Fyp8RTFNCnYkNb0pTKw40JgDJnP6MHDi6j3th8U5clb0+SnBeyPMT9urHA ahzjaVCRTxfM0XtZISa22YxSo07tRt6nOkOd7LQzCRs/tV9kV7lJkcjsNimhL2iVYfj9hx/Owi4D 6GGwUz84dx0NlzzcTiHcRzBtqIkTPqYPU+gxXX6/VLVdZZ+gZsvYJCA12bqE7eQdTdzavwb3ZCC8 /UHeh8WIcLaSs5uJpL1lZFPs6uRg3+BrxMRuOfs1PipeUKESzGSW1kgrdvSwwmxRZzNKx1cS7Lku B8XyENox5nTTIo2XYkid55jq0NxI2ZDbuNTeTlHmWIAo6mR+tEzmQv5WxymGkXKxAFxwr0S/inh4 yniIt7zpzYVpSs7qMqm2QIJY5XqrifbHnYbTLU906CHJuwpMQNwxPxYfcdr4ngk3N+QywaifYMdJ YpyHHcxeIHIXPYf3WT7BUSdUxzlmpLrbwPQ4aI+QA4ABAIX5D0Y6U+S/kfTK3c+iNXeJilrSI6Ub 2ebkcSCU4Qgja/5NP31GdHlrB5bL3Vgu92O5bGO57MVy6WO53I+lKxK4sDZJYiShL1HSzqL3FmS4 OQ4e5iyerbgd1vdhHR9AFIUJ6IxMcZmrl0nh7SQCQmrb2d+kh02BRcKFg2XOKVcNErkf90x08GgK lJ3OVK6hO/NUjM+2q8jE73sURVQONKXuLG/zuIojTy6WaT4FsbXojhsAY9GuN+HcXHY7mXI2sWWp Bpf/9en7D++xOYIamN106oaLiIYFpzJ8GpdL1ZWmJtgogB2ppV/3Qd00wIMHZnJ4lAP+7y0VFCDj iA1tiOeiAA+Ayn5sM7c4Jgxbz3UVjX7OTM57GydikFWDZlI7iHR6efn29NPpgFJMg/8duAJjaOtL h4uPaWEbdP03t7mlOPYBoda5lMb4uXPyaN1wxP021oBtub3PrlsPXjzEYPeGpf4s/62UgiUBQkU6 2fgYQj04+PlDYUKHPoYRO9Vh7k4OOyv2nSN7joviiH5fmrs9gL+3hjHGBAigXaihiQyaYKql9K15 3UNRB+gDfb0/HIK1Q692JONT1E6ixwF0KGub7Xb/vH0BNnpKVq/Pvjt/f3H++vL00/eOC4iu3IeP Ry/E2Q+fBZUjoAFjnyjGnfgKC1/AsLiHWcQ8h381pjfmdcVJSej19uJC7wys8TgD1reizYngOVfN WGico+Gsp32oy10Qo1QHSM65EaoOoXMlGC+t+cyCynUNLB1HmaKzWuvQS58HMueGaBs1AumDxi4p GARXNMErqlSuTFRY8o6TPkvTg5S20bYOIaUcVGd32tlvMdl8LzFHneFJ01kr+qvQxTW8jlSRJhDJ vQqtLOluWI3RMI5+aDdUGa8+Deh0h5F1Q571TizQar0KeW66/6hhtN9qwLBhsLcw70xSNQLV6GIt lQixEe8chPIOvtql12ugYMFwY6nCRTRMl8DsYwiuxSqBAAJ4cgXWF+MEgNBaCT8BfexkB2SOxQDh m/X88O+hJojf+pdfeppXZXr4D1FAFCS4ciXsIabb+C0EPpGMxNmHd6OQkaNKUPH3GkvAwSGhLJ8j 7VQuwzu2k6GS6UKXM/j6AF9oP4Fet7qXsih1937XOEQJeKKG5DU8UYZ+IVYXWdhjnMqoBRqr2y1m eErM3fY2nwPxcSXTVBdEn7+9OAPfEQvuUYJ4n+cMhuN8CW7Z6lovPsXWAoUbuvC6RDYu0YWlTf15 5DXrzcyiyFFvrw7ArhNlP7u9OqnOMk6Ui/YQp82wnJLzCLkZlsOsLHN3txnS2W1GdEfJYcaYXJZU NelzBnA0PY05MIKICYv6TbKZ9y6TrDJlcmkyA20KihfU6hhEBUmMJ9eI//KM0715qcyBF3hYbMtk uaowpQ6dIyq2x+Y/nH6+OH9P1esvXja+dw+LjikeGHPpwgnWpWHOA764tWbIW5NJH+fqVwgDdRD8 ab/imogTHqDTj9OL+Kf9ik8cnTjxIM8A1FRdtIUEwwCnW5/0NBLBuNpoGD9u3VmDmQ+GMpJ4wEGX F7jz6/KjbdkyKJT9MS8fsVexKDQNh6azWwfV/ug5LgrcXJkP+xvB2z4JM58pdL3pvNlVceV+OrKI hx8Bo25rfwxTk9RpqqfjMNsubqHgVlvaXzInY+q0m2UoykDEodt55DJZvyrWzZkDvdrdDjDxjUbX SGKvQh/8kg20n+FhYondiVZMRzo7QaYA8xlSHxGpwZNCuwAKhEpOh47kjkdPX3hzdGzC/XPUugss 5PegCHUBKB0syEvgRPjyG7uP/IrQQlV6LELHX8lkltvqJPxsVuhbPvfn2CsDlMpEsSvjbCmHDGts YH7pE3tHIpa0rccxV0mrWkJzN3iodzsYvCsW/bsnBrMWH3Ta3chtWxv51MEGvccPfAhlvAHtXtTV kNdq52YBNtdbsMMQkyS/hTvodQ96Ghb6Xb/17OHgh4ll3Etrr1pHW0L7QvuVsxICpkrRZoljhY2H 6BrmxgaeNFZ4YJ/qihH7u+e8kFPl6sJlFFyo3gwHukEr1B/wyRU+uZdQZXRzsEK/m8tbmebgFkHE hYXvv9rC91FkUx29NUF/BoKX28ttP3r0pkHu2BTno+OkCljIKJPVEWLUm5C5B7kGH1z2X3TQEGc3 5Me++fl8LN68/xH+fy0/QOSD59fG4h+AiXiTlxAB8hlKOtyOpf0Vh3Z5rfCQG0GjzQS+BwBdqkuP 2rhxoc8c+IcNrBYTWGdZrvnyCUCR50jnihsbbirp4bc56tN1Fo0j17c0A/0SybD7AAQeGjjSLaNV tU5RnTupjGZNrwYX52/O3n88i6o75Hbzc+CkOvwqHZyR3sgtcdNqLOyTWY1Prh2/9nuZFj1urY4M zWEKjAxFCMFDYaNBvtsgthFAXGJ4L4rtPJ9F2BJ4n89vVRvwc0dOEHivHfaMIMIajvRWV+Ns42Og hvilrZcG0JD66DlRT0IonuJBIn4cDfot5VhQ/hn+PL3ZzN30tT4RQhNsY9rMeuh3t6pxxXTW8Fxm ItRO7EqYc4JpEqv1dOaeH/uQCX07BSg92o+Qi7hOKyEzEGEKxumaAND97pEvlhPmFrY4dA6K0inp Jt4qpyImVmKAow7opDNunFBmD2LlH+IbthB4Fk3UfKgVoBOiFOHkTldVz1Ysxxy0EAF7CgQ2Sfby RdghMg/KkeyscTVhnujYMUZLWen584Ph6Op5Y+wpezzzDnzOCrCDLqccgA4tnj59OhD/cb9/wqhE aZ7fgOMEsPvCVnFBr3d4FnpydrW6vrd5EwFLzlbyCh5cU5bbPq8zSiHu6UoLIu1fAyPEtQktP5r2 LUvNybWSN4S5BW8saRPyU5bQHTSYApKocvVVPpgeMgJFLAm6IYzVLElCTifAemzzGs9qYTpQ84u8 A45PEMwY3+JOFgfDK/QBqbDSco9F50QMCPCACp14NDrsSqeVAM/J5VajOTnPkqo5Z/DM3eTUh7or e7WM5isRb1AyzDxaxHCO/Xms2vjA+V4W9WKKfHblJgZbs+TX9+EOrA2Sli8WBlN4aBZplstyZowq rlgySyoHjGmHcLgz3ahDBigKelAagIYnwzC3Em3ffmHXxcX0A+33HpqRdJlPZW8p4iROnLWq3aKo GZ/SRZaQlm/NlxGM8p7Sz9of8MYSX+jkJxaZe5cpuMfd6kxfksB1Fs3NCQCHLuaxCtKyo6cjnNug LHxmWh1uNHcqODXxGEQTbrdJWdVxOtEH+SfouU3sBrjG0x6T2nsA0Pos4Pbn4BAf6pJu8B1MNQzS EysyTcn+iVjoJELkHj3yT+kUOfp6Lzw9jqnpZ3wRgKPBseWX5vDKQ1S+OULROX3gYjmm2qNw1K6o 7LTCfQ5TIm+d7HYc8KghW7B8h31WbPFOHpjWk3lE/0LfkaPLFHBj6tGDp8mUBgv7Co/v76srATH+ W4OgLBI5P3yiEDvG+Y9C1VAMddxA4REzDOnuCQL5ZWsnzykv5NrfXds3HaBff7UPrKuCewufac/E V8v6aJtbidxs2uDnwHrEK3C6UW/MzWFkrZb43CbqEDaI9qy5qVdpH5mB1w+f8p4JP2BHNMTBNHe4 8rqPVha/faRqGgW/i0q6Vz+t0AnGUtFVzG9QmdXFsQ0V+TBfRmn2oVtAhJ/qpre0Psa7j4jRq5tw 3/S5/7656xaBnbnZP+vM3T9C49JA993NL300YAddE+JBVbkWo8mfI7pjvbXbn6LSn4W9hZEzVcSD GrWxZsl1PHO/Y4HBIV/i6B6HClyQZtVbc+qcD2uzc5eTu9zMm6n43J6QpB3yuWYvNud0pc+Ea64m crlUkxhvhJqQD0j1AR3jbryKd3QbkIzV1jgDeOcCgDCsoiu53GJNWHXwM/lmSt5edw7XCxqaitCc qjaVzDm2154HgIs4pqf+JnPEZWmDVGI2RtVlUYKzNtD3F/K+b1+pXAPUxJfrWN0Y1E2Psb7ODofg YgNzhIozCewAetQBQvDJCudmF67znEzsO+CXZ81R0WRsGUJm9VqWcdXckuDvLyXiW2cEOjiHC+xE kI3YtTjFRSyx/OEghTGc/f6ldo4832/P+dCRVWkPZyvqoZMTjzl66ki54ebkzt6S5N7OMadrMSle 5Ns1hG3WcJ+9GQKWwlz5Q4pQh3T8Vl9DwvfTcc4Jq+ocPgK5d4+t+NWNVmexw2DRcJ65iqF77wSe fCRD23edVIcLuhdH+czQjO/rDcssnd2EHY0tFU+4Ra/iaUYbNYEOFiLdE+j4xaaPDHQ8+A8MdPTl X2BNND5aH/SWn94TEbGacG/SahgB+kyASLhh0rqHydjDoVvMCeFKcjewl1GyznROiBgzgRzZvWKF QPCNWcqtfPNutDHj9kUivnTR4+8uPrw+vSBaTC5P3/zn6Xe0zY9ZvZbNenAkmOWHTO1Dr6zQjQr1 1mzf4A22PVfTcW28htB539nW6oHQfw6ib0Hbisx9vatDp5682wkQ3z/tFtRdKrsXcsf50rXL7oZs q/4v0E+5WMv8cvbWzCOTU2ZxaBLG5n2T49My2kmB7Fo4p2yqq060U6ovM9uRnhnZ4j1aAUztIX/Z zJ6pxLb5I3ZU2leEU8UhnmIxNwGAFM6kcyEV3UXFoCr/LvISlF2MOxTsMI7tvZ7UjrOYyl5Yi7sU MxkZgnjHSAbd+bnCPpfpDioEASs8fd0SI2L0n877272yJ0pcHdKBtUNUNtf2F66ZdnJ/TnBHrLL3 liiz5Y27AdB4UafuLpft0+lAzh8lTfOFUyENmu8I6NyIpwL2Rp+JFeJ0K0KIEvVWDhZdER31nUMO 8mg3HewNrZ6Jw13HmdzjPEI8391w3joxpHu84B7qnh6qNodGHAuMdT+7zimJbwkyZ90FXVTiOR+4 26Ovx4Svt1fPj23KFvkdX7vXYCDtB45hv2pOBuy9GsvpTbxSjqn+A4uNRm3w1wOHNRdid4DTqXPe EQSZ7TiGNPDe99dGmB7enb2DNqKW745hQmL4RI1oUk5luMbdPhl1JtuorC4MLnK/H0ZH+wEohNLv m+CHb2MB9fxMx4PTmu4TtA4nHg115IEKHXxe4B7G62uwa3eno2kP6k4l//agADdo855ebxBr9hq4 lZfo2G0L2jNveGCH7edDfv39nz+gf7ckxnZ/sc+htq1e9h4sYScWi6hw87pFIfM4AusCCnNIahrr b42E4+H9howONzVTQ65Ah4/qsvCuUAosyImdaMtvjUHwf71Zz9M= """.decode("base64").decode("zlib") ##file ez_setup.py EZ_SETUP_PY = """ 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 178BYnMUkw== """.decode("base64").decode("zlib") ##file distribute_setup.py DISTRIBUTE_SETUP_PY = """ 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 """.decode("base64").decode("zlib") ##file activate.sh ACTIVATE_SH = """ eJytVU1v4jAQPW9+xTT0ANVS1GsrDlRFAqmFqmG72m0rY5IJsRRslDiktNr/vuMQ8tFQpNU2B4I9 H36eeW/SglkgYvBFiLBKYg0LhCRGD1KhA7BjlUQuwkLIHne12HCNNpz5kVrBgsfBmdWCrUrA5VIq DVEiQWjwRISuDreW5eE+CtodeLeAnhZEGKMGFXqAciMiJVcoNWx4JPgixDjzEj48QVeCfcqmtzfs cfww+zG4ZfeD2ciGF7gCHaDMPM1jtvuHXAsPfF2rSGeOxV4iDY5GUGb3xVEYv2aj6WQ0vRseAlMY G5DKsAawwnQUXt2LQOYlzZoYByqhonqoqfxZf4BLD97i4DukgXADCPgGgdOLTK5arYxZB1xnrc9T EQFcHoZEAa1gSQioo/TPV5FZrDlxJA+NzwF+Ek1UonOzFnKZp6k5mgLBqSkuuAGXS4whJb5xz/xs wXCHjiVerAk5eh9Kfz1wqOldtVv9dkbscfjgjKeTA8XPrtaNauX5rInOxaHuOReNtpFjo1/OxdFG 5eY9hJ3L3jqcPJbATggXAemDLZX0MNZRYjSDH7C1wMHQh73DyYfTu8a0F9v+6D8W6XNnF1GEIXW/ JrSKPOtnW1YFat9mrLJkzLbyIlTvYzV0RGXcaTBfVLx7jF2PJ2wyuBsydpm7VSVa4C4Zb6pFO2TR huypCEPwuQjNftUrNl6GsYZzuFrrLdC9iJjQ3omAPBbcI2lsU77tUD43kw1NPZhTrnZWzuQKLomx Rd4OXM1ByExVVkmoTwfBJ7Lt10Iq1Kgo23Bmd8Ib1KrGbsbO4Pp2yO4fpnf3s6MnZiwuiJuls1/L Pu4yUCvhpA+vZaJvWWDTr0yFYYyVnHMqCEq+QniuYX225xmnzRENjbXACF3wkCYNVZ1mBwxoR9Iw WAo3/36oSOTfgjwEEQKt15e9Xpqm52+oaXxszmnE9GLl65RH2OMmS6+u5acKxDmlPgj2eT5/gQOX LLK0j1y0Uwbmn438VZkVpqlfNKa/YET/53j+99G8H8tUhr9ZSXs2 """.decode("base64").decode("zlib") ##file activate.fish ACTIVATE_FISH = """ eJydVm1v4jgQ/s6vmA1wBxUE7X2stJVYlVWR2lK13d6d9laRk0yIr8HmbIe0++tvnIQQB9pbXT5A Ys/LM55nZtyHx5RrSHiGsMm1gRAh1xhDwU0Kng8hFzMWGb5jBv2E69SDs0TJDdj3MxilxmzPZzP7 pVPMMl+q9bjXh1eZQ8SEkAZULoAbiLnCyGSvvV6SC7IoBcS4Nw0wjcFbvJDcjiuTswzFDpiIQaHJ lQAjQUi1YRmUboC2uZJig8J4PaCnT5IaDcgsbm/CjinOwgx1KcUTMEhhTgV4g2B1fRk8Le8fv86v g7v545UHpZB9rKnp+gXsMhxLunIIpwVQxP/l9c/Hq9Xt1epm4R27bva6AJqN92G4YhbMG2i+LB+u grv71c3dY7B6WtzfLy9bePbp0taDTXSwJQJszUnnp0y57mvpPcrF7ZODyhswtd59+/jdgw+fwBNS xLSscksUPIDqwwNmCez3PpxGeyBYg6HE0YdcWBxcKczYzuVJi5Wu915vn5oWePCCoPUZBN5B7IgV MCi54ZDLG7TUZ0HweXkb3M5vFmSpFm/gthhBx0UrveoPpv9AJ9unIbQYdUoe21bKg2q48sPFGVwu H+afrxd1qvclaNlRFyh1EQ2sSccEuNAGWQwysfVpz1tPajUqbqJUnEcIJkWo6OXDaodK8ZiLdbmM L1wb+9H0D+pcyPSrX5u5kgWSygRYXCnJUi/KKcuU4cqsAyTKZBiissLc7NFwizvjxtieKBVCIdWz fzilzPaYyljZN0cGN1v7NnaIPNCGmVy3GKuJaQ6iVjE1Qfm+36hglErwmnAD8hu0dDy4uICBA8ZV pQr/q/+O0KFW2kjelu9Dgb9SDBsWV4F4x5CswgS0zBVlk5tDMP5bVtUGpslbm81Lu2sdKq7uNMGh MVQ4fy9xhogC1lS5guhISa0DlBWv0O8odT6/LP+4WZzDV6FzIkEqC0uolGZSZoMnlpxplmD2euaT O4hkTpPnbztDccey0bhjDaBIqaWQa0uwEtQEwtyU56i4fq54F9IE3ORR6mKriODM4XOYZwaVYLYz 7SPbKkz4i7VkB6/Ot1upDE3znNqYKpM8raa0Bx8vfvntJ32UENsM4aI6gJL+jJwhxhh3jVIDOcpi m0r2hmEtS8XXXNBk71QCDXTBNhhPiHX2LtHkrVIlhoEshH/EZgdq53Eirqs5iFKMnkOmqZTtr3Xq djvPTWZT4S3NT5aVLgurMPUWI07BRVYqkQrmtCKohNY8qu9EdACoT6ki0a66XxVF4f9AQ3W38yO5 mWmZmIIpnDFrbXakvKWeZhLwhvrbUH8fahhqD0YUcBDJjEBMQwiznE4y5QbHrbhHBOnUAYzb2tVN jJa65e+eE2Ya30E2GurxUP8ssA6e/wOnvo3V78d3vTcvMB3n7l3iX1JXWqk= """.decode("base64").decode("zlib") ##file activate.csh ACTIVATE_CSH = """ eJx9U11vmzAUffevOCVRu+UB9pws29Kl0iq1aVWllaZlcgxciiViItsQdb9+xiQp+dh4QOB7Pu49 XHqY59IgkwVhVRmLmFAZSrGRNkdgykonhFiqSCRW1sJSmJg8wCDT5QrucRCyHn6WFRKhVGmhKwVp kUpNiS3emup3TY6XIn7DVNQyJUwlrgthJD6n/iCNv72uhCzCpFx9CRkThRQGKe08cWXJ9db/yh/u pvzl9mn+PLnjj5P5D1yM8QmXlzBkSdXwZ0H/BBc0mEo5FE5qI2jKhclHOOvy9HD/OO/6YO1mX9vx sY0H/tPIV0dtqel0V7iZvWyNg8XFcBA0ToEqVeqOdNUEQFvN41SumAv32VtJrakQNSmLWmgp4oJM yDoBHgoydtoEAs47r5wHHnUal5vbJ8oOI+9wI86vb2d8Nrm/4Xy4RZ8R85E4uTZPB5EZPnTaaAGu E59J8BE2J8XgrkbLeXMlVoQxznEYFYY8uFFdxsKQRx90Giwx9vSueHP1YNaUSFG4vTaErNSYuBOF lXiVyXa9Sy3JdClEyK1dD6Nos9mEf8iKlOpmqSNTZnYjNEWiUYn2pKNB3ttcLJ3HmYYXy6Un76f7 r8rRsC1TpTJj7f19m5sUf/V3Ir+x/yjtLu8KjLX/CmN/AcVGUUo= """.decode("base64").decode("zlib") ##file activate.bat ACTIVATE_BAT = """ eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8 qxaKMMsvboQ+LxxE44VICSW1gEa2UFaibqoS0iyJ0xw2lIA6nX5AHCu1jpRsv5KRjknkac9VLVug sX9mtzxIeJDE/mg4OGp47qoLo3NHX2jsMB3AiDht5hryAUOEifoTdCXbSh7V0My2NMq/Xbh5MEjU ZT63gpgNT9lKOJ/CtHsvT99re3pX303kydn4HeyOeAg5cjf2EW1D6HOPkg9NGKhu """.decode("base64").decode("zlib") ##file deactivate.bat DEACTIVATE_BAT = """ eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q FlWqXJpcICVYpGzx2BAZ4uHv5+Hv6wq1BWINXBTdKriEKkI1DhW2QAfhttcxxANiFZCBbglQSJUL i2dASrm4rFz9XLgAwJNbyQ== """.decode("base64").decode("zlib") ##file distutils-init.py DISTUTILS_INIT = """ eJytV92L4zYQf9dfMU0ottuse/TeFkKh3MvC0Ydy0IdlMVpbTtR1JCMpm+T++s5Y/pBs53oPZ1hQ pPnSb34zo5WnVhsH2jLpV/Y2Li/cKKkOFoYN3Za6ErAdFtKC0g44vEvjzrwR6h1Oujo3YgdWw0VA yRWcLUo6cBpqqSpwRwHWVY18ZRB9W3jq3HDlfoIvqK7NG2gF7a297VANvZ3O1sGrQI/eDe5yB0ZY WQkLUpHxhVX09NDe3FGr31BL1lJUD9f8ln+FShpROm1ujOFS8ZOAPUKRt9wd836Hjqw7O9nYgvYD iX+1VOlMPPXQ5EVRy0YURbaDZDSQZEzWo7rS5kSLNHaQwX4RRLrQGe1nj92Fh1zltEhHDDZfEO0g O6MraHn5xg8IpYOfLfC2FdxYShLC64EES4A0uuROYhq49Zs368RpMvTHJmOiscKHUXRXKIpcKiuM Sz/sYHa7TkxcRYkkEhN8HZaxKCJXFFJJh+baW5JluRG8SjM20JHEA9qWWtXywBjbbvF2rjzC61k2 VSGuDibTUGlhVeLgTekLHPEP73wQrrscUsUGrPCGjkTCC1JXXyw8EJWP3FSUZY8IiSCCRp97dnfO RUUx5a0RtbxSzLX/3XBXYxIpyQka/fh74pGrjQ5QzUt9OnFV5dMV+otOG5gQjctxozNTNtzaSSiN JHqu0FeJmsqRN/KrKHRLGbaQWtHUgRB9FDfu5giN4eZWIDqWCv8vrcTjrNZgRXQPzy+RmGjQpLRI EKz0UqQLlR28ciusM8jn7PtcLPZy2zbSDeyyos0iO+ybBgPyRvSk/CEFm8IndQebz8iXTRbbjhDP 5xh7iJfBrKd/Nenjj6Jvgp2B+W7AnP102BXH5IZWPV3tI2MUOvXowpdS12IIXhLLP0lKyeuZrpEv pFhPqHg3JFTd1cceVp0EsPgGU0wFO2u4iyYRoFYfEm9kG/RZcUUBm87t9mFtx9iCtC9kx4Rt4R8a OdgzSt40vtyFecAZZ8BfCOhCrC8djMGPFaz2Vlt5TSZCk053+37wbLDLRXfZ+F45NtdVpVWdudSC xgODI8EsiLoTl5aO0lhoigX7GHZDHAY4LxoMIu1gXPYPksmFquxF4uRKZhEnKzXu82HESb+LlNQz Fh/RvFJVuhK+Ee5slBdj30FcRGdJ5rhKxtkyKxWcGoV/WOCYKqkNDYJ5fNQVx3g400tpJBS2FSU+ Tco9ss8nZ08dtscGQfSby87b73fOw+4UgrEMNnY6uMzYvSDxPVPpsij6+l0/ZPfuH0Iz010giY34 HpL0ZLyLJB4ukaQRU+GwptO7yIZCQE33B0K9iCqO6X+AR4n7wAeH68DPkJzpTsD3x+/cj9LIVHC2 An1wmv7CzWHoqR02vb0VL73siP+3nkX0YbQ0l9f6WDyOm24cj3rxO2MMip6kpcu6VCefn/789PR3 0v0fg21sFIp70rj9PCi8YDRDXFucym/43qN+iENh1Jy/dIIIqF3OIkDvBMsdx+huWv8Kz73vl8g5 WQ3JOGqwu3lb4dfKKbvLigXDQsb8B/xt39Q= """.decode("base64").decode("zlib") ##file distutils.cfg DISTUTILS_CFG = """ eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg 9FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q= """.decode("base64").decode("zlib") ##file activate_this.py ACTIVATE_THIS = """ eJyNUlGL2zAMfvevEBlHEujSsXsL9GGDvW1jD3sZpQQ3Ua7aJXawnbT595Ocpe0dO5ghseVP+vRJ VpIkn2cYPZknwAvWLXWYhRP5Sk4baKgOWRWNqtpdgTyH2Y5wpq5Tug406YAgKEzkwqg7NBPwR86a Hk0olPopaK0NHJHzYQPnE5rI0o8+yBUwiBfyQcT8mMPJGiAT0A0O+b8BY4MKJ7zPcSSzHaKrSpJE qeDmUgGvVbPCS41DgO+6xy/OWbfAThMn/OQ9ukDWRCSLiKzk1yrLjWapq6NnvHUoHXQ4bYPdrsVX 4lQMc/q6ZW975nmSK+oH6wL42a9H65U6aha342Mh0UVDzrD87C1bH73s16R5zsStkBZDp0NrXQ+7 HaRnMo8f06UBnljKoOtn/YT+LtdvSyaT/BtIv9KR60nF9f3qmuYKO4//T9ItJMsjPfgUHqKwCZ3n xu/Lx8M/UvCLTxW7VULHxB1PRRbrYfvWNY5S8it008jOjcleaMqVBDnUXcWULV2YK9JEQ92OfC96 1Tv4ZicZZZ7GpuEpZbbeQ7DxquVx5hdqoyFSSmXwfC90f1Dc7hjFs/tK99I0fpkI8zSLy4tSy+sI 3vMWehjQNJmE5VePlZbL61nzX3S93ZcfDqznnkb9AZ3GWJU= """.decode("base64").decode("zlib") if __name__ == '__main__': main() ## TODO: ## Copy python.exe.manifest ## Monkeypatch distutils.sysconfig Pylons-1.0.1/scripts/pylintrc0000664000076500000240000002114711645401276016157 0ustar benstaff00000000000000# lint Python modules using external checkers. # # This is the main checker controling the other ones and the reports # generation. It is itself both a raw checker and an astng checker in order # to: # * handle message activation / deactivation at the module level # * handle some basic but necessary stats'data (number of classes, methods...) # [MASTER] # Specify a configuration file. #rcfile= # Profiled execution. profile=no # Add to the black list. It should be a base name, not a # path. You may set this option multiple times. ignore=.svn # Pickle collected data for later comparisons. persistent=yes # Set the cache size for astng objects. cache-size=500 # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. load-plugins= [MESSAGES CONTROL] # Enable only checker(s) with the given id(s). This option conflict with the # disable-checker option #enable-checker= # Enable all checker(s) except those with the given id(s). This option conflict # with the disable-checker option #disable-checker= # Enable all messages in the listed categories. #enable-msg-cat= # Disable all messages in the listed categories. #disable-msg-cat= # Enable the message(s) with the given id(s). #enable-msg= # Disable the message(s) with the given id(s). disable-msg=C0323,W0142,C0301,C0103,C0111,E0213,C0302,C0203,W0703,R0201 [REPORTS] # set the output format. Available formats are text, parseable, colorized and # html output-format=colorized # Include message's id in output include-ids=yes # Put messages in a separate file for each module / package specified on the # command line instead of printing them on stdout. Reports (if any) will be # written in a file name "pylint_global.[txt|html]". files-output=no # Tells wether to display a full report or only the messages reports=yes # Python expression which should return a note less than 10 (10 is the highest # note).You have access to the variables errors warning, statement which # respectivly contain the number of errors / warnings messages and the total # number of statements analyzed. This is used by the global evaluation report # (R0004). evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) # Add a comment according to your evaluation note. This is used by the global # evaluation report (R0004). comment=no # Enable the report(s) with the given id(s). #enable-report= # Disable the report(s) with the given id(s). #disable-report= # checks for # * unused variables / imports # * undefined variables # * redefinition of variable from builtins or from an outer scope # * use of variable before assigment # [VARIABLES] # Tells wether we should check for unused import in __init__ files. init-import=no # A regular expression matching names used for dummy variables (i.e. not used). dummy-variables-rgx=_|dummy # List of additional names supposed to be defined in builtins. Remember that # you should avoid to define new builtins when possible. additional-builtins= # try to find bugs in the code using type inference # [TYPECHECK] # Tells wether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # When zope mode is activated, consider the acquired-members option to ignore # access to some undefined attributes. zope=no # List of members which are usually get through zope's acquisition mecanism and # so shouldn't trigger E0201 when accessed (need zope=yes to be considered). acquired-members=REQUEST,acl_users,aq_parent # checks for : # * doc strings # * modules / classes / functions / methods / arguments / variables name # * number of arguments, local variables, branchs, returns and statements in # functions, methods # * required module attributes # * dangerous default values as arguments # * redefinition of function / method / class # * uses of the global statement # [BASIC] # Required attributes for module, separated by a comma required-attributes= # Regular expression which should only match functions or classes name which do # not require a docstring no-docstring-rgx=__.*__ # Regular expression which should only match correct module names module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ # Regular expression which should only match correct module level names const-rgx=(([A-Z_][A-Z1-9_]*)|(__.*__))$ # Regular expression which should only match correct class names class-rgx=[A-Z_][a-zA-Z0-9]+$ # Regular expression which should only match correct function names function-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct method names method-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct instance attribute names attr-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct argument names argument-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct variable names variable-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct list comprehension / # generator expression variable names inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ # Good variable names which should always be accepted, separated by a comma good-names=i,j,k,ex,Run,_ # Bad variable names which should always be refused, separated by a comma bad-names=foo,bar,baz,toto,tutu,tata # List of builtins function names that should not be used, separated by a comma bad-functions=apply,input # checks for sign of poor/misdesign: # * number of methods, attributes, local variables... # * size, complexity of functions, methods # [DESIGN] # Maximum number of arguments for function / method max-args=12 # Maximum number of locals for function / method body max-locals=30 # Maximum number of return / yield for function / method body max-returns=12 # Maximum number of branch for function / method body max-branchs=30 # Maximum number of statements in function / method body max-statements=60 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of attributes for a class (see R0902). max-attributes=20 # Minimum number of public methods for a class (see R0903). min-public-methods=0 # Maximum number of public methods for a class (see R0904). max-public-methods=20 # checks for # * external modules dependencies # * relative / wildcard imports # * cyclic imports # * uses of deprecated modules # [IMPORTS] # Deprecated modules which should not be used, separated by a comma deprecated-modules=regsub,string,TERMIOS,Bastion,rexec # Create a graph of every (i.e. internal and external) dependencies in the # given file (report R0402 must not be disabled) import-graph= # Create a graph of external dependencies in the given file (report R0402 must # not be disabled) ext-import-graph= # Create a graph of internal dependencies in the given file (report R0402 must # not be disabled) int-import-graph= # checks for : # * methods without self as first argument # * overridden methods signature # * access only to existant members via self # * attributes not defined in the __init__ method # * supported interfaces implementation # * unreachable code # [CLASSES] # List of interface methods to ignore, separated by a comma. This is used for # instance to not check methods defines in Zope's Interface base class. ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__,__new__,setUp # checks for similarities and duplicated code. This computation may be # memory / CPU intensive, so you should disable it if you experiments some # problems. # [SIMILARITIES] # Minimum lines number of a similarity. min-similarity-lines=10 # Ignore comments when computing similarities. ignore-comments=yes # Ignore docstrings when computing similarities. ignore-docstrings=yes # checks for: # * warning notes in the code like FIXME, XXX # * PEP 263: source code with non ascii character but no encoding declaration # [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME,XXX,TODO # checks for : # * unauthorized constructions # * strict indentation # * line length # * use of <> instead of != # [FORMAT] # Maximum number of characters on a single line. max-line-length=90 # Maximum number of lines in a module max-module-lines=1000 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' Pylons-1.0.1/setup.cfg0000664000076500000240000000034112012307216014477 0ustar benstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 [easy_install] find_links = http://www.pylonshq.com/download/ [nosetests] where = tests cover-package = pylons cover-erase = True with-doctest = True nocapture = 1 Pylons-1.0.1/setup.py0000664000076500000240000001113212012306114014364 0ustar benstaff00000000000000import sys try: from setuptools import setup, find_packages except ImportError: from ez_setup import use_setuptools use_setuptools() from setuptools import setup, find_packages version = '1.0.1' tests_require = ['nose', 'Jinja2>=2.2.1'] if not sys.platform.startswith('java'): tests_require.extend(['Genshi', 'coverage>=2.85']) setup( name="Pylons", version=version, description='Pylons Web Framework', long_description=""" Pylons ====== The Pylons web framework is designed for building web applications and sites in an easy and concise manner. They can range from as small as a single Python module, to a substantial directory layout for larger and more complex web applications. Pylons comes with project templates that help boot-strap a new web application project, or you can start from scratch and set things up exactly as desired. Example `Hello World` --------------------- .. from paste.httpserver import serve from pylons import Configurator, Response class Hello(object): def __init__(self, request): self.request = request def index(self): return Response(body="Hello World!") if __name__ == '__main__': config = Configurator() config.begin() config.add_handler('home', '/', handler=Hello, action='index') config.end() serve(config.make_wsgi_app(), host='0.0.0.0') Core Features ------------- * A framework to make writing web applications in Python easy * Utilizes a minimalist, component-based philosophy that makes it easy to expand on * Harness existing knowledge about Python * Extensible application design * Fast and efficient, an incredibly small per-request call-stack providing top performance * Uses existing and well tested Python packages Current Status -------------- Pylons 1.0 series is stable and production ready. The Pylons Project now maintains the Pyramid web framework for future development. Pylons 1.0 users should strongly consider using it for their next project. Download and Installation ------------------------- Pylons can be installed with `Easy Install `_ by typing:: > easy_install Pylons Dependant packages are automatically installed from the `Pylons download page `_ . Development Version ------------------- Pylons development uses the Mercuial distributed version control system (DVCS) with BitBucket hosting the main repository here: `Pylons Bitbucket repository `_ """, keywords='web wsgi lightweight framework sqlalchemy formencode mako templates', license='BSD', author='Ben Bangert, Philip Jenvey, James Gardner', author_email='ben@groovie.org, pjenvey@underboss.org', url='http://www.pylonshq.com/', packages=find_packages(exclude=['ez_setup', 'tests', 'tests.*']), zip_safe=False, include_package_data=True, test_suite='nose.collector', tests_require=tests_require, install_requires=[ "Routes>=1.12.3", "WebHelpers>=0.6.4", "Beaker>=1.5.4", "Paste>=1.7.5.1", "PasteDeploy>=1.5.0", "PasteScript>=1.7.4.2", "FormEncode>=1.2.4", "simplejson>=2.2.1", "decorator>=3.3.2", "nose>=1.1.2", "Mako>=0.5.0", "WebError>=0.10.3", "WebTest>=1.3.1", "Tempita>=0.5.1", "MarkupSafe>=0.15", "WebOb>=1.1.1", ], dependency_links=[ "http://www.pylonshq.com/download/1.0" ], classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Framework :: Pylons", "Programming Language :: Python", "Programming Language :: Python :: 2 :: Only", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Internet :: WWW/HTTP :: WSGI", "Topic :: Software Development :: Libraries :: Python Modules", ], extras_require={ 'genshi': ['Genshi>=0.6'], 'jinja2': ['Jinja2'], }, entry_points=""" [paste.paster_command] controller = pylons.commands:ControllerCommand restcontroller = pylons.commands:RestControllerCommand routes = pylons.commands:RoutesCommand shell = pylons.commands:ShellCommand [paste.paster_create_template] pylons = pylons.util:PylonsTemplate pylons_minimal = pylons.util:MinimalPylonsTemplate [paste.filter_factory] debugger = pylons.middleware:debugger_filter_factory [paste.filter_app_factory] debugger = pylons.middleware:debugger_filter_app_factory """, ) Pylons-1.0.1/test_files/0000775000076500000240000000000012012307216015021 5ustar benstaff00000000000000Pylons-1.0.1/test_files/__init__.py0000664000076500000240000000000011645401276017134 0ustar benstaff00000000000000Pylons-1.0.1/test_files/event_file.py0000664000076500000240000000033111645401276017524 0ustar benstaff00000000000000from pylons.events import NewRequest, NewResponse, subscriber @subscriber(NewRequest) def add_reggy(event): event.request.reg = True @subscriber(NewResponse) def add_respy(event): event.response.reg = True Pylons-1.0.1/test_files/sample_controllers/0000775000076500000240000000000012012307216020730 5ustar benstaff00000000000000Pylons-1.0.1/test_files/sample_controllers/__init__.py0000664000076500000240000000000211645401276023045 0ustar benstaff00000000000000# Pylons-1.0.1/test_files/sample_controllers/controllers/0000775000076500000240000000000012012307216023276 5ustar benstaff00000000000000Pylons-1.0.1/test_files/sample_controllers/controllers/__init__.py0000664000076500000240000000000211645401276025413 0ustar benstaff00000000000000# Pylons-1.0.1/test_files/sample_controllers/controllers/goodbye.py0000664000076500000240000000071011645401276025312 0ustar benstaff00000000000000import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers import WSGIController from pylons.controllers.util import abort, redirect from webob import Response from webob.exc import HTTPNotFound log = logging.getLogger(__name__) class Smithy(WSGIController): def __init__(self): self._pylons_log_debug = True def index(self): return 'Hello World' __controller__ = 'Smithy' Pylons-1.0.1/test_files/sample_controllers/controllers/hello.py0000664000076500000240000000166311645401276024775 0ustar benstaff00000000000000import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers import WSGIController from pylons.controllers.util import abort, redirect from pylons.templating import render_mako from webob import Response from webob.exc import HTTPNotFound log = logging.getLogger(__name__) class HelloController(WSGIController): def __init__(self): self._pylons_log_debug = True def index(self): return 'Hello World' def oops(self): raise Exception('oops') def abort(self): abort(404) def intro_template(self): return render_mako('/hello.html') def time_template(self): return render_mako('/time.html', cache_key='fred', cache_expire=20) def special_controller(environ, start_response): return HTTPNotFound() def empty_wsgi(environ, start_response): return def a_view(request): return Response('A View') Pylons-1.0.1/test_files/sample_controllers/controllers/i18nc.py0000664000076500000240000000263611671746603024622 0ustar benstaff00000000000000import datetime from pylons import request, response, session, url from pylons import tmpl_context as c from pylons import app_globals from pylons.i18n import _, get_lang, set_lang, LanguageError from pylons.controllers import WSGIController from pylons.controllers.util import abort, redirect class I18NcController(WSGIController): def set_lang(self): return self._set_lang(_) def set_lang_pylonscontext(self, pylons): return self._set_lang(lambda *args: pylons.translator.ugettext(*args)) def _set_lang(self, gettext): lang = request.GET['lang'] try: set_lang(lang) except (LanguageError, IOError), e: resp_unicode = gettext('Could not set language to "%(lang)s"') % {'lang': lang} else: session['lang'] = lang session.save() resp_unicode = gettext('Set language to "%(lang)s"') % {'lang': lang} return resp_unicode def i18n_index(self): obj = request._current_obj() locale_list = request.languages set_lang(request.languages) return unicode(_('basic index page')) def no_lang(self): set_lang(None) response.write(_('No language')) set_lang([]) response.write(_('No languages')) return '' def langs(self): locale_list = request.languages set_lang(request.languages) return str(get_lang()) Pylons-1.0.1/test_files/sample_controllers/i18n/0000775000076500000240000000000012012307216021507 5ustar benstaff00000000000000Pylons-1.0.1/test_files/sample_controllers/i18n/es/0000775000076500000240000000000012012307216022116 5ustar benstaff00000000000000Pylons-1.0.1/test_files/sample_controllers/i18n/es/LC_MESSAGES/0000775000076500000240000000000012012307216023703 5ustar benstaff00000000000000Pylons-1.0.1/test_files/sample_controllers/i18n/es/LC_MESSAGES/sample_controllers.mo0000664000076500000240000000071411645401276030165 0ustar benstaff00000000000000,<=CHelloProject-Id-Version: PROJECT VERSION Report-Msgid-Bugs-To: EMAIL@ADDRESS POT-Creation-Date: 2010-06-25 18:12+0700 PO-Revision-Date: 2010-06-25 18:19-0700 Last-Translator: FULL NAME Language-Team: es Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 0.9.4 ¡Hola!Pylons-1.0.1/test_files/sample_controllers/i18n/es/LC_MESSAGES/sample_controllers.po0000664000076500000240000000076711645401276030200 0ustar benstaff00000000000000# -*- coding: utf-8 -*- msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2010-06-25 18:12-0700\n" "PO-Revision-Date: 2010-06-25 18:12-0700\n" "Last-Translator: FULL NAME \n" "Language-Team: es \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.4\n" msgid "Hello" msgstr "¡Hola!" Pylons-1.0.1/test_files/sample_controllers/i18n/fr/0000775000076500000240000000000012012307216022116 5ustar benstaff00000000000000Pylons-1.0.1/test_files/sample_controllers/i18n/fr/LC_MESSAGES/0000775000076500000240000000000012012307216023703 5ustar benstaff00000000000000Pylons-1.0.1/test_files/sample_controllers/i18n/fr/LC_MESSAGES/sample_controllers.mo0000664000076500000240000000071311645401276030164 0ustar benstaff00000000000000,<=CHelloProject-Id-Version: PROJECT VERSION Report-Msgid-Bugs-To: EMAIL@ADDRESS POT-Creation-Date: 2010-06-25 18:12+0700 PO-Revision-Date: 2010-06-25 18:19-0700 Last-Translator: FULL NAME Language-Team: fr Plural-Forms: nplurals=2; plural=(n > 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 0.9.4 BonjourPylons-1.0.1/test_files/sample_controllers/i18n/fr/LC_MESSAGES/sample_controllers.po0000664000076500000240000000076611645401276030177 0ustar benstaff00000000000000# -*- coding: utf-8 -*- msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2010-06-25 18:12-0700\n" "PO-Revision-Date: 2010-06-25 18:12-0700\n" "Last-Translator: FULL NAME \n" "Language-Team: fr \n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.4\n" msgid "Hello" msgstr "Bonjour" Pylons-1.0.1/test_files/sample_controllers/i18n/ja/0000775000076500000240000000000012012307216022101 5ustar benstaff00000000000000Pylons-1.0.1/test_files/sample_controllers/i18n/ja/LC_MESSAGES/0000775000076500000240000000000012012307216023666 5ustar benstaff00000000000000Pylons-1.0.1/test_files/sample_controllers/i18n/ja/LC_MESSAGES/sample_controllers.mo0000664000076500000240000000120011645401276030137 0ustar benstaff00000000000000<\p$q552.aCould not set language to "%(lang)s"Set language to "%(lang)s"basic index pageProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2007-02-05 12:36+0900 PO-Revision-Date: 2007-02-05 13:06+0900 Last-Translator: FULL NAME Language-Team: LANGUAGE MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit 「%(lang)s」に言語設定が変更できません言語設定を「%(lang)s」に変更しました根本インデクスページPylons-1.0.1/test_files/sample_controllers/i18n/ja/LC_MESSAGES/sample_controllers.po0000664000076500000240000000167111645401276030156 0ustar benstaff00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2007-02-05 12:36+0900\n" "PO-Revision-Date: 2007-02-05 13:06+0900\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: controller_sample.py:7 msgid "basic index page" msgstr "根本インデクスページ" #: controller_sample.py:59 #, python-format msgid "Could not set language to \"%(lang)s\"" msgstr "「%(lang)s」に言語設定が変更できません" #: controller_sample.py:63 #, python-format msgid "Set language to \"%(lang)s\"" msgstr "言語設定を「%(lang)s」に変更しました"Pylons-1.0.1/test_files/sample_controllers/templates/0000775000076500000240000000000012012307216022726 5ustar benstaff00000000000000Pylons-1.0.1/test_files/sample_controllers/templates/hello.html0000664000076500000240000000002211645401276024725 0ustar benstaff00000000000000Hi there ${4 + 2} Pylons-1.0.1/test_files/sample_controllers/templates/time.html0000664000076500000240000000011211645401276024560 0ustar benstaff00000000000000<%! from datetime import datetime %> Hello, the time is ${datetime.now()} Pylons-1.0.1/tests/0000775000076500000240000000000012012307216014022 5ustar benstaff00000000000000Pylons-1.0.1/tests/__init__.py0000664000076500000240000000000211645401276016137 0ustar benstaff00000000000000# Pylons-1.0.1/tests/__init__.pyc0000664000076500000240000000021512012306033016270 0ustar benstaff00000000000000 Nc@sdS(N((((s6/Users/ben/Programming/Python/pylons/tests/__init__.pytsPylons-1.0.1/tests/conftest.py0000664000076500000240000000064011645401276016235 0ustar benstaff00000000000000import sys import os import shutil import pkg_resources here = os.path.dirname(__file__) base = os.path.dirname(here) sys.path.append(here) sys.path.insert(0, base) here = os.path.dirname(__file__) pkg_resources.working_set.add_entry(base) if not os.environ.get('PASTE_TESTING'): output_dir = os.path.join(here, 'test_webapps', 'output') if os.path.exists(output_dir): shutil.rmtree(output_dir) Pylons-1.0.1/tests/conftest.pyc0000664000076500000240000000123512012306033016361 0ustar benstaff00000000000000 Nc@sddlZddlZddlZddlZejjeZejjeZejj eejj deejjeZej j eej jdsejjeddZejjerejeqndS(iNit PASTE_TESTINGt test_webappstoutput(tsystostshutilt pkg_resourcestpathtdirnamet__file__theretbasetappendtinsertt working_sett add_entrytenvirontgettjoint output_dirtexiststrmtree(((s6/Users/ben/Programming/Python/pylons/tests/conftest.pyts    Pylons-1.0.1/tests/test_units/0000775000076500000240000000000012012307216016223 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/__init__.py0000644000076500000240000000534411645403130020343 0ustar benstaff00000000000000import json import os import sys from unittest import TestCase from urllib import quote_plus from xmlrpclib import loads, dumps data_dir = os.path.dirname(os.path.abspath(__file__)) try: shutil.rmtree(data_dir) except: pass cur_dir = os.path.dirname(os.path.abspath(__file__)) pylons_root = os.path.dirname(os.path.dirname(cur_dir)) test_root = os.path.join(pylons_root, 'test_files') sys.path.append(test_root) class TestMiddleware(object): def __init__(self, app): self.app = app def __call__(self, environ, start_response): if 'paste.testing_variables' not in environ: environ['paste.testing_variables'] = {} testenv = environ['paste.testing_variables'] testenv['environ'] = environ return self.app(environ, start_response) class TestWSGIController(TestCase): def setUp(self): import pylons from pylons.util import ContextObj, PylonsContext c = ContextObj() py_obj = PylonsContext() py_obj.tmpl_context = c py_obj.request = py_obj.response = None self.environ = {'pylons.routes_dict':dict(action='index'), 'paste.config':dict(global_conf=dict(debug=True)), 'pylons.pylons':py_obj} pylons.tmpl_context._push_object(c) def tearDown(self): import pylons pylons.tmpl_context._pop_object() def get_response(self, **kargs): test_args = kargs.pop('test_args', {}) url = kargs.pop('_url', '/') self.environ['pylons.routes_dict'].update(kargs) return self.app.get(url, extra_environ=self.environ, **test_args) def post_response(self, **kargs): url = kargs.pop('_url', '/') self.environ['pylons.routes_dict'].update(kargs) return self.app.post(url, extra_environ=self.environ, params=kargs) def xmlreq(self, method, args=None): if args is None: args = () ee = dict(CONTENT_TYPE='text/xml') data = dumps(args, methodname=method) self.response = response = self.app.post('/', params = data, extra_environ=ee) return loads(response.body)[0][0] def jsonreq(self, method, args=()): assert(isinstance(args, list) or isinstance(args, tuple) or isinstance(args, dict)) ee = dict(CONTENT_TYPE='application/json') data = json.dumps(dict(id='test', method=method, params=args)) self.response = response = self.app.post('/', params=quote_plus(data), extra_environ=ee) return json.loads(response.body) Pylons-1.0.1/tests/test_units/__init__.pyc0000644000076500000240000001021212012306033020465 0ustar benstaff00000000000000 XNc@s$ddlZddlZddlZddlmZddlmZddlmZm Z ej j ej j e ZyejeWnnXej j ej j e Zej j ej j eZej jedZej jedefdYZdefd YZdS( iN(tTestCase(t quote_plus(tloadstdumpst test_filestTestMiddlewarecBseZdZdZRS(cCs ||_dS(N(tapp(tselfR((sA/Users/ben/Programming/Python/pylons/tests/test_units/__init__.pyt__init__scCs=d|kri|ds  c Cst|ts3t|ts3t|ts3ttdd}tjtddd|d|}|jjddt |d||_ }tj |j S( NR1sapplication/jsontidttestR4R.R&R'( t isinstancetlistttupleRtAssertionErrortjsonRRR/RRRR3(RR4R5R6R7R((sA/Users/ben/Programming/Python/pylons/tests/test_units/__init__.pytjsonreqGs N(( R RR!R#R-R0RR8R@(((sA/Users/ben/Programming/Python/pylons/tests/test_units/__init__.pyR!s     (R?tostsystunittestRturllibRt xmlrpclibRRtpathtdirnametabspatht__file__tdata_dirtshutiltrmtreetcur_dirt pylons_roottjoint test_roottappendtobjectRR(((sA/Users/ben/Programming/Python/pylons/tests/test_units/__init__.pyts    Pylons-1.0.1/tests/test_units/cache/0000775000076500000240000000000012012307216017266 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/cache/0000775000076500000240000000000012012307216020331 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/cache/container_dbm/0000775000076500000240000000000012012307216023135 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/cache/container_dbm/f/0000775000076500000240000000000012012307216023362 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/cache/container_dbm/f/f2/0000775000076500000240000000000012012307216023671 5ustar benstaff00000000000000././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000Pylons-1.0.1/tests/test_units/cache/cache/container_dbm/f/f2/f246b96c6e5bc523da041adfca8ffd3affc89fbd.dbmPylons-1.0.1/tests/test_units/cache/cache/container_dbm/f/f2/f246b96c6e5bc523da041adfca8ffd3affc89fb0000664000076500000240000004000012012307072031707 0ustar benstaff00000000000000ϚW @ pEp0/!8fred0fred(F1344900666.0637791 I20 ccopy_reg _reconstructor p1 (cwebhelpers.html.builder literal p2 c__builtin__ unicode p3 V\u000aHello, the time is 2012-08-13 16:31:06.063456\u000a tRp4 tp5 .Pylons-1.0.1/tests/test_units/cache/cache/container_dbm_lock/0000775000076500000240000000000012012307216024145 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/cache/container_dbm_lock/2/0000775000076500000240000000000012012307216024306 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/cache/container_dbm_lock/2/22/0000775000076500000240000000000012012307216024531 5ustar benstaff00000000000000././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000Pylons-1.0.1/tests/test_units/cache/cache/container_dbm_lock/2/22/22b5697111b9eaf491d2f96c851cd9286eb5426f.lockPylons-1.0.1/tests/test_units/cache/cache/container_dbm_lock/2/22/22b5697111b9eaf491d2f96c851cd9286e0000775000076500000240000000000012012307072031136 0ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/cache/container_dbm_lock/f/0000775000076500000240000000000012012307216024372 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/cache/container_dbm_lock/f/f2/0000775000076500000240000000000012012307216024701 5ustar benstaff00000000000000././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000Pylons-1.0.1/tests/test_units/cache/cache/container_dbm_lock/f/f2/f246b96c6e5bc523da041adfca8ffd3affc89fbd.lockPylons-1.0.1/tests/test_units/cache/cache/container_dbm_lock/f/f2/f246b96c6e5bc523da041adfca8ffd3aff0000775000076500000240000000000012012307072032062 0ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/container_dbm/0000775000076500000240000000000012012307216022072 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/container_dbm/d/0000775000076500000240000000000012012307216022315 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/container_dbm/d/d5/0000775000076500000240000000000012012307216022625 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/container_dbm/d/d5/d5fdbd7d787be89ce138c47e2928108a32299635.dbm0000664000076500000240000004000012012307064030642 0ustar benstaff00000000000000ϚW @ pp4141@޿޿8ܿh8HطPؼxXڿ( Pٿ5I0opp8BBAAApAHA A@@@@X@ۿٿ޿Xȳph8HطPڿؼ@޿I(P8oppb`b8bbaaapaHa a`0FVtest0`ڿ޿ٿ`(hXȳph8ܿ8Hطۿ0Ixotest_dbm_cache_decorator(F1344900660.908267 N(dp1 S'content' p2 S'Counter=2' p3 sS'status' p4 S'200 OK' p5 sS'cookies' p6 NsS'headers' p7 (lp8 (S'Content-Type' p9 S'text/html; charset=utf-8' tp10 a(S'Content-Length' p11 S'0' tp12 a(S'Pragma' p13 S'no-cache' p14 tp15 a(S'Cache-Control' p16 g14 tp17 astp18 ..Pylons-1.0.1/tests/test_units/cache/container_dbm_lock/0000775000076500000240000000000012012307216023102 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/container_dbm_lock/7/0000775000076500000240000000000012012307216023250 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/container_dbm_lock/7/78/0000775000076500000240000000000012012307216023506 5ustar benstaff00000000000000././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000Pylons-1.0.1/tests/test_units/cache/container_dbm_lock/7/78/78de1e289b688271826294912a5be42267dc17d9.lockPylons-1.0.1/tests/test_units/cache/container_dbm_lock/7/78/78de1e289b688271826294912a5be42267dc17d90000775000076500000240000000000012012307064030536 0ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/container_dbm_lock/d/0000775000076500000240000000000012012307216023325 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/cache/container_dbm_lock/d/d5/0000775000076500000240000000000012012307216023635 5ustar benstaff00000000000000././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000Pylons-1.0.1/tests/test_units/cache/container_dbm_lock/d/d5/d5fdbd7d787be89ce138c47e2928108a32299635.lockPylons-1.0.1/tests/test_units/cache/container_dbm_lock/d/d5/d5fdbd7d787be89ce138c47e2928108a322996350000775000076500000240000000000012012307064031110 0ustar benstaff00000000000000Pylons-1.0.1/tests/test_units/test_basic_app.py0000664000076500000240000001335411645401276021577 0ustar benstaff00000000000000import os import re import sys from nose.tools import raises from __init__ import test_root def make_app(global_conf, full_stack=True, static_files=True, include_cache_middleware=False, attribsafe=False, **app_conf): import pylons import pylons.configuration as configuration from beaker.cache import CacheManager from beaker.middleware import SessionMiddleware, CacheMiddleware from nose.tools import raises from paste.registry import RegistryManager from paste.deploy.converters import asbool from pylons.decorators import jsonify from pylons.middleware import ErrorHandler, StatusCodeRedirect from pylons.wsgiapp import PylonsApp from routes import Mapper from routes.middleware import RoutesMiddleware paths = dict(root=os.path.join(test_root, 'sample_controllers'), controllers=os.path.join(test_root, 'sample_controllers', 'controllers')) config = configuration.pylons_config config.init_app(global_conf, app_conf, package='sample_controllers', paths=paths) map = Mapper(directory=config['pylons.paths']['controllers']) map.connect('/{controller}/{action}') map.connect('/test_func', controller='sample_controllers.controllers.hello:special_controller') map.connect('/test_empty', controller='sample_controllers.controllers.hello:empty_wsgi') config['routes.map'] = map class AppGlobals(object): def __init__(self): self.cache = 'Nothing here but a string' config['pylons.app_globals'] = AppGlobals() if attribsafe: config['pylons.strict_tmpl_context'] = False app = PylonsApp(config=config) app = RoutesMiddleware(app, config['routes.map'], singleton=False) if include_cache_middleware: app = CacheMiddleware(app, config) app = SessionMiddleware(app, config) if asbool(full_stack): app = ErrorHandler(app, global_conf, **config['pylons.errorware']) if asbool(config['debug']): app = StatusCodeRedirect(app) else: app = StatusCodeRedirect(app, [401, 403, 404, 500]) app = RegistryManager(app) app.config = config return app class TestWsgiApp(object): def setUp(self): from paste.fixture import TestApp from routes.util import URLGenerator app = make_app({}) self.app = TestApp(app) self.url = URLGenerator(app.config['routes.map'], {}) def test_testvars(self): resp = self.app.get('/_test_vars', extra_environ={'paste.testing_variables': True}) assert re.match(r'^\d+$', resp.body) def test_exception_resp_attach(self): resp = self.app.get('/test_func', expect_errors=True) assert resp.status == 404 @raises(Exception) def test_no_content(self): resp = self.app.get('/test_empty', expect_errors=True) assert 'wontgethre' def test_middleware_cache_obj_instance(self): from paste.fixture import TestApp app = TestApp(make_app({}, include_cache_middleware=True)) resp = app.get('/hello/index') assert resp.cache def test_attribsafe_tmpl_context(self): from paste.fixture import TestApp app = TestApp(make_app({}, attribsafe=True)) resp = app.get('/hello/index') assert 'Hello World' in resp def test_cache_obj_appglobals(self): resp = self.app.get('/hello/index', extra_environ={'paste.testing_variables': True}) assert resp.cache == 'Nothing here but a string' def test_controller_name_override(self): resp = self.app.get('/goodbye/index') assert 'Hello World' in resp class TestJsonifyDecorator(object): def setUp(self): from paste.fixture import TestApp from routes.util import URLGenerator app = make_app({}) self.config = app.config self.app = TestApp(app) self.url = URLGenerator(app.config['routes.map'], {}) def test_basic_response(self): response = self.app.get('/hello/index') assert 'Hello World' in response def test_config(self): import pylons import pylons.configuration as configuration assert pylons.config == configuration.config @raises(AssertionError) def test_eval(self): from paste.fixture import TestApp app = TestApp(make_app(dict(debug='True'))) app.get('/hello/oops', status=500, extra_environ={'paste.throw_errors': False}) def test_set_lang(self): self._test_set_lang('set_lang') def test_set_lang_pylonscontext(self): self._test_set_lang('set_lang_pylonscontext') def _test_set_lang(self, action): response = self.app.get(self.url(controller='i18nc', action=action, lang='ja')) assert u'\u8a00\u8a9e\u8a2d\u5b9a\u3092\u300cja\u300d\u306b\u5909\u66f4\u3057\u307e\u3057\u305f'.encode('utf-8') in response response = self.app.get(self.url(controller='i18nc', action=action, lang='ch')) assert 'Could not set language to "ch"' in response def test_detect_lang(self): response = self.app.get(self.url(controller='i18nc', action='i18n_index'), headers={ 'Accept-Language':'fr;q=0.6, en;q=0.1, ja;q=0.3'}) # expect japanese fallback for nonexistent french. assert u'\u6839\u672c\u30a4\u30f3\u30c7\u30af\u30b9\u30da\u30fc\u30b8'.encode('utf-8') in response def test_no_lang(self): response = self.app.get(self.url(controller='i18nc', action='no_lang')) assert 'No language' in response assert 'No languages' in response def test_langs(self): response = self.app.get(self.url(controller='i18nc', action='langs'), headers={ 'Accept-Language':'fr;q=0.6, en;q=0.1, ja;q=0.3'}) assert "['fr', 'ja', 'en-us']" in response Pylons-1.0.1/tests/test_units/test_basic_app.pyc0000664000076500000240000002246012012306033021720 0ustar benstaff00000000000000 Nc@sddlZddlZddlZddlmZddlmZeeeedZ de fdYZ de fdYZ dS( iN(traises(t test_rootcKssddl}ddlj}ddlm}ddlm} m} ddlm } ddl m } ddl m } ddlm}ddlm}m}dd lm}dd lm}dd lm}td tjjtd dtjjtd d}|j}|j||dd d||d|dd}|j d|j ddd|j ddd||dR;R:Rturl(RR=R>R:((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pytsetUp>s  cCs>|jjdditd6}tjd|js:tdS(Ns /_test_varst extra_environspaste.testing_variabless^\d+$(R:tgettTruetretmatchtbodytAssertionError(Rtresp((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyt test_testvarsFscCs1|jjddt}|jdks-tdS(Ns /test_funct expect_errorsi(R:RDREtstatusRI(RRJ((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyttest_exception_resp_attachJscCs(|jjddt}ds$tdS(Ns /test_emptyRLt wontgethre(R:RDRERI(RRJ((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyttest_no_contentNscCsJddlm}|tidt}|jd}|jsFtdS(Ni(R=R6s /hello/index(R?R=R;RERDRRI(RR=R:RJ((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyt"test_middleware_cache_obj_instanceSscCsMddlm}|tidt}|jd}d|ksItdS(Ni(R=R7s /hello/indexs Hello World(R?R=R;RERDRI(RR=R:RJ((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyttest_attribsafe_tmpl_contextYscCs8|jjdditd6}|jdks4tdS(Ns /hello/indexRCspaste.testing_variablessNothing here but a string(R:RDRERRI(RRJ((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyttest_cache_obj_appglobals_scCs(|jjd}d|ks$tdS(Ns/goodbye/indexs Hello World(R:RDRI(RRJ((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyttest_controller_name_overridecs( RRRBRKRNRt ExceptionRPRQRRRSRT(((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyR<=s      tTestJsonifyDecoratorcBsneZdZdZdZeedZdZdZ dZ dZ dZ d Z RS( cCsdddlm}ddlm}ti}|j|_|||_||jdi|_dS(Ni(R=(R>s routes.map(R?R=R@R>R;RR:RA(RR=R>R:((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyRBis   cCs(|jjd}d|ks$tdS(Ns /hello/indexs Hello World(R:RDRI(Rtresponse((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyttest_basic_responseqscCs7ddl}ddlj}|j|jks3tdS(Ni(RRRRRI(RRR((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyt test_configus cCsOddlm}|ttdd}|jdddditd 6dS( Ni(R=RREs /hello/oopsRMiRCspaste.throw_errors(R?R=R;R*RDR2(RR=R:((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyt test_evalzscCs|jddS(Ntset_lang(t_test_set_lang(R((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyt test_set_langscCs|jddS(Ntset_lang_pylonscontext(R\(R((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyttest_set_lang_pylonscontextscCs|jj|jddd|dd}djd|ksEt|jj|jddd|dd}d |kstdS( NRti18nctactiontlangtjau,言語設定を「ja」に変更しましたsutf-8tchsCould not set language to "ch"(R:RDRAtencodeRI(RRaRW((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyR\s**cCsP|jj|jdddddidd6}djd |ksLtdS( NRR`Rat i18n_indextheaderssfr;q=0.6, en;q=0.1, ja;q=0.3sAccept-Languageu根本インデクスページsutf-8(R:RDRAReRI(RRW((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyttest_detect_langs$ cCsL|jj|jdddd}d|ks6td|ksHtdS(NRR`Ratno_langs No languages No languages(R:RDRARI(RRW((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyt test_no_langs$cCsG|jj|jdddddidd6}d|ksCtdS( NRR`RatlangsRgsfr;q=0.6, en;q=0.1, ja;q=0.3sAccept-Languages['fr', 'ja', 'en-us'](R:RDRARI(RRW((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyt test_langss$ (RRRBRXRYRRIRZR]R_R\RhRjRl(((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyRVhs        ( R+RFtsysR"RRRRER2R;R1R<RV(((sG/Users/ben/Programming/Python/pylons/tests/test_units/test_basic_app.pyts   2+Pylons-1.0.1/tests/test_units/test_controller.py0000664000076500000240000001524311671720166022041 0ustar benstaff00000000000000# -*- coding: utf-8 -*- from paste.fixture import TestApp from paste.registry import RegistryManager from webob.exc import status_map import pylons from pylons.controllers import WSGIController from pylons.testutil import SetupCacheGlobal, ControllerWrap from __init__ import TestWSGIController, TestMiddleware class BasicWSGIController(WSGIController): def __init__(self): self._pylons_log_debug = True def __before__(self): pylons.response.headers['Cache-Control'] = 'private' def __after__(self): pylons.response.set_cookie('big_message', 'goodbye') def index(self): return 'hello world' def yield_fun(self): def its(): x = 0 while x < 100: yield 'hi' x += 1 return its() def strme(self): return "hi there" def use_redirect(self): pylons.response.set_cookie('message', 'Hello World') exc = status_map[301] raise exc('/elsewhere').exception def use_customnotfound(self): exc = status_map[404] raise exc('Custom not found').exception def header_check(self): pylons.response.headers['Content-Type'] = 'text/plain' return "Hello all!" def nothing(self): return def params(self): items = pylons.request.params.mixed().items() items.sort() return str(items) def list(self): return ['from', ' a ', 'list'] class FilteredWSGIController(WSGIController): def __init__(self): self.before = 0 self.after = 0 def __before__(self): self.before += 1 def __after__(self): self.after += 1 action = pylons.request.environ['pylons.routes_dict'].get('action') if action in ('after_response', 'after_string_response'): pylons.response.write(' from __after__') def index(self): return 'hi all, before is %s' % self.before def after_response(self): return 'hi' def after_string_response(self): return 'hello' class TestBasicWSGI(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.baseenviron = {} app = ControllerWrap(BasicWSGIController) app = self.sap = SetupCacheGlobal(app, self.baseenviron) app = TestMiddleware(app) app = RegistryManager(app) self.app = TestApp(app) def setUp(self): TestWSGIController.setUp(self) self.baseenviron.update(self.environ) def test_wsgi_call(self): resp = self.get_response() assert 'hello world' in resp def test_yield_wrapper(self): resp = self.get_response(action='yield_fun') assert 'hi' * 100 in resp def test_404(self): self.environ['paste.config']['global_conf']['debug'] = False self.environ['pylons.routes_dict']['action'] = 'notthere' resp = self.app.get('/', status=404) assert resp.status == 404 def test_404exception(self): self.environ['paste.config']['global_conf']['debug'] = False self.environ['pylons.routes_dict']['action'] = 'use_customnotfound' resp = self.app.get('/', status=404) assert 'pylons.controller.exception' in resp.environ exc = resp.environ['pylons.controller.exception'] assert exc.detail == 'Custom not found' assert resp.status == 404 def test_private_func(self): self.baseenviron['pylons.routes_dict']['action'] = '_private' resp = self.app.get('/', status=404) assert resp.status == 404 def test_strme_func(self): self.baseenviron['pylons.routes_dict']['action'] = 'strme' resp = self.app.get('/') assert "hi there" in resp def test_header_check(self): self.baseenviron['pylons.routes_dict']['action'] = 'header_check' resp = self.app.get('/') assert "Hello all!" in resp assert resp.response.headers['Content-Type'] == 'text/plain' assert resp.response.headers['Cache-Control'] == 'private' assert resp.header('Content-Type') == 'text/plain' def test_head(self): self.baseenviron['pylons.routes_dict']['action'] = 'header_check' resp = self.app._gen_request('HEAD', '/') assert '' == resp.body assert resp.header('Content-Type') == 'text/plain' def test_redirect(self): self.baseenviron['pylons.routes_dict']['action'] = 'use_redirect' resp = self.app.get('/', status=301) def test_nothing(self): self.baseenviron['pylons.routes_dict']['action'] = 'nothing' resp = self.app.get('/') assert '' == resp.body assert resp.response.headers['Cache-Control'] == 'private' def test_unicode_action(self): self.baseenviron['pylons.routes_dict']['action'] = u'ОбсуждениеКомпаний' resp = self.app.get('/', status=404) def test_params(self): self.baseenviron['pylons.routes_dict']['action'] = u'params' resp = self.app.get('/?foo=bar') assert "'foo', u'bar')]" in resp, str(resp) resp = self.app.post('/?foo=bar', params=dict(snafu='snafoo')) assert "'foo', u'bar')" in resp, str(resp) assert "'snafu', u'snafoo')]" in resp, str(resp) resp = self.app.put('/?foo=bar', params=dict(snafu='snafoo')) assert "'foo', u'bar')" in resp, str(resp) assert "'snafu', u'snafoo')]" in resp, str(resp) def test_list(self): self.baseenviron['pylons.routes_dict']['action'] = 'list' assert 'from a list' in self.app.get('/') class TestFilteredWSGI(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.baseenviron = {} app = ControllerWrap(FilteredWSGIController) app = self.sap = SetupCacheGlobal(app, self.baseenviron) app = RegistryManager(app) self.app = TestApp(app) def setUp(self): TestWSGIController.setUp(self) self.baseenviron.update(self.environ) def test_before(self): resp = self.get_response(action='index') assert 'hi' in resp assert 'before is 1' in resp def test_after_response(self): resp = self.get_response(action='after_response') assert 'hi from __after__' in resp def test_after_string_response(self): resp = self.get_response(action='after_string_response') assert 'hello from __after__' in resp def test_start_response(self): self.baseenviron['pylons.routes_dict']['action'] = 'start_response' self.app.get('/', status=404) Pylons-1.0.1/tests/test_units/test_controller.pyc0000664000076500000240000003147212012306033022165 0ustar benstaff00000000000000 vNc@sddlmZddlmZddlmZddlZddlmZddl m Z m Z ddl m Z mZdefd YZd efd YZd e fd YZde fdYZdS(i(tTestApp(tRegistryManager(t status_mapN(tWSGIController(tSetupCacheGlobaltControllerWrap(tTestWSGIControllertTestMiddlewaretBasicWSGIControllercBsteZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z RS( cCs t|_dS(N(tTruet_pylons_log_debug(tself((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyt__init__ scCsdtjjdeZdZdZdZdZdZdZRS(cCsd|_d|_dS(Ni(tbeforetafter(R ((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyR =s cCs|jd7_dS(Ni(R.(R ((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyRAscCsK|jd7_tjjdjd}|dkrGtjjdndS(Nispylons.routes_dicttactiontafter_responsetafter_string_responses from __after__(safter_responsesafter_string_response(R/RR#tenvirontgetRtwrite(R R0((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyRDs cCs d|jS(Nshi all, before is %s(R.(R ((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyRJscCsdS(NR((R ((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyR1MscCsdS(Nthello((R ((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyR2Ps(R+R,R RRRR1R2(((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyR-<s      t TestBasicWSGIcBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZRS(cOsltj|||i|_tt}t||j}|_t|}t|}t ||_ dS(N( RR t baseenvironRRRtsapRRRtapp(R targstkargsR:((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyR Ts    cCs$tj||jj|jdS(N(RtsetUpR8tupdateR3(R ((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyR=]s cCs"|j}d|kstdS(Ns hello world(t get_responsetAssertionError(R tresp((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyttest_wsgi_callas cCs,|jdd}dd|ks(tdS(NR0RRid(R?R@(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyttest_yield_wrapperescCsWt|jdddtdS(Nt_privatespylons.routes_dictR0RGRHi(R8R:R4RHR@(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyttest_private_funcxscCs9d|jdd<|jjd}d|ks5tdS(NRspylons.routes_dictR0RGshi there(R8R:R4R@(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyttest_strme_func}scCsd|jdd<|jjd}d|ks5t|jjddksQt|jjdd ksmt|jddkstdS( NR!spylons.routes_dictR0RGs Hello all!s Content-Types text/plains Cache-ControlR (R8R:R4R@RRtheader(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyttest_header_checks cCsZd|jdd<|jjdd}d|jks;t|jddksVtdS( NR!spylons.routes_dictR0tHEADRGts Content-Types text/plain(R8R:t _gen_requesttbodyR@RP(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyt test_headscCs-d|jdd<|jjddd}dS(NRspylons.routes_dictR0RGRHi-(R8R:R4(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyt test_redirectscCsXd|jdd<|jjd}d|jks8t|jjddksTtdS(NR"spylons.routes_dictR0RGRSs Cache-ControlR (R8R:R4RUR@RR(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyt test_nothingscCs-d|jdd<|jjddd}dS(NuHОбсуждениеКомпанийspylons.routes_dictR0RGRHi(R8R:R4(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyttest_unicode_actionscCsd|jdd<|jjd}d|ks>tt||jjddtdd}d |ksztt|d |kstt||jjddtdd}d |kstt|d |kstt|dS( Nuparamsspylons.routes_dictR0s /?foo=bars'foo', u'bar')]R$tsnafutsnafoos'foo', u'bar')s'snafu', u'snafoo')](R8R:R4R@R(tposttdicttput(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyt test_paramss!!cCs3d|jddeZdZdZdZdZdZdZRS(cOs`tj|||i|_tt}t||j}|_t|}t||_ dS(N( RR R8RR-RR9RRR:(R R;R<R:((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyR s    cCs$tj||jj|jdS(N(RR=R8R>R3(R ((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyR=s cCs:|jdd}d|ks$td|ks6tdS(NR0RRs before is 1(R?R@(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyt test_beforescCs(|jdd}d|ks$tdS(NR0R1shi from __after__(R?R@(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyttest_after_responsescCs(|jdd}d|ks$tdS(NR0R2shello from __after__(R?R@(R RA((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyttest_after_string_responsescCs+d|jdd<|jjddddS(Ntstart_responsespylons.routes_dictR0RGRHi(R8R:R4(R ((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyttest_start_responses(R+R,R R=RbRcRdRf(((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyRas      (t paste.fixtureRtpaste.registryRt webob.excRRtpylons.controllersRtpylons.testutilRRR RRRR-R7Ra(((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_controller.pyts 0ZPylons-1.0.1/tests/test_units/test_decorator_authenticate_form.py0000664000076500000240000000713111645401276025415 0ustar benstaff00000000000000# -*- coding: utf-8 -*- import logging import logging.handlers import os from beaker.middleware import SessionMiddleware from paste.fixture import TestApp from paste.registry import RegistryManager from routes import request_config from __init__ import data_dir, TestWSGIController session_dir = os.path.join(data_dir, 'session') try: import shutil shutil.rmtree(session_dir) except: pass # Eat the logging handler messages my_logger = logging.getLogger() my_logger.setLevel(logging.INFO) # Add the log message handler to the logger class NullHandler(logging.Handler): def emit(self, record): pass my_logger.addHandler(NullHandler()) def make_protected(): from pylons.controllers import WSGIController from pylons.decorators.secure import authenticate_form from webhelpers.pylonslib import secure_form from pylons import request class ProtectedController(WSGIController): def form(self): request_config().environ = request.environ return secure_form.authentication_token() @authenticate_form def protected(self): request_config().environ = request.environ return 'Authenticated' return ProtectedController class TestAuthenticateFormDecorator(TestWSGIController): def setUp(self): from pylons.testutil import ControllerWrap, SetupCacheGlobal ProtectedController = make_protected() TestWSGIController.setUp(self) app = ControllerWrap(ProtectedController) app = SetupCacheGlobal(app, self.environ, setup_session=True) app = SessionMiddleware(app, {}, data_dir=session_dir) app = RegistryManager(app) self.app = TestApp(app) def test_unauthenticated(self): from pylons.decorators.secure import csrf_detected_message self.environ['pylons.routes_dict']['action'] = 'protected' response = self.app.post('/protected', extra_environ=self.environ, expect_errors=True) assert response.status == 403 assert csrf_detected_message in response def test_authenticated(self): from webhelpers.pylonslib import secure_form self.environ['pylons.routes_dict']['action'] = 'form' response = self.app.get('/form', extra_environ=self.environ) token = response.body self.environ['pylons.routes_dict']['action'] = 'protected' response = self.app.post('/protected', params={secure_form.token_key: token}, extra_environ=self.environ, expect_errors=True) assert 'Authenticated' in response self.environ['pylons.routes_dict']['action'] = 'protected' response = self.app.put('/protected', params={secure_form.token_key: token}, extra_environ=self.environ, expect_errors=True) assert 'Authenticated' in response # GET with token_key in query string response = self.app.get('/protected', params={secure_form.token_key: token}, extra_environ=self.environ, expect_errors=True) assert 'Authenticated' in response # POST with token_key in query string response = self.app.post('/protected?' + secure_form.token_key + '=' + token, extra_environ=self.environ, expect_errors=True) assert 'Authenticated' in response Pylons-1.0.1/tests/test_units/test_decorator_authenticate_form.pyc0000664000076500000240000001112412012306033025535 0ustar benstaff00000000000000 Nc@sddlZddlZddlZddlmZddlmZddlmZddl m Z ddl m Z m Z ejje dZyddlZejeWnnXejZejejdejfd YZejed Zd e fd YZdS( iN(tSessionMiddleware(tTestApp(tRegistryManager(trequest_config(tdata_dirtTestWSGIControllertsessiont NullHandlercBseZdZRS(cCsdS(N((tselftrecord((sY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pytemits(t__name__t __module__R (((sY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pyRscsfddlm}ddlmddlmddlmd|ffdY}|S(Ni(tWSGIController(tauthenticate_form(t secure_form(trequesttProtectedControllercs/eZfdZfdZRS(csjt_jS(N(tenvironRtauthentication_token(R(RR(sY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pytform'scsjt_dS(Nt Authenticated(RR(R(R(sY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pyt protected+s(R R RR((RRR(sY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pyR&s(tpylons.controllersR tpylons.decorators.secureRtwebhelpers.pylonslibRtpylonsR(R R((RRRsY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pytmake_protected s " tTestAuthenticateFormDecoratorcBs#eZdZdZdZRS(cCsddlm}m}t}tj|||}|||jdt}t|idt }t |}t ||_ dS(Ni(tControllerWraptSetupCacheGlobalt setup_sessionR( tpylons.testutilRRRRtsetUpRtTrueRt session_dirRRtapp(RRRRR$((sY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pyR!3s    cCsmddlm}d|jdd<|jjdd|jdt}|jd ksWt||ksitdS( Ni(tcsrf_detected_messageRspylons.routes_dicttactions /protectedt extra_environt expect_errorsi(RR%RR$tpostR"tstatustAssertionError(RR%tresponse((sY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pyttest_unauthenticated=s  cCsvddlm}d|jdd<|jjdd|j}|j}d|jdd<|jjd d i||j6d|jd t}d |kst d|jdd<|jj d d i||j6d|jd t}d |kst |jjd d i||j6d|jd t}d |ks0t |jjd |jd|d|jd t}d |ksrt dS(Ni(RRspylons.routes_dictR&s/formR'Rs /protectedtparamsR(Rs /protected?t=( RRRR$tgettbodyR)t token_keyR"R+tput(RRR,ttoken((sY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pyttest_authenticatedFs2         (R R R!R-R5(((sY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pyR2s (tloggingtlogging.handlerstostbeaker.middlewareRt paste.fixtureRtpaste.registryRtroutesRt__init__RRtpathtjoinR#tshutiltrmtreet getLoggert my_loggertsetLeveltINFOtHandlerRt addHandlerRR(((sY/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_authenticate_form.pyts&      Pylons-1.0.1/tests/test_units/test_decorator_cache.py0000664000076500000240000002655411645401276022771 0ustar benstaff00000000000000import os import shutil import time from webtest import TestApp from paste.registry import RegistryManager from beaker.middleware import CacheMiddleware from __init__ import data_dir, TestWSGIController environ = {} sap = None def make_cache_controller(): global sap import pylons from pylons.decorators.cache import beaker_cache, create_cache_key from pylons.controllers import WSGIController, XMLRPCController from pylons.testutil import SetupCacheGlobal, ControllerWrap class CacheController(WSGIController): @beaker_cache(key=None, invalidate_on_startup=True) def test_default_cache_decorator_invalidate(self): pylons.app_globals.counter += 1 return 'Counter=%s' % pylons.app_globals.counter @beaker_cache(key=None) def test_default_cache_decorator(self): pylons.app_globals.counter += 1 return 'Counter=%s' % pylons.app_globals.counter def test_default_cache_decorator_func(self): def func(): pylons.app_globals.counter += 1 return 'Counter=%s' % pylons.app_globals.counter func = beaker_cache(key=None)(func) return func() def test_response_cache_func(self, use_cache_status=True): pylons.response.status_int = 404 def func(): pylons.app_globals.counter += 1 return 'Counter=%s' % pylons.app_globals.counter if use_cache_status: func = beaker_cache(key=None)(func) else: func = beaker_cache(key=None, cache_response=False)(func) return func() @beaker_cache(key=None, type='dbm') def test_dbm_cache_decorator(self): pylons.app_globals.counter += 1 return 'Counter=%s' % pylons.app_globals.counter @beaker_cache(key="param", query_args=True) def test_get_cache_decorator(self): pylons.app_globals.counter += 1 return 'Counter=%s' % pylons.app_globals.counter @beaker_cache(query_args=True) def test_get_cache_default(self): pylons.app_globals.counter += 1 return 'Counter=%s' % pylons.app_globals.counter @beaker_cache(expire=1) def test_expire_cache_decorator(self): pylons.app_globals.counter += 1 return 'Counter=%s' % pylons.app_globals.counter @beaker_cache(expire=1) def test_expire_dbm_cache_decorator(self): pylons.app_globals.counter += 1 return 'Counter=%s' % pylons.app_globals.counter @beaker_cache(key="id") def test_key_cache_decorator(self, id): pylons.app_globals.counter += 1 return 'Counter=%s, id=%s' % (pylons.app_globals.counter, id) @beaker_cache(key=["id", "id2"]) def test_keyslist_cache_decorator(self, id, id2="123"): pylons.app_globals.counter += 1 return 'Counter=%s, id=%s' % (pylons.app_globals.counter, id) def test_invalidate_cache(self): ns, key = create_cache_key(CacheController.test_default_cache_decorator) c = pylons.cache.get_cache(ns) c.remove_value(key) def test_invalidate_dbm_cache(self): ns, key = create_cache_key(CacheController.test_dbm_cache_decorator) c = pylons.cache.get_cache(ns, type='dbm') c.remove_value(key) @beaker_cache(cache_headers=('content-type','content-length', 'x-powered-by')) def test_header_cache(self): pylons.response.headers['Content-Type'] = 'application/special' pylons.response.headers['x-powered-by'] = 'pylons' pylons.response.headers['x-dont-include'] = 'should not be included' return "Hello folks, time is %s" % time.time() @beaker_cache(query_args=True) def test_cache_key_dupe(self): return "Hello folks, time is %s" % time.time() app = ControllerWrap(CacheController) app = sap = SetupCacheGlobal(app, environ, setup_cache=True) app = CacheMiddleware(app, {}, data_dir=cache_dir) app = RegistryManager(app) app = TestApp(app) # This one is missing cache middleware and the cache object to miss on purpsoe bad_app = ControllerWrap(CacheController) bad_app = SetupCacheGlobal(bad_app, environ, setup_cache=False) bad_app = RegistryManager(bad_app) bad_app = TestApp(bad_app) return app, bad_app cache_dir = os.path.join(data_dir, 'cache') try: shutil.rmtree(cache_dir) except: pass class TestBadCacheDecorator(TestWSGIController): def setUp(self): app, bad_app = make_cache_controller() self.app = bad_app TestWSGIController.setUp(self) environ.update(self.environ) def test_no_cache(self): self.assertRaises(Exception, lambda: self.get_response(action='test_default_cache_decorator')) class TestCacheDecorator(TestWSGIController): def setUp(self): app, bad_app = make_cache_controller() self.app = app TestWSGIController.setUp(self) environ.update(self.environ) def test_default_cache_decorator(self): sap.g.counter = 0 self.get_response(action='test_default_cache_decorator_invalidate') response = self.get_response(action='test_default_cache_decorator_invalidate') assert 'text/html' in response.headers['content-type'] assert 'Counter=1' in response response = self.get_response(action='test_default_cache_decorator_invalidate') assert 'Counter=1' in response def test_default_cache_decorator(self): sap.g.counter = 0 self.get_response(action='test_invalidate_cache') response = self.get_response(action='test_default_cache_decorator') assert 'text/html' in response.headers['content-type'] assert 'Counter=1' in response response = self.get_response(action='test_default_cache_decorator') assert 'Counter=1' in response response = self.get_response(action='test_get_cache_decorator', _url='/?param=123') assert 'Counter=2' in response response = self.get_response(action='test_get_cache_decorator', _url="/?param=123") assert 'Counter=2' in response response = self.get_response(action='test_expire_cache_decorator') assert 'Counter=3' in response response = self.get_response(action='test_expire_cache_decorator') assert 'Counter=3' in response time.sleep(2) response = self.get_response(action='test_expire_cache_decorator') assert 'Counter=4' in response response = self.get_response(action='test_key_cache_decorator', id=1) assert 'Counter=5' in response response = self.get_response(action='test_key_cache_decorator', id=2) assert 'Counter=6' in response response = self.get_response(action='test_key_cache_decorator', id=1) assert 'Counter=5' in response response = self.get_response(action='test_keyslist_cache_decorator', id=1, id2=2) assert 'Counter=7' in response response = self.get_response(action='test_keyslist_cache_decorator', id=1, id2=2) assert 'Counter=7' in response response = self.get_response(action='test_get_cache_default', _url='/?param=1243') assert 'Counter=8' in response response = self.get_response(action='test_get_cache_default', _url="/?param=1243") assert 'Counter=8' in response response = self.get_response(action='test_get_cache_default', _url="/?param=123") assert 'Counter=9' in response response = self.get_response(action='test_default_cache_decorator_func') assert 'text/html' in response.headers['content-type'] assert 'Counter=10' in response response = self.get_response(action='test_default_cache_decorator_func') assert 'Counter=10' in response response = self.get_response(action='test_response_cache_func', use_cache_status=True) assert 'Counter=10' in response response = self.get_response(action='test_response_cache_func', use_cache_status=False, test_args=dict(status=404)) assert 'Counter=10' in response def test_dbm_cache_decorator(self): sap.g.counter = 0 self.get_response(action="test_invalidate_dbm_cache") response = self.get_response(action="test_dbm_cache_decorator") assert "Counter=1" in response response = self.get_response(action="test_dbm_cache_decorator") assert "Counter=1" in response self.get_response(action="test_invalidate_dbm_cache") response = self.get_response(action="test_dbm_cache_decorator") assert "Counter=2" in response sap.g.counter = 0 response = self.get_response(action="test_expire_dbm_cache_decorator") assert "Counter=1" in response response = self.get_response(action="test_expire_dbm_cache_decorator") assert "Counter=1" in response time.sleep(2) response = self.get_response(action="test_expire_dbm_cache_decorator") assert "Counter=2" in response def test_cache_key(self): from pylons.decorators.cache import beaker_cache, create_cache_key key = create_cache_key(TestCacheDecorator.test_default_cache_decorator) assert key == ('%s.TestCacheDecorator' % self.__module__, 'test_default_cache_decorator') response = self.get_response(action='test_invalidate_cache') response = self.get_response(action='test_default_cache_decorator') assert 'Counter=1' in response response = self.get_response(action='test_default_cache_decorator') assert 'Counter=1' in response response = self.get_response(action='test_invalidate_cache') response = self.get_response(action='test_default_cache_decorator') assert 'Counter=2' in response def test_cache_key_dupe(self): response = self.get_response(action='test_cache_key_dupe', _url='/test_cache_key_dupe?id=1') time.sleep(0.1) response2 = self.get_response(action='test_cache_key_dupe', _url='/test_cache_key_dupe?id=2&id=1') assert str(response) != str(response2) def test_header_cache(self): response = self.get_response(action='test_header_cache') assert response.headers['content-type'] == 'application/special' assert response.headers['x-powered-by'] == 'pylons' assert 'x-dont-include' not in response.headers output = response.body time.sleep(1) response = self.get_response(action='test_header_cache') assert response.body == output assert response.headers['content-type'] == 'application/special' assert response.headers['x-powered-by'] == 'pylons' assert 'x-dont-include' not in response.headers def test_nocache(self): import pylons sap.g.counter = 0 pylons.config['cache_enabled'] = 'False' response = self.get_response(action='test_default_cache_decorator') assert 'Counter=1' in response response = self.get_response(action='test_default_cache_decorator') assert 'Counter=2' in response pylons.config['cache_enabled'] = 'True' Pylons-1.0.1/tests/test_units/test_decorator_cache.pyc0000664000076500000240000003137712012306033023113 0ustar benstaff00000000000000 Nc@sddlZddlZddlZddlmZddlmZddlmZddl m Z m Z iZ dadZejje dZyejeWnnXde fd YZd e fd YZdS( iN(tTestApp(tRegistryManager(tCacheMiddleware(tdata_dirtTestWSGIControllercsddlddlmmddlm}m}ddlm}m }d|ffdY|}||t dt }a t |idt}t|}t|}|}||t dt}t|}t|}||fS( Ni(t beaker_cachetcreate_cache_key(tWSGIControllertXMLRPCController(tSetupCacheGlobaltControllerWraptCacheControllercseZdddefdZddfdZfdZefdZddddfdZdd d efd Z d efd Z d dfdZ d dfdZ ddfdZ dddgdfdZfdZfdZddfdZd edZRS( tkeytinvalidate_on_startupcs jjd7_djjS(Nis Counter=%s(t app_globalstcounter(tself(tpylons(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyt'test_default_cache_decorator_invalidatescs jjd7_djjS(Nis Counter=%s(RR(R(R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_default_cache_decoratorscs+fd}dd|}|S(Ncs jjd7_djjS(Nis Counter=%s(RR((R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pytfunc#sR (tNone(RR(RR(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyt!test_default_cache_decorator_func"scs[dj_fd}|r9dd|}ndddt|}|S(Nics jjd7_djjS(Nis Counter=%s(RR((R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyR+sR tcache_response(tresponset status_intRtFalse(Rtuse_cache_statusR(RR(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_response_cache_func)s  ttypetdbmcs jjd7_djjS(Nis Counter=%s(RR(R(R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_dbm_cache_decorator4stparamt query_argscs jjd7_djjS(Nis Counter=%s(RR(R(R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_get_cache_decorator9scs jjd7_djjS(Nis Counter=%s(RR(R(R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_get_cache_default>stexpireics jjd7_djjS(Nis Counter=%s(RR(R(R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_expire_cache_decoratorCscs jjd7_djjS(Nis Counter=%s(RR(R(R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_expire_dbm_cache_decoratorHstidcs&jjd7_djj|fS(NisCounter=%s, id=%s(RR(RR'(R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_key_cache_decoratorMstid2t123cs&jjd7_djj|fS(NisCounter=%s, id=%s(RR(RR'R)(R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_keyslist_cache_decoratorRscs8j\}}jj|}|j|dS(N(Rtcachet get_cachet remove_value(RtnsR tc(RR R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_invalidate_cacheWscs>j\}}jj|dd}|j|dS(NRR(RR,R-R.(RR/R R0(RR R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_invalidate_dbm_cache\st cache_headerss content-typescontent-lengths x-powered-bycs>djjds(t assertRaisest Exception(R((RsM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyt test_no_caches(R8R9RFRM(((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyREs tTestCacheDecoratorcBsPeZdZdZdZdZdZdZdZdZRS(cCs9t\}}||_tj|tj|jdS(N(RDRBRRFR?RG(RRBRC((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyRFs  cCsdtj_|jdd|jdd}d|jdksGtd|ksYt|jdd}d|ks}tdS(NiRHRs text/htmls content-types Counter=1(R@tgRRIR4tAssertionError(RR((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyRs c Csndtj_|jdd|jdd}d|jdksGtd|ksYt|jdd}d|ks}t|jddd d }d |kst|jddd d }d |kst|jdd }d |kst|jdd }d |ksttjd|jdd }d|ksJt|jdddd}d|kstt|jdddd}d|kst|jdddd}d|kst|jdddddd}d|kst|jdddddd}d|ks(t|jddd d}d|ksRt|jddd d}d|ks|t|jddd d }d|kst|jdd}d|jdkstd|kst|jdd}d|kst|jdddt}d|ks1t|jdddt d t d!d"}d|ksjtdS(#NiRHR1Rs text/htmls content-types Counter=1R"t_urls /?param=123s Counter=2R%s Counter=3is Counter=4R(R'is Counter=5s Counter=6R+R)s Counter=7R#s /?param=1243s Counter=8s Counter=9Rs Counter=10RRt test_argststatusi( R@RORRIR4RPR5tsleepR:Rtdict(RR((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyRsX  cCs!dtj_|jdd|jdd}d|ks@t|jdd}d|ksdt|jdd|jdd}d|kstdtj_|jdd}d|kst|jdd}d|ksttjd|jdd}d|kstdS( NiRHR2Rs Counter=1s Counter=2R&i(R@RORRIRPR5RT(RR((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyRs"   cCsddlm}m}|tj}|d|jdfksDt|jdd}|jdd}d|kszt|jdd}d|kst|jdd}|jdd}d|kstdS( Ni(RRs%s.TestCacheDecoratorRRHR1s Counter=1s Counter=2(R<RRRNRR9RPRI(RRRR R((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyttest_cache_keyscCs_|jdddd}tjd|jdddd}t|t|ks[tdS(NRHR7RQs/test_cache_key_dupe?id=1g?s/test_cache_key_dupe?id=2&id=1(RIR5RTtstrRP(RRt response2((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyR7s    cCs|jdd}|jddks+t|jddksDtd|jksYt|j}tjd|jdd}|j|kst|jddkst|jddkstd|jkstdS( NRHR6s content-typesapplication/specials x-powered-byRsx-dont-includei(RIR4RPtbodyR5RT(RRtoutput((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_cache.pyR6s  cCs~ddl}dtj_d|jd<|jdd}d|ksIt|jdd}d|ksmtd |jds    k Pylons-1.0.1/tests/test_units/test_decorator_https.py0000664000076500000240000000653411645401276023064 0ustar benstaff00000000000000from paste.fixture import TestApp from paste.registry import RegistryManager from routes.middleware import RoutesMiddleware from __init__ import TestWSGIController def make_httpscontroller(): from pylons import request, url from pylons.controllers import WSGIController from pylons.decorators.secure import https class HttpsController(WSGIController): @https('/pylons') def index(self): return 'index page' @https(lambda: url(controller='auth', action='login')) def login2(self): return 'login2 page' @https(lambda: request.url) def secure(self): return 'secure page' @https() def get(self): return 'get page' return HttpsController class TestHttpsDecorator(TestWSGIController): def setUp(self): from pylons.testutil import ControllerWrap, SetupCacheGlobal HttpsController = make_httpscontroller() TestWSGIController.setUp(self) from routes import Mapper map = Mapper() map.connect('/:action') map.connect('/:action/:id') map.connect('/:controller/:action/:id') map.connect('/:controller/:action') app = ControllerWrap(HttpsController) app = SetupCacheGlobal(app, self.environ, setup_cache=False) app = RoutesMiddleware(app, map) app = RegistryManager(app) self.app = TestApp(app) def test_https_explicit_path(self): self.environ['pylons.routes_dict']['action'] = 'index' response = self.app.get('/index', status=302) assert response.header_dict.get('location') == \ 'https://localhost/pylons' self.environ['wsgi.url_scheme'] = 'https' response = self.app.get('/index', status=200) assert 'location' not in response.header_dict assert 'index page' in response def test_https_disallows_post(self): self.environ['pylons.routes_dict']['action'] = 'index' response = self.app.post('/index', status=405) def test_https_callable(self): self.environ['pylons.routes_dict']['action'] = 'login2' response = self.app.get('/login2', status=302) assert response.header_dict.get('location') == \ 'https://localhost/auth/login' self.environ['wsgi.url_scheme'] = 'https' response = self.app.get('/login2', status=200) assert 'location' not in response.header_dict assert 'login2 page' in response def test_https_callable_current(self): self.environ['pylons.routes_dict']['action'] = 'secure' response = self.app.get('/secure', status=302) assert response.header_dict.get('location') == \ 'https://localhost/secure' self.environ['wsgi.url_scheme'] = 'https' response = self.app.get('/secure', status=200) assert 'location' not in response.header_dict assert 'secure page' in response def test_https_redirect_to_self(self): self.environ['pylons.routes_dict']['action'] = 'get' response = self.app.get('/get', status=302) assert response.header_dict.get('location') == \ 'https://localhost/get' self.environ['wsgi.url_scheme'] = 'https' response = self.app.get('/get', status=200) assert 'location' not in response.header_dict assert 'get page' in response Pylons-1.0.1/tests/test_units/test_decorator_https.pyc0000664000076500000240000001310212012306033023174 0ustar benstaff00000000000000 Nc@scddlmZddlmZddlmZddlmZdZdefdYZ dS( i(tTestApp(tRegistryManager(tRoutesMiddleware(tTestWSGIControllercs\ddlmmddlm}ddlmd|ffdY}|S(Ni(trequestturl(tWSGIController(thttpstHttpsControllercskeZddZfddZfddZdZRS(s/pylonscSsdS(Ns index page((tself((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pytindexscsddddS(Nt controllertauthtactiontlogin(((R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pytscSsdS(Ns login2 page((R ((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pytlogin2scsjS(N(R((R(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pyRscSsdS(Ns secure page((R ((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pytsecurescSsdS(Nsget page((R ((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pytgets(t__name__t __module__R RRR((RRR(sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pyR s(tpylonsRRtpylons.controllersRtpylons.decorators.secureR(RR((RRRsM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pytmake_httpscontrollers "tTestHttpsDecoratorcBs>eZdZdZdZdZdZdZRS(cCsddlm}m}t}tj|ddlm}|}|jd|jd|jd|jd||}|||j dt }t ||}t |}t ||_dS( Ni(tControllerWraptSetupCacheGlobal(tMappers/:actions /:action/:ids/:controller/:action/:ids/:controller/:actiont setup_cache(tpylons.testutilRRRRtsetUptroutesRtconnecttenvirontFalseRRRtapp(R RRRRtmapR$((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pyR!s         cCsd|jdd<|jjddd}|jjddksGtd |jd <|jjddd }d|jkstd |kstdS( NR spylons.routes_dictR s/indextstatusi.tlocationshttps://localhost/pylonsRswsgi.url_schemeis index page(R"R$Rt header_dicttAssertionError(R tresponse((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pyttest_https_explicit_path1s cCs-d|jdd<|jjddd}dS(NR spylons.routes_dictR s/indexR&i(R"R$tpost(R R*((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pyttest_https_disallows_post=scCsd|jdd<|jjddd}|jjddksGtd |jd <|jjddd }d|jkstd |kstdS( NRspylons.routes_dictR s/login2R&i.R'shttps://localhost/auth/loginRswsgi.url_schemeis login2 page(R"R$RR(R)(R R*((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pyttest_https_callableAs cCsd|jdd<|jjddd}|jjddksGtd |jd <|jjddd }d|jkstd |kstdS( NRspylons.routes_dictR s/secureR&i.R'shttps://localhost/secureRswsgi.url_schemeis secure page(R"R$RR(R)(R R*((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pyttest_https_callable_currentMs cCsd|jdd<|jjddd}|jjddksGtd |jd <|jjddd }d|jkstd |kstdS( NRspylons.routes_dictR s/getR&i.R'shttps://localhost/getRswsgi.url_schemeisget page(R"R$RR(R)(R R*((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pyttest_https_redirect_to_selfYs (RRRR+R-R.R/R0(((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pyR s    N( t paste.fixtureRtpaste.registryRtroutes.middlewareRt__init__RRR(((sM/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_https.pyts  Pylons-1.0.1/tests/test_units/test_decorator_jsonify.py0000664000076500000240000000316011645401276023373 0ustar benstaff00000000000000import warnings from paste.fixture import TestApp from paste.registry import RegistryManager from __init__ import TestWSGIController def make_cache_controller_app(): from pylons.testutil import ControllerWrap, SetupCacheGlobal from pylons.decorators import jsonify from pylons.controllers import WSGIController class CacheController(WSGIController): @jsonify def test_bad_json(self): return ["this is neat"] @jsonify def test_bad_json2(self): return ("this is neat",) @jsonify def test_good_json(self): return dict(fred=42) environ = {} app = ControllerWrap(CacheController) app = sap = SetupCacheGlobal(app, environ) app = RegistryManager(app) app = TestApp(app) return app, environ class TestJsonifyDecorator(TestWSGIController): def setUp(self): self.app, environ = make_cache_controller_app() TestWSGIController.setUp(self) environ.update(self.environ) warnings.simplefilter('error', Warning) def tearDown(self): warnings.simplefilter('always', Warning) def test_bad_json(self): for action in 'test_bad_json', 'test_bad_json2': try: response = self.get_response(action=action) except Warning, msg: assert 'JSON responses with Array envelopes are' in msg[0] def test_good_json(self): response = self.get_response(action='test_good_json') assert '{"fred": 42}' in response assert response.header('Content-Type') == 'application/json; charset=utf-8' Pylons-1.0.1/tests/test_units/test_decorator_jsonify.pyc0000664000076500000240000000654012012306033023523 0ustar benstaff00000000000000 Nc@s_ddlZddlmZddlmZddlmZdZdefdYZdS(iN(tTestApp(tRegistryManager(tTestWSGIControllercsddlm}m}ddlmddlm}d|ffdY}i}||}|||}}t|}t|}||fS(Ni(tControllerWraptSetupCacheGlobal(tjsonify(tWSGIControllertCacheControllercs5eZdZdZdZRS(cSsdgS(Ns this is neat((tself((sO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pyt test_bad_jsonscSsdS(Ns this is neat(s this is neat((R((sO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pyttest_bad_json2scSs tddS(Ntfredi*(tdict(R((sO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pyttest_good_jsons(t__name__t __module__R R R ((R(sO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pyR s( tpylons.testutilRRtpylons.decoratorsRtpylons.controllersRRR(RRRRtenvirontapptsap((RsO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pytmake_cache_controller_apps   tTestJsonifyDecoratorcBs,eZdZdZdZdZRS(cCsCt\|_}tj||j|jtjdtdS(Nterror( RRRtsetUptupdateRtwarningst simplefiltertWarning(RR((sO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pyR$s cCstjdtdS(Ntalways(RRR(R((sO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pyttearDown*scCsWxPdD]H}y|jd|}Wqtk rN}d|dksOtqXqWdS(NR R tactions'JSON responses with Array envelopes arei(s test_bad_jsonstest_bad_json2(t get_responseRtAssertionError(RR tresponsetmsg((sO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pyR -s  cCsC|jdd}d|ks$t|jddks?tdS(NR R s {"fred": 42}s Content-Typesapplication/json; charset=utf-8(R!R"theader(RR#((sO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pyR 4s(RRRRR R (((sO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pyR#s   ( Rt paste.fixtureRtpaste.registryRt__init__RRR(((sO/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_jsonify.pyts  Pylons-1.0.1/tests/test_units/test_decorator_validate.py0000664000076500000240000001134411671720166023507 0ustar benstaff00000000000000# -*- coding: utf-8 -*- import formencode from formencode.htmlfill import html_quote from paste.fixture import TestApp from paste.registry import RegistryManager from __init__ import TestWSGIController def custom_error_formatter(error): return '

%s

\n' % html_quote(error) class NetworkForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True new_network = formencode.validators.URL(not_empty=True) class HelloForm(formencode.Schema): hello = formencode.ForEach(formencode.validators.Int()) def make_validating_controller(): from pylons.decorators import validate from pylons.controllers import WSGIController class ValidatingController(WSGIController): def new_network(self): return """
Network
""" @validate(schema=NetworkForm, form='new_network') def network(self): return 'Your network is: %s' % self.form_result.get('new_network') def view_hello(self): return """
Hello Bad Hello! 
""" @validate(schema=HelloForm(), post_only=False, form='view_hello') def hello(self): return str(self.form_result) @validate(schema=HelloForm(), post_only=False, form='view_hello', auto_error_formatter=custom_error_formatter) def hello_custom(self): return str(self.form_result) @validate(schema=NetworkForm, form='hello_recurse') def hello_recurse(self, environ): if environ['REQUEST_METHOD'] == 'GET': return self.new_network() else: return 'Your network is: %s' % self.form_result.get('new_network') return ValidatingController class TestValidateDecorator(TestWSGIController): def setUp(self): from pylons.testutil import ControllerWrap, SetupCacheGlobal ValidatingController = make_validating_controller() TestWSGIController.setUp(self) app = SetupCacheGlobal(ControllerWrap(ValidatingController), self.environ) app = RegistryManager(app) self.app = TestApp(app) def test_network_validated(self): response = self.post_response(action='network', new_network='http://pylonshq.com/') assert 'Your network is: http://pylonshq.com/' in response def test_network_failed_validation_non_ascii(self): response = self.post_response(action='network', new_network='Росси́я') assert 'That is not a valid URL' in response assert 'Росси́я' in response def test_recurse_validated(self): response = self.post_response(action='hello_recurse', new_network='http://pylonshq.com/') assert 'Your network is: http://pylonshq.com/' in response def test_hello(self): self.environ['pylons.routes_dict']['action'] = 'hello' response = self.app.post('/hello?hello=1&hello=2&hello=3', extra_environ=self.environ) assert "'hello': [1, 2, 3]" in response def test_hello_failed(self): self.environ['pylons.routes_dict']['action'] = 'hello' response = self.app.post('/hello?hello=1&hello=2&hello=hi', extra_environ=self.environ) assert 'Bad Hello! ' in response assert "[None, None, u'Please enter an integer value']" in response def test_hello_custom_failed(self): self.environ['pylons.routes_dict']['action'] = 'hello_custom' response = \ self.app.post('/hello_custom?hello=1&hello=2&hello=hi', extra_environ=self.environ) assert 'Bad Hello! ' in response assert "[None, None, u'Please enter an integer value']" in response assert ("""

[None, None, u'Please enter """ """an integer value']

""") in response Pylons-1.0.1/tests/test_units/test_decorator_validate.pyc0000664000076500000240000001642612012306033023637 0ustar benstaff00000000000000 vNc@sddlZddlmZddlmZddlmZddlmZdZ dej fdYZ d ej fd YZ d Z d efd YZdS(iN(t html_quote(tTestApp(tRegistryManager(tTestWSGIControllercCsdt|S(Ns,

%s

(R(terror((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pytcustom_error_formatter st NetworkFormcBs)eZeZeZejjdeZRS(t not_empty( t__name__t __module__tTruetallow_extra_fieldstfilter_extra_fieldst formencodet validatorstURLt new_network(((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyR st HelloFormcBs eZejejjZRS((RR R tForEachRtIntthello(((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyRscs@ddlmddlm}d|ffdY}|S(Ni(tvalidate(tWSGIControllertValidatingControllerc seZdZdedddZdZdededddZdededdd e d Z dedd d Z RS( cSsdS(Ns9
Network
((tself((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyRstschematformRcSsd|jjdS(NsYour network is: %sR(t form_resulttget(R((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pytnetwork+scSsdS(Ns
Hello Bad Hello! 
((R((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyt view_hello/st post_onlyRcSs t|jS(N(tstrR(R((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyRCstauto_error_formattercSs t|jS(N(R R(R((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyt hello_customGst hello_recursecSs2|ddkr|jSd|jjdSdS(NtREQUEST_METHODtGETsYour network is: %sR(RRR(Rtenviron((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyR#Ls ( RR RRRRRtFalseRRR"R#((R(sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyRs  '(tpylons.decoratorsRtpylons.controllersR(RR((RsP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pytmake_validating_controllers9tTestValidateDecoratorcBsGeZdZdZdZdZdZdZdZRS(cCscddlm}m}t}tj|||||j}t|}t||_ dS(Ni(tControllerWraptSetupCacheGlobal( tpylons.testutilR,R-R*RtsetUpR&RRtapp(RR,R-RR0((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyR/Vs     cCs.|jdddd}d|ks*tdS(NtactionRRshttp://pylonshq.com/s%Your network is: http://pylonshq.com/(t post_responsetAssertionError(Rtresponse((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyttest_network_validated`s cCs@|jdddd}d|ks*td|ks<tdS(NR1RRsРосси́яsThat is not a valid URL(R2R3(RR4((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyt(test_network_failed_validation_non_asciiescCs.|jdddd}d|ks*tdS(NR1R#Rshttp://pylonshq.com/s%Your network is: http://pylonshq.com/(R2R3(RR4((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyttest_recurse_validatedjs cCsBd|jdd<|jjdd|j}d|ks>tdS(NRspylons.routes_dictR1s/hello?hello=1&hello=2&hello=3t extra_environs'hello': [1, 2, 3](R&R0tpostR3(RR4((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyt test_helloos cCsTd|jdd<|jjdd|j}d|ks>td|ksPtdS(NRspylons.routes_dictR1s/hello?hello=1&hello=2&hello=hiR8sBad Hello! s.[None, None, u'Please enter an integer value'](R&R0R9R3(RR4((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyttest_hello_failedus  cCsfd|jdd<|jjdd|j}d|ks>td|ksPtd|ksbtdS( NR"spylons.routes_dictR1s&/hello_custom?hello=1&hello=2&hello=hiR8sBad Hello! s.[None, None, u'Please enter an integer value']sW

[None, None, u'Please enter an integer value']

(R&R0R9R3(RR4((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyttest_hello_custom_failed|s ( RR R/R5R6R7R:R;R<(((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyR+Us     (R tformencode.htmlfillRt paste.fixtureRtpaste.registryRt__init__RRtSchemaRRR*R+(((sP/Users/ben/Programming/Python/pylons/tests/test_units/test_decorator_validate.pyts   @Pylons-1.0.1/tests/test_units/test_helpers.py0000664000076500000240000000277311645401276021323 0ustar benstaff00000000000000import warnings from unittest import TestCase from paste.fixture import TestApp from paste.httpexceptions import HTTPMovedPermanently from paste.registry import RegistryManager from __init__ import TestWSGIController def make_helperscontroller(): import pylons from pylons.controllers import WSGIController from pylons.controllers.util import etag_cache class HelpersController(WSGIController): def test_etag_cache(self): etag_cache('test') return "from etag_cache" return HelpersController class TestHelpers(TestWSGIController): def __init__(self, *args, **kargs): from pylons.testutil import ControllerWrap, SetupCacheGlobal HelpersController = make_helperscontroller() TestWSGIController.__init__(self, *args, **kargs) self.baseenviron = {} app = ControllerWrap(HelpersController) app = self.sap = SetupCacheGlobal(app, self.baseenviron) app = RegistryManager(app) self.app = TestApp(app) def setUp(self): TestWSGIController.setUp(self) self.baseenviron.update(self.environ) warnings.simplefilter('error', DeprecationWarning) def tearDown(self): warnings.simplefilter('always', DeprecationWarning) def test_return_etag_cache(self): self.baseenviron['pylons.routes_dict']['action'] = 'test_etag_cache' response = self.app.get('/') assert '"test"' == response.header('Etag') assert 'from etag_cache' in response Pylons-1.0.1/tests/test_units/test_helpers.pyc0000664000076500000240000000561512012306033021444 0ustar benstaff00000000000000 Nc@sddlZddlmZddlmZddlmZddlmZddl m Z dZ de fd YZ dS( iN(tTestCase(tTestApp(tHTTPMovedPermanently(tRegistryManager(tTestWSGIControllercsLddl}ddlm}ddlmd|ffdY}|S(Ni(tWSGIController(t etag_cachetHelpersControllercseZfdZRS(csddS(Nttestsfrom etag_cache((tself(R(sE/Users/ben/Programming/Python/pylons/tests/test_units/test_helpers.pyttest_etag_caches (t__name__t __module__R ((R(sE/Users/ben/Programming/Python/pylons/tests/test_units/test_helpers.pyRs(tpylonstpylons.controllersRtpylons.controllers.utilR(R RR((RsE/Users/ben/Programming/Python/pylons/tests/test_units/test_helpers.pytmake_helperscontroller s  t TestHelperscBs,eZdZdZdZdZRS(cOsddlm}m}t}tj|||i|_||}|||j}|_t|}t ||_ dS(Ni(tControllerWraptSetupCacheGlobal( tpylons.testutilRRRRt__init__t baseenvirontsapRRtapp(R targstkargsRRRR((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_helpers.pyRs    cCs4tj||jj|jtjdtdS(Nterror(RtsetUpRtupdatetenvirontwarningst simplefiltertDeprecationWarning(R ((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_helpers.pyR"s cCstjdtdS(Ntalways(RR R!(R ((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_helpers.pyttearDown'scCsTd|jdd<|jjd}d|jdks>td|ksPtdS(NR spylons.routes_dicttactiont/s"test"tEtagsfrom etag_cache(RRtgettheadertAssertionError(R tresponse((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_helpers.pyttest_return_etag_cache*s(R R RRR#R+(((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_helpers.pyRs  ( RtunittestRt paste.fixtureRtpaste.httpexceptionsRtpaste.registryRRRRR(((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_helpers.pyts  Pylons-1.0.1/tests/test_units/test_i18n.py0000664000076500000240000000311411671744177020437 0ustar benstaff00000000000000# -*- coding: utf-8 -*- import os import sys from paste.fixture import TestApp from __init__ import test_root lang_setup = None def setup_py_trans(): global lang_setup import pylons from pylons.i18n.translation import _get_translator root = os.path.join(test_root, 'sample_controllers') lang_setup = {'pylons.paths': {'root': root}, 'pylons.package': 'sample_controllers'} sys.path.append(test_root) pylons.translator._push_object(_get_translator(None, pylons_config=lang_setup)) glob_set = [] class TestI18N(object): def setUp(self): setup_py_trans() def test_lazify(self): from pylons.i18n.translation import lazify def show_str(st): return '%s%s' % (st, len(glob_set)) lazy_show_str = lazify(show_str) result1 = lazy_show_str('fred') result2 = show_str('fred') assert str(result1) == str(result2) glob_set.append('1') assert str(result1) != str(result2) def test_noop(self): import pylons from pylons.i18n.translation import _, N_, set_lang foo = N_('Hello') class Bar(object): def __init__(self): self.local_foo = _(foo) assert Bar().local_foo == 'Hello' t = set_lang('fr', set_environ=False, pylons_config=lang_setup) pylons.translator._push_object(t) assert Bar().local_foo == 'Bonjour' t = set_lang('es', set_environ=False, pylons_config=lang_setup) pylons.translator._push_object(t) assert Bar().local_foo == u'¡Hola!' assert foo == 'Hello' Pylons-1.0.1/tests/test_units/test_i18n.pyc0000664000076500000240000000567212012306033020564 0ustar benstaff00000000000000 Nc@sgddlZddlZddlmZddlmZdadZgZ de fdYZ dS(iN(tTestApp(t test_rootcCs|ddl}ddlm}tjjtd}ii|d6d6dd6atjj t|j j |ddtdS(Ni(t_get_translatortsample_controllerstroots pylons.pathsspylons.packaget pylons_config( tpylonstpylons.i18n.translationRtostpathtjoinRt lang_setuptsystappendt translatort _push_objecttNone(RRR((sB/Users/ben/Programming/Python/pylons/tests/test_units/test_i18n.pytsetup_py_trans s  tTestI18NcBs#eZdZdZdZRS(cCs tdS(N(R(tself((sB/Users/ben/Programming/Python/pylons/tests/test_units/test_i18n.pytsetUpscCsddlm}d}||}|d}|d}t|t|ks[ttjdt|t|kstdS(Ni(tlazifycSsd|ttfS(Ns%s%s(tlentglob_set(tst((sB/Users/ben/Programming/Python/pylons/tests/test_units/test_i18n.pytshow_strstfredt1(RRtstrtAssertionErrorRR (RRRt lazy_show_strtresult1tresult2((sB/Users/ben/Programming/Python/pylons/tests/test_units/test_i18n.pyt test_lazifys     csddl}ddlmm}m}|ddtffdY}|jdkskt|ddtdt }|j j ||jd kst|d dtdt }|j j ||jd kstdkstdS( Ni(t_tN_tset_langtHellotBarcseZfdZRS(cs|_dS(N(t local_foo(R(tfooR"(sB/Users/ben/Programming/Python/pylons/tests/test_units/test_i18n.pyt__init__.s(t__name__t __module__R)((R(R"(sB/Users/ben/Programming/Python/pylons/tests/test_units/test_i18n.pyR&-stfrt set_environRtBonjourtesu¡Hola!( RRR"R#R$tobjectR'RtFalseR RR(RRR#R$R&tt((R(R"sB/Users/ben/Programming/Python/pylons/tests/test_units/test_i18n.pyt test_noop(s  (R*R+RR!R3(((sB/Users/ben/Programming/Python/pylons/tests/test_units/test_i18n.pyRs  ( RR t paste.fixtureRR)RRR RRR0R(((sB/Users/ben/Programming/Python/pylons/tests/test_units/test_i18n.pyts   Pylons-1.0.1/tests/test_units/test_jsonrpc.py0000664000076500000240000001571211671720533021333 0ustar benstaff00000000000000# -*- coding: utf-8 -*- from paste.fixture import TestApp from paste.registry import RegistryManager import webob.exc as exc import json from __init__ import TestWSGIController def make_basejsonrpc(): from pylons.controllers import JSONRPCController, JSONRPCError class BaseJSONRPCController(JSONRPCController): def __init__(self): self._pylons_log_debug = True def echo(self, message): return message def int_arg_check(self, arg): if not isinstance(arg, int): raise JSONRPCError(1, 'That is not an integer') else: return 'got an integer' def return_garbage(self): return JSONRPCController def subtract(self, x, y): if not isinstance(x, int) and not isinstance(y, int): raise JSONRPCError(1, 'That is not an integer') else: return x - y def v2_echo(self, message='Default message'): return message def v2_int_arg_check(self, arg=99): if not isinstance(arg, int): raise JSONRPCError(1, 'That is not an integer') else: return 'got an integer' def v2_decrement(self, x, y=1): """Like subtract, but decrements by default.""" if not isinstance(x, int) and not isinstance(y, int): raise JSONRPCError(1, 'That is not an integer') else: return x - y def _private(self): return 'private method' return BaseJSONRPCController class TestJSONRPCController(TestWSGIController): def __init__(self, *args, **kwargs): from pylons.testutil import ControllerWrap, SetupCacheGlobal BaseJSONRPCController = make_basejsonrpc() TestWSGIController.__init__(self, *args, **kwargs) self.baseenviron = {} self.baseenviron['pylons.routes_dict'] = {} app = ControllerWrap(BaseJSONRPCController) app = self.sap = SetupCacheGlobal(app, self.baseenviron) app = RegistryManager(app) self.app = TestApp(app) def test_echo(self): response = self.jsonreq('echo', args=('hello, world',)) assert dict(jsonrpc='2.0', id='test', result='hello, world') == response def test_int_arg_check(self): response = self.jsonreq('int_arg_check', args=('1',)) assert dict(jsonrpc='2.0', id='test', error={'code': 1, 'message': 'That is not an integer'}) == response def test_return_garbage(self): response = self.jsonreq('return_garbage') assert dict(jsonrpc='2.0', id='test', error={'code': -32603, 'message': "Internal error"}) == response def test_private_method(self): response = self.jsonreq('_private') assert dict(jsonrpc='2.0', id='test', error={'code': -32601, 'message': "Method not found"}) == response def test_content_type(self): response = self.jsonreq('echo', args=('foo',)) assert self.response.header('Content-Type') == 'application/json' def test_missing_method(self): response = self.jsonreq('foo') assert dict(jsonrpc='2.0', id='test', error={'code': -32601, 'message': "Method not found"}) == response def test_no_content_length(self): data = json.dumps(dict(jsonrpc='2.0', id='test', method='echo', args=('foo',))) self.assertRaises(exc.HTTPLengthRequired, lambda: self.app.post('/', extra_environ=\ dict(CONTENT_LENGTH=''))) def test_zero_content_length(self): data = json.dumps(dict(jsonrpc='2.0', id='test', method='echo', args=('foo',))) self.assertRaises(exc.HTTPLengthRequired, lambda: self.app.post('/', extra_environ=\ dict(CONTENT_LENGTH='0'))) def test_positional_params(self): response = self.jsonreq('subtract', args=[4, 2]) assert dict(jsonrpc='2.0', id='test', result=2) == response def test_missing_positional_param(self): response = self.jsonreq('subtract', args=[1]) assert dict(jsonrpc='2.0', id='test', error={'code': -32602, 'message': "Invalid params"}) == response def test_wrong_param_type(self): response = self.jsonreq('subtract', args=['1', '2']) assert dict(jsonrpc='2.0', id='test', error={'code': 1, 'message': "That is not an integer"}) == response def test_v2_echo(self): response = self.jsonreq('v2_echo', args={'message': 'hello, world'}) assert dict(jsonrpc='2.0', id='test', result='hello, world') == response def test_v2_echo_default(self): response = self.jsonreq('v2_echo', args={}) assert dict(jsonrpc='2.0', id='test', result='Default message') == response def test_v2_int_arg_check_valid(self): response = self.jsonreq('v2_int_arg_check', args={'arg': 5}) assert dict(jsonrpc='2.0', id='test', result='got an integer') def test_v2_int_arg_check_default_keyword_argument(self): response = self.jsonreq('v2_int_arg_check', args={}) assert dict(jsonrpc='2.0', id='test', result='got an integer') def test_v2_int_arg_check(self): response = self.jsonreq('v2_int_arg_check', args={'arg': 'abc'}) assert dict(jsonrpc='2.0', id='test', error={'code': 1, 'message': "That is not an integer"}) == response def test_v2_decrement(self): response = self.jsonreq('v2_decrement', args={'x': 50, 'y': 100}) assert dict(jsonrpc='2.0', id='test', result=-50) == response def test_v2_decrement_default_keywoard_argument(self): response = self.jsonreq('v2_decrement', args={'x': 50}) assert dict(jsonrpc='2.0', id='test', result=49) == response def test_v2_decrement_missing_keyword_argument(self): response = self.jsonreq('v2_decrement', args={}) assert dict(jsonrpc='2.0', id='test', error={'code': -32602, 'message': "Invalid params"}) == response Pylons-1.0.1/tests/test_units/test_jsonrpc.pyc0000664000076500000240000002562712012306033021465 0ustar benstaff00000000000000 [Nc@snddlmZddlmZddljZddlZddlmZdZ defdYZ dS(i(tTestApp(tRegistryManagerN(tTestWSGIControllercs9ddlmmdffdY}|S(Ni(tJSONRPCControllert JSONRPCErrortBaseJSONRPCControllercseZdZdZfdZfdZfdZddZdfdZd fd Z d Z RS( cSs t|_dS(N(tTruet_pylons_log_debug(tself((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyt__init__scSs|S(N((Rtmessage((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pytechoscs)t|ts!ddndSdS(NisThat is not an integersgot an integer(t isinstancetint(Rtarg(R(sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyt int_arg_checkscsS(N((R(R(sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pytreturn_garbagescs>t|t r2t|t r2ddn||SdS(NisThat is not an integer(R R (Rtxty(R(sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pytsubtracts sDefault messagecSs|S(N((RR ((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pytv2_echo$siccs)t|ts!ddndSdS(NisThat is not an integersgot an integer(R R (RR(R(sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pytv2_int_arg_check'sics>t|t r2t|t r2ddn||SdS(s)Like subtract, but decrements by default.isThat is not an integerN(R R (RRR(R(sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyt v2_decrement-s cSsdS(Nsprivate method((R((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyt_private4s( t__name__t __module__R R RRRRRRR((RR(sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyR s   (tpylons.controllersRR(R((RRsE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pytmake_basejsonrpc s*tTestJSONRPCControllercBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZRS(cOsddlm}m}t}tj|||i|_i|jd<||}|||j}|_t|}t ||_ dS(Ni(tControllerWraptSetupCacheGlobalspylons.routes_dict( tpylons.testutilRRRRR t baseenvirontsapRRtapp(RtargstkwargsRRRR"((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyR <s     cCs@|jddd }tdddddd|ks<tdS( NR R#s hello, worldtjsonrpcs2.0tidttesttresult(s hello, world(tjsonreqtdicttAssertionError(Rtresponse((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyt test_echoHs c CsN|jddd }tdddddid d 6d d 6|ksJtdS(NRR#t1R%s2.0R&R'terroritcodesThat is not an integerR (R.(R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_int_arg_checkNs   c CsH|jd}tdddddidd6d d 6|ksDtdS( NRR%s2.0R&R'R/iR0sInternal errorR (R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_return_garbageUs   c CsH|jd}tdddddidd6d d 6|ksDtdS( NRR%s2.0R&R'R/iR0sMethod not foundR (R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_private_method\s   cCs7|jddd}|jjddks3tdS(NR R#tfoos Content-Typesapplication/json(sfoo(R)R,theaderR+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_content_typecsc CsH|jd}tdddddidd6d d 6|ksDtdS( NR4R%s2.0R&R'R/iR0sMethod not foundR (R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_missing_methodgs   c sJtjtdddddddd }jtjfd dS( NR%s2.0R&R'tmethodR R#R4csjjddtddS(Nt/t extra_environtCONTENT_LENGTHt(R"tpostR*((R(sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pytts(sfoo(tjsontdumpsR*t assertRaisestexctHTTPLengthRequired(Rtdata((RsE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_no_content_lengthns   c sJtjtdddddddd }jtjfd dS( NR%s2.0R&R'R8R R#R4csjjddtddS(NR9R:R;t0(R"R=R*((R(sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyR>}s(sfoo(R?R@R*RARBRC(RRD((RsE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_zero_content_lengthws   cCsF|jddddg}tddddd d|ksBtdS( NRR#iiR%s2.0R&R'R((R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_positional_paramss c CsQ|jdddg}tdddddid d 6d d 6|ksMtdS( NRR#iR%s2.0R&R'R/iR0sInvalid paramsR (R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_missing_positional_params   c CsT|jddddg}tddddd id d 6d d 6|ksPtdS(NRR#R.t2R%s2.0R&R'R/iR0sThat is not an integerR (R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_wrong_param_types   cCsG|jddidd6}tddddd d|ksCtdS( NRR#s hello, worldR R%s2.0R&R'R((R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyt test_v2_echos cCs@|jddi}tdddddd|ks<tdS( NRR#R%s2.0R&R'R(sDefault message(R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_v2_echo_defaults cCsA|jddidd6}tddddd d s=tdS( NRR#iRR%s2.0R&R'R(sgot an integer(R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_v2_int_arg_check_valids cCs:|jddi}tdddddds6tdS( NRR#R%s2.0R&R'R(sgot an integer(R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyt.test_v2_int_arg_check_default_keyword_arguments c CsU|jddidd6}tddddd id d 6d d 6|ksQtdS(NRR#tabcRR%s2.0R&R'R/iR0sThat is not an integerR (R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_v2_int_arg_checks   cCsN|jddidd6dd6}tddd d d d |ksJtdS( NRR#i2RidRR%s2.0R&R'R(i(R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyttest_v2_decrements# cCsG|jddidd6}tddddd d |ksCtdS( NRR#i2RR%s2.0R&R'R(i1(R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyt+test_v2_decrement_default_keywoard_arguments c CsN|jddi}tdddddidd 6d d 6|ksJtdS( NRR#R%s2.0R&R'R/iR0sInvalid paramsR (R)R*R+(RR,((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyt*test_v2_decrement_missing_keyword_arguments   (RRR R-R1R2R3R6R7RERGRHRIRKRLRMRNRORQRRRSRT(((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyR:s(                ( t paste.fixtureRtpaste.registryRt webob.excRBR?R RRR(((sE/Users/ben/Programming/Python/pylons/tests/test_units/test_jsonrpc.pyts   0Pylons-1.0.1/tests/test_units/test_middleware.py0000664000076500000240000000366311671720166021776 0ustar benstaff00000000000000# -*- coding: utf-8 -*- from webtest import TestApp def simple_app(environ, start_response): start_response('200 OK', [('Content-type', 'text/plain')]) return ['Hello world!'] def simple_exception_app(environ, start_response): if environ['PATH_INFO'].startswith('/error/document'): start_response('200 OK', [('Content-type', 'text/plain')]) return ['Made it to the error'] else: start_response('404 Not Found', [('Content-type', 'text/plain')]) return ['No page found!'] def test_plain_wrap(): from pylons.middleware import StatusCodeRedirect app = TestApp(StatusCodeRedirect(simple_app)) res = app.get('/') assert res.status_int == 200 def test_status_intercept(): from pylons.middleware import StatusCodeRedirect app = TestApp(StatusCodeRedirect(simple_exception_app)) res = app.get('/', status=404) assert 'Made it to the error' in res def test_original_path(): from pylons.middleware import StatusCodeRedirect app = TestApp(StatusCodeRedirect(simple_exception_app)) res = app.get('/', status=404) if getattr(res, 'environ', None) is not None: # webob<1.2 assert res.environ['PATH_INFO'] == '/' def test_retains_response(): from pylons.middleware import StatusCodeRedirect app = TestApp(StatusCodeRedirect(simple_exception_app)) res = app.get('/', status=404) if getattr(res, 'environ', None) is not None: # webob<1.2 assert 'pylons.original_response' in res.environ assert 'No page found!' in res.environ['pylons.original_response'].body def test_retains_request(): from pylons.middleware import StatusCodeRedirect app = TestApp(StatusCodeRedirect(simple_exception_app)) res = app.get('/fredrick', status=404) if getattr(res, 'environ', None) is not None: # webob<1.2 assert 'pylons.original_request' in res.environ assert '/fredrick' == res.environ['pylons.original_request'].path_info Pylons-1.0.1/tests/test_units/test_middleware.pyc0000664000076500000240000000610112012306033022106 0ustar benstaff00000000000000 vNc@sSddlmZdZdZdZdZdZdZdZd S( i(tTestAppcCs|ddgdgS(Ns200 OKs Content-types text/plains Hello world!(s Content-types text/plain((tenvirontstart_response((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_middleware.pyt simple_appscCsE|djdr*|dd gdgS|dd gdgSdS( Nt PATH_INFOs/error/documents200 OKs Content-types text/plainsMade it to the errors 404 Not FoundsNo page found!(s Content-types text/plain(s Content-types text/plain(t startswith(RR((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_middleware.pytsimple_exception_apps cCsJddlm}t|t}|jd}|jdksFtdS(Ni(tStatusCodeRedirectt/i(tpylons.middlewareRRRtgett status_inttAssertionError(Rtapptres((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_middleware.pyttest_plain_wrapscCsMddlm}t|t}|jddd}d|ksItdS(Ni(RRtstatusisMade it to the error(R RRRR R (RR R((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_middleware.pyttest_status_interceptscCsoddlm}t|t}|jddd}t|dddk rk|jddksktndS(Ni(RRRiRR( R RRRR tgetattrtNoneRR (RR R((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_middleware.pyttest_original_paths cCsddlm}t|t}|jddd}t|dddk rd|jksdtd|jdj kstndS( Ni(RRRiRspylons.original_responsesNo page found!( R RRRR RRRR tbody(RR R((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_middleware.pyttest_retains_response#s cCsddlm}t|t}|jddd}t|dddk rd|jksdtd|jdj kstndS(Ni(Rs /fredrickRiRspylons.original_request( R RRRR RRRR t path_info(RR R((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_middleware.pyttest_retains_request+s N( twebtestRRRRRRRR(((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_middleware.pyts      Pylons-1.0.1/tests/test_units/test_templating.py0000664000076500000240000000543611645401276022024 0ustar benstaff00000000000000import os import re import sys from beaker.cache import CacheManager from beaker.middleware import SessionMiddleware, CacheMiddleware from mako.lookup import TemplateLookup from nose.tools import raises from paste.fixture import TestApp from paste.registry import RegistryManager from paste.deploy.converters import asbool from routes import Mapper from routes.middleware import RoutesMiddleware from nose.tools import raises from __init__ import test_root def make_app(global_conf, full_stack=True, static_files=True, include_cache_middleware=False, attribsafe=False, **app_conf): import pylons import pylons.configuration as configuration from pylons import url from pylons.decorators import jsonify from pylons.middleware import ErrorHandler, StatusCodeRedirect from pylons.error import handle_mako_error from pylons.wsgiapp import PylonsApp root = os.path.dirname(os.path.abspath(__file__)) paths = dict(root=os.path.join(test_root, 'sample_controllers'), controllers=os.path.join(test_root, 'sample_controllers', 'controllers'), templates=os.path.join(test_root, 'sample_controllers', 'templates')) sys.path.append(test_root) config = configuration.PylonsConfig() config.init_app(global_conf, app_conf, package='sample_controllers', paths=paths) map = Mapper(directory=config['pylons.paths']['controllers']) map.connect('/{controller}/{action}') config['routes.map'] = map class AppGlobals(object): pass config['pylons.app_globals'] = AppGlobals() config['pylons.app_globals'].mako_lookup = TemplateLookup( directories=paths['templates'], imports=['from markupsafe import escape'] ) if attribsafe: config['pylons.strict_tmpl_context'] = False app = PylonsApp(config=config) app = RoutesMiddleware(app, config['routes.map'], singleton=False) if include_cache_middleware: app = CacheMiddleware(app, config) app = SessionMiddleware(app, config) if asbool(full_stack): app = ErrorHandler(app, global_conf, **config['pylons.errorware']) if asbool(config['debug']): app = StatusCodeRedirect(app) else: app = StatusCodeRedirect(app, [401, 403, 404, 500]) app = RegistryManager(app) app.config = config return app class TestTemplatingApp(object): def setUp(self): self.app = TestApp(make_app({'cache_dir': os.path.join(os.path.dirname(__file__), 'cache')}, include_cache_middleware=True)) def test_testvars(self): resp = self.app.get('/hello/intro_template') assert 'Hi there 6' in resp def test_template_cache(self): resp = self.app.get('/hello/time_template') resp2 = self.app.get('/hello/time_template') assert resp.body == resp2.body Pylons-1.0.1/tests/test_units/test_templating.pyc0000664000076500000240000001002612012306033022136 0ustar benstaff00000000000000 Nc@s ddlZddlZddlZddlmZddlmZmZddlm Z ddl m Z ddl m Z ddlmZddlmZdd lmZdd lmZddl m Z dd lmZeeeed Zd efdYZdS(iN(t CacheManager(tSessionMiddlewaretCacheMiddleware(tTemplateLookup(traises(tTestApp(tRegistryManager(tasbool(tMapper(tRoutesMiddleware(t test_rootc Kscddl}ddlj}ddlm}ddlm} ddlm} m} ddl m } ddl m } t jjt jjt}tdt jjtdd t jjtdd d t jjtdd }tjjt|j}|j||d dd |td |dd }|jd||dR'R(R-R)R+tTrueR=(tself((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_templating.pytsetUpEscCs(|jjd}d|ks$tdS(Ns/hello/intro_templates Hi there 6(R=tgettAssertionError(RCtresp((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_templating.pyt test_testvarsHscCs@|jjd}|jjd}|j|jks<tdS(Ns/hello/time_template(R=REtbodyRF(RCRGtresp2((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_templating.pyttest_template_cacheLs(RRRDRHRK(((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_templating.pyR?Ds  (R'treR.t beaker.cacheRtbeaker.middlewareRRt mako.lookupRt nose.toolsRt paste.fixtureRtpaste.registryRtpaste.deploy.convertersRtroutesRtroutes.middlewareR t__init__R RBR5R>R3R?(((sH/Users/ben/Programming/Python/pylons/tests/test_units/test_templating.pyts   0Pylons-1.0.1/tests/test_units/test_xmlrpc.py0000664000076500000240000001377011645401276021165 0ustar benstaff00000000000000# -*- coding: utf-8 -*- from paste.fixture import TestApp from paste.registry import RegistryManager import webob.exc as exc import xmlrpclib from __init__ import TestWSGIController def make_basexmlrpc(): from pylons.controllers import XMLRPCController class BaseXMLRPCController(XMLRPCController): def __init__(self): self._pylons_log_debug = True foo = 'bar' def userstatus(self): return 'basic string' userstatus.signature = [ ['string'] ] def docs(self): "This method has a docstring" return dict(mess='a little somethin', a=1, b=[1,2,3], c=('all','the')) docs.signature = [ ['struct'] ] def uni(self): "This method has a docstring" return dict(mess=u'A unicode string, oh boy') uni.signature = [ ['struct'] ] def intargcheck(self, arg): if not isinstance(arg, int): return xmlrpclib.Fault(0, 'Integer required') else: return "received int" intargcheck.signature = [ ['string', 'int'] ] def nosig(self): return 'not much' def structured_methodname(self, arg): "This method has a docstring" return 'Transform okay' structured_methodname.signature = [ ['string', 'string'] ] def longdoc(self): """This function has multiple lines in it""" return "hi all" def _private(self): return 'private method' return BaseXMLRPCController class TestXMLRPCController(TestWSGIController): def __init__(self, *args, **kargs): from pylons.testutil import ControllerWrap, SetupCacheGlobal BaseXMLRPCController = make_basexmlrpc() TestWSGIController.__init__(self, *args, **kargs) self.baseenviron = {} self.baseenviron['pylons.routes_dict'] = {} app = ControllerWrap(BaseXMLRPCController) app = self.sap = SetupCacheGlobal(app, self.baseenviron) app = RegistryManager(app) self.app = TestApp(app) def test_index(self): response = self.xmlreq('userstatus') assert response == 'basic string' def test_structure(self): response = self.xmlreq('docs') assert dict(mess='a little somethin', a=1, b=[1,2,3], c=['all','the']) == response def test_methodhelp(self): response = self.xmlreq('system.methodHelp', ('docs',)) assert "This method has a docstring" in response def test_methodhelp_with_structured_methodname(self): response = self.xmlreq('system.methodHelp', ('structured.methodname',)) assert "This method has a docstring" in response def test_methodsignature(self): response = self.xmlreq('system.methodSignature', ('docs',)) assert [['struct']] == response def test_methodsignature_with_structured_methodname(self): response = self.xmlreq('system.methodSignature', ('structured.methodname',)) assert [['string', 'string']] == response def test_listmethods(self): response = self.xmlreq('system.listMethods') assert response == ['docs', 'intargcheck', 'longdoc', 'nosig', 'structured.methodname', 'system.listMethods', 'system.methodHelp', 'system.methodSignature', 'uni', 'userstatus'] def test_unicode(self): response = self.xmlreq('uni') assert 'A unicode string' in response['mess'] def test_unicode_method(self): data = xmlrpclib.dumps((), methodname=u'ОбсуждениеКомпаний') self.response = response = self.app.post('/', params=data, extra_environ=dict(CONTENT_TYPE='text/xml')) def test_no_length(self): data = xmlrpclib.dumps((), methodname=u'ОбсуждениеКомпаний') self.assertRaises(exc.HTTPLengthRequired, lambda: self.app.post('/', extra_environ=dict(CONTENT_LENGTH=''))) def test_too_big(self): data = xmlrpclib.dumps((), methodname=u'ОбсуждениеКомпаний') self.assertRaises(exc.HTTPRequestEntityTooLarge, lambda: self.app.post('/', extra_environ=dict(CONTENT_LENGTH='4194314'))) def test_badargs(self): self.assertRaises(xmlrpclib.Fault, self.xmlreq, 'system.methodHelp') def test_badarity(self): self.assertRaises(xmlrpclib.Fault, self.xmlreq, 'system.methodHelp') # Unsure whether this is actually picked up by xmlrpclib, but what the hey def test_bad_paramval(self): self.assertRaises(xmlrpclib.Fault, self.xmlreq, 'intargcheck', (12.5,)) def test_missingmethod(self): self.assertRaises(xmlrpclib.Fault, self.xmlreq, 'doesntexist') def test_nosignature(self): response = self.xmlreq('system.methodSignature', ('nosig',)) assert response == '' def test_nosignature_unicode(self): self.assertRaises(xmlrpclib.Fault, self.xmlreq, 'system.methodSignature', (u'ОбсуждениеКомпаний',)) def test_nodocs(self): response = self.xmlreq('system.methodHelp', ('nosig',)) assert response == '' def test_nodocs_unicode(self): self.assertRaises(xmlrpclib.Fault, self.xmlreq, 'system.methodHelp', (u'ОбсуждениеКомпаний',)) def test_multilinedoc(self): response = self.xmlreq('system.methodHelp', ('longdoc',)) assert 'This function\nhas multiple lines\nin it' in response def test_contenttype(self): response = self.xmlreq('system.methodHelp', ('longdoc',)) assert self.response.header('Content-Type') == 'text/xml' def test_start_response(self): self.assertRaises(xmlrpclib.Fault, self.xmlreq, 'start_response') def test_private_func(self): self.assertRaises(xmlrpclib.Fault, self.xmlreq, '_private') def test_var(self): self.assertRaises(xmlrpclib.Fault, self.xmlreq, 'foo') Pylons-1.0.1/tests/test_units/test_xmlrpc.pyc0000664000076500000240000002652512012306033021312 0ustar benstaff00000000000000 Nc@snddlmZddlmZddljZddlZddlmZdZ defdYZ dS(i(tTestApp(tRegistryManagerN(tTestWSGIControllercCs*ddlm}d|fdY}|S(Ni(tXMLRPCControllertBaseXMLRPCControllercBseZdZdZdZdgge_dZdgge_dZdgge_dZddgge_d Z d Z ddgge _d Z d Z RS( cSs t|_dS(N(tTruet_pylons_log_debug(tself((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt__init__ stbarcSsdS(Ns basic string((R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt userstatusststringc Ss(tddddddddgdd S( sThis method has a docstringtmesssa little somethintaitbiitctalltthe(sallR(tdict(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pytdocsststructcSs tddS(sThis method has a docstringR uA unicode string, oh boy(R(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pytuniscSs't|tstjddSdSdS(NisInteger requireds received int(t isinstancetintt xmlrpclibtFault(Rtarg((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt intargcheck sRcSsdS(Nsnot much((R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pytnosig'scSsdS(sThis method has a docstringsTransform okay((RR((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pytstructured_methodname*scSsdS(s>This function has multiple lines in itshi all((R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pytlongdoc/scSsdS(Nsprivate method((R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt_private5s( t__name__t __module__RtfooR t signatureRRRRRRR(((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyR s        (tpylons.controllersR(RR((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pytmake_basexmlrpc s+tTestXMLRPCControllercBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZRS(cOsddlm}m}t}tj|||i|_i|jd<||}|||j}|_t|}t ||_ dS(Ni(tControllerWraptSetupCacheGlobalspylons.routes_dict( tpylons.testutilR'R(R%RRt baseenvirontsapRRtapp(RtargstkargsR'R(RR,((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyR:s     cCs%|jd}|dks!tdS(NR s basic string(txmlreqtAssertionError(Rtresponse((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt test_indexFsc CsO|jd}tddddddddgd d d g|ksKtdS( NRR sa little somethinR iRiiRRR(R/RR0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_structureJscCs(|jdd}d|ks$tdS(Nssystem.methodHelpRsThis method has a docstring(sdocs(R/R0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_methodhelpNscCs(|jdd}d|ks$tdS(Nssystem.methodHelpsstructured.methodnamesThis method has a docstring(sstructured.methodname(R/R0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt*test_methodhelp_with_structured_methodnameRscCs.|jdd}dgg|ks*tdS(Nssystem.methodSignatureRR(sdocs(R/R0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_methodsignatureVscCs1|jdd}ddgg|ks-tdS(Nssystem.methodSignaturesstructured.methodnameR (sstructured.methodname(R/R0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt/test_methodsignature_with_structured_methodnameZsc CsC|jd}|ddddddddd d g ks?tdS( Nssystem.listMethodsRRRRsstructured.methodnamessystem.methodHelpssystem.methodSignatureRR (R/R0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_listmethods^scCs)|jd}d|dks%tdS(NRsA unicode stringR (R/R0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt test_unicodebscCsGtjddd}|jjdd|dtdd|_}dS( Nt methodnameu$ОбсуждениеКомпанийt/tparamst extra_environt CONTENT_TYPEstext/xml((RtdumpsR,tpostRR1(RtdataR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_unicode_methodfscs5tjddd}jtjfddS(NR:u$ОбсуждениеКомпанийcsjjddtddS(NR;R=tCONTENT_LENGTHt(R,R@R((R(sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pytls((RR?t assertRaisestexctHTTPLengthRequired(RRA((RsD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_no_lengthjscs5tjddd}jtjfddS(NR:u$ОбсуждениеКомпанийcsjjddtddS(NR;R=RCt4194314(R,R@R((R(sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyREps((RR?RFRGtHTTPRequestEntityTooLarge(RRA((RsD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt test_too_bignscCs|jtj|jddS(Nssystem.methodHelp(RFRRR/(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt test_badargsrscCs|jtj|jddS(Nssystem.methodHelp(RFRRR/(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt test_badarityuscCs |jtj|jdddS(NRg)@(g)@(RFRRR/(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_bad_paramvalyscCs|jtj|jddS(Nt doesntexist(RFRRR/(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_missingmethod|scCs(|jdd}|dks$tdS(Nssystem.methodSignatureRRD(snosig(R/R0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_nosignaturescCs |jtj|jdddS(Nssystem.methodSignatureu$ОбсуждениеКомпаний(u$ОбсуждениеКомпаний(RFRRR/(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_nosignature_unicodescCs(|jdd}|dks$tdS(Nssystem.methodHelpRRD(snosig(R/R0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyt test_nodocsscCs |jtj|jdddS(Nssystem.methodHelpu$ОбсуждениеКомпаний(u$ОбсуждениеКомпаний(RFRRR/(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_nodocs_unicodescCs(|jdd}d|ks$tdS(Nssystem.methodHelpRs&This function has multiple lines in it(slongdoc(R/R0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_multilinedocscCs4|jdd}|jjddks0tdS(Nssystem.methodHelpRs Content-Typestext/xml(slongdoc(R/R1theaderR0(RR1((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_contenttypescCs|jtj|jddS(Ntstart_response(RFRRR/(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_start_responsescCs|jtj|jddS(NR(RFRRR/(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_private_funcscCs|jtj|jddS(NR"(RFRRR/(R((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyttest_vars(R R!RR2R3R4R5R6R7R8R9RBRIRLRMRNRORQRRRSRTRURVRXRZR[R\(((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyR&9s2                       ( t paste.fixtureRtpaste.registryRt webob.excRGRRRR%R&(((sD/Users/ben/Programming/Python/pylons/tests/test_units/test_xmlrpc.pyts   /Pylons-1.0.1/tests/test_webapps/0000775000076500000240000000000012012307216016522 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_webapps/__init__.py0000664000076500000240000000000011645401276020635 0ustar benstaff00000000000000Pylons-1.0.1/tests/test_webapps/__init__.pyc0000664000076500000240000000023212012306033020767 0ustar benstaff00000000000000 Nc@sdS(N((((sC/Users/ben/Programming/Python/pylons/tests/test_webapps/__init__.pytsPylons-1.0.1/tests/test_webapps/filestotest/0000775000076500000240000000000012012307216021067 5ustar benstaff00000000000000Pylons-1.0.1/tests/test_webapps/filestotest/app_globals.py0000664000076500000240000000115511645401276023742 0ustar benstaff00000000000000"""The application's Globals object""" from pylons import config from beaker.cache import CacheManager from beaker.util import parse_cache_config_options class Globals(object): """Globals acts as a container for objects available throughout the life of the application """ def __init__(self, config): """One instance of Globals is created during application initialization and is available during requests via the 'app_globals' variable """ self.cache = CacheManager(**parse_cache_config_options(config)) self.message = 'Hello' self.counter = 0 Pylons-1.0.1/tests/test_webapps/filestotest/base_with_xmlrpc.py0000664000076500000240000000162211645401276025010 0ustar benstaff00000000000000from pylons import tmpl_context as c, app_globals, cache, request, session from pylons.controllers import WSGIController, XMLRPCController from pylons.controllers.util import abort, etag_cache, redirect from pylons.decorators import jsonify, validate from pylons.templating import render_mako as render from pylons.i18n import N_, _, ungettext import projectname.model as model import projectname.lib.helpers as h class BaseController(WSGIController): def __call__(self, environ, start_response): # Insert any code to be run per request here. The Routes match # is under environ['pylons.routes_dict'] should you want to check # the action or route vars here return WSGIController.__call__(self, environ, start_response) # Include the '_' function in the public names __all__ = [__name for __name in locals().keys() if not __name.startswith('_') \ or __name == '_'] Pylons-1.0.1/tests/test_webapps/filestotest/cache_controller.py0000775000076500000240000000176611645401276025000 0ustar benstaff00000000000000from pylons import app_globals from pylons.decorators.cache import beaker_cache from projectname.lib.base import BaseController class CacheController(BaseController): @beaker_cache(key=None) def test_default_cache_decorator(self): app_globals.counter += 1 return 'Counter=%s' % app_globals.counter @beaker_cache(key="param", query_args=True) def test_get_cache_decorator(self): app_globals.counter += 1 return 'Counter=%s' % app_globals.counter @beaker_cache(expire=4) def test_expire_cache_decorator(self): app_globals.counter += 1 return 'Counter=%s' % app_globals.counter @beaker_cache(key="id") def test_key_cache_decorator(self, id): app_globals.counter += 1 return 'Counter=%s, id=%s' % (app_globals.counter, id) @beaker_cache(key=["id", "id2"]) def test_keyslist_cache_decorator(self, id, id2="123"): app_globals.counter += 1 return 'Counter=%s, id=%s' % (app_globals.counter, id) Pylons-1.0.1/tests/test_webapps/filestotest/controller_sample.py0000664000076500000240000000520511671746437025215 0ustar benstaff00000000000000import datetime from projectname.lib.base import * import projectname.lib.helpers as h from pylons import request, response, session, url from pylons import tmpl_context as c from pylons import app_globals from pylons.decorators import rest from pylons.i18n import _, get_lang, set_lang, LanguageError from pylons.templating import render_mako, render_genshi, render_jinja2 from pylons.controllers.util import abort, redirect class SampleController(BaseController): def index(self): return 'basic index page' def session_increment(self): session.setdefault('counter', -1) session['counter'] += 1 session.save() return 'session incrementer' def globalup(self): return app_globals.message def global_store(self, id=None): if id: app_globals.counter += int(id) return str(app_globals.counter) def myself(self): return request.url def myparams(self): return str(request.params) def testdefault(self): c.test = "This is in c var" return render_genshi('testgenshi.html') def test_template_caching(self): return render_mako('/test_mako.html', cache_expire='never') @rest.dispatch_on(GET='test_only_get') @rest.restrict('POST') def test_only_post(self): return 'It was a post!' @rest.restrict('GET') def test_only_get(self): return 'It was a get!' @rest.restrict('POST') @rest.dispatch_on(POST='test_only_post') def impossible(self): return 'This should never be shown' def testjinja2(self): c.test = "This is in c var" c.now = datetime.datetime.now return render_jinja2('testjinja2.html') def set_lang(self): return self._set_lang(_) def set_lang_pylonscontext(self, pylons): return self._set_lang(lambda *args: pylons.translator.ugettext(*args)) def _set_lang(self, gettext): lang = request.GET['lang'] try: set_lang(lang) except (LanguageError, IOError), e: resp_unicode = gettext('Could not set language to "%(lang)s"') % {'lang': lang} else: session['lang'] = lang session.save() resp_unicode = gettext('Set language to "%(lang)s"') % {'lang': lang} return resp_unicode def i18n_index(self): locale_list = request.languages set_lang(request.languages) return unicode(_('basic index page')) def no_lang(self): set_lang(None) response.write(_('No language')) set_lang([]) response.write(_('No languages')) return '' Pylons-1.0.1/tests/test_webapps/filestotest/controller_sqlatest.py0000664000076500000240000000345111645401276025563 0ustar benstaff00000000000000import datetime from projectname.lib.base import * try: import sqlalchemy as sa from projectname.model.meta import Session, Base from projectname.model import Foo SQLAtesting = True except: SQLAtesting = False import projectname.lib.helpers as h from pylons import request, response, session from pylons import tmpl_context as c from pylons import app_globals from pylons.decorators import rest from pylons.i18n import _, get_lang, set_lang, LanguageError from pylons.templating import render_mako, render_genshi, render_jinja2 from pylons.controllers.util import abort, redirect class SampleController(BaseController): def index(self): return 'basic index page' def testsqlalchemy(self): if SQLAtesting: c.foos = Session.query(Foo).all() return render_mako('test_sqlalchemy.html') pass def set_lang(self): return self._set_lang(_) def set_lang_pylonscontext(self, pylons): return self._set_lang(lambda *args: pylons.translator.ugettext(*args)) def _set_lang(self, gettext): lang = request.GET['lang'] try: set_lang(lang) except (LanguageError, IOError), e: resp_unicode = gettext('Could not set language to "%(lang)s"') % {'lang': lang} else: session['lang'] = lang session.save() resp_unicode = gettext('Set language to "%(lang)s"') % {'lang': lang} return resp_unicode def i18n_index(self): locale_list = request.languages set_lang(request.languages) return unicode(_('basic index page')) def no_lang(self): set_lang(None) response.write(_('No language')) set_lang([]) response.write(_('No languages')) return '' Pylons-1.0.1/tests/test_webapps/filestotest/controller_xmlrpc.py0000664000076500000240000000105211645401276025223 0ustar benstaff00000000000000from projectname.lib.base import * from pylons.controllers import XMLRPCController class XmlrpcController(XMLRPCController): def userstatus(self): return 'basic string' userstatus.signature = [ ['string'] ] def docs(self): "This method has a docstring" return dict(mess='a little somethin', a=1, b=[1,2,3], c=('all','the')) docs.signature = [ ['struct'] ] def uni(self): "This method has a docstring" return dict(mess=u'A unicode string, oh boy') docs.signature = [ ['struct'] ] Pylons-1.0.1/tests/test_webapps/filestotest/development.ini0000664000076500000240000000304311645401276024126 0ustar benstaff00000000000000[DEFAULT] debug = true email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@exceptions.com [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 [app:main] use = egg:projectname cache_dir = %(here)s/data beaker.session.key = projectname beaker.session.secret = somesecret # If you'd like to fine-tune the individual locations of the cache data dirs # for Myghty, the Cache data, or the Session saves, un-comment the desired # settings here: #beaker.cache_data_dir = %(here)s/data/cache #beaker.session_data_dir = %(here)s/data/sessions # If you are using SQLAlchemy you will need to specify a # dburi. You can do this with a line similar to the # one below but adjusted for your database connection # according to the SQLAlchemy documentation. The %(here)s # part is replaced with the current directory which is # useful when using sqlite on UNIX based platforms. # For Windows you should look at the SQLAlchemy # documentation for a special syntax to use because the # path returned by %(here)s contains a : character. # SQLAlchemy database URL #sqlalchemy.url = sqlite:///%(here)s/development.db # Do not set debug to true or uncomment the line below # on a production environment otherwise in the event of # an error occurring the visitor will be presented with # interactive debugging tools and these could be used to # execute malicious code. # For development purposes debug should be set to true # to enable the debugging code but be sure to set it back # to false before releasing your application. #set debug = false Pylons-1.0.1/tests/test_webapps/filestotest/development_sqlatesting.ini0000664000076500000240000000307211645401276026546 0ustar benstaff00000000000000[DEFAULT] debug = true email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@exceptions.com [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 [app:main] use = egg:projectname cache_dir = %(here)s/data beaker.session.key = projectname beaker.session.secret = somesecret # If you'd like to fine-tune the individual locations of the cache data dirs # for Myghty, the Cache data, or the Session saves, un-comment the desired # settings here: #beaker.cache_data_dir = %(here)s/data/cache #beaker.session_data_dir = %(here)s/data/sessions # If you are using SQLAlchemy you will need to specify a # dburi. You can do this with a line similar to the # one below but adjusted for your database connection # according to the SQLAlchemy documentation. The %(here)s # part is replaced with the current directory which is # useful when using sqlite on UNIX based platforms. # For Windows you should look at the SQLAlchemy # documentation for a special syntax to use because the # path returned by %(here)s contains a : character. # SQLAlchemy database URL sqlalchemy.url = sqlite:///%(here)s/development.db sqlalchemy.echo = True # Do not set debug to true or uncomment the line below # on a production environment otherwise in the event of # an error occurring the visitor will be presented with # interactive debugging tools and these could be used to # execute malicious code. # For development purposes debug should be set to true # to enable the debugging code but be sure to set it back # to false before releasing your application. #set debug = false Pylons-1.0.1/tests/test_webapps/filestotest/environment_def_engine.py0000664000076500000240000000420211645401276026162 0ustar benstaff00000000000000"""Pylons environment configuration""" import os from mako.lookup import TemplateLookup from genshi.template import TemplateLoader from jinja2 import ChoiceLoader, Environment, FileSystemLoader from pylons.configuration import PylonsConfig from pylons.error import handle_mako_error import projectname.lib.app_globals as app_globals import projectname.lib.helpers from projectname.config.routing import make_map def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object """ config = PylonsConfig() # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='projectname', paths=paths) config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) config['pylons.h'] = projectname.lib.helpers # Setup cache object as early as possible import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) # Create the Mako TemplateLookup, with the default auto-escaping config['pylons.app_globals'].mako_lookup = TemplateLookup( directories=paths['templates'], error_handler=handle_mako_error, module_directory=os.path.join(app_conf['cache_dir'], 'templates'), input_encoding='utf-8', default_filters=['escape'], imports=['from webhelpers.html import escape']) # Create the Genshi TemplateLoader config['pylons.app_globals'].genshi_loader = TemplateLoader( paths['templates'], auto_reload=True) # Create the Jinja2 Environment config['pylons.app_globals'].jinja2_env = Environment(loader=ChoiceLoader( [FileSystemLoader(path) for path in paths['templates']])) # CONFIGURATION OPTIONS HERE (note: all config options will override # any Pylons config options) return config Pylons-1.0.1/tests/test_webapps/filestotest/environment_def_sqlamodel.py0000664000076500000240000000444511645401276026707 0ustar benstaff00000000000000"""Pylons environment configuration""" import os from mako.lookup import TemplateLookup from genshi.template import TemplateLoader from jinja2 import ChoiceLoader, Environment, FileSystemLoader from pylons.configuration import PylonsConfig from pylons.error import handle_mako_error from sqlalchemy import engine_from_config import projectname.lib.app_globals as app_globals import projectname.lib.helpers from projectname.config.routing import make_map from projectname.model import init_model def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object """ config = PylonsConfig() # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='projectname', paths=paths) config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) config['pylons.h'] = projectname.lib.helpers # Setup cache object as early as possible import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) # Create the Mako TemplateLookup, with the default auto-escaping config['pylons.app_globals'].mako_lookup = TemplateLookup( directories=paths['templates'], error_handler=handle_mako_error, module_directory=os.path.join(app_conf['cache_dir'], 'templates'), input_encoding='utf-8', default_filters=['escape'], imports=['from webhelpers.html import escape']) # Create the Genshi TemplateLoader config['pylons.app_globals'].genshi_loader = TemplateLoader( paths['templates'], auto_reload=True) # Create the Jinja2 Environment config['pylons.app_globals'].jinja2_env = Environment(loader=ChoiceLoader( [FileSystemLoader(path) for path in paths['templates']])) # CONFIGURATION OPTIONS HERE (note: all config options will override # any Pylons config options) engine = engine_from_config(config, 'sqlalchemy.') init_model(engine) return config Pylons-1.0.1/tests/test_webapps/filestotest/functional_controller_cache_decorator.py0000775000076500000240000000352211645401276031254 0ustar benstaff00000000000000import time from projectname.tests import * class TestCacheController(TestController): def test_default_cache_decorator(self): response = self.app.get(url(controller='cache', action='test_default_cache_decorator')) assert 'Counter=1' in response response = self.app.get(url(controller='cache', action='test_default_cache_decorator')) assert 'Counter=1' in response response = self.app.get(url(controller='cache', action='test_get_cache_decorator', param="123")) assert 'Counter=2' in response response = self.app.get(url(controller='cache', action='test_get_cache_decorator', param="123")) assert 'Counter=2' in response response = self.app.get(url(controller='cache', action='test_expire_cache_decorator')) assert 'Counter=3' in response response = self.app.get(url(controller='cache', action='test_expire_cache_decorator')) assert 'Counter=3' in response time.sleep(8) response = self.app.get(url(controller='cache', action='test_expire_cache_decorator')) assert 'Counter=4' in response response = self.app.get(url(controller='cache', action='test_key_cache_decorator', id=1)) assert 'Counter=5' in response response = self.app.get(url(controller='cache', action='test_key_cache_decorator', id=2)) assert 'Counter=6' in response response = self.app.get(url(controller='cache', action='test_key_cache_decorator', id=1)) assert 'Counter=5' in response response = self.app.get(url(controller='cache', action='test_keyslist_cache_decorator', id=1, id2=2)) assert 'Counter=7' in response response = self.app.get(url(controller='cache', action='test_keyslist_cache_decorator', id=1, id2=2)) assert 'Counter=7' in response Pylons-1.0.1/tests/test_webapps/filestotest/functional_controller_xmlrpc.py0000664000076500000240000000265611645401276027460 0ustar benstaff00000000000000from projectname.tests import * from xmlrpclib import loads, dumps class TestXmlrpcController(TestController): xmlurl = None def xmlreq(self, method, args=None): if args is None: args = () ee = dict(CONTENT_TYPE='text/xml') data = dumps(args, methodname=method) response = self.app.post(self.xmlurl, params = data, extra_environ=ee) return loads(response.body)[0][0] def setUp(self): self.xmlurl = url(controller='xmlrpc', action='index') def test_index(self): response = self.xmlreq('userstatus') assert response == 'basic string' def test_structure(self): response = self.xmlreq('docs') assert dict(mess='a little somethin', a=1, b=[1,2,3], c=['all','the']) == response def test_methodhelp(self): response = self.xmlreq('system.methodHelp', ('docs',)) assert "This method has a docstring" in response def test_methodsignature(self): response = self.xmlreq('system.methodSignature', ('docs',)) assert [['struct']] == response def test_listmethods(self): response = self.xmlreq('system.listMethods') assert response == ['docs', 'system.listMethods', 'system.methodHelp', 'system.methodSignature', 'uni', 'userstatus'] def test_unicode(self): response = self.xmlreq('uni') assert 'A unicode string' in response['mess']Pylons-1.0.1/tests/test_webapps/filestotest/functional_sample_controller_i18n.py0000664000076500000240000000224311645401276030263 0ustar benstaff00000000000000from projectname.tests import * class TestSampleController(TestController): def test_set_lang(self): self._test_set_lang('set_lang') def test_set_lang_pylonscontext(self): self._test_set_lang('set_lang_pylonscontext') def _test_set_lang(self, action): response = self.app.get(url(controller='sample', action=action, lang='ja')) assert u'\u8a00\u8a9e\u8a2d\u5b9a\u3092\u300cja\u300d\u306b\u5909\u66f4\u3057\u307e\u3057\u305f'.encode('utf-8') in response response = self.app.get(url(controller='sample', action=action, lang='fr')) assert 'Could not set language to "fr"' in response def test_detect_lang(self): response = self.app.get(url(controller='sample', action='i18n_index'), headers={ 'Accept-Language':'fr;q=0.6, en;q=0.1, ja;q=0.3'}) # expect japanese fallback for nonexistent french. assert u'\u6839\u672c\u30a4\u30f3\u30c7\u30af\u30b9\u30da\u30fc\u30b8'.encode('utf-8') in response def test_no_lang(self): response = self.app.get(url(controller='sample', action='no_lang')) assert 'No language' in response assert 'No languages' in response Pylons-1.0.1/tests/test_webapps/filestotest/functional_sample_controller_jinja2.py0000775000076500000240000000042411645401276030663 0ustar benstaff00000000000000from projectname.tests import * class TestJinja2Controller(TestController): def test_jinja2(self): response = self.app.get(url(controller='sample', action='testjinja2')) assert 'Hello from Jinja2' in response assert 'This is in c var' in response Pylons-1.0.1/tests/test_webapps/filestotest/functional_sample_controller_mako.py0000664000076500000240000000033711645401276030435 0ustar benstaff00000000000000from projectname.tests import * class TestMakoController(TestController): def test_mako(self): response = self.app.get(url(controller='sample', action='testmako')) assert 'Hello, 5+5 is 10' in response Pylons-1.0.1/tests/test_webapps/filestotest/functional_sample_controller_sample1.py0000664000076500000240000000412511645401276031047 0ustar benstaff00000000000000import pylons from projectname.tests import * class TestSampleController(TestController): def test_conf_with_app_globals(self): assert 'pylons.app_globals' in pylons.config assert hasattr(pylons.app_globals, 'cache') def test_root_index(self): response = self.app.get('/') assert 'Welcome' in response # Test response... def test_index(self): response = self.app.get(url(controller='sample', action='index')) assert 'basic index page' in response def test_session(self): response = self.app.get(url(controller='sample', action='session_increment')) assert response.session.has_key('counter') assert response.session['counter'] == 0 response = self.app.get(url(controller='sample', action='session_increment')) assert response.session['counter'] == 1 assert 'session incrementer' in response def test_global(self): response = self.app.get(url(controller='sample', action='globalup')) assert 'Hello' in response def test_global_persistence(self): response = self.app.get(url(controller='sample', action='global_store')) assert '0' in response response = self.app.get(url(controller='sample', action='global_store', id=2)) assert '2' in response response = self.app.get(url(controller='sample', action='global_store')) assert '2' in response response = self.app.get(url(controller='sample', action='global_store', id=3)) assert '5' in response response = self.app.get(url(controller='sample', action='global_store')) assert '5' in response def test_helper_urlfor(self): response = self.app.get(url(controller='sample', action='myself')) assert 'sample/myself' in response def test_params(self): response = self.app.get(url(controller='sample', action='myparams', extra='something', data=4)) assert 'extra' in response assert 'something' in response assert 'data' in response Pylons-1.0.1/tests/test_webapps/filestotest/functional_sample_controller_sample2.py0000664000076500000240000000142311645401276031046 0ustar benstaff00000000000000from projectname.tests import * class TestSample2Controller(TestController): def test_session(self): response = self.app.get(url(controller='sample', action='session_increment')) assert response.session.has_key('counter') assert response.session['counter'] == 0 response = self.app.get(url(controller='sample', action='session_increment')) assert response.session['counter'] == 1 assert 'session incrementer' in response def test_genshi_default(self): self._test_genshi_default('testdefault') def _test_genshi_default(self, action): response = self.app.get(url(controller='sample', action=action)) assert 'Hello from Genshi' in response assert 'This is in c var' in response Pylons-1.0.1/tests/test_webapps/filestotest/functional_sample_controller_sample3.py0000664000076500000240000000122011645401276031042 0ustar benstaff00000000000000from projectname.tests import * class TestSample2Controller(TestController): def test_session(self): response = self.app.get(url(controller='sample', action='session_increment')) assert response.session.has_key('counter') assert response.session['counter'] == 0 response = self.app.get(url(controller='sample', action='session_increment')) assert response.session['counter'] == 1 assert 'session incrementer' in response def test_default(self): response = self.app.get(url(controller='sample', action='test_template_caching')) assert 'Hi everyone!' in response Pylons-1.0.1/tests/test_webapps/filestotest/functional_sample_controller_sample4.py0000664000076500000240000000133011645401276031045 0ustar benstaff00000000000000from projectname.tests import * class TestSample2Controller(TestController): def test_get(self): response = self.app.get(url(controller='sample', action='test_only_get')) assert 'It was a get' in response def test_redir_get(self): response = self.app.get(url(controller='sample', action='test_only_post')) assert 'It was a get' in response def test_post(self): response = self.app.post(url(controller='sample', action='test_only_post'), params={'id':4}) assert 'It was a post' in response def test_head(self): response = self.app._gen_request('HEAD', url(controller='sample', action='index')) assert '' == response.body Pylons-1.0.1/tests/test_webapps/filestotest/functional_sample_controller_sqlatesting.py0000664000076500000240000000165111645404775032053 0ustar benstaff00000000000000from projectname.tests import * try: from sqlalchemy.exceptions import IntegrityError except ImportError: from sqlalchemy.exc import IntegrityError from projectname.model.meta import Session, Base from projectname.model import Foo class TestSQLAlchemyController(TestController): def setUp(self): Base.metadata.create_all(bind=Session.bind) f = Foo(id = 1, bar = u"Wabbit") Session.add(f) Session.commit() assert f.bar == u"Wabbit" def tearDown(self): Base.metadata.drop_all(bind=Session.bind) def test_sqlalchemy(self): response = self.app.get(url(controller='sample', action='testsqlalchemy')) assert 'foos = [Foo:1]' in response # def test_exception(self): # me = Foo(id=3, bar='giuseppe') # me_again = Foo(id=3, bar='giuseppe') # self.assertRaises(IntegrityError, Session.commit) # Session.rollback() Pylons-1.0.1/tests/test_webapps/filestotest/helpers_sample.py0000664000076500000240000000024211645401276024456 0ustar benstaff00000000000000"""Helper functions Consists of functions to typically be used within templates, but also available to Controllers. This module is available to both as 'h'. """ Pylons-1.0.1/tests/test_webapps/filestotest/messages.ja.mo0000664000076500000240000000120011645401276023631 0ustar benstaff00000000000000<\p$q552.aCould not set language to "%(lang)s"Set language to "%(lang)s"basic index pageProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2007-02-05 12:36+0900 PO-Revision-Date: 2007-02-05 13:06+0900 Last-Translator: FULL NAME Language-Team: LANGUAGE MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit 「%(lang)s」に言語設定が変更できません言語設定を「%(lang)s」に変更しました根本インデクスページPylons-1.0.1/tests/test_webapps/filestotest/messages.ja.po0000664000076500000240000000167111645401276023650 0ustar benstaff00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2007-02-05 12:36+0900\n" "PO-Revision-Date: 2007-02-05 13:06+0900\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: controller_sample.py:7 msgid "basic index page" msgstr "根本インデクスページ" #: controller_sample.py:59 #, python-format msgid "Could not set language to \"%(lang)s\"" msgstr "「%(lang)s」に言語設定が変更できません" #: controller_sample.py:63 #, python-format msgid "Set language to \"%(lang)s\"" msgstr "言語設定を「%(lang)s」に変更しました"Pylons-1.0.1/tests/test_webapps/filestotest/messages.pot0000664000076500000240000000146711645401276023446 0ustar benstaff00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2007-02-05 12:36+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: controller_sample.py:7 msgid "basic index page" msgstr "" #: controller_sample.py:59 #, python-format msgid "Could not set language to \"%(lang)s\"" msgstr "" #: controller_sample.py:63 #, python-format msgid "Set language to \"%(lang)s\"" msgstr "" Pylons-1.0.1/tests/test_webapps/filestotest/middleware_mako.py0000664000076500000240000000456111645401276024607 0ustar benstaff00000000000000"""Pylons middleware initialization""" from beaker.middleware import SessionMiddleware from paste.cascade import Cascade from paste.registry import RegistryManager from paste.urlparser import StaticURLParser from paste.deploy.converters import asbool from pylons.middleware import ErrorHandler, StatusCodeRedirect from pylons.wsgiapp import PylonsApp from routes.middleware import RoutesMiddleware from projectname.config.environment import load_environment def make_app(global_conf, full_stack=True, static_files=True, **app_conf): """Create a Pylons WSGI application and return it ``global_conf`` The inherited configuration for this application. Normally from the [DEFAULT] section of the Paste ini file. ``full_stack`` Whether this application provides a full WSGI stack (by default, meaning it handles its own exceptions and errors). Disable full_stack when this application is "managed" by another WSGI middleware. ``static_files`` Whether this application serves its own static files; disable when another web server is responsible for serving them. ``app_conf`` The application's local configuration. Normally specified in the [app:] section of the Paste ini file (where defaults to main). """ # Configure the Pylons environment config = load_environment(global_conf, app_conf) # The Pylons WSGI app app = PylonsApp(config=config) # Routing/Session/Cache Middleware app = RoutesMiddleware(app, config['routes.map'], singleton=False) app = SessionMiddleware(app, config) # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) if asbool(full_stack): # Handle Python exceptions app = ErrorHandler(app, global_conf, **config['pylons.errorware']) # Display error documents for 401, 403, 404 status codes (and # 500 when debug is disabled) if asbool(config['debug']): app = StatusCodeRedirect(app) else: app = StatusCodeRedirect(app, [400, 401, 403, 404, 500]) # Establish the Registry for this application app = RegistryManager(app) if asbool(static_files): # Serve static files static_app = StaticURLParser(config['pylons.paths']['static_files']) app = Cascade([static_app, app]) app.config = config return app Pylons-1.0.1/tests/test_webapps/filestotest/model__init__.py0000664000076500000240000000071711645401276024242 0ustar benstaff00000000000000"""The application's model objects""" from sqlalchemy import types, Column from projectname.model.meta import Base, Session def init_model(engine): """Call me before using any of the tables or classes in the model""" Session.configure(bind=engine) class Foo(Base): __tablename__ = 'foo' id = Column(types.Integer, primary_key=True) bar = Column(types.String(255), nullable=False) def __repr__(self): return "Foo:%s" % self.id Pylons-1.0.1/tests/test_webapps/filestotest/rest_routing.py0000664000076500000240000000206711645401276024206 0ustar benstaff00000000000000"""Routes configuration The more specific and detailed routes should be defined first so they may take precedent over the more generic routes. For more information refer to the routes manual at http://routes.groovie.org/docs/ """ from routes import Mapper def make_map(config): """Create, configure and return the routes Mapper""" map = Mapper(directory=config['pylons.paths']['controllers'], always_scan=config['debug']) map.minimization = False map.explicit = False # The ErrorController route (handles 404/500 error pages); it should # likely stay at the top, ensuring it can always be resolved map.connect('/error/{action}', controller='error') map.connect('/error/{action}/{id}', controller='error') # CUSTOM ROUTES HERE map.resource('restsample', 'restsamples') map.resource('restsample', 'restsamples', controller='mysubdir/restsamples', path_prefix='/mysubdir', name_prefix='mysubdir_') map.connect('/{controller}/{action}') map.connect('/{controller}/{action}/{id}') return map Pylons-1.0.1/tests/test_webapps/filestotest/test_mako.html0000664000076500000240000000014111645401276023753 0ustar benstaff00000000000000<% from datetime import datetime mytime = datetime.now() %> Hi everyone! The time is ${mytime} Pylons-1.0.1/tests/test_webapps/filestotest/test_sqlalchemy.html0000664000076500000240000000002111645401276025163 0ustar benstaff00000000000000foos = ${c.foos} Pylons-1.0.1/tests/test_webapps/filestotest/testgenshi.html0000664000076500000240000000057411645401276024154 0ustar benstaff00000000000000 Hello from Genshi

Hello from Genshi

You visited the URL ${request.url} at ${datetime.datetime.now()}

${c.test}

Pylons-1.0.1/tests/test_webapps/filestotest/testjinja2.html0000664000076500000240000000043411645401276024047 0ustar benstaff00000000000000#import datetime Hello from Jinja2

Hello from Jinja2

You visited the URL {{ request.url }} at {{ c.now() }}

{{ c.test }}

Pylons-1.0.1/tests/test_webapps/filestotest/tests__init__.py0000664000076500000240000000377011645401276024306 0ustar benstaff00000000000000"""Pylons application test package This package assumes the Pylons environment is already loaded, such as when this script is imported from the `nosetests --with-pylons=test.ini` command. This module initializes the application via ``websetup`` (`paster setup-app`) and provides the base testing objects. """ from unittest import TestCase from paste.deploy import loadapp from paste.script.appinstall import SetupCommand from pylons import url from routes.util import URLGenerator from webtest import TestApp import pylons.test __all__ = ['environ', 'url', 'TestController'] try: from sqlalchemy import engine_from_config from projectname.model.meta import Session, Base from projectname.model import Foo, init_model SQLAtesting = True except: SQLAtesting = False import os import pylons from pylons.i18n.translation import _get_translator from paste.deploy import appconfig from projectname.config.environment import load_environment here_dir = os.path.dirname(__file__) conf_dir = os.path.dirname(os.path.dirname(here_dir)) test_file = os.path.join(conf_dir, 'test.ini') conf = appconfig('config:' + test_file) config = load_environment(conf.global_conf, conf.local_conf) if SQLAtesting: engine = engine_from_config(config, 'sqlalchemy.') init_model(engine) # Invoke websetup with the current config file SetupCommand('setup-app').run([test_file]) environ = {} class TestController(TestCase): def __init__(self, *args, **kwargs): wsgiapp = loadapp('config:test.ini', relative_to=conf_dir) config = wsgiapp.config pylons.app_globals._push_object(config['pylons.app_globals']) pylons.config._push_object(config) # Initialize a translator for tests that utilize i18n translator = _get_translator(pylons.config.get('lang')) pylons.translator._push_object(translator) url._push_object(URLGenerator(config['routes.map'], environ)) self.app = TestApp(wsgiapp) TestCase.__init__(self, *args, **kwargs) Pylons-1.0.1/tests/test_webapps/filestotest/websetup.py0000664000076500000240000000105111645401276023310 0ustar benstaff00000000000000"""Setup the projectname application""" import logging import pylons.test from projectname.config.environment import load_environment from projectname.model.meta import Session, Base from projectname.model import Foo from sqlalchemy import engine_from_config log = logging.getLogger(__name__) def setup_app(command, conf, vars): """Place any commands to setup projectname here""" config = load_environment(conf.global_conf, conf.local_conf) # Create the tables if they don't already exist Base.metadata.create_all(bind=Session.bind) Pylons-1.0.1/tests/test_webapps/test_make_project.py0000664000076500000240000003504311645404275022621 0ustar benstaff00000000000000"""Tests against full Pylons projects created from scratch""" import os import sys import shutil import re import pkg_resources from nose import SkipTest from paste.fixture import TestFileEnvironment if os.environ.get('SKIP_INTEGRATED', 'False') != '0': raise SkipTest() import pylons import pylons.test try: import sqlalchemy as sa SQLAtesting = True except ImportError: SQLAtesting = False # SQLAtesting = False is_jython = sys.platform.startswith('java') TEST_OUTPUT_DIRNAME = 'output' for spec in ['PasteScript', 'Paste', 'PasteDeploy', 'pylons']: pkg_resources.require(spec) template_path = os.path.join( os.path.dirname(__file__), 'filestotest').replace('\\','/') test_environ = os.environ.copy() test_environ['PASTE_TESTING'] = 'true' testenv = TestFileEnvironment( os.path.join(os.path.dirname(__file__), TEST_OUTPUT_DIRNAME).replace('\\','/'), template_path=template_path, environ=test_environ) projenv = None def _get_script_name(script): if sys.platform == 'win32' and not script.lower().endswith('.exe'): script += '.exe' return script def svn_repos_setup(): res = testenv.run(_get_script_name('svnadmin'), 'create', 'REPOS', printresult=False) path = testenv.base_path.replace('\\','/').replace(' ','%20') base = 'file://' if ':' in path: base = 'file:///' testenv.svn_url = base + path + '/REPOS' assert 'REPOS' in res.files_created testenv.ignore_paths.append('REPOS') def paster_create(template_engine='mako', overwrite=False, sqlatesting=False): global projenv paster_args = ['create', '--verbose', '--no-interactive'] if overwrite: paster_args.append('-f') paster_args.extend(['--template=pylons', 'ProjectName', 'version=0.1', 'sqlalchemy=%s' % sqlatesting, 'zip_safe=False', 'template_engine=%s' % template_engine]) res = testenv.run(_get_script_name('paster'), *paster_args) expect_fn = ['projectname', 'development.ini', 'setup.cfg', 'README.txt', 'setup.py'] for fn in expect_fn: fn = os.path.join('ProjectName', fn) if not overwrite: assert fn in res.files_created.keys() assert fn in res.stdout if not overwrite: setup = res.files_created[os.path.join('ProjectName','setup.py')] setup.mustcontain('0.1') setup.mustcontain('projectname.config.middleware:make_app') setup.mustcontain('main = pylons.util:PylonsInstaller') setup.mustcontain("include_package_data=True") assert '0.1' in setup testenv.run(_get_script_name(sys.executable)+' setup.py egg_info', cwd=os.path.join(testenv.cwd, 'ProjectName').replace('\\','/'), expect_stderr=True) #testenv.run(_get_script_name('svn'), 'commit', '-m', 'Created project', 'ProjectName') # A new environment with a new projenv = TestFileEnvironment( os.path.join(testenv.base_path, 'ProjectName').replace('\\','/'), start_clear=False, template_path=template_path, environ=test_environ) projenv.environ['PYTHONPATH'] = ( projenv.environ.get('PYTHONPATH', '') + ':' + projenv.base_path) def make_controller(): res = projenv.run(_get_script_name('paster')+' controller sample') assert os.path.join('projectname','controllers','sample.py') in res.files_created assert os.path.join('projectname','tests','functional','test_sample.py') in res.files_created #res = projenv.run(_get_script_name('svn')+' status') # Make sure all files are added to the repository: assert '?' not in res.stdout def make_controller_subdirectory(): res = projenv.run(_get_script_name('paster')+' controller mysubdir/sample') assert os.path.join('projectname','controllers', 'mysubdir', 'sample.py') in res.files_created assert os.path.join('projectname','tests','functional','test_mysubdir_sample.py') in res.files_created #res = projenv.run(_get_script_name('svn')+' status') # Make sure all files are added to the repository: assert '?' not in res.stdout def make_restcontroller(): res = projenv.run(_get_script_name('paster')+' restcontroller restsample restsamples') assert os.path.join('projectname','controllers','restsamples.py') in res.files_created assert os.path.join('projectname','tests','functional','test_restsamples.py') in res.files_created #res = projenv.run(_get_script_name('svn')+' status') # Make sure all files are added to the repository: assert '?' not in res.stdout def make_restcontroller_subdirectory(): res = projenv.run(_get_script_name('paster')+' restcontroller mysubdir/restsample mysubdir/restsamples') assert os.path.join('projectname','controllers','mysubdir', 'restsamples.py') in res.files_created assert os.path.join('projectname','tests','functional','test_mysubdir_restsamples.py') in res.files_created #res = projenv.run(_get_script_name('svn')+' status') # Make sure all files are added to the repository: assert '?' not in res.stdout def _do_proj_test(copydict, emptyfiles=None, match_routes_output=None): """Given a dict of files, where the key is a filename in filestotest, the value is the destination in the new projects dir. emptyfiles is a list of files that should be created and empty.""" if pylons.test.pylonsapp: pylons.test.pylonsapp = None if not emptyfiles: emptyfiles = [] for original, newfile in copydict.iteritems(): projenv.writefile(newfile, frompath=original) for fi in emptyfiles: projenv.writefile(fi) # here_dir = os.getcwd() # test_dir = os.path.join(testenv.cwd, 'ProjectName').replace('\\','/') # os.chdir(test_dir) # sys.path.append(test_dir) # nose.run(argv=['nosetests', '-d', test_dir]) # # sys.path.pop(-1) # os.chdir(here_dir) res = projenv.run(_get_script_name('nosetests')+' -d', expect_stderr=True, cwd=os.path.join(testenv.cwd, 'ProjectName').replace('\\','/')) if match_routes_output: res = projenv.run(_get_script_name('paster')+' routes', expect_stderr=False, cwd=os.path.join(testenv.cwd, 'ProjectName').replace('\\','/')) for pattern in match_routes_output: assert re.compile(pattern).search(res.stdout) def do_nosetests(): _do_proj_test({'development.ini':'development.ini'}) def do_knowntest(): copydict = { 'helpers_sample.py':'projectname/lib/helpers.py', 'controller_sample.py':'projectname/controllers/sample.py', 'app_globals.py':'projectname/lib/app_globals.py', 'functional_sample_controller_sample1.py':'projectname/tests/functional/test_sample.py', } _do_proj_test(copydict) def do_i18ntest(): copydict = { 'functional_sample_controller_i18n.py':'projectname/tests/functional/test_i18n.py', 'messages.ja.po':'projectname/i18n/ja/LC_MESSAGES/projectname.po', 'messages.ja.mo':'projectname/i18n/ja/LC_MESSAGES/projectname.mo', } _do_proj_test(copydict) def do_genshi(): paster_create(template_engine='genshi', overwrite=True) reset = { 'helpers_sample.py':'projectname/lib/helpers.py', 'app_globals.py':'projectname/lib/app_globals.py', 'rest_routing.py':'projectname/config/routing.py', 'development.ini':'development.ini', } copydict = { 'testgenshi.html':'projectname/templates/testgenshi.html', 'environment_def_engine.py':'projectname/config/environment.py', 'functional_sample_controller_sample2.py':'projectname/tests/functional/test_sample2.py' } copydict.update(reset) empty = ['projectname/templates/__init__.py', 'projectname/tests/functional/test_cache.py'] _do_proj_test(copydict, empty) def do_two_engines(): copydict = { 'middleware_two_engines.py':'projectname/config/middleware.py', 'test_mako.html':'projectname/templates/test_mako.html', 'functional_sample_controller_sample3.py':'projectname/tests/functional/test_sample2.py', } _do_proj_test(copydict) def do_crazy_decorators(): _do_proj_test({'functional_sample_controller_sample4.py':'projectname/tests/functional/test_sample3.py'}) def do_jinja2(): paster_create(template_engine='jinja2', overwrite=True) reset = { 'helpers_sample.py':'projectname/lib/helpers.py', 'app_globals.py':'projectname/lib/app_globals.py', 'rest_routing.py':'projectname/config/routing.py', 'development.ini':'development.ini', } copydict = { 'controller_sample.py':'projectname/controllers/sample.py', 'testjinja2.html':'projectname/templates/testjinja2.html', 'environment_def_engine.py':'projectname/config/environment.py', 'functional_sample_controller_jinja2.py':'projectname/tests/functional/test_jinja2.py', } copydict.update(reset) empty = [ 'projectname/templates/__init__.py', 'projectname/tests/functional/test_sample.py', 'projectname/tests/functional/test_sample2.py', 'projectname/tests/functional/test_sample3.py', 'projectname/tests/functional/test_cache.py' ] _do_proj_test(copydict, empty) def do_cache_decorator(): copydict = { 'middleware_mako.py':'projectname/config/middleware.py', 'app_globals.py':'projectname/lib/app_globals.py', 'cache_controller.py':'projectname/controllers/cache.py', 'functional_controller_cache_decorator.py':'projectname/tests/functional/test_cache.py', } empty = [ 'projectname/tests/functional/test_mako.py', 'projectname/tests/functional/test_jinja2.py', 'projectname/tests/functional/test_sample.py', 'projectname/tests/functional/test_sample2.py', 'projectname/tests/functional/test_sample3.py' ] _do_proj_test(copydict, empty) def do_xmlrpc(): copydict = { 'middleware_mako.py':'projectname/config/middleware.py', 'base_with_xmlrpc.py':'projectname/lib/base.py', 'controller_xmlrpc.py':'projectname/controllers/xmlrpc.py', 'functional_controller_xmlrpc.py':'projectname/tests/functional/test_xmlrpc.py' } empty = [ 'projectname/tests/functional/test_cache.py', 'projectname/tests/functional/test_jinja2.py', ] _do_proj_test(copydict, empty) def make_tag(): global tagenv #res = projenv.run(_get_script_name('svn')+' commit -m "updates"') # Space at the end needed so run() doesn't add \n causing svntag to complain #res = projenv.run(_get_script_name(sys.executable)+' setup.py svntag --version=0.5 ') # XXX Still fails => setuptools problem on win32? assert 'Tagging 0.5 version' in res.stdout assert 'Auto-update of version strings' in res.stdout res = testenv.run(_get_script_name('svn')+' co %s/ProjectName/tags/0.5 Proj-05 ' % testenv.svn_url) setup = res.files_created['Proj-05/setup.py'] setup.mustcontain('0.5') assert 'Proj-05/setup.cfg' not in res.files_created tagenv = TestFileEnvironment( os.path.join(testenv.base_path, 'Proj-05').replace('\\','/'), start_clear=False, template_path=template_path) def do_sqlaproject(): paster_create(template_engine='mako', overwrite=True, sqlatesting=True) reset = { 'helpers_sample.py':'projectname/lib/helpers.py', 'app_globals.py':'projectname/lib/app_globals.py', 'rest_routing.py':'projectname/config/routing.py', 'development_sqlatesting.ini':'development.ini', 'websetup.py':'projectname/websetup.py', 'model__init__.py':'projectname/model/__init__.py', 'environment_def_sqlamodel.py':'projectname/config/environment.py', 'tests__init__.py':'projectname/tests/__init__.py', } copydict = { 'controller_sqlatest.py':'projectname/controllers/sample.py', 'test_mako.html':'projectname/templates/test_mako.html', 'test_sqlalchemy.html':'projectname/templates/test_sqlalchemy.html', 'functional_sample_controller_sqlatesting.py':'projectname/tests/functional/test_sqlalchemyproject.py', } copydict.update(reset) empty = [ 'projectname/templates/__init__.py', 'projectname/tests/functional/test_sample.py', 'projectname/tests/functional/test_sample2.py', 'projectname/tests/functional/test_sample3.py', 'projectname/tests/functional/test_cache.py' ] _do_proj_test(copydict, empty) # res = projenv.run(_get_script_name('paster')+' setup-app development.ini', expect_stderr=True,) # assert '?' not in res.stdout # Unfortunately, these are ordered, so be careful def test_project_paster_create(): paster_create() def test_project_make_controller(): make_controller() def test_project_make_controller_subdirectory(): make_controller_subdirectory() def test_project_do_nosetests(): do_nosetests() def test_project_do_knowntest(): do_knowntest() def test_project_do_i18ntest(): do_i18ntest() def test_project_make_restcontroller(): make_restcontroller() def test_project_make_restcontroller_subdirectory(): make_restcontroller_subdirectory() def test_project_do_rest_nosetests(): copydict = { 'rest_routing.py':'projectname/config/routing.py', 'development.ini':'development.ini', } match_routes_output = [ 'Route name +Methods +Path', 'restsamples +GET +/restsamples' ] _do_proj_test(copydict, match_routes_output) # Tests with templating plugin dependencies def test_project_do_crazy_decorators(): do_crazy_decorators() def test_project_do_cache_decorator(): do_cache_decorator() def test_project_do_genshi_default(): if is_jython: raise SkipTest('Jython does not currently support Genshi') do_genshi() def test_project_do_jinja2(): do_jinja2() def test_project_do_xmlrpc(): do_xmlrpc() #def test_project_make_tag(): # make_tag() def test_project_do_sqlaproject(): if SQLAtesting: do_sqlaproject() else: pass def teardown(): dir_to_clean = os.path.join(os.path.dirname(__file__), TEST_OUTPUT_DIRNAME) cov_dir = os.path.join(dir_to_clean, 'ProjectName') main_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) # Scan and move the coverage files # for name in os.listdir(cov_dir): # if name.startswith('.coverage.'): # shutil.move(os.path.join(cov_dir, name), main_dir) # shutil.rmtree(dir_to_clean) Pylons-1.0.1/tests/test_webapps/test_make_project.pyc0000664000076500000240000004304312012306033022741 0ustar benstaff00000000000000 Nc@sdZddlZddlZddlZddlZddlZddlmZddlm Z ej j dddkrenddl Z ddl Z yddlZeZWnek reZnXejjdZd Zx'd d d d gD]ZejeqWejjejjedjddZej j Z!de!dd0Z?d1Z@d2ZAd3ZBd4ZCd5ZDd6ZEd7ZFd8ZGdS(9s7Tests against full Pylons projects created from scratchiN(tSkipTest(tTestFileEnvironmenttSKIP_INTEGRATEDtFalset0tjavatoutputt PasteScripttPastet PasteDeploytpylonst filestotests\t/ttruet PASTE_TESTINGt template_pathtenvironcCs6tjdkr2|jjd r2|d7}n|S(Ntwin32s.exe(tsystplatformtlowertendswith(tscript((sL/Users/ben/Programming/Python/pylons/tests/test_webapps/test_make_project.pyt_get_script_name,s% cCstjtddddt}tjjddjdd}d }d |kr]d }n||d t_d|jksttj j ddS( NtsvnadmintcreatetREPOSt printresults\R t s%20sfile://t:sfile:///s/REPOS( ttestenvtrunRRt base_pathtreplacetsvn_urlt files_createdtAssertionErrort ignore_pathstappend(trestpathtbase((sL/Users/ben/Programming/Python/pylons/tests/test_webapps/test_make_project.pytsvn_repos_setup1s !  tmakocCsdddg}|r%|jdn|jdddd|d d |gtjtd |}d d dddg}x\|D]T}tjjd|}|s||jj kst n||j kst qW|sC|jtjjdd}|j d|j d|j d|j dd|ksCt ntjtt jddtjjtjdjdddtttjjtjdjdddtdtdtatjjdddtjtjdR t pylons.testt sqlalchemytsaR;Rt ImportErrorRRt startswithRRtspectrequireR(R6RRR!RtcopyR<RRTR=RR*RFRKRMRNRORaRbRcRdRiRjRkRmRnRoRrRsRtRuRvRwRxRyRzR{R|R}R~RRRRR(((sL/Users/ben/Programming/Python/pylons/tests/test_webapps/test_make_project.pyts             $ -   *    "                       Pylons-1.0.1/UPGRADING0000664000076500000240000000354411645401275014144 0ustar benstaff00000000000000Upgrading your Pylons Project ============================= Pylons projects should be updated using the paster command create. In addition to creating new projects, paster create when run over an existing project will provide several ways to update the project template to the latest version. Using this tool properly can make upgrading a fairly minor task. For the purpose of this document, the project being upgraded will be called 'demoapp' and all commands will use that name. Running paster create to upgrade -------------------------------- You'll first need to cd to the directory *above* your projects main directory. The main directory is the one that contains your setup.py, setup.cfg, and development.ini files. .. code:: bash /home/joe/demoapp $ cd .. /home/joe $ Then run paster create on the project directory: .. code:: bash /home/joe $ paster create demoapp -t pylons paster will prompt you on how to handle conflicts and updates to the existing project files. The options let you (hit the key in the parens to perform the operation): (d)iff them, and show you the changes between your projects file and the one that has changed in Pylons (b)ackup the file, and copy the new version into its place. The old one will end in .bak (y)es to overwrite the existing file with the new one. *Not recommended* since you will then have no way to see your existing one, unless you have seen the diff first and know there is no changes you're losing. (n)o to overwrite, and just keep your existing file. Also safe if you know that nothing has changed. It's recommended when upgrading your project that you always look at the diff first to see whats changed. Then either overwrite your existing one if you are not going to lose changes you want, or backup yours and write the new one in. You can then manually compare and add your changes back in.