Mojolicious-Plugin-AssetPack-2.13/000755 000765 000024 00000000000 14023167353 017007 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/LICENSE000644 000765 000024 00000021413 14022450732 020010 0ustar00sristaff000000 000000 The Artistic License 2.0 Copyright (c) 2000-2006, The Perl Foundation. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software. You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement. Definitions "Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package. "Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures. "You" and "your" means any person who would like to copy, distribute, or modify the Package. "Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version. "Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization. "Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees. "Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder. "Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder. "Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future. "Source" form means the source code, documentation source, and configuration files for the Package. "Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form. Permission for Use and Modification Without Distribution (1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version. Permissions for Redistribution of the Standard Version (2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package. (3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License. Distribution of Modified Versions of the Package as Source (4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following: (a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version. (b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version. (c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under (i) the Original License or (ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed. Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source (5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license. (6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version. Aggregating or Linking the Package (7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation. (8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package. Items That are Not Considered Part of a Modified Version (9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license. General Provisions (10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. (11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. (12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. (13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed. (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Mojolicious-Plugin-AssetPack-2.13/Changes000644 000765 000024 00000045647 14023167234 020320 0ustar00sristaff000000 000000 2.13 2021-03-13 - Restored documentation. 2.12 2021-03-11 - Mojolicious::Plugin::AssetPack is now maintained by the Mojolicious team. 2.11 2021-02-19T10:23:04+0900 - Use 'partial(1)->to' instead of 'detour' which was deprecated in Mojolicious 9.0 Contributor: Marius Kittler 2.10 2020-12-11T11:16:01+0900 - Fixes warnings issued by latest Mojolicious Contributor: Zoffix Znet 2.09 2020-09-07T08:56:50+0900 - Prevent JavaScript from runnning in 404 assets #140 - Slimmed down the bundled documentation 2.08 2019-05-07T21:16:40+0700 - Fix link to Mojolicious::Plugin::Webpack 2.07 2019-05-04T23:54:32+0700 - Add RollupJs->add_global(); - Add note about Mojolicious::Plugin::Webpack 2.06 2018-09-02T22:25:13+0200 - Fix deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to coffeescript - Fix RollupJs pipe compatible with new rollupjs #138 2.05 2018-08-01T14:19:35+0800 - Fix s///r is not supported in older Perls #136 - Fix Favicon rendering of manifest and browserconfig - Add Asset::renderer() for dynamic assets - Add fallback for serving assets with wrong checksum - Renamed Asset::renderer() to tag_for() 2.04 2018-07-19T17:39:06+0800 - Add support for generating manifest with Favicon pipe - Marked AssetPack::tag_for() as deprecated - Removed support for Mojolicious::Plugin::AssetPack::Backcompat 2.03 2018-04-26T10:22:06+0200 - Ensure asset is processed when calling processed - Update favicon generator URL to use https - Set higher inactivity timeout for favicon generator 2.02 2018-01-28T13:12:59+0100 - Add EXPERIMENTAL support for fetching assets from helpers 2.01 2017-11-06T13:02:45+0100 - Up version number to try to fix pause indexing issues - NOTE: 2.00 was a mistake. There are no major changes 2.00 2017-10-29T10:08:37+0800 - Fix RollupJs package name #130 - load_module() confess on error - Removed EXPERIMENTAL Reloader pipe - Removed EXPERIMENTAL clone() method in AssetPack::Asset 1.47 2017-10-14T18:58:55+0200 - Dropping "original" from assetpack.db 1.46 2017-09-27T21:35:33+0200 - Add "asset_class" attribute to AssetPack::Store - Add rollupjs pipe - https://rollupjs.org/ 1.45 2017-06-19T23:49:30+0200 - Add Developing guide - Removed deprecated method end_range() from AssetPack::Asset - Removed deprecated method get_chunk() from AssetPack::Asset - Removed deprecated method is_range() from AssetPack::Asset - Removed deprecated method mtime() from AssetPack::Asset - Removed deprecated method start_range() from AssetPack::Asset - Removed deprecated method tag_helper() from AssetPack::Asset - Removed MOJO_ASSETPACK_CLEANUP (only used in test suite) - Can prevent AssetPack::Store from writing assetpack.db while developing with MOJO_ASSETPACK_LAZY=1 (EXPERIMENTAL) 1.44 2017-05-21T23:02:46+0200 - Improved documentation #125 Contributor: William Lindley 1.43 2017-05-12T14:38:02+0200 - Fix not escaping Vuejs template code - Less verbose logging when processing assets 1.42 2017-04-29T14:23:37+0200 - Fix missing use lib '.' in register.t #124 - Add fetching of source maps to "Fetch" pipe #117 1.41 2017-03-15T22:09:14+0100 - Fix bug in @import regex used by Pipe::Sass 1.40 2017-02-05T15:10:58-0800 - Fix skipping @import in comments #121 - Improved documentation for assetpack.def and paths #110 - Can disable Pipe::Reloader from the browser 1.39 2017-01-25T22:39:45+0100 - Skipping t/sass-source-map.t for now #115 http://cpantesters.org/cpan/report/c59d94d4-e16e-11e6-ab5a-96809f28caea 1.38 2017-01-23T14:12:31+0100 - Fix missing path() function in Pipe::Sass 1.37 2017-01-12T20:52:18+0100 - Add support for sass source maps - No need to delete known media types in AssetPack::Store 1.36 2017-01-11T11:18:45+0100 - Fix bug in Fetch pipe, fixing t/font-awesome.t - Change Mojolicious::Plugin::AssetPack::Asset::path() to return a Mojo::File object 1.35 2017-01-11T10:30:09+0100 - Forgot to remove Carp::Always from t/recreate.t after debugging 1.34 2017-01-10T23:22:16+0100 - Compatible with Mojolicious 7.15 1.33 2017-01-08T14:20:03+0100 - Fix t/reloader.t when CSS::Minifier::XS is missing #113 1.32 2017-01-08T11:50:36+0100 - Fix Mojo::Home::rel_dir is DEPRECATED in favor of Mojo::Hom::rel_file #112 - Disable "Reloader" pipe, unless in development 1.31 2017-01-04T14:19:34+0100 - Fix generating favicons once with MOJO_ASSETPACK_LAZY - Made Reloader call process() later 1.30 2016-12-23T03:14:34+0100 - Fix CoffeeScript, by changing to coffee-script npm package - Fix "Unable to download" messages after downloaded sass file #107 - Add EXPERIMENTAL support for MOJO_ASSETPACK_LAZY=1 - Marked AssetPack::Asset::mtime() as deprecated 1.29 2016-12-15T23:04:40+0100 - Fix custom helper name #111 1.28 2016-11-24T10:51:55+0100 - Fix resetting end_range and start_range after a "Range: bytes=..." request #109 1.27 2016-11-18T15:13:55+0100 - Add custom 404 page when an asset could not be found 1.26 2016-11-13T17:50:42+0100 - Change Pipe::Fetch to avoid fetching URL that start with "#" #108 1.25 2016-10-30T21:24:48+0100 - Add end_range(), start_range() and is_range() to Asset #104 1.24 2016-09-11T17:22:08+0200 - Forgot to delete t/sass-current-app.t after 1.23 1.23 2016-09-11T17:01:57+0200 - Add EXPERIMENTAL support for mixing in dynamic SASS files 1.22 2016-09-02T14:27:42+0200 - Fix showing error message when asset could not be found 1.21 2016-08-29T15:48:01+0200 - Add support for merging assetpack.db files 1.20 2016-08-19T15:11:58+0200 - Add EXPERIMENTAL Mojolicious::Plugin::AssetPack::Pipe::TypeScript - Will default to "==" test when checking mode in assetpack.def - Moved Backcompat to the Mojolicious-Plugin-AssetPack-Backcompat dist 1.19 2016-08-10T19:14:16+0200 - Add EXPERIMENTAL support for compiling .vue (Vue.js) files 1.18 2016-07-25T17:52:06+0200 - Fix Can't locate object method "authority" via package "Mojo::URL" #102 1.17 2016-07-18T18:43:23+0200 - Removed Mojolicious::Plugin::AssetPack::Asset::tag_helper() - Add Mojolicious::Plugin::AssetPack::tag_for() - Add Mojolicious::Plugin::AssetPack::Asset::url_for() - Add EXPERIMENTAL Mojolicious::Plugin::AssetPack::Pipe::Favicon - Add support for gif, ico, mp3, mp4, ogg, ogv, svg and webm. 1.16 2016-06-29T19:05:43+0200 - Improved documentation for store() #101 1.15 2016-06-23T10:50:26+0200 - Fix Fetch pipe will skip downloading "data:..." urls #100 1.14 2016-06-21T13:33:41+0200 - Fix Fetch::URL_RE for url(...) without quotes #91 #99 - Fix trimming whitespace for topics in .def file, closes #93 - Fix replacing all fetched files #94 - Will show download error message #96 1.13 2016-05-21T08:11:27+0200 - Fix sass-current-app.t after 1.12 1.12 2016-05-20T20:59:10+0200 - Fix compressing Sass assets with SASS_STYLE_COMPRESSED Contributor: Zoffix Znet 1.11 2016-05-17T07:55:56+0200 - Fix failing reloader-process.t 1.10 2016-05-15T11:50:24+0200 - Fix watching the actual input asset files in Pipe::Reloader #86 Contributor: Mark Grimes 1.09 2016-05-10T21:36:09+0200 - Fix to deal with multiple imports of the same Sass file #83 Contributor: Mark Grimes 1.08 2016-05-09T22:23:42+0200 - Add support for minifying jpeg image files - Add support for minifying png image files #81 Contributor: Heiko Jansen - Add Mojolicious::Plugin::AssetPack::Asset::tag_helper() to support future "image" assets. 1.07 2016-05-03T13:55:45+0200 - Fix rendering assets URL in mounted apps 1.06 2016-04-17T14:22:08+0200 - Fix Fetch with Combine #75 1.05 2016-04-17T11:19:29+0200 - Need to "use CSS::Sass 3.3.0" to avoid test failures on missing features - Add support for automatic download of fonts #75 - Add support for conditions in assetpack.def #78 - Fix SCSS files with UTF-8 encoding #70 - Fix adding route earlier than on the first request #77 - Fix setting url() on asset from db file 1.04 2016-04-08T22:40:29+0200 - Fix Pipe::Reloader and files from def file - Change default Pipe::Reloader strategy to "document" to make reloading JavaScript more robust. 1.03 2016-04-08T20:15:31+0200 - Add Pipe::Reloader for instant refresh in browser on asset change #72 - Marked old modules as deprecated 1.02 2016-04-08T14:30:19+0200 - Add support for "sass_functions" #68 Contributor: Mark Grimes - Fix 2 naked subroutines - Fix t/sass.t: #919191 != #909090 - Skip more old tests by default 1.01 2016-04-06T16:10:06+0200 - Cannot load CSS::Minifier::XS in old code - The module is optional - Cannot load JavaScript::Minifier::XS in old code - The module is optional 1.00 2016-04-02T21:26:35+0200 - Rewrote the module. Breaking changes might occur. - Changed from "pre-processors" to "pipes" 0.69 2015-12-02T16:37:36+0100 - Fix "uninitialized value" warning in Scss.pm line 203 #65 - Fix fetch() from $app 0.68 2015-09-28T08:28:29+0200 - Will skip tests unless possible to write to out_dir 0.67 2015-09-27T15:24:23+0200 - Fix asset can be read-only 0.66 2015-09-27T14:56:56+0200 - Skip some tests on windows - Remove EXPERIMENTAL remark for wildcards in filenames #52 - Remove EXPERIMENTAL remark from headers() - Remove EXPERIMENTAL remark from source_paths() 0.65 2015-09-25T16:55:49+0200 - Add EXPERIMENTAL fixed mapping between moniker to packed files #64 - Add EXPERIMENTAL test_app() to ensure all assets are created - Change headers() into a method - Change out_dir() into a read-only method, as documented - Remove EXPERIMENTAL support for reloader.js - Remove deprecated preprocessor() method - Remove support for in-memory assets #64 - Fix memory leak 0.64 2015-09-20T11:44:26+0200 - Add "SHIPPING" section to Cookbook - Fix adding custom response headers when assets are already built #55 - Fix always add newline to JavaScript assets to prevent issues with comments - Improved logging for in-memory assets - Improved error reporting when unable to build assets 0.63 2015-08-29T00:51:29+0200 - Fix responding 404 when in-memory asset could not be found - Add support for custom response headers #55 0.62 2015-08-27T11:40:41-0400 - Fix @import tracking #62 0.61 2015-08-23T13:34:34+0200 - Add include_paths() to Scss preprocessor - Fix using SASS_PATH environment variable when calculating checksum #60 - Deprecating asset->preprocessor() in favor of asset->preprocessors->add() 0.60 2015-08-20T17:21:54+0200 - Fix detecting changed sass/scss files in sub directories, with leading underscore 0.59 2015-08-20T14:42:25+0200 - Cannot look for packed files in "source_paths" - MOJO_ASSETPACK_DEBUG need to be set to "2" for more verbose debug 0.58 2015-08-09T14:28:04+0200 - Change "source_paths" to return original reference and not a copy - Need to look for packed files in all directories (source_paths+public) 0.57 2015-08-09T11:34:21+0200 - Add support for "source_paths" (EXPERIMENTAL) #58 - Add support for fetching assets using a proxy 0.56 2015-08-05T10:44:15+0200 - Add purge() method (EXPERIMENTAL) - Add EXPERIMENTAL support for wildcards in filenames #52 0.55 2015-05-25T12:58:04+0200 - Will not add memory asset route if not needed #56 - Make error visible regardless of page scroll position #57 Contributor: Zoffix Znet 0.54 2015-04-23T17:37:01+0200 - Fix saving unchanged assets on disk 0.53 2015-04-23T17:27:41+0200 - Fix regenerating sprites:// assets 0.5201 2015-04-20T08:48:47+0200 - Fix sprites.t - Fix skipping t/plugin-with-assets.t 0.52 2015-04-18T12:54:40+0200 - Add support for generating image sprites and css - Add EXPERIMENTAL ::Handlers::Sprites, ::Handlers::Http and ::Handlers::Https - Add ::Asset::content() - Rename ::Asset::url() to path(). - Remove ::Asset::add_chunk() 0.51 2015-04-16T08:15:50+0200 - Can reload assets on server reload (EXPERIMENTAL) 0.50 2015-04-13T11:37:08+0200 - Need to start with a fresh asset to avoid adding duplicate processed data to the same asset. 0.49 2015-04-05T09:54:27Z - Will not pack asset.ext.swp files 0.48 2015-04-05T09:19:01Z - Fix serving in memory assets with Content-Type - Fix serving in memory assets with Last-Modified 0.47 2015-04-04T13:53:32Z - Fix Mojo::Base::tap() does not support arguments before 5.57 0.4602 2015-04-02T18:44:01Z - Improved cpantesters 0.46 2015-04-01T15:09:35Z - Remove "fallback" attribute #44 (experimental) - Remove "process" method - Will prevent AssetPack from registering twice - Will not write assets to "mojo-assetpack-public" in TMPDIR #46 (experimental) - Allow in-memory assets with out_dir(""), MOJO_ASSETPACK_DEBUG=1 or read-only static dirs. #46 (experimental) 0.45 2015-03-31T22:02:06Z - Can also fetch remote assets from local $app #30 - Will calculate MD5 sum recursively for sass/scss #44 - Add Cookbook 0.44 2015-03-23T13:00:45Z - Add ".min.ext" to minified asset filename - Change filename for assets with errors from "-with-error.ext" to ".err.ext" - Will look for existing assets even with MOJO_ASSETPACK_DEBUG=1 - Remove errmsg() from Mojolicious::Plugin::AssetPack::Preprocessor - Remove detect() from Mojolicious::Plugin::AssetPack::Preprocessors 0.43 2015-03-20T11:27:22Z - Same CSS::Sass detection for Sass as for Scss preprocessor 0.42 2015-03-16T19:31:36Z - Fix "Unescaped left brace in regex is deprecated" warnings 0.41 2015-03-16T13:47:17Z - Will die on CSS::Sass errors 0.40 2015-03-16T11:04:47Z - Fix reading sass files from SASS_PATH, when using CSS::Sass 0.39 2015-03-06T17:06:19Z - Will default to CSS::Sass if installed - Reversed production/development logic - Fix spelling in documentation (berov) 0.3801 2015-03-02T23:58:21Z - Removed reference to "expand" #38 0.38 2015-03-02T23:55:36Z - Improved documentation. - Less logging 0.37 2015-02-04T16:59:36Z - Will use CSS::Sass if ENABLE_LIBSASS_BINDINGS=1 is set This is candiate to become the default in later releases 0.36 2015-01-30T12:08:51Z - Require JavaScript::Minifier::XS 0.11 which include many bugfixes, such as: JavaScript::Minifier::XS::minify(q|function(s){return /^\s*[\w-"']+ *:/.test(s)}|); 0.35 2015-01-29T21:20:25Z - Include original error message when failing to fallback - Will die() instead of return $err on process() - Improved detection of minified JavaScript code #34 0.34 2015-01-23T12:51:25Z - Add preprocessor() method to AssetPack - Add support for assets from __DATA__ 0.33 2015-01-06T20:00:42Z - Can fallback to existing assets in production mode 0.32 2014-12-18T12:23:58Z - Add logging of JavaScript code to console on error - Able to pass on attrs to script/link tag generator #33 0.31 2014-10-09T13:19:44Z - Fixed and wrote tests for external AssetPack plugins 0.30 2014-10-08T21:55:37Z - Processed assets can be other places than out_dir() 0.29 2014-10-08T20:53:32Z - Improved error message when unable to find external preprocessor (regression) 0.28 2014-10-07T23:58:45Z - Add support for %= asset "foo.js", { inline => 1 } - Will also generate asset files with md5 from single files - Remove expand() - Remove rebuild() 0.27 2014-10-07T00:28:39Z - Fix t/google-font.t 0.26 2014-10-07T00:16:27Z - Generate a different checksum when unable to process input files - Replaced "/Mojolicious/Plugin/AssetPack/could/not/compile/..." with an actual asset using Preprocessor::Fallback 0.25 2014-10-06T16:28:59Z - Preprocessors are added on the fly - Deprecated "no_autodetect" - Improved documentation 0.24 2014-09-28T20:44:00Z - Add preprocessor classes for every detected preprocessor - Add Preprocessors->can_process method to detect if preprocessors exists - Improved error message from sass preprocessor 0.23 2014-09-07T18:20:35Z - Add AssetPack->fetch() method #24 - Can calculate checksum with included .sass and .scss files #25 - Can load external assets with minify=0 #27 - Support printing sass error to web page #26 - Better error message when unable to find asset file - Change to using objects for processing files 0.22 2014-08-21T15:08:56Z - Made compass test more robust 0.21 2014-08-07T21:33:48Z - Add support for more debug output with MOJO_ASSETPACK_DEBUG=1 - Add error message for missing "jsx" preprocessor - Will render missing text for all types which is not detected. - Remove map_type() from Mojolicious::Plugin::AssetPack::Preprocessors 0.20 2014-08-01T09:55:12Z - Catch exit code from external applications - Improved error messages 0.19 2014-07-27T20:26:45Z - Fix failing test for "compass" 0.18 2014-07-18T01:29:04Z - Will not continue if asset failed to download 0.17 2014-07-15T03:03:57Z - Fix loading empty javascript file 0.16 2014-07-07T22:39:30Z - Fix CPAN testers error http://www.cpantesters.org/cpan/report/caa7015a-050b-11e4-ae21-9a7d1ff27 236 0.15 2014-07-05T11:28:42Z - Add JSX support. 0.14 2014-06-14T12:33:10Z - Add ::Preprocessors->map_type() method. - Add support for .sass files - Add support for sass+compass - Add support for custom base_url for minified assets 0.13 2014-06-09T16:11:57Z - Fix including online assets without extension - Fix Use of uninitialized value $_[3] in concatenation 0.12 2014-05-22T21:39:43Z - Allow asset moniker with same name as expanded packed filename. 0.11 2014-05-08T19:13:41Z - Add CoffeScript support. (Alexander Rymasheusky) https://github.com/jhthorsen/mojolicious-plugin-assetpack/pull/7 - Add -I to sass command line (Per Edin) https://github.com/jhthorsen/mojolicious-plugin-assetpack/pull/5 - Add support for MOJO_ASSETPACK_NO_CACHE=1 (Alexander Rymasheusky) https://github.com/jhthorsen/mojolicious-plugin-assetpack/pull/9 0.10 2014-05-08T19:09:00Z - See 0.11 0.09 2014-03-23T11:45:03Z - Remove option for cleaning up old asset files 0.08 2014-03-22T19:14:00Z - Fix finding compiled files by MD5 sum 0.07 2014-03-16T12:07:46Z - Add support for fetching assets from web - Improved support for finding a writeable out_dir 0.0601 2013-12-30T17:01:20Z - Fix bug when asset has the same moniker as one of the source files 0.06 2013-12-17T20:16:24Z - Will not die, but log with custom error message on missing preprocessor 0.0502 2013-11-27T09:21:33Z - Fix plan in t/expand.t when sass is missing 0.0501 2013-11-26T09:43:06Z - Cannot define assets when missing preprocessors 0.05 2013-11-24T18:20:11Z - Bundling JavaScript::Minifier::XS and CSS::Minifier::XS - Will calculate md5_sum from input files - Add support for getting assets for a moniker 0.0402 2013-11-12T21:17:34Z - Will select the latest processed file when preprocessor is missing 0.0401 2013-10-31T21:09:56Z - Fix cleanup of files without md5 0.04 2013-10-31T18:57:22Z - Add support for custom out_dir - Fix cannot lookup preprocessor based on moniker extension 0.03 2013-10-28T18:31:03Z - Use md5sum instead of timestamp in filenames 0.0201 2013-10-10T20:10:25Z - Fix need to change back to previous working dir 0.02 2013-09-24T09:17:43Z - Will only write asset files if the preprocessors exists 0.0102 2013-09-15T15:15:37Z - Fix AssetPack in embedded apps 0.0101 2013-09-15T14:26:29Z - Fix t/compress.t 0.01 2013-09-15T14:20:22Z - Add "asset" helper - Add support for chained preprocessors - Add default preprocessors for js, css, scss and less - Can expand from moniker to multiple script/link tags - Can compress multiple files to one moniker asset Mojolicious-Plugin-AssetPack-2.13/MANIFEST000644 000765 000024 00000005762 14023167353 020152 0ustar00sristaff000000 000000 .gitattributes .github/CONTRIBUTING.md .github/ISSUE_TEMPLATE.md .github/PULL_REQUEST_TEMPLATE.md .github/workflows/linux.yml .github/workflows/perltidy.yml .mergify/config.yml .perltidyrc Changes examples/not-found.pl examples/rollup.pl examples/sprites.pl lib/Mojolicious/Plugin/AssetPack.pm lib/Mojolicious/Plugin/AssetPack/Asset.pm lib/Mojolicious/Plugin/AssetPack/Asset/Null.pm lib/Mojolicious/Plugin/AssetPack/Guides/Cookbook.pod lib/Mojolicious/Plugin/AssetPack/Guides/Developing.pod lib/Mojolicious/Plugin/AssetPack/Guides/Tutorial.pod lib/Mojolicious/Plugin/AssetPack/Pipe.pm lib/Mojolicious/Plugin/AssetPack/Pipe/CoffeeScript.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Combine.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Css.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Favicon.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Fetch.pm lib/Mojolicious/Plugin/AssetPack/Pipe/JavaScript.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Jpeg.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Less.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Png.pm lib/Mojolicious/Plugin/AssetPack/Pipe/require.js lib/Mojolicious/Plugin/AssetPack/Pipe/riot.js lib/Mojolicious/Plugin/AssetPack/Pipe/Riotjs.pm lib/Mojolicious/Plugin/AssetPack/Pipe/RollupJs.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Sass.pm lib/Mojolicious/Plugin/AssetPack/Pipe/typescript.js lib/Mojolicious/Plugin/AssetPack/Pipe/TypeScript.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Vuejs.pm lib/Mojolicious/Plugin/AssetPack/Store.pm lib/Mojolicious/Plugin/AssetPack/Util.pm LICENSE Makefile.PL MANIFEST This list of files README.md t/00-basic.t t/assets/css-0-one.css t/assets/css-0-two.css t/assets/css/c.css t/assets/example.css t/assets/image/master_favicon_thumbnail.png t/assets/image/photo-1429734160945-4f85244d6a5a.jpg t/assets/image/sample.png t/assets/js/export.js t/assets/js/not-found.js t/assets/js/some-lib.js t/assets/js/vue-app.js t/assets/other/dummy.gif t/assets/other/dummy.ico t/assets/other/dummy.mp3 t/assets/other/dummy.mp4 t/assets/other/dummy.ogg t/assets/other/dummy.ogv t/assets/other/dummy.svg t/assets/other/dummy.webm t/assets/recreate.css t/assets/sass/70-utf8.scss t/assets/sass/_sass-1-blocks.scss t/assets/sass/sass-1-inc/_var2.scss t/assets/sass/sass-1-inc/variables.scss t/assets/sass/sass-1.scss t/assets/sass/sass-2-dup.scss t/assets/sass/sass-2-dup/_mixins.scss t/assets/vue/example.vue t/assets/vue/Test.vue t/base-url.t t/bin/coffee t/coffee.t t/css.t t/favicon.t t/fetch-all.t t/fetch-hash.t t/fetch-source-map.t t/font-awesome.t t/from-helper.t t/google-font.t t/Helper.pm t/jpeg.t t/jquery-mobile.t t/js.t t/lazy.t t/less.t t/mode.t t/mount.t t/not-found.t t/other.t t/png.t t/range.t t/recreate.t t/register.t t/riotjs-not-loaded.t t/riotjs.t t/rollup.t t/route.t t/sass-bin.t t/sass-dynamic-include.t t/sass-functions.t t/sass-source-map.t t/sass-unable-to-download.t t/sass-utf8.t t/sass.t t/typescript.t t/util.t t/vuejs.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Mojolicious-Plugin-AssetPack-2.13/t/000755 000765 000024 00000000000 14023167353 017252 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/README.md000644 000765 000024 00000001615 14022250667 020271 0ustar00sristaff000000 000000 # Mojolicious::Plugin::AssetPack [![](https://github.com/mojolicious/mojo-assetpack/workflows/linux/badge.svg)](https://github.com/mojolicious/mojo-assetpack/actions) Compress and convert CSS, Less, Sass, JavaScript and CoffeeScript files. ```perl use Mojolicious::Lite; # Load plugin and pipes in the right order plugin AssetPack => {pipes => [qw(Less Sass Css CoffeeScript Riotjs JavaScript Combine)]}; # define asset app->asset->process( # virtual name of the asset "app.css" => ( # source files used to create the asset "sass/bar.scss", "https://github.com/Dogfalo/materialize/blob/master/sass/materialize.scss", ) ); ``` ## Installation All you need is a one-liner, it takes less than a minute. $ curl -L https://cpanmin.us | perl - -M https://cpan.metacpan.org -n Mojolicious::Plugin::AssetPack We recommend the use of a [Perlbrew](http://perlbrew.pl) environment. Mojolicious-Plugin-AssetPack-2.13/examples/000755 000765 000024 00000000000 14023167353 020625 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/META.yml000644 000765 000024 00000001567 14023167353 020271 0ustar00sristaff000000 000000 --- abstract: 'Compress and convert CSS, Less, Sass, JavaScript and CoffeeScript files' author: - 'Sebastian Riedel ' build_requires: ExtUtils::MakeMaker: '0' Test::More: '0.88' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'ExtUtils::MakeMaker version 7.60, CPAN::Meta::Converter version 2.150010' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Mojolicious-Plugin-AssetPack no_index: directory: - t - inc requires: File::Which: '1.21' IPC::Run3: '0.048' Mojolicious: '9.0' resources: bugtracker: https://github.com/mojolicious/mojo-assetpack/issues homepage: https://github.com/mojolicious/mojo-assetpack repository: https://github.com/mojolicious/mojo-assetpack.git version: '2.13' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' Mojolicious-Plugin-AssetPack-2.13/.github/000755 000765 000024 00000000000 14023167353 020347 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/.gitattributes000644 000765 000024 00000000123 14022250537 021672 0ustar00sristaff000000 000000 *.pl linguist-language=Perl *.pm linguist-language=Perl *.t linguist-language=Perl Mojolicious-Plugin-AssetPack-2.13/lib/000755 000765 000024 00000000000 14023167353 017555 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/.mergify/000755 000765 000024 00000000000 14023167353 020527 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/Makefile.PL000644 000765 000024 00000001764 14022250651 020762 0ustar00sristaff000000 000000 use 5.016; use strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Mojolicious::Plugin::AssetPack', AUTHOR => 'Sebastian Riedel ', LICENSE => 'artistic_2', ABSTRACT_FROM => 'lib/Mojolicious/Plugin/AssetPack.pm', VERSION_FROM => 'lib/Mojolicious/Plugin/AssetPack.pm', TEST_REQUIRES => {'Test::More' => '0.88'}, PREREQ_PM => {'File::Which' => '1.21', 'IPC::Run3' => '0.048', 'Mojolicious' => '9.0'}, META_MERGE => { 'dynamic_config' => 0, 'meta-spec' => {version => 2}, 'resources' => { bugtracker => {web => 'https://github.com/mojolicious/mojo-assetpack/issues'}, homepage => 'https://github.com/mojolicious/mojo-assetpack', repository => { type => 'git', url => 'https://github.com/mojolicious/mojo-assetpack.git', web => 'https://github.com/mojolicious/mojo-assetpack', }, }, }, test => {TESTS => (-e 'META.yml' ? 't/*.t' : 't/*.t xt/*.t')}, ); Mojolicious-Plugin-AssetPack-2.13/.perltidyrc000644 000765 000024 00000001024 14022250537 021162 0ustar00sristaff000000 000000 -pbp # Start with Perl Best Practices -w # Show all warnings -iob # Ignore old breakpoints -l=120 # 120 characters per line -mbl=2 # No more than 2 blank lines -i=2 # Indentation is 2 columns -ci=2 # Continuation indentation is 2 columns -vt=0 # Less vertical tightness -pt=2 # High parenthesis tightness -bt=2 # High brace tightness -sbt=2 # High square bracket tightness -wn # Weld nested containers -isbc # Don't indent comments without leading space -nst # Don't output to STDOUT Mojolicious-Plugin-AssetPack-2.13/META.json000644 000765 000024 00000003015 14023167353 020427 0ustar00sristaff000000 000000 { "abstract" : "Compress and convert CSS, Less, Sass, JavaScript and CoffeeScript files", "author" : [ "Sebastian Riedel " ], "dynamic_config" : 0, "generated_by" : "ExtUtils::MakeMaker version 7.60, CPAN::Meta::Converter version 2.150010", "license" : [ "artistic_2" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Mojolicious-Plugin-AssetPack", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "File::Which" : "1.21", "IPC::Run3" : "0.048", "Mojolicious" : "9.0" } }, "test" : { "requires" : { "Test::More" : "0.88" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/mojolicious/mojo-assetpack/issues" }, "homepage" : "https://github.com/mojolicious/mojo-assetpack", "repository" : { "type" : "git", "url" : "https://github.com/mojolicious/mojo-assetpack.git", "web" : "https://github.com/mojolicious/mojo-assetpack" } }, "version" : "2.13", "x_serialization_backend" : "JSON::PP version 4.06" } Mojolicious-Plugin-AssetPack-2.13/.mergify/config.yml000644 000765 000024 00000001031 14022250537 022506 0ustar00sristaff000000 000000 pull_request_rules: - name: automatic merge conditions: - "#approved-reviews-by>=2" - "#changes-requested-reviews-by=0" - label!=work in progress - base=master actions: merge: method: merge - name: remove outdated reviews conditions: - base=master actions: dismiss_reviews: {} - name: ask to resolve conflict conditions: - conflict actions: comment: message: This pull request is now in conflicts. Could you fix it @{{author}}? 🙏 Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/000755 000765 000024 00000000000 14023167353 022051 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/000755 000765 000024 00000000000 14023167353 023307 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack.pm000644 000765 000024 00000027556 14023167207 025540 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack; use Mojo::Base 'Mojolicious::Plugin'; use Mojo::Util qw(deprecated trim xml_escape); use Mojolicious::Plugin::AssetPack::Asset::Null; use Mojolicious::Plugin::AssetPack::Store; use Mojolicious::Plugin::AssetPack::Util qw(diag has_ro load_module DEBUG); our $VERSION = '2.13'; has minify => sub { shift->_app->mode eq 'development' ? 0 : 1 }; has route => sub { shift->_app->routes->any([qw(HEAD GET)] => '/asset/:checksum/*name')->name('assetpack')->to(cb => \&_serve); }; has store => sub { my $self = shift; Mojolicious::Plugin::AssetPack::Store->new( classes => [@{$self->_app->static->classes}], paths => [$self->_app->home->rel_file('assets')], ua => $self->ua, ); }; has_ro ua => sub { Mojo::UserAgent->new->max_redirects(3) }; sub pipe { my ($self, $needle) = @_; return +(grep { $_ =~ /::$needle\b/ } @{$self->{pipes}})[0]; } sub process { my ($self, $topic, @input) = @_; $self->route unless $self->{route_added}++; return $self->_process_from_def($topic) unless @input; # TODO: The idea with blessed($_) is that maybe the user can pass inn # Mojolicious::Plugin::AssetPack::Sprites object, with images to generate # CSS from? my $assets = Mojo::Collection->new; for my $url (@input) { my $asset = Scalar::Util::blessed($url) ? $url : $self->store->asset($url); die qq(Could not find input asset "$url".) unless Scalar::Util::blessed($asset); push @$assets, $asset; } return $self->tap(sub { $_->{input}{$topic} = $assets }) if $self->{lazy}; return $self->_process($topic => $assets); } sub processed { my ($self, $topic) = @_; $self->_process($topic => $self->{input}{$topic}) unless $self->{by_topic}{$topic}; # Ensure asset is processed return $self->{by_topic}{$topic}; } sub register { my ($self, $app, $config) = @_; my $helper = $config->{helper} || 'asset'; if ($app->renderer->helpers->{$helper}) { return $app->log->debug("AssetPack: Helper $helper() is already registered."); } $self->{input} = {}; $self->{lazy} ||= $ENV{MOJO_ASSETPACK_LAZY} // $config->{lazy} || 0; $app->defaults('assetpack.helper' => $helper); $self->ua->server->app($app); Scalar::Util::weaken($self->ua->server->{app}); if (my $proxy = $config->{proxy} // {}) { local $ENV{NO_PROXY} = $proxy->{no_proxy} || join ',', grep {$_} $ENV{NO_PROXY}, $ENV{no_proxy}, '127.0.0.1', '::1', 'localhost'; diag 'Detecting proxy settings. (NO_PROXY=%s)', $ENV{NO_PROXY} if DEBUG; $self->ua->proxy->detect; } $self->_pipes($config->{pipes} || []); $app->helper($helper => sub { @_ == 1 ? $self : $self->_render_tags(@_) }); } sub tag_for { my $self = shift; deprecated 'tag_for() is DEPRECATED in favor of Mojolicious::Plugin::AssetPack::Asset::tag_for()'; return $self->{tag_for} unless @_; $self->{tag_for} = shift; return $self; } sub _app { shift->ua->server->app } sub _correct_mode { my ($self, $args) = @_; while ($args =~ /\[(\w+)([!=]+)([^\]]+)/g) { my $v = $1 eq 'minify' ? $self->minify : $self->_app->$1; diag "Checking $1: $v $2 $3" if DEBUG == 2; return 0 if $2 eq '!=' and $v eq $3; return 0 if $2 ne '!=' and $v ne $3; # default to testing equality } return 1; } sub _pipes { my ($self, $names) = @_; $self->{pipes} = [ map { my $class = load_module /::/ ? $_ : "Mojolicious::Plugin::AssetPack::Pipe::$_"; diag 'Loading pipe "%s".', $class if DEBUG; my $pipe = $class->new(assetpack => $self); Scalar::Util::weaken($pipe->{assetpack}); $pipe; } @$names ]; } sub _process { my ($self, $topic, $input) = @_; my $assets = Mojo::Collection->new(@$input); # Do not mess up input local $Mojolicious::Plugin::AssetPack::Util::TOPIC = $topic; # Used by diag() for my $asset (@$assets) { if (my $prev = $self->{by_topic}{$topic}) { delete $asset->{$_} for qw(checksum format); $asset->content($self->store->asset($asset->url)); } $asset->checksum; } for my $method (qw(before_process process after_process)) { for my $pipe (@{$self->{pipes}}) { next unless $pipe->can($method); local $pipe->{topic} = $topic; diag '%s->%s("%s")', ref $pipe, $method, $topic if DEBUG; $pipe->$method($assets); } } if (my $tag_for = $self->{tag_for}) { $_->{tag_for} or $_->{tag_for} = $tag_for for @$assets; } my @checksum = map { $_->checksum } @$assets; $self->_app->log->debug(qq(Processed asset "$topic". [@checksum])) if DEBUG; $self->{by_checksum}{$_->checksum} = $_ for @$assets; $self->{by_topic}{$topic} = $assets; $self->store->persist; $self; } sub _process_from_def { my $self = shift; my $file = shift || 'assetpack.def'; my $asset = $self->store->file($file); my $topic = ''; my %process; die qq(Unable to load "$file".) unless $asset; diag qq(Loading asset definitions from "$file".) if DEBUG; for (split /\r?\n/, $asset->slurp) { s/\s*\#.*//; if (/^\<(\S*)\s+(\S+)\s*(.*)/) { my ($class, $url, $args) = ($1, $2, $3); next unless $self->_correct_mode($args); my $asset = $self->store->asset($url); die qq(Could not find input asset "$url".) unless Scalar::Util::blessed($asset); bless $asset, 'Mojolicious::Plugin::AssetPack::Asset::Null' if $class eq '<'; push @{$process{$topic}}, $asset; } elsif (/^\!\s*(.+)/) { $topic = trim $1; } } $self->process($_ => @{$process{$_}}) for keys %process; $self; } sub _render_tags { my ($self, $c, $topic, @attrs) = @_; my $route = $self->route; $self->_process($topic => $self->{input}{$topic}) if $self->{lazy}; my $assets = $self->{by_topic}{$topic} ||= $self->_static_asset($topic); my %args = (base_url => $route->pattern->defaults->{base_url} || '', topic => $topic); $args{base_url} =~ s!/+$!!; return Mojo::ByteStream->new( join "\n", map { $_->tag_for->($_, $c, \%args, @attrs) } grep { !$_->isa('Mojolicious::Plugin::AssetPack::Asset::Null') } @$assets ); } sub _serve { my $c = shift; my $helper = $c->stash('assetpack.helper'); my $self = $c->$helper; my $checksum = $c->stash('checksum'); if (my $asset = $self->{by_checksum}{$checksum}) { $self->store->serve_asset($c, $asset); return $c->rendered; } my $topic = $c->stash('name'); if (my $assets = $self->{by_topic}{$topic}) { return $self->store->serve_fallback_for_assets($c, $topic, $assets); } $c->render(text => sprintf("// No such asset '%s'\n", xml_escape $topic), status => 404); } sub _static_asset { my ($self, $topic) = @_; my $asset = $self->store->asset($topic) or die qq(No assets registered by topic "$topic".); my $assets = Mojo::Collection->new($asset); $self->{by_checksum}{$_->checksum} = $_ for @$assets; return $assets; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack - Compress and convert CSS, Less, Sass, JavaScript and CoffeeScript files =head1 SYNOPSIS =head2 Application use Mojolicious::Lite; # Load plugin and pipes in the right order plugin AssetPack => {pipes => [qw(Less Sass Css CoffeeScript Riotjs JavaScript Combine)]}; # define asset app->asset->process( # virtual name of the asset "app.css" => ( # source files used to create the asset "sass/bar.scss", "https://github.com/Dogfalo/materialize/blob/master/sass/materialize.scss", ) ); =head2 Template %= asset "app.css" <%= content %> =head1 DESCRIPTION L is a L for processing static assets. The idea is that JavaScript and CSS files should be served as one minified file to save bandwidth and roundtrip time to the server. There are many external tools for doing this, but integrating them with L can be a struggle: You want to serve the source files directly while developing, but a minified version in production. This assetpack plugin will handle all of that automatically for you. Your application creates and refers to an asset by its topic (virtual asset name). The process of building actual assets from their components is delegated to "pipe objects". =head1 GUIDES =over 2 =item L The tutorial will give an introduction to how AssetPack can be used. =item L The "developing" guide will give insight on how to do effective development with AssetPack and more details about the internals in this plugin. =item L The cookbook has various receipes on how to cook with AssetPack. =back =head1 HELPERS =head2 asset $self = $app->asset; $self = $c->asset; $bytestream = $c->asset($topic, @args); $bytestream = $c->asset("app.css", media => "print"); C is the main entry point to this plugin. It can either be used to access the L instance or as a tag helper. The helper name "asset" can be customized by specifying "helper" when L the plugin. =head1 ATTRIBUTES =head2 minify $bool = $self->minify; $self = $self->minify($bool); Set this to true to combine and minify the assets. Defaults to false if L is "development" and true otherwise. =head2 route $route = $self->route; $self = $self->route($route); A L object used to serve assets. The default route responds to HEAD and GET requests and calls L on L to serve the asset. The default route will be built and added to the L when L is called the first time. =head2 store $obj = $self->store; $self = $self->store(Mojolicious::Plugin::AssetPack::Store->new); Holds a L object used to locate, store and serve assets. =head2 tag_for Deprecated. Use L instead. =head2 ua $ua = $self->ua; Holds a L which can be used to fetch assets either from local application or from remote web servers. =head1 METHODS =head2 pipe $obj = $self->pipe($name); $obj = $self->pipe("Css"); Will return a registered pipe by C<$name> or C if none could be found. =head2 process $self = $self->process($topic => @assets); $self = $self->process($definition_file); Used to process assets. A C<$definition_file> can be used to define C<$topic> and C<@assets> in a separate file. C<$definition_file> defaults to "assetpack.def". =head2 processed $collection = $self->processed($topic); Can be used to retrieve a L object, with zero or more L objects. =head2 register $self->register($app, \%config); Used to register the plugin in the application. C<%config> can contain: =over 2 =item * helper Name of the helper to add to the application. Default is "asset". =item * pipes This argument is mandatory and need to contain a complete list of pipes that is needed. Example: $app->plugin(AssetPack => {pipes => [qw(Sass Css Combine)]); =item * proxy A hash of proxy settings. Set this to C<0> to disable proxy detection. Currently only "no_proxy" is supported, which will set which requests that should bypass the proxy (if any proxy is detected). Default is to bypass all requests to localhost. See L for more information. =back =head1 SEE ALSO L. =head1 COPYRIGHT AND LICENSE Copyright (C) 2020, Jan Henning Thorsen This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0. =head1 AUTHOR Jan Henning Thorsen - C Alexander Rymasheusky Mark Grimes - C Per Edin - C Viktor Turskyi =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/000755 000765 000024 00000000000 14023167353 025165 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Store.pm000644 000765 000024 00000034421 14022250537 026617 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Store; use Mojo::Base 'Mojolicious::Static'; use Mojo::File 'path'; use Mojo::Loader 'data_section'; use Mojo::Template; use Mojo::URL; use Mojolicious::Types; use Mojolicious::Plugin::AssetPack::Asset; use Mojolicious::Plugin::AssetPack::Util qw(diag checksum has_ro DEBUG); use constant CACHE_DIR => 'cache'; # MOJO_ASSETPACK_DB_FILE is used in tests use constant DB_FILE => $ENV{MOJO_ASSETPACK_DB_FILE} || 'assetpack.db'; our %DB_KEYS = map { $_ => 1 } qw(checksum format minified rel); our %FALLBACK_TEMPLATES = %{data_section(__PACKAGE__)}; for my $name (keys %FALLBACK_TEMPLATES) { my $text = delete $FALLBACK_TEMPLATES{$name}; $name =~ m!(\w+)\.ep$!; $FALLBACK_TEMPLATES{$1} = Mojo::Template->new->parse($text)->prepend('my ($c, $assets) = @_;'); } has asset_class => 'Mojolicious::Plugin::AssetPack::Asset'; has default_headers => sub { +{"Cache-Control" => "max-age=31536000"} }; has fallback_headers => sub { +{"Cache-Control" => "max-age=60"} }; has fallback_templates => sub { +{%FALLBACK_TEMPLATES} }; has _types => sub { my $t = Mojolicious::Types->new; $t->type(eot => 'application/vnd.ms-fontobject'); $t->type(otf => 'application/font-otf'); $t->type(ttf => 'application/font-ttf'); $t->type(woff2 => 'application/font-woff2'); delete $t->mapping->{$_} for qw(atom bin htm html txt xml zip); $t; }; has_ro 'ua'; has_ro _db => sub { my $self = shift; my ($db, $key, $url) = ({}); for my $path (reverse map { path($_, DB_FILE) } @{$self->paths}) { open my $DB, '<', $path or next; while (my $line = <$DB>) { ($key, $url) = ($1, $2) if $line =~ /^\[([\w-]+):(.+)\]$/; $db->{$url}{$key}{$1} = $2 if $key and $line =~ /^(\w+)=(.*)/ and $DB_KEYS{$1}; } } return $db; }; sub asset { my ($self, $urls, $paths) = @_; my $asset; for my $url (ref $urls eq 'ARRAY' ? @$urls : ($urls)) { return $self->_asset_from_helper(Mojo::URL->new($url)) if $url =~ m!^helper://!; for my $path (@{$paths || $self->paths}) { next unless $path =~ m!^https?://!; my $abs = Mojo::URL->new($path); $abs->path->merge($url); return $asset if $asset = $self->_already_downloaded($abs); } } for my $url (ref $urls eq 'ARRAY' ? @$urls : ($urls)) { return $asset if $url =~ m!^https?://! and $asset = $self->_download(Mojo::URL->new($url)); for my $path (@{$paths || $self->paths}) { if ($path =~ m!^https?://!) { my $abs = Mojo::URL->new($path); $abs->path->merge($url); return $asset if $asset = $self->_download($abs); } else { local $self->{paths} = [$path]; next unless $asset = $self->file($url); return $self->asset_class->new(url => $url, content => $asset); } } } return undef; } sub load { my ($self, $attrs) = @_; my $db_attr = $self->_db_get($attrs) or return undef; my @rel = $self->_cache_path($attrs); my $asset = $self->asset(join '/', @rel); return undef unless $asset; return undef unless $db_attr->{checksum} eq $attrs->{checksum}; diag 'Load "%s" = 1', $asset->path || $asset->url if DEBUG; return $asset; } sub persist { my $self = shift; my $db = $self->_db; my $path = path($self->paths->[0], DB_FILE); my @db_keys = sort keys %DB_KEYS; my $DB; unless (open $DB, '>', $path) { diag 'Save "%s" = 0 (%s)', $path, $! if DEBUG; return $self; } diag 'Save "%s" = 1', $path if DEBUG; for my $url (sort keys %$db) { for my $key (sort keys %{$db->{$url}}) { Carp::confess("Invalid key '$key'. Need to be [a-z-].") unless $key =~ /^[\w-]+$/; printf $DB "[%s:%s]\n", $key, $url; for my $attr (@db_keys) { next unless defined $db->{$url}{$key}{$attr}; printf $DB "%s=%s\n", $attr, $db->{$url}{$key}{$attr}; } } } return $self; } sub save { my ($self, $ref, $attrs) = @_; my $path = path($self->paths->[0], $self->_cache_path($attrs)); my $dir = $path->dirname; # Do not care if this fail. Can fallback to temp files. mkdir $dir if !-d $dir and -w $dir->dirname; diag 'Save "%s" = %s', $path, -d $dir ? 1 : 0 if DEBUG; return $self->asset_class->new(%$attrs, content => $$ref) unless -w $dir; $path->spurt($$ref); $self->_db_set(%$attrs); return $self->asset_class->new(%$attrs, path => $path); } sub serve_asset { my ($self, $c, $asset) = @_; my $dh = $self->default_headers; my $h = $c->res->headers; $h->header($_ => $dh->{$_}) for keys %$dh; $h->content_type($self->_types->type($asset->format) || 'application/octet-stream'); if (my $renderer = $asset->renderer) { $renderer->($asset, $c); } else { $self->SUPER::serve_asset($c, $asset->can('asset') ? $asset->asset : $asset); } return $self; } sub serve_fallback_for_assets { my ($self, $c, $topic, $assets) = @_; my $fh = $self->fallback_headers; my $format = $topic =~ m!\.(\w+)$! ? $1 : 'css'; my $h = $c->res->headers; $h->header($_ => $fh->{$_}) for keys %$fh; $h->content_type($self->_types->type($format) || 'application/octet-stream'); if (my $template = $self->fallback_templates->{$format}) { $c->render(data => $template->process($c, $assets)); } elsif (@$assets == 1) { my $url = $assets->[0]->url_for($c); $url->path->[-1] = $topic; $c->redirect_to($url); } else { $c->render(text => "// Invalid checksum for topic '$topic'\n", status => 404); } return $self; } sub _already_downloaded { my ($self, $url) = @_; my $asset = $self->asset_class->new(url => "$url"); my @dirname = $self->_url2path($url, ''); my $basename = pop @dirname; for my $path (map { path $_, @dirname } @{$self->paths}) { # URL with extension my $file = $path->child($basename); return $asset->format($1)->path($file) if -e $file and $file =~ m!\.(\w+)$!; # URL without extension - https://fonts.googleapis.com/css?family=Roboto for my $file ($path->list->each) { next unless $file->basename =~ /^$basename(\w+)$/; return $asset->format($1)->path($file); } } return undef; } sub _asset_from_helper { my ($self, $url) = @_; my $app = $self->ua->server->app; my $args = $url->query->to_hash; my $helper = $app->renderer->helpers->{$url->host}; my $output = $app->build_controller->$helper($url->path->[0], $args); die "[AssetPack] Unknown helper @{[$url->host]}" unless $helper; my $asset = $self->asset_class->new(url => $url, ref $output ? %$output : (content => $output)); $asset->format($args->{format}) if $args->{format}; $asset; } sub _cache_path { my ($self, $attrs) = @_; return ( CACHE_DIR, sprintf '%s-%s.%s%s', $attrs->{name}, checksum($attrs->{url}), $attrs->{minified} ? 'min.' : '', $attrs->{format} ); } sub _db_get { my ($self, $attrs) = @_; my $db = $self->_db; return undef unless my $data = $db->{$attrs->{url}}; return undef unless $data = $data->{$attrs->{key}}; return {%$attrs, %$data}; } sub _db_set { return if $ENV{MOJO_ASSETPACK_LAZY}; my ($self, %attrs) = @_; my ($key, $url) = @attrs{qw(key url)}; $self->_db->{$url}{$key} = {%attrs}; } sub _download { my ($self, $url) = @_; my %attrs = (url => $url->clone); my ($asset, $path); if ($attrs{url}->host eq 'local') { my $base = $self->ua->server->url; $url = $url->clone->scheme($base->scheme)->host_port($base->host_port); } return $asset if $attrs{url}->host ne 'local' and $asset = $self->_already_downloaded($url); my $tx = $self->ua->get($url); my $h = $tx->res->headers; if (my $err = $tx->error) { $self->_log->warn("[AssetPack] Unable to download $url: $err->{message}"); return undef; } my $ct = $h->content_type || ''; if ($ct ne 'text/plain') { $ct =~ s!;.*$!!; $attrs{format} = $self->_types->detect($ct)->[0]; } $attrs{format} ||= $tx->req->url->path->[-1] =~ /\.(\w+)$/ ? $1 : 'bin'; if ($attrs{url}->host ne 'local') { $path = path($self->paths->[0], $self->_url2path($attrs{url}, $attrs{format})); $self->_log->info(qq(Caching "$url" to "$path".)); $path->dirname->make_path unless -d $path->dirname; $path->spurt($tx->res->body); } $attrs{url} = "$attrs{url}"; return $self->asset_class->new(%attrs, path => $path) if $path; return $self->asset_class->new(%attrs)->content($tx->res->body); } sub _log { shift->ua->server->app->log } sub _url2path { my ($self, $url, $format) = @_; my $query = $url->query->to_string; my @path; push @path, $url->host; push @path, @{$url->path}; $query =~ s!\W!_!g; $path[-1] .= "_$query.$format" if $query; return CACHE_DIR, @path; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Store - Storage for assets =head1 SYNOPSIS use Mojolicious::Lite; # Load plugin and pipes in the right order plugin AssetPack => {pipes => \@pipes}; # Change where assets can be found app->asset->store->paths([ app->home->rel_file("some/directory"), "/some/other/directory", ]); # Change where assets are stored app->asset->store->paths->[0] = app->home->rel_file("some/directory"); # Define asset app->asset->process($moniker => @assets); # Retrieve a Mojolicious::Plugin::AssetPack::Asset object my $asset = app->asset->store->asset("some/file.js"); =head1 DESCRIPTION L is an object to manage cached assets on disk. The idea is that a L object can store an asset after it is processed. This will speed up development, since only changed assets will be processed and it will also allow processing tools to be optional in production environment. This module will document meta data about each asset which is saved to disk, so it can be looked up later as a unique item using L. =head1 ATTRIBUTES L inherits all attributes from L implements the following new ones. =head2 asset_class $str = $self->asset_class; $self = $self->asset_class("Mojolicious::Plugin::AssetPack::Asset"); Holds the classname of which new assets will be constructed from. =head2 default_headers $hash_ref = $self->default_headers; $self = $self->default_headers({"Cache-Control" => "max-age=31536000"}); Used to set headers used by L. =head2 fallback_headers $hash_ref = $self->fallback_headers; $self = $self->fallback_headers({"Cache-Control" => "max-age=300"}); Used to set headers used by L. This is currently an EXPERIMENTAL feature. =head2 fallback_templates $hash_ref = $self->fallback_templates; $self = $self->fallback_templates->{"css"} = Mojo::Template->new; Used to set up templates used by L. This is currently an EXPERIMENTAL feature. =head2 paths $paths = $self->paths; $self = $self->paths([$app->home->rel_file("assets")]); See L for details. =head2 ua $ua = $self->ua; See L. =head1 METHODS L inherits all attributes from L implements the following new ones. =head2 asset $asset = $self->asset($url, $paths); Returns a L object or undef unless C<$url> can be found in C<$paths>. C<$paths> default to L. C<$paths> and C<$url> can be... =over 2 =item * helper://some.mojo.helper/some_identifier?format=css Will call a helper registered under the name C, with the query parameters as arguments. Example: $output = $c->some->mojo->helper(some_identifier => {format => "css"}); C<$output> can be a scalar containing the asset content or a hash-ref with arguments passed on to L. Note that C need to be present in the URL or the returning hash-ref for this to work. This feature is currently EXPERIMENTAL. Let me know if you use it/find it interesting. =item * http://example.com/foo/bar An absolute URL will be downloaded from web, unless the host is "local": "local" is a special host which will run the request through the current L application. =item * foo/bar An relative URL will be looked up using L. =back Note that assets from web will be cached locally, which means that you need to delete the files on disk to download a new version. =head2 load $bool = $self->load($asset, \%attr); Used to load an existing asset from disk. C<%attr> will override the way an asset is looked up. The example below will ignore L and rather use the value from C<%attr>: $bool = $self->load($asset, {minified => $bool}); =head2 persist $self = $self->persist; Used to save the internal state of the store to disk. This method is EXPERIMENTAL, and may change without warning. =head2 save $bool = $self->save($asset, \%attr); Used to save an asset to disk. C<%attr> are usually the same as L and used to document metadata about the C<$asset> so it can be looked up using L. =head2 serve_asset $self = $self->serve_asset($c, $asset); Override L with the functionality to set response headers first, from L. Will call L if available, after setting Content-Type header and other L. =head2 serve_fallback_for_assets $self = $self->serve_fallback_for_assets($c, $topic, $assets); Used to serve a fallback response for given C<$topic> and a L of C objects. Will set the headers in L and then either render either a template matching the extension from C<$topic> from L, a 302 redirect to the actual asset, or a 404 Not Found. This is currently an EXPERIMENTAL feature. =head1 SEE ALSO L. =cut __DATA__ @@ fallback.css.ep % for my $asset (@$assets) { @import "<%= $asset->url_for($c) %>"; % } @@ fallback.js.ep % use Mojo::JSON 'to_json'; (function(w,d,a,b){ var c=function(){ var t=d.createElement("script"); t.src=b.shift(); if(b.length) t.addEventListener("load",c); a.parentNode.insertBefore(t,a); }; c(); })(window,document,document.getElementsByTagName("script")[0],<%= to_json([map { $_->url_for($c) } @$assets]) %>); Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/000755 000765 000024 00000000000 14023167353 026062 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Asset.pm000644 000765 000024 00000013462 14022250537 026604 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Asset; use Mojo::Base -base; use Mojo::Asset::Memory; use Mojo::URL; use Mojo::File; use Mojolicious::Plugin::AssetPack::Util qw(diag has_ro DEBUG); my %TAG_TEMPLATE; $TAG_TEMPLATE{css} = [qw(link rel stylesheet href)]; $TAG_TEMPLATE{ico} = [qw(link rel icon href)]; $TAG_TEMPLATE{js} = [qw(script src)]; $TAG_TEMPLATE{$_} = [qw(img src)] for qw(gif jpg jpeg png svg); $TAG_TEMPLATE{$_} = [qw(source src)] for qw(mp3 mp4 ogg ogv webm); has checksum => sub { Mojolicious::Plugin::AssetPack::Util::checksum(shift->content) }; has format => sub { my $self = shift; my $name = $self->url =~ /^https?:/ ? Mojo::URL->new($self->url)->path->[-1] : (split m!(\\|/)!, $self->url)[-1]; return $name =~ /\.(\w+)$/ ? lc $1 : ''; }; has minified => sub { shift->url =~ /\bmin\b/ ? 1 : 0 }; has renderer => undef; has tag_for => sub { \&_default_tag_for }; has _asset => sub { my $self = shift; return $self->content(delete $self->{content})->_asset if $self->{content}; return Mojo::Asset::File->new(path => delete $self->{path}) if $self->{path}; return Mojo::Asset::Memory->new; }; has_ro name => sub { my $self = shift; my $name; if ($self->url =~ /^https?:/) { my $url = Mojo::URL->new($self->url); my $qs = $url->query->to_string; $name = $url->path->[-1]; $qs =~ s!\W!_!g; $name =~ s!\.\w+$!!; $name .= "_$qs" if $qs; } else { $name = (split m!(\\|/)!, $self->url)[-1]; $name =~ s!\.\w+$!!; } return $name; }; has_ro 'url'; sub asset { my $self = shift; my $orig = $self->_asset; my $clone = $orig->new; if ($orig->is_file) { $clone->cleanup(0)->path($orig->path); } else { $clone->auto_upgrade(0)->mtime($orig->mtime)->add_chunk($orig->slurp); } return $clone; } sub content { my $self = shift; return $self->_asset->slurp unless @_; return $self->_asset($_[0]->_asset) if UNIVERSAL::isa($_[0], __PACKAGE__); return $self->_asset($_[0]) if UNIVERSAL::isa($_[0], 'Mojo::Asset'); return $self->_asset(Mojo::Asset::Memory->new->add_chunk($_[0])); } sub path { my $self = shift; return $self->_asset(Mojo::Asset::File->new(path => $_[0])) if $_[0]; return Mojo::File->new($self->_asset->path) if $self->_asset->isa('Mojo::Asset::File'); return undef; } sub size { $_[0]->_asset->size } sub url_for { $_[1]->url_for(assetpack => $_[0]->TO_JSON); } sub _default_tag_for { my ($asset, $c, $args, @attrs) = @_; my $url = $asset->url_for($c); my @template = @{$TAG_TEMPLATE{$asset->format} || $TAG_TEMPLATE{css}}; splice @template, 1, 0, type => $c->app->types->type($asset->format) if $template[0] eq 'source'; return $c->tag(@template, Mojo::URL->new("$args->{base_url}$url"), @attrs); } sub FROM_JSON { my ($self, $attrs) = @_; $self->$_($attrs->{$_}) for grep { defined $attrs->{$_} } qw(checksum format minified); $self; } sub TO_JSON { return {map { ($_ => $_[0]->$_) } qw(checksum format minified name url)}; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Asset - An asset =head1 DESCRIPTION L represents an asset. =head1 SYNOPSIS use Mojolicious::Plugin::AssetPack::Asset; my $asset = Mojolicious::Plugin::AssetPack::Asset->new(url => "..."); =head1 ATTRIBUTES =head2 checksum $str = $self->checksum; $self = $self->checksum($str); The L of L. =head2 format $str = $self->format; $self = $self->format($str); The format of L. Defaults to the extension of L or empty string. =head2 minified $bool = $self->minified; $self = $self->minified($bool); Will be set to true if either L contains "min" or if a pipe has minified L. =head2 name $str = $self->name; Returns the basename of L, without extension. =head2 renderer $code = $self->renderer; $self = $self->renderer(sub { my ($self, $c) = @_; $c->render(data => "...""); }) Can be used to register a custom render method for this asset. This is called by L. =head2 tag_for $code = $self->tag_for; $self = $self->tag_for(sub { my ($c, \%args, @attrs) = @_; return qq() }); Used to register a custom tag renderer for this asset. The arguments passed in are: =over 2 =item * C<$c> The L object used for this request. =item * C<%args> A hash-ref with "base_url" and L. =item * C<@attrs> The HTML attributes passed in from the template. =item =back =head2 url $str = $self->url; Returns the location of the asset. =head1 METHODS =head2 asset $asset = $self->asset; Returns a new L or L object, with the content or path from this object. This method is EXPERIMENTAL. =head2 content $bytes = $self->content; $self = $self->content($bytes); $self = $self->content(Mojo::Asset::Memory->new); Used to get or set the content of this asset. The default will be built from passing L to L. =head2 path $str = $self->path; Returns a L object that holds the location to the asset on disk or C if this asset is in memory. =head2 size $int = $self->size; Returns the size of the asset in bytes. =head2 url_for $url = $self->url_for($c); Returns a L object for this asset. C<$c> need to be a L. =head2 FROM_JSON $self = $self->FROM_JSON($hash_ref); The opposite of L. Will set the read/write L from the values in C<$hash_ref>. =head2 TO_JSON $hash_ref = $self->FROM_JSON; The opposite of L. Will generate a hash ref from L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Asset/000755 000765 000024 00000000000 14023167353 026244 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Util.pm000644 000765 000024 00000005313 14022250537 026436 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Util; use Mojo::Base 'Exporter'; use Carp 'confess'; use Mojo::Util; use constant DEBUG => $ENV{MOJO_ASSETPACK_DEBUG} || 0; use constant TESTING => $ENV{HARNESS_IS_VERBOSE} || 0; our @EXPORT = qw(checksum diag dumper has_ro load_module $CWD DEBUG); our $SUM_LEN = 10; our ($TOPIC, %LOADED); tie our ($CWD), 'Mojolicious::Plugin::AssetPack::Util::_chdir' or die q(Can't tie $CWD); sub checksum { substr Mojo::Util::sha1_sum($_[0]), 0, $SUM_LEN } sub diag { my $f = @_ > 1 ? shift : '%s'; my ($i, $pkg) = (0); while ($pkg = caller $i++) { $pkg =~ s!.*::(AssetPack::)Pipe::!$1! and last } $pkg = 'AssetPack' unless $pkg; warn sprintf "%s[%s%s] $f\n", TESTING ? "# " : "", $pkg, $TOPIC ? "/$TOPIC" : "", @_; } sub dumper { Data::Dumper->new([@_])->Indent(0)->Sortkeys(1)->Terse(1)->Useqq(1)->Dump; } sub has_ro { my ($name, $builder) = @_; my $caller = caller; $builder ||= sub { confess qq("$name" is required in constructor') }; Mojo::Util::monkey_patch( $caller => $name => sub { confess qq("$name" is read-only") if @_ > 1; $_[0]->{$name} //= $_[0]->$builder(); } ); } sub load_module { my $module = shift; confess qq(Invalid module name "$module") if ($module || '') !~ /^\w(?:[\w:']*\w)?$/; return $module if $LOADED{$module} ||= eval "require $module; 1"; confess qq(Could not load "$module": $@); } package Mojolicious::Plugin::AssetPack::Util::_chdir; use Cwd (); use File::Spec; sub TIESCALAR { bless [Cwd::getcwd], $_[0] } sub FETCH { $_[0]->[0] } sub STORE { defined $_[1] or return; my $dir = File::Spec->rel2abs($_[1]); chdir $dir or die "chdir $dir: $!"; Mojolicious::Plugin::AssetPack::Util::diag("chdir $dir") if Mojolicious::Plugin::AssetPack::Util::DEBUG >= 3; $_[0]->[0] = $dir; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Util - Utility functions for pipes =head1 DESCRIPTION L holds utility functions. =head1 SYNOPSIS use Mojolicious::Plugin::AssetPack::Util; use Mojolicious::Plugin::AssetPack::Util qw(checksum diag DEBUG) =head1 FUNCTIONS =head2 checksum $str = checksum $bytes; Used to calculate checksum of C<$bytes>. =head2 diag diag "some messsage"; diag "some %s", "messsage"; Same as C, but with a prefix. It will also use C if more than one argument is given. =head2 dumper $str = dumper $any; Dump a Perl data structure into a single line with L. =head2 has_ro Same as L, but creates a read-only attribute. =head2 load_module $module = load_module $module; Used to load a C<$module>. Will confess on failure. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Guides/000755 000765 000024 00000000000 14023167353 026405 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe.pm000644 000765 000024 00000014512 14022250537 026417 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe; use Mojo::Base -base; use File::Temp (); use IPC::Run3 (); use List::Util 'first'; use Mojo::File 'path'; use Mojo::JSON; use Mojolicious::Plugin::AssetPack::Asset; use Mojolicious::Plugin::AssetPack::Util qw(diag has_ro DEBUG); my $REQUIRE_JS = path(__FILE__)->dirname->child(qw(Pipe require.js))->realpath; $ENV{PATH} ||= ''; has topic => ''; has_ro 'assetpack'; sub app { shift->assetpack->ua->server->app } sub run { my ($self, $cmd, @args) = @_; my $name = path($cmd->[0])->basename; local $cmd->[0] = $self->_find_app($name, $cmd->[0]); die qq(@{[ref $self]} was unable to locate the "$name" application.) unless $cmd->[0]; diag '$ %s', join ' ', @$cmd if DEBUG > 1; eval { IPC::Run3::run3($cmd, @args) } or do { my $exit = $? > 0 ? $? >> 8 : $?; my $bang = int $!; die "run($cmd->[0]) failed: $@ (\$?=$exit, \$!=$bang, PATH=$ENV{PATH})"; }; } sub process { Carp::confess('Method "process" not implemented by subclass') } sub _find_app { my ($self, $apps, $path) = @_; return $path if $path and path($path)->is_abs; $apps = [$apps] unless ref $apps eq 'ARRAY'; for my $name (@$apps) { return $self->{apps}{$name} if $self->{apps}{$name}; # Already found my $key = uc "MOJO_ASSETPACK_${name}_APP"; diag 'Looking for "%s" in $%s', $name, $key if DEBUG > 1; return $ENV{$key} if $ENV{$key}; # MOJO_ASSETPACK_FOO_APP wins diag 'Looking for "%s" in $PATH.', $name if DEBUG > 1; $path = first {-e} map { path($_, $name) } File::Spec->path; return $self->{apps}{$name} = $path if $path; # Found in $PATH } my $code = $self->can(lc sprintf '_install_%s', $apps->[-1]); diag 'Calling %s->_install_%s() ...', ref $self, $apps->[-1] if DEBUG > 1; return $self->{apps}{$apps->[-1]} = $self->$code if $code; return ''; } sub _install_node_modules { my ($self, @modules) = @_; $self->run([$self->_find_app([qw(nodejs node)]), $REQUIRE_JS, @modules], \undef, \my $status); $status = Mojo::JSON::decode_json($status); for my $plugin (@modules) { next unless $status->{$plugin}; $self->app->log->warn("Installing $plugin... Please wait. (npm install $plugin)"); $self->run([npm => install => $plugin]); } } sub _install_gem { shift->_i('https://rubygems.org/pages/download') } sub _install_node { shift->_i('https://nodejs.org/en/download') } sub _install_ruby { shift->_i('https://ruby-lang.org/en/documentation/installation') } sub _i { die "@{[ref $_[0]]} requires @{[$_[1]=~/\/(\w+)/?$1:1]}. $_[1]\n" } sub _run_app { my ($self, $asset) = @_; my $output = ''; my ($tmp, @args); for my $arg (@{$self->app_args}) { if ($arg eq '$input') { $tmp = File::Temp->new; unshift @args, $tmp; push @args, "$tmp"; defined $tmp->syswrite($asset->content) or die "Can't write to file $tmp: $!"; close $tmp; } else { push @args, $arg; } } if ($tmp) { $self->run([$self->app, @args]); $output = path($tmp)->slurp; } else { $self->run([$self->app, @args], \$asset->content, \$output); } return \$output; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe - Base class for a pipe =head1 SYNOPSIS =head2 Write a custom pipe package MyApp::MyCoolPipe; use Mojo::Base "Mojolicious::Plugin::AssetPack::Pipe"; use Mojolicious::Plugin::AssetPack::Util qw(diag DEBUG); sub process { my ($self, $assets) = @_; # Normally a Mojolicious::Plugin::AssetPack::Store object my $store = $self->assetpack->store; # Loop over Mojolicious::Plugin::AssetPack::Asset objects $assets->each( sub { my ($asset, $index) = @_; # Skip every file that is not css return if $asset->format ne "css"; # Change $attr if this pipe will modify $asset attributes my $attr = $asset->TO_JSON; my $content = $asset->content; # Private name to load/save meta data under $attr->{key} = "coolpipe"; # Return asset if already processed if ($content !~ /white/ and $file = $store->load($attr)) { return $asset->content($file); } # Process asset content diag q(Replace white with red in "%s".), $asset->url if DEBUG; $content =~ s!white!red!g; $asset->content($store->save(\$content, $attr))->minified(1); } ); } =head2 Use the custom pipe use Mojolicious::Lite; plugin AssetPack => {pipes => [qw(MyApp::MyCoolPipe Css)]}; Note that the above will not load the other default pipes, such as L. =head1 DESCRIPTION This is the base class for all pipe classes. =head1 ATTRIBUTES =head2 assetpack $obj = $self->assetpack; Holds a L object. =head2 topic $str = $self->topic; $self = $self->topic("app.css"); Returns the name of the current asset topic. =head1 METHODS =head2 after_process $self->after_process(Mojo::Collection->new); L will call this method before any of the pipe L method is called. Note that this method is not defined in L! =head2 app $obh = $self->app; Returns the L application object. =head2 before_process $self->before_process(Mojo::Collection->new); L will call this method after all of the pipes L method is called. Note that this method is not defined in L! =head2 process $self->process(Mojo::Collection->new); A method used to process the assets. Each of the element in the collection will be a L object or an object with the same API. This method need to be defined in the subclass. =head2 run $self->run([som_app => @args], \$stdin, \$stdout, ...); See L for details about the arguments. This method will try to call C<_install_some_app()> unless "som_app" was found in L. This method could then try to install the application and must return the path to the installed application. =head1 SEE ALSO =over 2 =item * L =item * L =item * L =item * L =back =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Guides/Tutorial.pod000644 000765 000024 00000025167 14023166623 030726 0ustar00sristaff000000 000000 =head1 NAME Mojolicious::Plugin::AssetPack::Guides::Tutorial - AssetPack tutorial =head1 OVERVIEW This guide will give detailed information about how to define assets and include them into your templates. See L for a short description of AssetPack. =head1 GUIDE =head2 Loading the plugin The plugin needs to be installed an loaded before any assets can be defined: $app->plugin(AssetPack => \%args); Details about C<%args> can be found under L, but there is one mandatory argument worth noting: "pipes". "pipes" need to be a list of all the pipes you need to process your assets. Example: $app->plugin(AssetPack => {pipes => [qw(Sass Css Combine)]}); Loading the plugin with the list above will enable AssetPack to process Sass and Css files, minify them and combine them into a single asset in production. =head2 Optional dependencies AssetPack has only optional dependencies. The reason for that is that the dependencies should only be required while developing, and not for running the application. See L for a complete list, but here are the current list: =over 2 =item * L 0.09 Used to minify CSS. =item * L 3.3.0 Used to process and minify CSS. =item * L 0.90 TODO: Used to generate CSS sprites. =item * L 0.11 Used to minify JavaScript. =back =head2 Pipes AssetPack does not do any heavy lifting itself: All the processing is left to the L. =over 2 =item * L Process CoffeeScript coffee files. Should be loaded before L. =item * L Combine multiple assets to one. Should be loaded last. =item * L Minify CSS. =item * L There is a special topic called "favicon.ico", combined with the L pipe which can be used to describe favicons, touch icons and tile icons. =item * L Will look for "url(...)" in CSS files and download the related assets. =item * L Minify JavaScript. =item * L Used to crush "jpeg" image files. =item * L Process Less CSS files. Should be loaded before L. =item * L Used to crush "png" image files. =item * L Process L tag files. Should be loaded before L. =item * L Process sass and scss files. Should be loaded before L. =back =head2 Where to place source files The source/input files that make up a virtual asset (topic) can come from either... =head3 On disk AssetPack will look for source files in the "assets" directory, relative to the application L. Unlike the "public" directory, this directory is not shared on the internet, but the generated assets will still be available thanks to a custom L. L is a sub class of L, allowing it to find files relative to L. For example, to change asset search paths, you can do: $app->asset->store->paths(["/some/new/location", "/other/location"]); =head3 DATA section L is a sub class of L, allowing it to look for files in DATA sections of L. The DATA section can also be used to lookup "@import" files. (Currently only supported by L) =head3 Web Any file starting with "http" or "https" will be downloaded from web using L. It will also parse recursively "@import" files and download those as well. (Currently only supported by L) Assets from web will be cached locally to prevent downloading new and untested assets on each application startup. =head3 Current Mojolicious application See L. =head2 Process assets Assets should be defined when you application starts. This can either be done using a L or inside you application. =head3 Defining assets in the application Assets can be defined using the L method: $app->asset->process( "app.css" => ( "sass/bar.scss", "foo/bar.css", "https://github.com/Dogfalo/materialize/blob/master/sass/materialize.scss", ) ); In the example above we have defined a topic named "app.css" which later can be included in L. The list of files following are the source files which will make up the final asset. =head3 Defining assets in a definition file Moving the definition to an external file can be useful for keeping the application code tidy. The definition file should be located in the L directory, or optionally defined it in the "DATA" section. The default file is called "assetpack.def" and will be looked up if L is called without arguments. Example file: ! app.css < sass/bar.scss << https://github.com/Dogfalo/materialize/blob/master/sass/materialize.scss < sass/main.scss Empty lines and lines starting with "#" will be skipped. Each line starting with "!" will be used to define a topic (virtual asset name), and "E" will define a source file. This means that the file above will result in (almost) the same as in the L. The idea of the line starting with "<<" is to download an external (remote) file for your convenience, which can be imported in your SASS/LESS files. The downloaded file is not included in the output asset. For example, you have "sass/main.scss" which depends on "materialize.scss" (remote file) and you need this "materialize.scss" file locally available to be imported in "sass/main.scss". If you want to include a remote file in your output asset, use '<' insteaf of '<<'. It is also possible to add conditions: ! app.css < development.css [mode==development] [minify==0] < production.css [mode!=development] "development.css" will be processed if L is "development" and L is "0". "production.css" will be processed if L is something else than "development". This is especially useful if you want to include a JavaScript with debug flags set while developing, but switch to a smaller version without debug in production. =head2 Using assets Any processed asset can be accessed by referring to a topic. =head3 Template An asset can be included in a template using the L helper: %= asset "app.css" %= asset "app.js" The L helper takes additional arguments which will be passed on directly to either the L helper or L helper. Example: %= asset "app.css", media => "print" In production mode, the helper above will just result in one "link" tag. On the other hand, if you are in "development" mode, it will result in on "link" tag per source asset. =head3 Asset objects It is also possible to retrieve the processed asset objects. The example below will retrieve a L object holding zero or more L objects: my $collection = $app->asset->processed("app.css"); print $collection->map("checksum")->join(", "); This can also be used to inline assets in a template: %= stylesheet sub { asset->processed('app.css')->map('content')->join } =head2 Application mode The application L will define if the assets should be combined and minified. The L attribute can also be set manually if you have special needs. =head3 Development The assets will be processed, but not minified/combined if L or L is set to "development". This is to make it easier to map JavaScript or CSS bugs to a specific file and line. "development" is the default mode while running L: $ morbo -w assets/ -w lib/ -w templates/ script/myapp =head3 Any other mode Any "production" mode will result in one combined and minified asset. This will save bandwidth and roundtrip time to the server. =head2 Caching Processed assets will be cached to disk when possible. The process step is run so if such a processed asset exists, the process step will not be run again. Again, the external tools (less, coffee, ...) and modules (L, L) will only be required while developing, but can be skipped when installing an already built application. =head2 Assets without topics One nifty feature is to use L for assets which do not have any pipe to process them. The reason why this comes in handy is to avoid cache issues, since changing the file on disk will generate a new URL. These assets can also be defined directly in the templates, without having to be defined in the application startup process. Examples: # %= asset "/image/foo.gif" # %= asset "/image/baz.svg" # %= asset "/image/bar.ico" # %= asset "/audio/baz.mp3" # %= asset "/video/foo.mp4" # %= asset "/audio/bar.ogg" # %= asset "/video/foo.ogv" # %= asset "/video/bar.webm" =head1 SEE ALSO L, L and L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Guides/Developing.pod000644 000765 000024 00000004164 14023166706 031213 0ustar00sristaff000000 000000 =head1 NAME Mojolicious::Plugin::AssetPack::Guides::Developing - Developing with AssetPack =head1 OVERVIEW This guide will provide a setup for effective development with L. =head1 GUIDE =head2 Environment variables It is possible to set environment variables to change the behavior of AssetPack: =over 2 =item * MOJO_ASSETPACK_DEBUG Set this environment variable to get more debug to STDERR. Currently you can set it to a value between 0 and 3, where 3 provides the most debug. =item * MOJO_ASSETPACK_LAZY Set this environment variable if you want to delay processing the assets until they are requested. This can be very useful while developing when the assets are changed frequently. =back =head2 Faster development cycle For a faster development cycle, you can use L. This environment variable will make AssetPack only rebuild the asset that is in use on the current web page. $ MOJO_ASSETPACK_LAZY=1 morbo myapp.pl =head2 Enforcing production assets To be sure that production assets are built correctly, you can add a unit test like the one below. This is especially important if you are using L. use Test::Mojo; use Test::More; $ENV{MOJO_MODE} = "production"; my $t = Test::Mojo->new("MyApp"); $t->get_ok("/") ->element_exists(q(head link[href$="/app.css"])) ->element_exists(q(body script[src$="/app.js"])); done_testing; The C tests should match the topics defined when defining the different assets. =head1 Optional modules There are some optional modules you might want to install: =over 2 =item * L Used by L. =item * L Used by L. =item * L Required if you want to download assets served over SSL. =item * L Used by L. =back =head1 SEE ALSO L, L and L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Guides/Cookbook.pod000644 000765 000024 00000015277 14023166657 030701 0ustar00sristaff000000 000000 =head1 NAME Mojolicious::Plugin::AssetPack::Guides::Cookbook - AssetPack recipes =head1 OVERVIEW This guide will provide recipes for cooking with L. =head1 ASSETS FROM CUSTOM DOMAIN You might want to serve the assets from a domain different from where the main app is running. The reasons for that might be: =over 2 =item * No cookies send on each request. This is especially useful when you use L sessions as they are stored in cookies and clients send whole session with every request. =item * More requests done in parallel. Browsers have limits for sending parallel request to one domain. With separate domain static files can be loaded in parallel. =item * Serve files directly (by absolute url) from CDN (or Amazon S3). =back =head2 Synopsis You need to customize L to accomplish this: $app->asset->route->to(base_url => "http://cdn.example.com/my-assets/"); =head2 Caveat Many recent browsers blocks mixed content, meaning if your HTML is served over HTTPS, then you can't serve the assets over HTTP. One way to fix this is by using "//" instead of a scheme specific URL. Example: base_url => "//cdn.example.com/my-assets/" This will tell the browser to use the same scheme for fetching assets, as it did fetching the web page. =head2 See also L. =head1 DYNAMIC ASSETS Any L asset with the hostname "local" will be routed to the current L application. Example: $ cat assetpack.def ! app.js < http://local/some/resource.js The above URL will make AssetPack issue a request to the current Mojolicious application, allowing it to render dynamic JavaScript. Example Mojolicious resource: get "/some/resource" => [format => "js"], sub { my $c = shift; $c->render(text => sprintf "rand = %s\n", rand); }; =head2 Sass Sass files can also be generated dynamically. Here is an example Sass file: @import "http://local/sass/dynamic"; $color: red !default; body { color: $color; } Normally, the C<@import> statement would be left untouched, but AssetPack will (in the special case where the host is "local") inline the result from that resource. This allow C<$color> to be set from the application and override the default C<$color> in the file above. Example: get "/sass/_dynamic" => [format => "scss"], sub { my $c = shift; $c->render(text => "\$color: black;\n"); }; Note that this feature is EXPERIMENTAL and not compatible with standard Sass rules. =head1 ONLINE ASSETS Instead of making custom AssetPack plugins, it is possible to simply include projects such as Bootstrap, FontAwesome or jQuery directly from the web instead. =head2 Bootstrap The SASS version of L can easily be included by defining it in the L file: $ cat - > assets/assetpack.def ! app.css < https://github.com/twbs/bootstrap-sass/raw/master/assets/stylesheets/_bootstrap.scss After that, you might want to customize bootstrap. This can then be done by changing "assetpack.def" to: ! app.css << https://github.com/twbs/bootstrap-sass/raw/master/assets/stylesheets/_bootstrap.scss < sass/main.scss "assets/sass/main.scss" should then have a modified version of L: @import "variables.scss"; @import "../cache/github.com/twbs/bootstrap-sass/raw/master/assets/stylesheets/bootstrap/mixins"; @import "../cache/github.com/twbs/bootstrap-sass/raw/master/assets/stylesheets/bootstrap/normalize"; @import "../cache/github.com/twbs/bootstrap-sass/raw/master/assets/stylesheets/bootstrap/print"; ... The file "_variables.scss" should also be copied to "assets/sass". (Note that the rest of the example file above is truncated) =head2 Font awesome L can be included with the snippet below: $app->asset->process( "app.css" => ( "https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css", ) ); See also L for information about automatically fetching related font files. =head2 Google fonts L can be included with this snippet: $app->asset->process( "app.css" => ( "https://fonts.googleapis.com/css?family=Roboto:400,700", "your-app.css", ) ); =head2 JavaScript polyfills L contains a list of many shims which can be included. Here is just one example: $app->asset->process( "app.js" => ( "http://cdnjs.cloudflare.com/ajax/libs/es5-shim/2.3.0/es5-shim.js", "http://cdnjs.cloudflare.com/ajax/libs/es5-shim/2.3.0/es5-sham.js", "your-app.js", ) ); =head2 jQuery L can easily be included by referring to a CDN: $app->asset->process( "app.js" => ( "http://code.jquery.com/jquery-1.12.0.js", "your-app.js", ) ); =head2 Materialize CSS L can be included by defining it in the L file. L will also discover all the "@import" files and download those recusively as well. $ cat - > assets/assetpack.def ! app.css < https://raw.githubusercontent.com/Dogfalo/materialize/master/sass/materialize.scss < https://fonts.googleapis.com/icon?family=Material+Icons After that, you might want to customize Materialize. This can then be done by changing "assetpack.def" to: ! app.css << https://raw.githubusercontent.com/Dogfalo/materialize/master/sass/materialize.scss < https://fonts.googleapis.com/icon?family=Material+Icons < sass/main.scss "assets/sass/main.scss" should then have a modified version of L: @charset "UTF-8"; @import "../cache/raw.githubusercontent.com/Dogfalo/materialize/master/sass/components/prefixer"; @import "../cache/raw.githubusercontent.com/Dogfalo/materialize/master/sass/components/mixins"; @import "../cache/raw.githubusercontent.com/Dogfalo/materialize/master/sass/components/color"; @import "variables.scss"; ... The file "_variables.scss" should also be copied to "assets/sass". (Note that the rest of the example file above is truncated) =head1 SEE ALSO L, L and L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Asset/Null.pm000644 000765 000024 00000000774 14022250537 027520 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Asset::Null; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Asset'; 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Asset::Null - Skipped asset =head1 DESCRIPTION L is a subclass of L with no new functionality. The special thing about this class is that it will be ignored when generating output assets. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/Riotjs.pm000644 000765 000024 00000003715 14022250537 027674 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::Riotjs; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojo::File 'path'; use Mojolicious::Plugin::AssetPack::Util qw(diag $CWD DEBUG); has _riotjs => sub { [shift->_find_app([qw(nodejs node)]), path(__FILE__)->dirname->child('riot.js')] }; sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; my $file; $assets->each(sub { my ($asset, $index) = @_; my $attrs = $asset->TO_JSON; $attrs->{key} = 'riot'; $attrs->{format} = 'js'; return unless $asset->format eq 'tag'; return $asset->content($file)->FROM_JSON($attrs) if $file = $store->load($attrs); local $CWD = $self->app->home->to_string; local $ENV{NODE_PATH} = $self->app->home->rel_file('node_modules'); $self->run([qw(riot --version)], undef, \undef) unless $self->{installed}++; $self->run($self->_riotjs, \$asset->content, \my $js); $asset->content($store->save(\$js, $attrs))->FROM_JSON($attrs); }); } sub _install_riot { my $self = shift; my $path = $self->app->home->rel_file('node_modules/.bin/riot'); return $path if -e $path; local $CWD = $self->app->home->to_string; $self->app->log->warn('Installing riot... Please wait. (npm install riot)'); $self->run([qw(npm install riot)]); return $path; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::Riotjs - Process Riotjs .tag files =head1 SYNOPSIS use Mojolicious::Lite; plugin AssetPack => {pipes => [qw(Riotjs JavaScript)]}; Note that the above will not load the other default pipes, such as L. =head1 DESCRIPTION L will process L ".tag" files. This module require L to compile Riotjs tag files. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/typescript.js000644 000765 000024 00000001044 14022250537 030621 0ustar00sristaff000000 000000 #!/usr/bin/env node 'use strict' // TODO: Get these from environment, set by Pipe::TypeScript var compilerOptions = {noImplicitAny: true}; var tss = require('typescript-simple'); if (process.stdin.isTTY) { console.log('typescript-simple is installed'); process.exit(); } var stdin = process.stdin; var stdout = process.stdout; var content = ''; stdin.resume(); stdin.setEncoding('utf8'); stdin.on('data', function (chunk) { content += chunk; }); stdin.on('end', function () { stdout.write(tss(content, compilerOptions)); }); Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/Fetch.pm000644 000765 000024 00000005221 14022250537 027445 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::Fetch; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojolicious::Plugin::AssetPack::Util qw(diag DEBUG); use Mojo::URL; # Only made public for quick fixes. Subject for change our %FORMATS = ( css => { re => qr{url\((['"]{0,1})(.*?)\1\)}, pos => sub { my ($start, $url, $quotes) = @_; my $len = length $url; return $start - length($quotes) - $len - 1, $len; }, }, js => { re => qr{(//\W*sourceMappingURL=)(\S+)}m, pos => sub { my ($start, $url) = @_; my $len = length $url; return $start - $len, $len; }, }, ); sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; my $route = $self->assetpack->route; my %related; return $assets->each(sub { my ($asset, $index) = @_; return unless $asset->url =~ /^https?:/; return unless my $format = $FORMATS{$asset->format}; my $base = Mojo::URL->new($asset->url); my $content = $asset->content; my $re = $format->{re}; while ($content =~ /$re/g) { my @matches = ($2, $1); my $url = $matches[0]; next if $url =~ /^(?:\#|data:)/; # Avoid "data:image/svg+xml..." and "#foo" $url = Mojo::URL->new($url); $url = $url->base($base)->to_abs->fragment(undef) unless $url->is_abs; unless ($related{$url}) { diag "Fetch resource $url" if DEBUG; my $related = $store->asset($url) or die "AssetPack was unable to fetch related asset $url"; $self->assetpack->process($related->name, $related); my $path = $route->render($related->TO_JSON); $path =~ s!^/!!; my $up = join '', map {'../'} $path =~ m!\/!g; $related{$url} = "$up$path"; } my ($start, $len) = $format->{pos}->(pos($content), @matches); substr $content, $start, $len, Mojo::URL->new($related{$url})->query(Mojo::Parameters->new); pos($content) = $start + $len; } $asset->content($content); }); } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::Fetch - Fetch related assets =head1 SYNOPSIS use Mojolicious::Lite; plugin AssetPack => {pipes => [qw(Css Fetch)]}; app->asset->process( "app.css" => "https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" ); =head1 DESCRIPTION L will look for "url()" in a CSS file and fetch the resource from the remote location. Note that this pipe is EXPERIMENTAL and subject for change. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/Combine.pm000644 000765 000024 00000003211 14022250537 027765 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::Combine; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojolicious::Plugin::AssetPack::Util qw(checksum diag DEBUG); has enabled => sub { shift->assetpack->minify }; sub process { my ($self, $assets) = @_; my $combine = Mojo::Collection->new; my @other; return unless $self->enabled; for my $asset (@$assets) { if ($asset->isa('Mojolicious::Plugin::AssetPack::Asset::Null')) { next; } elsif (grep { $asset->format eq $_ } qw(css js)) { push @$combine, $asset; } else { push @other, $asset; } } # preserve assets such as images and font files @$assets = @other; if (@$combine) { my $checksum = checksum $combine->map('checksum')->join(':'); my $content = $combine->map('content')->map(sub { /\n$/ ? $_ : "$_\n" })->join; diag 'Combining assets into "%s" with checksum %s.', $self->topic, $checksum if DEBUG; push @$assets, Mojolicious::Plugin::AssetPack::Asset->new(url => $self->topic)->checksum($checksum)->minified(1) ->content($content); } } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::Combine - Combine multiple assets to one =head1 DESCRIPTION L will take a list of assets and turn them into a single asset. =head1 ATTRIBUTES $bool = $self->enabled; Set this to false to disable combining assets into a single file. The default value will be L. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/Vuejs.pm000644 000765 000024 00000004602 14022250537 027512 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::Vuejs; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; return $assets->each(sub { my ($asset, $index) = @_; return unless $asset->format eq 'vue'; my $vue = sprintf 'Vue.component("%s", {', $asset->name; my ($script, $template); if ($asset->content =~ m!]*>(.+)!s) { $script = $1; $vue = "$1$vue" if $script =~ s!^(.*)\s?module\.exports\s*=\s*\{!!s; $script =~ s!\s*\}\s*;?\s*$!!s; $vue .= $script; } if ($asset->content =~ m!]*>(.+)!s) { $template = $1; $template =~ s!"!\\"!g; # escape all double quotes $template =~ s!^\s*!!s; $template =~ s!\r?\n!\\n!g; $vue .= qq',\n' if $script; $vue .= qq' template: "$template"'; } $vue = Mojo::Util::encode('UTF-8', "(function(){$vue})})();"); $asset->content($vue)->format('js'); }); } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::Vuejs - Process .vue files =head1 DESCRIPTION This modules is EXPERIMENTAL and based on homebrewed regexes instead of running the code through an external nodejs binary! This pipe could get pulled completely from the L distribution if the problem is too hard to solve. =head1 SYNOPSIS Currently only C The vuejs file above produces this output: (function(){ var initial = false; Vue.component("example", { data: function() { return {id: id, loading: initial} }, methods: { toggle: function() { this.loading = !this.loading; } }, template: " Example {{loading ? \"loading\" : \"click me!\"}} "}))(); =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/TypeScript.pm000644 000765 000024 00000004201 14022250537 030517 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::TypeScript; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojo::File 'path'; use Mojolicious::Plugin::AssetPack::Util qw(diag $CWD DEBUG); has _typescript => sub { my $self = shift; return [$self->_find_app([qw(nodejs node)]), path(__FILE__)->dirname->child('typescript.js')->to_abs,]; }; sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; my $file; $assets->each(sub { my ($asset, $index) = @_; my $attrs = $asset->TO_JSON; $attrs->{key} = 'ts'; $attrs->{format} = 'js'; return unless $asset->format eq 'ts'; return $asset->content($file)->FROM_JSON($attrs) if $file = $store->load($attrs); $self->_install_typescript unless $self->{installed}++; local $CWD = $self->app->home->to_string; local $ENV{NODE_PATH} = $self->app->home->rel_file('node_modules'); $self->run($self->_typescript, \$asset->content, \my $js); $asset->content($store->save(\$js, $attrs))->FROM_JSON($attrs); }); } sub _install_typescript { my $self = shift; # TODO: This is a bit fragile, since tsc is not part of typescript-simple my $path = $self->app->home->rel_file('node_modules/.bin/tsc'); return 1 if -e $path; local $CWD = $self->app->home->to_string; $self->app->log->warn('Installing typescript-simple... Please wait. (npm install typescript-simple)'); $self->run([qw(npm install typescript-simple)]); } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::TypeScript - Process TypeScript .ts files =head1 SYNOPSIS $app->plugin(pipes => [qw(TypeScript JavaScript Combine)]); $app->asset->process("app.js" => qw(foo.ts)); =head1 DESCRIPTION L will process L files into JavaScript. This module require the C nodejs library to be installed. C will be automatically installed using L unless already installed. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/Sass.pm000644 000765 000024 00000016753 14022250537 027341 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::Sass; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojolicious::Plugin::AssetPack::Util qw(checksum diag dumper load_module DEBUG); use Mojo::File; use Mojo::JSON qw(decode_json encode_json); use Mojo::Util; my $FORMAT_RE = qr{^s[ac]ss$}; my $IMPORT_RE = qr{ (?:^|[\n\r]+) ([^\@\r\n]*) (\@import \s+ (["']) (.*?) \3 \s* ;)}sx; my $SOURCE_MAP_PLACEHOLDER = sprintf '__%s__', __PACKAGE__; $SOURCE_MAP_PLACEHOLDER =~ s!::!_!g; has functions => sub { +{} }; has generate_source_map => sub { shift->app->mode eq 'development' ? 1 : 0 }; sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; my %opts = (include_paths => [undef, @{$self->assetpack->store->paths}]); my $file; for my $name (keys %{$self->functions}) { my $cb = $self->functions->{$name}; $opts{sass_functions}{$name} = sub { $self->$cb(@_); }; } if ($self->generate_source_map) { $opts{source_map_file} = $SOURCE_MAP_PLACEHOLDER; $opts{source_map_file_urls} = $self->app->mode eq 'development' ? 1 : 0; } return $assets->each(sub { my ($asset, $index) = @_; return if $asset->format !~ $FORMAT_RE; my ($attrs, $content) = ($asset->TO_JSON, $asset->content); local $self->{checksum_for_file} = {}; local $opts{include_paths}[0] = _include_path($asset); $attrs->{minified} = $self->assetpack->minify; $attrs->{key} = sprintf 'sass%s', $attrs->{minified} ? '-min' : ''; $attrs->{format} = 'css'; $attrs->{checksum} = $self->_checksum(\$content, $asset, $opts{include_paths}); return $asset->content($file)->FROM_JSON($attrs) if $file = $store->load($attrs); return if $asset->isa('Mojolicious::Plugin::AssetPack::Asset::Null'); $opts{include_paths}[0] = $asset->path ? $asset->path->dirname : undef; $opts{include_paths} = [grep {$_} @{$opts{include_paths}}]; diag 'Process "%s" with checksum %s.', $asset->url, $attrs->{checksum} if DEBUG; if ($self->{has_module} //= eval { load_module 'CSS::Sass'; 1 }) { $opts{output_style} = _output_style($attrs->{minified}); $content = CSS::Sass::sass2scss($content) if $asset->format eq 'sass'; my ($css, $err, $stats) = CSS::Sass::sass_compile($content, %opts); if ($err) { die sprintf '[Pipe::Sass] Could not compile "%s" with opts=%s: %s', $asset->url, dumper(\%opts), $err; } $css = Mojo::Util::encode('UTF-8', $css); $self->_add_source_map_asset($asset, \$css, $stats) if $stats->{source_map_string}; $asset->content($store->save(\$css, $attrs))->FROM_JSON($attrs); } else { my @args = (qw(sass -s), map { ('-I', $_) } @{$opts{include_paths}}); push @args, '--scss' if $asset->format eq 'scss'; push @args, qw(-t compressed) if $attrs->{minified}; $self->run(\@args, \$content, \my $css, undef); $asset->content($store->save(\$css, $attrs))->FROM_JSON($attrs); } }); } sub _add_source_map_asset { my ($self, $asset, $css, $stats) = @_; my $data = decode_json $stats->{source_map_string}; my $source_map = Mojolicious::Plugin::AssetPack::Asset->new(url => sprintf('%s.css.map', $asset->name)); # override "stdin" with real file $data->{file} = sprintf 'file://%s', $asset->path if $asset->path; $data->{sources}[0] = $data->{file}; $source_map->content(encode_json $data); my $relative = join '/', '..', $source_map->checksum, $source_map->url; $$css =~ s!$SOURCE_MAP_PLACEHOLDER!$relative!; # TODO $self->assetpack->{by_checksum}{$source_map->checksum} = $source_map; $self->assetpack->{by_topic}{$source_map->url} = Mojo::Collection->new($source_map); } sub _checksum { my ($self, $ref, $asset, $paths) = @_; my $ext = $asset->format; my $store = $self->assetpack->store; my @c = (checksum $$ref); SEARCH: while ($$ref =~ /$IMPORT_RE/gs) { my $pre = $1; my $rel_path = $4; my $mlen = length $2; my @rel = split '/', $rel_path; my $name = pop @rel; my $start = pos($$ref) - $mlen; my $dynamic = $rel_path =~ m!http://local/!; my @basename = ("_$name", $name); next if $pre =~ m{^\s*//}; # Follow sass rules for skipping, # ...with exception for special assetpack handling for dynamic sass include next if $rel_path =~ /\.css$/; next if $rel_path =~ m!^https?://! and !$dynamic; unshift @basename, "_$name.$ext", "$name.$ext" unless $name =~ /\.$ext$/; my $imported = $store->asset([map { join '/', @rel, $_ } @basename], $paths) or die qq([Pipe::Sass] Could not find "$rel_path" file in @$paths); if ($imported->path) { diag '@import "%s" (%s)', $rel_path, $imported->path if DEBUG >= 2; local $paths->[0] = _include_path($imported); push @c, $self->_checksum(\$imported->content, $imported, $paths); } else { diag '@import "%s" (memory)', $rel_path if DEBUG >= 2; pos($$ref) = $start; substr $$ref, $start, $mlen, $imported->content; # replace "@import ..." with content of asset push @c, $imported->checksum; } } return checksum join ':', @c; } sub _include_path { my $asset = shift; return $asset->url if $asset->url =~ m!^https?://!; return $asset->path->dirname if $asset->path; return ''; } sub _install_sass { my $self = shift; $self->run([qw(ruby -rubygems -e), 'puts Gem.user_dir'], undef, \my $base); chomp $base; my $path = Mojo::File->new($base, qw(bin sass)); return $path if -e $path; $self->app->log->warn('Installing sass... Please wait. (gem install --user-install sass)'); $self->run([qw(gem install --user-install sass)]); return $path; } sub _output_style { return $_[0] ? CSS::Sass::SASS_STYLE_COMPRESSED() : CSS::Sass::SASS_STYLE_NESTED(); } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::Sass - Process sass and scss files =head1 SYNOPSIS =head2 Application plugin AssetPack => {pipes => [qw(Sass Css Combine)]}; $self->pipe("Sass")->functions({ q[image-url($arg)] => sub { my ($pipe, $arg) = @_; return sprintf "url(/assets/%s)", $_[1]; } }); =head2 Sass file The sass file below shows how to use the custom "image-url" function: body { background: #fff image-url('img.png') top left; } =head1 DESCRIPTION L will process sass and scss files. This module require either the optional module L or the C program to be installed. C will be automatically installed using L unless already available. =head1 ATTRIBUTES =head2 functions $hash_ref = $self->functions; Used to define custom SASS functions. Note that the functions will be called with C<$self> as the first argument, followed by any arguments from the SASS function. This invocation is EXPERIMENTAL, but will hopefully not change. This attribute requires L to work. It will not get passed on to the C executable. See L for example. =head2 generate_source_map $bool = $self->generate_source_map; $self = $self->generate_source_map(1); This pipe will generate source maps if true. Default is "1" if L is "development". See also L and L for more information about the usefulness. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/Jpeg.pm000644 000765 000024 00000003765 14022250537 027314 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::Jpeg; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojolicious::Plugin::AssetPack::Util qw(diag DEBUG); has app => 'jpegoptim'; has app_args => sub { my $self = shift; return [DEBUG ? ('-v') : ('-q'), qw(-f --stdin --stdout)] if $self->app eq 'jpegoptim'; return []; }; sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; my $file; return $assets->each(sub { my ($asset, $index) = @_; my $attrs = $asset->TO_JSON; $attrs->{key} = sprintf '%s-min', $self->app; $attrs->{minified} = 1; return if $asset->format !~ /^jpe?g$/ or $asset->minified; return unless $self->assetpack->minify; return $asset->content($file)->minified(1) if $file = $store->load($attrs); diag 'Process "%s", with checksum %s.', $asset->url, $attrs->{checksum} if DEBUG; $asset->content($store->save($self->_run_app($asset), $attrs))->FROM_JSON($attrs); }); } sub _install_jpegoptim { my $self = shift; my $class = ref $self; die "$class requires https://github.com/tjko/jpegoptim"; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::Jpeg - Crush JPEG image files =head1 DESCRIPTION L can be used to crush "jpeg" image files. This pipe is EXPERIMENTAL. Feedback wanted. =head1 ATTRIBUTES =head2 app $str = $self->app; $self = $self->app("jpegoptim"); Can be used to set a custom application instead of "jpegoptim". =head2 app_args $array = $self->app_args; $self = $self->app_args([qw(-f --stdin --stdout)]); Can be used to set custom L arguments. The special C<$input> string in the argument list will be replaced with the path to a temp file holding the image data. If no C<$input> element is found in the L list, then STDIN and STDOUT will be used instead. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/Favicon.pm000644 000765 000024 00000015706 14022250537 030012 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::Favicon; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojo::DOM; use Mojo::JSON qw(false true); use Mojo::Template; use Mojo::Util; use Mojolicious::Plugin::AssetPack::Util 'checksum'; # this should be considered private use constant API_URL => $ENV{MOJO_ASSETPACK_FAVICON_API_URL} || 'https://realfavicongenerator.net/api/favicon'; has api_key => sub { die 'api_key() must be set' }; has design => sub { shift->_build_design }; has settings => sub { +{error_on_image_too_small => Mojo::JSON->true} }; sub process { my ($self, $assets) = @_; return unless $self->topic =~ m!^favicon(\.\w+)?\.ico$!; my $store = $self->assetpack->store; my $asset = $assets->first; my $attrs = $asset->TO_JSON; my ($urls, $markup, %sub_assets); $attrs->{key} = checksum(Mojo::JSON::encode_json($self->design)) or die '[AssetPack] Invalid pipe("Favicon")->design({})'; if (my $db = $store->load($attrs)) { ($urls, $markup) = split /__MARKUP__/, $db->content; $urls = [grep {/\w/} split /\n/, $urls]; } else { ($urls, $markup) = $self->_fetch($asset); $db = join "\n", @$urls, __MARKUP__ => $markup; $store->save(\$db, $attrs); } my $renderer = sub { my ($asset, $c, $args, @attrs) = @_; my $content = $asset->content; $content =~ s!"/([^.]+\.\w{3,})"!sprintf '"%s"', $sub_assets{$1} ? $sub_assets{$1}->url_for($c) : $1!ge; return $content if $args; return $c->render(data => $content); }; for my $url (@$urls) { my $asset = $store->asset($url) or die "AssetPack was unable to fetch icons/assets asset $url"; $sub_assets{join '.', $asset->name, $asset->format} = $asset; $asset->renderer($renderer) if $asset->format =~ m!(manifest|xml|webapp)$!; $self->assetpack->{by_checksum}{$asset->checksum} = $asset; } unless ($markup =~ m!msapplication-config!) { $markup =~ s![\r\n]+$!!; $markup .= qq(\n); } $asset->content($markup)->tag_for($renderer); } sub _build_design { my $self = shift; my $name = ref $self->app; my $bg_color = '#F5F5F5'; my $theme_color = '#536DFE'; return { desktop_browser => {}, android_chrome => { manifest => {display => 'standalone', name => $name, orientation => 'portrait'}, picture_aspect => 'shadow', theme_color => $theme_color, }, firefox_app => { background_color => $bg_color, circle_inner_margin => '5', keep_picture_in_circle => 'true', picture_aspect => 'circle', manifest => {app_description => '', app_name => $name, developer_name => '', developer_url => '',} }, ios => {background_color => $bg_color, margin => '4', picture_aspect => 'background_and_margin',}, safari_pinned_tab => {picture_aspect => 'black_and_white', threshold => 60, theme_color => $theme_color,}, windows => { background_color => $theme_color, picture_aspect => "white_silhouette", assets => { windows_80_ie_10_tile => true, windows_10_ie_11_edge_tiles => {big => true, medium => true, rectangle => false, small => false}, } }, }; } sub _fetch { my ($self, $asset) = @_; $self->assetpack->ua->inactivity_timeout(60); my $res = $self->assetpack->ua->post(API_URL, json => $self->_request($asset))->res; unless ($res->code eq '200') { my $json = $res->json || {}; die sprintf '[AssetPack] Could not generate favicon: %s', $json->{favicon_generation_result}{result}{error_message} || $res->error->{message}; } my $data = $res->json->{favicon_generation_result}{favicon}; my $files = $data->{files_urls} || []; my $markup = $data->{html_code} or die qq|[AssetPack] No html_code generated. Invalid pipe("Favicon")->design({})..?|; return ($files, $markup) if @$files; die qq|[AssetPack] No favicons generated. Invalid pipe("Favicon")->design({})..?|; } sub _request { my ($self, $asset) = @_; return { favicon_generation => { api_key => $self->api_key, favicon_design => $self->design, settings => $self->settings, files_location => {type => 'path', path => '/'}, master_picture => {content => Mojo::Util::b64_encode($asset->content), type => 'inline'} } }; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::Favicon - Generate favicons =head1 SYNOPSIS =head2 Application plugin AssetPack => {pipes => ["Favicon"]}; app->asset->pipe("Favicon")->api_key("fd27cc5654345678765434567876545678765556"); app->asset->process("favicon.ico" => "images/favicon.png"); # Can also register variations of the favicon: app->asset->process("favicon.variant1.ico" => "images/favicon1.png"); app->asset->process("favicon.variant2.ico" => "images/favicon2.png"); Note that the topic must be either "favicon.ico" or "favicon.some_identifier.ico". The input image file should be a 260x260 PNG file for optimal results. =head2 Template %= asset "favicon.ico" The above template will expand to whatever HTML that L has generated, based on L. Example: By default this pipe will only create desktop icons. Configure L for more icons. =head1 DESCRIPTION L uses L to generate all the different favicons that is required for your site. This pipe is EXPERIMENTAL. Let me know if you are using it. =head1 ATTRIBUTES =head2 api_key $self = $self->api_key($key); $str = $self->api_key; An API key obtained from L. =head2 design $hash = $self->design; $self = $self->design({desktop_browser => {}, ios => {}, windows => {}}); Can be used to customize the different designs. Look for "favicon_design" on L for details. =head2 settings $hash = $self->settings; $self = $self->settings({compression => 3}); Can be used to customize the different settings. Look for "settings" on L for details. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. L. L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/require.js000644 000765 000024 00000000361 14022250537 030070 0ustar00sristaff000000 000000 var modules = {}; for (var i = 2; i < process.argv.length; i++) { var name = process.argv[i]; try { require(name); modules[name] = ""; } catch (err) { modules[name] = err.code; } } console.log(JSON.stringify(modules)); Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/Css.pm000644 000765 000024 00000002507 14022250537 027150 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::Css; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojolicious::Plugin::AssetPack::Util qw(diag load_module DEBUG); sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; my $file; return unless $self->assetpack->minify; return $assets->each(sub { my ($asset, $index) = @_; my $attrs = $asset->TO_JSON; $attrs->{key} = 'css-min'; $attrs->{minified} = 1; return if $asset->format ne 'css' or $asset->minified; return $asset->content($file)->minified(1) if $file = $store->load($attrs); load_module 'CSS::Minifier::XS'; diag 'Minify "%s" with checksum %s.', $asset->url, $asset->checksum if DEBUG; my $css = CSS::Minifier::XS::minify($asset->content); $asset->content($store->save(\$css, $attrs))->minified(1); }); } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::Css - Minify CSS =head1 DESCRIPTION L will minify your "css" assets if L is true and the asset is not already minified. This module requires the optional module L to minify. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/Png.pm000644 000765 000024 00000005764 14022250537 027154 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::Png; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojolicious::Plugin::AssetPack::Util qw(diag DEBUG); has app => 'pngquant'; has app_args => sub { my $self = shift; return [DEBUG ? () : ('-quiet'), qw(-clobber -preserve $input)] if $self->app eq 'optipng'; return [DEBUG ? ('-v') : (), qw(--speed 2 -)] if $self->app eq 'pngquant'; return []; }; sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; my $file; return $assets->each(sub { my ($asset, $index) = @_; my $attrs = $asset->TO_JSON; $attrs->{key} = sprintf '%s-min', $self->app; $attrs->{minified} = 1; return if $asset->format ne 'png' or $asset->minified; return unless $self->assetpack->minify; return $asset->content($file)->minified(1) if $file = $store->load($attrs); diag 'Process "%s", with checksum %s.', $asset->url, $attrs->{checksum} if DEBUG; $asset->content($store->save($self->_run_app($asset), $attrs))->FROM_JSON($attrs); }); } sub _install_optipng { my $self = shift; my $class = ref $self; my $app = $^O eq 'darwin' ? 'brew' : 'apt-get'; # not very nice die "$class requires http://optipng.sourceforge.net/ '$app install optipng'"; } sub _install_pngquant { my $self = shift; my $class = ref $self; my $app = $^O eq 'darwin' ? 'brew' : 'apt-get'; # not very nice die "$class requires https://pngquant.org/ '$app install pngquant'"; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::Png - Crush PNG image files =head1 SYNOPSIS =head2 Application plugin AssetPack => {pipes => ["Png"]}; # Forces the use of "optipng -clobber -preserve $input" app->asset->pipe("Png")->app("optipng"); # Forces the use of "pngquant --speed 2 -" app->asset->pipe("Png")->app("pngquant"); # Set custom application arguments: app->asset->pipe("Png")->app("pngquant")->app_args([qw(--speed 10 --ordered -)]); =head1 DESCRIPTION L can be used to crush "png" image files. This plugin has default settings for "pngquant" (default) and "optipng". Which will be the default in the future is unknown, so force the one you want in case that matters. This pipe is EXPERIMENTAL. Feedback wanted. TODO: Detect which application is installed and use the best available. TODO: Add support for pngcrush. =head1 ATTRIBUTES =head2 app $str = $self->app; $self = $self->app("pngquant"); Can be used to set a custom application. =head2 app_args $array = $self->app_args; $self = $self->app_args([qw(-clobber $input)]); Can be used to set custom L arguments. The special C<$input> string in the argument list will be replaced with the path to a temp file holding the image data. If no C<$input> element is found in the L list, then STDIN and STDOUT will be used instead. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/CoffeeScript.pm000644 000765 000024 00000003176 14022250537 030777 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::CoffeeScript; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojolicious::Plugin::AssetPack::Util qw(diag $CWD DEBUG); sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; my $file; $assets->each(sub { my ($asset, $index) = @_; return if $asset->format ne 'coffee'; my $attrs = $asset->TO_JSON; @$attrs{qw(format key)} = qw(js coffee); return $asset->content($file)->FROM_JSON($attrs) if $file = $store->load($attrs); diag 'Process "%s" with checksum %s.', $asset->url, $attrs->{checksum} if DEBUG; $self->run([qw(coffee --compile --stdio)], \$asset->content, \my $js); $asset->content($store->save(\$js, $attrs))->FROM_JSON($attrs); }); } sub _install_coffee { my $self = shift; my $path = $self->app->home->rel_file('node_modules/.bin/coffee'); return $path if -e $path; local $CWD = $self->app->home->to_string; $self->app->log->warn('Installing coffeescript... Please wait. (npm install coffeescript)'); $self->run([qw(npm install coffeescript)]); return $path; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::CoffeeScript - Process CoffeeScript =head1 DESCRIPTION L will process L files into JavaScript. This module require the C program to be installed. C will be automatically installed using L unless already installed. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/JavaScript.pm000644 000765 000024 00000002507 14022250537 030466 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::JavaScript; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojolicious::Plugin::AssetPack::Util qw(diag load_module DEBUG); sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; my $file; return unless $self->assetpack->minify; return $assets->each(sub { my ($asset, $index) = @_; my $attrs = $asset->TO_JSON; $attrs->{key} = 'js-min'; $attrs->{minified} = 1; return if $asset->format ne 'js' or $asset->minified; return $asset->content($file)->minified(1) if $file = $store->load($attrs); return unless length(my $js = $asset->content); load_module 'JavaScript::Minifier::XS'; diag 'Minify "%s" with checksum %s.', $asset->url, $asset->checksum if DEBUG; $js = JavaScript::Minifier::XS::minify($js); $asset->content($store->save(\$js, $attrs))->minified(1); }); } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::JavaScript - Minify JavaScript =head1 DESCRIPTION L will minify your "js" assets if L is true and the asset is not already minified. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/riot.js000644 000765 000024 00000000472 14022250537 027374 0ustar00sristaff000000 000000 #!/usr/bin/env node 'use strict' var riot = require('riot') var stdin = process.stdin; var stdout = process.stdout; var content = ''; stdin.resume(); stdin.setEncoding('utf8'); stdin.on('data', function (chunk) { content += chunk; }); stdin.on('end', function () { stdout.write(riot.compile(content)); }); Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/Less.pm000644 000765 000024 00000003412 14022250537 027322 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::Less; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojolicious::Plugin::AssetPack::Util qw(diag $CWD DEBUG); sub process { my ($self, $assets) = @_; my $store = $self->assetpack->store; my $file; $assets->each(sub { my ($asset, $index) = @_; return if $asset->format ne 'less'; my $attrs = $asset->TO_JSON; @$attrs{qw(format key)} = qw(css less); return $asset->content($file)->FROM_JSON($attrs) if $file = $store->load($attrs); diag 'Process "%s" with checksum %s.', $asset->url, $attrs->{checksum} if DEBUG; my @args = qw(lessc --no-color); my $file = $asset->path ? $asset : Mojo::Asset::File->new->add_chunk($asset->content); push @args, '--include-path=' . $asset->path->dirname if $asset->path; push @args, $file->path; $self->run(\@args, undef, \my $css); $asset->content($store->save(\$css, $attrs))->FROM_JSON($attrs); }); } sub _install_lessc { my $self = shift; my $bin = $self->app->home->rel_file('node_modules/.bin/lessc'); return $bin if -e $bin; local $CWD = $self->app->home->to_string; $self->app->log->warn('Installing lessc... Please wait. (npm install less)'); $self->run([qw(npm install less)]); return $bin; } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::Less - Process Less CSS files =head1 DESCRIPTION L will process L files into JavaScript. This module require the C executable to be installed. C will be automatically installed using L unless already installed. =head1 METHODS =head2 process See L. =head1 SEE ALSO L. =cut Mojolicious-Plugin-AssetPack-2.13/lib/Mojolicious/Plugin/AssetPack/Pipe/RollupJs.pm000644 000765 000024 00000013077 14022250537 030176 0ustar00sristaff000000 000000 package Mojolicious::Plugin::AssetPack::Pipe::RollupJs; use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; use Mojo::File qw(path tempfile); use Mojo::JSON qw(encode_json false true); use Mojo::Loader; use Mojolicious::Plugin::AssetPack::Util qw(diag $CWD DEBUG); has external => sub { [] }; has globals => sub { {} }; has modules => sub { [] }; has plugins => sub { my $self = shift; my @plugins; push @plugins, ['rollup-plugin-node-resolve', 'resolve', {}]; push @plugins, ['rollup-plugin-commonjs', 'commonjs', {sourceMap => true}]; push @plugins, ['rollup-plugin-terser', '{terser}' => {}] if $self->assetpack->minify; return \@plugins; }; has _rollupjs => sub { my $self = shift; my $bin = Mojo::Loader::data_section(__PACKAGE__, 'rollup.js'); my (@import, @plugins); for (@{$self->plugins}) { my ($plugin, $import, $args) = @$_; my $func = $import; $func =~ s!\{\s*(.+)\s*\}!$1!; push @import, sprintf "const %s = %s;\n", $import, $import =~ m!^\s*\{! ? qq[require("$plugin")] : qq[_interopDefault(require("$plugin"))]; push @plugins, sprintf '%s(%s)', $func, defined $args ? encode_json $args : ''; } $bin =~ s!__EXTERNAL__!{encode_json $self->external}!e; $bin =~ s!__GLOBALS__!{encode_json $self->globals}!e; $bin =~ s!__SOURCEMAP__!{$self->app->mode eq 'development' ? 1 : 0}!e; $bin =~ s!__IMPORT__!{join '', @import}!e; $bin =~ s!__PLUGINS__!{join ',', @plugins}!e; if (DEBUG > 2) { $self->{_rollupjs_src} = path(File::Spec->tmpdir, 'assetpack-rollup.js'); diag "[RollupJs] Keeping $self->{_rollupjs_src} around."; } else { $self->{_rollupjs_src} = tempfile(SUFFIX => '.js'); } $self->{_rollupjs_src}->spurt($bin); return [$self->_find_app([qw(nodejs node)]), $self->{_rollupjs_src}->realpath]; }; sub add_global { $_[0]->globals->{$_[1]} = $_[2]; $_[0]; } sub process { my ($self, $assets) = @_; my $minify = $self->assetpack->minify; my $store = $self->assetpack->store; my $file; delete $self->{$_} for qw(_rollupjs _rollupjs_src); $assets->each(sub { my ($asset, $index) = @_; my $attrs = $asset->TO_JSON; return unless $asset->format eq 'js'; return unless $asset->path and -r $asset->path; return unless $asset->content =~ /\bimport\s.*\bfrom\b/s; $attrs->{key} = 'rollup'; $attrs->{minified} = $minify; return $asset->content($file)->FROM_JSON($attrs) if $file = $store->load($attrs); local $CWD = $self->app->home->to_string; local $ENV{NODE_ENV} = $self->app->mode; local $ENV{NODE_PATH} = $self->app->home->rel_file('node_modules'); $self->_install_node_modules('rollup', @{$self->modules}, map { $_->[0] } @{$self->plugins}) unless $self->{installed}++; $self->run([@{$self->_rollupjs}, $asset->path, _module_name($asset->name)], undef, \my $js); $asset->content($store->save(\$js, $attrs))->FROM_JSON($attrs); }); } sub _module_name { local $_ = $_[0]; s!\W!_!g; lcfirst(Mojo::Util::camelize($_)) } 1; =encoding utf8 =head1 NAME Mojolicious::Plugin::AssetPack::Pipe::RollupJs - Use Rollup.js module bundler =head1 SYNOPSIS use Mojolicious::Lite; plugin AssetPack => {pipes => [qw(RollupJs)]}; =head1 DESCRIPTION Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. See L for more details. =head1 ATTRIBUTES =head2 external $array_ref = $self->external; $self = $self->external(["vue"]); Comma-separate list of module IDs to exclude. =head2 globals $hash_ref = $self->globals; $self = $self->globals({vue => "Vue"}); See L. Any module IDs defined here are added to L. =head2 modules $array_ref = $self->modules; $self = $self->modules(["vue"]); List of NPM modules that the JavaScript application depends on. =head2 plugins $array_ref = $self->plugins; $self = $self->plugins([ [$module_name, $import_statement, $import_function_args], ["rollup-plugin-vue", "VuePlugin"], ["rollup-plugin-node-resolve", "resolve", {}], ["rollup-plugin-commonjs", "commonjs", {sourceMap => false}], ]); List of NPM modules that should be loaded by Rollup.js. =head1 METHODS =head2 add_global $self = $self->add_global($key => $value); $self = $self->add_global(qw(vue Vue)); Used to add a key/value pair to L. =head2 process See L. =head1 SEE ALSO L. =cut __DATA__ @@ rollup.js #!/usr/bin/env node "use strict" const globals = __GLOBALS__; const external = __EXTERNAL__; const rollup = require("rollup"); const stdout = process.stdout; function _interopDefault(i) { return i && typeof i === "object" && "default" in i ? i["default"] : i; } __IMPORT__ Object.keys(globals).forEach(function(g) { external.push(g) }); const inputOptions = { input: process.argv[2], external: function(name) { return external.indexOf(name) != -1 }, plugins: [__PLUGINS__] }; const outputOptions = { format: "iife", globals: globals, name: process.argv[3], sourcemap: "inline", // TODO banner: process.env.ROLLUP_BANNER, footer: process.env.ROLLUP_FOOTER, intro: process.env.ROLLUP_INTRO, outro: process.env.ROLLUP_OUTRO }; async function build() { const bundle = await rollup.rollup(inputOptions); const { code, map } = await bundle.generate(outputOptions); stdout.write(code); if (__SOURCEMAP__) stdout.write("\n//# sourceMappingURL=" + map + "\n"); } build(); Mojolicious-Plugin-AssetPack-2.13/.github/workflows/000755 000765 000024 00000000000 14023167353 022404 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/.github/PULL_REQUEST_TEMPLATE.md000644 000765 000024 00000000322 14022250537 024141 0ustar00sristaff000000 000000 ### Summary DESCRIBE THE BIG PICTURE OF YOUR CHANGES HERE ### Motivation EXPLAIN WHY YOU BELIEVE THESE CHANGES ARE NECESSARY HERE ### References LIST RELEVANT ISSUES, PULL REQUESTS AND FORUM DISCUSSIONS HERE Mojolicious-Plugin-AssetPack-2.13/.github/ISSUE_TEMPLATE.md000644 000765 000024 00000000514 14022250537 023050 0ustar00sristaff000000 000000 * Mojolicious::Plugin::AssetPack version: VERSION HERE * Perl version: VERSION HERE * Operating system: NAME AND VERSION HERE ### Steps to reproduce the behavior EXPLAIN WHAT HAPPENED HERE, PREFERABLY WITH CODE EXAMPLES ### Expected behavior EXPLAIN WHAT SHOULD HAPPEN HERE ### Actual behavior EXPLAIN WHAT HAPPENED INSTEAD HERE Mojolicious-Plugin-AssetPack-2.13/.github/CONTRIBUTING.md000644 000765 000024 00000000260 14022250537 022572 0ustar00sristaff000000 000000 Please read the guide for [contributing to Mojolicious](http://mojolicious.org/perldoc/Mojolicious/Guides/Contributing), Mojolicious::Plugin::AssetPack follows the same rules. Mojolicious-Plugin-AssetPack-2.13/.github/workflows/perltidy.yml000644 000765 000024 00000001135 14022250537 024757 0ustar00sristaff000000 000000 name: perltidy on: push: branches: - '*' tags-ignore: - '*' pull_request: jobs: perltidy: runs-on: ubuntu-latest container: image: perl:5.32 steps: - uses: actions/checkout@v2 - name: perl -V run: perl -V - name: Install dependencies run: cpanm -n Perl::Tidy - name: perltidy --version run: perltidy --version - name: Run perltidy shell: bash run: | shopt -s extglob globstar nullglob perltidy --pro=.../.perltidyrc -b -bext='/' **/*.p[lm] **/*.t && git diff --exit-code Mojolicious-Plugin-AssetPack-2.13/.github/workflows/linux.yml000644 000765 000024 00000001421 14022250537 024260 0ustar00sristaff000000 000000 name: linux on: push: branches: - '*' tags-ignore: - '*' pull_request: jobs: perl: runs-on: ubuntu-latest strategy: matrix: perl-version: - '5.16' - '5.18' - '5.20' - '5.22' - '5.30' - '5.32' container: image: perl:${{ matrix.perl-version }} steps: - uses: actions/checkout@v2 - name: perl -V run: perl -V - name: Fix ExtUtils::MakeMaker (for Perl 5.16 and 5.18) run: cpanm -n App::cpanminus ExtUtils::MakeMaker - name: Install dependencies run: | cpanm -n --installdeps . cpanm -n Test::Pod Test::Pod::Coverage - name: Run tests run: prove -l t env: TEST_POD: 1 Mojolicious-Plugin-AssetPack-2.13/examples/rollup.pl000644 000765 000024 00000001565 14022250732 022477 0ustar00sristaff000000 000000 #!/usr/bin/env perl die "Run $0 from ./mojo-assetpack/ root" unless -d 't/assets'; use lib 'lib'; use Mojolicious::Lite; use Mojo::File 'path'; plugin 'AssetPack' => {pipes => ['RollupJs']}; app->asset->store->paths([path('t/assets')->to_abs]); # Add Vuejs as dependencies app->asset->pipe('RollupJs')->add_global(vue => 'Vue'); push @{app->asset->pipe('RollupJs')->modules}, 'vue-template-compiler'; push @{app->asset->pipe('RollupJs')->plugins}, ['rollup-plugin-vue', 'vue']; # Process js/vue-app.js app->asset->process('app.js' => 'js/vue-app.js'); # Set up the mojo lite application and start it get '/' => 'index'; app->start; __DATA__ @@ index.html.ep Test!
%= asset 'app.js'; Mojolicious-Plugin-AssetPack-2.13/examples/sprites.pl000644 000765 000024 00000001123 14022250537 022644 0ustar00sristaff000000 000000 #!perl use lib "lib"; use Mojolicious::Lite; app->static->paths([Cwd::abs_path("t/public")]); plugin "AssetPack"; app->asset("my-sprites.css" => "sprites:///images/xyz", "/test.css"); get "/" => "index"; app->start; __DATA__ @@ test.css .xyz { background-color: #f00; } @@ index.html.ep Sprites %= asset "my-sprites.css" CSS sprites Mojolicious-Plugin-AssetPack-2.13/examples/not-found.pl000644 000765 000024 00000001264 14022250710 023063 0ustar00sristaff000000 000000 #!/usr/bin/env perl die "Run $0 from ./mojo-assetpack/ root" unless -d 't/assets'; use lib 'lib'; use Mojolicious::Lite; plugin 'AssetPack' => {pipes => [qw(Css JavaScript)]}; app->asset->store->paths(['t/assets']); app->asset->process('app.css' => 'css/c.css'); app->asset->process('app.js' => 'js/not-found.js'); # Set up the mojo lite application and start it get '/' => 'index'; app->start; __DATA__ @@ index.html.ep Test!

Check the console for debug messages

And the background should be gray.

Mojolicious-Plugin-AssetPack-2.13/t/recreate.t000644 000765 000024 00000002631 14022250537 021227 0ustar00sristaff000000 000000 BEGIN { $ENV{MOJO_MODE} = 'not_development' } use lib '.'; use t::Helper; use Mojo::File 'path'; use Mojo::Loader 'data_section'; use Mojolicious::Plugin::AssetPack::Util 'checksum'; # simulate minify() no warnings 'once'; $INC{'CSS/Minifier/XS.pm'} = 'mocked'; *CSS::Minifier::XS::minify = sub { local $_ = shift; s!\s+!!g; $_ }; my $t = t::Helper->t(pipes => [qw(Css Combine)]); my @assets = qw(one.css recreate.css); my $recreate = path(qw(t assets recreate.css)); $recreate->spurt(".recreate { color: #aaa }\n"); $t->app->asset->process('app.css' => @assets); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href\$="/app.css"])); my $link = $t->tx->res->dom->at('link')->{href}; # use cached $t = t::Helper->t(pipes => [qw(Css Combine)]); $t->app->asset->process('app.css' => @assets); $t->get_ok('/')->status_is(200); is $t->tx->res->dom->at('link')->{href}, $link, 'same link href'; # recreate $recreate->spurt(".recreate { color: #bbb }\n"); my $tr = t::Helper->t(pipes => [qw(Css Combine)]); $tr->app->asset->process('app.css' => @assets); $tr->get_ok('/')->status_is(200); isnt $tr->tx->res->dom->at('link')->{href}, $link, 'changed link href'; $tr->get_ok($tr->tx->res->dom->at('link')->{href})->status_is(200)->content_like(qr{color:\#bbb}); # reset asset $recreate->spurt(".recreate { color: #aaa }\n"); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ one.css .one { color: #aaa } Mojolicious-Plugin-AssetPack-2.13/t/sass-unable-to-download.t000644 000765 000024 00000002166 14022250537 024102 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_ONLINE=1' unless $ENV{TEST_ONLINE} or -e '.test-everything'; plan skip_all => 'cpanm CSS::Sass' unless eval 'use CSS::Sass 3.3.0;1'; my ($t, @message); my $url = 'https://raw.githubusercontent.com/select2/select2/master/src/scss/core.scss'; run(); ok + (grep {/Caching/} @message), 'cached assets' or diag join ',', @message; ok + (grep {/Unable to download.*_layout\.scss/} @message), 'unable to download' or map { diag $_ } @message; run(); ok !(grep {/Caching/} @message), 'assets are already cached' or diag join ',', @message; ok !(grep {/Unable to download.*_layout\.scss/} @message), 'assets are already downloaded' or diag join ',', @message; done_testing; sub run { @message = (); $t = t::Helper->t(pipes => ['Sass']); $t->app->log->on(message => sub { shift; push @message, join ' ', @_ }); $t->app->asset->process('app.css' => $url); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link[href]')->{href} || '/nope')->status_is(200)->content_like(qr{select2}); } __DATA__ @@ index.html.ep %= asset 'app.css' Mojolicious-Plugin-AssetPack-2.13/t/range.t000644 000765 000024 00000001036 14022250537 020527 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; my $t = t::Helper->t(pipes => [qw(Css Combine)]); $t->app->asset->process; $t->get_ok('/')->status_is(200); my $href = $t->tx->res->dom->at('link')->{href}; ok $href, 'found link[href]'; $t->get_ok($href => {Range => 'bytes=0-2'})->status_is(206)->header_is('Accept-Ranges' => 'bytes')->content_is('.on'); $t->get_ok($href)->status_is(200)->header_is('Accept-Ranges' => 'bytes')->content_like(qr{color:}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ assetpack.def ! app.css < css-0-one.css Mojolicious-Plugin-AssetPack-2.13/t/sass-dynamic-include.t000644 000765 000024 00000001411 14022250537 023444 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'cpanm CSS::Sass' unless eval 'use CSS::Sass 3.3.0;1'; my $t = t::Helper->t(pipes => ['Sass']); $t->app->routes->get( '/custom/asset/sass/variables' => [format => 'scss'], sub { shift->render(text => "\$color: black;\n"); } ); $t->app->asset->process('app.css' => 'dynamic.scss'); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_unlike(qr{\@import}) ->content_like(qr{body.*black}s); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ dynamic.scss @charset "UTF-8"; // @import "skip/this"; // Variables @import "http://local/custom/asset/sass/variables.scss"; // special case that AssetPack handles $color: red !default; body { color: $color; } Mojolicious-Plugin-AssetPack-2.13/t/less.t000644 000765 000024 00000001554 14022250537 020406 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_LESS=1' unless $ENV{TEST_LESS} or -e '.test-everything'; my $t = t::Helper->t(pipes => [qw(Less Css Combine)]); $t->app->asset->process('app.css' => 'foo.less'); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/fd1bf3a731/foo.css"])); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_like(qr{-webkit-box-shadow:}) ->content_like(qr{color:\s*\#fe33ac}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ foo.less @base: #f938ab; .box-shadow(@style, @c) when (iscolor(@c)) { -webkit-box-shadow: @style @c; box-shadow: @style @c; } .box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) { .box-shadow(@style, rgba(0, 0, 0, @alpha)); } .box { color: saturate(@base, 5%); border-color: lighten(@base, 30%); div { .box-shadow(0 0 5px, 30%) } } Mojolicious-Plugin-AssetPack-2.13/t/rollup.t000644 000765 000024 00000002513 14022250537 020751 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_ROLLUP=1' unless $ENV{TEST_ROLLUP} or -e '.test-everything'; # Development mode my $t = t::Helper->t(pipes => [qw(RollupJs Combine)]); $t->app->asset->process('app.js' => 'js/some-lib.js'); $t->get_ok('/')->status_is(200)->element_exists(qq(script[src="/asset/693887ef13/some-lib.js"])); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200)->content_like(qr{someLib\W+=\W+function}); # Production mode $ENV{MOJO_MODE} = 'Test_minify_from_here'; $t = t::Helper->t(pipes => [qw(RollupJs Combine)]); $t->app->asset->process('app.js' => 'js/some-lib.js'); $t->get_ok('/')->status_is(200)->element_exists(qq(script[src="/asset/96b3f18ab2/app.js"])); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200)->content_like(qr{someLib=\W*function}); # With modules and plugins $t = t::Helper->t(pipes => [qw(RollupJs Combine)]); $t->app->asset->pipe('RollupJs')->add_global(vue => 'Vue'); push @{$t->app->asset->pipe('RollupJs')->modules}, 'vue-template-compiler'; push @{$t->app->asset->pipe('RollupJs')->plugins}, ['rollup-plugin-vue', 'vue']; $t->app->asset->process('app.js' => 'js/vue-app.js'); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200)->content_like(qr{\bVue\b}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.js' Mojolicious-Plugin-AssetPack-2.13/t/bin/000755 000765 000024 00000000000 14023167353 020022 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/t/other.t000644 000765 000024 00000002366 14022250537 020563 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; my %expected_element = ( gif => q(img[src="/asset/d220f096b3/dummy.gif"]), ico => q(link[rel="icon"][href="/asset/40c24538f4/dummy.ico"]), mp3 => q(source[type="audio/mpeg"][src="/asset/1710ca7e28/dummy.mp3"]), mp4 => q(source[type="video/mp4"][src="/asset/228088807c/dummy.mp4"]), ogg => q(source[type="audio/ogg"][src="/asset/641f8d27ad/dummy.ogg"]), ogv => q(source[type="video/ogg"][src="/asset/cbfe0298bd/dummy.ogv"]), svg => q(img[src="/asset/64705cb07d/dummy.svg"]), webm => q(source[type="video/webm"][src="/asset/fc19b68890/dummy.webm"]), ); my $t = t::Helper->t(pipes => ['Combine']); for my $ext (sort keys %expected_element) { my $attr = $ext =~ /ico/ ? 'href' : 'src'; $t->get_ok('/')->status_is(200)->element_exists($expected_element{$ext}, $ext); next unless my $elem = $t->tx->res->dom->at($expected_element{$ext}); $t->get_ok($elem->{$attr})->status_is(200)->header_is('Content-Type' => $t->app->types->type($ext)); } done_testing; __DATA__ @@ index.html.ep hey! %= asset '/other/dummy.gif' %= asset '/other/dummy.ico' %= asset '/other/dummy.mp3' %= asset '/other/dummy.mp4' %= asset '/other/dummy.ogg' %= asset '/other/dummy.ogv' %= asset '/other/dummy.svg' %= asset '/other/dummy.webm' Mojolicious-Plugin-AssetPack-2.13/t/typescript.t000644 000765 000024 00000000757 14022250537 021652 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_TYPESCRIPT=1' unless $ENV{TEST_TYPESCRIPT} or -e '.test-everything'; my $t = t::Helper->t(pipes => ['TypeScript']); $t->app->asset->process('app.js' => 'foo.ts'); $t->get_ok('/')->status_is(200)->element_exists(qq(script[src="/asset/8e77d0ac51/foo.js"])); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200)->content_like(qr{var n = 1;}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.js' @@ foo.ts var n: number = 1; Mojolicious-Plugin-AssetPack-2.13/t/route.t000644 000765 000024 00000000747 14022250537 020601 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; my $t = t::Helper->t(pipes => ['Css']); is_deeply([sort { length $a <=> length $b } routes()], ['/'], 'one route'); $t->app->asset->process('app.css' => 'one.css'); is_deeply([sort { length $a <=> length $b } routes()], ['/', '/asset/:checksum/*name'], 'two routes'); done_testing; sub routes { my $r = shift || $t->app->routes; return map { (($_->pattern->unparsed || '/'), routes($_)) } @{$r->children}; } __DATA__ @@ one.css .one { color: #000; } Mojolicious-Plugin-AssetPack-2.13/t/vuejs.t000644 000765 000024 00000001632 14022250537 020571 0ustar00sristaff000000 000000 BEGIN { $ENV{MOJO_MODE} = 'not_development' } use lib '.'; use t::Helper; my $t = t::Helper->t(pipes => ['Vuejs']); $t->app->asset->process('app.js' => 'vue/example.vue'); $t->get_ok('/')->status_is(200)->element_exists(qq(script[src="/asset/23d7a115e2/example.js"])); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200) ->content_like(qr[^\Q(function(){\E], 'starts with function') ->content_like(qr[\Q)})();\E], 'ends with calling function') ->content_like(qr[\Qvar initial = false;\E], 'var initial') ->content_like(qr[\QVue.component("example"\E.*data:.*methods:.*template:.*\);]s, 'vue') ->content_like(qr[\Q\"loading\"\E], 'quotes espcaped in template')->content_unlike(qr["loading"]); done_testing; __DATA__ @@ index.html.ep %= asset 'app.js' Mojolicious-Plugin-AssetPack-2.13/t/jquery-mobile.t000644 000765 000024 00000000725 14022250537 022223 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_ONLINE=1' unless $ENV{TEST_ONLINE}; my $t = t::Helper->t(pipes => [qw(Css Fetch)]); $t->app->asset->process('app.css' => 'http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css'); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200) ->content_like(qr{\Qurl(../../asset/2edfb2ffe3/ajax-loader.gif)\E}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' Mojolicious-Plugin-AssetPack-2.13/t/sass.t000644 000765 000024 00000004641 14022250537 020411 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'cpanm CSS::Sass' unless eval 'use CSS::Sass 3.3.0;1'; my $t = t::Helper->t(pipes => [qw(Sass Css)]); $t->app->asset->process('app.css' => ('sass-one.sass', 'sass-two.scss')); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/5660087922/sass-one.css"])) ->element_exists(qq(link[href="/asset/a2245cadf4/sass-two.css"])); my $html = $t->tx->res->dom; $t->get_ok($html->at('link:nth-of-child(1)')->{href})->status_is(200)->content_like(qr{\.sass\W+color:\s+\#aaa}s); $t->get_ok($html->at('link:nth-of-child(2)')->{href})->status_is(200) ->content_like(qr{body\W+background:.*\.scss \.nested\W+color:\s+\#9\d9\d9\d}s); $ENV{MOJO_MODE} = 'Test_minify_from_here'; # Assets from __DATA__ $t = t::Helper->t(pipes => [qw(Sass Css Combine)]); $t->app->asset->process('app.css' => ('sass-one.sass', 'sass-two.scss')); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/08eb78e42a/app.css"])); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_like(qr/\nbody\{background:#fff\}/); if (-e '.test-everything') { my @content = split /[\r?\n]/, $t->tx->res->text; is $content[0], '.sass{color:#aaa}', 'line1'; is $content[1], 'body{background:#fff}.scss{color:#aaa}.scss .nested{color:#939393}', 'line2'; } Mojo::Util::monkey_patch('CSS::Sass', sass2scss => sub { die 'Nope!' }); $t = t::Helper->t(pipes => [qw(Sass Css Combine)]); ok eval { $t->app->asset->process('app.css' => ('sass-one.sass', 'sass-two.scss')) }, 'using cached assets' or diag $@; # Assets from disk $t = t::Helper->t(pipes => [qw(Sass Css Combine)]); $t->app->asset->process('app.css' => 'sass/sass-1.scss'); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/4abbb4a8c8/app.css"])); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_like(qr{footer.*\#aaa.*body.*\#222}s); # Duplicate @import $t = t::Helper->t(pipes => [qw(Sass Css Combine)]); ok eval { $t->app->asset->process('dup.css' => 'sass/sass-2-dup.scss') }, 'sass with duplicate @imports' or diag $@; done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ sass-one.sass $color: #aaa; .sass color: $color; @@ sass-two.scss // .foo { @import "sass-two.scss"; }`). @import "sass-0-include"; $color: #aaa; .scss { color: $color; .nested { color: darken($color, 9%); } } @@ sass-0-include.scss body { background: #fff; } Mojolicious-Plugin-AssetPack-2.13/t/sass-bin.t000644 000765 000024 00000002561 14022250537 021156 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_SASS=1' unless $ENV{TEST_SASS} or -e '.test-everything'; my $t = t::Helper->t(pipes => [qw(Sass Css)]); my $sass = $t->app->asset->pipe('Sass'); isa_ok($sass, 'Mojolicious::Plugin::AssetPack::Pipe::Sass'); $sass->{has_module} = ''; # make sure CSS::Sass is not used $t->app->asset->process('app.css' => ('sass.sass', 'sass/sass-1.scss')); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/8d347a7a6f/sass.css"])) ->element_exists(qq(link[href="/asset/71dcf0669a/sass-1.css"])); my $html = $t->tx->res->dom; $t->get_ok($html->at('link:nth-of-child(1)')->{href})->status_is(200)->content_like(qr{\.sass\W+color:\s+\#aaa}s); $t->get_ok($html->at('link:nth-of-child(2)')->{href})->status_is(200)->content_like(qr{footer.*\#aaa.*body.*\#222}s); $ENV{MOJO_MODE} = 'Test_minify_from_here'; $t = t::Helper->t(pipes => [qw(Sass Css Combine)]); $t->app->asset->pipe('Sass')->{has_module} = ''; # make sure CSS::Sass is not used $t->app->asset->process('app.css' => ('sass.sass', 'sass/sass-1.scss')); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_unlike(qr/[ ]/) ; # No spaces in minified version done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ sass.sass $color: #aaa .sass color: $color Mojolicious-Plugin-AssetPack-2.13/t/base-url.t000644 000765 000024 00000000712 14022250537 021145 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; $ENV{MOJO_MODE} = 'development'; my $t = t::Helper->t(pipes => [qw(Css)]); $t->app->asset->process; $t->app->asset->route->to(base_url => '//cdn.example.com/my-assets/'); $t->get_ok('/')->status_is(200)->content_like(qr{="//cdn.example.com/my-assets/asset/ec4c05a328/css-0-two.css"}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ assetpack.def ! app.css < css-0-two.css @@ css-0-one.css .one { color: #000; } Mojolicious-Plugin-AssetPack-2.13/t/sass-utf8.t000644 000765 000024 00000000624 14022250537 021272 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; use utf8; plan skip_all => 'cpanm CSS::Sass' unless eval 'use CSS::Sass 3.3.0;1'; my $t = t::Helper->t(pipes => ['Sass']); $t->app->asset->process('app.css' => ('sass/70-utf8.scss')); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_like(qr{コメント}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' Mojolicious-Plugin-AssetPack-2.13/t/sass-source-map.t000644 000765 000024 00000002031 14022250537 022451 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'cpanm CSS::Sass' unless eval 'use CSS::Sass 3.3.0;1'; plan skip_all => 'cpanm CSS::Sass' unless $ENV{TEST_SOURCE_MAPS}; my $t = t::Helper->t(pipes => [qw(Sass)]); $t->app->asset->process('app.css' => 'sass/sass-1.scss'); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/71dcf0669a/sass-1.css"])); $t->get_ok('/asset/71dcf0669a/sass-1.css')->status_is(200) ->content_like(qr{sourceMappingURL=\.\./8f89310ec6/sass-1\.css\.map}); $t->get_ok('/asset/8f89310ec6/sass-1.css.map')->json_like('/file', qr{sass-1\.scss})->json_has('/mappings') ->json_has('/sources')->json_has('/version'); $ENV{MOJO_MODE} = 'development_required'; $t = t::Helper->t(pipes => [qw(Sass)]); $t->app->asset->process('app.css' => 'sass/sass-1.scss'); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/71dcf0669a/sass-1.css"])); $t->get_ok('/asset/71dcf0669a/sass-1.css')->status_is(200)->content_unlike(qr{sourceMappingURL}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' Mojolicious-Plugin-AssetPack-2.13/t/fetch-source-map.t000644 000765 000024 00000002006 14022250537 022573 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_ONLINE=1' unless $ENV{TEST_ONLINE} or -e '.test-everything'; my $t = t::Helper->t(pipes => ['Fetch']); $t->app->asset->process('app.js' => 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js'); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200) ->content_like(qr{\QsourceMappingURL=../../asset/0bf00b0aa8/angular.min.js.map\E}); $t->get_ok('/asset/0bf00b0aa8/angular.min.js.map')->status_is(200); $ENV{MOJO_MODE} = 'production'; $t = t::Helper->t(pipes => [qw(Fetch Combine)]); $t->app->asset->process('app.js' => 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js'); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200) ->content_like(qr{\QsourceMappingURL=../../asset/0bf00b0aa8/angular.min.js.map\E}); $t->get_ok('/asset/0bf00b0aa8/angular.min.js.map')->status_is(200); done_testing; __DATA__ @@ index.html.ep %= asset 'app.js' Mojolicious-Plugin-AssetPack-2.13/t/png.t000644 000765 000024 00000002146 14022250537 020222 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; # This part does not required optipng my $t = t::Helper->t(pipes => [qw(Png Combine)]); $t->app->asset->process('test.png' => '/image/sample.png'); $t->get_ok('/')->status_is(200)->element_exists(qq(img[src="/asset/348b799a81/sample.png"])); $t->get_ok($t->tx->res->dom->at('img')->{src})->status_is(200)->header_is('Content-Type' => 'image/png'); my $len = $t->tx->res->headers->content_length; diag "original size: $len"; if ($ENV{TEST_PNG}) { $ENV{MOJO_MODE} = 'production'; for my $app (qw(pngquant optipng)) { $t = t::Helper->t(pipes => [qw(Png Combine)]); $t->app->asset->pipe('Png')->app($app); $t->app->asset->process('test.png' => '/image/sample.png'); $t->get_ok('/')->status_is(200)->element_exists(qq(img[src="/asset/348b799a81/sample.png"])); $t->get_ok($t->tx->res->dom->at('img')->{src})->status_is(200)->header_is('Content-Type' => 'image/png') ->header_isnt('Content-Length' => $len); my $len2 = $t->tx->res->headers->content_length; diag "$app size: $len2"; } } done_testing; __DATA__ @@ index.html.ep cool image! %= asset 'test.png' Mojolicious-Plugin-AssetPack-2.13/t/js.t000644 000765 000024 00000001615 14022250537 020052 0ustar00sristaff000000 000000 BEGIN { $ENV{MOJO_MODE} = 'not_development' } use lib '.'; use t::Helper; use Mojo::Loader 'data_section'; use Mojolicious::Plugin::AssetPack::Util 'checksum'; plan skip_all => 'cpanm JavaScript::Minifier::XS' unless eval 'require JavaScript::Minifier::XS;1'; my $t = t::Helper->t(pipes => [qw(JavaScript Combine)]); my $checksum = checksum join ':', map { checksum(data_section __PACKAGE__, $_) } 'd/one.js', 'd/two.js'; $t->app->asset->process('app.js' => ('d/one.js', 'd/two.js')); $t->get_ok('/')->status_is(200)->element_exists(qq(script[src="/asset/$checksum/app.js"])); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200)->header_is('Content-Type', 'application/javascript') ->content_like(qr/function\(\)\{console/s); done_testing; __DATA__ @@ index.html.ep %= asset 'app.js' @@ d/one.js (function() { console.log('one') })(); @@ d/two.js (function() { console.log('two') })(); Mojolicious-Plugin-AssetPack-2.13/t/google-font.t000644 000765 000024 00000002662 14022250537 021661 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_ONLINE=1' unless $ENV{TEST_ONLINE} or -e '.test-everything'; my $t1 = t::Helper->t(pipes => [qw(Css Fetch)]); $t1->app->asset->process('app.css' => 'https://fonts.googleapis.com/css?family=Roboto:400,700'); $t1->get_ok('/')->status_is(200); # comment from https://github.com/hugeinc/flexboxgrid-sass/blob/master/demo/sass/_code.scss $t1->get_ok($t1->tx->res->dom->at('link')->{href})->status_is(200)->header_is('Content-Type', 'text/css') ->content_like(qr{font-family:\W*Roboto})->content_like(qr{\Qurl(../../asset/\E\w+/.*\.ttf\)}); my $cache_file = File::Spec->catfile(qw(t assets cache fonts.googleapis.com css_family_Roboto_400_700.css)); ok -e $cache_file, 'cache file does not contain weird characters'; Mojo::Util::monkey_patch('Mojo::UserAgent', 'get' => sub { shift; die "Should get font from cache! @_" }); my $t2 = t::Helper->t(pipes => [qw(Css Fetch)]); $t2->app->asset->process('app.css' => 'http://fonts.googleapis.com/css?family=Roboto:400,700'); $t2->get_ok('/'); $t2->get_ok($t2->tx->res->dom->at('link')->{href})->status_is(200)->header_is('Content-Type', 'text/css') ->content_like(qr{font-family:\W*Roboto}); my $t3 = t::Helper->t(pipes => [qw(Css Fetch)]); is_deeply($t2->app->asset->store->_db, {}, 'nothing stored in db file (t2)'); is_deeply($t3->app->asset->store->_db, {}, 'nothing stored in db file (t3)'); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' Mojolicious-Plugin-AssetPack-2.13/t/00-basic.t000644 000765 000024 00000002133 14022250537 020730 0ustar00sristaff000000 000000 use Test::More; use File::Find; if (($ENV{HARNESS_PERL_SWITCHES} || '') =~ /Devel::Cover/) { plan skip_all => 'HARNESS_PERL_SWITCHES =~ /Devel::Cover/'; } if (!eval 'use Test::Pod; 1') { *Test::Pod::pod_file_ok = sub { SKIP: { skip "pod_file_ok(@_) (Test::Pod is required)", 1 } }; } if (!eval 'use Test::Pod::Coverage; 1') { *Test::Pod::Coverage::pod_coverage_ok = sub { SKIP: { skip "pod_coverage_ok(@_) (Test::Pod::Coverage is required)", 1 } }; } if (!eval 'use Test::CPAN::Changes; 1') { *Test::CPAN::Changes::changes_file_ok = sub { SKIP: { skip "changes_ok(@_) (Test::CPAN::Changes is required)", 4 } }; } find({wanted => sub { /\.pm$/ and push @files, $File::Find::name }, no_chdir => 1}, -e 'blib' ? 'blib' : 'lib',); plan tests => @files * 3 + 4; for my $file (@files) { my $module = $file; $module =~ s,\.pm$,,; $module =~ s,.*/?lib/,,; $module =~ s,/,::,g; ok eval "use $module; 1", "use $module" or diag $@; Test::Pod::pod_file_ok($file); Test::Pod::Coverage::pod_coverage_ok($module, {also_private => [qr/^[A-Z_]+$/]}); } Test::CPAN::Changes::changes_file_ok(); Mojolicious-Plugin-AssetPack-2.13/t/fetch-all.t000644 000765 000024 00000001152 14022250537 021271 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_ONLINE=1' unless $ENV{TEST_ONLINE} or -e '.test-everything'; my $t = t::Helper->t(pipes => [qw(Css Fetch)]); $t->app->asset->process('app.css' => 'http://harvesthq.github.io/chosen/chosen.css'); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200) ->content_like(qr{\Q../../\Easset/\w+/chosen-sprite\.png["']\)}) ->content_like(qr{\Q../../\Easset/\w+/chosen-sprite\@2x\.png["']\)}) ->content_unlike(qr{\Qurl(['"]chosen-sprite.png['"])\E}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' Hello world Mojolicious-Plugin-AssetPack-2.13/t/jpeg.t000644 000765 000024 00000002223 14022250537 020357 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; # This part does not required optipng my $t = t::Helper->t(pipes => [qw(Jpeg Combine)]); $t->app->asset->process('test.jpeg' => '/image/photo-1429734160945-4f85244d6a5a.jpg'); $t->get_ok('/')->status_is(200)->element_exists(qq(img[src="/asset/99cc392264/photo-1429734160945-4f85244d6a5a.jpg"])); $t->get_ok($t->tx->res->dom->at('img')->{src})->status_is(200)->header_is('Content-Type' => 'image/jpeg'); my $len = $t->tx->res->headers->content_length; diag "original size: $len"; if ($ENV{TEST_JPEG} or -e '.test-everything') { $ENV{MOJO_MODE} = 'production'; $t = t::Helper->t(pipes => [qw(Jpeg Combine)]); $t->app->asset->process('test.jpeg' => '/image/photo-1429734160945-4f85244d6a5a.jpg'); $t->get_ok('/')->status_is(200) ->element_exists(qq(img[src="/asset/99cc392264/photo-1429734160945-4f85244d6a5a.jpg"])); $t->get_ok($t->tx->res->dom->at('img')->{src})->status_is(200)->header_is('Content-Type' => 'image/jpeg') ->header_isnt('Content-Length' => $len); my $len2 = $t->tx->res->headers->content_length; diag "jpegoptim size: $len2"; } done_testing; __DATA__ @@ index.html.ep cool image! %= asset 'test.jpeg' Mojolicious-Plugin-AssetPack-2.13/t/riotjs-not-loaded.t000644 000765 000024 00000001270 14022250537 022771 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; my $t = t::Helper->t(pipes => ['Css']); $t->app->asset->process('app.js' => ('r1.tag')); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/7373328564/r1.tag"])); local $TODO = 'removed support for detecting unprocessed in 1.37'; $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->header_is('Content-Type', 'text/css') ->content_like(qr{content:'"r1.tag" is not processed.';}s); done_testing; __DATA__ @@ index.html.ep %= asset 'app.js' @@ r1.tag
Mojolicious-Plugin-AssetPack-2.13/t/font-awesome.t000644 000765 000024 00000002461 14022250537 022042 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_ONLINE=1' unless $ENV{TEST_ONLINE} or -e '.test-everything'; my $t = t::Helper->t(pipes => [qw(Css Fetch)]); $t->app->asset->process('app.css' => 'https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css'); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200) ->content_like(qr{\Qurl('../../asset/986eed8dca/fontawesome-webfont_v_4_5_0.eot')\E}) ->content_like(qr{\Qurl('../../asset/6484f1af6b/fontawesome-webfont_v_4_5_0.ttf')\E}); $t->get_ok('/asset/986eed8dca/fontawesome-webfont_v_4_5_0.eot')->status_is(200); $ENV{MOJO_MODE} = 'production'; $t = t::Helper->t(pipes => [qw(Css Fetch Combine)]); $t->app->asset->process('app.css' => 'https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css'); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200) ->content_like(qr{\Qurl('../../asset/986eed8dca/fontawesome-webfont_v_4_5_0.eot')\E}) ->content_like(qr{\Qurl('../../asset/6484f1af6b/fontawesome-webfont_v_4_5_0.ttf')\E}); $t->get_ok('/asset/986eed8dca/fontawesome-webfont_v_4_5_0.eot')->status_is(200); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' fa-camera-retro Mojolicious-Plugin-AssetPack-2.13/t/mode.t000644 000765 000024 00000001767 14022250762 020372 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; $ENV{MOJO_MODE} = 'development'; t()->content_like(qr{development})->content_unlike(qr{foo}); $ENV{MOJO_MODE} = 'production'; t()->content_like(qr{foo})->content_like(qr{production}); $ENV{MOJO_MODE} = 'foo'; t()->content_like(qr{foo})->content_unlike(qr{production}); done_testing; sub t { my $t = t::Helper->t(pipes => [qw(Css Combine)]); $t->app->asset->minify(0); $t->app->asset->pipe('Combine')->enabled(1); $t->app->asset->process; $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200); } __DATA__ @@ index.html.ep %= asset 'app.css' @@ assetpack.def # there should be a whitespace after "! app.css" # https://github.com/mojolicious/mojo-assetpack/issues/93 ! app.css < development.css [mode==development] [minify==0] < production.css [mode=production] < foo.css [mode!=development] @@ development.css .development { color: #222 } @@ foo.css .foo { color: #333 } @@ production.css .production { color: #444 } Mojolicious-Plugin-AssetPack-2.13/t/not-found.t000644 000765 000024 00000002640 14022250537 021346 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; my $t = t::Helper->t(pipes => [qw(Css Combine)]); eval { $t->app->asset->process }; like $@, qr{Could not find input asset "no-such-stylesheet\.css"}, 'could not find asset'; $t->app->asset->process('something.png', 'image/sample.png'); $t->app->asset->process('app.css', 'input.css'); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/f956a3f925/input.css"])); # Valid request $t->get_ok('/asset/f956a3f925/input.css')->status_is(200); # TODO: /:name is ignored. This might need to change $t->get_ok('/asset/f956a3f925/foo.css')->status_is(200); # This is useful when assets are combined $t->get_ok('/asset/aaaaaaaaaa/app.css')->status_is(200)->content_is(qq(\@import "/asset/f956a3f925/input.css";\n)); # Both checksum and topic is invalid $t->get_ok('/asset/aaaaaaaaaa/foo.css')->status_is(404)->content_is("// No such asset 'foo.css'\n"); $t->get_ok('/asset/aaaaaaaaaa/something.png')->status_is(302)->header_like(Location => qr{^/asset/\w+/something.png$}); $t->get_ok($t->tx->res->headers->location)->status_is(200); # XSS attack $t->get_ok('/asset/aaaaaaaaaa/foo.xml%3Cscript%3Ealert(\'ouch\')%3C/script%3E')->status_is(404) ->content_is("// No such asset 'foo.xml<script>alert('ouch')</script>'\n"); done_testing; __DATA__ @@ assetpack.def ! app.css < no-such-stylesheet.css @@ index.html.ep %= asset 'app.css' @@ input.css .one { color: #111; } Mojolicious-Plugin-AssetPack-2.13/t/riotjs.t000644 000765 000024 00000002225 14022250537 020746 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'cpanm JavaScript::Minifier::XS' unless eval 'require JavaScript::Minifier::XS;1'; plan skip_all => 'TEST_RIOTJS=1' unless $ENV{TEST_RIOTJS} or -e '.test-everything'; my $t = t::Helper->t(pipes => [qw(Riotjs JavaScript)]); $t->app->asset->process('app.js' => ('r1.tag')); $t->get_ok('/')->status_is(200)->element_exists(qq(script[src="/asset/7373328564/r1.js"])); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200) ->content_like(qr{^\s*riot\.tag.*onclick=.*"foo";\n\s+this\.clicked.*\);\s*}s); $ENV{MOJO_MODE} = 'Test_minify_from_here'; $t = t::Helper->t(pipes => [qw(Riotjs JavaScript)]); $t->app->asset->process('app.js' => ('r1.tag')); $t->get_ok('/')->status_is(200)->element_exists(qq(script[src="/asset/7373328564/r1.js"])); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200)->content_like(qr{"foo";this\.clicked}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.js' @@ r1.tag
Mojolicious-Plugin-AssetPack-2.13/t/Helper.pm000644 000765 000024 00000002536 14022250537 021031 0ustar00sristaff000000 000000 package t::Helper; use Mojo::Base -strict; use Mojo::File 'path'; use Mojo::Util; use Mojo::Loader; use Mojolicious::Plugin::AssetPack::Util; use Mojolicious; use Test::Mojo; use Test::More (); $ENV{MOJO_LOG_LEVEL} = $ENV{HARNESS_IS_VERBOSE} ? 'debug' : 'error'; $ENV{TEST_HOME} = path(__FILE__)->to_abs->dirname; END { cleanup() } my %CREATED_FILES; unless ($ENV{TEST_KEEP_FILES}) { my $spurt = \&Mojo::File::spurt; Mojo::Util::monkey_patch( 'Mojo::File' => spurt => sub { $CREATED_FILES{$_[0]} = 1 unless -e $_[0]; goto $spurt; } ); } sub cleanup { $CREATED_FILES{path($ENV{TEST_HOME}, 'assets', $ENV{MOJO_ASSETPACK_DB_FILE})} = 1 if $ENV{MOJO_ASSETPACK_DB_FILE} and !$ENV{TEST_KEEP_FILES}; unlink $_ for keys %CREATED_FILES; } sub t { my $class = shift; my $args = ref $_[0] ? shift : {@_}; my $app = Mojolicious->new; $ENV{MOJO_ASSETPACK_DB_FILE} = sprintf '%s.db', path($0)->basename; $class->cleanup unless state $cleaned_up++; ${$app->home} = $ENV{TEST_HOME}; delete $app->log->{$_} for qw(handle path); $app->routes->get('/' => 'index'); $app->plugin(AssetPack => $args); return Test::Mojo->new($app); } sub import { my $class = shift; my $caller = caller; Mojo::Base->import('-strict'); eval <<"HERE" or die $@; package $caller; use Test::More; use Test::Mojo; 1; HERE } 1; Mojolicious-Plugin-AssetPack-2.13/t/coffee.t000644 000765 000024 00000001056 14022250537 020664 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_COFFEE=1' unless $ENV{TEST_COFFEE} or -e '.test-everything'; my $t = t::Helper->t(pipes => [qw(CoffeeScript JavaScript)]); $t->app->asset->process('app.js' => 'foo.coffee'); $t->get_ok('/')->status_is(200)->element_exists(qq(script[src="/asset/e4c4b04389/foo.js"])); $t->get_ok($t->tx->res->dom->at('script')->{src})->status_is(200) ->content_like(qr{console.log\('hello from foo coffee'\)}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.js' @@ foo.coffee console.log 'hello from foo coffee' Mojolicious-Plugin-AssetPack-2.13/t/util.t000644 000765 000024 00000002273 14022250537 020414 0ustar00sristaff000000 000000 use Mojo::Base -strict; use Test::Mojo; use Test::More; use Mojolicious::Plugin::AssetPack::Util qw($CWD diag has_ro); use Mojolicious::Plugin::AssetPack::Pipe::Sass; has_ro 'no_builder'; has_ro with_builder => sub {42}; my $obj = bless {}, __PACKAGE__; eval { $obj->no_builder(1) }; like $@, qr{read-only}, 'no_builder read-only'; eval { $obj->no_builder }; like $@, qr{required in constructor}, 'no_builder'; $obj->{no_builder} = 'yay!'; is $obj->no_builder, 'yay!', 'no_builder with value'; eval { $obj->with_builder(1) }; like $@, qr{read-only}, 'with_builder read-only'; is $obj->with_builder, 42, 'with_builder'; { my $diag = ''; local $SIG{__WARN__} = sub { $diag = $_[0] }; diag 'foo'; like $diag, qr{\[AssetPack\] foo\n}, 'diag foo'; diag 'foo %s', 'bar'; like $diag, qr{\[AssetPack\] foo bar\n}, 'diag foo bar'; } my $dir = $CWD; { local $CWD = File::Spec->tmpdir; isnt $CWD, $dir, 'chdir'; } is $dir, Cwd::getcwd, 'back on track'; for my $name (qw(gem node ruby)) { my $method = "_install_$name"; eval { Mojolicious::Plugin::AssetPack::Pipe::Sass->new->$method }; like $@, qr{Mojolicious::Plugin::AssetPack::Pipe::Sass requires.*$name.*http}, $method; } done_testing; Mojolicious-Plugin-AssetPack-2.13/t/favicon.t000644 000765 000024 00000005120 14022250537 021056 0ustar00sristaff000000 000000 use lib '.'; use File::Basename 'basename'; use t::Helper; plan skip_all => 'TEST_REALFAVICONGENERATOR_API_KEY=is_not_set' unless $ENV{TEST_REALFAVICONGENERATOR_API_KEY}; my $t = t::Helper->t(pipes => [qw(Favicon)]); my %sub_asset; $t->app->asset->pipe('Favicon')->api_key($ENV{TEST_REALFAVICONGENERATOR_API_KEY}); $t->app->asset->process('favicon.ico' => '/image/master_favicon_thumbnail.png'); $t->get_ok('/')->status_is(200)->element_exists('[href$="114x114.png"][rel="apple-touch-icon"][sizes="114x114"]') ->element_exists('[href$="120x120.png"][rel="apple-touch-icon"][sizes="120x120"]') ->element_exists('[href$="57x57.png"][rel="apple-touch-icon"][sizes="57x57"]') ->element_exists('[href$="60x60.png"][rel="apple-touch-icon"][sizes="60x60"]') ->element_exists('[href$="72x72.png"][rel="apple-touch-icon"][sizes="72x72"]') ->element_exists('[href$="76x76.png"][rel="apple-touch-icon"][sizes="76x76"]') ->element_exists('[href$="16x16.png"][rel="icon"][sizes="16x16"][type="image/png"]') ->element_exists('[href$="32x32.png"][rel="icon"][sizes="32x32"][type="image/png"]') ->element_exists('[href$="safari-pinned-tab.svg"][color="#536DFE"][rel="mask-icon"]') ->element_exists('[href$="site.webmanifest"][rel="manifest"]') ->element_exists('[name="msapplication-config"][content$="browserconfig.xml"]') ->element_exists('[name="msapplication-TileColor"][content="#536DFE"]') ->element_exists('[name="theme-color"][content="#536DFE"]'); # Make sure that all the [href] above looks like /asset/19b5e7c873/apple-touch-icon-57x57.png $t->tx->res->dom->find("[href], [content]")->each(sub { my $src = $_->{href} || $_->{content}; return if $src =~ m!\#!; # Skip content="#536DFE" my $name = basename $src; $sub_asset{$name} = $src; like $src, qr{^/asset/\w+/\w+.*$}, "meta $src"; }); $t->get_ok($sub_asset{'site.webmanifest'})->status_is(200)->json_like('/icons/0/src', qr{^/asset/\w+/[\w-]+\.png$}) ->json_like('/icons/1/src', qr{^/asset/\w+/[\w-]+\.png$}); $t->get_ok($sub_asset{'browserconfig.xml'})->status_is(200); like $t->tx->res->dom->at('square150x150logo[src]')->{src}, qr{^/asset/\w+/mstile-150x150.png}, 'browserconfig.xml square150x150logo'; #$t->get_ok($sub_asset{'manifest.webapp'})->content_is(1); { no warnings 'redefine'; local *Mojolicious::Plugin::AssetPack::Pipe::Favicon::_request = sub { die $_[1] }; eval { $t->app->asset->process('favicon.cool_beans.ico' => '/image/sample.png') }; like "$@", qr{Mojolicious::Plugin::AssetPack::Asset}, 'will also process variants of the favicon'; } done_testing; __DATA__ @@ index.html.ep favicon! %= asset 'favicon.ico' Mojolicious-Plugin-AssetPack-2.13/t/lazy.t000644 000765 000024 00000003325 14022250537 020415 0ustar00sristaff000000 000000 BEGIN { $ENV{MOJO_ASSETPACK_LAZY} = 1 } use lib '.'; use t::Helper; plan skip_all => 'cpanm CSS::Sass' unless eval 'use CSS::Sass 3.3.0;1'; my $t = t::Helper->t(pipes => [qw(Sass Css)]); $t->app->asset->process('app.css' => ('sass-one.sass', 'sass-two.scss')); $t->get_ok('/asset/5660087922/sass-one.css')->status_is(404, 'not yet compiled'); $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/5660087922/sass-one.css"])) ->element_exists(qq(link[href="/asset/9f0d8f784a/sass-two.css"])); $t->get_ok('/asset/5660087922/sass-one.css')->status_is(200)->content_like(qr{\.sass\W+color:\s+\#aaa}s); $t->get_ok('/asset/9f0d8f784a/sass-two.css')->status_is(200) ->content_like(qr{body\W+background:\s*\#fff.*\.scss \.nested\W+color:\s+\#9\d9\d9\d}s); Mojo::Loader::data_section('main')->{'sass-two.scss'} = 'body { background: black; }'; $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/5660087922/sass-one.css"])) ->element_exists(qq(link[href="/asset/0dfb452e32/sass-two.css"])) ->element_exists_not(qq(link[href="/asset/9f0d8f784a/sass-two.css"])); { local $TODO = 'Not sure if we need to clear out old checksums'; $t->get_ok('/asset/9f0d8f784a/sass-two.css')->status_is(404); } $t->get_ok('/asset/0dfb452e32/sass-two.css')->status_is(200)->content_like(qr{body\W+background:\s*black}s); $t = t::Helper->t(pipes => [qw(Css Fetch)]); is_deeply($t->app->asset->store->_db, {}, 'nothing was stored in db'); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ sass-one.sass $color: #aaa; .sass color: $color; @@ sass-two.scss @import "sass-0-include"; $color: #aaa; .scss { color: $color; .nested { color: darken($color, 9%); } } @@ sass-0-include.scss body { background: #fff; } Mojolicious-Plugin-AssetPack-2.13/t/mount.t000644 000765 000024 00000001277 14022250537 020604 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; $ENV{MOJO_MODE} = 'development'; $ENV{MOJO_ASSETPACK_DB_FILE} = 'mount.db'; my $app = Mojolicious->new; $app->plugin(AssetPack => {pipes => [qw(Css Combine)]}); $app->asset->process; $app->routes->get('/' => 'index'); my $t = Test::Mojo->new(Mojolicious->new); $t->app->routes->any('/mounted')->partial(1)->to(app => $app); $t->get_ok('/')->status_is(404); $t->get_ok('/mounted')->status_is(200)->element_exists('link[href="/mounted/asset/5524d15cbb/foo.css"]'); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ assetpack.def ! app.css < foo.css @@ foo.css .foo { color: #333 } Mojolicious-Plugin-AssetPack-2.13/t/fetch-hash.t000644 000765 000024 00000000742 14022250537 021450 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'TEST_ONLINE=1' unless $ENV{TEST_ONLINE} or -e '.test-everything'; my $t = t::Helper->t(pipes => [qw(Css Fetch)]); $t->app->asset->process('app.css' => 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.1/leaflet.css'); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_like(qr{url\(\#default\#VML\)}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' Hello world Mojolicious-Plugin-AssetPack-2.13/t/css.t000644 000765 000024 00000004047 14022250537 020230 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; use Mojo::Loader 'data_section'; use Mojolicious::Plugin::AssetPack::Util 'checksum'; plan skip_all => 'cpanm CSS::Minifier::XS' unless eval 'require CSS::Minifier::XS;1'; my $t = t::Helper->t(pipes => [qw(Css Combine)]); $t->app->asset->process; $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/d508287fc7/css-0-one.css"])) ->element_exists(qq(link[href="/asset/ec4c05a328/css-0-two.css"])); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_like(qr{aaa}); $ENV{MOJO_MODE} = 'Test_minify_from_here'; my @assets = qw(d/x.css d/y.css d/already-min.css); my $url_checksum = checksum 'd/x.css'; $t = t::Helper->t(pipes => [qw(Css Combine)]); $t->app->asset->process('app.css' => @assets); my $file = $t->app->asset->store->file('cache/x-026c9c3a29.min.css'); isa_ok($file, 'Mojo::Asset::File'); ok -e $file->path, 'cached file exists'; Mojo::Util::monkey_patch('CSS::Minifier::XS', minify => sub { die 'Not cached!' }); $t = t::Helper->t(pipes => [qw(Css Combine)]); $t->app->asset->process('app.css' => @assets); $t->app->routes->get('/inline' => 'inline'); $t->get_ok('/inline')->status_is(200)->content_like(qr/\.one\{color.*\.two\{color.*.skipped\s\{/s); $t->app->asset->process('app.css' => @assets); my $asset_checksum = checksum join ':', map { checksum(data_section __PACKAGE__, $_) } @assets; $t->get_ok('/')->status_is(200)->element_exists(qq(link[href="/asset/$asset_checksum/app.css"])); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->header_is('Cache-Control', 'max-age=31536000') ->header_is('Content-Type', 'text/css')->content_like(qr/\.one\{color.*\.two\{color.*.skipped\s\{/s); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ inline.html.ep %= stylesheet sub { asset->processed('app.css')->map('content')->join } @@ assetpack.def ! app.css # some comment < css-0-one.css #some inline comment < css-0-two.css # other comment @@ d/x.css .one { color: #111; } @@ d/y.css .two { color: #222; } @@ d/already-min.css .skipped { color: #222; } Mojolicious-Plugin-AssetPack-2.13/t/register.t000644 000765 000024 00000002420 14022250537 021255 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; $ENV{HTTP_PROXY} = 'example.com'; $ENV{NO_PROXY} = 'mojolicious.org'; $ENV{no_proxy} = ''; ok !eval '$undeclared_variable=123', 'strict is enabled'; my $t = Test::Mojo->new(Mojolicious->new); delete $t->app->log->{$_} for qw(path handle); $t->app->plugin(AssetPack => {helper => 'foo', pipes => ['Css']}); isa_ok $t->app->foo, 'Mojolicious::Plugin::AssetPack'; is $t->app->foo->ua->server->app, $t->app, 'app'; is $t->app->foo->ua->proxy->http, 'example.com', 'proxy http'; $t->app->foo->process('x.css' => 'a.css'); $t->get_ok('/asset/e270d1889a/a.css')->status_is(200)->content_like(qr{aaa}); { local $TODO = $^O eq 'MSWin32' ? 'Proxy test fail on windows' : undef; is_deeply $t->app->foo->ua->proxy->not, [qw(mojolicious.org 127.0.0.1 ::1 localhost)], 'proxy not'; } $t = Test::Mojo->new(Mojolicious->new); $t->app->plugin(AssetPack => {pipes => ['Css'], proxy => 0}); ok !$t->app->asset->ua->proxy->http, 'no http proxy'; $t = Test::Mojo->new(Mojolicious->new); $t->app->plugin(AssetPack => {pipes => ['Css']}); is @{$t->app->asset->{pipes}}, 1, 'only one pipe'; eval { $t->app->asset->process('test.css' => '/file/not/found.css') }; like $@, qr{Could not find input asset}, 'file not found'; done_testing; __DATA__ @@ a.css .one { color: #aaa; } Mojolicious-Plugin-AssetPack-2.13/t/assets/000755 000765 000024 00000000000 14023167353 020554 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/t/sass-functions.t000644 000765 000024 00000001141 14022250537 022407 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; plan skip_all => 'cpanm CSS::Sass' unless eval 'use CSS::Sass 3.3.0;1'; my $t = t::Helper->t(pipes => [qw(Sass Css)]); $t->app->asset->pipe('Sass')->functions({ q[image-url($arg)] => sub { return sprintf "url(/assets/%s)", $_[1] } }); $t->app->asset->process('app.css' => 'functions.scss'); $t->get_ok('/')->status_is(200); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_like(qr{body.*url\(/assets/img\.png}s); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ functions.scss body { background: #fff image-url('img.png') top left; } Mojolicious-Plugin-AssetPack-2.13/t/from-helper.t000644 000765 000024 00000001464 14022250537 021660 0ustar00sristaff000000 000000 use lib '.'; use t::Helper; $ENV{MOJO_MODE} = 'not_development'; my $t = t::Helper->t(pipes => ['Combine']); $t->app->helper( 'some.mojo.helper' => sub { my ($c, $name, $args) = @_; $args->{val} ||= 'red'; return {content => "$name:monospace;\n", format => 'css'} unless $args->{format}; return "$name:$args->{val};\n"; } ); $t->app->asset->process; $t->get_ok('/')->status_is(200)->element_count_is('link', 1); $t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_like(qr{border:1px;}) ->content_like(qr{color:red;})->content_like(qr{font:monospace;}); done_testing; __DATA__ @@ index.html.ep %= asset 'app.css' @@ assetpack.def ! app.css < helper://some.mojo.helper/border?format=css&val=1px < helper://some.mojo.helper/color?format=css < helper://some.mojo.helper/font Mojolicious-Plugin-AssetPack-2.13/t/assets/recreate.css000644 000765 000024 00000000032 14023167326 023053 0ustar00sristaff000000 000000 .recreate { color: #aaa } Mojolicious-Plugin-AssetPack-2.13/t/assets/css/000755 000765 000024 00000000000 14023167353 021344 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/t/assets/js/000755 000765 000024 00000000000 14023167353 021170 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/t/assets/vue/000755 000765 000024 00000000000 14023167353 021353 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/t/assets/other/000755 000765 000024 00000000000 14023167353 021675 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/t/assets/css-0-two.css000644 000765 000024 00000000026 14022250537 023014 0ustar00sristaff000000 000000 .two { color: #000; } Mojolicious-Plugin-AssetPack-2.13/t/assets/image/000755 000765 000024 00000000000 14023167353 021636 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/t/assets/css-0-one.css000644 000765 000024 00000000025 14022250537 022763 0ustar00sristaff000000 000000 .one { color: #aaa } Mojolicious-Plugin-AssetPack-2.13/t/assets/example.css000644 000765 000024 00000000035 14022250537 022713 0ustar00sristaff000000 000000 body { background: #fa0; } Mojolicious-Plugin-AssetPack-2.13/t/assets/sass/000755 000765 000024 00000000000 14023167353 021525 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/t/assets/sass/_sass-1-blocks.scss000644 000765 000024 00000000041 14022250537 025132 0ustar00sristaff000000 000000 footer { color: $footer-color; } Mojolicious-Plugin-AssetPack-2.13/t/assets/sass/70-utf8.scss000644 000765 000024 00000000076 14022250537 023533 0ustar00sristaff000000 000000 @charset "UTF-8"; /* コメント */ h2 { color: #000000; } Mojolicious-Plugin-AssetPack-2.13/t/assets/sass/sass-1.scss000644 000765 000024 00000000121 14022250537 023517 0ustar00sristaff000000 000000 @import "sass-1-inc/variables"; @import "sass-1-blocks"; body { color: $color; } Mojolicious-Plugin-AssetPack-2.13/t/assets/sass/sass-2-dup/000755 000765 000024 00000000000 14023167353 023423 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/t/assets/sass/sass-2-dup.scss000644 000765 000024 00000000157 14022250537 024317 0ustar00sristaff000000 000000 @import "sass-2-dup/mixins"; @import "sass-2-dup/mixins"; div.test { @extend .tester; font-size: large; } Mojolicious-Plugin-AssetPack-2.13/t/assets/sass/sass-1-inc/000755 000765 000024 00000000000 14023167353 023403 5ustar00sristaff000000 000000 Mojolicious-Plugin-AssetPack-2.13/t/assets/sass/sass-1-inc/variables.scss000644 000765 000024 00000000036 14022250537 026243 0ustar00sristaff000000 000000 @import "var2"; $color: #222; Mojolicious-Plugin-AssetPack-2.13/t/assets/sass/sass-1-inc/_var2.scss000644 000765 000024 00000000025 14022250537 025302 0ustar00sristaff000000 000000 $footer-color: #aaa; Mojolicious-Plugin-AssetPack-2.13/t/assets/sass/sass-2-dup/_mixins.scss000644 000765 000024 00000000037 14022250537 025762 0ustar00sristaff000000 000000 .tester { font-weight: bold; } Mojolicious-Plugin-AssetPack-2.13/t/assets/image/master_favicon_thumbnail.png000644 000765 000024 00000011120 14022250537 027376 0ustar00sristaff000000 000000 PNG  IHDRA>gAMA a cHRMz&u0`:pQ<bKGD pHYs.#.#x?vtIME x?IDATxy?;," "hQ$1&EIԘT*'J\5!#^A4&QM֨)QL@TYewe'|_ce{guO2L{w*ʔ?;#a ym 4j @#X ,6wf'} P D%.H``_`w`6HDQ4<` #T ƈ$ Fk]N h>MrVTבpf!,5Öׂ308Y~I[D|< <| ~ KTaT$QhRaR8^ pl\4xuiCCԭrK8^|38ӗK6%`0 N_K8h$l@s:-i$&k\V>.cn` 6 ~Csy  $!Xce K+(vFJ(XǮ ujaD2B_BAh g}ϡm90։*>ˁka-EKjH`Y:}ہ%JW7fOg֦@,@t&Ď@c.W_G@~Y$]=/Њ(܉R2Q|--ES`YSX`̉<ْ9>n De T0zF3ޯ { Td`̉UAΥrIAH#CI"JCnnRVO{n"p]Rw(h7BV8 m AIdn O$=P }|`~^Qzh EPT0woucH:`ViAuC^6J@֡N1%AVt0) م .n/ר('ZPSH$K )b7hq< Y/he(f n&&}ˀ'?P%: k?HMtQ%uY0VrJݟGC̃}5̴*ϠӉGƺg7y p ?,êB?5*ce4JN(&dQ}J!e8y@htu89K;j'^,ɤx8&NcYsPv4I$J9lM,6ֹ/|9'쐴 #g%Nc(2 r}Z@efVa=MlSmU:r>fs0f 2q6i:ú7`cUcYQ)B\Gˀu,:et<MgfR|\ͨ@:R`YUOP:W)*˺D6ȼ@=M%}"6[0Ñ% /__k3t B81m*Z?X@0IMG2p?.V0CoRT;Q9eGJN\BȡDw 'ujTp^NDTAqqT8[Gorw_65 ػ&9]XE:fG.QT8`I7,zGE(nWHn_e@%u<ئDCb Ԡ{pr(^',d`d'ը>h{Tavq` ruh-Ю0VewфVKX4uwE-bvQ(E8 +·x7&4?p) (p*K0ڐ  r7H(>~T` S QPp?)a/9LC:vU`CfuzZf{!]B)`7~*J0/ǢDku4eٹ ̝dM\[O!D$Uסò.'++^@5@xBp9aـ0`wm\0-h+Je]yo" \UdX6J_9\b >f~ͬIi1epd`2XFR[WYuyl('-5TX,Cܓژ'Lobfa>D[gb<E-@͎|nhU4;Pw0tom|3*ʪ(XY"s9> t_K=07*lh ՝';9: 5rY_Tz$N| hzhyZ-ڏi*n*F#+0o]0ͫlv~-< ܇ҡU PE(q3*J;d|bѪ%#-~63m* Jyyו䛧7 o^7_ VT#N'$]t:2;e_kx\, \|ϙy*Ʀ.DO̬u 15DBSPyw,. *i0͍6zx:I5 m®m|70`l6µеvy5ECXHT?w+pyjcƾ  5Z [MͣB*ʡ<^v"{"(4ŏ!G<,=z >g~YTrƼvV e{ǿ8+dxy%V0r(A"V3,?3.Qfj"xOInd=L kB3p1cET &Ulڟy3_*C3cP!D`6c{8x:{UѴ苈ز*-`:̤6;O (y1j]* j 0wr/AwٸY.]0-t"kZbbu2ʈEañX `aYa ܄dh#iml,;LhR v33Jc5p-p&+*6Tmv5\G9F!$XQ(o7ceH$Q,/K4}PD(_#Iц6˸x7H:UPV85*`MC%P1^'F 7ԥULZB H`lxơ6XW֚]w>1[h5Z4&Uӵ({Y&Y8ߴ5ےQx4xXJX^k׷6W $ܠBJHo ax8%d\Q1LZ7%5:t*kKw4UxAשK ft(Ɵ㊣:491&W^f}o>}Whea]DM7)<hoD0`~/'k"c_ZOc7{!57owcg[41Xiڦn7-Ggngkw'~}EkQ їKե76V2$Ktf<.T7?wq~ÿՍ%xILJ2|d6X-|rRR)zQ9y|UIfʱ.N-Y|sd}uq|M:tTp)gtT&Rnl-F^4i{PеG+Z}cửF bױi7d&{߼Ţ۝wF'mm`gPqY][RNׄu[XVm=-ctS[H[<XtO^"'7xCѼ3jkzΉO4y.bőQ"wt]Z[,x5[ DZ#U_Z1)tڶmx{T qy.ąa]sIH^+LUܰW[AM'us~~Ӯ?Lм'jW\Oi>EV?h{"(F6~ˉ19Gԫ_O/*PU+/э[΂(ӷqN epjBaJNS*VA$)4ڼZq쿵ngo| T?/W=ֺόWz KVz5֥MVHoY[-jZQ(@DC:,m:+.Der>p2@YhmF]Oÿ QnY57vh4)|UxHMhچDǭb+Fֵ{kIVKeKY.bẺ1io"hK*YYWrpI d5,ͩI.Us,ElU=tBVWqj.*hcM6u+v5 };ռ7-`_O߬Cl4:[Z\p%8L2U6`ڸiup˚pu:٩dR儠't(xh߲."__Y]E-r@NgIkn+-Z }a'ٿ߷ŕZviYYiu 7ڍNYgƿ@'0mu>u CPLM~#k˪1%ѭW6O]aRTJ8:4^ ]\$o=*<4s W*еoOé{/|2>rjZ& ['L ֶO$N.NY!g(t./"w>go,Dv?P{ql .Q~< nnd q6ZIG<ʪ>$^rQkX9BΧM6c){|~D`db%ڭ|GያYG/>&4 n۬}?O%^0jPF_s<ڎ ^&u :)VX5KIڋbIeI R#s3} ^݄ 9#k_N&SMtXKk1[.6Lf7m.Xf?*kSW3M'$*~_d9Wt+&Tsh׸ۥgԼ'!<%wpxkwslis |`ծ/46q{腒YoKs +Z׋k_Ӵ]j֗{Hc;Ho&$s4rf(ԭ>,E:֯xcX?b۽Z+^6KYE:m\ˬ>{uMuw ΫsesN ;o_F1׾:EEi:gVjzan,u ZkhNz4#f*$/"~9mJ/59sU,擋\7x $cJuAVOܩFY(NJܐoˣ%SƟׂ/~#.~$$d; G{x|?1XK:!F"i^ i6| +<>1g 5^/ iмUk:૏KK^͔+U\E+ozO}fbrTJ0ڭNkJJ(RO:sesF# ,rpucˋ*5E98_η%_Owjm"k>xtoڢZMo? ~-|A 9gXU涄sk6 2u& 6 w5~M}g|<3 I|A`_^?e7؞'A{_`W ~#ko07>9᥷-#e4 h_ /kmOúZ=ݎXj6+'<$CS?e {8n--Q5Φ_kƤ'9j89FH-+P=u7W ʪRjR\yJQrQ9E%/qdJrbգS6U>i0x4^"2h:ǃu6xGȅ..俞>%"kuon.+V /z>|<}Ş7WpEO3O6b/[moA}#Fx/ODO?͗|%sI~#w|;qM`X!]kWƟi2+w 6i|3K Zx;}V|m!x ȳ~ |F~ i_ChdžNI뺦GG1bkJi⾯85JXbc+_:;THƝIayc,6&t IPj֤V劼('NJ7dx-Gp_xTKPi~{_$M+HڻX|]N|pv ,|B=$ f߳UeITa7ӾpxPmOEVo[osP~>esꚎxz= /i5i7/$ .-.l mxߴ/k\à|n ź, *]ꚧAm+Fy#-eˬ2K'j_e9K-Gw`N5ïhd(auV"LW|X'DGIGS75KT-6>f b6TeK5A;J1hڵLgvSו$ĒG̥>XÝ)rx.M7 dټ^]퐺P Q?47,\!\g c|]l%֒1:2 w3*rKI0ͳ#{ybI<ˉæ>m㹇ͱa7>)\hmx?vk6Ge#cu':w!U*фIM%x\<^;5a-in[_(Tz;p+2' ?k]fW4#A"xg\J[iښ|2E4Hpc6ڵ&KR^{@aY晼wQpO^c zrC`Ӷ߻t㓜tZ5TdW@]R뭬KeDz{ '889#ܨs}scIt8 r2CpH< 4jIwVizid٭m+߬oݝgZ%axvN=p;ҔP1g g> R{8(99=bNs“'A[:tyn}Ziem}V|[kc9yu'϶K8;Fr3㌃i 89'9lg=r #9I=q/e}KW۵{-mVli+;nzz;nByHrF>lw8ɥ$`d03Ns1sIx#$w<H1ё18R1ދ^Zzlu^O禿ՁH,X (8 9 G^qZC=䓃2 O\NǷ+Z}/;kz=;QI8p}aqpd'4 r  psҜGrČ 2O\$;16994M%]~K-얾kt q3d$g`돛8I1`d1&O$Bx' }7zխ/]wt/ >:sԑJr7qhN1^ԃpyAs9=x;OzR;W'm7ګ߷zggxFTW9zcH=(H9c'<NH>9< NO=s>xNwz[o!Os gOԜR(<P$3=zNc?׹F;'q +_mknm;Î\`rq=ht9$O(#O txqӏ^펼d~t۾!$$g'8|Fqӌ`988=y^N3'~F:O#߷Uߧ/@ 3#?gf<rr3Ȥ lRI9ב2F{/7v {9$}=q$Fz`v';z0KO搟O\Fpy^_pN 9{x㩦wo3ӧRF)X'=pI遌`ds>'22Fs={=o~{SO$qR0rGL i@qqԓg89Fy;c8䞙3@xpA9mWdweZۥƵiZY[k #2<N2>nOCӊ0I033 Ԅ?tg/L bAcqtɧv.I|ѷd-|H\@ 8$pRq x #r8J qFqӜKrs}Os<r8˺ok$Dޝnj/Yz=~"0N8* @N9T/|T0eFT6@\=$Sf8PpI$SC20.:+Og6j7vZ:LsKjbAs4En~ξiKIM*g`kSMAJRQj+I6ݛj)d}2Z[._m7n?݇~ x[MռW)[XuV6enuMezP^]ZZA=P+~Yuoګⷊ| ⟊-gWlWմK{/׼1COE8$KHے]=Z-?ľ,5. f.oKY]\q{jhlQGmm#ıa?ⴺ}αmno4+-_oGm-a[oxc{Y"8dXNq#Iܨ7QOޛVjTe(r7I\ZdgxWմϙk?Cyx/B׍4/ڵ/¶|6)~Vsn-=mjzg#J g 5oh-phX --%x7!cwmO**0έH%*Dk :+P&ҌgJmٸiM5޼Μ+sRJnJ9cƥ~^XFSqͥn]ɺu%S7̱E-כ2]TFU|PG"פzMXwi( е(K": &X; ujq!m&`'UWp>U;K]qz gHl26e}~VG|t~!)o ,jPTN**-j䭯^etvVUO6N:.->R(_.`dz ͈^Լ9-k}ȸW+;E-bxӬxX$ '8).~2IY̊ _Sxφ}dž2fdKx Sm`XE|2.>Yjq\e}r#%V%S5i)jWj)[ɥ{Ivc!*X,e98qi'QFڤ_\hM]~kw2˩ş5|6˕D a(a/ZA-·8 > "|:EVRYup$f|i%H%GlaG!?zx~ i^_y%nn`[>ۼ˚Q6ഩ0{6yWյQ+[K7޺];wVN]%6m 6凜$ݓvI]^-&v?  x\,?qk,]\i4-E o }S*[2w{q\ܵi/y}kK',ŧe͹K,s'y<$wQE)ʼnm409XE{ifGp 1ܬ[ thhUX+{KV3i[y*rэk]ʬjN/^eR<ZOm+uci˛m#YfVlfoxF/-b7yeVE-kt40ʡ$ǀRn[*G斞mEeoj.a"Jr± i<5+1;wSmYI?u3>Ln. 6YY{a_4T"i$۲q&d:{*hGqyX J cr#o*0;CHp_>iCPq c9h^61YLa}rYY[]#+^3[uWR͎kW2E0H$kKe#FlZ ܼQ.yM$XuKg=J Y{Vdik.=ԙAu qwڴʣya]͵P5O11",BRWĂ,2ܸmCXI&#l91&"̆GHsj.Ʒ \Wo|NnZx%eH՚#&T@mz>z$-`jҍW׶[zO\F;ZGk%$m| 8?fTyhѦckWRA jZ 9;>=|3^48%M 6tg/n#w_' NheH-bh3Nn?gb2!kg0Eq4d~l7Sy&ޅ~gf.m[Mmh/JnJv;rq&O6fA_DdaGU*K+rªiR#PcX-[@ݘy5}#h\KxKH̰dea$͒#$7mqz[QmDen̑yI0R6G$h0.h+oLM $4֟g[ۙ>^g$+;{D,my,Uiad!PU-.&t3y i. Mnare, 6yXgiYAK{xnAXbKB."[H e0Xw4&/.Gkth#d{.?+"0#\VOɦOFշ}oFuRJU'&Pq浕奛(+{ VHI_88ifbTU+%ѻynI<4vL!.>B 23UubfN_:R{%J<wK# pw%r%piIc-ԚI'3{ۙ];__#gV[܂v6e{;=Þ>oQ5Tk|"-Qy$$!Nc 8GFu" qU+EEN!S-υ> gsM0 \wU'c( ёntTҴX+pϐ.HDN$(jg$nvM_EF|GkiZwV}=e2mgi JmrU?\Qq! ^`%1]F\[ț_kBes*X!5tJUHbM"$e-.)P$x!+o ՓvoKEnc ?6QznIt?oH]-WҾ+tyt[goᠹ^Bi1n7]^{+զ [yexZ$v ĺ"[귖e'w:'lO5%̸v2ex.QwiGK[sJ]>έ pZ5(JQ19BfV!84ӭUR ~~?> |V c~W:龽mOvHS:-Ճcc1uأaҭԭ\8mŶ7>ާyj^&M.K{I7wYDBi73L5Aij|Gyn2j]QU^$Tmu؃UFoHG\R;ROw 3ƺt-n\RmcܥC=N_9Ѿ#|)iY⵱<Gw/4H4k]}֕}ZD[N(cLT\/(CK*N~iǚVMYeFR\|= xΥ:rqmy8B27A࿉ [xJ\ZuWӋK{ewŎas6y3*`0:ю?%5P\j­ (1FQwZr6gΟaJx|JjI_ :g6xM\E?)/|U @4? |tҴXkz-5K|%(w_ ^hz3T`Ku+AOiߡ~8״_: ~'>׊8ukky:rq!>٨Ǩ\ZS!ә-_Po^>%53ŷs*_S[2V)[i:%t a/x/=-j^? kO0m;>u?xwW.?A c[YGjP]|APě'qC/2lTjXxR# }N/P.aQjXky#Lml <|qtR? BJ|Bk9E 9T9Ϙf]m济 ,Q+~$ .͊7QM4ϩxyPk'_ 4ۍ?qiBMSP'~'|!CjԥTYwnltDQVUm+<+.B-K𮱥eWzFwC>GN`Mi {hZ|=ţZɢxĿhLFΑHmln []:dH.Yr~OxO>+7" |Mu,ww^.4JԎzR񍭅αMZK^mI縋tk.MW|6ZRᣗ< 8(ңLB ]? MmAL[~c111G[xV_7֍%ܲ\A}|'"XJV[<}դZ[hv[gE|ҍ^y&Kx]Ki^/tju(iN{)#GhobM_//`H֦ڕFc/8f\ӔI¤bNuhssSRJOW%*Xܽ>jQQuRVBQM&)ԧ^h^ Ο-տtK4美hoص]:x&/uԼ+lxqB>,YƖп<a^%qN:t ;?O _!+ 12Du[[[[vqwo &Q /nt2Kia6DSj Vhɹ9xe(|"< KmJ(G]}W>K-~>hyoÝIj7OXmLxv>#䵙߲\.G}{㮥i*MmgO.ܨ&J61\G5Re0tC-qJ*P⢥NN7dF˸o0Z.ai9żS_3RtICԥ~h߈Z>!jkmC[kWnjm4˴K~l_Gݨ~7~+ Ci|otz:|Uۍ[Q4=FH_M,5FK).7xNtg PJkfៃbᯈ5){^%-{%0L`ʖF+_(4ɵhd0]ڛ 6um5՝1^[Hf,Q+[}w[:j4'WiG֜ir+\5ZnjͶx=ecb!<_aWj RZbB#eN#c,sp-C +7 ~ }\) -'|0`# CH'qT6 @.9=sې z?h8c/i6o=>]Oe}Ow{ok|ǩYO%-$K[u۷vj]dfJYrKb* Ss`873 ]hzVz5 )g=W~4VGIVy5?aM_Buy\:'٣S,i'nx9"s* 70Ԥ&YQ8:s4Ӽ^4aaVITm*3V G!9p ǾsS\qF0rpC dASxzWSxcJ[DҬV.W,+X<\󿋿iKM^<=ieh7Vϊ95ic,$IAg)I!xl5,^76Rb#J/J+ߟ$䠧q攩ŦܢIIiҜٴU[kVϭ#'Bg#N9 pspHUXnb+yR{k")K  [0, B}y99N.-ZJI'tiUf{o]5En={keg)8 dpyx=1Ԛ~H{~'gퟔ \`q <`1yQ< U֑}mk[N/k;&馋 ' z dvlz@H#t8Ө`q=qwc<#<z#psz2:שjv٧YikWqokMi읭쟶:#GBs@4Nq1<=H]w ` 8#<0A#='OM1(@=1ז>O\ґcz`ܐ1]Vizu+=6__v~Ӧ84##Adc7-Om:t]!-.mӯ:c t gO=r.q$q=GҼz\[˾}+t_-݀HgNH><:c8GrI4syr >'#uNA=Uo-ziݴhE{#9$g&y'#t4r=<2sǮ1F ;sNqۓ4]-_gu᧟[֏=y~ y^r7Z?r0}Avgulu}8<~98^2x4z qO҅mݺm-6E)cSN{:ҎOlg3q<wLNGS`c-ԜzHN Gb;c (nޚ_-iuon=O\; ry?dp2O\;Ns鑃H<0PAI?b(_?wҿkQ{2ytA8>:1 ` @: u4dpOv`Fh]:|i}ii~\ dN soc'S;r0zq9L0T䎙b21ϡn>} P8Ah9J xzҒG'y8'dtI[#wd0 t'=x`:;p08'<ݮ_[[ֲ~[Y=-Jjk۵ו'?69[8vUU*:8  1#FH`(܌:! 0w#}1R_UemۿN'@Vj^kϢZuo['_X?KYgIb5fzidod\l F ZޥWT{Q{Fʣ]Iu \LDqoq…aX־9hzϋf>xNLlm}JZ WRaMO2ѨQեo [Ǎ4~Α k#?.|ak]\hh^!YW׺YeOi3$E^!a3Ucm:ËYoعApC$DqPsSy#G I5icEc|L۸eL^4Rjv7m4K>e%;H^B`3ZZ"IpJЉщ!b,L 5GECli6Op&b2*Lhk'k%ivڶ^彛ڽU{[nFX,%d$ 5ӹ0]Eh,ELp^OEO2O`7d,;?.?MƾSmʱJDb>SԊ.l$p0yQ]IU>b#TFX JE4{HV!"Q$\y`@(գުMaM]7N=Uv׻ Jm7 j_Yi'&V*qX_6cRG#,߹R_x9[ǿ_Y0ʱ# E&ਯ|(gaj0I3ʞ*c&]oVEm ]#> )n>!rBHX V#˔fFJҽI;%v5%ub/{N-Qԝ֑I^KEvXw&oQRO27 ș 32r[꿊H /_.A"e#C-"EAu3D]gXق.*2BH/Ȅڰ/@ZsA\a'=K;^sKs ZY%1{WJ*&y;oD{ueO Y]P+轝hݓK^k6ol,^d36.hiZܟ-b𡷖5@$`X0"km.F0ͼEHOLm+_6u7?ju,-ow% P=Ŗ6+\|Vvv1OhH廊HθVџZ\9,t6Nk4./UD.+5R5|Wq|QfQo^dnxZ#ש[*^Ue'gʝ7dN+ݟy[nRmd/C,,j欏Œʪ$=k$s5/ytg _K͒-A4HP)6sx#Ԡ -,/ hCEdQYAne700pK^x:;>Wŝ@y{V)ZG%ٶHE[xmrKZM8N[%+rk\z|8pI?o/ai$޲q|2Q|H]'VKtԭO1_ lxX-ϟq*Kxo8LE,QKuM\b]jSAB;"T-y(c[}5] ycX^-;$H`G һ|`,W7NeG{b6} Syr31J*wQN7ruk=׽}^FyTb>Tri;|-YWVӫ~=6<ֶ֥1,QBryT۩Qk 8vI5dk>n5<(]%Mշ5wmQmxb+XKk{8KhZF $!i9]!18' /^%Y$o8'rdQ*ks%׌>iv[[^bXky$YLnm*K!,CYby9Rxf5Vge+-"sjʞ^[K>Q66#;nSvM|2浞^y"Fu_>}6$n|2lG^H50H4Ek[>8=Ď|Y2'ZGꄨs+`DZжT;ݵ(rY`n ِ`0P>"An.UF$vN,+p!d'0v(Iյ;liƲ9i(-柕mfy1x%E!=[N .50^ NkTWespJGrBeKc,R!M#FG-3n)o #;`IWm]9f6Zƻ%fTY$y!V` bXI动`Kd8EU^XIĵVMi]iI)]wlߓi=’'m o] N r,vOr# Q,D+hTvY;mQEvQPӕ+西}~m#y‡¬ޚ]/-4etx? _i&3»{ME/Ŏ<n-tCbk-38.D؆ş/O|4Eſsx3S^ e<6 qp|/r϶uc]^DW7? cl}v¾XHž0>E_ x5 Qh:式//?߲hkqg;↚ugx[} _ꄛy=֏uĖG,B3*🎓f97~Y/BP8$ܩ1jN6˽ڎJj)Gu+s;FmOKepŵR]}éX-R)xs!Yor3@bX3h۸2Q7󭵏@e%I~ ߳Iz[~([[^Kַմ-_[ 7-om-?T+]7mefEy,;4|a^T0 w<ώv vԜs+$vm4w?-ᵩР]gO _B?d{]WKٵORYik?nMW5;[kuhgo ]ky@"!@ 9.$JқemY*aGT+B4 m`7_KkM{IVa]^;9{ck#TmfiW3vڴ oUxw(>U)Ϊ}KQV NQJI`^(ǹsbq8Jt]%G4|$]8rsh* |IXিaD&WoyYcU֯%LhMVa ]I4̿Oo[E@E]UY4wVnc{{{@?`IuE+x:J uI))" =J,oe6CbkG3t12˙WC~ +g@H]d -}B+3/$y$<7.dմdt %^9!ֲ}\i?I#KwHLܧ?ēro{ٻYWzYops:x[u͡Am>goWƺPP^.˵&25-ƞ:q.5mOA,&kD:|2l 'S&t{\R,oƸDQܤ߳?ė/IsNk2Kfդiu*kK-ŕCƟZb^u5m_..-;X[m z}٤g7%њCەӌ#Qt¹}*x*^o)#}c%o'^X^ sq8R/QC<{7U6etONo<Ŷg^Xe]M>)d٬kmr4㸻tHھ_,ŻK9X.n;8oi4[(zj6%4˹^hi{(^%{[ rB=k|'[x?b/<7RG%%7մCw^MG%4B\\mb2>WV9 pm*y:mw)FT{]2> Ux\KFw(T/Gh?IG,^kRFiّk+Y`wdWYCD]㏄> x៍4 WM4qs[iZEiln+4뫫H~?lk-+Ʒ=8h!w`uCA&m*L6N '-4ϳs^7yѼM[7KrWv֙?Z*vז]/&p]Iqna2:x 2Z4/1|6N7a栓n*J*Oql.\ 6+grYmxIBQX%jSMs9)JRU$Ӊ E|?}mh?"ĮzyT4\䕜Ɩk_>8[v ]Wƚ Iæ[6iomi2kE݃O_փl,Y5A1󦵼᧋c$[ۍ6 m<\쑹\KU]S& =)ƛgF&4*Ǘ%FVjJQY<$s)R+Pkԝ2PJsKQ|J2Ғ^'?#YI>!~ڙm{]/Tcjw6.Gxȸo~*֬uiJd&[$񞇦Yxe<.uciie75[;mBB?οn>7 %uKKu+mFDZ3D8⍠3gQz-`>״8't4񗅼-Ocu D_ȗA9/uDsΥ =weэ9QS,x҄ND}^JqzSj V(qU<}%<>;3$N%UңۂJr )A"c_gh6>.qIcxZo DN[t/'n&Eގx?>qt~2=Oo>*[+']j3j+!y- (J+"j֬V|⟅u?3/¿j# /[>źot k jTT)vz_d࿍߰~ EaO:2ͭZ[Oh{E< QM~z|3?j#Mڌ ;K_|me|_c0Z.zթjЪYn>#R:~0"eه0 ]lX kg78BThU*R+{ ԫaVYJu'e~:bCzCq:[^; -TX<7'K%/&K%CV,5Q ' E,A~$-B72x݂E'f'5k] e.= eixFhu{6v[xšXk6x?ï蚯?8oܫ[_?m;.h-SIV1)Ob͡ü&*]W8`psaSj58ԅXT;riWJnqU)JΦXӯ U)FPvn-AJJI~e~Ò<U_Ц~>d{c*4kXܣ\z)+'qV]?V4>l?d+FeKrg7Tl,7GgXٴJ~lm@j:jvkiRKkiv7mWk/ُ 1$wIs&eF}ݛo<|}~0N >֦դc.f֩>Ps|#"N_m5-մKWc_ c,() nW<&Ոhe"3A,P3ʳBðe?7Z6gom>YG9m?x1ͫ Hdt:7CS$ZZ3nFM|xB?_lcw{vf0؋B,&/9]$)}CM.lV! Isl YK۳ e4vDS3oh` 䘙]?֫ 0T}N_R8BNOJJW]G2r'4 V"|p1Nj-r׋M=J{e&Msuio|_7ïK+?mMKĒm^=?;_]/>i"1]xCRT 5ħefugھb+=~AORBDԵzzrqyo/K/waAsYkZYh__[19]:61B^TTB|Ug]Tfx<m|tQF+.Rq(]T<՜'86oU vQ厵-Sŷ|񶓪O=x~>Ξ/me~8$qKoڞ}ommvI[??d? _|!7?lRRexIO x;|YA[tK5ƞ4/~Vmcjꗾѵ/Gs wT]a0xUH6ᥖb|K??G[.gUu 'ֵ;%o;M1~x\D?Lï;)t->Ʊ_1Ur' T623J2oRҜN)̔emmv/,񇈼?bsxIթ*?SVY^ wv` ٧e""G M\ЩJ^Ɯ}BI(_i־:uuZ?jFè6\QDeYnuh!Hltr$F#R*YUč+cqj4 :ӣ@`yO[B"Lt$FpXx ˿ +Pxyy㸸] ^Γu;ytUImcI-"O\_S *xJ|jӄ"TTqṃTr//JAŘTΰ$*~SrʭK%J2:zs%s>ٮBxȘhJ[W 2  Q~4>i6VmUMOi&}{f0dMeLWß8~ko|qL::ifX6St -Z^oĿ2|xLn+FJ~MioA<⳽5{PKG6cEZQJ0*.G7nriF2ImØ!ǧ?gT~5$a 4S]~ 4x:9ueiKx&xsUYLj h0t%9.?Yެ|4N+p[9$1:-ba ,^Oړ|9:¯~\j?5{[]Bfq Yyȑ_7隝rM'oWx!%`%eU"3-xmyQ$B#F2^ʼkѥ?$J*Rt,[t4iY)GFܩԦQvU! Z}a3x jSռ,5uFf2奰o]=CN>R2qqO#1iC5=T:uƜ/t[۪MW0o泛ogm~e.c=>qufPQىe|S Vt"ҫJT1PwxF ɶvƋI2[Qrֲڴu]{}-,`[ɉ- Pn&PVVmd6y@tb#cxBҵZԵ+ONfiP˰躺k|7GvS"v\11e ^Q\JZ3xj5_gRk ٪Rj Ffڔy(j|NҳOK;-t;c1#d=r@9`ds+) z)H8zg'wB$k澏Dw{R{뽛}-/UnSx:udzvsI$w~pZ|@@0AOQ/#9=y㏧u9")˚6Zj[MI%oZݧF1$c#{x=!tg8^X9:s3gx\dd@$~ a]K{qYwiz^w秧@=ztw~`?L|ܞ3:1ϧls:8#qQ$q CK]mo{&y'8?O=1F3a=0zdH{ORs\sf+rIvǡ`cҍ:"}ݾ!I߻.k_I98:W'YO~9L=ON)3yOR2s :`88qSIW/uOtA;5g_w)=H8{cNFGd _Nr;F<ArA1I81pN0G'8q8r}8z7{ZiwWowtj[[}kQ u09wPNr}$9#yȠ1'87sytJ~X$JwvI.5-BLRyO繺K]&M7/%"V;DQh:_;M6:BgX..^WVY -2CTImxP{@p\K5ΡfנG1 XmF x`$deTל](KHM[+VL$Ґ[ɺ7(B*} *kFI:1R|TM/cZQVQspR~$ԕKufX5$8̇G(@;Ud ]Ws}M_Ekaw7aSȪƀ9)ZGe5:Kȉ"^Ʈd f"`c.ʢ@_;\WK4copapgbZЗj󭶤n <Oo.s_:2QmGydi[\ɨU pN`i>ZJ;tM7vi(cs;kJ9g-e2/=p$m gyc?ĺڶ&\Ŧ[=ԢS{{%D6ӻ-_A%]=4k;kXUӒ^dKs=7SmTJܶ06bQ B<ʙ$ - Kq0fx0I)=ZT7oFk2#Ѩ҅R\ma'-T&iYހp/ܒջZzQ:xjqK5dTTRvJ\_ͩ,Fo mlkR̭=YcHbHy,FwkT+aUb-FDbV͑Y?{e,ڔ&t- d2Ecs$ -(d{԰#Q,[`cdE D+fGHs;*N'$VNKbwisnMwdEE},[5=.u~̗VgIl.nBE(C*ۇ"޼(KmD#DzI"UeAU}|eIߍ S'Ow1pE;YDPQ *230I .K]UoTҲVb⹤M'}]]ڶF'dKjilwS[11*DZ7\I#I5ZF7/329hUG9I5|S cIqy7Ľk?P'6SZo,\]"q  p=<'PX'~3]y |\奍Ȣ(h3*ʤ2f9OqrڌVw毭^ތUTo,-ŶmvZ|{iM2G;(U#@$_8Oz$*^KG<;22+ھ>)"M~h 0\%2yk&MUTc m|=heV QrOf\Oo#iJ̿"Dnb R}l{^Tz(w8kBJZݦMZu++_k`{am5{[:kxg.jX |2REW=4|ْ9!SHɵ"uj[H G[KvE&i̔4417y}-ͬR4NUVN+oꝴzt~")w 5](I-mKxfOj6{WՌWJK$0 i,^t($Wa7z=-l/ˆ˷xº.?D5w/+2Lgg$< e\h~ 1^ϯX<%X9[(}]RzZa猹ѵmU{%ZN.)G[J颽eX>yq5Tspѣk:8//'pQ#G|*uQ&&0#1omm=)cF/Mx/tdwq\ƶY"Id~Iy<{,w0Z9. qFYV7zjЩvRN-&س&RNfNm~d}t$ҕA$CvebN Uۀ:9-p'5"$DEܢ7bK>dځ|6>!-zo}Ƀ.9#qEK$;RId$9Smtͥ'TؘBк0/)?)pdШ( r|wc)ɦN/NNM,-buZ:qm6V}'зGQZAېՂO5ڱ*UQ^IncT1w*ϊxS~ әS%i dlbTr8 dcnAoΓ'ʖJ)2RWH+H<0Zx/$wugۺӮrN4MiY_ᅯkYzꝈZ8FYR s(2l! w|VGPGζ |F9';@>uk7&y̬ѬSBwvi ecV zȮ.Av0jF b6\V#SJy]+kmUIU jX:^uO[O ] /H-d!<! d(<*ŖY)|躣2m8`XH;hM^[Kk{-QʼnSyiiw}Sv]7~oGo9xUs/jX3j|,Sc+':xbi_iMyZ87!Fќc 3m85g 9io8ՠ/,&MN3H߁̑$/7GcH` =_[Jmg;&]2HThc+!n.7Fnb?aHo,څ%5` k[.hVFڗ5)ʥZR1m;ܱNF7mݭu}KMY7v,G.]TJMYN*ϖI|OJ8$|s; ueulߴ~WϥƯ,r5wfsoPX"¼r"woosu^1"[k2%"xgMٟ;k 7_Fen.Vin]dJy Pa _6H;gIyW`w+t¿ؐH"'en:c)6 RZ`m+&|eE )qt}EoTm]4iKߟV+QS.~?$6#MJek/l5=:o-kr ﳼ K빷X&Vl;X;[y_CEt VMSXY#w.fgf8IJ|pn'g$h?^":\^~WN9UP%n`rGYlQèUwQMIAV|WWz$MSy. ERIiFϭj*-soN?Ϫo2xúuͥv'r-M-n4߳Y VfD?2Ƞ~̟ϗG_Q'߼7NoɊtoi!OXXkRh9{^&]ݘS~oEaH+(O+3"A}op?VoX o-rGu!k5Ťq9>mek1tV|CrM E׺SnRzW%`LR?|~UG<|zGw9|6]Pi_hX.n-ukY_^+#S~|\_|j1Q(i౒ tu݅Mi"Zh k-Eev[j :ɹp0#k[}g¶v\K}\W/xrE !ԭ OMӞXD+k&ٖ]>,ecmK{vv\YOВ?x4Ki=q],wjV"1klKsqf"k}:hfRX㾚Clmt,o/qxJYmJIrvQ]J|ܼ<ѺkECZie%jy~XKTY9&QRzMF3ڿ_Kf<-ry|f,mIƾ ߍ%' mױ}⧃CpZߍ+YiZ\zˬw{%|M~!zjԿOG `1xg7^ds4wQ,fo?O(_K}ПB[;I{o[ 緸9e-K{#u| Xu / ;y kDG~$'\6ͨ隖sϾ'ϩj |PUi&h%ȤI%v~ɿ |1J\׾I5VW\x+࿈:Ė7m>m/uG l|cw%C|mmO**I=]Di|M< n .6U5Md!$~2wq=[U:%۩O*\(ԫį:Sҕ9F E47g{߹k$e_HN7#9Udu%HD0H@&gxA˄Mz1ACo'SKwp142ioy1,BR%_O'%E'b!7ď#[iueX11{).?OGIpX<۷T.&UAGڻAIc|Jtr:ENj7qo(uIZcxL9ݛ-ddJT'kt@_M/ ߰/^?~)Cq Ek##ɸG,0i^ͧ_qe<71TӮ< kM^Z\宴.]jO}wiŶ>#&ytXt k:fe\[l/ޝ?l1|2ia|Ds?<|_E jEO>%K54wź(@<[uoq[)~Go :uǂ|)[xKWmĮ6O|Dn>xXkV-FxNlmy'|iKbrY|#5դt h_4W._@ s}º;Mv[?|J>ͫ|?ՙ?~iS]Y.j5m UʃNyo]]h:~%ri|uwÚ oC9T*Fxݢ, \%cOJ 95o8EXwnKi/3J|ƚI'|xzɖS/H-K]IiΝ໊X|A,^_~MxVp[|,? 8GB;m2Ӣo^;K o4>ShTXi£hN%yaT7{UU5Ԕ.c(P:Kywq P?_2 TO7ح4*S?ggE2[;9:|Duf\Zߥm/ڥV<ܐMH#O/~Ӄ|%jb6 5; 58`I&6Ο*jP$)d67j<ք:um/ QI(UT%MF(N˱ ]~Ҭn"rէjI;S$STW#RÒy ]E# (YVpZD^9i%U[pp 7~cg_~YViYU#M1M ĠeeIc}H˱%]|λN]uH #NdF*BlcJr̴Oge{&ݺ吝ʫJi7:D'-o뮿Ki׌+3$FLj bQ@{m<,o. Vul;H .`O95_Kŵ]^bbnɏi3oʴ! F@;V\ o}oHQWQ.e],r-v-fP[:fh%il'DZ0.X4nz JMlZ%_Ub S\J1dMi ZUPFUK 5[Y,* PH!W뗇?+sUvC &~\Ž<>{UNծzG5Z[&h"jj[?CIJQ3Izj=u]f"ҮoYl|.i-Uḛ^ƪ^xv'7#*3w%Oٴ՗,S6*񭄚Mrm?gi%d[f>Ws$p8RI38$PNO9sUAI(Bͽf9xD` sP8gfIwI^Muuq5̼ުy'nGp1r9 =2:8G34 N `p1sSFç^}q]muѥתMRW^}읞g`rs8Ԅ@Ϩ*q93`#09bx88G9͜118< =~~u}ߗGge@zq Ǿ zE&{n@8$g8$r1M;$ih魴]zyoEN;pO$NN34'zg'1{zFp1K@L N> -R?nyZ#uNC psiA HG'S0FCN38c=Oz`c[@Ֆvp9?;23I^8#EO>Lfr>Ids3NG8KKGV[]B' ~Gsq@#$w9b`H=:cKo7e{_^zقӢGuꃎÒr~QpA9냌K9<׃r8}$> Rs1~SF?'{c9z]ӿm?ulqQߒr3; gӁ'+q;rFi0,v ry<# B{g$ @ ܜgQ;iZ+]iFR]^+}5ZU[F@RAr'}- 1g$d 9x'9AI\ zsש**;8-ex_8,nJc'9jy>ROBI$`԰8{zc8,CO 1mMoko+#f5񀐥b!KX@yR+vqhD;~'hSN^Lּyx (czf4X8ݥ)999GE^}~#{xŞ?u&u:jw^!\m>8`Y" h{zśzk'.8`еI/RBG3RVԭu}?Q<[cVzu][j kܤ}1nˈ,?06ozig\G ֽ y<~[ @SteVQO.Qq*Is9ɶ9) ]gw+҆J.1N+KފM$)45{Y_TѶ:^n%Jz#DaRXl ~W!CfVQ(`Jtּ^օ ihbIYIiծ$J7V~mY讚kmҳY_j(ql7SZsGo u#;vcs!Kh/*?͎e ŢȭnuĨ 3LHU)(w߅3&a%]p%ŌX;XXR?{f%/>* x^Y|DH`TdbźF$vBǼX։OimE`Ax[_y %FUHY|B2V[{{ⷘ'gQcmJ_(#VA_S[=I4)Ջj֪R,ӾIw^_B.s=bvH<JYB4#dZ/.(bֿ/A(2D]fXBDPGu0V o,# H>4s6o[|67c|l^EBPRF0Q]M '˾%6Υk2_:eY_W̆;Z3lDž% PӋkWI_TV/57ZY%2O io)k'>˿=h3yK͛b1_ h.R$yr k{eaMiVVߵ̂(#_DfSed G#j&f|KDǧlSQPonQe[Hm>FU*[Tv-p7Z[eH㷎*ZMT愛:++9?z+Gݓa&;:sUy"Ǜ˚NwJ.JQ紭.!-,会+7e-"9n-vi&^yDmi1Y"Nnl4rEot,ڴ,c ^Pŝn Z""K-^8SiY׷}U%^ e͹u-r΄6$v'c:n<րU)|>?*VgYbeBݍB#=g_ݘLO{FʙTmFWO50u,64X!. #۫ܧ$eK0Q֋im:%z>ױyJ/]iѻٿiKjbphBD$Jnr (Ut9/04)ʎ]31Ič=ۨ2sruʹ )[dIHx}%_.$ DqST<L'?@]#yYK5ӗh h ldGDN)30$7.I"xfb@]ux7C "}X+r_I66}0ɷo |$A}5_ⶖc3nX[{mtQ<6u*5?)AEy2A+fʀw|٨4Oq;oi8Q& Em evq_> 594o42I7:1dS Fo0CS.>H21,O5{"2HH]Yj޷'ŝ9ZNdWvhk.zӍK8a7W t-.2,ճ`> +5ġ#v>K )E]"h+6H}䶍e;䶙Hs|$P @-f0]1FB[ĔܟyI E(;zϢit׿UON잎]5o|CtZpHQ6(ꭓĶ`cylX#*]ȃ*I^0;ߖM7u]礤T)՛I{];7xVY>5o-l'ճ uK,^+I>I=d7 V;.!?^EWe N4k|]{}ujo:;[mđk0WkVCڏ.~iS[d$X@t睸$!.N<;P w N-GV+mmEK=BgXaĚݎSN[2GŒ9!&v^ d2/r Fp&]Nk~1οs4ղt$bwkn?3\5 nyFcxZ)*Y5Rvi+s)MD}3Ybg˜#-?ߔx z%yqs.BE;D  3꟱썦/=ѭ^D_k rFm!:]y{8Z'xTzYE7%&z3 k=^0o:?)_~xOͶ6ZRd"Fon,v1fL~sg=Swí2[v:ڬrK zrGer36;Ifj`Mյ(yiho-cox?`${h,Fi7y2ewb7T_:_|ukIR!Ү:-i:իi!.6H^2 NS1tۍ/klQK >c)WbB(p}u 3,JU*Խ}:?uJiϋgTh@ ynn,cMՌj۱|C0EyQp &(_#1G$wvۻj1XcЛV~+퀰L~ZE]u-dE@ln#M۬LR s1m1t<,`;k~}Qq+Rygkmlr/WYd{J)Uw|wh}VҍL3(2+sZNv~_%$kbnb}Km6}ב}5ww t ./fiOgİi'rDM z{JLG3Y1W%?g'ZK4'?6ym)?PC]]F\Ag]+Iy^)kxo?ச1/1Om:EMabd<7ڶ#k?>'d۷.+[.gZmVVh=I8:UG\5 MIF GQp ۹aua?6iφFDzB$-6dNO)׶KlL|fQ-uwE- l}2x/a$*ıG &" fYbk&f- _t>P%ii){h`_]\|wu=?ƥPX:um=Eo]G<2ȯ~A%^MlWI{\.snRLɮldi*)VUVGٳĶ0̉f r#xco7Wj+PK}*$\¶̵P"\H@IQ9Y>^kӿGei~QR(fs'n1hoW&T ,کWj |Fn4{t6MbSQ±XX== VY#i?_4WUәu%TEcykg\xԷ:mMsqq5EY}΋(!i[kyZt_x6n ]Rƿlgƽ/SDiQ{+]^,Yo$ϘsZH7%ı[iz=?x(Fj8^׊RwnXܹ'Y%hZiRmV̲?&I}_,nIK*2ԣ:SRTjђ"1k>45MOGkuv |}nIgc{iw}WL// nC@u? --䑋M+dIr!TR| _?u/*w J>Gm֚u:o} ֆ)5K=t)/gXtf~c꿶w{4r< "$ 0oKbFѪMTR]4QΔ 4'juVqf˪G1#wzɫk4ԒJK?d[ _/U hXkGXEkxAntG?'88u+Mlkz~$[URE7y-nX ]kŕݮ%ռM5߳vVEU뺌x[Ėׇ֚7I%[{&J5O- $%tmk[jEhDzAw$2eHˇ[E,ɽ_f.nNʔ<*1JJFѩ8҄NPjR(Q(J(Wzu9*u$jRZt(W#Gf^o /46iưxz-ۉu=JU⠶~/ռ!,W4ծu{Vs>%GQM~˶i_e{1[!2HdyZʭhDrK# S&fiT*Q1gIsfއ8FYB)ٸMV%NZ]6. =KHL![|,V$(*9<̲agMW s<]Yu(bIkeO8'yҹR~+*;aܕ56QrI+IWx'3DɶH<7=iia y:,^\u7RR?EƙH 1=IUgtVemlVx yk&gcŞ#a᛿KI,P38.!q-zϏUNJ,$XKG>ZfDc&|MM"Gw-&a6ŵH.B=՛af821k6¢äNR\֮xl< ×O Oݵe(J+~C~( V?~"iW[ 5f LKwk ~[\/7$Bֺl?g/#S&H:ׅg&CwèB/>|JcM;T~Ik"EtY^UW6A+Mck _]5Io+~)GOكNw|ScyJ^F4ςѼN/Q]VK~ES ϱB^W<^'ܛ|Ybyw*r`<қU瓗2~'QsXʮ7e^LeFH(8AF4QR_|Pku;TdҼCmwGs"ޮw. K m,B9K/ JƲ,0-f ,KT M2BY[kK mq}6/1yđB =dd2SwӿK{q|%(b%OVrM\nAIvH.1bJuͤI)8mknW7+MIW;+O֊UVsYV&J=f}tM >KKXu)4<*CM $`jGW;cv{1f|f6q߄6y$W9Vx76R!b8! 6~mMJwy|.ERȷ$$U&˸OƝ4]CG%3@H](G\y;7.,lj-:8OX> ]fN3T`iÝ4S弟2v廏WjeR9cpT1<]BѴ1m;F1Q^a ɨJ1(/Vi+7dO϶:r2=E$#p;9g9dcTg8=cgܷI_TMk6{{y7K~ZSi ;98#F2)@r:sߜy=၀ 9y4ws'RsNsiӽvJZ[wfM[k=$Wqp@G'=ps8><9@<ǸF@g\$ ^0:}[z[EM>-SmYj][o]5{Vw8$Grxtc9~c$)go5G}M? r2x@u ^ dhG>Оs Ap@;2A sK7WkUVY~Wv'遐:Ap3)98H8'888#L \c92z|$gWD[.+/Nqc^#:@y1׵IAl# Ӿ&TֽZ޷>'w:z`s^rx=9nIN@$؀801:uKUvjue-^@9s=ӠpFx)F02F8p8<ۓЎsn}8)2A rOa$q|uYa]|ud s<yQӮIH7|r =(k_mm켟^]m?T ǯzqo#Ad;G9{rJ=1}ޣpps==N>{yy//kkt{;kE g휓= qF%r\29$u|N0\\nrIaRIۻ$N?n(ylVM.y"ߥKr;rw89'9'A 0q܁xa$t@'1`qQ89 y1G5}tWk{4dfE.ۧaw~S< IGEu-@ݜ8$92N9ݷFG_ ,F~FM+^kyY;y+-'YKU}}ޤlۘ1PH#/ @ qn%y$uiubxA'%p17$$>lG<%񾬓Ke.mDBדXao-$Z8!*'V*rVQ:PIN[FQ妮1Wv]ʣ)(-ɸ)nR]wz_]g GLumowq"#ԮA+ȗ s"2mkEkު,njZ>YK D+;,p 8%D7km爵Be5BHfT߽S'eiV#IU>mKHް3 f I ,n]AԄ4۩9Z+ʤ;+tiWsB4B tݩ%xUE8eX}: R>i$~&.4_5ćRc RR}JiuAWn7>&͆FJ}O^W:y +I>T>yhDqn<9W6zωѬtxľ.XaCKOgi9{䳂˖QJQ˩Žn1$©^vfj5K%y"(vR~WgKoxWQ{x^U{&̲y)̉l.aŨi% -}AtVZfuv^ NAԗ+X%Gߩ!qxֶWju"2FMn"y7I$bƈ(r}cZZikgVRmm}vjG٥sa7eGR8e٥TtV:]DTZg‚wg+' J ad+C%׺HI`l]TtrY4תVCuw$ʢ,7 oGzv|6[ism%$nQuH io dZKD%Q3kW&w˕P@mnxNӁkaȒZ;~hԮN3a\3F`bŞ1?0ʬ_ݡqxSPm8myWQy 5ų$2+۱Yʅ ׊QT*>q{lⓍߩn36Ed굋zρd>jF"զaVs7WthP!i N6Ĺk6]+NKVWA4k,ږg VxmWerZ<|,';&ծ/| ![ĺHWcd !Ԡo$$g|sKOYiO-P $9\@`)PM~9$VaU\"|W(X +x<57^2]V4Ih-P+Ț4s{T&۾WZ&׼z%vW-)FmM˺)$zn/Na6K,scI,knj2 %>TW9Ubv#gY!~#hmݠ՛֠Bhp̡ſ^KatiOo]] idHcv H%#ϊ< ueDDgu w]ɹUU|؈eO^MD޷r>/WqJxL[mӬ&ZZ~@4$*`^=WaKx_ɶ"%u2jC\Bd! FWǂ$*Vq;$ER[qݏ⾂#x~݉.(Y"&6mB1C}/!260|JK]n;n|~^ԎףwvӷܩLn`toA HU\#"8qU̬ :3Vd8I TpB`g[s*ߏ77-l%J"d&}\NV]Ⱥt.".k'E%|BlU |H(311kA^s wn{%e04ݽ/ʕev»,r9]<egvX.ЪUCWK .J]DB_m,(9;湟Ǐ fÛ  d!'h±\ sZs0Ui%L$[٢F9!uU ď R+YQf֮lqaSxkItnodlZ,jWTF U|k%!OCU*}IG-jHH l3١YFYcrUT20] ݥʡRgp#4`Ie\"~e!'{|0կqSQGo}acvH>kE.Քa=mh|t.nRܾ Gѽ:7-ߍ1{q3N,D9(0WRTYmxԀ$O'O^-oI Lj|#f4O$m.|۽=[#F`8mJ|Cҵi' / }/@ӯ3Ӽ;$S|7QƥokV\0{?[mqW ax[(ƼZ۩8NeNVaRZ2'dXmwScj8PT^O{9έ^W)ތO??b: `om_ ["chX9 KNBPK X_>̆"U0ܤ"Q_oo|Y ~^-MbM#5;I Lt{oֺLH57k+GK'c7:<gExK1Ҿ(O6]ėvZt7oiu{Xd{a2_ŴLFaO2pѕj2U<5YasRs T|kr>mX<.SN^NxyFt o|KXgTvYdO AU8VsuiƔOU:s-R R<*¤\RP"p+G Vy>i1N4b)pQyh>˚pofo+_^iijΗb;+ /Z.6 AܖtқkvdO+t<|ĘC^YyY~^s\؝:x7J}IZLf H2Gx[Yޗǥ4[unOw,IMovW; [ڿX;~(|l4n9#~9\j2$CLw}TQ..ʒz,ɥkh j>F{TҔqdI4Rm3:'s_ a0][3Í=[Eky #L.>,Erm*8#?7=;k{1`"e?,4H|A!Eއ6KYU#+|tMRt*~=r+tq }GIӼK+;&sh̏ CG c/"j2iHa{k),pa߲YMUOi{WRJrml”?X|>ݕXJseM<knW(J_V] %n[{OktdrN7Mq{)d?a_|+ٚT>>DP2M?)v/,Cw%[[T9: /ӋII+YJdۡ0j&-sbЕ_+ erF gk>0q,kq%nf^$޻K+M'~[ͦҔx7j~GOBRm]Mo-#|H =e6'e߆) mh#AB7r^ ԲX]׾n9x[y_J^9MjFyKwqpImLaӮ$yM֍i-~~ȷ6~MrIo?|PNnluhk>wvbh>"hlqouo) nsLkM7x8&nωv uݖ_߱O2vVi2y%ռ?l"{IRȸx2SYhu/*dR0$~(Ѥ/y$ؤ2hwz,vcKW:sI30Ծ?/Gx붷ED}K< ->WԼ'~>d-]5u[n' fc ~ug!47**œ21%]=>x%gfY')4,JMܑTRoITf%i?l|~HM !F sltf&AH'wxU0GV(Z8dl -/Kknh/죻/h8 p {>#\Gi8+_J,5fSD_͎i^x1=N ? |X\1eړbiR}J~$  kEqE`.~/`!>[AgyTc~ OY𶟫¾5mԼL6ZbY%7ZHo-6/YvyaTpX )J)МyTJJr=8a+jj**I_a֩#ZQ5=<}sIEaUoS{oI_F{Säe[\]c^!q\]_||%jXŞ&bҬl?i[<}{r,;k/Oq4ݢO_دeϨFv5#a NdS?g hH4k{G⹝CF?oό]wv]ZnC'[I'i R9סhRiQup#(6)̣nfτ/$~ʣYV;TF\oh¤UJSi9(NR\ܱ=kGu_5մY4o 7~:8o"k7mS"l5KSSjzuqfwS tS#i^ѹs㢌**P4~x~$j/xc߁} ^ N#Ҧ];_snG{;1 xKT֯Ꮙ_MCXo~$!V/~-|u_ 7-xzˣսkgŦC\\M}+ktFP`~A,qO~~#\ndg1Rq3%k?ko>$Rʖ.= Y'j&h'eY֍G:XT:2tUQ%iUn9J2 )ENld'(җիWR'RHemҜM75%%7 .@^VƗ^C0|(INNig>wgs=C߳ͶߴO |COv>  , 3^(6bN/MWI4O4+Ge[%F|๵O"J|3[v,)с]̒WOxv;gM_A{w>j^7񖎫_(E-5K o67 o%^A&5ta|+bʞ )ɤe^+٨yBnhr-FWVSPMRAԇ5(ҊMtBsk9B5*[<(sW45_^w׀C%m[oicmKJնqngϯxkݪ>?uLncW7/ X$QS|_" *h7SW~\|lTa?)m>|J5K cڌlܨSԝ:/eUtee6s> >7B6iPUq祌B:rS6eJRWSNOm_Vssዸl54tK/nCLk[!sx=L^!ũZ\EH.Tѵ*儓zWWf)OxoAm㽴A}0ƷPܴZm7 3Gp"DE 3_b0XXBWtjQOy85TRwp咿1^ޝO)ԧQ*I()ASqg}amx£76Q .w 3|P]ѨDZ*s|3Zk,c멭yR^u}CTlW,k?4𠷝fEp ˻[9DOm5͢g󤸉#&_8ݷ|I^m iIjL3]ZE}wiE< hlXhbprE9bSVn5=$vr")EZd+ZQT5fݞ3ko.K׵۳EJ-h xWl6L 5z_OV x"T"m@^V8 ̠G \5WV5ݽQǨޑq=S-K4:25H O -m++=֡ vK6e2" vHReP̩ա(E.T۔ztcS107:"ͫ]6 s(Gݵv~oxVѭP`u[[;?lV>ЪQ*T,s@YwJI'u(&|I}IӧmE%-b($# ;9kW0red6OzU\G}wGb۬۷.$2xT; vu<1eeCQF3JiG NoӫsRѩRJҏxQJ:iiG|xNg#^s0}x88; Q.a*Ă7GX1ɐ )q;{ԝNN]Uնvz;ߣۿ5>kw鮗"lc;8Xy#{ccdzëc9<{qp:AK39;@϶O1MUAA#<8 c4+coNq:$=Fsנzد@=t=ic qqG=9Oݴ[k}ԵZ{wqF@P@s=niN1ׅ<9 ;&q`:4n<O8z瑞OT]iuvV[iYw^^{0=A ׹'d\rrpzdz,1N'glr2qוU{=ګ[~?A`@$2A #'pps0(AaFdO#3[ly= /;i_-[iw?`L^S0rccA5!?&r= 1'qVuyP;8n#H IzI0 p#9${YYl,Eg`pN' 3\CN*SQr7qM^kGf浿ptqk襁}7}㾚|+Kn585Y[\ܵɧ%[go-[İLa YޖEgYm+r͵~MͷʂݿiMb#4:hH|\oR 8R2_4Y|/khCK,%yplk94X+:7Ϙ|[S)mx웓VV'{x%5 ӓy7Tcui==[v~M_ -]q"!:K --,,C*εf:lZw-x iqkiVtM\^-z?ƾ<.䱚Ǻnk+ Ƭ%()($A,$wZ kIGˣ^vLr2_@31["AC4W,hГe|>1抲q\QIiEIƜEJUڔF֮ݩ/y5^M-GK4HJ2#x6mē doegfa5܅|!.׃uwgf:ٚ2wVvkk:$l8qtR˻b7kx,M6“9ym+u%]U,$++ >&ywHX\ 'UA$9ΚIД%wJ/{rvQoY[8T)G3VViI~DŽ.wj(&m>GE+[lA4Yi..+ܲg2"C{t*v45@)˷DD$*-#ѾDvxE _#Ny4R5ġp;r.)~=TJi 'D,S2x k#) nj ke>RZL@7HkM6`UYd<ii7F@RQ`d2&}/$ouci:sV]SNGdY"2=F9F+5drZl׻WomS{RkajJ/V&eIWv3i-IZ}>'6#RuFg{gc8̬T%IJ\A7L"8/høoq-ܾ=&OFc$+}8m&Gr۩SZ愗2B׺^h壄:lEktEY LcAtWn[8mM'QifZkj(6kx_Ñ5{pNg v%:b24jq)(zy<6"-Bu4( !V 7ǯSZ_q5{i?u[|'G ۷o/ۻI^4 +w&(a4hhןZyI$i'L~K$+*|n6c$>?Kqk%f3Rb]O79>B<)86uq$0HH᠉ыBfF Igkp͕YIAVI''Dqx`BxvHJmLRm'Y]]YdջW&ѫ^{؈E%(%j}Ta[e[[6MlrxUXWqI_ Yn| &᫈IHqV"'b,t ZD.+xޗ:=nPVxFa @7$ !$,⒭]j]/ ZIIyyIRh6BT\1oVkVMVjFD̵m]1WQk6lӓrRf̥ZjQL-IF7#n 8fexndDux- dM/BT9 )ΑѴv}zI|/(Ǖ}IAIV"&{tO<.%āv3YzEI o>K.ܕ@>fpTⴙ#|SwHwYAkc>Y x8M))q$йQHBmg)W~ߞj儵}wݽ/K+ {z $I(򤽣.oYݐ6f*6UĈHg糌Lմx'wk\߱E;ȯF7[ g;y:SGFE1GIc5Čxliiﯝ& XDY'sYAFb +$//[>y^~얷]%~gk[IIFEh;kKD 5e"t./c;PpTJU71'C~'% "~;|".匈EIEh+fT.[j0Hݹzd! Am$b1G\++K {=3(;Wv-"m}դrEaQ8jKExI% O0@${-jiN%{e[[l"[:so#~̟g|3' 2Vա2XVuXR#*9P~<6m?k u\xc&Wi[^K[Υc$42i/7sផiٯǏk][6HL藚[iH`X-apd8-X]qEc˱TpE֖q0]fJΧ49TαY O.XUhBNo*pONVӄ' 5.yJVqQo xš|im _KE]_er-VOi$&F'oƶǿshw=oMӛlWi6| ڄxWש>(]F/s`)fۈa׀)F0Esx8ӟV?]Jc 0ܹTuqsªͨ] P74}?qSaӿڔj=rWlvڕZwohb{{y-mu YVxU>?~K׏d?nlSQ5S'tkMB}Yu:=3C[tG[~7x G\çZ V_3%~&F 3UK_Xm IhZpCkc? d x1i?hV jviw1+Iosoo4|'O֧?o .E:?ԫyN,>K['(: Jjӝ>YiٛJϮխB*WZ8"a(F'jhUMI4h> I>Wϧk?A5ʹW@&=Y.ѢR푒Q 2[w]BW q & <}%HH.՜Y1𖳧i f_'7kuʹbS[kr.s5W&嫉%0 _ k% +A.U\~<R"ӣpIVqm:GbSTNqt$$IӄJVkLVmu\sT'SXr1/;әFG Z7wعԿeed8`%=]Kr}8 J^bsH[Ls_'x2_fsf֡ V ڎ4HE|e/C{5O*ύ-%Ci~zHgզ|;er^","D?t;Q2o+$KgA]4&G6^$qHI$BM﷓*~Sm_et^mi?%NU8.V<@$aJ.*QI^Gԍ#??dĶ.d!b(\A=iml8iU!ҵ98wSӯG<*;ٿ[9n/5 ΁s{6~*"Ev; \֜|bIٞ)%>|sخ%e.j rywV_a4?b|dᗅoMV F;=%ZMώM־8X5G. 4۷ˇ!̒-[ݦH$q_rˣgo3Wm(o&qY$Wƿw  s!#g&8U&]\Җ9X R |omF? Ct;@VdyؠƧ ¿d#izfox>5+@Ytϟ'3o}J,Lߴ$jFdjQ:B݂;&s'noI{c{o\\“˪kC-zOh8?cϱTr=u8 5fMJ5)%g\ e5)v2 YJ8s$*]ٴۀ-{/R;eitĂ3ф <]5|WO[Z( ,>sG)ma#; W~a-7RHJ\M ,n ƟǙnLK6,Y_?ln?j*!?!/(Y"y~SF< pP]LX6iQG䮸%yVoE;3|\r@IWS+Qk+s]Zzb&/ə]T´HV}^ߢVݔ*EZJH׆(,4 5Ez?z2ܜc&zis^i3t):̐fו)fh,[$鵍Q,@k럇e`5э/,‘e+ z ɹ_&`\R99}]_XFओ`Gq ̗A􏇑 >=ȸG71Y.)ѻyZIrWJYXG~DeUivp;#o1!eV݆$aFST-֍-b0YG};]*Qn ky!XΟ\LT+źAJ/c6/L\-^b2o J]< O26 k'bM|5v#O:5S*(EIxF|Zr#ycڔg׃Mt抷Kkoo9+OkR4)axZ.V%u Cυ"t].[V 4"1&2ka\|blnS`ߎH/%[ct'Cô[u|9[uW-% "{AZL?dMܟcE}3??Wk[u MMSL,姷!5ʬ>*QCQaPeoM5W]:&ҵFˢ0ׇኵV\|UKI5*4G&ڔ%ӿy2+ė]Q3IJ]kV$IwTԈ&IvD0[ԖG/bBed#PrC5Vّ2dĎߧN`LC0s"4Fe[<2ծa{ѧ"41ToʏF>Gy/sb$s$$JHngGtr;8cKG(aaAF\ҝ8tNﮩ諉jCkqqh55NQ;G%ʢwItOG`lONq~ Z ᷚh5-3WZmn.# ا)::3O |Q|/ xAeXxXizwksxr=\Fa~^:ǁ/_4OV3YҮ⵹>x^eXlV6}l&xG3][Zj]4ˏ~6t.u)sm0´+fKtYO-&ghmNĺtR<kx8Jʆ#긹%(ʜ*JPD?s*]`ƅWRkE7?!{+^ Iwӵ4|wai~ <3hrWcbb[SX-t}s?zoL3㍳J]#8IdImPt?OoٖM3|7OM7R:fgvGio[iZǃ<_ak qh|GxW>0x#ޓmZ=M> zfY!ּX<:߇%KӭҾ٫Mi[?ďM8'e2~đc0u*sV𹜝jb*򺖏5d| M֜b\%c%RU!r\R䕡>OFXCG #%g)WY6 /*8bDj?¿YGo_hbpıy7 -ʪef W@}; Gl eU| 6tm#Eϖ~K$b9/"럄ߴKփѮ"gN bC61ț]VC?9^!ɶq=i]t's<%̯1'drE{ϖɦVpn0|Oj[ !u;oŸW¶GSim`R,G4!|yVf[xރS}qqxcVF:vo27qĦHX^.r/cG T?%V4pNU6TlE`ԒoCNsvJ+tiJϙ(xs.Ak!jmȑy~.:R&6~wrD^&x ~<O׉y-A \)'ڵxaG;h$0ZVO.F 5x-˪,QA;HVV2+ۉZXъ2Dܧ  >!)|'qJL)2Mi 6ؚ}]oĻg庶 ObCiIVMʜ,U7a'KNpR=.L*2[5'9J*j2Z8&Zk/>ob?8IˮZRA[tht jqs$zwn^"x:j IZ g`о*s.g%G#F]pWtۭA©.Ou+.<^P9f}R峻>ӫB9׭8p& Vn)tvO[5n\NڵΣuo*@/\ɠioo$6&+;$]9x[:LN;gf}]s$"TeKI GuuֵiH8;a+(̌ a|jx>XЦ5*ޜ$䟾i[4ϋ%>Iѭ;& ] i0ņ,C4X$Yrco)raquyN;IH'=s4FTM2Z&UBQ8,\>ÂHI[ r@=NO|уL5(Uxt҅:jRN0xI8{m5IJs/#([tq_r[%%\dd`󍧦8$B0*e;K13׌A=0r\`08<9*FI39c9=FHӮUn=vw7U~lᵸHpxG\w#$AxcE6{=;B2y50$0d <<z:VɩZIyِ՟VkOaG͑8'ۀxLGRlzyX<^-w##q9<܇u{4i\Z_N룺dcNN;ӿ$} (bF8cn'=HsRx d瞼 c$ 3ߑU-V㤾~v_1<@\Ɯp@r3'~OP3$g=4ARy`ï^}98Lp~җ$/LpOLǷ8`sHq '=z>qQ6 :cb$pnAg Ԝ\?]AtxdKWK2lՃPZ"6ݭNJ,>](ҫU.ksCF-)JK_g:|mKjt}w[sA%ym4ꕶ痻ron~ 6~n )@@r `n7@96#WvA2XH%_lq`F KKz^5]NQ=_\N#i(\Q"c븶#jO8O;Bc#z/,~.7IUu#))J>Ƥz4ZIZ Ԓiou;wkNNƟ6Ɨl#l,؊[Q \$SBYl.kL{5tԐ'kWZ OEZ9q$Oy&A@4M7Ɨ09S0kEƲWHxaѤmu<}N[}Iēy/ݖ}?vo4R rR6QIJKحCc+_T쓻_Vɨݴ?|ok 3% 3yT:nvVH'ggds>/4mGQM1fi6XHk˫{㺁Y~]Yt|ONj&̓>ⅷo>Ayv|4dd!&0D>k..I s.'kmklZaemeje0{ݥxlyܰ8]VyCyk/OjpKAθXdRҿKMFo&ܽw ]V44)K0|)Bf6 mtG'pL-ʃ=w){*k(qtVI5;ˍ:{yggA"2B$ y܂,DX9q:c~(AnRqddL7cR(dPȩV 1Ti[7%6.I7O #$,jS<mhOcʣ3CnΠHBRfM:(5i!/SY"7_:8+"Ɔ5TCmh0WmbY[Wvދoe6}^d˜RWkJ4(v\W,3ѯU!"Z%i!~"KŸfI@%o㜷7>x gYF9u82  *`LNY $%t &ʶ6xDm-_Fdsjܼʡv*jBrɑXJNʤSݶ=hkߡD_6WiF5VʚQ{I[Y7s b+y=iMpRm$.oVE'6 `;Uvо|㳴IbKk ꡖ(<Љ6|:@(me28Ν#ʊi%X zۺFR%Q^yx",bk6p. 㔗Y|H-Č4iFaH(QO%cN "I2}mD1:җ0Q u9Ͳ 1u.JrIՒijKEm,io|O)gꜥ8$SjKrR]Zm%;hں9w nR yyOdFKK=K]LӀVylVLƄ}H)ic}Ia4Z4/2G {94-p,_cz/A5;ses"+x<䵔48G4Q, j3qճB(=/0Mf{~-6)J-(%%wJMݶϓeT/P*Af'!Ic$+}ݣz,WLuQK-~|5Ir(]B/aThpĞsz!ss| xa$(gN ڍ@V'te8Mfu%zj7JuZ6ݒoK7, u^i^ޥ5Vm6ݕjS܍I(%&w  1 1l6f.\%Ljt.UAE@vF[`PXcxhº$ox.Fo5e,"IYD %ؠc#Wq %2l Bmn/vҕe,mZ벳myҌjJǗk%WwZM`<*?X(t%m;VkjdUq(k١;mR6Y&猱ede炋$ڊm1H#$˫hJmP7a@/a'uohKKY=mua'%Õ]8ͻku'ʚMZum>jrdJz11r2w`v`B H.ٕL>bKp VIkyU‚3F*`YA8` <6(#VyP L.dp9w` U5vJͦӵI5^Z?yT+Jqz{9?|Fyk7ڭ*Vș8>eSb#4βhFy4(rA  H#=I_FdEr>bI,܌%P,{.Yp(gi,hp$v9; hiRU}Km43֬wWzZ]W{ V m% "`#38\5}ȒGO*ԨYX,e"651\H~DwwBdKh>F÷c go9k"$8&IB@\Rq# Z + \9ơ_Iq3̫emmeEI>l? V}w_>?:FmFPѯWƒEqyo2ZYK>i>O_׿c"{)c9~uqx| >[oZob$V7_]+ʱ&n,2sg(8O/d(^m(M]IO[*4R7+$V_𣄟,w J6䋔b䕗߰:ݟ?Y=7>E,נ[;ĉI4ŵ7'Wɷ紻~oKlo xg{&v iAq= x&n$-^DO0 C]'4~$¸;MdCJ\{ nnUYȬncKcYग़oA|~y%)]b $,ਊndHdi쥭!#\kW [rI$xRewv>*:b\^m9ʞ)KV8'!X!k%о4 +d1BMo $eghxIb5?dFYKSM%徺XliM: *Kj USAt-/`' '?d]OC6=3Җm:Y-At JA5 ?b3 Iběw"]J|1wocewqqF tNfWOQujIE'qlgGþZ{ᨸ7ihbT.ɧ%&ԓm .$I!e1N˧R.u;sAA&rs<_U#NX%7Hēɩk5ͣqeo,ݤ+J<qk-u[;V sWZ^#ٵ6?(] ;dtTd6wJ_b}?IW~WQq3 Ч:̏/ jfK{=Z"&n.żb?Gwo > Y?||Hntq$:vCuDPjs%Y e\B1KCυ- e=uӭngeRd0\\A[ܕs(T,GNYE OFҵ-x'pǦ y4[Z^> [RKmCKռ#Un3[_UfP T$PKw1,饋<.5v.Koe|xkEӥ^QY]J¬jps>U}\zjPP츧.OF?7{(Vl4.XÙ7ۃrOo*c~$f_Қod MKAOdv%ߘqkqoZ p09|ߠŕt{߁bjS1^'ve;[N$Cge: }"8e3jsZr3N.1Q]NjsB13Rӫq iJu0q)Bcu$,9O?m?ۙ\OR~VfhOq<YDבu=2J(@з br[7Ԭ^i4-HMͭuǟT<9_c[\+؝uO&%ڧuZj]GqsW,O6-lIH_NgepxKxtG?%h}cTUwݜ{lRS=Jr.>ӣݵ(J278FUqXP߽V*tb)^|̯,l4ṁ>5~Ri)ë7siW香Rssx$bQK/iмkSZ񗄼I!ď?`:؍CŞ'Դ^_[4 xdbഹxN #/PM>q,A"FXH231RR|ZKŸ+{ojA$׉(x\jVwr 2W6*j.cOx|bx/jР s(օSJ.Hal5qӧR9};S洚O?[GoAigşe-Dhv$l2ZZ|hGM4> + dE:jj.ue{K{JmIhO{ ,"Yk^7'xzqB洗FMkR]ZmD&i|7&׺Ukp$o >@t97%{eo$oҰ]YuzQ];̫cʔ*bcJڽJ%ʥ7NswU%Q>W<3PT#|% ʕ8M'(CǑKHst=F'sχ?k,at#wxbrAi46`Q?E̬mટDS]_($mcy2-4Unq|;Þ㟋>׼AW~ּyI}c'5-sq46 e`l=U4K~._Mف-eQ\PO,qƫh' *M} 㿶sqxNn7ٕ!xA,EPԵ߅& }OV׋$mg%>GeCiF^Rxi\v^Ɔ_9,`ZҳWSiwݏVX˚񔨥b*7?!1l_\C9bΣB@ F!˹mY PUn+o $M~N-OWt2k$yH۰f%gWbbe} 8Iw}aiNZ,ain>=dRneD'(]~&9[$ۨ:F?~2$cٲ:m1$p$qI.]r)%oRz-坭dk(Z2$S4ީ4rʯ?MV^~חP[ ĬKq_Z,3GʯmMe$\H*ۖx>0x{Mщjyw|^ʪ rɘ!X<b&U&0OŻAᝑgi 4YN3-O.XmϊHC JWA3:[ :q)KĺzST[//"w7~F󪮞#WssJr4w~emo+Y]uD _??LUŵgK?ٓ⮋3—x~4"Fn4?|{yK1imxda?m 7{=i_uG<'Gws]5" \˨xͪxv Z9A\M_'Λo浾񄗐DvM]FRBuiҏi~&/5v>'POZhvF&K;H6s"$M#|~~2^qd'N~9 <4'MQvͪi`Ԅx8+š}l/^R(HKWf7 eE^j_<'o\iZV΋C/ kNֺWW6m+kr5OP v2:x'coxvxZEul#|zVi yHڧA[[ F O8musgg$r5ź*IX=k]wMUy =OOZ 6ayl[Id+/~,[x77=-,5M=~&XSžM4]n% _; 66ĺ"隮2;/F,'9rf.)Jź%`Qѣ^Y(fRs. J3NQqlRaN},>aJZ3Ynoؿahölj8`$T> Z]+ 'Vۏ i!xm+Űr$A9@am_w+kw3Sԭ4oiKot{ obvzږiאjYp[ƺg "k[e1x찅; bhݼxewTR1_;ISɔRM[z8c0P2g-Je BQrMZ4Mi>uKcf^7aŶ.Vƫm/LKtftmk9Af[?R[&Iԧox[Pkƹk_$[  hgi۬W~iOZ5hlcߌe(M񭡆 Um dQEu3xwW66IqB!2ퟧAg9uvPLdlq`뤣x 7'u)D3 T%ʓtQi]G|\N -8ҍHʃyt(Y-hښ~ (ž? Z=sBvxzCoE|S$څݣKkW6qϩ+ց;2y[ㅼ([d>N๦S#sĨ>37M`i'V%Q1w38F+1]"$2Is06XxV,]^݇-+RK?$+~Ɩ.*ғ9V:+OUm8~&33NjV穙r+M%>" SJQF>j"^ҕXVUKٹ>u8;V.څI/:<`,fem *{[_E?nZ! "y~dxs"e"ύ]"HDvƨ?)n#R5J;/{M>^?ڝj[}wouoor*/uq֙akoaI !T ̰!Zk_w6MӃNW$zn-NOL9j+JIqnUsB-5(8Ynvoq l|)’mua9evkr8_}Z;{y5wQKZ =;>r\eյygt;灴=d:r[~s2 nge،l)2Dծh4ءDt).OP΢<ˋb%0iLlx2ʭU^i>Zs墔tY9F:I|~2LUWRQTbp꓊h%&t֑ںQ?SxS/)Ԭ c}(Bj@m#^ lm׾+d8Py; 6&K[>ˎrp3GLS;`qS]>to'sZ)mf4-lO]{u'>F{gpCO#'}`v<d`{rsRg'BQ'23/w]oM.kwv٥viZm?A~9'Á:c' MGr1B Ǡ:y4ӻz%մrG_尣O^t4Ԑsm2N@9 `~ӪKtz^/_N:`A#8ۓ _qϠsyvg͌ANs^~SӑۮO$u;EfޛonUtn*nZzۢ]scz7<qF8q<!HyHx mo#'"$3 4HkZB6M4V[s6lIkiZ'9[9\E[kR;hQK=kE_;`rbk &XdcX$r%IgcÞ,ԵmHau}Z(ǑIyiiO-fm$u* I4VY4_1ބxVWP?s8]ꑼ6>X]D%KmKє3Kw^x|$ bVb8k1D #ⶠ"xt"ӖI$ l8/)`X23u(%[ऊy־= X<ĒImȌdX/:RpV~Xt嫼a+'NM_Uˍ8§qU劬i9=4|vLƂSnm<9bg{4H jИbYdm?:ç{2ZVitTe{lk&O~$xo ^ZM]LC[Y&1.м;f/3SS6iAxȦw+`׻IF:Id좓i՛wMJ%#_// c06~!hbʲ<< Z! rw.Hkm"&(H USi."$*qhu*rIݤk%ٵ4ݹP9T~UZ}bm-5HuMos)$_{y%V81*ȮcBe]RBa+”vg qw|X O'ۏ[sƚa`9Z Q@^hXD2זZjP"mN7yhU`\6\g4״WVd:r{{ֺ4Kx4]p9l y7(ʶC0Z`ā6c+2mT܀Bdf6,lr*H#g;HX0#&R='Ƙ #  K 0[&W3ڷ5fOU]t]IZFl잧1qHmM8y3BbdXDfSwפ|xt_ h_i46mTg4w#±=!|m*Qhb۹d~ӥһRFD|$sm!eF͞Oi4yv(4:g3:M1*u/%4ַSqfI?m^׽ѺwKMfmYEtZk B4*L΅cbIǰAicxuxcẙ-Ԥo-AxOmgI} ai"?ِ#bkϨZawRj؂͠ӬPE$6gnBd;PrlD/|4z-v5[[[-[ܭUը\zY'iׅC—antS,+0SyC. 2a dT21*0 ^ aJY=VF.S2bC1(@¡*Q]24|'ˀѺY(FXn ,?pn\]^yM=]KmsΞ t޻]-f?3cnhʪ W\eQj.'h\cTr]7E,ke|©|ۙTME/ bv:I#3E Xemiʢri/i{+蝯F[G _ٸmv=Ԥh} x3BKs=4_.v dg&$o<[2mf3,c8]0X~[Ev\T ]IojPZIڂ8SΙ`1ۗc1K 8bn&VV{/K+vk][vm+;;YtIii~d+g䗳vH\!8 ؁x%IQxT -0v1&dTGd+? `reb,.iYj:{YsGѫjR6c'wn׳i~(/,䳳ҒYf}JY隬~$w:{}4s&ws%O/|E"jVGCq3j o&jsjۤf.4KZӭLkJh巵}Y5|SV}(ZO6Ky[i֒[.;ZWP3-|['*rtGQժkR=]Tmѕՙ~40Np[hV^ܗ+ۜ3?$O-FKtmCRZMF[Q&yZ_+SkStYni`LoZ$^E†W"::RPn$sk NΛwo*GwD.Ucdjks1ַ<@ǂLl ($|GediuE7(ԡ(tRMqFuO4˸Rtթp2IP;Ҍg+7╠ |[6I;kn[XZ;/&8R\D gea5϶ւki''V;fG՞,.\MsgHRy> ~_Q}"INufkojO"j / ɐ~:|;kk4=1G|Ii{$57V ՛-x/eT)rp Re-CHŧV~*浝Mݎ q\ NKFLdnۛJIŷ_7bjKsܶ?cKSEwzL{$,FD"2k8+UK涻3e𼗶w6H3K,^&֍s .Fo-Ci=(w&/XMgJWEI,OM m#<w[ؽi_څkhҝl-ng|_id-% x&67 e1ȰBPB{1A&kt:;]eI ,էO'tҒf14kN[&LjFrJa*t{LTm.KENJRo[1mz/>!ص Ÿkw <}NSGZ֡{n-6Tմ⾲{XOf)?my­S~4۟ j<8 .; `iW: cq-A4Zmw|VwifU=gIOíx3^.ZMsF*܈xL&_Kwx8d_iMCuؼ9N }j4n"d>|+?ȳKC.xW"UcCVJ1F9JrsnUTgcbYa:OAɮhέX0峧)O8K~M_MH<7'm< ~ []kzlK{kPDvb?ٟ ] xž6>|տ+[3_/Qҵ MK}O%/y[Ifd߆rArDxfkZ gʪ'3 'Yk5E]F8| P{MNh,M6K)n|T]m }=`B7|=!i4.b?5` Iw*rRN3/Ԅ'&wq_MjeCQR EMEIW֫:rym^_L+{lkHGD~ֳGoi_\/eb.n"M3\sE (B~76?P+ +O x%N)NH%H絃N"M)~zAkzwaFPKj_g{iv{zkiZͱy4W<0^yrBg/mu?yS+6'?mSrHL[4 lcԦT lR?c8ʔd<ײ6o$CNN)7̞n6p".ຐӧb$*gnpqw[k<+pAl|[[a[Ax\7NeQ1;oj }ĢOԿ-G/w 㧆5X|M>$| &…&bO BKY)Eєz%xKӢRK;Ⱥմ֯^$m%~v -N$H+8fJkPS[fX߿U]O9Ti"9nbú喣sމPӵi 5awr.lbskrOb64zOܬYVu~ 4r3Ml3]|byQ֑-˷*pE+5iJgdۍےW2W4jXܢ M|A;9{Y,]vn=>IXxnI LM?ʷg%H7;[X|GulT &x[_W4е ^9R[ĹM+j;gl E6wsi Fӵagn)?f2oh{t18|R< F9xsF?xzydY¦#3JJ*(byT9Uj<(ٛ*? 2?~|?Γ]SE>$:Σ+*BM "OÐ[WFr^DgIF_4Z%ǃj;+"o.("Mpҍޕs?hw- nxIq+q6 ܱngI٭/?G)kZC 7ɇR/kvx c?˕*+ya/QáE{.f#ӨMpfsI|mt`&Ku[~IT^?IHHȋs.|iLJ`Cć{Rm_/0|\kMZrmo c,gUsqqn)efOdei3rFȫ:2D/5Puح faEp~_؎]sHobԴB'PI~'hzD$Q4meI#x1lFy?O݁~5`Loن4Wf!Y |9$\[7/,l&~6y'ſ f7fi7BVrۀmhg hSy+FpqIN3Ϩ7$|SJ񕬒Ѯ⏲փOԣzEJ8nn˙Z6k'^7֩}kYG~ϖŭCsm(}{XaƝ~·6-pe o^¬|>|Do|j<?k I];b/e؝ofdDr.% ^(>dNQK%i:G(6T$e>lOdO: kjm1w6on. e+[a9,#).+C.s'havݕI4{.*i{^Ο4Ru9OU̓T-ғJ/ݿ&ŝG}/! 5>gTR K2,v]^Cp-'?ŦZK'+ IIho]e3^~FϷl5;}b+]f$Z혖yI 7np̀jwkjY<'u}GXٚO`<-d|d߄t$ht#R[xwWH#]vlײi ^K=F y;4L%ISObeF1\V&R^tj%Ȕj)BsJIF^)FSYJ{Ӝ5YF Yتכ.(K\U*>xG9|;BMgg6귐g\Û v:/{4+b_M|6n4wBмS6>}힯w GpekLVpCK'kXwwo>#~__Mu 񞣤j41IkKխ ëxsR48s!L;O>&~ȿ=|!.oG;_h .=Rɾ7TѮm&l5*̪nf*S?*FKi*y36g,{8Sx:qJ 51U d[4qVo7PI``7Wܑ l6#RTߴ%י:~$nk/QC @e9 |1eF'l7?k:~>[Hg*k&]';R(uwYt8ud:u|I$VZoiv$H=z:@VWw2]r\^aҩ(ƴ3IMմ'Md&+4[ KN5)X,]j3sVKRBn$^zif3)؇ij,HBh^I[e#$ k(\"K/72yIdq㿈MĬ<g[QFh!Xg /rKŰ(UNg`hh<, 56ݣ-3[Xʶ"0C 7e&efg+髲 3<7r'g!LSI -j=Õ)lck54/GtOiP|?n!8a7*lճF]i 7w ȽԑgRkx8r {?xڦh62ʖ]k׉/o)L c0_/$RU7NSOߕZ%QJiMZ][mJ3kN7sKr(k#_~]6]r+ !V}D/[s5v!" 6@cŨ_i:f/5Y߃-g}z(10{gYomJ=nuHUL.e4R,Hnᓆo Ԁ@x'`~pf_NnօjUQNZy:KW5*|״|TM,4*\jS::8HYu}UR7~Lx%cc HO#As psesn9'.[ݞ LHzzq.Mլwne4kjWUY+ܘ3T䃃vĂ 9GW r1erǂ2@D!ۓ u6cs`rrn ZKkٮOvvi-MK浾DF }0q>9sR}Ҥm8B9;R`sѺN_r;xp:2>cG\˃+YkZ}<׭^߽n_Ӣ$# o n#=xzRלn$p C0y$8 /O=sf׺W/kYv}}^t[l(=sByc$x9ssuG 2qԯ, p:d; 9$=8:GMS[i[kd6],JϪQMp9$ @8G$IKWq'H8 psӮOL`w9=Fx#OQؒy$#<-5]7ivfᣆcIJ [$a 1+67 B4F9SoEnd\km)U*B ҔUέjWKGiiX>+R m^E10p$hUB7bWaet .4j#rmq!O`Nƥp&X͡ՙu(3* 2VeL? Lp0; Jx8~rM9Sܥ)rMɶܛ|ݶZٯR*Ir1W+]:'OR p!Q±°''8Mj;HmU^Yb(eBޗx.Ő[l>Kܻ @VGQbg<ݷ,`*,Ѧ֏W.-d\M6Nڤť; R>FI$&pv1*\22I,oϖS0ۍl_JLr_j IdAÁ77S"0<`e|nT2X8d`v}z%O{uײ:TV]dJ]]ZJZڴIDn2 2I\aH G*ILΊ7;܂o#.0M}Jpȯmj,˩r:Nt#IHb*%X99 I^.OOMkY]_wIܻ|]dӊR讵M'udiE]uެMUm-c$H(^kdvaHd%d_#sm,y,~b!@6Jd d @bY1),RK$#/ȏϖ]YBGvЌ\-{%t֯-RիJVdR$۴)$(ɦ6Wvv1eBpB_x}/+񍔰y3"ڮY@8J(;+ggXQWWv1۴XrZ ԫ[]V&;))cB'=m0S~!$E l`Payw+6ڏT)KC+wX˕ܢ;WI7&%  {ԣW,SQ*IYsJ$QYp𹃗,eKrvIݧrqJͷ')6/Qߊ1|c00U[Odm>Nj16[Ib:/BfkhϟVKh@};g~Esp$Y-+B$mh&Tx8Z\;#z֔O y?8\y'qo݂~OG/jW*N\[OVO]RVN1;$TS_Duv1{"ȑmcE&+iY,"S0S#X0lx9m<'&;8h+{D{6ķ*JY( ?s n/b0u#$dӡ6֘#נ8HSZF<|i$"[{h^}S6V񖐾mҷgɁZ9+&2uehҹI>d=Snɻ-tU&D2;{?jh\iCIʑ$sJm_ؾrgv1j:=ĐLD1`N#d7U^c PkwL[6''{I&Դx})$%/]ݾr񿇥O -Qt[m庻m /퉆Gl+^)N0YSuM{+Xљ"IrӯU6iY%uu hlNEFY&@c{< eF#d{6ahѼu]BM6FIh縹"Ț样wbiidm  sq,b5U+!o0$#0N4w(`)E2w8/L(DDdƱ0I7"2Y5]!N)lJY\ ~쌌e=KmշM^]1hV}.-UV%xxgN||M9,JŴm[ mVɺ)YZ:i/(x%"(Hu˯R5IG0[Cbk_9Z4􅷗U~{ "+^WW->t{3y4YyF(RQ* 덇 #]NI '4πl5h,Iٚ[vxd"Z(+FIhW;e9eF'rѵwz\~ Kow #G a 7*'ۃtT ?x7 u:!hcEhK1oJ7qiC&'̕qPc*ʠbA~TejK4"4Z-O䩈"JQcRە,nƀ>%'VRi$ݯvk|R ׋qk_-N Qѵ)G3 ')IǗܒ*M-m G2ӷh D{rvJ$(t &LD![1eɆ9*&+IUmY.]hkKZRO%J:je>o[Bk`pRv ẁ#]TihrclU*gP//Ni6P$<6>drT"KnǢXj:/'Ehf=3-ǒFsgmR뽟VK>p[qa=?8\_c;!]O (a2"3B>X[Wf }%Ke#=Չ}䒵ڣDΩMw$q,tlEyj];X4u-R|S,:lVOhik[3-pC3e}(v0g댨*ÌL1HZ-^DRI"êGu?hmRRrV¨RIS =-đH7Tp ͲY'o@M&압fZ;rē๒ݶҳr蚷5|%a魦f[\IJ+*ƒƱ$Ħ(3$"@ y7g`Gdp9# r+|fC\"Ui!+x[gkfJ؈j0[Ҽmiu+ wKݕ䜉</Ĉl.{ٳڨmč,Q $EuDhXJQ`O((ɔNXh&JD RJv d(UrZ"ie,޼ny, !FdA%dn)m-/󿖖{'nvS8…g&正ad˅77Lζ5EFKıĐ͸5& ;` e'O\ZM;Gm 4fLMKH9tvn\v[!:?ҁʁ >;Ќ)B6`ӃNJ[]km-g7%״k{&ݵm];?+6äŧxwpO!,!.##%Ҫ)iOD٭$;ܜ*0v C8 vEz8gJk}R vOk2Qs6OI8+Ӳ\  m =ōi95u$CI=(Hc,{Qơnm h=Ώ$*D*v{Q7ʑmĄ' ܏q%,w kG^e_)&Y#Ȏ)`TfխhR/%๹Lj 3D+!=5ѕL#IJwzJ/i4M]I&i! :'wiJW̝.{oM&䑃߹!ϵoa4LGё{ic70Cڥe]NX+BqHBbJ bfg8d4a}7+!x kطIrQ6~(3Z),|UlőswjcrT ÑIVKwV櫊Ooeo2%I<9T%h*I5{YY_M>FMcmoWMA)[ƭcr-/j4˸mrBuխ~mZJ gK(O7-aB-Je2HlWnɅXbU!|?[r!?fNu!=BUzènfE3iqntkn)uqrF6uK҇+roD}|^uŭSM*$xsIZc(«˂#k Eu%'kiFIVU2W+fTtW ڥƙ? Xm߅>Y['%c=ࣚ =y,j(ޞ!mG#|lvn[KS|f2gS'(~͸RoK4ՙ M{kI":[{a-ŷڮmkh$p7:$?<k?P^ܧhn"("?.7l,CJ mX˧eXgzd_,+;4 |k˧8w*͍%yeY𝍜P7?i`Y]2GE{)jшmHEQ'T%,?< NM;{QOUu|&E'NYS/8,Ise,V4qVħ+ |+?\<Gy=>][[,{?d;m3Z6$vwHeܴsIuao* |/b-bԟqk2\݇ yvt~5򅳻+i?ezE\L_ٺCY ,縱%4Vb5#md"y B.џ 6k_~GҬҔ5_ 2"[MQ*ٮ!NkrkZG[V?^Ncy%/o_CR1K+piKMT*NQ+F- E+@~j-C@Ob6pD[ |(:Cd Y?e[ɻ11Z \^okyDoʌ_UY[x"XwM$|+q+*' Eh)L%U79:4Q{? pz{;];kE(=#A^ZvJяd+m7\~pX%t)K$H;UOD5Pn z~N̠[hOǞ ׼##MSk/!]&G5[-.;T.҂+ %#Q -PO,\;y]/(Ė`LuA7|o񮅯][JSQAԖ]+XΖf[**5X^Iddԧh ʙCO P*Xէ:;O3?Tt+*($ ^«1[]gpZm;U5ḙ9Vrm'eMjwv_Ưkqcj -|=rth-4G`šQu>sjOH/$" om"k~Eoo%wLqh9_؅|o(IGǿxR?_Kcu=,׳ZAy7-%e9\H|҆߷=j #--k5Yͩ]]#\XIoRH\+}.QNpcSYA'ui[|JԥxKU;3 yTF\l?x(OF1MW&rմX>Rc|<5O:9tVOIxk]֬t IyaJ{=XmZ+ xa+__,m(Rֹuk:τ+.'X,c/fk"? 㝿ǟ 7+g4>Q~Z_xkX{qoA"Q ,>s)4^4{X '8k䳑x#=Y K4x#P`q e~77URQap$m{+?sJ*hqRՄ*J"|IJII(蹜ySw_*jkCm/}ŧd7kxeZ oلcI:* ="c_׷O=֡xWC -~79/n3Xog!EȖ;/1[\CkuDg*ѵr\)$VOxx{ We̟GĝBMK ^1][jzΫ2 {ݴgpF3JQڗe:i5t2F㨸S-]6itK]J-.?ҏ,Yw:3fY/~yKI ] O_Go Jdž?eZ. -GN}Oǟ 4?YfRFӯ,[_N-kx೺?4ڇndKJ'K_"hinQSD67,ſ0fIԡ E ԞsrҌS|˓޺r%d[]ږBSl8a1Qvw(ɫ^qmQ(gb(|B6Xgu jd $2nvcU+{7 iinAkxK=>,:wy"9X~OҔ쿲mm.>.58|gY#$­)ykq?aݖS5l#tctcY[N94MVï ɈUxէn=TI#ikubiJSiIrygF}m*S滒Ky=ywJ72Mo-߈e],5қ)OV"Qwy8|z>dY>>xQo<%f/A/NydhfkykZ^dmKisHd$!Q $ 10K$!X9CO_k>\m+;)>.AnvE.$y<>z/ 0NI\icRVƳuz_I/jYX4J|A>%C/s|>ԭ"8ě>csceN\$Z\]Bj.NmG)%6Wgq[ 9~A l.zqTԒV)GY%&~.U;/O?e#VN?dRC mKYZJrCxP3xJ|Gm_mZ6leKğX[G}ޟ7"*opjkVZKF4Kƥ^Hbx%oj]HYV=&?Ou7VZV%%I]#HEiO!?1H bRB:`.c1,·WeVF8 ]P[\Լ?jt־Ѝ㺆vήi-֘&vWP#-YM;3&zt{;ZAlgEY@kVax`g% rC27~'$sarv,\-ݮ5dt 'rXx?*$Ծ:7r}v1fRיj.F"RF*j-zȾg¸[ӛ\U*|٨xxS܂SմyD៎R/{|?6`4{Zxٝ$O/cg EQqHEhD'+yo5C&M'2+l3TE0ZF[|\E\yҰ]2r>F 1~-K&FZ KBdφ:iTWikvKEkmG]ݏ ,R1ӨJpvbsnR856K յm&% nE}VO53F$@UGkM!| J8BZi) H#=~5̭xO7xo+$˳O2#`pє3F[m-\[\JbE+f_Y 0 UcptQB ڥRp3Iojdq摣wMER5fLEIM7nRvm;V>IgMBFK;k}"e2ܤ%Cl,bhTŽQ\ ʹ%x%Yo3#m H'k[뽘#'83$l1ٹKma3 Զ1h#$~c GLRA2F= ' x;rrH Ӗ=x ԜӶg֌Oӻ[ݥv~^j? [h?We sGd^zqޔrsy82:0J`98 #En0J<iZwwC}m}m6hZ!c91<999i,#n9-ieWN1i!W[q2T̓ yI'|J.=.Ku . Hiڅ%%as KdžKpS'wᇊQr98ŧa7vmsr|Dm"{׭ٞۤX5Vk;NQڭ싅?w[wHb\4:c,iԂV%[>b˟R:lp,{.n1/culE;gkuX·/ٷFvqŎ66eE/ܞ+ki-o{Y&IUݓOn^TU+i@ym:$\P,@?t.\*$>QRI@F=c%a N$JT k --:Z]%,^1 $M!ɍ,K4lP^(| -@ܿyWc! s,q\2JJmS%f!ȥ̒oV՛jwVuh%iJIv_ln!NXŽ3\f4i H!Rv,(\q[TRB6\l`Hp0)#է Ila]jp]wrPhEW]f[[Gf}k[(l[us䷙fmʴqUIu>jD>fQ(A).Ą ܠw$ρ]UȬ ?un 6p²ڮ$A"3nF Iwmir>_m('%mtmYڲMy{ۭ2Z&{پ[Yn >WVxѼR\;o`Dd%vP2&gVp'tl"6`#wڦ\4NІBxwI!T1b6vpy-IT}d̥Ό$`|I,* dZZ-^-VfmOd颳=?vo_xË# s9}CǙ!\*nFs{uי7Cox"Io#|U n žIUxNL5˔_Yƿk`G AbIEBxO,ˋ?ΏzGdgV o[`4B+8~)\^IW1Kgo$ /aSn _SKMٟ.ټCn8&/m{"%ĨcYcLK|РU%$rQnUԬa}e;_MF\ ?Lc8 -yC3-Im?W~Z$s^Iq+y+pDdE00k;?  K |Msy hbMźY߭ͼ&X[,/!Bo xE'}Z&Z圥J1gO-J7gwvu558 MhO K5fHU#Fx"d-as+=Z܈"ًᢕ8 I$DfF'6i(u?Lc(bd4EPgc \c)GcZEunEM SY-H_:%E!ƲoHA;%k^XuNӂڒvNr.3'{]g_#]OxĻ()G:S39 nJ *8|A\V[E^2f)E؂Ia TTQL>Y\Zx0AeR9n|;+D XIFJ#__.$Yu]2WF;b8p_|y'hmnekkY7d'KdckJsjVg-oѳs~[[)Ex " #!Vs21++nOؿ w'⩋,emӄn=*\z68+ҳ,6)7YU MYf,2>Iv²YJG+$*Ws1.w Siy[Fz4ݴ+ݘNV$ңCXE%m鵣vwn+bv# Ge'pJ'%86/җI~  cUt%LƻK7w9_*ubI&'KդC不~]ȫsGŞUi/'Q)\QыZhVumI$"n޺7n-јVϾ?2?˴H4X"VUm&0 F xk7e7bV"JDi+ff2rŔǛ]?k ⩘0|023ڲ2$Xn7F5"c!> 1pʏK6;R )Zm5xwJ蜯klީNKK̚I+ߪVS{|j^KؖX+q% q ?4vU@mLa@"@B C6X ǏZ:C'H%lGG+ (SWr:;L0۩+YBIP9He8oR@,OyK A6C}cZqg4H1N1 XO!~Hn˘ɊGFED#\ms$C۰GZ4ɽ.Ѧev{9Ufs4e2 bځ  !A34>~57lѤIZ Č2v+Jc_lGPe6ۚ ̬#@8FR0q^gvmi{hՇe{]뤒|B3W*ElK˵-ʄ Q9K WeO ؠ$N+pytbU#=jG3g+gn6 #nH9~]w*ȶnGTk #C1k,K.uw{D|[M+ѝ۸v[M|Ox3QXjjC!14kWs*lT] wx"NbA.&A!]m9'gcʑ'uѢ4R,n"7j"G٘ FY)^S!u: A_x!9,A-oi&g.%痢f.iڕ(>fE$EX%[1#8q9!mnA6$W.HۦVlPޯ4Q,Hr3𬏻%,䑝݁U(At675)T__ $!^D7#TW%09#GBznl៳MlұA^iڍxPN䌃*pmb<'^~xhy- LdFO:Ƙ̻K!$+I z4H̯k O0IKI-ClR70G@-m[E;ki˥l]f+-Wu-ݬ^k~JH*Iݷ5 BmJ@U.BefO*wAFMzpJr𾙃B\&LPY^S*PŏN#0(>b: r8nN{-oߞaVnzI.ihյ+U}1b-H@\oVQHm ς8lgghpEo#RA2Mr0tl񥝂IK*#B,A5Z cX"f*RJ`<n8ŵ 3ZXy+3 W̺!ؑ±D` nԿկ}/~ZhO_Wre I;Tt"{=[,IcbdRꛮLmR7@J݁R9gVV\ 0;$pe2Ao ż,zIJKxcC$,ʹ#;T޷\|X oRI sHP9IY~뮏g~6iwRf6Ѧn=ҢYxzI$V$1#C,(BR>mS<> [ḭD1F !0e@$\*kܖ\[BVo}עql?4pRn6i;kM;ݟE3.6'/-Lj6-̤I I,wQbaĖb4( uVKmMҬ4f-edë6.ݯ9$$VF֡5OK|EEg/H$,H ėYU9."y/i)-iʭmW3+V҆ɷ(]&wkY+I.]9RMFoKvۻrGdPΜF%K{;Eh?H)ar'Mmrn#0Q"2H&0 THq>CӵJhTEn>=ִlG,FU仠+]m 8 w WP\@R!p@jTjNJE[Miλmr]ڽCx(+M5oqiou+8qiq<6%ܱ>,>H0VL?P f Be7l\L1Kat kKׇG{!1MÛ<|%g $߳WVxȎI .)⿵ثSge-F[y>|ӥh|_ 4uM6Y1jI3>KC'(7ÒKz`9^j4?|&puŴ\*a1NUb`\֜1ff?.@K[l)5۾Et\Œ$qjo/$%k cyu$~jP4֚~u=Hy WŻȧ>~{(~#vvU)aq*,շ(xmTbEM׿6¿mODm$ R IOHm)XefUWJ<5͵ifs8[Y4I "D6$f_{}J?mO(m^[xൾpӴW}r@fٯș{p@.5;}zxS [$FkK}Rѯnn[,i{Ҥf{ILgg {ZH9$|Yݥܗ<ϩS8vcIrxu M“j.K*b#(Fq5iJe0R0;RP*iJ,/aOvt kw{x߷f䵤r7eGMbi1Q6_5ᲊuM'8^v}w*.~)hjVp@Q fN)m!Os+HQ Mx'pV1\/ZS_F-[ff^w?8Fjb뚮qIN8I֗$V⦅9ԟXGKGu+PE񶲽_8/n-˸dEVՙG;0=|3𐷕s9?[9d6 {(lW:yoOwopeO'ˬuG0Hy[ Zl?yRZKm{'τ1\5_}kclL'SE )<ڑMF-6]rW'ȹRis;Ӽ/_g櫦_hz)-w3SO{iZHQ䷩8sYbdI5kI%ߋlk/w8>rbPM;RoY_ yHKw6|#b^!h'G<2Bb ?ml?U=H$i hϏ6qM4QUe'ڇ˵i rOckVOoqT@b~'#X~|; S:cfP!ƅ}#( KKW?i+Wz;ž_iYU'o[R>8/.<\Qrk];;n#: (xjFx⬢O 8CFc$217K۫5{X]@4yu#|5"Me2  I$E|#2\De?VsZمƔH<ɼg2ژҮ&{dIݢ"[&6@b?Krݳ-i_{2fNwI̞N RYkM(VkE%7,R|j˕i+nkK51$kmHEPx-%죳u{]t;_bK=?MRM H<b(?Qo#icyo/9 kILr'?@uL|/u$muk'O-䷟֐#G[ٛ/k,f[Yd|' X) %:nPc4HfQdvhT9ҏ5`|:j<ͯw Qd9X2ܷa|<ͻ-V5'?߳կm>2oh<{ ,^[ܥv~sm|s~'56^ NYuX-ᵴԭo=-gJo?u }xQ2J{9Ffޒ":C2|yYB)Ѿ)ொ7[xgO< |Iw{R#mM!%PvT|?=\-U)S6ũmn[ŻFMp=Z V!TQNbt7deT~~$ Bduʅ3k^$-gkzͅMl|;+[ҞkmZj1i$⼲8p95:eyN&4I8<,֥ q}&1j\3Φ*c*֔bshrե.[4b_$ΦnUc<тAԆYR9#/1Z|X+sh?4aEk_,K~ߴVe$SIe^+pѤm%HRّw>6>m-zv5MƧwy+ϧZ\LP:8Z%݉fy^ !cKW) g"u0|}ĸjmNqdI^^rivz8yj#+JЭG;rPQnڄTS2c qV?aiG?f^H}cDoC?फ़MiXt;{F ԣͮ%.DZbZ| aSY>5O7w_5?mk@Lᶫ5 h5),,=n]5ŸZy^;VhJ H[-޵Hjy 4}u `erQAN>9pjj՘QNRj!N4mY.[)1*.QTp)5)kӧΤU%*[bdE]Zhvu~ݴIi{Hcswnb(߲7;ⴑs*? SjekgUeV wZ?J-uo|p8ė?F]m WkEWqkeY`WGch_EMoĭ6mOWS/OSx#yn&5XwlE>',GI+Cu=y\T[v~QWO%SɚnR573JI'7ߴfG?3[0W YVI|T1$Pά -wgع@Djˢ,b%rqp1_&XϧZ}c}e(YG紺-"]i曪k%r׮~6oG[fG'N Ghʛ;2g'OjYwQ®7/iNTn/_gR8ʕdN-%nwZ}Y~+DЯe!HQ+# ++ohT~!폨iPzdy.K֙X+-K<儴]gDV?ش 8XJcTR]Hf`pz-A?70][Y۪E@B6RQ<)raeN-]/i.MZ58e%krT)KE$&XrmSvtܫ%1դ󘮹udRۇ=߻ltloi9 ^Y!Cuo8i$WԪT6+go^KXu{6VnD;Eݴ$`ȿ_+?~$E[ji[.qy.{vd&dkG#Fs-` ZGˈe s/[OizX?Ɠ}h- nGixY]V]K:Qt4H&;β|lR6īh!͉u ip*kԯn(mۑ(ңFIdMu\|=*x؈^.Z4vڋQI/ykus|KoBMJl$/ pVA^y¾JKX1B@gO'˺DfR|aF#ȴd8 /n@^.c_!丶`[߇~ҵoPxm䖈Ih=*[9vHWi.8+ ԏmc×[xx4ki|la,kIh%F*O_.R2n'x8R+MZKxMvOs.aao=ūɍV|?H%-PRKh&iזb"QB@+'Q]GiS^J\k:9 Jq0OҤMf>k'զ$*r?!&𔤢_zMދvҺ\YF;nʜF4-ZiI&i+&u[GRGk/R-BؘRXDy6ewk$?,ï k:?ui" };[uđZ"i+\۩8)_ZwBku=kIҎm繂}?He4 t$Αc4k7|FQ5~xA'|,KDh#B#aQ22=+xCf7)`C)Ny}\S|iXkmJ18qWv4miu&\`>R@ dpl  03N>@F  x0NH# `p!q|U>$@ >luB8+{=.I_{gW{>[EiTN@IyzeC$v^6+p@t~a>RYHS'5"B0GVqpGJ4욲ٶ{>nk={Wذ1]U9` >l$2@@ʄΒ2H䜤D$ *wI,p@;}M{6kut#n/'*]Fh:Un՗*Z?lՕۥdwVkt:'GF @QX`qN2=vˍXMXb.ךΟȢ9$1w# e%FF]h'=9:r A;3HRԩF2SDDo[[{MYvw^Y48HFv#989e>wO88'q^H8syP0=9cN9 0>P 9^VO=kk+m}Zh}*qǜ`%Arr1=; =1Lbyݴs')$8$ܱy8(kVӺODީ^INkm8=1ž'@ЀN YH9Ǯ3i9H$ zdXJ8''sIy?&t&vIu~|7vM4K3x'MEk+;h^ߣZ;x }qH00x8GSԬ4M:U.>can7S,rNx'ALĜ*;)zt~)![(WO[]Vu(YCAn^Y`]gO;1Ͱm Te/ҕ/:u*FN[+9loztVVRQ|I-9=,;gsu_h-n;{yZfIx.'[ˋСgʈ#2~wk>"|E k_dj:ŽnF5պQX8(xYOž&Hf5ii!g.ne3J uewm Y'*ҙLMn4iSHYP?1lfh3RN3Q3NqRzwgF(Պ?+nI-J׻Ikwv6M˛iA*uOĐQn3cq`pY@ PH)ofִBɁ ݥt'ghcKEGXVlu(K bHREߐ6ۅ $nV3/^$ݞI4,QƨOʊhLj㢽VuU-Gl$MVDw{觹vFbš00J^ʈљ N_1_0b !|u$)pX20%I|KZ,u AA a`G^OmW=3 $U~!gfFro21..[*KE%¬cB0ۚ@Bm'212*F\lDBm,ͻe%vn=.Z_Y|VZke'vw4~$vU0#gR. d}M3Ȃ1dd 9#WP 2:';2HnG̫[-y^D˻W+lV$̋\+]^^VՕI괻꛻Wh/VK㘠ٟu.vC~SBS<:Mɥ+F۴(?Dx< m?ڬg5ύC GP l.a?]?ĿeGRvK:e$b8ćK'2vKi Tp`&UmV=JT FgFtI2Tk-(VvrY6~zamxL$C:N0|n}V[Q]]4%=/֒jD%MyBG[VH˿~3^Kv7"o,nuS",(ԗ<ӵKXϋ&c$MuOKiCJEfeJ9cbe[/9QmvJWgc]GnYjH6F$RHYv4e38i]duHu A3?eѭ*;41D# Z7aw$ U_Gj N]0hoχlIolPD y_ Y ݔhdy!}ـhY S.p3xcCFU "CeViU|mB6%wk%WM:{gzZ~m/[hm-KRC峮d!s< cѕV#mOnHÖ-1d9$C& e1dTWӴ"mWHP@M'C3!n$۹BH9;|[Nj@ q]pp*TcJu*Y6 wu_ocGZG dӲm]nmݭy?Հ)k3bwmXl"2,9X_479rrD]7 [_]iNfHWj኶Xf ,-:^,h ]ϜY6*NFGR{PoJ1w]׽hmT剆812].cV1HĒ8E(IkmZ3PK]URi$kk̛$ y쐤Q *-Ԝ9IPE07"um5|!!eyHՀ'F#\ Tm{yY+hg~ooLyh)=-4eY5|ҧ,'gq70MCrq=pR@{d%2K DŦxc6IdQv!eV̪6F 0okgo*!ò  i JӚhQASsh9f3Q@JvjKUt߶[+氾akiB6WIT\\~4?W#Hc&"X&̨0$Aα(wɫ:#j8#Ca=NGʰʓMdl`.G.ՍeauFC<4S'i^EZ~=|9*ƫj $?cӭB)g,"Gڰ31^+vN:lVϦ[e| ]7٫6v[Uc!?2B,?.J׽xMúQ#X-&I[氊WVh&%\&5EѾ*,̫-RbRĜD*Hl)ؒ9uBѻdYCuږFIwJ˭'+JJ떓{jg/Iom>%FS;4qyg̕c*ށH=A~6*w3`̣kp̟ q[69)+4P!V9(cGd%If/.5f*neE4<0v3.Dr6uE$bvE˚N^[;]mY9x_;hn+hmnQm DŽ3G 'WRߘп,e2w!Q ܱJH񏄼\_{*g3dcd '5QƷ,qӕ[ ˂g=ޚ{Z;hѯ3twjTKp76=ݠH[]3=QYcv(cv""Z\oYcb|OJ%n j:k09~\;}`0E{KnI9$f[yrk#lܲn͵m]ZY-V\jj-/}Dxm-BOs`$kH<߳D83/#Ȫ[H9lMLp"f!~%NNO JygF10^EPYg1 -#4JȠ§L~KHqier͌r)-}]unYoSWVײ掉XpDxd.p|A$dU@`H8{.D\ݴ[{*U5 y .ypO!˪_'.#XdhϚ. ;Go>s6K9&ZkUm{es+iB7;?uE;oN-ө,vTxevREޱƪYA#쇘HG K)`qp7g{,x/pF]L^ap630C *.1Ҷ< H~aUvVVw{|Κz+hԵk]m=)FY"y,%Di'f,rfԀrT>孮E%sCcH/w)EzOҔxݓqߓw8qͪ(ᇡD|[oWZ4{[@#Ki|UFo!~fxaE"%f9džkB%}n4l@3 sb)(]*I-^[}RG\:熵H]cM+\Xo.C|"[y.I33/x.'s>}y X6l]Cݻ[NtWM*TRץ3m/{+hWΏ!G"75\Q+7اDyC(-.%n +q( 1>[Oi=$Io4 [^DEtD{ a¬7khbshbBw(IJ\UmڧkuJWmg09Ռ)RUX]ɷ$J6VWn}[Yiڇǽm,oޮ"_+pNbIErP濵.Bej7uΝ 5,v[HԵG{Sl隺 ({žӭ_"~КrI~@97XYfrV"gdw"濲Oz4~̺[^~Ϳ -m.m+gg- k'h[x⺹ͥ+Y/ Ѳiʯ倧tUeweM=>UleU5fVSR|RSIj5$t# w/ٿzϥk>OWj?^F ΐ aKk9o"ʖ1_~[YQtexhKmþ2{O,fݭVvýE4| mRDN$;i;yu_ ]^[^/ey-Ɵịm>YYV7V1𯈮_H|GeQsMTjb.P#@>W+|RTBUFJPqZ1)ӄ8Ө9.f{>RojVJ.5rxS*JQ壀PU"Rhʓ4N;G - fR"&k_#^n-纳 v N c܍qvj_ e.Iž—iA{*8G5+.Sa〷Xjú5ϊŭ4,U!_]>k b0[f\j>!"Wڔ:\/u$vj3MZɯik5c S# 8*f_)nK RqN+΋hݝՍCK}BNfI<5.Ml]cFb3F ŧ|N_/wk]O)9^ƫ$2ncٲqCE |ZwѭS;eM:ͪ"F׭SKGPGlm_ƪ׿S_@ۂkן% 4eA$xT$ •_?l]In Odx&t6kh3<-bo0$P_+PYϓa.BЊDIb8e jіKs|- uev_)gNt3qmIfWkIc+jnKY>Z r~|e?)bO_+"Ydi>dN11q/i/ïR]5 /v~-i&G[_ 7s j!<9!M2yo|/o [P,b9HYe~]+x{U͊>@=ַxg[Aa]/ː}7Ė&)ZT<<_V?cg:H{&z;R-q?rֲZu{;y$?ڎK[X>7֗0Y|H-q:0DK(kniKXOo>9x>N:ׄ|X> XeB^GKkV,Cᯆo>i !@\ 0_eįC.ڼ1[-ռٷx?l- <|{⏋t;>)/xBK?X1K\Gs4ēUKgRfkUonl|i=HU1~~eJ4N(Iqj*RZTfFH˃0g*xY}LUIќe8ISNQb:*I'Fd7_N\Iob#qH[].D§Q#‰DQ[iߵ/N}u?Z,LpH>8xWTi5^),ۡ{Wxk_[}0)[s?>8|H>j%l)*o\ko{SZKu$W67'm4Kyo6[ZOx˥K\ˍFi[^XHJ?^&Je)fY*RsT9-+F9+6)'R(dk呫e2 2W -F+mm!:ɏ˘̰IʲYK^%`  f3,2*vnߟ2¿f-QtclAlvo? u~ٿL<;P=Bght'}ZPMC8#mWG|EE ŧߍRDv! m h1rM EkH5ma'9{-ju1Zv\ xT RqL:FThϕS`[6'-9wm$|?͗ڵ|i~$+uo+ZHвKkZ"̊?y>$vuGw<}e[Q\yMH4*->'6ݞnVN7t-~N)TYgҏ*QxGTc{.]R]|LoTB(4O_|K[툙Qѯ 3KxlVKI7jWves/Gǘ<-W5kOíM`E-c[1܆]A!xආtbI廒?7cQ(ca!vՕ=Fٙpym~!%KZ$a׵MFԒM1Ԯmͽ[cXpjˁ0c^pdZYWN2XZ>c$ٌkR}YEez4g*I'7(%+I$~Inf&Ǎo]@,L{]".caY-k1]|kv?b {{Z{d]Vm:]VVYx5$q\Cy 7xM* d]ڭ9Ӛ]}R(%˦Gm~֍~n*h͞&<~=Q i#Ե&"y|Ay, Lv$DF3>*{ Gw>#b#Xǖ {wy'eʬ՛\$c5Ry~a^ ~ԡg ۖKCԿ`..h_&k[O8?"XZ;[+ɤ(wK [m#ω-+-J U4[ٶUuxn^^ ZݥO>$VK{'/xC|Zo_t{ktX_؏$yw2w ռщPbZu:u¢xᎃZMh>Q+IΩgeI}RS0kY[<3Oj/h3x )uHc}'_B<t̗Kl Ϋ-^seKVG~>^ YiV+q9$_.vo;wڒ@_ 㨞f$-bI-~ xTcvA%V[^C!a ZB$_Fp?|k(rbH{ /Dgč2Cq~? Jmo|M?<ӡ{<{fJ҇ψ,fK7,SkBv^(C0 aLGL*UWV1 cctVƿ~j~6$o Z3gXY۶4/SѼ?u[6~z?:] >ݥ~Z׈żϭ V ܹ"oz .!G߄>݈euu=Bo ں^'P:wZźTgʹSjo8UJJ.[7d_{rh~:va_- ^\PGO}I2wV=ǒa`-&C#i?7K$7ey mFI9><Ƣ?%< =2NNWG,[Ii=ci3I!iOQFZS 򂓌4 (&(E*>ϛ2烶.U{{UqnMY*>`)ۃ) q brC;|8ʭ|ïXX'Z&az#Mqj,j׺^b5\%Heb l`/' <0?m %uV! .K^oWgj_\.SkH^6mFX۟5DF%ush>1߳ ]4k3KnMMn d%pX$sqiө_^PVuVOӪ5ASyvLXjcV+m%8IsNMssJ׵{g:g/ ivs^\˨fn,hY||\Λ--'ev!|i2GJ,ZrJ>IU#IN 5%$rMII)wh)+e~YVe{[Y&ziI=yrA˸r NeGUH3odգ>R@ݓ3WI.{qm$cpӞ8n+w]$lm.ruWKӻw޺U灌dt)cO<^Q[Ϯ:D7+gk-#K/ T rnf}g coq~lA?oÚໃI5) kk=[Jt m n\ 3e)uq85\ӣ<;yg ӨT%pXaӛm>^[}`{+=ϋAgx2[[ ZY,:[eKyp,In$gു>OE#q$ȤߓowM܎ig}A䵜}1,*9ȝ/+cT^u'9ʤ¤SSueV#Rw Y|.1iӌT"ÑJI(ӄif.gڵc)AwyHv{i 'Gk*F@1(w+ژcSj7RRjpy@XS#rWsC"=xXmTzD҅ɓ݈sd:2 ]udc. $gS+Hdi'h(J3O`y+X}*lJgfx<6d6iRX]rz֚@ÈpK7rXޮTBl(9gt-$k8%NUAYaC99rMVO]oV~K௴V*ڝǤxv5,8mFwp\WOguRAʬ{UY")B`$ DjvE$$f*A!b×nC7ɹA|reR\aIYRڲ\ɽݫ'ݜ k-ShﭵwBv9X Se`+f$/mI ܆(9۸?7XmR$YS\V6xؓmqK W<1;Z0 jC\,v7U4j9Y{k5^ ^6v~I(ڵFͷdfHe(G-(I +%'u;ؘ#r,6Rm;" yljHv*RF$Sr2 HW†o4. әvJ`"0j.FРnV8feu}w_e?]ҵյvi>#d 2"b D%@KܾY_1pQKI@؉!wL }UfgLCa P@X18;~0lXX('^)ZݵvrZLگwk5\WI!b] \ġ Zbbd`!c/bՇ4zH <!0$UbYA$&$l$7|p մvP7 X;T$ %XOII}n]~V+uwC+n,eFإOW6=6<[i=Ue}R>z1k Zٶ}RWVZAthEI|y9e1znZLbWbm0Х| 3*`3  ~pvGƷ n4Y ͩbLy Z=!dFp̟u~j AY,aYjzdl҃*ġ`".TiivM]f{n=gnef쵩AK֑+ ؐ_! 3CO"bXH#dawGm)$!GI*N;pTgeYf2e 3DE%H̋楤o錅<[z hRFPb)r̒~Z%{O\ʍ'eAhߗ{ݯt1/lgq[L=zZۖzו-CƆZ(fGeS%>vk eFkjG|FD!bf*wRt??W f7b ܁s"?(a$Wվ*O LxWላI|bnnXb-Y!9~+" $iG ܉˸,7c|\DHd*Hy?`H%VJ,љ$F{U W |V1{h}iYX&1GO)!A%Bйy&lU>[G,in;KޓS nb;)<ܥA\!W +2KM h -PL"u(g1ܻ`ܧâm#< $i?xѣ%HQmzvm̑1NR"캃U aVJ@P[wmBVII՝OoˣVrvra+`0|M_kC'Ei$r-֙jH#O5.20dyl G-w~#`x:pZD(m h32mndB#0ktK2ňX  VO2Av\e\Ft~ ÷ӆˋ`F"DlVS |cK%3‹|8tʞ^Wׇǩ+_WmZRMhIrtM}t0`lYy]( TL %G>tV8dL[;F| h/gnGerO sn9`rp=A;]Fn d4PߝJwRw:;?;kDvyy[}s;_G(M[" jeޗ Z((827gwe;Aa$mKD )B*2#`3$iݕu 2%pul.cq|$6iB +>|xݪFʍiJ6]pL2rں&9RiӶYu$ҳN]Yt^-*L| I#9TyvꫂzrTj hB#ًd.6#]wxMXP"ٜnbn' eXDu.$eYf1n <,1 Ll8PԤsvW&mukAGU%~^v/С3"RkiP#V$ȠP½~q0\JpXf !vFe* +f #9RĨ hݔu@C>c 1Rȃl1 zě@P<BƤz\)o~VVMە~yE$|ѵݴj7`4@Ͳ,JmFRyZ`ۯbTැIm0l*p$(HF OxIvHMd{}#J3Cl(gi$ %&|y@仛 $N:IiWOɭiJҚ];4kgk_W@XPF+Ǔ*A)Rw3 *:^v"fɎ,k/k{@$Jp|BƯb$f drdlf `@@ɯTkT'[F6|I6|-Wib *\[k~kW}V}Tݯ4׹kE]JNI=]LnR;G(YnVVi&/4Gr,oh ҙ<;H#MmvmoK}[^^85#!b@w\ LTbFh'v(@*7ʕ\C]ZMm+/?^IE^KQW$Ee I@ H2M;\K xкm._3EC&Ef&wLu ֒>>|AIoj6k f!a" LXLg_ோm&i"_ CG'xf>m{@hI:fٞ> ~xn~#FĚQOubwciב_+[}W5?/tqr!uc)U 0J)UN)ϕ%̿nJUj%WVգV:5,ڤ^)§=jp%RRTbw %-~:iQCυ^3K8.9㼖kk[ZQOmuxRn'dZ|3{oZx*;4C u[k}r ƣ @m# :G$i7 I&m9xwz$M|tiN=.;g?b[^jkmQFw ]_~wռ[Z_5<[5/|7yiڝ֝SYn^ѭm\V&&ӜTdB/R󔓂M)FIe; 8QӄpqS:brxGn.'J'6̭~ZߵolV??LrIޭk"\wI$1Ɗiz\$;i8>|V|1kV^9cGH tGFn|!a -iꚢؿCGHԤIc [?no(j"hvwxS@ьV᯳\Y^ŭdX̟pu+dze}2J-%´{-N[엚2jk=]\n~(ah{JMO*Vjn ӭ 5KnRpi|aV8[BeN1q\E9I҄%%7]h)BpIy}gP{ JQSi񿇼7I3M'1 'x^ن9 u Z/NXf{9W$'4I٢;La$O GZ'?\ĺ"[ɮxWz]Z=AIwlhپn_(O:m]ZI9/e k"<3}uFt29*sф9c*'S[ij|@OUbkU+Qˌ\Ӕ)E>HJMVMO 3F^<;>,~l" {fHD8f]|J߉Iq9P77&x|⋋r< £dX1*z7㾸>oNFUUt3c&)˧|ODWŖvo/_oo _hZ/g% G7"k w˿ YiZ~o5xr y;W=rKk[wψ5t{Ē6}ºG b<ppG.ayWNT񅛔yeOJXrI^ $ PQ%w38:gI,:j^'_}wPA_qh^??hW~*E6wBִw 8cl.9?[V%ȳL[^1FhO.%Ld&bן%j|o۫~+{?sFIaɭY^kO[Col].=.+Qvexv*?Sahǟ`rӝYڍZXzYN QW>SqMhЯKQE7S O5FHF 3/~*|p&h/*gV:v5}?TZb:B{[{?K{KԖIV76V2P]2YJ$kwy,˅}r_K/'~>#?ڑkH/o-wsLMܪipEq-.cg״2ZOh6ztm>iw-[̒UĩzJޕIKGBn<*<<+$ܩ tZPVSoyFrqoJ+F>I׊|?Ox㞯c| x/WMRoеOZ/QҞA;V7TG,wOXynMya3,D$KpF ܠڷEnWL;+[']Fžg@CH ,M6 -?jU? 7KL~VxY2ڴGipEiRj*I8gGmScjn['q % e|J%yUɛJSr*i6E F|FFs&ޭ">!R@qG4{1o|1Ý_Ś͟.ỸM(:mu GOP#M:KuUԮND?.G+5|pٵVӞ?K!bGDt'ZiLZ Y'93kw-"X}X &x;diPT#Fxo-Iʜ|m6Ӌ*N.Ҍe9_C`xXRӞ>Q񮓅Zs\+2d(BG.~h?o~|]x7GGZ[Ix'īgu6:ׄCm z_4 NhA$cx~M?಺U޷i:DPmYRG ;{X,fkU&Fl~:e_f;=;O+8Ţ UfQ\ 1b@4~𒅞"+KwRL5sHx) 2WB5\>><Ē <%kP d2 8# ň[&oajxWñۢHdwyG󤲼#*f#ixŚysex()Eg}wө~#RsW*A[IݫZWջg4\;VF?WeQ_V4ӕ'z7t{탮[u%.`{ՄI{xWo(Ηl#\#UyuCgffdjاľ8-kjz! \yQ˨q NUyIfq.~ gc3[%`?Kt-XG""ٖVqOk+[;-m$F,?66@²F` M|txͷ>3A6ϛbZޛZVY,δllެWĔ,ea(+YJ|S~ƘuHmt x䵺$2| =*m;?J.7k+j%[k)?'G|}Ϗ uaQ(m@Y]|L1;*۹$Q_ 5oB{}b?ens >ѐUs Al~>kʛm7Bֿ<1#8 =E,hyЉJ, tN&Y^*\ʩJPqmRmɹ._{KюM^[t)y-s7',U\)OsQY%Xۅ.l|e)~4>2I|Ci0[|{OL{h{e|.-^%O{mX-2b%NO$a}Ҵ@(ڇg ,3l/|s5Ax$IDPpXWɝfT%V CQۄyOb&j&Qzu S\JJ mY|rѕ5+cⶍ(~~'I5o1FQ%ah0ܒA2Gg/ڪH[s'o;2]쟱ϋ*pvdeؠx#Y߰nRcEu`gIQ]$M),Q\+Nn-VeWfx_i?<@e>xvi$Ytq2y\vFێŶVX@|3J1I;$Q'M]iR쬟Ĭ]Rfڶ4VO]Q )ᴖT<Ւ"2FĒ ,m.ѳ~ZU+ʭ', UXzd$ Okٸr4IT/Y̊l@&3qrC>rޭ1Z~•g,l|),)ʕ|㮝o ??)\(I-`mbe,ADZ~yG1Qiuڲ_+R 4*XJR)r[X *zs+*ROf]B/:D:lrD$WvGC&#eᦻ"'3/I3ľe݅]TD#R-o IdRR2mawx㦒Ixbo0_"YXT$d'71hAvYl׾Y̞vyfakdDգ`\<ʛpp쟼r;'RT$n*ӛ'U:Je%[7N+Z'vnm=}Ǟ.46IukKm"kf#fk8o|OEpTɩ跖K3?$/KfdX&ueX m U{yx +5?֑v z/,iI4O*[Lף퓷gse$R/5|UsTO2MxЪ]cB0"Bnr[LXLT /yII%EE=vo]AE4?CNimN*S9NkɴnInguYgun[M߉[GMxkPI CHlZhy '5ƙȓG%̑ͅL̊[8%.Awh~ua?lWǎ|SYƢ:2m\Ed?{(hWpRYج)!}8p]%̅VE6)PT~2o+)'%uŒ9nq98WI%Kv9+;%d'N.Hec l"_]%㨉dVݙdXbW @U_n~ >Q 1}o.ԦuLD8ߵzQ'YRҌwaW+z˿߰ײ\NwDﶝ>+~uO]oH4[}#Rɸ4wq, Y[>;τ:Z j[?$Mye@"Ym^.B.EO%ܫ5ޕfY2<2Hb9FuO$VHaӼG]M HzK"Kҡ lrd&Rpƞ J/غ,3ҩ'v|Rw{K][]5%RURQvӵkEvw~ tI%$tFU{e ,bd ہ W >!;.8bw 7w:K^K=\O-%ycY^Fl+,P&¬7mRgvP9gwG!~m(UݛotwI;9$]޻MznޏkjiI%'~#p@Z:J 2$,At[kxvEg@IV>xJyJl.~PNFɃ ۍ3[ ȶ,km 9,$BK)uP2Uъ%2iG߄o̹ZI]dS5k?k[jyYp$wUSªYx 1[c;Mv7Xid^ {D[_xkQ!&変8dK!ݻmo$h$n%2['RwEcB$I+ts) F(]]cPٍJq*`k{*hΕJjGR5(.fg'%ҵ &"3͸pQ$gMi[k?䍃iqY^}~,C.0f cW'7źUTQVܳadg~G??F.8J(QeQ,=jZ\ ,0^_ 䝤itШ#XYn , VBQ>" FY/_p~M''2J~z'dp w攴Vۼu o[Zl^Ze>4FTPiX}y$lQw(v,|yRPuy}nLR'[FS\Bct+-{'YiZi-U .&H)qqqlou2D%L$ 1$h'-̒ڻ -zH!(7M$rY]*Tjcq U1U֚UIEJMICזXhN1'ogF^"ݯuglݘ[ ki$CKEkkx2hN43IJIzpvx/ENXzo R{IXxmaB%">f *6 5ݶiXHiװ}hJC}Asgˆe湡3I&n|˽;Br#H"g5=Aw2/7vq̳\p)yWp,Ѳ,BC9V@6>[[%^-6[ #}-,+Ҵp .2s𾑽Adg+y.r栭X$ >&Ƅ1q0wFr'9qjXc&Z:76$PA3<[RY|Y6_?o>iB0 ?w]w]Λ{j~$i6OEZ}K*N%uپ3!AtOع$"&.QX/≘2Q7%_[8Ǘ" c@mͩi>0G>/@-=> .rs>(H7ĥ f\I_k.& _9*6M4fn2{Invs%gr]T>-/ /8x$lK1d& P1yc Wo@dv̍B *d1I!?0WygK+aC<λX4ՎvhDlByLW5{n.5=>Z(|+⥃syCo:H(x;3?S(FJWQI{+Օk]UqJ;\UR]no*/WAqc QLRM$ij^7%3yhxsJ.-Vp=QGu*AJV8fyx#8/CX쮮n"jHk$998C?1_c#3*B\3%1p%*C\._dOݦiJn6jɮ[óeV^u;IJ+mtvv%׊<}%_7gXđ gEyn&mmy |tB_j$2%fjHMsp7\Ik +2<[* x>|#F%IW.!X/e1Υ8\|N)'tEKV\R%ZWt)r~U~}qoq ߋˈ(Y.`%i HAT"4@U7> {χ2!Şg$}Qc1UfuN͵;ĩ&X q!PTȧk+n"m儌s_ 4.TվQc#nNm$ݚZ쬜}m"QO۹k5y]4.weoi>.1Q 5 S|7dng ]ekVB4$@0KY4L$m-9p61Kzb@G8ØuP ^U~UAE9fB#y:q$$kv 1dj+WחMwvotndwrT־NͶb"Cd3uw&hbgH O OEƣ#XfFl)_$B 2+GH2r1̊K!F)O62~}BA[F Td @Rqwm;AYY߽n롍WzX%%mӒ;Y;e{3֘d0Qaq,D#Ė-LTxo,o4 w!ߴ{)|Z4-=,@yCbKvew#xl Ja%t 1Q~Q'd׳ݷz+m5;^V[0IR٭eOOC+M9yNޫ0wu8]b0E Y|#~Vˌ*pI8:+2c E/?$r,7"v+RA-[e3]Md}Ȍ?&HeH|Vv\m~nggT\F-Vj֧{II˕4w󏅂AƑY!աxѐJH,CWax<$3}A8ΛhVI6H!wf#~u9]%}z%qlwz:nFqAK2-:q+,*%  De"IJ O V]u!]td}e3EV~D{zD{նkЮʨ ] I̚Vz6|t:+舾V b@]x@SG9l#Iگoe 6 :Kw,k{A)i%i5 o:+eLZkFn'뺶A1J[FL_ U,VH,p(T(0D}o^o$]jI&`eg;jxXtd'w~WS>Vww/>c@_s eᄹfeV*X oԭhҫ4Xs@@Ѝ^u |slBXa56mHͼ"ϳe`esEJé,o 0<ޕ#mVK2Xl;egʕ%T[mbE_$VX  UHA۶2S.9J&>TP2r+jJQIH4Q*;`q*~Z4]Y-_S^+.Vwvocŷc]DeԳؓKd$$2csB #HH!|Mo$KYT~.1 n 8AWChf#͂e&+xLIQ?Lޮz@e(T4eepKLvЬpya5TҼS[vwI=DmvXvW|ܫ{-lwoKcOX̗HPZ3:,n$, @?`ͅ,ؤ0"Ԏ)m-`$Gd*r(:Љ`dã|V0M ̥nu.J ph4Xo\+RLdnH{fW3\,1z,ΝZ&++nXf~Ʌ|f{γAcCv(ֺ[F4uKT6N N:g=H d֚5φVjn@t=⳱u <X_c'f.b?Ay5jvX]Feenɮo ΦI7[eY++:T`qӧ^|hBB6I|ޜ,Wj҄as :)G8Z(Ԕ%9{7R 3jr[OkW ÷S짨ť>;ڏ1nc;ϵI6Zè6biPiИE$yU3eh:Aqm[j5 \$ґ\l0#4)+h ehdogi_/SQsxk፴Л# xwwW5 i~Ao?]h=.ᧆ|YGyw&t(eO`x~Q8OkBYm9F\Ir6C')W}s#tygM3uZV<%).ILJZUxcZFzN-_6Okw>k%#څ_-ۇX-DuW{xUj]as\iW 4ҵD[G˿ Jz%{;|Ei>sj]*OmZ'W߱chG;Z$(Ź;~d͍n|h`V >5CK~Ú, XhڥV}F q46RUHr)ըirΜNQ|1`+rNv8M7q<ZJέE uEMNU5fWbzSHh?._omkhwiq|3ȻΥì2<7Zp[H5Kv[hkuV{im%Hɕ#.%՞>4xN[OGW{YkS[ ĭJ -h։ix~pƶ%[;/qil[[-Q VyP? VUFrUIB?tOiuJQN*ғb9̱* (z'X(:JNRM2Nn]r@?kA)w >6Bй2Gs |S`sj!|ZdHidO?dio)?F[iS㯅;[#"ǦhsxkRƵidw6ǂcⶋIUյ  %?"=__/_~ƹmw-H4kߊ-F}*+@ ;IG|vO֊im-KY$]?vk֑rMmzѣ9Ka(᧎LMzS9Z5NUU)s\\JMєn/O2%AJ^ƭ IiS)JT:%'+ۙ~6~:k%omzaT۸򆞈?RF4Vv17}a) *i{b|n$h6h15O x&[E2Keg H~WJo\Mfl$𽥤 J]\i`&yvΣς%Tw }:rzXﯴ_["a0-Ͷ!hmnfx!=&)E;ȑm*U13450oWu*URTSI̶w|uS>:*F8aa<4*\'*Kc m/Lڭ6y0 6{t^t8k3!{x* L4U6񛹧uq3Hi= $o]iOۃݧi  ( R_K z{ѼU\JڝyovI7GT u3{3N\K/Oya!WvI3lVn~VC:Z FbZxIu$iyq..?0ɫSqϚ*M8K$&߼dݛJZ?~jeߍVߎ?㏆z_|rt=_~;H7ZuƱ+x q_g3ڶt]c^;i:6gmYߥNx&.I>85k?ڷ>#Ų^ Ybծ_u{'Q8qmukwfJIn:k,N{NJ7WU)SQyʂI^~fM=()71׭Rb%YNN,5h81/쵨['_.8y ?~ PW(bH9$Pns!kk_LMWS ~ x <,"͂rti#TE[v3yW>QBi "=?R?_-hD8ɊeE{]*4T4˭Vc+5łNm]-m%}BX.~qMө45K)JIZNQ=z}C~O:W(^:Jt^s 4Ag|:oG?[dYC5iwvna7vODvC_ZO/⶟?N]j+bY"1ǴJp\evӦf߅[mz\[O -"]m/d%M[އS&e>/g+`6 !P<"ܖ+9V|Ei^6m/fRKK6|ؙVdޝ6߳S ;ꖜ%&/߿iW Y1/co}h|AWҴkom:>~)Uѥkx#y-5Go-Er;%Z?ٞm -̂/b)VG13,[Da+7oëCMm6L . ]0@Ҽ˵Xk`Λ#d_KoWQ<=kA]SL8}2o S[Yܩ\$K u\OpJ`|NHOkT#9^.R斲nɦ⏪ztq8!(”RRpnɧ)PTڽN*N6/A<;VGѯz=3Şܴ-mZTt`O5¨7~8~Ϟ1u_x㕖KqjjHڎ0IK-Uom.% }5?؟0g{ikqGEcre_K.hNj%H\-Ey1ܱm?~R|)K.c5  *+w2:I\ iRJ9e 63l }5|=Kݫ$/9lY¬qyvweNj7Qi9NIA'wOZ9GY.T·KePb)5h#,24Jѯ# N~M㯋P(QVz}*H<` f-J[|%zRZ ! |55+yo$Ӆk#Ck<7o46_-D5_x$&\_|m$"o"_9G K Z?/ 2*S+s$ѫh-yt/ZUz"6-]$?- [^DJj…U|_^fYn c€ ?_u*M&[wk' )fj*~uUO%ퟡWVZy]M]C#,E22?ӟgJŷj[*F%P+0g&FU`"lIb?ewGE6H򷤢Qȡs^1:Pqm+k[3|}c<WpE+J 6c|ٗ3i #FҤF!BH8TʘV|w+Db(,@B5EBIVL2 YB~3lǀ32X`rKp˅r8ݧ֯gfRiZ_7:x%^m'|MWI;7w{VI)!}kU#kj7yM#O6!՛[geEu8"NɖDA8R6c23s3Aޡյ gRG w4$G6(!ɒ)9,G#J긍H ɐ^E$RoUڻwֿfM6۽W;;o '6$S5| =VFm|748W~x;M,/pPF_HȻNôWj|+'7@n"_;$Ik,ĸʉجo:V1DkOFnۉW̑ê~5",W8.P|^ʰ'ÔkKJnN7)߲G'(aWPj/Gx+7*Nsmū+zq cRr|o1Ĭ?o}<ĵƩK.[C&k3r,łe_2YZOzws}߈П5P.#HQ䊾h 7! 3.3ƯB'_j$ǰVz1uoVR\yk#QUr%e{M-nvۻwRO iH{fPUktIi̱ۄ\1׏?:S{k|m&'go^-..ȝBv{6_)nRHe?#FLb%W?k_I#e(="_\yŮ7YA/d8qV$$qԜJ Ӛw{˗/ĵg([N-oH0G@K.p?'g=fS-..Snf8 C*iBsuu{q"Ȗ|D3 ){d$ېA\ܤ ~NqBdK pM7+$y;+4~i%J%9R(vM*BWnkN2$6<{;;0|ExLY[ #Hwࣱ"H$mXl,<ǩCHmm )Dp(谻2k?qP[ cekrȺje}. 9X6<ʦ3NQܯSZJm]M,ٞ_N12T'ܶ{mo &{'ƙ0튉:ѳFif+aq/4QͤV ʡTǹ(-w%'$ĬG YwVcﺶ;L 0enz{NK.G̊R퇉;O̰)ҊpqSr[bvZ(lԭ)6k;F.Mj=/ǨxM1 Me* /$:>>dvTTr|TBdu#`6aWqe, è%BC,AUJO!1C 9PS.eJc۔!v vHB`n&\2vOUwdm.Se)9-:(ѽXj2l2H9DaԐ]Mjm7d6q`,X%Ȯ*j&m A ɲ2YKd|!A&WS[k>ʉW֊F Dq~h,qW@x%%V[jKK[֔oz.j.-]-VIi+jd^ Adfe8g#s"rox:",i 1okkJ t(..Ƽ𭉚4,HݽNoN]kTF29Y7>k'Qt+VᚷCf}FgDE݄*FdWD[Q*UH-4VwQ]gFHI5^R?vD u" qI0!<[,"_k?f-}c9Ge uʽ]vis]Fmj4մrqwr7DI=ؤ~WHnwu3k˅ij[t EH7iy7R9%҄QmBGmj"wm±ڣjאG&O y+h"i&g!% ZE RNbI+C8{-VLGg`l)+g浜^ߦVvMWT~Wvh^Kuv$T0uyYH$e-t(S%I-Fˏ)ګ^g+ BinB!'8FY#b k[C\kz2 {UQPf5ZK^iVxMR'XSzJnӳiۣwխ3Z >-uw&M${k̺76pr+g 27hW[jW&K]Kn󮵻i#10Dcm3ew:T7ヱI<ۍ3̶2cwwWan^Ibu;VM'EfSEKI9&+MVQMY2][ߤs\B[NfeRVVGiB*+Y"IC$[@,*DU%I h pJʥ_[}زKh,,fi.c2*ďHyb29YHE\d]v0,Yrya[qVIB6VWwZEhWivT 9J.騵'+vJGh;q^ Η uH#,%<+ SI#q#b9%E7 7 sϼ[a!&PPlEa*y~V#yQCXW7K cAW#;]1fdA/]VjJKImsjӺӵT^F*qNҷf❬ܬG/xQ$&,4b Mg*(y {0db¼@~u,yiWi43JyXE+d U\ *C( b,%*;9|Kuk4ޯmmd]3B5/&>k+y[nIWgUaIUUc^^BE1 注!R1^iEl̪FUi,D"I^I9|G-QQ)*~h]@. $` !.QOnm$q|$).F@'c+é^>Z[;&W讵6\O(2N\%Ӵc;/]&vKKQsc&IҙQ|N2-s~xvS gY""M{!O Jxd,ﵽ;y- @dZʘ130;*/jx 颍|O d̲I 2`+*sVW]Փ5,զtEiehrrm]S{/~.7^i2*fc' Uˌ~wvyVUGB$BF#Ũui?(KdVŦ)/?p ҎPmATeڸC?^KGY2)x1do r\Q  ;4U]&乪e{$ײVV3WumY_)jݶ+xsƎJ|DT6$kB8RLe;Fg2۝G@'HH`$,EO2oY4l(nNֈBHH.5 vVAfy]3d4WڮcrX tvHЕՖ52j5(QwJ$֭ٽiv̿fuT0ަs6tQ* 8g 8ʏ6[iTR$v\b˵2>)y|>$v$$MRd 3@e 47`v8L;{og 6n'$Вa}_;{_/%Vҳ⭵{&e^Y[R]}NA`)}?J)bim;HW;ėYJIK8 B5!VpVsYV8 V-)AR2iYYLKI9MsRIx|%Qv4$n0pA kݯݻ[>u&"OyA{[Es'AkţH#jI $)$‚܎|]xOEtQjd#90^Df!yeڑ66@M~+єi+\ kyfȉ Tf|,r*GYt 4*=cEehL..cyYeVrɶUCTy5m󾖺ѭ/gu{r\'rJ=hqk]t1,|xx"e@H  l77bf\"ƮmuEeY#B,j@_oN^T}?R`H 01@1b)!ldy(Yضڢ2ɶ=@D(lViWv-lwwZӔk5k1Ow+&vݷJm-eqq'>7 dhď'#J&cjYw|QÖx %HiΛ<򺩊4Mǖ;ш`"M8VVAHiviKIy{q& 3'ΏQ=$4*Y`q>!&k^z_= ܖF1VT^\vqI]"~ߐoAMՉP8syal^sPl"3h̊L'sDd6n D+[b6;@eq L9w*mBN>\X+x6y_08y%>gIϸ7Y>L:ߚIZ[|ETϤ˗zr<էk7d'#YQ[񫈙b†#wa3H>Xpц ~G5 9e#̸tv9#Pȉ{wT]#M<S/J3nx;\.dhqvc7]9-𹾰.,U$ekB U;yⵎ\/+5km-J $QV sm[t&O[v(Ӵ8]@B/ߺ5DR% 攍f`^}KL0id6+qke*'t YLb5R;oadim%E53r88FF o+43,f'ttV2C]cf*(Ɲ6bv}uwR>o*uZ[NWM}vќm_43j:t{]dXĉ ?ƪ|Ĕ 62'("Tl6e31@; >9ǐN aɨil7Ifv-WZg;\ڹFmwu;}5[=L1CRoL&6ZB۶a8msZCQv3I88FcgaatY?-g# [/́NѩlkP8ݥ}镖;g v) T&[ԓO^KVY=tg5Mj4oEn/y"ÈFWܘ"$bۘoRRb`&%J:6%L9Pmb[i|û֌$ӫ)hlJ!]w! W#*Rjo&XbDwyj[$`N3Y4Zoܭ׮+ݷKҥ-bx?w=kѤBP&~̶}ѐ\a |ڧ=9=܀A pwx<:Ɗ#{mզyb͵f Y fʯ-;2  nl/$e+0A$]6{k'KvYØ?;-U:z^m9vvۡSHn(2$n*** P,숑Gb+ B5ߌÙcbX>bF}ķKI(r\DR'mO+j_vXn-H1,3ghc#CK[j9'>D]K[٭[Yۦv`)SQvM[ݴם2&cc"DIH14Cșo*5PNѕz:'$`$/ Fר8KQ PBL*,f>fVHQvT; r9 k4m|cta)+0#@r@FsqiR]]мlqi8JV}5Z5$"yZbw2%µ\d~tQFBJϢo#rڪo}7 0)ݶNZFKkh/^k7Kme ۻS˚He~6FNu{,JDSW%x Cđsw! QTh0\B#2!*|e$pӆ8TsMmhnͳx1ζTJcGrK qTXNJ87rU'BiEP&?n獉cG|x|8@5 $R<!@@0KԻdx=}q7m{{|'+ nefa {޿?Go]Ŀ9OOX}?gڗ2BRx'L00|aiy7jmGI4Hn.D}[Z|M?PLәMM`k.8THM]ShSZM{捽&]Axg*ˉ9T+BIU*}ne8ԊNIQ<ּYZ߷?.Kc7EӼA^3`7cSR1΂WRwqmŤEwMBsrZ-R! {LU#wm!PeS<|W)ogki,;xt%DqݩynK B& u^x@. }6Pei'ta>D+i{'h&rΪd~d12+ |D %<4\ڄn_V9`O_*7i6&Y;!7zuڝ,~׳]%<qo5k~~>:Ty|ɩ蟴os,S] 0xK{GTI$2-D ɐ3)(죭Yi Y`J|=J-@$sG1dXV)B־YzG-!xkuhAxŭZ.Z3#ryl$F+Av.473Īn1LD.iNƚj+P'gtZz;M}*x$^RJQ`'+~ysE'vxs8|`_QߌA0͵v>7u$g%y[گk+K)~_V6Դ?v)I\ =ߊ~'I<I9餝.1aƯ"t+xH,$ {5ψI=y"6@&gUExb`K_ -J&_ҽTDmsI7KʻDtkY6T8.h*TN.Iپ qmYGVJNY᱙gBPagyӧQ{ɧF|Q/Us[0ZhtԲO%HaA8hL#+XEU #p!Ǎ_Pԗ&rRWRMpĶ$ ILx*_Y{]CK,O uUBq#7I?"p J6Yqb< p$48.mMaun|նmn1*y)5 q$vѦょ-I^QQvM| ߱^Ke-ke ~1g{5/yx͐c Mrs6k3z亝\@," /|='M5Hzoةr4wY1~$Kj؅mw;k}EmKLɲX[D"gj{$:=׊UuE 53it+Ղiќ9Ni9ws|V79;EּǞ)(Y/d[ᕯR[__Gex|9,Z,4k2}.$eR+IwGLk& [\PI,N&R8͟G\ysfqGƒ8=&G6~Cjp[ P+_DռKF@D' Ť[I$PIFKs ^eQg9});7SJIc nq6 sEq89s>gRtRQrZ)A~_?h!:j*˕I+%7oc*v*u*VX*ANqQVNyA8ZrFV|ߪ<=Ek~#r pk,5? Ui sk"ɧ慒R1?_=6m<&u=̷kmHo"KBySGX(5b[&\!}j oDk47XߕLMC<-ŭαaa㯊-ͮx?uk3Δ[j6 Hnmฎ&8%S09 )S+Ru&QF-Ӆ۔E+Y8e>#1y*oywَwu7~HO0OiI|?>{{*s+4FynViMM&E5)!- i|Z񭞕L)P!ZV1F,w3|:/LIVpe$܂~m4U_M-f'ZßoO KAKas{m Pٙ/[˸G-+ VxӊeBQRKjNJӌfRҌ3_P B*0s҄qJJwvjJ3IĿlWa >x?xr%|?}k:3 u Z7wZ\G#>}%\k_|-ݛcin~Z$O*?cKdu~?̥DK"閅DzMVtv'G/]I|WP-ms\mg{I#q-ZKx6Sŵ[q |A̛-j叵nQQԧ;s[/UU)*M:Ҍu&{/{O\i7(M?'UZ6SH#>1~!:deP!kl8N;? /pX֭.l/DrKc~T4[Twv'Ef?`k˝[;]/QMkoڿ WKQoHB6Y0I0A?gOxG>W~ Dne| 񭿌綏^&m5˻-6Tb!^%3ݯg\8TWX*-Te=yQΛ>hYNrӎJJTT9jUꮢqN6R[l~m_ ~5>RH Gew q;k}GI[FaU?ŭ*qx_D*γ#{;IU4zD|g.|+zE? #6O!YU#Mm,fG_0翌 G|T淒2Z)ksm= Ѷ_- 7Vg8y5B|?1?k+qA~sVЪ$"[jyJ\K;#>M=F]ିW~k|5ʜ13r^y%G4mjy;-5%Ehׯ6? Xuu |jX|+ ]|"یGtrYF;Ֆb!TO)E"e,O(ԮH6j¯ m$U,q4Y*팢P) '&jF$D]rӅ~Y5쒼[IhSOg4ݖ.1qJ} !JL553}o.eC"d-ć⽌H%?y1g?X% #"<+6 ?+acQ3 JPL*EhzIc? .f$3-0oY5e*k>3{YKua者OG٤T(õⵗn՗ɦ[UOd |!"vƉ>9@cd$yߕ؅bS|d,Hh?wo3)'b>YԉblbeU/'#FƊ7`_Edx+5yqcv\>.AY0*PyPpu9I,f!eZޗkJ={}hGX\$^Yu*IݶW=Nڲ[H?};ȑ"/,ϗϼX*SqKd`!t 0+ynvHW31Νҧ*$.∄n?/a0(^{h;V_ 4p$WIo-6ĵtV_O[imnIZ+tN/ ⯮F3XԾ۩I3oWc,~&I.WN9 T&TMo]RI.Kncu؉r IJ%x&~f"?(\Kk -3H|} %y ft@ (ř:bvNPN1N.sUpmۮmn[>bH<>Q|ܜuhi{B=\ͻm>4 =?YuMRA4vedJ`.ey"{ ^Xoǟ$|84]Mx]2@7 Cmra[~H$x~8_!C ~s$ CmLY]٘%C/xoUƋ[^B~_ș!ۦi0Xn$Y{wFq $gs<\hZ3%E+7P*-9J-)Z-QV%7B$QPiS܋JJ2M8&i +7ŗOa-xȂ+_?[]P40Ź%Y)[GL4hĔ#yk$e ~|K>C 1>2 1DQ+Z2"0WU]i>__0v܉FdȢy6yaa,sW JܣNiJ0jN)iRIƜMO%-%Z얻%mG+kZ[2<~d(4/Sr o[Եo_!Zqt$ bPom.ad#2GG %̛hѽ3 %wg\ԖgNŲ" 8tsO}g_r,ّ;}V MC U^3[N^^/8؋URƔ[#Rqm+}[պWֱ<ך}3Z_P*914.-BL2G=t[I@_l[gv]eo603Mm)!>TR`kHp4ˆ ǝDg-EB]1AΫW&81|Z{ڻ6I+zTzoDU+QIE+M%m@<0~l"s663cS3#'@Wʌʅnl-m:1#Ye.WBmcqjȦ%b#1Lml R!oT^-0mmet@#5\-a%I],iy}$Plˢ}C T5Ѽ[k%k$zѻ2hrI3n*I4ߝ%E䣤XWٗː+_LVvkՖ3#-k*!!-Z?OŸOrn.53I!&V!؛v,H yoOhT" +TDgrwU+F&Wn7$/~0 e*rX$5WoZ6TmwlqB-Un2o+y%c-ZWFGKf  ',9eyc6sqswmg6HK(yK#81m^$!iw;d 2e/ԅ`߻zm,tDJ!p\ё1ɭQk|]'gt{=I5kk4VPB|(􁂣FIf88~Pim+"ΖΡ7!ԓ1wGm8omh*$s"0?0 xsp{vhHYmѠ;&I|e&I+駮uՌ;6I$o{Y'Ӧҝ'_ ڞ V$novyVo:г-xI]FMсRIL*`* M8_*x$a<˻$co'̷zeOĮ@f$V[=[JR[n2ѫm>ZkE+ιiY݇imlC-Q[,V%%@" 5B:"$YXF!,?8It]6mJKeEXw88cDeͻ ' $0Fd`j9u*ێ rTv9^XiǕ_k6++zM;dV[IMVRzsY;i"JєTSԚI^WF8H51m x+32dTWT5|Ce>/Wui E4q<ցeܑ؛ `u_Oxj% T~b2yݺ}Tյ=lsW-9$Bn֪wh<h nhD7Boہ%Lm{ K$!u_"6WL[.Pr6.ȿxlk2[ #nϙ,̀)N>I?xFv /ĄG Bot կ*_kx7c;XXXynI1[8ȬGIIo CZȷdH w qʖVBpk˞;I ?C:VXdpGdfvҊpjOiMm*+E,~jGs9r._ԕgNn,4) a~'9i-5ɭ\9*+an|·pΚO/[e#ܠVo0)$f ʶVVdH<"T b1 E:Æ>+1ڠҐK31P@sZӌTSRYIn۷n)Juͻ[6}ok6tlX$a6`1?vw*eS xk%qiko[HY6 ~oB1+e0}> ޙmET] | 2yB y/f*A  e%7~V-ZV+yJߵӓI;(wfە ֤g%2|nJ]w!)9e21S>?hfSooc 8`wsXFg4xC".=ԖCw*ȭ[""X WP<0lm!Im W4nD]r-uRͻ7{7wuxۊ vXPɧ$02l.c .)&6?3cĒ"/f<d5I$* ռ-o$O7Mu%X8(]V(* fﭚiݫmMw*#ӊskv֟~VB}"ԆDd9$@m\`/VmgLR@`[go$ b]X .[x}n?m.$bQI;QgTY]mgaƋOwrbmi\Ousqok+)sdB>n2$i&\]zle'uKݾuwNLK96NHФQ*̠.+J=Vͮjwl/{]T<w2l@1ٴ#F2!$?#BlHw W8fYccf"ɭZJGvi(\"`H+yow=/mjһ×.z,f.)Y$թ[wuk<&6[cn]S\ReMh!hXw3]CyAV>-H[=!*3 E~#i9ꋴ8Q e=af|y.gDe->c!P>._@z{ƭi|V"0чRH+2[JRWms6^ݷ2i)phҴ9-s^Wmݬ,cR[l-2"Gˑ#CHcde_1Px~-v¬V _ee9<"&JDq3C!+ʱ*α#a #`߻<ҾMNWz^I;u˻j29ekӌI;/u+)s%n aP (-) I*B6Po\N_a,̥^-[YI4V19f2cGC𘍲5]vْ6!m{kx)1Zhą X2ߑ#`2{߹I>M=RU[kXuklg/i)'9.[B1v&Ri)heY%dc Yo0y؂2 $R(Q](5J+[Fwk+]-Wh7kKU6һrZvN)wo laB;8 ;E]ь3=#,k:6{шl PJ* ?IQ#BڍcȂ"'5Y7)UU%Un;MPW!H?gT&9J۝w,L0U Zi]z%|ގWv1ҴSnVTSki.m,=-G{CƲDO6eFM0HJReD̉$%:Ѳʧd jqxbm 2C51[{ґ"lVcmd;F*1+k񆿼",~#bn$.€⭒,9aܧ'gZS6K^hE{e3=g].=7|4^DFTp26 U(6v{7KCKi=5O^Uo%gY+vk+t湆("ՠxZ-R2_񬲋K\U#U#VGpf-BU-RGUXd6KxC[[\"k$βC#6kxd e[!i,#\坣. :t慎6mjյwo{Vn2'Mk%yln ;?|J$,ż3NNceI[(]6 67 1'+<(|'$i5 jJtY0fG_/&6iB`P2FW's}sϱA8v䤭giϥծzY;jdGDVZ|}F_Ǟ*_mHֱK?K2>cɰ3 (˧[6KE= ~GwEŠ֖D~Qk(% 6n_Ej#]|Wk:ޡrڤfȷEexwKl,l GaGse.R'Oz:7'dH. 5]K:tK2\"YUO煦9nN4KKe}SKD}Srpm+)sH- O/^1> zhfb2Ȉ\`:섇eڟ"7_!#Ϣq, UX_B'k?b*`n[еn[>a3Mʌ~$b\]uVl~W(3խ.}^ћQj1u6ȸA\`.W@c1"H}{N{y{ _2|N q bnt V`\טc(c|5?ͤ^GK?YaX $-g oYF҈u 8Y“>?Ŷ,*%x@o!c$y0=uʫqj.Yul'm,%5!%4ܓ4.\NQ:quX擒4$照y^ϖZMD~"!7gC0乹j`۷,$Qihx&/FF/~R’ϧb³4cy]l.d)3x/dK_!g|<*F /4, Cfl׷#xkaizK}4:f;WJ n$hQ ?2F]Z3 Wӕ^:_{_6.N sfuZdlAI/8uѾI{gmk="X'21eޢY$Eh?੾>|}*Қן'ˆomcQ~"ie6@j`IpȉTf"aRp[ZFݡ`IhI.QoQoNoLդi5߳M&*8o6$gRXA;1P/'>9CW$?ើ3Ȩ`oCDW@ Urq`VO%goC&nwL`1uDa0xbgUd `~Ο`lȿ']VMJR\a\xFQxM[J9ԮM^>(,^NJIh\/VZ/.Q^V>~@$Țpn(uQ?,oU2HnIg_a>:yŜ~+*Oq GP&9HkG;5|{tÌ-H))q*#.hO0rQI5.k%%+i8dH֒x)Vl*7V֑՜ yaM%> ֧E $['O3Kp(RU[ºώ>|a5Iu\ơt$KGT %pF %}BIE/k !{Fw$rF q2H;$ ?w_g _2Kٺ٥/,Hy6OG+{(J% דNRmIGi7S_39aeKsaEj))Y)>VRfDY]k ?jFE.7[-'Sđmta/u]"jk>3j$ӓ#0i#φ4KIpeȯ k*2[蚟+m:[ѫQS H!E(.!Y# ?eUS|q˫}(w m~|1ץ"h.Xg(ک*ļEVSU4L4yI5NWQNM&2E%%i'hRr_ I-l&C!_g&7nRXKEٟTISlk G嗛X$<,+5%{Ze 2R3+eUHTo_$}m$1ʚ#x|K~dYt3=nyN @k b|/);]+5® E}_WN:eXtj-SI^}nz9UtYo#9%v爎&%vݓWWM/Wk*s;./̼F&_&Q cpւP Kb|Yj_YJ+=qtٗ9 Xy6K6bwT <[6UG,dwkIža~h[|ZUKx`I.7]$@@Wix#J`Q_ec/c[uWV~7C ӵ _⟆,];tsY+tm<'W])Y HߏM[$^_ĺ-NU~V=Օ/@'46oO&2֭n*M7QӭAA7UO^!NTF.PNsh)5WRTSSqQ?>g`| Ni3y 񣫀1V8,[/P@ ,Xxcɂ$2᯵dF/!LG+5yǃtQxm펋]ݥ]`Ms`ּiv .-gѴLmbc2MG7ěN2~>\ƣYZh0[_3o8g<ƝiJTS*\0βkGӿl}8)TquiiPqOG:X*t`I>DgW'X]H!4U#G_K#*yC;rm:>bG|QtfuDeo~ 4j&'p蠼[_42HWD`S$XxA- VԛQo4_r#6/7Ⱀ›@bmT`TJTq6RIs-[_i]\tx2J2nYPJV۪wVjI%dyJk_*H1ݬ`1@Fu/0v,!]YU-۴JY^EV(SN )Bb6z?'1xF&c~.@UL*}gpt;K Fem0w;[hQ2yal,b0dk7%#@"-bѴ#LW6 84e"Xvg^nijBu%X!dWZ̷M>b\C [. Un3^pqvrv6+YY 8Qj6⭵ZI5eHh/θfB^h+"2H&K z Q.Y&Ud$%K K $lיkd ڵ6&yCY"Uv- [Qwyvf]Zf{Dd{I"=1%%b78ڼj6۲Z*ZumiZt?v7qdJ=Kud#3FxF_ sgWR+H䷲w-;#@-lKH%TdI?*jꚄ=v1+wR2M9FdHEƫ&`X͊'xس+bSq6Zzk%wg&ڲZWj  8]c_$2ZYVpF@m '$⮥Sm@G'SC w`:Nv B dlU\RHsmw^ U.s4o4N2,T7}4zukkUujM%{HEjiyEfr [ m:q3)U9nÇPz˻q,RW dpW;`A9/ udD|*&1 Q$$ԗx#)0KkR6W]w}%9vM-6wE/ ޅo3jzP!d븬{dX1+FW!뛻R t(PXu1q1fb8+1][<.ѫh @ Zٸ]p78ȕނI  %<ƪ+VMڼӺ_z]yRt)^V%&ǽ?/[k;.S$Q/F## IwRL;Im#'ː&HbC]jH'.q*@ c](ſ6ydFjF33~pTlTUSNpҲK޳mv[-w2&(T)Tssw(NR74ގɿIwvS%"h9ECW(Hb%9 t A>VxZn7uefMFlVM%{GbVZvM-_~0hAVecaeo hhwpHxf?ޮ[#cOp,H (}w0A?0;@foxvō,A '|=E"n vAQi’'nMvkN* >G %I.e2}}Eҁ|JVy.tK5x ٥ E%mK%Wak?mXY`x+HKj^D XGiX]V+ոPkk6WkGD{Ɗ7htyw_ja\yʒI+%Vk;MuOXSmJNW{]h{yn- FYuXrn!arJ  -^eeLx%B{06,YkmQ4;Zmn[2F4UpFxV-c \)%JֹHĦ+,f$9#0;UJDø SIs*c]Fh`j )P 5Fŭy0t"2)h*`H>9%UIhɷt[jIzU%vwߙkf7קYA.8@321B{JIf_2I㺊 :H!A^NC)fTc[C-#FR>RSs]Ē"gBlYA%*vS($vcNolKXJn|tVޓ*m'R8k yc.J 9ʡ FTzlLJeRv20FbR*! yV;.fw%A3;|\do#}0Ś 䀾H6#NTd;*ۧKmkt,'J/t֖m~4nTXI_}.eB\lt|ʛ"1Z A Lދk¢F1*~T,MoW q$Y?.c-fp̤9x&OrL#*˫:u w9V(lB(Čwd)k k_Gk7^IU!<>Ӛ[VKZOѻ4ޖM&A84]bx%{^Pϛq9B *Ovvmj͙E0CeIx(Qce.VL#m.ȷ,z> G5fcx'=FEuٲHX*Q4#H!}UXf-+^uT^F)-ZGlI AC+^\ܟ2@ʿRI]-ʻW7^W[Z]^gqA& _gm_WM]'ݧ4'¨HT*:{:MWo+GROmPw˩qRm۵i!%  :mlس]Mđ qj0cm~j&K3$JF?IHDkFZ0l6iZSVKE~j B-3AfLFsЄcRFq^q-`{qa$򣷅؁FӴזx}4m_G7FMnA) V`TT3ȲM *^+(8S(_1 e%ݦMR}+_MNiONխc?gًh 9.di"L/Bar,Lh~`2H{u\3y8z.(n#[wgdhǧl zz;mBE `Nzq7oue8WIUggct U`F/!@ ld)R葈_1QkIMRJ@F+_x(8 'خ$`#ԣi$+.%YdY|@< $H1ֽE6y ^+nȋJJ9 n?Ӡfě]x9Pxn}FN=Iĺ'M{Yt%~I-S۾սҸ`n%Jp ~PqbҴ fu#kjWV}K*f1!+2bbDg֎90fEw7hfRT]|:.dK$ztMˁdK{^S"E#"Ej=ZZVhVՉۑf۽ߣ_6֮m"(ZV1C\ KKHSKhWr2***S"ivA'HJk-Ktmdɀk'$2$8$fr7ft{hP u⨤bX܀PȊl@u܎b,}4VSI7fkW-LrꕚI'講[42$|[鑪,2Cp$5wIK'A@ׯ,f|G X4_.Zcoo'H6m=^ ^Yw%)r˖ҽ+N]^7Z QrtIҌFľ)5;9%POI%#mO.1 yh"Ǽa_/[وkvsʏbQ%$,ڬc$W|!dB8rG,nTfb*e9Un4X5L aAH/ SISq^-Nr[v}iYMZkBRkwx/m''wgoߐ6%V}Gdg@ E<gxK>&C&O/Y.%%[ͽI$/t52,ì9:6@<}s*\oUfit[o!O躬!Dj7_"Wߺu;lkk멧 ѮpNr +ܡ.c 2rphQ}"Ho.!K lu Dq\{il{9>@ҕ dw`4y5m`1W*20_R{VX7-;YZvz,b$aBȚݴ_gURڏK(I5vܓ]uVqwjji~Moumio`2YyFf,kd #*A#Wվ$xAu #V.xFkZMQ Gӵ]6;3ā$I#jRKoq3]Ζmb%е%֪M\ĨX$Awm-emi#ۿ⾜.>jr]ɥxOcXMZT݋yRDJ>:qӭOU#.jr\ݚNI+zS^$bg9NPc'89Eŷ_#MY>t>Tm>(Ejw5˦iVve=-%%_:G[{xd,?_QBXKX$_~5W6? RDW~,A_FlM-eeqm YEm M)xz+9`^mBՊ!TX#RUFu'$ʎI(U*Emm3'9|mF:SI,i7ρ<ze4Ь"j:}׫GeEj \&-Ô11o"O:^#$i>..t˸!Uy%_1v"12FY5G j]WĿO6tGGV`αgn#@TCwa=$_z_oգOs&ZSJ›Vc4Q΢uH.BĐI}9|]jxW8pvT3Hr,l&m)TgT0U1\*)sSSV;u+.? hSDx_T#>DdP<3xmaft.- Օ~kM'Ti.?UQ|<;ܨDp;yJt' r0eVC^I,~߰/ Osm:Oflt]BtFw0[{MNZKoOg\_ %^x[ZUִm$3wjWb.]m嶋KWk^O>ܯtZQia)T*S:t9*Q炒!(F^rz())'SSZ5;џX \ S_xcSs5K 'pMοaik`3SCiL,n< 7Ą]V-rmW^*Ie[|E/dO3Mqg塛J[? ܟ +{+#u/ÏOkڥ奍uk;-,$C[ΝKmuR))Ua U9A)ң8j0Xi].I%]4Z䔥RnMUH(_urM??eM.Ii:u RmPӵ+Z\[܈ Žų[*r.kRݔ],|s⋗. \H B̄6ܯ#ThcG?iMFԼ#/-ķvvYjF|GxL4(O' OC7r߇mBMqq*9*"UV+/)].IAWnZXѧ'Z7M˒Rj>_OC ,qR5#+S(19(I9ӑ2hH{/O] FdʒLAUo?`Fy{ge"KXd@++T$r8%؏_WψU~¶៉>UX45=KR.\~M[C4 N]z~+ju/j׺=X΢95m?OUL }CR4y>g>|;~F~|Zf\\';Jt%kMJ*pIc2<&.SK)Gu*a/ V*ONhN4( rգ(7{V{->+m呎ar%?|Tѱ;O"Ւ5"3l9||{uoHX.lGp\e?3jx֟}k'|3o\$lU} 0Z <}B7#OnㄞVԾ6k:l`4 X[sk6%FHլ=M_ueq\څ;NS VV'%J禧̢0U8ieƍY(N*΅F#i[E GeXYoM_0ȱ5ދ,hȭ3Yi00 Ǯ3/6=tqrsaI% $)[h*#|1iígn\w^/E+X5X'A8.tu3izwյm3ۼO i3)/MclĒ4?ⶍYu2-]igH,k:0qͳL“'4kNw=E$ڶ\;I+7cxy$G(aMh`%W{{Sӿc=~;_p T|PI@Y]C5*9E_jeO!+KP"Xv"9Xo9t_&T-Ӯ~Cumqe"yX]E{Uh\ҟ vy-忒 o -ع,2&`yBM\ݻ7F*HS <$(#Ir+|_Z:F7qsmdڂ[ѵo15U\c'BsiFuݕs4'߰d/rV3xLK4H-*Ulnrw`?~>u#ᦀ-Ɨ⿆% =eIBVF"JwaC~߳r†k]㴾tvAnXZJ[P.˫k_X\6 7wq LŭidXxsOBQKoSi^iӢ?A G* NdJ4j.׼My7ZW."?~&E{?Z|WFzX&D,弿0f)Z.kKU=*^A[G wQ`YhͶr FLw<;|Ÿv< dcI5Ub F~$*^?o&O/\CZ m3o ,/k[7O64sqdt}?S N|e/dBKEqTRrMIMݤNJjy][QSsJ]z-G(/?iԢL05x]*Xb٪h:Vr[]-%[nE}VDρ>+K5{kq[I v+-3_hu1hOʺj4YQSki|G(o0BՄM2_ :7.jNY$wkF2KWpۊm΍X)N.ӌ]QҨ]xT3OIM\jnC1ŗѺmez`dK=Xu}'Jȏ][۶eLCar|Zq/^!q"s\]5\7#m*2L9jSB"ʮ.27bК&yWOKV.؜L%: )F7~[a*EvӴetm~ *QD f pFBqX_ Ĭ +`2o|3H;7(v}ZT w YM#hC!WT89ǔs_a~̺Os xO8l EO~NHPԵ<VJ~]ϨlTd9s-cfJ8Fޯ&fdyI]+蕜%O5X-,bAl]hr@Xws$6GDڮy9i X\AFO!R-4Css!'هH1VA6P\ LH]A9o &ǚ5Q*Gk*iΜI+Ҫyc~^YjZۚMZc*8sNxY;(ΖZs;~lG_7˼He(`&3)س$tL\Y.[XY<74Ie4Rǖl*)XoyNq !I}ʮ[ٌr\# JJ.&ujPSq.w%5m \W90nܝ!iV|99ai]=d՞WGFJTpPMNɭ#CM+;J?i\}IM[6~l&9,$HLy I"R_l'ٶzіkh+cV` IUC4Ȱ&NtIP}TA/$1L}rFgDa݌i>oDr iLC)W'%0R2ue^^mK Ph_8U'VuRi?-æ?6xR9$ 2]T`%e-?Ūk-#Me,Xo+uv¢<!F ?[gXz]xvP!,#Q8P9*ti#· m>ߟ"%k9zUe]8Si%ٵ8_IY\?YAEf/H~`ʪea vI !} rjTVɹN1jM"KqES,SJSiBjJSuM6z7մxzx$Hd .2k|9< ʎD@,Qe2ICVF_e;]J[ڳIӺ]٧+r;7kMJIw>,̃-@W WF( X䲣9,><>Iɑ'偕.r1".R7+.!T0x WZ!(ؾRJG aEq4o2e>$yfw_WRH] pZ},ZwWI#9V,+q8lӧ]wONGNrSwd @?1O 0w+sZ a G!]#/WidM[WGNy"+ x ]Sr*AݐXyI| P+: yl瀣^`ڶT]5jEvUgm4oKJm=ZbxF$eb6GVDkeWRXڬFXF:| OY,n%UСh3 X̎Ӿl0Rɿpڠk񷃈tlEpP{9&%R쫒|͒#Y˥OUT]jz;^m?Y%/% Or1mRp*HYnr1T`VTR 1ڬhcMoXo%B1e۹Fi]<&xKIK`)cY] !S3k5uK'IpMwoo<ȺMvvG*>LnV>Ӄ5X{9_Ს3fqY%ۜ+7Ȟ\襱32&d(GVW8BdǂY.k}5֞ )_u{ivcXa&Ǒν+mٰ6蠫1<[*+o) awK`-[sҢXX $mZi*r%VoG2FU㏘*gάĚDtکg>c?,KLvv{[hfJ~h5e$սztXM2LֺlƮLc4qċv.IsW+s_6,jhX C2ǩG&V##BC@c1 r qWͳrƟpvaR@2 i< h.\3IUpȭS B Z-KZ+^2mhVZ\֧*r͸lLO^lK HI>RmVf` bI=8 X-RF gd_dacUS\Bn _ b3xRU*e/P՝uM-x0C9wU<;i',! Fh>j;=[j+k;޷{􏯕Fzrquk[ݡtnIw/9݀#6:9&?yb]hZ12̻>͡i Rm]cYܗէyI%dd{!EøBmBWF1FeD1*D\;DhQ`ޤ3(QXYoC2gkH܇q^\1Z* +ZVmjחkJm6}7=wYO1JS6m5WjHܵ$B^.p)?{d|G޹GCo]bX#!F; F?>Hohu}Q 챀bUf𷄙г lI`;PG#!wqBYz5QdRZ'u'}7^/y8Сnd䢟-Ӷ&D @З|%bVr. }#`\ Bx`TK=v$HEh.$`dG tPDi D"SYdyDdxU\J7JAPPlE;|FÐN 2i;)?ftye* ۷ƺWRHѧK^٥'۵<gew7df?uExTLf8y,2  ~PAV8z%4xo2(L]L*ET~mϙy,vH(A8Z-.n&EyY3G `6P0HmqSV=fLg:qzCGg8]wf2̱PE*2 5{o!\,3.b4 XBY#plï-R"BfTFysgO$Z\=r,w KpIFtI`_dEԻ2s]ooJ`4ciڅFr3Lp\3_}OhcL]4ԓtI,TMI|}$O'WA fPIyd,)zّ_R˪Xq6ٵS7AfH+w)ዩ]:9֬ıq n F.%0cmہlkS g 6Y],mY%%&亻{kӅ;5-"FxLoi[#$Q0%r+Eɽ "* 4@2y'iTyK"G)錤 `*C[I"i-\<:%x}vTAn cUx'm?-5wRim;_kFܺ2+JAs9[kkk]v|WdobKM(Va\aIl6kΜэvƝGszWA]#$Uf+%ʓ:N<ɏLe81Sb|^^2$P sXQyXekt%fo%+k{d4*$JN&ءADʅQp@SjYi%ʺe}w{UҜV/&RiY-ַ_\jѵ-6M;[6grC{n m9C2I2@PA8z02Nk|~gQK ziNpJaK5o(7 #gR<3\m$#$b]@  vT,yatҔ޽OVE{FQKV.WGk^탑]8$d a$Zm$Z onlԣ٬1n|fm Sce ;&˼]DNQbB, $R^.񤌑[[mGnґcfU R%Y$0q ddؐ5PMTjr~[I[XVnNs|Aw$rJlw/f༆*|Z0|;ռ?mkd3Vɤ :m{IfKܴ8mj̥ +W]mngmtJF-}/kvԴ223]󥼪>"Ƒ@;r<ѻbQen%o1# $hJ֓F<@.]s:̺zEpߙ2>+I#;g&!T]F`kufeb\%2)R8F'8 I_iŗ+ϵ`1'9ֶL$b4|],L|-G Ulp#I85^0w4^k>#:E^kmױU{w6+[[ًFAk$)S&-tkH m+7+76ö~ֵ4& G_2;+6hon'9ިː Oz ӦrNV~I^ͭ+P|~ꕝG4٥v^Gڿ n?G6oῈ8dS X{K5Qqu},c1M\fWT_|)ߍ){aq_xG_?-gxd[GO s@LEO;9!?^.> Ιl5bf6$(1.eF tMYHޛ {*i̗}R4YmL%xѢc <C2|xϞ儠j\J4'ͪfӱV21pXLi򸴪ٸ٦(mi'>?oߌ<9]%\_^;Ĭu7-uOHմQpwcc3K3h;~ o~3^ZKӵ%uzaE??. [4hj.ijvvvqq +J%IѴU|yiRiחJ&u VrrMp:vc(RE '6>χ|}y$PG5o60XGd+S["q8猞[2UVUx|_6ƣQTSnm)o{zxTi%_ʚiɨZĖc—Z"`?4ZΑG\#Ś6exd'Im4MgQm7#$A a{6zlc6EIZp:-8rI< by$`aCW\'UZF*p2U=ZTNJUUrÒ0S4*x<5VN3 u(FT}+ɷxMJMe?='^9ĖSx>Cޛ,O4}{į:WqVhgm4a>|NY^xAWk?|Kꉠ&j{t.fC #Cwavx&cӢ⇇#X䝞2.H}l1fF&&!+[7owHxHYR+P-G &JTI'fi&Ɍ8ݻ=w FյX$:\zjqj.<1rru %ng'o%! MAGJ (!*)orw_cCH xioF'hQ!G%FXOz\s3RK,4?&\ܨ^9y[f5̪АGetvKo ̨w% F_NRqX֢SR|N1wmNjZF^PwIJ׾4t-vu+ҭOcVxd 7!$Tw>,]%Y1 ش4o4dn^\9Ƿ #Zuo V?8]՚$a{i`1]3KkvTR1o8*_%IWojZjgsJजZWmIZ2i+u}=g"]5թf2TmI)\ 3$f ~'xYfԮb&ukkpr^AڭP'dy;ޠSm#%D)8(TԮ$mTY=:V3a}y FGr\+K#;÷c}' -]^QI({%m<弴/{%7vMv_k6cqEBDTSb%F`Y|jaRbMoUʱVS<%&s&EQ@>.tωZֳu4IA><,I{lb_ZxAonGD_+Q`e:x4ZJiȝ▭ݵFھjXxJg կVc/M%ˢWkm%o1M3$ЋYQi529AkIulIgd~J>,lZėZug}5=.%-O2i:;HKTE;[#1Vfې΢w\ͦ~IFWJ嵛z&-vftiҌU*soݻWIrKI;}^DveQ=Ū%p)@!d_.6+nvp+ tsķ7GU VM|Ȣʬ6[J> K3‘$%H[`' .(j]\DGXm+ʦ|FŐ:n>vz7YziRsZ .]%'ݷJ>_ !_ xsZC Zjq";27S"%̟hbU̇+zKgmtOIdbD flW 8ELHX[]KJcPYݤN#KEdXnś Ueυ/6w"ܵ]ݓq{4" ٲ[yKG5ߗ[De;UynKd|׵W{5JTOf۬bQi[EdOZ>Jê1V%ͭI,AG#b한7iJLe8ė:Xf]T Q6¼ \%Y":w]TXD `X~̿rD)cwTޗYqiatwZw_;ia%<8@ w{]F^q斖jnym}y{IYM5;;,;ݷP4˘qncyI $Q&jK/lr 9 }>KvK\&dTctVdǖ+&I+e_Y܄HY].1"9sآ AR b#mV<ުO4"\2(qW5Z=]eln;mEǤ]gPX5-.Vl/$h&ۆU\29B2C-6P%w+[ܰYfcJIwfǕ+#i ^^\1DS$ypq^}"X-(ûbml௡9xMW7Y[u&vwWM'{E51XCy_j"ŔaKX$pF0>7l•T4bo-N 8b#Բ#m %@;Ns]LPBDPq=lNT@Vֺ(՚sZhk^ԋt!'n[šzގ߆[m~otb Pą!XrαX]+Xm6 YFN dnˇ?}@͐1d$6I^?Z屩݂39Vg nbiokF5n;iW_VbIfx5 CL@Hd5fmN-æoY#[C y`˕l+FF+_VH ҟ,6V}Jї eCFg<2yS6XF> jIʼ9R։vsM|/V2^J(,zPiW;&ӓv9{@Z0cus$#r_tUPIpNJ⸭G]Vh*n̎F&ef2ppK55yG/o|(D2`8^5{LQ{#-x-u;9KO E6gkI[ӬԪC+QRV,yj+OI]SrR˷XB !q`dʂSxϙvH3&.B*#Vscʂ|Fc1mװɽ#&2:?ኡ0v*<(15T;[2YXrpJ#D{)B*+ٽ.5mיZ(]-ƤWR6ue~N-{m)$o?VKa"|̂w*RMɴl,6W)ye{!%cWHB]cc`OdY,a;FK y2s&65+JI O7AۿҺc9 .5Mܪ Jc-ϳ-;#NIss>~eTmiʭٴN7uחς,Pk:8!c*890W%o3$0pK< wDžܸvX[m; `ě|cbEe|AI!t=qbPnN;1UAo5S/_l*|Fڛ ㉹UkJ+਷UZجN^cB8?yڝ6TX]ֽM>(Acq z.1#Gie +H0 .Kk62@"ފPd!fY $vW{ٽgd(Ti~7J3^>*̴_F|};rLj: evX݂ᄅp[|@|)chl)W'@;;#|UmCF|7/Ab!bS牼vB.~Tn+#(5m;kI撒s֒f{]t_U` kan߰)ېQEyW%+67[r UpkG۲S! ()J' *dGP ¬FP+R1bLnnYB#3.^i-.7Zo}[R+m]tf<6:z"F]e+(@d%ISiR:ř. c9D;9!K(wtwp] )aRy5iy`qpspA'iíZֱz)ݽt լW}ڻj67yyX#TrPXE:'SV,]ődN<𚂙4](. vIS LĔ> z~sh:T`3duT 67/}*+M_tڂUhݬ[f&Q2ǐcmÜ6uc |X.k}}RLIc+ES椊4weHG+ Y?20c[tVg Gvw.zxNhxJc}&66FLI$YI>Mg}ncTt㢝L,,dƍ4X|$ x'ȅnBvrwI+ON[-g',yj|vX>wp($6{ )1WPjF ql̑*$o%F(Yw'x x,y[(qoU![ G |'l셴eFPE&nku4z7Kgޗ~9t. Dݽ^'W ]oʑhB,̌VTtaZBIzUҽ\O5nuy.d,Z}lPJ,<ߕu-–u/ putCS)Tv.9a v aH,xfu=6͒C] %H5O5Ɠn\ֺ^\Iq#k!(J+@YU@((f"j6~,M5mZ7u}[ZMX$7 r9CQ-6׻v/4U2Lزjg oݎ(ϼC?8`iV+ԩ@$f+}쎑8.ĩ Kin4gqR\w{7kj־+]1hYĬGU[(UaV/,u2SHL@Jm!B v.J%e reA)r%mWצ箟Zݝqt뚯[@[%ݤjӤ|V_%2HFW8$k/XiI.jHfkkl,ӯ% ky6ሎI-CĞAZDDrຄ]ZXgv>s͍Woi[ƶڅi@!VeNf{U9YO%xMotclgBysBז>rJdMʼb:sjmݴg2Q,Igh5vKFu ol{VcXG[A T*d!b'1Wn{u;am4VZ3\C"2h:ohS|nI@]|i5ONKн揬mi qnz[Yu[i@Wj+|k|.F"ɷmIvXs$A!tgCUg{XӌWSsWI&3WMehgIZNk~XβbTV@2X؈'eh/=dˊ/V#9xCyPWnG*pᄫɄ4:{{8QyDrM Y$D"g1&p9F?>pc_-+mq$Q$Aq,+H\#ʍkgmwfﮂ-OZgnf5=WӬHt@u}2UIq1A,>Xx ,wZƝ;t}k}ZY_K*W6wq_G&ti\G{<ܾO^9m:'Ӗc΅D1 *jN(wBX|`Dʆ$qDﷷGT'v\# ^e,>cJYq.eJE9E%^?MIFo&Ԝd)gcV*EQJiEy;YuڗZ^-mgwƛw}N 5nZ8"H|n?ȸ O* Ycuؓ 0d%̫4 Y yž)]CGd$5Wmbx.<$I,1ER}2+1bh;He5gȊKкE8*tobǕi$ֽ&fRq+WI̒l՝Zޙb&bi ʙ| [kynW,{W+IU 2PasD4F6$ULYFt+i'cCr! mQ3 ̇9v2*f{xYQ@M4h,bT,7|PiJvәY&]:v1i9C_eD]]_N ҈ͧ .5!,"WӀ cnGa#mA24zDJZXɒ%uDFyv! -fvlDWʿ#tV# (`W/´FYʯiƓkm -3g'h5[NI&VZϭYNz-m}=mtգ:֦k}:>Gk;kZ9X.[VS|yb"YT*QKZHQm"LhNҪ@=@GMObtȕbwI&w"#( x@|ZsHf/#k&dNjSń,vg$q7/>wmݽͪte}.۾=Y۳i6p>E &5 d%avrHs%˖w7ѐGYG$,\*ۢF`в >hW¯~֒{x5+xOA+1,E2(BFpɸVu.șc\[ZGfaqI\[2KŔ'S/~t-ۖOu&mm(}[-4íA4~KY7[[Z9UC0Han3*&e1jo"YHPR[cv,:Gp"VV^H٥bp|?\'#MKurB&)m2DU_ [w.-"PKŵBy˴c>Bey,<˱(R[.T+m_7tVީ.N諸:ţ@ebIxnnr7V\UU[JF#* O JÝafE 8'8I;d".oV>s4ΊdVPᎧ`Jn&W; ӘYRo5wH!C[2ų$OݖiG%dʤkޑJˣVDɩ')_[[Kt}-ߢ^jg׿ VX|'$$wd&/ 610P8ޛɖJmČI6PȲJ"`.d3$̃*Ljmtxnׇ|7[4DEٵghЍr1ud DY xQM,:>,RC$k}jDGFnűeC#:ɵ$ )J_3ٽWKUy5fN_nv$i(蓶Zڮw=kb<;zr*[L4VR Rz{ga0Ug̏,AI(6%Լ+,Ƕ x˙$n`YB||ux?HHdO7y6ZNJD9Y^1UňP[>$i!{Ʈa&w,Ygst9hݤpN2èNRI&vz6j-uVѻܨɸ$۷n|mw~KZ? L= O Aqeh~$Qʫ8 /HLIA?'|{btR+[;d^CbV)I.}UcY#g[s0c}UO/En>L2-΍fn-o?<*Gpb [ԣYޗ1%UVO3^ 7q. ;Ip, 7չ] 8i߽wisiT"ӵ6Toj0OkEjIl|FFY^co*$pχ:ſ\۰4 HbC'ta#LD^31ad}x/|/u(`v՜I¶0H@\me@7, xtOiBdoXiyY5 4*~<,R<=(B60NQQvM+A4k$kՌ*T-'%Ӎ{Kލֶml}]ޱ3c1d!h²4k22E ?N%Mⶑ"72nC-MA'+pdye.ͅ ?%u~X?N9V2% -oɕ&HMG?½ LB|AP-市:X9eBw%V5yXW|5dGDw1 =RUTo{+$*%P[Nťda8IJMw̠8nk"X05điė hu b8q`9|qC,%;BL)p6BjE;}+O>斳z;i=k:4[álݐ4X{h!0\PQS?jtQm^Ԟ0.&{ԚDq&4]>HgK$*/㏆:o' Y|c:o_qMvIq$g,ؖ5*ҘUD!x7(\#+Pqa.|oDtTCd=76IǕO2"K#:UҪ8h&,Vsw"zP%,3u!pSe80qI;~fC]h=f-/U D_&Wx.`c3i7WXd}kT]ShHq:,Ų:JeėG2ZFHѦ~ to?eI-h)|[DmZby$C&Nsj>=&i&j$oo'ïڑq[iqkRޕKLmx>e4oMB6WscUjXBNPVRVM&ۻVph5_[X#og2Vm`L\V-!tVcI  zP|?{mMKI\4g{4ْ`04pĺ˴1\)!${o5TG-5ߍ#ѮM=įx>[(-̾]d7.IJ?-Ƨk/kKp'k]~ƞ4! {cNiMrZY2V :Tm ):u06~IrMuŘӕ&xkZZJ<(;ݸk_EQ-~y〡` YѾ܍݆|9Vjf6Qy5=]Qw*LfT`C&Ef~$K8fOڮfov$>x}Ŧ9Bml@I#MWt]Q~ Dq,XèiE9@H@biM7cyŦk|*]52kY:KjmW֍Une(Ssac|XFvIXy[كZԉ=JH Q ĻD˷ʔChTn,yeaUA lC1(WuX}.xexOXGi>ե2DqrFcff:nSrtOk==l8XsG8z/v*pm=5umWe)d^`:wgGDp|+l,c>cSff}VLHP0[ݬ";040Lh*f&7.U+=3UmRURe7wo#4LeYcX2PIڤg#O'ҼWooì ӞN厲tY$_R$7s[[?쒳(mq1I(F.V򦛛i]E6NVu' {z6Qi릉;]_~ޅOmk$jzW,swl-(Q8{hݥykSԡ}ipYGȻ*34jp1bY .kyҴmzIoӵ6=X,4%U :MOӭnbsWf"nkեܒJM@N *J2W+KKֺ.MFuȆs +LAtnU`<,Z2AzQi"G|т'UIYJ fBU[>WuCjV{E AxnMN@CC&X5@EYB3@bDYD#֬$XhQH]L(0$KB7bͳYɭmҖŻuwk-2m]%3zOGEm}2FRuQW-22 r5vmB Xnd76kXI3-ű `ppJr-A HʤǤ6K)kc83z5ik-J+ORal2AoR?ckɷmhJS\o徎ƪ7VIhݫy&˪_;uЋQy-2Ce2ÅQ!ڸK0j&W ϓ~2 .]/Ts[eGd Ø7BDț|#Tc*4콣œUk }gPѳέ*H<0 A:()Ż4>g7wk]|ʌ[]uѶݽom; ֥+% 7yWlAbIh8ڪaدnL%ϖ!$dXl?y+y-Fd?XD)!X]S3g vLϺi"kV_.L A B@I\a;,X-ƔmR}z'Odti{]k+eUc3sV!ɩbDeͲCd=F:=@KuG3&$h偦A&2c<\JJTҧw~U!AUJ' 8Ld 0Xֱ7ke$C]v[)'ɒ.)]^7ZovI4WRi k|#wԱ 1 gp9l<ڠ0!#cP?v; ^I'9HYbihafU=%I$XeXs259 :78m@k-}nMl8O+_Gm{=V@AYNGR鸆Ow[dK>X6 kp>T#18Ɂ _!H~6^w\[y_n%X*@PA#,(ݛ#O |E2**68"mʙe!p{%9J1|mk}twwg^[tici˝ӕt[F+[^%VSU' v|ʅNϝPKfĭP+{AdIY opXr" ElF9Y԰\\(i!}I 3Eg1F wVe CHi!c(pKYA4JMHIϢ:;}dɖ\|V`$s皭" +kV4h$xX]*'U jm(hqzmmeijzSrꢩMIJͶ1|wٷ\J"-qY,h[aq;LnrY!xVv*4r1Ϋ̒4rI+O&ܡߍD:ݚXj־&}㼺4i^Kͱ,ofV`k[kDWH'PA" @H]Õ!޺ &/D3#+*UHdH.#AW2G9Ӄ[Q\jotwxFbe-`P@G'o2\..;)S&@6Iv` ҥ(P]Iԩ)Kݴ]]"xxu!R%VO4n楫;W߻)9]]-$lA:\p\}LL&@ߌ#`Dɻ{f5-$e[{uU/HDI/$I2ijN"7ΛG%rUJ8,Tl ?yfաk+&7#GTfI? uwվwƚk[\icRkW5$WLd2,gA^cectZ{h'cc+m-P{`kZ$ ڵ,[56w]wl,_$͎oo&ginx]IqnчĒZk%k}l~IZm ٥-Z抺Z_UwfL )m+xaumL&:u(&EMMIVQ&kcI$eY'f|J"gݼ&gqźiJynJ*ULL[ F23\,^,n2"C/ c-P`A Kyxʆcn[Nw%BQ뵟s7iwɷT;wo8TF%R7+ iQ`.ϤbxfTӥ|KjwK4L-ΖPcB:K~o&ִ3ar̾P$*p1{x^NִimQ"Vg7 F;ۆ*8.tFk|ٙJJWOEfn(Y55浧ygSo5qkV3Q$VP6o)x`hLcR2b+KDF5šCW.T6*ٝ2.A I"HuK>XF-b2!i<`)s=]wWfVMR\[t].cQxZf`XxvLkMGW* /4+F&Z׶Q+Mqy[$+.ip4NC$^dXBM+G`U%فXg焰][[a/|Ź8 K+$3m{=.i{YBjI%&މO6=n⽖}'X |}o x87tԕu8MncT=mWOgRIw"n.9]Ee $/_jl^Z˼ѬF˩iKNA ?vb2Bv؜98-QT լ[qvIk6z+MŻ}t]nڦΞ@ӼR_Qhaqmncv]lbݦqp5^M-HWQVXHe"T(lYgUp÷ _s ,7Ya̝ mwBes2;+Gw0(A `5'x>Ue^tUfq[h7>Sqcu;(Yw6֫ ϖ'L(^?R z]dZFcgHKk7g0ey*TI+:=ͦl+3]QUfޖ 7P];RzD4koiז5쓋xQG+$dL-X{ :@uAPm\Z%ե,= ĭOO[W2hzծmRK5 $7 K(yHRURjL9nY,a+їTb) TLL"ڂg8RrpNc9VJRj}zxLUkNqʢ$ J;sJ2sM⹔nw,h.֎Fx_|YPMod$F+pgk}#>T0U3]4KZFϤO MiM~ebcCu(z|J dJDI5y |I<,<*VT_y~)$zG]4¥\ZRR['g%NVe̶LDeg d\"r֊Fp]n l /3bF`6p XՋR!Vf][6RxF;&Tq+$HJiY@6.{XJ*(a"k62[*;nwHXlN/5o֊uukY|J崘_:[WHf>q2[{WxYP0B2ܓs:23[ZpbUFcE1 J*GQ m2uhU I<D䜂O=xMrM%)r;+﷒o6YUju,mKVmHu f,)UՔ4̑*G 3HWgrV64"{6g˫mا,\ò5q: v-5I,(RQKX|YA* VnFtvy9lK&KU? dS{Kn{|1Uh]B1z'8j\[/f2Z^nc8N\!(B"11,p M/M|R6o.EK`dWjY6Z3G#U brWb!Gm2!aFtJ7 A# n"|)"HQ`w JRJɫY=ٷg}79Vqn 5dVJu+cI' "CyADXs Dl,#"^%Ʒ ]~;HvdIQ|ɶVIhZ߫طZUd(WVm;Ts.,Y 3 [ӢR:3n6sg{R$n.&Uȇ@g2tV%l,fBn\BF^ ʢŒ Lx5R F;sŢ BK`D{՛]Z52IWW{֛;i2ԙEͶi;cqrQEsm=ī,Ot!Uf0}0:ss<^'m6"r>k啒ƞD$|mPfsq㷬#MTk;kC&d?*?(s #\\G#E]5 *Hݨƥ#hcY48 (Jo'ybzok35ė7Wr}[9춰 R8FhߺOH7#ƛ%cQr7Z_[{kpRVD[_K[kmlagyJo Tɀ7dIJNP%®Sm#~]nJwi#,+m(Y^[v!*";A\DLrY0֛tsI$VVvDGU#ѵgQ]2dN trbݾkY'&ݭ6VN7koionjMO_SˎI!EԘ$W.JlOѿꗸXAsJ!Cm_DI7IFiӲ+[mno)C0'X $!nʬDi,fimdhX MKb,#;ڿK\+̝R3$mq~Uwzԭa y!]Msqchϗ|0ܲmÌ4ڽZjegMZ_ٳ{>-ڌkoYdI"H`wDrKkpWİb+_!iqmunQL;H)qo&TJ x`<+IxV;LG|ܣHlDd2^XZKeGd?|;pNc.[rw3e3333J,q$&ZtWZ*uzU\.W7Q*1XWW6(ԮH#q2H]x¾&4|Go8tlO"92xc#LPA_Z oZi"'@lvF 1H#8xCuik; ڷZ6cmP"mV*tY˙>nVz6һVwShӔ)+r7{%m;][[Yeܭrsr1g" ŶIM[{aVMyth{{vyZB {|yW"|ѧ"Y%D,UkI wI|G#EXlL 6wb #DDIXnʜIss^"Zy$S2[5f{4I7S4߅]CCcyXٶFsx+U:!>Vx6s὾qFI0v0 K(3>BeW;F\%HP# oXa:DxPgsb|W"g/wW\˙]'f.륞s/*M6VV^m=KiRÿ R6z%T IMŬN 6t]8~@ ~4]H iU5ۋg7-MA0D#FdNJ; ~Xl&/LvbE "Uw,d$*I@|bq_8<ʂ3"hH\L yCߞkoGk)C[knҳh+jŮUj֮~w;j Z<5Da12Os# Č{ǗuH@ϹDoAɒo..0]E,XN Vd-r>fJG12mHncÂd[kmrh*5^.QlQ mIr9l33t BSk]$ݝRm5+u/7kσ:GǐIc~mš崒Hf,F>\IAo26 ,וWI$[T}By9ёbѷ `x_1v ݴj730#WϋT$gk6.K0B3/{wM:vton=wl\/`)C f&U7/$!J\1' 9[t[ElDy!1ԣ/]ImOz8Ma<Ј|ڊCMadN*SIrƣVj1m=wzzrJPoRiNp+rYk;9/[q3G?=yB<\-PD^cUbFm}+Jլւ+'/PЭ5?c1]2*-!%"dy<7G/%"z,v2!YO 8Q.$?5MFX'"/? +m D˼\j .3+oKWQܮngw>$BMFȰ,̧ff륮KbLMZ۔>T&g[/;I.Z5wNJJE 9jO@&t/ot"-hd[ku=bmh{ kƭ67x"/\Z,qonBZN$w(Yi*t%]BkvYb+x Hݾ+i"'VdW{s$r^I+-X_$tp=9bゔ[qjiN-_MO֨sδnNUpSR~]*iE]$^1kwu륷<ȷ&Wt 4Q}z]{)#V-k-Ha]gMFr6[_|N 8i> Sc6U$* ɽ1$|7.+*JOI'kpV+%˳QGJ֜^FvvwkI$tDLFb%[2`pqP:t7c> 4B:VmpjuN]R% F΂ Hcf?h:Cm,\JFHS5e T%Ǣh"tWuP2Fc&..cb5,/` F?iIө d8Y*I/u4ޒk 8ݜWVmWEf}S :Mׅ{VQ񥮭qVOjΥgky %Z]AƆjSiack3+߭6ok++K}rLqg.s\F{-T @#_8 >cfE_-0$';xLٚH.?1VBm$eUfF:?̡U7,Qz5)I\VnnSJE95[F)^b*X:uJ˫JIkPjZ]2MKKʿ:k` Yd8e"U,Kƛ]NXr\ZK%DB-R,nXugGf1 G@ا ae'.iYk+}ld-4%]rVOF}JIT[]* nvң} i3VjF#md"@@Fbѵ,T dc|shm0.BuޗjVD]«S@;́O۫㿇cs<~zjFi "adHiK}'$k->~2tQO4Q2IMkVִRt䖑JR|NҲkK.xVwEsARl:V"@X(i!@i!]M`zk/#[+4b{%#XJB veeT LEpOH˹&a5ߖY uI];;Ǒi^)_u7u{˻vQT:& bp=!NmFt7ZaR7kJ @QRm|.b" iXڶ 1rH8~/;Q>]yA?0Rp1d`,#|E4(>箺][k*.tw]tM쬭5sudij4ꄲJAPvep*[v:RoRFYSɔMVg3-,WBb^e ʴא.X)s=ԏ!,v,̳ml|\0SfۼMhi-noU}ΗmI-FNH\ X%p" |\n7FWפn\ "! gVF%BZ;}jV`Ro)@!H^+hЖuHwIB)  #\MC{vv/(yjvXe;&讝A'귳M\.۽oZWEo;B 6e2ܹ0\rveB3z[yREp*lG'r.0#ָe`ZDp1bʂɵ&-J i]XiIS* $ ܳiV(8j<;rmiWի՚LVԤ$ZJKJN뢶^O5 =; ī*m$ɵp%cJ#n-|۲W $%֣Ȥ  o87#hH%v5>cgzɴMK!!BolːM{E[vĻ-me-.G-GGggkG>HhVDiq fJE?:6!qX[Ha% ϙboMiUm F$"2+j,Y7) !S)ݸ _m3L/#G$vh݉Y#X W"4bz"┡)%5kk2NţcLjUQT"ۓ勴T{Z=YՏj"5t F*s*(IXZY>P`7msN|AX<,Z% iQYD#Ɓ%l b wc2`2ILFR@걳Lm' j3JГo+85dS 9׊K{+Z$ۍī12C%׵a1?K(, e2va2 q4CԘ˻6ZݳHO Y S]n cW5ȏ.Σ"by :^{/OZXlC '5]\xnTio<{fV2mVV rfxs%ĪL=]>gjQVjT_|W7'G6\Jm,6 ]֎W&#ⶦm.&Ќ7CZJ" x\*wU`uvq]Ұ,BgAh;}f7Bms7.d-0NȬbCkKO]} Ɍ C׽JigiNk&}W)r^&KrVMRogexl ;nCgi#$l1񣍘0mowUh1:Bo X|ĪU i1DO K,*)*IT+j-YaX3ZFDI 2"`bV$8bpWYs8KOZ>imJ!5&4oOY;&ߥy`'~|1Y hr=O>.fb#Y,`9t% ~\Vֿ}!@W]r\ba\0B# x^1q9_Fc\IcS&쯬ZwVM-{:^{h +oKFz] ̷Yk @]GIJr!sP%.oR'C{^!T'c+U5 :Jn"_0gjҹ$ILbw(@!Hn3L+=&ݝIH;)ʾIP0'ދOj{V䎭[$vE%\&$Et>PV -ZVcz:ȹH"X+ lUl.X('>yxA)N Ӱm(/c 3k]wMQ $AIW`nd! w2k+wv}H'nCWv9]>Ye$f4K:ͧ[ {6bE[ѠUZ4%ma*1^2k-GO $W[ *dYchV% XpQbjWњI*/&l?2"OCHv#gÐ[>T,V^Knݯb II^n.XRew5+^nh(\u bq; LRnRv 3w 66?2X"p.43X\ а`$t8DS7\# m1ܤEmKJ0f>&i ]qbOn,@NdhcQJmQ`78I+nTrJ]]i%c\\%QJMM'f#.SRdVId*hPwx_%(Ḽg2ppb[D"09+7$MHմ{SI4Iwqux9-B%A;gw(4z&XԾ}\Q "H$!@'(u3EԎz[]Z>Ƽ[.Χ*UT,lJNpRq/,\&h,K%a2HQ5!e]Í%Yd_Gx?C>ѧ GF#l^ZOΤE: `H%4)8tT xѝ8&d_*UEV2AGruc-f5kXZCI"Amt69sMz5%N}e+$m,'vկoX(ӡ%)\U/tmY5bxNiX 4BF@#dFv UW|mjm&9B1cs3&JHb6T ϭmZ[{BK6Ē>$CU;K"@vanmI{ٌV #I!SSoaM+to-oukZTc 12,ڄ*E Ż~D? !d8wdW1 AXM2mGV3iIqIaYgBBu-`m[!Sc$i%係|#+]rC5ci.),;G(f*,$Bd]n&B2E(J7\"K>֏Uwgb(œh Q'wz2|E4x3W}2ULoFѵՀ#Cky-Kva4)h3YZRƘWc[BeLpZ8fk&D`;]~U}Z,ThѣfGX`)l&M]={6*)+ۚϖ.qwVqVrVGk6keonq8,De6yJ_p]ܶHV.E`-B%u)- ,82>wX2elBpCa 1u*Tz,n]mtwvtݻr٭4[7ס͍s9 3? &e%*"e@x@3N$;Bd$pn^=9oiƧΖpo{ S ^3"@', tl-@e'1-e~H@̌[q%ՇxA5Ce"h@ep"mV\.HGbIJ7MWݚ3i{]ujMkz_U{]3ӢK$q ^]Y‰d{<0" Un]nZ[;TwWKy;=DL\«|=RE.Aފ΍0*u|Lq62#D,U̬,d *@̄ЙΖZ8w"l]D4%HPKX Υi[׾ ጩU q`Cp)hVrY]^;hZ_Kkov+oգwۙp{& m" rwt[~0Hg庞ɭT圶[;nedOA&B9 (䀠$` kZ= F߸-Z& 3'ӖIu;;%w-oKڕ4odz75FwOq,u;[vef|W3WW%;"} M5c/ wj0lg2c, K-Y܉VH1O}VXy,V<؟Gt,Z0o;7޲l%nƒ J܊EfPZ]~Ї?hӡX4ybYnTHoB` ki kVQ|edDq(Z1\7jd2"r# ق+H'f`ܠW6)$U**;ߵZ&ݮӣ]ݜg7=.Mwalo+ϓn WZs_iCp<6$uXp͓q l-Dv{ p$QFS\26Q;z >Bq0m-,zݯӲctKtnK\' Vv6\Fdw5$r4řW0@dhGf}vݽXofc|Udd$% StceS` ;ŬlWL?ot%"S?{ʗ< ֟M7v͹KK뮍ۭwImE}OMkf_Gn\o j yFI r%iI ºo\I̒{,D/S-hM c>arZD]ɅY-i$*2FG*r,)<5)FW]#P.K߫8vX)TXR3`\0].2kZ={jսi7~|6 oV+LE~e/kn}ϒ#%&Ef_ 7'X~+_!Led/ˌdWx~@ hÑՄ@K#FUTnA0ّX_, 2IL Wi/ >Y{N n^Mhɕz[?_{ڝrGI@9ucʹeK׺|Zƒ6 ,ܪ(ʰTfc+ŘOTv PF_ibQU_OOC`hW&K|QBeKye1Ʊ1BT$ݚ[G˪VkԸދZ=f3s/⴦RCf#s:&t]6b%v(8HPb|nEzVڇݠI{im}WPY/n56"w5s1"OkrZ6/_Uyy$Y4>Pd!`ǑIP?fpXT\`܂Vv þYn:rJ[il&kV׻d{ԳqҳƂWKTsq@(x?$bhhu4)&$FYdT +q43Z/:$*|hk'jz,啼i0Flm:IuXOӯѴߝd'_+#*j-qX뎠$E؅2'OCщ##Xa"#[Be(AuxOѴsVN%j7l qgoaiGq$KyҤZ'4e浫kQMoyg3.Zu6h3O57[^Lo#][$ 3Vª74ڒMQN2㭚\4ڬ S4#G*tFPV悩Z5}r)K;}!Ee!yt(O*8ʛVFf0R?궖ZOu.'6P- t~ :$yl&[u QBUo@ѵ kۛ/VzwVVV`ְQAj is%ڂNΰKUۈ|1&i%_ۺĹC~ ~\, !YeCl<ɡ[J'c%T*;2^M^YY87s) i8qo'8(NWu;D7+ryM.o?_Ŵ1&h.nc|\xIפ|HUfefջ{ϷFS$v2FffxYMN3$ܥڝi_KٚOqEy,wmq;F>ucrתz;hƩ ifۑu܋_ПWm"g~ -MZ;d)!Zt@_";Ǘ Kݺ9)%kߚN)&ZkV!j/+ԎSzŦތ}i[Fuysv~њOcb3Iſ^Yq9os'6N{@мG㛍N;R io%. HlY"ැ\/lWߌ>ĐxwP&[m4K=w?N&kynDcKwxD3O#[[xڏC,Zf<зH ʗN\(8ǒ/ iSmI]oe$ԮwɸMN:rNvk&/&ʈ/y΁R7eVe.Z3mm>3ŚBIѵ O<ĪXfYJH_WҚSYq36=H_aE{ Q DvUO"#*FE˟n5z [г#66,D(++K!R")79+;ݴTOV~)oqjI;wʬ^5(-xOÑ>"{ ϡZJPMBRSajI񴷿,+7Z.}c);hA1rXjeR}h-啮 \^6!+٣d.x ,rj:-7Iɴ-牯" 2C-K4ee&TI6cGg!٥RXgyEHo68ۘ%-qi 5-ZY$Bm7k& xЧʩ0y1Z-I{R[p-򦵽=bMt_wݯo_DT@g*,Nq+h: bO1#deW6)4];ysea-=D`ul'"lYNn7x:92N?>ؙdFHEbcͲ庢;EFծ;t##@ d ϒzWn#P5V-˕$۳䓋7wvnDl՜*VVTz3Xuzۃ!DܥNқTx";"V|N,KOt[_*^C5Qt WԉB3"S x-͍32zrS4ʫ9F)v<61\ZQȶsMojv$lK`+JQm\j#U @$ܪ]+ ᆃk23J.ZRRpN9DDLΧ$~TRD5D^,rܲHU!#7nz=Bn>ZΩarv)m>UR"k]Je?&wjJ\$7U8xd- *!0I!Y ޞvz&ZwȩUfvV[+%m:juft'ɨ-T;WNMe 3fk)P,2k|VeKPLIvYkpF1y{x4˕M;l.k#i~(/Rͧu&Q>u{LOٴف&$J$_<^Fij)uI|3e2 Dq$HC+]ʶ{%ĞJ%sK?ėv7dGU5nn,Ο\|R3}PgmI =խGo^24^' /m#>0k5xM&}CNF4ۻ&ߧ6qpřV&J8a;)Rr(tӒ\tjRc)T:^ҥZeuB=&J׃z4*?agy-.l"d5?'hMn@ӫs$NR?g 4xsLцk8O<=y6isKaY!\,`"Fߥ_3|weKO_%/'PYӇ\I|aw^yk h5Vx; m 橹{xNPLʳL63.5QJhTOP'̓3I]*= jrm55>XAnJm9$I۶_{ۋO&Cj yaIabaljχ^&*7\j"o _707?""|Utۛv-'UID"'_Xh}▓eag 6Zo-:Y[CIIjYoB*.&r"yyHЮ vBڱ6 ṃk=u1RvMߕ&ߚѣ=);8N'wC/fu=/93&!OĆ@thR#%~Ggs%+8ݷgJZuvdjzM.O3s o C uuU%y4 LckV2=>U*,@ ]>\t[]q;Ȉm0B7g1M# 0K ]ۘ4V62>3rBrSW{_G|RqmSi[m+ew"?.ǖ‚dY$edM0IbM P92 |硙|E' aK N>U0-p㜚WNpT6*pT|Y32߻NNZ[n-oOWR8'W*ZIJ:Xm/ICFNu67H ѓ~FE;B~+|'l:)W Xn:I8w)#n1$3H781X@ާ pp1 Zjs%Z7jJڻuͿ}lT]z\2̆yX||( U9m%$lA1':dʹ$d͕nF~v!uQUcw67Rf w. @)eF*8j['-ugk./߮.gʂpefWtm g<]B|dUb2T`w7zkK,B"2y,"3űB Jr[U%a$>c$L/$T+gח[M Ve}ݙWQgc$Pr, 1WV5$~i *]B8P#e#"[2=³ ߟ0ÞXV"{DdD$8iQ3n7U(0H.: 90dˉ;o֕fv@,̫֬4vg2P`o-9)wJk+yt-tu̞rum.OMمQmR9JWIN|'x1[< F*|(Et|TU2,!6*1 fiU3Y'y 4so"S)$p $(B(bQؔ FKBIZVVGm_MoUW>T+Ҳ[[wtKZgF8$q,<싸ǦM`65UXKnЬΰдFĈe{ycs3wvC>c\dIac!' HNX3vbHn!kdUUP^Z]KO.X9\6*22FE`c|l2CƱlmrvG}2rAbػoe6 <*T  $-4[k{fTԄW*|ּ!{s;;V[#}Vx*J6Gsc) <0 ͌WvTnl4wxcbҐBt_pg˜\  !Qm+dx&E: `ӽ Ēnhݬ/Bݰ)nfUsUyTxݒIwgfr)4>ZCdPqVմfPQ6" K!7S)eJ. UX=7RIibMέte~yt`AM H8i@KslEEQv*c(sEnZMlexTDg5!HyMgW=V=ٸg;+[%mdw8YJnRQc-ꚋiUIZw6#VPAg<%$ɚ2y7coev$▞R@躞o}OhC)rDD,"%$FRVkVI[n~^f'G1M69vql+yXeӤk} LGg,0JeeTLбº3 vo=DE$C$HLsI* c&$Ռ`>s\NPM$LU/W=3f20bY빙GKn O2=ctvbM%< _42:z&ފ1Wzmk5pJmg~i]4XwRഥ3yѡDD.%2)0-EkRf&FY\4m!ap}۹Jb#4]XK5gnfUpZ|2ɵ#$ A UZ׽ݾ.ukjɒץM:tg&5>t(BD+Ryk'K+(|:G#ˉ4*҅X]7 kvy8%vvACo)M-u݃}w;647 /!iNK^U`&0I$#qe1[¶N,$%Xqq,Q w)t5EH ZɔUyHZ+YX5e O$vYCJo D97qِ Bkξ'mb̔l^{rߑn;|JZ]Y&M<ZXeMͩgs7 ؤʩTf10p[Z4.ehp Vл 3eW!+ APuMFKnYQ\6df78`:蟼׻i>MNP6EթәP%V}GʍpؖL5O);0-8ۼ(5m .ṕ>V6I@;4$BId7+FQ,S_9J~g&:gAVLpKorPbԣR SM6[+OM}{3>kg-!3*VoT]WYO"J-Ԍj Mc)*nv?:۪EٝZP`,Uu\+8 i*H,=%ޟ㖲I"7:.Y<uƟˤG#qW G "fPү=[{DywlVUy[`JmndĎWy^^y@L3:4* a+Zb`Bvc4Bd-CC_)+3NܳVj7ӛT^+|-jGowJ[hz~2Q,r[I[_Z"38u>y[kT`N6w>ܬ~77ْOj%R`xS[ҺWOG5ۮjjTZiu]v;Hr M9N c V@VجPNgy_*3X T?um0F$U䜆.xM3IRgE#*L0σ&Ur e|6aӼBCseVv.N@Rw]$omݒvcE6;tWOV~=L6wnEa浶P<Y?*3P WuubVPIG2j8>sǏpiDg KE;VanRdS(ru%ڀKN`tv#(c>̠_i]bXӵz^fH4kҷk^.ֿ?ƿD;u 3 eG徟kEnnwv4%PoƥaſK_ށM蚃j&3VbѵIm|<i/i)>SĐk5*xm5 2+imjO𕅆̚h|3{r=Z C]Ү톧qh7>4/X Dv6ߵYo/t.e$OQHjs&^oژ-4~&#5b!Z*{:Xz59TeK Vpj2;ԃC0wR*z85֞ խB Rr)6҄µEÖχ^ ~G'Ľ.QC&~ğhŮyMsh>"մg}ܓJasȞK_XTSuöPiG#ѧx&]CQ$jS\ [{>k]1>h~(ZSt]IuGŗl^"4֑^x*{5,4M 5h]BmRYu)|N'CKx_GBg^"::߈5]O/5KfEIF,ѭb-IEP<gwZ 8V&SI(ETphAJqO!PlKxN4+U!C1gjtU9ҭdt@fZƓmCLt|AeX kq{:~to.+ZKWiݭ_^xS_}'DI$ZZO5heߎ5x﯅Σw.0kOwG"E4]>S6޳qƍmRk'Eռ@>!jjJ&1|E{eo cJ5 7Gѥo=b&Ԥ׆[2H7=Ś([y$<2ƿ 81ckԯF&?jd㈅J45Qrsya03 #˲|5*xFShB&8u+SJ:5d5ı_OX ~(>aZ.[GE,m[Kt8dżz槯`6yg<$pcaqm58g[ވncѯR+mXKw`5u$!4nh J4tn:'lg$o#v/Lͩ~Jmo ln/m";6u"U12+83JࢡiEN{Ӎ88ьR*I)1SrSٽ0vzG[.+V)FBTIV3j~#]Vsla̲u廽PaUX&V#2?۪F涄-9\ܤmi&Tܛs眹Z%n3nZ݆҅ 5,ͦN}SWs-^@n帞[j-/bOᕽ o{~m#ZPVҼj^'fkyĒI? jU~^\ cfQf!+4R–O{ek[yg[˹nRVA0k[Gi.f>\4 ZO,.uA>{ϨOsa[Z8 U*εB* IУ9u)JU"۔PzB\a 9)FjB;^_ w mY;Mρ-]~ŗz5_hQZt>tY}c7 c5| }&("# +˭*ךO|kZi2ku?uOHf%Ρ=/9rº]+QMXu+ ;R!m&Y(4kx/kvHtI$n#H!Ik't ۰ax5 \^;aq$ -øO:REQ),DM]SQzQe(էi+j+8Wvӿ}ywUaԎcw:yFjB?e2-|󐴗0[R ۰_ˤ[~!]MhGNYlnf޴d>X0dL4Z}Ŭ)%9Xt+5am-|)5KY6GݞՅ:uU>-5-WJմdH8-u?Sd̗qI--֘R9t{h,/r#npu!Q{5{H9-y+]f(.TOM%i6OkY^Xj ,-7S/tբSѵ eh[y;hۋi)_Dlvi(j2-{{kVIi5>Dw-omskodv3M?~iVޡ ·{T[$/,納h A;GJHӥԼ=.Z_i@oy$HK{{}8")wmdR֚b}uob.FP-v q%W^`#e^2TJ;6UڋsVMۻZս^'tR}I%]24VZ}(!Kky%1[$i-m[BاV1'|,6<%#b1MC)Ǜ/)J1QRdJZ^H裆UQ#z|sFsTgV3vVj.<'h݇Rh͕ۋx\lnXH֑}3x>|+E;Gu4٦ͽ' [.>FhM[yLH_G+kO5ekx~fy%HRH=2L $smYA Y#IS+ ^BG.u,!R5/B#S*j񒓌[Ms|Oߺi1IZɻs\[\RjVѧkZY6.5k+KKM5!M A$6pڨYO2IfJQkYุxY m4iY)ef1Rɶs_jZ47ⷻ(byb1Bd|)c "Fj:lwD0Xa88"ŏ6'L$*m'XkrW"I^z$IZTZ>ѷIW^iq4p&d2C2#%@B`6xi.)c)mdYX>Z9 ?5X2(馺//$h&HPuw\I4.t(ũG x$r#4#RHUF-Y(ɸە6du\m4{j%6m5J)3bI.}шe[F: LԮ-i+5z}d3xePHx#沗Seh (eg3/"ɢRn".\=]Fz<3-< &@#tdS h͈D8MRIJh- guƓcI]7/]J^r#|hQNܻnFBIc1ca6ͤ|@} 6Mf0@"+8WLFʑSºRF\8 \hI>/'>kڽ8[͵='JKc[{p0!+&їkqwJ,X6eM7N)[U+Si*iI?Up\Rc{+٦ivy,tVTFWӴ N%a 7IuE4j,`N[iC?N~6}VufM1Iͭt2]ILfJ@3階6|{> *-rޫo-'OtM[M%jq^[C)$6Q1dždtĹm=\eu|de}<^>xh$'*1o+a!V>YҼۨӍvmז Tduk:;Ii5ݫ /|E>ǷdI5? jYGZՍ~o"P2ŗpZ4aeq~OwC5ވ4[ާ2^DYf/g:!ŰYa'PwfRmySUk*/tԊNmdw;o"55]7X_/<|FV=w^Z=e6w&\Xu A/úM5 !Ki2:^ҭkBSW*P#Ǧx֕JձUN4*PnQTr7QsjҒ擓ڟ0xz_5O]+_Q-5Z]rPBf$QYөL2I^Kg[xa C#Ue`]a4xx[zkuJ^˥]V%hM] 6Z{qm  \E,sHn2 01cc+0Ч8SSii(4/uIKD4:sxB\'g 7wqnVZn'ƺZoHsY%DyW RB&wWVaMCzbK37z:UH[0 1)قj>gQC6 mh%V)z;\/UܙiDe\} ]i#UȏM_"t>[dE4rI+;+?w^;ݶsImkmv+N[,wGTPo[``N2O޹km8.cRu*Pnv ]UkS]%:V [D%ڶAS̼a0$NӅIChq*"3., %'-H֚6S{_UvO[_[vۢU`dM{kH`)6s+ȪnO (`o#n4PSk}SGf.lpxொ'kX.\# >^Y E2rN9.g1vjWqޮ`ﳊoʚ)"qKC' H%F1Ce#7rV RtIǒJH @<# Lm$%\H`vJg;Sn?ʢ&8oW$,q#'$3-.mKu-tow]?ZW'qU`+S b Q\iw2":I j! ʕ]2[3~!Hܿ9s ۽im+hr+(b,W8;nKyj:ir5+ -%WʘыƢ@ye T=P6TyMLT@tZ\c"2RɔUpv<*m<֘Dw.B= "_gvI rzoz嶩7~[+鮶]9=!gvߩj*N#,Mq!^AdUc}ۉuZW,Q~lHb lqO)z&*/5au]w9ٌ>>bgOMt49}҈cl>TLa0HKX^Z*kwK]kbvs]yavv9eoJVC"Ad27xP\ y5w24B!: eH&2|IJʷG3{^چYIlFUEvyjofR|֮(B2VCrD@x V-o~Kl;I+o-:+yokFyȳIu%RUYKd( 7l\[܏gW{K#y)I] E/I$Ʌ' amj9KXX|88 7֯g Lxv c-I ˖ Oyn>M~+N;_mura`$T! Żۿx =[WR(eė؄E$ OXŀ,G2\*t1I!۰ "+!S+$fk|8m̥ V;-H,FXWuBEjVG~-u}t]];Y .mflj`i*UPe%J 5aDӬ.V+澂H }8Rv\ZrA_-c]d-($biO؋ {Kskr2,gyFI$xY{geecd2^@\ kUV.Wpj+q#++"5iB0*@8;#eʱ̫RɖTS$J*cח_OW찜Hs`US+4仃TJMn!%#ڳ2,<3I"Vc.].HmvK}z+|UxSi5-6ʞpYD~dd$EucZ=Kn,G%PUJ#L{ҭ.)-$ffD;vإ7v1`<!~ hEDn'_?usIv(,K.F&$nVm_uw[zxhT<+({hwngLw|*'e(hgH~_0]H?z@+OT[/ڪZ Y79fnE{'.AU'䚕TkZI=etI'wmnqq77#Ⱦm]5wީ4&֖n]*x{\٬Ky+yͲD3,1]lc2'; iYdYfy7IxUfX"q:]J(eox:_#VPX]?RrG8z3evV2#sd7 n;aPhۃzp}O'9'xCYUw{$ d/׽Iŧ%ձendΞ=4qGrm%;!`H@26m_]͊BWȕ?tni2D6Iы&G'OY捦v%ޤ>6!(@Y)JB0Ao0iKH]\nF퓼nb}-{{ܯ+i~j Av}Þ=?`Ԣ8t[FT1niG ϹdgU;W tw'v^é9ÃEj-^FED/d819鍧%NmN/_eX]~6+i#HnDk0@q)G#?LNAuIݭj?w:sl&PČ@(V@RmbF9u=>/p@4kWjw{v ƒ+#j7n6K 2N q ϖ7;_fI8ƈf2v 2M^\Fw%I2b :2w3#ВzG'#e|$l.H'ȉc2JO*sV+ٮAYif$זJm-n}CͭIAfEX=rG^3&fs2ᐲiTvE)cVFfO#|ѡ2298_*9%YL;3kѣ VheFcO4HT~zmnMuy7+Tu%}U$U7 Y c1]dž]LJ"ԞBTl3$jՊLב " mHֵv$꧝bV`XBp0]:E7MXVp!EUY2`*DK!ngv=e系D_Z74J[hYXGp}#!PDބTje fٝ[Wȕl P۲rA譆cbMԳJ^KF`Ud;E2;2Dy)7iJ 7><YNiGB0KI;o~Fֻl['kI[C3y'b>P̎xj6 ,N2M'v˾o0D,ڸdxlj]FSۻdBxă;+2n;߈q'4r|(cc?:P@,#4ք(_ut[avKKtGO~;f !ʳ#S Iu.:^ٕvdDŽt$ pH, {/;l̽["+hR⑇ʧtaSk=X]zjHnDQ֗8F 0DYUݯe׵H-S+,vԘirGim$n1[W{|7&WGtiw_lž2/fJ:J%p+F9g1,/"O=?យkyom{oq|) smEԴF¶ H+UgxgZh#(d{xE YO(VQ g?0mjz=? ,n^Hc]$$SHwn=e~|﫶YظYq5jӣ 4BNHSULqM'9J13z5usx M玌iʣ~Rv,&c)SRRb|@3+ lu|iHb(uIX&1p%#,xVևxzUڑhw3V-+P9CxA|R.8Ծ FIe庱pOnۣf:` igQ>[Kv|9閚Sk 2[Yꗐu i7mfH?Ֆ2<@m %"d!Dދ*Fd7>BQLq]8i ;Ʈ$8*R~wܣtMf6+]G,8!3J5T#<.qRjӫĵ)Ӕ+B3 r`Fjs |q1/?'ӼFlĥ* y ۼ s呃UJT`<6hm\k+h.{)c-:Ũ=+3,9Χ3FgKo3YAHU$0|'`Խ'ZPcuUb)9J '%~Y*\e,mL~AkV:ObzKJqQcx x]>$.nqmywmeyZ]yWkެZi'b.Kh<'csS]u>%Km÷EֺZ[پu&+]Asu*;OK}oSu/ qe}3*2a659c[v5l%uKŷpk73 }0XΨW詑S%Lʄ(>SJOjZRwQQsi{ߙӭJrT*FZn/'F]ݫd|87cU#֥ff?1-:!ʀH';oGjX5EH_ՠ9 #ñdʁkY)G0(Ӗd ?~-IQMNSv:#S gaVZ}ErKi8ɥhw\xKrt.ZwW2g%l,.5 h.K) /~oUŕdž~^5ך'm*VgӮ5­fmbwtW30Ub&تP|;+?fJ3 SjU:/ڵHK(]5Y&:SvJ)%vc7oyXSMK֫Z 6{K]OPI H/'S;WOY>z5%'+Z:;igZi.oⅸKgK9aI-gopF+&"6u9K벴EKx]K̻QfIԣ9y?eM5f&Hw;Gwj~mmKK𭱍4 GukRf Xo]6vf 6 ўl+o+}nO҂] v_yZ[x3x2< I5"$=\5PRkx)׼Bh] tv1 N6 eS0fO [)4xȗ,\f=iaF^5vZFۺZYCKkfoxȵQo׺/#'i m kfShw}cM ϤE}O60SNN{^dP %4$$:c8]=7͋T-ϚCw ռDl:洎H jT#5rʬd  [(M^a'UMQYHͶ&sa4ݨ_OFV~=vxVlzRxZK@׷ZM6X\C&;Lw.^%ƝϚ MIҷh[FxK!c$s1Ӽ'*mf.{ZR#I Y^ }u_^ 0i>#[ Bݯ5;OrI Y7#Zܽ#G+₄IN"%Ƭ% 1b0'_(OX/ܤu .! 0<Mհiw5kS|ҍ敟4TTaӆ;]rMՒ˿ kqjrAj6tD_-MĶɦalζ^v7mL2%R6Ro`HF.I\yLB5UdB򧔲ŏw/W֐+mO#G}ybeM o+77/I?D-9S]5:4ޞ]qIPquPN6WwoXW5j#IRqH*pq%8N_e;s-rgYxr:6Z,WVZu|yn略X3YZh|wV XciIKl׷-Y #OK4{x8绖oh2[Y">Vi acl7?~&5q|K-,?dOx+[9-ŸW;e 8J#"p$M\;njRҲ|fmJ\p#l}Kɞx8TڊVw$oQA]5.[TrJdܯSv`$~3[iitֿɾhgMxqNRah_Zd7CooijZEOigԧқ㻇:3_ \PRgV>+x^&$2Z Ukclx"e>(|IG#G$@HduTôQ zYaԝJdQ*fi6WWNMWM;>Լ{k]B/xKMuӴ/6w:ew˓J1ǿ;Z隥3>,60ϡ'.SbUݵs[Gkq5sɒ1ğX$Ɩv gr?!dfuܥк^"YdJ#td($ $Fu C\s4xKaxM$ַmssIfbR*Ҳ6J|%gh)Y>,4v k+ dkpR$}4`V90"5wU$ ~(McZȟ_?>)\lj1/ŕm2U{ b %_^,lSƛ#x/[iH>({xm Vm6v/=Ӽ؏&?/>9B_ jYB$o-;[#DYiK.U189IWuNJsZErUSM;mt%h>/6 -<OgPK&'[I7 80ک.~;5xS'oZkO KqizbkQ\]%2 ;G$ ~75^yu4:lZZFmlڳ6)KH$h9\bֹTdMJO^NqOlj4xSmpHnMO}CcN *}J$O.%2ȴ &d*#S$rrci=j +4Ʈ?chwQԠ 1m iKK+[F-u6-w/rsm[.e}:&~O/= weχltoi8^<[/If%RPkWЬ=1UaY(o2U <K-6|#*b,٘jsnT;dIHyP YnyJRp ө 8,ٶ%$rVB+{|Brj YrI+ݭotQJ==_ c|;x+>)oq0[ jbPdP)fLT \#ǻJ`ZtfXSu}HB7[PEU[ o+[Cg{kVTWRM-M<3\-.dAgU^E6Y-H,dF{cڭriح37ҌNn3cv\҇4s4t6KϜ98(iy%%u(HDVC|Y{rtIJ \X9 {Y,ѴB )[W[ImL~8:Ɛxv'pV$F0I\NJtW7vlI%4m=Y/fXZYMC;Sz)\[h;;ԓT_kcPM@ iX̐Ik+4lxKj/nfݾ_;^ZJKm^ݓzydRG4{[n,̧.FŔC i<̄+)䑘m˵uŕ!I%V!&gb-B#Hlk*`;ھ\i".DHse/tOMo %8ˣWniYz_m>qnh' CUF%*W(0܆絜yZZEyL$,K&c!@@KCFK²[ᢙ5G܃Q#,DUy * Ѳ27]LV _ur7׶idQk]uW^ZO_X/ SFٻytE(62hݢUMPB)rI!`FM҈=uf#lJFF\aMGYAPG$p0=JtI+mҿ{-m孯筺z^K)ru[W|e`߽LFVrc`>k#Hf]FȄ @! 6+2qʠ21i*ǦD>DJ$JY],Bclgy\ nlGAٺFv-}7lEtW}@M]ۻj"6]%G{2D8Y|/i#s2)Wf*I6֭e? Q [Gї1+h/͒6g PP|knl㍿訛CP\.w?P[jֺԵ%k^*DooVr:ч=aB29'p0TQ!+DZa$8Rn5$𐥍&$+-p^Mw3`9n+GŨmb,(mk8IJr!}ZK_}-n/nzi}$iֆJޒ@eVRnp ÌI cؔs [&ݠf##vܪ$dhc̽t>ICTXv m<ۍz[C0F^rccbX j&0vlaYX'%M[]_Wm-4M;+k]-G!H>0p2dq<?ݙ RXdof66L6*U$9pwtQY\E"f@D$JAu`tg؋FRc`^Xݸed%0jk%}u{^:4M+nJ5]u}M)ROC,rSWpѴ{ o2yC) `Ilڛg>Y/$()$q#r\*f$!B-TeA֦ptU|r 0V7ˢNI7ʉFîc| mI7{u+k~Vվ՗Nkپiեnv: `(#9!6$LSHe >!:X`{>0-\ġhn#ᰏ3;qi"hl@Y"2D^! u8yI7Jc{DT#8rmT'پ~Խm.},?+;I%̟3X&RU4,KλN p |*H8 kla4M6١wshf%F45}UCmJ2[eV X0S|:>'ӥQeD6MoyT*QNKG̒Mko'+4ˢ-u)e.]ZN뵌iV##%Υx4wF, {v IV&e%к8RYnEgiL"u )$3nB$fA.XVýbOcw q ݊ "qW D#. (";AFz-ZMZ򾏔[AWԄ)?2|QȵI5>uo{/MdC/ uas$Q˵IaD8\/.9hHdP֍qNM?urvS HmVWV_6'[=ϟ֗4,ssk I7[~Vi^_.iJ ۺݷo2FAbX`dˌ{$Fl;i/ : "$ġVF$ _h4 QgmGϘYe8'v ʩQ&)E3@~I|I!> A)H䐀Z6JhmSM6ݵukg9!K)biߩ@B4 $e+q u@+yidz͖Vs+db²6A 7|m rq}^ʧk>zN$IشLBڮʔ iV5 [z)&J:UW#WBAffy[p ~\~FlcF:+=<ѩ?ma&ЎE ŀ"K'O %wVic僵b9Fւh-잊-[vWM4W+jϧs2+d:HO#=;WoL~#$wz 2,X(@uݎzg )9 i]/v=-O>;nZ ʿ"]{x2AnϗdL;A.xJt ŢKW̩vm`c`iSd 8 ƣ+sh nE,[)omJрs dme;O :vG{RS(u +;Sr^HW~q>Ef֮軮^hmik|_b[ H#pA m'={'S4)@%+somw:(ol8Ke> {$: >=pkiRsyOBhV{CC ̃O,n7<t){ȥ/@XlΌ9 p5w͡jD%U{՛3>JHͦknݛvjotӾz$F`6 av;#D,``2zo tR|K1~gTW' GH|R5 =qEy$c,8|bk/@Yb1>M<-77*crSUZյOtCwIkInAekp@`uq]. lkEDF1 s*l??kmh|7(. qvV#2>ЄCm*Odj`; .z|ˢ[ݽ;^/͖:1A 'pFᒹϐ #FFg2KutEA+Aa~F 3<슿5) +622cU 9AZa6g;%Zڨ &8fuy۶Mmv聯ojU]uh_Lb]H#iXg|8c3dմc,B&];R}/IU#iq<Xrx$dItIݘՃ<2bUr+Լqmk7vRjfAau[džZ(1h"m?deb؄&vNϕ뭓SGk4lIdhكُ+h`|ڑ^B%ϗv6C*e@>jg "{h!F FZ'emT=JO}7·rA s<_exohXId *0thZUQQxJ&DPʋ;SZ+-lO]]ieehˤZj˨}h9 &iY5mJq/:wM$ 3v7ɣRN-A2^Xmಊ5M.$a1X}b?4t30pV,`wdU]cw&~F6:\Fڮj"uNCO5 < ir٧gnմd)+7]{-c K}?V(VJlfJ^bۡX#A퐫9{%:Pg(ţQŔ+yYBA۫tmўvje#}(Xmâ -&%YB E͚5d7v IwX;c%|J@nSOmm]/kk~m-ͧk;^ry0MY02:=طQXVEˆrL?viX w<ݭH'E[c:{K[hHn Y$|b"Pd8LYצXӖ_0^wr|$H GF/3{ݲӯE/vkZ CX ?0-;.PUK %mICǶHdBYâUhJQ}0>bf8BfD!ѤTer%uM7⭼TinjMj֗7M7o=WP6]i׮Ѕ\3]]P۩gE[j2_}/ "+-0>6fgy1E%ťxj3qsn#H6JH-|Ii[x>o|ڬJfKKrg'~vaaB _ҟf;>!ԭz0Vѭ9:CNowcjss Qŷf.<Ğ[.+Z8W[&Z~#[pєZh$4ro1御gqij4Of4W-e=]d6{"]iwiqqssFe?/[xGM7–\ Ont n}f@9nn;wc\CEy>z07%[V!1Y޺b'r[y1DiBjeD$ -EpBDrKGH7m ־s)3Jxi۾`T$9[E4ZCIdX"U**%HrNbWM/"ٿhO wO>6FM@J);7g t\ګͲ>^YJ^IJ.Z26V B&>Yv+UnZP씮/4kUʥh&N 3Ư]o_xΉ7YoAu ]>xGYK+%ۯ}>chi њn|&->!moH.Pw:k=gVhþkf7-ŜZd'omuoM}mxײ| u6mU|sޮ6{7; imwK3lך6q mh!Z4.i3M-nf6/In4F 4wd|[4=N}\iX\Ni:qtl,Dg)R~)#㪏.GXe̾T+F4'%~NG7/Z׍t_xS!#ާ7<5-Mg/$ft'ΪV1 _ Zͨ,W7XSO@n5Gm1IS^$p "Gv5~~Vri.ݠXN![\C͗x{o$L*__^[ Q<_ 숗! [ w*UdOx + d9 7 cl|n*xY9Fj:Jqd~CP_/Υ5)I{iƌ+J)9{htկ;Du+ +&RkbB Y2^!t34֒.ZG$~<sb :$XHύ8 5I\v,6ھ Iqk$vZ%ΡFwƄ%:IEZͷ}uM۲mxT"T~핕emt{TOZj0WZIcG=k7[>;~$ݶNy[m "?sši=>h>|iaL~ TιP4sbPY>>g;4MSJ;pnʶn>o}h]jZOmB.m;Jk[xn/t>kFFDeHվa.w~©kyqj⣇QrT"KOR,fI_ F1{ȢJ\qjNZE+I$ϋ)Oiuӛ[r^o-ݶwMuu\0]oׁG{ώ4ho& tZG,~퐋H{vci\BžgE}|C_i{O^ -͂Gg&wI S&hj3lߡͮ,[xIa:iqkc?lӼCcoo(ԧX_bWhx,}]b)oeQ\/$iEz*zke8UC\+Ү̝J)3m*-sNfl洴eBI?b_ x{m^HEsћy[-IkofRaacuMCOֲmvoe%ش6>iuC6BF3C+b ye"[D%@ϹCE˵=F>uT>Yui ͈Kb9^hNy"nmGTd׺۶p1Jw$h=vHςm~=j%E{1x9VjG26S E28h)K=¨.nx"˒[H$5_gTIy[D_߿Atiu6{g$EȾ2M#M(^egV*{idi7 @đژY"ɀ0U>><+'j7OMū*:5{Z1eô"_tޣO]gw`}*G$VV-%Ve4x_=vʶ<G >5^yqnWB[HZ $氕"o"k+@Vy㐻 b.# |yF]H8T5X纁 ,R:բxg{D+ؙ#7]6wΎΔar^I6pī{;yYgycqs'6ir4tJ'kT=W讝I_ix[Uo tc~rN+Q߇t-QZ!bi"CP`|2kg~4i?cb w&hUL$ ح/4-o=A<5onbҴp%MG<1K 1U1Ī]O&72om31]B+[tdhX#򣻼#h(mQ$#Mx:vT[Q兓v{IIu\M^2?6wvSvOGkY9=,[:foq5~#+sp540w:B>Q Aw_^Ŭ LӴe:\Z,K=泦tzN3Kܫ2JJ14\TKm(VU2e(ImnWer"')I.IQ6~I7*R7\+n?jvU-"Si=UK>")KK$>$xwYiMBSj 孵拥]]Q*65-JT\_|ldžwktXWo^v ]NQ[UyljÛ+U_&lk-W@ykoeAѵ=KZ-Zɨ] K-{f62iRGykSmr[ !m)$2v;kIemwu1cs7e$cQFqM\-eFUEծdV'әxcjH'XM") Ra.)<1V9AڒF0O%0>&?!\7dž|U8ou ie, ea6-E5Z/ٮu ZMRH-dP΂ 9q}0B,\ho]IrWQ{ Y6EQkFvJM%.G+8ZQjٙ*zۻi;}-F/}7Mj!+p;P@9,>fl1Yy1kosqg,~\:AIb%YC_vu+u2\_\# c*`Y*3g-\4$}7/( VU$ܡs]` z (5Z6nVlRvZ;J7h۵r,T,i+FHf $JɀTF֮r YfKo_ܡy#)o-!!,cBw28Ȟeq FA3]me}_nYHG#FiVih̛RߦWew!7Iudך^ލ'nIS4̱S}>ɴ7/A Kg5mjwwN+uv3z^wOKi$Gn1D1d[V 9ڷvRD `nXeb `G\uQeK|亙uW1lpVITZ,~smU% !TsoZMZjkfկ;^_IIuNWvsIlͤo$mjI VTnz[ys}  bNju8gem'[[ι!e?(bxoFu)ncڇ"uIC1[#$ -ԫA5, l!ٺ-cq?޿{V ;ߕݑYJa M9BMJ/k'9;٦ukNNZm.Y^v[6j:HO2 {,ihfքeeavG R=v`2`2u[&zxwI8hdXA7)K1KQ//aNaefV%29r.%Uh<2J=لUôثN {nkwoԋkVߚ[]t+g+ޫrNC,) W w#pz0ѝ5bw!I$&L0ʋ9KR{,S~pUA ˩+:Hd߻'_5WMͮc\V!WtW't3 Zm#t#&RT!A' p8l/yw lUVqn77fHKI ,7涌:2kv$U($(~Xm gekIxH7V@<`֒$J[ݹov{m32>TN-xlܵ'Vqk*(bX,D&oGDIP$Xqrᦓ,~a<qȨox>G$~F<T2 \73t8#*y ۊp!^tIk5vHq{.vw]ۻ5<>q?Ԗ Fnc xn7 J#IDH-naIRUWة>K<Ή[mD',TKUp8%xhLgY4(Y$x^yb9ŒIeN2 `եuzJ]9wOUۗkQWgMlvn>,AaIX}.5gF`|&tS*3(P3O]3fm,I-i4,o, bU e\*͝~O6|n!{ r2b)Ttp^C8pŘ4 -yN[ \xBfeҷM?=z=yN?f]5OtOfW>_,-ϙ hR(ڱKMxJܥ/rXƤl V}ԖqTgg?c+ſ/- $vKmeJS^2I󦽔+ݻ+$׊X$Z?.K 0q*< UU}^#vY&K7eM4Kk5ؐy,O_qXTv{||;WmONv.3Ƌm8,PUZᘑV )nwncʵ7:{XBrsD"-pJȱE2'8"w,@J|߲;6Au{'~W Qxl-ced﭂Iiov:(osc|F2zd7p| #b7r%#y峁JzGOZ4ԟT;F%" H ˃'W˻}GԮ:tM\PX,$0N:9%s'NrH zg3А 5Өhv 4^"/ٵ5eUXY݀H!du###cMnFu=ѩ^Wf ])Rb${xYȘk1 oy_wTkkZ"$b0He#-en&9TbxUf%Ԯ7%f HCF2! rlYA33}O $72k;2vfvۺ]tj˯Uy+hkxv[P$ l$f~b IHa#h\^͞g\G#BK"(f Ĩ6U \QVpb| FAU: PڜͽUd #6r-f%}Vͭm%e.Xe٥q7f~O?h/0;%I C?$HH*Y]"c$+fJqmmVo۳N|i_ﹰVa2sB.'V29M4JӵsSWNJkwLe,GJ3xl:>%GJPV"wI$z?E^ى cI42a"]B㍪ۆd0c@PsoN-WC7.?? R\_? mrJc!Bg-}߇j3jVSA[Kaos4pI lǹn/h- +"i`Z*J0ө;rY~URNnk沴w9QJrJ ~yRFQC۷Gc[xXd0hp%Σ} 1([\Y}8"kXo!!I9>4_&5o U/rIk=Cm+0YE%kX3,[=Qt/[N}Oϰtt{]_\Caw&` [;_{-FZ:f6}`Z\k5>/>kw\\ήT\hfksN>NVB5!%^)59r6;4TlxhOj=qm8{J.ݕ&$4, jixb;9ŝͪ&K(5\?$g5j{ n젼 okkok-4Mo~#_Ɵ{qI,޼x]>̅-vӯRDžQuqc <Hntu=Ei4{-P~%7^,pO߆ z=iZ՝w"k圳C{Qui}#0iV,[, n=7],2[顒Su*&6l]U 93dž/֎?m,dXlQӖBKBMAT{VmFs43>x&4[޻VOY[My6[vI=|jsGMQ&x?w?f5Ko]\I}LX!r>cHn&k{ּSOÿjvS5Ly)ռ)\M[-W4(4}Ba[}E-^6_uq^R.. NQ"ȡnG&˫|n+\HmVR?4&%b-zC펫om_]@6^ [z]_tMw3L5_i跗rwFj6z`ֱG۶ Tdž=agТImo&kwjǿ ?٦mjv7{&IZvk:zl~Ζl4cݽZ 2PQXJ&S'ukxAME3rMRQ*6n$n=%YMIidiť+:;}vG<0u{a^>s=n-ZKkKGbKFXN-boj")ﴽ3\KOPk2Oge%{50~x Xfw 5-k[Q PHm\֟j"Dã0KG;_xvgkv}^ UaQדv2ǨZ km2++=JEUk].ZiTPQipOTwP):IBOZ]8ܓٻR\.UE;jEk}j [yṸfO+sH}ԑ$1wYMZ'jRL1pU>۾0 m5-JZ`o|?Zⴹ]^ 2)g wv%ֹif&m.Ooxb]ZNRMk[1 Ɖ%Y!kA ,ۘ}My^E,}QK=fKM5JNkYٴ^ob%xBL)Q);W8.M]NxvUcژDS`ؾHV2_3~}Xkk *mU#ʹ,vJWr mmNTkDDC]mjܪϥwY|zeeMXpqڪ&c$Lf^IhNԒA,XLCF}yhi $O h&XېD.Ba"9m(b@%c4F[y$,t+$8f {IXR qkVVnڷ=m{꒽H%mSK==O# ۸)8%P!~e>TYϩ+2RXQܻ~b P Pn8!\8 tfi|fB1 GQ.5ī,H+dC9 snuV]tvn[MKk]jkM#A-xR0eE$d2˂1,#ҭ3 TdHZ6bU!4*v|#3|UY쫤[I l; Yr*H`;KBb vݵvU;L|gHɤMt5RkM[kkj%mZ iȶ 6q1`)Y17,57bYQl|-!u*ђ*)n^žToHUvؖF35G#;{-Sj}>'|-|{(D3u CdpeDqbBlf\;&upi^OQIoIZPܮ쪑 g0K2#47/3 C Ug,Ve]Q ,>YlB0e jI(MuevЍ4H=R۾+dTe| y~ xT䧖vʡDuI> iVVE ymm=yk >йgO-yѬ-U"viwW%b('OۡsxxN찁ZVުɾNwWːc%*1R9I75VIYMҲ,zF}c{{ןf- Tk-.ۈB<I,ѽIR5O1lipJl5@`n[Ѭ{G9.I%k/_E%$B I !e`[U;J N!P <3+0'ŰjI.K{8ޝVtӽOmSu'Yr3Mv?eK=R;;5X0\kuA@:eaP2IX\iח]߃oSZ^YF[Yc&P AlW-;Z;wH渗rxŭKUy[aq3D.KjQe{5guWvi7mn{٫z+aHQE]] wW\X^YβI&Tp7F++D+*) "r\3a_f@dSaq#omtֳ-AXBG ʕ0Hf*v ̑*X (Hxgw@l$Pː0HjA 02oIfif@3Up#dďV ,yl+邌\KzdImiWmy4S /<_sc+`Hg#[ y>a_|6F1[RДƣ*m Dh²zr՝(Jl0v0 , @'rdggO[o}֗Vbݤto;^ݥoImlIr',MIf*T k񜙇KJ2ܳ!LHDdG&"|`/dpjz?[40\@D33$k[D^&.9N,W8\i|#=̘UXC%bXmݵQXJ/&Jt־=ՌI9&wݵIM+߆mA"%qcN8Ԏų^cl+kػ0$Pʲ,E6 H͂P`J@FPa\'i#<`=Zȩ4h|S-YC2LXofD*KEfwuew޸eV<=RP߻m]4}o mmQUeGKeFh$+e wC+2.ntH# 7 ?D.h<$ؑJDo;XW5X^y8%~mEmB3.onoxٽ]oyos=nivX~ keq_,$A8%Ux!AlMFMPM<RC2|l6pAʔ qݓUn26 PxR:N{aүR&eX|NU67ۀ}AtRi;ӫ|XD{7JTM+_VӼkxȏ&DA!amuM/ W?g!l²Etd @ ʜm݂v>Ht-3^h@9pJ.~g܌*~jC5.pLdtֆH|C+Fce O%ujJ۵ֹڤ̓8HԯJQI:j8+5$p^(_<.[9W/,qԑ0joL`&01md9#8tO6IMEDsKdnĖcӎ-s=v.2yIx8;.hZZwW\jiI 94oe}]n{'X1]Elk[ .B36$|°; 4RA-]jH766כhq(! yXc_Jc2}3]z7P:CRE[.V Q>jDŽ-%t-,f5=u*ƍNZnps̢UwIku]O,t1JUA%XZi1&vTT7f@RduUOv4."L{Eۀx8v n)0 )O0iC^nF.8`0p2:ǃWֶ|g}N(+k+?]^ͻ颽{smM O٭n1\/mRFVě)@0(ĕkrtXkhaW˒3~]υ 3cp CpTct}\}޷eXԮ^ʄWnZTd[hmיF*D֡R0ʠuXP(s@^9yy%XCPM+ 8awyfl 9}CK &Hc|F7F9^mq$ ͵YK5h[720(QP*dL TĴ7WZ_&B~s۵Z^]x 681sqI` 5[xr@G 7?(VQ `z ~]׊t.E{瘐҆w~#u X8 c9 0qVsމml[h]}{5]4z9MKX!fH!eGf1oVuFU#ba:ImT>.o&T"D(R"dajizsy7Ί 2i!$1PdEBcɴ[g7R)ޱ"!%p04W+m{j7VeߺdKIoqz +3E F$/.XWWMf>S]91x0=/$EWd$f\DbexYyg;T+(|K綏gW{=]42L%H$!U~Ff!J9ݴ9HO&9G!r3`s烑ZhUcfbC(r B8~lm nv:WӞiWi}Ӧᅲk#X\o rZ@yp#dF[ $}ȎVEĐƁʎmZ5hgnl}|,fro,vM˖H z۩KWqMK1v^_! >M:S*NW:}^Y&[nIu.w_$x%@dt1) HwAQ oR{QW$v ,[iHF|˼CwwK{\^^܆ynkI GHj(%qtQOUs$J3R8I-K]Wv_MtѧmmyNs%^_1 gh20~*YoT+8X3Z VD0YwE\\N"I7Cm@kX&@^G#`.FG *Es`3QjLqra*! n܃.*av'yȉpcc>YܪZ6F,/ wd092Ƹ , Zvz&֩'YCִ_.}g.fAZۋl^g_2He][N7]RhVn V";!UW+fi$QWv4-mxXƯcUI䑜+6}xgN+(fE<݅X k2ϵd=C#H,ժO6[im>,zt[DY+W?[j!Mu]^U q\C-Ԉ3Ya1b"thسp'q 2@o>^zF[Ȭ|pZ&C\\ʑYFL@ s:ż{lΜG]𰇂dncdQY;.uV黎jO6Jk$Vm'];vWmKBd$1cȄl)_]Z}ֽFwKn?6]u3<[& ؁ofy $.>C9Dm̬Oi3#Zn׼2CM /gMPȧq[zymsyfaO$g(T)b IeLͶzz>#>GYUaD1 U KFL#V+BNNQ&6kek+nDPiveEvʺHae$pe! 5Rh bP|˗u6(l1R;)C&(dF@J0BDĄik6VQݵ[droܪ@R--{[n=UMkѴ[h/$lx%.f<<$y &@i%uI[²ouU; p3+vC 0eU VhGmwl]ѩك! X1܊kBũ̌1:yK'rҺɖf,읛=練Ilvս7nj{;Yw9];R /a2'_?)QF 1-mTQ۳9% ŖG_#,S̊R2B2bay1F*:7-6TKaɟ%L(٫qq#+H9)[we}6I7Y>5k7˭wVNk+>+QĐApSInSL˷$[4w7",oS[WLxAxS_hۖ4C{pЙv / pH [ Pޭu[dWǚ HHXED Y_?اSi`{KE -?f($a! G2ڲ34q*}B' :HT2T׳j]4*5&__SZ.'hPO-}I]rqմ!ıGPau{fxr4"|~9HLjx6)\$˒bv۴0+G`[ 6j77> k){D6^b+_xksqNBl*P,uʱ-pX4gp* ] !wpX n)I{xJcRqnsZ%.~7mwM3 iI7Oa΅Of$^awF8 _4W?aEmh'Q2k] YY@gMBdy8'yl>;2]Fñ]2Ò9FEP o bj#՟2Gw㮗l+YDcEo'Ŭ?(I=^+kgefv(Si*0qך˫<,)g'{["_ٚy4OC?gHOK3W_Vx;T2$3G!:qQ6_j[h%ZOW@u6xX %KB /𠲂ݰ4\[IGo<snѻ#'[wAR%__ % ڞj6$kT[mZFQ/u6"t{[K5F8ڷ)ՆjϰY&S.M]2gg[3jSV3+%}9`_'+iْ~ҟ4ŭ&TҤҵ٣PI=2 ?T_O_j-'Zp]MI6h8K,O_uHm5/ x^I!ko#^4&wjζw-ƐaȓOo4ח֖ wmđ}OZ.$WPn-v_ߏB4:ȟ-ckKo3ZZ]Zإ,^+ :[^+myVw3{O'!q԰Y4y5<5 2Zo0-.Y7{q_'ju%SJI褕Gk+_?S/SE^%IhE3[//.#wMoc}vqk&jȢ_|J4|I(h,?glqᵆekI@5Ωi7cĚ%F[v7ִOZz{WӬ`PΟk=m~9l P!Oq49K+o xscI'{Yx^y,n+55yV,oQʡ-JR<<6.D4eW\QQQRJMZVoxQ nzkhgԚ=K_մ-c6ֺ,u4ok3wwprx:ލ`[w5׶ԭof/y֙YMsCK4־\%n'g?-? 5l\kjVvq\i0е(gTW:'ǪXGq&OtE6ljtcmV i|+4Wl# 1eITTI҄KjT'8Ԅ "}V nݣxni.IO1iVH2&W幚diO`!:E{^NfY$~3j ]5%);E5^RjǓ4`!,B6V[h4FXoXRD>uϹ6"_%[oRnpiԢrƕII{甹nw*UOޛiݯv+YN-%+%ӚFY>rmy/e; !EG~P@,GϋzK(%|ytPvsXʲ^!_*n}7ZG}vO/Y! к# %cAFٚ9{|p$Q U; c 1&хސdF%hR1w{K׫Ih֜^+wzk[KjJ6bI$3~/[pa1ǹ#QUQ]CU1tG=)-⼖+I̓LO$*GMql̰G/V?ThGE}鈆0 nGϕ RQbrU8yU)ŵ*tb6%i]I=[WzwҿTyք&SbX K3sd8䷱K䅶 Vθi'w(9so}Jek/--mP4 kBAk۹ :M]]n S/J/5C]YKk ǍBL#Kwkkw:Σyy_xZf<_W>-GB#OMrO=kViPizxje6.|ijMɢj:k-u,ǧj !σIiwSSoiVv"o%ռbM{;U/QFPnyH7hҭ&yg /fխ~X85BMkd|-S@ӵ =| 1 &}.ٺkNssQmIO5C]мYkV5 w<1M){?ċwmcii>Rqx~ :}uiޏ #Oj5usEhQ5 4O x(êhK._"xHWtK]BRPo9Mo_h^BS\Kk G@]W0JNPu$gRTӝIBө7u(Mx'ݔ'&*M/v+Y;FI5cW5+?Mmu԰Ҵ/Wu}:rZW&?p6DkkZlHmJS^=*W?Ũ|[M[Mc84Swp6y4[n;iQj-}jza>({;[|j<*-ԯnj/jcxSN<ݫJ˞A۵nwUK[lloH/co=dŵ(6qtDxt%&%9[ܣCM踍%s;PNI闎9Vz|Su[Kj ְ-%hQ.pu?PFe\]j!NmbC]CVTҖ(|K%db|K`t _40\y> u⽣,Tx$Q)\ئ8eԒWrӴmke--XTj׉+lmaYVqlQ&]>7Ll,uXWcm,nlm^[ }j$/ҮO*R8Hkۅ\(q&?A3 T2(AUf\o$OetgdI+tvik5%A[-/Ed._MfCVpTw+$.́9Bwdqɻ#@x lnM"љn!|bK^HidaNljs$r9 Rss;jy_o+ϥ5Mޝv[>ɽNƃMHTPp̱;`#;J4\2Mb RHN`?vvD%wmma~@H2cB $ VGեc|' v4ɶ<MUun[W]k]z>ې%Y_XUVF>ötACPɔVeB̲w;J(ہ _B6") T Y7`!#.߸3Aft*Sn] sI}ok][GkKDk麾wz[+j6(TIΫKRԻr:;ɕ% YqFIb͸ n 5 RD2˂X2X6 5f6սM_ziP^M=E z_LDagC%If.%W*jM'>ƪqP 2_$0R[ˉ lbܸ6rB`*(`ϱ3UO$rEwŴV14yndd/kVNSN)Ͷ\ZNz_W]˥:*eki7_;]*1.mb<-b 0FdB#`řً]mNC-tzR]e\Α,-ƕ,NmfxB;?YٵO#vpСab.̮2|N&| mx'5!@ VD|"$LB~e5#(BRqNϕJnTRSMA]X>iU+LˤŢܫCQ[FUR,8{"{MXveFR˅].'&HhIgXr\+Fcm$u[FOTTD̦hлsg5sđ\۴k$R᣸ُ"xyh-q0ˆ9r1xY Y IF%Fkܢ_m,b/|YltLwkt-:hmTB3yF4KK@`]:D%hK؎W5vrN&ڕ$շpҖvZ8ɴMJ-Ug^Eu5kVCF9XJ۬ 䓕zccfѰrH(d,@nAg=gNӥlmc4y^ԡUyu wXh<-mL dH*iSRI4Nik}h>WoDzkb OJfMvGF1 af#QSjDi3ZJ/./;y*kM^ZgxǔJZPs;6"I)UQO}{]cN<%wMZ2y>e6慖8Ydኝ!P$Z:1;!l~RqA{;+$a$̆0[k>\`S&Akou";p6бd1F@b̹c-VW]dwZw?]&YouXJrn&@x"uIH2WQ ` l4]4UF$,C c`CnSS P6GLmPw|ʣ|ݥvռv}o?G; & %^izn-sӺT`\LSiLʡ(8,K|syӯc2]@'(Xe2n(v HIle (E"9L,k)vHxxo5A*,hT sM5VTVONy<S\[U'g螻Y.psvp &1%Ө8Ӵ%KC9@DGr;ob$b&0C`mJԁ0k%|  "XXX"H ha,H9P_n鶟k^v}Ug6 On3qnɧ$WIml1Vq#nI};M{KM17M8[ɨꞭJ骽v& yVNcX@$%X;i' H%z]%+b BM,6B;w+W_*z5֚7knwn]m'?7-y-͜ꀦ%+H,!pK)8\va>uO[1CI%Q6ȫy0~Y$bSP lq׍m&a^17sBm™-ŀ8q'O:eZp^뗖=lҾWӥNWy.iO񺸴HQ:1M $b%`6L莬TϜFdO\s16M-$b1Ȯ>f22pD.  㟔d/88AΦ{=oDۦ_Gv44c$*,M < rr\OSkgӪ[T=+a(!9LQF jʩY:{f/e 4A<֒9d@d*v,W{QT(ldvvxPH qZ%\Fo{VԺl{׶e[s":rJ @ ` +Ro ;-}JYj3dc iA2.q\<AGNMu>U73!rG“ VY_$,QJ fmYPnIGƵ]Z]#̯̌ LZ|1,6.pT5rS8rO\p8\i%Hq:)`׊pHh\gCMyFk`!`3vr O*Y7m]Dkv=}#gpBHhأ,r &hȕm::vuc^#m|pq:QFoS}⑄ kfE2$jD<*:s d7.4)@*~%n/ebPJCgi|-tvom-w+vnCW{[gxC+8%eMy$L`[p(:c osI9H%?hy`rхon  5k+;ml՛Vb-%w֋kMwKi쯬4_X#HbDO,IE' v1 g [iFt-'DeC'tq7YJ.U W/4N7 |NWh|sG%8 \+lVEСO[[vIk{i-){s,D6~om䜣dndR앷VoiY{^[7d1d\Kmvg}e,R,".$%PeURQ%׆c/fYd 4S]\\,S@FA"td.VöW}}#Yo?K)6ˣe qdQG )ъ;˵WaYgxXwc:FviߞWPVmUNVTy qoe;hvIt^`DZ+ >!]nvnԴ)'jZY8I.nBKndi'tY Kqu1|ȷyI%ZJFT׍!}bkfOB')3H3Hy[k1 n;[8ul6 w}iEڭľag}(hԾ&nW*k$LZiUf%weշwh<+ۋ.9²‚3d_73I#޸GVS W%/X3.[,$!F|CnOo_aUI2V5v2CkЮEUP`X&2CpwHڌ[Y%m֚ovF;_O W8dW?pˀT,H(n$Rc.U]1`Peg : .W<ʆp;}K&-opB;[Xx,2< X0阚8W[+ $RU5x4Iv]nO}Kݢ&=!pH-C%^CUcgmvX6f  r[IfbΣ>P6H?X;X$yK1Y#HE!ˉI%J܁Wf,t=$X9! ˦߅Dd " Gɒt^RJzmfkFjW].7zfEXdGYTb%'JQea 8k(in^6!Bx#VB(, Pc%,9f2o?(`t maE{*Ky Xə^Co (Pyn+H_hI$S<`p=rfiWvBDsJһ vÌIi{?uh֖iٽ|%ߦ֮Efb`k>K>]8TT -#bKoײͦ>zE)O -TQq#|7_?+x-!l1^!BhiLX߇IbyڴUbK*e|-F^GWԒh{R<6kKigN[ g o&ZhoZhHʫ5~?5ho 6l֟޷? T6G6"$Lyߘ5+..o,"m9IOA *RX,B'1>X ~ѷ6ijhiz#8] VB>^qKȱ jU5K6~W^Wxf.&sOeS0T쭪U\t7dsӮc[!ӵK5B:ki^iF5i}/x"#Tkx;]۳=cy-[?tr_Fs\[9c kYm t5IYywVQ2[$~r+^6O giH|K%%Yu/ʎ |Dς_|,Z^iZgmL4[Ϣj6^Iyi#Wt )ZuܱYx)NkJ0J\VҼpA't&!i(_úpٹ(VY] Wvu*ը(Βkeʝ/~~X]YxÞ>ִ{]WO#gS?8] $FCu7؋} 6 ུ,^YY3jiayچ <,)W%#Jjj[-C*Xj魣V0Mkm9I\;a)Ӕyc0UHXuLZmꚗ*Me7fEʾZ@hnfQ^'f@ߘ1es"ΑMZwtKԬ{L^+OGtK-iڴ}iy{'{X:͎csu EqaIB" {ght!]6=ř:Ik(hfEա,Aa6Vq<4WGXj~9kWM'̲ `ܤPE'h[rI?Y+y'>xþ$5 ԍH+=N0="yu]]RBY Oy;B9幛Lt'Լg].{ׇ҅f5xnZ\_Y\ɥ:多py]CFNĭsgsxOkoe}'OK|Gn|t2?kԴNN6k-kx' |/ctdtOxoKNVñK [閺s-kۙ4J qW C 5CPvVm%~W&)K#J_WTj-'Q0iJIBMJɨe%{Sqm.c< Kw4k[xSMq_g-&FM{Q]B_|Y5~\[\{lm\&y.ִ0\kZoitjWݵoxF|Gh&ni/txeЅ@}gIjm}O|xGR5ƼdݭY^^]YhV/ad ;[Ҵe٢}W;Ʃ/syiMRn4*SݔjTT/N7Qqm%v5xJI>gM;8ESsqY}%5o5ZNs61o,>q%g~/$:űiCdzA}m 3xGzIbҡ]Bi~vcz$1,^/YV9YeYey<$K2[ytيC?3$uV yҼyi6mO _]%wԘKo"ږqoESP-<d7q8{δ%̽ewt H{;E6qW IQ㶱JUcqRO<{wus ՚Kծnc$E{+pFԒ4E6(naX^O5nLf AcqViΝZr #Vucoi5(o:qJRnѵv*j{Zf-MΣAc/^[Zٵ8tRO;e ( crmdxeu6Sf{)G1J2Vnmk%I%dR6孜U%'ӌwpURVJrJ2n4+[Vشha/+^[f'+3MoejZGI1$!V t[;'&K3+Gͤw"E arٮMo+ MSJK4IGi| nt+!Yf!:ki5i;C-ã ) ?͛Uz1>͹}89YJI*MZ;rߞteM>^m[7RVM海jؚSjjK;Ӥ>Ro[dfyC FzFe 7.dy6 񴨒ρ9VsoI^P yiXL`SY*gs,)f$RE f"sngiRVXq36m1EW]UI2Is*T%ksRIF\M^OM%^Q\2Mg)}~N:5QA< 9,m47ik-%,h7#{۝mcs:HoncKVx7Ww2ty!h|C,j5#2x n&m7S!ctX}N ]g4|u,R=/QӥYZúXEi:C]Iy2c+mJki,8kMl ƵӃJ1n<-$5IŴ'hJtNѾxwJ}6!/ & ['JkG =7LA I LzwGJMFdRZX!%-;y'dQ4Q)yf8 9vO[S@lݚ؋V,3+=icMSVVDjwVZd#>E\{ ?Z76We%Wjrhdi^ҫi4ԥ+BEA'ߏ,Gm.^^9譻*]$&zծtRuH\<[C 4][Y(ȅ\C㹚d^ַS>曪څ ·ӡФk"ka/QMth-yΧ|7P5_5{[k; [CL𖕣\7wV$Q/^_Ggyucw}}A\uZ\AmkvGYE`ޟa=ڍwdϡXhu 4^sRlmZQD#u"=-?xY5 MCk>lp-ui5 {ɮ'4[7Hm9ڃ:c#887+%r5+7(-[dN~gN,ۓRVR6\{|ocZO^0χcP>JӴ=v=^K =DA[in?onz{}|O՚Tg>(ZiZ({xN+ c\ƢvZokFu]?Kޯo>eF}2ŚƳupX: |5q[Iy5|@P:ޅi+.hzlzF& _ xR{h4 4 }Suu b&> R1rr8{YORu' 8J0tyjJ64Og@qmhgR.]xO [=_Pu>JUST}ZeoAxcZ-t./LW⯎--k~G{-J]:I\xڈ*O 1&hǪxd=Qѵ[ׇY&{ oI?>-iz[g^95.. 5ƏxSV_ m/PѵkˣWͥiZg } 2MaԔg4v%WFTIVtN-SN+˂ōkISsj|ҊR=O5v,pEaۑYGJQ[榢ihsF沌%)9aRtIKouF)+Ҍy5v{ׇRv1If(A$.Rv QNQnx L彺Kh{%a[k[eO]oZml7-1 11*qcϓ7D/nUn݂ MsN1ecz6͖eiʐݺEUr@%'f-u';_Wf&wm5^[;otW]3FU-II%d _ih킘- `YQ ! 20Z\Hp68 Jppňr_㶉-oFl-ʟn]VPKvmvߖ][Tt_K{=o;>ij\Ӌ{+iJ"UѐB=JnYw"%m2G\GvݽILZ6`$pUPbꁈ uR`ۤr2LWddዜ.v%fFVDZ峻km[nǒurʿ;q QF?8eռd[L bѫOȡ(Xc\a**V)LmEzf!@.pl|.rlV *ⴒMvǮ_{oKKk4Ep#c`4ͷq6gprk"rrX.3>a0gR,"ܮH9lmfTiPU<(;dL nJ m}p^[Ӯuʖ gԝ_Q`eiP˿%vK Osw61tH$P,s$SN&g P`F{%/6F$dHFR6Y-1{@aK m9!H\#\(8_VvIItKR' FV}խQK.&[lpE: ݗ8e8Pn@vbj~y vF<Eܒ|.op$@셷1EA B(9н.`y|$#Y]x܈̛ڱOKԸ1єlՓ\]9u}ZݦsWĝn[ݥ׿]oK;"=fMk2U fq"߃\mxۋIT+)GHf 03*f&Hf>dA²V9$ȻlJ΃O4 %S^(bxs2j;¯mvn^uF[:龦7uKpq4ʁɁ寐.J$F>[@BGhj 3bMHcp@bڥT5g,PVЕng|ob*Rd49rDM;]59W Bma4 zsk2=*v{u-k]]UCJ:6Gݜ? ^"e}MJ{E,z{jbF q;$ɶYEHl|cB0 !f5MGH}WCo=VK?>uVLL}a5qnBk$-zǎ#'2B&b&&0"W{ZK@/%Ku ]\ RI{5RV咺nekEEmK]ovy+_ [6<`\[;&V)܁%RU^K:y ̤j:eٮ#DLQDDb2ǹA*{;F Mֵ7KĶK*":h? o&xOǮ^i^hھ.躵~j8~y7# A*u+&0%9)>XIŭyex%gd$먚Uں}%D֏MzBmM{>Un^@N9e$e" ndiJUAt2c1lf sp`d0Uy:<#6'9͂L_$0Vg *w-Sk|EE{Go61r$bFC%d8!Y#hG(T,[FU}6 De*8wa:PB TAHI31Hҟ.hD. RF#&Go*ZK{i%H̺+fAG$RY%rv|],ͻjwJ%TԣQmc]칖R XdX9h +pmb7)9I3 ++ǜfF:r>B3dqi̚}Y6 hlQLl1 ζm^nU]C9ٸ-wR{M^<\"i%iKyBa'"U܊2ϸ( ޛ2yGh]jlYY4)TL(GQ:l[LF;k$U^1#m+sss8ڌj3]1Y "=ۭل#J6|[rtz2ͺM$#9+J)rћj;4ӛ]4w3*m0oRd,%plap2I;J/-7QKwa)I:,l,-–bO eMP1P$62$!@6vT3`yn1@!' *ʣCn1PVzi[?߄Ҝ4\ך2M-mu}YnD&1KU?.BFsrvfv 89$]O[cBRHe#ʳmYOf@ȮU\)9#N1nkiG.)5Ԥg$Mj;^{-׆&j΢U1ʬF̥ 0eee7>7E¾Ց$Й/!st*SwE2&C$98Iͷ'FbA[=V,oHah̍T3bc!NX vilmݝ4{;άXӄ梹Փt;%V5ޫi3^?d@v4YYfH ;d`#۫*mɹ  xv GSNlj ! 2TT瑿nUKY )CxViI_feVP\S_{iZm꯭I76xHCcRc([x#$ G@^p뀱ܕ).c& _q,C aqZM$ke{Z>yjs:9Rp]}5M.y֘ݎ#y.eW$s2cLRh`Xƒ=EVAy< 4ȑ-f_,Q4 n&Q1KBWDۇ<090"g8@tV ,vYdHRX;E6 !]GJRֺnt[tuK?լ2.| (<r̒ax>n89$5xxd2 {+ݨ?8`lwD(Oq  IHS#VU>7~k{mKտ_dw)T,ry R71fVC˰#kc r. *{SR%*4.N6[, 8̒Bb2#r]B4lFNr !uoTSkKG\m-+g=kD{=-jX6>_  |Yca q4g*mԄwW#;XT!BC\>|m~ep#s$ak)iQm ' ,tiDo#MAwʑy$!gZb6 &zu/F^KWZ]kkm-nP+|`HoyT\{#,vaZlԿKC [,h!Q r8ce'fYӵRvQtr|Mek}5$"\uZtև_}YTgGY0cÚ&k 7'JhV*_,X2DUXdE}j:IJeHbs:i&DhyUYbaIѣϙ+#FoPvtѺH#$iŨ(F1O{+]6{]ݷt&-dzYɷkYD]Ek"XeQ-$ Y^BHBa H$GmkN,dQ,FڱKVcº)cnRG4qEFȩ"8gɄeY I?t@\ogfrwzWZ;_[ֽ>]-zIFo. O3fTvMpM%8"DP9@FDdXBX!r=֜I$[؎5}85`kqCFjFs$ 9-`bUum~W_-w_馩_5vڕD71 BVQp9WzT͹@d(*#(T'q.f&ډ$PI 8l(ذ,řTHxX$J]4pwZk"SMH,?A-wH4nR?Mo)Ή.-Sԭn4ʹ_o%m?\j> Q,-%ғZƅxk>|^jwVwVkk:$K2WCm94o h7nltwCyEwkxZđ5myRRO]ѫF%IMʜ% s+'V^1"Vp0EnfםHr›q8Up49NJ2~3JI}I/hΟ-ō޳wtxg K}Jofeo=Ԗd.-L^khvhT5t [{Cv_>"i-Oaaqi6uw2,Q\|Yaiv:l>+犮,}sZ׌5_"F L"-.{Ӫǡx~i59|KE[jS>b%u[WĆXkK{;?n 5y{ZMKLWK+:B/w$ҧJ8Fʚq=Q.U6|МwU|6-++\__F^5 ΢]-CFlK]bH;{{unTh'Zg~x5 xpgi+Ω6$7IM Lͳ_8j,rG=>k./mtmNo[FNxI,jZiݤN 0g;h?i>mn70]&?sjiZMOkIyn:VK}C59?}i?uppӞ#5NR.iSK 5&c6䩮f`]SZ#hBO.ortjIFvO|t@bӦk˅5ܖ.k\j6mfo)KH^ Xk]Jh>VW/ eGXFyI Y8n_+Ƿe/)ljծ^-UUX[/./#1jp '.^JYiwq[h+ᛛm;UK.Z𿌵TgҦNqG;bv*pIN1v'Q僧c8]KwFRo9:6ZZjK*S9Y&mW,ԟY[߬WZlIiyi!rK=e!,.V()a 7a[NOHԯ!mB ymsƟkLzC*^x<#BׯR zqXMB^&]:xnķWy%0i} {xM7,ѵUum2;QZf F[ V+)4}-&&{ bkZ bc(-=)Y%hӒycY){GT=RӵZ |2u+}J> Yjzބ.e14}fion4kiDw, OOi˛/1,ז6gT?a Xm!Ҿwq[jFXyu4O-oϦ:H<#T.4+ oڵK~/NK+K{;˽2tazׅMO}g(u[5~3֏om\i:ipZl]NK{nj:)ޝHΫ^({pvRo$ӧ F-5)77&ԴV\DRz9]+n(٫Sh0qiS7M׾4v=~lռQx_ƞ 76N Zޭ 0>ti~~+V_~τWT Y-}<-r߉9XU݆ :1ڕ8(Ni)B?T.KMra \9QFbӳւ2Rk5] &ITg~kjus,3_YBX~kYź .|mH<wX>+Abگ_xÒj^Iao[xW5u'MԠgYGq|17ZN{L U]{IӚx9ƖI~;JmhŹ-[|28]N\]QaSҬ|_ZEܼ|KKFд%o/tjM^){/5 ?7!h5hZ]xWtGOҵkT\i.9'ҟUC-χuI- 5mD$RM^{x{V w(麌z[~rɫZ\\xwFI6o=.t)&]85dU:S#2N8+(J^ -)rFJ1mF[G޿ړM'&/ėz>yssyy=CR)MGOxv:7'j!ּZKL siƧ=k-sHWPW_[U>&sxK]ޓb }>: 5oSIg4Zj6O |76[SDy|7wE[[ J..|C]Zx__L|tS2j5ckxOAKk U5o ^}gHӴrsFFRq6եe)C%ej\\Vhs]'xQy7q^󌹓R9/|w}{Jk'oOEkrhXxwP N_~M:{_^Yx| 2i$/,-~|l>0kό/)xω}KǺwׯASi'š /z$!QiӒ=#ᗋx4Wt/xn,k/_sZ_xo/=C}Wv^#u A-yXGk:Fizm|7>!{EVFJܧ8Jܜ]N*SKUi֕#Rr4i%ErO^嬼=+h:F-g5no,u+]7ė%YXڬr_#/ sk:Zfqcu/|-qcNmyaug|Z\^ڠMh# *eqg'|ex;W?oxy*C ;?y4ɚ+Y+,ݚoFf&u :dO-[X$tn-={%r[ ?t.m@N:-.l{q=Ɇ 4Ǟ4;toAfh[iD'ӥ%Fܼ)٧%&utYF59Nw{}j*RqQpiIr- Yt%%&I]/ h"N,2͜r=#nrʠ c9 =3zkc>WkR+ش5-hͧZy%dm.y_tv*cO$yXU"' $&\@ C*]ӽ~)jM-zvu{uZ%}[Z_]-Vě >W1m0Jb!6߂>U`b@˥bx匂Y5s @70)fs\\2,̌%, Nљ%( N k^I+i&N̫mm:}oӵ5L,%%@]pS4o0cYЂxPFZUTrP3drO%j#"+2@؅J1L-ͺ4o`/92@V,]VѾmdVY4ki?EBPq# n1Vr8  57Th$c"" I,\.J󴞄JJ`R W9_{\F^!.t 4hqngebr@*ğy>[􊵴ݽ:eo;EH GFKeJHB2w)^C; Jə"f+cwy$ ! X7rL7fëJ#_Uvg{l5WxQ홒@9HppAL*I;Z[]z>hd=ӿ]}mnQ=lH82K'WDʫ"j~_YUXF@->}Ҍ"A q9$d)3YJ() B\HxeM/!?9j]]nzukcUi]$su4.ʯwn?0a"+p[ U:5nZOIi2yves6ч4@I#l3|*psZFr'o Yؔl+uϸXUÇZɾkn;V%^"I$h̬P1a"1b6Xmf-.ރ6%_0;6ً`UpgI`31x0IY%!rP ? mYp|$T1dF6 ~wӵ]ZZ _'gC|Z(PA PB'LeBp ջwN;dro<66kт u, gݼkrG Tѣܕq.f!OS#fRqбB*v Y6K:kKg[+iEBM| \nS]غ|͐8SN GjǗRjmZ1h Gel4Ec}Rx] &b'hc!O? tePYw*HB07[zn"ܤd֝ov"lFY/ M,)ӭI QO,u9p?[336,|@Dυl|IEuhtAsLm.AL2qsl th`ce{̐꒶ex0QEj카]Q7u.m߿˺Y W Ύ7,(%3b4OWuxʼn1𥼩cxkq]kz| . X7‰4vtf^YJn-egBA].r<!TF2,25>{;<7ggm) fw)kjnEr0c dWi(6f]I9ok/{YY}Stkk Kej# -cP`Y\Tv GSTBs:3/- ]ŵg lX* q(56XuڷJYY%dX@Ž0~d@*K[V^It~ք]C";T{iTm[nI4۲]յd[}c]謭ُ4d%X؏ʸhAWg m,vʄhKS7Vyuo}m.Veu&6|Et3jZ<.$!De{I2ʘ;F8942ZZtnK.$ 4qij}vѧXdKidK_08 VvS.mْ9ʢ07Jmȕcې,ad͸msY^$܈M1 5EdB"&F`2M[Ek%v!9BM6[ݺmKFZ0mm^&%nrRoU$۵%ײO?3;jF#ݏߩVH\!x bVሔMauv; @p4;wDm"L7cYxYw78c򂮧ρWvс+Iq A;8bYWf Y}[{hԺrJSvm}]z[I5(pXw w\yڭ!YdʻXQB]b+-XoH 0)u%Aڠ0=02aV*BhY7(W$#WfXْj[^Y5W^{;46GtMg%ia!;B1][Ÿ51 8<@Q/8kQܬ1Fi mi>S2 1\nV8w gb `sR{eN]ެ魢K릾gUēe^xqr"0P>ZG,enFG%t3)pT reR. reWm̸Ñ!!m8P a%D1WIMU)]Ű-ݫ$_jץ֚ZTݴZ4ۼ_;mAne LB`Y9ˌ W±+Yl$ң#;0*喍IWܲ2#`>d* `JyV`!]U%(<$9;nâ쐏%EH1mEI9`̹*78Qԭ,VSvP`x Mm2/c!AVsE9>eM#fUN5G>[g[#m}iڷ0 Tn!،$%NpF*bCdwSf\ 饶Jխބm&Ѵҳ3H7+' P+l-_JdsmF"2]* d w-HVjÌ! C[hT|* 0:yiuI7 Gk) !<EMF*ܻӵ֛Kz7j-U Z:*|&&H]IQΡeb*Al]c%"0P8`p[c3IYS\\f]I2#Pٻi@F+x6e+zK[Nķ/lɿL~.MM]ŵVwWih]ֶkk$.ʹciMQSଲ;v(*bQYUkF9o/-eEF7Pi#bXķ\mo`dV7H*]^ ռ[nQ 4i-emi#Ky H*rf@T{dgc3 6=vM6T&0M8vQV^JTegkn'w-t]Um.F^5TֵcpFHe%On/fX ';MFc 2gkvzu&YgIJ.-Ue赽L$r۰6RFE@U܃k0vʩ Ƭ ?vU[ˑ|RXM4BEp nTYmkwm5Wi+vM[Tޝ,۲]]WvftRnk g>|p""L۷[J m,p#dlAh_XXBfQs>l6b|dW+<Ɓmɴ" R8L(nBōuVYH8,n]*̠)5մVwn^OWwm]4̌?wJk]@#W}|"ȉ;B~_3&0\.H&I2Yblo \Mk0bW ||@loŏ]MTPNL(HPw);-9[m;j{VZ:uce:$@6s\qć W5. &Rɑ6 t9j-ip[v]*und chhFRp0OK9d ;sr[OkUoc:0]׏sN6*nXVĸ m2(xa7m .&42-kPKE5wl%(.Yal$j QqMirEܠ°oed7n$;]i$կm[Yh+'r͓ ž`$]~oӒ2:NoYx+'f;=.ì_ a{^;qX nr|6&JӺ]Z潞-%GGsΕjUvn)yu~Y>MSzN:\7ZޱkgO5ӭ5k=6KH3(ޛC7 +{|/rjL[u!fx)W17-φʹֶs[\xLVA{mmoG5;t$k׽bN6(Zn]OHiRkhu^&IfDy!&MɰƖ&g^TkJ2*$]O4ӕZҋᅥ6QIE4Gk%^>OO=CRIU$PV9qad͘Ȃ[7Hh<5o:.{xf Im/kbOhMamoNc=͸wZ. swrڬ k =PB:ۙFTO5"6>OXDi^%Ҭ"]y4ɵ kKe{ZO3%ե70V79ltsRylwRc5v3եv{\=8$w[f !6$cNS _Wخl&]ixK J[ 3^i&ui=izl#ti b7Ne˸:*^>|эFNr_PZsWח8S,JO]nn0sI9&o{ ,3YjƟ}wԢEdxYC6Lz]욄sw m2|5?SMUC~Rt :lV_\K5Wg[˫?O쵫ya֬f(t ;Vw+1l54fI3dޝ[ͥ4: KMoDC6Z揩hڿom/@3:ZiۢυhUSՓ\V$(T9NNQQ"eRϥMѡ4u8d,fUrW?q| kZOZ' }-2Eq>(LWԛZE/\/!?x;U7^S O]WT4__&':ZvvO|o8ͪv?tGGK"\{D[X۷7>8ESAdֺ夺ïÏe_V:~X;_Ez7$_ ݿ5m: Ju}2y#'mRs>ԕH;t۝r4lv/Bmuo UukKHl溊K!4Zzg>6|*M9w᮰O:h^M嵱oé|A.-4TjVڕg)M:{x#>*6OsYEa'-|uSKDP%62|9m2;M^S ɽ_^?emxu'R6hѵ CB[{-6TncC̶0ܱ+pmip<pJ!3n)ͥϚpol3rޘj29IrֵQk|NC_-/iyux^k2ӵ{i].P i÷['ľ)op"d΅g;4,u04Dνa߄VV04IbAmpMBιWmf i4{XKc/c-NoKC.{mf, bu?A5woٿ᮫EgעI>h%XI,@-/,ⶼh/NؾqWTy=keXsxQF<-RjNIr\;.p4tyriKFmWd6hwWbÞ.,ٮXw)5o7Qh4&ZU]Z^}`ql|ge_ i Y[hڛimtUͼwDڕк:}.ݣAq%f@ 摭Zů gw*)46=z|=]XEsw֓W4k=ZY&FF׏b`K{mP^Ħ (ZwL`$tMW%^!|xVImo:ēk;8Og _iomȺTq#j|)O:RPtPjh˥Gwuw[C50a%%T,<;YNlt FrT[Ԍ\ui3N%H>eR (b(:mZ Mw>YKUn-D\ j? Ǩſ^e___xFbYZ\kPzyI.SķWr?V:~m]YO_á^ɤmZmS/oyñduԛsVRԥONtF'8X Gҕ[9J*JU6գh>nX> o[/u]鰭lko iv?4"Mq C[-mϢVEe<~dGMxPlGHVU$ڗ^{?XM^Z*Wq}M6Mӵ?XYxQ8|5A[s]oX{ od;fφ՞h߉5w-G0_=ơo=kmyhmŅq5U&Xi:?ThӋ ʜwwtFk޽51ڴ)&)Ns$(7t+)mݯ4_!V[ پ)^|' ͧi'KoÏx{Zt..eo/4D5[l~'+ė3[Wι{e)ִH׌46E/ j2a𿈼WMiVu&珌,x^FO x^47Zv]wL,c h~-?SZks,Vj7:d6گh[/h4Zoi>vV1uxƳ\O,nKk-;Nһip2Tic+ҬQ"E!/rQ:'(J̨Fp B#:9w(Z34xw#O/1Iw>(<={}M*Kz^Yx? ډ5#N<h˭i,>/kexktxV)N𧉮񎵯]\o0fa(,ouG?h2#xI ][Pt[:dӬ4)4kxP]?N{yG7t}+S#C/ھ{'XZַgL4CX42hqyuk'Kce麛I}N{-qu;? j3Z_W5)NJstGٯhM/zrm7N<u$?I&;IIʴԣjqQNl~~#8 ծ$𯆦Ԣ/[+VtH~XS~dǡ[^Y{[ߕgkCIa3}%IGTy!K&H<'5mOZ񭆊\iI›j4/ΨI5Ky bF]B_utyۥFzzhOm-ESCiVVnFOnuyUVد!MrҲ:E+Jݼ״GN9s?jwpJmpMExݨ߉ܺ֯ey\i5P-5}mC-WM7>M"io<=#G}nDX4Y. TT>6-V: "wA+k6oֺU֭:56mhS6Xx5 G[7gkm-l}:l5k{X{8ɾDsPKrZiIX†.۝9Ji5n7ekIZZ*}7484y-}BX5MOIko\,ouVЬt{`]*.%̼I-P^ߍCF7}7^{=kq OKֵk~X6w^#ڬ>*O$!uQe4YꗓI-.R]-,/~i5km^MjOz>igMkxyiZNtQ_PFhZuۋ ;#Kqs5#9rXE˖|%R7r7ܜT#\ŶV/,a nNMC'k;{gwwrjwk@wmo*3Ol#BK[!&o=VUOϽ׼sivuiiCRkl5mSZK;.maF>c"Kw̏Y; P:.Z˩[xSgueXkV,kg?{abإz4:kzM-nWMaOռ%q,a:b4\kiEq-]e$$ͥSuZQJ[w3WJRG85+iXo l#YBV-%ĪV8 l3͒@ҸwWBVh8H Ò)PYٿai=6o`՟Prsu/\}Kd="Zatm?i-wZifxaoEwFQt&4`,+MZ;Bv^I;ZM'$jn^K$'̱JJP"WQviQjѷmg۷#L.ŊՒWxEAqE-tq(tc.Y>2+0IyY>` LHR,sڏKk{/ j6CmSSԯ,%OqZ]o%[A?ܦÏiudڭ4SϦ=A.ex%l]Ohg*;r*-"նh{)$k j-R%tRѫ_[-c^J]V5 hB+o@d,;7SQg&9 !+9PU@m*fKa_XO\Y 9`i`%DŽyN7!bVR&W27'(g3*LNX(["RwjZ8n޶Dm~^kIJ:4vJu$1R]#;$*˷&RE8"\FTrf G p0 QU!P1ɹge9l1?66i ,!p3plB `PmM' -mˮ׿-{Y'k5tEK\Ovq(vu 9aY^yo<7j đWrH2V KbpFYeYF$?5Cݙ4dʲ@\F>c2_ɧ}k5_"kkr;_ۯudssHmDY3hf%*<6b"F(]d%$ĖF\ 6: W65,QW|y6y`IJۗT/ T2)2$7kDՒW]GfVoe=6#{, dNhYAVOkeZHfb r@J,;@="|O-pr  XcE+5SV?l*ۡV  cH>\%M׭>קHUFM*?Cm])3!/k1]BZ(C030xyX;֦:H,0*99HKJK-\k+&$i.Bd[WܡSI'RIlVKK]齺iַR^-wfYm{WM"W?v20WrΎcǸmBBt5rTBۋ]VP7m54kYޔPDcbǫhp蚆)%LB96k,k F BdYH@֛Pg!RƓʈ*X)Y+IkWV5z/I}דx4A%ݜn(4 J;q%2@Zr |1&.IX;C4_q-"dFQTZJtd]wOIno]̩a&ZA縺Xz7h ߭\x\@f7˺#i*M9Ey$}N^]/;vGgk໔V %wo >Q+̧Q"U<#d"VC2NkqpY̍ n￶d1Qr;&!TJ-]WIm;蟚[4y&D[1Je)(P[,Fݮij*a\2iҧgCy13FhT&omuK<^GrH# swdLFbu0o" @1ϖݪǿtwh`\:.UwY7XXʜE'&{bwʛy6"I 4Řm6RI_TV{mv]Kz}kWyqqw4nbC@, *+bc ̄m2Z#L.5ʌ](߇_%JRED"AwzT*y!p[$+8%ON!fI'Fq#Dc*R-a-mkˢ߿mK_eKkde y>-n+b@efs˳.s܏:ᛟmFG˹w^6R98sոPLLŜfʀJ6`S2ekOM,@䍤*VsQ 泓\k{knz;ۯ^M'L-m;\Eqm= mIQ®֎5;3vlc~yn[nv"KX9l5"DV+pE!Cd4,$0]"ؕިNKo!Qr~*rQ>YDR ` <Dr jnzno_z];ym5N~mm[2-jJ2n"qP 2Q$GLjT&j+X[r|:[6 b 8h Ɏh=Y#J X",TBUI!`iTi]nYtշ⯹)5,]Ӯ蘪+Ie3,HLU iGaNW9-PNv3ضnMF1Nȯ#r1IGMRV]W۲yo>vMt+ݙmN#h؏*Uvʆ#5jN|G;3ddV%eH\,HP* 9W[[;ukuklʹ=mek+wI"<3[U_)[SFhc,[yFeGrS~pjw3`%"}@٫C%ѭ/$wCu$t۫;+ws#i /7J1JrQ+R.T䖍F8ҜiԦNQ\a(\{=y;햳׶Ηi`\ #9ڮo F!1$$b>#Zh:|L@}[r%D߼c{25 ga$ x?F5=bG'!;Oqrs#C/[v./> DMfCoqm<4^!maBtEϯO]+Tܳ?C,V7pfy:u9)3$'[mx7ݩY=512*:q7J3vsRqWmIɩ+KIi#T ,n \J\iKv^mKq[Mk l0rCѴI,49S]]6},Q7kڮԣ[Ɠq3'%4yoS[e6]ŵa$l.n-iV'Dt<ڭku2o֥VQ_^EΛk7hlNw}8dO`0xZQJ2RRV|NQtgJ^pB+Y'FS[J4j\^&?_j/Ek[X+/kӥOot͑ xRnȵ+Km.fDᥚ }=-5.Y"3e@x7Oq6o ڵ<{[l'o|L"ӚI}8aҤ[x|6/h?n⮡2jvwׅ?:ZXJRE-.dH7ZEk m= 8{(AGTeISiE|甹_ku$Ң"2*{'.WSiTMEG|Ɠ^ѭ4M忇u9o5+}'T񏊴Ķqy}*\YX[58 G*w5MD֍wOs۝8%ω+Sq}*iچ/|E#<1^C$Z}jysiO~[ZVGZ$I5M+eڂ]\-ŎC.OmNY?4 UuuoFucS* 8Y9.X?+/yI^KEezþLɋTFZF4m.4t9:U_ Nv 6hQG)ݯǀ+ ޗqicqn5Ki!cJ[x0Xj%\K?hV]VI8.m^;/4H'(eӿ,n$#D<{[5Ɖc[ZO&𹽵Ee<#Vxni֥N)NjSc)SM: &kI7+TJl-яtKj(t ķ1_7I[쳻үF~/{/ \V+uk#5m7V焭,Kōlk/C`-#=בJeoݹT%NjI{%?xJ#QʤS"XσoQiqaa%0KvՆ,뷗Rރ*%x{: Ճ%40ߵs܉omtta>ZJkY5&>mG/t߳_xNjMԧ;tMZtr[=ւqO o=tX4럶-3źC5 =m{cy笠ail'7Oivaou޳[\^ԖM>HiR9 .l"}:9o-Lm5YnZ['bod.--So,AEUk-:M'ǙԔT^N6P%ө'PiByRN.m7T)j _5'FJ\9{ZJN\_Rm] 5=\zH`K{XH&mR6'yeu(,H$+Z?i,.f|P\[qK&PZ-sE,z~|4˛hPϤD[_WUYS}Gn#F[h^YO~'.u1k{mjv7OSAmulZ{>jve ,s۵%Oǧس0-݃_YKFTg-nB[ʗ[_Bp\I<}iF 8 WRO(V]Ov*Qd#J[ŵ-M8I+'www눬٦;]nBn&n.&(WfV."Y):v>ent{ N;s6qY[i_Pѥ-n`[{.$nV&7 u25HW4i%Ŧicpmu=|mYUŢhyWC&pe߁"kniZ+g wW6y,ꈲxwNmFx{M`񥥪'^ E9hWo YI6r{F.2׻r'''xI=5iהdbP[b䴴n$MDrMhIy{imd~_R=:\"A.b53RYt[].]6{{KYj2Ŭ[\]cx-nK5[!u&;Y5]')7,_3xyN䲢, {lXEhG{hVIOӵMTY]gfY5W.|y Z%jZli}eZ</澒]3PT[y4u [/YivK]UJ'<f{-FO.u7!Xw{kkFHc6 mwm>;Y5}f݁Mc\xfe5n"YugN Z,oh]'.fPkZ46թ8Ҍb7:e&?z0I8A(S~;riMy7HMŝVN+l54{-U6%͆B^[aH5׆nVw u; &>ahV0Gy&k? tKS*6qkWr뚵χ,fdXJK\|On$?4_|;>$:j,h~-u?.0_Y+MÚvKLl[.ku[h[b=^U!XEյ7įI5ki4v2f_iEq^,-NF k\>Zχ9q^KZYxq2.utr)Пq%RJc2#m5CéPYFcΨMGȪBsqjiSy|,\x]oZΡ[_|.k]v@=jSզIk^)l4{؝NZp%Kfk6Vv \i/$A75У}xU}#İk֚5ݣC3vSO-C| @]՝[ok2 `&c=KX6Q.<xY]m"|%k_ Ri1xÖ/=|Qs=޻x%|ֺ+z &9粼Je62gڶ%Hf{=KCIk3ʱ=ŨQopUYfZU6BOѾ0ƃu+xpdjԯ!4^oBki l$C{8y݇]fB]:]:#jBյ-4kPZ[3Z\_^Ac,U\[%Sw\Y{4ړ۵qN\kk)6Q\N.j7I9%$i]%xjgfhv&2IGreNq\|vzHWg*;򑐻ՊI`+m3t֬\DBp$D nC)CȞea`A,v- `d*RI(J-;FR՚];5륬 ~ʢ-#nO+ņǶ(8n)m\6B傆 [>fx&`W [`g1K&7Q(qER"i!R @?;LFI$'r)6Z=mJO^[/nQV\&ݡ.- cTbFQA J.TW (eY[}.M凞]5]t[4I2K "˹HU 1*r2`b䑍J Ы yw7#frI C4@f8Ԁ%X(2[v,VeLoLfTǴmT X hjRDo[%WKu՟V56ΎM%zt,YHm*' YKp@7Kd n K IIVXB3.<ę#;hلpdhd𰩕7#\Vi 1# ˝NXcY<#TY(4U^Ugm/j}._5༷齇,UͣnS;WOۭ[#x夋 )qI`;b?-JZ6* R6C} {",~OBD<9ItR?#B yeM${-j+iӪd7Pq lȶ$g|".v֍I1coܤ@R7yAo)Ăf]7*4l;nAXJ~Gق2a?RMa.ÕҼ]kݥ{;ufK|{X.g/+7"bUYeR'VF>Wd1z+$2k+`>`n!vYDžl$.Bc1C}V@9Qm³ Ȥ!W > *Vhåt}6j˦$۵̋M_q6XIG#9~1P.d߼;oh6;Pc4Qulr<*|\2c* $ ݖap\c 7 ţ,B<[QSoMZoM+~+d]v3 ybdhWe6R9̓H&&8//`4 =Νf&B$WT̈vJʛ~Jy`cIo<nvEKcSKQryR|%NAʫ`m5yPE$$`JG!{yoA. 2Zii5I^o'w뺽9s>f;쏣i($"9"'He.7I",E(E]#+xʐ^(1 -٠fEHđ-*L*#(ҧJ28'nS}NMZuXp^᥽I5[B햙eh~BmIa,Xo+;5d]@6-!IQ@'wwh'q*H^Y˳bV֗dκnxF C BV9CE&w|}AFA'r2rO_ZkR8vK2ya 圄vhC,v䭹T]zvOڕ-<('BXR_j|..UHŽPalx!2pBRU`,vElrWi/ZjfX陞7)dC4krKۋ (wu%‘)t@Y%rf%XC-$mkۣJVtN*ZZkv ,UnwHLaDfLRK:DT)]m$YYIV+nHmT$yR&R^by7Y7 A&+Kg`39 2Iu_ݗ̍ ¤16R[ Nd䘊>D΅(\|_fߺ]{ޡ4}zPgt&H/梤J˲4YӬ-ͮ.Y&0ZژeB|V%@3rlZN`LJwe $XFF*JY$C#c :!ijԗR1%"7qP&V8a@ܲ'kuemEgN˫nT}4vvWUcwWd21ݑ$fW*y\ƫN1‘ wȊ*SJ)̒)9fX;0HTq ݗd.$f%#VO0Rc#\"EU^?15v~OW}w~-}7ZknF cXwmULc+~V@@IL'9_V#i0$.6\P\G+4K?NY!#ifAT=,;0i^Cq\ Tv|*4J ,d,oI]oweןOent^#hE2n2H>hErXr#I9o*vA" \߸2HhΪn+3, p,IKsܫ(Yli I.Jxd˳4DĐ߼Lvby+VE|t wd1%r~lIvJ&0K4c2C i*pIim{jmuk{>.*"C * S e)c瓀F fe?PT(dW+)'F#5j!;MO^AnnF %v]mn EӧetFYPaY|Pv(X*+UNХx`²+&UuQ 9df.W8rYIj3&Lt!\nP[#DZﳉy 7ۅ7yіpJrhzJ-}lҳNƬMlptJ(`Ca P%wN-܇ pD0 Dr@|y9#vN Jw`a"$'=q8wG4@ ~U( @ݜotmEl*@mR2pO''9ĺ}ZC-;JAweE.i eh) D ;oWvlA,6[PM0\iz<:o}1_xˬEPs!$fCr!fy'{e_0Ķ>\hnwpM*.TNOݷE=亣&nɾ'mmmvѮ5Wf)HSIVr/t[}2Ѯ'kt)g;&#iֺO"Tcx-J+YEIt.z<?V4{ɬSxm+Q?xZŽcus$͇RIlĖhzGÚ兄yЧ ^iQ^YA^.=7LP` Y;Kԯϕ)4#ץɨIҵkgnV|?>nLMյ\i:͔]Dz76V: 3 q4K=eTI/GIK_E4U F|Ҕ"QU7kKrՒ;s`50JOR4BQUr7IMӛBP߂2Zw,5Kv[%k5!*$1ϧ@X-O$qʺmh.Km]3T>[=/><qjZIşن^#/kWR^u3Ե2WԠJ4oKXZ\O :78f1_j-J{6'Эd`ԫ$I6ҭrT7Χ{$II^V~k 5!TZuZeˇJJ\UۊzǕ}PxQ,_%x_0$/ej1ZB 6FM*M-'jmt6nlm $5Ӎ:֥ujVzΏ5ez5gV/-OݥCmyo,WZf% oѭo@2xU4+ڿ4[Y;H4vd_Lݺt״kK?'M)̮yIrN|FU!%5'rI%.fcj:Ok:tҊrrStg rgolXFU$㽥xONÞ3񮹣꬟l{[Is^iPw] C񏇯aeL:sYz ;$-bZ[[k$ּWB?t/CjV/NO|5ibԿgo x{{NZߋVsGZ%0x>l(ᱳFjFy랽Fky>еcSms_7t_hF:kx7/EZIOa:XpTu:3|R5QǝGSoHkƟ+ʴsJs߱jR\RZ*R5Wrzo}4BNЦO k^ tֽԓM]O6swΗaDVI/Zmׇgnt B]FS‡~O ԯ_j [k[Zfo߁jZ<9Zj|IѼ_%޿ x3T׸ko;{;{n qr6VZ~.$1i?@Kxt/ZWC}4'OHb m7YbNKB\NIIROOg*u#9I.IY{\J?N1QuS8NNm , rNx}[+XnWso_Tjn,#^ML:#ԣ4;ҴD>An}S_xZM[S85Ht gŗ_=ìuKnFþ~:uJ#t?KҼ{m YQlOִj]{Sj?tz^5֭gpy㸲5;QqA+oY>iڈ2J.͹FuycN!Q^gNQiR䓏<ǖ.ҌcJT4hJNҷ?mN:%+{|GOԢ|>e;* ;Da[K1è5?/뗖!mSSk/i兝Z[[:K\6E -,/lh'ҭ[ѴǛ@:GX~(xwwwP[Ro/mNJ5ͭjɤMiJ\5Myu{鴭o^ Ӯ .4uVw궖 Մڎ|.6kT|js]5:nMb R5QMF|ih՗*UqZJҦh;s5gW@lҦ4i:E_"jBN[ذx#-f[mr][=j:,"yU!m:v(V36>v_vZ>esM3Do #s^\oXxGewcgkZ^K5V:m/xOJӡrijVV䵛G$k2طC)RRxBJ4ԧohMx9.YMJJ%)5$)]ܾ"rKN3[vy1m\akWӯ屳An>ߨ~+h|L 8fMdK %ӅHu MFKYfYOXY W ɻ0E5xgBuxdH[Xo4v޽[MkIq#էנ_ 6o:__D6t1[jou AsţE1MRgKuR:JxE^ji9sU79.nJN:+7k{٤}IW?Z]Bjvj1hzezwkq=KK)E]pOmq[ڡ8:zoKEn:1·Lf/mno>0[[5غ~|OwkWDm6?R-cG𦋢^+(n-lO-jS #S⎣Ii" e:މeiM g,sW湚CpMNUJP T\$\i'%/'$G'{tI{:i^RP V\My\Od[@u?\W[6٣jPtxl#2zsquz@]E]jW {>H:tza/G֦{ 8 _X>LckXM wX13^]1jZUUtPMs>خ6t̑ʹ5 A)4  \"TSlUe8K#]G%gRgB b$PsM)& WiRi:~Y?vRXʤRwcQWnͯXRKX7"NKXfYMOR[&l 1K=S4wQT|M۵em"_ilrUޣmᕞoIC[xe:>}mC熯m4+twI(4!_Z^趷 :F6ڝY5y4VX[M2G.AQo-VgUm^iLmEΟ x5}R!YEa1ʢIԓ^(EJt%ӋmKO:䔔v,[8ԔyN[IC[m-`Zc͜wj-XUx4@t[m"Q¬f'I#!t-2H/oDVuψ4Դ[xFoZރ;iy/m/ o:6mO^ε}Pԭ;j>ҠK1}Z<ۛFNk{dhm3ec]OVضvv'oKcI0U^m'jvoz{i+LpxQn˕:qQ!*4Fs:J2rg.wN2^-'y;ry')NT2PKHZPC?em-O4 cO,>(,.dԬ%䵟 hu5jlگoCUͤrHX-txE֣pmmndNh汎36j^m;Q:9m{7!.tսu kk[:6Z-( bo툍//(ZQ5}_Mt/ˢ^g'ok +[w"#t ͤZ$O 6Kq6N4}SH[/m74FźfJ. o%֙]SX$H|=e-=4 y,V:_n5M߅'+} XEm]Hwo=KSt]{qh.$.Kdt1Ǿ`c{{X^:ut_UY'U~麵j  otS/r=ד4F۷59ArFRf]ANmfҜZ2Qqi89MAͷyr߱ռ-_KPo9^Y/4{> w$֍ugfNjm6|;ˍI._sn,MŜa흻_jVz-oɧG{j\jKexgY6ڤZDŽRdU{}>= -noO|q& m6N7[տ$in=g:/4 ǬZX!]R(MNGkskm>\kil֙|zƳMNT\ٸΥOz-N2J*p'qq3Ҍr)E(>yS>Y$$yZ\_\]K]2{c Ɨ$n4GΙzωu{>-/n|k{DO-?ZwIn-kugzE޳d[mዝ{Pχ5Qet_3QOl7zcg+RQ^ֵ?ì؏L-4.9rZIxZ2n}+W*[BsqҢ^05;)8B\NoIǚNVjI8 O.Fw߇"D<4xBWм~C/}~{oh7wt= _մ Z/a/I\Qx²w=߆4|ook& SEᵎ[}zOxcchjqioï;Is_m5kqՇBo ?o<6ogf$|YsTψWӭ>-xrN-'|"6ŦxòxVҼ1-VVH#(b'*]2'd\P9jFi8q79 RN.2I5SE:JO䟋7|IaNI.uW m;3]Ӥ<{eu[K ~RkN$^uz^+i]Mg |9ss]7MA KOj^11[ZjZ^c{Ýxcᾆu/k:5'𥭅,%/Ƨ<л?ɡxķzT~|:uw]姍t˖oZ5f}^{KY-4YKx=/CյYmif;NE+)./ک8u\$9cQNr.WyI9%z4Y2R,׳se85MKF+SOCxKWW"öv3om,[s0H5 {{gQ:ݍ62swy\ͯ'HH5Yŧ .|rM{Y8>ds&)BvZ>gg&a%9FOE?vRM'+(ٜmUv,]!;%Zם9D?0$`2qI-,o}I]=moi)NMIJ.0qN׵IﱥdvnersHdP dm, n% `Wps vd%[w/HЩ 117Bټ%/.Im jHIr-ɵZַj,;JRB WnvDlAr8v "gHv$|i*PN(7,WF&֬ekXB2BC 1;W8 \EZ^ۥ%kwdvę,ʒ HtbWq`CJ&IݺrfH7"&3Zi;1SD#|#o1&YTnT+eS74)iu[tʬ"(+m XH*"U Y_]ծɥu}wZ V}Zdu{1_]kht4"! P|Ñsf-m$@so;(e ~W`Ve1jKeYU3Ay ٸeDDs\ĬEX?yfO)f8*I$uVmVMKʑ3~m^Hru&b\) W_ .Eas\s q?j9RGbv90H¡?7 & DJƒ!$g0 ]rrŔq #dRT èՓ[;5kiGw ۭZ^^\,@t>aY+b7YHOwSM$glY2ô8@Hqe6 ),2A$i!+"f%b8;*۷jfIDR#0 o(b+#SRvWWm}ooMzmnReUeA$)ud_Q!&hd2, )pQ[]H.e9Ii(Sf#h2PA >[3*9P^Te H[y 1Gϸ]ǂYT+]M`[wt[ⶺ|{%WZᕤV(V^PR&@x]fB 9w0=̈`,hL`$4qZB7&1&0YSgYXu >mi@6Y( 26c$F5UZ=mt;N].m\~h1J7gبI^5&ǐ3/lznA(_r#bgȎCCY[Ȑ ċ*jE9H,bCF35|`Av`|ɷ9W^$wNhi٭5[յ.Eu.YL+gP2@3 Ui Ȓ[F2+N?zuR7D7 ?8V ];eL6Vń@g,NY*NA,2Ӗލ=OvF+ elm Nn;"ې"ՎFR^/'nc3˝9 BTcNev/ I-9 9"1I希.rZAJUd lPO٬BW6wVz.[}JB`S 9Uv 'ZG+uF7,PȤJ<ę eB 7n*[pRYHd2ȎDl YZ 00gmbnC3dƩF I1N(#4okj}{-5!Ym pccb3yo'8g'3 l6ThBFٮ|bOD;]A>]D)`A%Em fXٶ#pF|'jG>vϜ[(F믪M}l=Ao#+N V 9m8yN.Tq >fjhHbdA 'nW淏"P3]pQӣЀʌ@ 2s !7 KY+$2AۓcHw4&7|[ %ǩZ뒢rĚqi[j_xBHx$n[8(Z,ݠ.U027O$P$ԺXRm/O6Osx*3fT.]p~Q1 oIy'o翖ꭹMK Euic+ciyUڣTХh l_Z5dM2\nMjbXa Zz!QWbd'm#cMͅ ȬPA8 " y%P&;avlu3hBd,9ueRvEgfm5٧kkzZ|k{螻$|̤ 1tR3}j:0]wv/o$tbFʐxؤ bn[nO1g]_Hht/J$oki3(u I.;]m$Q_[ӵl7'5)a{3hW>!RGʄջ'^JKF[]> 6uWۙk|Mh }:=2;qKjۿw݋MdJݺG$^gg{drZ2lԕilUO N'7}#ͫZ- Ն1," kܫ;<:r8)g*d8MuQԔ;[ mu0^# Tr-4ˮnϻTԢi%m_Wy:t9$sO A$Df"%^ *L0Hx+#Ϙ$$g F:zdAɳBm䍤 ˅2x,b~mNoQۯo҉~QFC*XT GUpmbA !dMsw <{vggt#%ǐ'.K|Fvs#+ "eR!b̳ỳmoPm;,.YYP7,'kM>FYZkKe[_M%u[vYZުV"kpr"h^%U.F`çDXAEWV,]^P sYh"tcm;9;2wI12YP>"awᰭ,U#ʩn][[}ݛ٫mDޏio-LbG|3.eE+"|$ xrӤ(EP"^L6ϔnFb*3$jVGDI!Z)%h}GM rb3 9<# `dn۵]68(+i =36Ӟ 6Un/'| xQ$P#bIZC ƌiZ]ƥ!p+X[rVQ]a,7仳*t2qeeU1J^!Mͱ;DU׳zE;oխeЙJ.{%~-Kծm6dcX5NDt^#Qn;%nK %>-Ϙs:FDxp|!|6r.Vݥ$^[=Vx'mRG%XQ浲մ5|3>-Zku[s}mky^ghq]9cgeG-׉?k8P{(<=xn[=WK1mlz>dp]A*/5 *!,_-I<[wdIj,+OASu ["ofoXgm<9yfSZmGIyծ{;_iVkix-ңF7øɥ! s/kI&3N)Zb\\ۋPRT:J狃Vڌ$Gݼ xɼ9Ky_xmjQe>'nn綎[1sy=j w3/%x Ě+}f*--ց/hbWOZyk0-n&esZbV]Y(Է~-fV Pg#6QZE%of|mo^kVk.x{{;yej Y7Vù㺵J+ K͖loW~6}3w@2i`DP%7/uSN"rFPU9k/jIIF\6JJrnnXyb^R5^UxE>N^HJ3FO݋SB?6gcUݎBw Z<}CShh2B2M*{.[x*hLҾפx7ǓŖ ~kh:uGwmG_?Tl=,)??V:|%;ٴoͥxU[ss}>k:ntt}oR5ޟ4MW:saƯxl7+*C+x煠\=0Z5i5QK=6'+8+EU*VF8s' B-ZNvuTS)KIcGңU:Ϋji9'*NJ+:U$ߣjk2jW߆mhZ>ggDӾ0.*T}{_MB-QZi-gzt(`U#RO]NxVz;-oMwKYxcSr6muXI3ٛMk Ջζzn4 u>!F&_4ŴK+IŃ~];OOfFg [EZn~cW 2R9Ƣ FXNYJNMA79)Gk]/m7|<62xH mvxxz]?Ra%gm[Ư*\ӫMN*YIJхoƜTۥMAΕ&aiAJZNJJyC){Z[j>Z6]Bګ_ku.oWICv)&l}ɭ޷iӿ%iN rPgg*3(ʌFwRW ;ƚ¨tot]3▵M׵ltȼ7Ne,WVvV5Ėz}oi5o%W75j&lfxK }9uӵoVao ^#4 Ge-C]*DUj$O]x_eiD[.yo<5-D@h}D-\SIa j~ެZ4t߳TAPPJU?y'8Ҵ=rxJ>ҭ7F(F}kO%:tmR-A]6coöuûsci2Y|/.2?"ǪiC{{YԭK溳i[4 _YR,('OiVjh>".l`yom/"OzUF-2żEHZ&N⛡Ux]7#ԊIu *Qi<' Rwz8Vo1PK T|c{m^KIu_<.Ƶ^[Kqy}oOm\/*``ԵY]Q.6Oqx. SQ 7M4]^Klā?.#gY&_'mmN >KOzNKv.ROM{K}fMѮEO>/NYgnz#^ZXRM)۫罟WOm+y ]EqgAu&M+jsum) (:?Jg6;v,t{Y>RKؒ+].w Ϋޥ}xk gdݿfͨxw\JbuX.5MJ)eB,su-<%sG=iM^H<5GP%]YC0L42AQ5*Ӌ)T/N0i87F*N2Ho i*Q FUm^i+.[i3^C߇~.xOY?|Of oi>+ %"5[+k odjWRƉlK-{Eu hrIj6kPEk.Z:DΣZ647w>5ҠC.Fti8 Z^CzwjUD>w ~/i dbX!ӗHrLڞu^[ w62,Uc:U![†s]FXFjN'(TJ3}ʽ$w'Ւq4n_Qt ZVzl6jW[%n|iowkwgtwiɥka>AP,t{ہp2=CS佶s MW®mj̶wzdZ>/0u$2Ck0k6wz9O m:]oӍj!34k+;Sխ#4ƴ'b xǾ^!טx'^Io%A+{koK)ίo,k$ٺ~T&]I7MG7;iڊeՍtcMmIl'}*ySX2ѩRcU\kU*NiFF2qIkH:u%ӄ$ےջ]Y99ɽisp][Ú/4n]+A:)!t^9ƷZvKfW^qͶ7Z i< j^!յ:X֣ѬZK:ھOa<17gռ9 ^->*>5Wگm]:%n[*q:RXrNyb*Te)j0K*ѫۊU J7'$J:8y--+nE; |3I|'ះ:⸤mWR-~xYt5E_xL]Mt]-uG ^ V;DŽ#Tmt\No j^eibѾh~mgk}3GX?kiY=>$?hmK?4}k o(| }?SOzW'Լc]O¾ 񮍫\|9~ƚu^*l*eZϽRW+Uì_4',<'],N_ YVѥUN9T Qz©;7u'R0sWQ䒫d"y|ծ|1oo{;T'Ym.)/ٻt Vn+>ax T bV7!M[j>-͗~-G"QXV~]x.-Vg$6?#jP5xO[7~Fqs5;ɨi1LZnh_0/x.>/cϟ~2[/kPז֥R[hAa2UPq8 n0gU7zqa+7 T)p瓑[K*YY*X|MT̩քT&׽-Tnx¾c/3ijYx~]#Nҭ4O?گekiuisq!oY>{p|4M⥦}9[iQ7iyukKĿ~%OMcm&jZ6IkO~!|_DžTԣ;1I7WךUnut?{mCotkMKE֑]2izN '*/v:uΥ?-,m6\үl5 +n4oXh1K6mbvhC]>-6A^xKԴj_x>$֯,u%ҬM[vbQ7Ze.xUq{~RŧjV~4QbKcO2Qxn ֑>^{#Of⣛STb-QǖM'5.gN0t%RN\)jFpVWRWQWORVR|u֟mPs4h"m5Et-~xƞIgq.-wv-|Aỽf_1|%9>,gޝ닝*7o73k>[hzEDږ [K=^3dtc OZl>$xPiO4Ny!kP7ͼ5=vxo_yaxM&থ{WTԵhBD^I)G|5f}Kĺ߁<)li#i}xSŚXM3U] ^m]4i[\q&xrm|cǍO xW>(<(Ľfݵci+/ϯiS-y,5jV/ULjyk⏍uEuú^Y.KN#JK7]iזp~+7}x[͠VG*zZg_oJoӮe]rSXuϝ-"xO:7@'tۏywKV~6Mfo-LJlt{HIaۇxJ*M9ލH:|ן4W5GN ?uI.җ/uSW̔e|׼K∴O>?t8m5mWB| `sZɧ\M={ߴLm;u& ȭn*y淛xtm+8]d+q7Tee$[,[$OVWxuATB9PeCs xmndIA15Qcd#ո"4Oose=<¦uY I`xKYdѤKY$lx2iAX)䟼I+QwmVW]eI7T]mnv ;F{81&0左X|0p@S$2џi#! 'ۦ P`f,s 9r,y׏ $$U2ޥvFw~bek^~[|ˌQ6сW )@€ N7]!UEK&ʅ3w  =b+'F{a3y,֡BBvH'2,4Jp$t$nx$zkۧi-[i-Vn-UѵϨi-UcHeHb ;lʯo*lȋo,̢S;` r |2e_f#9ؼ>fzf &U9`oU }Ruy]zu}M C<PM.mD܀8-h<`j5ƿJp'rall1p7 $҈`-Eed%eeWj 種=Fx^\*d2#r0%N>gž=m{u=[ju+n}=:z۪|ج)[D,NYk]Q' `+u)VHBgK4Y8@E9#+`E$ n/OcܐKpTIU7,U]Asщ˝$R6rA>s8¨-P͆E)ܛWpo,%f~XLfʡD q Ʊ0!/nUgTznwvK](xV!|n 2ve&95&U!rs fmΠģ7HQ~Y'dC=%?$ T1 cNA%T%O-Y\WR6r*)QJ+夰h-c^ v~Y'Ebio譥Դc(C *U%QX!9bD &WllǸ"&C GUyX$XuDmHR9bK,l s6Lq,J)<9 +,(F Ca/~rw租vG.fU6$32@LPj%DRb<άI= 31T?{)L&|Lcrch- -bݹrYpA "Bv͘;kwe]o;1,7!0wppXl9t )c?1ޠ)ER$+!;HCNm$14ɖ NqK39FՐ3Jq|r$8%Jb$'[S?E{/m}OiԃdTu^|߷z%͡6&⪘݄BARYp!tK aWjZ7iCl̍J6Widwcf1j=QxhY $z}`U٭z잛ַyW޿.DkypQϺDC0xw\n[ /;&z\5T#fIZ!A V|=?J +UgB5!`Ф\ EeFu1K;gsUezkg-}mzJx\]tH 3&` k+$ϐvd3Bh*#Xڕa iiHAGነ)R9ܛ5(&leq` /s5;\CɣOm]-nߪ~kZ_^ߟ.< v4q84B`NetF$o6+O$;Ǯ; +gR1c>ڧ͐1/o[^|J&Y͓qGOlp3=6~_u}64;xg[i+:*@e<*WhxHU^6P0 tqKZqc5G^ތ+J ^c PSL6c,A y"B% u7𪚕ݓ9>N|o~kK_^&vfE-vnHnPYladFlh,I<Ӯ XKՆwe`Mt-aC(.4~x$bUKiȺe0H؝w. MqkH;یCE Fګum/kooE7~YJMp$Dɽ%1aHn®B)eJ*Ek+ID- ʹ [jW^Zsk[ez?_p=.Wnszg&{s!9Y@Y$2J~il亘cH"۴~h^KvgLHkp [<=-tbU6Jw1%U0Ŋ$GeM@0r[n6`V4Mw=R:ً5iW϶kemWT鯬55O(|eqq p1G6YLҶ ۃ`ʨfuv\$'+,lڜ~oCX_q+̯$nUZP1J,%!#FǏ1UD!XC#9}B,wW^)Ũ+z]+Yk[yz eQs60lyJp L[ .X祏]koiE#@s*Ȣ4!h  goKt$"sQf2wǞHAp#`Z9\)r*d #}G䥲M8foԎE;;o[.wvviݾv[Zn[}7y$rLғ4sΨrB#Xh ƽżjXn* ٛ,D% pKll!)'1<FFX&ByN`gU $x㕢 #i|3<34Mp2yQJچ]:ߢwjnz^Hm9`O\Bsr%\n-ʫo.L˒cit Am,l$A J|L"WUv_M2<77jO(KKv& ;XpXe rLO)!;X)HEvL!ٷoi<ϔd?*Zl*շ}V{nvﱲ1?1'Y c叙<tSSsIN+ _HlJ+2!1ȍIX\]G,XHΨy?mȷnMy"qik%vh-ԡbf3,VF}ڻFv-uMV{`t\y%UHaN  2{#h#L1!e 20HPжtrϱI_s໳(f,$ E _,FNμH SmDe5O_]FWi!\جW0EE qPw3D9m .8TtrB j dI8 K7 f&wHc_HfN L_%5M{w{O惜F; Ub#<$:[=d1u+ûH{cRNтv@YkV4)-{.l&{BD,uKb-Zk1$E6mot$xnJݴ;I:(kWRnirvM]rI8kgmI+{k868մDBG$1\4XլZ8WYhׯ{5V.v^(-#XlK.Aw/*O;hnKx$'H`{Z]_F:֟2ڭw 43cy\"Z5Ůy $usciOak07ZSS+-ٛi[Eq$jIҒ~Ĺ_2JM?-F\[[D/vV~6H~ѳmۭlRF oÑAIGqjZս LPk=_𭿇E԰u5aqyyOV Ͷذkzvezk-OxArĖpV>[(  p/!Y}_tpv' 68m,5/zo 5]~KkOU ӥZ_\I7RKsi%ϳQpU%!+)QR4R5Zs7\qS\|jƣy*M)F%'#*~m/Oeُͬ [F5[m;QjZwW JwPḚ%-Zx6{+K:}þY\U8l-2=Qs=.o!3O]5_*~fJlJ ȒjKX]GgIi=\vC$7VˤZgE4m/D^Wexv{F#n~^=֝sҦV*Q~ehneWRn0wJ%ԨSqm|ڵ~H۾8nkF.Ei(*8Щ9rϝ5Sȧ*qQK{K-G@NJVxmWRh6qC(4 xNB.)VMGQß7ψjӼ?Znnm/,-GO^ ui-5  jBI&_tc=<=a(Fo5\z ̏OuM\j zMsyVvY 7"ivw??h/'7Kmc |#CnF&>,'`EҡML_JMB*%:q%5f O *)6ڌd5.LU<6*<ʩ:pBOi5WjRR(՗,ҏ|Ba7:e /ë3⮛'φ|W{Aῇiwzmރw]^j?Kxk-i{Q?5oLz/_Ǡ?lem^y],3 .l-cx=4}MZT)42O./hhXXC:7.ŶGCѓ\WuE<  0O]xJ>5omu=7NJ5 x_ԵsXX/ wcKյ-Wdž\j֩%x:E[]čc:֚fo->ٍ./Ajτbu++źǃtme&-z5Bڕm p'hêwFeߞQ@eO*% S5*_g)*gWOٸJ eG<$S{{/xo8d㶖( K7ľ ~{wx:u[&rjWvqiJ7Z>!irEwu+ 'TM+[Ad,^|SmJnb&.|W/uK/ .[NU>w-bյX{-V^Nm.olB|Cx\.V>'ſ5м[.M?ĿB kZu]H΋ U‰wkw󾭬jz$N")Ҧ*>V^Ф*LT*%.w9S\-+y{t9ʞ%P=)NWbUcm6^7ğ/n4Wög}+ƾ ۝;RhAu;x}NH_ ^w_}{JS?S^ N<*Ru - oiZ\mW.?4I|GZj)suSuSރwvaKmuYmUN1j|Eu})uI|Ož&q.ǏGխo4-Ju.<)ōyg)9aVJ|)'*Aʾq(TjȜy9]N2GUS JJJ] ƞ&XOd۔a2º'-t~;io k;.%˝CU3dꚇ-l-PGU4fA mltO kR~ x{@7O:?2"ndպMu$v%h |Ah66:~X}%k~(_ѭJBꗑ=+In>Of[-[C׍4kZغ_ xN~h6}}\[^iַ7vbEUH%9UWEΒsҗqf_5fܬr^9TnjBu!+S/N1P,6!INIrs[j9[? Xxs_Υqyh,u NV:_kzE &_MѤڮ~;Cƺ5 [7z$7~/[i%sRi1𵠰=]ah4[uM"& Kѿ~;Zŷٮv*ų7[iZ_5O.A{6i>%ϙf /'~kP\rj^3;x~>4Ӟ]wBK{r=|lf RjjIQJ˞ )a\(hB:O_J4 n BS XJ1<)7r(|xF/HFQ_RKGS_^=WWC[~%um, xvRm:wZZo.V>O݌,5K XU,J7|8\ӭU_j?ڶ&/:!&{i(+8 P[A~?SY.0~A51u ŶF :ÖaޗQuε1xĐŨ kw,dTAͤI Y+p>54ؗUO<7 D/| _yq%İ+ nIַGh,N׵SJR-Ɵx:6<-|K՚Qޣ%b-mqגKmq>fGgwu&K[x,FѮKT-kwsc2Fm>xb[KN>ҭ<Zh%C߭J'7^UN(tnc4*2v~<ݞ}mx,Z@c|/-OtUn,YImj{+_y.>8ԭmtsh?Kv0*\{qg>M2cXϾYu "푲j^׾#ZmU5Iux ڗ_RDۣ` kĒ{<[SyMDP?j5/!HSO^OKXtkkfbhet]OUYUu0rRT* ҇湛<"V*%D;U;QiPzIj.j}ZF,t]QP}J? #:WWWMzeykLm+X{EVU|?65v-ğ5G)5$K7txm.bA?:%ib77xE} OYa2t4[tXH[;SĝvH絰2Pc4P}{_| ,#N5h`ѯ|a][[{ڭzs kKb-"Y[+MI*Jg0xΕ&3^[Q'.[eXr% R[JMrߝAMӌwjRM6麕\O|Cj{e/yuA .h:حi! SA^u]SH1|I_ڍU&uZ˧!3?7OYkw:r?xnXҮNR?;Hd'gmoeKe^=m.<,wXfT/?xSXԌWWT[f)_xtݿlt( ZjX\6*Q狣WuIt+Q#8~ԩ).hߕڨsrP.pRi](6m9oZj~~њTVzT~륚Ŀݤ0p_ %2Z9*2x9,>5?OC_ ?ox>O M3Ot#wS׀&ԵI>`-%#խx_]vxdV:6O |9^zL.ymO]xun絺ohWqYkxoGAg/V? \; Du\յφ/<6A/S7UQt0t0rիeST%VZ(uc^F"!?gFSpMF2s,J7>ڿU{YK-(j%tRxkYoOFu&?BҭtMR/W4yw7ϊ8ggh79&JKR5׃|=r+}>N|$,Ni xKֵ ڧ5OAҮdkxvU8ӧTxrEB_-M>0OѪxCĿ|5=1>OhmE!U\TכEonwqAIo屚W&%)^z-u+_|/3x"]vÚSöLguAldY7[E{mqw=a/#٥[Z`$fuѳo#[[1`=^k?x_o;WK'Sм\cMMjԬu+xSʑtm.y>+<J5':K 9Q*5ބ\TR|ҦKiYaxZjUTVn~Əm5/q%ΕqS[<#ĭ)-F..~O)j-c2-ePFY?ۓikhlzx_χ]u i^.KxAg-Ah.ncËVD5 5=nVS4w/|Mck_Nt xoA'Ɓ}Đ^;RomKd[46֚tv}QiW/&W;&mwu;[T湺𽞵='~մ}"R9ldԟ- **Z񝿇N4PVk{;7&A7Fns7JiGrS7'&T#6`r^R~ /wό|wUƍax }u.+߈tm?Z4h,uxt?8G?wvΓxF[;+XksSjz# O3߆-k=_hڞ O!=zĞ>^,;sc߅.;?%_48>+k:i<|~66i{Et.Qks)_SƑN|Vk{q,|?k 7-5ojFeW߈Ew:o~x>iW[ [ğ5ֳWO+hwdlm4oOsC]g_Gms+_|`t3ˮ{ㆷ⿌~p|54exZҵS:?eмOwo$X?txc;*Gpmņ٤^-¾-+Wտ*Ή_꺁2Q@.5]+N|7]] 4ԗ6>J|[;z~(o|IuᔍԮOмk^2Zu7[-FDhjPTZjq*T$hMԦN)'7hQ$Yԩ$ɵUR;FPnJ<,i2T8_[u-~yM71IiSU? ]~(u5McƺiQ拊~rb̔$.[Aj*J)$)J1JUj{8(Er;vgHMŵ惬Kxz̆8Ouu(T-&VR(a9U$Dٕki7#YX( y%$Ȩ#׬EWrx[UKv$խg8hvzfy%gjP{$tM \\iYt &n8/ +N0}喣s="ƪABWm$7o}:Uf}vOw%g[TTѯ|9'p eGH\tm+F.I+sԶXq٥[oo8`Xp1\1{Ư"X݈bGbef#VN02@ n p*Hɑoyqe#< iV*ņ +y%wVvK__&5h=l]0HAu'nF_b2on$XpHl98EI\|IC 0 I<`J;<'r:rv'hp m-۷s]m迯sw!RmM}\ne679<6ˎroR>8=0HwQPA06kt3q<ͺI&ug+2qAzA'&iumJɫme}]}uO׸ngq,&:I&8?1?(qwuXnCer b1mː4 uJAj( ٘5䣕N@ rP2 0Vk'ھt[n~{ccb dIO ``yOUUL"P,e[ϒI 7Y!u .0ʃH8 r`F]$9`+vxpid;-+1/i\tvzom^m&~^yR ̌ ̡d&9o"X”U!7EL Vڧ2GoA ]$$)>sX[Ʒݱ(K+gGEe JӖRV2NNP1>b:bFI_,Ȳ[nmѿ-߽-?[Ev"ù plq)uxH㔰Y_Po܆Idx9Ur*c#Bv}\}813l,A)V6InָInVIV#i۶;@L& 2(6Vo]}nUk^4_϶}dbK"C|ya!rT})$tP2Y2I q 7٘/c/|%c*ZC/* hRc+9Q/&­ h붎ɥ~ߎ_֟ =نeYqvJNԛ`QoCPGdF+nHC:&3(fp!ib*ai$]" U&Ln$ I+dt *Fg؛beXްZ,mjj쵽ؾ}Dq(R URA#!"1ï E6@lX5C91LЦc0EQAc+irJo4-eM%f-aS$$2XZ&B'jQoxGtZ1NewG;yHS֊wG~iam].ש6˜Ýv8 5Ka2U,Xv*%vY&{":F7A#-Z&gp|w+̲JY>\(_%ʟ/PLf2Ƃf$G* .-Liϕab{tߥ{?=toZ;_~N{PU3ˤYrKppʮ7E} 0qq*'$-<OmĂG:c 5u2DUmU 9 F#{S,p+% PpqGRs:\dt|O[z/aSVGdyf[9U!Aq{f w?#t)!X՛RG;"jZ,7jObPOՒI[Mہ ꢞBΤ0bz]nN $FNiyasjﮚ"P`b!e"ķ0̑ZMRaOc-^L5ZdlÐo 0,0'ρ'焔mQfwG(HcBD8ݹ4HwlJ2n1Cfheao>g,kAWD@l! kuZۺKE 6|'@cX~k;`,]2 %@9I%Ai4 rd_-a|-EV[%~]V_#M/o?~-IKjV2 $ s烿sC KqKb#R$ 1Yhlk AiEnFGV1G%H>x82ذ e mXdWMҤq>ת at6^YUl譣Moӱ]z]u}^ 62Z`V@FC[pEg]\  ;Gd3k0< $0T1B/"R"iI+Yr1ӌǦH5Ks6V3_ t <{_/&RNFNrz6RB JI.衕eV`Ca[hd(uHX`UL~d#[8a{h|ۡ PHAU eB-nF^k+gpsj dA[fN@wK%i._Ml!O.C sv[pJL~MS-,qG(J^eUO8>NT^}D-pF[k ƫ omfpsB#ec!*BHC`gղ^)Y%z-oI-lj_VU跻rbgrۻ>\uIiE@C1SO]Kp0ܔ 9 ɑ kU gX9&#vG5bH|1VKQ*c BJ7.YXC+ |ɉ1LbS;vӦ<ֽZ+yy;]zZmКhb/,oULU(HeTH;H\yJ)c2rI"4(f'sbbmC"+Ac F$(eYQsvAԣaNAVُ6@{4{螭h#z7;J@ɝ!m~Wctb%lq#@`i'U[W`7-1c,k.H b408;'xBv2*H~i'd$/ |ĺx 0ZZ_f}4M6?m:4gĄ C;+喐g(23!2aZV,(ʀv1l1b#"]6# 1.g#X`bu⥑Id`R9ܤA8 +j]Kߦ[pӭ]{iFMw,AXaD`5V"3#˕LgZ0dɝ тPs&B3XoĒUH8+; 78g` ;'mUv]RZkpwNKFu{Ba89•qt#2kP?5\dv:ƣ `p32 Đ3$,/T,!Ikq gSs1ko.:-󷞿-5&P$n;!`1V0TnH+Q8#r(#$္cw]p 2@Bg]dNw 03rNkvIV諭6Kon`veFPq)'>뛋R5 mr28q3OpJ T$>\sv`Aas5^P@XmDw$. vMwkKڶ_^oөj-H#Ad`<–d׈lᘴiA (03UV[) v1ʟ1'\0r\4D}BH.DjK<7;.lT "6lDH-%kK2n5 h\K}. ?mkc=͟ڮdM%Xm JF ѽ^UݾVEkj-m&խ(7^>k+hބG?W w:i}x{',S}K.6wo->ح{=>h0\\ϥio4}GFH7vNJl䰷Q$"KVxd𝎱ew-hZz>nI}V!]BLv6\-w7`C646Re^1GҴƖj- ;?kޙdS~#j=}\~v F֗wN8˛s+5y'99Adӂs{VҴf/ ::4D-+(gOiI vuq*oII.Ӽ9eBҦҵOxOþ^Y[A}\j6aM NWPMT;UCoT4,o,4cPjk7DGj"tle{a{T4=#F[ij~usv֖z?[=Nx5 UtJ? _SK4x~h9$²գ^1{t>ZݥhSRjSN'N5]$kkY-N|.dck1qiv^i5;PS7Wئ$~0ޡ5zMΏm%֫X70 R>/T<%mzŅĻ-3}+[ki~%]R(t"Ԯnw{oP\vWOh<,:\ <_ΥCK4=Z;VV_dm>򭞷SOt-k?OZ艥ǫkZ@M:m^YƶkjT^ʜm*rO):|\o SeJO٥7:2n0傩S sQUeTe w%rRZKC[x6wZG[7[Ť̺~&xn[jODά?^:[XPC.%:~Zvj]kRl>ax̗6MwZ xkJԼ+3Oq]|;9E 2%M ! UMZ1]wsH8R*uwP䌜#:E{nQ%MŴg.KV;O=jjCʜѥUQtIS}  ?|/MoF "iϡ3X%ti:oirxQSmA.`4{}wk 4뛭~o(.um;Q5tցs )<_ccm. LޛpZ_-.?O k}7t/^! i$Լ9MGVM=fF>ukmhq^b:}gnǞ7Դ |F-/Z[|.ďXM^&? lu KD :9֣]NZ(F弧qV*8ҭ4R<-J_# /0)M1RsӴ^ޝxvZou>4 ImHb>s>Qaľ-54y-o <9K_ xB—Qu6|CO;+H_4-GFA\y}gz|)kFӟX] J{]i^]b 㾯VjZ5{ FM{[-.X0MΫ*kOxTе,.4ilt:RÏj4mo++ȣ7%;?qx:m2O=F hCI<%I.|M_Xڽφ|qR"?xZÿɦH>^(ֱwuwa_i]=~xFQ[]Z#s:YjsE[> nS[k&sE|].[[j7}JFtbj{sU9eN\U:U':Խ支(JV #B6YVJa ӔUj:Z\t)xyY*I¤e'G\4MOmwZuoAꖞ&F__ƿ s#iel>:MkS]BxGÉ4ǃ,֬|H"k&Myc{ |G`7/͞w&;oD^@ |8-FaΓ-[_YF&xZtkn]4LiCc_ХQ_Pt Le75̺mӥ|CZ~WK}y+K}^ݵkEڵ΅j5j,!FiӪӫQ(~>xlDUZ.TJ4z•L^(yhruެ$FE.uoBFxnYkA6Q}x^\t CźeƆu;۹t0)7:φ>/\> |B׈lR T4y3uhReqk݆ G{s熼_mC_x@Ϡ|.%T C =nxύt\܍>"@C_Y[{Ŀ|Alko%NhZwvI"|DsԂ#4]oK|7(]6vfeœ8ҕZץRRoa4%RV|E$Y4(b0V'KJruy8T m wi߄|MWL𮣤 i>(Qh mx.u=>SղR ?o͌]m~+|JӼ +}mkj^%΅K]+B1g{ԎdtOL0yvN%?+? AT>kmxe4Io'ƹW~t.-%.Um ^׿fN/ Ӧ_KKxogMK`kWtnO{GK7SVcV*T:V~IGA¤`)k/Ng':1!NU`*Oݧ:~9?e/h"4}?|vt[fW_k V:a~~}kR3}wE6?Z-u[{<)hڻa'?Y8 UơeZ qW|G5G+5"O{my> ׆Mk-~< ͮw-p!🂯|SZ>.->?LkF:6c}BV;۝cPUO_ @|Ww6'vZ9/;˝Y⿸<5J](ЌNSeҩ*tSB^ҏPY75R92MV rnI{:$'\ZςƝqa7nHԼAKeziCmctwkqLJ$ej^(ԭDڕx)㶱K[b|EjH) /M/OӼANxyzx_3h? I &|^#֞2 9<1/2466Ryb%gNjWajyw=RAECAF NpIF <Һ|wS^j\\ޱ(+muߌuѥPѢFxzwmrK_ZB[6ڍԷ5 3$ |+mjn%X4_-ŝŴzyDcMivQ_iwEvśnJ͏T>bih/t)dmD?Oa\èC꺖Yx᷋l_ɶQV񯄢ӒTӤ+:jqNʓYב{]5O /w aSx2~RrJIUgfc/EJ6ݵG|S^IsiYݯ[🇿gYxL/.-X&s>ڕiX/~Ӛ G3ž%yZmkI|-| ߈KԭSĞ>2xHd/y='C:N^b\&aVU! NNt r7GrrI٬!dJiS(++iVI̧(٤|;%Mc^"-ܱZǤ3 D'{??5 XI:Ϩȉh~xj?:^,l!T.kh!:񾷻;IaҝbJG|D}[ӵxN=;A[4Sx,$/|xw^#ћE^+kĞ;"k7?YfҼ)~ΓXi:|;ᯍ^>,)\xwFe4+l9d\>iSSclT*FP5+Qӌ%x8IJm5M*Q^^Wd;b~п E Y< 6Wn|Im_kzMW㋟ ZK_w>07d~*[ *k+5߁AzŞu' 2 }46uKl #ZҵM7> ա${I:W4+dMŨ+\WWKEӯ0i>-cutm׈A|Y*`,-%x+[M7~!h{ nm/EeƘ G ϨUĺSZl!a}RoG cro1j8ER,%5J 1Q)Mp4)({SIN7RQju#4VS/+Ss' U|+n$>x[60h-kHҼKk9P@ۛ-sVnXfc;5PcI!O~V~Fɭ|gmli>qD>dX? ]+xStG]xC6%#aVH<9F-$K[h,G޲>+v#WV 1#[ϣxUy)7jd{x._y0OD&Ԍc?Uºܭyms`lo 17q}3TƏ%duP,~iV,Yii v6='IKwl5H/3U-dd=<&[p{5NQ|޶&8N>ӌnΣY^.MY” m- xk{v!QeK iKM{Gk %<;W ͨY\xW&xY:q/ pHHXDyߊ ν/ ᧈm5 kV"%IXxKGQhvZw%P ɿxc^>1 +d#G4y -N猵]cּ \h͏uOLJ5m&v/hڶzuNtQ}2bQ+'{XVRJJmMsG1q^ZwVh|Pix?V~>kht1|g&i/ [io.u #RC+k}64r'Y?I񗌭hz|6>! wk6&uymk>6-|MėG}˷k&>KOԢ+yPƗb/jel"ĭu]o}\C蚅hP6m'↪5D* j[>IYFZ>5 2 ^?),miT)|T/i/dyE-Su|qjQ[Mf׳QqQwg%'+ҝLZRx_YƃP:Ƶ*| -T_/,:TkOyiRj5K?g6AMVǺ/<|kW]os-F) u(c6R6GMy|MΜ&$>s|Go5Iq!g՗|U;)tsz>cmnaMEgkag7Hm'WZRǬY]^ie2]ʳZwE#|6Rqw)NIs*7uP|/zM;be)K-.Ad_4)[iӌb=G{}3FtY^YJt6񅾟-m&mc+^έd[i Ρq-6Gmkz$4[ˍNuk-sV!U}*[o6m|7PTW|DyD?olu/hIm"ӣw4\ZIx~-oE7jf5f}$䤚s ]4vU8r&Qs|RRkt٨x~h.,qmgW2K$m%Cn*&hx"ر]*LmMK+/Mc\GӤ_kᦆfki%0Z^=I$Uu WJ[+UcgaqjZD]_Εj76ٮm⺵{׻d!=dz&xVM\xW%m|:-* V-$tlҗ&I"g0<5-9k%I^?^)Z_RujRQUz.G9|VoI_Kgۊra17|ʊX%i؎JHOR2ri[׿]%UP .Ty| A<0;k`,# p3ÒA18,w:>dFX XdTS}1Ќ: u/]wv ?h҉-]~EX>s 䟺~uM;P$U[h-Eva@#'4f9p@pM'Um NJ9^.|n$O<0*~Rﵴ?o]?N!$/PSN-F.\B˹bT ryQ_&4z+Gb6, 0>X2-my,%Ip S/^A @Fͫnk[o7ܖ$hDaZP E,~aq#s0kG3ťW Rccg)~Xm$2$5$ReHE20Q/o2p"THRA_Vep `:SRY#-aIRM/]OVOjKx}wpYuhK6HN|t}XĜ+c$ ÜcҾ\0ǖP`͂y0ېVwn&Rs[!6sr q߃qm0af!Q0҇hBny0$e,E[y<;Ƽ 80An V+$lr?tkerӃE,dYĭ4K x6ed ȥ%pcH' Eta|2}>#h+HEv=W4cF{c(V.L?f5;-A F4 ..X&)?1H=Rx,fK`>YRK3o,o.2RD' v Y5ɒco!0|e ,^i3]۩ E칛߽mMӮ&_ 7$!#jFm. ղS7  /:G75DTӵ5oowPrqzs=枽on<ͯ}Wt]\|V\n}so c7a ޥ{PK0X 2/.;fyp<P,mFTdaYlܯϸȌ5۠:uLl2JP&)"RATԓ604- ɼ|(٫[dٮV5Yw[.kVV|qX0ѸT[Hٖ?p)r[;p `m q ;}c'Nd Ѣ/f&H]#'W  bIY6NTbF\wgevp+ ]Mtm}:/+pDeFsS v}u o7JYw RߺP8nM6{=6sT&9Bo1) YǛ3Fnp"Xm Ⱥo0Ƭa 6mnF?yYS*M'A7~T+r1CB(p*>cyj B`V 2[nQ=8BFN!7I'$[K]fwinݟEK]8P1’I g09 <#zH=Y7sEEp(I # ONnzԶEm˴#qAʂz^XT[[m^{^%ls mVܠH##lIJI#qPy\d0g!Pg3#"ة  E<ghc$s$#ýkӶ+h#FFA2'kCAr0ۀ#: PBN61n2NTg`F\=';atkZ|IT,W 8dvmK(S1,d$jyAb@}x9 a scXghN맟K[d dOLܷQ]5ߦͮl-xY\_L$QAoxiN4dH9 +@Z 8gcp!1- L5DT#x%$>f&84Kond(m‘TR%(Iݭ#9kDz-;V[gzG)"E;U\<7yZXUZ6wogk{xbD."F`K3hva4}$Tkv_ h|/Z4z߈!l#n|K鶷UѿZekV-`D4[ }*H𦗪yuiE-fQS2StKnugHíPZ=JKiq>is{.w,ZZ ҧJrP|OW%.}qFB)II(F#e j(JnN-)%t)B\D'c|VMA-džGw31O+>#aq}m*{k7cO"ǀviϋ/4jy}^ Q|>nY-R-*UH<;mv4>kK{MnY#SK Ŧ\k(fgG4+*6֭F_K4ԵݚYǬn˸7<hZV3nyiWJؗz{/:NhF2(Nm84)Ir{DHGwX)7N~ͨyk*uT_.f9…OvM/v2=wLwq %u[qc|.:ޕ3I w:sjūꏣ6,>f:fE}=rV%,xKUI>eΡETդIf~%4]j?^]W|;zxbG-[X J $ xOkִBQ][C`[uaҧ[0K\ͥ~Hl/-|^*O)}7UyYQy[Z^ ~i׭,an/nmO[>:PЖ(e_yQBSRT+˒8V䩸>W+9UxOyc3nO ԫ*͉QSz6[ߎkg{Þ ux X{EP5]Ə)Q>wZjDŽ( _2kp^-xFCo^GmYGzo?iqwjī':G䲰&FյZ]'GմgNƕ>mğx&Wö~#)N&\4FFἑu(, WީxvR+[;t:}|@o|U_'t[1h:|W|O.YOa*etu-^A^ڞ(ʔTc&M>Y]ӞRIJ>iW̱5kJCjU\R(%(ӡ&)NP~?cW־|F׆su_{ tFNZ>_K̈́е.~&Kh7M"_ x2mſKN<16f1I%v3XhY_Pj=csxIx/<5;KojUޢ|Ogoze%LEU_?cx◇.m-=|vN[|Fֵ6M,Qu"K^\~?AVwS_ xSswYxG%^ x7[|aO huu|=wy'?Sz][x{H14$M3qއ}?~ |B_-u/xNsuC-?NNl<, :AZ5 *Hk/ϣ>o/E-:WF5InL^m,4p m#ʤUj&>QQ;TwR4U89Uj\IES_t~njxF0NZ|ycb tWNc ~+x; ~o8mu_zu<7>,/~^X|?I}+P+jSk,kFtH4=.75/)xLCW_!_NeֵjWwv!^.K++MoGo՞qg2EiV&=[~x<]l4Ojekz^_Zf x ŔKi.^'R BU]'QF~짤}޲gLF4B/k5*w F-EF.i(8ۑI5X|IWM~]_Z_>3|{6{HGÖXYmfjZ衸ĘO^>⺒ğצ^3Cw=lx~,z}K <$گ/ ]]\MՎOyV麕ΧkjHկ;i4Vz޾'֦m<3-sK?_q-w:u޽ZE:m"F;6PԠJiFJ߲ypj*^ʱѫN< TNPհ/ö5qrSM}?_#ޛo}VeȞ$ֵY&.cF/oms#Jo_N-HJxnFGW˦'Gi_ ]B+U[{ V¾5um6cP"-Z:د>$Sh>2jơ-W7s/[Q垟vCڷ!ԬLZH4g֥֢ 4O=McI.)o 5+;ž1֦[h|)ejvwWr4v42XdҡW%Q6s)B1}j*p8G~rPKѥ^sl5:G Wrʬ))UW;>~*'Dž/k_ KXůA-M.{%Ɵ~uz[k]7VShZ6k^0M}yim}}vBxķZ|vsmKB {\]sjWHWb?>.jv܏g_OAxh=ST zTG{ԷW^}| itn[}W^ VKS_{Yn<|NY]B:G^T9NYtYn('9+H0E[QBgҗ9:xQ7NU k:?mbRBYoVKo^mͱدO^%_h֟>(:|+s-mN5}î#-tKr ho%7/`_ \zE/.I4bKc,N <"ZTJv# %W(RF潝IMjR)7b2S Vj2)TjNY΄&ʔ\y#Ew!п<_3D4/įj7:}|={4qwq nokN/'t]Rus<JOI{ v>{ii"jP\Y[ zEg1xoEM&~#ڼQ[9{-BKkk# c |a~#7i5EXt|$խYͬi> ~BsjfO2ӥ\V4VeRjYjV%V0֗7Qjn ud)SuW}"+un.kEɴ宯oپW _{|r`wBXskj>%ݭkiGo–g.86ix? o{gx9&WbQͰ&*Xe)NSSkKN0𰊒Tӧ5)/g;E~h*WW^wE%|*W UO@Ēyݸe. m~Z5i[?w߳χuӇ/l"13G[ĕ ѦcWe|C^k"j_G%5ƅi_tBך>!u %oWß]kwv\X^C& 4]Mysy.կ-/#Q;?-|?g_.~?%BxMoOoQ]+X] [ݎo/ZþZ6^5ğx/5[azExkT]rO`<[_\}Cէῃ?~6ߴ^5nVcgWğkYaX^.ozڦφDe4hiSg"xZ(5G2QsVX|=E9bjQyԕIƭ4!/ihڸro2)Ɨ-*iN)jWKk|svjm-zk>>ouY55x> VᏇi^,:sܘ, |=\Mm|FU81;2ХZTqȑI"%NjBjs3Aoo֍O|k/ {F 4_ tӪX]NhǪx?Jާmq\m!t;j~mh"*%ŬI^?_é_Oki~LYJY" kp4trƵJX7NQPF.N*TZ~OYFkƜ)>Ҍd*;ڕRVMWܢ'z'!c?J_%yMԯ./ĺUy[qoP[k> x Kq7Èu}?'JPԮ~~F[AkZ,7c-֩Kkǻo U,~.joē}u%m";[m:/^國+-5oInw~ x= [CyΒiK]G}|u=@#OecxaۘQeV)֦&N-(E7[<+>i˒&U=]_5)tM'( g[k?xGI{m:۫kU]Em[}\׀<^\G:%}m۴b$~m7 I4X˽d䞭& .iFqO[5+N2ݜmnd+'Ҿ:zs/Kkz[%Դ2H,#[A Sk%+pQ?,mk^|Rϋo=&Vwׄzk2ԓTAU~/I>H?qi~2cStX)gxH*y):b+c{*i^ߊ?WdxP/}+c,RRD&8K VKPɵo vF}LZxKG4ꚮ:M^I]_j,ӵM_2XxSZo>QKOh› SmoY|PMrK;Pkvwp^\kfrl j8F|K1|IFrv:{J%a 4* ):Zq_\#t Sg}*"xG7MkMOY4O M[ _%ΝuZmNY\E,W^9%"x''DžWdm-Tx]KcJ޳NaNKX4SZIe> xIaagv:$mO_:X`}j],V{lu\4WA/5y5/#/"6gO42h.dDH5L5 HAՌ]58M>e8rFIF){N9$|tά'%wu5v9>H[Mht-G'H_xO S\ulZ6r_ ]wu KƱe 3 !|!Qzz%LJxά5쩫޳qI$g.W.Xt]O=s|co/>xV(JĒx|-/t5|W_^/&yliiq,wFskڧMƄ}X$ Ea'ju)I;_Tj/RN23ycl/C$Зþ'A` .TЬc߈tZVխ#-IA{G&|;mVCtM#Z_]8tj?zܒ{H Jco4ci[&=nM犭{Z׬)hTiTK7Q҂J79TV~^_kGo,K֚Ul٠NӣBK=zQXI9@ٝy`U {7U2gKh䶾Ԓ4ܵ㔗Nk,oJK}m[[֯u/uDOiOl/.,t]\x6L }_|W-7*,O$N:V=];—ڬ-."iwgK=FQ_A Bkt}WV@ 7 .}-JsӦqqwnNh_3mTkҜUYkmTQ唩 .Jj)݅m-Z&CgCAMIӍZȴL@$ @VW]2KiU̡kZ#ymkXo<7G2C]J' RR}YY4WB\3:{=UֳdҦ;nn7oҞ'=ŻAr3+q6L_ʢ/(*vǝduux/̤ɶ R^ViJ욎JiIu[H2,pRagD2E47[NDuUΖk ^>u5`X-]XĶrA01c1X!ض0n7o$%76J$lt 3\$lDѭ[%In2vHISgHC|MEJ쬚IwwQ]M% ;]JT\uY|-rF]lu{&Y8B0G F-? 'n@r@ʀz2 ]γYAw ZRu=a=>u],ۻG TNKnj{XK.Uk7r܌sY4կOm~ m!`ܠ1P7bF<w|0@؎  1$/lghv|0s;TV @xY8`^49A0NࣨO]8 n !``x.; In0!אîuyk׿Ku`JZ=tfI 9ӻnKyv!Vqr(l\Efpzdr'=OR gI5p0[x<! \6qqimU馺,b 29V?wA$dYYUh1) WrHfj>rݷ02\E3|W) ˂qAR`КI^Ϧh޷~[4&K}7ܙ$X%p5PQ7aBb2)lUZJC#RA#,  Ҭl,U+C 3`U\J9K@bG',w:`v_t^{i/#*ZéfVy(XEA``A%vn pP(RI-K%b,/ D 8_3ibyB<p#i*|,HjG{/'}Z+Z[et,qIH܄*&IB9Efv@芅0%v>SGo&KmmdHL"0Ĥ呂m A($%W7<u# [Q/b=4i[[h˧yuMyxtYwt-bnfR ʡ0-@9uko y,)9@B +Mym8DeG Jҏ-"u$aԪI$ 3G +k"@'RiW[i>R:Y[,iFk?$#Dq% Dq[fv$M*@g prsiTC/#dԯ)`R&o-LsJUPc>-OɅ$s\.-JHY]9܆mJ[nkh8fFnw˻!J]Nͳ%!v3ЌD [ ޭ2Z$s!oi2QAvVVA '[hʌ+86IJ6b8eܥ#Y$ D;T[}}:fe{Wj՗I!_ns7Ts6h~lc6 5r UpPy80$/8VkeS{ Ǘ;|*N%M W'il3wH/^{,w!##’!U|1ڵeZuW]>¥H܅b1&'[yK)в ;yI6WW ri[o۴\$S$Ȼ[qaH"ɝAΓ1 ͍@ݝʀ,!yms[mm׆OwOfTo忑Ф{#H&4Yvui6-#L-jE)sM(,F ۱+ 6ЮPmW*g#ؤe]˂I-b }\hKxab$L3m,g#2Ӥ%v|-UfJiewo]om7/,dC8BO%䐝;QrP9TKTErB.!!ԊfZHG 8(N;i~z;Yid}'S!`nA #5>TliZrV@2,csG pX`Lk1>o! ~uRD^NlyB'VC0<,=[ӌqOb  Ti#c*PX秼g$Uw`2EE2yqG4t8Id#(IXQ*^*mIr2bK""8"$,]($B"(`(4_Wk~s:0JH` ܧ ݖxذm~]Ā@I͔9Ȗ{#hn~^[ VE1֚jov߸ͼBF2ShB3&G*|ds)UV;N~iBXPgB cvI#n p۷ Irv ݿ~gN;JmrMv,s%#_geD]^V@XNarr@;TBwB+fRcwPF7"` R%*"YUYA&i)Ws#';b @)/2N& \pA"i*8skw H8ۃgt\K7Il?2['Xdz`Ԑp1(q;XI%RH1prAQ݁g*XyT?/;gh$cݒ  R ߮I*Nv10NwNׁ'9s'rqKר 9*?7$KEꨯJK4 IB0~AX帵HH!ES tݸdA(G^o..a奴aI( ,ё kHo|_^ˮW%ytח6ѫ 1ckĀ(]JHGg 8#ڥ$UU#țaMLb':&9HKlMwvUbv21F`Hዉ3>!*X+ٰ.x &`e -?(T"-^zn[Yt{8m)1fs0#9dTH"Vcfi Kk--lRmɱ)'IEåMnH9Ă6,,LِtY-˪4e#%Ղ2vz.[Zz.'*".ZB=D"ByGƂ)G"^t-.Wq]ZoќujE&oEg'},Rmٽ]HH-E~4ǧqC dJ-sF&KZZ+oҹgF-!uWy<{c\HVK KO&upD.$I ~BehɈ.Z%a/4BQ"+HR̶.6I;"&T>}⮴iʮV:qo65.skd)-ٴ-`[ }!w^frkmRia/-")e=O-bmCO5^4d mF[XZx_R-/RGDvsC2Xi:Ju~]NkCja9^izܭ6}jiWq$wvP>&ߟgGǨZ0Z4h4qņ4ٖ1<d/ "Y-oLq|D C_ߊ[=gðꉯg#Akwm#P/EzMƫ[YםTc<.ZjIME7'iJj Zgzu+I֩:'JèS;RqQ)Biƴ+xySM iz?Gyulmi_OwQ\^$7ZhpCh...$ß l.<K}Au+?hIux-58<4_AOy.kK=miGi>/iuh=֝o@e׆-ŮƺgWś4DG?zwý[(x{u]^T3jWa ῆ#~&i'xy&^FIS~P(ӝZSkFW2)N8: ӥJ2n4)Fƽl5SՓ Fteb-mt7ZԾIB{?햧Z@!47D{[X[^\lX]O[]6t;uf5ď>xPyz90jKizGMG]G<kmwKGx׾(_>oĚ,-d5OisΩEk4u޴b n,i?G?;ݖ~z$^&w)j/jVNϊn*O_oiP2;jB'z uF*#*gN^IЦj)%*ZQ(Pa(N&5SU%FUl)j59{)]ҼswH5})o7~~ĝ:4AƛaF|/x ]O`:|3>%Vľ ,>X=v/f^𽶙zyusAx9!{K;Z}/Ú8nak&D7mx$3+*hn./mkY񴶛vJն?~&cփKzEr?%lOMT,'nbJ5 ibGZ8H.*JAKP(+.EIT*rE]Sv\>& UҍEiKp*1)ьTWU#*Gï44~ C{oÚot|J\x{UŸY %熬5M;ijk:1ŨjjOG:x־:5/| 4oVѬ kS񆗪h._o \\ZO:mimix/=7¿FsOahldJSu]f!8ל]uU:>Y{ IS)ӌZ/xc1 TJ:2sQe)Ӵc8$֨J7߆|?Eyw7SZŇ<]E件o/!g;U:^,<%]'w/e٠ 0jOxko>+M5h|Iuz=ۏ! XmO !1j0YW35]&7>i.~|ZyiV SiygᥦOY>}) Nд,ckziG&'5'0 6*hATT+aV%+sUnSzaq_SJ,ȼNrSغjՌi(Ԫ:pیB0Q,|E^]#Fl˃Z࿆^ noq WO!{{r:/uMKX່_]4/pfwo.T{3k6k}KNѮK驋RIk:Qr ŶJ\ҩVS'Uu%ySc qRU:SRI%Z85(5As֔fb{HMF2ZoM:Hǟ>.e]xgAucMK FeQ:M=Bozvy~Ѿ'j:|5{-5wIcsZW|~Cu]\ki%1}=OJ ?A6?W |?(MV(VW4-j[cV[RAڼw6v~῀FCcsqo*[k:K?/_|Ic_iMSO:/-据˦r"5 bGЗei( n%%>y|g. 7vE>+Mιa^ 8Q?hOSC{j>nIqx?:{(-n.^ዻ;-/e/kP,=N9h 6:4X[h]ZXxlnum6O/G2Ζ8< :V>#Rhބ\iu*Js*cib-{ F5k'(sssJSE' OmwOF>Yuψ9Qa^%pM6 &'զK]j Ih˯xjq ˈm [5$EOqS_\'a<7 ص T4K-#fb[BMOKӼ#si^kw>c4Vux}CU}Z =7uqQ*)$&g%BunTWc85! )Jnu)9^7TdQIMJJϙKm_I?M>+j7SSP yg{ci^YTs/о?}B^6v M>h- xG,Q\XX_}xJʌ?:HBzj^xGM*jzFcpK97׋txSYL:O:Mai]n{ocO xy/ne]-RQZ0J4t T8J"£RN}+Bq)ӛUMӟ,c9PHTj2w%8fp|_׎ui,֣cuWrͼl)k8g{6$߁^mG׾1i?/I~܉:¯ 7cӣ.}Vp:{oiu[:W#񇂼=v yukk/}+Y]MerH}/9ep^0n5ՎYIN i9~*RVySqyAJ2iFxZsqqQzMY_OOWּiXk~ *6B𞹠&5OVkwc|'K/Oѯg6n~˾<-W~=x3, Zױ0_\귦_}ⶂM o~SSXωvW #^jzޫ?tTjR|~$O>><мI cm>yxӟEjE#Wchć=*]:[i_P.}*̗lEkhHkyHhm7[EZֻ\Z׵mnk(QnHҾh-7^/QM$>2|?}x}kKyo$.}\>:n,Q|-[:뷺KM +R2D8!YĊ^I]_o-/ÿK i[|I,ƃoyj:_RN+&O irVk{Ka4[6ޓ ggccjǍZY鶱Ztֱĭ\o>Gm=Αcĺ5]2ðXswemw{s _5mOźǏ/['Z'_Y47j=S|4[Ur#9LrM"Cxv㍴.kxSO-%ėdmG%|K{i=J{BK{-wMOM, 6LC.+ B(I}k8+Zͻi#3Ub(4IR 1_xZYM4&JZX>"5c:sjFTiUPiI7JIDڛj U)S8g Ppo(ɦzxvҌi'>4h 𴚏o[⯷ipa&^"ӼAq^oSxgO5ԼЯ4r[~+7_l.n(m4}*>mOJt;-MJitk.׼C&ڽhj]+4Ӽ?lSwm7+jΉ'bl:ΓjW/ěí?|%^xxÑiWk03ieYhjՖ 6S.WT:ʔTPtQr֡.VӜn(%I'9h}XTI2ӗӯo&d񸱷帺Ӯn"4E{M2J`{sDe۵}/DF nz'_R^#Okw'eylO鶋-Z{8~ Ҍe SQc[:i*~ࢮc'kӎ"9rkfQ`IMZrSƟ|U}q_Oi~%kyR.Mȇ1,Et.%G58jp+}6-5.4i[ՒmR 4(.C̊i.Wa^о<0p.[$ teE-yfhvB &爵Oƙ7qIj4Q~{,N,>p,}KRI{E]ԴM6VZ. 3pQjt6ӕqS^3X\vmg} ٘e>bHe)6Җ8]Fxa⸵y+5.r8F}{LjUY`4yB9oHko(IlųRpS/ŀԵ i]>Ymmo@$hfUʹ(܁+%܀bM.X7d;J3u&wK$+9sNRm;ͨYFZsWI*/3&07 eT1ʓH'#ۇK%R3 BQ{&◖!kֶ̇P"#{ l+n Rͮ}silm ^uNdIﶉ%0CY fkhPK%O fh'9*rqRkiYI%$fݚvnWh($⹮&u6kf&[̎0?e D%I$䝣X.ydl2HѯcKK5{ LHt6$ĊdIߐdS$< qng[%䃃ĖO07A+08N2 1@Bx NFH)ze rqdpFr spI<`cLX=Q i @8$d%8``gۏ]<.yʶI 烁q;lުުz.:n8# Љ O@q 5cfZ7ivײ/ѥ7:ܟhO*۵_-j:Sewe+,6J?@pDb" 6٦"Ԃ15n'n?7"XǷiA*^F"cu qg8RI%X& 3=췼N7iRZjjA{S*Y-Zh{5{'-4om}dpذ9LFbfba K%F\$fv0.nw;ߥ:[|ʗ*Kvgye9P`®s[t$U 8 y5$GcrQv*2UA"ؐsA 2 8q rsu~_5#E,C*e)",p~fʨ bTtU“Tݸn8g$c&X||ϴ" [1i,AU,ARa?tunAl88z 'ERM>-=5۽'1kmoAުWDdmu˶[y8i&7=ɒv$mр9ʵ8!)fn2 8, dN\*7N(@U;G*G2O}[oϡ_8So$όMvLp:EKl}$ ˜c=L(@h H'x7yͅpĂIY3vwZ饇_=̀ ב#@Sh>[I#941g&2© zvy8=[q#1Rp^ :tg  2G;A@4o-;-N2I r;gp<*9' =x9y@w q 2$!zC8ng@$;g:_Z^vn8@27a 1 @%#$scP09c13)=0{ 䌎xV+ N7P 'es9!W84kK%l- ۭgܞ8 p>]`.gi\O24ȭ.ʲD1]I1DAlIͪ)Qq\έ,r2Frc^Pu=oP5=Aypn濜yD.n&1qVz,lg}{l路Zn՝vkkӿ/&kФe rQ]ܱXpM,;sn;W~Wc0Po8ؒm 2Mnv-`j)]Amk!m0I5 6%a("E!{s#%ͨJڷm_tob%.XgMkgNvuR,"G=8DmaBfyofmIAwT4k-Gu^]VO_k#-?H mྛJ,PiVNЏ=ݗ45qsIFɴgtӲmԥ'RP4cڕW6ڇj;پi$hWv_]_iEog~%3F"^)oq2fŬw^ou%8Mv@lu{t YtMz76SKgsk=L[iWk6?_Z0C ׉!MNͽc}n+k (,a\m0g-݅&˦ef{KɂlR;Ux$,R7 +hӲw\վUnf xN*R)^mnQqR?gETUyis<=;/hБ|o kU;>t xT4;b)Mܚ]z}FV=Ǐ?ia`M^Mkkk:~lVz& t5k.ۜ-"ַ<=qem_cz]ZCտ<%ѦZ}uwnV~x/Lt%w~">s^]YyWwړk `Ӵ\Ci6 KG[.LY`{9s8mSOW777gn {%bTrFS|>% gNJJeJuiU.ebjW}/dmѬhڟ|CxFOHGgX]BizǤKk_Xzx~>)'_UU@2IoI6e&>!-5MPjQ\߭הº~? ^vPj^2@_} NlXM:|OZGm>k?75NOWӯ;ZlVoAM9n.gW8jMW¤iӌxQ*sPIJXFV1lq{H.P~ޥ?T)ZV(x>C(|3M+H=[kKtC@Eֱ[OK\t,C횬sis·m*ž &\ ƚ.&| |mo[cih~7V>m퍄7>s^xㆵ709 q~:}冫kmFsCOYo>V<1M|?`#qrOa7߳X|Mg&.ox*sy V=L}hо}5(R *SeO ,N#:4\}N9vUgUJqNqQLХN%k:XF|~U\ϑ.2|V%ּGR ~U|/__χI.66_CpçI?\ivKǡ#K6V]?T5ψ |KSAVך2il_|@)E>ޭI}<^K>;Nx")6-:~zW/h:M?|c+jN:U ZhoW_ӼM=eaӣnn[+Hmm}!^zٮ3wj>kD5j?tH/֑W%ݾu_Zݶ=/To|k~!o<3A"G=[F%α`|=|GaIW/Yx㲹xM/mIJI!o~ Zum??5ᖂN [i]RJ:}?LXh4_Uy*> ִ-;Kεk75l9|_?Ú_ksQMGoeaiÏDjwzg=kW[m%wWOuMg֬~ߴvhz(AOTtF_XC'_m'?35ޭ>#37m/O[H:ek|AmI/{D6gn^ExĿm/A/tVRHaaM;)>'x;7ͩ/N~ldғE{}7G"ӵ-CKx#Zeԧtk-WNOv[5hK'_Hվ]xm7_Ӿ||.|@u_V#T:L+5$"܍>ẊKl V<<*Y&IԖ**z8u(:mI/J1W ?-9F+9SfI)޼5N-n+_K{I'KN't -XmkgU'iƓ4[y,=n|Mc//|+{& {OyY<3{"=Y]u,Yoi }-7Et+[8RIm,&$nbgW+Z[CcwS[dw){/&g>X׺Qk:6gw=Οgk\_FςTC(T"R5aф9iTB3\1r+kf+Ӗe*ue.g S:#~\}&_&Mڧd-A_|]6ۂ~<=-xM-T֚tVw//o-·}w%/Ry%܎Ν-5:>mw4yM'iGK'7:5J7J'*ve*q(ǞKo)*Sm{ǖ*j6MsPLM4_.W^V8-|+׬ia%JNKĻ}?,x\K}WMoUݟt jF(tnDMofo+A߉*OԓHZxzH$ӣ >$$S}Hvf֋gi^(O)mV ė k_mK5KGI"kk\[>X^!m帷Ӡo7+T׭:UR$SHҤ8%)Si.iXҜmU#$+Ba*-cRu9`~Ǟ񋶋4䟌Roë]7XWFn~7_:m]uKJi7v2붾#խek2EO%un55N+jZޗ/GoSYkokˣui+FoSC,ZQNIrwShTIVAsތJ*'=pcV*ni{6/9TR-B:xľ53w> Wmw&9e?dA*V8ԪҫNn>zu1)ny(]x.)ܣGSvםFhS+hkOO%o=ʅ[~.^#x趺6yxĶ[}-C%򢭼Ogbaj>1 mWxC@.-̬+.K27h$)Hi2vmũ$ݝMݽbi5hI+Vݝݝֻ;E^V'h&+y,499 o,!q!Bz}yi $..6W?\Z_[YM*~TJ+K̖-R'"Fpԍ|tˈZ60,Ď.n-Ko< -A(=6V8;r1#Mh{E}֛u;hDV蕯mck+Sg}x!x{[&(dptx$}C!I kںK-Ƨio]M hmis^T1I&x(nǞ+(ɬ=*#SԾFky9fnZ|]mJ $;%1 ĻgjdHĀpv`l4e8QF)._yMݴ5[NzI(J)ZќiӍZvm+$~@G|F_kz7Zv\WoZK ,@62[.7΍wsz>}5iMt4X{m4tOT o%w~ECE|Ca[ŝU!(H LhblklKƷfW!trM &)uvv j+AqiF\VMZmI;oBTխ$~%h[|?- u_O4Y~êxP`۫-sljV g~`Mt YSPпfy iuiZKk>Eayy  7\|JQL}nm^jP[?nO9"XmwIJ#mNXҥcpP̰ƒ" /%yuM#@H#H#  e.U!49MouQ[5&iZj;^kI.HZmkw:dx,dX^S@Zw6/j0NGn,#{}.O<c ? ׂ|#ha׼gm2/j>.m5'Ax^QBைƖ:/<7 \_YYE(|I ee⩾$~ JQl5iۧ pq7ZWpR IN r.h)iQ'NЩ(bg ^PPN2TYǖR.v_ڗ-]׼5cOQx;_qkm.ͯ5}2m&m:HKe_ gj^{? vl~>x+}WQ-5hkOoŏ|@ԯ}6/Ef <;osflŪk:H i<$WʡΜnsFlI3i­:U)^/J1RSo+J۝h(9|0%v˩%[Yt83J[,gs%%wk-Ivwi[8ߙɦrwgO:maycxgYGh*u$ªG!VqBB|3< ~xUB%_64yZHHهrJ!|*^Ij63C<7%{'-aDi l ฼GqiMKXF|ͺHgѓ4UܝZީUrjԝҊ2*jJ[=v|[8-ԓ|o'!IxV+71FX(V2Wy|Y7*d&H$P[XK,;y2ȊGn^C;9W|X I(fs6@{h[ŝ  W \18t .o9F+F鳻jٽН"WFct%X0q#Q:jrb([+%ݣh9dKY!o&*tWΏ9"wTxNIU6pC)8 8$jۮ׺}S[5=a@3O#Ć^)0'zy #Khx=iOrH RqW_/ YPD@cn9=IP2 Ob a v1F:``wF920/Зd<FA s $ :I.5d}V=j 2 vq=3دpmC@$[ň3 Ȥ<ܤ%TdN$w)LIBĒWPHkIV]6`ePfg|'ѹE- q9?1m#8`[.UzurArr3q3m6a9\rM4ZiV/_wFMe Prx2J 9vhi[$qH2ހ 2*GU!ʐ:N mR69m9'*6AZI7}9_]}7YyxcRx}T\pp6|mX[A,(&{)HI`Pp\rK87gr"2[Dp: ^1o`˵U#DB-4v4ik] ~]-+A9@P;, јͻp2YPGe!aP<Xc\S(.,rTdݺ9<5ۼO>lئ x zr;t)  PU]_[m{[4ZC˫K2UO<2_k[ -㇆@-d)ð{h2y3"r8}Gg;n!,K5ED "yB蛳s/U{"B]4䐖Rײ0Tg].VKF&+gvdž}4J <# n*VcV`XӕE*̑$0(4 VKd;29e1Er~3Y>FA_0<2aF썯"*,J@DJ 7r.IPwTFNW'D+?HlɆ bêm{T\ UB'c@X&A?,DdQ\c(^Cd*w@[+m ĿHbB I=vXiIh-m۵%b_fw[X$2;G|ûupDɎdi1v ~RQ`0gy@0A916 U"8VĬhifRN0E_Ԁw/ -.ץzw tre "e5b eR#P۹{t<x;w$0'ַ;α,\InF,(jc,MUTqkn6ݟ]UC7'_k[KצL4IJ eiFrNJb?2~[+LDk*FYKFZ$;ClG&ܡDbE"sl7p ҭdyBJ6cpXdԫn@bbj0MJ{onӲv몺kk3'e73,–Xbpȅ=-oc<f&th-)йXeVDC,K+$9b FJ, f8u"r$9KWF4[[GŬ%nۭPٚɚGgݶ"]TD:Qw^-]SM.Y]V]5=I+2;y%i>Bv,dmH[z8Ik&bAS:!|>P)6_1,h:4]?O`[gekI໶,mf^Ug/IYM&6 ni@oVIM1#IIP2).v/f4Q#aτ5;0jvt}[FvH$ 9ltMZR+&Uy#FkG  -Ql<6βew ZR˾6SZ4x5__]\ݪ 61+;5Dl.<14͛Jqu (4}[i=US)BmN w]&v|zXi6DκI?e"ǮΟ܃+$Vʶp<1iZ\V^CMI hƵm } Z8asw\X>[5ͽY_#O?e6D'TKX+G/tvl]G.tEM&ӛ=Z / M>o$҈)mlja-[sikZvovpy FUkymlembΫu,vة4ﴟ,ZUrӒzu[P5EuRJ%IjmBjIAYӯt(Qek%57V*E;}FLܖ)s6%$p!Yx{{s[jpjo&}>g%K~ų2ia__Yu1\kvڭCxnTM̯mK? 02xlI5IRaq{m.s\M5ͭ{Ş񖥥EubnEjfAym} 2hG7&ZN-]^6mYJ-Ytb$#UIMMF>NtSkM4B.^uKiu,!oL涳izngKu/[][Lfm6[=CZMwL{|\cm];:Om: y>xiBݮwm66 mu;[in" w=.+Ym#t-cY[-sǥsGM.URs<Q?ڞ,SCQ־h[MlH ƥsu\^nn.X2psK|#N9WqII5(Q3>E TR\MV Ue*nn5Tjjn$Tn.|?mAt_:ι݆x3ZΡ#g>sZZozeWaKl5v^ =~VÚ=~7UI:Ѣ֞({}GDhC^[m2ǺGOԬu QEOĻ|EK`W z*B$Qxv[P!oo[jZfzޭگ$7CجflRRsi%Rk%{;g(Ǚ9h(85ysQ4jWsQ0bbj8VtUZv%咕 B!IROǬxĭ+Λc@m2 XI-νz4xXԬ+/|y?lLeAZVY֣7{?Z/,M/ψ<5}XDs>o^5coF<~=Z(I7~|5s| ~ZZx{TӼKa{O k:H&"84M> uZ4Bo" 'hU8ssp)1TJi9rUR+Sy{媨YңN! J4}i宿E5j #a'|H4K?gⷂ<=<9"~miͤ]3Zh7Uf>҆=Ou3i:]r^!Ӿ.]kzt?jrR_~|@_47n Tx;. %ψ|m^&҆q>j$Э5+kh-hmGĒۤI3L<>*hʜ0TMJTJ%WJ,<#ѩozw~[K%Wū(צTBOYu\d9r΅{{gősÚ>lg iL7:Vj*ukBPEο ~I -GJDž4Vk]ctZ>qSEhŧqm/ZvYxBC?!/ɬm."qV,tW_MWU{ҚǍspYNM>">=IEs"hWx4/Lvy H2x5|JhE[z/&B= 8 {^JS|)9siU:rp8JJ.<591|NcSC u.NXcO*J%YEqŸk:v᮳Ú3wix6)4)gIжLS6yE4w< _kM$>_~*M["KXG;HNKOuZO3Jm.n&`Ӕp^>݆2TnV(˙iSSjVa1j)U\<=jc5J'Cpԡ)6QRKg>!/  5hk[|>]M)d?6SxK;->ˬMy7sN_h,<7?߲ĝU0&<oZC5KI3iW{ڼ}-Q-YQ_ MMU7KR{-M;6/IҾ Ϻa/|MwaּW&5۷Qsժ~#'94(yƦR!)C tҜcb9X1cpu^Ƣ\e̮1*XzyתJR_Q2c+Gһn$G?ÿ~ҼQᛯ ?w|Ex?W[ht@/GMJ"|=wsy2ךxǞ(K״[zJ,5ZĚvt >;/I}^:N KBG 2IS^߂nN:ωvi(5 a-$:߇GZ\Mij͖׿[~/#O/4 x_]ƫ>࿋4bIim̫)EcNl׳t7 ɧN5jk u_*rP34'O-*X)R~ nR!8I+ɩ[S'kĶ>-xgZA)h:ւz{;B/g6Ajz4!-3|9{q k{SԵ4RM?׺V?kj$-ou&CՍuG[wşޟmω>:LV.^$^oϧ^mRIԮm/|9{6O)oVkz|q׼sZ[K1oK4=:5|? ?i-"kVQʕLRNPRJSu+)Bt1Tp1qѨIT'cɇU"xTwfO3j4/wY+ 3wsMV;?yo!-b"N{ƯE|&$vgkMm9≾ q\?|!Hoj3ݫi7=HUNcqlSxZel/ëj[EO3]xMңM:T~$=x.[ hzqOU5s/ںl.be];jwv㟉{q6uM~%WpG[::rrpsupzurx:N ɪ >jfԧRBjjI'IRqqf-[;K?ڻ(▷c6=6Sm̺~4=GO.sXk\Li^7!wwro/S_σit-BOiz?g=k[Gtdڡ'RPX{{Ï>|E(O|`ҭ,[4lzxK-,u /PӬmn/4o<vG5a6{: ^Eıx+ ZZVDK]ƁZZI%ի:4Gi/Ǻ?o?f|8eFE}s=IxX1-i1ZӮ,dΟ 8pZjuhIT*1357NPY6PJt;MWIʎ`OR\g ٔk{ҟԥN|o>ž4?[O?zdkڟxtZ_>YO ;+(յ 2;dԴ.-lo2ǃ"hu'&=k_λE}aS/<0t} Kx[k}>u-R?5}:V񗇴kZ']m |"|gbnoiw6OedjG;h¶C i%tHuf}.|F[gwu5Y5$SiG9 9XJyRStYQkF*IWKHץpkb.h)b)bT\R 8]9J[8s+>5y}45-nL[htn/;c /kԼoxv[&ԧ?o>5^K(Omo=φ< FE6k,񗂭uG햷OiZZjW}0?C7ÿ^1GM'ĿEW1 /s-dCBM_떗aw9K V->xPվA|ͧi/¿Mf YKs-Yc:P]2=@ I8bc,c rG 6 Ywq*@d?6qf妕-1kdt8yuR`Rr w]]dVeiVKi&ny9'niJW|^S:m:7|E^riZ7^w6)X>8#|0v/aKĶ) –.lgs.=%d-և֖;u%67^Gt/umOܒ^KkqVΑ躺ZxK5]R֯)4MWKD5&xH٭?]O|ZW<)U|jxA-Ǩ^׭FNjN^_|3oxkk611iK *.73rr:c86JimHR4rFVUzwRjQ I{%ʹg/iS2x7]$wƩ%][bRF5;ukCԵ-/_t{Z߁/m2׼)}OSn5==C_Şsm-CoaCkK{ ~_ } ?cfok?Ǟ.n`kq/sT~DoV:&/xvL5rv\!Ɛx'M|GxVڟ3X:iwW:~{|~zգ北[Hu;ŽbR+JJRM8^>42yy\߼5((9ν*wj[5%SIJt6ۂqjI;Ř|?}Ro|,Dž|gy[ƗQY,vKV3DfcӄڝƉs^oޅ5iŽW0IWi\y|φ5f->PԵjZ]ާo\ZEAWQŷ LO&F 7PX|O:߄EƯi5 71;-,m5HICZCOӼeaKE4WYkwK:m&4}Mxv K{#B*)69%xEd^M8E(9GK嫉NV)viN0Q}.y6ޭ]|Ox@(E:5߉yjĺ[}s]_eLYcix3wv ~[+c5AX %|I:ihf3H^KȊK%-dm"KqzYKTmCGeg{m3Z;f.T CsWgxkT~mgE{KG$߳k!Pa[q rƛ=Z0urF6IJ1t\Rq*My8֩n~j^y69*tGw&x&{G[ծ:.G<^I1^G2q{b#V)one,{S,XDwd agY#Pm2-U0hYI럗ͲH/K_%eYʸV9#.c- 7x,3#"=[)Fĭ{~!EV@ i%ȵ(7;ZDnl^풲Z^JiZz)-nᄋmA 2_\\P/%%YNq`S;- G"<(i3ZA$dum pu" YHTѺ)bO5D]8fU$!&EILUP*%e, >a%fZZٷWWOwnw60Jnqa>e2(t}XH=f,m]R;HfjZ0@61W&("_Lѡd]ϒ nU3Hfuv%63: HYZ"'\2pBi>ʡHd^9c] jOi[׳ mo3g(g$BF)l<3+)ޒ`[sѲ2prG8{}-n$j\e$7c+IvcqvӈKy^ 1I$r!VV`B9BJKk^{YzwԈrǣdu<"$@  RFqpNOx#z `Gv92pOn7wϦ[?=^2U TCH:#p^Tp:q= ʷ^YI>Q?( ZIG=G nj,sQAǮsG@qpvpz+V8c͌Q)`c(SCB3H`Wq璹Pe$eG F6 M)sn>T4LĶ %Fs12P8hl uDsg\4aH#9#J ðu'd;+tYhWLh6 !wYʐm 2IS K`AV8pddGm8 RZ0fA.U~o0r<0EE$"qOF} x[=ﶉMt^ŋG`sۑ00'#a>JēʤlfMnYONB0HI,monK&8䂪슿,-,1uu $mU>PIi7ZiA4d''%r` G8dd0sOcʩFO\ȃ撬G:H̥C#_wr6 +J$Z6OI? H̬ Z$oc#ovrvۓyaI{cxW;x9q' 撱FoB3 iۃFɔ2F$^BlB3[]̨?1f<9o(6a2 w[=gI_[?&MO뫑o#EnUU$RTn߆F&neݳ?n2H]Lw|(XnX~]2~wÓXh.Bl/V$*A'RI*$LI0&]7Ik.b&YYJ:@%5܆1OE6EŵɠAa"*Ʀ\ &H@ɤM煷C0Y#׼&o<>tSM%X,)1Idm(&FBrd\G5YmՑdM 6_*tFOv:k{ZKMSZtI^k6r9*c"I 3Ih| /syǖ U{.%CK.2Z]JG-uhF6q4RK]7-d5jɽ-Uش@e!R+*s$mɒmʵ3o"@C!X Ci_Wj?4QS$uUBI%rG2*2vyilq%fA+|2hXAPwUKk:.}zodRIq9%͓Ԑ7c8naWb}VfW$>-1&J mW,`]@H+Cb9G>l("L/or۶Ah gMm[5y@n$g ʠ3o,À 8JrQ"`7`,*34c 14Ξw.ಁ$N0rRemq/wI=svnz8=Y89\ywK>֐5۸’dDd GpgW[ﶳƩ# %̦ܰq0dL]^ Զ] 1Fc\:r>XY{J/ݷ<6c2;u%A"\-hO1ep3"_f;xLa,֓[+5m ȖWR_"h#.fUEu[y$,MZe3Y/$MvO1lw"hd6Ww\=0\ixJ6u{ɖ;bO2y;Mk%_I98mDm]l)a g 'ĺ&cR-"Tګ>f*4 l E5u5y_7|;pm/'.x;M.tZ_[Kk+;7]]OHՏ⯄m{P 6w.t07[ܞ=]oUmӯ,ö}w qw=֣%SK}y!9jz·x#3Z\6V~usaqޭi'PzEWCT?[?AM2io5/h$!mGoO7 B7iW'tPo%F2궣&ܩ9{˚1)ߞisӕ,.4ԅHƝ?eYЭNr6 񓃧SNRQmJIʹ+i.XKXej~!}NѬeKuIα:}E:mZQj˦uIE4[ 2oZ.W7&{ier;Wǒi:+ Iz_x\]I\ |'2Z/|zEVWZle{{iipM64,t n/+zvoN$V .t♼Hujhm5+ͫoQq:S F/|$iMǙ,FjUPZj4#$S7N 4RKr-gy47L[6QK[I8]Ysi Iq(k;K{߼+]eXD֩ QhOF%Y_ykz[LiJ!,n4eQ}|-^ƍ&<7EtEYMYgj:lvzBis(BmJ _ <7g]'[.-?~%B[2%nԥ{ &Y4jaBzSԹ`(8AYIZiq}PNcGTju)SYʥnzt;CSRH߈./ɂK_X%?ϡmiJclesTx-:Ujj|comj]2+/kqAkoᶉщoG:eν}Mj&|/otm*Nj ]LsA+O7W1BW]SyM mVy=A٠wM4K%c~%U5}7Hѵ횜5Z*Sӌe Ra.GQҩN'.2匽ٝXL"BµWQONT$g:TS>כ3GhO5o N?toC6ھo լt#ÚfxvZiϨE3䯏#5MG[Q&E|a6|K;n,/4мgVV#V Y𿆭;q^qQj1B4Ԣn`S:԰Te 4pӌTaV䛔bǻbNxዕ;^w=m%_u1QRRMR;ʧκx|?j_|]B_Ӥki][k˽7ךwiq5Z.xP>FeO#Auo} R7vkV·kM?iO j"I)K[CA{G|B{FWu m&z͇4c^kծ< ᫛ۍKϰ:ky`-/;? ~~)5~2KMDC?|KKun/F}gƝ(SHbc֓YI1-9Ӆ9'zU)b %zu)|/*n+:jQ9UJ7'8Օ*P,,"pԣt*",AO~p~84h7M$Ekx“_k6~}ĚxmZYz> `Kb=žS/|7-^-M QѴ%+|N.\[daiVc4^x/~#\^\XGoM>x, GclKn=^okW-}QڔW 7)UN5&FҜTy95rBK„!pףZ0K⾭V2*է Wrw/vjKfM+"'cEijz&DWm̼д|QfjY>?Ĺ|Zi >kkh5}[ek-ZOtxF[I]7NM̺LjjM~jzᏈ't l|;};Ɵ5 xR]V=Ň5o}VZnuo{(fK6nдg_nuӮOrQ[ s[ܟv>مv?lzx$1 *2QFJQEJnCB4l!B*7T}QAJԧ6jG|%osI/g~([hcj:v!~}s]d>0ݍcgş/;ᗎ[J_TzծjZ4?q5.-o½oAVQ%ϫ-Nn$O hnZ5oe/W.3P𮗠jz^sk?ZƣmM׬.4KMz.d$8IiyuE}[{-?^4՘uxbY-.5%)'ګԅ+Z9b\)S59 J2G%BNR4:sPt Q*2n֜baV8޲Nnی|Cm7-#L4]Nw(5)x,c]O.-&:5nt}.|_?lxOQcǚôBiO+eMCL]c[ƇxW^iߍs[C~#c֟ '? Mj|Ӽ3O9.%}SGWRi]~ 3k&^Kw/5xo~>rC{[=kğ >0ksX:ž6Am.].8j8L.>sH8t}TݫQ*Rn5dGJ 73´S5"ѧuysIJN jFtӃ;|6kHo3km.wK]zO<*piBsit.Y.^TqF>Ƨ?C;;xl$?>*NeOoMu'mT>i.nH%ז\&u Y:߇iZS]o_.?h׈l,~ejI ڦs:fm4i4VHʼn91eG WނJ/d,4%wL*rQ&#,Z|*1M\!j~O?|` h:j/n5+; [MnÿlA\jiQ O ғGGaj^Ms=~MJ]nM73Mucm.K7iqw豆/&4{.ֱqCX ODM( aRG0Zg+zm4O i^8ҵY-Lit64a9?Uu=9Q؝4Yқi2Ϥ~d}/Vզ+euxGGޝh >+_Öwkz>xQom [M*/~;EƏB5 ɴRҦhwRU#Vx>.zUkQuMB{?<7q.F}AX EqkhI[3\Flj=L]MNJxݵԼg[YkZƭjPHiq7ن/}7ҵ ii "w6z~'Xxqω񶝪#frK~7'HtxsOKKSo&x/xtOR)u񴾔[˯j>nie^}ޅiU.%;ɫR)SƵ5(BrstO8oI~=`7y r:U4~ Ӭn.Mgj:~$mk"Ė^4l*i>8jOnx+O7RډVƒQWN)n"*ESMBR!VJ4:U<_ 40UBJU`Qr*Q$ӋY.5uo~)/H .çpX}|E-];]Ao,6xǺW_~"_iȲiVQx#Þᴝ|1YZ\xW6.#okmNNKgQ-b|$.syygi~Ommjr\LԬte=^+1O}UmSޟT3i-k;q>(Cp"yeMs\2ۿĿk(,|"4;/YCS^; zYϧ:ش:v]Aiڭw:\%.|<.'cB3u=5}G#"q6 SnXM(BQVfTn S,վ+ӫ(ӅJ(NQVcywZVRσu^ L] ;]ԢBJMgE\k +XY*JgrZmbfDXKī+P^붩ƚߖI4]jj2u"+SqѩFSRQMjm%4_5;8̻F.UF N%UNo.&lXd24ʟ*O1dtm'Qּ=+GԺKF2]*4 XYRY-KHY1-O SkgDmړFiD%KǵƒmE6n^+myF:&L. YF-huUKT׼T|:D!T9e JvM.J[.aK.,! SEŒ7`MJ#oIR&N s/gi^.*Kvk}3cos=:|ɨ^!" Zef~% 7ik g5i7.-$n<?$kpa-:][zfYkOx/!4m4{tRǺ5,ZYwgƯ [h6NҭS*xNjڷJoQ~(7IcWĩoq*8M3tSJ-J.tdEӕ'wVQߦTATqRT*i9Fusݷz5%fܕԾ)o;CH鯮i~Ium./dS#Q-4iP^YC%iw[R[?kWvSI C\qcml'dMrnl|wj [M_O(>c:(3Mt_!W[ja}wcw\SyGB >D5h=lIt&A};FN%׋-dӥZ0)˚Q\'I[ ^ΛiJ*1'juU+8EENQh j,DŽn4y4׼# 3J.m|#A˽}׺=#L䷷Y,7[=kDZ )n팉MNme }5qgA%I.>,Ѿ2kl.ehմS^կ.gԴ7OzΣwmx5{Zu#ڭ.5_xO2k:.k&{4/uo~Z["`mo/#%ZQ)JSV&ԒR~,%etQ֌ӎAђuf*qji 98ƛiλP_({B?kv.hZ=cl:|0_\'[Aboot}2Ptk;K]Rw[I2[Lxv_J Դy.M e_ڸ,R S㸚4L#IJX_j[x7S7Me$x~9mgMwbՄGa - IH&时I1<%-[v╛"rM*?ga䢹 1\S(R.{jp:Cx,e* eIjO4WCIjVX~4fՑYۊZim,V^}NZMXùsx I&Ie;jS;w+{k?YkQ]uȸ[tA ֟c^+e UfDYEῇ ukX?nd#me-LonP)x-=6D{[ƙ{a:rH::1e>XrxūQi'w]t\WIheeiW_[]{]}ѵFAkxwBXYYX@L u+ȠIV0,dD_2bէ|)fܭ#|$(! H8B@(HRXY,|[ܤ:4 n;ȸSºMt՞ݞnզ MBv8'* DO\LF0Gr9ZسO1$C8q&MѤ3IVFc%M3EBktmu`YH7VwVd +q/ӷ_W]JX`>mN;02I;qH@1B䟠ӗkBŀ H]AdFFq$RUqJF\;Yi ?w##'9(U >b[qJ=~lI t+z zz ` r1 A `ey0@ӻ{(0Fݓ'Â1' r&ƒW;i$AA94X:,u $JRUR8 lRI=(Z_}Km/p@Ыcnw|Yxʐx8S);!_zO@؂RXcDd;dIy_[۪+WH;9C|ͷDIaUH\) 䓒Xcvx5q4Q vmPdl5d]Zt ʥ HvrIb G*+;m.)n""cPY9A\Cw!Vfʃ$9#{* saAs3&AU.IPBR>\(J~nMZ]epYO1z9V$a b3"mPP2m 3ܥHĎl_8 nOʡu$8m߮-۽n.~z-_є$;v(o,TnV_lTd As\W W0r[. J\x9'~cn$q#8Q(T^CÐf!B+!]mou VRʪv T'yI2B =ncH3 g9iwS`m ٖWO1~J,Gβ' VaDS]jeYVY- .Sd+$bP hpKn|ȉ_Y4nOtR{_UB肋{.'o2y3*ѳm<$ q͹H`L0 *I )p+*͸Rw2 k-EnNVҷUwnޞ{[򉷈f'N͸(UYEmƊYjAb7gɐl" V,1ۂNTVYB0y{G2m8&F v'ir5b K7A+pπJ e鯥Z%dJf# {caw0$K'V^Trx ~ѓ0rI@ܓv??`19SG%  dVUy|1 gv`ap@ FFG<=鯝]DkӾޟO(*[ .H()pJzۇ U'Hm eawz'F2HprIaey%d@3P\rĕU' *r@-u{-Ͼ6?.[Jw1r bq.ĝֺ LЍJJaKx'*dd,yl^8J`{eV)%QI:I>UAث;$^[_73nC:D$,!&DAdwIq H˼xT=5(e{FOWmRySrQvvKum4~]:Y]_Mw3ww.-A!i% b6 ֳw82I+j 1ú2Ā஄624m[C,;IX4BF0r*7I\HUYv) ,qҩMŝcEn.VOTWZ饕bI5Ik^k^hR/9tmoG/cf{e*cn&`Io$Gh˚[#JK(٘Ghh" D#lm#3#Bedp,)4 đifUFPgI%hyPR.`+EGYeX4ʷ#a&ǖFt)ˬ\qvjZ{Fm]/h4G;[ưZGG/oq1hW* #,;BOw4vZ<p\HǴ10m"#ҵBkPL DXB[Y