Catmandu-FileStore-1.13000755000765000024 013362073757 15200 5ustar00hochstenstaff000000000000README100644000765000024 1003013362073757 16153 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13NAME Catmandu::FileStore - Namespace for packages that can make files persistent SYNOPSIS # From the command line # Export a list of all file containers $ catmandu export File::Simple --root t/data to YAML # Export a list of all files in container '1234' $ catmandu export File::Simple --root t/data --bag 1234 to YAML # Add a file to the container '1234' $ catmandu stream /tmp/myfile.txt to File::Simple --root t/data --bag 1234 --id myfile.txt # Download the file 'myfile.txt' from the container '1234' $ catmandu stream File::Simple --root t/data --bag 1234 --id myfile.txt to /tmp/output.txt # Delete the file 'myfile.txt' from the container '1234' $ catmandu delete File::Simple --root t/data --bag 1234 --id myfile.txt # From Perl use Catmandu; my $store = Catmandu->store('File::Simple' , root => 't/data'); # List all containers $store->index->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new container $store->index->add({ _id => '1234' }); # Get the container my $files = $store->index->files('1234'); # Add a file to the container $files->upload(IO::File->new('get('foobar.txt'); # Stream the contents of a file $files->stream(IO::File->new('>foobar.txt'), $file); # Delete a file $files->delete('foobar.txt'); # Delete a container $store->index->delete('1234'); DESCRIPTION Each Catmandu::FileStore is a Catmandu::Store and inherits all its methods, A Catmandu::FileStore is package to store and retrieve binary content in an filesystem, memory or a network. A Catmandu::FileStore contains one or more Catmandu::FileBag which is a kind of folder. Each Catmandu::FileBag contains one or more files. One special Catmandu::FileBag is the index and contains the listing of all Catmandu::FileBag in the Catmandu::FileStore. CONFIGURATION index_bag The name of the index bag to use when no bag name is give. The index bag is a bag containing a listing of all Catmandu::FileBag-s in the Store. my $index = $store->index; $index->each(sub { my $bag = shift; printf "%s\n" , $bag->{_id}; }); index_class The default class implementation to use for an index of Catmandu::FileBag-s. By default this is the Catmandu::FileStore implementation with '::Index' added. METHODS bag($name) Create or retieve a bag with name $name. Returns a Catmandu::FileBag. index Returns the index Catmandu::FileBag for the Catmandu::FileStore. my $index = $store->index; # Add a new file container $index->add({ _id => '1234'}); # Anf use it... my $container = $store->bag('1234'); $container->upload(IO::File->new('data.txt') , 'data.txt'); log Return the current logger. Can be used when creating your own Stores. E.g. package Catmandu::Store::Hash; ... sub generator { my ($self) = @_; $self->log->debug("generating record"); ... } See also: Catmandu for activating the logger in your main code. AUTHOR Patrick Hochstenbach, Nicolas Steenlant, Nicolas Franck, SEE ALSO Catmandu::Store::File::Simple, Catmandu::Store::File::Memory, Catmandu::FileBag LICENSE AND COPYRIGHT This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See http://dev.perl.org/licenses/ for more information. Changes100644000765000024 51013362073757 16530 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13Revision history for Catmandu-FileStore 1.13 2018-10-18 14:09:14 CEST - Fixing EAGAIN bug 1.12 2018-08-29 14:22:03 CEST - Replacing writes with syswrites and better checks on number of bytes written 1.11 2018-06-28 11:30:58 CEST - Fixing Windows tests 1.10 2018-06-25 13:37:20 CEST - initial version LICENSE100644000765000024 4370513362073757 16317 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13This software is copyright (c) 2018 by Patrick Hochstenbach. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2018 by Patrick Hochstenbach. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2018 by Patrick Hochstenbach. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End cpanfile100644000765000024 70313362073757 16745 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13requires 'perl', 'v5.10.1'; on 'test', sub { requires 'Log::Any::Adapter::Log4perl', 0; requires 'Log::Any::Test', '1.03'; requires 'Log::Log4perl' , 0; requires 'Test::Deep', '0.112'; requires 'Test::Exception', '0.43'; requires 'Test::LWP::UserAgent' , 0; requires 'Test::More', '0.99'; requires 'Test::Pod', 0; }; requires 'Catmandu', '1.06'; recommends 'Log::Log4perl', '1.44'; recommends 'Log::Any::Adapter::Log4perl', '0.06'; dist.ini100644000765000024 4113362073757 16660 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13[@Milla] installer = ModuleBuild Build.PL100644000765000024 311313362073757 16553 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13 # This file was automatically generated by Dist::Zilla::Plugin::ModuleBuild v6.008. use strict; use warnings; use Module::Build 0.28; my %module_build_args = ( "build_requires" => { "Module::Build" => "0.28" }, "configure_requires" => { "Module::Build" => "0.28" }, "dist_abstract" => "Namespace for packages that can make files persistent", "dist_author" => [ "Patrick Hochstenbach, C<< >>" ], "dist_name" => "Catmandu-FileStore", "dist_version" => "1.13", "license" => "perl", "module_name" => "Catmandu::FileStore", "recommends" => { "Log::Any::Adapter::Log4perl" => "0.06", "Log::Log4perl" => "1.44" }, "recursive_test_files" => 1, "requires" => { "Catmandu" => "1.06", "perl" => "v5.10.1" }, "test_requires" => { "Log::Any::Adapter::Log4perl" => 0, "Log::Any::Test" => "1.03", "Log::Log4perl" => 0, "Test::Deep" => "0.112", "Test::Exception" => "0.43", "Test::LWP::UserAgent" => 0, "Test::More" => "0.99", "Test::Pod" => 0 } ); my %fallback_build_requires = ( "Log::Any::Adapter::Log4perl" => 0, "Log::Any::Test" => "1.03", "Log::Log4perl" => 0, "Module::Build" => "0.28", "Test::Deep" => "0.112", "Test::Exception" => "0.43", "Test::LWP::UserAgent" => 0, "Test::More" => "0.99", "Test::Pod" => 0 ); unless ( eval { Module::Build->VERSION(0.4004) } ) { delete $module_build_args{test_requires}; $module_build_args{build_requires} = \%fallback_build_requires; } my $build = Module::Build->new(%module_build_args); $build->create_build_script; META.yml100644000765000024 240313362073757 16531 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13--- abstract: 'Namespace for packages that can make files persistent' author: - 'Patrick Hochstenbach, C<< >>' build_requires: Log::Any::Adapter::Log4perl: '0' Log::Any::Test: '1.03' Log::Log4perl: '0' Module::Build: '0.28' Test::Deep: '0.112' Test::Exception: '0.43' Test::LWP::UserAgent: '0' Test::More: '0.99' Test::Pod: '0' configure_requires: Module::Build: '0.28' dynamic_config: 0 generated_by: 'Dist::Milla version v1.0.17, Dist::Zilla version 6.008, CPAN::Meta::Converter version 2.150005' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Catmandu-FileStore no_index: directory: - eg - examples - inc - share - t - xt recommends: Log::Any::Adapter::Log4perl: '0.06' Log::Log4perl: '1.44' requires: Catmandu: '1.06' perl: v5.10.1 resources: bugtracker: https://github.com/LibreCat/Catmandu-FileStore/issues homepage: https://github.com/LibreCat/Catmandu-FileStore repository: https://github.com/LibreCat/Catmandu-FileStore.git version: '1.13' x_contributors: - 'Nicolas Franck ' - 'Patrick Hochstenbach ' x_serialization_backend: 'YAML::Tiny version 1.69' MANIFEST100644000765000024 267113362073757 16420 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.008. Build.PL Changes LICENSE MANIFEST META.json META.yml README cpanfile dist.ini lib/Catmandu/Cmd/stream.pm lib/Catmandu/DirectoryIndex.pm lib/Catmandu/DirectoryIndex/Map.pm lib/Catmandu/DirectoryIndex/Number.pm lib/Catmandu/DirectoryIndex/UUID.pm lib/Catmandu/FileBag.pm lib/Catmandu/FileBag/Index.pm lib/Catmandu/FileStore.pm lib/Catmandu/Plugin/SideCar.pm lib/Catmandu/Store/File/Memory.pm lib/Catmandu/Store/File/Memory/Bag.pm lib/Catmandu/Store/File/Memory/Index.pm lib/Catmandu/Store/File/Multi.pm lib/Catmandu/Store/File/Multi/Bag.pm lib/Catmandu/Store/File/Multi/Index.pm lib/Catmandu/Store/File/Simple.pm lib/Catmandu/Store/File/Simple/Bag.pm lib/Catmandu/Store/File/Simple/Index.pm t/Catmandu-Cmd-stream.t t/Catmandu-DirectoryIndex-Map.t t/Catmandu-DirectoryIndex-Number.t t/Catmandu-DirectoryIndex-UUID.t t/Catmandu-DirectoryIndex.t t/Catmandu-FileBag-Index.t t/Catmandu-FileBag.t t/Catmandu-FileStore.t t/Catmandu-Plugin-SideCar.t t/Catmandu-Store-File-Memory-Bag.t t/Catmandu-Store-File-Memory-Index.t t/Catmandu-Store-File-Memory.t t/Catmandu-Store-File-Multi-Bag.t t/Catmandu-Store-File-Multi-Index.t t/Catmandu-Store-File-Multi.t t/Catmandu-Store-File-Simple-Bag.t t/Catmandu-Store-File-Simple-Index.t t/Catmandu-Store-File-Simple.t t/author-pod-syntax.t t/data2/000/000/001/test.txt t/data2/000/000/002/test.pdf t/data2/000/000/002/test.txt t/data2/000/000/003/test.txt META.json100644000765000024 435213362073757 16706 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13{ "abstract" : "Namespace for packages that can make files persistent", "author" : [ "Patrick Hochstenbach, C<< >>" ], "dynamic_config" : 0, "generated_by" : "Dist::Milla version v1.0.17, Dist::Zilla version 6.008, CPAN::Meta::Converter version 2.150005", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Catmandu-FileStore", "no_index" : { "directory" : [ "eg", "examples", "inc", "share", "t", "xt" ] }, "prereqs" : { "build" : { "requires" : { "Module::Build" : "0.28" } }, "configure" : { "requires" : { "Module::Build" : "0.28" } }, "develop" : { "requires" : { "Dist::Milla" : "v1.0.17", "Test::Pod" : "1.41" } }, "runtime" : { "recommends" : { "Log::Any::Adapter::Log4perl" : "0.06", "Log::Log4perl" : "1.44" }, "requires" : { "Catmandu" : "1.06", "perl" : "v5.10.1" } }, "test" : { "requires" : { "Log::Any::Adapter::Log4perl" : "0", "Log::Any::Test" : "1.03", "Log::Log4perl" : "0", "Test::Deep" : "0.112", "Test::Exception" : "0.43", "Test::LWP::UserAgent" : "0", "Test::More" : "0.99", "Test::Pod" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/LibreCat/Catmandu-FileStore/issues" }, "homepage" : "https://github.com/LibreCat/Catmandu-FileStore", "repository" : { "type" : "git", "url" : "https://github.com/LibreCat/Catmandu-FileStore.git", "web" : "https://github.com/LibreCat/Catmandu-FileStore" } }, "version" : "1.13", "x_contributors" : [ "Nicolas Franck ", "Patrick Hochstenbach " ], "x_serialization_backend" : "Cpanel::JSON::XS version 4.04" } t000755000765000024 013362073757 15364 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13Catmandu-FileBag.t100644000765000024 27213362073757 20715 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; my $pkg; BEGIN { $pkg = 'Catmandu::FileBag'; use_ok $pkg; } require_ok $pkg; done_testing; author-pod-syntax.t100644000765000024 45413362073757 21302 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!perl BEGIN { unless ($ENV{AUTHOR_TESTING}) { print qq{1..0 # SKIP these tests are for testing by the author\n}; exit } } # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use strict; use warnings; use Test::More; use Test::Pod 1.41; all_pod_files_ok(); Catmandu-FileStore.t100644000765000024 533413362073757 21344 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; my $pkg; BEGIN { $pkg = 'Catmandu::FileStore'; use_ok $pkg; } require_ok $pkg; { package T::Store; use Moo; with $pkg; package T::Store::Index; use Moo; with 'Catmandu::Bag'; with 'Catmandu::FileBag'; sub generator { } sub add { } sub get { } sub delete { } sub delete_all { } package T::Store::Bag; use Moo; with 'Catmandu::Bag'; with 'Catmandu::FileBag'; sub generator { } sub add { } sub get { } sub delete { } sub delete_all { } package T::CustomIndexClass; use Moo; extends 'T::Store::Index'; has prop => (is => 'ro'); package T::CustomBagClass; use Moo; extends 'T::Store::Bag'; has prop => (is => 'ro'); } note("create a new store"); my $s = T::Store->new; can_ok $s, 'bag_class'; can_ok $s, 'default_bag'; can_ok $s, 'bag'; can_ok $s, 'index'; is $s->bag_class, 'T::Store::Bag'; is $s->default_bag, 'index'; note("create a custom store"); $s = T::Store->new( bag_class => 'T::CustomBagClass', index_class => 'T::CustomIndexClass' ); is $s->bag_class, 'T::CustomBagClass'; is $s->index_class, 'T::CustomIndexClass'; my $b = $s->bag; isa_ok $b, $s->index_class; is $s->bag, $b; is $b->store, $s; is $b->name, 'index'; ok !$s->bag('foo'), 'unkown bag'; note("options"); $s = T::Store->new( index_class => 'T::CustomIndexClass', bags => {index => {prop => 'val', store => 'junk', name => 'junk'}} ); is $s->index->prop, 'val', "options are passed to bag"; isnt $s->index->store, 'junk', "store can't be overriden"; isnt $s->index->name, 'junk', "name can't be overriden"; note("default options"); $s = T::Store->new( index_class => 'T::CustomIndexClass', default_options => {prop => 'bar'}, bags => {index => {store => 'junk', name => 'junk'}} ); is $s->index->prop, 'bar'; $s = T::Store->new( index_class => 'T::CustomIndexClass', default_options => {prop => 'bar'}, bags => {index => {prop => 'baz', store => 'junk', name => 'junk'}} ); is $s->index->prop, 'baz'; note("plugins"); $b = T::Store->new(bags => {index => {plugins => [qw(Datestamps)]}})->index; ok $b->does('Catmandu::Plugin::Datestamps'), 'apply plugins'; $b = T::Store->new(default_plugins => [qw(Datestamps)])->index; ok $b->does('Catmandu::Plugin::Datestamps'), 'apply default plugins'; $b = T::Store->new( default_plugins => [qw(Datestamps)], bags => {index => {plugins => [qw(Versioning)]}} )->index; ok $b->does('Catmandu::Plugin::Datestamps') && $b->does('Catmandu::Plugin::Versioning'), 'prepend default plugins'; done_testing(); Catmandu000755000765000024 013362073757 17423 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/libFileBag.pm100644000765000024 554713362073757 21425 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandupackage Catmandu::FileBag; our $VERSION = '1.13'; use Catmandu::Sane; use IO::String; use Catmandu::Util qw(:is :check); use Moo::Role; use namespace::clean; sub stream { my ($self, $io, $data) = @_; check_hash_ref($data); check_invocant($io); $data->{_stream}->($io); } sub as_string { my ($self, $data) = @_; check_hash_ref($data); my $str; my $io = IO::String->new($str); $data->{_stream}->($io); $str; } sub as_string_utf8 { my ($self, $data) = @_; check_hash_ref($data); my $str; my $io = IO::String->new($str); $data->{_stream}->($io); utf8::decode($str); $str; } sub upload { my ($self, $io, $id) = @_; check_string($id); check_invocant($io); my $file = {_id => $id, _stream => $io}; $self->add($file); # The add() method of FileBags should inline data the passed $file with # file metadata. Use a get($id) when this inline update wasn't implemented # by the Bag. if (exists $file->{size}) { # all ok } else { $self->log->warn( "$self doesn't inline update \$data in add(\$data) method"); $file = $self->get($id); } if (!defined($file)) { return 0; } elsif (is_hash_ref($file)) { return $file->{size}; } else { $self->log->error("expecting a HASH but got `$file'"); return 0; } } 1; __END__ =pod =head1 NAME Catmandu::FileBag - A Catmandu::FileStore compartment to persist binary data =head1 SYNOPSIS use Catmandu; my $store = Catmandu->store('Simple' , root => 't/data'); # List all containers $store->bag->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $store->bag->add({ _id => '1234' }); # Get the files my $files = $store->bag->files('1234'); # Add a file to the files $files->upload(IO::File->new('get('foobar.txt'); $files->stream(IO::File->new('>foobar.txt'), $file); # Delete a file $files->delete('foobar.txt'); # Delete a folder $store->index->delete('1234'); =head1 DESCRIPTION Each L is a L and inherits all its methods. =head1 METHODS =head2 upload($io, $file_name) An helper application to add an IO::Handle $io to the L. Returns the number of bytes written. =head2 stream($io, $file) A helper application to stream the contents of a L item to an IO::Handle. Returns the number of bytes written. =head2 as_string($file) Return the contents of the L item as a string. =head2 as_string_utf8($file) Return the contents of the L item as an UTF-8 string. =head1 SEE ALSO L , L =cut Catmandu-Cmd-stream.t100644000765000024 206513362073757 21442 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use App::Cmd::Tester::CaptureExternal; use Cpanel::JSON::XS; use Path::Tiny; use utf8; my $pkg; BEGIN { $pkg = 'Catmandu::Cmd::stream'; use_ok $pkg; } require_ok $pkg; use Catmandu::CLI; path("t/tmp/cmd-stream")->mkpath; note("download"); { my $result = test_app( qq|Catmandu::CLI| => [ qw(stream File::Simple --root t/data2 --keysize 9 --bag 1 --id test.txt to -) ] ); # is $result->stdout , "钱唐湖春行\n"; is $result->error, undef, 'threw no exceptions'; } note("upload"); { my $result = test_app( qq|Catmandu::CLI| => [ qw(stream cpanfile to File::Simple --root t/tmp/cmd-stream --keysize 9 --bag 456 --id test.txt) ] ); ok !$result->stdout; is $result->error, undef, 'threw no exceptions'; ok -f "t/tmp/cmd-stream/000/000/456/test.txt", "found the correct file"; unlink "t/tmp/cmd-stream/000/000/456/test.txt"; } path("t/tmp/cmd-stream")->remove_tree; done_testing; FileStore.pm100644000765000024 1440513362073757 22041 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandupackage Catmandu::FileStore; our $VERSION = '1.13'; use Catmandu::Sane; use Moo::Role; use Catmandu::Util; use namespace::clean; with 'Catmandu::Store'; has index_bag => (is => 'ro', default => sub {'index'},); has index_class => (is => 'ro', default => sub {ref($_[0]) . '::Index'},); has index => (is => 'lazy'); sub _build_default_bag { $_[0]->index_bag; } sub _build_index { my ($self) = @_; my $name = $self->index_bag; my $inst; try { my $opts = {store => $self, name => $name}; my $default_opts = $self->default_options; my $bag_opts = $self->bag_options->{$name} //= {}; $opts = {%$default_opts, %$bag_opts, %$opts}; my $pkg = Catmandu::Util::require_package($self->index_class); my $index_name = $self->index_bag; my $default_plugins = $self->default_plugins; my $plugins = delete($opts->{plugins}) // []; if (@$default_plugins || @$plugins) { $pkg = $pkg->with_plugins(@$default_plugins, @$plugins); } $inst = $pkg->new(%$opts); } catch { $self->log->warn( "no instance of " . $self->index_class . " created : $_"); }; $inst; } sub bag { my $self = shift; my $name = shift // $self->index_bag; my $index_name = $self->index_bag; # Return the index when requested if ($name eq $index_name) { $self->index; } # Otherwise load the container for files elsif ($self->index->exists($name)) { my $opts = {store => $self, name => $name}; my $default_opts = $self->default_options; my $bag_opts = $self->bag_options->{$name} //= {}; $opts = {%$default_opts, %$bag_opts, %$opts}; my $pkg = Catmandu::Util::require_package(delete($opts->{class}) // $self->bag_class); my $default_plugins = $self->default_plugins; my $plugins = delete($opts->{plugins}) // []; if (@$default_plugins || @$plugins) { $pkg = $pkg->with_plugins(@$default_plugins, @$plugins); } $pkg->new(%$opts); } else { return undef; } } 1; __END__ =pod =head1 NAME Catmandu::FileStore - Namespace for packages that can make files persistent =begin markdown # STATUS [![Build Status](https://travis-ci.org/LibreCat/Catmandu-FileStore.svg?branch=master)](https://travis-ci.org/LibreCat/Catmandu-FileStore) [![Coverage](https://coveralls.io/repos/LibreCat/Catmandu-FileStore/badge.svg?branch=master)](https://coveralls.io/r/LibreCat/Catmandu-FileStore) =end markdown =head1 SYNOPSIS # From the command line # Export a list of all file containers $ catmandu export File::Simple --root t/data to YAML # Export a list of all files in container '1234' $ catmandu export File::Simple --root t/data --bag 1234 to YAML # Add a file to the container '1234' $ catmandu stream /tmp/myfile.txt to File::Simple --root t/data --bag 1234 --id myfile.txt # Download the file 'myfile.txt' from the container '1234' $ catmandu stream File::Simple --root t/data --bag 1234 --id myfile.txt to /tmp/output.txt # Delete the file 'myfile.txt' from the container '1234' $ catmandu delete File::Simple --root t/data --bag 1234 --id myfile.txt # From Perl use Catmandu; my $store = Catmandu->store('File::Simple' , root => 't/data'); # List all containers $store->index->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new container $store->index->add({ _id => '1234' }); # Get the container my $files = $store->index->files('1234'); # Add a file to the container $files->upload(IO::File->new('get('foobar.txt'); # Stream the contents of a file $files->stream(IO::File->new('>foobar.txt'), $file); # Delete a file $files->delete('foobar.txt'); # Delete a container $store->index->delete('1234'); =head1 DESCRIPTION Each L is a L and inherits all its methods, A L is package to store and retrieve binary content in an filesystem, memory or a network. A C contains one or more C which is a kind of folder. Each C contains one or more files. One special C is the C and contains the listing of all C in the C. =head1 CONFIGURATION =over =item index_bag The name of the index bag to use when no bag name is give. The index bag is a bag containing a listing of all C-s in the Store. my $index = $store->index; $index->each(sub { my $bag = shift; printf "%s\n" , $bag->{_id}; }); =item index_class The default class implementation to use for an index of C-s. By default this is the C implementation with '::Index' added. =back =head1 METHODS =head2 bag($name) Create or retieve a bag with name C<$name>. Returns a L. =head2 index Returns the index L for the L. my $index = $store->index; # Add a new file container $index->add({ _id => '1234'}); # Anf use it... my $container = $store->bag('1234'); $container->upload(IO::File->new('data.txt') , 'data.txt'); =head2 log Return the current logger. Can be used when creating your own Stores. E.g. package Catmandu::Store::Hash; ... sub generator { my ($self) = @_; $self->log->debug("generating record"); ... } See also: L for activating the logger in your main code. =head1 AUTHOR Patrick Hochstenbach, C<< >> Nicolas Steenlant, C<< >> Nicolas Franck, C<< >> =head1 SEE ALSO L, L, L =head1 LICENSE AND COPYRIGHT This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See L for more information. =cut Cmd000755000765000024 013362073757 20126 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandustream.pm100644000765000024 576713362073757 22136 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Cmdpackage Catmandu::Cmd::stream; use Catmandu::Sane; our $VERSION = '1.0505'; use parent 'Catmandu::Cmd'; use Catmandu; use Catmandu::Util; use Carp; use IO::Handle; use IO::File; use namespace::clean; sub command_opt_spec { (["verbose|v", ""], ["delete", "delete existing items first"],); } sub command { my ($self, $opts, $args) = @_; my ($from_args, $from_opts, $into_args, $into_opts) = $self->_parse_options($args); my $id_name; my $bag_name; my $store_name; my $store_opts; my $filename; my $upload; if ($bag_name = $from_opts->{bag}) { delete $from_opts->{bag}; $id_name = $from_opts->{id} // $self->usage_error("need a --id"); delete $from_opts->{id}; $store_name = $from_args->[0]; $store_opts = $from_opts; $filename = $into_args->[0]; $upload = 0; } elsif ($bag_name = $into_opts->{bag}) { delete $into_opts->{bag}; $id_name = $into_opts->{id} // $self->usage_error("need a --id"); delete $into_opts->{id}; $store_name = $into_args->[0]; $store_opts = $into_opts; $filename = $from_args->[0]; $upload = 1; } else { $self->usage_error("need a --bag"); } my $store = Catmandu->store($store_name, $store_opts); return $upload ? $self->upload_file($store, $bag_name, $id_name, $filename) : $self->download_file($store, $bag_name, $id_name, $filename); } sub upload_file { my ($self, $store, $bag_name, $id_name, $filename) = @_; unless ($store->bag->exists($bag_name)) { $store->bag->add({_id => $bag_name}) // return undef; } my $bag = $store->bag->files($bag_name); return undef unless $bag; my $io; if (!defined($filename) || $filename eq '-') { $io = IO::Handle->new(); $io->fdopen(fileno(STDIN), "r"); } else { $io = IO::File->new("<$filename"); } croak "can't open $filename for reading" unless defined($io); $bag->upload($io, $id_name); } sub download_file { my ($self, $store, $bag_name, $id_name, $filename) = @_; unless ($store->bag->exists($bag_name)) { croak "No such bag `$bag_name`"; } my $bag = $store->bag->files($bag_name); return undef unless $bag; my $file = $bag->get($id_name); unless ($file) { croak "No such file `$id_name` in `$bag_name`"; } my $io; if (!defined($filename) || $filename eq '-') { $io = bless(\*STDOUT => 'IO::File'); } else { $io = IO::File->new(">$filename"); } $io->binmode(':encoding(UTF-8)'); croak "can't open $filename for writing" unless defined($io); $bag->stream($io, $file); } 1; __END__ =pod =head1 NAME Catmandu::Cmd::stream - import and export streams into a Catmandu::FileStore =head1 EXAMPLES catmandu stream /tmp/data.txt to File::Simple --root t/data --bag 1234 catmandu stream File::Simple --root t/data --bag 1234 to /tmp/data catmandu help stream =cut Catmandu-FileBag-Index.t100644000765000024 30113362073757 21753 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; my $pkg; BEGIN { $pkg = 'Catmandu::FileBag::Index'; use_ok $pkg; } require_ok $pkg; done_testing; Catmandu-DirectoryIndex.t100644000765000024 410313362073757 22375 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use Role::Tiny; use Cwd; my $pkg; BEGIN { $pkg = 'Catmandu::DirectoryIndex'; use_ok $pkg; } require_ok $pkg; { package T::DirectoryIndexNoGet; use Moo; sub add { } sub delete { } sub delete_all { } sub generator { sub { } } package T::DirectoryIndexNoAdd; use Moo; sub get { } sub delete { } sub delete_all { } sub generator { sub { } } package T::DirectoryIndexNoDelete; use Moo; sub add { } sub get { } sub delete_all { } sub generator { sub { } } package T::DirectoryIndexNoDeleteAll; use Moo; sub add { } sub get { } sub delete { } sub generator { sub { } } package T::DirectoryIndexNoGenerator; use Moo; sub add { } sub get { } sub delete { } sub delete_all { } package T::DirectoryIndex; use Moo; with $pkg; sub add { } sub get { } sub delete { } sub delete_all { } sub generator { sub { } } } throws_ok {Role::Tiny->apply_role_to_package("T::DirectoryIndexNoGet", $pkg)} qr/missing get/, "method get missing"; throws_ok {Role::Tiny->apply_role_to_package("T::DirectoryIndexNoAdd", $pkg)} qr/missing add/, "method add missing"; throws_ok {Role::Tiny->apply_role_to_package("T::DirectoryIndexNoDelete", $pkg)} qr/missing delete/, "method delete missing"; throws_ok { Role::Tiny->apply_role_to_package("T::DirectoryIndexNoDeleteAll", $pkg) } qr/missing delete_all/, "method delete_all missing"; throws_ok { Role::Tiny->apply_role_to_package("T::DirectoryIndexNoGenerator", $pkg) } qr/missing generator/, "method generator missing"; dies_ok(sub {T::DirectoryIndex->new();}, "new without base_dir should fail"); lives_ok(sub {T::DirectoryIndex->new(base_dir => Cwd::cwd());}, "new with base_dir should succeed"); can_ok(T::DirectoryIndex->new(base_dir => Cwd::cwd()), "base_dir"); done_testing; Catmandu-Plugin-SideCar.t100644000765000024 674613362073757 22226 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use Catmandu; use Path::Tiny; use utf8; my $pkg; BEGIN { $pkg = 'Catmandu::Plugin::SideCar'; use_ok $pkg; } require_ok $pkg; path("t/tmp/sidecar")->mkpath; note("Combined Simple + Hash sidecar"); { my $store = Catmandu->store( 'File::Simple', root => 't/tmp/sidecar', keysize => 9, bags => { index => {plugins => [qw(SideCar)], sidecar => {package => "Hash"}} } ); my $index = $store->bag; ok $store , 'got a store'; ok $index , 'got an index'; note("...exists"); ok !$index->exists('9012'); note("...add"); ok $index->add({_id => 9012, foo => 'bar', test => [1, 2, 3]}), 'adding bag `9012`'; ok -d "t/tmp/sidecar/000/009/012"; note("...get"); my $item = $index->get('9012'); ok $item; is_deeply $item , {_id => 9012, foo => 'bar', test => [1, 2, 3]}, 'found combined metadata and file data'; note("...bag"); my $container = $store->bag('9012'); ok $container , 'got bag(9012)'; note("...upload"); ok $container->upload(IO::File->new('t/data2/000/000/001/test.txt'), 'test1.txt'); ok -f 't/tmp/sidecar/000/009/012/test1.txt', 'test1.txt exists (2)'; note("...list"); my $array = [sort @{$container->map(sub {shift->{_id}})->to_array}]; ok $array , 'list got a response'; is_deeply $array , [qw(test1.txt)], 'got correct response'; note("...exists"); ok $container->exists("test1.txt"), "exists(test1.txt)"; note("...get"); my $file = $container->get("test1.txt"); ok $file; note("...stream"); my $str = $container->as_string_utf8($file); ok $str , 'can stream the data'; is $str , "钱唐湖春行\n", 'got the correct data'; note("...delete_all (bag)"); lives_ok {$container->delete_all()} 'delete_all'; $array = $container->to_array; is_deeply $array , [], 'got correct response'; ok !-f 't/tmp/sidecar/000/009/012/test1.txt', 'test1.txt doesnt exists (2)'; note("...delete_all (index)"); lives_ok {$index->delete_all()} 'delete_all'; $array = $index->to_array; is_deeply $array , [], 'got correct response'; } note("Combined Hash + Simple sidecar"); { my $store = Catmandu->store( 'Hash', bags => { data => { plugins => [qw(SideCar)], sidecar => { package => "File::Simple", options => {'root' => 't/tmp/sidecar', 'keysize' => 9,} }, sidecar_bag => 'index' } } ); ok $store , 'got a store'; ok $store->bag->add({_id => '9012', name => 'patrick'}), 'adding a record'; note("...upload"); ok $store->bag->files('9012') ->upload(IO::File->new('t/data2/000/000/001/test.txt'), 'test1.txt'); ok -f 't/tmp/sidecar/000/009/012/test1.txt', 'test1.txt exists (2)'; note("...get"); my $file = $store->bag->files('9012')->get("test1.txt"); ok $file; note("...stream"); my $str = $store->bag->files('9012')->as_string_utf8($file); ok $str , 'can stream the data'; is $str , "钱唐湖春行\n", 'got the correct data'; note("...drop"); lives_ok {$store->bag->drop} 'delete_all'; my $array = $store->bag->to_array; is_deeply $array , [], 'got correct response'; } path("t/tmp/sidecar")->remove_tree; done_testing; 001000755000765000024 013362073757 17455 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t/data2/000/000test.txt100644000765000024 2013362073757 21265 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t/data2/000/000/001钱唐湖春行 002000755000765000024 013362073757 17456 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t/data2/000/000test.pdf100644000765000024 136607113362073757 21366 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t/data2/000/000/002%PDF-1.3 % 1 0 obj <>/Font<>>>/Subtype/Form/BBox[0 0 595 842]/Matrix[1 0 0 1 0 0]/Length 738/FormType 1/Filter/FlateDecode>>stream xVMS0WfBLV%!ɡ$22QhWnk&8>,JR&ltc-Ģ8TpZuM B90 %"$&̆9~qԮ'l-P8!po3_EL{ؒ z84@6yR`{< kmՈ&4xi\L˂{o={5^zEFZ4= Ws^]/B^Co572 yQ]kPЃ= MLU0FqĒx+3J#lahasұQ%TPI_JދclX!vcmTeXAGQQuBZ¦`X(+WM\Qۣ@+0eF4uQ ,Կ}TunUi߭F}+u\nym]nGE6,ڤwW 7ȷ endstream endobj 2 0 obj <>stream JFIFddDuckydAdobed=      ! 1"W A#ԕVXQ2ַ8x9aqB3S$vw%67RCs45UubT&'DHi*  !1"AQ2UaqBR#3T6VbrCSs$tc45ƒDd% E&'e ?D&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0A#"?S槬m G]cJ&}eآkm)%2@YB{ > ȴ[YE$4Jhm3\= Vn\7n~ 5vb3% ŵRZxljlpCqixR6 fv#zL"y(c2ggmgpwykiaqaڴCUis̼Bll{@ZhPlD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0 G, 4)%ћт6ړnO']^ba>Aԧ0iiia>ީ6f[FMT6#,rj3l'H/^'"Tk. @)C%7{ig y?#?8mo(&#k)-hep-y,N+UPFZED5ҺyHZa7kya啻Wcu#џmKCwF> u=ccpn^s#qRVSdsUz~q:"rm?v-ؓ_oT*yE=fӋtAqJxAjWKSolѱ^54MIiATGI99 Z9飝-!R>s[ 7lh&"'0߽21=k|OoߴWL #oCAze;Ź9&y~LցQ , P T*KÝχc*}!N rcv\oׯIޕ-k.7YASRz@RQEP: tn`z+6jVZ@xOXo[溭V;뫀|p4hKq- ehYoaV9=lN#QsT}+ó?%<uguDU%]tlh)YX3g>[/n2緃cJ7Qkr'_pSEZ+3Å+B\uagQD\آܚ+:P?= o5O'+(!2zC]BE'rGws7FK o.%Bc$ $Dp.sWt('$o+ҭmC9Pċ*e掠ŅBȸ0 JGd=:˚xDsq\nB |.N,qhO>\:&ΝgUqAvjbc$*k#lH״JQpӸ>*4ki2G4ϬտP}Ej35n#h RG"umD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD-?jI>gBI!g XФaj '=O_4%Ui=$>U>YV)/|I!cM?jI>cOIO{iU K zH||Oڬ?R_ϰ5XC?S'/~aB}4,???V>ATg XФaj '=O_5SQ\y|AN!;] Ie>͑]Te6O:SxMйb!;\4'n㦫tpk4IHh~{{6SnWuF2WnFn.C/Sr@k$ĥb[f;5] v}藺QҵWTKid{Z}' K`{Gn+ ?nDe${5;ȡAC&bdb}^1qN.7)%ʟWvK7*ٶ߼Mj}K-]y:-e{R>@LZ x=֯̊#vM#kCWU@e+"O^ENW*"Zvsk< qrWkmٟ=6!I) [ Qq!#p %hW1qs9%[ܜmeHÝx^| x+BޭJ΋⅛joi' ol[ԴtFes\>c .nș"ov51NbwY6ZcMz (VQ贶sRc*CLcoy#yi4*㷯;e5 gcB尵o`) t>hqh[nVIaw 5E"]@! bj1e˓Wc2GGY>LPېhnYי7[Hc߸ZFIZt{Χs"Oʚ&*{s3z6hbļMG0kvv͉&Tn(PmF_ }|a ^I{A%PЅg}khp $sHjm[PExn۟ԣI.otƕ瑭ĔҼvb (ms [# x}ͯR/NQ gin`No[zcT:jG[^o9W+2~dm\nOy l҃^FrWn"W ǘ޿5}@i\99δnKmGAU-+}rG6#u% *D)R>jt+oxÜ:K8R5y``CZښ o B$4 }7|FeCTrﭤP-)#*#.% ל%hdS:VC u+!34M F…Ω0j4͢AoAYܲ*h{/%h@,rsir2:˳1ַma4.n^Ua\[W%񠢹"łX2s$dmqO[8)+0!= )o%!}ljq,է6z3O`5+uiyEnnFj&n;0 |Lyv)5Uan{ sGhAYEE"lDZߴm.AAZ bاޢ,ӅlTpʉ(d.chI&/)O;!cIq<+2<gbT0(iW0n"b5iXJS(F2<3PY$e;f lw:^dPU*_$M=KZWH 0|{Țѧ/4p.`#U E-3qMv*/FvYCYP(z HD@D>`ػ㱵>F>?QyɸA;gQ`c8N=NLslMk-G]u3kg%yYDD9ʛ|(9t@EL%bR{Z)}5;LmE3%q(5VEr MYh%Ei :&Yknrc͍3ihh5$,r>}ݷ )֮.#kUlD&0VL/Vr>-hvKk0=aZH+"e v:yW(Tӑ ~z?}Qk}賶h~Ui٫hӨ@u~=>W#`pL"aD&0L"aD&0L"aD&0_Š&j*I$eUC &:!P s9*j8 ۍNAךD_x k-`hT"ɺ#0N=8ݙl`?MV60(^ꆑꨶgy\._{a}@#r 9h&B4YGr"9t`/Ǵ\guԭ[88u\9U9~^m&ky imyPq"Vͨ})SDm w2.n.TY10t_8@͖R*+Tvdc3boJy:߰Q5Aj!X(5FYy$S S['af9p SF%7:Kxoa--Q\tM5ٻ?<Ŗgoiv&}d}wbY!XYWB`#,K6+SntWHzMMTd(Ce׳Nx DH6$cd1s\W9&Kng0-ߥ?Nkip*?L"WviRm'u&DÖavKF ׵'N?@2&_88?Xsg%íns9\ۺ`9Epbcm-{f%D<*V.ҒEkY*.%PI}puhb"(:Wt_5ٛWRqbl 単cXu\cdf+;5[c ֺm0\ĺv [N0VVD+(-J( BEdDKbn vY%(};o7v6a]m%|!pnl#cE,r.{hfCff}c-O!cqwʫD:j)g4a_LA%$V@d*s9 .=G2t힫)Ko-\LRUɛ@3 yqqo%&hu+5g͗V- `uk^,k)V{aAf뫍70Gyc7'Eqhqs#[NQ;!EH1Ue8("nf&fR6*/aT1rxӋOn[n7\ $6EDچ%fx\\ҷ>?m윷4^YGeډWl X*{Uz-~{9'R3bРI)QeLP:/ro a.c7䶞w. 4,ptrArCm8cج.rmnѝ-8RL>X'*?[)4} gP5:*ZJ 2ƍ|irHv ju0*DMbA w޹2ۿzOL,u=`n;; dn vM`wduI^FOe^G @%s K${bBH]k@Ĺ` "I$tܓP!ֆoU6ngc!ᒰ"w|>qp8d S'-mn">P3tgU<4S)FX5TK$)htUިj/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^|-?'r?iLݟX&`/w1Z~O+v~ҙ?dߎMIVz^ciW3v~c歂i<ۑOJf~97'[{ݧy_#>%roO OnG<})K5l?v?KO܏xS7g;ɾ)>j/K ~>~ݹn,w|R|հ^sD&0L"aAזbNvACH|4L\zS;Y&Wp7{ϜѲe 87 |t.:a \O&q5m1xjԚkZ94 IUN<=*75CB#\bH6fp3}zUײ d+3gK_#V|Z~APЊܱ{wSx6;mkAt{l"hL3 2 T' 5-M~CzjO/$hqyu8mƟAJΑPq[f"eQUab+v 'u}FoÌPF'I -vfInɀ<3H<(HuZFB6w4]q[^iձ>VTh4lU%b|rﹶ#Ί1$lG&@UV}u%4-[!.Vj ۶adC+ \xPU#$# 1=5nS66inVLJ_v(1l/SU z^#+[Ml=QJ ѷ[GV}9uDS5nQƩѵZDI)6kg=Q7ưSWrfTV͗EQ#pn+?2̳3f2W\4bǮu[ȍ6CU̐yGkcN.B Kd> "5לkՈO3 #|k9c&e^^UܠS)a7!7j$RMo#,Fd':A` {aPx8 ׽67LsW9:Ȋn kze8alJ "B rlUWR+ljN^G_,7IM[:{O=-&05R*UTfmW+k6ȣk o0_08:IAXȐ>*I8D@3.#0Y>ō/?Y-b3\94\-Mꔋ=F Ȫ}Q2lWͩ8X[l\pplӗTf;Or\w{p}Q Z ?s,G,7B=^R8WaCjrV_ճ_CٹEH{2T7Qy7dٛ^T}R]Y>2I .eft;n|| xP956p .I;[}f 4 SU3koN#E)5*Kt\X*jV3fUho%1Wj ^œ ]04gr{=,]uY]dbY#k:k\jKCZWtD MHi!iz"qh.Z^{TMELn.ْhU)LW2y.Ce\A>"Mo#5ˆȷn;r_HNELT'$ @r6GO'"GTxB#-g9lmxQA<ȷ "gr^R(,[~I({ul3z̋S,\."B9ݨ6b"lYKbpfi 9Аg}e^uvAWvo pW6=[v?7oКO7kݸk)YksQedrj)F(@yH!nAY8˜{ͅi-]ŘGѤp`b4͒s5WvOYY6>Wh{V$= ъ3~Z-ztfխcɠ8cgn&n$څfEm^yOǸ+<MFf1=Ԇ7D:͑ $5=AM #<fxL doD&0X[V,G UIX9yŴ\ em˪sv!M^ð%*ա2)8vTkdlf{L5~֥ lYX9RA[G%{F/sƯ$ "4HnutNd?63AٯfUǘ3;-z"4t{!K4 Ahpgwt *KahО$X6'FcwAvxH+_E0L"aD&0L"aD&0L"aD&P=^:Q%U.̖eCiX)6 )bl*Yi IK}w28c/}A^g+\U}'WY 4͕OE >E cF#U5}1}zrG%qIߨaұ#}̾լ+PhC]gowE> ڕNSM)f %7%HD_\؟TTG-p< )NAh LPwV #@-s5G|&\1D[yu BK_jٓf Bt["u5DӮBoemݫ}h$m}Hwa s-8p#Ix{SЫYcrl"F@dufeQGROo^ >e?coۙ."^܋7 :t&DѩޡsM})-Lf;ahwf0$N'.x,K!q{u2]{B IWO0J a( hc|W#,<Ef̽<G>7ŅGǶ"H4WU`;`쭇,]zlK|ZFvY%0 R[vXtၼƆUwlNS5K!'Ix< JŮL"aD&0L"aepU[AB,(dAdMTULJJ&`) !3d Oz<<>j 9xO۟Uf;QM˯"7y]٢yDgjQK)#RI /dL@P0L.ڙR|׷ m Kj|ju?qbrul)Q'R4wVIhs@}aג]Ci놮M0Y~ Âu*7/Nl/zck\fH@'C<OV;[KrD˩”Z Gt%>}ق*Jcn.[)'X upf h1J<,#K`V6Ow-&uF$'mu.aEd35{Kj>Y`7<,ͤ,k6M.pbw 4@=hN܎_$o Y JX'Tt f2K8::._hHDp-!~Wۏ3w>2˪8q>}!hQ# p;skE,{]9žmxj[Oayxǹx7Uчg*50L"aEDoҲ2]ljјfmE#(rMeNC S|09ר)w>[aq sљ1Yi-2֭^;,`Cfvqmb7B;M݋yi/6xԨSht }6(%IZ5o2QQISJ߅*70G0t|྘u=ݗ[gxm{]g!9Lm1!Dxs8ηqb-s&+ ɛK[@nhkt($˂ 7T;@8Ֆ\Wq/L 2nʚ.:b%xg&uZw/L/ e;mޖleGVJ95ƒ.0n{D3 exÜ^ 2wcבCѢUIڵ{DW]R%{WlWzK#oߝaאW]?Phv9H.ٳnwɶnHZ36($kg*҉+̠ &z=얗4ܻIYlV"؂^߸ JG |P"Ub[.2߻9;f۹ZUufg;Fk%-qk2-X2kiiǺ311x\XH$B5γ\h(PY9?sKtǦb}Q#[j չN 3xq_k ?0d,xIԦX6Cpymi:)[}հY!(uT#_"v=;]*!3gQQ,c1Kqy̑$'x# m}ö|ͤxֻ=V5dhU7:LS,h|R匞'`QNLJ UjzC*^bٹ gy[<[ E!ҽ[iQ$N glip-%i xV>bJLM.VVDpr1GeEUW3־tS/ΆT SӪ߻D;nW.n'ۼ~߹r؉\C-a_m6fRQ )nB7fCr16:.+@ö핥$idl(8kYPuU`^ZI'R:us8n= a'Zn{-p]`dOZBW9sмf4 plܦlˆb\sn[8r*3!Qxif?%cA֬DT&'MV[VJ pX,3l"mX~4vG$̞*hxst"pdm:Ko7iFLsZE+멦LB)_BYU%q_k!'oha"!ԆS\[X[#cݮ25m׶]ck>ن=gMzuZ}w@D]LW5VX^k$l\«20n=6W-!δqZ]G#A1kL恲JփPU{'TE꺇y90B%& R]k~E"!,ճ&ho#xa"ڱ^ ٍSdk;6sQ\Gfُ^isk,f(!uz w#bIvFÔ:g3ͨ*WjI(9/kZ*hMۖZE5ыc$Nm";\ EA,`?\2i/{Ie] 9Zጉek'1dx-&#8wbX\R0-c\\l f{h|sWF%h;Rvrw>IMFX5ù8VYQ#r]$S%a?|Xl\A=Y9"]Io~@Y_ kYlnj6Wy}27i#|fk΢.lBf~mOnvg5u3"810;)u R#&T%:U{=D]}_o[-]n!7d-{;|Cۘ1˜鴄Im{4ib̺y 4[QV;#ji鵄a$&s&DEyho I1 }9s͛ 3is$6ay(ɣg| ıCXncqLC]nC䀑V)cݡ{fIw^6y\SoH4QD O8% um<Ȼ|ʊkyc49̑Nos)n.mčo'2F:9#w9Xi- >E0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0ZgL"aD&0`Gr̪k Y\.5Ms$:-kJ٬VQlSQӕhUd2 %g$kGq -7m+&C9XI>$T؊]ch(sesH@d*/!gEWZȔB֠Yˊ<[yȰݸѱW 8-69qWKF43skŠКѭs̿ɛ w]i K ܱU9M➐8y=u8x`4XXAGe HKWq אHwd3{fEGZú 2IZ+e ZHJV bES%Lu~l˲)7M(rs| ,V/;7Itt|I]B| hS51TLВKN [SЋk cSȚ`Xs`R&`*_񱁺AZFOf?H:[Iٹ,ىwO#˴Gv]Q/q^!i=?Bol GmsLY9ې4zN!q*B S|$ZIm] Ic_  +F}M0vk82(ڔ>Hf@ziN~4ovQ&Γԣ+*v2bq=SS7f5ۈVقEnvi[}".`Dq=juŅ.q,ɷ-ķ ܒ FL_WR45 k-m #9A͛ ¼jѬVl{IJa [o~jj{x?E%]=Q5ڴn--+K\NCh+J R}Xy$Cq4>i \#mFOeё 6rqMu݋Y*DF,&QsZ4ۥ)kzeF%ql^NtA-2aI/.\|垠b2*s!j16Tk -h1@> xjI|kS܊4Ddgu] HHMe3;$g:bV1۩am핈ltr<xy 5džRW- aq×L1Ukx,h\Ӗ5[YqFBo_R(BE7#m=KAKU g-9Q5Ta!Wp9p+e]3{|68Y{uKqXɚX;Hѵ{;MSHO44 mK[\vŇqd5Wg6Z)Lo1i~ {$W,PWQtJF\}UXUfqdsw!a֓W7Sr5cB.E*{bT[6 -"A ̕am'@ZA=Y{ Ȥi7튞kprch,6[,Z_N|?R+ x!+KMΐevчUx"g8nXq/TYvMo'n嫘Jq*H$)] 97y94lN8XJyuN4> 6yyke{iqt#k)(cӓȤ7/+Qi0'*QRxB!-Ru#xöjg ;X!W(U"rf,037BC^8"َ'3q(A[Y]d@vHy9L #m:G.e5AϪ8DĵRWЩqv4A趖(.7Hyēt OӠf{7.bK\O[3OOz=dI/&m!%6_ZS\uPC$#ֆxa"#-]2k1~ci9H=Jx0:x1Z\ v"OdSAmmDnRsP-ݤe.}Ev܏1yJL?U$k\bm!x6hwcp@&*Y 8!cpֲGo~2HuuIhV39}rV]IG%{Si')w7`b8#nn rk>uHY&ǔHw"m0:%뛗pYyp%i-ٜf&pZ{IVFq"Ɯ=7ط ''.ь񛆎Q5$ӕI + DGܷZ@7FcEO9%q,级)SY͆5~+4H@Z=X9xIu>Ykz_uEk!wʫ.Hs<;I)L+jjl3u dB%$&)N~qdù6{~&YZ| `b3&,ne$W&qnmmm{-hy2^$ҕ$xhq{줜dҠ{V ֎M OEL"aD&0L"aD&0L"aD&0Z';W OG㥑:VUёDdv͉_Ջ2XcAV{Z!q1/l~ utIkU@X c AYp y*Wu=,ZI;fcN{oz͖#<{ ^.kdJGUk2Vذ`3%#8Ċ "k/Qhs ôܫ' NJPS+e:$]]& d퍺ыr}GQT󚣸u}KhG#O(xT*ǿ`-l:ORQ ڟS0ܞbG'w'?X*G$xJNn֫RP<Ζ~FjNO-ɱQm3@Stydf±oIo^HjMn`,+8DU++a֮ =@|@C@sBH _W-:))(DLLb"SS@D<%FE69`!#05v#=30Ɔ%4aʦ,9+&bq:έm+w[qy_äqǻ:CvJ5w1y=pA,Ĝc%<#nV(*{MRU4c7UagN;x<=b:X A;1p+gs :Լn16`in| GT:w.얚6ChF M#=72ԞpQ N2|ztI:ٰφ.:j2ԼUU5cOL?6$q?@Gg$KQp [7R,WT}+|8#L7`xDlAJk% {>5j$ '9O^na+Rj4{ް91Dxg2%3ϸK_iZN\gywnDwOqsk~,w~Ї%~,V/Qr0}ܑ錫e1xjaFBLb/=S:Bu7(va`m"ȹnaU2ZM3S89F :+hRch'!DnfmJeܐ:f7)AK,|o1Sk-k9IἜQ4zN[޽A/O?ej:6-r5❌{l#x<񖤃G4] :M}o#^ַZO]M?8PSPRա"g2"M^* 8J&wVeb'6޿5ՎObj}n#~*$pI0GVF Znhزb76.ᄑmvA>+SfqQu41QN bh-fJ]YbP٪PU\7zD"A){%m{G.pD9(x.!sF^L]ouf.-rt`=cAcǔF "{#XWVD.nuo# *l** ME}Mڙ@:m䶿_6uDwcwb5"ع̿DMU]l\8{{Qɨȑ6:qW`'۶wMbJ{$nLp,p4lcڼEdp\+v۽،iݱm՜ܱQK@̭(n2\P91X)c%{RH]%u8XaLџƪqΔnfO(( %c1Ս"b$% QD#gwu WR9]fjnKH: tr7 hka;Wkaj@2y4dcP -aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"a@edD&0(,KF-Š>\ =:z d`1J 9눛(Eh<|C,X\>ݑj<woHAN) i;dHEׯX%<[P)SSV+ͧhbt fj? o{jwo {l#T2uaW VhB5uVU<%+lr)dr\61RȉFt@^*66+Ubd4xԐQ 1@S՟Ԣ]ڦ鄚؞vuTSQj"E' =.͹Xa(J%> __Sh 2u]1ŖqshP9%^"ECWqOO#}P69PIqDEBLn賷vq\@sv^yukiSt \D4"tG$2pM ԗ\tׅZ_6}f&j-rb8@IyJbW/j*n`VUtJr+laܻi[`.4t|>Ɣd7 ;pX5{Q"-`qZyc;KhrvD+y)ɞY4mr`:M.PWzGSu]$ãN]ojMXՐN^wjy=3V֍\5Rf&mtZ [05{:-.z] ʎԔXi7N L_4lioESIvy-Q*DM"Tϟޙ%c|7NFN5.<ʛ1 F8§I8=:(LĿ灲E25G+UyM(*klY&j֊SG(3mNp]TY#vfͷu㜄jw0xM(>̍ 4$kĚP[4J}:ȭKy*{Q;|4k+EbJ&!Z/BIcI֑s1tړ9S8䊨t:m<,b\ 8aD@+yeqqkfEwyj-mx.rnR[w|-\3FW[!P 8½W#%r9rTTjyN Di-AD.ps?5Xr(.q2Mxͨ͡#A-# z Ӝrsn I%qq8 \Ӭ{59) %`0꣗*V r>#| &ROHX><-J($os#J6swH2j%~NV@ r(VhrP)L!,ۊv6{gl@I^{ a'9pqͰGvk8Uh54;R",HL͗;gE6b['LDQ5IsΞ97Mѽpi+湭ik|Z{l[p̰y{0=y;YeAT/F ֱ՞2!&fT[.Ǫ*H]d@GA1k{#M*ѱD4&.R#D,q>x/[ qoeWb/5>T>CEAo8eȥn,&nӶ`YQdZrv`|.bHȥy!9|K;#$ȽC26$5kE+6X\{Pڜ\sʃ(8*uN{Yʜc-$"-;>z-@L`0C.e%F8YR1iEI&̒x/^߹+{e ? M{훗X#+ {BRf+4&TCeMx(ٸl ;6+: Äq,dMc mpy@s6!ͭqj}F#8CXVUxdF.JȪ#V28Yc&+-[I5$Ȟ\\;`~͛UcZ"j.7C7wo75뱸&/! Z揫Âe[_=ȿE+J ӗ Ƨ!zk][M>Gwp| EHw+Wzw.7&\*ZjN?$sfeg.cG=>n=V[]>885OkG@>ͼzus)I9N9\g?GLzsٿWgM}7'9=?eK4fnOOΚ[OoOszDʗhܟʟ5p/??W? ??K:km>?Y*_9~~7r*~t|}~&Ts@\6oT,鯵g?GL?AlߍY_ki ~OR<~sٿS2cx~7'gM}7'9=?eK4fnOOΚ[OoOszDʗhܟʟ5p/??W? ??K:km>?Y*_9~~7r*~t|}~&Ts@\6oT,鯵g?GL?AlߍY_ki ~OR<~sٿS2cx~7'gM}7'9=?eK4fnOOΚ[OoOszDʗhܟʟ5p/??W? ??K:km>?Y*_9~~7r*~t|}~&Ts@\6oT,鯵>GD?#Vk(:+DDG5aKFhb t! Х K-}ՃN|\aq"$xYCR0L"aD&0L"aD&0L"aD&Q]ìu`h.P &$Z" Jli!f^1Z9,A(s^zM[(VY8)^CMǪ=@R* ^F̷wۛ&: Խcฅ,P|SD%@sY$oBbnޙnXp/TrsӢhdK\* @ igZgXfjⵏ]8SkWcy IC1H3SqI)} ^-fF]i}" ]nqG&ym|{Z}K|,rVU n/pVm YĒڧtǖؘe Eْ7PM8Bsz}EX˷_;=-ߐdXj]WF=ԓYܞݴ>ۿ:k1ӛm)Kc1HHG+8ٖSs+mSuuŅD YZ:Dz32t[ۊ9s ɷe db99َ#@7;{b,7=Y䌅pZ|!G 1 yxH1Uli:@|q2yh09R3eT;oT.wnG=v6$x9'ᎷN:@pvtqR.l Bm9FUEA'a,^ds2뽊=UNߩl r#VWyη)tm[eb\n- =1>Src"Ze%=lE-& Ҭ`5dgز;C6[v4bq뭢J~A]{ [C^ ٞO5&迁G$,Ln''Z.`o}dƞ1%3 6Oe#6@͓p컮O-S9}>{w @@$lkD1stIhh(+3IuLa897Q&ٻV#\|Z-pڢiqڙגs;L&w\DnX_wf<s(de{gw_D[kI+29?k7x Dw}:eqMn島Y,Xx<"oo[C mj[ϻ[&vmcڸiZ<䃄{3kfnrQP1TȞL+;!-$SJ)A8O}1v;<^~n3FHVn?rdi,|o t+},0ѷ6iifkm 6-8X-%:ܼze;KыdrԆY4TQ!(?Jn˿Л6y 5$؝UaH5=unܿesY#Et٭'=ut UrWNkXfg"f솷N\HnðzײY5T:2IAǺbYwOuCCs;Z$[I&=K&@.]ٌ[{pWtG1W{mR,o :B S65X "Smw[9:R+>IS WwvNn@ujݵߛ4isffbMeth$j17uga$ŭngS+ p5Kx_Ifpe,UG" ;2  <׍w*ƸW^HT* ۫ >]euJu4^]k魠DGmY~$*Վ7MMK|Nmk>v+XfQ/HI@YeSQir稩/U]r$Kݴ1L Sx\3ݵڙ+kͭm#׶VIkEqΛc@7Ȣ6FlCX]o(+8jPslr99cm#MVd덊GV,,qpC?eN3{TbiCY[^,K/Ώcr/yk Ra9s3X<\l9ryro4m é\4Wy muZ6GCXL:lhlsG&\f)\:Dفn,X)s-rIw1BKm52».q̚.BQ=N0. iSSmDŭfЩ؍YA;C~Z'G. vϯQn=[[z8

e:x@<"'ɚD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"a@edD&U=y%iْ4)}Ǯ+X{E6V1@)=^H3os:kKsk`w+nj7Gn><=8G3&0`muJE 5""ڡ?{JMIJ¾"d?SkX}SDY錭h8*goXAx˓k\>i %9kۇ;rn-Ԇ.'ts3nᭌ84htӐKm P=T?ivңivs[ 1T$qI;DIi_$\6H-d2MybJkKqى_wt5K{pcFրµ=xch[wiPj2Lj]Es =QLc JG$6 Nke=X$aO+H$(]o {OpZO>y=k|5._\|fᣫ/%D:?rDZ.{#.=#jm^Gu5sb9j_ےb`HwpX+J3`Mj :B]yĞ,f嶣p8LWoruS$1`xƝTp={ P0Fo3 V7=Z7ddI^8WxmQ[)է(iZ2C9G-7$LJ<Ûѳ?:snm l>Hl(aAD Nۃ~yiL- #|S{d pX0:wxj{ˇI I5W+,Fasw_WUµ4: P1ŞsBQo* /pLeK}|F?UΠ˺'OeZK5uK1"5L^g"x}ϝrrU.;&Uy=2-kX g<Ҡ\֞⎷{-ܰtE~9+T:FNns6èD*M#Xjq<Ǝo{}aR@8w0. m@MhV;t&!jWq66 Vku* %vFE$gdWD#(O%r,,8mLi}K;N.Zla<5rTV9ƖY7 uy9*3Lj)+ЮxǧHpP3Q'VDM)kt&2v f _j).1365fى7]>jxb\]jaxcO*S|J~禗铴?9#,{?/ϒ=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EI;_NN>X O=EKr85ܓ|[غ=HVʸpB0~;͍/}X9\tkAqw_+#|fen | S_;J*Zjqw^= Q)?,An>cwَCmLH a5͡ QTmllVֺ}>K$z* ,aZ90L"aD&0L"aD&0L"aD&0rȮ3][m+l'<#R!qjOB"2~1 9=NzO}nҵ]ui̬*ߺ+qfۍ[;Rxebh"]i#+{#_u'ʎkx}4g^ںL*EzԲԎHPAɺrlƽ /'%ŶU C1hZTW%^7R/͙#Yc%u8VkϨ$8tpp^`ھ7[Ds:wRM^{C>=\b e'լ^_eCC0‘emL$WeܪQ_z]l,l7-ϴDkuT+Y9,M6.BJ1UCǵTNGb! QlQvĸcY =Ѹxk98!Of\n,s6i!  PAfͷJY"LjEB*.4V3[CJ`ŸiivnEvYk9+H;Ë+HYO,kEXip޸Y8IJ#f؝kp[94KɰӬ bs&틒hU:f"Ըޙ*\vƇ\O^\ػ֊IlfJZ0H] 5e!bE 'wސ^@w װgvk)ak\c|MܖcfŝI1Jzsq{#a2@-XC]qi v2W߮z蕬Jix'ndRehRfZMo,/Z.쩄i:b7@zXss-s{ pMrB}.tBhrNz4Cg> Eop{P<CkuTClŮ=?]rlhuYAD@z1oR%Nt.1+k73L sd+h>AV.mտ9#Ym]ٗ{08.#k>߽kx ԭzײg\8cϐGRiUjJQXn"bQH|S9*iuwAp;Knm;Dt6;'eZc=dr<,fo,f"uۼ;>ks:Q i* tbXu &o!WSMt~Τc/v_SӼY_Z3cLDNɣ 4u+-ɶnaqBh=ٞ*&v.%IJ71cI]!]R=)! 9C&3`W杶B`/0ВvG r{ 5/{~[E֑n1,{Vrœb`Y}^CK$ǻi]ẝdc'q]%m*>w۹*j+g^Ķ^Z \a!ji=fbt;*|3ܹ;Ls6EdGR6D[}ۤڊ|gVzm=:K }v;i1Y6Ruj!zը\N-(Gsx; kmx lcW{ Ž!L}kce*ׯPu$\Cf ˳:/vq2 [Q:X_b̎M6_y!hc3{\Gg&उ7oyg=y,㚥&u0UjAAY'lvX@E@:6(*e[[ͷrsE1#+rxq /XR:xk{wisA.̕}4n)Hy*;YA2U oƩ밨vbD; ¾؉bdg)]uեvKlt8dxܸ3BIq }6qavpE+ {oy4w r~~d%v!XjM uSD˲mړr%+! bȶUlq}9]԰m)~֒=btwV"o\rFt59srxY&@\ slρÄ&3rH5ϝvekں.5 " k)ۜ zRC}MFRflVE'yX۶󷘁 t/kL00=mL;鑮h0Uti,")l+ٴGM%6;Rw#i@*> k7F}۷#](:X(gx\g3r̮6i{\IOG_MXcq2pq ݣ1 Fed)(½p V.k)Č@>_\~c$ KoM ۮX"n-4~31jj;fKm9|.Y8dY%ND;8ϴɖ~8\(:'3RAV0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aEv$&3s_#SMc0,B>fI&ĨMJvr&mo tT2F)͋m{oxyƚ&"Gx&r*On77AVEBG{y_j;$UAW.CL%C.N_Ӵ}t 5 =_V.kPF y7JU='_j⟠+\QvAz"2Q=|v9pGSO?Th鱸l5JAwPrmÙ$)za1э0[Kyq=xд 3DLwneSzKJrxvH-1JȰ9\EG(gg:j f+%"8NE 4(hc;ȏIp,Ym|[6{b^,PfI@5P5ii#G/XRCqo546mAhǪE=5M*R겏r q(*JyRy41JY/nCNr9#g7.&?%7Ba)>ho,H@dKSLa2VNʟƢ\̧˯ŸySj샰`M-{s5EbG#IɆ:h9|uz0]sK/2k8A:}nA푚xgFV2ӇI\ ?WC) &EHDUW6z]Jn#Lph%9JBf %ڴPѡw78ҕ9xM{sl!v^9gmºxR{Vu&+ȋ jWlBxBN-Ymsq9. 27o',#{+S5][\_&:a-2j1쎠ם:h;?mmGqڃw"@lSTC=ZDWIA8V$&>RJ7ͭ*,qK"1G8Rq.<底9h3Yus//dmFuFvA'I7WksU@WL4{ Ga]n*16tR9ZA奖9E&]"Zse\Dl- m9ja`;#|I341:"`/hqCV4:辜t'\ndrrG@y_'c$M յWP3rҩ.Q"odٮ~B obXHo83[89iJ6[DG9,Ɓk n-sE\Ma}ExERHy9ʭ,صzNZ,ܴsG튩#fj/r7ܷ֔llCcSL(VVgOu#v;W +K>.=\ַ;_y/.-SXEQjjtsU |KTTj7wd0蠌oym l,Qd]9G€7wjDqx y⪬鹞H6V1K杹9iqxh Jas*Zdx\m{7x\ΎFQul[ 4{\n}Gj_ s BraS\eʱl$jEJ]6iKjlp֑uޤiFPcWop g*cݣ+ʨ2ba-Y+̛KƦF>r}@caрݞ!p͵4!#ⅈ՟Wt_K~?S6~c$)ZvVcܑyf";b_fo:*W!@i [{K|`{CX5ܖwLn2#P4C59P (\bi^$jE 58+FT)#(wY֨CE-|s6Ihr-O>\[bkjأyKsI9Li<džٶln#TMx28iWL4 cv=/R֚ݚ<Ɣ^-j7LQʎY7D2Ǭ)&vڻ.I6B53Jt/{5DExnu[.^Wqs-٥j"6hie5 쏥= }>xL8#S+p::*8S]uiDT ɴu@F?v߈p9$ `Sy&*`Y]a[˸,i$J݅$d+NL~R=e'Orss(Kg{2oWtdDw bipcȺa+z':2WOc5ѹBDz."-t,ȉn!έae{lZ7:e[fWm)F'w'Y֨>@D[IƴE$r~a%vhmv èiXʗHA:B84lcIrW5ϐD9YݏUr[cogQb$-wh['=~96)U\*֫q (7˸]H7I؛r[Lie78#\LEtR7n @"΅c{]vhC\V x /AC8I'9#%1pM4(8%Rg]%^E }:%"V%4v H;P?5[e&{jEe͈T.ݵ$G4?rdmodVuhdLv  %Ķ;1wN]MERђZ[h\؛~B Aӿ~4*Ͱ6W;Z*-VB`b}.}`}<FP )\WY9l8Vـ|oiفÏm*;Kzέy>~J]Xڿ/@H))Ggh]ܷP0@Dq&ila";˂<:@xKB4;*Yj!K,-BBԺʄm~*FC6!JCvdN҇zIw{n.{I[!MlpPZ ܚ{Fշ8Toe)7@HaM.STPBTJg:Q'MP@,,JF{stӎ\O8%Z̶p(H{RvIN@2Ӆɭ˾pYb77(\]28=guXL_4st4;m x]o-n>XZҔ>%/ٷ"1:nYg|iuc*rm)6_47MK,7]|IE gR/}. {"ܿ[}~Ϳ uR>_=|n_­?fԋƆ)cfK>H/VlroEcC~tϳ}t$[oOٷ"1:nXgپǺO-U?ܧߝ7_,|iuc'*SmHhoΛ>Yo1rm)6_47MK,7]|IE gR/}. {"ܿ[}~Ϳ uR>_=|n_­?fԋƆ)cfK>H/VlroEcC~tϳ}t$[oOٷ"1:nXgپǺO-U?ܧߝ7_,|iuc'*SmHhoΛ>Yo1rm)6_47MK,7]|IE gR/}. {"ܿ[}~Ϳ uR>_=|n_­?fԋƆ)cfK>H/VlroEcC~tϳ}t$[oOٷ"1:nXgپǺO-U?ܧߝ7_,|iuc'*UpWktQ`d=Bci5N9q6C-ݸs@w4ùimgDjm7q9AV^Uo gU$X4u0bohwyx Ț'G4gt.^.1Wou֦ m.8m b;ݻu3xsr]5x &2<.Vsfq”|K$!ZK<])XFxn̯M L<"T9ڛÁ}7ҿy Kb;nqylL.{K0vJ#v$A0J4ű$.^Rٍ..dWVwo{djzjnݠ^2c[0YmiFn*1/6l h@' ;(4ТF*Ӹݽ:c&fptΛj՜SO#Km7l%;|72`klG_tLn1[kdw3cg%{*=SXjuN.1٤[53׶;%+ZCsLȮUjv~3a'RAD:ݟIV{-79l}i,: L4p2uwceubc[3@44~P$p-u-}jK b̫Mtl9%0~驛AyHQiǻ1A-1qf-mwѸ, ж>iNDіZy쁢I-#|jt|`⺚I=b~A/Ƒ] kN i4ltShU%nAꭶ0҉rXcga9K_Fni^̱z.#;U(x[.!׆i6Q1t][=..̓A5npi9L C"&;+q]t +FJ=jg) fd̰sZS zѩap'$)榉DI/[a~d1ܻmŝ=Ѻtbu=.6ⳝm]6-s"X#Y>f+>&.1G4d_C.occĥhD7VeIGKWB1]!63[=p0wrgOnO_x=!Zx+ltkZ]$׍B1ZFοv3p㷗+_k22pGLp*ƨVm)('m\1̛n]/r꣆C숑>y6XwgdӼO &v]ml8q/lPەٝGgmopN sLsĮ}o!OngOA~DыxVm މl&%1Jc=ϧY͎'v\E݌>ym8a2T6[{ZG?=pc5*7:[8UZqk7q}o+(LrF4piJ*h(TiҤq#dJ&bY!}|J~, tmޗ[Hk6mc.@h;2%KcY~n>IَdJ3uFOapsO3>Ҫ]5C# + LEyn~҇L%2hD<:奵co.fo {l^ׂpYn7qd-Q\Gun% EĐ:;ӈ,uathxDڼdT2v۫yuEAh'n:Tp\rުvcyAµy:9pYLp:HfHZAlNm 8.˶,pL)JyBqkV r;-` ʋ*TȗMלbH|LA1 țc5՞m12o;ѤI79x>2mbЛL=h%.\h$a< ,4TXD<˹ģ3t2 ?dcnrtŶmq{"7G0 q,awsdk'L/lWz۝-G 팃CR;QHj`<T)I+ 3q҉NǘB^""Un*h,!(5㷫7.&frLL][e5o,^NRnXGtJ lm/r {cE'Os15mOvet@Uȑ](;VXL;9E>EWL&)JU n0ŏ*-}t'RVJtp%fsN-0X,|*J!K G>ƻT1Ajw.Qwhx0""`(|lٳK^&(sۙ$[> OHF8CĽxs^{BObiPP2 ]w1Qr n=!d6'[93^e h! NGhjxp}F#q?]Og)A R{6+e+OW\%ᩊvNTݪ}RaxFcM\pts@nZ;SLȾGm&Si 4cyGt@?8ߧSkQgn3NAB_H-NLV]CLWz < kӬ?Q<]1yƸ}FMl%5t&i6r])~&gw l&$eΐP&l., ̅md+` u˵"+Gf&D5S bpm ˘))1w.6U\Mwso+DH e1֙f Aq81Cj uE# kcLcgE#9%PGB'WIv,#tV$n:IAΣ+b݀x9¢ӐɨSB9Q!r9Lb b ]s&c\ \   +5k H##9SD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&h]_I0QBWTy`X.G OSC(-Bn.hOx p^⸱edA<)ƒ51w.A^::$$,uܹTNU,N&9DGZc@cG8 Ie2\<^.q'5$SUQ qF@]!P h|d,yxI7,hꕖmNܴ }z"J_gtb 7{%܋xZ¸4bڤnեאQ#gPY+llty"S>ȩq#H@+gn?9wtƞQ]ƭO 'ߞWe;"f"[H+ah62ݧ>$1w7%,ىe}ۚtq*O&xE e,e u[gVքH,SNXĕweUnNdU%A/+u>") kyCsPVݯ6nH AJt\v04-Hр.)T=S%>ɂg]b*ktN"2)]_;K=9R% 'CVXP8REeplq6۴dEyZ:=:t}ǹnKosO{0N")p@JYxRkc ECȜ>?m3B;I#X>uM|㬝}xk˥!+Fեu4P enOoz貹M:bZj~J P osiG2]ltqs3mqc$|I<Ο{ɻxnfJw{!/ƒOoIc=b.yKbˮW" ePZŷ\&V8M6Q<уҪ|o=}s:W>04s|n!&4ԝ 2xY뺚CO ]A˂|ා$yAԼC[O{DtP#ZTqV5[P)ހڗ\Ϳ{cD(x?"a$QlUg;Nj&F-%sjE|4o[ VcpL+vJ[̸]66ӬX4E]pܮ 儉ә5"(3.8ţܶQa+JnV׾PV+o#ɽn-Gy _fhE7;c4US#|c0iÎG,rHp;ޒܻHpl&6Gɉ5yByS{qf:qSG(9l Rm̞+k26QL^3Ը^[r#}Փ.׏<-q4QG-jz:q^nlJ '/"l,oy˵YŠ+[Gs(g?.my-4P&0pXU OpI-]4.:^ڍž/r/#|H$[E[F%ucP{ DfҶj¯g? ܘ*PafXmlL.72 dtB.i#4{$hu(XqvP8]Uia2WHH6*%ٻf!@nQ;cV>'7tthm@|NbIM"6` r[x 9k{SZkyjy6#fl8S.HrdlgղqA)<[[s%Ic NOslx<9Pǟ?>n.|N-cO.]$ ck jɧ8aVrՎ<o-F{J쭸D>%͏iiu{)!1Uy7fUbiJ%Dž}Ӎ 4#{\4ھxь탗[4ON|I^s_ֱQF)YA(0q)m9!r/ptKH4b77]VpIu#DUkƓM*J}1ς8*;l;̄X<$<J#)wl.Ҭ4ho45mA3nT1=A'#1A|2J}P%,Ͷs# >!ɌŃ35%Ay D CVTp+'y,!bK|!]qk|*j8b Jz)w&dn6uM%m\%:.yՎQpeIbE0ľٖ8% dl h0r `UW6Hcoi<\|.s78>2xx7V@H뜭 ܯ5'[Dk)\:v&gdw3yF[w# Hwٯ f3bi稍gkU?5=TeGNu c:]ԬÙgO]8K'}}FC%Ap@ց[7L-O2I$$XoC n&sx`?UqW EnUAPUzn}l,"I6Zh<ylil2@dL^'ڴPH(Λ*$L6~ĈxYSz䢂 X`U-Z'GftJ)XnFkp-˸\\x1D| m U*B5ܢ6[,~⧒hkA̼'oD&0L"aD&0L"aD&0L"aET߻F(Mmdl3OuNw0R+fk>`͖1Ț1Jswu nW!zܔ"F5q*ϪKV nlsiN "#¼yCzs:%lI"؇EdS~$a((0 LQ9~]l-яi1Ln܏BnxڎE|=^1<R6=8E57Mb7x6E 5퟈sK<6-t:ct:+ jm"XTbҕ=~E)1ZIU{0×Eܵ+xgOxƾ+M@ҴWL#l|C3w8yЊ#Q^U&w9\:L@Zx"8K8}uza_I7[IN14zMϳw59˅m19BQohJ)2QÝь'+c}&N e`i};$j9TUYL@8儻աm|VN4*s+|C2dy_XO+9`H?`Wii_e'+}FptER50@ze6ڏoIoahi1kL8F![߸77sD4EhE WK)Zx}$NNrJrG5$fcuʾw|AH 6 ޻EWE)Ru(/FpX.\$my0HxSUd.<4Q#9SD%ϔu߾JMK^##&#O*B9WF"S&rXim6ֶ6ek qڂ)*wv~rY]%kKKA Ǒ!j0KoYDhkJfsVJĬؖ[٩=ʤ V-HͺB$^ >OoOsO;p6#.Rxxʣr؜6XA8=TE|ĬwzewvP$U\߶tՠgk6myc0uV&Jm DSU3L=:L7֛J;@6& q!ØQ͇3 om}w,Lƨ].얨S+tNA+|DS7Er=Lx88{{=_Du5s+CnYl.a7ʾS@Ln]nxlm9z6ˋ(>]BHWb3Q;) %ҟ 33txKd =yn5ὢ=[æ &n<lϽfL2pwdUY[6v+i $VNi 9!XKxDHZ}qD* Pw4aB[dz *g[B`Vԟ5:&sg9_Rw~wtf>/{>o)ik36!P4+?R{3og28jܸ[ZH**j.Tr4ѷ6sy79ZI^;m>[+{mդo<♜㙴sM9B;%͑\,aQ7g5Iʽ 9a =\38 :nW'KnZljՔZ 6pi#e}( 5{>ɛj͛p!Cͮ<+h4Uw/E_&S텭5Qrcb bCrer* 6T|S|*tku_m5h"RA t3Pvy}za{w<~pCxܡ4,6=ia16vSDEx9fɍ1~{=9śhU.ߜ>8ԗ)!,U>vY͸;qv)62[}^QFó& _4LDI ~?aiTGçr8G[;C7Y͓8|ZB M Âu66b{kN[TX7LdQJ ef6vV(3%;COPvc-mj* Z(FN'EJy;C=g,Q/ym|K9µ;n{Y# p* +J@zc:d\\퟼9؋` dbAx n!yGT:Yr/!m95ںO\vKEj [[E:Q~t+3֐TL ֧BZuN)GH8)9E *>&⎪t;|+d7-<-^sb8c};dT;oO6?ޱ1MmyyWV);@qdyZ^86F#5gBw,[&/ٻVbS5tNAIYm0t"۟lŐP 8\@uœR[>7kmt>M uZOyCZPH5FhC$kOURI)1pVıJ&A`8jnIb鈀HYΉ~0{-_G)oy"+}c*kLrWKƼse1#í].{04c#l'mvò@nhܣ& ?+KHR< .RԿwLLwU;{CfۙCެ=d}Lenևw1֝5X ׈D Ob$-1ǯ˖_dDja>iHd:.J"j K݆fQ !EO G97^Aîz}/NkcqD$yuiݼVͼdWTgjWk7VZ3l\kdcGx$LqVW%WtҦ<)+ $9ɸuQh5 gtK~y>9߻Zg~j-lKKI̮m^ˋXf/`݁#\7VL햒6v;a{ pkdwd*oJ/xv 5@Ź}n*~, UhB|&/P~o,n l1Ź[+i)ؼkr6$ci{GA6uL3f Imx,7 x5E$9$D^5Xy7p듉FaFQ*2KD,n$6p+-Ss|2wS\&ƷNg._3ꑭyKIݗ0hˍ{FijdWh{lQF1<Δi:+$Na#yE#CRG>i&~ɦYer1xtB!-g<6 2ڑmcpm}k\1p]f߰D7}ԃI}ۛS[dB>4$!"jbQq7_!@^)5 {Xeo?m mW6-weKn۸y ys%؆)L,Իz෕1Lei(խ: uRQ6$@bd6w p0fePp *SG%w&\9Bw[^F\ sZri# b#wejr{Kx_I4dms61E4i#O7W k~zbLhHEEB~K93fFPpgA;3o}w>%a.pۺN k'9C)/9ClCt帆x CM$LTO+$? hI(?&Le2ÿ|LÅǪd1zsl\;ܺNOI!hXy#b̠V6;=-GaKsVTIבӔ JMf#4u%5즙4t!k/ΒJfS4z_)v>g,./a_Bji$3|:εFqfRA6y52smww?װK m7}kY -ի:Nꩬlj..qP7 " g[gmø-0xݝ "ymӜY<q\{P |gyf;f^ )t-[Ʈ Oj9#|gJTײ)uy7(+SVJIx)4)YsQ0ˬ:;?->>Տ`uWw0 -w@>ѶƓ[HE>X3[o( ۇ} 6SnP#G9+fV-"F!]3FTLPђ;EA 69NUN#`.U p78V!m{|$洝ұžn湲<1#T9c >6W4- d$A4;n Rۧ $H=E峘hrhy*͖Owzb_d%߉lS,RldlH_AeCjӸ(m l sd x\5GsBz }U EDa:`a(OeYo,00=4%49q4ӭ)mo֏[PůkiJkY*XtlsmavFSrLJ5WȔ-)7 %)_)WLAAX $[}ȷon7>f]^Y1ih:Lnj7 .61s"a$DW`8hI1O _{e7S唃%pHrèASKg'p'57X,7hdiX%ZՉ<{l{m|o {HSQ+]~ ݫB^L*eJ`tL*4QbL@,vlA&˽3#/hps˭baqqKf #F쵥ٗw2!umg4 myV!<xSHDe$w"HfP}i}XJ@!lnH[ɥnZƞw;k)7Lb֗5R2] -i';gs*hH<"^A`X<LD*?Fb=\;_!;/4J=rƁbj=}cO#׌~)n|S{G✽SNC5nmEhx8Tr(8agŹN X3Pɢc|w N!:7lu*!Ȓ%$OZ$WTf[$NYF(n& .\x7$4l2 )U,% # GwUœZ); XuZ}SZ8^7%fqp 5Ht5q"Gs1h-kC6[+.ٲevAy`<vyzćA&nKe^r[̍ww>ݭŵM*l ̛LZe{MnĨDrq_IcݶrdžHkcu4 @ր gm/1F VvAc}DyqR{%Cܲu-Bqlc8HQ+,d"`aKL`;'oN{n%eh={&qi:^/{;V=:P;o h{(^Әqָ5IVϬ{waBӣҴY_ܕ^;K xRN~e`LU&T˸E>KEuǽ6MOll.wOh1V#5怓F'RdnPAh &PY{Bv4{Y]|)Q< \^V6{.4!s<.*k#{F4+VKx#ah+ ico.R90CyDW8gج;mvS5`ϐ d":U=s[xh&}!:q sOd1 o|gHoyp^c,-J)cy1GI5}}=JX}u_s=0Ðɶhc2b  wu n3udW3?H'֊+. +w\;L,mI <$q'Xn/'v=7vLi#kI9)Z^5®u~}[6dXʕg Oh7a&[1I3scm]q"=w wk"e\ƒYeyuh{rGԂV/pF$qq!fCQy,VTqqx.A|9I3ʚiQE !P9HRQ ׏~{iwҮsEy i-Y#,,`dMh)(a"D*i;`X~l;[)e<GĖS/Nk4O$HEbWyߪ(U}?}5h|4g1'ۗ{0nNE\u-b/%Ou.jkic1!Tr% "ټ_uo 0Z! 84Υ .Pbld\À +Z d!zD&0L"aD&0L"aD&0L"aD&j%-xOqeCT;2^ )>)|U-itIOԔ2*&9T `1GàgE***\Mm", J]ZD Gr>#;c8}bWs0ՠ3}-4<| ⵨IS/uBC! W:;ю%/֗;N=OZC9S/ =i&G(:IPCerIc/ڼ=,P+m\T>(AKrL>n ڕ%q#O.+S$!}>v`ں?DzN']6 FnznI# J%P@z ?|E?Ó=hdZ91E6'3[ԗ8eua;Ϥ2P~}Cl@?AMu '<uGYeD}ҟnĹոo5k^R#SG =nui|z7Fn ZNo c?ZGċSD&0L"aD&0L"aD&0L"aD*EwkŠWZ"fG0(tΒ tD$8@6\pGt`u㲖IJPu4-s."k vQ3η \vnm$"5CpsjB[׭eDZI0E3&j<y*S);GHAOOy :/G_siKn>tݲ7+7kqy> Y$\Ȅq`ԕIIɑTVHQ%RPtIBD!J`D3Cs .--hs\5­s\* H q $Hd1JZH A *5j[LjK JY3w"ASn!(-܍} inaxq[ɘ2lͭb}o"}I$a W҉ҥ!TY6 aY[ѻzJTUnu٠`u\׶n㝴e/ ƑU6؞ j2K<9H@3>3W[[oJ\*{Z!d@EFˇcHEDztU  9}=xN -.),0Om;9{yZa5[5>" 8qdp>ɒ0Cj ݬ.f)Ǽk6xy3uk=;W@Rp}2/YK2L?|auc:FAWvd6k'NQXnb<㑾? ;QZE^b|آ!6 П=QU")Cqtgx15j¼hlP Eo7Fnf9^;5ɑy|0YT+7U#>sءD d]vxv,,0~ G|l]]6ݖ͹B85x%m ;;J-l1]ZFx8Gaֳ (Ig.R=W. ւ;Qs[tUzh͵7WH7=ɼ^J!\,Gb#NW/QrX+.r0.*s؞/YB.sUJ~ab%OzkZѩ5?4ȝ~ؑґSG S8=6#VdXe\ކ괙Mj1|6 ]G7VsNٞHhi4$OuMTR 5sJڬ XMV2kgfD%urQP63cy&FnX;IZEbEKhi#AOmvF;2Lpso1o9jx23_ HވkKE6A˦;i!ax"],u$9Rv<߻Z9zEtmm3r˻WI$L)*WW쑱hRGі7Wx E.iu TֵůZ; vw]M⥇l Sخ(`YO eWxMŬTQ;~.J/H0~T2͌lT/u q(6ϕ1_8 _iFGd_/LzgY{FLX ww,!fIU?ymޑ0f`]9p+ҬiZ$ۼ'>iG:'zu>jծI$׈m@m7&("{%hNǾ]]y7O+)HsZ^[TsmǼkǮ9:UN;{Q l vn ۊ^ uHko &ŝubEu S~X\1re"˸߀-2l7%:_b2V͠if`5/KDHN2GF/(ψRآ"ZW{=`c/-8hKdv_\\A6pi n5cH`~s`1w7ֽNڷEz=53s f p!¼hͨ_phWNfuy-1/]kCC]B*:leOtKp"؄]`'CǜI`=n1xhaUGb[<"m.-l7m'rFc}u,NZ<0R$Gֺ5Hf{ XULLQ Ҏ-7<粱nۏks@6a˘50LawQp"lSՅ\ iip:78Uam|cAl|žѪ-30b_&d\@֐*2vhvBf!pR;0c/Άg_p!aqt%FnCdi Xbs XKݾ>~cƘ-j>X@%l'asWQn,>zLئŽgY`Fٕ?-CoːmՅX˸ok0ٶ8ty8mc#Nki2z(^!8K;`1cttm<٦?0[kr[|{C{ 36PѪkN`Vb<$kH\[˦ixMv:s&GU^3vا5՚N!aV*&;熎.oto0b;!ZM~%Ԟ{Ky^c_mm`H˖\Lx%2L&0əm-䴵a`m%IlFk#kp@ r"łKk5ڽ({MBµ^"E~Xk@@-I>_J؂>wm:&˟t$_ wkrSTVjF1gE zXlYv{~m{rg%7, 蕪2)i&@MT ,ЌJ ]7%(n+Ӹ=nq 1]D"¢$2j4 kc:EC28jk^,{Z֎*fI}UQò{) 1訇D䬟9L* \[ᮙ=#enO3dsw$Zr55؛DN ָvkcMp*?rMK*gV4te+$z$QhR+1P1e@&!om:4dcidV\nSu؝M8kM;~cm;a{E 412BA1e`_؃ٽbya$ ]CpҷVܗ澣37X#tc kDܖ &iobސeqn֨vVV\ԩ g;jp08h:uYS9G1J!ZYo :`-Cu{\TM/cXSGV)&/ts2iG%A jf) U8r7AS)Y8q: f.m_."IVM*t& {ܵ6M-/fzK|#17=xi{ "4b,( P;2d7M:|SuYlC)ɭ4hr"Rv|2sAM@PYS f ) óގ&m﷝-xx" K GC s_ b:Z iZT>'U#Qi"H`9@K)?Sb_ W . 8 'њ(") %f ">ptE ?l1)1sb{iAo0 ==0pfN9Bը#p SBLa!;);M~kto".% SϚh!8yWէ9SD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD-☡ 6D6q dKӼCDtOަg9u:&jcKJ3v#F*\I> ?R{(9*x]1ʦᥝ4D*-[[nAYNzQ(X- IOR!JI#4}4V 4i~DD+,+t9x"I'M [@tZd4xOē|>p(*\\hÉ$q:JXӦt]^({ 7`z!éJ[ח nSO+1x| #g"x 93S~!A!s3*)Z-#ZT% 1nLGȧGpEl JEP*}tu]aikHjO8xVˡnZ5kZP\U'\4sd'vM8Jǧ2Ԗ; Ӗ3p/;Jg+&HI]fAш_$q:gM%Qطib{M'L2챥S86p";ʥ5V0VL3u^!jU6DHM*?je 2VEQAҵD;NZѺ⎗Di145!ͰJ6NI &URtkR Pڸ*_{ܻcQV קk8sЩlcjuvW<믳IJ,RJKie[vڞK$h֊5h2yR(ьh hh( \jy@ l0'K$#^b;~!۰tšAФ*F"SUؙ-A_xWu/uu @OTSǤj"^)u+) ?g>PWN/$0S/4 R( &*+MI {y_;R*j`̦UFa wY6L 09m̈k kC:i١*,) =EQдi!;65^ԕqKmgX\8&-UE\X"ɻzv>Uݺ2, u|{P w]y5s8 4r&:y,XIm49](Ԟ.#HU8ޝܬt Wl*'0AsRű-ؕ4<-bٶ)̲-fw#ydwVt{6GGJy'o69f\Y{ؠ`q]-`'[h-ܷȳH¹9I]kž;{D\:(Ee0u(F[6[.=]i0-7 LnypaHR@ (GkEāgSZ_o]FI&X}N91 &5W $RDp1twJH y quam-a܊k Ch8  f{uADxsO&2ؖyHyYM:A=ktlx=m8khGt45nH5M,Îb؟ݲ"]r{!Ke^dt4x֎Z< h-ŭ"١\j\OIMv86U$=d\zr Wiao[H%3&~c; U۳fwq%SN9ͬeZno.2Y &S|12gP? __g=N7* Q!lBGۡmMVkc#畵^hþiQW)q+9ӓŤ0NT -Kqg"5 jExI%I'OqYiX/.{U{Tlf8_Heʑ޵ P2;zRL=Ҽ3t;zQys?y'rcxdR#q2 |˽=᥼7?qR<қCv R5ovfS‚o -Pʪ?>vᝆ DL7xlx5.:S> 95^ Э3܎\hQO_} ]y2؛}_ecAv4 aTRi"bJɄmmsLw7߁,%!.w=Nlw^>3%?kǹ HjtYw (hZɰgs(/9'Sls\C%Zku@I(+2+Z[au g e#I&Md {+ޠx=SRn{elٶfѷ@(T,+cb"7ܪb \I"CenGQh' 8 :Yb3, @|7)K/p\ubɮ5~N™,R{M2oNPJƜ3,*5T`T&n6\\.g;5{&/9cl Cod1ۿ$g|tpbD:J͟8 !Bhƛ'[?kEaa5D (dQiWBw(x&b ۀ\ꮥwNGt^wgM*#Z}SgBcPj`7pJkj4DG"uo>M8ꍧIE8NSMq|fHӧQU=Nמ_mz ӬfAK_J+dz ]u-fzt38?V YiW]() S@Jbu }._E7R3QbX!zB{DX@D@:_uEh9C1Kz_(6$ۚL 1" v)wQ/,uY봨pnq.u#tDsh/"ߋT Gc1/=~Ý{iq#5u}ۊ6[_Xrۋn>}>PmjGRsI/>arG9CƓ ~pR.p>rNɀpUrGĂ"잓k3팧.X?h׍5l^ [ ^LG7h* >(n;͟h撟V`Kn37QiL"aD&0L"aD&0L"aD&0L"ak*𳨜s9j NCHGPQUpR(SrIWۻ2٣q="z'V#ptS]{BlyQ88i'T4ud׊>7Q i݁'Jh]z 9z&U%WPFF2C^#[?^wNKcqVK.|-̆{$}^$n[ i%u;OGmM_ Idchl<6H ^E7fy]xicÈ$( ]Z5u;; rCWQY:*.Oro]*]L}i,^dZ%VT37#6[xevĞk|]tZ5Gdab%EYa.dR=!"w _pI8f4Yh@.A-d%<St+iEŕE݅>um'6jYXkjnț0meax$TRi)4)J{N]MmJٕ=F7'D R|t=EFq@R˩97V6M Ƌ\ݣ8yx6fyK: .kulky6 7RL=LHxYrUan5*M#r+PʢA3t&u!rb  QA7} X!s,h| HCv{=8$[|n[)_vn&8G'$5  HuZEC SbIN c\HI/`8Σzt>l%ЪD7AS 3[잢]Mқ+79%tŌI<8EpZ9O/xYK0yB 6/o-8?^;űOȑv|JpX!9лkm킟m+l锒`sO==p YLB<"ym1$8xǪ'4P%Ir^ DO#~/(qLZu x8sk½pd?g(pep"0EZs=J,V:eh"t2QKDܛ*2v{BC-.cu~ø7rt. k x -x;ˋfԹ2XVc7;Mg͒mۮK;}@t)J@ܼ)ӣYCcߴX@A%K7Ζ9،j|P$J*@B^7F>ߨ}3,Lr0;b&֏s(`,G()6ww9Zu<8L-U{͹!Yͯ=Ē`6c+`:uŻV*8)Li1Qpy^3(lh[,ٸi09_nmKWXoDqk$ڇD8ih.{1P -gO]6B"7LXHx>!Y!k!ݦb8U\:WXw^xPC]!6Mg;{u2Y<ukmK{ۛv4ipLjANX 36qh.G+[0i1H<-ћ3V1uyv1#0;aX"*3Bq2LL @*Md}՛X &~i^/P^ti5ȫ'팕ͷ|5Oq}[vy[>ӾdDPdmF]\\^Ҋ˨Sd1Vb%@ת?5S*E! g6i]nG [f#tz(vPT.u1-jlyt. l?9r0,cd! ˘۶ v#ƥP,2^1yHdGn a`l^Fj*Gj,kF*~6c$Xl+huIl~\:|ȌrpԒɱ=ͻZfMqyb7bdhpjdu82傱b-VQǑƎHB"eMg%h2O:ss<; >m9vM@$~A14O1PݓXvsk`,N-=X)n;bH:Q:ȸؚO=F J; T"a..ĊDܗxt6h-v3m~c ǚ>*a)ߥ2m0"HܰJ8L9 Oz7tc=ZrˋȈ~S͋]:MGHLJ%jñS6%uڨn^]DUHРJs7.l6;qW>;+]}m5md'bKh]2%ݘx5̆xJJ3ph]%,#"m21Ss9AVR-R8DL@0N`2BZ=6/qKGn#!eFRF4rb,F94Uѽ<f &G utPlbU?=D0@;|beܳIq1FDX9H!8ihǺAݐ]NTOțSbjsuA7%S3uLT' 9 BrZV6Q@Al*EVLss̷p#K7p[jUtjD7J$L?9$=3+?ue}C 8&mϑqǽŀ驢Xmcw;N"֓$4΂`$q2.#0HfɉNM3W*S0p@ >ӎ y-FQ :+9xtRu80W't/Io('AG4ӁFPE1Tص5uDl1duԲgMVү[ыA%Pta3ٸ|\ňg-K]ı1A$ݾ*ۼ=L5,M=C䉎 ]MM|BH"aDy>aT0 sR") ?L|=n<ݎr,f5Aጽ0 |.Zp$qtwZIg͌Y$*bk\*Tdl"ݝw(6tI)9*L _i9L32Eh6J\t8.%dO!,k-=ڄmpt C49vm3k.$iMDa Aa0DDz@CzwBR . Zx4">k(PU3Ƽ!RttP1٫  &*Ԍ=MX&h[m"ѳAAڹӌ۸~a 8Aǁ< yhurCY7(9dG3e[(goPvCE{eH$cb|ng;]`GY? PWPpCI`иz+q^@`h+SC$^_7hFo9~ERM#1ffTZMCT**?fAɁsp%7H j(8}z_f;vwogoim \I I'jŤ20cޚK8TdÝe'V*3^{[6BAr; I[ٮ`w1RU#QsUw#ukqU{7W lBohI 06YZq϶v͏_]Bj=88&!by#殔]oBzoYUdDк3UQ&jAY^eRݟ&Y&C=kw4'H@yFSFl8[нB,39]C75b&{Y5KPSMZݻ-ƠCA)D+ u::ͫh( y*}ùM#4 vI _[d.1]޼*s@ 5pjk{*毤VC][vgm4btXGyR{V,/pNHZޛ.377={jjo ZޏҪifHeӏz>d"J2|wyG7SThVrEzn+.$xR@ yQץd߅2[GT Gg1#C{|M>}+7vVѕdSm)0 m^io֘hJ?tԺ8øIK}ե^(sXʹN׿ЛyoʔH3[nzl {z|g (s,HB5(2nO lvSm춶F6Ҡ!mLC+A4cJ{e{zkXchC^8r|هvѥԏ_fK^-mxNخ7 HKKU5a8}zZnHʴA0=YHYoMaG5v0 pq>hUt'spÀǟ :WWFAA#ͳ'Rg_55dHCk-8ZּK!_6$U㙇A]Cmgn̊V+IMj${LqA $ $ؿ2%|q :0pw XֵD֥$n-qK R"6 Jvط)ݷc\v)rS V$C ms"K`L66 h*J65sKn{||<;wlMf6 榆MżUJJI$cˮk6AQX])EqWlQNF%si^Gw~ F$S~ksp{wk||GԻ5-GR.frdj5^qŚBZiݱ*K wݕݴʔ!IAk J9@ QP0A LL{狝υ7|n.qSYxFLhx,t]uSAS:,ʚI$D(BD@|M5Zs_{vcfPxWϹo:dAAlҰȦu5Bzf:Q6gQʉ-3g6!cւ^cx>[qzzq%~+tzgQ9xgs# \,sz$M$\f2o]+X=Z8=~d*ݶͤmT '̓|y-?pe G:f/[ >T5^Tڜ$٧" "CV Xj}59ёs|<֎$XT>m@ɭh}_oEBT䌚l_@p']<+\p3E {Z,E Bul~!kG>$sq"vgsTFnyz789z}Oh\'PEL^6%`ٻ.j;N26|̪A5Q8,DUUkLn7r%6;HY8gsq|I㳌G{$9+*L"a_ż%pb/ZZgc? 7oi(&<;3n|;~zNT\PNt;^4ӝ*@*7gL"aD&0L"aD&0L"aD&0ZA})7g)Aov5^w{tBLE;>Qg}M~ ~$ʎf]U7$I~qH3h a2kTzJ?W8/rW&1˶qRwi}gtYE Eca$B/I6пSgP.:m]fv2Ȋ*C 핾SM~L z}VT&,n @Ŵr|G=gw;^G+j|aLWl?Ʊ$=ӹwg6C!wxy_63]3@BwhVN\3쮵+G# "q'%_S`;-oQV"C n3FǏDwƹ?+֍%l\..aqR` F7F7^OdVA'\nĻj3᳛-{;VLىL"aD&0L"aD&0L"aD&0k$ 'Ӫ],j{SH+F g1EP"zuݳfʒջKO:ewۇ:> ٌ6Uؓmٻ0i1(q^~<o$+XD&I׊<I*QMtEʲTͥeu3)W+j0 D@`]EvvL6kk\c7v3-sxV<9sLln|Ɍ5 X5E2f;[N۽M[e$o.[^\* I\9JOsx't<Ӿmln{."<4sym5x; jV6r(#1L(;lq~2g0xo7}A?vw<tK㑽<49аm{ɡ3\򦁯ddY+VX T P&bRw.sB sN>\p;Wx9d6zo5E5\~ar<:RxCuzP&w7NHdr^=]koZ@;p1%rmEoi6 &; 6׆oaofFѯ{Zֽ7; n5j˯m-[HJj: .ӖHzɃc8e]׈ۻ۴vK L{] \<&[8CDc]Ooz.--!1{ycc{0Cbu"4걸YٔwQ[mdT)3#Q 5DDb3 c KW3yvnp@1Emcdh w'鶞k]P9'keb"M!6ٶlొmm\}{mw#ׅlZ~Ĉ~h %ff|nďmEdDlh1iA`I2}&#h[n-0d-26l[45(e4Fc{C!g;r>77$Ko1Co#:w˪ך;#k1[@~ႏf*&ʊ$yWt QH|@M~c|`ڽueitE#vFuf!ڴ1_dt5Գh˖p{SݴoSTgjc`6oґOk5{ ޻$&T@G>r%6Oauk=Ol嶖 X˝o5~Z!Km}5xgC3fJidMH@Խ?jhbeݺ `W{_u e-Ǐ9RR9Q %d\o]g!dvN6)d[- ]ڱ{c}>bc_p-ي;V QX6{u]\ش}XȰy}*37Y2K{Vh4 ^v^Ο޿7VvO:ݷ vdqd_6&2ؖUݧ9ŀʹ82;9 gie6K KgG+iW :qq,U0$~lc(!L&/f-Ը)kx7A%T5c˙tbevç{ MG GS#tHV"%t3FeD UJO#QEqqor[-8JY#KItBO{{v)uA{*'< iĴ)S"Sh< -x4 VH EgHS*G`Xp!N1ܒKס:PG񹲳P pqm[w UPW^\ M8+µ=Qy$STD*/N /^C\ʵV\@ v*H{5+Q9Jp><qE`B-TZEɂ&rA/;pԦM %u 3 DP:cءNN{d8P_/ \7^#bZm獄I|gEZMWsᾂ_ZW2F2F*Zh ]^{\*. ٛ.v 3)^=rKSrF(*:ff>{k[a`"8o1ӻR+wot\,EV9Lb{>Y JFO>qpci=gINbE`k(q+%8QCEyG{ltzm7rqv:6ܹƂьԸhuayfϵAshA 9ö<[(qNWLF}̟qM7 AB%D.ɨ_` {sm^UX"q,2Uk$ l'MK\=Ǵkx9tHs,ME$ jB U|B0dkΝѤA?[K pakG~͐PְuyDT Q q0>1Jr1;rt> …3_;;ÅZI*8Tr^h}Q2|Ad$P5Jڡt@- IjׁZ H׹ixңUC')J`)QxwBL|uX4$9Tp<9kW1aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"л? MJ2k-Qd=-AT慀[/Y&ҼF pl)=)ٌm9xG`*JLҎ1xh.76&Ǎme!S(8_'?sX P#r͒=38,."coΣG"jxơds,}lJ>Lm.|(yeƉ6}7pԕ.Ml, 8'RHtQ'Q$+Zm:nI6UHZ48۲Hiu?Yq2v H.KLOsxBHsCN4\\&Wm1q#uo'.9˿'Hu TT>m 4'<q;!Lt2%sξie:;pLէñ[M[ɪPqHa{.&B.Wh?P.CAc 4>-hh&DƮh3x  Ǧ1܌^L.\:f$sYxsj́t5Q& Ֆ!N;Oi3nrxlcHI{|^d) Zd}Sjqj?x**Rkss@xEn#[W;@h!.s lF] kAS4y{f# iMeVM+U#X?]0cpS L/b hu(Y;|*\O.{˗üݭ:( !i(˞W&(u1mͯLT+IitѲ;F㮴(jzSQT8In;*պ"{չEÆ:T7kkbMF Ys;Moul7#%9fRW-cn\hL0ӌo9[~[,!m&ꏿ{@R6 C h;Emmzk+~hVCL]Lu-h.Q;9c!fI x{jP9(gXv~{4O>o4p=yDě u3^#SUаZlYH1(A7Vy1̰^o;jj;zƲ8W-)8}:=<.Hvvc{J C~?~+^Ż^#_馉Vq@I&ȫ\s h ZJ;a =M?4DNls=[Z8#x-iƎuM5SzLa-\6;]ü"8FxNc#};o}ccC"'pVGvW8nHڷc~ٓ)LrGnEpr@U5O䅆Cm$[!|ePM v7, Q(8Tԛ593׻u]1w*Jo.UZ9$ݦJ=._^ wid d;_mfزp kl$4WDd wxr?9{1XaW)ҸyE1öFZm -v}2:t,#@תwX "Zfm4~)WkֽE&LvY陧 ;LU:RZ7igec fjO YgCm7yZC2Gȃ{ \dsWf B=G۶Nҵox;icx<̪%)(T6g!(Itg  .e9Pw󫣳gqB!{ϲ^<#JuJA{tky4}^dñX*0S{LUv_{5;=8T<4Dju#))$DZ0`ŲfQUU9HBf(F\@k@$Mq$V{4RO XP[9^\m.=zNkYI:v|-Q/, Wm;BBiPJj( [KH]ֲ> 6}cL`8*F#ZWt|.qĕM kWiVW{T神P>:-\?\LZ@ e'K8] rL92;?[#͞s{#v<.< Bu F]ʷMպJ O5cŤ[A0o7smLQMh>$vqX]#\w 8 3LE"GXݼ[gfX_7<\$@NfufgQ6@MgYXٳ7\^+ 5Ϫ+8|rcViM 5I$w˓u%՜\, qk1]%-^@ `c|h&Dm^oq^@1p1(ǭē,mRG<=Fp^Fh0L"aD&0L"aD&0L"aD&h%9$_PW(uCԽ N۹^#sYf+ko]ĵˬTM^ʚgӷn^*(C@ }wd9y븟] 3v~[Š[ޢ;ݘPudɘt@~Ý_(vC1KO捧K_pHM+O쮧ޟ;^J2h{\WX"&0#w>F?8a,#w[U TmƇ^i!u.NɄie?|p%]~X>XKEAclE!ȕM?{m*wPg('sAWpu@x>¬9W9/_9@O``1`!ӔCE}Ƶ>ҟrU7[}v5ưS Sz(=@!K^JVq+ c%)CH n_7?7%WsՀSc/jOާsXνz5Nb4l|{8y\;&X;}X!|e|:fLYZHKembXPA?x)O!N_l|CEk> A韈z>Qi8 X4hH4 7F侣?^>XS:fT 1c\wu;3 oׇgABb'aƫ6p&0L"aD&0L"aD&0L"aE#^5rB=_kŬfCoQUJ`|dr<27KvSg,;g/gL֗,iL{x)Fٍtk%n#heœ7\ cL۪w땍KhYX7hB$nr@f|S1MԃV`za]mn7"ylH}cR wOMK:[bx[,WT&0Ru ~Ri5JU7Lr퇽;*A!z:%mwq2@wwVw1wi0C<.5ÁcØ4ȶLcKMZY$o'p|30|o{dBˣkQ;sbѪKcujOdCD;]xZ&u# vDS ґ-rHhSϚ6M"]6Tɪ)! &o167k[,3D­s*?\{ ]O=k0A8)3bւ`P.P3)E U 5CvRpLzWVuR{17Qg¼$QwVϬw1ºHl>ּKnWl^}x{QH;Q * ֵ~[UZMZlB^pT-nXYje ډL)cq5sϸFI̫ ʦuF= -u.@P*dLl_9췻nk>X Hm "Gpo.W<[m'F[-ZJ=޳sȯVkK$9a2WcFz0:dtr!3S*߃oͿVVqP&+tA"x}ȜZ__K_zΖQvZU"Hq*cۚGHhRQ3R˃z(Uh&X<%v>M4ܗ=;g: ľg^i78ycc{m Yof 79gQr; ag}{Nn #s[БWFIjy뀚W [jʶ#H5>Eu%G[l08[ƱK ЧΕX;6XvJvw0W$7ZKc%Jֈ]# cvEv7mx250lG_:NR[.Yag6snJcpM2yH? jw>нXOM͇~7xFooa+i$7 ƒ,~AU p6$%H _4훥kVYuՋb+m1U ǿ8VQrn $nϝ]-юݛ;8 XO pdf`{d:XGˉp>]#X]鈹 y.h=h˶Pv(#me%~Pܤ~@vI'M71Y]$=]eS`ky]ayCg479$N 9^Hzqa/ʖJq8o-x:i-KɠqQ#ZCg:EE1euUYeB2-= nDA@x{aqkHd.[ZQ*]._k,q s|ĹMno.2n[Źm%<2Tj-A܄Q MUW )&s,i~"x%OUTL]մwD1{^`7N.#m\/3N22dYP/|O [n(&xwkN)ݽTu##^kSEnv{#JL\+HɋꃧV|yA@ɗøvY8"=Ruڲw^gZfΰ}\laa2P&vKi~gk0J.@.; U{xb"j^A eH2PY&ԫ!2+5PD®Ir;"-s1de^aq,so#&}Esmwu,ǿX6ۋ|r+;m3ټ^YӼ3iv*M;3ZF;ide\=J,g4t?uwл%5uh'Li (K4{śX*-]d rQȂEr #)ȴ]cݒ{ dr%a8{bcayƗ5mݰOwwk4iQzٱY aѸ6x_AsLRH XxE"Uvk(nNdU1 +Q!,Cw:1LA*,E6Iu#{MZN 23[ 1G$'ds #.*q[A!0TAR;e`s\*g1IÂ;`03*'1@Ҕ5;X/lۈ#hi%F{e/sYHֵv[!ice['N(֒C5R Uj$3m:+@D2n"Q:;q'de ilis\湤A3שac{TNNiծAy/(tkE<>%Wg৅3TUW誑UKq(YĠ$P@J"QᲐ]-ͭ崑9k㑴$k8\05>)CNcA9ZGb<LtP2(.I ^ tQ In+'?H4X@[_Qzh?JZ/"K(K2@*MRCb-f\@ּx#X_?]"{{X8H i BTRBq܋VTM ʵh3y-T+]F~r"pL9"o wo;xqv/(tF%tZg I,19w+i{dsx@,Kd pJX2Xk5jW2pfSI*U'["uR?WM  d7m7yl˶T9tn1cKk6>.!3G(qk6훊>u\qMlieodU:a'ylgoՒ$ER.K,]9d7Cy/ijrq[lOZ -ꕥfcL zl.OuwM݌,Ivmdel,u2ۂ$2ù3E;GI&eliEPMaܣU b&Ctv:h;sf'(XhWe6x!`pKO'Op_ ^L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0ZIidw=A{X,WJ=JLM{UZeSPR8OrD'" K-uUc.-!} as`san,F|.`=׈MUK.dzo+ܟZ-eKHZNJ)ȿu2ˠ]}S:gdlP5PS|cx3'St!J\I>$E2$OB'@7N7SD"9hh_~վG4pr(9sxQ [9Z/ ?W2jQm+4+n/,Vt S(D p0H0G騨4ب>Z[nC~DҴ44x0P(^GźP(y\K|zu>7Su^?Ã_ī .]~JTf:B2F_8*6d {;e ?6")Pw&f sX+II X-q|vciĀKNq4y- (zYa]Ru [EGO@XF5vmmL")Fh,- &@N@LXd%ͨTҕH. W@ qeqMw>D_#c yke 4@. 7uwH2fm!"1 :Tzys& !N.w<' Jɬ85O&75u+yML{HbwRl{WZ@epخKJ]Vu*䣃 5w6b §Q?Ë#ōy<6Mg+g:4p ->[N/q4VmC.4OJyٖ^7H=MjH#br)pT,Sg9$8"mqX^9r9w fsOf[qdV?rl$Ky76 eL-#-LIM$,\m%Ja(ZDknESZޗHV#4TNd98t8&̂Kreos fSWu C\g%Ϙ4;h=AKKev>iFU.6 y˰w`3vHC_zG !SLT1^ܧc|[}G4h\LorO ]0226Ӑ:[ZڜxhjҚ)nojjθTesu "i<]$:@ge~Hܦ[!(`AITVG0 t, nAq,";و!{rkBޠTٸå"ԃf[m,-u 2ired$3u7x!2֌\Ay5l [|dT60|2LM<ťV+FŽjQx'-  "٭7cX)Nf,P1W, i.w#O&KdpF0jp/YWL,mX\p8u#3ݥuԛjg[ǑQGZ>{Rv{R_A1꺍z^MB0[=Y :ތ> w26f{;Nk2B])ccuɗ-#Wr{Żj&+݂i k: - ]-T8L6I _6X8dq:A qt-I],2:kxvВ8hjm3YKyl`Șȝt$<#<ggۜ}Vѯx3V\\vWAn?-Fi9GJC Бoef^.h8㞞++\c 1lܬ9Dt18Q7|L!!{+AH%6 ֏Y=3M)94Wk1e\_\in"RF;`찀eTlYڢZ{cfgyvI84}XF[v?Oyp8K1=p2PiuQSE5zMTt֝[Ծ2=-$;vB3t⺛J[5Z䞉Ŕpmsuk6lTM(uĠA-(Kyh #L"$;u߽e0 "ist3#C-\rU%㎎XyqȆ(.)Z˹R^qۿiwbN_#Fg"HQCOF帍hbtdz@FckGJIu-/>ܳ .ykK=%ҹƞGUvfc\l/fb~GSkn~ak97 /dz ] wNNKv\^ztV|x$6{k4[oS` =sxDgTrs]pQ5B?ךOLR"[زd+vôDYܨB!3b]6&$ҿȊ1QP둝V')ޤaRnPp9r(xP:A oǾ_:2c(hO7>/{`l VY6ƳR؇s{MQLxҢ)~QU T)bc7 ckEI'kg,A4I4dޠqxc;;X)LXg ۛ,;"v#2 )aDd[n`bE PRRIy3oó kgiwdyR/ c>W' 1[}w_]!]sFiN]:toYz/a}˒AhX[Logoq w+.7l(Eu)'Hèqk^tq5+[5$0вHpl!Ĉ9=yk 5 m m&w,ux\UqtىT+}vTiryU1: [yxݪ'oܘrRkq20MG'x<4 C_xͰ1巬,ʔFFFii5'-uL p9Ҕ6[\͡{:yb } O !g*JY5imoGb&W6@yRI-xUasn쉟m흋^7tviU:/;hXML@LCvl^Zl"nao~x\y X[;S'< h@g&0檩,EΪriQ9QCHB"""8<4X7mh\fuү+|}sa3T['=TA۰3y@LV"O-[JdѶlŲ܏w426`!:O){!Q}5GuwQijdUYDaFnjIqRFz0 UgN2,N1x>rkG [[KKkv02}rII?K[ʦLGycwwׯ_iā~t 4o<_֟]oY ,d9oW=?U"/}M'Vj^c޽z_:,ӳm<?sgXxEOey*s]==(d]^uOy[7Hx?\hmqM`C1A(ϮԿSy>nsb||?OPQw7P 쾔E[#rT7|k##4B'(ȁ1Л^_XU?qs7 ;qï¤/Ogot6f8?\W&u!u>D2*&| ʡCdyQB.OQO]uֲT^yҪ=@pxw׮>.Ks}.X>rW1e[RDDDضDL" Bw^̋ژVP{nt;s#~ĭX\*o{E:hhx 3u~vR-^N1m/W]4"TMBB:1P1LzA(kL"aD&0L"aD&0L"aD&0PHSI撱2MvP?C=Ħ! Qn xk-`cZ<ͮs\C#;a ^ǰG " 7N}b*Xck] *mmej" 5_{Om߻mx=[HrrKw. Gmw\c!d dcZ⺥pg6[Vrtw<%/EGUY' $ẩdVDQ%PtIBD "3` slm#C湮kPA GOIil$9AxW=Wa 1pW HNG+MK]6?_*A}5Co~d`Vgyuawndc<Ǒ+ MwNGiD=9jypE69 rW6K[WbmJ$AE L Ųw69!tجͻaYCqdh̦1y |zAcŦ.,GG^X~}۝)]SPje&++HkcAJVty9TBz&+R@=:tE% #n0>S1celgغAqǘ/pּv;knyڗ2\i䭽{+xa6@5H$ kGv #a˽hL kIaRa8XM'L2=L76ɖ^ H{! |{\IlvlKl>ڮV߃!ePϣaٶH%v\ɚ ;;NS>v4)#9f`HÉSDnX6t勠e댖"09Ƴdp1W_bgxClqn/OQ@# w;i0=v ka`HnG 5?zJ@0C'* tSgTm]շߵ;V BHծiC)^VHN{]){LzGT _竝3Zݕq7]Rc%-[C-%g8DRF3ut\nmiEk R!ͯYh7FV8~O< Q@6(mS02qlvLmrHo;q isZ( M&ڹ29[ugq <=FAJZ1iuu*:}F;:/lVf(dP*|^z@EsLHs;ZXKPbtր6 v;ӽ!ܑÉWc4 1coz-_ {ZP)5ꝙ_J٨X FF)A:^eݗȃE!i` =; msv C9m: Giw2 ͕v6@u]H#sȾ7kiJkNfkTY7^EOן'ƛdRK%WFQ&@AB#}Ax 6ۿoeٹe8pIEk+\ؤ0[y  >\.BGOmn| Hr:FM>Ұ+Iz.(-YRױFkJT2V;j1lcIw^(~"øv9cb] ėemm#̓[C7@eFVܻ 6IuE'3#Zݵq$ mh[=0Sp6Ji(ҨJñfہ{N|zgm⧇l䱙s d p⹵w:9iB]ure-nnZ䣚*8E3Ss|`jQH\unj wBC|TZyE7LO@PY1gᤃi6app)_{8I^10в1gku7z33CEߟ9_06hv|Pdj6mo]&Y3ҎWmT"*ǸkH {U3 qID[Cyaݗ=q\nbq8ը ǹkΈ̤}awclHg\T k\#]X0֠U@έ#H{R>18kPv,fϝ5buRT$qf{NP9]=[1s0;n vJb%KE켾Şn6K5O9ɶ-.r6b͓[Cs1x.ѢfnbF6mXi/ýB?Gr)991\vݱۜ:^SV{=="ɹ}egn-.kmŵͽkLS{:]uo+Zw?14da4RHZl}z튕{^9~Ng]\S@M.#v19së(ƿjIq2ܲ{ŗw%"p݆GE]$c}hW{AlkjQy85AvZ43d4=@ҼZu؄5x=sAF+>t F͇Q/W6L#fP(:z3c:۝Bw!gq|ۆIFю@Z Y(XO;u,#Ovlm͋y"Q)60UHwv 2-v)Qn۩ >8tDRie,<1nlwCC_u n!k˭ˮm#$جܸdw7F<Ǣ sӝjb^@R)d IAm G##0Y 102m3qV9\NF&_/ 0[nh%> RMqC3T\l09ֱhV#-׷x;:]emM+uۘe꤯hlO4ĸ߱#Ƅzi$bRQ6!-FN۟lzG'rc70b2=9]6Lȿ o6?J$!dZRFVWPZϹ.E)mr2GY^{3E iG E*eqץ<_ɘ͛.DknВT8 g B6&So$*.@?KH&٭`.=LHVL")ow$5;=?iM_Y K#`5׷{rK'Hq'p+i*3\SJ$\tbC~ V[7)`\4Fِ> ]NoG0lR. {<}]4sh2 T7 ̌G"1Qt劊jIBdB.Gn!V(r:29cqy6͒EvHtse% =I&37w` aV7 [##<1{ƪ9ђthBn2&E1AJQ1HvS @騠6P雨mwՖ˸ܻ~wq!P4\i;Y>9iCq#32xcq QQG+]N7rs[48q#ʕƼ8pR@@zzA8i}N?XtDN*:h ydlp2%!@#PLd.[$^2BP<.C98mKKZxkEBL"!Ι=b$8xXgNB+8A |x#8$;I2dptF E!ID t./Û͹9_mi&5l{[\:\KJ^9ҜV-":AK hyv^,Iav%cvmVQM9Wznޫoߖ9-07os!8Z˙b,љ>Bbv i昈D]BI110M !~|"=2q!LD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aEg&3LP$PVVN5Rv(uHr*kbW:^5_V" "=>t@^@WRpp&UH#/I@LAQPRRJ <)t'SA9}CEugqdK$"O9+NWZ/kkJ ӂFXl`THoH&1:*+sv2pHor*9"^Kg%|"T+h8HH L'(%4C=\HXѹSjHr믖}?< SDBp#]N-#POml+#qIČqmh5R]QR[s:V5T0W&^E`Q샷R@^AOU! O0)H=lK-|THuHVr ȣ`q: kwq/K;Xv.H%!nH "[DAR#40yO4@T㹺 Xp]>&h;KYC#Bh9h-XgsgEJI$ADQX^,B)=~(xKAGKOX$ `}ƧGm=qS)nPVڝmS*]loWA60Q9U&EV9XN6acl/DyG \kN a^e#O604&@ Fr'TB6tu]^ԩ'j^wӳoܥ_UڀwO,ə8zC󣋼xh8ցS^8r6Z e6A4d`;hI&Wx[-e %V :j &Q܃WJ eVps  LsvDBn(k@ sy9@scYs7mibm* w֎dIp &0/gGcyofʖsCyhEV! $npt 9*]mqm7ot hO|FҬaAjy%VQlrU%.1ڎp/-5sKy>Pgpf ȼRTP?`M{vL !3{U"  +yTv-wꍏx8H4 !f[Mo[29) 5№y Apih5>.wg;ͻu|.EDR=aI{\ELV!$](cV.9#uu16sBLAWP3$ذj뻒xe Z8!Ѭn$`֛io+Y\gu_lRպE6 9U*kluva[1[F>vFA笫..XkgܦeY|^³9԰c>Ӹ4CzN4Eב[ƌơZ;Dpbʜu',f({4ddaB5kٹ-50:+=h鉇SjKkOUuI{h-~/n5uu=ikb$ ,QhZ@ k@*MOP_k[yKCo 6Dʱilڶ)tGLm [z.: Gz糶VCyjwqF*#qhh4 6Yd1|^q%|:$9k8ֵRVބT5G%.)inC"ˌ[{Q,@$ӷb\K5h?se:1RLA,{ָQљ>E,d`weu sC\I-m ^֎W3ޱwxU,p*BQ!Z,\MS|DY!ڞPPt:l{%S|uy͡&Tκ3 dٽyh hc]ZqK-;q",״A_1ee]vdvs06Kp0S7RJar'YԾ? a\o}S)A.Gcu<l׻\(r7jɭr3 pf5ۻ.@ȣs&P-s8}qWњyyK+I@Wg4MZ^AqsD&*"R}r Vgbn]{JLS3|0yܘ-|e#i&!c,v)58QЬ5NU9{t&طiZòJ9ydzΊ}kwUd!5:\# $>*MӃ& ڨAv,S`1/nbcǎQN}܎e ^ 8LI B;= su!K!61P^уDMl[v S;69ehq21MX$FYHIG b 2EۂvCl}"dvK$WoTx4k298kdN_.k-}M\TRF{+MiJRBuH.0nuEHBeloe|O4Rk{yItZ `.4qAmeNHU5㉎1pgfٱ4Y (>E楞v..ٔmbM֖s\LiX5L"QIm̔q Ma7=]&WA[rz瓜q NUdW OeTT(鱝n9g^68m8%Ak>Lj9xLJ |.sc9-Nrֶ^}z6a4|y큒$&޺Fk43-˽-`(w&@U"XfنDyg9;98«DsxXj4 I+CX 4jzpྟ!}Vg uڛ"$z8Z*1J,\VU彾ty8[!0{9u]N}]lqLӌh&=18p^rs#տʌ{줔v ;eH3ih:*SV*%0sHͺΕWW񼈟7qʼ+ODUp߈m j-JN֮AYVLD+U!Hؠa*Hly X<켑ڳ[! }$n? dwy})n#Ս<\I7ղL"aBAKZFE4s!%% L#2D^=znѣFEUP"d(9ֹ `%Ēy<$@<XhV;+[YvY6 9%%:@#].;y'ħhJl6w#G2ND|4 4O^b<Msk6s8Qz50MB! f^`d,$C&cض)A$Gw&0D`w77{sKI*EQAad,5P9z&0L"aD&0L"aD&0L"aD&0~/=P6qt(Q>d~ÝyiqM)G.in(NJ e[D^qQzƟ]_m7h?eGuZ߮f2^5#Nޠ ?]]?V'',<:?652ry(# Z\g=?8e"&Q6Ș!3}G⽛^Gmf2n26KG!{7w:=)q`_z ;wѲiroR\Hh‹Cd$ >'pJL$ 9&z=eYEA "t83sFbyςoc'{{+xcJѭ,T 7L+aQ[O፥qW\=j?Yz?&}bv˼o o[{ OGy0Q0@9gwg}gw[*;K36; =C1qe#w)'AS +誚2gxf@ȅd{3~0L"aD&0L"aD&0L"aD&|\n] RQ &EEb5Q]ɬ0`0A{[[Y,ck9>7=ck44!z46xN5%k-# q[.Efy/'pԠMPw@##(~H;^uiۖخ͸ݥF5qq1ڒl)&%TeՈDSQȲ_ɱPv]GЫfF9A'$壶ʑv[@QY12jf)D:)eK4w$RHǀ潎i-s\ AU ͵ŝncqkZ湦 Ne&H[xk;ZBR4z"en[|(V}Q7x8]!I*a2S0@) $0;1e6+HP]v7ui&FG!$lg ~tndwrA/.]kqOְ%#1'۶|KepS06VJ 4m^wZ(ĺsxG/un]tsGEHq6 |.:jKv$9Vxt[(壃. ,N45Wpa! \1^A( 31i~Τk[Sr1W6H{ \ %hjNn#$R ۟DH,1o.57YCH;`[m0Rz5gv}[fsL>޺E{?r q\V%+mL>mT<[9kkG8VH zA 84vTITFER8霢Sghmݷwݵ{V;AJEdp,7 BX\͈2;K s\(湤 AT;y2o8pvHp;e[{[ْTYpUs!?@KGI%mAB#㤙ts@w㻑̄ ?;ǥQb;m.h}]ŨL7L7iSjj|5ˆڂԖl`.cb}J˾ WxUF5U{R@@FNL7Knq6K{n;gI0Ye9FM`xZA0ԟnm!$ۥ aX1…H$4 kK̖9QZI| |B֗wI>ҞN6WV^2>HN=ۿnni[nefqsY+.: c-24cH6ײؖm+'gHnȞQor"kGjQ:ݙozFg'pgh.NUlpQ%9ܣ+b ֠r&*#`nޠcz1{Cpm'n탌#-A,/k 5]kΗo$$mp E-Z׷P ף5ދmbjȱgcj.Xnt) Aa$A@0tN~1G&j?_0n;v䡊)Yu4I`rs_wfiq#)F<4-!ZEͤiͳUd*v B`iUp57a1EDL@ƻ{o#o|P:|V 8t ̖mp7 ]]Ǽp_=5NJ{wxMɭFc^0Ǟ{tXl=܅Dow$`(elk^ҚA0Qs:qk{6mv3:{ 424K󜃨U>nIƂm9іHv%"j$LA8׹Jv{9GY"N ՜k"N:>d.w.MܜBLZh`Zغv"-ᥠ4Jv3h`]3qm[Wkk)'[}Զ[y[PiS[U|&tjX7tM$Ѧ/ƞBeVv$[#Б6FM<((^qS8fhc+iQ+F7Io ޻krx{fK=5ѓe4Tn\jnKy5nKI"Ay('1aiZ_b0/QDe~ەD]-eɃ(&unVgXq7;ԋ|ͳ&^.Z4 ol!k4̀U]*C()sBg9sSyL'[px{C mݛa{$ 8Ew C'xs|^sLCDRJÙɿ<<Ƚqap4w Q45ަWkkJe!]J’+5e~f vvEbqm!w;#gm|n_cqMdS+6d[9qQ3iSowwMOaq+!_iw5nVaE\ּlqI6f>DY<.)$N>"Zjx¢_CtG@͌VbݲyZUH~2jDjI6W^DHt ݭ.c9#¹6 c]%o=*'5sy'\NNpTD ELC!PԽ>TϰeծIP8<Y@ *9VY-.%E}M_ƢF*/cd<ªS1$ت%w@jzb t&qx/ ZZMuҍfHcb[Oy:*V'S<,5ow&z̷kIoM)6b&Ar,S[I/%P*3ϑW1[LWv{Kpq8 NZ i7^;\N/7oIP8nEI Yۗ@E[(nB8%SH A%}ck,ᴾYi['\# #TcY$6¯s ns@y]+*;4 -01~)C_G# im8xy>xx)^|J+(ҦL`ujc g e 6'oq9vW;LtR5'!5CV̼}"6EZ$Q ZM_&zإQa("HT1|z|/S63yLxkVsc#[Lm^bWnbD~B@M9T@@D@@|@C`9cx$Q/ZWS"i*DL:P&1a>y^5h%q4kZH$ k^$9O״s"*n7EpHe%JrzfK &qGpDskItqUĭkYl(y**qR*^=l5K*ulB>Aݤ)]DM笒K0mυ6/cS$t9 ޳[Mc)-on0.e3ZLkpdz,.#9 do#pӮ3fӠ0C"D8o,"W،Uxf9ʎ8]^]BL:6&H{]n$`e'9.-…C26SD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"6eIn6naH(.) {'[)DĪ/>jR<6G¡ Һ{p8dp` r.74ܺfkCfKKÍA,hMA5#f$5hݶ<}9bޭQi({j[FE&rg2AURl3˩#UY 9 ZNnPԆPjgY7&57s˚#Zq[BW\P8U_־esH, 6tR 8^#ūfD?Yˍtb2yyٳ0S@@{#- 9^uZSb#sBaHL'ix%@FZ#-iRzmMa+HcM*R.9ILq9Y4iYn9 jgʿ[99kr(02-yqv6cj99< A8.o5&hL۝½#*FɶM..;(k )YI:D4F"UoQ[=󽦮m (]Ay/Ll{@c:2W { hw#V!P>]o+vR)٭"+rj]-#SvF5W5曤e瞜eEJ aMpd۸{(d&{SFjAtӘȜtshs+8wb8IHyfU7Q!bSv֑4ry.b]FXjV]Md2%N(Z9{s8qs|T$Ck%><M&3DKxFjG>v2kǯHKG{As{cEC'{? 8NdN\M,Bd3Y˄:&XWckF4v d.ui4siݩ [W!&#}-Ojn?SN]y}*mEOzb5Uܗ\T)';ʡ5 .c,erni7l k\xq ߍÇd7v - LSjP.s S>emFvڵm7\Mjl FG،-ʤۄKnuSd>}&A9͡.`AhЌ˫hю"Sp(^ӸVP]rFF"6QF!Hu*NWV 5lm^ G:Wg6{ԠԮBm!#j%YeqouAaŤUA' ݌*(R ,ln#w-kKXh Y_< vgM@CB,)DDmX0?/1ɑlI.dA/y28#y.@;$YelvEK"[9043Xl Uz}Mk-2y%aɏ8쳻nPЭ6m/ d[B&F@վ;{pvxZؚ׌p&fjMI:Mfn@8?@lQJ3t{Lt:p.[ >UMj^B@AC nV7,t\kEnĒLaʫgz'I?]M;- LNgmmu.:EnyK ۻnX?V[KaV&ߗU1Q]ÐC6Ֆ+zlX47ed >ڝHxoFUw1e7cZC:UmwjutLD, ty@,7Z`j"i#IGt[4pX;]yt6Ay4{Hɍln$brcZڲ]`D]9/61fs dskU[K" vT|f[[l6W1c+P}-ˇuEjrtK㢤!|\8G=1Rֽ55|}]5bQ(]7xJW4Y?2sܗbF1۰ѱtzlXc,Z]Ȇ1M)i8˜tJ8 e|ƀ*G|7 y,ڡݿ܋h3_jݚ@P+tVI<1T|CI <XlziR2!8Y֪[9c~)9XZ QRmLHA 9O xl &s< Ov봊 ^3yҟȹoH>Xy)Vˢ_/K4a;+V)|@sdȏޚ?uMl2~בYN5O[)QDn?:Γb#3_cX̱CsG^dKW/Tw_ 9QރN ѳqa$dBMHI/zhpww#%?=?> "?5;gzxY,Ao-/QBMsiTrwvycׯD3/Q)z > uq<፥qwIߵqĬ%'ztp%޹`#" Og onG/_Er~TyA ~3ޛpH{ ĸ3;dkiѴ.1@_ ܧ5AnŧZX]U7$I~Hd*%rz^Պ`p^gw^>;U3 \-}_{fi!7p. "#)2ݞ(X> w#Ĺ#; xfs-]<:߲Y^7Ȍ4,e4u/hN{_78,+tkq !w@x>­^ɄL"aD&0L"aD&0L"aD&0L"M5:J (R59D!`(tωbx k{K\C 8x$dFAG"<[:hIGLf *tA:0h8By}K~sxfMw_uf%۲H͂~!%6DlmşV-Ya|AԸ !5g)IW96mdc tUHg- (,$  9x썆^.h16Hs^4A*K;O-{ \4е Y)'OMMQpl&*w!ؙ:n߷v&mϺ[i,͏&nnN@97w@DH$7ΨWHq ͅ{H[5ccRVIѿ=nRbfCjܑN"pA;}lhY:0UG*LOq8%$`tu @o-yz-8Z=7^Fec`/-0]fvKoݴmn}C,%c= [֎={Ց;XHWv̧*SDA0pJbDU/A1|;d`-o0ڎh&icA׊#H!o},AKLf*/&5䰑3opwnyTeO >&ps$csH 76wck4 Bn +/If$$Ɣ -(V.-/VSPqX sׯݓng7YwTQu[5>E-V&1z.54ͻzwL?355)i!%͚]qBڠTԖqkCD$jKz;-6j fNjg0n;ms=Z[S}Zǐeo7Pa;Lhs;طb\U/絕򗹺o"{V9PH3P=;칋bj[>QӽdcYXĤ VgR2QödPf990,~ %.|ɗwpمuå|5vd; n%:LS[ "kA$G>@ kvKBƕ^9+Nq)-e'P);ӱfR.gE [cllpm_,4Kߔ-u*mYw]ZiS+vI}q0^ȋPGk7\wpZ jQ˪wűn[E oZ㙳ܴPXeTsLRtG'C㲶yj#Qn06KG7Ͳ>- cݴWY&0ܠy~",oZj$q6z+s:~ܵ6'E<Q:p>c+CP$Y6USo2Adcoxgǹ2B 1x\/mdAkp_,0G8t$}"CiIl_K J#W@ {2ᣀ7ѿtc&]靪N85qKi}2%b[3 Ɣ |q.Tñ7K&|팣V̶w{2 -dYk]^s1 ēZK^{ +aB \Ih"׶cɚIBB/ea:rv&rVr13ڳ Nw>t>Ĩ%(mt Ût `cLا^L>k޽g5%휽|*A|VG0\ 4#|0n&tfe6Y4tI ٢x(#'n%Ye(2f0x-oU1n7-[Ccีܙ,4HK ڝc_f$н.tqn]cᧄ,du6`HV[r %b_5F)#EfBw|m谐2ީ[gm/W0 .m[Kcyk# {u󡶹rYI@7S'u+ k$/mZIŎӫX 3|wFP""j:܇qRLPT,2d%{_$W=t \4i|!ڛ^b!THm[ -H"5,s~$Ë`P£RMBHUH?0g?|n^j./I j?TbVZ+q_1w7淈%hxCE'%f͗2A6XPXS]%@lDDn-%w:gHCC u4 ,oP,9:$bf7P4i"ǃIOUj_1b%1D SD SzϦ=5* qMR wDʩbq?n.,f.[`ֻ<Ů /dVԏHtR@UrF_L DS9p = ?@0ln巹7/XdֽἝ+Jpt#5UxCjLEҤ^a&5U{&*9^l)ӆD1&绡U2%H {|S[ϐ%Mpi[dA+lBFwsmlc ?SD/ּCˋO l-aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"л? ̒aJ& >  #g /EG~|!2K+x. zAHQmGS'*Ulͬ{tkfeԜՖw+4L*:rn¨)hKx#K9hI?9;诧8-ֵ!Z5|'Ky Tb\G*-Xh5b-Dq&̫/wl+w^Jf_H5s)cr'ژ"ͽq9FH+K.$]k;fșCcgb3э KZ 56 r8zwRIV[R&9&>:th.4ܺPYE;`.3Fɶ.J :8 .cWr0 mںAudJh Cb!µse*[Ny[J,þy ]=اD3+7K{*ȗ5Z] &_2ǒʹ/-mu&<gncG־Oc-&$EIC}N-O{G <﵆:q85CjMq-Ir GMIZܜ+- X@Nmܹ*E)V ~c/z&ͻbfɔp̖ce/e>m5\uwcHөc(PA9G!l@ocRNa1c(+xKWXKXZ֑r܌ۑ5ܦ9L}k!s뛇ys3SNfBTk49BXvd-lݵ i @6q=Mr;g@i^-C F] [ۑrnPGLv_Tu-Бب*x7Y,ܿ$\p=}MS8QE0vFjca`B]LMF!ĉ' 4; *-Š}fmK~G#%lb2"~[n;\`&q#cDGTp;ZO#mݸiư艧ǭ]ą+V#ro\ڈ䑴|yS6k2'+-~֗PDwLӳDgD⊼5sBjfF~U&t+ewdJ, r{#eݹHXC2F4ڷAq~c54[[NA{m̵t.SqSx:\bھG"R /u[B(f ! ,o6'FEs)gnCySOwYXeq 61;,cG|B&SE>_"q%qƮ{9Hr \rr}N9[~0ښ=cZ=ј睼q5<(,X8.︗\>lz8]5}@ow'4i[ fڼVu##`<Z5M".D|I'`^r"sLݩ.>G=݌C\&83^ZH&g/׾xp8y@fkzg?vnDNK2KAh=U EדxyQtQ2TAd7V  h#P)($$W_r/N\=3Dz֎~ (p*z+.a0j~O(U!uJĝ6T2Z6Bg v @_M2q[7m 9:QW0rh<3.yd9YxdYTwo-U-mb{CS W c((Y U̓Dta&CgcqkXctO<?4s.4q%c]@뛧@dOx+|z:mquǏ<;'UݻȘ#W'c%!OIZK%ȺSDU(}E[lr38S&ahnC#$QW1ӔB۟b_k:}z\Q)6W@Ee<&.&-daR&L?Tr ,fs幑$9MI'L @xX\]ս2(6Z#}=ΛrCJ#5E~QEBE,)BxEmIJxʵlpFo`tϾ0m4. hEc WV#`+a6l8iы-"H i P I$Hqt$I$ĒOIJkCZhrEs~0L"aD&0L"aD&0L"aD&0L";'_S_8w &0OtQjqf/NC&h kv|}Lı]܀َl&㵣G₆J_:Ɉ~rXzH}gYt؃@j?Ƴbb~'On+wcr%6Q}~;oMѲ?^'u,.H3džM t7;^釬ww{bޝCw$%@uwD~`>6m?ב5Lr缿 7x?XԿ = @ ݟsq-wwV?Z^IatG{F_wRv?$q7R{kvٳ>#U27-e=ʮLLwא@ ר ^l[=Mڠ}QL~h\cI_ jC7k@9ލr'"n/Y"#p||~(2 3Fi5aڶ& [l?M$"cH0^Y$3n]\4PwF?}C5UQj6{Y }u&Dßly׻ڤ9ׯ_=Ҫ"ݺ c !w}e;x+ SK!4S7MaW2P> la.?vw490L"aD&0L"aD&0L"aD&0L"L*B(2j&@P)r!=C>$9t35! A 8xF״9|+qp怑VF='4-rVȼ[YhĊUJ;rܠ#q(LPˋK*-~۰ɷ'uͻE\4: mMɖ!S[fͶwnd]L0"` ִR9 <MF2H'm! .d 1LCQ?Jr ꘥1CsHڂi>\TOeՅю@o!{OBi]JyRIz݃S`)P0S].E0 _/?o^h}ԛ6`Kݲ]@ʚq{iRD`ߒ6pZyTز dg .G^U}νzBvYc#vϣ_"=%Xt5>*bu #ylMܛN\X=ŏiA38Ios $;$RHR'%  ޫ`e1ӌ'VwRyG,|sD#(`coR3noh}՜N ,ՠp|NAO:knGH:Gzңsp+F;e7ecDY>`^d~xuomt06Ck<2c{o#ptN:S7O>M87l@d85#F8 R\2Qoam5keJ58zTNQN(:/mNe;{yaH^[>) IuͰSGsh;M+s, --ndc/ `SZcd{Ye5-/kSRJRa㹮: X=BL hv}OsnOƫrVF+wL}%ռhty͛lعV1)-g ю"@ۈ[+pǺ*}vkoT.I>)m$Q]S>"&嫄)9lT c&sgvVǶ2ko1YKRǾb{ƭ7>[CÖ5,W0.%[+Fͮi|vOWڗ:ނsrRI,,ir2a4bHʄhhG;Mt}+:Yv5[fFZ9?02 dS- osbmްmͷp`3SȹQqM27LyD4Df &>b(C00 L !խn]w0g{Oj8!eq9,B\^^-KG<Á!„*۷>m8skUgk((3l[$Qӝqހ=.7S1GܶG+Q0wBŮ,-#14o$ x#o~YMWwE_h;T|y[-NpUezvu@qH%NR.}7dLg/Jy^Lv}=fkyns%­u&0-R5YmZiŒyVK G4b튫=ݨ\"'h7Eױe.սܶgh wS}{{ l#B{2܍1MJv䉒p %{8κdd O=)@Yxa;]qV(Rt ;oρkmw/1(mn77:70ջF k-fCivL+ḁJ[ü*+ڵt ى6v@ }v9=T|qvcĽJ*Gy'\vKwV qՖ|`sF[YL2Yx}Z #*%dIDv6(S7L]K:& {Gk'YLKP#L˛wSm42 ]-ʹmlnlT֠9jM`kpfHW.ت)Y2y VZآoLR"o;-/<ْ/wueغЇGn̓ ka,Xo;K|Q]QGH8Y)DGNנ"zx~n6SQ?x+rHh䧚epzwkAۖP{&,-ӑ0xNpԶKwg8lmspd2;KvbؗU@ iis%tRUŷ"˴^[ۘ71pKzqt2Rd *=+U-v$k$NHe1|'+w(-Q1Nz݋8"vzubaː'hUݵt3ip_nmeX@ba5K[;*ˈy: (%IATs0L`(*{l;G!G&TI{Dph., ldWx"TXI1tn;@@;j%; 8t:G:f) >=o.4n X!%Oj7oHueg7 Zrs\(EGNi-p Y^sFoQ%ft `E1H)sw~b7O|nHg=|O &̖7<xwv$'5v5Ñ8x~b8M&`Km̰$XB'N1*O0ݎ<ŴYJ MMxkp H5΋Pko,03 ishWxgjn O:Z*y p*^eoȱh)O[WԬ&ASyM\%khT]"_y!lV~a~O3Z//%0hA?WEi_ T+?W&O?iz ?z| 7BC,2z#Ѐbf*Dڔ%d( pY%YArRA4SLq1C SSu]Dz<+NTI&FY(t0uē+ rVBDW֑z(8xɢًiϥ$8:L"Qç &)(gwT$@dOc+7it$e+Ē0XtH5騫DTsR0N=>N = ~^&nۚHM84UMXA%F֣Y#FlkLqm˰rZu"ї ͹H#d,%BK;1Ƃ5; 4\MaDpI\6&ih+ŴkI@ R\)12Y\:ʪX"UF.UA4RYE16܍NPP+ABhp$-,Ho!Zmj@I*\VvQMj$=[ZJkZU)wI5I!W<ɑpGMxoy'6?WH->'!K!#XOwȿ׸t龹rZb)ѯ:ށbjG[j޵UVlT, ;7zb6lm"iY\#:#PҀGݹȽk"#lCK#8Ex> IApVIa%%b6}޷Q=^=}ZQn̹9F Ĉ\,prLi|[M< %69ϞQ6N t'e}j9+iG9"uKKUCieMFSY1;9 ~#7 Bɂzi0q +UAgW][O}ed1DXSV5WQ.  Zkl~`utEҹ$HtGUyK7:Ʈw$1IX}xPGzO5K߉:_7: $L(_a) efEe,iY`Md3+δ>:啑{lfj$"cg3EsByy`K +%'d: C]@n&ucP2KW-Rŗ 61mCƛM%E=j-& Mϔk 0n<6X8ƗܱNEeZ&Zhg&Zv|.:_s!]#kA @!uvRǵtorgKǷO~r(3|*u& jHtRÐ1aYcp,o^kI'_) v[qGrsn"q'y )P8ie^ORvo;Ī+Brh4 AʚJ){1Ip{"Ap^3]\Wl=ysjY.zSVF@|,\) ᦃpȏ|bP-G9䳆j]A.BzpӋld[lFokELueBYi Fum}[Ye$W7lG)o朠uS 1[Spfuܞ2GQI&eEѶb82C\ ^LjZwkQn ,ɴTL-Ost&.SU/B]U oƩL]ţYCZ=w[6&۽[Nco 5XޟINDYXZ]:[!^IdtdͺtejŸ1R(\:;}ku;I*I pn_ F05*l^"O'KNn!39!D9R1= DrK w;caim1+]֖Eۀx5.n0n@?V4:KLCh9{sfw }vC\ }O/vJ>Sv7#Y=‰/GG>w޼`eXr\Nk Ŗ>ux.]VzDk%>PA,/9Zf4;AϨGW0y6ww,{T5i#VkS5Ǟ>>w^,_TZy*R-kr'muiA{d((B|3ͳcaw{.n84Tpm8λbḿ{Γ72z~ ݒ?ݍOp?&{Qwfiun׳:ql9n^0ڸ ")#&vW(yn@ylfot:+ft  j8x .8F܃fTTf!fK+,\wom{ˬ? 6ĕcsR]UmT峲o,/Q6U"kı4k#Qs67wyklo-ďiPZTVIS'>пٳMސd Qg [8 }=]y)KyJʱ?dOeZ"V:Od7iND@ q]u%FC@$Fƞ`+gY^vݵEaචGH|?C~R.o[Kѳ=v+uQ@ZXpPRC0ugc:m[{"cH4j=} fsu* UH?؟u_Mސd Qg [zI꽟=멷%6N7hZaV+?u2:zE?B:7PXߗY=yKg+ZPt<#-kucn㣅AhӈʅdUҊʨeVMI" Tɦ@7@|:D [fkJf^@8 ߼{ڇӵnηNNJDo&O弇N-{~=OC^noݍOpL#K}/L}q5xŬ^B)8 =^QFk?xn`9R=f1 * pz(o+L载xYZ@x{k[hcHB)Pew6HjN:0@S*稜~s4EeHr!D)z@CڞUЂ?H8S⏏U7A5Y@י%ݯ( ݶ&"xGp?4.!ŖM&L_F c$k&EQPj&r5Pr NC@@@D:)b&^湤PA##B^F"ABw,mmkv߰dk{ rV3 Y̐ѬCHS1ߝ)WԐ 处;oZ8Ev hɻIh67g}SL[OOmŚ^8=|rDDĸ}*R9[(}n3AruE}A Mz^.iY5᱗c@e݅ggʆfV)q=Cjݲ9ˌe;kn">7x'weÑ3Y*,uiy)" S(;MD764@Ϡޠt]Fݡ'sEPr|Nqtofr o+onSL)rK|[hc6wZn#gfvUB[I\M5m&clsIXz;E[uEY$jk؎IKc r!1۩ꨋrAZ۽H۷{w>5KdgidHnm%n+Z[gvr=kdCmb|V%^F֘La|Ri-3s8lq+5c$WDjK(t;o0;;Yqaf}d ^䴺ȉ[709#7?~ċZښT~bVă5܀CC;oˢ]H.m؜(gtA.d2c-4%isCnW[, lmN6[2n@ӱG)J*7U f (C3Ntnb3v]0,ue9;-ÿGwL4+k.7/wIdis_v.l9+%?9ɭiV ^3GMa]NS#';]{*H(SݩFDvj( ӿ%j2 Neb@t7[kyS[raG0g-$hכjw+Y7mo]LkI#Ǵat!ef4٥jrH 8eJ!!~1 9cn x􅂱dA.NnnVG2!c wt5ܵe˥t &.g\5=-65Ee!x %Y^s#˦7ȃɀk:=H'L[V,6]!:`(\CLf sth:JU}:*qTdo[j1pHitM7 d ì[eŦϋG̞'8/-eu_Z\Ydm֑nֹ42@4]Y,sn4{a# ] o'" i,Z^G:PQ$Fֈh`-$x_vIqe͜ =i۲ȹն~0{4Wr-Q`03,L{3[{R:@O ot^_r vNbn1;C;MYꌃ$h+%y0;-΢VU3P:` ӵly- .O8}.xZMB(,42dz)>^/1=W`J#Z3Xly׃ k.חA:*,`6~V7 OĔ^CǘTSN!T}@&ۯmmŋLƺwmq}jX[,L}#2fktL'\C,nȖ)=sWD.p ."Y^tRY %^7pd \`TA2Dʳt ~DU$ { Nml_\;mf051ɪ9h=:AۛFC̍ؒ9+^'KxCR VYɦѮQ.nCO|E5Z:P"U 1L$N8Ӻm`}=R(b 5#mMpdoamOƾK^69:#NWr1<@K4L D(I% S݊) PI69C 8/ M@5楦7:=qsjgp$Vb;ŗtݜ|y_zT)n1 ܑb G,+ݵM썱k9#SDlײgT2r0Fᓻq&JֹY!* Ϭ3O$U8>`/d/DDIdERDɪC&@LC0xx{[9MrE;iV EAxc#C!>j8p6y6`lkԠWԨ:YYq# e$xByN* ~EAk4]Q@LTP)`"sC!DD6*jUoi%=|54̓@{)Itgh3H$ߵDHDzxgcu#X B}T f>:>SX Z^tW"qeq6<_QLW\$-(MypmrfD_O&$Y,({()D$c#n!;{Ư$F'U(L촷c(4exhW.$uEC!ʯ eǵ$  ̵ԓ:!Dg =g@LDAE s,Nsu@ OCQ 48qX6ַv`_W GNk.F^8R20F:X8RIMtĚ+sSlܲOjs(6 ZqoōU""]b]bympDTٸ;;%-턎Jwv\0j9 !k7 ߜhhq:p<Z$e) ig`Y ]èhIåWTDUc@y@H+ɨrsP2qnmq_ruil.4gsd|IhAhݦ}ȓrml;]. flVaFPltT] tcBKu)!-k{05W5xT32|DI5>Wi hHGl5Z"cJݱ:s:^r2lFѐU8-ZUPJE'v5AfLS#U\(x `;E3. `&/#ʕ:c`PM-#P[l[_/^mFH-fc(*5 y{};NKJ'IUxr\-f)ҷgbFnr ,knܜd ̗{SFBP,hT-O0Po])s| hsS4-ԶsIHml_@Ʃ 4 {+V*GVIH.mjq'՛qݯˇe~;xp0~{S Rvn]a!rѯZf-nܗsDYFd,c6|nwPYn [+potk]8m;e {q-hk(`2F YX7^M حPymu_ښ#6UZM'?*((M?YR &ljdr$!5 ??%Ԭ۵}chisLQ5ZjMs{#w5l{WD5YWhGQhUmuAG:x(,;Tl\IGjkSjɒ7Zn2\\gn{ ww 52F4!h Oޯ,\Ѱurfl^5`h6@2/l;c{o}ii֚e'T1GpNqHJTC/o/Za`HXM41姓$Zn E.ϕWPNim#YքԳ<~#;qL( %!HsDidlLmq6h_>Wڞ{81cY,٩Kͼ=TRF V?$WG+C&恪(wH#q5.Ҝn!^qS7W!~(ıx!*g>z-8((k<7G1P'#qtṂ+&b:(8ଢlol[cC+3DW8 =o*Yq*)5,]k&a}@yJgV %ݠH_^Zlpr³cg|r^ݿ!9Cew~sڍg2Uč=pbywusfm5'cO1K izcDl_ThAK`TՊ맵c6Uzv1Ꞽ *Avu~ђ>ò6㏚I3Y,WK Tֵ{0amdِ<9``k`CYk9$TpW~rrWnY+ejrs is;uuF9!AͫJZ1P;9y(@=-m~7۸mH EG) 2Jōpo2J͔5Eb G}3 2 x;Hu4)7VYxGGLv5`%i6##u(c%MI95IqMM*"s"۬&7r-&g(78U#+(Þ q8I}syՐv1vTʌR#8I0uln̢w( ^fsoEk\i/G5rŴǸ!GІmYfnEP#G"+lv chxQr)g9ich,:fpaO*Z_RM*5f"FC3UkM*="ՓD D RCYCE cU.dqsMI'?n8cl06&8 s}0L"aD&0L"aD&0L"aD&0L"כ\{CBٶ뵙gb[X9miՑtR (R^ut WO܌ҲVw,4-J9~d7]ZFZXc)2m2gV_ UUc)2m1=W_|0K?g|b~_]~.ϋO;y/,Ciu>-?Xo'3 L~/w'Uc)2m1=W_|0K?g|b~_]~.ϋO;y/,Ciu>-?Xo'3 L~/w'Uc)2m1=W_|0K?g|b~_]~.ϋO;y/,Ciu>-?Xo'3 L~/w'Uc)2m1=W_|0K?g|b~_]~.ϋO;y/,Ciu>-?Xo'3 L~/w'Uc)2m1=W_|0K?g|b~_]~.ϋO;y/,Ciu>-?Xo'3 L~/w'Uc)2m1=W_|0K?g|b~_]~.ϋO;y/,Ciu>-]yyzN<Ֆ}[j.TT-&Jq22evu =ysd ,- BK308 X9p+ywsژD&0L"aD&0L"aD&0L"aD&0YXnoUR*ܷ]3$ p*Jbb_Y,db{ trG#C$ocsIihW {sIkj8#NT:˕פgNv=QڝO:P0W*nj9/a0Wwfe祒ndX\p2;ğ0Ƙ뗚@L޿ߪX35AL?74{ β橾JߵYך3k&D0cH>a +] &>SQNFC77|Z"BGfy߭$"X]1o'^l˗ȕɾD^8"b3~elB"EP|xTL~ K:a[[}{b i15‚{I/ ^nsf [yo_kwsfy2&e"R7t$WJ4L5> ^Fl(FqIq..J|}~}齶^Vor9"`Y%<O< ?^44h xźmV&)<:Έ'q(r5Q ]n~}:~}%gscbXX؟֔MqlDٚ,y{?L75M7{mt1.oHMccC,!̯z!Զ"b!B]Q\Ғnb'f~2[.nT+ʴaPٔs۷n]o5Z^Kы$̝[nJ#]s6")dW7nq\%-7a닌'r-vY5L)֭]bhpbQ09>QI7Y= 3_mskzkݸo+D,MYm]CycnYC-3Œ0{IcZ7FLôvŐY!+7KdJDb+or7yS>>.m6s~f,V7xd0w -qE哧k?kf3/k@/ 1WLiqMFHk49%Ln7߮-?dI+XcL :PDq߰zhr[J3asw[o#u:6e} wck/> ÃDgab3W\7ZŨF&@H؛wk,_^5YLL%](%UrĮ*M[< )\&F@ b`\57zdz1pݒJdc$,c/8%j3wdHss qlCZ9]#&+YvH[KGn#LHWQ_\ZY"!N7*붘J1DH;'^6R]Fڛ{ _wӌͳ% |#٬2V.Il[,e,uv\s o ø%,~t=QBJ5iR)rv2bGeZ&va?qIb lata6V.!C5Hmmjʉ '+qm-{g!͚^r{OY9${alv_#٣#TXX|T5F<=v ]vzǾt\n-lqCrX 7xzn7dz|>Q##˞5#e`A.2*zIHYQM$%4U*/ ⤺K1QQJUkcnܼ_ugH5el125tr!ac;]c,FBx5P0TݒTj6nAc 壺mh.p*VM- :$XSϒ>t]^>9;e {OC`.L]jٺs$95p[H'yqdTYˮpI8b%~#V4xw)ArZcp{P[wkGKv:)c.!3E#6ӎk(vdRxP%)+Ui؋:Sw1Nfs{;g)+UHw+fl򑼆X/jŞii5iV{:WA5p4 0ZOr@̢yVXvL<"ºe"׵$Rygx nÈmӬ-x-~Es## xd]Z_Os]p}шK25sk !4<͍\hqse+5RjFEw yb%L .1~1T|:xA. kxd&|x̌#AnIcQPi  I:H< |5Wf@&1♻ %;@JaY9u4i励#K+GQ)~1|<>ϕWDu+JC͕ME#s KN?zl{Gqn=_V9ڍǰxYVּTJ#,qc8s25$=0*G}s9&Cgd&I@Ə08ħʻkb͞1__=up1ʞc%4GtpM4I2SM"P=G䕱'ω桒$w9 &$T5$7U9le\1tfPun*9mjH Ay ӇE^iͨTIOqL20te %&K7v ulYY,]>pVIg1丝m:\*Ղҿ.跟NI6i |TEN9o -ZT+EO=EUi\yi<5x gk{'}{GJ?sgP3efBAx*57HԴ jlej[,2n_6&UMI珟3 -٩Sn;mc#f|9"lq׎꺤w=AظI/xokZP*rm}hi[B/X1u5\za9vGnt)CH@źt v ר7ιa79 p khuR*)FXv\54RF֝ +.a~2v9ںb]U?\m+bMcJeUX\ݬ.+7+d{]=,haV̉"\81qAm) Fh| L,o8vJ9LimgC%l['WĝEjbM88G&Ms qM~amdNwmQ](p;חd[rYH[FZZf& G84i%njK[Ѵ=ڸC\k 7mdGr`ݧ, ,EAUSpڭZTRxIɝcMpP o81p<KC,Zh*uX֖|N *I I3Sw]d坎"z8lNnh?t0NjmatJzZ!5`UJ]K&5{ǚcH-刖ume.`[GS*6"5XHAڜEKZZҫ<IHv,mGrr5c 6F6H,^@^B ~ DaY"3kےc/|F vͽf:" 5%daq2=4 CC^Vr^ܦq[OAѵ+6־}ӛEYSUm۸H(Ҽf0%sɵPɴH[0LIM{ !h[0-MZ]k<^-mLswz! YxZZ $ 79^&*n?꺧|honEӟ!$'Ru)mRpz3Tҫ鸗x)+%pT<w>Lioe]4v44: %FK9<$D{휌'@>hm۶^<}3[SuڻaSvݙ˨}nb@WKϬV@#T*%0$'YY93NHo6)Q<Ϋa4kfZY.]QmOV;Hn =hsB㕲-{_Jz*y'œ<xlj'w6&כOl"Pgo<K(r!!yUMGu@}m7sXWm#=%q;{(Oa޸r"!OJ^2xUS0}̮,+7Oҷ):봘/G(B]&Q/0[~fySk46y\ Ohu^@oJ%{/ ;勣qQ&v65c;4bswߣ|gkql6%>~vዳ}3^U3SyYZskjIG}n6l/Rۺ+WpRM49$ύ;y!Ζ@k kXmGccAqKX֊ WZo藫?8v߼t- y_SK՟;ol|XzB_oOB,=!/'C}~"~g!塾? ?jvzm͏HKmIGȟ?DYöE%6hoOڟݿ^~c"}|7'O/V~pya ~ >Zo藫?8v߼t- y_SK՟;ol|XzB_oOB,=!/'C}~"~g!塾? ?jvzm͏HKmIGȟ?DYöE%6hoOڟݿ^~c"}|7'O/V~pya ~ >Zo藫?8v߼t- y_SK՟;ol|XzB_oOB,=!/'C}~"~g!塾? ?jvzm͏HKmIGȟ?DYöE%6hoOڟݿ^~c"}|7/ڟݟ^~c"}|7,Rz_Q>DZ4FҵmTDkٷYjPIƝ{T dgPwG#~tgbctzKC@uj ¦;~{%0wq^l1"D&0L"aD&0L"aD&0L"as6bzZ|_'c% ^X3b\[ dT)zN_no]gn틟v1m+֐[wW0XxA4244m48lhmA$DuD=i(?75/w ڣdՏA^\Ӧa!L wíY-6nown^&&vNmgh&ߣpvd]MدpB|Cd^8չǰDٙ#2^Z2Ul((>)1|J96ٽwFՃ[pn|-ua6暂 xm|Wc<4&:U庡3 a`N&Q;Ln% =Qg8mцۆ+%.henIP!b/%|<>7pGHTB5+l1ąbYAm (;#hΰD807/oR:lÚg߻۹iݩΠ_xy,qyt}2gg;6ۑ2,ݸՓP 7qyꋂ΢U"[ ]brR%kcR9a'|3Zgld(QH@ jS)ݗvcݷլK,tm XNGi<7;;,<2&f8wVͳ# IVnh]`r[Q6vړRxPY()"}Hcz PtBe]6!)m#Y,N.,/`+825n6b^mƗ]0QscsMwVMDUMDWI5U3J&JHj%:jD r֚nau$ik5Žk-p$E4*!D$N-A 8c\{ܘ(bnl[e[Iݤ<B F̄meճt;/;iyr.\Jkt[jS$y{mr-i(#h-nbP#ֻY+}Y~e]2SjǹCU4wnFE Ӹ:/;{S)rW#d[wdy2w6ip,Y oMxײgzsM󉵓1m5bHIP ֲCȰKVtD|T[>`>zr.鲝UQ"/ZM2y &k"Rڛf;8{}iV7!s}WF$;=5Xu[dGڶz\r_}k;)3)fQmqlN>ۗSlk+ Ih[k-Lؑ$n7T,l: *3O* }nY.Y3sloʺ\sGF}ن5k %Vţav*LbL-ěY"u;K6DLsJ[sȩwMq*86Y2!JΈRl?3;‰fb\칅$mXW$Tׯ:k^x۸Z@ t34EufImfeL$'{E^$6N5a>TRNa F dݶVI5g+ `hKSɨcyɀ u a3rE{7v̹ {ܵ+V1]{{\3p\B#haO}"Cֱ(Nb(`Cï9X9iH G<̭Zi|zpy53 &1v\IYPra,aPqʠZ;c%)1oZK1u6oap:.6FJ |n-r19\DoHq4,t.aiZZZ 5 |T\MC( 0iG7!U >ơ#0b TOu]lՍv0SSYj'ɛqbu{npr^y>fFsS,1FhGAWiF]|#rc$!/ SnT:`d2Bașbkq_Xa kۑoq<mEZջ2)$qHװllb<"c=ё.4H|Riw紇(쫻},moOjyHE|4(nd>S2S6in 9kX.eyaM(6l_*Wmtlx5'݇WùJn" M4xw>T4F .c&yr_N ge2Wv;lw3967p{6X$$ t5SV&Ko[`'nR $oi "5P0Jsx/[Tjíu%x}Ar(ȉ!LcdH:l({KE,U?|n{pa-WbXcZItWeHFAݖ-nˣy{FI$K9)P':uiEtݤtDEc⚉*E1\C{6nQv֯& 7s+K8\1tRG#_ |gQ޶7qbG.=5 &À&q׍W- uC>dY߶&ҔiKkJK6.Q;rtQeJ`_}Kc ^$NKrYN|ٌh|ϓ#kN`*(zgk-6Q]ȭmcVMXsrjVVnJ52zo0"O0i#;pr }c.r-Iͣ]-=4'#u'u6ةj"$n<+=rK`饟]"g ;9XIaf..w{67L1ERf {kZ5:0 G\g:zOx 4=60*{e,6e2AERuS;[ڕA'+\YZ۸dicN4cIѤV)y#c,qW kEx 0 :ZOlmvthZztPw96Pg^Gx-eh2dr[]mu{:ɠCCAZ71Z0Yγ\a:M[ v-7Jz녅Ҵ:zJb w;zRF֫YFA+WyΠ]iMfukwqLcuK"Kv\G`J6"zx..uyUa5ʴ@./'ZM̯?e:ʮ}VQ׼! ^;p;Ldox@% qj5Ol`nO-c6X%sb%ҹM:Z.|bwtXt.?."sMh,6CeWFxȫ]EBB5 "ݲ٭;+|HoKXA97&ն69ڴHhB U+_ Rܓw̙òLjMOZi-gv9ȺU4n\]\V1&syxD;{GMQ^[+?4UW;$g5Ŏ>[.6 wD #:|"ccؼug y=pp벭JX.YC9k.N/gcvՋdԍ`VDo @42#)n]tR/08IGf#ܣjtz89Qev$oNilehڞ۩4uU h (VLù1o}ِlIlph޼#дtی\1Kл_#K4@GlGwq_hRt ?ʧo`n-LҲb:SXQLr"-$D2J"^嚶ZKܷc& Mey1L` lͭ\ 1sw1COv]s$^VMZL\_T5]Z/ߐFuUFٗ镙=hi3`Qap(nJ}y^ 7{VGkh@s{Np2Qm{oMd+vƐ&h_$Gch!>rcx/fƺnKqKzJ٤tRmSϏ,R&vUp -Ϲr3䲲VkĆxco򠢰n`[ij>x Ɗ 2侪GJFvؗ5WwA@WegQX 5iTG4DA-JuW&X[uC-Ѳn`78]++W:혛dY.rڋv\}#m4W 0 ߺoquMMoRHHJ%6RhTǘ1A8k, Vv-m"cf8vjǰO)nuq<\KyPk//su+=ө YNM NOګܰvRsDqkZA(B>߰&{Ӛ{Zcf%A$c8{3l|[ܮ u}I0 #3aWu6;M W6Y,  !jLfg[t/>򧁺rCbnKr&Tl=,V=S:ăxꋩaY7]}x89H)L\&迆 w-VXC#&[G޼>bNZvx#%ӊAtG \--QLM_l5ʉnsj;k<ۍ56:9Ɲ.J^/ri]Ll .S(Ϊpmڙ5S[m-٦Ѯks"`4BJm f:\.㋵IcK N+5:ѩlW8@^v e VҴ"K(uF4 KXHȝ35ge{)$C\Qku3Gcn<vqHF0yOw 8DxEW#aC JM/u˕rHiT2l١(TT_c[Il:-ǃ$ z)¼쬤l_S}=Oln

[hJyw']V}&$E$OYz^'im5XjĒ|Eo9&k_$YOi{΍$A <Gv#xGeLw2fֆL0Ie6RrL#b_sBdidaiOΙLm8wr\6oM|O2Wƿ_v+֙< z'c.{., |;z?Hv3w~\D42w|rW طotTO ^[м ]ƠhyUlIn.= y,eVps |T 4Mϟ̷]J`X>fb16cjґ{σ4+dD&0L"aD&0L"aD&0L"aD*C4]Y#zk:ըkce]D7m:ɣ-%jzݜp,pdqdApZ[-:I@?Qc]Z_E^ֺ^_#UN?пߛws=%yUY ~?Ug_Ox9G*~,?rӏ/'<~I^|#?EOY?Nw>ʟo ?ܧ ;WO}SVzq~ӝ+τwc)=8B?~o;S_mg1U7?xzJ/~N?пߛs=%yTY ~?Ug_Ox9G*~,?rӏ/'<~I^|#?EOY?Nw>ʟo ?ܧ ;WO}SVzq~ӝ+τwc)=8B?~o;S_mg1U7?xzJ/~N?пߛs=%yTY ~?Ug_Ox9G*~,?rӏ/'<~I^|#?EOY?Nw>ʟo ?ܧ ;WO}SVzq~ӝ+τwc)=8B?~o;S_mg1U7?xzJ/~N?пߛs=%yTY ~?Ug_Ox9G*~,?rGiww||ڪu톕We ( OE,Js]r 'D5Ǟ-sv׼@4>>̳l-B(K֒88T4bD&0L"aD&0L"aD&0L"aD)RF]- >D$5vb{SS2g)ro:i;[#c7q[&[nn{shG#I8~jMiuT")W O*2;C*?m9M=ciW7pӁ3?f:Fm+M (CZ77̳h.+!:I$eZB-vQ%[MEūwnlc{j׶@ڴЀT tj-ڨm9J}[l9>KTJF)_@:!-vKɸ9a*NrV-m mucݧvmnSwc6quýj`yx8tZU)ؚmWMq#$ъae*V,'d $D:U( BR}Ve蹶{嘮bXEq:d3B _o%'FS͟.Q:f^8wЃۉsl9YV>":`1|+Wn1LKD =~@Y n`1CmҾYsmym&/}be1fAp;[x"kpvџl]E,oݷg,N1 Ӵ21["lTi)(nvS-3*N VGFAHRp;T/~=mټKe]ŝϾ09 ;e}ZC˦5mͿxێ<$kjd3]+V#\O5s b3$ 3!U>C3"^R>!P%\JcNuNw7lv6 όvsrGm6F͎k/$O]5k䦇ry\Ģ; ceeZoDGjգ5K$,ޘ mvd),OJ*B2:!Osj7MzIAc?t>-gVҿS1Vn+\ FEp;Xa>1Ͻ.,m7u,71C09n"qv9h~ EI̠4Wj#8etq A?T?i9߾zgmq?~3#?|8YJ+"{Ž/6Y46+-Lqu9wӚ o4~LȪ —8'a=U2.l7Pw~'ҿ \n>{ӧ΋"n#ۢK@H>$ zF>)_O>:9xZCձ_ʌk S}clUhwOx:a' ɱJAƻURt"(!j-տv7_q8\vQOLXNK;yZeskvbیMoa]^ok>'=Ʀ)瑔c@qԽInj~}'ب&NwaF' '&UM?O?gk @)N cvd7etzuyibfl{{Po7'Ae匞+[wv79ՑqC=ˋm%pSAbvvW4i I fOT|C*F5MD?5l\颢r%A5 a~v[bl C.."ddV#\MI}Vz~&@#H襉,{H/k%h!!+=*ֶtWJʼF(MAs5r8q#ViCL,.:3P쥶C0s|07w.R:1,Lwm_ ,ɲu :P ikey5Ї=õUw"k"es. DEV>]vWFNeH2*aOr8 Fj[n"dbQ!P<=Ue#{\{ey[{7?o,SNC]@F0]V AkYGTo)m7 g<.Iq]H1é@/Fuk=kz9}>سLUxfd k^bdwSwe-2;{ wݶ]kD7a&LLf:1꫉dvH5frVl/ZU`E)"Sg+3=AR>5cw~2C:_p1\Z{KkugܵXk4kAhx-4 QiI;7n̑K<N0*SS\tsN N;rۋ{[n#g#{cqud턤 y% kFԬvKlEF mF`keѬ*DQ lV*n^`UDۨ"TEڈyG(MNͷo.*鮛ue#'7pvۦ[S4.`7;rX0Kv̂tFQ-"%_3+vl%U[|?nd" !$j_0SP?qL%9llvV]e$7:9ۖl[vvq8"P~8m䶸2ua0n sc}LeYkBSM3s )JOrdEFE0*J?|BwHPs@qr[eg6Me]=kEk B]QUkq&3&X2j{I#5.hs*X+|22'H6WI)G#V)@!J#`wTzI9n6K,G {dxM|2]'Kx`rza\(Z9F8Ӑp8TzJB=WAU UA *3&a1J? "!6L/%1a%;tc\֞i$p%x[FK<.hH(O*MC$n1zPQ!B= =:N0k^(Z{.A 懍&ȑט^\+*B,"c5R9 CNQzZ]X6Gu^\* <8aVFy*QF>c MߪZ]4BA&-n cw,0,s6}û)ډb ײ)hΨ#c^)^癭)0qʞ-{uZ\$U$R5!#[,:'qȾ!,8vyD,N,#ca9s}ms(':n,&>>m/(\m0 .sn}b>H}8xN4 "v7Vi .D嚵^򞮄K[9G*€yx,D"\8HŧRw-2vp:Ӭ]'9p|Oi G{pK q޺ؒ5Vi5WIL-bi9X)L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"a./$EUZvMϱ_f+SLhB̹OR*ĉ " )uLx:^]`hԇW6]]CiM h hNP%J*v)3o(9T>ͺ$2I$=!d fE ]!5% lPdgi65s?SPF1<+r7f̩;DIwKLDGJcDh܇ {gt.'& vuD@D:Q_c4 4߼A8'OU{sk):"(M ZYJ3n#h#Sx4hS$SUJ:\R5.<ޘaF]6mx54 >+5mhtUϧAQ>"Tsv8: kaGR" T]XRnsV`"Dp("̂$.=:+y_zr nTJNV[3-L۸h饭i|i\}RHZQS }svfHOp?>؝UiZYB;^SY6嵂Z +-z])=xf'w:%罋p%%AW Wrh&vnu&<_u=B؏QDp$p.$QVrEѲ -/-:CRy6 wcmQ=;e4ߨZ=^k1kZ☮PHlw_Qv9M"[wػJή!0 X gvZb xI5?ťp{eCqsZ|<5((Oҫ@[9[,tghERYH-'`zcpOgT8, /s{j ^ʂQǁ*2ji|p3#ls{9ZZ&PvK@[+IK[JlIkl_HՒ '3so/ ++2,,s.OͶFAi#D}@@H Q'2/>8.d\I@j*N%5@fKm \5&[I~nh&-R̋o*iT;C3g5ۺ8X qhjIßh!v5gѧM*Www/̰ԯ4[QkQeu]F-h0@Z&g A(MM&V =WG`#5Xo5 $ 4|%౻;'#@._WAZX ¯WYPZ-+󄠂,l\Fr[b WrsL!L,nnatdORK|'C+>hSl핕̀kDd8<жJFTi%U=һ&Ijč(kQMnu{@ygMP)"Ogoj B 8P<Fޱ6VPftQDh|P  SorT\QT֐ %!t٠}F^afhHU]r;4qeEڳL`6 * aiQ%،Am:Fa( \-fkY-0P,PI=NEWc‰fP`U۸bl3SҍfqiZ ;Ks,MCN^$]ŭ[MUC ?2766>׾gث?WAɠZg\Yvݪ =q.?ۄiseZ&cq]4擓Ap8svṉ?!C;wQ41SZWPs]JvI4j[ #g|0i Gؙ::%m0jkMQ˒NL))!&5J.51QSjxͺܤ13sc(֊#XtWGRIk䅒*ìX6Ejqyq䊻f[e&m+*QO70AB+I,!U͛dO s.<zLk{myk9D$k IpvKўzW9tiy]{]]~@^Tu< i'Z܎oo]+6Φ>^CחoQKQ!.nN; m@;;S{`hc\]sy% !)0Cc}-k(nm1Dջy3+=vv S%W=q3b;p]#6]@5ƲuwhlV\$kfl 0۲28m"|h#cwoN;=q~GAquM~OAȰmKvVc2)NAriReTJ }khdXAVOe+.,Kۻ6FkgI/q4;1ZCBx;ޟ}MëO>SCjJo{5unA0F:)*@`l}̴F#k!I#\A{t0Ӳp3a0If&(Z(R!ԃa|󉛱nCr&ok51Kxlfl詻Dz􈗑ӓ;$2K8NVg {11h|yW'qI pF#[dH-kPƅuOa!MXnuNnKv[ܢb2I,fYʘy4,>+uYcA"3<`X9}SI^R ޛ?k\߷}\3xSx@s}[cop'7v34bhp=JN6չ:$حr3-AF{O@Mll'H U{͗2}Y<T1ȺF+6F'prS܉7 hnƵ:@8ku,}tC'kiLXL ⷏7|my8N+k _]L^^w-s8-֙KZ< dEp|fjhu"q`R _{$dxz7'3y\\zc~ }g[c qK@'/EL"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0=WY>oslݥ1Ls9#]A kfpWwHQBle7hJDV*E VSn0*<,zh`1Hn;K[vl\lcx˻H$8G46fېZEѓåZXng%,vR9t3:X[jBw߷7v̨Xyasl=HK&nO .We3;\m+7gOqd7Ixѩsv:7c{  ֖Eآȱ:c,Lpڤ3 $Q5EK?{O]v>Wduff]7ύIMm|͑|r292{\{=i6]:S%WR2d=\Y5=-KF{mh9F^ndw̤hVh P~ y׸D->]Mqac3R'Mc{o0I޵ y-uaM{kvO%1{[4ڋ|cBB*n ha4(oan.3!b^ׯ$m .kRQg06QL~OUnSwoLHLV\JӮ8|`幸}s$s5;]ȟD1m-W31 *r4 =x S&$]ۼQlk븉VG3k85-v$P)%}Iuphdo'qKk1d0f;g} esA,Q,6O7wj"9r1װ彙#b458(ΘT7]85n(K*%re-)5D)1gCɕCowx:-Ր_- |uIandlk\G9j#ziƛw$Ozց%qgm8=5֖ lkIw.dNjt`\GeDV\ i\z?zag6jTSF'۾\V귆7[dy6MkT`LV왖pA~.q ˼L8IG]:h4i6&2};wNPQMF9`(Q ?EdS꟔0 nmv'`k0͞R^>{(p-mRCŸr~"p;v74]7p=գLJF1Z2tFx hL3*4ʢ1N"^Á\9)RPvpᰟ.]q&=cKCq֍d.a ch jRmuF8nI-ナI$h&Z*x^)!۾Y yAɊfg.DbuΘa"`B,Z2B[%Imnl{f8CK_I/vcdT9I` #^1*9,Kap:7WfX0*V&˒'X+%ܮUWHt׵d|1 %#i]͖vFêB/] ]ɜ5pG6Ԗ5/9y'E톍G=kR-P6x UеH@ȹT뙻F=Y mD=(uKtʿ;K~mLoU/- rbq{@Fm\myKIxiZT=s{ Edq=Z9|^# ЃШ*3R0"ZG<4H:s&ٰY7h>ki)%X*@gD!I^Lf{R ՘~ݷYzKcddG\46rƾA=cCn#&:!F'wa&0H />~`I2>Ę6rlSe%%UI.c*@1|լũkLW{7s!9s'85ơ_$>!n'kH-190 Mc#qk[_)GYTE&4m61R@@u+vKU vgǰ.7Q8"oAmtoysn {JnN;gyQ8wo>zbUV#[tM$RϯQS:^n:P`l\7FƙJ8H5h)p@ID '>m]>nnm޶_AmߵZ]cŴwF1ô-vRvc ^dI4Ap/k.!:7Q>~-kE+SS!^eE⦞F<<,4[!;d,V 廦tPEQLH=<zv#lw9F#>XWC)7N:H#9r>Kn9 ʲ,=W +ML=x.lsH>(ݢ^`Yc%>so#{庣mbqJŎ`{\s6)cL@u֎f65 ^>n7pvvt%&^>j wڸS)Jִ㪔O jiկE}^|||z3AEyz?E}G*jQ%yLN骟Q2j?`"wf=[K]$MM{kV^LQ,p!ȃFMÆh?)PpH`*rz:{Pu{m-|ѴTE 4ԡ5I1E#qM $}GF% e ֵ̱MPtM_NP$SL3s ޽WwNiVՓF-,5**ud[hs6H$A:Y( 'w ųёHMbBKGe+JКhhiCe|.\% 5'Q^"%oq`1`U^48!vc KVS* 㘥eLu,!i|Ztn$8.q882؋r;C˪1i$ 4 4 k[4s)Ne_^~_||) Q=oUV5CwcMW"=z%0ps"Eh]YR]?#5󨒈*E9L7L>߽ZE.᠐K ?d/Ls1%{ܔɾӐr_p:u ̈́YۓCu=~[ F! b R(}?. ԗ3Q.kSZ׏F#}&e~9چ wa 1 " b!! ͓DfMHDRZf-G$HyI'RI$jI$=1\'>N  (F.aahXG0)C$p@)A@G潛l|"?4e㪺ujI7{V㽓iNS56ݣ%]l[P Nm܍Se 1; 8rE*FK_/U|09E&8s=աq+\v5![;"ļ{N~Ӈ!AĞeP,bHcvw7 &L@!ޯzKQqwyJW}r. X]~U-srNl=%iBNTjʁ +"uǫ~rϘy-7•lA hޟG8%K\.Z ._bp "im|Ym ghøfv1B--ix61#/@w)Q7iK^u„+n̘_vY{L6X]_ȱ:´ҧpC(!##ϋ;kYR3F1 kk#PQ@T[-aiuc.v;O.<\KcjH{@R+/:A!usS{MNC\C^ r{pO5Ʊ!X+(>QQ|8ۻuY/xX{v%CGE9G},k8ik}-$P۹mzWbL[tN6r88\' Ѹ]_YT2 t1Lwcͳ3鐶]O 5֔qX;e#2AW8Zy4X=}Hv~f$||U5\J.wWN,i9ENu]HNtʇYqT7];2a<<G05r ``PQkۗ2,㾚 &5*^gQuO1ąӞړAO_ުS{byɽۢ}%QLu[jkZܔB(Wl垮SM?S9[q@`hgBNe1Ocb.!8Y>Ҟ8+ץ+V+^- f #XY騶i(L)5Bȩ_Yiec`IЍ:lK,Ihpt Ǒ:ޝ]]ɻq!(K`gۘXq]:縊@k@k[J_$ױлFpkX %qw6-NM\|-ZƄm`P,ui[}-(N(۳6ٺM&cn{  XWR*E,OPP &`7 0Z!}M,e#J[!c"rkZ?q ?Qmz}wj}UF/tƺ##2f?fq%;1vy\m6|U;VH#5=܇ 5q-q̷Go&<\E4y1x'\\MO ئ0L"aD&0L"aD&kCONf{&fͫ!2o[?g8 -մQjvT*cml,V򵺛!$ vZcU7L[:8lᦔo֠9Sz9smz~\ַ-}9M]mPLpS]*nMYV9w"Id2B`)=  Mw[kIMqd`=ᤊV&6֒4sj%nFr:*8UNIWk7ֳbHlY&M&SuLʠCģ ݺxasP*+H#!T[kY0|^"h)< b9D"1NQ?>ݟd+I#zRî^d75oi5E[Nɪ`v Κ÷Fjh-/Stvwae;5)iH@UUd_Aa7a;{zu]M9&ۘeֺj)JxU{7mbN\4h(Ƶ䪿n[z-@f2~1וv3J- ƺ ɊMD;zQh~J <{|r^LQ4(=U7-ž錍혰Z|.wWrWah&U˃h9oLIGSxt;nug*2 VV5œxY3> .Rݬtp$Exzz5z;;lYz_i{1ּFK8BRV63)L%")өF[~6~2 |K,xZE494o57븞+0:5sq]RoUXuz}roNA}=gkWSfU/jMK%36v$|s8+Tk$H($/sN'eY+ZP8q $wgjd[ K9"CICɥVU}%}@q2YmefU0~˜%Q,%d%dV^ 9_΀(MKbsR98 x)n#sapkn5xTe!*ND-td=g66ZW9 S`Kz i0kZڌ4x=elߴΟ1M7m~{RtqlG!k߶-- 'ut}zxu\m+m/.-и_ⴵceښo[l9P9Bƣ`mO*$UeT*`czfj,nb q #iXX \PUk%%n$s7x^k 3M֓U9+mvjUjn PfT)<&RQgtݶb{L/sx<%Tۯy(h\S6?/I*Sx0܉52tGi@ dQ7J?Q+^խS_UY})ͬQ^+kS }esT[|dZxb$e|a~t&N:F1괲f5dF|5fkTzc k)j{xff5o뭕14x>~ 5æ"⊇*cM}se#ƌTn+@ZTqVrbwPxyׅj@(gשuuj.XE?X&ޡ Wr&زjQC RG=![[ /I'{ 1̓ Qm&Y66'OcqjGȺ S9S4'^3#anaeT]3#='B˽3 1hyTսδF٤i}BO>m<;JzIy@8HȽoD:hDx|sz}^9cGҽ}ӬÝ2_NYᔶjأ-2dW_I},Pǥv[5#*nʯUDȬ@U&փD,ȄJ:aۋX٠trWrDr;=Ko `z+gh;p-G9T*ۇ[omRۺw׷x8fIf뢱u'#MG)%HSrb䰿9?G^60^@ۛgVr#0x*}Y9)9m)5Y( yGY^nS|.Mb6۶{p|n가p x-&O͔k,Zh -eN,vr')6'N0C F[CkXZx~m}\ld%:c|.w׋SU\S7n=jW* 27jGv9:u z: 9r%D ؆) 2Lpo3-{5.#C5 _^;6Q6$N:>!S׆:i?%c#ɟn" e~ mO\(Ύ>Cvm'.[[oOzOGtqh)>Yr߂}gbg?*y}ǍB4U{`RkF4i4u3{M^0)V81(|ravL/c{[G844<8Cte0G.%S}P#}<7ήnl]FQÄIʡ0^vK\kSP訧cN _N:}8G,Shqo{偶E#ei'XuACO\(ΎX!k߶˖?Q?)?|/~?O\YΟ1M7m~{R|ų8ۻp@ѫ}lMXkCAU(szzJ:U 1L!D &,vuMd&s|S<>*Ɇ+14(O|P+9g7^3OhgmSKlH[L1@njuq& `t`ⷍ 'HdkGvZ5qߛicFͪ)JP7ը"nߝ[_6˸`(,klu|l2Ujlg.O؝DάK*LS)#ױYc1ݯ&Bj\%rc'zѵ4Kxֹ/*^i8ЫH=60Hw[q&! {ĥ)DD.+>mHqx5G̀OJg+Ob{w6)\h :s䥿zOGts'7m~{RtqlG!k߶--'=s䣌Sd:8 _^,om1lC=F)ɺ+޲WZ0uu]-Hy,[w^,dJR@Ja!Qu#gcu嵶9=F8Zx5Vܷ[%#͗H  SW:xYMD&0L"aD&0L"amGZd{f>WWnzG Ydd(PJp{ح7wan{kmnrMir4/i$hr7]EX%գX-!̚#ŏiV)6r hg/j͝~:g/'9;W䡊AGG## X)r"Wz TWPO铺U}}w#|cyh,5-G2HwQu ookBH]F֞8i4q]$5Jم&7s)5 窦&wQ6w+ (~(/ҝ07/d-dvϖW5RDcƮ&-8h7޾n]ct͊ `&Mo!Q qg|K$o`P\u{TlfIzQ cx%OW2[S4s<c]Nl B(8QhWޱ>Zc`c@ 8 9A-= .C p5ևо`,)ڛj0AV-3>2I,T zzHl/7nlj. 5 m.c64Gvq'=2,8% H9/pR+Lz%L -!~cC+mͧmSqfF{Y?+[f?H7 S3NlrG(;do^\W{?QS_*D&WK^~8>ޜ/z=_/ߝ.v7<2âr6Yx ;tT[ w _6Ig)Rt0aytlں~g4٠FXki@^Hh$mv =t4.72FdAK\;NfaXtcX /h+ e 7b}ݤ Sjkpf31dV o4e@11vh66#o 8ie9P>C1§N ѥU긒a1-yt_zsK^$Y:]o5z-@@zOPgn PCr v6_+9RvQE cs9"c4PcQϹatWO>ϝ.s"\jI&ҤēĞ%~7݌hc1(%?n^ Nyk/Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z?_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;Oq}x/8/z=_'Ηwz;WşIL"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aEGҞ^([)Џ T3sa"?F 3gN5C&*Xw#[#e6+`/`߿M7[o`ew?\=+k^Y 5n3-qE1By'\P::ɨ:jCr(&!r!<@C?-!pёOH^)l*|<ŧوoB99A;D)T&HAa!s/SzjkWIt4}<.h9Cz?_>~7s[H*,m?ݏUF.j40o1ߕu|7E1xUZ**bAo+M؃v9]{pN3i|>,>K/ܾ} ݥdi]>Tjo6i#6)-~ 4mNSZȂ`o,]:U1:~(e=2o-Փ7PH>UI3~g+彟Q<4Ix.9ɋ6<&c$P`f,)g" . =Ĭ((*~#QXaf[ {Z2\h%|cKh*Ok+7ܼۛۀYJXNZMtUư5kz{"DR:D(w(QL9{mv6Do^u q\o[GéY# hƀU[c#h/٫e̺I]՚E s}{HP1٩wv/%i,H> QWթ]WCȘJq'v3O Kg`+V}BvE[qS'~7^mSMzOZ.% 8صv^jMtڐl*2c99wj wR1gonZ@\`a'O2Z{Kߢ7zBorEp}OԻ|?(ᏔM =~Y_謌QUmmLk<;z6] Z(VEŶQ(AQCJP0Dnn&}ˋ$ysy8ԓO5[dQ(lm9\n'U+)ge".zڟspWes_Z.m)LY^+71!d/?Oc =~Anf[GtH;W۸+c$֐:GZDI-$yԕѾсs-V h w!$'*sc(S Nutchɘ-+>sOXYn휌Nh͵ɩi$Vkƍ-;y+{̳3ۏFQwBXcUEUH&ܳ=Xz^L 郱MR/D]uPK>S]8}B**9T ͧQl{@Y%5J=;>Sjwt,`P;1&@'V=*=;e9tZn`gp*{EyK*@HicnplHbs7Q2FyZ8vj{NS xI׵G/T[9+d9{/djw7`[OYcgrKnII=xQ{aLl^N0ln16( VL*e;G9.X.ѤֆҤi}^߫K{]<-yfX5:|%}/息߃[g|o_HMWRPΐ4Nu݋YM"N&"2)&+*$a2F)@|s%7.b9;&q5ꬫ<.+/}eqKJUJ;_S|t+yLuw*};]nl@h*̼wʺ9 CG^pэLW2 Qd==۸wrCmvK )'NkͯմRN纮sjO%Ի} kW~V(}f{9߁?R聯_D޾3ܧ x}JCqui67WR8ɰ*e&w,!Z%0*!Р=Dc\K7r/2:kRA$xIiieiaqgcEJkCqk [߁΄O:vURh,}wgы/ܿ]~͟J])TV,z6zeJ?=ԄrO)3}zŽ8R8T(C@ 3&㿘1(pKxeHRKjIJ?/$ޡU2ʛŪ6NC Lxdd쏘I.~PD:A ޻%,oeG9MѠG7VCتm5/R?U]IZzKե֑n={?/֊{e$5Kة@Du a] d6{A z_nL1[~K_}ڿ>Q7&+Ep}W[q֘8x-Uv'iius/9gKJ34lR{D|sEedy<]N#U1Xآ&7S5 10L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aJ{x ontB?2GRδ}R}?7͟8YT?dKocԍlڳпՃ~%6m+ՁsѮX=yO;d?ڻ._?M̷ywg Yr{~+ Q}i:"cĴ3 nbiuZEI?`G>ܨxˋR(ȵnyR&A" w c F/0@P}3ڛ5v%XN0exߌ{cٛ~ǜri'}_HeEZs*ŸSo#'(>ĪO ߢy5ui]uչ;W?/՗ܒ7^ºHbii_/cM7,#l'+deɪ;YE/AGb:2R=Q!*3{~^f f<45Ê3H._~3O +gnԬV=@tm]M X'UT;7g5˨1o#W;eD.k>?ړ_гz_a ?ΑrR]/=xȉoOW\/Q3wK]'V?[UQoVIeUרl;h C߱}m.@Ignveb?y&Otίgnӑ}o,zW8usދV<[BGzZY9(*1)҆%bjXP(&1y:"`?®}mk&ONPſHXR:1WO$!;}Y;j!Xyc'IPo n`3-7wyHL#=]PZ* ].#LVpx^:4}WgGOQ\mD[sf(wcĴKyfa>iX&YhG}߬o!>vg-~Aʪލ?ڻ-3F&r]g{\?^?]hW]hk>;Я% YEd[/])LT`l#2EҚZsNT_Z<]IJYbnw/Wd'gWJUUcՔUue(޿M]?Z=ړ?3?Et;9taD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0J=^P7:STgZ>c)>VD~_fk,M2U%7rFFmYɄV_˿fn?jBzWh ?[R]/kf[ىScOLIh,,+6M]O.|֖AQwm}vV&*zK$nn훂 F)Wh᫄ȪG))^b#uZ[{w0>iG`W;T?KǵS|I{^̬:k]3˒DP'ܚђE/imb~ػyXwfYDra<ͽڗ%qc6z]NTq݇}i[f^"rțmjM9!6KeR\DvtHjS=gM]{&&F?'?a&;,-d`O)@xLJxբU?{:+FOP}U֟qE4k99zrw3(g_W.yIXJPVߟՒCTdi":39wV Z'"ԪƗ#vҭD+z󳢪Q.p( $3!tKqw{U4p*Ŝ0[jXlnf68wr9 #)kIӍZ.1j́*ށ#:6~e$.3$FRo#ngnfM[9*st9]y|$׺$6pi<O0@bKkt$YWjo zERjۻ'P@LQ9ؑpӔzXYu{veaAOQB,Sy4mm+I\( U<5[0p_,n2ptw Fo vE#T2(ޔ3UD>]rE ZStZ͎R&N}kFUȽ {LdN#hƤxN*Dk3 s9x9Ge!"d#qrLU]ZUY#5`1D@r9!2V H 8A"TYMr^wk jxVUy{d,Z5ƂКUUև[ar7o&B~?Zok7 _ w?wڅ'YMy[i4ܤI;i{nE@?!@3챱+F"@ IWȿ{܋dO#?5!-ПuX%ϣv_'!=lm?̕JS??[e>[)GVN:m=F'셨7ԝ)nѝԙċƪ+_` SD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0ZS)%1}J:+I`WH BT91cɂZ b`Q'o'I\pu~5^SJL"o𷗇PL s몭`D|n'qX`5*@ܓ\+=FYa5<=jﰹwwonf'N-鏲W;>3?%㎭P86_c!u]>ںݦN:鯮'A(d#o1le9 ^/tWqA# Ƽ}sO#sqzeM5ge_iݾXlJgr-DH)&$`/ERCv>Li`dKG-Mt˼G yyǗV96z]NNP8q7cE/ZFg]+5B+VɅndMnc&[aI"aL?=Jo~sq51>???; ~E!܋3 <P<#1}* zxȻ?GPuAZ~UɯD擮O[bϤIX]曣_mm'bu+BoXf.+~VIS[eO \c[g0+[w/]7/BM6m*N2ELbAPIS_5Tib؁J"b% 9fmW\GX9;rXOi^DV4#0qn.60q;axhLg.b6U=ae`~znn-tVw.8KYTg,q5i:\=M*<N 5j؜X9P#TuPmhӢLFL$9{@͘"6ouCi d|-l̏P͡-G:Hfvg:+\z6&De$%R+LlJiaxcp7} G9RxKP4x;Gv G#χ!?i<pNR=sZ?r?/Q>q%`uwn~eyԯ ]eaLY$?MmO]?6r*?5o1- ~H'kE22n͖٨.Q@*DΜ:Ϊ~wV3[S}@߫#m9ƗZTRRQcyd>!qK6\3/xU9#QCZ2QSz%(kZuɾ#hb%᎝kA8D;\ٲC묐(<#NZ[Q˗5gѤ/ώWWZ"g H]&+U\0;݊gjp Ѹ8fY#+?YJx uvuqP&ib5[gm̶o*$8} Q ]JM,Iɍ7}"HmkxJ=% _E{uCk"rx̗NQHxzΤ(9vG<.}@8F;Zc2'iP WV^ԏd,x%ת>OY0'#n|k%lA""D 6lJ"su퉱-6]rrIJ&3NP[{OesVN>Zx=xcA;|Iϖ7ʻ}u!:8qݑ>Oisp"rzչ;W?/՗JWpkJ tE)#˵/4* JQ '2H(pa" #ga2apkCwAz4hH\bJ@#F.|GU9>2I<=EVEk-Fց5}@AUE;g륳ǏarPqҶƆv]o5u xo4Ӕ<zXΔ6Q?PQPɦcDNc{-uyf\8W΅\GڐAHXxJ ߚ_kFY){G~U\5V}K$\敜MI۟V뽻Q,*>XI,ԌeKmg;lp6~rEUBRӨWscf cja-4>QN-\k*?s~?ړ_г_a ?ΑrR]/=xȉoOW\/Q3wK]'V?[UYo6x{Cʋ3#v8ݣX)UvUv0&_s׻o/Zg|ai#ZoaA8VA!st䟦71gۏF"LjbRd[RN~~2g-s&/e&~mD qQq?8}G \+2rvjbyHdg P:-zߞv"L*B?H݂'< 5@+8&N<;jjX8'p8'Y<6Q(X=1p츶Mbli%dJ͕*) S޽bvw ] O:GI"iPugkV(#]F8̸ Cz;<ڴ|KǫkYKn|#QR&ʕqTIFI$23nd\y6B8jy/^$Rqv/RZܳ%tph<P7dg޹*YKHFbL(MK3A P %xc`yM 7 e0Ιowbҥk=o]o;7w4'j]:j]-/t9'E+Nŵ&vs&E4tqYȠ.YUND/tEsɍ kI$5:RԎq'=qEh?oKF\9քuQoѐ;c\?UzUoFw]xˣ.{3DY+oQյΝW ?ݬT n "OJn67yHi49a'`JvXA.'L)D=z7Qw6pvAs|af]pv; K.XTi'WiWӗr_ z[|! a?jS}9!5Ǭ|o/p){Ge'|ۛFqFx׮Kwk^5"61i-0TU%=&0.IpHjRF^7i-)-UBGcK>_ nj/l2U*Oplq*nӗ[8?GWGRtFt?XRg/~;}'g .L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0ר}MSszd*ݥ,bPT$7l58H:ns s)Ns&.@mjSZTɤ@pZ,;o7GWtp{jh||-Uk9> ^nv숋eT~*~p`=PU?N~quƽe,_ ꤿ9˶O h'~e?~]'+C(5NI-D$=by(IDQ[P0U;ᥦ9 XI{p4<-pÁ-2v`AB"GxHOtg)55adqOznf8Ҕbæքû@_"!RytQ ~ݖ[,M1ܲزVxdOqKmZX1p^ZC~RN '(2 m)Kq8 7n1ay= ~w}j6v;K02퇿"'3NU8KS>+7*L\!u5r5VYoM}m7.5{ϵV ^-x|d{ߨvXAMWy6yU|il}4;Z tӈ>/YNA=<W\f?"WT’fE[w3wu9,N!ew['1!ZM/t_Gu0_8SО_(i w6/5#8$1TMߘ$?|O?| ǻ_TNmo/ѼsHpwh7o5&kr؅tmto8%E]o+;N"[N4ִV+AUn66M&6>[>bmrMnU:hɍE=UzE}Cw4g hDo#{?3~7o{>eiW)_}Z*:w}w{O/mzx?Q _ETFvޤ_eQ~bkЂGZ'u >D%D* 3cMc5-E{.) 4:ZYB7nʷݒBtB GOSiX(i w&/5#8$1TMߘ$?|O?| ǻOR6~`wq?[I32Og3)tq{D)m; *"gI,6`TP;,MUoMnU=:.s]-竕<Տp`!#O0)WxP+bHzoU5m} kK-p jxyj~> ~?eOnQpf:PR Wvlbl:7Q5SiOX)}26i4vi;̙ؿj K;3K>Y,vp\ A0GK7[UG@ -G^ukە<l3lRYT<OƲ1!V318km88 ,5i eaC=R=owQ̝]5\tu9בZrv+4֕Jp$ӂ|QO9f"FJYդ> ,$+v!ޥݖ꬛ &B0uSK)ςm~팉ApIansYT-VaD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"a=_1QJa!Nkׂ<@A9/f|aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"~tzq,6˪Nøy2b[7 jJH*ݠ TeS6vov\8M+#g|.-Hgw+nyJ@A#$ +R Hל;BR;I _U [\v ̌#-qZ 'Q1|= 1e.|:du UHf:ÅGQCMo4&pG>rԻq.3m73o}$"zN';S)JL؏슿JPΠџ Np fzzairslU*׶8Qܒխq `>6ؙ;7TA+ѻ`[t+M\<_ ~uMC6r cmŨ?cYۇJMb]&Q.~rtF=3ǺQQz:g:qᩦI $濱5:<h*Ne)t.ڪɐ% {}B'vB >* 涹l8T9y=Dѹ5~J.ϫc'ZGA@]"bg{D7oSDDs01w{K0嶉=䢮sI$@yޣnݝA̬h4kds@a&xI>2L)l6_% 6,~Q)?^ϪgHg+_eG?;co]T(Ε|ӝC =,`W|b 2<@'ɉ =ZrPv)H=r) DLWtBנqlXcep .Fy>ңkBS|\s$,wn$!%of^N=bA¬jE21޳(\ Npv;CsM[y `$\y˸PܗXxГ4Z ,E*_c1 5TDTFH4QVEQY#58 9RG$2:)Z[+IBA !\s\ZEAυD-y>^=Y۲WW=jmqrq0Z'xmɓ&8Om u 9ÍBu;hqwsOe :  PiO)NRI}::O8YKl 8 yׯyO+v7\έml}pw"a.]=<:yQatqwY;Z_%!Ϋ+ܓ WqUJNڕ*XkN#`+؈v =i(cZ8.%͠7QW9s xyYn-^6V3ޘhֽo'I*~Tyӿ |>^f+,.Fh.t  ^h|#͞ g^ //_}?[~zrs\iMC^G5լS+Za4r^3m$#P踪'oSu:pi' e{GsMG9O9m̸Ue5wHZ-VzaD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD,szT=<)߶ecٖ ӏ);%Fy%J*U+3e )6)UG ~ڗ;2|dѝ_Y N *??#p58pc|.q=aCr' Gu-7֖^jh\0MI7nEFUJ-UtLjt7ZmÈl8[FyOw Ē|nqs5{YI+I>Dl *9[cЯ\Lؕ8nHn۷q-z1IԢe;N+k&cD 7OSHLeM#>AGK}C.ؘ-H+#x ZjLjUiGd6-HH6 "͓D٫r&<(>ep9/y%Ǚ-wp-xn&uo{`II*(mks0ݶ *CA̔c}i*rrhvZ!Anvqdǹ9neڲP$Bc"aLV]ŴV;sK+xjRU yCisJW(~[JMXM3v8j-}o^f4zcf Y=yqE^6nɺ ٠VQIV" 7@MHIHR)@f\.+ p\7x?nK+:~2F_%'_qzumOČr'3(,毑xA`cƪsGy.d.s0y<#]z|(x9(YrO[HH#8j|EH $s&fD9e|O1 di (A Ѐj &jz6ϡ:?S%͟fYq%<^Din;YYGdd%􌌃Վ]Wr EUP:0""9F38[@ ^W< 6OG+ 9oj']2<5r i7%F{GzJFn[վjJ.IJW,'a$RKY]F;"N"0)s4&XJ2i }g"(B1FY8QDo?F?fs8k˯.[oQ~j=Q$:^)2VRKԏ*F"H|VbQHCv7׷K.[W5JVE{@U 1WaD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aE??wEη׫2|©5Um3LT#D*`g{#s2L=G\0R;]^{OǬC˙:%6#X-BAEi[Kzn9d\9g-IH\})- Σxi9L< "m6rZ66  VW601Ugh|V{ <],jL""¶38xL4f݋S=xn4R]u:w9La{!\Rk (e#u3'%v[|)<a@z\w kL`%1@0 WLS@@@C;@\y@#ΝϏgWіC+=в[Mlq ]i7#`2˯9TLC7iĆBR[-$Ӧ)Qkb vs㌱x}-#$fLC2dJ.R1dMVXjITdLb-9kH G0G] ȯv|ժҝn)/>֯۷ʨ[ EO63mfǯ?u𖷣?G$[}g=c_8y_dc~ceܿ%ڑ޳澙~?ɑt.]^D&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"hrgr"qsangU?C{mQAcogt8Cj)uarQ䷣㓃&5yN?\u@6MT$ki&Rdɲe gI#HjIjW_K>aoTnfLi(ɀg!/XyLs 3g?B![ì#717PN/en՛rGMf@ptcM<!!pȦhCT?Q׋][W7;͏ɦ|o,]l_~_Jڽ;>M7ǣx1?Mv+"wp*{QY{fh˱nba.~TīHIקA.K wwq9i #R+{nmͻBPxirVronɝշ?Wlk?5qdy?UݿNnf] U .: Y"*VMt@1J !C uWn.]I7+܅=g"ҽP~@9@O9>_aԯkW6xfGs's{YwʺnbESp(#d(CJ@ 71:|U.<ee-z4UZ)_g?8tѸ&W;@lǙN+{2F1lGHW1~t^2zih*W-1L1C L!98AA\t`wܦye^`VxFȾ[qɗpUri =M%[#gԦye@r`<(v^~O^sL?<^<\'.,(w5WxEJ>X|+:DWD; tCޥչ?=`v&?|'Ozl0Ycgkaqn11 J=i%$ѻ&xEH/F;nTITb(C":7<H #ĺEG%Wҝn)/֯۷ʩ[ EO63mfǯ?u𖷣?G$[}g=c_8y_dc~ceܿ%ڑ޳澙~?ɑt.]^D&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L";s7\rk-rQ(u@ A_E:@v,صY5*=R>\c.hDz乤qI][COV7\#wqwqG]U>[9Y~ % X>"S83L \PP+~,mx8xU5)0WSBE󏘗Eݻ*UK]~*1u;,%FZ4p過b0`]8\I3Kti8RǂO1~Da _S?eǘ?#h2]#~߬kwnӓvMyfFxx 9ẑrkA7fW!ET8R\l382cxR8TV^؃ˊ6S>TWHI\wuن~}3dQ1UM V@rJ"s.BX,6Уuۍ`,Z6yTUs=;'nXM߬f5F4>e#u3'%v[|)<a4n? =-3qwӾLop\tw]9/Tt|{f,"j9MVټlU% b(C L!s Ђ9G"KEZOF+OP80xC82<cj\{qEGiԦue)x@9~cB&$m0av|3>_o&8w$Y DJ*P©ZB%Ծ0,(dpQJ>gw^Q5/Gg'Ǯ$H:lox5t7TvvsPPMB9  9k\ph RvDrS%͟fYן}iK]џ #-ұu0uIGl={Yadzxͬx&ji{XIK,͂30=QSQG QPL'I3y"iX{gc?f;dh5KƤ!}cםE(sOh44z8eߢK? q%mtgBHċotzg4Vllo ovrsR8u?TQoc\/;O2.˫D&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0RT=ϯngcn4 媷.N-}DU:nf1j2,ȩ`ɳG{dGun #༦+]! ']fJ\Y|`h-/ѽgk5dT6D;D }qz06͇6 ѓξM@yzt38La$Ocp ;|M֛f5KiFafDlCT8HJIf$"(."C ut yN o'K8PHJ۝V< ZH(8:+P =7բ*Dy^ RQ?T=Et2me{`.תN. p?I}(mi'h,aW8T&AڙR 쌲6Lq^,q5847u{n3pݖr@4Z߶G/Jy뫀tbccHjz=4!*(4ʬbTKʽ¢xYm".Ɯs<9O^n] !LI,9@$<[Қ[lMGuQ'J(H?(L#z&`a`qyܻx85%tVVwE>n݂PWVۂt4̫*Qo5i `J6@e#1Y0p:kԘ pne^x  P^PϝB/Y[CH<}G< .lt/f^~-F/ďH{WJpG߿fVpIWoKG-=#=+gSG 65}2s"I\0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD(d׹-Ev}U}omBgwwؼ>;Uj)NuRk^TUiC^KJRtJIovv;<1uɭ|cڏ/`KjGwΐGݥcNȽ.<=NIos_?_5iSuէEؽ1{י Q*SPK>L2AOj> \iu0~ʬ.bZOl^#n8oUMCz=GOƟuP{Pi] "_oV$7q9ԗc}8Viw_\n1mgߐkFiU7]g執N?fjgjѡuStҴUAL:y'yM4׭کj"z??aZ_z??O_z{Mw/__߯|k<]xyY{i={=+ޞ t`/yݾ3/;;{;U9V+]h| zC݉+WOa_Ks~~{ݞOye~:[d>o;]:E+9+*3#qo<]SE5WON|V>d}ٓ|ߋ};xuX}uWg&0Tۿ)_ß/w~ ~7piz罷y~iε+U{:iUiJq%&;ו<5 SVއ>Hz9ޔRkX; ??O~+'> i8V~j|i/v^;'bz[{km4RUTKoF:~U'W[g80L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD&0L"aD& endstream endobj 3 0 obj <> endobj 4 0 obj <>/FirstChar 32/Widths[226 0 0 0 0 0 0 0 311 311 0 0 257 0 267 0 506 506 506 0 0 506 0 0 0 0 275 0 0 0 0 0 0 0 0 529 630 0 458 0 630 0 0 0 422 0 0 0 532 0 562 472 495 0 591 0 0 0 0 0 0 0 0 0 0 493 536 418 536 503 316 474 536 245 0 479 245 813 536 537 536 0 355 398 346 536 473 745]/FontDescriptor 7 0 R>> endobj 5 0 obj <>/FirstChar 32/Widths[226 0 0 0 0 0 0 0 0 0 0 0 249 306 252 386 506 506 506 0 0 506 0 0 0 0 267 0 0 0 0 0 0 578 0 533 615 488 459 630 623 251 0 0 420 0 0 662 516 0 542 459 487 641 567 0 0 0 0 0 0 0 0 0 0 479 525 422 525 497 305 470 525 229 0 454 229 798 525 527 525 0 348 391 334 525 451 714 433 452]/FontDescriptor 8 0 R>> endobj 6 0 obj <>/FirstChar 32/Widths[226 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 605 0 518 0 487 0 637 0 0 0 0 422 0 0 0 532 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 527 527 411 527 491 316 527 527 245 0 0 0 803 527 527 527 0 352 394 346 527]/FontDescriptor 9 0 R>> endobj 7 0 obj <> endobj 8 0 obj <> endobj 9 0 obj <> endobj 10 0 obj <>stream x|TL9lzOv7B$j$4iJXPPvzWzmW`/W^}}} L=sfyis8-^85 Xs/@Ӗ-u54\ 3Zpؖu9%t3܅mw?aXXa<{ ~1?@W` sg/J ǜ0;ְ Bv{WBm5ǿpm¯;'&v&Nܑ'wI1;|GQsLq,r\c= uF:$g3Yr}xÏh勪/n;5dLcS=A7۞q UQ V՚k-Z36z,Ymwt֗X?+/a__RjFm1@ 5+CN^bĬel[|;f߰ow{ƳxY+8CDL4Ȇ<*:0&t K`)Uc r ;! $"H'CSȩdYM' % ymbL óy&/d#@Aa3X@ xHDpB>@!C,4Ti0Fh908UN"JI"q'qd "SIOō/ʿMʯAqrHܢ*GmGܮxĝw{ ._0a[El.4C<(ta;M<$]^ ȹ"D<,B.&vpHhOXOx+`&N$gDxV8s)I/dH/TWWDxUd_ 2W"K)ExKM䊷EP#ĻX'JTÜjN33̙,s9ǜk3 ̅"s\j.3+̕A*`sediX[Z-#,#,c,c-mq,-D$ 9lVdK2222222222dI)-XZY[XZN,,WB5fբUA] VCP5L W#H5J&ߒAPt4&Vf ؆؆R4(l0ݶ&[6jai+%,cckkdoku&&&:te26eMMP+Kemm_fN---Qα--f;ݶڶƶv,ٶsm.]hvRe+lWڮ]k޶vm;lwy|u^CZJ+hm4"ZLKh-t5MZ::6&:t$L[Nb. FWӵ,z6=BzH/fz%A7 Rz:Udu\.TԥDS]NQX[YgX[gZXgYOζbc]hk]TgsSձ4uڭ.Sbu:N=IOѿ;)҇#MF/[mvzCG밇n;i/EwG $} %2K__tә1; c,ŰXǜRX*Kg,ˊZgl=zu*֫Zf;5D}>IQow}~>EEoջ]ߡOgw3Y=l^}~>W_?{Vd}~]_!}ޫ/֗n}JT?ML?]\B_?џO=3Ys9 z__W W _7K}_Me[+;Ukk7ݧ-Ԗje"Tm\NIAE^YQfӬZEinR/U/Q/V/zެʵ\L*{{ԝCpEo՚FmV }_}6Muj1X[SDXH}O֛) dmw]k[QfM[3,k5}EX>b}q'"ZSX'gL,S8T)1 2UL5&7"d)'- *]D~C?L0H a,@ׇp o z}[D!CNS/eM*v#D&^~g0cx+XzA^#ѯ\FGP>fsX0^藢fjpг\l:!wt6M&DO-+9d&mΤ43g(۟Q?lFe3g(۟Q?lFe3_Dts%xv"?x>/{8DpG2Ng?`eO =ssmj.R$O=Z XyE n+ o.#亯kx!'|=`O_?_'D(/m6vjcݹՠ܏,w莾i|,5ݸnE wb>ewBX߳/mی(E}+k? Qzz'GRYq,m?g}ԗȶw9J2؉/᳾g5|?P?bgKAp_Ȁ#=B% Tӗq0*[ S&wN8}\1G:qXC}!U*+JKrsSS]IQa Z&pF d׻=]=<ؘ#ˮnWc8nc{=ݾlGѳ%Fc~csȷyjXp: G}:Gr4,۪C]Cg9ٰU0a'ݵp+I&FWn`=F:F 5C{LX9rpck.Ԯ,}kz֍m`6ՓXI.yFO'˅{QR.dž':ձ5b dV.L gs:\.uT,+;`j6peu.D%|lYh{[UlvTϺl/avM6[36|tkkqa_k<݅#0'ϵ'Usƶ ]Oy97t&(rnl-vn/bZ}̞Įȟ3w>Cޓix 6w\)hCV8 ]FQhmBC ,ehlbѡL)?'%o,;VߜP~F] 3⟠ϓJZ_Ov6X \8Q%w1{T\-c]-'璶cJr_(Сȃ Ym5Ìr_q@sSٱjA4 7x~zutdɗ0JvߘJ|Q^džWq6()ĂsX,:|D28i.l@js6Y'KX_ VBO 5$ùI%ťEN\RpK"':^KΜ'~w6k+9 5ێؒgg-nX:%ĝ=ȦaߊB{k<$ě҃H)J&]d ZR t5(-0U!Վg9O y7T`mHh P5YPKИpcEὤs[Wovw^!YMQ#8sӶ+B99!#V3re`bѢ3=gxB HM/`O-b!dmBw +vG}\Dcbw k ՝V wmٞ  Ռ+c,sIgZ\gvj]{iJ<οV\y)g(2j%?snw@^༾T,܇08ɱ?\vy"" ASRSj5'Tf|ixz;sLp(HGƎX=>\_ HWYVl}y[y\rY0(G+8J/o2:Ԗ^єMuEx.-߼x?g*)?^`rarKzneeQ IU/qCbEvT'R@VpEE^N],0rҰLg yg?mA1Q4/o:{jk~[:r'3)0,˝7r#3US9ӝթ5Y-ݹ3ftħq,_Z $? Pm !::'!,$y{알o{HGej3$(,GjSK3C)TΈOȌ֤G๼e2[kK[wztߚ8&J ;/!5$:/j0"^ &gfTꢑHK6"BXbO.LHpZ]*-2ǗpnփpaAc؇:./Ð$ÿKdq/Ҡֻ,I"{brzp[P\;$Dc?H"lu$NԕĂΓxaBbF秤Iuu6O Z_TP]RPFZʌnCWAR}v MO\Ԋc lI鞿 +5x doBI@G]jxd$WK6] 54 gtZUVkw#dzAå(񹳶/֩CK", 7NSZTRj& tݫw,]jAQwlaPRY[3m',(&nCCٽt趬b+)d١46i.E]=nt(鍼S"ɑہ}>Imlv f6KNZ-Q;.DYPKE)-P5݆X.g? ?ixZO&3#ȇ:NofFZ9ai+U/k-3dˋ`nvE琤PS3:"1"\j叟P{ꍓsW&g?{^*Xߕ;98e{~fK⷗I=QIot 7Yƅ5xSLj3~pDO@T*nV)8:)26-FE1aqPNIn]>:!fxWd6 FǗɕ^yej'Zi s0꣋{dPnfͤt;0$%QcppU~jtd>RK-oHlnH@ި9ى搡ybFbXo֚軫j_O>:c&`)>&PFD=˖P\jtHqjUPMCJ1aZ}~[ֈp=(GgU.}7 v'ff2˦7&Ib=jJ)O 5,<%tPcP1cRň0֕59bجp59">YUT(qVFFԝ4q9%k謊ĺQeGNɧJˑ`/,L͓_G&NVKߍlu[9 }99|Om116@?xu= 9 NMH͟Zs&nMJ 0=92$a5wM I={lTF!@ 2>q &6v:\r Y5pm V7w W?i .]*y @ǿ;D! IGvt33#c[9EbDHDۭg9CLa΂ԔD=(s5[V'9ZPRox*\8U5Q D[7B0lt|s*HBB!~ʶQi*/{9M؊3!)gxt gW; /H* 6s[/ZXx-U3,T;81HQe--iZ}95@n֨QYU)YiU6I+܃B8ÿ Ђ>nGSBz@i(2h⣐?z ?&O걿#! W# iGPh'_D%又ߡ'6{.nΫVgiUgIHxؚ؈ꊶGk]ӻl6Y{F)cr3F2 ӜHs\eY8#usIMg mDMjJL1Aj2+S[2֭SM},O^QDGĠWa !9xPWuyy5)UUGDN)LU7MM&hd8/2\F=sI'eNςR9(3¹AU ;~"ùvb1t;,NwL?~GW̾hluWT2utetg9c&lIhO*tSGYJ/ 7E'bcqI 5y3ؤ0SxT-sf;p"_ыV|PpuPrvNf[]@U[" zɰmn8x8H`0'=?vcpwEZ+,Ƥya-j>-jxuO sD&Uyh\1ٞ#(xğyuΦ&d OFjq,jy4t;(4)MSS 5ľH^/-;yY 4gF*1V:IA]$kϟI*<C с_mugnٝpC8]ӭLorj1MFt1hneoPpϏJpҒG y3k\^jJ^ʶ(e^,-aX#z0jp\ރz Cr홽t[UVګzif!MEM|-vL1ud"S"[KdEVꭣy!Q}F"c Ҏf1UspAA7S%WW#%0Nc[)YcRRrc5ѻ4@SbUvH8JK`(e. +K$evXjG!Zd3lA~Aoee}n _o JOe=8U MRYj3#5vCRfˍ.an{R\hR5B|ehO(]6giFFS}m`Ed'%gfU&ɕG3+dEEf s;I ,,l8NAz6qcݗtk'kS<[hr q!Qɯ ѥs&y.0$2"'%rAl;iJGĖ,zT#97)O{y3Y{Mioho훣Mdt|Bp>NH~}%B•8 tmQ}ߛ3*3545"Ĕ,eAq9b),:'%1=FcӘEl7-Cgo.zsQ3y`f5<1} G\x[-ĒNi|' 2z QZp284v[\c2DS: .{3JIdtN2=^%GCƚ3L Ų+l,GJ6`A6D(AQiyQ7,A2=.M~_h|%a3 #hYE!ڑv U?l<,b$ {&E) נy𱥆le9;+(B䎵D*Yy2CϢ} 9$z1Y7ˍ۱Srh O7>*xz$*f Ϩ4>j&Sg\9 jW1/>#F3Gfy)oL%E&FG&nYEw](;zT~WJRr̦RB[.En%6R~ⓔUKom%S yRa7> }clҾ>ķIC$bcw/ZDQ\>˔Ff=M^\5`BE7CVNMNplDgXjSrJ%um"#BScǾqQ%[c4ZcJ=_rZ0e鋦Uf?/zFWgxQo<?-WG!oHa#'F$>~i1q~#cP$H0MŴшXI ۽.+M5-A8_Ǯ?90wgw!՘?>̕){C"WP*? "Ln><ހ"?dʇG\HzL8qR%bH?z֎]'zOB1zjvaibb,b4BDS4xo > ìX:яA34 ط?؈h<OA~S׋ߊ~cqMM!TgJB1N>CoCދ q;Үe,gg#nZ1}\Ge֨ 1}@f r!6!6h,! 3G,`X8٨ a9l݉B|nAi}xAB<}?F{#QoA{!/~$ `&]tf쀽],mF|6z|g>{s# ; {-t7H>#6{ KOLNS oR{~ӋROl[?8Bcv%[# }Ov+q(וC+ eD'10=FʱPf#$G.Na%hw5"ސ+(?3O& ^ Dh`C'`KUPC(21|c/93/Ki2C ;I.2T?VM8\]Vʰ=8Bz{K1jgWSv?;NS\xѷhknTL"h5s {VӰnb$f$4UF+A|^EgӏJC xyqJX' 6[+"&DJ~ ~AX/Ahvli4>)t~97@+,ñm?Xk#On󽋭^B`0I J̇@0Zq{ Jpq^E\&6q" . V+[tgSܣ~;HuII+"_u l!PVi/Ysh `?I_q585MQ'"XF&ČǤ|݈0l<}ԭgJ忲 <>Aei(TF(0*; ot oᘿ Qe|xa[P hC(*̓QV8S r _=O`Z1nh0q91B!F##j}Ha4;7o)hgS Cw[ЎނcrSarW|< =hC'h]X|)} 5Vi!A+b,<|6.|;u\( v@=7eCr.rP: q0H p[uBV*ӡt0#m$X~1LD=bmD9$v9"S uK>7!Lޝ}f/qRi#^G|C# 'D7Prd v&߾؈w?i_{?uC`{DO0AbmB5"ڟ:#P6mɣ|'y7I>/V6΃(SF`*m&I%>yBSas6VЇ|:Y`Yt#X`l m})by(ozP6&|` hczD:KB{,P{%ݨ}J3Z-\^b}"$~ }Wy>x2|8ra8Y#d5>`#~XKA!΁8!h{%^}ȶفM P#^Gc0$K O ɀ$(3X2`A,Kd 60aq0K4݄?"?;4Pڑrұ ȸgF Q¾ؽ7%7v!De6[ġ̬6)W F7H>>X祖5|s>[:+( 裁o>l𾃶V0Wm9oF_x2I?^J~H~=y7@~wLD5b]CpP/z' 3qw 'wGqA~@ 0;~1"v ڬ@k/{½B^>ǺMaxXPK =O2kF}I3+x)"VXm/u }}x ~1hs} qgwԼX,}g3x?We퀯3hc.Cٗ1 x~[x"Ys:"໧z?4|TUx3^|{x)H[MWju ;q{1@<~?f[-^ǜ~da?-1U 'CKVaLF ؀} lج dscfz46 wHb+y8\`|G1Чӫw~=1,^79lheQ?uٛvig%p&.Ihg}w=F mqNC}~l@^؀cC ֛/sNjD*7"{v p'7Q]{q|-om >G|Zݳ ߵϧxuz15bOߞx&K%h2,EP!ygE{2`{?rp#F~L1@ՏE5DC;`)1.p?s 4/ߝ_쿽C:3by{!WnČOU ޠ8u8sPcKubZ3$Ӏ/}? 2~wsLigw!ۆ$eYv_u2ogr.ő2@瓱OFBX/ 1aGC;0C(CC=gȷو&Du2֍r.F7JDǕ@G>E_(|+6>!v #ueG~g>̍~_Wn)EXG{!qD{>yw^dO1ww.uށuc~ ߡSg'}} =}ĵȷʟ6SƠL#B "ݔqJI:yzŽ## <?;Q>gi0X"^@KP/7ާЦ๨@=Eu|f."h0`<,Q_nOaܛi)y{#` cvDQќ?Po C8^%W*4yu<|B1ē{/"nF7tGsO~FTGc" j09SDzJ&k=cMe]~8 c w^.CD;dc]nX?X7B@` `za<~_ljS1=<͸.Lÿ_ 'o9o1y _M1+gwRw9~qfJ~eO//vdu2beYQJd\(Irem~wd?z Or qdOw' yydjdy?f:ܑߌv/*!-HϠn.^ָ6/UnB eԣ8_<~ mahwW<=xn:zdj{pNmPa~)]eذmmD*o ˣ)ϴqrq8/w_<0? ѩ]"ȳ@yʀX#6(,B?).3՞/$.YX@=dBt;UxRO?Qky-)3UԳqrׅe@C^ET{.ELP~UY9/OTzay+bQ*+:h2ys:beϫ:w_/!ߢ }vFg!cY% B|8 Qob$~[0#,"|{ ? \U{.(v]r+vwsQZHd料ie[*8kiY[ii-Z, =X=y֗,g,̙33 1u~g8}_cWA3Ud<'y" ]ݶx>bC` ej,"8"*;Wtqi`v#qp2>&ɸǿ@yӢ|'%1cJf ꊾHB0>NpO7][T23!jnBD|Wd2.+/h;֣m3dj(2wb޳(|# ,2 fyc9`SShW@aiD=[f ?~B8΋+D+ϖ5_>kϬD=]܄t790GOL>@_'6χz2QŌ <0bmd{̟i>^8Q\jؓ}i" QI" e͍eW h3OqO|ぶʵČQԌgq1y mwh6d/[b@hh(4GMM>p6K!t*ZGpy0-ظ|Q&QP݌&ߥhK\)Z^&)-wY%|e|G] s?Qɯ/wEG4ieyX\f vyz?sT Sr="qr]#bMH([I_zx_ /GMr~"X>5Ai}E#mpغ:uJ>K^Uqw_N=-p^6´Z6ڛJ~+p>k1Vڃr(:˴[5%^UQ2mOapTQѱ u~ڭbvI@HpEGzh؉=Mڌ@ݘ&cSETqHSזĨ׻8}X]jj/Lٍr %,ll !X֦؊+ծW{lqwVv^ppaZ׏dwS'V,Pwe{Fr\1#Mfqma _7M[Q _8Wm x_7-m;vhHyHIfr.7k' y OLV% Mn1ik2Ƥ2=zTxMTܾ ߍ|#L2g&.#T{@QWX~}*N1\%fߵT]2*/Lɩ>XL Q)Nl`Zc 7*7  Eg[Pb&5AU~c@ wc?Q?R稳L='~KNS/$ǾNezt$]:F}F>eO81u:L>ާR>n^=]jWSMޢޤvQ;7שv湍ʉ[&j#zZOJR:FʡVo^^^UzJj{ZN-RK\jzZ@=Ǭy\).7zM=A͢fR3t.>zJ=FMRIDj^!0E2 !Aju?5CyT:FGR)zT#h5u/5NM RC .j 5OR}T/=6(ImOxc#f}ffA.wORQr=mnn-M= VvP۩mVj Ĭ72 5fzZtj WC^a/S/Q*jvWY^ezx'h-ûBp7,bL<,Y=Ôy\ijzϡfs`YL9w34qj =a}G~d==4IM L<^ s={*JFQ#QR#T3=D)ՄjLFJ5RP tzT* T0P6(Ti*JQ~z,j|g7(18 >Q,#` `XxlPx顲?s?5CyT+jAA]¨R5MSuwm*ց]@AK+ ՙJ:QT"՞jG%Pmx u'U̍DR1T4U@EQTyf9*,@. .gpG~)_(ݽ=.o-&v 5z*Xւge<C=z(BpnaPj5DE P~T_՛E%S=Nե\<7Su8&6UIՠlQU);e4J½508>@o5WHB, OfvtF tFO3%<=c6N x a챞c1 ^Ow ^-;;;{zywy 2⳼j«8-OOR6BgO`==ó s 53?OvoO/W'pux{xfw$:y:azGWCv+.;9AinDԘs1S碵Ԋ*+(ΨQ34'93raHSdQSCBzCm"tQ\\Ԓg>mSY=x< 8%Xsq- r5"()H\ AjƷL - T܁5jǟ 8W}ДJ"H+%H G}\t-t51T>9ʔ_w9)9ӻOEkإ7'M.ZE'DwKY+1' n9À^!ZMO?:_C rt$qR^#Qwy`&X#Gݓo7 endstream endobj 11 0 obj <>stream xw|TU?~ʽ25}L&T$@ !t]@D@`/(QA]+.Z|ֵ*\u9wp?}^&2ysv/A!$"O^S }%۶lo !1vsNEϣcf̹zByO9uGI]8( IG9B3=0N9w E}V2lVz voۺbwc|ςE\t.E|ȾFsC}"^N֐d?9Nӥt Lҽua贔ŝ{%8w=nv_>>qwylO'Ǔ)z== =7yvxx+zHǛMfysý&`Mp$'$Z&.N& %$5ɖ7鉤ג~Qʵs2gE>g8!H;9AЕtps}nnPܩ=nr{U7kGݿskwq7ٞ\OYYMDn ؁x:7ĖOpx+:72Z27x~F]3$?Y?9݀z|v=M?!ta:qS>=|}a>X1+>|0оvϠ_~iͧ%>ύ>Wnss BOkS@[^ j z onb"Bl3>a/HQ yqN&SWԏ4Z ֦zM𓏴yko^Z{M{]H;=C}sڅK%<}i! %"J;1PD;a\Ko1tms<~I_ot+ ZGF#RPFŨrTj8ԄƣIh*%j]K:1Vl18xH~H^|a{F*G0JW>{:Kt8jHȄHEVP Z3h=wM7f-E|[|m$Y n*7]vw=]|_@nc;d 'ŏNCD)~c]ya/KvGZ7e߰!'HV`{ş{Pd]a1a=0{8{Q I&cڙ`fvSavLcGcVfcvց4 1`Ǚ= ΞaYɞcQ$fX { ,űӨ ߎ{X<-s1{yK,|^eI5ΰ:Kegi,{foXf,IJ؟Y6a}Y. ceo{M)TS)ݔa4eM9\S)T`*47ML%RPs<\c5יGḥ 1qFsyyy"_07<̶̰̲\ecgY`YdY,^oYbYfYaYiYeYmƲƲֲβ޲reee&v-,[mmϲ!#qUy.K"^R@H FFu$Di*C3h&ͦ}i>G hZDZBR꧃h$,OCi Bhͥڵ6-j7ii7kzmvvvQAiw4OA]Q۩m6kwj[]V.m ˿,_Y]Q'=jA$ڦ>NUULu:K}R>^W\:O=W BH=.VKuL=.WVW'ԫgԕ*9uzR=^>Q_PUUOשUשS׫/ԗ՗ՍݠިnRϨ-խYu& fvM-Vm6u'vN/_;QwSRUVޣVWU?c%s6g VK6}oVξa[VɾcCُlհY-X'lH zQe FK"#16V8%3kd6^RIe%5K6IɒHv*9ڤ06U gӤ6]d3(6Sf6[rX6Gcsx6Or-lI>XJdK$TJfˤߠlVHij[)UR[-ek,FʖrR'K%Ra\xHX!<,\-<"V Džk'5>ZIap_X' ppH(n7 GM1a!l [m &fYappJMx^! .F)~+)NKxI[xYGxE-*+Vᗄ3^u(LBI|E$ooʛ)%Vqɏʏȏˏ)>%EIRҔD%UIVO!).VRD+2e2H~Y>#*^~E~]~M> SZeR ߒ$#E~[2ZiT*1J2N LUf*ӕ4e2CJHT>'.,&"WEV+JRTZ\ebSؕpũD;;].n%[S*%_U i9|B>,P(eBeXY.%+[^ZNFA(X(EUb[[mhuZSJRd*E> |D>֪5jRT)CP\~Su:\)Sfe2JiPZI?SGjr2_YSV#UZRT-M룥kZ&TZ2<-_ۧ=Ii o^FWhZ:NS":NmZ1nbw^$`T{(0ALYEPMV&A.7D+*JmVUkô,}XmV(O+ B)~BP d B_HcXQ'4 a0QhF t0B &+FY1V5gW;MqivR;=odJl- lT6HziTn$?NYx(k#2O12rދ??J%g?Dz~ aBG!sY_8d|n= Y|o d| ;d{iy-tI{^5wjJaPE :XE?WniP-`7 Ct&Ey)gs ,a:N zNmB1dny3=Evh[3">M2_lV~Zek*ۯU_lV~Zek*ۯU_lU6&7@ߪ_toGzɠ h"jF-m07<}4̀0 gYh`K2]ƈ[BϝWAy\#+ t-uh Az]vmMݽh |.m[Э;h'ntO/:.t/t(=~;t=,@jA2]jp}巼[Zkwf@_e]rM/IlG_qOܭx7;n؁{K~wI= zjz ~/{SI}tBa%cCcW2)hsX7Dyh' i~c~Vp;"XWЫ5{[ G֠ |v? BH||&NKiy.=gNu?xLl󔠒 O~i?4xp"jfx*+\R;C|Cə耬@W^{oZI(>@I_N*Zo(wyM: ΆK<ρSvДtuojv m7nOoO󕷧G<=W^ўՌ.&|"RZ K}x-&8#z\to =h g7~TH~dmH->/_߲Qkx23@$=4eJL޶N+/mtc:V׊9p~k 01=۷=78x<| f54 iG-mU|^- {{=Cy(5yG EI8uz5sm7|Ӛ*liyoԯz:s.%!F5 jZ2Qxyph@VB˪aUաÞ&_Mf~sqCL-5+*[}rskG` *Zf{n54jƵу33 >77!qtAɐMXqB~J8N``w#V?*}ցN3hu  A_X b0|yV77JQ;ov78,Hg.b 6is(T#r*R~KOG 0{u 60ݜ_L hm|hL#VJnk Nn7JpQ ,~ZmjoJ_8IWg[;ò)&/n{to07`_|pP[zЖʮ eD!yeD-hr9 nx_[RLG7'wQrQtP5 O}ߦ'IZRu+ P|CP{R%ι rI;qbͽ 33LN޼٤]LZwˉ pbdXIH6Q(#GMsxlL!~@c11ec6jˤmw;_|(scx,Glxx^u _'aP2}%Vmat;_V:2t1d㟚Tg(.ї􍪨Q q>YTJN~>է:F9ƈcPYY(;Yd=v>מOoNPzzRDEBB} 8(HGR%IN0Tvb㒬؄ ZtJOEX_TRx@f,WpP(5Ym;/U͚r( H:hA~)Uz u glX Uf8B]a) 3u^4%8oQzzEA [YBeFۆ,B")#crfϛݐpS[n'!* y/W8|@߼ G_;6v*("X_\\ं%yYahΥv[zs`:59xg\p_mtzwu̙n!=#`R~[Ng0I^qWIGq-wbW5=}=h00000xظU GF.<4=a/R+v,}My0t2V,OEuˎ\zDžolh\7F `fT<\"7l8185'k8#gDcnB;8):*:*9=*Jt#GQ݁sqss3$I<R ((г_ K`NFUv5#5!0 x1Ƴ L;QxbAQ8ÐL|R(ts >lM}!?j{݃S owbXVTlءbƚ*V@q1쑿E|2T>Fog Ӂ]~ }5luVzݼpRsȡN\dY`'Au^?ûA )h:"xXNle-Cg.ytꈾËVUMY\Noqtʧv74`VǗU&UNT`XRe~8_m93Ƭ}:2,ap9HwH-q!돀jcO{*?]<bLrz=SjMUU-R +RW)m,/=Ҟ\6v ~>:g}iź}vjWҶ xMbu3sy<}K4(~-ۂ-VvڬU쀹l)WY"J%5٭;pWSz}y(3#͚R2x^sIزtU%z=ڮE'9-(3ʑz=5n}czbr8%".WߝE6q^ĵ+K #B(;(lCXنm++V*E).R<5 pR'rwSY OݩK-UV䞡v!GdžB]ڶK͝rR!הF WDhyغ,9ah ;SVM]җK Z:GOd/N^qz3x$Ř7Ѕ?Nx m|cX۠ތ rJg,<, ?g()T6 n=*R#)@%+%`|zlUR%TR .dQq=moo|^|BHfجpМVUrXuntۑU;Od#l|eX-WZ s2 s$u$/|>Skc\*Nf=cvQI UOFlL Os%{,/谾lqٸW5wop ꌴfW_ΑUi'c'06MN{\nK GY#s(eCMP͉ku~"(3ʤkV94Otyk̓\.)/S2s!7h>I~$kDp. bSpˑ^k_P19X *;9,2V7zO]ZѽtV0 {Lύʪ)]]hs)䊇ngbT8sKT[?z1#/z77G#Xݩq Ţ_*7" 1~݁KG۪u}>ݰgrM.WFB\[Ό" )VjX|t_-+i}q_A@pVf_A{@r!&"3qFJձB@!xVf<_Aa`%#"j3!勲 %G Q f4)ziJݥ]dL([]IpCfdzs^r3pXU{Zek}ԌYgD]^ןO%x!"%.+/xi\ololT7 H,Q=Z:b`07_42ufmtY,2VPU;H7FCYijA4eg-N2"2d-%gjoTcˬ8nYU*SpŔ1#b-sSh\Aaޫ Oxzl!;?4p0a}C~ꦆ n!QKj?xQlYNu4;5$8ل%܇4P'urgXQ\ZcVT)a>ȕDȲ͡N-^+(Zo1OJgUuQ5܃9ƚk/vM)ʟnغ֢Ix6ݵZM{ dCKdCK emi=+tm/fWJ#H:)|?RZm]}<ʔCJ c'˞Y?Ԗ* BJA{S^aҊ릖8ӆdjZGNpG \Te=.3LӇ%[=0^JezW6Hy0ӯ{$ *.Ӽq@1o7ͦ˷+5ɲ٢?'u]SV3ښ5bwF\1xy٫^9( ;e2w_w0LUfP>b_`2_y|XĹjuȍx3/x(_oI猫ȉ^N/ۿOy+?rL?%mԪQUi_/3sBAuvZxԘ T́Kt;clr S cKVgpj٣mRDtӗ/ՓЧd4_ o_d$*F!/ӐyZdV,LjyWہRjgTΜf+'t5V5(kP qEM G;mHmH;\,fu: ~3:E!/k E*ubMRzAŲ=#.<2vL &֑U9*07\ۿ-3dƦ)$!;;1yHR4D1jt'}x`y6$7vqgц] 0𥿐?^i)6*T L ˻e^b˼ˋf{x+fPE/_ / zSJL4CtZӃxx^͇xtF:WaBIAIO] "69ݑq>YDvz]v'eU/ &Lǩ33FUGfDIvz8 i ֟/B&ed/Nd7Nq8% 8x@1Ku6#_uy6A_厄0l#lmQe˫N.ޞ3 n5mΈ3HP#k\oqI6.+; ⃒࣒OPЬ[4E!GW ]S-25'Zj1iu( +G&8LτHP{D!mbvzcHa֋B͝/.5L2+BwuƘͰB^IThDL2_45^hqcYn7@1Q8Ұ !R6smó0~M }@|UoNZOUۻsgP\yz%K9R19SpE;df ;S852Y:G@C%5[W|Ѩ;߅\8JOpBR8ݟ .eg\#@5F V[7=i dМGoN&onNjv4"fO&Y]T,HptbxE&֙Ev*" pҧ]\H>D"ۛg/,HRPw ݯ/fH&QsF;2Wc#YѯKIW'\yx&q"=Fo3 AV}YPٙ3ܕ^ro3G=Qwjz<.Eqex2yٙ L0I1\y?"?u? 7SPBJy٥%YsfgU=pTCt&9ʈŅG{#͂._iV iNҬfVIrIyWjʨ78d9]7i?Ļ=$]>E=t?W–J2KL#0~¢xo{u4 =t}r'bV>2==gNUж[\%u9cf4Edh{v|ZZ60zg!]kB>1eqbN>NјoH]^af!4#J3f4B%>_O}\E7=ƓSƋK zb۝\v7*ց{vegH?Boypɢ^x /]b, ]c&uNT1f–s3#(iS,X^81v3Gڣl*;8 )͠ E {@KVqZ\\~8B+£{"y4/ ~Q!뢧ɵH G«5EO(_Ѽ`;5$`^Hyyj]FD8ܙzόGg`NdVsg?KUUyܬ"Gl#p=MQ0i[sVЍϐ+ohe7Cɋ̟n~M6YW|6x`AwV=0d+!6U$YUCgԯ;196GUx~3(jq]vSt\|ưen5&X3,Ibj"׺xoGӪL|MV8xۄ;WSQ)1"|2ԅiy?yk!a/`kxO(GWpst@.zTm6du}}U47 p?G"}D 6"@_H*R[mH" p=6븎N1 P0 c\j7B?C 􀘀o!lF R<B ʁ{_h[pK_Esa -,Gt-l=2i}/ ׭Cs. @[ȏ?G{FhF\h/)`4 t@>2_B{ҍ]z:q4A}w? *v"-qM` h,5v"/+EA_Ct=YoBLz W`Ahƅ|4 s[ـ|JF BBIP6%0 :[ z_rcH{xL8DIR*JQymt=~;0Z+"@#`]^G7Ooh?Їm ŒNMu zRV{M_}Z+hWG>[o34  ?4Ϡd#wY{?wyduMFGO(A@z.tJ iɀ"ڊP9'Cm@C(k P+I`¹ЯkwCא둛 e56"7)DhgK;`92rv>^݀Y8-4-*3tj{\CU[vG}@A^s1}\_8mA/uhWBe{Ex Bn@EӂB׽7ㅮQb߃><_~>I[.Dđ]?|"g}VoA}=w hR/YtA-] ܿ i.r༇@G%pcأ\>XurQ {'dTMi451C| oES9&}-e DDwt#>qYseF)[LWP+F<8zևF^P|vaGpX8["} gʢfML_]b7Pl]7@qRX#W^ &p ˆI6t]8b7n9/Mp,8'4 ީd)9?UK_r>6@X\nv 4BDO/Fhk|Z.~}(gPc 13HΰQ tl7.!O7. Ð, -`nfX(:x3ntA&xtSJAp-nD;C-эPkQp* E~0Z0;x3L|^x {h? =7]XIOKx,%~~Ct^r 2]% x O-"OTIoH%=s@V|P2z菃N?h,ҡO >ؿAxwi^Tm[qv'@ɫ`?GS h zbTx 0L\h1d E.{%ә0c j rlLLfs>W8˹`T hG5I4%AG&_%|ꡭ'g8 j4\Kv[ԗB%r #pM=!Q{P'*'Fh똁ΠT <2 GU@( uT h&&!X1\OP ~h}+9ddF4 ]uX~ɂC<C6Eg{h8c:rrssOO 5PmwW%2ppn%?^t/\i^l2Tm(?x[!6xph_2h/] õ/t^0v/x =& w.]`=7q0qnʱ1x֞9yϼX125&(`+a<݄Da,̅cKn.'?|8Um G>D1B؊#p-4bNaz y/*jwKx@O=qlA Z3@ϗnA`v= nw9l0Vc$1'^s{@/?,>E?MV wE:mĀwgA<wn0?0?7H-UXzcZ 'Os9sm*yw-}Xod0fؠuiאW+& G7躙ҵ0g#]/1ل> 8m =:Q9pm G,sE\o~:k_nyj˽jey3Nn{ԓɨAs4:źqܨo SFFmv`QHw#ܳ6cC548"~.w9 t]| BW@9\*9 _ z:7 ?Noxl N7t$ď;$b]r--p 2V4xӠØ?9 O >m*z'#>Bf~xgmC;/{\YiT(v@{cl nSMxbuk\_{> 1՟ݦלѭ~Ǚث(l@ m |F dlZJ[d)p 1a>}?y=1>jmB&BH`C/ A%H( dI !7 VA( 0 "`AA,ػyM6߽}yΙ39gSV7 4]y,v)mx~,0h 17g|ܟϼߵy?Q>gP DlSynw~Ϙyqfׂce{o,/Cq.9EƳc 9ni;V9/0Sy*Teuy3c̯x[ 4瘢uu6 .W:j>Ey47ލ?U/E7B40>~i<҆w1Q5ڿ;Juzjۿ$y0V>]Uv6;K96] bY) 5"[3 e1SulMTf'sѸ'lsp=pO`*{> ks8!1q-D"ܪmQ?*m[up!Qӛ&67p c}՛px* :9J^)|"!E5h9MKb1ޡR1 ϴr?sHB?F_g}L5xsϜ3~>\9 {DGC͹<OƶŢul_Լ48(W~Qۍ<+m;=@moNh3;[U b81먪1WN+3D e1o:`HRsQ6}<$V"=x{nUaX(OokGs5:{L~iwϬM6XbΫ\js?hdpl5'T>nm/+n׈Q`")j)’&j^^]zt3\ta3ǽɢbcnXPqoe+nKѺ2(Qe_zO^qrI97^?{9n\Rqz9~ЋQrjz~mV_ Oz\qGQQ[AꙧeG̿Q~7uoOY>>iERyOii] {7ӊa s\ c/f"TOgka LnH|t^/Y?ט]יTs}Ŕ_7dԅiotfvs`9Fre/z*嗭akWJ;VwGoagxi?80| _OA03֋k G:61s 1׺Ulq$@ko;yj]xhP8-k940(Z1[:^/5Cpt=Z9nm[2Ds,8ew5,cK.X}Ӊ/y]`R#H A_[eW62[OWBD1S~"1 w/cgWc/FjD;ףz.hDSPπ___E)vAsmأ MqCT}ƱiGD'[ȳ.BqN+"[:)jk]kc|^j} f{MlޮN Y\;VNNĹ pPS뛵" F*ƋE":OD5w=L?(2Ih_P^=b|E ɸ&oen%;N6k/³kF>;3睊>| oM X'kG QXC^ FT6>i5^Smwݖ*RkԹ*g'pP|FiO62y01(0P뛾苄z;|)O(sx6 qsQzچ8p^“f2O[iv%%ShM)p)6ӭMT:$4TĸRWVL^AƳjyf+t7Q](QvEJ+ Q[_~3G&UĒ7EUo骁}!n-z?OGH]yU'l?5}j QjDvHԬQkmj1ʉSgi9u.-!/MGN4lQF;FMTf iǏ?Ue'B u 6@!rǏ?~Ǐ?~Ǐ?~Ǐ?~Ǐ?~ǏRg}'B+!,baw Wܴz-f167Yf!l泙f.9lff&l䱙flfl&flưflFa306l es!l2dz6ظ٤f46lǦ/>lRfs^lzIfӃMw6$&M6ײl:*6 ldӑM6\lڰiͦlZgӜM36M4aӘM#6 4`SM=6ql\l격&M lb&Mp65`&M`6AlΦ;d#L#lcsͧl>a1؜`!llyͻla6#ly͛l`sA6956fWؼ%6{ټflvylcͳlvyv6l)b4$)$ בczCz$1)zLHwn$I+H҅dgNU$ $Wt$@kOrI[6t$h$-HI4#iJ҄ݘ!Itz$q.IXz~hZz(Hʌ ̚$5Hh[(2CHIh[ IIuVAbףS!6=: X)B)I" ^QDR<9' 7_Z鐳z_(u4I1m;EI~"@=e~G-7$_S(%$m|B|DrC*rRH>УG %y2%ym#T0[&$HRIPk$'G |R/%y!MH^ y9TYJ yd;6= D#@#ǂ'>nzz4xƮw;oǻ-lyoOr?:ׂǹ^ <Ƶ ^޽"vMs u4|P9<lێmې<8Tד\[ 6'&< l}<}CNp! 88k5U`%~wxws-3`뎀\lt-6rdMp- " 1Sϝ_8y9sܳ3ݳ g,-Kv(wkyֳ0_vϗmE[ܹ酹n((W\{2"reNm1urCNqO=='8.a{l脑Q##r oHt)tg$ v_t44w~~S}]a/wτdw\ 312MLbɘM썱pvն4sFnˣZkYk5k:iԩ(fbTV"242.-oz]`\kኰpEHv28bP)NӒDqg+Ģ~yC!mLv-7u&A@W%%1KmUI)d(ZMp%^o6);)EReE߉iEeE9dV)*-ҋS2);DR:R&Q/5R$egMϟ_Y*2տVi*ɞ<̻^ G}ppoC xW~^/E y ;3`;tSI l(xZ0x<5`5 V p; n`)X"Fv]$Q%D_K/Q%D_K/Q%h$6@ h$6@ h$6@ h$6@ h$6@ h$6@ h$6@ h$6@ _K}/Q%Dݗu_K}n2'_S+;TQ endstream endobj 12 0 obj <>stream x}w|TE3sw l*IHHO!B 5tP**ҋDECQA˃>VDEDET]H"~fܙ3gN$lH}rY+G#:(:2et^ѕ}Eψ}0_1bu$82َBG1qcccc9& &$(&3c̀{bV<KbyOlPlXltlrlJl؁C댉3b<ēx-7>0>4ߎ'YR'5 y:+t!扳qcd$&{:ރYD8z,Cm;{f3 zvCFs%8q6LGg11ךMn1sc\ΦAlg6UC8uf)9Up6!O;aF2~HvՀz(9y~: \S0vC"~xoNVzN:?>d2kN:g֝Yz3ߋO^s+N/=]y ubඃít/eQjGZWY7N-Pr%h#ڷ:6lsg;nYoo? = j֥֯T`'0w7JCt}Ї*1"֔iEy#@?_E+E{2֜#!f$B*C!A1AKhzC#NS`*̢8:Ss|$_)LRo4R%&J3%i_: Koӻ:ѷt}RuһtkI֊N~f]2:4Iё,5d#(54(ȀƐ mPt :fFmp;P!=,QI%EI$EK)FrJR4HH3Ylit7+vJi@z lT vI%!H R8I+ŁS8)DpH$ud+4AҤ>H Y@ȑC4򥡐' i84nhi 4AsiB?i1i)TI`J@9Jpi-vi/8%CzK$ ̐L-w`tLZ͗˟ɟ|_%O7wiZ^>gsuyG^Wcq"BOʗ7/+||UƟ𳲋?s<_ |8q|3Ws+m|+W6|Nn绸|7{?>_Ae !|?xK*Jv!5(:懸1 N~x<'<J&=ʓ;<x 4~7t!'xc, 7&?_lÿ<O|5/ /xS /f4/[FYF[XZYi`222222222222reB"bR2r J}aj#Gk뭏Y>!&]>ItS֍֧Xn>g}޺Eku 'q$B[ۭ۬;;5=ֽ}֗lvNζ.n^ [mtAULdkBHQH 4 ,\y$w?h_rs}}}}}}}}!BW?j_k_g_o (y2O Ed!YLdyyl##]d+y!Sd#yl"ϑ:&[NRC% OArA$oQrC%T:44C4&$ڐ4NlCsi>- -Mi1-i ԏ6hGi K#i&_EN2~\?ЏoL!;g{l<5ykSFvV{FA{V;mki?jkO ڋ/ZvQۢm.i۴ߴmvYۥ]jn횶Gsi{}.iDۯSδWuYk-U;۴úkڛ[cjAz/=D;j 0}Gh'zo=ZTwh1zԾ㴯x}'j$O_/__|P7?R3oe"o%ޚy[/y;~Wy~w.މBxWn P8(bW**h󾊝S|xŗPx*|+A|̇*!|ʇ+ %TmJ]䣔(>ZcqJ,CqJS~'*I|'+ %OUR4%OWJ:dYJc>[ɄWaL^s,~*9%߫|>O)BR4UfJ `w'DMbOl#žfS3l{Mg ɞgf6ݬe[=l+mcl泝~-`5=l/[%̖l9;VWJ[avaoG؛Qveoum&ֳq{SۨrVS;َ޳c}ۻ@u:XR.~TGc1(uo_m.~]]Vgws{չjsۧ/m}az:ENS'StK%*fTTYݩQk}.u[}ISjS5_-R bMP]*Gm>hk%ju:AީβlvvvM[-ՖE|u@ SjR[RUQTPVWO&Na!mC}YݎTjH[cqxN}~>QO֧S7ק} 3\Czdnѱ@ڙ]sӏ߯4GR 2Hi+|RRFRk)_j؄(#?CS/L0}6FGSﳡ@O|>fw7|Co9IO]Je1>.LV~gw֞bY"::w#һ{ юk:լLGБ(zK?3y\p5r8+a=гɒF:|>Y!zƠp3L~HiZۺnHItSN9eSN9eSN9eSN9eS)(O_^˕sQxv8G_d*^ W$@(Ho~\sѠ诅]Z91nƹy16֗seL\&DlqAYzѵpX0cjO9|'Of w|'t'u}[|6bp ~CHao~Ǵ.ceɊ)QJ].eK9RT*uTyb ?LB>W|#gnbA?&:3}[m1kX~v-MP|97{~O7:< `(,yˤ&Oa*Znzq_aq]7kU!꼉=+wj5;0ϔLZ~){K.+#_0.1G/Q,\qÒ?0~ ⟋8pc,d.0P*J(8mh\X%Ip~8O)p0j<)SbH!gU?k a,Jf1Qp ;9!b)99;IJ2,)[I5R3ɉ9Ra 9^*’RK )UP,'q?(?풌U&cc*?&&oп_>++ztֵKN;oW޶MV-Z6/iVܴIaA~^nNzԤ8glthڬˌ R[:[U9YM4vČ2ժnjGYQf VffR-eNGԻK9+x3̄lh:Q-U9ZV8bA˪2ojkl1Ԗ [l*FUU'9m%3BZn!`gi|ˁC;whYSiA jޢZ1rc[R/xUhCCry~)β䩧BqCSe-SY? UNǂ_vKRQnqJl)w]m[DZTVnò3\)=uńŬ`Y 3=F3͓`p qz1w^'~pBG Qܶt 3rĂJ JՒxDVms-V"o"_A@2iA2TKnVKGat9~2Y/wE5e_Z Tavكq@ Vo;!Vi[mF+`Gl4l?ճ++SG+FV[ m>LsoV*9ďUh8N,\@j3 Y-Km(YPpO!ixUU[aWFbKJe{fj~۷Z%"Rڊy8TQK tuNF"m`qv w{s!#TOݹtkSbj:r ốrA>)i`Ey7,3=FN%zh='tڑl)jn#A,h[n)g$>.߸.R2tf}Y?;Q)s9_@;QΝH^^nnVVf1nDvDBNv1+YQĬibeKډG&:Fi@vIzd309[m%14X[bSά>de^>;cDZ hv(>6g.Y#6n (]_b7.@C[P[EmZ^Cf!  qq!rd+HE%%P=CKѢ5SMCڬY3t@C6%? 9)8AAR<_AA \Y3*Ŋ4"4FS\<ɽ4!Sad)87!#&9]a))2,I|)F k$S]b.{N6/HT 8tҪ8˦Nȇh 5Բ3 k4ekviڶb8fbRp;s]0d?E;fe-cblJ@WػEԪ6!ҪC[V-6=/N-M03ZϖF/Ii2pynk匊 S"`gTPĭ9#3E8p/[-Iaz8&;Rb,5R֔.l+~} L}ffΘw[mmΜ14ƤI)c2rODmD"PsM)kQ0_Ikn 'QI1Jd|#е<(PO EH~!A+SB8nhq8 Y(^NvRAODxjHn5m%9<==,uܜ{܌yvP;]zWr܂!ʹ3T>=ʦQ&m\\tQ3$*툉`M|/.Owi{V!v0q;YԲÄIRJ@ጋOMv9 \b%j&zw Cb|HQzE@z|6ک%km%/=ud?nyTQa%J-JtRCg|mo8QVΉtQ%# bM?I5R]!VŞ%!]n1C82-#"O&VzIݫ#!QTNHLH2U5ȯy݈olvB|Z*gwMj:,uQFPcB]kw䞽+-jZTBP5'P4{h4FZjHvL FBBl`mƴmX#V[#uQb@{ @,㟝h-kfW$$T-Gщ )=m%ᡙG/6;ˢB,G~V54):o ;Z&ڢ֬ei cs]KjQ1``rTn9}C<eq)<[~%_dTÙ_Q_|F~XdK?CZ!!(@ϥ *B9w}]6 ٔ rbF챴%8dB@YثtaQ bw4on!eGospfAP֧sN*KVQ\ڢ}P@`6ךtGlGdfYFr^^NbIP41Cȁ;RyGD%ehڤ厽R4@x? ǭApS7T?gD$74)Lm>sAj Wf<)$uÓڗ4UlghTFm =҉k痕٦˖/D hHfbҚb56OOPj,MlVp{c7c#pZVWK 4ؽKzwiK z4M f>Hl$oG#w^,2/9ܞ[o6Gi%Y~I /[]뜗ؼWUUJ9] rMvPwKŝ 38k Y^buiQ40Й^C$O<0Pp_^;*^s%rTr(ϼ[ sBP/ޙCR0 JvyE f/c씭i6ZIqU2W0ɿ5+Tw<4|n!i]}RSlZhuVW^ҺO҃dy2z(d2j?$_ۢ6%m n[҄ACFJֱu M۴Y%qd8Lv`3aSzr{/-wQBSzX(^/MNney͐`ZBejhGzl Z4{a_:fɌrjrt4|1}u n\yxl\tWbqJ{a}ţpB=R|q<"3%IP#.>2`p=SdeSJ亖ڼDPoX8iݴKȈQԴjrDvD09mtY,Dr+Q:$ѐFCj$DdN ;y]U*>(trsoP~=·9 {6RoTSuYJ6@ҵH"}id 0~~q+"bgGgަ9*7̉_MsSl~bPN-Q%hM4{ꭞoqU9Py6j$40J ʝ l׈G%j/8H#aiml ~2(^kO6 I|'ĥY[ɕ.Ƃpm8]ֿ(ܢ|LFBr}{Onͮe4 lQP??GRp[] nO*訨dFZS.k>pM焹%\PWMVYζy)qm [up aj5'Pf  ,-g0 GJ[G{k yc#n 4Ϊ#r,'uiVV>À¿%Xr~Bg  >ytz@(o "ح5[sN8n/*^Mqoݛ>6 |Pƍ_bEo6/50?Ͻ=RDv(HV0.5Fw6YY'$wrG;Q^3=Bi0ZnnY]_u ihNxȤ(MwfHsdhY8v^-34Bfcs;5InиWy+7,ݦIZz3 ?ahtc S-vkDll_hdԄž[O퓥&o@a[eԔRy5%%#/$/2J5/Ú Jbjl2=*_ٟOwr7 >|urBrhlEVk\>DiQߞd}WI?EE$IU HZ}5An"5KBreܿM{LVj(4.lk jh\"g+Qmvvo0xΊ2?ZZ&u 9 F0ZlHتm6 *c<[VѤ̷1ލٺI\byI7{NYljڰ?S+4_}xڢ}@7Hm]۶( Hkjui7R;ccgStc Pu Uhb"wP4O.46XYF !Z #z"c~$7FcyV9t~CO8L(.&hC3B6" m7%XxJs8Tlq%A5"@ 2 v*/6`۠B.@C't $O?!8͈/_ IvG4GtC ELP XoA"? 5h T&x&t8x#F __v`~ ~0U ǧ$ F"&"͆2RA> ƌ#Fy4D*]lXo<"0GA2kś(} 7̶;)=ndQηߍrv/bW9;z_ Vgn%J/oIr(~7 CaoDbb(b4nQQD8jx@i@Hc<ߪsƗxDoc (&L_#>@0~B\@"-.`lC'e_^5,@$p=@Z:`| lA zB7<`,} :`-9 I1]_G~ETX"c%a4 Y,? CkWӥU` d "C{1_;IsQDшf4ӭc̼Si #qf3d=I3fIm *b DK#}von\k!@Fǰ rbER+ cf6qk<a#v~W ˭]E5QWnfIBorЧ|"l]ytDSuƔrf?!zU^CŭK֨RM2գ zu/Ny/a_e_Cf4>/(Ϣ~E _&ָC2 }I9'ȏ $d =e_בIW&zX,O~0㩈(Oӻᴌ_`id 0o=_ۉb@V6ò_P^x3ȎA׃?T O斞ǵqxUGh˖@ +5aV~-LwCqc76_! ]|x q?G?D1D1]e=AtAh0_%oOpa߃_{|;O3CNGAFa;V5L&` s)!kqR&'޻<9 ðџlG6sa)ko019e|EN`wq1鰱ƐqƧd]ƿmhB<[$&4_ T[8U(̄Ry)^ e^@z `ك{(vc= 7# aKl3}p-CC`"%Ym, 0 $IuZkl, h6Nmz;l'Zt8Hf6A.b8f M'Bc|wz2NG&mYȤ$>s4PGS PxC"ɐtD1OB|D6!%#ZK?ބmjc-s!Kub%'iS.rѮSnmE\'pGl X@:&}. p,Y2F:A+Ac2p|ķ0Ox.>P(oZz4^:&"2^;`yhoqa~ ݂c1@vz_L+{?c:>+56OGŸ,QI+~Ȓ?IW B2ҤU/*üD{0Na~8X(RWEBMzŨAEsMT "гF%)I=Ɉ|]rŸ[)Q8oϾwB?8vMD[6e -1^ӇG;~yN[X62mT#m؃E? }"Y[>vĘ cU{ 8 wЕF/D@{ d c"#[mmutq΃&/}q ٟWW%[)~kgDŽ)5mֶ-簞6޳>vo`hc*lq}>O| X-9ߩ0=+ \A R*l}6wmm0]q!p챛.!{}nLFD|]4G wH0Fϝ_1:#M_|L@l?Qey|9G֙q'9:؊F4DT:õ:gg_xCfalq6D"%HG'γ)9獏hGW̾-Dc8(:h5`!50J{hH&C_N1RĶE†hEN vch.pWn[\,@s/, X(/~"ԓrh[wڛ6Q;ԩc<8E{o=a%y53=#O:ʂ2 mxq<:x);:B ^F݇r8C \ {Δ<:"Ӕ#PCSi㎘xħ?*pЛ}KTʨ΃Jq(>hC(9D~FdD_30ԿZxUnENWP.uGxqA"sbDPtb //>#淨^ȂBzH4ȓ9m2YA(! ]ܗ|6ަ'Q_6 y+tze^zݏJ^n5ihL{ D0쁶}h5Yao:a={1gwM  @3ӯNGջW/D[PӦ-|k_mԯ\w(wORm0A܁JSsea:Ӽ$OCOq̄SXF߃]UȖ@;'7'adq3y՘G C7Ҍ;rW7vM?͜ R6Vӓa 6ؘNB0;:AdۑZp/<(mP=:j*Y#G}X2cn;6sF<{qDWsH!!cQ%w^EܧӤ w;L%i&6ErbAK ~5WXGwa0  K3`.=!G`$yi0Ovq-Kb;~GUo.{n{HsAv(),Fc7d4=p}F a, ,rNq.;s_ z^X_a _PUoq 8_'ߌ7í7PgWhF;L7`6b>YjEp_C"G$vc % Vbtuk"8o!>'rָ).}zĝzm\{T&c__oxryf6^?$dyv!ރ50bg(#QQ˨F? uV)轠] nqe('wvtsaKv}wa2m}ePCNCc%ڶUa>0Fr7&l!}lg#20JD']Hwײ "#~x7WDaXik ]_+>U\/ڵɈ0؏ItbM b0UOvOZ_= Q i:HbALxM#$膘*W~+DY w!*VlkvD*e̓YEmמFx&47yY9bW")iC)s}guMGtVvOM_W7:vn  WIqb.bmm_R*ďidHĈPNfPzyͽq;on\C={ Aϻ1LD "|⋶!n"!w3q&!d.=aw op'- [aCkA0,0,=Ue{GƟ+i}\îJוc1^#*<']y=} #GWeʿ<xJ}ۃgOԎײ'D G<=7o J}{`bS`{߇0|w ytG01=Ldd& wyȕ+H]_wS^K9*o ͻ({2ݠ`0u}  ;W 6~?Dp@2V(N%->ɦ"A^_$=oڡol!A01 M;(wp~vڣٕqSN s 2Ż<&IˬD4Z ;z޸c<{;=e|WiH&;}>o|' a0^^ؽ8*ecplPvW|C=%! GXϢyR,_ MY#l;qf~06˝`<\&/3ڊBw[Mf}|+Bt8;7eskqq<vxW!P;P>H qN嫈ٰw!f>:>}pS`p\ HOH^tog}յ'ƧxfoZc%sϘz2La[[%`c`덲U챝V~\HPBLe5$H(6x텖(++e$Kĵ(*.@y2|+oyxYW /30.1^r7.)~p78F\{Oy7A^jR'i_1u޴%"!vR;DR&<2+!D9i JΔ}J~Zi[)=ן&u‘T^~!嗶gMg"PK%T|UIt_5*ؾP_+%VZkQj"O~I(OU͕u:6uw~'I:3VzP۷;ͺON˯rZgzc/]]|x#,n֑ 7lo_÷oWIGXKmqdߥ<ҫV~ۚz #׬WV|dh?Wnoif+hhd10R2|#0&XG9=ljP:A\p^Ib cz(hh  C`fc>`l=xށa lMFx 6^u^EX Fx#+MG`9, buz:n@gȏ[RJeH:,?쇭 [`3 +ؖdx ބa92/rV*X / 1X|r̄ fgdIp'\ ~p0·QН B #! Xm Ў;w}=5|_9|Sv'u<8:@{hm8$2 BF[&ro`| _9D_&1zx;l[b ,'a6XŊgfTa \1`e^.Ѱ΀B p @O'Ip p"hfބ40f0 9A8O4q\l[׸BϏꇔ=;=gzY^T*2i\-SATը%IZjZWQ5_=%T!P>uIKݩthyiᎄ<V1X|8ؤn<Gv\ DLipVBvnyp™PgA4 r yPDzl2 uk4߹{گU^#@mS[:zsYB=4Sּ}cnj1p1\BFH8AW!ЉBg t_i5NW% ҙ:H,56-6XlrXc(̇G^Ln#`8|8P\6@A^6(vt+@X TMiXիSkR}>WO.zC6Z^QZU?Rȓ<s8"ln yō콩p\0 p5\JD(2Ja\x>ک@8Nܐ ) I<"%B4=:"wYRoM:JwfFRv%u;nxnsCa}}ҞRXa_*zTUXI9⚊@ŶN L&gLv%^]8ɾ*0Nd&_YK h8߿ߪ OQP.o#g'L,,ev\Y벒2}eWf,+-sieeDV).hU++.(`&ؗ^fl+ѲVj UbTY%_:ޕpn8{l`}w}Q`}{w={='Pd- Ņ xI[ڲ徖qI#sKs]sZ-pM1S->ɪʚ$+=a%WJ*\|iҶii.w{{㖸%+SHHjS#Vc_K;WIONO95_UbR] |)/yD57%P71%_BN,Vi(r,̦=2xS?,-WT0> endobj 14 0 obj <>stream x+| endstream endobj 15 0 obj <>stream xS**T0T0Biy8# endstream endobj 16 0 obj <> endobj 17 0 obj <> endobj 18 0 obj <>stream x˖]9ꢫo@K 9dž44X<([?2#tMRed׌MYݺܮz+ߖ?}pllǽ)u~1|ۮWk!˗IzYVݢ\oͮ}Xm/를+/MXCWv""h|y/].߿*%ZW/ՋE!eEN^_G-77_/#9ϛ=}kL7PEo`HnAnH¬O;0 ʤS#@H\*; J17jֱ?W_6\OzW7KXn=ߦ#jTBJɠ\-H) OFbh3Oj歟jox?^ɺɘc馚 ҭof'yWd-:o zN+^d(hNykAO31$ȳ$I1V)#vQ ex~2u,rt/.a\v"7C}1.0n)mj?ZfᕘRQs\jTjmb5t$= p^m@WmTY-XPgZX"XClֱ2av2p1R%6] ϱEC, y:L5XYu<$}yiG{q~QT hfXmb:uuy *%go@:$eKE]O@~/棋tUBz;TrjWxĨ i^Ӂ~RVksma[9KyCx3D4F"Td(F(y &%QA| 8] fEMUjo<yDq"!Ɖ6g<VtT5-=7eZ3WDyCq[pReWz[etfx1e Qgo$`/,4=5@IgzlpM; <9VZ_y4 GEK'@Md<sk<2Ual#^1 >Rk]=|=߅v4>A1{_]nCu V'zg{;RZmaQOp")c)<݊JN㼈<2,^H"ζ!;Tmz$pHtsJRdv9IMgWUr ҘťB>J3zAW©R,Pi9'pRT{L8Vu5h84[AGQqlլc3Y4'}I*%FfKI%3NjAx}PXWQutϓ rtw040ZXJ4ghmpDw 2̲eݳc&`<6ӄdZ jmO0U˳}=@RMm}XӋZ9"r3Z岐jtqiLO cΊℱJAGpua] yv QL<Ag$fYb,}lټB:49By?Ip!'r K1  CgrXl!Gp'&sb6'>#:110) qkԴqDdPzZukh> D>6|> ~m<-Xz gV)j$͈쭽yU|"VLjdi x)ni|\R̊bpP1hz GQ*Z=Q' 53/x2Rd10Jı NvEd.CY)=}?pwOzM/>U|"Jf c!wꚼ#J,FՌfj-θ,k|!sN^P҈rCn' tƯ.)Mf)CcM,'=4T%L!ms;5ͭ++쵭c՝,>gӋr)ۦsA.H7([ Nбt7as/gibQ}oP>aPl͡z6GLo׀ʐ"CQe5"LĴpoV0s\m=)`h뫥l/jn##l=0TOo>{̙ =Q6v6 }9.h2nBСZؾGVB%>28#)@ө0}#ad_ݙ9!H5D(~GfNab1* G LØ?*׎u[q _{S  BN`hle۴1*q4> ArfW?@e@oQR鑟<`1;mr% Oe`<ڍruXe}Jh?RF ;:FQOT9[S\p cA6S^crK/ޱ&]! 9`ˊ`0b:WjYǺڎ>44r\,'L?>5`&!"ۅm63־`< QT_\$fx|XTdlHGy,; fV4@@ȃ_KLd͖ b?v^#j"qԐMp8]KM'*SEKO"u 1%,SX4tMVRFY"R\쬏-Ü"UDj1dzuMIF=dXWaiE&$ͮш5B;K06,X DXJOd>3rє,UtNphj?(Ώ$9r!'(x,}3uӠ~vrȯuNCbHξ#yNwwW.ډa+[%&{Vaԓa)0$|GŸX7*FΪ R{'}JF W[U}0 fo'`"U!.0 7kkg-֟:@ >#Oʉf-mۏߕnXڕx=1e3YbZT/ۏ03-Ovqt)YH|a3-_fVstN! *K:G`퐮4Y>ߢAdK2QCxhC@ܸŊKS ?A'pm -YL'yw!%]--L/-C!'~&|nUD,DPxl!Dk̷Z㺞Md{0 at\*F栅K7>'KT`0>SC>K?Ah}o0q<@gȍ#R[纒\Tym I:0|m0PMCP>VY"{a^Y&[mv{֮IjB7FFICk n9vwvk~&Y兑F]*8dĨᒉ)ADѯlH endstream endobj 19 0 obj <>/Font<>>> endobj 21 0 obj [/ICCBased 27 0 R] endobj 24 0 obj <> endobj 23 0 obj <> endobj 22 0 obj [/ICCBased 31 0 R] endobj 26 0 obj <> endobj 25 0 obj <> endobj 31 0 obj <>stream xWTS[@ W)#̀tDJ 6bH Ć.łeEE]l+kłŊe-tQPł W5rp矿,RH2v2+s|frh<W$e%&A )׿WBP^3_Pă\( @@h܄tr)Cl.kd`H2qKlnAHjb++E)!@ @xHC|_* q "?YT!/* qG05b(C%S _Kȱ8W3eBȓ=d gH!~.sRU+*N!6|I03yܘD!M fU*O$d9["'tA\!(R3raj4{@֗RrD(qB,C R`L2E2;˕E!H"J;A:P¿< ݀+Q.878ؐK r (2@"\-9W T|8g\"S{etrTRW0W!WڧNRZ%&8 GLHd>FIUGhb;aigӀ+Uu߉8!U (ZJޭj\fpJ$q&)-Vư\6EĻt`oU䋠 UzouIvw b}[aS9ح|NiU2}e=}h `oNR/DIws/yPeSfLIXɂ+W -2W( H(w%굤L|UҞ fj6()D{hQudT:lH ?W܍|y;8}2S> Dõ~f>O9!!?1oS,Rם@Ut ݅Cg |amqtMwGG|ǧ!"MeB+?Uɔa#D2iDh44S/T5th ƕeU!0ѽ`B&(s^s:s`GK aØrcC8Uźp5G$;#Nue!GQA$Q.`/^(-rr L bz¯q!xx  H$WR CO%M'UIuӰ^dc?Lry&y1y#y82yBQ\) "TPQvSQPz(o445444$;5j\x1,\MEfUD Rk ;ZZZZZIZ"Zkjz=Q[D{q[/h4#-EӖi'ihot:ΧϡWOu4utX:uJuu\u ֭mֽ;g穗WXo9^}~>_V 0;p|m z ɆN<* ; 􍼍ҍf12ƌ9b34aL4\1ym:4T`ZiǴ,,l!渹ytMGQ9b_-P d[---,ٖRu'-¬VY6Y>fa`1ČS h!['4r=wvv9vZٗAAơᵣcBCNNR]NwiΡӜk$?rK.Х+*rzٍ&qur/vaQq(QYj/mO}r^.^<kiF4{Mq> }Z}6emol)`lo}r;i`̶1m[B!!߇tڄrCkCمFXYO2:<0|V,Q>^mTnԮ{&x4):6zy %ǩ ̊9>~K,e:.fqw%@'aeDi?'j&{&%LIٙ*uliit3"2Vdt5~ 晢̦,JVzV] 'LX1$I3&l>Y<))I;sykxOaU>A`QNpΊܕ}Pa_.Z/z9u~B f$_rЪpFeB5-piXY]R4In)lW8+Qt> %.%JF0ɛZfS6{k֖쩳[Y0g.{yy~)g(9?c~s<ͮ z ſ}۱hu>T+W1/->wk$gIRߥI]_| +qcU媗>W]y ubMڸM-[~p}gؚ=,6,z#Ma6[n{74:Vo%o-p[3sd{׎wZ\ ݥշ{K?Fްe񞪽`b}z@O?m8hpi,i8$<Քt9%?o?lsёGGxq'Ni}rkNu=}Lԙmcg>xC|/4痃.6] ryWBq5ε 񝗯]yc⍮ķZz^yWn={=]]G#ܿoEY^}Q}OxDdw7>stream xwTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf endstream endobj 35 0 obj <> endobj 28 0 obj <> endobj 36 0 obj <>stream xz xU^Nu;B$@H$!0 83<\A|t xoA- R o~ .O/NCBrκBaκu J\r\rZ|^qN$c ՟kN;[S`1J[:7"kg&{#wp}$:} ÅS?&/n!9(}@xz\T<$9(񷮓 6t'瀜,>ࣞ?(,r E,Bٙ/L+aWPM^;(TO d~A N=)c6yDKzY%Xa' λDbE|½5LJ9Hdq0>&܄\xǁoA@E|G_uw{=@ އ6~._gI|>TE"DR(QP >$Erp y2r^C<<($Ѓ"Sn6Grekil [[+ Xokɶە+Ԯ:Q(khn0ygl}WWk=mޕRUGV~oTt\(C˦5MKk2G[iず#8Ix'~tEC[="ڎvrL4KQ%=^GWW`tp ^A)`vN0_+ڍi㹸/PTOd$:^FoU4G~N *jVS5:~Mk{9%=-F_GPO"UX=8OL|7^{a|_—]%PCu|k~:D Zz>NO8vUSI)-NR8ɍ@]hz N75t8 g<\ "+0܇Gt7RR)LZ NzKOm |I,aV1vf7͎egMl'{}{\{{WYv^± HVN4NG :H 7O"_`p(3KT~KM {i%\Ҁ_÷s9vcMF>2BՄUJϱ Ma\(oyZL"mPv[EU#xm6hSF=Xc+D)ɶ2{aᦩ hj9E·BnleRʼ]e)*%BHDj2o[ '=ʼGi<Ѯޚ eQv{cJEox=0;%yGB:nhv+ɵ57xF/J&yRM?o6\m^u[Im3*l0,`c?$d܃n6Q] 4G5 Rh-mچ~h )ɇLk @C))$-O'i  &s;&^hG{ꝓ䃫*>򲮉m!4:J[Pگ4[}jagi\i$!/n" Kf5*Lp8+}HYЇÍ>xЇJ`gIDtPHND;rH;qn"Ÿ{=@ `Q10N*^0‚ <~IU4LmvFyF :qF6)`zit9-3[ C41vި^u2xȣ+ġ "]}ޅaInwFBL[nOS8{ox3͖)3Q8N(G3 c y;~Ex"`[$SgpɝPxQt.K y0?Mxۉ2+& W “1A)dBpOSno@r`['Sg;;p0#(87 7 SXp(~vB~=I{QWA:"H=%=#ԭtoEݤnm5mEkdj.<σC9ġPAl(9x!@ G~r%/?ARΑj8fԀO(gZC%x2BmEA + <gʣi}h}k/7+yʵ*VD;|v,S,g84R)}pH4y_8YMa_ 2v`'i|L?,)ed<8agyh!Stm˨z; $Icp5P@[5 Aa7r\jjI?l0{9NSUzsJ%٨i`x;vLypyLYIǨߏ#)8Ǯbh0C;w z&`,"Ua^Vލ|t1[jaQ(,!M-JkT 1cwOzZ?pv9PT8hic]nf4q8G,4df9d㴸__g1i=q_8=^zQ H'03<8wAN^_Kq;m*AKČ:+ܼ;A@L2vfn?J%ꕉJr53v&k'@EEv@9;+Α 1JJ2>?Й3ozB?HbNwb27,eץXcOd%(5p)*G:i+Z%T Z.FR=%?[aE Zcaer?;[94C,"207>(CyϢ1QT1-izVLOC-vX~x gـ ~c) g@?Riq"Njsn:?u&AosY__ПIq]RÐVk\F+6L͘R&F{"i8I1mhS[-BvI5ṕhPVAP!1Xb  Q,wNeg!{3^>h0G~lW%T\T(nu1lODba.Oke 5ܞ1Ӕzb;Ƒ5v;ZOq[cw5/3 a VT嚉_{mcPehi64,̧OlmI\]ayL̜6+0:,,sy.9JmX:Ǹ*65; 8)! %D8[74 t=h -iKZb*v2x} $jPo, GU37 F)k+kȍ1bi7X8^K:oq[wC{J2!8Gpa}<=PQ2h^9  neZ#*MNr%rC~o8 8 eaxg-; i0;@*ٙdRq%IGHv*7IWh:f+|=d6P"0wCaJCM7 L:L"mK6QNpӒ#,R9D6hVK`UYP;tN-mF:ݷ6YptulU~ҳoJ߆ᜐE;b<m{\"pENB|$FoVc 4'Q.p>0b` VBz?!t; }'0olim t0gpϻZT"!^lM Tƫ\'VSXHLl:p!Yv=q2}ds~FEI"u#O4@=uWW5,drRWΚ_NmlK2%ɈbnfMkJ m*rQ)X]87;i829pbֆGjIc!-ѵscbף9Ѡ =Xji4W 1,`KŴIKo"dC m 5 Y)W;&1Z,l]Ћג@h!)N-݆_^ӳJ>>s GzϞ={I/>MҳS"rT $&#h NP% AW#[A( Cl/]ڊ=)eM͚}ⷓWN!ębg{ AF`aǜtx*<c&> Q٨4Jh=h+v#>ĚncMu_gJ-Op7 m( v53JƮVW&'Km h5b Ixurr^ecy} _ kux N2™짓 ?($Ӛ`j |ZݹrDp'+r$Al7Gȴ9RPU1>̞%-S}yS | t4W32汩eyTmw?vSK"ZvN:IBffs&`M87(7'-/,${|08PdA0=AoǖְW'ы^icWNG&ԃ0=SU!ѐgηvb!sLjY$# 6~@n ؀OOKHWai_Mϙ=-.q>5ƱlFDa[PZvp[OD>z|Hh0·ʅ ұ=ɧ|T?'H'w/Me1%7hː*(aq8E@=(vRC˦ 4>o&'\_:բ:zj:M6= CsćnHh_վl{%n]p<8_;b 64` ^o|QZ @h ]<K9QQQ٣sF#Ɨ~FbTcTyݣ Gooo{F;G*;,}j_N |4 endstream endobj 30 0 obj <> endobj 29 0 obj <>stream x]j0D= gc():EAk࿯zAz3gHJ` X gux%mU&*a[@mWF$\h '} kwD:rċAO>S/[F8<*Dc!'it4&U$j~O=?c endstream endobj 37 0 obj <>stream xX pT@cwy^ 1 a1$Ap&Y 4T`1b+Ќ-`oNFhUfTj}N(MiU V8Lfss~woD`uK+(kw&E$3[.VtՑ-Rvվvx|dok[~Hr3$tI⨤/}M˰?5u.wDHRdK^_v*fwG1@ `^*UBh>2?%o9,iʝbnkYx1|HR6$= eqhVFm&>"ngT+JHdeBkqp:vX[6J-6+X >ps>'ű,THܒ\NbtYX%t9gt9Mz./ Lz ΑxP/|@z8_:X\"r*H? =ٰp 3nIHIut ן,j.jMq\;ͭ& s9ߜcvo2g-,YZX,EpBMLv~*t+phV` eis?r Ɛb[hC1鬣ۃWnFW7=аb_D_ZHfzeZ5>'d8U"^qW3wžEjkP|J63]XZS\ @ xĝ`*H#&0FtdN\t#0l]؇VP`_ю Gd6x>8(fl?n:IăuwP Q8fvA>BӿgEB m0,s`+@ p%mqknwQQ,^{G޲-T;O~#Y'^&#oJ{P"G G n'6a+v~<9 sNaak`qN |P LexӸ/rn=0!w*m.曠J^P]6vBJhO Xp>.¥s\ ^|?ƿW5Iqݔo#Ÿ~nO)N$,=b)Tm ݣo{i]n|@ blJ={9xb/8 4˦8밞cޏ>."ϘM{MML.N&,2 LnIfZA\`A; l5s=| ^ (w^?[q~J땬jA~^n˩LvM ۍ7LJ8!-uƍMcMsnR&(~J + !M&SMfR䊫"DTJ=n٧1"qI}*AY45FG}>[W0$/_THak0/W"|Zi ǻ|V>f9A[y-JJ6px8G!@=mc[mqC^pPB,GZvnK+ GUF35ĴäU74-%p c 쉻H<&\UfU*quXSBޠ Xa(wmCHTx*,q6$7%0ip3 I^VLMn$a.mMQ "J3Oh+.Mt-k=0map1kF\ R|(:S9zhe-&WY`N-ar=?]Hj)ml&]0Ξ[ztWZC|$G}K~zwABVz))n7 #U 9*GF*2$9"` Z`Qd7 ΥyyhG4êHKT䮦ʩ ozD:m⁺6@7IxJ0iyj'fך"9CFW j:l a DZƒPYA/o z67'qYf0> endobj 38 0 obj <>stream x|wxE̼knnK/@!$hN@X!JQA Y . kŲ"˖EWw!B<>ޜ9o9s99NBԌ4dم{fŒq3xaB_"1'Ϝ2##tO~7N71q]$x s'xC䗧=9}3z?x͘9|j@2{,֙'u]~o# GHB"HKJ7b,=>I"(w>">|U?iG(Bj ;TuO;֎bCxzh@Oݥ`9f{mJv̷=Qlh%ކF?x!A`tw,ڍf51r\+8Y /y:v_y%y= ĩ=Q%nt:O;|ݎ\7wFtwb|~ІvΏE~o7+.b3܃9p.:oo8qW{{"4`hцv|HN/D6Dk o0ZCyapp+ !$` NԊjQ)Ў_8P⽨ IJȋ\;~G>C"+/@y12m:ZK\񾃉Cb^X2$"EVp;Zle⪊\OdžݭkoͥNwm 63NM*OK8l&WN T TNPSyϷLzʄƎHqZg&UN T78=n TG+o?96@S20 7kefwӇͦ/] xh+/ghr@_kdxkZ}+8X1qǑ;"\3rYȋP@i.ȝF:iFߘÔTVԂx 4mBg4w6L,jGЛh=ڏp dkps!1(GK:A)-CP1"7Fu';2x q .cیx;>LW GL%'[Tf=[[/G|PD/,{0"CϔN4Z;B?Vo It _a@߃6`ŵoœT>W|G#艕p2 }8Tf3i*sX#kfh5; .6Ws#fn%>k7_,VC@s\ǣ 8 k"^" bd6m݌h{G!htxd3ɖ#7z ZESp(H仜j1NV)s,C0J Tƶ@MMkVo\9Ǖĕ+WJ3}_+v¥Xʍ[ >x,YZ_׊vUqԔV71'N*UƂpѰC6hH{.3mKdBmq"m/ 8[J  $-ɤ"jB >9ӯ0V.\khHTn촊 Ctz][:|q]G[DOҎ֕VnWu=rPV.Nɔ Z\lUC/Rz4)xT[Ws9p>/]Vg [Z\E[oǨXׁvD/"oC^~UOe TF%\]oj[ K$"?I%5I¥P*>; IeY±zC%od $H'I7I \I%\pM%fW³c@&RJ8Oc*x@fo.huJxx%n*@7C?]lm1DJ:N"K8?ο_ipFMܣ(+'TkT/YxMfBbRvVdhG4Ec)ݴtbimֿؖˡ\Ŭvv..MK|㽎*.lL^ZLC#dVu VE,ۏ~"})}ǥ?^X<]nő߯A>P+Lj bjQf;(H URv{5ya4uV6~:b-蘒#\C>-3iYGKu#y?1 hE!RND=i$[`Jd[ {<T0ئsJ863>NǾe1!; dAڲ (k#wlXcP(fĩ~Z9*xW'-Ν` ,u~̺M`\hV̺U9?s CsHvNw2xF^ȩ #r!1DSUm`#ĮtEbq&~N ~_8Uh H MVKo$iԲ&j}O˪y~M_J(.܂|=vHK} 6rmn3ب1oI ss3 !IYy7F}3aWݷB1g]_u:b $K +B .&xDˈv"B) $݂ҕRI? 7$?rɥH|˕,,BWa?P(P[~Y:_l7e-7Mj qb?OZ^5߿c뙇fmxO3W]s/6̫ s{7Zr-t拣 /)VWGޢZ# 2Ik0 $( UiWCsmIJn^(r܍|T8 ZQ^|]ņitPB _a b<09s AlNHD;TOWJEJYb`f'E۶m>ܰ4k r)t܌!SOaUE?})Eiv^}Czԛ (w~A0weڹ4.bFn}cCQ% p8_uR41 pJ1 %sXE0Gq}L"P2pbl%~JiWkWki|VeYU2K2:*ꋳdm{ʞ_i8OvTiƱ p3̬m/ѧ$de|3J?.ȳF %%l@hf~_H=q$kEhK*mq ݽ@+Fwfq_#8xxa?s+pY|o7mVxcgrH.G)rvoZB]͇t7rYƐ6 ,\1rA\qŘҦEIHD fjq$Rz~0"+HFz<^Y<#^S>7s±E GpuZ:tm$I]إ'm5~W; &h.o0\QI"cá jv׽,^G[As8ԉZ $ * &e;J-~6*7 IPHogps}iYe9|wCëg^?@]=aOrN7?\i1R/9{_3L?Ր{/ޒIWCk9vwڀxwgAd)E!D)9+*dW5MT& PJqHTHygɵgYX|;J?*,(ZxtP2`c$+;8{N:?ffFTKVv~j!pYPY*A0+4xA:ޠ 9  ,L}013 'K{Gt~Ȕ~=u3a~C&XHl!X# &/v0;Xq1إp` DNG0wBAHa'x(\AùH9:\ks%fH0\h- :?հ_Β+kңkQ#'PH@ e|q$Td̓g;oĤI֎sTCz qqF ?q7hωڑb/400<^=2=Hp  /h-LNT#*a%ˀ(L4* zO!K?Ґj# H^>%ik׌g9! YabB4㚹bisė n>u[7g|dlw`/(-DP@-KQ%ڴ 6j$3Jmd%úlLYYi&흦&JOIF8rA}̲nOd!01@1!!Pk%[HދD" (}Fq44Ұ݆34pP3,D!\plt:9ʙhGQ(S8$:W ELTɼp;/&q!ׄ+380p3_~Grn?ߺyt;oZzO_laH->hZ_mrwzMMe<>~z/;+d~/~e_+ ӣ rU.ҠⳗA._GxyYI玵\;Iϩ?IWJJc+tGoX,&EPnmU>1 2X'27s^LZ-^ڟ]mڶ}cfV_;-mVIL1Uw)l#e40 ( ~p(TXh^[|&XRJFďn $"o}'a͘)އ?}4ȃWP<hUPhكo̝1>g8nkV?rg5͵}jz!բ(|ǎl\;3xƕ5Omw :-55] T͗b5~bsF|æ wV=hf,sIhoW=; m+ ]mȽ4L ѼXnZ;J䂢$uHt*.Ә *{ol~ `7R(T6$NBHC@wU] YiOwk/ھcx>){ҕo>w^:)HWP3<⢻:`c$3$)ĨTĜƯ1+>~dP֟6;DΟN)wۢ ];]` AKRٕjA 'Ü#)P=C.{qy@^Dj2 'kK mcy/eQgұ:L !rǭ !2kCX 8pD^itn]\jZYA}eٟX=,[XʓgX[Ĥ탢7ܣ-۴_5g؂[;UEol]#N̳ K,4\ ͭz*ip!rΓXn'-ޠV`HzD{dٯ,NX$ t7:qeZځ *Ûa}:XwEMbuU|_ϕkkvAG*a.x]-bbEXXޑvة՞T&ÔQ]ip+2LdZ23#[ k.{V rG1Հoa`遈ãҧu'B$z֏jMНag7]s:rh`8R\X )z0HT7&/GL?ki}|;b 6-zQ#⹟R\w߉[ӥsly@rl:pڑ 48S~qe!{K@ԦXX:*X06抢QCAZ*6GhAM>ztQ*Ř.rʓ̑Dܡ,iz3{r| C?Jm*A CA fI% @o[ǚV2yAӖz]ŨNXOpo 0+?- ˹YVI?۷IiA/v7!QD$8j`exS [ {ʖJQIVѪ&0H:T:֠muk睮 cTFQX"Q;1ApknT oOΡu2wi%dzְ^>3G瞧!Gtml֦[ST5Br!kv#Gg|my1`g讻1Ci9gRMm*CJU8\8#ٛGbJD5D(j)``]d=rg/Ee8NaOz5YSoCeK`$cX&q .qn]<#~~I[6A6n&$S6֎-u͆ p&l $+8 &ua$#F %䄢)%KQ%/f: IL <~ yƥq5pc'jFAhVw;$"\z-6 IR%kIHQ&')ӕ!g[eq"bC ,`6&Eߥm(<~< >@^:r2RޗCs6/]Ҷ76߱_?R*̆;=Q],F.VC}ha,Vc;].>"w'~̽xz^x񘝭6>R_fVï0p^N=5 3!M!SͲZQG Bp+ES v\ $vQaFw5֖ѵOC;{:nZ0 ̎o2/yHw#EMMM|$%.WS#SF'L -P/,6 J72qlV V͜aʌ$Z$dM3^sܜZDY,f}#!!qha]_δgST&bhs BiLg8gFG 5яT( pi/)ُZVq(PCѻuLDƉYRrbpaÁȸ<,`Gw o`Ůyd-s>9=\VF;Q>Ͽ9-CxQnL?9^^3OnXUJ|w>F~y Qp &Sy\qY,Z U0-NȬ5'1^0,|خ(E'xi.~A^l+cP>ucwwoȜ‹G?7Zz]xrj:A͝_1ݢ;zΘ(F)c>qZ%5JlM TF*Gie߽[dCwm@>1a #("G/W@)A[ċkD{S}Ro{bJ2d]r| @)42S n'ED51dpؕi '+0r3 `C 3+`Ã7ox %QpeZL%q oO⋮_?¡lCnnZ!| Fo[?r.  ae=844vlb aػPRc_lq5Gݏ*quryM8+3RTY^؍>R Uf˷& iݢ6tM.zg͚^9) ÷ν'm٣sTzD vzsUh~ Eʧq0Rd<&#ۋ%Dw{8hH{Hwt/`x~F,N;c?[e^aichP 3L1զMM捖]hEWglGs;:o[g3[-˘ժ$N Nj/^bԀ^ym=+qtEB,3 VØ(ິ;h&BɞEp1 E/.`Ѓ˷6o E=Y,W+yج)cҟ_&soOa?@gӆņm>|0QIeEdNXa~Sa/d{~a1݅?m:kPL6P fM8+p~mG?bn)zDm*|wSаn3]ae8'aA?aF0oy>QB$3}/>K #>umOT*Q?S[41 {m?FQգ?@qx3^XCBC56fIsN'_!\h6PP PP#|@v0D Ph> M@ځ}t {d5Z hP;.}d5Z hP{gׇ G{=x|v>߃_[z=x|e_݃Cpzk{{N7?[~D~d~T~t???/ۉmrSz==z{3zQwggg7aT7>UL%'~ endstream endobj 34 0 obj <> endobj 33 0 obj <>stream x]j0D= gc():EAk࿯zAz3gHJ` X gux%mU&*a[@mWF$\h '} kwD:rċAO>S/[F8<*Dc!'it4&U$j~O=?c endstream endobj 39 0 obj <>stream xX{pTݐPIX^6A@(,ݐ  I6&1 Tp;,HU*8*}X" 7P12:*h}(w&+a*?ssws{g(T2J5Hw#dnsoB"h C?-iIkmp$mv䔶ےv1HGx[m]ۆƧ`Dq=S%quv B ^42QV6E9)akҒ/x:#m8K[`QC\7jP^ZR2I1݃(Hl;m@݆ g{m\Л.)(1k{XyI;rc)m({ZHa#HTu*aP7j UHLbdW>-/S>.7PN3ayR\+OnRNJ!rթl >ޤXBJW܊1C e+ʌnzG`)h4zY$.e6B]٨'Aپgr*WS4sn.,lwFuអOQ)*( {=;82c`HSl'!Z9l`O)d-'Cpca~h6Kp_uثH\@up'9ZH:۰֫{9e͚U[؊ Kr21t\1]tg=BQ_II }k(jXcMzT]75qZԯwh~hp+jX<ހ|Vk[ju3wddcwcfk1b:i5lbYtwsLR1F . ?25nf=l-x;cVy7ࡈTZ ӳ/}.8LG|μ7S-fg^_ĜN2*Y=gB\ ?n> ҭRB!?`K}.!LJapH8-,\YnIk\:7?d36[h;ߢ3)<< 1Lx*u{F貧&aDZNgJ!?SSk> ylă|S{Ega?,=uSkk)lS1u5&Kk Jelg`V~knDov?ƇQV G5jF{E񚖸Za3IK" xeKPh6ACcH5$M+T̯6?OCXl߁> !<7;0ObįMwƠ8%mѥ )7Xm!4wn X!u; gxF 7ZhgX ϼB  óGpE sgsG0< {Sr>z-}W0Á Ws3cz5gxa 7@B+0xT /I!p=0/ 7| /p^ ˁv+OFppT RHG0CR {t]r?W]D9ޔl g|@E;M(tn"L/j4ΠrtH;@+%'Г 9,wVOi|W* i|#ú([/$r .-vF{ڛ#KFy/$s⎋d endstream endobj 40 0 obj (Untitled) endobj 41 0 obj (Mac OS X 10.9.5 Quartz PDFContext) endobj 42 0 obj (Ruben Verborgh) endobj 43 0 obj () endobj 44 0 obj (Pages) endobj 45 0 obj (D:20150609150023Z00'00') endobj 46 0 obj () endobj 47 0 obj [()] endobj 20 0 obj <>/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]>>/MediaBox[0 0 595 842]/Rotate 0>> endobj xref 0 48 0000000000 65535 f 0000000015 00000 n 0000001017 00000 n 0000268801 00000 n 0000268889 00000 n 0000269497 00000 n 0000270113 00000 n 0000270594 00000 n 0000270783 00000 n 0000270963 00000 n 0000271160 00000 n 0000293954 00000 n 0000319537 00000 n 0000341208 00000 n 0000341505 00000 n 0000341582 00000 n 0000341685 00000 n 0000341785 00000 n 0000341867 00000 n 0000346091 00000 n 0000382293 00000 n 0000346221 00000 n 0000346808 00000 n 0000346653 00000 n 0000346256 00000 n 0000347501 00000 n 0000346843 00000 n 0000351062 00000 n 0000353814 00000 n 0000361988 00000 n 0000361749 00000 n 0000347651 00000 n 0000365130 00000 n 0000378992 00000 n 0000378760 00000 n 0000353767 00000 n 0000354054 00000 n 0000362263 00000 n 0000365363 00000 n 0000379267 00000 n 0000382056 00000 n 0000382083 00000 n 0000382135 00000 n 0000382168 00000 n 0000382187 00000 n 0000382211 00000 n 0000382253 00000 n 0000382272 00000 n trailer <<0aabe0d4926f56482c328dc2015852f7>]/Info 13 0 R/Size 48>> %iText-5.3.4 startxref 382474 %%EOF 13 0 obj <> endobj 35 0 obj <> endobj 48 0 obj <>stream application/pdf Ruben Verborgh Untitled 2015-06-09T15:00:23Z Pages 2016-01-12T21:41:24+01:00 2016-01-12T21:41:24+01:00 Mac OS X 10.9.5 Quartz PDFContext; modified using iText® 5.3.4 ©2000-2012 1T3XT BVBA (AGPL-version) uuid:7630f5dc-e966-6643-95bc-fcb09986b27b uuid:ebb481cd-2050-964d-84b1-70d686e33dec endstream endobj xref 0 1 0000000000 65535 f 13 1 0000383599 00000 n 35 1 0000383890 00000 n 48 1 0000383953 00000 n trailer <]/Prev 382474>> startxref 387896 %%EOF test.txt100644000765000024 613362073757 21252 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t/data2/000/000/002test2 003000755000765000024 013362073757 17457 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t/data2/000/000test.txt100644000765000024 613362073757 21253 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t/data2/000/000/003test3 FileBag000755000765000024 013362073757 20714 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/CatmanduIndex.pm100644000765000024 243113362073757 22461 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/FileBagpackage Catmandu::FileBag::Index; our $VERSION = '1.13'; use Catmandu::Sane; use Moo::Role; use IO::String; use utf8; use Catmandu::Util qw(:check); use namespace::clean; sub files { my ($self, $id) = @_; return $self->store->bag($id); } 1; __END__ =pod =head1 NAME Catmandu::FileBag::Index - Flag a Bag as a FileStore Index =head1 SYNOPSIS use Catmandu; my $store = Catmandu->store('Simple' , root => 't/data'); # List all containers $store->bag->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $store->bag->add({ _id => '1234' }); # Get the v my $files = $store->bag->files('1234'); # Add a file to the files $files->upload(IO::File->new('stream(IO::File->new('>foobar.txt'), 'foobar.txt'); # Delete a file $files->delete('foobar.txt'); # Delete a folder $store->bag->delete('1234'); =head1 DESCRIPTION Each L is a L and inherits all its methods. =head1 METHODS =head2 files($id) Return the L for this L containing all the files =head1 SEE ALSO L , L =cut Catmandu-Store-File-Multi.t100644000765000024 462113362073757 22507 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use Catmandu::Store::File::Simple; use Catmandu::Store::Hash; use Path::Tiny; use utf8; my $pkg; BEGIN { $pkg = 'Catmandu::Store::File::Multi'; use_ok $pkg; } require_ok $pkg; path("t/tmp/multi/a")->mkpath; path("t/tmp/multi/b")->mkpath; note("Simple stores"); { my $stores = [ Catmandu::Store::File::Simple->new( root => 't/tmp/multi/a', keysize => 9 ), Catmandu::Store::File::Simple->new( root => 't/tmp/multi/b', keysize => 9 ), ]; my $store = $pkg->new(stores => $stores); my $index = $store->bag; ok $store , 'got a store'; ok $index , 'got an index'; note("...exists"); ok !$index->exists('6012'); note("...add"); ok $index->add({_id => 6012}), 'adding bag `6012`'; ok -d "t/tmp/multi/a/000/006/012"; ok -d "t/tmp/multi/b/000/006/012"; note("...bag"); my $bag = $store->bag->files('6012'); ok $bag , 'got bag(6012)'; note("...upload"); ok $bag->upload(IO::File->new('t/data2/000/000/001/test.txt'), 'test1.txt'); ok -f 't/tmp/multi/a/000/006/012/test1.txt', 'test1.txt exists (1)'; ok -f 't/tmp/multi/b/000/006/012/test1.txt', 'test1.txt exists (2)'; note("...list"); my $array = [sort @{$bag->map(sub {shift->{_id}})->to_array}]; ok $array , 'list got a response'; is_deeply $array , [qw(test1.txt)], 'got correct response'; note("...exists"); ok $bag->exists("test1.txt"), "exists(test1.txt)"; note("...get"); my $file = $bag->get("test1.txt"); ok $file; note("...stream"); my $str = $bag->as_string_utf8($file); ok $str , 'can stream the data'; is $str , "钱唐湖春行\n", 'got the correct data'; note("...delete_all (bag)"); lives_ok {$bag->delete_all()} 'delete_all'; $array = $bag->to_array; is_deeply $array , [], 'got correct response'; ok !-f 't/tmp/multi/a/000/006/012/test1.txt', 'test1.txt doesnt exists (1)'; ok !-f 't/tmp/multi/b/000/006/012/test1.txt', 'test1.txt doesnt exists (2)'; note("...delete_all (index)"); lives_ok {$index->delete_all()} 'delete_all'; $array = $index->to_array; is_deeply $array , [], 'got correct response'; } path("t/tmp/multi/a")->remove_tree; path("t/tmp/multi/b")->remove_tree; done_testing; DirectoryIndex.pm100644000765000024 1064213362073757 23100 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandupackage Catmandu::DirectoryIndex; use Catmandu::Sane; our $VERSION = '1.13'; use Moo::Role; use Cwd; use Catmandu::Util qw(check_string is_string); use namespace::clean; with "Catmandu::Iterable"; has base_dir => ( is => "ro", isa => sub {check_string($_[0]);}, required => 1, coerce => sub { is_string($_[0]) ? Cwd::abs_path($_[0]) : $_[0]; } ); requires "get"; requires "add"; requires "delete"; requires "delete_all"; 1; __END__ =pod =head1 NAME Catmandu::DirectoryIndex - A base role to store relations between id's and directories =head1 SYNOPSIS package MyDirectory; use Moo; use File::Spec; use File:Basename; use Path::Tiny qw(path); with "Catmandu::DirectoryIndex"; # translate id to directory sub _to_path { my ( $self, $id ) = @_; File::Spec->catdir( $self->base_dir(), $id ); } sub get { my ( $self, $id ) = @_; my $path = $self->_to_path( $id ); is_string( $path ) && -d $path ? { _id => $id, _path => $path } : undef; } sub add { my ( $self, $id ) = @_; my $path = $self->_to_path( $id ); path( $path )->mkpath unless -d $path; { _id => $id, _path => $path }; } sub delete { my ( $self, $id ) = @_; my $path = $self->_to_path( $id ); if ( is_string( $path ) && -d $path ) { path( $path )->remove_tree(); } } sub delete_all { path( $_[0]->base_dir )->remove_tree({ keep_root => 1 }); } # return a generator that returns list of records, that maps _id and _path sub generator { my $self = $_[0]; return sub { state $records; if ( !defined( $records ) ) { $records = []; opendir my $dh, $self->base_dir() or die($!); while( my $entry = readdir( $dh ) ){ if ( -d $entry ) { push @$records, { _id => $entry, _path => File::Spec->catfile( $self->base_dir, $entry ) }; } } closedir $dh; } shift( @$records ); }; } package main; my $p = MyDirectory->new( base_dir => "/tmp" ); Catmandu->store->bag->each(sub { my $r = $_[0]; my $mapping = $p->get( $r->{_id} ) || $p->add( $r->{_id} ); say $id . " => " . $mapping->{path}; }); =head1 CLASS METHODS AVAILABLE =head2 new( base_dir => $base_dir ) =over =item base_dir The base directory where the files are stored. Required =back =head1 METHODS AVAILABLE =over =item base_dir =back =head1 METHODS TO IMPLEMENT Implementors must implement these methods =over =item add( $id ) : $mapping * Accepts $id as string * Translates $id to directory path * Creates directory if necessary * Returns HASH with keys C<_id> and C<_path> This method should throw an L when it detects an invalid id. It should either return the mapping or throw an error. =item get( $id ) : $mapping * Accepts $id as string * Translates $id to directory path * Returns HASH with keys C<_id> and C<_path>, if a path exists for $id This method should throw an L when it detects an invalid id. Difference with method "add": * no directory created * no mapping returned if no existing directory could be found =item delete ( $id ) * Accepts id as string * Translates id to directory * Removes directory if it exists * Do other internal cleanup actions if any required This method should throw an L when at failure. =item delete_all() * Deletes files/directories in base_dir. Please keep the base_dir. * Do other internal cleanup actions if any required This method should throw an L when at failure. =item generator() Inherited requirement from L: * return function reference * every call to this function must return the next directory entry in the index as a HASH with keys C<_id> and C =back =head1 INHERITED METHODS This Catmandu::DirectoryIndex inherits: =over 3 =item L So all functions from L are available to these objects. =back =head1 SEE ALSO L , L , L , L =cut Plugin000755000765000024 013362073757 20661 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/CatmanduSideCar.pm100644000765000024 1514613362073757 22720 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Pluginpackage Catmandu::Plugin::SideCar; use Catmandu::Sane; our $VERSION = '1.09'; use Catmandu::Util qw(:is); use Hash::Merge::Simple 'merge'; use Moo::Role; use Package::Stash; use Carp; use namespace::clean; has sidecar => ( is => 'ro', coerce => sub { my $store = $_[0]; if (is_string($store)) { Catmandu->store($store); } elsif (is_hash_ref($store)) { my $package = $store->{package}; my $options = $store->{options} // +{}; Catmandu->store($package, %$options); } else { $store; } } ); has sidecar_bag => (is => 'ro', default => sub {'data'}); sub BUILD { my ($self) = @_; my $sidecar = $self->sidecar->bag($self->sidecar_bag); # Insert a Catmandu::FileStore 'files' method into Catmandu::Store-s unless ($self->can('files')) { my $stash = Package::Stash->new(ref $self); $stash->add_symbol( '&files' => sub { my ($self, $id) = @_; return $sidecar->files($id); } ); } } around get => sub { my ($orig, $self, @args) = @_; my $orig_item = $self->$orig(@args); my $bag_name = $self->sidecar_bag; my $bag = $self->sidecar->bag($bag_name); my $sidecar_item = $bag ? $bag->get(@args) : {}; return unless $sidecar_item || $orig_item; merge $sidecar_item , $orig_item // +{}; }; around add => sub { my ($orig, $self, @args) = @_; my $orig_item = $self->$orig(@args); my $bag_name = $self->sidecar_bag; my $bag = $self->sidecar->bag($bag_name); my $sidecar_item = $bag ? $bag->add(@args) : {}; return unless $sidecar_item || $orig_item; merge $sidecar_item , $orig_item // +{}; }; around delete => sub { my ($orig, $self, @args) = @_; $self->$orig(@args); my $bag_name = $self->sidecar_bag; my $bag = $self->sidecar->bag($bag_name); $bag->delete(@args) if $bag; }; around delete_all => sub { my ($orig, $self, @args) = @_; $self->$orig(@args); my $result = {}; my $bag_name = $self->sidecar_bag; my $bag = $self->sidecar->bag($bag_name); $bag->delete_all(@args) if $bag; }; around drop => sub { my ($orig, $self, @args) = @_; $self->$orig(@args); my $result = {}; my $bag_name = $self->sidecar_bag; my $bag = $self->sidecar->bag($bag_name); $bag->drop(@args) if $bag; }; around commit => sub { my ($orig, $self, @args) = @_; $self->$orig(@args); my $result = {}; my $bag_name = $self->sidecar_bag; my $bag = $self->sidecar->bag($bag_name); $bag->commit(@args) if $bag; }; 1; __END__ =pod =head1 NAME Catmandu::Plugin::SideCar - Automatically update a parallel Catmandu::Store with metadata =head1 SYNOPSIS # Using the command line $ cat catmandu.yml --- store: files: package: File::Simple options: root: /data/test123 bags: index: plugins: - SideCar sidecar: package: ElasticSearch options: client: '1_0::Direct' index_name: catmandu ... # Add files to the FileStore in bag 1234 $ catmandu stream /tmp/test.txt to files --bag 1234 --id test.txt # Add metadata to the FileStore for bag 1234 $ cat metadata.yml --- _id: 1234 colors: - red - green - blue name: test ... $ catmandu import YAML to files < metadata.yml # Export the metadata again from the FileStore $ catmandu export files to YAML --- _id: 1234 colors: - red - green - blue name: test ... # Or in your Perl program my $store = Catmandu->store('File::Simple', root => 'data/test123' bags => { index => { plugins => [qw(SideCar)], sidecar => { package => "ElasticSearch", options => { client => '1_0::Direct', index_name => 'catmandu', } } } }); my $index = $store->index; $index->add({ _id => '1234' , colors => [qw(red green blue)] , name => 'test'}); my $files = $index->files('1234'); $files->upload(IO::File->new('get('text.txt'); $files->steam(IO::File->new('>/tmp/test.txt'),$file); =head1 DESCRIPTION The Catmandu::Plugin::SideCar can be used to combine L-s , L-s (and L , L) as one access point. Every get,add,delete,drop and commit action in the store will be first executed in the original store and re-executed in the SideCar store. =head1 COMBINING A FILESTORE WITH A STORE To add metadata to a L a SideCar needs to be added to the C bag of the FileStore: package: File::Simple options: root: /data/test123 bags: index: plugins: - SideCar sidecar: package: ElasticSearch options: client: '1_0::Direct' index_name: catmandu sidecar_bag: data =head1 COMBINING A STORE WITH A FILESTORE To add files to a L a SideCar needs to be added to the bag containing the metadata (by default C): package: ElasticSearch options: client: '1_0::Direct' index_name: catmandu bags: data: plugins: - SideCar sidecar: package: File::Simple options: root: /data/test123 uuid: 1 sidecar_bag: index Notice that we added for the L the requires C options because the L is using UUIDs as default identifiers. =head1 RESTRICTIONS Some L-s may set restrictions on the C<_id>-s that can be used in records. =head1 CONFIGURATION =over =item sidecar STRING =item sidecar HASH =item sidecar Catmandu::Store | Catmandu::FileStore The pointer to a configured Catmandu::Store or Catmandu::FileStore. =item sidecar_bag The SideCar L into which to store the data (default 'bag'). =back =head1 SEE ALSO L, L, L =cut Catmandu-Store-File-Memory.t100644000765000024 105213362073757 22660 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; my $pkg; BEGIN { $pkg = 'Catmandu::Store::File::Memory'; use_ok $pkg; } require_ok $pkg; my $store = $pkg->new; ok $store , 'got a store'; my $bags = $store->bag(); ok $bags , 'store->bag()'; isa_ok $bags , 'Catmandu::Store::File::Memory::Index'; ok $bags , 'create memory store'; ok $bags->add({_id => '1234'}), 'adding `1234` bag'; ok !$store->bag('1235'), 'bag(1235) doesnt exist'; lives_ok {$store->bag('1234')} 'bag(1234) exists'; done_testing; Catmandu-Store-File-Simple.t100644000765000024 411013362073757 22637 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use Cwd; use File::Spec; use File::Temp; my $pkg; BEGIN { $pkg = 'Catmandu::Store::File::Simple'; use_ok $pkg; } require_ok $pkg; dies_ok {$pkg->new} 'dies ok on not enough parameters'; my $t = File::Temp->newdir(EXLOCK => 0, UNLINK => 1); my $dir = Cwd::abs_path($t->dirname); my $store = $pkg->new(root => $dir, keysize => 9); ok $store , 'got a store'; my $bags = $store->bag(); ok $bags , 'store->bag()'; isa_ok $bags , 'Catmandu::Store::File::Simple::Index'; my $expected_path = File::Spec->catdir( $dir, "000", "001", "234" ); is_deeply $store->directory_index->add('1234'), { _id => "000001234", _path => $expected_path }, 'directory_index->add(1234)'; is_deeply $store->directory_index->add('0001234'), { _id => "000001234", _path => $expected_path }, 'directory_index->add(0001234)'; lives_ok sub { $store->directory_index->delete('000001234') }, 'directory_index->delete(000001234)'; dies_ok sub { $store->directory_index->add('00000001234'); }, 'directory_index->add(00000001234) must die'; ok !$store->bag('1235'), 'bag(1235) doesnt exist'; lives_ok {$store->bag('1')} 'bag(1) exists'; dies_ok sub { $pkg->new(root => $dir, keysize => 13); }, 'dies on wrong keysize'; lives_ok sub { $pkg->new(root => $dir, keysize => 12); }, 'keysize ok'; #delete all lives_ok(sub { $store->index->delete_all(); }, "delete_all" ); is $store->index->count, 0; #UUID $store = $pkg->new( root => $dir, uuid => 1 ); $expected_path = File::Spec->catdir( $dir, "018","970","A2-","B1E","8-1","1DF","-A2","E0-","A70","579","F64","438" ); is_deeply $store->directory_index->add("018970A2-B1E8-11DF-A2E0-A70579F64438"), { _id => "018970A2-B1E8-11DF-A2E0-A70579F64438", _path => $expected_path }, "index->add(018970A2-B1E8-11DF-A2E0-A70579F64438)"; my $uuid_records = $store->index->to_array(); #same directory_index as above $store = $pkg->new( root => $dir, directory_index_package => "UUID", directory_index_options => +{} ); is_deeply $store->index->to_array, $uuid_records; done_testing; Catmandu-DirectoryIndex-Map.t100644000765000024 322313362073757 23112 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use File::Temp; use File::Spec; use Cwd; use Path::Tiny; my $pkg; BEGIN { $pkg = "Catmandu::DirectoryIndex::Map"; use_ok $pkg; } require_ok $pkg; require_ok "Catmandu::Store::Hash"; my $t = File::Temp->newdir(EXLOCK => 0, UNLINK => 1); my $dir = Cwd::abs_path($t->dirname); $dir =~ s/\//\\/go if $^O eq "MSWin32"; ok( $pkg->new(base_dir => $dir, store_name => "Hash", bag_name => "data") ->bag()->does("Catmandu::Bag"), "bag must be Catmandu::Bag (1)" ); ok( $pkg->new(base_dir => $dir, bag => Catmandu::Store::Hash->new()->bag()) ->bag()->does("Catmandu::Bag"), "bag must be Catmandu::Bag (2)" ); my $p; lives_ok( sub { $p = $pkg->new( base_dir => $dir, store_name => "Hash", bag_name => "data" ); } ); my $a; lives_ok( sub { $a = $p->add("a"); } ); lives_ok( sub { $b = $p->add("/a and b/"); } ); my @a_parts = File::Spec->splitdir( $a->{_path} ); ok( ref($a) eq "HASH" && $a->{_id} eq "a" && index($a->{_path}, $dir) == 0 && $a_parts[-1] eq "a"); my @b_parts = File::Spec->splitdir( $b->{_path} ); ok( ref($b) eq "HASH" && $b->{_id} eq "/a and b/" && index($b->{_path}, $dir) == 0 && $b_parts[-1] eq "%2Fa%20and%20b%2F"); is_deeply $p->get("a"), $a; is_deeply $p->get("/a and b/"), $b; is_deeply $p->to_array, [ $a, $b ]; lives_ok( sub { $p->delete("a"); }); is_deeply $p->to_array, [ $b ]; lives_ok( sub { $p->delete_all; } ); is_deeply $p->to_array, []; done_testing; File000755000765000024 013362073757 21376 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/StoreMulti.pm100644000765000024 1005213362073757 23204 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/Filepackage Catmandu::Store::File::Multi; use Catmandu::Sane; our $VERSION = '1.13'; use Catmandu::Util qw(:is); use Hash::Util::FieldHash qw(fieldhash); use Catmandu::Store::Multi::Bag; use Moo; use namespace::clean; with 'Catmandu::FileStore'; with 'Catmandu::Droppable'; has stores => ( is => 'ro', required => 1, default => sub {[]}, coerce => sub { my $stores = $_[0]; return [ map { if (is_string($_)) { Catmandu->store($_); } else { $_; } } @$stores ]; }, ); sub drop { my ($self) = @_; for my $store (@{$self->stores}) { $store->drop if $store->does('Catmandu::Droppable'); } } 1; __END__ =pod =head1 NAME Catmandu::Store::File::Multi - A store that adds files to multiple stores =head1 SYNOPSIS # On the Command line # Configure the File::Multi store with a catmandu.yml file $ cat catmandu.yml --- store: files1: package: File::Simple options: root: /data1/files files1: package: File::Simple options: root: /data1/files_copy multi: package: File::Multi options: stores: - files1 - files2 ... # List all the folder in the multi store as YAML $ catmandu export multi to YAML # Add a file to the multi store with ID 7890 and stored name data.dat $ catmandu stream /tmp/data.dat to multi --bag 7890 --id data.dat # Download a file from the multi store $ catmandu stream multi --bag 7890 --id data.dat # In Perl use Catmandu; my $store = Catmandu->store('File::Multi' , stores [ Catmandu->store('Simple', root => '/data1/files') , Catmandu->store('Simple', root => '/data1/files_copy') , ]); my $index = $store->index; $store->index->each(sub { my $item = shift; printf "%s\n" , $item->{_id}; }); # Add a folder to the multi store my $item = $store->add({ _id => '1234'); # Retrieve the folder bag my $files = $store->files(1234); # Listing of all files $files->each(sub { my $file = shift; my $name = $file->_id; my $size = $file->size; my $content_type = $file->content_type; my $created = $file->created; my $modified = $file->modified; $file->stream(IO::File->new(">/tmp/$name"), file); }); # Add a new file $files->upload(IO::File->new("get('data.dat'); # Stream the file to an IO::Handle $container->stream(IO::File->new(">/tmp/data.dat"),$file); # This will delete the folder and files $index->delete('1234'); =head1 DESCRIPTION The L is a combination of many L-s as one access point. The Multi store inherits all the methods from L. By default, the Multi store tries to update records in all configured backend stores. Importing, exporting, delete and drop will be executed against all backend stores when possible. =head1 METHODS =head2 new(stores => [...]) Create a new Catmandu::Store::File::Multi. The C configuration parameter contains an array of references to L-s based on their name in a configuration file or instances. =head1 INHERITED METHODS This Catmandu::FileStore implements: =over 3 =item L =item L =back The index Catmandu::Bag in this Catmandu::Store implements: =over 3 =item L =item L =item L =back The file Catmandu::Bag in this Catmandu::Store implements: =over 3 =item L =item L =item L =back =head1 SEE ALSO L, L, L , L =cut Catmandu-DirectoryIndex-UUID.t100644000765000024 442613362073757 23151 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use File::Temp; use File::Spec; use Cwd; use Path::Tiny; my $pkg; BEGIN { $pkg = 'Catmandu::DirectoryIndex::UUID'; use_ok $pkg; } require_ok $pkg; my $t = File::Temp->newdir(EXLOCK => 0, UNLINK => 1); my $dir = Cwd::abs_path($t->dirname); my $p; lives_ok( sub { $p = $pkg->new(base_dir => $dir); } ); dies_ok( sub { $p->add("test"); }, "ids must be valid UUID's" ); lives_ok( sub { $p->add("11979D40-F504-11E7-AD0C-1F86AB14EC2F"); }, "valid UUID added" ); lives_ok( sub { $p->add(lc("11979D40-F504-11E7-AD0C-1F86AB14EC2F")); }, "UUID's are normalized to uppercase" ); is_deeply( $p->get("11979D40-F504-11E7-AD0C-1F86AB14EC2F"), { _id => "11979D40-F504-11E7-AD0C-1F86AB14EC2F", _path => File::Spec->catdir( $dir, "119", "79D", "40-", "F50", "4-1", "1E7", "-AD", "0C-", "1F8", "6AB", "14E", "C2F" ) }, "get returns mapping" ); $p->add("6998EBAE-CEE7-11E7-97D5-911D6EE4309A"); is_deeply( $p->to_array(), [ { _id => "11979D40-F504-11E7-AD0C-1F86AB14EC2F", _path => File::Spec->catdir( $dir, "119", "79D", "40-", "F50", "4-1", "1E7", "-AD", "0C-", "1F8", "6AB", "14E", "C2F" ) }, { _id => "6998EBAE-CEE7-11E7-97D5-911D6EE4309A", _path => File::Spec->catdir( $dir, "699", "8EB", "AE-", "CEE", "7-1", "1E7", "-97", "D5-", "911", "D6E", "E43", "09A" ) } ], "path index contains 2 mappings now" ); lives_ok( sub { $p->delete("11979D40-F504-11E7-AD0C-1F86AB14EC2F"); }, "delete directory" ); lives_ok( sub { $p->delete_all(); }, "delete all directories" ); is_deeply($p->to_array(), [], "list of entries should be empty now"); my $t2 = File::Temp->newdir(EXLOCK => 0, UNLINK => 1); my $dir2 = Cwd::abs_path($t->dirname); path(File::Spec->catdir($dir2, qw(1 2 3 4 5 5 6 7 8 9 10 11 12 13))) ->mkpath(); dies_ok( sub { $pkg->new(base_dir => $dir2)->to_array(); }, "invalid mappings trigger an error" ); done_testing; Memory.pm100644000765000024 351313362073757 23346 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/Filepackage Catmandu::Store::File::Memory; our $VERSION = '1.13'; use Catmandu::Sane; use Moo; use Carp; use Catmandu::Store::File::Memory::Index; use Catmandu::Store::File::Memory::Bag; use namespace::clean; with 'Catmandu::FileStore'; with 'Catmandu::Droppable'; has _files => (is => 'ro', lazy => 1, default => sub {+{}}); sub drop { my ($self) = @_; $self->index->delete_all; } 1; __END__ =pod =head1 NAME Catmandu::Store::File::Memory - A Catmandu::FileStore to keep files in memory =head1 SYNOPSIS # From Perl use Catmandu; my $store = Catmandu->store('File::Mempory'); my $index = $store->index; # List all folders $index->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $index->add({ _id => '1234' }); # Get the folder my $files = $index->files('1234'); # Add a file to the folder $files->upload(IO::File->new('get('foobar.txt'); # Stream the contents of a file $files->stream(IO::File->new('>foobar.txt'), $file); # Delete a file $files->delete('foobar.txt'); # Delete a container $index->delete('1234'); =head1 INHERITED METHODS This Catmandu::FileStore implements: =over 3 =item L =item L =back The index Catmandu::Bag in this Catmandu::Store implements: =over 3 =item L =item L =item L =back The file Catmandu::Bag in this Catmandu::Store implements: =over 3 =item L =item L =item L =back =head1 SEE ALSO L, L, L, L Simple.pm100644000765000024 1227613362073757 23355 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/Filepackage Catmandu::Store::File::Simple; our $VERSION = '1.13'; use Catmandu::Sane; use Moo; use Carp; use Catmandu; use Catmandu::Util; use Catmandu::Store::File::Simple::Index; use Catmandu::Store::File::Simple::Bag; use Data::UUID; use Catmandu::DirectoryIndex::UUID; use Catmandu::DirectoryIndex::Number; use namespace::clean; with 'Catmandu::FileStore'; with 'Catmandu::Droppable'; has root => (is => 'ro', required => '1'); #DEPRECATED has uuid => (is => 'ro'); #DEPRECATED has keysize => ( is => 'ro', isa => sub { Catmandu::Util::check_natural($_[0]); croak "keysize needs to be a multiple of 3" unless $_[0] % 3 == 0; }, default => 9 ); has directory_index_package => (is => "ro"); has directory_index_options => (is => "ro", lazy => 1, default => sub {+{};}); has directory_index => (is => "lazy"); sub _build_directory_index { my $self = $_[0]; if ($self->directory_index_package()) { Catmandu::Util::require_package($self->directory_index_package(), "Catmandu::DirectoryIndex") ->new(%{$self->directory_index_options(),}, base_dir => $self->root()); } elsif ($self->uuid()) { Catmandu::DirectoryIndex::UUID->new(base_dir => $self->root()); } else { Catmandu::DirectoryIndex::Number->new( base_dir => $self->root(), keysize => $self->keysize() ); } } sub drop { my ($self) = @_; $self->index->delete_all; } 1; __END__ =pod =head1 NAME Catmandu::Store::File::Simple - A Catmandu::FileStore to store files on disk =head1 SYNOPSIS # From the command line # Export a list of all file containers $ catmandu export File::Simple --root t/data to YAML # Export a list of all files in container '1234' $ catmandu export File::Simple --root t/data --bag 1234 to YAML # Add a file to the container '1234' $ catmandu stream /tmp/myfile.txt to File::Simple --root t/data --bag 1234 --id myfile.txt # Download the file 'myfile.txt' from the container '1234' $ catmandu stream File::Simple --root t/data --bag 1234 --id myfile.txt to /tmp/output.txt # Delete the file 'myfile.txt' from the container '1234' $ catmandu delete File::Simple --root t/data --bag 1234 --id myfile.txt # From Perl use Catmandu; my $store = Catmandu->store('File::Simple' , root => 't/data'); my $index = $store->index; # List all folder $index->bag->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $index->add({ _id => '1234' }); # Get the folder my $files = $index->files('1234'); # Add a file to the folder $files->upload(IO::File->new('get('foobar.txt'); # Stream the contents of a file $files->stream(IO::File->new('>foobar.txt'), $file); # Delete a file $files->delete('foobar.txt'); # Delete a folder $index->delete('1234'); =head1 DESCRIPTION L is a L implementation to store files in a directory structure. Each L is a deeply nested directory based on the numeric identifier of the bag. E.g. $store->bag(1234) is stored as ${ROOT}/000/001/234 In this directory all the L items are stored as flat files. =head1 METHODS =head2 new(root => $path , [ keysize => NUM , uuid => 1]) Create a new Catmandu::Store::File::Simple with the following configuration parameters: =over =item root The root directory where to store all the files. Required. =item keysize DEPRECATED: use directory_index_package and directory_index_options By default the directory structure is 3 levels deep. With the keysize option a deeper nesting can be created. The keysize needs to be a multiple of 3. All the container keys of a L must be integers. =item uuid DEPRECATED: use directory_index_package and directory_index_options If the to a true value, then the Simple store will require UUID-s as keys =item directory_index_package package name that translates between id and a directory. prefix "Catmandu::DirectoryIndex::" can be omitted. Default: L =item directory_index_options Constructor arguments for the directory_index_package (see above) =item directory_index instance of L. When supplied, directory_index_package and directory_index_options are ignored. When not, this object is constructed from directory_index_package and directory_index_options. =back =head1 INHERITED METHODS This Catmandu::FileStore implements: =over 3 =item L =item L =back The index Catmandu::Bag in this Catmandu::Store implements: =over 3 =item L =item L =item L =back The file Catmandu::Bag in this Catmandu::Store implements: =over 3 =item L =item L =item L =back =head1 SEE ALSO L, L, L, L =cut Catmandu-Store-File-Multi-Bag.t100644000765000024 617513362073757 23204 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use Catmandu::Store::File::Simple; use Catmandu::Store::File::Multi; use Path::Tiny; use utf8; my $pkg; BEGIN { $pkg = 'Catmandu::Store::File::Multi::Bag'; use_ok $pkg; } require_ok $pkg; path("t/tmp/multi-bag/a")->mkpath; path("t/tmp/multi-bag/b")->mkpath; my $stores = [ Catmandu::Store::File::Simple->new( root => 't/tmp/multi-bag/a', keysize => 9 ), Catmandu::Store::File::Simple->new( root => 't/tmp/multi-bag/b', keysize => 9 ), ]; my $store = Catmandu::Store::File::Multi->new(stores => $stores); my $index = $store->index; ok $store , 'got a store'; ok $index , 'got an index'; ok $index->add({_id => 7012}), 'adding bag `7012`'; my $bag = $store->bag('7012'); ok $bag , 'got bag(7012)'; note("add"); { my $n1 = $bag->upload(IO::File->new('t/data2/000/000/001/test.txt'), 'test1.txt'); ok $n1 , 'upload test1.txt'; is $n1 , 16, '16 bytes'; ok -f 't/tmp/multi-bag/a/000/007/012/test1.txt', 'test1.txt exists'; ok -f 't/tmp/multi-bag/b/000/007/012/test1.txt', 'test1.txt exists'; my $n2 = $bag->upload(IO::File->new('t/data2/000/000/002/test.txt'), 'test2.txt'); ok $n2 , 'upload test2.txt'; is $n2 , 6, '6 bytes'; ok -f 't/tmp/multi-bag/a/000/007/012/test2.txt', 'test2.txt exists'; ok -f 't/tmp/multi-bag/b/000/007/012/test2.txt', 'test1.txt exists'; my $n3 = $bag->upload(IO::File->new('t/data2/000/000/003/test.txt'), 'test3.txt'); ok $n3 , 'upload test3.txt'; is $n3 , 6, '6 bytes'; ok -f 't/tmp/multi-bag/a/000/007/012/test3.txt', 'test3.txt exists'; ok -f 't/tmp/multi-bag/b/000/007/012/test3.txt', 'test1.txt exists'; my $data = { _id => 'test4.txt', _stream => IO::File->new('t/data2/000/000/003/test.txt') }; ok $bag->add($data), 'add({ ..test4.. })'; is $data->{size}, 6, '$data->{size}'; } note("list"); { my $array = [sort @{$bag->map(sub {shift->{_id}})->to_array}]; ok $array , 'list got a response'; is_deeply $array , [qw(test1.txt test2.txt test3.txt test4.txt)], 'got correct response'; } note("exists"); { for (1 .. 4) { ok $bag->exists("test" . $_ . ".txt"), "exists(test" . $_ . ".txt)"; } } note("get"); { for (1 .. 3) { ok $bag->get("test" . $_ . ".txt"), "get(test" . $_ . ".txt)"; } my $file = $bag->get("test1.txt"); my $str = $bag->as_string_utf8($file); ok $str , 'can stream the data'; is $str , "钱唐湖春行\n", 'got the correct data'; } note("delete"); { ok $bag->delete('test1.txt'), 'delete(test1.txt)'; my $array = [sort @{$bag->map(sub {shift->{_id}})->to_array}]; ok $array , 'list got a response'; is_deeply $array , [qw(test2.txt test3.txt test4.txt)], 'got correct response'; } note("...delete_all (index)"); { lives_ok {$index->delete_all()} 'delete_all'; my $array = $index->to_array; is_deeply $array , [], 'got correct response'; } path("t/tmp/multi-bag/a")->remove_tree; path("t/tmp/multi-bag/b")->remove_tree; done_testing(); DirectoryIndex000755000765000024 013362073757 22357 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/CatmanduMap.pm100644000765000024 1364013362073757 23616 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/DirectoryIndexpackage Catmandu::DirectoryIndex::Map; our $VERSION = '1.13'; use Catmandu::Sane; use Catmandu::Util qw(:is :check); use Catmandu; use Cwd; use File::Spec; use Catmandu::BadArg; use Catmandu::Error; use POSIX qw(); use Data::Dumper; use Moo; use Path::Tiny qw(path); use URI::Escape qw(); use namespace::clean; with "Catmandu::DirectoryIndex"; has store_name => (is => "ro"); has bag_name => (is => "ro"); has bag => ( is => "ro", isa => sub { my $l = $_[0]; #check_instance( $l, "Catmandu::Bag" ) returns false .. check_instance($l); $l->does("Catmandu::Bag") or die("lookup should be Catmandu::Bag implementation"); }, lazy => 1, builder => "_build_bag" ); sub _build_bag { Catmandu->store($_[0]->store_name)->bag($_[0]->bag_name); } #checks whether mapping record is syntactically correct sub _is_valid_mapping { my $map = $_[0]; return unless is_hash_ref($map); is_string($map->{_id}) && is_string($map->{_path}); } #creates new directory: returns path if all is ok, throws an error on failure sub _new_path { my ($self, $id) = @_; Catmandu::BadArg->throw("need id") unless is_string($id); my $escaped_id = URI::Escape::uri_escape_utf8($id); my $t = POSIX::strftime("%Y/%m/%d/%H/%M/%S", gmtime(time)); my $path = File::Spec->catdir($self->base_dir(), split("/", $t), $escaped_id); my $err; path($path)->mkpath({error => \$err}); Catmandu::Error->throw( "unable to create directory $path: " . Dumper($err)) if defined($err) && scalar(@$err); $self->bag()->add({_id => $id, _path => $path}); $path; } #translates id to path: return either valid path or undef. sub _to_path { my ($self, $id) = @_; Catmandu::BadArg->throw("need id") unless is_string($id); my $mapping = $self->bag()->get($id); #no mapping, no path return unless _is_valid_mapping($mapping); #inconsistent behaviour: mapping exists, but directory is gone Catmandu::Error->throw("mapping $id contains non existant directory") unless -d $mapping->{_path}; $mapping->{_path}; } sub get { my ($self, $id) = @_; my $path = $self->_to_path($id); is_string($path) ? {_id => $id, _path => $path} : undef; } sub add { my ($self, $id) = @_; my $path = $self->_to_path($id) || $self->_new_path($id); {_id => $id, _path => $path}; } sub delete { my ($self, $id) = @_; my $path = $self->_to_path($id); if (is_string($path)) { my $err; path($path)->remove_tree({error => \$err}); Catmandu::Error->throw( "unable to remove directory $path: " . Dumper($err)) if defined($err) && scalar(@$err); } $self->bag()->delete($id); } sub delete_all { my $self = $_[0]; if (-d $self->base_dir) { my $err; path($self->base_dir)->remove_tree({keep_root => 1, error => \$err}); Catmandu::Error->throw("unable to remove entries from base directory " . $self->base_dir . " : " . Dumper($err)) if defined($err) && scalar(@$err); } $self->bag->delete_all; } sub generator { my $self = $_[0]; return sub { state $gen = $self->bag()->generator(); my $mapping = $gen->(); return unless defined $mapping; Catmandu::Error->throw( "invalid mapping detected: " . Dumper($mapping)) unless _is_valid_mapping($mapping); Catmandu::Error->throw( "mapping $mapping->{_id} contains non existant directory") unless -d $mapping->{_path}; +{_id => $mapping->{_id}, _path => $mapping->{_path}}; }; } 1; __END__ =pod =head1 NAME Catmandu::DirectoryIndex::Map - translates between id and path using a Catmandu::Bag as lookup =head1 SYNOPSIS use Catmandu::DirectoryIndex::Map; use Catmandu::Store::DBI; # Bag to store/retrieve all path -> directory mapping my $bag = Catmandu::Store::DBI->new( data_source => "dbi:sqlite:dbname=/data/index.db" )->bag("paths"); my $p = Catmandu::DirectoryIndex::Map->new( base_dir => "/data", bag => $bag ); # Tries to find a mapping for id "a". # return: mapping or undef my $mapping = $p->get("a"); # Returns a mapping like { _id => "a", _path => "/data/2018/01/01/16/00/00/0cc175b9c0f1b6a831c399e269772661" } my $mapping = $p->add("a"); # Catmandu::DirectoryIndex::Map is a Catmandu::Iterable # Returns list of records: [{ _id => "a", _path => "/data/2018/01/01/16/00/00/0cc175b9c0f1b6a831c399e269772661" }] my $mappings = $p->to_array(); =head1 DESCRIPTION This package uses a Catmandu::Bag backend to translate between ids and paths. Each record looks like this: { _id => "a", _path => "/data/2018/01/01/16/00/00/0cc175b9c0f1b6a831c399e269772661" } If the mapping for the id does not exist yet, this package calculates it by concatenating into a path: * $base_dir which is configurable * YYYY: current year * MM: current month * DD: current day of month * HH: current hour * MM: current minute * SS: current second * TEXT: the md5 of the _id Every call to C will generate a directory entry in the backend database, if it didn't already exist. =head1 METHODS =head2 new( OPTIONS ) Create a new Catmandu::DirectoryIndex::Map with the following configuration parameters: =over =item base_dir See L =item store_name Name of the store in the Catmandu configuration. Ignored when bag instance is given. =item bag_name Name of the bag in the Catmandu configuration. Ignored when bag instance is given =item bag Instance of L where all mappings between _id and _path are stored. =back =head1 INHERITED METHODS This Catmandu::DirectoryIndex::Map implements: =over 3 =item L =back =head1 SEE ALSO L =cut Catmandu-DirectoryIndex-Number.t100644000765000024 462513362073757 23634 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use File::Temp; use File::Spec; use Cwd; use Path::Tiny; my $pkg; BEGIN { $pkg = 'Catmandu::DirectoryIndex::Number'; use_ok $pkg; } require_ok $pkg; my $t = File::Temp->newdir(EXLOCK => 0, UNLINK => 1); my $dir = Cwd::abs_path($t->dirname); dies_ok( sub { $pkg->new(base_dir => $dir, keysize => 1); }, "keysize must be a multiple of 3" ); my $p; lives_ok( sub { $p = $pkg->new(base_dir => $dir, keysize => 9); } ); dies_ok( sub { $p->add("test"); }, "ids must be natural numbers" ); dies_ok( sub { $p->add(-1); }, "ids must be bigger or equal to zero" ); dies_ok( sub { $p->add(1234567890); }, "ids must fit into configured keysize" ); lives_ok( sub { $p->add(123456789); } ); is_deeply( $p->get(123456789), { _id => "123456789", _path => File::Spec->catdir($dir, "123", "456", "789") }, "get returns mapping" ); is_deeply( $p->add(1), { _id => "000000001", _path => File::Spec->catdir($dir, "000", "000", "001") }, "number are converted to left padded strings" ); is_deeply( $p->add("000000002"), { _id => "000000002", _path => File::Spec->catdir($dir, "000", "000", "002") }, "left padded strings are ok if they respect the keysize" ); is_deeply( $p->to_array(), [ { _id => "000000001", _path => File::Spec->catdir($dir, "000", "000", "001") }, { _id => "000000002", _path => File::Spec->catdir($dir, "000", "000", "002") }, { _id => "123456789", _path => File::Spec->catdir($dir, "123", "456", "789") }, ], "path index contains 3 mappings now" ); lives_ok( sub { $p->delete(2); }, "delete directory" ); lives_ok( sub { $p->delete_all(); }, "delete all directories" ); is_deeply($p->to_array(), [], "list of entries should be empty now"); my $t2 = File::Temp->newdir(EXLOCK => 0, UNLINK => 1); my $dir2 = Cwd::abs_path($t->dirname); path(File::Spec->catdir($dir2, "a", "b", "c"))->mkpath(); dies_ok( sub { $pkg->new(base_dir => $dir2)->to_array(); }, "invalid mappings trigger an error" ); done_testing; Catmandu-Store-File-Memory-Bag.t100644000765000024 411513362073757 23352 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use IO::String; use Catmandu::Util qw(:io); use Catmandu::Store::File::Memory; use utf8; my $pkg; BEGIN { $pkg = 'Catmandu::Store::File::Memory::Bag'; use_ok $pkg; } require_ok $pkg; my $store = Catmandu::Store::File::Memory->new; my $index = $store->bag; ok $store , 'got a store'; ok $index , 'got an index'; ok $index->add({_id => 8012}), 'adding bag `8012`'; my $bag = $store->bag('8012'); ok $bag , 'got bag(8012)'; note("add"); { my $n1 = $bag->upload(io('t/data2/000/000/001/test.txt'), 'test1.txt'); ok $n1 , 'upload test1.txt'; is $n1 , 16, '16 bytes'; my $n2 = $bag->upload(io('t/data2/000/000/002/test.txt'), 'test2.txt'); ok $n2 , 'upload test2.txt'; is $n2 , 6, '6 bytes'; my $n3 = $bag->upload(io('t/data2/000/000/003/test.txt'), 'test3.txt'); ok $n3 , 'upload test3.txt'; is $n3 , 6, '6 bytes'; } note("list"); { my $array = [sort @{$bag->map(sub {shift->{_id}})->to_array}]; ok $array , 'list got a response'; is_deeply $array , [qw(test1.txt test2.txt test3.txt)], 'got correct response'; } note("exists"); { for (1 .. 3) { ok $bag->exists("test" . $_ . ".txt"), "exists(test" . $_ . ".txt)"; } } note("get"); { for (1 .. 3) { ok $bag->get("test" . $_ . ".txt"), "get(test" . $_ . ".txt)"; } my $file = $bag->get("test1.txt"); my $str; my $io = IO::String->new($str); my $bytes = $bag->stream($io, $file); ok $bytes, 'can stream the data'; is $bytes , 16 , 'got 16 bytes data'; is $str , "钱唐湖春行\n", 'got the correct data'; } note("delete"); { ok $bag->delete('test1.txt'), 'delete(test1.txt)'; my $array = [sort @{$bag->map(sub {shift->{_id}})->to_array}]; ok $array , 'list got a response'; is_deeply $array , [qw(test2.txt test3.txt)], 'got correct response'; } note("delete_all"); { lives_ok {$bag->delete_all()} 'delete_all'; my $array = $bag->to_array; is_deeply $array , [], 'got correct response'; } done_testing(); Catmandu-Store-File-Simple-Bag.t100644000765000024 614113362073757 23334 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use IO::String; use IO::File; use Catmandu::Store::File::Simple; use Path::Tiny; use utf8; my $pkg; BEGIN { $pkg = 'Catmandu::Store::File::Simple::Bag'; use_ok $pkg; } require_ok $pkg; path("t/tmp/file-simple-bag")->mkpath; my $store = Catmandu::Store::File::Simple->new( root => 't/tmp/file-simple-bag', keysize => 9 ); my $index = $store->bag; ok $store , 'got a store'; ok $index , 'got an index'; ok $index->add({_id => 1234}), 'adding bag `1234`'; my $bag = $store->bag('1234'); ok $bag , 'got bag(1234)'; note("add"); { my $n1 = $bag->upload(IO::File->new('t/data2/000/000/001/test.txt'), 'test1.txt'); ok $n1 , 'upload test1.txt'; is $n1 , 16, '16 bytes'; ok -f 't/tmp/file-simple-bag/000/001/234/test1.txt', 'test1.txt exists'; my $n2 = $bag->upload(IO::File->new('t/data2/000/000/002/test.txt'), 'test2.txt'); ok $n2 , 'upload test2.txt'; is $n2 , 6, '6 bytes'; ok -f 't/tmp/file-simple-bag/000/001/234/test2.txt', 'test2.txt exists'; my $n3 = $bag->upload(IO::File->new('t/data2/000/000/003/test.txt'), 'test3.txt'); ok $n3 , 'upload test3.txt'; is $n3 , 6, '6 bytes'; ok -f 't/tmp/file-simple-bag/000/001/234/test3.txt', 'test3.txt exists'; my $data = { _id => 'test3.txt', _stream => IO::File->new('t/data2/000/000/003/test.txt') }; ok $bag->add($data), 'add({ ..test3.. })'; is $data->{size}, 6, '$data->{size}'; } note("list"); { my $array = [sort @{$bag->map(sub {shift->{_id}})->to_array}]; ok $array , 'list got a response'; is_deeply $array , [qw(test1.txt test2.txt test3.txt)], 'got correct response'; } note("exists"); { for (1 .. 3) { ok $bag->exists("test" . $_ . ".txt"), "exists(test" . $_ . ".txt)"; } } note("get"); { for (1 .. 3) { ok $bag->get("test" . $_ . ".txt"), "get(test" . $_ . ".txt)"; } { my $file = $bag->get("test1.txt"); my $str = $bag->as_string_utf8($file); ok $str , 'can stream the data'; is $str , "钱唐湖春行\n", 'got the correct data'; } { my $file = $bag->get("test1.txt"); my $tempfile = Path::Tiny->tempfile; my $io = IO::File->new("> $tempfile"); $io->binmode(":raw"); my $bytes = $bag->stream($io, $file); $io->close(); ok $bytes , 'can stream the data'; is $bytes , 16 , 'got correct byte count'; my $str = path($tempfile)->slurp_utf8; is $str , "钱唐湖春行\n", 'got the correct data'; } } note("delete"); { ok $bag->delete('test1.txt'), 'delete(test1.txt)'; my $array = [sort @{$bag->map(sub {shift->{_id}})->to_array}]; ok $array , 'list got a response'; is_deeply $array , [qw(test2.txt test3.txt)], 'got correct response'; } note("delete_all"); { lives_ok {$bag->delete_all()} 'delete_all'; my $array = $bag->to_array; is_deeply $array , [], 'got correct response'; } path("t/tmp/file-simple-bag")->remove_tree; done_testing(); UUID.pm100644000765000024 1026113362073757 23643 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/DirectoryIndexpackage Catmandu::DirectoryIndex::UUID; our $VERSION = '1.13'; use Catmandu::Sane; use Catmandu::Util qw(:is :check); use Moo; use Cwd; use Path::Tiny; use Path::Iterator::Rule; use File::Spec; use Data::UUID; use Catmandu::BadArg; use Catmandu::Error; use Data::Dumper; use namespace::clean; with "Catmandu::DirectoryIndex"; sub is_uuid { my $id = $_[0]; is_string($id) && $id =~ /^[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}$/o; } sub _to_path { my ($self, $id) = @_; Catmandu::BadArg->throw("need valid uuid") unless is_uuid($id); File::Spec->catdir($self->base_dir, unpack("(A3)*", $id)); } sub _from_path { my ($self, $path) = @_; my @split_path = File::Spec->splitdir($path); my $id = join("", splice(@split_path, scalar(File::Spec->splitdir($self->base_dir)))); $id = uc($id); Catmandu::BadArg->throw("invalid uuid detected: $id") unless is_uuid($id); $id; } sub get { my ($self, $id) = @_; my $f_id = uc($id); my $path = $self->_to_path($f_id); is_string($path) && -d $path ? {_id => $f_id, _path => $path} : undef; } sub add { my ($self, $id) = @_; my $f_id = uc($id); my $path = $self->_to_path($f_id); unless (-d $path) { my $err; path($path)->mkpath({error => \$err}); Catmandu::Error->throw( "unable to create directory $path: " . Dumper($err)) if defined($err) && scalar(@$err); } {_id => $f_id, _path => $path}; } sub delete { my ($self, $id) = @_; my $f_id = uc($id); my $path = $self->_to_path($f_id); if (is_string($path) && -d $path) { my $err; path($path)->remove_tree({error => \$err}); Catmandu::Error->throw( "unable to remove directory $path: " . Dumper($err)) if defined($err) && scalar(@$err); } 1; } sub delete_all { my $self = $_[0]; if (-d $self->base_dir) { my $err; path($self->base_dir)->remove_tree({keep_root => 1, error => \$err}); Catmandu::Error->throw("unable to remove entries from base directory " . $self->base_dir . ": " . Dumper($err)) if defined($err) && scalar(@$err); } 1; } sub generator { my $self = $_[0]; return sub { state $rule; state $iter; state $base_dir = $self->base_dir(); unless ($iter) { $rule = Path::Iterator::Rule->new(); $rule->min_depth(12); $rule->max_depth(12); $rule->directory(); $iter = $rule->iter($base_dir, {depthfirst => 1}); } my $path = $iter->(); return unless defined $path; #Path::Iterator::Rule hardcodes forward slashes $path =~ s/\//\\/go if $^O eq "MSWin32"; #TODO: does not throw an error when directory is less than 12 levels (because no directories are validated) my $id = $self->_from_path($path); +{_id => $id, _path => $path}; }; } 1; __END__ =pod =head1 NAME Catmandu::DirectoryIndex::UUID - A uuid based path translator =head1 SYNOPSIS use Catmandu::DirectoryIndex::UUID; my $p = Catmandu::DirectoryIndex::UUID->new( base_dir => "/data" ); # Returns mapping like { _id => "9A581C80-1189-11E8-AB6D-46BC153F89DB", "/data/9A5/81C/80-/118/9-1/1E8/-AB/6D-/46B/C15/3F8/9DB" } # Can be undef my $mapping = $p->get("9A581C80-1189-11E8-AB6D-46BC153F89DB"); # Create path and return mapping my $mapping = $p->add("9A581C80-1189-11E8-AB6D-46BC153F89DB"); # Catmandu::DirectoryIndex::Number is a Catmandu::Iterable # Returns list of records: [{ _id => 1234, _path => "/data/000/001/234" }] my $mappings = $p->to_array(); =head1 METHODS =head2 new( base_dir => $base_dir ) Create a new Catmandu::DirectoryIndex::UUID with the following configuration parameters: =over =item base_dir See L =back =head1 LIMITATIONS The keys in this directory can only be UUID identifiers. =head1 INHERITED METHODS This Catmandu::DirectoryIndex::Number implements: =over 3 =item L =back =head1 SEE ALSO L =cut Catmandu-Store-File-Multi-Index.t100644000765000024 453213362073757 23555 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use Catmandu::Store::File::Simple; use Catmandu::Store::File::Multi; use Path::Tiny; my $pkg; BEGIN { $pkg = 'Catmandu::Store::File::Multi::Index'; use_ok $pkg; } require_ok $pkg; my $stores = [Catmandu::Store::File::Simple->new(root => 't/data2', keysize => 9),]; my $store = Catmandu::Store::File::Multi->new(stores => $stores); my $index; note("index"); { $index = $store->index(); ok $index , 'got the index bag'; } note("list"); { my $array = $index->to_array; ok $array , 'list got a response'; # Order is not important in a list is_deeply [sort({$a->{_id} cmp $b->{_id}} @$array)], [{_id => "000000001"}, {_id => "000000002"}, {_id => "000000003"},], 'got correct response'; } note("exists"); { for (1 .. 3) { ok $index->exists($_), "exists($_)"; my $zero_key = ("0" x $_) . $_; ok $index->exists($zero_key), "exists($zero_key)"; } } note("get"); { for (1 .. 3) { ok $index->get($_), "get($_)"; my $zero_key = ("0" x $_) . $_; ok $index->get($zero_key), "get($zero_key)"; } } path("t/tmp/multi-index/a")->mkpath; path("t/tmp/multi-index/b")->mkpath; $stores = [ Catmandu::Store::File::Simple->new( root => 't/tmp/multi-index/a', keysize => 9 ), Catmandu::Store::File::Simple->new( root => 't/tmp/multi-index/b', keysize => 9 ), ]; $store = Catmandu::Store::File::Multi->new(stores => $stores); $index = $store->index(); note("add"); { throws_ok {$index->add({_id => 'abcd'})} 'Catmandu::BadArg', 'failed to add(abcd)'; throws_ok {$index->add({_id => '1234567890'})} 'Catmandu::BadArg', 'failed to add(1234567890)'; throws_ok {$index->add({_id => '00000000001234'})} 'Catmandu::BadArg', 'failed to add(00000000001234)'; my $c = $index->add({_id => '1234'}); ok $c , 'add(1234)'; ok -d "t/tmp/multi-index/a/000/001/234", 'found a container on disk'; } note("delete"); { ok $index->delete('1234'), 'delete(1234)'; ok !-d "t/tmp/multi-index/a/000/001/234", 'container on disk was deleted'; } note("delete_all"); { lives_ok {$index->delete_all()} 'delete_all'; } path("t/tmp/multi-index/a")->remove_tree; path("t/tmp/multi-index/b")->remove_tree; done_testing(); Multi000755000765000024 013362073757 22470 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/FileBag.pm100644000765000024 1037313362073757 23703 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/File/Multipackage Catmandu::Store::File::Multi::Bag; use Catmandu::Sane; our $VERSION = '1.13'; use Moo; use Catmandu::Util qw(:is); use Catmandu::Logger; use namespace::clean; extends 'Catmandu::Store::Multi::Bag'; with 'Catmandu::FileBag'; sub add { my ($self, $data) = @_; # Overwrite the Multi::Bag add an store each stream in the backend store my $rewind = 0; my $id = $data->{_id}; my $stream = $data->{_stream}; my $new_data = {}; # By default try to add the data to all the stores for my $store (@{$self->store->stores}) { my $bag = $store->bag($self->name); next unless $bag; if ($rewind) { # Rewind the stream after first use... Catmandu::BadVal->throw("IO stream needs to seekable") unless $stream->isa('IO::Seekable'); $stream->seek(0, 0); } my $file = {_id => $id, _stream => $stream}; $bag->add($file); for (keys %$file) { $new_data->{$_} = $file->{$_} unless exists $new_data->{$_}; } $rewind = 1; } # Check if the returned record contains the minimum required fields # (otherwise we have a File::Store implementation that doesn't inline # update the passed $data in add($data)) if ( exists $new_data->{size} && exists $new_data->{created} && exists $new_data->{modified}) { # all is ok } else { $self->log->warn( "$self doesn't inline update \$data in add(\$data) method"); $new_data = $self->get($id); } if ($new_data) { $data->{$_} = $new_data->{$_} for keys %$new_data; } else { $self->log->error("can't find $id in $self!"); } 1; } sub upload { my ($self, $io, $id) = @_; # Upload in a FileStore should send data, in a normal Store it adds an # empty record my $rewind; my $bytes = 0; for my $store (@{$self->store->stores}) { if ($store->does('Catmandu::FileStore')) { my $bag = $store->bag($self->name); next unless $bag; if ($rewind) { # Rewind the stream after first use... Catmandu::BadVal->throw("IO stream needs to seekable") unless $io->isa('IO::Seekable'); $io->seek(0, 0); } $bytes = $store->bag($self->name)->upload($io, $id) || $self->log->error( "failed to upload $id to " . $self->name); $rewind = 1; } else { my $bag = $store->bag($self->name); next unless $bag; $bag->add({_id => $id}); } } return $bytes; } 1; __END__ =pod =head1 NAME Catmandu::Store::File::Multi::Bag - Index of all "files" in a Catmandu::Store::File::Multi "folder" =head1 SYNOPSIS use Catmandu; my $store = Catmandu->store('File::Multi' , stores [ Catmandu->store('File::Simple', root => '/data1/files') , Catmandu->store('File::Simple', root => '/data1/files_copy') , ]); my $index = $store->index; # List all containers $index->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $index->add({_id => '1234'}); # Delete a folder $index->delete(1234); # Get a folder my $folder = $index->get(1234); # Get the files in an folder my $files = $index->files(1234); $files->each(sub { my $file = shift; my $name = $file->_id; my $size = $file->size; my $content_type = $file->content_type; my $created = $file->created; my $modified = $file->modified; $file->stream(IO::File->new(">/tmp/$name"), file); }); # Add a file $files->upload(IO::File->new("get("data.dat"); # Stream a file to an IO::Handle $files->stream(IO::File->new(">data.dat"),$file); # Delete a file $files->delete("data.dat"); # Delete a folders $index->delete("1234"); =head1 INHERITED METHODS This Catmandu::Bag implements: =over 3 =item L =item L =item L =back =cut Catmandu-Store-File-Memory-Index.t100644000765000024 217713362073757 23736 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use Catmandu::Store::File::Memory; my $pkg; BEGIN { $pkg = 'Catmandu::Store::File::Memory::Index'; use_ok $pkg; } require_ok $pkg; my $store = Catmandu::Store::File::Memory->new(); my $index; note("index"); { $index = $store->bag(); ok $index , 'got the index bag'; } note("add"); { ok $index->add({_id => '1'}), 'add({_id => 1})'; ok $index->add({_id => '2'}), 'add({_id => 2})'; ok $index->add({_id => '3'}), 'add({_id => 3})'; } note("list"); { my $array = [sort @{$index->map(sub {shift->{_id}})->to_array}]; ok $array , 'list got a response'; is_deeply $array , [1, 2, 3], 'got correct response'; } note("exists"); { for (1 .. 3) { ok $index->exists($_), "exists($_)"; } } note("get"); { for (1 .. 3) { ok $index->get($_), "get($_)"; } } note("delete"); { ok $index->delete('1'), 'delete(1)'; } note("delete_all"); { lives_ok {$index->delete_all()} 'delete_all'; my $array = $index->to_array; is_deeply $array , [], 'got correct response'; } done_testing(); Catmandu-Store-File-Simple-Index.t100644000765000024 376713362073757 23725 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/t#!/usr/bin/env perl use strict; use warnings; use Test::More; use Test::Exception; use Path::Tiny; use Catmandu::Store::File::Simple; my $pkg; BEGIN { $pkg = 'Catmandu::Store::File::Simple::Index'; use_ok $pkg; } require_ok $pkg; my $store = Catmandu::Store::File::Simple->new(root => 't/data2', keysize => 9); my $index; note("index"); { $index = $store->bag(); ok $index , 'got the index bag'; } note("list"); { my $array = $index->to_array; ok $array , 'list got a response'; # Order is not important in a list is_deeply [sort({$a->{_id} cmp $b->{_id}} @$array)], [{_id => "000000001"}, {_id => "000000002"}, {_id => "000000003"},], 'got correct response'; } note("exists"); { for (1 .. 3) { ok $index->exists($_), "exists($_)"; my $zero_key = ("0" x $_) . $_; ok $index->exists($zero_key), "exists($zero_key)"; } } note("get"); { for (1 .. 3) { ok $index->get($_), "get($_)"; my $zero_key = ("0" x $_) . $_; ok $index->get($zero_key), "get($zero_key)"; } } path("t/tmp/file-simple-index")->mkpath; $store = Catmandu::Store::File::Simple->new( root => 't/tmp/file-simple-index', keysize => 9 ); $index = $store->bag(); note("add"); { throws_ok {$index->add({_id => 'abcd'})} 'Catmandu::BadArg', 'failed to add(abcd)'; throws_ok {$index->add({_id => '1234567890'})} 'Catmandu::BadArg', 'failed to add(1234567890)'; throws_ok {$index->add({_id => '00000000001234'})} 'Catmandu::BadArg', 'failed to add(00000000001234)'; my $c = $index->add({_id => '1234'}); ok $c , 'add(1234)'; ok -d "t/tmp/file-simple-index/000/001/234", 'found a container on disk'; } note("delete"); { ok $index->delete('1234'), 'delete(1234)'; ok !-d "t/tmp/file-simple-index/000/001/234", 'container on disk was deleted'; } note("delete_all"); { lives_ok {$index->delete_all()} 'delete_all'; } path("t/tmp/file-simple-index")->remove_tree; done_testing(); Number.pm100644000765000024 1114713362073757 24331 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/DirectoryIndexpackage Catmandu::DirectoryIndex::Number; our $VERSION = '1.13'; use Catmandu::Sane; use Catmandu::Util qw(:is :check); use Moo; use Cwd; use Path::Tiny qw(path); use Path::Iterator::Rule; use File::Spec; use Catmandu::BadArg; use Catmandu::Error; use Data::Dumper; use namespace::clean; with "Catmandu::DirectoryIndex"; has keysize => (is => 'ro', default => 9, trigger => 1); sub _trigger_keysize { Catmandu::BadArg->throw("keysize needs to be a multiple of 3") unless $_[0]->keysize % 3 == 0; } sub format_id { my ($self, $id) = @_; Catmandu::BadArg->throw("need natural number") unless is_natural($id); my $n_id = int($id); Catmandu::BadArg->throw("id must be bigger or equal to zero") if $n_id < 0; my $keysize = $self->keysize(); Catmandu::BadArg->throw( "id '$id' does not fit into configured keysize $keysize") if length("$id") > $keysize; sprintf "%-${keysize}.${keysize}d", $n_id; } sub _to_path { my ($self, $id) = @_; File::Spec->catdir($self->base_dir, unpack("(A3)*", $id)); } sub _from_path { my ($self, $path) = @_; my @split_path = File::Spec->splitdir($path); my $id = join("", splice(@split_path, scalar(File::Spec->splitdir($self->base_dir)))); $self->format_id($id); } sub get { my ($self, $id) = @_; my $f_id = $self->format_id($id); my $path = $self->_to_path($f_id); is_string($path) && -d $path ? {_id => $f_id, _path => $path} : undef; } sub add { my ($self, $id) = @_; my $f_id = $self->format_id($id); my $path = $self->_to_path($f_id); unless (-d $path) { my $err; path($path)->mkpath({error => \$err}); Catmandu::Error->throw( "unable to create directory $path: " . Dumper($err)) if defined($err) && scalar(@$err); } +{_id => $f_id, _path => $path}; } sub delete { my ($self, $id) = @_; my $f_id = $self->format_id($id); my $path = $self->_to_path($f_id); if (is_string($path) && -d $path) { my $err; path($path)->remove_tree({error => \$err}); Catmandu::Error->throw( "unable to remove directory $path: " . Dumper($err)) if defined($err) && scalar(@$err); } 1; } sub delete_all { my $self = $_[0]; if (-d $self->base_dir) { my $err; path($_[0]->base_dir)->remove_tree({keep_root => 1, error => \$err}); Catmandu::Error->throw("unable to remove entries from base directory " . $self->base_dir . ": " . Dumper($err)) if defined($err) && scalar(@$err); } 1; } sub generator { my $self = $_[0]; return sub { state $rule; state $iter; state $base_dir = $self->base_dir(); unless ($iter) { $rule = Path::Iterator::Rule->new(); $rule->min_depth($self->keysize() / 3); $rule->max_depth($self->keysize() / 3); $rule->directory(); $iter = $rule->iter($base_dir, {depthfirst => 1}); } my $path = $iter->(); return unless defined $path; #Path::Iterator::Rule hardcodes forward slashes $path =~ s/\//\\/go if $^O eq "MSWin32"; my $id = $self->_from_path($path); +{_id => $id, _path => $path}; }; } 1; __END__ =pod =head1 NAME Catmandu::DirectoryIndex::Number - A natural number based directory translator =head1 SYNOPSIS use Catmandu::DirectoryIndex::Number; my $p = Catmandu::DirectoryIndex::Number->new( base_dir => "/data", keysize => 9 ); # get mapping for id: { _id => 1234, _path => "/data/000/001/234" } # can be undef my $mapping = $p->get(1234); # create mapping for id. Path created if necessary my $mapping = $p->add(1234); # Catmandu::DirectoryIndex::Number is a Catmandu::Iterable # Returns list of records: [{ _id => "000001234", _path => "/data/000/001/234" }] my $mappings = $p->to_array(); =head1 METHODS =head2 new( base_dir => $base_dir , keysize => NUM ) Create a new Catmandu::DirectoryIndex::Number with the following configuration parameters: =over =item base_dir See L =item keysize By default the directory structure is 3 levels deep. With the keysize option a deeper nesting can be created. The keysize needs to be a multiple of 3. =back =head1 LIMITATIONS The keys in this directory can only be natural numbers 0,1,2 ... =head1 INHERITED METHODS This Catmandu::DirectoryIndex::Number implements: =over 3 =item L =back =head1 SEE ALSO L =cut Memory000755000765000024 013362073757 22646 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/FileBag.pm100644000765000024 1057713362073757 24067 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/File/Memorypackage Catmandu::Store::File::Memory::Bag; our $VERSION = '1.13'; use Catmandu::Sane; use Moo; use Clone 'clone'; use Catmandu::Util qw(content_type); use namespace::clean; require bytes; with 'Catmandu::Bag'; with 'Catmandu::FileBag'; with 'Catmandu::Droppable'; sub generator { my ($self) = @_; my $name = $self->name; my $files = $self->store->_files->{$name} // {}; sub { state $ids = [keys %$files]; my $id = pop @$ids; return undef unless $id; return $self->get($id); }; } sub exists { my ($self, $id) = @_; my $name = $self->name; my $files = $self->store->_files->{$name} // {}; exists $files->{$id}; } sub get { my ($self, $id) = @_; my $name = $self->name; my $files = $self->store->_files->{$name} // {}; $files->{$id}; } sub add { my ($self, $data) = @_; my $id = $data->{_id}; my $io = $data->{_stream}; delete $data->{_stream}; my $name = $self->name; my $str = Catmandu::Util::read_io($io); $data->{_id} = $id; $data->{size} = bytes::length($str); $data->{md5} = ''; $data->{content_type} = content_type($id); $data->{created} = time; $data->{modified} = time; $data->{_stream} = sub { my $io = $_[0]; Catmandu::Error->throw("no io defined or not writable") unless defined($io); $io->write($str); bytes::length($str); }; $self->store->_files->{$name}->{$id} = clone($data); 1; } sub delete { my ($self, $id) = @_; my $name = $self->name; my $files = $self->store->_files->{$name} // {}; delete $files->{$id}; } sub delete_all { my ($self) = @_; $self->each( sub { my $key = shift->{_id}; $self->delete($key); } ); 1; } sub drop { $_[0]->delete_all; } sub commit { return 1; } 1; __END__ =pod =head1 NAME Catmandu::Store::File::Memory::Bag - Index of all "files" in a Catmandu::Store::File::Memory "folder" =head1 SYNOPSIS use Catmandu; my $store = Catmandu->store('File::Memory'); my $index = $store->index; # List all containers $index->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $index->add({_id => '1234'}); # Delete a folder $index->delete(1234); # Get a folder my $folder = $index->get(1234); # Get the files in an folder my $files = $index->files(1234); $files->each(sub { my $file = shift; my $name = $file->_id; my $size = $file->size; my $content_type = $file->content_type; my $created = $file->created; my $modified = $file->modified; $file->stream(IO::File->new(">/tmp/$name"), file); }); # Add a file $files->upload(IO::File->new("get("data.dat"); # Stream a file to an IO::Handle $files->stream(IO::File->new(">data.dat"),$file); # Delete a file $files->delete("data.dat"); # Delete a folders $index->delete("1234"); =head1 DESCRIPTION A L contains all "files" available in a L FileStore "folder". All methods of L, L and L are implemented. Every L is also an L. =head1 FOLDERS All files in a L are organized in "folders". To add a "folder" a new record needs to be added to the L : $index->add({_id => '1234'}); The C<_id> field is the only metadata available in Memory stores. To add more metadata fields to a Memory store a L is required. =head1 FILES Files can be accessed via the "folder" identifier: my $files = $index->files('1234'); Use the C method to add new files to a "folder". Use the C method to retrieve files from a "folder". $files->upload(IO::File->new("get('data.txt'); $files->download(IO::File->new(">/tmp/data.txt"),$file); =head1 INHERITED METHODS This Catmandu::Bag implements: =over 3 =item L =item L =item L =back =cut Simple000755000765000024 013362073757 22627 5ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/FileBag.pm100644000765000024 1453013362073757 24041 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/File/Simplepackage Catmandu::Store::File::Simple::Bag; use Catmandu::Sane; our $VERSION = '1.13'; use Moo; use Carp; use IO::File; use Path::Tiny; use File::Spec; use File::Copy; use Catmandu::Util qw(content_type); use URI::Escape; use namespace::clean; with 'Catmandu::Bag'; with 'Catmandu::FileBag'; with 'Catmandu::Droppable'; has _path => (is => 'lazy'); sub _build__path { my $self = shift; $self->store->directory_index->add($self->name)->{_path}; } sub generator { my ($self) = @_; my $path = $self->_path; sub { state $children = [path($path)->children]; my $child = shift @$children; return undef unless $child; my ($volume, $directories, $file) = File::Spec->splitpath($child); next if index($file, ".") == 0; my $unpacked_key = $self->unpack_key($file); return $self->get($unpacked_key); }; } sub exists { my ($self, $id) = @_; my $path = $self->_path; my $packed_key = $self->pack_key($id); my $file = File::Spec->catfile($path, $packed_key); -f $file; } sub get { my ($self, $id) = @_; my $path = $self->_path; my $packed_key = $self->pack_key($id); my $file = File::Spec->catfile($path, $packed_key); return undef unless -f $file; my $stat = [stat($file)]; my $size = $stat->[7]; my $modified = $stat->[9]; my $created = $stat->[10]; # no real creation time exists on Unix my $content_type = content_type($id); return { _id => $id, size => $size, md5 => '', content_type => $content_type, created => $created, modified => $modified, _stream => sub { my $out = $_[0]; my $bytes = 0; my $data = IO::File->new($file, "r") || Catmandu::Error->throw("$file not readable"); Catmandu::Error->throw("no io defined or not writable") unless defined($out); while (!$data->eof) { my $buffer; $data->read($buffer, 1024); my $n = $out->syswrite($buffer); if (!defined($n) && $!{EAGAIN}) { # would block $n = 0; } elsif ($n != length $buffer) { $self->log->error("incomplete write"); } else { # all is ok } $bytes += $n; } $out->close(); $data->close(); $bytes; } }; } sub add { my ($self, $data) = @_; my $path = $self->_path; my $id = $data->{_id}; my $io = $data->{_stream}; return $self->get($id) unless $io; my $packed_key = $self->pack_key($id); my $file = File::Spec->catfile($path, $packed_key); if (Catmandu::Util::is_invocant($io)) { copy($io, $file) || Catmandu::Error->throw("failed to write file : $!"); } else { Catmandu::Util::write_file($file, $io) || Catmandu::Error->throw("failed to write file : $!"); } my $new_data = $self->get($id); $data->{$_} = $new_data->{$_} for keys %$new_data; 1; } sub delete { my ($self, $id) = @_; my $path = $self->_path; my $packed_key = $self->pack_key($id); my $file = File::Spec->catfile($path, $packed_key); return undef unless -f $file; unlink $file; } sub delete_all { my ($self) = @_; $self->each( sub { my $key = shift->{_id}; $self->delete($key); } ); 1; } sub drop { $_[0]->delete_all; } sub commit { return 1; } sub pack_key { my $self = shift; my $key = shift; utf8::encode($key); uri_escape($key); } sub unpack_key { my $self = shift; my $key = shift; my $str = uri_unescape($key); utf8::decode($str); $str; } 1; __END__ =pod =head1 NAME Catmandu::Store::File::Simple::Bag - Index of all "files" in a Catmandu::Store::File::Simple "folder" =head1 SYNOPSIS use Catmandu; my $store = Catmandu->store('File::Simple' , root => 't/data'); my $index = $store->index; # List all containers $index->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $index->add({_id => '1234'}); # Delete a folder $index->delete(1234); # Get a folder my $folder = $index->get(1234); # Get the files in an folder my $files = $index->files(1234); $files->each(sub { my $file = shift; my $name = $file->_id; my $size = $file->size; my $content_type = $file->content_type; my $created = $file->created; my $modified = $file->modified; $file->stream(IO::File->new(">/tmp/$name"), file); }); # Add a file $files->upload(IO::File->new("get("data.dat"); # Stream a file to an IO::Handle $files->stream(IO::File->new(">data.dat"),$file); # Delete a file $files->delete("data.dat"); # Delete a folders $index->delete("1234"); =head1 DESCRIPTION A L contains all "files" available in a L FileStore "folder". All methods of L, L and L are implemented. Every L is also an L. =head1 FOLDERS All files in a L are organized in "folders". To add a "folder" a new record needs to be added to the L : $index->add({_id => '1234'}); The C<_id> field is the only metadata available in Simple stores. To add more metadata fields to a Simple store a L is required. =head1 FILES Files can be accessed via the "folder" identifier: my $files = $index->files('1234'); Use the C method to add new files to a "folder". Use the C method to retrieve files from a "folder". $files->upload(IO::File->new("get('data.txt'); $files->download(IO::File->new(">/tmp/data.txt"),$file); =head1 INHERITED METHODS This Catmandu::Bag implements: =over 3 =item L =item L =item L =back =cut Index.pm100644000765000024 341013362073757 24233 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/File/Multipackage Catmandu::Store::File::Multi::Index; use Catmandu::Sane; our $VERSION = '1.13'; use Moo; use namespace::clean; extends 'Catmandu::Store::Multi::Bag'; with 'Catmandu::FileBag::Index'; 1; __END__ =pod =head1 NAME Catmandu::Store::File::Multi::Index - Index of all "Folders" in a Catmandu::Store::File::Multi =head1 SYNOPSIS use Catmandu; my $store = Catmandu->store('File::Multi' , stores [ Catmandu->store('File::Simple', root => '/data1/files') , Catmandu->store('File::Simple', root => '/data1/files_copy') , ]); my $index = $store->index; # List all containers $index->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $index->add({_id => '1234'}); # Delete a folder $index->delete(1234); # Get a folder my $folder = $index->get(1234); # Get the files in an folder my $files = $index->files(1234); $files->each(sub { my $file = shift; my $name = $file->_id; my $size = $file->size; my $content_type = $file->content_type; my $created = $file->created; my $modified = $file->modified; $file->stream(IO::File->new(">/tmp/$name"), file); }); # Add a file $files->upload(IO::File->new("get("data.dat"); # Stream a file to an IO::Handle $files->stream(IO::File->new(">data.dat"),$file); # Delete a file $files->delete("data.dat"); # Delete a folders $index->delete("1234"); =head1 INHERITED METHODS This Catmandu::Bag implements: =over 3 =item L =item L =item L =back =cut Index.pm100644000765000024 1032213362073757 24431 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/File/Memorypackage Catmandu::Store::File::Memory::Index; our $VERSION = '1.13'; use Catmandu::Sane; use Moo; use Carp; use namespace::clean; use Data::Dumper; with 'Catmandu::Bag'; with 'Catmandu::FileBag::Index'; with 'Catmandu::Droppable'; sub generator { my ($self) = @_; my $name = $self->name; my $containers = $self->store->_files->{$name} // {}; return sub { state $list = [keys %$containers]; my $key = pop @$list; return undef unless $key; +{_id => $key}; }; } sub exists { my ($self, $id) = @_; croak "Need an id" unless defined $id; my $name = $self->name; my $containers = $self->store->_files->{$name} // {}; return exists $containers->{$id}; } sub add { my ($self, $data) = @_; croak "Need an id" unless defined $data && exists $data->{_id}; my $id = $data->{_id}; if (exists $data->{_stream}) { croak "Can't add a file to the index"; } my $name = $self->name; $self->store->_files->{$name}->{$id} = +{_id => $id,}; my $new_data = $self->get($id); $data->{$_} = $new_data->{$_} for keys %$new_data; 1; } sub get { my ($self, $id) = @_; croak "Need an $id" unless defined $id; my $name = $self->name; my $containers = $self->store->_files->{$name} // {}; return $containers->{$id}; } sub delete { my ($self, $id) = @_; croak "Need an $id" unless defined $id; my $name = $self->name; my $containers = $self->store->_files->{$name} // {}; delete $containers->{$id}; 1; } sub delete_all { my ($self) = @_; $self->each( sub { my $id = shift->{_id}; $self->delete($id); } ); 1; } sub drop { $_[0]->delete_all; } 1; __END__ =pod =head1 NAME Catmandu::Store::File::Memory::Index - Index of all "Folders" in a Catmandu::Store::File::Memory =head1 SYNOPSIS use Catmandu; my $store = Catmandu->store('File::Memory'); my $index = $store->index; # List all containers $index->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $index->add({_id => '1234'}); # Delete a folder $index->delete(1234); # Get a folder my $folder = $index->get(1234); # Get the files in an folder my $files = $index->files(1234); $files->each(sub { my $file = shift; my $name = $file->_id; my $size = $file->size; my $content_type = $file->content_type; my $created = $file->created; my $modified = $file->modified; $file->stream(IO::File->new(">/tmp/$name"), file); }); # Add a file $files->upload(IO::File->new("get("data.dat"); # Stream a file to an IO::Handle $files->stream(IO::File->new(">data.dat"),$file); # Delete a file $files->delete("data.dat"); # Delete a folders $index->delete("1234"); =head1 DESCRIPTION A L contains all "folders" available in a L FileStore. All methods of L, L and L are implemented. Every L is also an L. =head1 FOLDERS All files in a L are organized in "folders". To add a "folder" a new record needs to be added to the L : $index->add({_id => '1234'}); The C<_id> field is the only metadata available in Memory stores. To add more metadata fields to a Memory store a L is required. =head1 FILES Files can be accessed via the "folder" identifier: my $files = $index->files('1234'); Use the C method to add new files to a "folder". Use the C method to retrieve files from a "folder". $files->upload(IO::File->new("get('data.txt'); $files->download(IO::File->new(">/tmp/data.txt"),$file); =head1 INHERITED METHODS This Catmandu::Bag implements: =over 3 =item L =item L =item L =back =cut Index.pm100644000765000024 761313362073757 24403 0ustar00hochstenstaff000000000000Catmandu-FileStore-1.13/lib/Catmandu/Store/File/Simplepackage Catmandu::Store::File::Simple::Index; our $VERSION = '1.13'; use Catmandu::Sane; use Moo; use Path::Tiny; use Carp; use namespace::clean; with 'Catmandu::Bag'; with 'Catmandu::FileBag::Index'; with 'Catmandu::Droppable'; sub generator { my ($self) = @_; return sub { state $iter = $self->store->directory_index()->generator(); my $mapping = $iter->(); return unless defined $mapping; $self->get($mapping->{_id}); }; } sub exists { my ($self, $id) = @_; croak "Need an id" unless defined $id; $self->log->debug("Checking exists $id"); defined($self->store->directory_index->get($id)); } sub add { my ($self, $data) = @_; croak "Need an id" unless defined $data && exists $data->{_id}; my $id = $data->{_id}; if (exists $data->{_stream}) { croak "Can't add a file to the index"; } $self->store->directory_index->add($id); } sub get { my ($self, $id) = @_; croak "Need an id" unless defined $id; my $mapping = $self->store->directory_index->get($id); defined($mapping) ? {_id => $id} : undef; } sub delete { my ($self, $id) = @_; croak "Need a key" unless defined $id; $self->store->directory_index->delete($id); } sub delete_all { my ($self) = @_; $self->store->directory_index->delete_all; } sub drop { $_[0]->delete_all; } sub commit { return 1; } 1; __END__ =pod =head1 NAME Catmandu::Store::File::Simple::Index - Index of all "Folders" in a Catmandu::Store::File::Simple =head1 SYNOPSIS use Catmandu; my $store = Catmandu->store('File::Simple' , root => 't/data'); my $index = $store->index; # List all containers $index->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $index->add({_id => '1234'}); # Delete a folder $index->delete(1234); # Get a folder my $folder = $index->get(1234); # Get the files in an folder my $files = $index->files(1234); $files->each(sub { my $file = shift; my $name = $file->_id; my $size = $file->size; my $content_type = $file->content_type; my $created = $file->created; my $modified = $file->modified; $file->stream(IO::File->new(">/tmp/$name"), file); }); # Add a file $files->upload(IO::File->new("get("data.dat"); # Stream a file to an IO::Handle $files->stream(IO::File->new(">data.dat"),$file); # Delete a file $files->delete("data.dat"); # Delete a folders $index->delete("1234"); =head1 DESCRIPTION A L contains all "folders" available in a L FileStore. All methods of L, L and L are implemented. Every L is also an L. =head1 FOLDERS All files in a L are organized in "folders". To add a "folder" a new record needs to be added to the L : $index->add({_id => '1234'}); The C<_id> field is the only metadata available in Simple stores. To add more metadata fields to a Simple store a L is required. =head1 FILES Files can be accessed via the "folder" identifier: my $files = $index->files('1234'); Use the C method to add new files to a "folder". Use the C method to retrieve files from a "folder". $files->upload(IO::File->new("get('data.txt'); $files->download(IO::File->new(">/tmp/data.txt"),$file); =head1 INHERITED METHODS This Catmandu::Bag implements: =over 3 =item L =item L =item L =back =cut