grape-1.0.2/0000755000004100000410000000000013231337007012637 5ustar www-datawww-datagrape-1.0.2/Rakefile0000644000004100000410000000104713231337007014306 0ustar www-datawww-datarequire 'rubygems' require 'bundler' Bundler.setup :default, :test, :development Bundler::GemHelper.install_tasks require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) do |spec| spec.pattern = 'spec/**/*_spec.rb' spec.exclude_pattern = 'spec/integration/**/*_spec.rb' end RSpec::Core::RakeTask.new(:rcov) do |spec| spec.pattern = 'spec/**/*_spec.rb' spec.rcov = true end task :spec require 'rainbow/ext/string' unless String.respond_to?(:color) require 'rubocop/rake_task' RuboCop::RakeTask.new task default: %i[rubocop spec] grape-1.0.2/Gemfile.lock0000644000004100000410000001227513231337007015070 0ustar www-datawww-dataPATH remote: . specs: grape (1.0.2) activesupport builder mustermann-grape (~> 1.0.0) rack (>= 1.3.0) rack-accept virtus (>= 1.0.0) GEM remote: https://rubygems.org/ specs: activesupport (5.1.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) appraisal (2.2.0) bundler rake thor (>= 0.14.0) ast (2.3.0) axiom-types (0.1.1) descendants_tracker (~> 0.0.4) ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) benchmark-ips (2.7.2) builder (3.2.3) claide (1.0.2) claide-plugins (0.9.2) cork nap open4 (~> 1.3) coderay (1.1.2) coercible (1.0.0) descendants_tracker (~> 0.0.1) colored (1.2) colored2 (3.1.2) concurrent-ruby (1.0.5) cookiejar (0.3.3) cork (0.3.0) colored2 (~> 3.1) coveralls (0.8.21) json (>= 1.8, < 3) simplecov (~> 0.14.1) term-ansicolor (~> 1.3) thor (~> 0.19.4) tins (~> 1.6) danger (4.0.5) claide (~> 1.0) claide-plugins (>= 0.9.2) colored (~> 1.2) cork (~> 0.1) faraday (~> 0.9) faraday-http-cache (~> 1.0) git (~> 1) kramdown (~> 1.5) octokit (~> 4.2) terminal-table (~> 1) danger-changelog (0.2.1) danger-plugin-api (~> 1.0) danger-plugin-api (1.0.0) danger (> 2.0) danger-toc (0.1.0) activesupport danger-plugin-api (~> 1.0) kramdown descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) diff-lcs (1.3) docile (1.1.5) equalizer (0.0.11) faraday (0.13.1) multipart-post (>= 1.2, < 3) faraday-http-cache (1.3.1) faraday (~> 0.8) ffi (1.9.18) formatador (0.2.5) git (1.3.0) grape-entity (0.6.1) activesupport (>= 5.0.0) multi_json (>= 1.3.2) guard (2.14.2) formatador (>= 0.2.4) listen (>= 2.7, < 4.0) lumberjack (>= 1.0.12, < 2.0) nenv (~> 0.1) notiffany (~> 0.0) pry (>= 0.9.12) shellany (~> 0.0) thor (>= 0.18.1) guard-compat (1.2.1) guard-rspec (4.7.3) guard (~> 2.1) guard-compat (~> 1.1) rspec (>= 2.99.0, < 4.0) guard-rubocop (1.3.0) guard (~> 2.0) rubocop (~> 0.20) hashie (3.5.7) i18n (0.9.1) concurrent-ruby (~> 1.0) ice_nine (0.11.2) json (2.1.0) kramdown (1.16.2) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) lumberjack (1.0.12) maruku (0.7.3) method_source (0.9.0) mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) minitest (5.11.1) multi_json (1.13.1) multipart-post (2.0.0) mustermann (1.0.1) mustermann-grape (1.0.0) mustermann (~> 1.0.0) nap (1.1.0) nenv (0.3.0) notiffany (0.1.1) nenv (~> 0.1) shellany (~> 0.0) octokit (4.8.0) sawyer (~> 0.8.0, >= 0.5.3) open4 (1.3.4) parallel (1.12.1) parser (2.4.0.2) ast (~> 2.3) powerpack (0.1.1) pry (0.11.3) coderay (~> 1.1.0) method_source (~> 0.9.0) public_suffix (3.0.1) rack (2.0.3) rack-accept (0.4.5) rack (>= 0.4) rack-jsonp (1.3.1) rack rack-test (0.6.3) rack (>= 1.0) rainbow (2.2.2) rake rake (12.3.0) rb-fsevent (0.10.2) rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) rspec (3.7.0) rspec-core (~> 3.7.0) rspec-expectations (~> 3.7.0) rspec-mocks (~> 3.7.0) rspec-core (3.7.1) rspec-support (~> 3.7.0) rspec-expectations (3.7.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) rspec-mocks (3.7.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) rspec-support (3.7.0) rubocop (0.51.0) parallel (~> 1.10) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 2.2.2, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) ruby-grape-danger (0.1.1) danger (~> 4.0.1) danger-changelog (~> 0.2.0) ruby-progressbar (1.9.0) ruby_dep (1.5.0) sawyer (0.8.1) addressable (>= 2.3.5, < 2.6) faraday (~> 0.8, < 1.0) shellany (0.0.1) simplecov (0.14.1) docile (~> 1.1.0) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) term-ansicolor (1.6.0) tins (~> 1.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) thor (0.19.4) thread_safe (0.3.6) tins (1.16.3) tzinfo (1.2.4) thread_safe (~> 0.1) unicode-display_width (1.3.0) virtus (1.0.5) axiom-types (~> 0.1) coercible (~> 1.0) descendants_tracker (~> 0.0, >= 0.0.3) equalizer (~> 0.0, >= 0.0.9) PLATFORMS ruby DEPENDENCIES appraisal benchmark-ips bundler cookiejar coveralls (~> 0.8.17) danger-toc (~> 0.1.0) grape! grape-entity (~> 0.6) guard guard-rspec guard-rubocop hashie maruku mime-types rack-jsonp rack-test (~> 0.6.3) rake rspec (~> 3.0) rubocop (= 0.51.0) ruby-grape-danger (~> 0.1.0) BUNDLED WITH 1.16.0 grape-1.0.2/UPGRADING.md0000644000004100000410000006747613231337007014525 0ustar www-datawww-dataUpgrading Grape =============== ### Upgrading to >= 1.0.0 #### Changes in XML and JSON Parsers Grape no longer uses `multi_json` or `multi_xml` by default and uses `JSON` and `ActiveSupport::XmlMini` instead. This has no visible impact on JSON processing, but the default behavior of the XML parser has changed. For example, an XML POST containing `Bobby T.` was parsed as `Bobby T.` with `multi_xml`, and as now parsed as `{"__content__"=>"Bobby T."}` with `XmlMini`. If you were using `MultiJson.load`, `MultiJson.dump` or `MultiXml.parse`, you can substitute those with `Grape::Json.load`, `Grape::Json.dump`, `::Grape::Xml.parse`, or directly with `JSON.load`, `JSON.dump`, `XmlMini.parse`, etc. To restore previous behavior, add `multi_json` or `multi_xml` to your `Gemfile` and `require` it. See [#1623](https://github.com/ruby-grape/grape/pull/1623) for more information. #### Changes in Parameter Class The default class for `params` has changed from `Hashie::Mash` to `ActiveSupport::HashWithIndifferentAccess` and the `hashie` dependency has been removed. This means that by default you can no longer access parameters by method name. ```ruby class API < Grape::API params do optional :color, type: String end get do params[:color] # use params[:color] instead of params.color end end ``` To restore the behavior of prior versions, add `hashie` to your `Gemfile` and `include Grape::Extensions::Hashie::Mash::ParamBuilder` in your API. ```ruby class API < Grape::API include Grape::Extensions::Hashie::Mash::ParamBuilder params do optional :color, type: String end get do # params.color works end end ``` This behavior can also be overridden on individual parameter blocks using `build_with`. ```ruby params do build_with Grape::Extensions::Hash::ParamBuilder optional :color, type: String end ``` If you're constructing your own `Grape::Request` in a middleware, you can pass different parameter handlers to create the desired `params` class with `build_params_with`. ```ruby def request Grape::Request.new(env, build_params_with: Grape::Extensions::Hashie::Mash::ParamBuilder) end ``` See [#1610](https://github.com/ruby-grape/grape/pull/1610) for more information. #### The `except`, `except_message`, and `proc` options of the `values` validator are deprecated. The new `except_values` validator should be used in place of the `except` and `except_message` options of the `values` validator. Arity one Procs may now be used directly as the `values` option to explicitly test param values. **Deprecated** ```ruby params do requires :a, values: { value: 0..99, except: [3] } requires :b, values: { value: 0..99, except: [3], except_message: 'not allowed' } requires :c, values: { except: ['admin'] } requires :d, values: { proc: -> (v) { v.even? } } end ``` **New** ```ruby params do requires :a, values: 0..99, except_values: [3] requires :b, values: 0..99, except_values: { value: [3], message: 'not allowed' } requires :c, except_values: ['admin'] requires :d, values: -> (v) { v.even? } end ``` See [#1616](https://github.com/ruby-grape/grape/pull/1616) for more information. ### Upgrading to >= 0.19.1 #### DELETE now defaults to status code 200 for responses with a body, or 204 otherwise Prior to this version, DELETE requests defaulted to a status code of 204 No Content, even when the response included content. This behavior confused some clients and prevented the formatter middleware from running properly. As of this version, DELETE requests will only default to a 204 No Content status code if no response body is provided, and will default to 200 OK otherwise. Specifically, DELETE behaviour has changed as follows: - In versions < 0.19.0, all DELETE requests defaulted to a 200 OK status code. - In version 0.19.0, all DELETE requests defaulted to a 204 No Content status code, even when content was included in the response. - As of version 0.19.1, DELETE requests default to a 204 No Content status code, unless content is supplied, in which case they default to a 200 OK status code. To achieve the old behavior, one can specify the status code explicitly: ```ruby delete :id do status 204 # or 200, for < 0.19.0 behavior 'foo successfully deleted' end ``` One can also use the new `return_no_content` helper to explicitly return a 204 status code and an empty body for any request type: ```ruby delete :id do return_no_content 'this will not be returned' end ``` See [#1550](https://github.com/ruby-grape/grape/pull/1550) for more information. ### Upgrading to >= 0.18.1 #### Changes in priority of :any routes Prior to this version, `:any` routes were searched after matching first route and 405 routes. This behavior has changed and `:any` routes are now searched before 405 processing. In the following example the `:any` route will match first when making a request with an unsupported verb. ```ruby post :example do 'example' end route :any, '*path' do error! :not_found, 404 end get '/example' #=> before: 405, after: 404 ``` #### Removed param processing from built-in OPTIONS handler When a request is made to the built-in `OPTIONS` handler, only the `before` and `after` callbacks associated with the resource will be run. The `before_validation` and `after_validation` callbacks and parameter validations will be skipped. See [#1505](https://github.com/ruby-grape/grape/pull/1505) for more information. #### Changed endpoint params validation Grape now correctly returns validation errors for all params when multiple params are passed to a requires. The following code will return `one is missing, two is missing` when calling the endpoint without parameters. ```ruby params do requires :one, :two end ``` Prior to this version the response would be `one is missing`. See [#1510](https://github.com/ruby-grape/grape/pull/1510) for more information. #### The default status code for DELETE is now 204 instead of 200. Breaking change: Sets the default response status code for a delete request to 204. A status of 204 makes the response more distinguishable and therefore easier to handle on the client side, particularly because a DELETE request typically returns an empty body as the resource was deleted or voided. To achieve the old behavior, one has to set it explicitly: ```ruby delete :id do status 200 'foo successfully deleted' end ``` For more information see: [#1532](https://github.com/ruby-grape/grape/pull/1532). ### Upgrading to >= 0.17.0 #### Removed official support for Ruby < 2.2.2 Grape is no longer automatically tested against versions of Ruby prior to 2.2.2. This is because of its dependency on activesupport which, with version 5.0.0, now requires at least Ruby 2.2.2. See [#1441](https://github.com/ruby-grape/grape/pull/1441) for nmore information. #### Changed priority of `rescue_from` clauses applying The `rescue_from` clauses declared inside a namespace would take a priority over ones declared in the root scope. This could possibly affect those users who use different `rescue_from` clauses in root scope and in namespaces. See [#1405](https://github.com/ruby-grape/grape/pull/1405) for more information. #### Helper methods injected inside `rescue_from` in middleware Helper methods are injected inside `rescue_from` may cause undesirable effects. For example, definining a helper method called `error!` will take precendence over the built-in `error!` method and should be renamed. See [#1451](https://github.com/ruby-grape/grape/issues/1451) for an example. ### Upgrading to >= 0.16.0 #### Replace rack-mount with new router The `Route#route_xyz` methods have been deprecated since 0.15.1. Please use `Route#xyz` instead. Note that the `Route#route_method` was replaced by `Route#request_method`. The following code would work correctly. ```ruby TwitterAPI::versions # yields [ 'v1', 'v2' ] TwitterAPI::routes # yields an array of Grape::Route objects TwitterAPI::routes[0].version # => 'v1' TwitterAPI::routes[0].description # => 'Includes custom settings.' TwitterAPI::routes[0].settings[:custom] # => { key: 'value' } TwitterAPI::routes[0].request_method # => 'GET' ``` #### `file` method accepts path to file Now to serve files via Grape just pass the path to the file. Functionality with FileStreamer-like objects is deprecated. Please, replace your FileStreamer-like objects with paths of served files. Old style: ```ruby class FileStreamer def initialize(file_path) @file_path = file_path end def each(&blk) File.open(@file_path, 'rb') do |file| file.each(10, &blk) end end end # ... class API < Grape::API get '/' do file FileStreamer.new('/path/to/file') end end ``` New style: ```ruby class API < Grape::API get '/' do file '/path/to/file' end end ``` ### Upgrading to >= 0.15.0 #### Changes to availability of `:with` option of `rescue_from` method The `:with` option of `rescue_from` does not accept value except Proc, String or Symbol now. If you have been depending the old behavior, you should use lambda block instead. ```ruby class API < Grape::API rescue_from :all, with: -> { Rack::Response.new('rescued with a method', 400) } end ``` #### Changes to behavior of `after` method of middleware on error The `after` method of the middleware is now also called on error. The following code would work correctly. ```ruby class ErrorMiddleware < Grape::Middleware::Base def after return unless @app_response && @app_response[0] == 500 env['rack.logger'].debug("Raised error on #{env['PATH_INFO']}") end end ``` See [#1147](https://github.com/ruby-grape/grape/issues/1147) and [#1240](https://github.com/ruby-grape/grape/issues/1240) for discussion of the issues. A warning will be logged if an exception is raised in an `after` callback, which points you to middleware that was not called in the previous version and is called now. ``` caught error of type NoMethodError in after callback inside Api::Middleware::SomeMiddleware : undefined method `headers' for nil:NilClass ``` See [#1285](https://github.com/ruby-grape/grape/pull/1285) for more information. #### Changes to Method Not Allowed routes A `405 Method Not Allowed` error now causes `Grape::Exceptions::MethodNotAllowed` to be raised, which will be rescued via `rescue_from :all`. Restore old behavior with the following error handler. ```ruby rescue_from Grape::Exceptions::MethodNotAllowed do |e| error! e.message, e.status, e.headers end ``` See [#1283](https://github.com/ruby-grape/grape/pull/1283) for more information. #### Changes to Grape::Exceptions::Validation parameters When raising `Grape::Exceptions::Validation` explicitly, replace `message_key` with `message`. For example, ```ruby fail Grape::Exceptions::Validation, params: [:oauth_token_secret], message_key: :presence ``` becomes ```ruby fail Grape::Exceptions::Validation, params: [:oauth_token_secret], message: :presence ``` See [#1295](https://github.com/ruby-grape/grape/pull/1295) for more information. ### Upgrading to >= 0.14.0 #### Changes to availability of DSL methods in filters The `#declared` method of the route DSL is no longer available in the `before` filter. Using `declared` in a `before` filter will now raise `Grape::DSL::InsideRoute::MethodNotYetAvailable`. See [#1074](https://github.com/ruby-grape/grape/issues/1074) for discussion of the issue. #### Changes to header versioning and invalid header version handling Identical endpoints with different versions now work correctly. A regression introduced in Grape 0.11.0 caused all but the first-mounted version for such an endpoint to wrongly throw an `InvalidAcceptHeader`. As a side effect, requests with a correct vendor but invalid version can no longer be rescued from a `rescue_from` block. See [#1114](https://github.com/ruby-grape/grape/pull/1114) for more information. #### Bypasses formatters when status code indicates no content To be consistent with rack and it's handling of standard responses associated with no content, both default and custom formatters will now be bypassed when processing responses for status codes defined [by rack](https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L567) See [#1190](https://github.com/ruby-grape/grape/pull/1190) for more information. #### Redirects respond as plain text with message `#redirect` now uses `text/plain` regardless of whether that format has been enabled. This prevents formatters from attempting to serialize the message body and allows for a descriptive message body to be provided - and optionally overridden - that better fulfills the theme of the HTTP spec. See [#1194](https://github.com/ruby-grape/grape/pull/1194) for more information. ### Upgrading to >= 0.12.0 #### Changes in middleware The Rack response object is no longer converted to an array by the formatter, enabling streaming. If your custom middleware is accessing `@app_response`, update it to expect a `Rack::Response` instance instead of an array. For example, ```ruby class CacheBusterMiddleware < Grape::Middleware::Base def after @app_response[1]['Expires'] = Time.at(0).utc.to_s @app_response end end ``` becomes ```ruby class CacheBusterMiddleware < Grape::Middleware::Base def after @app_response.headers['Expires'] = Time.at(0).utc.to_s @app_response end end ``` See [#1029](https://github.com/ruby-grape/grape/pull/1029) for more information. There is a known issue because of this change. When Grape is used with an older than 1.2.4 version of [warden](https://github.com/hassox/warden) there may be raised the following exception having the [rack-mount](https://github.com/jm/rack-mount) gem's lines as last ones in the backtrace: ``` NoMethodError: undefined method `[]' for nil:NilClass ``` The issue can be solved by upgrading warden to 1.2.4 version. See [#1151](https://github.com/ruby-grape/grape/issues/1151) for more information. #### Changes in present Using `present` with objects that responded to `merge` would cause early evaluation of the represented object, with unexpected side-effects, such as missing parameters or environment within rendering code. Grape now only merges represented objects with a previously rendered body, usually when multiple `present` calls are made in the same route. See [grape-with-roar#5](https://github.com/dblock/grape-with-roar/issues/5) and [#1023](https://github.com/ruby-grape/grape/issues/1023). #### Changes to regexp validator Parameters with `nil` value will now pass `regexp` validation. To disallow `nil` value for an endpoint, add `allow_blank: false`. ```ruby params do requires :email, allow_blank: false, regexp: /.+@.+/ end ``` See [#957](https://github.com/ruby-grape/grape/pull/957) for more information. #### Replace error_response with error! in rescue_from blocks Note: `error_response` is being deprecated, not removed. ```ruby def error!(message, status = options[:default_status], headers = {}, backtrace = []) headers = { 'Content-Type' => content_type }.merge(headers) rack_response(format_message(message, backtrace), status, headers) end ``` For example, ``` error_response({ message: { message: 'No such page.', id: 'missing_page' }, status: 404, headers: { 'Content-Type' => 'api/error' }) ``` becomes ``` error!({ message: 'No such page.', id: 'missing_page' }, 404, { 'Content-Type' => 'api/error' }) ``` `error!` also supports just passing a message. `error!('Server error.')` and `format: :json` returns the following JSON response ``` { 'error': 'Server error.' } ``` with a status code of 500 and a Content Type of text/error. Optionally, also replace `Rack::Response.new` with `error!.` The following are equivalent: ``` Rack::Response.new([ e.message ], 500, { "Content-type" => "text/error" }).finish error!(e) ``` See [#889](https://github.com/ruby-grape/grape/issues/889) for more information. #### Changes to routes when using `format` Version 0.10.0 has introduced a change via [#809](https://github.com/ruby-grape/grape/pull/809) whereas routes no longer got file-type suffixes added if you declared a single API `format`. This has been reverted, it's now again possible to call API with proper suffix when single `format` is defined: ```ruby class API < Grape::API format :json get :hello do { hello: 'world' } end end ``` Will respond with JSON to `/hello` **and** `/hello.json`. Will respond with 404 to `/hello.xml`, `/hello.txt` etc. See the [#1001](https://github.com/ruby-grape/grape/pull/1001) and [#914](https://github.com/ruby-grape/grape/issues/914) for more info. ### Upgrading to >= 0.11.0 #### Added Rack 1.6.0 support Grape now supports, but doesn't require Rack 1.6.0. If you encounter an issue with parsing requests larger than 128KB, explictly require Rack 1.6.0 in your Gemfile. ```ruby gem 'rack', '~> 1.6.0' ``` See [#559](https://github.com/ruby-grape/grape/issues/559) for more information. #### Removed route_info Key route_info is excluded from params. See [#879](https://github.com/ruby-grape/grape/pull/879) for more information. #### Fix callbacks within a version block Callbacks defined in a version block are only called for the routes defined in that block. This was a regression introduced in Grape 0.10.0, and is fixed in this version. See [#901](https://github.com/ruby-grape/grape/pull/901) for more information. #### Make type of group of parameters required Groups of parameters now require their type to be set explicitly as Array or Hash. Not setting the type now results in MissingGroupTypeError, unsupported type will raise UnsupportedTypeError. See [#886](https://github.com/ruby-grape/grape/pull/886) for more information. ### Upgrading to >= 0.10.1 #### Changes to `declared(params, include_missing: false)` Attributes with `nil` values or with values that evaluate to `false` are no longer considered *missing* and will be returned when `include_missing` is set to `false`. See [#864](https://github.com/ruby-grape/grape/pull/864) for more information. ### Upgrading to >= 0.10.0 #### Changes to content-types The following content-types have been removed: * atom (application/atom+xml) * rss (application/rss+xml) * jsonapi (application/jsonapi) This is because they have never been properly supported. #### Changes to desc New block syntax: Former: ```ruby desc "some descs", detail: 'more details', entity: API::Entities::Entity, params: API::Entities::Status.documentation, named: 'a name', headers: [XAuthToken: { description: 'Valdates your identity', required: true } get nil, http_codes: [ [401, 'Unauthorized', API::Entities::BaseError], [404, 'not found', API::Entities::Error] ] do ``` Now: ```ruby desc "some descs" do detail 'more details' params API::Entities::Status.documentation success API::Entities::Entity failure [ [401, 'Unauthorized', API::Entities::BaseError], [404, 'not found', API::Entities::Error] ] named 'a name' headers [ XAuthToken: { description: 'Valdates your identity', required: true }, XOptionalHeader: { description: 'Not really needed', required: false } ] end ``` #### Changes to Route Options and Descriptions A common hack to extend Grape with custom DSL methods was manipulating `@last_description`. ``` ruby module Grape module Extensions module SortExtension def sort(value) @last_description ||= {} @last_description[:sort] ||= {} @last_description[:sort].merge! value value end end Grape::API.extend self end end ``` You could access this value from within the API with `route.route_sort` or, more generally, via `env['api.endpoint'].options[:route_options][:sort]`. This will no longer work, use the documented and supported `route_setting`. ``` ruby module Grape module Extensions module SortExtension def sort(value) route_setting :sort, sort: value value end end Grape::API.extend self end end ``` To retrieve this value at runtime from within an API, use `env['api.endpoint'].route_setting(:sort)` and when introspecting a mounted API, use `route.route_settings[:sort]`. #### Accessing Class Variables from Helpers It used to be possible to fetch an API class variable from a helper function. For example: ```ruby @@static_variable = 42 helpers do def get_static_variable @@static_variable end end get do get_static_variable end ``` This will no longer work. Use a class method instead of a helper. ```ruby @@static_variable = 42 def self.get_static_variable @@static_variable end get do get_static_variable end ``` For more information see [#836](https://github.com/ruby-grape/grape/issues/836). #### Changes to Custom Validators To implement a custom validator, you need to inherit from `Grape::Validations::Base` instead of `Grape::Validations::Validator`. For more information see [Custom Validators](https://github.com/ruby-grape/grape#custom-validators) in the documentation. #### Changes to Raising Grape::Exceptions::Validation In previous versions raising `Grape::Exceptions::Validation` required a single `param`. ```ruby raise Grape::Exceptions::Validation, param: :id, message_key: :presence ``` The `param` argument has been deprecated and is now an array of `params`, accepting multiple values. ```ruby raise Grape::Exceptions::Validation, params: [:id], message_key: :presence ``` #### Changes to routes when using `format` Routes will no longer get file-type suffixes added if you declare a single API `format`. For example, ```ruby class API < Grape::API format :json get :hello do { hello: 'world' } end end ``` Pre-0.10.0, this would respond with JSON to `/hello`, `/hello.json`, `/hello.xml`, `/hello.txt`, etc. Now, this will only respond with JSON to `/hello`, but will be a 404 when trying to access `/hello.json`, `/hello.xml`, `/hello.txt`, etc. If you declare further `content_type`s, this behavior will be circumvented. For example, the following API will respond with JSON to `/hello`, `/hello.json`, `/hello.xml`, `/hello.txt`, etc. ```ruby class API < Grape::API format :json content_type :json, 'application/json' get :hello do { hello: 'world' } end end ``` See the [the updated API Formats documentation](https://github.com/ruby-grape/grape#api-formats) and [#809](https://github.com/ruby-grape/grape/pull/809) for more info. #### Changes to Evaluation of Permitted Parameter Values Permitted and default parameter values are now only evaluated lazily for each request when declared as a proc. The following code would raise an error at startup time. ```ruby params do optional :v, values: -> { [:x, :y] }, default: -> { :z } end ``` Remove the proc to get the previous behavior. ```ruby params do optional :v, values: [:x, :y], default: :z end ``` See [#801](https://github.com/ruby-grape/grape/issues/801) for more information. #### Changes to version If version is used with a block, the callbacks defined within that version block are not scoped to that individual block. In other words, the callback would be inherited by all versions blocks that follow the first one e.g ```ruby class API < Grape::API resource :foo do version 'v1', :using => :path do before do @output ||= 'hello1' end get '/' do @output += '-v1' end end version 'v2', :using => :path do before do @output ||= 'hello2' end get '/:id' do @output += '-v2' end end end end ``` when making a API call `GET /foo/v2/1`, the API would set instance variable `@output` to `hello1-v2` See [#898](https://github.com/ruby-grape/grape/issues/898) for more information. ### Upgrading to >= 0.9.0 #### Changes in Authentication The following middleware classes have been removed: * `Grape::Middleware::Auth::Basic` * `Grape::Middleware::Auth::Digest` * `Grape::Middleware::Auth::OAuth2` When you use theses classes directly like: ```ruby module API class Root < Grape::API class Protected < Grape::API use Grape::Middleware::Auth::OAuth2, token_class: 'AccessToken', parameter: %w(access_token api_key) ``` you have to replace these classes. As replacement can be used * `Grape::Middleware::Auth::Basic` => [`Rack::Auth::Basic`](https://github.com/rack/rack/blob/master/lib/rack/auth/basic.rb) * `Grape::Middleware::Auth::Digest` => [`Rack::Auth::Digest::MD5`](https://github.com/rack/rack/blob/master/lib/rack/auth/digest/md5.rb) * `Grape::Middleware::Auth::OAuth2` => [warden-oauth2](https://github.com/opperator/warden-oauth2) or [rack-oauth2](https://github.com/nov/rack-oauth2) If this is not possible you can extract the middleware files from [grape v0.7.0](https://github.com/ruby-grape/grape/tree/v0.7.0/lib/grape/middleware/auth) and host these files within your application See [#703](https://github.com/ruby-grape/Grape/pull/703) for more information. ### Upgrading to >= 0.7.0 #### Changes in Exception Handling Assume you have the following exception classes defined. ```ruby class ParentError < StandardError; end class ChildError < ParentError; end ``` In Grape <= 0.6.1, the `rescue_from` keyword only handled the exact exception being raised. The following code would rescue `ParentError`, but not `ChildError`. ```ruby rescue_from ParentError do |e| # only rescue ParentError end ``` This made it impossible to rescue an exception hieararchy, which is a more sensible default. In Grape 0.7.0 or newer, both `ParentError` and `ChildError` are rescued. ```ruby rescue_from ParentError do |e| # rescue both ParentError and ChildError end ``` To only rescue the base exception class, set `rescue_subclasses: false`. ```ruby rescue_from ParentError, rescue_subclasses: false do |e| # only rescue ParentError end ``` See [#544](https://github.com/ruby-grape/grape/pull/544) for more information. #### Changes in the Default HTTP Status Code In Grape <= 0.6.1, the default status code returned from `error!` was 403. ```ruby error! "You may not reticulate this spline!" # yields HTTP error 403 ``` This was a bad default value, since 403 means "Forbidden". Change any call to `error!` that does not specify a status code to specify one. The new default value is a more sensible default of 500, which is "Internal Server Error". ```ruby error! "You may not reticulate this spline!", 403 # yields HTTP error 403 ``` You may also use `default_error_status` to change the global default. ```ruby default_error_status 400 ``` See [#525](https://github.com/ruby-grape/Grape/pull/525) for more information. #### Changes in Parameter Declaration and Validation In Grape <= 0.6.1, `group`, `optional` and `requires` keywords with a block accepted either an `Array` or a `Hash`. ```ruby params do requires :id, type: Integer group :name do requires :first_name requires :last_name end end ``` This caused the ambiguity and unexpected errors described in [#543](https://github.com/ruby-grape/Grape/issues/543). In Grape 0.7.0, the `group`, `optional` and `requires` keywords take an additional `type` attribute which defaults to `Array`. This means that without a `type` attribute, these nested parameters will no longer accept a single hash, only an array (of hashes). Whereas in 0.6.1 the API above accepted the following json, it no longer does in 0.7.0. ```json { "id": 1, "name": { "first_name": "John", "last_name" : "Doe" } } ``` The `params` block should now read as follows. ```ruby params do requires :id, type: Integer requires :name, type: Hash do requires :first_name requires :last_name end end ``` See [#545](https://github.com/ruby-grape/Grape/pull/545) for more information. ### Upgrading to 0.6.0 In Grape <= 0.5.0, only the first validation error was raised and processing aborted. Validation errors are now collected and a single `Grape::Exceptions::ValidationErrors` exception is raised. You can access the collection of validation errors as `.errors`. ```ruby rescue_from Grape::Exceptions::Validations do |e| Rack::Response.new({ status: 422, message: e.message, errors: e.errors }.to_json, 422) end ``` For more information see [#462](https://github.com/ruby-grape/grape/issues/462). grape-1.0.2/Gemfile0000644000004100000410000000124713231337007014136 0ustar www-datawww-data# when changing this file, run appraisal install ; rubocop -a gemfiles/*.gemfile source 'https://rubygems.org' gemspec group :development, :test do gem 'bundler' gem 'hashie' gem 'rake' gem 'rubocop', '0.51.0' end group :development do gem 'appraisal' gem 'benchmark-ips' gem 'guard' gem 'guard-rspec' gem 'guard-rubocop' end group :test do gem 'cookiejar' gem 'coveralls', '~> 0.8.17', require: false gem 'danger-toc', '~> 0.1.0' gem 'grape-entity', '~> 0.6' gem 'maruku' gem 'mime-types' gem 'rack-jsonp', require: 'rack/jsonp' gem 'rack-test', '~> 0.6.3' gem 'rspec', '~> 3.0' gem 'ruby-grape-danger', '~> 0.1.0', require: false end grape-1.0.2/Dangerfile0000644000004100000410000000007513231337007014624 0ustar www-datawww-datadanger.import_dangerfile(gem: 'ruby-grape-danger') toc.check grape-1.0.2/grape.gemspec0000644000004100000410000000165113231337007015305 0ustar www-datawww-data$LOAD_PATH.push File.expand_path('../lib', __FILE__) require 'grape/version' Gem::Specification.new do |s| s.name = 'grape' s.version = Grape::VERSION s.platform = Gem::Platform::RUBY s.authors = ['Michael Bleigh'] s.email = ['michael@intridea.com'] s.homepage = 'https://github.com/ruby-grape/grape' s.summary = 'A simple Ruby framework for building REST-like APIs.' s.description = 'A Ruby framework for rapid API development with great conventions.' s.license = 'MIT' s.add_runtime_dependency 'activesupport' s.add_runtime_dependency 'builder' s.add_runtime_dependency 'mustermann-grape', '~> 1.0.0' s.add_runtime_dependency 'rack', '>= 1.3.0' s.add_runtime_dependency 'rack-accept' s.add_runtime_dependency 'virtus', '>= 1.0.0' s.files = Dir['**/*'].keep_if { |file| File.file?(file) } s.test_files = Dir['spec/**/*'] s.require_paths = ['lib'] end grape-1.0.2/spec/0000755000004100000410000000000013231337007013571 5ustar www-datawww-datagrape-1.0.2/spec/grape/0000755000004100000410000000000013231337007014667 5ustar www-datawww-datagrape-1.0.2/spec/grape/middleware/0000755000004100000410000000000013231337007017004 5ustar www-datawww-datagrape-1.0.2/spec/grape/middleware/exception_spec.rb0000644000004100000410000002105513231337007022344 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Error do # raises a text exception module ExceptionSpec class ExceptionApp class << self def call(_env) raise 'rain!' end end end # raises a non-StandardError (ScriptError) exception class OtherExceptionApp class << self def call(_env) raise NotImplementedError, 'snow!' end end end # raises a hash error class ErrorHashApp class << self def error!(message, status) throw :error, message: { error: message, detail: 'missing widget' }, status: status end def call(_env) error!('rain!', 401) end end end # raises an error! class AccessDeniedApp class << self def error!(message, status) throw :error, message: message, status: status end def call(_env) error!('Access Denied', 401) end end end # raises a custom error class CustomError < Grape::Exceptions::Base end class CustomErrorApp class << self def call(_env) raise CustomError, status: 400, message: 'failed validation' end end end end def app subject end context 'with defaults' do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error run ExceptionSpec::ExceptionApp end end it 'does not trap errors by default' do expect { get '/' }.to raise_error(RuntimeError, 'rain!') end end context 'with rescue_all' do context 'StandardError exception' do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true run ExceptionSpec::ExceptionApp end end it 'sets the message appropriately' do get '/' expect(last_response.body).to eq('rain!') end it 'defaults to a 500 status' do get '/' expect(last_response.status).to eq(500) end end context 'Non-StandardError exception' do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true run ExceptionSpec::OtherExceptionApp end end it 'does not trap errors other than StandardError' do expect { get '/' }.to raise_error(NotImplementedError, 'snow!') end end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, default_status: 500 run ExceptionSpec::ExceptionApp end end it 'is possible to specify a different default status code' do get '/' expect(last_response.status).to eq(500) end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, format: :json run ExceptionSpec::ExceptionApp end end it 'is possible to return errors in json format' do get '/' expect(last_response.body).to eq('{"error":"rain!"}') end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, format: :json run ExceptionSpec::ErrorHashApp end end it 'is possible to return hash errors in json format' do get '/' expect(['{"error":"rain!","detail":"missing widget"}', '{"detail":"missing widget","error":"rain!"}']).to include(last_response.body) end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, format: :jsonapi run ExceptionSpec::ExceptionApp end end it 'is possible to return errors in jsonapi format' do get '/' expect(last_response.body).to eq('{"error":"rain!"}') end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, format: :jsonapi run ExceptionSpec::ErrorHashApp end end it 'is possible to return hash errors in jsonapi format' do get '/' expect(['{"error":"rain!","detail":"missing widget"}', '{"detail":"missing widget","error":"rain!"}']).to include(last_response.body) end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, format: :xml run ExceptionSpec::ExceptionApp end end it 'is possible to return errors in xml format' do get '/' expect(last_response.body).to eq("\n\n rain!\n\n") end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, format: :xml run ExceptionSpec::ErrorHashApp end end it 'is possible to return hash errors in xml format' do get '/' expect(["\n\n missing widget\n rain!\n\n", "\n\n rain!\n missing widget\n\n"]).to include(last_response.body) end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, format: :custom, error_formatters: { custom: lambda do |message, _backtrace, _options, _env, _original_exception| { custom_formatter: message }.inspect end } run ExceptionSpec::ExceptionApp end end it 'is possible to specify a custom formatter' do get '/' expect(last_response.body).to eq('{:custom_formatter=>"rain!"}') end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error run ExceptionSpec::AccessDeniedApp end end it 'does not trap regular error! codes' do get '/' expect(last_response.status).to eq(401) end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: false run ExceptionSpec::CustomErrorApp end end it 'responds to custom Grape exceptions appropriately' do get '/' expect(last_response.status).to eq(400) expect(last_response.body).to eq('failed validation') end end context 'with rescue_options :backtrace and :exception set to true' do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, format: :json, rescue_options: { backtrace: true, original_exception: true } run ExceptionSpec::ExceptionApp end end it 'is possible to return the backtrace and the original exception in json format' do get '/' expect(last_response.body).to include('error', 'rain!', 'backtrace', 'original_exception', 'RuntimeError') end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, format: :xml, rescue_options: { backtrace: true, original_exception: true } run ExceptionSpec::ExceptionApp end end it 'is possible to return the backtrace and the original exception in xml format' do get '/' expect(last_response.body).to include('error', 'rain!', 'backtrace', 'original-exception', 'RuntimeError') end end context do subject do Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, rescue_all: true, format: :txt, rescue_options: { backtrace: true, original_exception: true } run ExceptionSpec::ExceptionApp end end it 'is possible to return the backtrace and the original exception in txt format' do get '/' expect(last_response.body).to include('error', 'rain!', 'backtrace', 'original exception', 'RuntimeError') end end end grape-1.0.2/spec/grape/middleware/versioner/0000755000004100000410000000000013231337007021020 5ustar www-datawww-datagrape-1.0.2/spec/grape/middleware/versioner/header_spec.rb0000644000004100000410000002576413231337007023625 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Versioner::Header do let(:app) { ->(env) { [200, env, env] } } subject { Grape::Middleware::Versioner::Header.new(app, @options || {}) } before do @options = { version_options: { using: :header, vendor: 'vendor' } } end context 'api.type and api.subtype' do it 'sets type and subtype to first choice of content type if no preference given' do status, _, env = subject.call('HTTP_ACCEPT' => '*/*') expect(env['api.type']).to eql 'application' expect(env['api.subtype']).to eql 'vnd.vendor+xml' expect(status).to eq(200) end it 'sets preferred type' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/*') expect(env['api.type']).to eql 'application' expect(env['api.subtype']).to eql 'vnd.vendor+xml' expect(status).to eq(200) end it 'sets preferred type and subtype' do status, _, env = subject.call('HTTP_ACCEPT' => 'text/plain') expect(env['api.type']).to eql 'text' expect(env['api.subtype']).to eql 'plain' expect(status).to eq(200) end end context 'api.format' do it 'is set' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor+json') expect(env['api.format']).to eql 'json' expect(status).to eq(200) end it 'is nil if not provided' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor') expect(env['api.format']).to eql nil expect(status).to eq(200) end ['v1', :v1].each do |version| context "when version is set to #{version}" do before do @options[:versions] = [version] end it 'is set' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json') expect(env['api.format']).to eql 'json' expect(status).to eq(200) end it 'is nil if not provided' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1') expect(env['api.format']).to eql nil expect(status).to eq(200) end end end end context 'api.vendor' do it 'is set' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor') expect(env['api.vendor']).to eql 'vendor' expect(status).to eq(200) end it 'is set if format provided' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor+json') expect(env['api.vendor']).to eql 'vendor' expect(status).to eq(200) end it 'fails with 406 Not Acceptable if vendor is invalid' do expect { subject.call('HTTP_ACCEPT' => 'application/vnd.othervendor+json').last } .to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql('X-Cascade' => 'pass') expect(exception.status).to eql 406 expect(exception.message).to include 'API vendor not found' end end context 'when version is set' do before do @options[:versions] = ['v1'] end it 'is set' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1') expect(env['api.vendor']).to eql 'vendor' expect(status).to eq(200) end it 'is set if format provided' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json') expect(env['api.vendor']).to eql 'vendor' expect(status).to eq(200) end it 'fails with 406 Not Acceptable if vendor is invalid' do expect { subject.call('HTTP_ACCEPT' => 'application/vnd.othervendor-v1+json').last } .to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql('X-Cascade' => 'pass') expect(exception.status).to eql 406 expect(exception.message).to include('API vendor not found') end end end end context 'api.version' do before do @options[:versions] = ['v1'] end it 'is set' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1') expect(env['api.version']).to eql 'v1' expect(status).to eq(200) end it 'is set if format provided' do status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json') expect(env['api.version']).to eql 'v1' expect(status).to eq(200) end it 'fails with 406 Not Acceptable if version is invalid' do expect { subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v2+json').last }.to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidVersionHeader) expect(exception.headers).to eql('X-Cascade' => 'pass') expect(exception.status).to eql 406 expect(exception.message).to include('API version not found') end end end it 'succeeds if :strict is not set' do expect(subject.call('HTTP_ACCEPT' => '').first).to eq(200) expect(subject.call({}).first).to eq(200) end it 'succeeds if :strict is set to false' do @options[:version_options][:strict] = false expect(subject.call('HTTP_ACCEPT' => '').first).to eq(200) expect(subject.call({}).first).to eq(200) end context 'when :strict is set' do before do @options[:versions] = ['v1'] @options[:version_options][:strict] = true end it 'fails with 406 Not Acceptable if header is not set' do expect { subject.call({}).last }.to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql('X-Cascade' => 'pass') expect(exception.status).to eql 406 expect(exception.message).to include('Accept header must be set.') end end it 'fails with 406 Not Acceptable if header is empty' do expect { subject.call('HTTP_ACCEPT' => '').last }.to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql('X-Cascade' => 'pass') expect(exception.status).to eql 406 expect(exception.message).to include('Accept header must be set.') end end it 'succeeds if proper header is set' do expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first).to eq(200) end end context 'when :strict and cascade: false' do before do @options[:versions] = ['v1'] @options[:version_options][:strict] = true @options[:version_options][:cascade] = false end it 'fails with 406 Not Acceptable if header is not set' do expect { subject.call({}).last }.to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql({}) expect(exception.status).to eql 406 expect(exception.message).to include('Accept header must be set.') end end it 'fails with 406 Not Acceptable if header is application/xml' do expect { subject.call('HTTP_ACCEPT' => 'application/xml').last } .to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql({}) expect(exception.status).to eql 406 expect(exception.message).to include('API vendor or version not found.') end end it 'fails with 406 Not Acceptable if header is empty' do expect { subject.call('HTTP_ACCEPT' => '').last }.to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql({}) expect(exception.status).to eql 406 expect(exception.message).to include('Accept header must be set.') end end it 'fails with 406 Not Acceptable if header contains a single invalid accept' do expect { subject.call('HTTP_ACCEPT' => 'application/json;application/vnd.vendor-v1+json').first } .to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader) expect(exception.headers).to eql({}) expect(exception.status).to eql 406 expect(exception.message).to include('API vendor or version not found.') end end it 'succeeds if proper header is set' do expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first).to eq(200) end end context 'when multiple versions are specified' do before do @options[:versions] = %w[v1 v2] end it 'succeeds with v1' do expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first).to eq(200) end it 'succeeds with v2' do expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v2+json').first).to eq(200) end it 'fails with another version' do expect { subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v3+json') }.to raise_exception do |exception| expect(exception).to be_a(Grape::Exceptions::InvalidVersionHeader) expect(exception.headers).to eql('X-Cascade' => 'pass') expect(exception.status).to eql 406 expect(exception.message).to include('API version not found') end end end context 'when there are multiple versions with complex vendor specified with rescue_from :all' do subject do Class.new(Grape::API) do rescue_from :all end end let(:v1_app) do Class.new(Grape::API) do version 'v1', using: :header, vendor: 'test.a-cool_resource', cascade: false, strict: true content_type :v1_test, 'application/vnd.test.a-cool_resource-v1+json' formatter :v1_test, ->(object, _) { object } format :v1_test resources :users do get :hello do 'one' end end end end let(:v2_app) do Class.new(Grape::API) do version 'v2', using: :header, vendor: 'test.a-cool_resource', strict: true content_type :v2_test, 'application/vnd.test.a-cool_resource-v2+json' formatter :v2_test, ->(object, _) { object } format :v2_test resources :users do get :hello do 'two' end end end end def app subject.mount v2_app subject.mount v1_app subject end context 'with header versioned endpoints and a rescue_all block defined' do it 'responds correctly to a v1 request' do versioned_get '/users/hello', 'v1', using: :header, vendor: 'test.a-cool_resource' expect(last_response.body).to eq('one') expect(last_response.body).not_to include('API vendor or version not found') end it 'responds correctly to a v2 request' do versioned_get '/users/hello', 'v2', using: :header, vendor: 'test.a-cool_resource' expect(last_response.body).to eq('two') expect(last_response.body).not_to include('API vendor or version not found') end end end end grape-1.0.2/spec/grape/middleware/versioner/path_spec.rb0000644000004100000410000000364013231337007023316 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Versioner::Path do let(:app) { ->(env) { [200, env, env['api.version']] } } let(:options) { {} } subject { Grape::Middleware::Versioner::Path.new(app, options) } it 'sets the API version based on the first path' do expect(subject.call('PATH_INFO' => '/v1/awesome').last).to eq('v1') end it 'does not cut the version out of the path' do expect(subject.call('PATH_INFO' => '/v1/awesome')[1]['PATH_INFO']).to eq('/v1/awesome') end it 'provides a nil version if no path is given' do expect(subject.call('PATH_INFO' => '/').last).to be_nil end context 'with a pattern' do let(:options) { { pattern: /v./i } } it 'sets the version if it matches' do expect(subject.call('PATH_INFO' => '/v1/awesome').last).to eq('v1') end it 'ignores the version if it fails to match' do expect(subject.call('PATH_INFO' => '/awesome/radical').last).to be_nil end end [%w[v1 v2], %i[v1 v2], [:v1, 'v2'], ['v1', :v2]].each do |versions| context "with specified versions as #{versions}" do let(:options) { { versions: versions } } it 'throws an error if a non-allowed version is specified' do expect(catch(:error) { subject.call('PATH_INFO' => '/v3/awesome') }[:status]).to eq(404) end it 'allows versions that have been specified' do expect(subject.call('PATH_INFO' => '/v1/asoasd').last).to eq('v1') end end end context 'with prefix, but requested version is not matched' do let(:options) { { prefix: '/v1', pattern: /v./i } } it 'recognizes potential version' do expect(subject.call('PATH_INFO' => '/v3/foo').last).to eq('v3') end end context 'with mount path' do let(:options) { { mount_path: '/mounted', versions: [:v1] } } it 'recognizes potential version' do expect(subject.call('PATH_INFO' => '/mounted/v1/foo').last).to eq('v1') end end end grape-1.0.2/spec/grape/middleware/versioner/accept_version_header_spec.rb0000644000004100000410000000630413231337007026676 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Versioner::AcceptVersionHeader do let(:app) { ->(env) { [200, env, env] } } subject { Grape::Middleware::Versioner::AcceptVersionHeader.new(app, @options || {}) } before do @options = { version_options: { using: :accept_version_header } } end context 'api.version' do before do @options[:versions] = ['v1'] end it 'is set' do status, _, env = subject.call('HTTP_ACCEPT_VERSION' => 'v1') expect(env['api.version']).to eql 'v1' expect(status).to eq(200) end it 'is set if format provided' do status, _, env = subject.call('HTTP_ACCEPT_VERSION' => 'v1') expect(env['api.version']).to eql 'v1' expect(status).to eq(200) end it 'fails with 406 Not Acceptable if version is not supported' do expect do subject.call('HTTP_ACCEPT_VERSION' => 'v2').last end.to throw_symbol( :error, status: 406, headers: { 'X-Cascade' => 'pass' }, message: 'The requested version is not supported.' ) end end it 'succeeds if :strict is not set' do expect(subject.call('HTTP_ACCEPT_VERSION' => '').first).to eq(200) expect(subject.call({}).first).to eq(200) end it 'succeeds if :strict is set to false' do @options[:version_options][:strict] = false expect(subject.call('HTTP_ACCEPT_VERSION' => '').first).to eq(200) expect(subject.call({}).first).to eq(200) end context 'when :strict is set' do before do @options[:versions] = ['v1'] @options[:version_options][:strict] = true end it 'fails with 406 Not Acceptable if header is not set' do expect do subject.call({}).last end.to throw_symbol( :error, status: 406, headers: { 'X-Cascade' => 'pass' }, message: 'Accept-Version header must be set.' ) end it 'fails with 406 Not Acceptable if header is empty' do expect do subject.call('HTTP_ACCEPT_VERSION' => '').last end.to throw_symbol( :error, status: 406, headers: { 'X-Cascade' => 'pass' }, message: 'Accept-Version header must be set.' ) end it 'succeeds if proper header is set' do expect(subject.call('HTTP_ACCEPT_VERSION' => 'v1').first).to eq(200) end end context 'when :strict and cascade: false' do before do @options[:versions] = ['v1'] @options[:version_options][:strict] = true @options[:version_options][:cascade] = false end it 'fails with 406 Not Acceptable if header is not set' do expect do subject.call({}).last end.to throw_symbol( :error, status: 406, headers: {}, message: 'Accept-Version header must be set.' ) end it 'fails with 406 Not Acceptable if header is empty' do expect do subject.call('HTTP_ACCEPT_VERSION' => '').last end.to throw_symbol( :error, status: 406, headers: {}, message: 'Accept-Version header must be set.' ) end it 'succeeds if proper header is set' do expect(subject.call('HTTP_ACCEPT_VERSION' => 'v1').first).to eq(200) end end end grape-1.0.2/spec/grape/middleware/versioner/param_spec.rb0000644000004100000410000001227413231337007023465 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Versioner::Param do let(:app) { ->(env) { [200, env, env['api.version']] } } let(:options) { {} } subject { Grape::Middleware::Versioner::Param.new(app, options) } it 'sets the API version based on the default param (apiver)' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' }) expect(subject.call(env)[1]['api.version']).to eq('v1') end it 'cuts (only) the version out of the params' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1', 'other_param' => '5' }) env['rack.request.query_hash'] = Rack::Utils.parse_nested_query(env['QUERY_STRING']) expect(subject.call(env)[1]['rack.request.query_hash']['apiver']).to be_nil expect(subject.call(env)[1]['rack.request.query_hash']['other_param']).to eq('5') end it 'provides a nil version if no version is given' do env = Rack::MockRequest.env_for('/') expect(subject.call(env).last).to be_nil end context 'with specified parameter name' do let(:options) { { version_options: { parameter: 'v' } } } it 'sets the API version based on the custom parameter name' do env = Rack::MockRequest.env_for('/awesome', params: { 'v' => 'v1' }) expect(subject.call(env)[1]['api.version']).to eq('v1') end it 'does not set the API version based on the default param' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' }) expect(subject.call(env)[1]['api.version']).to be_nil end end context 'with specified versions' do let(:options) { { versions: %w[v1 v2] } } it 'throws an error if a non-allowed version is specified' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v3' }) expect(catch(:error) { subject.call(env) }[:status]).to eq(404) end it 'allows versions that have been specified' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' }) expect(subject.call(env)[1]['api.version']).to eq('v1') end end context 'when no version is set' do let(:options) do { versions: ['v1'], version_options: { using: :header } } end it 'returns a 200 (matches the first version found)' do env = Rack::MockRequest.env_for('/awesome', params: {}) expect(subject.call(env).first).to eq(200) end end context 'when there are multiple versions without a custom param' do subject { Class.new(Grape::API) } let(:v1_app) do Class.new(Grape::API) do version 'v1', using: :param content_type :v1_test, 'application/vnd.test.a-cool_resource-v1+json' formatter :v1_test, ->(object, _) { object } format :v1_test resources :users do get :hello do 'one' end end end end let(:v2_app) do Class.new(Grape::API) do version 'v2', using: :param content_type :v2_test, 'application/vnd.test.a-cool_resource-v2+json' formatter :v2_test, ->(object, _) { object } format :v2_test resources :users do get :hello do 'two' end end end end def app subject.mount v2_app subject.mount v1_app subject end it 'responds correctly to a v1 request' do versioned_get '/users/hello', 'v1', using: :param, parameter: :apiver expect(last_response.body).to eq('one') expect(last_response.body).not_to include('API vendor or version not found') end it 'responds correctly to a v2 request' do versioned_get '/users/hello', 'v2', using: :param, parameter: :apiver expect(last_response.body).to eq('two') expect(last_response.body).not_to include('API vendor or version not found') end end context 'when there are multiple versions with a custom param' do subject { Class.new(Grape::API) } let(:v1_app) do Class.new(Grape::API) do version 'v1', using: :param, parameter: 'v' content_type :v1_test, 'application/vnd.test.a-cool_resource-v1+json' formatter :v1_test, ->(object, _) { object } format :v1_test resources :users do get :hello do 'one' end end end end let(:v2_app) do Class.new(Grape::API) do version 'v2', using: :param, parameter: 'v' content_type :v2_test, 'application/vnd.test.a-cool_resource-v2+json' formatter :v2_test, ->(object, _) { object } format :v2_test resources :users do get :hello do 'two' end end end end def app subject.mount v2_app subject.mount v1_app subject end it 'responds correctly to a v1 request' do versioned_get '/users/hello', 'v1', using: :param, parameter: 'v' expect(last_response.body).to eq('one') expect(last_response.body).not_to include('API vendor or version not found') end it 'responds correctly to a v2 request' do versioned_get '/users/hello', 'v2', using: :param, parameter: 'v' expect(last_response.body).to eq('two') expect(last_response.body).not_to include('API vendor or version not found') end end end grape-1.0.2/spec/grape/middleware/auth/0000755000004100000410000000000013231337007017745 5ustar www-datawww-datagrape-1.0.2/spec/grape/middleware/auth/strategies_spec.rb0000644000004100000410000000405713231337007023464 0ustar www-datawww-datarequire 'spec_helper' require 'base64' describe Grape::Middleware::Auth::Strategies do context 'Basic Auth' do def app proc = ->(u, p) { u && p && u == p } Rack::Builder.new do |b| b.use Grape::Middleware::Error b.use(Grape::Middleware::Auth::Base, type: :http_basic, proc: proc) b.run ->(_env) { [200, {}, ['Hello there.']] } end end it 'throws a 401 if no auth is given' do @proc = -> { false } get '/whatever' expect(last_response.status).to eq(401) end it 'authenticates if given valid creds' do get '/whatever', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('admin', 'admin') expect(last_response.status).to eq(200) end it 'throws a 401 is wrong auth is given' do get '/whatever', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('admin', 'wrong') expect(last_response.status).to eq(401) end end context 'Digest MD5 Auth' do RSpec::Matchers.define :be_challenge do match do |actual_response| actual_response.status == 401 && actual_response['WWW-Authenticate'] =~ /^Digest / && actual_response.body.empty? end end module StrategiesSpec class Test < Grape::API http_digest(realm: 'Test Api', opaque: 'secret') do |username| { 'foo' => 'bar' }[username] end get '/test' do [{ hey: 'you' }, { there: 'bar' }, { foo: 'baz' }] end end end def app StrategiesSpec::Test end it 'is a digest authentication challenge' do get '/test' expect(last_response).to be_challenge end it 'throws a 401 if no auth is given' do get '/test' expect(last_response.status).to eq(401) end it 'authenticates if given valid creds' do digest_authorize 'foo', 'bar' get '/test' expect(last_response.status).to eq(200) end it 'throws a 401 if given invalid creds' do digest_authorize 'bar', 'foo' get '/test' expect(last_response.status).to eq(401) end end end grape-1.0.2/spec/grape/middleware/auth/dsl_spec.rb0000644000004100000410000000324113231337007022066 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Auth::DSL do subject { Class.new(Grape::API) } let(:block) { ->() {} } let(:settings) do { opaque: 'secret', proc: block, realm: 'API Authorization', type: :http_digest } end describe '.auth' do it 'stets auth parameters' do expect(subject).to receive(:use).with(Grape::Middleware::Auth::Base, settings) subject.auth :http_digest, realm: settings[:realm], opaque: settings[:opaque], &settings[:proc] expect(subject.auth).to eq(settings) end it 'can be called multiple times' do expect(subject).to receive(:use).with(Grape::Middleware::Auth::Base, settings) expect(subject).to receive(:use).with(Grape::Middleware::Auth::Base, settings.merge(realm: 'super_secret')) subject.auth :http_digest, realm: settings[:realm], opaque: settings[:opaque], &settings[:proc] first_settings = subject.auth subject.auth :http_digest, realm: 'super_secret', opaque: settings[:opaque], &settings[:proc] expect(subject.auth).to eq(settings.merge(realm: 'super_secret')) expect(subject.auth.object_id).not_to eq(first_settings.object_id) end end describe '.http_basic' do it 'stets auth parameters' do subject.http_basic realm: 'my_realm', &settings[:proc] expect(subject.auth).to eq(realm: 'my_realm', type: :http_basic, proc: block) end end describe '.http_digest' do it 'stets auth parameters' do subject.http_digest realm: 'my_realm', opaque: 'my_opaque', &settings[:proc] expect(subject.auth).to eq(realm: 'my_realm', type: :http_digest, proc: block, opaque: 'my_opaque') end end end grape-1.0.2/spec/grape/middleware/auth/base_spec.rb0000644000004100000410000000135113231337007022216 0ustar www-datawww-datarequire 'spec_helper' require 'base64' describe Grape::Middleware::Auth::Base do subject do Class.new(Grape::API) do http_basic realm: 'my_realm' do |user, password| user && password && user == password end get '/authorized' do 'DONE' end end end def app subject end it 'authenticates if given valid creds' do get '/authorized', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('admin', 'admin') expect(last_response.status).to eq(200) expect(last_response.body).to eq('DONE') end it 'throws a 401 is wrong auth is given' do get '/authorized', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('admin', 'wrong') expect(last_response.status).to eq(401) end end grape-1.0.2/spec/grape/middleware/error_spec.rb0000644000004100000410000000340513231337007021476 0ustar www-datawww-datarequire 'spec_helper' require 'grape-entity' describe Grape::Middleware::Error do module ErrorSpec class ErrorEntity < Grape::Entity expose :code expose :static def static 'static text' end end class ErrApp class << self attr_accessor :error attr_accessor :format def call(_env) throw :error, error end end end end def app opts = options Rack::Builder.app do use Spec::Support::EndpointFaker use Grape::Middleware::Error, opts run ErrorSpec::ErrApp end end let(:options) { { default_message: 'Aww, hamburgers.' } } it 'sets the status code appropriately' do ErrorSpec::ErrApp.error = { status: 410 } get '/' expect(last_response.status).to eq(410) end it 'sets the error message appropriately' do ErrorSpec::ErrApp.error = { message: 'Awesome stuff.' } get '/' expect(last_response.body).to eq('Awesome stuff.') end it 'defaults to a 500 status' do ErrorSpec::ErrApp.error = {} get '/' expect(last_response.status).to eq(500) end it 'has a default message' do ErrorSpec::ErrApp.error = {} get '/' expect(last_response.body).to eq('Aww, hamburgers.') end context 'with http code' do let(:options) { { default_message: 'Aww, hamburgers.' } } it 'adds the status code if wanted' do ErrorSpec::ErrApp.error = { message: { code: 200 } } get '/' expect(last_response.body).to eq({ code: 200 }.to_json) end it 'presents an error message' do ErrorSpec::ErrApp.error = { message: { code: 200, with: ErrorSpec::ErrorEntity } } get '/' expect(last_response.body).to eq({ code: 200, static: 'static text' }.to_json) end end end grape-1.0.2/spec/grape/middleware/globals_spec.rb0000644000004100000410000000160213231337007021765 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Globals do subject { Grape::Middleware::Globals.new(blank_app) } before { allow(subject).to receive(:dup).and_return(subject) } let(:blank_app) { ->(_env) { [200, {}, 'Hi there.'] } } it 'calls through to the app' do expect(subject.call({})).to eq([200, {}, 'Hi there.']) end context 'environment' do it 'should set the grape.request environment' do subject.call({}) expect(subject.env['grape.request']).to be_a(Grape::Request) end it 'should set the grape.request.headers environment' do subject.call({}) expect(subject.env['grape.request.headers']).to be_a(Hash) end it 'should set the grape.request.params environment' do subject.call('QUERY_STRING' => 'test=1', 'rack.input' => StringIO.new) expect(subject.env['grape.request.params']).to be_a(Hash) end end end grape-1.0.2/spec/grape/middleware/stack_spec.rb0000644000004100000410000001177113231337007021457 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Stack do module StackSpec class FooMiddleware; end class BarMiddleware; end class BlockMiddleware attr_reader :block def initialize(&block) @block = block end end end let(:proc) { ->() {} } let(:others) { [[:use, StackSpec::BarMiddleware], [:insert_before, StackSpec::BarMiddleware, StackSpec::BlockMiddleware, proc]] } subject { Grape::Middleware::Stack.new } before do subject.use StackSpec::FooMiddleware end describe '#use' do it 'pushes a middleware class onto the stack' do expect { subject.use StackSpec::BarMiddleware } .to change { subject.size }.by(1) expect(subject.last).to eq(StackSpec::BarMiddleware) end it 'pushes a middleware class with arguments onto the stack' do expect { subject.use StackSpec::BarMiddleware, false, my_arg: 42 } .to change { subject.size }.by(1) expect(subject.last).to eq(StackSpec::BarMiddleware) expect(subject.last.args).to eq([false, { my_arg: 42 }]) end it 'pushes a middleware class with block arguments onto the stack' do expect { subject.use StackSpec::BlockMiddleware, &proc } .to change { subject.size }.by(1) expect(subject.last).to eq(StackSpec::BlockMiddleware) expect(subject.last.args).to eq([]) expect(subject.last.block).to eq(proc) end end describe '#insert' do it 'inserts a middleware class at the integer index' do expect { subject.insert 0, StackSpec::BarMiddleware } .to change { subject.size }.by(1) expect(subject[0]).to eq(StackSpec::BarMiddleware) expect(subject[1]).to eq(StackSpec::FooMiddleware) end end describe '#insert_before' do it 'inserts a middleware before another middleware class' do expect { subject.insert_before StackSpec::FooMiddleware, StackSpec::BarMiddleware } .to change { subject.size }.by(1) expect(subject[0]).to eq(StackSpec::BarMiddleware) expect(subject[1]).to eq(StackSpec::FooMiddleware) end it 'inserts a middleware before an anonymous class given by its superclass' do subject.use Class.new(StackSpec::BlockMiddleware) expect { subject.insert_before StackSpec::BlockMiddleware, StackSpec::BarMiddleware } .to change { subject.size }.by(1) expect(subject[1]).to eq(StackSpec::BarMiddleware) expect(subject[2]).to eq(StackSpec::BlockMiddleware) end it 'raises an error on an invalid index' do expect { subject.insert_before StackSpec::BlockMiddleware, StackSpec::BarMiddleware } .to raise_error(RuntimeError, 'No such middleware to insert before: StackSpec::BlockMiddleware') end end describe '#insert_after' do it 'inserts a middleware after another middleware class' do expect { subject.insert_after StackSpec::FooMiddleware, StackSpec::BarMiddleware } .to change { subject.size }.by(1) expect(subject[1]).to eq(StackSpec::BarMiddleware) expect(subject[0]).to eq(StackSpec::FooMiddleware) end it 'inserts a middleware after an anonymous class given by its superclass' do subject.use Class.new(StackSpec::BlockMiddleware) expect { subject.insert_after StackSpec::BlockMiddleware, StackSpec::BarMiddleware } .to change { subject.size }.by(1) expect(subject[1]).to eq(StackSpec::BlockMiddleware) expect(subject[2]).to eq(StackSpec::BarMiddleware) end it 'raises an error on an invalid index' do expect { subject.insert_after StackSpec::BlockMiddleware, StackSpec::BarMiddleware } .to raise_error(RuntimeError, 'No such middleware to insert after: StackSpec::BlockMiddleware') end end describe '#merge_with' do it 'applies a collection of operations and middlewares' do expect { subject.merge_with(others) } .to change { subject.size }.by(2) expect(subject[0]).to eq(StackSpec::FooMiddleware) expect(subject[1]).to eq(StackSpec::BlockMiddleware) expect(subject[2]).to eq(StackSpec::BarMiddleware) end end describe '#build' do it 'returns a rack builder instance' do expect(subject.build).to be_instance_of(Rack::Builder) end context 'when @others are present' do let(:others) { [[:insert_after, Grape::Middleware::Formatter, StackSpec::BarMiddleware]] } it 'applies the middleware specs stored in @others' do subject.concat others subject.use Grape::Middleware::Formatter subject.build expect(subject[0]).to eq StackSpec::FooMiddleware expect(subject[1]).to eq Grape::Middleware::Formatter expect(subject[2]).to eq StackSpec::BarMiddleware end end end describe '#concat' do it 'adds non :use specs to @others' do expect { subject.concat others }.to change(subject, :others).from([]).to([[others.last]]) end it 'calls +merge_with+ with the :use specs' do expect(subject).to receive(:merge_with).with [[:use, StackSpec::BarMiddleware]] subject.concat others end end end grape-1.0.2/spec/grape/middleware/versioner_spec.rb0000644000004100000410000000113113231337007022353 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Versioner do let(:klass) { Grape::Middleware::Versioner } it 'recognizes :path' do expect(klass.using(:path)).to eq(Grape::Middleware::Versioner::Path) end it 'recognizes :header' do expect(klass.using(:header)).to eq(Grape::Middleware::Versioner::Header) end it 'recognizes :param' do expect(klass.using(:param)).to eq(Grape::Middleware::Versioner::Param) end it 'recognizes :accept_version_header' do expect(klass.using(:accept_version_header)).to eq(Grape::Middleware::Versioner::AcceptVersionHeader) end end grape-1.0.2/spec/grape/middleware/base_spec.rb0000644000004100000410000001142613231337007021261 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Base do subject { Grape::Middleware::Base.new(blank_app) } let(:blank_app) { ->(_) { [200, {}, 'Hi there.'] } } before do # Keep it one object for testing. allow(subject).to receive(:dup).and_return(subject) end it 'has the app as an accessor' do expect(subject.app).to eq(blank_app) end it 'calls through to the app' do expect(subject.call({})).to eq([200, {}, 'Hi there.']) end context 'callbacks' do it 'calls #before' do expect(subject).to receive(:before) end it 'calls #after' do expect(subject).to receive(:after) end after { subject.call!({}) } end context 'callbacks on error' do let(:blank_app) { ->(_) { raise StandardError } } it 'calls #after' do expect(subject).to receive(:after) expect { subject.call({}) }.to raise_error(StandardError) end end context 'after callback' do before do allow(subject).to receive(:after).and_return([200, {}, 'Hello from after callback']) end it 'overwrites application response' do expect(subject.call!({}).last).to eq('Hello from after callback') end end context 'after callback with errors' do it 'does not overwrite the application response' do expect(subject.call({})).to eq([200, {}, 'Hi there.']) end context 'with patched warnings' do before do @warnings = warnings = [] allow_any_instance_of(Grape::Middleware::Base).to receive(:warn) { |m| warnings << m } allow(subject).to receive(:after).and_raise(StandardError) end it 'does show a warning' do expect { subject.call({}) }.to raise_error(StandardError) expect(@warnings).not_to be_empty end end end it 'is able to access the response' do subject.call({}) expect(subject.response).to be_kind_of(Rack::Response) end describe '#response' do subject { Grape::Middleware::Base.new(response) } context Array do let(:response) { ->(_) { [204, { abc: 1 }, 'test'] } } it 'status' do subject.call({}) expect(subject.response.status).to eq(204) end it 'body' do subject.call({}) expect(subject.response.body).to eq(['test']) end it 'header' do subject.call({}) expect(subject.response.header).to have_key(:abc) end end context Rack::Response do let(:response) { ->(_) { Rack::Response.new('test', 204, abc: 1) } } it 'status' do subject.call({}) expect(subject.response.status).to eq(204) end it 'body' do subject.call({}) expect(subject.response.body).to eq(['test']) end it 'header' do subject.call({}) expect(subject.response.header).to have_key(:abc) end end end context 'options' do it 'persists options passed at initialization' do expect(Grape::Middleware::Base.new(blank_app, abc: true).options[:abc]).to be true end context 'defaults' do module BaseSpec class ExampleWare < Grape::Middleware::Base def default_options { monkey: true } end end end it 'persists the default options' do expect(BaseSpec::ExampleWare.new(blank_app).options[:monkey]).to be true end it 'overrides default options when provided' do expect(BaseSpec::ExampleWare.new(blank_app, monkey: false).options[:monkey]).to be false end end end context 'header' do module HeaderSpec class ExampleWare < Grape::Middleware::Base def before header 'X-Test-Before', 'Hi' end def after header 'X-Test-After', 'Bye' nil end end end def app Rack::Builder.app do use HeaderSpec::ExampleWare run ->(_) { [200, {}, ['Yeah']] } end end it 'is able to set a header' do get '/' expect(last_response.headers['X-Test-Before']).to eq('Hi') expect(last_response.headers['X-Test-After']).to eq('Bye') end end context 'header overwrite' do module HeaderOverwritingSpec class ExampleWare < Grape::Middleware::Base def before header 'X-Test-Overwriting', 'Hi' end def after header 'X-Test-Overwriting', 'Bye' nil end end class API < Grape::API get('/') do header 'X-Test-Overwriting', 'Yeah' 'Hello' end end end def app Rack::Builder.app do use HeaderOverwritingSpec::ExampleWare run HeaderOverwritingSpec::API.new end end it 'overwrites header by after headers' do get '/' expect(last_response.headers['X-Test-Overwriting']).to eq('Bye') end end end grape-1.0.2/spec/grape/middleware/formatter_spec.rb0000644000004100000410000003176013231337007022355 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Middleware::Formatter do subject { Grape::Middleware::Formatter.new(app) } before { allow(subject).to receive(:dup).and_return(subject) } let(:body) { { 'foo' => 'bar' } } let(:app) { ->(_env) { [200, {}, [body]] } } context 'serialization' do let(:body) { { 'abc' => 'def' } } it 'looks at the bodies for possibly serializable data' do _, _, bodies = *subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json') bodies.each { |b| expect(b).to eq(::Grape::Json.dump(body)) } end context 'default format' do let(:body) { ['foo'] } it 'calls #to_json since default format is json' do body.instance_eval do def to_json '"bar"' end end subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('"bar"') } end end context 'jsonapi' do let(:body) { { 'foos' => [{ 'bar' => 'baz' }] } } it 'calls #to_json if the content type is jsonapi' do body.instance_eval do def to_json '{"foos":[{"bar":"baz"}] }' end end subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/vnd.api+json').to_a.last.each { |b| expect(b).to eq('{"foos":[{"bar":"baz"}] }') } end end context 'xml' do let(:body) { 'string' } it 'calls #to_xml if the content type is xml' do body.instance_eval do def to_xml '' end end subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('') } end end end context 'error handling' do let(:formatter) { double(:formatter) } before do allow(Grape::Formatter).to receive(:formatter_for) { formatter } end it 'rescues formatter-specific exceptions' do allow(formatter).to receive(:call) { raise Grape::Exceptions::InvalidFormatter.new(String, 'xml') } expect do catch(:error) { subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json') } end.to_not raise_error end it 'does not rescue other exceptions' do allow(formatter).to receive(:call) { raise StandardError } expect do catch(:error) { subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json') } end.to raise_error(StandardError) end end context 'detection' do it 'uses the xml extension if one is provided' do subject.call('PATH_INFO' => '/info.xml') expect(subject.env['api.format']).to eq(:xml) end it 'uses the json extension if one is provided' do subject.call('PATH_INFO' => '/info.json') expect(subject.env['api.format']).to eq(:json) end it 'uses the format parameter if one is provided' do subject.call('PATH_INFO' => '/info', 'QUERY_STRING' => 'format=json') expect(subject.env['api.format']).to eq(:json) subject.call('PATH_INFO' => '/info', 'QUERY_STRING' => 'format=xml') expect(subject.env['api.format']).to eq(:xml) end it 'uses the default format if none is provided' do subject.call('PATH_INFO' => '/info') expect(subject.env['api.format']).to eq(:txt) end it 'uses the requested format if provided in headers' do subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json') expect(subject.env['api.format']).to eq(:json) end it 'uses the file extension format if provided before headers' do subject.call('PATH_INFO' => '/info.txt', 'HTTP_ACCEPT' => 'application/json') expect(subject.env['api.format']).to eq(:txt) end end context 'accept header detection' do it 'detects from the Accept header' do subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/xml') expect(subject.env['api.format']).to eq(:xml) end it 'uses quality rankings to determine formats' do subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json; q=0.3,application/xml; q=1.0') expect(subject.env['api.format']).to eq(:xml) subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json; q=1.0,application/xml; q=0.3') expect(subject.env['api.format']).to eq(:json) end it 'handles quality rankings mixed with nothing' do subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json,application/xml; q=1.0') expect(subject.env['api.format']).to eq(:xml) end it 'parses headers with other attributes' do subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json; abc=2.3; q=1.0,application/xml; q=0.7') expect(subject.env['api.format']).to eq(:json) end it 'parses headers with vendor and api version' do subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/vnd.test-v1+xml') expect(subject.env['api.format']).to eq(:xml) end context 'with custom vendored content types' do before do subject.options[:content_types] = {} subject.options[:content_types][:custom] = 'application/vnd.test+json' end it 'it uses the custom type' do subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/vnd.test+json') expect(subject.env['api.format']).to eq(:custom) end end it 'parses headers with symbols as hash keys' do subject.call('PATH_INFO' => '/info', 'http_accept' => 'application/xml', system_time: '091293') expect(subject.env[:system_time]).to eq('091293') end end context 'content-type' do it 'is set for json' do _, headers, = subject.call('PATH_INFO' => '/info.json') expect(headers['Content-type']).to eq('application/json') end it 'is set for xml' do _, headers, = subject.call('PATH_INFO' => '/info.xml') expect(headers['Content-type']).to eq('application/xml') end it 'is set for txt' do _, headers, = subject.call('PATH_INFO' => '/info.txt') expect(headers['Content-type']).to eq('text/plain') end it 'is set for custom' do subject.options[:content_types] = {} subject.options[:content_types][:custom] = 'application/x-custom' _, headers, = subject.call('PATH_INFO' => '/info.custom') expect(headers['Content-type']).to eq('application/x-custom') end it 'is set for vendored with registered type' do subject.options[:content_types] = {} subject.options[:content_types][:custom] = 'application/vnd.test+json' _, headers, = subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/vnd.test+json') expect(headers['Content-type']).to eq('application/vnd.test+json') end it 'is set to closest generic for custom vendored/versioned without registered type' do _, headers, = subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/vnd.test+json') expect(headers['Content-type']).to eq('application/json') end end context 'format' do it 'uses custom formatter' do subject.options[:content_types] = {} subject.options[:content_types][:custom] = "don't care" subject.options[:formatters][:custom] = ->(_obj, _env) { 'CUSTOM FORMAT' } _, _, body = subject.call('PATH_INFO' => '/info.custom') expect(body.body).to eq(['CUSTOM FORMAT']) end context 'default' do let(:body) { ['blah'] } it 'uses default json formatter' do _, _, body = subject.call('PATH_INFO' => '/info.json') expect(body.body).to eq(['["blah"]']) end end it 'uses custom json formatter' do subject.options[:formatters][:json] = ->(_obj, _env) { 'CUSTOM JSON FORMAT' } _, _, body = subject.call('PATH_INFO' => '/info.json') expect(body.body).to eq(['CUSTOM JSON FORMAT']) end end context 'no content responses' do let(:no_content_response) { ->(status) { [status, {}, ['']] } } Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.each do |status| it "does not modify a #{status} response" do expected_response = no_content_response[status] allow(app).to receive(:call).and_return(expected_response) expect(subject.call({})).to eq(expected_response) end end end context 'input' do %w[POST PATCH PUT DELETE].each do |method| ['application/json', 'application/json; charset=utf-8'].each do |content_type| context content_type do it "parses the body from #{method} and copies values into rack.request.form_hash" do io = StringIO.new('{"is_boolean":true,"string":"thing"}') subject.call( 'PATH_INFO' => '/info', 'REQUEST_METHOD' => method, 'CONTENT_TYPE' => content_type, 'rack.input' => io, 'CONTENT_LENGTH' => io.length ) expect(subject.env['rack.request.form_hash']['is_boolean']).to be true expect(subject.env['rack.request.form_hash']['string']).to eq('thing') end end end it "parses the chunked body from #{method} and copies values into rack.request.from_hash" do io = StringIO.new('{"is_boolean":true,"string":"thing"}') subject.call( 'PATH_INFO' => '/infol', 'REQUEST_METHOD' => method, 'CONTENT_TYPE' => 'application/json', 'rack.input' => io, 'HTTP_TRANSFER_ENCODING' => 'chunked' ) expect(subject.env['rack.request.form_hash']['is_boolean']).to be true expect(subject.env['rack.request.form_hash']['string']).to eq('thing') end it 'rewinds IO' do io = StringIO.new('{"is_boolean":true,"string":"thing"}') io.read subject.call( 'PATH_INFO' => '/infol', 'REQUEST_METHOD' => method, 'CONTENT_TYPE' => 'application/json', 'rack.input' => io, 'HTTP_TRANSFER_ENCODING' => 'chunked' ) expect(subject.env['rack.request.form_hash']['is_boolean']).to be true expect(subject.env['rack.request.form_hash']['string']).to eq('thing') end it "parses the body from an xml #{method} and copies values into rack.request.from_hash" do io = StringIO.new('Test') subject.call( 'PATH_INFO' => '/info.xml', 'REQUEST_METHOD' => method, 'CONTENT_TYPE' => 'application/xml', 'rack.input' => io, 'CONTENT_LENGTH' => io.length ) if Object.const_defined? :MultiXml expect(subject.env['rack.request.form_hash']['thing']['name']).to eq('Test') else expect(subject.env['rack.request.form_hash']['thing']['name']['__content__']).to eq('Test') end end [Rack::Request::FORM_DATA_MEDIA_TYPES, Rack::Request::PARSEABLE_DATA_MEDIA_TYPES].flatten.each do |content_type| it "ignores #{content_type}" do io = StringIO.new('name=Other+Test+Thing') subject.call( 'PATH_INFO' => '/info', 'REQUEST_METHOD' => method, 'CONTENT_TYPE' => content_type, 'rack.input' => io, 'CONTENT_LENGTH' => io.length ) expect(subject.env['rack.request.form_hash']).to be_nil end end end end context 'send file' do let(:body) { Grape::ServeFile::FileResponse.new('file') } let(:app) { ->(_env) { [200, {}, body] } } it 'returns Grape::Uril::SendFileReponse' do env = { 'PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json' } expect(subject.call(env)).to be_a(Grape::ServeFile::SendfileResponse) end end context 'inheritable formatters' do class InvalidFormatter def self.call(_, _) { message: 'invalid' }.to_json end end let(:app) { ->(_env) { [200, {}, ['']] } } before do Grape::Formatter.register :invalid, InvalidFormatter Grape::ContentTypes::CONTENT_TYPES[:invalid] = 'application/x-invalid' end it 'returns response by invalid formatter' do env = { 'PATH_INFO' => '/hello.invalid', 'HTTP_ACCEPT' => 'application/x-invalid' } _, _, bodies = *subject.call(env) expect(bodies.body.first).to eq({ message: 'invalid' }.to_json) end end context 'custom parser raises exception and rescue options are enabled for backtrace and original_exception' do it 'adds the backtrace and original_exception to the error output' do subject = Grape::Middleware::Formatter.new( app, rescue_options: { backtrace: true, original_exception: true }, parsers: { json: ->(_object, _env) { raise StandardError, 'fail' } } ) io = StringIO.new('{invalid}') error = catch(:error) { subject.call( 'PATH_INFO' => '/info', 'REQUEST_METHOD' => 'POST', 'CONTENT_TYPE' => 'application/json', 'rack.input' => io, 'CONTENT_LENGTH' => io.length ) } expect(error[:message]).to eq 'fail' expect(error[:backtrace].size).to be >= 1 expect(error[:original_exception].class).to eq StandardError end end end grape-1.0.2/spec/grape/exceptions/0000755000004100000410000000000013231337007017050 5ustar www-datawww-datagrape-1.0.2/spec/grape/exceptions/invalid_accept_header_spec.rb0000644000004100000410000002462713231337007024677 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Exceptions::InvalidAcceptHeader do shared_examples_for 'a valid request' do it 'does return with status 200' do expect(last_response.status).to eq 200 end it 'does return the expected result' do expect(last_response.body).to eq('beer received') end end shared_examples_for 'a cascaded request' do it 'does not find a matching route' do expect(last_response.status).to eq 404 end end shared_examples_for 'a not-cascaded request' do it 'does not include the X-Cascade=pass header' do expect(last_response.headers['X-Cascade']).to be_nil end it 'does not accept the request' do expect(last_response.status).to eq 406 end end shared_examples_for 'a rescued request' do it 'does not include the X-Cascade=pass header' do expect(last_response.headers['X-Cascade']).to be_nil end it 'does show rescue handler processing' do expect(last_response.status).to eq 400 expect(last_response.body).to eq('message was processed') end end context 'API with cascade=false and rescue_from :all handler' do subject { Class.new(Grape::API) } before do subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false subject.rescue_from :all do |e| rack_response 'message was processed', 400, e[:headers] end subject.get '/beer' do 'beer received' end end def app subject end context 'that received a request with correct vendor and version' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } it_should_behave_like 'a valid request' end context 'that receives' do context 'an invalid vendor in the request' do before do get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99', 'CONTENT_TYPE' => 'application/json' end it_should_behave_like 'a rescued request' end end end context 'API with cascade=false and without a rescue handler' do subject { Class.new(Grape::API) } before do subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false subject.get '/beer' do 'beer received' end end def app subject end context 'that received a request with correct vendor and version' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } it_should_behave_like 'a valid request' end context 'that receives' do context 'an invalid version in the request' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' } it_should_behave_like 'a not-cascaded request' end context 'an invalid vendor in the request' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' } it_should_behave_like 'a not-cascaded request' end end end context 'API with cascade=false and with rescue_from :all handler and http_codes' do subject { Class.new(Grape::API) } before do subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false subject.rescue_from :all do |e| rack_response 'message was processed', 400, e[:headers] end subject.desc 'Get beer' do failure [[400, 'Bad Request'], [401, 'Unauthorized'], [403, 'Forbidden'], [404, 'Resource not found'], [406, 'API vendor or version not found'], [500, 'Internal processing error']] end subject.get '/beer' do 'beer received' end end def app subject end context 'that received a request with correct vendor and version' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } it_should_behave_like 'a valid request' end context 'that receives' do context 'an invalid vendor in the request' do before do get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99', 'CONTENT_TYPE' => 'application/json' end it_should_behave_like 'a rescued request' end end end context 'API with cascade=false, http_codes but without a rescue handler' do subject { Class.new(Grape::API) } before do subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false subject.desc 'Get beer' do failure [[400, 'Bad Request'], [401, 'Unauthorized'], [403, 'Forbidden'], [404, 'Resource not found'], [406, 'API vendor or version not found'], [500, 'Internal processing error']] end subject.get '/beer' do 'beer received' end end def app subject end context 'that received a request with correct vendor and version' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } it_should_behave_like 'a valid request' end context 'that receives' do context 'an invalid version in the request' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' } it_should_behave_like 'a not-cascaded request' end context 'an invalid vendor in the request' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' } it_should_behave_like 'a not-cascaded request' end end end context 'API with cascade=true and rescue_from :all handler' do subject { Class.new(Grape::API) } before do subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true subject.rescue_from :all do |e| rack_response 'message was processed', 400, e[:headers] end subject.get '/beer' do 'beer received' end end def app subject end context 'that received a request with correct vendor and version' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } it_should_behave_like 'a valid request' end context 'that receives' do context 'an invalid version in the request' do before do get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77', 'CONTENT_TYPE' => 'application/json' end it_should_behave_like 'a cascaded request' end context 'an invalid vendor in the request' do before do get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99', 'CONTENT_TYPE' => 'application/json' end it_should_behave_like 'a cascaded request' end end end context 'API with cascade=true and without a rescue handler' do subject { Class.new(Grape::API) } before do subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true subject.get '/beer' do 'beer received' end end def app subject end context 'that received a request with correct vendor and version' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } it_should_behave_like 'a valid request' end context 'that receives' do context 'an invalid version in the request' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' } it_should_behave_like 'a cascaded request' end context 'an invalid vendor in the request' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' } it_should_behave_like 'a cascaded request' end end end context 'API with cascade=true and with rescue_from :all handler and http_codes' do subject { Class.new(Grape::API) } before do subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true subject.rescue_from :all do |e| rack_response 'message was processed', 400, e[:headers] end subject.desc 'Get beer' do failure [[400, 'Bad Request'], [401, 'Unauthorized'], [403, 'Forbidden'], [404, 'Resource not found'], [406, 'API vendor or version not found'], [500, 'Internal processing error']] end subject.get '/beer' do 'beer received' end end def app subject end context 'that received a request with correct vendor and version' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } it_should_behave_like 'a valid request' end context 'that receives' do context 'an invalid version in the request' do before do get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77', 'CONTENT_TYPE' => 'application/json' end it_should_behave_like 'a cascaded request' end context 'an invalid vendor in the request' do before do get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99', 'CONTENT_TYPE' => 'application/json' end it_should_behave_like 'a cascaded request' end end end context 'API with cascade=true, http_codes but without a rescue handler' do subject { Class.new(Grape::API) } before do subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true subject.desc 'Get beer' do failure [[400, 'Bad Request'], [401, 'Unauthorized'], [403, 'Forbidden'], [404, 'Resource not found'], [406, 'API vendor or version not found'], [500, 'Internal processing error']] end subject.get '/beer' do 'beer received' end end def app subject end context 'that received a request with correct vendor and version' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' } it_should_behave_like 'a valid request' end context 'that receives' do context 'an invalid version in the request' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' } it_should_behave_like 'a cascaded request' end context 'an invalid vendor in the request' do before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' } it_should_behave_like 'a cascaded request' end end end end grape-1.0.2/spec/grape/exceptions/validation_spec.rb0000644000004100000410000000120513231337007022537 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Exceptions::Validation do it 'fails when params are missing' do expect { Grape::Exceptions::Validation.new(message: 'presence') }.to raise_error(ArgumentError, 'missing keyword: params') end context 'when message is a symbol' do it 'stores message_key' do expect(Grape::Exceptions::Validation.new(params: ['id'], message: :presence).message_key).to eq(:presence) end end context 'when message is a String' do it 'does not store the message_key' do expect(Grape::Exceptions::Validation.new(params: ['id'], message: 'presence').message_key).to eq(nil) end end end grape-1.0.2/spec/grape/exceptions/invalid_versioner_option_spec.rb0000644000004100000410000000051113231337007025516 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Exceptions::InvalidVersionerOption do describe '#message' do let(:error) do described_class.new('headers') end it 'contains the problem in the message' do expect(error.message).to include( 'Unknown :using for versioner: headers' ) end end end grape-1.0.2/spec/grape/exceptions/invalid_formatter_spec.rb0000644000004100000410000000047613231337007024127 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Exceptions::InvalidFormatter do describe '#message' do let(:error) do described_class.new(String, 'xml') end it 'contains the problem in the message' do expect(error.message).to include( 'cannot convert String to xml' ) end end end grape-1.0.2/spec/grape/exceptions/unknown_validator_spec.rb0000644000004100000410000000046413231337007024157 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Exceptions::UnknownValidator do describe '#message' do let(:error) do described_class.new('gt_10') end it 'contains the problem in the message' do expect(error.message).to include( 'unknown validator: gt_10' ) end end end grape-1.0.2/spec/grape/exceptions/body_parse_errors_spec.rb0000644000004100000410000001022013231337007024125 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Exceptions::ValidationErrors do context 'api with rescue_from :all handler' do subject { Class.new(Grape::API) } before do subject.rescue_from :all do |_e| rack_response 'message was processed', 400 end subject.params do requires :beer end subject.post '/beer' do 'beer received' end end def app subject end context 'with content_type json' do it 'can recover from failed body parsing' do post '/beer', 'test', 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq 400 expect(last_response.body).to eq('message was processed') end end context 'with content_type xml' do it 'can recover from failed body parsing' do post '/beer', 'test', 'CONTENT_TYPE' => 'application/xml' expect(last_response.status).to eq 400 expect(last_response.body).to eq('message was processed') end end context 'with content_type text' do it 'can recover from failed body parsing' do post '/beer', 'test', 'CONTENT_TYPE' => 'text/plain' expect(last_response.status).to eq 400 expect(last_response.body).to eq('message was processed') end end context 'with no specific content_type' do it 'can recover from failed body parsing' do post '/beer', 'test', {} expect(last_response.status).to eq 400 expect(last_response.body).to eq('message was processed') end end end context 'api with rescue_from :grape_exceptions handler' do subject { Class.new(Grape::API) } before do subject.rescue_from :all do |_e| rack_response 'message was processed', 400 end subject.rescue_from :grape_exceptions subject.params do requires :beer end subject.post '/beer' do 'beer received' end end def app subject end context 'with content_type json' do it 'returns body parsing error message' do post '/beer', 'test', 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq 400 expect(last_response.body).to include 'message body does not match declared format' end end context 'with content_type xml' do it 'returns body parsing error message' do post '/beer', 'test', 'CONTENT_TYPE' => 'application/xml' expect(last_response.status).to eq 400 expect(last_response.body).to include 'message body does not match declared format' end end end context 'api without a rescue handler' do subject { Class.new(Grape::API) } before do subject.params do requires :beer end subject.post '/beer' do 'beer received' end end def app subject end context 'and with content_type json' do it 'can recover from failed body parsing' do post '/beer', 'test', 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq 400 expect(last_response.body).to include('message body does not match declared format') expect(last_response.body).to include('application/json') end end context 'with content_type xml' do it 'can recover from failed body parsing' do post '/beer', 'test', 'CONTENT_TYPE' => 'application/xml' expect(last_response.status).to eq 400 expect(last_response.body).to include('message body does not match declared format') expect(last_response.body).to include('application/xml') end end context 'with content_type text' do it 'can recover from failed body parsing' do post '/beer', 'test', 'CONTENT_TYPE' => 'text/plain' expect(last_response.status).to eq 400 expect(last_response.body).to eq('beer is missing') end end context 'and with no specific content_type' do it 'can recover from failed body parsing' do post '/beer', 'test', {} expect(last_response.status).to eq 400 # plain response with text/html expect(last_response.body).to eq('beer is missing') end end end end grape-1.0.2/spec/grape/exceptions/missing_mime_type_spec.rb0000644000004100000410000000072513231337007024134 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Exceptions::MissingMimeType do describe '#message' do let(:error) do described_class.new('new_json') end it 'contains the problem in the message' do expect(error.message).to include 'missing mime type for new_json' end it 'contains the resolution in the message' do expect(error.message).to include "or add your own with content_type :new_json, 'application/new_json' " end end end grape-1.0.2/spec/grape/exceptions/unknown_options_spec.rb0000644000004100000410000000045313231337007023663 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Exceptions::UnknownOptions do describe '#message' do let(:error) do described_class.new(%i[a b]) end it 'contains the problem in the message' do expect(error.message).to include( 'unknown options: ' ) end end end grape-1.0.2/spec/grape/exceptions/missing_option_spec.rb0000644000004100000410000000046613231337007023456 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Exceptions::MissingOption do describe '#message' do let(:error) do described_class.new(:path) end it 'contains the problem in the message' do expect(error.message).to include( 'You must specify :path options.' ) end end end grape-1.0.2/spec/grape/exceptions/validation_errors_spec.rb0000644000004100000410000000445213231337007024142 0ustar www-datawww-datarequire 'spec_helper' require 'ostruct' describe Grape::Exceptions::ValidationErrors do let(:validation_message) { 'FooBar is invalid' } let(:validation_error) { OpenStruct.new(params: [validation_message]) } context 'initialize' do let(:headers) do { 'A-Header-Key' => 'A-Header-Value' } end subject do described_class.new(errors: [validation_error], headers: headers) end it 'should assign headers through base class' do expect(subject.headers).to eq(headers) end end context 'message' do context 'is not repeated' do let(:error) do described_class.new(errors: [validation_error, validation_error]) end subject(:message) { error.message.split(',').map(&:strip) } it { expect(message).to include validation_message } it { expect(message.size).to eq 1 } end end describe '#full_messages' do context 'with errors' do let(:validation_error_1) { Grape::Exceptions::Validation.new(params: ['id'], message: :presence) } let(:validation_error_2) { Grape::Exceptions::Validation.new(params: ['name'], message: :presence) } subject { described_class.new(errors: [validation_error_1, validation_error_2]).full_messages } it 'returns an array with each errors full message' do expect(subject).to contain_exactly('id is missing', 'name is missing') end end end context 'api' do subject { Class.new(Grape::API) } def app subject end it 'can return structured json with separate fields' do subject.format :json subject.rescue_from Grape::Exceptions::ValidationErrors do |e| error!(e, 400) end subject.params do optional :beer optional :wine optional :juice exactly_one_of :beer, :wine, :juice end subject.get '/exactly_one_of' do 'exactly_one_of works!' end get '/exactly_one_of', beer: 'string', wine: 'anotherstring' expect(last_response.status).to eq(400) expect(JSON.parse(last_response.body)).to eq([ 'params' => %w[beer wine], 'messages' => ['are mutually exclusive'] ]) end end end grape-1.0.2/spec/grape/parser_spec.rb0000644000004100000410000000447413231337007017533 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Parser do subject { described_class } describe '.builtin_parsers' do it 'returns an instance of Hash' do expect(subject.builtin_parsers).to be_an_instance_of(Hash) end it 'includes json and xml parsers by default' do expect(subject.builtin_parsers).to include(json: Grape::Parser::Json, xml: Grape::Parser::Xml) end end describe '.parsers' do it 'returns an instance of Hash' do expect(subject.parsers({})).to be_an_instance_of(Hash) end it 'includes built-in parsers' do expect(subject.parsers({})).to include(subject.builtin_parsers) end context 'with :parsers option' do let(:parsers) { { customized: Class.new } } it 'includes passed :parsers values' do expect(subject.parsers(parsers: parsers)).to include(parsers) end end context 'with added parser by using `register` keyword' do let(:added_parser) { Class.new } before { subject.register :added, added_parser } it 'includes added parser' do expect(subject.parsers({})).to include(added: added_parser) end end end describe '.parser_for' do let(:options) { {} } it 'calls .parsers' do expect(subject).to receive(:parsers).with(options).and_return(subject.builtin_parsers) subject.parser_for(:json, options) end it 'returns parser correctly' do expect(subject.parser_for(:json)).to eq(Grape::Parser::Json) end context 'when parser is available' do before { subject.register :customized_json, Grape::Parser::Json } it 'returns registered parser if available' do expect(subject.parser_for(:customized_json)).to eq(Grape::Parser::Json) end end context 'when parser is an instance of Symbol' do before do allow(subject).to receive(:foo).and_return(:bar) subject.register :foo, :foo end it 'returns an instance of Method' do expect(subject.parser_for(:foo)).to be_an_instance_of(Method) end it 'returns object which can be called' do method = subject.parser_for(:foo) expect(method.call).to eq(:bar) end end context 'when parser does not exist' do it 'returns nil' do expect(subject.parser_for(:undefined)).to be_nil end end end end grape-1.0.2/spec/grape/api/0000755000004100000410000000000013231337007015440 5ustar www-datawww-datagrape-1.0.2/spec/grape/api/inherited_helpers_spec.rb0000644000004100000410000000470713231337007022504 0ustar www-datawww-datarequire 'spec_helper' describe Grape::API::Helpers do let(:user) { 'Miguel Caneo' } let(:id) { '42' } module InheritedHelpersSpec class SuperClass < Grape::API helpers do params(:superclass_params) { requires :id, type: String } def current_user params[:user] end end end class OverriddenSubClass < SuperClass params { use :superclass_params } helpers do def current_user "#{params[:user]} with id" end end get 'resource' do "#{current_user}: #{params['id']}" end end class SubClass < SuperClass params { use :superclass_params } get 'resource' do "#{current_user}: #{params['id']}" end end class Example < SubClass params { use :superclass_params } get 'resource' do "#{current_user}: #{params['id']}" end end end context 'non overriding subclass' do subject { InheritedHelpersSpec::SubClass } def app subject end context 'given expected params' do it 'inherits helpers from a superclass' do get '/resource', id: id, user: user expect(last_response.body).to eq("#{user}: #{id}") end end context 'with lack of expected params' do it 'returns missing error' do get '/resource' expect(last_response.body).to eq('id is missing') end end end context 'overriding subclass' do subject { InheritedHelpersSpec::OverriddenSubClass } def app subject end context 'given expected params' do it 'overrides helpers from a superclass' do get '/resource', id: id, user: user expect(last_response.body).to eq("#{user} with id: #{id}") end end context 'with lack of expected params' do it 'returns missing error' do get '/resource' expect(last_response.body).to eq('id is missing') end end end context 'example subclass' do subject { InheritedHelpersSpec::Example } def app subject end context 'given expected params' do it 'inherits helpers from a superclass' do get '/resource', id: id, user: user expect(last_response.body).to eq("#{user}: #{id}") end end context 'with lack of expected params' do it 'returns missing error' do get '/resource' expect(last_response.body).to eq('id is missing') end end end end grape-1.0.2/spec/grape/api/nested_helpers_spec.rb0000644000004100000410000000166313231337007022011 0ustar www-datawww-datarequire 'spec_helper' describe Grape::API::Helpers do module NestedHelpersSpec module HelperMethods extend Grape::API::Helpers def current_user @current_user ||= params[:current_user] end end class Nested < Grape::API resource :level1 do helpers HelperMethods get do current_user end resource :level2 do get do current_user end end end end class Main < Grape::API mount Nested end end subject do NestedHelpersSpec::Main end def app subject end it 'can access helpers from a mounted resource' do get '/level1', current_user: 'hello' expect(last_response.body).to eq('hello') end it 'can access helpers from a mounted resource in a nested resource' do get '/level1/level2', current_user: 'world' expect(last_response.body).to eq('world') end end grape-1.0.2/spec/grape/api/invalid_format_spec.rb0000644000004100000410000000174213231337007022001 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Endpoint do subject { Class.new(Grape::API) } def app subject end before do subject.namespace do format :json content_type :json, 'application/json' params do requires :id, desc: 'Identifier.' end get ':id' do { id: params[:id], format: params[:format] } end end end context 'get' do it 'no format' do get '/foo' expect(last_response.status).to eq 200 expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: nil)) end it 'json format' do get '/foo.json' expect(last_response.status).to eq 200 expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: 'json')) end it 'invalid format' do get '/foo.invalid' expect(last_response.status).to eq 200 expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: 'invalid')) end end end grape-1.0.2/spec/grape/api/parameters_modification_spec.rb0000644000004100000410000000156613231337007023677 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Endpoint do subject { Class.new(Grape::API) } def app subject end before do subject.namespace :test do params do optional :foo, default: '-abcdef' end get do params[:foo].slice!(0) params[:foo] end end end context 'when route modifies param value' do it 'param default should not change' do get '/test' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'abcdef' get '/test' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'abcdef' get '/test?foo=-123456' expect(last_response.status).to eq 200 expect(last_response.body).to eq '123456' get '/test' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'abcdef' end end end grape-1.0.2/spec/grape/api/shared_helpers_spec.rb0000644000004100000410000000123213231337007021765 0ustar www-datawww-datarequire 'spec_helper' describe Grape::API::Helpers do subject do shared_params = Module.new do extend Grape::API::Helpers params :pagination do optional :page, type: Integer optional :size, type: Integer end end Class.new(Grape::API) do helpers shared_params format :json params do use :pagination end get do declared(params, include_missing: true) end end end def app subject end it 'defines parameters' do get '/' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ page: nil, size: nil }.to_json) end end grape-1.0.2/spec/grape/api/required_parameters_with_invalid_method_spec.rb0000644000004100000410000000060513231337007027144 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Endpoint do subject { Class.new(Grape::API) } def app subject end before do subject.namespace do params do requires :id, desc: 'Identifier.' end get ':id' do end end end context 'post' do it '405' do post '/something' expect(last_response.status).to eq 405 end end end grape-1.0.2/spec/grape/api/namespace_parameters_in_route_spec.rb0000644000004100000410000000122613231337007025063 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Endpoint do subject { Class.new(Grape::API) } def app subject end before do subject.namespace :me do namespace :pending do get '/' do 'banana' end end put ':id' do params[:id] end end end context 'get' do it 'responds without ext' do get '/me/pending' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'banana' end end context 'put' do it 'responds' do put '/me/foo' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'foo' end end end grape-1.0.2/spec/grape/api/custom_validations_spec.rb0000644000004100000410000001252313231337007022711 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations do context 'using a custom length validator' do before do module CustomValidationsSpec class DefaultLength < Grape::Validations::Base def validate_param!(attr_name, params) @option = params[:max].to_i if params.key?(:max) return if params[attr_name].length <= @option raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long" end end end end subject do Class.new(Grape::API) do params do requires :text, default_length: 140 end get do 'bacon' end end end def app subject end it 'under 140 characters' do get '/', text: 'abc' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'bacon' end it 'over 140 characters' do get '/', text: 'a' * 141 expect(last_response.status).to eq 400 expect(last_response.body).to eq 'text must be at the most 140 characters long' end it 'specified in the query string' do get '/', text: 'a' * 141, max: 141 expect(last_response.status).to eq 200 expect(last_response.body).to eq 'bacon' end end context 'using a custom body-only validator' do before do module CustomValidationsSpec class InBody < Grape::Validations::PresenceValidator def validate(request) validate!(request.env['api.request.body']) end end end end subject do Class.new(Grape::API) do params do requires :text, in_body: true end get do 'bacon' end end end def app subject end it 'allows field in body' do get '/', text: 'abc' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'bacon' end it 'ignores field in query' do get '/', nil, text: 'abc' expect(last_response.status).to eq 400 expect(last_response.body).to eq 'text is missing' end end context 'using a custom validator with message_key' do before do module CustomValidationsSpec class WithMessageKey < Grape::Validations::PresenceValidator def validate_param!(attr_name, _params) raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: :presence end end end end subject do Class.new(Grape::API) do params do requires :text, with_message_key: true end get do 'bacon' end end end def app subject end it 'fails with message' do get '/', text: 'foobar' expect(last_response.status).to eq 400 expect(last_response.body).to eq 'text is missing' end end context 'using a custom request/param validator' do before do module CustomValidationsSpec class Admin < Grape::Validations::Base def validate(request) # return if the param we are checking was not in request # @attrs is a list containing the attribute we are currently validating return unless request.params.key? @attrs.first # check if admin flag is set to true return unless @option # check if user is admin or not # as an example get a token from request and check if it's admin or not raise Grape::Exceptions::Validation, params: @attrs, message: 'Can not set Admin only field.' unless request.headers['X-Access-Token'] == 'admin' end end end end subject do Class.new(Grape::API) do params do optional :admin_field, type: String, admin: true optional :non_admin_field, type: String optional :admin_false_field, type: String, admin: false end get do 'bacon' end end end def app subject end it 'fail when non-admin user sets an admin field' do get '/', admin_field: 'tester', non_admin_field: 'toaster' expect(last_response.status).to eq 400 expect(last_response.body).to include 'Can not set Admin only field.' end it 'does not fail when we send non-admin fields only' do get '/', non_admin_field: 'toaster' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'bacon' end it 'does not fail when we send non-admin and admin=false fields only' do get '/', non_admin_field: 'toaster', admin_false_field: 'test' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'bacon' end it 'does not fail when we send admin fields and we are admin' do header 'X-Access-Token', 'admin' get '/', admin_field: 'tester', non_admin_field: 'toaster', admin_false_field: 'test' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'bacon' end it 'fails when we send admin fields and we are not admin' do header 'X-Access-Token', 'user' get '/', admin_field: 'tester', non_admin_field: 'toaster', admin_false_field: 'test' expect(last_response.status).to eq 400 expect(last_response.body).to include 'Can not set Admin only field.' end end end grape-1.0.2/spec/grape/api/optional_parameters_in_route_spec.rb0000644000004100000410000000146313231337007024757 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Endpoint do subject { Class.new(Grape::API) } def app subject end before do subject.namespace :api do get ':id(/:ext)' do [params[:id], params[:ext]].compact.join('/') end put ':id' do params[:id] end end end context 'get' do it 'responds without ext' do get '/api/foo' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'foo' end it 'responds with ext' do get '/api/foo/bar' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'foo/bar' end end context 'put' do it 'responds' do put '/api/foo' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'foo' end end end grape-1.0.2/spec/grape/api/patch_method_helpers_spec.rb0000644000004100000410000000330413231337007023160 0ustar www-datawww-datarequire 'spec_helper' describe Grape::API::Helpers do module PatchHelpersSpec class PatchPublic < Grape::API format :json version 'public-v1', using: :header, vendor: 'grape' get do { ok: 'public' } end end module AuthMethods def authenticate!; end end class PatchPrivate < Grape::API format :json version 'private-v1', using: :header, vendor: 'grape' helpers AuthMethods before do authenticate! end get do { ok: 'private' } end end class Main < Grape::API mount PatchPublic mount PatchPrivate end end def app PatchHelpersSpec::Main end context 'patch' do it 'public' do patch '/', {}, 'HTTP_ACCEPT' => 'application/vnd.grape-public-v1+json' expect(last_response.status).to eq 405 end it 'private' do patch '/', {}, 'HTTP_ACCEPT' => 'application/vnd.grape-private-v1+json' expect(last_response.status).to eq 405 end it 'default' do patch '/' expect(last_response.status).to eq 405 end end context 'default' do it 'public' do get '/', {}, 'HTTP_ACCEPT' => 'application/vnd.grape-public-v1+json' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ ok: 'public' }.to_json) end it 'private' do get '/', {}, 'HTTP_ACCEPT' => 'application/vnd.grape-private-v1+json' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ ok: 'private' }.to_json) end it 'default' do get '/' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ ok: 'public' }.to_json) end end end grape-1.0.2/spec/grape/api/deeply_included_options_spec.rb0000644000004100000410000000216413231337007023706 0ustar www-datawww-datarequire 'spec_helper' module DeeplyIncludedOptionsSpec module Defaults extend ActiveSupport::Concern included do format :json end end module Admin module Defaults extend ActiveSupport::Concern include DeeplyIncludedOptionsSpec::Defaults end class Users < Grape::API include DeeplyIncludedOptionsSpec::Admin::Defaults resource :users do get do status 200 end end end end class Main < Grape::API mount DeeplyIncludedOptionsSpec::Admin::Users end end describe Grape::API do subject { DeeplyIncludedOptionsSpec::Main } def app subject end it 'works for unspecified format' do get '/users' expect(last_response.status).to eql 200 expect(last_response.content_type).to eql 'application/json' end it 'works for specified format' do get '/users.json' expect(last_response.status).to eql 200 expect(last_response.content_type).to eql 'application/json' end it "doesn't work for format different than specified" do get '/users.txt' expect(last_response.status).to eql 404 end end grape-1.0.2/spec/grape/api/required_parameters_in_route_spec.rb0000644000004100000410000000122613231337007024747 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Endpoint do subject { Class.new(Grape::API) } def app subject end before do subject.namespace :api do get ':id' do [params[:id], params[:ext]].compact.join('/') end put ':something_id' do params[:something_id] end end end context 'get' do it 'responds' do get '/api/foo' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'foo' end end context 'put' do it 'responds' do put '/api/foo' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'foo' end end end grape-1.0.2/spec/grape/api/recognize_path_spec.rb0000644000004100000410000000104713231337007022002 0ustar www-datawww-datarequire 'spec_helper' describe Grape::API do describe '.recognize_path' do subject { Class.new(Grape::API) } it 'fetches endpoint by given path' do subject.get('/foo/:id') {} subject.get('/bar/:id') {} subject.get('/baz/:id') {} actual = subject.recognize_path('/bar/1234').routes[0].origin expect(actual).to eq('/bar/:id') end it 'returns nil if given path does not match with registered routes' do subject.get {} expect(subject.recognize_path('/bar/1234')).to be_nil end end end grape-1.0.2/spec/grape/entity_spec.rb0000644000004100000410000002157413231337007017553 0ustar www-datawww-datarequire 'spec_helper' require 'grape_entity' describe Grape::Entity do subject { Class.new(Grape::API) } def app subject end describe '#present' do it 'sets the object as the body if no options are provided' do inner_body = nil subject.get '/example' do present(abc: 'def') inner_body = body end get '/example' expect(inner_body).to eql(abc: 'def') end it 'calls through to the provided entity class if one is given' do entity_mock = Object.new allow(entity_mock).to receive(:represent) subject.get '/example' do present Object.new, with: entity_mock end get '/example' end it 'pulls a representation from the class options if it exists' do entity = Class.new(Grape::Entity) allow(entity).to receive(:represent).and_return('Hiya') subject.represent Object, with: entity subject.get '/example' do present Object.new end get '/example' expect(last_response.body).to eq('Hiya') end it 'pulls a representation from the class options if the presented object is a collection of objects' do entity = Class.new(Grape::Entity) allow(entity).to receive(:represent).and_return('Hiya') module EntitySpec class TestObject end class FakeCollection def first TestObject.new end end end subject.represent EntitySpec::TestObject, with: entity subject.get '/example' do present [EntitySpec::TestObject.new] end subject.get '/example2' do present EntitySpec::FakeCollection.new end get '/example' expect(last_response.body).to eq('Hiya') get '/example2' expect(last_response.body).to eq('Hiya') end it 'pulls a representation from the class ancestor if it exists' do entity = Class.new(Grape::Entity) allow(entity).to receive(:represent).and_return('Hiya') subclass = Class.new(Object) subject.represent Object, with: entity subject.get '/example' do present subclass.new end get '/example' expect(last_response.body).to eq('Hiya') end it 'automatically uses Klass::Entity if that exists' do some_model = Class.new entity = Class.new(Grape::Entity) allow(entity).to receive(:represent).and_return('Auto-detect!') some_model.const_set :Entity, entity subject.get '/example' do present some_model.new end get '/example' expect(last_response.body).to eq('Auto-detect!') end it 'automatically uses Klass::Entity based on the first object in the collection being presented' do some_model = Class.new entity = Class.new(Grape::Entity) allow(entity).to receive(:represent).and_return('Auto-detect!') some_model.const_set :Entity, entity subject.get '/example' do present [some_model.new] end get '/example' expect(last_response.body).to eq('Auto-detect!') end it 'does not run autodetection for Entity when explicitely provided' do entity = Class.new(Grape::Entity) some_array = [] subject.get '/example' do present some_array, with: entity end expect(some_array).not_to receive(:first) get '/example' end it 'does not use #first method on ActiveRecord::Relation to prevent needless sql query' do entity = Class.new(Grape::Entity) some_relation = Class.new some_model = Class.new allow(entity).to receive(:represent).and_return('Auto-detect!') allow(some_relation).to receive(:first) allow(some_relation).to receive(:klass).and_return(some_model) some_model.const_set :Entity, entity subject.get '/example' do present some_relation end expect(some_relation).not_to receive(:first) get '/example' expect(last_response.body).to eq('Auto-detect!') end it 'autodetection does not use Entity if it is not a presenter' do some_model = Class.new entity = Class.new some_model.class.const_set :Entity, entity subject.get '/example' do present some_model end get '/example' expect(entity).not_to receive(:represent) end it 'adds a root key to the output if one is given' do inner_body = nil subject.get '/example' do present({ abc: 'def' }, root: :root) inner_body = body end get '/example' expect(inner_body).to eql(root: { abc: 'def' }) end %i[json serializable_hash].each do |format| it "presents with #{format}" do entity = Class.new(Grape::Entity) entity.root 'examples', 'example' entity.expose :id subject.format format subject.get '/example' do c = Class.new do attr_reader :id def initialize(id) @id = id end end present c.new(1), with: entity end get '/example' expect(last_response.status).to eq(200) expect(last_response.body).to eq('{"example":{"id":1}}') end it "presents with #{format} collection" do entity = Class.new(Grape::Entity) entity.root 'examples', 'example' entity.expose :id subject.format format subject.get '/examples' do c = Class.new do attr_reader :id def initialize(id) @id = id end end examples = [c.new(1), c.new(2)] present examples, with: entity end get '/examples' expect(last_response.status).to eq(200) expect(last_response.body).to eq('{"examples":[{"id":1},{"id":2}]}') end end it 'presents with xml' do entity = Class.new(Grape::Entity) entity.root 'examples', 'example' entity.expose :name subject.format :xml subject.get '/example' do c = Class.new do attr_reader :name def initialize(args) @name = args[:name] || 'no name set' end end present c.new(name: 'johnnyiller'), with: entity end get '/example' expect(last_response.status).to eq(200) expect(last_response.headers['Content-type']).to eq('application/xml') expect(last_response.body).to eq <<-XML johnnyiller XML end it 'presents with json' do entity = Class.new(Grape::Entity) entity.root 'examples', 'example' entity.expose :name subject.format :json subject.get '/example' do c = Class.new do attr_reader :name def initialize(args) @name = args[:name] || 'no name set' end end present c.new(name: 'johnnyiller'), with: entity end get '/example' expect(last_response.status).to eq(200) expect(last_response.headers['Content-type']).to eq('application/json') expect(last_response.body).to eq('{"example":{"name":"johnnyiller"}}') end it 'presents with jsonp utilising Rack::JSONP' do # Include JSONP middleware subject.use Rack::JSONP entity = Class.new(Grape::Entity) entity.root 'examples', 'example' entity.expose :name # Rack::JSONP expects a standard JSON response in UTF-8 format subject.format :json subject.formatter :json, lambda { |object, _| object.to_json.encode('utf-8') } subject.get '/example' do c = Class.new do attr_reader :name def initialize(args) @name = args[:name] || 'no name set' end end present c.new(name: 'johnnyiller'), with: entity end get '/example?callback=abcDef' expect(last_response.status).to eq(200) expect(last_response.headers['Content-type']).to eq('application/javascript') expect(last_response.body).to include 'abcDef({"example":{"name":"johnnyiller"}})' end context 'present with multiple entities' do it 'present with multiple entities using optional symbol' do user = Class.new do attr_reader :name def initialize(args) @name = args[:name] || 'no name set' end end user1 = user.new(name: 'user1') user2 = user.new(name: 'user2') entity = Class.new(Grape::Entity) entity.expose :name subject.format :json subject.get '/example' do present :page, 1 present :user1, user1, with: entity present :user2, user2, with: entity end get '/example' expect_response_json = { 'page' => 1, 'user1' => { 'name' => 'user1' }, 'user2' => { 'name' => 'user2' } } expect(JSON(last_response.body)).to eq(expect_response_json) end end end end grape-1.0.2/spec/grape/api_spec.rb0000644000004100000410000031137013231337007017004 0ustar www-datawww-datarequire 'spec_helper' require 'shared/versioning_examples' describe Grape::API do subject { Class.new(Grape::API) } def app subject end describe '.prefix' do it 'routes root through with the prefix' do subject.prefix 'awesome/sauce' subject.get do 'Hello there.' end get 'awesome/sauce/' expect(last_response.status).to eql 200 expect(last_response.body).to eql 'Hello there.' end it 'routes through with the prefix' do subject.prefix 'awesome/sauce' subject.get :hello do 'Hello there.' end get 'awesome/sauce/hello' expect(last_response.body).to eql 'Hello there.' get '/hello' expect(last_response.status).to eql 404 end it 'supports OPTIONS' do subject.prefix 'awesome/sauce' subject.get do 'Hello there.' end options 'awesome/sauce' expect(last_response.status).to eql 204 expect(last_response.body).to be_blank end it 'disallows POST' do subject.prefix 'awesome/sauce' subject.get post 'awesome/sauce' expect(last_response.status).to eql 405 end end describe '.version' do context 'when defined' do it 'returns version value' do subject.version 'v1' expect(subject.version).to eq('v1') end end context 'when not defined' do it 'returns nil' do expect(subject.version).to be_nil end end end describe '.version using path' do it_should_behave_like 'versioning' do let(:macro_options) do { using: :path } end end end describe '.version using param' do it_should_behave_like 'versioning' do let(:macro_options) do { using: :param, parameter: 'apiver' } end end end describe '.version using header' do it_should_behave_like 'versioning' do let(:macro_options) do { using: :header, vendor: 'mycompany', format: 'json' } end end # Behavior as defined by rfc2616 when no header is defined # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html describe 'no specified accept header' do # subject.version 'v1', using: :header # subject.get '/hello' do # 'hello' # end # it 'routes' do # get '/hello' # last_response.status.should eql 200 # end end # pending 'routes if any media type is allowed' end describe '.version using accept_version_header' do it_should_behave_like 'versioning' do let(:macro_options) do { using: :accept_version_header } end end end describe '.represent' do it 'requires a :with option' do expect { subject.represent Object, {} }.to raise_error(Grape::Exceptions::InvalidWithOptionForRepresent) end it 'adds the association to the :representations setting' do klass = Class.new subject.represent Object, with: klass expect(subject.namespace_stackable_with_hash(:representations)[Object]).to eq(klass) end end describe '.namespace' do it 'is retrievable and converted to a path' do internal_namespace = nil subject.namespace :awesome do internal_namespace = namespace end expect(internal_namespace).to eql('/awesome') end it 'comes after the prefix and version' do subject.prefix :rad subject.version 'v1', using: :path subject.namespace :awesome do get('/hello') { 'worked' } end get '/rad/v1/awesome/hello' expect(last_response.body).to eq('worked') end it 'cancels itself after the block is over' do internal_namespace = nil subject.namespace :awesome do internal_namespace = namespace end expect(subject.namespace).to eql('/') end it 'is stackable' do internal_namespace = nil internal_second_namespace = nil subject.namespace :awesome do internal_namespace = namespace namespace :rad do internal_second_namespace = namespace end end expect(internal_namespace).to eq('/awesome') expect(internal_second_namespace).to eq('/awesome/rad') end it 'accepts path segments correctly' do inner_namespace = nil subject.namespace :members do namespace '/:member_id' do inner_namespace = namespace get '/' do params[:member_id] end end end get '/members/23' expect(last_response.body).to eq('23') expect(inner_namespace).to eq('/members/:member_id') end it 'is callable with nil just to push onto the stack' do subject.namespace do version 'v2', using: :path get('/hello') { 'inner' } end subject.get('/hello') { 'outer' } get '/v2/hello' expect(last_response.body).to eq('inner') get '/hello' expect(last_response.body).to eq('outer') end %w[group resource resources segment].each do |als| it "`.#{als}` is an alias" do inner_namespace = nil subject.send(als, :awesome) do inner_namespace = namespace end expect(inner_namespace).to eq '/awesome' end end end describe '.route_param' do it 'adds a parameterized route segment namespace' do subject.namespace :users do route_param :id do get do params[:id] end end end get '/users/23' expect(last_response.body).to eq('23') end it 'defines requirements with a single hash' do subject.namespace :users do route_param :id, requirements: /[0-9]+/ do get do params[:id] end end end get '/users/michael' expect(last_response.status).to eq(404) get '/users/23' expect(last_response.status).to eq(200) end context 'with param type definitions' do it 'is used by passing to options' do subject.namespace :route_param do route_param :foo, type: Integer do get { params.to_json } end end get '/route_param/1234' expect(last_response.body).to eq('{"foo":1234}') end end end describe '.route' do it 'allows for no path' do subject.namespace :votes do get do 'Votes' end post do 'Created a Vote' end end get '/votes' expect(last_response.body).to eql 'Votes' post '/votes' expect(last_response.body).to eql 'Created a Vote' end it 'handles empty calls' do subject.get '/' get '/' expect(last_response.body).to eql '' end describe 'root routes should work with' do before do subject.format :txt subject.content_type :json, 'application/json' subject.formatter :json, ->(object, _env) { object } def subject.enable_root_route! get('/') { 'root' } end end after do expect(last_response.body).to eql 'root' end describe 'path versioned APIs' do before do subject.version version, using: :path subject.enable_root_route! end context 'when a single version provided' do let(:version) { 'v1' } it 'without a format' do versioned_get '/', 'v1', using: :path end it 'with a format' do get '/v1/.json' end end context 'when array of versions provided' do let(:version) { %w[v1 v2] } it { versioned_get '/', 'v1', using: :path } it { versioned_get '/', 'v2', using: :path } end end it 'header versioned APIs' do subject.version 'v1', using: :header, vendor: 'test' subject.enable_root_route! versioned_get '/', 'v1', using: :header, vendor: 'test' end it 'header versioned APIs with multiple headers' do subject.version %w[v1 v2], using: :header, vendor: 'test' subject.enable_root_route! versioned_get '/', 'v1', using: :header, vendor: 'test' versioned_get '/', 'v2', using: :header, vendor: 'test' end it 'param versioned APIs' do subject.version 'v1', using: :param subject.enable_root_route! versioned_get '/', 'v1', using: :param end it 'Accept-Version header versioned APIs' do subject.version 'v1', using: :accept_version_header subject.enable_root_route! versioned_get '/', 'v1', using: :accept_version_header end it 'unversioned APIs' do subject.enable_root_route! get '/' end end it 'allows for multiple paths' do subject.get(['/abc', '/def']) do 'foo' end get '/abc' expect(last_response.body).to eql 'foo' get '/def' expect(last_response.body).to eql 'foo' end context 'format' do module ApiSpec class DummyFormatClass end end before(:each) do allow_any_instance_of(ApiSpec::DummyFormatClass).to receive(:to_json).and_return('abc') allow_any_instance_of(ApiSpec::DummyFormatClass).to receive(:to_txt).and_return('def') subject.get('/abc') do ApiSpec::DummyFormatClass.new end end it 'allows .json' do get '/abc.json' expect(last_response.status).to eq(200) expect(last_response.body).to eql 'abc' # json-encoded symbol end it 'allows .txt' do get '/abc.txt' expect(last_response.status).to eq(200) expect(last_response.body).to eql 'def' # raw text end end it 'allows for format without corrupting a param' do subject.get('/:id') do { 'id' => params[:id] } end get '/awesome.json' expect(last_response.body).to eql '{"id":"awesome"}' end it 'allows for format in namespace with no path' do subject.namespace :abc do get do ['json'] end end get '/abc.json' expect(last_response.body).to eql '["json"]' end it 'allows for multiple verbs' do subject.route(%i[get post], '/abc') do 'hiya' end subject.endpoints.first.routes.each do |route| expect(route.path).to eql '/abc(.:format)' end get '/abc' expect(last_response.body).to eql 'hiya' post '/abc' expect(last_response.body).to eql 'hiya' end %i[put post].each do |verb| context verb do ['string', :symbol, 1, -1.1, {}, [], true, false, nil].each do |object| it "allows a(n) #{object.class} json object in params" do subject.format :json subject.send(verb) do env['api.request.body'] end send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(verb == :post ? 201 : 200) expect(last_response.body).to eql ::Grape::Json.dump(object) expect(last_request.params).to eql({}) end it 'stores input in api.request.input' do subject.format :json subject.send(verb) do env['api.request.input'] end send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(verb == :post ? 201 : 200) expect(last_response.body).to eql ::Grape::Json.dump(object).to_json end context 'chunked transfer encoding' do it 'stores input in api.request.input' do subject.format :json subject.send(verb) do env['api.request.input'] end send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json', 'HTTP_TRANSFER_ENCODING' => 'chunked', 'CONTENT_LENGTH' => nil expect(last_response.status).to eq(verb == :post ? 201 : 200) expect(last_response.body).to eql ::Grape::Json.dump(object).to_json end end end end end it 'allows for multipart paths' do subject.route(%i[get post], '/:id/first') do 'first' end subject.route(%i[get post], '/:id') do 'ola' end subject.route(%i[get post], '/:id/first/second') do 'second' end get '/1' expect(last_response.body).to eql 'ola' post '/1' expect(last_response.body).to eql 'ola' get '/1/first' expect(last_response.body).to eql 'first' post '/1/first' expect(last_response.body).to eql 'first' get '/1/first/second' expect(last_response.body).to eql 'second' end it 'allows for :any as a verb' do subject.route(:any, '/abc') do 'lol' end %w[get post put delete options patch].each do |m| send(m, '/abc') expect(last_response.body).to eql 'lol' end end it 'allows for catch-all in a namespace' do subject.namespace :nested do get do 'root' end get 'something' do 'something' end route :any, '*path' do 'catch-all' end end get 'nested' expect(last_response.body).to eql 'root' get 'nested/something' expect(last_response.body).to eql 'something' get 'nested/missing' expect(last_response.body).to eql 'catch-all' post 'nested' expect(last_response.body).to eql 'catch-all' post 'nested/something' expect(last_response.body).to eql 'catch-all' end verbs = %w[post get head delete put options patch] verbs.each do |verb| it "allows and properly constrain a #{verb.upcase} method" do subject.send(verb, '/example') do verb end send(verb, '/example') expect(last_response.body).to eql verb == 'head' ? '' : verb # Call it with all methods other than the properly constrained one. (verbs - [verb]).each do |other_verb| send(other_verb, '/example') expected_rc = if other_verb == 'options' then 204 elsif other_verb == 'head' && verb == 'get' then 200 else 405 end expect(last_response.status).to eql expected_rc end end end it 'returns a 201 response code for POST by default' do subject.post('example') do 'Created' end post '/example' expect(last_response.status).to eql 201 expect(last_response.body).to eql 'Created' end it 'returns a 405 for an unsupported method with an X-Custom-Header' do subject.before { header 'X-Custom-Header', 'foo' } subject.get 'example' do 'example' end put '/example' expect(last_response.status).to eql 405 expect(last_response.body).to eql '405 Not Allowed' expect(last_response.headers['X-Custom-Header']).to eql 'foo' end it 'runs only the before filter on 405 bad method' do subject.namespace :example do before { header 'X-Custom-Header', 'foo' } before_validation { raise 'before_validation filter should not run' } after_validation { raise 'after_validation filter should not run' } after { raise 'after filter should not run' } params { requires :only_for_get } get end post '/example' expect(last_response.status).to eql 405 expect(last_response.headers['X-Custom-Header']).to eql 'foo' end it 'runs before filter exactly once on 405 bad method' do already_run = false subject.namespace :example do before do raise 'before filter ran twice' if already_run already_run = true header 'X-Custom-Header', 'foo' end get end post '/example' expect(last_response.status).to eql 405 expect(last_response.headers['X-Custom-Header']).to eql 'foo' end it 'runs all filters and body with a custom OPTIONS method' do subject.namespace :example do before { header 'X-Custom-Header-1', 'foo' } before_validation { header 'X-Custom-Header-2', 'foo' } after_validation { header 'X-Custom-Header-3', 'foo' } after { header 'X-Custom-Header-4', 'foo' } options { 'yup' } get end options '/example' expect(last_response.status).to eql 200 expect(last_response.body).to eql 'yup' expect(last_response.headers['Allow']).to be_nil expect(last_response.headers['X-Custom-Header-1']).to eql 'foo' expect(last_response.headers['X-Custom-Header-2']).to eql 'foo' expect(last_response.headers['X-Custom-Header-3']).to eql 'foo' expect(last_response.headers['X-Custom-Header-4']).to eql 'foo' end context 'when format is xml' do it 'returns a 405 for an unsupported method' do subject.format :xml subject.get 'example' do 'example' end put '/example' expect(last_response.status).to eql 405 expect(last_response.body).to eq <<-XML 405 Not Allowed XML end end context 'when accessing env' do it 'returns a 405 for an unsupported method' do subject.before do _customheader1 = headers['X-Custom-Header'] _customheader2 = env['HTTP_X_CUSTOM_HEADER'] end subject.get 'example' do 'example' end put '/example' expect(last_response.status).to eql 405 expect(last_response.body).to eql '405 Not Allowed' end end specify '405 responses includes an Allow header specifying supported methods' do subject.get 'example' do 'example' end subject.post 'example' do 'example' end put '/example' expect(last_response.headers['Allow']).to eql 'OPTIONS, GET, POST, HEAD' end specify '405 responses includes an Content-Type header' do subject.get 'example' do 'example' end subject.post 'example' do 'example' end put '/example' expect(last_response.headers['Content-Type']).to eql 'text/plain' end describe 'adds an OPTIONS route that' do before do subject.before { header 'X-Custom-Header', 'foo' } subject.before_validation { header 'X-Custom-Header-2', 'bar' } subject.after_validation { header 'X-Custom-Header-3', 'baz' } subject.after { header 'X-Custom-Header-4', 'bing' } subject.params { requires :only_for_get } subject.get 'example' do 'example' end subject.route :any, '*path' do error! :not_found, 404 end options '/example' end it 'returns a 204' do expect(last_response.status).to eql 204 end it 'has an empty body' do expect(last_response.body).to be_blank end it 'has an Allow header' do expect(last_response.headers['Allow']).to eql 'OPTIONS, GET, HEAD' end it 'calls before hook' do expect(last_response.headers['X-Custom-Header']).to eql 'foo' end it 'does not call before_validation hook' do expect(last_response.headers.key?('X-Custom-Header-2')).to be false end it 'does not call after_validation hook' do expect(last_response.headers.key?('X-Custom-Header-3')).to be false end it 'calls after hook' do expect(last_response.headers['X-Custom-Header-4']).to eq 'bing' end it 'has no Content-Type' do expect(last_response.content_type).to be_nil end it 'has no Content-Length' do expect(last_response.content_length).to be_nil end end describe 'adds an OPTIONS route for namespaced endpoints that' do before do subject.before { header 'X-Custom-Header', 'foo' } subject.namespace :example do before { header 'X-Custom-Header-2', 'foo' } get :inner do 'example/inner' end end options '/example/inner' end it 'returns a 204' do expect(last_response.status).to eql 204 end it 'has an empty body' do expect(last_response.body).to be_blank end it 'has an Allow header' do expect(last_response.headers['Allow']).to eql 'OPTIONS, GET, HEAD' end it 'calls the outer before filter' do expect(last_response.headers['X-Custom-Header']).to eql 'foo' end it 'calls the inner before filter' do expect(last_response.headers['X-Custom-Header-2']).to eql 'foo' end it 'has no Content-Type' do expect(last_response.content_type).to be_nil end it 'has no Content-Length' do expect(last_response.content_length).to be_nil end end describe 'adds a 405 Not Allowed route that' do before do subject.before { header 'X-Custom-Header', 'foo' } subject.post :example do 'example' end get '/example' end it 'returns a 405' do expect(last_response.status).to eql 405 end it 'contains error message in body' do expect(last_response.body).to eq '405 Not Allowed' end it 'has an Allow header' do expect(last_response.headers['Allow']).to eql 'OPTIONS, POST' end it 'has a X-Custom-Header' do expect(last_response.headers['X-Custom-Header']).to eql 'foo' end end context 'allows HEAD on a GET request that' do before do subject.get 'example' do 'example' end subject.route :any, '*path' do error! :not_found, 404 end head '/example' end it 'returns a 200' do expect(last_response.status).to eql 200 end it 'has an empty body' do expect(last_response.body).to eql '' end end it 'overwrites the default HEAD request' do subject.head 'example' do error! 'nothing to see here', 400 end subject.get 'example' do 'example' end head '/example' expect(last_response.status).to eql 400 end end context 'do_not_route_head!' do before :each do subject.do_not_route_head! subject.get 'example' do 'example' end end it 'options does not contain HEAD' do options '/example' expect(last_response.status).to eql 204 expect(last_response.body).to eql '' expect(last_response.headers['Allow']).to eql 'OPTIONS, GET' end it 'does not allow HEAD on a GET request' do head '/example' expect(last_response.status).to eql 405 end end context 'do_not_route_options!' do before :each do subject.do_not_route_options! subject.get 'example' do 'example' end end it 'does not create an OPTIONS route' do options '/example' expect(last_response.status).to eql 405 end it 'does not include OPTIONS in Allow header' do options '/example' expect(last_response.status).to eql 405 expect(last_response.headers['Allow']).to eql 'GET, HEAD' end end describe 'filters' do it 'adds a before filter' do subject.before { @foo = 'first' } subject.before { @bar = 'second' } subject.get '/' do "#{@foo} #{@bar}" end get '/' expect(last_response.body).to eql 'first second' end it 'adds a before filter to current and child namespaces only' do subject.get '/' do "root - #{@foo}" end subject.namespace :blah do before { @foo = 'foo' } get '/' do "blah - #{@foo}" end namespace :bar do get '/' do "blah - bar - #{@foo}" end end end get '/' expect(last_response.body).to eql 'root - ' get '/blah' expect(last_response.body).to eql 'blah - foo' get '/blah/bar' expect(last_response.body).to eql 'blah - bar - foo' end it 'adds a after_validation filter' do subject.after_validation { @foo = "first #{params[:id]}:#{params[:id].class}" } subject.after_validation { @bar = 'second' } subject.params do requires :id, type: Integer end subject.get '/' do "#{@foo} #{@bar}" end get '/', id: '32' expect(last_response.body).to eql "first 32:#{integer_class_name} second" end it 'adds a after filter' do m = double('after mock') subject.after { m.do_something! } subject.after { m.do_something! } subject.get '/' do @var ||= 'default' end expect(m).to receive(:do_something!).exactly(2).times get '/' expect(last_response.body).to eql 'default' end it 'calls all filters when validation passes' do a = double('before mock') b = double('before_validation mock') c = double('after_validation mock') d = double('after mock') subject.params do requires :id, type: Integer end subject.resource ':id' do before { a.do_something! } before_validation { b.do_something! } after_validation { c.do_something! } after { d.do_something! } get do 'got it' end end expect(a).to receive(:do_something!).exactly(1).times expect(b).to receive(:do_something!).exactly(1).times expect(c).to receive(:do_something!).exactly(1).times expect(d).to receive(:do_something!).exactly(1).times get '/123' expect(last_response.status).to eql 200 expect(last_response.body).to eql 'got it' end it 'calls only before filters when validation fails' do a = double('before mock') b = double('before_validation mock') c = double('after_validation mock') d = double('after mock') subject.params do requires :id, type: Integer end subject.resource ':id' do before { a.do_something! } before_validation { b.do_something! } after_validation { c.do_something! } after { d.do_something! } get do 'got it' end end expect(a).to receive(:do_something!).exactly(1).times expect(b).to receive(:do_something!).exactly(1).times expect(c).to receive(:do_something!).exactly(0).times expect(d).to receive(:do_something!).exactly(0).times get '/abc' expect(last_response.status).to eql 400 expect(last_response.body).to eql 'id is invalid' end it 'calls filters in the correct order' do i = 0 a = double('before mock') b = double('before_validation mock') c = double('after_validation mock') d = double('after mock') subject.params do requires :id, type: Integer end subject.resource ':id' do before { a.here(i += 1) } before_validation { b.here(i += 1) } after_validation { c.here(i += 1) } after { d.here(i += 1) } get do 'got it' end end expect(a).to receive(:here).with(1).exactly(1).times expect(b).to receive(:here).with(2).exactly(1).times expect(c).to receive(:here).with(3).exactly(1).times expect(d).to receive(:here).with(4).exactly(1).times get '/123' expect(last_response.status).to eql 200 expect(last_response.body).to eql 'got it' end end context 'format' do before do subject.get('/foo') { 'bar' } end it 'sets content type for txt format' do get '/foo' expect(last_response.headers['Content-Type']).to eq('text/plain') end it 'sets content type for xml' do get '/foo.xml' expect(last_response.headers['Content-Type']).to eq('application/xml') end it 'sets content type for json' do get '/foo.json' expect(last_response.headers['Content-Type']).to eq('application/json') end it 'sets content type for serializable hash format' do get '/foo.serializable_hash' expect(last_response.headers['Content-Type']).to eq('application/json') end it 'sets content type for binary format' do get '/foo.binary' expect(last_response.headers['Content-Type']).to eq('application/octet-stream') end it 'returns raw data when content type binary' do image_filename = 'grape.png' file = File.open(image_filename, 'rb', &:read) subject.format :binary subject.get('/binary_file') { File.binread(image_filename) } get '/binary_file' expect(last_response.headers['Content-Type']).to eq('application/octet-stream') expect(last_response.body).to eq(file) end it 'returns the content of the file with file' do file_content = 'This is some file content' test_file = Tempfile.new('test') test_file.write file_content test_file.rewind subject.get('/file') { file test_file } get '/file' expect(last_response.headers['Content-Length']).to eq('25') expect(last_response.headers['Content-Type']).to eq('text/plain') expect(last_response.body).to eq(file_content) end it 'streams the content of the file with stream' do test_stream = Enumerator.new do |blk| blk.yield 'This is some' blk.yield ' file content' end subject.use Rack::Chunked subject.get('/stream') { stream test_stream } get '/stream', {}, 'HTTP_VERSION' => 'HTTP/1.1' expect(last_response.headers['Content-Type']).to eq('text/plain') expect(last_response.headers['Content-Length']).to eq(nil) expect(last_response.headers['Cache-Control']).to eq('no-cache') expect(last_response.headers['Transfer-Encoding']).to eq('chunked') expect(last_response.body).to eq("c\r\nThis is some\r\nd\r\n file content\r\n0\r\n\r\n") end it 'sets content type for error' do subject.get('/error') { error!('error in plain text', 500) } get '/error' expect(last_response.headers['Content-Type']).to eql 'text/plain' end it 'sets content type for json error' do subject.format :json subject.get('/error') { error!('error in json', 500) } get '/error.json' expect(last_response.status).to eql 500 expect(last_response.headers['Content-Type']).to eql 'application/json' end it 'sets content type for xml error' do subject.format :xml subject.get('/error') { error!('error in xml', 500) } get '/error' expect(last_response.status).to eql 500 expect(last_response.headers['Content-Type']).to eql 'application/xml' end it 'includes extension in format' do subject.get(':id') { params[:format] } get '/baz.bar' expect(last_response.status).to eq 200 expect(last_response.body).to eq 'bar' end it 'does not include extension in id' do subject.format :json subject.get(':id') { params } get '/baz.bar' expect(last_response.status).to eq 404 end context 'with a custom content_type' do before do subject.content_type :custom, 'application/custom' subject.formatter :custom, ->(_object, _env) { 'custom' } subject.get('/custom') { 'bar' } subject.get('/error') { error!('error in custom', 500) } end it 'sets content type' do get '/custom.custom' expect(last_response.headers['Content-Type']).to eql 'application/custom' end it 'sets content type for error' do get '/error.custom' expect(last_response.headers['Content-Type']).to eql 'application/custom' end end context 'env["api.format"]' do before do subject.post 'attachment' do filename = params[:file][:filename] content_type MIME::Types.type_for(filename)[0].to_s env['api.format'] = :binary # there's no formatter for :binary, data will be returned "as is" header 'Content-Disposition', "attachment; filename*=UTF-8''#{CGI.escape(filename)}" params[:file][:tempfile].read end end ['/attachment.png', 'attachment'].each do |url| it "uploads and downloads a PNG file via #{url}" do image_filename = 'grape.png' post url, file: Rack::Test::UploadedFile.new(image_filename, 'image/png', true) expect(last_response.status).to eq(201) expect(last_response.headers['Content-Type']).to eq('image/png') expect(last_response.headers['Content-Disposition']).to eq("attachment; filename*=UTF-8''grape.png") File.open(image_filename, 'rb') do |io| expect(last_response.body).to eq io.read end end end it 'uploads and downloads a Ruby file' do filename = __FILE__ post '/attachment.rb', file: Rack::Test::UploadedFile.new(filename, 'application/x-ruby', true) expect(last_response.status).to eq(201) expect(last_response.headers['Content-Type']).to eq('application/x-ruby') expect(last_response.headers['Content-Disposition']).to eq("attachment; filename*=UTF-8''api_spec.rb") File.open(filename, 'rb') do |io| expect(last_response.body).to eq io.read end end end end context 'custom middleware' do module ApiSpec class PhonyMiddleware def initialize(app, *args) @args = args @app = app @block = block_given? ? true : nil end def call(env) env['phony.args'] ||= [] env['phony.args'] << @args env['phony.block'] = true if @block @app.call(env) end end end describe '.middleware' do it 'includes middleware arguments from settings' do subject.use ApiSpec::PhonyMiddleware, 'abc', 123 expect(subject.middleware).to eql [[:use, ApiSpec::PhonyMiddleware, 'abc', 123]] end it 'includes all middleware from stacked settings' do subject.use ApiSpec::PhonyMiddleware, 123 subject.use ApiSpec::PhonyMiddleware, 'abc' subject.use ApiSpec::PhonyMiddleware, 'foo' expect(subject.middleware).to eql [ [:use, ApiSpec::PhonyMiddleware, 123], [:use, ApiSpec::PhonyMiddleware, 'abc'], [:use, ApiSpec::PhonyMiddleware, 'foo'] ] end end describe '.use' do it 'adds middleware' do subject.use ApiSpec::PhonyMiddleware, 123 expect(subject.middleware).to eql [[:use, ApiSpec::PhonyMiddleware, 123]] end it 'does not show up outside the namespace' do inner_middleware = nil subject.use ApiSpec::PhonyMiddleware, 123 subject.namespace :awesome do use ApiSpec::PhonyMiddleware, 'abc' inner_middleware = middleware end expect(subject.middleware).to eql [[:use, ApiSpec::PhonyMiddleware, 123]] expect(inner_middleware).to eql [[:use, ApiSpec::PhonyMiddleware, 123], [:use, ApiSpec::PhonyMiddleware, 'abc']] end it 'calls the middleware' do subject.use ApiSpec::PhonyMiddleware, 'hello' subject.get '/' do env['phony.args'].first.first end get '/' expect(last_response.body).to eql 'hello' end it 'adds a block if one is given' do block = -> {} subject.use ApiSpec::PhonyMiddleware, &block expect(subject.middleware).to eql [[:use, ApiSpec::PhonyMiddleware, block]] end it 'uses a block if one is given' do block = -> {} subject.use ApiSpec::PhonyMiddleware, &block subject.get '/' do env['phony.block'].inspect end get '/' expect(last_response.body).to eq('true') end it 'does not destroy the middleware settings on multiple runs' do block = -> {} subject.use ApiSpec::PhonyMiddleware, &block subject.get '/' do env['phony.block'].inspect end 2.times do get '/' expect(last_response.body).to eq('true') end end it 'mounts behind error middleware' do m = Class.new(Grape::Middleware::Base) do def before throw :error, message: 'Caught in the Net', status: 400 end end subject.use m subject.get '/' do end get '/' expect(last_response.status).to eq(400) expect(last_response.body).to eq('Caught in the Net') end end describe '.insert_before' do it 'runs before a given middleware' do m = Class.new(Grape::Middleware::Base) do def call(env) env['phony.args'] ||= [] env['phony.args'] << @options[:message] @app.call(env) end end subject.use ApiSpec::PhonyMiddleware, 'hello' subject.insert_before ApiSpec::PhonyMiddleware, m, message: 'bye' subject.get '/' do env['phony.args'].join(' ') end get '/' expect(last_response.body).to eql 'bye hello' end end describe '.insert_after' do it 'runs after a given middleware' do m = Class.new(Grape::Middleware::Base) do def call(env) env['phony.args'] ||= [] env['phony.args'] << @options[:message] @app.call(env) end end subject.use ApiSpec::PhonyMiddleware, 'hello' subject.insert_after ApiSpec::PhonyMiddleware, m, message: 'bye' subject.get '/' do env['phony.args'].join(' ') end get '/' expect(last_response.body).to eql 'hello bye' end end end describe '.http_basic' do it 'protects any resources on the same scope' do subject.http_basic do |u, _p| u == 'allow' end subject.get(:hello) { 'Hello, world.' } get '/hello' expect(last_response.status).to eql 401 get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('allow', 'whatever') expect(last_response.status).to eql 200 end it 'is scopable' do subject.get(:hello) { 'Hello, world.' } subject.namespace :admin do http_basic do |u, _p| u == 'allow' end get(:hello) { 'Hello, world.' } end get '/hello' expect(last_response.status).to eql 200 get '/admin/hello' expect(last_response.status).to eql 401 end it 'is callable via .auth as well' do subject.auth :http_basic do |u, _p| u == 'allow' end subject.get(:hello) { 'Hello, world.' } get '/hello' expect(last_response.status).to eql 401 get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('allow', 'whatever') expect(last_response.status).to eql 200 end it 'has access to the current endpoint' do basic_auth_context = nil subject.http_basic do |u, _p| basic_auth_context = self u == 'allow' end subject.get(:hello) { 'Hello, world.' } get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('allow', 'whatever') expect(basic_auth_context).to be_a_kind_of(Grape::Endpoint) end it 'has access to helper methods' do subject.helpers do def authorize(u, p) u == 'allow' && p == 'whatever' end end subject.http_basic do |u, p| authorize(u, p) end subject.get(:hello) { 'Hello, world.' } get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('allow', 'whatever') expect(last_response.status).to eql 200 get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('disallow', 'whatever') expect(last_response.status).to eql 401 end it 'can set instance variables accessible to routes' do subject.http_basic do |u, _p| @hello = 'Hello, world.' u == 'allow' end subject.get(:hello) { @hello } get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('allow', 'whatever') expect(last_response.status).to eql 200 expect(last_response.body).to eql 'Hello, world.' end end describe '.logger' do subject do Class.new(Grape::API) do def self.io @io ||= StringIO.new end logger ::Logger.new(io) end end it 'returns an instance of Logger class by default' do expect(subject.logger.class).to eql Logger end it 'allows setting a custom logger' do mylogger = Class.new subject.logger mylogger expect(mylogger).to receive(:info).exactly(1).times subject.logger.info 'this will be logged' end it 'defaults to a standard logger log format' do t = Time.at(100) allow(Time).to receive(:now).and_return(t) message = "this will be logged\n" message = "I, [#{Logger::Formatter.new.send(:format_datetime, t)}\##{Process.pid}] INFO -- : #{message}" if !defined?(Rails) || Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('4.0') expect(subject.io).to receive(:write).with(message) subject.logger.info 'this will be logged' end end describe '.helpers' do it 'is accessible from the endpoint' do subject.helpers do def hello 'Hello, world.' end end subject.get '/howdy' do hello end get '/howdy' expect(last_response.body).to eql 'Hello, world.' end it 'is scopable' do subject.helpers do def generic 'always there' end end subject.namespace :admin do helpers do def secret 'only in admin' end end get '/secret' do [generic, secret].join ':' end end subject.get '/generic' do [generic, respond_to?(:secret)].join ':' end get '/generic' expect(last_response.body).to eql 'always there:false' get '/admin/secret' expect(last_response.body).to eql 'always there:only in admin' end it 'is reopenable' do subject.helpers do def one 1 end end subject.helpers do def two 2 end end subject.get 'howdy' do [one, two] end expect { get '/howdy' }.not_to raise_error end it 'allows for modules' do mod = Module.new do def hello 'Hello, world.' end end subject.helpers mod subject.get '/howdy' do hello end get '/howdy' expect(last_response.body).to eql 'Hello, world.' end it 'allows multiple calls with modules and blocks' do subject.helpers Module.new do def one 1 end end subject.helpers Module.new do def two 2 end end subject.helpers do def three 3 end end subject.get 'howdy' do [one, two, three] end expect { get '/howdy' }.not_to raise_error end end describe '.scope' do # TODO: refactor this to not be tied to versioning. How about a generic # .setting macro? it 'scopes the various settings' do subject.prefix 'new' subject.scope :legacy do prefix 'legacy' get '/abc' do 'abc' end end subject.get '/def' do 'def' end get '/new/abc' expect(last_response.status).to eql 404 get '/legacy/abc' expect(last_response.status).to eql 200 get '/legacy/def' expect(last_response.status).to eql 404 get '/new/def' expect(last_response.status).to eql 200 end end describe '.rescue_from' do it 'does not rescue errors when rescue_from is not set' do subject.get '/exception' do raise 'rain!' end expect { get '/exception' }.to raise_error(RuntimeError, 'rain!') end it 'uses custom helpers defined by using #helpers method' do subject.helpers do def custom_error!(name) error! "hello #{name}" end end subject.rescue_from(ArgumentError) { custom_error! :bob } subject.get '/custom_error' do raise ArgumentError end get '/custom_error' expect(last_response.body).to eq 'hello bob' end context 'with multiple apis' do let(:a) { Class.new(Grape::API) } let(:b) { Class.new(Grape::API) } before do a.helpers do def foo error!('foo', 401) end end a.rescue_from(:all) { foo } a.get { raise 'boo' } b.helpers do def foo error!('bar', 401) end end b.rescue_from(:all) { foo } b.get { raise 'boo' } end it 'avoids polluting global namespace' do env = Rack::MockRequest.env_for('/') expect(a.call(env)[2].body).to eq(['foo']) expect(b.call(env)[2].body).to eq(['bar']) expect(a.call(env)[2].body).to eq(['foo']) end end it 'rescues all errors if rescue_from :all is called' do subject.rescue_from :all subject.get '/exception' do raise 'rain!' end get '/exception' expect(last_response.status).to eql 500 expect(last_response.body).to eq 'rain!' end it 'rescues all errors with a json formatter' do subject.format :json subject.default_format :json subject.rescue_from :all subject.get '/exception' do raise 'rain!' end get '/exception' expect(last_response.status).to eql 500 expect(last_response.body).to eq({ error: 'rain!' }.to_json) end it 'rescues only certain errors if rescue_from is called with specific errors' do subject.rescue_from ArgumentError subject.get('/rescued') { raise ArgumentError } subject.get('/unrescued') { raise 'beefcake' } get '/rescued' expect(last_response.status).to eql 500 expect { get '/unrescued' }.to raise_error(RuntimeError, 'beefcake') end context 'CustomError subclass of Grape::Exceptions::Base' do before do module ApiSpec class CustomError < Grape::Exceptions::Base; end end end it 'does not re-raise exceptions of type Grape::Exceptions::Base' do subject.get('/custom_exception') { raise ApiSpec::CustomError } expect { get '/custom_exception' }.not_to raise_error end it 'rescues custom grape exceptions' do subject.rescue_from ApiSpec::CustomError do |e| rack_response('New Error', e.status) end subject.get '/custom_error' do raise ApiSpec::CustomError, status: 400, message: 'Custom Error' end get '/custom_error' expect(last_response.status).to eq(400) expect(last_response.body).to eq('New Error') end end it 'can rescue exceptions raised in the formatter' do formatter = double(:formatter) allow(formatter).to receive(:call) { raise StandardError } allow(Grape::Formatter).to receive(:formatter_for) { formatter } subject.rescue_from :all do |_e| rack_response('Formatter Error', 500) end subject.get('/formatter_exception') { 'Hello world' } get '/formatter_exception' expect(last_response.status).to eql 500 expect(last_response.body).to eq('Formatter Error') end end describe '.rescue_from klass, block' do it 'rescues Exception' do subject.rescue_from RuntimeError do |e| rack_response("rescued from #{e.message}", 202) end subject.get '/exception' do raise 'rain!' end get '/exception' expect(last_response.status).to eql 202 expect(last_response.body).to eq('rescued from rain!') end context 'custom errors' do before do class ConnectionError < RuntimeError; end class DatabaseError < RuntimeError; end class CommunicationError < StandardError; end end it 'rescues an error via rescue_from :all' do subject.rescue_from :all do |e| rack_response("rescued from #{e.class.name}", 500) end subject.get '/exception' do raise ConnectionError end get '/exception' expect(last_response.status).to eql 500 expect(last_response.body).to eq('rescued from ConnectionError') end it 'rescues a specific error' do subject.rescue_from ConnectionError do |e| rack_response("rescued from #{e.class.name}", 500) end subject.get '/exception' do raise ConnectionError end get '/exception' expect(last_response.status).to eql 500 expect(last_response.body).to eq('rescued from ConnectionError') end it 'rescues a subclass of an error by default' do subject.rescue_from RuntimeError do |e| rack_response("rescued from #{e.class.name}", 500) end subject.get '/exception' do raise ConnectionError end get '/exception' expect(last_response.status).to eql 500 expect(last_response.body).to eq('rescued from ConnectionError') end it 'rescues multiple specific errors' do subject.rescue_from ConnectionError do |e| rack_response("rescued from #{e.class.name}", 500) end subject.rescue_from DatabaseError do |e| rack_response("rescued from #{e.class.name}", 500) end subject.get '/connection' do raise ConnectionError end subject.get '/database' do raise DatabaseError end get '/connection' expect(last_response.status).to eql 500 expect(last_response.body).to eq('rescued from ConnectionError') get '/database' expect(last_response.status).to eql 500 expect(last_response.body).to eq('rescued from DatabaseError') end it 'does not rescue a different error' do subject.rescue_from RuntimeError do |e| rack_response("rescued from #{e.class.name}", 500) end subject.get '/uncaught' do raise CommunicationError end expect { get '/uncaught' }.to raise_error(CommunicationError) end end end describe '.rescue_from klass, lambda' do it 'rescues an error with the lambda' do subject.rescue_from ArgumentError, lambda { rack_response('rescued with a lambda', 400) } subject.get('/rescue_lambda') { raise ArgumentError } get '/rescue_lambda' expect(last_response.status).to eq(400) expect(last_response.body).to eq('rescued with a lambda') end it 'can execute the lambda with an argument' do subject.rescue_from ArgumentError, lambda { |e| rack_response(e.message, 400) } subject.get('/rescue_lambda') { raise ArgumentError, 'lambda takes an argument' } get '/rescue_lambda' expect(last_response.status).to eq(400) expect(last_response.body).to eq('lambda takes an argument') end end describe '.rescue_from klass, with: :method_name' do it 'rescues an error with the specified method name' do subject.helpers do def rescue_arg_error error!('500 ArgumentError', 500) end def rescue_no_method_error error!('500 NoMethodError', 500) end end subject.rescue_from ArgumentError, with: :rescue_arg_error subject.rescue_from NoMethodError, with: :rescue_no_method_error subject.get('/rescue_arg_error') { raise ArgumentError } subject.get('/rescue_no_method_error') { raise NoMethodError } get '/rescue_arg_error' expect(last_response.status).to eq(500) expect(last_response.body).to eq('500 ArgumentError') get '/rescue_no_method_error' expect(last_response.status).to eq(500) expect(last_response.body).to eq('500 NoMethodError') end it 'aborts if the specified method name does not exist' do subject.rescue_from :all, with: :not_exist_method subject.get('/rescue_method') { raise StandardError } expect { get '/rescue_method' }.to raise_error(NoMethodError, 'undefined method `not_exist_method\'') end it 'correctly chooses exception handler if :all handler is specified' do subject.helpers do def rescue_arg_error error!('500 ArgumentError', 500) end def rescue_all_errors error!('500 AnotherError', 500) end end subject.rescue_from ArgumentError, with: :rescue_arg_error subject.rescue_from :all, with: :rescue_all_errors subject.get('/argument_error') { raise ArgumentError } subject.get('/another_error') { raise NoMethodError } get '/argument_error' expect(last_response.status).to eq(500) expect(last_response.body).to eq('500 ArgumentError') get '/another_error' expect(last_response.status).to eq(500) expect(last_response.body).to eq('500 AnotherError') end end describe '.rescue_from klass, rescue_subclasses: boolean' do before do module ApiSpec module APIErrors class ParentError < StandardError; end class ChildError < ParentError; end end end end it 'rescues error as well as subclass errors with rescue_subclasses option set' do subject.rescue_from ApiSpec::APIErrors::ParentError, rescue_subclasses: true do |e| rack_response("rescued from #{e.class.name}", 500) end subject.get '/caught_child' do raise ApiSpec::APIErrors::ChildError end subject.get '/caught_parent' do raise ApiSpec::APIErrors::ParentError end subject.get '/uncaught_parent' do raise StandardError end get '/caught_child' expect(last_response.status).to eql 500 get '/caught_parent' expect(last_response.status).to eql 500 expect { get '/uncaught_parent' }.to raise_error(StandardError) end it 'sets rescue_subclasses to true by default' do subject.rescue_from ApiSpec::APIErrors::ParentError do |e| rack_response("rescued from #{e.class.name}", 500) end subject.get '/caught_child' do raise ApiSpec::APIErrors::ChildError end get '/caught_child' expect(last_response.status).to eql 500 end it 'does not rescue child errors if rescue_subclasses is false' do subject.rescue_from ApiSpec::APIErrors::ParentError, rescue_subclasses: false do |e| rack_response("rescued from #{e.class.name}", 500) end subject.get '/uncaught' do raise ApiSpec::APIErrors::ChildError end expect { get '/uncaught' }.to raise_error(ApiSpec::APIErrors::ChildError) end end describe '.error_format' do it 'rescues all errors and return :txt' do subject.rescue_from :all subject.format :txt subject.get '/exception' do raise 'rain!' end get '/exception' expect(last_response.body).to eql 'rain!' end it 'rescues all errors and return :txt with backtrace' do subject.rescue_from :all, backtrace: true subject.format :txt subject.get '/exception' do raise 'rain!' end get '/exception' expect(last_response.body.start_with?("rain!\r\n")).to be true end it 'rescues all errors with a default formatter' do subject.default_format :foo subject.content_type :foo, 'text/foo' subject.rescue_from :all subject.get '/exception' do raise 'rain!' end get '/exception.foo' expect(last_response.body).to start_with 'rain!' end it 'defaults the error formatter to format' do subject.format :json subject.rescue_from :all subject.content_type :json, 'application/json' subject.content_type :foo, 'text/foo' subject.get '/exception' do raise 'rain!' end get '/exception.json' expect(last_response.body).to eq('{"error":"rain!"}') get '/exception.foo' expect(last_response.body).to eq('{"error":"rain!"}') end context 'class' do before :each do module ApiSpec class CustomErrorFormatter def self.call(message, _backtrace, _options, _env, _original_exception) "message: #{message} @backtrace" end end end end it 'returns a custom error format' do subject.rescue_from :all, backtrace: true subject.error_formatter :txt, ApiSpec::CustomErrorFormatter subject.get '/exception' do raise 'rain!' end get '/exception' expect(last_response.body).to eq('message: rain! @backtrace') end end describe 'with' do context 'class' do before :each do module ApiSpec class CustomErrorFormatter def self.call(message, _backtrace, _option, _env, _original_exception) "message: #{message} @backtrace" end end end end it 'returns a custom error format' do subject.rescue_from :all, backtrace: true subject.error_formatter :txt, with: ApiSpec::CustomErrorFormatter subject.get('/exception') { raise 'rain!' } get '/exception' expect(last_response.body).to eq('message: rain! @backtrace') end end end it 'rescues all errors and return :json' do subject.rescue_from :all subject.format :json subject.get '/exception' do raise 'rain!' end get '/exception' expect(last_response.body).to eql '{"error":"rain!"}' end it 'rescues all errors and return :json with backtrace' do subject.rescue_from :all, backtrace: true subject.format :json subject.get '/exception' do raise 'rain!' end get '/exception' json = ::Grape::Json.load(last_response.body) expect(json['error']).to eql 'rain!' expect(json['backtrace'].length).to be > 0 end it 'rescues error! and return txt' do subject.format :txt subject.get '/error' do error!('Access Denied', 401) end get '/error' expect(last_response.body).to eql 'Access Denied' end context 'with json format' do before { subject.format :json } it 'rescues error! called with a string and returns json' do subject.get('/error') { error!(:failure, 401) } end it 'rescues error! called with a symbol and returns json' do subject.get('/error') { error!(:failure, 401) } end it 'rescues error! called with a hash and returns json' do subject.get('/error') { error!({ error: :failure }, 401) } end after do get '/error' expect(last_response.body).to eql('{"error":"failure"}') end end end describe '.content_type' do it 'sets additional content-type' do subject.content_type :xls, 'application/vnd.ms-excel' subject.get :excel do 'some binary content' end get '/excel.xls' expect(last_response.content_type).to eq('application/vnd.ms-excel') end it 'allows to override content-type' do subject.get :content do content_type 'text/javascript' 'var x = 1;' end get '/content' expect(last_response.content_type).to eq('text/javascript') end it 'removes existing content types' do subject.content_type :xls, 'application/vnd.ms-excel' subject.get :excel do 'some binary content' end get '/excel.json' expect(last_response.status).to eq(406) expect(last_response.body).to eq("The requested format 'txt' is not supported.") end end describe '.formatter' do context 'multiple formatters' do before :each do subject.formatter :json, ->(object, _env) { "{\"custom_formatter\":\"#{object[:some]}\"}" } subject.formatter :txt, ->(object, _env) { "custom_formatter: #{object[:some]}" } subject.get :simple do { some: 'hash' } end end it 'sets one formatter' do get '/simple.json' expect(last_response.body).to eql '{"custom_formatter":"hash"}' end it 'sets another formatter' do get '/simple.txt' expect(last_response.body).to eql 'custom_formatter: hash' end end context 'custom formatter' do before :each do subject.content_type :json, 'application/json' subject.content_type :custom, 'application/custom' subject.formatter :custom, ->(object, _env) { "{\"custom_formatter\":\"#{object[:some]}\"}" } subject.get :simple do { some: 'hash' } end end it 'uses json' do get '/simple.json' expect(last_response.body).to eql '{"some":"hash"}' end it 'uses custom formatter' do get '/simple.custom', 'HTTP_ACCEPT' => 'application/custom' expect(last_response.body).to eql '{"custom_formatter":"hash"}' end end context 'custom formatter class' do module ApiSpec module CustomFormatter def self.call(object, _env) "{\"custom_formatter\":\"#{object[:some]}\"}" end end end before :each do subject.content_type :json, 'application/json' subject.content_type :custom, 'application/custom' subject.formatter :custom, ApiSpec::CustomFormatter subject.get :simple do { some: 'hash' } end end it 'uses json' do get '/simple.json' expect(last_response.body).to eql '{"some":"hash"}' end it 'uses custom formatter' do get '/simple.custom', 'HTTP_ACCEPT' => 'application/custom' expect(last_response.body).to eql '{"custom_formatter":"hash"}' end end end describe '.parser' do it 'parses data in format requested by content-type' do subject.format :json subject.post '/data' do { x: params[:x] } end post '/data', '{"x":42}', 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(201) expect(last_response.body).to eq('{"x":42}') end context 'lambda parser' do before :each do subject.content_type :txt, 'text/plain' subject.content_type :custom, 'text/custom' subject.parser :custom, ->(object, _env) { { object.to_sym => object.to_s.reverse } } subject.put :simple do params[:simple] end end ['text/custom', 'text/custom; charset=UTF-8'].each do |content_type| it "uses parser for #{content_type}" do put '/simple', 'simple', 'CONTENT_TYPE' => content_type expect(last_response.status).to eq(200) expect(last_response.body).to eql 'elpmis' end end end context 'custom parser class' do module ApiSpec module CustomParser def self.call(object, _env) { object.to_sym => object.to_s.reverse } end end end before :each do subject.content_type :txt, 'text/plain' subject.content_type :custom, 'text/custom' subject.parser :custom, ApiSpec::CustomParser subject.put :simple do params[:simple] end end it 'uses custom parser' do put '/simple', 'simple', 'CONTENT_TYPE' => 'text/custom' expect(last_response.status).to eq(200) expect(last_response.body).to eql 'elpmis' end end if Object.const_defined? :MultiXml context 'multi_xml' do it "doesn't parse yaml" do subject.put :yaml do params[:tag] end put '/yaml', 'a123', 'CONTENT_TYPE' => 'application/xml' expect(last_response.status).to eq(400) expect(last_response.body).to eql 'Disallowed type attribute: "symbol"' end end else context 'default xml parser' do it 'parses symbols' do subject.put :yaml do params[:tag] end put '/yaml', 'a123', 'CONTENT_TYPE' => 'application/xml' expect(last_response.status).to eq(200) expect(last_response.body).to eql '{"type"=>"symbol", "__content__"=>"a123"}' end end end context 'none parser class' do before :each do subject.parser :json, nil subject.put 'data' do "body: #{env['api.request.body']}" end end it 'does not parse data' do put '/data', 'not valid json', 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(200) expect(last_response.body).to eq('body: not valid json') end end end describe '.default_format' do before :each do subject.format :json subject.default_format :json end it 'returns data in default format' do subject.get '/data' do { x: 42 } end get '/data' expect(last_response.status).to eq(200) expect(last_response.body).to eq('{"x":42}') end it 'parses data in default format' do subject.post '/data' do { x: params[:x] } end post '/data', '{"x":42}', 'CONTENT_TYPE' => '' expect(last_response.status).to eq(201) expect(last_response.body).to eq('{"x":42}') end end describe '.default_error_status' do it 'allows setting default_error_status' do subject.rescue_from :all subject.default_error_status 200 subject.get '/exception' do raise 'rain!' end get '/exception' expect(last_response.status).to eql 200 end it 'has a default error status' do subject.rescue_from :all subject.get '/exception' do raise 'rain!' end get '/exception' expect(last_response.status).to eql 500 end it 'uses the default error status in error!' do subject.rescue_from :all subject.default_error_status 400 subject.get '/exception' do error! 'rain!' end get '/exception' expect(last_response.status).to eql 400 end end context 'http_codes' do let(:error_presenter) do Class.new(Grape::Entity) do expose :code expose :static def static 'some static text' end end end it 'is used as presenter' do subject.desc 'some desc', http_codes: [ [408, 'Unauthorized', error_presenter] ] subject.get '/exception' do error!({ code: 408 }, 408) end get '/exception' expect(last_response.status).to eql 408 expect(last_response.body).to eql({ code: 408, static: 'some static text' }.to_json) end it 'presented with' do error = { code: 408, with: error_presenter }.freeze subject.get '/exception' do error! error, 408 end get '/exception' expect(last_response.status).to eql 408 expect(last_response.body).to eql({ code: 408, static: 'some static text' }.to_json) end end context 'routes' do describe 'empty api structure' do it 'returns an empty array of routes' do expect(subject.routes).to eq([]) end end describe 'single method api structure' do before(:each) do subject.get :ping do 'pong' end end it 'returns one route' do expect(subject.routes.size).to eq(1) route = subject.routes[0] expect(route.version).to be_nil expect(route.path).to eq('/ping(.:format)') expect(route.request_method).to eq('GET') end end describe 'api structure with two versions and a namespace' do before :each do subject.version 'v1', using: :path subject.get 'version' do api.version end # version v2 subject.version 'v2', using: :path subject.prefix 'p' subject.namespace 'n1' do namespace 'n2' do get 'version' do api.version end end end end it 'returns the latest version set' do expect(subject.version).to eq('v2') end it 'returns versions' do expect(subject.versions).to eq(%w[v1 v2]) end it 'sets route paths' do expect(subject.routes.size).to be >= 2 expect(subject.routes[0].path).to eq('/:version/version(.:format)') expect(subject.routes[1].path).to eq('/p/:version/n1/n2/version(.:format)') end it 'sets route versions' do expect(subject.routes[0].version).to eq('v1') expect(subject.routes[1].version).to eq('v2') end it 'sets a nested namespace' do expect(subject.routes[1].namespace).to eq('/n1/n2') end it 'sets prefix' do expect(subject.routes[1].prefix).to eq('p') end end describe 'api structure with additional parameters' do before(:each) do subject.params do requires :token, desc: 'a token' optional :limit, desc: 'the limit' end subject.get 'split/:string' do params[:string].split(params[:token], (params[:limit] || 0).to_i) end end it 'splits a string' do get '/split/a,b,c.json', token: ',' expect(last_response.body).to eq('["a","b","c"]') end it 'splits a string with limit' do get '/split/a,b,c.json', token: ',', limit: '2' expect(last_response.body).to eq('["a","b,c"]') end it 'sets params' do expect(subject.routes.map do |route| { params: route.params } end).to eq [ { params: { 'string' => '', 'token' => { required: true, desc: 'a token' }, 'limit' => { required: false, desc: 'the limit' } } } ] end end describe 'api structure with multiple apis' do before(:each) do subject.params do requires :one, desc: 'a token' optional :two, desc: 'the limit' end subject.get 'one' do end subject.params do requires :three, desc: 'a token' optional :four, desc: 'the limit' end subject.get 'two' do end end it 'sets params' do expect(subject.routes.map do |route| { params: route.params } end).to eq [ { params: { 'one' => { required: true, desc: 'a token' }, 'two' => { required: false, desc: 'the limit' } } }, { params: { 'three' => { required: true, desc: 'a token' }, 'four' => { required: false, desc: 'the limit' } } } ] end end describe 'api structure with an api without params' do before(:each) do subject.params do requires :one, desc: 'a token' optional :two, desc: 'the limit' end subject.get 'one' do end subject.get 'two' do end end it 'sets params' do expect(subject.routes.map do |route| { params: route.params } end).to eq [ { params: { 'one' => { required: true, desc: 'a token' }, 'two' => { required: false, desc: 'the limit' } } }, { params: {} } ] end end describe 'api with a custom route setting' do before(:each) do subject.route_setting :custom, key: 'value' subject.get 'one' end it 'exposed' do expect(subject.routes.count).to eq 1 route = subject.routes.first expect(route.settings[:custom]).to eq(key: 'value') end end describe 'status' do it 'can be set to arbitrary Integer value' do subject.get '/foo' do status 210 end get '/foo' expect(last_response.status).to eq 210 end it 'can be set with a status code symbol' do subject.get '/foo' do status :see_other end get '/foo' expect(last_response.status).to eq 303 end end end context 'desc' do it 'empty array of routes' do expect(subject.routes).to eq([]) end it 'empty array of routes' do subject.desc 'grape api' expect(subject.routes).to eq([]) end it 'describes a method' do subject.desc 'first method' subject.get :first expect(subject.routes.length).to eq(1) route = subject.routes.first expect(route.description).to eq('first method') expect(route.route_foo).to be_nil expect(route.params).to eq({}) expect(route.options).to be_a_kind_of(Hash) end it 'has params which does not include format and version as named captures' do subject.version :v1, using: :path subject.get :first param_keys = subject.routes.first.params.keys expect(param_keys).not_to include('format') expect(param_keys).not_to include('version') end it 'describes methods separately' do subject.desc 'first method' subject.get :first subject.desc 'second method' subject.get :second expect(subject.routes.count).to eq(2) expect(subject.routes.map do |route| { description: route.description, params: route.params } end).to eq [ { description: 'first method', params: {} }, { description: 'second method', params: {} } ] end it 'resets desc' do subject.desc 'first method' subject.get :first subject.get :second expect(subject.routes.map do |route| { description: route.description, params: route.params } end).to eq [ { description: 'first method', params: {} }, { description: nil, params: {} } ] end it 'namespaces and describe arbitrary parameters' do subject.namespace 'ns' do desc 'ns second', foo: 'bar' get 'second' end expect(subject.routes.map do |route| { description: route.description, foo: route.route_foo, params: route.params } end).to eq [ { description: 'ns second', foo: 'bar', params: {} } ] end it 'includes details' do subject.desc 'method', details: 'method details' subject.get 'method' expect(subject.routes.map do |route| { description: route.description, details: route.details, params: route.params } end).to eq [ { description: 'method', details: 'method details', params: {} } ] end it 'describes a method with parameters' do subject.desc 'Reverses a string.', params: { 's' => { desc: 'string to reverse', type: 'string' } } subject.get 'reverse' do params[:s].reverse end expect(subject.routes.map do |route| { description: route.description, params: route.params } end).to eq [ { description: 'Reverses a string.', params: { 's' => { desc: 'string to reverse', type: 'string' } } } ] end it 'does not inherit param descriptions in consequent namespaces' do subject.desc 'global description' subject.params do requires :param1 optional :param2 end subject.namespace 'ns1' do get { ; } end subject.params do optional :param2 end subject.namespace 'ns2' do get { ; } end routes_doc = subject.routes.map do |route| { description: route.description, params: route.params } end expect(routes_doc).to eq [ { description: 'global description', params: { 'param1' => { required: true }, 'param2' => { required: false } } }, { description: 'global description', params: { 'param2' => { required: false } } } ] end it 'merges the parameters of the namespace with the parameters of the method' do subject.desc 'namespace' subject.params do requires :ns_param, desc: 'namespace parameter' end subject.namespace 'ns' do desc 'method' params do optional :method_param, desc: 'method parameter' end get 'method' end routes_doc = subject.routes.map do |route| { description: route.description, params: route.params } end expect(routes_doc).to eq [ { description: 'method', params: { 'ns_param' => { required: true, desc: 'namespace parameter' }, 'method_param' => { required: false, desc: 'method parameter' } } } ] end it 'merges the parameters of nested namespaces' do subject.desc 'ns1' subject.params do optional :ns_param, desc: 'ns param 1' requires :ns1_param, desc: 'ns1 param' end subject.namespace 'ns1' do desc 'ns2' params do requires :ns_param, desc: 'ns param 2' requires :ns2_param, desc: 'ns2 param' end namespace 'ns2' do desc 'method' params do optional :method_param, desc: 'method param' end get 'method' end end expect(subject.routes.map do |route| { description: route.description, params: route.params } end).to eq [ { description: 'method', params: { 'ns_param' => { required: true, desc: 'ns param 2' }, 'ns1_param' => { required: true, desc: 'ns1 param' }, 'ns2_param' => { required: true, desc: 'ns2 param' }, 'method_param' => { required: false, desc: 'method param' } } } ] end it 'groups nested params and prevents overwriting of params with same name in different groups' do subject.desc 'method' subject.params do group :group1, type: Array do optional :param1, desc: 'group1 param1 desc' requires :param2, desc: 'group1 param2 desc' end group :group2, type: Array do optional :param1, desc: 'group2 param1 desc' requires :param2, desc: 'group2 param2 desc' end end subject.get 'method' expect(subject.routes.map(&:params)).to eq [{ 'group1' => { required: true, type: 'Array' }, 'group1[param1]' => { required: false, desc: 'group1 param1 desc' }, 'group1[param2]' => { required: true, desc: 'group1 param2 desc' }, 'group2' => { required: true, type: 'Array' }, 'group2[param1]' => { required: false, desc: 'group2 param1 desc' }, 'group2[param2]' => { required: true, desc: 'group2 param2 desc' } }] end it 'uses full name of parameters in nested groups' do subject.desc 'nesting' subject.params do requires :root_param, desc: 'root param' group :nested, type: Array do requires :nested_param, desc: 'nested param' end end subject.get 'method' expect(subject.routes.map do |route| { description: route.description, params: route.params } end).to eq [ { description: 'nesting', params: { 'root_param' => { required: true, desc: 'root param' }, 'nested' => { required: true, type: 'Array' }, 'nested[nested_param]' => { required: true, desc: 'nested param' } } } ] end it 'allows to set the type attribute on :group element' do subject.params do group :foo, type: Array do optional :bar end end end it 'parses parameters when no description is given' do subject.params do requires :one_param, desc: 'one param' end subject.get 'method' expect(subject.routes.map do |route| { description: route.description, params: route.params } end).to eq [ { description: nil, params: { 'one_param' => { required: true, desc: 'one param' } } } ] end it 'does not symbolize params' do subject.desc 'Reverses a string.', params: { 's' => { desc: 'string to reverse', type: 'string' } } subject.get 'reverse/:s' do params[:s].reverse end expect(subject.routes.map do |route| { description: route.description, params: route.params } end).to eq [ { description: 'Reverses a string.', params: { 's' => { desc: 'string to reverse', type: 'string' } } } ] end end describe '.mount' do let(:mounted_app) { ->(_env) { [200, {}, ['MOUNTED']] } } context 'with a bare rack app' do before do subject.mount mounted_app => '/mounty' end it 'makes a bare Rack app available at the endpoint' do get '/mounty' expect(last_response.body).to eq('MOUNTED') end it 'anchors the routes, passing all subroutes to it' do get '/mounty/awesome' expect(last_response.body).to eq('MOUNTED') end it 'is able to cascade' do subject.mount lambda { |env| headers = {} headers['X-Cascade'] == 'pass' unless env['PATH_INFO'].include?('boo') [200, headers, ['Farfegnugen']] } => '/' get '/boo' expect(last_response.body).to eq('Farfegnugen') get '/mounty' expect(last_response.body).to eq('MOUNTED') end end context 'without a hash' do it 'calls through setting the route to "/"' do subject.mount mounted_app get '/' expect(last_response.body).to eq('MOUNTED') end end context 'mounting an API' do it 'applies the settings of the mounting api' do subject.version 'v1', using: :path subject.namespace :cool do app = Class.new(Grape::API) app.get('/awesome') do 'yo' end mount app end get '/v1/cool/awesome' expect(last_response.body).to eq('yo') end it 'applies the settings to nested mounted apis' do subject.version 'v1', using: :path subject.namespace :cool do inner_app = Class.new(Grape::API) inner_app.get('/awesome') do 'yo' end app = Class.new(Grape::API) app.mount inner_app mount app end get '/v1/cool/awesome' expect(last_response.body).to eq('yo') end context 'when some rescues are defined by mounted' do it 'inherits parent rescues' do subject.rescue_from :all do |e| rack_response("rescued from #{e.message}", 202) end app = Class.new(Grape::API) subject.namespace :mounted do app.rescue_from ArgumentError app.get('/fail') { raise 'doh!' } mount app end get '/mounted/fail' expect(last_response.status).to eql 202 expect(last_response.body).to eq('rescued from doh!') end it 'prefers rescues defined by mounted if they rescue similar error class' do subject.rescue_from StandardError do rack_response('outer rescue') end app = Class.new(Grape::API) subject.namespace :mounted do rescue_from StandardError do rack_response('inner rescue') end app.get('/fail') { raise 'doh!' } mount app end get '/mounted/fail' expect(last_response.body).to eq('inner rescue') end it 'prefers rescues defined by mounted even if outer is more specific' do subject.rescue_from ArgumentError do rack_response('outer rescue') end app = Class.new(Grape::API) subject.namespace :mounted do rescue_from StandardError do rack_response('inner rescue') end app.get('/fail') { raise ArgumentError.new } mount app end get '/mounted/fail' expect(last_response.body).to eq('inner rescue') end it 'prefers more specific rescues defined by mounted' do subject.rescue_from StandardError do rack_response('outer rescue') end app = Class.new(Grape::API) subject.namespace :mounted do rescue_from ArgumentError do rack_response('inner rescue') end app.get('/fail') { raise ArgumentError.new } mount app end get '/mounted/fail' expect(last_response.body).to eq('inner rescue') end end it 'collects the routes of the mounted api' do subject.namespace :cool do app = Class.new(Grape::API) app.get('/awesome') {} app.post('/sauce') {} mount app end expect(subject.routes.size).to eq(2) expect(subject.routes.first.path).to match(%r{\/cool\/awesome}) expect(subject.routes.last.path).to match(%r{\/cool\/sauce}) end it 'mounts on a path' do subject.namespace :cool do app = Class.new(Grape::API) app.get '/awesome' do 'sauce' end mount app => '/mounted' end get '/mounted/cool/awesome' expect(last_response.status).to eq(200) expect(last_response.body).to eq('sauce') end it 'mounts on a nested path' do APP1 = Class.new(Grape::API) APP2 = Class.new(Grape::API) APP2.get '/nice' do 'play' end # note that the reverse won't work, mount from outside-in APP3 = subject APP3.mount APP1 => '/app1' APP1.mount APP2 => '/app2' get '/app1/app2/nice' expect(last_response.status).to eq(200) expect(last_response.body).to eq('play') options '/app1/app2/nice' expect(last_response.status).to eq(204) end it 'responds to options' do app = Class.new(Grape::API) app.get '/colour' do 'red' end app.namespace :pears do get '/colour' do 'green' end end subject.namespace :apples do mount app end get '/apples/colour' expect(last_response.status).to eql 200 expect(last_response.body).to eq('red') options '/apples/colour' expect(last_response.status).to eql 204 get '/apples/pears/colour' expect(last_response.status).to eql 200 expect(last_response.body).to eq('green') options '/apples/pears/colour' expect(last_response.status).to eql 204 end it 'responds to options with path versioning' do subject.version 'v1', using: :path subject.namespace :apples do app = Class.new(Grape::API) app.get('/colour') do 'red' end mount app end get '/v1/apples/colour' expect(last_response.status).to eql 200 expect(last_response.body).to eq('red') options '/v1/apples/colour' expect(last_response.status).to eql 204 end it 'mounts a versioned API with nested resources' do api = Class.new(Grape::API) do version 'v1' resources :users do get :hello do 'hello users' end end end subject.mount api get '/v1/users/hello' expect(last_response.body).to eq('hello users') end it 'mounts a prefixed API with nested resources' do api = Class.new(Grape::API) do prefix 'api' resources :users do get :hello do 'hello users' end end end subject.mount api get '/api/users/hello' expect(last_response.body).to eq('hello users') end it 'applies format to a mounted API with nested resources' do api = Class.new(Grape::API) do format :json resources :users do get do { users: true } end end end subject.mount api get '/users' expect(last_response.body).to eq({ users: true }.to_json) end it 'applies auth to a mounted API with nested resources' do api = Class.new(Grape::API) do format :json http_basic do |username, password| username == 'username' && password == 'password' end resources :users do get do { users: true } end end end subject.mount api get '/users' expect(last_response.status).to eq(401) get '/users', {}, 'HTTP_AUTHORIZATION' => encode_basic_auth('username', 'password') expect(last_response.body).to eq({ users: true }.to_json) end it 'mounts multiple versioned APIs with nested resources' do api1 = Class.new(Grape::API) do version 'one', using: :header, vendor: 'test' resources :users do get :hello do 'one' end end end api2 = Class.new(Grape::API) do version 'two', using: :header, vendor: 'test' resources :users do get :hello do 'two' end end end subject.mount api1 subject.mount api2 versioned_get '/users/hello', 'one', using: :header, vendor: 'test' expect(last_response.body).to eq('one') versioned_get '/users/hello', 'two', using: :header, vendor: 'test' expect(last_response.body).to eq('two') end it 'recognizes potential versions with mounted path' do a = Class.new(Grape::API) do version :v1, using: :path get '/hello' do 'hello' end end b = Class.new(Grape::API) do version :v1, using: :path get '/world' do 'world' end end subject.mount a => '/one' subject.mount b => '/two' get '/one/v1/hello' expect(last_response.status).to eq 200 get '/two/v1/world' expect(last_response.status).to eq 200 end context 'when mounting class extends a subclass of Grape::API' do it 'mounts APIs with the same superclass' do base_api = Class.new(Grape::API) a = Class.new(base_api) b = Class.new(base_api) expect { a.mount b }.to_not raise_error end end end end describe '.endpoints' do it 'adds one for each route created' do subject.get '/' subject.post '/' expect(subject.endpoints.size).to eq(2) end end describe '.compile' do it 'sets the instance' do expect(subject.instance).to be_nil subject.compile expect(subject.instance).to be_kind_of(subject) end end describe '.change!' do it 'invalidates any compiled instance' do subject.compile subject.change! expect(subject.instance).to be_nil end end describe '.endpoint' do before(:each) do subject.format :json subject.get '/endpoint/options' do { path: options[:path], source_location: source.source_location } end end it 'path' do get '/endpoint/options' options = ::Grape::Json.load(last_response.body) expect(options['path']).to eq(['/endpoint/options']) expect(options['source_location'][0]).to include 'api_spec.rb' expect(options['source_location'][1].to_i).to be > 0 end end describe '.route' do context 'plain' do before(:each) do subject.get '/' do route.path end subject.get '/path' do route.path end end it 'provides access to route info' do get '/' expect(last_response.body).to eq('/(.:format)') get '/path' expect(last_response.body).to eq('/path(.:format)') end end context 'with desc' do before(:each) do subject.desc 'returns description' subject.get '/description' do route.description end subject.desc 'returns parameters', params: { 'x' => 'y' } subject.get '/params/:id' do route.params[params[:id]] end end it 'returns route description' do get '/description' expect(last_response.body).to eq('returns description') end it 'returns route parameters' do get '/params/x' expect(last_response.body).to eq('y') end end end describe '.format' do context ':txt' do before(:each) do subject.format :txt subject.content_type :json, 'application/json' subject.get '/meaning_of_life' do { meaning_of_life: 42 } end end it 'forces txt without an extension' do get '/meaning_of_life' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s) end it 'does not force txt with an extension' do get '/meaning_of_life.json' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_json) end it 'forces txt from a non-accepting header' do get '/meaning_of_life', {}, 'HTTP_ACCEPT' => 'application/json' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s) end end context ':txt only' do before(:each) do subject.format :txt subject.get '/meaning_of_life' do { meaning_of_life: 42 } end end it 'forces txt without an extension' do get '/meaning_of_life' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s) end it 'accepts specified extension' do get '/meaning_of_life.txt' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s) end it 'does not accept extensions other than specified' do get '/meaning_of_life.json' expect(last_response.status).to eq(404) end it 'forces txt from a non-accepting header' do get '/meaning_of_life', {}, 'HTTP_ACCEPT' => 'application/json' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s) end end context ':json' do before(:each) do subject.format :json subject.content_type :txt, 'text/plain' subject.get '/meaning_of_life' do { meaning_of_life: 42 } end end it 'forces json without an extension' do get '/meaning_of_life' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_json) end it 'does not force json with an extension' do get '/meaning_of_life.txt' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s) end it 'forces json from a non-accepting header' do get '/meaning_of_life', {}, 'HTTP_ACCEPT' => 'text/html' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_json) end it 'can be overwritten with an explicit content type' do subject.get '/meaning_of_life_with_content_type' do content_type 'text/plain' { meaning_of_life: 42 }.to_s end get '/meaning_of_life_with_content_type' expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s) end it 'raised :error from middleware' do middleware = Class.new(Grape::Middleware::Base) do def before throw :error, message: 'Unauthorized', status: 42 end end subject.use middleware subject.get do end get '/' expect(last_response.status).to eq(42) expect(last_response.body).to eq({ error: 'Unauthorized' }.to_json) end end context ':serializable_hash' do before(:each) do class SerializableHashExample def serializable_hash { abc: 'def' } end end subject.format :serializable_hash end it 'instance' do subject.get '/example' do SerializableHashExample.new end get '/example' expect(last_response.body).to eq('{"abc":"def"}') end it 'root' do subject.get '/example' do { 'root' => SerializableHashExample.new } end get '/example' expect(last_response.body).to eq('{"root":{"abc":"def"}}') end it 'array' do subject.get '/examples' do [SerializableHashExample.new, SerializableHashExample.new] end get '/examples' expect(last_response.body).to eq('[{"abc":"def"},{"abc":"def"}]') end end context ':xml' do before(:each) do subject.format :xml end it 'string' do subject.get '/example' do 'example' end get '/example' expect(last_response.status).to eq(500) expect(last_response.body).to eq <<-XML cannot convert String to xml XML end it 'hash' do subject.get '/example' do { example1: 'example1', example2: 'example2' } end get '/example' expect(last_response.status).to eq(200) expect(last_response.body).to eq <<-XML example1 example2 XML end it 'array' do subject.get '/example' do %w[example1 example2] end get '/example' expect(last_response.status).to eq(200) expect(last_response.body).to eq <<-XML example1 example2 XML end it 'raised :error from middleware' do middleware = Class.new(Grape::Middleware::Base) do def before throw :error, message: 'Unauthorized', status: 42 end end subject.use middleware subject.get do end get '/' expect(last_response.status).to eq(42) expect(last_response.body).to eq <<-XML Unauthorized XML end end end context 'catch-all' do before do api1 = Class.new(Grape::API) api1.version 'v1', using: :path api1.get 'hello' do 'v1' end api2 = Class.new(Grape::API) api2.version 'v2', using: :path api2.get 'hello' do 'v2' end subject.mount api1 subject.mount api2 end [true, false].each do |anchor| it "anchor=#{anchor}" do subject.route :any, '*path', anchor: anchor do error!("Unrecognized request path: #{params[:path]} - #{env['PATH_INFO']}#{env['SCRIPT_NAME']}", 404) end get '/v1/hello' expect(last_response.status).to eq(200) expect(last_response.body).to eq('v1') get '/v2/hello' expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2') options '/v2/hello' expect(last_response.status).to eq(204) expect(last_response.body).to be_blank head '/v2/hello' expect(last_response.status).to eq(200) expect(last_response.body).to be_blank get '/foobar' expect(last_response.status).to eq(404) expect(last_response.body).to eq('Unrecognized request path: foobar - /foobar') end end end context 'cascading' do context 'via version' do it 'cascades' do subject.version 'v1', using: :path, cascade: true get '/v1/hello' expect(last_response.status).to eq(404) expect(last_response.headers['X-Cascade']).to eq('pass') end it 'does not cascade' do subject.version 'v2', using: :path, cascade: false get '/v2/hello' expect(last_response.status).to eq(404) expect(last_response.headers.keys).not_to include 'X-Cascade' end end context 'via endpoint' do it 'cascades' do subject.cascade true get '/hello' expect(last_response.status).to eq(404) expect(last_response.headers['X-Cascade']).to eq('pass') end it 'does not cascade' do subject.cascade false get '/hello' expect(last_response.status).to eq(404) expect(last_response.headers.keys).not_to include 'X-Cascade' end end end context 'with json default_error_formatter' do it 'returns json error' do subject.content_type :json, 'application/json' subject.default_error_formatter :json subject.get '/something' do 'foo' end get '/something' expect(last_response.status).to eq(406) expect(last_response.body).to eq("{\"error\":\"The requested format 'txt' is not supported.\"}") end end context 'body' do context 'false' do before do subject.get '/blank' do body false end end it 'returns blank body' do get '/blank' expect(last_response.status).to eq(204) expect(last_response.body).to be_blank end end context 'plain text' do before do subject.get '/text' do content_type 'text/plain' body 'Hello World' 'ignored' end end it 'returns blank body' do get '/text' expect(last_response.status).to eq(200) expect(last_response.body).to eq 'Hello World' end end end end grape-1.0.2/spec/grape/endpoint_spec.rb0000644000004100000410000013471213231337007020056 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Endpoint do subject { Class.new(Grape::API) } def app subject end describe '.before_each' do after { Grape::Endpoint.before_each(nil) } it 'is settable via block' do block = ->(_endpoint) { 'noop' } Grape::Endpoint.before_each(&block) expect(Grape::Endpoint.before_each.first).to eq(block) end it 'is settable via reference' do block = ->(_endpoint) { 'noop' } Grape::Endpoint.before_each block expect(Grape::Endpoint.before_each.first).to eq(block) end it 'is able to override a helper' do subject.get('/') { current_user } expect { get '/' }.to raise_error(NameError) Grape::Endpoint.before_each do |endpoint| allow(endpoint).to receive(:current_user).and_return('Bob') end get '/' expect(last_response.body).to eq('Bob') Grape::Endpoint.before_each(nil) expect { get '/' }.to raise_error(NameError) end it 'is able to stack helper' do subject.get('/') do authenticate_user! current_user end expect { get '/' }.to raise_error(NameError) Grape::Endpoint.before_each do |endpoint| allow(endpoint).to receive(:current_user).and_return('Bob') end Grape::Endpoint.before_each do |endpoint| allow(endpoint).to receive(:authenticate_user!).and_return(true) end get '/' expect(last_response.body).to eq('Bob') Grape::Endpoint.before_each(nil) expect { get '/' }.to raise_error(NameError) end end describe '#initialize' do it 'takes a settings stack, options, and a block' do p = proc {} expect do Grape::Endpoint.new(Grape::Util::InheritableSetting.new, { path: '/', method: :get }, &p) end.not_to raise_error end end it 'sets itself in the env upon call' do subject.get('/') { 'Hello world.' } get '/' expect(last_request.env['api.endpoint']).to be_kind_of(Grape::Endpoint) end describe '#status' do it 'is callable from within a block' do subject.get('/home') do status 206 'Hello' end get '/home' expect(last_response.status).to eq(206) expect(last_response.body).to eq('Hello') end it 'is set as default to 200 for get' do memoized_status = nil subject.get('/home') do memoized_status = status 'Hello' end get '/home' expect(last_response.status).to eq(200) expect(memoized_status).to eq(200) expect(last_response.body).to eq('Hello') end it 'is set as default to 201 for post' do memoized_status = nil subject.post('/home') do memoized_status = status 'Hello' end post '/home' expect(last_response.status).to eq(201) expect(memoized_status).to eq(201) expect(last_response.body).to eq('Hello') end end describe '#header' do it 'is callable from within a block' do subject.get('/hey') do header 'X-Awesome', 'true' 'Awesome' end get '/hey' expect(last_response.headers['X-Awesome']).to eq('true') end end describe '#headers' do before do subject.get('/headers') do headers.to_json end end it 'includes request headers' do get '/headers' expect(JSON.parse(last_response.body)).to eq( 'Host' => 'example.org', 'Cookie' => '' ) end it 'includes additional request headers' do get '/headers', nil, 'HTTP_X_GRAPE_CLIENT' => '1' expect(JSON.parse(last_response.body)['X-Grape-Client']).to eq('1') end it 'includes headers passed as symbols' do env = Rack::MockRequest.env_for('/headers') env['HTTP_SYMBOL_HEADER'.to_sym] = 'Goliath passes symbols' body = subject.call(env)[2].body.first expect(JSON.parse(body)['Symbol-Header']).to eq('Goliath passes symbols') end end describe '#cookies' do it 'is callable from within a block' do subject.get('/get/cookies') do cookies['my-awesome-cookie1'] = 'is cool' cookies['my-awesome-cookie2'] = { value: 'is cool too', domain: 'my.example.com', path: '/', secure: true } cookies[:cookie3] = 'symbol' cookies['cookie4'] = 'secret code here' end get('/get/cookies') expect(last_response.headers['Set-Cookie'].split("\n").sort).to eql [ 'cookie3=symbol', 'cookie4=secret+code+here', 'my-awesome-cookie1=is+cool', 'my-awesome-cookie2=is+cool+too; domain=my.example.com; path=/; secure' ] end it 'sets browser cookies and does not set response cookies' do subject.get('/username') do cookies[:username] end get('/username', {}, 'HTTP_COOKIE' => 'username=mrplum; sandbox=true') expect(last_response.body).to eq('mrplum') expect(last_response.headers['Set-Cookie']).to be_nil end it 'sets and update browser cookies' do subject.get('/username') do cookies[:sandbox] = true if cookies[:sandbox] == 'false' cookies[:username] += '_test' end get('/username', {}, 'HTTP_COOKIE' => 'username=user; sandbox=false') expect(last_response.body).to eq('user_test') expect(last_response.headers['Set-Cookie']).to match(/username=user_test/) expect(last_response.headers['Set-Cookie']).to match(/sandbox=true/) end it 'deletes cookie' do subject.get('/test') do sum = 0 cookies.each do |name, val| sum += val.to_i cookies.delete name end sum end get '/test', {}, 'HTTP_COOKIE' => 'delete_this_cookie=1; and_this=2' expect(last_response.body).to eq('3') cookies = Hash[last_response.headers['Set-Cookie'].split("\n").map do |set_cookie| cookie = CookieJar::Cookie.from_set_cookie 'http://localhost/test', set_cookie [cookie.name, cookie] end] expect(cookies.size).to eq(2) %w[and_this delete_this_cookie].each do |cookie_name| cookie = cookies[cookie_name] expect(cookie).not_to be_nil expect(cookie.value).to eq('deleted') expect(cookie.expired?).to be true end end it 'deletes cookies with path' do subject.get('/test') do sum = 0 cookies.each do |name, val| sum += val.to_i cookies.delete name, path: '/test' end sum end get('/test', {}, 'HTTP_COOKIE' => 'delete_this_cookie=1; and_this=2') expect(last_response.body).to eq('3') cookies = Hash[last_response.headers['Set-Cookie'].split("\n").map do |set_cookie| cookie = CookieJar::Cookie.from_set_cookie 'http://localhost/test', set_cookie [cookie.name, cookie] end] expect(cookies.size).to eq(2) %w[and_this delete_this_cookie].each do |cookie_name| cookie = cookies[cookie_name] expect(cookie).not_to be_nil expect(cookie.value).to eq('deleted') expect(cookie.path).to eq('/test') expect(cookie.expired?).to be true end end end describe '#params' do context 'default class' do it 'should be a ActiveSupport::HashWithIndifferentAccess' do subject.get '/foo' do params.class end get '/foo' expect(last_response.status).to eq(200) expect(last_response.body).to eq('ActiveSupport::HashWithIndifferentAccess') end end context 'sets a value to params' do it 'params' do subject.params do requires :a, type: String end subject.get '/foo' do params[:a] = 'bar' end get '/foo', a: 'foo' expect(last_response.status).to eq(200) expect(last_response.body).to eq('bar') end end end describe '#declared' do before do subject.format :json subject.params do requires :first optional :second optional :third, default: 'third-default' optional :nested, type: Hash do optional :fourth optional :fifth optional :nested_two, type: Hash do optional :sixth optional :nested_three, type: Hash do optional :seventh end end end optional :nested_arr, type: Array do optional :eighth end end end context 'when params are not built with default class' do it 'returns an object that corresponds with the params class - hash with indifferent access' do subject.params do build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder end subject.get '/declared' do d = declared(params, include_missing: true) { declared_class: d.class.to_s } end get '/declared?first=present' expect(JSON.parse(last_response.body)['declared_class']).to eq('ActiveSupport::HashWithIndifferentAccess') end it 'returns an object that corresponds with the params class - hashie mash' do subject.params do build_with Grape::Extensions::Hashie::Mash::ParamBuilder end subject.get '/declared' do d = declared(params, include_missing: true) { declared_class: d.class.to_s } end get '/declared?first=present' expect(JSON.parse(last_response.body)['declared_class']).to eq('Hashie::Mash') end it 'returns an object that corresponds with the params class - hash' do subject.params do build_with Grape::Extensions::Hash::ParamBuilder end subject.get '/declared' do d = declared(params, include_missing: true) { declared_class: d.class.to_s } end get '/declared?first=present' expect(JSON.parse(last_response.body)['declared_class']).to eq('Hash') end end it 'should show nil for nested params if include_missing is true' do subject.get '/declared' do declared(params, include_missing: true) end get '/declared?first=present' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)['nested']['fourth']).to be_nil end it 'does not work in a before filter' do subject.before do declared(params) end subject.get('/declared') { declared(params) } expect { get('/declared') }.to raise_error( Grape::DSL::InsideRoute::MethodNotYetAvailable ) end it 'has as many keys as there are declared params' do subject.get '/declared' do declared(params) end get '/declared?first=present' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body).keys.size).to eq(5) end it 'has a optional param with default value all the time' do subject.get '/declared' do declared(params) end get '/declared?first=one' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)['third']).to eql('third-default') end it 'builds nested params' do subject.get '/declared' do declared(params) end get '/declared?first=present&nested[fourth]=1' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)['nested'].keys.size).to eq 3 end it 'builds nested params when given array' do subject.get '/dummy' do end subject.params do requires :first optional :second optional :third, default: 'third-default' optional :nested, type: Array do optional :fourth end end subject.get '/declared' do declared(params) end get '/declared?first=present&nested[][fourth]=1&nested[][fourth]=2' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)['nested'].size).to eq 2 end context 'sets nested objects when the param is missing' do it 'to be a hash when include_missing is true' do subject.get '/declared' do declared(params, include_missing: true) end get '/declared?first=present' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)['nested']).to be_a(Hash) end it 'to be an array when include_missing is true' do subject.get '/declared' do declared(params, include_missing: true) end get '/declared?first=present' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)['nested_arr']).to be_a(Array) end it 'to be nil when include_missing is false' do subject.get '/declared' do declared(params, include_missing: false) end get '/declared?first=present' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)['nested']).to be_nil end end it 'filters out any additional params that are given' do subject.get '/declared' do declared(params) end get '/declared?first=one&other=two' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body).key?(:other)).to eq false end it 'stringifies if that option is passed' do subject.get '/declared' do declared(params, stringify: true) end get '/declared?first=one&other=two' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)['first']).to eq 'one' end it 'does not include missing attributes if that option is passed' do subject.get '/declared' do error! 400, 'expected nil' if declared(params, include_missing: false)[:second] '' end get '/declared?first=one&other=two' expect(last_response.status).to eq(200) end it 'includes attributes with value that evaluates to false' do subject.params do requires :first optional :boolean end subject.post '/declared' do error!('expected false', 400) if declared(params, include_missing: false)[:boolean] != false '' end post '/declared', ::Grape::Json.dump(first: 'one', boolean: false), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(201) end it 'includes attributes with value that evaluates to nil' do subject.params do requires :first optional :second end subject.post '/declared' do error!('expected nil', 400) unless declared(params, include_missing: false)[:second].nil? '' end post '/declared', ::Grape::Json.dump(first: 'one', second: nil), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(201) end it 'includes missing attributes with defaults when there are nested hashes' do subject.get '/dummy' do end subject.params do requires :first optional :second optional :third, default: nil optional :nested, type: Hash do optional :fourth, default: nil optional :fifth, default: nil requires :nested_nested, type: Hash do optional :sixth, default: 'sixth-default' optional :seven, default: nil end end end subject.get '/declared' do declared(params, include_missing: false) end get '/declared?first=present&nested[fourth]=&nested[nested_nested][sixth]=sixth' json = JSON.parse(last_response.body) expect(last_response.status).to eq(200) expect(json['first']).to eq 'present' expect(json['nested'].keys).to eq %w[fourth fifth nested_nested] expect(json['nested']['fourth']).to eq '' expect(json['nested']['nested_nested'].keys).to eq %w[sixth seven] expect(json['nested']['nested_nested']['sixth']).to eq 'sixth' end it 'does not include missing attributes when there are nested hashes' do subject.get '/dummy' do end subject.params do requires :first optional :second optional :third optional :nested, type: Hash do optional :fourth optional :fifth end end subject.get '/declared' do declared(params, include_missing: false) end get '/declared?first=present&nested[fourth]=4' json = JSON.parse(last_response.body) expect(last_response.status).to eq(200) expect(json['first']).to eq 'present' expect(json['nested'].keys).to eq %w[fourth] expect(json['nested']['fourth']).to eq '4' end end describe '#declared; call from child namespace' do before do subject.format :json subject.namespace :parent do params do requires :parent_name, type: String end namespace ':parent_name' do params do requires :child_name, type: String requires :child_age, type: Integer end namespace ':child_name' do params do requires :grandchild_name, type: String end get ':grandchild_name' do { 'params' => params, 'without_parent_namespaces' => declared(params, include_parent_namespaces: false), 'with_parent_namespaces' => declared(params, include_parent_namespaces: true) } end end end end get '/parent/foo/bar/baz', child_age: 5, extra: 'hello' end let(:parsed_response) { JSON.parse(last_response.body, symbolize_names: true) } it { expect(last_response.status).to eq 200 } context 'with include_parent_namespaces: false' do it 'returns declared parameters only from current namespace' do expect(parsed_response[:without_parent_namespaces]).to eq( grandchild_name: 'baz' ) end end context 'with include_parent_namespaces: true' do it 'returns declared parameters from every parent namespace' do expect(parsed_response[:with_parent_namespaces]).to eq( parent_name: 'foo', child_name: 'bar', grandchild_name: 'baz', child_age: 5 ) end end context 'without declaration' do it 'returns all requested parameters' do expect(parsed_response[:params]).to eq( parent_name: 'foo', child_name: 'bar', grandchild_name: 'baz', child_age: 5, extra: 'hello' ) end end end describe '#declared; from a nested mounted endpoint' do before do doubly_mounted = Class.new(Grape::API) doubly_mounted.namespace :more do params do requires :y, type: Integer end route_param :y do get do { params: params, declared_params: declared(params) } end end end mounted = Class.new(Grape::API) mounted.namespace :another do params do requires :mount_space, type: Integer end route_param :mount_space do mount doubly_mounted end end subject.format :json subject.namespace :something do params do requires :id, type: Integer end resource ':id' do mount mounted end end end it 'can access parent attributes' do get '/something/123/another/456/more/789' expect(last_response.status).to eq 200 json = JSON.parse(last_response.body, symbolize_names: true) # test all three levels of params expect(json[:declared_params][:y]).to eq 789 expect(json[:declared_params][:mount_space]).to eq 456 expect(json[:declared_params][:id]).to eq 123 end end describe '#declared; mixed nesting' do before do subject.format :json subject.resource :users do route_param :id, type: Integer, desc: 'ID desc' do # Adding this causes route_setting(:declared_params) to be nil for the # get block in namespace 'foo' below get do end namespace 'foo' do get do { params: params, declared_params: declared(params), declared_params_no_parent: declared(params, include_parent_namespaces: false) } end end end end end it 'can access parent route_param' do get '/users/123/foo', bar: 'bar' expect(last_response.status).to eq 200 json = JSON.parse(last_response.body, symbolize_names: true) expect(json[:declared_params][:id]).to eq 123 expect(json[:declared_params_no_parent][:id]).to eq nil end end describe '#declared; with multiple route_param' do before do mounted = Class.new(Grape::API) mounted.namespace :albums do get do declared(params) end end subject.format :json subject.namespace :artists do route_param :id, type: Integer do get do declared(params) end params do requires :filter, type: String end get :some_route do declared(params) end end route_param :artist_id, type: Integer do namespace :compositions do get do declared(params) end end end route_param :compositor_id, type: Integer do mount mounted end end end it 'return only :id without :artist_id' do get '/artists/1' json = JSON.parse(last_response.body, symbolize_names: true) expect(json.key?(:id)).to be_truthy expect(json.key?(:artist_id)).not_to be_truthy end it 'return only :artist_id without :id' do get '/artists/1/compositions' json = JSON.parse(last_response.body, symbolize_names: true) expect(json.key?(:artist_id)).to be_truthy expect(json.key?(:id)).not_to be_truthy end it 'return :filter and :id parameters in declared for second enpoint inside route_param' do get '/artists/1/some_route', filter: 'some_filter' json = JSON.parse(last_response.body, symbolize_names: true) expect(json.key?(:filter)).to be_truthy expect(json.key?(:id)).to be_truthy expect(json.key?(:artist_id)).not_to be_truthy end it 'return :compositor_id for mounter in route_param' do get '/artists/1/albums' json = JSON.parse(last_response.body, symbolize_names: true) expect(json.key?(:compositor_id)).to be_truthy expect(json.key?(:id)).not_to be_truthy expect(json.key?(:artist_id)).not_to be_truthy end end describe '#params' do it 'is available to the caller' do subject.get('/hey') do params[:howdy] end get '/hey?howdy=hey' expect(last_response.body).to eq('hey') end it 'parses from path segments' do subject.get('/hey/:id') do params[:id] end get '/hey/12' expect(last_response.body).to eq('12') end it 'deeply converts nested params' do subject.get '/location' do params[:location][:city] end get '/location?location[city]=Dallas' expect(last_response.body).to eq('Dallas') end context 'with special requirements' do it 'parses email param with provided requirements for params' do subject.get('/:person_email', requirements: { person_email: /.*/ }) do params[:person_email] end get '/someone@example.com' expect(last_response.body).to eq('someone@example.com') get 'someone@example.com.pl' expect(last_response.body).to eq('someone@example.com.pl') end it 'parses many params with provided regexps' do subject.get('/:person_email/test/:number', requirements: { person_email: /someone@(.*).com/, number: /[0-9]/ }) do params[:person_email] << params[:number] end get '/someone@example.com/test/1' expect(last_response.body).to eq('someone@example.com1') get '/someone@testing.wrong/test/1' expect(last_response.status).to eq(404) get 'someone@test.com/test/wrong_number' expect(last_response.status).to eq(404) get 'someone@test.com/wrong_middle/1' expect(last_response.status).to eq(404) end context 'namespace requirements' do before :each do subject.namespace :outer, requirements: { person_email: /abc@(.*).com/ } do get('/:person_email') do params[:person_email] end namespace :inner, requirements: { number: /[0-9]/, person_email: /someone@(.*).com/ } do get '/:person_email/test/:number' do params[:person_email] << params[:number] end end end end it 'parse email param with provided requirements for params' do get '/outer/abc@example.com' expect(last_response.body).to eq('abc@example.com') end it "should override outer namespace's requirements" do get '/outer/inner/someone@testing.wrong/test/1' expect(last_response.status).to eq(404) get '/outer/inner/someone@testing.com/test/1' expect(last_response.status).to eq(200) expect(last_response.body).to eq('someone@testing.com1') end end end context 'from body parameters' do before(:each) do subject.post '/request_body' do params[:user] end subject.put '/request_body' do params[:user] end end it 'converts JSON bodies to params' do post '/request_body', ::Grape::Json.dump(user: 'Bobby T.'), 'CONTENT_TYPE' => 'application/json' expect(last_response.body).to eq('Bobby T.') end it 'does not convert empty JSON bodies to params' do put '/request_body', '', 'CONTENT_TYPE' => 'application/json' expect(last_response.body).to eq('') end if Object.const_defined? :MultiXml it 'converts XML bodies to params' do post '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' expect(last_response.body).to eq('Bobby T.') end it 'converts XML bodies to params' do put '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' expect(last_response.body).to eq('Bobby T.') end else it 'converts XML bodies to params' do post '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' expect(last_response.body).to eq('{"__content__"=>"Bobby T."}') end it 'converts XML bodies to params' do put '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' expect(last_response.body).to eq('{"__content__"=>"Bobby T."}') end end it 'does not include parameters not defined by the body' do subject.post '/omitted_params' do error! 400, 'expected nil' if params[:version] params[:user] end post '/omitted_params', ::Grape::Json.dump(user: 'Bob'), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(201) expect(last_response.body).to eq('Bob') end end it 'responds with a 406 for an unsupported content-type' do subject.format :json # subject.content_type :json, "application/json" subject.put '/request_body' do params[:user] end put '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' expect(last_response.status).to eq(406) expect(last_response.body).to eq('{"error":"The requested content-type \'application/xml\' is not supported."}') end it 'does not accept text/plain in JSON format if application/json is specified as content type' do subject.format :json subject.default_format :json subject.put '/request_body' do params[:user] end put '/request_body', ::Grape::Json.dump(user: 'Bob'), 'CONTENT_TYPE' => 'text/plain' expect(last_response.status).to eq(406) expect(last_response.body).to eq('{"error":"The requested content-type \'text/plain\' is not supported."}') end context 'content type with params' do before do subject.format :json subject.content_type :json, 'application/json; charset=utf-8' subject.post do params[:data] end post '/', ::Grape::Json.dump(data: { some: 'payload' }), 'CONTENT_TYPE' => 'application/json' end it 'should not response with 406 for same type without params' do expect(last_response.status).not_to be 406 end it 'should response with given content type in headers' do expect(last_response.headers['Content-Type']).to eq 'application/json; charset=utf-8' end end context 'precedence' do before do subject.format :json subject.namespace '/:id' do get do { params: params[:id] } end post do { params: params[:id] } end put do { params: params[:id] } end end end it 'route string params have higher precedence than body params' do post '/123', { id: 456 }.to_json expect(JSON.parse(last_response.body)['params']).to eq '123' put '/123', { id: 456 }.to_json expect(JSON.parse(last_response.body)['params']).to eq '123' end it 'route string params have higher precedence than URL params' do get '/123?id=456' expect(JSON.parse(last_response.body)['params']).to eq '123' post '/123?id=456' expect(JSON.parse(last_response.body)['params']).to eq '123' end end context 'sets a value to params' do it 'params' do subject.params do requires :a, type: String end subject.get '/foo' do params[:a] = 'bar' end get '/foo', a: 'foo' expect(last_response.status).to eq(200) expect(last_response.body).to eq('bar') end end end describe '#error!' do it 'accepts a message' do subject.get('/hey') do error! 'This is not valid.' 'This is valid.' end get '/hey' expect(last_response.status).to eq(500) expect(last_response.body).to eq('This is not valid.') end it 'accepts a code' do subject.get('/hey') do error! 'Unauthorized.', 401 end get '/hey' expect(last_response.status).to eq(401) expect(last_response.body).to eq('Unauthorized.') end it 'accepts an object and render it in format' do subject.get '/hey' do error!({ 'dude' => 'rad' }, 403) end get '/hey.json' expect(last_response.status).to eq(403) expect(last_response.body).to eq('{"dude":"rad"}') end it 'accepts a frozen object' do subject.get '/hey' do error!({ 'dude' => 'rad' }.freeze, 403) end get '/hey.json' expect(last_response.status).to eq(403) expect(last_response.body).to eq('{"dude":"rad"}') end it 'can specifiy headers' do subject.get '/hey' do error!({ 'dude' => 'rad' }, 403, 'X-Custom' => 'value') end get '/hey.json' expect(last_response.status).to eq(403) expect(last_response.headers['X-Custom']).to eq('value') end it 'sets the status code for the endpoint' do memoized_endpoint = nil subject.get '/hey' do memoized_endpoint = self error!({ 'dude' => 'rad' }, 403, 'X-Custom' => 'value') end get '/hey.json' expect(memoized_endpoint.status).to eq(403) end end describe '#redirect' do it 'redirects to a url with status 302' do subject.get('/hey') do redirect '/ha' end get '/hey' expect(last_response.status).to eq 302 expect(last_response.headers['Location']).to eq '/ha' expect(last_response.body).to eq 'This resource has been moved temporarily to /ha.' end it 'has status code 303 if it is not get request and it is http 1.1' do subject.post('/hey') do redirect '/ha' end post '/hey', {}, 'HTTP_VERSION' => 'HTTP/1.1' expect(last_response.status).to eq 303 expect(last_response.headers['Location']).to eq '/ha' expect(last_response.body).to eq 'An alternate resource is located at /ha.' end it 'support permanent redirect' do subject.get('/hey') do redirect '/ha', permanent: true end get '/hey' expect(last_response.status).to eq 301 expect(last_response.headers['Location']).to eq '/ha' expect(last_response.body).to eq 'This resource has been moved permanently to /ha.' end it 'allows for an optional redirect body override' do subject.get('/hey') do redirect '/ha', body: 'test body' end get '/hey' expect(last_response.body).to eq 'test body' end end it 'does not persist params between calls' do subject.post('/new') do params[:text] end post '/new', text: 'abc' expect(last_response.body).to eq('abc') post '/new', text: 'def' expect(last_response.body).to eq('def') end it 'resets all instance variables (except block) between calls' do subject.helpers do def memoized @memoized ||= params[:howdy] end end subject.get('/hello') do memoized end get '/hello?howdy=hey' expect(last_response.body).to eq('hey') get '/hello?howdy=yo' expect(last_response.body).to eq('yo') end it 'allows explicit return calls' do subject.get('/home') do return 'Hello' end get '/home' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hello') end describe '.generate_api_method' do it 'raises NameError if the method name is already in use' do expect do Grape::Endpoint.generate_api_method('version', &proc {}) end.to raise_error(NameError) end it 'raises ArgumentError if a block is not given' do expect do Grape::Endpoint.generate_api_method('GET without a block method') end.to raise_error(ArgumentError) end it 'returns a Proc' do expect(Grape::Endpoint.generate_api_method('GET test for a proc', &proc {})).to be_a Proc end end context 'filters' do describe 'before filters' do it 'runs the before filter if set' do subject.before { env['before_test'] = 'OK' } subject.get('/before_test') { env['before_test'] } get '/before_test' expect(last_response.body).to eq('OK') end end describe 'after filters' do it 'overrides the response body if it sets it' do subject.after { body 'after' } subject.get('/after_test') { 'during' } get '/after_test' expect(last_response.body).to eq('after') end it 'does not override the response body with its return' do subject.after { 'after' } subject.get('/after_test') { 'body' } get '/after_test' expect(last_response.body).to eq('body') end end it 'allows adding to response with present' do subject.format :json subject.before { present :before, 'before' } subject.before_validation { present :before_validation, 'before_validation' } subject.after_validation { present :after_validation, 'after_validation' } subject.after { present :after, 'after' } subject.get :all_filters do present :endpoint, 'endpoint' end get '/all_filters' json = JSON.parse(last_response.body) expect(json.keys).to match_array %w[before before_validation after_validation endpoint after] end context 'when terminating the response with error!' do it 'breaks normal call chain' do called = [] subject.before { called << 'before' } subject.before_validation { called << 'before_validation' } subject.after_validation { error! :oops, 500 } subject.after { called << 'after' } subject.get :error_filters do called << 'endpoint' '' end get '/error_filters' expect(last_response.status).to eql 500 expect(called).to match_array %w[before before_validation] end it 'allows prior and parent filters of same type to run' do called = [] subject.before { called << 'parent' } subject.namespace :parent do before { called << 'prior' } before { error! :oops, 500 } before { called << 'subsequent' } get :hello do called << :endpoint 'Hello!' end end get '/parent/hello' expect(last_response.status).to eql 500 expect(called).to match_array %w[parent prior] end end end context 'anchoring' do describe 'delete 204' do it 'allows for the anchoring option with a delete method' do subject.send(:delete, '/example', anchor: true) {} send(:delete, '/example/and/some/more') expect(last_response.status).to eql 404 end it 'anchors paths by default for the delete method' do subject.send(:delete, '/example') {} send(:delete, '/example/and/some/more') expect(last_response.status).to eql 404 end it 'responds to /example/and/some/more for the non-anchored delete method' do subject.send(:delete, '/example', anchor: false) {} send(:delete, '/example/and/some/more') expect(last_response.status).to eql 204 expect(last_response.body).to be_empty end end describe 'delete 200, with response body' do it 'responds to /example/and/some/more for the non-anchored delete method' do subject.send(:delete, '/example', anchor: false) do status 200 body 'deleted' end send(:delete, '/example/and/some/more') expect(last_response.status).to eql 200 expect(last_response.body).not_to be_empty end end describe 'delete 200, with a return value (no explicit body)' do it 'responds to /example delete method' do subject.delete(:example) { 'deleted' } delete '/example' expect(last_response.status).to eql 200 expect(last_response.body).not_to be_empty end end describe 'delete 204, with nil has return value (no explicit body)' do it 'responds to /example delete method' do subject.delete(:example) { nil } delete '/example' expect(last_response.status).to eql 204 expect(last_response.body).to be_empty end end describe 'delete 204, with empty array has return value (no explicit body)' do it 'responds to /example delete method' do subject.delete(:example) { '' } delete '/example' expect(last_response.status).to eql 204 expect(last_response.body).to be_empty end end describe 'all other' do %w[post get head put options patch].each do |verb| it "allows for the anchoring option with a #{verb.upcase} method" do subject.send(verb, '/example', anchor: true) do verb end send(verb, '/example/and/some/more') expect(last_response.status).to eql 404 end it "anchors paths by default for the #{verb.upcase} method" do subject.send(verb, '/example') do verb end send(verb, '/example/and/some/more') expect(last_response.status).to eql 404 end it "responds to /example/and/some/more for the non-anchored #{verb.upcase} method" do subject.send(verb, '/example', anchor: false) do verb end send(verb, '/example/and/some/more') expect(last_response.status).to eql verb == 'post' ? 201 : 200 expect(last_response.body).to eql verb == 'head' ? '' : verb end end end end context 'request' do it 'is set to the url requested' do subject.get('/url') do request.url end get '/url' expect(last_response.body).to eq('http://example.org/url') end ['v1', :v1].each do |version| it "should include version #{version}" do subject.version version, using: :path subject.get('/url') do request.url end get "/#{version}/url" expect(last_response.body).to eq("http://example.org/#{version}/url") end end it 'should include prefix' do subject.version 'v1', using: :path subject.prefix 'api' subject.get('/url') do request.url end get '/api/v1/url' expect(last_response.body).to eq('http://example.org/api/v1/url') end end context 'version headers' do before do # NOTE: a 404 is returned instead of the 406 if cascade: false is not set. subject.version 'v1', using: :header, vendor: 'ohanapi', cascade: false subject.get '/test' do 'Hello!' end end it 'result in a 406 response if they are invalid' do get '/test', {}, 'HTTP_ACCEPT' => 'application/vnd.ohanapi.v1+json' expect(last_response.status).to eq(406) end it 'result in a 406 response if they cannot be parsed by rack-accept' do get '/test', {}, 'HTTP_ACCEPT' => 'application/vnd.ohanapi.v1+json; version=1' expect(last_response.status).to eq(406) end end context 'binary' do before do subject.get do file FileStreamer.new(__FILE__) end end it 'suports stream objects in response' do get '/' expect(last_response.status).to eq 200 expect(last_response.body).to eq File.read(__FILE__) end end context 'validation errors' do before do subject.before do header['Access-Control-Allow-Origin'] = '*' end subject.params do requires :id, type: String end subject.get do 'should not get here' end end it 'returns the errors, and passes headers' do get '/' expect(last_response.status).to eq 400 expect(last_response.body).to eq 'id is missing' expect(last_response.headers['Access-Control-Allow-Origin']).to eq('*') end end context 'instrumentation' do before do subject.before do # Placeholder end subject.get do 'hello' end @events = [] @subscriber = ActiveSupport::Notifications.subscribe(/grape/) do |*args| @events << ActiveSupport::Notifications::Event.new(*args) end end after do ActiveSupport::Notifications.unsubscribe(@subscriber) end it 'notifies AS::N' do get '/' # In order that the events finalized (time each block ended) expect(@events).to contain_exactly( have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), filters: a_collection_containing_exactly(an_instance_of(Proc)), type: :before }), have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), filters: [], type: :before_validation }), have_attributes(name: 'endpoint_run_validators.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), validators: [], request: a_kind_of(Grape::Request) }), have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), filters: [], type: :after_validation }), have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(Grape::Endpoint) }), have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), filters: [], type: :after }), have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), env: an_instance_of(Hash) }) ) # In order that events were initialized expect(@events.sort_by(&:time)).to contain_exactly( have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), env: an_instance_of(Hash) }), have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), filters: a_collection_containing_exactly(an_instance_of(Proc)), type: :before }), have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), filters: [], type: :before_validation }), have_attributes(name: 'endpoint_run_validators.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), validators: [], request: a_kind_of(Grape::Request) }), have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), filters: [], type: :after_validation }), have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(Grape::Endpoint) }), have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(Grape::Endpoint), filters: [], type: :after }) ) end end end grape-1.0.2/spec/grape/validations/0000755000004100000410000000000013231337007017204 5ustar www-datawww-datagrape-1.0.2/spec/grape/validations/types_spec.rb0000644000004100000410000000563213231337007021715 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::Types do module TypesSpec class FooType def self.parse(_); end end class BarType def self.parse; end end end VirtusA = Virtus::Attribute.build(String) module VirtusModule include Virtus.module end class VirtusB include VirtusModule end class VirtusC include Virtus.model end MyAxiom = Axiom::Types::String.new do minimum_length 1 maximum_length 30 end describe '::primitive?' do [ Integer, Float, Numeric, BigDecimal, Virtus::Attribute::Boolean, String, Symbol, Date, DateTime, Time, Rack::Multipart::UploadedFile ].each do |type| it "recognizes #{type} as a primitive" do expect(described_class.primitive?(type)).to be_truthy end end it 'identifies unknown types' do expect(described_class.primitive?(Object)).to be_falsy expect(described_class.primitive?(TypesSpec::FooType)).to be_falsy end end describe '::structure?' do [ Hash, Array, Set ].each do |type| it "recognizes #{type} as a structure" do expect(described_class.structure?(type)).to be_truthy end end end describe '::recognized?' do [ VirtusA, VirtusB, VirtusC, MyAxiom ].each do |type| it "recognizes #{type}" do expect(described_class.recognized?(type)).to be_truthy end end end describe '::special?' do [ JSON, Array[JSON], File, Rack::Multipart::UploadedFile ].each do |type| it "provides special handling for #{type.inspect}" do expect(described_class.special?(type)).to be_truthy end end end describe '::custom?' do it 'returns false if the type does not respond to :parse' do expect(described_class.custom?(Object)).to be_falsy end it 'returns true if the type responds to :parse with one argument' do expect(described_class.custom?(TypesSpec::FooType)).to be_truthy end it 'returns false if the type\'s #parse method takes other than one argument' do expect(described_class.custom?(TypesSpec::BarType)).to be_falsy end end describe '::build_coercer' do it 'has internal cache variables' do expect(described_class.instance_variable_get(:@__cache)).to be_a(Hash) expect(described_class.instance_variable_get(:@__cache_write_lock)).to be_a(Mutex) end it 'caches the result of the Virtus::Attribute.build method' do original_cache = described_class.instance_variable_get(:@__cache) described_class.instance_variable_set(:@__cache, {}) coercer = 'TestCoercer' expect(Virtus::Attribute).to receive(:build).once.and_return(coercer) expect(described_class.build_coercer(Array[String])).to eq(coercer) expect(described_class.build_coercer(Array[String])).to eq(coercer) described_class.instance_variable_set(:@__cache, original_cache) end end end grape-1.0.2/spec/grape/validations/instance_behaivour_spec.rb0000644000004100000410000000217713231337007024422 0ustar www-datawww-datarequire 'spec_helper' describe 'Validator with instance variables' do let(:validator_type) do Class.new(Grape::Validations::Base) do def validate_param!(_attr_name, _params) if @instance_variable raise Grape::Exceptions::Validation, params: ['params'], message: 'This should never happen' end @instance_variable = true end end end before do Grape::Validations.register_validator('instance_validator', validator_type) end after do Grape::Validations.deregister_validator('instance_validator') end let(:app) do Class.new(Grape::API) do params do optional :param_to_validate, instance_validator: true optional :another_param_to_validate, instance_validator: true end get do 'noop' end end end it 'passes validation every time' do expect(validator_type).to receive(:new).exactly(4).times.and_call_original 2.times do get '/', param_to_validate: 'value', another_param_to_validate: 'value' expect(last_response.status).to eq 200 end end end grape-1.0.2/spec/grape/validations/params_scope_spec.rb0000644000004100000410000006520713231337007023231 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::ParamsScope do subject do Class.new(Grape::API) end def app subject end context 'setting a default' do let(:documentation) { subject.routes.first.params } context 'when the default value is truthy' do before do subject.params do optional :int, type: Integer, default: 42 end subject.get end it 'adds documentation about the default value' do expect(documentation).to have_key('int') expect(documentation['int']).to have_key(:default) expect(documentation['int'][:default]).to eq(42) end end context 'when the default value is false' do before do subject.params do optional :bool, type: Virtus::Attribute::Boolean, default: false end subject.get end it 'adds documentation about the default value' do expect(documentation).to have_key('bool') expect(documentation['bool']).to have_key(:default) expect(documentation['bool'][:default]).to eq(false) end end context 'when the default value is nil' do before do subject.params do optional :object, type: Object, default: nil end subject.get end it 'adds documentation about the default value' do expect(documentation).to have_key('object') expect(documentation['object']).to have_key(:default) expect(documentation['object'][:default]).to eq(nil) end end end context 'without a default' do before do subject.params do optional :object, type: Object end subject.get end it 'does not add documentation for the default value' do documentation = subject.routes.first.params expect(documentation).to have_key('object') expect(documentation['object']).not_to have_key(:default) end end context 'setting description' do %i[desc description].each do |description_type| it "allows setting #{description_type}" do subject.params do requires :int, type: Integer, description_type => 'My very nice integer' end subject.get '/single' do 'int works' end get '/single', int: 420 expect(last_response.status).to eq(200) expect(last_response.body).to eq('int works') end end end context 'when using custom types' do module ParamsScopeSpec class CustomType attr_reader :value def self.parse(value) raise if value == 'invalid' new(value) end def initialize(value) @value = value end end end it 'coerces the parameter via the type\'s parse method' do subject.params do requires :foo, type: ParamsScopeSpec::CustomType end subject.get('/types') { params[:foo].value } get '/types', foo: 'valid' expect(last_response.status).to eq(200) expect(last_response.body).to eq('valid') get '/types', foo: 'invalid' expect(last_response.status).to eq(400) expect(last_response.body).to match(/foo is invalid/) end end context 'param alias' do it do subject.params do requires :foo, as: :bar optional :super, as: :hiper end subject.get('/alias') { "#{declared(params)['bar']}-#{declared(params)['hiper']}" } get '/alias', foo: 'any', super: 'any2' expect(last_response.status).to eq(200) expect(last_response.body).to eq('any-any2') end it do subject.params do requires :foo, as: :bar, type: String, coerce_with: ->(c) { c.strip } end subject.get('/alias-coerced') { "#{params['bar']}-#{params['foo']}" } get '/alias-coerced', foo: ' there we go ' expect(last_response.status).to eq(200) expect(last_response.body).to eq('there we go-') end it do subject.params do requires :foo, as: :bar, allow_blank: false end subject.get('/alias-not-blank') {} get '/alias-not-blank', foo: '' expect(last_response.status).to eq(400) expect(last_response.body).to eq('foo is empty') end end context 'array without coerce type explicitly given' do it 'sets the type based on first element' do subject.params do requires :periods, type: Array, values: -> { %w[day month] } end subject.get('/required') { 'required works' } get '/required', periods: %w[day month] expect(last_response.status).to eq(200) expect(last_response.body).to eq('required works') end it 'fails to call API without Array type' do subject.params do requires :periods, type: Array, values: -> { %w[day month] } end subject.get('/required') { 'required works' } get '/required', periods: 'day' expect(last_response.status).to eq(400) expect(last_response.body).to eq('periods is invalid') end it 'raises exception when values are of different type' do expect do subject.params { requires :numbers, type: Array, values: [1, 'definitely not a number', 3] } end.to raise_error Grape::Exceptions::IncompatibleOptionValues end it 'raises exception when range values have different endpoint types' do expect do subject.params { requires :numbers, type: Array, values: 0.0..10 } end.to raise_error Grape::Exceptions::IncompatibleOptionValues end end context 'coercing values validation with proc' do it 'allows the proc to pass validation without checking' do subject.params { requires :numbers, type: Integer, values: -> { [0, 1, 2] } } subject.post('/required') { 'coercion with proc works' } post '/required', numbers: '1' expect(last_response.status).to eq(201) expect(last_response.body).to eq('coercion with proc works') end it 'allows the proc to pass validation without checking in value' do subject.params { requires :numbers, type: Integer, values: { value: -> { [0, 1, 2] } } } subject.post('/required') { 'coercion with proc works' } post '/required', numbers: '1' expect(last_response.status).to eq(201) expect(last_response.body).to eq('coercion with proc works') end it 'allows the proc to pass validation without checking in except' do subject.params { requires :numbers, type: Integer, values: { except: -> { [0, 1, 2] } } } subject.post('/required') { 'coercion with proc works' } post '/required', numbers: '10' expect(last_response.status).to eq(201) expect(last_response.body).to eq('coercion with proc works') end end context 'with range values' do context "when left range endpoint isn't #kind_of? the type" do it 'raises exception' do expect do subject.params { requires :latitude, type: Integer, values: -90.0..90 } end.to raise_error Grape::Exceptions::IncompatibleOptionValues end end context "when right range endpoint isn't #kind_of? the type" do it 'raises exception' do expect do subject.params { requires :latitude, type: Integer, values: -90..90.0 } end.to raise_error Grape::Exceptions::IncompatibleOptionValues end end context 'when the default is an array' do context 'and is the entire range of allowed values' do it 'does not raise an exception' do expect do subject.params { optional :numbers, type: Array[Integer], values: 0..2, default: 0..2 } end.to_not raise_error end end context 'and is a subset of allowed values' do it 'does not raise an exception' do expect do subject.params { optional :numbers, type: Array[Integer], values: [0, 1, 2], default: [1, 0] } end.to_not raise_error end end end context 'when both range endpoints are #kind_of? the type' do it 'accepts values in the range' do subject.params do requires :letter, type: String, values: 'a'..'z' end subject.get('/letter') { params[:letter] } get '/letter', letter: 'j' expect(last_response.status).to eq(200) expect(last_response.body).to eq('j') end it 'rejects values outside the range' do subject.params do requires :letter, type: String, values: 'a'..'z' end subject.get('/letter') { params[:letter] } get '/letter', letter: 'J' expect(last_response.status).to eq(400) expect(last_response.body).to eq('letter does not have a valid value') end end end context 'parameters in group' do it 'errors when no type is provided' do expect do subject.params do group :a do requires :b end end end.to raise_error Grape::Exceptions::MissingGroupTypeError expect do subject.params do optional :a do requires :b end end end.to raise_error Grape::Exceptions::MissingGroupTypeError end it 'allows Hash as type' do subject.params do group :a, type: Hash do requires :b end end subject.get('/group') { 'group works' } get '/group', a: { b: true } expect(last_response.status).to eq(200) expect(last_response.body).to eq('group works') subject.params do optional :a, type: Hash do requires :b end end get '/optional_type_hash' end it 'allows Array as type' do subject.params do group :a, type: Array do requires :b end end subject.get('/group') { 'group works' } get '/group', a: [{ b: true }] expect(last_response.status).to eq(200) expect(last_response.body).to eq('group works') subject.params do optional :a, type: Array do requires :b end end get '/optional_type_array' end it 'handles missing optional Array type' do subject.params do optional :a, type: Array do requires :b end end subject.get('/test') { declared(params).to_json } get '/test' expect(last_response.status).to eq(200) expect(last_response.body).to eq('{"a":[]}') end it 'errors with an unsupported type' do expect do subject.params do group :a, type: Set do requires :b end end end.to raise_error Grape::Exceptions::UnsupportedGroupTypeError expect do subject.params do optional :a, type: Set do requires :b end end end.to raise_error Grape::Exceptions::UnsupportedGroupTypeError end end context 'when validations are dependent on a parameter' do before do subject.params do optional :a given :a do requires :b end end subject.get('/test') { declared(params).to_json } end it 'applies the validations only if the parameter is present' do get '/test' expect(last_response.status).to eq(200) get '/test', a: true expect(last_response.status).to eq(400) expect(last_response.body).to eq('b is missing') get '/test', a: true, b: true expect(last_response.status).to eq(200) end it 'applies the validations of multiple parameters' do subject.params do optional :a, :b given :a, :b do requires :c end end subject.get('/multiple') { declared(params).to_json } get '/multiple' expect(last_response.status).to eq(200) get '/multiple', a: true expect(last_response.status).to eq(200) get '/multiple', b: true expect(last_response.status).to eq(200) get '/multiple', a: true, b: true expect(last_response.status).to eq(400) expect(last_response.body).to eq('c is missing') get '/multiple', a: true, b: true, c: true expect(last_response.status).to eq(200) end it 'applies only the appropriate validation' do subject.params do optional :a optional :b mutually_exclusive :a, :b given :a do requires :c, type: String end given :b do requires :c, type: Integer end end subject.get('/multiple') { declared(params).to_json } get '/multiple' expect(last_response.status).to eq(200) get '/multiple', a: true, c: 'test' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body).symbolize_keys).to eq a: 'true', b: nil, c: 'test' get '/multiple', b: true, c: '3' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body).symbolize_keys).to eq a: nil, b: 'true', c: 3 get '/multiple', a: true expect(last_response.status).to eq(400) expect(last_response.body).to eq('c is missing') get '/multiple', b: true expect(last_response.status).to eq(400) expect(last_response.body).to eq('c is missing') get '/multiple', a: true, b: true, c: 'test' expect(last_response.status).to eq(400) expect(last_response.body).to eq('a, b are mutually exclusive, c is invalid') end it 'raises an error if the dependent parameter was never specified' do expect do subject.params do given :c do end end end.to raise_error(Grape::Exceptions::UnknownParameter) end it 'does not validate nested requires when given is false' do subject.params do requires :a, type: String, allow_blank: false, values: %w[x y z] given a: ->(val) { val == 'x' } do requires :inner1, type: Hash, allow_blank: false do requires :foo, type: Integer, allow_blank: false end end given a: ->(val) { val == 'y' } do requires :inner2, type: Hash, allow_blank: false do requires :bar, type: Integer, allow_blank: false requires :baz, type: Array, allow_blank: false do requires :baz_category, type: String, allow_blank: false end end end given a: ->(val) { val == 'z' } do requires :inner3, type: Array, allow_blank: false do requires :bar, type: Integer, allow_blank: false requires :baz, type: Array, allow_blank: false do requires :baz_category, type: String, allow_blank: false end end end end subject.get('/varying') { declared(params).to_json } get '/varying', a: 'x', inner1: { foo: 1 } expect(last_response.status).to eq(200) get '/varying', a: 'y', inner2: { bar: 2, baz: [{ baz_category: 'barstools' }] } expect(last_response.status).to eq(200) get '/varying', a: 'y', inner2: { bar: 2, baz: [{ unrelated: 'yep' }] } expect(last_response.status).to eq(400) get '/varying', a: 'z', inner3: [{ bar: 3, baz: [{ baz_category: 'barstools' }] }] expect(last_response.status).to eq(200) end it 'includes the parameter within #declared(params)' do get '/test', a: true, b: true expect(JSON.parse(last_response.body)).to eq('a' => 'true', 'b' => 'true') end it 'returns a sensible error message within a nested context' do subject.params do requires :bar, type: Hash do optional :a given :a do requires :b end end end subject.get('/nested') { 'worked' } get '/nested', bar: { a: true } expect(last_response.status).to eq(400) expect(last_response.body).to eq('bar[b] is missing') end it 'includes the nested parameter within #declared(params)' do subject.params do requires :bar, type: Hash do optional :a given :a do requires :b end end end subject.get('/nested') { declared(params).to_json } get '/nested', bar: { a: true, b: 'yes' } expect(JSON.parse(last_response.body)).to eq('bar' => { 'a' => 'true', 'b' => 'yes' }) end it 'includes level 2 nested parameters outside the given within #declared(params)' do subject.params do requires :bar, type: Hash do optional :a given :a do requires :c, type: Hash do requires :b end end end end subject.get('/nested') { declared(params).to_json } get '/nested', bar: { a: true, c: { b: 'yes' } } expect(JSON.parse(last_response.body)).to eq('bar' => { 'a' => 'true', 'c' => { 'b' => 'yes' } }) end end context 'when validations are dependent on a parameter within an array param' do before do subject.params do requires :foos, type: Array do optional :foo_type, :baz_type given :foo_type do requires :bar end end end subject.post('/test') { declared(params).to_json } end it 'applies the constraint within each value' do post '/test', { foos: [{ foo_type: 'a' }, { baz_type: 'c' }] }.to_json, 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(400) expect(last_response.body).to eq('foos[0][bar] is missing') end end context 'when validations are dependent on a parameter with specific value' do # build test cases from all combinations of declarations and options a_decls = %i[optional requires] a_options = [{}, { values: %w[x y z] }] b_options = [{}, { type: String }, { allow_blank: false }, { type: String, allow_blank: false }] combinations = a_decls.product(a_options, b_options) combinations.each_with_index do |combination, i| a_decl, a_opts, b_opts = combination context "(case #{i})" do before do # puts "a_decl: #{a_decl}, a_opts: #{a_opts}, b_opts: #{b_opts}" subject.params do send a_decl, :a, **a_opts given(a: ->(val) { val == 'x' }) { requires :b, **b_opts } given(a: ->(val) { val == 'y' }) { requires :c, **b_opts } end subject.get('/test') { declared(params).to_json } end if a_decl == :optional it 'skips validation when base param is missing' do get '/test' expect(last_response.status).to eq(200) end end it 'skips validation when base param does not have a specified value' do get '/test', a: 'z' expect(last_response.status).to eq(200) get '/test', a: 'z', b: '' expect(last_response.status).to eq(200) end it 'applies the validation when base param has the specific value' do get '/test', a: 'x' expect(last_response.status).to eq(400) expect(last_response.body).to include('b is missing') get '/test', a: 'x', b: true expect(last_response.status).to eq(200) get '/test', a: 'x', b: true, c: '' expect(last_response.status).to eq(200) end it 'includes the parameter within #declared(params)' do get '/test', a: 'x', b: true expect(JSON.parse(last_response.body)).to eq('a' => 'x', 'b' => 'true', 'c' => nil) end end end end it 'raises an error if the dependent parameter was never specified' do expect do subject.params do given :c do end end end.to raise_error(Grape::Exceptions::UnknownParameter) end it 'returns a sensible error message within a nested context' do subject.params do requires :bar, type: Hash do optional :a given a: ->(val) { val == 'x' } do requires :b end end end subject.get('/nested') { 'worked' } get '/nested', bar: { a: 'x' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('bar[b] is missing') end it 'includes the nested parameter within #declared(params)' do subject.params do requires :bar, type: Hash do optional :a given a: ->(val) { val == 'x' } do requires :b end end end subject.get('/nested') { declared(params).to_json } get '/nested', bar: { a: 'x', b: 'yes' } expect(JSON.parse(last_response.body)).to eq('bar' => { 'a' => 'x', 'b' => 'yes' }) end it 'includes level 2 nested parameters outside the given within #declared(params)' do subject.params do requires :bar, type: Hash do optional :a given a: ->(val) { val == 'x' } do requires :c, type: Hash do requires :b end end end end subject.get('/nested') { declared(params).to_json } get '/nested', bar: { a: 'x', c: { b: 'yes' } } expect(JSON.parse(last_response.body)).to eq('bar' => { 'a' => 'x', 'c' => { 'b' => 'yes' } }) end it 'includes deeply nested parameters within #declared(params)' do subject.params do requires :arr1, type: Array do requires :hash1, type: Hash do requires :arr2, type: Array do requires :hash2, type: Hash do requires :something, type: String end end end end end subject.get('/nested_deep') { declared(params).to_json } get '/nested_deep', arr1: [{ hash1: { arr2: [{ hash2: { something: 'value' } }] } }] expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq('arr1' => [{ 'hash1' => { 'arr2' => [{ 'hash2' => { 'something' => 'value' } }] } }]) end context 'failing fast' do context 'when fail_fast is not defined' do it 'does not stop validation' do subject.params do requires :one requires :two requires :three end subject.get('/fail-fast') { declared(params).to_json } get '/fail-fast' expect(last_response.status).to eq(400) expect(last_response.body).to eq('one is missing, two is missing, three is missing') end end context 'when fail_fast is defined it stops the validation' do it 'of other params' do subject.params do requires :one, fail_fast: true requires :two end subject.get('/fail-fast') { declared(params).to_json } get '/fail-fast' expect(last_response.status).to eq(400) expect(last_response.body).to eq('one is missing') end it 'for a single param' do subject.params do requires :one, allow_blank: false, regexp: /[0-9]+/, fail_fast: true end subject.get('/fail-fast') { declared(params).to_json } get '/fail-fast', one: '' expect(last_response.status).to eq(400) expect(last_response.body).to eq('one is empty') end end end context 'when params have group attributes' do context 'with validations' do before do subject.params do with(allow_blank: false) do requires :id optional :name optional :address, allow_blank: true end end subject.get('test') end context 'when data is invalid' do before do get 'test', id: '', name: '' end it 'returns a validation error' do expect(last_response.status).to eq(400) end it 'applies group validations for every parameter' do expect(last_response.body).to eq('id is empty, name is empty') end end context 'when parameter has the same validator as a group' do before do get 'test', id: 'id', address: '' end it 'returns a successful response' do expect(last_response.status).to eq(200) end it 'prioritizes parameter validation over group validation' do expect(last_response.body).to_not include('address is empty') end end end context 'with types' do before do subject.params do with(type: Date) do requires :created_at end end subject.get('test') { params[:created_at] } end context 'when invalid date provided' do before do get 'test', created_at: 'not_a_date' end it 'responds with HTTP error' do expect(last_response.status).to eq(400) end it 'returns a validation error' do expect(last_response.body).to eq('created_at is invalid') end end context 'when created_at receives a valid date' do before do get 'test', created_at: '2016-01-01' end it 'returns a successful response' do expect(last_response.status).to eq(200) end it 'returns a date' do expect(last_response.body).to eq('2016-01-01') end end end context 'with several group attributes' do before do subject.params do with(values: [1]) do requires :id, type: Integer end with(allow_blank: false) do optional :address, type: String end requires :name end subject.get('test') end context 'when data is invalid' do before do get 'test', id: 2, address: '' end it 'responds with HTTP error' do expect(last_response.status).to eq(400) end it 'returns a validation error' do expect(last_response.body).to eq('id does not have a valid value, address is empty, name is missing') end end context 'when correct data is provided' do before do get 'test', id: 1, address: 'Some street', name: 'John' end it 'returns a successful response' do expect(last_response.status).to eq(200) end end end context 'with nested groups' do before do subject.params do with(type: Integer) do requires :id with(type: Date) do requires :created_at optional :updated_at end end end subject.get('test') end context 'when data is invalid' do before do get 'test', id: 'wrong', created_at: 'not_a_date', updated_at: '2016-01-01' end it 'responds with HTTP error' do expect(last_response.status).to eq(400) end it 'returns a validation error' do expect(last_response.body).to eq('id is invalid, created_at is invalid') end end context 'when correct data is provided' do before do get 'test', id: 1, created_at: '2016-01-01' end it 'returns a successful response' do expect(last_response.status).to eq(200) end end end end end grape-1.0.2/spec/grape/validations/attributes_iterator_spec.rb0000644000004100000410000000011613231337007024640 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::AttributesIterator do end grape-1.0.2/spec/grape/validations/validators/0000755000004100000410000000000013231337007021354 5ustar www-datawww-datagrape-1.0.2/spec/grape/validations/validators/exactly_one_of_spec.rb0000644000004100000410000000416313231337007025715 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::ExactlyOneOfValidator do describe '#validate!' do let(:scope) do Struct.new(:opts) do def params(arg) arg end def required?; end end end let(:exactly_one_of_params) { %i[beer wine grapefruit] } let(:validator) { described_class.new(exactly_one_of_params, {}, false, scope.new) } context 'when all restricted params are present' do let(:params) { { beer: true, wine: true, grapefruit: true } } it 'raises a validation exception' do expect do validator.validate! params end.to raise_error(Grape::Exceptions::Validation) end context 'mixed with other params' do let(:mixed_params) { params.merge!(other: true, andanother: true) } it 'still raises a validation exception' do expect do validator.validate! mixed_params end.to raise_error(Grape::Exceptions::Validation) end end end context 'when a subset of restricted params are present' do let(:params) { { beer: true, grapefruit: true } } it 'raises a validation exception' do expect do validator.validate! params end.to raise_error(Grape::Exceptions::Validation) end end context 'when params keys come as strings' do let(:params) { { 'beer' => true, 'grapefruit' => true } } it 'raises a validation exception' do expect do validator.validate! params end.to raise_error(Grape::Exceptions::Validation) end end context 'when none of the restricted params is selected' do let(:params) { { somethingelse: true } } it 'raises a validation exception' do expect do validator.validate! params end.to raise_error(Grape::Exceptions::Validation) end end context 'when exactly one of the restricted params is selected' do let(:params) { { beer: true, somethingelse: true } } it 'does not raise a validation exception' do expect(validator.validate!(params)).to eql params end end end end grape-1.0.2/spec/grape/validations/validators/coerce_spec.rb0000644000004100000410000007124613231337007024165 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::CoerceValidator do subject do Class.new(Grape::API) end def app subject end describe 'coerce' do module CoerceValidatorSpec class User include Virtus.model attribute :id, Integer attribute :name, String end end context 'i18n' do after :each do I18n.locale = :en end it 'i18n error on malformed input' do I18n.load_path << File.expand_path('../zh-CN.yml', __FILE__) I18n.reload! I18n.locale = 'zh-CN'.to_sym subject.params do requires :age, type: Integer end subject.get '/single' do 'int works' end get '/single', age: '43a' expect(last_response.status).to eq(400) expect(last_response.body).to eq('年龄格å¼ä¸æ­£ç¡®') end it 'gives an english fallback error when default locale message is blank' do I18n.locale = 'pt-BR'.to_sym subject.params do requires :age, type: Integer end subject.get '/single' do 'int works' end get '/single', age: '43a' expect(last_response.status).to eq(400) expect(last_response.body).to eq('age is invalid') end end context 'with a custom validation message' do it 'errors on malformed input' do subject.params do requires :int, type: { value: Integer, message: 'type cast is invalid' } end subject.get '/single' do 'int works' end get '/single', int: '43a' expect(last_response.status).to eq(400) expect(last_response.body).to eq('int type cast is invalid') get '/single', int: '43' expect(last_response.status).to eq(200) expect(last_response.body).to eq('int works') end context 'on custom coercion rules' do before do subject.params do requires :a, types: { value: [Boolean, String], message: 'type cast is invalid' }, coerce_with: (lambda do |val| if val == 'yup' true elsif val == 'false' 0 else val end end) end subject.get '/' do params[:a].class.to_s end end it 'respects :coerce_with' do get '/', a: 'yup' expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') end it 'still validates type' do get '/', a: 'false' expect(last_response.status).to eq(400) expect(last_response.body).to eq('a type cast is invalid') end it 'performs no additional coercion' do get '/', a: 'true' expect(last_response.status).to eq(200) expect(last_response.body).to eq('String') end end end it 'error on malformed input' do subject.params do requires :int, type: Integer end subject.get '/single' do 'int works' end get '/single', int: '43a' expect(last_response.status).to eq(400) expect(last_response.body).to eq('int is invalid') get '/single', int: '43' expect(last_response.status).to eq(200) expect(last_response.body).to eq('int works') end it 'error on malformed input (Array)' do subject.params do requires :ids, type: Array[Integer] end subject.get '/array' do 'array int works' end get 'array', ids: %w[1 2 az] expect(last_response.status).to eq(400) expect(last_response.body).to eq('ids is invalid') get 'array', ids: %w[1 2 890] expect(last_response.status).to eq(200) expect(last_response.body).to eq('array int works') end context 'complex objects' do it 'error on malformed input for complex objects' do subject.params do requires :user, type: CoerceValidatorSpec::User end subject.get '/user' do 'complex works' end get '/user', user: '32' expect(last_response.status).to eq(400) expect(last_response.body).to eq('user is invalid') get '/user', user: { id: 32, name: 'Bob' } expect(last_response.status).to eq(200) expect(last_response.body).to eq('complex works') end end context 'coerces' do it 'Integer' do subject.params do requires :int, coerce: Integer end subject.get '/int' do params[:int].class end get '/int', int: '45' expect(last_response.status).to eq(200) expect(last_response.body).to eq(integer_class_name) end context 'Array' do it 'Array of Integers' do subject.params do requires :arry, coerce: Array[Integer] end subject.get '/array' do params[:arry][0].class end get '/array', arry: %w[1 2 3] expect(last_response.status).to eq(200) expect(last_response.body).to eq(integer_class_name) end it 'Array of Bools' do subject.params do requires :arry, coerce: Array[Virtus::Attribute::Boolean] end subject.get '/array' do params[:arry][0].class end get 'array', arry: [1, 0] expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') end it 'Array of Complex' do subject.params do requires :arry, coerce: Array[CoerceValidatorSpec::User] end subject.get '/array' do params[:arry].size end get 'array', arry: [31] expect(last_response.status).to eq(400) expect(last_response.body).to eq('arry is invalid') get 'array', arry: { id: 31, name: 'Alice' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('arry is invalid') get 'array', arry: [{ id: 31, name: 'Alice' }] expect(last_response.status).to eq(200) expect(last_response.body).to eq('1') end it 'Array of type implementing parse' do subject.params do requires :uri, type: Array[URI] end subject.get '/uri_array' do params[:uri][0].class end get 'uri_array', uri: ['http://www.google.com'] expect(last_response.status).to eq(200) expect(last_response.body).to eq('URI::HTTP') end it 'Set of type implementing parse' do subject.params do requires :uri, type: Set[URI] end subject.get '/uri_array' do "#{params[:uri].class},#{params[:uri].first.class},#{params[:uri].size}" end get 'uri_array', uri: Array.new(2) { 'http://www.example.com' } expect(last_response.status).to eq(200) expect(last_response.body).to eq('Set,URI::HTTP,1') end it 'Array of class implementing parse and parsed?' do class SecureURIOnly def self.parse(value) URI.parse(value) end def self.parsed?(value) value.is_a? URI::HTTPS end end subject.params do requires :uri, type: Array[SecureURIOnly] end subject.get '/secure_uris' do params[:uri].first.class end get 'secure_uris', uri: ['https://www.example.com'] expect(last_response.status).to eq(200) expect(last_response.body).to eq('URI::HTTPS') get 'secure_uris', uri: ['https://www.example.com', 'http://www.example.com'] expect(last_response.status).to eq(400) expect(last_response.body).to eq('uri is invalid') end end context 'Set' do it 'Set of Integers' do subject.params do requires :set, coerce: Set[Integer] end subject.get '/set' do params[:set].first.class end get '/set', set: Set.new([1, 2, 3, 4]).to_a expect(last_response.status).to eq(200) expect(last_response.body).to eq(integer_class_name) end it 'Set of Bools' do subject.params do requires :set, coerce: Set[Virtus::Attribute::Boolean] end subject.get '/set' do params[:set].first.class end get '/set', set: Set.new([1, 0]).to_a expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') end end it 'Bool' do subject.params do requires :bool, coerce: Virtus::Attribute::Boolean end subject.get '/bool' do params[:bool].class end get '/bool', bool: 1 expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') get '/bool', bool: 0 expect(last_response.status).to eq(200) expect(last_response.body).to eq('FalseClass') get '/bool', bool: 'false' expect(last_response.status).to eq(200) expect(last_response.body).to eq('FalseClass') get '/bool', bool: 'true' expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') end it 'Boolean' do subject.params do optional :boolean, type: Boolean, default: true end subject.get '/boolean' do params[:boolean].class end get '/boolean' expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') get '/boolean', boolean: true expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') get '/boolean', boolean: false expect(last_response.status).to eq(200) expect(last_response.body).to eq('FalseClass') get '/boolean', boolean: 'true' expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') get '/boolean', boolean: 'false' expect(last_response.status).to eq(200) expect(last_response.body).to eq('FalseClass') get '/boolean', boolean: 123 expect(last_response.status).to eq(400) expect(last_response.body).to eq('boolean is invalid') get '/boolean', boolean: '123' expect(last_response.status).to eq(400) expect(last_response.body).to eq('boolean is invalid') end it 'Rack::Multipart::UploadedFile' do subject.params do requires :file, type: Rack::Multipart::UploadedFile end subject.post '/upload' do params[:file][:filename] end post '/upload', file: Rack::Test::UploadedFile.new(__FILE__) expect(last_response.status).to eq(201) expect(last_response.body).to eq(File.basename(__FILE__).to_s) post '/upload', file: 'not a file' expect(last_response.status).to eq(400) expect(last_response.body).to eq('file is invalid') end it 'File' do subject.params do requires :file, coerce: File end subject.post '/upload' do params[:file][:filename] end post '/upload', file: Rack::Test::UploadedFile.new(__FILE__) expect(last_response.status).to eq(201) expect(last_response.body).to eq(File.basename(__FILE__).to_s) post '/upload', file: 'not a file' expect(last_response.status).to eq(400) expect(last_response.body).to eq('file is invalid') end it 'Nests integers' do subject.params do requires :integers, type: Hash do requires :int, coerce: Integer end end subject.get '/int' do params[:integers][:int].class end get '/int', integers: { int: '45' } expect(last_response.status).to eq(200) expect(last_response.body).to eq(integer_class_name) end end context 'using coerce_with' do it 'parses parameters with Array type' do subject.params do requires :values, type: Array, coerce_with: ->(val) { val.split(/\s+/).map(&:to_i) } end subject.get '/ints' do params[:values] end get '/ints', values: '1 2 3 4' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq([1, 2, 3, 4]) get '/ints', values: 'a b c d' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq([0, 0, 0, 0]) end it 'parses parameters with Array[String] type' do subject.params do requires :values, type: Array[String], coerce_with: ->(val) { val.split(/\s+/).map(&:to_i) } end subject.get '/ints' do params[:values] end get '/ints', values: '1 2 3 4' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq(%w[1 2 3 4]) get '/ints', values: 'a b c d' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq(%w[0 0 0 0]) end it 'parses parameters with Array[Integer] type' do subject.params do requires :values, type: Array[Integer], coerce_with: ->(val) { val.split(/\s+/).map(&:to_i) } end subject.get '/ints' do params[:values] end get '/ints', values: '1 2 3 4' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq([1, 2, 3, 4]) get '/ints', values: 'a b c d' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq([0, 0, 0, 0]) end it 'parses parameters even if type is valid' do subject.params do requires :values, type: Array, coerce_with: ->(array) { array.map { |val| val.to_i + 1 } } end subject.get '/ints' do params[:values] end get '/ints', values: [1, 2, 3, 4] expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq([2, 3, 4, 5]) get '/ints', values: %w[a b c d] expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq([1, 1, 1, 1]) end it 'uses parse where available' do subject.params do requires :ints, type: Array, coerce_with: JSON do requires :i, type: Integer requires :j end end subject.get '/ints' do ints = params[:ints].first 'coercion works' if ints[:i] == 1 && ints[:j] == '2' end get '/ints', ints: [{ i: 1, j: '2' }] expect(last_response.status).to eq(400) expect(last_response.body).to eq('ints is invalid') get '/ints', ints: '{"i":1,"j":"2"}' expect(last_response.status).to eq(400) expect(last_response.body).to eq('ints is invalid') get '/ints', ints: '[{"i":"1","j":"2"}]' expect(last_response.status).to eq(200) expect(last_response.body).to eq('coercion works') end it 'accepts any callable' do subject.params do requires :ints, type: Hash, coerce_with: JSON.method(:parse) do requires :int, type: Integer, coerce_with: ->(val) { val == 'three' ? 3 : val } end end subject.get '/ints' do params[:ints][:int] end get '/ints', ints: '{"int":"3"}' expect(last_response.status).to eq(400) expect(last_response.body).to eq('ints[int] is invalid') get '/ints', ints: '{"int":"three"}' expect(last_response.status).to eq(200) expect(last_response.body).to eq('3') get '/ints', ints: '{"int":3}' expect(last_response.status).to eq(200) expect(last_response.body).to eq('3') end it 'must be supplied with :type or :coerce' do expect do subject.params do requires :ints, coerce_with: JSON end end.to raise_error(ArgumentError) end end context 'first-class JSON' do it 'parses objects, hashes, and arrays' do subject.params do requires :splines, type: JSON do requires :x, type: Integer, values: [1, 2, 3] optional :ints, type: Array[Integer] optional :obj, type: Hash do optional :y end end end subject.get '/' do if params[:splines].is_a? Hash params[:splines][:obj][:y] elsif params[:splines].any? { |s| s.key? :obj } 'arrays work' end end get '/', splines: '{"x":1,"ints":[1,2,3],"obj":{"y":"woof"}}' expect(last_response.status).to eq(200) expect(last_response.body).to eq('woof') get '/', splines: { x: 1, ints: [1, 2, 3], obj: { y: 'woof' } } expect(last_response.status).to eq(200) expect(last_response.body).to eq('woof') get '/', splines: '[{"x":2,"ints":[]},{"x":3,"ints":[4],"obj":{"y":"quack"}}]' expect(last_response.status).to eq(200) expect(last_response.body).to eq('arrays work') get '/', splines: [{ x: 2, ints: [] }, { x: 3, ints: [4], obj: { y: 'quack' } }] expect(last_response.status).to eq(200) expect(last_response.body).to eq('arrays work') get '/', splines: '{"x":4,"ints":[2]}' expect(last_response.status).to eq(400) expect(last_response.body).to eq('splines[x] does not have a valid value') get '/', splines: { x: 4, ints: [2] } expect(last_response.status).to eq(400) expect(last_response.body).to eq('splines[x] does not have a valid value') get '/', splines: '[{"x":1,"ints":[]},{"x":4,"ints":[]}]' expect(last_response.status).to eq(400) expect(last_response.body).to eq('splines[x] does not have a valid value') get '/', splines: [{ x: 1, ints: [] }, { x: 4, ints: [] }] expect(last_response.status).to eq(400) expect(last_response.body).to eq('splines[x] does not have a valid value') end it 'works when declared optional' do subject.params do optional :splines, type: JSON do requires :x, type: Integer, values: [1, 2, 3] optional :ints, type: Array[Integer] optional :obj, type: Hash do optional :y end end end subject.get '/' do if params[:splines].is_a? Hash params[:splines][:obj][:y] elsif params[:splines].any? { |s| s.key? :obj } 'arrays work' end end get '/', splines: '{"x":1,"ints":[1,2,3],"obj":{"y":"woof"}}' expect(last_response.status).to eq(200) expect(last_response.body).to eq('woof') get '/', splines: '[{"x":2,"ints":[]},{"x":3,"ints":[4],"obj":{"y":"quack"}}]' expect(last_response.status).to eq(200) expect(last_response.body).to eq('arrays work') get '/', splines: '{"x":4,"ints":[2]}' expect(last_response.status).to eq(400) expect(last_response.body).to eq('splines[x] does not have a valid value') get '/', splines: '[{"x":1,"ints":[]},{"x":4,"ints":[]}]' expect(last_response.status).to eq(400) expect(last_response.body).to eq('splines[x] does not have a valid value') end it 'accepts Array[JSON] shorthand' do subject.params do requires :splines, type: Array[JSON] do requires :x, type: Integer, values: [1, 2, 3] requires :y end end subject.get '/' do params[:splines].first[:y].class.to_s spline = params[:splines].first "#{spline[:x].class}.#{spline[:y].class}" end get '/', splines: '{"x":"1","y":"woof"}' expect(last_response.status).to eq(200) expect(last_response.body).to eq("#{integer_class_name}.String") get '/', splines: '[{"x":1,"y":2},{"x":1,"y":"quack"}]' expect(last_response.status).to eq(200) expect(last_response.body).to eq("#{integer_class_name}.#{integer_class_name}") get '/', splines: '{"x":"4","y":"woof"}' expect(last_response.status).to eq(400) expect(last_response.body).to eq('splines[x] does not have a valid value') get '/', splines: '[{"x":"4","y":"woof"}]' expect(last_response.status).to eq(400) expect(last_response.body).to eq('splines[x] does not have a valid value') end it "doesn't make sense using coerce_with" do expect do subject.params do requires :bad, type: JSON, coerce_with: JSON do requires :x end end end.to raise_error(ArgumentError) expect do subject.params do requires :bad, type: Array[JSON], coerce_with: JSON do requires :x end end end.to raise_error(ArgumentError) end end context 'multiple types' do Boolean = Grape::API::Boolean it 'coerces to first possible type' do subject.params do requires :a, types: [Boolean, Integer, String] end subject.get '/' do params[:a].class.to_s end get '/', a: 'true' expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') get '/', a: '5' expect(last_response.status).to eq(200) expect(last_response.body).to eq(integer_class_name) get '/', a: 'anything else' expect(last_response.status).to eq(200) expect(last_response.body).to eq('String') end it 'fails when no coercion is possible' do subject.params do requires :a, types: [Boolean, Integer] end subject.get '/' do params[:a].class.to_s end get '/', a: true expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') get '/', a: 'not good' expect(last_response.status).to eq(400) expect(last_response.body).to eq('a is invalid') end context 'for primitive collections' do before do subject.params do optional :a, types: [String, Array[String]] optional :b, types: [Array[Integer], Array[String]] optional :c, type: Array[Integer, String] optional :d, types: [Integer, String, Set[Integer, String]] end subject.get '/' do ( params[:a] || params[:b] || params[:c] || params[:d] ).inspect end end it 'allows singular form declaration' do get '/', a: 'one way' expect(last_response.status).to eq(200) expect(last_response.body).to eq('"one way"') get '/', a: %w[the other] expect(last_response.status).to eq(200) expect(last_response.body).to eq('["the", "other"]') get '/', a: { a: 1, b: 2 } expect(last_response.status).to eq(400) expect(last_response.body).to eq('a is invalid') get '/', a: [1, 2, 3] expect(last_response.status).to eq(200) expect(last_response.body).to eq('["1", "2", "3"]') end it 'allows multiple collection types' do get '/', b: [1, 2, 3] expect(last_response.status).to eq(200) expect(last_response.body).to eq('[1, 2, 3]') get '/', b: %w[1 2 3] expect(last_response.status).to eq(200) expect(last_response.body).to eq('[1, 2, 3]') get '/', b: [1, true, 'three'] expect(last_response.status).to eq(200) expect(last_response.body).to eq('["1", "true", "three"]') end it 'allows collections with multiple types' do get '/', c: [1, '2', true, 'three'] expect(last_response.status).to eq(200) expect(last_response.body).to eq('[1, 2, "true", "three"]') get '/', d: '1' expect(last_response.status).to eq(200) expect(last_response.body).to eq('1') get '/', d: 'one' expect(last_response.status).to eq(200) expect(last_response.body).to eq('"one"') get '/', d: %w[1 two] expect(last_response.status).to eq(200) expect(last_response.body).to eq('#') end end context 'when params is Hashie::Mash' do context 'for primitive collections' do before do subject.params do build_with Grape::Extensions::Hashie::Mash::ParamBuilder optional :a, types: [String, Array[String]] optional :b, types: [Array[Integer], Array[String]] optional :c, type: Array[Integer, String] optional :d, types: [Integer, String, Set[Integer, String]] end subject.get '/' do ( params.a || params.b || params.c || params.d ).inspect end end it 'allows singular form declaration' do get '/', a: 'one way' expect(last_response.status).to eq(200) expect(last_response.body).to eq('"one way"') get '/', a: %w[the other] expect(last_response.status).to eq(200) expect(last_response.body).to eq('#') get '/', a: { a: 1, b: 2 } expect(last_response.status).to eq(400) expect(last_response.body).to eq('a is invalid') get '/', a: [1, 2, 3] expect(last_response.status).to eq(200) expect(last_response.body).to eq('#') end it 'allows multiple collection types' do get '/', b: [1, 2, 3] expect(last_response.status).to eq(200) expect(last_response.body).to eq('#') get '/', b: %w[1 2 3] expect(last_response.status).to eq(200) expect(last_response.body).to eq('#') get '/', b: [1, true, 'three'] expect(last_response.status).to eq(200) expect(last_response.body).to eq('#') end it 'allows collections with multiple types' do get '/', c: [1, '2', true, 'three'] expect(last_response.status).to eq(200) expect(last_response.body).to eq('#') get '/', d: '1' expect(last_response.status).to eq(200) expect(last_response.body).to eq('1') get '/', d: 'one' expect(last_response.status).to eq(200) expect(last_response.body).to eq('"one"') get '/', d: %w[1 two] expect(last_response.status).to eq(200) expect(last_response.body).to eq('#') end end end context 'custom coercion rules' do before do subject.params do requires :a, types: [Boolean, String], coerce_with: (lambda do |val| if val == 'yup' true elsif val == 'false' 0 else val end end) end subject.get '/' do params[:a].class.to_s end end it 'respects :coerce_with' do get '/', a: 'yup' expect(last_response.status).to eq(200) expect(last_response.body).to eq('TrueClass') end it 'still validates type' do get '/', a: 'false' expect(last_response.status).to eq(400) expect(last_response.body).to eq('a is invalid') end it 'performs no additional coercion' do get '/', a: 'true' expect(last_response.status).to eq(200) expect(last_response.body).to eq('String') end end it 'may not be supplied together with a single type' do expect do subject.params do requires :a, type: Integer, types: [Integer, String] end end.to raise_exception ArgumentError end end context 'converter' do it 'does not build Virtus::Attribute multiple times' do subject.params do requires :something, type: Array[String] end subject.get do end expect(Virtus::Attribute).to receive(:build).at_most(2).times.and_call_original 10.times { get '/' } end end end end grape-1.0.2/spec/grape/validations/validators/except_values_spec.rb0000644000004100000410000001762213231337007025572 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::ExceptValuesValidator do module ValidationsSpec class ExceptValuesModel DEFAULT_EXCEPTS = ['invalid-type1', 'invalid-type2', 'invalid-type3'].freeze class << self attr_accessor :excepts def excepts @excepts ||= [] [DEFAULT_EXCEPTS + @excepts].flatten.uniq end end end TEST_CASES = { req_except: { requires: { except_values: ExceptValuesModel.excepts }, tests: [ { value: 'invalid-type1', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 'invalid-type3', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 'valid-type', rc: 200, body: { type: 'valid-type' }.to_json } ] }, req_except_hash: { requires: { except_values: { value: ExceptValuesModel.excepts } }, tests: [ { value: 'invalid-type1', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 'invalid-type3', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 'valid-type', rc: 200, body: { type: 'valid-type' }.to_json } ] }, req_except_custom_message: { requires: { except_values: { value: ExceptValuesModel.excepts, message: 'is not allowed' } }, tests: [ { value: 'invalid-type1', rc: 400, body: { error: 'type is not allowed' }.to_json }, { value: 'invalid-type3', rc: 400, body: { error: 'type is not allowed' }.to_json }, { value: 'valid-type', rc: 200, body: { type: 'valid-type' }.to_json } ] }, req_except_no_value: { requires: { except_values: { message: 'is not allowed' } }, tests: [ { value: 'invalid-type1', rc: 200, body: { type: 'invalid-type1' }.to_json } ] }, req_except_empty: { requires: { except_values: [] }, tests: [ { value: 'invalid-type1', rc: 200, body: { type: 'invalid-type1' }.to_json } ] }, req_except_lambda: { requires: { except_values: -> { ExceptValuesModel.excepts } }, add_excepts: ['invalid-type4'], tests: [ { value: 'invalid-type1', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 'invalid-type4', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 'valid-type', rc: 200, body: { type: 'valid-type' }.to_json } ] }, req_except_lambda_custom_message: { requires: { except_values: { value: -> { ExceptValuesModel.excepts }, message: 'is not allowed' } }, add_excepts: ['invalid-type4'], tests: [ { value: 'invalid-type1', rc: 400, body: { error: 'type is not allowed' }.to_json }, { value: 'invalid-type4', rc: 400, body: { error: 'type is not allowed' }.to_json }, { value: 'valid-type', rc: 200, body: { type: 'valid-type' }.to_json } ] }, opt_except_default: { optional: { except_values: ExceptValuesModel.excepts, default: 'valid-type2' }, tests: [ { value: 'invalid-type1', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 'invalid-type3', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 'valid-type', rc: 200, body: { type: 'valid-type' }.to_json }, { rc: 200, body: { type: 'valid-type2' }.to_json } ] }, opt_except_lambda_default: { optional: { except_values: -> { ExceptValuesModel.excepts }, default: 'valid-type2' }, tests: [ { value: 'invalid-type1', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 'invalid-type3', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 'valid-type', rc: 200, body: { type: 'valid-type' }.to_json }, { rc: 200, body: { type: 'valid-type2' }.to_json } ] }, req_except_type_coerce: { requires: { type: Integer, except_values: [10, 11] }, tests: [ { value: 'invalid-type1', rc: 400, body: { error: 'type is invalid' }.to_json }, { value: 11, rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: '11', rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: '3', rc: 200, body: { type: 3 }.to_json }, { value: 3, rc: 200, body: { type: 3 }.to_json } ] }, opt_except_type_coerce_default: { optional: { type: Integer, except_values: [10, 11], default: 12 }, tests: [ { value: 'invalid-type1', rc: 400, body: { error: 'type is invalid' }.to_json }, { value: 10, rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: '3', rc: 200, body: { type: 3 }.to_json }, { value: 3, rc: 200, body: { type: 3 }.to_json }, { rc: 200, body: { type: 12 }.to_json } ] }, opt_except_array_type_coerce_default: { optional: { type: Array[Integer], except_values: [10, 11], default: 12 }, tests: [ { value: 'invalid-type1', rc: 400, body: { error: 'type is invalid' }.to_json }, { value: 10, rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: [10], rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: ['3'], rc: 200, body: { type: [3] }.to_json }, { value: [3], rc: 200, body: { type: [3] }.to_json }, { rc: 200, body: { type: 12 }.to_json } ] }, req_except_range: { optional: { type: Integer, except_values: 10..12 }, tests: [ { value: 11, rc: 400, body: { error: 'type has a value not allowed' }.to_json }, { value: 13, rc: 200, body: { type: 13 }.to_json } ] } }.freeze module ExceptValidatorSpec class API < Grape::API default_format :json TEST_CASES.each_with_index do |(k, v), _i| params do requires :type, v[:requires] if v.key? :requires optional :type, v[:optional] if v.key? :optional end get k do { type: params[:type] } end end end end end it 'raises IncompatibleOptionValues on a default value in exclude' do subject = Class.new(Grape::API) expect do subject.params do optional :type, except_values: ValidationsSpec::ExceptValuesModel.excepts, default: ValidationsSpec::ExceptValuesModel.excepts.sample end end.to raise_error Grape::Exceptions::IncompatibleOptionValues end it 'raises IncompatibleOptionValues when a default array has excluded values' do subject = Class.new(Grape::API) expect do subject.params do optional :type, type: Array[Integer], except_values: 10..12, default: [8, 9, 10] end end.to raise_error Grape::Exceptions::IncompatibleOptionValues end it 'raises IncompatibleOptionValues when type is incompatible with values array' do subject = Class.new(Grape::API) expect do subject.params { optional :type, except_values: ['valid-type1', 'valid-type2', 'valid-type3'], type: Symbol } end.to raise_error Grape::Exceptions::IncompatibleOptionValues end def app ValidationsSpec::ExceptValidatorSpec::API end ValidationsSpec::TEST_CASES.each_with_index do |(k, v), i| v[:tests].each do |t| it "#{i}: #{k} - #{t[:value]}" do ValidationsSpec::ExceptValuesModel.excepts = v[:add_excepts] if v.key? :add_excepts body = {} body[:type] = t[:value] if t.key? :value get k.to_s, **body expect(last_response.status).to eq t[:rc] expect(last_response.body).to eq t[:body] ValidationsSpec::ExceptValuesModel.excepts = nil end end end end grape-1.0.2/spec/grape/validations/validators/default_spec.rb0000644000004100000410000002421613231337007024344 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::DefaultValidator do module ValidationsSpec module DefaultValidatorSpec class API < Grape::API default_format :json params do optional :id optional :type, default: 'default-type' end get '/' do { id: params[:id], type: params[:type] } end params do optional :type1, default: 'default-type1' optional :type2, default: 'default-type2' end get '/user' do { type1: params[:type1], type2: params[:type2] } end params do requires :id optional :type1, default: 'default-type1' optional :type2, default: 'default-type2' end get '/message' do { id: params[:id], type1: params[:type1], type2: params[:type2] } end params do optional :random, default: -> { Random.rand } optional :not_random, default: Random.rand end get '/numbers' do { random_number: params[:random], non_random_number: params[:non_random_number] } end params do optional :array, type: Array do requires :name optional :with_default, default: 'default' end end get '/array' do { array: params[:array] } end params do requires :thing1 optional :more_things, type: Array do requires :nested_thing requires :other_thing, default: 1 end end get '/optional_array' do { thing1: params[:thing1] } end params do requires :root, type: Hash do optional :some_things, type: Array do requires :foo optional :options, type: Array do requires :name, type: String requires :value, type: String end end end end get '/nested_optional_array' do { root: params[:root] } end params do requires :root, type: Hash do optional :some_things, type: Array do requires :foo optional :options, type: Array do optional :name, type: String optional :value, type: String end end end end get '/another_nested_optional_array' do { root: params[:root] } end end end end def app ValidationsSpec::DefaultValidatorSpec::API end it 'lets you leave required values nested inside an optional blank' do get '/optional_array', thing1: 'stuff' expect(last_response.status).to eq(200) expect(last_response.body).to eq({ thing1: 'stuff' }.to_json) end it 'allows optional arrays to be omitted' do params = { some_things: [{ foo: 'one', options: [{ name: 'wat', value: 'nope' }] }, { foo: 'two' }, { foo: 'three', options: [{ name: 'wooop', value: 'yap' }] }] } get '/nested_optional_array', root: params expect(last_response.status).to eq(200) expect(last_response.body).to eq({ root: params }.to_json) end it 'does not allows faulty optional arrays' do params = { some_things: [ { foo: 'one', options: [{ name: 'wat', value: 'nope' }] }, { foo: 'two', options: [{ name: 'wat' }] }, { foo: 'three' } ] } error = { error: 'root[some_things][1][options][0][value] is missing' } get '/nested_optional_array', root: params expect(last_response.status).to eq(400) expect(last_response.body).to eq(error.to_json) end it 'allows optional arrays with optional params' do params = { some_things: [ { foo: 'one', options: [{ value: 'nope' }] }, { foo: 'two', options: [{ name: 'wat' }] }, { foo: 'three' } ] } get '/another_nested_optional_array', root: params expect(last_response.status).to eq(200) expect(last_response.body).to eq({ root: params }.to_json) end it 'set default value for optional param' do get('/') expect(last_response.status).to eq(200) expect(last_response.body).to eq({ id: nil, type: 'default-type' }.to_json) end it 'set default values for optional params' do get('/user') expect(last_response.status).to eq(200) expect(last_response.body).to eq({ type1: 'default-type1', type2: 'default-type2' }.to_json) end it 'set default values for missing params in the request' do get('/user?type2=value2') expect(last_response.status).to eq(200) expect(last_response.body).to eq({ type1: 'default-type1', type2: 'value2' }.to_json) end it 'set default values for optional params and allow to use required fields in the same time' do get('/message?id=1') expect(last_response.status).to eq(200) expect(last_response.body).to eq({ id: '1', type1: 'default-type1', type2: 'default-type2' }.to_json) end it 'sets lambda based defaults at the time of call' do get('/numbers') expect(last_response.status).to eq(200) before = JSON.parse(last_response.body) get('/numbers') expect(last_response.status).to eq(200) after = JSON.parse(last_response.body) expect(before['non_random_number']).to eq(after['non_random_number']) expect(before['random_number']).not_to eq(after['random_number']) end it 'sets default values for grouped arrays' do get('/array?array[][name]=name&array[][name]=name2&array[][with_default]=bar2') expect(last_response.status).to eq(200) expect(last_response.body).to eq({ array: [{ name: 'name', with_default: 'default' }, { name: 'name2', with_default: 'bar2' }] }.to_json) end context 'optional group with defaults' do subject do Class.new(Grape::API) do default_format :json end end def app subject end context 'optional array without default value includes optional param with default value' do before do subject.params do optional :optional_array, type: Array do optional :foo_in_optional_array, default: 'bar' end end subject.post '/optional_array' do { optional_array: params[:optional_array] } end end it 'returns nil for optional array if param is not provided' do post '/optional_array' expect(last_response.status).to eq(201) expect(last_response.body).to eq({ optional_array: nil }.to_json) end end context 'optional array with default value includes optional param with default value' do before do subject.params do optional :optional_array_with_default, type: Array, default: [] do optional :foo_in_optional_array, default: 'bar' end end subject.post '/optional_array_with_default' do { optional_array_with_default: params[:optional_array_with_default] } end end it 'sets default value for optional array if param is not provided' do post '/optional_array_with_default' expect(last_response.status).to eq(201) expect(last_response.body).to eq({ optional_array_with_default: [] }.to_json) end end context 'optional hash without default value includes optional param with default value' do before do subject.params do optional :optional_hash_without_default, type: Hash do optional :foo_in_optional_hash, default: 'bar' end end subject.post '/optional_hash_without_default' do { optional_hash_without_default: params[:optional_hash_without_default] } end end it 'returns nil for optional hash if param is not provided' do post '/optional_hash_without_default' expect(last_response.status).to eq(201) expect(last_response.body).to eq({ optional_hash_without_default: nil }.to_json) end it 'does not fail even if invalid params is passed to default validator' do expect { post '/optional_hash_without_default', optional_hash_without_default: '5678' }.not_to raise_error expect(last_response.status).to eq(400) expect(last_response.body).to eq({ error: 'optional_hash_without_default is invalid' }.to_json) end end context 'optional hash with default value includes optional param with default value' do before do subject.params do optional :optional_hash_with_default, type: Hash, default: {} do optional :foo_in_optional_hash, default: 'bar' end end subject.post '/optional_hash_with_default_empty_hash' do { optional_hash_with_default: params[:optional_hash_with_default] } end subject.params do optional :optional_hash_with_default, type: Hash, default: { foo_in_optional_hash: 'parent_default' } do optional :some_param optional :foo_in_optional_hash, default: 'own_default' end end subject.post '/optional_hash_with_default_inner_params' do { foo_in_optional_hash: params[:optional_hash_with_default][:foo_in_optional_hash] } end end it 'sets default value for optional hash if param is not provided' do post '/optional_hash_with_default_empty_hash' expect(last_response.status).to eq(201) expect(last_response.body).to eq({ optional_hash_with_default: {} }.to_json) end it 'sets default value from parent defaults for inner param if parent param is not provided' do post '/optional_hash_with_default_inner_params' expect(last_response.status).to eq(201) expect(last_response.body).to eq({ foo_in_optional_hash: 'parent_default' }.to_json) end it 'sets own default value for inner param if parent param is provided' do post '/optional_hash_with_default_inner_params', optional_hash_with_default: { some_param: 'param' } expect(last_response.status).to eq(201) expect(last_response.body).to eq({ foo_in_optional_hash: 'own_default' }.to_json) end end end end grape-1.0.2/spec/grape/validations/validators/at_least_one_of_spec.rb0000644000004100000410000000366513231337007026046 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::AtLeastOneOfValidator do describe '#validate!' do let(:scope) do Struct.new(:opts) do def params(arg) arg end def required?; end end end let(:at_least_one_of_params) { %i[beer wine grapefruit] } let(:validator) { described_class.new(at_least_one_of_params, {}, false, scope.new) } context 'when all restricted params are present' do let(:params) { { beer: true, wine: true, grapefruit: true } } it 'does not raise a validation exception' do expect(validator.validate!(params)).to eql params end context 'mixed with other params' do let(:mixed_params) { params.merge!(other: true, andanother: true) } it 'does not raise a validation exception' do expect(validator.validate!(mixed_params)).to eql mixed_params end end end context 'when a subset of restricted params are present' do let(:params) { { beer: true, grapefruit: true } } it 'does not raise a validation exception' do expect(validator.validate!(params)).to eql params end end context 'when params keys come as strings' do let(:params) { { 'beer' => true, 'grapefruit' => true } } it 'does not raise a validation exception' do expect(validator.validate!(params)).to eql params end end context 'when none of the restricted params is selected' do let(:params) { { somethingelse: true } } it 'raises a validation exception' do expect do validator.validate! params end.to raise_error(Grape::Exceptions::Validation) end end context 'when exactly one of the restricted params is selected' do let(:params) { { beer: true, somethingelse: true } } it 'does not raise a validation exception' do expect(validator.validate!(params)).to eql params end end end end grape-1.0.2/spec/grape/validations/validators/zh-CN.yml0000644000004100000410000000033613231337007023020 0ustar www-datawww-datazh-CN: grape: errors: format: ! '%{attributes}%{message}' attributes: age: 年龄 messages: coerce: 'æ ¼å¼ä¸æ­£ç¡®' presence: '请填写' regexp: 'æ ¼å¼ä¸æ­£ç¡®' grape-1.0.2/spec/grape/validations/validators/presence_spec.rb0000644000004100000410000002061713231337007024525 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::PresenceValidator do subject do Class.new(Grape::API) do format :json end end def app subject end context 'without validation' do before do subject.resource :bacons do get do 'All the bacon' end end end it 'does not validate for any params' do get '/bacons' expect(last_response.status).to eq(200) expect(last_response.body).to eq('All the bacon'.to_json) end end context 'with a custom validation message' do before do subject.resource :requires do params do requires :email, type: String, allow_blank: { value: false, message: 'has no value' }, regexp: { value: /^\S+$/, message: 'format is invalid' }, message: 'is required' end get do 'Hello' end end end it 'requires when missing' do get '/requires' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"email is required, email has no value"}') end it 'requires when empty' do get '/requires', email: '' expect(last_response.body).to eq('{"error":"email has no value, email format is invalid"}') end it 'valid when set' do get '/requires', email: 'bob@example.com' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hello'.to_json) end end context 'with a required regexp parameter supplied in the POST body' do before do subject.format :json subject.params do requires :id, regexp: /^[0-9]+$/ end subject.post do { ret: params[:id] } end end it 'validates id' do post '/' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"id is missing"}') io = StringIO.new('{"id" : "a56b"}') post '/', {}, 'rack.input' => io, 'CONTENT_TYPE' => 'application/json', 'CONTENT_LENGTH' => io.length expect(last_response.body).to eq('{"error":"id is invalid"}') expect(last_response.status).to eq(400) io = StringIO.new('{"id" : 56}') post '/', {}, 'rack.input' => io, 'CONTENT_TYPE' => 'application/json', 'CONTENT_LENGTH' => io.length expect(last_response.body).to eq('{"ret":56}') expect(last_response.status).to eq(201) end end context 'with a required non-empty string' do before do subject.params do requires :email, type: String, allow_blank: false, regexp: /^\S+$/ end subject.get do 'Hello' end end it 'requires when missing' do get '/' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"email is missing, email is empty"}') end it 'requires when empty' do get '/', email: '' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"email is empty, email is invalid"}') end it 'valid when set' do get '/', email: 'bob@example.com' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hello'.to_json) end end context 'with multiple parameters per requires' do before do subject.params do requires :one, :two end subject.get '/single-requires' do 'Hello' end subject.params do requires :one requires :two end subject.get '/multiple-requires' do 'Hello' end end it 'validates for all defined params' do get '/single-requires' expect(last_response.status).to eq(400) single_requires_error = last_response.body get '/multiple-requires' expect(last_response.status).to eq(400) expect(last_response.body).to eq(single_requires_error) end end context 'with required parameters and no type' do before do subject.params do requires :name, :company end subject.get do 'Hello' end end it 'validates name, company' do get '/' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"name is missing, company is missing"}') get '/', name: 'Bob' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"company is missing"}') get '/', name: 'Bob', company: 'TestCorp' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hello'.to_json) end end context 'with nested parameters' do before do subject.params do requires :user, type: Hash do requires :first_name requires :last_name end end subject.get '/nested' do 'Nested' end end it 'validates nested parameters' do get '/nested' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"user is missing, user[first_name] is missing, user[last_name] is missing"}') get '/nested', user: { first_name: 'Billy' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"user[last_name] is missing"}') get '/nested', user: { first_name: 'Billy', last_name: 'Bob' } expect(last_response.status).to eq(200) expect(last_response.body).to eq('Nested'.to_json) end end context 'with triply nested required parameters' do before do subject.params do requires :admin, type: Hash do requires :admin_name requires :super, type: Hash do requires :user, type: Hash do requires :first_name requires :last_name end end end end subject.get '/nested_triple' do 'Nested triple' end end it 'validates triple nested parameters' do get '/nested_triple' expect(last_response.status).to eq(400) expect(last_response.body).to include '{"error":"admin is missing' get '/nested_triple', user: { first_name: 'Billy' } expect(last_response.status).to eq(400) expect(last_response.body).to include '{"error":"admin is missing' get '/nested_triple', admin: { super: { first_name: 'Billy' } } expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"admin[admin_name] is missing, admin[super][user] is missing, admin[super][user][first_name] is missing, admin[super][user][last_name] is missing"}') get '/nested_triple', super: { user: { first_name: 'Billy', last_name: 'Bob' } } expect(last_response.status).to eq(400) expect(last_response.body).to include '{"error":"admin is missing' get '/nested_triple', admin: { super: { user: { first_name: 'Billy' } } } expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"admin[admin_name] is missing, admin[super][user][last_name] is missing"}') get '/nested_triple', admin: { admin_name: 'admin', super: { user: { first_name: 'Billy' } } } expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"admin[super][user][last_name] is missing"}') get '/nested_triple', admin: { admin_name: 'admin', super: { user: { first_name: 'Billy', last_name: 'Bob' } } } expect(last_response.status).to eq(200) expect(last_response.body).to eq('Nested triple'.to_json) end end context 'with reused parameter documentation once required and once optional' do before do docs = { name: { type: String, desc: 'some name' } } subject.params do requires :all, using: docs end subject.get '/required' do 'Hello required' end subject.params do optional :all, using: docs end subject.get '/optional' do 'Hello optional' end end it 'works with required' do get '/required' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"name is missing"}') get '/required', name: 'Bob' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hello required'.to_json) end it 'works with optional' do get '/optional' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hello optional'.to_json) get '/optional', name: 'Bob' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hello optional'.to_json) end end end grape-1.0.2/spec/grape/validations/validators/values_spec.rb0000644000004100000410000005240713231337007024222 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::ValuesValidator do module ValidationsSpec class ValuesModel DEFAULT_VALUES = ['valid-type1', 'valid-type2', 'valid-type3'].freeze DEFAULT_EXCEPTS = ['invalid-type1', 'invalid-type2', 'invalid-type3'].freeze class << self def values @values ||= [] [DEFAULT_VALUES + @values].flatten.uniq end def add_value(value) @values ||= [] @values << value end def excepts @excepts ||= [] [DEFAULT_EXCEPTS + @excepts].flatten.uniq end def add_except(except) @excepts ||= [] @excepts << except end end end module ValuesValidatorSpec class API < Grape::API default_format :json resources :custom_message do params do requires :type, values: { value: ValuesModel.values, message: 'value does not include in values' } end get '/' do { type: params[:type] } end params do optional :type, values: { value: -> { ValuesModel.values }, message: 'value does not include in values' }, default: 'valid-type2' end get '/lambda' do { type: params[:type] } end params do requires :type, values: { except: ValuesModel.excepts, except_message: 'value is on exclusions list', message: 'default exclude message' } end get '/exclude/exclude_message' params do requires :type, values: { except: -> { ValuesModel.excepts }, except_message: 'value is on exclusions list' } end get '/exclude/lambda/exclude_message' params do requires :type, values: { except: ValuesModel.excepts, message: 'default exclude message' } end get '/exclude/fallback_message' end params do requires :type, values: ValuesModel.values end get '/' do { type: params[:type] } end params do requires :type, values: [] end get '/empty' params do optional :type, values: { value: ValuesModel.values }, default: 'valid-type2' end get '/default/hash/valid' do { type: params[:type] } end params do optional :type, values: ValuesModel.values, default: 'valid-type2' end get '/default/valid' do { type: params[:type] } end params do optional :type, values: { except: ValuesModel.excepts }, default: 'valid-type2' end get '/default/except' do { type: params[:type] } end params do optional :type, values: -> { ValuesModel.values }, default: 'valid-type2' end get '/lambda' do { type: params[:type] } end params do requires :type, values: ->(v) { ValuesModel.values.include? v } end get '/lambda_val' do { type: params[:type] } end params do requires :number, type: Integer, values: ->(v) { v > 0 } end get '/lambda_int_val' do { number: params[:number] } end params do requires :type, values: -> { [] } end get '/empty_lambda' params do optional :type, values: ValuesModel.values, default: -> { ValuesModel.values.sample } end get '/default_lambda' do { type: params[:type] } end params do optional :type, values: -> { ValuesModel.values }, default: -> { ValuesModel.values.sample } end get '/default_and_values_lambda' do { type: params[:type] } end params do optional :type, type: Boolean, desc: 'A boolean', values: [true] end get '/values/optional_boolean' do { type: params[:type] } end params do requires :type, type: Integer, desc: 'An integer', values: [10, 11], default: 10 end get '/values/coercion' do { type: params[:type] } end params do requires :type, type: Array[Integer], desc: 'An integer', values: [10, 11], default: 10 end get '/values/array_coercion' do { type: params[:type] } end params do optional :optional, type: Array do requires :type, values: %w[a b] end end get '/optional_with_required_values' params do requires :type, values: { except: ValuesModel.excepts } end get '/except/exclusive' do { type: params[:type] } end params do requires :type, type: String, values: { except: ValuesModel.excepts } end get '/except/exclusive/type' do { type: params[:type] } end params do requires :type, values: { except: -> { ValuesModel.excepts } } end get '/except/exclusive/lambda' do { type: params[:type] } end params do requires :type, type: String, values: { except: -> { ValuesModel.excepts } } end get '/except/exclusive/lambda/type' do { type: params[:type] } end params do requires :type, type: Integer, values: { except: -> { [3, 4, 5] } } end get '/except/exclusive/lambda/coercion' do { type: params[:type] } end params do requires :type, type: Integer, values: { value: 1..5, except: [3] } end get '/mixed/value/except' do { type: params[:type] } end params do optional :optional, type: Array[String], values: %w[a b c] end put '/optional_with_array_of_string_values' params do requires :type, values: { proc: ->(v) { ValuesModel.values.include? v } } end get '/proc' do { type: params[:type] } end params do requires :type, values: { proc: ->(v) { ValuesModel.values.include? v }, message: 'failed check' } end get '/proc/message' end end end def app ValidationsSpec::ValuesValidatorSpec::API end context 'with a custom validation message' do it 'allows a valid value for a parameter' do get('/custom_message', type: 'valid-type1') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type1' }.to_json) end it 'does not allow an invalid value for a parameter' do get('/custom_message', type: 'invalid-type') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type value does not include in values' }.to_json) end it 'validates against values in a proc' do ValidationsSpec::ValuesModel.add_value('valid-type4') get('/custom_message/lambda', type: 'valid-type4') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type4' }.to_json) end it 'does not allow an invalid value for a parameter using lambda' do get('/custom_message/lambda', type: 'invalid-type') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type value does not include in values' }.to_json) end end context 'with a custom exclude validation message' do it 'does not allow an invalid value for a parameter' do get('/custom_message/exclude/exclude_message', type: 'invalid-type1') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type value is on exclusions list' }.to_json) end end context 'with a custom exclude validation message' do it 'does not allow an invalid value for a parameter' do get('/custom_message/exclude/lambda/exclude_message', type: 'invalid-type1') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type value is on exclusions list' }.to_json) end end context 'exclude with a standard custom validation message' do it 'does not allow an invalid value for a parameter' do get('/custom_message/exclude/fallback_message', type: 'invalid-type1') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type default exclude message' }.to_json) end end it 'allows a valid value for a parameter' do get('/', type: 'valid-type1') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type1' }.to_json) end it 'does not allow an invalid value for a parameter' do get('/', type: 'invalid-type') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end it 'rejects all values if values is an empty array' do get('/empty', type: 'invalid-type') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end context 'nil value for a parameter' do it 'does not allow for root params scope' do get('/', type: nil) expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end it 'allows for a required param in child scope' do get('/optional_with_required_values') expect(last_response.status).to eq 200 end it 'allows for an optional param with a list of values' do put('/optional_with_array_of_string_values', optional: nil) expect(last_response.status).to eq 200 end end it 'allows a valid default value' do get('/default/valid') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type2' }.to_json) end it 'allows a default value with except' do get('/default/except') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type2' }.to_json) end it 'allows a valid default value' do get('/default/hash/valid') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type2' }.to_json) end it 'allows a proc for values' do get('/lambda', type: 'valid-type1') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type1' }.to_json) end it 'does not validate updated values without proc' do ValidationsSpec::ValuesModel.add_value('valid-type4') get('/', type: 'valid-type4') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end it 'validates against values in a proc' do ValidationsSpec::ValuesModel.add_value('valid-type4') get('/lambda', type: 'valid-type4') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type4' }.to_json) end it 'does not allow an invalid value for a parameter using lambda' do get('/lambda', type: 'invalid-type') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end it 'does not allow non-numeric string value for int value using lambda' do get('/lambda_int_val', number: 'foo') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'number is invalid, number does not have a valid value' }.to_json) end it 'does not allow nil for int value using lambda' do get('/lambda_int_val', number: nil) expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'number does not have a valid value' }.to_json) end it 'allows numeric string for int value using lambda' do get('/lambda_int_val', number: '3') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ number: 3 }.to_json) end it 'allows value using lambda' do get('/lambda_val', type: 'valid-type1') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type1' }.to_json) end it 'does not allow invalid value using lambda' do get('/lambda_val', type: 'invalid-type') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end it 'validates against an empty array in a proc' do get('/empty_lambda', type: 'any') expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end it 'validates default value from proc' do get('/default_lambda') expect(last_response.status).to eq 200 end it 'validates default value from proc against values in a proc' do get('/default_and_values_lambda') expect(last_response.status).to eq 200 end it 'raises IncompatibleOptionValues on an invalid default value from proc' do subject = Class.new(Grape::API) expect do subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], default: ValidationsSpec::ValuesModel.values.sample + '_invalid' } end.to raise_error Grape::Exceptions::IncompatibleOptionValues end it 'raises IncompatibleOptionValues on an invalid default value' do subject = Class.new(Grape::API) expect do subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], default: 'invalid-type' } end.to raise_error Grape::Exceptions::IncompatibleOptionValues end it 'raises IncompatibleOptionValues when type is incompatible with values array' do subject = Class.new(Grape::API) expect do subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], type: Symbol } end.to raise_error Grape::Exceptions::IncompatibleOptionValues end it 'allows values to be true or false when setting the type to boolean' do get('/values/optional_boolean', type: true) expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: true }.to_json) end it 'allows values to be a kind of the coerced type not just an instance of it' do get('/values/coercion', type: 10) expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 10 }.to_json) end it 'allows values to be a kind of the coerced type in an array' do get('/values/array_coercion', type: [10]) expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: [10] }.to_json) end it 'raises IncompatibleOptionValues when values contains a value that is not a kind of the type' do subject = Class.new(Grape::API) expect do subject.params { requires :type, values: [10.5, 11], type: Integer } end.to raise_error Grape::Exceptions::IncompatibleOptionValues end it 'raises IncompatibleOptionValues when except contains a value that is not a kind of the type' do subject = Class.new(Grape::API) expect do subject.params { requires :type, values: { except: [10.5, 11] }, type: Integer } end.to raise_error Grape::Exceptions::IncompatibleOptionValues end context 'with a lambda values' do subject do Class.new(Grape::API) do params do optional :type, type: String, values: -> { [SecureRandom.uuid] }, default: -> { SecureRandom.uuid } end get '/random_values' end end def app subject end before do expect(SecureRandom).to receive(:uuid).and_return('foo').once end it 'only evaluates values dynamically with each request' do get '/random_values', type: 'foo' expect(last_response.status).to eq 200 end it 'chooses default' do get '/random_values' expect(last_response.status).to eq 200 end end context 'with a range of values' do subject(:app) do Class.new(Grape::API) do params do optional :value, type: Float, values: 0.0..10.0 end get '/value' do { value: params[:value] }.to_json end params do optional :values, type: Array[Float], values: 0.0..10.0 end get '/values' do { values: params[:values] }.to_json end end end it 'allows a single value inside of the range' do get('/value', value: 5.2) expect(last_response.status).to eq 200 expect(last_response.body).to eq({ value: 5.2 }.to_json) end it 'allows an array of values inside of the range' do get('/values', values: [8.6, 7.5, 3, 0.9]) expect(last_response.status).to eq 200 expect(last_response.body).to eq({ values: [8.6, 7.5, 3.0, 0.9] }.to_json) end it 'rejects a single value outside the range' do get('/value', value: 'a') expect(last_response.status).to eq 400 expect(last_response.body).to eq('value is invalid, value does not have a valid value') end it 'rejects an array of values if any of them are outside the range' do get('/values', values: [8.6, 75, 3, 0.9]) expect(last_response.status).to eq 400 expect(last_response.body).to eq('values does not have a valid value') end end context 'exclusive excepts' do it 'allows any other value outside excepts' do get '/except/exclusive', type: 'value' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'value' }.to_json) end it 'allows any other value outside excepts when type is included' do get '/except/exclusive/type', type: 'value' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'value' }.to_json) end it 'rejects values that matches except' do get '/except/exclusive', type: 'invalid-type1' expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json) end it 'rejects an array of values if any of them matches except' do get '/except/exclusive', type: %w[valid1 valid2 invalid-type1 valid4] expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json) end end context 'exclusive excepts with lambda' do it 'allows any other value outside excepts when type is included' do get '/except/exclusive/lambda/type', type: 'value' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'value' }.to_json) end it 'allows any other value outside excepts' do get '/except/exclusive/lambda', type: 'value' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'value' }.to_json) end it 'rejects values that matches except' do get '/except/exclusive/lambda', type: 'invalid-type1' expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json) end end context 'exclusive excepts with lambda and coercion' do it 'allows any other value outside excepts' do get '/except/exclusive/lambda/coercion', type: '10010000' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 10_010_000 }.to_json) end it 'rejects values that matches except' do get '/except/exclusive/lambda/coercion', type: '3' expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json) end end context 'with mixed values and excepts' do it 'allows value, but not in except' do get '/mixed/value/except', type: 2 expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 2 }.to_json) end it 'rejects except' do get '/mixed/value/except', type: 3 expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json) end it 'rejects outside except and outside value' do get '/mixed/value/except', type: 10 expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end end context 'custom validation using proc' do it 'accepts a single valid value' do get '/proc', type: 'valid-type1' expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type1' }.to_json) end it 'accepts multiple valid values' do get '/proc', type: ['valid-type1', 'valid-type3'] expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: ['valid-type1', 'valid-type3'] }.to_json) end it 'rejects a single invalid value' do get '/proc', type: 'invalid-type1' expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end it 'rejects an invalid value among valid ones' do get '/proc', type: ['valid-type1', 'invalid-type1', 'valid-type3'] expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end it 'uses supplied message' do get '/proc/message', type: 'invalid-type1' expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type failed check' }.to_json) end end end grape-1.0.2/spec/grape/validations/validators/allow_blank_spec.rb0000644000004100000410000004377313231337007025216 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::AllowBlankValidator do module ValidationsSpec module AllowBlankValidatorSpec class API < Grape::API default_format :json params do requires :name, allow_blank: false end get '/disallow_blank' params do optional :name, type: String, allow_blank: false end get '/opt_disallow_string_blank' params do optional :name, allow_blank: false end get '/disallow_blank_optional_param' params do requires :name, allow_blank: true end get '/allow_blank' params do requires :val, type: DateTime, allow_blank: true end get '/allow_datetime_blank' params do requires :val, type: DateTime, allow_blank: false end get '/disallow_datetime_blank' params do requires :val, type: DateTime end get '/default_allow_datetime_blank' params do requires :val, type: Date, allow_blank: true end get '/allow_date_blank' params do requires :val, type: Integer, allow_blank: true end get '/allow_integer_blank' params do requires :val, type: Float, allow_blank: true end get '/allow_float_blank' params do requires :val, type: Integer, allow_blank: true end get '/allow_integer_blank' params do requires :val, type: Symbol, allow_blank: true end get '/allow_symbol_blank' params do requires :val, type: Boolean, allow_blank: true end get '/allow_boolean_blank' params do requires :val, type: Boolean, allow_blank: false end get '/disallow_boolean_blank' params do optional :user, type: Hash do requires :name, allow_blank: false end end get '/disallow_blank_required_param_in_an_optional_group' params do optional :user, type: Hash do requires :name, type: Date, allow_blank: true end end get '/allow_blank_date_param_in_an_optional_group' params do optional :user, type: Hash do optional :name, allow_blank: false requires :age end end get '/disallow_blank_optional_param_in_an_optional_group' params do requires :user, type: Hash do requires :name, allow_blank: false end end get '/disallow_blank_required_param_in_a_required_group' params do requires :user, type: Hash do requires :name, allow_blank: false end end get '/disallow_string_value_in_a_required_hash_group' params do requires :user, type: Hash do optional :name, allow_blank: false end end get '/disallow_blank_optional_param_in_a_required_group' params do optional :user, type: Hash do optional :name, allow_blank: false end end get '/disallow_string_value_in_an_optional_hash_group' resources :custom_message do params do requires :name, allow_blank: { value: false, message: 'has no value' } end get params do optional :name, allow_blank: { value: false, message: 'has no value' } end get '/disallow_blank_optional_param' params do requires :name, allow_blank: true end get '/allow_blank' params do requires :val, type: DateTime, allow_blank: true end get '/allow_datetime_blank' params do requires :val, type: DateTime, allow_blank: { value: false, message: 'has no value' } end get '/disallow_datetime_blank' params do requires :val, type: DateTime end get '/default_allow_datetime_blank' params do requires :val, type: Date, allow_blank: true end get '/allow_date_blank' params do requires :val, type: Integer, allow_blank: true end get '/allow_integer_blank' params do requires :val, type: Float, allow_blank: true end get '/allow_float_blank' params do requires :val, type: Integer, allow_blank: true end get '/allow_integer_blank' params do requires :val, type: Symbol, allow_blank: true end get '/allow_symbol_blank' params do requires :val, type: Boolean, allow_blank: true end get '/allow_boolean_blank' params do requires :val, type: Boolean, allow_blank: { value: false, message: 'has no value' } end get '/disallow_boolean_blank' params do optional :user, type: Hash do requires :name, allow_blank: { value: false, message: 'has no value' } end end get '/disallow_blank_required_param_in_an_optional_group' params do optional :user, type: Hash do requires :name, type: Date, allow_blank: true end end get '/allow_blank_date_param_in_an_optional_group' params do optional :user, type: Hash do optional :name, allow_blank: { value: false, message: 'has no value' } requires :age end end get '/disallow_blank_optional_param_in_an_optional_group' params do requires :user, type: Hash do requires :name, allow_blank: { value: false, message: 'has no value' } end end get '/disallow_blank_required_param_in_a_required_group' params do requires :user, type: Hash do requires :name, allow_blank: { value: false, message: 'has no value' } end end get '/disallow_string_value_in_a_required_hash_group' params do requires :user, type: Hash do optional :name, allow_blank: { value: false, message: 'has no value' } end end get '/disallow_blank_optional_param_in_a_required_group' params do optional :user, type: Hash do optional :name, allow_blank: { value: false, message: 'has no value' } end end get '/disallow_string_value_in_an_optional_hash_group' end end end end def app ValidationsSpec::AllowBlankValidatorSpec::API end context 'invalid input' do it 'refuses empty string' do get '/disallow_blank', name: '' expect(last_response.status).to eq(400) get '/disallow_datetime_blank', val: '' expect(last_response.status).to eq(400) end it 'refuses only whitespaces' do get '/disallow_blank', name: ' ' expect(last_response.status).to eq(400) get '/disallow_blank', name: " \n " expect(last_response.status).to eq(400) get '/disallow_blank', name: "\n" expect(last_response.status).to eq(400) end it 'refuses nil' do get '/disallow_blank', name: nil expect(last_response.status).to eq(400) end it 'refuses missing' do get '/disallow_blank' expect(last_response.status).to eq(400) end end context 'custom validation message' do context 'with invalid input' do it 'refuses empty string' do get '/custom_message', name: '' expect(last_response.body).to eq('{"error":"name has no value"}') end it 'refuses empty string for an optional param' do get '/custom_message/disallow_blank_optional_param', name: '' expect(last_response.body).to eq('{"error":"name has no value"}') end it 'refuses only whitespaces' do get '/custom_message', name: ' ' expect(last_response.body).to eq('{"error":"name has no value"}') get '/custom_message', name: " \n " expect(last_response.body).to eq('{"error":"name has no value"}') get '/custom_message', name: "\n" expect(last_response.body).to eq('{"error":"name has no value"}') end it 'refuses nil' do get '/custom_message', name: nil expect(last_response.body).to eq('{"error":"name has no value"}') end end context 'with valid input' do it 'accepts valid input' do get '/custom_message', name: 'bob' expect(last_response.status).to eq(200) end it 'accepts empty input when allow_blank is false' do get '/custom_message/allow_blank', name: '' expect(last_response.status).to eq(200) end it 'accepts empty input' do get '/custom_message/default_allow_datetime_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts empty when datetime allow_blank' do get '/custom_message/allow_datetime_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts empty when date allow_blank' do get '/custom_message/allow_date_blank', val: '' expect(last_response.status).to eq(200) end context 'allow_blank when Numeric' do it 'accepts empty when integer allow_blank' do get '/custom_message/allow_integer_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts empty when float allow_blank' do get '/custom_message/allow_float_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts empty when integer allow_blank' do get '/custom_message/allow_integer_blank', val: '' expect(last_response.status).to eq(200) end end it 'accepts empty when symbol allow_blank' do get '/custom_message/allow_symbol_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts empty when boolean allow_blank' do get '/custom_message/allow_boolean_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts false when boolean allow_blank' do get '/custom_message/disallow_boolean_blank', val: false expect(last_response.status).to eq(200) end end context 'in an optional group' do context 'as a required param' do it 'accepts a missing group, even with a disallwed blank param' do get '/custom_message/disallow_blank_required_param_in_an_optional_group' expect(last_response.status).to eq(200) end it 'accepts a nested missing date value' do get '/custom_message/allow_blank_date_param_in_an_optional_group', user: { name: '' } expect(last_response.status).to eq(200) end it 'refuses a blank value in an existing group' do get '/custom_message/disallow_blank_required_param_in_an_optional_group', user: { name: '' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"user[name] has no value"}') end end context 'as an optional param' do it 'accepts a missing group, even with a disallwed blank param' do get '/custom_message/disallow_blank_optional_param_in_an_optional_group' expect(last_response.status).to eq(200) end it 'accepts a nested missing optional value' do get '/custom_message/disallow_blank_optional_param_in_an_optional_group', user: { age: '29' } expect(last_response.status).to eq(200) end it 'refuses a blank existing value in an existing scope' do get '/custom_message/disallow_blank_optional_param_in_an_optional_group', user: { age: '29', name: '' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"user[name] has no value"}') end end end context 'in a required group' do context 'as a required param' do it 'refuses a blank value in a required existing group' do get '/custom_message/disallow_blank_required_param_in_a_required_group', user: { name: '' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"user[name] has no value"}') end it 'refuses a string value in a required hash group' do get '/custom_message/disallow_string_value_in_a_required_hash_group', user: '' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"user is invalid, user[name] is missing"}') end end context 'as an optional param' do it 'accepts a nested missing value' do get '/custom_message/disallow_blank_optional_param_in_a_required_group', user: { age: '29' } expect(last_response.status).to eq(200) end it 'refuses a blank existing value in an existing scope' do get '/custom_message/disallow_blank_optional_param_in_a_required_group', user: { age: '29', name: '' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"user[name] has no value"}') end it 'refuses a string value in an optional hash group' do get '/custom_message/disallow_string_value_in_an_optional_hash_group', user: '' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"user is invalid"}') end end end end context 'valid input' do it 'allows missing optional strings' do get 'opt_disallow_string_blank' expect(last_response.status).to eq(200) end it 'accepts valid input' do get '/disallow_blank', name: 'bob' expect(last_response.status).to eq(200) end it 'accepts empty input when allow_blank is false' do get '/allow_blank', name: '' expect(last_response.status).to eq(200) end it 'accepts empty input' do get '/default_allow_datetime_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts empty when datetime allow_blank' do get '/allow_datetime_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts empty when date allow_blank' do get '/allow_date_blank', val: '' expect(last_response.status).to eq(200) end context 'allow_blank when Numeric' do it 'accepts empty when integer allow_blank' do get '/allow_integer_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts empty when float allow_blank' do get '/allow_float_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts empty when integer allow_blank' do get '/allow_integer_blank', val: '' expect(last_response.status).to eq(200) end end it 'accepts empty when symbol allow_blank' do get '/allow_symbol_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts empty when boolean allow_blank' do get '/allow_boolean_blank', val: '' expect(last_response.status).to eq(200) end it 'accepts false when boolean allow_blank' do get '/disallow_boolean_blank', val: false expect(last_response.status).to eq(200) end it 'accepts value when time allow_blank' do get '/disallow_datetime_blank', val: Time.now expect(last_response.status).to eq(200) end end context 'in an optional group' do context 'as a required param' do it 'accepts a missing group, even with a disallwed blank param' do get '/disallow_blank_required_param_in_an_optional_group' expect(last_response.status).to eq(200) end it 'accepts a nested missing date value' do get '/allow_blank_date_param_in_an_optional_group', user: { name: '' } expect(last_response.status).to eq(200) end it 'refuses a blank value in an existing group' do get '/disallow_blank_required_param_in_an_optional_group', user: { name: '' } expect(last_response.status).to eq(400) end end context 'as an optional param' do it 'accepts a missing group, even with a disallwed blank param' do get '/disallow_blank_optional_param_in_an_optional_group' expect(last_response.status).to eq(200) end it 'accepts a nested missing optional value' do get '/disallow_blank_optional_param_in_an_optional_group', user: { age: '29' } expect(last_response.status).to eq(200) end it 'refuses a blank existing value in an existing scope' do get '/disallow_blank_optional_param_in_an_optional_group', user: { age: '29', name: '' } expect(last_response.status).to eq(400) end end end context 'in a required group' do context 'as a required param' do it 'refuses a blank value in a required existing group' do get '/disallow_blank_required_param_in_a_required_group', user: { name: '' } expect(last_response.status).to eq(400) end it 'refuses a string value in a required hash group' do get '/disallow_string_value_in_a_required_hash_group', user: '' expect(last_response.status).to eq(400) end end context 'as an optional param' do it 'accepts a nested missing value' do get '/disallow_blank_optional_param_in_a_required_group', user: { age: '29' } expect(last_response.status).to eq(200) end it 'refuses a blank existing value in an existing scope' do get '/disallow_blank_optional_param_in_a_required_group', user: { age: '29', name: '' } expect(last_response.status).to eq(400) end it 'refuses a string value in an optional hash group' do get '/disallow_string_value_in_an_optional_hash_group', user: '' expect(last_response.status).to eq(400) end end end end grape-1.0.2/spec/grape/validations/validators/regexp_spec.rb0000644000004100000410000001147513231337007024215 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::RegexpValidator do module ValidationsSpec module RegexpValidatorSpec class API < Grape::API default_format :json resources :custom_message do params do requires :name, regexp: { value: /^[a-z]+$/, message: 'format is invalid' } end get do end params do requires :names, type: { value: Array[String], message: 'can\'t be nil' }, regexp: { value: /^[a-z]+$/, message: 'format is invalid' } end get 'regexp_with_array' do end end params do requires :name, regexp: /^[a-z]+$/ end get do end params do requires :names, type: Array[String], regexp: /^[a-z]+$/ end get 'regexp_with_array' do end params do requires :people, type: Hash do requires :names, type: Array[String], regexp: /^[a-z]+$/ end end get 'nested_regexp_with_array' do end end end end def app ValidationsSpec::RegexpValidatorSpec::API end context 'custom validation message' do context 'with invalid input' do it 'refuses inapppopriate' do get '/custom_message', name: 'invalid name' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"name format is invalid"}') end it 'refuses empty' do get '/custom_message', name: '' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"name format is invalid"}') end end it 'accepts nil' do get '/custom_message', name: nil expect(last_response.status).to eq(200) end it 'accepts valid input' do get '/custom_message', name: 'bob' expect(last_response.status).to eq(200) end context 'regexp with array' do it 'refuses inapppopriate items' do get '/custom_message/regexp_with_array', names: ['invalid name', 'abc'] expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"names format is invalid"}') end it 'refuses empty items' do get '/custom_message/regexp_with_array', names: ['', 'abc'] expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"names format is invalid"}') end it 'refuses nil items' do get '/custom_message/regexp_with_array', names: [nil, 'abc'] expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"names can\'t be nil"}') end it 'accepts valid items' do get '/custom_message/regexp_with_array', names: ['bob'] expect(last_response.status).to eq(200) end it 'accepts nil instead of array' do get '/custom_message/regexp_with_array', names: nil expect(last_response.status).to eq(200) end end end context 'invalid input' do it 'refuses inapppopriate' do get '/', name: 'invalid name' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"name is invalid"}') end it 'refuses empty' do get '/', name: '' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"name is invalid"}') end end it 'accepts nil' do get '/', name: nil expect(last_response.status).to eq(200) end it 'accepts valid input' do get '/', name: 'bob' expect(last_response.status).to eq(200) end context 'regexp with array' do it 'refuses inapppopriate items' do get '/regexp_with_array', names: ['invalid name', 'abc'] expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"names is invalid"}') end it 'refuses empty items' do get '/regexp_with_array', names: ['', 'abc'] expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"names is invalid"}') end it 'refuses nil items' do get '/regexp_with_array', names: [nil, 'abc'] expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"names is invalid"}') end it 'accepts valid items' do get '/regexp_with_array', names: ['bob'] expect(last_response.status).to eq(200) end it 'accepts nil instead of array' do get '/regexp_with_array', names: nil expect(last_response.status).to eq(200) end end context 'nested regexp with array' do it 'refuses inapppopriate' do get '/nested_regexp_with_array', people: 'invalid name' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"people is invalid, people[names] is missing, people[names] is invalid"}') end end end grape-1.0.2/spec/grape/validations/validators/mutual_exclusion_spec.rb0000644000004100000410000000345313231337007026320 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::MutualExclusionValidator do describe '#validate!' do let(:scope) do Struct.new(:opts) do def params(arg) arg end end end let(:mutually_exclusive_params) { %i[beer wine grapefruit] } let(:validator) { described_class.new(mutually_exclusive_params, {}, false, scope.new) } context 'when all mutually exclusive params are present' do let(:params) { { beer: true, wine: true, grapefruit: true } } it 'raises a validation exception' do expect do validator.validate! params end.to raise_error(Grape::Exceptions::Validation) end context 'mixed with other params' do let(:mixed_params) { params.merge!(other: true, andanother: true) } it 'still raises a validation exception' do expect do validator.validate! mixed_params end.to raise_error(Grape::Exceptions::Validation) end end end context 'when a subset of mutually exclusive params are present' do let(:params) { { beer: true, grapefruit: true } } it 'raises a validation exception' do expect do validator.validate! params end.to raise_error(Grape::Exceptions::Validation) end end context 'when params keys come as strings' do let(:params) { { 'beer' => true, 'grapefruit' => true } } it 'raises a validation exception' do expect do validator.validate! params end.to raise_error(Grape::Exceptions::Validation) end end context 'when no mutually exclusive params are present' do let(:params) { { beer: true, somethingelse: true } } it 'params' do expect(validator.validate!(params)).to eql params end end end end grape-1.0.2/spec/grape/validations/validators/all_or_none_spec.rb0000644000004100000410000000335313231337007025206 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations::AllOrNoneOfValidator do describe '#validate!' do let(:scope) do Struct.new(:opts) do def params(arg) arg end def required?; end end end let(:all_or_none_params) { %i[beer wine grapefruit] } let(:validator) { described_class.new(all_or_none_params, {}, false, scope.new) } context 'when all restricted params are present' do let(:params) { { beer: true, wine: true, grapefruit: true } } it 'does not raise a validation exception' do expect(validator.validate!(params)).to eql params end context 'mixed with other params' do let(:mixed_params) { params.merge!(other: true, andanother: true) } it 'does not raise a validation exception' do expect(validator.validate!(mixed_params)).to eql mixed_params end end end context 'when none of the restricted params is selected' do let(:params) { { somethingelse: true } } it 'does not raise a validation exception' do expect(validator.validate!(params)).to eql params end end context 'when only a subset of restricted params are present' do let(:params) { { beer: true, grapefruit: true } } it 'raises a validation exception' do expect do validator.validate! params end.to raise_error(Grape::Exceptions::Validation) end context 'mixed with other params' do let(:mixed_params) { params.merge!(other: true, andanother: true) } it 'raise a validation exception' do expect do validator.validate! params end.to raise_error(Grape::Exceptions::Validation) end end end end end grape-1.0.2/spec/grape/dsl/0000755000004100000410000000000013231337007015451 5ustar www-datawww-datagrape-1.0.2/spec/grape/dsl/desc_spec.rb0000644000004100000410000000510213231337007017724 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module DescSpec class Dummy extend Grape::DSL::Desc end end describe Desc do subject { Class.new(DescSpec::Dummy) } describe '.desc' do it 'sets a description' do desc_text = 'The description' options = { message: 'none' } subject.desc desc_text, options expect(subject.namespace_setting(:description)).to eq(options.merge(description: desc_text)) expect(subject.route_setting(:description)).to eq(options.merge(description: desc_text)) end it 'can be set with a block' do expected_options = { description: 'The description', detail: 'more details', params: { first: :param }, entity: Object, http_codes: [[401, 'Unauthorized', 'Entities::Error']], named: 'My named route', headers: [XAuthToken: { description: 'Valdates your identity', required: true }, XOptionalHeader: { description: 'Not really needed', required: false }] } subject.desc 'The description' do detail 'more details' params(first: :param) success Object failure [[401, 'Unauthorized', 'Entities::Error']] named 'My named route' headers [XAuthToken: { description: 'Valdates your identity', required: true }, XOptionalHeader: { description: 'Not really needed', required: false }] end expect(subject.namespace_setting(:description)).to eq(expected_options) expect(subject.route_setting(:description)).to eq(expected_options) end it 'can be set with options and a block' do expect(subject).to receive(:warn).with('[DEPRECATION] Passing a options hash and a block to `desc` is deprecated. Move all hash options to block.') desc_text = 'The description' detail_text = 'more details' options = { message: 'none' } subject.desc desc_text, options do detail detail_text end expect(subject.namespace_setting(:description)).to eq(description: desc_text, detail: detail_text) expect(subject.route_setting(:description)).to eq(description: desc_text, detail: detail_text) end end end end end grape-1.0.2/spec/grape/dsl/request_response_spec.rb0000644000004100000410000002054313231337007022422 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module RequestResponseSpec class Dummy include Grape::DSL::RequestResponse def self.set(key, value) settings[key.to_sym] = value end def self.imbue(key, value) settings.imbue(key, value) end end end describe RequestResponse do subject { Class.new(RequestResponseSpec::Dummy) } let(:c_type) { 'application/json' } let(:format) { 'txt' } describe '.default_format' do it 'sets the default format' do expect(subject).to receive(:namespace_inheritable).with(:default_format, :format) subject.default_format :format end it 'returns the format without paramter' do subject.default_format :format expect(subject.default_format).to eq :format end end describe '.format' do it 'sets a new format' do expect(subject).to receive(:namespace_inheritable).with(:format, format.to_sym) expect(subject).to receive(:namespace_inheritable).with(:default_error_formatter, Grape::ErrorFormatter::Txt) subject.format format end end describe '.formatter' do it 'sets the formatter for a content type' do expect(subject).to receive(:namespace_stackable).with(:formatters, c_type.to_sym => :formatter) subject.formatter c_type, :formatter end end describe '.parser' do it 'sets a parser for a content type' do expect(subject).to receive(:namespace_stackable).with(:parsers, c_type.to_sym => :parser) subject.parser c_type, :parser end end describe '.default_error_formatter' do it 'sets a new error formatter' do expect(subject).to receive(:namespace_inheritable).with(:default_error_formatter, Grape::ErrorFormatter::Json) subject.default_error_formatter :json end end describe '.error_formatter' do it 'sets a error_formatter' do format = 'txt' expect(subject).to receive(:namespace_stackable).with(:error_formatters, format.to_sym => :error_formatter) subject.error_formatter format, :error_formatter end it 'understands syntactic sugar' do expect(subject).to receive(:namespace_stackable).with(:error_formatters, format.to_sym => :error_formatter) subject.error_formatter format, with: :error_formatter end end describe '.content_type' do it 'sets a content type for a format' do expect(subject).to receive(:namespace_stackable).with(:content_types, format.to_sym => c_type) subject.content_type format, c_type end end describe '.content_types' do it 'returns all content types' do expect(subject.content_types).to eq(xml: 'application/xml', serializable_hash: 'application/json', json: 'application/json', txt: 'text/plain', binary: 'application/octet-stream') end end describe '.default_error_status' do it 'sets a default error status' do expect(subject).to receive(:namespace_inheritable).with(:default_error_status, 500) subject.default_error_status 500 end end describe '.rescue_from' do describe ':all' do it 'sets rescue all to true' do expect(subject).to receive(:namespace_inheritable).with(:rescue_all, true) expect(subject).to receive(:namespace_inheritable).with(:all_rescue_handler, nil) subject.rescue_from :all end it 'sets given proc as rescue handler' do rescue_handler_proc = proc {} expect(subject).to receive(:namespace_inheritable).with(:rescue_all, true) expect(subject).to receive(:namespace_inheritable).with(:all_rescue_handler, rescue_handler_proc) subject.rescue_from :all, rescue_handler_proc end it 'sets given block as rescue handler' do rescue_handler_proc = proc {} expect(subject).to receive(:namespace_inheritable).with(:rescue_all, true) expect(subject).to receive(:namespace_inheritable).with(:all_rescue_handler, rescue_handler_proc) subject.rescue_from :all, &rescue_handler_proc end it 'sets a rescue handler declared through :with option' do with_block = -> { 'hello' } expect(subject).to receive(:namespace_inheritable).with(:rescue_all, true) expect(subject).to receive(:namespace_inheritable).with(:all_rescue_handler, an_instance_of(Proc)) subject.rescue_from :all, with: with_block end it 'abort if :with option value is not Symbol, String or Proc' do expect { subject.rescue_from :all, with: 1234 }.to raise_error(ArgumentError, "with: #{integer_class_name}, expected Symbol, String or Proc") end it 'abort if both :with option and block are passed' do expect do subject.rescue_from :all, with: -> { 'hello' } do error!('bye') end end.to raise_error(ArgumentError, 'both :with option and block cannot be passed') end end describe ':grape_exceptions' do it 'sets rescue all to true' do expect(subject).to receive(:namespace_inheritable).with(:rescue_all, true) expect(subject).to receive(:namespace_inheritable).with(:rescue_grape_exceptions, true) subject.rescue_from :grape_exceptions end it 'sets rescue_grape_exceptions to true' do expect(subject).to receive(:namespace_inheritable).with(:rescue_all, true) expect(subject).to receive(:namespace_inheritable).with(:rescue_grape_exceptions, true) subject.rescue_from :grape_exceptions end end describe 'list of exceptions is passed' do it 'sets hash of exceptions as rescue handlers' do expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, StandardError => nil) expect(subject).to receive(:namespace_stackable).with(:rescue_options, {}) subject.rescue_from StandardError end it 'rescues only base handlers if rescue_subclasses: false option is passed' do expect(subject).to receive(:namespace_reverse_stackable).with(:base_only_rescue_handlers, StandardError => nil) expect(subject).to receive(:namespace_stackable).with(:rescue_options, rescue_subclasses: false) subject.rescue_from StandardError, rescue_subclasses: false end it 'sets given proc as rescue handler for each key in hash' do rescue_handler_proc = proc {} expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, StandardError => rescue_handler_proc) expect(subject).to receive(:namespace_stackable).with(:rescue_options, {}) subject.rescue_from StandardError, rescue_handler_proc end it 'sets given block as rescue handler for each key in hash' do rescue_handler_proc = proc {} expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, StandardError => rescue_handler_proc) expect(subject).to receive(:namespace_stackable).with(:rescue_options, {}) subject.rescue_from StandardError, &rescue_handler_proc end it 'sets a rescue handler declared through :with option for each key in hash' do with_block = -> { 'hello' } expect(subject).to receive(:namespace_reverse_stackable).with(:rescue_handlers, StandardError => an_instance_of(Proc)) expect(subject).to receive(:namespace_stackable).with(:rescue_options, {}) subject.rescue_from StandardError, with: with_block end end end describe '.represent' do it 'sets a presenter for a class' do presenter = Class.new expect(subject).to receive(:namespace_stackable).with(:representations, ThisClass: presenter) subject.represent :ThisClass, with: presenter end end end end end grape-1.0.2/spec/grape/dsl/parameters_spec.rb0000644000004100000410000001313713231337007021160 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module ParametersSpec class Dummy include Grape::DSL::Parameters attr_accessor :api, :element, :parent def validate_attributes(*args) @validate_attributes = *args end def validate_attributes_reader @validate_attributes end def push_declared_params(args, **_opts) @push_declared_params = args end def push_declared_params_reader @push_declared_params end def validates(*args) @validates = *args end def validates_reader @validates end def new_group_scope(args) @group = args.clone.first yield end def extract_message_option(attrs) return nil unless attrs.is_a?(Array) opts = attrs.last.is_a?(Hash) ? attrs.pop : {} opts.key?(:message) && !opts[:message].nil? ? opts.delete(:message) : nil end end end describe Parameters do subject { ParametersSpec::Dummy.new } describe '#use' do before do allow_message_expectations_on_nil allow(subject.api).to receive(:namespace_stackable).with(:named_params) end let(:options) { { option: 'value' } } let(:named_params) { { params_group: proc {} } } it 'calls processes associated with named params' do allow(subject.api).to receive(:namespace_stackable_with_hash).and_return(named_params) expect(subject).to receive(:instance_exec).with(options).and_yield subject.use :params_group, options end it 'raises error when non-existent named param is called' do allow(subject.api).to receive(:namespace_stackable_with_hash).and_return({}) expect { subject.use :params_group }.to raise_error('Params :params_group not found!') end end describe '#use_scope' do it 'is alias to #use' do expect(subject.method(:use_scope)).to eq subject.method(:use) end end describe '#includes' do it 'is alias to #use' do expect(subject.method(:includes)).to eq subject.method(:use) end end describe '#requires' do it 'adds a required parameter' do subject.requires :id, type: Integer, desc: 'Identity.' expect(subject.validate_attributes_reader).to eq([[:id], { type: Integer, desc: 'Identity.', presence: { value: true, message: nil } }]) expect(subject.push_declared_params_reader).to eq([:id]) end end describe '#optional' do it 'adds an optional parameter' do subject.optional :id, type: Integer, desc: 'Identity.' expect(subject.validate_attributes_reader).to eq([[:id], { type: Integer, desc: 'Identity.' }]) expect(subject.push_declared_params_reader).to eq([:id]) end end describe '#with' do it 'creates a scope with group attributes' do subject.with(type: Integer) { subject.optional :id, desc: 'Identity.' } expect(subject.validate_attributes_reader).to eq([[:id], { type: Integer, desc: 'Identity.' }]) expect(subject.push_declared_params_reader).to eq([:id]) end end describe '#mutually_exclusive' do it 'adds an mutally exclusive parameter validation' do subject.mutually_exclusive :media, :audio expect(subject.validates_reader).to eq([%i[media audio], { mutual_exclusion: { value: true, message: nil } }]) end end describe '#exactly_one_of' do it 'adds an exactly of one parameter validation' do subject.exactly_one_of :media, :audio expect(subject.validates_reader).to eq([%i[media audio], { exactly_one_of: { value: true, message: nil } }]) end end describe '#at_least_one_of' do it 'adds an at least one of parameter validation' do subject.at_least_one_of :media, :audio expect(subject.validates_reader).to eq([%i[media audio], { at_least_one_of: { value: true, message: nil } }]) end end describe '#all_or_none_of' do it 'adds an all or none of parameter validation' do subject.all_or_none_of :media, :audio expect(subject.validates_reader).to eq([%i[media audio], { all_or_none_of: { value: true, message: nil } }]) end end describe '#group' do it 'is alias to #requires' do expect(subject.method(:group)).to eq subject.method(:requires) end end describe '#params' do it 'inherits params from parent' do parent_params = { foo: 'bar' } subject.parent = Object.new allow(subject.parent).to receive(:params).and_return(parent_params) expect(subject.params({})).to eq parent_params end describe 'when params argument is an array of hashes' do it 'returns values of each hash for @element key' do subject.element = :foo expect(subject.params([{ foo: 'bar' }, { foo: 'baz' }])).to eq(%w[bar baz]) end end describe 'when params argument is a hash' do it 'returns value for @element key' do subject.element = :foo expect(subject.params(foo: 'bar')).to eq('bar') end end describe 'when params argument is not a array or a hash' do it 'returns empty hash' do subject.element = Object.new expect(subject.params(Object.new)).to eq({}) end end end end end end grape-1.0.2/spec/grape/dsl/routing_spec.rb0000644000004100000410000002051613231337007020503 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module RoutingSpec class Dummy include Grape::DSL::Routing end end describe Routing do subject { Class.new(RoutingSpec::Dummy) } let(:proc) { ->() {} } let(:options) { { a: :b } } let(:path) { '/dummy' } describe '.version' do it 'sets a version for route' do version = 'v1' expect(subject).to receive(:namespace_inheritable).with(:version, [version]) expect(subject).to receive(:namespace_inheritable).with(:version_options, using: :path) expect(subject.version(version)).to eq(version) end end describe '.prefix' do it 'sets a prefix for route' do prefix = '/api' expect(subject).to receive(:namespace_inheritable).with(:root_prefix, prefix) subject.prefix prefix end end describe '.scope' do it 'create a scope without affecting the URL' do expect(subject).to receive(:within_namespace) subject.scope {} end end describe '.do_not_route_head!' do it 'sets do not route head option' do expect(subject).to receive(:namespace_inheritable).with(:do_not_route_head, true) subject.do_not_route_head! end end describe '.do_not_route_options!' do it 'sets do not route options option' do expect(subject).to receive(:namespace_inheritable).with(:do_not_route_options, true) subject.do_not_route_options! end end describe '.mount' do it 'mounts on a nested path' do subject = Class.new(Grape::API) app1 = Class.new(Grape::API) app2 = Class.new(Grape::API) app2.get '/nice' do 'play' end subject.mount app1 => '/app1' app1.mount app2 => '/app2' expect(subject.inheritable_setting.to_hash[:namespace]).to eq({}) expect(subject.inheritable_setting.to_hash[:namespace_inheritable]).to eq({}) expect(app1.inheritable_setting.to_hash[:namespace_stackable]).to eq(mount_path: ['/app1']) expect(app2.inheritable_setting.to_hash[:namespace_stackable]).to eq(mount_path: ['/app1', '/app2']) end end describe '.route' do before do allow(subject).to receive(:endpoints).and_return([]) allow(subject).to receive(:route_end) allow(subject).to receive(:reset_validations!) end it 'marks end of the route' do expect(subject).to receive(:route_end) subject.route(:any) end it 'resets validations' do expect(subject).to receive(:reset_validations!) subject.route(:any) end it 'defines a new endpoint' do expect { subject.route(:any) } .to change { subject.endpoints.count }.from(0).to(1) end it 'does not duplicate identical endpoints' do subject.route(:any) expect { subject.route(:any) } .to_not change(subject.endpoints, :count) end it 'generates correct endpoint options' do allow(subject).to receive(:route_setting).with(:description).and_return(fiz: 'baz') allow(subject).to receive(:namespace_stackable_with_hash).and_return(nuz: 'naz') expect(Grape::Endpoint).to receive(:new) do |_inheritable_setting, endpoint_options| expect(endpoint_options[:method]).to eq :get expect(endpoint_options[:path]).to eq '/foo' expect(endpoint_options[:for]).to eq subject expect(endpoint_options[:route_options]).to eq(foo: 'bar', fiz: 'baz', params: { nuz: 'naz' }) end.and_yield subject.route(:get, '/foo', { foo: 'bar' }, &proc {}) end end describe '.get' do it 'delegates to .route' do expect(subject).to receive(:route).with('GET', path, options) subject.get path, options, &proc end end describe '.post' do it 'delegates to .route' do expect(subject).to receive(:route).with('POST', path, options) subject.post path, options, &proc end end describe '.put' do it 'delegates to .route' do expect(subject).to receive(:route).with('PUT', path, options) subject.put path, options, &proc end end describe '.head' do it 'delegates to .route' do expect(subject).to receive(:route).with('HEAD', path, options) subject.head path, options, &proc end end describe '.delete' do it 'delegates to .route' do expect(subject).to receive(:route).with('DELETE', path, options) subject.delete path, options, &proc end end describe '.options' do it 'delegates to .route' do expect(subject).to receive(:route).with('OPTIONS', path, options) subject.options path, options, &proc end end describe '.patch' do it 'delegates to .route' do expect(subject).to receive(:route).with('PATCH', path, options) subject.patch path, options, &proc end end describe '.namespace' do let(:new_namespace) { Object.new } it 'creates a new namespace with given name and options' do expect(subject).to receive(:within_namespace).and_yield expect(subject).to receive(:nest).and_yield expect(Namespace).to receive(:new).with(:foo, foo: 'bar').and_return(new_namespace) expect(subject).to receive(:namespace_stackable).with(:namespace, new_namespace) subject.namespace :foo, foo: 'bar', &proc {} end it 'calls #joined_space_path on Namespace' do result_of_namspace_stackable = Object.new allow(subject).to receive(:namespace_stackable).and_return(result_of_namspace_stackable) expect(Namespace).to receive(:joined_space_path).with(result_of_namspace_stackable) subject.namespace end end describe '.group' do it 'is alias to #namespace' do expect(subject.method(:group)).to eq subject.method(:namespace) end end describe '.resource' do it 'is alias to #namespace' do expect(subject.method(:resource)).to eq subject.method(:namespace) end end describe '.resources' do it 'is alias to #namespace' do expect(subject.method(:resources)).to eq subject.method(:namespace) end end describe '.segment' do it 'is alias to #namespace' do expect(subject.method(:segment)).to eq subject.method(:namespace) end end describe '.routes' do let(:routes) { Object.new } it 'returns value received from #prepare_routes' do expect(subject).to receive(:prepare_routes).and_return(routes) expect(subject.routes).to eq routes end context 'when #routes was already called once' do before do allow(subject).to receive(:prepare_routes).and_return(routes) subject.routes end it 'it does not call prepare_routes again' do expect(subject).to_not receive(:prepare_routes) expect(subject.routes).to eq routes end end end describe '.route_param' do it 'calls #namespace with given params' do expect(subject).to receive(:namespace).with(':foo', {}).and_yield subject.route_param('foo', {}, &proc {}) end let(:regex) { /(.*)/ } let!(:options) { { requirements: regex } } it 'nests requirements option under param name' do expect(subject).to receive(:namespace) do |_param, options| expect(options[:requirements][:foo]).to eq regex end subject.route_param('foo', options, &proc {}) end it 'does not modify options parameter' do allow(subject).to receive(:namespace) expect { subject.route_param('foo', options, &proc {}) } .to_not change { options } end end describe '.versions' do it 'returns last defined version' do subject.version 'v1' subject.version 'v2' expect(subject.version).to eq('v2') end end end end end grape-1.0.2/spec/grape/dsl/configuration_spec.rb0000644000004100000410000000040213231337007021653 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module ConfigurationSpec class Dummy include Grape::DSL::Configuration end end describe Configuration do subject { Class.new(ConfigurationSpec::Dummy) } end end end grape-1.0.2/spec/grape/dsl/logger_spec.rb0000644000004100000410000000101713231337007020266 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module LoggerSpec class Dummy extend Grape::DSL::Logger end end describe Logger do subject { Class.new(LoggerSpec::Dummy) } let(:logger) { double(:logger) } describe '.logger' do it 'sets a logger' do subject.logger logger expect(subject.logger).to eq logger end it 'returns a logger' do expect(subject.logger(logger)).to eq logger end end end end end grape-1.0.2/spec/grape/dsl/helpers_spec.rb0000644000004100000410000000530313231337007020453 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module HelpersSpec class Dummy include Grape::DSL::Helpers def self.mods namespace_stackable(:helpers) end def self.first_mod mods.first end end end module BooleanParam extend Grape::API::Helpers params :requires_toggle_prm do requires :toggle_prm, type: Boolean end end class Base < Grape::API helpers BooleanParam end class Child < Base; end describe Helpers do subject { Class.new(HelpersSpec::Dummy) } let(:proc) do lambda do |*| def test :test end end end describe '.helpers' do it 'adds a module with the given block' do expect(subject).to receive(:namespace_stackable).with(:helpers, kind_of(Grape::DSL::Helpers::BaseHelper)).and_call_original expect(subject).to receive(:namespace_stackable).with(:helpers).and_call_original subject.helpers(&proc) expect(subject.first_mod.instance_methods).to include(:test) end it 'uses provided modules' do mod = Module.new expect(subject).to receive(:namespace_stackable).with(:helpers, kind_of(Grape::DSL::Helpers::BaseHelper)).and_call_original.exactly(2).times expect(subject).to receive(:namespace_stackable).with(:helpers).and_call_original subject.helpers(mod, &proc) expect(subject.first_mod).to eq mod end it 'uses many provided modules' do mod = Module.new mod2 = Module.new mod3 = Module.new expect(subject).to receive(:namespace_stackable).with(:helpers, kind_of(Grape::DSL::Helpers::BaseHelper)).and_call_original.exactly(4).times expect(subject).to receive(:namespace_stackable).with(:helpers).and_call_original.exactly(3).times subject.helpers(mod, mod2, mod3, &proc) expect(subject.mods).to include(mod) expect(subject.mods).to include(mod2) expect(subject.mods).to include(mod3) end context 'with an external file' do it 'sets Boolean as a Virtus::Attribute::Boolean' do subject.helpers BooleanParam expect(subject.first_mod::Boolean).to eq Virtus::Attribute::Boolean end end context 'in child classes' do it 'is available' do klass = Child expect do klass.instance_eval do params do use :requires_toggle_prm end end end.to_not raise_exception end end end end end end grape-1.0.2/spec/grape/dsl/validations_spec.rb0000644000004100000410000000375113231337007021333 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module ValidationsSpec class Dummy include Grape::DSL::Validations end end describe Validations do subject { ValidationsSpec::Dummy } describe '.reset_validations!' do before do subject.namespace_stackable :declared_params, ['dummy'] subject.namespace_stackable :validations, ['dummy'] subject.namespace_stackable :params, ['dummy'] subject.route_setting :description, description: 'lol', params: ['dummy'] subject.reset_validations! end after do subject.unset_route_setting :description end it 'resets declared params' do expect(subject.namespace_stackable(:declared_params)).to eq [] end it 'resets validations' do expect(subject.namespace_stackable(:validations)).to eq [] end it 'resets params' do expect(subject.namespace_stackable(:params)).to eq [] end it 'resets documentation params' do expect(subject.route_setting(:description)[:params]).to be_nil end it 'does not reset documentation description' do expect(subject.route_setting(:description)[:description]).to eq 'lol' end end describe '.params' do it 'returns a ParamsScope' do expect(subject.params).to be_a Grape::Validations::ParamsScope end it 'evaluates block' do expect { subject.params { raise 'foo' } }.to raise_error RuntimeError, 'foo' end end describe '.document_attribute' do before do subject.document_attribute([full_name: 'xxx'], foo: 'bar') end it 'creates a param documentation' do expect(subject.namespace_stackable(:params)).to eq(['xxx' => { foo: 'bar' }]) expect(subject.route_setting(:description)).to eq(params: { 'xxx' => { foo: 'bar' } }) end end end end end grape-1.0.2/spec/grape/dsl/inside_route_spec.rb0000644000004100000410000002277313231337007021514 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module InsideRouteSpec class Dummy include Grape::DSL::InsideRoute attr_reader :env, :request, :new_settings def initialize @env = {} @header = {} @new_settings = { namespace_inheritable: {}, namespace_stackable: {} } end end end end end describe Grape::Endpoint do subject { Grape::DSL::InsideRouteSpec::Dummy.new } describe '#version' do it 'defaults to nil' do expect(subject.version).to be nil end it 'returns env[api.version]' do subject.env['api.version'] = 'dummy' expect(subject.version).to eq 'dummy' end end describe '#error!' do it 'throws :error' do expect { subject.error! 'Not Found', 404 }.to throw_symbol(:error) end describe 'thrown' do before do catch(:error) { subject.error! 'Not Found', 404 } end it 'sets status' do expect(subject.status).to eq 404 end end describe 'default_error_status' do before do subject.namespace_inheritable(:default_error_status, 500) catch(:error) { subject.error! 'Unknown' } end it 'sets status to default_error_status' do expect(subject.status).to eq 500 end end # self.status(status || settings[:default_error_status]) # throw :error, message: message, status: self.status, headers: headers end describe '#redirect' do describe 'default' do before do subject.redirect '/' end it 'sets status to 302' do expect(subject.status).to eq 302 end it 'sets location header' do expect(subject.header['Location']).to eq '/' end end describe 'permanent' do before do subject.redirect '/', permanent: true end it 'sets status to 301' do expect(subject.status).to eq 301 end it 'sets location header' do expect(subject.header['Location']).to eq '/' end end end describe '#status' do %w[GET PUT OPTIONS].each do |method| it 'defaults to 200 on GET' do request = Grape::Request.new(Rack::MockRequest.env_for('/', method: method)) expect(subject).to receive(:request).and_return(request) expect(subject.status).to eq 200 end end it 'defaults to 201 on POST' do request = Grape::Request.new(Rack::MockRequest.env_for('/', method: 'POST')) expect(subject).to receive(:request).and_return(request) expect(subject.status).to eq 201 end it 'defaults to 204 on DELETE' do request = Grape::Request.new(Rack::MockRequest.env_for('/', method: 'DELETE')) expect(subject).to receive(:request).and_return(request) expect(subject.status).to eq 204 end it 'defaults to 200 on DELETE with a body present' do request = Grape::Request.new(Rack::MockRequest.env_for('/', method: 'DELETE')) subject.body 'content here' expect(subject).to receive(:request).and_return(request) expect(subject.status).to eq 200 end it 'returns status set' do subject.status 501 expect(subject.status).to eq 501 end it 'accepts symbol for status' do subject.status :see_other expect(subject.status).to eq 303 end it 'raises error if unknow symbol is passed' do expect { subject.status :foo_bar } .to raise_error(ArgumentError, 'Status code :foo_bar is invalid.') end it 'accepts unknown Integer status codes' do expect { subject.status 210 }.to_not raise_error end it 'raises error if status is not a integer or symbol' do expect { subject.status Object.new } .to raise_error(ArgumentError, 'Status code must be Integer or Symbol.') end end describe '#return_no_content' do it 'sets the status code and body' do subject.return_no_content expect(subject.status).to eq 204 expect(subject.body).to eq '' end end describe '#content_type' do describe 'set' do before do subject.content_type 'text/plain' end it 'returns value' do expect(subject.content_type).to eq 'text/plain' end end it 'returns default' do expect(subject.content_type).to be nil end end describe '#cookies' do it 'returns an instance of Cookies' do expect(subject.cookies).to be_a Grape::Cookies end end describe '#body' do describe 'set' do before do subject.body 'body' end it 'returns value' do expect(subject.body).to eq 'body' end end describe 'false' do before do subject.body false end it 'sets status to 204' do expect(subject.body).to eq '' expect(subject.status).to eq 204 end end it 'returns default' do expect(subject.body).to be nil end end describe '#file' do describe 'set' do context 'as file path' do let(:file_path) { '/some/file/path' } let(:file_response) do file_body = Grape::ServeFile::FileBody.new(file_path) Grape::ServeFile::FileResponse.new(file_body) end before do subject.file file_path end it 'returns value wrapped in FileResponse' do expect(subject.file).to eq file_response end end context 'as object (backward compatibility)' do let(:file_object) { Class.new } let(:file_response) do Grape::ServeFile::FileResponse.new(file_object) end before do subject.file file_object end it 'returns value wrapped in FileResponse' do expect(subject.file).to eq file_response end end end it 'returns default' do expect(subject.file).to be nil end end describe '#stream' do describe 'set' do let(:file_object) { Class.new } before do subject.header 'Cache-Control', 'cache' subject.header 'Content-Length', 123 subject.header 'Transfer-Encoding', 'base64' subject.stream file_object end it 'returns value wrapped in FileResponse' do expect(subject.stream).to eq Grape::ServeFile::FileResponse.new(file_object) end it 'also sets result of file to value wrapped in FileResponse' do expect(subject.file).to eq Grape::ServeFile::FileResponse.new(file_object) end it 'sets Cache-Control header to no-cache' do expect(subject.header['Cache-Control']).to eq 'no-cache' end it 'sets Content-Length header to nil' do expect(subject.header['Content-Length']).to eq nil end it 'sets Transfer-Encoding header to nil' do expect(subject.header['Transfer-Encoding']).to eq nil end end it 'returns default' do expect(subject.file).to be nil end end describe '#route' do before do subject.env['grape.routing_args'] = {} subject.env['grape.routing_args'][:route_info] = 'dummy' end it 'returns route_info' do expect(subject.route).to eq 'dummy' end end describe '#present' do # see entity_spec.rb for entity representation spec coverage describe 'dummy' do before do subject.present 'dummy' end it 'presents dummy object' do expect(subject.body).to eq 'dummy' end end describe 'with' do describe 'entity' do let(:entity_mock) do entity_mock = Object.new allow(entity_mock).to receive(:represent).and_return('dummy') entity_mock end describe 'instance' do before do subject.present 'dummy', with: entity_mock end it 'presents dummy object' do expect(subject.body).to eq 'dummy' end end end end describe 'multiple entities' do let(:entity_mock_one) do entity_mock_one = Object.new allow(entity_mock_one).to receive(:represent).and_return(dummy1: 'dummy1') entity_mock_one end let(:entity_mock_two) do entity_mock_two = Object.new allow(entity_mock_two).to receive(:represent).and_return(dummy2: 'dummy2') entity_mock_two end describe 'instance' do before do subject.present 'dummy1', with: entity_mock_one subject.present 'dummy2', with: entity_mock_two end it 'presents both dummy objects' do expect(subject.body[:dummy1]).to eq 'dummy1' expect(subject.body[:dummy2]).to eq 'dummy2' end end end describe 'non mergeable entity' do let(:entity_mock_one) do entity_mock_one = Object.new allow(entity_mock_one).to receive(:represent).and_return(dummy1: 'dummy1') entity_mock_one end let(:entity_mock_two) do entity_mock_two = Object.new allow(entity_mock_two).to receive(:represent).and_return('not a hash') entity_mock_two end describe 'instance' do it 'fails' do subject.present 'dummy1', with: entity_mock_one expect do subject.present 'dummy2', with: entity_mock_two end.to raise_error ArgumentError, 'Representation of type String cannot be merged.' end end end end describe '#declared' do # see endpoint_spec.rb#declared for spec coverage it 'is not available by default' do expect { subject.declared({}) }.to raise_error( Grape::DSL::InsideRoute::MethodNotYetAvailable ) end end end grape-1.0.2/spec/grape/dsl/middleware_spec.rb0000644000004100000410000000305013231337007021123 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module MiddlewareSpec class Dummy include Grape::DSL::Middleware end end describe Middleware do subject { Class.new(MiddlewareSpec::Dummy) } let(:proc) { ->() {} } let(:foo_middleware) { Class.new } let(:bar_middleware) { Class.new } describe '.use' do it 'adds a middleware with the right operation' do expect(subject).to receive(:namespace_stackable).with(:middleware, [:use, foo_middleware, :arg1, proc]) subject.use foo_middleware, :arg1, &proc end end describe '.insert_before' do it 'adds a middleware with the right operation' do expect(subject).to receive(:namespace_stackable).with(:middleware, [:insert_before, foo_middleware, :arg1, proc]) subject.insert_before foo_middleware, :arg1, &proc end end describe '.insert_after' do it 'adds a middleware with the right operation' do expect(subject).to receive(:namespace_stackable).with(:middleware, [:insert_after, foo_middleware, :arg1, proc]) subject.insert_after foo_middleware, :arg1, &proc end end describe '.middleware' do it 'returns the middleware stack' do subject.use foo_middleware, :arg1, &proc subject.insert_before bar_middleware, :arg1, :arg2 expect(subject.middleware).to eq [[:use, foo_middleware, :arg1, proc], [:insert_before, bar_middleware, :arg1, :arg2]] end end end end end grape-1.0.2/spec/grape/dsl/callbacks_spec.rb0000644000004100000410000000222013231337007020723 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module CallbacksSpec class Dummy include Grape::DSL::Callbacks end end describe Callbacks do subject { Class.new(CallbacksSpec::Dummy) } let(:proc) { ->() {} } describe '.before' do it 'adds a block to "before"' do expect(subject).to receive(:namespace_stackable).with(:befores, proc) subject.before(&proc) end end describe '.before_validation' do it 'adds a block to "before_validation"' do expect(subject).to receive(:namespace_stackable).with(:before_validations, proc) subject.before_validation(&proc) end end describe '.after_validation' do it 'adds a block to "after_validation"' do expect(subject).to receive(:namespace_stackable).with(:after_validations, proc) subject.after_validation(&proc) end end describe '.after' do it 'adds a block to "after"' do expect(subject).to receive(:namespace_stackable).with(:afters, proc) subject.after(&proc) end end end end end grape-1.0.2/spec/grape/dsl/settings_spec.rb0000644000004100000410000002017713231337007020657 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module SettingsSpec class Dummy include Grape::DSL::Settings def reset_validations!; end end end describe Settings do subject { SettingsSpec::Dummy.new } describe '#unset' do it 'deletes a key from settings' do subject.namespace_setting :dummy, 1 expect(subject.inheritable_setting.namespace.keys).to include(:dummy) subject.unset :namespace, :dummy expect(subject.inheritable_setting.namespace.keys).not_to include(:dummy) end end describe '#get_or_set' do it 'sets a values' do subject.get_or_set :namespace, :dummy, 1 expect(subject.namespace_setting(:dummy)).to eq 1 end it 'returns a value when nil is new value is provided' do subject.get_or_set :namespace, :dummy, 1 expect(subject.get_or_set(:namespace, :dummy, nil)).to eq 1 end end describe '#global_setting' do it 'delegates to get_or_set' do expect(subject).to receive(:get_or_set).with(:global, :dummy, 1) subject.global_setting(:dummy, 1) end end describe '#unset_global_setting' do it 'delegates to unset' do expect(subject).to receive(:unset).with(:global, :dummy) subject.unset_global_setting(:dummy) end end describe '#route_setting' do it 'delegates to get_or_set' do expect(subject).to receive(:get_or_set).with(:route, :dummy, 1) subject.route_setting(:dummy, 1) end it 'sets a value until the next route' do subject.route_setting :some_thing, :foo_bar expect(subject.route_setting(:some_thing)).to eq :foo_bar subject.route_end expect(subject.route_setting(:some_thing)).to be_nil end end describe '#unset_route_setting' do it 'delegates to unset' do expect(subject).to receive(:unset).with(:route, :dummy) subject.unset_route_setting(:dummy) end end describe '#namespace_setting' do it 'delegates to get_or_set' do expect(subject).to receive(:get_or_set).with(:namespace, :dummy, 1) subject.namespace_setting(:dummy, 1) end it 'sets a value until the end of a namespace' do subject.namespace_start subject.namespace_setting :some_thing, :foo_bar expect(subject.namespace_setting(:some_thing)).to eq :foo_bar subject.namespace_end expect(subject.namespace_setting(:some_thing)).to be_nil end it 'resets values after leaving nested namespaces' do subject.namespace_start subject.namespace_setting :some_thing, :foo_bar expect(subject.namespace_setting(:some_thing)).to eq :foo_bar subject.namespace_start expect(subject.namespace_setting(:some_thing)).to be_nil subject.namespace_end expect(subject.namespace_setting(:some_thing)).to eq :foo_bar subject.namespace_end expect(subject.namespace_setting(:some_thing)).to be_nil end end describe '#unset_namespace_setting' do it 'delegates to unset' do expect(subject).to receive(:unset).with(:namespace, :dummy) subject.unset_namespace_setting(:dummy) end end describe '#namespace_inheritable' do it 'delegates to get_or_set' do expect(subject).to receive(:get_or_set).with(:namespace_inheritable, :dummy, 1) subject.namespace_inheritable(:dummy, 1) end it 'inherits values from surrounding namespace' do subject.namespace_start subject.namespace_inheritable(:some_thing, :foo_bar) expect(subject.namespace_inheritable(:some_thing)).to eq :foo_bar subject.namespace_start expect(subject.namespace_inheritable(:some_thing)).to eq :foo_bar subject.namespace_inheritable(:some_thing, :foo_bar_2) expect(subject.namespace_inheritable(:some_thing)).to eq :foo_bar_2 subject.namespace_end expect(subject.namespace_inheritable(:some_thing)).to eq :foo_bar subject.namespace_end end end describe '#unset_namespace_inheritable' do it 'delegates to unset' do expect(subject).to receive(:unset).with(:namespace_inheritable, :dummy) subject.unset_namespace_inheritable(:dummy) end end describe '#namespace_stackable' do it 'delegates to get_or_set' do expect(subject).to receive(:get_or_set).with(:namespace_stackable, :dummy, 1) subject.namespace_stackable(:dummy, 1) end it 'stacks values from surrounding namespace' do subject.namespace_start subject.namespace_stackable(:some_thing, :foo_bar) expect(subject.namespace_stackable(:some_thing)).to eq [:foo_bar] subject.namespace_start expect(subject.namespace_stackable(:some_thing)).to eq [:foo_bar] subject.namespace_stackable(:some_thing, :foo_bar_2) expect(subject.namespace_stackable(:some_thing)).to eq %i[foo_bar foo_bar_2] subject.namespace_end expect(subject.namespace_stackable(:some_thing)).to eq [:foo_bar] subject.namespace_end end end describe '#unset_namespace_stackable' do it 'delegates to unset' do expect(subject).to receive(:unset).with(:namespace_stackable, :dummy) subject.unset_namespace_stackable(:dummy) end end describe '#api_class_setting' do it 'delegates to get_or_set' do expect(subject).to receive(:get_or_set).with(:api_class, :dummy, 1) subject.api_class_setting(:dummy, 1) end end describe '#unset_api_class_setting' do it 'delegates to unset' do expect(subject).to receive(:unset).with(:api_class, :dummy) subject.unset_api_class_setting(:dummy) end end describe '#within_namespace' do it 'calls start and end for a namespace' do expect(subject).to receive :namespace_start expect(subject).to receive :namespace_end subject.within_namespace do end end it 'returns the last result' do result = subject.within_namespace do 1 end expect(result).to eq 1 end end describe 'complex scenario' do it 'plays well' do obj1 = SettingsSpec::Dummy.new obj2 = SettingsSpec::Dummy.new obj3 = SettingsSpec::Dummy.new obj1_copy = nil obj2_copy = nil obj3_copy = nil obj1.within_namespace do obj1.namespace_stackable(:some_thing, :obj1) expect(obj1.namespace_stackable(:some_thing)).to eq [:obj1] obj1_copy = obj1.inheritable_setting.point_in_time_copy end expect(obj1.namespace_stackable(:some_thing)).to eq [] expect(obj1_copy.namespace_stackable[:some_thing]).to eq [:obj1] obj2.within_namespace do obj2.namespace_stackable(:some_thing, :obj2) expect(obj2.namespace_stackable(:some_thing)).to eq [:obj2] obj2_copy = obj2.inheritable_setting.point_in_time_copy end expect(obj2.namespace_stackable(:some_thing)).to eq [] expect(obj2_copy.namespace_stackable[:some_thing]).to eq [:obj2] obj3.within_namespace do obj3.namespace_stackable(:some_thing, :obj3) expect(obj3.namespace_stackable(:some_thing)).to eq [:obj3] obj3_copy = obj3.inheritable_setting.point_in_time_copy end expect(obj3.namespace_stackable(:some_thing)).to eq [] expect(obj3_copy.namespace_stackable[:some_thing]).to eq [:obj3] obj1.top_level_setting.inherit_from obj2_copy.point_in_time_copy obj2.top_level_setting.inherit_from obj3_copy.point_in_time_copy expect(obj1_copy.namespace_stackable[:some_thing]).to eq %i[obj3 obj2 obj1] end end end end end grape-1.0.2/spec/grape/dsl/headers_spec.rb0000644000004100000410000000125513231337007020426 0ustar www-datawww-datarequire 'spec_helper' module Grape module DSL module HeadersSpec class Dummy include Grape::DSL::Headers end end describe Headers do subject { HeadersSpec::Dummy.new } describe '#header' do describe 'set' do before do subject.header 'Name', 'Value' end it 'returns value' do expect(subject.header['Name']).to eq 'Value' expect(subject.header('Name')).to eq 'Value' end end it 'returns nil' do expect(subject.header['Name']).to be nil expect(subject.header('Name')).to be nil end end end end end grape-1.0.2/spec/grape/integration/0000755000004100000410000000000013231337007017212 5ustar www-datawww-datagrape-1.0.2/spec/grape/integration/global_namespace_function_spec.rb0000644000004100000410000000064413231337007025736 0ustar www-datawww-data# see https://github.com/ruby-grape/grape/issues/1348 require 'spec_helper' def namespace raise end describe Grape::API do subject do Class.new(Grape::API) do format :json get do { ok: true } end end end def app subject end context 'with a global namespace function' do it 'works' do get '/' expect(last_response.status).to eq 200 end end end grape-1.0.2/spec/grape/integration/rack_sendfile_spec.rb0000644000004100000410000000164013231337007023343 0ustar www-datawww-datarequire 'spec_helper' describe Rack::Sendfile do subject do send_file = file_streamer app = Class.new(Grape::API) do use Rack::Sendfile format :json get do file send_file end end options = { method: 'GET', 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect', 'HTTP_X_ACCEL_MAPPING' => '/accel/mapping/=/replaced/' } env = Rack::MockRequest.env_for('/', options) app.call(env) end context do let(:file_streamer) do double(:file_streamer, to_path: '/accel/mapping/some/path') end it 'contains Sendfile headers' do headers = subject[1] expect(headers).to include('X-Accel-Redirect') end end context do let(:file_streamer) do double(:file_streamer) end it 'not contains Sendfile headers' do headers = subject[1] expect(headers).to_not include('X-Accel-Redirect') end end end grape-1.0.2/spec/grape/integration/rack_spec.rb0000644000004100000410000000172613231337007021477 0ustar www-datawww-datarequire 'spec_helper' describe Rack do it 'correctly populates params from a Tempfile' do input = Tempfile.new 'rubbish' begin app = Class.new(Grape::API) do format :json post do { params_keys: params.keys } end end input.write({ test: '123' * 10_000 }.to_json) input.rewind options = { input: input, method: 'POST', 'CONTENT_TYPE' => 'application/json' } env = Rack::MockRequest.env_for('/', options) unless RUBY_PLATFORM == 'java' major, minor, patch = Rack.release.split('.').map(&:to_i) patch ||= 0 # rack <= 1.5.2 does not specify patch version pending 'Rack 1.5.3 or 1.6.1 required' unless major >= 2 || (major >= 1 && ((minor == 5 && patch >= 3) || (minor >= 6))) end expect(JSON.parse(app.call(env)[2].body.first)['params_keys']).to match_array('test') ensure input.close input.unlink end end end grape-1.0.2/spec/grape/presenters/0000755000004100000410000000000013231337007017061 5ustar www-datawww-datagrape-1.0.2/spec/grape/presenters/presenter_spec.rb0000644000004100000410000000321113231337007022424 0ustar www-datawww-datarequire 'spec_helper' module Grape module Presenters module PresenterSpec class Dummy include Grape::DSL::InsideRoute attr_reader :env, :request, :new_settings def initialize @env = {} @header = {} @new_settings = { namespace_inheritable: {}, namespace_stackable: {} } end end end describe Presenter do describe 'represent' do let(:object_mock) do Object.new end it 'represent object' do expect(Presenter.represent(object_mock)).to eq object_mock end end subject { PresenterSpec::Dummy.new } describe 'present' do let(:hash_mock) do { key: :value } end describe 'instance' do before do subject.present hash_mock, with: Grape::Presenters::Presenter end it 'presents dummy hash' do expect(subject.body).to eq hash_mock end end describe 'multiple presenter' do let(:hash_mock1) do { key1: :value1 } end let(:hash_mock2) do { key2: :value2 } end describe 'instance' do before do subject.present hash_mock1, with: Grape::Presenters::Presenter subject.present hash_mock2, with: Grape::Presenters::Presenter end it 'presents both dummy presenter' do expect(subject.body[:key1]).to eq hash_mock1[:key1] expect(subject.body[:key2]).to eq hash_mock2[:key2] end end end end end end end grape-1.0.2/spec/grape/validations_spec.rb0000644000004100000410000015333713231337007020557 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Validations do subject { Class.new(Grape::API) } def app subject end describe 'params' do context 'optional' do it 'validates when params is present' do subject.params do optional :a_number, regexp: /^[0-9]+$/ end subject.get '/optional' do 'optional works!' end get '/optional', a_number: 'string' expect(last_response.status).to eq(400) expect(last_response.body).to eq('a_number is invalid') get '/optional', a_number: 45 expect(last_response.status).to eq(200) expect(last_response.body).to eq('optional works!') end it "doesn't validate when param not present" do subject.params do optional :a_number, regexp: /^[0-9]+$/ end subject.get '/optional' do 'optional works!' end get '/optional' expect(last_response.status).to eq(200) expect(last_response.body).to eq('optional works!') end it 'adds to declared parameters' do subject.params do optional :some_param end expect(subject.route_setting(:declared_params)).to eq([:some_param]) end end context 'optional using Grape::Entity documentation' do def define_optional_using documentation = { field_a: { type: String }, field_b: { type: String } } subject.params do optional :all, using: documentation end end before do define_optional_using subject.get '/optional' do 'optional with using works' end end it 'adds entity documentation to declared params' do define_optional_using expect(subject.route_setting(:declared_params)).to eq(%i[field_a field_b]) end it 'works when field_a and field_b are not present' do get '/optional' expect(last_response.status).to eq(200) expect(last_response.body).to eq('optional with using works') end it 'works when field_a is present' do get '/optional', field_a: 'woof' expect(last_response.status).to eq(200) expect(last_response.body).to eq('optional with using works') end it 'works when field_b is present' do get '/optional', field_b: 'woof' expect(last_response.status).to eq(200) expect(last_response.body).to eq('optional with using works') end end context 'required' do before do subject.params do requires :key, type: String end subject.get('/required') { 'required works' } subject.put('/required') { { key: params[:key] }.to_json } end it 'errors when param not present' do get '/required' expect(last_response.status).to eq(400) expect(last_response.body).to eq('key is missing') end it "doesn't throw a missing param when param is present" do get '/required', key: 'cool' expect(last_response.status).to eq(200) expect(last_response.body).to eq('required works') end it 'adds to declared parameters' do subject.params do requires :some_param end expect(subject.route_setting(:declared_params)).to eq([:some_param]) end it 'works when required field is present but nil' do put '/required', { key: nil }.to_json, 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq('key' => nil) end end context 'requires :all using Grape::Entity documentation' do def define_requires_all documentation = { required_field: { type: String }, optional_field: { type: String } } subject.params do requires :all, except: :optional_field, using: documentation end end before do define_requires_all subject.get '/required' do 'required works' end end it 'adds entity documentation to declared params' do define_requires_all expect(subject.route_setting(:declared_params)).to eq(%i[required_field optional_field]) end it 'errors when required_field is not present' do get '/required' expect(last_response.status).to eq(400) expect(last_response.body).to eq('required_field is missing') end it 'works when required_field is present' do get '/required', required_field: 'woof' expect(last_response.status).to eq(200) expect(last_response.body).to eq('required works') end end context 'requires :none using Grape::Entity documentation' do def define_requires_none documentation = { required_field: { type: String }, optional_field: { type: String } } subject.params do requires :none, except: :required_field, using: documentation end end before do define_requires_none subject.get '/required' do 'required works' end end it 'adds entity documentation to declared params' do define_requires_none expect(subject.route_setting(:declared_params)).to eq(%i[required_field optional_field]) end it 'errors when required_field is not present' do get '/required' expect(last_response.status).to eq(400) expect(last_response.body).to eq('required_field is missing') end it 'works when required_field is present' do get '/required', required_field: 'woof' expect(last_response.status).to eq(200) expect(last_response.body).to eq('required works') end end context 'requires :all or :none but except a non-existent field using Grape::Entity documentation' do context 'requires :all' do def define_requires_all documentation = { required_field: { type: String }, optional_field: { type: String } } subject.params do requires :all, except: :non_existent_field, using: documentation end end it 'adds only the entity documentation to declared params, nothing more' do define_requires_all expect(subject.route_setting(:declared_params)).to eq(%i[required_field optional_field]) end end context 'requires :none' do def define_requires_none documentation = { required_field: { type: String }, optional_field: { type: String } } subject.params do requires :none, except: :non_existent_field, using: documentation end end it 'adds only the entity documentation to declared params, nothing more' do expect { define_requires_none }.to raise_error(ArgumentError) end end end context 'required with an Array block' do before do subject.params do requires :items, type: Array do requires :key end end subject.get('/required') { 'required works' } subject.put('/required') { { items: params[:items] }.to_json } end it 'errors when param not present' do get '/required' expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is missing') end it 'errors when param is not an Array' do get '/required', items: 'hello' expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is invalid') get '/required', items: { key: 'foo' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is invalid') end it "doesn't throw a missing param when param is present" do get '/required', items: [{ key: 'hello' }, { key: 'world' }] expect(last_response.status).to eq(200) expect(last_response.body).to eq('required works') end it "doesn't throw a missing param when param is present but empty" do put '/required', { items: [] }.to_json, 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq('items' => []) end it 'adds to declared parameters' do subject.params do requires :items, type: Array do requires :key end end expect(subject.route_setting(:declared_params)).to eq([items: [:key]]) end end # Ensure there is no leakage between declared Array types and # subsequent Hash types context 'required with an Array and a Hash block' do before do subject.params do requires :cats, type: Array[String], default: [] requires :items, type: Hash do requires :key end end subject.get '/required' do 'required works' end end it 'does not output index [0] for Hash types' do get '/required', cats: ['Garfield'], items: { foo: 'bar' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('items[key] is missing') end end context 'required with a Hash block' do before do subject.params do requires :items, type: Hash do requires :key end end subject.get '/required' do 'required works' end end it 'errors when param not present' do get '/required' expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is missing, items[key] is missing') end it 'errors when nested param not present' do get '/required', items: { foo: 'bar' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('items[key] is missing') end it 'errors when param is not a Hash' do get '/required', items: 'hello' expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is invalid, items[key] is missing') get '/required', items: [{ key: 'foo' }] expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is invalid') end it "doesn't throw a missing param when param is present" do get '/required', items: { key: 'hello' } expect(last_response.status).to eq(200) expect(last_response.body).to eq('required works') end it 'adds to declared parameters' do subject.params do requires :items, type: Array do requires :key end end expect(subject.route_setting(:declared_params)).to eq([items: [:key]]) end end context 'hash with a required param with validation' do before do subject.params do requires :items, type: Hash do requires :key, type: String, values: %w[a b] end end subject.get '/required' do 'required works' end end it 'errors when param is not a Hash' do get '/required', items: 'not a hash' expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is invalid, items[key] is missing, items[key] is invalid') get '/required', items: [{ key: 'hash in array' }] expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is invalid, items[key] does not have a valid value') end it 'works when all params match' do get '/required', items: { key: 'a' } expect(last_response.status).to eq(200) expect(last_response.body).to eq('required works') end end context 'group' do before do subject.params do group :items, type: Array do requires :key end end subject.get '/required' do 'required works' end end it 'errors when param not present' do get '/required' expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is missing') end it "doesn't throw a missing param when param is present" do get '/required', items: [key: 'hello'] expect(last_response.status).to eq(200) expect(last_response.body).to eq('required works') end it 'adds to declared parameters' do subject.params do group :items, type: Array do requires :key end end expect(subject.route_setting(:declared_params)).to eq([items: [:key]]) end end context 'group params with nested params which has a type' do let(:invalid_items) { { items: '' } } before do subject.params do optional :items, type: Array do optional :key1, type: String optional :key2, type: String end end subject.post '/group_with_nested' do 'group with nested works' end end it 'errors when group param is invalid' do post '/group_with_nested', items: invalid_items expect(last_response.status).to eq(400) end end context 'custom validator for a Hash' do module ValuesSpec module DateRangeValidations class DateRangeValidator < Grape::Validations::Base def validate_param!(attr_name, params) return if params[attr_name][:from] <= params[attr_name][:to] raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: "'from' must be lower or equal to 'to'" end end end end before do subject.params do optional :date_range, date_range: true, type: Hash do requires :from, type: Integer requires :to, type: Integer end end subject.get('/optional') do 'optional works' end subject.params do requires :date_range, date_range: true, type: Hash do requires :from, type: Integer requires :to, type: Integer end end subject.get('/required') do 'required works' end end context 'which is optional' do it "doesn't throw an error if the validation passes" do get '/optional', date_range: { from: 1, to: 2 } expect(last_response.status).to eq(200) end it 'errors if the validation fails' do get '/optional', date_range: { from: 2, to: 1 } expect(last_response.status).to eq(400) end end context 'which is required' do it "doesn't throw an error if the validation passes" do get '/required', date_range: { from: 1, to: 2 } expect(last_response.status).to eq(200) end it 'errors if the validation fails' do get '/required', date_range: { from: 2, to: 1 } expect(last_response.status).to eq(400) end end end context 'validation within arrays' do before do subject.params do group :children, type: Array do requires :name group :parents, type: Array do requires :name, allow_blank: false end end end subject.get '/within_array' do 'within array works' end end it 'can handle new scopes within child elements' do get '/within_array', children: [ { name: 'John', parents: [{ name: 'Jane' }, { name: 'Bob' }] }, { name: 'Joe', parents: [{ name: 'Josie' }] } ] expect(last_response.status).to eq(200) expect(last_response.body).to eq('within array works') end it 'errors when a parameter is not present' do get '/within_array', children: [ { name: 'Jim', parents: [{ name: 'Joy' }] }, { name: 'Job', parents: [{}] } ] # NOTE: with body parameters in json or XML or similar this # should actually fail with: children[parents][name] is missing. expect(last_response.status).to eq(400) expect(last_response.body).to eq('children[1][parents] is missing') end it 'errors when a parameter is not present in array within array' do get '/within_array', children: [ { name: 'Jim', parents: [{ name: 'Joy' }] }, { name: 'Job', parents: [{ name: 'Bill' }, { name: '' }] } ] expect(last_response.status).to eq(400) expect(last_response.body).to eq('children[1][parents][1][name] is empty') end it 'handle errors for all array elements' do get '/within_array', children: [ { name: 'Jim', parents: [] }, { name: 'Job', parents: [] } ] expect(last_response.status).to eq(400) expect(last_response.body).to eq('children[0][parents] is missing, children[1][parents] is missing') end it 'safely handles empty arrays and blank parameters' do # NOTE: with body parameters in json or XML or similar this # should actually return 200, since an empty array is valid. get '/within_array', children: [] expect(last_response.status).to eq(400) expect(last_response.body).to eq('children is missing') get '/within_array', children: [name: 'Jay'] expect(last_response.status).to eq(400) expect(last_response.body).to eq('children[0][parents] is missing') end it 'errors when param is not an Array' do get '/within_array', children: 'hello' expect(last_response.status).to eq(400) expect(last_response.body).to eq('children is invalid') get '/within_array', children: { name: 'foo' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('children is invalid') get '/within_array', children: [name: 'Jay', parents: { name: 'Fred' }] expect(last_response.status).to eq(400) expect(last_response.body).to eq('children[0][parents] is invalid') end end context 'with block param' do before do subject.params do requires :planets, type: Array do requires :name end end subject.get '/req' do 'within array works' end subject.put '/req' do '' end subject.params do group :stars, type: Array do requires :name end end subject.get '/grp' do 'within array works' end subject.put '/grp' do '' end subject.params do requires :name optional :moons, type: Array do requires :name end end subject.get '/opt' do 'within array works' end subject.put '/opt' do '' end end it 'requires defaults to Array type' do get '/req', planets: 'Jupiter, Saturn' expect(last_response.status).to eq(400) expect(last_response.body).to eq('planets is invalid') get '/req', planets: { name: 'Jupiter' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('planets is invalid') get '/req', planets: [{ name: 'Venus' }, { name: 'Mars' }] expect(last_response.status).to eq(200) put_with_json '/req', planets: [] expect(last_response.status).to eq(200) end it 'optional defaults to Array type' do get '/opt', name: 'Jupiter', moons: 'Europa, Ganymede' expect(last_response.status).to eq(400) expect(last_response.body).to eq('moons is invalid') get '/opt', name: 'Jupiter', moons: { name: 'Ganymede' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('moons is invalid') get '/opt', name: 'Jupiter', moons: [{ name: 'Io' }, { name: 'Callisto' }] expect(last_response.status).to eq(200) put_with_json '/opt', name: 'Venus' expect(last_response.status).to eq(200) put_with_json '/opt', name: 'Mercury', moons: [] expect(last_response.status).to eq(200) end it 'group defaults to Array type' do get '/grp', stars: 'Sun' expect(last_response.status).to eq(400) expect(last_response.body).to eq('stars is invalid') get '/grp', stars: { name: 'Sun' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('stars is invalid') get '/grp', stars: [{ name: 'Sun' }] expect(last_response.status).to eq(200) put_with_json '/grp', stars: [] expect(last_response.status).to eq(200) end end context 'validation within arrays with JSON' do before do subject.params do group :children, type: Array do requires :name group :parents, type: Array do requires :name end end end subject.put '/within_array' do 'within array works' end end it 'can handle new scopes within child elements' do put_with_json '/within_array', children: [ { name: 'John', parents: [{ name: 'Jane' }, { name: 'Bob' }] }, { name: 'Joe', parents: [{ name: 'Josie' }] } ] expect(last_response.status).to eq(200) expect(last_response.body).to eq('within array works') end it 'errors when a parameter is not present' do put_with_json '/within_array', children: [ { name: 'Jim', parents: [{}] }, { name: 'Job', parents: [{ name: 'Joy' }] } ] expect(last_response.status).to eq(400) expect(last_response.body).to eq('children[0][parents][0][name] is missing') end it 'safely handles empty arrays and blank parameters' do put_with_json '/within_array', children: [] expect(last_response.status).to eq(200) put_with_json '/within_array', children: [name: 'Jay'] expect(last_response.status).to eq(400) expect(last_response.body).to eq('children[0][parents] is missing') end end context 'optional with an Array block' do before do subject.params do optional :items, type: Array do requires :key end end subject.get '/optional_group' do 'optional group works' end end it "doesn't throw a missing param when the group isn't present" do get '/optional_group' expect(last_response.status).to eq(200) expect(last_response.body).to eq('optional group works') end it "doesn't throw a missing param when both group and param are given" do get '/optional_group', items: [{ key: 'foo' }] expect(last_response.status).to eq(200) expect(last_response.body).to eq('optional group works') end it 'errors when group is present, but required param is not' do get '/optional_group', items: [{ not_key: 'foo' }] expect(last_response.status).to eq(400) expect(last_response.body).to eq('items[0][key] is missing') end it "errors when param is present but isn't an Array" do get '/optional_group', items: 'hello' expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is invalid') get '/optional_group', items: { key: 'foo' } expect(last_response.status).to eq(400) expect(last_response.body).to eq('items is invalid') end it 'adds to declared parameters' do subject.params do optional :items, type: Array do requires :key end end expect(subject.route_setting(:declared_params)).to eq([items: [:key]]) end end context 'nested optional Array blocks' do before do subject.params do optional :items, type: Array do requires :key optional(:optional_subitems, type: Array) { requires :value } requires(:required_subitems, type: Array) { requires :value } end end subject.get('/nested_optional_group') { 'nested optional group works' } end it 'does no internal validations if the outer group is blank' do get '/nested_optional_group' expect(last_response.status).to eq(200) expect(last_response.body).to eq('nested optional group works') end it 'does internal validations if the outer group is present' do get '/nested_optional_group', items: [{ key: 'foo' }] expect(last_response.status).to eq(400) expect(last_response.body).to eq('items[0][required_subitems] is missing') get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }] }] expect(last_response.status).to eq(200) expect(last_response.body).to eq('nested optional group works') end it 'handles deep nesting' do get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }], optional_subitems: [{ not_value: 'baz' }] }] expect(last_response.status).to eq(400) expect(last_response.body).to eq('items[0][optional_subitems][0][value] is missing') get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }], optional_subitems: [{ value: 'baz' }] }] expect(last_response.status).to eq(200) expect(last_response.body).to eq('nested optional group works') end it 'handles validation within arrays' do get '/nested_optional_group', items: [{ key: 'foo' }] expect(last_response.status).to eq(400) expect(last_response.body).to eq('items[0][required_subitems] is missing') get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }] }] expect(last_response.status).to eq(200) expect(last_response.body).to eq('nested optional group works') get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }], optional_subitems: [{ not_value: 'baz' }] }] expect(last_response.status).to eq(400) expect(last_response.body).to eq('items[0][optional_subitems][0][value] is missing') end it 'adds to declared parameters' do subject.params do optional :items, type: Array do requires :key optional(:optional_subitems, type: Array) { requires :value } requires(:required_subitems, type: Array) { requires :value } end end expect(subject.route_setting(:declared_params)).to eq([items: [:key, { optional_subitems: [:value] }, { required_subitems: [:value] }]]) end end context 'multiple validation errors' do before do subject.params do requires :yolo requires :swag end subject.get '/two_required' do 'two required works' end end it 'throws the validation errors' do get '/two_required' expect(last_response.status).to eq(400) expect(last_response.body).to match(/yolo is missing/) expect(last_response.body).to match(/swag is missing/) end end context 'custom validation' do module CustomValidations class Customvalidator < Grape::Validations::Base def validate_param!(attr_name, params) return if params[attr_name] == 'im custom' raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: 'is not custom!' end end end context 'when using optional with a custom validator' do before do subject.params do optional :custom, customvalidator: true end subject.get '/optional_custom' do 'optional with custom works!' end end it 'validates when param is present' do get '/optional_custom', custom: 'im custom' expect(last_response.status).to eq(200) expect(last_response.body).to eq('optional with custom works!') get '/optional_custom', custom: 'im wrong' expect(last_response.status).to eq(400) expect(last_response.body).to eq('custom is not custom!') end it "skips validation when parameter isn't present" do get '/optional_custom' expect(last_response.status).to eq(200) expect(last_response.body).to eq('optional with custom works!') end it 'validates with custom validator when param present and incorrect type' do subject.params do optional :custom, type: String, customvalidator: true end get '/optional_custom', custom: 123 expect(last_response.status).to eq(400) expect(last_response.body).to eq('custom is not custom!') end end context 'when using requires with a custom validator' do before do subject.params do requires :custom, customvalidator: true end subject.get '/required_custom' do 'required with custom works!' end end it 'validates when param is present' do get '/required_custom', custom: 'im wrong, validate me' expect(last_response.status).to eq(400) expect(last_response.body).to eq('custom is not custom!') get '/required_custom', custom: 'im custom' expect(last_response.status).to eq(200) expect(last_response.body).to eq('required with custom works!') end it 'validates when param is not present' do get '/required_custom' expect(last_response.status).to eq(400) expect(last_response.body).to eq('custom is missing, custom is not custom!') end context 'nested namespaces' do before do subject.params do requires :custom, customvalidator: true end subject.namespace 'nested' do get 'one' do 'validation failed' end namespace 'nested' do get 'two' do 'validation failed' end end end subject.namespace 'peer' do get 'one' do 'no validation required' end namespace 'nested' do get 'two' do 'no validation required' end end end subject.namespace 'unrelated' do params do requires :name end get 'one' do 'validation required' end namespace 'double' do get 'two' do 'no validation required' end end end end specify 'the parent namespace uses the validator' do get '/nested/one', custom: 'im wrong, validate me' expect(last_response.status).to eq(400) expect(last_response.body).to eq('custom is not custom!') end specify 'the nested namespace inherits the custom validator' do get '/nested/nested/two', custom: 'im wrong, validate me' expect(last_response.status).to eq(400) expect(last_response.body).to eq('custom is not custom!') end specify 'peer namespaces does not have the validator' do get '/peer/one', custom: 'im not validated' expect(last_response.status).to eq(200) expect(last_response.body).to eq('no validation required') end specify 'namespaces nested in peers should also not have the validator' do get '/peer/nested/two', custom: 'im not validated' expect(last_response.status).to eq(200) expect(last_response.body).to eq('no validation required') end specify 'when nested, specifying a route should clear out the validations for deeper nested params' do get '/unrelated/one' expect(last_response.status).to eq(400) get '/unrelated/double/two' expect(last_response.status).to eq(200) end end end context 'when using options on param' do module CustomValidations class CustomvalidatorWithOptions < Grape::Validations::Base def validate_param!(attr_name, params) return if params[attr_name] == @option[:text] raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message end end end before do subject.params do optional :custom, customvalidator_with_options: { text: 'im custom with options', message: 'is not custom with options!' } end subject.get '/optional_custom' do 'optional with custom works!' end end it 'validates param with custom validator with options' do get '/optional_custom', custom: 'im custom with options' expect(last_response.status).to eq(200) expect(last_response.body).to eq('optional with custom works!') get '/optional_custom', custom: 'im wrong' expect(last_response.status).to eq(400) expect(last_response.body).to eq('custom is not custom with options!') end end end # end custom validation context 'named' do context 'can be defined' do it 'in helpers' do subject.helpers do params :pagination do end end end it 'in helper module which kind of Grape::DSL::Helpers::BaseHelper' do shared_params = Module.new do extend Grape::DSL::Helpers::BaseHelper params :pagination do end end subject.helpers shared_params end end context 'can be included in usual params' do before do shared_params = Module.new do extend Grape::DSL::Helpers::BaseHelper params :period do optional :start_date optional :end_date end end subject.helpers shared_params subject.helpers do params :pagination do optional :page, type: Integer optional :per_page, type: Integer end end end it 'by #use' do subject.params do use :pagination end expect(subject.route_setting(:declared_params)).to eq %i[page per_page] end it 'by #use with multiple params' do subject.params do use :pagination, :period end expect(subject.route_setting(:declared_params)).to eq %i[page per_page start_date end_date] end end context 'with block' do before do subject.helpers do params :order do |options| optional :order, type: Symbol, values: %i[asc desc], default: options[:default_order] optional :order_by, type: Symbol, values: options[:order_by], default: options[:default_order_by] end end subject.format :json subject.params do use :order, default_order: :asc, order_by: %i[name created_at], default_order_by: :created_at end subject.get '/order' do { order: params[:order], order_by: params[:order_by] } end end it 'returns defaults' do get '/order' expect(last_response.status).to eq(200) expect(last_response.body).to eq({ order: :asc, order_by: :created_at }.to_json) end it 'overrides default value for order' do get '/order?order=desc' expect(last_response.status).to eq(200) expect(last_response.body).to eq({ order: :desc, order_by: :created_at }.to_json) end it 'overrides default value for order_by' do get '/order?order_by=name' expect(last_response.status).to eq(200) expect(last_response.body).to eq({ order: :asc, order_by: :name }.to_json) end it 'fails with invalid value' do get '/order?order=invalid' expect(last_response.status).to eq(400) expect(last_response.body).to eq('{"error":"order does not have a valid value"}') end end end context 'documentation' do it 'can be included with a hash' do documentation = { example: 'Joe' } subject.params do requires 'first_name', documentation: documentation end subject.get '/' do end expect(subject.routes.first.params['first_name'][:documentation]).to eq(documentation) end end context 'all or none' do context 'optional params' do before :each do subject.resource :custom_message do params do optional :beer optional :wine optional :juice all_or_none_of :beer, :wine, :juice, message: 'all params are required or none is required' end get '/all_or_none' do 'all_or_none works!' end end end context 'with a custom validation message' do it 'errors when any one is present' do get '/custom_message/all_or_none', beer: 'string' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine, juice all params are required or none is required' end it 'works when all params are present' do get '/custom_message/all_or_none', beer: 'string', wine: 'anotherstring', juice: 'anotheranotherstring' expect(last_response.status).to eq(200) expect(last_response.body).to eq 'all_or_none works!' end it 'works when none are present' do get '/custom_message/all_or_none' expect(last_response.status).to eq(200) expect(last_response.body).to eq 'all_or_none works!' end end end end context 'mutually exclusive' do context 'optional params' do context 'with custom validation message' do it 'errors when two or more are present' do subject.resources :custom_message do params do optional :beer optional :wine optional :juice mutually_exclusive :beer, :wine, :juice, message: 'are mutually exclusive cannot pass both params' end get '/mutually_exclusive' do 'mutually_exclusive works!' end end get '/custom_message/mutually_exclusive', beer: 'string', wine: 'anotherstring' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine are mutually exclusive cannot pass both params' end end it 'errors when two or more are present' do subject.params do optional :beer optional :wine optional :juice mutually_exclusive :beer, :wine, :juice end subject.get '/mutually_exclusive' do 'mutually_exclusive works!' end get '/mutually_exclusive', beer: 'string', wine: 'anotherstring' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine are mutually exclusive' end end context 'more than one set of mutually exclusive params' do context 'with a custom validation message' do it 'errors for all sets' do subject.resources :custom_message do params do optional :beer optional :wine mutually_exclusive :beer, :wine, message: 'are mutually exclusive pass only one' optional :nested, type: Hash do optional :scotch optional :aquavit mutually_exclusive :scotch, :aquavit, message: 'are mutually exclusive pass only one' end optional :nested2, type: Array do optional :scotch2 optional :aquavit2 mutually_exclusive :scotch2, :aquavit2, message: 'are mutually exclusive pass only one' end end get '/mutually_exclusive' do 'mutually_exclusive works!' end end get '/custom_message/mutually_exclusive', beer: 'true', wine: 'true', nested: { scotch: 'true', aquavit: 'true' }, nested2: [{ scotch2: 'true' }, { scotch2: 'true', aquavit2: 'true' }] expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine are mutually exclusive pass only one, scotch, aquavit are mutually exclusive pass only one, scotch2, aquavit2 are mutually exclusive pass only one' end end it 'errors for all sets' do subject.params do optional :beer optional :wine mutually_exclusive :beer, :wine optional :nested, type: Hash do optional :scotch optional :aquavit mutually_exclusive :scotch, :aquavit end optional :nested2, type: Array do optional :scotch2 optional :aquavit2 mutually_exclusive :scotch2, :aquavit2 end end subject.get '/mutually_exclusive' do 'mutually_exclusive works!' end get '/mutually_exclusive', beer: 'true', wine: 'true', nested: { scotch: 'true', aquavit: 'true' }, nested2: [{ scotch2: 'true' }, { scotch2: 'true', aquavit2: 'true' }] expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine are mutually exclusive, scotch, aquavit are mutually exclusive, scotch2, aquavit2 are mutually exclusive' end end context 'in a group' do it 'works when only one from the set is present' do subject.params do group :drink, type: Hash do optional :wine optional :beer optional :juice mutually_exclusive :beer, :wine, :juice end end subject.get '/mutually_exclusive_group' do 'mutually_exclusive_group works!' end get '/mutually_exclusive_group', drink: { beer: 'true' } expect(last_response.status).to eq(200) end it 'errors when more than one from the set is present' do subject.params do group :drink, type: Hash do optional :wine optional :beer optional :juice mutually_exclusive :beer, :wine, :juice end end subject.get '/mutually_exclusive_group' do 'mutually_exclusive_group works!' end get '/mutually_exclusive_group', drink: { beer: 'true', juice: 'true', wine: 'true' } expect(last_response.status).to eq(400) end end context 'mutually exclusive params inside Hash group' do it 'invalidates if request param is invalid type' do subject.params do optional :wine, type: Hash do optional :grape optional :country mutually_exclusive :grape, :country end end subject.post '/mutually_exclusive' do 'mutually_exclusive works!' end post '/mutually_exclusive', wine: '2015 sauvignon' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'wine is invalid' end end end context 'exactly one of' do context 'params' do before :each do subject.resources :custom_message do params do optional :beer optional :wine optional :juice exactly_one_of :beer, :wine, :juice, message: { exactly_one: 'are missing, exactly one parameter is required', mutual_exclusion: 'are mutually exclusive, exactly one parameter is required' } end get '/exactly_one_of' do 'exactly_one_of works!' end end subject.params do optional :beer optional :wine optional :juice exactly_one_of :beer, :wine, :juice end subject.get '/exactly_one_of' do 'exactly_one_of works!' end end context 'with a custom validation message' do it 'errors when none are present' do get '/custom_message/exactly_one_of' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine, juice are missing, exactly one parameter is required' end it 'succeeds when one is present' do get '/custom_message/exactly_one_of', beer: 'string' expect(last_response.status).to eq(200) expect(last_response.body).to eq 'exactly_one_of works!' end it 'errors when two or more are present' do get '/custom_message/exactly_one_of', beer: 'string', wine: 'anotherstring' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine are mutually exclusive, exactly one parameter is required' end end it 'errors when none are present' do get '/exactly_one_of' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine, juice are missing, exactly one parameter must be provided' end it 'succeeds when one is present' do get '/exactly_one_of', beer: 'string' expect(last_response.status).to eq(200) expect(last_response.body).to eq 'exactly_one_of works!' end it 'errors when two or more are present' do get '/exactly_one_of', beer: 'string', wine: 'anotherstring' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine are mutually exclusive' end end context 'nested params' do before :each do subject.params do requires :nested, type: Hash do optional :beer_nested optional :wine_nested optional :juice_nested exactly_one_of :beer_nested, :wine_nested, :juice_nested end optional :nested2, type: Array do optional :beer_nested2 optional :wine_nested2 optional :juice_nested2 exactly_one_of :beer_nested2, :wine_nested2, :juice_nested2 end end subject.get '/exactly_one_of_nested' do 'exactly_one_of works!' end end it 'errors when none are present' do get '/exactly_one_of_nested' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'nested is missing, beer_nested, wine_nested, juice_nested are missing, exactly one parameter must be provided' end it 'succeeds when one is present' do get '/exactly_one_of_nested', nested: { beer_nested: 'string' } expect(last_response.status).to eq(200) expect(last_response.body).to eq 'exactly_one_of works!' end it 'errors when two or more are present' do get '/exactly_one_of_nested', nested: { beer_nested: 'string' }, nested2: [{ beer_nested2: 'string', wine_nested2: 'anotherstring' }] expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer_nested2, wine_nested2 are mutually exclusive' end end end context 'at least one of' do context 'params' do before :each do subject.resources :custom_message do params do optional :beer optional :wine optional :juice at_least_one_of :beer, :wine, :juice, message: 'are missing, please specify at least one param' end get '/at_least_one_of' do 'at_least_one_of works!' end end subject.params do optional :beer optional :wine optional :juice at_least_one_of :beer, :wine, :juice end subject.get '/at_least_one_of' do 'at_least_one_of works!' end end context 'with a custom validation message' do it 'errors when none are present' do get '/custom_message/at_least_one_of' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine, juice are missing, please specify at least one param' end it 'does not error when one is present' do get '/custom_message/at_least_one_of', beer: 'string' expect(last_response.status).to eq(200) expect(last_response.body).to eq 'at_least_one_of works!' end it 'does not error when two are present' do get '/custom_message/at_least_one_of', beer: 'string', wine: 'string' expect(last_response.status).to eq(200) expect(last_response.body).to eq 'at_least_one_of works!' end end it 'errors when none are present' do get '/at_least_one_of' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'beer, wine, juice are missing, at least one parameter must be provided' end it 'does not error when one is present' do get '/at_least_one_of', beer: 'string' expect(last_response.status).to eq(200) expect(last_response.body).to eq 'at_least_one_of works!' end it 'does not error when two are present' do get '/at_least_one_of', beer: 'string', wine: 'string' expect(last_response.status).to eq(200) expect(last_response.body).to eq 'at_least_one_of works!' end end context 'nested params' do before :each do subject.params do requires :nested, type: Hash do optional :beer_nested optional :wine_nested optional :juice_nested at_least_one_of :beer_nested, :wine_nested, :juice_nested end optional :nested2, type: Array do optional :beer_nested2 optional :wine_nested2 optional :juice_nested2 at_least_one_of :beer_nested2, :wine_nested2, :juice_nested2 end end subject.get '/at_least_one_of_nested' do 'at_least_one_of works!' end end it 'errors when none are present' do get '/at_least_one_of_nested' expect(last_response.status).to eq(400) expect(last_response.body).to eq 'nested is missing, beer_nested, wine_nested, juice_nested are missing, at least one parameter must be provided' end it 'does not error when one is present' do get '/at_least_one_of_nested', nested: { beer_nested: 'string' }, nested2: [{ beer_nested2: 'string' }] expect(last_response.status).to eq(200) expect(last_response.body).to eq 'at_least_one_of works!' end it 'does not error when two are present' do get '/at_least_one_of_nested', nested: { beer_nested: 'string', wine_nested: 'string' }, nested2: [{ beer_nested2: 'string', wine_nested2: 'string' }] expect(last_response.status).to eq(200) expect(last_response.body).to eq 'at_least_one_of works!' end end end context 'in a group' do it 'works when only one from the set is present' do subject.params do group :drink, type: Hash do optional :wine optional :beer optional :juice exactly_one_of :beer, :wine, :juice end end subject.get '/exactly_one_of_group' do 'exactly_one_of_group works!' end get '/exactly_one_of_group', drink: { beer: 'true' } expect(last_response.status).to eq(200) end it 'errors when no parameter from the set is present' do subject.params do group :drink, type: Hash do optional :wine optional :beer optional :juice exactly_one_of :beer, :wine, :juice end end subject.get '/exactly_one_of_group' do 'exactly_one_of_group works!' end get '/exactly_one_of_group', drink: {} expect(last_response.status).to eq(400) end it 'errors when more than one from the set is present' do subject.params do group :drink, type: Hash do optional :wine optional :beer optional :juice exactly_one_of :beer, :wine, :juice end end subject.get '/exactly_one_of_group' do 'exactly_one_of_group works!' end get '/exactly_one_of_group', drink: { beer: 'true', juice: 'true', wine: 'true' } expect(last_response.status).to eq(400) end it 'does not falsely think the param is there if it is provided outside the block' do subject.params do group :drink, type: Hash do optional :wine optional :beer optional :juice exactly_one_of :beer, :wine, :juice end end subject.get '/exactly_one_of_group' do 'exactly_one_of_group works!' end get '/exactly_one_of_group', drink: { foo: 'bar' }, beer: 'true' expect(last_response.status).to eq(400) end end end end grape-1.0.2/spec/grape/extensions/0000755000004100000410000000000013231337007017066 5ustar www-datawww-datagrape-1.0.2/spec/grape/extensions/param_builders/0000755000004100000410000000000013231337007022057 5ustar www-datawww-datagrape-1.0.2/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb0000644000004100000410000000542313231337007031276 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder do subject { Class.new(Grape::API) } def app subject end describe 'in an endpoint' do context '#params' do before do subject.params do build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder end subject.get do params.class end end it 'should be of type Hash' do get '/' expect(last_response.status).to eq(200) expect(last_response.body).to eq('ActiveSupport::HashWithIndifferentAccess') end end end describe 'in an api' do before do subject.send(:include, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder) end context '#params' do before do subject.get do params.class end end it 'is a Hash' do get '/' expect(last_response.status).to eq(200) expect(last_response.body).to eq('ActiveSupport::HashWithIndifferentAccess') end it 'parses sub hash params' do subject.params do build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder optional :a, type: Hash do optional :b, type: Hash do optional :c, type: String end optional :d, type: Array end end subject.get '/foo' do [params[:a]['b'][:c], params['a'][:d]] end get '/foo', a: { b: { c: 'bar' }, d: ['foo'] } expect(last_response.status).to eq(200) expect(last_response.body).to eq('["bar", ["foo"]]') end it 'params are indifferent to symbol or string keys' do subject.params do build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder optional :a, type: Hash do optional :b, type: Hash do optional :c, type: String end optional :d, type: Array end end subject.get '/foo' do [params[:a]['b'][:c], params['a'][:d]] end get '/foo', 'a' => { b: { c: 'bar' }, 'd' => ['foo'] } expect(last_response.status).to eq(200) expect(last_response.body).to eq('["bar", ["foo"]]') end it 'responds to string keys' do subject.params do build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder requires :a, type: String end subject.get '/foo' do [params[:a], params['a']] end get '/foo', a: 'bar' expect(last_response.status).to eq(200) expect(last_response.body).to eq('["bar", "bar"]') end end end end grape-1.0.2/spec/grape/extensions/param_builders/hashie/0000755000004100000410000000000013231337007023320 5ustar www-datawww-datagrape-1.0.2/spec/grape/extensions/param_builders/hashie/mash_spec.rb0000644000004100000410000000333213231337007025610 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Extensions::Hashie::Mash::ParamBuilder do subject { Class.new(Grape::API) } def app subject end describe 'in an endpoint' do context '#params' do before do subject.params do build_with Grape::Extensions::Hashie::Mash::ParamBuilder end subject.get do params.class end end it 'should be of type Hashie::Mash' do get '/' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hashie::Mash') end end end describe 'in an api' do before do subject.send(:include, Grape::Extensions::Hashie::Mash::ParamBuilder) end context '#params' do before do subject.get do params.class end end it 'should be Hashie::Mash' do get '/' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hashie::Mash') end end context 'in a nested namespace api' do before do subject.namespace :foo do get do params.class end end end it 'should be Hashie::Mash' do get '/foo' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hashie::Mash') end end it 'is indifferent to key or symbol access' do subject.params do build_with Grape::Extensions::Hashie::Mash::ParamBuilder requires :a, type: String end subject.get '/foo' do [params[:a], params['a']] end get '/foo', a: 'bar' expect(last_response.status).to eq(200) expect(last_response.body).to eq('["bar", "bar"]') end end end grape-1.0.2/spec/grape/extensions/param_builders/hash_spec.rb0000644000004100000410000000343413231337007024345 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Extensions::Hash::ParamBuilder do subject { Class.new(Grape::API) } def app subject end describe 'in an endpoint' do context '#params' do before do subject.params do build_with Grape::Extensions::Hash::ParamBuilder end subject.get do params.class end end it 'should be of type Hash' do get '/' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hash') end end end describe 'in an api' do before do subject.send(:include, Grape::Extensions::Hash::ParamBuilder) end context '#params' do before do subject.get do params.class end end it 'should be Hash' do get '/' expect(last_response.status).to eq(200) expect(last_response.body).to eq('Hash') end end it 'symbolizes params keys' do subject.params do optional :a, type: Hash do optional :b, type: Hash do optional :c, type: String end optional :d, type: Array end end subject.get '/foo' do [params[:a][:b][:c], params[:a][:d]] end get '/foo', 'a' => { b: { c: 'bar' }, 'd' => ['foo'] } expect(last_response.status).to eq(200) expect(last_response.body).to eq('["bar", ["foo"]]') end it 'symbolizes the params' do subject.params do build_with Grape::Extensions::Hash::ParamBuilder requires :a, type: String end subject.get '/foo' do [params[:a], params['a']] end get '/foo', a: 'bar' expect(last_response.status).to eq(200) expect(last_response.body).to eq('["bar", nil]') end end end grape-1.0.2/spec/grape/util/0000755000004100000410000000000013231337007015644 5ustar www-datawww-datagrape-1.0.2/spec/grape/util/reverse_stackable_values_spec.rb0000644000004100000410000000764713231337007024264 0ustar www-datawww-datarequire 'spec_helper' module Grape module Util describe ReverseStackableValues do let(:parent) { described_class.new } subject { described_class.new(parent) } describe '#keys' do it 'returns all keys' do subject[:some_thing] = :foo_bar subject[:some_thing_else] = :foo_bar expect(subject.keys).to eq %i[some_thing some_thing_else].sort end it 'returns merged keys with parent' do parent[:some_thing] = :foo parent[:some_thing_else] = :foo subject[:some_thing] = :foo_bar subject[:some_thing_more] = :foo_bar expect(subject.keys).to eq %i[some_thing some_thing_else some_thing_more].sort end end describe '#delete' do it 'deletes a key' do subject[:some_thing] = :new_foo_bar subject.delete :some_thing expect(subject[:some_thing]).to eq [] end it 'does not delete parent values' do parent[:some_thing] = :foo subject[:some_thing] = :new_foo_bar subject.delete :some_thing expect(subject[:some_thing]).to eq [:foo] end end describe '#[]' do it 'returns an array of values' do subject[:some_thing] = :foo expect(subject[:some_thing]).to eq [:foo] end it 'returns parent value when no value is set' do parent[:some_thing] = :foo expect(subject[:some_thing]).to eq [:foo] end it 'combines parent and actual values (actual first)' do parent[:some_thing] = :foo subject[:some_thing] = :foo_bar expect(subject[:some_thing]).to eq %i[foo_bar foo] end it 'parent values are not changed' do parent[:some_thing] = :foo subject[:some_thing] = :foo_bar expect(parent[:some_thing]).to eq [:foo] end end describe '#[]=' do it 'sets a value' do subject[:some_thing] = :foo expect(subject[:some_thing]).to eq [:foo] end it 'pushes further values' do subject[:some_thing] = :foo subject[:some_thing] = :bar expect(subject[:some_thing]).to eq %i[foo bar] end it 'can handle array values' do subject[:some_thing] = :foo subject[:some_thing] = %i[bar more] expect(subject[:some_thing]).to eq [:foo, %i[bar more]] parent[:some_thing_else] = %i[foo bar] subject[:some_thing_else] = %i[some bar foo] expect(subject[:some_thing_else]).to eq [%i[some bar foo], %i[foo bar]] end end describe '#to_hash' do it 'returns a Hash representation' do parent[:some_thing] = :foo subject[:some_thing] = %i[bar more] subject[:some_thing_more] = :foo_bar expect(subject.to_hash).to eq( some_thing: [%i[bar more], :foo], some_thing_more: [:foo_bar] ) end end describe '#clone' do let(:obj_cloned) { subject.clone } it 'copies all values' do parent = described_class.new child = described_class.new parent grandchild = described_class.new child parent[:some_thing] = :foo child[:some_thing] = %i[bar more] grandchild[:some_thing] = :grand_foo_bar grandchild[:some_thing_more] = :foo_bar expect(grandchild.clone.to_hash).to eq( some_thing: [:grand_foo_bar, %i[bar more], :foo], some_thing_more: [:foo_bar] ) end context 'complex (i.e. not primitive) data types (ex. middleware, please see bug #930)' do let(:middleware) { double } before { subject[:middleware] = middleware } it 'copies values; does not duplicate them' do expect(obj_cloned[:middleware]).to eq [middleware] end end end end end end grape-1.0.2/spec/grape/util/inheritable_values_spec.rb0000644000004100000410000000426413231337007023056 0ustar www-datawww-datarequire 'spec_helper' module Grape module Util describe InheritableValues do let(:parent) { InheritableValues.new } subject { InheritableValues.new(parent) } describe '#delete' do it 'deletes a key' do subject[:some_thing] = :new_foo_bar subject.delete :some_thing expect(subject[:some_thing]).to be_nil end it 'does not delete parent values' do parent[:some_thing] = :foo subject[:some_thing] = :new_foo_bar subject.delete :some_thing expect(subject[:some_thing]).to eq :foo end end describe '#[]' do it 'returns a value' do subject[:some_thing] = :foo expect(subject[:some_thing]).to eq :foo end it 'returns parent value when no value is set' do parent[:some_thing] = :foo expect(subject[:some_thing]).to eq :foo end it 'overwrites parent value with the current one' do parent[:some_thing] = :foo subject[:some_thing] = :foo_bar expect(subject[:some_thing]).to eq :foo_bar end it 'parent values are not changed' do parent[:some_thing] = :foo subject[:some_thing] = :foo_bar expect(parent[:some_thing]).to eq :foo end end describe '#[]=' do it 'sets a value' do subject[:some_thing] = :foo expect(subject[:some_thing]).to eq :foo end end describe '#to_hash' do it 'returns a Hash representation' do parent[:some_thing] = :foo subject[:some_thing_more] = :foo_bar expect(subject.to_hash).to eq(some_thing: :foo, some_thing_more: :foo_bar) end end describe '#clone' do let(:obj_cloned) { subject.clone } context 'complex (i.e. not primitive) data types (ex. entity classes, please see bug #891)' do let(:description) { { entity: double } } before { subject[:description] = description } it 'copies values; does not duplicate them' do expect(obj_cloned[:description]).to eq description end end end end end end grape-1.0.2/spec/grape/util/inheritable_setting_spec.rb0000644000004100000410000002406313231337007023233 0ustar www-datawww-datarequire 'spec_helper' module Grape module Util describe InheritableSetting do before :each do InheritableSetting.reset_global! end let(:parent) do Grape::Util::InheritableSetting.new.tap do |settings| settings.global[:global_thing] = :global_foo_bar settings.namespace[:namespace_thing] = :namespace_foo_bar settings.namespace_inheritable[:namespace_inheritable_thing] = :namespace_inheritable_foo_bar settings.namespace_stackable[:namespace_stackable_thing] = :namespace_stackable_foo_bar settings.namespace_reverse_stackable[:namespace_reverse_stackable_thing] = :namespace_reverse_stackable_foo_bar settings.route[:route_thing] = :route_foo_bar end end let(:other_parent) do Grape::Util::InheritableSetting.new.tap do |settings| settings.namespace[:namespace_thing] = :namespace_foo_bar_other settings.namespace_inheritable[:namespace_inheritable_thing] = :namespace_inheritable_foo_bar_other settings.namespace_stackable[:namespace_stackable_thing] = :namespace_stackable_foo_bar_other settings.namespace_reverse_stackable[:namespace_reverse_stackable_thing] = :namespace_reverse_stackable_foo_bar_other settings.route[:route_thing] = :route_foo_bar_other end end before :each do subject.inherit_from parent end describe '#global' do it 'sets a global value' do subject.global[:some_thing] = :foo_bar expect(subject.global[:some_thing]).to eq :foo_bar subject.global[:some_thing] = :foo_bar_next expect(subject.global[:some_thing]).to eq :foo_bar_next end it 'sets the global inherited values' do expect(subject.global[:global_thing]).to eq :global_foo_bar end it 'overrides global values' do subject.global[:global_thing] = :global_new_foo_bar expect(parent.global[:global_thing]).to eq :global_new_foo_bar end it 'should handle different parents' do subject.global[:global_thing] = :global_new_foo_bar subject.inherit_from other_parent expect(parent.global[:global_thing]).to eq :global_new_foo_bar expect(other_parent.global[:global_thing]).to eq :global_new_foo_bar end end describe '#api_class' do it 'is specific to the class' do subject.api_class[:some_thing] = :foo_bar parent.api_class[:some_thing] = :some_thing expect(subject.api_class[:some_thing]).to eq :foo_bar expect(parent.api_class[:some_thing]).to eq :some_thing end end describe '#namespace' do it 'sets a value until the end of a namespace' do subject.namespace[:some_thing] = :foo_bar expect(subject.namespace[:some_thing]).to eq :foo_bar end it 'uses new values when a new namespace starts' do subject.namespace[:namespace_thing] = :new_namespace_foo_bar expect(subject.namespace[:namespace_thing]).to eq :new_namespace_foo_bar expect(parent.namespace[:namespace_thing]).to eq :namespace_foo_bar end end describe '#namespace_inheritable' do it 'works with inheritable values' do expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar end it 'should handle different parents' do expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar subject.inherit_from other_parent expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar_other subject.inherit_from parent expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar subject.inherit_from other_parent subject.namespace_inheritable[:namespace_inheritable_thing] = :my_thing expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :my_thing subject.inherit_from parent expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :my_thing end end describe '#namespace_stackable' do it 'works with stackable values' do expect(subject.namespace_stackable[:namespace_stackable_thing]).to eq [:namespace_stackable_foo_bar] subject.inherit_from other_parent expect(subject.namespace_stackable[:namespace_stackable_thing]).to eq [:namespace_stackable_foo_bar_other] end end describe '#namespace_reverse_stackable' do it 'works with reverse stackable values' do expect(subject.namespace_reverse_stackable[:namespace_reverse_stackable_thing]).to eq [:namespace_reverse_stackable_foo_bar] subject.inherit_from other_parent expect(subject.namespace_reverse_stackable[:namespace_reverse_stackable_thing]).to eq [:namespace_reverse_stackable_foo_bar_other] end end describe '#route' do it 'sets a value until the next route' do subject.route[:some_thing] = :foo_bar expect(subject.route[:some_thing]).to eq :foo_bar subject.route_end expect(subject.route[:some_thing]).to be_nil end it 'works with route values' do expect(subject.route[:route_thing]).to eq :route_foo_bar end end describe '#api_class' do it 'is specific to the class' do subject.api_class[:some_thing] = :foo_bar expect(subject.api_class[:some_thing]).to eq :foo_bar end end describe '#inherit_from' do it 'notifies clones' do new_settings = subject.point_in_time_copy expect(new_settings).to receive(:inherit_from).with(other_parent) subject.inherit_from other_parent end end describe '#point_in_time_copy' do let!(:cloned_obj) { subject.point_in_time_copy } it 'resets point_in_time_copies' do expect(cloned_obj.point_in_time_copies).to be_empty end it 'decouples namespace values' do subject.namespace[:namespace_thing] = :namespace_foo_bar cloned_obj.namespace[:namespace_thing] = :new_namespace_foo_bar expect(subject.namespace[:namespace_thing]).to eq :namespace_foo_bar end it 'decouples namespace inheritable values' do expect(cloned_obj.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar subject.namespace_inheritable[:namespace_inheritable_thing] = :my_thing expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :my_thing expect(cloned_obj.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar cloned_obj.namespace_inheritable[:namespace_inheritable_thing] = :my_cloned_thing expect(cloned_obj.namespace_inheritable[:namespace_inheritable_thing]).to eq :my_cloned_thing expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :my_thing end it 'decouples namespace stackable values' do expect(cloned_obj.namespace_stackable[:namespace_stackable_thing]).to eq [:namespace_stackable_foo_bar] subject.namespace_stackable[:namespace_stackable_thing] = :other_thing expect(subject.namespace_stackable[:namespace_stackable_thing]).to eq %i[namespace_stackable_foo_bar other_thing] expect(cloned_obj.namespace_stackable[:namespace_stackable_thing]).to eq [:namespace_stackable_foo_bar] end it 'decouples namespace reverse stackable values' do expect(cloned_obj.namespace_reverse_stackable[:namespace_reverse_stackable_thing]).to eq [:namespace_reverse_stackable_foo_bar] subject.namespace_reverse_stackable[:namespace_reverse_stackable_thing] = :other_thing expect(subject.namespace_reverse_stackable[:namespace_reverse_stackable_thing]).to eq %i[other_thing namespace_reverse_stackable_foo_bar] expect(cloned_obj.namespace_reverse_stackable[:namespace_reverse_stackable_thing]).to eq [:namespace_reverse_stackable_foo_bar] end it 'decouples route values' do expect(cloned_obj.route[:route_thing]).to eq :route_foo_bar subject.route[:route_thing] = :new_route_foo_bar expect(cloned_obj.route[:route_thing]).to eq :route_foo_bar end it 'adds itself to original as clone' do expect(subject.point_in_time_copies).to include(cloned_obj) end end describe '#to_hash' do it 'return all settings as a hash' do subject.global[:global_thing] = :global_foo_bar subject.namespace[:namespace_thing] = :namespace_foo_bar subject.namespace_inheritable[:namespace_inheritable_thing] = :namespace_inheritable_foo_bar subject.namespace_stackable[:namespace_stackable_thing] = [:namespace_stackable_foo_bar] subject.namespace_reverse_stackable[:namespace_reverse_stackable_thing] = [:namespace_reverse_stackable_foo_bar] subject.route[:route_thing] = :route_foo_bar expect(subject.to_hash).to include(global: { global_thing: :global_foo_bar }) expect(subject.to_hash).to include(namespace: { namespace_thing: :namespace_foo_bar }) expect(subject.to_hash).to include(namespace_inheritable: { namespace_inheritable_thing: :namespace_inheritable_foo_bar }) expect(subject.to_hash).to include(namespace_stackable: { namespace_stackable_thing: [:namespace_stackable_foo_bar, [:namespace_stackable_foo_bar]] }) expect(subject.to_hash).to include(namespace_reverse_stackable: { namespace_reverse_stackable_thing: [[:namespace_reverse_stackable_foo_bar], :namespace_reverse_stackable_foo_bar] }) expect(subject.to_hash).to include(route: { route_thing: :route_foo_bar }) end end end end end grape-1.0.2/spec/grape/util/stackable_values_spec.rb0000644000004100000410000000751013231337007022516 0ustar www-datawww-datarequire 'spec_helper' module Grape module Util describe StackableValues do let(:parent) { StackableValues.new } subject { StackableValues.new(parent) } describe '#keys' do it 'returns all key' do subject[:some_thing] = :foo_bar subject[:some_thing_else] = :foo_bar expect(subject.keys).to eq %i[some_thing some_thing_else].sort end it 'returns merged keys with parent' do parent[:some_thing] = :foo parent[:some_thing_else] = :foo subject[:some_thing] = :foo_bar subject[:some_thing_more] = :foo_bar expect(subject.keys).to eq %i[some_thing some_thing_else some_thing_more].sort end end describe '#delete' do it 'deletes a key' do subject[:some_thing] = :new_foo_bar subject.delete :some_thing expect(subject[:some_thing]).to eq [] end it 'does not delete parent values' do parent[:some_thing] = :foo subject[:some_thing] = :new_foo_bar subject.delete :some_thing expect(subject[:some_thing]).to eq [:foo] end end describe '#[]' do it 'returns an array of values' do subject[:some_thing] = :foo expect(subject[:some_thing]).to eq [:foo] end it 'returns parent value when no value is set' do parent[:some_thing] = :foo expect(subject[:some_thing]).to eq [:foo] end it 'combines parent and actual values' do parent[:some_thing] = :foo subject[:some_thing] = :foo_bar expect(subject[:some_thing]).to eq %i[foo foo_bar] end it 'parent values are not changed' do parent[:some_thing] = :foo subject[:some_thing] = :foo_bar expect(parent[:some_thing]).to eq [:foo] end end describe '#[]=' do it 'sets a value' do subject[:some_thing] = :foo expect(subject[:some_thing]).to eq [:foo] end it 'pushes further values' do subject[:some_thing] = :foo subject[:some_thing] = :bar expect(subject[:some_thing]).to eq %i[foo bar] end it 'can handle array values' do subject[:some_thing] = :foo subject[:some_thing] = %i[bar more] expect(subject[:some_thing]).to eq [:foo, %i[bar more]] parent[:some_thing_else] = %i[foo bar] subject[:some_thing_else] = %i[some bar foo] expect(subject[:some_thing_else]).to eq [%i[foo bar], %i[some bar foo]] end end describe '#to_hash' do it 'returns a Hash representation' do parent[:some_thing] = :foo subject[:some_thing] = %i[bar more] subject[:some_thing_more] = :foo_bar expect(subject.to_hash).to eq(some_thing: [:foo, %i[bar more]], some_thing_more: [:foo_bar]) end end describe '#clone' do let(:obj_cloned) { subject.clone } it 'copies all values' do parent = StackableValues.new child = StackableValues.new parent grandchild = StackableValues.new child parent[:some_thing] = :foo child[:some_thing] = %i[bar more] grandchild[:some_thing] = :grand_foo_bar grandchild[:some_thing_more] = :foo_bar expect(grandchild.clone.to_hash).to eq(some_thing: [:foo, %i[bar more], :grand_foo_bar], some_thing_more: [:foo_bar]) end context 'complex (i.e. not primitive) data types (ex. middleware, please see bug #930)' do let(:middleware) { double } before { subject[:middleware] = middleware } it 'copies values; does not duplicate them' do expect(obj_cloned[:middleware]).to eq [middleware] end end end end end end grape-1.0.2/spec/grape/util/strict_hash_configuration_spec.rb0000644000004100000410000000165613231337007024455 0ustar www-datawww-datarequire 'spec_helper' module Grape module Util describe 'StrictHashConfiguration' do subject do Class.new do include Grape::Util::StrictHashConfiguration.module(:config1, :config2, config3: [:config4], config5: [config6: %i[config7 config8]]) end end it 'set nested configs' do subject.configure do config1 'alpha' config2 'beta' config3 do config4 'gamma' end local_var = 8 config5 do config6 do config7 7 config8 local_var end end end expect(subject.settings).to eq(config1: 'alpha', config2: 'beta', config3: { config4: 'gamma' }, config5: { config6: { config7: 7, config8: 8 } }) end end end end grape-1.0.2/spec/grape/path_spec.rb0000644000004100000410000001635213231337007017171 0ustar www-datawww-datarequire 'spec_helper' module Grape describe Path do describe '#initialize' do it 'remembers the path' do path = Path.new('/:id', anything, anything) expect(path.raw_path).to eql('/:id') end it 'remembers the namespace' do path = Path.new(anything, '/users', anything) expect(path.namespace).to eql('/users') end it 'remebers the settings' do path = Path.new(anything, anything, foo: 'bar') expect(path.settings).to eql(foo: 'bar') end end describe '#mount_path' do it 'is nil when no mount path setting exists' do path = Path.new(anything, anything, {}) expect(path.mount_path).to be_nil end it 'is nil when the mount path is nil' do path = Path.new(anything, anything, mount_path: nil) expect(path.mount_path).to be_nil end it 'splits the mount path' do path = Path.new(anything, anything, mount_path: %w[foo bar]) expect(path.mount_path).to eql(%w[foo bar]) end end describe '#root_prefix' do it 'is nil when no root prefix setting exists' do path = Path.new(anything, anything, {}) expect(path.root_prefix).to be_nil end it 'is nil when the mount path is nil' do path = Path.new(anything, anything, root_prefix: nil) expect(path.root_prefix).to be_nil end it 'splits the mount path' do path = Path.new(anything, anything, root_prefix: 'hello/world') expect(path.root_prefix).to eql(%w[hello world]) end end describe '#uses_path_versioning?' do it 'is false when the version setting is nil' do path = Path.new(anything, anything, version: nil) expect(path.uses_path_versioning?).to be false end it 'is false when the version option is header' do path = Path.new( anything, anything, version: 'v1', version_options: { using: :header } ) expect(path.uses_path_versioning?).to be false end it 'is true when the version option is path' do path = Path.new( anything, anything, version: 'v1', version_options: { using: :path } ) expect(path.uses_path_versioning?).to be true end end describe '#namespace?' do it 'is false when the namespace is nil' do path = Path.new(anything, nil, anything) expect(path.namespace?).to be nil end it 'is false when the namespace starts with whitespace' do path = Path.new(anything, ' /foo', anything) expect(path.namespace?).to be nil end it 'is false when the namespace is the root path' do path = Path.new(anything, '/', anything) expect(path.namespace?).to be false end it 'is true otherwise' do path = Path.new(anything, '/world', anything) expect(path.namespace?).to be true end end describe '#path?' do it 'is false when the path is nil' do path = Path.new(nil, anything, anything) expect(path.path?).to be nil end it 'is false when the path starts with whitespace' do path = Path.new(' /foo', anything, anything) expect(path.path?).to be nil end it 'is false when the path is the root path' do path = Path.new('/', anything, anything) expect(path.path?).to be false end it 'is true otherwise' do path = Path.new('/hello', anything, anything) expect(path.path?).to be true end end describe '#path' do context 'mount_path' do it 'is not included when it is nil' do path = Path.new(nil, nil, mount_path: '/foo/bar') expect(path.path).to eql '/foo/bar' end it 'is included when it is not nil' do path = Path.new(nil, nil, {}) expect(path.path).to eql('/') end end context 'root_prefix' do it 'is not included when it is nil' do path = Path.new(nil, nil, {}) expect(path.path).to eql('/') end it 'is included after the mount path' do path = Path.new( nil, nil, mount_path: '/foo', root_prefix: '/hello' ) expect(path.path).to eql('/foo/hello') end end it 'uses the namespace after the mount path and root prefix' do path = Path.new( nil, 'namespace', mount_path: '/foo', root_prefix: '/hello' ) expect(path.path).to eql('/foo/hello/namespace') end it 'uses the raw path after the namespace' do path = Path.new( 'raw_path', 'namespace', mount_path: '/foo', root_prefix: '/hello' ) expect(path.path).to eql('/foo/hello/namespace/raw_path') end end describe '#suffix' do context 'when using a specific format' do it 'accepts specified format' do path = Path.new(nil, nil, {}) allow(path).to receive(:uses_specific_format?) { true } allow(path).to receive(:settings) { { format: :json } } expect(path.suffix).to eql('(.json)') end end context 'when path versioning is used' do it "includes a '/'" do path = Path.new(nil, nil, {}) allow(path).to receive(:uses_specific_format?) { false } allow(path).to receive(:uses_path_versioning?) { true } expect(path.suffix).to eql('(/.:format)') end end context 'when path versioning is not used' do it "does not include a '/' when the path has a namespace" do path = Path.new(nil, 'namespace', {}) allow(path).to receive(:uses_specific_format?) { false } allow(path).to receive(:uses_path_versioning?) { true } expect(path.suffix).to eql('(.:format)') end it "does not include a '/' when the path has a path" do path = Path.new('/path', nil, {}) allow(path).to receive(:uses_specific_format?) { false } allow(path).to receive(:uses_path_versioning?) { true } expect(path.suffix).to eql('(.:format)') end it "includes a '/' otherwise" do path = Path.new(nil, nil, {}) allow(path).to receive(:uses_specific_format?) { false } allow(path).to receive(:uses_path_versioning?) { true } expect(path.suffix).to eql('(/.:format)') end end end describe '#path_with_suffix' do it 'combines the path and suffix' do path = Path.new(nil, nil, {}) allow(path).to receive(:path) { '/the/path' } allow(path).to receive(:suffix) { 'suffix' } expect(path.path_with_suffix).to eql('/the/pathsuffix') end context 'when using a specific format' do it 'might have a suffix with specified format' do path = Path.new(nil, nil, {}) allow(path).to receive(:path) { '/the/path' } allow(path).to receive(:uses_specific_format?) { true } allow(path).to receive(:settings) { { format: :json } } expect(path.path_with_suffix).to eql('/the/path(.json)') end end end end end grape-1.0.2/spec/grape/loading_spec.rb0000644000004100000410000000145213231337007017645 0ustar www-datawww-datarequire 'spec_helper' describe Grape::API do let(:jobs_api) do Class.new(Grape::API) do namespace :one do namespace :two do namespace :three do get :one do end get :two do end end end end end end let(:combined_api) do JobsApi = jobs_api Class.new(Grape::API) do version :v1, using: :accept_version_header, cascade: true mount JobsApi end end subject do CombinedApi = combined_api Class.new(Grape::API) do format :json mount CombinedApi => '/' end end def app subject end it 'execute first request in reasonable time' do started = Time.now get '/mount1/nested/test_method' expect(Time.now - started).to be < 5 end end grape-1.0.2/spec/grape/request_spec.rb0000644000004100000410000000532313231337007017721 0ustar www-datawww-datarequire 'spec_helper' module Grape describe Request do let(:default_method) { 'GET' } let(:default_params) { {} } let(:default_options) do { method: method, params: params } end let(:default_env) do Rack::MockRequest.env_for('/', options) end let(:method) { default_method } let(:params) { default_params } let(:options) { default_options } let(:env) { default_env } let(:request) do Grape::Request.new(env) end describe '#params' do let(:params) do { a: '123', b: 'xyz' } end it 'by default returns stringified parameter keys' do expect(request.params).to eq(ActiveSupport::HashWithIndifferentAccess.new('a' => '123', 'b' => 'xyz')) end context 'when build_params_with: Grape::Extensions::Hash::ParamBuilder is specified' do let(:request) do Grape::Request.new(env, build_params_with: Grape::Extensions::Hash::ParamBuilder) end it 'returns symbolized params' do expect(request.params).to eq(a: '123', b: 'xyz') end end describe 'with grape.routing_args' do let(:options) do default_options.merge('grape.routing_args' => routing_args) end let(:routing_args) do { version: '123', route_info: '456', c: 'ccc' } end it 'cuts version and route_info' do expect(request.params).to eq(ActiveSupport::HashWithIndifferentAccess.new(a: '123', b: 'xyz', c: 'ccc')) end end end describe '#headers' do let(:options) do default_options.merge(request_headers) end describe 'with http headers in env' do let(:request_headers) do { 'HTTP_X_GRAPE_IS_COOL' => 'yeah' } end it 'cuts HTTP_ prefix and capitalizes header name words' do expect(request.headers).to eq('X-Grape-Is-Cool' => 'yeah') end end describe 'with non-HTTP_* stuff in env' do let(:request_headers) do { 'HTP_X_GRAPE_ENTITY_TOO' => 'but now we are testing Grape' } end it 'does not include them' do expect(request.headers).to eq({}) end end describe 'with symbolic header names' do let(:request_headers) do { HTTP_GRAPE_LIKES_SYMBOLIC: 'it is true' } end let(:env) do default_env.merge(request_headers) end it 'converts them to string' do expect(request.headers).to eq('Grape-Likes-Symbolic' => 'it is true') end end end end end grape-1.0.2/spec/spec_helper.rb0000644000004100000410000000120413231337007016404 0ustar www-datawww-data$LOAD_PATH.unshift(File.dirname(__FILE__)) $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'support')) require 'grape' require 'rubygems' require 'bundler' Bundler.require :default, :test Dir["#{File.dirname(__FILE__)}/support/*.rb"].each do |file| require file end I18n.enforce_available_locales = false RSpec.configure do |config| config.include Rack::Test::Methods config.include Spec::Support::Helpers config.raise_errors_for_deprecations! config.before(:each) { Grape::Util::InheritableSetting.reset_global! } end require 'coveralls' Coveralls.wear! grape-1.0.2/spec/shared/0000755000004100000410000000000013231337007015037 5ustar www-datawww-datagrape-1.0.2/spec/shared/versioning_examples.rb0000644000004100000410000001363313231337007021453 0ustar www-datawww-datashared_examples_for 'versioning' do it 'sets the API version' do subject.format :txt subject.version 'v1', macro_options subject.get :hello do "Version: #{request.env['api.version']}" end versioned_get '/hello', 'v1', macro_options expect(last_response.body).to eql 'Version: v1' end it 'adds the prefix before the API version' do subject.format :txt subject.prefix 'api' subject.version 'v1', macro_options subject.get :hello do "Version: #{request.env['api.version']}" end versioned_get '/hello', 'v1', macro_options.merge(prefix: 'api') expect(last_response.body).to eql 'Version: v1' end it 'is able to specify version as a nesting' do subject.version 'v2', macro_options subject.get '/awesome' do 'Radical' end subject.version 'v1', macro_options do get '/legacy' do 'Totally' end end versioned_get '/awesome', 'v1', macro_options expect(last_response.status).to eql 404 versioned_get '/awesome', 'v2', macro_options expect(last_response.status).to eql 200 versioned_get '/legacy', 'v1', macro_options expect(last_response.status).to eql 200 versioned_get '/legacy', 'v2', macro_options expect(last_response.status).to eql 404 end it 'is able to specify multiple versions' do subject.version 'v1', 'v2', macro_options subject.get 'awesome' do 'I exist' end versioned_get '/awesome', 'v1', macro_options expect(last_response.status).to eql 200 versioned_get '/awesome', 'v2', macro_options expect(last_response.status).to eql 200 versioned_get '/awesome', 'v3', macro_options expect(last_response.status).to eql 404 end context 'with different versions for the same endpoint' do context 'without a prefix' do it 'allows the same endpoint to be implemented' do subject.format :txt subject.version 'v2', macro_options subject.get 'version' do request.env['api.version'] end subject.version 'v1', macro_options do get 'version' do 'version ' + request.env['api.version'] end end versioned_get '/version', 'v2', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2') versioned_get '/version', 'v1', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('version v1') end end context 'with a prefix' do it 'allows the same endpoint to be implemented' do subject.format :txt subject.prefix 'api' subject.version 'v2', macro_options subject.get 'version' do request.env['api.version'] end subject.version 'v1', macro_options do get 'version' do 'version ' + request.env['api.version'] end end versioned_get '/version', 'v1', macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('version v1') versioned_get '/version', 'v2', macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2') end end end context 'with before block defined within a version block' do it 'calls before block that is defined within the version block' do subject.format :txt subject.prefix 'api' subject.version 'v2', macro_options do before do @output ||= 'v2-' end get 'version' do @output += 'version' end end subject.version 'v1', macro_options do before do @output ||= 'v1-' end get 'version' do @output += 'version' end end versioned_get '/version', 'v1', macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('v1-version') versioned_get '/version', 'v2', macro_options.merge(prefix: subject.prefix) expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2-version') end end it 'does not overwrite version parameter with API version' do subject.format :txt subject.version 'v1', macro_options subject.params { requires :version } subject.get :api_version_with_version_param do params[:version] end versioned_get '/api_version_with_version_param?version=1', 'v1', macro_options expect(last_response.body).to eql '1' end context 'with catch-all' do let(:options) { macro_options } let(:v1) do klass = Class.new(Grape::API) klass.version 'v1', options klass.get 'version' do 'v1' end klass end let(:v2) do klass = Class.new(Grape::API) klass.version 'v2', options klass.get 'version' do 'v2' end klass end before do subject.format :txt subject.mount v1 subject.mount v2 subject.route :any, '*path' do params[:path] end end context 'v1' do it 'finds endpoint' do versioned_get '/version', 'v1', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('v1') end it 'finds catch all' do versioned_get '/whatever', 'v1', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to end_with 'whatever' end end context 'v2' do it 'finds endpoint' do versioned_get '/version', 'v2', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to eq('v2') end it 'finds catch all' do versioned_get '/whatever', 'v2', macro_options expect(last_response.status).to eq(200) expect(last_response.body).to end_with 'whatever' end end end end grape-1.0.2/spec/integration/0000755000004100000410000000000013231337007016114 5ustar www-datawww-datagrape-1.0.2/spec/integration/multi_xml/0000755000004100000410000000000013231337007020126 5ustar www-datawww-datagrape-1.0.2/spec/integration/multi_xml/xml_spec.rb0000644000004100000410000000017213231337007022265 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Xml do it 'uses multi_xml' do expect(Grape::Xml).to eq(::MultiXml) end end grape-1.0.2/spec/integration/multi_json/0000755000004100000410000000000013231337007020277 5ustar www-datawww-datagrape-1.0.2/spec/integration/multi_json/json_spec.rb0000644000004100000410000000017613231337007022613 0ustar www-datawww-datarequire 'spec_helper' describe Grape::Json do it 'uses multi_json' do expect(Grape::Json).to eq(::MultiJson) end end grape-1.0.2/spec/support/0000755000004100000410000000000013231337007015305 5ustar www-datawww-datagrape-1.0.2/spec/support/endpoint_faker.rb0000644000004100000410000000070613231337007020625 0ustar www-datawww-datamodule Spec module Support class EndpointFaker class FakerAPI < Grape::API get '/' do end end def initialize(app, endpoint = FakerAPI.endpoints.first) @app = app @endpoint = endpoint end def call(env) @endpoint.instance_exec do @request = Grape::Request.new(env.dup) end @app.call(env.merge('api.endpoint' => @endpoint)) end end end end grape-1.0.2/spec/support/versioned_helpers.rb0000644000004100000410000000340613231337007021355 0ustar www-datawww-data# Versioning module Spec module Support module Helpers # Returns the path with options[:version] prefixed if options[:using] is :path. # Returns normal path otherwise. def versioned_path(options = {}) case options[:using] when :path File.join('/', options[:prefix] || '', options[:version], options[:path]) when :param File.join('/', options[:prefix] || '', options[:path]) when :header File.join('/', options[:prefix] || '', options[:path]) when :accept_version_header File.join('/', options[:prefix] || '', options[:path]) else raise ArgumentError.new("unknown versioning strategy: #{options[:using]}") end end def versioned_headers(options) case options[:using] when :path {} # no-op when :param {} # no-op when :header { 'HTTP_ACCEPT' => [ "application/vnd.#{options[:vendor]}-#{options[:version]}", options[:format] ].compact.join('+') } when :accept_version_header { 'HTTP_ACCEPT_VERSION' => options[:version].to_s } else raise ArgumentError.new("unknown versioning strategy: #{options[:using]}") end end def versioned_get(path, version_name, version_options = {}) path = versioned_path(version_options.merge(version: version_name, path: path)) headers = versioned_headers(version_options.merge(version: version_name)) params = {} if version_options[:using] == :param params = { version_options[:parameter] => version_name } end get path, params, headers end end end end grape-1.0.2/spec/support/content_type_helpers.rb0000644000004100000410000000054613231337007022074 0ustar www-datawww-datamodule Spec module Support module Helpers %w[put patch post delete].each do |method| define_method :"#{method}_with_json" do |uri, params = {}, env = {}, &block| params = params.to_json env['CONTENT_TYPE'] ||= 'application/json' send(method, uri, params, env, &block) end end end end end grape-1.0.2/spec/support/integer_helpers.rb0000644000004100000410000000027113231337007021011 0ustar www-datawww-datamodule Spec module Support module Helpers INTEGER_CLASS_NAME = 0.to_i.class.to_s.freeze def integer_class_name INTEGER_CLASS_NAME end end end end grape-1.0.2/spec/support/basic_auth_encode_helpers.rb0000644000004100000410000000027213231337007022774 0ustar www-datawww-datamodule Spec module Support module Helpers def encode_basic_auth(username, password) 'Basic ' + Base64.encode64("#{username}:#{password}") end end end end grape-1.0.2/spec/support/file_streamer.rb0000644000004100000410000000027013231337007020452 0ustar www-datawww-dataclass FileStreamer def initialize(file_path) @file_path = file_path end def each(&blk) File.open(@file_path, 'rb') do |file| file.each(10, &blk) end end end grape-1.0.2/benchmark/0000755000004100000410000000000013231337007014571 5ustar www-datawww-datagrape-1.0.2/benchmark/simple_with_type_coercer.rb0000644000004100000410000000067313231337007022213 0ustar www-datawww-data$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) require 'grape' require 'benchmark/ips' api = Class.new(Grape::API) do prefix :api version 'v1', using: :path params do requires :param, type: Array[String] end get '/' do 'hello' end end env = Rack::MockRequest.env_for('/api/v1?param=value', method: 'GET') Benchmark.ips do |ips| ips.report('simple_with_type_coercer') do api.call(env) end end grape-1.0.2/benchmark/simple.rb0000644000004100000410000000065013231337007016410 0ustar www-datawww-data$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) require 'grape' require 'benchmark/ips' class API < Grape::API prefix :api version 'v1', using: :path get '/' do 'hello' end end options = { method: 'GET' } env = Rack::MockRequest.env_for('/api/v1', options) 10.times do |i| env["HTTP_HEADER#{i}"] = '123' end Benchmark.ips do |ips| ips.report('simple') do API.call env end end grape-1.0.2/lib/0000755000004100000410000000000013231337007013405 5ustar www-datawww-datagrape-1.0.2/lib/grape/0000755000004100000410000000000013231337007014503 5ustar www-datawww-datagrape-1.0.2/lib/grape/middleware/0000755000004100000410000000000013231337007016620 5ustar www-datawww-datagrape-1.0.2/lib/grape/middleware/formatter.rb0000644000004100000410000001337513231337007021161 0ustar www-datawww-datarequire 'grape/middleware/base' module Grape module Middleware class Formatter < Base CHUNKED = 'chunked'.freeze def default_options { default_format: :txt, formatters: {}, parsers: {} } end def before negotiate_content_type read_body_input end def after return unless @app_response status, headers, bodies = *@app_response if Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status) @app_response else build_formatted_response(status, headers, bodies) end end private def build_formatted_response(status, headers, bodies) headers = ensure_content_type(headers) if bodies.is_a?(Grape::ServeFile::FileResponse) Grape::ServeFile::SendfileResponse.new([], status, headers) do |resp| resp.body = bodies.file end else # Allow content-type to be explicitly overwritten formatter = fetch_formatter(headers, options) bodymap = bodies.collect { |body| formatter.call(body, env) } Rack::Response.new(bodymap, status, headers) end rescue Grape::Exceptions::InvalidFormatter => e throw :error, status: 500, message: e.message, backtrace: e.backtrace, original_exception: e end def fetch_formatter(headers, options) api_format = mime_types[headers[Grape::Http::Headers::CONTENT_TYPE]] || env[Grape::Env::API_FORMAT] Grape::Formatter.formatter_for(api_format, options) end # Set the content type header for the API format if it is not already present. # # @param headers [Hash] # @return [Hash] def ensure_content_type(headers) if headers[Grape::Http::Headers::CONTENT_TYPE] headers else headers.merge(Grape::Http::Headers::CONTENT_TYPE => content_type_for(env[Grape::Env::API_FORMAT])) end end def request @request ||= Rack::Request.new(env) end # store read input in env['api.request.input'] def read_body_input return unless (request.post? || request.put? || request.patch? || request.delete?) && (!request.form_data? || !request.media_type) && !request.parseable_data? && (request.content_length.to_i > 0 || request.env[Grape::Http::Headers::HTTP_TRANSFER_ENCODING] == CHUNKED) return unless (input = env[Grape::Env::RACK_INPUT]) input.rewind body = env[Grape::Env::API_REQUEST_INPUT] = input.read begin read_rack_input(body) if body && !body.empty? ensure input.rewind end end # store parsed input in env['api.request.body'] def read_rack_input(body) fmt = request.media_type ? mime_types[request.media_type] : options[:default_format] unless content_type_for(fmt) throw :error, status: 406, message: "The requested content-type '#{request.media_type}' is not supported." end parser = Grape::Parser.parser_for fmt, options if parser begin body = (env[Grape::Env::API_REQUEST_BODY] = parser.call(body, env)) if body.is_a?(Hash) env[Grape::Env::RACK_REQUEST_FORM_HASH] = if env[Grape::Env::RACK_REQUEST_FORM_HASH] env[Grape::Env::RACK_REQUEST_FORM_HASH].merge(body) else body end env[Grape::Env::RACK_REQUEST_FORM_INPUT] = env[Grape::Env::RACK_INPUT] end rescue Grape::Exceptions::Base => e raise e rescue StandardError => e throw :error, status: 400, message: e.message, backtrace: e.backtrace, original_exception: e end else env[Grape::Env::API_REQUEST_BODY] = body end end def negotiate_content_type fmt = format_from_extension || format_from_params || options[:format] || format_from_header || options[:default_format] if content_type_for(fmt) env[Grape::Env::API_FORMAT] = fmt else throw :error, status: 406, message: "The requested format '#{fmt}' is not supported." end end def format_from_extension parts = request.path.split('.') if parts.size > 1 extension = parts.last # avoid symbol memory leak on an unknown format return extension.to_sym if content_type_for(extension) end nil end def format_from_params fmt = Rack::Utils.parse_nested_query(env[Grape::Http::Headers::QUERY_STRING])[Grape::Http::Headers::FORMAT] # avoid symbol memory leak on an unknown format return fmt.to_sym if content_type_for(fmt) fmt end def format_from_header mime_array.each do |t| return mime_types[t] if mime_types.key?(t) end nil end def mime_array accept = env[Grape::Http::Headers::HTTP_ACCEPT] return [] unless accept accept_into_mime_and_quality = %r{ ( \w+/[\w+.-]+) # eg application/vnd.example.myformat+xml (?: (?:;[^,]*?)? # optionally multiple formats in a row ;\s*q=([\d.]+) # optional "quality" preference (eg q=0.5) )? }x vendor_prefix_pattern = /vnd\.[^+]+\+/ accept.scan(accept_into_mime_and_quality) .sort_by { |_, quality_preference| -quality_preference.to_f } .flat_map { |mime, _| [mime, mime.sub(vendor_prefix_pattern, '')] } end end end end grape-1.0.2/lib/grape/middleware/versioner/0000755000004100000410000000000013231337007020634 5ustar www-datawww-datagrape-1.0.2/lib/grape/middleware/versioner/path.rb0000644000004100000410000000354713231337007022126 0ustar www-datawww-datarequire 'grape/middleware/base' module Grape module Middleware module Versioner # This middleware sets various version related rack environment variables # based on the uri path and removes the version substring from the uri # path. If the version substring does not match any potential initialized # versions, a 404 error is thrown. # # Example: For a uri path # /v1/resource # # The following rack env variables are set and path is rewritten to # '/resource': # # env['api.version'] => 'v1' # class Path < Base def default_options { pattern: /.*/i } end def before path = env[Grape::Http::Headers::PATH_INFO].dup path.sub!(mount_path, '') if mounted_path?(path) if prefix && path.index(prefix) == 0 # rubocop:disable all path.sub!(prefix, '') path = Grape::Router.normalize_path(path) end pieces = path.split('/') potential_version = pieces[1] return unless potential_version =~ options[:pattern] throw :error, status: 404, message: '404 API Version Not Found' if options[:versions] && !options[:versions].find { |v| v.to_s == potential_version } env[Grape::Env::API_VERSION] = potential_version end private def mounted_path?(path) return false unless mount_path && path.start_with?(mount_path) rest = path.slice(mount_path.length..-1) rest.start_with?('/') || rest.empty? end def mount_path @mount_path ||= options[:mount_path] && options[:mount_path] != '/' ? options[:mount_path] : '' end def prefix Grape::Router.normalize_path(options[:prefix].to_s) if options[:prefix] end end end end end grape-1.0.2/lib/grape/middleware/versioner/param.rb0000644000004100000410000000331513231337007022263 0ustar www-datawww-datarequire 'grape/middleware/base' module Grape module Middleware module Versioner # This middleware sets various version related rack environment variables # based on the request parameters and removes that parameter from the # request parameters for subsequent middleware and API. # If the version substring does not match any potential initialized # versions, a 404 error is thrown. # If the version substring is not passed the version (highest mounted) # version will be used. # # Example: For a uri path # /resource?apiver=v1 # # The following rack env variables are set and path is rewritten to # '/resource': # # env['api.version'] => 'v1' class Param < Base def default_options { version_options: { parameter: 'apiver'.freeze } } end def before potential_version = Rack::Utils.parse_nested_query(env[Grape::Http::Headers::QUERY_STRING])[paramkey] return if potential_version.nil? throw :error, status: 404, message: '404 API Version Not Found', headers: { Grape::Http::Headers::X_CASCADE => 'pass' } if options[:versions] && !options[:versions].find { |v| v.to_s == potential_version } env[Grape::Env::API_VERSION] = potential_version env[Grape::Env::RACK_REQUEST_QUERY_HASH].delete(paramkey) if env.key? Grape::Env::RACK_REQUEST_QUERY_HASH end private def paramkey version_options[:parameter] || default_options[:version_options][:parameter] end def version_options options[:version_options] end end end end end grape-1.0.2/lib/grape/middleware/versioner/header.rb0000644000004100000410000001504013231337007022411 0ustar www-datawww-datarequire 'grape/middleware/base' require 'grape/middleware/versioner/parse_media_type_patch' module Grape module Middleware module Versioner # This middleware sets various version related rack environment variables # based on the HTTP Accept header with the pattern: # application/vnd.:vendor-:version+:format # # Example: For request header # Accept: application/vnd.mycompany.a-cool-resource-v1+json # # The following rack env variables are set: # # env['api.type'] => 'application' # env['api.subtype'] => 'vnd.mycompany.a-cool-resource-v1+json' # env['api.vendor] => 'mycompany.a-cool-resource' # env['api.version] => 'v1' # env['api.format] => 'json' # # If version does not match this route, then a 406 is raised with # X-Cascade header to alert Grape::Router to attempt the next matched # route. class Header < Base VENDOR_VERSION_HEADER_REGEX = /\Avnd\.([a-z0-9.\-_!#\$&\^]+?)(?:-([a-z0-9*.]+))?(?:\+([a-z0-9*\-.]+))?\z/ HAS_VENDOR_REGEX = /\Avnd\.[a-z0-9.\-_!#\$&\^]+/ HAS_VERSION_REGEX = /\Avnd\.([a-z0-9.\-_!#\$&\^]+?)(?:-([a-z0-9*.]+))+/ def before strict_header_checks if strict? if media_type || env[Grape::Env::GRAPE_ALLOWED_METHODS] media_type_header_handler elsif headers_contain_wrong_vendor? fail_with_invalid_accept_header!('API vendor not found.') elsif headers_contain_wrong_version? fail_with_invalid_version_header!('API version not found.') end end private def strict_header_checks strict_accept_header_presence_check strict_version_vendor_accept_header_presence_check end def strict_accept_header_presence_check return unless header.qvalues.empty? fail_with_invalid_accept_header!('Accept header must be set.') end def strict_version_vendor_accept_header_presence_check return unless versions.present? return if an_accept_header_with_version_and_vendor_is_present? fail_with_invalid_accept_header!('API vendor or version not found.') end def an_accept_header_with_version_and_vendor_is_present? header.qvalues.keys.any? do |h| VENDOR_VERSION_HEADER_REGEX =~ h.sub('application/', '') end end def header @header ||= rack_accept_header end def media_type @media_type ||= header.best_of(available_media_types) end def media_type_header_handler type, subtype = Rack::Accept::Header.parse_media_type(media_type) env[Grape::Env::API_TYPE] = type env[Grape::Env::API_SUBTYPE] = subtype return unless VENDOR_VERSION_HEADER_REGEX =~ subtype env[Grape::Env::API_VENDOR] = Regexp.last_match[1] env[Grape::Env::API_VERSION] = Regexp.last_match[2] # weird that Grape::Middleware::Formatter also does this env[Grape::Env::API_FORMAT] = Regexp.last_match[3] end def fail_with_invalid_accept_header!(message) raise Grape::Exceptions::InvalidAcceptHeader .new(message, error_headers) end def fail_with_invalid_version_header!(message) raise Grape::Exceptions::InvalidVersionHeader .new(message, error_headers) end def available_media_types available_media_types = [] content_types.each do |extension, _media_type| versions.reverse_each do |version| available_media_types += [ "application/vnd.#{vendor}-#{version}+#{extension}", "application/vnd.#{vendor}-#{version}" ] end available_media_types << "application/vnd.#{vendor}+#{extension}" end available_media_types << "application/vnd.#{vendor}" content_types.each do |_, media_type| available_media_types << media_type end available_media_types.flatten end def headers_contain_wrong_vendor? header.values.all? do |header_value| vendor?(header_value) && request_vendor(header_value) != vendor end end def headers_contain_wrong_version? header.values.all? do |header_value| version?(header_value) && !versions.include?(request_version(header_value)) end end def rack_accept_header Rack::Accept::MediaType.new env[Grape::Http::Headers::HTTP_ACCEPT] rescue RuntimeError => e fail_with_invalid_accept_header!(e.message) end def versions options[:versions] || [] end def vendor version_options && version_options[:vendor] end def strict? version_options && version_options[:strict] end def version_options options[:version_options] end # By default those errors contain an `X-Cascade` header set to `pass`, # which allows nesting and stacking of routes # (see Grape::Router for more # information). To prevent # this behavior, and not add the `X-Cascade` # header, one can set the `:cascade` option to `false`. def cascade? if version_options && version_options.key?(:cascade) version_options[:cascade] else true end end def error_headers cascade? ? { Grape::Http::Headers::X_CASCADE => 'pass' } : {} end # @param [String] media_type a content type # @return [Boolean] whether the content type sets a vendor def vendor?(media_type) _, subtype = Rack::Accept::Header.parse_media_type(media_type) subtype[HAS_VENDOR_REGEX] end def request_vendor(media_type) _, subtype = Rack::Accept::Header.parse_media_type(media_type) subtype.match(VENDOR_VERSION_HEADER_REGEX)[1] end def request_version(media_type) _, subtype = Rack::Accept::Header.parse_media_type(media_type) subtype.match(VENDOR_VERSION_HEADER_REGEX)[2] end # @param [String] media_type a content type # @return [Boolean] whether the content type sets an API version def version?(media_type) _, subtype = Rack::Accept::Header.parse_media_type(media_type) subtype[HAS_VERSION_REGEX] end end end end end grape-1.0.2/lib/grape/middleware/versioner/parse_media_type_patch.rb0000644000004100000410000000117313231337007025654 0ustar www-datawww-datamodule Rack module Accept module Header class << self # Corrected version of https://github.com/mjackson/rack-accept/blob/master/lib/rack/accept/header.rb#L40-L44 def parse_media_type(media_type) # see http://tools.ietf.org/html/rfc6838#section-4.2 for allowed characters in media type names m = media_type.to_s.match(%r{^([a-z*]+)\/([a-z0-9*\&\^\-_#\$!.+]+)(?:;([a-z0-9=;]+))?$}) m ? [m[1], m[2], m[3] || ''] : [] end end end class MediaType def parse_media_type(media_type) Header.parse_media_type(media_type) end end end end grape-1.0.2/lib/grape/middleware/versioner/accept_version_header.rb0000644000004100000410000000413413231337007025477 0ustar www-datawww-datarequire 'grape/middleware/base' module Grape module Middleware module Versioner # This middleware sets various version related rack environment variables # based on the HTTP Accept-Version header # # Example: For request header # Accept-Version: v1 # # The following rack env variables are set: # # env['api.version'] => 'v1' # # If version does not match this route, then a 406 is raised with # X-Cascade header to alert Grape::Router to attempt the next matched # route. class AcceptVersionHeader < Base def before potential_version = (env[Grape::Http::Headers::HTTP_ACCEPT_VERSION] || '').strip if strict? # If no Accept-Version header: if potential_version.empty? throw :error, status: 406, headers: error_headers, message: 'Accept-Version header must be set.' end end return if potential_version.empty? # If the requested version is not supported: throw :error, status: 406, headers: error_headers, message: 'The requested version is not supported.' unless versions.any? { |v| v.to_s == potential_version } env[Grape::Env::API_VERSION] = potential_version end private def versions options[:versions] || [] end def strict? options[:version_options] && options[:version_options][:strict] end # By default those errors contain an `X-Cascade` header set to `pass`, which allows nesting and stacking # of routes (see Grape::Router) for more information). To prevent # this behavior, and not add the `X-Cascade` header, one can set the `:cascade` option to `false`. def cascade? if options[:version_options] && options[:version_options].key?(:cascade) options[:version_options][:cascade] else true end end def error_headers cascade? ? { Grape::Http::Headers::X_CASCADE => 'pass' } : {} end end end end end grape-1.0.2/lib/grape/middleware/stack.rb0000644000004100000410000000546513231337007020264 0ustar www-datawww-datamodule Grape module Middleware # Class to handle the stack of middlewares based on ActionDispatch::MiddlewareStack # It allows to insert and insert after class Stack class Middleware attr_reader :args, :block, :klass def initialize(klass, *args, &block) @klass = klass @args = args @block = block end def name klass.name end def ==(other) case other when Middleware klass == other.klass when Class klass == other || (name.nil? && klass.superclass == other) end end def inspect klass.to_s end end include Enumerable attr_accessor :middlewares, :others def initialize @middlewares = [] @others = [] end def each @middlewares.each { |x| yield x } end def size middlewares.size end def last middlewares.last end def [](i) middlewares[i] end def insert(index, *args, &block) index = assert_index(index, :before) middleware = self.class::Middleware.new(*args, &block) middlewares.insert(index, middleware) end alias insert_before insert def insert_after(index, *args, &block) index = assert_index(index, :after) insert(index + 1, *args, &block) end def use(*args, &block) middleware = self.class::Middleware.new(*args, &block) middlewares.push(middleware) end def merge_with(middleware_specs) middleware_specs.each do |operation, *args| if args.last.is_a?(Proc) public_send(operation, *args, &args.pop) else public_send(operation, *args) end end end # @return [Rack::Builder] the builder object with our middlewares applied def build(builder = Rack::Builder.new) others.shift(others.size).each(&method(:merge_with)) middlewares.each do |m| m.block ? builder.use(m.klass, *m.args, &m.block) : builder.use(m.klass, *m.args) end builder end # @description Add middlewares with :use operation to the stack. Store others with :insert_* operation for later # @param [Array] other_specs An array of middleware specifications (e.g. [[:use, klass], [:insert_before, *args]]) def concat(other_specs) @others << Array(other_specs).reject { |o| o.first == :use } merge_with Array(other_specs).select { |o| o.first == :use } end protected def assert_index(index, where) i = index.is_a?(Integer) ? index : middlewares.index(index) i || raise("No such middleware to insert #{where}: #{index.inspect}") end end end end grape-1.0.2/lib/grape/middleware/auth/0000755000004100000410000000000013231337007017561 5ustar www-datawww-datagrape-1.0.2/lib/grape/middleware/auth/strategy_info.rb0000644000004100000410000000046513231337007022770 0ustar www-datawww-datamodule Grape module Middleware module Auth StrategyInfo = Struct.new(:auth_class, :settings_fetcher) do def create(app, options, &block) strategy_args = settings_fetcher.call(options) auth_class.new(app, *strategy_args, &block) end end end end end grape-1.0.2/lib/grape/middleware/auth/strategies.rb0000644000004100000410000000121713231337007022261 0ustar www-datawww-datamodule Grape module Middleware module Auth module Strategies module_function def add(label, strategy, option_fetcher = ->(_) { [] }) auth_strategies[label] = StrategyInfo.new(strategy, option_fetcher) end def auth_strategies @auth_strategies ||= { http_basic: StrategyInfo.new(Rack::Auth::Basic, ->(settings) { [settings[:realm]] }), http_digest: StrategyInfo.new(Rack::Auth::Digest::MD5, ->(settings) { [settings[:realm], settings[:opaque]] }) } end def [](label) auth_strategies[label] end end end end end grape-1.0.2/lib/grape/middleware/auth/base.rb0000644000004100000410000000176213231337007021026 0ustar www-datawww-datarequire 'rack/auth/basic' module Grape module Middleware module Auth class Base attr_accessor :options, :app, :env def initialize(app, **options) @app = app @options = options end def context env[Grape::Env::API_ENDPOINT] end def call(env) dup._call(env) end def _call(env) self.env = env if options.key?(:type) auth_proc = options[:proc] auth_proc_context = context strategy_info = Grape::Middleware::Auth::Strategies[options[:type]] throw(:error, status: 401, message: 'API Authorization Failed.') unless strategy_info.present? strategy = strategy_info.create(@app, options) do |*args| auth_proc_context.instance_exec(*args, &auth_proc) end strategy.call(env) else app.call(env) end end end end end end grape-1.0.2/lib/grape/middleware/auth/dsl.rb0000644000004100000410000000235713231337007020677 0ustar www-datawww-datarequire 'rack/auth/basic' require 'active_support/concern' module Grape module Middleware module Auth module DSL extend ActiveSupport::Concern module ClassMethods # Add an authentication type to the API. Currently # only `:http_basic`, `:http_digest` are supported. def auth(type = nil, options = {}, &block) if type namespace_inheritable(:auth, options.reverse_merge(type: type.to_sym, proc: block)) use Grape::Middleware::Auth::Base, namespace_inheritable(:auth) else namespace_inheritable(:auth) end end # Add HTTP Basic authorization to the API. # # @param [Hash] options A hash of options. # @option options [String] :realm "API Authorization" The HTTP Basic realm. def http_basic(options = {}, &block) options[:realm] ||= 'API Authorization' auth :http_basic, options, &block end def http_digest(options = {}, &block) options[:realm] ||= 'API Authorization' options[:opaque] ||= 'secret' auth :http_digest, options, &block end end end end end end grape-1.0.2/lib/grape/middleware/filter.rb0000644000004100000410000000072713231337007020440 0ustar www-datawww-datamodule Grape module Middleware # This is a simple middleware for adding before and after filters # to Grape APIs. It is used like so: # # use Grape::Middleware::Filter, before: -> { do_something }, after: -> { do_something } class Filter < Base def before app.instance_eval(&options[:before]) if options[:before] end def after app.instance_eval(&options[:after]) if options[:after] end end end end grape-1.0.2/lib/grape/middleware/globals.rb0000644000004100000410000000067013231337007020573 0ustar www-datawww-datarequire 'grape/middleware/base' module Grape module Middleware class Globals < Base def before request = Grape::Request.new(@env, build_params_with: @options[:build_params_with]) @env[Grape::Env::GRAPE_REQUEST] = request @env[Grape::Env::GRAPE_REQUEST_HEADERS] = request.headers @env[Grape::Env::GRAPE_REQUEST_PARAMS] = request.params if @env[Grape::Env::RACK_INPUT] end end end end grape-1.0.2/lib/grape/middleware/versioner.rb0000644000004100000410000000157313231337007021167 0ustar www-datawww-data# Versioners set env['api.version'] when a version is defined on an API and # on the requests. The current methods for determining version are: # # :header - version from HTTP Accept header. # :path - version from uri. e.g. /v1/resource # :param - version from uri query string, e.g. /v1/resource?apiver=v1 # # See individual classes for details. module Grape module Middleware module Versioner module_function # @param strategy [Symbol] :path, :header or :param # @return a middleware class based on strategy def using(strategy) case strategy when :path Path when :header Header when :param Param when :accept_version_header AcceptVersionHeader else raise Grape::Exceptions::InvalidVersionerOption.new(strategy) end end end end end grape-1.0.2/lib/grape/middleware/base.rb0000644000004100000410000000454713231337007020071 0ustar www-datawww-datarequire 'grape/dsl/headers' module Grape module Middleware class Base attr_reader :app, :env, :options TEXT_HTML = 'text/html'.freeze include Grape::DSL::Headers # @param [Rack Application] app The standard argument for a Rack middleware. # @param [Hash] options A hash of options, simply stored for use by subclasses. def initialize(app, **options) @app = app @options = default_options.merge(**options) @app_response = nil end def default_options {} end def call(env) dup.call!(env) end def call!(env) @env = env before begin @app_response = @app.call(@env) ensure begin after_response = after rescue StandardError => e warn "caught error of type #{e.class} in after callback inside #{self.class.name} : #{e.message}" raise e end end response = after_response || @app_response merge_headers response response end # @abstract # Called before the application is called in the middleware lifecycle. def before; end # @abstract # Called after the application is called in the middleware lifecycle. # @return [Response, nil] a Rack SPEC response or nil to call the application afterwards. def after; end def response return @app_response if @app_response.is_a?(Rack::Response) Rack::Response.new(@app_response[2], @app_response[0], @app_response[1]) end def content_type_for(format) HashWithIndifferentAccess.new(content_types)[format] end def content_types ContentTypes.content_types_for(options[:content_types]) end def content_type content_type_for(env[Grape::Env::API_FORMAT] || options[:format]) || TEXT_HTML end def mime_types types_without_params = {} content_types.each_pair do |k, v| types_without_params[v.split(';').first] = k end types_without_params end private def merge_headers(response) return unless headers.is_a?(Hash) case response when Rack::Response then response.headers.merge!(headers) when Array then response[1].merge!(headers) end end end end end grape-1.0.2/lib/grape/middleware/error.rb0000644000004100000410000001153013231337007020276 0ustar www-datawww-datarequire 'grape/middleware/base' module Grape module Middleware class Error < Base def default_options { default_status: 500, # default status returned on error default_message: '', format: :txt, helpers: nil, formatters: {}, error_formatters: {}, rescue_all: false, # true to rescue all exceptions rescue_grape_exceptions: false, rescue_subclasses: true, # rescue subclasses of exceptions listed rescue_options: { backtrace: false, # true to display backtrace, true to let Grape handle Grape::Exceptions original_exception: false, # true to display exception }, rescue_handlers: {}, # rescue handler blocks base_only_rescue_handlers: {}, # rescue handler blocks rescuing only the base class all_rescue_handler: nil # rescue handler block to rescue from all exceptions } end def initialize(app, **options) super self.class.send(:include, @options[:helpers]) if @options[:helpers] end def call!(env) @env = env begin error_response(catch(:error) do return @app.call(@env) end) rescue StandardError => e is_rescuable = rescuable?(e.class) if e.is_a?(Grape::Exceptions::Base) && (!is_rescuable || rescuable_by_grape?(e.class)) handler = ->(arg) { error_response(arg) } else raise unless is_rescuable handler = find_handler(e.class) end handler.nil? ? handle_error(e) : exec_handler(e, &handler) end end def find_handler(klass) handler = options[:rescue_handlers].find(-> { [] }) { |error, _| klass <= error }[1] handler ||= options[:base_only_rescue_handlers][klass] handler ||= options[:all_rescue_handler] if handler.instance_of?(Symbol) raise NoMethodError, "undefined method `#{handler}'" unless respond_to?(handler) handler = self.class.instance_method(handler).bind(self) end handler end def rescuable?(klass) return false if klass == Grape::Exceptions::InvalidVersionHeader rescue_all? || rescue_class_or_its_ancestor?(klass) || rescue_with_base_only_handler?(klass) end def rescuable_by_grape?(klass) return false if klass == Grape::Exceptions::InvalidVersionHeader options[:rescue_grape_exceptions] end def exec_handler(e, &handler) if handler.lambda? && handler.arity.zero? instance_exec(&handler) else instance_exec(e, &handler) end end def error!(message, status = options[:default_status], headers = {}, backtrace = [], original_exception = nil) headers = headers.reverse_merge(Grape::Http::Headers::CONTENT_TYPE => content_type) rack_response(format_message(message, backtrace, original_exception), status, headers) end def handle_error(e) error_response(message: e.message, backtrace: e.backtrace, original_exception: e) end # TODO: This method is deprecated. Refactor out. def error_response(error = {}) status = error[:status] || options[:default_status] message = error[:message] || options[:default_message] headers = { Grape::Http::Headers::CONTENT_TYPE => content_type } headers.merge!(error[:headers]) if error[:headers].is_a?(Hash) backtrace = error[:backtrace] || error[:original_exception] && error[:original_exception].backtrace || [] original_exception = error.is_a?(Exception) ? error : error[:original_exception] || nil rack_response(format_message(message, backtrace, original_exception), status, headers) end def rack_response(message, status = options[:default_status], headers = { Grape::Http::Headers::CONTENT_TYPE => content_type }) Rack::Response.new([message], status, headers).finish end def format_message(message, backtrace, original_exception = nil) format = env[Grape::Env::API_FORMAT] || options[:format] formatter = Grape::ErrorFormatter.formatter_for(format, options) throw :error, status: 406, message: "The requested format '#{format}' is not supported.", backtrace: backtrace, original_exception: original_exception unless formatter formatter.call(message, backtrace, options, env, original_exception) end private def rescue_all? options[:rescue_all] end def rescue_class_or_its_ancestor?(klass) (options[:rescue_handlers] || []).any? { |error, _handler| klass <= error } end def rescue_with_base_only_handler?(klass) (options[:base_only_rescue_handlers] || []).include?(klass) end end end end grape-1.0.2/lib/grape/namespace.rb0000644000004100000410000000227213231337007016767 0ustar www-datawww-datamodule Grape # A container for endpoints or other namespaces, which allows for both # logical grouping of endpoints as well as sharing common configuration. # May also be referred to as group, segment, or resource. class Namespace attr_reader :space, :options # @param space [String] the name of this namespace # @param options [Hash] options hash # @option options :requirements [Hash] param-regex pairs, all of which must # be met by a request's params for all endpoints in this namespace, or # validation will fail and return a 422. def initialize(space, **options) @space = space.to_s @options = options end # Retrieves the requirements from the options hash, if given. # @return [Hash] def requirements options[:requirements] || {} end # (see ::joined_space_path) def self.joined_space(settings) (settings || []).map(&:space).join('/') end # Join the namespaces from a list of settings to create a path prefix. # @param settings [Array] list of Grape::Util::InheritableSettings. def self.joined_space_path(settings) Grape::Router.normalize_path(joined_space(settings)) end end end grape-1.0.2/lib/grape/formatter.rb0000644000004100000410000000142313231337007017033 0ustar www-datawww-datamodule Grape module Formatter extend Util::Registrable class << self def builtin_formmaters @builtin_formatters ||= { json: Grape::Formatter::Json, jsonapi: Grape::Formatter::Json, serializable_hash: Grape::Formatter::SerializableHash, txt: Grape::Formatter::Txt, xml: Grape::Formatter::Xml } end def formatters(options) builtin_formmaters.merge(default_elements).merge(options[:formatters] || {}) end def formatter_for(api_format, **options) spec = formatters(**options)[api_format] case spec when nil ->(obj, _env) { obj } when Symbol method(spec) else spec end end end end end grape-1.0.2/lib/grape/exceptions/0000755000004100000410000000000013231337007016664 5ustar www-datawww-datagrape-1.0.2/lib/grape/exceptions/missing_option.rb0000644000004100000410000000030213231337007022245 0ustar www-datawww-datamodule Grape module Exceptions class MissingOption < Base def initialize(option) super(message: compose_message(:missing_option, option: option)) end end end end grape-1.0.2/lib/grape/exceptions/validation.rb0000644000004100000410000000126213231337007021344 0ustar www-datawww-datarequire 'grape/exceptions/base' module Grape module Exceptions class Validation < Grape::Exceptions::Base attr_accessor :params attr_accessor :message_key def initialize(params:, message: nil, **args) @params = params if message @message_key = message if message.is_a?(Symbol) args[:message] = translate_message(message) end super(args) end # remove all the unnecessary stuff from Grape::Exceptions::Base like status # and headers when converting a validation error to json or string def as_json(*_args) to_s end def to_s message end end end end grape-1.0.2/lib/grape/exceptions/missing_group_type.rb0000644000004100000410000000026613231337007023143 0ustar www-datawww-datamodule Grape module Exceptions class MissingGroupTypeError < Base def initialize super(message: compose_message(:missing_group_type)) end end end end grape-1.0.2/lib/grape/exceptions/validation_array_errors.rb0000644000004100000410000000026513231337007024140 0ustar www-datawww-datamodule Grape module Exceptions class ValidationArrayErrors < Base attr_reader :errors def initialize(errors) @errors = errors end end end end grape-1.0.2/lib/grape/exceptions/invalid_versioner_option.rb0000644000004100000410000000033313231337007024322 0ustar www-datawww-datamodule Grape module Exceptions class InvalidVersionerOption < Base def initialize(strategy) super(message: compose_message(:invalid_versioner_option, strategy: strategy)) end end end end grape-1.0.2/lib/grape/exceptions/missing_vendor_option.rb0000644000004100000410000000026713231337007023634 0ustar www-datawww-datamodule Grape module Exceptions class MissingVendorOption < Base def initialize super(message: compose_message(:missing_vendor_option)) end end end end grape-1.0.2/lib/grape/exceptions/incompatible_option_values.rb0000644000004100000410000000044713231337007024633 0ustar www-datawww-datamodule Grape module Exceptions class IncompatibleOptionValues < Base def initialize(option1, value1, option2, value2) super(message: compose_message(:incompatible_option_values, option1: option1, value1: value1, option2: option2, value2: value2)) end end end end grape-1.0.2/lib/grape/exceptions/validation_errors.rb0000644000004100000410000000252013231337007022736 0ustar www-datawww-datarequire 'grape/exceptions/base' module Grape module Exceptions class ValidationErrors < Grape::Exceptions::Base include Enumerable attr_reader :errors def initialize(errors: [], headers: {}, **_options) @errors = {} errors.each do |validation_error| @errors[validation_error.params] ||= [] @errors[validation_error.params] << validation_error end super message: full_messages.join(', '), status: 400, headers: headers end def each errors.each_pair do |attribute, errors| errors.each do |error| yield attribute, error end end end def as_json(**_opts) errors.map do |k, v| { params: k, messages: v.map(&:to_s) } end end def to_json(**_opts) as_json.to_json end def full_messages map { |attributes, error| full_message(attributes, error) }.uniq end private def full_message(attributes, error) I18n.t( 'grape.errors.format'.to_sym, default: '%{attributes} %{message}', attributes: attributes.count == 1 ? translate_attribute(attributes.first) : translate_attributes(attributes), message: error.message ) end end end end grape-1.0.2/lib/grape/exceptions/invalid_with_option_for_represent.rb0000644000004100000410000000031513231337007026216 0ustar www-datawww-datamodule Grape module Exceptions class InvalidWithOptionForRepresent < Base def initialize super(message: compose_message(:invalid_with_option_for_represent)) end end end end grape-1.0.2/lib/grape/exceptions/invalid_accept_header.rb0000644000004100000410000000037213231337007023470 0ustar www-datawww-datamodule Grape module Exceptions class InvalidAcceptHeader < Base def initialize(message, headers) super(message: compose_message(:invalid_accept_header, message: message), status: 406, headers: headers) end end end end grape-1.0.2/lib/grape/exceptions/unknown_parameter.rb0000644000004100000410000000030513231337007022746 0ustar www-datawww-datamodule Grape module Exceptions class UnknownParameter < Base def initialize(param) super(message: compose_message(:unknown_parameter, param: param)) end end end end grape-1.0.2/lib/grape/exceptions/unknown_options.rb0000644000004100000410000000030713231337007022463 0ustar www-datawww-datamodule Grape module Exceptions class UnknownOptions < Base def initialize(options) super(message: compose_message(:unknown_options, options: options)) end end end end grape-1.0.2/lib/grape/exceptions/invalid_version_header.rb0000644000004100000410000000037413231337007023720 0ustar www-datawww-datamodule Grape module Exceptions class InvalidVersionHeader < Base def initialize(message, headers) super(message: compose_message(:invalid_version_header, message: message), status: 406, headers: headers) end end end end grape-1.0.2/lib/grape/exceptions/invalid_formatter.rb0000644000004100000410000000034613231337007022725 0ustar www-datawww-datamodule Grape module Exceptions class InvalidFormatter < Base def initialize(klass, to_format) super(message: compose_message(:invalid_formatter, klass: klass, to_format: to_format)) end end end end grape-1.0.2/lib/grape/exceptions/method_not_allowed.rb0000644000004100000410000000030613231337007023057 0ustar www-datawww-datamodule Grape module Exceptions class MethodNotAllowed < Base def initialize(headers) super(message: '405 Not Allowed', status: 405, headers: headers) end end end end grape-1.0.2/lib/grape/exceptions/unknown_validator.rb0000644000004100000410000000034013231337007022752 0ustar www-datawww-datamodule Grape module Exceptions class UnknownValidator < Base def initialize(validator_type) super(message: compose_message(:unknown_validator, validator_type: validator_type)) end end end end grape-1.0.2/lib/grape/exceptions/invalid_message_body.rb0000644000004100000410000000035113231337007023357 0ustar www-datawww-datamodule Grape module Exceptions class InvalidMessageBody < Base def initialize(body_format) super(message: compose_message(:invalid_message_body, body_format: body_format), status: 400) end end end end grape-1.0.2/lib/grape/exceptions/base.rb0000644000004100000410000000461413231337007020130 0ustar www-datawww-datamodule Grape module Exceptions class Base < StandardError BASE_MESSAGES_KEY = 'grape.errors.messages'.freeze BASE_ATTRIBUTES_KEY = 'grape.errors.attributes'.freeze FALLBACK_LOCALE = :en attr_reader :status, :message, :headers def initialize(status: nil, message: nil, headers: nil, **_options) @status = status @message = message @headers = headers end def [](index) send index end protected # TODO: translate attribute first # if BASE_ATTRIBUTES_KEY.key respond to a string message, then short_message is returned # if BASE_ATTRIBUTES_KEY.key respond to a Hash, means it may have problem , summary and resolution def compose_message(key, **attributes) short_message = translate_message(key, **attributes) if short_message.is_a? Hash @problem = problem(key, **attributes) @summary = summary(key, **attributes) @resolution = resolution(key, **attributes) [['Problem', @problem], ['Summary', @summary], ['Resolution', @resolution]].reduce('') do |message, detail_array| message << "\n#{detail_array[0]}:\n #{detail_array[1]}" unless detail_array[1].blank? message end else short_message end end def problem(key, attributes) translate_message("#{key}.problem".to_sym, attributes) end def summary(key, attributes) translate_message("#{key}.summary".to_sym, attributes) end def resolution(key, attributes) translate_message("#{key}.resolution".to_sym, attributes) end def translate_attributes(keys, **options) keys.map do |key| translate("#{BASE_ATTRIBUTES_KEY}.#{key}", default: key, **options) end.join(', ') end def translate_attribute(key, **options) translate("#{BASE_ATTRIBUTES_KEY}.#{key}", default: key, **options) end def translate_message(key, **options) case key when Symbol translate("#{BASE_MESSAGES_KEY}.#{key}", default: '', **options) when Proc key.call else key end end def translate(key, **options) message = ::I18n.translate(key, **options) message.present? ? message : ::I18n.translate(key, locale: FALLBACK_LOCALE, **options) end end end end grape-1.0.2/lib/grape/exceptions/missing_mime_type.rb0000644000004100000410000000032313231337007022730 0ustar www-datawww-datamodule Grape module Exceptions class MissingMimeType < Base def initialize(new_format) super(message: compose_message(:missing_mime_type, new_format: new_format)) end end end end grape-1.0.2/lib/grape/exceptions/unsupported_group_type.rb0000644000004100000410000000027613231337007024063 0ustar www-datawww-datamodule Grape module Exceptions class UnsupportedGroupTypeError < Base def initialize super(message: compose_message(:unsupported_group_type)) end end end end grape-1.0.2/lib/grape/router.rb0000644000004100000410000001124613231337007016354 0ustar www-datawww-datarequire 'grape/router/route' module Grape class Router attr_reader :map, :compiled class Any < AttributeTranslator def initialize(pattern, **attributes) @pattern = pattern super(attributes) end end def self.normalize_path(path) path = "/#{path}" path.squeeze!('/') path.sub!(%r{/+\Z}, '') path = '/' if path == '' path end def self.supported_methods @supported_methods ||= Grape::Http::Headers::SUPPORTED_METHODS + ['*'] end def initialize @neutral_map = [] @map = Hash.new { |hash, key| hash[key] = [] } @optimized_map = Hash.new { |hash, key| hash[key] = // } end def compile! return if compiled @union = Regexp.union(@neutral_map.map(&:regexp)) self.class.supported_methods.each do |method| routes = map[method] @optimized_map[method] = routes.map.with_index do |route, index| route.index = index route.regexp = /(?<_#{index}>#{route.pattern.to_regexp})/ end @optimized_map[method] = Regexp.union(@optimized_map[method]) end @compiled = true end def append(route) map[route.request_method.to_s.upcase] << route end def associate_routes(pattern, **options) regexp = /(?<_#{@neutral_map.length}>)#{pattern.to_regexp}/ @neutral_map << Any.new(pattern, regexp: regexp, index: @neutral_map.length, **options) end def call(env) with_optimization do response, route = identity(env) response || rotation(env, route) end end def recognize_path(input) any = with_optimization { greedy_match?(input) } return if any == default_response any.endpoint end private def identity(env) route = nil response = transaction(env) do |input, method| route = match?(input, method) process_route(route, env) if route end [response, route] end def rotation(env, exact_route = nil) response = nil input, method = *extract_input_and_method(env) map[method].each do |route| next if exact_route == route next unless route.match?(input) response = process_route(route, env) break unless cascade?(response) end response end def transaction(env) input, method = *extract_input_and_method(env) response = yield(input, method) return response if response && !(cascade = cascade?(response)) neighbor = greedy_match?(input) # If neighbor exists and request method is OPTIONS, # return response by using #call_with_allow_headers. return call_with_allow_headers( env, neighbor.allow_header, neighbor.endpoint ) if neighbor && method == 'OPTIONS' && !cascade route = match?(input, '*') return neighbor.endpoint.call(env) if neighbor && cascade && route if route response = process_route(route, env) return response if response && !(cascade = cascade?(response)) end !cascade && neighbor ? call_with_allow_headers(env, neighbor.allow_header, neighbor.endpoint) : nil end def process_route(route, env) input, = *extract_input_and_method(env) routing_args = env[Grape::Env::GRAPE_ROUTING_ARGS] env[Grape::Env::GRAPE_ROUTING_ARGS] = make_routing_args(routing_args, route, input) route.exec(env) end def make_routing_args(default_args, route, input) args = default_args || { route_info: route } args.merge(route.params(input)) end def extract_input_and_method(env) input = string_for(env[Grape::Http::Headers::PATH_INFO]) method = env[Grape::Http::Headers::REQUEST_METHOD] [input, method] end def with_optimization compile! unless compiled yield || default_response end def default_response [404, { Grape::Http::Headers::X_CASCADE => 'pass' }, ['404 Not Found']] end def match?(input, method) current_regexp = @optimized_map[method] return unless current_regexp.match(input) last_match = Regexp.last_match @map[method].detect { |route| last_match["_#{route.index}"] } end def greedy_match?(input) return unless @union.match(input) last_match = Regexp.last_match @neutral_map.detect { |route| last_match["_#{route.index}"] } end def call_with_allow_headers(env, methods, endpoint) env[Grape::Env::GRAPE_ALLOWED_METHODS] = methods endpoint.call(env) end def cascade?(response) response && response[1][Grape::Http::Headers::X_CASCADE] == 'pass' end def string_for(input) self.class.normalize_path(input) end end end grape-1.0.2/lib/grape/formatter/0000755000004100000410000000000013231337007016506 5ustar www-datawww-datagrape-1.0.2/lib/grape/formatter/xml.rb0000644000004100000410000000042513231337007017634 0ustar www-datawww-datamodule Grape module Formatter module Xml class << self def call(object, _env) return object.to_xml if object.respond_to?(:to_xml) raise Grape::Exceptions::InvalidFormatter.new(object.class, 'xml') end end end end end grape-1.0.2/lib/grape/formatter/json.rb0000644000004100000410000000036013231337007020003 0ustar www-datawww-datamodule Grape module Formatter module Json class << self def call(object, _env) return object.to_json if object.respond_to?(:to_json) ::Grape::Json.dump(object) end end end end end grape-1.0.2/lib/grape/formatter/serializable_hash.rb0000644000004100000410000000205213231337007022503 0ustar www-datawww-datamodule Grape module Formatter module SerializableHash class << self def call(object, _env) return object if object.is_a?(String) return ::Grape::Json.dump(serialize(object)) if serializable?(object) return object.to_json if object.respond_to?(:to_json) ::Grape::Json.dump(object) end private def serializable?(object) object.respond_to?(:serializable_hash) || object.is_a?(Array) && object.all? { |o| o.respond_to? :serializable_hash } || object.is_a?(Hash) end def serialize(object) if object.respond_to? :serializable_hash object.serializable_hash elsif object.is_a?(Array) && object.all? { |o| o.respond_to? :serializable_hash } object.map(&:serializable_hash) elsif object.is_a?(Hash) h = {} object.each_pair do |k, v| h[k] = serialize(v) end h else object end end end end end end grape-1.0.2/lib/grape/formatter/txt.rb0000644000004100000410000000031613231337007017652 0ustar www-datawww-datamodule Grape module Formatter module Txt class << self def call(object, _env) object.respond_to?(:to_txt) ? object.to_txt : object.to_s end end end end end grape-1.0.2/lib/grape/parser.rb0000644000004100000410000000117113231337007016324 0ustar www-datawww-datamodule Grape module Parser extend Util::Registrable class << self def builtin_parsers @builtin_parsers ||= { json: Grape::Parser::Json, jsonapi: Grape::Parser::Json, xml: Grape::Parser::Xml } end def parsers(options) builtin_parsers.merge(default_elements).merge(options[:parsers] || {}) end def parser_for(api_format, **options) spec = parsers(**options)[api_format] case spec when nil nil when Symbol method(spec) else spec end end end end end grape-1.0.2/lib/grape/path.rb0000644000004100000410000000352313231337007015767 0ustar www-datawww-datamodule Grape # Represents a path to an endpoint. class Path def self.prepare(raw_path, namespace, settings) Path.new(raw_path, namespace, settings) end attr_reader :raw_path, :namespace, :settings def initialize(raw_path, namespace, settings) @raw_path = raw_path @namespace = namespace @settings = settings end def mount_path settings[:mount_path] end def root_prefix split_setting(:root_prefix) end def uses_specific_format? if settings.key?(:format) && settings.key?(:content_types) (settings[:format] && Array(settings[:content_types]).size == 1) else false end end def uses_path_versioning? if settings.key?(:version) && settings[:version_options] && settings[:version_options].key?(:using) (settings[:version] && settings[:version_options][:using] == :path) else false end end def namespace? namespace && namespace.to_s =~ /^\S/ && namespace != '/' end def path? raw_path && raw_path.to_s =~ /^\S/ && raw_path != '/' end def suffix if uses_specific_format? "(.#{settings[:format]})" elsif !uses_path_versioning? || (namespace? || path?) '(.:format)' else '(/.:format)' end end def path Grape::Router.normalize_path(parts.join('/')) end def path_with_suffix "#{path}#{suffix}" end def to_s path_with_suffix end private def parts parts = [mount_path, root_prefix].compact parts << ':version' if uses_path_versioning? parts << namespace.to_s parts << raw_path.to_s parts.flatten.reject { |part| part == '/' } end def split_setting(key) return if settings[key].nil? settings[key].to_s.split('/') end end end grape-1.0.2/lib/grape/parser/0000755000004100000410000000000013231337007015777 5ustar www-datawww-datagrape-1.0.2/lib/grape/parser/xml.rb0000644000004100000410000000056413231337007017131 0ustar www-datawww-datamodule Grape module Parser module Xml class << self def call(object, _env) ::Grape::Xml.parse(object) rescue ::Grape::Xml::ParseError # handle XML parsing errors via the rescue handlers or provide error message raise Grape::Exceptions::InvalidMessageBody, 'application/xml' end end end end end grape-1.0.2/lib/grape/parser/json.rb0000644000004100000410000000057013231337007017277 0ustar www-datawww-datamodule Grape module Parser module Json class << self def call(object, _env) ::Grape::Json.load(object) rescue ::Grape::Json::ParseError # handle JSON parsing errors via the rescue handlers or provide error message raise Grape::Exceptions::InvalidMessageBody, 'application/json' end end end end end grape-1.0.2/lib/grape/api/0000755000004100000410000000000013231337007015254 5ustar www-datawww-datagrape-1.0.2/lib/grape/api/helpers.rb0000644000004100000410000000015413231337007017243 0ustar www-datawww-datamodule Grape class API module Helpers include Grape::DSL::Helpers::BaseHelper end end end grape-1.0.2/lib/grape/request.rb0000644000004100000410000000156013231337007016522 0ustar www-datawww-datamodule Grape class Request < Rack::Request HTTP_PREFIX = 'HTTP_'.freeze alias rack_params params def initialize(env, options = {}) extend options[:build_params_with] || Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder super(env) end def params @params ||= build_params end def headers @headers ||= build_headers end private def grape_routing_args args = env[Grape::Env::GRAPE_ROUTING_ARGS].dup # preserve version from query string parameters args.delete(:version) args.delete(:route_info) args end def build_headers headers = {} env.each_pair do |k, v| next unless k.to_s.start_with? HTTP_PREFIX k = k[5..-1].split('_').each(&:capitalize!).join('-') headers[k] = v end headers end end end grape-1.0.2/lib/grape/api.rb0000644000004100000410000002013113231337007015576 0ustar www-datawww-datarequire 'grape/router' module Grape # The API class is the primary entry point for creating Grape APIs. Users # should subclass this class in order to build an API. class API include Grape::DSL::API class << self attr_reader :instance # A class-level lock to ensure the API is not compiled by multiple # threads simultaneously within the same process. LOCK = Mutex.new # Clears all defined routes, endpoints, etc., on this API. def reset! reset_endpoints! reset_routes! reset_validations! end # Parses the API's definition and compiles it into an instance of # Grape::API. def compile @instance ||= new end # Wipe the compiled API so we can recompile after changes were made. def change! @instance = nil end # This is the interface point between Rack and Grape; it accepts a request # from Rack and ultimately returns an array of three values: the status, # the headers, and the body. See [the rack specification] # (http://www.rubydoc.info/github/rack/rack/master/file/SPEC) for more. def call(env) LOCK.synchronize { compile } unless instance call!(env) end # A non-synchronized version of ::call. def call!(env) instance.call(env) end # (see #cascade?) def cascade(value = nil) if value.nil? inheritable_setting.namespace_inheritable.keys.include?(:cascade) ? !namespace_inheritable(:cascade).nil? : true else namespace_inheritable(:cascade, value) end end # see Grape::Router#recognize_path def recognize_path(path) LOCK.synchronize { compile } unless instance instance.router.recognize_path(path) end protected def prepare_routes endpoints.map(&:routes).flatten end # Execute first the provided block, then each of the # block passed in. Allows for simple 'before' setups # of settings stack pushes. def nest(*blocks, &block) blocks.reject!(&:nil?) if blocks.any? instance_eval(&block) if block_given? blocks.each { |b| instance_eval(&b) } reset_validations! else instance_eval(&block) end end def inherited(subclass) subclass.reset! subclass.logger = logger.clone end def inherit_settings(other_settings) top_level_setting.inherit_from other_settings.point_in_time_copy # Propagate any inherited params down to our endpoints, and reset any # compiled routes. endpoints.each do |e| e.inherit_settings(top_level_setting.namespace_stackable) e.reset_routes! end reset_routes! end end attr_reader :router # Builds the routes from the defined endpoints, effectively compiling # this API into a usable form. def initialize @router = Router.new add_head_not_allowed_methods_and_options_methods self.class.endpoints.each do |endpoint| endpoint.mount_in(@router) end @router.compile! @router.freeze end # Handle a request. See Rack documentation for what `env` is. def call(env) result = @router.call(env) result[1].delete(Grape::Http::Headers::X_CASCADE) unless cascade? result end # Some requests may return a HTTP 404 error if grape cannot find a matching # route. In this case, Grape::Router adds a X-Cascade header to the response # and sets it to 'pass', indicating to grape's parents they should keep # looking for a matching route on other resources. # # In some applications (e.g. mounting grape on rails), one might need to trap # errors from reaching upstream. This is effectivelly done by unsetting # X-Cascade. Default :cascade is true. def cascade? return self.class.namespace_inheritable(:cascade) if self.class.inheritable_setting.namespace_inheritable.keys.include?(:cascade) return self.class.namespace_inheritable(:version_options)[:cascade] if self.class.namespace_inheritable(:version_options) && self.class.namespace_inheritable(:version_options).key?(:cascade) true end reset! private # For every resource add a 'OPTIONS' route that returns an HTTP 204 response # with a list of HTTP methods that can be called. Also add a route that # will return an HTTP 405 response for any HTTP method that the resource # cannot handle. def add_head_not_allowed_methods_and_options_methods routes_map = {} self.class.endpoints.each do |endpoint| routes = endpoint.routes routes.each do |route| # using the :any shorthand produces [nil] for route methods, substitute all manually route_key = route.pattern.to_regexp routes_map[route_key] ||= {} route_settings = routes_map[route_key] route_settings[:pattern] = route.pattern route_settings[:requirements] = route.requirements route_settings[:path] = route.origin route_settings[:methods] ||= [] route_settings[:methods] << route.request_method route_settings[:endpoint] = route.app # using the :any shorthand produces [nil] for route methods, substitute all manually route_settings[:methods] = %w[GET PUT POST DELETE PATCH HEAD OPTIONS] if route_settings[:methods].include?('*') end end # The paths we collected are prepared (cf. Path#prepare), so they # contain already versioning information when using path versioning. # Disable versioning so adding a route won't prepend versioning # informations again. without_root_prefix do without_versioning do routes_map.each do |_, config| methods = config[:methods] allowed_methods = methods.dup unless self.class.namespace_inheritable(:do_not_route_head) allowed_methods |= [Grape::Http::Headers::HEAD] if allowed_methods.include?(Grape::Http::Headers::GET) end allow_header = (self.class.namespace_inheritable(:do_not_route_options) ? allowed_methods : [Grape::Http::Headers::OPTIONS] | allowed_methods).join(', ') unless self.class.namespace_inheritable(:do_not_route_options) || allowed_methods.include?(Grape::Http::Headers::OPTIONS) config[:endpoint].options[:options_route_enabled] = true end attributes = config.merge(allowed_methods: allowed_methods, allow_header: allow_header) generate_not_allowed_method(config[:pattern], attributes) end end end end # Generate a route that returns an HTTP 405 response for a user defined # path on methods not specified def generate_not_allowed_method(pattern, allowed_methods: [], **attributes) not_allowed_methods = %w[GET PUT POST DELETE PATCH HEAD] - allowed_methods not_allowed_methods << Grape::Http::Headers::OPTIONS if self.class.namespace_inheritable(:do_not_route_options) return if not_allowed_methods.empty? @router.associate_routes(pattern, not_allowed_methods: not_allowed_methods, **attributes) end # Allows definition of endpoints that ignore the versioning configuration # used by the rest of your API. def without_versioning(&_block) old_version = self.class.namespace_inheritable(:version) old_version_options = self.class.namespace_inheritable(:version_options) self.class.namespace_inheritable_to_nil(:version) self.class.namespace_inheritable_to_nil(:version_options) yield self.class.namespace_inheritable(:version, old_version) self.class.namespace_inheritable(:version_options, old_version_options) end # Allows definition of endpoints that ignore the root prefix used by the # rest of your API. def without_root_prefix(&_block) old_prefix = self.class.namespace_inheritable(:root_prefix) self.class.namespace_inheritable_to_nil(:root_prefix) yield self.class.namespace_inheritable(:root_prefix, old_prefix) end end end grape-1.0.2/lib/grape/endpoint.rb0000644000004100000410000003332113231337007016652 0ustar www-datawww-datamodule Grape # An Endpoint is the proxy scope in which all routing # blocks are executed. In other words, any methods # on the instance level of this class may be called # from inside a `get`, `post`, etc. class Endpoint include Grape::DSL::Settings include Grape::DSL::InsideRoute attr_accessor :block, :source, :options attr_reader :env, :request, :headers, :params class << self def new(*args, &block) self == Endpoint ? Class.new(Endpoint).new(*args, &block) : super end def before_each(new_setup = false, &block) @before_each ||= [] if new_setup == false return @before_each unless block_given? @before_each << block else @before_each = [new_setup] end end def run_before_each(endpoint) superclass.run_before_each(endpoint) unless self == Endpoint before_each.each { |blk| blk.call(endpoint) if blk.respond_to?(:call) } end # @api private # # Create an UnboundMethod that is appropriate for executing an endpoint # route. # # The unbound method allows explicit calls to +return+ without raising a # +LocalJumpError+. The method will be removed, but a +Proc+ reference to # it will be returned. The returned +Proc+ expects a single argument: the # instance of +Endpoint+ to bind to the method during the call. # # @param [String, Symbol] method_name # @return [Proc] # @raise [NameError] an instance method with the same name already exists def generate_api_method(method_name, &block) if method_defined?(method_name) raise NameError.new("method #{method_name.inspect} already exists and cannot be used as an unbound method name") end define_method(method_name, &block) method = instance_method(method_name) remove_method(method_name) proc do |endpoint_instance| ActiveSupport::Notifications.instrument('endpoint_render.grape', endpoint: endpoint_instance) do method.bind(endpoint_instance).call end end end end # Create a new endpoint. # @param new_settings [InheritableSetting] settings to determine the params, # validations, and other properties from. # @param options [Hash] attributes of this endpoint # @option options path [String or Array] the path to this endpoint, within # the current scope. # @option options method [String or Array] which HTTP method(s) can be used # to reach this endpoint. # @option options route_options [Hash] # @note This happens at the time of API definition, so in this context the # endpoint does not know if it will be mounted under a different endpoint. # @yield a block defining what your API should do when this endpoint is hit def initialize(new_settings, options = {}, &block) require_option(options, :path) require_option(options, :method) self.inheritable_setting = new_settings.point_in_time_copy route_setting(:saved_declared_params, namespace_stackable(:declared_params)) route_setting(:saved_validations, namespace_stackable(:validations)) namespace_stackable(:representations, []) unless namespace_stackable(:representations) namespace_inheritable(:default_error_status, 500) unless namespace_inheritable(:default_error_status) @options = options @options[:path] = Array(options[:path]) @options[:path] << '/' if options[:path].empty? @options[:method] = Array(options[:method]) @options[:route_options] ||= {} @lazy_initialize_lock = Mutex.new @lazy_initialized = nil @block = nil @status = nil @file = nil @body = nil @proc = nil return unless block_given? @source = block @block = self.class.generate_api_method(method_name, &block) end # Update our settings from a given set of stackable parameters. Used when # the endpoint's API is mounted under another one. def inherit_settings(namespace_stackable) inheritable_setting.route[:saved_validations] += namespace_stackable[:validations] parent_declared_params = namespace_stackable[:declared_params] if parent_declared_params inheritable_setting.route[:declared_params] ||= [] inheritable_setting.route[:declared_params].concat(parent_declared_params.flatten) end endpoints && endpoints.each { |e| e.inherit_settings(namespace_stackable) } end def require_option(options, key) raise Grape::Exceptions::MissingOption.new(key) unless options.key?(key) end def method_name [options[:method], Namespace.joined_space(namespace_stackable(:namespace)), (namespace_stackable(:mount_path) || []).join('/'), options[:path].join('/')] .join(' ') end def routes @routes ||= endpoints ? endpoints.collect(&:routes).flatten : to_routes end def reset_routes! endpoints.each(&:reset_routes!) if endpoints @namespace = nil @routes = nil end def mount_in(router) if endpoints endpoints.each { |e| e.mount_in(router) } else reset_routes! routes.each do |route| methods = [route.request_method] if !namespace_inheritable(:do_not_route_head) && route.request_method == Grape::Http::Headers::GET methods << Grape::Http::Headers::HEAD end methods.each do |method| unless route.request_method.to_s.upcase == method route = Grape::Router::Route.new(method, route.origin, route.attributes.to_h) end router.append(route.apply(self)) end end end end def to_routes route_options = prepare_default_route_attributes map_routes do |method, path| path = prepare_path(path) params = merge_route_options(route_options.merge(suffix: path.suffix)) route = Router::Route.new(method, path.path, params) route.apply(self) end.flatten end def prepare_routes_requirements endpoint_requirements = options[:route_options][:requirements] || {} all_requirements = (namespace_stackable(:namespace).map(&:requirements) << endpoint_requirements) all_requirements.reduce({}) do |base_requirements, single_requirements| base_requirements.merge!(single_requirements) end end def prepare_default_route_attributes { namespace: namespace, version: prepare_version, requirements: prepare_routes_requirements, prefix: namespace_inheritable(:root_prefix), anchor: options[:route_options].fetch(:anchor, true), settings: inheritable_setting.route.except(:saved_declared_params, :saved_validations), forward_match: options[:forward_match] } end def prepare_version version = namespace_inheritable(:version) || [] return if version.empty? version.length == 1 ? version.first.to_s : version end def merge_route_options(**default) options[:route_options].clone.reverse_merge(**default) end def map_routes options[:method].map { |method| options[:path].map { |path| yield method, path } } end def prepare_path(path) path_settings = inheritable_setting.to_hash[:namespace_stackable].merge(inheritable_setting.to_hash[:namespace_inheritable]) Path.prepare(path, namespace, path_settings) end def namespace @namespace ||= Namespace.joined_space_path(namespace_stackable(:namespace)) end def call(env) lazy_initialize! dup.call!(env) end def call!(env) env[Grape::Env::API_ENDPOINT] = self @env = env @app.call(env) end # Return the collection of endpoints within this endpoint. # This is the case when an Grape::API mounts another Grape::API. def endpoints options[:app].endpoints if options[:app] && options[:app].respond_to?(:endpoints) end def equals?(e) (options == e.options) && (inheritable_setting.to_hash == e.inheritable_setting.to_hash) end protected def run ActiveSupport::Notifications.instrument('endpoint_run.grape', endpoint: self, env: env) do @header = {} @request = Grape::Request.new(env, build_params_with: namespace_inheritable(:build_params_with)) @params = @request.params @headers = @request.headers cookies.read(@request) self.class.run_before_each(self) run_filters befores, :before if (allowed_methods = env[Grape::Env::GRAPE_ALLOWED_METHODS]) raise Grape::Exceptions::MethodNotAllowed, header.merge('Allow' => allowed_methods) unless options? header 'Allow', allowed_methods response_object = '' status 204 else run_filters before_validations, :before_validation run_validators validations, request run_filters after_validations, :after_validation response_object = @block ? @block.call(self) : nil end run_filters afters, :after cookies.write(header) # status verifies body presence when DELETE @body ||= response_object # The Body commonly is an Array of Strings, the application instance itself, or a File-like object response_object = file || [body] [status, header, response_object] end end def build_stack(helpers) stack = Grape::Middleware::Stack.new stack.use Rack::Head stack.use Class.new(Grape::Middleware::Error), helpers: helpers, format: namespace_inheritable(:format), content_types: namespace_stackable_with_hash(:content_types), default_status: namespace_inheritable(:default_error_status), rescue_all: namespace_inheritable(:rescue_all), rescue_grape_exceptions: namespace_inheritable(:rescue_grape_exceptions), default_error_formatter: namespace_inheritable(:default_error_formatter), error_formatters: namespace_stackable_with_hash(:error_formatters), rescue_options: namespace_stackable_with_hash(:rescue_options) || {}, rescue_handlers: namespace_reverse_stackable_with_hash(:rescue_handlers) || {}, base_only_rescue_handlers: namespace_stackable_with_hash(:base_only_rescue_handlers) || {}, all_rescue_handler: namespace_inheritable(:all_rescue_handler) stack.concat namespace_stackable(:middleware) if namespace_inheritable(:version) stack.use Grape::Middleware::Versioner.using(namespace_inheritable(:version_options)[:using]), versions: namespace_inheritable(:version) ? namespace_inheritable(:version).flatten : nil, version_options: namespace_inheritable(:version_options), prefix: namespace_inheritable(:root_prefix), mount_path: namespace_stackable(:mount_path).first end stack.use Grape::Middleware::Formatter, format: namespace_inheritable(:format), default_format: namespace_inheritable(:default_format) || :txt, content_types: namespace_stackable_with_hash(:content_types), formatters: namespace_stackable_with_hash(:formatters), parsers: namespace_stackable_with_hash(:parsers) builder = stack.build builder.run ->(env) { env[Grape::Env::API_ENDPOINT].run } builder.to_app end def build_helpers helpers = namespace_stackable(:helpers) || [] Module.new { helpers.each { |mod_to_include| include mod_to_include } } end private :build_stack, :build_helpers def helpers lazy_initialize! && @helpers end def lazy_initialize! return true if @lazy_initialized @lazy_initialize_lock.synchronize do return true if @lazy_initialized @helpers = build_helpers.tap { |mod| self.class.send(:include, mod) } @app = options[:app] || build_stack(@helpers) @lazy_initialized = true end end def run_validators(validator_factories, request) validation_errors = [] validators = validator_factories.map(&:create_validator) ActiveSupport::Notifications.instrument('endpoint_run_validators.grape', endpoint: self, validators: validators, request: request) do validators.each do |validator| begin validator.validate(request) rescue Grape::Exceptions::Validation => e validation_errors << e break if validator.fail_fast? rescue Grape::Exceptions::ValidationArrayErrors => e validation_errors += e.errors break if validator.fail_fast? end end end validation_errors.any? && raise(Grape::Exceptions::ValidationErrors, errors: validation_errors, headers: header) end def run_filters(filters, type = :other) ActiveSupport::Notifications.instrument('endpoint_run_filters.grape', endpoint: self, filters: filters, type: type) do (filters || []).each { |filter| instance_eval(&filter) } end post_extension = DSL::InsideRoute.post_filter_methods(type) extend post_extension if post_extension end def befores namespace_stackable(:befores) || [] end def before_validations namespace_stackable(:before_validations) || [] end def after_validations namespace_stackable(:after_validations) || [] end def afters namespace_stackable(:afters) || [] end def validations route_setting(:saved_validations) || [] end def options? options[:options_route_enabled] && env[Grape::Http::Headers::REQUEST_METHOD] == Grape::Http::Headers::OPTIONS end end end grape-1.0.2/lib/grape/version.rb0000644000004100000410000000011613231337007016513 0ustar www-datawww-datamodule Grape # The current version of Grape. VERSION = '1.0.2'.freeze end grape-1.0.2/lib/grape/validations/0000755000004100000410000000000013231337007017020 5ustar www-datawww-datagrape-1.0.2/lib/grape/validations/params_scope.rb0000644000004100000410000004300713231337007022025 0ustar www-datawww-datamodule Grape module Validations class ParamsScope attr_accessor :element, :parent, :index attr_reader :type include Grape::DSL::Parameters # Open up a new ParamsScope, allowing parameter definitions per # Grape::DSL::Params. # @param opts [Hash] options for this scope # @option opts :element [Symbol] the element that contains this scope; for # this to be relevant, @parent must be set # @option opts :parent [ParamsScope] the scope containing this scope # @option opts :api [API] the API endpoint to modify # @option opts :optional [Boolean] whether or not this scope needs to have # any parameters set or not # @option opts :type [Class] a type meant to govern this scope (deprecated) # @option opts :type [Hash] group options for this scope # @option opts :dependent_on [Symbol] if present, this scope should only # validate if this param is present in the parent scope # @yield the instance context, open for parameter definitions def initialize(opts, &block) @element = opts[:element] @parent = opts[:parent] @api = opts[:api] @optional = opts[:optional] || false @type = opts[:type] @group = opts[:group] || {} @dependent_on = opts[:dependent_on] @declared_params = [] @index = nil instance_eval(&block) if block_given? configure_declared_params end # @return [Boolean] whether or not this entire scope needs to be # validated def should_validate?(parameters) return false if @optional && (params(parameters).blank? || all_element_blank?(parameters)) return true if parent.nil? parent.should_validate?(parameters) end def meets_dependency?(params, request_params) if @parent.present? && !@parent.meets_dependency?(@parent.params(request_params), request_params) return false end return true unless @dependent_on params = params.with_indifferent_access @dependent_on.each do |dependency| if dependency.is_a?(Hash) dependency_key = dependency.keys[0] proc = dependency.values[0] return false unless proc.call(params.try(:[], dependency_key)) elsif params.respond_to?(:key?) && params.try(:[], dependency).blank? return false end end true end # @return [String] the proper attribute name, with nesting considered. def full_name(name, index: nil) if nested? # Find our containing element's name, and append ours. [@parent.full_name(@element), [@index || index, name].map(&method(:brackets))].compact.join elsif lateral? # Find the name of the element as if it was at the same nesting level # as our parent. We need to forward our index upward to achieve this. @parent.full_name(name, index: @index) else # We must be the root scope, so no prefix needed. name.to_s end end def brackets(val) "[#{val}]" if val end # @return [Boolean] whether or not this scope is the root-level scope def root? !@parent end # A nested scope is contained in one of its parent's elements. # @return [Boolean] whether or not this scope is nested def nested? @parent && @element end # A lateral scope is subordinate to its parent, but its keys are at the # same level as its parent and thus is not contained within an element. # @return [Boolean] whether or not this scope is lateral def lateral? @parent && !@element end # @return [Boolean] whether or not this scope needs to be present, or can # be blank def required? !@optional end protected # Adds a parameter declaration to our list of validations. # @param attrs [Array] (see Grape::DSL::Parameters#requires) def push_declared_params(attrs, **opts) if lateral? @parent.push_declared_params(attrs) else if opts && opts[:as] @api.route_setting(:aliased_params, @api.route_setting(:aliased_params) || []) @api.route_setting(:aliased_params) << { attrs.first => opts[:as] } end @declared_params.concat attrs end end private def require_required_and_optional_fields(context, opts) if context == :all optional_fields = Array(opts[:except]) required_fields = opts[:using].keys - optional_fields else # context == :none required_fields = Array(opts[:except]) optional_fields = opts[:using].keys - required_fields end required_fields.each do |field| field_opts = opts[:using][field] raise ArgumentError, "required field not exist: #{field}" unless field_opts requires(field, field_opts) end optional_fields.each do |field| field_opts = opts[:using][field] optional(field, field_opts) if field_opts end end def require_optional_fields(context, opts) optional_fields = opts[:using].keys optional_fields -= Array(opts[:except]) unless context == :all optional_fields.each do |field| field_opts = opts[:using][field] optional(field, field_opts) if field_opts end end def validate_attributes(attrs, opts, &block) validations = opts.clone validations[:type] ||= Array if block validates(attrs, validations) end # Returns a new parameter scope, subordinate to the current one and nested # under the parameter corresponding to `attrs.first`. # @param attrs [Array] the attributes passed to the `requires` or # `optional` invocation that opened this scope. # @param optional [Boolean] whether the parameter this are nested under # is optional or not (and hence, whether this block's params will be). # @yield parameter scope def new_scope(attrs, optional = false, &block) # if required params are grouped and no type or unsupported type is provided, raise an error type = attrs[1] ? attrs[1][:type] : nil if attrs.first && !optional raise Grape::Exceptions::MissingGroupTypeError.new if type.nil? raise Grape::Exceptions::UnsupportedGroupTypeError.new unless Grape::Validations::Types.group?(type) end opts = attrs[1] || { type: Array } self.class.new( api: @api, element: attrs.first, parent: self, optional: optional, type: opts[:type], &block ) end # Returns a new parameter scope, not nested under any current-level param # but instead at the same level as the current scope. # @param options [Hash] options to control how this new scope behaves # @option options :dependent_on [Symbol] if given, specifies that this # scope should only validate if this parameter from the above scope is # present # @yield parameter scope def new_lateral_scope(options, &block) self.class.new( api: @api, element: nil, parent: self, options: @optional, type: type == Array ? Array : Hash, dependent_on: options[:dependent_on], &block ) end # Returns a new parameter scope, subordinate to the current one and nested # under the parameter corresponding to `attrs.first`. # @param attrs [Array] the attributes passed to the `requires` or # `optional` invocation that opened this scope. # @yield parameter scope def new_group_scope(attrs, &block) self.class.new( api: @api, parent: self, group: attrs.first, &block ) end # Pushes declared params to parent or settings def configure_declared_params if nested? @parent.push_declared_params [element => @declared_params] else @api.namespace_stackable(:declared_params, @declared_params) @api.route_setting(:declared_params, []) unless @api.route_setting(:declared_params) @api.route_setting(:declared_params, @api.namespace_stackable(:declared_params).flatten) end end def validates(attrs, validations) doc_attrs = { required: validations.keys.include?(:presence) } coerce_type = infer_coercion(validations) doc_attrs[:type] = coerce_type.to_s if coerce_type desc = validations.delete(:desc) || validations.delete(:description) doc_attrs[:desc] = desc if desc default = validations[:default] doc_attrs[:default] = default if validations.key?(:default) if (values_hash = validations[:values]).is_a? Hash values = values_hash[:value] # NB: excepts is deprecated excepts = values_hash[:except] else values = validations[:values] end doc_attrs[:values] = values if values except_values = options_key?(:except_values, :value, validations) ? validations[:except_values][:value] : validations[:except_values] # NB. values and excepts should be nil, Proc, Array, or Range. # Specifically, values should NOT be a Hash # use values or excepts to guess coerce type when stated type is Array coerce_type = guess_coerce_type(coerce_type, values, except_values, excepts) # default value should be present in values array, if both exist and are not procs check_incompatible_option_values(default, values, except_values, excepts) # type should be compatible with values array, if both exist validate_value_coercion(coerce_type, values, except_values, excepts) doc_attrs[:documentation] = validations.delete(:documentation) if validations.key?(:documentation) full_attrs = attrs.collect { |name| { name: name, full_name: full_name(name) } } @api.document_attribute(full_attrs, doc_attrs) # slice out fail_fast attribute opts = {} opts[:fail_fast] = validations.delete(:fail_fast) || false # Validate for presence before any other validators if validations.key?(:presence) && validations[:presence] validate('presence', validations[:presence], attrs, doc_attrs, opts) validations.delete(:presence) validations.delete(:message) if validations.key?(:message) end # Before we run the rest of the validators, let's handle # whatever coercion so that we are working with correctly # type casted values coerce_type validations, attrs, doc_attrs, opts validations.each do |type, options| validate(type, options, attrs, doc_attrs, opts) end end # Validate and comprehend the +:type+, +:types+, and +:coerce_with+ # options that have been supplied to the parameter declaration. # The +:type+ and +:types+ options will be removed from the # validations list, replaced appropriately with +:coerce+ and # +:coerce_with+ options that will later be passed to # {Validators::CoerceValidator}. The type that is returned may be # used for documentation and further validation of parameter # options. # # @param validations [Hash] list of validations supplied to the # parameter declaration # @return [class-like] type to which the parameter will be coerced # @raise [ArgumentError] if the given type options are invalid def infer_coercion(validations) if validations.key?(:type) && validations.key?(:types) raise ArgumentError, ':type may not be supplied with :types' end validations[:coerce] = (options_key?(:type, :value, validations) ? validations[:type][:value] : validations[:type]) if validations.key?(:type) validations[:coerce_message] = (options_key?(:type, :message, validations) ? validations[:type][:message] : nil) if validations.key?(:type) validations[:coerce] = (options_key?(:types, :value, validations) ? validations[:types][:value] : validations[:types]) if validations.key?(:types) validations[:coerce_message] = (options_key?(:types, :message, validations) ? validations[:types][:message] : nil) if validations.key?(:types) validations.delete(:types) if validations.key?(:types) coerce_type = validations[:coerce] # Special case - when the argument is a single type that is a # variant-type collection. if Types.multiple?(coerce_type) && validations.key?(:type) validations[:coerce] = Types::VariantCollectionCoercer.new( coerce_type, validations.delete(:coerce_with) ) end validations.delete(:type) coerce_type end # Enforce correct usage of :coerce_with parameter. # We do not allow coercion without a type, nor with # +JSON+ as a type since this defines its own coercion # method. def check_coerce_with(validations) return unless validations.key?(:coerce_with) # type must be supplied for coerce_with.. raise ArgumentError, 'must supply type for coerce_with' unless validations.key?(:coerce) # but not special JSON types, which # already imply coercion method return unless [JSON, Array[JSON]].include? validations[:coerce] raise ArgumentError, 'coerce_with disallowed for type: JSON' end # Add type coercion validation to this scope, # if any has been specified. # This validation has special handling since it is # composited from more than one +requires+/+optional+ # parameter, and needs to be run before most other # validations. def coerce_type(validations, attrs, doc_attrs, opts) check_coerce_with(validations) return unless validations.key?(:coerce) coerce_options = { type: validations[:coerce], method: validations[:coerce_with], message: validations[:coerce_message] } validate('coerce', coerce_options, attrs, doc_attrs, opts) validations.delete(:coerce_with) validations.delete(:coerce) validations.delete(:coerce_message) end def guess_coerce_type(coerce_type, *values_list) return coerce_type unless coerce_type == Array values_list.each do |values| next if !values || values.is_a?(Proc) return values.first.class if values.is_a?(Range) || !values.empty? end coerce_type end def check_incompatible_option_values(default, values, except_values, excepts) return unless default && !default.is_a?(Proc) if values && !values.is_a?(Proc) raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :values, values) \ unless Array(default).all? { |def_val| values.include?(def_val) } end if except_values && !except_values.is_a?(Proc) raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :except, except_values) \ unless Array(default).none? { |def_val| except_values.include?(def_val) } end return unless excepts && !excepts.is_a?(Proc) raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :except, excepts) \ unless Array(default).none? { |def_val| excepts.include?(def_val) } end def validate(type, options, attrs, doc_attrs, opts) validator_class = Validations.validators[type.to_s] raise Grape::Exceptions::UnknownValidator.new(type) unless validator_class factory = Grape::Validations::ValidatorFactory.new(attributes: attrs, options: options, required: doc_attrs[:required], params_scope: self, opts: opts, validator_class: validator_class) @api.namespace_stackable(:validations, factory) end def validate_value_coercion(coerce_type, *values_list) return unless coerce_type coerce_type = coerce_type.first if coerce_type.is_a?(Array) values_list.each do |values| next if !values || values.is_a?(Proc) value_types = values.is_a?(Range) ? [values.begin, values.end] : values if coerce_type == Virtus::Attribute::Boolean value_types = value_types.map { |type| Virtus::Attribute.build(type) } end unless value_types.all? { |v| v.is_a? coerce_type } raise Grape::Exceptions::IncompatibleOptionValues.new(:type, coerce_type, :values, values) end end end def extract_message_option(attrs) return nil unless attrs.is_a?(Array) opts = attrs.last.is_a?(Hash) ? attrs.pop : {} opts.key?(:message) && !opts[:message].nil? ? opts.delete(:message) : nil end def options_key?(type, key, validations) validations[type].respond_to?(:key?) && validations[type].key?(key) && !validations[type][key].nil? end def all_element_blank?(parameters) params(parameters).respond_to?(:all?) && params(parameters).all?(&:blank?) end end end end grape-1.0.2/lib/grape/validations/validator_factory.rb0000644000004100000410000000077113231337007023066 0ustar www-datawww-datamodule Grape module Validations class ValidatorFactory def initialize(**options) @validator_class = options.delete(:validator_class) @options = options end def create_validator @validator_class.new(@options[:attributes], @options[:options], @options[:required], @options[:params_scope], @options[:opts]) end end end end grape-1.0.2/lib/grape/validations/types.rb0000644000004100000410000001322713231337007020516 0ustar www-datawww-datarequire_relative 'types/build_coercer' require_relative 'types/custom_type_coercer' require_relative 'types/custom_type_collection_coercer' require_relative 'types/multiple_type_coercer' require_relative 'types/variant_collection_coercer' require_relative 'types/json' require_relative 'types/file' # Patch for Virtus::Attribute::Collection # See the file for more details require_relative 'types/virtus_collection_patch' module Grape module Validations # Module for code related to grape's system for # coercion and type validation of incoming request # parameters. # # Grape uses a number of tests and assertions to # work out exactly how a parameter should be handled, # based on the +type+ and +coerce_with+ options that # may be supplied to {Grape::Dsl::Parameters#requires} # and {Grape::Dsl::Parameters#optional}. The main # entry point for this process is {Types.build_coercer}. module Types # Instances of this class may be used as tokens to denote that # a parameter value could not be coerced. class InvalidValue; end # Types representing a single value, which are coerced through Virtus # or special logic in Grape. PRIMITIVES = [ # Numerical Integer, Float, BigDecimal, Numeric, # Date/time Date, DateTime, Time, # Misc Virtus::Attribute::Boolean, String, Symbol, Rack::Multipart::UploadedFile ].freeze # Types representing data structures. STRUCTURES = [ Hash, Array, Set ].freeze # Types for which Grape provides special coercion # and type-checking logic. SPECIAL = { JSON => Json, Array[JSON] => JsonArray, ::File => File, Rack::Multipart::UploadedFile => File }.freeze GROUPS = [ Array, Hash, JSON, Array[JSON] ].freeze # Is the given class a primitive type as recognized by Grape? # # @param type [Class] type to check # @return [Boolean] whether or not the type is known by Grape as a valid # type for a single value def self.primitive?(type) PRIMITIVES.include?(type) end # Is the given class a standard data structure (collection or map) # as recognized by Grape? # # @param type [Class] type to check # @return [Boolean] whether or not the type is known by Grape as a valid # data structure type # @note This method does not yet consider 'complex types', which inherit # Virtus.model. def self.structure?(type) STRUCTURES.include?(type) end # Is the declared type in fact an array of multiple allowed types? # For example the declaration +types: [Integer,String]+ will attempt # first to coerce given values to integer, but will also accept any # other string. # # @param type [Array,Set] type (or type list!) to check # @return [Boolean] +true+ if the given value will be treated as # a list of types. def self.multiple?(type) (type.is_a?(Array) || type.is_a?(Set)) && type.size > 1 end # Does the given class implement a type system that Grape # (i.e. the underlying virtus attribute system) supports # out-of-the-box? Currently supported are +axiom-types+ # and +virtus+. # # The type will be passed to +Virtus::Attribute.build+, # and the resulting attribute object will be expected to # respond correctly to +coerce+ and +value_coerced?+. # # @param type [Class] type to check # @return [Boolean] +true+ where the type is recognized def self.recognized?(type) return false if type.is_a?(Array) || type.is_a?(Set) type.is_a?(Virtus::Attribute) || type.ancestors.include?(Axiom::Types::Type) || type.include?(Virtus::Model::Core) end # Does Grape provide special coercion and validation # routines for the given class? This does not include # automatic handling for primitives, structures and # otherwise recognized types. See {Types::SPECIAL}. # # @param type [Class] type to check # @return [Boolean] +true+ if special routines are available def self.special?(type) SPECIAL.key? type end # Is the declared type a supported group type? # Currently supported group types are Array, Hash, JSON, and Array[JSON] # # @param type [Array,Class] type to check # @return [Boolean] +true+ if the type is a supported group type def self.group?(type) GROUPS.include? type end # A valid custom type must implement a class-level `parse` method, taking # one String argument and returning the parsed value in its correct type. # # @param type [Class] type to check # @return [Boolean] whether or not the type can be used as a custom type def self.custom?(type) !primitive?(type) && !structure?(type) && !multiple?(type) && !recognized?(type) && !special?(type) && type.respond_to?(:parse) && type.method(:parse).arity == 1 end # Is the declared type an +Array+ or +Set+ of a {#custom?} type? # # @param type [Array,Class] type to check # @return [Boolean] true if +type+ is a collection of a type that implements # its own +#parse+ method. def self.collection_of_custom?(type) (type.is_a?(Array) || type.is_a?(Set)) && type.length == 1 && custom?(type.first) end end end end grape-1.0.2/lib/grape/validations/types/0000755000004100000410000000000013231337007020164 5ustar www-datawww-datagrape-1.0.2/lib/grape/validations/types/multiple_type_coercer.rb0000644000004100000410000000627713231337007025123 0ustar www-datawww-datamodule Grape module Validations module Types # This class is intended for use with Grape endpoint parameters that # have been declared to be of variant-type using the +:types+ option. # +MultipleTypeCoercer+ will build a coercer for each type declared # in the array passed to +:types+ using {Types.build_coercer}. It will # apply these coercers to parameter values in the order given to # +:types+, and will return the value returned by the first coercer # to successfully coerce the parameter value. Therefore if +String+ is # an allowed type it should be declared last, since it will always # successfully "coerce" the value. class MultipleTypeCoercer # Construct a new coercer that will attempt to coerce # values to the given list of types in the given order. # # @param types [Array] list of allowed types # @param method [#call,#parse] method by which values should be # coerced. See class docs for default behaviour. def initialize(types, method = nil) @method = method.respond_to?(:parse) ? method.method(:parse) : method @type_coercers = types.map do |type| if Types.multiple? type VariantCollectionCoercer.new type else Types.build_coercer type end end end # This method is called from somewhere within # +Virtus::Attribute::coerce+ in order to coerce # the given value. # # @param value [String] value to be coerced, in grape # this should always be a string. # @return [Object,InvalidValue] the coerced result, or an instance # of {InvalidValue} if the value could not be coerced. def call(value) return @method.call(value) if @method @type_coercers.each do |coercer| coerced = coercer.coerce(value) return coerced if coercer.value_coerced? coerced end # Declare that we couldn't coerce the value in such a way # that Grape won't ask us again if the value is valid InvalidValue.new end # This method is called from somewhere within # +Virtus::Attribute::value_coerced?+ in order to # assert that the value has been coerced successfully. # Due to Grape's design this will in fact only be called # if a custom coercion method is being used, since {#call} # returns an {InvalidValue} object if the value could not # be coerced. # # @param _primitive [Axiom::Types::Type] primitive type # for the coercion as detected by axiom-types' inference # system. For custom types this is typically not much use # (i.e. it is +Axiom::Types::Object+) unless special # inference rules have been declared for the type. # @param value [Object] a coerced result returned from {#call} # @return [true,false] whether or not the coerced value # satisfies type requirements. def success?(_primitive, value) @type_coercers.any? { |coercer| coercer.value_coerced? value } end end end end end grape-1.0.2/lib/grape/validations/types/json.rb0000644000004100000410000000417413231337007021470 0ustar www-datawww-datarequire 'json' module Grape module Validations module Types # +Virtus::Attribute+ implementation that handles coercion # and type checking for parameters that are complex types # given as JSON-encoded strings. It accepts both JSON objects # and arrays of objects, and will coerce the input to a +Hash+ # or +Array+ object respectively. In either case the Grape # validation system will apply nested validation rules to # all returned objects. class Json < Virtus::Attribute # Coerce the input into a JSON-like data structure. # # @param input [String] a JSON-encoded parameter value # @return [Hash,Array,nil] def coerce(input) # Allow nulls and blank strings return if input.nil? || input =~ /^\s*$/ JSON.parse(input, symbolize_names: true) end # Checks that the input was parsed successfully # and isn't something odd such as an array of primitives. # # @param value [Object] result of {#coerce} # @return [true,false] def value_coerced?(value) value.is_a?(::Hash) || coerced_collection?(value) end protected # Is the value an array of JSON-like objects? # # @param value [Object] result of {#coerce} # @return [true,false] def coerced_collection?(value) value.is_a?(::Array) && value.all? { |i| i.is_a? ::Hash } end end # Specialization of the {Json} attribute that is guaranteed # to return an array of objects. Accepts both JSON-encoded # objects and arrays of objects, but wraps single objects # in an Array. class JsonArray < Json # See {Json#coerce}. Wraps single objects in an array. # # @param input [String] JSON-encoded parameter value # @return [Array] def coerce(input) json = super Array.wrap(json) unless json.nil? end # See {Json#coerced_collection?} def value_coerced?(value) coerced_collection? value end end end end end grape-1.0.2/lib/grape/validations/types/variant_collection_coercer.rb0000644000004100000410000000437413231337007026102 0ustar www-datawww-datamodule Grape module Validations module Types # This class wraps {MultipleTypeCoercer}, for use with collections # that allow members of more than one type. class VariantCollectionCoercer < Virtus::Attribute # Construct a new coercer that will attempt to coerce # a list of values such that all members are of one of # the given types. The container may also optionally be # coerced to a +Set+. An arbitrary coercion +method+ may # be supplied, which will be passed the entire collection # as a parameter and should return a new collection, or # may return the same one if no coercion was required. # # @param types [Array,Set] list of allowed types, # also specifying the container type # @param method [#call,#parse] method by which values should be coerced def initialize(types, method = nil) @types = types @method = method.respond_to?(:parse) ? method.method(:parse) : method # If we have a coercion method, pass it in here to save # building another one, even though we call it directly. @member_coercer = MultipleTypeCoercer.new types, method end # Coerce the given value. # # @param value [Array] collection of values to be coerced # @return [Array,Set,InvalidValue] # the coerced result, or an instance # of {InvalidValue} if the value could not be coerced. def coerce(value) return InvalidValue.new unless value.is_a? Array value = if @method @method.call(value) else value.map { |v| @member_coercer.call(v) } end return Set.new value if @types.is_a? Set value end # Assert that the value has been coerced successfully. # # @param value [Object] a coerced result returned from {#coerce} # @return [true,false] whether or not the coerced value # satisfies type requirements. def value_coerced?(value) value.is_a?(@types.class) && value.all? { |v| @member_coercer.success?(@types, v) } end end end end end grape-1.0.2/lib/grape/validations/types/custom_type_coercer.rb0000644000004100000410000001655513231337007024602 0ustar www-datawww-datamodule Grape module Validations module Types # Instances of this class may be passed to # +Virtus::Attribute.build+ as the +:coercer+ # option for custom types that do not otherwise # satisfy the requirements for +Virtus::Attribute::coerce+ # and +Virtus::Attribute::value_coerced?+ to work # as expected. # # Subclasses of +Virtus::Attribute+ or +Axiom::Types::Type+ # (or for which an axiom type can be inferred, i.e. the # primitives, +Date+, +Time+, etc.) do not need any such # coercer to be passed with them. # # Coercion # -------- # # This class will detect type classes that implement # a class-level +parse+ method. The method should accept one # +String+ argument and should return the value coerced to # the appropriate type. The method may raise an exception if # there are any problems parsing the string. # # Alternately an optional +method+ may be supplied (see the # +coerce_with+ option of {Grape::Dsl::Parameters#requires}). # This may be any class or object implementing +parse+ or +call+, # with the same contract as described above. # # Type Checking # ------------- # # Calls to +value_coerced?+ will consult this class to check # that the coerced value produced above is in fact of the # expected type. By default this class performs a basic check # against the type supplied, but this behaviour will be # overridden if the class implements a class-level # +coerced?+ or +parsed?+ method. This method # will receive a single parameter that is the coerced value # and should return +true+ iff the value meets type expectations. # Arbitrary assertions may be made here but the grape validation # system should be preferred. # # Alternately a proc or other object responding to +call+ may be # supplied in place of a type. This should implement the same # contract as +coerced?+, and must be supplied with a coercion # +method+. class CustomTypeCoercer # Uses +Virtus::Attribute.build+ to build a new # attribute that makes use of this class for # coercion and type validation logic. # # @return [Virtus::Attribute] def self.build(type, method = nil) Virtus::Attribute.build(type, coercer: new(type, method)) end # A new coercer for the given type specification # and coercion method. # # @param type [Class,#coerced?,#parsed?,#call?] # specifier for the target type. See class docs. # @param method [#parse,#call] # optional coercion method. See class docs. def initialize(type, method = nil) coercion_method = infer_coercion_method type, method @method = enforce_symbolized_keys type, coercion_method @type_check = infer_type_check(type) end # This method is called from somewhere within # +Virtus::Attribute::coerce+ in order to coerce # the given value. # # @param value [String] value to be coerced, in grape # this should always be a string. # @return [Object] the coerced result def call(value) @method.call value end # This method is called from somewhere within # +Virtus::Attribute::value_coerced?+ in order to # assert that the value has been coerced successfully. # # @param _primitive [Axiom::Types::Type] primitive type # for the coercion as detected by axiom-types' inference # system. For custom types this is typically not much use # (i.e. it is +Axiom::Types::Object+) unless special # inference rules have been declared for the type. # @param value [Object] a coerced result returned from {#call} # @return [true,false] whether or not the coerced value # satisfies type requirements. def success?(_primitive, value) @type_check.call value end private # Determine the coercion method we're expected to use # based on the parameters given. # # @param type see #new # @param method see #new # @return [#call] coercion method def infer_coercion_method(type, method) if method if method.respond_to? :parse method.method :parse else method end else # Try to use parse() declared on the target type. # This may raise an exception, but we are out of ideas anyway. type.method :parse end end # Determine how the type validity of a coerced # value should be decided. # # @param type see #new # @return [#call] a procedure which accepts a single parameter # and returns +true+ if the passed object is of the correct type. def infer_type_check(type) # First check for special class methods if type.respond_to? :coerced? type.method :coerced? elsif type.respond_to? :parsed? type.method :parsed? elsif type.respond_to? :call # Arbitrary proc passed for type validation. # Note that this will fail unless a method is also # passed, or if the type also implements a parse() method. type elsif type.is_a?(Enumerable) ->(value) { value.respond_to?(:all?) && value.all? { |item| item.is_a? type[0] } } else # By default, do a simple type check ->(value) { value.is_a? type } end end # Enforce symbolized keys for complex types # by wrapping the coercion method such that # any Hash objects in the immediate heirarchy # have their keys recursively symbolized. # This helps common libs such as JSON to work easily. # # @param type see #new # @param method see #infer_coercion_method # @return [#call] +method+ wrapped in an additional # key-conversion step, or just returns +method+ # itself if no conversion is deemed to be # necessary. def enforce_symbolized_keys(type, method) # Collections have all values processed individually if type == Array || type == Set lambda do |val| method.call(val).tap do |new_value| new_value.map do |item| item.is_a?(Hash) ? symbolize_keys(item) : item end end end # Hash objects are processed directly elsif type == Hash lambda do |val| symbolize_keys method.call(val) end # Simple types are not processed. # This includes Array types. else method end end def symbolize_keys!(hash) hash.each_key do |key| hash[key.to_sym] = hash.delete(key) if key.respond_to?(:to_sym) end hash end def symbolize_keys(hash) hash.inject({}) do |new_hash, (key, value)| new_key = key.respond_to?(:to_sym) ? key.to_sym : key new_hash.merge!(new_key => value) end end end end end end grape-1.0.2/lib/grape/validations/types/virtus_collection_patch.rb0000644000004100000410000000106313231337007025437 0ustar www-datawww-datarequire 'virtus/attribute/collection' # See https://github.com/solnic/virtus/pull/343 # This monkey-patch fixes type validation for collections, # ensuring that type assertions are applied to collection # members. # # This patch duplicates the code in the above pull request. # Once the request, or equivalent functionality, has been # published into the +virtus+ gem this file should be deleted. Virtus::Attribute::Collection.class_eval do # @api public def value_coerced?(value) super && value.all? { |item| member_type.value_coerced? item } end end grape-1.0.2/lib/grape/validations/types/file.rb0000644000004100000410000000153013231337007021427 0ustar www-datawww-datamodule Grape module Validations module Types # +Virtus::Attribute+ implementation for parameters # that are multipart file objects. Actual handling # of these objects is provided by +Rack::Request+; # this class is here only to assert that rack's # handling has succeeded, and to prevent virtus # from interfering. class File < Virtus::Attribute def coerce(input) # Processing of multipart file objects # is already taken care of by Rack::Request. # Nothing to do here. input end def value_coerced?(value) # Rack::Request creates a Hash with filename, # content type and an IO object. Do a bit of basic # duck-typing. value.is_a?(::Hash) && value.key?(:tempfile) end end end end end grape-1.0.2/lib/grape/validations/types/custom_type_collection_coercer.rb0000644000004100000410000000573213231337007027010 0ustar www-datawww-datamodule Grape module Validations module Types # Instances of this class may be passed to # +Virtus::Attribute.build+ as the +:coercer+ # option, to handle collections of types that # provide their own parsing (and optionally, # type-checking) functionality. # # See {CustomTypeCoercer} for details on types # that will be supported by this by this coercer. # This coercer works in the same way as +CustomTypeCoercer+ # except that it expects to receive an array of strings to # coerce and will return an array (or optionally, a set) # of coerced values. # # +CustomTypeCoercer+ is already capable of providing type # checking for arrays where an independent coercion method # is supplied. As such, +CustomTypeCollectionCoercer+ does # not allow for such a method to be supplied independently # of the type. class CustomTypeCollectionCoercer < CustomTypeCoercer # A new coercer for collections of the given type. # # @param type [Class,#parse] # type to which items in the array should be coerced. # Must implement a +parse+ method which accepts a string, # and for the purposes of type-checking it may either be # a class, or it may implement a +coerced?+, +parsed?+ or # +call+ method (in that order of precedence) which # accepts a single argument and returns true if the given # array item has been coerced correctly. # @param set [Boolean] # when true, a +Set+ will be returned by {#call} instead # of an +Array+ and duplicate items will be discarded. def initialize(type, set = false) super(type) @set = set end # This method is called from somewhere within # +Virtus::Attribute::coerce+ in order to coerce # the given value. # # @param value [Array] an array of values to be coerced # @return [Array,Set] the coerced result. May be an +Array+ or a # +Set+ depending on the setting given to the constructor def call(value) coerced = value.map { |item| super(item) } @set ? Set.new(coerced) : coerced end # This method is called from somewhere within # +Virtus::Attribute::value_coerced?+ in order to assert # that the all of the values in the array have been coerced # successfully. # # @param primitive [Axiom::Types::Type] primitive type for # the coercion as deteced by axiom-types' inference system. # @param value [Enumerable] a coerced result returned from {#call} # @return [true,false] whether or not all of the coerced values in # the collection satisfy type requirements. def success?(primitive, value) value.is_a?(@set ? Set : Array) && value.all? { |item| super(primitive, item) } end end end end end grape-1.0.2/lib/grape/validations/types/build_coercer.rb0000644000004100000410000000654113231337007023320 0ustar www-datawww-datamodule Grape module Validations module Types # Work out the +Virtus::Attribute+ object to # use for coercing strings to the given +type+. # Coercion +method+ will be inferred if none is # supplied. # # If a +Virtus::Attribute+ object already built # with +Virtus::Attribute.build+ is supplied as # the +type+ it will be returned and +method+ # will be ignored. # # See {CustomTypeCoercer} for further details # about coercion and type-checking inference. # # @param type [Class] the type to which input strings # should be coerced # @param method [Class,#call] the coercion method to use # @return [Virtus::Attribute] object to be used # for coercion and type validation def self.build_coercer(type, method = nil) cache_instance(type, method) do create_coercer_instance(type, method) end end def self.create_coercer_instance(type, method = nil) # Accept pre-rolled virtus attributes without interference return type if type.is_a? Virtus::Attribute converter_options = { nullify_blank: true } conversion_type = if method == JSON Object # because we want just parsed JSON content: # if type is Array and data is `"{}"` # result will be [] because Virtus converts hashes # to arrays else type end # Use a special coercer for multiply-typed parameters. if Types.multiple?(type) converter_options[:coercer] = Types::MultipleTypeCoercer.new(type, method) conversion_type = Object # Use a special coercer for custom types and coercion methods. elsif method || Types.custom?(type) converter_options[:coercer] = Types::CustomTypeCoercer.new(type, method) # Special coercer for collections of types that implement a parse method. # CustomTypeCoercer (above) already handles such types when an explicit coercion # method is supplied. elsif Types.collection_of_custom?(type) converter_options[:coercer] = Types::CustomTypeCollectionCoercer.new( type.first, type.is_a?(Set) ) # Grape swaps in its own Virtus::Attribute implementations # for certain special types that merit first-class support # (but not if a custom coercion method has been supplied). elsif Types.special?(type) conversion_type = Types::SPECIAL[type] end # Virtus will infer coercion and validation rules # for many common ruby types. Virtus::Attribute.build(conversion_type, converter_options) end def self.cache_instance(type, method, &_block) key = cache_key(type, method) return @__cache[key] if @__cache.key?(key) instance = yield @__cache_write_lock.synchronize do @__cache[key] = instance end instance end def self.cache_key(type, method) [type, method].compact.map(&:to_s).join('_') end instance_variable_set(:@__cache, {}) instance_variable_set(:@__cache_write_lock, Mutex.new) end end end grape-1.0.2/lib/grape/validations/validators/0000755000004100000410000000000013231337007021170 5ustar www-datawww-datagrape-1.0.2/lib/grape/validations/validators/default.rb0000644000004100000410000000244313231337007023144 0ustar www-datawww-datamodule Grape module Validations class DefaultValidator < Base def initialize(attrs, options, required, scope, opts = {}) @default = options super end def validate_param!(attr_name, params) return if params.key? attr_name params[attr_name] = if @default.is_a? Proc @default.call elsif @default.frozen? || !duplicatable?(@default) @default else duplicate(@default) end end def validate!(params) attrs = AttributesIterator.new(self, @scope, params) attrs.each do |resource_params, attr_name| if resource_params.is_a?(Hash) && resource_params[attr_name].nil? validate_param!(attr_name, resource_params) end end end private # return true if we might be able to dup this object def duplicatable?(obj) !obj.nil? && obj != true && obj != false && !obj.is_a?(Symbol) && !obj.is_a?(Numeric) end # make a best effort to dup the object def duplicate(obj) obj.dup rescue TypeError obj end end end end grape-1.0.2/lib/grape/validations/validators/values.rb0000644000004100000410000000500513231337007023014 0ustar www-datawww-datamodule Grape module Validations class ValuesValidator < Base def initialize(attrs, options, required, scope, opts = {}) if options.is_a?(Hash) @excepts = options[:except] @values = options[:value] @proc = options[:proc] warn '[DEPRECATION] The values validator except option is deprecated. ' \ 'Use the except validator instead.' if @excepts raise ArgumentError, 'proc must be a Proc' if @proc && !@proc.is_a?(Proc) warn '[DEPRECATION] The values validator proc option is deprecated. ' \ 'The lambda expression can now be assigned directly to values.' if @proc else @excepts = nil @values = nil @proc = nil @values = options end super end def validate_param!(attr_name, params) return unless params.is_a?(Hash) return unless params[attr_name] || required_for_root_scope? param_array = params[attr_name].nil? ? [nil] : Array.wrap(params[attr_name]) raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: except_message \ unless check_excepts(param_array) raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:values) \ unless check_values(param_array, attr_name) raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:values) \ if @proc && !param_array.all? { |param| @proc.call(param) } end private def check_values(param_array, attr_name) values = @values.is_a?(Proc) && @values.arity.zero? ? @values.call : @values return true if values.nil? begin return param_array.all? { |param| values.call(param) } if values.is_a? Proc rescue StandardError => e warn "Error '#{e}' raised while validating attribute '#{attr_name}'" return false end param_array.all? { |param| values.include?(param) } end def check_excepts(param_array) excepts = @excepts.is_a?(Proc) ? @excepts.call : @excepts return true if excepts.nil? param_array.none? { |param| excepts.include?(param) } end def except_message options = instance_variable_get(:@option) options_key?(:except_message) ? options[:except_message] : message(:except_values) end def required_for_root_scope? @required && @scope.root? end end end end grape-1.0.2/lib/grape/validations/validators/exactly_one_of.rb0000644000004100000410000000154513231337007024520 0ustar www-datawww-datamodule Grape module Validations require 'grape/validations/validators/mutual_exclusion' class ExactlyOneOfValidator < MutualExclusionValidator def validate!(params) super if scope_requires_params && none_of_restricted_params_is_present raise Grape::Exceptions::Validation, params: all_keys, message: message(:exactly_one) end params end def message(default_key = nil) options = instance_variable_get(:@option) if options_key?(:message) (options_key?(default_key, options[:message]) ? options[:message][default_key] : options[:message]) else default_key end end private def none_of_restricted_params_is_present scoped_params.any? { |resource_params| keys_in_common(resource_params).empty? } end end end end grape-1.0.2/lib/grape/validations/validators/all_or_none.rb0000644000004100000410000000113113231337007024000 0ustar www-datawww-datamodule Grape module Validations require 'grape/validations/validators/multiple_params_base' class AllOrNoneOfValidator < MultipleParamsBase def validate!(params) super if scope_requires_params && only_subset_present raise Grape::Exceptions::Validation, params: all_keys, message: message(:all_or_none) end params end private def only_subset_present scoped_params.any? { |resource_params| !keys_in_common(resource_params).empty? && keys_in_common(resource_params).length < attrs.length } end end end end grape-1.0.2/lib/grape/validations/validators/coerce.rb0000644000004100000410000000434613231337007022764 0ustar www-datawww-datamodule Grape class API Boolean = Virtus::Attribute::Boolean end module Validations class CoerceValidator < Base def initialize(*_args) super @converter = Types.build_coercer(type, @option[:method]) end def validate(request) super end def validate_param!(attr_name, params) raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:coerce) unless params.is_a? Hash return unless requires_coercion?(params[attr_name]) new_value = coerce_value(params[attr_name]) raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:coerce) unless valid_type?(new_value) params[attr_name] = new_value end private # @!attribute [r] converter # Object that will be used for parameter coercion and type checking. # # See {Types.build_coercer} # # @return [Virtus::Attribute] attr_reader :converter def valid_type?(val) # Special value to denote coercion failure return false if val.instance_of?(Types::InvalidValue) # Allow nil, to ignore when a parameter is absent return true if val.nil? converter.value_coerced? val end def coerce_value(val) # Don't coerce things other than nil to Arrays or Hashes unless (@option[:method] && !val.nil?) || type.is_a?(Virtus::Attribute) return val || [] if type == Array return val || Set.new if type == Set return val || {} if type == Hash end converter.coerce(val) # not the prettiest but some invalid coercion can currently trigger # errors in Virtus (see coerce_spec.rb:75) rescue Types::InvalidValue.new end # Type to which the parameter will be coerced. # # @return [Class] def type @option[:type].is_a?(Hash) ? @option[:type][:value] : @option[:type] end def requires_coercion?(value) # JSON types do not require coercion if value is valid !valid_type?(value) || converter.coercer.respond_to?(:method) && !converter.is_a?(Grape::Validations::Types::Json) end end end end grape-1.0.2/lib/grape/validations/validators/multiple_params_base.rb0000644000004100000410000000110013231337007025675 0ustar www-datawww-datamodule Grape module Validations class MultipleParamsBase < Base attr_reader :scoped_params def validate!(params) @scoped_params = [@scope.params(params)].flatten params end private def scope_requires_params @scope.required? || scoped_params.any?(&:any?) end def keys_in_common(resource_params) return [] unless resource_params.is_a?(Hash) (all_keys & resource_params.stringify_keys.keys).map(&:to_s) end def all_keys attrs.map(&:to_s) end end end end grape-1.0.2/lib/grape/validations/validators/presence.rb0000644000004100000410000000050413231337007023320 0ustar www-datawww-datamodule Grape module Validations class PresenceValidator < Base def validate_param!(attr_name, params) return if params.respond_to?(:key?) && params.key?(attr_name) raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:presence) end end end end grape-1.0.2/lib/grape/validations/validators/as.rb0000644000004100000410000000050713231337007022122 0ustar www-datawww-datamodule Grape module Validations class AsValidator < Base def initialize(attrs, options, required, scope, opts = {}) @alias = options super end def validate_param!(attr_name, params) params[@alias] = params[attr_name] params.delete(attr_name) end end end end grape-1.0.2/lib/grape/validations/validators/base.rb0000644000004100000410000000616113231337007022433 0ustar www-datawww-datamodule Grape module Validations class Base attr_reader :attrs # Creates a new Validator from options specified # by a +requires+ or +optional+ directive during # parameter definition. # @param attrs [Array] names of attributes to which the Validator applies # @param options [Object] implementation-dependent Validator options # @param required [Boolean] attribute(s) are required or optional # @param scope [ParamsScope] parent scope for this Validator # @param opts [Hash] additional validation options def initialize(attrs, options, required, scope, opts = {}) @attrs = Array(attrs) @option = options @required = required @scope = scope @fail_fast = opts[:fail_fast] || false end # Validates a given request. # @note Override #validate! unless you need to access the entire request. # @param request [Grape::Request] the request currently being handled # @raise [Grape::Exceptions::Validation] if validation failed # @return [void] def validate(request) return unless @scope.should_validate?(request.params) validate!(request.params) end # Validates a given parameter hash. # @note Override #validate if you need to access the entire request. # @param params [Hash] parameters to validate # @raise [Grape::Exceptions::Validation] if validation failed # @return [void] def validate!(params) attributes = AttributesIterator.new(self, @scope, params) array_errors = [] attributes.each do |resource_params, attr_name| next if !@scope.required? && resource_params.empty? next unless @required || (resource_params.respond_to?(:key?) && resource_params.key?(attr_name)) next unless @scope.meets_dependency?(resource_params, params) begin validate_param!(attr_name, resource_params) rescue Grape::Exceptions::Validation => e # we collect errors inside array because # there may be more than one error per field array_errors << e end end raise Grape::Exceptions::ValidationArrayErrors, array_errors if array_errors.any? end def self.convert_to_short_name(klass) ret = klass.name.gsub(/::/, '/') .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') .gsub(/([a-z\d])([A-Z])/, '\1_\2') .tr('-', '_') .downcase File.basename(ret, '_validator') end def self.inherited(klass) return unless klass.name.present? Validations.register_validator(convert_to_short_name(klass), klass) end def message(default_key = nil) options = instance_variable_get(:@option) options_key?(:message) ? options[:message] : default_key end def options_key?(key, options = nil) options = instance_variable_get(:@option) if options.nil? options.respond_to?(:key?) && options.key?(key) && !options[key].nil? end def fail_fast? @fail_fast end end end end grape-1.0.2/lib/grape/validations/validators/at_least_one_of.rb0000644000004100000410000000107113231337007024635 0ustar www-datawww-datamodule Grape module Validations require 'grape/validations/validators/multiple_params_base' class AtLeastOneOfValidator < MultipleParamsBase def validate!(params) super if scope_requires_params && no_exclusive_params_are_present raise Grape::Exceptions::Validation, params: all_keys, message: message(:at_least_one) end params end private def no_exclusive_params_are_present scoped_params.any? { |resource_params| keys_in_common(resource_params).empty? } end end end end grape-1.0.2/lib/grape/validations/validators/except_values.rb0000644000004100000410000000133213231337007024363 0ustar www-datawww-datamodule Grape module Validations class ExceptValuesValidator < Base def initialize(attrs, options, required, scope, opts = {}) @except = options.is_a?(Hash) ? options[:value] : options super end def validate_param!(attr_name, params) return unless params.respond_to?(:key?) && params.key?(attr_name) excepts = @except.is_a?(Proc) ? @except.call : @except return if excepts.nil? param_array = params[attr_name].nil? ? [nil] : Array.wrap(params[attr_name]) raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:except_values) if param_array.any? { |param| excepts.include?(param) } end end end end grape-1.0.2/lib/grape/validations/validators/allow_blank.rb0000644000004100000410000000075213231337007024006 0ustar www-datawww-datamodule Grape module Validations class AllowBlankValidator < Base def validate_param!(attr_name, params) return if (options_key?(:value) ? @option[:value] : @option) || !params.is_a?(Hash) value = params[attr_name] value = value.strip if value.respond_to?(:strip) return if value == false || value.present? raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:blank) end end end end grape-1.0.2/lib/grape/validations/validators/mutual_exclusion.rb0000644000004100000410000000132313231337007025114 0ustar www-datawww-datamodule Grape module Validations require 'grape/validations/validators/multiple_params_base' class MutualExclusionValidator < MultipleParamsBase attr_reader :processing_keys_in_common def validate!(params) super if two_or_more_exclusive_params_are_present raise Grape::Exceptions::Validation, params: processing_keys_in_common, message: message(:mutual_exclusion) end params end private def two_or_more_exclusive_params_are_present scoped_params.any? do |resource_params| @processing_keys_in_common = keys_in_common(resource_params) @processing_keys_in_common.length > 1 end end end end end grape-1.0.2/lib/grape/validations/validators/regexp.rb0000644000004100000410000000072613231337007023014 0ustar www-datawww-datamodule Grape module Validations class RegexpValidator < Base def validate_param!(attr_name, params) return unless params.respond_to?(:key?) && params.key?(attr_name) return if Array.wrap(params[attr_name]).all? { |param| param.nil? || (param.to_s =~ (options_key?(:value) ? @option[:value] : @option)) } raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: message(:regexp) end end end end grape-1.0.2/lib/grape/validations/attributes_iterator.rb0000644000004100000410000000306313231337007023446 0ustar www-datawww-datamodule Grape module Validations class AttributesIterator include Enumerable attr_reader :scope def initialize(validator, scope, params) @scope = scope @attrs = validator.attrs @original_params = scope.params(params) @params = Array.wrap(@original_params) end def each(&block) do_each(@params, &block) # because we need recursion for nested arrays end private def do_each(params_to_process, parent_indicies = [], &block) params_to_process.each_with_index do |resource_params, index| # when we get arrays of arrays it means that target element located inside array # we need this because we want to know parent arrays indicies if resource_params.is_a?(Array) do_each(resource_params, [index] + parent_indicies, &block) next end if @scope.type == Array next unless @original_params.is_a?(Array) # do not validate content of array if it isn't array inside_array = true end if inside_array # fill current and parent scopes with correct array indicies parent_scope = @scope.parent parent_indicies.each do |parent_index| parent_scope.index = parent_index parent_scope = parent_scope.parent end @scope.index = index end @attrs.each do |attr_name| yield resource_params, attr_name, inside_array end end end end end end grape-1.0.2/lib/grape/router/0000755000004100000410000000000013231337007016023 5ustar www-datawww-datagrape-1.0.2/lib/grape/router/pattern.rb0000644000004100000410000000332213231337007020025 0ustar www-datawww-datarequire 'forwardable' require 'mustermann/grape' module Grape class Router class Pattern DEFAULT_PATTERN_OPTIONS = { uri_decode: true, type: :grape }.freeze DEFAULT_SUPPORTED_CAPTURE = %i[format version].freeze attr_reader :origin, :path, :capture, :pattern extend Forwardable def_delegators :pattern, :named_captures, :params def_delegators :@regexp, :=== alias match? === def initialize(pattern, **options) @origin = pattern @path = build_path(pattern, **options) @capture = extract_capture(options) @pattern = Mustermann.new(@path, pattern_options) @regexp = to_regexp end def to_regexp @to_regexp ||= @pattern.to_regexp end private def pattern_options options = DEFAULT_PATTERN_OPTIONS.dup options[:capture] = capture if capture.present? options end def build_path(pattern, anchor: false, suffix: nil, **_options) unless anchor || pattern.end_with?('*path') pattern << '/' unless pattern.end_with?('/') pattern << '*path' end pattern = pattern.split('/').tap do |parts| parts[parts.length - 1] = '?' + parts.last end.join('/') if pattern.end_with?('*path') pattern + suffix.to_s end def extract_capture(requirements: {}, **options) requirements = {}.merge(requirements) supported_capture.each_with_object(requirements) do |field, capture| option = Array(options[field]) capture[field] = option.map(&:to_s) if option.present? end end def supported_capture DEFAULT_SUPPORTED_CAPTURE end end end end grape-1.0.2/lib/grape/router/attribute_translator.rb0000644000004100000410000000125213231337007022624 0ustar www-datawww-datamodule Grape class Router # this could be an OpenStruct, but doesn't work in Ruby 2.3.0, see https://bugs.ruby-lang.org/issues/12251 class AttributeTranslator def initialize(attributes = {}) @attributes = attributes end def to_h @attributes end def method_missing(m, *args) if m[-1] == '=' @attributes[m[0..-1]] = *args elsif m[-1] != '=' @attributes[m] end end def respond_to_missing?(method_name, _include_private = false) if method_name[-1] == '=' true else @attributes.key?(method_name) end end end end end grape-1.0.2/lib/grape/router/route.rb0000644000004100000410000000560413231337007017513 0ustar www-datawww-datarequire 'grape/router/pattern' require 'grape/router/attribute_translator' require 'forwardable' require 'pathname' module Grape class Router class Route ROUTE_ATTRIBUTE_REGEXP = /route_([_a-zA-Z]\w*)/ SOURCE_LOCATION_REGEXP = /^(.*?):(\d+?)(?::in `.+?')?$/ FIXED_NAMED_CAPTURES = %w[format version].freeze attr_accessor :pattern, :translator, :app, :index, :regexp, :options alias attributes translator extend Forwardable def_delegators :pattern, :path, :origin def method_missing(method_id, *arguments) match = ROUTE_ATTRIBUTE_REGEXP.match(method_id.to_s) if match method_name = match.captures.last.to_sym warn_route_methods(method_name, caller(1).shift) @options[method_name] else super end end def respond_to_missing?(method_id, _) ROUTE_ATTRIBUTE_REGEXP.match(method_id.to_s) end %i[ prefix version settings format description http_codes headers entity details requirements request_method namespace ].each do |method_name| define_method method_name do attributes.public_send method_name end end def route_method warn_route_methods(:method, caller(1).shift, :request_method) request_method end def route_path warn_route_methods(:path, caller(1).shift) pattern.path end def initialize(method, pattern, **options) @suffix = options[:suffix] @options = options.merge(method: method.to_s.upcase) @pattern = Pattern.new(pattern, **options) @translator = AttributeTranslator.new(**options, request_method: method.to_s.upcase) end def exec(env) @app.call(env) end def apply(app) @app = app self end def match?(input) translator.respond_to?(:forward_match) && translator.forward_match ? input.start_with?(pattern.origin) : pattern.match?(input) end def params(input = nil) if input.nil? pattern.named_captures.keys.each_with_object(translator.params) do |(key), defaults| defaults[key] ||= '' unless FIXED_NAMED_CAPTURES.include?(key) || defaults.key?(key) end else parsed = pattern.params(input) parsed ? parsed.delete_if { |_, value| value.nil? }.symbolize_keys : {} end end private def warn_route_methods(name, location, expected = nil) path, line = *location.scan(SOURCE_LOCATION_REGEXP).first path = File.realpath(path) if Pathname.new(path).relative? expected ||= name warn <<-EOS #{path}:#{line}: The route_xxx methods such as route_#{name} have been deprecated, please use #{expected}. EOS end end end end grape-1.0.2/lib/grape/dsl/0000755000004100000410000000000013231337007015265 5ustar www-datawww-datagrape-1.0.2/lib/grape/dsl/headers.rb0000644000004100000410000000054213231337007017226 0ustar www-datawww-datamodule Grape module DSL module Headers # Set an individual header or retrieve # all headers that have been set. def header(key = nil, val = nil) if key val ? header[key.to_s] = val : header.delete(key.to_s) else @header ||= {} end end alias headers header end end end grape-1.0.2/lib/grape/dsl/inside_route.rb0000644000004100000410000003415513231337007020313 0ustar www-datawww-datarequire 'active_support/concern' require 'grape/dsl/headers' module Grape module DSL module InsideRoute extend ActiveSupport::Concern include Grape::DSL::Settings include Grape::DSL::Headers # Denotes a situation where a DSL method has been invoked in a # filter which it should not yet be available in class MethodNotYetAvailable < StandardError; end # @param type [Symbol] The type of filter for which evaluation has been # completed # @return [Module] A module containing method overrides suitable for the # position in the filter evaluation sequence denoted by +type+. This # defaults to an empty module if no overrides are defined for the given # filter +type+. def self.post_filter_methods(type) @post_filter_modules ||= { before: PostBeforeFilter } @post_filter_modules[type] end # Methods which should not be available in filters until the before filter # has completed module PostBeforeFilter def declared(passed_params, options = {}, declared_params = nil) options = options.reverse_merge(include_missing: true, include_parent_namespaces: true) declared_params ||= optioned_declared_params(options) if passed_params.is_a?(Array) declared_array(passed_params, options, declared_params) else declared_hash(passed_params, options, declared_params) end end private def declared_array(passed_params, options, declared_params) passed_params.map do |passed_param| declared(passed_param || {}, options, declared_params) end end def declared_hash(passed_params, options, declared_params) declared_params.each_with_object(passed_params.class.new) do |declared_param, memo| if declared_param.is_a?(Hash) declared_param.each_pair do |declared_parent_param, declared_children_params| next unless options[:include_missing] || passed_params.key?(declared_parent_param) passed_children_params = passed_params[declared_parent_param] || passed_params.class.new memo_key = optioned_param_key(declared_parent_param, options) memo[memo_key] = handle_passed_param(declared_parent_param, passed_children_params) do declared(passed_children_params, options, declared_children_params) end end else # If it is not a Hash then it does not have children. # Find its value or set it to nil. has_alias = route_setting(:aliased_params) && route_setting(:aliased_params).find { |current| current[declared_param] } param_alias = has_alias[declared_param] if has_alias next unless options[:include_missing] || passed_params.key?(declared_param) || param_alias if param_alias memo[optioned_param_key(param_alias, options)] = passed_params[param_alias] else memo[optioned_param_key(declared_param, options)] = passed_params[declared_param] end end end end def handle_passed_param(declared_param, passed_children_params, &_block) should_be_empty_array?(declared_param, passed_children_params) ? [] : yield end def should_be_empty_array?(declared_param, passed_children_params) declared_param_is_array?(declared_param) && passed_children_params.empty? end def declared_param_is_array?(declared_param) route_options_params[declared_param.to_s] && route_options_params[declared_param.to_s][:type] == 'Array' end def route_options_params options[:route_options][:params] || {} end def optioned_param_key(declared_param, options) options[:stringify] ? declared_param.to_s : declared_param.to_sym end def optioned_declared_params(options) declared_params = if options[:include_parent_namespaces] # Declared params including parent namespaces route_setting(:saved_declared_params).flatten | Array(route_setting(:declared_params)) else # Declared params at current namespace route_setting(:saved_declared_params).last & Array(route_setting(:declared_params)) end raise ArgumentError, 'Tried to filter for declared parameters but none exist.' unless declared_params declared_params end end # A filtering method that will return a hash # consisting only of keys that have been declared by a # `params` statement against the current/target endpoint or parent # namespaces. # # @see +PostBeforeFilter#declared+ # # @param params [Hash] The initial hash to filter. Usually this will just be `params` # @param options [Hash] Can pass `:include_missing`, `:stringify` and `:include_parent_namespaces` # options. `:include_parent_namespaces` defaults to true, hence must be set to false if # you want only to return params declared against the current/target endpoint. def declared(*) raise MethodNotYetAvailable, '#declared is not available prior to parameter validation.' end # The API version as specified in the URL. def version env[Grape::Env::API_VERSION] end # End the request and display an error to the # end user with the specified message. # # @param message [String] The message to display. # @param status [Integer] the HTTP Status Code. Defaults to default_error_status, 500 if not set. def error!(message, status = nil, headers = nil) self.status(status || namespace_inheritable(:default_error_status)) throw :error, message: message, status: self.status, headers: headers end # Redirect to a new url. # # @param url [String] The url to be redirect. # @param options [Hash] The options used when redirect. # :permanent, default false. # :body, default a short message including the URL. def redirect(url, permanent: false, body: nil, **_options) body_message = body if permanent status 301 body_message ||= "This resource has been moved permanently to #{url}." elsif env[Grape::Http::Headers::HTTP_VERSION] == 'HTTP/1.1' && request.request_method.to_s.upcase != Grape::Http::Headers::GET status 303 body_message ||= "An alternate resource is located at #{url}." else status 302 body_message ||= "This resource has been moved temporarily to #{url}." end header 'Location', url content_type 'text/plain' body body_message end # Set or retrieve the HTTP status code. # # @param status [Integer] The HTTP Status Code to return for this request. def status(status = nil) case status when Symbol raise ArgumentError, "Status code :#{status} is invalid." unless Rack::Utils::SYMBOL_TO_STATUS_CODE.keys.include?(status) @status = Rack::Utils.status_code(status) when Integer @status = status when nil return @status if @status case request.request_method.to_s.upcase when Grape::Http::Headers::POST 201 when Grape::Http::Headers::DELETE if @body.present? 200 else 204 end else 200 end else raise ArgumentError, 'Status code must be Integer or Symbol.' end end # Set response content-type def content_type(val = nil) if val header(Grape::Http::Headers::CONTENT_TYPE, val) else header[Grape::Http::Headers::CONTENT_TYPE] end end # Set or get a cookie # # @example # cookies[:mycookie] = 'mycookie val' # cookies['mycookie-string'] = 'mycookie string val' # cookies[:more] = { value: '123', expires: Time.at(0) } # cookies.delete :more # def cookies @cookies ||= Cookies.new end # Allows you to define the response body as something other than the # return value. # # @example # get '/body' do # body "Body" # "Not the Body" # end # # GET /body # => "Body" def body(value = nil) if value @body = value elsif value == false @body = '' status 204 else @body end end # Allows you to explicitly return no content. # # @example # delete :id do # return_no_content # "not returned" # end # # DELETE /12 # => 204 No Content, "" def return_no_content status 204 body false end # Allows you to define the response as a file-like object. # # @example # get '/file' do # file FileStreamer.new(...) # end # # GET /file # => "contents of file" def file(value = nil) if value.is_a?(String) file_body = Grape::ServeFile::FileBody.new(value) @file = Grape::ServeFile::FileResponse.new(file_body) elsif !value.is_a?(NilClass) warn '[DEPRECATION] Argument as FileStreamer-like object is deprecated. Use path to file instead.' @file = Grape::ServeFile::FileResponse.new(value) else @file end end # Allows you to define the response as a streamable object. # # If Content-Length and Transfer-Encoding are blank (among other conditions), # Rack assumes this response can be streamed in chunks. # # @example # get '/stream' do # stream FileStreamer.new(...) # end # # GET /stream # => "chunked contents of file" # # See: # * https://github.com/rack/rack/blob/99293fa13d86cd48021630fcc4bd5acc9de5bdc3/lib/rack/chunked.rb # * https://github.com/rack/rack/blob/99293fa13d86cd48021630fcc4bd5acc9de5bdc3/lib/rack/etag.rb def stream(value = nil) header 'Content-Length', nil header 'Transfer-Encoding', nil header 'Cache-Control', 'no-cache' # Skips ETag generation (reading the response up front) file(value) end # Allows you to make use of Grape Entities by setting # the response body to the serializable hash of the # entity provided in the `:with` option. This has the # added benefit of automatically passing along environment # and version information to the serialization, making it # very easy to do conditional exposures. See Entity docs # for more info. # # @example # # get '/users/:id' do # present User.find(params[:id]), # with: API::Entities::User, # admin: current_user.admin? # end def present(*args) options = args.count > 1 ? args.extract_options! : {} key, object = if args.count == 2 && args.first.is_a?(Symbol) args else [nil, args.first] end entity_class = entity_class_for_obj(object, options) root = options.delete(:root) representation = if entity_class entity_representation_for(entity_class, object, options) else object end representation = { root => representation } if root if key representation = (@body || {}).merge(key => representation) elsif entity_class.present? && @body raise ArgumentError, "Representation of type #{representation.class} cannot be merged." unless representation.respond_to?(:merge) representation = @body.merge(representation) end body representation end # Returns route information for the current request. # # @example # # desc "Returns the route description." # get '/' do # route.description # end def route env[Grape::Env::GRAPE_ROUTING_ARGS][:route_info] end # Attempt to locate the Entity class for a given object, if not given # explicitly. This is done by looking for the presence of Klass::Entity, # where Klass is the class of the `object` parameter, or one of its # ancestors. # @param object [Object] the object to locate the Entity class for # @param options [Hash] # @option options :with [Class] the explicit entity class to use # @return [Class] the located Entity class, or nil if none is found def entity_class_for_obj(object, options) entity_class = options.delete(:with) if entity_class.nil? # entity class not explicitely defined, auto-detect from relation#klass or first object in the collection object_class = if object.respond_to?(:klass) object.klass else object.respond_to?(:first) ? object.first.class : object.class end object_class.ancestors.each do |potential| entity_class ||= (namespace_stackable_with_hash(:representations) || {})[potential] end entity_class ||= object_class.const_get(:Entity) if object_class.const_defined?(:Entity) && object_class.const_get(:Entity).respond_to?(:represent) end entity_class end # @return the representation of the given object as done through # the given entity_class. def entity_representation_for(entity_class, object, options) embeds = { env: env } embeds[:version] = env[Grape::Env::API_VERSION] if env[Grape::Env::API_VERSION] entity_class.represent(object, embeds.merge(options)) end end end end grape-1.0.2/lib/grape/dsl/request_response.rb0000644000004100000410000001520713231337007021225 0ustar www-datawww-datarequire 'active_support/concern' module Grape module DSL module RequestResponse extend ActiveSupport::Concern include Grape::DSL::Configuration module ClassMethods # Specify the default format for the API's serializers. # May be `:json` or `:txt` (default). def default_format(new_format = nil) namespace_inheritable(:default_format, new_format.nil? ? nil : new_format.to_sym) end # Specify the format for the API's serializers. # May be `:json`, `:xml`, `:txt`, etc. def format(new_format = nil) if new_format namespace_inheritable(:format, new_format.to_sym) # define the default error formatters namespace_inheritable(:default_error_formatter, Grape::ErrorFormatter.formatter_for(new_format, {})) # define a single mime type mime_type = content_types[new_format.to_sym] raise Grape::Exceptions::MissingMimeType.new(new_format) unless mime_type namespace_stackable(:content_types, new_format.to_sym => mime_type) else namespace_inheritable(:format) end end # Specify a custom formatter for a content-type. def formatter(content_type, new_formatter) namespace_stackable(:formatters, content_type.to_sym => new_formatter) end # Specify a custom parser for a content-type. def parser(content_type, new_parser) namespace_stackable(:parsers, content_type.to_sym => new_parser) end # Specify a default error formatter. def default_error_formatter(new_formatter_name = nil) if new_formatter_name new_formatter = Grape::ErrorFormatter.formatter_for(new_formatter_name, {}) namespace_inheritable(:default_error_formatter, new_formatter) else namespace_inheritable(:default_error_formatter) end end def error_formatter(format, options) formatter = if options.is_a?(Hash) && options.key?(:with) options[:with] else options end namespace_stackable(:error_formatters, format.to_sym => formatter) end # Specify additional content-types, e.g.: # content_type :xls, 'application/vnd.ms-excel' def content_type(key, val) namespace_stackable(:content_types, key.to_sym => val) end # All available content types. def content_types c_types = namespace_stackable_with_hash(:content_types) Grape::ContentTypes.content_types_for c_types end # Specify the default status code for errors. def default_error_status(new_status = nil) namespace_inheritable(:default_error_status, new_status) end # Allows you to rescue certain exceptions that occur to return # a grape error rather than raising all the way to the # server level. # # @example Rescue from custom exceptions # class ExampleAPI < Grape::API # class CustomError < StandardError; end # # rescue_from CustomError # end # # @overload rescue_from(*exception_classes, **options) # @param [Array] exception_classes A list of classes that you want to rescue, or # the symbol :all to rescue from all exceptions. # @param [Block] block Execution block to handle the given exception. # @param [Hash] options Options for the rescue usage. # @option options [Boolean] :backtrace Include a backtrace in the rescue response. # @option options [Boolean] :rescue_subclasses Also rescue subclasses of exception classes # @param [Proc] handler Execution proc to handle the given exception as an # alternative to passing a block. def rescue_from(*args, &block) if args.last.is_a?(Proc) handler = args.pop elsif block_given? handler = block end options = args.extract_options! if block_given? && options.key?(:with) raise ArgumentError, 'both :with option and block cannot be passed' end handler ||= extract_with(options) if args.include?(:all) namespace_inheritable(:rescue_all, true) namespace_inheritable :all_rescue_handler, handler elsif args.include?(:grape_exceptions) namespace_inheritable(:rescue_all, true) namespace_inheritable(:rescue_grape_exceptions, true) else handler_type = case options[:rescue_subclasses] when nil, true :rescue_handlers else :base_only_rescue_handlers end namespace_reverse_stackable handler_type, Hash[args.map { |arg| [arg, handler] }] end namespace_stackable(:rescue_options, options) end # Allows you to specify a default representation entity for a # class. This allows you to map your models to their respective # entities once and then simply call `present` with the model. # # @example # class ExampleAPI < Grape::API # represent User, with: Entity::User # # get '/me' do # present current_user # with: Entity::User is assumed # end # end # # Note that Grape will automatically go up the class ancestry to # try to find a representing entity, so if you, for example, define # an entity to represent `Object` then all presented objects will # bubble up and utilize the entity provided on that `represent` call. # # @param model_class [Class] The model class that will be represented. # @option options [Class] :with The entity class that will represent the model. def represent(model_class, options) raise Grape::Exceptions::InvalidWithOptionForRepresent.new unless options[:with] && options[:with].is_a?(Class) namespace_stackable(:representations, model_class => options[:with]) end private def extract_with(options) return unless options.key?(:with) with_option = options.delete(:with) return with_option if with_option.instance_of?(Proc) return with_option.to_sym if with_option.instance_of?(Symbol) || with_option.instance_of?(String) raise ArgumentError, "with: #{with_option.class}, expected Symbol, String or Proc" end end end end end grape-1.0.2/lib/grape/dsl/configuration.rb0000644000004100000410000000043113231337007020457 0ustar www-datawww-datarequire 'active_support/concern' module Grape module DSL module Configuration extend ActiveSupport::Concern module ClassMethods include Grape::DSL::Settings include Grape::DSL::Logger include Grape::DSL::Desc end end end end grape-1.0.2/lib/grape/dsl/logger.rb0000644000004100000410000000101013231337007017061 0ustar www-datawww-datamodule Grape module DSL module Logger include Grape::DSL::Settings attr_writer :logger # Set or retrive the configured logger. If none was configured, this # method will create a new one, logging to stdout. # @param logger [Object] the new logger to use def logger(logger = nil) if logger global_setting(:logger, logger) else global_setting(:logger) || global_setting(:logger, ::Logger.new($stdout)) end end end end end grape-1.0.2/lib/grape/dsl/api.rb0000644000004100000410000000066313231337007016370 0ustar www-datawww-datarequire 'active_support/concern' module Grape module DSL module API extend ActiveSupport::Concern include Grape::Middleware::Auth::DSL include Grape::DSL::Validations include Grape::DSL::Callbacks include Grape::DSL::Configuration include Grape::DSL::Helpers include Grape::DSL::Middleware include Grape::DSL::RequestResponse include Grape::DSL::Routing end end end grape-1.0.2/lib/grape/dsl/helpers.rb0000644000004100000410000000552113231337007017257 0ustar www-datawww-datarequire 'active_support/concern' module Grape module DSL module Helpers extend ActiveSupport::Concern include Grape::DSL::Configuration module ClassMethods # Add helper methods that will be accessible from any # endpoint within this namespace (and child namespaces). # # When called without a block, all known helpers within this scope # are included. # # @param [Array] new_modules optional array of modules to include # @param [Block] block optional block of methods to include # # @example Define some helpers. # # class ExampleAPI < Grape::API # helpers do # def current_user # User.find_by_id(params[:token]) # end # end # end # # @example Include many modules # # class ExampleAPI < Grape::API # helpers Authentication, Mailer, OtherModule # end # def helpers(*new_modules, &block) include_new_modules(new_modules) if new_modules.any? include_block(block) if block_given? include_all_in_scope if !block_given? && new_modules.empty? end protected def include_new_modules(modules) modules.each { |mod| make_inclusion(mod) } end def include_block(block) Module.new.tap do |mod| make_inclusion(mod) { mod.class_eval(&block) } end end def make_inclusion(mod, &block) define_boolean_in_mod(mod) inject_api_helpers_to_mod(mod, &block) namespace_stackable(:helpers, mod) end def include_all_in_scope Module.new.tap do |mod| namespace_stackable(:helpers).each { |mod_to_include| mod.send :include, mod_to_include } change! end end def define_boolean_in_mod(mod) return if defined? mod::Boolean mod.const_set('Boolean', Virtus::Attribute::Boolean) end def inject_api_helpers_to_mod(mod, &_block) mod.extend(BaseHelper) unless mod.is_a?(BaseHelper) yield if block_given? mod.api_changed(self) end end # This module extends user defined helpers # to provide some API-specific functionality. module BaseHelper attr_accessor :api def params(name, &block) @named_params ||= {} @named_params[name] = block end def api_changed(new_api) @api = new_api process_named_params end protected def process_named_params return unless @named_params && @named_params.any? api.namespace_stackable(:named_params, @named_params) end end end end end grape-1.0.2/lib/grape/dsl/middleware.rb0000644000004100000410000000233313231337007017730 0ustar www-datawww-datarequire 'active_support/concern' module Grape module DSL module Middleware extend ActiveSupport::Concern include Grape::DSL::Configuration module ClassMethods # Apply a custom middleware to the API. Applies # to the current namespace and any children, but # not parents. # # @param middleware_class [Class] The class of the middleware you'd like # to inject. def use(middleware_class, *args, &block) arr = [:use, middleware_class, *args] arr << block if block_given? namespace_stackable(:middleware, arr) end def insert_before(*args, &block) arr = [:insert_before, *args] arr << block if block_given? namespace_stackable(:middleware, arr) end def insert_after(*args, &block) arr = [:insert_after, *args] arr << block if block_given? namespace_stackable(:middleware, arr) end # Retrieve an array of the middleware classes # and arguments that are currently applied to the # application. def middleware namespace_stackable(:middleware) || [] end end end end end grape-1.0.2/lib/grape/dsl/routing.rb0000644000004100000410000001571413231337007017311 0ustar www-datawww-datarequire 'active_support/concern' module Grape module DSL module Routing extend ActiveSupport::Concern include Grape::DSL::Configuration module ClassMethods attr_reader :endpoints # Specify an API version. # # @example API with legacy support. # class MyAPI < Grape::API # version 'v2' # # get '/main' do # {some: 'data'} # end # # version 'v1' do # get '/main' do # {legacy: 'data'} # end # end # end # def version(*args, &block) if args.any? options = args.extract_options! options = options.reverse_merge(using: :path) requested_versions = args.flatten raise Grape::Exceptions::MissingVendorOption.new if options[:using] == :header && !options.key?(:vendor) @versions = versions | requested_versions if block_given? within_namespace do namespace_inheritable(:version, requested_versions) namespace_inheritable(:version_options, options) instance_eval(&block) end else namespace_inheritable(:version, requested_versions) namespace_inheritable(:version_options, options) end end @versions.last unless @versions.nil? end # Define a root URL prefix for your entire API. def prefix(prefix = nil) namespace_inheritable(:root_prefix, prefix) end # Create a scope without affecting the URL. # # @param _name [Symbol] Purely placebo, just allows to name the scope to # make the code more readable. def scope(_name = nil, &block) within_namespace do nest(block) end end # Do not route HEAD requests to GET requests automatically. def do_not_route_head! namespace_inheritable(:do_not_route_head, true) end # Do not automatically route OPTIONS. def do_not_route_options! namespace_inheritable(:do_not_route_options, true) end def mount(mounts) mounts = { mounts => '/' } unless mounts.respond_to?(:each_pair) mounts.each_pair do |app, path| in_setting = inheritable_setting if app.respond_to?(:inheritable_setting, true) mount_path = Grape::Router.normalize_path(path) app.top_level_setting.namespace_stackable[:mount_path] = mount_path app.inherit_settings(inheritable_setting) in_setting = app.top_level_setting app.change! change! end endpoints << Grape::Endpoint.new( in_setting, method: :any, path: path, app: app, route_options: { anchor: false }, forward_match: !app.respond_to?(:inheritable_setting), for: self ) end end # Defines a route that will be recognized # by the Grape API. # # @param methods [HTTP Verb] One or more HTTP verbs that are accepted by this route. Set to `:any` if you want any verb to be accepted. # @param paths [String] One or more strings representing the URL segment(s) for this route. # # @example Defining a basic route. # class MyAPI < Grape::API # route(:any, '/hello') do # {hello: 'world'} # end # end def route(methods, paths = ['/'], route_options = {}, &block) methods = '*' if methods == :any endpoint_options = { method: methods, path: paths, for: self, route_options: { params: namespace_stackable_with_hash(:params) || {} }.deep_merge(route_setting(:description) || {}).deep_merge(route_options || {}) } new_endpoint = Grape::Endpoint.new(inheritable_setting, endpoint_options, &block) endpoints << new_endpoint unless endpoints.any? { |e| e.equals?(new_endpoint) } route_end reset_validations! end %w[get post put head delete options patch].each do |meth| define_method meth do |*args, &block| options = args.extract_options! paths = args.first || ['/'] route(meth.upcase, paths, options, &block) end end # Declare a "namespace", which prefixes all subordinate routes with its # name. Any endpoints within a namespace, or group, resource, segment, # etc., will share their parent context as well as any configuration # done in the namespace context. # # @example # # namespace :foo do # get 'bar' do # # defines the endpoint: GET /foo/bar # end # end def namespace(space = nil, options = {}, &block) if space || block_given? within_namespace do previous_namespace_description = @namespace_description @namespace_description = (@namespace_description || {}).deep_merge(namespace_setting(:description) || {}) nest(block) do if space namespace_stackable(:namespace, Namespace.new(space, options)) end end @namespace_description = previous_namespace_description end else Namespace.joined_space_path(namespace_stackable(:namespace)) end end alias group namespace alias resource namespace alias resources namespace alias segment namespace # An array of API routes. def routes @routes ||= prepare_routes end # Remove all defined routes. def reset_routes! endpoints.each(&:reset_routes!) @routes = nil end def reset_endpoints! @endpoints = [] end # Thie method allows you to quickly define a parameter route segment # in your API. # # @param param [Symbol] The name of the parameter you wish to declare. # @option options [Regexp] You may supply a regular expression that the declared parameter must meet. def route_param(param, options = {}, &block) options = options.dup options[:requirements] = { param.to_sym => options[:requirements] } if options[:requirements].is_a?(Regexp) Grape::Validations::ParamsScope.new(api: self) do requires param, type: options[:type] end if options.key?(:type) namespace(":#{param}", options, &block) end # @return array of defined versions def versions @versions ||= [] end end end end end grape-1.0.2/lib/grape/dsl/parameters.rb0000644000004100000410000002250713231337007017763 0ustar www-datawww-datarequire 'active_support/concern' module Grape module DSL # Defines DSL methods, meant to be applied to a ParamsScope, which define # and describe the parameters accepted by an endpoint, or all endpoints # within a namespace. module Parameters extend ActiveSupport::Concern # Set the module used to build the request.params. # # @param build_with the ParamBuilder module to use when building request.params # Available builders are: # # * Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder (default) # * Grape::Extensions::Hash::ParamBuilder # * Grape::Extensions::Hashie::Mash::ParamBuilder # # @example # # require 'grape/extenstions/hashie_mash' # class API < Grape::API # desc "Get collection" # params do # build_with Grape::Extensions::Hashie::Mash::ParamBuilder # requires :user_id, type: Integer # end # get do # params['user_id'] # end # end def build_with(build_with = nil) @api.namespace_inheritable(:build_params_with, build_with) end # Include reusable params rules among current. # You can define reusable params with helpers method. # # @example # # class API < Grape::API # helpers do # params :pagination do # optional :page, type: Integer # optional :per_page, type: Integer # end # end # # desc "Get collection" # params do # use :pagination # end # get do # Collection.page(params[:page]).per(params[:per_page]) # end # end def use(*names) named_params = @api.namespace_stackable_with_hash(:named_params) || {} options = names.extract_options! names.each do |name| params_block = named_params.fetch(name) do raise "Params :#{name} not found!" end instance_exec(options, ¶ms_block) end end alias use_scope use alias includes use # Require one or more parameters for the current endpoint. # # @param attrs list of parameter names, or, if :using is # passed as an option, which keys to include (:all or :none) from # the :using hash. The last key can be a hash, which specifies # options for the parameters # @option attrs :type [Class] the type to coerce this parameter to before # passing it to the endpoint. See {Grape::Validations::Types} for a list of # types that are supported automatically. Custom classes may be used # where they define a class-level `::parse` method, or in conjunction # with the `:coerce_with` parameter. `JSON` may be supplied to denote # `JSON`-formatted objects or arrays of objects. `Array[JSON]` accepts # the same values as `JSON` but will wrap single objects in an `Array`. # @option attrs :types [Array] may be supplied in place of +:type+ # to declare an attribute that has multiple allowed types. See # {Validations::Types::MultipleTypeCoercer} for more details on coercion # and validation rules for variant-type parameters. # @option attrs :desc [String] description to document this parameter # @option attrs :default [Object] default value, if parameter is optional # @option attrs :values [Array] permissable values for this field. If any # other value is given, it will be handled as a validation error # @option attrs :using [Hash[Symbol => Hash]] a hash defining keys and # options, like that returned by {Grape::Entity#documentation}. The value # of each key is an options hash accepting the same parameters # @option attrs :except [Array[Symbol]] a list of keys to exclude from # the :using Hash. The meaning of this depends on if :all or :none was # passed; :all + :except will make the :except fields optional, whereas # :none + :except will make the :except fields required # @option attrs :coerce_with [#parse, #call] method to be used when coercing # the parameter to the type named by `attrs[:type]`. Any class or object # that defines `::parse` or `::call` may be used. # # @example # # params do # # Basic usage: require a parameter of a certain type # requires :user_id, type: Integer # # # You don't need to specify type; String is default # requires :foo # # # Multiple params can be specified at once if they share # # the same options. # requires :x, :y, :z, type: Date # # # Nested parameters can be handled as hashes. You must # # pass in a block, within which you can use any of the # # parameters DSL methods. # requires :user, type: Hash do # requires :name, type: String # end # end def requires(*attrs, &block) orig_attrs = attrs.clone opts = attrs.extract_options!.clone opts[:presence] = { value: true, message: opts[:message] } opts = @group.merge(opts) if @group if opts[:using] require_required_and_optional_fields(attrs.first, opts) else validate_attributes(attrs, opts, &block) block_given? ? new_scope(orig_attrs, &block) : push_declared_params(attrs, opts.slice(:as)) end end # Allow, but don't require, one or more parameters for the current # endpoint. # @param (see #requires) # @option (see #requires) def optional(*attrs, &block) orig_attrs = attrs.clone opts = attrs.extract_options!.clone type = opts[:type] opts = @group.merge(opts) if @group # check type for optional parameter group if attrs && block_given? raise Grape::Exceptions::MissingGroupTypeError.new if type.nil? raise Grape::Exceptions::UnsupportedGroupTypeError.new unless Grape::Validations::Types.group?(type) end if opts[:using] require_optional_fields(attrs.first, opts) else validate_attributes(attrs, opts, &block) block_given? ? new_scope(orig_attrs, true, &block) : push_declared_params(attrs, opts.slice(:as)) end end # Define common settings for one or more parameters # @param (see #requires) # @option (see #requires) def with(*attrs, &block) new_group_scope(attrs.clone, &block) end # Disallow the given parameters to be present in the same request. # @param attrs [*Symbol] parameters to validate def mutually_exclusive(*attrs) validates(attrs, mutual_exclusion: { value: true, message: extract_message_option(attrs) }) end # Require exactly one of the given parameters to be present. # @param (see #mutually_exclusive) def exactly_one_of(*attrs) validates(attrs, exactly_one_of: { value: true, message: extract_message_option(attrs) }) end # Require at least one of the given parameters to be present. # @param (see #mutually_exclusive) def at_least_one_of(*attrs) validates(attrs, at_least_one_of: { value: true, message: extract_message_option(attrs) }) end # Require that either all given params are present, or none are. # @param (see #mutually_exclusive) def all_or_none_of(*attrs) validates(attrs, all_or_none_of: { value: true, message: extract_message_option(attrs) }) end # Define a block of validations which should be applied if and only if # the given parameter is present. The parameters are not nested. # @param attr [Symbol] the parameter which, if present, triggers the # validations # @raise Grape::Exceptions::UnknownParameter if `attr` has not been # defined in this scope yet # @yield a parameter definition DSL def given(*attrs, &block) attrs.each do |attr| proxy_attr = attr.is_a?(Hash) ? attr.keys[0] : attr raise Grape::Exceptions::UnknownParameter.new(proxy_attr) unless declared_param?(proxy_attr) end new_lateral_scope(dependent_on: attrs, &block) end # Test for whether a certain parameter has been defined in this params # block yet. # @return [Boolean] whether the parameter has been defined def declared_param?(param) # @declared_params also includes hashes of options and such, but those # won't be flattened out. @declared_params.flatten.include?(param) end alias group requires def map_params(params, element) if params.is_a?(Array) params.map do |el| map_params(el, element) end elsif params.is_a?(Hash) params[element] || {} else {} end end # @param params [Hash] initial hash of parameters # @return hash of parameters relevant for the current scope # @api private def params(params) params = @parent.params(params) if @parent params = map_params(params, @element) if @element params end end end end grape-1.0.2/lib/grape/dsl/callbacks.rb0000644000004100000410000000256313231337007017537 0ustar www-datawww-datarequire 'active_support/concern' module Grape module DSL # Blocks can be executed before or after every API call, using `before`, `after`, # `before_validation` and `after_validation`. # # Before and after callbacks execute in the following order: # # 1. `before` # 2. `before_validation` # 3. _validations_ # 4. `after_validation` # 5. _the API call_ # 6. `after` # # Steps 4, 5 and 6 only happen if validation succeeds. module Callbacks extend ActiveSupport::Concern include Grape::DSL::Configuration module ClassMethods # Execute the given block before validation, coercion, or any endpoint # code is executed. def before(&block) namespace_stackable(:befores, block) end # Execute the given block after `before`, but prior to validation or # coercion. def before_validation(&block) namespace_stackable(:before_validations, block) end # Execute the given block after validations and coercions, but before # any endpoint code. def after_validation(&block) namespace_stackable(:after_validations, block) end # Execute the given block after the endpoint code has run. def after(&block) namespace_stackable(:afters, block) end end end end end grape-1.0.2/lib/grape/dsl/desc.rb0000644000004100000410000000637513231337007016543 0ustar www-datawww-datamodule Grape module DSL module Desc include Grape::DSL::Settings # Add a description to the next namespace or function. # @param description [String] descriptive string for this endpoint # or namespace # @param options [Hash] other properties you can set to describe the # endpoint or namespace. Optional. # @option options :detail [String] additional detail about this endpoint # @option options :params [Hash] param types and info. normally, you set # these via the `params` dsl method. # @option options :entity [Grape::Entity] the entity returned upon a # successful call to this action # @option options :http_codes [Array[Array]] possible HTTP codes this # endpoint may return, with their meanings, in a 2d array # @option options :named [String] a specific name to help find this route # @option options :headers [Hash] HTTP headers this method can accept # @yield a block yielding an instance context with methods mapping to # each of the above, except that :entity is also aliased as #success # and :http_codes is aliased as #failure. # # @example # # desc 'create a user' # post '/users' do # # ... # end # # desc 'find a user' do # detail 'locates the user from the given user ID' # failure [ [404, 'Couldn\'t find the given user' ] ] # success User::Entity # end # get '/user/:id' do # # ... # end # def desc(description, options = {}, &config_block) if block_given? config_class = desc_container config_class.configure do description description end config_class.configure(&config_block) unless options.empty? warn '[DEPRECATION] Passing a options hash and a block to `desc` is deprecated. Move all hash options to block.' end options = config_class.settings else options = options.merge(description: description) end namespace_setting :description, options route_setting :description, options end def description_field(field, value = nil) if value description = route_setting(:description) description ||= route_setting(:description, {}) description[field] = value else description = route_setting(:description) description[field] if description end end def unset_description_field(field) description = route_setting(:description) description.delete(field) if description end # Returns an object which configures itself via an instance-context DSL. def desc_container Module.new do include Grape::Util::StrictHashConfiguration.module( :description, :detail, :params, :entity, :http_codes, :named, :headers ) def config_context.success(*args) entity(*args) end def config_context.failure(*args) http_codes(*args) end end end end end end grape-1.0.2/lib/grape/dsl/validations.rb0000644000004100000410000000222613231337007020131 0ustar www-datawww-datarequire 'active_support/concern' module Grape module DSL module Validations extend ActiveSupport::Concern include Grape::DSL::Configuration module ClassMethods # Clears all defined parameters and validations. def reset_validations! unset_namespace_stackable :declared_params unset_namespace_stackable :validations unset_namespace_stackable :params unset_description_field :params end # Opens a root-level ParamsScope, defining parameter coercions and # validations for the endpoint. # @yield instance context of the new scope def params(&block) Grape::Validations::ParamsScope.new(api: self, type: Hash, &block) end def document_attribute(names, opts) setting = description_field(:params) setting ||= description_field(:params, {}) Array(names).each do |name| setting[name[:full_name].to_s] ||= {} setting[name[:full_name].to_s].merge!(opts) namespace_stackable(:params, name[:full_name].to_s => opts) end end end end end end grape-1.0.2/lib/grape/dsl/settings.rb0000644000004100000410000001246613231337007017463 0ustar www-datawww-datarequire 'active_support/concern' module Grape module DSL # Keeps track of settings (implemented as key-value pairs, grouped by # types), in two contexts: top-level settings which apply globally no # matter where they're defined, and inheritable settings which apply only # in the current scope and scopes nested under it. module Settings extend ActiveSupport::Concern attr_writer :inheritable_setting, :top_level_setting # Fetch our top-level settings, which apply to all endpoints in the API. def top_level_setting @top_level_setting ||= build_top_level_setting end # Fetch our current inheritable settings, which are inherited by # nested scopes but not shared across siblings. def inheritable_setting @inheritable_setting ||= Grape::Util::InheritableSetting.new.tap { |new_settings| new_settings.inherit_from top_level_setting } end # @param type [Symbol] # @param key [Symbol] def unset(type, key) setting = inheritable_setting.send(type) setting.delete key end # @param type [Symbol] # @param key [Symbol] # @param value [Object] will be stored if the value is currently empty # @return either the old value, if it wasn't nil, or the given value def get_or_set(type, key, value) setting = inheritable_setting.send(type) if value.nil? setting[key] else setting[key] = value end end # @param key [Symbol] # @param value [Object] # @return (see #get_or_set) def global_setting(key, value = nil) get_or_set :global, key, value end # @param key [Symbol] def unset_global_setting(key) unset :global, key end # (see #global_setting) def route_setting(key, value = nil) get_or_set :route, key, value end # (see #unset_global_setting) def unset_route_setting(key) unset :route, key end # (see #global_setting) def namespace_setting(key, value = nil) get_or_set :namespace, key, value end # (see #unset_global_setting) def unset_namespace_setting(key) unset :namespace, key end # (see #global_setting) def namespace_inheritable(key, value = nil) get_or_set :namespace_inheritable, key, value end # (see #unset_global_setting) def unset_namespace_inheritable(key) unset :namespace_inheritable, key end # @param key [Symbol] def namespace_inheritable_to_nil(key) inheritable_setting.namespace_inheritable[key] = nil end # (see #global_setting) def namespace_stackable(key, value = nil) get_or_set :namespace_stackable, key, value end def namespace_reverse_stackable(key, value = nil) get_or_set :namespace_reverse_stackable, key, value end def namespace_stackable_with_hash(key) settings = get_or_set :namespace_stackable, key, nil return if settings.blank? settings.each_with_object({}) { |value, result| result.deep_merge!(value) } end def namespace_reverse_stackable_with_hash(key) settings = get_or_set :namespace_reverse_stackable, key, nil return if settings.blank? result = {} settings.each do |setting| setting.each do |field, value| result[field] ||= value end end result end # (see #unset_global_setting) def unset_namespace_stackable(key) unset :namespace_stackable, key end # (see #global_setting) def api_class_setting(key, value = nil) get_or_set :api_class, key, value end # (see #unset_global_setting) def unset_api_class_setting(key) unset :api_class, key end # Fork our inheritable settings to a new instance, copied from our # parent's, but separate so we won't modify it. Every call to this # method should have an answering call to #namespace_end. def namespace_start @inheritable_setting = Grape::Util::InheritableSetting.new.tap { |new_settings| new_settings.inherit_from inheritable_setting } end # Set the inheritable settings pointer back up by one level. def namespace_end route_end @inheritable_setting = inheritable_setting.parent end # Stop defining settings for the current route and clear them for the # next, within a namespace. def route_end inheritable_setting.route_end end # Execute the block within a context where our inheritable settings are forked # to a new copy (see #namespace_start). def within_namespace(&_block) namespace_start result = yield if block_given? namespace_end reset_validations! result end private # Builds the current class :inheritable_setting. If available, it inherits from # the superclass's :inheritable_setting. def build_top_level_setting Grape::Util::InheritableSetting.new.tap do |setting| if defined?(superclass) && superclass.respond_to?(:inheritable_setting) && superclass != Grape::API setting.inherit_from superclass.inheritable_setting end end end end end end grape-1.0.2/lib/grape/serve_file/0000755000004100000410000000000013231337007016626 5ustar www-datawww-datagrape-1.0.2/lib/grape/serve_file/sendfile_response.rb0000644000004100000410000000065413231337007022667 0ustar www-datawww-datamodule Grape module ServeFile # Response should respond to to_path method # for using Rack::SendFile middleware class SendfileResponse < Rack::Response def respond_to?(method_name, include_all = false) if method_name == :to_path @body.respond_to?(:to_path, include_all) else super end end def to_path @body.to_path end end end end grape-1.0.2/lib/grape/serve_file/file_response.rb0000644000004100000410000000071313231337007022011 0ustar www-datawww-datamodule Grape module ServeFile # A simple class used to identify responses which represent files and do not # need to be formatted or pre-read by Rack::Response class FileResponse attr_reader :file # @param file [Object] def initialize(file) @file = file end # Equality provided mostly for tests. # # @return [Boolean] def ==(other) file == other.file end end end end grape-1.0.2/lib/grape/serve_file/file_body.rb0000644000004100000410000000111213231337007021102 0ustar www-datawww-datamodule Grape module ServeFile CHUNK_SIZE = 16_384 # Class helps send file through API class FileBody attr_reader :path # @param path [String] def initialize(path) @path = path end # Need for Rack::Sendfile middleware # # @return [String] def to_path path end def each File.open(path, 'rb') do |file| while (chunk = file.read(CHUNK_SIZE)) yield chunk end end end def ==(other) path == other.path end end end end grape-1.0.2/lib/grape/presenters/0000755000004100000410000000000013231337007016675 5ustar www-datawww-datagrape-1.0.2/lib/grape/presenters/presenter.rb0000644000004100000410000000021513231337007021227 0ustar www-datawww-datamodule Grape module Presenters class Presenter def self.represent(object, **_options) object end end end end grape-1.0.2/lib/grape/http/0000755000004100000410000000000013231337007015462 5ustar www-datawww-datagrape-1.0.2/lib/grape/http/headers.rb0000644000004100000410000000163413231337007017426 0ustar www-datawww-datamodule Grape module Http module Headers # https://github.com/rack/rack/blob/master/lib/rack.rb HTTP_VERSION = 'HTTP_VERSION'.freeze PATH_INFO = 'PATH_INFO'.freeze REQUEST_METHOD = 'REQUEST_METHOD'.freeze QUERY_STRING = 'QUERY_STRING'.freeze CONTENT_TYPE = 'Content-Type'.freeze GET = 'GET'.freeze POST = 'POST'.freeze PUT = 'PUT'.freeze PATCH = 'PATCH'.freeze DELETE = 'DELETE'.freeze HEAD = 'HEAD'.freeze OPTIONS = 'OPTIONS'.freeze SUPPORTED_METHODS = [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS].freeze HTTP_ACCEPT_VERSION = 'HTTP_ACCEPT_VERSION'.freeze X_CASCADE = 'X-Cascade'.freeze HTTP_TRANSFER_ENCODING = 'HTTP_TRANSFER_ENCODING'.freeze HTTP_ACCEPT = 'HTTP_ACCEPT'.freeze FORMAT = 'format'.freeze end end end grape-1.0.2/lib/grape/validations.rb0000644000004100000410000000112313231337007017342 0ustar www-datawww-datamodule Grape # Registry to store and locate known Validators. module Validations class << self attr_accessor :validators end self.validators = {} # Register a new validator, so it can be used to validate parameters. # @param short_name [String] all lower-case, no spaces # @param klass [Class] the validator class. Should inherit from # Validations::Base. def self.register_validator(short_name, klass) validators[short_name] = klass end def self.deregister_validator(short_name) validators.delete(short_name) end end end grape-1.0.2/lib/grape/extensions/0000755000004100000410000000000013231337007016702 5ustar www-datawww-datagrape-1.0.2/lib/grape/extensions/deep_symbolize_hash.rb0000644000004100000410000000127313231337007023247 0ustar www-datawww-datamodule Grape module Extensions module DeepSymbolizeHash def self.deep_symbolize_keys_in(object) case object when ::Hash object.each_with_object({}) do |(key, value), new_hash| new_hash[symbolize_key(key)] = deep_symbolize_keys_in(value) end when ::Array object.map { |element| deep_symbolize_keys_in(element) } else object end end def self.symbolize_key(key) if key.is_a?(Symbol) key elsif key.is_a?(String) key.to_sym elsif key.respond_to?(:to_sym) key.to_sym else key end end end end end grape-1.0.2/lib/grape/extensions/hash.rb0000644000004100000410000000116713231337007020157 0ustar www-datawww-datamodule Grape module Extensions module Hash module ParamBuilder extend ::ActiveSupport::Concern included do namespace_inheritable(:build_params_with, Grape::Extensions::Hash::ParamBuilder) end def build_params params = Grape::Extensions::DeepMergeableHash[rack_params] params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] post_process_params(params) end def post_process_params(params) Grape::Extensions::DeepSymbolizeHash.deep_symbolize_keys_in(params) end end end end end grape-1.0.2/lib/grape/extensions/deep_mergeable_hash.rb0000644000004100000410000000101613231337007023150 0ustar www-datawww-datamodule Grape module Extensions class DeepMergeableHash < ::Hash def deep_merge!(other_hash) other_hash.each_pair do |current_key, other_value| this_value = self[current_key] self[current_key] = if this_value.is_a?(::Hash) && other_value.is_a?(::Hash) this_value.deep_merge(other_value) else other_value end end self end end end end grape-1.0.2/lib/grape/extensions/deep_hash_with_indifferent_access.rb0000644000004100000410000000102313231337007026074 0ustar www-datawww-datamodule Grape module Extensions module DeepHashWithIndifferentAccess def self.deep_hash_with_indifferent_access(object) case object when ::Hash object.inject(::ActiveSupport::HashWithIndifferentAccess.new) do |new_hash, (key, value)| new_hash.merge!(key => deep_hash_with_indifferent_access(value)) end when ::Array object.map { |element| deep_hash_with_indifferent_access(element) } else object end end end end end grape-1.0.2/lib/grape/extensions/hashie/0000755000004100000410000000000013231337007020143 5ustar www-datawww-datagrape-1.0.2/lib/grape/extensions/hashie/mash.rb0000644000004100000410000000115613231337007021423 0ustar www-datawww-datamodule Grape module Extensions module Hashie module Mash module ParamBuilder extend ::ActiveSupport::Concern included do namespace_inheritable(:build_params_with, Grape::Extensions::Hashie::Mash::ParamBuilder) end def params_builder Grape::Extensions::Hashie::Mash::ParamBuilder end def build_params params = ::Hashie::Mash.new(rack_params) params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] params end end end end end end grape-1.0.2/lib/grape/extensions/active_support/0000755000004100000410000000000013231337007021751 5ustar www-datawww-datagrape-1.0.2/lib/grape/extensions/active_support/hash_with_indifferent_access.rb0000644000004100000410000000165313231337007030157 0ustar www-datawww-datamodule Grape module Extensions module ActiveSupport module HashWithIndifferentAccess module ParamBuilder extend ::ActiveSupport::Concern included do namespace_inheritable(:build_params_with, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder) end def params_builder Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder end def build_params params = ::ActiveSupport::HashWithIndifferentAccess[rack_params] params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] # TODO: remove, in Rails 4 or later ::ActiveSupport::HashWithIndifferentAccess converts nested Hashes into indifferent access ones DeepHashWithIndifferentAccess.deep_hash_with_indifferent_access(params) end end end end end end grape-1.0.2/lib/grape/util/0000755000004100000410000000000013231337007015460 5ustar www-datawww-datagrape-1.0.2/lib/grape/util/reverse_stackable_values.rb0000644000004100000410000000173413231337007023055 0ustar www-datawww-datamodule Grape module Util class ReverseStackableValues attr_accessor :inherited_values attr_accessor :new_values def initialize(inherited_values = {}) @inherited_values = inherited_values @new_values = {} end def [](name) [].tap do |value| value.concat(@new_values[name] || []) value.concat(@inherited_values[name] || []) end end def []=(name, value) @new_values[name] ||= [] @new_values[name].push value end def delete(key) new_values.delete key end def keys (@new_values.keys + @inherited_values.keys).sort.uniq end def to_hash keys.each_with_object({}) do |key, result| result[key] = self[key] end end def initialize_copy(other) super self.inherited_values = other.inherited_values self.new_values = other.new_values.dup end end end end grape-1.0.2/lib/grape/util/strict_hash_configuration.rb0000644000004100000410000000516613231337007023257 0ustar www-datawww-datamodule Grape module Util module StrictHashConfiguration extend ActiveSupport::Concern module DSL extend ActiveSupport::Concern module ClassMethods def settings config_context.to_hash end def configure(&block) config_context.instance_exec(&block) end end end class SettingsContainer def initialize @settings = {} @contexts = {} end def to_hash @settings.to_hash end end def self.config_class(*args) new_config_class = Class.new(SettingsContainer) args.each do |setting_name| if setting_name.respond_to? :values nested_settings_methods(setting_name, new_config_class) else simple_settings_methods(setting_name, new_config_class) end end new_config_class end def self.simple_settings_methods(setting_name, new_config_class) setting_name_sym = setting_name.to_sym new_config_class.class_eval do define_method setting_name do |new_value| @settings[setting_name_sym] = new_value end end end def self.nested_settings_methods(setting_name, new_config_class) new_config_class.class_eval do setting_name.each_pair do |key, value| define_method "#{key}_context" do @contexts[key] ||= Grape::Util::StrictHashConfiguration.config_class(*value).new end define_method key do |&block| send("#{key}_context").instance_exec(&block) end end define_method 'to_hash' do merge_hash = {} setting_name.each_key { |k| merge_hash[k] = send("#{k}_context").to_hash } @settings.to_hash.merge( merge_hash ) end end end def self.module(*args) new_module = Module.new do extend ActiveSupport::Concern include DSL end new_module.tap do |mod| class_mod = create_class_mod(args) mod.const_set(:ClassMethods, class_mod) end end def self.create_class_mod(args) new_module = Module.new do def config_context @config_context ||= config_class.new end end new_module.tap do |class_mod| new_config_class = config_class(*args) class_mod.send(:define_method, :config_class) do @config_class ||= new_config_class end end end end end end grape-1.0.2/lib/grape/util/stackable_values.rb0000644000004100000410000000231213231337007021313 0ustar www-datawww-datamodule Grape module Util class StackableValues attr_accessor :inherited_values attr_accessor :new_values attr_reader :frozen_values def initialize(inherited_values = {}) @inherited_values = inherited_values @new_values = {} @frozen_values = {} end def [](name) return @frozen_values[name] if @frozen_values.key? name value = [] value.concat(@inherited_values[name] || []) value.concat(@new_values[name] || []) value end def []=(name, value) raise if @frozen_values.key? name @new_values[name] ||= [] @new_values[name].push value end def delete(key) new_values.delete key end def keys (@new_values.keys + @inherited_values.keys).sort.uniq end def to_hash keys.each_with_object({}) do |key, result| result[key] = self[key] end end def freeze_value(key) @frozen_values[key] = self[key].freeze end def initialize_copy(other) super self.inherited_values = other.inherited_values self.new_values = other.new_values.dup end end end end grape-1.0.2/lib/grape/util/xml.rb0000644000004100000410000000023713231337007016607 0ustar www-datawww-datamodule Grape if Object.const_defined? :MultiXml Xml = ::MultiXml else Xml = ::ActiveSupport::XmlMini Xml::ParseError = StandardError end end grape-1.0.2/lib/grape/util/json.rb0000644000004100000410000000022613231337007016756 0ustar www-datawww-datamodule Grape if Object.const_defined? :MultiJson Json = ::MultiJson else Json = ::JSON Json::ParseError = Json::ParserError end end grape-1.0.2/lib/grape/util/content_types.rb0000644000004100000410000000125313231337007020704 0ustar www-datawww-datamodule Grape module ContentTypes # Content types are listed in order of preference. CONTENT_TYPES = { # rubocop:disable Style/MutableConstant xml: 'application/xml', serializable_hash: 'application/json', json: 'application/json', binary: 'application/octet-stream', txt: 'text/plain' } def self.content_types_for_settings(settings) return if settings.blank? settings.each_with_object({}) { |value, result| result.merge!(value) } end def self.content_types_for(from_settings) if from_settings.present? from_settings else Grape::ContentTypes::CONTENT_TYPES end end end end grape-1.0.2/lib/grape/util/inheritable_values.rb0000644000004100000410000000162313231337007021654 0ustar www-datawww-datamodule Grape module Util class InheritableValues attr_accessor :inherited_values attr_accessor :new_values def initialize(inherited_values = {}) self.inherited_values = inherited_values self.new_values = {} end def [](name) values[name] end def []=(name, value) new_values[name] = value end def delete(key) new_values.delete key end def merge(new_hash) values.merge(new_hash) end def keys (new_values.keys + inherited_values.keys).sort.uniq end def to_hash values.clone end def initialize_copy(other) super self.inherited_values = other.inherited_values self.new_values = other.new_values.dup end protected def values @inherited_values.merge(@new_values) end end end end grape-1.0.2/lib/grape/util/registrable.rb0000644000004100000410000000040413231337007020306 0ustar www-datawww-datamodule Grape module Util module Registrable def default_elements @default_elements ||= {} end def register(format, element) default_elements[format] = element unless default_elements[format] end end end end grape-1.0.2/lib/grape/util/env.rb0000644000004100000410000000153313231337007016577 0ustar www-datawww-datamodule Grape module Env API_VERSION = 'api.version'.freeze API_ENDPOINT = 'api.endpoint'.freeze API_REQUEST_INPUT = 'api.request.input'.freeze API_REQUEST_BODY = 'api.request.body'.freeze API_TYPE = 'api.type'.freeze API_SUBTYPE = 'api.subtype'.freeze API_VENDOR = 'api.vendor'.freeze API_FORMAT = 'api.format'.freeze RACK_INPUT = 'rack.input'.freeze RACK_REQUEST_QUERY_HASH = 'rack.request.query_hash'.freeze RACK_REQUEST_FORM_HASH = 'rack.request.form_hash'.freeze RACK_REQUEST_FORM_INPUT = 'rack.request.form_input'.freeze GRAPE_REQUEST = 'grape.request'.freeze GRAPE_REQUEST_HEADERS = 'grape.request.headers'.freeze GRAPE_REQUEST_PARAMS = 'grape.request.params'.freeze GRAPE_ROUTING_ARGS = 'grape.routing_args'.freeze GRAPE_ALLOWED_METHODS = 'grape.allowed_methods'.freeze end end grape-1.0.2/lib/grape/util/inheritable_setting.rb0000644000004100000410000000671113231337007022035 0ustar www-datawww-datamodule Grape module Util # A branchable, inheritable settings object which can store both stackable # and inheritable values (see InheritableValues and StackableValues). class InheritableSetting attr_accessor :route, :api_class, :namespace attr_accessor :namespace_inheritable, :namespace_stackable, :namespace_reverse_stackable attr_accessor :parent, :point_in_time_copies # Retrieve global settings. def self.global @global ||= {} end # Clear all global settings. # @api private # @note only for testing def self.reset_global! @global = {} end # Instantiate a new settings instance, with blank values. The fresh # instance can then be set to inherit from an existing instance (see # #inherit_from). def initialize self.route = {} self.api_class = {} self.namespace = InheritableValues.new # only inheritable from a parent when # used with a mount, or should every API::Class be a separate namespace by default? self.namespace_inheritable = InheritableValues.new self.namespace_stackable = StackableValues.new self.namespace_reverse_stackable = ReverseStackableValues.new self.point_in_time_copies = [] self.parent = nil end # Return the class-level global properties. def global self.class.global end # Set our inherited values to the given parent's current values. Also, # update the inherited values on any settings instances which were forked # from us. # @param parent [InheritableSetting] def inherit_from(parent) return if parent.nil? self.parent = parent namespace_inheritable.inherited_values = parent.namespace_inheritable namespace_stackable.inherited_values = parent.namespace_stackable namespace_reverse_stackable.inherited_values = parent.namespace_reverse_stackable self.route = parent.route.merge(route) point_in_time_copies.map { |cloned_one| cloned_one.inherit_from parent } end # Create a point-in-time copy of this settings instance, with clones of # all our values. Note that, should this instance's parent be set or # changed via #inherit_from, it will copy that inheritence to any copies # which were made. def point_in_time_copy self.class.new.tap do |new_setting| point_in_time_copies << new_setting new_setting.point_in_time_copies = [] new_setting.namespace = namespace.clone new_setting.namespace_inheritable = namespace_inheritable.clone new_setting.namespace_stackable = namespace_stackable.clone new_setting.namespace_reverse_stackable = namespace_reverse_stackable.clone new_setting.route = route.clone new_setting.api_class = api_class new_setting.inherit_from(parent) end end # Resets the instance store of per-route settings. # @api private def route_end @route = {} end # Return a serializable hash of our values. def to_hash { global: global.clone, route: route.clone, namespace: namespace.to_hash, namespace_inheritable: namespace_inheritable.to_hash, namespace_stackable: namespace_stackable.to_hash, namespace_reverse_stackable: namespace_reverse_stackable.to_hash } end end end end grape-1.0.2/lib/grape/error_formatter/0000755000004100000410000000000013231337007017717 5ustar www-datawww-datagrape-1.0.2/lib/grape/error_formatter/xml.rb0000644000004100000410000000142113231337007021042 0ustar www-datawww-datamodule Grape module ErrorFormatter module Xml extend Base class << self def call(message, backtrace, options = {}, env = nil, original_exception = nil) message = present(message, env) result = message.is_a?(Hash) ? message : { message: message } rescue_options = options[:rescue_options] || {} if rescue_options[:backtrace] && backtrace && !backtrace.empty? result = result.merge(backtrace: backtrace) end if rescue_options[:original_exception] && original_exception result = result.merge(original_exception: original_exception.inspect) end result.respond_to?(:to_xml) ? result.to_xml(root: :error) : result.to_s end end end end end grape-1.0.2/lib/grape/error_formatter/json.rb0000644000004100000410000000161213231337007021215 0ustar www-datawww-datamodule Grape module ErrorFormatter module Json extend Base class << self def call(message, backtrace, options = {}, env = nil, original_exception = nil) result = wrap_message(present(message, env)) rescue_options = options[:rescue_options] || {} if rescue_options[:backtrace] && backtrace && !backtrace.empty? result = result.merge(backtrace: backtrace) end if rescue_options[:original_exception] && original_exception result = result.merge(original_exception: original_exception.inspect) end ::Grape::Json.dump(result) end private def wrap_message(message) if message.is_a?(Exceptions::ValidationErrors) || message.is_a?(Hash) message else { error: message } end end end end end end grape-1.0.2/lib/grape/error_formatter/txt.rb0000644000004100000410000000141713231337007021066 0ustar www-datawww-datamodule Grape module ErrorFormatter module Txt extend Base class << self def call(message, backtrace, options = {}, env = nil, original_exception = nil) message = present(message, env) result = message.is_a?(Hash) ? ::Grape::Json.dump(message) : message rescue_options = options[:rescue_options] || {} if rescue_options[:backtrace] && backtrace && !backtrace.empty? result += "\r\n backtrace:" result += backtrace.join("\r\n ") end if rescue_options[:original_exception] && original_exception result += "\r\n original exception:" result += "\r\n #{original_exception.inspect}" end result end end end end end grape-1.0.2/lib/grape/error_formatter/base.rb0000644000004100000410000000247413231337007021165 0ustar www-datawww-datamodule Grape module ErrorFormatter module Base def present(message, env) present_options = {} presented_message = message if presented_message.is_a?(Hash) presented_message = presented_message.dup present_options[:with] = presented_message.delete(:with) end presenter = env[Grape::Env::API_ENDPOINT].entity_class_for_obj(presented_message, present_options) unless presenter || env[Grape::Env::GRAPE_ROUTING_ARGS].nil? # env['api.endpoint'].route does not work when the error occurs within a middleware # the Endpoint does not have a valid env at this moment http_codes = env[Grape::Env::GRAPE_ROUTING_ARGS][:route_info].http_codes || [] found_code = http_codes.find do |http_code| (http_code[0].to_i == env[Grape::Env::API_ENDPOINT].status) && http_code[2].respond_to?(:represent) end if env[Grape::Env::API_ENDPOINT].request presenter = found_code[2] if found_code end if presenter embeds = { env: env } embeds[:version] = env[Grape::Env::API_VERSION] if env[Grape::Env::API_VERSION] presented_message = presenter.represent(presented_message, embeds).serializable_hash end presented_message end end end end grape-1.0.2/lib/grape/cookies.rb0000644000004100000410000000151613231337007016467 0ustar www-datawww-datamodule Grape class Cookies def initialize @cookies = {} @send_cookies = {} end def read(request) request.cookies.each do |name, value| @cookies[name.to_s] = value end end def write(header) @cookies.select { |key, _value| @send_cookies[key] == true }.each do |name, value| cookie_value = value.is_a?(Hash) ? value : { value: value } Rack::Utils.set_cookie_header! header, name, cookie_value end end def [](name) @cookies[name.to_s] end def []=(name, value) @cookies[name.to_s] = value @send_cookies[name.to_s] = true end def each(&block) @cookies.each(&block) end def delete(name, **opts) options = opts.merge(value: 'deleted', expires: Time.at(0)) self.[]=(name, options) end end end grape-1.0.2/lib/grape/locale/0000755000004100000410000000000013231337007015742 5ustar www-datawww-datagrape-1.0.2/lib/grape/locale/en.yml0000644000004100000410000000471213231337007017073 0ustar www-datawww-dataen: grape: errors: format: ! '%{attributes} %{message}' messages: coerce: 'is invalid' presence: 'is missing' regexp: 'is invalid' blank: 'is empty' values: 'does not have a valid value' except_values: 'has a value not allowed' missing_vendor_option: problem: 'missing :vendor option.' summary: 'when version using header, you must specify :vendor option. ' resolution: "eg: version 'v1', using: :header, vendor: 'twitter'" missing_mime_type: problem: 'missing mime type for %{new_format}' resolution: "you can choose existing mime type from Grape::ContentTypes::CONTENT_TYPES or add your own with content_type :%{new_format}, 'application/%{new_format}' " invalid_with_option_for_represent: problem: 'You must specify an entity class in the :with option.' resolution: 'eg: represent User, :with => Entity::User' missing_option: 'You must specify :%{option} options.' invalid_formatter: 'cannot convert %{klass} to %{to_format}' invalid_versioner_option: problem: 'Unknown :using for versioner: %{strategy}' resolution: 'available strategy for :using is :path, :header, :accept_version_header, :param' unknown_validator: 'unknown validator: %{validator_type}' unknown_options: 'unknown options: %{options}' unknown_parameter: 'unknown parameter: %{param}' incompatible_option_values: '%{option1}: %{value1} is incompatible with %{option2}: %{value2}' mutual_exclusion: 'are mutually exclusive' at_least_one: 'are missing, at least one parameter must be provided' exactly_one: 'are missing, exactly one parameter must be provided' all_or_none: 'provide all or none of parameters' missing_group_type: 'group type is required' unsupported_group_type: 'group type must be Array, Hash, JSON or Array[JSON]' invalid_message_body: problem: "message body does not match declared format" resolution: "when specifying %{body_format} as content-type, you must pass valid %{body_format} in the request's 'body' " invalid_accept_header: problem: 'Invalid accept header' resolution: '%{message}' invalid_version_header: problem: 'Invalid version header' resolution: '%{message}' grape-1.0.2/lib/grape/error_formatter.rb0000644000004100000410000000152513231337007020247 0ustar www-datawww-datamodule Grape module ErrorFormatter extend Util::Registrable class << self def builtin_formatters @builtin_formatters ||= { serializable_hash: Grape::ErrorFormatter::Json, json: Grape::ErrorFormatter::Json, jsonapi: Grape::ErrorFormatter::Json, txt: Grape::ErrorFormatter::Txt, xml: Grape::ErrorFormatter::Xml } end def formatters(options) builtin_formatters.merge(default_elements).merge(options[:error_formatters] || {}) end def formatter_for(api_format, **options) spec = formatters(**options)[api_format] case spec when nil options[:default_error_formatter] || Grape::ErrorFormatter::Txt when Symbol method(spec) else spec end end end end end grape-1.0.2/lib/grape.rb0000644000004100000410000001237513231337007015040 0ustar www-datawww-datarequire 'logger' require 'rack' require 'rack/builder' require 'rack/accept' require 'rack/auth/basic' require 'rack/auth/digest/md5' require 'set' require 'active_support/version' require 'active_support/core_ext/hash/indifferent_access' require 'active_support/core_ext/object/blank' require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/hash/deep_merge' require 'active_support/core_ext/hash/reverse_merge' require 'active_support/core_ext/hash/except' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/hash/conversions' require 'active_support/dependencies/autoload' require 'active_support/notifications' require 'i18n' require 'thread' require 'virtus' I18n.load_path << File.expand_path('../grape/locale/en.yml', __FILE__) module Grape extend ::ActiveSupport::Autoload eager_autoload do autoload :API autoload :Endpoint autoload :Router autoload :Namespace autoload :Path autoload :Cookies autoload :Validations autoload :ErrorFormatter autoload :Formatter autoload :Parser autoload :Request autoload :Env, 'grape/util/env' autoload :Json, 'grape/util/json' autoload :Xml, 'grape/util/xml' end module Http extend ::ActiveSupport::Autoload eager_autoload do autoload :Headers end end module Exceptions extend ::ActiveSupport::Autoload autoload :Base autoload :Validation autoload :ValidationArrayErrors autoload :ValidationErrors autoload :MissingVendorOption autoload :MissingMimeType autoload :MissingOption autoload :InvalidFormatter autoload :InvalidVersionerOption autoload :UnknownValidator autoload :UnknownOptions autoload :UnknownParameter autoload :InvalidWithOptionForRepresent autoload :IncompatibleOptionValues autoload :MissingGroupTypeError, 'grape/exceptions/missing_group_type' autoload :UnsupportedGroupTypeError, 'grape/exceptions/unsupported_group_type' autoload :InvalidMessageBody autoload :InvalidAcceptHeader autoload :InvalidVersionHeader autoload :MethodNotAllowed end module Extensions extend ::ActiveSupport::Autoload autoload :DeepMergeableHash autoload :DeepSymbolizeHash autoload :DeepHashWithIndifferentAccess autoload :Hash module ActiveSupport extend ::ActiveSupport::Autoload autoload :HashWithIndifferentAccess end module Hashie extend ::ActiveSupport::Autoload autoload :Mash end end module Middleware extend ::ActiveSupport::Autoload autoload :Base autoload :Versioner autoload :Formatter autoload :Error autoload :Globals autoload :Stack module Auth extend ::ActiveSupport::Autoload autoload :Base autoload :DSL autoload :StrategyInfo autoload :Strategies end module Versioner extend ::ActiveSupport::Autoload autoload :Path autoload :Header autoload :Param autoload :AcceptVersionHeader end end module Util extend ::ActiveSupport::Autoload autoload :InheritableValues autoload :StackableValues autoload :ReverseStackableValues autoload :InheritableSetting autoload :StrictHashConfiguration autoload :Registrable end module ErrorFormatter extend ::ActiveSupport::Autoload autoload :Base autoload :Json autoload :Txt autoload :Xml end module Formatter extend ::ActiveSupport::Autoload autoload :Json autoload :SerializableHash autoload :Txt autoload :Xml end module Parser extend ::ActiveSupport::Autoload autoload :Json autoload :Xml end module DSL extend ::ActiveSupport::Autoload eager_autoload do autoload :API autoload :Callbacks autoload :Settings autoload :Configuration autoload :InsideRoute autoload :Helpers autoload :Middleware autoload :Parameters autoload :RequestResponse autoload :Routing autoload :Validations autoload :Logger autoload :Desc end end class API extend ::ActiveSupport::Autoload autoload :Helpers end module Presenters extend ::ActiveSupport::Autoload autoload :Presenter end module ServeFile extend ::ActiveSupport::Autoload autoload :FileResponse autoload :FileBody autoload :SendfileResponse end end require 'grape/util/content_types' require 'grape/validations/validators/base' require 'grape/validations/attributes_iterator' require 'grape/validations/validators/allow_blank' require 'grape/validations/validators/as' require 'grape/validations/validators/at_least_one_of' require 'grape/validations/validators/coerce' require 'grape/validations/validators/default' require 'grape/validations/validators/exactly_one_of' require 'grape/validations/validators/mutual_exclusion' require 'grape/validations/validators/presence' require 'grape/validations/validators/regexp' require 'grape/validations/validators/values' require 'grape/validations/validators/except_values' require 'grape/validations/params_scope' require 'grape/validations/validators/all_or_none' require 'grape/validations/types' require 'grape/validations/validator_factory' require 'grape/version' grape-1.0.2/gemfiles/0000755000004100000410000000000013231337007014432 5ustar www-datawww-datagrape-1.0.2/gemfiles/rack_1.5.2.gemfile0000644000004100000410000000123613231337007017431 0ustar www-datawww-data# This file was generated by Appraisal source 'https://rubygems.org' gem 'rack', '1.5.2' group :development, :test do gem 'bundler' gem 'hashie' gem 'rake' gem 'rubocop', '0.51.0' end group :development do gem 'appraisal' gem 'benchmark-ips' gem 'guard' gem 'guard-rspec' gem 'guard-rubocop' end group :test do gem 'cookiejar' gem 'coveralls', '~> 0.8.17', require: false gem 'danger-toc', '~> 0.1.0' gem 'grape-entity', '~> 0.6' gem 'maruku' gem 'mime-types' gem 'rack-jsonp', require: 'rack/jsonp' gem 'rack-test', '~> 0.6.3' gem 'rspec', '~> 3.0' gem 'ruby-grape-danger', '~> 0.1.0', require: false end gemspec path: '../' grape-1.0.2/gemfiles/rack_edge.gemfile0000644000004100000410000000125213231337007017670 0ustar www-datawww-data# This file was generated by Appraisal source 'https://rubygems.org' gem 'rack', github: 'rack/rack' group :development, :test do gem 'bundler' gem 'hashie' gem 'rake' gem 'rubocop', '0.51.0' end group :development do gem 'appraisal' gem 'benchmark-ips' gem 'guard' gem 'guard-rspec' gem 'guard-rubocop' end group :test do gem 'cookiejar' gem 'coveralls', '~> 0.8.17', require: false gem 'danger-toc', '~> 0.1.0' gem 'grape-entity', '~> 0.6' gem 'maruku' gem 'mime-types' gem 'rack-jsonp', require: 'rack/jsonp' gem 'rack-test', '~> 0.6.3' gem 'rspec', '~> 3.0' gem 'ruby-grape-danger', '~> 0.1.0', require: false end gemspec path: '../' grape-1.0.2/gemfiles/multi_xml.gemfile0000644000004100000410000000126013231337007017775 0ustar www-datawww-data# This file was generated by Appraisal source 'https://rubygems.org' gem 'multi_xml', require: 'multi_xml' group :development, :test do gem 'bundler' gem 'hashie' gem 'rake' gem 'rubocop', '0.51.0' end group :development do gem 'appraisal' gem 'benchmark-ips' gem 'guard' gem 'guard-rspec' gem 'guard-rubocop' end group :test do gem 'cookiejar' gem 'coveralls', '~> 0.8.17', require: false gem 'danger-toc', '~> 0.1.0' gem 'grape-entity', '~> 0.6' gem 'maruku' gem 'mime-types' gem 'rack-jsonp', require: 'rack/jsonp' gem 'rack-test', '~> 0.6.3' gem 'rspec', '~> 3.0' gem 'ruby-grape-danger', '~> 0.1.0', require: false end gemspec path: '../' grape-1.0.2/gemfiles/multi_json.gemfile0000644000004100000410000000126213231337007020150 0ustar www-datawww-data# This file was generated by Appraisal source 'https://rubygems.org' gem 'multi_json', require: 'multi_json' group :development, :test do gem 'bundler' gem 'hashie' gem 'rake' gem 'rubocop', '0.51.0' end group :development do gem 'appraisal' gem 'benchmark-ips' gem 'guard' gem 'guard-rspec' gem 'guard-rubocop' end group :test do gem 'cookiejar' gem 'coveralls', '~> 0.8.17', require: false gem 'danger-toc', '~> 0.1.0' gem 'grape-entity', '~> 0.6' gem 'maruku' gem 'mime-types' gem 'rack-jsonp', require: 'rack/jsonp' gem 'rack-test', '~> 0.6.3' gem 'rspec', '~> 3.0' gem 'ruby-grape-danger', '~> 0.1.0', require: false end gemspec path: '../' grape-1.0.2/gemfiles/rails_3.gemfile0000644000004100000410000000127313231337007017323 0ustar www-datawww-data# This file was generated by Appraisal source 'https://rubygems.org' gem 'rails', '3.2.19' gem 'rack-cache', '<= 1.2' group :development, :test do gem 'bundler' gem 'hashie' gem 'rake' gem 'rubocop', '0.51.0' end group :development do gem 'appraisal' gem 'benchmark-ips' gem 'guard' gem 'guard-rspec' gem 'guard-rubocop' end group :test do gem 'cookiejar' gem 'coveralls', '~> 0.8.17', require: false gem 'danger-toc', '~> 0.1.0' gem 'grape-entity', '~> 0.6' gem 'maruku' gem 'mime-types' gem 'rack-jsonp', require: 'rack/jsonp' gem 'rack-test', '~> 0.6.3' gem 'rspec', '~> 3.0' gem 'ruby-grape-danger', '~> 0.1.0', require: false end gemspec path: '../' grape-1.0.2/gemfiles/rails_4.gemfile0000644000004100000410000000123713231337007017324 0ustar www-datawww-data# This file was generated by Appraisal source 'https://rubygems.org' gem 'rails', '4.1.6' group :development, :test do gem 'bundler' gem 'hashie' gem 'rake' gem 'rubocop', '0.51.0' end group :development do gem 'appraisal' gem 'benchmark-ips' gem 'guard' gem 'guard-rspec' gem 'guard-rubocop' end group :test do gem 'cookiejar' gem 'coveralls', '~> 0.8.17', require: false gem 'danger-toc', '~> 0.1.0' gem 'grape-entity', '~> 0.6' gem 'maruku' gem 'mime-types' gem 'rack-jsonp', require: 'rack/jsonp' gem 'rack-test', '~> 0.6.3' gem 'rspec', '~> 3.0' gem 'ruby-grape-danger', '~> 0.1.0', require: false end gemspec path: '../' grape-1.0.2/gemfiles/rails_5.gemfile0000644000004100000410000000123713231337007017325 0ustar www-datawww-data# This file was generated by Appraisal source 'https://rubygems.org' gem 'rails', '5.0.0' group :development, :test do gem 'bundler' gem 'hashie' gem 'rake' gem 'rubocop', '0.51.0' end group :development do gem 'appraisal' gem 'benchmark-ips' gem 'guard' gem 'guard-rspec' gem 'guard-rubocop' end group :test do gem 'cookiejar' gem 'coveralls', '~> 0.8.17', require: false gem 'danger-toc', '~> 0.1.0' gem 'grape-entity', '~> 0.6' gem 'maruku' gem 'mime-types' gem 'rack-jsonp', require: 'rack/jsonp' gem 'rack-test', '~> 0.6.3' gem 'rspec', '~> 3.0' gem 'ruby-grape-danger', '~> 0.1.0', require: false end gemspec path: '../' grape-1.0.2/gemfiles/rails_edge.gemfile0000644000004100000410000000125313231337007020063 0ustar www-datawww-data# This file was generated by Appraisal source 'https://rubygems.org' gem 'arel', github: 'rails/arel' group :development, :test do gem 'bundler' gem 'hashie' gem 'rake' gem 'rubocop', '0.51.0' end group :development do gem 'appraisal' gem 'benchmark-ips' gem 'guard' gem 'guard-rspec' gem 'guard-rubocop' end group :test do gem 'cookiejar' gem 'coveralls', '~> 0.8.17', require: false gem 'danger-toc', '~> 0.1.0' gem 'grape-entity', '~> 0.6' gem 'maruku' gem 'mime-types' gem 'rack-jsonp', require: 'rack/jsonp' gem 'rack-test', '~> 0.6.3' gem 'rspec', '~> 3.0' gem 'ruby-grape-danger', '~> 0.1.0', require: false end gemspec path: '../' grape-1.0.2/grape.png0000644000004100000410000001026013231337007014442 0ustar www-datawww-data‰PNG  IHDRX{1#˜ltEXtSoftwareAdobe ImageReadyqÉe<RIDATxÚì]rÓÊÇ'ÔyÇw˜D ˆXf(+ÀþÓÓ3Óc €@œÅÎÀêÙßçôaSnÓ’ÓÑÔ·ŸÎPÌ«ö£ùµÖ¦Ž¿W[͸ •ß¿"TÉ ¾È8‘!·±ÚS‘ö„Ú'‘Äõ3&W@h ²j­½=9µ/õÕ~¬QÇ€ˆ,lª|‹lPeq-P·€Dð*²ÁÖ¾Ä;ˆ+ Q‘=Ÿ¬ÀÚÌ?5¿´ E6S¶`I\¨C@¢ä¼³i’ × uÔß½ , °^©³Ò~`ˆƒ¹ÒsÔ?³g{@ ȈË ÂóúöÓֵ͔0×ö…¯Ð®,~¯ˆãSžæ—?¡:ÛNY`I\sÍÑpÒâûË~|´BÛÙÏ*…<=I¸¼6W€@h¯L".Å”¶FSLY?’XX¯Z,œ0XðÄ_(w^¾|ùÌüû&†îçÏŸ·'ø®´&óñžöÙ‡Ž*níoÜL°¬(€ÈbJíâ@œd[†À¦Û_›ß§>2óÀæfûÿèƒ|A %ÛH¿Oô}ßšûk}{þ:àóƒQ_n¹9òš .Ë»ÎΩíS*â+h}Û¨í;üŠ”ß|P•·“gˆ.VÕr[s³¹ïlk"ûYÙ†ùqÏó?˜ñ¤sû¬ëåÑŒü~¹//‚÷]!ª$<…q?mÓ r>xó{Õxsl§w-oÅvAe²µÏ©¹>n=·ã þÍ•¿©¾/û»«Wì³Z.s:|°ÇwÆÎ¸G£ÆYÚçý—§)[èÎïKÂjÓW~ÖFA\*W¸Ž~=D9½Sj =ÊÿgmuaµéÂ…Ñ9±DõYq{~ ¥€ÀJâ£n‘¡M­QRÇfA¬…•žó™Å§ü½P}ð\V_yÐÐdÔŠuúÍø½oÉBû#Ôྸ’…Ùz´º 7Ê·‰¼ïÓuãZn‰ïZÉ"èK\}$Ú [È3‘U 2ÏS4 °iŠkc„YÜ$â.h\“A¹e‰Te¡-²Äu·m|æóëLÄap¨ ²ØÄõOƒŒüΟÅ5µØ¿…¢»`Ãå16ÿ÷EL ²ؽÓä*‚Hd±¦ÔìëÓøíå6Æ] á\GÌÿëƒe‘H¹Ï^d!°; 9âô6–8iYÏšåÖxªÛ)S=6H°˜­Ë÷&å3¾Á>X}KnJ¥³Œœ‡Ž§³Í¾ƒ“c…£eFÓûË ×Õ‚ËéÍö{n‰º'ß”¯°`a½jXƒÔ‘—V,Îú4ˆÔB0ÆWÚXÿܦ/‡NcÑ 'ÚÜoÓ%—£4JÒÂó¢–è|§î—Ü&¨mlcõÀö-qݲxçTNä_<»qÝ vúÖkîØ¹V‡Ná°xPºXÙÌ‹}MÂ:æ T޶üV\Þ— ‰…öI)§âÐ1hn”¾Û¼¯ƒ°‹!ðj§ý~phOô¼Í¡£º;ù/Yˆ%ù'?rãHð©[°ù:»‹ÕjÍ‹c8’HÐÿOt:wH@jîˆ×gÎKß¡+®;^ú»Ú{˳•ïGæ¬ñ7Ž®Ž|hÅŽêJê5££ÒÇŠ•=ç_Rþ 3 œª^…°`%º h½>s°(jžºJ„âÒþö„Û>–†-›CâqÍ@$bẅ¨vVMmÙðKP÷W\vÒ‚Êüz`Œµæ·œ÷‡¶»ˆÅãØ²b¥îÕAØ«KWà¦.°·5îÛa ãî—óÑ0iúþêËLÚ]}Ñ]åT¸H©Úl!ÌûBÛ•X±A ‡QTóçÛE°qèä©O Ö®#1?¥iSoÙ;}—ìV¡Üb‡É+•B$JXZ°{Í{cÇÖJØLWMª3¶?ek Cµ8ÞÖfòƒx…¼OGRáVˆ6~N*VìØic¿ò<69y_åÖ(’âFú¬\Øv+Ųä}å#ZØ¡ÁD:€òìÛ/>XW—Fd;“CÄ"íüÕ&þé›ÑVYÄ@×eÄrÒŽ] ß'Î ÔÚ.ïêèù ¼‡>_; èÕ±ÜõòUU –TߦŽâÚ¼Q6s¨8톓ÎÄ?»~̀؇SŒ9ÍT­+žj7¶;vq«ñ°À$)§ç¶&ΡŒ6äª<û½©Á/ŸK3 |Öý¬ ýç¡ÚÕ•K+²¡gÇÉìÝ# ßêÜl•惔¡¬Î`æÖîhP 6°³ÈÖì.6 ÇXUzÙ:°K õÎÂU·Ê‘ÉV'VG[ÏõŸ¡xYÚ¹ð·`õÁÓ½Šm,%!!¿mê­ ²Þ;ïcƒ–°ž›û½±`õ‹(~u×µ‘osEÌp…4Z—dAižœ@ƒ‹GtŠe…ƒéÔZ·óÔ¦oÜF½[®)ì:9ñƒ aÆB8Ùé!ïM-Zzs ŒÜ­ÖÖDpY¥p›,ŸjÓ2_BË‚uZ¸a˵ðœÇ†]s÷?ÒP‡‰³4ó"ÈÎ 6ÚêXåë샭o?ñ‘óá2E\Ñ1[Ú»°’GjäkôpL4Š벯“}®Z–kÇõÑ'üÚÄ@,'úìaw‰”e¨|T e[±H·c׋T¹x‹%ÚÔ{áøR%/|¥32ã÷Õšb¿6ÓÄõxmÃm¥I BV4 ü„â(¼Ÿ‘kàÂÑ-pwØe^}ÍÌ5Ÿœh„VY32Ä¡é4E;“ÛÎÄÖkîPîîñzb¯Mì¹IÌ’"R¸X­´wÖ5^|°l}æÓ€Þ)µ;‘Ÿ 6$—æíc£Sµ'à&JÊE06ÆmÑjÉ–l˦Ýqô[ÏVfâ1úNâPN1CÕ6CAÒ¥S]Ç«oêòkQÓñÕæÝi¥œß¡ôµÙ Öü¹I£â3~Né3÷¡‹W—Ó_…Ë*6[yJ3Ÿ±–ìà^±Âáw7;o…uñMR4‹°é‡à¶|¯ØD)ÍüBƹ ™š.¤ YŠÖY²?Žt½5÷Ñœ¤4ÃcÚŽW“ݑۊ]/Ç«KÔ´ÍÜ: \ƒ†Ê÷ÅZÙy'—ÔM ™ò“åDß+Žñűp•&í0ˆ”·†¯°nö >™¹¬aì¶Ýö·WF~r’žY²‹«Ý“ÿ¥¹¿M< S>!°óÙï¶‘¹úc¥âZ™i…á«Ü‡˜³åÔòs¶æÿýº½åfZ‹Kã7²Øæía…qP•y,ïÂÌì¿Eö½íø‹À Â5 Y,uµº}vèS£3,f‘Û€g`U‚yßL0î„ ðÁîo¬—j1ÅÆçèû‹ÅTÅœ²GóRjÛÎ)‚vœÈÆßÂWßi¦¼ªº1éÄ= h 7ÎúØøÃƒGÅÕÌü !ìãAzQz^Æŧ\>dQÅ8Uµ5²ÅÈ¥Â; ,`ÅØAx`D×ĦC`‘[›^+m*nt¯Nå4 [V>-ý}w)¬ •hR¬Ä-ÂWÂ<öÆAŒù\_Ì]\!°ãì5w¬þTV `ûˆ¥Z±-èû§èìçΜ{îÌTÎå ãJWÌs¥wöéBº»CÊõZ"þ~{sˆ°·ZßC1~ƒ]²iñwNšH`¶ • ­bÓ;¬nŒÛ~ ÛfhõÓß¼ït촿Ъ;Xl0)yg”=¹½~l?ôøÎ˜Û)-ì´X:ÏÍNç,|úÎ\p’ ¹?n\?0Õ,Mäˆd,ú—öK¯ÕÈ<õþäÊç즯®Ÿ×æ~k ´üÚA¾oÑ}!°©3Vˆ¶{:z'e¸3ÓbÐöyfƒ©y~Àê?»c;lJ癦ÆïùØi/^ÙÎàÙª ÏÆÃíÄÇäõÏ ŒóºÔK¶g°ïÌ}€ïv®{ZOJ`é>ó@7ËF‡ãs޵`Û)¼‹í5'“Ê @l¯&”×ÛAýÌvF87 67ú~Î}âvadÛ°VŠÛ¬ á pX?¢“ò.‚Pº]®îÖø§Xtg¿&‘Ø) ln êk )¬4žæ3…,”ÂéL®À^qmà"8RÄl‘©_šÆó͵®4B‹´–^zÈÖëk¡¥^c7˜±€î[&¡°Ÿ¡n•uaiÞ~t¦Giè½þÒÃÑ"ËÁ—¥ÁR6èj`¦ø8º>DÕõ6û[eÙMpeÜn–þœ®ê0ò ïl“À1¨½sÉ»k3|kÍúƤU§t° ‰ ßÇ>]:æs~€ª)ºzñJÚ’¥(I|í†ë@à3ˆô:ÆÆtfÀÖxp½ÙEÀ QÍ yeÒ½ø°âPy}6>6…ܦU˜Äomå…ª<Á|V®wØÒZqõrÂ0˜À’/6QñÚÙã?ôÞJˆ+þÄÕx\ zÐÀŠìÍ„D–ü¨17ó“Àçs¼ê€âê3æIð“\,²¾÷²©¸ lzÁšíK?Çv,üÍ ­½ðP*ÊQYrØÔ_Ã’ô‘O¾Éà¹ùíCö9(ˆÓ¬%¬V¼/´S`éËçºKÔ£²¼»àÎJ[=û›¢Z-MäÊ-F¸âÃ+s°Ø…ÆÜ•Æö«°P¹—(†ÉÑ êêz˳砜¡¾ÜàX®4(ô{_÷,nv+‚ iþ'À¬¶Mû9UIEND®B`‚grape-1.0.2/pkg/0000755000004100000410000000000013231337007013420 5ustar www-datawww-datagrape-1.0.2/pkg/grape-0.19.1.gem0000644000004100000410000056700013231337007015744 0ustar www-datawww-datametadata.gz0000444000000000000000000000425713034734553013455 0ustar00wheelwheel00000000000000‹k¹sXí[_Û6×§Ðõ¥Oþ³Û‡hÑm²HH·Å&íC‹‚ ¥±ÌZU’ò®Sô>û IY–mR¢zwXìÁ›`cq~CG3Ù13™Lâˆz¹›ñåï¨Å;(‹$lŪ/£’°ˆ3A+ˆ¶ $Ž-L?[RÇ-h>½úrzU9U+.ŠE¬™"Z«5rMâïY²¦ÇßæÀ²µ¦pÔLà‚Ñ’•)‹ÿŠ –ᬿþ¥T!âz~õÏÉüj2ÿ2žÏæït¾ÿ‰‰R¨ L¡L˜ÕÎe~»GìPl»OA“ >4bP*×fdÁq)=2Á?Ÿ}ýÕgæA?öiÌþ´z»š~1ã°ÚU(ÑBÔ¥bà@%@@TâðŠæÚ&G"<“È:.j©@´,'Ö¬þ[úþ××KøùôÕ³éû?y„MOh’@¥žÛ´?Ÿþ² [ ¨fš(¶YWEÿ]Ô¹bäwi¦yöH}ýò"õõ8M?ùs+z>}ýÒmETôšÊ5ƒçÖòõôê¥%Vä@-o™Pµ|þ 1yéÝ<\ËËšå)ˆË ø7NA&‚UÊ ÜÄȯªõ‘‹MŒU&sKã›ïâ¶óJ¯?2µÆ ¨Š^nqgÓ Êr]ü¶Ôú†•J°è4áEOÔŠ.s,t]O J-Lû(()OÈŠí1öÎxSU‚2‰*ć7ßÝÜ¿»}ÿûi‘êÇî?>Ü}ûÓÇ»ûfä--3šPÇŸ¦9Dz k*Ò†ôþîÍíý‡[üôp{óöû[;ÏÃíûÛ›í´t þ§ß=ܼm)K´ÉuAÅf&YQáb‰£™]OÎtNL®tˆžf­4ÇTH3pY.É~Ò+?鵟tºœ®Œô³Äj¼}®Ê ?çl9³ÏfSíã mÃ14[C^¡•’Î7XŸ§2wM¤‡šçKÔ“ oŲZ˜¶  Û5¾š:ij$§äšÄÐRS ‚× \ôœghq.JÁÒ4‡G*œ|Õþ¦<«j—©0TÈ ýÄ9ƒ‰•™‹$Ai’sê-ÍYJ­ãž1ÄV]÷l\.ˆn®P¥Î7{Bž-é¹À§VaÔÓ$3ÌÏ OºÕÛs r ³£S…ªÀÈD¸$¨úÜV˜Œ‰-t‰5ª¼_{çØ¤¤%Owðý¹,KâÙu‹Žü{áVÐ0ñ„“à°•/š÷š§¤äŠ CóGHûÀLJ4Y’¡YWDŸ§àÛPìàV÷@<ÖR šºÜ”ü±l€2Ùú|¶qSÞmÚ†éíàûA B… ;bœN†q¸±^ãïªÁp‘O:‰ ºŠñCQ£7^¬•ª|gæ 4×qqºÃâ´K9÷™î4;CÍ)£ïDb*¤ s—䎰rÅ{À‚™÷ÕCÇ4Áñں߫í`²œ/1ëAH…Ç}½X!˜Y›û㢓sÔ8s(Rõ”Qã T²dUg@]þÈŠ&g¯Õ¬#Ü£NÿjH§p­Û|”íðñÓä-gÃ:{îÑZ`KüHФK™»‚^­Œ¥•ª3Gà nÁÚ–Ýgê)Æ—uup¸ý´‹¹™ÉU±ÔQæ­K'Ê­sœ•k y¦h"M67ˆsç.&0¦èˆ±ÌÁC×6‡Ki?š,$X¢L¬&½){O>Ú!¬D†/Ûe$]¸ñNIdÂÏÄ.ÎùfÎ3ÓlÀ}€H@ ÓZ*^Xgf2ê ÊåÇç(ÓQÅrt¤[ŠÇ,ÚkÂós ‡óš®W—Õ溌mŽƒ¯7Ï &]%F½pþH–9-7¡ŠèŽŒ"¸á«@.×êZ]‚SXQ|Khx¢‰ÊwãDo­ ñ†[)jUÓœ`’—ײßk»lö`Ö†%xªÁî`Óœ•vX71: ‰Æ ;ópbS€*×Ùn8Å|ºÉêý Ç…×ׇôCXi; =lxŒ¢Mg³râ«5{\ð´½…ÑÇ€¾LšŠnP( ÏJöɤ:ë>œél¦ã„wq™úôP?1½È5ºuŽT=î™ç‡éf•ŸÚ”%}€ž-œ¶¯ü(ÛÄòÓ¹©Óy^Ìi[«i›[~À¾ÅåG ºý¾Ýå£*¦vZ§Ç„ù$±¾­}9œ¤`®¶Þ æ8íö 2žuW‚98éœãÛÃ`ã¬#1†Ã E;ÌzsSÏ’Cd_ÕeÆjZþmñw¡rNS¯ƒ¸ºaHtœ0à¡S1ˆZÝvvQû6ˆð“óîÄ Î”=ƒ¨.ÄþÑ &ÂûÎfÜ´-Í7¿«•àFîO 'ÑW)¢mBÙöUÅ=,£ ž ÙÍ3P 3uKâa´)ê†aîn,ß¾Çw\ÎⵕÚ(–¦^Ås\µb=-ÀF1ï˰QL¶ÅÒgã–OëÉ›û¦îFŸNg³õ} ÒîjÕßµË.5 }wÔ~=¢O –}nT Ç„øèß#l·g×k“ÇÝ8×´¼€Y‚‹nŽy {þ%ö¡7íbÖ¼€Šfú2—R•\Ìf–>õRß´˜é[ ö²³Uk”³0϶×àï>F˜ ST3]ÄþU ¥=·ùÎqGæ&F“š™»M½ej93VßQ[„é5IÏýãÛ,§wYŽn² ßc9ºÅr$‚¾Âð¬b4×y´¾Ó 5&¸™"ŽÎE¼ž¾ž^E’eƤ7°C”ìþ—ˆôU$뢠b§/ëØ{&®;;¦I‰“Å·>Nr¶}GN#¥OÐöFÍ¥Iri’\š$—&É¥Iri’\š$—&É¥Iri’\š$—&É¥Iri’üŸ4Iþ 4ÕÙ×q@data.tar.gz0000444000000000000000000055333513034734554013402 0ustar00wheelwheel00000000000000‹k¹sXì½i{ÛÈ™(šÏüˆ}Ï¡ÔMR\µp¦“ȶìVÆÛ#ÉÝÉõø ‘°@€€’éNßß~ß­ Årw:™9ñ“´$T¡ðÖöîËéb‘QÄùïþnÿÚvû°ßÿ]›ÿ­ÿlíßuzí^ÿ¨× zп׃G^ûw¿Á¿e^€r? Ãø ýj_ŸÜ“ïèÕáGœ7{uo’ÖÅ2 óZíïýãΠwøaoV‹|xpÀ½5NçÜãæ4 áÿw±Œãì¾?ôÞ-&A—Ý’» Ž&ׂ Âì:]ð‹ïYäq€xMïýŸ^wé$¬ü7í· ~Ï  ~ºdlãa'¯Ûêó'ÃçIšMª¿Émû è—óe¾ nƒÊžº”Œ>™åë»A{ ОޥÑÄ»d%S/¼ /º,ƒ¿,‚b7I oã™wãz‹,¼‰>ÑÄŠY:òæ"\eѸò󥎓äy ÚNó´ñX&í¶ÛH,&áM°Œ îa±Ì½›4ƒGqˆ‡¦˜°Qá"^ñÄÆiR„IA3û€gIX=)Õ(Á'¼ '¼{Ð9Æ3~¸íŒ·ÝŽTÔi§÷^‘zK˜UNÃO {PÀdò Ë‚UN€·i\,“ÊÏH›^Úö‘4GÍdâM³t¹ð‚¢È¢ÑWWudÁÖ×÷&J"¼p R¯Ý¯ü<× ôºn—¿‹w-,rØæþ·yç Xy©Ú·XËÄóG!€ú^L˜†IXTö”63G·£Òé*X'!Ýõ–;œ˜óšÃõ ½(ÇË <Ç |¦ÿxŽch™ìQÏ|ß§YÝf£¼òûØ``tCZ¶‚À€k儈ä–#åÂ=‡-âÐAšLƒ|±å€H›¬ëFd»Hd/ÂÉrz÷A–ÀÙÌá&šx@à¢î[mwA£XˆÝ~€ý3ôBÇ ¸©ãYM+?nš :踡ƒŽÅ Ã< À‡É8’ø;@l~Lؼ}pô%dÞ?vÚdè.”‰î¼îԜɰ&‚»üöÂP  ÍÅéø¶zo©I­YÿøÐ ÜÚó9œ§9œ5Ø©ðÓ8\àæá¹[º"Ch(Mæc@PÕxH50Gnks„kó,KJ\£¥ Þ]Ø‹¦;ßÐ?qƒà!¸„ËlÐÚ þô§o½|•Á§¯áÄ „‹D¦ìú&Ê@·ÝÆÌÙ:\ýMÂÖ?9v ¹ÅK$XŽJ”ãøEaéDæ®d«ä¶PGöB 3º.óh2‰Ã{ÄæL~ˆð N“Õ<¶zž‡8^BëÀcã[‚;KóêýÅsÙÜÖï×ï,É}€à2ŒÞM&' ÇatgsYø_Kä\)ªËòŸôÜr¥OÓ0ã1D'æ£I@g6çóšÛÖ}(|„(ðïÉ—PpÏ òAþÊìú8€#ÊB’Æ[¨‡OŽâ*_à öq¡ƒM¢ñ2†sU ƒnVëÜsCI=BIÌýWr^‚l€›­¼E DãW8Ù½C'2Ýñ.¸lþ<Ìs`Ö®oÕïÁ¾û´nÃáQDÃáúX0?5¿M—•ijrÇn+w,’Šge¼ ¯o²tî ©Ïu¨¡AZ_Þ`‘±pGK¸–ͨb>qé¸xò±¿|ÄÂX>œ¡YpL1Q0©³ò“ ]Ç9Ÿ›ù|‡A5+"múfº© ú¤‚8ûÌ#L0²“b¬Æóßfé˜~Ëq:^æE:‰ÒÊÏ”»h NBt—Í€Ë,‹tàU6'dæyõÑĆj vè¶4‡=f±YV†{·3bRfr×|x™xÝÜÄéªz‹¸I/Æ¡ÛbŒ:ãš:œ<H`UŠû9m$ËŸ#;MG埥ÌQ!J‡WsÔ¦Ùœ$7î°(pâ)öÃäÎGMB#Ú> eF7ÕR‹†­çFL{Hþ¯çÁÑž,ðõ¤ ü3€£¶Ð RŽ„°tK¹|.d±çÆAöÚö’mJjýHD¾¦Ç|O³Û ¢jÒ¨5Tn*‰~[8[R·Ñ¢\ѹ¢`â±’;fh‚ÈoW•S†h ܈†ê&bTªq2«@+˜{Y¦º·E4O‹Y5\ªQÃå&¢õŽÕútš¯GqܯÜíó¾^EsTëÝ1bv”Ü4æåô_§¯è.œá|]ÿ9<»,²TÖŒ£ÛÐKGaؾ‰&I5’ã& TÏíd'¬u¸îiÁaI§Iô ¬Õ/Æ]7¯‹ö-ÝpƘcT…×´q³0^„b¹$æÃ+V e4š¦Éç ?W©ZÍ.ºi+ºJ¬áëQ’Õ•Æ oÏ÷g§ÏÔåQ4-àMà Îð6˜/•ßæ¦¯±u÷Ü$ŽI¢æ˜¢Í¸‚ÛpuŸfšQ0!æšø9YcéædñJ¨ˆâÚŠä «ÛÊ“»Æ³” ÒIt³ò¾r4]O—txA˜ó‰ãÿ=³6ÅÇûêõÅ ï PQØ;ø¢Ý½Ûu"fÐý—)µòâã,šWË(yMj»n†ï.¾¿§ ÄvË$½÷‚» ŠÑüfdL[¾ûŠÝíöܬw¤U•UVJÔ£±:ªáÝÏ"Çéæ1;´Œh1rKp×Bœ‹&¢ÌŒ’ŲÀ¿á\+}ÑxLƒm:#i4“9v› ²yOñ¦+Ë=ˆÌ–š*ÑôkÖM£×%]q¦í~É@¶&»Â2p;{ƒ®Þd¥gK;B½b¾åaŠsÀ™ÀÃs¥¡X‘KtsD¤tžÀ§€6EplßÐ=ú;’–&Ì‚ÉéDµ4jµ›É Ü&3ГaÒ K¥3»¡ªq^a·k40×µ ïr5¥1®+0¸l•¥ÓÆez­VëëàsÓtI?¢ oþ0dÃáe˜L#ò×OãÎ\O÷Øm뎵BYù$°®ï$i±Â@¯Õºë «¾\ñ ctãªÖ|Û=4œ'npž(8™Û*­l.{NÓlО6‡UVµVrlÝŽ}Y_8£?_¾y-ø Ú`…´²[j*Í\xš4ùlÊÕÍnPTÉ«}yt«^S7ƲÛÕš1oˆ(`\zØ%#щ¸–œ6쟃ä²@ª͘fƒ¾OÜÐ÷‰–ŠÑ8ª…7qWe¤Cå¸Z§'¤ÖüZvÁp½Ýn¦¼î¡bŽ}BA¾'Yž§­Y”ÿþ$½†Å¾f4)š80ñ Ä,œ/Â-–ZÕ¨avséi­`iKyÈzOuûÌ-C îóòóÕgÜfГ™¤7JD`[ÏÎ)Ê[6Wî³À_÷ü¯e4¾]ÕZ2Õh`w»a…`½F° aˆ(á âp]3ä-e¸Rê~×]ÀzÜD:´À[&FwGº”’KèWÈS7Ó|G›æAà…qhSEC—¥· •LFƒè´z">†´¹“èæ&$£¯œ…Ü ´ÝHeIå«pžFŸCï‡(ÃíÁºlt.€Ùʃ½fwÇy#ÇÍ8¬÷³;Ðܰ]»£"7P¡Å’æpLÐ$,럎Q¢×¢jk)…ÔÜë·yQý&5.†^‘-CÆ‹!Ýi§%O«Öî`fáĵɎtAÈF§""^˜I¢5‚S™g¤Á‡õ'&“uÉ´Ø‚“¸ÉbÎ{ÈœÃ÷¿Ä›·Ýlb<—Ó †òØªÒ )Ð Ó‡}dYÛ}'º3(¹íŒùìòåpøV³' À‹¬„ÄÂVSìà¡Óí‡î¢¡Z,G€Û7m¶iƒÜNòÇ7ðêµÒ_ùâX<’8œ%aVlq064¬nürûÈì+^“…}‘daU @¬^0¹ ’I8ú¸±zòél™Ü†ô3¬Õç-ÞÒ¦Ás §iS8€wJÊÑ“‡¯Ó"º*>Ç4•‘ÍËÐÂÝâß6y öáŽD(Ês Á¸å:îˆ,Þm¤äq¬=:‹åêúG+c“À)¬‚(›Vûs“^Ùž#r2‘ʓ墩|7|Ö:úÔ¡¼QÙj%3Zв²Ïáš».ªVžj6 Ú7âð“œ;‰ªånxn>>pÃ1cWeÆLkæ/D}Khgã,ÓšÂ~2Ьšã&£Û’ßÔ›(ºëúç¼;Èô°ÍÇoHÖŽÆö1^óÞ{p:™ÌƒÏœ¿Ûh ƒfõаº¹Údä‚U‚N´/‹èn¼òIúà«@èA‚§õÕlGÛM‡Ñ&†2Ä”Ð×k}»~bnØ à¦É"â£Éý1[|ÄÃ0º©¦Ú'‡—"Q̸‹^Lq ¸w(ö[¸…“]M4ruO”f[P Ã͹dÃ&üxÿOöA♲ ÌDˆt[L“é°/,«Ïá²+ë{²«-NNÆ8\!UeÍ8 &¢Ï}ð›»J„ê›$jàoARˆ¸§èÉ[~ ·ÐúÝ÷vèÈ…Þ†è*«⺒ûƒ¥½ŸE/“d5Ù"w–zèUrÑ£PŠKÎC Æ™‘£I¤\Áù]As’·`œ•ÍI¢Î½½azÛð†7é2™ÀÏQ0¹—¤†ãÖ>cí$µ,Ú…¦[õ\ºNsénÌçA¹Šr11hã ’”qËžÓ×@zä)+ãÖ²c °r¯ó’S??‰b_ŒoÚ £§*l=ˆo>϶„§©Fí¡Óºv…\ŒXú¬¹Mt ƒ“t¼”HmœYÖ>Þ¥É$ ª=4u«FànÎrí®ÅÒŠ…ŸŽ@Ã&.Š ¤Da×Gm7¶| wu%-ñ·'N*¾““¾VXi³; h¹­óÙN(ɉ4Ÿk€u‰‘í¯Ö¢ìôm''»“žQØ­B-²tŒÚ‘2õêˆÙ¹¿Îvî¯c¸¿'½×‰bCr8#KN4a–!QáˆLFòñ¨?‡£D<=Š8cÏ}ƒÌœ§Â×0Çÿ;#=3àèþfi¸åÈq“¾nJŸ¶Rú_;;E¨}åË‹–_ù‰¶»âSùå“"÷´_.ܨ-7˜Z n‚ üB‡@4q$/(ŠANbvW³«Ô¢pK¾Òî˜Ý¯ ©ýQÑ2²Cá]Ú‰¡¾Y&AV-YJ›Áp=GÉ­kôÄËР+ŠrÀ¨Xó9¨êBã £5É…¸n’ß1³)@Ù}¢>ƒgvh»%ñÁŒjzS@6†™“ݬÐ5/+æçË}õ@ˆ—9zkXÂò®ÊyÅœw9ït{Š9'TáäÜsÒ5'Ö/RïÂ/4æ˜)¼g€H1øVœÏcNAÃêàáðT‘ÏáPõôwñNŽRÐÛEõ¡üåà5ç,ÈaöÙΦ¤Šó±`ÇG.X z›Õ«¸ìO§>δôOnpA 8h?¦[œÁ®Q7r·ƒjE,r½^§uØj+_`rJÏ»}d˜‡ìðîñZî sö9ÉqCl×K-­/t§ãÓ`f˜ÍŠpóàýγ¢´jéÄóÕç4Â}øC²ûûÞ «kŒß«–kXŽ—Pñ„Ð; ãIîÄÌ´ÐyûÐd^c©•œ‘%ib ³ R?^2Õ‘(uGÐ:=§UìÓ"ƒ&ꥅWp sÏI.’ )Þ£,Äâ!DVvoÐnïKêCøì5ª x^ê–¹ï¤1 ¾ ½/¾¿ºz{©ŽMÃyÞJ3Ž=Ó<¯ž[ÌO›ÒÛ÷CªÉ¾p?LJ.‚#ô¦\ŒÇNŠè-o9ñ ‡òä‡ Îì ¿!ŸËò”ˆ÷¹¤)I¡w\l˜R–àcŽtfçR ÐÄgMv¡0ŸoÛ>iSÑÉzy|h¤ýíaüóˆœ Þ7ôœ´kyX'DI;mý _£Å"˜d[´½ÒV:’ö¤t(œ2ÀBoÞÞ®‹zhØuš]'i^§7þf†ñä‹akãb•nÉãkš%°±Ç·¸¡c“lé‘“>÷ˆô¹špø, Ä«k-¢à) ?è=q-3‚'Aq w^¨GHEîÓìV…ÃÉÊ»ðLß°Æcˆ*b"—À+!?¢INƒY<~jeƸœ½ nﶘU£š´SŒ×‘ ñZ“‘«· f&„zÁ9=r+#ŒƒIºÅSZ4Œ')±-ÙèÊ"ûiN«•å¹üJ·æc˸ˆ|å³Ö4nÁm0Ê‚Ù×cÝú ”EŽ¢$ÈV Jh#v÷ƒû¢©lè¾8'Ýô馟ŠfY{–QS#w¿N™0N 8åЩT9jkÕßÖ†¾«æ¸îƒ8üTùYnR°9åÚ9:¶¨ŽÖ lGêx~ÄóBë]”.s$:˜rèrDC’÷™ÕäÄrõi;Šíˆ.i)vWƒ;¹×“wºÛ’  }öZCÖXî£ðvƒ.v)§…§˜ÝUº¬g¡œ’—Ь%:ν°5m5”%ƒŸ 7àVàâY"ê3îIÁ!¨<ã.-Ä+Ü‚LûíþþWH‹ÇN žcKÁŒ¢˜ÔΩ¸dzÁ*,…Ò–E7ú7Ôˆn<ãxú»ó&¤” ÷ŒæpˆªuV»žŸÓvwtÜ )Cˆ‰ð·åòà«øk™Þ³Ë—|?G·Àη8zšfŸS¦ã®áM1†„ØKŽ}eå‡$J‡å…õÖÛ()¹ú„# vã-ÎhÒ¨Ásâ:»xÿP$8°­KÁ4@ß./Žà?pÇY"ß^‹‹œ$Õyá¹ÞP'‘Ä0LþCa¤öͽIŽw‹C8¤p‚¤õ>Ýf-6îã_Ùâ¿bšõ :]0ÉÁ§M¢iKz5Aã´ÉˆR%…}k’ô.-¶ƨ°ô”³Qz“ b9RÅcH€.åiúÞEÕ‹N-ú¦õnZ_§Ð´mS¬Q™ÿ@ÀPµ¸|v~¶<.\Ö³¿«§­È}Ë×–T|¨©¤f££%1²lÅ>ÂäÚ‡e…A n"†§uHœÖS‰‡âDE|PGß”"kl²ç¼Z…C-†ÒS­þA÷ „~0p‘ð ·'ÂÕšìÕ+¸@ûH`Æ"cLTˆ.MÕvå’æTf«ìUe¥ÛªnWϳA§ãŽ%‘+<ê«â^”–Ä“õ(½Ñ¸ÚFÏNÖâAWÕ¥Sz£kbB¯•Dgµp+Ö*mRtËè+…9 Ki\sÀG€ªÏ¡jÔ€œRw Ä, B¨ªs5÷Û=œ&¦ÍrÁInÕ¹˜¢Ò¼Ë’âõUî2èÀg/Ýî`9q¤h¡°BwVöZå!§BÊoÜH”ŒMrÿ¯ƒS6ãA¯]ewÁܘ¡Ê5þa°V`…ÐʇÊ8øŽSqºÙTŽr{’^d:—˜oF_lŒ¨ ǬÁ£‹ d[¡žÇ†ñÝlKÔ!6)°ûN;Ðoo/¬|[£u¾Ïý¾Ó÷û2iìÖ–ogÇFšsàÌN¾Û×€•%{Ên‚Y¤÷µðÆñˆ"’7lyœÄsb}}'‹µ[Il®ˆÍà.Ò<Ìåb6½RäÞ•o:Ár¨iÍšÊfà TÃ&¹¤•‚…¬¼mzYNŠgv¸J‚l2ß’>Uµª™¹0qÐÛ‚ð¾ãίÉðÓYBlNo²å‚ëöJQ®í²Ð[ç'EWM`/}­DSä匶m+Ë8á$T)™–ŠôeÖsy›GEµÂRÚÔ²;¥èt’"hÌ0]¸FŽ,…"ʤä;:Õ8HȘj/ОÐ;¢'oíÁ±•í> ÀJ›z#Ûµ}äDÒÅrlQà8%øÞ)pPÇ3Ü;•_,L€u‚ûÓ VDžŠuÖM˜t¹JÐ[Â@ÕºÇìð¤*°Œþìo”—ÑÂŒ,˜Úê^Î;Ní¤(ªSFP‹†z൭Äbú%zÁ>V!¥ÌιIiŸëœ¡â—g€•«=Y¨IƒwìÞ1UT^Õј¹ÐfZ/á7ãt%ÿ~ÈJ“‰x­­Ò ‹o²0ÜæbµëëtÍ /Q½a‰üD¿¤¦oé<(7†0^)€9Mþ×–<4Тê9Ô³L%ë¬( ãYO,¤ÈÕpa Uö© ez(5ÙWÉšNÔªc®Ø8 Ñ‹@à ÞWߤ-¢¹rUÙUqÊè3èo„)[‚7‘Åò¢ìÌŒ8eçô¹ŸøJ2Ç™ÜÜ**Ⱥ™*Ètˆn_Êê&ä…îM¦ŽáîÜœ“ôF¾¤o)¯§ s­9@®c{Ñ8reûd$ eÅ“™X™ÒØkO|)Ãl‹×µhéÄF«Tî\ky”¦H$átNšypÂ¥gOæÏ"œyXMU£ÃiA•ÁÎKƒuu‹ªPÁ 3qšï'€ÛŒÂâ¦I/4ïºM%Â÷Š4ó6c ÉÁ¬˜ÇÕ¯ì{Zëè2»C'×a§­Ï8+Ù•4…QôxhÑO^'K§£Pv»Åâ ópµE-gš:‘*uÚùЫV(öœ¨íQužŽ-SNç `¹|ß%“<þ–üN9+#ÏPUKBþ¡ðdçdúó°ž­äæƒÓ?2¿**Ùô%>æ.ß®€Ì|¼’j~¦ÔC¹k &¥°x·€‡æ$å&ê¾:•GÿèÈi¿ìà[-©såú>\PNÕ@¹sö^¯`ÒŸçQuÕ¨}†ñæé9Y—U.–£˜;à•X?Âiz ò“¦ßÉVŸÃÌÕÆ~ˆš÷“ƒÎáÖ›b%xR¿³’ÊÝ” ê´Ž[GND»ï˜å®O™<Α ‘7æ ‹¥OØ Ž ¨ÚýÁ-ýûˆ_Ó1mÚk¤ã ‹}XÎi­mî𣵬o%ªb"PÀ¾7JÕJ L‰=ïó"á}µHÞkœäÊÁwÊáÞ¾¹¼‚ã»*çIÇï?;{yvuVfö' jÍÛÜg¤Q多ê[ª)ýPå2t­×„f› 9¬&åÂqõβ88‹áD¨tKü»ÝE¯jÏiUQ,x‰¹·zÝÐÑV¥`)@úŸC*a)uÏœDA§$^ý¥ªâ„ë$0“Ç™YveãÑ‘ÃäuRZXv^ZÇ¿h¹{n [ ?Döóžö)áÖkš£œ§qÌ4Ç2£¢ó ‰^¼ïòñ ¸Ç-UÿTs%qì:’èî±vpÌ)ñuô™çÅÖ®uÙNd)¼\– *l.—^Aiý³ŽjQŒ 2’“Ünv±*†÷5wp’š7<Žý/p‡='ËAÏF¯\âÒ"§×ðÈg‚ù„IDZîœë ’¨¦òaågþzÇÆžcúŒÞ±eüù“8ˆaJ®$` ¤eœ‡dOÊJï_šOù•)\‰o¸•ØßÔáen~V]'?+Éô@ÅJŒf‰ê†ð™ãi;toOªm…“Ù²š«•6¢S‚—Þ‘•°Ç®ç×P^ ùr0óMyJu€S°ªU-ýî^a='ývïÄPÄ’n„ib–²œ–Fwi:I«q¯jTX×I÷ÕßâoUÚbï4:šœð¾ùƒâÀädRü| rt4޶( M³óÈ +¶©l«1¬kÉ©•85Sї^dd‰Þ¾»òÇR&W˜7ˆxár™º}7¬ý©®YR¤&‰âSI…ºØwb¬a—FâÙímПÞѱӕ:V>Î9²ûÚI³(Y¶XñN²Š@‘BaLx„¤ZŸ Z5buº>Çmí}­éÕcT)]c8×5a~‰.+Ðïë‹.ŠÕƒŠp¶x>®p0 i¼-çƒî`J/ôúng¶××þâZ‰N Äœ©T4Júu9åÐì)¿¾!'(T‚›‘>u3åÃÒ’Vó#¥¶äé–FuÍ;޼\G§°·œhÖÌUæ¦Kʦœy‹Aü*èºkfÖ‘æ÷i¾Î—ó “¤À12M<(êå%g=9›ª¤+{VéEæÃ„ —²¦R(†£¢ó0Hæé–“¡5juÛú¿$çbÁÎ*¢P°<æ¤ðÉ`LFW+7Åd€ê•¥} ñ~Gß¡ ²¹ô½Iª: ÷iJ¿¡\+Ù#Žg{§ÑpRthh··QvA9~*k’¿VFùº”‹›îEaËÄn²÷{ð)øH4 dzjkµë™8.wׄ¸l:eÛÞŠÓºNG‡w•U–Ù½ˆæ3 ¹™AµÄkw0ÂCuËýƒŽ’˜z œ¨×@_Ì2®¼‚ŒÕ0d ‰²ÐÚ"'¼£ÈRsæÏP¥5ðÍmuÔýõ¹p}ç¨4§]½N_&þ\ñ6,—K'Ê$¡|”öÂiKÕ(a÷bdÅcv^áCô9š‚¢Zÿ-m :©"zº%Ïç@ÇÄo×ÒÈ+?%ÆÈú†ãÛñ,ˆ¶h£Të/¢Æ¬re  Í0¹~) `FLÒ° äê¸,…)c¬1öï Ñp¡A_5Aš„ð³L‚â{„PÌ›f¦ ÏŠÂà&è@\kaüGÜúˆ “aü\ʳìŽT/‚{fyX@'É‘T•82.¸VKîùar÷¾Rçm‹:×?´Ëƒã«üVmg%í:òrKxÀÝÁzË6ÝÝ {ðó8Œ›{oÏI%ÙëkJ£H¦‚æUÏD¯Ò*}(Ž0†ò,ó"¸Kó`¹%vÀî@gõ~…Ü}Í«eOÓ¬Q†S(×À\ÉÄDå*,ÖÃDÿá½°og€¶•ET ”®[ÍgVCƒöâð׊ €¨šÎUG–rÀÎå‚:Ük¦d¶ ÅétÊ6}æn8)Ï}-P€àæKNï}þÒØJ‚M Þr¬ÕXWÚ3ɪëè}^'åBÅÃ×Qü|}¥üÀ…WÅ«•uŽõ4x17$Ðj”Óö&ž&Í•N÷Z]Jm}\¦ÓÇâ jqðÉ.NN–Y€¾‹0 N.,¾«y¸-}M®‹t‚nP†ÎQIñqO7Ýļí®å¥Ú~m¬ÄªuÃ̺'ý’‚q9 ª£÷ž^j²¯XµýdaRîhÄvç}o*:l«ÇC#hÄ줛èé¢çT?¡×·Œ7CÑ—|}´®cYYÑ-ÞLH#()§§ôÌ¥‹=‰ÂÑ–šdáHM´çDz[ô…Æú‚bfŠì¤Õä8¯Âlö¹šõT ¬¶[õ¢^Û¨‚ÉÐjC‡º+¦2kÁØÛ)ïZ¯m‚áÿòê¥í5Îä÷Xv«FçïdŒéLlµ;±‘ž¾èôŒù‚ËЏ+É«È ó” Íi[’Ãs7æ×QOÐë˜)]ˆám\ÅAexg«èòäÃÜÀkZ7WžSlh¯ZiTz©±gIG@J8bO¯ÅéݶLyÔ¤y¡cG^èXx!¥#´Rt˜´]o‡Iæ¸Z#1Ì–¾zçzâÆ¨uÈŽò#*!§ &Jrvå‹=‡­~p¹Òe6ѱÇ<'é3èüTF›ˆ‰9FM%JD˜–÷Wø Î_ŒŒ0F”¯—™¤×IZ\³ Ï’SœŸŽ5±¯îßûu'ÎÁär$Ÿ_Këipñ¬ô×`¹„Pœ9KÕa¥Ô²R4+¶- –¦¢­œÿ³"׸äJQLödC(–ÜÒ 3šàºg%çš g:W–Wã)PL)ÏÎi‘»]ÇËØUçÝ^9tTæ Ø†­ÕPé¼~„ÛL©¢4+›Á%اœ¬Ô)rßíêjŽN%Nþd†¬¤ÌôéJ»£b'=ao`iÆÿÆ#S¨¼òöôêé÷¾î†¯¬°9œç¨ “ÿ¨E5>ºÛ:>ºsбøh¶}¿PÚ,B4ãY@ì2eogM¬rv()-X™Ñt“ÚžþpÖD@šíÎÑ ÁöÉëOóXJ&Ü-ã$Ì$€·¡‹R˜nèÿÑuÁº­/BÛ,—J|ç¸;wQ ¼A|ŠhÄ)¶]‹&ÖÀ%k Ñí%ÌŽ©QÔW*ß™eËle ƒ.ð êv@òW™ÛòÍCמlJ<rúö)Ú ¤K)Îç— à6éR~%Vù4µ{´Òõͪ¢ÁÜ@¨°Ï)g$T¯òa¤Å²tÖˆyÔñŒõÚÖâF`EZ ¦Y?œ§ò>ÉCºÆïõ†¶ø§æýý}_i.³˜ÌÀáÈõ™8 Fªü8Cu9ZlÈgžÏÑaÙ—x ®˜`E„ìNau íA…@,À\®L.„¦¢¬ÌquVl•C6‚@… ¨¡dn:÷2X4¹£->Œv‡_A„‹ÖE¸/VîîA§O§}XÖ^9j/,c«»“GÉWA° ‚׿ ŒGTd6%.þ;¨p'PzæÎ%)>Aè[Ç„¡Ôf×MuÒE¥½×•¹Þß8Mo£0oM®àˆ0aö[ew´¸dn+?‰ JÌ9rSuŽTÊS9‘,#À‘|}þúù›ú¿<Äø"j)»åÉ嶆‡Ž­­•§â¼}Æ„å‰ÅW÷ë\2ºN1²ÝãÇ´åȽ‘–,æ°Í÷îÓe<¡˜No²¤ço<´9±Jc‰IRæãEµbCµj¬ç¨ž5Ì$º]~³•·ˆ÷‚Ï!Q#³pkyƒv§>Ž6‘¶ ÉWj ¸¹-.–æÛá¯sqz ‘ª¥Fú‰±Q‹\­£ÐÍ>'…J»k¸xæÏàô/“ 5Q ª¨|T·e‘@´œFyú9«Ò­úÎvstè2ÎSLÆ ´K›lÓ°q‰“[+ò  ö´µ•[*K—Át9QºEäbg´ÞÍßÈE¡×=v;z]ãîWŠV…ñ’i,u-ÇßÜgç“Ï@h˜nI'OmnÉvßñîho;ULÄûÔð†´æßýÁ3>¬žäĶºj^U`ÃQ¯vè¨WÓ(#Wj=}8ë¶wàý ¨¬çso•‘†›ìx*ã/Ê+H?æÑ§(q Kë:ù®t)5ä3NÉWŠ-TÈ-!œ•XìuZÛ¤yòéÊ’0,¢,ØRJT•ý3÷6œæé¢9V9²J´-]Ìέ´³ÿR)8ªëhßík¥B9âá…/´Éµn´ Av›~ÞRO›ô¶u#Ê´°¹ šl(aÀ²Ec òåæ3Òm3ç÷Ú´%£c/È&Œ½¿ê‚:¥BîvL…öRñNYFnÇ:ùE¡W£b9uœ9%÷‡(—ÊØ,S}ý4œnIÇDŸéƒZR"¡™˜â%7<óèsXÿz8êªt½à)G›ð=ÉÅÖÊÎ’\Œ-žpNuxä/ǃc—£Ñ9îlÂJ iXyX•Ã\ùÇ"ÚpD›ÆXÕ “,…S2Š—[þXôz;qÿVmàÑ™è-Ã󸂗'gÀˆ'ÙÝ€½Á¨4UÜÀøO²Åü‚3ã„Ö(ì Ïáⲋ Oó£iÍ<\Çiˆvá‚k¨Pʈùˆ‘°‚÷Û¿SäI—"O.ÄßG2q°ÒB• %§ãAž_¥útä#¿÷нô"¹¼÷˵àúÞ6>Oá–ï;Ê»šóìPéNI â(wŽnOrQ“¨Ž)fU7ǧ“er¼Š$+qÛŽÎñ±ÓµÖT’ iª…f½p°@i¯nJÐÖU‰Y©†{ w;Í“4œoI–jÚu=HÇrÄrwœâ;Çí ×WÒäã™ñ"¡[¯'¥£ÑŠê…æÛb$U»Ö=»àýΖ$j–¢KÖ˜ ŽÑ —ƒ{?ã[@êaµ` [Œ‡NãP ÀMŽuì^"æŠ3“´rÊÔJÝ$,æÁSÚ4h'N ¡Fì2BOåÑòÑVÞ“7˜­µ¿ŸarÒ-ë¤5,‡N°l©¥x;ߎJ3¬^oˆÓ,ÈVâ ó¹£-¢Ü¨`8­×àÄr]/‡Å ‡]uI?Ké#R23 Ë–¡šD»1å\ÝëNS„R¥¨(©7Ò­f§uT¯kÀ‰³Ö "„}åå=î9¡–^•«ŒkåüéQRî&f[ÌzܤArÚàcÜ`ñ”ՖêkHí2Tr1ÃëGù¶4IºƒÀäèñÀ.Dç$òŸX@;î+Œ©Ë@Ý-ÞgVü>ŸiŽ*"–‹Ñ99Ãb£“²ÒXÕ/'7qu%.¹Î±#/oƒüsG÷Õ¤Õjß2 çäÿ .w  mX>¦áêt:‹¶ð¦yËgˆC#ßKîåU5Ϸ‰ÅÎG”ñ\] 夞…7±8DQˆì/Y]6f©v¿ƒýLu ÚÇûÛÈÀ}ôqË*˜ö/-ƒJÓM2‹`&ÕØ‘š¶ ”iCÀ$rrÓ‚ —W«g¸iË`RKOñ•„…2úBsšVçI[ë³epN2´ÕdMë:ÞR e<#µc–N>o‰Cá¦-ŸÖNÉ8U)È]‘ÂQ-ïBæ«ÙÄà–3Š¿©Fðë"ð•ýà¿fl‹~p’ Vì3?%³¿½åõÌG=1ò-ǔڶ]¼ý7Ñt™‘JÞ:^n€—Іr^:2”QiI†â4¬Æ®¥D‡*š¢œ=Ô’RhG]—U¶»Ñýѵ —­eQú%ˆÇÄÊDyoU’ãÉ6KäûÚoé)èDß„Oèbõí2®ö‘’¶/Ḡ•‘¦ÚIx;ƦîåèÌç-åú ÅÞ>¦96›qZ‰I/IîŒS´C—AÕ]¶%}ìx–EyrììkµoÃ.Ê•Ø{wñr#éjÒ¢xVÍøêÖm$ÞNë®ÇÌ}¼…“F{ýzÞžòÃïlá„ìô°ýl\×^Üî>_ú kSYsps OîPŽòŽÜË6ßKÙãÜÔ¥`k@5Å=֌Ú±-~Å'ÛüÉžùä9ç‚õË ˜ ƒÜe:¿ûçþ÷ôÍë«‹ó'ï®Î_¿hÍ'—oÀZ¶ûýßµùßúÏãöàw^»×?êõè×é ŽÚ¿óÚ¿Å`²Œ @¹Ÿ_ó…~µ¯Oî¿É?»H,´4ñµïªþÕj:Õ9¹‘ö}?l›…BÅc5Tšå»I„øßY~`¿¸O‘šuª5N™² 1_ŽæQá½G¹V‹²»‹Â9²”ˆ4R4‰Š±&“ØŠ<çR¹‹$  R<`ÐIº /ÈoÙÆš+!ÉÓ{^¶i:zôý u5 òŠÌ[SjžXŸ4O\sïm–"—P«é'83â<á£/îæ±O ÀÖ4Ê®`½a+ø¤ïû5xÕÇXU²ŠTšMãÑZÐXc BÖR<f²VÓµ*¾pî(• 'ý‡ƒ&pJÇ*佸¨ÖH‚"Oïð"a@uxDüÒAà&v[ÄUÅÐ<õ-Dff¦á¤eß.ZýPùTzcjr=yÎØ^žý3[ëY«©?éó!HY*žt¾B˜g§Ï^}ØãŸÀ–h$ønAWû)Õ)µV;¥Ì1ú½à¶?ýþôõ‹³—o^|ØÓ¿â"|óK¶^0÷MË£yÂõÓô?0UÓJT8ª­¦§½CÏ#ZFh%31=e´‹éèPý À}šÎ‘j1¸¹½¬ˆ3nAtÍ× çÀ(èS>´‰ç^³9Ó¬šg[ôÖ£¿â¯á×GÛ{ò°,¤ý§ðS€;ˆ'è_àE; ÔÒtXcÊ™¡I á†YmÊ5EÝP˃B—nÆ ÝÏlr‚´ Õj  8Š…;Þ.ó™éºXbž 6û"F}Ųÿ[¼¼’°8•”t';-’³Î–ï&¨å=1ç8žËºý:ÜÜ¢‡½ô·Æ;€ÝP°j1<™ ´Ì—Ï{…÷r³1ê>yïM‚•¾;!jÌkP¯ú]ȱU%(²üñ‹òæ~Å!sã{"Dꀉ”µ7!zº](5½¸öÎÃÛà5o¬P—SÝ;ïIM­&Ïéjo½Ÿ\ÞjVÆÂ^²œx8sÅjqéãªà¾’…ö&Eõ€¢Vd"qÊûÚér‚¶"/)d^{јÓR­/0퀢h%Nçh§“¤ ìÈ}‘è¯qÈ‹J%Þ3Ø\÷m6Èu ž23—x„6îU³Q(«´Ð¬¡ã£86òÓÍ Úž„®âˆ¾$¡„^e€¼óæÓó–w†¸³ %‚àÂ«Ó Noƒqê}„ ¸*+é7Í’©•Ê5FAehzª«ñ$ĨˆJ@c˜)"íx¥ÙL] ;B‚ôɶ:“J¯@þX‹ ˜¸ˆ‘¸V1òdÀÅ#c¨©7O±ú7zYа¨8ÊJaMÅä-ïû@Ê+aÁÛß ´WË-îE­ö–0â-i,Ž{4¦N°¸q^ c‹Å‘Â퉕³wÔÖ—‘Žá.Vø+üûɘÈÿÐØ[—ÿ{οäÿßâß„ö¿Åäýz¢OÃÞ4œ½ºAšMn«ï×~÷¯ÿsþ½çßËÿðýïtíµûß=ìýëþÿÿ³—6M.Ìþ s“ DnˆÿÞ¿)YÒk˜šûæß´ä×ZMRBÔ»„(dŠ$2ͦõZ E•A«'¦¨cÃ’Š`’Ö<ÊúYg±3««¿Qô40õ†Wÿÿþ€éÚõ²L#[CN—A6©—þjfÑú3]=]Ù¯éeÑO€ÏæAvÛŒ¹1œŒƒleÈÖfi§;Õ³9ÔƒÀ¨ËÛ¥µãÛ&Ž`žøüb¯ÕÖÏÙgäc•ßE—8\5qøòã~¬? l{‚T ¼IÔèeL³hêÿ´ÿÔø¿…vã þïtúí þo0ø—ýç7ù‡yhàZ³ª~èµàwÄ&ù~ñX—ïíÁ½>iuöé‘'©ÉEu,ÏHùfò׌Ódïýá;¯‹(A½i¹äbæ†ï–Û06Q:Ó„ÒæÕðä“zR”‹'r¤'JJi  ø|`->GÉM*cÉSQ’»Î^k6ªÞlª¾Î—7(²âK] k0„}¯´EBqõ Þ† †ÈÀ¼5½ò)ïë5>Eé\÷Ȇ¯ÆEq>¤¤.ù5æ ¿ 3™=l¤^“qx &—[:\\wþëÎKk¦DùÕ¹S‰#XGj²r:½½† ó³q`™½ŽÙ=~Ô\ÄË)æí… œ˜ýƒø-¿&ÁB~KaÒ—}éÉ )|)XáÀzúÜK;%ÇîáEѯÆ)ÆÒÁ‹ ðõ†Cê ÅGà{æiv‹ºæËzX]FfZîíõÍ€fø—Ÿš¥¢(­VÅø Þ\õì&È‚I°’Ç'k›x#›ã`<Û€UcôH=¸Í‚ù$½O¤ã@=OÇ, wî`§`"³fÁ—È Å Ñ++/ž9ËÜÌ“ob¶¤dÍå]—e¦{)¯T„ÒÕØáüO¢››f<Î鬨Ù'F•Œe¼ŽôÕ‹Úk½›š‹¯6!­nÃûw¯Wz¯´+ÂúnË[7´@Cd>ì{LÒŒ—V€¥µP¸ÍcÇCiÚN^ˆ¥'Lg ZÉ®Yî8’“;°^ŒI)ý‘hNùH&ar·~¾“´€Aƒ—\m§³•¾8}*óYǽmü{¬FgQeLe!xÛK $à}>2÷Y–‚¨B§ôPc“ <­ÄÉ Rk1J²CЮú’¡Éª+Í®+ÏÃТ~Ș>qTïâ@”AÌÜyYŸCµ}½–…²Qó&ç|¦‚kä˜}‡>mØj£Ï‘5…Õõ$\”‘›}(ˆ¦Ø,½ñL¤+‡Ò]‹  -ǺEK]»á ÔcJuJ†³Ýî Ö_“vj„Û2èvTÅY ð«§Ö…åë–Ÿ/f]ºuäÐ5HÍphø†uUŠ4Õ^¯wmjî²oc 3Òw6“D—iªú›®ZÛ ëž•8ª;Y}É4€ChÈDܯ4]>N ùS¹R ¶‘c$Åi‰1²v1ÆN³ ‹ô>Ìtb,ˆ -Zî²)<ßLkµÊ'I@4ÓŒå¦Ðʼa×f¡»†ó°¸gÞ£Á·]z™õ käL>x¤zœ{[%£ô¾Ä—’§É^Ç:qöeÆÛy¬ëû[º´D‚dãÔJ9ƒ÷E¯ »žÍQÓ3@Y(«¹ÑÆÙ,ÄßKŸ9yp¯5ÚCãã~ù-fT½Uþh鋆`Îh»»Ò‡xõqu£Ý¢È)‹Ê«›DÄ‘y‡x«ƒ¹Bå®OÁ tkýMÒa-²tŠRÔ(Èäré³L"¼vÍI”/â`u}MŠÙ†8×Ñà—bëÒ<$´½ÁIZŒ&£JkYÖ€ì˜ûmèPÇ,¤ÂV%o–ˆWf ¿ ã %±„-‹[_ë"rÑŠX*ÄlTííËÓ«ço.^]Öø4ÔjÏÎÞž½~vöúéù>ÔR~mM<®Ù’¾–kÂrÿ¾¶Î{³Ja ®®Vâ0kk|`Mq=µ2GÃZdÄЋšEjZá QsM#dëå Ùȳõ ¨ôÑØŒËV«=y÷úÙ˳gÞç¤óòˆc<ü¿[5ý7îïl|Èþß?<\×ÿv»ÿÒÿþÿXHÒ%£Pÿë4¹Æ%)†^‘-Æ7žO†Ê' dobÖ=F íý¯ì§ÿCN¶­o¯ñç¶²Ñÿóó~©=ŽF{­o÷¥ðÝOÞßæóÑ«š¿ï|ø™Þ‡.¼Ÿõëuê€ÿ¹æ¨Uh¯ïãëuåg1¯ÉdAX`ô݃L{¶¾=Øÿ#4ñ+ÿÙZÍcŽ{Ž–‘I”¡ŸåÞü}ûþ|éÎýyþôìõåÙ?Òþßmu×íÿ½Þà_÷ÿ·‰ÿY¬2rpßï{ö†ÅƒÞ«˜Ò0öžP9 £¯ã$ ðÛ¸Üò{9eÉ‹rÝÞF+d0‡|ÃÃ8qŠ šÙÐÆÍ‰YŽ0ØHrÕŠ8áPN&Oo $ÇÀƒœ¼½bÖ]Êöœ4’œÈÇO5iuà‚aT Ñò뮩æ8šGòª¨…ë’KÚ“ÁÙÀxy.ìSØ`:Ÿ5jÀJJ2­+”&øÌãC÷C,B–.0‡ƒ„­*è옘Ö0 úXÒÑwïgé¼<ôÎÀˆa`É'⡘§ôEŠQØYål§ 'x@grLKÞ”4Þv”–Ç¡øFÂè ³«Ò”ÏÐïcÖ$• %l¬édTÃ)Rd;;:W'æêû3ïòÍó«O/μóKïíÅ›ΟGöèôþ~Ô ÖìÍ»+z\œ¾¾ú«÷æ¹wúú¯Þœ¿~Ö¨ýåíÅÙå¥÷æÂ;õöåùÙ38‹¯Ÿ¾|÷ìüõ ï ¼÷úÍ•÷òüÕù zõÆÃÊPÀÃ`µWgèw|uúäüåùÕ_Þóó«×8&ðÑÞ©÷öôâêüé»—§ÞÛwoß\žÁçŸÕ^¿y}þúù|åìÕÙë«|>åýx—ߟ¾|IŸ:}Ð_|Oß¼ýëÅù‹ï¯¼ïß¼|vŸœÕ^žŸ>yyÆŸ‚I=}yzþªá=;}uúâŒÞz£\xØM ûñû3zß;…ÿ=Å5X Û„?0Ë‹+ýêç—g ïôâüäùÅ—ÞxCƒÀ{¯Ïx\j¯´#Ðÿ~wyf`yvvúƺėíέytüø§ClþQô¿;8êuzþÝùÿþ&ÿ~Ï•¹1–'ý°Çñ—‹dº_«½ÿýûáÜûMøÃ(˜LáU+J²‘mæwÓ}ÖZÝgÇ|B1—”ØÖ ZpÁ8"‡‹ˆPüîð‡¦ìïú*}ó™©ç¾þái8O‚òJknLè(Á67¶ày”åEó)‘ò1K¯g}CMT_Š4ç¥)¿RÙŽ$á±~K¥AjÜPzËÚ&@=¯9«r ^k“Ò›&çïnV&¯Eùå‰z¼ù%ÁðÞp-èJ~ñM)Ü(}ž¨À&ey¬Ê«ó“ê1_«Š_8~ºjÄÇON@é˲ñßµ¾FÕ—ÖÖ£âÕÑìb…•_ÂA^IMÔOâhª`*]8ƹÆ+üô‚Ò¶"£_¤'¥—¦žô›\Øbæ™&DXÍr»ºz¥0þÒ5.éeè­§œ©ÁçßÌÆÌ¥D@PЇŒ+4‘Õaè%=.£™Ìü%­¦,” Y«RT“Q.¾#ªóo£C@ø”QßÔïbì›&Á›>å\s‡+bVÌGÒ}òŽ77gǤ@%aëc…”Ç*'[þ$˜4,žê ½4,MÕß&Y^¯õI‘­fï ó2Nùݘãey{.I›iIQ“}àÔã¼…²Ì©úæâ’öRÅS+K(=7êo©¼—ìGìÊ ¡T†5B>âdŒ4ˆJ±Ç¼ ÉîxŠ±ãˆ›éu¥pržJ­ŠSQ¿S WÿøJ§Šƒ~Tƒ£)ØÏ$‘+ízéÞ÷ž|=J=ù–löäTEçoéäáïÍhAPª¤Wœpêñ=ÿMkuÂJ}8*^XÞRoâe›\ù3¡•/¾ô²XŽhÿ úÎåQ …ƒ`Ɇªò þö™ Ž£)K7<⎒#•µbèôJ©aÊ©zjåT-ï³™Õ¡zܦ/ƒ»V °qˆR0Ýû+`Á uЦ®¦j(ßfa1)SV¢nr§…ÏÄ»cwÐ’rM–ã‚¥õ´¹§kn¤Yô©žcâ*#Ù½dbpþMƽ=½+¿³ Y–­dm‡¸¶IÙmðhÁ‡’‡`Ö¡–G©g€°Êv þLyƒk”~Z'0¢'”ä:Ùùt-ÉËË—ã&qàE¡µÑª†?'ý¼<ÂqU%@©%‡ÎS$ô"ˆè&ì)P宪qvì9¬<;Ð#χ¶GçúCæ’IЉ¸ jÉ0Tšæ%á4-¢€­EVöbœÏgˆ¹!(1…W–Ãk5Éa‡îGU»ž¡¦Ü¥ü¢Ê+ |8í[Ã㘫–ÊA…¬ß¿{ûââöô¯œ=…ª{.àøp|®ö¥ð ë†>€ª—ðqù1å‘Ò\ îïï[FùŠ¡}èü:Ä2>€fþèaН_˜àIãû¤kÙE÷‚¼N.oI¥v®î×^.ø|ÞÑG“¯Š­ç°/ÊWÚŽoÍÓ{QŽ|Ž ë„ë¿qû0KB=áùnáx*}¥þÁ]áÜoYƒ² ÉÛ„ $Ó Ä!ÁuNÛæ—¼ù¼‹–.FM^Ãç6S]Sºlâ„xTã.‰“v&Æââê *É¢0­ ™ót*ÞuujEuj²HÒúTàsàØU•<…µ¡P¶§ÁùpÈ¥õ.ª±æI‰eDdÿî¨ÙiOT)õ»N½Á‹>ô†,5$­ûЫËñ¨[¡(\šYü¯ # ò†¨Ú<äNÂ.}7žpGט]K{ÞŸì§ÞßþöìCäà€&|¿&wÚ×=VÌ€›GþwÒ e‰ßïÕûíŽ÷.ÑM`zð³šÅ VAƒÃ—>£T}Þ¥’°4£|ìÕ/T9Iv‹©gP«Üª«ˆŽJ\ÈU£Äy¨Efô½n»r¦å‘©;ˆ·|j§¬òCÕ‹e¯BKMÒ~Eƒ … ­ÏJ\{î £I3R…CO´M  —È„ÑD£vÂó¬"ç8„=4Î×úS¯åM”Lö’÷ðʇ}s4ô°3Ò)3fÄ]Õ¬.©B¤že“ZÌ|ŸÂAÜ™# ßïýdÍ7lXÚ¾†ÕŠxcè©5`(>èöŸ·î«¤ûÊ}][ÙÖógz˜_kñ–…W‡ïÖ¿ö|oœÖ’&þ¬ð³3@þÝVØ,Ò„?ô+¯Ó™¾tU0ù¿øI­æ)ãç '¶Ør§É™:òÙ&Ž{3¦œ®!ñÖ¡¡|´\x>'mVË'ߦáVh¨!¾*¤É眣ô`˜oÍ*•Wöbe ð*/ή¼ ojqÖú–^%|¼¥,-µ`AÊr?~·í…gg/Ï®Î*…»áÜlX¿v˜wÜuN§¨§Œ…Žˆ;WÅV(;"¼`²—1pë­l8â’dðÛíSŠ­Óyg±$ÖFwO„§®”‹.dÉj^N­j¿Z§ª˜IHr Õ4®¡gUÁŒœT^¾ÑÑCi ªîʲŒgN<*¼³k_ÀJKò‰WAì# %¾«€ÇÔs5ûTJ1]\Ef¶¦-ëx®¯Åph>v: h°Ÿj[Ž6mÆnæ>³3fWLXaCµ!ŽUÆÈÂJd•O4tfò°S¢)­hÍÇwaA>ÖÒ¾Ÿ½3á”õÚÁÌùa Y»nž(>+SË|P×XὟ<ú0&ÀOêä'­Ð• b $SŸ LÊcÕ4­OÃÒ(„sõ ¸<ÅË\qÏP—O›Tš|+ ïIéÛÀ~0›&—åmŒR;Ï&•÷3â=÷[¢!àH6’7@2'•šIRGªK!‰¢)á­ˆ ”.Y¤r¥/p—/¾HKÔÆÍCÂ,’Mƒñ¥!NÇÆ‚d ¢~ö)õíâÌ2-%âï­l„Û+ò¥Š$`‹urä¼P½ ˆä|þ1’=L7…–`¸ú~Ãü¾C»ù›o°õrŠWã ŽDÚ5—åûö;ïY”±B´•¥i±92Qß—TðòhŒmpùnÙ+á}÷<]B‘tY±xEEÅqu•x–ÞpjKÞ{@UýVû[ñ@ KT“¤Ržˆñ…ôì^¬Ø‘ÄÆ5ªµQ3eåør´?ŒÍ…ɵ®|‹uo«« ¿ >Eó&,s‚mzwð…1ö[ÞÕŒJèαžÕ†cíN¼Pé„ß7žLG2½¶ªÙ³­gf•\¤<¤³f¢DjÀáð.L–1ª"·-‰n¡FZ…/LAöí2„Õ¡ø¿«VXW_ÔUä&rÿ„BC;elÔÐÖHByÅã‚Th„ù¤i)e¤h7`â6fOAŽ„ )Ý*žw”|Ö0€5$£‡ÊxßÀD΀,0§+é9S,ÄY..TVI0Ž-ý5¬½y;î:Õ»†ËT&‡»R¦g¼Áªàzȃ<ŸoÒݰÆÂWËÀ§i‰nø¼ZEÆ7¿~¾ßwz‰/6®0Ä” E(C¾“D,'=x§¥`WÑââ<3ªÖC˜>PÏu §|èùCœµß¨ù¢¾ñðŒ=c®e箥…0¾÷Á§×èB@XáºÉrÌÐzlV¤Zq„ýy¢lª"ÿxK¬Foèi -À,É‚¶ò(3ÕT\»‹—¢ìô{¢*E’Ï@–žtOº°ÒÛÙsš›ÿšÄvíÍLL€ˆ¥™Q¢*΢[׳ŔÏd@åHN™†‘.X‰&éêï’I‹¿F¦@ø¡TOÍ»N·×ÿ–{ó÷IÉ)Q¥šÞ†pŸU9'&ɈUü¦¯ „ÿ­Ïh~„¬*LÎ?žõ ·©LëWß52ùûìµåSiC{›ßKÑáEÀp-dÁaòßRªêíÞ¾×OVê<+&%Ë S®KC™#•˜°) IËböʹ ¹2uJX‰½m™ƒÞ©7޲ñrNùhAÕ Sc4jX'fL ©È®?d£Šï±gÔË¡÷ù }9äÜm·<ðü~û«·Óˆø¬Eiˆ+æYó±¨b¾º|=ýÀÞî%Ì/õþ2 ž ƒ06þp,¢@ms^”ðÒþœ†ï{º}ÕÈÀÛ’€_€9ZjMØZ-¨V8>„*ñèßÓÙwF©Ö|íö<*÷ÞuýÆWeÀÿ›¯ŒÁ¶úl{[ÏvíW:Û^ùl“ÿÙÃD;ýªg—¬ª0‚vukÔÂˆË h"Ž¥¾2¬£Cn¦€]˜õaB¿í8ÿ¸né;`k6SCò©²3H\ç:¿GJ”ʽ¢Ü×e® ÒÂ2ákú¸í´Ú ó=à'î„“øÚYÞÑ‘—Üte¶˜b*óÃ^M| áü!ç*}t^µ{gnMÄ6òäªòÅš}‹U"“°À*9u2hò”ÊY$-üÜp¨¼Í†C1h”ìú˜*t —Š•9voú uÍ70,Š‚ïß÷Ûº×Ìzuë¼9õ¨‰Ç™M¼ú«•üF×aÏOï/è7v…ìÓгÿž½f°[?ñ„tÔ´ÑDe.½"ê© §°š~¶ûý…ýwƒ˜‰Î—¿‹Aj] "§ºå“œ3ÚúfŽí¶Ç «£–O¾Áì¸þÐ;e;u˜ÌÐ+hbƒ‡ýDÂ!¼Á‘­Ê®¬ýÀYgŸx>ï%–›ñe·áÅ=dkáòŠî“¢z²ðÉD~_FD„êRÖbÿ âU:#Ö¨x©®Q¶Î÷a*¦®Sihu´ˆê¢Wj.N}|¢pd:>´RÿÀ™¢;T (80µ¨Ðb‚^Rš¤&Are–ïƒ|†ãËy¤/lRÜ–ÙE/s­v±ŽqÙ™Áxe3qÊ…sÔ†Qê@©›,4Zb@â{qv…r#š"üI‰oß]ùÖ¬æbx:ß. TÀ0ò\)½¸,c}ÓXöíÚÔK†ŽEºEt× * xªž™*’ 7Xpj’| §QNêÜ@bɯ‹~%Ç8)óE±òüïI<¾‚Ÿ>û£ñ¾|ó ïo¾á¹Œð]ù ›‚QÂ+ao <òÖ¯ˆ5oÁBø°ÐOH²»FtýhÈî~ÔðÅná?¸åçŸë²-ÚŒóPK«ìË£µUÅoý\û¹&o¾AOã{.ik,a^Â2N¹š)É:rå>9–úðñgZÛO€åJaœ(ÈCÜ(pS”IÏô0ëSv·Xë¦×j£—6þªgð¿ÃA– PT:ÇÇ Ö%·ÇäëO-ºIxÛd^ 4Õc €5f‹ñÿ? @L¨D¾&–ˆ¼7·ÜØu“F›Ö™¾‹@ÜJ)? ­¼E‘¼=n‘Ããwßm4¼§ƒS«"é?6h†…7„•p¦áôRÏg_áàëw±~7âØKä3´È¢4«!W­…`Í'C…¯BrëÖR¢­02ØOÁîNrŠÜ‡™6Ùp6F Rö|JHÀ‘¸9.](ñ8z ã…€_à¹æO]›OiÝŒ­”Ù†Rôk$ÎëêHe§-ƒ"¬U" ‘NyĺÝ]{¬ûƒ™Ádz(žlCSÊ#‹ü¬®– ˜9ë⥳¹8UXI…T¬¥H ûòп¸(Lëa®v6{G¢ÇÕW Hçà&MFA¶Ûºœ¡™AüÃ"f"Á£ê3¯ZM„üÒT°ÞÖA¦³/´DŸõ5&ÎO¢ØçŠ›_¾²Uì¤b÷hs[µ:WÔ¨umMõf¯uï—ØÈ¡#ïðÎ …Îv¾à×àÌ‘ùª÷ÏË)ìΰ*a}‚4¿¿«PÁ < (PàRJÝåÁ$kvÕK$,*VãØßËÂ)Åm¡p¿«ý?æbAƒ,>¾4–û\>‡;÷¿tš?·€ÔÌ‚ l‰Ôÿ]oé/“-ðÞî6©ÿw™EãÙ#Ã=â³m.ÿ¶ ¿N ñ CkŽò;Í«M„•40ŠèâY•o¸¶v¡§F¶Í/RR拇ÿÄB(íÓ³¿Ëù)C_q(l À¶´-ÆÈ—åñÈ\%í ÂÍIéÍv>í±Ù3XWòYjÖJ’³çUâ’P¿¼Í÷!ü´zÿyú>h~þðí~> túTù•½¨6轚¢fø`9‰Ò "G¤Rw5¥pj˜zï‡óE¯á ïƒ;øoŒá¿étú¡¡øÍ¡‡=ôçæËb‰æ…ëð¡MA eC Ò±¥ôسiHÕèÒêgv¹!0éj4ºáÌñ6EEÉ}Wö—rGˆ>YvcÃŒ™ XRK50=JŒN 6UY&í€'ˆþ@Ë ´f[΀Ùªe·´$‹YÁõÒ LÔ®ÊwW'(o6ÿ7ä‚ú¶ð•½N«Õi·÷鎘ђ4¹ÞqĪÑÌ~ \š®éXmÌlœ±ÙÚ!uÁôV¶H£cÄ&,(ú>Xåd”DWŸÒWøn T†PF€pò«l…u°þ2šÔ§Y&uË2rE‡‹`ÊÎÄt Ôi+¹ž3q¢5ÊIácá¡_py°u(oÍ‘V[Û2%*€Ù…³a™»Ð¸!›Qú Í!ì ŒF!u©¿ñžÇiPÀÏ'Ñôìþ<ˆ1ÀrC¿= Èr?®¢9þ*?ž¤ihc¾÷AYð G’h«ÜpøŽ¬\á„2§í¸Aîùø‡Qÿh¼T €í)Þj*eœè€â™èÌÓô”÷{GSŠ%é¶ú4Rdqk©Ä[hHS=Ô&1{‰0`ñøf²!‘²PÐÊÂAÒ—CQ²18Û×ùþ›“æ‰=LžxôüËRQ„¥Õ —–è˜;8,:ÕmEà{=øúõC‹ÜÆYPiµZ5û=Õi>´¼zÀIAL‘Oâô3YFi‘ý³Ö…:¨Å1g}{J¾Z피޵M\û~‡t¬Í9gße* 8á¸Í!8v‡gG©y(‘`2ÉA §P–!LFmÏù.áû5\pDNÞcÈñ!ÀÊÊùšN*à%ã?"Zøˆ|‹äyÆ"ÝëiMɃ–ǘî”Î_G?1Ú«!x ôYÄg!ÏN¥£¤Šªe—jB}÷A®Üg[ÞYkÚj¬‡yKÙ§[ b’³Êð!¯oLí *GϽK^¤œ`…€ôq¶þƒÈIûýFtºµ CLºö[ èÞ8NÉìgYTÓåäºê¤”jþËmü$ÛÍç{ÜÂB¦è­,`iPXzů FN=XÿÖY†Ó, VïyN6aÅChàG+‡ƒRìügþíÁ¾ò–ÀÙý^é)pŽI4^ŸW!±°åÇV:fJóÑ$²/GN©J˜Rü¥Iü7ˆµ÷QÛH”^ ¬™J×dð!­Âp®i§ö'•=/•´~ðw==Ì”×[ ²ó‚·æÁbï‹ô:²”v·-¯¬r„ÁÀò\¯0óV¢èð뛉³è„´5ò(2âR ØK¸DkòÓÈò\à<]bц-Qp¾øË–ìØ¥Ñ£áfctó[hße±ikÙâq[8rP|L¡jòt‘Lë] ýá?îÊÎZÕ=Ãù‚–†z>þw„úåÙ–´W틦â$jŸìEe„ß“ü˜Èžˆs¡å­M2FBñêÑwj¼NÌh€‘4óHBrÆÒOQ Ì ß bƒH=h'E3o„šZ†q˜¬÷b^–r%ÈH‘vC„õàÖ£ Jm|5º"&uM°ÕòP§áu^ïÃ׺Ʋâg>´$Ùe‰¢³ï ÞÚƒ·ö¢Ž¾ûhØù¹¾Ï;üè'„ä»?t~~´í÷òңΣŸ?è÷Þë?äJû–"-âеÇìZ@NyBÄTÎbþÌ 1^;ÿ›tè6\­=QÚ QY˜Û½à!g…mN¹›yÈ{UÅj5Òç¡Î˹nþBÆÎ&š½Cç&8D*_F)z8Ò«ô­¾-{«rþTàÅåÈÁøvJ2) 9˜”8O‡mV¿¹®²Ä1÷¬;l.ñ(J*_,­ªÜme»à;¾¦óGqÜþ‘¹Æ³p|‹±´B>¡UA 1¥ÛX{Á<>bö‚D4Àão³t,8Fkn&aˣ̫ á;›ŽS«FFAG‚5ƺ¦ÙŠú‡ïù7iê?¸ÊêE½¬êÁš¼Š^¾u±¼ÔÆzÛAuk«L‡·T÷£„±•iI07á,R¦êVØL•ôÂOXT½¨IþYÛX•‰Æ÷†Êo+W²²ÊIm:¥¼Q{;„êQÔ¼rð ùX8Ÿ&å­@þ ³»Í7É2ß{ Ó!>×6÷ziÎÓ¶û8œý¾b -NP[†yhhô–VáÚ¨SçÄéCmmÁZŸ_ˆp½í€ïÙ9¬r‘·.sõRnYÌÍ«º Õm¨á±çÓ‚^Âñ«¸åw޶1»oƒ­–Ìí³ÅkE¢L€ÄPŒÝeÇSÍÔ›Èí •s«EPùO[q§E² iÞ£"W_!ĆN\Ñ€ÙáX"E°3ä, ñW@` '"dkœ{¢j!àŽh%ŽRJ™¹…ÇÑf™±SÈ´Ò+f—GôÎ+VÓ+/F˜_Õà?Þæ‘+PDUÈѲë D†?bRF‚ÅYóEÔcÖˆr SD±ìia"¯Xt@ëcÖ qÎHýzøXnîE ýÛ—£¢«Í‚Àå=ª<*“¾¨Œ”¯ÀXÙã´ÏA!Ø@4§V ‚ge÷ ÷€pÃäuØGË;%:íoúGHôšêªr¡"6ªq" ¤sÖ!f$O×¢^¼•³meT_©ÅÁgLIó¢¡Uðã’tѬܤæ×&ž£µ› ¶ÝñŽÌ5Eœá®6ŘÂŒCt¬ùPv+a‹õ6…µ¶ku6Õp oÐðŽ-oä>㋨ævSKº¾¹âW‘“|é:bZÏ2ÓºïÙE§é-þÀžuø—*G÷GÿÁED®µXN4Õ#¿3ÇæI»Õnµ¾ÅkvdúÅ;Çü&ý,;Ó‡E±±ÔÚ£¨õV«þ¹^å°ó "·odê:Mš•×yÊÇ·Q2¹No€KåxÖ!‹n²ô{Â9qJ<­¶ãm²{6lUÞ`“¬(øC)›+†A õEÐñ« ®Ôò.×3GÚŠ<|ؽúu¶,y=œ¼ÇðSÍ|zì£ aÅÉhݵZ8þ0£´Ù×Á§ä9´qªuÖ>ÛÔªÌWÄê7¬€µm˜¢EJH­\Ó€hJ$?$n ê‰L| c[Ti ä[S¹\Ø“‹*B…UtÄm;Ê¥WÁÔçÁ¼:òu~Qßôgûžû´¯*cV0-Ù²®”¼¢sWbµ‚Š1B;[jk$Ž’fÙP˜Z™ÂŒVžRœÁwÙ¹~i•þÕGnøU–lÓ8 ¢¼&ƒîánÂM¦ã?ÃbÜzçŒ2à ¨µúI¼-©zõ(Cmiydj¿‰”Ú€Å} oéy_tô=…lxP†Oo C̈) q|­•ô]¿iÈxÅsvÏ)%È Óö¡$Îö+IFº3›?ex}&˜ ")GåI+”"àô;ä§=G»#骽¦|˜òIª˜ᘂ+Ò»kðàóêT}O­¡Jšõb~ò+”. ÍÕÊæ¹D §¥‰T(>¬ÊƒÕº¥r¬â(ØÎø‚õYöÛ]*¢òº˜Æ ºÜEð‡¡¡Šsƒœ˜TËz]ŽW)U»$8S+AÚW±r´ùÁ,!`”*6'ô‹ÀQ¸G¥eP‰>bWƒ(_tµâõ¦µÌ]ÕÓD%u ò¦ÛfþÞèCQnjÁï¸VU(‚÷ZkCgíâÙøfæ×hÓ§w¦Fäó”·¯Ýt—­Ë*œv|ÛýŽ*V>1,ñÿøþA—~peǯ{è¿iuÇj^‹¹Ù¬aµÕâɃ«IèÀë/ö ÙêP?Cfd:ïë|rSäS&mÆ7Vä)hC­o8?·*-›èK¼¶æ9”mD\œÏvìÑœ-Ä…4;){¾ÏÓ7yUŽbŠ8Ø©!Öóh²a^“”UI[—žç.¯Ëѧ ·†ídóu÷h¼-Qˆ-âã4òßä­rñæBÁ‡-yÉÖ¿ÙmÞã;.¶@¾NØýÖLožÉ¨"Ìb”BCñ±k(lÐ~² ø¡¬‹78tÚ`ì.8ÄN!× :´Õî©ÒÆ1-•ÌøD3jB‰ðç î‘<&<Á{Ç…Ø2‘Ì>5°Ö»ôêOËAe#¨ Lðg¥–â^Ï交žRµp.·”|S¨dP3¡L% —À*Lð >Æ3SV,k?®ˆ¾ü;b}-òæ1íO@Æ}¼›Á =âX™¨­#))‚ Ĥ<«>âÆ‚'b¹Ù~dÆz²ÂÎÈWëgouÉ™g£ººˆVz2÷Å2’áòñ{cíº¥Ø+rQk ÄL6°fµÝVÛÊûÐu6Ñ]ÈÐi€s…9—Ê@¥ÏªŠÃ-ª²br^[±#‘>Ë€7(×ИTú­Ç.ÇÛšq††Œ_Ý3«©ØÓf‡•Œ7—\5Ó™*4ŒT†#ˆ‘$ÛÙƒŒB† F„ÁÎp´wQšq¶_ƒ±»Ó·)ŽZeFFðª¸n· —‰Ì¾ÈF*Îô!,yŹޠóPµîInÆT`̇“ѱÃ-´x¼k3Ûm{ßþ¤Œ•V¹RÆõMߥ©ÜšðH¢"„¥Êì´Pû½Ö¼ì%*6¹íÎŽ@:i¬FŠ ÜŸE¢qUœáÑr_‹cx;àút"¹Ù¶t©ž†\(:†š9îNA›) G6Ú!ÝÆ¢ÙsŒLà†‹2×tç ¨ …úm×m6£ dâ`f±*”Úd32l’¦ æÃ¥/®)÷*¢8ÈêÐPž¨k=G›Æk’Øn‹mômªº€[g±˜ÏcXOgƱ€ÀêÙô}ÂïN‚“7%L´Rª8Øn´¦þÊØqK ¾R ì6D@×ÏÒ*×{¨KI«¿)v 0=º [’ˆ >DE± †n’¨Nb‡e r.05µžËJm‘ëDªê[]Ó|€ ùºÛ™_h+ë¥L ʆ8æíE«£å²êiÚ —0ƒ¨ã`‡4âÀ$O¦ÒYB'M°¸øn_ÃÚH-#l¥x%¸ §‰í{Š\g¡³è’£§Û@zñÊÊ—$?¯ ›¦©!òÉ O|†@…K?b}âSïx}Ï…þYÛ€¯N5Ãà&4ŽÌü³T¸’…±$\àŸ€àŒ×cäÁT´Ñé¸á/ûŽ <"U1òû‚jÕhëéé®Ñ@«°þ5E@— Ññ¾6}|@BøLã‚ä`æfò²NxÕegNΘ—¾uLßèÓÇdÃýÂ;‘‘9ë/QJšêç< 7&Pãû'’Æ*y.•)ÒU*öwàøÓšù/©bUr6òÀˆé>ÉX1©ìveiJlÈSrñA]”Á㪧‡y_5ü“¸`¹¸ghÈØË½ þdü1²Z3Sõ—ðc1†nØ–…úƒ÷~DÆ_Þ©ü¨©NöÝ`³0â‹ÚtÖŠ™^84&&¹‹3^BÞþ`yÂ2V"…eoHzëŠU² BsÔ]lrë“ö™@V…×õGÝpÖÅØ')„r¶‚4ÛmÓDK”/Äœ" šŽÙ¦»€Ó¦È„ÙÕ¬aÔ„"¥äŒYLƾ᭭DÜ,XŠÎFS2ÍÅåè&GR¥ùÖITmŽÏÐó¤TkrCIˆý£a¿É 9mµ(s@;Ó©=í8}2|²"¦OÔðI:²€ž"JÍ6Y;*‹Žè¢#'kEG)(Á Ö0¹"«WåT‚Ù^•ªJ¯oƒ½“9××ä zbbÄpŒ„E§ß“ùöd ÉÉödV?™4²ÊAk5¯µ\c™Á‡Çþ<¦ë†mKŒ‡ãe)4žór´<œ“b˜R¾N‚¯E»D ¬XûŠƒÏI6iZYO3¢ãÓY€R©NîÞ9±{ªzx|ròòC»z´s…‘‹ÅÕÊ"NžKý2'=ï œBÓ¹ì#Î)L‚ω Sîä²Âd(߈ª°¦± Ke]Å|WdWsj ×̓DÅN„õ«Fö½‘kŸ4Í&'96‰|kU–\ ðxY+§IC\KI´…X1¤nå¬9'ç“=`DU(9Ù„·ìn³W¥[TEåýA­aÍýÚEQ{ììTµ¡_j;À™\qÉHÙ*û>“ëlj§Û: |@CÎpÊéÂ÷è?¡hÚ†Ðb½:•бÓÔÂx¡Ÿææ‰¡U0¨Ç^ˆ:åcžðîk¼ö ÷³¾kŸlužÌ貊ÝöNDÞ†MnËÎ[´,é¦ÇóÆô@h굜=ý2eï¨W}m!^T…ψäŒÉ:‚׋÷È{ØðíqÓL+™ÊòÒ˜2'"$dAôkVÀ=äQÒ¨ºmdäjnT§0ç5k}€¶(¿‚I‚=ÕNÄe¡@uV¦Ó‰E8óGÓª˜¦¬Þñƒª*“ÖDzýOóÅàq¯åÖªyæÚή\’µ÷5÷\ º ØÇjùtŸÕà…X®ßÇ^‹wb´kœŒ"€¨­K#Ï;ÖoÊ`dZ»âNV›€ÓªAêwů—8ïµ¼kD­í…HòÍ6£•G tÓ(b,ð,Ï B¢å¨R*Í v 3[\)ô–Bw¡”R<'Ú^,ÆRì2sšD½Ý†8]ƒó¶“Ÿƒ/¦Mâ]q~Ì"”§|MëywŒ«6ŠE»Œ/ö k½l—ÕL.Ši‹Å$Š­OXSöÉ“#"}5Å´±*‰J:èO$ôª£0¥ñ•ôcî‡û@þIaÄu6½#Û10çÄÛçĉíN¹Ws¶;Ãøþ¸c¾¨t+ÒdDp˜éýéR]‘>´jÍ©ZÕ_Šè°9 ³.0ÇѪXc°¥€ÔÛÐ~ñ|%]º¾óø°¡œGú¼ƒ@›Å5&ª ƒxÓ]pøÉÛ‚‹gŽM6$\³¥,¤?Noišáar‡i8»hª\žŠi.jÉžó,9VµŒ)¡T›Ñeí…>+ÉýWr §«.6vóòFÆŒÝÎHy)å,/°²D¢‘ò(½Øµ{ÿî©ÝúçVAx…7½*“¢“ãýH¹,‘ð‹üI æE0YSQ74wÓˆ=&Þ‡«Xºêçbl)c³òÇãfå†GÊ#°«…ØÌ¶o‡~eYÜψE¡ ó=Ù\„š¦-cLZe­œG¥ i¦v:m¿É[ì•••"ôUP§"H;LÁK¡(Jÿ•.…6’Òfj|êÒÉêÎC»vOÀwºíŠãÕcЕVPå•°Ü„»!¦Õ^FôlZÞŠ¹Á :ÝÀ7•GrÀ&‰«dÑm‘§¨x8l‚¨j ɺY[c•V"¯ëd ¹îk=˜oùWQ…ëÕì0½ñìhNT’H( “à#„Ù$€îª ogŠP\U­o¢­b+32 Sý¬B?’ó")Qn—Àº0` é:8~힪±&ˆ¼±dpK^EMHÃ~mïîñ]µŒŠn2òƉÊÀrnåØPªã†±Ô2*i Ó²  8;> ¸³ynœÞ““üNé J| ºÆjDß#tL£ŽŸÅØÄô9%‡Oí;tp²Ç¬°®Mª71 ”ß)—]ø,Ã6¼ÀuÊÐ&§ÆÁ(r•…9?åÁ)»™õJøJ˜¬†îÓàÆQ˜ºôañŽyõÂÃG+`ú©Kc÷ÂN«ÿm+„½øÅ.U,õQQ>6Y„npå45Þ q=p~ ª‚ˆ+*7Bâ0÷Z²é}lŽdÏén«¿Î™šu°-›œq$Ê­ÀÄ[§AÜT.—U?3™óUIõ¯©Òpq8s~æ<õ¯ÔƒÃ ÅÜLù}vÞ9|éTLÝeS§×1eO*¢˜Ë]lŸ°3-Ší«<ý:-½wñ‚•©LÜV†aØÇœA¢T€‚!‰WNŸž$ZFϽÿÀìwkÍŽ8ĨÀêõ^²¬Ö5söÂ7Žý¹½”0#É YsIávcs‡öy3ØYPˆÓ7Ì»“uE^æBšLØ‘¶›OR #äÝïì‚XF¶ŒHoþÕö‚ F7épm£8O‘‚ Tù\F¾RY˜ l×–ª =¡ÑÑÞŠHétÌ>È2ûB|¨g#ÑÔ8á Odà>Ô˜°’¥‹{¼+ƒÇ©AŽ:-!&¯>>ʡ㘚ɋCÌhCK´.ޝ¨ÕqéP)…LY‘RÐ È>íU—Þèé]º(/:] ÓªYVÊñ1‘v¢ùhèÒT7~ǡ刚\¾ÕzÀÓ•˜›ô2•é#æ¾pxmâ%à ˆÐÎkF<ˆÑoÒ X%cQyp•@šééÑòÖ|‡z6ƒëÇ|+±OÈÅwk®ÿÁð’ÂJÒ° .šBq?Ôç (_IŽ=,É&¡Ž^¯Kî‹Khdçæ“œô.ð#%ä’v ‹VYfë5Lù}ç»ñ‡’~!- û0z­Â.³z/jɦÅÜîôñïú £;͆¶å1 †ÑÈŠGx@“™÷º ˜Ñõ…`¿ª6àÁ¢&ˆ¯ÚEóSÂ4b¡ˆK­Yl‹!²¦-Ÿ p —]ö¬ð¤}èÕ…š§zØÁ” ¢KÕ*Ûap‘´aå 4(­%ZºZµš'ÿ”LÓo^4„92@%h$1‰ê¦RÓ)}yyŒí Ù`”>ŒZTRu»™y©D‡åy‚ B?Á¼N‘Š÷M|™‘ÑRÜ߸Y°3Y”ì‘àÛóQ$L±¶‚ýñS´÷!ÐÑgTTŒRœ06ñnÕ´)ZªSé’®Û^ r»J™ÙUì»^+NÙo îHlµ47zˆ4•>ò› ï5òÚmF¨D$kTZ S>¸«„,³Â`(0£€§¯+èÌkUzoê®»‹¶†×]EXèN¹éqfvÌæÑ¢¾‹ŸÄ öýˆ‚eÅ“xI ‘ÒåŒ`‘ôÖj‚t·n¨ŠÕ¯{é’²Â1"Ãç´WÀ9 ·!±ç°¾uÖ0bL~‹0gH3Ø3: ƒj/ÆC3Ò>Nžò¯+ÊG¹>yËc$¦èF¦ÔΞò†d-·)†A °¨VÀ\DŸ/†hFJ¶5¤ûÃ;Æ: ½Ô¦ÜŒAD1ÃÆëš9ºBUËN¥ qõ…ó™™”— e$?¥ ì©åêÌg€¹áÊ“¶áÆãêӘþ»NT:ˆÀ•…]N²§4QÉ~šÉNA¨[»»,Ñ+)ùAEÿi ö§2‹tbò‰nwÏ´† ½ŽDbiSÌ\ç muá%Ý7± y¡=è~]•)çg€Ê4äâ{„\›ÚÉ„½3Í1N*èió[Ýgç½uõÜŠ ìk Z¼›ôB¸¸(hLJpy±‡²æa&G@€£(‘èœìíëÒçŠÓ‰µ„YA+€Ò’0Oº‚¨@5»+*aRS˜¡wÚñŠÒ‰w&9í.óÞb„f/~ø ß­i;Ô*PÁ=*IÖ@Â/nÍ}2W/ß¼i5§ëR¿šƒXV #vY†âÃüXLNÅ ÷I~Q¢ÌË!‹Z$ƨ°¬¡‰qî¯TuƒH¥Àa€Œ¹P`ª§•ŠÑiÅQ Róã ú[e|©û\³ RÆþJm'‚°Ó‘E OÒ£¼°Pч _B㱯§[<(‡Ü`ÿޝiɨœH=v¶;…‘õ ™Âg­éè´Ð–'´©¨'ŽMm—93?Î;Ý:Õci*jBºO]Þœuü“û·Û”Jÿ1ôãÒl:š¢Wµ!ïÏÅ“âaáõB:Œ³ÍÎ?`wPÌ=´Íw&‰®gMº¡PQ^s5ûÞ¨±î5O)Cë‚D&±ÐMXÂä\GG½Uˆ'@„µ(1ñ¸¦<­%auÖp#Þˆh@è¹?ÿÛV1﨤æ«Ä»ÔC•éµEWRný¬äé˜9¡IÍ’¤”ÀbŸÒ¢%´ã1RÞÿÒBÂ'˜éÒ(¾úÌCdL¶ð®š’@)ïlÐõÇ26„DZ#såAã+0 Áä ºB3öY±®Úoµ¸jZSƒuâ9²j‚¥ë†©¶×¤®–Åj³5ÃÖ&a”¬Ôëð¹®Yu×d`ü¥- KÓþ”¦@â ™ËÄÉ(šª&S++”" a™ ÆòBIC9€ïƒÃ–·5ò˜N"ëV|©ÌÌÓ˜«¬]å±k¹ÅM¥sƒ%IêærÎøÏzuäV¤v‘5E&R¡ÎÝu¥T†:\å|žÇÚ²Ë^£ €OA¨tjƒÿE¥€ãC>KL·'-D2~jßÃüœªR ª0!Hiäl*cgˆE0XâiÁÇo˜xC¢©OòRÿ£p‘0ů8_]n@ÐÙŒx´™Ì˜¨†í1@3Úë&¦}&™¦ÁZ¿–XSRORCô² ‚NIzØä3„EÆ:á‡i€Ò\ ”Ü%¿4´›À.©†y“ÑðBl4¦MÁ—ˆÒ\Í`ÖTŠõå\-±ëÑ›w'¥µn•£ŒhžŽ¬š<4…`'•Ag¨½Söó’/‘½ç|$è wÅk]¬1[†5•m°"† °Éj6hwªÃÉ2´­@r–œ3µŠØ0uqLT¢0ªãgÈ‚ŠTÌóHXL0¯å±oÓö&˜/5³Œ‹ µ#…Ô.ÃËȳ*ùf%·ZÒ}ÂÈi–——<½Ùåálžìžâ^£JóbO·x­²fX nÞ¨Ll÷ýÁü<jšº×¤žÓŠ6E p›‘¾=8>Ç#‡ÊºiËã G¾Ÿ¾ç+…yÞÙUÂXFIlÙÐ !©®`áE{8 —YyZRžßfš^Ã\&G=ÿ¡õŒeù³¡ÆçXû—€·áêé¦o4ã¾\}~là•™¬á/ú]A2iìP·ï˜qÉTO}GÊ P?ÈãGÎv‡–L\K/:ÔEEç M\â$ʾÇ[;°º_ÎÌÕ å¬zHº²‡#ȤÌñâÊB¦²´¿>·l“¯øû±d©ž‡j¸Ÿë\* Ø!+Á.%z.oï&Euå‘ûB•§ú/ˆ»/tÅæ/YEщ”(ç¨è­W ž§ûAø ¿Þi¨Ôå3t‰ ;gŸôµÄ¬†*>ˆSÌËÌÞ†î Í_* ÉpãÇ"U̇~L”NŽ5•»öjÞ´åq5™ê‘û«y§ -ðß ÷Ÿ¸¢J^ÑÕ©#SU» ¤!–tKcøÔ@£_;WiY»ÛáéÁâíŽÀ…Á'í,ú›¬ta‘ÊóK^Õñ·E ›ûg¬7‚/–9/<«. râðÑ\t"ÏÒeGýªâ7ÆtJfý±žKBÕ¨°Ì¾UŽ- ù* Øÿ‚Ù‚*JâI6Q ÄÃX9x”,8ë·ÄU+ÔÛ^»@7~ò´ÇT¸ÔtHÕp€ò©(dØyŸñv“ª½Å»;˜Ö—¦\¥¡—bãx^3fák'âçðÐOeä1 Í$7>2éx¶3äé⤌Uƒ€¯zò¬cGŸÒ† AQ/vŽxšººâ‘:Ô ÅÉô¯æ@*²Å6QD¶}³­3ÌIj™vPÅ)Ös+*¨NÉDd|©Úv)šåìÌ}$ù¼Ck¢zêÝÛ,KâÆM]ï$Š³Ë aŽ| ø0V2¢<›sÊÝJ;†b!Qs‘Ža}!øsðhÔª’¿ãþáE7±¢¨_:"Ñ`­¦Í.ÒÀnš]µkTÙAcŸŽ·!2É„Ó#D¦’—d…Èbu$KI¦ÚlÛÞôvCª7±Í­²)§/ð1„§Ú5ˆ±ß`ç ëÀ'Ù!Î@FWçuNºÖ”S‚:: î¼vLÇŸBbX Âf#›tÛÂ( §„åjΠôg湯8C¥!¹9Gåÿã„JLÞ¡‘ÜRx±¥Á,‹Žà&L.g®hw«ˆ´”Rš¨°†y:º´áN"V×ÔÄöô*×Ñÿ”º¡Ÿ²~"-Ýû,f™©¸K‰£\†’}É™!]]ïî4£5WtA⮫¹„›‰¤É¾ò¢Ç‘6+RîcU¡{‰ÞÅN†’¨¹£Vú ^'hž«Ðôʶ–CÜױƩ½Ö\Jv†Äµ1”xë=Xvºu­Ç4+‘NÁ‘!çÀY¾M¿\A)™'ô @:r—ü"U•©™Îg~…ÊL? Q“äH§³Ô \AçÃY¿ º¼²âþŒ~(‰Ÿ‚iÆ(êE™zScb×ÛÎ}v;ëvä I]׫?èKt4 <š¡ÿ`Ž6È3ô¡RA¦"<R<(Ëç¦ËJ#“ÅæT4Äüqì!ä²ö¡}•b˜nÛM„†8à{Q‰%-*»|±M"T\eó¢¤ó¹j°CÛ/º¨°5›Ýx|çž}E/ª‹©Ò8iæÇRóW7þYÀønžx3H/Y+8NÃ+2Ã$÷)ÅçÉÈ«½‡04$¨ÐÐYô'£NUÄÁ.­ùÀªPMœê5?‰ýîzÉ?wqú™Ó#ºhú+ ô4o=™ ‚Y7$±C¤Õ!žAM¨Rò#´Žh5ü¬zݳ½êØlÔ‘WÆXA|çí¤rEçv’O19¡}Þ5¤Žh§Îivp³w1ÚlyóAÛ‡ü9.ÞËŠ ›RŸfl[‹sø27ñÅËžFEçÐ ÔÊèT|bØ„”Ú‚4P%”šgEÉV§ÜVCcŸC½$7ã6Èø­%âí%ÆŠ"0´9…••L‚Pè„‚À‚6 Ð"2ÈnØ.áK höcF¢Fq9c<_ô‰§Eg\E½‡2~ž»ýf¯ítêo;p–ncÎ k÷"TÕ°XÊ!Àî†ÄLÈ#àG®¥£.«ˆjÃÀX¾(!µkwL"Šà2ã'áý±ú§ qm‹ô¤Vü*Ñô„Å0¯#¼äeÆ&0Þ…ARlµµ†”vÊ ßÌ+¿IÛëS_¤iÑ6êíýòjYKSԱ݌õ²ôOÂÿ9&–6ãz™åV£¸À§åScX¸pþ ôs!§héf"XQàþº=iFÝ}žÍ† µÉlz}Ì÷w¬Žj/G c,­z‰¼gCRóW!Œ ‡`µzŠÒ]HCWž(á 8? õ‹¢ÅFgq©†5Âe–R!]Ʊú:‰c""¬ì² ñv0˜k…IJíð¸Go ”n s!5Q]²DšÍ<›Ø kQ+kðÐéúã(Ÿ jÀð Å=ˆ'F\”¤[^Ä‹\f¸û®ïéf›ÁliÑÄ)"0>DÌ“b8»qÿØæ-¹ u}1]-½¢J44VeÜeÁ»ðxÅŽã ¿Y2ê¶Ÿ…¸¤_?è%÷ÆáD– |Šûcš|¥ðAïqÒ `K猧¼Ì´ù®Ï0j×oñØ|Ž 7(hÔöx‹ Ô,_LÄUp²X’íah„ýgŒ.IòÉp¨äÆì^dî/G^>5W顉ÉÄTÂCs&áwê4ÔW;r¨Ë$v2³?MÎ^¥L]>Ó†ó%yom(TÈ£bçüùbØA¡«ÇTCúÑŒžÎ4ÔR¦i‰‰Ð‘“ÊJÿ0BVò’C®p˜'£ˆŸbLòvZqÏpdš/÷lŒ}3”ÖŠ@ëˆ]Coãü‚9;û„ü“§ofvUE¢"ÊtpÔ*ì~1F‚E¯ õ6±7jf\W¶~XǨúK ï>°ì†š¤m—„sRà÷ »€B*ã/mZÎJx!¹'‚<€ä4²”3€|…_:¥PûXBfµÉCèE™ˆ‘&ÝY1ßBöo³ B,¹ ¶Æ;þ€÷­2òiöÈ6L‹S–‰Yÿ0g¦Š¿Á– l—9eºéïšdÚÕKpch‚âcÕðË%–Œ ˆöZä®+û®áÐqLV%S:sM*Ï%#t93tX8OÿmÐ4XNÁâþ*ˆû ÕJË$£ŽáBÈBæ¶Ë•¤ +ì^¤Õ†ëŽÕu@'Ab—}Jh‘†—61O!®´ƒÔ¾@¦™fkÀZÀ ^æh°ª‘ˆ«ÍTò*×#Kg Ù(`u©Cªc°yzxÝaìòÚ|¦BÛ× g”Š…Ã¨s½¥û½ŒœËs’ÍðdÆâ긿üÁ.1°ç É‚û­å€}¨ðÜá̸/)óá Ns¡ádaËdlfÛȶ‘7_Øë˜$¯bŒÂ),§Ãñ°ƒÁu,JK²[ËoÆuv59#d"ƒ´!d¥Jø¥ÈÛv (ê÷)Cq$AÛâ*<kœ(D Ù=9Q¾„|ßt&<¿pÙ8v뻜v!o©U'¼Z•HOpzˆÞË^¹ˆz n‰ütØ“‰’Hc³ö¯àúÒ…ÆfMtÉ22=Š‚º. ØŸôù=€- ¯¥„ð‚¼xíå JüpЄÐQ˜­¤é@0Dnäþ#¹(&†y˜bæ0A¿†Þ¹ &Ú°AM×ӢŧOìßu`wq±‘Ë`7@Þ$ü›¨+…¤ QNdQ7þ¡& ï|Ò@STh8F£AxPâÇžSÖð¦+¡eÉÔŸUpcÜTg‰r‚ƒ#%é«Í*ý%°»ëZ*#2Q ;òŽDÍ§Ï çrd“Üj9…ZD°±¥Î¬`n.HTÙðçñΉX 'T›]X¦R9°k¬¸à£O¸Á¢ Äp[ÆèÚCo \Ø•÷-‚ÇLr;.ð \"¡b®“Å;Ç1½{3ì¹È7ê J졃dšj°á-!{S´V3)‘âäè˜ì Wâ¢)þ!ÙÝnã½aŽç œ xqÅàY¯%;ÈdLÖk#îÄ:,Áíðzï§a¢™¦Y‡P05¦ÃéQ¼]¼pt>ìYªõ†ZÿÒíDÐl•3:kf@б* äÖ(L¨âL‹#4cï³Þk\¤/+~ÃŽŒ±üåæJÙûlî×ZS/×'s‘½[h1 ´ƒuÌÖ.£«ëǘâ®;1u.þ0åQ)³'1÷¦ÒÚn“Ó —íw:‘ÀHìÞ˜}mQžüç#öÈaÝ¥ŠèÅaÊ®TDWòÖXÅ‚Ï „Ä9Ѩ6λ Ý*'ãüà¶€”È6#.BÁ¿©È«FFÆüv@½Þò\fµ‘UÁH²Pò+I+§œàƒ=}ÁðY‚Ø8àŽsqšGï{§Ñ $ï€øæce?]¡ºóž#Ÿ]×ö¶! À»®Î> ÔzûV%ÄWk'/œåèhä2'áRÁ+C~Ã[Û֠¨Ø…ÌÚ]#ì‚Å¥U''Ëè.«a\Ô7‚Æ'4ÌeI‹‚…í„ãªöÆ&_QŠ.åàŒÂRŽ ™šª?ªI1)N j¬…E Ë«|˜™JŒ —ãÔõ¼%‚…ŽÈÈŽ1KñK%Ø ’(Ȇ(!$†¥Lt•ÆüÕ8J§¶WËr7Õº]l/´áð¡åŒw¢0—0a 4÷d“â8At\ëc `rH©'±ƒ‰Á«­†³×,¬üDà†ö-8 ÒÖ‚vÐòA_*Šä> ½³w|?¬±ÎÎp EJìF CH#*9B—Ì06çü•ºÃ‚ ¤@?Òˆ¨ Ú&Q£îà‚‚Ê_ 8­÷f›ñ R»+:IÃÝR(Jä…,ËQrà¨Få!u«-9x¬UH]'€HvY«iãdØ'Qº2[©ºplÝŠuÑ• ‰£€.~VEzVôg9ÇøÑsºÕÚð•ႜ”î-¯=Qã&có$†ŒqbW` P5‰×%%iæ5âyQ±ž/Qð+_‚@Ý¿®„Ç>ô«ñhǹ¤NÑ P :Ù9þ•íÆXIsµ¢LdµÑîxD\áé:@Ô»ôܶF;ÔVÜhA#ìµ@®áþ|+€Î”ÔØ/ÆÒ RƒßÕlDæšvM¾ AÇ_J„œµã(âäÚÎÞa1ÓN¿óUdKYj´Ê]Øt.àFI_BˬœØ”±Ði§εEN¥gãºF߀ht@?ÕæH„äB7òëH[IÆÅBRå—–bL”t­êÈ{”`‰k(?Õ2È€´°8’Rš>X<&‹ñþsE'ÞQ<6f~cƒ`Æ @Ÿït@Ì"̘êÄÃű€È÷-]¦Kœïó? ΢Ê൸Nä;ø-`ØáDDmBš/‡³ÎÉiY&ó”o’º\쫎‹Íê6Ï0… °ägAá^ša bSCFRÀ±°úL=mÁÑÎÎL÷Þ›á^ݵو ox,•§Ù0à¡r5¶‘4Ð'leþæ@¯oŠÎÞ`TÅvbÆøŠ¢p|`c\ئéSº0)iG×ÀŠ£kqÈ#!O&£vl‡Î0ÚúR4ÝY¯YC8ohšˆî |½Bo®I¸°Úàlˆ‚n –ÓÔĦÙZ$Ù†TI»°Ÿø ®. œÁÀ‰‹K~S&æ’ònˆ”#è ÆÌ@Q–’'~Î?Îô[B)¨êÐÈœ¡ÕȓòfKÓÖyHÁ‹:ÂfwuÝÐSQ±« +\íêû—rw[š?©öÛÇùBeGd0‡Õ”¶Ü ¹¦"u:‹^üÖ‡#ËÀ´rk®»­;\©¨%Ûè¬ú^³9ÓŒ ‘]É:3Va®T…… ëÏGv™A åcpÓ²!ÌMz9òXjë²=æ.½ Y`š§r†*:nͨԫ Ú¬;©á06Òj[½º¦ðžšõ<ˆl‡Ð+4~‘[w¹8£wÛò›0ºœ†t'gN¨pð*+îÂGÍæ\Mέt² ÄÚÄ® è²:'0~u"³j á5Àö 8ë¢YJóâJFýwFíaò«±b¤—ˆTµ” …ûIÞeè¤`eY€ÕLvû‘ÆÑMÖ!Ý<¦¥T×)ˆU bJ”DóØIpÉ'À½‹LŽ åYÉNé|´ÀºÝI™¸"šÿS è¸ Ž^ƺ>ž1QOÞlgÞ˜ߊ½súq²²ñ8T{2ÍcìBì3žÕqH¾•É\H ˆy •IƒCu3”ãÌòæ%\§4ÊË\^ù ?ªjpt3Ù—ùXL½ÑjF';âžt ¸Ï Uó™õ·Ù@fSÑ1~GÕÌh1¥™1QÌt5ªf6Ër^Ðö–"g4ïŒa?7St΀Y·ÀÚ` À‹­^bNôÀd ’" AÉDT9j=%•T<‹”íI—©?ßÎ#%Š’_2º÷Ó]²‚ˆã9I+q„J8'Ñ¿ò»ŸééÞî_ŸÔ处:âœÈA5M$Dgpt±:õ¼Ñ‘<ËxÌ#…‰`6hG…)\+²­€ÌûFÀßÐA…94”ÉìTU‘^ˆLaÝZ>y} Mªv¥Ò×}ÓI `dAÿ³MwA{Õq.PñŒæá~&¨Pþ›UFfÃÁ0LËÖ >»Mã+£ÝY7Ô'j‹×¥ãµjcyŠéö ‡uBéFÓ8 ù±0ŠPÊû5Ë fé´›xÇÁé¥Jз´RØe*‹]¢àÀ5 ñJËMÎ ä­ƒ»h©`Ó|—ï¿Ã¿r±<ÚY•¼ Šk‘W¸³T­¿­Ô×áĸÅÚho,¦V3Þ½ÊN®ÀÁvPBÚ‘y0ˆ3ù{:á±ÍÉ^Ã2Qy^:µU9kãè妱S3kìb¬•®ï×ÎÙdìž©´5Z.s[ΙƒÞŠ8YISnTŒh F0ºŠŽj¢D\$rœÆ)/|E0 ¦g°–Û c=ˆ2qÖRÔÅ0UÔq‰GÖw#1K»”‡Hµ/(‡õ@_n´ó¡çÌ‘MÔ&ßäÙxvvö”VAVãXÿ6:Çä›Ê50pÒþäèñöñ¦àñøx ŠÃ£|jìb¤³:6•F]ξN?‚WaS¹,‚‡Þ $VŸ‘͵å;„qÍ% ÅgÄœ±@…´˜âù]Ä÷›€7DwAà†¥ã’´•Fd§è ȰTIÌ…¨B,‘²$IÞ v'˜ÎZuH¨­ئ.¾‹°WI ½)t[YsÛ–Ô{éÄþ ë;„ç&jClF4¤T¼2ãÅnCäwFgyݬH@:‚ËÄÜuþ"C-­ÈÄU`¤Ô ¾‚zs›àTž9ÚÌÎÎ’èS‹¿Râ'Sèã“@psM‘LÊhO–н—CÔÕ©`V„“À®AïšÅ !bFAsY:s‰E<É¢öR“D-É| ÒWIÆŸ±<8ÞêáB:É`´+0Ëtó±ä›)?L„e*§KÀ„c £îDíbíóxÊï*ý«{À¢ùâ¹lÞ±¦UÄ]È¿¨æWùÄPòF†cciw^ô íT—Sîï[xÕ1ÔØÙL\1”k§«Ü$cÚ&oÒ¬ÔE0Ñ“É0+|N¸.ÌBb²ÿïLú§x¬Ž¾enÄOéƒm|‚±ˆœ5¬T¿åµ¢ðÃAa»Á‚‘“ nˆšº7¤#ª·ÝwØÊ ­v;UÊB ‡h—jšß¢‹Rg0„O}G’B@îÃIÅ ¿'.I?tÙ6¯<çd]Ó8……¨½Úd܉J©„Säk2o‚·ö 6qi¸¼mÛ–ry¬„ÀÈQ[A[3 ³^{ÅóZE*øKqÕSñÓoÐ5Çæ$DŒ $×÷-Á¡E(ß˺XJðEG³µx0{Hh*Zmp%½â%êTÕ_*†³Y1Ë—v‡0ÀXWpJ¦ÁrÖ›>¸LŠåá=AIK§‘eI Ó‰1¡‚ê-r1çKrQ²Ç]’Ã..´›äb„«]Òþu!Ýæ4“އ¯F¦Ô`²§±¨æ.k!6lñ¸¢Ši,;©¢›HF@‹ór¹ 3@@ѲÑVmÎþ¥è?NzDí9ýƒ^¸ñÆT"ž‰Iq\õUÖFGéXŒèYP=‚ã$x,h- J’¡½þ’‘”÷y¼‡*Í´ “’]µ±…p~d ,¹¿MQ"Ùâ3òêY¢u±°+tL »\fQþ݊ݤ˜H… ¡ô‚нÙVü—L)W±÷ªÁ‘r9g—FøAŒÔŽ}^Ä9þŽ¢ìü =ÆnZÀ­ñÊ„©b"2òJǘqœ1v s„¨ßÐfƒ´áã(x2¨”›zèê$Ò§J²Â«Ã>ïÚ‹]oÖ@bÛ‰ù@ Z„ÚÀH Ô¨a"vΨ`¤vIyÛcÛª™Ç¬‰±¦fÌy­U§wŒéôq œG±Hé߬'gd)Å/ZMêˆ=9µyÁŸ:8µûàTuêŠÃ»‰?KK=Ðײ”‡»­Ò—q?œ –#1äĉŒ—䢹KˆÈ+Ax42õaÓ²’T§ÁÙ0Ž6W[»¼å’ËUp ΠIeúI½ÒH”¬EÐ'Ùr‘p{:!%›¤_'h¹ÏG´P—åí61BRÔÏnùé:§¸Qdœ·áÏ\Ïu> ¨?Ðè”鄉×? %Ç&YÑúâ€ظ»X¿*G^Ñè*ÏmÕmU‘æW‘ˆTƒ9õIf=Ôؘ|¢ÍS½ÀxY³#¸—陼ӛÈ÷3¿¡GÀO«³«Ú{_ôµ+¬Ût:ï$»œ&ï¤ò,‚ï³¹õן¦KýTîóŸù«ü~ÜâûX‚Í[œ$nn±9Ð20dŠzI¸™K’bלù0è,éìuv¤\tU±Ž*È· c‚‚U¥*TÉ›î*¸²Ÿ’Ê|3˜­˜¯‡»3;š¸œ¬°0 É*õôœíÎ.?$Ee\à’5CÙÜ #dÀŽfdåóMY5rÖHý9¦ì^k¹ØÐ 4voìò–3¡U‡À7‹]í´ nÄ ÈÁ9ççdÍ«õåÀÐRZ“þ†fÌÑ N[}{¼{0¹—" ×ί~”2`ª&sr['.²"O™ÍÏVLY\¨|N/…C£ˆ€Ùµ"»×Vý¹*á‚%˜#ÔœN‚¶ùk››F¶ŽlëKÍe x!`•raŸŒBÓŸ-È}º ‰ pô¥º4ºióÖ­›¶näÿ’º¡ÙŒ8²ÓÍðþÄŽbG§ôÚ¡²•g-ÿAƒÓ±õ;´•Ñ:ê[‡¬*(Yß³™*™/»*/@Ô-烇ê8Æá€‘UK kì“8`hR|øÐÐAoîV¿>;?Ãúªs€HOÐ¾Ž„ ž”Üyè‘(ü»¤5|‘û6ÉÈ‘OÆò¦âp¹X–»OùeLË6ªáÒbT*PUmëêK©Iýö˜ßZô[Mw6*Ù¥±"œ‘ý¥[Ìü­«G4/4’&½J­9òÜÖbpŽbYTW;=ytµéÏ/Sº²²RŒøiÑJ9j+J4›á—¢¸ü³“Ï1ÝÐWÏl‹p|rÔ5ÁIMúó-·i÷MPÅCËÜ9õ [íÃÄEJvá]”=´Z,ÍS\d½·¼FIÑÞ‚Þcxš6Ò*œsqx:mŽÒÛC´ˆÏ(%B$y V#î_ü]—ß!AjƒÁ2ötB±§|(}púÐ.’Q#ò!cÏ ž¬r"·†Õ;`ÀŽ¢âš"šú‰}^:µïàž™Aóà¦Ò=¼ß¯{BäËdì›’?È»ßÎÝ'w#ÕÐȪ8Ü¥Õ0ÝùOg°žu~¹ þgÌ9 nG×k:6=ñ6Ïqömtwóâ¯z1³áô¿õÿ›Ø½÷ø$-àƒÕ†XÄòæÑÑ eúÿïØ–áò†áMåM£[6މrÛ†7mpÊÅtà`Š®¬,x^³G¹µÞÇ÷³²þ„Ä+¯žÌvûŸ4q†˜0EGÑ:aS>b€6*`P7@áõXSÑ™àŸ†:ç61$WqÈ{­¨ ¦w Œw '$Ä£Rp¯³à 6¶¹ª…i¨>“™è/‚dÉêsÈE™5¸zé Â9~‚Íl¢‰…k63¡{ÔcÙT×w:è±(LXVDª¨é©Ð]¤xç>}´ñQ¡î#‡šc_tš—1eìAL»è…¥ÀÅø%àÝ$ì5AU³?„ë #¤›úBºËI¬5é@%–qž‹íâ&@uÑ9Œü-8ËÛÇÙ»{|1øŽBé¸ÛÒƒ¼NËin'Àujü ´KLœ„°?y‡:[q²ñ®f¥^¾j÷.ŽÜÉSz›UgëÐGüJHß3ƒiOs(8v}ÈL:­Îâ,$‚žÎ´eI”ÛV º$VÜãÙÈxóæÉmЛ/ò&ujåâXq-»øçH s䯼:$ðKo]a°,ºW¾2õXto~s± ÍgДar†IÊËÍÇgÀ‘;`O+ ô™A ‡^dÅÍh\ñ¬#x<'ä70¿2Ë ½-gŠލyk=ð–’üÓÔf_ =¹‡hZ$”Iѹ„€H9Wz°Pcà¡(£Áõ°ÕØG:¯ý¼eÓ´Q mκÁÏDåÇž ;ÈcQÌ;8óEIO°ýƒ0sjÖa¶wî?¸g÷þC{pÂÍ_99 ‚¿—_õWôëw·•†7—{´)GMñ\"ÙÕ3Ò’+8Ñs” £VÀLzIèµ2àZyÔ¯˜ðšø‘1w;ƒEà%Éј6¢<áâ1hÕrÌ¡9i¿©S…Egà0ª¬d nTNë–FÏeB„pˆ,Ê90W÷©NHî¼´ä?OÓ‡b"¢g‡€äJ™)w¸æe^Êâ9ñS÷“Øä¶;é—FåpDUU¡L]Ô&Ã¬Ž“›÷‡wþÄNj ?pìÎ8¤ãÒà20UÃE ¦$v¤DW§qBûºâ(Ÿ-™‘Ï'_&¨°:'¦ ×9ŒºagÖ+÷I—s%S..±Çj‹îŽˆ—.mÿ'ì‰sœËvOLî;tBð±}h`íh;}×qÊ •»>謅¢Eì}(Qãƒ1-g¼Õ :‚îíE>u§ÒR6­×wÇ|Ì7=4µG°ö3ƒ‹B~l•er (lš~Ä P˜’¨~”Ì“³Ç8ÆÈ¦ï—F‘9bgþg«%uÇ©dyÛ:øÉ§áµ1U‹<í½´»ö X¶2Óu!—–`Jõªâ~›¡NŸ2ÿ/ænÑSÆXCþÛ´iÓX\þƒ×§å¿‡àŸÎóÇ·UV{Ê‘ˆf1Ã?³­³¤²…äþœ@* Ӛʅ+•=Þ"Yõ‹,dUÛnt4ʹÑ}¥€Ã¿Ø‡ø>›a7”DöÀþœÑBVò¾ ™þ VMAjZ@$±Æ¡¡ÒPß„³D0{UÖƒåuWÊ…à[Q¢vg×¢ÙN)¹ª®ÖæÐ%zòÁâ+±9š`¯á~iL$IJm2t%“)@æ-…^}í–rmk,÷ÂMѪn}uu›!sH/¢72ƒÐcq£^*«Ã]wâÚ`vN¶ø@L¯.Ë-V”Õ]ŠzN,}r’2Sô¾ P”T°ÑÖÍ3(LË )4wŒö¬˜ÇM¯ AÄð0ªtVË„#WX5( g íeQI&aP]ÃÐ_â^¡ß‹Lÿ ï¹W[Aµ.ÐÃ/'¡•©u\„¦ÚáG±ë>¥¸Áìh«:¸º6ÑS[áÉ0¤•„{ÊÆÜ%7õ©±&¸Å{¸6¦à­Åa¦¼†[óLÈÙ'öj‡‹Ž¢])i Õ$ ª´"Ï ë Í&ƒ Ʀ aB…ç=ZSùlJiø·qÑ”¼¢Ûau¨AÃÐ_ÜWæÜ¥ÌwºJ,‰:‰›cÃ5tm¤. ªºWŒX­È†p#dù-15ƒ·/ø>KD „Ms*bcTç,/4J* ‘õ8·ŸÏc®À Ù¯‚åuÌ ™rÓdL ]%ÊÃÁu%¶®B†4 ½  7X •—îœÜdÞŒ†Û§–fJIÒŠ~¤„ØÛô9“„%5 }ñZUU (PÀ¥?ê/-¡:Vž¸òغN&w?qòT5´³'ã¡êÎH,ØÍ ­h’YŽ6G¤¬ÿ\íR™‰•Âé ŒS‰ªH°«Å˜?/R9ŠáŒ]@ãaµ ò4¹Ãõïßv¢}i¹Q“¹½Ô„›QÈ& ¬Æ€öo%Є/•ÂØ,ÖŠ´ûÄ:[3Vqx}ts¸Ü{§ƒŒ.Oó‚€oøòFÀ½¼B|­(n7!—*y¢ggÒkG lF•ªÁÅkwùÆÓ70Y£Å̸,ʼ)ÄGöDQîqƒ‘:~´@Yì)Å{ÈqBnäÓ}HXE!cêD~ƒà25ê½ÄÝqc\ \…œÓ4õ†W§ÅθÉÛø€å¸Ê~XL¾I`Û~Ûb:Öä9Ê}ò¥ìÑ X9Ø\›FÖµ¹6äºß¿[Šå©VÞ¿fèÀ„¨[pH#Eñ†g  ×ZJÀÎ* u¸6J,â¢Å^Áš–ä)à “h¢œ|(Ç¿¬"Ö4úqË^!oI™WÕ1…ì(›UœuÈ!Õç'l˜ÚSçtttx=S)ŠÓ9m­EnM¦Fz *\y˜HáE#;ðzI-#¡áDûÀº\¢Bm‚çÓÍ-#¢ý-ã#ƒƒZ=Ä J)pq<ææÈ¼PfHɹ@ ­D]jwé¦hA×N‘[-ÝÓȘîõ]n£k]nd—Q¹düÖ•„%ÊÓe÷l¹2Xì[‚bêõ=EÓî„°f uåá´ æÑB+ĘIBîq%ÏÏXŸ [-jéöÃe„l?´Ý)WrŒÕ‘p=ˆ­¢\Äê@FHcªÇúÜÙä]‚س¯%ÇÑjl6¨ÆR¶c¨ñYñH‚„lfÈü” ¯/áQ;Þ'ñBzRoÄL¢ëCK„‹‚óŒîêŠE:ïªW¾«.ŸÛ³Íس{*kÈ ”TUíó:¨Å#Œ%… /a½)<Ç —É}Žðˆèbº²ƒÈ¯‘L1DJG;qT;­:áœÉÄí &ŽIJ«šþQ5ã…-÷¥ÚŠy¹•Èo¥ûçX;E—"šRW,vXÔu¼q/×kVȰ:ºtPÁb‡úíl×P6Ä „#>}¶y4§³ƒÇá þXìPˆûDk$<”Iœ4üŸë:lŠ /¯/®9L´ˆÆÒÎ&ÐO!D*}Ƙœ»]èݘ¢wRKb e¯ð›òžå±ßükOäp²€]Êiûsš2o…„y6¹ë:¹º8€6g¥¨²[T•1¼’ì,”äKhkÓ]œm¸Ѝ‰ëšmtÝ©`ò$]Å)a ¤ ÐO«L4¤âœf& Ê!ŒánS®AæT²¦â‰þJâ*Ïv¢hí˜F‚…¥ ZÖ@þVë»h¢ÐægäˆýI¡ c­SDfnbxtËú¸ ñAYññÈhy}‹ˆáè-#dVÅq‹ûG)U Ž·f×€†¥ iä”e/ž£Iºsrt2ƒ^˜ðÒˆoáÒqäÍ¡²°o·¼€‘÷d):0‚o„X0žû9 ˜=ð Ù†¡wV‚0É…Ž/ùö–ÜUc[U¥¬'¼Ák”æ)Ê’°â7+ý&f¶VudëºØqQ¼]T¦‡“£²´ÂÊÕ@Iš,QãùAEI ¼DÙÆ%ZŽøN}Fþ¿´Êr9•) pµ8ªß¾àbB›.j… ¡¶Å®±–Ñ‚·ÓUöÑYÂ'9¡U­^‘󎺂¿xqdë¦õ-Ù¦¾—,¥÷—iåŸÖª±r¦Û„Oÿ®fèG4ÏTã1WÓXcX^~T‹¿ë™ž·mïNÊÄ*à1†¹Ž«íà¨×ªRÂó6]E^µBiTê/5ë!þƒÑ^¢-¹˜ÛÖwþ¶­×º2Úß²kr¿!BË ~¾97J=Büö$|këTJ/¦‘J OõÎDPÓcž§X9i Z¡s­¶™h°RÙ‡”%#ãˆ]áµÇeë†.¶¼et}×ø çõ“rv8­Þ²ÊnÅZÔžÇÞAÍeU_i±Y`Ð%NÂTÄgÜL¼D  ëIzËDM¨µŸåL´hb*HðsÙ55e35Ñ™g%«‹v•Ø$q‹î£±#{ºXCO•¶¬É›ÈêIØeQ=&.m«i’ ¬árC4œ²ýÄ8e™àKr*ãë9S¢xoy!ecŒ´C›<,WÁ_×é¡Hc8*’g1)ò#2ÎcL$f Bt£l¤öC²ô®r,ÉÄTºú¼3ÀFQ‰pTÞq³£|†Ì´’Ô{çÝXpõõ°t2µéÙUìwúÌŠô?¶Bñ%ð¼Å‡6"ÍnÜ?¶yKN¯Ó¶uYHDñÞë4áüN$ƒ¾S#PNÓcAã7†\¾†‹˜ N¡K,òßbiÄœ!ª.ò‚s±àF°¼Pœk±ÙÆÚ0´qÅß‹K !òBæá4f¸cl¨h5dŠ2iaµÍ²çX%‰ñ‘1N-’$R¢´ˆ¡àE' œÏCŸž¹NSÙfĤޢ')BG¢O¸±Të;RÛF×{M$®©˜²®"D3SbéWì»GeÊØ·œT¥Í®ÚMyZ0è@„ª²ÓÏuK6±5uyXj–ìUË;7† òé€N e ½5ÐɰÍÉvåx8uˆ[_ð.ìÀ©:%aÒ–‡g¦³»-i$;¸Êþ¢WtÛƒå\±Ó®k }뫸T˜à•„žJøè®dF¶­g‹âýñÎè°‚ù’© ‘›ux™<Ñ&\o8 ÃQŸ@ÖÍœh|\-*ô¸VPN`lýê´T5¸z l’È;2/9Û§ ´Ff*ζ©0¯ÈËÑŽèUR:¢nw)£êU;zEv¢’$Û]@OH½Œ’é6ó‰þrBy^F p…æ aà†Ó9èr¥XaÉá)ÕDydÓ:yÑM¹þOÜb ¤³¨ë¹&ùFHá5Vã)ÖuÔ5ú¸f¸Zˆ«$îoëSi QØeà_ÃrÕÙ¦Û:*3Ô­éû¨›y'ùižGSqJÅsvÏ)ÅÒ¶±-ë8G¢ôZ77 …(k=Î ɸ5µœ‹‘ѧ†1M“ÉŽŒ~ÿJoO!Œ!Y¸-8Ò9ncP‰á OV%Sb&‹1À…\ǤI”9~R0b‚Ö·CÂvgz&§²lãû”´MÌÁUQ t²ˆ§j?¯õ^gæ«ÊÝÓÝT­æd—U¿r¶#u±dìÙ<®…TãÏìÁ€¨„;³yÇoˆ‡LGªð&P»è󥯤§ª ^lZ|˜KÞ"^…õ÷Ûî·IeDEM/»DÚ`D[îBQÚ\³“`· Y!œÍ±O-M…Ò¿Ö”Û‰­8ÂlêfÂnˆÞR¿ÄxìšÎŽÊä4æ>V.s¨œq§x9Wª#“9¤@cSj—¤*^j_h ÅZ Þ"P A|Dsdsɤ(ô§µËçcŒ2– ì4ò| Àš 莈E)‚•(â‘,¦} énõ—Åc‹MHéÇ¿ÚÇĽ¶”~0|_° åu¹ ‰â’ÃØ6¼>åÓ¶„>¢»Ô4¬¤¦qÜ"( c¼?S6ÓµS»<ê\À¾)îdü¬þVŠB„¹×iÑm‘âK³CÖ°f˜P6n9Ã#[/¹0ÏJ_ò#7 2žq65ã:ÆÌkpý·Ä5çSù¬IÆÆÖGDùµ¸òz#_(É\â­¿a¿{Ç8¤ùb¨”€¼u˺hÀ–î=¢.]$žö!fÖÜUê1ä~2…l¦¼•rÈÚ\•) lÂ´Çø’´¨Kㄳn„Ž»kéÑãŽí^sàÞtžUó´m]§h[yxyBÌ =‹pð‡!äðÞkÀ10ØkÃM&Å©2Rª€w§¢!&cœsBg¯-ù”Þ2¤EYåƒ&æ £ÆÄ4 f[‡«-}yËu?#hÔs_ªß©/ôNÛºy=;mëæõ*bʉh  ”òÒ¤¯“«ÌŒ±àpš6ÁˆxI±…NrפŸ¸åXÎÅi¯qrmŠ­0´: ÖÂ¥7Ä éØ/#|…n«Z¬sx_Ájêô|n^fK”^ÿ|¦Ø_ÌìgQÒÝÌxixq°ì‚HÁ.h¨Íäbðäq“†l(îaë¥x ßÁ­Ùéã™ÉÄÃ'í6Üp1h ûÐN‚z"ãþ4ü_ ƒ*KòÖ!BD ³+(Ç`8Ä}ãáÏh ω"ZX~t#' Õlž½Ú~{µâ wÙnøá{ÿµJE¤i.V„“„X 6y“9ÙrCJ¨™>2Þi/L}OH8Fp>ûÓ‰/s› 4àíæ7¨“\‘½E³N2?ÔIöaõî¢5Êü;Zá¥-°-¡µ>2±& ©ÄL^~$¢,È»Á“ü‚J‹ÂîOnUÁJÅNÒa-qj´±õÈÈ™îg¢ÁžßÓWØEQ+døyˆf€Q;jÙ éºð ¬;½;"%5²Ÿu«ÿ ª.P{ÖBÜΔª‘°©=5Ó݃ŠÜI1ŠÑ]º1ôÎ ´R|(è´=jð}ä›Uä¦Ù˜…E·å :I µ˜8Çk¤œ4t0þ¹šŠA=4F½Q4çDâù ^%!Ѫsâ(iº˜®@=3ý–#mÍÙt…©Òæ/ÂL #¶`‘ç2òšs©YÏQ ¬’>û‘TúÓÉ| °JX«‘j”xUè_Íþ¨BIÍ“ï åØ]ò‹Rw˜)* ÕÀ?gx¬ä ­cEå… V輊t•œ£$5gSãnô,¿Õ¢ƒ£ÈcÁÊ¿`S WÌÅ ©µ ?¥-ÚË€q‡÷Ѭ¥.…ÕõAì:«™«AæÌrmVQ±á^Wjm夭’äDeÇBg0ç2Î"ÎJ•¼j_ÛépìØ eÁœGиÈTäÒ<ÏásìdmEF—ÌŽ ÝòëUõývgt$“±ÒEÃBC^ÆXQ2ùìH>UÎÈp«b i_yoÓw7%êvy€ì÷bZîdBƒ[UlŸbú0’ƒXG÷»E‰g»ióú”g›6§Ù5v©¿LÚ5"Ü÷:_½+/eù Ÿb¸§(ÑË‚úmÚÒ…G;Pñå]3ç6µ”ê€tKv¢»}ÍÁFCA!ÊIûSë0q›²\O71ÌÌwúv “—¼VùÕã2M<$;öã¬V¨ÄÞžpè÷EMQlžòô(¢¤ÃR‹\‚Tà }Õò켃T?’ýN©ëègç7Öðã[ªw‚ßÙ_ŸzØnjØ^öüIGz8Ü_RÇÂr=µ¦y[]šï¡ͳVTH ²~…è²F o”²º‹êW‚­ WYVfŽgÝ}Ùg¯Å\'D'ši`«EÜ]ù—ºR÷Cq¸ ò&¾g[pˆÝZK} s¹¾}áØ†Ã gOæ?Å ¤ôÝð?œE ;uö"5óÒZ”U09D$5â§`1Iч[G|·å+q´¡óÊ7BñCÔ;LÃÎsDCÇ÷ÀÝ-5T §é^í7 ƒ;*Hޤ‹Ò2¡#DPï9BDÏå`1¯NgÉα‹í^:v9•å<÷”Cl¦+ÇòNeuì¡ 5ßT®6Ãi `uè &ôõÚv(ƒ<'ëé„lßh½ruÜm`ky}©[{(€ã;`YâŽïÓàFâÌ#+Á¹@EG»žP+áÊm§hÐ[2¶¹Aq„¸ÜjøË~2ƲÒ\Üñˆ: d#²ÒÌQ*Þ;@N ÒÃ?”Ÿ.ÂxÅùþB±Þ 0|øå(µB×àöó|H%h£eylqA. ò Òq Èp6>Œ…Ù™ß#>+,'¾Q¢–îØÈýíØH·ŽU¬\Ýñ¾d»Â7ªýkñ äKWÃtÅbšKË#¥áZ^Ëæ¸Úˆ!Ýþ”TPãæ)µM©è…>%Û¶®ï”lÛÚÓL’¢•Þ–æm Z.rF'–Õ&]†;$gÕ뢚®¥øúAÕÈèûõZÏ"»|Ñ™vï2‡à?0]„×?+" O²oäÚ+H5„⚺fÖ)ÐQañn  b§H½<mr­K–p°é5zš7a)<k1Iã¨ZÌZÅÔ}Tqž¶2HÜ…–`ÖSÁõæÈ#£"=ÛÚ˃²òT@¤œ {GF¼ëg1”¾ÑÏ‚9p§ÙsÄ|q*¾à Å-ÍÂçͦŸ½l^ˆOvzXIi±1¶fGxÃaGÄó†×*`¬O:K°´¨³AX²ÊæÀö5 =>nË%£L¯3™ê.!¥‰u¯c˜#¸€µãá¬B79LBþ-ýfŸh‡žW¢J:Ç‚®§0—jÆhÃQ›|‘ƹJê¶¥¼¦¿åÍü‰Òë4¸mI#mJ¨töªÈ›qA==)Çh“_(ŠBŒB‚i,¦8TÁy$Áü}.^"ì½à7²”ñ •á,Q¬c?o;墠ûÄvGØ bL)‘à:…èRoý&H ‰ìŇBqÍè l°ÝjºÛµ.!æøUhãF%BåF‘˜æ<}Û O2TŒü™Ä»à{‚&†õ…Uß ^ù´/"P ÷Ì{"+&ݶ@VSHü±Žÿ2c –ùŒq"ÃÇGë3÷Û0‹@ ºKlN‚½ÈIlóå‘‘Û êÌò–LqôíÒɼÓíãu-;àŒ®Çd.J¯áÄaœS˜],’a ™b¿v=i¨hÊ!€ÔŽ iGHf£åMÆ„±{1¤–Bxr&¬±6«õ£%ÈAuö€iÁ¾‘à&ª35É(úͺZ²DI&¨…Eϼþ€©g1.g@å:˜Kd+/”]Fi@aAHÜSÛ1‚‰ø…è°úŽÕ‡ç…=Kƒ5°ܾ@ÈcïTÜ §8qyxÏÙ“Õ(Õšt¹&oe.²Ìuj^\ï®Bÿµ½º´„µGÆÖq‰Òýïc­vØ…:ÒLˆé„ãû¹†NL ,’R6Ó'鵯.€È’jYÏ à>Š  ‰îJ`„p$pYZ;$Ã( )i½yŒÊ!¿ª ØÆ¥¥?@á´ ïb/ÐzÊÏm«"Q8*¬¡»8ëÏw jD²0Ø$Y`g9W¥ >}òÒýoÃ5ì /ÖuLv[fwj4|VÔP¹A}äïħÇÄ ç%`::ù&ÁH•n¢–<3S-ÂÏ[2ƒH,5ÃÂ(õó‚X`Æ>UªøAȬ,ž{ÌÁåìvì·8˜”VÝYÐ ©-dsB¤dôÛFÓHް–-QÖõ“à¼0à7*Î0H3°üÒ§a@oñlàâ`¡Ån>j¯ 8âÍ®ÀÈ€Ãɸ1"ªI_"¬!_;·‘È|µÎ®ßB'ä{81Ć—·æº¨ÍèØ:dzÌð§'c°Í.)‘âP®„ˆFØ(¯b‚Åž@Ç.ƒbÉ)u£u1åtT)$AÚ¦zZrð"‰jið,˜ë›€´¥„'aÍn‹V  V¤¿kýƒr¦EÍ¥D5ÐÖUA.#,Ì«ÝAš#ì<¦¿`C„"!ñy®/Óíèæ‘ui€DùÜÿﳆÏz­ú¢-EhbýCÿ­¼y,žÿ{løtþ·‡æßS÷ßU,«b§-øsmÊZteà·ºä/ÂÔYhÐôg³¹œNSƹ›uþ8µ·ü¥(Ûán)ô h¦â.ù™¸Ò½CŽÒFæ‹éÌI…m¢Ñet¢/ CäƒRa¬Ä“Q¶Ñ: nÅ ²EÅóª (ƒÙ„¿aÓ\S.“.Á¾DTÏG¢Öòô°äUÈ‹½{bãqÿäZg‡G6qι åø‹büôéR‹ÿ!{wØÌÒ±Ó) À{ ÅÑ‚1¬kýç)–$BýYuVùÙCuþ‡Ë[¶ÄÎÿæá‘ÑÓçÿ¡ø·‘˜l„x¶fž¦¡m|i x ·™É°q,+ïW3¹q6c á.‚‡$Ù!9e¤tÑZ4rLòoHq¨PÒ/¨³\Ü´ BšÈË+Q±Qã|‡3ê_L4ƕ˧«æg®¹z¢ˆY‰™ì¡×¨»á’×¶{$…ÓK÷fÌŒ…ߊJ;G;Æ Ô ý{O‘]›ŒëApÔ÷®tCû[`›`ΘWèq‰«F9£X ¨ø<«ÞHä!78¢g],·è‚²V0}böt†µŸõ6ý÷óÞNþפÿÃcñü¿›7m>ÿíg•þ“è%É>|`ïA•ÊÅѱÿ5׎góOÓ}«XKÐën(‡E)£fЦ9}[üLÒ¿U7=ðÔ¿ú¿i4NÿËå-§éÿÏýÇ@S'»I‘ÃÛ²úV(Ôá 9ÍíÎðiáà´ppúßO%ýý‰Ðÿr9Iÿ‡OÓÿŸYú?*øÂͧiüiúßÏýû©¡ÿ§õ??»ôÓI>àôÿ‘Æç4ý?ýï§’þ?(€µõÿ ýÏØØ¦Óôÿgþ»¡×´õÿbK•ðéƒb8­þ?­þ?ýï~ÒXÖ"¯ÖƒÔÆô$ÉÿoÚ²ù4ýHþþKˆòù½cKn«¹máè‚£_ÞQ€1¿;ì "¿Ç[¬T&1¨†‹Q8'Ðñ-*b<ÿÛ®\átû£7Ìh÷Ää¾C±ÀRÓmƒÏ/€¦ó£JeâÒ ¯ÀRxq5ÓÙ~}ÁõšÎ…MÏŸ_ÈÎ`!Ìá z1-ÈÚha~ÃsÁo˜‹.‹`æs‡ûð/¦áDEAÉWå@Çrôs&DigÂ0)Ùæòò›è”>±{rв Þ©¤¡"”+J©A4ëæˆy b¨Ë|è¹mÊðÓBwF®¶é×=HÁý;°o PÄ6UFb«R \q×­jï®óÁ‚Ã×C÷Ò‹˜ÍfÑmµhjôµ½Ö—xiQTEï‚n;1nÞZ½i¶}ô'7F0ÒÏ7Ç›üI™¼Úz}A#¾ÇåGðvìY~ÙÛHu©¼VyÜ(Àa) Ö‡i—Ng‡†JCÙ™âQÏ[ªúsÎqÎHMçþ¼“`çÆ&*cQUqp”¨",ÄǽJÙ¸á¼A˜yPýROÿ{(ïÿ¥ÖüƒØFïû¸<²9qÿo:­ÿ{Hþ½àðÁ=Ê<Îñ£öíÝ5±aÃÃŽˆ¿?òÄÿoü#ò¯¶wiOsm1Ø0Þf=gߢ¸'<·±zÕ?xçmØð˜‰}»Æ§ŽÝõõWÍ„·þãã>–½mõc+ÿ£'ìzü™×yØÜÃÏùðy¯ÚsÓÆCô„?Ó†·þÜË~xÏ{érmyéu;_øÕÜù‚Ûo½÷ìÿñ_ýqøÆgáüÝzë¦[ë¿tÿ÷œ¯üè-þÚg?ÿ•ÿt'[·¾ôÖOÝö®?»åð‹6|âçÿꬳ¾÷š_ýþ;îxí º|úæw?êåŸÿÐÀYSÿð1üû­/9û]o½kò%ßûÇÜ•}ÉMßÝôâ§?æò ;2o»ò¯ýíÛ®}Gé»·_ó¦g|lÃs®Ï7ßxâ…ÍÃ×zW¿kÃsv}{èm{ƼéÜëÏÙà<ã%ÛÿìM¾ëŒ}謿ٰÁÙ½yòµ}Ï:ëõ;7ìø‹/¾ÿíþKîÌψçÛÎúüÎÌ¿8sã³¶á oÿô5µëŸû ïùtôäÛ.Øðöùã;Îüûë?þø_úȽ?øÞ­7¿ìŒ;ÞQþÌ÷®{Ë?½yÆü5oyôõ_˜üÓ/¿âѼºr÷Á+DíÑÍŸ:cÃÒ§ï¹ïãלø› ïþì'‡®;oû¾w¿³Ãsv,¼eÿ@ñ£/{ø;/š|؆ýW\ðÒ'9ò– ñÌGæ7lxeù1bù¿}SuðçVžýÁßÿÄï{úó¾ù•OþÙ»²ÿýæ¿yÂÓïý?ýÞgŸÃPëÁçößø¦ÁçüýìÅ߸gÇS^Ù˜~Þ‡_{÷#«òù×?r£Úz϶ïü±Süøûn¹å ߘºçœ…³NÞýúoœûÃß}ÙçO>ëÅ/ÿ­wýÁüõÅ3.»=œŽžüö_}Ï·šG7pߟ}Þ÷¯úä½üÑüÚÿ‰î{Ó¿_û¥OýÞ¯yO©ôÛÿ5óg¿ñ©ç]wÕ‹·žžÿøc÷¿ýXÔ|ÝJ!øèò¸÷¶w|ò ï9¿µý]_8óG7¿üW?ô†–î{ß_]þõ·?³ýú• 'nüØÊßÝòî=Íß]q×Wþç¯{qnú«·|ë’\yëå×ÜqÑø³~sèòǽû†k^üðí»¶}`òʳÎ|âöüñü;î;þí¿ü‘ë>µí­»¾{ÅUǯ9ó/Ÿóá‹Ï¸ç7_ó›­—œñêýŒ‰Í¿é)×½üOïý>úºGþðÉ8|òÛϺ¬ºúOÿôèÆm¿üø³~·óƒ›ÿû?üÃ…÷m¼í_~áÚW}ðÝ/½î³WÿÍ{iË?¾ëïÿÖ­×v¾ðÌÖ‹^ð[ßzæ? |õ’g|ô¯?õ®GMÿý“7½äÒ?ùääè¯;7ú¿{´þ‘ß¹âsO½§¸ð¬GüÁø{¼Ly¯.¼ía7uÞµxâ _¾÷Uÿ¾ÿ&wéõÎÛsçãoúî¡çþÞoù³'|tìw~躿x_í ÿï—†7ÿøçÿk÷~(ð[¿8ôÛ{o}ím_ÿ÷[ÿûOúÒæ¿›ùóýµgíùÄÿý±Ïõ^²÷=Ÿ|vãìÏ}Ô¶{þsónõ¯øäéŽco¼;7¹}óÞÿè¯åãÿõô/=eÓÿöü#'/i]üûùöß{åóoxÝÛoþàÏÿüsÿ ~Ýk¼‹n½ïã¿ø™Ûûãÿvóµß;ÞzÜ ®}oöó/{ËY7ÖÜ\yä¹·½ä—åoùÁèc®¿íÂòß=ñò»Žüøs¯-=ÿ`ýS¿˜½ësÁ­O{ÅkF/þôGî}â_üá#¾zâuß|ÅçžþúÅæS~«þݯpÖUÿü¶c_™:øË_¬ž÷¾«þù±;sùwýæï¹ìùÿõÆc‡ßûä#Oþì'^xòÀG*_>sê†wþð²gýßǽ"ó‚ë¾·/÷¸×ÝóOà ­_yÙï~ÿ[ñÜ_xö·¯|Ýÿ\³´pè?ßó«_óÞs¿_ºâú§}?{Aø„/ìýö¦oüþã+ï{áíWþÚÍ/¬¿xëK÷þÓµ++{w\ùÍëþ™ù[~ë’Ï¿ú)ç¼ùܧ<ûï»ë‰Ç?þö—kÏ—_õ¦ÿØrÛo8±ðÑGß𵋿6öš×|úc¿û/ßþ•êÄÎÜô¨³^ùÆg_wcíi/zï™ 8?ºqðÊ?}ïÅ¿sϧô½üÎÝgœÿ‡Ï+üÉÎ{®ºùa;ž:û¯ï½îõO\¾ìÀµ‹Ÿ}Ê·/9ü_—?kùÓ×þö?þðêÚ¯ÿÞ;¾ü®Wþׯ=ÿï{üõýèî<ãm³ùÍ'Ý>~ç_=ü’ËÿåµÅýsïûæÝnæ ß|ŽŸ*û?øÑ×ùñýw=iæä§f~îKSï~äñ÷ O¸«yö'î{Ñ…w¿üÈ[Ç)óü_{ÆÔ½_¹{÷W}õ‹o8ô‹w¼yãðo]ð—þdðÙ_?÷ä+ùõË^ý¹ÙçÿÃ9/¿ð©?âÈ3o<~óñúÇî¸öâ;÷?âòoÜôÎ ¼£ÚùŽ­Oü¿gÜ1÷W=÷Øuï?´gâ__uÙõ›¯98tÙ×ïôëúÎy›·=vµú¥;_õÒ{®½èozÖËç|ôm¿ÿÅ“_ÚøÌ;_ý·»*ÏùÎ×ïþÕÒùGžxù+.zRãÜ?ØyÓÀ7~xûÓôoò©Ë®¸iÇg¼›ÂO?ú†™_ü|ö¬[œÛî*~ëk_=ãûþþç?òü깿ôÕÝþÖÏ}÷;—^zæN}þµ¿yÃ=wñþglŽ^¿õÏ{ÌÜrÓï»æϹóù“¿·íæ©¿>çO¯Üò‘wž»|Õ_ýÇ~jîÅçž¹ôÑoß9t÷_ûìüŸÜtßë^U8ò½ËóŸøŸÛåÍ¿ó7_ü?›|ÇÌ“^ô‚K>}߯|öi‡ŸôŸzÃí—þÊÞvåÐêo¾ï†Ç4~ùÝc·]sÅÉ¡§¼èùï»{èëÑð›ßˆ.x^û± ?“ù“ïÿþ™OzéEÿì¿ð±Û?ù»Çþ ~ãÿcï[àã:ª»Ó%(”Gð*×Ö﮽^K²$‡;¶"+‰¿°dç¡,«Õî•´ñjï²wW²b+ ”(„w[RHi @!å BÞi@!@Cy$(…¯~sΙ™;3wîîÊ–»]÷× ½wÞwæÌyþϯm¸?<ðœ7ެzÿÝ{ÌëÞqEòî“οúæ—?òs½¯{Ôù“¿¾ãå…·O|ø/>ôè§\¸ãù×Üöí3¯yÇý\u×µ¯üþ»6þö–w~rÝ£ßrþú?=ôµß_ÿÖßßí=×|õõ篹éÚéOöä¿ýäî·Þû”G>ð­òëï{ñ뮽þqwMÜ÷µŸÌìþÓÁÿé3_{0sòà[?ýgþÙÞ˾áÞx¾óÐ]ÏüÔ‹ö~èsrõg÷%ö3þϽåÚgxÊE÷ÜüŸ×|hâ¡O~喗Ϧ¯8mÅŠOzê¯9çU—~ÿ/ªÛû_þ¨ÿ¸é½¯]¼áâ7ìÿôC_J<ãw÷Üþ¸-éÄoÌ?}þ/_çý㡱.oü}ç~¨ð¯Wzó«žrÚ=wü÷_ï9mÝ¡ëþ|}ß÷~õÕ¿™üÄàWnèÀì§f¯Û朵¯ÿ‰}Úï^òÝäÇÞrõþïÜö¥µÕ§ÎÝ{âóŸzÅ¿0ð–7ϼdßEÏ^ßwûµøQÿÈ/xí7ﺑ¨Ý?yòO~vÙä{¯ÙñàÍÛ¾ðš•{>|á{Þ?ÿµG<ïÐåÅû÷•nÜý¨—=jßçøÎý×OÝ}à·{Ò Ïú|úONÙuíŸ ?æÞ/ᔟí8íß}`ÇÄ£WŽÿ÷žðõO$žrÑ{^_þìëŸržõÈ º.ÿjùE?½æECï{Åé§<ý º÷K~çퟸõ—?ùãkŸòÌÚ?̾äÞ5Ù÷<ý#ŸÚþÆwÿå¯/^ÜqÆÀtÏ5W¿gÅ›ïùÑG~¿.õø7e÷ßðß/9ý³_}Ì#׿ÿÖóÞó¥ÏÍ=áKwÌë}—®_ç^wÿ÷Ÿx½íÖ—ÿá{þèëOþøo~óÒµ¯úP÷ÏŸ[úöÉ_¾åÒ>÷¿O½þmW>í‘Ëg¼ Cëçî¹ã û «xRðáÇœõîµ·ð¶ó®«½îy7Ϩ¾á±ÿ²fÇæ¾O —îÌ>ýu7­úÇû~ü—4ßý®ïݼéìúé+ÿûÑÝ÷æ{}W>î÷é+núüì™ÿ–úÀW¿åÕ}Äàãþï©o¼ïÇO)¼mô‰ï¬:ïs#=¼söK—~ö åÏ_óöo?ÿU¿ÿç}Sßí}ôov~w÷ÎÞGupxèË×f?ýnÿkþëiûŸû•“~öÕû¾]ºîÍ÷^û„_|à'òµßÝüÔmoûîúËw~êëuíÓ¯zÒ/xãWrW~~õàø+Î[ÿ–÷½áÁï<ï}·ýûü†3^à_ÙøÙŽ=Ïî¿êÆýÅwžõÁ?:ôÞ'|}kê‹¿;ëΛ¿þ›Ì?<âé§\ôò¯=þ¢›6ÿUý‰· üêKoþ‡þOîù« ^ðÚG}ûêo¾<»îÓ'¿ûü»ßÿÅo¹¹ä‘/~éç~õ”;.þÆ«o¼{‡ó×ÿõÚl½wÍ_ýìŽ÷U_¿êÇ=/{݇^úÞ+¿|ì™}󫮸>òƒüö«~ù¡ ξ¼öš¿»è¦«Þýí×þ÷u7âÙ;6:£g®¸ñç§~ã§¼úæß®ûîÅ]ºòßßýÊoýÅ›þéwÿWðÁûþû÷¹åi?˜ºøª+ÎÿÞ†›¾~ß?Î_ùüWí~ýBú§·}á '?ø‰‘_Þòã__uëŸÞ6ÐuQúŠÆ>²8÷ÃÑ·­|zêêo¾pzbï‹îÝÞó“—týç'â_ÿÆ?z楽wÜyÿ{Õcw¼ùOn:çUOûùï¹ô¿yWêEO}äÜ›?sê÷ÞvÁ½¥·ì]éýÑíOÝô'úì™Çn¸ë7_ÿõ§®xå‹Ï¹ã«_ø]׊“üÞ©CϾì¹Oºìyw>óŽw\rfñ¹wœ¾÷7Ýñ™ën;ãIOÜñõ¡¾õ©ÿzû¿}xâIO¾züoŸ÷ôkÖÌ®®Ôß»óý§Œï;síïŸ5Ÿºþ”×Ïì¹âúÛ×>þ¶ nÛøË;‡^ñô?ù—ä¾½dÅß{ƃó×ÿalß Þ:ñÛ—]wñûNZûÃß¾ã‡Þ×›þä cwýà­ß;ï‚/×ÍÿòGg}ä£ÃŸ{è╸üƒ—ýѺøÞáÞË_œ}äM¥ŸÍïü›sOøàc^Ê{&¿rÆõ¯¬¼â›—ŸòÍ©™‡¾rïÇ~ZðýŸø—wñŒ Ëÿç§ö¼2µ0ýº§nºù–Ëÿ¼¼ùO|Á¯ïzõ›¾™Z{òƒï¿ðd÷Ÿ¿¸óþô“žvè7w]R}Ícÿüš›7W.ÙÜóÕôŽï¿¬˜þÍyÍù§¾÷«ŸÙøÐ¾ÿ¹û|û{ŸyÃ[þõ¾Ë÷¿õý¿»gèãþ—WÜøÎõû^öÁƒîe–ð>¼þ+“ÿòÔ_.L½ø —ßúÇlþháŒòy§>éþ¿~û?ý_/­{Þ7îúÎ7žý®·þóŸúñíŸþþCÿüØWüü#~÷ùœ¾ñ§_X|áOçn8xñ®ó&~tæÏ·løüÙñ½à¯>0ñÍÔÇžyÕ¯ýœó„-å÷®zÝ¿~sè÷_˜;ûô § nøÍåw-~w._üæû^þÍë»þýÉzRõÂÍÿÚÿʼh÷3?’½á'_{¯ßÁäŒúô'V]ýõG§N)WNy`ÿ[S×÷ÿÝ}ë¯L¿î¶må ¼õyÏŸýÎÊÓ÷Ü^¾âêwæžõ7wþü‹¸¡ÿ¬«Þÿ†ç]ö™¯ýÇþk¯{^áIÞô¾þdü ?yÛ{Ÿ²êÚßrmåõ|éÿüÛåõ·¿úœÒoù×?õ¥•Ÿÿä¯ûäžÁ^:ñö_Ÿþ‘3·~õ¡Áߎ{ߨQõ¾Uyóžô”?¼ù†zþ딟>£üÚ?ºõU½ÿxKðÙ>jÿúCû¿ø›;ÿáÙ{ßQ¿ñ±¯úË®{?}fÖ½/xåå'½ð©ïJ}ääË~vÞ=¯¹.¹íÐ_ú[¾³þe¿pï¼³~ÒÔ­_;P½åQß¹õ”ç~ñ‘] Þ—oùõßݽpÒI‹ƒg>nðÊo½}ï›n÷gpå»6~òоæ¿þˆ“÷募ÿPí¶ž7ÝúšuƒÏýÙ=OùÆ3¿·ùÿö´ó˜üø‡Û¿zà’gw]ö/·¾üÁ/¾dë~÷½~þÚ[ï>öÀÓ^øêï>°þ¾mÿùÚKÒ7}üW7½óç”/{Ò'ÿæÇ8ó§çÒ'ýî‹}Ï©·üç³v¯þÜs/ª=õëwç>õš_\½ëãŸýÎÍÿïÇÿ|NòÕ/ûʩןvý¾“>öôuïøÑçïÿÈùw¿í¦}ô;w7¾é·û÷¯Ýñý“>÷ø“×>ëì÷S\<ûƯ_yç·ýú;ùîwßüÆäK?û¥Ç<ðÊ.ûü?ÝÿÖ7_ûño}çÂú“¿8˜ûÕ£Ò•¹5Ï|Ñá+Ò·žtýã_ýÁ¿}Î^x²mdçÖΚxQGc·¼ÿ$NåÑþhOÿ×Û;hÆÿ¯èìèÿŽÅ?iÊ+ûÓ`Ùm{¸©ý\' úca­1žJÐZë›JVyÍ-(áƒÀSÛ%“OŽÛ|BÃc\‚_ór9Ú]ØãSS@4æ+©šþä¥^¡¾½·QÄÖqxY‘ªízóì$¶;›"˜x0«V»50«qà-­!Nµ[íŒÌ_Eš´J^{Á/ûùb|ñŠ_—ædµUŨg>«]ø¬Ô{ºZ¤>èg‰®ð ·Ãuumc%30´u97Úíádì-û…|Ù[çU2 h$ íãfž.ž kç5JÓB˜dœ9Xó¼<;|9± Fþ–ØÙᓞËxŒ™Yj]ÆÓùY/¨æ žùb7 êφÑ(0ž*Ø_æH´‹r]ÔN}÷|wžíDó!Çâ‰Ìt.-\ õR™­øœ@ü “ [¯W M¬ùbcëj«}RbÁÀ¶WS® T´vû Û†ÌM±‹û1G>š½Œõ5Ï¥» ЯQþB{‰¥YRçÚßZkn« ´\ÜGæ¯ybxÏÞûÞÊþŠ?_‘¹§ì¯wUm[¿”À¡öþ/(Õg¨>èÒÕ#e þ,;á€ðJ…yîëj˜™‰å?¾O%N_°Ž§ÓÍ¡3 ¦ IDf!“ÿYÛ¶©$BnÒ.ŸþÂÚ;Ë/.Ø áõM[¾é´Ù[;ýú@IzѳBÃ/ÏY»©MJChÌú³s7èRó%\½HiÑzˆÖAª·Žn<­ƒkíôÂ6È–óRP^™êƒOŸö’Ǹ;/ggR9KYvœ"Oi—Dw‚<îedzé{åxtÖ³7ZgÌcìÛ=ÄÝ4/¤t1J¹#}ÔJ…:€˜û•©Òt£f#Ë{Øw Ø÷ “'*WCô:<Ò-^ÁØ“€]8[ŽŒå†aés”-£—Á´a…kHÊŤã±5/ŽÝ²paÆ…;9¢˜'V‰ì$}KB–väÛ,”‹šÏ ’9¼}yÅÙ+Õ}ÏÆ ND3ÖO}·ÅÆ(õƒ4æê  —þùÕ0¶]æ’W[J›²n¤U„oÖéB-m…õW–[x”5>¥×’`–†§-²¿j6» )‚ýëÂÌœ ˆ«2_´¬ÄÒr¥:åbI´Ùvnþœ)"7¯RÏ•=À~fWZΟj·ZÁ÷j¯ÝÒT¼Ý☠¤¼°Ä!Í6ê|™‰À…rÃÐF4­'²o¶[¾æM39´ÝÒ”a®iiBúÎa‚¶%|éœ_ËUØ5­·7…¦£x=Þô¿{{”tÀÍõ¿}àîièûû;úßc«ÿ¥M€IÁÁÜÐ`ucv”0wy)àÉ/KäÀ®#ö_ÔGaUÈû %õ£&2öX©OýU’9\øš˜¸ªÙ‹+ašGJ¶"ƒ«3àµÃd”²*d²„õ² é‚RÕãéø÷‚oøÎ¼‡ jáä§ íL碙÷Ø'‡$[Úðå ËXÿ\Ü5úã)è`%`4§ Ï “I¯>I ‰×ç}¬™S ïPMQˆBƒ˜˜AÖ€ÇÄ;óOAæ¦@K'ûГ©fqßaF†´²S=g†4ilsi15ã`ú ø ž'‰ëà³²>f[p×­›ŸŸÏ@TÑ/d /ŽR2 òd‚Àæ®Ý=2¦éЖ˜íñ¤W™KÉE†S‘ *…™š_)]æ9Å·tF¥ì!ÉàGYT‚fV¨íheˆàÊZ¥Í¢Dœg‹æºPÛÔ }T¢ÇŒ9`­£$¤¥è.äƒ[áÍ)­I|–¤ S¸}”Ƨè›eØÓÍJvËR¨ºÈ$jb4êõsÊÛÌ~o!Èpò¸9éòÞRÎfg…µBXûtØf©5ÂåôʧŒ£y<·q80«¬¶8°6ü¤“É¢ã4|\5ÔUñR_$á?G¸Aä÷£ë.Ó¤eÐU‘Ò´Kãâíqš©Îšhkf6_M®réu*3UuLŶ"#¼äC¢œ3<Õô\©·ŒLÁ\¡ÚxºÃ‡ÒûT!Cä{Ê8¨Š ðŒñ°Ã¥N@R¼F5UYK|3@ ™d>RO$UJ®¦<Ëigþ~zÎÖì¤+Ø\aiÛ™—ÈWôýL!y“¼UY<7ÍdíŠZž·‚ó?èš<i‚ÚZÞZ‘mIó Ë"SR'#VO2ÆÍ+Ÿ“¹}ú#S(3‘ªi?âÐIL—-†Öýj¹IDU¼7ôjÜŸì ç0Ì ]²¥nÈß[ÍOCN:ȯfߖ顿+ÀAºR… ;g µ”ÖäýKç c9'ø]eR!ù>™}t–!E „ò7¥µagk”e¶s>‘¬ÛYS,­ÝÎYÀ«ÒMOÐ]Í3-"Ó¦2kSSj“ØÕMk#ônÝ’ãL’Ó0ÿ5„9Ӻў`ŒèbÅžÙBÃÔ&DÓB–¢Iá–gR{=—'#MŽò¢9°ks/ñŒWÎ9C›Õö•ø£C‘O™™õ¸±’|LRÊßdø¾Xa<žbŒ Ÿ™¬ÔMIh½+"&¹!Æx4 ä™ÒAÙ›‡|qìjž` X¸næ…Í>;drÜŽÈZ`¼7›)ze¯î%ù¥æfW˜‰]÷ÂÜðÐèðÐÖ‘”¸tĽ¯µcNiÔŸõÄtÌäHŒ›$¦{ìïéç)Ç]¤„ÄŒo „m)HÆØ¿ÂL¸wp˜Ç•Dª|À.díš…Ýœå…k‡i€œ„ÃŒ›WU]vãf™vV"wL"í€'M$<ö”¼  ìà!X2"ó¶ÊàWÀjLajE1r3.HŸ`5Ã?Z7¯Ì¦Àb)¹‘'ée¦3î7h‰ˆµ„À3)† »óôL]a¡M‘á-òLhxLk°¯¡ v5ÖÙÙŒäÝãÊÎjZd2_£(Ö£îp532«`ˆÿg씺_\9n-˜4Ø Jé#æ —:Î- ²‘-e‘µYßYµê0jÁl¢“Œ«†¬9¨&U¸’nÈ ¬§>mÞßLXɯ•¦KÍúâëK3϶SrãFeDHAošT;&»ºŽõΰLe“sÚ|òœ‘1g÷^öÿ»FÇœ­#ÛGÆFœÝCcÃç:+ÎáÄéx\C!™N¬N´¦A7Kàóžš_´æ ù´è$ S¼@ºù#v?xç/t…l:c¡JŒÞ”É]zXH5Ýæ<È¡´¾è&ËȦ¶–ˆmUš Z‡YRùŠÏû•D‡öÕ°¨lEé•Þi66ÑOÌ8vFºxþ@iÁ_+Ý+oÕÃ’—\`ª4­’GðMümø‘´bùdÅù_™bCÛšŽà[ßyE)3m Ô)­h§päì *ì<¼Ÿ*áF³×c{YïT“šärœ‹ÜZ¯%MKr›#³qã&ÃO£1f%®HÔr,ºÝ¡CK]9qÌO&6‘$aÞǸ+n[êÚ«ÀxŠ@S4uœý#Hã½Ü§tóN£vÍi¤µèj¿ô± hH ·³—SZ‘&‹WŠ1ÄÌŒÎái¬Q„‹2DŒ.Aªm¹y[H¤Ýû X!®Ñæe€j6=>­´YÍq6ÕÕ«£“µpTí\)g­ÙG“7Ê<ªö½×?nÝð]ºTÀ² ãÍVë ›M©žõåJ°”DfÃå³´áÚÚÖTÙ\½©˜·-yNÚ*¥éŠÏ wÊ%Pˆ¸b§@†<Î7#뾊-i‚‚í½Q’«ršªÐ/Å[ö©Û–h,ÕsaÛ¥ FvÜZ3ǘXÆEƱÔz‘ŽJ^¹Øî(d3iuRK­-‘¶-ã‘îà1DŽbe³KË-£ð(¶=Ã[nç[+--ý;Û*/ñ[)M¤•±§ W¿0܉éÿ³n†¼,—Ù¨Uþ÷(þ÷À†õü×còÏðóÑ]lDh•æ…ló»á%\t^§’p‚‚Ž‚`+üÿÞAóü3 Ð9ÿÛùW#@íÖF¾YE¹¹%`g<y!Ù.råÈ“\ËÚÈš'öŸÔÇÂÝIBŒèyÞ‚•nX(N˜DV ¬×I]ªMeßãêàT°ß[H;9êRŸÐ8js7‘,î,¶%UÊ ÿòç)¹üæ$΀²ƒÞ¹¬WüËåBU16]"©`„u>.™¯àf»´Cý«6[‡ñl*˜K ¬¦­Î¦¤2Ë&u/¡/ V,j§ž`Q ÿ‹-ê¶ÐÞi5¹q–†¹z5cü¥$ÊRð”kEøš'¨^1‘v¼ÕR åÆJlœùz²'¥I!á*D¤Šù† é1(%ðVüßààz“þ÷ ötèÿ1õÿŽÀ:T ^­õ7âìD𬌔³K Ss]v2 gðªä*»šð›Ñˆ4[)3TÏZƛׄÃmR"“g+dÁ³–T‚ñŽ"‘ÑÏA¬Ø²RVù?"ç°¯¯Ãÿç¿Û9 ý2…kƒG^¬E‡üMÐÉ£o=9Z` Ûdin?œ big‹M¤y«ü…â¿9ÎHTL}¬û EÝBQîÓ/¶´šÃƒ0¦|Р0àÄÕšéÍÈ¡ñ'}Û˜øËõGõ4ÍñÇýËxù»VED•ÀEAQgBÐhÝ«NÚÀ¹ :~¥¼àÌä«U¯Â]ÆyNÐ(<¯È¨ø÷2iáái ÁäE' =ìÐ̪g3LÝz¹Ã2ß"áÐõjÒ“w‹§ÂÜ+5yU‰­z“'HF¼xU¿ué%št©tv,N¿mÌ€¶X¸‰' (.ùèN§|¿¦Ÿæh·²Q–6uûÙl”†xÜ 7 éQwJkêWÂo£ÏËÜÿíNˬw„³‚§Ú(ÙÙ œZ£bí’†hWT;N…ãþW÷²ñ­øÿþHüç†ÞþÎý"ñÿ66º­+¦ÙÍa»~ {! ”Â^DTœ§ôXÈ5¶ü €çpý†SþïëØý¯ýt+‡¥é™ c,ѧYÍ\Çà *Œ(„—)0ySJ¡®pCÝÎŒ1Òj,Se:>œƒhÖš'ÀhƒUìÝ_-ìÌl_èÇA#›åÑÕšÏÄü:h°ü 5ÍÄFO=OzZà]õ¢u•qA._VfEýÉnÝ¢W‡$„rjàI•þ*?é7ê1s‹4dzølhŠˆÂL8Rfœ 8S–Ë iœ›˜26­€ñâ¥<~§ jnÂaTûM5™ 岕Þz#ø3Ëy.|EnDL,lT!\饕 ˜j”Q ¢Âfœ/(W‰¥O=Î#ÇæŒØˆôß,›»€âG.bTš´}µ0ä&MÞûlÌ¥›q<|ˆta¹¯HQÕñ£O_T¾¥Œ˜ÆM“Ó:Eíàôj Þ“mväÉ%>'ÎD<ÃúÜá6(…‹‡m¡O±¿ø n•p{„:À3D o²Y&LRDºRa¸)ìÇ94åÐyɈO ƒÊ¥šYgwñAÙ–ËHʤÁâg˜‘ 1Ä2²¡Wkl®bÆÙÁ$Æ(`Q S ^&ãy«Å´I&wmDJk¶4œ$™Ó”åtÕµÖiš:„Û0ºoº¬áMË¡ÓJÉÜÂ$þ—[2ãºì{f“>ޤk¨^‚`âk¥Ù¹ˆ©9Ž5-ª‘r„ã½”¦¬'"6ôãs1«›ê:üÑ)EÀ-µi¢³'t'Ðvg~¦Än/yr!Šl¹Èå(×áZq2n6cì…àˆ1î@¦˜'¶Ö`4Ö,÷nžh†8ë¤F´­a¾kÅxH<šñ.dãaxç/o1 +Ø×ôO ¥ 4"´n~ç$WçkÓ.ɾ1H­¥Q~Ú §coø„ÔÄò?ÿôÇØÿs ¿/âÿÙÛÁ;~äÿs5ŠÐíŒ"À¢Ì•Š &±òð/ˆ¥ôÅóæBÙÙ)ºä! ™1-“€}Åî•ÞR©$ܲ›¯iË%½ßSc1¡Ìf^¼´TW$Çå/Äe"Þ§â.Ô-|&FÜn”’8$ºÈ©Íر"cžÿ‡Áÿ»°§7rþû:çÿÒÿëî1Í5ÿËj[M#íZiá&=‡òü :%p—Hê$8#âòNPª7$€øÃ@…!¼Q'QªÌ1F°ˆ†ßw»T'BÒ'—êÜ€D¼:ÊsùR$:1¶2=ÚE^}HÚèŒÖ™p‘¯1]Ôú¥²%4ß;㣠³“~9‹ Oø„1ä|<t c–ŠONÌD±ØÌ&Æ9…=p‚(%ˆ!ñµ¸¾ -|iü9¯V+½6h÷¹Pý ª~@H »šF¨Œ+€Ð0>ñ‹ ŠÂ˜ÐšŒƒ×¨ÒOÜ‚G¾â %M ¡H”A´$.[>.2‘*íñÑðv8GEIJ†D|‹VÇÁoLîë:»Y r>?›:[lZ{:ÈÚ8 .ãò«ì4c—ñI1v£R/• ºªé…l6„¹Dö$cÐóÈvpÍ’iίÅ5jèélÆB-m’ßOH¨ãiqªs„&š o* Ù"Ào>:Žˆ¡I+ Q‹áõÞ²µ ?ÇÞšmfØY¯ë ½Ø,è)vŠYBÁŠŒÂm=RµóZ¾0β6 ¸<•db¬V"T…zˆFˆWÄ´aèå ~™.õLBpMM:, f“pgHñ–ál½ÌH£ð§)=é[ØgÙ¥Éw4e©ˆègÔEy.:˜™ 1,·¡hìA6Lá01lëæPIG}þ÷LØù!Ü<è˜i0I^´&õ^Í—jb-ØWJ“¢‰ýiöÅNR£^mÔ9¥ÜEäÿVšZ€]C n›íå×ÂlW¤=ôÂÓ½ÂMÉ#8Н†P«Ôf*Ú¬Ïx8DJSr6‘âÖ¢txì¸ÜA½â`’¢—òp“A(õxâ¨Síu%w™Ñ§²Ó°eù>ÕVÑ-ûOŸY[mŠ‚ècûÇÚ@•,D”{>Ô›Jê‘å‘£CŒ `Äùh‰‰u$Ia÷{ÈAI‡BÈA‚˜£„çÈSpò¶Žñâà¤zUÒ:ɆBbiñƒ¬kÌK­[ŒhM´QÝwr ³µ âùÕH’ 9Œ ”ô¶¸V—2®f1Án¦ÃŒmgÂ~îæ:•gû˜_Ù:xŠÎçáSÀ7g%øæ‰Ä×nãkê¾ü®O][V†™]_ò3Š$L!3$C®ä-¦D1I/¨d*(›`ã‘$$ àa÷îÑÜAxQådÍ…¯s¨®ÎíÙ3 ^]ÖÜ^à.–‚j9¿€L.⼓Ÿt—b  u’pNUF9Ky3q»š¿½RaÎâ!x4SßÇkÊäŒo«Ô½i¯F~¼è:Jo†}è< çhü;‡sÈñ4CÎ@O4-½XnE’&-ºäŠqaR58JäÕ©d’Wy ¨¡eD !¯ÏÔüyÇõˆ5âãpc@®Ú§—°)v'¤"“– x–ò èrµrì'bïôÏÀ}v 5”iAP –x„àtˆÎ­mÿçV½Úl¾‚ü_2"-+Bš¨°Nž–åö"B$˜ƒ$—d³M;r.õœÆ T.m…Õ«u?LÃ^çDG›ð§ê ÛS.D¾]Ö÷ôª eÔv€?_‰Ê\‰/U³LØ,†íì>ÈF¿˜Y©:”¦T¢`"ð²$é É$àɺÞLoTGÇÀF.Ó¨B&gÅ&'¤×6ÙõM';8ÏË ~ÓrÒlÈu™Qôºu’ž­«¾Ã_WÆ TýZ¾VŠ[W…™áΉí>¥€H¤áÄ(°;af\'^dë…+UÚÞÑh;ÃàÞ¢x²„ôOW rínI=Ç,ÔS¹GeøŠØªvB#v9Ä-A¯BØk8û¤0j%® 'ã¸Ý©¥EØ¥ Þž™•BFP ˆ\wô¢gíÚžÛ•Û;šÞµuÄÈ-Áé­ªù—“Ðpð!ºòEêà\ø*Z²Í=LħhýEv<·•ø2¶>|J ìÈ~ÔWãËû4ŠÓ¤&!ëV6\LÆG™‚ë›  ¯§§«…Ò×Ó¿)YoQ“"ô¢vƒº£[É? œ'Ú—ŠSzŒhÇO‚:ó#½Ž´–2<éI»—{ªŒ˜û–Ùx×α‘c¹±‹v ÓY¬{w3kÝL¶Y²Eþ8Ïá»ZƽHd1Ȱ@‚¸?`ì KiY`-  ½¤‹©ìBšÆ,ª;lVoßz;d–Ôz* pß;۱Ĵ9 \îE—‰ÉðÉ‘|AH!6üNÔÎ@û‘ ìt%äz_©=_ÉÄžùÊrXáØûµéL½AÄŒ`¿“í†2 -±Åˆ²À“ f©”HDo}•¸x–j-UÚ·c›©\*”ê2™)hùù1oësˆ]V*š_ƒÚËUüoOÿ& ŸˆøÄÖß„C¶¯ëí£i€vú_G.zåJÓµ÷l]C\jõ,q§çÁÈV×–Kû=±„ U#;:g³ÿŒb^,J,—Ìd2©öv/Ö§ÝË— à,O](øÝ"*)ýHXR9 ¨šãÛ”ÓåQ¯6Êö'üŽ ÛHMÊö)/®ž@麲›”qvV¨ÃÛY*ë™ íA_âꄦ®®úéÌ`¯½eyáú(ãWØÝ£…y-aFf¢VãO©é–Û:±›’rª¡ª&nWn›Ghív¯2]§¸±Z¾L±e©0®£äjŒ¤—ó•ýN2?ëKjÎöEO©0½1%J¶Òà±[AhU40Òøf•ýÁÎ UŽœz|$g†·ÀO Ë+:q§§[á(æÉ²?¹î9Ïé{Îú©|ïúâ郅bÿé=}½ƒë{¦ …þÉâ@¾PxNј,Ö¯'¬Æ“©M厼z~:ì…d!X;b¡¾ƒ‡¢Š¢PdOÅ”Îf¼µÐdÍ/CB™Š¿¶Ï°ÖûKÕÀËO‹¼! DL¾­PzȽ֨‚ëq¥Ž7¤v©Ö§j6¿CˆáÃã©v0¨¤ÉGÍC(Rzë¼G^¼Bøâ)¤pÑ)CÕˆ‘Ü2é0W‚N¸ zœà:&žDxµn¾ˆiŠÙJL•0B¾Q÷!oSµåUâZ†ëUæJl=fÕ‹8æÒRM™ƒ§¨I¶$˜“*¬àr^>Àéý0Ñ€q~á”0”B¢!ehèq ’‘NÂRâÏÃèéÀ>Íe·ÐëXú—ŠY…V…i«\ÐKóÈmö‘™¨ÌªšóÅÙRÅÕœ3øl³•ÄðLÕ03b.´ÒÃsvzl´g:½`‰†Þ:;‘u¡†[¦¶.Åš™×šý”F;Ùš-|„Y­ÅŽ‚`¼U *t†•mU†awq¶5Ý<»AƘ«?slW€y8IóS€•Àd¿®ø7ð #L“¡–òøÚçy$,ê ÃŽºššþ°œÞŒ,©¶ ¾N|X†Jj©«©12~jùšœi¾Z¤tw~=>’+ÒX’ÄtHñPsnq×˦"ZØpm¤ú=5Á$N5¶GJÐ(vÔ{%wöE‘]s¬+lˆŠâÌ(O„üÁ7'],›j6}Òþдcç«~ \-½d³@iJ¬¥’[á?Å銩“l‹""JÆJчLˆ­…v¯ŒPÐá$ÔhÈw”°©P*Q«Ü9{†väöìÚ;¶mç9¹¡=çŒfÇ)wwfnµÔ ÕA)6R†ã4øÅA¤‚’‡8{ÜÖ¥;Ÿ…rm˜SX¤V3"Côá xÕŸÝü“ë"¾ÄÌÂð±ðÇh™ ÁL„¦P„Ò„Y‰R=P®Üû´~šZ˜ˆžïÂÿ%ûÖ|Eš›ªâÑnи9Ž‚G â‹&˜êuÞ¼¨£RQØ.ԑဇ~Ÿ Ú8¦Ø ¥î¡öè~Ì¥a’˜ŽBþMzòYKUªMv˜>¤‡ç®id©Ö=p~I«Ëxj»÷Ó¨9xëI鑸7žT:¡"rl„\.Ó(Ô~S’¹+2û›ßbíÝ8zß8pîá/‰ »âa‹ÛÓÀP' w¿ í©ú <0>óÁ€¯¨$“–`ò%¶šÝþ¦Ü‘ìþ—ígãq"iƒ¦ØF0“œ.¤ÂO§¥‘ÓF[ÍŠ•±XæÆ9 á’2ˆw•:’THžl‘sŧ(}è —S°ˆjF%Ò‰¶5î?¢P+Ó–jFAF"G@i0Æ?@š0”ˆZ]Jœ¨Áe€ åPÈ «š ®¡+qûœ¤ ”Т@»–BK’¡mç=À–É ¤Øéνæ(.Xô Õ‰Í$ ›&© €4k—°NK>¨û”~Î#÷½pMðfQщU · !ÙÉ%GÇŸƒœ,*Éc]w R¤,rs._{u=0ƒŠdyùík­:8eœa=9ïŒiE&q©§šl·l`ª2+ÔX[f@—@}í<û|0é èN…7>‘i¶WDÖ—¸eÎÌF&Éšª–ódK_ƒUÖtiÒ4'FQHÀÖ‰Xvöåz °,óàŒ‹âFRš9ÝK®»ƒW…ŸÃøej‹¡‡!¹³Õ¬ÈÌŠF†%o$±Pw._+åyŒrœb×/ÆhÚ$r©+úò>ÖOU|[ä)Õäâ~Ü´DÿÀ“Y ä•×ßì’„%ÑPr5ž©¨NÖ¯•¦stÀ7ÑAÏÊŒht©ÂPøÎ”„xaµ,ì¸ëž'I8+]‚JòŸYgÑìnËtÍoTC—Ý{è©æNF ! Îj¤8ñœ j9¶-r‚TR†ž IsBw*t…‰O…ÀoM/'Ù#^›ê…ëªÆþ«ðÕ›èEªd¸æ²àT5‚ÈŒúHµzD)©‰0ðY§Û”Ç,Ù#îIÀêû)¹$ìïaŠU?F{ï’M|_¨È‚KÜ[ÝNaƃ„cÐ,˜ÔÞ„4žª(»‘f±jU®2‰ö‚÷Áë—øå|t4Ì2º_c^¥y\›®’±-í­HÉÌÒwÆŽÿ28¥Íæ£f:i}èŽÃsFägYNGô/ø³³åIî>´E¬ÇmùŽÜO±Ç&Ž_O_9Ifa}>¥;ŽP!ÄÒ‰ÐîH‹7ºé¯ënÆW °V½1ñ…•YÍ6êˆ$–C&;`#às ç&jÉÝ@uD HµwÓrÁðÍÉ¿µ³˜²G?ÇXÃõ¸ËxëŠ!›Ñª_•÷’c½äü©Ös×Ë™3î®ì®ëèN=_Ïa7mÏݨpt&"…WB¹$1eℱ˧LÞô°By%Uë’æ_.çüZ®ÒöôµòË;û­B's„º‚W±dÁ¥W)"ž•gÙ/ ‘ˆ½‚r²jÎb‹ úí ²õV’¢?ë"$Œ/â«°«Üÿƒ_W¦£øfÇߣ˜¥fw8ü)’L'P)FQN²²@^ÖrÙ(v4q8|Ò¡ ÝvDÚ¸z±Äž³BÂò?é9,àÝÇÙ&nDà#ÐmŒ÷`(ül·Ð×,þRvxÜÍj+–\]e¶Ïkà͉—éL žh»ut C@$ pέ”½Ãµ–h[æ—Òr$t‹lÑžJÓD€ Ïå‘•é»ÑìÂó(þGͱ³Å„:Æ4ÒÒàBâ,ªž¹Þ ^ЀÝ?‰ÉÑý@u8™GQ€Õ©2¨±a¾Šß¯é.ÃË…ÐUÚ•å&KòRÂTS¢Îæ«‚¥x²^N5a&™#ØvÅ¢${F(ŠÒ‡W¶´Ál2;Ä£éoœ7”5L‚Ÿ›¯9œª¥ª¶‚ÈF‹ 'o| Lsšš4«›‹Tk¥9ËÒ>H8ñÐhÊ’õr(i°³JËwÞ">Vä?ŒšÇ«§’îÿ#ðÏ‚Àòx5÷ÿéèëÙ`æÿØÐÛÉÿw"ùÿî¡#ðe'àQ¡žñB$S´fJÒ1´{["XzR:géË'ÜK¿ÂUéõõ 'É[KeÌÔZ0K}`²#Þ]$B ˆZª–vÂ&Pïb} 2˜*Ï Ð=Ö½S]ƒÃŸ;àP˜-ãÿ °‹¦^Ð'߯¤yÚ8z“iM[Ë2˜Ó¥Ñ*0CâCv²0^ׂvúÓ‚eÝ´äáùÙâqFÀÈÂp˜Ã=fˆyaßž-Ízª=„ohö4ÇUw* a0Yƒ¬ÅY&^£¶ƒ5<†ú3ƪ†m…™ÒDÇ­3àiã²|0ÊæšfßkúÙSí$¹ 7¸ôõ—_…{p¨p‘¶- žÚê”ÔÕõtqÖå·XZûdÊjÄ4Øj&hÂk= *f™½h9*Ö|ôfS±C9~vBiœ³¤¶NUß‚ˆˆbú®R_‡¸gm^Ñd:’>b©D#vµ{bZnë`HHueyu²Â¨ëU’’•&-C¸8ŒÉ?8¦Al¿H"Ų‡ƒÝÃ[èj+’ߺ³`[J=‹ Ôe¦3®™£¡N»ʬPB |X7W)ffƒµàxPNhßLC±E(% {¶=’,RšÓuðZ}rCå²’47ÛbÇ¥a%Óá#ïhª5 NˆOÔFÖ­0|@ÑO;lŽ A 47ÒPÜ A3JÄÁµÑtbØv–’[€(€‰aý °² Oªll‘ŠÎt§Oð«Êt*r€BÝ5š›Èÿ ½¢ÂÍB9Ì!ÖA~†Œu\ZFï‘^¡êVúÍÚ#—]C4hot9B ·Ëðïå£k¨ùHx}ë'Ô%º“Œp€ÆÞ“y'|Vª¨-K…D»óÏ4&åÅ"oNy vbê–Ø·pv×üB–¯[MYRÈ<Û|EÉ1ÛøÆ"÷B ø!D"}"pi{4.ÎP€ï·6¿ËaÈú¥-†ÏÑþª~UgUâ³#«uõ$ÀQ R06’ šð¼ ¶Ã=?é×g8Ž”pà«ùnáÙÈÕ0I fÀ;bÔh~Ž"ÿ…ë-5ÇpTÛb"ùçdÅÓ<¥aËJHr¼"fZŒ7ò qám‘ )ÆÑ¤¬dvm! ò©pqØ`1Gƒä1#GÛd8E&ê6ÂRºú2š<§•MeÄ*ðr`ð˵¨­u¥DöKÉ1i“N£cÜ8~:Ðÿt±¿9ðD~鬳Ø<ÊÊ-òáJ×d ˜Y%ˆÈz˜Ç.C±Uu#BT#¼Ëp¶UøFŠl©9{Rª!‰÷PSØe@£Ô-º]æ)ƒVÅ J³òž®ÎÏDM7gmt~ ¬‹œ?Bº¦9d+¹tVk,ÓBH‡³*Ⱥ¥Æ[U!]y £Þ<ú#¨u±³Ó„ùÙé‹HÂFi±wÚØâ]àÒjÀMª øÀX[¶CäÊ”äq 0æMÁO[NkœVƒ>Eà§ØKÈíˆå˜ØÅñ ñ»Ã÷æo”¿ÒÒdc?ìvIƒÂ“ÇéÇ Ë0!û›À=ÕÔ6—ÏŸ ¤B™JqR? ü6DÑÝbcápÍ&Ãűìub˜˜2V«& V‘¸R]À†B¼ÞÙ~M¢¢ªNuºä¯\àü çD" ø1´JCÎKkkÍ„[½é&¬€ºvÄz›G2铊áA(ml•ƒ´ÚÁ#-«•JSêÏŒŒ_ô§¢,[´ºö›µÂ–Áž_&’IÁ†K¨û ÚßbvÙI¢ÓŸt˜ÈÊVÉ…ÿ¸¸ìû-3`+ûþCOÏúŽý÷D²ÿÒÆiËf_ĬQÂWÂ?¤x¬šÝŠš÷µ…þ Jâu\ö¦ó…ÿ›±p;Z0Ž"½Ab®/ÑŠE„œ…6&ñ d±rD1_Ï'ÛÔué÷ZnÑ/ë™V ®ï(óÙ.;ªdÖm­ÛÈWtDûªµ¬¸³…DFQèÚï DDç@Þ ^1ÇG*;äîc]K2Ïîc+á׈¯á’µ¡HžàòL$Œ§Z¡s$sØ€‘Š}‹26ùç!ËØ»Ì,ƒ±‡‡…‰¤M؆&ºÞ]Ú2‚ÔÛ°H¯‘Bƹ&£[(ªí±ŠúG>™%O¥I‚F]¾—_u|‚Y ŸjÑ2†X/1=ÃÞ=ÛAŽš*@© åq6j„•§[œ±\’o×FÝä¨Nš7«rÈ­ä< {Ž‘o'?5ú€ha«XFdé/½»Qôt„˜ôÓ”¦k"˜€‰…QÍŽ]jR­Œ¦D–×W ÌK_òÚUL×6ÒÕê÷w2R«‰ÄVý°)©Â¹#C[ŞĉA)ù[©Ðma~޵’£D@hV´a÷2ë˜z=ûHuÍ{×nȃ6ÚdLÞΰ|»Æ1b.Ÿ…5Iü¯vé qŠ?ÏÄô‹Òyëhéà“ž«æKµhSùŽœÖ«Õ4fqÓ={ÙáAU`“g'žFh6kG‚¥’Mqˇ•ÃDrÒ]Ø7ðlû8hKðu2z:ØoݯæÐz(:²áAÚPÑņ¿º,MòÑ‹ƒ¤e:¢¯-šu`¶® 3ùÊ´·ÂT1[žFt¹’äF æÀƒGÁ×*v€ió# #˘ ÆÑ˜ï`\üo::|þc>×¶>Ȱ‹pƯñ„ê΢YžÑüù|­˜c§²ÀºZÑÎfJYqÀ+OiÏÛ%b» Ïé¡0+øÓ¶ Uþq’ìý¤±Ô.)›ŽŽägoïój“Yg—§ˆÙ½9©`û¨èr”,3Ð \9#¬ð©&¸2“L¸ œ;Þ@&:ø˜AÇ¢…rïºö”_xly§A“ RJžpVs¹e«)‹*`6˜•Ú[°f÷)£ƒ3»B)«l‚0ï×ÊÅæÒ‰ñ[fñIJAZ±MÎ8£½Ù´¾Ã:/ÚîZñÙ79‰Õ øTòÁ&c«Œ)¶G¤‹V2š Ó`˨×;Ù:xRyÜPXL“v¶X+NJ˜÷qráÜD÷ 0žÒž²´Óü«Ä“pŽŸå¬”ûv¥…#ŽßCãx[øµ"€,ò\`ï2ÌF… Ú¬½ ·BÁÃO1 d±€ .ðŒÓÉ´j9¬2iºR¥…[)¬‡<Ü`Þ™y¬_~k (ÅŸÓF‘GJÈÉóFÚ541l0ib•2“ùZŒJ¦["©Xw.Ï»ìûëXÕ%ªi€Ëq%it\²iE{µ¥òlóÅ*Z«ØÆ™+ù ,“SÁË69[¬/ŒV¶ÄÕNƼ‰ÒE…7¡¤¦ì s6M‰X#‹—«Õ¦ìú¨¬8 FZ xM‡íIì"5ÿÍô¦>%õ¥>D†æ¨5”.šÏ8ÕRƒ2eUã­ - ±%8yQÞ« ”:ðRDá2QæFuÙÂé x±åª”3 E Ûgý9„#”‘¼Öžð^£7+l×+^SÉU®V0eÚ&-+rD€¦ú²Yµ¯-!ßd¶+3›)yDM÷y~£TØ_VP2ÃXcøQcĵX­$îÌ'ÔDcœ  ¸‡°#äòKÁŒÙÔz¿Ç›öT³¼•'Sf¥¨yÓ Vl¥lÍP 2y/S4²Ò/€v±Uñê–D§wÚš"GõÝEëÇQ=ªÐ„øþÙ'ŒÝ).æöj*Ϩ)´µRÜ€Kèmè< X8’½|µDÜu>X€‡ñµ!ð09 w¢ù@ZuŠ`²é›’+ÝîƒØòâÊ&ì’±¿ET³¤âÜJE¼ÅØô½H&ŽNæÝþ+Ô/ËknaÿíØ±ÿötì¿'þÿùŒgb,(P?EbC%K³U<õLÈÎØZÂk](;=xk£º…7DÁ"iä³ç}Á]3±¸îW9B²lœ¤Œ<’XʈÆþ¨ø]Bƒ_'”·œ@à]‘H¿âZkm\=»äÕ  ø+àø-LLc]©®å‰ñ–FmP&@¦Z%j7VÕÙíœ (ëŽÁ#æÂ¥µIBF5o‚˜ªr‰iŠö%)Tä’*NË÷ÖKep%“ãêboÞ\¬µí3É)Ô<ñ>ÜE(HÒ÷à_PBÀ B Û‰…š0Ž®4YFB×¥¦ó‰ªÝåD-/Ûj¦Nî¼ Ä'qÈQIõ7†wD×t± اs~Æ| °ÁÆ;L'Pa-'Éë˜ o°¦6ˆLÀú7@òÄ+® ó¹/ÇPå;¢~Zè‰!/¡1Õt28džy‰ ‰÷Be„ƒ\aVërQ±øè|€ ³(ñÖ”`˜‘Šó Á_ê:¦©Ô,giŠš0y•qÖI6žE-.Ê€[¶´¿ö‘Å$À¯p5T /#Ue¸B¦9¬î¸TI]Ï¥ \îï\´û°G,¡ufë…ONk'efž_âü°N«éQǶi¤"ÓŒ "2˰ËÙdTÒÞDåÅòMÖ:˜È„õ®lÒª©y‰WëE0¿‘¡,ýPYÛÊ1±-„Þ¹ØYk Z*wgJ ÒR?‘¬ÙüéÝE"y–Üm¤…¥to3Ù®qýÛ›µªéᄽ²ò™Ér¾²s¤yrm ¿p¼’SÀéð+•Éãrýÿ_E¹º"I¥±i±Ò‡=å¸_ÚÔi*¨r±/Zvø“CÑÛ9,ƒ0Áüƒ2tÐÇ8È"“©ßåQ}¨^si¬º¿›}Mç(ç«% óXâ%#ë-'}µ&2}½k«<ã×ö£8c•61zrÏEÀd©¼(J¬^—·ÏÚD@˜‡¨‹Á–øÎ¼Ç!™¼ ÞÍLütFØFç±q\Í—ÎMgò<h%˜÷0nCTê¿-›Q&Ž Õêͤ£"Ù:² Hè¸1ãÙW^&@À9„ŠMొ ÏW;h‹rÌümW¡†,¨˜‰~a‚ e[Õ@4…²—Çw³¢"¨§cS ªü«: ÛxÍRÚ)žü%)ÜZv)l¬¤†‰= dzÁïW’°È£ÁÄ?ºÆÆKe ˆpÕ¬˜\ef}3·m” Jmlâݘ}õ"ˆ'ÆÇeÔ“®ÿUf²Œ*àVùßûúMýï`_oGÿ{Åÿì‹ÀLKìÇa ƒfUq¶µœjV{©ÕÈ‰ç‡ 'š†#Ü^¥(w‹ 1+ÖxJ7)i˜¢vU½JÀÿ¹FXKÄ+ïœÐ)’Ó©9Π)]\Lfö[07ò6à†V î*„¯†×µe.É:¨fja¥#·sÊÃæßHŠ”›UÝ9<¼×#_@zçYŠ [Á„žC@!@*>Ëj¨îƒ7ãîT£\Æ-”EC-‰ †“`ó.™Ñœ[CŠÑ[[ãfâ ÕRhé„/÷¿<ÄËüÛòþ_ß×?`â?¬ïØñýO›`¶T,–½yv³­Ã³½ÿÑáI¸ü‚¹Ýf ×·ŒÊ\rp×d\0Ï0@ü¾GRdö¬ð\žó~ ü¾Á sV^ðÝÑá…×]^"Ë$ù°óT‡ ¼¢ÑípA1(!¨ØÄ´(ÆàÄ¢sÐ>“®8vD³àÚ lÃn0‚†È¦a¿åiö\á«êªP—Fó„.SôVZÄB83¿Ý»Bä¼ÕØ ”TÙ@ %Á^~¶ÍÄIáµ)¦2Ñü˜$¤¡¦£ Ì9t(ãò:“¤7QÔIt[”ò¦G zå-ð&¢0ZÜ/<ÆÙT+ÊVKÇ,3lgZa609–ls rJN] é„.?,!!"ų1?•lD©ElÁAçÐdy?8ÛîÏÀÖWÚB)v¿ÒER1–ähò„0ù¤ά8{+“‰}O{ >lETe‡ŸU†B„ðƒÀx{R‘Œ¡lM‹C ;7¼5oxzHµTÇÓJ³5´ÖÈ8Q z)›[³ÝgÅÏkÌVÄdHQ‹ ‡QFàPY$ZÞY€%kØÓ)¯‰ØÐn5¯°ÈçKMÊì¾¼6á¡!ðwžƒ©¸šnFR3ÈM-¾ô #(%ž –·Ø¨‰ ›(’>žG¥áÛHõUÈd%¥ ¢šÆÁ_—, _OS®Ç×ÂThè6™/ñZ`/Ò›Ÿì㯆Iíª%ùT¥`!Ü"Ÿ¨„°Sj PxpÀn¿BæFNÉÞJ>ÅîƒjMÖ>|ÏEcš¤z“¨‚˜úÌ= ¬Œ—< æKÃ[ÛdÎW­•RôN°¯­EŒ$¿@fDdŽhZ2 Ù}§_/MqP㱄j¸·“ ÙJ òÕ2ÈK$ÒJLB¤Ÿˆ' 4 -nIÂD—[§.§Ê“£êšñ¨–:«)í‹ ÏŠ \ ê²äÛ"O3ân€Fz5D²ÞÄ€t"&”Õ0¤dt4Bõ>ÆhÞñ|‰£ÒÒë3 ›Ša9숃[&¦'¾£}χ•|ë)‘ŸNHØÀ»Á¦(®?=<H­ŽB ΰ[5¤ñ¯—È£ÜñÃ\cFdz_ u„ ËÝr$lcz”ê ò~ ¿ Nþ1ŠY:ûåbi ï‹zt""íiÅ¥†ež££«º°Ä°£ˆ •Ú’Àí:S¢ONþi˜H©t™—TwlsGp==iRú.k('±…èKJÂÌIÆnèÐì5âðæàCä@‰/Z0bƒ<»Í”¤i»ÂÁ(%D¬MjÇÐÚœR"%'Ø*ÝxV²kíTHušø@O¥“–åL¶D¼ÿÍ7ã®Í'•“þ8SšqÒ€† :øã‹ úÚmŽvB[ÈÒ íH;òR“%Š•ó—-ä£ÃÓµÉÙÁêPKÍrEÍÍdË$¯ºl€6+ÐH¤ ˶ðt›¿$îG¹­öV!ó%ÚÊBëB~s7D°<ƒ“µT‡zî ’‘Žt…ù(1IHoJIÂ*tAùNòOØÁ²ÍS]-,†ãÑ£˜uÖXSŒ«§Qp¥d&5‰ƒÓ€Q,+- S1 µ6yFH­íW…,ŒuJÚ#p¤,yCçìU«Œ(.ÝÖ÷ⲟlš¬v¯ø;´³ a¬ÐK ¡)›Ó:Ê'ã&q½ö@–1„²¾½dˆI‚â£ëØ|’Q¸°ªAçdpðgNÂ2I-¨Oú ¿ëfå³ür©Vq»”Ø„A¨!‚ÆwŒFýµˆøƒ“!‹t™¡:µŒDêßW‘­“8–ö¸ l6ê)T==¶‘GAJS þ>dE…'õƒÈrÈ7™ļ¢]ð#L’ckÔ7ü¼œ[¯WÙIçºçŒŒYdMƨðN±hõBèÕpü¢n&âÇÑ6NŒ9Œ™žÚ eL  þ¿xè©GèÈ@úùREü èk¦Ôï©–AN¾˜ä @˜J#þRK—þ(vE«5DDð­`¦è}8paÎWy;ÊJ›@NSI4iÁP ³ˆ‚±M‡¬Ò‘8È— SS¥5’¡ÊJˆÿU°B 9¦}2²Âá2JXÃÈrê±Ê95¶Ó ;Ú» 5Ù;3øTÅ6¡”Z+­(>@ç#© k¥àxYG•Šé‡“bƒÝ.àÍ _±ÿÕi®ÞÓ†û R^ØV-µRÍ6o››ó`ÔKIÁ’ A1x8©+Û¨†]F-ŽÌmö±ÓŠ*ÉÃÚPAøT1›"3‘`:Å8ŒY:âpëÆ3`J>+aFyS¥}KR{.®ÅøÏÆ—·K[}µ!DrV¤ËtIˆµ\ÐÒÍ”½Ê4ŸMN/ã'ÄSDƒ!ƒ¼ë¨£1ø°(-Z½Zd=í2cÅõ/U(ƒä ©•õÎ$!5æ·±H~Á/3“ýâo‘ðrŸ=•Ö9‹Í>H„"Ãß9ÅuܶŸàæ‚Ì6gî5‘l³žRLʽ»‘BÓ“D©•ðm€–å4+˜Ì#ÆßÐ:ãV¦91tCÄ,Y±QEu튰l¤™j;ìÏq‰%5‡ d¹‘[wïÚ¶s,Ëë. -1çó<' ¤Ÿ60EžÞC§‡À<‘³FÝâTbȪŒDÝ"7q#—„Jº|EAK(‘BŽß„â´ÉË-ÍÆžÍ(Ñ·Sú+-›–ÕA'EEË T,)¦'%ËÃV/#€c ‡f›—J7)`t]­ùuL ˆ& AÜШXl äâÅ>7˜æ4C™¬jŒ@~!¾Wacé²JÊFɾ05<¯”1Ô¼ ­öXðýý%‰|1)Š)öEUdZ„‰ oäø‹•Ñ‘‘ŠÁíEu©Æ³$LÙÅó\³gh÷Hnhûö]ŒlÍí;w×ÖÑl[ù@ÈèË>Ùõ’vhΜþ%ðqܾŒa˜ ÕDÏ?¯œ6«êhm˜þÇÀŸšÅ‹çoìëé3ðG—QW»‘‡FeþÂgõµŠüÛÆt•Ÿ‚ ³zO泦ÓäÊÅÍü¢t„€âÆãóD† ûìÐyŸOÒ—Héè<žs–_L´ÙY@C@c…´¸@BÉH»¬¤’ï44—êtT1¥ñÙ¥²·¶\Úïñ´=™®øY³±#ŽØø$ àÐ!³H(² }9Í WÒÊ^O6Jå"Ý~lÊU¶Nâ0àÃ^ìnQ®; ¯PÓ¬–Í4ØÁÙÃþ é=ò*ô·±4‰vèÀ*”+þˆ– Œ¶n‹äÚÑzZÎUwié\£­ ù„>†»$ƒE´µ0óœÛ:9]|}3 »Ä¤uMæi¤v—šÓ9Ú²™¼¸å'1+įƒ¾µE½8¸‹mU¤¿sÛ Ö4“îŶ›h¯åbkÆöÍ©û)£ESúù'ý¾Ý zU¦»D 1°K¹Ý8±Ž}TšÝĘ8"Ù^ö”È3aÙ6R¨Œ?1RRÝܪ„¢¾LøÎlÛ´é lm-A5´4]f™J~ùH° -êëÅp+»õõ£MÒ—@Šš!Æ=í4ÂËÉów3ròô]ð·þXggí™ÈÀ;›K‘XvѨÏdÆ·ÄñüÎíÒ®b»ù1é öAÓÝì@ÏiÌðrP4 í³>ˆq9î±vHºëÏ£ú î§É8Ö{I‹_bÌr*ú$LÄ¿-jmbÄ{®‘P±ˆ¡½©¥>,T 35ÐÝUÁ­ÝF9^°Â«saij 4Rä+DÙqùrbFÁкDêU9b7 Ø*¬áɆÕ,ÞJ®Y+·©KÉðO)D¢ÊÄ9pMý­_S,?ò™¢„ö¦Kªl!‹dø_^ÒèVÜí6ù/ ¼Ï‹¶« ÔíJI&ïçÈF|SùR97•ê›—Ô5Š#|EZb h.èï%Æêëé‚pÈÁRs²éÐiÔiâó5Œ4&$döI³î .Ö%ùÿR¨Û.ªŸRG¢jmǪ\ø{×Ñ:wñ¿šFŒNÕͣLJÌ\MôXwNç·‡0î"I¹êÜŒ¸È` j@è 4L-†j4^!ÚË%@Ê–fŽa¼ˆJô-Mä¢QŸMZÓLq GÔ ÍÚnÞlë¶âˆŽ¨•s^lS†ºHhþGN€À¸Š )U¯ä kúž‘çî㚯l¼žg'úߘ¨Äÿé屋ÿïˆæÿܰ~C'þïXü³G÷ãu%ež.…’ËÆ\°K_ó 4à£ØÑWJ8XäùzjÔ5d°PZAÁ•‚6B×=/PíØŽsi†î%Æèñ6Ë3ù+¶ì˜.›˜-ǽp6Ô߯ a…kÍZ]?®—j§2÷1àÏ%5•GY=›AÜ DÙóšigõêÈ  `4¸á¸ÃBãaÝPƒ‹v5¨%Ÿ ‘MÕm+ä?F£†ˆÿ zÓq¤J R±èšêÿ…¯ÇÒÿu N[žK þKÿ†~ƒþoèÐÿãŠþó7gå—:$¯ä§=4˦Tß x«åí2_¢½+£[þ¥Ú5#Åx s¥õ9¾¹h]È€©““äRY{E8Nb‰˜ˆ>Q©f1½êÊ(ÈòV_àsìı*é3mŽOQ@p£jØ%£vsïž]{Ƕí<'7´çœÑ¬‰+Ü•Œ.K7„D–<¨Â0¨y€±ãáII°Ž_(4jJ~¦PíµF"qU„;GÒ €Â¶04AËêá83Œ/ÏAÖxs¶6?ážTªLùÙŒR›¤Œ.U¿Ù¨ñ%k9,˜™‚\P©Ègº?mR>ïA¬“úH4ýÜÜÒª‚°vŸáÍ!ƒ†RÑ<-T›Üm9 5¼ŠÅLYŸÐZøÀ¾•CWSÇ2;é)3ªð½p#ïÇ…¢>s öìeÂU6n^â}›G›É)bál'ˆ•ÊDÉæGX¶ð?¥&þþ¦ø˜Üÿ½}ëMùoÆžÁÎý<Þÿ éª5äø#›¨øÊc ¨›1Ä3ƒWɽÏH1.1çÙ(ÅÉLZY ¹ ¼¢”4Dªy[H<ã® ºÛÉ_ðc…ü¥;Ý£âðÆ$cÉ*nØV*6„c«X‚%eŒÉl5I-ŲС-«¶"ü¬|:ÛÔL=ʸæ\–aÑ,Yß“àŠ²ú5Ñ;1èýÀrAµ ÿ=6˜øŸ;òßqIÿCmÊ1#ÿ¦Ï6m7……Š9›Mr+è¥ãZ¨Ú1¹<ÖlrV^R»¤â¬Œy6‚1¦¼pü…¢·C`ãÏÿÙò±9ÿ½==‘ó¿¾§sþÇóê¬OÀó/Zr‹Âÿ¶3)Ç?çÈ«j*„ºŸc‡&ÊßÒƒ$ø½¹iýØ…oƒ+Öáÿý—’Á2ªþÛ¡ÿýƒ½ýQü÷ý8é¿Ü Šu(½³Ñ­ç+Å|­ˆw§g ŽävŒŒŽ32š;ä"ˆÐÁmÅ]°2œÊ‰ÌTÍó.óÔŠCcc{¶µw,¦jïlT>{hûö³††ÏÏmß5<´}¼ <=‹¦@VQ"®¼9\#fËØ’‘ P^øKúiá¯Õ«sèDΫì¯ðM¼©C‰+C³ZcdzÉR¥èPÑ]1¡){­aäa`Ï®­»\È×Z Ê'–×Ápá¤rÊöuÐ…Ù)OG@Hpreë`)füZ]ªkKDÊ\róâ>ë±á`ý¢ý€Íl²ìÍ:i'hÌÎæk ˆ¶¹ÜË %¬ ™¶êct2éI0SÐêÕá¾RÖR÷¦p™Ú© y£ÔúÄ}à T¬Y1òMbÍÚ„ÝÄç·IÌ´Eùp ˆÅà?š×Oì¦Ñ$ÒrˆÙ´3ž¥Ná1ïï‘ Ã›°›lVÀ'$)–ÁwFÑ«ƒ¯%æÃ>dS*ë¸ò’J÷AµäxOvÑeRc<îÍ.®v0ã…™µ+Fo¥j¢ k¿ú[CkßѶ¾Ñm´²û +½˜áUWrXS[u£3m,­3^u ™Ûgiý…µ—ÐeØ\X:¬þ&ðA`§±ê¾’-Á€,Äf1Cã\™Á®ÃI¤@E!˜§´Àyjgäɸö–ol±ƒ0(Vdèy¦.‹óމŽT½èmãL$¬ýaó€;¬4ΪêЮÆAT‡{üÂÆM5$è®»­÷ôJ¦í*.snÖÄG{+e@fl‚Á—Ä|³ãCƲòÿ¥ \™ùz ¬¥4ôfÖ;¼¬P­ô¿ýzuþ¿oýúÿlþHÁ/2Îuõ©µ§w-A"ئìÂ܇»„I †ŸÂZÓ~êå¹{… ¨?è3pó“’û6Ù87~›ŠF{zìÎ5»uÍþ]1ŽÔÿ…HÌùGßLbQ­ç8ÔÃa+ZžSþïëëíøÿç÷ÉnŠžhzô¥$À%Ü¥uËŽLG”¸©´#$÷þžÁHLUêè8—rþ—)¤Õù_¿Á°ÿôõö÷öuÎÿ‰rþ¥¡¨éáßO¹’™ÈCÙ—|øåvL;ؘë˜mºJó³~ÄçŸÀð h}þ×›÷O'ÿÛ‰sþwÐ6A´¨f¶Ña~u/¦¥)Wý¡1=pdç_`®¡Ðšÿ4ÏO‡ÿ?aÎ?Ç :&€¾%;À±8ÿ^kW“´¼ÿLý_OoÇÿÿD;ÿ^t€M)D×½é…Ã>ùr3ÂA§¶\ùW‡é_Öóø\\± aŠ2Ôji„ åù_oäîëßБÿOœóÛ&tôÏök{ÄiF–|øcwbçÄ…ó/23ùõÇd>"`ëóÑÿ °â󼟼éÍߊåO0™Ïam9¼±„ÊÉt8ùcyþ)µ[nºæ7ªztÏoäüöõvÎÿñþiŸœÛdŒít ^–{?º;ý±?ÿ³¾÷ˆëóß?±ÿõuîÿæüï`ÛŽÓëD/U÷Ù‡i'lÆUþrþHë·„óßgúÿôlèïÜÿ'ÌùoCíG;ié'_¨úè…¯^縛ó?ÇVÓ¯1hÍÿ›þ¿}ë;ú¿çüïÃmÒš ,ùôkû¯sèÙùoTöWüy™kåH€Öú?óü÷ötüÿÿó¿—öÉ.ŽáКX‚Áߨƒ)BæãíЃ£~þ1õ¥wôýû6DäÿþÎýœÿÝb›4¥¸™–~þåäì]úŸÎé?ç?L’stÏÿ`_ôüwüN˜ó¿Ol“¦ç_n¦œšŸ§}B ë§½)×øÝ! G~þJå—ÃØúþ7í}ýß qþå>9 6@û.ìœî£þÃ]Ë‚Öÿ;rÿƒM°sþÅ?HPªyrËKt-…(I"7Ú29*$ѹ ˜7µp‘¥ìïDà@4‘,×êZ½:_›Va¹¨à.©Ý© Ù*Œ’Òo×Ô&¼J zÃÎZA¤"HÝ*ÑEuì ÞI·Sóf}ÈŸQ.czF¥âÁRBTPoLM9S56nùri¿§£’u#p–@C–‚_™ój²O¤é ¯J¹?ê>&ÌrØŸ„ý¥|•|ƒwÉÕ9}í¬I¼EE¡üß’uá„¡ÿ©%žæeЊÿë4ý?ú;ø¿Çæßa‘w5¯Æéi ‹<ù®fÓK…8ËLÇZÎÞ x˜Ïÿ‘ü¶Îß@_ÿ¡¯£ÿ9ù?Išs"ÉýH¥1ë)ÙD—NH\g<«¸ˆ–¸™UR%ßâf2u¹ûUHAÞÀ¸Y&C,e3˜Žg—RcãÆH6p{ä CwªQ. †2P° µø¨Û¼ ƒÉÛ$WÍ—j¸*ÒP$1W—Å\ÂȺ9ÎBÉ+³•¶ÃØøKü¸*>#‡HigNíÿ 6.08ûÓ6ˆPHÏ %W¢º†’ºØ¡3B>ô /“kUý¨![ÌfuPù"‘ü!­|2ò>å,f•Òóm¸ÀZ2!³kKSr0„|˜TVE‡k&Ì„üTÊ…‘§ ;XtN;È»]L¨ÅÃ"®òw¦à7*uHº×ël¶Bn*eÑ ï­ ¢ i:šoÀ¥‰gLÑð–þ)¼ÿFæïöô?ý}þKïÀ@_ÿåaäÿ—;õ7kl©©¿µÞKÈÝݤh|6q¥Ò¨R±Çcò~·—òûèdû¦ål7Û÷ ”ç{í™IòÒ´“ƒÄ.ìÊc?”;·“½û˜ÐÿeÌüÙ¦ýo ’ÿ£CGþ;nè4õg‹DOìØz…:?ÆZÒ"HáÐkÁƒJ?1³ÁëT|ºLª•êìe>ÿ‘{ò‰A+ýOOÄÿ§wCÇÿïx;ÿ&g´Œ´@¡ܪ††%Kyƒˆ­ê bÂ,,ÊH7GÈÄ1¡CÍÓö¶ m‘S‰ézµUC½<æ™çÙØ šŸT[s¢­9‹‘æôä¿Ú¬ÔIx– X×ÒÒ«¦á5šb|¹UŽlÒ¶î'ºÞÍÇM•<£ë•tÕš©¬ÂºãûÁt®ñœÞ¶ž •o–™zí$aîükëþ_¾ÌÏmòÿ&þgïàúŽÿÿqwÿ‡©Ÿóʹ]Ùvƒœ¥ámÌ8®ò»“¥ôØžÿåËüÜÞùïÿþÇqwþCær‰ÿl£5áº!—±Z;_ <›AÙÌB©xó| ™%H°¶EAÓó?S¯W×q#ñòš€ZÙØmožÿÞþïÃyþÏe{A=úçj¾Ýì•À]·nºTŸiLf þìºZ¾°Ÿþ3Yö'×Íæ¸J`{ÁC¶¡xåsÇÆvçöìݶk'üÞä$ÔGFŠßÝCcçæ¶í<{?¹¬´|dÝ3òܽ#£c¹#cçîÚŠEõGFyöjÏE¹Ñ±=ÛvžÃ›V¥‡wíÙ9–»h÷/=ìWê^¥¾¢di^üœ‘11^ö§9©]£cb2ìOóí^Y•ý]áså: Ÿk¼Þ:²}dl_ÓŸÆûsG†¶ŠEgowíc_`Þò?Íiîݽ{מ±‘­|I¡ì8›`甆±§iŒi>–4ö™mgñÓ ì³m ý1Ü sÃC£ÃC[Gtəսpíp>(°-kNÚÛ3´sôì‘=¹‘û¶ÂǽEÞØªÓŒ•7æ’½kÏŽ¡1ÇüÇ* G ¥c …ôŸ²W®ó*™…Ùò±´ÿ÷oè‰Úÿ;öÿcòÏ«¸lÇáp»BG*—ï^µ¶¢‰ÏN—á=š|}¯Vd×Ràp ç„¢üfñš#¾„¯kÞ´w SÓ;Ó;o¶Z_ßPúGöªè{Sñë”,œG1Ðë°4y;²Ò3ù€Ê4<¬ÄQÃ’VDWáNygÖ/ê¸T–ÃUdª9šò0³ÂhÒæÈöNë‰Ì ~Ùe»×¥©³A'¡±Ö"Ó²ë¬ô¦]Ùfb®7‘¦–]‘ô>íPK¬ÿú| XæÄÊÈL%æ^óYB1ŠÁVa»"Ää[ŒŸ¦™\ ³,ä+NaÆ÷{ï(u£]%œ…_¹pã2Æ_½“Gu…gÍÉ‹°„l¹æ+À‡CT TÆI9®6T&!ä«Õr©€N˜ëb§ÁF µ‚&·/ÜEæge“g…Kõ.V•*×ãâ˜-›GýÔ øÔ²Cgo—jn:ÓÁf]G·²€T‹Žˆ­ ½\X+Ê"ÉØX ì©áaCl`^¶Eˆ:í ÌȶmÄÌé`_2fî¸t@`£ÉŠ.ëAdXŒ]¦ü\¾TE¾Ì­ðq«ùúL:< .O4i¦›¡Hµ°ŸHp:ëŒ?s”g§ÔCÔ£-HxY_>Ÿ#°T“ðJEåÙiñ‡¶ôqIsÑ/“§Ë]äcnx½‹’à°&Q´/,Ú§t3Û¨7ò声åFÀ?BÍãË 1§Pã|=Wö˜ØcßU§½ Yã|ç°wáühÛNz°WæJE•`{ò…zyÁÖÕvSl¼9öÝ*Ôñwl ÁSÇŸ  ¢'- ^vÁW–ý ÊÆÖ•»ßÕk‹zÖ+б¢é‹qØà¦æœ7Êxg6"|8¿²Ñ§fQ³¶•"ÐJ8òeÇ\»=F¢Øh9[°²7§,pØN;¨¤k[tØÅËéòZx•×^ˆ!ŽZkШϩ%¬£Ô“€×­h¶–FÖNt¸VÉ¡¢üVŽ%0Qv(BäÚêM\ÛKè®k™øÿÙR±XöæÙ÷]—oÔg0þcyô@­ô?ÌøïÞ ýϱù'ãPu#>|©ù³CnUA4Ä*jÊa%Ê'Ñ-!Ý\Æt±ÿz•9ݳ@ ïÁÿSÇÙÂ^11šýW}È ²¾Ÿdõ_@ºs@7‹Ï seÎu‡voËìܺ{×¶cÙ& ÒÛÐuÕL.ú"R7g« jõ {ÑêÚ_gÉö{  '×°tp±Ù§È1ÊRPt ÒžgíÅs|=Xq±2ZAÁ9åJ•)Ÿâ î¶^¬-×¥‚%/—ýÂ0³Y½ÁúLÍŸORt—´Ô«ò'Ø'ÀÍå×J—QúÙŒ•óŠ™DŠ]•eVNX†ó›íƒ— ­x¡æ±_É-¸ÏÄ.C¯ D0Ý2"«•)UØÈ™ËX¯ÄJig•,õÚ°Ž+nƒfŽl”Û†9|Žxú_ –Ë ØÊÿoýÀ“þ¯ÜСÿ/ý—o·ÌøôgK×±_ðj•ÿ ø“­£Ûn#L†°§Qê¥}è)<¼æ0Ü0”{(PA·3Äd~&NÃ,@¤&ižXf&ŠŸÈÈIÆnÔjì}yA«ìW˜L0á‚i#‡K0‘?‹¥iÆ\N8 FHî<£G¶a¯Iìká„W„£®š,û…ý:9`Ô*4¦Â‰ šg$¥T™ñj¥:®IÚ—fj°Š€(±$" H»Þ²à:ÔiÊè¡R£änît³A$ͤQÎêjNlq¤Ï šu`&J\àðP>¨ZIk€_œq²ò{ 9èúç‡W©^‰žÊâã䋚u\vU”g•‘+i¥3ÆF¢Œ šû#ÜXÉÖ;C^œØ…GïÂDä&w”ý+7‹è"~­åøh§¥Ê:~5ÏÄ5^)ðØ\ ¨Õ\:–ýe—ÿÉÆeüïÞ¾Þ ‘üü¿‡Ñþßî²úÆ›jT p`ui'_,&ËùI¯&ï';7åÕ ì¶`4gí™ÉDÿgE X ˜êp[ŽcKà%͇±° 8zðþ‰k¼‰ f4® šú«H¨ª£Ðv7:˜=Œ³R.W Ìl†WCG€?9…‰§£=-lÑÅV*äîØ:к#öäN•E_Œ_²ñ,}ÌÖߨCŸOXúÏå䣙ÿ±0šÿm°ƒÿu<Ó•nêHŠÍÏq¿KWPI€¢¯ëÎHÿ¢ª_l §ÜŒ _Á¸½]ÒŠH-¡Ip88<Ò'jÍEûû_D¥¬çùTÿmùÿ ô›úŸÁÁÿwlõ?´ ŠAYø·«à‰èû5ì.©áOK½?/66ráXîܱÛÁT©ëfê³eÓ}N@„quÅÖÑí®+¼Q»L9Ø g(täȂ…sÐÑóµ"€³6&íÿyk„;?ÓµDÕãŸJ³Õ2@¯úÜ0ŠÚ•Iö¤1‰KãIýB›¦ ‹aC1k¸¡» PL39ò©¸NÊŽûa´(8ƒRU@ƒ±ž®P[j­Ð«m MÒ³Ëc+è)?§KÃæ£Îi‹Tˆo1Ì,A£¦ª¥Ì†Ø.¤¥-| \ qhç®ù¦3]ÛÅvMÅYYÈ7¦gê×'­žÓ}Уø´Rcó¸ “°çJ•¼º¢­‡ßOùYoÑq±¢°ï®Ôz£¯‰òCq ÓgNõÐ!}ô]¶•r 8òÚx oÉOÂ*ƒL»a6Sv 胢ªNñ°ׇàüð :åÒ”WX(”=õÜP;g´Ù+-öuÊZçñ*ã{øÄÓp†²‚jŒîW\AJeÐJ2óÿgïÛû›8²Dÿ÷§hðn$Ųüöj⇠³Ãã‡Ifv…¦Ó–Úv²Z£– x?û­ó¨ªSÕÕ’l ˜‰rïV×»êÔ©ó>rhœ¨ï üú'ÿ¦6çávì~`/dâõŒíp¿#)ä4ïl+^Ðý²Yú²Õ­ºÜ´£ù™~þ-›œ>ö³ããÄï¨Æ™ÈæE£ã†š1”ÅUÒ0°åTÁéÉ£S´Èj„1«·Ä²˜Œ½1Ì’~©‹ÞúæÍ ll.íÂh `q•O'±‰`.ÜÊ%Íñ,õÖ9o P'õÚŸj Š˜2•7ÁØä¡Š.èà–ú¸Ÿ ã¬ÒÕnH!Ïz $Uº#hfä9\¡©ÙÒ}âLîÔùgÃí§¤ŠZô À¿²ñWË1é |xc ÀlúkóÞŽoÿÿÁƒ%ÿÿ%è ¼P‘ú¥’¾,‡µÈ=]»ª?³q# õ~ë\¬éˆLT;2´'n°¾Ót0Â𸠲-ÕŸèhÂ~¬Û¸ºœèÆXQíè8Ù°MÆSÔA3Q $Bê†Pvãa͆î©\Órm¤‰"p[$©íLÑ:Å$í—û2Çï# Q²JyäèR®¢Ÿ©CáIS«iŠé„`EqJÃþ à°[—jê¸Ífþü™tز@f êúø*ÐW0AEM?PhÐÁ® ^¿ÝŠCEG…Š“­`¥à1êóŠcFÜB¡úª·™?n±Ófîb(¤òçë°g• ]ýBÖ{`&Ì&]ލÏ#cC<NIóÙ/E`5´ìß‹Ìßûuæ¼¼DšH®ˆJŽA„êwœ^Ñf~ÄGt3mÿ^À† Ta%ãP¹x;„_/gÙxÇ„œKÅPÇÙ°¯!5´nOÕÏ5[ ¤÷£}þIaÇë)„J;6Û_3ú†ÿnÌ}íLå;;aa:àÜÞn Ú×׿ת?âÄÖñ‡è àÑ¥"ÇJƒfÎt_‰&ºìkNó2ö‹ ˜ôFÀü8” ˆŽóYNöJi9w§Cµ_Yqµ¼så[M¯„Ú:¦½½‘~%#wã­”ßÍ}sëR’܃ûE6QWW­ mz¢zaÙçÅx³­Z”¸ØŸju>Ðû/|Zž$’³£~²XLJÆÙä¢õ{:Î÷%*tlVÜÅInõ«¡¼¬wtÂ+mæ+±€KúÙ,l|dh p5ï |bj™˜ŽID20c×e^É<‹SWcZ”M¤žŸ»KÌ̤\0s¯8Ù®T¼¢6}«<|µ#‡dq¯žÿø¼½:·ZB.ê¯>8 ªç9í·¢—jÇ{®Uñð-ÿ¬ì4Ïё=>,ì´ùЇw ~r/ÛØ¤H µÖ…]ýpÅ›ë x2ü•¨&ï[P!“ë›O¸$‘äS”Ûï5/Ùµvs¦d±£¯¼xã3Ò1|ÖÆ¬¸ü‘§Wí”<ëÊ€³ #äÆC×±ÐK:º1De7†ûÂáî+ë£fÜç¢Úê{í Wüì¬u±!ŽXLÎÔ‰Œ.o“P¥‡2x~+-UØñ”Îy­M·õJ ®M£• /ö%õÇÊDàÌÙ,DÈéTSŒzbÌn芯ÔJ (ÿ;Î7™džýσí’ÿÇÖ2ÿß-²ÿY%j"ƒ ¨ïvTgÇm$+¬íƒ„¢¤‚#H*¸—Iβ!…¤‹Vôd]N …)-iNα«\}†«ÂOØo“lGÈ4öó¸Èä©(Ò§,BKê©,µô4Ñ ´°t°"ôëßX´U‰rð?V¤±rtͳúÆš^×ôífpOøþßl* 9òÿ?þëƒû»Kÿ߯NþoH'÷6=úù—gÿýøG0óéN‡oÒ¾oäsU-A•0¿Z(?JgHŸçÉd½‹?LOòI™Ã‚ja°sÂh q6M'‹\wWÕ6ÅðÈæ&„cÓó½è[·”%išù~øêàÕ/‡ñßž¼ú9~ö@:EºCÙŸUÄ“82ð É]W2Âr/XU°@hXWæÜPõXÁTp¬ ï–͉Ùä¡G‡[tæ3á]äBfð»+hV±²2µ—7OGt˜NPMÆ EVm4_$úØÿR³³ê*eÍÈ&ÀŒæÍˆ™V}K}_Éвl{%?£ŒjÖ­–2ÑÅ·ÕÑË8§¥;æHŽ®!aœg7ÔX@ ÊR«¥ã¨¼Ð ¿à= óÿ«d¯Š¯W„˜ÄÁÌj 8ZÜe Kj]gôÐsç½ibÇ꺫Q^LX®Ï¦ÞoP:_úé ¤û •“=ÞÑåvq?™$ØÊ|>KûYB]·å;”"PîO­Ýþu-}pƒtx29¿ê,ú>Ú”3GéAA8žh4L5V*‚:GY²õòàÑÇOž½øEŠxÀ ¶:±·™xø šŽ‰K©Jºƒ¤_©åÅSGY#VFäÜà§óÔ wàÆbܯ6 N5è>ñ¤fA({*¨?U+9;ó°ohº°®òg§ GOè¥]‰„Êf‘gN–¢J­òþ&øDT £5K‘l°oªäÐe#g õY D!@ué¿Ô~ð>öʬ7¡@:ºz8@vñχ?#ô/Z¹4ÈUþ[p Æì.Ð\c´rL„«ýø˜ñ½ä@‹í€Á3ÏÊìª)1àËÖó!‹öE-ï«%ï³è·`à ÿ¸¹,Þ̯͠¡ pˆøÚêû2> ª æSs¸Y¬†{¦#³`Hºœ6E¨XüšL1†”|×À™³ô={°€<¡§9›\sǃ›¹"^€I¦K† :ÕæØ­šË§bÝV‘ýž*:dKn‰9£=®4HЉÃ&çyÖ ´NQË=ËÇPó XR&CM”'[NÙaFàð2Áƒ2•AÓñJÿ£2Tyð(äô6ÆC<ŸXíÙø¢^M…ÉxþÝFE%ŸyºîfiS‘³É¬Mr ÙBëŒ-9u IxIÀLmýQ”0ùP>2AäL¦±(tÜäŠÇd¶<-ÅÆt^Œ!L‘ñ»þVuºšæ¥ŽV¼Ž §v’ÆÂi+^~ÔÌŽ¥T°îàî×o×6:êZëݵhz"q6·ýVú.=Fëì‚özíÝ™L*]ßw˜ªŸêü£Ùýv¿±oF!6Ãh¶gÔ"ÔqN"…od'z]|û¯½zçu¿e§¦;‰îòòîËŒ2½T‘m'Ñ¿ö6[÷$lXûòÝ3M­³wê"»–ûºÕùÇZwíõÚ†¿Ç­¢— ë³öÛ'„Z…Â}ñÑyâfĵb;ëÑzù#܉c/Ý¢êëxúþdÁÀhéס¿à[Åô¨\Y3ªÕ]Gˆ» 'qCúß“A~” n, Ð<ýïýÍ’þw{™ÿáëÓÿü™Àf®.UK¬ ß+VK6è¹÷ç—/kb¼k)§[ÄæñËCѲå ýæôðâàåÁS§&…ÁÚ~>ëtËUðþ«+)›>Oü‡{¥ø/[÷Ü[æÿ»MörÔIìÕ3¡˜ ½7àZd!§@—ôÏ:Àð_?f v¥õÆ!´ã~Ÿp®ì;>¬GôŸFqJÆ6Õ_¼™–ãO`€—6úê¨Ñl«2ØôŠZóm8*ŒÂ lþMfhŽÚ”ÂÒÀ?ò3¹íEnÈÂR -püÍÞ˜hÕMööêùäÔõ@ÏXü*>¢[k`—Ì@ “ÆF-UØô‘÷Ño|}æJ%ß|ÃÓG¿¥žSµ±HÜ:H0)mÉŒ\°^¸ÇÃéY:F¯™•` r³™¦W„=³ì» á|Oš÷>¤öò£o¯Xµ`GÄÄ)ê÷݇è"Kýè]•aB!'#»^G ›ˆ¯I§[Ï¡6¬[åÄwµž ûé»Ê˃¥pC ¨ãOÝ„m¥B£:¾-‰ ­P1–\¨;9[PŠ©ÓN ^MÌ–lô«¼Ú1ÓǬ;uí<£µh«¢Soë§E:>zGÓâ´>s묇?ØÜŠº1\ä"Ô-•XF®Ð²ç¼ò®º>!Ô²ÞáE)¶úhz¤8üÝ"ýÎ ";t0ÊGY‚ßY},o==¥W?€EK:î’ß)ýàÄ·”ORUIƒ ã¥kŒb꺭‹qÇp–v†„ZÅiv<©ë K4p¿ëß°oXÛžY#|ôæxÎäyœµèaÛ×+i žµôûyÖâMçŠàV8«fXÅ-‚›ÛO‹Þ8£@Í&Zîng GÍêhÑDØ*2î6#mªÎ×ú[ÑôoƒÄZnÙ P%¢KGÃec.=ĉoXðTDõ´uÒŠ:˜]“µn3ê´¤ÃðÖ5ÎN“DuRC6JÏÏwßQü §Vkœþ“MròQN>àIƺô‚ÿàf:Qd~'ŽMW>Q R× .€!1† iUÂ×üÉp’ž@ØÀ}Ʀm»›®d ¢½Rýî³<*¦ „Å‘XBsõ=Ž~ —xP"<.ï6þÐñÿLvµÏ“ÿçÞƒ’ýï½eþ‡Ïòßjô«>ì¢jZ ‚Z—ø€Ää¦BoBr^&…Ø€)¦mr(Èl\E cïõ(Ý;#¢C“ê@áÕ3EdOL¿`Ø¿²ºvÿìy­›B ®€!ödB®Uµ™ú׫>g­1îÆùÖ$КŽ{©n˜<Ð"B¥¥dq~ó}µ7ªÍÞùÎõ0"±Ÿgýi2ˆtÀ ^c*«+åÉ0§±23œ¶y‹Lb›¹žw½T†˜Œ[¢L‰‰S3Ü»îÖ¡5Õ†˜ÈÚ^<&¯>óŽ8A7¼?©†§ÝŠ"ÏoZ÷c@ÉßT'˜±Q´!¸ {g{„ %ÌuñNÇÏ)=§ 9þ•Å„šÿ7‚›zÕWa^ü×­]/þóîÖ2ÿÏ×$ÿ¯@^ì7&éátIÇY>- ê§@f÷ћޟlœ1F+TNaú3j¢3®Ðµ^ÿÕIœX²6~LêÞ6ø¨ýƒ[×âÝY;:ß*õ/Úq2Kx»ô”íT#^f»Ô’W¼Ç › Is©ú“c³A^Î lê8ŸN î½Í»›÷1( ®>²4¦Ÿ¿¯?JŠžZ©6ÝVp2úWk_ 'ú<™€ 'nîRÁáx† ]¥A[Ž6€V]PP¤8„ #²d ‘‹g¥XmGÿúøåá“çÏÐШVS̉z«G^–<øÖ›ì;Ü=îé0ƒLÛÏÌTš oß:׬ˆKm¬`|Dv»ÐLLzWE­Úâ “øYŸ5õo3&޹“ ð3§öÊ -÷ÕBõjÚ,„kÆüüCtŽR`à=Ët¹2ÇPÌ@N uXí9'0ëy­ré2?DIÈ]†P¿í שze!သ*†Z~¸0qôÖ–p>”w7É‚ÿÍ ‰ß4/ PÂo†÷7àÓ3…yXWæW€ý@Sƒ"õC ˜¢(¢z‘¦.ši i|F²U²–‹1Å)ä`ør®ÎDô„˜î(=MÎ37Kú}Ýò´›˜ÕÊì¼ò[»§«pb/Xôù­å¥ñÄzûÁt›W<ÎÎÉ]V¤Î*Ÿ$×ïÎ’QB¤½E)ÎMt5E¸Ôh¿2üÇßãG‡~D'–@A-‚àÔï/—É\þ0òŸëüWóÿ¾·¹»éçÙÚ\æ¸ôu¹²Éµ¶é1ªü¿ÞA¿x(û†2¶04|Éx´M‰ëƒ¯µ[àk²íÒ8g½ül¤ˆŸV²ÞËóÁºB­Ÿo­ý³04ËMs'pˆÀšs"fU V/¦GÜy™E&^«àŠ`[»¸—Ž/›qy½—éóL°…z}ÓÌÇŒIÓËs{f½Ýý¢°G†±¾u@ÒŸ…tµ»Ôá.ÿ[Dÿ‹÷äc½æØîìlyþßÛ›î-ã?,í?çèpµB $ïÆéY~Ž"«D”‘¿jfUjåæ@Z*¤Y@ x,؉CÇ ·V<ë9½h…‰¯2L†ÖÖL¸[ÕžfDš¨MÜåÔ&YA¶vÆd : ºÒ¾S§~šœÂ"ÏrÅk¥&¿¢5z›  B€4 ­Ù ìý#„M?¨VCŽ×ÕJã.£/hTST­hlÓSÍ W ©°öµ®2˜4§è>²R­ B/Qâm¯8²0Õý9싉y/«ÉxH—Õ$ÖBƳ7% §®¸î‚¦¥àö¿€è®40âH¾>SÐûèmjÂŒôj¬FÀTlôî”?c¢É…ìIoÀœtNèMÚ}Š>JëúyÂh® ^Õc¬Ì`/ £ˆÄ»!óEÛàÓ (–Äêg¦ÿ¦]W$çùnùþŸÛ»;»Ëø?Ÿ3þÏKŠ«Ã¿ˆÛ””£¤¢Gô»ï0¬„àåã1:}â"?ŽNò.Ú'ÙätzÔêåggÿT£ùp(uën ò£³D½Xã J(c÷3k…ºú×ÝÍõ¿îîú¨lfx5Q"LGÍf¢xø¢•¥“ãV>>Ù8œ 6ÆÇ½ûÿµó_«EŠ®–ë»­mÊm„ å=Uè­‡tb6$‘±ûýF"²3ˆ1næ€ï ‹+þsüþh³ômw­ñzÃS}óú¯×ãÕ×ÿq§µ¦Š Þ¤.ÜûÚYýÇeÃb?êœu¶ºêUílãÿî°?L7jûâì2Î1•Œ åŠ[º¸,b‰­¿^ü?9ýè sðÿöƒÍû>ÿk{‰ÿ—üÿlþ_s£×â5ómLgÜ_€‘¿ w-Ü^¶zÕc¯ÕPÁ]kûûh£õíFv]&1+2õ‹ƒW?ÇOžýô\ñ]Sß}”b ûˆ@BqfècxÅMMò^>j÷³¶èhßw‡ú†}fŽŽz³5M&ÐÚ§uøŸFµÕÅ(K{hÅ##Ço8ã„„ÔÌ5*s-Ú­þ/¬!Q÷æÿÛËÀ/ÀLãù–sÃ…OÔn"6ëâüÝ Ÿ\ò_ûþ#;JzéÍ~]ðýß~°åÅÿ¹·{o™ÿósòúy_´}[Z(ðåÙP=Û`júN)…ç õr|ÀV£A~’õÔKy2Χ#6ï°%Eô6 àßBñUP®Xó|¨F?ÎN¦ƒ­…==M.ÈõdþÇ Ã€”;‡¶Ø¹Â6é  Íݬè%ƒ¶ô=Óó])…‡ÅÏ”Ÿ¤7¸”Z-1:稾`%hV2t:6Í´u%¯3?OÎ{¯*²õˆ.j3‹0í°³õ1ØÒª¿3p¥Wû ƒÓ¦ƒñ¿É”¬¶æL½ôGw€µ"âÈÔÌÅŠíÏ†Þ `ëLghoEAðP=¶XLdqä Ýím"g¼ºÜ×·ßzyÒVîÑ–Ê@®õì9y® Ò]^¦jÿSMÛ9;eÈ:¹ÇM@¥'ÙyÊW0› ¶\Ð]­”2ÞÛ2d¬ÙEÌ M“Úíæ +Æ…ÅöµF/»)ËU“ Ø=™}1t‚ù³dTÿ†À²Mík.†þKž 8ÒU¤½H¢AVLFLÇê¢ô¸OÀ´ z\Z¨ëê:¸¡î‡Ÿ2Ð+€å²ºÿÙÈCnЪ^-=wþ’g¾áÍj,¥Ÿžÿçìo7ýø/$ÿ-½ÿ›[Kùï—xÿùç ›\MÕûÝÿ—éIÎL\í(XǪUw7æ¼Û6T©W€nE’ûܶ›±Ýþ‹úØô*)vtn½wgƒR¿‹ Q9'èÝùc 0Å–}ꪶ-ê–Ûó|;ª&T÷ÅܼÞåæÓ"-b„ÙDm¸›Yy!; R9z{%Ž[¹Eàu» cKµ¥T"¶ÈiÜmP6ë½½hËpÅ’¥DÇÊ*ë%³&Ø.­´S£T¯‰ë8‹ Çõ¬.å®0~pñ& ÙÌn:ÔCs¨HïÕÖoP/ÚB§ÞjôHCúÑÆ?^n8Eàð^Û¨•»†Ié^Íuïyþ»Ü§©UÕe1=¶°›Í†È(º[o­¾/Õeãbu'&)müÄõØ«Õ[Æk¡­¯Õ7ÊBG îñ=>$f7ýF¸'òxw6êîê{(¹T›Ÿ9d„ÓTèS‚½˜ÊŽúšÅNÛ”’Ñw,jJ¬Óma@>“˜ê+J°¦á»f޵âRš&.lú¥ÉBOBd5‚ï°.“ÚÛè2z¦Ûúß³Á€ø>H¯·­9=;‹¯X²%è?zöÕ‘Ù??KþŸÍmßÿoëÁƒ­%ý÷%ù? BÊo>Êœ”@ö5Éh˜¿o¿Kbk*[Ê„oëý×Ù¬ožœ›ÿkÓçÿîmo.ïÿ—¸ÿtÓ9{ô;¾9Ö1žÏ‹—z1ZkøÓø6®Ø<ªJˆíOè‡è€ßÌ4q%ÐbÊÇX;¸˜„#ʆ²B5ÉS$Òv2{ˆdOýËÌ©YFÃR®âŸÿòêɳ?Ç/ÿ,"Árjèš ªu!RŸ§nŠ2™žL¸.;ÃiGBÃñ„K1ØN ±slZªª’ŽbTcÞ©Ë VÄUuHå“С¯`Þ[•ë9†$‹Á² a½iFç6AfSÔ7Lt©‹:AÒv_B¡5Å„LÛo:÷Z­õ­®&ÑâšÎyÚî%£l‚ùmZ³. ey’7` z^Z¯[ÿ&¯–ÀÿĶ|vû­­Rþ/J °ÄÿŸá?Ïÿƒ€€þ);ðë€uÊ⸳dÔŒÚÀ"fƒÔq1;^¨·ä@UÎŽTÛWãdX(>.®×Ù¸ÈÈD·‘én¹œŒÞá/kIçëåFAÎi×Öö,¼»Á øÝiׯð°zñîHc{kðÿŸã÷k¯ÿ÷RšüswÀ fÇüKý¬‰âŠ9šÌH1§Ð4âF¿ß°»Ãá//^<ùÊÆ*Ö¢NíÛZ@ÐhÂ=Óédœ buÄ2ÉýCúý3?–À“¦â”? -&òÌØÄÛ Áç8ÎÄ 7ߨ1õ jwJ¬¼Aq:ä —Ö墨ìmmG&\¢Íš^>‘?Ø—‹SíEªÏvEªf¹x] bflóhqÐCÈv ýsºü DRFcÿ-•Ò‚`ëûßÅœåøòûÕ÷TÌמWªyÙØ¦â®œ¶»£ÁZeÒá¡>ˆÃ¬ÃÓ9'›ŒF‚g©ÛC—zUqŒ â`:C§.  R Ï¢È{™¢cÚk‰f:QüCÿ‚‚Eïs#ƒ1dXù @šÚâNÏÓvßÒjª9<@hÝzO¬1œÙ€Sõf%=½ ¼š8ÏfĈìjt-Aióž¢n ë|˱ëìXÀ°¼8ïƒJ"y\é;5åX,¬Q^™]®3QUò­¢ÁÁã=Æ ŒÏf€b×ÄM·8Gôˆy`›ätöœEº?ÝsÊÀ¹W½…ÖbS'ot¯:Œe]wQFMD¹"v>fÏÄ.²tÐ÷AÄ…{SàBÿ ~qu^ꦼ4=Ö0ÍNN ¾nð’­ÈèR¦nú.+&:šÉx…Y=ñêÉóg‡MHËçÑ%‹ŽV;‘2=„4[ØrXQ«.ž¢ó¦€šdKV;˜ ŠðZ™ªíÓG¦h0^Q w•·reeÖeV„“¸€|%½‘3¦Äzú¨äӫݯÜbÄá-ïd#jláj®æ,“7mÑÛ¡Ú+艜¬„=<5ñ ß  Ç¨ËÍÈÐ[ë>Jߥ=;QW§_êT¿QÕòúdE´¬\¦Íàw)š°u¹¦à@ Ãw90¯EöËÀbeJh¾ˆ×´y4ê«n¤#Uç¡«ã`½À[V"´Óý¯»ä>¢T±ª©WôZ¾Rü±¦b¦À¹Ù:4w»!0©¦zÓñL# ñ&§WBÎÚn[6ã›ÍÅÊÏ!ø9ó˜÷Ó kXé5]tîÆš… Žân7ÄŸß›Ðô‰A»þ´%ÑüñÓž‰+™ýk{¨ÆLäãçÃÈ@’‡7fU.!ïM¨‚n‘/…þ»³ÕíÌ[´:!À H,pNB0ÞÌDT[ªó¾vùÅ#¦û¤ù_7·¶ïmûù_w–þ_Rÿg%¼œ@¡—OÕ›zqp£ç£tx8OAѯãä k“èm>~Žå/§ŠØní´6›&äD€;š*âe¬ ×Éðã®eE¡˜‹­íí{[R^¼¨¤ØJzQ·$dÄN‰ýö½›äñi¨i¸6!ðøLMŒ‰ÎšÑ·REF¹#;ë[„f÷j2¡ší»sÖÙDM¼ ØÁŠ›Ÿ‘º¸3³‹ª!+2ÏÕ––lîÒ £€ªô!j ñ´A é?«;ãÅ«ÏbþRö”:Ú§„PòöšËËf‚¼0/£V©|µbÕÖ|BEèÃ’~¦Ü‘Ï‹í°åÔV¼øÔjbàìØïˆ$M¸G]”àÑ‚Š’þ,gÑuGõ–:©dØ;ÍÇmz´›ld‚º°&óÜÔŒ-ãq—ÔXd]S¯} C¸Aäø<ÁÚ{£f‚Ä•›nT6£N+ªù*}abÝš$#Ô* ø§wõ¡C†á¤,‹Ö# N¢Ú~-Zc“qÈQ­>+â«V_šÝï®4K÷NÈ¿2Ždà Þ,'¦²ZÆ'¾7¤‘ë¢5¡!IËÐÈÖmˆ{w B±¦»¥°ëjXòÕÑp‹ º ' ¶å¯‰uç^»2`WR¨¥õ˜&•¨~I(~2úUì7i6‡þ»wÇÿs{s™ÿç Ú1„à\‘¨&%©Q´0 ùRhÕ@‰ó8VÏíË'?À_˜ÅìXh²¤Þ‰“õßÖÿ·ûúí·Æˆåðù//=ŽÿúüÑÁ+“û [ý£Þúv¿Ñ®¿î¯íC´õ¶"’~k­í×ûÿ¡[ÿôäï ã<;xjñΡjûŸoëDdj»ÜFˆÄ„ÈõE¡XAÚÍR?’P{(‡nFmCþ95 („¶ M™Ü%âp–hƒ~f}qL½‡ÈÈ僇Ãâ|Ó…9u„ B†o5I(Ð ×–& ñÇ..ÎDµä!©µa–+Ü©z:®o5ZÅiv<‘Ï™<Ø º•¡À°ð£„-°‰±ÿ{&Ʋù±9T¬ÕkÆG|Ñlâ³IöC?-zã wD|Ñ] Œ™lËúñ…liœÞ&I6U$Eâ}¶¦\¢Àw­îúwx^dü‰l¨À$aÿ‰›ÔMY/.àòˆú ²·•€ØæEù@Øô—í‚öû¬á…Ûixpºã•ð¯É^Ñ7Ž`1õBfr‡DGÄRÚ„ÅøÕ3€.JVcr—†iGe»¾c‰íYÊàšÖ…&gÑ&ºeñ2ö`6½ƒ˜5¥ý/mHú9µ|3=¯„¹¨«ÿu›èzdYJpÅI-¥¤Ç &ò퇧‚”¢è /j:…Ñ>YHß ½Ñ-z>À(D M£æÎ,¸&iø$Ðh^J1ݽ+RQrQf}ÄRØm‘úü6µÂ¿p3­ë¯dn ¢ƒšaqCT€M»ŽYº¬©Ë·…q)ç²û®`0œ¾`{ƒŽrÅ}þƒ}xbµeï£q3¢üñôî_tÙ*0ˆèia«Êɘ†P ½¬ƒœBà€‘áˆ²þxÇIh Ð2h8týVÑK†õ0e¦(©l,˜u6™ÿ)€Ño2°&ú+/˜ Ô·ÿ´ÑÂLÙ¹H»m&§êàwXYôÝw럮°…{õ=L÷²©hÕïÞ½Ó*{E@¬k6OŒWßC—ÑiržFGi:T¦^ãä²P¸rBäÅ©ú¿Õ÷z—6I8 { ¸XËÿ¡¯Y|¬özþ'>ÊûŸÅÿ{kkkÛ÷ÿ¾÷`™ÿå ú,ÀµCÀ|ôó/Ïþ;>|ò¿ bߺïü×®Dý9µÓt0R·()L1=9…L‚Ÿƒþ „VHdÈŠ—ž¯¿Ž¾^)ü>mx2í½(LÔ¬FÏR… :¹µªBœï™›ÍF&?1¡ÃËÓPÄ€C…U“RðH™jˆÍòQ:¬‚¬jZF7p$soOarõÞét®ÇŒûu{ 7¡™¾aƒª÷§ŠªÝÛ«ctÿ†‡}÷(è¿O(.Ånÿnò?ÿkƒ²æÅÿx°åçܼ·¹µÄÿ·ÿCR"ƒLUŒÉ§%à /šã c|Xpj ‘9( 7ÌuŠaJ=A+E‰†‘Óu@qàC cÓ\û¼ô\äcc–DôçÈ$T<&PE<&Ø‚Ðnè1yü¯©j6¹ÐÑ%ûjóŠÉà˜‰b‹VõkòCž+úp؉€i{ó¸!¼ÿ?Œ7„æÝÿû~ü×í­eüÇÛtÿõm‹ŠS4dqÜ`¦‚"!²ZÅ+@.@–Òú)@iÑ}Öt˜å»ÐÝ÷%¬ž›¶bƒ<7s,Ø0èžO½Anäx¤¤„+9½7>RFìLú_?…eïÿt’ 6œøŒ7¥œoÿëÛ=Øy°´ÿý‚÷ÿd.4§GŸÐ4‹2KB† õêeCõpû›S"¼tœ)û–âŸ?{õøÙ«øÕÿ¼@ÝÙû@ÚÄÃÉ…zržN1«E‡qÚÃ¥€ËMã’0Æ—Æ. ˆÌ®+Sb‘êò£l˜Œ/¼yo’NÖ‹‰¢,ÎLÍÉ»‰ª6IßM6Fƒ$ãàï—^Ðç&;…Ž>X”2"•c¶ŽÉðÍþа,í|ÙÀ4ˆ ö©u1L>ð¿-Žßƒ…`TÄàDëg(ö'©fç|/x8Å¡˜šì–"Ký’ ²d0¿ÿ‡øÂ2Ýx ¹ñßvÊñßî/é¿/ˆÿ)–È‘ Fu2°4Ê…jŸýøâù“g¯t=íØVª¨AŸ<{ñ‹©­ƒ¢Þ£²ÉÏü¿PO¥€LtEÀk¥ ‡¿ü ëÓ£`µ_Õªž¿´Köóq©ÒOÏ_>=0+!vÖˆ÷òàÑÛõBH¹ÀB±’^©úß—ÿÿ|pø³i¡Œàð¹«nS ·†é-ÒØ­ÓÚ:¶gOkêZ!JÑÍœ¡œªñÏ~TðUjÒb#ƒM_¼P30·i4ÎGéx¢ú–ãÝRSÁ)qÆQˆ-ʧc}ðêPg‚ðU Ž™®j&ˆ¹ƒ"·¡š¦£>œ/´+õ—1¾ZéÊi¥ÎÛtŒÚš7&ÒÊ*AàTâ ­ºÇItÊÚս؛U§&¥ÈHè¢%dVqFô‡- BgË,9æ%Cõ½ˆ[¨/ÿ =•`x¡«^óp;£fãIŸ¦À5W'õ9dáVÿó!²·äqé¿-&ß8 ²ž ×aH rRBŒ(P…Ùq<ŒÇ¦7Lz¯.€†èg9B0xy26Ãu?”öæÆ(ßX3<ˆÏ¯+ÊfB¹îq’л¹ ð"`¬‹ˆŸgݸgŠ]‘7½´½¡[¯°“ñnSk’Ûñq ¡+H b«ËD¾öë"ˆÎmLmÕ™×Â{Â×o±ž$R]¼Åz =³.߬^õ­¢ë4«¦|áÍßUÛ=ûÕG¨ˆK'ão¦VˆÚé{:^§¹.DËYcr'Ôk‰z ½z‰#|ÇX½0qM½ðIa5^2ß7½{mþ—6·éDZmË­—¥æDÛnB! #ª'á±]¦3ÛˆisfÛÔµg‚¤¿m—ŸB:>ƒÿçƒüxqð<ùïýí’ýÏÎîRÿwøÿ›Mdu˜§õ ˜ ÆZ¡@.›áè ÚŸÏ@ŠÑ5ó`F­@m0‰N·îƤ¡éVj²Çñ¤f[‘˜^6‡¤ð3Ü §äpllíqÑ«B‰ cøóo…‹½>ÀGÀ&4ƒ£óÀZiñ{£¥Îtñ¿ÿUZI"1n+ÑJ¿#$›|£(×Ê¢ Èdê A ä–OƒÑ"ò òË {}?,mmÿCÛyãöè9=ü?NO²b2Æ÷çÆô€óì¿v7ýü÷Ž¢ÑŒ¤ôL&Âå'ê@ô{´ ŒÍ§:M]€ÍûžÅnh½-_ü¦íª±èÓïJ[e‰ +þex üàÞ«™ÈÞÛH3ížù˜÷¢†àд ÛÎ-‚”Ïùwé¡3FÐ ¿J³Awɇ} üŸz ²~BñXoÖxnü§›¾þswÿéKð«ZÕ&ÏdY NX½3Þ ó·ÃèW‚”œ9s¿Zð’ãモQk=Yð¹éÇ M€ØÛÒ;n"ѱû™ZͨÈÁ†ü}ŽR¡ŠËSŠ;›NLòiã©Pœª×ˆRã-ÎÁ»s¼‘~A¨¶Œ4 ·é\bŸ©.ÚäšéÐò[Ñ!¨K—#î#’;Önÿ j­x>T´ÔØôZ·“mÒèú9³»Õ±u€Œyc°tï¿ ð_Ä™šÁG怜—ÿkó¾oÿ¹½µ³´ÿù‚òŸðe6q³‹' +.¡øx8U4.Z …´;E/¥Zy‘¡Z“#EËãð(sìÆI.Xu%õÐÂ/~¬dSºj¹4Ž©† qZoÕÖÔýNÕ>KœM?ñ;wÜŒ¸‚BGi/ÁoSŠˆ7N{S ¯€¾•Ä­F L£X(Z³ŠF‚4œš½É>1q6ìg=íb¦"b~z …bsU m:N‹|:^IBu½a]'é„Wü—B…gi2,ÈÑF]@¨¥M¹è­¤Yd ¨°‰Û5ïºýˆ-|› ÑÁ^)í¤äe»â#o­¬ˆ“ý:»Ë˜ê}--¼ƒ+ïR®)¹¿å­%úÝa <ÔdšŒ¢”xk§LÚl(ù«}¢ˆ‹ö äH?æ0àú$Ê0{kRŠö?¦ª{n†OŸWÇÐí¶ºÓÏ*2ÇD 'øpp±û}媸7Ñ3+ŸW¤·Xã‡æ§ÃI¨¢îÄŠm ®~ï”Ü8ÒQƒõmÍÊ9¹û¥Ñ™ÈÁ Ârv!ˆW}¨Žÿ[‚RS»YuJKæmÉÿ úŸÑOÿcçþƒÍrüeü÷[Gÿ½@¨8ä—ÇÐñ Þá-$^sˆAxâV<ú‘å×?þµÝ~a6ë|™Ç£éˆy?1f„áx ˆƒaôH`œQ¶k~°jÑÙqÊìùh¢X;žwMâOŒw¾Ëb VuJj¢÷@1“˜}ƒøBýÉi¼ Ñן o1A,¡ðÈcÕö<½|ȯ&ääeßæŠ9hï{±C4z¬x°[s—n£ƒO¨½ú#Ò½`~ \²ã‹Š¦ô#ØhÇ@‚É¢ÊÄŽŽ.²iˆ¯kË»³?· $])'Í’'­IMœîI~žbÈ3lݦìhÌì‘ ádœ+ð»<¨ÔŽi-Pd+³À;"¦ÃþìèCì!à2ö'…?8ÊvFq($Ye§CDã2ÌòêfypÁkfÕ`]eòö¡†q›ªèèÛÐu¸+SËT£]™ü(³Ä‰®¥>–I)ð’UôG4¦Æ À"¤ß'|Ò{uð#ö(-ƒÕUåÇ®¬«0è8í[T¶i¬꛵eêø5O €ÅõC„Ã0– ±7Vȉ»†I]#Èàx: åÙüªI“¬fß‘Sü¤.6†D.ƒd­àQNF°+P³h‰glÙ²k4Û¸\}Lñ¦—ÎFÕ½»âì YÝ 03Ø ”{cHK¤$ ÞbêQ(sÐFo=Ra<[É·–àîœgQ³ý-5ôÍspå-,@œQ¾KÄGöptœ™˜{†zXlœ©|Wí abµ‡lK­~øaޝG f…YGŠ’Ï4ÅâÈE­;!‚3î š®Â8÷Ï4›6,”vˆl]wò4¢˜®ñúeW\ixî ‘¶ëbz”ûÙ#SåbÞÍHÝOü×tÜG†Eƒ¶%Þ«Éé´À©ç±Apϳ!~£Y^{Kx!bOJ—MlÊY»r•‘ÅSl‰HP9%Cñ4«BÄÕŽ£-æ`íK Óïî¾îêìújàÄ¡Ö@F&8¢ÂôIu²Ï\‘Ⱦƒ‚Ê.Å~ ³~«+~?Ÿ–—è¡c)ýê7®ÚýÂki´ŽÄvØXœ´ŸEZƒÉY/Ö¦ï iÕvä*9€•çûõ6aäæzŠ¡L˜vʆÇé8Æoª‡º3ryhMVíÉ^PÆJRóMz—=kŒ‰³ä0 m(jiRU8Î-4Bò.êHTÿ¨…)z+~€8w`h„Ÿ»á© û¤ÖÙ±¿»ûu]¯áè`& *ÆT‘>7ÙõÔ=UEª:£º]þèÖPqhÚ\¤£‰xPÝ*8—•PåÔ±c¡žD_{zDzù`†‘ï£hð§þ€Û¬@2𕶝žŠ.£KG£ÞÒ£Z¡BÝØ´ uö½d=ų)šø8ÉñqRLì‹ïs BAN½iSµ[¦BêìÅè¿jõ˜²ƒ#‚SçLž)$ò\Iø¹+ï»E‘Štîœ.éºQÛpðzM—Öš­ÈÈRn¢/䊂Ë7šSO=AEr’V€“. s‡«Ñ´_oÓh<%S5ìD+þìæ5Ú¢Su‡En °æVÛpŽÄ"ÝÐÆ!Áö6ÅËþ6¿òQÚò.üëÛK ›p$ˆ¯ÄÚª¶t%$Ò²<ºÅŒ›?„NÓ©1ÿà*BñÈ|Øhœž¦¬V]Çs­Ék¤è]kóRa—ÖLO†;„ýPÁw:„ 9£Af©é ÚŒǯì¸< mºgI:ú3ÅÒõ ‹gz"DPã@Ü¡Ñ@>¨¢ç£1dfR|#²^ Žfúp—è. '€ ¾&šU0mß[Ç2pG†nÌ—KÊò„0BÙ9 ¶P}œ%Ò.¿_8X7åx:–ø¹ëc»³þ‘˜Ýõ™ ¹UÌã_þJî9t˜eu gÊÞ€®=ç¬#.Dè³¥ÍP&Õq]â÷uê ’ÉñAÁ]V<¬Á±þª&gâ[”Yy¸V9è1¨Z©‘ýœ0Ð`ö¨÷¡º©…Ÿƒªik઻„¡ƒEÈ6¤†«ˆ6,lÌØ†YÓŠƒWO+,4AÓÊC¯;§Š¹‹ïU1s³ŠY»U|ÌvWÙ¯â*V4¯~¦©Îbí]2=tò ?Ù^2€'4Öɽ …/|_!&¬šLD/ç‰ÂáÃÉ:½ÆDYŠWo1 ÏýНóœq•+ LœñûWšÃ#3:¡ú±/qv¨é„¶^¼;r.ajÕÙ…'ôü?ªMiÉoi ø_NÄbhûNÿ-ÕŽYh³n)*hd6Y-ƒÜzŒßìÛú—ÃçÏÖ@͆Íê´!7ÈÊ(®™À€¶îÕ4¦ˆÒš¸11Û0^秈¥,åÃî;Ó{ÆT]ãlx•EƒVke6öǰõõèuP›7/‡•Á>l|Áw ö3b„¯ª¨› ÀSá"‚ØJöh+6§6Iå‚w»F<¾à³W/!©Ÿœr˜ìÎQ cÔ‚VV}Ö«™‰ Љ-_µ¹A]¦ªÓ¤`ú“µ }Icfr«±®ÞLä€ ¨DÇB›xMÑÇyÙ‘ì<vD!(2V[Órâµ5-¶ä±¹CM–h[ó'àf˜<Ëüâ.DÏ:p/D! ° O|Qya®xcʨFÓ`{N†,:éôHœHp¬‡Sõ*ãsמù´–òNI~˜ê*nØúü=\sWW\¨3#öD° Êļ•¶º,wXäDM?Jöà/Æy¯Ô–k F€”žÕ¸û¢¼ÓáKHZˆâ²•ž&ûÅÞ*‹ë¯"y«fX²š"W ¤ë,oLëÏÚ#ÑVË´õt rl¶ŸÖÙð‡O«Á»²2WÿDlÃsüh“ů٠Mî>\Tˆõ¯*^0ÒÒI˜ˆ0(#|tá “ŒÕbøg\‘p.^Òã–P{°Ç D®ªÓÖ*Šn“tcÞ2«U)vâGWÙD-"¾ ï¼pDÊJAÔ,öø\[ê»øÈŒ§¿»uÀFm²þìBº.“!Õ8dã"¡pÚn¤“ŒÞÁEMûQ‡?¥'ÙPŸBKÍ„Y?¹ÍeÄ÷k6žLÔš#í6[Lù94ÜiÐ/¶~|(÷Õ:šfƒ>ÿe…©h Éq׊"Ú‡¾Ïùò¢†èòcñ ­Ë!œôÝdœô&ú©c„îÛ1óÒ[«—Gj…àIK;¢–ºô ãÚÞª5ÊGêP=Q¿'‰ÖÖV…e®Ñ\Ju‚µKrív8Ï6,Ôaði‡tÍ2»"I‡È¸°õ6ôQþS=ì¼£pî¥r ‚.L¾|§’™g^„ÇÑÊ™ Î PÊêß´©÷›I"öÿ'Ø¿©(p³ýÿ·¶·lyñßlo.ó~–ÿ¬' p Q Ï~q&SÈãÚJUµžÚ¾ü ÑÖüÊZ¤´`u–UÅVL5¿Í?‹|X]zœ ÒÚÊÊjô"™ôN‘¼)ûMny”€Ú&'©æšÐcU*”¸!i]Ë{íNT ‚îD—Üú¯ª«¬y:K²!·R~|A‰Ùm Ž—×÷$Au®ÐeKÆÓÇ FNñ„]½ RÈ‚;r¼0TgÕiþ&%Ò~:Ì'©Ý\ŠØc¢à{¸Ñ¬5aÅPË =ÿ„=HüÉ á AÿG65FºÌÒÒCˆ;WçÓ“S¾TV™66B¢A~’õÀ€7]ÏæÅË'OŸ¼zòëãCðŒB¸gO.ë {í'ÃIz’Ž­4ã§Až»²“ÕPgÒr“{iJQàê6mL2‘€¾4_¯T±ýB¿DO³¢g~VS°¶rB¿Ñ€×þ~©X¢vû)bÉB2ÿ2R‹ë§ýŸ2£Œ7iXf”ºòê°&ãiOÑ~6ûá«—¿ª55»Åo…ºbÑ÷ÑV&~ÌÓòÆD'¤‚5 D£ª[ÓÔÔ¾žµÒv€>ƒ xgˆ.¡?¨}#bÿ,A³L'ëùñºj¿~”¿Û‘_…"h­ã>kÉ»,?['S+ç…[£ÁÖÊGn ™ôX¯‰µ éÕZÓ}=É‚N3³ÊgúMßЃ_Y±°ÁÚèá°Â”KMÜŠWÓþþZëFQC¤Â€ãÔA|éúÐfK|xóÃ-~+Ž?!”¶½á†ªH£cØsƒÒàôÙOþ 54Õõ0O™§9#D~‡œ*QSxT–¿³ç« -ˆ3qîÏ>½ æAàyYК*f^u׳Ê\2»åºh ªÒ1ûC÷äŸâí$Ü,ô{Þ!¦í.? LAB(Þ%³ 3ä\1ë^îzz½¨véí¢IR’Ê*ûà›•ì@¡Äà³}ŸBXÄÖ£Ù-I4$ÑŽxÔeºq‘7äÚ)ofxUþf½T‰V¶FU»y@ ‘}æ{ï¸WZ»~çÎõq qóÁ6nu¨¡®ÐJùyJ¡­eâ/ÿ7 þtùvwÜóó?ln-åÿ·(þoPlù7-êEm‰‚ZÓÔ¨ >!P¿±àC[1ÄÐ…vq Z…„¿õ>Ò$Ï¡Š5Cà¢]:¼¾àÛ _˜œiyp™Ôxr¬PíŒ kÓ?€Ë’ÓC}NqÌX-x)!ÌÎ&ƒ=ÞæU‰‘xu'Ã|ZRTðA€#aûÙKÜZíá U†¶;‚£*©¬ ÷\‘¤ÍŒ7FnD#5Ÿ¨Œ; |ö<ïê—åÔss‚YRÿžÕ% 5-ÒòC[:”®…=ýÀŠ Y ëJü§×Áƒ¬€æaÐViöz@üÿhœ®AÆÔ/ñœ…1ô˜7½ “Ì,R1;Ñ_ÏÓ1ä Û§ƒAv|Azé¶›ÊáÒëÒwác³Ð=¤EgF_}Ž{>³Êj)_Ç?Êc2 ¥¼œ¥¢=§Þ¸wd6‰‚1õå·»ï/ïþ6§b ÍmëtÍÜh§õ®‚;¸äÏéNš“©%ô_)¬ÿŸ ü‚í]·¾_ d9$g¡;@¢I„Ý &ú%_…¥¿oÇ_+m$:æüO¹¹ÀDÆØLß“r§ÊnZ˜  ö¼sp„X Å?eøýðW¦£\k çV*–A|ñ6š¹ÀüiþE¶\N"ãn£Ö¬æ•dC³´x”yQZ1U®“ˆŒY5ÑE]›½ƒ·Þ@µZ«o~ÄþFÒöU°Ì¡cuYþŽiÛƒd¾qxñ!ª’sDcEˆøt†}ò³3,?ºp¥–Q¥I˜7çfÿî<È,ú?`Üq-.`ŽýϽ›>ý¿³}™ÿí¶ÓÿsÌÊþ½ÕÄ3ÇÔÒÎÃcß7ºŒúû±•>аÀ“¬8¾`99Ú|`ôcìg- «gù·+ÀÔóDãHü*6H*µÐ=@¶Op‡hÇ‚ ˆš]Y¤l§ «oÍTv„Iš%jFZbi„w ÀAÌÔ¿é¤×jè Åìj€S‹iïTøðÐ3Ì‘‡éx‘+Rƒœ•—ûÈ×û¯ó…ˆ|ï¢p‘Þ1òfÔï¤0{‘RÁ5$$×´³îpúyâBX?gc*°$1áš+'äúš?MU Ûºä'ä‰f—cð1 µe°zec ¤€ OÆù‘Z'Æc+´¨²Jx0PïÕó“¡Õh˜eß> ã-K¸YX„ε¢jxža<¾Æxš T™3'ËÑÇàÜžÐnix¢ˆ{,•ÀED‚Ž2!$]@­àòˆÙÙÐ…!ï‘¥¾Ò‹´åÀ#ìV÷r¨= 'ê ûÓžž-0%Z¡MQ7L{«¤C°ùáÂÄߣޣ˜!¦&ØÉe=oÉ $’e}ؤžæD‰§Éy!º™ã±8VÑ<ã¬ßO‡Zòïi[ ÷šù€ÛGI\ܾ¼~Æ ÁnŒÓ^ –,Æ0D†B%¯åÒŽ:¸Ù½Fmq,.êYšª‰ãnÐûÁÈÆG™‚®ñ…4dd>Kúi„wòˆ\H$…n¬‚vÂ$ žsW)í\RÐEqCñÑõð\˜«¬@ t`JGƒw@Åy‡öD_)ÍíÕ²çHº¦’Û.ÞʤlÉ¥qŒkVXâ’\ή˜AÀÛQÄCéŽkx%â{’7ªàÕ]Úã8—ƒÍ4ˆulÎì!Í,ÉcB:4S*ÍôIѾãvTb&+ú`@HÉ{ñ<Øy·'aU_÷«Øƒ’̯¹ªÁ¤¹ÊW„uû]Ñ.2~Ãv^œà•à„—tXý¼'˜´’8ay 3‚yãü•Tvš}Zº×ØTpãŸèï²'r¡i—R€¸@KOФÅÀ^œ»íÏ邘.@òfxûiV(àUÇö .F‚bHt».ò³”,/( †h5ƒ*Æœ"ã>‘~ôM:ú»†E3¡‰0³ÉÆC?‰ždØ‚ ¥„kŸ¤– ÞBJß#|>¢È¹»$Uê: ‰ü¨ÀÔIŽ×¡8BL¬äÈÒ ã øÜÁÀšñyeé•ÓÜLŒDK"—±í0xLX”¡Z\â›Õö T¼G„vY cšhÌ´‘C¼ÈïbàgÀ×’åuq ƒÅ~Ý»çsëaŸ¹7ÀËn‚ÖK@ÈeÃ4¨Äy›ÖÆŽišw ŽˆHýˆ8fþ[ÌͪK;¸ïJ¨‚>Ö=UEû(‡ÂbÔ])ì6h7³¶þ*-$"2€ð¤ÿ\ç¨P)Ft³O—Ú(46¾à£ eL½aÁŸÏB¾â~kÍý•¹\6%æ´^àˆÔOÁÜex¡¹Û•0)/ÖOR9Š«ž rÌI>vÕ!ĉpª–œ9iÅ®e}ŸöÁB›å5({(\s™­•Rád±ÌE³Ô…à²X’ÐZI9P.80t&RãX¸ê°0´*.HûÆ=:æQ¿ú05H¯PË9€±PW=7=’Ëö!ÿÅ{ªcêÁògÚçŠ'dd!z©ñ«dØ‚{Íi ÌÔ%íëÐjÜá´õýó©ó€~P,›ìXÁ× lÝŒ”ëß3½g2 èvplÏÔûû!‚ÿe53ôÖÙì:Ñcƒ(ÃJ* B5Þ£ØNÈ'ª¦`Çs‡ª¾æ:è–¥§)3iô…?ƒ|O.¢·Šži9šÿŒSºÒ—t˜|Õ `7;;Kû(ã;M3C½Sâ0œ–z³'Üô’¥-3a¤ÿוּ| ò4Œ ­ÃdGÍK¡I REræHáÍlAw…W0ø–Í@iÖþ6”ä „î÷3/­ à1µÒu«aS¤z:BèG¿Ap®ñ “dà¬É¨G(#Œs¦îIßIDKm†)6êZ»°‚«|°Al­]ƒ˜4qòÄ•÷³ó¬?Ò´Œm0¶?‡Ö•Žþ$gGýcÖªî?„~Íž4Z“d„u!ËN§œ ×Ùh¸x½a¸¬gè é? B€ª+!K„Ù_œ« ë\(¼+f7û™/X¢6Ø»Òfo^xu¥==ßC‹Î ' 9ιµR"€ØÊ™ R¾3ö÷¾>:€NK4›?‘z–þ|Þo"ÄûÏ­û;^ü‡íÍ­í­¥þ÷–ëC L×ÅÍ,_¸*¸QgÚ—â+0rhE½ÉT„´š $œŠÔ¾Ë6m<ôkä×û’â¬ýIŒhDÄøØ/2$ß')P':Í´2^0çXçó“¡8SŸƒlýÜuwG._Ûö é ÆßŒù¡Ëu´¨t_§„`RÆÒß?§£dÏ:IÞ€„±cØ.g·\„¦ˆÝSÖA( &Ëqba"u IVYº¶êŽõÐh_|#PÛ Â N;6dÒbP £'Ïyá-6¸ê¤pI:2>æ£TOSŒŠ²fhóý¬â pk@Åæ´íO{o@’å#IÇÖéÍi·Ÿb¬$ªKGÈMÏF°¢ÆçÀé7…ÿ!˜ÊgÀÿ»[vKøÿþæÿÆø?Q"ç¬|Ú÷€3@Ü—¢:.DdlÒÝ÷þ!^o•µÌ2­«kóÀé­èÉÄH`07 2V.Ê\åä5`Æ ˆ€K ã³Ezƒ#3ˆöîð‚›·&ž¬! ¸&µºÀTœ§Š{‹ž £4Cé.Fó†Î\çe¡¦dõ2y˜cdÎeèÛDJ‹”uì,uÖ¯ªó A¬Œ™ÏÛïÈ¥ª7 ‹» ) ¼83¹RêÁh~÷Œ¼Ð5!ý!‰°†?¿o³AwÁGómƒ<Ù £¼ç©àF^ÄN(`âàhò{ÿmüãuñílˆ&°ŒIl°VÓÊ&0OAÖö•Ê:´W)¬:‡†z›Ú&^*r<=nV kÔ2Ñ[÷ûFj £&X»¯E”sZÁÊ °bÅï<Å•hùt¶Û`Pm57¡³Jm=õƒ—¥^øæÒ‚äNXÐåK±ÿù6d•ù»Â>솖02;’ÌœÓÖÃZ:¶œ> ûÝDƒzhàÒ7®P$ãÉTí€"µ„ߌºû¼D¹£‚d÷P«¾Ü+jÖ?ŒbQM€”KÇ}ÔLÂ&Ü“2.#iËwø·Ìšò"õ‰µ¢¿ÆÐ‚,Ù÷"hìªHLà¯Åp¼ÊÑâ%jÁnÕ¡†Ño"Åæd%öп8^^é:è —.¼_¯ý0^ã5‚9ôÿýí|ûÿû[;Kúÿ–Ë^92x û¬IC?àâ‰!W-ѣ兠¥dsAVA˜OK¤¬™sh/½™5ë\ 8¤ia6-”vs()ǾõÐòÁ¡ ;ð´ˆ=zdšL8Ú#p0¦%É)‡ J¯¸–Nê+_ £j"Ó¶è>NB96¦õLÔ åtÁ±KQÃëØbâ{.iKÉÙxsB[ö1¥ÙP´±±—Ï$Ûä„äkG«Ng ¥›6?GÍzk}&WÝ)Ý¥9ݵksþÀI;üËxNŸmüL.:Žù4k³‘¾¬›KáqÍÕËnx›4Ήg6Ã$Tl}ÙÕ_AÁ‰öfù(޼D“_‘½ÖÉÏ\1Á'à»1HÞÛ” `} ´‰À‚ôÒŒ©@˜¤ª:= wŒñW‡ìáž{D¢g“‹¦Aìªåhz¤HÎStbå‘Î`ª5+´Ö– 2H†ªÞâ™Ù IÆ©šBÔYå*&U¦Á\y6îE’€-úÿ1^E.ËÉ@DªK´ù‡Áÿ6ëø†‚“8Ç]ûº¶àóðÿVÉÿg{÷ÁÒþûÉÌ+1TŒ½¥.Ž!’CmÅJlƒçãg ž›¼ôÑw†©ÃsÅI‘r¾ß¡DÈ"‘²k¹_zùR±Rp:ž š\tþ R† †KúnIÿp‰?Ò |žÿ‡*öðÿÖÖ2ÿÛí£ÿfFr¢J¤ã¨\¡u5|d¢9€.Í"zTMéüT:H°õ¶k¿hMcoŠ(®í ÖX? 6„}” Û¤ÆAaJT¥KgVŸá YÛÐ/mlN.“Å ¶vÎ$h.üþô*ŒBÎõs_ï§#p†NDWÜÆïJ9ˆt¡fZõ¢ânSÇt“ ü~÷GzCáGöæ@Ed˜vJUähÝ1½¤°Þ]ƒg¼€›ÜÔušfÖMš@“úß‹Þ_Úñ! GË¢.D)ç"ØóŽ@›É[²gƱ…´à=×~†`}ñ±z”©Ã¢Ó6_º@º#1ržåC˜&Ó±3Emá¢J+eD}r ÷d½HŽS¿ús ¼ŸF«†ÊÑ*õ‹|Ji8&”S¾(¤eNyx LP¥Ã XéJUFÔ3IˆÉŠ˜â1ˆ¬|DufRA]f•ŒGí¤Ók›Ïó¬ß sužM‰äõ3D:’X·Ú×ÍZ>1hÉÄp9çi±ć¹ñcÅÔ×;R¦bùZJºÜ,úó]™xTÝdó㉚'àL’ýš|¬eQúØÅjÛrÄn oëDáQ¬ÍÈpÇÒ¯b˜¾›p2øBÝsŸâu™}A Ï½_ e–wÜ2ŽÒáx 2 ñ nÇ¥èMç0 ÑÞ÷‘‹ó­±Ö‹x³a H΋œØÐkDIgtÆ ÇÜ;¬#‘z£®•ŽsVß}-¢wÆ Ÿ€ÇØmÓœ!ÄoälÊ÷ڦʦ,nê8c…?Ô(Ayƒ&&Ý(@Ã-(oÓ£úF»½ÑŒjµF( #שwÖÿ·»Ö ;ÉúïÝ´z½¿ÞžÓRU~ÝïrÓ¹­&ãzm½¦*ÅúùÛa/' áÅZ@³ãšÕ"¡±!çkÛ– O!›`Ú÷·Ên"z(-°¹‚~T—ë$+ ¥ž™EÝ6lFNKoZš›fÿD`¶}£H›ïT[ÄÅh¶~4Hã“tRok¡ß‚E<MÞGþâF1rxŠNoêšbF×›(@;WvC9èal¥KõDðã½&õ¡+{óVaè ýµ´ü‘ù²ù( Àþçþ–ïÿ±µ{oÿóKðÿ,¨}ñ¯:s¤ g “¸pÅ “™²2¾ž¡7Œä·q2>©ô>4IZuŽÙ`‚n£:"º½[ñÄ\E]õI584{ãf(U[nôcäÙ¸ ÓÏzIÓõ…¦Ž[Цdûu3Ù†'÷Ó„—RW›+WüÉ®ª3îÚœ½¦ÆsÎýn`­©Zuºáñ• ´/‚hàw«¿¿,õï` ‡³;o>ö†iW€‘b’Èb³›½ÂÒ%Ü ë¬(©m897Ñð¢:Á7æåc°¢+Úîém#îwÅ ²áB¦àHt0÷§#õ ©Q€çñ¸²è3&EŽï— Ìd.­¤¥– ¸àÖÑÒsé?æ€>†œCÿmïîúöÿ[÷w–úŸ[§ÿù‘@a1"îZÚˆ¨,ð—4àGpÆpGÈô¬ôp&î`ú2Y±ØCRéϦ[”•j`¾ Sÿxœÿž1úìí½²‚ýº®ÒXpèy£¦sú1¾ Ž @:_~|}Ñ1Ú¤^Q6¬¶ÚïJ|^–þ Xp¥2×—õVgø¨"}=’ême'§¨ŽØ@rp:"-ÅxÛïB‘*¶s¹£~Q°cÇO}îìÑp¡¢)ì‰vòã 7*ËŸA¦ª¬TÐ@z_Ç´Gz¬Èö‰][Z½´Ô]Œ¥Šâ)2Ëj\×Ü÷?}—€_öG˜ÿ͵ÿ»·{Ï·ÿÛÞZú|…öµE›ªß ¥lÿ ÍcÝÄ·M¸9 @_U¶¼]JÛÑ)dô ÍÅí¹šà'SdDZ|×[ ß,+I‚š“ŽhLP¹ÕJRV¸,ö8’™äyi+¹þõ^ñ˜ëÿW²ÿÛݹ¿´ÿ¾uü_ÙNÛåÁ¦s¿c:mÀ „%ÑôA×ï¶Ž£ixSêà áÍ ¥yUd¿Êˆ¢þMþ©Ð(ÌÁ>/ÚéjÙã †Ä4ªëÇ&*Û§PdÕìø+k«ðÓY2RÓe}Åtu‡?n·Ôÿþá蟨»ùøÿ[;Û;¥øÿ›Kùß¿ÿO­?ËÈySF&ùaìbÙ•ë± “·9xlƒéÛ'qªœoˆUð/ÚG{ ]yu’8 Q“b´‡•+ÛºÂYÝh_óeX§/‚ÿ H>Êhžÿ÷½Mßþg{s)ÿ¹}ôÿ …›öþži…6¾þL–-øÿ}ià¹÷œž¤ïFŸÒþoóÁö}_ÿ{oIÿݾûÿAáFo¿kív= `ðˆÈŠW¶…3ϰèõj2|Rƒð»çóêñ(dÜÉO‹“èBÞFš{ÿ)¼í§¼ÿÛ÷w”îÿÒÿ÷öÝ´À*>¡ùGúŽrˆîù LwŽÎÊà.v„Zá!‡eÞ ÞåpOæRCGž´²ì4ÌTÁY °”©æx¯Ý¨ÙJÀ4؆*J+…éôAÄÇŠ7çù$ÆÙ÷"çÀzyI<X» 䯹»­ZîÌœ¡Þ#¿½þ¬;àß.‹“ãZ ~áìý¨  Uû™XE²û¢cÿ50S*>¹ŸîSWnÐèO‚Öià˜WøÎÙ8IΉxé VF¡•ꌵê>*—úiß/¾±£bw>ÖéËí6€Mbá&t¹PT!F¯¼Veu@¬gPõö¿,k!Þÿt|MùîÇÒÿ[[Þû¿uo{Iÿ‘÷•2’AwÄ ¡2°˜Nÿúøåá“çÏÔÝ«m¶¶þ_k«Ö:§éïéRöö5þFøŒ’Q¶A ÔbÁ h3ýOvÿ·¶ï•ô?[»›Kÿ¿ÏòŸÑìÀ1ǧé@Ñ«µ••~ZôÆÙ‘¡C@±Ç!?ÄW¨Qd“«åõÖ㜪C„ÌÜ×Iñ<Âf¢{pp²Ž*Òîü¯: myNíö‰oFtÛ 6Ãddû,yב@æŒ×¡¤JÊiêIzUGÏÝÓC¸-?±uWG)áô#g¹ú¹úžÇ¿Œz§ªÃ†äÓ» Y%Ë‹)ùØ™ã|DÒ·u^ÊÁ‹' [¬Wò‹Q+Q`©iŒ¿hÇÚ‘BA%˜¢ñÜŽjGIOÛVO|ÅØ<Œ´Q0¯Ã­’XAã¨& öªf…Ô6jÍ&ÞŽjÉQOž¾S<©C®ë˜ZDM&Ó¢¡ )JÿmonΪ|”÷/tU¹2½˜_~~¥éÕ¢oUí­Å§¸{…)""Aœ;?µòJL$0‘á_Ót|Áy‚X“ûä]ûj«û¨`8©Â€ÐxóºÞ(|2üAu\ýJš™ TXŽºŽ”Ï;5E´ôXT­Û¸%x"Æ0¡6º&|) ± Š ‹[t‹0yêŠ â½ Í|{¯3Í+c ˆ£•¡¢ÿ 7ÊÜ#J!ɯðò7q±þ¦ú|J]þwú±,@kÄ!b㓼úF]yK®)œV,NëËÞWpŒ/šq[óü(ߺ›ÀèxÃ$…»¹÷å ¦pÄ•‰ëð‹²*b㌠þjÍRGYÀŸàkž™xŠ^'b POÎÊ©“tÚ@ºk㉮9X)4$ wC’3(Ù:ÎÆ¥éàÄ1îÕñ 9¹)z§9°h ýE—Ó‚ƒ(`הϫ›`*÷ô]±Fb5î›tH‘UuxGˆfaºÍ&µ}^ =d•ŽA7µGWAl’=øà´jþ&Ÿ¢_Ñ©ý}ý£®¿‚É׺ 2©ák_q阪Q§ã šèýߎ(íg“v±í³m:̇qeóYƒåÌ!e\Ò/‚6)܇Zà:«:uH¾ 0ÿB[ÒÔ¡à€æpw ŠòËn粦cÀ–×ÞÏSÂPv¢QOl_l¶.°§ qu ýjðjkÜí‘oïµ×fÎÝ7ŸþíY¶s|°r~DÙåâŠ|¼ÕôÖõ!þÖl“H‹lléâã–ìÓ§B_©9 'ÿï§éhpóâû±Ö›~”`žýÏÖý’ýïÎ2ÿÓ•ÿ3ãð#‚Ɔç#É<˜*(³%ó ųÒ8ÀHý‡ÓÑ(O …©âIÇDújȲXCq,gÉ$jÿ³`êØá„x¼x+‚¥q†]d`3tõ¢Úmw15ƒôK2Là é‰ õ‹ÓÝÛ赧ع åJ”a1æg;B˜XŽOÉÖéYŸåÓádã¢n+)†T‡4OM‰¿ŸÕ+NæreÅ¥>-íÉ3‡·èm>~S`ľéЊˆ XÌ›Co ncâ¹ÀÀla°.rÞà ß3-j˜¢‡ ÑÀi­j®‹Ì´¥{øBÓ½ 4˃iã¬ù ö³ããÿ2Ϭånh“w“Å×°»¹»tÐùÞŽïDÜ€î÷«lÿ¿©þ\¾ÿ·HÿÿxØåÙpâãú°¸e>†w•\Œqø‹QÒKgP,eœGÍ0Ê ‹{¬”:ëƒÊ¹è)&â $ëd7nÕVü×Ñžª]“ݼ—ÑÄ¢²~·)Šhþ¶˜~[áË™/¸«˜ÁáÁæþû¢‘óqž¦±ŽºQ;ÛêOÏFuX2HÉS¦—i%5ƌɶäa}îãäjIë0§3æÍU¾ØÔõøÎì¯þÂzøßÜÀØfšoÜq>¤×}æáÿíþß¹wo‰ÿÿÈø¿}&ÞñÒªöÇã”jµ’|¨þß,A¸z¦¼.ðøµP3û°‘¦QÝ`MKä,Ýà•|2 Ÿ]~xÞjñÁy‹¹âþÀ\?Õ£BHméÂ{èÿ!HaûŒŠÏDÿß¿ïÛÿnÞ[ÚÿÞ*ü¯Ðz»ý3A!–Ã=C€ácVÀ…ôù)FÒ÷$u~e ÒãÇ j‰?Ä×èÃk¨+ ºUúN‡Ñ|Cb<+Œ¤çé`K> |¼U ë‚ó÷|ºœÑ¶Ýö¥+º\DM.ðeZH[S~2<{éÄI¬gëÏíAÎN€¨7-šˆ:½;žøŒFQÁr3-¬zä3¤Q’´æÊëN ¬U ³m1wžôÏvyºoóñ ¿èt©rãS=Žþׯ 7IþÏÅÿ»%ü¿³»û`‰ÿÿÈô¿FhVy}£­ž†C¯w¤àżªZ·Ûêågª·IëŸjêu‘ÔQ:~1®Ûg"¬Ã›5««Y?^qf¶÷äM>ãþ›2'þh_ÑpÙ1‹T?©þëÞýû%ýÿý%þÿCã°ê·½$Å·V”ê–Ï1E\­'G=õ+,ÅàxÕ¼Û*Y/½Sßl‹zÐj 餈nNÊ8(Þ‚ƒÏè»NvC9ÎÑÆ¨wš véŸÐLïÖo_íôÞú–"ýîÝÿDcëÎ?÷ZoóRÂÿ“ølƒ{cR yù_wJñ·îß[Æü*ä?/`|ñ‡‹„¢Ó#…[CB‡€fWÇ›P ´Z?^]`ÚQ›¬K›ªÒ°ŸPëÜf©žò7mÝQ-¨f•’ªƒ)8I9>_ê+è…!µÐ?UIUh¼æÊ ¥fWZ©PÈ9s‘ïÿ¹K(³?»F³š±m‹È“Äù¾s°ŸÒƒ*ɸ|I“e ¢ûÄòÁ BU!Ãã÷—ͨöó«W/âƒG¿xU‹ö¾w-·ýnúºÄµ+*ªw7ï•ù/³±=-772/&EBóº^Ïå#ò‡’± ÿ,Gt…¼N ,ŒÖX䌯·ªkŸð5–eîûŒu•a„×õ…6|©-üôß8íå'Ãìw°ÿ˜œ~&ýßæîƒ²ýßö’þ»]ôÝ{SPk¹°Ró˜ùÙÂö7JÕ#£øäTKŽ.¢“L‘=‘Ó£@p?4¿Ú‘mC!Ô`…£d<¯Âï¶‚Î4уü Ñž©ê®»²Öh!£_t6»­|œdC­QWF…cç’È‚“pùɳc±úÈx®áSŒÛqz’+¨žpá=²Ëæ -°$œíQ«‰,QìÿsËÏ©ÿ Øÿíî,å¿Ký_>ËûFE².È;S¡üÿì½ûwÛÆÑ0üü¬¿¡O²¥(‘’Ó>ˆÇuœÄ}ã˱•~í«ð° I¨I‚/@JVýïßÎì{$%;­rNk›ØËÜvvvvvFn°Ùeà§¼|¸b{øomýi|øÃ æn´Ôåÿýj_¯ÿüø«ƒ‡ü¿ÿÍú¿âæo+ïwªUø"+Tíx¸ÿXVŒÛ0Ü[ÃF>²O¬î´õ_\Äù½ÇÿÆùÿñCýßÏûþG‹ e‚#J÷¾Â{Ð Ò¢s‡þª«=ZÄäLQû?ùžðdI/É¢=—bbËV9èÚ[÷5i£ø•‹‚¥ízÇ©µVE"£U0IÆS˜Š•´èò$#–3Žæ¡êTi³Ú0\Ò ó(…DÉ +{vX|^ݦÌ“Àü«êÝ}°?þß’Âo¢ÿö¿2â¿úï?œÿ?¡þ/E…ÇkƒÀ1˜å,¤Fô °åuè•"d]³Qò>/r¢¾>ªgXt‰PU%X^3·)¦ TÛ—F'ý„ñUÝ^¯ÆIhqªJê9üÀ¸y¢œ²Å© ØàšlÚà=µ¢:˜)Q¤Ø,ÒÓ5°Uü)õCY³’hô*hò "xóöøå›×ïïIbxI#û ~BsèEÆÓdt:ç,7¼iÁ’Z¿}óþxÄw”ƒÒÚY $À´’TŤæ|è“ï[xŽœ)ã!bt.ûÒ3bõ>…µ7=¤iÇ2£@;ÕÃH«bjéÚÆi êT£ÑFêE[ºÑ`ÔÑir_&£iút)µ¿ÐêlÍâqžD-=Gz ×sù%¾¨—ت÷/™LNæ!,eH”¾H/ˤ†ëâCC½î !X&}!f³kô™Ï¯C[ö’PA Üaa‚¿Üi–C¶b&ßp«›Ÿ_õ¿â‰dyªÈT4bÝ/–ËE´·wuuÕ»:èeùùÞÛ<[fãlZì±1øŸ»E2îö.–³)ËgËiLÆ/ópÁ«¾ÅR'4Ìe[èzžÑXÞjäÁå"ü")÷GÒN¬õ²l]ð³M/öX ¸j!<²q§Ià»?䬞_³d’Æx ÆTÓ ë“Iè!¦”ˆ#öãè~¥Ö:yãu—'4;¾~íÁœ‰q¡iD’=…¨v‰ÍZÞ¡³‚7ø„uá –¦Ó%yžåmKRí—Ô…õhR¼ï³üÌO&Ms^Ù8¥î%ÚA$ `E™Šd¹T)ýC4J[[Û§M<€íg(³Ã‰Àz‹x;pm¦Î xÈ·G¹SÉ%1ƒÂ¥²ˆ/ó4¹„)i†ólNÞà’±c=^$%[mÏXKòQPn‘¶ûFj¤È²h„ÿÝðà0Z™½¸=Ó÷Ø,¶@¢~A ÏHoÉ>G\u;Ç0È¢<žì¸­—®º7"—ao¦É*À\‡`³Ü:Ìû=ËÞeŸ£ÚÌÀoóám‚:ŸS¢Ë–E2=“(u:Í Ù}@M¤ÏCŒ±%°áUøŠòÇ@|&;!”M¿s<•T<„ÏjŽ‚JpŒ‘l yê–±‚Ì.úÜFOO è.SÐØ«"9Ÿ=V5“çd|%ýy:Ÿ'¹?±gÉìTKîZ~ ÷Øw=þÀ:ADGö£2|A >ôÎQæ(B¸÷þ«—´5£`Q²ƒ/áo_P&Õ>îÏà.þ7”#ã,VÙ°çlKÄdÑ‘–KEéÆå@WN͇¨˜o"ôØB©_ØC!ìå ©R¤3wz;”!((…ÿpÕ>'â¢LnÁÿRð%Ðé%ñ‚ƒßâiñ[yNmý«÷è†ütû/´%çÄœL㢥ê÷B)©iæÛd ®ÐKæ Aé*É Jâk8bì›~ðdæY\ž Ó_yT&§]`Z3V a$–¦„[îÚÜ0f¾‚êe®ξÞ*×ßàu3©©þÄ5°¾È 3q3Rt•á£`ïd÷‡Ú»ÍÒñEœLý=XíÃýÃNsZ«c“^ÇåHâRÒà™9¢í­ù”È %SãI|ã"èOv³z¿ä^bZïKæ >ÃVîZu``2¯£Ê.ü¤ªó.n»²œ†,ë ¾BboZ¼VÝnÃN“…¯.yVòK)¹bÔ%Ê]fpø®Êêþš„V´Ñ{ª¶~ž'1œyâú…>²{)Oàá`Wb‘.Mǰ©èŠ r¬™Bàÿl±¼ÆÞÉ^¾/òxm¤BêõŽ8gñ‚ˆyF˜OS¡Ãz’À0SrÀø•ÿòãÒøÖ(;±>$iXŸÝoÚ;—’ù%ØôßÒ’»2>@2Çã8àFõ¿P"ž<À(¡4ˆUvèéÊô>WÑ6‡*鎦5³¼ˆt<{ûRÕ=&ÁÍó,ûÓa³>äPò°©^y±Sñéyv™NÝ6G/÷ÀQÉ)»4ó¸”óì?±™GX±B“ÉH<´œ×Ui™Ã=Sý½ž*u¦®u$Ïãë ;ã ¾!¦åe?¸t ²Üø¡­ì înw7«`£ö¡Îç Iôq Kï³å•"¸ãÍùÊ9|ða•.!‘4” dÕ÷*±<ûŒP êÙÞ„T,#˺œÇîÛÅ^Röº$vÿÎ@ÙTl«ýè[A¦j ¹ÕÜ‘*`4{@¿Ñì5±@I8Œö 9žŽ«=HÜ2T¢¡ü B·²êÊ&«;¥4í.',jÐÝ<ûÏo±H-5_¿[Íf×ßc—ç’×ß¡:éöÜŽÀ! PÉ<ŠçP7Œ^æãd”µÙ”Q¤Ï‚ˆäÉ8I/Éh<ò¯GL½ûncêÎÖÆ'fš:<»³cHµ’pnussN%]«Tì7L él¦.'jÛs“c¡§ÌVÁ£æÙMæã Jp׳ÓlZ óòãÒ²(tG“ p|…E™=×93͹éþÛÕbI‹(«>ïô=°’ %§ìÑ7²óÀ}ïÁÜJõ-T4oZ餵XïÖmèƒ^:—|ÈÔ/ês%l«<žÐ{þ¡Ï¹R—ZTOZС5 ý45ÙNmš7‚öIDàè’ý“Q‡ÝÀ²nËô:¶hìrs¡oZX±gö¦»ôwâ¿ÓEí­KÄ`îvÕvéli“¡gçðuœD‹• Z‰)Pú·Õþ‡ß”ç–aU‰ÉîQÅÑ úä˜Úïõib“ÂJïÒzÅ]pöJsÐÃëoªQßb|ÛäÐðè&cGhP­·¨«ø™7³EØÒ8ú™\ʲdñ3V} Ðå Dôôx±j d8ÜQÛLÔqz5{Ú¥–V³…NLéðù›×Ç/^Žÿùö…™ñE?˜yéRdÎÑedð4ì÷ƒ(P4¬ŸØ®D.˜..5on;;.BaLå2ƒ‹tOJ!¶Diü1¼®Ò¹þkÙÊ®N^ 3r|±š€ØŠ<žgäÐ&ƒ_² {=ìÇbO&›lÞ.£yZ§ãwÏ^¿ÿþŻы×Ïß|÷òõ´=#g( öÓ‹×?ÿˆŸåK±m‹ÊV…E§¢gíëþçKçQ̱Áókwjm›§¿¹÷y÷pÚ@Ù4—»u@íÑÈmHö£Ë"è7ØÎ%è˜9°fo6õžJ7c§Üžƒ°Ù( ({±êÇ’;¸Ä-‚ÀÇnjaÉ8¥ šÙ­Èi6µð®Î ðHP{“dš,Æéó¤»óYiø :›‰¹š‰4PªÐ»äV¯Âï&𕵍¼±’ÝüšïÙY>‹Ö:ï¥õ’(xwÎñGí4ƒ#¤|n¾(. ¤‰"fáùÐ[ͲeDöгÁxêÊ lŒeõ@k᪱E0pÁ¬œ(.A¾X`ݨ ¦ìf?œÈG²{/òl‘äÓk0\Èé$FQt=z«Å8.’Û€&¬hÙ¼‹Â°€ÅÈÞµé®øl½µwn°šùŽîûláaHvpe¾GÁs\ÁKGAþNÑ)‚ ^Ñ:Í4ZT§YÆÙ<鉱ڔ»Á üe(é&j$“YàW~²cÉñL&£|L8žeDNÄ@Zé’ù_2-Ìî”6_~YR Óë°Áö«KÄû!kÕ’ñx$aêkõð§<1šg|à¼o¨¤á™Äd˜©5E€/Y7íÐ*›ü–ݲ9±Í™wkôˆ¬ßøš?¬BœðQ%rºš³·uD4©3±žÿØ}¾"§ˆÙîú3 Nv7|ÃoAB½K—úŃ[[§„B?ù ¨ˆÉƒÕÀR@ÜHùj€ PYoÏne«i›K¸F7%U‚xM$‰H•8ÅS¢+&×#2Ù&ÐA¸Ž ©ág²¨pˆrدR0táÑS9­ÔQ|–ÒÇñu¨ý~8V%5¢@+ñ8Í1ŽÇŸ>߃VØí{êWÿ¥¿M¸ú¸ú~ðZús›ö&¯W‹°n©‹§ßëmØ R4^’…{“'õqq$ÌZ/½›2ØÊ([å°z‘©ÁSü²®>ΦŽWÞ5RX~øq6µÝaÛÍÓàÑŽßV«§©ÂòÈùøäÉî?^ý´óä)ŸG”µú½ý–ð2µ~>þ~÷/­§ßì<Áç”ß៕SÄçÉ7šáôdØy²ÇZÃ^ÏðiÍO¸Næ—[d‘m¿QíJe«Ov·"wõ^èðFoó?FÏ~üæÕèÇϾ{ñÎzo»dܳ`T˜Ä:éëîkÚUðYø‡àZ›µ6ëÜsÆ7;2Èçµ»;nXõ3RŽíØÝà‡Ç]ÉxÈ”‚Å¿·˜ÆéÜN_öÌ…D“Ë %°Ê¾Ù¡H¥55-ã46†Nã_ã41ŠNÑlä0ÚXs).þ*Ï2n_9Ç8VóIW$ÒÇt[kj•ìû9 kCéÝÉ|´XßE“>œÀ(ÿ(}%ókdYqÖí«‘J]dÌ‹¯?ørºÈ² fõ9ŠÂ 0³å°Ñ†Þ‡äúiÛ²"yAå°[ ‰±R·È ”t‰oÆÉBf*À-móLÙmê'•ßÖØ¹gø)™Ÿkë¾rŽ)¶¯N¯äµoàk1~^žˆZ'Eã e]¤ú .&mv¾¦wY>°ÕC2¸BÞ£o–=^÷ Uíú V7Q«àôŧߪãî®Ul99’-Mîvü·(—@;"­i›®£JÐn·k‘j+ŒyøZKjªõÆSM ½‰¥_P/`މh¸Æa7«8ÞÃzÇ”ŒSVÜ¡mo‰Û=)ìF”\Ä ›Žç/šŸ••a MLüý5ö¢ýíïEÒÃgÇ4$IºÊSš6EÈ‘yŒg–ó>¥‡;Œ¨!!êË+P$à9È“è»_•.¥©ÀÁ/±_Uœ4Íù3|µö…ˆ lÄÂ%4ÌŽ›"ÉÿD^1Ó¨<'P}F÷ýr´ owš‹ÖúVKh )ÐCEb×#¡œŒ}!xì+Œ¤kÉï» Q0‰4ƨ 㜱-q°×æ“3O¡˜:uît[¢± iV±#µ»þ´¥óqYª†õ-Ùƒ#Ïq'eÃÓ8‡†,XÕ ¢fðj=ºáoò'é}ÛrÅ7» ܳôA—Wy©Œ0çâE ±üHIãJÜy;Œ0çÆnÀk97éÀJU–ke‰ôª¡jM…ÖÂQŒ‰µ»/yÖ87“ Y2¬ñ¡½exïÜB TÉ\jð4€Ñ` µñ~‡j Í‡¢°0©rÄßXDÇh)¸Ý¢üèFzŒy)ÿdÇZƳZ³*ëêNUU•ÙÒÚîé$ ƒ?O‘„0)…m„DÁ|Oþèe‹dÞVûtÉħa7ø2‚÷*úi›GÓ‰­ëœ~Âñp½ãDäGN›«ÔùÌ$u½C*{$o*XB- ʈì ÿ‰dÅ-~Éøçˆ7& 9¾k¦°öb9ÊIrĸtœÌðW,[IsLvôf=¼YSæ1šäÉUj&©`Š™s ç,gWyÓœ),>¡dËàq5ëkOFrªØTÊE C™ð”,EÑ_ ^ÌW³$—YÎ*O¿N?”ÏšÉ?z×i2¨¼m ¬aI/•ßÅãQôœ¦y±r–K=’¢ÐÊ«üemiZ-êÿ÷ïÞ¿|󚦓_öú½~¸s,¬¦y:õ _$»0LžM%HæÙî>yÂqÌ’í¾àI‰Ê¡x¦ÎޝT¶Æ¿ä¿Ìei€Oàÿ €öáÿà-ï­ ¯Ç9éW zÞi  ¤;Î`æC"÷÷uM»ÞM(|µ‰ãÄÉ’ËÉ]–FÉ…h½ ¥™×«ÍëZÚØsyùY¥µ*nyÓ Ñ5åà)#LmµhNBä+™c&âtnZs î4ÓHµI[õÚ9§ñ¯½º[*{mzŸ/1rõå·‚V:Yc%¨ØnޤQÉX­"öÊ1Ž^AYj5:ŠVÏ€þXYÑ€÷Ûý¦=Ò‹„¬¿œ'^]¬~`m´|ØÚ Ò¯ŒmÉ|KêéHo¾”Ôë ³î-ªÆ¼í2/[’Š@kè%j¬XôrIL™\§³´ÝÙAJèòÓþ_†z&C.·¯^¾zE€Yуà©Q[|Nö‡ë®Ø±äd:kH&eç¬à­ábüo)ã˜jŒ6é²#bНKzPI&A+£eÉ5À‰ÿ]JØR`"ª­’_ ôÿx„OcÃðÑÍó^ö’bLΔ%2J‚F§%;À {pþ«ößA&t1;Y» o¤Ä®«|ZØ iµ˜fñ„&˜dWsö¯àíë¨Eu™B–&ÒïVËæêqd™H÷.1ëû˜ØÓQô3NžL¾ç'5ãH?ìQ” ÷C§Q ö`¿_Û£Îô.Ah>”,#bÄjQDlÉÓU{:ÈÛ4û­QæÑ ÍTáòƒÁb‘y·:½ÖñŠ*¾ùÓ‹ÑH-š¤/ºP<EÂ_1qvs„!+M%esO$…£éˆkˆ Q|#x(L(' L).õ‚ÒXLìy´L/73cféd2M®â¼” kZåàíE6¿~%º(Õ“°^¸<“6!v7øcœŸò*ù~ ‚(?/ðëb!ÿH+ÑÑŠ´£óô2™? ž¢ä‘’çU‰>@àæ¬ &‘¾ -úLO¶!ˆ|9V6yò„Âlo„á~†@¥g h µž NEª3©fš…3Ú™ l4]Ñ2g9á*+am¯^Q†Aãh—–7èýÁ¾÷-ÈQÏ~>þñÍ»—ÿ÷Ù1½ ¥)V£xµ¼h3ºP2^&—d1vÖU/P $*„á9îKë‰b;›MfdÇ’D±šCV™’é‹ñ¶­1¯Ê[\䨬ÏrÚ Z0B®&zÀW(sE†·½Q„ÏÑZÒý Þ"Á&^…ÆïÅ^óäXò…¡€eÄÝÀÔmÑHÛXG)’éÙγlû7‘ᙄâÑbÿCu\¶•¿`íÔqÀº€Τ¨´r¤C ÈrðŸŠ/:å<øoSõ™ÆÍU‰©ö¹?S¦5Rok1I‹Íà°êÇq<‡ãxÀ‹/—qž‚¶äò“‚æ„gX@µ±%ð-µUŽtÆl¶4Ù¨Ÿs=ì6UÛ4;?—LF†’ú†]ÿìíËŽ¾~AöRÙ:ý6ÍÐlå^_¾qÔ¸:E?á_èm{Öñ*ˆ3/¥); èìºÎZGsÏÑ©é{A;:г*ó(•ÁPýÈaèš¡$‰4c xKíÅ9ûU}C”ÎÏ2ç³# !h„KFåá#øÅöÖŽ µw î•ù$Î'œ+ä3â6½c2{/^¶û¥Ç Ô†*äóìJ©›. Ãòñù‰†SGÑûãw/_ÿÐ ¾92Û†‡½}}¡‹b¦’ ãþÙK1Ugm[gtûUÎf©¢€ñÊŒ)‹U³‰£Z”ßøY´PíVÍ4lv¥%,“7Ø|cõèyrr žÌ“<ˈ§WñuÁB½ü𯎼•QøÆªîA‰Ù/ºE& qÛSYûÝjvþ zyÌ´ø©0p‚Ù„&¡¦>œWX½é‘Ð÷®’u%D±#Cof nQ_£Ì¢ÖòÒS±ÛÏX #â Î eÖ :ÍNÉÏä†6( X†ð~ Åî²Ó°êa‘ؾâE*«¢)¸bbÀÔ•ÛVµs>‰{N£ú,SS5ò×@#)‰û„Xá`D¶g|—eröäRY´T+cØBxÞä á©„§êQW—Y:)‚E6®p:Ÿf§ñÔK˜Ì/‰ Gê_åMÓÛ#¿ãóšp¯|ƒ[¦ƒ)ïpOC%¤â„FpA§U]€\fÿY>* *èeÚ3=Stg„E¹é­QbÓ5zã­©W½çöž}*‹_š½Ž4ì}!¾ ¯¡š½ˆdެQE“ß7AÛìAbÄÁÀÍpxvÜDÆ“è8É1á·]… ²äXÝ-³Ö5‚iÛ;Ô÷”´5}©jÙol[鵚›ýÂÓ$9Ç’PëÊÛ6$¼ÝÜ(§®57@ÇþFK"PD ‚Ô7üb‹LAcd*Ÿ8Z§”T䩞¸&øÚï%•dÿíRÚ áFðñAd=ö7¸£r¡H2ÁÃcd4nuÝ/xdŒä>‚Y .Ð¥Á¬A|×&ág…_y¨p#•ü¦Ô•Â×_“C0¶$;³ÅúJ›nÓ-¨ œ'©„TR”_ÈVœÕ h3÷î"²$Kån —‡ü(R "`Âã'mûFù²Väè‹ÄoêÅEù³â’3ƒˆû=»Q5€-‡ïíãˆáaƒ¢ív§fŸBáIҥɖ˜RHØã’ öp(ÈÅR—#õ9Q—“¡gmîf³3êødƒ Y½rªå ÿ…e‹·Ñ^VöúWYÐb;½>yt“ôÄ¥R—šÜÞ÷ltˆ¼ù `f=^ëï* »ÁÜÊØŽ•Íçdv<ßµdŠ«[íñ]¼ŒOÉãÛþy6›­æìñ+ï¤,â¯Ý› °S™á„a]úÚ¬Ý-Ä®ØLñÓƒ,: ”å\µWØ¥ˆË‘FíÊ"[šL5]ÝåJƒ-4׋ÂÍF­å.hìØ2;$ËV¬kFsEûÀœ˜#|kîcÝç±fä¹U5?1ø®-ÚUCÂ:œ‚a…xIP}jùâ ¼î …Vq×/,â`’ž%4Økø:h5ã 0‡À馋uDÃwÁ‡4\æ€ÏGãzÏN'±Õºz“àd¦5öp$ñ ‚×™‡s€yÙX*£u[Ꮁn§”Å¿Ä;í¬söz¥Žý4œ|LÆ´f+§/ë7 1Ö#xÅ)Gœj¶Eæn²i—ñ*:%ðŸ‚NhŸ>QÑ‹D¬›ä¹XØ>Mä€ö ”¾µ7‘ ¸â“¯‡ˆvRÙZ4–mÐy6bøT ý:{…œC{Üuêb¨é@Î6€…>€«‹¹ú¯í3Iƒ(:„½œÜ_Þ7‘wS:V@t4îU|,Ú/>Íò%^b8—KYê4ù˜K»5!!àDÆN á*æ²(·{Ð~¿ ö67jMtÃÕœ*0ÿ¥ùKhÝ&hŸÿ¹È²3©²ÃJpA&9PâßEIÑÏCéèè …kT¨œäêæ.õ"D.ÐU)â›ËZú%¦X7S+ÚŒŸJ©¨°ß%²h4ÞÂÙOܹ‘QpšeÓ$ž; ¤8®èøÏo_¾Ð%™%—‹sÁï ¥äØ„"ª¼½Ô»ê~ÏyGL-öTþþùzÞ +Îëˆþ²Þ˜ D‘´•Ô˜Y®¡ÓÝy sùÝéai„%imQ¸KÊû½@<=—ˆR3:?è¹ÇW¤È"©`­›²\ 'Y ±O*ºRé›R …A¶¬þÉ5¤÷w#¤[e¼=·9ó¾ÐÏF´‰ÄbgЧÛW8î3Åê»YKkø{pª®Þßp„‘ö–ÏOèc½ Z~\6Mã1X¤ó'¹îÔ ^ûÇ¡i˜Óï”ÈÎ2WCÝ& hM·°Ï2°¤óåp{J– J«‘°÷ÿ%Üža{LVFîéáye쪽HùÞeµE¤ªp÷É׫«H'$­¤©[àÊ·¶,¤^ŠYfîÚëÇ4ªD…þ]WU’õ8±=R×ÖfQÌû›°QnÝŠ‹µYX5¬%Øv 3È!bí׈Ú/JP·x^áÈÂ;z†ü¥½bå0”îAÐá_åSg(\Ϻ·´´Z~Y×å‹Fö?Ã?LYn®3Ëòæ…¥@ˆúìZ#ßL6¹öUEu“ë^E¨px‰ö>ùþ@¥HÀ:åÏ-2è-…MäÐ.† QÅ:Ñ”kG4Éu¤²N.©ÈO:â3–ÐXî½c¤µˆãvÒÛwà0ž´"¦ íF{Á£{7ÍÍ`GÚ“ wgDÞ™ƒ£à„‘üü½õ.lTSÉ ÝNhá$¹:·Ü´¤Ï°7ÅÒ€Üý&Øw’=}“Hn?¯ÔšÝFˆ÷0?£¹­¾KæàW^U´kò6ŽCZÁQ}'=‹1 Ž«X”ÊÂB.ùµä|É1¡ a¡— ®­Åét•'”<ÊÓ0_ ®g§Ùô…7A¼Ðá°·hxÔ8¦µ—Ýj¤S¶YÙ¬’1\Úa-å&œgñd‚5_â)/…µ«4³>N í˜q9ŸôfÅ.¨—©íáåe7`å²,õSu­5í‘Y+WŸ £µ8ŽdÇP:,Ùé˜]ŠC•„ª f¼àšþ,S‹­þ_ÆÀ•Ųä}xçÁG¢}û_»0× ã·>iÇ¢cgÏ‚^¡‚†+ÇŸ© 4+ðÙ>ÜÿÊûF©u|eØð*¸©¶ qÃáïàW‹E–“¯½Vµ7Îô”/6EŸS¦¥\"=ìï~ÓÖk%¶n~i±÷=¢ù/­è—Ö£Úô$ºoiݶ,eu{×6…>>Øüêà-{Æ *Ò ¯é7XR7Ât“òëhשÕG°ù¤Dª#œI‘O»PGè^€Œ[ˆVhØ­§D SM2©t²îæ{ @urÖȯt‡…@·-ÛÛ“@L8a› Q#lr¦ Y5MY&ËçÏ_¼=¦«زÝeR+šîi§gnÛq[uc(â£x R—Ùïbai¾‹j§ÚÃrùDËÅ4+q^HÀcæ}ø© µdEùlÉŒ9½®3b+¼ ¬L& ®Pì&ø‰º±‡–³˜Ü³ ¸lE‡ƒ[øûó7¯_¼>ÿóí “° <©z¦óŸAѱ+%¬Q¹éšF›‰Úß‹iœú/fìâZŨʽñ& ¿`âëVú¡—CJâ‚Y-ÛâbåXçœÉôÛ°r™Ÿ(¨}Œ/ƒ%+*U–©¡•ÉfˆCŽÀG7r[½,0àÀ—1Ì^þÍ8y˜¦u}÷; \±dÙ'ÓÅ,-ÂÚ"¦ææÈ0_gg|‹]ר}eèÎvÄûY=Ú¨‘k««B߃ íÒHríh6ÜÆbëU<ÍŽ>Φjm¡D ÍÃ%Å6¸ŽgÓ–µš;P¾Ú黌χÖË:J1èTzBÚ¡×â¨EýŒ­oâþààÉùý›ú- ¿³„”ß±|ûãd–ìýd?_-‰ùÄá­¥óκ…P·À¸ðScÓVËÉiìòÄHDàh/JÝ3Ã1 ‡5Iî”Ð1* Æ$”“ÜN€†—ñ4PS±‘µ°ýeÐ)þT¾¾W5$F)ÖØµI,Õ«G]ÛÜ TcwœYí&ÞáÀbÚIvÖ¡ûÚvšÅÜ­Åîž,Ø{µXÝ’Fï«é|Ê)A+nPÙÞû6×6Š”õg@1/±”2°.îŸ4—œŒšofÃ+à9á¾Øwq—]ÂÝ%myoÅf‰…d ½0á€(ÔãØ+È’æˆJY‚ñ+”´SZŸìíñC¥£çeã䓃Òn³h0YöÑv%Äë„{v`\Eï^‡õ|Q8ÁžÖ_‰ôù4D+¶¦$®;+±!‚ð²O4"f ï‚ö€SÖ^;7ÁI‰}±_qPƒËAƒ:x:þ…éñ(ëÌ„ó¾žüm }cÅŽ— ·Í"‹iŠ "ˆKA–B«P£I¹,˜ 5„RÊ)¸dx *Įڗ} NÇ}çKð¦h²*!êíH.‹akN–¥¶²"âû³j•icõõ±åhóþÞ|P1¦oª–¸Lëû@íÍjzÌ鵇#¹kѼ$R¥j.ºøüƧmÅà‹õtœ®…G×Ä)R±˜¦Ë½ˆ%†·*~ö°m[8œa7?à”P<<ØÊŽÒN}ØŒXˆ HÛ5 ÂwO»ãóAáÄÍn“7'­¸Õm’ÿ[C—©ÐP&SB6¬K»‘¿Ö²["J:ÜCÁÍâ^éà?S®‹éQÀ-DåÚ˜ç•?‘û)[ ãFÛ’BÎMtÅtõ¯TŽáã —ö »6„VôÞŒZo|„jYÊÍH ü«üûpÅï*¢±á¢Ç‚H>K‹&­±àÉZIé1‡§b‚RM~Pže«|-0 z˜¿ßD_Sà‘[÷ns°‘Ñk¼ÿ *¤#¿Âß¡z—!+ÿ öaÍ|ª5³‰¤²wì&šñìN ‰€bÇ¿L—ê’ëbÚ§«$t‹–UB¨uâ!ãl5_r.÷k<½³4/–v/wÂà篘Ú2."ý'pè‡ÖåÐ7Ú÷i‡p…Ã<¨^Uë‘Ã;F ±ºT*¶#ײµÝhé†;®Ø!ËÒµß-|v¶ØÖ×iÉjcy Á¬‚K«e„ß×kªõpNx±(¸2`,ó¬×9ä!Fì1CÁ¨%jƒ;ê°Ð9T Ár!ðRD” £cÖøj5 DøGŸÛÐÏÐùëØÍ¨q#(B{RˆûÔÇb]ÏÔÖ°vhÝ” P‚o°6|ƒõàÔÁçH»Í‰_·ÀÛ_FÌÕ+e¹À‰B«UºÙ¡)¢H6ë~BÖȵ…‹ÎÁÃê•fa­9Ö`3¼MðÔà5h€×@ËWÚŸ´œ­¦Sºxùª¦¦YÊLÔ¬ch•–ñÕ>¦ožeKmÇ‚ŸôýŠ­, FÅÊ’¶dlªïÊ’R[c‰|¦[ '»ÇX’»Z|$˜{1l¸¤®'2ojäXá˜÷V¦•Ãû`b骯€¸¢2•LGa?çþƒÞTå~ç)¤'–Òš»ºHȪËdNCF´óô2™{ÁªD¯hË€=l®2§r¯zþ+Ñ.‘÷õºÑÛ÷ô×Ä ¨ù´ŽÔ½¨xð¥zûRÍ7¼3¸|Tß+âOD7Å‹äwÙý¦ÍS½œ ö÷»ÁÍm78 _½ùùõñ‹ïÂáç²ä—²ú¬‘±Ìç0–Pœ; ÀàÚ=üáÚâQÁÃ<-«Ig{Çf âË8Ƨ¹JÕéµÈÒ¹-ÈYÞ'„™cß±ƒÏÇ´æ¥ò - ̈K, ‚.ý¸˜ºAÚ‹¯xí¶EЈEªÖã¸Ç{De„T½u~)Å]$¤cJdûù$üÇîs6ø08:í¹#Vó)¤&Æ´oŸÿ8zùúû7á°ÇîÅžBæƒ,”SÃP‰cÂØ}çgÉù|uNö€aù€ì–ÊI¸£‘ñ´6¬G¡ù?ærÒ3¤¬‘$«F¸ššŒ¦JYNÎ-«ÆƒôÉ¥xS+÷¼˜ó•ìy„”ßl$c’ùƉ®èR{TÈ¡D@°QƒhU$yaK5]$ÓifÚî!ýû…3éžw‚‰…á8øNÔÄc(CÖ©!9Íü´}ŠóÔoÒâÏžâä§;$9÷³³×¸ðð^œo¶L|K’n_âT¿¡XñGwAw£µÔÖ@RSz:é¹d?Õ1Åíi\¤cô™è°ëÐ{^b)OT':ÿŽ·¡üaðå—¢½¸'…¸w•ß3·õ‚ýŽ}cÀJ!ý|üã›w/ÿï³ã—o^c D2‡„”ö#`»$hW"aç®DiY‘KÙß ?Ùë7Üá ‡IiôÐ ñ.ù<Ÿ@aØÒXnM!KùR|DDFkÐ-È`s_hÁ\ë eˆ~ßýiPvR1’D›mA݆ ­ß©`¸Žïܨ^?7 ç[‚Gáh…&QW3À$¹4´aœ'±êCVs¾„öº Žp=1·ÍQç.e<[¤SKcð¤s¢Ò抇E›“·03ˆ”……p¿îˆgŸ#Àîzùiè=HHS¦òtÄÁ~¥X¨‰ÇEp-ÑÕ0:Q Z ¼È"^ŸnÏðÖÖôWS[-òì2…Äñx p»‰ .Ÿe–è¿&ÚwÏšY‚ºÉXС"³Q m-QK-7h¤°(d¾¾7ÊIMl<¾W²RXJ ¡„Û~¤]¯CG!_ 4Þ‹Ò‰C$0™‡"§“áÐ;+9 Â&9¹L‚w<€±¦Ï(% Iñ±QèS…µ`©gn®ÿ«£û ß-H·mUÆewLI îJ²#¦é™~Ñrhß•ÒVnY à‚‰K é<¡ðÄGga—Ž&'+ŒXw±S]Z ÁP6±aÙÝ*8õ“š•x_¸ç» ƒeJ-_z*RGmÞí!TÔª]db/+IÍ6Zÿ½âL¥¡à¡,ïÔ@Š——÷³Ø(˜%lä¸-áªv^¾u§»iÿÛV—V0Ü{e).Âu ÍÞÃR8?éZt«lmw6Ý^îzaÊ”¼éG¹XÖV‰Ý˜ä,ï.Oi@h,QV iÄ„8Њ¹×HíÆÉ @“cemXW…SÖ‘7Uá?µ Ü¥x`ÔÞ$ µÿ¨€ÌÒÉdš\ŹJ„òg›ëô•øE‹¤£§I9cÚIqlÂ[¡+6y7`ñù‘QyêyÀ¥ÁÀªH$˜­r`ÍÍîy´ÕöžA#'>"¬ãéSñIžÆÓôWx!7Òžb9w –ÞK]!£ï‹1”Ó6Š¡kheÐãSxáIZ†ÅÎÍ È5¼*œWŸY¡×–«GØ Žó±œoZ„­¨EѺuR³lÙƒÞhØ l¬[éFøÀ¬­HÁË…XLÔa¦¿Ï8©À§[…ì°×¢QyË®ò¯a½K)R˺{_¤›½ „YsÉGRB“ÍkJ‚ªÒ7 A ž<ÙýÇ«Ÿvž<%Øñ[£V¿·ß¢× ³£ÖÏÇßïþ¥õô›'¨¿!Ã?aJÿ²¹ƒ5E¨Kz/ƒ÷âí8ðÉoµódu…ÙlTÔ”¡çjS¯Ûh›~$hÛת&±Ÿe %ÙØí–Y1¸KVÁ×oø_žì‰Ÿ¤ïþ} ¾€/t[„[!aée½L{)ʱdCUÌ…Ô¤¾¼+¶rάҥ—}¯0ÄÞ-(5NÙ´ƒ{˜v`/^oêCß©O“Ñé4žØ‘³ÜÊÆ¼¢’Rõ ™‹Õ‡Î¢K''ËÁèxj8HÖ"›ÉâÓe*¸¼$˜á¥iúˆ.Ï;C£í¶±<êégKLS>óÇî5îȪ\9nÝ*áŠún‹ÒÙž­zN Q î$¬·dMªå=ûhcïû>;ÞéËݸè¢&†e¼š.G¸ûè‘y)¹§å[ì€ ­±` ®Ë˸ ëìá[ðXsy¡ŸÛC©J[ÉK½ÇNv|ÕÙñÔº­›_Zÿ/­è—Ö1>ŽDÍ )9¨ "İ„”eÌ[-YN¾ö~iݶ:\‚YL½‹ç•3eº‚­H;çÁÈšäÖÅŸà0’”M 縟mÜ©•ð‚ €¿7 ŽÖÜ÷î þˆÅÿ_–O•¸ü0=ŸgŽ•kA¼»¶ S{Àÿþç³ùîµ÷°báÞ¤˜îA"´Óxü¡àq‡Û˜c¿¿¿ÿÕááÿìÓÿô?ƒÁþÿôöÿ|pøø1i×ÿóaÿà‚ýû ÀŠp<' \]$É´¢]Ýw¹ßÉ,})”¬OÆ#²Ý. îÆÎ,›¬¦I€'Ýxg‰ÿüî==ͳ>çÂòžôÝ‘oj¾[Íf×eN¶·²s3%ŠD_Wª;£&Z;ep#Ê`È$AGø31ëæ"ÏÆ,Ýf‡–¹Úá>!Gµœ‘ò £çc¢]²ñÌHÛµ4…§†h£^ çˆ$½LÚ‘x0;"7þ·˜íˆ ,BKîæ¡ÿRýnÍ bà2bÑèú¥~ZR—­b([‹¬Ô¶)Þñ±|¡­÷ØÖú°HëM×ÂÙÑmbW‡R5ŸóÎøßñŸ¾ÿgó³ô|•£ n˨Ùÿ÷÷êþ? Øÿ?ÿý_–ul¹]=v¥q) Ã¥™ǹþÜÛ4ý}Öÿã¾¾þû_öÖÿç¾þ¿#ÂR³ì1žt¢¬zèU·Ø¡MõçsKKÛ4Š´WSÒËÒ8p?xÂ5€Ž£ /”õ1üzðFº0žÃ3a%²Ly%ïòþNC¬'Ù^4»t;’@á’ø[ÀVÜk+uÄlŽ{Z¼y›S(o»¥øW(“Âë€IjµC“ÉH¢¬rI¯ÖtÐYÓÕÚBac¨O†^+^æXiS¾HÃL+y¥”IæËtyo^ê7ÌQÉÈ0''‡ûý®3¾€þ)ianÉp8TÇ>O¤¯®é_é£0 Væµ&³üãý8ûÌõÂ;:…þOé3äël•é„"¢ h%L”·z[þß?Þ°4?"\&$.˜^g0›Ö ²I2I&a×ÙS+aåhw;T˜\+Ï=•M`,òÒV„EÍ6Z¬èëÓ7jn>LrBÆ[‘‘ý¥ÄCFl"òyHˆ¿€¬-^â¡H‡–¯u=}««©ÍT«{´Z-ÊÕ$”M¬Ò¨ö“ýUœÏÙQ><ùîÅÛw/žc˜að–—Q3@„œ< øþØü îb&É‚Œ Y$zÁ«ì2Áú+Ø…÷‡»è× •ÔÀ¾;-]Œ¢¥kniCvè gæ õʾŸvÅ&ͼ™¬­5ÑƒÇæ¿èüǶíkÎýÁãÇúýO¿ÿÕÃùïs?ÿÑ}ÛÖ³îÈšÙN‚ÒÜìÈ•§ÀG–g‚åW¢/õ}ãž[Þ3è`ÄLa©ÐˆµJ*êäÈwÓ—ØVYSãt‚:ÁP\-ó8:¶iÇŽ»£3 — êÜœžõÈÐ;ê¡W»}lGLF;´¼Còáýk–M“xþŽí;6ÿä³·/ ØXµÑˆWº-³óói2Zä3{!Üò;¯Êæ­t`3W;>%¢WE9H ± “ðà¿i/a ¡²©DÚ/ö·-ö;hÆ×-4ã]!³Vn|l­¸fówžÂÏ"rôMýكșv1O£,OÏÓy<ÝÕc—{"6æ·äîÍ“OdüÑŠÉ…œ,®Œ«p`íu–$mÂx¡¿o%¿B.<ü†/Žÿ«yB¨Ñ |Ãm-Yw)ô׊öÒ49Tï>K—ƒâŽ‚© †Åó÷4‡‡gÑ3^\œ~ݦ*U'µçÂD ÊQrOë¥#L¸ß™ýGT Ñ#æKÚ’Xmÿ þóÿ1ظÿýìí¿—(,ï@VÖ°¥ÞR~k¢gF9=cGÉü²K /²µ‘¿‘‰û75Ó1§K̽ _|KúëÕ³¿eçwýgyhô—› «ö ÛI„y„,ûLDÃI}•àŽ0šA^°'@T•—fŸƒ^V¯‡äñГáSú@„(VN÷Ú6À:ëçs±¡Énxž/RÞghyÍ‚/8¥6P­œ@°‡õ€CjëHbûˆ¾8UðÅÝ{Ñm`Kh+ľôâéûl5‡Ë¸ÃýCÌiCŸ…ŠëÙi6mÓ±:ëÎ8¯|1Ïœù8>0ØÓm€u@*(›¿FGå) W{ ÕWDÆî' Öå—æxÝ@ÉÏQG’ŸçæHÖZZ€d× PC£Ç¢ÖA£GôxJÛ·Ù„¿ý&ê~ŸXqe¹Ÿ¹Ò °¿”y¤Iºå•ÿ…p—š¢Ÿ'¢¿Ç¥Óà¦ù0rjwµ$ƒFéƒý?aD!fÛ —ä¹"ÉV›„÷BŸ}·ÈÔz“¦ŽCvÖþŽ×l‘8‘>­0¬_blìÚtQ‘$#ÌÞ»ã¥x,ØA:¢‚>Ò†Òì+´C8iE¥”tÀ†eÉ9˲¤Œ(Ș€Z m¥öt7ßÓžWXv's²Ò"½°ã&tNNgËä<á´Â± hý}šÎ^XK0ÖSˆ ÀgÇX ð ©æ1ûfN*ù›PkFÎóplyYNþ'—if·£@š Ö<ƒ©½DM ˆÒ^—¦ƒ6Z-d4SWŸ„¬™`]×ÝnÓ§îå¶QtÔuía"+0²ïÔ7¦Y[7‰vŒµÓ-û&…5[C<¥{ ¼ús­©e~lÀŸÜÇ|`+áPä©9ßèö€ƒlÈ)EæôæµB#mBµMV†7¬¡¯1w¸a“’+Ô ™âíw1W\Ä^˜UÌñš>°&=d\ÅÜ{ð+£#ÅA—ÍyÖ½ü"|CŽ“å}’_&ߓߣþÿ¯ä#š/å¬R{Ÿw‘Þ;ÚQ_ Š¢Wxwô:[þ3Y>ãs³nW(¦ÿ7ÍÎÏ“|Ë`êÞÿí÷ÿ¬çùóã‡÷Ÿ}üßO(,Í3ÀÐ~uÿh«êÇ%ö·TœÁ3ÉV‘ı¥‹¡ß\ c,_KµG?²6îm˜ÍÎö_­µÓ“æ˜Û:v›MQ1ÇCxöîøï²LÍ÷€º÷û÷_=äÿýüõYiiðïWzA$÷‘£lZ½¨ðøæ–½öY6*W€î¸—žÆyECsgYΔÂR1+ñ2.OÏ/–AFX[2­ùªœ¨œD¢n âÛ ¢8?ïÓ„®ÃŽ-‘T²rt‡RÞOÉY%É—£êlËŸˆ4 lkIé¿UrU&ùý´ÔBÐÖ'vß­Eãdƒ H#‘ 1tvÞï⿪*DgøcPõ¬°Ô.Ì’;ñX´ñ­š8|0 ì?ÙþÃ×îÉr») ªí¿þAÿ°oØùŸ?ûï­–5쿲³úø/ÆŠYN4Ô"%z*™&à ìbºE¤Tþ±„ùÉ(攋öáfT¾ÖúÖÒ*8 °ëžË:4{™X3´{ÈŪ¸q7߈e“4Áµ5#ðVƒkëd×Ö¬žUDm@Ê*Vt‡Ç™çy¶ZŒŠ1±eÚ(ø‘Q¨7žfóDË ×i2¸§H>.óx¼±Y,c˜ªLE-ˆVó)dúÄ&½´ÅOÛÏ JnGÍHˆœÃ6P8ˆ5„òàà)û°ÈA¤>H…ŽP ì)1·(HàË/ƒ/à÷þÓ°GàxJ†ÁÖ²R–‰Ô>òÈ­¤´Ê5i;h©Ë½.ë–~ä±]Äá]‰ 9µ€h¡ŒQ6©É¤è½Š¨-±H½íUÌ—ÊDÝ^6Ït<ÿ&Áô†¥‚Œ‚ÅÉʯ{±µ2(vaKe1Bs Ï—rMâ9b"Psdñm™SHžIÍvšÝ•ZÈÕˆ#rWJÊU“"Õ‘|$ù˜Œi9Éplu…©t$ÇÌ|mz>å§dç%+.›ï&ÓŸ½H4‚ç@Rå%ÆV‰usk’Hºµ1Ð3¯n·,‡Ò ®ˆÎà­ï¡w™XUT gB¢Ic —6Ÿy¼À»¢v$ÆcK ðØF_l :>Üv€ã)š\hžN8F°ãLXæzJ'<Ç{oÒÅ ‰ÞxÉR)÷ŠCžÛÄà[É¡/cÝMí4]öm Éhd#}¨*=7†m‹(¤aEÙ 3B…ièOøŒe‚v~ðµ” ?'Êß?Aµè2¶±AÁ‹\Ðt7¡ª¦DÒAWÔæ žòS|•êüÿc =[-WŠœlzDdçpÊ0iŠIËEËR˜G)2©Ž»1O@ì¸Iƒ£f5I3 [U†@Ó‰ø4`áøëŠ:b%‰Mp æ÷(;sŠ5ƒ(ÿi@%u‚;¢:É6é/GÓЇÖ(^ØÉCðl@!mŠ;"‘6ËVi„©ÙFó:M§ð²s¾…” îŠ@Ê$Û¤êójëÊjæ8M,Ði_ñ±ü´\Bš¦àé4ÏòlP‡Ž'ý±ôzÜ€Ã;‚·)¹=‹?íP­¶UOì$›ü U[õà' Ò³.†6 ј…¼Áy< Úp1xi¼µ) )æãÀ² ›ö-sœ’kgŠ@Þæ_™WEQ3TOTvt%öüŠû3_¸jÛuò³Zzh>Y›*44²†wˆ{‰¸À’þk;øÑðOÆø¼Ýd¶X^ÛÙP´® ¢ec¨v~HøøzÿÃ’‚ˆ—[¹ªÉÿ¸ÿøPÏÿØï÷òö÷?,ƒ ê¸Æ%6‚%x‘,ÛD‹w©vWÊ óÌkä3ä+)®gðÛ¹ý8h:;]%5ÃV4òq¥k˜U.Yi^Óœðâ?^,¦)Íïµ÷ï"“ä±P¦|ãÛãpùq:Ê#ÒŒu´­=îu‰U™°]`içD"eänyuönÀA¶j’›ò–õ³<ësf«%ÝxÝ&ÇLnPíÀÍ@„U1+UˆáþkË´ç4§²ÕÓÙ&WiD:>FñL§ðû÷üç(:†RS¶|”kÑqé â.åF•ÅSi) s6Š3Ý€.XFààè› üÚqb ÀÑŽ]©½7ˆˆî0vúõΧÃ[1§Ÿ:ö#\!ãLÿí°C檖½Y²7½GéÿQÜU O'ˆ@Ó{ÓÅ“UÍ®?è>²¹€h³šBIÑÚØ(¤SFì"Ú‡Š‚sÈ©º$Ç~H-7'p.Ó1ÿ<η³îSú®®ß*á°& Ó$CVLcl°’A°Q‡Y;š(éÉ8AhóµP8CEÁÓ(“¡Æ­¦ ÊÏgP‡X6ØÈ/eoíÿˆ)ÎñªŽý‘Ål:(tÚÆ8D7DJ"·¦œ¦ó8¿Ö@ÉÆËd¹ËòîtÖÜ,I •2àÔ¶¥‚¥íÖvkök—Êi3÷½±&Göñ*gÕQë."Âì*6B{£¸CÚó¼¶P]:0ÈÈØ]¹³aÁËΆ¾ Z| ûìˆÏG"²-;k¿âûRŸZ`%5ª)ŸfùòäÊ´e—ÌýO3Õvyb²!<E,h¸@ëÍp4-»B‹¶}tÃòõŽÐy7JÞv^žÜ[«ã‰4æ9Q0Çì¹tÁ牙M¹*ÙD=ST©4ûtÃÿ¢ž^'aGûªõ¶¥¨0rWáW&¨`X6¼1ŠÐ?A œüÚÄÙ°:†¶9¬<×;zh?Ç”$óÆiZ`E‰p¶dè ÅñRZíclòÅštϨd9]ªš¾ÍEþç\²p¾4ŒÅ5ϱl¦ŒóA½,µsA¦®|4t+‚l>½ E§ (V6(™õvRD4¯2WC.ælL_€d0>¥]È7¤¿{  4ç!Äe|H®!Á¨õº~ÛæìK¢ÖýTKäNìÙ{îå(âǰížO6`WýáâÓñ«æðâïu2 à¨÷MôsyåúUùmŽÊ[ñ-PINGÈt|‘8~TNÙ±>ðàiì"Ñ…SLtüψ€ÒãXrá­&€«ÿ饿ÿîÿùáý÷çÿC…e¸Ú³>І¶«‰ž)ÁX#çòì3Ž‚è4ÐZ”E6X*j[,^rUÓ‚ì3ê@5=8ý? ÂË~¸Ë6b78áÅY;[¶ÜzV¡}DzQ{Q×6/îÊïÆø¿ý£òä,ýX±Û¯N2³Ï„Ê{ñ"Ý ó,[Žè¸]6~Çžgf¦x#kêI_z)½ ´)>;#3Ár8—ŸßýÔà ÆHç#© :ÛÍ­ÿ=cÅÄ!Wÿv¶M2ô~b;Lþow<¯§ÃaºJÄ-œòzزåáƒ0kz—8g.‘m»Æ¥le±ÿðWðZ`ÈM±Ä‡µË {àløµÙNñìíKÖx±èû5x6ë'PÛužŽM§_¸˜ÆF¢xÛË=À’Áö ª•…¢¿áße£h4¨z*ñ“W%‡°8윔l:‚ó×K¡êq!ÏA…E.†DJ`§(8aÔRƒ•Ó ¶;M—Þÿ¹UÏÜCœi,ìk”çVß({qEwº É ¾íÉÙd9*Á_tÜP³8ÿ%Ü'˜P²ÅYvÌʪ¢6è”"í(ž_wªuQJ7™¾Ù†pLÈ®ŠÇS¬ëi· ÿ¦¸`-PŠOÛÀ¦DˆOçÉ2&P73ÇŠÚ¼7ßýBïE…Žiƒ2Ò–,¥,´³ôWö6Ís5È¡²‚¡ç8´)°<Þ“¡©M’\u°pöÈ¢àºeÎyF›ßl#½ŠN,£^(Âác·_¹Z¬ÙÓ*þä4]Ùëu9¶nwˆ7JYWÚÿTËF¡Ôæ×0âS7І¶AImÆr‡vš4¹Þ£s#™Œ(< Pà…xm•€•eg™†‚WV BHÔ­š®ãÍJCFlßÑ rû=õHæJ¯•‚Ä"‰‘ðÙ*'[…’z€wi±MP‹ä|f»åÝP6æV)šYÎPûÓ߫վšG„-µ MUN!·ËÈ2AµbT;ªª€þä&ïCÉCÿeW~¢9f¡h‹à*î@¢k–$“(BÏš*®JÚ!ÌmȤ B}™³Ô©‚øÞÕ²¡ÃÂoU”JŠ7ŒŒÀC.^ͺOYM kêW¯­—[\;àÞV'f•l‡¼‹ë¬-§ä<ù«i¯ÝûcgOMŽû…v©Ê®˜a©“S^ºTd‡g‹Ÿž±Vyå‘pýoS™*ÐÙÖ~ÇG„£Ü™ØÎ|µ¸­‚3lE5ycï;WSÍâ½·£]lËÎGÓ˜+o-+_ß³®óú[l¼‡ŸÍ­ïIËH­­c¬c™?ác ·fdlk¾*Ì}5Œ'0òÀÃí˜A¾T¸+]ã¹ü¶¤iŒEçeÑhë®A…ŸEÊ2LÝçYPÌZ£Y èÖwB5Dt#nè¹yè°Yõ99€Íq»jcäàLLÿûˆÈˆ‘®Èšör<ÜÒ±Ðr%BÒÓËãõ$º²Æ•Gž3ªØz¢C6ö÷޳Ùbš| Šq2ó43oÝŠà*1Òƒf§ÿ†7wŽ;µáÀ·áAECmîÑ8[\“æj)`˜Ìùå@þ¢ WËlT¿“A3k‰Oi'æCŽf»™¡¯)Ë” ­k%§`Cû8•m”i”¡ŽžÆ8 üx0pñ`ÐŒƒ‰ƒ-ò`°)kð` óàÀ‡~<8pñà  H<8Ø"6åÁÁ<8ºh™-FÓä2×BGš®§dv%š(TõC8‡ÚÚR?`‹’éÇáC…°ßaü{±½ êøŸýƒ??îkõ¿ö÷ù>ûøŸ¿—²FÔ»6ÀGjk‹ñÑa¥5ObTû¼¿ÂC@N[jÁénpÒ,ACß$XÖèí3­v}.=–îÒ?¢ œfSéÁmå˜íç%zg¥§åfY®öªP¤ ô™vø UîÙvþMsØ'–z7™tmD›ã7ÉÆ˜àôšXÞäŸ0†^7Á"öAÑ ‘†Ýé_åÓwþ&U¶l…ŽËˆ±·Øà½‘ÁÉQu•S&æJRRjQ$ æ¦[Žmô'aFǺô¬í Ík`Ð7æk©ÎƒwÝ0Kx¦s%?@}R$Ê»Q¼\’Ÿ|²©”9‰ô®í“³ÕtЧ¢«>~ü•GŒïÅ‹Nú@©—SûÜ>jRag-ñä։㷇¦KöŸÈÓ°Õäuö_¿ÿÕcÝþ#?þùÁþû„öŸXÂZ"ºTlY¥4[Ôð‚€îx±Ø‘ÖôŽXš’Š :`Y}ÅJ¤VÃ>»Ü¶ ¡¯ÜÄc/a5¡Yt™Æ†,·G\Ô1­ã<Ëejàª)¿Ä1øš³§z‘;ôÎÒ¼àþÚ¶ÔY((àyr–ä‰úNosà9ËïAG°I«ì’ìéÒ2)2,ufn‡{!>^å9(÷~¼ÝѶ(š˜-4k—Àsh܈ÄbÊðê‹S«|îEŸJ%ÖÔ<2XÊÃÆð¯Ù©Øa¤ý…AªÒ.D íÞi6¹ωè0²&¥ÌoD–*áæÁi?ŒWË šjŠìV@•ÒΗiµclB¿?Vnwz“p r&Æßƒ8Y4÷£tž.±$a©©@à–ñ4µø#*vÒsB¸4õóÂHªoÿÑ1”6žŸ—é4Š^–nâ÷üKrÕ njÊÒT„uu éÛôÈL¯¥ÿ‡/i%ó÷3MâŠÀât …Ê!Ã= *¾ V„ûø&ZÌ¢UÃ!Ï}p•åÓIo ²L©…UÇ{dô“0^¤"¥[(ŽiR"±Ù™‘ÎÌ*ZñD¦{dÔ?芦î«È\d³DÕC¬ â`ÿ+ñE6t-"£j!Ñ!ùR"#w¼—Ù¹—C¥ ^X’ôìïãý·š/l–Ì2²t&¼Ö£|—YG ³/ýËÑf_£€»á‰ØG"jÙÊ|¨]¶LFÌU¶û¾tì¯OGÛÚ„T^Òž¿ÑÚL®U*Ò±ƒð»Ï®¸‚T«XI«¤#ÿâÈ互ŽtŽâDšDä ¤sùà_*'Ýñ £H[[Ð,àÍ»T…[=lópfôvÓ|DÃúì%Öôwó¿½óš–D·qc-É(®H,œ|Œ!Ò£—åçÒF>ϲiB›ð¹:n¨ãÉ$…:žz#€ ×<>~;úÇè‡wÏÞ¾=ÿéå‹×ÇtÚ~#͸åì>Ÿ¦‰Ø€×ý°r+x ¤Àª…2à°—ïˆEE¯ˆœ¿+wA¨¢-s¿ìqB1{ÿÏW}óÓòç½x²JÕCH'ÿC6M!ÏÎ\NËOo))–±/;'ƒ!"L[N 1šÐ Œ»?Ò¥\’Ä1wõ‚£Llg·&ÿ¿ÇÇS– ûñ$œ]ïÆtÙîÒßú!’ fÌd¯«»Ç{Èv†ñFb²IdŠù6Éfq ·³ë_ãl¦´±Ú}EBÎddÐ+âç[ƈþå1¡T· BÿrHñ%#ûŸ|œ@¢ûÜ¡u’îxiFbï>ì‹iºl·~™·:½"ËùA~œ”jÄ@ïê_(¸pÿ„àJmL–¥ÅŸ›U­¼ÕŸ»¾f<:R9ô5²åhïkÆ N¥¡i* ±|šgWàF`Ãó…¸CK‚+Ð¥^—d8§a’«GüóÐ8îjÝi&ª4ž¿yó^¾ j78šå‹éŠ ZXO³Gl óÞóiÿ°ÓX2ô “š@½ÕbY¦5®K6†$¬ÀªZ¾‘å%÷ º"­FK¢¯ÃY)@§ö7º 7dMÌ Ûe{OÜÛl@Y¢ö,Æ5Ïf1fFƒ¥5å¶šîëÜé ÿ Ñ­ü›r›3¦‘_a»L¥/¼?ËË ½wlá·d¯£‹ÏtXT*Ftª£þ× ÜøÓÑÀßÇr XÌÌQð#” hªˆgñ ×Þt¨ß4jBá üËßâ<Šè_1Kü¨ì„Ëå"ÚÛ#{r<½ Æ'DÙF {BÿÝ£¼¡ÿ´×P%gIAŽ$â(‘ÿÃU›S/0‰Û)å€þ€×tüø¢–ZI—Ñ2"åˆ~_,7ê¡ xE“+,«­É¿Ò<™»ŒS<ƒž A–‹ ˆÏâù5ääÂ,á€Ä€º3,,Ï¡2-•‡¿5pQ‚{Ô¾:a0IVyî & ïö…òˆ×NÝÄ+¦(œCåJq¤Ñ0¸©qW+Mh¹Wáæi—Í“­Ñí„®yîS™¶µ%o¡äé*Nв²Ùý‰šRbö%ö„ê áQ‹ô£CqÈRÈ^©Õ’ަV£pã<¯íVY„SrèM>çÍà ³önðy Ò°%ó§ÁH—,Xƒ‡5¹¥5)’‡£ÿ‡Q!]•°ЂX¬³´(ÔÇÌxç–Ô‡ùäG¬9ôDWMeÓÔƒ#u<éê0DFùË0´‡ŒúìÕM9TÍ#ýÛF}a‰ )© ù']4¦n¬OJdáó¦rI«ÕMmë"À¢ºÄÄ”.Ä–ñmMܰ>_éË Ìâ£åU¶=“h“§íï çò2'"‘žÁQ?=£TciÝS~Kw/Ä#Gzʵ®¼öÝó$ÄÑÃò‚°kí'Aþ”Š/zïEbJâ™í‹àp¿ 7Ê1¤ÞK§!Là»þO˜E5ü„VƒIĵvI(<ðЃ¬|8AFÒUè&Våi–M“xn"®Ô¼«dD»ä…¬ ¬é4ãƒc|q$­UWt ºÁ+bê¦+²yXß‹6¢QQílp>‘šço^¿x}<:þç[æEŒ´r)¡ËDO¬4³[Q€·ï7Ú”§ãèj>MŠ¢ù ë‘1žn“¡tÜ“Kß7}´7E™—‡™©P—Õu3é8,ÞçiQ6·Öw:T¦gíJŒèÔ£:dÓÊÐ!þ`ž€uËÈ Pmz¬»´êLÖMÏpüß ­‡'H¶áþîl°”öƒÝ§è>òޏjS”¥@Þçœy¤µ%ôꥒI‡ É 4uÖo #¿Ï­Ã×´†B/ÒéÄ’¿Êu!A~‘-(’B-%¡,Õ\‰p7µ‘¼ziû½„¢k÷=¶öV9S(wÕNx¶)åIõª9mÍãsÑúå|™œ'¹;7‹ f9™QæË§<õyÏ'^àj°õ­š“™ Bîg";#Ó0f0MÈqr$q'²&ÝœÊh.Œ,û[_÷‘¨±of½«ZMN5' JoïÆù­ì-D% wɲ^æ1Ù^.ʘk1 VÃhȉP“p?UGÚe±é¯ôz”c'½¼ñPÀ¿«¹ÊÐÖ¬c“æ$ãoÃÕ ª„úæSV[†½[räÊcàj¤8‰œ64† KT1g•ÖEƒŽË9â½æê«Cñ&>¿˜Fl޼æR£ˆ>e—W’F’\ùh'šÙŠsCb‚«‰RF’®$˜Šl…€^D’30|"¢t•çðÆjw‘«zFá‰ùy`–­æð§xËäÚ¨'Ùêtz=âíìO™­å|¦]¶Wïß×®=QÖ¢R%>ÒCꄎ“uv޵իÀÞõd=TÁM,Q€ûƒÐúJ*Y•ItÁe’/Ý!eêm<$02Êq˜ùGbáÓåõÐÄÁ›=å9ÁÖGßÁËÜÂ/Ö¾SåÁœ_){æÍ‹Ýk®ƸdF„Næo•¾4Aƒ™Qål´ Š7›pL¢)å Ùü9 özÜ n;6—õ‰2Ò°*Ê”p6O¾•ßW‡)Ä´uïhsXÚôÓ gÁ`Œ3Ïch5Μ“9½98ö¢ùjvJ´I-[8°íÞ;é^7 ]É·“ýÝÿzr-xòD| 4e$¼¿!¥ûCÅ\0>dºÊ3rÌõšM½Á;Ü?tI ŒV"3Œ ¶=|–N&Ód žeRž!šDœ>#ö¸©*½qu×J`|:.¥/¸µœX eÓ1Ï0ÕªÄzW$AŠw&¤ÚJèÖ.|.„kÔì²Æ³Öüîx$5´áþÀqE¾#_­zÚgeëÝIa[9M'eâBœ]ºy(Ø[n€Q<µÅ«Ùg2›l;ÛDuJ3÷ÃŽÏ \¨ ´1'Šõ ƒªŠ6ªŠŽmóbáLì&d#…öÕ¯aÙX« ‡Òvea1Â9Liø™Eêmh‘Y0-9Dþ5;=½Ž{a³€,Ï‚lh;F"6‹¡FÖúbyíƒßÊ‚^nà‚ÿxõÓ:œŸñ¿áôy‚¹¾©‡ÿãlºMú7@cõùbaDøI>øy’œ¥s²]AàLk,Dmíg³t¹Ns=ƒwe3_Є¨Ç© ûô«v; Ö™Î?Gh¥[ºMØù!&„ûŠÖë›CUÂÕb‘å@@Ôßóå.xeC¯ˆ§GeÊ+Úw}i“nÐÒ‰ÐÚi¤›mÜ*yuW‹ÁkûnJò¦…âÚŠZljt»/S;øE‡æ—Âû1¿çO¯uë<í³ÁСÎsXh Ç|7^ÁØ ’±†tŒ/ÀL\­–g» wìËÚºïNâe\¹ÍÕ]À S% õzšÅ“œG›E3«Œ™‹¬.Í'…¤äË¥ ú¬¤0¸×-Ú©R|„wƬ„B…€>›U˜œÎ-Iûêr =g2w +¼ ™¬egÁ·€¬È=¥ùz' î™÷Ýã#d_bu̸»}ugƒ;­UzñHßFq'ÒE|™é9Dd”ŒƒsÉh·PýÁä‘ ÒI×ݘ b¤pÑ3ý#›¢AY³sîe² éõó»Ÿlä¢ç92ÍÓtrD`·LÁ»¿.2‹Z_Ê­“, µ\@ÖnŸ'þ—Ì– ![Ûò°xROÊ.Ë?ª'™UwñÇMr[À³Ü*”t€”ŠÍ‰ðó²Êg9d î᳡þvp=l’oX…¢ Í9”ž„,1pñš“6pûG€€ªxçE @oy6uCΫ Ëd›ã–D8èTP¡×ð’<œ‡ñðÛcš_*ËÏòìׄSd ˜÷Îò$ù5ùÜ ÁdxÏt–^[L’øÞ…¤ÓÏWÅ2›Ñoøø/¼OjH‰© eb^3Ï&sYÞqÌ &$Mö¯E®JyÊù7µ¼u5 m¡¸ÀÝÙ‘êœÃᢴkcÉ“IšËk‡ž]é艃U>¥&1£ìÁþÀ_Íò±‰ØõȾ‘b…ù½¤ç'~s\n¹2 5ëí€"²<&DÙ̲Kr”\&3rDŒótz T"÷B{j(YöÀ]úšîkç˜I—&…N¿@½ ßëÛײ¼û éÌsë'×JR¿¿x÷þå›×Tá—=˜µ +î…ÏæA 8sÈ +XB(…úYeéb;ËÃmÑ,žÃYÎù†BÜ-ÇŠl‰÷Ö•êþ§—jX¥Tc‰ž‚»³ÄóTA%<Ñð+ õ© Ã@n(XèkZ“Î úÚhF¥áS…˾´àþB¤åÐ ƒ £\ [•óäJFIäA#v-Ï6[СÀw‚h|:¶”qÜÈñ«uÛH“äÌw$hÚQIÀŠ•Bˆw:'B '¯K¢é >ªÚÉG°¾húúN ]hY,)ð ØñMK0þ[þKðÛoGîP*…€º,a¹swW;qy!õ8¬&QXæ0×™ï(×™Nn¶šH×i:NA=a°Ÿ öâ5¬‹\YEÇY i”ô£A³áy2Or¨Ô/Ò­ñ¤šβDa,šk%aå ðÒT|<͉ÎJyþW_Êʱ éEµ¤hi,¹¢”OÕ.ügù9–=(°Êb‡×²­ õ/Ž… ”ÏÀhZ¾œ…²°.¡„dÛ2Ôª¸`¹1™¶e ^˜ÃTºå 6Í% (%IIϪÓå«9µû•VÀˆB) eds½¡EHXA7̶‹õ$ÞüŸPrú© Onܱp«G<ÉŸÜ00:µ5ÜCZÔÓN¾Sòï6îÎÔeeѬTâåB±9ÇMü\’…zrÌgw«ÑBj×€tòºKPsbbKŸÖ. ¦(+ñmŠ*½BÛ¢8Våµ"Û, {Úü<ÀÚˆò¥ÏSÑ(w‚X¬wÑ_º|å•è©]¤Rõfoé£HúÍ“’Ì>¤þ­ËØT? 1J×à°|ÔGá(ËE7xŒ) \zBš®Jc‰Am2ÈcèÂTŸäQ·I¬Ã03òÊ#(MDÌ¡™†ZäiF±ç®"ä™t© lµ™ÐámÔ¯Ì #îJÕÁêP¹ó+­… á°F)À·£‚Ç)âñA¿œ,; E£|§öö¡Ï#@%GÈÿÏÞÛu·$ ‚÷Y¿-Ÿ.]%R²]kW•Ëåêrß*Ûc©úv¯šƒIHB‰$ØhY-kžæuÏþ…ݳϻOû°{Μý5;³gÿÅfD~ 3‘ø$(Q.º«m HdFFDFFFƇ– q&aFü妒†+á¾CÊz›h5¬ GÿàH3’å“胧gdÎ6ì{íÌ!óæã–CÛu`1Q÷V»ÃúäYMn$¶2²Ox]G16ÛnWÂñÑÁQÆ*B("Œë‰À‹§’çS¯?Åû›”ð‰Ó’q$1½Y8Û£8 Ë¡ rÒ?ëžz_L½HÝ#'"ôù,VñÅb8èPþVtÛTV“{G±ˆÀK Ȳ¼ŠÙ•x-Ä9(Cœ$œ°$@ÙÁ Þ@$‚a„0˜nÑ¿‚ë†E=ºjÒƒËð“âF_RÎ=ºO»ËùÈ‹ü[F½]s(bšç‰;m;‚晾5¦3éSUrB EâÊØØìù×]Ú 2‰i…ß=– 7,mHËVƒe¬Mƶ¥n`}B7¶MzQ&c¼Hë2ìO*†2™,žîP…jvÍÇÅD¿¡…tÉ‹ŒËø¤| 1­Í%•4¦C*†ÁSûCÐÜùÐ(" Œ¦ŸvR¡>Ü÷œµ ì?Ýîš¶ÞŒýÛ±–4]¨Ë:Ãä’B‹ 1*ãrv÷X Ýò–˜]¦´ÎÚ9Ū5ÔÌþYðÑ@uŽ Šq&Äýö^£Ýç¾ö?ôVf ©›vÎáS-*þÈzóö䕃óGVÀMvþï¢`' é-xCÑS/‘™lÜ~Ü-…k N‡°ãl Î/¼`¹£õlt ‰åEo8ŸeEÀ®……Ç`B£×ט‰9˜áA;•È!UVðÅË—¯Þ¤®?ÌÆ]6—î‡Þ—•=tž´k@>òf€ý!F¢D4òdá.÷¨ÇV£³ùW.B*•wQ&–æÒa0ó×e*ÚËT? &¾õùë8^øÞÔ_`Þ'×ýáõO¯\7מ-Á9œDàKæÈ†TøRH«•ú«ðbÀïÂE›wÆj–ìŠ`‰ Q–öL§KïÔ~YÑöÀO~Nö^€ê»÷vœ3z!ó»VUª$Ù‘’3ÊX¢OYÃRPUßÕšâÙYè- ÅF‡¾°v|Ú?¯2ÊÓÑÆrE¡R.%¹²ÿ¹ò¤óïÕlåùá‘õnâü‹p2IùЉ¥¶$ù[HnG²ñ[°Çá™mA¿ÅÁÿ˜z9Λ0Θ¸‰º¢ekÿî@÷Û¨ýÁ[œGÉIñìYnoŽó Ú¡PÀ2%µ-‹éå‚QdHif±=Ãïàªú˜tbàC±õ¾žYáбÔò3á‘‹ôÐhAõB õBz Èz*s†dà/˜¹DgÅ“ë$G*øø»IÄËuÊížîb9ãÖí.¯hØ‘ƒW¯´QÜË`6vÃ3ý¾ÚѹæŒ5 '2GB—M¬31;oærŸ®¼ÛÍAÅ»`ƒÐ«‡ÌÓÁz0#_êl‘”BRê⫎0â@ ‡ù¹UÂÑ–&4©Š˜{Cˆ?û@úWEÔ;ÒŠ û ÛQ®|<åq@7ãÒÈÆç¯[_8°í´WÞP6c햸ݷ[âvKÜÒÄ´%¦JÖÓ¿áÿÿ²™ 4É.Ä×.<é.† ŽqÐ;8xrtô/ôöo¿÷øéãé==yêl 1Þ|.Ç ˜SßjΡJÔ$*ŽDª °êÎBqi Viž€.U_ÛgW”ã7‰Ê–7±ˆ•¶VlŽu ÿd\að~M5Ìä»¾Ô Z4ídÓ^„Ëó ~a'ríQ:Y#À? $œá-CÊ­Ÿ.ô)˜Dž[o™šÅ^ã…~Kj„ AfÒOËYø íª”Æ¢þ!Ž KÄ©I…—€ ÏÑýÓËabdÄg êFî„äÒ)d˜ª Pæn°’…®7ƒŠ;`bmÙ?מ‘hÌp¡âa„Vb»¼( öêȦœ‰M k²5Ðä\‡ 2vp÷$™†ãåÄ·hŸÇ/‰_'ÎåÄâ·\Dh«¼Kÿ¥˜RãÌRë‡ÂŸ¤S‰h¥òµ¤9(Üq’~Wä¨Ss¯í (¥ß¾±c¹_iû6¿¦Núwµ àüÅ4Äê~e…Gˆ’sÝr‰}’É[Æá”ÐöÆkˆ»‹¬ƒ±…zÂ뢧耥ˆð'2ŠÖM¤Þ½±“éþN"–€rª$€GªÃÉPI¯ RB›AuŠ =¸q±ž3’bƒ Ï¤-bèc²%¾“ü¦ÈwªÒopWjäün5i[uD¬1*bö ¥ :wY2àD©‹>^ƒÖãtìÀ(º¤…¡'ù@øÑ Ò#K¶Kª¡Y„Ñ­G”›Y\0Á½}ïÂÅØqÞûºc@×ZŽ­™ï±ò{ô‰õ¥¿¸®‹¿ï=½2ÖJC‹@îEDíLAkaëK€R6™Ä]ˆMU>%°We¢¦$m²6NL6¿$…‹'ä袾5¡ß­eߪ$ò8ë¤Î¬iŽÇ¨Ñ…?—þ5?T‡Ëüà³OÑ+[n¬ä¨¹–ÇràŸ5šè(êØVNYW'òxåÙ4Ü /º¼li®ìdËæÅÒ?º¡-T×ڲ⌷ì"Yl6;È´lk3-É”ÃJ2Œw²2ŠÒŒ¡fR‘Cž «îM†ow®I8®üŽÉa+ëEµ¿ r0([w!Y#D[¯mÜçÌá—)”U, P*1d×¹Ù Æ»Nïö6# >‹Q$¥ïñL´¹LÃ!­*aúS¿=0°ÿ¢2{EwÂ_Ñ®sÊ9¬CèßnóS¨Ù¼«kXe™Kc-¸Ë*tJ)¿5æ0•ÂR8`&KÉ>}Œ¥0yÍs Þœâ×ëÓ'pÅ£im 5I‰Z0ªtb÷€¿†³Ùu€õéÚ™zyU )“‘Êe·ŽåìÖ­Tž÷²É/­gÏöþúóO;Ͼ!_ ïÝ^÷`—ÌjB֋绿œü°÷Õî7_ï<ƒýókÒ÷36ůqœg€©¯%<=ÛÇ'Ðp_´|¶O¿†ñ ˜½ç7‚»1}Ç–½7ˆ½‘7*•&Höt˜ò®³+My÷Ö˜ð5ÍŽsk“œ¼­÷ÞèÒq §È;[ޤyÍâðE‹”]y =–6R;wÏåäñáü^Cco1¦…q’p“™…"@Õ#Jdº¡¯À­€ião:{Dsÿ2 ­›¸wÓG<zåß²i~~>ûÛ¿›Xަõø X*‡„®Ïɱè{ž‘ðî×§÷Áƒ+ðy\r•ò¨=›‚Ý*^±m;»FbT-$Ø üTUÐÜÆ4b-I¶Ikò*üuW6[à„=Ò ü+3>—îÿá÷~F»¾\S²ò1Æ$}JÉÈ;ÑŠôPsïÜïX=Ó+œdÇbÿÏZë>mÝÏ95”:“ &wYú)¹†=ÇÚrד]¸Qàù ­FIÃòØãÛTÛ¾¹m_Î}sk*š`Zˆ|)›&_fC|Âdÿ/L– ×÷û0/ã"irÆh%¯°|ÿ¯ÞA¿ úõûOz·þ_÷çÿ•vô¼á8®§˜ª“…4&É’æÈý2Zú.ÞC®:ë‚hHr¥òb±¼¨¼T÷`•týD'‚h^±-›•±®¼’_ý1Ñ8¨³9ôsBÿX¦ch£]Ãn—ÛÙ [79ÙQ.³’·R†K;ò* dTÈ;Iμ²wñ‚>‘œÜJJÕŒèÐTÔvã•ì$Ü—9˜)Ø.,?•Æjº;UÜ üÀó;C ¶?Ÿ@Æ Å QY “‘‚§õ èævÐ`È‚gìÌCXìPÊçÎgçsÝx*™;iNC•®ÍÛÄÑ—Sç!nÀ1ç#AÚhâAb)Voª‘­â.·¾¢)¼eËšö.ª†¥ÁCX|Nã·¡“1VjUb¥vÕγ Ø¿i…ï\Žý¦•IRæšb¬¡ðPTÉG"QË§ŽØ½ˆ§“†‘µña’Ÿí³ý¥tsi.4—ÞaÔ¶Ä=é?Õ쇇Ožníjÿ{M™ãòÆô–†F€^À^ãò{U\ÅmÖõLyGq·b¡äªýƒƒtŸ2ÉãäÄ–rç˜ »ñ±vúr –aBKÔû3gÎÒ2æL¶ê³€lݱá(E¦«ÍŸ'ã-q¯\ü¤ÈûëÞKúÍsÈÇòÄÁ(×F¥_³{Ï¡ïr‡ÙÅÐMY‹ÕóP!,‰Ž'eÑA)‰‰è"¼ÒŽQܤ¡îþfåË·™O~ääÆŽ< 54Á)­ú¼ÖK€$Sêÿ˜—*•þ€·}¦ ;ܱ"7yªÑþTËüÔ±üSX4ÈÍx7çT ‰ã=â–ve üË[R¼!%y-º,QGDºl†Ô„ {@:qÛÄ.Íié}L.2 .ýô.RbN²Ï‚¤‡ótµ|j,à,-gÒL—\^Wš*އ³ÍM?RíMf‹ú!Ûª6@³Ù·"v«ãmu¼®ã=hCžaØŠå­XÞj¾¿EÍ÷NÝ óýEš5Æÿ<6ÄÿlãÿïäÏ#‘«Ì±0[ÐN}àDÊ"\iR9=.nâÇ-¿Tž·»"u|‹–C&«2 >Që¡Ðn¯ƒ2œøS¾îÓÁxK9`^ÿDŠ×õçÿ=8:zÜO­ÿíýïÏÿâiÅ‹å(®•¹ÄI|ÙAÞíÂð;Ó1S3½CÓ?a"âÆz;÷gÇ ŠšαNÓÝX¥yq/˜$‹WųàI(I5n¿Ø£‰MöþÍ¿¦·€â ™ìR¤-¿Uw)È•itE©Àã³A‡›…}Ñ øèõ¢Ez Îg¼( •Uiâ´ôãê¼o–ð!5TÚãB¨ rY™Pî{jqV£ˆ¯ˆŽ•BQ;ËM åHü¥Èùn4ŸqËîØíîÔ›·¾pSóvR#'†$“¡&ÍeÒå|êÓnDx'ÞèI,"ð*íŒgËÉ„w¥ñ‹!Š·:jÜÌ=„Hä^÷I·Ç ‚m>%Ùúú¹Õ‡2à-ñkÏúâ «Õ©ÀLÃït@òö°M[ã[òû“v»."Ÿ6œ+[ói€¶óîY°ˆâö©-q#+€U\¼†jѪ=|ˆ– _á¬Ñ$ŒÔ'd†Áìr¥]C’ÿ“д6&öKËÿ”ÿGïÉáá6þs“ì¿â´ŽÊÕ¯á0r½yÐ.yhOŽÍN8SÒVHoâ«PÞò»‹…¯¥» ½?=ó„h—ê]o'ÿ–Þ}q0 §Ã`æ<ü™ æÅ< "‘£¨ zxؽó¡—$’`¥—Ø;—ç•0¥Œ˜†ËYÌÇNƒ«XàNy5í/tx¥Û¯…Ù£¼Éô ÿ£?ZâÅ3‘—"ý–!óÈ€QÝ­8˜&Ú,^¨éCô ò¸; ¯và ÖÛŸ‘>È‘ „«K·Y[ºhñ­=Þ«Ìb=³ÿ–îÿ¦Áx<ñ¯¼…¿™CöÁ•¨‘Í Hþ>îéúÿÓƒ­ýwüÿ€ž6„Ÿ³ A¸Åq¾ϳ]LÛCÆ F°Ê'S¢O¯]üÑFïe䣮Ep§—¸ŠÀsª³Ñ7ð3>#Ê–á[!eÆQ4¾ûæ•]Ûh  zög1èçD— άóàƒÏœ‰­ÑKãA %É/'?¾}ÿúxqòúíÔûÑOÛ§˜rá«–í‰~ Fô‡öNI×>wý(.…i«s_Ã+¸k<:èÁ¥ãÕ"$Ú8€¿á„×1I¦ü$ pííã òMš9 ÈÿÃþQJþ?~¼•ÿ›¤ÿ§Åý÷Ç?©Ò>×7Uæá$]‚ïèÞ×-òÏmâòùqLÔÞÄûFP<¢‚×›O„gbt‡üaŽ…òG|ó€£Ê &oÐH">‚ˆjHÑÎ88'ú °Â§s»°4_?ލ”Ãc¼«–`ƒk(K»ÕrȶÔîÂUb+wûìX;šs!Ž+ƒÞá柜:ø`ÐHKÞÐ'äÕÉ3@áÀì ƒq1š@dô#%¸sQÁ§ËIÌ™‚¾FĬ¡ÓîÔ_œû-ÎAÑr¯(ǵï˜xôqù»ä^‡-Š:‰j€”gŠÄeöÓ ñg7 g­Y»´WuêR›<ún¢?VZ®""Gý¬³^ ÈrGêÈò«Äì(mëO~ošŸ¯äýy“æ¼)KmÓÐ[ß°MÒÿ¢‚ÎÍñÿGŸ¦ò<ÞÆÿÞ§þWÇp,ø…Š!áCõJײB¥Fª€\ ;Q —DH€†¸Äƒ=žèñ8/.·èµÖwË`2öx—&‚abvÁ™Ä$ú«ÍŠôƒLÁ ·¥¾Ë@ïÂ¥þ´Ùnáœ{jÿèO&!øÜ.ü®=}Ò„TWOÖgÖ,Ì8V[Ö·id@Z¼ñV±q\]j|jV éÔ¼ &ÔØÍ˜4*5²1šo«hzÙVQõi7Äïéþó÷Õuôþ˜ôLn‰Ð%ë*˜ù·äŽ.@/ŸK÷#xÙˆ ÆA¤Œ&Y>Ú %¬A@à_H7&ZÓSûßÿýß÷^HÌb¬çÿÙÚÿ øýÜÏéE©?Ç×ßd-‘i8^’F"h`ö<0>­è™tk%”¡®`ëó@V„¸ö*Lp õIñ)°ÏÂ^Ž…mÝžòfåiGÍÌë9ˆ-ëôƺð¯É ×á’ôCØ ‡÷ OÈ`øû?É+*ƒlU‘å8'üØ«, `j¢´ÞáVJðQjÄrc‹ó ÷¢‡•^¹1›—h+®0aRòw(‰V­ŒÀâ ñÌÖÅÀT ccˆÛjã¿1ý¿±«¿ú¯w¤ûÿõž>}ÜÛêÿjÿM_ôÝd5CcðpâÍ.]²#µƒ¯ô ÍÁ®ª6Û?Be¶n© Y-ÄñÈú7ߟƒÄj* ž ç‚Ùy—:JÝûÊl$/çí®7»4^4R¯º.<š`Ü=š1`…+Â…Ô˜˜EÈœ˜ M&©v Ó$cGò²ºD²›Û$Ûˆ'ƒ#8Ž4$'¦H±ÑñQ„–4ÔÒÆF#0væÅJ}޼¾°­Ö>#< Ïùw0iÙ<Ÿž¡>+ ¢xÙ ƒ‘ˆ>Dˆî-Æxä¼ÕÄT¤ðVpéÀUŠ<ÅŸâ…ÏW@¥W¥Éat ¢Ìê2ÿàé”úîª#™’î…äP„>±‘%9¡Z\…ÈÎ8#¨ÙC\.g^%–)EŠõ* æë¬"àå–ž©ö ‚†.¥þØ"RqFÕtµéLð-oENöÒ§‰â”v½ÙµÌÈÖ5AvˆV†üU9:„…ðiú)éüÙ3k*9C—d$`e+'A…è"¼"-ÓP¥îš‘(&0'nÈÉ“yþü샎e!î<óÊ:€&I­Ÿ|.‚,BjµzÏß3e X°»Š!¹$ãÜ÷SÛ¨9ƒ’ÆÊ®{çLo8r ]am<+ áȯà€ Pψ“¼¤N@GlÆ€ÕF’½XNÙŒ2£¾•« GûÀ±ìÏ¥MVÌpÔÎ:¥s2©¬Q‚^ê4K"N¯c!%)Û[ê­‰zé ‰ÅR(»Ïüv£8! à‘EÅÀ•%¤óbµx˜š~!_—ft/àv—q ¸÷ªpNïKcÿÌ[Nb™˜i ’Œjܬöê£7Oü‡¤ϲđdØ„çV\¯oÈx³K0})qÚù~ØÍvAR³, Jù´ ©…˜‰v8I°HaK#2h‹ j0°L(‹ðy;® QG ÍûÙâëRœª­FtšØ0eK­Ft 9Õg$bÒñ xÌŽ{ßÑ*O¶ÙVŠÆKP4²{yú9Ô=¼öm9^ ˜T7ª÷IpÌ“h7I rR%åxÙÕ~ïó7ß»(¼ï‘TȇR•)aV"… 0=Õ°¼f‡ÂtÐuE!c0Ÿ³[fn³ý—¦Ñ¼£øïãTþ·ƒÞ“­ÿï&Ä gìÁ]Y|]`¦5\£Lîã!뙤‡g¯°¿DÒß“åÉãÀåºöÎÁhg'Ý쉄ôw ö¥ÌŠÀBÒGÏž‘]xr–ØBâxár{¯E“g½¤qq꾂Ç—åèàð~uÖ±Ô> âeÙMtA0 ÉÊuŽ0QNEññr>1à|<ƒYüƒw)6¿<Ï çZ<ÈzA]lÀq™”䑿D?º‡‚$aÜ‹««9tM‡ËÅ9x0ØüàŠ‡VŸéøÌ xP°ç‹À‹ýIrÌLÓEÜBè=ûÚ±ŽzL“w2·¡½͆/ ££ð|Õa“1áC–íòì¬k—…T ×ÑúЀæç>4uY,Í*h-¼=>80\¨x⸤§X^}| oµ³2|wr—z ñnænãqš{ƒ3ëÊ›©¹ÒKñÇ ~ï@Ž01J‚<]HƉҋšÁBÑÇhǯ¼_ìÚêí;±42©Ûu/0ÍuëÕ­ÿñÔŸwÿÛ;êêõ?zÛú{ÿ/)zè ˆt¦‚o$%?ÒAþ¼H ËÔ¤è}®Mþ™ý®ÔÙW‚–lC’ò%é¦?’7e@b‰ê™œë0Ÿ­éIŸ8–øtìÇ^0q’ôÅWÁ˜ˆ@ôÿ㪠ý7Û†aă‘¡Rê÷ÚÕÅ„ÿï$,½@÷{@²‡5"JûbEP°- w-\X#"+ÂiŠm^âcº*ž™R[ ã•v‘>\qH=%è:‚Ý0ÑU E·?–ŠeØeÏxÔYP«Œí†=&sæ¥3†×\OšÂ·pŒOë=¡ÈgYèHÄPO)Òí3Ó8Ò—Îï—3ˆgä ÆéJÊT#Yñ B(´ç‚kÏbé«[üàd(‡µÒx+:Û%€+™eÊa3_Á.«¹IÕгÊgŒ!ã!*}u0ÉvÁ¯XÆ4ðâ>;óDw§,éø±)ØëˆÃ—VYêãÍA)+‘ÃäZ0£r¨¡gsðHáq´Tˆë^¶7»ˆ–]gðî­]Ÿ‰êõ9 5­2 õ4…»Î.UÉU$XÕ‹ã³wR$(©t Ô¬·¼y°Ùã©ÌÞBxð¨ý-‡ÓÉæÒ‹wWË`÷Ù7€ –¬ðùßw{݃¿ïŠÒÂäÁ/'?ì}õ÷Ýo¾þûìâü`YϘü5ÒèÙ>ÿ•4Úç­vë.¨Mœê ©6 è úZ]?ÏöÙclB[3"ñO%éë²6,ÆJÀ(Á²ú2Otivâ§TS£î—‘JVµìF'Rö3zý/fM´ó›ÒeôèHŽ5ñ¦Ã±‡Q´Âã‚Ã~¼ðFð3»[!?ù³Ÿ*”é»ac$ [9¿3 _\º?=[löŸÛ»S*}†Ï¿ÎÓ/TCÌÂ?_N¼³|á±ïžNÍy3›W8Ó™C}iã1šØjFhSu´yÙ¡Óˆ<£åP²‡Ö@ÞA»4{¦-‰ÛKµÏëþOÈ;¸ÿë?}ÚOßÿ=>ØÞÿmèýßœ9J‹¶èÚ.b€YàÛM]9¡$H%ô+ÒSr$‘ÆRh:;t0N–ù C€†>¤7Ñ!Çþ™êø1 ÃËB=ÀÎO¾€”H›Ì”ÌkK '‘¡ž´ë¸ø}õÜúƒÌb¿{qò£ûúÍoY…)ðö¹‚0D[$ªyùòÕ»“ŒR!\ÈÓî»Xóüò'q±?äRþgHçøgòMw¼œÎ[´´TÌÞQ’>o)H;E2%>ñRÐ-óΰˆz?JB:X¶y¢Ÿ#ôò¶‹ébD¤O6#ÕƒnÌX§Š~gïÙµs"NÌaD+cP<ŒÍC;¯7 pÎì1YȦ‹‚•Ǿa ƒ®L%#ùÛèœ!óâ`³3aq2¨c®@‰›]p×9½ÁI;äïî`wJ³1Qé‚/+Q)ô2”#gã,ªñòî´SuiÔNK“E6D Už‘ íÝ$ ºZ£‹„ÁØÎ¯ð)ðMÝÒ.Èf2‘ãi¡8¾CöEu¸äámN¼=ÛðÄ&§n`‰E~jc&'¾qÞ*Dÿ’F{Ô Œ¤£Š­Cpf’¤<0¸$¼¦ù„Ôí™–ŽîPþl'á£ì–\âžÄ´·¨ÇF[Þn„dÊòÊyÒ½|Θ"Ò !8eÔiÙ"6#õÒIŒýØO×­]‚ È/¤?Ãz4DÐ@r°Ž¥#ó'ÌÎBœ[F`¢Š’9]¦0ˆ0ŒŽñBÜœšQQŠJØá3+€dj‹HÌ»*˜À!ÿá—Wïÿ柼ÕEé(ÏWÂʬƒÌº™áVA`eøâq|¬4‘?– äÁÝC:f­’ËkðÍ1+6MV”a>ló«3§.Áãšæ¥PÈ%ëgñ`B³Ü£OYíJÀÅ ù£f‰×ô*ùÇ’làñ5Ùf—˜È…|óYL!(íi ü÷¯Ö?žt;ÚÔàq¯{°Â …€b‚ÞØúAmÒD‡ið²ý€; QG.Ô„7 ͱyô«ÁPÊ2µq.TŸWÐ`¸Œýµ°–7=ïws)ø´1 šfù´ Š¡­¾ì³Ù¹Â2šì}è}ÙTP½PÙ= áEù¤˜Ÿ~Š-2M°O]ütÄa•h|Ê.±à+ãü¿”‹×j™5ÈÿÅŦ½fgyY_*[PRPØÚy‘í&6‹®§Ã齈:-`AتL†é6gÞn:d¢£L]ð`v,ûà½þs% #}DÉ+ß™w[Fú=…Hìj<¡Áú©™ðÜÇIGªrRQWaþ/eÐ3Ô N( BÕ„R@Ãb®_òyx K­|^< îþ|∣ËÀÀÁ%I]1òqZìóU(¶§ô‘!‡YˆÀy@Öü®I´;À™QôVE\M©Z¿¦Ž H†«}¨ÅÖ¹?óÁHbJþ}¶™3B„Ë8‡›‹“*tQ¬]ÁˆCŽ/Óz8owL ­‘·ðw³¾N|Œ”Oá¶.þJ}ƒÐ,þò—ã“·?[P–þÅIb—e׫¬y4•«)çÔñ*ïé×^Ù÷]à dRŒùH nß¼ßc-‰]Õ©™UÃÔNwªÝšQO_[2ÏdB™OOø,—š>~ûfe’šT6Aå!yËh ½™{ÁDêÍÁ,t9óky™o pý‘'³RVMêUôKL"Ç9>yqò˱ûï¯É ß¼u_½9y}ò7÷»·ßÿ^„€íëSÂK»Âè= ÇÔcñÑ mu+ ÞMgŸóÇb‚cÃ<ØZÖÙÏm­ËåKúTÿ™:µžY7óËü«`6_&ëï÷W­woO,Â(/´Þýrb}ÿê§W'¯Ú ipŽÄÓ´lí˜N¦£ ÐâãçËølï+{t'‹¿Ä‰‘ƒ'¿Uo߀zìdÀœ®©êÑ …ð¡£pn¼ Ü 3´û.»ÌþˆŽ»zuû $¤¥7:¯ßÒ,¡7»AäÃpâ{³]ýHwéu㮳‹– á^hI³Ùê,–Å^FÖš(¼UޝÒîXZ«w/Þ¿zñÝO¯RMݳ hù³"=+8Ÿ‘ãwD˜Hns«),ö€¹= ×_¼¾ú×äê _~ç-r^NÂÑeòzGʷΓ¡‰¤‹’J~ë |—hÆßâïD“¿1„pC™/ÂÛKÈ?R!ú¿Ñ;SgùdÖáQšÏ€(ÎD{üEìÒm.»­úFx¬©Ã•ÆÛ ¯%L¬)ÊS‰±ú¨Qéð‘Ý,Ø8 :ç9œÌÆþÇ<üÒ®¬ƒÎúVãéÁ CžöL*òª ê\­Àq&™¸ôfÔÇYÇm1ÙH™ÒõÁ#¹$þ…³ëiÉF‘+ÏÉ9n†FòM´$º…ŽQy½¿„w,1{)V&EJv4BŒ H-Cþ ¬R ^jžn(‡M~æ&¯’R Aœå¤N~’aG2ã`ž.”C'»Ô’Wkwgr,-,¶Â‚§ÜÇz¯Ía­w޽MXî)BÜÿj/£;d¬÷=µ™ÕÞÊê.v`…µ>õç¾ ¦²ÒÑ"Oõ‡“ ÷³Â3+$|è±L_³±RîBOiñ£_i†é¯¸ï‹ÑLÈBÖ3Ïü’ÅÃkkHÓ¢Y<ÕDº 1G¶ä1¹z½’_-3´ Jê~KiaC±Eºó­rP—Y¾“› (çÃ$þ ƒ…H½]ýª9d)œˆÆN[¤Þf$ŠÓ/Ñ’±® Óåþó¹®4YŒ—‰ØüZw‚)²Ô¥•µÈæc%†ažŒ•FyjY+˜§åèBæpw,ÎAèÈg:Ò¨uzJŸâQn`: Ó …/¹ñ%=›$`f®õê#é¥ÝÅ^ Nƒ"3šÍö_*±Ø§ñe.{àRC}EËpÁýߓÃ#Íþûøp[ÿscí¿áÌA“xÎcöàGj¦S¯)·räü‹{äZ6óãYå:dé³džŸ>Y7·m“T4y.ÒÙr¶foä<·KH4ìXŽqìÈaoMÙæAWÖý'¾Q¬%FÚœÚzöÀ˜£8ò• -Yàv˜ƒzÃ%9,¸yõþøõÛ7ô¢‹t¯© "¼•CÌ%÷[kâJÉÚÏ*¤7tÁ™È„bHÚ±¹àC~SfÀ<:xb½ c–ÝvȬØ@Ž‚/"š÷U™^:CPÙùõí6n2j¶¬‘åÒ¸áÄÕÕÌJÆ¥Ÿž$Ùå*T³ÿº÷Ò‹F‚Áæx:»MÚ&Î&'J–“¬w9z J$Þ×. â|²Y¬9à:ŠE7›îÚ³QD¤øÈ$T4_Ù[ÉB ÑnëBD,Z.;§ìSXÄIßû›™ª8«óª/“Êb@¸-W[Y,]‹E — cÖ ÏÛ¦ø„¦DÍon2#Ã’©ƒ:¯›8öÃG›¼€!•7ù2A”‰‰Z6›¬iôïTÖ:ËÓù;šYÿºËÿ€¥ÉªÏ`©n×ä]ãç~ß6Óü:ü¿’ó­µüïŸ>ÑÏÿýÃÞÖÿ÷œÿ×}俳S>eóD6Ò¤!D4ÒìR~Œòf©ÃºdŠ©dH´ö+oÅZज5ºƒ‘WjngH~ Ön,ëIà5[­£4¬ØÿCæZÉ<2QÂìŒOøLåc7Ù±(æ0ÃYõ#8bŠNÙ”)§â„åX‡8u™]V@C*›S1à“ “§—ž³yج`ü2§âa2åÉJö6¡÷ë™ÃfÁ„®ãmay³)?‘$:°ä,ð Ò±œ=)õ«<Ú“ÓpÏ@’ÁˆÙQݰgjèg: aæiˆý20'£7òIsØ…lZŠª,SŒð¬Iå³O£“¬6?9δìäÊÄ¢Rs.rõÈ‹2¾–Å»¢Ü›M¼¾TkpJ%ìä˜M5ˆ,º˜s3[nŽx¡©LÊfמý啸í“Ãù»Tœ”¡j$ÕMÛ9}ñ°&Žê–Ñ–ÛƒB†  9¯5;ÑË0ÉáþÝkNgár&¥ªÈ.Rbã¹¹cK˜°ô$¯ii½1VuË1ã<ò—ö·¡µÏo¥uÞÈJOf­/öŠË½ÙßÄ’¯ºèË-û–yÙ›SH•ÙŠ7ä*»ìª7Û•ú&Üv7·óIöÕu]a1×YÈŠóH{§©U\eWY½ïéåk\° ^·~×ìÛëõ²wv7櫺µ/Mó»+S©+£Ü‘å–Xý±PÆÚ[R5Bªo4Ëíð[ƒßЏJ’¢Ê%§5¬¡i~Û½å³^W Û½Cªà>Þ±˜>^Þg¥U†)ÌËíAÛe¸Â2|zêºÏ ƒqÀâ¡kÁY Y1Ê)¿¿j}èYúy^a´¬Zï.çžD¿1 ú€„8O—•[ÕŒrø%/¼µ Ô¶ ¨KSúáòH/Zf/œ’‡¹À‹ˆ×y‚2Ô.¦Ñv1m-SBû$ž¡€Þ– èzWY2=°>ôh:ÄòÝs,Ñ;~Í#*ñ„‚y]oo†¨Ñ.#È®«ž>:='8jÞr¥€uÌ’ô1Ä’½%uÔ“®ö¾n…,~Ó¿3ú‹´1{-ÿbGÆ.Ža”æ"RïÕÏýp1™„z ;œùvé’ ‘úõ‰Ô¯A¤2DéW#J?‡(ýÊDé7E”ø*¬AÈ!G¦­…ÐN‰Èˆ-J+ó«^úU^aN¦ $…ÈH»y@f,tä+¬q–:‹Ì”Ûéɾ6  2æä,¨‡‡lÙÞñÇ. ÎÞGŒÒÇï²Æ²×e1 Dá¥ð®’v™öDH»t1;ã²27ýZ¸é¯7À¬kÇM¾¿|‘ÿ7æ1]1hAþÏ~ÿiÊÿ»·Íÿüü¿ßw”wÿÖ..¹78MÛAMøè¦š“8‘øˆ‹ŽDªgêv åÝ%pèED‡¨ç‰r|Èíé' ÍÚÉ}^ãÒ,%?±Ìr'CÞ_—la-{ß»ò¡ä4ñ/F¿ÑnD0‹u›}Ùè:í Ì7»-ô,]¦–dN­p6¹nã ø´ ¬ex†X âf'Ad"ža\lB?N¦–ªMAþ^\³âbx¬y×ÅŠ3î Œ]lG/·•Ü̃8Ëð”CŸª‹Q·?yî yëÔa^`Ð×MqƒŽžüÒ}ºêÉ_L!;I:K1ÕÔÑËO‹£ ÎÄ­ +É(…?äiˆ¡H¾…0 Ö2ÓìÊ­9V[2‚Úüú!µÞVYqjöqQn‘ç/'PVŸT†$©<3y˜O¾*{ðo1c8…5HaŒZ”r–‘5àAêž=Lü¯¦HÛ¡šÁØacä|3ºhÑàɶnwÁÍëî¼° &gŠ£ƒ£4Oà4¢Ä4_Í…÷Òbú³µM©Yö6@TQ%Û/U.óºÑµj7½_ìèod9¢ª×âtx›Bu’xŒhVk $dy¸¨ñšƒ‹Jp{UŒâ·ºùµÈ¦»·§HÆ”Ùè&ÃVp»B°5â¬Ùˆ“‹å­Uf V™Ê6”*$gGÖŽ*¹wê˜L7 ”CB¿ú"A¶¬ uÍþ›&Ÿ;š"¾•×w!¯Ëb}+¿¾üNÈû•ÝUpGr{›÷ånò¿Ì½øbÕB`ù_ûOõúä,µ­ÿõ ìÿñÅý›ÿã‹Õ¬ÿÔxœž!£‰ýÐfƒ¶RIÈ`¯¦ÃÑ2Î6دZ{’‰­GiUÁN àŒÔeà²K›¢=†l2³#káXûºûÙÌ,Nž3ÓP‘¿We‚êÑ€¬´yêôE>FHªÂÁ€Ø_xc¢2NŒØÔ1§Âú Õç>ô YGÀ† ~ái<úƒtèÓŽšÆÃl ¶¼(Iåɹ<òlÃâë[5—þªÖáröÜ4¡BçzSÞ5¬½x/ ½hœÉz…^k@0H|ìXC"V2Ó÷Òå1Î[r؃p¡M4sÕ3<Ÿÿ$Ë`ÂÉ'ð&™Ž­B²œ…a ‡[íï¾ô¿FjÀÕÿîêõ_{G‡[ýoÓõ?Ió»SJ»@WKt2Ih8&­»ëâ´… DÙíb]PSqä¡è Sî`´IÉá/èŒU¡yr¤EéÙAÛìÑŒ¥ rG7~QC9†öVÆcêëŠ0îÈÖZøç9²-þ“ué__…‹±>oüŽ!°-ß6ŠÉ²Ø½ä Ìû´èÇKîÃŒ#º2˜Ñ Žß;Ê@íråÞX—à–“}>V„¤ðZ·ˆ9Õkb Ó ¬ï.‘ .]eù<›ÜY%à¶œ_q¹óÎLW6tý2Ì‹‹›¢•ô®ëf² É-œÈ†„þ^0ät6?Ë$KË¥Ó3Œ¬ðŸ$ï"ár0îÏ´6|ñü SJ˜PÅè1VVÈÍqˆæ3C…¡Â>ÎГâ#Óx%í;øwV‹QÔÿìÇá¸,ò¦ ™O;jçÎn–¯.‚Ñ…5"  «M³oM±/)Ñ™ƒ+ý@œž2ºÊPXÔýr×)Ï`LÊ"k9cÁVmÝÐZ&Žæ³ÐÿW¿ê«ÿóäð±vÿ×{üäIo«ÿߣþ? ÇË Óþåí9¹ðÓª¯`÷%b:µ§þtZVê‚ þàÓsK\áÙûN0¶‰‚2»Ž/ˆ>”ü”’!ðiwá]¹haæØA¦X“pƒhîü\ˆH˜Ó„]“èWŠ~™–€*òc¢lœG%J~"rÖ±l"Em3X¼cUúƒORs\s\€Rvrî1N]x`6"•ÏÕ'dÈôI 1Ëé Ø°Zs\ÞÊ• îÀ÷+CÍ'»ÁL€[ ªß_e-ØNKA¬`ø&aH:À¢|f€†ì*i]Ü Árì žÃU`l†!¸ltóÚ'‡ÉÉØ.!c ê ˆ–b "æ"ä,nQ&À|“fÌ‘_Nr©I ÖMŒà1ŠH9êL|“2=êÄš±Ý´ä@) .x&æ„÷é%Âh f[ÓØ€4yÈ(äÙ;B»"¤Œyœ/6ýbvM«1:iYZóÐç‰ÂL°@!Ž™³;9úÅÕ´$ ¯ðïÔ€JJºÏ””ö~ K, Œ¾ ¢ò*%ÊÕ)É–ðu1G–Ý,‚‡®A\ª:VgÁã­ÀJŒ§°[%°ã9[øzׂ£»I`³ñðèd‡Ìn<¦hb;f0$þ%kÀ60¾zJÏ-Éš/šç–`2BH ¯¥¬ÄfC”Äù§ã+tÌšUñFQ[èLzg`ÍÑpsõ ¡Êâ[}¯ªÇliH-$E!wÆÀ8ôãz @Íж/&ðbR:8•Õ£4$؉yC~œ™|¼d¨OY8ÙO h`dá]±¹ „”³ÎÈæ¶ {SѰ/ ,s–Š–g*õU#8½.ô¸ÇéÈÒª& ‡UôÒ‘œgM Ë/z"æ*n?P‡æ°¸tˆoàª÷¨Û=û^èÒˆ wõ’Ópʬ…hJßêâ5QiÊn =¨PþAB’ udî&×£ BîÞ ©þq[¶‹ÔI&¡BYîw:þêx„ȈKq}à •!N55ëÂÃо‚Ê`\^ñóYˆ¯‹:ø±kö>•š”WKaL]¸‰Îü›^ÂyZ¼ G/7µ¡»E83?¹ÑaՉϊ”36³O íÍ>‡²¨„ÀÌ]„â¾ãÝfï×ò,¥½›Èzh‰½²{ñ48¿`Ñ"C˜¥EÙ¬esÎGånê%hS´ÏoãEªßÿ/üÈ'|½ˆ’ï"þã°ßKÅôzGÛûÿ͹ÿg¿¾²COQêÓcÒèüýr:½ND ÓV˜ëÖ÷Ç?AVù(ûïÃeì'ÂÀ‹ã…» ×;,”üD ËÅJò ¤šHœäRâ4õ×,­¾eW$úc¹kx™(žn0#C€u; 3XGzEøgtÉ_HR±Ìf+P—üd#^øl*Ûõ…D÷%wŽ.Ûê^ñ–:6‘©dcDÇÌÁKÛn˜$°uEû–<.Ê–ô,ÿ¬ø+C8Ø„¹°¦°‰HÉiÂÀ xÎ’MÝz5zHüÂûçNqLeé%§O†?C7òÄË[,éçŒ*<ÖÛúèº7z’v#$'K‹aò"Å‘øÚ *¦{m$Dvc»§(ʘzW}sW}ÞU?¯«BêeÑ/‡‚½Š$Ìí¬_¹3m†S Cp»BÎÈ¢Tƒœ:@ AŠOzìEÉúéúìEjUòmÕ³ÍÑÿØÛ¼ haüWï@ÿ::ØæßDÿO–8U Ì`aS.õêÆƒæŸ^ð#¦Ò„æV•’¼hïórÊÒîöoG23Ð|­ô_còXe LM#úÏͶmˆåÝ%³Uç/O+™®Š¹Ö¢aAnÅòéHsP ²¥+Í‹m<|R`6€>rŒ>J²xmÒNs#ûËîõ•Ë“!yöñúŸÉ}Ém~ŒAj`± ñ ì ž£É"p\ËÒß`Dƒ&™ ÚYPÎuä´AT|×[hn¶iÙùB&Mwê/Îý–mê€#?0(8Õäfš«ìª‰ï“Žm Ç‚óÉxó=~¢½‘§£ÑH¾Ý¼Í>`UîÏE/"yïæCBU‘ßFô7ªªe’³³rÎHš Æ·8^¬c.âxÎ|ûà²X¥YFï5”´¤Û_Ý?½ñî•ûúØ}ùöíO#×¾wQ…NØw¯¥…€çäˆ:Ádìˆ ÇTpàGùôS˵Aµ6 {¯£½—!E .„4üA*„óV/ÏΚÂa‚ÂWoN^ŸüÍ=yË’È@â›Yxe]Ñ$®¬³8’ØMݯÄþ´þoåhŠ0ô,Éd‹VCb¢è§×ÿöêØ=þÛÏß½ýéõK"¨Xq³1¢ ¬î™òú"oò×–‰{Ñ1ÔËy I² <Ù켇Rþü)¸ô£½c†>ÊÒì¶Öá ú?ÙŒ&û’¡‹ÛÂV>äëÿý£ƒ'uûïÓþVÿ¿Gýßlþ…²=ê–ü:á–c潯GÏ:,ÏœX‰éoº`ÒˆÝóI8ô&¿K K®Šú³X‘BLǰÀ’œê–(½ÝØ›c’;n×ý$Iþ¬KG>uè¿.zEBµ"þà, Ý¡·0}*ìÀ§NbN:Hž•éC63ËýÉ‹ÒÔ·ü¾Ô8Âf-"ÇHÞ–aკ1Rê¥qÄt«œ‘QQ=u¨¾šôF׿3nÉT•äõÖÆkUÆEîŠmÊŒÖó”g,”=~FÒ¾6²S–øã¦U†|ZÕ—2\žšøˆŠ¢”O&@õ,ú–¦2Ñô(> rõRšXzMi6`ÃwÜlø¸ÜhîÌÿ¯4¤ÚCJÅyab¶!f:ÛKæøÊ~ ÈØR0„„÷˜]W¦NT@ž¬=.'3iEù§ܦŽÒø»—“±uAŽ•dãgg>ŒÀµ‰9>W–„,‰wšŸ±èHg5æ­^r2§9²L^úÂoˆŒƒ•ñR ‰ŽJ,d6©ìO’_w²ƒùó R¨às „²¸4»†KÂÞü.gd¯F|’n wŠ—áTž WÚ›«JIó§™XJ-8ô…‡+p*$¨3§‡OôȼbàŠáÚzobRæ.39¡T—™–æ Y­IqÈU¸¸dqeR³R›B uË0­Óè÷‰ W˜µúÕ Èœ»7Gä‡ÈŸœÊ.‚ó`æM œ”8ÉTìxÂIÛ,­ÆÆ¡›ŠsJ\ƒ!¨X\ËZ˜ÍÀUöê)û¦rŽÕTžÒµ·–’Ò·IAuZUZ,”̦q(c&…))í!#¤ÌŽÎ–)ÃU^¿b†Ž$Ê{O±Lý´ÀS-Z«ðO:åù¯ÄŸú”Ãg­LfvŠ™|N¬`Љ-l±pYàË­Š’[måÉàüJ‹ËÑ––u»u–Ýúÿ*þ¿T=Z=°(þ¯ÿäH÷ÿ}|ôdëÿû üÿBýRñcèHy“n©”¬JRÛµx?†üÆ>*}AƒÖxé_›•Æ”5Ûì(Ä%+íÑè²¢KáêW"æ„Bgl>¡Ðw&[üýΑôKëÿ§ƒ Õ_\•¤›:ó:`i jÐßàÅëÐeeèÀ­ð |uẠor– |œ>Ô­Ä8E¶ïšŽO £cȬ‚Ñ…7;ײ® ~C¯5ÙùyîMè1sý37À Õ -‘òÅÓj/®Bw.ür׆²ëÿ£•ôá°ÊiZ¯Žè³¼ù!möà¹u˜Ù[¾7Ã'òU™H7 §ó‰ÿÑj]¿‹Ì;_Ó >ømkìÅž_Ï k·ü]IÄ×ô²Õ:ùÒ‹¦ï[Ãå¹õè«?öÚ¦,lŒe¥¹ÔhGiºC¨–LM¯çw*w~U¿¤ñy`ÞaKò_“Bkãå|Œ¼Ø™8Ô ü©£rv•žmS…lœþŸ>u®~ (ÐÿŸ>yz¨éÿý§·õŸ€þÿžrË1g–‚C€V/:ã`h•{ ú}”½ŸM&VªA%Á´ù“¨ä>C'·I+Õ_7 q±RŠÁÖcœUù(jêlÑéFÊÌvÃWjßoaê"¼ýÿaƒÏþÜx P 99ÎÈ!bá]CÄGžÿÐêz·æ:FÁ'93!…ˆ7Š—"RÍj±_Ï‚E·ïý0yê$~ ùSÛèCee^¿ŸceûÌ—ÑAîÙr¾«¬µ¬Võ¤ƒæñ=,¤†JŠæA?u(—â®TkJŠOIήmœ¾ CÒoø²*0íA@mè§£À3x&Š<â5jÑPÓÊJæSexŽÊŒæÌö!ã@)b´VCˆÁ`ºvŽâ!ÌŠj/{F^“±¹•¥yH[Ëm6ÎûßíTå üª,G$0¤zÅW…ÉüI 9ù’Ò LÝÿö·ùÿ‚ý§¬áGk—aø1´ZÙð³µûlí>[»ÏÖî³µû”·ûl†¡§c9Åý[CÏÖг5ôÜ­¡'ºcêukèÉt]1’¼“wÚÞD#ŽAM7qL*¾ÇôÅo͈SÄ- ¨*ܳ5Ð9 Η ”»+‚ ì?½'ŸjöŸÃÞÖÿÿ!Øìcdئ_ÊÌ"­9nÞ‘áKa£WV¦V’¦ZΠKAj9”G{D.ÒŸú‹þp‚þx4à“‡ô§'Éë§âã¯E.ÓÉ-r|‚d²ô3u§{,ƒW+BǶlo2¿ðìÔ›¾eý˜¼H½9Ô›eŸ{Ó©Ò•^z/y÷ƒ%/¿JwüØÜñ“t9†0ë©ñùWÉ@ŠÂídèQJ²52Ä9s²Š ¯ClÅï!nŽaÚᨶn+öò8éåIòãSÇzÊYó+Çú ÜxÛw»¥HòŸì£ÁWW´%Xƒá2ö#7ˆ}²æÂJÈÿƒ^ï‰.ÿ¶òÿë¿ Ï„ñ_Þpœ‚9^3ÞI±õÌ~àþßòú§õ¼Üˆ¨Øþšë¿<~ÒëõSõ_¶÷›»þß!soPAÓñ„~×b_¿x÷º½#v{¨ÕíÍç;’²”¼gS¶ý[/5e«E'ÃÑrÊmB²iƒÚ£.º,vE¹ÅåÜ‹Æx•c]'Vùx±Œ/äÛŸta‘…ö­èH´Úœ7±œ`wðôìX¯É¨ç>9³Ñë¨o,µ%r™ø±YóÄ.ÊÌ-oH曞‹©ž¢Š2Ъ.¼¾{é_·l®\,ËðÁ)¶¨ßñ¢š¥>=å­ù»uÔogUý+A«3où j†N«¿‹x)oqŽóyí{3‰|8ð¦QfQHBlT“†ôÛ4«ÐqL "-CÏéø–ý&h¦_oÅ(Ä…4cÍjR¦ÁHöYC–ÄàmNKbVٔʧӎN*‚&ÊÕ7!FN.]ÔÖÏó6ºt,¢"Üͦ¤™|3”b'Ŭh”eÇR‚-»¬ìõIzêÎ?%¼½ëM&áUÄ“lYnôÆ·»e"Ó#¢¬Oíë4þ| ¥f¯ÉÒĬ¦ØÔ.Z¤–½X'úm(l1æ]6w¡|Úá`>ÐWÑ\b—LcN¿KTC²ðÓ?8hç·†ãkQ 2¨ä2¹­QJÃ)5¾‹y2#œ¤|vxRQ¢rY/ñ»“ëy²;ÁAžˆUE\;r\ òÁA#¿…oåÌB /ˆe˜?…õü9`O ¶šWYÿT1ëÀ(Á,ˆ¬L›å[Ö;¥LE`jû÷#ŸÖxB~ôc¸›<|˜û»d´0·]FN%lŒw/”5”;N ÏFÉÕ²÷)A=¥CÑ«ö.±¸Ï ¼IÛvˆ ƒJÎ š«1g1kÒÎÛyãk„.ÁQY¦^<ºhí“q`÷gíç‰?z{Ï÷!Jz¤ Œ4 FA<¹¶Îƒ~"•"`ØtèEþØ‚M¤¼åOü©ê?W†+Èé(ÇçŒX‡Ý@9ÖÞׄҿ¿j ´SüE[©~nâÖõ™Äæ¿1Á¡³ˆhܱ Ž:ÜšøE«^Žg^0‰ ¯äîÉyOP Q„èzð¨¶É`ëX€b6ˆ´"LhF‰‘îF>ÍÝ€›†äýžIe‚4¤S r6ô û³åtè/²°Úë€ÃäÈuŸ¬=ÔÆ,ú ÁØá@&&ÌÀ]± 3 ¼â“ˆ  &\EUi8ñßâCêP ð÷âxÍJÂù³—jÛi£ø8èt»½ƒ¦g–„(û@E`sMlvÌ)xŽÈT<Ü&É;X¢sP´Q®^ø£Kµwy„UOY §‹°J '(IrÊFéeI'(O'Y Ì„|¦.P Y ½J;f¯üòÌ˰Hk œ¬ùÔYeÜßПLDØ’¡€ T²4EÚÛýâà)a¶$(²Z ™7ÙEq>ñÏbÖNHï šÙ±õˆiì†gß½N:¡šöƒQÆœ@Ú@Þ á’x9ö³eÜQðÿñ@r¥k@ôç˜Ñ(~ÁùŃAPtgJÛƒ$6@škr¶˜ÑðuBc¸ ¡x…‚¡ AÌ%ƒ;='{³ ¤šÑj@lb$3i§ »Yíèö%'ü*!š£Ú0Rtç{¸èˆñNpyyV èªƒúxÉa³a(ä_†T O¯B[]…ÞÃ}a߆ؕ]Ýä6ñã–E¸LAàGŠíÙÝ®ýÏBÓÙ{hGŠÁ‚>ÈÞ—ô„ÄÚv,úçW{æ´_3š,Ð|˜€@%ÙÏ£`ìøüs%|UÃ'%qšÅS“Gµ#¦‹–³[ ë²ñù"\Ε®­H@¡-†È¢2| tW9)ä‘,ÇÓ¥HBÆa¿Ý{ÑÏAfÙ?Á€`ô{…Ò¢ЉD»7¸³eŒµð¢ò¦N¾N°ƒŒ5Ì®ú¢¡,„Ú/BSxér¡­:–jöЛû$¢¡i˜ G{§ÂmWÈ¡Óå]âõ ›É¤$5¹­BJÚÃ}ÐòT"æ`c©¹~Lä¤Êišž\t±‰hSËY´œÏÃxWµíE§ØáüxýÒè—ú†%é†L£àjOr¯CqìÏI;š¨›l¼b]évÝK–4\‡¤¶™z«8ö£Ø¦ ³¦äèÌ'†#»"'udáܳ8jT£8|E\¥ Q|´ 3ˆNj0DnoÃF{«Ï+•¸v”õ9Ðt¬Q³,ŒBø˜˜ã.从ˆVZÿùøíæ†bâÖèz: Á}Ä•óÄx02.¾Y0‘)X¦´éá½à $‡Í ©u¬ÿÍBUY¯`D* QWã"Ã"ƒ ^ ¨K2•'Qûå犜ÕfJÝ/|¨a¿‚Y„Ê‘fp-©ñ¶Œïå,¼š½ãàæÊB7uw,8¸3ë‘.£Ì*žaÓ«²ÞªÙè^È—=”~5‘I$› Êg× Œ^S?мsŸO“b>A«¯èÍ‚1üY¦ÓΕµ U>Ó·:z0‡ƒ00œ¶a°&„Þl,^uK5Ú[œª(Èg4FJüö°iUv³Ï Ýu®}ÉSmi‘îp5ÝX«ŒöG¸ ‘s«Ÿ"žj¹§øÜdz޲»Ì&|Q,ôÝ1ˆ™MÅ燮0†Ì+šI¨UŒí—#Í{æ‘5\BRØW¬‘ûðÙ"œbršþ,9*STògcÆô¦Ùsáud=·~´«pâ¶Yö$™¹¹íp÷êœùѺ¶þÙæÆÌaº­|’°ð šqÝáÄ›]²`#+Õ²cl5`—”Ò Ÿó9tÉÁj¼$´ðvpÚ©1‚À$»ÁÿG &t¬€‡Ð:¼WYj®_/ï¶€,Ö£›à¶­¤ã€œs"¬]:C¾¢?Ýò1é#øé–èO·»ÙÞ ú ´¹ðØtàPø‡?Ðn•V(Zxõ€;{›ýã?‚ôS|$†Ð ÃÈmÙn®SÝŒ2ºQåI=³]:yÚCãp¶×²ïD—Á\õ¦Â+q *#ïä:žÓ†½zׯ9Ù$J¨ß~ õÛ˜qO×Uå;àÊêŒé]§ßL,˜Í„)\\x´I†HÍ€øcEP4ò媅¼~u†q5 ý¸Úq>êÖƒF©TÿU ÕRõS”ØÞ¥ÂülX;‰õqν¦á0l„³æ1XžÛªçȬY”Òc³o€2·©:CüßÒ‡ÉL-AØ©*4êž"%:­x‚ü,¨TtzÈ£Zê ¹ê‰á£ñøh¢X£GÇM!dî9²Žù`ÍÔ7a‚¼3£‰ƾ?‡à£;4@|o±èez{$ÍÀ§WÆÇ‡ô×ÏñÑûì—µ.@öO–(ßx%UÕæÇ=. ¼2 ѯ:àÝCÿIJÁ‰xÒ‡'b64ÔOBŒ—ìT¾h¬¦ìðí<6‚(X”€©¼éó7\ʯ:Ämƒ%á F@IE?P 4qá=&ÇÀÿgÁL¹P¼­£8œ›ïJËú»†3ßø<¾2·/¾_Âýf²‡3-g³âŒ“|·FXÈ€œ¨ dù\…êï0É´9:½Tr¨Ç(ô*ég0¢á™bŠuŠ z„ì$¤Ô3e? ú¥¨Ãâ’‰N4rLû@ÑZ«is[‡49'p:ÖþéÁÞ_îgã~8îX@å8º6dûÓy|]%ŸC,šW¨×a’YÒ þÀ¤+€k§‚ŽZiе³7Ý`¬¼"OˆR‘ñÊÉ·‘Æú‘Û¸Ýj\@-u9Á8ˆLÌÈ-]:™M‘Q˜M ‡t,˜ŽÊ+YåK<ÙX„GYcO.Ë2LQÆ ÿ°l}L“v‹,e,8–N;ÍÀE!P ãáPXÈ 3.ÈÀ•÷Pš"h،ʒ%ZŽF¤ùÙ."èÌ«S&ß5_á"ˆƒÒ*1<»JÂ!XftºU!_ ûÃ@1…2‚±@nèáý5$Õ ¿÷â65)cx»Ÿ“ÀÕ"$Lœ­t¬dJå÷­‡(,ÊØ¨¯;4¸Ô7OuxèÕŽ¶JæÿÇÃTµ¿KÔÿ8ê÷ôúOG‡Ûüÿ›šÿÿ‹Â¡0aIiñ‰HGK“Ñþ†R†T-׬›0?þÎ[d~œg}¤ùÛ_XÏәܻèÚ¢º8zú0àiËŸñ—¹}ÁJMIN„¾üÎðÁÏ9í_f àO’ö?_¿ø„S2ü—ᛖšËu³¦Á,˜.§îÄŸ“-·Gz凇rå^·ËqD¥¿o’LÒ ³"Ó“Ћ;Ö›åÔ_£Žõ]pþ½? ¦Þ„—?ÊË—ÏU1ŠêVÿ>  r(ýû½7ºtœŸ1ØÇ[ÄŽóËœŒMöÍF)¥µžÆšl¸áù Un0m5µÉ‰)îš2³3\Œ]¤O7Áê…ôbpè»´"D^*â\—ÀC)²–ÔG(#ÕdÞ˜4º˜×¥?ËÏqت3t¤¬™Èb9"zƒàö¹Ã“]³dì5(!†(C‰ž’”0ÎJ€2NO‹I‰_Äü‡—¾øªO´ÌÌ$˜V™zÄy“ô¼àª›‘ë~%LÖÏŠË‹©°‘ÅÆ¥5•ñ;\°éwƒ¼K¡Ã¿ hŠôo”LC\û¥Îð̹ó %™Éè’A:¸™/R6Rö 5†“a¨” ‚8‰¡é9 nÖ¼ÅùRKF]LΊ—ðh„,…H”þHΔnÅÞ%Ädã]tL¨½:l?ÏKÛCÄæèÿâv+Ú÷&7\¸3Â5úÿááãTý¿§½­þ¿±õÿ&“·‹7„ÞžýEÜ‚¢Pê‘3ò§ÖíŠr’¹í7{,&‘b‰½ŸšþZDúÈqä×ìj<î7ÿšãà†ÐȼÍ<. O¯3ôAýu®ðüppyœ-–¸¦ÃÅ¡Žª „ ¥{ïXóżGаm.PÁjd×À¸Ü¿‘ÆÄ¥3å @É n,˜U€i📹ðpÞĵĔÃS±±åäŒm ltå¹ 3'M,µ²ŽÁ„6 >BF~ܳ<¡XaqÒP"ý©KÎ)çd\ü–Ϙ(+ÞLzÒ–}iêM9wÒ hbêòÓê‰F… V“Z¦X"€>屄ðVô ûmõs&Œù`äÔ³,„"æçñ)e§­ò„Všà%"Ma›vj»ß¥Ry…è÷*%pTK[õšô?~ñ½ýïèðéÓôþ÷d«ÿm°þ^} ¡©Ü š46aöÊðiªŠTzf%¥ceÝRz»gábêÅ–ޱ‰|Ê÷á…ëq“oN±¸qIííü‘T‡ÑNa¬~θ¤+WŒaµ@Xa²®ÈOJ}¦WÀr¦4·<†“QˆpâNìÈÕ…Ý'&ß6>zi\7AÞhlÕ49d]t×UÜIT˜•–¬?6»©>ò|ø0çÌ.mj MÓÞÕYÜÕ#ôÓ¦Ç./;+Œ/9Eþ¢\h¡\Ïv22Jyn(¡Rž0K€¢Ÿº´¯kå„IÑ„äÙ €¹ƒ™TØgµÐóÚ”R÷ã:óKÀØ(~Kžmþ$˜.†>¢ðÚð *±ÙªÌT kZ+uÉ ­#ºÃ%V f׆.ÏÉ¡@kN •ËH¢Ð3é²~Œ†j'<$83cT8/„!‹ÀPáP Q9B=ÿ$P]<8Ÿ4ò@È8mT‚ Ä‰#Wdehý Àмl¯kù~ ;e^E#'šu̺¬h+3¹z§›&fոƑwªAçjç¡â•ø`¹;[qø“®zÞjbÆk`ü&˜»:™ïyµ¯BæŒó\ÉD“àäÍçøB»‰2^]±xϤç0á1÷Ál¾Œ5_Ó³%ÖQ†ðP‹N!UÖ@»AJeß( ·SFÿÇ¥5:78ŠÒ©¡ÆÕE“½‘âÏž?=Ò ™ªýîZÖßgÖî:zþûl·)¬Í‚IYD‘¦MšN´l¾Ã¬7\zaP;ŠìÂÄBFRóB*µ”øTTÓ1•Ma¼çÍ.º“ì:»Ï- °ÝÛŒR&ðÐóü¢¹àL§–2]`c¹ó)å¬ð"¬Kk¼ (˪J€;7‘Í’Ä@U~–HæY%#x?{K5Í -Šjë–×0Éá  á°¸C-_zà3‰úLñšÍÝÁ›µ„É3ÅéZ@£òÜ8 ŒÎ²X¼`ëÚÇ1+;›Q÷$[3(4Ïv,0À5…kªÑ~õnxï4cÞªåUl8Eß‹*41Õõ þ Vl]ÓѺ8±ØÄSÏó¹Q^Ô’a•Èÿ»D›%ã@Ãð¬F¨¢üŸOžhùŸŽö·ùŸ66ÿSü0ÄÛÏ!¨ÆÜkHja›t›´N"Ð;O‰¹1AÙ/ý눼›Gd¸HÍÕ†Ébyv:_;™°xº±s¾«´¯Ÿ÷4?þGoO®­&Ð$/ŠÍ”Û|&Óbýoú‹‘¿J-¨|ýï1QTkú_ÿÉÑÓ­þwŽ…cÂ뎵ŒÏö¾Ú©£¾DÑtAVׯ—B%JR{¶Ía›ìKSåÊba±´¢Úø©”¢¿DR}׌êKL¯ä…Œh…X½6¬ôš†Ê*¥]s|¤z_ÉÒÀ;ƒzÚ+¹"zMZu'áÈ#SzN^ÏÌGPèŒ<´ ðΛ@BTßrÃ:ô@á ªÔ³gX¦KDQ†ðYËîv÷ÿy±÷òM÷z:!GM×ýáõO¯\·­v²ð¡›ße€jc6ÔõŽ®§¥Êw*ɲJñf”É$gh°†Lt;˜ÅÖU¸¸Œ2j$*ßv˜™àèЫ{°.ã&ñßþ¯ÿãÿû¿ÿËÿŸÿëû¯ÿÓÿóþÿýû_ÿßÿåÏŠ;§Å¦ y ˆAtG„ÉÐ]2zÓ+dz£n1ôódVd£K_0jtšÇ{ß½ßÒÉD'†B½êgA8œg‡ÂRÒ"£¢[Žœ"<_äòIô±ðЈLY©{{Wd#Í×O6€É8Ïv!\u/ZÊ‚EQ•F˜±îkÀ< ²ŸE…ÕbóØDY³”M"‰ONµ}ƒÓ±˜<ïXdâÓáØÃja¤É'-DpcYω¼¹VÔéŸT&‚œI$}E]˜Rߤ?òSHz3%ùþÞÎÌM¡.[Ç,Å÷©ã ºÔÄ’4'…aª@2éÒ&Ø4º‚ÌsRثʥeøô„Ð5³<·Æ(&.á[—äÁ¢ß:ܽ¬eŸ9 ¢È‚ÜEgNo<˜­ž/½¼Ë®›t9–s¾Jþ~’-&Œ{‰º­'Ãî éAB~Ñ®Pñ.£”è5í»@Å+¯Ê;@)ÚY-¬ÞØ®JÃqÄiH«?2J HéAc•’øÈ*¤'ýJ•“½å÷W­žÕ·¼¶×EÒq”MR(_ýñ ½&ºêÊr´…ÓùÄÿh…ˆðȤ š2‹dZVA”s>ÇŽ£œˆ³õ@èG×9tÅš ~-n/ûëÔ5ô´ú§sC¸Å±ûâ~ø»pXÿþ» |*ÖŠOTEÐÙ†­ëºGÚi•ó[0‹mSšäSè)Ay,ß Yûx7÷žEˆ\ jžâý"%øþ,É ?‘]Së^,®d%r‘æ™–ÌŠúIœèø×( ¼ ™€„¯„„?©´d¬DóU,|ËûàoXK…ÙæícuŽÚ’å$¨6ûµŽ*£s<²žË*MÄ,6ê…%ó­¢woàŸ-Iû¸õ¬/¾`~Åvß.Á§ðµ‡:á_!àT1ƒ®Å×-ʽãT@³ovƒ]§×Ùýu×ÙíïÞÚ›Ù)‚¶ÛÛÀ ìµÞ½* P”0avm¼I«|ÃâéBxI8Æ”Èo´RÙÂy7¾Xøìoˆètðám MYaôÀPz‰ÎbBæÃõóà)@Vm‰ hˆµŠàUdÂÃ’°® #÷O—ä>ô +̉ Àƒ/ô± Üe±0¬¬)Ÿ®’ÔÊÈæU=~ìÅâ|9õgñ+ø­øDˆ›ÂÌBæp¡¢Þ{Õ9åƒ 5K”¯üÝòcj}s%ƒ+$ƒŒ²n©]Út%@&W¶ ÜuÉZnÙ2Dߨϒ[ŠžA7ˆ\ïÅ|ûÂÚàäïkåJý…S]Ñý ‘…Ÿ¢OVÔ½ôÉ/ð±VšŽÞhF¸Øe|w…'(×êGÜZ»!U¿s8èì’Áv›Ýk"Q®Âðl÷v­k†H ÎS´/ÜvðÉ¡xr¤‚ý¥7º$p¯u?– Ð.Æó‘¶?XëÂÆ=ý8°D|ç…÷A„w²ô+ePÞK¡üHz2؈Y÷T‘xœ‘—X‡ †ÒÂ0‘$[a¸†[a¸†Sò#!) ¼Vt.â ¢!®®ÊÝ6&“/¯WT)‘‚Z4Hsôm'dÔ¥–»nè»Sç#ëì¶›<ãÜîVBhQHΗ-™@úbê¶K­õ»%´ÏýKœÁÝCn|º[B íÕÇùý‰$ êÍ•A»ðÉÌŽ­©wINç>éÝJ]oî6u,zcYU+aøUDUyM©à8ßôd$I{os*2QLÑ•hâÓˆ]I3§:"W“̉«´]±˜‹À¼*¢`Ⱥ¬±_%áÃI԰؆ØÍdýmÅDkôÞ»“™!¸ë3D±ÇìD½N„h©šrtævRœ…I{ ¶k–ãîŽÓ”õûà3Ø!ÎÃp¼Ö|O‰é4\XóE0 â€ìY£pÉ´ ïÏŠY ’¶DtÊrÕù!ë?L¾Ó¯¸K}?2š Ò’MýjœŒª}Ñ‘cD7ƒºÉZÚ¦”p³õéSÆ»aλQλ±:Ûv7˜a²‚²¹ X™PL–oa¬Sf@òâ‚àzHßvå]¯;¾~—³kra üþªIä0IäšããìGÏÀÚÀvŽng§»dÔÝŽµ‹£ï¾Îóþ"‡¿¡cõ×!”Ä@2Eïk=ÀYþ:¤H+âQ¡g%¢,¥r)ÓÞãôø¸YÜ0¼³€ÎZ°A–x“^Lß ø/Þó–bi££w¡™ú¹2é´Ý·ï{æ”<¦©›àƒÇ•}1|Yƒé|;Àn6¸â«pý ébÄnz@•«p÷öëÒ¡w•-Ê$j›j›jÓ2@ýò>É>:D¬ÃÑPvÓ‰C0dHgéi~£4V1¤y©+ˆŒР”qŒ§G¶Y‰Œ(³þ"V²Ÿ(©˜‡Ë`2NG¥Jw0õkyôð|ÐF×üB³„L™7k¤FÎXø#Ÿœ·[ΪÝõbwFq«OÞÂ4ºÁÜÝpœ3IèõhrNàBìöN’Ioÿ<¸?Åù¿yýÖú Àóó÷{Gýž–ÿûð ¿Íÿ½±õ_¾§¡¥ûf©¸¥–" 7{¥—JÓýâÝkë™tÉ!uA„mÜ‹-ç×(œI±£¹HÁØøy‡wLvzöÓnœF‘nTi:á=ð-‚?‚ßZôLIÈáÓ^ŒÊYMý¦ŸõM?ob†To78—ž:™›b_}ܯ4I9uá½Ì]›|:esq×d ²±‡Si{_@ÞãÓ.¼T,~ÉwDrSßJŸå~¶œÓIqn,ÚK_'³£É¬gáÌÍh“zU?’Ô®l5U W»åØeX1pˆ]ÂS&;Õ õwä´TÞuÍõ€zfψ‹)9Ø»ø>*‹¬H¿Éh‚Öf—i·1½Òë̘¡Ó‘Vþ^7‹0Œó¼6%·S¢±—A•’¶!Ìö¥?õ¥3#o®‰È ×Ìmm0a”&ã‚Jr¥5N~ƒ>LåêšÖèSº¿³ïá7ñãȺ—ÖÄçQÖ“º»ñJ˜Á, ƾRlQ­z`dËŽ`D;Š—ggtÁW*v]tŽ¿Ñ‡°nÁ6ªJ[(30 ø™(é†(\á4ˆåRElE—üZäÓIV¹:µ4ß*¢c³ä†IhHbàæöþ%Ñõ§óøŸ—$eÄH– Y;V-î̈ãÏ$yy[`lG¸j’'¼š¹nbÊ“)˜Íü…«™¹$ ¦aâ%HtjœP#:M›€‰Gïv3på5[´˜0²§å¿Ä®hBrrÜœñ&MàJa”ub«ìj+ƒ5²l ¼T€¤&ÔÉ'º•:50’ßÞVe¹’¿Sþf}áŠý¿üÞ(ž\»áÌwó:n`ùþ_G½'O4ÿ¯££ÞÿÏÞ×5Ç$‰í3DÝHO«ÕÝ$¥»örw4ÎŽ.f$…Ä߯¯Ý]$±> ›‡â›Ão?ûÍ÷xqçGØŽ¸ð¯ñžíáÊúª U@ 4›ÚfÄŒH P•™•™••••ÙÛÆmjü× åˆ7!zs®¥ß¹y°ø£TÓh±7L¦Ñ\Lyù~/§´X¬¹‰êd òž_ˆaÕøO½Ÿðóßü[ã¹5ƒFan:¤Ó<NÄ5?ú!Âÿ9—~j¡‘ïS9o8ò3z‡›à¤ ƒÆŽCbä;!´…ËJ…y¸[íF(YÄþοù™ž³9~Œ¤üþ¦ ‰[²{H€ ÿ=C‡>ÁæÝ´K…ýNÂTвöiÜvi\yJ•nÊâI®!]cµ>L"²]Ñå+ÿÏWI¢YÁG(C “Lë^¡ø=Ú#ßryáÌ …'û}ÄötÒSJO+NÙ®E³ÂJÒ ³qÐJ]0݃f´B1Š|@7pSð 9^â$$p')" ´qã_ó»}Ò§_ ‰B¸oùˆ뼄MÑÁKÉÍ,½zW½¾,bKƒÓ™D‘³ Yê}#8Ù“nOC­=³Æ™z[#û¡ÛÿWËÅo©0[Ë¿¬¾(±ÿ±Ñ¯ÚÿG½þÁÖþßTûÿGÂ'œ!6e P`æSÆf8ãâkÔ‚©o¤²¹Ï{rÒž¶fÿÖì_“Ùß(ómÍÿ?aó¿YV²0k5 `k·®jÿÑiš¢ú€KîÿöžõŸ«÷ý£­ý·©öß[ÆŠá§Ÿ–„žæN3I“#M³8S5$–G?eŒ›Š¾•ÀŒ1äÑ2ž"H;…ÌN‚ªPR58Žû/õ°-'m] cSÚ[sMCNå ¨TN=±šÙÞ}µ #åÙEdä30é —DV¼Ü°TCª£^’-'rzÃM©»{çî—`B¢Ìx°^1ÝÚ@Šq(sÓ©•F™8±Õkå$š|>yWóu±Á×–´RÖ© ¥éUÊëY9Ñ,C»ýóöÍûS+•_Í]sô‘x“?“¸§{Ö{ò—#,k;ªHÑ;BG·øã…tÛÞµF˜B’‹Ê=£,’¡}9Áüƒ™ŒÉ+a2nˆFÎ1Ó\¯Þõ*»Ív¡³ë=›¤ ™KØÒŸ~èúá|I7~„Ÿ½|óúôäõéøô÷oOÈS׃iüfÈZýpòú·§ß³¯» /—µqSÈžšå”8z¶¹TÀl¸;¬°b'¬a>! ’mKE²HîÊ—L¶RfÂIVA£d*+š¼žÕ_ÃÖ¸v1ø¢€Ÿj×^¶l—«f± °8¬°¢müJ–æhêaã­HÊæ+IHDüº‹Q!Ë»Oiî¼'¹1õRP ÍÓr€8UlA2/’d‚·xgå‡éñbŽOT ÔbvÚɘwB}Jx)ÈsËŽ4xÛvdM _)‡¦Ê[àP¸y-P)Ùb¥ÉB†Xçx£ØœbÎæŸŽÀ¸Õ ãKš™b0¢R­Å®Î~MÚ‡±:H)øïS”,^Fñ|C*K—’1ëJ Ì—¹„:Pvf¬$bÊ^ô¤·ùͱª)"²â{MŸÙq¾‘r ’öù ˆ(É<8ËH6Ê¿L 6*äJ†ýˆ\êH;NõƒàFÈÚ*‚M‚ÜqÒΘÀUA¢’t1޲/lfσÎ\šµa%qófW~h#o¤¡YÞ’å¼Hní%ÜBÊË$Ý6kU±Â#:pØ++­@ÛZ+‡±Òwƒ"ÄnÝ9‚‘Y¤ÇÝ)iýB¿:Ĥ9¹) j„} *‹@r–‰‘¬ƒé[äè È\öÚ¨Í5M+)ÊŒv)É**Îà …켑LQw*Sܳ¡ ¼üa9Ñk%Èf ¬çí– ¾¶XÛ1Z&â‚—•)ÉuOÒ¢p*¤é‚m$y’+´®¸š ¢«xýàØòBD IL$FHXAСåE‡d¬’59=ËoKs§fV.!ñk5H´%ê$é»Ë€•½7ú¦c¡ÙÚwËy±JA©¹C®¾óÌÈ¢“5ó¡LT«À¦£dÀê¡Xý4 m@€Qyü=5X!ýIüO¿øüH‰ÿ<ïmã66þçáˆÊéÿ•ÏšÊþÏ£M ¨ Y³à ])ØâäáÚˆ‘3ïÉÏ#‹ cA©\€ˆt_Õ²4ót ˜T‚F„mê…ã’A¡˜Â`AÊeª\ÿ×e²3ÖÂ*Ž’§"Ö&ü¦â0‰¶¢O¥ÁK¨P 9аi箩 |Iªpf­—cT7¸F(™ÀÕRwñg²ÅÍsG±Ð©DTŒÎ—D퇲y4}o!û¨Y +Ì8à}›ºÅšÌŠhfÒ¤£ªç×e˜m6V$OúÂϪÇ3Ò€nZÈӎªç¦bjNê‘ùzÍEãF 424~ƒ”ðw¸OóâM€ôí2«w09&S¡tiÛL’ÔæùF C‚½Ð% å׎¯dŸ˜qUİÉáUËBÔ+ŽLDˆ×LoW§òkeU(3ýUB³OJ¿8Ú,ê±·n)lߢ }Ú)[ûTÐï\¹ˆfiSÀå¬`Ïšþu³®’%]´*d±\Ù/VܱUsmjwR“jLX¹MEH·Ø”£“_[îŸâÅb‚Äõceë²då(§¾¡›—Þ4ˆ¡²›NËu€ÓÝíÚW:¬ÀRF"‘öroÌŠü ¹Zîÿ¥e;Úóÿ<<ëçü¿ýÁÖÿ»©þߟGØû©{—~õc4C\s}{òÝ‹ßýp:þéÅ¿;yïcKø.­ $ü9ÿ¨r]R°õ+HÀt.å#¡"!8Õ¾fµm>ÆãŠEÐÏ¿âMñX·X °» ý¿3§2ôf³1ùbüßfPþƒN~3÷NóH˜°G¨p•6®‚ ýdþ³o5rú#DµÉp‘1¤È¬vê@«Óùô‚¬téKÑQOsý¦÷Œy ޲ŽJýöjc' $0U-¶<´PË+ç#µlóØÉWn-𳇋2]‚7-Ööæi¥\+Ï+cê{9VñÇÖÍôA³,%Nà'P¹ kÇs?“6˜@©¼lúÙüß±¾úñé’c .ñwÉc:å„Í¡€–3œês/&ÞôʘÖ)h,aœ—ý*µÖ-­^T©~ÉË>xÊŽN×y>­Œ€V9ÞÍ hurmQ[hA™†ñz±±™‡òBf &kÂv÷MÈ ÓøÂ΄>q3 œAB¦Q´aVc€wÑ0ªâ¡Ý½ è.8p BlNG" ý^Çé÷Gbô^9FÓÅÓ|Þ·–0¡gý ŸQ+Ñ*em¡•/VcYÌ^–¸_~ÜóœÉ~õ:õÄ)Ń™4¹õ³Âå»P i›§i^´¶y§ŠÉU ð–V)6 svÐq;ÎѨk–d 6l—Ôïv:)jg£BlHÚH*» ³ð× èÑl¯M=Öy¥ˆŸòW¤Y…ò6^S/{Ÿ÷4a¬Zºè²Oêá z=[‡ó­n(µäŒtnoiån/L˜VÃUtiUAö° ²¼N âXl× è]Éó.<8áu¢}HK:£©€ºý¨Ë\eÂ,J‘ó9ºqõ¥a•Ãõ±Êa£¬BoM89Ål…ÿaŸ2íÂ÷É%Z¦Y!4úU´Ôí¯“¼&oÉC£¬Ámó° ÌIÊ g^<³\)[¢tÎatŸ46»¿ è[ÙŒ ô(2*¬M˜ "ugYÅI£ß+Ì\åyãP_z×Hž=ªYL‚”`¦¡ 4£hÁp’k?Çð)1ðëá^k*¨Á"”{)ä°>N/ý`f@²x»[ò)-}}` Œì]‹( Ì¢”Æ%!.74$ Í–áiƒ4Çðrÿ̸ñÌS#Köó Ö³Y5n ©¸¯X™.囈–Yå°±…C¿yУ¹ák‰ÌºÃ"HšŠ{×+N^•ËÙR†(ïú¯+)ñ*$ÙËþ$@oÈzA,YOÊ(Çó¾ëS¾ïèJS(n+•B‚?w¡LË/_9îX¹ñ˜/‰áhJb˜è×±7›Ä²üßåH¶S¢H¤f֊`É¡¬›DI–»ãæj-Ù9Œ ¸× ¢USp§$#pš.v*r„bBKålŽª"Ó Ç„Ljm¹£_T=oFÕs>øáŒWV$®}ÈãÂ*ò¼í¥‚ûí))Áè/ô§çÓ~¯=<û½2ËÕMŸh™ÿ%¼”ƒ>ŽÝY¿7j?è݈¡•È3üa¯K(µ0s,.é=:bíHd‘´6¢Ll;8»!‡®Ò1Oîzç¨M îd”’,¥EYªðœCRÄÙ{4]Æè¶V¢«îrI²ø«1¹6…Ç[1i—Ô¢=ÅC*±fŒÐDÍ¥Ä8V„†ðjŒ¦È¿F{Cm¿ †WŒË8ÜsÏ£ÈÝïBª¦üf= ¡Ð€IÌ>Ƥ³›Ð»ò§¤ ™*äMiŠ!”h OH¸¦†6 [oÇžB7½Œ¢$³FKF^Ñ=Ë{ï…DÁêÙsoˆgn¿1&eõ@(í¾ "o‘1i¯Ûëv±ˆ–FAäŽPÙÑ,?C% z¬Nü{;¼£'zˆäÄsÑ=|î0¡‰³¹Ç;LüYV¹¦8ç…¢¤ìpâum©e#ØxÔø²˜ñ¤=:‰`óÝgç9hüƒž«¿µŠŸ2b·GÇ,Ä8F b¹Ù‹– ‚¯õܹ^K®þ,ž7½ ¥ j6üEˆjæöœÔߢs{EŠZ⯙ìZs]™‰%ú†Ó$Rk‘Eôhã*€¤hªÌê'Æx%Ñ×µDnë'åe®r>ûÜ6SðÊ[L/áJ®S†“|µŽ#(eÅÍØÔY)íÅ)§¦†âÄkpúuÏ/„ ½œžHªÑ\˜[óœ‘ß2»ýÜíõÚå’~o܃ÿz½51ŠÓƒÀ%´è© Íýd˜3 V fUO– ¦c¢“&‘SfÐêÔ¬f¼:Ô›6›9œd!¥é„Ù#u3SŠm¿·‰Gâ_r æ ¿ÿÿóå“—¯»7WAí1Šïÿ÷zÏ”ûÿý£~o{ÿ?dv‡X¾ ©À¤&C©PóÐy丿¼õ‹ØÇkJî~yË¢°îør—½¦®r}ñÿó¿ý¿ÿõïÙ3ö•І:­±jø×ÿò/ü—ÿô¿ÿÇü×ú‡ÿó÷ÿœ]Vã5Èq›ÿû_ÿûÿþÿøþ³+ÜŦù.óßo廞ü¯’í£¢ü÷Ždùï?nó?ohþ¹Øû­Á[{·SVÆ=ÂUj¦6ª&‡¼ZANƒ˜ÕO˜–o¿˜K HÅÆáòjwqŒŒeÇ«Eñ'CÀ!‰ñ¹z'q.#=‡*9Ðò°-¦g䃉yŸ÷­€;<ª™ªÐ,•túDŒ»`G†®—±1/Kì>l–¸w:»ÞlFœghx±©b–-m¡>ɘ4ÑR’AÍûŠñ^Y˜ÂÞƒ@;Hö9*gB·#c^áœraoü6\ø‹¹X‹€ (4ZAuœFAﳬ1R™—cR³±§kcQúj’%ˆZr«\-%¡°Àšz"ê” W•ÅÁÇ@ÉK¸Ë5£òÒLBžùdÆ+¼.G±¹ë8ì·ÉÈ ¬ò (ö Ù…³¯È‰ƒ Ž4)b×+ëêÄØceXfsËDÊõ¸“è|³±šTÄj²1X™’‡ç å%½H¯dÁ-ÐïQ¶ôí µ‰ö±^KaÐë4Û2÷Õ­ƒÎN®ñÂ!gVêKžWºm5XšyUË9µa]aÈÅRx%VÌâ2†mÞœa! ”ñén>J=wE­êej[4„Цk5ôZ#Å›¨aR¨wÜ—WDÌÞòä0æ†N)Ow÷å›×§'¯Oǧ¿{â:ǿƔ›ÏJ–¿§Ðhå¹ü«÷o^}¤›V‘i âý¨2eCkÇÕ5¦ÒR츳)•gˆÙ˜LƶÒXI¦¶iӻмHŒ.ž¥a(Ó¤5¦¥ŽE!>'§}Û7À´°Ö•Jy–;*M¢*.r<:ô~…AŸüd†%@¥£KeãÂe±X1USM”“#ý^¤ ÌÆ&Þ˜ÏJK¤MU‰ ‡€LKÑñ»ä®°¶SÔU1áÛV"­hXíJ¹FR€Šm”•móù†Ýü¹ÕÎÙ°‰—wö^Äd¬økß&¢>ç¦ay_B–ÿpDÓ ¸nH…ËÔŠxÇg‘H±72sô?¨«‡Àn±þæaçWÖ/¾Œbî%•^ >ÆSÁvNÂd“+01¢JÈ ÷ŠXLÐâ#Âü‘’†"È‘HaÖ-«Œ˜qH¹bòÞj•ƒÓ1~ÔÔ‚‡™ÌT9½*Õ1Ì]qáåÊKe“;ê4l³ȤÎÐ'ç¬7"i\²)(^B€P¬à·^LL0ÈE*p¬º¡& ¯AŸ‘ƒÃ’ie45ËA… ‚ùÃXªpŠ (±zt•0ÛD¶2úŸm¨ÉgžC{‰š‚£/ØTMÁ/ìÄõ¡Ù5éRq œg “'òü@,¦uíK‡)‡†}Qƒµ­,5ômäße¥>®°›Í6y0Ÿ~šJg­ÚL‚¿üNx‘»|ጋÉ]G·ŠvóîM³é¥û«ymÁ%_·ì#ûS³øÖÝÑ±ê¶Æ–kZr)ü 3²Èж<ð¯?½dw]¥œ\Ž ÅÞé¼1Wò».‰Š®%ìY˜t9a³¶å¾!ö1×p`lX¦'æQÜMGs5SŠ©ƒRV$iÕ!̸J®>@©ÜI“TS¿˜YHNz© I‚ZÅúŠ» 5]Ó7ßz Èéu„›K=iíWµéWÚŠÇßx ’fŸU&wN¨Ô<Úƒëc(Þaì¾/}B YÄ  ;ïH¿ !¯êÈùÕ±îÝ"©]Á”.s\6‡‹ï×$Gx÷|¤Ë Ôý‘Per× \ç R#N7Ðc8=ÇÊ3:žDw¹»(rÍI=· YWp IžžŽ“ýN“BÚYÝ€š’’ÏTg,2·³;K#Æ÷ oÿ¸Åš¡p¿ñ°"œú­`eÉ+È2%7tWP46GHï4ƒèÁ9±PQcŽõJv•eXû)|KR X"’u"W`o|¨ÚL[ç=÷ü@Íñfç€ÂÙ¯ ç¡ §Å|híݦæC°7z>Jàla>ô+©,¬ã|ÿš¬ºi"e'bZ¨°ÌH¯X7xlé[cj?še< ¼ðÃf1®¼©›4Jœ±—;{whšN8k‹kŠùûÒ gØ ÑGZ #ás@‹v AÔˆî F§ãpjãe\ÊîäÀfñ_E—yˆ“ø,ø‹ÈÁ4{òM4ç…$ô„ E‰è‡éwmn·44·ðª‹5 J3+ÒØ¿2Q榠ù3;¯ßœž ©q”vŽàu"0XYþõ?À?‰åãÝÖG~"ô‘\FKÌXÞt±$ÉfA?‘.‡)zg –ѱ+…­{·E7A:z”PñÄÄ<·NÆ(×lÌŒ§’çCh¨(‹9yZó Àï)€ÓD0MÆæƒìÆ‚€½95¦Ü–Âë§aOËÅ‚Ù<ñΖVJd6l&1d¥3¹’ÚÑl›ŠµvrÆN±×2À+b[t­§|´†™Ñ»²t±¼qG÷Ç>MÆ qmÿüXœ ã9‹¾TÈ[\ N‘g]”‚ÿÙÝÝ;éNÀõ›ª2 n†2VG s¬ªÐ"©·-°>O©g¡KaÈúŽ ©X,6DAªU´/ây3hk:ª¶›Ì_wa¦m“$Q®ÊyM’h:²Øâ¥Ð³ÈBrò“ÅHêOä@[Pí±œû H/ôÞƒå¶MµÌ-;ýÁË . f»ú¸€™mý —‰l\ÿè¡T#[ x¦‡Ä„Ê^wÿ«°Q*0Öl‘T­Êät"oøÉÉ2Žæ^Çù­Þ\¡j“­È˜eià €M§+¶U&[ÜŒã^E2»½Äf³Ÿ,¢fYN‚†2yKÿˆâé2¾Pmˆ½éúhÍÛ°:u²šb¨Þ/[UŠd˜BvÀI'Àj•O+v¦@Ö Êã¬ÂÕÔt? ÷<°«z·45L6Æ-­²ÅÖAݦƒzEj«ŽËê¾ÊÔÅY– ìdáwÕCÝŠÿÌžÖõÙÉ~Œ tE•¤Îlòâr• ­Õ‚2Óïj©¢Á"®ì”«M# ÓN}ÒÔë¨@¸Ž4ƒ"¶õã8'fÚ}É//ük–cÚÈõ‘öH ‰¥ËbVimå¢Uôn%ÄñãµÞM`wiWëïSÖæ:¡ÂŒoÂ…vl›v­½átÌ6ܘE¦˜ëPr¯ QÖË^–!šïq_ª%LëÿÜiÇØË’ÏÔêÉ.R’t¬HIñ¡R[Ô—¦Dì ægÌ›ð‘Pd‚UsÄ™:%›Fcê!kqa(Âw¿Ý ¸š#TôØÞÛõJX"rìW|'´ BN1Þ9iÁkÒ˼£v óÍ·3„æ$.(±ÚdZ’¢ãäôJj$³­<¯:NJ‹Ûw2ØfÚ6FúÕ2Xøó@ ž§ÛÈbNn¢À'þ£waá Z|ŒÆ¦KºøSù¢.qŽ$êe¾\;Hã·$©ä®÷ÞS • ‹O+~Õ}n{“ON³Àné½$MtWôè=úþºÚí¼wó næ9ÇÇŽë_9w§õ[x.; >r«\¯nä ¥³U¼µŽzÁRâʼ–¥úÌô.í¸ÃHû§wÒvL‡aß,#·:šâ{f¸¨µ´J’†ê È™vc9׌£940GU«£zMwÁî°ùc‰…åª+«³ £ÂÑæëV»É.›¿é ±ƒ3“çÜ„õ½Î‰ ßeŠN`Lî]‡ºN£8†ü´¹Šêr*§ ±‘Ú ,ÖloY)ÈÔhhGA P©9fRr‚¼õ)H0¶éde¯Ð}©žŠ€¯G‹MÚ~õy2ŘP^ÛTd·eª, ª¿L¦dîM‘zÿV'œeâYG@UÍÆHAãÀºùñȨYßSùU®‹ÛýÐŽc3(ï7´/mÖ ­>± Ë¡¸2UÂH4 ò;¦vIc7º-}Ê´ cxzXM<\}¦Ìš ‹hm&ö,ZN´Ä6 õ®ýóر#% °L´‰ò,+º÷ž%«¬xumFQ1TýŠíÍKû JŠB»(GöLôÃ& è+aÉQrðÙðô áèƒSaV™ƒê40H– ü“øØÞ@pÏ”_ ’¨YŒlò¨#d-îð§°³ðâ–å$šÈ‹áXqÒ[Õp†œ&&L3P.]!W­,=j§Ty“9Y‘î+8¬ ¬Kîj¢…ãÐà:üwذ~Ã:¾§_àIüš"w6¬×’Ô‹ýR!½Mg …e3LŠ a:ˆ;-ºb \£[TjöÈ5ž˜Ü³QÈ6œwñˆˆÖu9ʽlý«¾Â:%9•œÇäÿ¹³ 5 ‹ÝLW.]L+&•Ë‹åâUôsõ 3c[öVåS&~ùwá‡tÅRZXʸ×®4Ÿ×#s…ôíû†Ãï)8T[Ò?TÀ/…sGçØù‘tÙ…'*„Ÿ@Ú’îC;OS TËuŠÍ§NƒåŒšA˲#jl­þ\ y°ÑÍòû«L=Ã¥®Å””± <ß xKUHß&™[„·BEy ¥¶(—µ¯ 8“ç1Þ)VòÃãö"fFf­u¾ïœ1r¤˜ŽJ¡§ú0=¥×ž•Pêpl·ŽÈÇŒcG¶6gšÃÚÅ_±Q<ÃZt9ŸÙúòÙÈŠ¤izss5‰‚¬ÀÙÐK¦£J¦bù"ÖëÙ=“^FŃŒ'7¦qÒþxÃòÁ Qe‹ zå-œ!ܪÆVŒLC‡’‡Ãô¢6ùp#ØÂŒ½ÅHùˆ´ÞÛŒðmÎL¼U)NÁâe é¬ttR»Am¢h Øjd)(ôF$¿]ÃðÖ1L‹@î¬Jܾ¡èű?˲jP>%»cÝ<þ†üÿäemÈÂ`mb‹;-C79ο· †Ám%ÙRéJî¶°ªe3Ê/´¼Q¸¥7›v‡»\… mìÞ¹Õò°š*Hûs’A_ªµVr1NÞ^¯Ù½è,5¾eäœ{îǘ„y:r÷å…æU%)*Ùº•>é’±|g"$#¼ØˆcøIOËCÏXÕo¥¶rþ«Ùh"oz©·0ù¢e ƒQP`ºNP­úÑÍÆù–þT}‹‘ÆK©S<ÆÛ6Ò{‡öÓa_ˆþ¡ ÜÐL ݤtÎ…g|”„Ñ5';®ðZãN±Í ›n^~[ÎñS@ÈÝÅo†£þœœc%ϰ„dÇcB&$‚¦ýC l±“¥JæÓ©9‰2µÍe‚ ÏÆD!΃òÛØŠæ *Ùsùuëžÿ2Þ,¤ùf%*m~6ËÙÕ’å EŸð¢•ø×•U¬,Åue³£˜”p/œUm'ez»è”½Pw—hï2ýí8œ´ã”´åZcžŸÛ$NBÈ¥|6 vqOó€èã4ë”{yœˆVL4PXꔵêb§þz—ª3»íáLŽw ø¶ˆg-ùÕr«mÁtv § Um„™šßzX0’mU‹K¼£EŸ`¬±¨áËR\Ë®â‰Áñ¸É&ëàRž-Õ­D £0 &¤[0>0Wãɹå§ÑbzYØÄû»¥wí/4mt˜Ñ;ég«£—_2ò(J2¥éØ`=¨„ö Ã{Ðâwõ„xÖLݱ¿èÜÁ¡<%_ö†‘?€‹l¢É½SFmñuîaÚ‰Ðl´Ë´4í‡K ·ÒWƒ K§*“Ù˜:¶¥¿DUîÔ×z%¯LÛÙhºB©ª°Ê”U©¢²SR•ÏUîÛpÚ<=r/š­Ö°×¶6d†pòyì/×7¤ >ëÐèü*Ö%,'ê ÛÆl¥¼Ð—YèÕm”«o;V“&m¢@­L…Tu$+ÍA¨ "$ Z+•íƒÈ[‡‡Ê%[6a*’;T5ê¹Å*Æ­¦ã‡‰?CtþõÊŠó‘ Iÿœø¬ñ«T¼ÊµW:çvœxAWÆ·Óh.â v#ýtô_ذ+ÆÜÖoî>ešA¯ä$ÞòÚ¿£°m_Yc…ô‡•Óè“7]°….:×9¥W:îK6í¼á;¶;ï»ÛóM0¿Ž)’NÊR-Ô2¥\Âyމ]“•SÞ’,G¿¡•Ô**$°;X¼G‡©Å”Y.?%´)§Œq¿ÙÔk½£1¯û9T­&fö" Ê—Ó)B³Ô¯~è¬dÕsçˆVÌÔÀQ]ô7ø¨óXYë%’¥UkÛ"W¢+<Ñý4£klÎ\3ú¤H‹~Ð4/W*0 õYaùÀ´ÌW!Ë­¶²\,Õ¼”€Ò˜~Rh¿•µ!¢¡o¤3 ÆJ±óNA7Íù9…á6(¬pØ#=±tŠz²ß¶Ë#Ž I!V0ŸPÖª–å”_äÒ²HL'ñœHûÍÒíœZ¢ãYÀ#Ó†+¹Ï6WëWÀ_v·‹Â¦®ÂsyíX·=z˜ŠË‰!4xáþ'ã&ðc‚ðØ6.Xî9|ŠÒLñèå|›Ð`mx°äÆïäm¨j¹$•‘Ç‚8º™W1»ÿÝ|%~ÖìjÓ{!„8õ÷ô*eîaSoÇUøÃÒµ2k·.›F挾鸇-z^ªÚq•eCO†5oÕËfÝ Íb°Ã³€ãï ïíÖܼÖñ{ó"¬[Úœ+Cwç÷¬©Öþ|S{ÃûÔÊѳ2XJb•÷ùEײ]¼6îm•¨7‹b⥱LV[É‚ ¨&Š©þ±ù¶¶â>ÒVÁÕµ)€‚¾ËÃÙªW”ß1©sAÅmç}Sæ½nÍÔ‚™®²¸êµ‹¸m(âJ\‘.»ç^@1x(˜÷Áayiü x°DúŒ=¨ÑÉXIh"4Îg‚ÚrÌZ8æ<ŠÒâvòÕ‚$ûþÿýbû“ÿOèSš¨ïé5Š!°[c–]&鯓ÕÇèõ{½g‡‡¿èÑåß~¿wtð‹þAïàðùÁáÑn7èõŽ~áôÖA€%¤Ã àEíÊÞ«È=”ù§9ù|ኙ›1S䘱<ð/Þ¾rX‹TC¨‰ÞŸÒsÖw݇PRoG< ðŽªŒ†¤|¦{v¢Ç·,0¼‹Âë3×›û¼cwt·»#Š>{ŽQ£:ˆV—ï(Û¶Ž›‚»ØI]V¿ò’ìòÎýOÜV—X¬ÀÏ}0Tì^¡øíQ؇øýÕI‹ko ¨Êm8<ü*Wt9OªA)©ðü#J¢+ñÌ}çÍü©¸òÔb&²>hߺð¦r&7÷4ZÀ¶kÚçªtçðUä_i œÃÞay÷ƒÚÝãš¶wF€Õ`·è|°aʸ.+cJ!H X®_Äx¾{…!ö“…»†0µ]~{?hfÎäcî™~ŽHA>Wäæ4ÙB¾BüÑ<ò…Ý¡ô9Ôgð˜&WœKXfyqW©#àÈâK(d©S|Ö&}_E_åXG]T²S½f×è•ôYªÓôc;é Çu¾²¥ÀO¯2 ÿ¸SH¡æk}ãÁö­€ê¯(Ff-‡Ý éo)ÿ}Uþ¶þßM¶ÿ_akú·'ïÆ/xñþýøõ‹O°*èñíw‰F_ñ#ô3’×xÊa¤©ù™®ˆù>·Ûÿ5ËvÈØ¨(‘ÿƒÃ^nÿß;ÜÚÿkùyìü”ûïÔSw¬9½r…írŸÖçÚ, î´Ÿgo—pM}!2Cø¶›ë5„Óú€vLR‘}ôÔ”JƶÐfÇ€Ë ³¾§÷G4}In™Ã²“)¼ƒédßR,À‰à¸âsަØ÷8ÚÏ {W+Œ£íôy3éY#½zÓ)š/ÒØ‚¦Ap&„óÁÉ”ó"¾ ¥žOà„Šì¤v—á‡0ú:Ù½ïR<¼”ÜÀueV3ÇqÁfSTu€TÂÙf޹½¾ £'ѼdÎÍ-s4¾•ƒ¿?=};~ñòåÉÛS²E “ŠÓcRB³Õ¾Ù··ÛíòþöŠ÷Ëõú¹^þð—ïûÕE yÃ02l6B+”%€‰Œ`' õpOæá_OŽÇŽIF²Çœ§; i’¬JÜ6µÌ3WÇ¿]á^›Ã)ÑtOÜ: ²v˜õ*,¦pë™.æ ÇhSœ3‚°“k€á^Î3&V‹ÙWW窡•5¤Æ8/6º×ž¦þ÷{{¹Tªk&±€aÉ^ˆç( ™-"W\z¬º%£ZŽ»ÈR•Åe’Ž{†É¡{àL"ÅM],+m$ãñ¦¸üSÄ¢grape-1.0.2/pkg/grape-1.0.1.gem0000644000004100000410000140400013231337007015642 0ustar www-datawww-datametadata.gz0000444000000000000000000000446413154552776013465 0ustar00wheelwheel00000000000000‹þÕ²Yí[Qã¶~ׯPó’'[ÞKÒ4ds·¸.p· ö.}HQ”DËŒ)Q%©Ýõíoï”eY&%j“vÀ{‡=‹ó 9¤†Ã™Ï¼ÅbÿI4é>áé¯$Së·¤\¯?Ô$£šaEyU¸$븸&ÑÚÖ¥¿YQÇèj¹Z^E5ÃjÃE¹ŽµN„µåB®£Eüžf[LXü#´Øj äŸ 0^”Ò*§bÿQF„B€¥ÐéßÿåXâÕêêëÅê›Åê/ñjµ6—«ÃOüK”“šT9©2JÌhç&¿9 ö`µ¦ÀÙZ3JR)×\ïbŸÀa(ݲ€?Ÿ}÷ígæA?Ž-˜ýé-ÛË4«} ­ES)Zh¨„,¡yƒ™$ÇÅF'&¼Ék\6RQâªZX¯ú½Öû?ß=ÓøÕ‹­÷o2y†O/p–‘Z½´k¾úüåØÚàÀeÆ™¢D6uÍÅe¡ÿ‡ ý@…jäËGéÕ/JψiCYNÄÅ‘ŸapNd&h­LÃu|ÊñFÀ²>r±‹!‚˜\Ó<¾þé6ÎÉa¼Ö£ÇTm!Ó"Xů  zˈ”˜2Ô6cúžVJМàeÆËˆ<‘¬Q8eçèôˆ<)RicºG‘Èy†6ô€±Ÿ Ç뺘JXBxxý×ë»·7ï~|»,sýøãÝÇûÛ~þx{×¶¼ÁUA„V†X‡ÓOKÆ!{‚Ç‹¼½»}}s÷á>Ýß\¿ycû¹¿ywsý¡ëöïH‹ÿù§·÷×o:I >¹-±Ø%’–5 !RG+Ò ‡´“ Œé¢ÅÖ.™” Sý*yµ,:«Ò§’¹„úôDW˯–¯¼R’Ä-¤L¢/ü¢/ý¢¯ü¢áp:‡ÒÏÒöî¹® øÌhšØg³ÝcîçhJ¶„ÕàÈCQÆù²èas.™«#ÝœaÆRX§øö†0õ…  ÷«}Kpî0ÏŠœ–k…Í$x£ˆKÎxQ<æTRÒÙ8Iñ¹ÁCŒÙMõ4eI¢·Ýò¤sU==·!G1­ Ö°ü7V§9÷Õ%³€È¦ÄÈ:UÞ¿zçØ’H‰ ‚Ržïà‡£+Ø–VˆvÖ*&F¶kSÇ„CT‡¯uÁ½·!kÃLË}ÉN$Çó/Ñ´31p@MA$$¤ŠŽŒÂƒÜƒ{løxÂ0ãÒ#rȤ¯­ð½Ú¦`<…4z!dD#ò.¨‡`’öø?:œš3 &Þ…"%M™Sl3q8–³m ª:ê"TÖ8;{­fánuî¯V䨮qÛ3l;~bÚÔî¬Y'˜ÂÝš€÷šÂG.]Iæ:Zhm<­òHi,L"².´/»ÓŽ!Æ—˜öp0ý| é«Iç•Ûú­K'‚TÎvZm!ä™Òµ ï$ÎÞ˜ëí€`£CIʈG®lÐtj”@ ™²çÛh¹cÐßÉñ{¢£[IDÁ;\^Õ‡›í,‘Ìøy’ÑÇ9_å 1ÑiÉ=Ï©xé¨ÓÇ” ±0‰r½ús”)ô5_0Ï„ ç28xÆ#™I’Âu YÙWuÆÅ¾b—7¢ ¤Z\ìƒÀà Œ!Pª ¦†kðG”2\íB5d(P!MÏ)Ö ¾ Ôrã¨}àœl0¼û@4y‚ugûy¦ÛdÚ<:?¶ûrÆôËF5˜!•5’Ž;OÍžiÁë“<Õ`ÏÔí1o›ë]a›«åÕ7Ë+M[A³f®z,T'zà °] °:¹g:?„uÈ¡ˆjK9¿B{–´¥ŒÆ ýÂßër•cyḲŒÓˆä!fØ)ÁËžÕ{\ò¼û:Lâj+þI£ÉxQézJgQc8C®çóŒwiµeâ_1fz;[,ÖÖ-8!0G ýsÝÓd¦_ÚÖdc€‘) éM?Ê’œ~ù11÷cz/ËÒž#HK~ú Ô˜Œ:Ô'UTí=² É4²ååF&5œ c°VWlk ÙÀIÅ3ö-X#p€³Œ?æ>SgŒÕ ´cyŒ§£ö+PKú xd˜&ñA£Û/-&Q_›DNlñsVigªÒIÔ{4C¶‚ué9x_Zá‚»‘–úñÉ|ý»( 7òpØ9…>†#m³é°´Q™õn NbZ ²…¡0A)ÙbúÀ›>›16õø4Ì]PÏÕ;”ÕóôNkæYº¶ž¥ÒųtNK㙪½y–æ°Ö¥|¨xg)Ùºw–Ê3æõi»x}×~éâF»ëŸ¾Ç;-†ýš†>•†im©t¥:@ÁKÖ·jd¿ÚjªßÚ~g(Í>y,5‡jää:Æ ¶ÏÀºÌ}ƒwÎ1mŠ¢<Ç%7ó‡Àíâpxä}Ì–—¤ÆYÇú+3¹N’r¸&Õ7­} ÌÞY¶¯*b4ƒ”ÍÞ¤zû1‚êëÃëø_ÿŽj[ÙÄ5ˆ#í…€u™›Xm^lîbµÅ®)¤MOŒ¦QWë1ÑȽûÓÛlûl'7Ù¦ï±Üb;1Aß/zQ3Úë|z½@¨VLpÓE›øjùçåÕ*’´0>½#{€Éþÿl8b¿ŒdS–Xìõm={¥ÌuiÏäãÐY|óáã‚ÑÑ7øä2R: è®Ô]ج ›ua³.lօͺ°Y6ëÂf]ج ›ua³.lօͺ°Y6ëÂfýÙ¬ÿ^˜4àAdata.tar.gz0000444000000000000000000137045713154552777013415 0ustar00wheelwheel00000000000000‹þÕ²Yì½i{Ûȵ ÜŸù+û‘ÔMR\µpn'‘mÙ­\o$w'ãëA"a€’éNÏoŸ³Õ”Yê%É}ÛOÒ’P…©íìËÉ|žùQîÇùW¿Ú¿V»Õ:èõ¾jñ¿ÕŸmhüªÝm÷{ý~çððúw»í¯¼ÖW¿Á¿E^ø€r7 Ãøž~_j_Ü¿É?Ÿ÷?ôvàGœ7º;^Ö¾iŒýñ4ÄÆÿøÖk7;;ž÷Ø{%žŸ{Iø©ðL'ï6Ìò(M¼Ýv³»çeá,½ sï|1Z¶›Ç^¾˜ÏÓ¬¨…IP«­ÂÓ«„§×l7vªßèW¾Ño¶š­Š7Æv³àÛ/oðn¨þJLBû? cxgÓÅh ½öéiåGWß—oZïoöéáêë³E\DWó4±ß·žÖa…ÿ¾ˆ²pPz\=ΧY¼> >\ŸÒ _ýþï¿Í¿§ß¼~qúòÍ‹æ,ø§àÿöaÿ Ý_Åÿ탃ßñÿoñïñãÇ€½[Ͷ·{¼´ßýØ«Õããç¡_,²0¯Õ¾öÞ?nô;v§E1ÏûûŒ§šãt¶ŸoL2îóç‹8ÞÇî{ï$¼(@šE“(ñc/ü4çƒ"¥–0ËÒìê:Íf~Q„Ù¦Þ ïýŸƒq>©öšæAß Ìƒ>€ùÊ¿ ½iÏPyþ-àn‡P³|1Ç~ž½Bæðüˆ¿€æy–Ž‘»–>¤É|Œ¯ýQ˜UCÉmr(´¼ÝÃýî}˜ ìtŽ¡;Lå–ÏÇð;?ŸFá`ð ~ÍÑν;ÉžŒ‹è6¼`žp0ÀÞ?@ÃYD××a&ÅÉxæ9™ðrÞ™UÏÛh«¸‘ã›êÃEMz›:n7¡£°ÜqÕoÈÐÚ8ó™šÇ€ àT=IÓ8„,–óлŽÂ8 @ŠÈÏâê­ä¦j‚Ñ;r;sˆ…Ÿ…@J3Xª$½ƒ+(T ò•Ƚ¤Dx™ šÈ½(÷ò°À#±äVLÓɤq“¹%n»‹û"ŠaÏB gYP原l»]Ìv_¨j^ûpvèÑvÜlh¢>¬†ï!‚ä{›¤ÜàI͢Ѣ1IÇ àNßÐÖáœ|CH T¡µÀIÐ͕ܞÈú·aLÜXeGÝjЙí!™}âqáåS8‡ÖRG€"}Øýؘâ.„É D óaðýÄ¿‰’Õ`q›"«À^7;Þno¿Ý¹—°öÖºó]‡§€Ç€ˆ2çuÿ)ýǎئàt¯¡»"ÈwhºtXI"¸ûċμñ4ß䮇´è¶H‡L$Q¬nâDžÊ)UX&1XÉéÂ÷Ü@;BО,&åO;4MñË3”Jr8êRiyëgxû „$àͱ]J5/œcû1žFq¼“}ý¶™Õ:âï¶ÜV¿¥Ä+Q‚3†)DÈz³tV¼Ø.ób{¬•¾ÉFyµr Œnhª­Ñ€T^XÚ[b¬Q¢Eã<mÐI0ñAD¬> Ò¦ë¸QYb+ÎCæ—µ¦lì“t „MéQPjgfú@·€ÿ,Rö„¦|_áaΙ‡yÜ;v⸀K8žâ.¥ôñF§ùé/_&…ÿéa@»øM¬$Þ9¢«k?/ĤeßËÔ2aou ׉LïøÈ 8Ͱ1Àô%>Ùx„o£Ó鬇빩[z‡š¨cˆ!ÌèþÌ¢ ˆÃ;ıL÷‰eL“å,b­Œð=iÌ 9Šâ¬PNóê½ÆsûÜVòH¯d˜°.(4Yµ Pï:ŠÙz9%ñ8Œnmâ,*cgbç²Ç]·³ÑU3§a6Æ£‰HìÏFO¬}®T Ö!vÁ, =²1¹s|zîºß%ð_™ýGÙ(”ć÷PŸ!Åõ½ 9Ý:8td¢^pªaÐÍj±»n¨ªK¨J1è•ÞGÍÇ(4[zó(Ê/pÊ»N4º#2 B†Ì0ÏŸºº —CTÊ iéƒSå“ßë“Á,Ïì&­V{aƒY¼#·Å;ÒÒÄ0C¥dxEÞêu¥½ƒÈ€M /”6…!\ÃÑ.h#ª˜ÅXi¥ãÀþòoc á MýÛ=.àÿ éfKdú@èU޳Ù8ýj‰AÚôuSôHQpú©@£q mkäI€N7|K—‡:1Xn§žepB[ü¢QB!3 €Û«O(6T“··å9&:ö‘,ë°ÍäYäÉf¢v}§Ëêmâ&½n¾c½e°Ýa¤³#OH"1¹‹ÐvŒ„ÚÈöú‚ ´•Ð*pòQ½šó5Íæ4¹qäSpâI†ÉíQQ„Fý2”q]WH-¶®}í²Ÿùy‹9š«pÉ?‡‰ÆÜBŒHúã©6þ»É®‹ÙmÙK¶.æ©õ#YöŠó]<ÉnüĪi¤jÔP¹éz-uàl‘ÚFCd”È(‘Ž]É&St7ÏoªÝŒ•y‰ØT´ PCò²p¯×vº+ßO¥jPá¶J•}¸˜Ü¨Nâj¾ž›ÛLO»Í¬^ÓºRØàýÑùÊXÆäˆ¾f :NÖE莔’”åó4ŽÄõ)Äp¯ÀŽ˜óä*°º¹*öÈUñišŒÙŸ*$³{Ù”H‡k¼È¨1Mø’ÎãÅMxL«]餑„–í§•G¥:@Û¯ÄñwÝ|#ºäÁ+DíÊ]0Øæ¼\eîí7ÖÍÕ K®çl\nùÈ)šB¡‘ò$·V? HàÝe) >7ýH‡ô#Ú€y Ù`p&rDÃÕÓ¸5×ÓqóïõU¼—ò`};ÞIÒb…¾^«UV~¹âÆèrU­û¶{h8ÝàHð{~@&\?Å%Â쀨ÕÕDR7hÊ̪¯«nµ¤ƒžøÐ¶Èß«¿I>h»qˆmäBß"³­ Š!йI™Œ”õBâ¦Ò; ǯ–f¸Í,¯Ú>>Xg¼ÅBw…†¯¡íª3],“)ðgÉØ¯Ž·;ˆZná†?YRà‘ˆ˜ŠB³­²™$©r_T,£4à;Q,ã0 ÒéLõjY4€nî9mrϱ8?+•À %¾bJ!T!#gRßæq5¦À †›sS›œ› 5Ο?=8ê‰% $˜ P¨ÈN‚‡vB òÅ—l0¹íÜaËð÷ š‡¬&I3JƒŸ‡[ŒP›b„ž¦ |'âXê ™ºÌ⎠HׯÖ8ÅQ¡{ ~£¨Â—u«|œç@©ÇH q­Br¿(;IÙÑØV·^eæU× *&Y^48~ˆHÖJ›áz®Ý4×mÒ\?]¥¹zI˜ -}àp+XÖ9ܶ[N‘¶ä "bæÌcŒ$|Í·Ÿ™òŸƒ‰ún˜¨/ÑU–*µ’èžQ¤6…MYjÒ‡×w£-}áÑH È:šI™1^M6>¤×JD`[ÏÎ Ê[6W^[Šsøû"ßÌýj-™j4°»Ý‚¾°BŠ/Y,Xð•pq¸®ò„2\)u¯ã.`aXsîéo‘ÝéRJ¢§Ún¦ù¶6̓À ãÐ¦Š†.Ko@* F1±Vˆ«!m®Î­£8îÜ ´ÜHe Iå«p–FŸCïû(ÃP“±‚tÙè\²¥{Í^3?F>ŽqX˜gw0 ¹a»V[yÆ¢B‹%ÍàŸc‡˜y³÷éDm­1å©„&IaØ9Lj\ ¼"[„ŒCºÓNKžV/¬ÝÁ̉%j‘霒<Šˆxa>&‰N<ÔNedž’ÖŸ˜LIÑ1)6à$n²˜ó.2çGðýûxó–›MŒç²0¹&dúeYÖVωA€î Jn»c>»x9¼ÕìI0Å"+!±pK{¢t oètq‹àöuÛ†mÚ ·“üñ5¼z¥ôWCñ/žùIN“0+6ø›V7~¹uhö¯IˆÂ¾H²˜"óEøÁ­ŸHÂÑÇÕ“O§‹ä& ÐϰVŸ7xÿI›Ï-ä¦ut`À»/ùJ-C · T[çZÛ¦ZP1é­·v¿!‹w)ykÆbœQi´46 œÂÒ²Iµ'17é•í:"§#í¾,æ å»1d­ãPr>‰7*[¢d RKQVö9\s×EÕÊSÍæÂDûF~²Ãhƒ¨Zî†çæã}7Ó7vUfÌ´fþ\Ô·„vÖžÁ2­(ìƒYTdÕì7Ývü¦Þ$1%Æð†g¼;:F>¬K†çÆb`å¼!öà4fþçÎßM´A³zhXÝŒ\-2rÁ*Á 'Ú—Et7Þø$}ª°èA‚§(õ`¶£å¦Ãh‘CbJèÆë6?áÝTé‰ÍÀ¬Ì$v¡Éý±Ê(Øp‹m¹©¦ZÇk—"Q̸‹^Lq )¸{ Ñð¸…ãmM4ruûÕÜ‚nÎ6áÇû7€x²Ø”0!ÒMÁM¦Ã¼°¨>‡‹Ž¬ïñ¶¶8:ã8x…T¹w^–5âÔDŸûÅoöÝò“H¨ €s¼I!➢'où)ÜBë÷¡·@NùnUº[$ºÊ*…¸®äþ`)@ï¦~áç‹$YäÎR½J.z´cJqÁ „AÁ€3rÔ i€”‹@ #¿+0zN PN¶œ$êÜÛ¤7uop.’~ŽüàJ\’ê^XŒ›œÎ7ðARË¢ áhºUÏ¥ã4—ÎÚ\(#Š ¹˜´qPIʸeÏé!:AÊʸ•<¬Üë¼äÔ$‡³b±ñM;‚a8âD…—ûñõçé† 5Õ¨ uÊyuL\Ø%r1bé³B ä6IÐ6éx!ÑÜ8+²¬}¼M“ ó«=4u«FànÎr­ŽÅÒŠ…ŸŽ@Ý&.Š ú¤Da×Gm7¶| ·u%-ñ·ÇN*¾ããžVXi³Q)‡¤å¶BÎg[¡$'Ò|¬‚ÃÀd«Ô¢lõm''»ã®QØ­BaªÅÐ$øÓ«#f7æþÚ›¹¿¶áþŽô^ÇŠ5Éáó=0Õ‡eHT8"“‘|<êÏá(Oφ"“)îFªªM¬ÍK‘6kÝß, 79nÒÃMéÓRJIïFL²¯|yÑò "_h»+>•ßQ>)r“³nÔ†L-H7Á@~IRŠŠ8’Å '1»Ù/•Z4nYRZm³û•!Ub¢W‰†Ù¡ð.íÄP_/?«–,¥Í`¸®£äÖ1zâEh Є 9`T¬ùÊD—(´F§QåÄwÌÂlPcž(G§ßà™­CZnÙv0÷™^càЃ̈́aæ$$G×Kô_ÍËŠùÙ¢XpÅ„x‘£·†%,o«œWÌy™óÎ~§«˜sBNÎ=Çsb‡E ²ómSæÏ‡‹õ )ßÁŠ“âYR-²:x08Qäs0P=‡ÛáX'G)èmˆ¢úÐ>þ²ÿÈs÷å0ÙΦ¤Šó±`G‡.X z›Õ«¸ìO§>δôOnp~ 8h?¦[œ­3’ÊÝ┤ë¢r½^»yÐl)_`rJÏ»}ìgJõ W­Ý9úÏ'Œ–Q1¾­ÆÔ¤—íÀiÙ”³/^àõ¨];ñ¸¿ZŠ€•ŸÁçe²Aí‰M®c'¸Ž‡ÈÞUQrZÜ`’zqJ¹…t†)twd°‡ël Ý‘[rKè¿vÜŒò5‰Ðï{ʼn—ý–‡çÈe%Ú“=v¢×ÇÆFcÜ@šDÖA‡R±ƒ]¼µ™¦´NœƒÌz“€1}Ü,òé &¯ŽMV­zÅÎ)é—_P‚< –{à “‹šb»¦Xji}¡;˜Æ‰É— ˜j ï·7˜¥UãH'ž¨¾NEAÊÚÙý‡Þ5«kŒß«–k|\ñ„C®9;1sÇ-'tÞ:0)ÒXj%g$BIÚ£˜Â,ˆÔLu$JÝ´v×i»Æ´È ‰ú@iá\ÂÜ3d’ä_@ „÷(˱øF‘•Ýí·Z{’£>{…ªž—ºenà;i ˆoBï‹ï./ß^謪“p–7ÓŒcÏß4Î*‡„çóCµ°0Ô˜T“=á~ŽœãCoJšxä¤H€Þò–¯p`!oA~¨ᤫðò¹,O‰xŸKš,W¦”%ø˜#Ù¹4ñF@“](Ìg›¶OÚFt²^is¿ä$6Áû†ž“Öb5:é„(»¦­‘B1s?È6h{¥­t(${ëqéP8ek…Þ¼½ $ô6<*а«4»JÒ$¼J¯‡ë"Ä“/†­‹eº!Å®i–ÀÆ"Üà†ŽM²¥‡NúÜCÒçšF, ÄË+-¢à) ?ùè=q%3‚'~qw^¨GHEîÒìF…ÃùÉÒ»‰ðL_³Æc€*b"—À+!?¢INY<~jeƸ˜¾õon7˜U£š´SŒ×¡•á¹,$TmU‘ª?B ½àœ¹€Æ~nð cß Æ¾]¶ ™}ƒEŠ`µ²<—_éÖ`-# •ÏZøYø7þ(ó§\uëÏPq0Š?[Ö)¡ØÝ÷S싆r°¡{pNºéCÒM?ͲxÔ(“À(d«µhB˜›´RRùÜQ¾±9mQ©‡¾wÇN÷îX£RñÏT>{–QSS±8çá”(óðØ€SÒÇ´êok]ßUsÜFw~~ª®a@M 6§\;‡GÕÑz¡‚íïHïÐï€x^h½ÒE’„/wèÐ分$A3«É‰åê9ÒvÛ]ÒRl¯;rr¯;"ï:u·%Aúí6¬±ÜCáí]ì¤Ô Åì.ÓÅNÊy!y ÍZ¢ãÜ ›“f]Y2øÙ€êœÁVíãâYRª@Á!¨<ã.MªƒFÝ(È´×êí=@Z ‡äÂÀŽè¶¼,b—šµ';y‰(ð‡íêšÒÁ‘‹¬½µ}…úŠéóŠËŒ[ÉE3޲¸TW&W Ÿºgʺ`ù\¢:F³E3ÖG2tÄ©ø9:gr Î9Ø›#š"Ù/rb™-v~6¨]©E!§œUÝÃJXÖ6§2¥.Bõ 㸪yynRp9±Ç–×] ®ªÓ´åœÆ˜þ`ägɆ,¾v“Ñ䀌&ç‹„Ø ‚Ìõ°RÉ¥Ýl×ñ÷(‰9þM'°ÓìÔ¹þõúòë¹`Ž®SÚ è­#¯4n`–¢YJŽ ë ;´T‰ ób1©ìÃ38‹Ñ¤:4YÚ4»éB£ ·k1ú¤Òý$ušÄúiåY/á¹Ë)yíü=Ÿ^§ÕJ/i«DqNž&äiÂTLëáØ–«J÷)ëå»VÒ/' ÃzÊ¢—/»!:y!ô@î·µ7…í®’%"š 6cTXzÊÙ¨½I±©z2$@—ò4} o£êE§}ÓzN7­§ShÚ¶)©×.™ÿ@ÀP5³†ìüly\¸¬go[O[‘'z–¯íz5\­£%1ö³lÉ>ÂäÚ‡e‰A n"†§u@œÖS‰‡âDýîÑZ˜²%xY,/ÊÖ̈Svî~Ϙû‰¯$sœÉÍ­¢‚¬›‘©‚Lèö嫬nB^èÞdênÏÍ9IoäKú–òzÚ:ךä:6#W¶OFÂPV<™‰•)½öÄ—2Ì6x-Q‹¦‘Nlô‘JåÎE—GiŠDNgÐÈýë.=Óx2á´ÈÃj¨5N ª v^ꯪ[T… f˜‰Ó|dn# ‹ë½Ð¸í4”tß+Ò4Λ،1$ûÓbïW¿²çi­£Ëìœt^í–>ã¬dWÒFÑã¡E?y,ŽBÙ싃ÎÂ嵜i6êDªÖnIäC·Z¡Ø;t¢¶‡Õyz8¶L9c(€åò}›Mxü ùrVFž¡ª–„üCáÉÎÉ :ôçËz¶Þ¡›NïÐhüª\PNU_¹sö^/?èÍò¨:‹jÔÀ>ÃxótŽ‚‚¬Ëªç‹Q ÌðJ¬á4=ùIÓï>ÈdËÏaæjc?@Íûñ~û`ãM±<©ˆß‚YIånJµ›GÍC'¢ÝsÌr×£L§‰H€ÀFÈó…Óv‡ãBª¾v§@0EK}ñk:¦M{bÌ'i¹s®'H¢šÊ‡å{”ŸùáŽ]ÇôÝ#Ëø;öó1&qÔ\IÀHË8 Éž”!•8Þ¿6žò;*S¸ßp+±¾©ÃËÜü¬:N~V’銕ÍÕ á3ÇÒvè^?žTÛ* ƒé¢š«•6¢S‚—î¡•°Ç®çWW^ ùbâ3óMyJu€S°ªU-ýö^a]'ýv÷ØPÄ’n„ib–²œ–F·i¤Õ¸W5*¬ë¤ûêmp‹·*m±wMNxßø^q`r2)~>9:G”†¦Yƒyè†[T¶ÕÖµäÀÔJœš)w\ÎèK/2²Dûoß]z€ã})“« ÌŒD¼p¹LžV€þTWŠ,)R“Dñ©¤B]ì;1Ö° #ñlw‹ÖèO÷ðÈéJ)çÙ}í$‡Y”,[¬x'YE H¡0&<BR­OP­±:]Ÿ£–ö¾Öôê1ª”®0œëŠ0¿D—è÷uEÅêAE8[<W8 Ž4Þ”óAw0¥º=·3Ûíiq­ƒD'PbÎT*¥}DN94»Ê¯oÀ •àf¤OäLù°´¤UÆFÅ,ÅH© yº¥Q]ó¶#/×Ö)ì-'šs•¹é’²„)gÆbA¿ ºîš™u¤ù]Gš¯óå¼Â$)pÌ€LŠzyÉYOΦ*éÊ®Uz‘ù0aÂ¥¬©Šá¨è<ô“Yºád¨FZ„Ç–¾ð/I㹘³ó…Š(,9)MÂñ´ÁZíz&ŽËÝ1!.ëNY#À¶7â´®ÓÑáÝDe•ev/¢ÙCnf¾_-ñÚŒðÐCÝro¿­d¦^}'êÕWàÓŒ+¯ c5ÙB¢,´¶ˆ„Ç ï(²Ôœù3Ti †æ¶:êþz\¸¾}Xš‹S®n_§/ÿ ®x –Ë%‹e’P>J»á¤©j”°{1²â1;¯ð!úÍF~Q­ÿ–6…TݾFÝ’g„s c⇷+i䕊cd}ÃñÍxêG´QªõgQcV¹2á„f˜@ˆ‚\¿P°ŠÀ#&©[ru\–€”1Öû· Ш»Ð M&!ü,“ ø!ó¦™iÝó¢0¸ :×ZX‡á#n}Ąɰ Ã\ʳlTÏý;fyX@'É‘T•82.¸VKîÃäöýH7Mê¼ó¡‰\_å·j;+ Ñ®#/7…ܬ·lÓݲ/~‡qsïí:©$»=MiTÂÉTи¤ê™èUºO¥å±ưSþ‘E^ø·iî/6ÄØè¬Þ-‘»Ï£Yµìiš5Êp åê›+™˜ˆ£\å‘Åb˜è?¼öíãÀ¦²ˆªQÒq«¹ÑåÌjhbÐ^Õ" ª¦sgÕFß‘¥ìs 3E¹ ·Àš)YÀ6¡8LئÏÜm]'幯ê}܆’ÓÇ»CŸ¿4¶’`“‚wŠk5Ö•6ÄÅÌÃZ²êô>ß!åBŃ×Qü|‡Jù ¯ŠW+ëëið cnI U/§íM<;Mš+î6;”Úú¨L§ûŽ;ÅÔbÿ“]œœ,3}aœ\X|WópSúš\#èÚ]¿ £:’âãž®»;ˆ7xË]ËKµýZX‰Uë8†™uŽ{%ã*s@UG}ï=½Ô`_±jûÉ$¤ÜÑÌ÷íÎ{ÞDtØV/ ³“n¢{L¦‹®Sý„nÏ2Þ DS\òõѸŽeeE·x3!ܧ¤œžÒ3—.v…£ 5É‘šh׉u7è õ ÄÌÙI«Éq8^†Ùôs5ë©X-·êEÝ–Q“¡Õ†uWLeV‚;°·SÞµnËÃÿõÕKÛkœ>Èï±ìVÎßÉÓ ˜Øjwb#Û]7|Ñîó—3qW’W‘-æ)A-,šÓ,6$$‡çn̯£ž Û6!ÿRºÃÛ¸ŠƒÊðÎVÑkåɇ¹W´n®]§ØÐn96´Òþ¨ô"Rc=Î’Ž€”pÄž0^‹ÓÛM™ò¨IóBGŽ¼Ð‘ðBJGh¥è0i»0Þ“ÌqµFb˜-}õÖôØQk“åTB O㥠9½Š=‡­~p¹ÒE6ѱÇ<'é3èüTF›ˆ‰9FM%JD˜¦÷7ø Î_ŒŒ0F”¯– Ò«$-®Ø…gÉ)ÎOÇšXƒˆW÷†õU'ÎÁär$Ÿ_Këipñ¬ôC°\B(Έœ¥Œj¾ „°RjY)šÛ–…‚ KSÑVΈÿŽY‘k\r¥(&{²!Kni†Mpݳ’s Í„3+Ë«ñö)¦”gç´ÈŽãeì¨ón¯:*sPlÝÖj(‡t^?Âm¦TQš•ÍàìSNVê¹ïvu´ G§'2CVRfút¥íQ±“ž°Û7‚4ãc)Ô^y{rùô»¡î†¯¬°9œç¨ “ÿ¬E5>ºÓ<>º½ß¶øh¶}¿PÚ,B4ã©Oì2eogM¬rv()-X™Ñp“Úž~Ú@@­öa¿ÎöÉ«O³XJ&Ü.â$Ì$€·®‹R˜nèÿÑqÁ:Í>/BË,Â}%¾sÜÛÈWÞ CŠhÄ)¶]‹ÖÀ%«ŸuÑí%ÌŽ©QÔW*ß™eËële ƒ.äó êv@òW™ÛòÍCמlB<rúö)Ú¤ )Î7,ÀmÒ¥üJ¬òi:k÷h©ë›UEƒ¹PaŸSÎH¨^åÃH‹eé¬ó¨ã)ëµ­Å!À’´@ ³~8Oå}’‡tÿŒß7ê mÿðO»»»¾ÒXd1™ÃÈõ™Ø§Fªü8Cu9ZlÈgžÏÐay(ñ@\1ÁŠÙžÂ:êZý +€X€;¹\™\ME)X™ãê¬Ø*1†¬ PCÉÜt"62îe°irF|í¿€­Šp÷VnïA§G§uPÖ^:j/,c£»“GɃ Ø HÁë_ƾ#Œ}*2›—ÿDT¸(=sç’Ž  ôÝÁ„¡Ôf×MuÒE¥½W•¹Þß8Mo¢0oa ×pD˜0û­²;Z\ 2·•ŸÄ%溩ÇÚ‡*e‚©œH–àH¾»:{ýüÍ·a9xÀ9ðE2ÔR&vË“Ëm 7Z[+OÄyû”+#,Ê‹¯îÃ\2:N1²cãÇ´åȽ‘–,æ°Í÷îÒEPL§,(‡ÇÙmN¬ÒX`’”Ùx^­ØP­ë9ªgM3‰nA—ßléÅÀ-â½àsHÔÈ,ÜJÞ í©£M¤¥Bò•Únn“‹¥ íð×™8½øóHÕR#ýD„Ø(‚E®ÖQèf Ÿ“B¥Õ1\<ógpúI€Dmˆ(UTCT·e‘@´˜Dyú9«Ò­úÎvstè2ÉSLÆ ´K›lÓ°q‰“[+ò  vµµ•[*K—Át9QºEäbg´ÞÎßÈE¡×9r;zãîWŠV…ñ’I,u-Çß|È:>Î'ŸÐ0ÙNžÚÜ4’­žãÝÑÞvª˜ˆ÷©î hÍ¿ý£g| X=ɉmuÔ¼ªÀ†£^íÀQ¯¦Qx–’{•ؽŠ-§¢K?+÷y§Ùõv;½ý6%£ëãÕvÌäÞ&Õwù&ÁCdÔù+²³^¯hëS{àÈïôŒ Œ+±%bÖZ×ój>_Ìæ7QÒ>Þ°.å.NÅôÖGó%¨ýð$74©×$ÆJRÊi”N¯Ÿ±ÛòÊæˆLþ8ÛDJµê²pnË«ü»¼·Àܬã3ö §“$¢€—á¾­½óãü¦ZHà&µ˜NÉ^;”ìõ+gÛ#šd²<Ì( [¯¦T~Œü†Ö“«›^ñ†Ó‘u Æí1Ƨ20”Ÿ‰<ÿH$%ÈV—âŠhÖ¸…ÙuË‹0ÜPd|­—¦.ÎË£Þ=€® 5UànOªúN€•ê§Ù YY`ÂÞ ¤ö°\là{Ò!›‰OÑfÅéü¡bL<œxû"bmÝý侸S¼ó|´Ð /#ju xcê½%þe1¯gstntwüè ãVpl)ZT©ÖqªE ½É  Óuqó„Þü–S%¥NÇi©ÐE•%¥'ÉK¹Ê{¤ =a¼â"»®v¨PÄ=ô’ã»~àÏ&)îÚ£¶ÝAì–ZhõªRK*ÄOÉ•ZOκíÝÅx¿*ë:ÁÜ]Ee¤á&;žÊø‹ò ÒYô)JÃÒ:N¾+J ùŒSò•b r`Kg%{Ö6iž¼ŽFºrE§$ ‹(ó7”•Feÿ̽5§yºè~ŽUެm‹D³s+mí¿T Žê8ÚwzZ©PNE xx`á m2G­-ƒŸÝ¤Ÿ7ÔSÅ&½mLj2-lΩ&J°lƨ|¹ù”tÀÌ »­6ڒѱdÆÞº N©;mS¡½Tü„S–‘Û±N~‘EèÕ¨XN§CNÉý!Ê¥26ËTŸ†Ó-i›è3}PKJ$4S¼äšçc}w§S]•ޱ<åh¾'¹ØZÙY’‹1¢ÅΩüùx°}är4ÚGíuX 4Í+o«òb˜+ÿBDkNƒhÓ«:¡a’¥pJFñbC«ƒ^o'îß  õ½1º ½exWðòäl8ñ$»°7•† ŠÿI¶˜ŸqfœÐ…€Ýò ..»Èð1?šÖÌÃuœ„h.¸V ¥Œ˜)+ø·¯±Mð;Ežt(òä\ü}$+-T Rr*0îäùUªOG>ò»¯øÑk@/’Ë{¯\ ®çíbãónùž£¼«9Ï6•Þi—” Ž‚pûèÀèö$5ù‡ê˜bVusœq,âãU$Y‰Ûv´Žœ®µ¦’MC-4ë…ý9zH{;¦íŽ*1+Õpoàn§y’†³ ÉRM»®éX’Xî¶Süqû¨µæúJšr<3^$t«óÕ¤£t4ZR½Ð|SŒ¤j׺g¼ßÞDÍòáCtÉÄ1ärpïG|H=¬ t«‚ñÀé`胡¸É±ŽÝKÄüAq¦b’VN™Z©›„ÅÌß pJ›íØ 4Ôˆ]Dè) ÚÊ{ò³µöwSLNºaT£†åÀ – U¢o7´£Ò ë‡×â4󳥸‡Â|îÂhƒƒ(7*ûNëÕ?¶\×Ëa1è!GW]ÒÏRúˆ”Ì È²e¨&ÑnL9W÷źÓ¡äG)*JªÃt«†Ùi]ûÕëêsâ¬Uƒa¼¼G]'ÔÒ­b•q­œ?=JÊÀ]ÇþtƒY›4HN|„,ž²Ú`Xuí©]JΧx}â(ß”&Iw˜=Øå‚èœDþ hÇÀ=À(A‘ºÔÙà}fÅïƒð™æ¨"b¹øg“S,6”•ƪ®x9¹‰«+qÉuŽhŒxqãçŸó8º«&­Vû†ÑX8'ÿq¹mÝÀò1 —'“i´¿0Í>Cù^Òp//«ù+x¾N,v>¢Œçê)'õ,¼ŽÅ!ŠBdÎê‚°1Mµûû-ìgªÑ>Þݤ@î¢VÁ´ß· *M7!È,‚™TcGjÚ0PN¤ “ÈAÊM 2\^­žá¦ ƒI-=ÅWÊ@ ôé IZ'm¥Ï†Á9ÉÐF“5­ëxC”ñ”ÔŽY|Þ‡ÂM>­’9p«R»"…£ZÞ…ÌW³‰Á-gS!ºa×Eà+ûÁ?dl‹~p’ Vì3?%±¿½åõÌG=1ò Ç”Ú6]¼ý×Ñd‘‘JÞ:^n€—Іr^:2”QiI†â4¬Æ®¥D‡*š¢œ=Ô’RhG]—U¶»6ÑýÑ• —­dQú9ˆÇÄÊDyoU’ãÉ6Kä{è·ôô¢oÂ'ô±úfWûHIÛ}8. 2ÒT; oÇØÔ½ €Î|ÞP®ZìÝèaú#³'e‘˜ôr‘äθ6E;t‰TÝeÒÇŽ§Y”g ÇnÀ¾Vû&ì¢\‰½wç/גΡ&-Š§ÕŒ¯nÝDâí´îzÌ|NÑǸ1i´×¯ëí*?üöNÈN/ÛÏÆuíÅíî󥿰2•7§ðä6å(o˽lñ½”=ÎM-P ¶TSÜaÍ8¬«Ñâ>ÙâOvÍ'Ï8¬7_Œ€p`Àdèç.Óùê·ÿ÷ôÍëËó³'ï.Ï^¿h΂_å°>­ƒ^ï«ÿ[ýypØêÕî¶û½~¿sxxý»ýÃï¼Öo±˜#Pî¦À«ÜÓïKí«“û7ù‡¢éu…^‘v½ömÕ¿ZM§/'×0À¨ï§€A³0 ô:VC¥Y¾”‡ÿæûö‹{}¹Cu Æ)°6 æ‹Ñ,*¼÷(«jñt{ñ6G6AŠfN±ù»DÀ*ä9—§È]¤S•bô+ébTÔ=?¿a»i®w$9ïyÙ^¤éhÌ ômÔ&ÈÓ1oN¨M˜zxb}Ò1qÍq¼·YŠ”¿VÓOpfÄMÂG_Ü[Íc€5ühh]ÂzÃ.ΗðÉápXƒW½qŒ•"«ÈŸÙ4­ µ1V¦À„ï¢c^A!¶L²ÈBæm „ßçy?å7¾w™Î«>ÉP«Õ^!‡r9ƒ}k's1o`ü ½“S/ôòˆ^&²ÃoñIÀà™Ñb‚ÅTì©ãÂàºÌÐæ•Ñ3:~z2VƒîÜy³eCnð­ÙBÖR<±VÓõ'î9w”ž…ùÃA8¥cÛñ^ŠVTk™F~‘§·x‘° :<"ÃÒAà&vEÄUÅp;õ-Dff¦aдo-ÃpõP ©œÆÉäzòœ…½<ûg¶&³VSÒçCœ2T&éÈz…0ÏOOž½:ý°Ë?-ÑHðÝœ®öSª÷ ’g­vBÙbôeÁmúÝÉë§/ß¼ø°«Å„Õÿú5–a=gÎìë¦Gó„ë§é `ú¥¥¨pT[õN{‡ÞD´ŒÐJ¦_zÊhSÌ¡JAû4!Õbps{YgÜ€8š¯ Î0(P&Ч|`!#¹½Fc§#X34¹6é­GÃ^ï6÷äaYHûÏá'wOÐ#¾À?ˆÆ¨:™è°Æ”-B3 ³Ú”»‰º¡ kû….ÇŒº›ÚäiA³Ù@q w¼]äSÓu¾ÀÜ@v/F}Åòü[¼¼’„8•”ô![-’3É–ï&¨é=18žËû;ps‹Bœð®Ñ‡ïvCa©Éðhd‚bÍ"_HŒîmÞÉÍÆHføäøK}wÎCÔ‚Ö $^;·!W¹VÕÈšÇk, ™»i‡ ïI‡©}&RÖ\‡ ¼év¡ÔôâÊ;_Þ¯qm턺œêÞy'Hjj5yNW{ãýä’UÓ2ö’ÅlÀÙ+–óˆKC+÷•¬®×)ŠüŠZ‘ÙÃ)—k»ÃI׊h¼ 0` hxíE`NKµÀ´Š¢•8™¡±›N’.š#÷E"ºÆ!/*•mcÌ`sÜ·Ñðq ×-xÊÌ\âRX»T¡F¡¬ÒB³Öâ,JØpO7ƒêu:DP¸2#ú‡„êw™òÎOÏšÞ)â΂‚¯N28½uÆ©w2àªä«¤Ô4K¦V*לém¨®Æ“#"*ët†¡£ˆ´ã¥f2u1ì° ¼'{éTª·ùŸc}-`â"r.âúÃÈ“Œz•¦Þ,ÅŠÞè9 @Ãj 2 «$…I4I7½ï|)™„Elÿ Ð^,7¸µÚ[VÀˆ7¤…D8îÐ@J8ÁâBÄ©w!Œ-pdD ·$T¸ÞR[]^þYzƒg¸Xà¯ðד1¿ ÿCcwUþïvZ¿Ëÿ¿Å¿€ö¿Éäý*ЧawÎÞŽAš nÛÙ«}õû¿ÿ>ÿ^„³_÷òùþ·;½Ã•ûß9èö¿ÿ¿Å¿ÇìyMD“˾³ÍÜ$‘kâ¿÷¿”,é5|L·‰}óý¯›òk­&iv»„(d‚$2Í&;µþŠ*ƒW0¦PcÝŠ HkeòÜa±3ÛQ£èiþ`8vêÞN«Ù;l¶tË”R¯îÔªøŽõÉÂÏ‚Ò_ á[}&ßRO—ökz‘ôàÆÓ™ŸÝ4¢ynƒ±ŸÍâ Ùʜ턦8·ÿûG,-©Q7 kEÆ7 ÁtmvM+M…[ºÖ±‡ÈG?+ƒp¸žâÞ5àÇûüX û}Ø;±B%0mø¨5Å2@»ˆN«º÷Q³}¸Þ×êwDýëâÿ&Ú‚ÿ9ø¿Ýiw:köŸþÁïøÿ·ø‡¹eàB²ª~à5áwÄù~ñX—ïíÂ-n¶÷è‰'ÙÆEs,ÏH÷fòK‡3?I2Ün£¥Æ@´âíþñ[Nùn?mp‘yrËµŠ¹'½_{qúÊ‚·ŠÈì—çP‚×Ûí£Û€ú"ÈïãVP)Ã/ uO>ØQ)=Õ.!©CõlF*dÀÝø¼o¨ø%שŒ%OE¡G3»Ìš§z³±ø*_\£€‰3íà‡ëÞx=µ4† û³`BõòÝ„ „)¬8ì›Aí˜÷?EéL<øvɈ®ÆEÙ;¤¬*ù&ë¾YŸ'ß2këÕ®ÜÒn¸¸ðû~—Ö.-)%8çN% ‰`ª%‘³äív1?Ç>–qÙµö„5æñb‚‰saÇfQÇ +˯‰?—ßÒy˜ôd[Ô¸)|É_âÀm=0E×ÒF•Îì}‹ÒV¯Æ)³íZƒÑ“ÎÆz¸rêð;}Õ&”gÔ5pf7ü e¦¨F&Ú®!šŠ½š½¥äÛÎ÷èÏVW5ä”|ÞSûسN2Ü↟ä}¬¼têñKÇæ\´Ôõ€Ÿ1OàíöÌ4Í–ò+?5»J‡¦´±²ÂôZi¿(êÙµŸù¿”ÇÇ+ˆ9c<]ƒUnôH=¸ÉüYÞ%ÒQO!°Yܹg€ÁUäg‚¯»Š¢1VÖ Ü¤Žuí¸™'ßÀÌJ%È*šËT–ùžF•g¶t‹·¸ªAt}݈Ç9~N6?HÇ_½À³Qdù@[^Ö»ºfªÚ5ª1O-ÑÁìX³j›ÚÍî¦í=’·®iQŽ›mõ€—ü Íx­XÚb‹öØ<7v<Ø@îо½èV䈢grHp@Ìfß(ZåŽÙŠ8²™ 8,h$EøG¢›åãš„ÉíêÙOÒ6 l‚¡4µÉ–úRµõ‰Í§aWô¶ÉÈ‘¢1•— LWn ‘ïú¡Á²ÿOf»ôPcK e<­Äñ1dk1JYiË_2|…êJ³ëÈs1÷¢b*ˆS=Ð4Žœ,ïv§©7Á ˆ¶EoÕ~v›ÎÈF뜥 b’ëfaPèÑ.×úZsZ^Ἄ íSBL›®n´[A`½¡&Žr·ˆìtñ¨Cbu0—ª|çõ¹"8b­¾I²y–NP ùŠ—Öè|‘DxA”ÏcyuÅtMmkðËê¶UñM[ÚZã/-ö“ ¢µ,+@¶Í7§'›*üU %YWÖ²Ïw°{ÃV}I µD+KL)Ë(Š]E__x€·œÅj'õ_m¶o=ã<ë ­ HmûôZ‚ÕÝ– py[Û¶½É̙قW‰‘GÒ%kÍPÀ‹zÓ”~¢mäë*9@¾´,‹ëRJš¶-Þ•” åËb ØeNö [cËlÉ+]DÔ['ˆÈÔÞ¾<¹|þæüÕEr­öìôíéëg§¯ŸžâC­c©­('j¶žE‹çµ’¬­µ×øiº™¨­J¬œ§ȤÖJ sm…­­)þ´¦˜·šÍaÕl²X+Q@eØ«i¦IOM¶ìÕ,\H$÷P?\Å0J͸´µÚ“w¯Ÿ½<}æýpF*DÎX÷wUý¿—þOݯlþ’ÿGïà`Uÿß>lÿ®ÿÿ-þ±À< ´@é®Òä —¤xE¶ëÞx ”%V€ÉªÈ&Ë;ŒÛýÙÿ‡œ¬›ß\áÏÿjf£ÿï§½R{öw›ßìI!ñ½Ìþá=¢Wÿ8{ßþð½]y?é×w¨þçŠ#‘¡}g_ßaP~ƒªLFPš FßÝ/Á´û§Aó›ý½?A¿ò_Íå,Fà°çh ¢ ýlwgï[öäKÿ}îÿ˳§§¯/Nÿ™þÖáªý¯Ó…î¿ßÿß$þk¾Ì(Àaw¼ça(#„:ô^E &„±÷„bÉñ }]ƒÐ¯Ãoã&°TÈÍæ”ù0Ê=t{-‘çÁºucÿ)*lêg@# <=f®Â o#ÉçVó)âˆÃsa˜<½.(”Có<%§È`%% 9x»Å4¬=º7íÕ9(9«§jÒ! —À¨¼¥å×_SÍq4‹ä T% ×%—T6u‚³Ž9@꯳Oi•ù´^þX¤Õ1X-Ž€•Å·`û˜Ž!ÄÂréórH(²‚®ÎŽ©i 3û --}÷nšÎÊ3AïŒ!)Õ<¥/R|ŒÂ.è*Ï8M8i`:`ò¦¥¹ð¶£cŠo,Œ>7»*Mùý~FaMÒÓP~ßšNF708€¢_AÚ¶#®èpb.¿;õ.Þ<¿üáäüÔ;»ðÞž¿ùþì°N.àïGuâ%ß¼»ô ÇùÉëË¿yož{'¯ÿæýçÙëgõÚé_ßžŸ^\xoν³Wo_ž>ƒ³øúéËwÏÎ^¿ðžÀ{¯ß\z/Ï^] —o<ü  \> V{uzŽ~ç—'OÎ^ž]þ­î=?»|c‚pàxoOÎ/Ïž¾{yrî½}wþöÍÅ)|þYíõ›×g¯ŸŸÃWN_¾¾lÂWáSÞé÷ð‡wñÝÉË—ô©“wý9Á÷ôÍÛ¿Ÿ½øîÒûîÍËg§ððÉiíåÙÉ“—§ü)˜ÔÓ—'g¯êÞ³“W'/Né­70ʹ‡Ýº¾;¥Gð½øßSÌ Rƒ5¡°]ø³³<¿Ô¯þpvqZ÷NÎÏ.pAžŸ¿áq9á74¼÷ú”GÁ¥öJ;]ðïw§–g§'/a¬ |ÙîÜüÏÿoñO‡Xý³èç ßo÷Öý?;¿Óÿßâ߸Ú:Ær¥v9þvžLöjµ÷xÿ"œyßs`¨ ùÁ$lZ6£t?IÐn~;ÙÓaÍÕ}öpÌ'ÓzAÉŠÍ ‘Œ#ràY‹†ÁÿÄá.ßrhÒÞ¶¯Ò7Ÿ…˜2LÆËµOÂYâçÑbVŠlfõåÎô) ÷ıp-æEÔ ù!ySÑ—>·å[ò]TFMµ j-íD8OóMãȮݷ֥Á6 ³ò2w–P|&ðp¹>"ÀLLÕ¦}y9¶{>mÍ8œøq)b‹íK5ÖJ:è™ {^“åyS3ŸÊG¡Jk<<ÚûâPô忤ÂwŽ1¸£‡ÍKY¬A¼r­òææ®«gqcÇ?-Š™˜í¾¥Qÿ'>ÀÊ™‹™õ`ìÏæ~4I¾cÒ-ý”»q?*’à]’²VFÒîåµZÃ{ÿÎøEJnð§»1ò³Qvº\°š[¢m¡KN’…úH2“̺ÉÊ6TAïœzJÈ<±çÐ)²þ¤ö'p3ÇÞ;,`Í#ü«±À¿¨õ•dú‚&•ô UЂ¹¾à)ªPåÉ ¹|œ‡ã4 ´è@AñÐýA2jlHc#ÃFõ6&LÌÑ·é"J|ÀNÞ.pÈP|)€0+ßáTÏFÎ=iÖ Ž «£‚’?oé§c£)Ño4Óïuê4h0yÔä,£ƒK ?äÉw”w žq6½hœmÈ`žîÄFÛ†ŒÛ(½ó3Ñàð“`y¦sòyœi5‰ú$Q0ÃýVçGRCÐöØ9`V?×í€ôñOéñLŠÐøWi9“´š¯"ªãH‡‡ž4fü¤ü}ÏTp"±è©”Û°Áj˜œö èÓP%9ä‹:¯‚“U"è:çBÃŒFJ} mNÂlÿyô)YÌJä:5_SkéÛj€§œP‰¾·ö:g[?ª·_é¤U¨ýòJ»b\2Po¬mÒó(Ë‹í‘7ÄÄQC=ëkj¢ý"«EiʯT.ÉÁ­ßR™¹>7”Þ²¶ ÓkNô]‚×Ú¤ôºÁ)åסVÜAQ~9P×ß .ÞÎé])£!µD5ˆ|ÂøSž=QuªtJ”óXU¯Vg*Õßy­ —Üs$uq“/I9¥/ËaXû®õ5*¶²–œèA×ö¡cøQù%ä•”î]û$ަêúÒ%d<“klÄOÏ)»0b?úEzRtêI¿É%.¦žiB4×(·«ëXÊLQºÚ%U½õ”ª"øüC€iì˜Ý¢, z+r!Žro ½dqfÔ“™¿¤ÕT/äl4k0¢¦óÄWÃàQu'l$ d‚ ?˜2sL3ðaÃä!Ô'ŸKCqáÖŠùHVZÞñÆú였¨\=,äóX¥lÀŸ“†ÅS=¡—†¥¡úÛ„Îë6?)b×è~¢a^¦“ ¿óo¼,oÏ$·8-É賊çÃÎ_¥Ý Õ"»Qb”}.ñ[²Õ„zI8I‹Èg³™•šç3Ãb’ÊÐâ•eþZM’9¢s‡—¯V7@¨)1/¿¨’¦GOûVgÇǦʟBEÚß¿{ûâü>võ¯œEˆ*×Îáôp‰®d§ñì êšê*óðiù!å‘Òà ö÷ïîîšFÏ‚:¨=èü:ÄU€eþäaª»Ÿ™è)ãû¤ÖÙF̓¼N†>oAe¤.ïV^.ø|ÞÑ'“oŠ­R±ïÉ-œVÚ /ÍÓÜQu ÎÞG¬¥þÆÝÃl!5ŽÎgº…SAª4V” w…s fuÊ&o.Xd3ÃïpúÂa9ÑáwÑRû¨)p2wøÜzwJ»ƒMœ’êWÁ ¹Ô®.CÀøOB\\Âr?%i¦7"ójžÎBeèÄK . N1ªÎ1@M–YºRŸ |l¾ª‰2µ6˜Ê6â48/ù+²ŠG5Ö<)Žxì?<5{dŠÖfç¶½SçEx–¨êR²`àíÈñر"¥¸ì¸Ä B!ä Qu§È­†ý5¯=aŽ®0Ëœ<ö¼?ÛO½üã[Ø8†ÈÀIøþa7Lnµ#'zî˜-.œ(¥ ØÝéµÚÞ»DÀôàf÷‹¥®‚‡/}Fi½‹2aiFùØÛ9W¥N$‘3¦`BvsGE…°Pî Í žQMr'Øí´*gZþ™üýxç¦pÊ*?T½Xö*4Õ$ áW4RtÓú¬$hȽAÔ13[8ðDmU§Áàp‰ zµ'ç:Š8„=4Î×úS¯åu”» É{xåÞ9zصéÔ±3â®jVTýTOвª­ f¾OqJ_Ü™# ?ìþhÍ7lPÚ¾ºÕŠxcà©5`(>èöŸ6ß{ྮ¬€lëÙ3=Ì/µx‹ÂÛïî<ô|¯æ‚&þ¬ð³3¡þj+l)àýÂë Ï—.+&ÿÿ/)=eGá<øÄ[nE9SG>ÛÄp¯P`&À”Û8$ÖZ84soÈÉKÕ’W‹#qëp`¨!¾*¤Éç^¤4y˜wÐ*Yö‡b ¢ð*/N/½} oûjqöWú†^%|¼¡,-µ`±Õr?~·é…g§/O/O+…»á…X›vxwÜuN+ª§ŒE¼ˆ9W…„(K(¼`²·1p«­l£â’B›MaŠ­Óù—±ÜÛZwO„§®”“1dÁjVN1l¿ºC_“Ä@«i\CCªnƒ™i©t,&>¤£‡Â†>Üù”mÚO#›xTx 8öN…SÖk3cä‡õ‘iìóDñù™ZæƒB¸Æ ïýèÑŸ€1î8Ø!q…®d ã` ™Ê`ðÄ—ìS@jö5Ýùކ¥QçêApyŠ!¹Dâž¡€6©4ùfÞ‘¦¸Žý`6M.ËÛÍ8¤u ßÕ(ÁR¢€ñž›¢ àK’7@0';AšIrSª¹" Ó)ñ³ˆ ”6\¤rš¥/p—{_¤%jãæ!aÉ¦ÎøR§ccv2QyJû”íÂã2-%âïÍl„Û+òž¥Š$`‹urä¼P…È& ˆä„ÿ1’]L´†¹Â`¸½º‡ù­vó×_cë× ÆA‰ú³+.9ùÍ·Þ³(c}h3KÓb}dbgOvPÁË£í3n´Áå»e¯„÷íñt EÒ%óâeË(ãê*ñ,½æ¯¼÷€ªzÍÖ7≖¨&I)¤;‹ ©Ù½Ø_²ÏŠk,Tk£fʾÌ1eh´š “+]Õk:WWÌ~åŠf XæÛôvÿž1öšÞå”ÊCϰ®Õ=dåN¼FÁéÄ÷×Þ™Žd¢Ë©K^^kfV9QÊÇ; i&J¤Ž9„É2EUÀ¹i£#Ñ-Ô¬ü€•S}»aµF(þo«Ö•Eu…Ä@î_˜ðBèahÇà ŒÚI(¯8wð/Ÿ4­ÂÃ"¥‹íLÜÆì)È‘°!!¥ÆâØSÿ–²ä†V‡dóP•ê˜Ðæ6&5gŠEfË…³Ê* Ʊ¥³¿‚µ×oÇm»úqÇp™jÂÄãpWÊxŽ7XsÃHgc?ãóMºÖX Õ2ðiZ`8¯V‘‡ñõφŸï÷m{Ç@üŸa8Ç]œE˜1 ({ È¶52ß°Oæ }»<×Z‡%Ÿ#…ƒ1¤OÉÕÞSVwŒ°ÀI--T+uJÃÀiZò ¡¬òvþÚ@úØ`<¢AÂ!#©–ÁEK‰O$ýšÖ¤©%¦Û¢ÈçúÚ¡(_|úÙxZ1Œñwh[Ë…'é«ÎO"¾4R×/Žèœâ‘ɨ¨!Ur'וÞò7àÖkCÑ„ ëðŒý™®ä\I !a|PËîÆ¼Â  )7­÷fªupØŸ'ÊF? ¹°4êjôºž–ì5&^ G™)Ø¢B]Þ¿½)`ÚØ­3RïxšæÅà¸sÜC»YÒ¡)ðÞi›‰431¦"Ácž“н‹•Bϳȓ)šcÄeFPc}¤TÀ¸M‚&ŒªðCiñ·,ö ÷æï“F˜³ª£v:½ ᪪oÌÝ ‚6†šÖ¿zê´£ƒU¨Ï´ŸÛ»ù‹ï¹\ Ù×nHÑÞÄÆwRu`ñû¸²à0ùo(ÏAõvoÞë'Kuž¿—å…©ê§¡Ì‘àlUIÒ2¤X ¯á¶Âœ¡ü¦”K A#ßdÛ8¡wê£l¼˜QnZPuÃÔõ–žÓB*f8`óÔÐco+)ÁEïóúrHlÏXá–ûÞ°×:ð^§…¬'Òã!ë”Q°äš֩òÎëoÖHâØlÇ]³àjåkoÈû8x'ló“):X6xØO48…(@Ù Y“€³ý#ñ†¼™XÂj(Û /î"_ WWtÕ“y¦:𫸅"&T·šÐSø¯±Ò!±FÅ[u…zŠ|¦bŠe+‘Ÿ†Vg‹È.ºçâÉG G¦óCËÁ.Î=Ë|ÁÁ¾©o‡Ö'ô ‘r_ 5 –+»}ççS_$}a”â7Î~=z™kµóU”ËŽ!ÆÃ¥˜ˆ.Æ¥6ŒR/I}u!Ò0"ß‹ÓKѬ3¬‘˜øöÝåÐú@uìˆÖ*0„|R‡[Ío`EÇmöÊ`| NšÒªàMåä@†Ÿ\•aô™ý%="•5·’«4ûªDªŠüD6ˆèª^E:#ä< ^UõZå8¬ŒÄ•.Ù(‚ Š¥$%⪉¤M ÙŠÎï_Ûò+ùV*ä‹úð}ô3_Ìÿèí(øÅ*¶ƒÆõLˆ¼ÊA6äSƦþ %WA™–,Žd¨Æ(7¸eál^,‰áøúká—¾þš¡!Æäé¯ìÉ‚Z•áõV)ï#o•*Y3€ðÿøˆ´)WÈ!=ðÄ.=ª{¨þƒ[~úiG¦ŽÐ¢ËK*pi}Qbx´²Žø­Ÿj?ÕäÍ7x¿î¸2½u–D^@Ölb¼m(ž,à•ƒ¨›¥¹yß-´cüÀÈMPÞ…@M³Fkh×î¦×«9“Qæ=yÿ‡Z2@Jé 'XÚ›<·“‡Ÿ"Zt ’ˆ”%ȼhªÇk,âÿ€˜?½I"Hvƒ>6·žU8á1#þ¤Ê49Tx±ÎV4g»[ˆµhIB˜g¨¥DQS“c,X\Ú†GQT‡/—yªáê±ñj³ß…™±?JÚ±9nif¼W4AotM­IÄáÁï§Ç0nN¨‡ ž"Ÿ³‰(—OrŒ²ºZ>¦F³#n€ë‹S…3TøQÅZŠZf¯^ú5LzØŸª½Y¿ˆÁÐ¥óŒÁÙ¿NÓý‘Ÿmd6.§A7fG{À°ˆ7Hoö¨zÅÌ«V¡¦4œ´qP…‡ì -y2|‰­bæ–J[ße«X<Å‚Ñ æ¶j#‡: ©1vØö›õ^«–ûX»#e¿‡nbÕþ%èµ¹#2_uãþuéøöÔšõk«¤ùý„¼‚P ÐXbìsñîÜ?ÿÒiîÙR3 6°%Rÿ«ÞÒŸÇùã½ÝnRÿ{‘Eãé#Ã=â³m.ÿ¦ ¿Æü L3_VŽ­bް‰°’ÆBñ]|-«ò5©rL¤ÉȈ$5²øßKI™/ü ‹ˆ´ÿ&g›óS†¾âPØf±MɤŒeœ.Ë¥šÍJÚ„›“Jš­ß†[c%¬¿ªx«Ö¾ÞHZâ’Ðè².÷!ü4xûÿuòÞo|þðÍ}Þ§¢+TT| ï§ap µæÚ|Ê_QúâG$TóœR8MÌØ¼÷ƒÙ¼[÷wþ-ü×÷Çðßt2ùPW|èÀÃúÓ³E±@[ÜUø ŽVŽvS=C$e%<ò±gEð‰‚@-œÖ@³ƒI×S;l ÓÚ oYT”üæqW`ßÉIYŒ/²ã˜“"Á`- bqáQÓ£ÄhÃ`³•ß>x²Hðµ Ak¶álÜ«f·sgcì”^`bw•PNÏŠey³ñG¸9çÔ·‰¯ì¶›Ív«µGwÇŒ–¤ÉÕ–#VföÃ`æÒüsízÊ:gc“æ”ùÖ©‹§·²Iš#¦(kƒ î;™“£†¼C…÷áöÐ@% e"¡{VT@>ÌziUPÓ;¡pÏáúÚˆ‚YuU˜=PãlóB?í1ûçŠU‹ÕæºÀªâþ2•ðËmI}¥ûŸ1*04 ­¬„ ò‹ýÙ(€ûD™_†ƒ€É2ó‹B ìdìz3ÉÂ0Ù± ¨däg¹rü]%uÏJódrM§#'˜…™qÀåÁÆ  ^`c~ËÚÊy$£©˜]½ë–UM0b×¥ŸÐhÃÖ#´+töµ÷‰&ÏàÜÏüs¯,f!°HðÛ3Ÿ\ðÇe4Ã_åÇ“4C]qDøZ5üÂÁ{Úx?¼#cxPÖË]ÊÚè ñ!&ZA¥Ùœž³¦²ÔÀ]ö)„”n;MOyy²²Ö8¤“Ñ·ÓìÑH¡ŸÅ¬¥ŠÉi¢QõP›Ä §‚ÅãcÌ7•òþÐÊÂAÒè MXQ²68»á0æ)$ Lš'öe‚Í£ç÷“JèUg*R¢ìJãHLè´c«FßëÁ?ЯšdfÑ­ÙЬ÷TWä‚Ðìæíôú ú7ù$N?“e”Ù?k]¨ƒZsÖ7§S­ÕN(ÐH»Îè‘޵9çã@e FÔn¬Ý£°FŽLä(J„Ønò#ò‰¸+dmH²Qé‡â3¾Kø~M#‘¯ÆeF˜øs@iÐI@t ß(ù!‰Èç(Z©ÀÐm¤øâdágrÛ¢å1¶EJÔƒ¦6pÊh¯†àÕÑÃS†<;•"’ò ”È€C/õÝù¹r³oz§ÍI³¾êúð±–ñç*cßã½\ã¼2ä5F9 w #r2‡?óøßray£hÇ7(ZŒÖj—z©ÂäèÏy&>ÿôÚŽJ?ó?îv{bÁ=ðæ^Sä…?ÙC$áùSë${t´«o[ ‰?å?4§¿1y—‘÷žTà ٷiq}½Æ5²ó1Ž1®ÖÎcÝBîÔäUÔøÿ­D‰¶( ñ³Ådõ`J$¡öþ¦è18ót¸•RŽšøm0š`Ç à0ôõÀw®n#C¢o¡d’(ru°S ÙÇ QúˆGÒœåèãÆˆœ*íÓ-u‰1çS‚‰¼ø×Œ×¶vd—£ÎgˆÞ%osÎiE@q¶Ã/"S$íwk A¬`ž«ð ×d@wÀkKVËœ.‚«ª“R¨ñG¬ôô£l7ŸïqË—£S2¿¥Aaém¿2ùþ­aý;XgMN²Ì_¾ç9}X‡¡ÍJ±»ÿ_ù7û{¢Ú°DÀÈh/é÷ÒHOgN¢ñjÆ•…¶\B‡KÇLiE˜A²/GN)KJ˜Râ*H!büDkï¡þ•(½@‰`2• ÏàCZ „áLÓNGBF ^*iý0Üöô0[P^o5ÈÖ ÞœùóÝÿ9(Ò«ÈRcJ,ò¦œàÊ]syäz…™·ÕÏpg=U!áLœ- `/á­HŽ#ËÛ‚³Âðt‰E|i‰ü[¿ðõµÀwXªfÿÏîƒ;æå`NŒú嬲SÕ]~‘Îì­¹©oÎæäZɽÿÂôÇò²oJ§®V]‡TrRÊOö’1ú²‰ïI–bd>ÄÃØŠÙ Yã!ymè;5+~¹É—œQ0s@>1òÈÔO‘Ï'¼ ß Ò¼HhŸÄaD–Z†í¬çcN•’ÏÈH‘ö!EtôÅE•›ÚÖjdD,èŠÀ®¥vÝëÔ½î‡5žtåHàg>4%yp‰^sPÞÚ…·êTwz€:Iøî£Aû§=ÞáG?"$ßþ±ýÓ£Mï¼——µýôA¿÷^¿øáÑ—>×ÓŸ#wý^«õ¥oõÌ—ô+k™+ÔÙ`Ô‚Ë ÈIˆñ‚¼ä8ÛÒ(`õä¼lÉN–OÍœâZ5±Jo‡YbÊœûy)Øý˧Âz›Ã±ÝI %ÃÞ?Üà9ð~‚5} ÙàôM~žRØz4f™¤ÈÒ˜|Z5§Ž÷ˆŽ.f×Sz ^ΪNùhì­¨ Æì9|/½V>—ÿ½wÛ#KÓÅz؆‘Æ ÃûÂ¾Š¢öL2YÉH’uÈ.UKRUiF% «»4Ì ’ÑJfp"2I±UÚ×ö½/æf~ßø lÀÀ†}k_ùü^ßX‡ˆÈdRuè®±4ƒ.fÄŠu^ÿúßßœu¡ÕúCRd‰¸ð/£Â^ØÉ7Ö7ÆÐS_¢ еǘ=ð)…ׇÓWeˆ‚«M.^,¯ÚÕN¯÷9$/þqðÍ‹íQ”ßkË?» "}p»áüEÀ@¡/ö£¯_|ÿüqG><0O»Ñšy˽ZDš=Bš  jÆ v–BÀëfØÀ cK•´ÔŒ£«×%bA=5œÎëtÆ[‡æX#Šn¢e„°ÇÕ³¯ÄMµ™;éÊ ®´€åW°¤ ÞŽf—¹XCð×Ìï5¡éš<"Aœ¹ÓDp!“ÍÞÑ)5é©ÎO«2²–峈x‰3|ž‡ÁDw2µzж Îa^L‡üÊám~¼ÑÐ3 »ŸdyÀÕ3P©ƒo $KS! -‹[ôºÞÕqwý¡Rƒn¬*JM}d¡¼‰Ä#™¶Ì¼Êͯ›Pƒ †,r‰ÀKZR)Gœ½…½rÆ€cµy™ZÕOß% &¥êÖrÜEÿUyÌ®ä„(—صªWÒÀ1sTÙÿõ{èMzUy¢º QH¸¾;Åu΋\„ëÀŽ·¢¦48­izËÔWÍ}`ühï¸ûÎ\f)QCLéïýû ßK¦,¦ H]žfçaxÕà|YÏëŒlLRó—yÿºå1ë994Y™{¶êS|”M? fµ)¤ªmM’é›/(šstšŽÞ ¢^®OóV{ QÁil}Ã<>(ûŒ0CÇ‘vDhŒÕËŒÓ8"(ë®cÈà¾gƒU›IS¿‘ØŒˆ÷¼¸¢²ÄáGÃã<^;Ëú¡V}P‘F£‡£¶©±mx©Ú|û‘µ•Y¦Ídd (¶šÌ„rÍ"U© d7Ëpý,tHLßÎØ@oßWˆ>÷˜ò:SFÄ@|Ý÷P‘tÍÌ Aù ½ªÅtšú§©í ¾\½Î&ÒPѧ¯Õ`ÎO¤¨d}qÇ;Ëá'yá47Oå‚ɬOX§´cΓ–Š¥ËÞ¯5OaR»îömNsƒ%#Iïa^Ì㵈êäš³ÜË==K²ÉÀºü%†Iãg5oø²„ÑúIøèÚ'¯ñ¹U?d°z( D‘*'þ¡Re`’õL¬¤’À´8nÁ074ψeðÔ@ .¥æ -2VCÆ7zqË4€í= ò?lâ15êvH¿l—-Ä,{±uñŠË„°âØ¥"t{¶üY‹hû…l`71¡…ŽY;BG )ÆdåÈf¥¶B ¡ß;q„4¬'–)ûT`‡Í$vA;¡þjÙ1;ʨ—ÍÏŽh&èV;Ê zÇiM`ë¡W[ºäNÁeË3Ö²3f>ÌüEëêòO³íÊLBe(Ä.eƒê‘‘Uª8J %&…rÁµq‹ø(aQ _$Ÿ¹0 qjšNø poÌÉ1fWC³G/¦Õz›Z–®ºiâ’®¨|’ÌDÎóúàÝš à†¡2\øuºoW7³¼&öÌÞL+F6š-t™¸~…M/غ¢Ñš àþ>[uT•òµa™ÿ§÷¿È¸Üƒ?ϳQJ®ÃAw‚¡vµXuÈ“É /ÓUG¯~PE„ׇlùË9èÐ*Cûx3­îën}St&m㦫L-ú®/]P0땚ÝÉýz³Hž›ì¤nÌYUgåiåQÁ3Õ°?ð}—¿éÚr‚„ÇQˆc³¶o–wBÖªaµšÖkéyìºrÕ¨Æ14ÅlyWFFÜ®<2µAÍ~F›®|Ó ÊU›. ¯vž.o9õÃÚTwh6B_×Ìrhq«C%bnÄ£,\VüYkdX¤ @b‹aIòÚi:-ªËÛêO˜`v‘EÊÛÁâDª{”´RóAòìú8@ò¹Åê!pêµW©á›S ¶Dv©¹)×® ÿ™eý)+*Cø [‡Döš ñ¤ôú°³ 1¥­E2½6d£$!Ð΄µû‘2I¢¢È¶¯ÔσÞ\WØv…¼0úw)þ&Ã2=¡¤€1Àz$ºË1QJXW9saЌɩ¶7'¨[…ED"½õE¯—!w¸ÊÞZQ7*Où;¶Vò•ÒòÉ{oí%à¥h°* Ö¸¶ÚE«d…Z8›äûvt©g,yþ\ZûNÙ<«ÂOMUF¶¬Ïë´r$šgºFT.¼Iåßnì:Þéa´±áýZœwÕ†¡ùvÄ øëäü4‘¨H‡ëÈ`ió"¸I5t<¶OÖ)nŠíBb¤ÎH`“tÑ:Œþ{ ¼?è'sÔú‡~oC¤, ¨Dv•~_´‘~tð¥"ÎÓøxnè<ªv=éúz ¯‘ÈG>Öf¸›S¯Cn/šÄåÜ# P¥©Tê›w Ÿ­Í„csY´Dt\£ŒÏ õ,žâ—^¢x"í<Œ¾ÌÕsæ—Zž5Íbf³ø™Ÿ·ÞIÃï½õ¡ ÆµŸ²H<®~´}gk¥Åñt™´>Ðah|xÕ`ñRâÈ3T}ƒDº¡,VdMßø,Cn=/‹j`"ªc8ãƒÕ7ǺŒ„÷Â-Õ™ûúB:…âîe ŠÐAó… XþZ>þÃ/pVU©Àì¡ÉH•šêËN²à-ñ™ÒŠjFè„€Ú\iN¬˜A!áS!f¤°+lI7T³28ÎÒÉøîfùÞìïæ’P-Iya·h^ä°¨NGT oÒ«/Ö¹ž˜Œz:›ì‘FZ•ãIrâÝØDaåþióª .SKU‘˜§ó®!¾°Z/µCR^«ðòvDÕ F¯lž‘ÈcágM•»M´ ‰ŠÁô ‰ ½qóìZrYŠölõAnßVë´»~ Ø*Å®÷2JQG ûØÈ\Re«iÂÊtült lÔpé>â¶ØsÆ1}îj:Ž}>%ó“Ó™µ´k¢r1‹4aZ½³µe{CJwÙ™lÒó¦Õ‡øs2ϧ\ Í6":ÆGZ–¬4¬[ÜXï OR¡XP’¶~å)J¢ÓùYÂ~ÒɘnˆR¶’&Ü^cIþ’Û¢IQºÖ­§I¢ñ3ª„VQ0Ô®]ÎhºòŒp\l° ä²¶3 /[U6ÌÈCÊš<^D#…N±8C„NO™b*fä³_OPÚ(n‚% ¾Ð„ú;OœyÝtƒÔ­J±Ï‹|<‡BaxðnM¿hA׺k˜¹µÃîšÖ‰W øðý¡/îXåœÒx=ˆV˜lp?¦?bañû“Ȭ"‚ü˵Êy þO0´ÖòYx.µ€é¯vàäÓa„|Ü\±­x)=0âœá­˜ªã ¯nèQˆûCŽÑEYg{Ú„Û¶ÃO Ö©ºGžT±œà#mž—*níçQù&;§ÍJ\éÓ Œ’]^=‹« Cà:Å•B ƒà>Ì­YÎøòU òðT„=¨ìÌŒn¤ìF6£¤Qȶ‹å­Dƒ0VzUéJP"°]0Üz ên¶ûaªEI³,ÛèÔÕ¨[*¾!¯Õÿ  ¦ëò \ÿJ ÊË5æé8š$§4d,]Bø¯™ SÍ5fWéÕg,Ð><ݾ?­…ãaèT¾IÁ;ˆ« ¨({ÇÒ@Mã“#dj4‡ú‰™Ó øöÇ­Ya˜‰û±™nôÖ%üÇ”ylÎÏ¡eåjO§ñÕÙäp}’õ(sçFJ{ü‚Ó³KàË­ !CµŠO2êQö5qÒÑæI°G1]0/ÖÈ[~”ŠuÄóõVß’®ç&qÏij®„Fç3û*’®m,ÊöV'Ø1¶Ù:®CQyEx›Ò§º±ìW½ÿŽÿ]ÏÿTè¨s‘¤ÇÝÆÎKtÕíW4‡ùJÉF ÆfA%6¨.ÿ(UN¯íÓÅœîV‹î¸¢;ï‡qdÍ¢§3ãã¸ú\QÐ+* ¼EñÛpCÖµÖcï fÃÖ¸–/üõ‰‰m´ë—ÂVsÖjæ% k53®&ÞEfV´6L§C‘2<ÎÌ šÛ¼’\–Æ+Rh5qô­íŽŠaVÛûž³Í—L)ê^úž0íº1ç&͘Ž´D4xýäÑ«'ûƒ—{¯_ÿñÅ«ÇKÚ ‚]²H2Ð3.ÿê¾€sw@S ·Ø|•>§ÜÜONàB=Í왾m{ˆÚPw’.ˆ‡3ì wvåJ¹âµ%Š˜†iè¢$Fn>¦$Ó”}¢M’M ¶ä2¢L§¥CÛ†¤yb¸û9íÜýâeü®G‹ Úr‚*g±VòÜ)íY?Ʊÿ#yS+„{x= Î#Uö ›wƒ’çjˆiï`kóÁáFOAº N†gÉG—ŠÕê¤Ëê4!xÚ­^jVµí^y\¼9±8te 7_£:²iPáŲ©&Êy«óGæ’;KFEÂ'M'™„KPô:Å xº®3sGL‚;ŸÈDiÙhÈN7Óã|±‘kíÖ;üxO~3âT2Žø¡õÍy/oÖËΚY*m};›SjðJsÞþ¦¶Ì÷¿^˜´öV8“e€™Cêù±õ¿8VKäݾÞé¨b~¦&qeo}|o~½Fƒ‰íÖÇŽ¤²”QO»§Tdæj›ftÞýé±ô¯27bá¬É-Ûw5Ô,jœp²ú±«€]¿™Î"WKBæ%Õo#ÞÅII·ì*yˆ+K&—mÿ<ÁÅD<†õŽñðs’“´Ž±R)c†´¨\°Âì¥ó ¬Í«]sËáô{uKýÇú6»);äÑ”ùø‘­=F¿ìæÃÃN|îek×¾vVñvZ´2Ön ôžS\“D=C»[~ßÛºvaÒ"ËÇuOMЏPl_øÂÔ©e¯ñõ+¼Êú^OGì‘õg`ÁVˆíšˆ®?Œð\Ö–]¶h NÌ÷g”yêc ÌrûZgϽlØ;öÕJ[HÕb®J’l‰»œÒäË&£¨Z¼0­lá“`L7eQÉèæÈZˆ"a°ëÍẍÿ&åH2ø¯qZüL[”ÁœaI—¾«^Å(08Ò¤aùèÀópì;y0°eššh®ÿï²u3xÚkëj>ü™¶s¢Krý¾–žëÀÐ]à™Ûås}¶ƒïG}÷¾òÚ¼3£½ædÄϰ[—GނߘãN¯õ21€Ý’Ÿcc0»¹ÆLµE~‰7ãü,cT;žžX æØ´»D‚à³Ù†½¹¥ÆšÀänópóT%2 "Ëó\ ë=—YŠ‚j´EÕÛAØÞìtÅJº^ÿ­ø¼d–"HAvÜŠ>ÚÙÚ& 5DÖ»á¦èx )ÚÙºÃ/?yödÿ‰{%™¢¿ÄbÈ3Ò áÄìlm©ÿ`þØ ÁT$9jM±=nd¥çqм/®¨&ri„‹ç¦Ž†±YJca¸¤á­ìj#í˃‡Ñ/fVná~&Ì#ÄÌœ,es >ž#ß¼19M»õ²UÓ/€ÍGóY6ŠmöååeŒ¾êCÚ Þ+LQþ|ÔûÝb]ÓþÞþ÷¯^<~òzNæ³Ä¯%ƒîOó¬D@à^¥ã 9N(Y²sŽâ‡Œ”4M/#d@|^$ðQÖooítÀ&™«ä,™²K­y¸í#üØjÔƒåòv¨hk*ÑuuŠaßõu”ŸL³¿€¨âzõ;ÌoÒ0L–t;Šö (r„(C è®Ýð¡££õ›ª†+m7PÓ‚úÎös€~Ôç…ððÛú;æD…æÁ\¿ä¯öd( ,v"Ó( ® /Q„á·Oö[6 ÌËŽi*ƒÁ?È›c5Þã¬ÕmV¶l"(¡eù@Vg½á'27ÑòÉ©gõ=¹„=] ´’ËùS™QWÏbebVœ’/÷Ÿ¾xþzɬˆŠPµ²”Ô.’Ϭk3>k‰€÷k´nkªÃð …çÛ¬JÂùYÇSíf ª¬!+a ŽRÉÏÞ'%Çÿ«ëMú6Í G ~*Ó\è§+MÝ+æÓÕ·­öª»>êJžXû,¢PAÅ6n ÌûAÖ`~ÇcE<) âšÊ½ØAÊ$Yï_sŸ ›£ì9ßÍ0vd7oˆ€h;‘°H«[Aˆ·Köz{kkËö³ÕúÜ–´éšêmÇÛ­Ï[ŸÙt¥>Ï#I+kÞÐfêë÷]ìþnôòûýŠºË;¦Ñ²c*2TÊ] »8<-0™íkçS·wé‚ÕôDÉ´%Év£u¦T€QâÕq§§C²tïÿ<û=X³"fT°zË—¬‡5“Âî¡·fÑ·ø& ?—3RŸk—·›Xiœ«žÇnA!Â¾ê˜ ñzg£F¨æB-=âFÉ[A¬> öœª‚ên‰z¸šÚ(Ÿo™óTZ¨K›µ%p9›Y e¶LXˆä‰Fï4ðVÂ@ª¯´¸NkΕêP?±p©,|Bžhá>7Ô˜ÒÕ3¿Ú•õw\ƒ!Gó©Åò¢Gm*Ø´`!gç3£cC.É(º × ãêªB¦VdÍÌc›7@NrÙ(<‰žß5‹ò¦Ó›lö˪_QP1igšOö9GõŸÐw›OXé}ð­Á™®¦æºs¬&w-…û¢á͘?V¼8 ˆs ½¸¯ß¬úîŠm„Låáá ¤Ÿƒƒ;[÷»5û#éÙhp’R£ê›Ü¯|žÉ÷;«F–+ÉÃò0ãdhaäÇOЊƒà,E}oôá°Ÿ…:~}#¹o·*¡±y^NrÝ)"+­ËÚ5*:™m5Ö°áKrù_Ä*ý".¾<%¯gr¶Å. zojiDþÖÐ Eõ!ÿ|žŠ•œÛ:aôE(ƒ€yBà §e¯'@ŠnÀXúÀ&M\µgþ§có!©‰KíÙl‹ HmßÍ}K™.§A×SrF#ÍÓ¨˜S¢Ó¥Á@ì0´HÎÆ&aZ( ¥µæH0C ºìVÓšd3 Ä;ä7A”pØRfíMe§S]eŒ³|"¸ˆlƒ<ËövósÍ™éyÂaŠ_c^÷YECû¦º‰ü€†¾i©}àÝ,Ôˆª÷Èðí’é€àÛňaPXÇ>ï}D„f’癸,'Ʀڭ¡³ «:•/ÙJš…0.íT·«bó]QßÝ ÝÙÔpGf«5yÿ#$Wã2â7më2Í–ðëIiA±‘\1µæ‚¢˜iÁþo^WèükÕú›në{¶FÖ݆¸>¸é=avˆÌvÉ~ÿ˜ˆžTkd%G›'Õ’ ‘ê)'‹§à“æUái~Ç„=œR×Ê™x\p‰f—9aŠ<!Ì:õë+¾u›0f­Ë/Ú "ÉT\è Ý‹•ÃÃÊ>®Å>~ðß(8Éú.¤‚䥣YDöí.þž[˜®Û”¢7ÖDTÛ¤ dkœ4à ñ‘7³–m-øþ°É(bÔ™R85G{KF€„ßhæø µ-Gý6?_fÂPF^B¢ ƒò„Ô ¨®ì]#Üð-ëFÊÛðÖ;ûá{xÔ¼_¢MÄ Wu¹ÎžòD}­ýôC¨»¾»"Ñ[©þAßýö2‹|bºµn/ + †FŒ‚#á4ZÂ2W%Y‹PÇ(ƒu¯Sª…#uxbý¤«²áü¬q™±.~Ê Û1ljï×jöÎ&>UÐó4v¶ ÝŸÃõ<e\i N¼{¸¸8ÖM%¸®ÙCmÿ0³ÿ"p;z,Fï—ûº¬¸âÉ0µÍU!(óáÍ…Åp°=í÷½ÆX+N•Ÿh= Ø*ïK×çahòöWc;MD¼˜„ެYbøž­uÃ8‹¾;\ôšTüR½èýÜÚ8tgÀþ]]Ó.‘QH7vc¼O€cMÜuÝô¾šO,“ m*é‰+S»`Îü»Ñ¢N-™Cž†¾ÅS×õg¾Huÿ.šRõ£ðfßÑ”¼j‚ ùS.žÞ’®Öa|âwþg»ƒ*î¡Ëh~µ3uÂàhò Eˆõš†÷ÆPt¯]Rº;Ö… 6 P%eQÌ{Îpö&½B‹ØE©ˆÇCÇà9-‰ä· 7Á¤˜)÷ç_Ú*v#ûÕ|ýj—– ü…ú4Üúmåé„9áIm³¤T¹¥Òb ´Ó1²A j¡ áfº&Šo?óQ#ÊD,< @g%PÎ6OMý•´#EŽ182÷1¾‚â0|b!†åŠ»ª³éTª1Hª)£ &,Ý"ð¹o‘ûbئjÛCÏÖ¦èVVÏG£9|®‡AÝCçÿ~J#¡céÛŸšHÛósr̳ ù,¸ãpˆ¢‘°#Âücj(GV8 9yÛA´¹¬#¤CÝt ÚnøŒ¿—+ExÞ£+£&Él£")JÛ°ð¦=SÅk¬¥QÖó{æKÌ%‰‘´<ÜûVø³‘Æçíì—ÀÛHõ|ÓÀÍ{à.É[ZócƒWò×ã/þ\!ùÎ4aXÞZ÷Ìýpj®g¾£aP¤”Æé£èaÄKf®¥ç_¿X ¢Áy"à åójkß]=ÓÙÀ\]r2ÕCò•m8C&5yN¢…|eéÚJq2nmS®øŸ°dž‡v¤Ÿ7\ª¯)WBa—2=×Û{ÂGÑ^yì¾0Çþ æî+³ù{AQr"çÎ4lz›nrÏ›ý ²q6šOòyÙ[ð¹DðI³ÏúZfV $p5“°§û"ó—BòÜø©È€Ò1’çkdRë®}ÕõmyRMkðÃwÏÝh‡ü÷«§Ï÷^ýiÀ^уýöaXC¬tËA ¡ÑþÞjYÛáùÃâ=)á±v–üM.s¾°Xe€I€Ãžá¶8MûêŒõ-øbùó"³šˆ gÏżL]v¹ª*þVE§ä×_鹺Ú& ÂòûÖ{fä«6’$f UôÌ“v­ÄÃJ9<ª<ʦæ*¨ÍG³t¶É7~ý²Ç°Tx>I8ë9@¨|j y¶CÙg²]aR ·¢ÙÁfw眽 ÀS®Ó`Å1¼fÅÂ7«ÅÏÑ'ÐOµôp‚23]âŸÚ/Jxù[Vóf²I»æ¿˜·!å¡ÊláäÀë¼! c9 Eþ´UßøtÈÔñ“èuÞå‹“Så‚¥_õú ¸ÁŽþ  S@QW-ö©yÚ¸ºæ—›7-ÌÉÌþ"Tl‹ˆúf+æM2Ëj™Y> )ë@©,-¨2­LUÛ '™ œ¥ë,ŸÏyMlO q½í`Yƈ;óet·“8ήµAÉ(èCR¬dÉ©l­»•s ¥B¦æ˜áè4ÏåsÏ0öj•Ì—ÂÂÉ¢ûWÜ/QÛ i¿‹<ØMGWa6oåÓ½"#ˆü xŸ¢ñ­¼¤sHÕ±,¥Lµßv¸éÆlo*›Û¦˜Ü°N_èUÓÂÚ\›µ_g‡$µ_?×9YHXN éèëî¼¹sL§ŸFb¸Ì‹‰dx X— Š’ˆzTn­«?³Ì}?Úèmèt"›X‘±ª§n‡rþÌú–¢‹­ Út„6éz}9;qØ­˜h)ç~±a!cÿt,h#2œD¥®/¸‰‡ÍUÞ ÿ u£ŸZ?“–Å}63MÌTÕ¥$².Cõ¾tüΰ®nyw&åµ+zªøôv.q3Iæ9í«Ü)nM³Òb5ì VÝ«õ®r2¬D-O›w÷ºF3è\¾Wv°Öà~ƒ5nìµãRVëp´a®ÚûJïaÙYÔµ%ÓlE:‹¢FœôûäÑãHñº–ïlQ(fOªÌ©iHø;æØ ¤›7²ó¡¾Ê2Ìãd–ÔBC¢5øž–œjEá­Ô¢ò83Û¤$ÅU»kJÚ1ÿÞvãá÷û_oÞo·o½{ôÍÓ8-GfªÜÞû‰Äì|àê¦?càÜ/òô ›A½dƒà4>}‚¶lÈ ‡)÷©‚â\ŠtíÞ£ ØØ0ThcïýiÙSUJ° EA;~X¶‰½æ_S¿^ò¿À]Ü|æ«ôˆ/šÕÊ‚žvƒ'Çy~”,v’tµ!3èUCZ‡i$Mwm—[Þó³ì­yG{6ê½ÐøyÁÏ&˶Ӈ¼ÃÀY¾}¼93Ë•Ÿ¡ªq À²a7þ«&ÀÜIG V‘Ô†¹·2r!p¦ï$ì˜"ŠÐ2Ó'ÅO±ú7 Um‹zR[~•izÍbØu^z™‰ Ì…wQP€Š­¡Öósùá›]ë7z}º‹´)ÚÆ¾ýI^-×iªª‘:¡›±›Cñ‚þkø?WÄÒIU/s1Çgå&|H>õ†@…7?_W?vŠV7Ãú˜?Õíù‡I¹ØçÙo˜Q›ü¦oæÁüSç!è¨órÔhoi“"­%ˆÛPÍ_Ÿ12h†!tê)ÎÒ¡†®.SÂK8?°‹ôÿ`ŠÆãùÙùjÄeÖP!_Æ•úæ%ãŸSþ$ªìbªíP0+Õ…ICíx¼¤·^V7 _ Öª«—XR³ŸwBf“š-jÿº¥®?‘õY‘Р1ö@ê)î!žxqEPÒly1/:­p÷ ßóÿMò£ÞYRšÒ1=$Ì“¸8ºõl÷î½N‹»~EP´^Ñæ9:ÊÇWw¹án`a³ã$èï(å¼›-{Û!.i,×yIàÞxYKŽAOi°¯=X>. ­»C`8•¶üw+Ö@Q»ÑÞØˆÇþs¹!AcøMzA`øb®BÔ¦úä“öC#öŸ7º:Égá•ÛßsÿGâ哺¾xõº6•xèÏ$~7NÃèj®³P” &qYøi}öвa꺭ΗòÞÎPh‘GÍg'q1'¡kÉT#OkËMç£\ µœ’[q" ·ºŒÚmõcdó «r_Â< Äü4«à“÷b> ˆ{˃#s|‘¹g+ì›§´¶ÚEìzz“ ç—‡IËòÏž¾­£+HŠ(ßÁÑ©°WÅ9ÍÏÒêbcnÔÌ»®Bý°!Žå¨ÈΕ~í")I{—„߯5Àï¡A!­ñ—7­†³2^@Áœ–rÈWTðå÷ûµˆ%ztäL@¯l•‚4™™ù6²ÿL\*9y¨5‘€ÄñÞ·ÖÈçØ£Ð0mNY«bý£ä¢6þ†ZBØ®pÊ|òßCeÚíK¸1L ø¸òürÙ…¥e¢Ó)»ëjßm 9ŽiUš¹0:žOy Hy®ŒÐ…¡£Â]þ!p 6÷צ¹¿H½aµLuŒ ¡„s´’‚V¸¸& hªÖª[@N†Ä^dœ‡¯d-Œ(.6qÂ!®¼ƒì¾Y#¦™gk-XÀ]æd°²ˆëÌTz•»èÒyh6^uH# 6o¯{I]¾žÏ´IÃY6báêÜr)!|¯‘smoNÚ-™ÌJ\ô·E€?Ô%!áÔYðlz‘‹;𙤔%>ÜÂÁà4oŽ£6¶L;j×0aì<ØéIó›ßF>Éë{£ˆ6/šáxD!à:¥eÙmšMª:»¡Î›ÈP‚7„Vj…_޼冢ž‚¼ï{Š#=³€«Œè \s¢ZÂ(Ñq’ê%+Ö)=«çÃ1D!ñØ#µÎk&mý¾á°¿Ë¦»&ui¿½„~–2€<‚l©äéKHVhä2p>ã4é¹rªA>|‹  ߕdžÑ|Ó³…:ÄDðí+3ü†,!\„èõÁÈ5x¦žž‚¾dH —á ÝÃá29wÊ)0ô›fûŠsÒ«'¯÷Vý]>N'Ñ«TÐFñ¾®°Y‰¤çÈážv%1úŒ8Cýµ:Æ/$¸dqƒ&˜YøÊê!©. z+Rȸ&€èSÿ™& ±#Eyô\ƒþÍVeäsK]È$Ó‚¼ÊÓ)9·*fò'ÎN­ë- U†£>ž§ƒÐk’ìßO‡Î©.wÜzÉX»EzÌþ™µ6BÙ›´F¯žì=þîI|6î´(×!ðàP¹ðJâ ±^{å"àùa'‹˜,Vùsnƒÿ!Ü}XM*Ï9Ÿ} D—áÝÚì[ѶønÒÔüœ³ÕÃs• ~•Ù9\-}ä­•¢¡@7Ò¤üÙæçëJ¦[­c!icBw;Ÿnò‹Z•ãì„hfýX©áG›íè1•é÷¿{¼Ÿ¦oùi06WŸ"œk0‡«½HÏ3`Ý ­çµ´“€é—õ Ò²ÊIG‘ïNÝWQ@ Ù/8Œ‹*ÑüéŒ$[B{«Y Mið*|þ[*IÈvtÏ= ö(ùøÑ²¸fðr h…Œi½!ÄQ¥ÃŠ&HüÔ‚À>¶éÌF ;ê@œ¿Dø––…ãóÎÒp9ÞÖÍ—î¡”ÛÜâm?å„ ²¨Š'ÆqYýèÀ¡ÃpŸ-_㘿\ïgã0)püö–[*a(õO¤_×M½®)M晸ñb –F”ú¸1£ÑÛëÇ›â…;±qr"‚mN\±³%®ÛÒ›þ,Ÿ%Éϰ½¾s™v*oÜÆ\i‹ÊœØhË*"ó£‘@n¸.õM—8ðU»Ò7]éc5 ~Hø ,ã`„ò ü£8I+W'+qÈUl SºP·qKƒ¬ç°gLÓDd›3bU(t¯P~¥nVÖY€à‘º F΂!Žtª4ß/EªãHï€êæ늌ÝÂèËžc'é$tÐ17˜e]·>”¾ÁŒG€v³ãEsTW GwÐ9ÇŠO 7ýF¶ª™§²²Á"­ë»Æ`…ȧC®N'Ëë®è½RðBÅVx æ…ƘcÞ±cVóvîïìœËá¼Ä™Ôó¦5´õ—C•K«Ô`(jo¢°²Ê/…©¤P|ý›¦æMšž3wÉ^ $VÍÅÕÃfP¢  qâ,$挅ýñÉ_©Ë§vY˺›†‹.µÃ‹6"9´’Ñ´ÄxÅe;å¹g# f’§à cèƒÉ!"eŸpN ¦‚gwÐìtœ%´ò¯ò¤oÁQãîÐ‚ÂÆb 9·‘’G“ꄘGÝ5Arù¤W˜‚=‡)¿¬œôÖ2¤EµÕOµÉcá0  .;=.ƒEnÕwëDÞ¥Ó°¨†Æ†ÿ\œê¤,nùú‰ÚûîuežÌ £ÏÌá%vðóœtÁt]rÆ•I×Aü±ÛšFè…Ào¾„@½ºrÂã íjxH} ©Óôzب},¿Ú‹+õ°”‰ÍdÎÿ‘‰+žÞµ~AÏCóÄmU­DˆÒ7öÅÏN¦y‘Ž›r}P¿¼„I }7 !°‡ÎDCò¢ xU‹ñ›UaÛ9–@Üñ*¶´U烪h÷€ÈÙ›å¼Ê ØòæFY_ÂËl½AÄvt:Ÿ¾—$·@‘é™_Ó79‚3ÙLH¾JÊlD´•e\*¤*'\Zù²V2 ªcw]Æ’ü4lĈÝ*`IèªÚšD<“% :qTí(ŽÆó¿ Q$(Åà~Ì;tN>¾z„ˆh,ùqßòez.ya¤h3Ãù Œ¯Íu¢ï"ð[`Øq"ÊC{èËívôþ@룤¯ú¦®<§^ˆáÙ¬ÉäÌð û´çY*ˆäŸ ŠÍ0›™kô™{:Éó7sÖ1.î-Þl/ënÈF¼JOÀcÙ|ޞŔ´Ù•äU±•å›ï–}Gßæ—XP…Ä`•-ï+àñÁ)@4Ø„^šq~6 M Ù°âäË]ÈHØuÌ«Ýc‡±JoAÎ+“ä( Éç€ÑN°7œ¼° ׳Bo]Sp޵–Êcý²aVM’&šWx'(T³Ç¸7DÎàô°çA­{›Ájdg-±âúÓ§Î%û‹"cè²Ëÿ¥ ®·ð¼"9²Ü6n ]råt^Ï ž -‘{ÖûgWŒ¯KgÛgO+§°;°iæèLFYJ|¹JŽÌ{:朌9ȵüÙO‡»¼L×M3›9z³ÓÈÓärÄÞèe9Ì™|–|<Í/z^™­Ç ÌÜŽš˜¿yÌhõ¦{:…Ë¥8ב*JŽ&ÁiXçº"=ž0¯³ð{⟡›†åôµ• u¡IÛP•4e %¤1\]ŠT"H•gçÙD8Iù BëC@JH”ål†…?ÎÞ›–+v…}`/÷ˆÍî7®D±RéJOçÜ!sD(wDüìuÃOMʼn3¬HeRt¡³eÃÝhþTí÷T´jG´ ”ü$hÊ™J\ÓWë¨K[X½õqd X7·æ®Û®Ãý¾]²[ÑU–NÆet í‹vt–JmQ?± œpï5eCÃLj(Ñi¹E‡sÓ\Ž].Îg®ì’¹k®B ÈTrEï‚U½Úó|&º“! ã¯ÆÛ«¿ ­'ÝSGi (ĺ‘ñ‹ýè·âíÝxË̳ؒˆÓ㊨ IMû )Ê$ âÒBe+ó3ˆ:. m!wÎÓ¢P$º¶¨û¤ÿsžsâ.$ÞÚf™‰ v$ vŠM{d‡«8AC³åpР-–~Ïg‚D8´s¬ùÒa»a¯ê‡žQÂò¦Cyå,¡†ùÏË2;bÎÜ\‡E– Ü PL ú‰×Ž„Ü)³)àM!´‹:^øDaØ)Ò˜ëÿ•M·àolJTbBò : 4CÍI•žŽE¯×ÑA¸¦×ÛêÐïØ§^†úCw¸g£Š×å&hA9‹Z#ѤD̃@—Œœb'ÇC[õjá¼é@ ° Zâ÷ý€P´ØÆl["<ؾlošå¼ªEn®dÒ·ìf·¼¡( ½”¬ªåŒ8ÒOvç#',‹ã+ V³IŸ•¸Ð49š•ò€ÚëbÕ˜™RAqŠ¢ÈI%„>â’9Ã6Í$Ä¢•H8·=õ²Ñ‰á•Í)nÚš¾«NmI'À…êÔá5»˜jeHñŸ´³¶wn{»GfªigÝÙÚ’¨ÂM>g¹‡Ò´•¦¾« h …Œ&–2ò Õ5±".9ÉC”_1.…/о†šsbŒšDK çË‹î’d²Ï;ÔÈw}Ê´k'»JoÌô›îÀÔÍÇ›íšOW¥Ð>5ßP v»üä ôøáÞÄðxò ˜âx´Öm¬@\Œ\͉ըëì»|/tU0X2S¯éKd²‚€ÏŽÈþÚÊ"@òJCé3g"P-f…„Jð†ä.nX=øf–k “8ÚØ`TgUyYã¨Â,‘µ$)ï„Ý ÓÙt„¼‹.³&›Ð»’zå f§¥…T»dH½ß¿zÖ}£^ÓÜ”3ÃQ¸Í˜QaÍ+? Ô\àB3Bí[.­î·ù¥"2>)% ÌÎÛêR3…ÁHé )2‹­—LàTÞz3HêüÜôi*_YqL²¸YÄòñ©AfÃ\³IHÔeÁ 'Ë‚è]uvó–ð;¨kèÝ$n1i™O.Ô™Ë,ºáIΜ—’™$nId¨¯’ü‰žà„z¤Ëê8†–à2³Ì7ŸˆA™ŸcŇ´ær"&#ƒ†9šÚÍÚwé"Ôïú««—àÐ3ùYßv7 ¦ATÄ È¿2^lgÚÆ¼ œõ6HVßk“Þ…=Ð`‰N‰69"tû-rSBÉú€|,´æªYâÄÁ^,¨=)ó¬ú³ùèM1ÆÓ®Œ²b4?»àP„ÀEÍÅæq$Py5%oiÊ1¨–Bb»HcϽíåÞþ· è=^dæ‘í")2-=`Í”ýA4½ÂèXOáåQå8¬\@{þŒ"$JŒ;|)>ªZSý ÿ©4 3i°Ü:Û:¤aÌ*ÒJæAÒ¤‘{ŽY3eˆ‚sÕá=N(G ›ýaÒŸø=™1b¶ç$ ‚ }W’/ÐѤŠÜ@¦N‰tüÒ´5°>!ÿ÷Ⴣ-2×ïnm9T+Øßf¹}ÈIgÖ×^qNfša‚xW]ý†œP„6ì^ƒpeb¼Ip‘·6fMý»r%)ëêÁZÙMæç`gy®vö«äA[0åb¤'^”ÍðeM]Û{êJµóyyZ Æ6Éõ€ä€Sp#îw™‚PnJ0’’ÆJö9ÿ†&ÿªy&LFuRùÜýÒSû¥µw røa0½×„ô»ÞÁÕ¢÷ª[J×K)í-m”œ˜~‘½€ëжVû6eÞ‡QŒ<5v»UU Õpø*÷ɘ3„éMÚV]„=ÍnAi8ð9é {ˆ‚à2ÿw>ý³¼NÛ…; 7ñS}°½Oh#Æ´ÁEÃÊõ^+°âˆØ N½$x¸!†öÞPGÔô }ú2HÂmw;WSh! ;$ËçCÇoñE©Í,ðiæ×q$›|mYAæ÷Ì%™‰ÃN¬çœÖu@S¸Yή&ôÑïõhJ@¾Ž‘êÞ Ô'lâÞöÖƒ÷¶¶v{„D½ijÛtÖÌÍ£tv™¦ÓMÅ&7´™ošãhŸšŸÙt“|Q;2lÎÚä?0&Èf„ŸžãÐöÂ÷Ú •2|Ñ›ö°1vsh±¸è`,5öÜŠ÷¸Sƒì<.ŽÚf–¿_ŒAÁÅpJæÃrŽ&\&ÍòÈžà,±IJ4 šé¤ \Cuò) 9΋“ž„\ôÂq÷tØñéìlÂ>!>@¾ ÏâÒ±hN[Í ìȬÆ¡pc;wí"rŠÇ}[Ìfç}×D=äÜœ—?:=PÉG(xÄ[Û\üKÉNzLí%߆[¸’Þlæ£W¯ÍquWٌձ˜àÊP= á8 -“ÄJ2¼ào¡Œ¤ÞçMx" žiC'•] Áœh~4P–Ýßö9‘mñ-½zÎy]°S#.—mÒÀ¿Û²›i¡8¬¾Â‡v¡¶iÜϮœ_GC$ Sù¥u»ÀH#>®›½9³ü—æð‹!öþÓúÎÖV',Mx_ù^ÄùŽ¢Â„KÆî[Àƒñj†Z³Î^¼r1fçÍÀZØÂ­w!šÙ iø4 „•2BÖ]B«ÚŒ4—²:âóîü°Äõ†p$LÐÌ!¶ EZF¢ï%……K» Çð’mkgžZ&&˜vžE˜ó¦WÑòÓƒwÿÍ_å?á*l7à$is›ÍA–“œ%SÒKâfî)ÅF'E>?wé)ìÈ2¸äª±Ž+hÛŘApeU…6{å$¹‚Ë#EysCCÌZ¢¨8¾·œk¸+è¼4#/ùJÚÉ×Ý–²¡°‘APD xÑ|ƒAªÙ¿/ƒï’wyw÷£úòßÒz]KŒRÝ †ž>bÝÎ È/ öxG´è¶¿þ°F78 ]*¼h@æ,Fל¿¿Büz6?¢¸ É¿?Vzéà ¤ûÙ²<Œac“ËðèY…4w5Üà (•šv#BùàÈ‚}TÙÕ&Û•jcq¯£Šz·(ânqHõ`Š}\d]…’ÖnÛn:ì: LŠÂŒ-Õ05ÜAm¤T·t¾0²£TW9ôcX2"Î,/q‡F´®O‰¨"‰Œ9¡ë}n‚?:±‘WäÊ_o“6+؃¿!Ç6[\VèÒ4›¸¯p¡`l¥§ë«å¬ª+^¥H ¢Xç(9YJ#]e~E*µd&i…÷ý(%ÞH"Æ©h#ó¿7Ißþ)™¾Imt9•íÄ@1¶5zÊ? 2‰îyĬBá)ž4ߤ(ª Ëfˆ8bT¼¬‘zª¡`æüg3çë¶ÚHµ¤r2Éúþë €¥¶7 ‰ëh=ÀÂ@“îé§£ÇYÁŠÊ.põšQE»s(ä °£££¸bÞã)F.iv,”=^Äc·€  •{ãqzÌ„éo.{0Ÿ¢n|€’Þ•ÑgŸEmÿ*"}9ZÎ#³Úм9:”Ïy f«?¬v“û=Áp=:MGo8åèºm²£Ûºv‘Å29l6ÿÄ2eU5¢õ9=>/Cc‰€ßµXÜkÙñ€qÁjÌiN_CÛüB´ÍÑ­Û;÷wîîŒ–² ¼‹Jy󶜌ÍIv´©ûô ™6qôU Ý»sûîýû·ïß’ÿ²º• Ù¼8¶Ó¾4Íã ¬ÿßåfG‰£ˆ‡Ó €½Yá¡l5ÅYk¦E4xPY¿çùÌ­Ë•uȶ‚^ð½è‘YA`³'‹«ò)¢n%ù8 ¶ã‡#5©–8ÖÛ'UÀ:2xÚLîÖ§¼/š’ø¹‰b¢\\œ­Å[#büLÊÖ‡ÇlÛ™&a´EžßÐÒ†á ¢CÔå¢ÖúÞïEЙvKáÒƒ8­åCÛžO2íÀJÕ˜Bò™–Ñ9J/½ØQ,´–R¼g-½Î×_7ª¹òvk.rò¤Ó4)•»aÔæÑ+²ú ÝGZÌ=iªœb-«‚”/MI¢1ë¸ìœ} åfù©cßqfþÿ”#âáØÆ‹}%ñf b@B%1ˆÏGÔáN'…èqÇpvšãM[Ääpߨxž^‚9ÈF˜«ƒ*r¼†™‚ª*P˜(-žô’ôŒi,ýÝsªKáD²æuØ©äâv¼½oéñ±Ž%ÚÆ 8?[ËÃz¦€ÀÂs€ý’Qv¿}›Mϲé$9*{aiªˆfäòº›™ÿ±£’ç…G2áW͈²i2=ËsÉj­E]µ¯ß\M²“SoJ///ãRžÆYÞëp[e­ ßŒ¼4ÅõÏML¾LÄÁDRZ=¿-"êp× +ø:;™&“°o†¬—ô-Kçì3juޔ酅—tQ{´Ø;áÀÎMr?KÇ={ylº=F§é/¡EÆ7‡g>“0Ão˜ Éù€V¥ š}:ŸŽ ˆ/æï‘~šu <ãi^˜==–Cy–ÁkÅùx–] )ÌË´ul˜Êy!©ÿÆY9šÃ_–sf%F¦†WO¿ú~ÿéóo×ý_~eFâY6JÌÚj}÷t_°ùÙÓGOž¿~BTÃAÃÒpϯ ,*²ÈŸÑú¨{ÄÖ¦ùŸ{ÑwæzOÒIôÕ$5o»À¸É]ó×(nýî7øïÕ“gOö^óüýRm˜9ܺ{çÎï¶ø_õ¿»÷¶·~·}{{÷Îîîν{wMùÛÛ÷îü.Úú5&`Žsaºryš¦“%å®{_ÜoeýS„Ô[¯ ÖÃðŸšH Êpã¢p£bN9:)À›8¤[àð|ª)Ž^ÉO„±goÁfìjŽDåö°S>¾Ü{Ç‘tFÂ|£‚ÿHÿ°Á“+'Œ£úVëÕœ­€%²[§¤bgÑKèfDôô9££9¢™;šLZEò&ÙÖÕ+z03ÖŠX•u°_$†>zêÈ÷ŒmŽ2âbªPuâkBN÷ (

bg¤N6o—ýÙÖÓ“X6i4ÜŠwãm² ÓŸ;CJj\i¼LGȸØÜºÅp9Kþì5}gã±XÜüÝx Í·¾ã)£l¯9‘ºŸµHS¬`O[ õÃu§‹âg [:ë~£ç„}èNraŽ${ͱÇ%7/cɃïB -àßf7ûy‘êâiQ(”8úG2•äöù9 Êàá¨Q†p]œŽsñqçÎ;?qmš÷#)±ý!×Qãßýÿæß÷/¿yµ÷ø¯©ÿ¿{ïνÿ·³óQÿÿë¬ÿ¹¡&ã%úˆn®¡{Ÿ?Œ¶ã­xKü<§<¤ä¹¤8(Î>kmêS`L½É14.Ó(ƒœÙ¢Ãf¼zžTEæ^Hn¦Ñ‹Œaj³3s“dÉ©_Þ† „Ž£VuŸ¬–Õ”«¦ï¨”%³q%ãlÂç(-ÑßRìüg?ÿü«üÈŒj?þŒ}>Œ.“R“6#„Rßk*'7lh¤±\ú_¼[ 4·È`íáçkZÅÚ{­D'&v5R>üMüƒ™ÿ~\îwOÆó³s^zf*bW桃£€{Å,›ÍIvµv õ¹ êõŸQÍæ™‘ø©_7¬²šH«#/j­‡~h28ûm:A4‡º«œAiÕǺœ]ºÊ–m¼ZÂû Þyˆ$¬b†¾µ}wçöj*)0+=_âû#—?€r°ïnNö¼GM 3ô7%;… ¿MÊÓ  ” ¦€Ê™A$ý~:ÕÀòÙÅÊm&ZJ-–™QÕóÊ׆@ѬGÍf:ªồ/áø¹†Ú œÎ*A×!ª¡ÍvÈ¢Æ7°l6+‚˜ÀèPq@2ÃU½ò0s]ü&¦µØQ·×f§i@5΋Ìñ>¥l<Ï»Lã#Ô¡ú­9Úô9¯–.g¿OÛã+$¸êEѯ2}ÔJë§Ïû­`*É}¤lDN²Óèã{ ôH‡:Î.²ñœ³ÈËQ9b¬cEÒDÇ”]Ï› ®Ä¢¹¨ÌÁuƒ®d/j³ >[œI‚V ``J%>‡Qú<`Gc–iqìgÞ`‰—m®ìŠ-`MðÜw”·$°¢ó›ÚÌ úFüqZÖ§_:Hrs:½èFµ*ú7ÛGŠW²¡¢Û[7¢¢Û[Ë©(Å}0Ò. þk P+r—9ŒŠõrÉ)Ü¡:‡Hò¹u©Ä%9­·þ‰3mè™YÙóIÂf^׸•Þy=j5÷82zÂ.ä5%¬3Ðíý)ym%ÉÆIÀ5µÙŒ1öÌ q:r%ÝxlǼ±Ñxv¼Ì¹]ù §é¯~´Çxùto…@»ÒGúcà€rWo’_"<&¬sä×ikiS¦ävµc¿0vò^GëÈœsÃKô‹è½ùFw+ùwÞd.‚Ñ ô©Ô¢yhþÀÎMǪóPmU'aÑÔ‡ÞpLïÞì˜Þ]vLkâÄV¼ý Þ–#üøÉ³'ûOhS 'QrÀ»Q8æÎÖ–Ø…ûTàÖ)±‘Hg¡[­—t«uÆ:’HSyDÚcWÅ$hÒà0¥^—¼‰ÅõÉO”g‘„;ÉÝkùô˜Ž*áÁ1Z Û’Á±2ÒljjÆN?kØ»b>ºL “«8Ú2¶lpdß'oeÐhᨂ1gÇàݼˆ ‰‡1SSªÖ«kóâÝäƒcVŒÀ ü¾¤_›Õg_-®ßjm"°Í¢óo“­.ù]³tÒ o4qPÝÍêZ4CþÐhvV¿fS–*èÆöÂx}D»«­§tNiþ:9ƒû(aô¥ÚÒ×' \m2:µÙ\rºÍT€bpÊimâïwµô}Þbb˜äXaŠ)`T·ø¬n1†§®°mÐn’šüîÊÉî1T7öìà/¤WÄ-jRº§9¤q0ÍUTV@©Ê=( ‡<Õþ€ÇVBˆ9Õ&ei¾rAæà¶ÖŒifq-ZWagÛ5Ê»»{#É¿)å½o)¯'‚’CœÆ±¹Ø0\ X[HI‡(4T(rR3”iRŒàÃŽW#OîOZؼBw¶vm³R„ SÐHB.©—® •E}N»#YÄýP*QÙHnW¥Úʤƒ-U.…FSjdvò çôµ!ÚmùÅKÌ ¢qD"S‘ý¾9ê›18,q× è[9P]ë‰n=ü\ÆÜÇ %œ¨Oå]ì>»„…ËsÃW‰ T‘$*YX„z/µ' ɯËÂw MnC†–KûaD“|”Q–/›ÙBÑ«7âÙ8sÈ‚ä3­zz/µ]«Vlª¥$@~¬7Ùù9q÷zâ¶votâ¸åzÅÎØÅc ÷è:ãT¤— ei’_Ž7Gi½ˆ¥"Þ¥Ðba³ÉCœε èîÌùÅ•¸B¢rÃ.™ƒAã±Ú™hGg—¹÷{(·i_=ÀìÀ4ǰÓï,½jƒÁeî_#… Y¬K²*z«x3ÁrwÁR/Oÿ‚À7ryg¬£ÅâiÌí†dHêÚÃô¬½Nge t¶ƒ«ÖžÈçn0YwâÖžÞ8Te8Q4šqF ó¬<%˜(ø Á+HÊŒïC>ÀœÓ¨ÌÆ Ûï²o)þgRáZp2“WGß «3)+g<)õ6p‘ƒ«\…ÁÅ I²YÀt\Ësl­ÈS|ݰLƒÅÌæº½s£Íu{§³øþ½g-)JªmŸÂüÊÔm8¤ØüŸ‡å)Wç³ýä€dkP´fi,mö Õt®§Œ*¬£Î›rñ¡V÷ xoR"k¯ˆ·ì2íÖcŠ,[]:ö'E5ÌíÙszçÎöM¦Òçs:½ŽÜúÌÍÂ\y¤#“es¢sº^Ëhfœè ü çÚÁThÆ0᮹ Bd¿•<-tå@þãÔvT$R4Çãø˜ÝtsÎpY€´3Cët€ÍÝ4-¸ÚAbêzZzÓ}³ËíÎu—ûwÙœ–ÙôÏœÓ@¦+ì-|B=„âÊ· »ì{èºxw^I!wSš¶²bŽ#ì6Á%Êó‹¥AÒçh¦ ¾ýh¡öâíÎ*ç «£H=„ñhõ}fu™Þ›êÝw68öðDMu‹©Æ]j°Š±py"èHB"6³ þÁ‰W·o–xuVmL’ ½/¸·¦¬…øúÐb5èfQhž)êÔ²Hóî.Ë»»àóp¶¥ß<Ùo{2ÃÍRºÏGÐ'–„iƒ ˆ—Xo޲O‹ Ãa\T¾˜þ<'½r©©NùC Ø1Gu>±-$“¶+<ž^Ï ›t–›“ìqFƒò´ð/Å·Z¶VNµ3Ê ¡º¸b©Ã¦®ˆê.w-oˆ_¡À“9”›u ›ÆnI_ÚßÑC©B-eýï&oøòðBäÒºûØìPàÏs"ª"M}¿m.WWG…×b¥Å¶¿J~+Šò‡I†žv=éÍòÞ·kY€tЩ̬[§q±â$¦¢ÂpD{À`ÃHŒ¯'"ÝÞŽ·˜šŽIk¯ÞÆdbÚÔ$LÚ5Œºœˆ†‡›G—…Y]²«`“Ì-ú”ǶGìé·4À!y$¤´½H×w VOSQ\˜ê(1ŸÙiÒN„^› 笣NY +§²}ç&gÊ_N ¿â¬ð¥sˆ“Gàª`øë¶Ms5†“"ùˆ½ð²’ó„­B™p eµ]Ú½ ÐМÄ:–´ªF*W}7:ʱQ=ºõl÷[§7²˜âË×éUʾg¥Œ‡œ9(E#Ðô =64þV!å‡t°˜Ùpi݆8Xf)ˆÿ6Kc挲{/(±Û§IÙ"+‚â¨7²¸Ñ†7®ùûì\ÍÊ´`a§±%CÅt¬©’Õ#j#Ò%™ñQ˜h“,’ê':¹òW7ÅA:%ŸžãùÄÙI)H4é™õ${ õ–êfGêÁ›^S;Má¾²W¡*[1ˆõ+áÝcŽÆgÄ-§ª´£«Ð¡©Ë †”¤z`;ýñ¢¤‡ˆÑéa²×°1ì- AìÓN ½C—XÖ³Íir<’Â0¦_Íqª>H˜ ¥ÅíÃö“·ç0´‘ß%;Kãd¶¾Õ‰ç³‘Kø|U• k¼Ò/ÐSe†î*#°óà&ûØ_¸m¾Ü$âËÄøæ+û'Žˆa¶F3º‹Õ#'ïns6§Ñv¼ß±· ©ãÀÌ•9»>ÅÕð¶Ç%:¢…•„ZU¿•ˆ!äˆ6èÀ©í[ù3“w.AÐí²l­ l226 ¯±uf>í\+p›äÔƒÃE"ê¾r[š$˜Esz`K@xô8yÁÜy¤ë¦Vmµ‚¬(#éàëyï9”(€‰ìÊĔɈ:®Y‰Ä;&%Ûv 5_âC©Ô Õ(&ÏùÔfð¿µ)v¨®°oÖ)Áw‘ñr £˜îp™}ð"ç B®4ÔÙ²¡#–¥S-YÞQ–‰\açåœî¡ÐGÄMT’¢![‰¡4ýeñB’Ñ‘ÐÜf‘'Å­f±iL¬`¯RX—v×ꣶV²ÁÎíNÓoX³Î?¾Õzéæš…Z³¯‡¢»µò &†üñÐó¯1üC‘ƒ®þàSµÊYàl è¡rƒ£I2}£éѯuxIHÓêŸve4ý¨úeüi¯J=ìÞ»ñ4¥¯c×X@Z§Ü¤YÍmM§\á¶ôõÅê.bv Øok¬aü £M¸u«{±ÉLl&_á¬%•æå>2eÞ½ï:R`†ÃåÛ´ïrk°$iþÞÇtªÖå|M)×t8ë<_{àºi[íh—m¿:¡÷HÀM´ÂÙZç4ÞŸíç9S„¼Çín”ÍC¡#<¤l}Ü.9úÙÆûÍy’‘†š6vê¬CKVáæ} ¶WmÒZÎI½/þ#¥³²•^º«¡}½ýƺB¬íŽ8òÒô£>Çpª¯QxÙR¯eG¨¦·Ü/3ž°æè=÷SÈiÅïwk‹%ë½/¨ï$®p­Ö Ëõ ¶ÕµÕí/ªrãÆÃ°P C|Lsr•7Xqœò22çc—Óe¯=ò’L®aMÖ\G×Ì¢Äp(OuñÓŽOfîßp#Úlʯ¬àT÷`\F¨ÇÅMëpñ[‚»åéSÅÂÙtrë&Œ¤)Ýá\çp@à>8™åÄ(X"iºÌæ<ÌÏñ˜m”[]y [™žL8—­vÞ 8—àX‚º¬a »ü°ÔÕ'e¨TsÙŒ¸Ê!­‹zƒÒF¼¤H«X^ED¦3b3Ÿ¦f‡¹lÁôӆ˼˜H QÀµÿ‘ÝBY˜§nÒ©Õ£o‡ÑƆ9ú ¦#7}j†÷eÌ¡íúköÖ #¸m*Ã&lÝÈ7ÌWãÁöÍ4ŽjJ¨Å¢ò¶•÷h‹T¼M`qBÙ|^%vŒ2£2ò«+†’ûVå_ÆKŸBE¨P# …(‹DG轤1‚ËÎýüª+š~v®6`…%êØ»Ž)í7®?¸ÈüûϹ|Û' »»7# ¦üuÜ»:²ƒ ´Zÿ˜^y¿±ß±KôŽ@l սр{‹{Ä]úÚ<ç8.¬yb¥Aâ~Z-›˜Çªæê¥"¶O®Ô ©¨˜B{¼/Y%D T&"0s&+(•ÉÍRŒÇš]Í÷˜¶óôàF§èÁÖö5óD€š÷„°m <3Þ²÷Æ8@b¬¼ö|C1)YÁ•±& .½^\Ž™Œ=öÆ*"„Ç`>ÕEŠUgWrÐÌ|Q¨ ™†ï˜Y¡ÖqU“ðÛ â5è3v{'ãÆ÷îýÂí´û7‰~4¥oª}Ûª…à€RꥳÎßfë3&‚CȦ3Æ Lëb ì£Ë?iˉœKÓ>dÑEj†ÞKÏuGdÊò’@-¹îg¶Æ“OÍM†ü…¹‡ƒ—æ¾Ã­hØâð½<ìîç{M‘zÔ‡)8 î‰{:ìø zjvÑbBT^MgÉÛ> $Fàñ9[£ TüY®u[Œ~†´`ù)v€“d´»âÚ2ËfWýˆ\ ŸàG––ò×U×Ãר‘ •j×BåAÂ`ÏjiÈ 5?ìÍg§û0ê Çh'Jóá’ɘ,?t»ecî¤TdEoÓA-âÑ{ᇦıdl1­Ñëƒ;[Ûæ"ü~ ƒr^dIáUÔ§D%»ú‘ˆ(2›Â¶ê_piS˜ ߨ—.¿ì‡"ƒaN— ²c…‰FüG;4¯ØES+ÒËþJ3 Èc»ìžôÎ]øEÖßý ’MÕÿœT¤=›RÒ‡†ª‰°Ù=u¸ØmŽ}ˆ_ÀÈèc×¹äGTÃÈ=C†¡Gc¹ï‰|‹]Ä÷³p–L3C'voø%emõ"©¨ ZZ~:ì‰<}mhŒ}c'è8*ÍóuºJ"_­ÕèÇ¡¤Y\à zW-ÇÚšOø ³¥ý_> Ÿ—°82—e:9®Š8ÈùÌa‚MÄ,+ýÀt Và kCV2¯ŠþHªË÷“M±Ñe‡'òðCŠ3Õ¶c«áâä硌•à]€°^Èp=èÚðf=àë8›¡t‹y¤_eùƒ#E— öþ#Ð%Ãìpp˜]+hø²}.ÐÆ_>åYk\Š ëëÔuQ3WCÌ7l±3QQ‰·†«4Ø Ö3ß.$ˉÖxIæ•èI‘Á`-fi›9ùéŒ-SbTö”Ç)çUadpªäB*QŸ ‰q9Ïú Æ»d¾üÚ­l4°ß?Œîì´Zš}X®œc\ƒJQ¶ó}Yj=Ð-àSÓ×!ÎSÃï)¬(*ß\+ƒŒ¯mU³}âæaÔqƒî/ g{ûîÍ”g·ï6Ù51©ÿƒMÍHûžŠ’Ý(ÑËÀZ>Ø‘÷g=M‹l&`p ¼ê‚ŸùòúsÛXÊv@}›‡]ëîJsp‹Ç°éPvÔþTʯݦâù¸Ô7éƒjþÁåÊ^“zÉ;•£jù&–WñPì#u¹û#9ûqF;á$±V§èEf‰Ô?e?0­¤ _]‰XÀ ­ÅÏ¢;ݼëä\™¯qÞ¼‰ª÷•¼ )ߊzØEjØeN¿Žôe¤1¬ŽaXâ&–jM»¡º´»D)ª¸–FRÐú-ŒÏ5m@ߨ²zBêWÆ**®DVŽçÆ}y®Åñ¼ Ϭ¡o`–Ò]Ï£›»2Ê s¸ç¨³Zp˜ÝºNýsy³}…†CzHiÃCI¾ý¡Èê»ñ?’›:õ5õ¢1kîu”Õ09›<ˆR5â`1iЇGüIà+ñÙêf較/ýQsHì;Jì)“.ÇÜCt¡Ý­ªq4Iþ’Mx1p‡å”è¢ZfJr„ÈGKÂ…˜è%W¦‘r¢ÎÏ#pŽ l÷õñ"ÀL{gÈâÛnÔ¿:„=ÔfN 7ý¿ø1T^V.ts‡įè9¹I'´}¯õþ_ªn÷·næ€sk{e{Þ…&­zê­B÷*ÖCñÑÕTçV¸Jf ô©´9xÙzò§(ÍÍOPc` ÇeØÃ †ˆ½—`x³ì€À†Š[)9~XçlšHã“ÕâïÓ¢l 9ü:$>îó5øðsä„€ã°÷ n‘äÿ¥¹ Ï ù†tÜ&²ÝnUÁï+±•þwŸšÏ6/jßXQËulç§vlgQÇ Ë°¤o;í…þvÿ†èK$ù`é†ß<Ùzfš{;½ía×Éæ´Ú ¢¾žV*Jó †ÌSjzáNɃû7;%î/5“4h¥4¹ØBËÅ̲†¤Ëó•Œè TÓÃOTMŒ~6.-ò8; íÒ2/ðL9RâúEú¤}³Ø£ˆ¿öuÍ¢Sà£"âÝ+àUTN‘}ù²ÈgìZW/QÓ×ô´ë'ᘠªÙ\Ä,“j±³÷Q?ú»ËuæŽ8ž(2*¸Þ{b´lxïÌyyp†y™ „GZ¬bäҤq•‹pÄsÄñ!ÐâöŽð9R¡®²ê­ó óÉãÝïØ*éw¯íˆl8ê;™nR€W3ðN~~ŽÌ#yÑ Êv`ûbÛ%Oó‹žW¦C×™æIÄ%d51ŠËœ¾… جÃÌ($t³Ã$’GÞ[5uá¬HÓÐs ú\õ4…8¨SÀËñ†ã6å"%M¸Ç™*u»·u­¿å7Žù3¥ohp»×DÚ¬P}kíö õ”³Ô ½.‰À†í6tÝ.ˆsõÇoãYoY±•{E*š7öôAŸä©å³ rû4K M,F§WÔK÷´/J¨†ñ­ðžÄŠ©{‚Ùe¼D´ÅIƒeG>oœÄðI”ÙÍÆ,ý¦6ü"hÁ5(ýib§ù2­n¾.1º Êù‘lÉGßìF‹>¾Ñ’‰Λ˜ÌMékœ8¼sŠx,"ű 1zdöëÂóÑ…gXíhᕌdvgë¶7aâ^Œ¼Ä‚_KÌÍD­_ž#Èá“5‡ÌC}cÁÍTçk’Iô;JœdI’f76…%AÅš©(kÍ&ʶ)±•à µË$ X» CA&/Œ˜À‡KA–œñ,õÖÚS¸}AÈïTÚ k8q]øÒÙÓj,nîP]®Ù[™‡K,óÈ¥>1×{b!ŸC¯îÚÇÀ öñÎî n"Szõ}ìÔI'Àš ŠN¸ºŸ‡äÄe‘JÙaÞ—Ò^e ÕŠžˆ‰ ˆÊ%w%J,“p–ëC æLØ'ŠÅ~U}ØÆUˆrp:À»Ê ²žÊózf ‰AÆ&gGÙÉÑç”`ÉE²Â([`Ø« ÔgEþAÝÿîP¸Fx!ÈÅzƒÉžijàñ8õÇ”‹ˆäd'9=>P¼,A=5“&µZºÂLM4ñÜ" tÔ‚dÕÏHé"€·V¿n6ž§%æàâvœM%}´J«ÉtBv …œ+³™×4‘#ªåÒ‘c]I? ç…µl¼Ö¶!ͬaù×Ô§aÍmólíòÓ©¸ù¬Ù½²™7ót­/†÷UcD9T_"F)b_»d\K›|ÃîÞ¢ú'æçØðzkÞˆÚÜÙ½LOé¡«ôdÛÜ⳩ŠßË0x ˆÃ¨ÿ6Üì rìò(–žHÕŽÌ”óQåµM-µäÐER›0yâèO"ÔXˆTÍn€ùÇbþ{¸:‹gZtPCTo]ä²#¼Pq€-¬9¢~à1ÿ…mŒ°T>CæóÎJ¦Û;wwn¤2åÍùþíçg_ç¾ *VÔÞ¬…öQ[._3( »‘ôãò}Ë”AÞm¦;ß™‹M³\™çCÖÛ=D°QÓRS§ÕÚÞŠa"b•zÔôâ` \õàÛ'{Ÿ¼ºõ.{¿†ùööÎmIþ•Ž?6ãçOÏK|lþ)<¶ÖÛ|ì\&_8@‘DbZð†õkÊëE¶ÎÁ(O‹QZütŠpíù¿w;<ÿ;[÷¶w>žÿiç>ðÙ ŽnzGd÷߀„ùKHÏ•$Qà€q:ƒ´„ËIȪ4â jí!cîvCZÓ¹Ñù¯;Gೊ€$|Ÿ›$œp8XÙsyQcyökÝÿÛ;ww*÷ÿÝ»w>Þÿ¿Ê¿[,'4/$“É{O¦ò½ósˆ ɤÕûv[YdðÅfŸ”q^œ´[Cè¶P»«G²<6Y³1N/ÒI~~F@Z}ÊC(ž—¦ž£9<¶õw‘¼IÝÎçú³ß¹‡HEyà Våî­·ã5p2OŠq;øµY@W}&méÓ+ÿ³D'Ç>±ôn“èv8’â<…=«Œ™A34ˆâ0ˆi+1µÎß̽½ÙD ®h|Û½¥¡ð›ÛÞòüM–þ9)Âz°2çÁŠ‘ÉŽÛö‡Ã£ü•Ñhs 5\a;³mõêÓ0 éÄyÈ—¶ôýxû^½¸xäža,„ßÝǵÓkÿ ¹þ–þUèÿÛ³ÉÏNþW ÿUùÏÿ;éÿo“þ›-Ô@þñô#õÿHý?Rÿ¿QúOøGÛñn¼óëóÿ·ïVéÿöí­ôÿ·FÿC„vÑGjÿ‘Ú¤ö¿1úŸŽOÒ¿ÿ¿[ÓÿܾûQÿó[¥ÿl=UÒB?Þï‚wÁß8ýÏ&åàöÏOýW ÿUûßöÝ­ö¿ß ýÏøxß6Bäöƒ¶»6G@¦Ç«Ï*üã…ðñBøx!ü Òÿ;úû^þßþHÿ³ôÿŽ9øw?Òø4þ#ÿÑÿÝ¿úÿÑþûÛ¥ÿ»ñ(ÑGúÿ‘þ¤ÿ¿)úÿ‹®×ÿ×ô?»w?ê~sô?)ÒI¨ÿ7[ªGO?Þï‚wÁß"ýÇ2Æ2Ý¿P×Ñÿ»»Ûúgkë#ÿÿ«üóâÎçåiD!?éÛód:àð­ãì!ЧÙ JÄOOu ‘ÿ&=ë÷_.†`ÅŠ‘G?RàK¤ü{hC†ðFÃ}øâ?yõúé‹çTà|’̶+ÐÔKyÔï¿úþ«?Q)ÎYPJ5íï²Ñi’N¢¯&ivrÚ>¤B”†ÑöâÀ9*ô%¿³qš ôWŠžæg)ÒÞI‡Wæá”ó3C»¯t {úD¯Léè”Lþ˜r°gŠ+õäõþ&ÐÓXÆ\‘«O5Ô`šÍ6Ô¿÷­â¤H“gfžR8£T;ÉF)2>Jÿ¾{ºO¦fÇ〩Æé9ŠNGWλësXpävY\úŒ²Ÿ%Ó)OÍ-µuÝ—t510Âò‚É ¹ú~yÑ‹¬˜ÍKÛûkû@+F„J1È–Ûµ³â ½±ÑÛhÆoÒô|Gï¢QìG>@øó‹uüo‡ _ËwöÀV$u€æö¸"*$çŠ^I'ïð— eú>=ùiÌrú¿½U÷ÿ¿½}gû#ýÿ5þý/ŸóoZÿ ¶×¿yúíãW¿ûÝ¿úÁüýî?ûOÍÿnßúg ù¿ž=ùaö:?ž‡îw{ãü(žžšø*MÆWÿô¤ŸýîwÿÅ«§÷ößþ?ÿï8,þ¯ÿó¿üíÿûê?^þëþ·ÿ«ÿü¿ÿá_ÿëõOÿ×ÏþÃ7ÿû­ÿüoÿ§ÿùwÿËò?þë—ßüéûþbøÿ±÷%ðQU×ÿ´jÕ`­Ö—Z¤230  #DDÙ$Ä8N&3/ÉÀdfœ7Cˆ$¸תuï¢UkÕºã.*j-îŠUÔ*Øbݵ.µ®U«ÿ{Î]Þ½÷½73´úûÇ~ª™û{ιç|Ïâì“O}ã³çN~fíƒÿùÕÕ¿É]uï¿;&|¹vmõÚøv›6¸c&^pÿš{ßz~ÃëÆÓkÏZûäÓ·]´föiÛâêAƒ>¾t÷ÿÜòìå§ß3¿ùñÛxî†{† jzø>2w?´ï™ƒo»a]ã™ÿ|‡u¾3WT}ÆÐæ˜ØQqãÂk·_5~¿coùÑ3Ë®9äÁÇœL]Õsjjö±æ‘#fß6à˜)ÿv㟶|öîÕûŸ4|€qÈ™ã/ºæÞuÕÕÜ3èæŒ†ÚÆ[[¦>è“Lüý+wÝ”<ëûÿJÒ OÚ°j`ðŒŠG|oÀ•7=µ¬å¤ã°ò)k§ëÜÔ¾tâÀ‡Nztçíîûà³×>~ΖÏÞ2ê¯/¿þ/× \výö'½Üø»×Îß¾î’ðú™ HíÖãOn9 ûÔKŸ?º¬çæIëŸbØòqã§Ý~W-Ã1;®Ÿ>$tÿ9[Ýz@ã÷L_PwÖ.‡zý€[¶MpÀ€ Fí@–ÿ_«£þïwqwÏûâó¡'¼ûúÝæûôº›wúÁû¿ûøùO–~'óÂô×øy¨õ w^š¸×‰æî½|ý6Ñßn¸bBÕ÷¾ÖöùWoßSÿÃ}ÖxϬ{7üæóE½».ýòÂð‹ìxü!ÑôÊýþý#ôèkÖ\ùNã°—†w ê]ÿÇwöÿâ”s6ôÌtƹGßvvûI¡-ç=“k¶ö¸i÷•ï¥ýxÈç ž?á?G>ñAݯÞßóÖç×üóØWŸüÅËVŽyÜ'‘Ÿ¾êgã–Y×¹v`nÂÎK>XúÌ+uE׈Ìý‹ëÍoyâÊ•Òão{yà—Ÿ»û=WÞ=òó;¯žÿöM‡…¬ŸlгâÁ®ÖÜ>u«KX°îõÿžÅæ7Ö¼wð} ×Î_öìõ‡ï=lþo?}Ù[Ÿ²ßªÆ…ƒî:þ‘¯Úwí,ÄnysëÝ·üÉýn˜òÑ‚#—.xÙ1÷´åK{_ºwúÌ-/™qí!sl«¿f¯åçþîƒ_ßÅ6_ì±jv￟íþË_¶O<ý£RøìñOWm‘yxÒç•O¿øƒc/¼ûö³–?ÔÍwl7ö‘ÛN¾ë½µÇ^>,}ÚÉG¿wØÃCÞ8øðÞíò³u?l~hê3ç^\õD㘟+’§,Šß÷ó/üì¥PÇá[Ÿ]¿Ò<¹É¼dÄß[]¸­³g—×>¸ðŸÓWDz4nÜá¹W4ëø_|±æ¢]å¹{–ÿþΖ]þüêèÚ¯¶ø¤a:dXµö•aǘ¸áò§ßþçÚOßÙíÕÚ"ÿcÏç>öÕ?w<Þ<óÀ•O‘¼bÿî÷Ò‡µçí›\ðÄo^}vÉUëãk\ñ«kwzô“¡¯îU}÷Ÿ&Ú{pú _^vÓ/.8ñô+nzüî-¶8þìøòKÍÖ~þè¶}æ¸Gß|üØ—¦|ò±wø6œsý -±U =þé3ÏŸ\óÙ˜NzzÒ¨v¿îЯ^¸|ä‰3ãOnë[÷Bfí>ç_:æ §îû`×ߟ·õ=W¼{þ CÿØ™ÚëèøG÷~ô°K_ðÙcznúÖóg\U}k¹è‡“oÙw׿oùlÛ¿/<~Éò»fMó çT»læ°yo?—ŒßóïqµûíØ}õYÿ…g½tìŸ]søs‹‡ßã/_é}µò°ç.ùÓ”ð1ÿ~{ýî#'ºëüóØ-±ÿÙ“Wyç‹g†~ùæoŸœ·`õÄ¿š«sOmzdÛ ¾AkŒ§×…Þ{ë-ÿsñ]'n3!ºÿvoœöÌ /|ôï¹sž×´áò½OiÝ–wRkýqßwNØáì5«ëî\öØ1ÏØø‹ýoºvøï޽ïÖýyõû+îýYàŒq³#s·¿iò°õϾõ|ûoW~Å…#ýx~ð±ÿ>³Óu?¿ù•?<ØxKd·ÓN>ø©Ïwz~ŸÙ»­šøä•ÏÌÝéÀ|xV÷Þwž¾CâG·×<½lAï°½N;ñÎõÃÞ¶~s÷»ïXu'äwì˜ù׊ßþç—w;뀿%OÝqü§<ôìôºŸ{v!üÆ’ýÎozóÓwm{ÎÇúŸpð™+OÙò‘Ñçlupë§÷Ÿ¿¼åöWïÙz—Cgyá}›pá¯ß:tÍ%¿¨}åªqŸ¯ºòO#·¾èàêö<ûßk.þïë—¬»ð™s~ã%í>¼ÍÛÛ¹òâ »lùÖ ©s_;þœK®Ù~MËkϾÛ1û‡µ+nzèÙ·CÛÔ^üàýñÜ£ž¯8ØøhÍž>nîmüà̇çùæMm~⣋.ÙsÉ. Ö­ü×…·µ|ô§µ«Né »ÏàÁ÷ìÑùÖµÆßÿ½øñž·âw¿ý|Õ -{|´÷©þe…]ÿzË™kφDzËÇv~¢>ù» &êSó§˜Ësǧ»mž¾<󫚯 lóöáýÞ?¾"öÀ¤}Ÿsð{3FlqØQÖÀ_lÿµÏ>;%»à²³¿ ^´ðûk«¢“v{ô¸Âa·Ç½å_{;¶{×Éç˜ìiª0›o8ð¶ø_OmÚuå’SwÙgÝÓKÿñéœ}Fö\ö“ꪗ?yæ7­÷Ô®]ýÑ’Î?w^6͘4oÌŽÛíöÅÏ_òßuÑ™‹^¼ïÉÙA]Ï™;Ñ;èØÇ«¹è‚ŽŸÏ[°wuÕêK¶xsLÃþGŸ½~ÍjB¢f¿»ó»ïÕzý…3Þ^9í±³†Ì¹ýÐkoîz¶f‹#zV¤z_Û~í1ãfouÒVó}ëÅׯi{zÉç¿pÝ^0pÖ%?ž¼í†§øþŒ}öxé­-[iþà ;ü̶[Vß|ïA×>ùÈâž¼¿ë…V _öú+;n|é¥÷žòåË·L¾óÜmîþì³Fœq[å‡$ÿ¶ÍïS«ÞzÈW»^séòݶ¼û¢‡Ì±õÕ‹×ÝÞ¢øÐ·v²nßvÒÕ#VßzßA—åÎ9beç’ìyÛýeøŒºª{&'ˆì~ÎCÿøÚ;'¯«òª—›VŽ? ¿ï¯¶®Ü]¨Z¾ýƒÇÞøhç„¿nÙÿÌ‹~¹ÝµÛÿl×ó_{g—ø¥·ø^zÐ# £¶ª} óÉ…Ÿ—zôÂËÿvä6?1¯í¥Ñ[6ó¥Ù3Go=ù™ÚÉõO]ÖyðêÌ[þ{·E‡¬ðþ3¯ý-yÙ.ÙáÃ[ž0ðÙ/VšvéKÕËfþùÊêO.ÙýÔvœþÚèòG‡Õ6ŸÖ}PõE7œ÷ö‹GÜpß?ºÆîtfyáýsösêŠ7O|q¯[¿×sýÏM <þŤV¿þMè[ì>pÁ)ÏþhÁu§çw\UóÉ“üaÌŸãëNŸôÙ[ýíÌõ§DF>¸ÍÕ?}óã/„·=|ËãOxä“]î?ìù3º}ç?=Ãøõ¿Ï~uʆ᧿ÿ Ùs‡¾3ê¤sn;áúé·›ðë•g{Ml›·oýÛß6ÿ€e¹³~·àÆS¯þÛÙ_]¶òž½gŒ3' ^ñÁ®Ï¿wë™+?‹_öÒa¿N.ÿÇÕ§½pâ¯nzõé[·¾öÕïXµÛ«m‡zìÁ/½ñ¹×Ž}'¶üÈ3fŸÛ|ï¾ÇvØæí{>^õΧ§ÞûÃûj*-ÜrGïâ7/­þQ°íÌõÇ´·Ì=®{ÃôQïþ¼â_z7sÍùßÛsáèûxýÏO½¿éþ ~pãÔ3vûàûs~ýšÀqƒ¶\|ÁC»>°á¾ù’—ßuÕ£ß\=hü~¸wÇvc×|öܧ>ö´ã§ÞÿÌc_T Þæí—w­ßû¨Cv:êˆö¼ÿŠÃ'$¹ß¹·ÔÜxÿC—Ý·ÿÑÛ[î®~IËO¦ úëêï_>¹e§Ïlþí»_8¼sX:ýÌWÇ lž7aÄ{÷ê \3ðÜŽ9Ç^³zÄî›߸¨ÿÅî?øÏáÑÇ"‡^ñòo×t]óeÓ¼£/nùü¤Ë»aÀˆ7>¿â·__sÁÒwkZóêÅ/4ÿ1벮ߜtÇ“ùè°!_.;z©uÒ÷VÜv؆ɣ—ÙòÆäû]3sà®-·n{îÀk[×îÍié_¬_6p}[ÇGk7Üõ^þí›ïùËUûïqhê§{ì:ê´@wû9ƒÆ¯\µì'©ºw<úÓ5¿üÕúÀˆmÞ¾ùÐmÂO<>óõàN»õ|¶æðìYÛýä•uéÃëF=œñÊI‰àgç|áÁ»^ÿÌCã>úò•G^ûòë÷¼î¢¿¾¶lÑÅ7±®þîÌ“½ƒW\Y=ï¤[—†ú±Ï¼½zmë_}ÜÝvü•ÝËîýþ[uwÆ÷O´ëN¯ÿúòÞûÏsÉ‘G<¿æÅç÷¾êâ'øó;«|å£'¶ûÅwüäéƒom_ñÞc½Ç¼·øº¥‡Í:¨åÍ Lûè'¾l~KËúÀ]{žúNïìGŒ&¦®zÎ_××ÿ÷±Åì;v`íØÏ–­é}iq,±~żSÖ_Sñ8 {hÝïÏþwè¸Ù{Þ¹îÝgwøô "gäÛïzæs[¦ÒßZtqàš1¿{­zyðœûÞœ~Úu[Þ{Ä‘/ÙwÎêÔ±g^Ýë7|ðø-×™têÍçqÔCÏþsÑ%—ßiì¯n8æÝæÞ½ôú]†^²â¢KÒçbÉŸþ}Yþò_NM¾±ê˧þüäGÿtþešSûÆÂ–Ë?Ý÷Ž Sžù¨öófóùYó…ôy{í´Ë—\÷Ö¨|oÔÙß»÷ŒÑ\e=|çV‹ª{=þÙØ{îùÛqrņ'D¯Y§-pÌ «wlsÔû­;ë2ÿ´žwNøçÄ«Oú0üÀùm÷>»$»j«çîxÈã[Vt›O­útÅK³» è­°}íò.Ÿû«Õ™ÎW—_5îO=ó®ëzn‹Û?uØ‘åîõ«{ÏY{Èûëvy~Ï—ë>üûnùñËÕÏ,9|þrï)o?þó)ç}ñÇÑc?8ûÞ×­»ÞÚí˜_¾ôVõkÓþuöáÁïþäÆ+o˜:j§?ýæ-®{pqpÀowí®«þµ×ìa² 7è¹§£>ëÃ3gÝýð‹+ÿóÎä÷óÿò¤µ»^³Ï5óܵûÈ›[Þ|ôõ;~úÒïºóÅ55ÿü·¿?lÄŒW<ò£mFìuÀí/ýyËáÖÞ+ž[þÀ [ŸûÀÇW¯˜½ò|ÿ ?¹í[§½uÔ£7½~ñ—Üý‹‡^7ÆÿáÒè'[Ó‹‡ïyÜÆë¬Œä—¾{\ó£_Þ:ãóýæBÊ´†™S®›Ôr\ÿ‹ÍæýG„ø:€ËÓÿUU­Ñõ5ÕýþßÈ?â)'•i‡—\ûm‡:î)?G ½¸šÌµõZªˆ;âúÅŽ"}¶L¹ªá2¿ýÎä•!žÉ™QsI~$XŒ„hQmm&€êG)ºm%3­ Íx~dk*–^TFvÄ|É‚ðP¾e—ë"¯ÜÑ$à¡ã —["Ñã-³o…(Fp¹¹-xE*73¾AѸ[ÞEÄ+LÒ´`ŸdR™XÂ;{:“Or­ÉÑûÊû$ߘվ ;…½UTL#9Cоºãƹ?Ò÷½T&K™#Ít¨Qnì'Q=º2‹a×c‡i1¼  ^–Ì9qQ>H÷Ç‹˜GvJ ]¬%cDÍ\…–:3ÖiZÙXÜÔ?ÌE-m2šˆXZª„Ù¬÷À–iŒÂ<z˽ÒgÇÈ~Ô¸¢c¤‹ƒü}¹O¦Èœ/öiy¢±¥LdNÍuhgJÍ„PD"[·óù,Å“.µp˜ÉuåäVipyK n&‡ÝæÈØå·j×ñ{=—ÊóÂa6p”l÷<®Ÿg$ |éb&G£Ø»ç˜‘ì4›º³¦ûW×’ÓÒ0îµeØçy”p˜î­ÏM/JgºÒ"±ûçYY·Ì>ŠðîíÏOæ;hyÒÑ9& ~›wäg: Å€843‹€é:SÁ &‹…‹ÿ°½*ÐÚ­‘´D-È%Ôç…ïZ¯³Î‚]¢H½lø3(âú¤L¢Û=C=rtÓ]A×,38uf&_L·Ó¢©/‡¸ÊõO!wç ¸! ÄpùÞØÝÙšI%òúɰ ¦Ù\ %§åÅⱞ…½“ûÈÖ5½ZïæEhGNÍÐ"r£›Á§ÀrÙÁÚ6åâg»Ì[„FHRÓ¦bT}-ó„ÛT£ï(wZôY]W¶FãtGZc,hÛ»§¥Û2^ù]«¯œ:ÑËÙ11Bý6rÉKˆž#•žeçyuÛ sÉ…º1Û`È çÑ•FâÊy~C9Û♤&Í<ÄCw´‘KÆópT&gÒmÉöBÎíúœCÖÊ"kFªq’%'´éÇá Ëч¦%y'SãèÍ&uÄ¥ÕF2}„råA4Ëë”ÄòmzÜàp3ñmvœQ‰7æ‘‹‡™n,ççŽR·¦•L˜Èµ»ÕT–3Ž*× ]Ç1Æ€EŽOŒ¹æVœßIøÉ(ÆøËߦ£¦ÀI M+î¤"æÃÆl{.´MEÙ/Á_÷­VQÚQ/^ñocª…rÊ<«Ÿ\x§FR}›ZJ@Ðk&¶(¸È‘è-Ÿ#¨ÇâV40²ˆîÌ+â`YÑdžÆQõ•Yw øµ¨®,)^Ä*;g>š2!¹£™¶r‹Qüürs³ÐaåfLjŸ©î>v©³/ÄRQÂ}§ š«h9*f”?˜œÙn.É–››Æ‘/äÀDË(DC3D1v{6R4“‹¦É¼-¶~9•FÛÈRerÝ.…ëûÕÿ¶þBZ|MoÅõÿU`î«ûT­é×ÿ£úº r¨Iô9Ô™•à è…ž¤‘â²¹$:9[‰üU“è§ðh ÁñЛÁ˜kÑ »’Çä‘qiäRVqÚÈäˆÄ1öðµ"+BL$/‘Ljš¡à HÃIUØqäÇ3,3ÕÆYrÏEs(Ïádš¬{šëF¡Sõ´ÐˆxPóôÁL[…œ)Â6²à çI¦¨“$â›gS¦¨ˆ*›-pø Ÿbi3S°RÝ4i b+L÷U J;Õ4:¨¢:ˆ5b8l¨† Œ  ?áÁŽ…:fï,Q&†GŽìêê T"AhEæ5R€ŽìŒ;ÐHàvG6În˜lGÚT¦XŠrdŸŠÕŽwä2éäQ¦±”¯¥ÑkÒ)I;ʼT3X®GY”zr‚Ó#¤:"Ò™´pJë¬öŠ·Ò;¬4ä‡È’•ñ˜'3\PªÄ4? ÛGª¼®Yˆ¤ÖUØj᤭ψZTîDo:|â‰J_C‹Ìn+ÄÈc?ÌZ uÆ`×vlÓ ›%W°§ÓLY¦ÔâUiçíáPiÐ1907ì¤Ó׫J8Œí°Ѭ­Â¢ÄKþà‡mâëG¯»P‘¤N‚ÇØ«Rç‹Nø]“ÑLyÔ”¶†:cYÿÐ0ýµ¥@C“v›‘†%fBÓ°±ôvÍ,N&à–Û£§ 3ï §Û¾qh„Þ,™‡Í!õèž1ævèk5É/Óqí YK%5±Ídy€j ¼X>Ù? !tb(þa¯M'sçƒÉXa)ۙ別»ÕýL!j’ãgµŠìÑv"r§åü¬ÿR£§µÇQõµ+yk9v´kOŠo`˜¶ýÍ„Ÿ32v!žÒn^‘NÍ-ÈÙ§„â)"úm‡zËŸpãâ§Ýh>“"÷"è/Š÷†Z,„û“œá(z?a­»BÔDnó\&k‡°òdÙì¡Úq÷ºÒÀe 9™ ;G ¥¤ÚÄýKÏAÈåœàºŠ¸Àâ{È1zç(mŠdqp@©Ã­‘¦Ùóá+/2*dNzt¯4&¯JozZ ½«á7gÚdf­­ÍD¥¹ºéÜp%\¥àß“d,œåN:otOÆ ”³|ÏL¤Ý°…”¦Ù,8¹Â-O¤ë|4F_Ø¢4V¡#f¶ÂÓX1àœCt³º­Kêq,e¨3SÀåg}r!¥ìKˆí‹ÁZra\ØÈD¡JãÀ ƒØ\eR"ŒG\žiDg {]ò½…\Í-„³çM¿°É².ŠÌšè‘k†æÑ‘PÂL™y“­{0å‡N®oœ\?¥!À/~ï+õèCjÌA€ Ç"'gäÈ !¶¬1fÔ5œÐE”Ѐo „l)ˆÿMØ¿x‡½wp!c“HÈ…¬\³°€³ƒà‚ô :€P3lÑ*Ya2$ &+–ͦ¸½á7Cí!÷ÔD'ˆÔ„À3†ŸlïÈ“+Œ@"ÉÂjdÁÌñ˜æ`_CäjÌ“!Á»ÛG•œÕÔHd¾BÚ’ž”*íÙ S¨BÑà òÿ„’÷ ¶3pÅ¥ãV‚Iƒ½ åÞd¾°¯ý`Ü2'f^SDëY™å¡C7¢ŒÆ9Á¸ŠCÆ.à ÊÁ%“+Ÿ>/‰ÝbÓÁé {Ó7kvÓ´Y3}lsæ˜H"žÍ*r6µÓ‚€ 1#•$ a¬0#ª´:[M¤BfØ4"‹Ò&í†D]DÞçÔ ÍÉAh’#r7K­ÐFØ1ƱÊÑè@ jïļè%œ-Ùî­ØÈ ƒÝ“ãí›Cc¢³ ªÀß2wPI£ãˆÃ0„èäò0JàBEŒfÂŽF(HN1JX1+ŸÌC¨V:céùo·ÌAB(Ùg¤”²fñ}5Êg¢T×®çÆYi#¨XÚë¨TðÜãÝËyh³>DôN)”|pCZv99µx{v¡L.Ùž,Ö›_:òæH99Ç“z8ôK‘¢|ÇØý"÷BÅ7½3\†2ÞØ§Ë?µ¡É˜=—üVc“1¥azCSƒ1»¾iòÄŠ7qA:îU‘M¦}Ã|%…iÐÍRÌPleq1Õ ×1—O†?Þ2À8¤’%‘ûÑÂ;¿»ÂfÓ •$ô&Ln7׋ÀD‚ZÌ €¿ê9”Î/ÚÌÚÙB¢ª)IʶJUPZqrוIûòØExhµ³ŠZ¤V ám'}ã-©%uŽ.7\<çÛŸ¥æ¥¯òaµÉK4Жl—IŒ!øxöÕ^$%›F>IvöW(QP¶¦Á9ÄÒw^"ƒ”™n Ô¥g£päÜTØyx?kEìæ^ŽìeµQEj}ˆ2.rŒ ²€aå—Úw éÂ-øù¨øå”z¤Èâé„1Ó$£©¬1…5rð`N†ˆÐ%² ™ÈÍêB"EèßWÀ 16ËÌP±á±a Çl6“¡æ¬ GUÎå0Fèm©\œE÷^yü¸ë†¯P¥R‘KBfg6ß]§Kõ¤­L< SIɬ=}.u„ÝÝæTÚL½)=0n[ðœt«$ÛÓöp']q‡]p ô!ñÍȺwƒbKS“iuî<¤íÛ†ÞUÈUVá7îin¹t¿=×<.ŽzE8Ü"9zn™Üýñ\sJžy_#‘QÏœÏØf¥%ÎUãü×VU÷ó߉ó_iLB»LnÚ`R+Ö„AíM ÐÉ£m=5´@²É‚ìý°…fk -˜­%Èje$ûÍ4F¢ÙädÕNhm²2›~¾¥y× æ„Ñ–- tNÂJ5£C¢k,¥*äÖ'ö±:dÈ–¦Q–<&äÒ_ö­†á^%ÐG^¦–—iQ:Ô˜7³–1&hÔàØjL:ÕmtIJY3ÍLÆY†UˆÇM3Á ¨Øzé´pcÈ´ Ády# =ÌPž-dËf.šõ2ƒe¶Eì®kæâTL­[Lñˆ¿RS«*¾ÕlkRài¥+^Ùn]X‰úÃ4·4\Œ~ËÝbö&n-€¢8™As:iI29¥ÿtŒný–6J߆ o¿MTóۡݵèðhsRmò*áÚ¨ãÒ÷¹ÃÒËm⨠Ué%9;–‘+¤]zÛ§.º÷Ë)‚}K…íþ—÷fãJñÿcþŸcG×ôßÿß%þß.ëŠ)vs¸]?â†{&¡Â=‹@«øNœÒoêüC¬±Í¯(qþkø¯5Uýï?ÿý¯ûé–KÑ3iûX¢M³¹Ž¹¤ Q°/S`òÚ éx^â†*‰èc¤”n¬¦t{ÄN\ Þ¬9îN€Þ«X º¿œÝ˜^?× 6ƒF6¼²¹ óó ÁîÎP¨o&Ò{Úr«©8ÞÙ^/JS!ƒÂÿÅRÒ¨h{¢ÙpÂÌCB14°¤… ö)Öš)ä=Ææ¨Ž9f±ÑÐ!"Z2q`H2Ò`L™Juqpd`Ò@Ȱ,‹'c¸N-´ºƒPf7Ud(4z­°ÖkÀŸÆsá'jFDÄÂBÜÁ¥vQZ±¬¶B Å ºQȈcqé*qi\£ÀÈ‘1#°%ýw„Œ=cYÁHMÄh¨ÒmÕl—› µÞ'}NæÈˆc`ác§ ÙÈU êUíÝXú„´–Âc7 žÖ©×/'?¹ŽZrñåÄ‘ð4,Ï þaƒRwq».´é ] ì/þB£[ÉÝ‘„–°‘Üš¬““Ô£Gž)ÛÝöãb4åе’áK †Î ©d ,do]ÉVVª v¢¼pXÊ.ÐF6}Áö¯´‡d.‰uJ R•LLj&³ÿó)È~Ⱦ‘ðÁòÙfÀ•Br…BJšÍÀ»µÄ<¯°gmìèú)8ÏàÐ$Q¸RÙÓ¦MñiÅÙÍFó˜QDÚ÷M/ªôá¾<ß;r>#bD´ج#Ú?Š^£cf|vF†“‰œ úcÅýÕJO/K{ƒÆP*]D5qÉÛã—å§o’ã±þ(3Q玗Ό!.تŷ¡\(ÒßžfµîÕú=Æ!LŒÙ¨¹q¤Ü…®X.møš§4ÌžÓ0¹l4#Æì‚»’-ŧ в©‹aB>Z ÇàËHºžÍ™°¹!c9裀Exy€Nr!Ÿ‡å­ü(¦ ÒÒ¹kÍSZyKÃAÒç4i:ÃòÜzë’4M„Ûйo*\Ý-ŠæÕ\§¥œÑ6 „~ü7{ÉôB^¨pß3ãÕ~øÃ®UË€Œw© 9%›±£ú‹ªcA6±¼•d›ë‰ðt}GÿǨÇì*6¾wR"w¸¥uºwQñ‚™c‡S£«#In/qrÁ‹Þr‘Ë‘®Ãü:$ÜlHÛ=Áá}œL1 l­À(¬1¼Ü‡½@FC”³ö+ÔAÙú¸V´DÊ£i‰ôBÖí;Wû€|‹žY‚.§ÿ(®‡ :o!vçø‡Årí–î.Ýq~ÑH­K¥ì*t«ÔŽ{ÅßIMÜ·AþgKÿ ÛÖa_·ÿ¬êÇûöÈÿ*¡ÒhD€DXœLˆÄÊÜ¿À—Ò$Ï\lË6ÈžÑ%^È„iiì+rÈô–æòS‡[r3ã5írI/2e_LÈSÇÊ‚•–lŠd„Ù~™ðï¯ u"‰æ·ë¤$]ÄÐ:Ü€²¿ýDF?ÿÿûorêG;οþÿ;¥ÿWÍcŠkþ7ëÛ2hé®U‘>¡Õ4hà'T¡®â =g€G¡žôãûg PŠD+`¿VJUͧh ìÀ¸ü†nƒ†a}µ”)W~QÍ™|zî1&Syüa”N—> é8€ü  Y­.5¡G„É›¢ö³Íž[—:äÚ˜¢PPÏL![8Qq-aƒu6Т`1NÔòb%Þ»Rå# 9ŒùU°ÌœKU#!P§D[»£Iðî>º9œÏ,2Ó‘€K™©¬ôLSRÜfeÛóðfΖe3Ï ˜ÏÏg3 f³@½M%—²zMïc¬Ó?LÚ_Nü7q”£R6¿ô7ÊnÒo'-ŽõúKâÀñì`3“LS˜iÈ>XΘ2r“š.F‘>¸~ÜèÝ9*>"©;¢†KG~÷^žs îŠÉØtJërSò HMØg(Ë¢Õ9´¢¢¸´¸:GúT½Þ"ò’Ò1g­nëO½­£­™LÊŒ¥aQHF삲l ’GcÙd”í+pLdÝju5¹`Eƒ†R»ç„Ê{¤Z¬ù€¼Ú0 Ö^N¸…QXöTʢ̽á•-±eÍ´í²ÍÜàë áð$ZJÝ» ×´]Ïïc|AcFÇ#”†û`‹ÒE'½ø ;¦Ð>åü¶ã˜@Pƒ¯ÔgBú(•¦ïÞ„ÊCgè'˜¢ (•¤ÅYÚ5KàDÑÆÐÍpœNzÛâüÛ¸ëÉ‘Ò÷„džƒ[L·™G9s1a´ñJ £Q^Ä6\`æëE¦qFcž—±\cˆí¯^Bmó £™&Œ ȦqŒõ‡BŸ€½cƒã#‘^lfýÜìm¦¬PĨç«ÅÞ;à¡MMf±™Ë%á½Þ*P fs#ÛÁd3EÒàÖõ´‡R¿,p}ヮ¢h ‡ xíJµ±¨<(oÆÒr#E#u ¤e~9³~Ñ'r©>ÖÖœ¤rD×>0ˆÒ,€Æ9m¢?QÉÂäi¼a™=tؘMrPçƒhc½EK7C7„é8ØÂJ;MÛelP„=!â^ŠB÷SƒzúATBß<–ÖiÙ$;8g‚| ÀââbT_õy.~ûjêZ·7c%0µŸóê,È)Ÿ ž‚ÊFmý Í Êj`ah[$Mûè×Ñj˜NY#c;Q»ÐlXm¨]ñ˜Ǥ(ïSª¾YªÞð7ªF/‰A;ÕWuãG NU' äÔ×*m lŸM 2ž>íŠvQPÏEé+²Z'ÇÇ1»8lµ4‘öÌÎŒ:üJcZÆ<¡Àc1 ÎJ±üIj"cÒt|A]#Ùï!­†Àö'Iè!µ[XríPLfrÜÔì  Q»%»žkptdÖ¢ô!Ãñ@ÏL³ø”_]<êÔ@*f¸®ŠkV»Ñ„`ƒJ6¢¢OŽrdhâc…Vš–ª&8Ía¸*©¶FXm'@s‰.é-%Û”¯†ölfAhNÒŠ_*c;‘ƒ ¦t¨YÊÑêvÐŽbÍé;Ó»Em–õFÃ!×Nh» OP6–Ì9NPrÖ‘Ì÷<ëMc€›kaEã G¬¨Ö—¢3%ªsi[‰Z-i–äEÓé¨ÖY7j§e ”ZZåwQ²Û‡ çäšÃÔv;ÙÖ1êôíï³FØ-µ»³Œy^øÞ Ãx8ÒŽ­åà<"ŽÕTÿaƒVÌÃdЪ(P.T&=#•¨K£´¹CádŒy¿ÃÄJÍ(Ú¨+u)5B5§DÞai¿iC#'(o Ý,ãRMr±¤e’zÛ1bŠ_AÃ×”KÒ’h•PÆŠvÑ¢T6iåC>N˜´.yo¶R ÈzÖI³4Etˆ™Á6[¤3èÊ ^Á4‘pX[ˆáÁËm…¥?C0p ´Ìb±Å™åÀPXvw [ZTdomn÷4\—6*y†; P&QujhÂ0jED ^ÅrApAÄ親8W ÊL|€%ü?&9«Ñ¢ß-àœn,æ†îM%솸¼S4·"ëRѧÅäNÖæÒ#Ç“Ð)Q;¸ptÅ`)`ÍI¶9x„¾Úe¬¦jôÈn™aö©¢GÆU“AŽŽXFÁâ )UøB‹$¹ ód–9¼vr$U ¬^®\˜;G±ÓdY¥“µØvEYŒï¥Ñy sÁÜÚ5ò3¬gHT¸À‰¤•MźQû€X¨S…d9@߸׈ÔK²¶V¬ÝÍî<öÝv1óDp5¢m;<¢hø>£yZ:o¶›9ê`ƒ®!ôËäŒÄ¢^KøwÇeñÿŒšQ£¢¯n‚…ùûYg‚¼IfŽÅm4•(4§Ÿ ‘Ú°K$žïÈeºŒ°IÉ2ëGØÐ:–ÛýâÆ^–»up"™£` ªÆ»…\Ês‰È7uy ìêa—ЊB% ”âIˆ‹°ùÎÒîÿ„³f®3–&‡5È‘’€’!~£]&F#ˆíes$.‰wÎOF4DÂ´å †† Ó­0lXÔÁXÁç(oh<þ”ÍöD}ÒåȶKõ¨Ñr¤7¹Pæ ÁW9¤Eèj;3‹ávæõR2X¹”ô¾74D¶ðK¶ÉDA‡Æ''HЀxóAÊÈÑ¡Ñ>”y>œùÑP! !–ŒÁã Oô|·ÁVl=`¼lphƒ&@}ŠÀs¹ Òtkªjãç•pÙL.–KzÍ«$0«Ißô 5<ñáÄHxxväzÃæÝ# …K¦}ÊÞQ:èv†ÁîT21µé®Œ>QY’z6¹POé~¥|Èjc…Øiä·ýdÇ£€³O5ù¥XÑ!ö`ŒpåRZS/l€doÏÐÎuJápã‚“fM6ÍŠ66Õ7ÍmŒNž5¥A úÄè­ü„+¡b"ÚØ;ÊàXØ,ºVä6v;B®ô|Ë‹ã9Q+Ħ±ôá“J`CîÐö!¡J¡8EJRˆ~]Á6£äf!¸T:_§‰U£F•Ò˜TSLòÖ ¨5*‚¹šÕ]¸‘wg+ÙÂy¢ûRòóMàø‰h ìH€#­Äi¶OºßÝ|›¤J=fFßî“?yÖ̦†™MѦ³ÐÜÓn›Ù—®&RÎ(ɤc¸š%Rä'„ðé¦‚ÊÆÇ@ß}.¹E†TÀ𩥘‹»Gá0ÄO†CÔ7ºªÚËR¨\¥ ˜Q¼õ¸8tÆ%Xõî†ò½Í öAH¡l(˜ƒÊ)Åî>‡…WtÁ‡(M «ÍˆQ-g)¨G+ÔïðfÅF‡L"ÿ¢¤!b vOÿäî A<°òküµBs"¿ýåú"-qsôãy'AÌ¥Ïç¼õeâbº+©‚PÖŽl¦T2žÌ‹(ãðüÊŽyYËÁwY2¡¯­/šÎDY}Ꚁ|ÂJ¯ ‹¥2rt]ˆÏ73È4y䢇 Q8]÷–]ç§Z^€>îôX@èó©ä"“9'öa'CQÇN†Dãò¯F XI#¾úC¡P ¼Ý‹åéîeS`1ËSž(ø]"N9}\¢Â’ÌY@Ñ(Û¦Œ.7š¹Å ü!¿áØ`·µ˜ádŸb÷¼ÊqøL,+š hgg°Ü½™ÉÔd5D³»76¿:aÑäÙ•—N÷žkÑðkLe¢c)¹{ÿë>ŒH ®a¨¨oGØsSÒ`§¨ªñÚ•ÓÚø1ÝL·ç©gzS.–¶ÚÈ´4¤ Wîë9BÒS±ô"ÃëÌjNö…5±A[‡˜½d1ÈL[œÇæl…‘¤£ŸxG!½ÈêÃy¡…'†&oÊ™a5°SÝ2†×é©”8 3,~ CïU+oJ•v² 4[˜Ô–ÌùšÝá(z¿¦AŠxÆ *POh7TQôUó©U@Ïür | \_ÃûøþJkª(ïÓ1´¥lN&èŸziÚLÞÛÅÚQ™ŸŠhÃ`0è¶­×phaí¹ê´ØW/ÕØµ#@(A£X¹Tm•Ú_ôò°×­ðºBº()δü”0ƒŸN?ŒyņOµ?tØžã•WgKÍY Á„F¼”É-7låoíšN²,ŠˆðUCx4°´#c® qPPá¤ÎN,'a“1Μ¯rSçÔÏnˆÎ™5·iÚÌ©Ñú9S#ÍaúÐ#w}©«ÏƒRßp¨2‡Á.J*hPŠ‘ÅÏ{ëR­‚m¹–ÝÀÕÃË>¹¼S ÜØ‚&#Ñq¼ê†f8²–Mþ©M9~„šp±ðOk¡i±ŸBãÌ€} %]¹q²´ÛcÖ~a¢ô¼yþ—¾ÿ±´â3Rü©Ê†7›Qpbp~lÒ8SB[ ,Ói\.äorÏpÈÕ@×'om䆒÷PytßãÒÐÉ? G"ÿ:="]©Sbˆ+ƒ„ćoÞ‰Ùœ‘¥‘0Á‹‰ú˜çÌžÚÊEtä ¼õ„ôHù7§[E £YÄÀ,‰Êe …Z¤K²wEhQñ[¬¼Gm‡ŒØGÊ?Їyb‰ÛS³È‘²w¿±”Í€ð@øÌh!6W ’ô»xuQK^´ «˜u&÷W³¨?â PähLé4u¢$ÓÏèBÀ^:% ÷ȴ󑻯DUêü‹Ax\5.ü‹ê[Â'•GשÀd›5ƈ"¼ËÚ;TÀP–U9Dγ»ñ,’ÙÙjbÜä¥p{„á_²5~mæ!`#È%z[~ê#°—eˆ:ƒ!ÑyAth³ìöç]|W}Uÿ¿gonèRñÿÈÿtü—šÚQýþßü'O½htdƘ{9#L7•û+>{Ä} ƒmAÐ;"OÐ…ÞKüsPEòe’hï'`Á¶‡” bUÐÖ°ò ÂY:*Ú˜ÊPAq–®ð5@ÑhºŸ}v*ÄS*ð<á¡S™ÖXʶ\¥‚,£§Ž×½^X^5rÔ{TiþŒŽ7è‡Âëÿ§ô¿SÄ0Ûœw@©ø_ÕÕŽø_cªúãÿ}—ð¿Áï¾ÉøRõÙ,‘ÇbFœ¬%¿ìMÌµÔ„Í a.Ùš¡’uø/Pìåt·pÇÃÈGRA©%·UŸËî ¸Dܤk¤>wg >r &©@Mˆ¼%?Ñ1$^ËôëÍ T%»a„Ärpm5‡ `ÎéQ.¢å7Žá€éP+¥ÀzìúAù›+ c™¹|”Åî*Ù{%ûÿ¼×4fT¹ÆÜÿ›>£‚‘ZNBØŽ§í?Ü Ê9ÁãÀ4±Ì«3ÒsGVBµ‘Ç’ðZ„ªÛ¶S§e ÙŸæH?KóõÝÿ¶£Ó7wÿWUÕŒë¸ÿkûãÿ|'îÿJõhI`*Ïf‚gu˜¨C̘¬ÈdT'VaÓ9ÔŽì{G0¶´ð^¢±"‰È,VÃØŒIydže¶¨¹/< •_‘fÒjзFZœPÉ(Äœ½ Ò±@Tøaw&A`™Òº©JÍ“1;ˆ³jõ’FΆ—i¥Õ 8JØ5–É0Ît5À ApoêÈáq`>éÞ´t"ÙÖf±¯Gp²pX鬟9›J·Uª¥Ë+“„(ÑžeË £!áj[¨¾ÙMD;ÉÔˆ,”Ió@߬”‚C¦šyI§?DËýò2÷ilÔà¥gJŸew—‹&AYÒMêÓlõø¥<ü\:Èì"|¬V_¤DEê# =<¿4RMu2QÅdSÆh)Ú ,”êt5Óá0«9³`Q7D:ù9„í¡ÖiŒy±5B X¸/f+§—Å^sU- VyÛ¯¬­ä·Õ—¢>´'ÓTaï’˰Á{!§Y|hùÉú–Sƹs¼"&mêÙâ' xcwðdÑtÆ',}àG$"ã¶“ØD}Úå † à P¢ÜH=på*r>O¹Øa%û5ºŽýz?{*4¬‹‚q²ÊnE›™wà3Z@žD 2†Ìf»°r)äêEQßlñ 6Äã¬D!b³_ T •{(jŸL2ƒûµµ²ô S$`Ùœ‚||cgvd;¡ÛTèÞÐŽ ´Ú‘Ì-´¤³]šq AKƒ0l®à™QÄ´¹å¯ëœû¡žúVÛTt7 êï¾(k¯n¬Ø2!T% VØß0ëYŠÀ[àŽÉr‡øf:/dÐQ‡)ô¢ ù mR3^{Nõ“"EóY æ\õ"¦ —2²8Ïú7A Ã^fÖÁæ^ž q(dRƾÂ\ˆŽ!c2Õ 1áãþµRÞMªŒÚpŽñ×}P*A‰)"4§Œ–0ÄܱÌv ç Ê™ôB†ô*ׯ9»–0£(5Ø“2Zjœ5³…÷:Ï9e ’'ÕF³Ž &A0@ú‰æ(Ê£.‰%’šiLD(iaœ³¥í# B¢µ«[“u.ðA¥‹¬† &¬Ã-DEL³Ê[BÅö Ë8·Ì„ˆc¤ªl*Fmj†c‘ኺ‹Á  ®‚ãsL ²‚„áL¨z ŒraÒ QÜHR5K{‰ðR¬(üœŒ+“ëµ-Mi¨%2›iú\ a(v§,”]Ë%cÌN:Nžs„£3®)5­MdâÔ A=UÞuQgoñŽÅpqƒ° OfÒŽàUÛ<¼8X'-ʱOÂ9£sákY ZÿS£p’ õXA8ù<0C™É£‰òŒ¢ç¿WÇ(áC«%†‹ &‡hÄaTž\Ȇ”5¦\ÛâîAoÜK"2)*—*L+ù*`Çz)©•´°Æ6"¨oR"ï<Š%2i_ÞH›ô£lG7–ßß „ŽzN!mòl¸-“ñl…Sn>Ü[H@¯Ä'Ž ±x[±œé¨FœEn èÙ™%A#ÜMþŸ‡)±¼éÙ½™¦•Wá¢X%bdî)˜0ðÅvT‚ D¨¶bÁc˜‹2s<*5HFðD¥ùŠØ•ˆ.Hz¹PÑÕæCD|J)ÊÎMèinº°}–xEþax¦œ&™\²=JøxzÐCñ!²0dÓ%!–YÎK;f«øKS¼%2Cs²Ÿ2J%knb{.SÈÚ¦_4´ MUÌJiEH‚#Š!9<ʉZ”l‹('•4„¦å§cB³J4‰óŽUÆnM3*Ø#Vš–s{ŒRb¤Ô!p?JT~{ÊE1#ld V‡POj"d¥’q“ˆ,V P–K"¾¤2BÁf!X¦|æ¾ÛaÏ㜱J¾¿ŽKÃý» K}C{ï–ñlŸÈPÐ}Ük•F¼Ã„ÁPL˜ÐæØ4Ÿ‘v'ÅС^3¨¨/”‘ÈÁ ÿ<ƒ¢M… yF· „š¤žº µgMsÓBRs©9ixŠƒ!RÒ­¼u–>„ßÀ¹ëëÁ£äèë9~,"W<ÓÙ‰`ìÔ`î×ó·ùÎ*½ÎÌ.'›éhé™Õñ$-”ü$;d‰vPžûø1‹{¼òuÏU¹Ó<ŒÃí«•ñ%—FÕYÈ#ä`¹p‹ô€Ñ/%–á% X¶×UÄéK`»•Ö0zîîC”á#¼cžå™oIé ò £ÎÊ«ÊZ‰’V¢™¶ÒcWó=#'ì_ÊeØ×;ôX>ŠÍ”=v­À×3x”9Ì$ Þ ªI§QØ©Û ÌØùmÔøS©h&M—=|%ÿæý®¨± me‚DAz‹†[0 Ð™¦¦Ë~‘…ï¤åi2© O#ßïJRìøªŒ‰£š¾*ä.^Kcè¥áHNÞ+Æ™œmw¿Š®-¨5£îJl ;C‰F aMìÖh¤-YޤJ¤ûÜ€n œ=ObÏx#þ4?{Ô¨QKºñ2d|” \~ÏÊæQr=ÂÏò˜ uNÐDÚn+àŽá['gq½ƒ«+Eöyì±ñò¢JpüÚî: *Ø)ÀÒ(.&=·B8·çZÀòé+¥ÐÐmÊ4{â±èmѺõ&\ð`ŤPuÉÖQGÓŽ¥¬Œý"Cå]ÔM3Å<«ï ²L-Ùd¬ erT¶5hº ’Ñ£ÞÇÀ¶1î”JÓMŸŠ×"h…|¡Ç²œÇâˆêf ‘ÿâ!B´¨fJÓ(Ú0S.õ;ÀÝôõìÝ’UÑÞ 5ÆÕ3 uqÜesY~ù²Í™¼!ÍÅ` ¤¿·ÉQ+i(9±ÄóNǯ·_U©nH͇¢’‚O-qYç‰|!° û¡•ü¿ik¨Úÿq˜ET²y¬‹Ûÿ®©rØÿ[5¦ßþï;dÿ?‡ncõ?phäêæÓLÆÇRAxêgOóY²F ImÌ êø–ðB+“fšúü’|‹mÝÒC±"Ž5mƒc²æ°J aÓbAîÕ( %H¦›#¥Ó žæÝòlüØî~Ig ÿ 3@®©|\|ƒf1ŸégȺÊt¸Lƒ>\Ú[ ÍŒ/4…hçoã9«œöT rQ6(8HH?€'‡Dt`¶;r.Æøóyg²Ó”Ÿ[؆&©Q¦ ”qS­fÇD\lq¼t3HÅM¨Ž#Œ®]—Y—7\:â±Ò/—Å÷WQ]Ñ8gE—½¬p_ö¾>bU˜ˆŒJë¶eÁSC’<¢¼^Øu:ì-T–Lš K_KƒfsýPr4[ñÞëUyvÝãø¹Jíœù•yˆ%ˆϦî*ù³ ¯XæáåUâ!Þ$¢á¹Ê=5—OŸ^N\p§äù²)²6 R°dŒ£–m]€Bxì$ÈÙˆ0VCEY€!®;[›²Å„ªÇ2!Pêä³"a¨=V<ópûð’É䓟F.N'BÖ°kHù”5SÀ²±M¸.$“rÒUŒlupõ©”›…UÃì¦<û¥@²Ón‚êmǪT ˆO†Is”̰€¼rØN‚¤HCq7XÅ(ÃðÇ—W£/!L(Сò áG!+^0…ÂÇ÷8ÕäfâDP¶ãÈ^uJlŒì&YÀfc@ñi@Ø®X·Ó)ÏèÙœ&î«Ìú„°õØED5b÷”ÝMåpûöZÒÃÌݶ ¹©U&k÷Èn½ãÏxе(vMªFËçUÇDˆœÊÄr=þabpQf( NªfŠn"ç(hÔ k-ž‚«*¢6‰ êx­×øXEÍÛÐèÊÞ,8\ôuËrí×$PF˜N°a‰/ ²–þ&õQ‹ćWè^ÕqÞ,Í|˜õ® ‡=bå5H1[n%„ôý¦p؈vZ2-×,åVΖÕ*´Šµ$«NJ>>tßW{fç2ñ›·œ4¥Y’^|F©Ý·¶Æ<Ä B dl$VºD*áRö¨—Ÿ1Çøcpv—C—ÕK›wŸŠf3Y•UÑÝËbo¬, ¹ÔÓQÁÐýœËa;Ü#\´fò ®ŽÛ¦l·Û(Ô’Ñçé¨ÀGø^¼×øxí4‡'ôÎpTËb"Ùr’ìAG,kBH¢¬ ëf÷×±„Z¿ð¶ˆÚãëê¤(¤7è¬ÁÁ ²¡0qXc1Œà1G[g8yÀÚ¬ƒ¥ «Óh•d—+ËŒÂsa´Diõ(È3ÅÞ ŽItíîšqéàõ`©ÑCþî1 E¬tÄè-‚QçÊ-²î ËgÌÄ"<Šåõ4Ì8‘ˆb«l•„àiW3¦¡fgáOtq%SÍØ“dI¼‰šÂ µÑª3Fõ¥ +Ù `Hk´°þ´ØXuqÖFåàûÀºˆñ#rt!CS‹q íÉ´P@ÕN9–ƒäÇj•‘£™³Z=š™#v~¢³S„ù™™á޶ °U`ðö  £Û ¦•1ܤ  ‚ †ýŽÙ3“D,q„G5à)° æë-SÅ¥6>Úµâí’–é xµíä9ËåB¥¸Ý¥U±t·ªŠ(_à çåW5Ĩo:„f¡j F f"Êz*d6g}z•Gf"“£ìwš uS€Ð,a爰RƒUFd1VP[(õMüÙãÒ÷ =†©§¢Ç`.gv˜z ¢ˆ €5téA u¸­Žll °ú[È©äq•ð7}0}Šw5±^¬0ªö8j§*>7š4/¬£1øËÜ9ÓA|jK.Aa Åp2r"S}hÆ|~–½Ü§h&JËYžš†É°™ZÞ#·ˆkk5€3B¹«4FŽ…‘õìBb3 °@k&h,„h·LAäJÌŒÚulRf…2 “ Î0p³À¸Ô™¡¦¾Ò‹µé*u‚ÀdÜï(UÄôaJ·iÈ–ê§ð=‰ƒðtâ· }¡>e¢¤–( ³„fpÏ]z]çÞSU¡@û=k6DYl,Ò'^N·2îŠFÇ+y'Àòã¿•#HSÐ5”ÿ9ƒßô ›LVc1€!{4KæœU…Ä7jéžÍ1F¤jLvóÄ‚§x{t<ÕA³I=j\ ¹ékY·¢¦RXI׿ðð,Jüìw^„¶›Ïd£øhÈrC3‚ Ä¼!pµµU¸TÉzÏ+´ü.Ãq}eÒ\;æÖT¼#–n7ëše—T‡ W0–Ð* "˜ *˜Xyv0¨/ò¯„Ù þ æ(Œÿ:»†ééÊÖ¯rvdra«ÖèÕóšßË%¢äTÆISƒËÙL—J†e¦Ú”ôr‰CDˆ1z éÉâ™ö4Ù†2ÿØJŸù©¢R¹¤ÜTsT<0šljšmÌ3s­c–ä܈ÉäÞl•ƒdPIŠã[Q”ÇŒÑKÕÂt˜ôåÜî¡oÉ*9û‹iÙ /rWhdoKUš² Lo;h`üVÀZ¡Ý*.·LáÐ'ð Hz¡òÅ,éÇ}Jè`‡I®P_ÀU6ÁoD@èÊäR‰âÒ‰ö[Äó ÜP:cãfB{#Au‡uîu»kù²7|Ã|°T"a<ž´ çQ–ë¬p;¡¼GîGTû …š¬Plj¿‚p)cw88ø§7”0Í,“chc".„„(Ä9sóY ß¥º{•w%³+Ê'N2±“) ë5¤O¶ÛÚ)´UiˆÝ»"Jð,föfˆð:„ÈÕùå"µÛtˆ*k g-•\껓ª}ºü g3„}̦ØÈœOZÈhÀöfƒ-#_ïô‰#ÊPhà?˜M‘v{6Z¬å'ÅŽª‰ðØpnœ{X¨…‡TvÈ‚FñUñ&á •Ë"öí5G9~ßüÀÈ"“Kt#‹4ÈP4íXwˆ¥O*¡h:öVp÷¢Ï*ºn,fÁÒ Ê†ùx(H¯Ä~a‹Ôˆ¶-Á¨V]&ªi€‹~ùiï˜dSŠöjKó“Íç©P(­N gq2S°ìÅîõ ¸“Fim(]q ,*${rŠ¢ÚWN%Jf°$§mŃ­(9Gx£â…ÕD½E‚Èqwe8ŸMä|&˘EíTÞˆ!±¥!ÉéL×åç)È Çsö!°/Ø d@²­u­l=+Ä%ãÀ- (ð—Åà_ˆÀ ÏvɼdDDÆìƒG´=ÓU²{ª<+ÃÝÈ ïˆ>mAeˆE›Â*]¦@¢œm Jåø„$‹†gð*¦àMØå³ë¶0¢Û9“·÷ ‘tØz¬¼@ Hö^<—±7—lM!m«#x9Uîbp.qxìÊš›O¦ÀPNdjäZq³+”§¼èÄÑcÈ¿„ê=:œóØ[ƒB±3^Fÿ@ÄÚ7 P&5û©¡1Ébß^EßBi_ƒÙ㟘6„T¶»*¾QJ!­¹Ž"ƒSø¦<c{X;™Ù™Íw;`I*”ɤ,6RÇ,„­Ei7'ùoÈPÏmD_ð÷’ç1HsmÂt&Ûh:t"+ÒL‰xá¹Èyàù_êp)„—òçÞ1™!Ìž L‹NkÏþ‚l7´<Ÿ}ë¸ØßQgóv‹˜CiÌ­68¥y€ª–µ¼ña™Rã » #ণŽQÚMnÌ Jò*).6ß`];ã°Úô¦ Z~fîãÀå²_Ï$hóžGWú~¨\ë"{”L„Ú¸±s-Íi•­dØØ)´G}]"Q²ø©Í9œwúܬ£†¾4ïö0ävƒØ_Þ¨e-#ìI›{µ¦béEuŽê©Y5ÇëÁ¿´7œ»R‰,^Hå{Ø%Åê`?½(Ý›3½ÑCöšñ¾ Õ-îÓ¯:,¥Çy;Ûyh˜-x¦Ç€6š1C™Lõ.wêBÕ’›‘ÆÊû»qQçtcŽr,›¤ž}¼dD¹ÍI_];ã¾Ú´«<“É-BqÆU¾Ä˜hùɬ†% x¤(r€?ah}I´@U ïhVÆè2F"‘0Á²™œFÙèÌýé¤àSLÓÊ P;b,øoÚê2ÑUƒª´×–Œ(äE…rùâÒ×"¹5ä* ñМ®³B.‘ÀǼÃZ)B²‚ƒ ŽW9hŽ×dñ»]… ¡Úc"úÙ!kXnYç@õß sˆ§Ì~ëä™$)xI>èõTæ_åa¸õWÏ¥t™º¾S[Iêa-šäï«Tñây@Ž'_$…uGƒˆnvtµi˜âò“¢¨GNß¶N‚Nam=cm{ì§AIb¬¹¤UÂÓRV˜Ú帩{ht%ŽÛ‚A”è­E+° Y3‡¥}åE³³@ îJ‚ @ 7RÚµHÔ<,RÈÊÓ[”ºî:¿Ý+²–¶8SóƒÇ»Y)r•ÅÔ8šÈ\uúÿÊiMÕÿKÛz3>×ÿªªªªÕõÿµÕýþ_ß%ÿ¯yòoûs2܉–òH.£´+!û\Î]  oæBî)(ÔårB¹—(àQ¹d–A£—8rjo’³²fÚb^ ìI@ Ä.ûAšÇ>”CèAU2º>çRôx<h<çtkÀ^Ü᪗ ´gç£vŸž‰å@V%žk©ÿ óg‡sñóˆ®YÕKÀfò+ Ì4]²ƒ<çY@‡D@)Ú€w_[÷ _šÃm…T ·P_ì© ©Y‹/bb:si`PÞ{×Ú˜½€()Áö»ƒ[îqˆ7¯ówÉû¿ºzLÕhíþ¯©®©ê¿ÿ¿‰´ÛíÚ¸e7Èhq0س·D—mNx}³èT´3©€aaÓ,lW&æý`lÛ)®ïJ ÀbÚ—½šxˆRÊÿ³8™ §@y±Ò`:+‰q-í&`T·€­¶UÍ }ØH*¼˜ åyÞ-Ã4l¥(QÄÇyðù°,ˆ—Êb4†¹IrX2ÕÜÓ0sÒ r7_2)üî®°qÇ“]lP)A.8?iÈ ®bÙê(Ÿ„—"O „œ5a*D¹kdiøî(Ú 2ÕL!K®>t.röb¢”_7\b0¾¬V…äD©‚™ÿ{Ø+YÉl©ˆtšÌ§d&}‰,Eþ°ŽÊ3!| *\äPÏÌ|4úR‰J¤RôÒ_jô´¦Mõ¢l}©.TX,RåhÈð0pÖ°#—rÜ´17Ýš)¤3XÌ\0U ©,9ü¤0d¢øM{.FiÁö‰Úw#»°¶,Ðê5ÃOs Àä&óxºQ?:œî…áÂX@šŠê†OÏì:³Q3œÇ7ÆŠmg2°›MPõiÌp4ÃIj›™ƒ( ¶ëo¥”Zh=°Jš•¦h7– ëcP9aE '¨6ç+=½Å(‹EfýMrÜóKFžªÔ_è˜YÐà&¬´¼ ˆ-…ûA¬J=ZT3˜eã”E`õD7ÅÌ1ô4 “‡Ö±±¯n2ð¤%œ6¨)DÚÌaÄl’9¸ø¥9©˜ZpO}ŒVJ%9ä?ØÙ—_À b$†ŠdobåR¹$©Ö³W&Õ² ÌHŒ~"ú†J†x˶ïOñ©aµ×Ç+— H*FØ×®Y$¬LœFâX¼jY„Ð$ó™™|²AV[ˆ•ýí÷‰ZrÛ*BvÑ”\Oí8 uiGCpüÎÜHáú$*Th NªR¨89ò³‚ÑìTùE”÷™¿<¾r*\b±Q3BÊÝ4sˆS¼‰Öa+N1tí ¡‚ÑQ©Óȶ›mh-†9L;˜ïàO>¢þ ºí°^ y´Äö¢³-Êó¡ÿ,ÛzV€·†b7à}p)=òjOõB¤ij¦¥$;È-„ú ú¸“ORÃ}ðº°ãÐQ¨A+8Y®=!Ó¤að &7cäÕ…%gÌH$Ûð¾È;ÂCâÑ¡?ébÏè‘ÀÝÈQDHReJàvíHÒ%§¦ˆd+y”é—wlq{5–­_˜¨+`6ž™èJ ÂÌIÈýMKyšã‡7 …÷^ƒæ‚jÅÈ ¬Ç¯ º«´\ÂȵJåºV'刖‡9ØìZ9_3j”K#% Š‘Lt8yè_šÃ*”Ôä€GnÂIè…ìÇBhVYçl„n!—fØgCÊ‘z*ž-;ª;j…(ž®ñÆ Rf‰ô6£çK(E[Y1Hâi2Æ?OkK¦L­d†ðJ ^¦JU*V¤ÛÛáDæz¦"e‹náA£CŸ)éâ››…«øÂj¿#6<3^{°Æºd[!äÚ’$nx/ép}’®¤¥SÃ4½ë2iv{HöÓ6~‡Ë‰ T”xgnvžêˆ1Ü5ÆD³|°9ƒK×u:cxT e‹ˆ§ˆ6ŠJ?”;+uÀå…p„ ó»w†#¹„·´Íø‡Õüþ„×|YëÅÄHQ5}&q¿C$+™Rðg6ðÚÖ¸b­Šê”Æ¢N³Ng„ ¸»ëiI¯SQÞ=§bƒ’ ¹"°z?!–vQdŠ ö6`i†ÏeЍì'j¯k´¬ñL*æwC)Aµ|gà.#;•jëèô-á# 'ÆVÔ}ˆUbéð!U×g‘Ìf I.õ^X¯ÂVyÈ*woXæ7+ÞTðw+ŽH3Õdðp˜l“©nïƒË…ËBƒ· AÄÎËù|–ü›ªÃá© M.Ⓦ?¤@0ϰ\~V*2 õ=‰G·~¢ŒÍÐ# Ï4Õ ŒH‡–bÿÅCOK1L—P&—lO¦ù/[&‚¶:Šã±–r! ~V84ùÑG4ÐwA’z9©žØ:ô w׿|ýnwœ?TDz¬i¦uè/†ÂÅ«tAݲƒÕ«œ r¦b·Ðw;¿UhkK.¡à4!úCš ¾8Þ«‚å|ÊÐ23lO£ÂtL§êÝ•½5²£|³ZSÔÝ•e4C©¥Ň HêìR8^®½ x´CÎI¢@n°†ÕÆ r† Ó*‰ö>päç°.¥Å6o™›s©Ó¶MB²aT˜rXÔËq0+4ÇkìY¸Øb%­”‰;´4r¤„9ÆÍ<6E¨ ü¦ ²1à» ÃL;ìÍ€…h”OaÕÉ›Jõk€j¢“J:¿6z½—Mo…2û ë†)ÊX‘ Ýc3™M©4”2Óí@|Æ£ ?ÁS?ˆ¾Ü‡ ¹7æ¤EÆñð¸:º€ºRñH*ô®VXmLR½bvó()ì2ÓÙ/ö /³ô”iÑ[lAþŽJnû n.áâf%ÏÌ+üe–“² z6RhÚA?¥Ô’Ó“ÒA—éÔ1N$˜ÌMFlQcV‹y×5i³d‰B5¿ƒí¼ŽjËõ?›úØb46Ìœ2{Ö´™M&XW0’Å0Ï‹y‚@*“äé9ôôPøWä¬QMÙæ¥rÕk¢š’½–#—„ú¾XZ²\帢\޶¿Øâ´Î‹-Mú I~Úmê'%ìæUaJyA—9æ8jBL÷ –‡Ì^ˆC A Å6/Í]$ƒÖt6—ÉcäI4)p¸/…´Ë³µ#Ë /‹•7‰‰ d[1’šÈØ^‰‹¥ È)áû=5¦—C”FÆð ÒŽœ;6Q°w¼É¦k`ýS²°$û'žÉ,JšÀ…Ä~žMµ ¹?LËlœoÜmÉKÒ\pñÑ¿*ä'Ûê`KJú‘œ:§~vC´~úôYó¦Dg448kJc¤¬˜3ô陬v=m%hÐ3ÒéÃd˜–iÝÐu ²¡[gV8¨U¡1Ä sl4I9RÓVãefàœFUQv$j…Ù‡ )¯d+ëÑT¬ ¢«-éiE‡Éô’uìJ$)ÜNØ ÊÑÑ®c"”…Ÿ®D@6KesJXrÀ¸´¯T»g4tJÃô†¦ÉʲÀ¥CE˜2I/žéì´dHS5uú¼hÑ$§ª×~Oæ)ñÀhÜ$SæˆTr‘É"NUxÏ%j”-ƒ~Ú ƒf®ø§“ÔKFŠ1÷”’àÝK&1•%SÍÏ&ÚäjF2‘H™„õ$7Â'T™ËyCröæ?¨îÀñÉ6r©Ô€ÀpưSaþ‡3 ¼.ÞYN î[Ôagm\:¢‹îÓË‹³6;@b¸t Eïòz¬Äpc+§;Ü×ÐãΚõÛ%—D/à=çð]kT³3@FÏZy”Æp™ÆzlHÏú=ãA–€gI϶œ¡?=—Ò™5 žúºàþ²Ù)Îz@z)!„VH$#".¤cÍM.s tâ//ZF€ÇEqÙ6B¤õ>1BN®+•CRžŒwcnÛ´èÜêÚ(Mˆ’Ø(õZA%{çcQÑÅ:€×ÍGÈ9‰)Q^͆"œ_’ÿº/†>´¢¤Œ0ñV9•°|â”á Ò]ü­~Þ1…WciqIóöjå‰F8/î‚ÝÜÊ…îþ„ês&DÑ?Í@CrŒk´”W Þn:3 ŠF™_°´VÓ:f¶j„%(Èñ>‹¡¨ƒÐ• ÂN”³(Óà¡¢`Z5Ð+-tØ5\YÝéxG.1 dá³ÜJ Ñ_c¼ºNܾ_’œ‡øRa6>Ó~!£*YÁŽªÀm–̉‚ô‹¹[H•]yVUœñ‹?£m±8ùOÒ´Å~ƒØÒ eDЬú•&»TÇôùq4´›ÃØ(‚4Oõ‚%,ý-FÔw€T¯x”iò»\«ÙžT¡—E¶ûËô;$Îþ¸IÙ¶ HÒ¦[ÝÒÀ‹ˆ’¥•Lð"ZÆúÑK¦ÈBXùº>vå±¶Ö¥û2TLôïê’÷c ×¤!àõtþ¢ƒ¡ãRÙÞ ve\øC9‰ŠÂ®Ç† Õ~ö_êÌH6}õ†MÚϬNÏÍ̾‡ ¥ñ0þ[ÙÀ¼wÜ‚zšÜ£‡e£Éªƒ»23<ÀW˜½yè^7!ÌA+àZB9k9’âróQUW1ã@–E¾é\ªˆ:ýz‹Ô¦¼%yUìPê«×‘¹xµ¥ëò®ÀÙ£RšžUiÊ:q+±?¢ƒú•·txó£™AÌi8dnCcÓ;F¼ ,X ²~×SÉÿSÕ¿9ü‡Ñ5U5:þÃØ1µýþŸÿÿOö/3!VHd–§Ì!l ¹bàhw[Ö’I$©rߨ5°âAŸCž(‚£PzdÉæ †±Ðû…>dFô€2ó‘Ô3o“*®.éLyf=´ÓÖ­{ÀâÙsãŒZïœ?öR"ôy)f:ÂÒ‰Õµr5¬‰W  ,°’AcØ0G§À¥ ôàv¿íLÍvY[5ŽÏ¥PJ¤ Þ_~w.U%À{AÔª©Ã>ÎxBíÊ=ü?_àIÿG‚žró\¥ðœøÿckkÇôÓÿoýg_&Å,›¹Âø 'iÅÚM|mÈ&_ðU à§Ä·X,ŒÖŽø—üæìÈÆb‰(Œ ¼«s–…P(Ž2QA^@Gq/ˆhç~ÌááóÉ å\žÅUý„{Ìw3ÀIrâàÐïh3¨÷OÒɰo»IBÿÜŸâçÌšÛ4mæÔhýœ©d¼ ù]Ö%¾5Œ³åºÓ’9°™T¾52ñx!'j³Ÿ”Ú¡@ƒÃóŽ‚PRY:@ûÐãD ïc„kBkrýô°‘3Õ Ê{™»_…ÅýÖ¼)5>á"W‘¸ð—°âÃ_ÆEoàkŒÚs“¿ì/ÞO]’Ç'ïšëk|sÄŸL'Ì%²Ÿ'Ƴ&in‘‡?[ôŽ›5eVâu§­‚gòé5d_J¸\Vpš˜÷Z‚m²(V¤˜Ù<¼Y™\^¨ë¥xB}®žqè4IwªÐÀñýˆŒ¬5evAÃ*tvÆr݈ÇIŠfRéŠBæ#Ó™Í èUaظaÃì}%Í¥Òïñö4•S‚Êå)#ѨyÏÇó1«vßx>Òùí9 w2ûQ¼Ts³o6í/(º ;FÚ($³ö1yލ¾ØÍD"Åç 0 ¶3fìrc`öÛã¦gÖqÈáéÊ¥rÎæQ‘Þ0 -yt¤wÕ>è!=Ty²rN³ö—±4H¸²ŽnóëÜFC*—’ܽ!Vt>v+®5¦l‚¾5ÆŠö¡1}ûô­=»tš´«³³Bã–«½|@¬Øi䇼¯DMÐ!bÓ¢ýäþIaƒG;vDÑÛ‚¾­œžû½êÛ|}óì„F±]@Ë+;Ž¥—u”³§òEïÖOŸÏµ=¬É¥ÊIQüY;ˆr÷<ŸÝC¯¡Ú=ž6zßt¨ì"!&YÖ)B¢{-)À¥'l‚Æ—x¬Ù·Côpåÿ“i¸2cù$¼–Ó®G1ÌêÆE…+Áÿ3VÓÿTUW÷óÿßÌ?`Ï$6 ù¶ûVôA"˜&í ï9w ‘4;1‰µ¦ûi4 Ü;š«€ªXB•YÃ/¸o {oS^éhÊ%š ë͆õöüÿôçm³0ÌM6e0,­(yþuù¿ªjt¿ýçwâüã>©ÇmB}kŠ}! 0 ·/GÝeGªÚ@Ðà’û˜Qµ;+ЯúëËùßLÎ@¥ÎõØQÚùÇ'¡þóÿ9ÿ⡨èá_E‚€³ËÐú|øÅv XYØÐë KÕ÷ŸõM>ÿl¢fµ $ ôù¯ÖïÿQµýñ¿3çÝ&¹VŒÀ6ÚèÃ/ïÅ !U–( À¨~°i矃m¢Pšÿ¯ÕÏÿ˜~ûïïÎùgà^߈ nÉ~ à›8ÿfŽiW6’”¼ÿkjtýߨª~ûßïÚù7sTX”j@ÞlïÞè“/6#tZWXüÕÏôoÖóuL± nªÂÕ®o„ äù¯Öìÿ«ÆŒí—ÿ¿;ç>Ù&ôèÉÍá{¤èóá÷܉ý'þk8ÿ<àZ&ex雤,}þú¿ššêþóÿ­?ÿ:bÑ›¿Ëï3ªÆ u¬2ŸÌÉ×ôsòÿ½7ïk#I†ÿçS”ÍN#! ¾ö՘ƴMO{¶}¼@÷ô¬ZS]HÔXRiT6ƒÙÏþd™™•% _»â7Ó†Ê;322îøœ÷Ÿ26Ƨã|:¨¹Ÿöþo•îÿC…–÷ÿ«¿ÿ'09RP‚&Á7òî—!pùÐþû?€ß}ýçßÿûJú¿{Ë÷ÿ›¹ÿ/˜ÀõŸùüC ùëÊþKp؈l7-ñû9|’ûÿQR¿kÜÿmßþçî£Ë÷ÿ›¹ÿ ˆý’®óµ¨/ׄÔÏòº–û®v34˜Oÿûö¿Û÷–ò¿oçþÿŠ`2 \ûö;ð·¼ôŸíþO‡o†ù[“Äèc €ùò?ÿþom=XÚÿý÷ÿ‚“W a>p …¿ƒ&R„I³½ÄŸüþcRÚôÓÛÿn?*ñÿ–ïÿ7sÿ_k0™‰˜®ÿ BŽsõk‹þYÞþÏpÿmB¥O{ÿn—ïÿÒþ盹ÿ¿j0™yÿmÒ6™½iqD`Ú‹œk1¥§òº^¢†¾ÿ%K{7¡œÿþûú¿íKùß7qÿ œ|` —·ûÓß›¾íF¢€Í‹ÿ¸]zÿïÞ½¿Ôÿ}–H‘S¹å[[¹:©E‡2 ”€Ñ¹À™·(¶h!I_„Ë´ã„™ÁY-?P×;ÉøT†å¢zwI'ã†Ë0Jb\®«cœâ¥ÈPJ0j[O» "U ^.c^”sñNV£q:È!J¿éU¦Ãa [¢ŠÉôä$:烪íúÙ›ÔJ¶Š³tô1 ÒÒ͇çé:ê4-tª”ûe’c´HýJ±¿Ä©$E eµ;±»÷"£¼Egü¿’uã›ÁÿRK§ÃýÀÇ`ý·ýзÿØ~xo)ÿý,?„Þeâf‡Òs‚.rªæ0ΦBœMÎo'Ãó|áûÿq7¡û¿ý`»ÿáÞRþó Ó7̦³a·?íAЏé Ùd¯HZQ»#LÄ!–x02«Á2"47ƒ8¦0‡(‚>ôË‚ÜAÛ¯Ó$’²ƒlÛë´xü¸”+>œéBKãžLû}MP"6¡ã_6›Sa°øÐ†Ä£$㮘†:ŽÜ KûEYÚïE~/ åÊ Ñ—x¸2>#‡Ö‘ ѹÿÒ™ 3 Ñ›F(D¨*8‡ŽjßA q'JêÕÁóŠòÔ›\¡"×®|°ÌÿþEé 2÷Ç‚Å!Aß.‚×àúÜȇÅaTuÅ?L³~ÏM.JÉDZ-gŒVëi>ì¦ã¡ÌäÁDdiu°÷0Q7u”t!ûëY:Î&@OÔZ%½GZä¸a‰½ÈÒ°•Ëiµäü¬.®ãg&>.­6º¹)Ìž\|àÄx¸‹ŽÛ'Ý7ÜW'ÐY³—¦žo|šÞª!J‰!/Øñ¡,(”ð5Â×éYG«'™WC}tdý"ºÒ'Àçãk¬@˵Šh˜AP3-T¯“<¨-"ÔåÃÔݵgj…•½ÓúgáJTÖ¿¦Aü?w%7êÿ¿uwÛÇÿ÷L±JFïÂ3¤ãF6è¿ÄUIÅ?•L|”“x4ÎAôÃÖÄÊ¥….Ò(ªZ®óâW=ñ¡),q÷·Œÿ³tspCÏÀ\üÿÀ—ÿ(ž`™ÿã«ÄÿYê¾/$Áþq:ÞO¬â¥Ù·Z/f<7 Æ­æãUµ²oÐeÔÄãSÿL*ÙÒ ¿¸ sùs#øÿ†’½}þ¿ïë!üóÿAüo2º­ÄýË$ë·Zéi錱.)?–ÒeЪÁ°Ô°Hã‰,Ãq 4œ•Vš`#ÙÒÖ̧Õú«úÞðê%£l‘ª…z2ÀhØ(µBE%À·²ƒÉ»I¨ÉÑ»‰¬õnÐÕúm`³\_UXší(ÇË)o'é¥klU³<©¨ówî¡Ý²½‚yrtyUŸ3:ŒQS{ÊÇL]ŒÒ®z“ÄŒm¥¶mÛq…~ÐÊ•¢ 3™k|ã{6¢X½Jõè$`B<ÎONÁêkÐu½J¬äŒ»|¤fãÿM4S¾ÁG`~ü»¾üçÁÝ%þÿjð?ü«µZá|B"ݤßg?_cq Çéd:j99ÂÊ_|ñ1ËöŠ:%´ Siö¦ƒQI·°¼ÜÿKïäG"ƒyþ_w”âÿl/ïÿWwÿ}ÊèqÀUz'®@\S ¯•@¼[BŸ ™?<­¹›=ÉÐ\J·³T³{¨˜$£ú¬bt’¹ª({‹Ê½EW¥î\+˜’t¹´ÿR’ÚÏÀ¨Žˆ[̪D*Ç\thäVÞïÙó(Û ¹þ†¾bÛ˜@ùNkضý¦ƒÆNzÏݾ¥ôë¯Ì0+òÊKÙÍò'ôþ+6÷Fe@óã?ôéÿ{ËøŸ_ÝûônòqO~Å˪À­튗X}ˆZâïb‰£>ëý7èÖûûAéþ/óÿ|u÷ß 0oŠýW€6ƒâV¥Në$+ÒP@ ÎBj挚1îgÚˆÖT_kK!ÁÌû6™Œ69HÄͪ€æúß»ïßÿ­eþï/yÿR°àhþØ!«ÀJÑÚÜ<Í&gÓãf7l‚*šþsÜÏÁvž/ø¨Šÿttô:þuÿàðù«—ð÷N´&?­5OÆij¢„¾Þ;ú)~þòÇW|sUmóÉ«z°ÿÿÿ²x¿Ø?úéÕ3¬ê~òê«¢ƒ¿Ç‡GÏ_þ…»–Ÿ¼ÚO_½<Úyýýõ>×~š'ép²QOMm®þ—ý#=_õ«¿¨W‡Gz1êW¿ôÓTýZÞ§?™}xú“Wülÿçý£},¦_½òŸö÷žéMW¿z¥¯^©8„RþÕ_Öá/¯_¿:8ÚÆ[ uÛj \SæÞ 96x. ³¡ûîxâÑï=}ºÿú(n‰7Ýßâ§{‡O÷ží»³jûÛÆÓ¤è*õ—}ì½<üqÿ ÞùôÕ38|=Z©$Ôœ¦ä (Jü-ûñÕÁ‹½£’Žj¤¥ˆ1>ÿ3dñ?Wwº™›ƒþçÔÿß´µ]Òÿ?ZÊ?ËO:l)ˆCh­Ø@J-†^jñÖŒ˜=+^ô$«òÍÓq2;gc‰´5!…üíº˜3>Ùâqzš¾U´=î'Ã7T–F“ [‚n…*êåi óIt–@°T ±EÅkÂR¨ÈØ4:K ª:M±-'?· ‚‰©ZÒø¬[ù÷…'4 jè‡E”ßRF“Ò±¥¨-õßtxîZˆð¾X#`EOT‘b£ÕåG®¨ rŸ8h·€ç«w}!ö^?÷_>{ýêùˣΌŽ@èíɺ{ÓQ3.”ÚÆ¡ÆèЭ¾A4t¹7dOÁ´Ø›ôääN.-Üluèì'd ƾwÂÕcÞU]ïŒSQ“Lq6<É­w¤…µ_ª¯Vë*fiÑ6ãÂ4;·ÃÉÙ8[£èÎ2hñ–H䱦Ž+gÿ¦$?*.í5×êêìC˜>gbM&‚wÓS §zwœª¿jOÎ4”¡5fñÍ1J»Õ̆jæŠU4NÚ­a£Fô©W¶ÖΫiÁ`–‡še30nÇQÿ{ÅMiçÙÿÝ{àû?º÷héÿý…ñ¿)ñ¢wÉ]ïÃMäðgße|žÃ8·| /Ì 4û—Žh«Ñžbö «^šØx¢• ¢B'Íè)Å…ê_8ó¡bþhj#Æ-ø£¡ÿìe§Šªü#þÁåMÏF­áX;”È>EŽþ»ã~Þ}㢈Hu1òÃ9Ux9Bÿ¦Óæ81åXSÄ`’>» De·Ñ ~ü©©U¤–Ñ7¼ÜY“ðPZ9vÕâmã59Òq‚dˆ‰¬‹lŸq ²‘Óe|ŠÚÀuÌyìEhò—Û§ÔmD_Mõ6Ù¢v¢–z*úƒèvéIº©™ˆ™bE>,`ÕæC†y8±+J+P~ ×J/y$à׋b¶ª€ôO4AÓ&%ŠOãFEªÞàIåRhFóÖ²Ôì´þÇÿ CÆ},07þ×–ŸÿûËüŸ_Pÿ¿ènI}ïŽO¦Ã.\X—ÛIz½Z?9Nû Cùꛟ¤“®z-ÎÙø¾ƒ÷_»]9‰õ€¨¶`ÙÆžÀ:š§qñ(z°þ©ê|#æuî0šnQÉU5¸½UžÌ¢¬Äã ˆY­°H' á(p¡úNaáò„ ç ñŒ*µ^<{0 uæ ceoÓ¯ª·¬Ý¡ÃœFKüüÍâæ“?æ ˜kÿYÊÿ·uÿá2þï׌ÿ%"<íN!™³ÝeKcƒ€eH”‘üEŠ_B§F¯ ?ŒÛ/IEŒ”ÐGH8œÉîÊãýÂRÁûs¢ÿ…ìÜ/Åÿ{ðhIÿ}^ùA¯èkàE<%y¿“»ÏHøFîÏÕŽö;Š:zñ3ØÂ(uól2èûæs:E ‹+žþÜjikÔŸÏ2(Ú³˜"s2Ú^2îAræ)„É@Åa ùÍ•kŠý” F}H½œ³F¥+ÇêËô·&5ò…UņPkèpZvA Šnb²©/X&Žûáõh:¸¬ˆRR@ƒ²¾Þ’Ÿ­n¹ÍžX‡±ìJÕ¦âÏÓlèé|äšžøOÍRLÇR,åw¤ ô"ˆ¾ðƒ«iíNÅ!ÈÁ”–`NãJ»Ô £ÛÝdzz6áüØ9Iõ¢ÕË”üP=Ýã.ÌeÃÌV/Q×ÃïS2H¯¢6ÔŠÝÛÎhä‘®,ëÝ_™]êû÷î>ŠìÛ ”b ¼Tì}p’’?IŽáM5Î¥«ÑSµRu!è@QT'L«Àæ¡KXsoï`ÔÏNÒîE·ŸÊ{CýüyÁQi³?jPÕ;û«´xá ¸C5_ï?µ» 6 Y¤’]™]Rõd€_ÿìß”ÀÆã<\àÏNÜì}Lœ ž±½îw$…œæímÅ º_î–¾luª.·°©ÃèAd—a‡Ÿ™’§&›õ¶:hÆPWI‹À¦S§c$NÑ"«ƬÞCÊb2öÆ0K^ø¥zé›7/<°1¶´ £5€©U>Ä& p'w–4Ç£<Ô[û¼Y(@ÔÖþ¼V§Œ™ Sy³B1¡Ê.êà–Ú¸Ÿ ã¬ÒÕnH!z $Uº#h_ä9\¡©ÙÔ}r8Dþ³îö€VSRE-zPà_Ùø›å‚ô?%>½1`6ý¿µõà^)þÓ£GKûŸ/Aÿ{Làõx"‘K^`&}YN k+ºzUfãFêýV/ªŸ>Z÷`MGœdÂÚ‘¡5qƒõ¥ý¦Ç•m©þDg÷s]ÇÕåD7ÆŠ hE'IȆÕh2ž¢š‰J R7…ºÓ˜bµÚº§rMËe´pŒ±E@’ÚέÙ/Ë}KcW¸ ô*PYi`=½L½ cš: SÔO'5Šgöú×]ÏV?S$:Ù §l“^9œ©#ÕÝ¡‘uFx³3ü™´ãró1Ä×逾‚U+ÚíÑ­¢¨~ßëÁ®¢[.èûP3LÚ|&æ“wrC1R¨¾j-漆ùl·ø²t0ÀRùó‡0~•¬]3ýöÖº`yÌÆbu?.´ CÜ NI’ó;Ex`5t؉Ìï»5æé¼ Gšü¸§6İDµ[N¯Š4ÄÇtçmÿ^!† TŽ%ãSPæx;„_¯fY÷È$–œKÅP'Ù°§!5´nψ€k6HïF»ügŒ³¬¥„,älè;þ½>?Å3•7îDì„…Q‚s{;Mh_Ûø^+1?ÙÆï£7Î`‡ù÷+Eè•:Ÿé¾MtÚØ×œæe< ,#0é4¦…ùI(oçËœ,¡öi9·§Cµ_<’5úcõ’;¼Z»­O_ÆZ(‚ÜRÌt8âªn×<†Í…ŠêU®>Yqµ¼så[æ0ÂcÚÙ™âW²›'áJùEÞ5·.%xtduuÕº@„§'!ê¡c—=q^Œ7ÛªE‰‹ý©Vç½O;T åù—Q@b?÷’]ÀbúS2Î&ͧã|׉Ü/­aÜÅInõ롼¬·jLïib‰\¢²ÓÐl%›5šœØUi™!©©À4¦½‰“á˜áñÑAô#¥výá‘ »€åo9‘—š˜µ‹tVyºu½ f¥à顿•Š7×ÒFÙÄ`Úœ9U¡RF÷£3ðú% ¥~ëó¢zãÓ^3:PÇÖ€ u:iúngGÈzGijŽ, `a»Å'ïÈc<¨ÒOòx2ùC¸µ. ÀÆet}8·'§àÉðW"½¼oA1‰„n®o>á’øcùà:pÍ«Kí©C/m»ÁûC¢š Ai¯5kª{üsÞw¬Ä13E¶m våu‰“™™ÁÐî×Ü,ûQ'D·_Gò¹Râ©En-8}¹É A¯ÃÏ—8ô‰ØsÄ3>¶~$ý"ƒÏnY_AãÆ­­^je@Iàïh½oû DhwÑ«BŠ}fšìÄ ºålq5ÁcÓzHT± ~!鬠*é UØ™AíÌ!¨L·µJ"ÐI½™ /v%ÎÊtúÌÙ,D¶ÉéTõzbÌH¿o×D$(ÿ=Éú7™fžý×£í’ÿÏÖ½¥ý××cÿµJäZÑQÐÞÁQžP˜ ±¶W]VÁ$ÜË$g‰ z1Šfô|]N …‚ûÙ›4*ròŠ^åê3\U~Ä~<`+BÖ¾—ÇE4%LEø8…`™ZSOe©µg‰¢%Ë­(v¬öÅX•H3ÿcG¹¶³úÆš^×ôífÐOøþßl*¨9úŸ{÷ùñ?=\Úÿ{úCǹ·ééO¿¼ü¯ýg`æÕ=›ߤ=ßÈëºZ¢*eNµRf”(.>Ï“œ{˜žæ“LÑKqÐ,ìÜ0ŒFœ GÓÉ"×ÝUu‡Mq<ê¾q8Àõ`'ºã6Òb M—â2öŽ~9Œÿöüè§øå«X1ÏþÿðêÙß-C£Ô« ¬ª¤6”ªPovÏòI³ž#Ì Ð£>‚e¿ÈÌ95«·—ÛF]¸üÃt|žª§žš´lOcr?Šš‡jQ'¢6±l^ m3`Mï=5F1jbÀ•=)è®ÊÚË=”Õh¢•9aTàÁ=†hZ`ˆ”a°›ótüv Á¾†¡{B0¨¶êÍšÙé@˜+d»7Óíæý>¤óPÔ;”½÷9øˆ¬Š«©pºÜu%¿.÷‚: „vÕ<9ªç}Uðá o®M¡¦v×Úµ¹E{¾h¡CRžj^}Ńä*6\f‚óæéöÓ ê>É’æ‹4"»ëjv[ݼl¢í¤ˆô‚£±ßªo«¯7Ùå–Mõäg”ÎBRнø¶:Æ2,néJ:’¼Ï33«/ %g)‡U½òÔHé{‡_ðÚ…íwWɼ»ß9° „™­)àhr—M,Yë8£‡^Gï ;VÓ]AÆrVÖð‡©÷7èƒ/½´ŸNÒ]PµÊoér»¸—Lle>Ò^–,ÞmyË¥hTæPk·]K\?žNÎÀ ?‹¾îÊŠ£ô  ~¶ê ¦žê+ôCΣ,•;Ø{ú_ñó—¯Q€"Þ;¨­Nìm&ž~sB ¦C(SGª’î éUªîñÔQ‚Š•—×ù¥½áò-ø¥‰¡;w«m¶ƒS º†O<©YŠAÁJêOÕÊßTþûíJ”\.ï@ú _B¬¥¡"Ä`Ùvvà¤P ¿R Þ¬h:4ÀÚêey†AgÐâ“(g+±}Ó¥À÷v©Qж”pË™Fø xµY$+uçÓ¥€ZU™˜¢ð-ÑC^Ú;ü ýdÑÊ+Ñÿ,8?!.t^{¬r¤ŽëüÀà>¶—¦j‘•”3³Í'RMoZöä(ûV,æRu?oŠœCú/r{œÓ«¤æ0»„Y™Fi1îÁP…ïß;l©Pù5™B )Y}Rv2[ÎÒMíÀª6ñЬÐ &‹bÔ°fÎÝL‰|'…x‚ <­¶Öo®¹l,ÖmÙ¿SEwlÉ-1g´Ã•úI1qXÇä<ÏzQ&Fj¹ƒ||V߀¡m2ÔQfy²åŒ.fŽ><(S©|g*ÝÓÊPåÁ£{гñ|bµgã‹Z5Õ%Ó=tê•|féC7KÛû &³6Éf ­3¶ä̵Bº$/tAIÃä}ùÈý¢®d&}O(²àäšÇd¶<,ÅLuxˆð¥Ä «ÚM"QG+^ÇŠdS;Iãá´«?râOc)4¬9Øú÷·ë›mõŸæFg½ÎšžJ_­Íóa¯™¾K@ÍÑ\Ð^¯¿Èœãµ]'¼­úóÏí4:wvë»6žb3ŒrX-$#è FsÍ6ýÿmÓãZpehm­Þqd¼Ëh#‹êNûùqÒ¿±,Póô¿ùþ?¶—ù?¾=ýÏ_læêRµÊð”Rõ YH@Ï=šr´„¿A©°ãº8à_ö^ïkr¸ci©[ľhÿàP´lúb¿9=¼Þ;Ø{átÀÄ18QÌçm>-ê Þu%0e×ç‰ÿñ ÿgëᣇËü_“ý†\uûrM(¦F÷ ¸–YÈ)Ðñ ýóö0üÛ³¬@I­´Þ8„vÜïsN²ƒ}gÃò†€õˆþÕ(N ÃØ¦ú‹7Órü ðÓB*õ/ZnUCQ‹î„£©‹ÎFúd‰æ¨M),ü#?“#×N䆬,RƒÀ¢Ù ¢ºÉÎN-Ÿœ¹^è_ÅGtkì’„ÌØ¨é¯ ›>õ>ú­€q¯Á\Éïç»ïxúè]ÖuªÖ‰[AG™"&¥-™‘ Ø ³?œÒ1ú6­cÐ ˜…È40½"ì?gѼ„óiùü„Ú˾³‚âÅ‚—¦ÈÛw,í÷¢wU† …œŒìBxMF_6^“v§–ÕCmÚY§ÊÕîj-öÒw•—Ká†P9Æ?u¶• êx I$‚´BÅXr¡îälI@Ë¥N;)x51[²Ñ_åÕÆˆ™>fÍØ¬kç­G[z[?-Òù›ðÑ{8šgµ™[g#<9&êÆp‘‹P·Tb…¹BÈóÊß»–ð ¡–eû¯K±õGÓcÅÂÇè¼êwù¡ƒQ>ªÏòœÕÇbñöÑcP<õЬé¸CÞÁô'>¦DJ£L"”H/mcSÓmµÜ‹;†³´3$|Ô,β“IMÿ¡°D÷»ö{ðµì™ÕÃGoŽg ÏcФ‡mW¯¤ €8hê÷sÐäMçŠàü9«fXÔÄ-‚›ÛK‹î8#óy.w·³†£æu´p"lw›‘6Uçk}G´ÝV?±–[6(F éPÇÑÞ0Bá—KqÆ#–,Q-mž6£vf× G­ÓˆÚ-é0¼u WÃ1iT'51d½ôü<~LñKœZÍqúO6ÉÉßG9x'wèÊ þ„›èD!ù86]ùD5H]3¸T4†Äüj˜U _óçÃIz a#w›¶<ìnº’}€Î´9µÛ/ó¨˜*Gb ÍÕKý "nñ Dx\Ý®ÿŸŽÿhÒê}žüOÝ+Ûÿ.ó|–ŸÕèW}ØDUµ6 kâ“” Ý5ÉÅœ4`Ô¥˜¶È¡!Ó°MŒ½Ø¥tìí‰~Nª…WŠÈžš~Á°euìþÙµ1Ú0…S,ìÉLlMªz1õ¯W}:ΚbÜÍó­MÈœ6wSÝ0y E„Z#8KYýæ»joT›ó-œëa Db/;ÏzÓ¤é€+¼ÆtR×Ê“bNcef8uó™ÄFm ÐñrXB`:Zl‰2I$V$NÍpïº[‡ÖTb"«{ñ¸¼úÌ;âTÝðZþI5<õUyÞíº»êHþMu‚©:E‚›°½G’)À\GütüŠò²ÊóßXL°Ùø3¸©×}æÅÿݺwß‹ÿ}k™ÿé[’ÿW /ö“ôp:lžã,ŸõŽS ³{èt ïO6·£*‚ §0ý5ÑwèZoüêdÌ,™ï“>·>*FÿàÖµ8Bw֊ηJ=Á‹v’ƒÌÞ.=e;Õˆ—Ù*µdëïqƒ"ÈÎ]ªþüÄl—u›:Χˆ¶Eoóý»1, ®²4¦Ÿß6ž&EW­TÛb+8éý«µ/Ð}žLÀ(7w©q<ĮҠMG@«®(¨RB–YÒ×Èų¬6ˆÝ?8|þê%Z­­)æD½Õ#/K"|ëNvî÷t˜‡A¦å–&è¬Îµb=Ç8ˆ±¿Ènš‰Éë« ¨¹¶xÂ,~ÖgM}ÅÛŒ‰cÏ$<ÇŽ©µrCË=Zh¸æš¶ûà…q ?£xÏ2]­Ì±3hG{ÎIÌz^+ÜVº¬ãEÇ( ¹Ëê÷¡}á0 Ge!D9ž*†Z~¸0q6Žp>dxœdHÁÿaÄP(áÈ¿üðé™Â<¬«û*À~ ©A‘ŠúC ˜Ÿ¢(¢Z‘¦.š©#i< Ù*™Ã€I˜âr°l9Wg"zBLwœž%瀌‡Þ"½‚nyÚ LçÝUK*ØåVWWáÄn°* »ôGÓKãŠõvƒéV¯y(œ•»¬HV>I®ß™%£„Xˆ‹*Rœ›èjŠp©Ñne”’ßâ§{‡O÷ž¡WÊ@ÁZÁÉ/¯–É|þÏÈ6?Œà¿žÿ÷ƒ»÷ïúù¶¶–þß_ý_]n„Œn­sIŒ*ÿo†wÐ/ʾ¡ŒM _²m‘Éá†Æàë-ÇØ÷ÙŽViœÁE7ŒñÓL6ºyÞßÐB¨ó­õ†f¹iîXbNĬւՋé1·@^f‘‰¯UpE°­·²“µY,U™£rji'ªåLå[ã¼ÂÌÖ¯û/Ÿ½:Д.›¯ÅûÙÿ-Ú$Àæï{hù[k'ÿ¾»ñÿ5߈o­þþßýþÎún½¶ÛÚÐEwÀ ¹¾«>ý¾n¾ý¾A_ÿ·0þiï0æ ðˆfœÐ0›^Cš²ßráJóå ÏI„2ÓC±Ú_Þ,˜E—òþ~Gj²ñÛûùçWÛ¿Ø?úéÕ³C×I`DÒ„Êäu?Ž™$ß*,vÓupΓ$ëSl«Œd‘1‹è¨‹[5LÂK-pOò©ºkõ…ÇDÀŸ7¨+4£Ò¥©¶ŠR òX¡³*¥³ø˜¼Ç»)U/×Ö³f‹ñ…Wðm‹ŽÊkÑü—ÚÄ)h×}§ëwβ~ †'gWýÝ "z½ã¢ôøà>ÀsÈŠ8Ðѵ \ýo&ä•S½~Üä¼CTœ (ÀNâÌ é1ÿOt† ò…Ý\CÏ…E¼’–ã‰q§Û¡ –ÎJ«;²¸Jvæ @õ¶y¬¨˜8?©%çê˜Ð1ÞÖ+ꋌQ¡´1EaŒ\˜@bî´éœ5áÄ?G„!T¿ÞJCUùA׿ù¬TÞŠ9çhOA/0àAzš¾¡ÁSŒ¤€ŒI>W¶Un½ÝqDoÓl "”d ®fÂ¥$ý"'(Ÿ…Ý,Ëãß›!›{ÙY€X¿††Žæ'ÿvDêêŒ3®#©_gŠþøs «"?|’Áë(ÓO„ÊÉfUІJ餯ïÍF$š»ÈÎ< :*¶iÍ%ï=ÙyxFëjJ%GóÛ>o´zIHúj~Ãî¯ÖW/Í<¯J[ìä¶×l–yÕ?ž1–;Ëjyþt}{“ŒQÕVŽ|™.zðÉ`S/Ø|Ò—ß~t1–?¾·ôàg±‹š¬y8˜ç1¼ò[;Üðz/ðdô,€ú(¯à–¹i&”›]–¸m&'fP ‘÷¿€C†|{€¬®ïá‹‘¦ÃI6Hƒæ¾ &¦Â ”x#ŠšÏ›H¡×fp0uÉ|̘4½<_Ϭ·;_öÈ0Ö·.Hú3ƒ ®v–:ÜåÏ"ú_¼'ë0ÇþóÞ½-Ïÿ{ûî£‡ËøKûÏ9:\­PE ‡‚É»q:ÈÏQd•ˆ22ðWͬJ­ÜHK…4 (;qèX¡óæŠg=§×­ð1ñU†ÉðÂÚš ·b«ÚÓŒHµ‰÷9»IV­Ýp!Ù‚¨®´çÔ©e§g°ÈA®x­ÔdÁ4£Fo³~T†¡9[ „°éÕjÈ1âCµÒ¸ËèËÕ”U+Ûô´f†[ ©°öµ®2˜4§è>²R­ By)q=JÜϘY˜jþöÅļ—ÕdÀ£«jk!ãÙ› ƒ†SW\HgAÓRpû_À@ô¾40âH¾¾TÐû#èmÖ„éõX€©ÙèÝ*Æt  Ù“Þ€9éœP—´ûå“B×ô Ô9)ò„Ñ=\C½ªÇX™Á^ F‰w7Bæ‹¶Á§P,‰ÕÏLÿL»®IÎóÿÜòý?·ïß{°Œÿó9ãÿP\þ‹¸MIÙ9J*zD?ư‚C~šÇèômˆ‹ü$:SÈ»hmnžf“³éq³›6ÿT£ùp( ën÷óãÍA¢^¬ñ&%”±û™µB]ýùþÝŸïß÷QÙ"Ìðj¢D˜ŽšÍDñðE3K''Í||ºy6ô7Ç'݇ÿyï?W‹]-7î7·)·.UûL¡·.Ò‰ÙDÄîCô‰È²ÁÌßWüi|ù´YºÓY¯ÿ¾i©¾ûý¿oÄ«¿ÿÇ­æº*‚€’ºpçÏhgõWugˆÝ¨=houÔ«ÚÞÆÿÞc>Þž‡3EL%#È_¹æ–..‹XbëoÿOÎ>:À<þÿÁýG>ÿÿpûÁÿ/ùÿÙü¿æF=®?Ä!kæÚ˜Î¸¿#îZ.øzÙêU½VC}w­íï£ÍæÍìCYd˜Ä¬ÐÓ¯÷Ž~ŠŸ¿üñ•⻦#¯%Øåݪ¡Ð$¦x kkÈŽ±?îÖà¿uÏl˜âç‰QˆúX6ó.ˆž¦Çy7µzY'$†¿<jèÛšå9šÑæ” “8=ž]¥ÁÆ(K»h$£Êo:ã„ä Ô̵Gsá­þ'\%žnçæd_/ï?ŸÁSi_QÁ¬w×¥1xÂ&h,±+`ÖíãíRí~ÖME½&§,jnlùMœž6(ä2ò“÷ô늽øOÄÜÁžÔœŽýîºUÊï·všZSto°TÈZõlè•“÷…ïUlÖA(qS°rÉ·/™°ôr1£¤›Þ\àßÅè¿ííG[^ü' ¼¤ÿ>ÿ¯É»ÕhOÛ÷°¥‚ÞQž Ù¦ö¨ï6Rx~áPÿ8Ç+¿õóÓ¬«(¥Óq>±yí,)¢·i¿ÿН†òn>äC5úIv:¥|MìéErA–ÈÇ ó9QÏh9rh‹«'#=‚²èDš’¶D¼Ôó])…ÆÏ–I’7¸”Z+tÎR}ÁJЬhètlšiëÊFhþM­ª.‹é‰…Ýl6DFÑíZsõ²TWõÛ+2ŠÙ­ ˜¤„´9ð'®ÇžØZ­©a|-´õkµÍr…Ј{<Çc<)¬D¿î‰"8u{õJ®Ôfàgâ4ú”`/¦²cƒÀb§‰mª~‡€0ÒîE •N2šÄŒT_Q‚k¾×̱V\JÓÄ…M¿Ô2Y¨ã‰ˆ¬Vðý=–Âe«è9˜|+V|Ïjàû"½ZÜ´æõŒe¾aÉ– ÿèÙWGfý,ùŸînûþŸ[m/é¿/ÉÿXR~óQæ$²o¬IFÃüݹ—ÄÖT¶” ­÷_''¿ypnþ·‡%ùïööÖòþûO7ý€=£³S)ÿ7ã9½>Øÿñ9Äè]Ã?oëŠÍ£‹¡¤Øþ„þ òcéð¼Y¡#½£Q¢a6PîéT§Y ÇS+ TÆ$;O)›H«&SÕŸ{ÙÉI ™èö0 4Š–’ÁN–QÌZ]3¢+>ÃU0«ÇKý¥œZ¹™N‡ãsʆ²B5¡†—4†øHЉE¢qN=ŽO|ðê—£ç/ÿïüåPÚ9¯Fˆ²Çç©›O&¿Žñb(í¤j¸©P†qŠ!*“,.ïMytœ4óZœcüºÌ 0jÚ›Ftn£¥aÄl6}Ú5\• kÍB!-û›ö°zíhz.^Ó r[Ýd”MDoi;œ aÍ“l¿ûßó_îçé×ûÄ üOlËg·ÿØÚ*僔–øÿsüxþ?ôOÙù‡_¬SÇ ’Q#j‹˜õSÇÅpox¡Þ’=U9;VmÆÉ°P|\>vòª›7=€ŒLt™î˜ËÉž~³¦ˆ¾Ë‚œ;Ò®3\&Xx{“ðÛ+Ò9CaJõâÝ’ÖkãOãËÍõßÿûJúmpwÀ f'ü׎µZ7r„òMf¬˜S¨q£_€¯JØÝåð—ׯ_ÙXõÑzÔ^»³4Ú£0BÏt:'ýX1ŒÕöüø7<±Rqãd€©8å÷h‹‰<361Æ6hð9Ç©xáæ››!¦žAíV‰•70È#N‡"ƒâãŸ5¹(6»D[Û‘ —‰›\>‘?ØÇˆS_íDªÏ6vDªn¹x] bflóhrÐKÈv ýsº ü „RFªÇI³K¥´ ØÀÚî㘳\_}¿zIÅ|}àŤšWõÍ`*öÊi»;¬U/½ŽOôù@nžÐ9Ùd4R×p–º=t©WEçhzï§#0tê ð*ú,м›)š*¦½–hÆcVýms@…¼e®¾¯#Zðöo3tc /ûðufLªßâùx[Q`¤ÒüÜ;:W¡jEàás î^.¬#ÕMÚ =°éçÒ䢿hku=ôöÉ'ØQêΉ±ê8íæ§CƒP³áhjT¼àB¹˜â¥¢nÓ´wAÁÂw¹‘Á2­À Mmq§çi»oj5Õj:´n½'ÖÎìÀ©z³’®Þ‰:^Mœg# bDv5ºV]¸ƒåÀ†4Öø–c×Ù‰€ayqÚÞ•Dò¸ÒwjʱXX½¼2»\g¢ªäŽ"«!âAŒ˜ÍÅ®‰›nq"ŽèÑçËFNgÇY¤KÄÓ=w ¡ œ;Õ[h-6qòF÷ªÃ˜ÖteÔä@”+b÷àcöL,á"Kû=D\¸7µ.ôïàÜXã©nÊKÓc Óìôìâ+/ÙŠŒ.fê¦ï²b¢£©‘,€W˜Ñ«×GÏ_½2EƒñŠÖpWy+WVf]fE8Õ­"Ëäk蜱0%ÖÓG%Ÿ^ínå#–ïhy'ëQË` W22g™¼i‹Þ!ãXL°±vÓ Ôă|ãÊQjòFdè-u¥ïÒn…l¨Ü©~£ª;åõÉŠh!YéI‹ÁïJ YȺ\Sp t⻘×"ûe`±€R´@_ÄkÞ<õU7ґʈóÐÇÕv°^à-+ Úé~ƒ×]rQªŒXVÔ+‰6ºž_+þ\C1Sà¡n½Ò;˜TSÝé„“±!>ÃäôJÈãÞmËÁ†`³¹XBùY?gó^:a +½æ¢‹öíX³ÄQÜî„ø³à{š>1h>mI4ü´gâJfÿƪ>ùøùá02”äáY•KÈ{ª [äK¡oouÚsà­Np‹œ“̰'3Õ–ê¼oXÿG¢?#<‹'FL÷IóÿÞÝÚ~°íçÿ½·ôÿû’ú?+áåÝ|ªÞÔcˆƒ½¥ÃÃÉx Š~('i¸6‰Þæã7àX~0U Àvó^ónÄ܃€ÇSE¼ŒUáF?žbܽ¬(s±¹µ½ý`KÊ‹•[I¯£;TO‚SbÿûÞMòø,Ô4\›xúå`ÔL-í7mì°ÓOc™³ÓlØ lÐ]&#Å–¤ô§ï£üh÷ÈbØŒNá*L;öHèÅÜc] ó¿Ý­híìè,ÝdGCÜSŸçjKK6wOh…Q@Uú5xÚ~…ôŸÕñb€Õg±){Ê í B¨yB{Íåe3AÞ ˜—Q«T¾ÚN±jk>¡"ôII?SîÈ ÊÆvØrj+^|r5± pvâŠ$]¸G”àÑ‚Š’~-gQvGõ–:©dØ=ËÇ-z´ld‚º°&óÜÔŒ-ãq—ÔX:ÒÛÂÈç ÖÞ›k&Ò_¹éfe3ê´"6ž¯Ò&ÖÍI2B­Z€¿wzWÚdNʲh#ê$ZÛ]‹ÖÙdrTk„ÏŠøªÕ—f·Î»+ÍÒ½òo†Œ#ÙЂ7ˉi„¬–ñ‰ïuiäÀºh DhEÒ24²uâÞ€P¬¡Áî})ì¾–|u4ÜbƒNÝɇm¹ÄÄkbݹ#¯ Ø•ji=¦I%ª_ŠŸŒþcûMZÍ¡ÿ<¼çÇÿy¸½µÌÿôí¿á Bp®ŒHÔ “’€T(Z˜„<Z5PâìÇê¹=xþü†Yì^ƒ…)Kjí8Ùø÷ÞÆw~{DZ¾úåàé~üó«§{G&÷¶úG­yg·ÞªýÞ[ß…hû-E$ýÑ\ß]«ïþ‡nýãó߯y¹÷ÂâCÕöOokDdjËÙzˆÄLÐÆX=°‚$´›¥þHF@í¡ºµ ùç"Ô4 fØ>>‚6er—ˆÃY¢ ú3둈cê=DF.<ç›>(Šª#T2|«IB±€V¸65¯8vq1MÔ’‡¤vÔ†Y®p¤ê鸶UogÙÉD>g:ð`[4èT†6öÀ&ÆvüØ31–ÍΑh­þ[3>â‹v`Ÿ˜M²ziÑg¸#â+ˆîb`Ìd[Ö‡ˆ/dKãô6I²¾¬")ï³5å¾kuÇ7¸Ãóz/ãOdC $ û§HܤæhzÜϺq—GÔ_อÌÄ/ʆ¿l—´ßg ïDV Nw¼þ5Ù+úñÆ,¦^ÈLîHãˆXJ›°¿zÀEÉjLîÒ0­¨l×`,±=K\ÓºÐä,ÚB·,^ÆLÆw³¦T¢ÿ¥I?G£¦o¦çµ‚P"5õ_·ˆ®G–¥W|‘tÐRJ*p b"ß~x*H)ŠÞð¢¦Sí’u€\ƒ=`¢¿„¦Qsg \“4|h4/¥œîÞ©€(¹(³>b)4ñ?èóÛÐ ‡‹ŒÌW27ÑÁšaqCT@“Eæ»Ø«05`ù¶ð/.åÜvß „Ól¯cÐQ®¸Ë¿°§M¬¶ì2z7 dï4}OÿàþEW̓øž¶ªœŒ{aHµÐËÚÏ)ô Ž(ë“wœ„ú -ƒ†C×oÝdX SfŠ’ÊÆ‚Yg“ù³>ý&}k¢°òš J}ûÏêMÌ$’‹´ëfrpª~‡•Eoì¿:\a ÿÖê%L÷ª…©5hÕïÞ½Ó*{E@¬k6OŒW/¡¿«è,9O£ã4ª S¯qr™(\ÙO!òâTýõRÏâÊ&‰‡a¿.Öòè Ÿ¨½Þ„ÿÄÇyïâ³øommmûþßï.ý?¿ ÿ÷!À\;̧?ýòò¿âÃçÿ "ö­‡ñ½ÿ¼¯Q?ENí,íÔíJ @óyLOÏ ]‡àç ?’Ä#²â¥gÇ믣¯W ¿ÏêžL{' 5«ÑËT!†Nn­‡ªç;p³Éä7&txyŠp¨°jR )S ±Y>J‡5N,3>^Ó2º¾#™{{“«uϦCðVõ¹ ã‘’®äô^ÿH±?0 ë~ý|–½ÿÓIÖßtâ3Þ”p¾ý¯oÿõèþÝ¥ýï¼ÿO +t¡9=ú„¦Y”Y2©W/ª‡ÞÝœòìAˆʾ¥8ÇW/ö_ÅGº³Ë@îËÃÉ…zr^L1«E‡qÚÃ¥@Ë ã’0Æ—Æ. ˆÈ®+Sb‘êòãl˜Œ/¼yw’N6Љ¢,¦æäÝDU›¤ï&›£~’qÐ÷+/hƒs“ÀBG,J‘Ê1›ÇýdøfwÅ‹@X–v^^Õ1—%ˆý@j]Lû“÷ü/IÕoÕ°°ŒŠœh "Åþ$Õìœïe§8S“ÝR$p©¿$ˆ,Ì/Çÿ!þ‡HK7hnü·{÷Jñß–ù?¾$þßRL+‘èŒêd hi” Õö_>{ýêùË#]O;¶•*jgÐç/_ÿbjëàƒ¨÷¨lòëg÷[õTjÈDW¼VªpøË²N1=VûU­êÕ]ú°—K•~|uðbϬ„ØY7"ÞÁÞÓÿ²ë…Èx…b%½Rõ߃¿Ç?íþdZècˆ6|Ô­az‹4vgë´v§ŽíÙÓš:€VˆRt3g(§jüÓþÞ3_¥&M62˜ÑôõÞÁÞ‹@KÒ … GpÑL8myœ¶ú†Úx@¢é7õ^yø?³ õSþÉåmm•ä÷î/ñÿ—ÃÿíψþŽÇ`+ |°›2”hQýu“aTLrÅ@&`HæÞ}cŒÒVQ(;Aâ´ \ª"»è¯ôjêè[½)$å|¤a<¿Ð‚yزQ¶0òš˜âXLW6‹ÍÒœ¯ã^HQZe8Æ„Å-|$Õñ$¤±bŒ²´°BFû6:íçÇIßr~ f*·B®é¯Bâ˧ý4¡¬À]¯‚ JflÌÇa>I£|(vÛEHhÕ]L=ß*ͪjNωùË(Y-„„30–a$ëö'Bþˆ§‰Úz…~‹3Ó“®Žà8Œ†Ç°(µ¦ó䄹C v²*Ó ÑtµÊõc¨_oEÇŽ‰NS‡ŒæøÝ@_ L¦)ÝŒŽ·J›./§ü%XÂÄ+6C éq³J9‚Ù±Y€@zÔ‹bÀpFàÚ«fçD¤9<Û¶ìVLXÞªÉW55—D5ôîù¬f¥;†Á!ð[¨·›Ð…£ †^=ÚU ËÖâÚ!ÕêF_ÍÀܦÑ8¥ã‰ê[BŒwKEL§ÄG!¶(ŸŽõÁ«Ceœ ÂW58fºfX3¡@ÌÝØë¹ Õ4õà|¡]©¿|ˆñÕJWN+uÞ¦cÔÖ¼1‘VV §ghÕ=N¢]FЮîÅÞ¬5)EFB(!«°Š3¢_li:›fÉ1/yÇôªèÍ@ÜB}ùo€ì©à õXõºx˜‡Ûq5/Hú4®¸ò€8©ÛÏ! ·úÏûÈþޔǥO8ü¶˜|ã0ÈF6Ü€A"5ÈH 1¢@fÇñ0ž˜Þ0齺¢_æÁàåÉØ ;ÔýPÚ{˜£|<`5RdÌð >K\¼®(› åºÇIBïæ‚À‹€9°."~žuwâ^ »"ozi{/B·^a'ãݦ~×$·ããBW@ÅV—‰|í×EÛ ˜Úª‰2¯…÷„¯ßb=I¤ºx‹õz"f]¾Y½ê[E×iVMù›߫¶{&ö ªP—N ÆßL­µ Ò÷t¼As]ˆ–³ÆäN¨×õzõGøŽ±zaâšzá5’Âj¼d¾oz÷Zü/mnÃcÛ’[/K͉¶Ü„BF8TOÂc«Lg¶7Ó ç̶%¨kÍIÛ®>…t|ÿÏùñâàyò߇Û%ûŸ{–ú¿¯ÿ/±ÙDV‡yZŸ€©`¬ äò°N€’¡}ðù Ô©]3fÔ Ô“hwjnLjÑ–®a¥&;lOj¶‰éesȆ»áÄŽã€í­ý!.zUH" ñ ` þÍp±×øØ„†bptX/í/~¯7Õ™N þ÷¿ªC+I$Æmå#Zéw„d“oåZYT™L]$¨Üòi0ZD>AC~9a¯ï'¥¢íb;¯=zNÿƒJüÆ€só¿m?ôõê×%þÿø_qÛd" fÅ$&·ÊÞnÔz1íO²¿„~Q·¦å|6Ê~Sú×ÃW/Í™Ë[•ŠOcß{©êÿÂúŸqzš“1ÒŸ7†æÝÿûwýü?îÞ]Þÿ¯þã¿,X8D EOVÄ úuÛ'Ð/©ÔCI'tžŽk:v·ª¯xþ™¦»¶Î0½£ëjoͪšKâEï¿Ç…Þ8ÿ{t¯dÿýàÁRÿûõðaÝÊ—dŸ\‡|òaÌ_»cd³ä]-„:äg­h¤n2‘”=ózïß«ÖõÊúþLí*-È+yÎÐDDº®@…æhZœ}BÆÔe*Ÿ”¹Ê'7ÃV†c€u,f‹L/Œq¬”-âc xBü}þ|•,ꇽkþ¿Q¼¿ þß¾çûoƒSÀÿ5øÿÓ þçÞ8ÿw:üâ/8ÿÉ™\çÕ`µµÛccÅ]»ß1\…¥p%d‘ƒ¶?äõ¸Þ 5ã¨|mÆIF ‹*×´|—>ï»D&¨4awkFÂ_‹¤çvÔòÞšø«EÏLvÒ(MÚ9Q×á;â¨Õ¥$•›7ã >v²ÄWEÊ@l¬uÕïˆlÙâTm¹lÓÉ)»4o%ÁЀĶ?/ YL£ëÆ7b ãã@`á¥;û‡ôß(ÉÆ–è ¬ÛÝ­Û«—ªâ•F6·Ýî»n£²ƒ-`ïV«g{7–hzÇØ:€ýÙ©q-„ôÞ{3ƒð!5õ¹øÒ=È~3Xc4µæo *Û±ÈGŽ¡S…\ª3y/ÚµßmÌ‹KàAµ³w%òd•¿·/v§ þA L¯båò{¹½À_ÐyÀÙ¤Ùï®@°ôÂ}³}E£Ié@&Âæ'ê@ö ´ ŽÍ§M]€Î{¬wVZkÉ¿a»ª/ú4…Ç»ÖVY¢@CÁŠE^B?¸÷j&²÷6ÒLû½g>꽨¡8tMè–s‹ åÄsþ]z⌅4ïÒlÐ]òjß ÿ÷nÐÿìþÿw·ï=òíîÝ]ò_¡ýÏob Õ¿Öú‡>ÚX—yÏ‹úüB13ºŠg t¨(ƒ^2î- ¾ØýW”`ÖK(ûÍ¢€¹ñËùÿîÞ_Æÿý÷U›ú\€Ëy–€6FïN£7Ãüí0ú• %£—÷ð«¡9züXF­÷tAç¦74Ro¶èx‰ŽŒ…Ø?ØÔjDE>\àï{œš•\žRÜùT5dÏã©Xœ)ôDL©Žñ‹gÝa¼‘þC¨¶œ4 ·é\bÉÔúä˜éÐò›Ñ!9¨I—cî#’;Öjý j®x>Ô´ÔØôZ³“mÐèšœµ»Õ¶u€yc¨´rä§^:sˆr߬V)ÕYwÿ»ð¿MðTÄ™Ì>/ÿë݇¾ÿÏöÖý¥ýç”ÿ‡‘¹É›R&‘HyP¤œ´H&ÁhåHjâtOóóCv™ak6e[}f §ã\ßµàA  v Hƒ|h"ÃXéÞ1ŽgÞÄ.ãØI¢ð gYÉ(™$«ìtˆ(pBư¾²A*\GðÚ„Y5XW™¼}¢aÜf-Úú6tîÊÔ2ÕècG&¿Ì,q¢k©¥D¢ ¼dý œ1 „È é÷ E§tÀ^üˆ=J qç`uUù±#ë* :N{–•ÆÏš„@s+‚úfk uüš§ÀßbŒú&¡˵Ø+ħ”†&x1!·Ï8õïçq€ÌžÔ½# k‰bº[³×·d%'„|9Íヒj’3§†_G…Wþ(Ä¡½@cj,û:rž °7~°9—Ôo.°²R\ŽtRÄ(ºÜD$˜õ¥°<œ°[rK,÷hªÓ¦yWäBØ.Aîf:%ˆ¯x‚âƒà=ÕƒìBL˜JX ßËØØ•y¦~¶€ÙÜŸœH'´ãº ÚõìÈ6`ˆß¾ÛqÙÄqÞuk±y¼WÏVÞhKY}yÁ“ñE­"wuÏ~0Ó)pÝD3à3™x«{Ów rj‹š&>Œ´ ŸŒaisfGÄB"»>¤¸¯€w€¡TøFFü:™öûÈpÖ4ש0\«”í—\»ŽpçGU㈠*…ïñZÁ3B2‚šEStÐÖ×ÁNA¿Lê.´×*TŽ¿4"ò6$£ÚwdSkCÈsuËêõN³›FIwÒü§¢xVÜcì' íf{‡ %Œuh©¿¤`‰Ë[õȽ€"ƒzz31‚¨ÓŸª{ÁkŠþ–šÌiœ§™CƒÂ¢¦#ü¡ »g4иܜòÞ8ÇC›S™ßh†×Äçäæ-­-@ÖQ2zœ£ íHçÛnéí‘°Ëíöê¥úpÕ¹ {x•ºØ»FZV˜5päVI6Ql¼\½Õ84îžÕš®x9=ÎA!›6L«PÐüÐÉÓˆbºþeÒ”–B*ú„ç΀l».¦Çù¸— 1Rl.æÝˆÀ¿ÑK ’›Þœi;ÚMK¼²“³iSÏ'bƒdC ÄL³üà-á…ˆ=)ÝQ±)·fíÊuF¤‘%êAœ ©¤ ;/þ5UVO™¦ƒˆ=¥Î®§NÚh?dÜaB€ K@Ÿ4ïð™]R¡´QpÜ¡XìaV|•§lÈ u:-Î|ª³†]6¢;w€.v~o¦²§J¤¤:D>K(3 …ûx?Ád!æ’­tk-µIaFh,P§^véjöøqtIûK¹Í£ïíD£«_oØ•3r•[‹¦qçs‹5ÈÅê>ÆÖâà‹šà ½3Óö­8OÑâAáyz¡‘E–³  ùžV=b~m;ªh^¯ŽD\°0ؾš u‰ ÓÏH Ç€qH¨Uu€ ˜f9w†ZIäÓPZšG\þÇœ‡º²»©z-Ø* þÐWðÈýþ¡ÏôE:žç]~ÌAp Â:­ö&ÕL@j]%ru×…}ýÆ„+®]ÌB•š¾˜â©Á–¥©Ýt x8ǵB‹0ŠúqZoúHïˆÒõ-éšÄÑØœÉµ }«¤¿g,ÈCÂPXVpÀ9 €!í° KdØÀ ¢uâæ#Y AÙþ˜¹eTÃÓ©¶·:Ñ®ùUtKd‡À—R>õ@dzôœÅèL`í#ú ÀY÷ü/°ÈŽˆÈ}R@ð«>¸R©=ýbWè1·sÌ1)c÷p·CÖÃrÆNfg@6ŠSlñý¾Z©ˆw/¢ýÔ²¤TÑ” iÞŠä†Ê D1¶¸ûF'¶Ìo²”樗ÀÇ(+|碥A=p[ä½¢Ô„|˜×Ä6¦?䪆ªAÒs䆑’ØkÖÍ/©¬²iœ÷£³ü-ÝWÌ«ƒœËq Ú–"¤¹ÀÖÕÊ ?+$;J»Ù ˜‘!ê^ ‘’N£B“{‡I%cçç©aêDwÌ[]­0·Áè…VF'‹Àèl8E)GÖÃhT §EËSg„Õb#ý€îò¿­è'/à¼<4} |ÕÄ Cüÿ±ÇvÀCê¾j7t³á 6­+Ðç"gþZqãii>T?²jKYˆé¤ÜÈ N … MT…äw– jkªâž}ƸS%@ö<¤œ ¥>ë++³ÙüRmË,P¿~Ýî^K½y¢PÞ$Ö'ùg‘Ü`ûصí¥!¹ZŽ@ ñÇn­E˜º‹I§…†2›4¦©²áI:Žñ›ê¡æŒ\Z“[;²”'“tÂ|“a.Š®µ ÆY²÷B ŠP SU8Î-ÔCòjTÿ¨—*º+~¤Zw`h„Ÿ;á© û¤ÖÙ‰¿»»5]OlªFɽ íïî JE:éËð™ð#R:+õÀm:ŽÐÿå­ˆ˜\ÞZƒ Ç£œÊ½Þ˜7®º r ¥iÅbÛ¸š’7MÄÓÓ1¥è-ŒiCÒ‡ q/ze¹9M:z»¢Ö¬Z++r/›zºð&êmcé8E "z=λ zÞQ|I«š¢›C"»@ý¨cI˜N^¾:¢d~xÞn>@“éml†«˜)É-à‘¶Û ÇHfÉ5Ev/3ö‹o5ñ»ž`#ò6œ§P—“Ô7€‚àÙ}†.zÿh{@ŽyFQúEŠAàjZûætÏÒî›X¡(PèM2ˆpIÐÀÓ©ñÈך-.ßNÒöM:Ò3-‰=h‹?l%ZÉ»(1D ìTaBY©^wœ:v,T"ê‡ÈŒnÞïƒ ÷eôm“Õ/ðo‹Õ¶FíØòÄê¢p|ëô¨VU³6ìBó(ú™aõ”F'IÖO’bbiBŸw¶<Ä š6U»e*Ô­u‘ýWÍÜ =? .Nȉò‚BÚEž×##òò¾ÛGô»ï\ü¢K:..ÅÁkkºt­QÑŠìÁå&úâÑ(¸|3¡9õ‘R$§i8éÒ°\a5úöëm§dÕ¦†hUºÝ¼†âŽA‘z¦î¼HƒŽ'jΑ »ºi$éߦˆÞæã7À`H·ƒþ…­»IascñžX[Õ–®„„¡VôK·›_¥÷¡ÓtjÌ?¸Š¬q2?–§g)*¬#iµÞà_Šu2¯XoñRa—ÖMOF®û ÂßðVLG£~fù­ FÒ2PGv\Œ†6ݳ Qý ?- LRø N0sõiŒ†!ã|4†$Âý :d½Íôá.Ñ]NeøúhfÒ´½´>Ð9º1_®(!1Â%’,ØNGõ1P,»0¡C?eÀ–ÅM9™Ž%¾@¹Ì‰ÝYÿHÌîúl²Ü*–tÂþJ¹Kè0ËšrN‚›½[c\{Î 2]ˆÐgK›ß¡4³í¨º:$)ÒYnIšËwYqí°ÇPµš±˜‰oQÚéáZQäZÎ…”rkd* ' ôXhë=E(¤nÖˆÏAÕ´5ð Õ\’•ÐÁ"”*òKU*ÖglìiÅŒÁ«§Çš éŒ¬Ã>pNs)ß«bæf³v«ø˜í*®³_Åu6L’F¡gšê,ÖÞ%÷C°â³'IžÐ4Ú nÅs|_!&¨:úšLD/ç‰ÂáÃɽÆDYŠWo1©+…fÔOw%Õ<ã*W0˜°cÐàžšÑ Õ}y³C § ´õâÝ‘s «Þ«Î.|<¡ç¨^´ú'Ë)à9‹¡í;ý·Tû¢{¥¨ Ùä`1~³o+dþZÕû`¨Óî’A"ò#ë0'¢{5ÉSÚ“÷&fÆëü±®|øÁ}gzÏxÕhœ ¯²hÐl®ÌÆþض¾ ½ÖæÍËae@%_ð]‚ýŒaà«*ê&}pªºˆ è…=$ÚÆŠÍiC‡,dÀß;#À _ðÙ«—ÔË „ÞDÒbÀkAÄ ÌÄŃĈ–ÀÛ4ö hU ÕYR0ýÉz¨ž¤13¹ÕXWo&ò ÀT¢´Í®èã¼€ åDv€QŠì8×µ&a}s]+,ylîPƒuÖ2¸æ9_@Ü…èYî…Hev£î‰;*/Ì5oLÕhlÇIæL'‚‰ .ƒõpª^e|îZ3ŸÖRŠdÉS]Å »SŸ¿‡ cîêŠ uæqÄž~Žlí \¤/!Bùló$ñ’ûD_–I¥nÊw(£¾Å.’¤CŒ~òÌùeÀÏ„ë .ŠÔ^VfË-QÒ‰Òî»™F“‹ÝàÃ8óÕ³¯ÆMÈüÂ×E +Á΃wvÀã7`« ê콪2éx.–ñ ?R2$EZf%æ—–^§œ~wÈ^Y²iÕBS¡í]Þ©° ö\µj‡ êQEpqµRWè v¾|òuÓhÞY.¶|0%u×ïM}ÑmpáDËÚí^„wáSí·úë­}Öª+ô‰×•Z¡ž j+l’D ¸¶Ñú vc† F«3bÜ,â ÜçN+DÛIW}²”éñGª†[Óƒ–P¼7õV ý¸"öÃGujõ·e•.ë|Ô2vD+d ð!!v?|TÞÉ·üõ•ùF=ÆSŸc[;KÉ3ó%/¿Þ¼¹Ô“¢« Ç8úD?-¹£§u_úݨ͟ÓÓl¨_«¦Ú@ÄLý Mók6žLÕ­4ÁÉZ-¶}õÙp*ôøþÚƒ?Þ—{kO³~ñÆUeü#‹QL¿ú-=W›Ä*x9u72ý¢~‚ŒüwÿºÁåÕ0kª”)&ß ‡Ár˜õõÒI„.i,ÚT×k"=xµQms”Ô‰{Z9Oi¤Mj +C›XÕ Ö.© ¤}®·PGG{§S3”% ’û@Ée…ûn¹vŽÀšösË)ý–°ëõf9ÛÝs¿v<æ ªn¤±SÊjßµ¨÷ú2ôÓ2þÓ&a°›Š=;þÓÖöö£-?ÿûöÖ½eü§Ïñcû ÄkÖðì7ñÙc±Ãxm¥ªZWm_>À§g~e-§_°:+b+ûŸßæŸE>¬.=ÉúéÚÊÊjô:™("„“òÁJûUÍÔ|Ý¡)6@q`/$Y¿¨ž:ö*g>‚ÕØ‹ÅÛZå„$,Cîa(2ÇÊ#¼®kET\“t`"G­Z*:[»& 耴ˆ=9$ÈŠ'´Ô¡±ù;Î4Ôhö=ƒ÷óI¤Xœ ™¯V|¬ý ¸W Nú.³ t;.ÊÖ\Š,7z ny ~³QNª¢uaP©¥ç†¤RwØ—Ú}¹èÝ—¯¸)ô_UWKwY?H8Ä*ÆQÌ!Á21 8^*h±.I-å\¡«¦Ì§‡Œð÷9‡ú)ÈÊÂ Ì CpÉߤäÒÑK‡ù$µ{€K{LÖs]ÜhVE³¶½é¤ž{NÚs¤(ÿìJåq†`TA†w5FeÇ*UR;WçÓÓ3¾TÖBal$ïýü4ë‚nºžÍëƒç/ž=ÿuÿ"#I{Iˆ' vŽæÛóá$=MÇ–ûû±Ÿ'´ý‡ìô™j )¸—†Ô¯P¼%çÔPg9iµ~©ÅõÒÞ™±p2©Zg”ºòê°&ãiWQé©Ñ(üòôè—o›]ÿ2;µs4AæªF†@ @ƒ½ê¬¶¥¤ßÓèi´øÀÂLóõþÓç{?;ºTí|ýUáwo®¤½Ò…Þô[-Ø;(„Üj]k_y ÿËÁ«_^»[èêî(jÚBs®ÜØç…°y¡«š€Wÿ ÃGQ{gÞÍO‡Ù¿ÕÍ;¾ Ýß­²rââióÜÿëļH90e‚ÐÃ’¢Wšâ¬j‡%søyºÌÂ|C‹¬ RÖpVpÏ N+ã݈¨f_fXÜ ÙèßÀÆz«â 5> ¨ýäTy½<¥˜+éÄÄk-d|GJå5Î9S…Œ0ä›KûÍRêI= ÿì,®Yü쌧íÅ¥jà•K1¡Õã¨)ÈHë—qòæl¢Ѳ=…‰‰B’¢hEmý„p¨«u²H§™ÁÈ.œ„gè?‰†ñX,ø‚¨8Ü jꩇ~¡—@vl»}þ𨠭9Œ9ª5ÕQß uŢL<ËÓòÆD§K‹ÍJˆFû!MSSûZÖL›Øºö/à!º\D4£öõˆÝ¥Í2lä'ªýÆqþn7zJ µ~ä@ú¬'ï²|°Aö«Î ·Nƒ­—ÜX‡ê3°ÎŠëÈõ†ûz’Y4œff9”_Þô›¾aÄ i¹Êb!køŒÃ ûX5q+¥N{»ëÍE} ‘ ŽSñY¤ëC›-ñáÍ#¹ø­8îý\PÚöºj«"Žyp JÛƒÓg·yú'ÔÐT×üd œæ8ŒørªDMáQYþΞ¯‚\4¯"ÎĹ?»ô.˜çeAkª˜yÕ]×ZÈ/?ÐECP•Ž-5⸷ Ão'ád¡/y‡˜¶»ú$0 ¡y—Ì.`Œ²sŬcVÿõ¢Ú¥·‹&‰¢Û¨Ê¨.øf%;P(Yølß§±õh¶ì÷…4$ÑŽxÔeºq‘7äƒ7RÞÌðªüÍ  ZÙZ–UíærDò$a‘'1>[˜cP„?F>ðH'2$ÀHˆ' Œµè…·v§°´fŠ}fé…öòŠlµ™$^ÝOJîÉdeHè‰å—²Ùb‘¿¿·|âY½­ûÜòé3¯Ø{ǽÒÞõ;w®[ˆ›ç¨ p«CµtÜMªÐLùyš½­¥*â‹Êÿ]ð§ËÿõàÑýRþ/õ¿¥üÿëÉÿ[þM‹zQ`[¢ Ö55*ˆOðA6fÑh€‹ºÐ~cD«ð×¢Þ§šäY'T±n\tö×BJÆv¼Z\&5žŸ(T;cÂÚžàß2„äIVEŸSÜT–@ ^J³³‰ðkcw0¤·yUb$^Ýé0‡€ÕS|àHØ)á ·V»i…¡íŽá¨J*+ƒÃ½ÿÎi3ãâ–ÑÁHÀ'*à iÏå‹úe9õÜX·vêß3e‡¡¦EZ~hK‡Ò±°§X1! a]‰ÿô:xMxF;nLën¢¶3Ö¡ûª^ruœž:­hrÍD÷³úògªH.’TŒÆéƤa½w\?vŒœöûÙÉÙ:´Ü¤cW^/(ÏÄ91 ÝAªy¦y帞Yeµ”YîŸ@2ÁˆòhΧ֚Óï ¢€ ‡"<õåÛ—W·ÿ˜Ó±ú/´;fn´ÓzWÁböÌé"„Ëœ‚¡/TGùDZA ´w½º)9’<,ÄüÙ+‘ (Bé•”‘Ž^¾W ¬´ÀXxs½àæg£Ðò AÃÍB ´|ÁŽ×6 ¤€ò ¿ïßójÃÿ‚k-½•Še¬¡x›Œ Ía¦gÿ"[~,‘bP` kVóJ²¡ÙZ niõ•k²JÈÏ6+¦hAz3DÔÖâµÀ9˜T>hÑn(E:©µô*o^^Õk%6ª½PònøµóqÏâÿÆ=Äαÿzø`Û³ÿÚ¾·ýhÉÿ}íüß³•rÐŒjæ‰Cœêˆc?àHùAÅ7…“ðY¤¡˜dÅÉëIÐæ³m`?ë[ Ö¸ œ@=O5‚Ìbƒ¥òX+]lÛôwˆv,È€ªÙ•U vZ ´ö …ÊŽ0Q³ÄH+À¬wªã¯ƒ D}³õo:é6ëzC1Ç ¼TÅ´{&c‰¸áLt¼È«Aåå>õí>6ø' 3Àƒïªâ]µ6Ò;F!4õ!Ìž¤TxÉóuíAN†[D60ÊúY§\%‰‰×]91××LÎYj¬ªØÖ)wx|u†8!96ÜbZ[÷«ÇRv1¦èD˜ðpœ+|?Àð¸…UW)÷úŠ R´›dhCga‰o‡ù=$\„,ìBçZÑÕ=wk i†ç`'™u½9$§PThôa“y'J?KÎ3H Ã|¤Å±Š’g½^:ÔšOÛ^¸×ÌØ.8Jâwåõ3V(®pkœvS°d2†A22=…)í¨ƒ›ÝÛiÔV'â¢b¦<Ú Úb?ùÍÞø8SÐ5¾†¬ ƒ¤—Fx'YÀ‰DRHáÊ&N¬BBÁsî*埃+BÊ!º(ndº~Ô(s•HaÔ+LénðNf‚AZ홾R›Û«eÏ‘t¥Xx+“²%ŸÆ1®Yi‰÷tùåb!o üF¦eŒ Ã7™¼Qý€Ä¥=Nr9ØLƒhÇæÐÒÁ¢Œô*¤ƒ3emÑL·2í¿5nE%½2JÞÆá–â/HV¡C„ XÕ—Çã¨+ö $óm¬j0i¬òU'aínG´‹L0;/EaŸ¦¬PEá5V/ïÍòZLƒ°<ØÁ¼qþJ*;÷RØÎ>-Ýkl*¸AÅôwÙ‹0Ú´K)òN\ ¥/hRcÌ'$ÎÝöçtAL y3¼ý4+3êcû#Aá.Æ2)òAJ–7”uM´šAc»qH?ú&£ç¸†e3¡‰0³I2I=ɰÉ ×:'>H-é¿M. rëEÎÝ%Y]ÇyHHê@æðĉÔËGˆ>ççî¶Oˆ]—ß*KuС˜^©¢ÜÁb¦^Ì<’ØÚ·Ë¬GÇ3;vE_o‹f &ÝÉpV˜Æ­Yõ’‹+ðñl¢á¦ÇßeèK¡þ¢8ÇȘ ?"T@ÔYúaŸ{"X7ÿ,t𛉑ÀNDµ4¶= ‹2Tk€K„ŠKDhW!2¦ÆlA›‘9ÄÛˆü.æá|-Y^2XìÖì±³§p=Œ}æÞ/ÙZ¯!7ȆiP‰÷6];¦‰Þ:~@"õ;â˜ùo07«.íà¾+¡ úX÷XB«_’Qw¥ ÁˆõU‰ù*-d"2€ñt*\ç¨PÔFt½ÕKm_ðQŠ«V·àÏg!_q¿µæþÊ\.Hs ºDpDë¥`î4¼PˆÜíJ•[™ÕX‚¥¹I¹æDH»êg»å„WKΜ̵×2ˆˆ¾O{`¡Ïòš.Å)s=Îe¶Vj…gÇ2ÍR:*rÈbMBk%å@)‹ÁÐHáªÅÂ<ÒU¹ íwé@‚½ÝêÃ Ô mM¹3&.çÆB]uÝl•.Û‡üï©T'8È_jŸ;zœ‘…à&‚ ÀÀkNa@i_‰^§­ïŸO´®bÙdǼ?_7и©J7¾g'ºd2M‡§ÈÔûû>‚ÿ²òzkßí8!Ùƒ(ÃJ* ¶B59^ ØNÈ'ª¦`Ç«Œ¬á]sÉÒÒÓ”‰˜,:„?‹|O.¢·Šži9šÿŒSºR—t¸|ÕPvm³Á í¡Œï,Í uÏdÜp¤&PB³Rwr:.Ô³ö¾fÆMŸx’ˆ9R(3›CË]ã >c3°™5½‚½$ÑÈŸ{ ½º îVI…¸aU–ŠJOGøhBap›k÷ÄÔØ˜j²çšZÊ<¢®HاÍ0šFÝh÷U0_•o5H¬µW“†ö1þ½¸ò^vžõ¦@•–ñ¢ÍÐÅ®ðÁzQÒO?÷eç}øÍלI½9IFXòJátÞ—,/LƳÊx±öª›,f‡hƒ2t‰iaÍ•aÇì/^"ãU÷&`÷²—yÑ÷%Nƒó²ÖÌÛ:w%¥œ=ÏC‹¿ 'ε¹R¢xجíz’ú{_­ÀŸ%"­í!Ýî¬ëV ì|äjàoŒÜå¸9ê_ws0%úŠÔ. 7ÇV3CÔ¨‡ŽÝ6U¯W†>:“'4gâáygCÚåUÝ@ùz?Ôt@õj¸‹:d§P5_Öv± ˜Õ¥ptõ^ž¦·j¦ÇïËüPuà¤oÞ.}–þb^ÜD˜9öß[îÝõôÿw·¶.õÿ_¹þ?¤ÀvÍÃÈ{̰ð®Ê ì@;àS|~#šÑ^w2qš­¦ ç"µt™Íâ „Þ:ùõP|“õ?‹Š).àE‡äû(jã2¯X‚޽à0x4ˆNRLŒê„=ç [9wÃ] ”G[Ì é$ Ld¡$2K5´¨vI”×ôÁ¤Œ?´¿NdFÈž}’¼ !2â'°]În¹ï›bvÎX¥p2l˜,ljU#}W’Y–®®º#³1tÁIËHÛ ´QN;6¹eÖ bÐ £ç¯xáÍè°!нÃõžÔiÜ›v߀8Ò‘G’©µZDQ(·iª³¤ƒL¨þ¿î˜…ÿ!˜ÒgÀÿ÷·Ý/áÿ‡–øÿ3ÆÿŠÖ(rÖʧ}8mÄ}*ªãÂDÆ'Å}?ì»âõWY Å|óF:„ÀY=íÒŒžOŒñ!wí¢ÌUÎ Æñ€C¸”0>[„PšD ¿ ¼ Ñ:`uðhY‚u©ÕÎdj&Ã(ÍPº)R 37xPS³yE˜ÀäœZÜ·4–I ÚX°ÖA¿ªÎ3±rf>Cl¿%—ªÞ4X,î.äyòâÌMPFó—¸gä…® É!Кø,øõûÆ0ëw|4÷0{ ¸–%>:—xžJ¤9;¡éRhQÅÆÓäwþ'ÚüÇïÅÿØM`M’Øa­†àx0l0ù°T*kÑ^©°ê<êmRhO©ÈóôøY1\› –‘Þê¼×3¢#5ÅÚý-¢œÕj,V^+þç鬮E„^]µÕÜ@„Î+µõÔO9)妲o>-Hî„]¾»ŸoCX™¿+ÃÂ#Ff«@’¥§´u^ú€ƒ=çdÊþm¢Â]¸òkÉx:U; H-á7§î>/Qî¨ Ù=Ôª/·ÅŠZF±¨&ƒ kG|ÔLGÜ“2.#‘Ûcü]¦¢Jy‘úÄšÑßchi¦ì{4v]$&ð×b¸ ^åh ±„’ˆƒˆ5a·jPÃè·‘bÁ„KèÆß¯®uôÄKþo—þÆký†`ýÿPý¾ÿÇÃ¥ÿÿW/ÿ9rd* ðöX“Šn³ÀÅ“_¡* h©-¿âhÎ\›² Ã$¥"àÔ˜Ã{9c­YïzÀÍSG `ÓRi7‰é°o=´|p(m!<-"F—™&Žö ÜŒiIrJ ‡Ò+®…ÆäÞ«aTdúŇÆÉÒËÆÔž‹‚¡ü/8vñÿcï+ ªÚº¶i‘–nŽH:¥KºéNi]Ò!‚¤ H (ˆŠ„ ”ˆ"¡JH§J*Šþ§hÔï}ãûuÜ1.gÇÚk­½ÖÜ3žùLh„ú=ß«[îµlô šËà«]Öwò%ì÷šMû(ù h¬}¨ Ø;…pÿ³î]ƒ³æyïf"ŸÚß%ZXŸhwǶÿÃÄ›Þg¿8Ãl˜x7e§À/œóïHXã.Óß.Àq)Þö‹‚‚¾®_gAûé™v+ñîã3ü $É‚£o·BÜP| ¼Ë;¿/HºM|" +> O8ØIø)pôcäì.òõ0¾i‡H|?¨iç¸à‡8Øíý" حٱ]@;à ´ê@®øQ™ê?«ëyøú# VGìù#îs¶úc°†ßˆÝ=ˆ]Ö½¬ÔGÁw¡H°À9”õ …†ƒ­³½ nƒm~͉ý3<ðv²ó€²'¬Ê½Ä¯înQø‘€#ŠÇZí”ïqg‡Ûð~ì/³·¶ŸÕnEwöýû!¸Ûoi˜d†‹Døô@œ {>;Üh0×ÀÛÜw_»Ü›oȽæ „F’“´ö·+rî¹ï»bß‹ZùŸ†Y¤a»DNÕoe ²·uÞƒÛɃ¡ K:Œ}¤!?d@€&sATO(  ö== +ÞÆÙ€·Ê-± âÝîØ"p àüm<üëôÿ£«þéà¯ðßœ§òórñüÆÿ{ñ°—ͱáØ}íÐ’™°‡‡+HˆƒÃ¬É{Z@h9@.ŽÎö–ð¥Âá d<¼<Û;gH*˜+¬Ü¦½Ï¶ì؃]ƒ¥îí¬úŠ Ow˜"f¾ õÝeè’dí–z´Ü[­®³cœÚîìÑVžàë-¡c˜Œ³²Þ‰îAé™ ß.‹ ¾ æ ×àÇ Ÿ]ÈT{ÁÛx:[ÂTt{_ÖÁ¾ÓÕÓ¬rÚAóÄàÁ£íJ@[h©"p¯ hí½2H ø[üÓj¤0!ij îŒó´:=쉤óÏe/Cr–šÿ —«P+ë€KrT¨þ›ÿßÈøß.î¦/µ‹»ïß‚ÿBþsò¬ÿÌÍÅwšï·üÿïñÿl{\à«B¶(0Ž´a™™0ƒµúÝõkIt»Žïvö¡Ð+öܻͿýoçÞ£ù|ádø;íý°PBl‰ í]Ö{cÖŸŸvïÿñÇoØöhüñ; ê?Èdéâjý§:2þå÷û¬8:š‚§ R]㯠_é཰þ /ÿïüÿ¢ý¿£%þt©ìàá‹ÂäøG~H::ª¹«‚’šÍŽ(ˆì8u  £ 3æ ½µ¯àÍ[Ÿd‚5º+öcb!µß {Ät›œÞ ˆÂ ²š‚<-@Ö¦ð*É{m(e œêTf›¶¬„íN+Ìá ‚x¡‰Ì_dnk-´ý“ОrTžÞÈa±u€B 2ìŸu:N+øøv"kà‹\üžîÖAºfŒ²ïè0.6âLprŒ½ À}ùo0Æ]{GVÈãìm] UÐ ôÌ{&ÂMo±/‚±ìî¹ó\¨ ƒ±K•úÌ?ï]î&FÚeÙ „^j  é¾$œ¬Ôº§ö$ÞÂ×.ÓAYÕöûÜ.Ç©zÅG$ZBR<Àw]Zè‡7l'0î¹aé¡ý—ûj_þ‡Õ\vg~7K¸»Ã¶óÁ¦‚‡‡=Ä-!t…pó€E;t•ì.7KðÜî:­ÀÓ`k»g'îØµð¯¬`=ü5BüÆ`eDˆŸo{Ú`–4Æ>f®ý+s¯Ð>¯´`ü>ÇïîÒÜÒdزÐDó½n˜} ã;KrÔø@Ý¥ý'£œà'þImü—úÜú; à/ô?n^ÞCñŸÓ¼¿ã?ÿuñiØRøA@ÛD„ÿ h¸·Çe¸ëœü©ºIßÞ 0 R‹åç»w*Dy¨®´ìÙÎõ6î.~ÖÎPöù“ÛÙ‹Ç8Óö%À?øè_=ÕúíìäNþÁ'I@þk÷ô_÷LC1éÒõ žêƒÞã½¢ù°syÏZØï¢ùë.àWû‘{@;ò¶8ÙÛÚAé kªÙyºÂ¢|0Ž·=Ó¿Oïöå$ø¬ØÁ¾|ðQÀIQØãŽ:S÷¶›I-hàÏ«B*•Ú[Ïq2w€ÐŽX@Ôk°î±;6ëÍzÿ° ÏŸÚ§'@?úPßóÞËþÿõwýòûoícáeùð¿_×ãå;ˆÿãæúÿõ?ˆÿƒTmÛ†ªAxvuØ2:û¹Gfû–ƒØ„º|Á§ X~»ä6Ž,ŒþAàžÝóçP€ÿX,ÄÞæá=ÃßŸŽ±çñ¬‡#&G†Q ÷ܱgß…ñ äpôå}a0É?ñ’c%ÿ¨ü‡¬~˜ûä/¦‚üJþóðÌÿâá<ý»þÃý„P—Ê?™ [q{8ö;MvdÉŽ·äµ÷»ÖÄ?ÙuÁF(|pð!A H¨~J†'´ýó«ÞП(ôñ¦0È™-0Í^`©˜n~Oñ ÿ˜÷ŸTîä°AìHcè±€QÃËm‹Ãº ü PÿwÈÿ£’:þägà—üœë?C)Ëÿÿ2ù8Og¿ðߣڧ_ý17ľ{ (C¸XØ¾Þ˜ÝÆÂÑëüWRiŽ´ô€}û3u¿V™„ ÿûADùãA©nh¼ý‰ù‰Cjç&¦mcpþ«¬aoã ½ò5ë§N`)Ï Áaý »Û ð§}ßo)ûÿ¡üßoÔÿëë¿qñpóªÿÆõ;þó?èÿùyþç|=?KÝ÷MqëË`I –r¦û¥,Æ_syx»@{ ˆè$Aô‡ý=J%>¸ÑþvÖèŸÝ.‘#"*{Ã(?!rý?„?kf›kH Àõ›Ö÷?"ÿa‹äo!@Íÿq°þ7çoÿÿŸþ¯_ ÿjöŸ¿â[ù÷¸)¶ÿÿ]ø—ûßÝÚÖÚÇõŸåå>}ˆÿõ·þ÷ß·ÿ5¡Ká_ºûÿ†wõ°ù©cs‡ðîT„þæ…dÂ~Bì]€hÐ_à#Û[wàŸ•I° ù¯’H¿Üÿ'ðóÇö?ø¿ßûÿ`ÿÿÓ‘Ÿ=YpGù¾vBC{h á‘ã½WÁ+òˆ ´8ö^ùm¼7Ñ×Û,T ¥eÔ5e¤$µÔT¡ÕºàïìxtÞÒne V h$+v#Àè XŽQ+-¿q·%Hlé²3B±†ð±b2>%Ým=!TP+€:'O E%ÂZ€ž€@Ñ¡í9ý•qB[û㣄´áhîdae(Dm#¿]¼¡=Aj¢Z[í”~‚'ÌC¤Ínÿ„سÀ2üÈ·à8üÿèêƒAĽF÷?Pr þæ:ç:tøá‹Üw8jDÄןE ìÓ~Áó/#Øßì>ÌÊþSÆ€B"ŽîðÅþa^$È^‚G3Á׉ÿö˜þþ÷ ûÏÚý/Æ÷þ®ÿ‡‹ë€ÿ‡‹›ë7þï?aÿ‚U$†åfàKB•½’©+£©6À‘‘‹“‹‘ÝÆÝÚÚÏú· ùŸüçê` Ûÿlàw)ÈÎÅnkíôoÝÿ|§ù9⿸xyçþ›ö¿µ‡9Xß4g·õûÇž™ÞË^n>ÿ?'/?x ð€ß?Ïoþ—Ó?šXt‡ò‚¡éÅÁÓøçû‹º× Ô¾ÝD‰$·ëqª”'‘¿ßʰ šSp»Ã_'iù–ÖªØlýT'Í\?o½÷WÌ,Ý‚¤päxš3¸x2”ÇÏGùÕ\ù8µ”XÜ*ÌD‹KDçØŠ_BÊ‘—D\Å#ÉU K`£T7Ô$lc³«ßt÷#ÒÔaa‘)Ë 5(å#q?¡2¾¤_Y˜Ø62ý¨ò^¡+âùWÊ£¡=I)@‚XÒïñøx1€Ô±²‡ßˆ ´OŽû­uµ=ÇýûjÉô’GÃ÷èóÑšÅ9ÊוIÓ{;­ƒêäÞ«;Ö©I&c‹ñZª3÷ÛÐàX¡Ð4ºE¹ůnõÚNKНÛw|»ëW—Ä•=Q1 ÃÔsæU꨽„Žöø‡˜i|œ9Z‘ä'!BìçnHÞeeì+ûf¸ù­¿ÿ¼Ò§Ï«½w澈ãû^PQ³K’(¸:xWüÚùo•X†˜”Å6™LU¨úg‰HHd¾ã¿ª±˜ô¶/ô]—ÜZ¦][P'ú bñ ÜzAè$ƒ£½šù”/l¦oymu¾€žZwR‚Í%Cý^À·®ó¾sÃ"FÏžeN£žÿÄ¢*ɪók¨÷ e9JÉÚ¥X•8B‘ÒÄš¥qªÄÅrjqî{ɱ‹cLœÝÐm_¢cwïšGmÖ­¸Õ;-çÞzŠ%>ã(x§ËFkaË©™‹×PÊäzJv~'¿Å5œ"no•üH‚Ì¥WñÉǰ]Z+ Ò«B0sâùÐ2…ZîÐMf¶tkjBû1ŒV³líÜØ_ðFÊ1gõ~+)=—vì§öŒ­Á0â蔌X:Iû$Ð<Ûs}Å›W¹Zt)7ÐÙ£œo©tòûŸ¹Ê6Wó¨ˆ4[×üÕËD:ž².€Z-Rï Óp?O+¼äÑéj2ºâìÍ!Ý‹éqHÑlÑ|%Lýg^#åç“%Ò«y#~تÁgUjFÈ}㉛ðÕŸjL·›óã…äÑŠdŽÌÌ¢üɘ©9ù/”yõ“®ëŸ•¾V„8Š„;¨þ~TwCB¤O“:'³vèò×ÛŽÁÜo6ªÜ´Þ^t@HŒ˜[ý" 8ž#l‘¥áV}Ûdb ýX J£ë%5¡h@mÌG)*<~“²”’[äiLÞ~7·Úæñ»J‚(‹¼ÂRÏhyKxÒÌùeõdB…{«ÿ#äÐŒ^©6ÞÆµ#¥ f•Y\!ï$åÃÛqëãõN¦ë\ù2‘› By%bÒDB[»¬1‘CzL»ÇJÇVÂøÛ“ÛòÞ²SCyªßÏÉã¹ÞD ¸¼ðá#áËI6Ûf!üÅ2ƒ‹fJ_å»ó•2êBMoƤP—ðÈ5c;7¤ÛΧyzºVoÝ%‰­Éh×¹ýJcú¦#ÒÓ› ¬,ßB;Z•ÓüQ v4ÎÂÙ¨ÛRý§#•ìÅ)3Yñèôr•Ëêþjb'©Ê¤ñ#8­éŒ«?ª*X5uá¶°w~¶éDàyéø(0X^«9Ù€ÙDÏ׆›hðtªm†é¥F«»G>ºaLë€CÓ %>('r%óÖÙ´^²éÚ8§„°rþ®ã Æô²õ®8ßäSÙø¯SÆÌ&ÄÑV£•J°÷#·£†jéi(…ØùäF?õžv¹™ó1â„!ðœÎË,³¤´þʇ:Çu3ô>ÄzŸ¤ÆE³—Y)^zü\BØÑ±…WNÄ»Zh3÷¿!th ¨mŸßÂj Ϧé§î\¥‘Ò³Æuô‰Ë%U±mºxÇ}¼”œÏÿ˜Ñ‡»õá=mÁ Ê™1ÎêLˆÇ»×Ûó…Þ‰eÍ9N\ðvËØ\U§àª'xÂG„XëI@®-š¸˜19g“rmà2}`ðU¶¬ªò¯Lƒ-Ë/qknмô%3é°7,=fÅ0èQCë”VíVÃðTs¡µAQÛ…Ït·ÉnÌ¢Ê7»UõcZ`a‹ûªçÙPA$¹,”‰Áf³Ä‰²S\ÍÇe„C:ü@Z]IRV¦½ÖøÏ|súˆ‡î}Ý]U«<¬º–À\Þ#‹sôºW®Á°—×1/$§£(?$¯,¶:/‹†‡°· ëÁb@ºØô¥Ó†d(þ. Ísþ‡¥)£²‹jXŒ=gÇrμA^×ieÍ˹Šñæ9:.§Ò¸ù]à|„ù"¾3ëHC"E›·Qgüø½”¦ÔBŠVѽx Q¶G²\KÏ*4”«H)Z_ØNP§ª½k¿ò¥0{Qöšªíµ@À‹Åøs½#÷ž±£Ÿç;èý*H4W Šè|B³í§YŠ‘SŽ÷mû‘’Ûˆ†úï{€¬ëœà‹åÿ~ý:ÿ‚E߃à›Mî4Í£²T±5Í‘»és†€õÊ;:—ï pvUõ.‰É¦çhió·œÿF¤C™} ¥@ôþçN·rÓ ²É™u¤*õÖçytG4 /Ìñ)tÅoM ²yë'8WbX Ö¶ºÓ…64}(³àí÷½ÛHöò"CumB§Ìƒ« WMd’¬çóWH]~ÿ-- yU‡î]nŽEÇ»×þ ·„… ¢“[qïÓˆ©ºW!†È©ž*Pë^—}^ ànŸd”I—ÆÐþ“?¿^ãUø†ÍÛû¦ßMâ·¹ö/ÿÕýÁðLÿ+ü<<|{ô^¨þÏùÛÿóoÖÿß×Ûû>É`ÊìúJØuý•ЦÑ=×Âä'Uïužjn_û„8~©B"98iNud$hä&qbN«»·P†àÇä»tÚ×?ô­/>›³¸„ªAÝòyé›ó÷l¯/#߯|¿ùÝmaÄÓoÁä{q? –_÷Ãþ09“/ÞZ› »‹c6ÂÜ¢>gzmè|òyÄ¥ó³½crYüþž.I}".äSõc½þ7KAšü]m÷Ÿ»q^ ýiiÄ7[÷þ¢ïÅúûã¨5i®aty,/6±^|Ñ2øî®ßâΗuœì©y:EžãSÏZiŸÇ¤+Ÿ»çé³™òaÕ0»Ï¼~3^rŠ"L·®÷–²Ùû»hè [/>ŒEÌ—_H¶·{H`e޵¤œgQE‰]Ð(Z€øMãûÜFQ¹iV}ÀJ.ßµ¯R‹çg*øg½û–ÎÛvîßúÎöM4èëk‡æagÏQ/ê,JÁì¼-ƒ.±óÔh­Ü˜+ K[9ÞŸÌ]t c|\«çS9F641Í‹I<†øÝûvÜòûñÕ·l ’ˆiÓê ý¡˜Mï…Œ ?Ä.é'NºŸ÷QYÚºf‚æ=GWö•á>JNP×ñœ \„Z+Ç sÆòÁùÆæ…L•’‡íN_°gÓPV¬0œÃž^­%B¸L'–1õަNÒ«ûêÛ‚ž–:D+|z-Ž˜µˆ¬aYC-ÐHщù0]¨ '2¼q'übYD‹õ´Äè á.OÓY÷T/¯P'$Oúb¨®ßý¨‡À°P5(ÏÊ0¦R‡‰»h~»£þ o˜œ[Tda:j…Æ­ÉÇ–Çöš$y¾ Û*è‰{™(`3>ðï|ÌT½w8A›ââ+{Ê¢ “K~Jé:ĪÍj˜qüÕY¡/ž…꨻ooÄšü´KþŠÉÀú% ^9ôçVã*w„æ>ÉíÁ?‹Öó„U#eQÿƒ"íW,Íòáò¯8"ý9«µÎic½ÙXÝ_O#¹ï;ƒ©ç{cù>9‚ɳ–¹“Áx›&‰Ê"âÕ!ÖëÝðÚN¾ù6‡Y¯,Ú!Úâmðrˆ¢ùÃ=ˆFÔ _ÙLºh@×T¶Iç~ÅäqÂ`·ó¨ÿÂAÚFŽpñ9ô'Å;Åz¾sñÞ››åÔYX"x*‘± òcbé zÚë—OóÈÝÏ{1ǬÇxrx %U8+}%³yíx=YÛ³ã"m˜¨…ß}ð,í2ÞktŒéÛä=XþòÚÌÌCÊ »*ôÄ£`‚© Q“©§¦šE#‘©ÙƻѨ$3•ÃnOË_A+{'kU'oÅÑÔîNé·!™úèMÇ%2C¦Äh.Ê¢!’“·$1jž^êpPðÏê„6Ìêúø*,âΙØB³Õ×ÃZ1Í"ÇIG¶ $5W £I8)¿~èºJoõVÜkÀj–ýrôâƒÅWY(í„ ¡ñu_×› ÕÄ9Ï©Zç>Uù¹ÜP¸©ÿýS76åÐÀŠ`V‘`ßë^ NÕ6Õ’ÑJÙ1©L[J¨÷úÈ“óqÊ9;€.8¬°*‘(åä¼5~[(<Ò-î6Šr²úÂ3\GœîÌo«E.õ)„EåÈc-ØbC¤ ßo2 <•¸?üµãÑ–JSŸ¸ 2vM«ZåEÅË(HŸdÌÉ礧oY•žŸ¬R—[?ƒˆƒÁS˾bÇÝìß2­„õ [5¹Wµ Ïïj$Ѐəw¨,' C…•Væ·ZÑ@o†ú–Hû—XÛñ(‚G¹ãÞª00¢0ÛÌ=lAúŸL•&q€%Ï–¯­á »¨½ä¤˜à’ÆaÄ™ÎS°==³’9x¬5‰0à釥ö4u×.ìejÉoOßo Ÿ¢xzâLÒcC¤âHµ„qfÓQÀºÛõ0|•ÜÜ ì0gÝwC )Ñ3 [g©ÝMB C‚¯Ü| ƒ!=qVàM½#7ÒðGvâjÇo" ³¾[.Í)K _î:7‘iK“5ánêqŠó=TIK¡iA»ãÞæÌâÍšƒkký«Ü¥ÒcûF—gñuIt$Ó·f—n»"Ê)U§>/¶Às›«&òY¾ý0 …¢IO,뺾ë1e. N¼wˆ–“Æm‚×®| Œ”äc¡uÚ´©½ØÌø‚ÒqJ9›³òb²EÒ±Ç+#6sé$AäÇž¹ ™LËE¿xÚu¹Î.MõÌ ´çÁψYc=¨GuN3ZM#áù®õ´DœÃðš­âµ¹­¯átŸÇBφ̽?À'Ãgx¨e®Ä/¶ZãñõA J”8¡‰L¡,*yB3˜/è‚Nt¨Ï(¯V‘#$™ºVСqñ¤"BäYЫÂ7Ytü‹ç™\ÇëÍ“r”„*gN ˆaYSÊò÷"hÆFÜœ‘Uö—ÿVŽ0ÓØs••äÃZþq’¯<ÁyxUÝÍ„ ˆJ5ìV·gK®¬'9)^<·%/ÝPØ@ vgp<÷Ü‹br>mgæè C*CÍû=¹zðkrÍÇo' ÛØ…>q9›B£a‡54Ï`¡]âÆ]*À’î¯_X{_†W-VŸÏ¨D£yŠ!w-¡—xÓ#³\Î-q'¤qha¥ÁD¤ýŽt˜$›ËÂëòïôÔªiQù,{Ö˜ˆOi^«“Þsvõغ%4oS§JÝ&ý÷$¥èæ¢3˜CA3]?¼ï„'r |¶|º½$DzÛáeÒ-­“²žøÞê4ëÂÎi¹y#›|NL¢xoÕðbËCnà¬Èpâ€ÑrÑP‹o%ã#×:Ä¥Ÿ ¿í³Å©ÌRA;-R£˜?|‹BÞx|5ÙM‚‰ÈSó\£"“׃Žb.•OIìãSN>ü:AÊ|IéIôÏ4HÏ"˨˜š“J~«è][ß<–½HÒzŒÿŠÂEGÇB7¡P ;ʼžG´e7ˆn,»Õ¢_¨IF"©%h¾/òÀ`ìÛÑ/ì-BuåkïYÉeV•ùðÚ3ÁC₼ˆYÕ9)rÆ¢'$<ƒÆ 7Ðs²gc‰hcpìòŸu!žFŒä8 ô߈}_­ñhbþ×®š_u,">Ö§à¦F¸l §yE%O"•ü×ÇÅ;„W !­—·^òðß ã¿µQ€Ù/ê>~æºðÍ&Z4”jšã>‰ªøoWÞZ›zF U€.V¬X§_z,;+`Lü]P¤ŽµG»/.o°[IŽÆ¼9·!šA/i‚[»kÁŠ€±Ì³šxѾÑ\¡Ha•ì8YY/Çc4c~´òX”u¶a×Çé–Ú$áýwÝîpš\°¨¡›nfÑÅ´æÍ,lŸàˆŸE¾aðœ½Öž¥V±lìFRoÊcl—® Û¢®WS¼8l£*£˜Ç;?œNç N™.,¿í¹1D—@­@™;žû½:tÐÕóš A¦çÉéL”O‚ú–sÓV‹EÄLb•>M®{|çröñ w–pÝyÕÒ<|$ÓW¢'¾‹Þ9ÝÚöe~­ s K]ãµð§ÜáúAOZ›î­4à½åñ Ö̳Ϙ|CTΑÕ9G,±“5<,ÂlñzFW¿Zˆéùjc¥lØð%fxa}ˆ¸Ì;_'EGWñUÞm¡’±á.Ú͹i.a„»qv\îJ®ýg²cr;â’Z+=3b ìñ!Vs:eÏ›,èu«ÒWíc!Ë3ѨŽTÒLæžUâ>•¼~úxjc·Â… v‰*Šº&nWaÿ°[o­ lC”„ÏÔ[4PN™‡Ä€e<"kàâ_×»¤ä’Î÷¸ú¨(ø´Œ«ãH·èfˆpR*CGh;Òœô=Þs÷®´c 1ðt'›#S¼(QðÔ]/q31¿ïÀËÙNt{ɦ€ë 'Iµ#JJÁËÇÖT~7uß½½¼è¡ ž‹åò •ÓªyÌ:]9ñÔr¿ÚD§‘ÚÆk§w ÷Î覫¸EµDg»I¢¼·öviCˆÒGLK‰’¾€AQÞ,Fg׫LƒÌd7ÙýUÉ^¢P8v_=‰«s^÷ž®»ãpA š¾©@ž¸iƒ/Û'lœ$³áw+ Ï1?7òÉäýìø´÷¹³ºv{i ¯G©‰ÿãÊÁÞL .—(&3#¿×¨ô§z¢«iR³N’ ¿¿6Y)RBþ<Ý&¬Am¨{#:5¦G $œßí¬u¾)þT5ªAc~ñW¯F×úaç‹×-ÏH6à3ê_-ºIB­ùû7ºúˆÖ^`æ1RN¢€‹-¬YMl©½Åæ^ Ê9jûø›föJ¾OüÔ<¿t°Iå,®-¯ôâØÙt'SdˆèòM/L QȽñ9ÎØõ‰î¦W/Àëâpz¸¥õùÝA÷ð2ÛšÞ¯TEsž*y]¡2ŸÏª¾t—àž$+#—ä\ÊÃO3Ç¬Ú ´³ªˆQÆ*tÖ¾±e›µóºJB³±¦ÎWŒjÐ'Ã("_Kâœ`Z¥âÈ! ² W ¯2á̾ðOw_»™rúÎg»/“®É‰1‡ùÈém«ŒèyF»’Ü8Ë«ÞéQaI;ñG¹6_+ÃKžÐÒ°óêÔ9L·&±£º¬úI•°T ƒÁ>Æ£Ðï^¹¿iÎçq½,šX&””ô Ätùí “Êóƒ"·¾ÎitYÌ'„…ä>n])Šl«·¼M‚’ŒˆAôFágwB´zh@Mk2–´³°·ÕW@fd‚"ãCô)ÆËˆÃoæF¢Ï¬²×w%Þx&Bãm%_{ºê10cËbvõ© {¥ðÂhÿ#_ÄË~q(äýÌVý±·( äXl-}`‘û9«sx²œ«°è|õ¢|ßýŠ’‰¯—FÞò -ìéyzsîQÃM‰óŒz§‡:F°¹ÖÞ¤ ÒzáÙuÒâ¨7Êtç™zˆB€=ÄÙ#!ʦCIí@ÏÑ-*5RHÊ7×ÂïšÇ†¿¢t<¾™ab'ð©á鳋wЙn -·æm0Fé5àîµ3ó®CE67«—­À0OŒBÀc£Æw5æ™dC·®Öœê7~äG4„$-t÷‘!ƒ¬·\íå$¥Ù³O´¨ø_È]™– w³Ó’‘J+¸HQN” ›=v×V,ânMòì4]^yVøPàî°¼5…ÂT©ëUÙkRK‘LÍè4 !µŽìÁ8ož†ÕÛx·ù&"ž¢i{.P†³qG˜´{¨Â¸.–_ýzkÒ4¥«r7ë»k ¹ý¹„çâÃ_ ½»ë«±EÉÀÇar‰MêqìIôa{Ä"zµR’¾E3›±ü{í ’ˆOd‹hiMÒ/*äàò…j‘eØæ7F®12${·ß}š\ÝnÑéÿ$‹¦yãaË•ûÃŽ"i/G,¿.y 켌 ijÒ dDC¬åaªYˆûü~yÊõ“îFlâG„±eZštµÞãŒ^¹¹˜{Ý€U.x߉¢Ê>lHu¹ÿÃü½¦à5*‚›$Eo®ëèÆyšŠ·Ìù«û—'ïYL’ñÂ/Y™ë`J”™pÖ`&!)lVßö[žsÌŠ @[å)ëa{{þEa#³È^K >Ø[ñ)nO2NdùKÚZDJf±6RÞ”KÏŸu7 œöÍYKfz Êi¬ž¢\|ÁúÖ)Ò­LTˆ4vŠz~SŽÅ2ù°,”éŠî— d“7WO¹s_zš<•{#€? Oh“òÕõoÎÒó$ÄTVveÖ±—è^=wš0À?þ!™*K8ºdÊÙÇYL̵™ Ùò¬õce‡ié@%;Û 2Ö—™MAÜcÊ2©&óq’F^]Aa¢®}·9ó@øÉjÅó6ù¾üÇë\&+äoñü]…2:ºNd=´Ã ³Y뮨%«°š Õ %P½Ë;ëü€fYas´T‚jV2´ˆ o­×QnP%²‡*‚»årw|¿C`SY…sök¬ÑÂvÚñ¼ö-.C²€c-Íœµ7 #)Òh5:ªcM”Ý0IÑ«½™N¬V‡'«ðº{ª]Ž·É6T4?¯±jføêó Om]r<£òx²t”‡¡rò\.ki×X%Ë;ÿÊR6ÕÕÇ8F'uëIš"¬Ÿ `3äv~¸R§xaþ þ9äQ$Iͨê¢Ùvà ŒûÝ›Ã^ȳOÂCBÞFÌ2—Ž×&} +@¨¿†*“È‘lÅ÷†Ö;ÕoVǽ'/[-F©S €…ñ8ãRšr¾ R#égãIPÒ}³,¤”ç ¹õõæ~ƒ"øç¸3uipÖ§åGOô‰Y. ÐÝcÀ/4\3ªUÍ9w ÎHÖĸsqÙMä$á\v{võe¿„ß$ e¢¯ÒPá^¾’¤%žH)maç2p+¯ˆÙQ4ÊE¬«êBÑ YÔ…ë/kñI¼Ââô6Ë‘jTð=râÃ’=\–wÊ"Òï{[ÐN‡Y"ÊëY*;êÜé¾p«õELøµ‰fö,´|ió~9'þª€·'=ÛÇûŒªÌ ÉÉ ºzöwN“bPØÕÜL\y£ÊÔÍ{’Æ4Ø3úÒBy_îûU'Fƺ䫯o¢ža«ôˆ ºÄ½6õ&¾æa§×b¹eõCÆúþh‹x)wÊSJª¼æ”©'5ÆP¢”e—?‹GæI‹ˆRÄXv&†ud5õs¶Ñ |>%ÊC1:ûÍÆ¾zê‰[r©³âµ*ÍÍDSaa™âÀ©g±©¦xŸ›¢«êƵ>SM%ÓnÜ5e*fãO7ÀJt Áøz&I‚—ÈŽƒ)FRÕ‹âìÒW¹!®J /Ӈ˱nàlhôpWJD_oÐgÔeÓW¼Òè**×~ÓaµåJ7yK 2‰û£b½Áâù3€<¾všðjç$‚.Ü;@‰ø7¹”ÙbHa¶^8DvuôãÎùŇhIàž&ˆÈHN¤.ë>ÏÇÁ2=ó )pM‚2*MÐÏA¯iùÖSßÖ,ïDÁ%jÿAFí±É!Ð >Æ>ÍÄì¥&RÞétàÛ`y®O8ºY„]–ª’Íó£c´/u©¯­z7ßVMÐìÄ“Y»Žüuj”/q†•œæ‰ùú›ÎÂüü•ÛfmrìzÇý®ô–V¿WC(ë¼»ªæì*‰%`G!^hˆšÕxKƒßý>ZØ9V÷z“"Ï×çXLÍÜ»âë)­Òñ"ßÈ^üx^Äœ·"&æ£1qC½c¤ê3¯â¬ÀH.² øu,~›Á¨³èiÄAÌS3“+Ìor×[°û£ Œc¤¬–J˜jØœ9ê H ¹Õ s¿nh–òr0ž}è6·œÈݽt¬5:m+u s²2Ð2ÚkÂJ-kv-úv)¿z8Ã%ÏîëÚŽ­f$.fN2…’Á@k‚¢ÓwÞÒ!™)ÓÜàEñØíÞ©ûóDÞBEù¦A’ÑÁb‹Ø ÄuÁvd7)Ç~B%¶›E/ÍlҟǸ®Œnußɽ{Žr®eåDï /aSà'©Ê/_Þb—:Ä”¦:è‘%¤©¼Ð-Œ1¡°ØÒ‘}7»Û÷K·•‰å”¬Kèôö-0î4ÅM¸{/1yÊu ‰é¼'{IÆ0\~Öõ8¨+Q=é<ïm+MË8ÅIi]/—nç%¥y©OïùJ0|LæSkB–ò¹ Çë9Öúùß HPiö}«È“ zþ¥H9%þUõ+/‘6¤JÚ\ÅÛ"ÙCO­ŵ©Æ Ì²¹~Ĉ$^&žŒÄ8ÑùãáÉkÏ–/GmÔä®{£¡:¦k¦ŽZ&xØÌhbu·Ø’"ªx]ç¼æ2(f¯EÚÓîç`—¿µ`þu% 'ëø[þÕ¬»Ä¾”zŒÒ ÂN[˜¦y­´éV†wë_è &XÏ÷`Êâ~tÆåíÛ[±hø~ÔDv¯=3íñMŠø¿ÙD œŒ5w˜°HqnŸpȤ¯¸ÞFs¿úºe²ãÜ¥d±¨ÕšL×O¬9-¥l¹£@lqÔYQ76žPFI7lJo“b9y™Å—ïuÛQÛŸÖÅP©xlÅlA›öˆå¤x®‚j˜¾HÐ9ëÇÕYõØÎKUé¸:y™wµâú/a|4H¾TzÆáüB¿FAQw„Sqa µ­Z(¼qÈŒ¤ÀÛlofñžÒfŸÿb¯Zš2UóUñþ´%γꨀ©;}¼ÎÄNœOCß÷[ob"\–¡LÈ¥{¢‹­hwÊk#ŒåKî Êc޳ hŒÃ«'æ ¯ÅØè‹œ»¬`FXÙkÀ{²CÅ@‘ñ3-‚FC¨“ÆÈoFÕEé<Í]ÚbþH©Z§Nx?<¡šÁyQK`ªû†¶à9‡^š‘¾ˆ†ÒéêøÅ0¯ÚŸõ5+§…ªŠú0‰ÏËÍû\ :Ö²ræñevP"’Pºû¬»´TÒFFïd‹;Ò¥½pÌB»=Ðël•pM?U²wví`Rv`ȺTŸÞbÞ¯0v/`QxQú°Nm™íõ,’¤´î2z¡Îú >'¾Ëôa×°OðêR’ŽëÓÎó,*4ž,™`gkaŠUþ²ðíÛYùØ6UŒ«–Jq¹é¯:oT[ù‘62³†¿H•áßä…å/2á³Y·ÂùxÈFÜ´kT‰'•nÝÕk/½¼=†1°€RQ¤ÑîO-–~rÈx{çYZž¸ÜýGä÷ü2mP¯iÆOÜSኸðZ)!Ðz*’N1r*|­| X³yáÀk‚­ÓîEq#h\¨Îçûyu:Š›J¼#ì £â®múä´#&±±Yt½¾¨c5oÕ©/µp*“2ÇË_^¯à+E ïJŠBq7 YlØæ<ÛéEÂÄ Óä7ã-2×0„Œ9ÛCŠTrðì•üø$'î¶GiÆÓ‡:$­²³UQŠØã|q¾ˆl9Lwå->*]~Ùs %L/3)"ÍÑÄ[öÖX¤¹OÕë˜_GÛT0&´À1ú®‰á/U>…y;¬+´Q -®Dì™?GãÁ[DVÙðNçâЫÆHâ‹æMò­Šæ(Ü>Ž«'vÊå#v3ªœçÁK‹že¹¤7 Ã/÷#ílBQyˆÖM+tµÂÐcCþxQ‚j$£ó±ã›†škÜUaò-È^^¡Öô3Y¨H¶$ý–-ƒ‚™ÍG$XºšVѨúb]£î¬ým㦠Ý>»˜å§žë#XÜlçuÒ½ñd¹—¥-¿_Ã)³í!ìî§1rù ·AÒ8ÕâOEöViåt:†ò•Ê“ËÕòkªe‹roè躞´œYŽ«Œ#•L™v“ò{K¤F)ø™“ò&²pîàre”±¬]ßÕ÷“ô¹"MÏò$â\4¶ œ½¹õŽåÕYåký¼z^fCìç²Ü°[ Üùj4?ñŠh±ÉêÜ®ä5\å²Tq£“jË ¹–ªºt²h4«™í¶àøu`Ò7cê‹™™»ØÂîOõ=_ —\°¶1kÍÓj—s&”f¦Í0 ¦øØù§Œ–©8htÚÇÍáÊJ¦:¶;x«w ’©à´Û¹ßVŽÂf~b„ûÌ­±wQè¦*òù‹Iv#Hu7ÃüGMÏŽ0=¼Š9=+XüVhYqÍhP0‰Î¬Fô¡í³"=CGì”]~%n׫ìËùn+û—ï 1ãCß •µ Ì&+n$_>ÿ®(ŶþÂLkÑä½ÓÏïnêú)ÒÇ€–yéÔ - pÛªŒthÔõ—˜_Ç' êëá·*r˜zIy,Ÿ¡™µsÁä3¢W’æÅÄÇs{\\±zùŽ•_2†… f«¥|0û”ý&á[™ÞXU¶ÍµlgÓ¢î»NZe(ß%©ß«ð ªa7ê»ó°´èæ‚ÀgýÄ©ñÚÅ7òmòòèQ¸p*[Åš&#­Ã%1œi#Š<å³ú´¢#Ç¥EôzçðƒVüªš™˜ªt°Ï7úJ ë{¥¶WJëê-‚)É(Ï«z,Éô"rkF,Er¾dÑRíD1Eô°šop{‰É¨Ë\¦¥tpD¨œy`.ÅñBëfö7É Ì Aœ®—>äÜ'blê É|ßËR-ñå¼¼ÙcZKeí(v•Þ2/Ü©¤im›‹¥ïu¬ KœÏvÝ‘,š@I ¿Ä"2_:nr91µ%y©¾§z@µ‹ˆRµo\òlo–_žƒÅ™òiÛ‹÷\Yð‘ú˜4=Ž=CŸe <®doz$L^ÒuýÜ«`Ü,tMo„ã-¬€3Å%'@”|ƒ¢Y …ÏÝœ{ kÒs_‚æsò |]³ðî§‘O>%h¹Õ¾ÑNp÷O2±JKw‘5uŒ+>ÞVÖH’‹a…gxý*uuÄÇaG¥W'O+¾¨ w»¸p”R!æ¡{6tm5¼Üø‚Ëmÿ¾/ÕŶM6óÊþBäbÇ”ÅézÍÉ·).””BîÅöÏ3ŸÚ4cj73 ¡Õä§„†—=pò ÑW%±õªV uäIÓ¹W’AYÃéÖ=HŠÿ¡a¢³¼ýÍKý3Žª.•S¡ïÖ5n-TÒtÎ0ÊœU1ã¼)­B29WåÄòL`Œ.^˜‘³jÝò½"'s¯IsàU¥p å¬G­]§qµlk8íÓüIa!ª^ù'é¤çˆ9º¯v ç¢3º,4ÞNYÃ$y¤xÅïÔà½ÀIiœ­ÄÇÜ5Fè?…¼%âR¸ª·ñ §˜²*{†~y Е¾ãÙ§’îQ£ØmHÓ$Ñ[ÛöþC>sEÜ·÷.—ÓzšâXÓæM:…UÑò™J´dÕc#üFQîÝl±Ø¤÷kÓ=IZÐÑY£`í]Öõqâ4Ûà”RQýb…0ï÷(o¹t´Mz{ÒkºmÐ 8Æø'<Èãé¿'=Q$OŽö¹‰s“ò Ö¥’shÙâÞ;äwÏshÔ›G•~˜_xÂeN„‰?‚Ó,xBÿ[ªow.â¼ â«;Êôïʘ0OL誱æ?éu5?®³Ny#ÇÚ‰ïÍÙöLÕW%–·^ `öÄJœÅ|{v$ÿ"[n»Î·§³<³T.€†¡ü—Z—sßwÄ XÏP¯Æ×\û¤ÈÝ–14ÄÌü¤–,ƒù‰G”³iÈÓy†ÉðE•„±Å¡¬äUÙ†|`yQ|覠Ä-Kÿwë/VtXÖ­Éz/^;¨›cûñïّϵÈÒ”j/9ø^.”§óPÍôu%h*°%W›î¢Í"òÕS!ÕÉCk¶—LiìT óôŒ-QoÄâqË\b$ Œk/Tàà]ªU¡§jÚˆá_!>m‰ÕÞX–Þv¬·ü½¿Á»Yî:)Æì~ó¢›],oRxÃ5V}ìzÔL•ŠòÔ½ÐêZÇsV\ïɰÙfÆ ]bñÀÿÜ]ªË´~1«xAÃó*u›–ê )†YMÀ}2±È·Ô¯ª‚,§ºÔu”Î|»þÁjÆ js¥âêÍó“Óa/ŹÉ2_¤`~³J/6ÍN>r+¸#ànÒ¹ ÂWR!5H˜¨ >÷ƒ# ¦é¦æQ„Rä¾Ï>±xñý(µ!Û ÐÔ&¾˜‘ºj¯D 5hÒ¤Üìŵ O$’ÞâÀˆÓsH¨‚(úi:Èxì©y„é£)zâMö~ËÉ…#ȉíº×š;zEen$‡uŽõ]± ÷Ñ<ñõNÒÓáË€ù» †rªÒuKéS·Ô2D:ñ/!„Ä.ñ£Mcƨ½Æ¦LÀD-FØÊFj$dÛú‚eú’ËiÀ!oâxl ^§ýM|§Eô̼{e.ô%ä´êø{1”q¢E—(WhQÇïÉã½u ÍšD|ÚèýuìmC̓Љ:æ…¶%qa_/O]›uFÀ¹ç$ƒC¶ùˆSù™ó†%Àæzõ)n›ýl®` –1L5¹Q¬uV ÄŽ¡H{(}­–)?×e¯£Áê]ƒtßo¸»‡—D·À,(±yMŠÙèÙ•%-YDg²RP2~ágr[†¾—õDÏ¥æIOM=/ƒ¶¦‡v5þÎÇ sÄQ¥×©V®®Çúp2Iò²hŠÜ:BPxÛ²¹órÉ‘Vr¢M /-ĪncÓù® ¢w{/”4»xÛ˵øÑs5c¦µï–çU+à#²T³#{š‰¤ýÖ„sqǹ©“’‡Î;{QÞfŽ @ØàóvM:‘ÉŸ(’°Åá)ÊøL²K¶ÜhümQÿ‡'¶¡Ÿ/(H,f½;žT\¸lŽJ=eûͯíñUË͸··­¿RûLš,e®x‹Î #ß: 5ÒJíi¢"å’i¦Úgª Q´KuÊkä‘WcÖÎAºÆŒâ,í«­Šq6Ñó2&í…=\¨ÕJœˆÂ“ßTf–¦œFÍÕ M{{)¥¢íÖL¿º à³;9犊o¼¢'R°VE‰ÛÖ¢‰¹(ã–×R‹zK’ó…‹ö©•Y©²ÞöB ¥nåç´õú6zGƉ]t,–x…2³>4|4i¥ù5Ã݃7¡Š [åÚÊl–ªŽ¥\eí!7Rø´«³zÒL¬¬¢qÞ6Ô-#´Ód8K–NÆå3æžQÈ_†°u㡾f>Cô¸–.yxíko‹2ó4Ùñ7 ÄNÝ×ÞöÜ~™"¤+Ö)Xùe@ç“~•ÞGÕʉKgÌQ”}Ð/ä\Ë1à³ð¬ksZ¼9×k© 4¶èç3Šfgé^z‡ËÓCéZå#vË•@iÿ€m&lÑL‘cuÓÙ¶ª¿ÿÛ¸Á±hÕœ–¬Ú¼Š¸›žx‚SÝïN22i‡^¹$æ™È3Õü"I—Œ‚h…ðTAÕä\ª¬çsá„FrE÷³ìú:t¦ •žâfù’Æ¢J~ež­u°é»4½AißЙ¶‚‘œÿˆ ™[E„i~ŠÞVTðJI>‹¿îœÌtó…ãi•…šLy¹+œòÓs©É×ÉùÎyâSn6=D ‹Ÿ±hì$aÎU¯™&Íÿ€Òn¦,{–…¿Ý*x>¥€8@ù1Hnä:feÍj½y‰PΩ½"ÉÃëF,'Þœ i­·õ')êqÕDôȶ³»_ÃKR0ˆÙ!é¡.•ìçÚ˱WeÌŸµ8Wn ûã~’Gç=ÞvçŠÃ½wìÞýª…¬ã߯¼¬U•‹ô&HÑI}S5̓U“qLò^‹ƒ7g“ç³­°„$ªt?ì¬â~‰Óî[Bãz9­0£+»hñ©ä=ÑMw©ð}xîäùjk­Æ5p¦˜—¤ˆÜ¸>DÕ”á‰ÑÇÓĬiJÄŒOé®\^o²Wêe2ß°°jµô2“Z̼škðÍ ã¸Ð Z?äøZú.ô‰¶\—þOXÄ é?ÙŒ˜üÈUe—§ýŽ#÷q™»5FÓñçœ!x¨5AÀ<3¢c²Ê/*0&ç«YÖe\ëKø9=®×%Mù$3/|¸£:îA½ãŠM!6nWLÓ(ì„‘ƒ9ÕW¹¡Í¨ãÉæ_žÞyŸ Íêoã«'ÁØ~I;E€›½ZWiñ³¹ûFŽæŒS¬P¿øÝÄga¥_uléi„–Ý•| 7ú=;=< ðÿ°"wÅߥKþÍ;Å<|bùÂÐi".éòÈÌL$ Ù‰œÙËYWh«•VÌjè½-JØ®…R?/µV{Y¦¡ÅÔÿȨ½EšrŠù"k^³ô÷±ú Û`”ªíxŒË· ŸÇSÛêJ„­èÁB.ÎìÌÖ¡@–KuÒI8*4„äPhEPu¼uÎãééÀig r`W ›:Mðè´’*Íuà·¯CU0Þ’¹—õê Ä#áÁ¥h/y7hÂ8u¿µ¹_ã+av@`Á×Gág[KS<Öx}¹ø/ÒuŸ»üráj6ÃóÕ cE§@£Â—ÈmÙãXçÜ>´³£¨ª¦ê7Ärbª²³6”úV³ªÜŠ 9áAê¬Ñ©A¥ðÑM˜ª…âÁ­©‚ '„²–OªæŽZÆ­¤P·lÁœ’¼«&ç*ËõîmY‘›k.ÚQ·óš tar,m“:e×ò>ÿÊlvâ\øõþûqüR=„iwQnYêë÷°½U–?…Ë,*Zí(ˆnêIÍ´“W¹;#âg¸þx3ÍÂ&æ}~ï¤ey“ãzMæx^˪ ×rM‹CÛ»ÏIEÖ²r;4fã¼.”;…Ž}_ž/XàëD¤™ÜÐó*•Y²B›#Vv¼'|ûRöUІÙոϡÏÈbªCXÚKŸ£c­\Î!&~nOlˆŸÔ âŸî×Pë~—žxh5ædÔ*iíc[:¿<Ù<ôÈÁ‡ÿlÈU-G»rJ ûóÚ~H'nܦ¶U“P°P#-o®Rö}•ï{ÝRÎdVÏçdÁ©»šéwI]"¦« Nqu¤6øÍ û?.ö|’°|ŠùdbÑqEw¯©XÑÈ›A®5/¬OãôÜnaœ£æ!œýª-{%*]PV…^Q7=uãì'ŒNÓ¸8NÙËåi'2òû ŒîœÀèJÒʺ–ÀwíDùâÈ—xO ÆÎÆIwºk¦Jïìñ]?–eã¬ö›Õ\PÏ:!¨DÖ‹D„n^ðªR“—¥Š •,µ0÷fÖ‰ïTwhû«'5”×­¤˜(S‡^`ñdŽÖÚÒÏf·:›zvH©® ìê´¿TgÜöìµḬ̂‰ ‡ötÎ눛½ê8s‚. *ßÈåe¹ÒHÿº(«ìÐ}dažúA‚*½ê7«ˆ²üŽÕ9$ź< FQs3ûÇßSŸ¢Ö*>†ð`y}u~n£a1âXyB…`ÖL1;ù{1Š ¹Xí ŠX-¨ûö'»ª@ô‡ê¬gx'ô%Þs[»Øª”¹{1Ùô2z<’®~sí“–È\èìÉi\o§¶¢§È0Ä6A×A|ÿz¬fºóì÷O¢ÆÚ›ˆgY›Òfª…½5rHÄØ!µP«ÈŒ‰cúÑ#;$a÷,Ðw$ÜР|u–y„4ƒÜú…£5 Œ‰ðqÎ<ž—ÄòÙ ôÁåçRýWEˆÝ7רùJÀΙ4ìÑÓsšAôºŸy³ïùß}±ö¼$·qH¢¸¢ hK§]¾lžßZéÑå‹ðêcÜÚ@ßx¢¬™ŒAN¡¾xVѲX»TíùÇKkUç?Mom˜Ú³ßIïx4†’ýd-C G¥ä«€”§ ãRÛ«]=æoÒ|·ÒÍd.¼W5§òÄ\ '’@a}”mtK™ýBa.aY‡›§®c ©ÔéP‰pŒâëVÎB'(È6¸õâykpóØÄâ¼"M%/ÄöÉTsÓ]\$—D/RC/ Ôë3¡<ÇÁbYJR—,×~V²“<1´ÿ!F²é1m«Óôì¸ß„ã‹]Õý¦;éb”’D³†m®¿²éWñD~!óÿ@é¿¥½×•¹Þß8Mo£0oM®àˆ0aö[ew´¸dn+?‰ JÌ9rSuŽTÊS9‘,#À‘|}þúù›ú¿<Äø"j)»åÉ嶆‡Ž­­•§â¼}Æ„å‰ÅW÷ë\2ºN1²ÝãÇ´åȽ‘–,æ°Í÷îÓe<¡˜No²¤ço<´9±Jc‰IRæãEµbCµj¬ç¨ž5Ì$º]~³•·ˆ÷‚Ï!Q#³pkyƒv§>Ž6‘¶ ÉWj ¸¹-.–æÛá¯sqz ‘ª¥Fú‰±Q‹\­£ÐÍ>'…J»k¸xæÏàô/“ 5Q ª¨|T·e‘@´œFyú9«Ò­úÎvstè2ÎSLÆ ´K›lÓ°q‰“[+ò  ö´µ•[*K—Át9QºEäbg´ÞÍßÈE¡×=v;z]ãîWŠV…ñ’i,u-ÇßÜgç“Ï@h˜nI'OmnÉvßñîho;ULÄûÔð†´æßýÁ3>¬žäĶºj^U`ÃQ¯vè¨WÓ(#Wj=}8ë¶wàý ¨¬çso•‘†›ìx*ã/Ê+H?æÑ§(q Kë:ù®t)5ä3NÉWŠ-TÈ-!œ•XìuZÛ¤yòéÊ’0,¢,ØRJT•ý3÷6œæé¢9V9²J´-]Ìέ´³ÿR)8ªëhßík¥B9âá…/´Éµn´ Av›~ÞRO›ô¶u#Ê´°¹ šl(aÀ²Ec òåæ3Òm3ç÷Ú´%£c/È&Œ½¿ê‚:¥BîvL…öRñNYFnÇ:ùE¡W£b9uœ9%÷‡(—ÊØ,S}ý4œnIÇDŸéƒZR"¡™˜â%7<óèsXÿz8êªt½à)G›ð=ÉÅÖÊÎ’\Œ-žpNuxä/ǃc—£Ñ9îlÂJ iXyX•Ã\ùÇ"ÚpD›ÆXÕ “,…S2Š—[þXôz;qÿVmàÑ™è-Ã󸂗'gÀˆ'ÙÝ€½Á¨4UÜÀøO²Åü‚3ã„Ö(ì Ïáⲋ Oó£iÍ<\Çiˆvá‚k¨Pʈùˆ‘°‚÷Û¿SäI—"O.ÄßG2q°ÒB• %§ãAž_¥útä#¿÷нô"¹¼÷˵àúÞ6>Oá–ï;Ê»šóìPéNI â(wŽnOrQ“¨Ž)fU7ǧ“er¼Š$+qÛŽÎñ±ÓµÖT’ iª…f½p°@i¯nJÐÖU‰Y©†{ w;Í“4œoI–jÚu=HÇrÄrwœâ;Çí ×WÒäã™ñ"¡[¯'¥£ÑŠê…æÛb$U»Ö=»àýΖ$j–¢KÖ˜ ŽÑ —ƒ{?ã[@êaµ` [Œ‡NãP ÀMŽuì^"æŠ3“´rÊÔJÝ$,æÁSÚ4h'N ¡Fì2BOåÑòÑVÞ“7˜­µ¿ŸarÒ-ë¤5,‡N°l©¥x;ߎJ3¬^oˆÓ,ÈVâ ó¹£-¢Ü¨`8­×àÄr]/‡Å ‡]uI?Ké#R23 Ë–¡šD»1å\ÝëNS„R¥¨(©7Ò­f§uT¯kÀ‰³Ö "„}åå=î9¡–^•«ŒkåüéQRî&f[ÌzܤArÚàcÜ`ñ”ՖêkHí2Tr1ÃëGù¶4IºƒÀäèñÀ.Dç$òŸX@;î+Œ©Ë@Ý-ÞgVü>ŸiŽ*"–‹Ñ99Ãb£“²ÒXÕ/'7qu%.¹Î±#/oƒüsG÷Õ¤Õjß2 çäÿ .w  mX>¦áêt:‹¶ð¦yËgˆC#ßKîåU5Ϸ‰ÅÎG”ñ\] 夞…7±8DQˆì/Y]6f©v¿ƒýLu ÚÇûÛÈÀ}ôqË*˜ö/-ƒJÓM2‹`&ÕØ‘š¶ ”iCÀ$rrÓ‚ —W«g¸iË`RKOñ•„…2úBsšVçI[ë³epN2´ÕdMë:ÞR e<#µc–N>o‰Cá¦-ŸÖNÉ8U)È]‘ÂQ-ïBæ«ÙÄà–3Š¿©Fðë"ð•ýà¿fl‹~p’ Vì3?%³¿½åõÌG=1ò-ǔڶ]¼ý7Ñt™‘JÞ:^n€—Іr^:2”QiI†â4¬Æ®¥D‡*š¢œ=Ô’RhG]—U¶»Ñýѵ —­eQú%ˆÇÄÊDyoU’ãÉ6KäûÚoé)èDß„Oèbõí2®ö‘’¶/Ḡ•‘¦ÚIx;ƦîåèÌç-åú ÅÞ>¦96›qZ‰I/IîŒS´C—AÕ]¶%}ìx–EyrììkµoÃ.Ê•Ø{wñr#éjÒ¢xVÍøêÖm$ÞNë®ÇÌ}¼…“F{ýzÞžòÃïlá„ìô°ýl\×^Üî>_ú kSYsps OîPŽòŽÜË6ßKÙãÜÔ¥`k@5Å=֌Ú±-~Å'ÛüÉžùä9ç‚õË ˜ ƒÜe:¿ûçþ÷ôÍë«‹ó'ï®Î_¿hÍ'—oÀZ¶ûýßµùßúÏãöàw^»×?êõè×é ŽÚ¿óÚ¿Å`²Œ @¹Ÿ_ó…~µ¯Oî¿É?»H,´4ñµïªþÕj:Õ9¹‘ö}?l›…BÅc5Tšå»I„øßY~`¿¸O‘šuª5N™² 1_ŽæQá½G¹V‹²»‹Â9²”ˆ4R4‰Š±&“ØŠ<çR¹‹$  R<`ÐIº /ÈoÙÆš+!ÉÓ{^¶i:zôý u5 òŠÌ[SjžXŸ4O\sïm–"—P«é'83â<á£/îæ±O ÀÖ4Ê®`½a+ø¤ïû5xÕÇXU²ŠTšMãÑZÐXc BÖR<f²VÓµ*¾pî(• 'ý‡ƒ&pJÇ*佸¨ÖH‚"Oïð"a@uxDüÒAà&v[ÄUÅÐ<õ-Dff¦á¤eß.ZýPùTzcjr=yÎØ^žý3[ëY«©?éó!HY*žt¾B˜g§Ï^}ØãŸÀ–h$ønAWû)Õ)µV;¥Ì1ú½à¶?ýþôõ‹³—o^|ØÓ¿â"|óK¶^0÷MË£yÂõÓô?0UÓJT8ª­¦§½CÏ#ZFh%31=e´‹éèPý À}šÎ‘j1¸¹½¬ˆ3nAtÍ× çÀ(èS>´‰ç^³9Ó¬šg[ôÖ£¿â¯á×GÛ{ò°,¤ý§ðS€;ˆ'è_àE; ÔÒtXcÊ™¡I á†YmÊ5EÝP˃B—nÆ ÝÏlr‚´ Õj  8Š…;Þ.ó™éºXbž 6û"F}Ųÿ[¼¼’°8•”t';-’³Î–ï&¨å=1ç8žËºý:ÜÜ¢‡½ô·Æ;€ÝP°j1<™ ´Ì—Ï{…÷r³1ê>yïM‚•¾;!jÌkP¯ú]ȱU%(²üñ‹òæ~Å!sã{"Dꀉ”µ7!zº](5½¸öÎÃÛà5o¬P—SÝ;ïIM­&Ïéjo½Ÿ\ÞjVÆÂ^²œx8sÅjqéãªà¾’…ö&Eõ€¢Vd"qÊûÚér‚¶"/)d^{јÓR­/0퀢h%Nçh§“¤ ìÈ}‘è¯qÈ‹J%Þ3Ø\÷m6Èu ž23—x„6îU³Q(«´Ð¬¡ã£86òÓÍ Úž„®âˆ¾$¡„^e€¼óæÓó–w†¸³ %‚àÂ«Ó Noƒqê}„ ¸*+é7Í’©•Ê5FAehzª«ñ$ĨˆJ@c˜)"íx¥ÙL] ;B‚ôɶ:“J¯@þX‹ ˜¸ˆ‘¸V1òdÀÅ#c¨©7O±ú7zYа¨8ÊJaMÅä-ïû@Ê+aÁÛß ´WË-îE­ö–0â-i,Ž{4¦N°¸q^ c‹Å‘Â퉕³wÔÖ—‘Žá.Vø+üûɘÈÿÐØ[—ÿ{οäÿßâß„ö¿Åäýz¢OÃÞ4œ½ºAšMn«ï×~÷¯ÿsþ½çßËÿðýïtíµûß=ìýëþÿÿ³—6M.Ìþ s“ DnˆÿÞ¿)YÒk˜šûæß´ä×ZMRBÔ»„(dŠ$2ͦõZ E•A«'¦¨cÃ’Š`’Ö<ÊúYg±3««¿Qô40õ†Wÿÿþ€éÚõ²L#[CN—A6©—þjfÑú3]=]Ù¯éeÑO€ÏæAvÛŒ¹1œŒƒleÈÖfi§;Õ³9ÔƒÀ¨ËÛ¥µãÛ&Ž`žøüb¯ÕÖÏÙgäc•ßE—8\5qøòã~¬? l{‚T ¼IÔèeL³hêÿ´ÿÔø¿…vã þïtúí þo0ø—ýç7ù‡yhàZ³ª~èµàwÄ&ù~ñX—ïíÁ½>iuöé‘'©ÉEu,ÏHùfò׌Ódïýá;¯‹(A½i¹äbæ†ï–Û06Q:Ó„ÒæÕðä“zR”‹'r¤'JJi  ø|`->GÉM*cÉSQ’»Î^k6ªÞlª¾Î—7(²âK] k0„}¯´EBqõ Þ† †ÈÀ¼5½ò)ïë5>Eé\÷Ȇ¯ÆEq>¤¤.ù5æ ¿ 3™=l¤^“qx &—[:\\wþëÎKk¦DùÕ¹S‰#XGj²r:½½† ó³q`™½ŽÙ=~Ô\ÄË)æí… œ˜ýƒø-¿&ÁB~KaÒ—}éÉ )|)XáÀzúÜK;%ÇîáEѯÆ)ÆÒÁ‹ ðõ†Cê ÅGà{æiv‹ºæËzX]FfZîíõÍ€fø—Ÿš¥¢(­VÅø Þ\õì&È‚I°’Ç'k›x#›ã`<Û€UcôH=¸Í‚ù$½O¤ã@=OÇ, wî`§`"³fÁ—È Å Ñ++/ž9ËÜÌ“ob¶¤dÍå]—e¦{)¯T„ÒÕØáüO¢››f<Î鬨Ù'F•Œe¼ŽôÕ‹Úk½›š‹¯6!­nÃûw¯Wz¯´+ÂúnË[7´@Cd>ì{LÒŒ—V€¥µP¸ÍcÇCiÚN^ˆ¥'Lg ZÉ®Yî8’“;°^ŒI)ý‘hNùH&ar·~¾“´€Aƒ—\m§³•¾8}*óYǽmü{¬FgQeLe!xÛK $à}>2÷Y–‚¨B§ôPc“ <­ÄÉ Rk1J²CЮú’¡Éª+Í®+ÏÃТ~Ș>qTïâ@”AÌÜyYŸCµ}½–…²Qó&ç|¦‚kä˜}‡>mØj£Ï‘5…Õõ$\”‘›}(ˆ¦Ø,½ñL¤+‡Ò]‹  -ǺEK]»á ÔcJuJ†³Ýî Ö_“vj„Û2èvTÅY ð«§Ö…åë–Ÿ/f]ºuäÐ5HÍphø†uUŠ4Õ^¯wmjî²oc 3Òw6“D—iªú›®ZÛ ëž•8ª;Y}É4€ChÈDܯ4]>N ùS¹R ¶‘c$Åi‰1²v1ÆN³ ‹ô>Ìtb,ˆ -Zî²)<ßLkµÊ'I@4ÓŒå¦Ðʼa×f¡»†ó°¸gÞ£Á·]z™õ käL>x¤zœ{[%£ô¾Ä—’§É^Ç:qöeÆÛy¬ëû[º´D‚dãÔJ9ƒ÷E¯ »žÍQÓ3@Y(«¹ÑÆÙ,ÄßKŸ9yp¯5ÚCãã~ù-fT½Uþh鋆`Îh»»Ò‡xõqu£Ý¢È)‹Ê«›DÄ‘y‡x«ƒ¹Bå®OÁ tkýMÒa-²tŠRÔ(Èäré³L"¼vÍI”/â`u}MŠÙ†8×Ñà—bëÒ<$´½ÁIZŒ&£JkYÖ€ì˜ûmèPÇ,¤ÂV%o–ˆWf ¿ ã %±„-‹[_ë"rÑŠX*ÄlTííËÓ«ço.^]Öø4ÔjÏÎÞž½~vöúéù>ÔR~mM<®Ù’¾–kÂrÿ¾¶Î{³Ja ®®Vâ0kk|`Mq=µ2GÃZdÄЋšEjZá QsM#dëå Ùȳõ ¨ôÑØŒËV«=y÷úÙ˳gÞç¤óòˆc<ü¿[5ý7îïl|Èþß?<\×ÿv»ÿÒÿþÿXHÒ%£Pÿë4¹Æ%)†^‘-Æ7žO†Ê' dobÖ=F íý¯ì§ÿCN¶­o¯ñç¶²Ñÿóó~©=ŽF{­o÷¥ðÝOÞßæóÑ«š¿ï|ø™Þ‡.¼Ÿõëuê€ÿ¹æ¨Uh¯ïãëuåg1¯ÉdAX`ô݃L{¶¾=Øÿ#4ñ+ÿÙZÍcŽ{Ž–‘I”¡ŸåÞü}ûþ|éÎýyþôìõåÙ?Òþßmu×íÿ½Þà_÷ÿ·‰ÿY¬2rpßï{ö†ÅƒÞ«˜Ò0öžP9 £¯ã$ ðÛ¸Üò{9eÉ‹rÝÞF+d0‡|ÃÃ8qŠ šÙÐÆÍ‰YŽ0ØHrÕŠ8áPN&Oo $ÇÀƒœ¼½bÖ]Êöœ4’œÈÇO5iuà‚aT Ñò뮩æ8šGòª¨…ë’KÚ“ÁÙÀxy.ìSØ`:Ÿ5jÀJJ2­+”&øÌãC÷C,B–.0‡ƒ„­*è옘Ö0 úXÒÑwïgé¼<ôÎÀˆa`É'⡘§ôEŠQØYål§ 'x@grLKÞ”4Þv”–Ç¡øFÂè ³«Ò”ÏÐïcÖ$• %l¬édTÃ)Rd;;:W'æêû3ïòÍó«O/μóKïíÅ›ΟGöèôþ~Ô ÖìÍ»+z\œ¾¾ú«÷æ¹wúú¯Þœ¿~Ö¨ýåíÅÙå¥÷æÂ;õöåùÙ38‹¯Ÿ¾|÷ìüõ ï ¼÷úÍ•÷òüÕù zõÆÃÊPÀÃ`µWgèw|uúäüåùÕ_Þóó«×8&ðÑÞ©÷öôâêüé»—§ÞÛwoß\žÁçŸÕ^¿y}þúù|åìÕÙë«|>åýx—ߟ¾|IŸ:}Ð_|Oß¼ýëÅù‹ï¯¼ïß¼|vŸœÕ^žŸ>yyÆŸ‚I=}yzþªá=;}uúâŒÞz£\xØM ûñû3zß;…ÿ=Å5X Û„?0Ë‹+ýêç—g ïôâüäùÅ—ÞxCƒÀ{¯Ïx\j¯´#Ðÿ~wyf`yvvúƺėíέytüø§ClþQô¿;8êuzþÝùÿþ&ÿ~Ï•¹1–'ý°Çñ—‹dº_«½ÿýûáÜûMøÃ(˜LáU+J²‘mæwÓ}ÖZÝgÇ|B1—”ØÖ ZpÁ8"‡‹ˆPüîð‡¦ìïú*}ó™©ç¾þái8O‚òJknLè(Á67¶ày”åEó)‘ò1K¯g}CMT_Š4ç¥)¿RÙŽ$á±~K¥AjÜPzËÚ&@=¯9«r ^k“Ò›&çïnV&¯Eùå‰z¼ù%ÁðÞp-èJ~ñM)Ü(}ž¨À&ey¬Ê«ó“ê1_«Š_8~ºjÄÇON@é˲ñßµ¾FÕ—ÖÖ£âÕÑìb…•_ÂA^IMÔOâhª`*]8ƹÆ+üô‚Ò¶"£_¤'¥—¦žô›\Øbæ™&DXÍr»ºz¥0þÒ5.éeè­§œ©ÁçßÌÆÌ¥D@PЇŒ+4‘Õaè%=.£™Ìü%­¦,” Y«RT“Q.¾#ªóo£C@ø”QßÔïbì›&Á›>å\s‡+bVÌGÒ}òŽ77gǤ@%aëc…”Ç*'[þ$˜4,žê ½4,MÕß&Y^¯õI‘­fï ó2Nùݘãey{.I›iIQ“}àÔã¼…²Ì©úæâ’öRÅS+K(=7êo©¼—ìGìÊ ¡T†5B>âdŒ4ˆJ±Ç¼ ÉîxŠ±ãˆ›éu¥pržJ­ŠSQ¿S WÿøJ§Šƒ~Tƒ£)ØÏ$‘+ízéÞ÷ž|=J=ù–löäTEçoéäáïÍhAPª¤Wœpêñ=ÿMkuÂJ}8*^XÞRoâe›\ù3¡•/¾ô²XŽhÿ úÎåQ …ƒ`Ɇªò þö™ Ž£)K7<⎒#•µbèôJ©aÊ©zjåT-ï³™Õ¡zܦ/ƒ»V °qˆR0Ýû+`Á uЦ®¦j(ßfa1)SV¢nr§…ÏÄ»cwÐ’rM–ã‚¥õ´¹§kn¤Yô©žcâ*#Ù½dbpþMƽ=½+¿³ Y–­dm‡¸¶IÙmðhÁ‡’‡`Ö¡–G©g€°Êv þLyƒk”~Z'0¢'”ä:Ùùt-ÉËË—ã&qàE¡µÑª†?'ý¼<ÂqU%@©%‡ÎS$ô"ˆè&ì)P宪qvì9¬<;Ð#χ¶GçúCæ’IЉ¸ jÉ0Tšæ%á4-¢€­EVöbœÏgˆ¹!(1…W–Ãk5Éa‡îGU»ž¡¦Ü¥ü¢Ê+ |8í[Ã㘫–ÊA…¬ß¿{ûââöô¯œ=…ª{.àøp|®ö¥ð ë†>€ª—ðqù1å‘Ò\ îïï[FùŠ¡}èü:Ä2>€fþèaН_˜àIãû¤kÙE÷‚¼N.oI¥v®î×^.ø|ÞÑG“¯Š­ç°/ÊWÚŽoÍÓ{QŽ|Ž ë„ë¿qû0KB=áùnáx*}¥þÁ]áÜoYƒ² ÉÛ„ $Ó Ä!ÁuNÛæ—¼ù¼‹–.FM^Ãç6S]Sºlâ„xTã.‰“v&Æââê *É¢0­ ™ót*ÞuujEuj²HÒúTàsàØU•<…µ¡P¶§ÁùpÈ¥õ.ª±æI‰eDdÿî¨ÙiOT)õ»N½Á‹>ô†,5$­ûЫËñ¨[¡(\šYü¯ # ò†¨Ú<äNÂ.}7žpGט]K{ÞŸì§ÞßþöìCäà€&|¿&wÚ×=VÌ€›GþwÒ e‰ßïÕûíŽ÷.ÑM`zð³šÅ VAƒÃ—>£T}Þ¥’°4£|ìÕ/T9Iv‹©gP«Üª«ˆŽJ\ÈU£Äy¨Efô½n»r¦å‘©;ˆ·|j§¬òCÕ‹e¯BKMÒ~Eƒ … ­ÏJ\{î £I3R…CO´M  —È„ÑD£vÂó¬"ç8„=4Î×úS¯åM”Lö’÷ðʇ}s4ô°3Ò)3fÄ]Õ¬.©B¤že“ZÌ|ŸÂAÜ™# ßïýdÍ7lXÚ¾†ÕŠxcè©5`(>èöŸ·î«¤ûÊ}][ÙÖógz˜_kñ–…W‡ïÖ¿ö|oœÖ’&þ¬ð³3@þÝVØ,Ò„?ô+¯Ó™¾tU0ù¿øI­æ)ãç '¶Ør§É™:òÙ&Ž{3¦œ®!ñÖ¡¡|´\x>'mVË'ߦáVh¨!¾*¤É眣ô`˜oÍ*•Wöbe ð*/ή¼ ojqÖú–^%|¼¥,-µ`AÊr?~·í…gg/Ï®Î*…»áÜlX¿v˜wÜuN§¨§Œ…Žˆ;WÅV(;"¼`²—1pë­l8â’dðÛíSŠ­Óyg±$ÖFwO„§®”‹.dÉj^N­j¿Z§ª˜IHr Õ4®¡gUÁŒœT^¾ÑÑCi ªîʲŒgN<*¼³k_ÀJKò‰WAì# %¾«€ÇÔs5ûTJ1]\Ef¶¦-ëx®¯Åph>v: h°Ÿj[Ž6mÆnæ>³3fWLXaCµ!ŽUÆÈÂJd•O4tfò°S¢)­hÍÇwaA>ÖÒ¾Ÿ½3á”õÚÁÌùa Y»nž(>+SË|P×XὟ<ú0&ÀOêä'­Ð• b $SŸ LÊcÕ4­OÃÒ(„sõ ¸<ÅË\qÏP—O›Tš|+ ïIéÛÀ~0›&—åmŒR;Ï&•÷3â=÷[¢!àH6’7@2'•šIRGªK!‰¢)á­ˆ ”.Y¤r¥/p—/¾HKÔÆÍCÂ,’Mƒñ¥!NÇÆ‚d ¢~ö)õíâÌ2-%âï­l„Û+ò¥Š$`‹urä¼P½ ˆä|þ1’=L7…–`¸ú~Ãü¾C»ù›o°õrŠWã ŽDÚ5—åûö;ïY”±B´•¥i±92Qß—TðòhŒmpùnÙ+á}÷<]B‘tY±xEEÅqu•x–ÞpjKÞ{@UýVû[ñ@ KT“¤Ržˆñ…ôì^¬Ø‘ÄÆ5ªµQ3eåør´?ŒÍ…ɵ®|‹uo«« ¿ >Eó&,s‚mzwð…1ö[ÞÕŒJèαžÕ†cíN¼Pé„ß7žLG2½¶ªÙ³­gf•\¤<¤³f¢DjÀáð.L–1ª"·-‰n¡FZ…/LAöí2„Õ¡ø¿«VXW_ÔUä&rÿ„BC;elÔÐÖHByÅã‚Th„ù¤i)e¤h7`â6fOAŽ„ )Ý*žw”|Ö0€5$£‡ÊxßÀD΀,0§+é9S,ÄY..TVI0Ž-ý5¬½y;î:Õ»†ËT&‡»R¦g¼Áªàzȃ<ŸoÒݰÆÂWËÀ§i‰nø¼ZEÆ7¿~¾ßwz‰/6®0Ä” E(C¾“D,'=x§¥`WÑââ<3ªÖC˜>PÏu §|èùCœµß¨ù¢¾ñðŒ=c®e箥…0¾÷Á§×èB@XáºÉrÌÐzlV¤Zq„ýy¢lª"ÿxK¬Foèi -À,É‚¶ò(3ÕT\»‹—¢ìô{¢*E’Ï@–žtOº°ÒÛÙsš›ÿšÄvíÍLL€ˆ¥™Q¢*΢[׳ŔÏd@åHN™†‘.X‰&éêï’I‹¿F¦@ø¡TOÍ»N·×ÿ–{ó÷IÉ)Q¥šÞ†pŸU9'&ɈUü¦¯ „ÿ­Ïh~„¬*LÎ?žõ ·©LëWß52ùûìµåSiC{›ßKÑáEÀp-dÁaòßRªêíÞ¾×OVê<+&%Ë S®KC™#•˜°) IËböʹ ¹2uJX‰½m™ƒÞ©7޲ñrNùhAÕ Sc4jX'fL ©È®?d£Šï±gÔË¡÷ù }9äÜm·<ðü~û«·Óˆø¬Eiˆ+æYó±¨b¾º|=ýÀÞî%Ì/õþ2 ž ƒ06þp,¢@ms^”ðÒþœ†ï{º}ÕÈÀÛ’€_€9ZjMØZ-¨V8>„*ñèßÓÙwF©Ö|íö<*÷ÞuýÆWeÀÿ›¯ŒÁ¶úl{[ÏvíW:Û^ùl“ÿÙÃD;ýªg—¬ª0‚vukÔÂˆË h"Ž¥¾2¬£Cn¦€]˜õaB¿í8ÿ¸né;`k6SCò©²3H\ç:¿GJ”ʽ¢Ü×e® ÒÂ2ákú¸í´Ú ó=à'î„“øÚYÞÑ‘—Üte¶˜b*óÃ^M| áü!ç*}t^µ{gnMÄ6òäªòÅš}‹U"“°À*9u2hò”ÊY$-üÜp¨¼Í†C1h”ìú˜*t —Š•9voú uÍ70,Š‚ïß÷Ûº×Ìzuë¼9õ¨‰Ç™M¼ú«•üF×aÏOï/è7v…ìÓгÿž½f°[?ñ„tÔ´ÑDe.½"ê© §°š~¶ûý…ýwƒ˜‰Î—¿‹Aj] "§ºå“œ3ÚúfŽí¶Ç «£–O¾Áì¸þÐ;e;u˜ÌÐ+hbƒ‡ýDÂ!¼Á‘­Ê®¬ýÀYgŸx>ï%–›ñe·áÅ=dkáòŠî“¢z²ðÉD~_FD„êRÖbÿ âU:#Ö¨x©®Q¶Î÷a*¦®Sihu´ˆê¢Wj.N}|¢pd:>´RÿÀ™¢;T (80µ¨Ðb‚^Rš¤&Are–ïƒ|†ãËy¤/lRÜ–ÙE/s­v±ŽqÙ™Áxe3qÊ…sÔ†Qê@©›,4Zb@â{qv…r#š"üI‰oß]ùÖ¬æbx:ß. TÀ0ò\)½¸,c}ÓXöíÚÔK†ŽEºEt× * xªž™*’ 7Xpj’| §QNêÜ@bɯ‹~%Ç8)óE±òüïI<¾‚Ÿ>û£ñ¾|ó ïo¾á¹Œð]ù ›‚QÂ+ao <òÖ¯ˆ5oÁBø°ÐOH²»FtýhÈî~ÔðÅná?¸åçŸë²-ÚŒóPK«ìË£µUÅoý\û¹&o¾AOã{.ik,a^Â2N¹š)É:rå>9–úðñgZÛO€åJaœ(ÈCÜ(pS”IÏô0ëSv·Xë¦×j£—6þªgð¿ÃA– PT:ÇÇ Ö%·ÇäëO-ºIxÛd^ 4Õc €5f‹ñÿ? @L¨D¾&–ˆ¼7·ÜØu“F›Ö™¾‹@ÜJ)? ­¼E‘¼=n‘Ããwßm4¼§ƒS«"é?6h†…7„•p¦áôRÏg_áàëw±~7âØKä3´È¢4«!W­…`Í'C…¯BrëÖR¢­02ØOÁîNrŠÜ‡™6Ùp6F Rö|JHÀ‘¸9.](ñ8z ã…€_à¹æO]›OiÝŒ­”Ù†Rôk$ÎëêHe§-ƒ"¬U" ‘NyĺÝ]{¬ûƒ™Ádz(žlCSÊ#‹ü¬®– ˜9ë⥳¹8UXI…T¬¥H ûòп¸(Lëa®v6{G¢ÇÕW Hçà&MFA¶Ûºœ¡™AüÃ"f"Á£ê3¯ZM„üÒT°ÞÖA¦³/´DŸõ5&ÎO¢ØçŠ›_¾²Uì¤b÷hs[µ:WÔ¨umMõf¯uï—ØÈ¡#ïðÎ …Îv¾à×àÌ‘ùª÷ÏË)ìΰ*a}‚4¿¿«PÁ < (PàRJÝåÁ$kvÕK$,*VãØßËÂ)Åm¡p¿«ý?æbAƒ,>¾4–û\>‡;÷¿tš?·€ÔÌ‚ l‰Ôÿ]oé/“-ðÞî6©ÿw™EãÙ#Ã=â³m.ÿ¶ ¿N ñ CkŽò;Í«M„•40ŠèâY•o¸¶v¡§F¶Í/RR拇ÿÄB(íÓ³¿Ëù)C_q(l À¶´-ÆÈ—åñÈ\%í ÂÍIéÍv>í±Ù3XWòYjÖJ’³çUâ’P¿¼Í÷!ü´zÿyú>h~þðí~> túTù•½¨6轚¢fø`9‰Ò "G¤Rw5¥pj˜zï‡óE¯á ïƒ;øoŒá¿étú¡¡øÍ¡‡=ôçæËb‰æ…ëð¡MA eC Ò±¥ôسiHÕèÒêgv¹!0éj4ºáÌñ6EEÉ}Wö—rGˆ>YvcÃŒ™ XRK50=JŒN 6UY&í€'ˆþ@Ë ´f[΀Ùªe·´$‹YÁõÒ LÔ®ÊwW'(o6ÿ7ä‚ú¶ð•½N«Õi·÷鎘ђ4¹ÞqĪÑÌ~ \š®éXmÌlœ±ÙÚ!uÁôV¶H£cÄ&,(ú>Xåd”DWŸÒWøn T†PF€pò«l…u°þ2šÔ§Y&uË2rE‡‹`ÊÎÄt Ôi+¹ž3q¢5ÊIácá¡_py°u(oÍ‘V[Û2%*€Ù…³a™»Ð¸!›Qú Í!ì ŒF!u©¿ñžÇiPÀÏ'Ñôìþ<ˆ1ÀrC¿= Èr?®¢9þ*?ž¤ihc¾÷AYð G’h«ÜpøŽ¬\á„2§í¸Aîùø‡Qÿh¼T €í)Þj*eœè€â™èÌÓô”÷{GSŠ%é¶ú4Rdqk©Ä[hHS=Ô&1{‰0`ñøf²!‘²PÐÊÂAÒ—CQ²18Û×ùþ›“æ‰=LžxôüËRQ„¥Õ —–è˜;8,:ÕmEà{=øúõC‹ÜÆYPiµZ5û=Õi>´¼zÀIAL‘Oâô3YFi‘ý³Ö…:¨Å1g}{J¾Z피޵M\û~‡t¬Í9gße* 8á¸Í!8v‡gG©y(‘`2ÉA §P–!LFmÏù.áû5\pDNÞcÈñ!ÀÊÊùšN*à%ã?"Zøˆ|‹äyÆ"ÝëiMɃ–ǘî”Î_G?1Ú«!x ôYÄg!ÏN¥£¤Šªe—jB}÷A®Üg[ÞYkÚj¬‡yKÙ§[ b’³Êð!¯oLí *GϽK^¤œ`…€ôq¶þƒÈIûýFtºµ CLºö[ èÞ8NÉìgYTÓåäºê¤”jþËmü$ÛÍç{ÜÂB¦è­,`iPXzů FN=XÿÖY†Ó, VïyN6aÅChàG+‡ƒRìügþíÁ¾ò–ÀÙý^é)pŽI4^ŸW!±°åÇV:fJóÑ$²/GN©J˜Rü¥Iü7ˆµ÷QÛH”^ ¬™J×dð!­Âp®i§ö'•=/•´~ðw==Ì”×[ ²ó‚·æÁbï‹ô:²”v·-¯¬r„ÁÀò\¯0óV¢èð뛉³è„´5ò(2âR ØK¸DkòÓÈò\à<]bц-Qp¾øË–ìØ¥Ñ£áfctó[hße±ikÙâq[8rP|L¡jòt‘Lë] ýá?îÊÎZÕ=Ãù‚–†z>þw„úåÙ–´W틦â$jŸìEe„ß“ü˜Èžˆs¡å­M2FBñêÑwj¼NÌh€‘4óHBrÆÒOQ Ì ß bƒH=h'E3o„šZ†q˜¬÷b^–r%ÈH‘vC„õàÖ£ Jm|5º"&uM°ÕòP§áu^ïÃ׺Ʋâg>´$Ùe‰¢³ï ÞÚƒ·ö¢Ž¾ûhØù¹¾Ï;üè'„ä»?t~~´í÷òңΣŸ?è÷Þë?äJû–"-âеÇìZ@NyBÄTÎbþÌ 1^;ÿ›tè6\­=QÚ QY˜Û½à!g…mN¹›yÈ{UÅj5Òç¡Î˹nþBÆÎ&š½Cç&8D*_F)z8Ò«ô­¾-{«rþTàÅåÈÁøvJ2) 9˜”8O‡mV¿¹®²Ä1÷¬;l.ñ(J*_,­ªÜme»à;¾¦óGqÜþ‘¹Æ³p|‹±´B>¡UA 1¥ÛX{Á<>bö‚D4Àão³t,8Fkn&aˣ̫ á;›ŽS«FFAG‚5ƺ¦ÙŠú‡ïù7iê?¸ÊêE½¬êÁš¼Š^¾u±¼ÔÆzÛAuk«L‡·T÷£„±•iI07á,R¦êVØL•ôÂOXT½¨IþYÛX•‰Æ÷†Êo+W²²ÊIm:¥¼Q{;„êQÔ¼rð ùX8Ÿ&å­@þ ³»Í7É2ß{ Ó!>×6÷ziÎÓ¶û8œý¾b -NP[†yhhô–VáÚ¨SçÄéCmmÁZŸ_ˆp½í€ïÙ9¬r‘·.sõRnYÌÍ«º Õm¨á±çÓ‚^Âñ«¸åw޶1»oƒ­–Ìí³ÅkE¢L€ÄPŒÝeÇSÍÔ›Èí •s«EPùO[q§E² iÞ£"W_!ĆN\Ñ€ÙáX"E°3ä, ñW@` '"dkœ{¢j!àŽh%ŽRJ™¹…ÇÑf™±SÈ´Ò+f—GôÎ+VÓ+/F˜_Õà?Þæ‘+PDUÈѲë D†?bRF‚ÅYóEÔcÖˆr SD±ìia"¯Xt@ëcÖ qÎHýzøXnîE ýÛ—£¢«Í‚Àå=ª<*“¾¨Œ”¯ÀXÙã´ÏA!Ø@4§V ‚ge÷ ÷€pÃäuØGË;%:íoúGHôšêªr¡"6ªq" ¤sÖ!f$O×¢^¼•³meT_©ÅÁgLIó¢¡Uðã’tѬܤæ×&ž£µ› ¶ÝñŽÌ5Eœá®6ŘÂŒCt¬ùPv+a‹õ6…µ¶ku6Õp oÐðŽ-oä>㋨ævSKº¾¹âW‘“|é:bZÏ2ÓºïÙE§é-þÀžuø—*G÷GÿÁED®µXN4Õ#¿3ÇæI»Õnµ¾ÅkvdúÅ;Çü&ý,;Ó‡E±±ÔÚ£¨õV«þ¹^å°ó "·odê:Mš•×yÊÇ·Q2¹No€KåxÖ!‹n²ô{Â9qJ<­¶ãm²{6lUÞ`“¬(øC)›+†A õEÐñ« ®Ôò.×3GÚŠ<|ؽúu¶,y=œ¼ÇðSÍ|zì£ aÅÉhݵZ8þ0£´Ù×Á§ä9´qªuÖ>ÛÔªÌWÄê7¬€µm˜¢EJH­\Ó€hJ$?$n ê‰L| c[Ti ä[S¹\Ø“‹*B…UtÄm;Ê¥WÁÔçÁ¼:òu~Qßôgûžû´¯*cV0-Ù²®”¼¢sWbµ‚Š1B;[jk$Ž’fÙP˜Z™ÂŒVžRœÁwÙ¹~i•þÕGnøU–lÓ8 ¢¼&ƒîánÂM¦ã?ÃbÜzçŒ2à ¨µúI¼-©zõ(Cmiydj¿‰”Ú€Å} oéy_tô=…lxP†Oo C̈) q|­•ô]¿iÈxÅsvÏ)%È Óö¡$Îö+IFº3›?ex}&˜ ")GåI+”"àô;ä§=G»#骽¦|˜òIª˜ᘂ+Ò»kðàóêT}O­¡Jšõb~ò+”. ÍÕÊæ¹D §¥‰T(>¬ÊƒÕº¥r¬â(ØÎø‚õYöÛ]*¢òº˜Æ ºÜEð‡¡¡Šsƒœ˜TËz]ŽW)U»$8S+AÚW±r´ùÁ,!`”*6'ô‹ÀQ¸G¥eP‰>bWƒ(_tµâõ¦µÌ]ÕÓD%u ò¦ÛfþÞèCQnjÁï¸VU(‚÷ZkCgíâÙøfæ×hÓ§w¦Fäó”·¯Ýt—­Ë*œv|ÛýŽ*V>1,ñÿøþA—~peǯ{è¿iuÇj^‹¹Ù@ú¿¬aµÕâɃ«IèÀë/ö ÙêP?Cfd:ïë|rSäS&mÆ7Vä)hC­o8?·*-›èK¼¶æ9”mD\œÏvìÑœ-Ä…4;){¾ÏÓ7yUŽbŠ8Ø©!Öóh²a^“”UI[—žç.¯Ëѧ ·†ídóu÷h¼-Qˆ-âã4òßä­rñæBÁ‡-yÉÖ¿ÙmÞã;.¶@¾NØýÖLožÉ¨"Ìb”BCñ±k(lÐ~² ø¡¬‹78tÚ`ì.8ÄN!× :´Õî©ÒÆ1-•ÌøD3jB‰ðç î‘<&<Á{Ç…Ø2‘Ì>5°Ö»ôêOËAe#¨ Lðg¥–â^Ï交žRµp.·”|S¨dP3¡L% —À*Lð >Æ3SV,k?®ˆ¾ü;b}-òæ1íO@Æ}¼›Á =âX™¨­#))‚ Ĥ<«>âÆ‚'b¹Ù~dÆz²ÂÎÈWëgouÉ™g£ººˆVz2÷Å2’áòñ{cíº¥Ø+rQk ÄL6°fµÝVÛÊûÐu6Ñ]ÈÐi€s…9—Ê@¥ÏªŠÃ-ª²br^[±#‘>Ë€7(×ИTú­Ç.ÇÛšq††Œ_Ý3«©ØÓf‡•Œ7—\5Ó™*4ŒT†#ˆ‘$ÛÙƒŒB† F„ÁÎp´wQšq¶_ƒ±»Ó·)ŽZeFFðª¸n· —‰Ì¾ÈF*Îô!,yŹޠóPµîInÆT`̇“ѱÃ-´x¼k3Ûm{ßþ¤Œ•V¹RÆõMߥ©ÜšðH¢"„¥Êì´Pû½Ö¼ì%*6¹íÎŽ@:i¬FŠ ÜŸE¢qUœáÑr_‹cx;àút"¹Ù¶t©ž†\(:†š9îNA›) G6Ú!ÝÆ¢ÙsŒLà†‹2×tç ¨ …úm×m6£ dâ`f±*”Úd32l’¦ æÃ¥/®)÷*¢8ÈêÐPž¨k=G›Æk’Øn‹mômªº€[g±˜ÏcXOgƱ€ÀêÙô}ÂïN‚“7%L´Rª8Øn´¦þÊØqK ¾R ì6D@×ÏÒ*×{¨KI«¿)v 0=º [’ˆ >DE± †n’¨Nb‡e r.05µžËJm‘ëDªê[]Ó|€ ùºÛ™_h+ë¥L ʆ8æíE«£å²êiÚ —0ƒ¨ã`‡4âÀ$O¦ÒYB'M°¸øn_ÃÚH-#l¥x%¸ §‰í{Š\g¡³è’£§Û@zñÊÊ—$?¯ ›¦©!òÉ O|†@…K?b}âSïx}Ï…þYÛ€¯N5Ãà&4ŽÌü³T¸’…±$\àŸ€àŒ×cäÁT´Ñé¸á/ûŽ <"U1òû‚jÕhëéé®Ñ@«°þ5E@— Ññ¾6}|@BøLã‚ä`æfò²NxÕegNΘ—¾uLßèÓÇdÃýÂ;‘‘9ë/QJšêç< 7&Pãû'’Æ*y.•)ÒU*öwàøÓšù/©bUr6òÀˆé>ÉX1©ìveiJlÈSrñA]”Á㪧‡y_5ü“¸`¹¸ghÈØË½ þdü1²Z3Sõ—ðc1†nØ–…úƒ÷~DÆ_Þ©ü¨©NöÝ`³0â‹ÚtÖŠ™^84&&¹‹3^BÞþ`yÂ2V"…eoHzëŠU² BsÔ]lrë“ö™@V…×õGÝpÖÅØ')„r¶‚4ÛmÓDK”/Äœ" šŽÙ¦»€Ó¦È„ÙÕ¬aÔ„"¥äŒYLƾ᭭DÜ,XŠÎFS2ÍÅåè&GR¥ùÖITmŽÏÐó¤TkrCIˆý£a¿É 9mµ(s@;Ó©=í8}2|²"¦OÔðI:²€ž"JÍ6Y;*‹Žè¢#'kEG)(Á Ö0¹"«WåT‚Ù^•ªJ¯oƒ½“9××ä zbbÄpŒ„E§ß“ùöd ÉÉödV?™4²ÊAk5¯µ\c™Á‡Çþ<¦ë†mKŒ‡ãe)4žór´<œ“b˜R¾N‚¯E»D ¬XûŠƒÏI6iZYO3¢ãÓY€R©NîÞ9±{ªzx|ròòC»z´s…‘‹ÅÕÊ"NžKý2'=ï œBÓ¹ì#Î)L‚ω Sîä²Âd(߈ª°¦± Ke]Å|WdWsj ×̓DÅN„õ«Fö½‘kŸ4Í&'96‰|kU–\ ðxY+§IC\KI´…X1¤nå¬9'ç“=`DU(9Ù„·ìn³W¥[TEåýA­aÍýÚEQ{ììTµ¡_j;À™\qÉHÙ*û>“ëlj§Û: |@CÎpÊéÂ÷è?¡hÚ†Ðb½:•бÓÔÂx¡Ÿææ‰¡U0¨Ç^ˆ:åcžðîk¼ö ÷³¾kŸlužÌ貊ÝöNDÞ†MnËÎ[´,é¦ÇóÆô@h굜=ý2eï¨W}m!^T…ψäŒÉ:‚׋÷È{ØðíqÓL+™ÊòÒ˜2'"$dAôkVÀ=äQÒ¨ºmdäjnT§0ç5k}€¶(¿‚I‚=ÕNÄe¡@uV¦Ó‰E8óGÓª˜¦¬Þñƒª*“ÖDzýOóÅàq¯åÖªyæÚή\’µ÷5÷\ º ØÇjùtŸÕà…X®ßÇ^‹wb´kœŒ"€¨­K#Ï;ÖoÊ`dZ»âNV›€ÓªAêwů—8ïµ¼kD­í…HòÍ6£•G tÓ(b,ð,Ï B¢å¨R*Í v 3[\)ô–Bw¡”R<'Ú^,ÆRì2sšD½Ý†8]ƒó¶“Ÿƒ/¦Mâ]q~Ì"”§|MëywŒ«6ŠE»Œ/ö k½l—ÕL.Ši‹Å$Š­OXSöÉ“#"}5Å´±*‰J:èO$ôª£0¥ñ•ôcî‡û@þIaÄu6½#Û10çÄÛçĉíN¹Ws¶;Ãøþ¸c¾¨t+ÒdDp˜éýéR]‘>´jÍ©ZÕ_Šè°9 ³.0ÇѪXc°¥€ÔÛÐ~ñ|%]º¾óø°¡œGú¼ƒ@›Å5&ª ƒxÓ]pøÉÛ‚‹gŽM6$\³¥,¤?Noišáar‡i8»hª\žŠi.jÉžó,9VµŒ)¡T›Ñeí…>+ÉýWr §«.6vóòFÆŒÝÎHy)å,/°²D¢‘ò(½Øµ{ÿî©ÝúçVAx…7½*“¢“ãýH¹,‘ð‹üI æE0YSQ74wÓˆ=&Þ‡«Xºêçbl)c³òÇãfå†GÊ#°«…ØÌ¶o‡~eYÜψE¡ ó=Ù\„š¦-cLZe­œG¥ i¦v:m¿É[ì•••"ôUP§"H;LÁK¡(Jÿ•.…6’Òfj|êÒÉêÎC»vOÀwºíŠãÕcЕVPå•°Ü„»!¦Õ^FôlZÞŠ¹Á :ÝÀ7•GrÀ&‰«dÑm‘§¨x8l‚¨j ɺY[c•V"¯ëd ¹îk=˜oùWQ…ëÕì0½ñìhNT’H( “à#„Ù$€îª ogŠP\U­o¢­b+32 Sý¬B?’ó")Qn—Àº0` é:8~힪±&ˆ¼±dpK^EMHÃ~mïîñ]µŒŠn2òƉÊÀrnåØPªã†±Ô2*i Ó²  8;> ¸³ynœÞ““üNé J| ºÆjDß#tL£ŽŸÅØÄô9%‡Oí;tp²Ç¬°®Mª71 ”ß)—]ø,Ã6¼ÀuÊÐ&§ÆÁ(r•…9?åÁ)»™õJøJ˜¬†îÓàÆQ˜ºôañŽyõÂÃG+`ú©Kc÷ÂN«ÿm+„½øÅ.U,õQQ>6Y„npå45Þ q=p~ ª‚ˆ+*7Bâ0÷Z²é}lŽdÏén«¿Î™šu°-›œq$Ê­ÀÄ[§AÜT.—U?3™óUIõ¯©Òpq8s~æ<õ¯ÔƒÃ ÅÜLù}vÞ9|éTLÝeS§×1eO*¢˜Ë]lŸ°3-Ší«<ý:-½wñ‚•©LÜV†aØÇœA¢T€‚!‰WNŸž$ZFϽÿÀìwkÍŽ8ĨÀêõ^²¬Ö5söÂ7Žý¹½”0#É YsIávcs‡öy3ØYPˆÓ7Ì»“uE^æBšLØ‘¶›OR #äÝïì‚XF¶ŒHoþÕö‚ F7épm£8O‘‚ Tù\F¾RY˜ l×–ª =¡ÑÑÞŠHétÌ>È2ûB|¨g#ÑÔ8á Odà>Ô˜°’¥‹{¼+ƒÇ©AŽ:-!&¯>>ʡ㘚ɋCÌhCK´.ޝ¨ÕqéP)…LY‘RÐ È>íU—Þèé]º(/:] ÓªYVÊñ1‘v¢ùhèÒT7~ǡ刚\¾ÕzÀÓ•˜›ô2•é#æ¾pxmâ%à ˆÐÎkF<ˆÑoÒ X%cQyp•@šééÑòÖ|‡z6ƒëÇ|+±OÈÅwk®ÿÁð’ÂJÒ° .šBq?Ôç (_IŽ=,É&¡Ž^¯Kî‹Khdçæ“œô.ð#%ä’v ‹VYfë5Lù}ç»ñ‡’~!- û0z­Â.³z/jɦÅÜîôñïú £;͆¶å1 †ÑÈŠGx@“™÷º ˜Ñõ…`¿ª6àÁ¢&ˆ¯ÚEóSÂ4b¡ˆK­Yl‹!²¦-Ÿ p —]ö¬ð¤}èÕ…š§zØÁ” ¢KÕ*Ûap‘´aå 4(­%ZºZµš'ÿ”LÓo^4„92@%h$1‰ê¦RÓ)}yyŒí Ù`”>ŒZTRu»™y©D‡åy‚ B?Á¼N‘Š÷M|™‘ÑRÜ߸Y°3Y”ì‘àÛóQ$L±¶‚ýñS´÷!ÐÑgTTŒRœ06ñnÕ´)ZªSé’®Û^ r»J™ÙUì»^+NÙo îHlµ47zˆ4•>ò› ï5òÚmF¨D$kTZ S>¸«„,³Â`(0£€§¯+èÌkUzoê®»‹¶†×]EXèN¹éqfvÌæÑ¢¾‹ŸÄ öýˆ‚eÅ“xI ‘ÒåŒ`‘ôÖj‚t·n¨ŠÕ¯{é’²Â1"Ãç´WÀ9 ·!±ç°¾uÖ0bL~‹0gH3Ø3: ƒj/ÆC3Ò>Nžò¯+ÊG¹>yËc$¦èF¦ÔΞò†d-·)†A °¨VÀ\DŸ/†hFJ¶5¤ûÃ;Æ: ½Ô¦ÜŒAD1ÃÆëš9ºBUËN¥ qõ…ó™™”— e$?¥ ì©åêÌg€¹áÊ“¶áÆãêӘþ»NT:ˆÀ•…]N²§4QÉ~šÉNA¨[»»,Ñ+)ùAEÿi ö§2‹tbò‰nwÏ´† ½ŽDbiSÌ\ç muá%Ý7± y¡=è~]•)çg€Ê4äâ{„\›ÚÉ„½3Í1N*èió[Ýgç½uõÜŠ ìk Z¼›ôB¸¸(hLJpy±‡²æa&G@€£(‘èœìíëÒçŠÓ‰µ„YA+€Ò’0Oº‚¨@5»+*aRS˜¡wÚñŠÒ‰w&9í.óÞb„f/~ø ß­i;Ô*PÁ=*IÖ@Â/nÍ}2W/ß¼i5§ëR¿šƒXV #vY†âÃüXLNÅ ÷I~Q¢ÌË!‹Z$ƨ°¬¡‰qî¯TuƒH¥Àa€Œ¹P`ª§•ŠÑiÅQ Róã ú[e|©û\³ RÆþJm'‚°Ó‘E OÒ£¼°Pч _B㱯§[<(‡Ü`ÿޝiɨœH=v¶;…‘õ ™Âg­éè´Ð–'´©¨'ŽMm—93?Î;Ý:Õci*jBºO]Þœuü“û·Û”Jÿ1ôãÒl:š¢Wµ!ïÏÅ“âaáõB:Œ³ÍÎ?`wPÌ=´Íw&‰®gMº¡PQ^s5ûÞ¨±î5O)Cë‚D&±ÐMXÂä\GG½Uˆ'@„µ(1ñ¸¦<­%auÖp#Þˆh@è¹?ÿÛV1﨤æ«Ä»ÔC•éµEWRný¬äé˜9¡IÍ’¤”ÀbŸÒ¢%´ã1RÞÿÒBÂ'˜éÒ(¾úÌCdL¶ð®š’@)ïlÐõÇ26„DZ#såAã+0 Áä ºB3öY±®Úoµ¸jZSƒuâ9²j‚¥ë†©¶×¤®–Åj³5ÃÖ&a”¬Ôëð¹®Yu×d`ü¥- KÓþ”¦@â ™ËÄÉ(šª&S++”" a™ ÆòBIC9€ïƒÃ–·5ò˜N"ëV|©ÌÌÓ˜«¬]å±k¹ÅM¥sƒ%IêærÎøÏzuäV¤v‘5E&R¡ÎÝu¥T†:\å|žÇÚ²Ë^£ €OA¨tjƒÿE¥€ãC>KL·'-D2~jßÃüœªR ª0!Hiäl*cgˆE0XâiÁÇo˜xC¢©OòRÿ£p‘0ů8_]n@ÐÙŒx´™Ì˜¨†í1@3Úë&¦}&™¦ÁZ¿–XSRORCô² ‚NIzØä3„EÆ:á‡i€Ò\ ”Ü%¿4´›À.©†y“ÑðBl4¦MÁ—ˆÒ\Í`ÖTŠõå\-±ëÑ›w'¥µn•£ŒhžŽ¬š<4…`'•Ag¨½Söó’/‘½ç|$è wÅk]¬1[†5•m°"† °Éj6hwªÃÉ2´­@r–œ3µŠØ0uqLT¢0ªãgÈ‚ŠTÌóHXL0¯å±oÓö&˜/5³Œ‹ µ#…Ô.ÃËȳ*ùf%·ZÒ}ÂÈi–——<½Ùåálžìžâ^£JóbO·x­²fX nÞ¨Ll÷ýÁü<jšº×¤žÓŠ6E p›‘¾=8>Ç#‡ÊºiËã G¾Ÿ¾ç+…yÞÙUÂXFIlÙÐ !©®`áE{8 —YyZRžßfš^Ã\&G=ÿ¡õŒeù³¡ÆçXû—€·áêé¦o4ã¾\}~là•™¬á/ú]A2iìP·ï˜qÉTO}GÊ P?ÈãGÎv‡–L\K/:ÔEEç M\â$ʾÇ[;°º_ÎÌÕ å¬zHº²‡#ȤÌñâÊB¦²´¿>·l“¯øû±d©ž‡j¸Ÿë\* Ø!+Á.%z.oï&Euå‘ûB•§ú/ˆ»/tÅæ/YEщ”(ç¨è­W ž§ûAø ¿Þi¨Ôå3t‰ ;gŸôµÄ¬†*>ˆSÌËÌÞ†î Í_* ÉpãÇ"U̇~L”NŽ5•»öjÞ´åq5™ê‘û«y§ -ðß ÷Ÿ¸¢J^ÑÕ©#SU» ¤!–tKcøÔ@£_;WiY»ÛáéÁâíŽÀ…Á'í,ú›¬ta‘ÊóK^Õñ·E ›ûg¬7‚/–9/<«. râðÑ\t"ÏÒeGýªâ7ÆtJfý±žKBÕ¨°Ì¾UŽ- ù* Øÿ‚Ù‚*JâI6Q ÄÃX9x”,8ë·ÄU+ÔÛ^»@7~ò´ÇT¸ÔtHÕp€ò©(dØyŸñv“ª½Å»;˜Ö—¦\¥¡—bãx^3fák'âçðÐOeä1 Í$7>2éx¶3äé⤌Uƒ€¯zò¬cGŸÒ† AQ/vŽxšººâ‘:Ô ÅÉô¯æ@*²Å6QD¶}³­3ÌIj™vPÅ)Ös+*¨NÉDd|©Úv)šåìÌ}$ù¼Ck¢zêÝÛ,KâÆM]ï$Š³Ë aŽ| ø0V2¢<›sÊÝJ;†b!Qs‘Ža}!øsðhÔª’¿ãþáE7±¢¨_:"Ñ`­¦Í.ÒÀnš]µkTÙAcŸŽ·!2É„Ó#D¦’—d…Èbu$KI¦ÚlÛÞôvCª7±Í­²)§/ð1„§Ú5ˆ±ß`ç ëÀ'Ù!Î@FWçuNºÖ”S‚:: î¼vLÇŸBbX Âf#›tÛÂ( §„åjΠôg湯8C¥!¹9Gåÿã„JLÞ¡‘ÜRx±¥Á,‹Žà&L.g®hw«ˆ´”Rš¨°†y:º´áN"V×ÔÄöô*×Ñÿ”º¡Ÿ²~"-Ýû,f™©¸K‰£\†’}É™!]]ïî4£5WtA⮫¹„›‰¤É¾ò¢Ç‘6+RîcU¡{‰ÞÅN†’¨¹£Vú ^'hž«Ðôʶ–CÜױƩ½Ö\Jv†Äµ1”xë=Xvºu­Ç4+‘NÁ‘!çÀY¾M¿\A)™'ô @:r—ü"U•©™Îg~…ÊL? Q“äH§³Ô \AçÃY¿ º¼²âþŒ~(‰Ÿ‚iÆ(êE™zScb×ÛÎ}v;ëvä I]׫?èKt4 <š¡ÿ`Ž6È3ô¡RA¦"<R<(Ëç¦ËJ#“ÅæT4Äüqì!ä²ö¡}•b˜nÛM„†8à{Q‰%-*»|±M"T\eó¢¤ó¹j°CÛ/º¨°5›Ýx|çž}E/ª‹©Ò8iæÇRóW7þYÀønžx3H/Y+8NÃ+2Ã$÷)ÅçÉÈ«½‡04$¨ÐÐYô'£NUÄÁ.­ùÀªPMœê5?‰ýîzÉ?wqú™Ó#ºhú+ ô4o=™ ‚Y7$±C¤Õ!žAM¨Rò#´Žh5ü¬zݳ½êØlÔ‘WÆXA|çí¤rEçv’O19¡}Þ5¤Žh§Îivp³w1ÚlyóAÛ‡ü9.ÞËŠ ›RŸfl[‹sø27ñÅËžFEçÐ ÔÊèT|bØ„”Ú‚4P%”šgEÉV§ÜVCcŸC½$7ã6Èø­%âí%ÆŠ"0´9…••L‚Pè„‚À‚6 Ð"2ÈnØ.áK höcF¢Fq9c<_ô‰§Eg\E½‡2~ž»ýf¯ítêo;p–ncÎ k÷"TÕ°XÊ!Àî†ÄLÈ#àG®¥£.«ˆjÃÀX¾(!µkwL"Šà2ã'áý±ú§ qm‹ô¤Vü*Ñô„Å0¯#¼äeÆ&0Þ…ARlµµ†”vÊ ßÌ+¿IÛëS_¤iÑ6êíýòjYKSԱ݌õ²ôOÂÿ9&–6ãz™åV£¸À§åScX¸pþ ôs!§héf"XQàþº=iFÝ}žÍ† µÉlz}Ì÷w¬Žj/G c,­z‰¼gCRóW!Œ ‡`µzŠÒ]HCWž(á 8? õ‹¢ÅFgq©†5Âe–R!]Ʊú:‰c""¬ì² ñv0˜k…IJíð¸Go ”n s!5Q]²DšÍ<›Ø kQ+kðÐéúã(Ÿ jÀð Å=ˆ'F\”¤[^Ä‹\f¸û®ïéf›ÁliÑÄ)"0>DÌ“b8»qÿØæ-¹ u}1]-½¢J44VeÜeÁ»ðxÅŽã ¿Y2ê¶Ÿ…¸¤_?è%÷ÆáD– |Šûcš|¥ðAïqÒ `K猧¼Ì´ù®Ï0j×oñØ|Ž 7(hÔöx‹ Ô,_LÄUp²X’íah„ýgŒ.IòÉp¨äÆì^dî/G^>5W顉ÉÄTÂCs&áwê4ÔW;r¨Ë$v2³?MÎ^¥L]>Ó†ó%yom(TÈ£bçüùbØA¡«ÇTCúÑŒžÎ4ÔR¦i‰‰Ð‘“ÊJÿ0BVò’C®p˜'£ˆŸbLòvZqÏpdš/÷lŒ}3”ÖŠ@ëˆ]Coãü‚9;û„ü“§ofvUE¢"ÊtpÔ*ì~1F‚E¯ õ6±7jf\W¶~XǨúK ï>°ì†š¤m—„sRà÷ »€B*ã/mZÎJx!¹'‚<€ä4²”3€|…_:¥PûXBfµÉCèE™ˆ‘&ÝY1ßBöo³ B,¹ ¶Æ;þ€÷­2òiöÈ6L‹S–‰Yÿ0g¦Š¿Á– l—9eºéïšdÚÕKpch‚âcÕðË%–Œ ˆöZä®+û®áÐqLV%S:sM*Ï%#t93tX8OÿmÐ4XNÁâþ*ˆû ÕJË$£ŽáBÈBæ¶Ë•¤ +ì^¤Õ†ëŽÕu@'Ab—}Jh‘†—61O!®´ƒÔ¾@¦™fkÀZÀ ^æh°ª‘ˆ«ÍTò*×#Kg Ù(`u©Cªc°yzxÝaìòÚ|¦BÛ× g”Š…Ã¨s½¥û½ŒœËs’ÍðdÆâ긿üÁ.1°ç É‚û­å€}¨ðÜá̸/)óá Ns¡ádaËdlfÛȶ‘7_Øë˜$¯bŒÂ),§Ãñ°ƒÁu,JK²[ËoÆuv59#d"ƒ´!d¥Jø¥ÈÛv (ê÷)Cq$AÛâ*<kœ(D Ù=9Q¾„|ßt&<¿pÙ8v뻜v!o©U'¼Z•HOpzˆÞË^¹ˆz n‰ütØ“‰’Hc³ö¯àúÒ…ÆfMtÉ22=Š‚º. ØŸôù=€- ¯¥„ð‚¼xíå JüpЄÐQ˜­¤é@0Dnäþ#¹(&†y˜bæ0A¿†Þ¹ &Ú°AM×ӢŧOìßu`wq±‘Ë`7@Þ$ü›¨+…¤ QNdQ7þ¡& ï|Ò@STh8F£AxPâÇžSÖð¦+¡eÉÔŸUpcÜTg‰r‚ƒ#%é«Í*ý%°»ëZ*#2Q ;òŽDÍ§Ï çrd“Üj9…ZD°±¥Î¬`n.HTÙðçñΉX 'T›]X¦R9°k¬¸à£O¸Á¢ Äp[ÆèÚCo \Ø•÷-‚ÇLr;.ð \"¡b®“Å;Ç1½{3ì¹È7ê J졃dšj°á-!{S´V3)‘âäè˜ì Wâ¢)þ!ÙÝnã½aŽç œ xqÅàY¯%;ÈdLÖk#îÄ:,Áíðzï§a¢™¦Y‡P05¦ÃéQ¼]¼pt>ìYªõ†ZÿÒíDÐl•3:kf@б* äÖ(L¨âL‹#4cï³Þk\¤/+~ÃŽŒ±üåæJÙûlî×ZS/×'s‘½[h1 ´ƒuÌÖ.£«ëǘâ®;1u.þ0åQ)³'1÷¦ÒÚn“Ó —íw:‘ÀHìÞ˜}mQžüç#öÈaÝ¥ŠèÅaÊ®TDWòÖXÅ‚Ï „Ä9Ѩ6λ Ý*'ãüà¶€”È6#.BÁ¿©È«FFÆüv@½Þò\fµ‘UÁH²Pò+I+§œàƒ=}ÁðY‚Ø8àŽsqšGï{§Ñ $ï€øæce?]¡ºóž#Ÿ]×ö¶! À»®Î> ÔzûV%ÄWk'/œåèhä2'áRÁ+C~Ã[Û֠¨Ø…ÌÚ]#ì‚Å¥U''Ëè.«a\Ô7‚Æ'4ÌeI‹‚…í„ãªöÆ&_QŠ.åàŒÂRŽ ™šª?ªI1)N j¬…E Ë«|˜™JŒ —ãÔõ¼%‚…ŽÈÈŽ1KñK%Ø ’(Ȇ(!$†¥Lt•ÆüÕ8J§¶WËr7Õº]l/´áð¡åŒw¢0—0a 4÷d“â8At\ëc `rH©'±ƒ‰Á«­†³×,¬üDà†ö-8 ÒÖ‚vÐòA_*Šä> ½³w|?¬±ÎÎp EJìF CH#*9B—Ì06çü•ºÃ‚ ¤@?Òˆ¨ Ú&Q£îà‚‚Ê_ 8­÷f›ñ R»+:IÃÝR(Jä…,ËQrà¨Få!u«-9x¬UH]'€HvY«iãdØ'Qº2[©ºplÝŠuÑ• ‰£€.~VEzVôg9ÇøÑsºÕÚð•ႜ”î-¯=Qã&có$†ŒqbW` P5‰×%%iæ5âyQ±ž/Qð+_‚@Ý¿®„Ç>ô«ñhǹ¤NÑ P :Ù9þ•íÆXIsµ¢LdµÑîxD\áé:@Ô»ôܶF;ÔVÜhA#ìµ@®áþ|+€Î”ÔØ/ÆÒ RƒßÕlDæšvM¾ AÇ_J„œµã(âäÚÎÞa1ÓN¿óUdKYj´Ê]Øt.àFI_BˬœØ”±Ði§εEN¥gãºF߀ht@?ÕæH„äB7òëH[IÆÅBRå—–bL”t­êÈ{”`‰k(?Õ2È€´°8’Rš>X<&‹ñþsE'ÞQ<6f~cƒ`Æ @Ÿït@Ì"̘êÄÃű€È÷-]¦Kœïó? ΢Ê൸Nä;ø-`ØáDDmBš/‡³ÎÉiY&ó”o’º\쫎‹Íê6Ï0… °ägAá^ša bSCFRÀ±°úL=mÁÑÎÎL÷Þ›á^ݵو ox,•§Ù0à¡r5¶‘4Ð'leþæ@¯oŠÎÞ`TÅvbÆøŠ¢p|`c\ئéSº0)iG×ÀŠ£kqÈ#!O&£vl‡Î0ÚúR4ÝY¯YC8ohšˆî |½Bo®I¸°Úàlˆ‚n –ÓÔĦÙZ$Ù†TI»°Ÿø ®. œÁÀ‰‹K~S&æ’ònˆ”#è ÆÌ@Q–’'~Î?Îô[B)¨êÐÈœ¡ÕȓòfKÓÖyHÁ‹:ÂfwuÝÐSQ±« +\íêû—rw[š?©öÛÇùBeGd0‡Õ”¶Ü ¹¦"u:‹^üÖ‡#ËÀ´rk®»­;\©¨%Ûè¬ú^³9ÓŒ ‘]É:3Va®T…… ëÏGv™A åcpÓ²!ÌMz9òXjë²=æ.½ Y`š§r†*:nͨԫ Ú¬;©á06Òj[½º¦ðžšõ<ˆl‡Ð+4~‘[w¹8£wÛò›0ºœ†t'gN¨pð*+îÂGÍæ\Mέt² ÄÚÄ® è²:'0~u"³j á5Àö 8ë¢YJóâJFýwFíaò«±b¤—ˆTµ” …ûIÞeè¤`eY€ÕLvû‘ÆÑMÖ!Ý<¦¥T×)ˆU bJ”DóØIpÉ'À½‹LŽ åYÉNé|´ÀºÝI™¸"šÿS è¸ Ž^ƺ>ž1QOÞlgÞ˜ߊ½súq²²ñ8T{2ÍcìBì3žÕqH¾•É\H ˆy •IƒCu3”ãÌòæ%\§4ÊË\^ù ?ªjpt3Ù—ùXL½ÑjF';âžt ¸Ï Uó™õ·Ù@fSÑ1~GÕÌh1¥™1QÌt5ªf6Ër^Ðö–"g4ïŒa?7St΀Y·ÀÚ` À‹­^bNôÀd ’" AÉDT9j=%•T<‹”íI—©?ßÎ#%Š’_2º÷Ó]²‚ˆã9I+q„J8'Ñ¿ò»ŸééÞî_ŸÔ处:âœÈA5M$Dgpt±:õ¼Ñ‘<ËxÌ#…‰`6hG…)\+²­€ÌûFÀßÐA…94”ÉìTU‘^ˆLaÝZ>y} Mªv¥Ò×}ÓI `dAÿ³MwA{Õq.PñŒæá~&¨Pþ›UFfÃÁ0LËÖ >»Mã+£ÝY7Ô'j‹×¥ãµjcyŠéö ‡uBéFÓ8 ù±0ŠPÊû5Ë fé´›xÇÁé¥Jз´RØe*‹]¢àÀ5 ñJËMÎ ä­ƒ»h©`Ó|—ï¿Ã¿r±<ÚY•¼ Šk‘W¸³T­¿­Ô×áĸÅÚho,¦V3Þ½ÊN®ÀÁvPBÚ‘y0ˆ3ù{:á±ÍÉ^Ã2Qy^:µU9kãè妱S3kìb¬•®ï×ÎÙdìž©´5Z.s[ΙƒÞŠ8YISnTŒh F0ºŠŽj¢D\$rœÆ)/|E0 ¦g°–Û c=ˆ2qÖRÔÅ0UÔq‰GÖw#1K»”‡Hµ/(‡õ@_n´ó¡çÌ‘MÔ&ßäÙxvvö”VAVãXÿ6:Çä›Ê50pÒþäèñöñ¦àñøx ŠÃ£|jìb¤³:6•F]ξN?‚WaS¹,‚‡Þ $VŸ‘͵å;„qÍ% ÅgÄœ±@…´˜âù]Ä÷›€7DwAà†¥ã’´•Fd§è ȰTIÌ…¨B,‘²$IÞ v'˜ÎZuH¨­ئ.¾‹°WI ½)t[YsÛ–Ô{éÄþ ë;„ç&jClF4¤T¼2ãÅnCäwFgyݬH@:‚ËÄÜuþ"C-­ÈÄU`¤Ô ¾‚zs›àTž9ÚÌÎÎ’èS‹¿Râ'Sèã“@psM‘LÊhO–н—CÔÕ©`V„“À®AïšÅ !bFAsY:s‰E<É¢öR“D-É| ÒWIÆŸ±<8ÞêáB:É`´+0Ëtó±ä›)?L„e*§KÀ„c £îDíbíóxÊï*ý«{À¢ùâ¹lÞ±¦UÄ]È¿¨æWùÄPòF†cciw^ô íT—Sîï[xÕ1ÔØÙL\1”k§«Ü$cÚ&oÒ¬ÔE0Ñ“É0+|N¸.ÌBb²ÿïLú§x¬Ž¾enÄOéƒm|‚±ˆœ5¬T¿åµ¢ðÃAa»Á‚‘“ nˆšº7¤#ª·ÝwØÊ ­v;UÊB ‡h—jšß¢‹Rg0„O}G’B@îÃIÅ ¿'.I?tÙ6¯<çd]Ó8……¨½Úd܉J©„Säk2o‚·ö 6qi¸¼mÛ–ry¬„ÀÈQ[A[3 ³^{ÅóZE*øKqÕSñÓoÐ5Çæ$DŒ $×÷-Á¡E(ß˺XJðEG³µx0{Hh*Zmp%½â%êTÕ_*†³Y1Ë—v‡0ÀXWpJ¦ÁrÖ›>¸LŠåá=AIK§‘eI Ó‰1¡‚ê-r1çKrQ²Ç]’Ã..´›äb„«]Òþu!Ýæ4“އ¯F¦Ô`²§±¨æ.k!6lñ¸¢Ši,;©¢›HF@‹ór¹ 3@@ѲÑVmÎþ¥è?NzDí9ýƒ^¸ñÆT"ž‰Iq\õUÖFGéXŒèYP=‚ã$x,h- J’¡½þ’‘”÷y¼‡*Í´ “’]µ±…p~d ,¹¿MQ"Ùâ3òêY¢u±°+tL »\fQþ݊ݤ˜H… ¡ô‚нÙVü—L)W±÷ªÁ‘r9g—FøAŒÔŽ}^Ä9þŽ¢ìü =ÆnZÀ­ñÊ„©b"2òJǘqœ1v s„¨ßÐfƒ´áã(x2¨”›zèê$Ò§J²Â«Ã>ïÚ‹]oÖ@bÛ‰ù@ Z„ÚÀH Ô¨a"vΨ`¤vIyÛcÛª™Ç¬‰±¦fÌy­U§wŒéôq œG±Hé߬'gd)Å/ZMêˆ=9µyÁŸ:8µûàTuêŠÃ»‰?KK=Ðײ”‡»­Ò—q?œ –#1äĉŒ—䢹KˆÈ+Ax42õaÓ²’T§ÁÙ0Ž6W[»¼å’ËUp ΠIeúI½ÒH”¬EÐ'Ùr‘p{:!%›¤_'h¹ÏG´P—åí61BRÔÏnùé:§¸Qdœ·áÏ\Ïu> ¨?Ðè”鄉×? %Ç&YÑúâ€ظ»X¿*G^Ñè*ÏmÕmU‘æW‘ˆTƒ9õIf=Ôؘ|¢ÍS½ÀxY³#¸—陼ӛÈ÷3¿¡GÀO«³«Ú{_ôµ+¬Ût:ï$»œ&ï¤ò,‚ï³¹õן¦KýTîóŸù«ü~ÜâûX‚Í[œ$nn±9Ð20dŠzI¸™K’bלù0è,éìuv¤\tU±Ž*È· c‚‚U¥*TÉ›î*¸²Ÿ’Ê|3˜­˜¯‡»3;š¸œ¬°0 É*õôœíÎ.?$Ee\à’5CÙÜ #dÀŽfdåóMY5rÖHý9¦ì^k¹ØÐ 4voìò–3¡U‡À7‹]í´ nÄ ÈÁ9ççdÍ«õåÀÐRZ“þ†fÌÑ N[}{¼{0¹—" ×ί~”2`ª&sr['.²"O™ÍÏVLY\¨|N/…C£ˆ€Ùµ"»×Vý¹*á‚%˜#ÔœN‚¶ùk››F¶ŽlëKÍe x!`•raŸŒBÓŸ-È}º ‰ pô¥º4ºióÖ­›¶näÿ’º¡ÙŒ8²ÓÍðþÄŽbG§ôÚ¡²•g-ÿAƒÓ±õ;´•Ñ:ê[‡¬*(Yß³™*™/»*/@Ô-烇ê8Æá€‘UK kì“8`hR|øÐÐAoîV¿>;?Ãúªs€HOÐ¾Ž„ ž”Üyè‘(ü»¤5|‘û6ÉÈ‘OÆò¦âp¹X–»OùeLË6ªáÒbT*PUmëêK©Iýö˜ßZô[Mw6*Ù¥±"œ‘ý¥[Ìü­«G4/4’&½J­9òÜÖbpŽbYTW;=ytµéÏ/Sº²²RŒøiÑJ9j+J4›á—¢¸ü³“Ï1ÝÐWÏl‹p|rÔ5ÁIMúó-·i÷MPÅCËÜ9õ [íÃÄEJvá]”=´Z,ÍS\d½·¼FIÑÞ‚Þcxš6Ò*œsqx:mŽÒÛC´ˆÏ(%B$y V#î_ü]—ß!AjƒÁ2ötB±§|(}púÐ.’Q#ò!cÏ ž¬r"·†Õ;`ÀŽ¢âš"šú‰}^:µïàž™Aóà¦Ò=¼ß¯{BäËdì›’?È»ßÎÝ'w#ÕÐȪ8Ü¥Õ0ÝùOg°žu~¹ þgÌ9 nG×k:6=ñ6Ïqömtwóâ¯z1³áô¿õÿ›Ø½÷ø$-àƒÕ†XÄòæÑÑ eúÿïØ–áò†áMåM£[6މrÛ†7mpÊÅtà`Š®¬,x^³G¹µÞÇ÷³²þ„Ä+¯žÌvûŸ4q†˜0EGÑ:aS>b€6*`P7@áõXSÑ™àŸ†:ç61$WqÈ{­¨ ¦w Œw '$Ä£Rp¯³à 6¶¹ª…i¨>“™è/‚dÉêsÈE™5¸zé Â9~‚Íl¢‰…k63¡{ÔcÙT×w:è±(LXVDª¨é©Ð]¤xç>}´ñQ¡î#‡šc_tš—1eìAL»è…¥ÀÅø%àÝ$ì5AU³?„ë #¤›úBºËI¬5é@%–qž‹íâ&@uÑ9Œü-8ËÛÇÙ»{|1øŽBé¸ÛÒƒ¼NËin'Àujü ´KLœ„°?y‡:[q²ñ®f¥^¾j÷.ŽÜÉSz›UgëÐGüJHß3ƒiOs(8v}ÈL:­Îâ,$‚žÎ´eI”ÛV º$VÜãÙÈxóæÉmЛ/ò&uj$\uTŽ÷¥SZ%e ¨¤tM$)QjôéfŒI‹ˆ€twNº™HJ Hw7£Æ€Õ÷s~¿sÞÿïÜwÏ{÷ÝîöÆ{O6áöë] :ï­~Ž„yþSmw ëŸÏÚL8âB»$Pï}ÜC¼kéÿ&[{Ei €%²+Xé=½s™þ’.ÚÒ®}”ÃÑü¬Š/ NQ`‹T †¦îþþò ¾,Û…IéôûwìÔ?Rk´£)²æDkÄ' 9“ Ÿdom×ò ɺQ?§©æÔ³åá¸û©€>µëUQ7é¸êö@µÂ ‡­þƒÙ 5M½Ÿ¸Ðp1oçë&ÿ“À0ÿ âñ{$'G†Hå¡L.Ùý)šS¢dRÉ BêoÎÌyçI¦ŸO~}*;Áàü°ø]Ï' ͽF‰5Óoÿài€ÓŒëDq…pµµG&Ò¤ ×7ÄÙ¦é½Fòåœ(ï"Ê ã"ÕÀkbUvÌÔnFº‡D?^Û«Dx|~6$'f‚.×Õ8¹×ѰÔ›Š¶á- dƒC£9>mi¥ ùs·ìØ[õÈ¢“æ¶šû©¯·=TÉŒYŒóu,þ=N詊OʤB“Gûã{uii€”=Uc²÷‹6'×$ÄŒ{ÔhKøýŠTMJ=U0m‚¹¤Âé‰ã¡ Çe?åJòfå¾Ú¬ÁŒ3O)Ñš©Þ ÉEDjœcOâ?§Š¸ˆb8½³†ýôtN|UNk¡¤ŽVÇ,ŽÙ P®Y‰çДvR彪ȵ#¨ þf8±¸0¸cšF>ìäÛ±š²o\é¤tõ¬ÿ@0㈌’d£úÏ«çá±*!)S¸í½ò?þfËé¥~›Fù¸,$y$©~@¶Ѝä.2õu¢œ ˜®|ä;PnǸ(ý§t½QœÍ8Vñ¸³¡ýÁíû&‰)_ÖÔVZ¨ŠÌ|Ý\ ‚èÀm‚Ò°ÿý+übƒÓÔ{s|ølé6"z-wìb Ùød(ñó]rñ Q}u}Q]ä1õâ ÝTÆPäÓ¥Þ¨ØgvÆ‹n>’Cl­äÐbîO=ˆ¹èkåLk™älbÕ«_ø,æ„ •w¡çd]4°Ðt<í»7/M_ð×öççO¾½·Q¯*1æ˜ ßö5Š\3Ó/xà§èLµfõ¤q ‘~/ôòx;‘É3éº~0Ï|ÚÏ£Ûª˜[’ôïa¦ ‰Õ›ï Ïß× ü½¸}!ÂŒ—г`n°™ai+$¦÷L†6¬î»¹‹õ€½-@ÞªÌb÷ƒûbK$ÞÅÔÛöÝä B9Ú\¤½¼ªë8üz´Ðü©º"ÜaÚŃ|>ÃÌwh>>k‰;û½²ÙŒösÈNÞÞÜØ`³W³^ qÖ´&-/g÷6EE Û‡j÷a÷G¾ÿéËq§Ín˜%•Þ(ý*wÈ¢ÆãeB=‚¾¾X v>ÔM8£ÃJk÷X­>;Bp´£èÁy×½cÂZå]â Síç$Êûåø‡ø0“ Ë‚’ÁæÔNŠ`0Þ{]“[„‡y6(fý%¸³Ë”øüƒo £ñU Æ‘‹fÒœiÆH3~šBŸ4~Ù°=R²ž÷&á3—ðÄŸ»ËyêCö3»b;Œ=\6´¬¡ ,46jù€­ +7-5¬'ÄnÓ§úq¸Ü€®}¢º ™ô‡4ê'Fd˜;øù ™‰”*ïK.Š/ß·$‡òþ²¾Ûq¢­d‘ÿÖ­,fz›Y©Väµ ÕÉåœnï#A?É"å£OðSf&ÏPÌë µVÔ0Íìü}tÞ½ñ´V.à ¾â¤Ãϧ©åÊ&áó(IèÅŽp¤%”ûø‡·+…˳èßlo&*Ü ¾¾™<Þ ¢÷d$ÂÿÚz’[>©äì±ðßXx`å§ÛDýâœXdXø]ò´Å— ÝgP¯ï†Œ—]yo“I~NÌŒ>Ô¦’ôÿzõ­*{à œŽý%goö)¥XEœÏ»áˆl>“÷R‚4`búc{}2ÍÇÖTo-zþ‚lXæ¯ÆêHi­Ì&f/EXþ~ëÈO)÷e3(Yàb\W¯=T.né>r¬”o!%aocž e34[ÿ#V”ê_z$CŸ‡*¯%{ÜBÖi‘.a^«î³.éˆ2»`fÔœ¸r&Ž/°r¢£™æ'{XÑÀ;Nw˜7ú8œº¿$ƒÑ:T%rWÉ”Ûð†ô£–Õu3‡çDrGÁ¢5«oYÂËž¿ä0×’ÉÎRñˆ›˳ùÊLÛ)WŽ"‘‡œm&_ßWFyðÙݰ ‹KQÅ…7‹^+k«ÒE¼ñ~bck´KDÿL”BRë 1 c"J–³9wܶæWÞ|Þ-K{¥Œá_Eô.Â>¹_Ÿ¿þÕy¯C%8®ZÐM†ˆ'õI`øxÒEýÎÇ×)Ý}.þ7ýS2ôb ûFZž uõÂÔ¯TõO<á‰ò! /> õA=Uܶ¦ ”ïÉÕxlTCÂ×$¤:{—=mÍiÍ#³¦$™PQ&¥œ}c-œ¹®?mµ …¼gÔéÒ´Z Y´‘ŸÙ’‚žße->"ŸÈ{/7gžùz¦±U:n«maöe›­üÝ ÂaïWD™™‡ŸÚ,ŠL›7kúMëרZßib­gq}–Ý?¶„zh’ ²‚U¼3’·žÃ–<îšé&Óâ‘G‚ß2³H}y8¦Iw>¦-îúøø( }™’s­Vs{C_ò:(ï‰y`šë: £Ú>…Ó Ma>¦üuUÌ/Ž6ó×°Ý©Qa>æœð&_x¸©Q/–Pè=OÅÁî·ìZ_Ü©Vµpöß/q|9«›h&¼<5˜v‚²p+t±p³KÕoµÃΤD<š²GßÿØJ!ñþÈ,Ìæ¥D¦6uñÓÚw{½zgBåioš¦Ê‰ç£ññ÷¹wÌ„™œ÷¯zì#>–…L¼¾N'<”>W˜3ö¼x­a[1p»4¿ÅnÆ0W40‘íüQº¬ß€¥É¶ììÙFQÄG‡ANl2 7\t]_a…MàL%`àÎÔ«s¿àðÕ}í.¦Ø°‹¯'_Ô䳑&]•"¹‹õ£Ùsõ'.ƒw’Œ/äËúø¾>Ф£µîR Mý?ý¼gÓV>OÔWh©+x)T˯gÿé=¦y¯©UÉq?¯/µy7R]¼ð%°5eн³û^A-•7ÀÊä™ßû¾TžÄ ¢¡³.ïÉ·ù¼í¾÷íMôíñÇÙ·Ò½Ô|ôÊЦ@ÉÒzÒðõ<üû£·Ÿ1ª.üŠÉšY’XnæÜCùT_î‹ÂEIkät>÷OŽ=þ«Ç£úÚÏ–Õn±·œVào MlCg?Í<ÏIØ®MXÅr¹èmyÄÕÅ}²rÂxgHP¸GFdJ·’Ê·¶Ér~’—ÕQ˜¥ˆw|?z–¼¥Mæè2e‘åÚÂõ¥,æ0ƒÅÕg¹Üꜟ͢OˆÈúa-õ_½J€dÑF–ÃcÚ! ªì¯ënl†5/©vŒê”°lÄãµ6žŒû82ßK{YLk:óÿî°Á±àïxë3N3ŸÎ–¢ÚP•ÓÁÍ&Àgø¶…úì%ý‡»ggƒŽP@,Ãç{ë{Â|vïú<ãb1\,êBÆ4ñÍĤ³DŸ¢Šéœ¶’íEs 5Û¼½|$Â-ÓN'?»¯Oznæ×‘þtoîø”ˆŽ³’ÿ&–æñ^,#G“¦ÄÆxJ;•ïÿ.LìOd¼èÍÕâ%c[3ão€â*Žn—ä¡¡ï?7džRâ;P5½óµ;l›óÔïX°pq°—Üc‹N*¬kø=4ýB3ã™þæÍKµ»š÷i:Tçû™Æ_ëB_ã C^r) Bt”²Ù¡«]k6*™"ΑyùM}5µ?&š§Œ¯&>üË7®¶LdúvOÖ† f¡ô´;,A Ï—t¥>+F§:mçÎTÔzÝ/YŒ€éjöÔ%Ç6ÅMȧÞÛ¾· 1Š%F¦ç°4»"u‡zŸ¬‰GµÆW¯•ÍVü¾`'—¶P³lTq2:à•:äù†Ÿ°,nM[œñÇ7ÅU϶I,0¬Ö¹x!xT††tÉÉh)©`¯ø9I‚]C´DKµèôP÷Œ©¾ºg›Sú^Î)Ï4ß»º)Ýñ§Á|t2Ó#¾ÍÏëö‡Q"Mö>ÐÙ„ë¼]T’—ŸlõJÝ[Ÿ)㿜f¦—£ öÆ÷È@Nµ¬þr°>ÒýmÔËF^¢Ò!í V}˜w¨c``V}ÃYÖ˜»­ÓàhóDãÔ{^ŠMÊþ¹ÔD: øÑÝÊX¿Æ9~ÏØ“ÂÚ8>H+åûWzD¬)MU¬2é‰4©æìõ•‹¸V:}ÏΫZ÷zÅ.™U‡ë•µO_ÓözÒSx(gXàNÈcoûµáY¦â3ònÐ,Ó~þ= [Ù'ßÁâDBç|c¶:üy*>…‹®H^Õ1]Öx=ûÓgÔvÛñœó×ký£ÏúÂ਑†ïÿ =Ì¥Ëï=P¨Ÿ>ûóÆGþ·#_X/lM*gÌN;ú¢³¥yéGÝ–€MÚºð©&ߪg+‡’ëLX]~Òð.€!ß[2&]À”íËM™(ó®(ÊØ4ºlÝ| Jígäç«6N½Y<"ça\Þµk¯Ùïþì¸ÿ6‹Â¥v>®A¬Á³o5V›™†ç\…yg]Ò¡Åöc™£”Ý §PëÆÑºÝ÷bιÅu‰…¿ópp7|Î_»«&@›E?þ*7§U×ðÛ¼C/SÑJ€—Šz^K­Ñ¡‚ÁâëYÈ›8þšò´ºû5¼ªÏ m÷MŽÚÕ¹âì‡æˆ›³ŒŠGkèßšŠí½ˆ¨ ¬›÷Õ–&©•ò |ïüãÈxXL†<êáùþ']jf{ÚN©ì¿~ŽþáöÛõýl:9úU.ÿÈzòÇýhpI}{‚p¨¿i˾ÀÄg1|Û¼vªÆ%zXÙb”¶–‘£uÿšx¯ÆŽìuS5»;ÛûÆ~󽜒:1Ó74€$]qâñ=swYêýÜ3ä £YÜŽÁæ,ÂO.[Þ½ÕµŠûˆ;h0b–j ¢ýø}PABTn±”Ž›»áµÇ“±¦r1øàƒá‰xâ=ãÐì8ù7!ÆB¦û$Æ Aj~ôßù-^èÝÕèüú}_úî[ ÞK%Ðò5GäõZç”Ü…yñ{ë?ëqBÓªvSò=‰oZïâõ–îÛÐÕ“•eÓ¶>¾y­±.õnShæ¾ï?©Û‡ÓÏ•üD',îć†NyúsökŒ ¯éù’Eù'ÏÿUïcˆØË2nœrÔ =µþ?вa²©VøPV½àÒTF†:RÑE‰uŒƒöO‹TcV\,gâDéï(ñ7I⿆´Üõx¾ò|h–”s³}³N£÷î‘¡ÍãXñ_‘æEšÉr!b6a3ͯØ~ûƒ—Ö}ÜÄ$7¼é6Ö§ö©û\êü  gBYÒƒ¿íT-O-UïØ¥#¼šøB}kíŽæ9k"6Ǻ?•QF(Ü­pÿ­£^qÊÈòømûÞE1¼¨´‚äŽåGÓà4í^vËHšxñ¤YÓ^Uíh;³ê‚•*…Ù‰Šþ‚9e}’U3õž¬ÑZ=vá7‘“ˆ™äŘjÙßÙ~»}^1@ôe<‹Ú’Ü!Q~'Ââ]–åYÊÀ gRÁ—$WÄö‚ÂÖÐ9µè‰¥3È1¯Ï”f…÷í—ÁªÞvÞŠ/K¹‡™vm¿Jü ;’<¾ó+ãÎ^<ýg5¡°EÓo±Èm‰zßÃ&ß ý.w‹ÔË»Ruñ†ž·ö rm#ùSQŽÇCßÞ ~Ñý1ÛcøyRNK†²Éñ Ü´KCRxW7u.ËûÎâ¤ã7SN–$M8=c}¤†î~„Ýî2ñ‚ÎÀNüãQ*×>ji!®%ÎÈ€÷ü`wæÃdq”…ˆ/ðuKÀ;…ˆY¾¿c…è{´¥9çíúK†ÿ¼ú¶%ô8ç‰UžÖµë(;³€­£†²àFâ³(;*µÏ6öÆþba —¨³)9D,ô“zÛ·•:fã{Ïœt‡òöTS„rAû?ɪ¢Ï%^Á‡t¶@Cé©FCævÅó_]TB'vØ*ü»/*­³$N®‰Úõ¯f8:P§½•v“ëá3m×óÅÉäIäxJKmÊ÷¸xàB›{¥v oª4ïö÷ϨßU½ila8â1 ~ûc¾QͰF@d‹HnlÊ’?uø·9þúq¢T bÁOŸsÅã0³d| ¾"Á÷±¤#!Åkðî‚yÊ}!ê¿®¿7–ioFÔ»EÄ·»ì³NlÆ[z3¯­øä_4¸Z”:šÄªŒÐQ+Åz°ŸFól®¸ü'‹›séyÃø¸¡\ â“)SÏcÛ,.o0œSønèMòŠD‘Ú‡íðÇ;´…ý½’\ÈÍ¢+9„¡Ã¾ ƒã?oPÅj¹è¥îb[ ’‚ëáê‰ÍPŒã¼äóIö¢88QRåÈ×Úµo¤ÒÝŸ4k)#u½f‹r[¶ßõ9Á=½\¿T‹5È?œù],ÓKG¿?'ÊéViZåêv> ¸ v³LpÐN¶$—ÌFŽÀú“Ë#Nž?Â4ºEË(F·lN·¸<“ˆ£> žX<\í®¦šß§ÜLÿÓÛÃ%p,½ä!îH‹ùK¢Ä»‰—Ä‚hÂÉŸhŸÏð¨¨R×?üF:`Å%Û %ÚdZw|8ÃKlzï}ˆŸ@ÞôÇœN®…HãFžÿ¼Ûõ:„‰Ð¨¥Vä$ò.")âýCé@ò$"f ¹y¯WZeéÊ+N¢:¡P= Ù×ʘ©QïL:I’µã™²$óDæN5ªzâ] à?M®+ë{¨“©!¬‚)÷}ÖõbáŸÂù°FJe‰ZâÐÇtå½:–!üdÏÛÙº“°aZ±¿ÙNôÜŒ»µút'­…©<ÈjQƒƒé'à‚î{9\«S&ôsjúOí®?;|ÒWàpž§ÛÏn;Í«RèTà}$U—ë[IxX!ò2£²4–\‘ø³\Ijj9üË’&ƒøªomâ—cDwÈ H‚÷È•œO¡ [™Æ[%óli‘jÍÛ´òšßh¤É°Q¹eIúˆá[93¾°¿Tʾ+ùºSŸErWuãæ¡å#Ž8ž‰ ï 2A§6Ö´šJÏq?ø\Gç}"Ë'wDY(~ëÐñ5Y%îJœgx—×§­ú®ŒI4º%žúüð'‡ÖûÊDçäã=Ð(1ž„¡LEs4 I»=gqkàŸ–-ô„ŽuúPµE[m«¶yçÝ^ÇŸʬB~)°á¦SÂå·gˆé‚ðÂAÛî!R„•až Ó}uy# ¨Xxa˜â“g4z¢ªX$rõòH¾2ý[åËÎ/×wúµë–&ήäÛEÕ÷¿o©Ú¨€Åv%ÆxÇîk¥t8ƒ÷=ޏçXé컳Ôÿ¶D¥ mM*ޝÓ{Ù¹ª½fK‰·|~hŒÂù}ø“j'ÕzT^Yö¿×—¸9ÒP6ô¨´¡sqºOùË<:ð üt„¶1=±S9iŒ73þ˜ks+ö=ü½:º]-†Üîtq› Δ.—òc.Gè,Hñ.¡åAOEIíoæÚ´” N ‡±Þº.pLFª+¼=Û¶x¾+ݘ|ðɇAàWÐí~ÍñêeÏ&ÆëPÌ3³ŽÅ\OF|d„Íÿ^Ü­_^RjÇ»›éo›où®6«Þ…–õ®äxì¡ÕÞPéÌ9¿Ì.`*ê1€Åš‡­Ñ@9§Ï:èÃî¿ãtË÷À»23§›f þa«ów‰èA¹AsnÎs–WXJMõ Y²%ÁãoR/¥Æ’@3‹ dþÝÑúwF4u!‘{u¯9óÜ“ëÚbLª©M>¼sˆ/CçÁð>sUì '«Jµ%‹žÖÔ6ô+ÏêóÇ÷»ÀfŸ—MµI¡4Þ­]Ðõ¹¨ð½6`]Ñåò)0KNÁ—éŠWêbÒ4ÙXLŽœC•_j£ÔJ\s"ÚL=¸yû©'3}CþŃŒ åÙ« :ô=cÞ÷U_ ¡- KÑ•î[ËP‡“³(<ш'/Š”`ÉçS}‹d’SQßfd±â‡ë‚ÿÕÆ[ÊûÉ¥l+¢“_},y:p®kïKq”O#ŲjT#ÝãtÇÊwïáãKÔ‚Ÿ`¸¢Àá~ÄÇUÇN/ß%W+—@(S¹DðÓ¦‚Õ‡xäÔÚë>–§Ý­/ÔÔÛsÞf?]r-uük&ÑÔúÒ3‚¨eÉùz8„T¢¿nÒ|éì³<ù;¾:ÎÉoL#ŒúdOØVî*¼Ð¥›ìa|LÎùMÐwƒW©¥ZÉ## ¾Þþ&Hߨ2»vuAÌp7Xã‘ca¶ý½Àž/E¨Ïé&=ïSzH³P*œO_ÍæS~úL K¿àÇÉÜ îxN£9Þ¸Ê|ù¬+ήý·LÎ…ô,o‹TۤǧÏ&C{˜¯xÝÔrx§eá3Ï2>ÙèíæŽP#ù›ò½HåG‹M5Èä‹ S:ß RV~ì¸R›Šx½ø1ýØ"J<}XQS|}ûrzpƒ2çmžH÷CJD¯Å,Ø"HfOyóôêÜ·žjHEld´9ÌýÕ·>s#É£µ)ÕèTä¢põªÖþáñs_*(C&ÔZH‘Ìå>«¸æf™éˆiß?¨‘gN“„ÆSä«ÃnÔÎ _!¯ÒâÂpxÝÝs£EY4õ×܇`ñ䮉ñ09®ÒyïÞ`Ï']ky}£¿w¿–äv~û˜mùYÏ/.;Àñ^Ó©V¼ÉA= ÇZ½÷"jö‰U•ž<…öϲ²ú—ïë†v~]IűQ+)»‘?*Ô¡‡?O? á)Ž õ…Û¦ñµ|jÜ\¯ºË˜ "#§£‚OÆ9ä:Fç˜0hÉ„Õp—Š¥Ó;ëwìÑÏ NìgiÕ:h*î(Alsbc&%[\5ù\µÊ|®*3=_*±*=z0à˜ü¢òU%̉õY‰¬ÑÝî@n~Žn*z,TÄ’÷ˆýÿ"m’ÏèRÖŸéWÙݶ ò0½ô~Lê€9Z!¶Ä5ùÈ=wNÜcJ š˜£¾hfÏÑ=fÚ?—ÛExv®7_?º¯²ý:1m'Nº˜§'aô›~¯·} ö8 i̾JmyÓ Êû–®§yÂûôñ2KÓ‹w†ØZ’x›„-Ý®›¯ž¼=ÄꇜÏÑœ‹b±/hÛˆµC?겄u j~¼ØNLü¶øð`äü‡Žçåñ䟎©ãM_av…µ¯5v"Zðõ^ë,ôP‹gß­ÙhÒ³³m~J§2Ç!žOÿâiœÔ5 ·ßôGÔBÄ‹~¨¼˜WÕJW¢  ¾ô½úDáÔÝ•¸ö¸â¹ÔÁÛÑ6Ó:UbÍÇeÌ‘Ùjã÷:ðŸËÁâ"àÛò$iÚvOCE“-^;½°~©±d¸(~7,æ:’‘eï'émüt4÷n¤’v\¸ÔO†¥®ƒ¶H£%jÒRYÏ@®€ñù¤iAªé ŸÖÇîö"u#¾ÙìΖæÈBcg €´!¢1A½Æ“%f‡´­ö›‹”'žÔ!bÿ¼±‰iÒÕÉ{öÝ@zJ`¿.òið»ó‡qš5zå/yŒy1'ZV üLø‰îöP Ò 9u~âATÐÌõ3_¬7Ð mDÿ »V²ó&èË>©Êo—=÷ÈÈNá¬Z'6ÇÿÁ ,gRœ§ =g˜Ä¹ßí‘:¢ ñÕñ3sðw– ~û÷¶•ê%t Ù[:Ð{g÷‘L^þ†ìq·FŠ[ÁÅç†Â¿ÇÍ$Â5ž=êù-ˆº{oÕ¯l\qýr°êY„i¤{ûÈï¨Y–4-ùÝò‡¿ÔåÂvÞ*Ev—‹¯§4âþþ¦O?s•´Ö!¶&CñdLLã9éO,éd©õ ÷{g×6¬òûÜ”Iáwd7Fk~q~bíùÓ"Î[¡ â%©â)4'7Ž=¨YU؂Ȋ3ôF¥6ï´•îÍÉÛœÞ+°ý9zﮈPâÆÛšˆÏ¯çɈà6a}9/DÂmþ°ùúŠoû ñ¿\( 2õ:åqv:}–v˜ù©¡˜4B€ÓzÔ9öݼwE\¸[‰Ú(q±ªÔßã—"|ÏF*©îÅ-¿Ìà;¢T,AXq¾ŠàÍæ9 ¬:ÞÛIôuú¤z³D@ÖGUßþ.àäVs̾oƒ{•M¨î|–C€|¼öÁ7Gﬢ«ÆäÏ*mJï _{»™úد5·m‰þþ÷Ññï%¸¾5K×°¿5Ó/ÛØŒ-\$]wº|èX²!r“Þ2Ùù*~òÞëØýÍHׂ {Ÿч¯¶Â ¬«z“Øõ)˜›˜&äºõQשÝ뻨È ŸgŽ@XO™Š$±‹°vw©«ß-˜9¿$ú¹e<Û ±Ùô$l‘™‚£Õ¥=ÇZi·¯cm°—ûd€XÂ]ˆÿ÷Èdí”PÞ/MûD˜x¥ nWè¿ îƒ/ó;Ö›ùW¾øèa³¦Þ1ÂÎzâÄÔ.!ÿº91ícDY“CKI~¶k°uÀæô??=Ÿ=EšÏ#g_ä3a*é¥sî®áY{;)ZVo¾Ô@§’18üT¿V38ú9Lj\G’ÖŸ2\Z¹®áj *øü8&ý(¶¬}ýûlä>'ä”6Úm„íkäê-u…þ;ÿîç‘àÈ z‰™__züC×ø¼Â˜YeZ¥Ñ›ìyÆpW¾&—+|O]v­X¹B¡±Å##[¶xÖ¼GV÷N jsåÕ˜‹‚IãÐ+¤ºøÙ"Bí‘)㪜M8§à“öý¡W¶B’¼Lꛨ%HÍǃ/ô¦ Œ•ïµÿ’º ²F« :|)‘ƒšau&avc¥Ó†[„“¤.ax[¸tŸ0Îxa(ЮI•سXwûNðñú¹Ñã±S§õµÛU½G8.æ/ÁKN“­7EÈýp |rý{´Ô ëÄ»]gÃ0åù„RØ~ ˜ÒT^»$Àûw%q@²ô;(Hñ©E ÆÏÍ•L]ÀqøöüÙÁF;åt?܆H¶ü¯pÈIØû^øLø¿~ŽKÿ‚ûBÝ$¦gÇô³?ŸßÜï´Õv« mu¥\ß +­èÓO@0+Qó"̪Œ‹—E‘²Å²é³È ü=~b£HFX¬1§XóÁÊ08¢{·º^QÖþ2˜r eýTBQ¨e¿1I ÿe@Àæ)55OíFeŒE¾Ï ŽYñŒ¬ç‰ î/;Z‡ôxw»§ÅŠÅr[íxGcNEKÖU³Õ^þ1Ù~1ðÀëÒû±ª˜þ7‹˜Ð<×Îùyæ^²r-ÄëKÝÃÀ eyQ>/K2ÃS­ò—’‡,;Ÿimʆƒ÷Z]‡N§Tü_×4íÏ*i°vã~ºÓ¿í%“æ0~mSi@cî9[팬¹èë™}…žŒMu˜pmtt¾lìœI pÒ7RC†¹=`Vw[1ítj‚^ ȼ›—¸Ÿ‰ÕLïX‚’¼äëØV?õ;ú2ϰ˜­á[Þñ.pIðÀZˆ†k&Ú)  ŽŽÒz5Ÿ¾¡?nVqë=æ9¦ñf—ßA”dµËØÿø ‰­¾ñ=Ï÷’ËxŸõtjÍ·¬w½L |‹3Ð#@‘„âløÜk$Ö¢X'çI`p—¯&@4ðk§ÝJ CŠìcg…WÇËRµÖ==ñŸ ÀsÖ^½;–íÞäpÒ£ðv%Ÿ[¡rP¯´°(6×Mv]çNÓb íý¥ñË(”ÉhD3~sSùG§+Êö)¡Pà(›> œ[ê¡¿9 „/xOõ¿‚]FaSQÍø¥aî€ñ{0Ⱦ—kྯèz°t¶èÞ‰>‚Î@8Ïë~x X:,1;Dø(ÐYàØ=a~ $¤|Ìš».gô–¯j€íÛ§±ÒÁ»„ƒªú.t‡W8 8¦´ßîø¶s }0$œ2‰³°˜jQ9Œ…{§Ëù£ULöÀR ôÏ›ÕåËRàÎ9Â} ÷ös8z¼XUßoo]”€ƒ?öx׌ˬlDŽö̙ܣG¸ôxûA!{®0Hÿ@ÇþÒáøüšâæ£EÂÑ@×! ëWè^bþg÷|gàyv#t\þ¥ st+ÚE8ÆkÃNFÆ?ïf/ŽÝb)ÇF²Þ›õ€¦u:wÂ¥Tãa.†yãs¹µ(2wzu³©0†Åñ× ÛÁNàõJµ âè«ÂŠ>~]vöDa¥Ü/Q 4ì”(bc‚µ£Í ÝýTõxb4WÞ¶g²يܜͺΤEâ¢kÜ1]þX=ÛžuØ^œŠB®D3‚ç¢p&æ§“\rç?è8¹ÏFÔwd>ØßˆÛÜ  †¾§»ïrpÝ,«„^$äö¢ë&E?ß^GÀí O!q @Ü 8Öóö³{÷jõº¤{‹;ê[mZΧ…¬Dƒ h¾JØùÍl6Ð Pô_M@Ü.±l&-,C€>{@½|R!èì%Tû㺱¨¾ç"íJYñ9Ø+t¼9C ã±z/º‚†ßnu²b'`ØBÌ d ÂëáVàzå—‹© N0â¬|ך<¶9‡=‡pm‹æFàÞÿ ^Öâ¹Þ;oA7ùŸÓ!å8 ì…º k¼ŒbøqYYàQÍÀz6Ü-{ €vnhuùüD‰6ºjá9k‚ß½‡xºÝV6~O0<Üž]òœ¸®ñÞ;èÄD¹XbOÛ› VçCõcÁW0ì–…UáDÌ„À&*7W·wAúŒàr¢¹ë±ã-»2 ‹ÌêÔ¬³RîkLÂhb_h¶«‡ÄÁ”oÛÔñ§²Áç‹ãmUm·z„˽~Wö¿–Íá™ )€í‰D»vƒBÖL §Ë¢'õ&„QÌiØuHŽ$ÌTÏúuŽÌÄZžš­íƒ³ƒ/á@Tú.I¦sk¸ÙÚÚƒ+ÈÜ" øÄÕÖ o½ÎÒ–Ó*ul÷5¤ƒU'.Òql-ã»Ò°A êBºý÷Qc‹ÜÞ»›î·'ù»ø÷›z`Ÿ£þ!{mˆÐ15™%C¸Þ%¸ COCͲ—‹Nwè±+ˆ€6#`8õn'w™70\#øø¦7€«GYÖ¡•rƒý68Ç¡ÿš xï € ~½€íÇÛºw(È´B/V8 {pØö&u)ªd?EI¸Âò ˆ:Y`1°›«UÈö…{Àò¢;~mœ€õ&ä…,»tĺu"7×é‹0Ì&Áï¢qUa%h‰¶ê~u! þ 3³Ä`¸ÕÚܹu/uÛý¦{϶qüû|Uéì¼={í V"Xá i‡ÞÝÕz>—×¢øKõè»Î×´á»Ü·›ƒ¿íÛ1 ©Ä/3Àà3Æl“-(]þzT•ƒîªÄßÔ2(xßPúsáv²‘­G7”T¿mô*f‹Oï¿Å¶ 8ÿ¥þ¤ì}å?­ãV:y/»šEÑ-³Ëz=´Õ ÀyJdÁŒûl‰pÕ ^&˜×7xìWa• ‹o¨mã¶ „¼¼Ž=Â]q–¸cñ›O‘õcü¨h"àPŸJ`h|úâo~3zÀ§ß˜…~GÜ ívÜ,•*b(‘í‡1@üU*Ìe<„*!ÌyõdºËÖžN¨¯ž6Æ"¤¯2fƒomNÑU|ÊAoÂØÒeY½åM?äo{ì$„L§ÈÛÈi½œp_•óA?aް¹K>«‡–Ʋçù׹‹°íQÄ…  dŒ$Y^†i+CWáÁWNѹ—¡rƒzŽSñC+~ÛÜ»Q’!7˶ÍÞ}òK;öní½Ã ì4sõ³H€%¦––˜t“„$àÓõ‚öÕGˆÓÚEàM; 6€§ Ù$Ø"ÍÖ6å+Ú§H &«‡ž>Ìΰ"k:-µëø£9šxŸÆ° ~Úíæ?«œ>Ii8sFÖù›ÔÙ=ÿ*ho_*yidžçjÐølWScЄ¯^ ÞõV8frëV:¾u6Ç®cw§¹îøKíú˜×iå(hÇ »ÑÃA7éíÜÏÆIYñk@îà3vt{´U 9G ãÌÏ‹WÎ ÊAqp¹]ãÔA´b—Zö;áë2G„ËW -ÅMô¾Ex¿×{Å‹‚vq›ùµ"îXènHÙ)Ü$.;è"´2ÇkAÉ€Eƒr®Ëù‡ø`è*:5HÇö®™¸Áö~•:Àw²ᄘèÒò|yk`Å …G.]7N—ŽÁ–!÷sƒúXb§?dÆ;ìVÕÆ-Wý1 ×ú„AvÑ€cd[vbÙ20ð\/Äo~ Ÿ?[]ì:ÍH(¯CV€„ÆPuEä߸í> 7:…Õm W–ªä¼º ¸ÃÍê-CךaIºñÛà[=Ýyßã\:àΊ(l=9÷Xö˜}j5Ð[hOèiÎ9EéñçxM@,Aø£ÃÜl¯Ô m›ÁùF ع£ö éÛ/MPÄQ'´¡µ!»Ç¹-¨TàͦKîùÈp¤kkEj­ˆ£äƒå.àûý ÛpQË%Ïþ_>ãR&p_&òfB=!‚º–±G¯ž®ŠÊáêAоYaæbå¢x|Ti]ÛvM­íZúйÈ/ÍÇ3©„u€ ¿w¨‡¿v¹˜l„ß¾EçšÝ^ýº¶'”ѽN¼«‰òq"6 î {u¸{ÒºI‡¡­ä08]ÈB46ÃN›.j*;Oeƹ˺Ök u;]zwROF”q¾2Õ·˜l*LrWƒŒ[îØ?ºÝJÀL,£w œPåôþS·[ìQ:áÇí/vÄöt´wm,wï@è u¸^’Æ «ä‘Þ|J ÞWÚ©!WtÛã ‹+w ÁÁFØ…®C/ÝýBüÑc+ê 0_€½áÙ8 Îê‚?tÂäbR’B®¦1]m'£hKL(xS û¼quûÏÕsr;ìr}ó=ž‚M²ˆlšx™„„ Ö®Ÿ²Ž™~ ;×»‘ŠHh3ƒzn¹š¿žW?Aôp}þ9¨n üåŠ@0Ôå ¡p8–™ÀgŽ7öKÍ/ÏáJø‚Li‚1.¦ùö@Û×»wrSIkyº ÅüwªÛO¦lû*¡Ï½5¡u+Q4d7•¬ ‚ﯼÏìÞ‰¾˜% ;ýGA¸£x´1q0 $ Y޶¼]á|Š>J‡A/*kZ”açáìUeÈM>íXWÇU¢}¯¤rw<‹GûÊÀ6æ¤å Á5-g»¥!›¥€ŽÛÕ»5˜“>˜EÛùê*nÈ×—‰ß§ô'˜œvcð4 uÛ ˜Öv]ñtŒ°•Ù²z8ºÁš‡àTnK›¡ëÔÀë˜DÐÊùæ¢|˜»"ý×WÿöK?¥r,ºg¢¹tðH dìý“å•‹¤TÜ®lDèíwú/`é¶þ7znò»Æz˜²õ2hr ¦ÝZÊzd£Wüº;‹›aG€}ÜıÞò¥ìö(}À­åPD@•ÖlÇŽ·nV‚®-f¿$°+坯»ŽZõÚŽý•/âýͽÎZý³ºÐ¤¤2Ëgé‡n ›ä šzKg¨|RXªœ„  šz]AX÷\ô¥ËÌHMÍ¿Õö J\éW¤‚÷1’5W*· Ÿ<;~Ôºq»8«Œo¢u[¼Vˆ¶<»ÞÀR·º¾uÚõÅ­BúÃIÿ£Ìúã*íŠüÙbª…ÿF×ô?»ÖµͰ›ÍdÀoÑÚúãÖªWa¢d³£„su0t«°'²·‘kÁ’S†§â&âm×+ë+à,èÖ›âÜQ$6Ó[/ûzÍÖ6yŒðêGÁ«:62SsÏGËÓ£»¼!¦°S\îuê?ÈWÚaÂ.{éU‡D£®­Ô­íæÇ0¡£ã†U/¸Ž Bev¥›BÎшS;t.¢å™”ã·'ãoaµ%`32eLDæ—.¦/㑈ª4ü(',pô¦´ ]™;ýÐEhÅ‚1ÜÀ3<ªk@áíà½M|ê}“¥ë1Æòª;üÄöãT¹ÿ4‰pþ$¢ÓyM›ºz;Àðï¸þõ<°TyÁdq0h5dEæävL&WÓŒ¿Èν=;ÎÅã_°s&X,,}Èê:+½^×Ûu“ 8«¹xâ³3ÞüñûŸHv®Á•ÅÎFÿ äN'P2ÃqYÂÛèš eÄN JSÀ\Ò•Þq»Ýöñawâ0–øÑÃv<î,Èõ{FX u8¢Ÿ¿w® € ¿á«Ý[_o/ÞYàPꥺB&ºV3ÃY4az×Aœ4\aÛt ¨Àñ\ÜØÐzɲkãÀ'%ãÇÆZò U•+„¨]‹«t8nï‡X®kr®\v±âí°ÔÀÀEHnÝÁ窗ë6*.xŸ€]ÜF5#n³&ÿs…=©@TqJ.a‹ŽÙÊéXÊŸ]rñ‰Ï›CPùÝ«ñÕ9}T—q`O}Îe2°ã&Š2˜œ«\ˆ]¶¡Œ; Ú§ó Ê΄ÛWÄu¦a}²ª8«…ß×@€P‡™NÑ€ímÎÓr¤tkk8ÄoE Þ*Òzü7t 0ëªÇÛ#<õ!“ÿªA o;·õWÙZQÉ»!g‰´+©î7¨¸ÕåNIÍØp°²Ûé{'™é†Ã<¶Û¥CÎÿvqî 📸ÑÛ±¹„·ÇM92Ë·¾áã¸y%½›þçˆæVÂUÃEö:z´öìoq%ÚÜ…íí²;ä A'tr†àÌ ÊW¿¦,¯Ê?ñ]®„›íI(ÖD¦ó¢§4Y2)@ØH…]”îN àNb ãåÍØÝz?8~É[´B uè¿«ŒÊ™wnþÇÒ(9ЃÖ=ŸÅ •ÏæúẒ”¯.}‘€ìë‰]$aðÆq\’½TðÏ–éÚo†aЬðå3\’2ú:iVùðˆ†6L0gQÄôÃA»Íܸ[ØÍ §ÿ*¶Kˆ)P<¢Á`Ë„æÌºû›ó6 !›†™.œLi•žXJ™= `nÎñÁm‚pÝÐ1Ë€:W»ÝαŒ}uÛæ¿îöÞQ0»¨àØO€ö8öñ}@§¡§˜)«yWÈÝ–rœ¹ã­­uµxŽÖ_ÓÃLF­w£Â‚ëá¿ %éÅ/«ôØš‡†.¼¾É±/XPÎmr¿Ü¡zZ—ß*¶Ìï¢gélÖçbêñ øÈVqtqÄߤɛ Vù®]J¬ÒsM¸š™G·ÑŒãø+Ù7H-£AË’Ò-й± >ûJݱk4î++“UZ\Wýƒ´™)“îcjN©›{|}]m=ãhð•ã”Y8^·;ÆDÏ›íKÐ:òß9ÞtÈÉ¡s¡Ú•ÒšRI³Ë’{Ñ¡¨,W{Ÿ„ö5þÇÜüzSÉpÀ×ôÎýSÙ7DËvhsnldòØÆ£&ÅržÌv4ˆb½,þ1±éBÙÑÁþ9Ǫ<1#>"Âæt(ƒôêë¬Xꤼl3¸ õ›ª[¦CçJ¨M÷/¢&Ãj£?ÌŨ‘7µ±œq&u2åŒÎ¯(©ñâöº¿p}¼ $æAñƒÝ…US·Ê‡ æKê;ð@›€ñÌÊþ ”ØZz÷7v5K@$ÿʿ‹ NƒË”9÷¸&¹§ùìiñÏÖ?jEž°:§¥Çl»ôé‚~Æ—Næ?X’§©êÀ“Dø°×Tίâ6)’‹§ÿ½ 0,*2G{gõƬkŸµáþ|(•™î–ñ…fÐD=³Jèø¦öò7Z¯Gn뽉eö .‘˜wj8M}žyYÁÐï– ÈYîr|ù[zð÷…Á[Ëôƒp½Ü«ï- ¢`°œö¿,^=§TUÿ°8Å{» }„s; Ô0S/c ±=ZTê]–-ò×jåæƒþÓŠ”ÿ”FI)Ÿô)tà†ÌùÓÌ¡i’ž˜¼º”Wœ†Y2²wÏ'}²5‹ÿºMe½ï,ü "µ»Á:’ÞEc¨V´Y+%¿\çAlÝÏ©À,÷­€2M€!î]Ì?T[å‡ßÖâ3ÊdæØŒqºïrTP®À¾ù§ÄÓÐñþ‡ºªÏgô ÍúúQá’;L‰¦âozRÄšX,v¾›˜ieÖ¹G¸SÎÀöãT„]#Q&?Ì’¥”‹g¿[ýˆ*®C8K·?db ÃQþÉzø¹RÔPÕ;IïU,¿m£Ù0ïÇí†Ï╌§(ý q01Ëun6íF;“×'¹Œ:–7Òh‹:~öòŒJħÇüŠôêùûZ²Z Î½É¬kçÍs¹†åÉdë''•Û1ë°¦GÁûY aã9f©jæf™Èß%…J+—"$Ùç×( ];qÚƒa0 ·«¶•„â7Ÿ4aÝÝK­|mý’Åü…Öþˆj³mýªá»ýS·VT!£· qøôo-@Û?V•Œ·š¾Xi΄ ѯJ«“O¿àó\‰Å uïµG¬D—-–J·í©ŽJ³gáà‹‘ö5/©»æ\&ülG¢íÙ< Mw˜îÒ?Ö±²=M+²¸°£ÌÑ»cD^,A®ùåÎhϤ(ãi·åöÓœUª!Zë qê‡TQ`ºÁÓ Eº\äG/¿Ÿ( ÑËçë¿¢æÕ¨¿á¶ëtÚ5[Ó§~ ¬P&³³J°þµ9¿û¦ñ &ã–&ý lÇÎþ‚¼ÑMÙxCóUÈõXâ*ô}9™Îø»œùuyZKÉ|ìSë u˜V oxå󵯻äº'vu¨º;ûaÓ›ûŒ×è0w¶ë±ŽhjgnØúVéÃcÐÝ‚tôœ@4¿ÙÕé6Í0Õ{‚ù’Ô-`ShÏŠê‘•déÃñ‡’4áÊ š‰c¸f)w¡Uô醑oßèV OK{9ó)n WáBïåNÉ mzÌߤrÏUë×Q u†Jà(Él§LÞNâôR›V·t×Ôœ91‡kõuÊf³Õ™¹¹ã/îMˆÚ=%Mˆ7 9· ûµSù¬$ÁU²ÿ÷GÚñY‘Iºöµ(ÃDêûO"Ó3@B;r”}Í>÷³_ñüYSÿ`æð®ìØ`ÿ9{mÈ´x´@5 »Óöv‘ë Ô¨`૜Uu!QñžÈV8‰Ùú¨Pµfð¢;†-ÐäþÒ½Lû¹©Q-¿aƒ²¶Ar~gÉ(ï¡Å‘wžAó¹ýóƒ1pd£Ê{2ŒÏœC¹ÔïíË¡ÐÒ¯…,ŠÍž²Ùb•UM²?¥±EI 8é7%ƒÌ¥þ3€ø×ê-/·Ð…‡"SE”ö'´Ù¹67ØÇžåcŽ.Ò 75^û¾OžSøêô5ñòQvl½*Èz®8}i^NÕüU§Û<Ÿl! ­‡3zcÄóêÁdè@ø¿8¨Š ðŒñ°Ã¥N@R¼F5UYK|3@ ™d>RO$UJ®¦<Ëigþ~zÎÖì¤+Ø\aiÛ™—ÈWôýL!y“¼UY<7ÍdíŠZž·‚ó?èš<i‚ÚZÞZ‘mIó Ë"SR'#VO2ÆÍ+Ÿ“¹}ú#S(3‘ªi?âÐIL—-†Öýj¹IDU¼7ôjÜŸì ç0Ì ]²¥nÈß[ÍOCN:ȯfߖ顿+ÀAºR… ;g µ”ÖäýKç c9'ø]eR!ù>™}t–!E „ò7¥µagk”e¶s>‘¬ÛYS,­ÝÎYÀ«ÒMOÐ]Í3-"Ó¦2kSSj“ØÕMk#ônÝ’ãL’Ó0ÿ5„9Ӻў`ŒèbÅžÙBÃÔ&DÓB–¢Iá–gR{=—'#MŽò¢9°ks/ñŒWÎ9C›Õö•ø£C‘O™™õ¸±’|LRÊßdø¾Xa<žbŒ Ÿ™¬ÔMIh½+"&¹!Æx4 ä™ÒAÙ›‡|qìjž` X¸næ…Í>;drÜŽÈZ`¼7›)ze¯î%ù¥æfW˜‰]÷ÂÜðÐèðÐÖ‘”¸tĽ¯µcNiÔŸõÄtÌäHŒ›$¦{ìïéç)Ç]¤„ÄŒo „m)HÆØ¿ÂL¸wp˜Ç•Dª|À.díš…Ýœå…k‡i€œ„ÃŒ›WU]vãf™vV"wL"í€'M$<ö”¼  ìà!X2"ó¶ÊàWÀjLajE1r3.HŸ`5Ã?Z7¯Ì¦Àb)¹‘'ée¦3î7h‰ˆµ„À3)† »óôL]a¡M‘á-òLhxLk°¯¡ v5ÖÙÙŒäÝãÊÎjZd2_£(Ö£îp532«`ˆÿg씺_\9n-˜4Ø Jé#æ —:Î- ²‘-e‘µYßYµê0jÁl¢“Œ«†¬9¨&U¸’nÈ ¬§>mÞßLXɯ•¦KÍúâëK3϶SrãFeDHAošT;&»ºŽõΰLe“sÚ|òœ‘1g÷^öÿ»FÇœ­#ÛGÆFœÝCcÃç:+ÎáÄéx\C!™N¬N´¦A7Kàóžš_´æ ù´è$ S¼@ºù#v?xç/t…l:c¡JŒÞ”É]zXH5Ýæ<È¡´¾è&ËȦ¶–ˆmUš Z‡YRùŠÏû•D‡öÕ°¨lEé•Þi66ÑOÌ8vFºxþ@iÁ_+Ý+oÕÃ’—\`ª4­’GðMümø‘´bùdÅù_™bCÛšŽà[ßyE)3m Ô)­h§päì *ì<¼Ÿ*áF³×c{YïT“šärœ‹ÜZ¯%MKr›#³qã&ÃO£1f%®HÔr,ºÝ¡CK]9qÌO&6‘$aÞǸ+n[êÚ«ÀxŠ@S4uœý#Hã½Ü§tóN£vÍi¤µèj¿ô± hH ·³—SZ‘&‹WŠ1ÄÌŒÎái¬Q„‹2DŒ.Aªm¹y[H¤Ýû X!®Ñæe€j6=>­´YÍq6ÕÕ«£“µpTí\)g­ÙG“7Ê<ªö½×?nÝð]ºTÀ² ãÍVë ›M©žõåJ°”DfÃå³´áÚÚÖTÙ\½©˜·-yNÚ*¥éŠÏ wÊ%Pˆ¸b§@†<Î7#뾊-i‚‚í½Q’«ršªÐ/Å[ö©Û–h,ÕsaÛ¥ FvÜZ3ǘXÆEƱÔz‘ŽJ^¹Øî(d3iuRK­-‘¶-ã‘îà1DŽbe³KË-£ð(¶=Ã[nç[+--ý;Û*/ñ[)M¤•±§ W¿0܉éÿ³n†¼,—Ù¨Uþ÷(þ÷À†õü×còÏðóÑ]lDh•æ…ló»á%\t^§’p‚‚Ž‚`+üÿÞAóü3 Ð9ÿÛùW#@íÖF¾YE¹¹%`g<y!Ù.råÈ“\ËÚÈš'öŸÔÇÂÝIBŒèyÞ‚•nX(N˜DV ¬×I]ªMeßãêàT°ß[H;9êRŸÐ8js7‘,î,¶%UÊ ÿòç)¹üæ$΀²ƒÞ¹¬WüËåBU16]"©`„u>.™¯àf»´Cý«6[‡ñl*˜K ¬¦­Î¦¤2Ë&u/¡/ V,j§ž`Q ÿ‹-ê¶ÐÞi5¹q–†¹z5cü¥$ÊRð”kEøš'¨^1‘v¼ÕR åÆJlœùz²'¥I!á*D¤Šù† é1(%ðVüßààz“þ÷ ötèÿ1õÿŽÀ:T ^­õ7âìD𬌔³K Ss]v2 gðªä*»šð›Ñˆ4[)3TÏZƛׄÃmR"“g+dÁ³–T‚ñŽ"‘ÑÏA¬Ø²RVù?"ç°¯¯Ãÿç¿Û9 ý2…kƒG^¬E‡üMÐÉ£o=9Z` Ûdin?œ big‹M¤y«ü…â¿9ÎHTL}¬û EÝBQîÓ/¶´šÃƒ0¦|Р0àÄÕšéÍÈ¡ñ'}Û˜øËõGõ4ÍñÇýËxù»VED•ÀEAQgBÐhÝ«NÚÀ¹ :~¥¼àÌä«U¯Â]ÆyNÐ(<¯È¨ø÷2iáái ÁäE' =ìÐ̪g3LÝz¹Ã2ß"áÐõjÒ“w‹§ÂÜ+5yU‰­z“'HF¼xU¿ué%št©tv,N¿mÌ€¶X¸‰' (.ùèN§|¿¦Ÿæh·²Q–6uûÙl”†xÜ 7 éQwJkêWÂo£ÏËÜÿíNˬw„³‚§Ú(ÙÙ œZ£bí’†hWT;N…ãþW÷²ñ­øÿþHüç†ÞþÎý"ñÿ66º­+¦ÙÍa»~ {! ”Â^DTœ§ôXÈ5¶ü €çpý†SþïëØý¯ýt+‡¥é™ c,ѧYÍ\Çà *Œ(„—)0ySJ¡®pCÝÎŒ1Òj,Se:>œƒhÖš'ÀhƒUìÝ_-ìÌl_èÇA#›åÑÕšÏÄü:h°ü 5ÍÄFO=OzZà]õ¢u•qA._VfEýÉnÝ¢W‡$„rjàI•þ*?é7ê1s‹4dzølhŠˆÂL8Rfœ 8S–Ë iœ›˜26­€ñâ¥<~§ jnÂaTûM5™ 岕Þz#ø3Ëy.|EnDL,lT!\饕 ˜j”Q ¢Âfœ/(W‰¥O=Î#ÇæŒØˆôß,›»€âG.bTš´}µ0ä&MÞûlÌ¥›q<|ˆta¹¯HQÕñ£O_T¾¥Œ˜ÆM“Ó:Eíàôj Þ“mväÉ%>'ÎD<ÃúÜá6(…‹‡m¡O±¿ø n•p{„:À3D o²Y&LRDºRa¸)ìÇ94åÐyɈO ƒÊ¥šYgwñAÙ–ËHʤÁâg˜‘ 1Ä2²¡Wkl®bÆÙÁ$Æ(`Q S ^&ãy«Å´I&wmDJk¶4œ$™Ó”åtÕµÖiš:„Û0ºoº¬áMË¡ÓJÉÜÂ$þ—[2ãºì{f“>ޤk¨^‚`âk¥Ù¹ˆ©9Ž5-ª‘r„ã½”¦¬'"6ôãs1«›ê:üÑ)EÀ-µi¢³'t'Ðvg~¦Än/yr!Šl¹Èå(×áZq2n6cì…àˆ1î@¦˜'¶Ö`4Ö,÷nžh†8ë¤F´­a¾kÅxH<šñ.dãaxç/o1 +Ø×ôO ¥ 4"´n~ç$WçkÓ.ɾ1H­¥Q~Ú §coø„ÔÄò?ÿôÇØÿs ¿/âÿÙÛÁ;~äÿs5ŠÐíŒ"À¢Ì•Š &±òð/ˆ¥ôÅóæBÙÙ)ºä! ™1-“€}Åî•ÞR©$ܲ›¯iË%½ßSc1¡Ìf^¼´TW$Çå/Äe"Þ§â.Ô-|&FÜn”’8$ºÈ©Íر"cžÿ‡Áÿ»°§7rþû:çÿÒÿëî1Í5ÿËj[M#íZiá&=‡òü :%p—Hê$8#âòNPª7$€øÃ@…!¼Q'QªÌ1F°ˆ†ßw»T'BÒ'—êÜ€D¼:ÊsùR$:1¶2=ÚE^}HÚèŒÖ™p‘¯1]Ôú¥²%4ß;㣠³“~9‹ Oø„1ä|<t c–ŠONÌD±ØÌ&Æ9…=p‚(%ˆ!ñµ¸¾ -|iü9¯V+½6h÷¹Pý ª~@H »šF¨Œ+€Ð0>ñ‹ ŠÂ˜ÐšŒƒ×¨ÒOÜ‚G¾â %M ¡H”A´$.[>.2‘*íñÑðv8GEIJ†D|‹VÇÁoLîë:»Y r>?›:[lZ{:ÈÚ8 .ãò«ì4c—ñI1v£R/• ºªé…l6„¹Dö$cÐóÈvpÍ’iίÅ5jèélÆB-m’ßOH¨ãiqªs„&š o* Ù"Ào>:Žˆ¡I+ Q‹áõÞ²µ ?ÇÞšmfØY¯ë ½Ø,è)vŠYBÁŠŒÂm=RµóZ¾0β6 ¸<•db¬V"T…zˆFˆWÄ´aèå ~™.õLBpMM:, f“pgHñ–ál½ÌH£ð§)=é[ØgÙ¥Éw4e©ˆègÔEy.:˜™ 1,·¡hìA6Lá01lëæPIG}þ÷LØù!Ü<è˜i0I^´&õ^Í—jb-ØWJ“¢‰ýiöÅNR£^mÔ9¥ÜEäÿVšZ€]C n›íå×ÂlW¤=ôÂÓ½ÂMÉ#8Н†P«Ôf*Ú¬Ïx8DJSr6‘âÖ¢txì¸ÜA½â`’¢—òp“A(õxâ¨Síu%w™Ñ§²Ó°eù>ÕVÑ-ûOŸY[mŠ‚ècûÇÚ@•,D”{>Ô›Jê‘å‘£CŒ `Äùh‰‰u$Ia÷{ÈAI‡BÈA‚˜£„çÈSpò¶Žñâà¤zUÒ:ɆBbiñƒ¬kÌK­[ŒhM´QÝwr ³µ âùÕH’ 9Œ ”ô¶¸V—2®f1Án¦ÃŒmgÂ~îæ:•gû˜_Ù:xŠÎçáSÀ7g%øæ‰Ä×nãkê¾ü®O][V†™]_ò3Š$L!3$C®ä-¦D1I/¨d*(›`ã‘$$ àa÷îÑÜAxQådÍ…¯s¨®ÎíÙ3 ^]ÖÜ^à.–‚j9¿€L.⼓Ÿt—b  u’pNUF9Ky3q»š¿½RaÎâ!x4SßÇkÊäŒo«Ô½i¯F~¼è:Jo†}è< çhü;‡sÈñ4CÎ@O4-½XnE’&-ºäŠqaR58JäÕ©d’Wy ¨¡eD !¯ÏÔüyÇõˆ5âãpc@®Ú§—°)v'¤"“– x–ò èrµrì'bïôÏÀ}v 5”iAP –x„àtˆÎ­mÿçV½Úl¾‚ü_2"-+Bš¨°Nž–åö"B$˜ƒ$—d³M;r.õœÆ T.m…Õ«u?LÃ^çDG›ð§ê ÛS.D¾]Ö÷ôª eÔv€?_‰Ê\‰/U³LØ,†íì>ÈF¿˜Y©:”¦T¢`"ð²$é É$àɺÞLoTGÇÀF.Ó¨B&gÅ&'¤×6ÙõM';8ÏË ~ÓrÒlÈu™Qôºu’ž­«¾Ã_WÆ TýZ¾VŠ[W…™áΉí>¥€H¤áÄ(°;af\'^dë…+UÚÞÑh;ÃàÞ¢x²„ôOW rínI=Ç,ÔS¹GeøŠØªvB#v9Ä-A¯BØk8û¤0j%® 'ã¸Ý©¥EØ¥ Þž™•BFP ˆ\wô¢gíÚžÛ•Û;šÞµuÄÈ-Áé­ªù—“Ðpð!ºòEêà\ø*Z²Í=LħhýEv<·•ø2¶>|J ìÈ~ÔWãËû4ŠÓ¤&!ëV6\LÆG™‚ë›  ¯§§«…Ò×Ó¿)YoQ“"ô¢vƒº£[É? œ'Ú—ŠSzŒhÇO‚:ó#½Ž´–2<éI»—{ªŒ˜û–Ùx×α‘c¹±‹v ÓY¬{w3kÝL¶Y²Eþ8Ïá»ZƽHd1Ȱ@‚¸?`ì KiY`-  ½¤‹©ìBšÆ,ª;lVoßz;d–Ôz* pß;۱Ĵ9 \îE—‰ÉðÉ‘|AH!6üNÔÎ@û‘ ìt%äz_©=_ÉÄžùÊrXáØûµéL½AÄŒ`¿“í†2 -±Åˆ²À“ f©”HDo}•¸x–j-UÚ·c›©\*”ê2™)hùù1oësˆ]V*š_ƒÚËUüoOÿ& ŸˆøÄÖß„C¶¯ëí£i€vú_G.zåJÓµ÷l]C\jõ,q§çÁÈV×–Kû=±„ U#;:g³ÿŒb^,J,—Ìd2©öv/Ö§ÝË— à,O](øÝ"*)ýHXR9 ¨šãÛ”ÓåQ¯6Êö'üŽ ÛHMÊö)/®ž@麲›”qvV¨ÃÛY*ë™ íA_âꄦ®®úéÌ`¯½eyáú(ãWØÝ£…y-aFf¢VãO©é–Û:±›’rª¡ª&nWn›Ghív¯2]§¸±Z¾L±e©0®£äjŒ¤—ó•ýN2?ëKjÎöEO©0½1%J¶Òà±[AhU40Òøf•ýÁÎ UŽœz|$g†·ÀO Ë+:q§§[á(æÉ²?¹î9Ïé{Îú©|ïúâ郅bÿé=}½ƒë{¦ …þÉâ@¾PxNј,Ö¯'¬Æ“©M厼z~:ì…d!X;b¡¾ƒ‡¢Š¢PdOÅ”Îf¼µÐdÍ/CB™Š¿¶Ï°ÖûKÕÀËO‹¼! DL¾­PzȽ֨‚ëq¥Ž7¤v©Ö§j6¿CˆáÃã©v0¨¤ÉGÍC(Rzë¼G^¼Bøâ)¤pÑ)CÕˆ‘Ü2é0W‚N¸ zœà:&žDxµn¾ˆiŠÙJL•0B¾Q÷!oSµåUâZ†ëUæJl=fÕ‹8æÒRM™ƒ§¨I¶$˜“*¬àr^>Àéý0Ñ€q~á”0”B¢!ehèq ’‘NÂRâÏÃèéÀ>Íe·ÐëXú—ŠY…V…i«\ÐKóÈmö‘™¨ÌªšóÅÙRÅÕœ3øl³•ÄðLÕ03b.´ÒÃsvzl´g:½`‰†Þ:;‘u¡†[¦¶.Åš™×šý”F;Ùš-|„Y­ÅŽ‚`¼U *t†•mU†awq¶5Ý<»AƘ«?slW€y8IóS€•Àd¿®ø7ð #L“¡–òøÚçy$,ê ÃŽºššþ°œÞŒ,©¶ ¾N|X†Jj©«©12~jùšœi¾Z¤tw~=>’+ÒX’ÄtHñPsnq×˦"ZØpm¤ú=5Á$N5¶GJÐ(vÔ{%wöE‘]s¬+lˆŠâÌ(O„üÁ7'],›j6}Òþдcç«~ \-½d³@iJ¬¥’[á?Å銩“l‹""JÆJчLˆ­…v¯ŒPÐá$ÔhÈw”°©P*Q«Ü9{†väöìÚ;¶mç9¹¡=çŒfÇ)wwfnµÔ ÕA)6R†ã4øÅA¤‚’‡8{ÜÖ¥;Ÿ…rm˜SX¤V3"Côá xÕŸÝü“ë"¾ÄÌÂð±ðÇh™ ÁL„¦P„Ò„Y‰R=P®Üû´~šZ˜ˆžïÂÿ%ûÖ|Eš›ªâÑnи9Ž‚G â‹&˜êuÞ¼¨£RQØ.ԑဇ~Ÿ Ú8¦Ø ¥î¡öè~Ì¥a’˜ŽBþMzòYKUªMv˜>¤‡ç®id©Ö=p~I«Ëxj»÷Ó¨9xëI鑸7žT:¡"rl„\.Ó(Ô~S’¹+2û›ßbíÝ8zß8pîá/‰ »âa‹ÛÓÀP' w¿ í©ú <0>óÁ€¯¨$“–`ò%¶šÝþ¦Ü‘ìþ—ígãq"iƒ¦ØF0“œ.¤ÂO§¥‘ÓF[ÍŠ•±XæÆ9 á’2ˆw•:’THžl‘sŧ(}è —S°ˆjF%Ò‰¶5î?¢P+Ó–jFAF"G@i0Æ?@š0”ˆZ]Jœ¨Áe€ åPÈ «š ®¡+qûœ¤ ”Т@»–BK’¡mç=À–É ¤Øéνæ(.Xô Õ‰Í$ ›&© €4k—°NK>¨û”~Î#÷½pMðfQщU · !ÙÉ%GÇŸƒœ,*Éc]w R¤,rs._{u=0ƒŠdyùík­:8eœa=9ïŒiE&q©§šl·l`ª2+ÔX[f@—@}í<û|0é èN…7>‘i¶WDÖ—¸eÎÌF&Éšª–ódK_ƒUÖtiÒ4'FQHÀÖ‰Xvöåz °,óàŒ‹âFRš9ÝK®»ƒW…ŸÃøej‹¡‡!¹³Õ¬ÈÌŠF†%o$±Pw._+åyŒrœb×/ÆhÚ$r©+úò>ÖOU|[ä)Õäâ~Ü´DÿÀ“Y ä•×ßì’„%ÑPr5ž©¨NÖ¯•¦stÀ7ÑAÏÊŒht©ÂPøÎ”„xaµ,ì¸ëž'I8+]‚JòŸYgÑìnËtÍoTC—Ý{è©æNF ! Îj¤8ñœ j9¶-r‚TR†ž IsBw*t…‰O…ÀoM/'Ù#^›ê…ëªÆþ«ðÕ›èEªd¸æ²àT5‚ÈŒúHµzD)©‰0ðY§Û”Ç,Ù#îIÀêû)¹$ìïaŠU?F{ï’M|_¨È‚KÜ[ÝNaƃ„cÐ,˜ÔÞ„4žª(»‘f±jU®2‰ö‚÷Áë—øå|t4Ì2º_c^¥y\›®’±-í­HÉÌÒwÆŽÿ28¥Íæ£f:i}èŽÃsFägYNGô/ø³³åIî>´E¬ÇmùŽÜO±Ç&Ž_O_9Ifa}>¥;ŽP!ÄÒ‰ÐîH‹7ºé¯ënÆW °V½1ñ…•YÍ6êˆ$–C&;`#às ç&jÉÝ@uD HµwÓrÁðÍÉ¿µ³˜²G?ÇXÃõ¸ËxëŠ!›Ñª_•÷’c½äü©Ös×Ë™3î®ì®ëèN=_Ïa7mÏݨpt&"…WB¹$1eℱ˧LÞô°By%Uë’æ_.çüZ®ÒöôµòË;û­B's„º‚W±dÁ¥W)"ž•gÙ/ ‘ˆ½‚r²jÎb‹ úí ²õV’¢?ë"$Œ/â«°«Üÿƒ_W¦£øfÇߣ˜¥fw8ü)’L'P)FQN²²@^ÖrÙ(v4q8|Ò¡ ÝvDÚ¸z±Äž³BÂò?é9,àÝÇÙ&nDà#ÐmŒ÷`(ül·Ð×,þRvxÜÍj+–\]e¶Ïkà͉—éL žh»ut C@$ pέ”½Ãµ–h[æ—Òr$t‹lÑžJÓD€ Ïå‘•é»ÑìÂó(þGͱ³Å„:Æ4ÒÒàBâ,ªž¹Þ ^ЀÝ?‰ÉÑý@u8™GQ€Õ©2¨±a¾Šß¯é.ÃË…ÐUÚ•å&KòRÂTS¢Îæ«‚¥x²^N5a&™#ØvÅ¢${F(ŠÒ‡W¶´Ál2;Ä£éoœ7”5L‚Ÿ›¯9œª¥ª¶‚ÈF‹ 'o| Lsšš4«›‹Tk¥9ËÒ>H8ñÐhÊ’õr(i°³JËwÞ">Vä?ŒšÇ«§’îÿ#ðÏ‚Àòx5÷ÿéèëÙ`æÿØÐÛÉÿw"ùÿî¡#ðe'àQ¡žñB$S´fJÒ1´{["XzR:géË'ÜK¿ÂUéõõ 'É[KeÌÔZ0K}`²#Þ]$B ˆZª–vÂ&Pïb} 2˜*Ï Ð=Ö½S]ƒÃŸ;àP˜-ãÿ °‹¦^Ð'߯¤yÚ8z“iM[Ë2˜Ó¥Ñ*0CâCv²0^ׂvúÓ‚eÝ´äáùÙâqFÀÈÂp˜Ã=fˆyaßž-Ízª=„ohö4ÇUw* a0Yƒ¬ÅY&^£¶ƒ5<†ú3ƪ†m…™ÒDÇ­3àiã²|0ÊæšfßkúÙSí$¹ 7¸ôõ—_…{p¨p‘¶- žÚê”ÔÕõtqÖå·XZûdÊjÄ4Øj&hÂk= *f™½h9*Ö|ôfS±C9~vBiœ³¤¶NUß‚ˆˆbú®R_‡¸gm^Ñd:’>b©D#vµ{bZnë`HHueyu²Â¨ëU’’•&-C¸8ŒÉ?8¦Al¿H"Ų‡ƒÝÃ[èj+’ߺ³`[J=‹ Ôe¦3®™£¡N»ʬPB |X7W)ffƒµàxPNhßLC±E(% {¶=’,RšÓuðZ}rCå²’47ÛbÇ¥a%Óá#ïhª5 NˆOÔFÖ­0|@ÑO;lŽ A 47ÒPÜ A3JÄÁµÑtbØv–’[€(€‰aý °² Oªll‘ŠÎt§Oð«Êt*r€BÝ5š›Èÿ ½¢ÂÍB9Ì!ÖA~†Œu\ZFï‘^¡êVúÍÚ#—]C4hot9B ·Ëðïå£k¨ùHx}ë'Ô%º“Œp€ÆÞ“y'|Vª¨-K…D»óÏ4&åÅ"oNy vbê–Ø·pv×üB–¯[MYRÈ<Û|EÉ1ÛøÆ"÷B ø!D"}"pi{4.ÎP€ï·6¿ËaÈú¥-†ÏÑþª~UgUâ³#«uõ$ÀQ R06’ šð¼ ¶Ã=?é×g8Ž”pà«ùnáÙÈÕ0I fÀ;bÔh~Ž"ÿ…ë-5ÇpTÛb"ùçdÅÓ<¥aËJHr¼"fZŒ7ò qám‘ )ÆÑ¤¬dvm! ò©pqØ`1Gƒä1#GÛd8E&ê6ÂRºú2š<§•MeÄ*ðr`ð˵¨­u¥DöKÉ1i“N£cÜ8~:Ðÿt±¿9ðD~鬳Ø<ÊÊ-òáJ×d ˜Y%ˆÈz˜Ç.C±Uu#BT#¼Ëp¶UøFŠl©9{Rª!‰÷PSØe@£Ô-º]æ)ƒVÅ J³òž®ÎÏDM7gmt~ ¬‹œ?Bº¦9d+¹tVk,ÓBH‡³*Ⱥ¥Æ[U!]y £Þ<ú#¨u±³Ó„ùÙé‹HÂFi±wÚØâ]àÒjÀMª øÀX[¶CäÊ”äq 0æMÁO[NkœVƒ>Eà§ØKÈíˆå˜ØÅñ ñ»Ã÷æo”¿ÒÒdc?ìvIƒÂ“ÇéÇ Ë0!û›À=ÕÔ6—ÏŸ ¤B™JqR? ü6DÑÝbcápÍ&Ãűìub˜˜2V«& V‘¸R]À†B¼ÞÙ~M¢¢ªNuºä¯\àü çD" ø1´JCÎKkkÍ„[½é&¬€ºvÄz›G2铊áA(ml•ƒ´ÚÁ#-«•JSêÏŒŒ_ô§¢,[´ºö›µÂ–Áž_&’IÁ†K¨û ÚßbvÙI¢ÓŸt˜ÈÊVÉ…ÿ¸¸ìû-3`+ûþCOÏúŽý÷D²ÿÒÆiËf_ĬQÂWÂ?¤x¬šÝŠš÷µ…þ Jâu\ö¦ó…ÿ›±p;Z0Ž"½Ab®/ÑŠE„œ…6&ñ d±rD1_Ï'ÛÔué÷ZnÑ/ë™V ®ï(óÙ.;ªdÖm­ÛÈWtDûªµ¬¸³…DFQèÚï DDç@Þ ^1ÇG*;äîc]K2Ïîc+á׈¯á’µ¡HžàòL$Œ§Z¡s$sØ€‘Š}‹26ùç!ËØ»Ì,ƒ±‡‡…‰¤M؆&ºÞ]Ú2‚ÔÛ°H¯‘Bƹ&£[(ªí±ŠúG>™%O¥I‚F]¾—_u|‚Y ŸjÑ2†X/1=ÃÞ=ÛAŽš*@© åq6j„•§[œ±\’o×FÝä¨Nš7«rÈ­ä< {Ž‘o'?5ú€ha«XFdé/½»Qôt„˜ôÓ”¦k"˜€‰…QÍŽ]jR­Œ¦D–×W ÌK_òÚUL×6ÒÕê÷w2R«‰ÄVý°)©Â¹#C[ŞĉA)ù[©Ðma~޵’£D@hV´a÷2ë˜z=ûHuÍ{×nȃ6ÚdLÞΰ|»Æ1b.Ÿ…5Iü¯vé qŠ?ÏÄô‹Òyëhéà“ž«æKµhSùŽœÖ«Õ4fqÓ={ÙáAU`“g'žFh6kG‚¥’Mqˇ•ÃDrÒ]Ø7ðlû8hKðu2z:ØoݯæÐz(:²áAÚPÑņ¿º,MòÑ‹ƒ¤e:¢¯-šu`¶® 3ùÊ´·ÂT1[žFt¹’äF æÀƒGÁ×*v€ió# #˘ ÆÑ˜ï`\üo::|þc>×¶>Ȱ‹pƯñ„ê΢YžÑüù|­˜c§²ÀºZÑÎfJYqÀ+OiÏÛ%b» Ïé¡0+øÓ¶ Uþq’ìý¤±Ô.)›ŽŽägoïój“Yg—§ˆÙ½9©`û¨èr”,3Ð \9#¬ð©&¸2“L¸ œ;Þ@&:ø˜AÇ¢…rïºö”_xly§A“ RJžpVs¹e«)‹*`6˜•Ú[°f÷)£ƒ3»B)«l‚0ï×ÊÅæÒ‰ñ[fñIJAZ±MÎ8£½Ù´¾Ã:/ÚîZñÙ79‰Õ øTòÁ&c«Œ)¶G¤‹V2š Ó`˨×;Ù:xRyÜPXL“v¶X+NJ˜÷qráÜD÷ 0žÒž²´Óü«Ä“pŽŸå¬”ûv¥…#ŽßCãx[øµ"€,ò\`ï2ÌF… Ú¬½ ·BÁÃO1 d±€ .ðŒÓÉ´j9¬2iºR¥…[)¬‡<Ü`Þ™y¬_~k (ÅŸÓF‘GJÈÉóFÚ541l0ib•2“ùZŒJ¦["©Xw.Ï»ìûëXÕ%ªi€Ëq%it\²iE{µ¥òlóÅ*Z«ØÆ™+ù ,“SÁË69[¬/ŒV¶ÄÕNƼ‰ÒE…7¡¤¦ì s6M‰X#‹—«Õ¦ìú¨¬8 FZ xM‡íIì"5ÿÍô¦>%õ¥>D†æ¨5”.šÏ8ÕRƒ2eUã­ - ±%8yQÞ« ”:ðRDá2QæFuÙÂé x±åª”3 E Ûgý9„#”‘¼Öžð^£7+l×+^SÉU®V0eÚ&-+rD€¦ú²Yµ¯-!ßd¶+3›)yDM÷y~£TØ_VP2ÃXcøQcĵX­$îÌ'ÔDcœ  ¸‡°#äòKÁŒÙÔz¿Ç›öT³¼•'Sf¥¨yÓ Vl¥lÍP 2y/S4²Ò/€v±Uñê–D§wÚš"GõÝEëÇQ=ªÐ„øþÙ'ŒÝ).æöj*Ϩ)´µRÜ€Kèmè< X8’½|µDÜu>X€‡ñµ!ð09 w¢ù@ZuŠ`²é›’+ÝîƒØòâÊ&ì’±¿ET³¤âÜJE¼ÅØô½H&ŽNæÝþ+Ô/ËknaÿíØ±ÿötì¿'þÿùŒgb,(P?EbC%K³U<õLÈÎØZÂk](;=xk£º…7DÁ"iä³ç}Á]3±¸îW9B²lœ¤Œ<’XʈÆþ¨ø]Bƒ_'”·œ@à]‘H¿âZkm\=»äÕ  ø+àø-LLc]©®å‰ñ–FmP&@¦Z%j7VÕÙíœ (ëŽÁ#æÂ¥µIBF5o‚˜ªr‰iŠö%)Tä’*NË÷ÖKep%“ãêboÞ\¬µí3É)Ô<ñ>ÜE(HÒ÷à_PBÀ B Û‰…š0Ž®4YFB×¥¦ó‰ªÝåD-/Ûj¦Nî¼ Ä'qÈQIõ7†wD×t± اs~Æ| °ÁÆ;L'Pa-'Éë˜ o°¦6ˆLÀú7@òÄ+® ó¹/ÇPå;¢~Zè‰!/¡1Õt28džy‰ ‰÷Be„ƒ\aVërQ±øè|€ ³(ñÖ”`˜‘Šó Á_ê:¦©Ô,giŠš0y•qÖI6žE-.Ê€[¶´¿ö‘Å$À¯p5T /#Ue¸B¦9¬î¸TI]Ï¥ \îï\´û°G,¡ufë…ONk'efž_âü°N«éQǶi¤"ÓŒ "2˰ËÙdTÒÞDåÅòMÖ:˜È„õ®lÒª©y‰WëE0¿‘¡,ýPYÛÊ1±-„Þ¹ØYk Z*wgJ ÒR?‘¬ÙüéÝE"y–Üm¤…¥to3Ù®qýÛ›µªéᄽ²ò™Ér¾²s¤yrm ¿p¼’SÀéð+•Éãrýÿ_E¹º"I¥±i±Ò‡=å¸_ÚÔi*¨r±/Zvø“CÑÛ9,ƒ0Áüƒ2tÐÇ8È"“©ßåQ}¨^si¬º¿›}Mç(ç«% óXâ%#ë-'}µ&2}½k«<ã×ö£8c•61zrÏEÀd©¼(J¬^—·ÏÚD@˜‡¨‹Á–øÎ¼Ç!™¼ ÞÍLütFØFç±q\Í—ÎMgò<h%˜÷0nCTê¿-›Q&Ž Õêͤ£"Ù:² Hè¸1ãÙW^&@À9„ŠMొ ÏW;h‹rÌümW¡†,¨˜‰~a‚ e[Õ@4…²—Çw³¢"¨§cS ªü«: ÛxÍRÚ)žü%)ÜZv)l¬¤†‰= dzÁïW’°È£ÁÄ?ºÆÆKe ˆpÕ¬˜\ef}3·m” Jmlâݘ}õ"ˆ'ÆÇeÔ“®ÿUf²Œ*àVùßûúMýï`_oGÿ{Åÿì‹ÀLKìÇa ƒfUq¶µœjV{©ÕÈ‰ç‡ 'š†#Ü^¥(w‹ 1+ÖxJ7)i˜¢vU½JÀÿ¹FXKÄ+ïœÐ)’Ó©9Π)]\Lfö[07ò6à†V î*„¯†×µe.É:¨fja¥#·sÊÃæßHŠ”›UÝ9<¼×#_@zçYŠ [Á„žC@!@*>Ëj¨îƒ7ãîT£\Æ-”EC-‰ †“`ó.™Ñœ[CŠÑ[[ãfâ ÕRhé„/÷¿<ÄËüÛòþ_ß×?`â?¬ïØñýO›`¶T,–½yv³­Ã³½ÿÑáI¸ü‚¹Ýf ×·ŒÊ\rp×d\0Ï0@ü¾GRdö¬ð\žó~ ü¾Á sV^ðÝÑá…×]^"Ë$ù°óT‡ ¼¢ÑípA1(!¨ØÄ´(ÆàÄ¢sÐ>“®8vD³àÚ lÃn0‚†È¦a¿åiö\á«êªP—Fó„.SôVZÄB83¿Ý»Bä¼ÕØ ”TÙ@ %Á^~¶ÍÄIáµ)¦2Ñü˜$¤¡¦£ Ì9t(ãò:“¤7QÔIt[”ò¦G zå-ð&¢0ZÜ/<ÆÙT+ÊVKÇ,3lgZa609–ls rJN] é„.?,!!"ų1?•lD©ElÁAçÐdy?8ÛîÏÀÖWÚB)v¿ÒER1–ähò„0ù¤ά8{+“‰}O{ >lETe‡ŸU†B„ðƒÀx{R‘Œ¡lM‹C ;7¼5oxzHµTÇÓJ³5´ÖÈ8Q z)›[³ÝgÅÏkÌVÄdHQ‹ ‡QFàPY$ZÞY€%kØÓ)¯‰ØÐn5¯°ÈçKMÊì¾¼6á¡!ðwžƒ©¸šnFR3ÈM-¾ô #(%ž –·Ø¨‰ ›(’>žG¥áÛHõUÈd%¥ ¢šÆÁ_—, _OS®Ç×ÂThè6™/ñZ`/Ò›Ÿì㯆Iíª%ùT¥`!Ü"Ÿ¨„°Sj PxpÀn¿BæFNÉÞJ>ÅîƒjMÖ>|ÏEcš¤z“¨‚˜úÌ= ¬Œ—< æKÃ[ÛdÎW­•RôN°¯­EŒ$¿@fDdŽhZ2 Ù}§_/MqP㱄j¸·“ ÙJ òÕ2ÈK$ÒJLB¤Ÿˆ' 4 -nIÂD—[§.§Ê“£êšñ¨–:«)í‹ ÏŠ \ ê²äÛ"O3ân€Fz5D²ÞÄ€t"&”Õ0¤dt4Bõ>ÆhÞñ|‰£ÒÒë3 ›Ša9숃[&¦'¾£}χ•|ë)‘ŸNHØÀ»Á¦(®?=<H­ŽB ΰ[5¤ñ¯—È£ÜñÃ\cFdz_ u„ ËÝr$lcz”ê ò~ ¿ Nþ1ŠY:ûåbi ï‹zt""íiÅ¥†ež££«º°Ä°£ˆ •Ú’Àí:S¢ONþi˜H©t™—TwlsGp==iRú.k('±…èKJÂÌIÆnèÐì5âðæàCä@‰/Z0bƒ<»Í”¤i»ÂÁ(%D¬MjÇÐÚœR"%'Ø*ÝxV²kíTHušø@O¥“–åL¶D¼ÿÍ7ã®Í'•“þ8SšqÒ€† :øã‹ úÚmŽvB[ÈÒ íH;òR“%Š•ó—-ä£ÃÓµÉÙÁêPKÍrEÍÍdË$¯ºl€6+ÐH¤ ˶ðt›¿$îG¹­öV!ó%ÚÊBëB~s7D°<ƒ“µT‡zî ’‘Žt…ù(1IHoJIÂ*tAùNòOØÁ²ÍS]-,†ãÑ£˜uÖXSŒ«§Qp¥d&5‰ƒÓ€Q,+- S1 µ6yFH­íW…,ŒuJÚ#p¤,yCçìU«Œ(.ÝÖ÷ⲟlš¬v¯ø;´³ a¬ÐK ¡)›Ó:Ê'ã&q½ö@–1„²¾½dˆI‚â£ëØ|’Q¸°ªAçdpðgNÂ2I-¨Oú ¿ëfå³ür©Vq»”Ø„A¨!‚ÆwŒFýµˆøƒ“!‹t™¡:µŒDêßW‘­“8–ö¸ l6ê)T==¶‘GAJS þ>dE…'õƒÈrÈ7™ļ¢]ð#L’ckÔ7ü¼œ[¯WÙIçºçŒŒYdMƨðN±hõBèÕpü¢n&âÇÑ6NŒ9Œ™žÚ eL  þ¿xè©GèÈ@úùREü èk¦Ôï©–AN¾˜ä @˜J#þRK—þ(vE«5DDð­`¦è}8paÎWy;ÊJ›@NSI4iÁP ³ˆ‚±M‡¬Ò‘8È— SS¥5’¡ÊJˆÿU°B 9¦}2²Âá2JXÃÈrê±Ê95¶Ó ;Ú» 5Ù;3øTÅ6¡”Z+­(>@ç#© k¥àxYG•Šé‡“bƒÝ.àÍ _±ÿÕi®ÞÓ†û R^ØV-µRÍ6o››ó`ÔKI%@Ú¿Á’ A1x8©+Û¨†]F-ŽÌmö±ÓŠ*ÉÃÚPAøT1›"3‘`:Å8ŒY:âpëÆ3`J>+aFyS¥}KR{.®ÅøÏÆ—·K[}µ!DrV¤ËtIˆµ\ÐÒÍ”½Ê4ŸMN/ã'ÄSDƒ!ƒ¼ë¨£1ø°(-Z½Zd=í2cÅõ/U(ƒä ©•õÎ$!5æ·±H~Á/3“ýâo‘ðrŸ=•Ö9‹Í>H„"Ãß9ÅuܶŸàæ‚Ì6gî5‘l³žRLʽ»‘BÓ“D©•ðm€–å4+˜Ì#ÆßÐ:ãV¦91tCÄ,Y±QEu튰l¤™j;ìÏq‰%5‡ d¹‘[wïÚ¶s,Ëë. -1çó<' ¤Ÿ60EžÞC§‡À<‘³FÝâTbȪŒDÝ"7q#—„Jº|EAK(‘BŽß„â´ÉË-ÍÆžÍ(Ñ·Sú+-›–ÕA'EEË T,)¦'%ËÃV/#€c ‡f›—J7)`t]­ùuL ˆ& AÜШXl äâÅ>7˜æ4C™¬jŒ@~!¾Wacé²JÊFɾ05<¯”1Ô¼ ­öXðýý%‰|1)Š)öEUdZ„‰ oäø‹•Ñ‘‘ŠÁíEu©Æ³$LÙÅó\³gh÷Hnhûö]ŒlÍí;w×ÖÑl[ù@ÈèË>Ùõ’vhΜþ%ðqܾŒa˜ ÕDÏ?¯œ6«êhm˜þÇÀŸšÅ‹çoìëé3ðG—QW»‘‡FeþÂgõµŠüÛÆt•Ÿ‚ ³zO泦ÓäÊÅÍü¢t„€âÆãóD† ûìÐyŸOÒ—Héè<žs–_L´ÙY@C@c…´¸@BÉH»¬¤’ï44—êtT1¥ñÙ¥²·¶\Úïñ´=™®øY³±#ŽØø$ àÐ!³H(² }9Í WÒÊ^O6Jå"Ý~lÊU¶Nâ0àÃ^ìnQ®; ¯PÓ¬–Í4ØÁÙÃþ é=ò*ô·±4‰vèÀ*”+þˆ– Œ¶n‹äÚÑzZÎUwié\£­ ù„>†»$ƒE´µ0óœÛ:9]|}3 »Ä¤uMæi¤v—šÓ9Ú²™¼¸å'1+įƒ¾µE½8¸‹mU¤¿sÛ Ö4“îŶ›h¯åbkÆöÍ©û)£ESúù'ý¾Ý zU¦»D 1°K¹Ý8±Ž}TšÝĘ8"Ù^ö”È3aÙ6R¨Œ?1RRÝܪ„¢¾LøÎlÛ´é lm-A5´4]f™J~ùH° -êëÅp+»õõ£MÒ—@Šš!Æ=í4ÂËÉów3ròô]ð·þXggí™ÈÀ;›K‘XvѨÏdÆ·ÄñüÎíÒ®b»ù1é öAÓÝì@ÏiÌðrP4 í³>ˆq9î±vHºëÏ£ú î§É8Ö{I‹_bÌr*ú$LÄ¿-jmbÄ{®‘P±ˆ¡½©¥>,T 35ÐÝUÁ­ÝF9^°Â«saij 4Rä+DÙqùrbFÁкDêU9b7 Ø*¬áɆÕ,ÞJ®Y+·©KÉðO)D¢ÊÄ9pMý­_S,?ò™¢„ö¦Kªl!‹dø_^ÒèVÜí6ù/ ¼Ï‹¶« ÔíJI&ïçÈF|SùR97•ê›—Ô5Š#|EZb h.èï%Æêëé‚pÈÁRs²éÐiÔiâó5Œ4&$döI³î .Ö%ùÿR¨Û.ªŸRG¢jmǪ\ø{×Ñ:wñ¿šFŒNÕͣLJÌ\MôXwNç·‡0î"I¹êÜŒ¸È` j@è 4L-†j4^!ÚË%@Ê–fŽa¼ˆJô-Mä¢QŸMZÓLq GÔ ÍÚnÞlë¶âˆŽ¨•s^lS†ºHhþGN€À¸Š )U¯ä kúž‘çî㚯l¼žg'úߘ¨Äÿé屋ÿïˆæÿܰ~C'þïXü³G÷ãu%ež.…’ËÆ\°K_ó 4à£ØÑWJ8XäùzjÔ5d°PZAÁ•‚6B×=/PíØŽsi†î%Æèñ6Ë3ù+¶ì˜.›˜-ǽp6Ô߯ a…kÍZ]?®—j§2÷1àÏ%5•GY=›AÜ DÙóšigõêÈ  `4¸á¸ÃBãaÝPƒ‹v5¨%Ÿ ‘MÕm+ä?F£†ˆÿ zÓq¤J R±èšêÿ…¯ÇÒÿu N[žK þKÿ†~ƒþoèÐÿãŠþó7gå—:$¯ä§=4˦Tß x«åí2_¢½+£[þ¥Ú5#Åx s¥õ9¾¹h]È€©““äRY{E8Nb‰˜ˆ>Q©f1½êÊ(ÈòV_àsìı*é3mŽOQ@p£jØ%£vsïž]{Ƕí<'7´çœÑ¬‰+Ü•Œ.K7„D–<¨Â0¨y€±ãáII°Ž_(4jJ~¦PíµF"qU„;GÒ €Â¶04AËêá83Œ/ÏAÖxs¶6?ážTªLùÙŒR›¤Œ.U¿Ù¨ñ%k9,˜™‚\P©Ègº?mR>ïA¬“úH4ýÜÜÒª‚°vŸáÍ!ƒ†RÑ<-T›Üm9 5¼ŠÅLYŸÐZøÀ¾•CWSÇ2;é)3ªð½p#ïÇ…¢>s öìeÂU6n^â}›G›É)bál'ˆ•ÊDÉæGX¶ð?¥&þþ¦ø˜Üÿ½}ëMùoÆžÁÎý<Þÿ éª5äø#›¨øÊc ¨›1Ä3ƒWɽÏH1.1çÙ(ÅÉLZY ¹ ¼¢”4Dªy[H<ã® ºÛÉ_ðc…ü¥;Ý£âðÆ$cÉ*nØV*6„c«X‚%eŒÉl5I-ŲС-«¶"ü¬|:ÛÔL=ʸæ\–aÑ,Yß“àŠ²ú5Ñ;1èýÀrAµ ÿ=6˜øŸ;òßqIÿCmÊ1#ÿ¦Ï6m7……Š9›Mr+è¥ãZ¨Ú1¹<ÖlrV^R»¤â¬Œy6‚1¦¼pü…¢·C`ãÏÿÙò±9ÿ½==‘ó¿¾§sþÇóê¬OÀó/Zr‹Âÿ¶3)Ç?çÈ«j*„ºŸc‡&ÊßÒƒ$ø½¹iýØ…oƒ+Öáÿý—’Á2ªþÛ¡ÿýƒ½ýQü÷ý8é¿Ü Šu(½³Ñ­ç+Å|­ˆw§g ŽävŒŒŽ32š;ä"ˆÐÁmÅ]°2œÊ‰ÌTÍó.óÔŠCcc{¶µw,¦jïlT>{hûö³††ÏÏmß5<´}¼ <=‹¦@VQ"®¼9\#fËØ’‘ P^øKúiá¯Õ«sèDΫì¯ðM¼©C‰+C³ZcdzÉR¥èPÑ]1¡){­aäa`Ï®­»\È×Z Ê'–×Ápá¤rÊöuÐ…Ù)OG@Hpreë`)füZ]ªkKDÊ\róâ>ë±á`ý¢ý€Íl²ìÍ:i'hÌÎæk ˆ¶¹ÜË %¬ ™¶êct2éI0SÐêÕá¾RÖR÷¦p™Ú© y£ÔúÄ}à T¬Y1òMbÍÚ„ÝÄç·IÌ´Eùp ˆÅà?š×Oì¦Ñ$ÒrˆÙ´3ž¥Ná1ïï‘ Ã›°›lVÀ'$)–ÁwFÑ«ƒ¯%æÃ>dS*ë¸ò’J÷AµäxOvÑeRc<îÍ.®v0ã…™µ+Fo¥j¢ k¿ú[CkßѶ¾Ñm´²û +½˜áUWrXS[u£3m,­3^u ™Ûgiý…µ—ÐeØ\X:¬þ&ðA`§±ê¾’-Á€,Äf1Cã\™Á®ÃI¤@E!˜§´Àyjgäɸö–ol±ƒ0(Vdèy¦.‹óމŽT½èmãL$¬ýaó€;¬4ΪêЮÆAT‡{üÂÆM5$è®»­÷ôJ¦í*.snÖÄG{+e@fl‚Á—Ä|³ãCƲòÿ¥ \™ùz ¬¥4ôfÖ;¼¬P­ô¿ýzuþ¿oýúÿlþHÁ/2Îuõ©µ§w-A"ئìÂ܇»„I †ŸÂZÓ~êå¹{… ¨?è3pó“’û6Ù87~›ŠF{zìÎ5»uÍþ]1ŽÔÿ…HÌùGßLbQ­ç8ÔÃa+ZžSþïëëíøÿç÷ÉnŠžhzô¥$À%Ü¥uËŽLG”¸©´#$÷þžÁHLUêè8—rþ—)¤Õù_¿Á°ÿôõö÷öuÎÿ‰rþ¥¡¨éáßO¹’™ÈCÙ—|øåvL;ؘë˜mºJó³~ÄçŸÀð h}þ×›÷O'ÿÛ‰sþwÐ6A´¨f¶Ña~u/¦¥)Wý¡1=pdç_`®¡Ðšÿ4ÏO‡ÿ?aÎ?Ç :&€¾%;À±8ÿ^kW“´¼ÿLý_OoÇÿÿD;ÿ^t€M)D×½é…Ã>ùr3ÂA§¶\ùW‡é_Öóø\\± aŠ2Ôji„ åù_oäîëßБÿOœóÛ&tôÏök{ÄiF–|øcwbçÄ…ó/23ùõÇd>"`ëóÑÿ °â󼟼éÍߊåO0™Ïam9¼±„ÊÉt8ùcyþ)µ[nºæ7ªztÏoäüöõvÎÿñþiŸœÛdŒít ^–{?º;ý±?ÿ³¾÷ˆëóß?±ÿõuîÿæüï`ÛŽÓëD/U÷Ù‡i'lÆUþrþHë·„óßgúÿôlèïÜÿ'ÌùoCíG;ié'_¨úè…¯^縛ó?ÇVÓ¯1hÍÿ›þ¿}ë;ú¿çüïÃmÒš ,ùôkû¯sèÙùoTöWüy™kåH€Öú?óü÷ötüÿÿó¿—öÉ.ŽáКX‚Áߨƒ)BæãíЃ£~þ1õ¥wôýû6DäÿþÎýœÿÝb›4¥¸™–~þåäì]úŸÎé?ç?L’stÏÿ`_ôüwüN˜ó¿Ol“¦ç_n¦œšŸ§}B ë§½)×øÝ! G~þJå—ÃØúþ7í}ýß qþå>9 6@û.ìœî£þÃ]Ë‚Öÿ;rÿƒM°sþÅ?HPªyrËKt-…(I"7Ú29*$ѹ ˜7µp‘¥ìïDà@4‘,×êZ½:_›Va¹¨à.©Ý© Ù*Œ’Òo×Ô&¼J zÃÎZA¤"HÝ*ÑEuì ÞI·Sóf}ÈŸQ.czF¥âÁRBTPoLM9S56nùri¿§£’u#p–@C–‚_™ój²O¤é ¯J¹?ê>&ÌrØŸ„ý¥|•|ƒwÉÕ9}í¬I¼EE¡üß’uá„¡ÿ©%žæeЊÿë4ý?ú;ø¿Çæßa‘w5¯Æéi ‹<ù®fÓK…8ËLÇZÎÞ x˜Ïÿ‘ü¶Îß@_ÿ¡¯£ÿ9ù?Išs"ÉýH¥1ë)ÙD—NH\g<«¸ˆ–¸™UR%ßâf2u¹ûUHAÞÀ¸Y&C,e3˜Žg—RcãÆH6p{ä CwªQ. †2P° µø¨Û¼ ƒÉÛ$WÍ—j¸*ÒP$1W—Å\ÂȺ9ÎBÉ+³•¶ÃØøKü¸*>#‡HigNíÿ 6.08ûÓ6ˆPHÏ %W¢º†’ºØ¡3B>ô /“kUý¨![ÌfuPù"‘ü!­|2ò>å,f•Òóm¸ÀZ2!³kKSr0„|˜TVE‡k&Ì„üTÊ…‘§ ;XtN;È»]L¨ÅÃ"®òw¦à7*uHº×ël¶Bn*eÑ ï­ ¢ i:šoÀ¥‰gLÑð–þ)¼ÿFæïöô?ý}þKïÀ@_ÿåaäÿ—;õ7kl©©¿µÞKÈÝݤh|6q¥Ò¨R±Çcò~·—òûèdû¦ål7Û÷ ”ç{í™IòÒ´“ƒÄ.ìÊc?”;·“½û˜ÐÿeÌüÙ¦ýo ’ÿ£CGþ;nè4õg‹DOìØz…:?ÆZÒ"HáÐkÁƒJ?1³ÁëT|ºLª•êìe>ÿ‘{ò‰A+ýOOÄÿ§wCÇÿïx;ÿ&g´Œ´@¡ܪ††%Kyƒˆ­ê bÂ,,ÊH7GÈÄ1¡CÍÓö¶ m‘S‰ézµUC½<æ™çÙØ šŸT[s¢­9‹‘æôä¿Ú¬ÔIx– X×ÒÒ«¦á5šb|¹UŽlÒ¶î'ºÞÍÇM•<£ë•tÕš©¬ÂºãûÁt®ñœÞ¶ž •o–™zí$aîükëþ_¾ÌÏmòÿ&þgïàúŽÿÿqwÿ‡©Ÿóʹ]Ùvƒœ¥ámÌ8®ò»“¥ôØžÿåËüÜÞùïÿþÇqwþCær‰ÿl£5áº!—±Z;_ <›AÙÌB©xó| ™%H°¶EAÓó?S¯W×q#ñòš€ZÙØmožÿÞþïÃyþÏe{A=úçj¾Ýì•À]·nºTŸiLf þìºZ¾°Ÿþ3Yö'×Íæ¸J`{ÁC¶¡xåsÇÆvçöìݶk'üÞä$ÔGFŠßÝCcçæ¶í<{?¹¬´|dÝ3òܽ#£c¹#cçîÚŠEõGFyöjÏE¹Ñ±=ÛvžÃ›V¥‡wíÙ9–»h÷/=ìWê^¥¾¢di^üœ‘11^ö§9©]£cb2ìOóí^Y•ý]áså: Ÿk¼Þ:²}dl_ÓŸÆûsG†¶ŠEgowíc_`Þò?Íiîݽ{מ±‘­|I¡ì8›`甆±§iŒi>–4ö™mgñÓ ì³m ý1Ü sÃC£ÃC[Gtəսpíp>(°-kNÚÛ3´sôì‘=¹‘û¶ÂǽEÞØªÓŒ•7æ’½kÏŽ¡1ÇüÇ* G ¥c …ôŸ²W®ó*™…Ùò±´ÿ÷oè‰Úÿ;öÿcòÏ«¸lÇáp»BG*—ï^µ¶¢‰ÏN—á=š|}¯Vd×Ràp ç„¢üfñš#¾„¯kÞ´w SÓ;Ó;o¶Z_ßPúGöªè{Sñë”,œG1Ðë°4y;²Ò3ù€Ê4<¬ÄQÃ’VDWáNygÖ/ê¸T–ÃUdª9šò0³ÂhÒæÈöNë‰Ì ~Ùe»×¥©³A'¡±Ö"Ó²ë¬ô¦]Ùfb®7‘¦–]‘ô>íPK¬ÿú| XæÄÊÈL%æ^óYB1ŠÁVa»"Ää[ŒŸ¦™\ ³,ä+NaÆ÷{ï(u£]%œ…_¹pã2Æ_½“Gu…gÍÉ‹°„l¹æ+À‡CT TÆI9®6T&!ä«Õr©€N˜ëb§ÁF µ‚&·/ÜEæge“g…Kõ.V•*×ãâ˜-›GýÔ øÔ²Cgo—jn:ÓÁf]G·²€T‹Žˆ­ ½\X+Ê"ÉØX ì©áaCl`^¶Eˆ:í ÌȶmÄÌé`_2fî¸t@`£ÉŠ.ëAdXŒ]¦ü\¾TE¾Ì­ðq«ùúL:< .O4i¦›¡Hµ°ŸHp:ëŒ?s”g§ÔCÔ£-HxY_>Ÿ#°T“ðJEåÙiñ‡¶ôqIsÑ/“§Ë]äcnx½‹’à°&Q´/,Ú§t3Û¨7ò声åFÀ?BÍãË 1§Pã|=Wö˜ØcßU§½ Yã|ç°wáühÛNz°WæJE•`{ò…zyÁÖÕvSl¼9öÝ*Ôñwl ÁSÇŸ  ¢'- ^vÁW–ý ÊÆÖ•»ßÕk‹zÖ+б¢é‹qØà¦æœ7Êxg6"|8¿²Ñ§fQ³¶•"ÐJ8òeÇ\»=F¢Øh9[°²7§,pØN;¨¤k[tØÅËéòZx•×^ˆ!ŽZkШϩ%¬£Ô“€×­h¶–FÖNt¸VÉ¡¢üVŽ%0Qv(BäÚêM\ÛKè®k™øÿÙR±XöæÙ÷]—oÔg0þcyô@­ô?ÌøïÞ ýϱù'ãPu#>|©ù³CnUA4Ä*jÊa%Ê'Ñ-!Ý\Æt±ÿz•9ݳ@ ïÁÿSÇÙÂ^11šýW}È ²¾Ÿdõ_@ºs@7‹Ï seÎu‡voËìܺ{×¶cÙ& ÒÛÐuÕL.ú"R7g« jõ {ÑêÚ_gÉö{  '×°tp±Ù§È1ÊRPt ÒžgíÅs|=Xq±2ZAÁ9åJ•)Ÿâ î¶^¬-×¥‚%/—ýÂ0³Y½ÁúLÍŸORt—´Ô«ò'Ø'ÀÍå×J—QúÙŒ•óŠ™DŠ]•eVNX†ó›íƒ— ­x¡æ±_É-¸ÏÄ.C¯ D0Ý2"«•)UØÈ™ËX¯ÄJig•,õÚ°Ž+nƒfŽl”Û†9|Žxú_ –Ë ØÊÿoýÀ“þ¯ÜСÿ/ý—o·ÌøôgK×±_ðj•ÿ ø“­£Ûn#L†°§Qê¥}è)<¼æ0Ü0”{(PA·3Äd~&NÃ,@¤&ižXf&ŠŸÈÈIÆnÔjì}yA«ìW˜L0á‚i#‡K0‘?‹¥iÆ\N8 FHî<£G¶a¯Iìká„W„£®š,û…ý:9`Ô*4¦Â‰ šg$¥T™ñj¥:®IÚ—fj°Š€(±$" H»Þ²à:ÔiÊè¡R£änît³A$ͤQÎêjNlq¤Ï šu`&J\àðP>¨ZIk€_œq²ò{ 9èúç‡W©^‰žÊâã䋚u\vU”g•‘+i¥3ÆF¢Œ šû#ÜXÉÖ;C^œØ…GïÂDä&w”ý+7‹è"~­åøh§¥Ê:~5ÏÄ5^)ðØ\ ¨Õ\:–ýe—ÿÉÆeüïÞ¾Þ ‘üü¿‡Ñþßî²úÆ›jT p`ui'_,&ËùI¯&ï';7åÕ ì¶`4gí™ÉDÿgE X ˜êp[ŽcKà%͇±° 8zðþ‰k¼‰ f4® šú«H¨ª£Ðv7:˜=Œ³R.W Ìl†WCG€?9…‰§£=-lÑÅV*äîØ:к#öäN•E_Œ_²ñ,}ÌÖߨCŸOXúÏå䣙ÿ±0šÿm°ƒÿu<Ó•nêHŠÍÏq¿KWPI€¢¯ëÎHÿ¢ª_l §ÜŒ _Á¸½]ÒŠH-¡Ip88<Ò'jÍEûû_D¥¬çùTÿmùÿ ô›úŸÁÁÿwlõ?´ ŠAYø·«à‰èû5ì.©áOK½?/66ráXîܱÛÁT©ëfê³eÓ}N@„quÅÖÑí®+¼Q»L9Ø g(täȂ…sÐÑóµ"€³6&íÿyk„;?ÓµDÕãŸJ³Õ2@¯úÜ0ŠÚ•Iö¤1‰KãIýB›¦ ‹aC1k¸¡» PL39ò©¸NÊŽûa´(8ƒRU@ƒ±ž®P[j­Ð«m MÒ³Ëc+è)?§KÃæ£Îi‹Tˆo1Ì,A£¦ª¥Ì†Ø.¤¥-| \ qhç®ù¦3]ÛÅvMÅYYÈ7¦gê×'­žÓ}Уø´Rcó¸ “°çJ•¼º¢­‡ßOùYoÑq±¢°ï®Ôz£¯‰òCq ÓgNõÐ!}ô]¶•r 8òÚx oÉOÂ*ƒL»a6Sv 胢ªNñ°ׇàüð :åÒ”WX(”=õÜP;g´Ù+-öuÊZçñ*ã{øÄÓp†²‚jŒîW\AJeÐJ2óÿgïÛû›8²Dÿ÷§hðn$Ųüöj⇠³Ãã‡Ifv…¦Ó–Úv²Z£– x?û­ó¨ªSÕÕ’l ˜‰rïV×»êÔ©ó>rhœ¨ï üú'ÿ¦6çávì~`/dâõŒíp¿#)ä4ïl+^Ðý²Yú²Õ­ºÜ´£ù™~þ-›œ>ö³ããÄï¨Æ™ÈæE£ã†š1”ÅUÒ0°åTÁéÉ£S´Èj„1«·Ä²˜Œ½1Ì’~©‹ÞúæÍ ll.íÂh `q•O'±‰`.ÜÊ%Íñ,õÖ9o P'õÚŸj Š˜2•7ÁØä¡Š.èà–ú¸Ÿ ã¬ÒÕnH!Ïz $Uº#hfä9\¡©ÙÒ}âLîÔùgÃí§¤ŠZô À¿²ñWË1é |xc ÀlúkóÞŽoÿÿÁƒ%ÿÿ%è ¼P‘ú¥’¾,‡µÈ=]»ª?³q# õ~ë\¬éˆLT;2´'n°¾Ót0Â𸠲-ÕŸèhÂ~¬Û¸ºœèÆXQíè8Ù°MÆSÔA3Q $Bê†Pvãa͆î©\Órm¤‰"p[$©íLÑ:Å$í—û2Çï# Q²JyäèR®¢Ÿ©CáIS«iŠé„`EqJÃþ à°[—jê¸Ífþü™tز@f êúø*ÐW0AEM?PhÐÁ® ^¿ÝŠCEG…Š“­`¥à1êóŠcFÜB¡úª·™?n±Ófîb(¤òçë°g• ]ýBÖ{`&Ì&]ލÏ#cC<NIóÙ/E`5´ìß‹Ìßûuæ¼¼DšH®ˆJŽA„êwœ^Ñf~ÄGt3mÿ^À† Ta%ãP¹x;„_/gÙxÇ„œKÅPÇÙ°¯!5´nOÕÏ5[ ¤÷£}þIaÇë)„J;6Û_3ú†ÿnÌ}íLå;;aa:àÜÞn Ú×׿ת?âÄÖñ‡è àÑ¥"ÇJƒfÎt_‰&ºìkNó2ö‹ ˜ôFÀü8” ˆŽóYNöJi9w§Cµ_Yqµ¼så[M¯„Ú:¦½½‘~%#wã­”ßÍ}sëR’܃ûE6QWW­ mz¢zaÙçÅx³­Z”¸ØŸju>Ðû/|Zž$’³£~²XLJÆÙä¢õ{:Î÷%*tlVÜÅInõ«¡¼¬wtÂ+mæ+±€KúÙ,l|dh p5ï |bj™˜ŽID20c×e^É<‹SWcZ”M¤žŸ»KÌ̤\0s¯8Ù®T¼¢6}«<|µ#‡dq¯žÿø¼½:·ZB.ê¯>8 ªç9í·¢—jÇ{®Uñð-ÿ¬ì4Ïё=>,ì´ùЇw ~r/ÛØ¤H µÖ…]ýpÅ›ë x2ü•¨&ï[P!“ë›O¸$‘äS”Ûï5/Ùµvs¦d±£¯¼xã3Ò1|ÖÆ¬¸ü‘§Wí”<ëÊ€³ #äÆC×±ÐK:º1De7†ûÂáî+ë£fÜç¢Úê{í Wüì¬u±!ŽXLÎÔ‰Œ.o“P¥‡2x~+-UØñ”Îy­M·õJ ®M£• /ö%õÇÊDàÌÙ,DÈéTSŒzbÌn芯ÔJ (ÿ;Î7™džýσí’ÿÇÖ2ÿß-²ÿY%j"ƒ ¨ïvTgÇm$+¬íƒ„¢¤‚#H*¸—Iβ!…¤‹Vôd]N …)-iNα«\}†«ÂOØo“lGÈ4öó¸Èä©(Ò§,BKê©,µô4Ñ ´°t°"ôëßX´U‰rð?V¤±rtͳúÆš^×ôífpOøþßl* 9òÿ?þëƒû»Kÿ߯NþoH'÷6=úù—gÿýøG0óéN‡oÒ¾oäsU-A•0¿Z(?JgHŸçÉd½‹?LOòI™Ã‚ja°sÂh q6M'‹\wWÕ6ÅðÈæ&„cÓó½è[·”%išù~øêàÕ/‡ñßž¼ú9~ö@:EºCÙŸUÄ“82ð É]W2Âr/XU°@hXWæÜPõXÁTp¬ ï–͉Ùä¡G‡[tæ3á]äBfð»+hV±²2µ—7OGt˜NPMÆ EVm4_$úØÿR³³ê*eÍÈ&ÀŒæÍˆ™V}K}_Éвl{%?£ŒjÖ­–2ÑÅ·ÕÑË8§¥;æHŽ®!aœg7ÔX@ ÊR«¥ã¨¼Ð ¿à= óÿ«d¯Š¯W„˜ÄÁÌj 8ZÜe Kj]gôÐsç½ibÇ꺫Q^LX®Ï¦ÞoP:_úé ¤û •“=ÞÑåvq?™$ØÊ|>KûYB]·å;”"PîO­Ýþu-}pƒtx29¿ê,ú>Ú”3GéAA8žh4L5V*‚:GY²õòàÑÇOž½øEŠxÀ ¶:±·™xø šŽ‰K©Jºƒ¤_©åÅSGY#VFäÜà§óÔ wàÆbܯ6 N5è>ñ¤fA({*¨?U+9;ó°ohº°®òg§ GOè¥]‰„Êf‘gN–¢J­òþ&øDT £5K‘l°oªäÐe#g õY D!@ué¿Ô~ð>öʬ7¡@:ºz8@vñχ?#ô/Z¹4ÈUþ[p Æì.Ð\c´rL„«ýø˜ñ½ä@‹í€Á3ÏÊìª)1àËÖó!‹öE-ï«%ï³è·`à ÿ¸¹,Þ̯͠¡ pˆøÚêû2> ª æSs¸Y¬†{¦#³`Hºœ6E¨XüšL1†”|×À™³ô={°€<¡§9›\sǃ›¹"^€I¦K† :ÕæØ­šË§bÝV‘ýž*:dKn‰9£=®4HЉÃ&çyÖ ´NQË=ËÇPó XR&CM”'[NÙaFàð2Áƒ2•AÓñJÿ£2Tyð(äô6ÆC<ŸXíÙø¢^M…ÉxþÝFE%ŸyºîfiS‘³É¬Mr ÙBëŒ-9u IxIÀLmýQ”0ùP>2AäL¦±(tÜäŠÇd¶<-ÅÆt^Œ!L‘ñ»þVuºšæ¥ŽV¼Ž §v’ÆÂi+^~ÔÌŽ¥T°îàî×o×6:êZëݵhz"q6·ýVú.=Fëì‚özíÝ™L*]ßw˜ªŸêü£Ùýv¿±oF!6Ãh¶gÔ"ÔqN"…od'z]|û¯½zçu¿e§¦;‰îòòîËŒ2½T‘m'Ñ¿ö6[÷$lXûòÝ3M­³wê"»–ûºÕùÇZwíõÚ†¿Ç­¢— ë³öÛ'„Z…Â}ñÑyâfĵb;ëÑzù#܉c/Ý¢êëxúþdÁÀhéס¿à[Åô¨\Y3ªÕ]Gˆ» 'qCúß“A~” n, Ð<ýïýÍ’þw{™ÿáëÓÿü™Àf®.UK¬ ß+VK6è¹÷ç—/kb¼k)§[ÄæñËCѲå ýæôðâàåÁS§&…ÁÚ~>ëtËUðþ«+)›>Oü‡{¥ø/[÷Ü[æÿ»MörÔIìÕ3¡˜ ½7àZd!§@—ôÏ:Àð_?f v¥õÆ!´ã~Ÿp®ì;>¬GôŸFqJÆ6Õ_¼™–ãO`€—6úê¨Ñl«2ØôŠZóm8*ŒÂ lþMfhŽÚ”ÂÒÀ?ò3¹íEnÈÂR -püÍÞ˜hÕMööêùäÔõ@ÏXü*>¢[k`—Ì@ “ÆF-UØô‘÷Ño|}æJ%ß|ÃÓG¿¥žSµ±HÜ:H0)mÉŒ\°^¸ÇÃéY:F¯™•` r³™¦W„=³ì» á|Oš÷>¤öò£o¯Xµ`GÄÄ)ê÷݇è"Kýè]•aB!'#»^G ›ˆ¯I§[Ï¡6¬[åÄwµž ûé»Ê˃¥pC ¨ãOÝ„m¥B£:¾-‰ ­P1–\¨;9[PŠ©ÓN ^MÌ–lô«¼Ú1ÓǬ;uí<£µh«¢Soë§E:>zGÓâ´>s묇?ØÜŠº1\ä"Ô-•XF®Ð²ç¼ò®º>!Ô²ÞáE)¶úhz¤8üÝ"ýÎ ";t0ÊGY‚ßY},o==¥W?€EK:î’ß)ýàÄ·”ORUIƒ ã¥kŒb꺭‹qÇp–v†„ZÅiv<©ë K4p¿ëß°oXÛžY#|ôæxÎäyœµèaÛ×+i žµôûyÖâMçŠàV8«fXÅ-‚›ÛO‹Þ8£@Í&Zîng GÍêhÑDØ*2î6#mªÎ×ú[ÑôoƒÄZnÙ P%¢KGÃec.=ĉoXðTDõ´uÒŠ:˜]“µn3ê´¤ÃðÖ5ÎN“DuRC6JÏÏwßQü §Vkœþ“MròQN>àIƺô‚ÿàf:Qd~'ŽMW>Q R× .€!1† iUÂ×üÉp’ž@ØÀ}Ʀm»›®d ¢½Rýî³<*¦ „Å‘XBsõ=Ž~ —xP"<.ï6þÐñÿLvµÏ“ÿçÞƒ’ýï½eþ‡Ïòßjô«>ì¢jZ ‚Z—ø€Ää¦BoBr^&…Ø€)¦mr(Èl\E cïõ(Ý;#¢C“ê@áÕ3EdOL¿`Ø¿²ºvÿìy­›B ®€!ödB®Uµ™ú׫>g­1îÆùÖ$КŽ{©n˜<Ð"B¥¥dq~ó}µ7ªÍÞùÎõ0"±Ÿgýi2ˆtÀ ^c*«+åÉ0§±23œ¶y‹Lb›¹žw½T†˜Œ[¢L‰‰S3Ü»îÖ¡5Õ†˜ÈÚ^<&¯>óŽ8A7¼?©†§ÝŠ"ÏoZ÷c@ÉßT'˜±Q´!¸ {g{„ %ÌuñNÇÏ)=§ 9þ•Å„šÿ7‚›zÕWa^ü×­]/þóîÖ2ÿÏ×$ÿ¯@^ì7&éátIÇY>- ê§@f÷ћޟlœ1F+TNaú3j¢3®Ðµ^ÿÕIœX²6~LêÞ6ø¨ýƒ[×âÝY;:ß*õ/Úq2Kx»ô”íT#^f»Ô’W¼Ç › Is©ú“c³A^Î lê8ŸN î½Í»›÷1( ®>²4¦Ÿ¿¯?JŠžZ©6ÝVp2úWk_ 'ú<™€ 'nîRÁáx† ]¥A[Ž6€V]PP¤8„ #²d ‘‹g¥XmGÿúøåá“çÏÐШVS̉z«G^–<øÖ›ì;Ü=îé0ƒLÛÏÌTš oß:׬ˆKm¬`|Dv»ÐLLzWE­Úâ “øYŸ5õo3&޹“ ð3§öÊ -÷ÕBõjÚ,„kÆüüCtŽR`à=Ët¹2ÇPÌ@N uXí9'0ëy­ré2?DIÈ]†P¿í שze!သ*†Z~¸0qôÖ–p>”w7É‚ÿÍ ‰ß4/ PÂo†÷7àÓ3…yXWæW€ý@Sƒ"õC ˜¢(¢z‘¦.ši i|F²U²–‹1Å)ä`ør®ÎDô„˜î(=MÎ37Kú}Ýò´›˜ÕÊì¼ò[»§«pb/Xôù­å¥ñÄzûÁt›W<ÎÎÉ]V¤Î*Ÿ$×ïÎ’QB¤½E)ÎMt5E¸Ôh¿2üÇßãG‡~D'–@A-‚àÔï/—É\þ0òŸëüWóÿ¾·¹»éçÙÚ\æ¸ôu¹²Éµ¶é1ªü¿ÞA¿x(û†2¶04|Éx´M‰ëƒ¯µ[àk²íÒ8g½ül¤ˆŸV²ÞËóÁºB­Ÿo­ý³04ËMs'pˆÀšs"fU V/¦GÜy™E&^«àŠ`[»¸—Ž/›qy½—éóL°…z}ÓÌÇŒIÓËs{f½Ýý¢°G†±¾u@ÒŸ…tµ»Ôá.ÿ[Dÿ‹÷äc½æØîìlyþßÛ›î-ã?,í?çèpµB $ïÆéY~Ž"«D”‘¿jfUjåæ@Z*¤Y@ x,؉CÇ ·V<ë9½h…‰¯2L†ÖÖL¸[ÕžfDš¨MÜåÔ&YA¶vÆd : ºÒ¾S§~šœÂ"ÏrÅk¥&¿¢5z›  B€4 ­Ù ìý#„M?¨VCŽ×ÕJã.£/hTST­hlÓSÍ W ©°öµ®2˜4§è>²R­ B/Qâm¯8²0Õý9싉y/«ÉxH—Õ$ÖBƳ7% §®¸î‚¦¥àö¿€è®40âH¾>SÐûèmjÂŒôj¬FÀTlôî”?c¢É…ìIoÀœtNèMÚ}Š>JëúyÂh® ^Õc¬Ì`/ £ˆÄ»!óEÛàÓ (–Äêg¦ÿ¦]W$çùnùþŸÛ»;»Ëø?Ÿ3þÏKŠ«Ã¿ˆÛ””£¤¢Gô»ï0¬„àåã1:}â"?ŽNò.Ú'ÙätzÔêåggÿT£ùp(uën ò£³D½Xã J(c÷3k…ºú×ÝÍõ¿îîú¨lfx5Q"LGÍf¢xø¢•¥“ãV>>Ù8œ 6ÆÇ½ûÿµó_«EŠ®–ë»­mÊm„ å=Uè­‡tb6$‘±ûýF"²3ˆ1næ€ï ‹+þsüþh³ômw­ñzÃS}óú¯×ãÕ×ÿq§µ¦Š Þ¤.ÜûÚYýÇeÃb?êœu¶ºêUílãÿî°?L7jûâì2Î1•Œ åŠ[º¸,b‰­¿^ü?9ýè sðÿöƒÍû>ÿk{‰ÿ—üÿlþ_s£×â5ómLgÜ_€‘¿ w-Ü^¶zÕc¯ÕPÁ]kûûh£õíFv]&1+2õ‹ƒW?ÇOžýô\ñ]Sß}”b ûˆ@BqfècxÅMMò^>j÷³¶èhßw‡ú†}fŽŽz³5M&ÐÚ§uøŸFµÕÅ(K{hÅ##Ço8ã„„ÔÌ5*s-Ú­þ/¬!Q÷æÿÛËÀ/ÀLãù–sÃ…OÔn"6ëâüÝ Ÿ\ò_ûþ#;JzéÍ~]ðýß~°åÅÿ¹·{o™ÿósòúy_´}[Z(ðåÙP=Û`júN)…ç õr|ÀV£A~’õÔKy2Χ#6ï°%Eô6 àßBñUP®Xó|¨F?ÎN¦ƒ­…==M.ÈõdþÇ Ã€”;‡¶Ø¹Â6é  Íݬè%ƒ¶ô=Óó])…‡ÅÏ”Ÿ¤7¸”Z-1:稾`%hV2t:6Í´u%¯3?OÎ{¯*²õˆ.j3‹0í°³õ1ØÒª¿3p¥Wû ƒÓ¦ƒñ¿É”¬¶æL½ôGw€µ"âÈÔÌÅŠíÏ†Þ `ëLghoEAðP=¶XLdqä Ýím"g¼ºÜ×·ßzyÒVîÑ–Ê@®õì9y® Ò]^¦jÿSMÛ9;eÈ:¹ÇM@¥'ÙyÊW0› ¶\Ð]­”2ÞÛ2d¬ÙEÌ M“Úíæ +Æ…ÅöµF/»)ËU“ Ø=™}1t‚ù³dTÿ†À²Mík.†þKž 8ÒU¤½H¢AVLFLÇê¢ô¸OÀ´ z\Z¨ëê:¸¡î‡Ÿ2Ð+€å²ºÿÙÈCnЪ^-=wþ’g¾áÍj,¥Ÿžÿçìo7ýø/$ÿ-½ÿ›[Kùï—xÿùç ›\MÕûÝÿ—éIÎL\í(XǪUw7æ¼Û6T©W€nE’ûܶ›±Ýþ‹úØô*)vtn½wgƒR¿‹ Q9'èÝùc 0Å–}ꪶ-ê–Ûó|;ª&T÷ÅܼÞåæÓ"-b„ÙDm¸›Yy!; R9z{%Ž[¹Eàu» cKµ¥T"¶ÈiÜmP6ë½½hËpÅ’¥DÇÊ*ë%³&Ø.­´S£T¯‰ë8‹ Çõ¬.å®0~pñ& ÙÌn:ÔCs¨HïÕÖoP/ÚB§ÞjôHCúÑÆ?^n8Eàð^Û¨•»†Ié^Íuïyþ»Ü§©UÕe1=¶°›Í†È(º[o­¾/Õeãbu'&)müÄõØ«Õ[Æk¡­¯Õ7ÊBG îñ=>$f7ýF¸'òxw6êîê{(¹T›Ÿ9d„ÓTèS‚½˜ÊŽúšÅNÛ”’Ñw,jJ¬Óma@>“˜ê+J°¦á»f޵âRš&.lú¥ÉBOBd5‚ï°.“ÚÛè2z¦Ûúß³Á€ø>H¯·­9=;‹¯X²%è?zöÕ‘Ù??KþŸÍmßÿoëÁƒ­%ý÷%ù? BÊo>Êœ”@ö5Éh˜¿o¿Kbk*[Ê„oëý×Ù¬ožœ›ÿkÓçÿîmo.ïÿ—¸ÿtÓ9{ô;¾9Ö1žÏ‹—z1ZkøÓø6®Ø<ªJˆíOè‡è€ßÌ4q%ÐbÊÇX;¸˜„#ʆ²B5ÉS$Òv2{ˆdOýËÌ©YFÃR®âŸÿòêɳ?Ç/ÿ,"Árjèš ªu!RŸ§nŠ2™žL¸.;ÃiGBÃñ„K1ØN ±slZªª’ŽbTcÞ©Ë VÄUuHå“С¯`Þ[•ë9†$‹Á² a½iFç6AfSÔ7Lt©‹:AÒv_B¡5Å„LÛo:÷Z­õ­®&ÑâšÎyÚî%£l‚ùmZ³. ey’7` z^Z¯[ÿ&¯–ÀÿĶ|vû­­Rþ/J °ÄÿŸá?Ïÿƒ€€þ);ðë€uÊ⸳dÔŒÚÀ"fƒÔq1;^¨·ä@UÎŽTÛWãdX(>.®×Ù¸ÈÈD·‘én¹œŒÞá/kIçëåFAÎi×Öö,¼»Á øÝiׯð°zñîHc{kðÿŸã÷k¯ÿ÷RšüswÀ fÇüKý¬‰âŠ9šÌH1§Ð4âF¿ß°»Ãá//^<ùÊÆ*Ö¢NíÛZ@ÐhÂ=Óédœ buÄ2ÉýCúý3?–À“¦â”? -&òÌØÄÛ Áç8ÎÄ 7ߨ1õ jwJ¬¼Aq:ä —Ö墨ìmmG&\¢Íš^>‘?Ø—‹SíEªÏvEªf¹x] bflóhqÐCÈv ýsºü DRFcÿ-•Ò‚`ëûßÅœåøòûÕ÷TÌמWªyÙØ¦â®œ¶»£ÁZeÒá¡>ˆÃ¬ÃÓ9'›ŒF‚g©ÛC—zUqŒ â`:C§.  R Ï¢È{™¢cÚk‰f:QüCÿ‚‚Eïs#ƒ1dXù @šÚâNÏÓvßÒjª9<@hÝzO¬1œÙ€Sõf%=½ ¼š8ÏfĈìjt-Aióž¢n ë|˱ëìXÀ°¼8ïƒJ"y\é;5åX,¬Q^™]®3QUò­¢ÁÁã=Æ ŒÏf€b×ÄM·8Gôˆy`›ätöœEº?ÝsÊÀ¹W½…ÖbS'ot¯:Œe]wQFMD¹"v>f@ä¿ÏÄ.²tÐ÷AÄ…{SàBÿ ~qu^ꦼ4=Ö0ÍNN ¾nð’­ÈèR¦nú.+&:šÉx…Y=ñêÉóg‡MHËçÑ%‹ŽV;‘2=„4[ØrXQ«.ž¢ó¦€šdKV;˜ ŠðZ™ªíÓG¦h0^Q w•·reeÖeV„“¸€|%½‘3¦Äzú¨äӫݯÜbÄá-ïd#jláj®æ,“7mÑÛ¡Ú+艜¬„=<5ñ ß  Ç¨ËÍÈÐ[ë>Jߥ=;QW§_êT¿QÕòúdE´¬\¦Íàw)š°u¹¦à@ Ãw90¯EöËÀbeJh¾ˆ×´y4ê«n¤#Uç¡«ã`½À[V"´Óý¯»ä>¢T±ª©WôZ¾Rü±¦b¦À¹Ù:4w»!0©¦zÓñL# ñ&§WBÎÚn[6ã›ÍÅÊÏ!ø9ó˜÷Ó kXé5]tîÆš… Žân7ÄŸß›Ðô‰A»þ´%ÑüñÓž‰+™ýk{¨ÆLäãçÃÈ@’‡7fU.!ïM¨‚n‘/…þ»³ÕíÌ[´:!À H,pNB0ÞÌDT[ªó¾vùÅ#¦û¤ù_7·¶ïmûù_w–þ_Rÿg%¼œ@¡—OÕ›zqp£ç£tx8OAѯãä k“èm>~Žå/§ŠØní´6›&äD€;š*âe¬ ×Éðã®eE¡˜‹­íí{[R^¼¨¤ØJzQ·$dÄN‰ýö½›äñi¨i¸6!ðøLMŒ‰ÎšÑ·REF¹#;ë[„f÷j2¡ší»sÖÙDM¼ ØÁŠ›Ÿ‘º¸3³‹ª!+2ÏÕ––lîÒ £€ªô!j ñ´A é?«;ãÅ«ÏbþRö”:Ú§„PòöšËËf‚¼0/£V©|µbÕÖ|BEèÃ’~¦Ü‘Ï‹í°åÔV¼øÔjbàìØïˆ$M¸G]”àÑ‚Š’þ,gÑuGõ–:©dØ;ÍÇmz´›ld‚º°&óÜÔŒ-ãq—ÔXd]S¯} C¸Aäø<ÁÚ{£f‚Ä•›nT6£N+ªù*}abÝš$#Ô* ø§wõ¡C†á¤,‹Ö# N¢Ú~-Zc“qÈQ­>+â«V_šÝï®4K÷NÈ¿2Ždà Þ,'¦²ZÆ'¾7¤‘ë¢5¡!IËÐÈÖmˆ{w B±¦»¥°ëjXòÕÑp‹ º ' ¶å¯‰uç^»2`WR¨¥õ˜&•¨~I(~2úUì7i6‡þ»wÇÿs{s™ÿç Ú1„à\‘¨&%©Q´0 ùRhÕ@‰ó8VÏíË'?À_˜ÅìXh²¤Þ‰“õßÖÿ·ûúí·Æˆåðù//=ŽÿúüÑÁ+“û [ý£Þúv¿Ñ®¿î¯íC´õ¶"’~k­í×ûÿ¡[ÿôäï ã<;xjñΡjûŸoëDdj»ÜFˆÄ„ÈõE¡XAÚÍR?’P{(‡nFmCþ95 („¶ M™Ü%âp–hƒ~f}qL½‡ÈÈ僇Ãâ|Ó…9u„ B†o5I(Ð ×–& ñÇ..ÎDµä!©µa–+Ü©z:®o5ZÅiv<‘Ï™<Ø º•¡À°ð£„-°‰±ÿ{&Ʋù±9T¬ÕkÆG|Ñlâ³IöC?-zã wD|Ñ] Œ™lËúñ…liœÞ&I6U$Eâ}¶¦\¢Àw­îúwx^dü‰l¨À$aÿ‰›ÔMY/.àòˆú ²·•€ØæEù@Øô—í‚öû¬á…Ûixpºã•ð¯É^Ñ7Ž`1õBfr‡DGÄRÚ„ÅøÕ3€.JVcr—†iGe»¾c‰íYÊàšÖ…&gÑ&ºeñ2ö`6½ƒ˜5¥ý/mHú9µ|3=¯„¹¨«ÿu›èzdYJpÅI-¥¤Ç &ò퇧‚”¢è /j:…Ñ>YHß ½Ñ-z>À(D M£æÎ,¸&iø$Ðh^J1ݽ+RQrQf}ÄRØm‘úü6µÂ¿p3­ë¯dn ¢ƒšaqCT€M»ŽYº¬©Ë·…q)ç²û®`0œ¾`{ƒŽrÅ}þƒ}xbµeï£q3¢üñôî_tÙ*0ˆèia«Êɘ†P ½¬ƒœBà€‘áˆ²þxÇIh Ð2h8týVÑK†õ0e¦(©l,˜u6™ÿ)€Ño2°&ú+/˜ Ô·ÿ´ÑÂLÙ¹H»m&§êàwXYôÝw럮°…{õ=L÷²©hÕïÞ½Ó*{E@¬k6OŒWßC—ÑiržFGi:T¦^ãä²P¸rBäÅ©ú¿Õ÷z—6I8 { ¸XËÿ¡¯Y|¬özþ'>ÊûŸÅÿ{kkkÛ÷ÿ¾÷`™ÿå ú,ÀµCÀ|ôó/Ïþ;>|ò¿ bߺïü×®Dý9µÓt0R·()L1=9…L‚Ÿƒþ „VHdÈŠ—ž¯¿Ž¾^)ü>mx2í½(LÔ¬FÏR… :¹µªBœï™›ÍF&?1¡ÃËÓPÄ€C…U“RðH™jˆÍòQ:¬‚¬jZF7p$soOarõÞét®ÇŒûu{ 7¡™¾aƒª÷§ŠªÝÛ«ctÿ†‡}÷(è¿O(.Ånÿnò?ÿkƒ²æÅÿx°åçܼ·¹µÄÿ·ÿCR"ƒLUŒÉ§%à /šã c|Xpj ‘9( 7ÌuŠaJ=A+E‰†‘Óu@qàC cÓ\û¼ô\äcc–DôçÈ$T<&PE<&Ø‚Ðnè1yü¯©j6¹ÐÑ%ûjóŠÉà˜‰b‹VõkòCž+úp؉€i{ó¸!¼ÿ?Œ7„æÝÿû~ü×í­eüÇÛtÿõm‹ŠS4dqÜ`¦‚"!²ZÅ+@.@–Òú)@iÑ}Öt˜å»ÐÝ÷%¬ž›¶bƒ<7s,Ø0èžO½Anäx¤¤„+9½7>RFìLú_?…eïÿt’ 6œøŒ7¥œoÿëÛ=Øy°´ÿý‚÷ÿd.4§GŸÐ4‹2KB† õêeCõpû›S"¼tœ)û–âŸ?{õøÙ«øÕÿ¼@ÝÙû@ÚÄÃÉ…zržN1«E‡qÚÃ¥€ËMã’0Æ—Æ. ˆÌ®+Sb‘êò£l˜Œ/¼yo’NÖ‹‰¢,ÎLÍÉ»‰ª6IßM6Fƒ$ãàï—^Ðç&;…Ž>X”2"•c¶ŽÉðÍþа,í|ÙÀ4ˆ ö©u1L>ð¿-Žßƒ…`TÄàDëg(ö'©fç|/x8Å¡˜šì–"Ký’ ²d0¿ÿ‡øÂ2Ýx ¹ñßvÊñßî/é¿/ˆÿ)–È‘ Fu2°4Ê…jŸýøâù“g¯t=íØVª¨AŸ<{ñ‹©­ƒ¢Þ£²ÉÏü¿PO¥€LtEÀk¥ ‡¿ü ëÓ£`µ_Õªž¿´Köóq©ÒOÏ_>=0+!vÖˆ÷òàÑÛõBH¹ÀB±’^©úß—ÿÿ|pø³i¡Œàð¹«nS ·†é-ÒØ­ÓÚ:¶gOkêZ!JÑÍœ¡œªñÏ~TðUjÒb#ƒM_¼P30·i4ÎGéx¢ú–ãÝRSÁ)qÆQˆ-ʧc}ðêPg‚ðU Ž™®j&ˆ¹ƒ"·¡š¦£>œ/´+õ—1¾ZéÊi¥ÎÛtŒÚš7&ÒÊ*AàTâ ­ºÇItÊÚս؛U§&¥ÈHè¢%dVqFô‡- BgË,9æ%Cõ½ˆ[¨/ÿ =•`x¡«^óp;£fãIŸ¦À5W'õ9dáVÿó!²·äqé¿-&ß8 ²ž ×aH rRBŒ(P…Ùq<ŒÇ¦7Lz¯.€†èg9B0xy26Ãu?”öæÆ(ßX3<ˆÏ¯+ÊfB¹îq’л¹ ð"`¬‹ˆŸgݸgŠ]‘7½´½¡[¯°“ñnSk’Ûñq ¡+H b«ËD¾öë"ˆÎmLmÕ™×Â{Â×o±ž$R]¼Åz =³.߬^õ­¢ë4«¦|áÍßUÛ=ûÕG¨ˆK'ão¦VˆÚé{:^§¹.DËYcr'Ôk‰z ½z‰#|ÇX½0qM½ðIa5^2ß7½{mþ—6·éDZmË­—¥æDÛnB! #ª'á±]¦3ÛˆisfÛÔµg‚¤¿m—ŸB:>ƒÿçƒüxqð<ùïýí’ýÏÎîRÿwøÿ›Mdu˜§õ ˜ ÆZ¡@.›áè ÚŸÏ@ŠÑ5ó`F­@m0‰N·îƤ¡éVj²Çñ¤f[‘˜^6‡¤ð3Ü §äpllíqÑ«B‰ cøóo…‹½>ÀGÀ&4ƒ£óÀZiñ{£¥Îtñ¿ÿUZI"1n+ÑJ¿#$›|£(×Ê¢ Èdê A ä–OƒÑ"ò òË {}?,mmÿCÛyãöè9=ü?NO²b2Æ÷çÆô€óì¿v7ýü÷Ž¢ÑŒ¤ôL&Âå'ê@ô{´ ŒÍ§:M]€ÍûžÅnh½-_ü¦íª±èÓïJ[e‰ +þex üàÞ«™ÈÞÛH3ížù˜÷¢†àд ÛÎ-‚”Ïùwé¡3FÐ ¿J³Awɇ} üŸz ²~BñXoÖxnü§›¾þswÿéKð«ZÕ&ÏdY NX½3Þ ó·ÃèW‚”œ9s¿Zð’ãモQk=Yð¹éÇ M€ØÛÒ;n"ѱû™ZͨÈÁ†ü}ŽR¡ŠËSŠ;›NLòiã©Pœª×ˆRã-ÎÁ»s¼‘~A¨¶Œ4 ·é\bŸ©.ÚäšéÐò[Ñ!¨K—#î#’;Önÿ j­x>T´ÔØôZ·“mÒèú9³»Õ±u€Œyc°tï¿ ð_Ä™šÁG怜—ÿkó¾oÿ¹½µ³´ÿù‚òŸðe6q³‹' +.¡øx8U4.Z …´;E/¥Zy‘¡Z“#EËãð(sìÆI.Xu%õÐÂ/~¬dSºj¹4Ž©† qZoÕÖÔýNÕ>KœM?ñ;wÜŒ¸‚BGi/ÁoSŠˆ7N{S ¯€¾•Ä­F L£X(Z³ŠF‚4œš½É>1q6ìg=íb¦"b~z …bsU m:N‹|:^IBu½a]'é„Wü—B…gi2,ÈÑF]@¨¥M¹è­¤Yd ¨°‰Û5ïºýˆ-|› ÑÁ^)í¤äe»â#o­¬ˆ“ý:»Ë˜ê}--¼ƒ+ïR®)¹¿å­%úÝa <ÔdšŒ¢”xk§LÚl(ù«}¢ˆ‹ö äH?æ0àú$Ê0{kRŠö?¦ª{n†OŸWÇÐí¶ºÓÏ*2ÇD 'øpp±û}媸7Ñ3+ŸW¤·Xã‡æ§ÃI¨¢îÄŠm ®~ï”Ü8ÒQƒõmÍÊ9¹û¥Ñ™ÈÁ Ârv!ˆW}¨Žÿ[‚RS»YuJKæmÉÿ úŸÑOÿcçþƒÍrüeü÷[Gÿ½@¨8ä—ÇÐñ Þá-$^sˆAxâV<ú‘å×?þµÝ~a6ë|™Ç£éˆy?1f„áx ˆƒaôH`œQ¶k~°jÑÙqÊìùh¢X;žwMâOŒw¾Ëb VuJj¢÷@1“˜}ƒøBýÉi¼ Ñן o1A,¡ðÈcÕö<½|ȯ&ääeßæŠ9hï{±C4z¬x°[s—n£ƒO¨½ú#Ò½`~ \²ã‹Š¦ô#ØhÇ@‚É¢ÊÄŽŽ.²iˆ¯kË»³?· $])'Í’'­IMœîI~žbÈ3lݦìhÌì‘ ádœ+ð»<¨ÔŽi-Pd+³À;"¦ÃþìèCì!à2ö'…?8ÊvFq($Ye§CDã2ÌòêfypÁkfÕ`]eòö¡†q›ªèèÛÐu¸+SËT£]™ü(³Ä‰®¥>–I)ð’UôG4¦Æ À"¤ß'|Ò{uð#ö(-ƒÕUåÇ®¬«0è8í[T¶i¬꛵eêø5O €ÅõC„Ã0– ±7Vȉ»†I]#Èàx: åÙüªI“¬fß‘Sü¤.6†D.ƒd­àQNF°+P³h‰glÙ²k4Û¸\}Lñ¦—ÎFÕ½»âì YÝ 03Ø ”{cHK¤$ ÞbêQ(sÐFo=Ra<[É·–àîœgQ³ý-5ôÍspå-,@œQ¾KÄGöptœ™˜{†zXlœ©|Wí abµ‡lK­~øaޝG f…YGŠ’Ï4ÅâÈE­;!‚3î š®Â8÷Ï4›6,”vˆl]wò4¢˜®ñúeW\ixî ‘¶ëbz”ûÙ#SåbÞÍHÝOü×tÜG†Eƒ¶%Þ«Éé´À©ç±Apϳ!~£Y^{Kx!bOJ—MlÊY»r•‘ÅSl‰HP9%Cñ4«BÄÕŽ£-æ`íK Óïî¾îêìújàÄ¡Ö@F&8¢ÂôIu²Ï\‘Ⱦƒ‚Ê.Å~ ³~«+~?Ÿ–—è¡c)ýê7®ÚýÂki´ŽÄvØXœ´ŸEZƒÉY/Ö¦ï iÕvä*9€•çûõ6aäæzŠ¡L˜vʆÇé8Æoª‡º3ryhMVíÉ^PÆJRóMz—=kŒ‰³ä0 m(jiRU8Î-4Bò.êHTÿ¨…)z+~€8w`h„Ÿ»á© û¤ÖÙ±¿»ûu]¯áè`& *ÆT‘>7ÙõÔ=UEª:£º]þèÖPqhÚ\¤£‰xPÝ*8—•PåÔ±c¡žD_{zDzù`†‘ï£hð§þ€Û¬@2𕶝žŠ.£KG£ÞÒ£Z¡BÝØ´ uö½d=ų)šø8ÉñqRLì‹ïs BAN½iSµ[¦BêìÅè¿jõ˜²ƒ#‚SçLž)$ò\Iø¹+ï»E‘Štîœ.éºQÛpðzM—Öš­ÈÈRn¢/䊂Ë7šSO=AEr’V€“. s‡«Ñ´_oÓh<%S5ìD+þìæ5Ú¢Su‡En °æVÛpŽÄ"ÝÐÆ!Áö6ÅËþ6¿òQÚò.üëÛK ›p$ˆ¯ÄÚª¶t%$Ò²<ºÅŒ›?„NÓ©1ÿà*BñÈ|Øhœž¦¬V]Çs­Ék¤è]kóRa—ÖLO†;„ýPÁw:„ 9£Af©é ÚŒǯì¸< mºgI:ú3ÅÒõ ‹gz"DPã@Ü¡Ñ@>¨¢ç£1dfR|#²^ Žfúp—è. '€ ¾&šU0mß[Ç2pG†nÌ—KÊò„0BÙ9 ¶P}œ%Ò.¿_8X7åx:–ø¹ëc»³þ‘˜Ýõ™ ¹UÌã_þJî9t˜eu gÊÞ€®=ç¬#.Dè³¥ÍP&Õq]â÷uê ’ÉñAÁ]V<¬Á±þª&gâ[”Yy¸V9è1¨Z©‘ýœ0Ð`ö¨÷¡º©…Ÿƒªik઻„¡ƒEÈ6¤†«ˆ6,lÌØ†YÓŠƒWO+,4AÓÊC¯;§Š¹‹ïU1s³ŠY»U|ÌvWÙ¯â*V4¯~¦©Îbí]2=tò ?Ù^2€'4Öɽ …/|_!&¬šLD/ç‰ÂáÃÉ:½ÆDYŠWo1 ÏýНóœq•+ LœñûWšÃ#3:¡ú±/qv¨é„¶^¼;r.ajÕÙ…'ôü?ªMiÉoi ø_NÄbhûNÿ-ÕŽYh³n)*hd6Y-ƒÜzŒßìÛú—ÃçÏÖ@͆Íê´!7ÈÊ(®™À€¶îÕ4¦ˆÒš¸11Û0^秈¥,åÃî;Ó{ÆT]ãlx•EƒVke6öǰõõèuP›7/‡•Á>l|Áw ö3b„¯ª¨› ÀSá"‚ØJöh+6§6Iå‚w»F<¾à³W/!©Ÿœr˜ìÎQ cÔ‚VV}Ö«™‰ Љ-_µ¹A]¦ªÓ¤`ú“µ }Icfr«±®ÞLä€ ¨DÇB›xMÑÇyÙ‘ì<vD!(2V[Órâµ5-¶ä±¹CM–h[ó'àf˜<Ëüâ.DÏ:p/D! ° O|Qya®xcʨFÓ`{N†,:éôHœHp¬‡Sõ*ãsמù´–òNI~˜ê*nØúü=\sWW\¨3#öD° Êļ•¶º,wXäDM?Jöà/Æy¯Ô–k F€”žÕ¸û¢¼ÓáKHZˆâ²•ž&ûÅÞ*‹ë¯"y«fX²š"W ¤ë,oLëÏÚ#ÑVË´õt rl¶ŸÖÙð‡O«Á»²2WÿDlÃsüh“ů٠Mî>\Tˆõ¯*^0ÒÒI˜ˆ0(#|tá “ŒÕbøg\‘p.^Òã–P{°Ç D®ªÓÖ*Šn“tcÞ2«U)vâGWÙD-"¾ ï¼pDÊJAÔ,öø\[ê»øÈŒ§¿»uÀFm²þìBº.“!Õ8dã"¡pÚn¤“ŒÞÁEMûQ‡?¥'ÙPŸBKÍ„Y?¹ÍeÄ÷k6žLÔš#í6[Lù94ÜiÐ/¶~|(÷Õ:šfƒ>ÿe…©h Éq׊"Ú‡¾Ïùò¢†èòcñ ­Ë!œôÝdœô&ú©c„îÛ1óÒ[«—Gj…àIK;¢–ºô ãÚÞª5ÊGêP=Q¿'‰ÖÖV…e®Ñ\Ju‚µKrív8Ï6,Ôaði‡tÍ2»"I‡È¸°õ6ôQþS=ì¼£pî¥r ‚.L¾|§’™g^„ÇÑÊ™ Î PÊêß´©÷›I"öÿ'Ø¿©(p³ýÿ·¶·lyñßlo.ó~–ÿ¬' p Q Ï~q&SÈãÚJUµžÚ¾ü ÑÖüÊZ¤´`u–UÅVL5¿Í?‹|X]zœ ÒÚÊÊjô"™ôN‘¼)ûMny”€Ú&'©æšÐcU*”¸!i]Ë{íNT ‚îD—Üú¯ª«¬y:K²!·R~|A‰Ùm Ž—×÷$Au®ÐeKÆÓÇ FNñ„]½ RÈ‚;r¼0TgÕiþ&%Ò~:Ì'©Ý\ŠØc¢à{¸Ñ¬5aÅPË =ÿ„=HüÉ á AÿG65FºÌÒÒCˆ;WçÓ“S¾TV™66B¢A~’õÀ€7]ÏæÅË'OŸ¼zòëãCðŒB¸gO.ë {í'ÃIz’Ž­4ã§Až»²“ÕPgÒr“{iJQàê6mL2‘€¾4_¯T±ýB¿DO³¢g~VS°¶rB¿Ñ€×þ~©X¢vû)bÉB2ÿ2R‹ë§ýŸ2£Œ7iXf”ºòê°&ãiOÑ~6ûá«—¿ª55»Åo…ºbÑ÷ÑV&~ÌÓòÆD'¤‚5 D£ª[ÓÔÔ¾žµÒv€>ƒ xgˆ.¡?¨}#bÿ,A³L'ëùñºj¿~”¿Û‘_…"h­ã>kÉ»,?['S+ç…[£ÁÖÊGn ™ôX¯‰µ éÕZÓ}=É‚N3³ÊgúMßЃ_Y±°ÁÚèá°Â”KMÜŠWÓþþZëFQC¤Â€ãÔA|éúÐfK|xóÃ-~+Ž?!”¶½á†ªH£cØsƒÒàôÙOþ 54Õõ0O™§9#D~‡œ*QSxT–¿³ç« -ˆ3qîÏ>½ æAàyYК*f^u׳Ê\2»åºh ªÒ1ûC÷äŸâí$Ü,ô{Þ!¦í.? LAB(Þ%³ 3ä\1ë^îzz½¨véí¢IR’Ê*ûà›•ì@¡Äà³}ŸBXÄÖ£Ù-I4$ÑŽxÔeºq‘7äÚ)ofxUþf½T‰V¶FU»y@ ‘}æ{ï¸WZ»~çÎõq qóÁ6nu¨¡®ÐJùyJ¡­eâ/ÿ7 þtùvwÜóó?ln-åÿ·(þoPlù7-êEm‰‚ZÓÔ¨ >!P¿±àC[1ÄÐ…vq Z…„¿õ>Ò$Ï¡Š5Cà¢]:¼¾àÛ _˜œiyp™Ôxr¬PíŒ kÓ?€Ë’ÓC}NqÌX-x)!ÌÎ&ƒ=ÞæU‰‘xu'Ã|ZRTðA€#aûÙKÜZíá U†¶;‚£*©¬ ÷\‘¤ÍŒ7FnD#5Ÿ¨Œ; |ö<ïê—åÔss‚YRÿžÕ% 5-ÒòC[:”®…=ýÀŠ Y ëJü§×Áƒ¬€æaÐViöz@üÿhœ®AÆÔ/ñœ…1ô˜7½ “Ì,R1;Ñ_ÏÓ1ä Û§ƒAv|Azé¶›ÊáÒëÒwác³Ð=¤EgF_}Ž{>³Êj)_Ç?Êc2 ¥¼œ¥¢=§Þ¸wd6‰‚1õå·»ï/ïþ6§b ÍmëtÍÜh§õ®‚;¸äÏéNš“©%ô_)¬ÿŸ ü‚í]·¾_ d9$g¡;@¢I„Ý &ú%_…¥¿oÇ_+m$:æüO¹¹ÀDÆØLß“r§ÊnZ˜  ö¼sp„X Å?eøýðW¦£\k çV*–A|ñ6š¹ÀüiþE¶\N"ãn£Ö¬æ•dC³´x”yQZ1U®“ˆŒY5ÑE]›½ƒ·Þ@µZ«o~ÄþFÒöU°Ì¡cuYþŽiÛƒd¾qxñ!ª’sDcEˆøt†}ò³3,?ºp¥–Q¥I˜7çfÿî<È,ú?`Üq-.`ŽýϽ›>ý¿³}™ÿí¶ÓÿsÌÊþ½ÕÄ3ÇÔÒÎÃcß7ºŒúû±•>аÀ“¬8¾`99Ú|`ôcìg- «gù·+ÀÔóDãHü*6H*µÐ=@¶Op‡hÇ‚ ˆš]Y¤l§ «oÍTv„Iš%jFZbi„w ÀAÌÔ¿é¤×jè Åìj€S‹iïTøðÐ3Ì‘‡éx‘+Rƒœ•—ûÈ×û¯ó…ˆ|ï¢p‘Þ1òfÔï¤0{‘RÁ5$$×´³îpúyâBX?gc*°$1áš+'äúš?MU Ûºä'ä‰f—cð1 µe°zec ¤€ OÆù‘Z'Æc+´¨²Jx0PïÕó“¡Õh˜eß> ã-K¸YX„ε¢jxža<¾Æxš T™3'ËÑÇàÜžÐnix¢ˆ{,•ÀED‚Ž2!$]@­àòˆÙÙÐ…!ï‘¥¾Ò‹´åÀ#ìV÷r¨= 'ê ûÓžž-0%Z¡MQ7L{«¤C°ùáÂÄߣޣ˜!¦&ØÉe=oÉ $’e}ؤžæD‰§Éy!º™ã±8VÑ<ã¬ßO‡Zòïi[ ÷šù€ÛGI\ܾ¼~Æ ÁnŒÓ^ –,Æ0D†B%¯åÒŽ:¸Ù½Fmq,.êYšª‰ãnÐûÁÈÆG™‚®ñ…4dd>Kúi„wòˆ\H$…n¬‚vÂ$ žsW)í\RÐEqCñÑõð\˜«¬@ t`JGƒw@Åy‡öD_)ÍíÕ²çHº¦’Û.ÞʤlÉ¥qŒkVXâ’\ή˜AÀÛQÄCéŽkx%â{’7ªàÕ]Úã8—ƒÍ4ˆulÎì!Í,ÉcB:4S*ÍôIѾãvTb&+ú`@HÉ{ñ<Øy·'aU_÷«Øƒ’̯¹ªÁ¤¹ÊW„uû]Ñ.2~Ãv^œà•à„—tXý¼'˜´’8ay 3‚yãü•Tvš}Zº×ØTpãŸèï²'r¡i—R€¸@KOФÅÀ^œ»íÏ邘.@òfxûiV(àUÇö .F‚bHt».ò³”,/( †h5ƒ*Æœ"ã>‘~ôM:ú»†E3¡‰0³ÉÆC?‰ždØ‚ ¥„kŸ¤– ÞBJß#|>¢È¹»$Uê: ‰ü¨ÀÔIŽ×¡8BL¬äÈÒ ã øÜÁÀšñyeé•ÓÜLŒDK"—±í0xLX”¡Z\â›Õö T¼G„vY cšhÌ´‘C¼ÈïbàgÀ×’åuq ƒÅ~Ý»çsëaŸ¹7ÀËn‚ÖK@ÈeÃ4¨Äy›ÖÆŽišw ŽˆHýˆ8fþ[ÌͪK;¸ïJ¨‚>Ö=UEû(‡ÂbÔ])ì6h7³¶þ*-$"2€ð¤ÿ\ç¨P)Ft³O—Ú(46¾à£ eL½aÁŸÏB¾â~kÍý•¹\6%æ´^àˆÔOÁÜex¡¹Û•0)/ÖOR9Š«ž rÌI>vÕ!ĉpª–œ9iÅ®e}ŸöÁB›å5({(\s™­•Rád±ÌE³Ô…à²X’ÐZI9P.80t&RãX¸ê°0´*.HûÆ=:æQ¿ú05H¯PË9€±PW=7=’Ëö!ÿÅ{ªcêÁògÚçŠ'dd!z©ñ«dØ‚{Íi ÌÔ%íëÐjÜá´õýó©ó€~P,›ìXÁ× lÝŒ”ëß3½g2 èvplÏÔûû!‚ÿe53ôÖÙì:Ñcƒ(ÃJ* B5Þ£ØNÈ'ª¦`Çs‡ª¾æ:è–¥§)3iô…?ƒ|O.¢·Šži9šÿŒSºÒ—t˜|Õ `7;;Kû(ã;M3C½Sâ0œ–z³'Üô’¥-3a¤ÿוּ| ò4Œ ­ÃdGÍK¡I REræHáÍlAw…W0ø–Í@iÖþ6”ä „î÷3/­ à1µÒu«aS¤z:BèG¿Ap®ñ “dà¬É¨G(#Œs¦îIßIDKm†)6êZ»°‚«|°Al­]ƒ˜4qòÄ•÷³ó¬?Ò´Œm0¶?‡Ö•Žþ$gGýcÖªî?„~Íž4Z“d„u!ËN§œ ×Ùh¸x½a¸¬gè é? B€ª+!K„Ù_œ« ë\(¼+f7û™/X¢6Ø»Òfo^xu¥==ßC‹Î ' 9ιµR"€ØÊ™ R¾3ö÷¾>:€NK4›?‘z–þ|Þo"ÄûÏ­û;^ü‡íÍ­í­¥þ÷–ëC L×ÅÍ,_¸*¸QgÚ—â+0rhE½ÉT„´š $œŠÔ¾Ë6m<ôkä×û’â¬ýIŒhDÄøØ/2$ß')P':Í´2^0çXçó“¡8SŸƒlýÜuwG._Ûö é ÆßŒù¡Ëu´¨t_§„`RÆÒß?§£dÏ:IÞ€„±cØ.g·\„¦ˆÝSÖA( &Ëqba"u IVYº¶êŽõÐh_|#PÛ Â N;6dÒbP £'Ïyá-6¸ê¤pI:2>æ£TOSŒŠ²fhóý¬â pk@Åæ´íO{o@’å#IÇÖéÍi·Ÿb¬$ªKGÈMÏF°¢ÆçÀé7…ÿ!˜ÊgÀÿ»[vKøÿþæÿÆø?Q"ç¬|Ú÷€3@Ü—¢:.DdlÒÝ÷þ!^o•µÌ2­«kóÀé­èÉÄH`07 2V.Ê\åä5`Æ ˆ€K ã³Ezƒ#3ˆöîð‚›·&ž¬! ¸&µºÀTœ§Š{‹ž £4Cé.Fó†Î\çe¡¦dõ2y˜cdÎeèÛDJ‹”uì,uÖ¯ªó A¬Œ™ÏÛïÈ¥ª7 ‹» ) ¼83¹RêÁh~÷Œ¼Ð5!ý!‰°†?¿o³AwÁGómƒ<Ù £¼ç©àF^ÄN(`âàhò{ÿmüãuñílˆ&°ŒIl°VÓÊ&0OAÖö•Ê:´W)¬:‡†z›Ú&^*r<=nV kÔ2Ñ[÷ûFj £&X»¯E”sZÁÊ °bÅï<Å•hùt¶Û`Pm57¡³Jm=õƒ—¥^øæÒ‚äNXÐåK±ÿù6d•ù»Â>솖02;’ÌœÓÖÃZ:¶œ> ûÝDƒzhàÒ7®P$ãÉTí€"µ„ߌºû¼D¹£‚d÷P«¾Ü+jÖ?ŒbQM€”KÇ}ÔLÂ&Ü“2.#iËwø·Ìšò"õ‰µ¢¿ÆÐ‚,Ù÷"hìªHLà¯Åp¼ÊÑâ%jÁnÕ¡†Ño"Åæd%öп8^^é:è —.¼_¯ý0^ã5‚9ôÿýí|ûÿû[;Kúÿ–Ë^92x û¬IC?àâ‰!W-ѣ兠¥dsAVA˜OK¤¬™sh/½™5ë\ 8¤ia6-”vs()ǾõÐòÁ¡ ;ð´ˆ=zdšL8Ú#p0¦%É)‡ J¯¸–Nê+_ £j"Ó¶è>NB96¦õLÔ åtÁ±KQÃëØbâ{.iKÉÙxsB[ö1¥ÙP´±±—Ï$Ûä„äkG«Ng ¥›6?GÍzk}&WÝ)Ý¥9ݵksþÀI;üËxNŸmüL.:Žù4k³‘¾¬›KáqÍÕËnx›4Ήg6Ã$Tl}ÙÕ_AÁ‰öfù(޼D“_‘½ÖÉÏ\1Á'à»1HÞÛ” `} ´‰À‚ôÒŒ©@˜¤ª:= wŒñW‡ìáž{D¢g“‹¦Aìªåhz¤HÎStbå‘Î`ª5+´Ö– 2H†ªÞâ™Ù IÆ©šBÔYå*&U¦Á\y6îE’€-úÿ1^E.ËÉ@DªK´ù‡Áÿ6ëø†‚“8Ç]ûº¶àóðÿVÉÿg{÷ÁÒþûÉÌ+1TŒ½¥.Ž!’CmÅJlƒçãg ž›¼ôÑw†©ÃsÅI‘r¾ß¡DÈ"‘²k¹_zùR±Rp:ž š\tþ R† †KúnIÿp‰?Ò |žÿ‡*öðÿÖÖ2ÿÛí£ÿfFr¢J¤ã¨\¡u5|d¢9€.Í"zTMéüT:H°õ¶k¿hMcoŠ(®í ÖX? 6„}” Û¤ÆAaJT¥KgVŸá YÛÐ/mlN.“Å ¶vÎ$h.üþô*ŒBÎõs_ï§#p†NDWÜÆïJ9ˆt¡fZõ¢ânSÇt“ ü~÷GzCáGöæ@Ed˜vJUähÝ1½¤°Þ]ƒg¼€›ÜÔušfÖMš@“úß‹Þ_Úñ! GË¢.D)ç"ØóŽ@›É[²gƱ…´à=×~†`}ñ±z”©Ã¢Ó6_º@º#1ržåC˜&Ó±3Emá¢J+eD}r ÷d½HŽS¿ús ¼ŸF«†ÊÑ*õ‹|Ji8&”S¾(¤eNyx LP¥Ã XéJUFÔ3IˆÉŠ˜â1ˆ¬|DufRA]f•Œ/@пGí¤Ók›Ïó¬ß sužM‰äõ3D:’X·Ú×ÍZ>1hÉÄp9çi±ć¹ñcÅÔ×;R¦bùZJºÜ,úó]™xTÝdó㉚'àL’ýš|¬eQúØÅjÛrÄn oëDáQ¬ÍÈpÇÒ¯b˜¾›p2øBÝsŸâu™}A Ï½_ e–wÜ2ŽÒáx 2 ñ nÇ¥èMç0 ÑÞ÷‘‹ó­±Ö‹x³a H΋œØÐkDIgtÆ ÇÜ;¬#‘z£®•ŽsVß}-¢wÆ Ÿ€ÇØmÓœ!ÄoälÊ÷ڦʦ,nê8c…?Ô(Ayƒ&&Ý(@Ã-(oÓ£úF»½ÑŒjµF( #שwÖÿ·»Ö ;ÉúïÝ´z½¿ÞžÓRU~ÝïrÓ¹­&ãzm½¦*ÅúùÛa/' áÅZ@³ãšÕ"¡±!çkÛ– O!›`Ú÷·Ên"z(-°¹‚~T—ë$+ ¥ž™EÝ6lFNKoZš›fÿD`¶}£H›ïT[ÄÅh¶~4Hã“tRok¡ß‚E<MÞGþâF1rxŠNoêšbF×›(@;WvC9èal¥KõDðã½&õ¡+{óVaè ýµ´ü‘ù²ù( Àþçþ–ïÿ±µ{oÿóKðÿ,¨}ñ¯:s¤ g “¸pÅ “™²2¾ž¡7Œä·q2>©ô>4IZuŽÙ`‚n£:"º½[ñÄ\E]õI584{ãf(U[nôcäÙ¸ ÓÏzIÓõ…¦Ž[Цdûu3Ù†'÷Ó„—RW›+WüÉ®ª3îÚœ½¦ÆsÎýn`­©Zuºáñ• ´/‚hàw«¿¿,õï` ‡³;o>ö†iW€‘b’Èb³›½ÂÒ%Ü ë¬(©m897Ñð¢:Á7æåc°¢+Úîém#îwÅ ²áB¦àHt0÷§#õ ©Q€çñ¸²è3&EŽï— Ìd.­¤¥– ¸àÖÑÒsé?æ€>†œCÿmïîúöÿ[÷w–úŸ[§ÿù‘@a1"îZÚˆ¨,ð—4àGpÆpGÈô¬ôp&î`ú2Y±ØCRéϦ[”•j`¾ Sÿxœÿž1úìí½²‚ýº®ÒXpèy£¦sú1¾ Ž @:_~|}Ñ1Ú¤^Q6¬¶ÚïJ|^–þ Xp¥2×—õVgø¨"}=’ême'§¨ŽØ@rp:"-ÅxÛïB‘*¶s¹£~Q°cÇO}îìÑp¡¢)ì‰vòã 7*ËŸA¦ª¬TÐ@z_Ç´Gz¬Èö‰][Z½´Ô]Œ¥Šâ)2Ëj\×Ü÷?}—€_öG˜ÿ͵ÿ»·{Ï·ÿÛÞZú|…öµE›ªß ¥lÿ ÍcÝÄ·M¸9 @_U¶¼]JÛÑ)dô ÍÅí¹šà'SdDZ|×[ ß,+I‚š“ŽhLP¹ÕJRV¸,ö8’™äyi+¹þõ^ñ˜ëÿW²ÿÛݹ¿´ÿ¾uü_ÙNÛåÁ¦s¿c:mÀ „%ÑôA×ï¶Ž£ixSêà áÍ ¥yUd¿Êˆ¢þMþ©Ð(ÌÁ>/ÚéjÙã †Ä4ªëÇ&*Û§PdÕìø+k«ðÓY2RÓe}Åtu‡?n·Ôÿþá蟨»ùøÿ[;Û;¥øÿ›Kùß¿ÿO­?ËÈySF&ùaìbÙ•ë± “·9xlƒéÛ'qªœoˆUð/ÚG{ ]yu’8 Q“b´‡•+ÛºÂYÝh_óeX§/‚ÿ H>Êhžÿ÷½Mßþg{s)ÿ¹}ôÿ …›öþži…6¾þL–-øÿ}ià¹÷œž¤ïFŸÒþoóÁö}_ÿ{oIÿݾûÿAáFo¿kív= `ðˆÈŠW¶…3ϰèõj2|Rƒð»çóêñ(dÜÉO‹“èBÞFš{ÿ)¼í§¼ÿÛ÷w”îÿÒÿ÷öÝ´À*>¡ùGúŽrˆîù LwŽÎÊà.v„Zá!‡eÞ ÞåpOæRCGž´²ì4ÌTÁY °”©æx¯Ý¨ÙJÀ4؆*J+…éôAÄÇŠ7çù$ÆÙ÷"çÀzyI<X» 䯹»­ZîÌœ¡Þ#¿½þ¬;àß.‹“ãZ ~áìý¨  Uû™XE²û¢cÿ50S*>¹ŸîSWnÐèO‚Öià˜WøÎÙ8IΉxé VF¡•ꌵê>*—úiß/¾±£bw>ÖéËí6€Mbá&t¹PT!F¯¼Veu@¬gPõö¿,k!Þÿt|MùîÇÒÿ[[Þû¿uo{Iÿ‘÷•2’AwÄ ¡2°˜Nÿúøåá“çÏÔÝ«m¶¶þ_k«Ö:§éïéRöö5þFøŒ’Q¶A ÔbÁ h3ýOvÿ·¶ï•ô?[»›Kÿ¿ÏòŸÑìÀ1ǧé@Ñ«µ••~ZôÆÙ‘¡C@±Ç!?ÄW¨Qd“«åõÖ㜪C„ÌÜ×Iñ<Âf¢{pp²Ž*Òîü¯: myNíö‰oFtÛ 6Ãddû,yב@æŒ×¡¤JÊiêIzUGÏÝÓC¸-?±uWG)áô#g¹ú¹úžÇ¿Œz§ªÃ†äÓ» Y%Ë‹)ùØ™ã|DÒ·u^ÊÁ‹' [¬Wò‹Q+Q`©iŒ¿hÇÚ‘BA%˜¢ñÜŽjGIOÛVO|ÅØ<Œ´Q0¯Ã­’XAã¨& öªf…Ô6jÍ&ÞŽjÉQOž¾S<©C®ë˜ZDM&Ó¢¡ )JÿmonΪ|”÷/tU¹2½˜_~~¥éÕ¢oUí­Å§¸{…)""Aœ;?µòJL$0‘á_Ót|Áy‚X“ûä]ûj«û¨`8©Â€ÐxóºÞ(|2üAu\ýJš™ TXŽºŽ”Ï;5E´ôXT­Û¸%x"Æ0¡6º&|) ± Š ‹[t‹0yêŠ â½ Í|{¯3Í+c ˆ£•¡¢ÿ 7ÊÜ#J!ɯðò7q±þ¦ú|J]þwú±,@kÄ!b㓼úF]yK®)œV,NëËÞWpŒ/šq[óü(ߺ›ÀèxÃ$…»¹÷å ¦pÄ•‰ëð‹²*b㌠þjÍRGYÀŸàkž™xŠ^'b POÎÊ©“tÚ@ºk㉮9X)4$ wC’3(Ù:ÎÆ¥éàÄ1îÕñ 9¹)z§9°h ýE—Ó‚ƒ(`הϫ›`*÷ô]±Fb5î›tH‘UuxGˆfaºÍ&µ}^ =d•ŽA7µGWAl’=øà´jþ&Ÿ¢_Ñ©ý}ý£®¿‚É׺ 2©ák_q阪Q§ã šèýߎ(íg“v±í³m:̇qeóYƒåÌ!e\Ò/‚6)܇Zà:«:uH¾ 0ÿB[ÒÔ¡à€æpw ŠòËn粦cÀ–×ÞÏSÂPv¢QOl_l¶.°§ qu ýjðjkÜí‘oïµ×fÎÝ7ŸþíY¶s|°r~DÙåâŠ|¼ÕôÖõ!þÖl“H‹lléâã–ìÓ§B_©9 'ÿï§éhpóâû±Ö›~”`žýÏÖý’ýïÎ2ÿÓ•ÿ3ãð#‚Ɔç#É<˜*(³%ó ųÒ8ÀHý‡ÓÑ(O …©âIÇDújȲXCq,gÉ$jÿ³`êØá„x¼x+‚¥q†]d`3tõ¢Úmw15ƒôK2Là é‰ õ‹ÓÝÛ赧ع åJ”a1æg;B˜XŽOÉÖéYŸåÓádã¢n+)†T‡4OM‰¿ŸÕ+NæreÅ¥>-íÉ3‡·èm>~S`ľéЊˆ XÌ›Co ncâ¹ÀÀla°.rÞà ß3-j˜¢‡ ÑÀi­j®‹Ì´¥{øBÓ½ 4˃iã¬ù ö³ããÿ2Ϭånh“w“Å×°»¹»tÐùÞŽïDÜ€î÷«lÿ¿©þ\¾ÿ·HÿÿxØåÙpâãú°¸e>†w•\Œqø‹QÒKgP,eœGÍ0Ê ‹{¬”:ëƒÊ¹è)&â $ëd7nÕVü×Ñžª]“ݼ—ÑÄ¢²~·)Šhþ¶˜~[áË™/¸«˜ÁáÁæþû¢‘óqž¦±ŽºQ;ÛêOÏFuX2HÉS¦—i%5ƌɶäa}îãäjIë0§3æÍU¾ØÔõøÎì¯þÂzøßÜÀØfšoÜq>¤×}æáÿíþß¹wo‰ÿÿÈø¿}&ÞñÒªöÇã”jµ’|¨þß,A¸z¦¼.ðøµP3û°‘¦QÝ`MKä,Ýà•|2 Ÿ]~xÞjñÁy‹¹âþÀ\?Õ£BHméÂ{èÿ!HaûŒŠÏDÿß¿ïÛÿnÞ[ÚÿÞ*ü¯Ðz»ý3A!–Ã=C€ácVÀ…ôù)FÒ÷$u~e ÒãÇ j‰?Ä×èÃk¨+ ºUúN‡Ñ|Cb<+Œ¤çé`K> |¼U ë‚ó÷|ºœÑ¶Ýö¥+º\DM.ðeZH[S~2<{éÄI¬gëÏíAÎN€¨7-šˆ:½;žøŒFQÁr3-¬zä3¤Q’´æÊëN ¬U ³m1wžôÏvyºoóñ ¿èt©rãS=Žþׯ 7IþÏÅÿ»%ü¿³»û`‰ÿÿÈô¿FhVy}£­ž†C¯w¤àżªZ·Ûêågª·IëŸjêu‘ÔQ:~1®Ûg"¬Ã›5««Y?^qf¶÷äM>ãþ›2'þh_ÑpÙ1‹T?©þëÞýû%ýÿý%þÿCã°ê·½$Å·V”ê–Ï1E\­'G=õ+,ÅàxÕ¼Û*Y/½Sßl‹zÐj 餈nNÊ8(Þ‚ƒÏè»NvC9ÎÑÆ¨wš véŸÐLïÖo_íôÞú–"ýîÝÿDcëÎ?÷ZoóRÂÿ“ølƒ{cR yù_wJñ·îß[Æü*ä?/`|ñ‡‹„¢Ó#…[CB‡€fWÇ›P ´Z?^]`ÚQ›¬K›ªÒ°ŸPëÜf©žò7mÝQ-¨f•’ªƒ)8I9>_ê+è…!µÐ?UIUh¼æÊ ¥fWZ©PÈ9s‘ïÿ¹K(³?»F³š±m‹È“Äù¾s°ŸÒƒ*ɸ|I“e ¢ûÄòÁ BU!Ãã÷—ͨöó«W/âƒG¿xU‹ö¾w-·ýnúºÄµ+*ªw7ï•ù/³±=-772/&EBóº^Ïå#ò‡’± ÿ,Gt…¼N ,ŒÖX䌯·ªkŸð5–eîûŒu•a„×õ…6|©-üôß8íå'Ãìw°ÿ˜œ~&ýßæîƒ²ýßö’þ»]ôÝ{SPk¹°Ró˜ùÙÂö7JÕ#£øäTKŽ.¢“L‘=‘Ó£@p?4¿Ú‘mC!Ô`…£d<¯Âï¶‚Î4уü Ñž©ê®»²Öh!£_t6»­|œdC­QWF…cç’È‚“pùɳc±úÈx®áSŒÛqz’+¨žpá=²Ëæ -°$œíQ«‰,QìÿsËÏ©ÿ Øÿíî,å¿Ký_>ËûFE².È;S¡üÿì½ûwÛÆÑ0üü¬¿¡O²¥(‘’Ó>ˆÇuœÄ}ã˱•~í«ð° I¨I‚/@JVýïßÎì{$%;­rNk›ØËÜvvvvvFn°Ùeà§¼|¸b{øomýi|øÃ æn´Ôåÿýj_¯ÿüø«ƒ‡ü¿ÿÍú¿âæo+ïwªUø"+Tíx¸ÿXVŒÛ0Ü[ÃF>²O¬î´õ_\Äù½ÇÿÆùÿñCýßÏûþG‹ e‚#J÷¾Â{Ð Ò¢s‡þª«=ZÄäLQû?ùžðdI/É¢=—bbËV9èÚ[÷5i£ø•‹‚¥ízÇ©µVE"£U0IÆS˜Š•´èò$#–3Žæ¡êTi³Ú0\Ò ó(…DÉ +{vX|^ݦÌ“Àü«êÝ}°?þß’Âo¢ÿö¿2â¿úï?œÿ?¡þ/E…ÇkƒÀ1˜å,¤Fô °åuè•"d]³Qò>/r¢¾>ªgXt‰PU%X^3·)¦ TÛ—F'ý„ñUÝ^¯ÆIhqªJê9üÀ¸y¢œ²Å© ØàšlÚà=µ¢:˜)Q¤Ø,ÒÓ5°Uü)õCY³’hô*hò "xóöøå›×ïïIbxI#û ~BsèEÆÓdt:ç,7¼iÁ’Z¿}óþxÄw”ƒÒÚY $À´’TŤæ|è“ï[xŽœ)ã!bt.ûÒ3bõ>…µ7=¤iÇ2£@;ÕÃH«bjéÚÆi êT£ÑFêE[ºÑ`ÔÑir_&£iút)µ¿ÐêlÍâqžD-=Gz ×sù%¾¨—ت÷/™LNæ!,eH”¾H/ˤ†ëâCC½î !X&}!f³kô™Ï¯C[ö’PA Üaa‚¿Üi–C¶b&ßp«›Ÿ_õ¿â‰dyªÈT4bÝ/–ËE´·wuuÕ»:èeùùÞÛ<[fãlZì±1øŸ»E2îö.–³)ËgËiLÆ/ópÁ«¾ÅR'4Ìe[èzžÑXÞjäÁå"ü")÷GÒN¬õ²l]ð³M/öX ¸j!<²q§Ià»?䬞_³d’Æx ÆTÓ ë“Iè!¦”ˆ#öãè~¥Ö:yãu—'4;¾~íÁœ‰q¡iD’=…¨v‰ÍZÞ¡³‚7ø„uá –¦Ó%yžåmKRí—Ô…õhR¼ï³üÌO&Ms^Ù8¥î%ÚA$ `E™Šd¹T)ýC4J[[Û§M<€íg(³Ã‰Àz‹x;pm¦Î xÈ·G¹SÉ%1ƒÂ¥²ˆ/ó4¹„)i†ólNÞà’±c=^$%[mÏXKòQPn‘¶ûFj¤È²h„ÿÝðà0Z™½¸=Ó÷Ø,¶@¢~A ÏHoÉ>G\u;Ç0È¢<žì¸­—®º7"—ao¦É*À\‡`³Ü:Ìû=ËÞeŸ£ÚÌÀoóám‚:ŸS¢Ë–E2=“(u:Í Ù}@M¤ÏCŒ±%°áUøŠòÇ@|&;!”M¿s<•T<„ÏjŽ‚JpŒ‘l yê–±‚Ì.úÜFOO è.SÐØ«"9Ÿ=V5“çd|%ýy:Ÿ'¹?±gÉìTKîZ~ ÷Øw=þÀ:ADGö£2|A >ôÎQæ(B¸÷þ«—´5£`Q²ƒ/áo_P&Õ>îÏà.þ7”#ã,VÙ°çlKÄdÑ‘–KEéÆå@WN͇¨˜o"ôØB©_ØC!ìå ©R¤3wz;”!((…ÿpÕ>'â¢LnÁÿRð%Ðé%ñ‚ƒßâiñ[yNmý«÷è†ütû/´%çÄœL㢥ê÷B)©iæÛd ®ÐKæ Aé*É Jâk8bì›~ðdæY\ž Ó_yT&§]`Z3V a$–¦„[îÚÜ0f¾‚êe®ξÞ*×ßàu3©©þÄ5°¾È 3q3Rt•á£`ïd÷‡Ú»ÍÒñEœLý=XíÃýÃNsZ«c“^ÇåHâRÒà™9¢í­ù”È %SãI|ã"èOv³z¿ä^bZïKæ >ÃVîZu``2¯£Ê.ü¤ªó.n»²œ†,ë ¾BboZ¼VÝnÃN“…¯.yVòK)¹bÔ%Ê]fpø®Êêþš„V´Ñ{ª¶~ž'1œyâú…>²{)Oàá`Wb‘.Mǰ©èŠ r¬™Bàÿl±¼ÆÞÉ^¾/òxm¤BêõŽ8gñ‚ˆyF˜OS¡Ãz’À0SrÀø•ÿòãÒøÖ(;±>$iXŸÝoÚ;—’ù%ØôßÒ’»2>@2Çã8àFõ¿P"ž<À(¡4ˆUvèéÊô>WÑ6‡*鎦5³¼ˆt<{ûRÕ=&ÁÍó,ûÓa³>äPò°©^y±Sñéyv™NÝ6G/÷ÀQÉ)»4ó¸”óì?±™GX±B“ÉH<´œ×Ui™Ã=Sý½ž*u¦®u$Ïãë ;ã ¾!¦åe?¸t ²Üø¡­ì înw7«`£ö¡Îç Iôq Kï³å•"¸ãÍùÊ9|ða•.!‘4” dÕ÷*±<ûŒP êÙÞ„T,#˺œÇîÛÅ^Röº$vÿÎ@ÙTl«ýè[A¦j ¹ÕÜ‘*`4{@¿Ñì5±@I8Œö 9žŽ«=HÜ2T¢¡ü B·²êÊ&«;¥4í.',jÐÝ<ûÏo±H-5_¿[Íf×ßc—ç’×ß¡:éöÜŽÀ! PÉ<ŠçP7Œ^æãd”µÙ”Q¤Ï‚ˆäÉ8I/Éh<ò¯GL½ûncêÎÖÆ'fš:<»³cHµ’pnussN%]«Tì7L él¦.'jÛs“c¡§ÌVÁ£æÙMæã Jp׳ÓlZ óòãÒ²(tG“ p|…E™=×93͹éþÛÕbI‹(«>ïô=°’ %§ìÑ7²óÀ}ïÁÜJõ-T4oZ餵XïÖmèƒ^:—|ÈÔ/ês%l«<žÐ{þ¡Ï¹R—ZTOZС5 ý45ÙNmš7‚öIDàè’ý“Q‡ÝÀ²nËô:¶hìrs¡oZX±gö¦»ôwâ¿ÓEí­KÄ`îvÕvéli“¡gçðuœD‹• Z‰)Pú·Õþ‡ß”ç–aU‰ÉîQÅÑ úä˜Úïõib“ÂJïÒzÅ]pöJsÐÃëoªQßb|ÛäÐðè&cGhP­·¨«ø™7³EØÒ8ú™\ʲdñ3V} Ðå Dôôx±j d8ÜQÛLÔqz5{Ú¥–V³…NLéðù›×Ç/^Žÿùö…™ñE?˜yéRdÎÑedð4ì÷ƒ(P4¬ŸØ®D.˜..5on;;.BaLå2ƒ‹tOJ!¶Diü1¼®Ò¹þkÙÊ®N^ 3r|±š€ØŠ<žgäÐ&ƒ_² {=ìÇbO&›lÞ.£yZ§ãwÏ^¿ÿþŻы×Ïß|÷òõ´=#g( öÓ‹×?ÿˆŸåK±m‹ÊV…E§¢gíëþçKçQ̱Áókwjm›§¿¹÷y÷pÚ@Ù4—»u@íÑÈmHö£Ë"è7ØÎ%è˜9°fo6õžJ7c§Üžƒ°Ù( ({±êÇ’;¸Ä-‚ÀÇnjaÉ8¥ šÙ­Èi6µð®Î ðHP{“dš,Æéó¤»óYiø :›‰¹š‰4PªÐ»äV¯Âï&𕵍¼±’ÝüšïÙY>‹Ö:ï¥õ’(xwÎñGí4ƒ#¤|n¾(. ¤‰"fáùÐ[ͲeDöгÁxêÊ lŒeõ@k᪱E0pÁ¬œ(.A¾X`ݨ ¦ìf?œÈG²{/òl‘äÓk0\Èé$FQt=z«Å8.’Û€&¬hÙ¼‹Â°€ÅÈÞµé®øl½µwn°šùŽîûláaHvpe¾GÁs\ÁKGAþNÑ)‚ ^Ñ:Í4ZT§YÆÙ<鉱ڔ»Á üe(é&j$“YàW~²cÉñL&£|L8žeDNÄ@Zé’ù_2-Ìî”6_~YR Óë°Áö«KÄû!kÕ’ñx$aêkõð§<1šg|à¼o¨¤á™Äd˜©5E€/Y7íÐ*›ü–ݲ9±Í™wkôˆ¬ßøš?¬BœðQ%rºš³·uD4©3±žÿØ}¾"§ˆÙîú3 Nv7|ÃoAB½K—úŃ[[§„B?ù ¨ˆÉƒÕÀR@ÜHùj€ PYoÏne«i›K¸F7%U‚xM$‰H•8ÅS¢+&×#2Ù&ÐA¸Ž ©ág²¨pˆrدR0táÑS9­ÔQ|–ÒÇñu¨ý~8V%5¢@+ñ8Í1ŽÇŸ>߃VØí{êWÿ¥¿M¸ú¸ú~ðZús›ö&¯W‹°n©‹§ßëmØ R4^’…{“'õqq$ÌZ/½›2ØÊ([å°z‘©ÁSü²®>ΦŽWÞ5RX~øq6µÝaÛÍÓàÑŽßV«§©ÂòÈùøäÉî?^ý´óä)ŸG”µú½ý–ð2µ~>þ~÷/­§ßì<Áç”ß៕SÄçÉ7šáôdØy²ÇZÃ^ÏðiÍO¸Næ—[d‘m¿QíJe«Ov·"wõ^èðFoó?FÏ~üæÕèÇϾ{ñÎzo»dܳ`T˜Ä:éëîkÚUðYø‡àZ›µ6ëÜsÆ7;2Èçµ»;nXõ3RŽíØÝà‡Ç]ÉxÈ”‚Å¿·˜ÆéÜN_öÌ…D“Ë %°Ê¾Ù¡H¥55-ã46†Nã_ã41ŠNÑlä0ÚXs).þ*Ï2n_9Ç8VóIW$ÒÇt[kj•ìû9 kCéÝÉ|´XßE“>œÀ(ÿ(}%ókdYqÖí«‘J]dÌ‹¯?ørºÈ² fõ9ŠÂ 0³å°Ñ†Þ‡äúiÛ²"yAå°[ ‰±R·È ”t‰oÆÉBf*À-móLÙmê'•ßÖØ¹gø)™Ÿkë¾rŽ)¶¯N¯äµoàk1~^žˆZ'Eã e]¤ú .&mv¾¦wY>°ÕC2¸BÞ£o–=^÷ Uíú V7Q«àôŧߪãî®Ul99’-Mîvü·(—@;"­i›®£JÐn·k‘j+ŒyøZKjªõÆSM ½‰¥_P/`މh¸Æa7«8ÞÃzÇ”ŒSVÜ¡mo‰Û=)ìF”\Ä ›Žç/šŸ••a MLüý5ö¢ýíïEÒÃgÇ4$IºÊSš6EÈ‘yŒg–ó>¥‡;Œ¨!!êË+P$à9È“è»_•.¥©ÀÁ/±_Uœ4Íù3|µö…ˆ lÄÂ%4ÌŽ›"ÉÿD^1Ó¨<'P}F÷ýr´ owš‹ÖúVKh )ÐCEb×#¡œŒ}!xì+Œ¤kÉï» Q0‰4ƨ 㜱-q°×æ“3O¡˜:uît[¢± iV±#µ»þ´¥óqYª†õ-Ùƒ#Ïq'eÃÓ8‡†,XÕ ¢fðj=ºáoò'é}ÛrÅ7» ܳôA—Wy©Œ0çâE ±üHIãJÜy;Œ0çÆnÀk97éÀJU–ke‰ôª¡jM…ÖÂQŒ‰µ»/yÖ87“ Y2¬ñ¡½exïÜB TÉ\jð4€Ñ` µñ~‡j Í‡¢°0©rÄßXDÇh)¸Ý¢üèFzŒy)ÿdÇZƳZ³*ëêNUU•ÙÒÚîé$ ƒ?O‘„0)…m„DÁ|Oþèe‹dÞVûtÉħa7ø2‚÷*úi›GÓ‰­ëœ~Âñp½ãDäGN›«ÔùÌ$u½C*{$o*XB- ʈì ÿ‰dÅ-~Éøçˆ7& 9¾k¦°öb9ÊIrĸtœÌðW,[IsLvôf=¼YSæ1šäÉUj&©`Š™s ç,gWyÓœ),>¡dËàq5ëkOFrªØTÊE C™ð”,EÑ_ ^ÌW³$—YÎ*O¿N?”ÏšÉ?z×i2¨¼m ¬aI/•ßÅãQôœ¦y±r–K=’¢ÐÊ«üemiZ-êÿ÷ïÞ¿|󚦓_öú½~¸s,¬¦y:õ _$»0LžM%HæÙî>yÂqÌ’í¾àI‰Ê¡x¦ÎޝT¶Æ¿ä¿Ìei€Oàÿ €öáÿà-ï­ ¯Ç9éW zÞi  ¤;Î`æC"÷÷uM»ÞM(|µ‰ãÄÉ’ËÉ]–FÉ…h½ ¥™×«ÍëZÚØsyùY¥µ*nyÓ Ñ5åà)#LmµhNBä+™c&âtnZs î4ÓHµI[õÚ9§ñ¯½º[*{mzŸ/1rõå·‚V:Yc%¨ØnޤQÉX­"öÊ1Ž^AYj5:ŠVÏ€þXYÑ€÷Ûý¦=Ò‹„¬¿œ'^]¬~`m´|ØÚ Ò¯ŒmÉ|KêéHo¾”Ôë ³î-ªÆ¼í2/[’Š@kè%j¬XôrIL™\§³´ÝÙAJèòÓþ_†z&C.·¯^¾zE€Yуà©Q[|Nö‡ë®Ø±äd:kH&eç¬à­ábüo)ã˜jŒ6é²#bНKzPI&A+£eÉ5À‰ÿ]JØR`"ª­’_ ôÿx„OcÃðÑÍó^ö’bLΔ%2J‚F§%;À {pþ«ößA&t1;Y» o¤Ä®«|ZØ iµ˜fñ„&˜dWsö¯àíë¨Eu™B–&ÒïVËæêqd™H÷.1ëû˜ØÓQô3NžL¾ç'5ãH?ìQ” ÷C§Q ö`¿_Û£Îô.Ah>”,#bÄjQDlÉÓU{:ÈÛ4û­QæÑ ÍTáòƒÁb‘y·:½ÖñŠ*¾ùÓ‹ÑH-š¤/ºP<EÂ_1qvs„!+M%esO$…£éˆkˆ Q|#x(L(' L).õ‚ÒXLìy´L/73cféd2M®â¼” kZåàíE6¿~%º(Õ“°^¸<“6!v7øcœŸò*ù~ ‚(?/ðëb!ÿH+ÑÑŠ´£óô2™? ž¢ä‘’çU‰>@àæ¬ &‘¾ -úLO¶!ˆ|9V6yò„Âlo„á~†@¥g h µž NEª3©fš…3Ú™ l4]Ñ2g9á*+am¯^Q†Aãh—–7èýÁ¾÷-ÈQÏ~>þñÍ»—ÿ÷Ù1½ ¥)V£xµ¼h3ºP2^&—d1vÖU/P $*„á9îKë‰b;›MfdÇ’D±šCV™’é‹ñ¶­1¯Ê[\䨬ÏrÚ Z0B®&zÀW(sE†·½Q„ÏÑZÒý Þ"Á&^…ÆïÅ^óäXò…¡€eÄÝÀÔmÑHÛXG)’éÙγlû7‘ᙄâÑbÿCu\¶•¿`íÔqÀº€Τ¨´r¤C ÈrðŸŠ/:å<øoSõ™ÆÍU‰©ö¹?S¦5Rok1I‹Íà°êÇq<‡ãxÀ‹/—qž‚¶äò“‚æ„gX@µ±%ð-µUŽtÆl¶4Ù¨Ÿs=ì6UÛ4;?—LF†’ú†]ÿìíËŽ¾~AöRÙ:ý6ÍÐlå^_¾qÔ¸:E?á_èm{Öñ*ˆ3/¥); èìºÎZGsÏÑ©é{A;:г*ó(•ÁPýÈaèš¡$‰4c xKíÅ9ûU}C”ÎÏ2ç³# !h„KFåá#øÅöÖŽ µw î•ù$Î'œ+ä3â6½c2{/^¶û¥Ç Ô†*äóìJ©›. Ãòñù‰†SGÑûãw/_ÿÐ ¾92Û†‡½}}¡‹b¦’ ãþÙK1Ugm[gtûUÎf©¢€ñÊŒ)‹U³‰£Z”ßøY´PíVÍ4lv¥%,“7Ø|cõèyrr žÌ“<ˈ§WñuÁB½ü𯎼•QøÆªîA‰Ù/ºE& qÛSYûÝjvþ zyÌ´ø©0p‚Ù„&¡¦>œWX½é‘Ð÷®’u%D±#Cof nQ_£Ì¢ÖòÒS±ÛÏX #â Î eÖ :ÍNÉÏä†6( X†ð~ Åî²Ó°êa‘ؾâE*«¢)¸bbÀÔ•ÛVµs>‰{N£ú,SS5ò×@#)‰û„Xá`D¶g|—eröäRY´T+cØBxÞä á©„§êQW—Y:)‚E6®p:Ÿf§ñÔK˜Ì/‰ Gê_åMÓÛ#¿ãóšp¯|ƒ[¦ƒ)ïpOC%¤â„FpA§U]€\fÿY>* *èeÚ3=Stg„E¹é­QbÓ5zã­©W½çöž}*‹_š½Ž4ì}!¾ ¯¡š½ˆdެQE“ß7AÛìAbÄÁÀÍpxvÜDÆ“è8É1á·]… ²äXÝ-³Ö5‚iÛ;Ô÷”´5}©jÙol[鵚›ýÂÓ$9Ç’PëÊÛ6$¼ÝÜ(§®57@ÇþFK"PD ‚Ô7üb‹LAcd*Ÿ8Z§”T䩞¸&øÚï%•dÿíRÚ áFðñAd=ö7¸£r¡H2ÁÃcd4nuÝ/xdŒä>‚Y .Ð¥Á¬A|×&ág…_y¨p#•ü¦Ô•Â×_“C0¶$;³ÅúJ›nÓ-¨ œ'©„TR”_ÈVœÕ h3÷î"²$Kån —‡ü(R "`Âã'mûFù²Väè‹ÄoêÅEù³â’3ƒˆû=»Q5€-‡ïíãˆáaƒ¢ív§fŸBáIҥɖ˜RHØã’ öp(ÈÅR—#õ9Q—“¡gmîf³3êødƒ Y½rªå ÿ…e‹·Ñ^VöúWYÐb;½>yt“ôÄ¥R—šÜÞ÷ltˆ¼ù `f=^ëï* »ÁÜÊØŽ•Íçdv<ßµdŠ«[íñ]¼ŒOÉãÛþy6›­æìñ+ï¤,â¯Ý› °S™á„a]úÚ¬Ý-Ä®ØLñÓƒ,: ”å\µWØ¥ˆË‘FíÊ"[šL5]ÝåJƒ-4׋ÂÍF­å.hìØ2;$ËV¬kFsEûÀœ˜#|kîcÝç±fä¹U5?1ø®-ÚUCÂ:œ‚a…xIP}jùâ ¼î …Vq×/,â`’ž%4Økø:h5ã 0‡À馋uDÃwÁ‡4\æ€ÏGãzÏN'±Õºz“àd¦5öp$ñ ‚×™‡s€yÙX*£u[Ꮁn§”Å¿Ä;í¬söz¥Žý4œ|LÆ´f+§/ë7 1Ö#xÅ)Gœj¶Eæn²i—ñ*:%ðŸ‚NhŸ>QÑ‹D¬›ä¹XØ>Mä€ö ”¾µ7‘ ¸â“¯‡ˆvRÙZ4–mÐy6bøT ý:{…œC{Üuêb¨é@Î6€…>€«‹¹ú¯í3Iƒ(:„½œÜ_Þ7‘wS:V@t4îU|,Ú/>Íò%^b8—KYê4ù˜K»5!!àDÆN á*æ²(·{Ð~¿ ö67jMtÃÕœ*0ÿ¥ùKhÝ&hŸÿ¹È²3©²ÃJpA&9PâßEIÑÏCéèè …kT¨œäêæ.õ"D.ÐU)â›ËZú%¦X7S+ÚŒŸJ©¨°ß%²h4ÞÂÙOܹ‘QpšeÓ$ž; ¤8®èøÏo_¾Ð%™%—‹sÁï ¥äØ„"ª¼½Ô»ê~ÏyGL-öTþþùzÞ +Îëˆþ²Þ˜ D‘´•Ô˜Y®¡ÓÝy sùÝéai„%imQ¸KÊû½@<=—ˆR3:?è¹ÇW¤È"©`­›²\ 'Y ±O*ºRé›R …A¶¬þÉ5¤÷w#¤[e¼=·9ó¾ÐÏF´‰ÄbgЧÛW8î3Åê»YKkø{pª®Þßp„‘ö–ÏOèc½ Z~\6Mã1X¤ó'¹îÔ ^ûÇ¡i˜Óï”ÈÎ2WCÝ& hM·°Ï2°¤óåp{J– J«‘°÷ÿ%Üža{LVFîéáye쪽HùÞeµE¤ªp÷É׫«H'$­¤©[àÊ·¶,¤^ŠYfîÚëÇ4ªD…þ]WU’õ8±=R×ÖfQÌû›°QnÝŠ‹µYX5¬%Øv 3È!bí׈Ú/JP·x^áÈÂ;z†ü¥½bå0”îAÐá_åSg(\Ϻ·´´Z~Y×å‹Fö?Ã?LYn®3Ëòæ…¥@ˆúìZ#ßL6¹öUEu“ë^E¨px‰ö>ùþ@¥HÀ:åÏ-2è-…MäÐ.† QÅ:Ñ”kG4Éu¤²N.©ÈO:â3–ÐXî½c¤µˆãvÒÛwà0ž´"¦ íF{Á£{7ÍÍ`GÚ“ wgDÞ™ƒ£à„‘üü½õ.lTSÉ ÝNhá$¹:·Ü´¤Ï°7ÅÒ€Üý&Øw’=}“Hn?¯ÔšÝFˆ÷0?£¹­¾KæàW^U´kò6ŽCZÁQ}'=‹1 Ž«X”ÊÂB.ùµä|É1¡ a¡— ®­Åét•'”<ÊÓ0_ ®g§Ùô…7A¼Ðá°·hxÔ8¦µ—Ýj¤S¶YÙ¬’1\Úa-å&œgñd‚5_â)/…µ«4³>N í˜q9ŸôfÅ.¨—©íáåe7`å²,õSu­5í‘Y+WŸ £µ8ŽdÇP:,Ùé˜]ŠC•„ª f¼àšþ,S‹­þ_ÆÀ•Ųä}xçÁG¢}û_»0× ã·>iÇ¢cgÏ‚^¡‚†+ÇŸ© 4+ðÙ>ÜÿÊûF©u|eØð*¸©¶ qÃáïàW‹E–“¯½Vµ7Îô”/6EŸS¦¥\"=ìï~ÓÖk%¶n~i±÷=¢ù/­è—Ö£Úô$ºoiݶ,eu{×6…>>Øüêà-{Æ *Ò ¯é7XR7Ât“òëhשÕG°ù¤Dª#œI‘O»PGè^€Œ[ˆVhØ­§D SM2©t²îæ{ @urÖȯt‡…@·-ÛÛ“@L8a› Q#lr¦ Y5MY&ËçÏ_¼=¦«زÝeR+šîi§gnÛq[uc(â£x R—Ùïbai¾‹j§ÚÃrùDËÅ4+q^HÀcæ}ø© µdEùlÉŒ9½®3b+¼ ¬L& ®Pì&ø‰º±‡–³˜Ü³ ¸lE‡ƒ[øûó7¯_¼>ÿóí “° <©z¦óŸAѱ+%¬Q¹éšF›‰Úß‹iœú/fìâZŨʽñ& ¿`âëVú¡—CJâ‚Y-ÛâbåXçœÉôÛ°r™Ÿ(¨}Œ/ƒ%+*U–©¡•ÉfˆCŽÀG7r[½,0àÀ—1Ì^þÍ8y˜¦u}÷; \±dÙ'ÓÅ,-ÂÚ"¦ææÈ0_gg|‹]ר}eèÎvÄûY=Ú¨‘k««B߃ íÒHríh6ÜÆbëU<ÍŽ>Φjm¡D ÍÃ%Å6¸ŽgÓ–µš;P¾Ú黌χÖË:J1èTzBÚ¡×â¨EýŒ­oâþààÉùý›ú- ¿³„”ß±|ûãd–ìýd?_-‰ùÄá­¥óκ…P·À¸ðScÓVËÉiìòÄHDàh/JÝ3Ã1 ‡5Iî”Ð1* Æ$”“ÜN€†—ñ4PS±‘µ°ýeÐ)þT¾¾W5$F)ÖØµI,Õ«G]ÛÜ TcwœYí&ÞáÀbÚIvÖ¡ûÚvšÅÜ­Åîž,Ø{µXÝ’Fï«é|Ê)A+nPÙÞû6×6Š”õg@1/±”2°.îŸ4—œŒšofÃ+à9á¾Øwq—]ÂÝ%myoÅf‰…d ½0á€(ÔãØ+È’æˆJY‚ñ+”´SZŸìíñC¥£çeã䓃Òn³h0YöÑv%Äë„{v`\Eï^‡õ|Q8ÁžÖ_‰ôù4D+¶¦$®;+±!‚ð²O4"f ï‚ö€SÖ^;7ÁI‰}±_qPƒËAƒ:x:þ…éñ(ëÌ„ó¾žüm }cÅŽ— ·Í"‹iŠ "ˆKA–B«P£I¹,˜ 5„RÊ)¸dx *Įڗ} NÇ}çKð¦h²*!êíH.‹akN–¥¶²"âû³j•icõõ±åhóþÞ|P1¦oª–¸Lëû@íÍjzÌ鵇#¹kѼ$R¥j.ºøüƧmÅà‹õtœ®…G×Ä)R±˜¦Ë½ˆ%†·*~ö°m[8œa7?à”P<<ØÊŽÒN}ØŒXˆ HÛ5 ÂwO»ãóAáÄÍn“7'­¸Õm’ÿ[C—©ÐP&SB6¬K»‘¿Ö²["J:ÜCÁÍâ^éà?S®‹éQÀ-DåÚ˜ç•?‘û)[ ãFÛ’BÎMtÅtõ¯TŽáã —ö »6„VôÞŒZo|„jYÊÍH ü«üûpÅï*¢±á¢Ç‚H>K‹&­±àÉZIé1‡§b‚RM~Pže«|-0 z˜¿ßD_Sà‘[÷ns°‘Ñk¼ÿ *¤#¿Âß¡z—!+ÿ öaÍ|ª5³‰¤²wì&šñìN ‰€bÇ¿L—ê’ëbÚ§«$t‹–UB¨uâ!ãl5_r.÷k<½³4/–v/wÂà篘Ú2."ý'pè‡ÖåÐ7Ú÷i‡p…Ã<¨^Uë‘Ã;F ±ºT*¶#ײµÝhé†;®Ø!ËÒµß-|v¶ØÖ×iÉjcy Á¬‚K«e„ß×kªõpNx±(¸2`,ó¬×9ä!Fì1CÁ¨%jƒ;ê°Ð9T Ár!ðRD” £cÖøj5 DøGŸÛÐÏÐùëØÍ¨q#(B{RˆûÔÇb]ÏÔÖ°vhÝ” P‚o°6|ƒõàÔÁçH»Í‰_·ÀÛ_FÌÕ+e¹À‰B«UºÙ¡)¢H6ë~BÖȵ…‹ÎÁÃê•fa­9Ö`3¼MðÔà5h€×@ËWÚŸ´œ­¦Sºxùª¦¦YÊLÔ¬ch•–ñÕ>¦ožeKmÇ‚ŸôýŠ­, FÅÊ’¶dlªïÊ’R[c‰|¦[ '»ÇX’»Z|$˜{1l¸¤®'2ojäXá˜÷V¦•Ãû`b骯€¸¢2•LGa?çþƒÞTå~ç)¤'–Òš»ºHȪËdNCF´óô2™{ÁªD¯hË€=l®2§r¯zþ+Ñ.‘÷õºÑÛ÷ô×Ä ¨ù´ŽÔ½¨xð¥zûRÍ7¼3¸|Tß+âOD7Å‹äwÙý¦ÍS½œ ö÷»ÁÍm78 _½ùùõñ‹ïÂáç²ä—²ú¬‘±Ìç0–Pœ; ÀàÚ=üáÚâQÁÃ<-«Ig{Çf âË8Ƨ¹JÕéµÈÒ¹-ÈYÞ'„™cß±ƒÏÇ´æ¥ò - ̈K, ‚.ý¸˜ºAÚ‹¯xí¶EЈEªÖã¸Ç{De„T½u~)Å]$¤cJdûù$üÇîs6ø08:í¹#Vó)¤&Æ´oŸÿ8zùúû7á°ÇîÅžBæƒ,”SÃP‰cÂØ}çgÉù|uNö€aù€ì–ÊI¸£‘ñ´6¬G¡ù?ærÒ3¤¬‘$«F¸ššŒ¦JYNÎ-«ÆƒôÉ¥xS+÷¼˜ó•ìy„”ßl$c’ùƉ®èR{TÈ¡D@°QƒhU$yaK5]$ÓifÚî!ýû…3éžw‚‰…á8øNÔÄc(CÖ©!9Íü´}ŠóÔoÒâÏžâä§;$9÷³³×¸ðð^œo¶L|K’n_âT¿¡XñGwAw£µÔÖ@RSz:é¹d?Õ1Åíi\¤cô™è°ëÐ{^b)OT':ÿŽ·¡üaðå—¢½¸'…¸w•ß3·õ‚ýŽ}cÀJ!ý|üã›w/ÿï³ã—o^c D2‡„”ö#`»$hW"aç®DiY‘KÙß ?Ùë7Üá ‡IiôÐ ñ.ù<Ÿ@aØÒXnM!KùR|DDFkÐ-È`s_hÁ\ë eˆ~ßýiPvR1’D›mA݆ ­ß©`¸Žïܨ^?7 ç[‚Gáh…&QW3À$¹4´aœ'±êCVs¾„öº Žp=1·ÍQç.e<[¤SKcð¤s¢Ò抇E›“·03ˆ”……p¿îˆgŸ#Àîzùiè=HHS¦òtÄÁ~¥X¨‰ÇEp-ÑÕ0:Q Z ¼È"^ŸnÏðÖÖôWS[-òì2…Äñx p»‰ .Ÿe–è¿&ÚwÏšY‚ºÉXС"³Q m-QK-7h¤°(d¾¾7ÊIMl<¾W²RXJ ¡„Û~¤]¯CG!_ 4Þ‹Ò‰C$0™‡"§“áÐ;+9 Â&9¹L‚w<€±¦Ï(% Iñ±QèS…µ`©gn®ÿ«£û ß-H·mUÆewLI îJ²#¦é™~Ñrhß•ÒVnY à‚‰K é<¡ðÄGga—Ž&'+ŒXw±S]Z ÁP6±aÙÝ*8õ“š•x_¸ç» ƒeJ-_z*RGmÞí!TÔª]db/+IÍ6Zÿ½âL¥¡à¡,ïÔ@Š——÷³Ø(˜%lä¸-áªv^¾u§»iÿÛV—V0Ü{e).Âu ÍÞÃR8?éZt«lmw6Ý^îzaÊ”¼éG¹XÖV‰Ý˜ä,ï.Oi@h,QV iÄ„8Њ¹×HíÆÉ @“cemXW…SÖ‘7Uá?µ Ü¥x`ÔÞ$ µÿ¨€ÌÒÉdš\ŹJ„òg›ëô•øE‹¤£§I9cÚIqlÂ[¡+6y7`ñù‘QyêyÀ¥ÁÀªH$˜­r`ÍÍîy´ÕöžA#'>"¬ãéSñIžÆÓôWx!7Òžb9w –ÞK]!£ï‹1”Ó6Š¡kheÐãSxáIZ†ÅÎÍ È5¼*œWŸY¡×–«GØ Žó±œoZ„­¨EѺuR³lÙƒÞhØ l¬[éFøÀ¬­HÁË…XLÔa¦¿Ï8©À§[…ì°×¢QyË®ò¯a½K)R˺{_¤›½ „YsÉGRB“ÍkJ‚ªÒ7 A ž<ÙýÇ«Ÿvž<%Øñ[£V¿·ß¢× ³£ÖÏÇßïþ¥õô›'¨¿!Ã?aJÿ²¹ƒ5E¨Kz/ƒ÷âí8ðÉoµódu…ÙlTÔ”¡çjS¯Ûh›~$hÛת&±Ÿe %ÙØí–Y1¸KVÁ×oø_žì‰Ÿ¤ïþ} ¾€/t[„[!aée½L{)ʱdCUÌ…Ô¤¾¼+¶rάҥ—}¯0ÄÞ-(5NÙ´ƒ{˜v`/^oêCß©O“Ñé4žØ‘³ÜÊÆ¼¢’Rõ ™‹Õ‡Î¢K''ËÁèxj8HÖ"›ÉâÓe*¸¼$˜á¥iúˆ.Ï;C£í¶±<êégKLS>óÇî5îȪ\9nÝ*áŠún‹ÒÙž­zN Q î$¬·dMªå=ûhcïû>;ÞéËݸè¢&†e¼š.G¸ûè‘y)¹§å[ì€ ­±` ®Ë˸ ëìá[ðXsy¡ŸÛC©J[ÉK½ÇNv|ÕÙñÔº­›_Zÿ/­è—Ö1>ŽDÍ )9¨ "İ„”eÌ[-YN¾ö~iݶ:\‚YL½‹ç•3eº‚­H;çÁÈšäÖÅŸà0’”M 縟mÜ©•ð‚ €¿7 ŽÖÜ÷î þˆÅÿ_–O•¸ü0=ŸgŽ•kA¼»¶ S{Àÿþç³ùîµ÷°báÞ¤˜îA"´Óxü¡àq‡Û˜c¿¿¿ÿÕááÿìÓÿô?ƒÁþÿôöÿ|pøø1i×ÿóaÿà‚ýû ÀŠp<' \]$É´¢]Ýw¹ßÉ,})”¬OÆ#²Ý. îÆÎ,›¬¦I€'Ýxg‰ÿüî==ͳ>çÂòžôÝ‘oj¾[Íf×eN¶·²s3%ŠD_Wª;£&Z;ep#Ê`È$AGø31ëæ"ÏÆ,Ýf‡–¹Úá>!Gµœ‘ò £çc¢]²ñÌHÛµ4…§†h£^ çˆ$½LÚ‘x0;"7þ·˜íˆ ,BKîæ¡ÿRýnÍ bà2bÑèú¥~ZR—­b([‹¬Ô¶)Þñ±|¡­÷ØÖú°HëM×ÂÙÑmbW‡R5ŸóÎøßñŸ¾ÿgó³ô|•£ n˨Ùÿ÷÷êþ? Øÿ?ÿý_–ul¹]=v¥q) Ã¥™ǹþÜÛ4ý}Öÿã¾¾þû_öÖÿç¾þ¿#ÂR³ì1žt¢¬zèU·Ø¡MõçsKKÛ4Š´WSÒËÒ8p?xÂ5€Ž£ /”õ1üzðFº0žÃ3a%²Ly%ïòþNC¬'Ù^4»t;’@á’ø[ÀVÜk+uÄlŽ{Z¼y›S(o»¥øW(“Âë€IjµC“ÉH¢¬rI¯ÖtÐYÓÕÚBac¨O†^+^æXiS¾HÃL+y¥”IæËtyo^ê7ÌQÉÈ0''‡ûý®3¾€þ)ianÉp8TÇ>O¤¯®é_é£0 Væµ&³üãý8ûÌõÂ;:…þOé3äël•é„"¢ h%L”·z[þß?Þ°4?"\&$.˜^g0›Ö ²I2I&a×ÙS+aåhw;T˜\+Ï=•M`,òÒV„EÍ6Z¬èëÓ7jn>LrBÆ[‘‘ý¥ÄCFl"òyHˆ¿€¬-^â¡H‡–¯u=}««©ÍT«{´Z-ÊÕ$”M¬Ò¨ö“ýUœÏÙQ><ùîÅÛw/žc˜að–—Q3@„œ< øþØü îb&É‚Œ Y$zÁ«ì2Áú+Ø…÷‡»è× •ÔÀ¾;-]Œ¢¥kniCvè gæ õʾŸvÅ&ͼ™¬­5ÑƒÇæ¿èüǶíkÎýÁãÇúýO¿ÿÕÃùïs?ÿÑ}ÛÖ³îÈšÙN‚ÒÜìÈ•§ÀG–g‚åW¢/õ}ãž[Þ3è`ÄLa©ÐˆµJ*êäÈwÓ—ØVYSãt‚:ÁP\-ó8:¶iÇŽ»£3 — êÜœžõÈÐ;ê¡W»}lGLF;´¼Còáýk–M“xþŽí;6ÿä³·/ ØXµÑˆWº-³óói2Zä3{!Üò;¯Êæ­t`3W;>%¢WE9H ± “ðà¿i/a ¡²©DÚ/ö·-ö;hÆ×-4ã]!³Vn|l­¸fówžÂÏ"rôMýكșv1O£,OÏÓy<ÝÕc—{"6æ·äîÍ“OdüÑŠÉ…œ,®Œ«p`íu–$mÂx¡¿o%¿B.<ü†/Žÿ«yB¨Ñ |Ãm-Yw)ô׊öÒ49Tï>K—ƒâŽ‚© †Åó÷4‡‡gÑ3^\œ~ݦ*U'µçÂD ÊQrOë¥#L¸ß™ýGT Ñ#æKÚ’Xmÿ þóÿ1ظÿýìí¿—(,ï@VÖ°¥ÞR~k¢gF9=cGÉü²K /²µ‘¿‘‰û75Ó1§K̽ _|KúëÕ³¿eçwýgyhô—› «ö ÛI„y„,ûLDÃI}•àŽ0šA^°'@T•—fŸƒ^V¯‡äñГáSú@„(VN÷Ú6À:ëçs±¡Énxž/RÞghyÍ‚/8¥6P­œ@°‡õ€CjëHbûˆ¾8UðÅÝ{Ñm`Kh+ľôâéûl5‡Ë¸ÃýCÌiCŸ…ŠëÙi6mÓ±:ëÎ8¯|1Ïœù8>0ØÓm€u@*(›¿FGå) W{ ÕWDÆî' Öå—æxÝ@ÉÏQG’ŸçæHÖZZ€d× PC£Ç¢ÖA£GôxJÛ·Ù„¿ý&ê~ŸXqe¹Ÿ¹Ò °¿”y¤Iºå•ÿ…p—š¢Ÿ'¢¿Ç¥Óà¦ù0rjwµ$ƒFéƒý?aD!fÛ —ä¹"ÉV›„÷BŸ}·ÈÔz“¦ŽCvÖþŽ×l‘8‘>­0¬_blìÚtQ‘$#ÌÞ»ã¥x,ØA:¢‚>Ò†Òì+´C8iE¥”tÀ†eÉ9˲¤Œ(Ș€Z m¥öt7ßÓžWXv's²Ò"½°ã&tNNgËä<á´Â± hý}šÎ^XK0ÖSˆ ÀgÇX ð ©æ1ûfN*ù›PkFÎóplyYNþ'—if·£@š Ö<ƒ©½DM ˆÒ^—¦ƒ6Z-d4SWŸ„¬™`]×ÝnÓ§îå¶QtÔuía"+0²ïÔ7¦Y[7‰vŒµÓ-û&…5[C<¥{ ¼ús­©e~lÀŸÜÇ|`+áPä©9ßèö€ƒlÈ)EæôæµB#mBµMV†7¬¡¯1w¸a“’+Ô ™âíw1W\Ä^˜UÌñš>°&=d\ÅÜ{ð+£#ÅA—ÍyÖ½ü"|CŽ“å}’_&ߓߣþÿ¯ä#š/å¬R{Ÿw‘Þ;ÚQ_ Š¢Wxwô:[þ3Y>ãs³nW(¦ÿ7ÍÎÏ“|Ë`êÞÿí÷ÿ¬çùóã‡÷Ÿ}üßO(,Í3ÀÐ~uÿh«êÇ%ö·TœÁ3ÉV‘ı¥‹¡ß\ c,_KµG?²6îm˜ÍÎö_­µÓ“æ˜Û:v›MQ1ÇCxöîøï²LÍ÷€º÷û÷_=äÿýüõYiiðïWzA$÷‘£lZ½¨ðøæ–½öY6*W€î¸—žÆyECsgYΔÂR1+ñ2.OÏ/–AFX[2­ùªœ¨œD¢n âÛ ¢8?ïÓ„®ÃŽ-‘T²rt‡RÞOÉY%É—£êlËŸˆ4 lkIé¿UrU&ùý´ÔBÐÖ'vß­Eãdƒ H#‘ 1tvÞï⿪*DgøcPõ¬°Ô.Ì’;ñX´ñ­š8|0 ì?ÙþÃ×îÉr») ªí¿þAÿ°oØùŸ?ûï­–5쿲³úø/ÆŠYN4Ô"%z*™&à ìbºE¤Tþ±„ùÉ(攋öáfT¾ÖúÖÒ*8 °ëžË:4{™X3´{ÈŪ¸q7߈e“4Áµ5#ðVƒkëd×Ö¬žUDm@Ê*Vt‡Ç™çy¶ZŒŠ1±eÚ(ø‘Q¨7žfóDË ×i2¸§H>.óx¼±Y,c˜ªLE-ˆVó)dúÄ&½´ÅOÛÏ JnGÍHˆœÃ6P8ˆ5„òàà)û°ÈA¤>H…ŽP ì)1·(HàË/ƒ/à÷þÓ°GàxJ†ÁÖ²R–‰Ô>òÈ­¤´Ê5i;h©Ë½.ë–~ä±]Äá]‰ 9µ€h¡ŒQ6©É¤è½Š¨-±H½íUÌ—ÊDÝ^6Ït<ÿ&Áô†¥‚Œ‚ÅÉʯ{±µ2(vaKe1Bs Ï—rMâ9b"Psdñm™SHžIÍvšÝ•ZÈÕˆ#rWJÊU“"Õ‘|$ù˜Œi9Éplu…©t$ÇÌ|mz>å§dç%+.›ï&ÓŸ½H4‚ç@Rå%ÆV‰usk’Hºµ1Ð3¯n·,‡Ò ®ˆÎà­ï¡w™XUT gB¢Ic —6Ÿy¼À»¢v$ÆcK ðØF_l :>Üv€ã)š\hžN8F°ãLXæzJ'<Ç{oÒÅ ‰ÞxÉR)÷ŠCžÛÄà[É¡/cÝMí4]öm Éhd#}¨*=7†m‹(¤aEÙ 3B…ièOøŒe‚v~ðµ” ?'Êß?Aµè2¶±AÁ‹\Ðt7¡ª¦DÒAWÔæ žòS|•êüÿc =[-WŠœlzDdçpÊ0iŠIËEËR˜G)2©Ž»1O@ì¸Iƒ£f5I3 [U†@Ó‰ø4`áøëŠ:b%‰Mp æ÷(;sŠ5ƒ(ÿi@%u‚;¢:É6é/GÓЇÖ(^ØÉCðl@!mŠ;"‘6ËVi„©ÙFó:M§ð²s¾…” îŠ@Ê$Û¤êójëÊjæ8M,Ði_ñ±ü´\Bš¦àé4ÏòlP‡Ž'ý±ôzÜ€Ã;‚·)¹=‹?íP­¶UOì$›ü U[õà' Ò³.†6 ј…¼Áy< Úp1xi¼µ) )æãÀ² ›ö-sœ’kgŠ@Þæ_™WEQ3TOTvt%öüŠû3_¸jÛuò³Zzh>Y›*44²†wˆ{‰¸À’þk;øÑðOÆø¼Ýd¶X^ÛÙP´® ¢ec¨v~HøøzÿÃ’‚ˆ—[¹ªÉÿ¸ÿøPÏÿØï÷òö÷?,ƒ ê¸Æ%6‚%x‘,ÛD‹w©vWÊ óÌkä3ä+)®gðÛ¹ý8h:;]%5ÃV4òq¥k˜U.Yi^Óœðâ?^,¦)Íïµ÷ï"“ä±P¦|ãÛãpùq:Ê#ÒŒu´­=îu‰U™°]`içD"eänyuönÀA¶j’›ò–õ³<ësf«%ÝxÝ&ÇLnPíÀÍ@„U1+UˆáþkË´ç4§²ÕÓÙ&WiD:>FñL§ðû÷üç(:†RS¶|”kÑqé â.åF•ÅSi) s6Š3Ý€.XFààè› üÚqb ÀÑŽ]©½7ˆˆî0vúõΧÃ[1§Ÿ:ö#\!ãLÿí°C檖½Y²7½GéÿQÜU O'ˆ@Ó{ÓÅ“UÍ®?è>²¹€h³šBIÑÚØ(¤SFì"Ú‡Š‚sÈ©º$Ç~H-7'p.Ó1ÿ<η³îSú®®ß*á°& Ó$CVLcl°’A°Q‡Y;š(éÉ8AhóµP8CEÁÓ(“¡Æ­¦ ÊÏgP‡X6ØÈ/eoíÿˆ)ÎñªŽý‘Ål:(tÚÆ8D7DJ"·¦œ¦ó8¿Ö@ÉÆËd¹ËòîtÖÜ,I •2àÔ¶¥‚¥íÖvkök—Êi3÷½±&Göñ*gÕQë."Âì*6B{£¸CÚó¼¶P]:0ÈÈØ]¹³aÁËΆ¾ Z| ûìˆÏG"²-;k¿âûRŸZ`%5ª)ŸfùòäÊ´e—ÌýO3Õvyb²!<E,h¸@ëÍp4-»B‹¶}tÃòõŽÐy7JÞv^žÜ[«ã‰4æ9Q0Çì¹tÁ牙M¹*ÙD=ST©4ûtÃÿ¢ž^'aGûªõ¶¥¨0rWáW&¨`X6¼1ŠÐ?A œüÚÄÙ°:†¶9¬<×;zh?Ç”$óÆiZ`E‰p¶dè ÅñRZíclòÅštϨd9]ªš¾ÍEþç\²p¾4ŒÅ5ϱl¦ŒóA½,µsA¦®|4t+‚l>½ E§ (V6(™õvRD4¯2WC.ælL_€d0>¥]È7¤¿{  4ç!Äe|H®!Á¨õº~ÛæìK¢ÖýTKäNìÙ{îå(âǰížO6`WýáâÓñ«æðâïu2 à¨÷MôsyåúUùmŽÊ[ñ-PINGÈt|‘8~TNÙ±>ðàiì"Ñ…SLtüψ€ÒãXrá­&€«ÿ饿ÿîÿùáý÷çÿC…e¸Ú³>І¶«‰ž)ÁX#çòì3Ž‚è4ÐZ”E6X*j[,^rUÓ‚ì3ê@5=8ý? ÂË~¸Ë6b78áÅY;[¶ÜzV¡}DzQ{Q×6/îÊïÆø¿ý£òä,ýX±Û¯N2³Ï„Ê{ñ"Ý ó,[Žè¸]6~Çžgf¦x#kêI_z)½ ´)>;#3Ár8—ŸßýÔà ÆHç#© :ÛÍ­ÿ=cÅÄ!Wÿv¶M2ô~b;Lþow<¯§ÃaºJÄ-œòzزåáƒ0kz—8g.‘m»Æ¥le±ÿðWðZ`ÈM±Ä‡µË {àløµÙNñìíKÖx±èû5x6ë'PÛužŽM§_¸˜ÆF¢xÛË=À’Áö ª•…¢¿áße£h4¨z*ñ“W%‡°8윔l:‚ó×K¡êq!ÏA…E.†DJ`§(8aÔRƒ•Ó ¶;M—Þÿ¹UÏÜCœi,ìk”çVß({qEwº É ¾íÉÙd9*Á_tÜP³8ÿ%Ü'˜P²ÅYvÌʪ¢6è”"í(ž_wªuQJ7™¾Ù†pLÈ®ŠÇS¬ëi· ÿ¦¸`-PŠOÛÀ¦DˆOçÉ2&P73ÇŠÚ¼7ßýBïE…Žiƒ2Ò–,¥,´³ôWö6Ís5È¡²‚¡ç8´)°<Þ“¡©M’\u°pöÈ¢àºeÎyF›ßl#½ŠN,£^(Âác·_¹Z¬ÙÓ*þä4]Ùëu9¶nwˆ7JYWÚÿTËF¡Ôæ×0âS7І¶AImÆr‡vš4¹Þ£s#™Œ(< Pà…xm•€•eg™†‚WV BHÔ­š®ãÍJCFlßÑ rû=õHæJ¯•‚Ä"‰‘ðÙ*'[…’z€wi±MP‹ä|f»åÝP6æV)šYÎPûÓ߫վšG„-µ MUN!·ËÈ2AµbT;ªª€þä&ïCÉCÿeW~¢9f¡h‹à*î@¢k–$“(BÏš*®JÚ!ÌmȤ B}™³Ô©‚øÞÕ²¡ÃÂoU”JŠ7ŒŒÀC.^ͺOYM kêW¯­—[\;àÞV'f•l‡¼‹ë¬-§ä<ù«i¯ÝûcgOMŽû…v©Ê®˜a©“S^ºTd‡g‹Ÿž±Vyå‘pýoS™*ÐÙÖ~ÇG„£Ü™ØÎ|µ¸­‚3lE5ycï;WSÍâ½·£]lËÎGÓ˜+o-+_ß³®óú[l¼‡ŸÍ­ïIËH­­c¬c™?ác ·fdlk¾*Ì}5Œ'0òÀÃí˜A¾T¸+]ã¹ü¶¤iŒEçeÑhë®A…ŸEÊ2LÝçYPÌZ£Y èÖwB5Dt#nè¹yè°Yõ99€Íq»jcäàLLÿûˆÈˆ‘®Èšör<ÜÒ±Ðr%BÒÓËãõ$º²Æ•Gž3ªØz¢C6ö÷޳Ùbš| Šq2ó43oÝŠà*1Òƒf§ÿ†7wŽ;µáÀ·áAECmîÑ8[\“æj)`˜Ìùå@þ¢ WËlT¿“A3k‰Oi'æCŽf»™¡¯)Ë” ­k%§`Cû8•m”i”¡ŽžÆ8 üx0pñ`ÐŒƒ‰ƒ-ò`°)kð` óàÀ‡~<8pñà  H<8Ø"6åÁÁ<8ºh™-FÓä2×BGš®§dv%š(TõC8‡ÚÚR?`‹’éÇáC…°ßaü{±½ êøŸýƒ??îkõ¿ö÷ù>ûøŸ¿—²FÔ»6ÀGjk‹ñÑa¥5ObTû¼¿ÂC@N[jÁénpÒ,ACß$XÖèí3­v}.=–îÒ?¢ œfSéÁmå˜íç%zg¥§åfY®öªP¤ ô™vø UîÙvþMsØ'–z7™tmD›ã7ÉÆ˜àôšXÞäŸ0†^7Á"öAÑ ‘†Ýé_åÓwþ&U¶l…ŽËˆ±·Øà½‘ÁÉQu•S&æJRRjQ$ æ¦[Žmô'aFǺô¬í Ík`Ð7æk©ÎƒwÝ0Kx¦s%?@}R$Ê»Q¼\’Ÿ|²©”9‰ô®í“³ÕtЧ¢«>~ü•GŒïÅ‹Nú@©—SûÜ>jRag-ñä։㷇¦KöŸÈÓ°Õäuö_¿ÿÕcÝþ#?þùÁþû„öŸXÂZ"ºTlY¥4[Ôð‚€îx±Ø‘ÖôŽXš’Š :`Y}ÅJ¤VÃ>»Ü¶ ¡¯ÜÄc/a5¡Yt™Æ†,·G\Ô1­ã<Ëejàª)¿Ä1øš³§z‘;ôÎÒ¼àþÚ¶ÔY((àyr–ä‰úNosà9ËïAG°I«ì’ìéÒ2)2,ufn‡{!>^å9(÷~¼ÝѶ(š˜-4k—Àsh܈ÄbÊðê‹S«|îEŸJ%ÖÔ<2XÊÃÆð¯Ù©Øa¤ý…AªÒ.D íÞi6¹ωè0²&¥ÌoD–*áæÁi?ŒWË šjŠìV@•ÒΗiµclB¿?Vnwz“p r&Æßƒ8Y4÷£tž.±$a©©@à–ñ4µø#*vÒsB¸4õóÂHªoÿÑ1”6žŸ—é4Š^–nâ÷üKrÕ njÊÒT„uu éÛôÈL¯¥ÿ‡/i%ó÷3MâŠÀât …Ê!Ã= *¾ V„ûø&ZÌ¢UÃ!Ï}p•åÓIo ²L©…UÇ{dô“0^¤"¥[(ŽiR"±Ù™‘ÎÌ*ZñD¦{dÔ?芦î«È\d³DÕC¬ â`ÿ+ñE6t-"£j!Ñ!ùR"#w¼—Ù¹—C¥ ^X’ôìïãý·š/l–Ì2²t&¼Ö£|—YG ³/ýËÑf_£€»á‰ØG"jÙÊ|¨]¶LFÌU¶û¾tì¯OGÛÚ„T^Òž¿ÑÚL®U*Ò±ƒð»Ï®¸‚T«XI«¤#ÿâÈ互ŽtŽâDšDä ¤sùà_*'Ýñ £H[[Ð,àÍ»T…[=lópfôvÓ|DÃúì%Öôwó¿½óš–D·qc-É(®H,œ|Œ!Ò£—åçÒF>ϲiB›ð¹:n¨ãÉ$…:žz#€ ×<>~;úÇè‡wÏÞ¾=ÿéå‹×ÇtÚ~#͸åì>Ÿ¦‰Ø€×ý°r+x ¤Àª…2à°—ïˆEE¯ˆœ¿+wA¨¢-s¿ìqB1{ÿÏW}óÓòç½x²JÕCH'ÿC6M!ÏÎ\NËOo))–±/;'ƒ!"L[N 1šÐ Œ»?Ò¥\’Ä1wõ‚£Llg·&ÿ¿ÇÇS– ûñ$œ]ïÆtÙîÒßú!’ fÌd¯«»Ç{Èv†ñFb²IdŠù6Éfq ·³ë_ãl¦´±Ú}EBÎddÐ+âç[ƈþå1¡T· BÿrHñ%#ûŸ|œ@¢ûÜ¡u’îxiFbï>ì‹iºl·~™·:½"ËùA~œ”jÄ@ïê_(¸pÿ„àJmL–¥ÅŸ›U­¼ÕŸ»¾f<:R9ô5²åhïkÆ N¥¡i* ±|šgWàF`Ãó…¸CK‚+Ð¥^—d8§a’«GüóÐ8îjÝi&ª4ž¿yó^¾ j78šå‹éŠ ZXO³Gl óÞóiÿ°ÓX2ô “š@½ÕbY¦5®K6†$¬ÀªZ¾‘å%÷ º"­FK¢¯ÃY)@§ö7º 7dMÌ Ûe{OÜÛl@Y¢ö,Æ5Ïf1fFƒ¥5å¶šîëÜé ÿ Ñ­ü›r›3¦‘_a»L¥/¼?ËË ½wlá·d¯£‹ÏtXT*Ftª£þ× ÜøÓÑÀßÇr XÌÌQð#” hªˆgñ ×Þt¨ß4jBá üËßâ<Šè_1Kü¨ì„Ëå"ÚÛ#{r<½ Æ'DÙF {BÿÝ£¼¡ÿ´×P%gIAŽ$â(‘ÿÃU›S/0‰Û)å€þ€×tüø¢–ZI—Ñ2"åˆ~_,7ê¡ xE“+,«­É¿Ò<™»ŒS<ƒž A–‹ ˆÏâù5ääÂ,á€Ä€º3,,Ï¡2-•‡¿5pQ‚{Ô¾:a0IVyî & ïö…òˆ×NÝÄ+¦(œCåJq¤Ñ0¸©qW+Mh¹Wáæi—Í“­Ñí„®yîS™¶µ%o¡äé*Nв²Ùý‰šRbö%ö„ê áQ‹ô£CqÈRÈ^©Õ’ަV£pã<¯íVY„SrèM>çÍà ³önðy Ò°%ó§ÁH—,Xƒ‡5¹¥5)’‡£ÿ‡Q!]•°ЂX¬³´(ÔÇÌxç–Ô‡ùäG¬9ôDWMeÓÔƒ#u<éê0DFùË0´‡ŒúìÕM9TÍ#ýÛF}a‰ )© ù']4¦n¬OJdáó¦rI«ÕMmë"À¢ºÄÄ”.Ä–ñmMܰ>_éË Ìâ£åU¶=“h“§íï çò2'"‘žÁQ?=£TciÝS~Kw/Ä#Gzʵ®¼öÝó$ÄÑÃò‚°kí'Aþ”Š/zïEbJâ™í‹àp¿ 7Ê1¤ÞK§!Là»þO˜E5ü„VƒIĵvI(<ðЃ¬|8AFÒUè&Våi–M“xn"®Ô¼«dD»ä…¬ ¬é4ãƒc|q$­UWt ºÁ+bê¦+²yXß‹6¢QQílp>‘šço^¿x}<:þç[æEŒ´r)¡ËDO¬4³[Q€·ï7Ú”§ãèj>MŠ¢ù ë‘1žn“¡tÜ“Kß7}´7E™—‡™©P—Õu3é8,ÞçiQ6·Öw:T¦gíJŒèÔ£:dÓÊÐ!þ`ž€uËÈ Pmz¬»´êLÖMÏpüß ­‡'H¶áþîl°”öƒÝ§è>òޏjS”¥@Þçœy¤µ%ôꥒI‡ É 4uÖo #¿Ï­Ã×´†B/ÒéÄ’¿Êu!A~‘-(’B-%¡,Õ\‰p7µ‘¼ziû½„¢k÷=¶öV9S(wÕNx¶)åIõª9mÍãsÑúå|™œ'¹;7‹ f9™QæË§<õyÏ'^àj°õ­š“™ Bîg";#Ó0f0MÈqr$q'²&ÝœÊh.Œ,û[_÷‘¨±of½«ZMN5' JoïÆù­ì-D% wɲ^æ1Ù^.ʘk1 VÃhȉP“p?UGÚe±é¯ôz”c'½¼ñPÀ¿«¹ÊÐÖ¬c“æ$ãoÃÕ ª„úæSV[†½[räÊcàj¤8‰œ64† KT1g•ÖEƒŽË9â½æê«Cñ&>¿˜Fl޼æR£ˆ>e—W’F’\ùh'šÙŠsCb‚«‰RF’®$˜Šl…€^D’30|"¢t•çðÆjw‘«zFá‰ùy`–­æð§xËäÚ¨'Ùêtz=âíìO™­å|¦]¶Wïß×®=QÖ¢R%>ÒCꄎ“uv޵իÀÞõd=TÁM,Q€ûƒÐúJ*Y•ItÁe’/Ý!eêm<$02Êq˜ùGbáÓåõÐÄÁ›=å9ÁÖGßÁËÜÂ/Ö¾SåÁœ_){æÍ‹Ýk®ƸdF„Næo•¾4Aƒ™Qål´ Š7›pL¢)å Ùü9 özÜ n;6—õ‰2Ò°*Ê”p6O¾•ßW‡)Ä´uïhsXÚôÓ gÁ`Œ3Ïch5Μ“9½98ö¢ùjvJ´I-[8°íÞ;é^7 ]É·“ýÝÿzr-xòD| 4e$¼¿!¥ûCÅ\0>dºÊ3rÌõšM½Á;Ü?tI ŒV"3Œ ¶=|–N&Ód žeRž!šDœ>#ö¸©*½qu×J`|:.¥/¸µœX eÓ1Ï0ÕªÄzW$AŠw&¤ÚJèÖ.|.„kÔì²Æ³Öüîx$5´áþÀqE¾#_­zÚgeëÝIa[9M'eâBœ]ºy(Ø[n€Q<µÅ«Ùg2›l;ÛDuJ3÷ÃŽÏ \¨ ´1'Šõ ƒªŠ6ªŠŽmóbáLì&d#…öÕ¯aÙX« ‡Òvea1Â9Liø™Eêmh‘Y0-9Dþ5;=½Ž{a³€,Ï‚lh;F"6‹¡FÖúbyíƒßÊ‚^nà‚ÿxõÓ:œŸñ¿áôy‚¹¾©‡ÿãlºMú7@cõùbaDøI>øy’œ¥s²]AàLk,Dmíg³t¹Ns=ƒwe3_Є¨Ç© ûô«v; Ö™Î?Gh¥[ºMØù!&„ûŠÖë›CUÂÕb‘å@@Ôßóå.xeC¯ˆ§GeÊ+Úw}i“nÐÒ‰ÐÚi¤›mÜ*yuW‹ÁkûnJò¦…âÚŠZljt»/S;øE‡æ—Âû1¿çO¯uë<í³ÁСÎsXh Ç|7^ÁØ ’±†tŒ/ÀL\­–g» wìËÚºïNâe\¹ÍÕ]À S% õzšÅ“œG›E3«Œ™‹¬.Í'…¤äË¥ ú¬¤0¸×-Ú©R|„wƬ„B…€>›U˜œÎ-Iûêr =g2w +¼ ™¬egÁ·€¬È=¥ùz' @ó¿î™÷Ýã#d_bu̸»}ugƒ;­UzñHßFq'ÒE|™é9Dd”ŒƒsÉh·PýÁä‘ ÒI×ݘ b¤pÑ3ý#›¢AY³sîe² éõó»Ÿlä¢ç92ÍÓtrD`·LÁ»¿.2‹Z_Ê­“, µ\@ÖnŸ'þ—Ì– ![Ûò°xROÊ.Ë?ª'™UwñÇMr[À³Ü*”t€”ŠÍ‰ðó²Êg9d î᳡þvp=l’oX…¢ Í9”ž„,1pñš“6pûG€€ªxçE @oy6uCΫ Ëd›ã–D8èTP¡×ð’<œ‡ñðÛcš_*ËÏòìׄSd ˜÷Îò$ù5ùÜ ÁdxÏt–^[L’øÞ…¤ÓÏWÅ2›Ñoøø/¼OjH‰© eb^3Ï&sYÞqÌ &$Mö¯E®JyÊù7µ¼u5 m¡¸ÀÝÙ‘êœÃᢴkcÉ“IšËk‡ž]é艃U>¥&1£ìÁþÀ_Íò±‰ØõȾ‘b…ù½¤ç'~s\n¹2 5ëí€"²<&DÙ̲Kr”\&3rDŒótz T"÷B{j(YöÀ]úšîkç˜I—&…N¿@½ ßëÛײ¼û éÌsë'×JR¿¿x÷þå›×Tá—=˜µ +î…ÏæA 8sÈ +XB(…úYeéb;ËÃmÑ,žÃYÎù†BÜ-ÇŠl‰÷Ö•êþ§—jX¥Tc‰ž‚»³ÄóTA%<Ñð+ õ© Ã@n(XèkZ“Î úÚhF¥áS…˾´àþB¤åÐ ƒ £\ [•óäJFIäA#v-Ï6[СÀw‚h|:¶”qÜÈñ«uÛH“äÌw$hÚQIÀŠ•Bˆw:'B '¯K¢é >ªÚÉG°¾húúN ]hY,)ð ØñMK0þ[þKðÛoGîP*…€º,a¹swW;qy!õ8¬&QXæ0×™ï(×™Nn¶šH×i:NA=a°Ÿ öâ5¬‹\YEÇY i”ô£A³áy2Or¨Ô/Ò­ñ¤šβDa,šk%aå ðÒT|<͉ÎJyþW_Êʱ éEµ¤hi,¹¢”OÕ.ügù9–=(°Êb‡×²­ õ/Ž… ”ÏÀhZ¾œ…²°.¡„dÛ2Ôª¸`¹1™¶e ^˜ÃTºå 6Í% (%IIϪÓå«9µû•VÀˆB) eds½¡EHXA7̶‹õ$ÞüŸPrú© Onܱp«G<ÉŸÜ00:µ5ÜCZÔÓN¾Sòï6îÎÔeeѬTâåB±9ÇMü\’…zrÌgw«ÑBj×€tòºKPsbbKŸÖ. ¦(+ñmŠ*½BÛ¢8Våµ"Û, {Úü<ÀÚˆò¥ÏSÑ(w‚X¬wÑ_º|å•è©]¤Rõfoé£HúÍ“’Ì>¤þ­ËØT? 1J×à°|ÔGá(ËE7xŒ) \zBš®Jc‰Am2ÈcèÂTŸäQ·I¬Ã03òÊ#(MDÌ¡™†ZäiF±ç®"ä™t© lµ™ÐámÔ¯Ì #îJÕÁêP¹ó+­… á°F)À·£‚Ç)âñA¿œ,; E£|§öö¡Ï#@%GÈÿÏÞÛu·$ ‚÷Y¿-Ÿ.]%R²]kW•Ëåêrß*Ûc©úv¯šƒIHB‰$ØhY-kžæuÏþ…ݳϻOû°{Μý5;³gÿÅfD~ 3‘ø$(Q.º«m HdFFDFFFƇ– q&aFü妒†+á¾CÊz›h5¬ GÿàH3’å“胧gdÎ6ì{íÌ!óæã–CÛu`1Q÷V»ÃúäYMn$¶2²Ox]G16ÛnWÂñÑÁQÆ*B("Œë‰À‹§’çS¯?Åû›”ð‰Ó’q$1½Y8Û£8 Ë¡ rÒ?ëžz_L½HÝ#'"ôù,VñÅb8èPþVtÛTV“{G±ˆÀK Ȳ¼ŠÙ•x-Ä9(Cœ$œ°$@ÙÁ Þ@$‚a„0˜nÑ¿‚ë†E=ºjÒƒËð“âF_RÎ=ºO»ËùÈ‹ü[F½]s(bšç‰;m;‚晾5¦3éSUrB EâÊØØìù×]Ú 2‰i…ß=– 7,mHËVƒe¬Mƶ¥n`}B7¶MzQ&c¼Hë2ìO*†2™,žîP…jvÍÇÅD¿¡…tÉ‹ŒËø¤| 1­Í%•4¦C*†ÁSûCÐÜùÐ(" Œ¦ŸvR¡>Ü÷œµ ì?Ýîš¶ÞŒýÛ±–4]¨Ë:Ãä’B‹ 1*ãrv÷X Ýò–˜]¦´ÎÚ9Ū5ÔÌþYðÑ@uŽ Šq&Äýö^£Ýç¾ö?ôVf ©›vÎáS-*þÈzóö䕃óGVÀMvþï¢`' é-xCÑS/‘™lÜ~Ü-…k N‡°ãl Î/¼`¹£õlt ‰åEo8ŸeEÀ®……Ç`B£×ט‰9˜áA;•È!UVðÅË—¯Þ¤®?ÌÆ]6—î‡Þ—•=tž´k@>òf€ý!F¢D4òdá.÷¨ÇV£³ùW.B*•wQ&–æÒa0ó×e*ÚËT? &¾õùë8^øÞÔ_`Þ'×ýáõO¯\7מ-Á9œDàKæÈ†TøRH«•ú«ðbÀïÂE›wÆj–ìŠ`‰ Q–öL§KïÔ~YÑöÀO~Nö^€ê»÷vœ3z!ó»VUª$Ù‘’3ÊX¢OYÃRPUßÕšâÙYè- ÅF‡¾°v|Ú?¯2ÊÓÑÆrE¡R.%¹²ÿ¹ò¤óïÕlåùá‘õnâü‹p2IùЉ¥¶$ù[HnG²ñ[°Çá™mA¿ÅÁÿ˜z9Λ0Θ¸‰º¢ekÿî@÷Û¨ýÁ[œGÉIñìYnoŽó Ú¡PÀ2%µ-‹éå‚QdHif±=Ãïàªú˜tbàC±õ¾žYáбÔò3á‘‹ôÐhAõB õBz Èz*s†dà/˜¹DgÅ“ë$G*øø»IÄËuÊížîb9ãÖí.¯hØ‘ƒW¯´QÜË`6vÃ3ý¾ÚѹæŒ5 '2GB—M¬31;oærŸ®¼ÛÍAÅ»`ƒÐ«‡ÌÓÁz0#_êl‘”BRê⫎0â@ ‡ù¹UÂÑ–&4©Š˜{Cˆ?û@úWEÔ;ÒŠ û ÛQ®|<åq@7ãÒÈÆç¯[_8°í´WÞP6c햸ݷ[âvKÜÒÄ´%¦JÖÓ¿áÿÿ²™ 4É.Ä×.<é.† ŽqÐ;8xrtô/ôöo¿÷øéãé==yêl 1Þ|.Ç ˜SßjΡJÔ$*ŽDª °êÎBqi Viž€.U_ÛgW”ã7‰Ê–7±ˆ•¶VlŽu ÿd\að~M5Ìä»¾Ô Z4ídÓ^„Ëó ~a'ríQ:Y#À? $œá-CÊ­Ÿ.ô)˜Dž[o™šÅ^ã…~Kj„ AfÒOËYø íª”Æ¢þ!Ž KÄ©I…—€ ÏÑýÓËabdÄg êFî„äÒ)d˜ª Pæn°’…®7ƒŠ;`bmÙ?מ‘hÌp¡âa„Vb»¼( öêȦœ‰M k²5Ðä\‡ 2vp÷$™†ãåÄ·hŸÇ/‰_'ÎåÄâ·\Dh«¼Kÿ¥˜RãÌRë‡ÂŸ¤S‰h¥òµ¤9(Üq’~Wä¨Ss¯í (¥ß¾±c¹_iû6¿¦Núwµ àüÅ4Äê~e…Gˆ’sÝr‰}’É[Æá”ÐöÆkˆ»‹¬ƒ±…zÂ뢧耥ˆð'2ŠÖM¤Þ½±“éþN"–€rª$€GªÃÉPI¯ RB›AuŠ =¸q±ž3’bƒ Ï¤-bèc²%¾“ü¦ÈwªÒopWjäün5i[uD¬1*bö ¥ :wY2àD©‹>^ƒÖãtìÀ(º¤…¡'ù@øÑ Ò#K¶Kª¡Y„Ñ­G”›Y\0Á½}ïÂÅØqÞûºc@×ZŽ­™ï±ò{ô‰õ¥¿¸®‹¿ï=½2ÖJC‹@îEDíLAkaëK€R6™Ä]ˆMU>%°We¢¦$m²6NL6¿$…‹'ä袾5¡ß­eߪ$ò8ë¤Î¬iŽÇ¨Ñ…?—þ5?T‡Ëüà³OÑ+[n¬ä¨¹–ÇràŸ5šè(êØVNYW'òxåÙ4Ü /º¼li®ìdËæÅÒ?º¡-T×ڲ⌷ì"Yl6;È´lk3-É”ÃJ2Œw²2ŠÒŒ¡fR‘Cž «îM†ow®I8®üŽÉa+ëEµ¿ r0([w!Y#D[¯mÜçÌá—)”U, P*1d×¹Ù Æ»Nïö6# >‹Q$¥ïñL´¹LÃ!­*aúS¿=0°ÿ¢2{EwÂ_Ñ®sÊ9¬CèßnóS¨Ù¼«kXe™Kc-¸Ë*tJ)¿5æ0•ÂR8`&KÉ>}Œ¥0yÍs Þœâ×ëÓ'pÅ£im 5I‰Z0ªtb÷€¿†³Ùu€õéÚ™zyU )“‘Êe·ŽåìÖ­Tž÷²É/­gÏöþúóO;Ͼ!_ ïÝ^÷`—ÌjB֋绿œü°÷Õî7_ï<ƒýókÒ÷36ůqœg€©¯%<=ÛÇ'Ðp_´|¶O¿†ñ ˜½ç7‚»1}Ç–½7ˆ½‘7*•&Höt˜ò®³+My÷Ö˜ð5ÍŽsk“œ¼­÷ÞèÒq §È;[ޤyÍâðE‹”]y =–6R;wÏåäñáü^Cco1¦…q’p“™…"@Õ#Jdº¡¯À­€ião:{Dsÿ2 ­›¸wÓG<zåß²i~~>ûÛ¿›Xަõø X*‡„®Ïɱè{ž‘ðî×§÷Áƒ+ðy\r•ò¨=›‚Ý*^±m;»FbT-$Ø üTUÐÜÆ4b-I¶Ikò*üuW6[à„=Ò ü+3>—îÿá÷~F»¾\S²ò1Æ$}JÉÈ;ÑŠôPsïÜïX=Ó+œdÇbÿÏZë>mÝÏ95”:“ &wYú)¹†=ÇÚrד]¸Qàù ­FIÃòØãÛTÛ¾¹m_Î}sk*š`Zˆ|)›&_fC|Âdÿ/L– ×÷û0/ã"irÆh%¯°|ÿ¯ÞA¿ úõûOz·þ_÷çÿ•vô¼á8®§˜ª“…4&É’æÈý2Zú.ÞC®:ë‚hHr¥òb±¼¨¼T÷`•týD'‚h^±-›•±®¼’_ý1Ñ8¨³9ôsBÿX¦ch£]Ãn—ÛÙ [79ÙQ.³’·R†K;ò* dTÈ;Iμ²wñ‚>‘œÜJJÕŒèÐTÔvã•ì$Ü—9˜)Ø.,?•Æjº;UÜ üÀó;C ¶?Ÿ@Æ Å QY “‘‚§õ èævÐ`È‚gìÌCXìPÊçÎgçsÝx*™;iNC•®ÍÛÄÑ—Sç!nÀ1ç#AÚhâAb)Voª‘­â.·¾¢)¼eËšö.ª†¥ÁCX|Nã·¡“1VjUb¥vÕγ Ø¿i…ï\Žý¦•IRæšb¬¡ðPTÉG"QË§ŽØ½ˆ§“†‘µña’Ÿí³ý¥tsi.4—ÞaÔ¶Ä=é?Õ쇇Ožníjÿ{M™ãòÆô–†F€^À^ãò{U\ÅmÖõLyGq·b¡äªýƒƒtŸ2ÉãäÄ–rç˜ »ñ±vúr –aBKÔû3gÎÒ2æL¶ê³€lݱá(E¦«ÍŸ'ã-q¯\ü¤ÈûëÞKúÍsÈÇòÄÁ(×F¥_³{Ï¡ïr‡ÙÅÐMY‹ÕóP!,‰Ž'eÑA)‰‰è"¼ÒŽQܤ¡îþfåË·™O~ääÆŽ< 54Á)­ú¼ÖK€$Sêÿ˜—*•þ€·}¦ ;ܱ"7yªÑþTËüÔ±üSX4ÈÍx7çT ‰ã=â–ve üË[R¼!%y-º,QGDºl†Ô„ {@:qÛÄ.Íié}L.2 .ýô.RbN²Ï‚¤‡ótµ|j,à,-gÒL—\^Wš*އ³ÍM?RíMf‹ú!Ûª6@³Ù·"v«ãmu¼®ã=hCžaØŠå­XÞj¾¿EÍ÷NÝ óýEš5Æÿ<6ÄÿlãÿïäÏ#‘«Ì±0[ÐN}àDÊ"\iR9=.nâÇ-¿Tž·»"u|‹–C&«2 >Që¡Ðn¯ƒ2œøS¾îÓÁxK9`^ÿDŠ×õçÿ=8:zÜO­ÿíýïÏÿâiÅ‹å(®•¹ÄI|ÙAÞíÂð;Ó1S3½CÓ?a"âÆz;÷gÇ ŠšαNÓÝX¥yq/˜$‹WųàI(I5n¿Ø£‰MöþÍ¿¦·€â ™ìR¤-¿Uw)È•itE©Àã³A‡›…}Ñ øèõ¢Ez Îg¼( •Uiâ´ôãê¼o–ð!5TÚãB¨ rY™Pî{jqV£ˆ¯ˆŽ•BQ;ËM åHü¥Èùn4ŸqËîØíîÔ›·¾pSóvR#'†$“¡&ÍeÒå|êÓnDx'ÞèI,"ð*íŒgËÉ„w¥ñ‹!Š·:jÜÌ=„Hä^÷I·Ç ‚m>%Ùúú¹Õ‡2à-ñkÏúâ «Õ©ÀLÃït@òö°M[ã[òû“v»."Ÿ6œ+[ói€¶óîY°ˆâö©-q#+€U\¼†jѪ=|ˆ– _á¬Ñ$ŒÔ'd†Áìr¥]C’ÿ“д6&öKËÿ”ÿGïÉáá6þs“ì¿â´ŽÊÕ¯á0r½yÐ.yhOŽÍN8SÒVHoâ«PÞò»‹…¯¥» ½?=ó„h—ê]o'ÿ–Þ}q0 §Ã`æ<ü™ æÅ< "‘£¨ zxؽó¡—$’`¥—Ø;—ç•0¥Œ˜†ËYÌÇNƒ«XàNy5í/tx¥Û¯…Ù£¼Éô ÿ£?ZâÅ3‘—"ý–!óÈ€QÝ­8˜&Ú,^¨éCô ò¸; ¯và ÖÛŸ‘>È‘ „«K·Y[ºhñ­=Þ«Ìb=³ÿ–îÿ¦Áx<ñ¯¼…¿™CöÁ•¨‘Í Hþ>îéúÿÓƒ­ýwüÿ€ž6„Ÿ³ A¸Åq¾ϳ]LÛCÆ F°Ê'S¢O¯]üÑFïe䣮Ep§—¸ŠÀsª³Ñ7ð3>#Ê–á[!eÆQ4¾ûæ•]Ûh  zög1èçD— άóàƒÏœ‰­ÑKãA %É/'?¾}ÿúxqòúíÔûÑOÛ§˜rá«–í‰~ Fô‡öNI×>wý(.…i«s_Ã+¸k<:èÁ¥ãÕ"$Ú8€¿á„×1I¦ü$ pííã òMš9 ÈÿÃþQJþ?~¼•ÿ›¤ÿ§Åý÷Ç?©Ò>×7Uæá$]‚ïèÞ×-òÏmâòùqLÔÞÄûFP<¢‚×›O„gbt‡üaŽ…òG|ó€£Ê &oÐH">‚ˆjHÑÎ88'ú °Â§s»°4_?ލ”Ãc¼«–`ƒk(K»ÕrȶÔîÂUb+wûìX;šs!Ž+ƒÞá柜:ø`ÐHKÞÐ'äÕÉ3@áÀì ƒq1š@dô#%¸sQÁ§ËIÌ™‚¾FĬ¡ÓîÔ_œû-ÎAÑr¯(ǵï˜xôqù»ä^‡-Š:‰j€”gŠÄeöÓ ñg7 g­Y»´WuêR›<ún¢?VZ®""Gý¬³^ ÈrGêÈò«Äì(mëO~ošŸ¯äýy“æ¼)KmÓÐ[ß°MÒÿ¢‚ÎÍñÿGŸ¦ò<ÞÆÿÞ§þWÇp,ø…Š!áCõJײB¥Fª€\ ;Q —DH€†¸Äƒ=žèñ8/.·èµÖwË`2öx—&‚abvÁ™Ä$ú«ÍŠôƒLÁ ·¥¾Ë@ïÂ¥þ´Ùnáœ{jÿèO&!øÜ.ü®=}Ò„TWOÖgÖ,Ì8V[Ö·id@Z¼ñV±q\]j|jV éÔ¼ &ÔØÍ˜4*5²1šo«hzÙVQõi7Äïéþó÷Õuôþ˜ôLn‰Ð%ë*˜ù·äŽ.@/ŸK÷#xÙˆ ÆA¤Œ&Y>Ú %¬A@à_H7&ZÓSûßÿýß÷^HÌb¬çÿÙÚÿ øýÜÏéE©?Ç×ßd-‘i8^’F"h`ö<0>­è™tk%”¡®`ëó@V„¸ö*Lp õIñ)°ÏÂ^Ž…mÝžòfåiGÍÌë9ˆ-ëôƺð¯É ×á’ôCØ ‡÷ OÈ`øû?É+*ƒlU‘å8'üØ«, `j¢´ÞáVJðQjÄrc‹ó ÷¢‡•^¹1›—h+®0aRòw(‰V­ŒÀâ ñÌÖÅÀT ccˆÛjã¿1ý¿±«¿ú¯w¤ûÿõž>}ÜÛêÿjÿM_ôÝd5CcðpâÍ.]²#µƒ¯ô ÍÁ®ª6Û?Be¶n© Y-ÄñÈú7ߟƒÄj* ž ç‚Ùy—:JÝûÊl$/çí®7»4^4R¯º.<š`Ü=š1`…+Â…Ô˜˜EÈœ˜ M&©v Ó$cGò²ºD²›Û$Ûˆ'ƒ#8Ž4$'¦H±ÑñQ„–4ÔÒÆF#0væÅJ}޼¾°­Ö>#< Ïùw0iÙ<Ÿž¡>+ ¢xÙ ƒ‘ˆ>Dˆî-Æxä¼ÕÄT¤ðVpéÀUŠ<ÅŸâ…ÏW@¥W¥Éat ¢Ìê2ÿàé”úîª#™’î…äP„>±‘%9¡Z\…ÈÎ8#¨ÙC\.g^%–)EŠõ* æë¬"àå–ž©ö ‚†.¥þØ"RqFÕtµéLð-oENöÒ§‰â”v½ÙµÌÈÖ5AvˆV†üU9:„…ðiú)éüÙ3k*9C—d$`e+'A…è"¼"-ÓP¥îš‘(&0'nÈÉ“yþü샎e!î<óÊ:€&I­Ÿ|.‚,BjµzÏß3e X°»Š!¹$ãÜ÷SÛ¨9ƒ’ÆÊ®{çLo8r ]am<+ áȯà€ Pψ“¼¤N@GlÆ€ÕF’½XNÙŒ2£¾•« GûÀ±ìÏ¥MVÌpÔÎ:¥s2©¬Q‚^ê4K"N¯c!%)Û[ê­‰zé ‰ÅR(»Ïüv£8! à‘EÅÀ•%¤óbµx˜š~!_—ft/àv—q ¸÷ªpNïKcÿÌ[Nb™˜i ’Œjܬöê£7Oü‡¤ϲđdØ„çV\¯oÈx³K0})qÚù~ØÍvAR³, Jù´ ©…˜‰v8I°HaK#2h‹ j0°L(‹ðy;® QG ÍûÙâëRœª­FtšØ0eK­Ft 9Õg$bÒñ xÌŽ{ßÑ*O¶ÙVŠÆKP4²{yú9Ô=¼öm9^ ˜T7ª÷IpÌ“h7I rR%åxÙÕ~ïó7ß»(¼ï‘TȇR•)aV"… 0=Õ°¼f‡ÂtÐuE!c0Ÿ³[fn³ý—¦Ñ¼£øïãTþ·ƒÞ“­ÿï&Ä gìÁ]Y|]`¦5\£Lîã!뙤‡g¯°¿DÒß“åÉãÀåºöÎÁhg'Ý쉄ôw ö¥ÌŠÀBÒGÏž‘]xr–ØBâxár{¯E“g½¤qq꾂Ç—åèàð~uÖ±Ô> âeÙMtA0 ÉÊuŽ0QNEññr>1à|<ƒYüƒw)6¿<Ï çZ<ÈzA]lÀq™”䑿D?º‡‚$aÜ‹««9tM‡ËÅ9x0ØüàŠ‡VŸéøÌ xP°ç‹À‹ýIrÌLÓEÜBè=ûÚ±ŽzL“w2·¡½͆/ ££ð|Õa“1áC–íòì¬k—…T ×ÑúЀæç>4uY,Í*h-¼=>80\¨x⸤§X^}| oµ³2|wr—z ñnænãqš{ƒ3ëÊ›©¹ÒKñÇ ~ï@Ž01J‚<]HƉҋšÁBÑÇhǯ¼_ìÚêí;±42©Ûu/0ÍuëÕ­ÿñÔŸwÿÛ;êêõ?zÛú{ÿ/)zè ˆt¦‚o$%?ÒAþ¼H ËÔ¤è}®Mþ™ý®ÔÙW‚–lC’ò%é¦?’7e@b‰ê™œë0Ÿ­éIŸ8–øtìÇ^0q’ôÅWÁ˜ˆ@ôÿ㪠ý7Û†aă‘¡Rê÷ÚÕÅ„ÿï$,½@÷{@²‡5"JûbEP°- w-\X#"+ÂiŠm^âcº*ž™R[ ã•v‘>\qH=%è:‚Ý0ÑU E·?–ŠeØeÏxÔYP«Œí†=&sæ¥3†×\OšÂ·pŒOë=¡ÈgYèHÄPO)Òí3Ó8Ò—Îï—3ˆgä ÆéJÊT#Yñ B(´ç‚kÏbé«[üàd(‡µÒx+:Û%€+™eÊa3_Á.«¹IÕгÊgŒ!ã!*}u0ÉvÁ¯XÆ4ðâ>;óDw§,éø±)ØëˆÃ—VYêãÍA)+‘ÃäZ0£r¨¡gsðHáq´Tˆë^¶7»ˆ–]gðî­]Ÿ‰êõ9 5­2 õ4…»Î.UÉU$XÕ‹ã³wR$(©t Ô¬·¼y°Ùã©ÌÞBxð¨ý-‡ÓÉæÒ‹wWË`÷Ù7€ –¬ðùßw{݃¿ïŠÒÂäÁ/'?ì}õ÷Ýo¾þûìâü`YϘü5ÒèÙ>ÿ•4Úç­vë.¨Mœê ©6 è úZ]?ÏöÙclB[3"ñO%éë²6,ÆJÀ(Á²ú2Otivâ§TS£î—‘JVµìF'Rö3zý/fM´ó›ÒeôèHŽ5ñ¦Ã±‡Q´Âã‚Ã~¼ðFð3»[!?ù³Ÿ*”é»ac$ [9¿3 _\º?=[löŸÛ»S*}†Ï¿ÎÓ/TCÌÂ?_N¼³|á±ïžNÍy3›W8Ó™C}iã1šØjFhSu´yÙ¡Óˆ<£åP²‡Ö@ÞA»4{¦-‰ÛKµÏëþOÈ;¸ÿë?}ÚOßÿ=>ØÞÿmèýßœ9J‹¶èÚ.b€YàÛM]9¡$H%ô+ÒSr$‘ÆRh:;t0N–ù C€†>¤7Ñ!Çþ™êø1 ÃËB=ÀÎO¾€”H›Ì”ÌkK '‘¡ž´ë¸ø}õÜúƒÌb¿{qò£ûúÍoY…)ðö¹‚0D[$ªyùòÕ»“ŒR!\ÈÓî»Xóüò'q±?äRþgHçøgòMw¼œÎ[´´TÌÞQ’>o)H;E2%>ñRÐ-óΰˆz?JB:X¶y¢Ÿ#ôò¶‹ébD¤O6#ÕƒnÌX§Š~gïÙµs"NÌaD+cP<ŒÍC;¯7 pÎì1YȦ‹‚•Ǿa ƒ®L%#ùÛèœ!óâ`³3aq2¨c®@‰›]p×9½ÁI;äïî`wJ³1Qé‚/+Q)ô2”#gã,ªñòî´SuiÔNK“E6D Už‘ íÝ$ ºZ£‹„ÁØÎ¯ð)ðMÝÒ.Èf2‘ãi¡8¾CöEu¸äámN¼=ÛðÄ&§n`‰E~jc&'¾qÞ*Dÿ’F{Ô Œ¤£Š­Cpf’¤<0¸$¼¦ù„Ôí™–ŽîPþl'á£ì–\âžÄ´·¨ÇF[Þn„dÊòÊyÒ½|Θ"Ò !8eÔiÙ"6#õÒIŒýØO×­]‚ È/¤?Ãz4DÐ@r°Ž¥#ó'ÌÎBœ[F`¢Š’9]¦0ˆ0ŒŽñBÜœšQQŠJØá3+€dj‹HÌ»*˜À!ÿá—Wïÿ柼ÕEé(ÏWÂʬƒÌº™áVA`eøâq|¬4‘?– äÁÝC:f­’ËkðÍ1+6MV”a>ló«3§.Áãšæ¥PÈ%ëgñ`B³Ü£OYíJÀÅ ù£f‰×ô*ùÇ’làñ5Ùf—˜È…|óYL!(íi ü÷¯Ö?žt;ÚÔàq¯{°Â …€b‚ÞØúAmÒD‡ið²ý€; QG.Ô„7 ͱyô«ÁPÊ2µq.TŸWÐ`¸Œýµ°–7=ïws)ø´1 šfù´ Š¡­¾ì³Ù¹Â2šì}è}ÙTP½PÙ= áEù¤˜Ÿ~Š-2M°O]ütÄa•h|Ê.±à+ãü¿”‹×j™5ÈÿÅŦ½fgyY_*[PRPØÚy‘í&6‹®§Ã齈:-`AتL†é6gÞn:d¢£L]ð`v,ûà½þs% #}DÉ+ß™w[Fú=…Hìj<¡Áú©™ðÜÇIGªrRQWaþ/eÐ3Ô N( BÕ„R@Ãb®_òyx K­|^< îþ|∣ËÀÀÁ%I]1òqZìóU(¶§ô‘!‡YˆÀy@Öü®I´;À™QôVE\M©Z¿¦Ž H†«}¨ÅÖ¹?óÁHbJþ}¶™3B„Ë8‡›‹“*tQ¬]ÁˆCŽ/Óz8owL ­‘·ðw³¾N|Œ”Oá¶.þJ}ƒÐ,þò—ã“·?[P–þÅIb—e׫¬y4•«)çÔñ*ïé×^Ù÷]à dRŒùH nß¼ßc-‰]Õ©™UÃÔNwªÝšQO_[2ÏdB™OOø,—š>~ûfe’šT6Aå!yËh ½™{ÁDêÍÁ,t9óky™o pý‘'³RVMêUôKL"Ç9>yqò˱ûï¯É ß¼u_½9y}ò7÷»·ßÿ^„€íëSÂK»Âè= ÇÔcñÑ mu+ ÞMgŸóÇb‚cÃ<ØZÖÙÏm­ËåKúTÿ™:µžY7óËü«`6_&ëï÷W­woO,Â(/´Þýrb}ÿê§W'¯Ú ipŽÄÓ´lí˜N¦£ ÐâãçËølï+{t'‹¿Ä‰‘ƒ'¿Uo߀zìdÀœ®©êÑ …ð¡£pn¼ Ü 3´û.»ÌþˆŽ»zuû $¤¥7:¯ßÒ,¡7»AäÃpâ{³]ýHwéu㮳‹– á^hI³Ùê,–Å^FÖš(¼UޝÒîXZ«w/Þ¿zñÝO¯RMݳ hù³"=+8Ÿ‘ãwD˜Hns«),ö€¹= ×_¼¾ú×äê _~ç-r^NÂÑeòzGʷΓ¡‰¤‹’J~ë |—hÆßâïD“¿1„pC™/ÂÛKÈ?R!ú¿Ñ;SgùdÖáQšÏ€(ÎD{üEìÒm.»­úFx¬©Ã•ÆÛ ¯%L¬)ÊS‰±ú¨Qéð‘Ý,Ø8 :ç9œÌÆþÇ<üÒ®¬ƒÎúVãéÁ CžöL*òª ê\­Àq&™¸ôfÔÇYÇm1ÙH™ÒõÁ#¹$þ…³ëiÉF‘+ÏÉ9n†FòM´$º…ŽQy½¿„w,1{)V&EJv4BŒ H-Cþ ¬R ^jžn(‡M~æ&¯’R Aœå¤N~’aG2ã`ž.”C'»Ô’Wkwgr,-,¶Â‚§ÜÇz¯Ía­w޽MXî)BÜÿj/£;d¬÷=µ™ÕÞÊê.v`…µ>õç¾ ¦²ÒÑ"Oõ‡“ ÷³Â3+$|è±L_³±RîBOiñ£_i†é¯¸ï‹ÑLÈBÖ3Ïü’ÅÃkkHÓ¢Y<ÕDº 1G¶ä1¹z½’_-3´ Jê~KiaC±Eºó­rP—Y¾“› (çÃ$þ ƒ…H½]ýª9d)œˆÆN[¤Þf$ŠÓ/Ñ’±® Óåþó¹®4YŒ—‰ØüZw‚)²Ô¥•µÈæc%†ažŒ•FyjY+˜§åèBæpw,ÎAèÈg:Ò¨uzJŸâQn`: Ó …/¹ñ%=›$`f®õê#é¥ÝÅ^ Nƒ"3šÍö_*±Ø§ñe.{àRC}EËpÁýߓÃ#Íþûøp[ÿscí¿áÌA“xÎcöàGj¦S¯)·räü‹{äZ6óãYå:dé³džŸ>Y7·m“T4y.ÒÙr¶foä<·KH4ìXŽqìÈaoMÙæAWÖý'¾Q¬%FÚœÚzöÀ˜£8ò• -Yàv˜ƒzÃ%9,¸yõþøõÛ7ô¢‹t¯© "¼•CÌ%÷[kâJÉÚÏ*¤7tÁ™È„bHÚ±¹àC~SfÀ<:xb½ c–ÝvȬØ@Ž‚/"š÷U™^:CPÙùõí6n2j¶¬‘åÒ¸áÄÕÕÌJÆ¥Ÿž$Ùå*T³ÿº÷Ò‹F‚Áæx:»MÚ&Î&'J–“¬w9z J$Þ×. â|²Y¬9à:ŠE7›îÚ³QD¤øÈ$T4_Ù[ÉB ÑnëBD,Z.;§ìSXÄIßû›™ª8«óª/“Êb@¸-W[Y,]‹E — cÖ ÏÛ¦ø„¦DÍon2#Ã’©ƒ:¯›8öÃG›¼€!•7ù2A”‰‰Z6›¬iôïTÖ:ËÓù;šYÿºËÿ€¥ÉªÏ`©n×ä]ãç~ß6Óü:ü¿’ó­µüïŸ>ÑÏÿýÃÞÖÿ÷œÿ×}俳S>eóD6Ò¤!D4ÒìR~Œòf©ÃºdŠ©dH´ö+oÅZज5ºƒ‘WjngH~ Ön,ëIà5[­£4¬ØÿCæZÉ<2QÂìŒOøLåc7Ù±(æ0ÃYõ#8bŠNÙ”)§â„åX‡8u™]V@C*›S1à“ “§—ž³yج`ü2§âa2åÉJö6¡÷ë™ÃfÁ„®ãmay³)?‘$:°ä,ð Ò±œ=)õ«<Ú“ÓpÏ@’ÁˆÙQݰgjèg: aæiˆý20'£7òIsØ…lZŠª,SŒð¬Iå³O£“¬6?9δìäÊÄ¢Rs.rõÈ‹2¾–Å»¢Ü›M¼¾TkpJ%ìä˜M5ˆ,º˜s3[nŽx¡©LÊfמý啸í“Ãù»Tœ”¡j$ÕMÛ9}ñ°&Žê–Ñ–ÛƒB†  9¯5;ÑË0ÉáþÝkNgár&¥ªÈ.Rbã¹¹cK˜°ô$¯ii½1VuË1ã<ò—ö·¡µÏo¥uÞÈJOf­/öŠË½ÙßÄ’¯ºèË-û–yÙ›SH•ÙŠ7ä*»ìª7Û•ú&Üv7·óIöÕu]a1×YÈŠóH{§©U\eWY½ïéåk\° ^·~×ìÛëõ²wv7櫺µ/Mó»+S©+£Ü‘å–Xý±PÆÚ[R5Bªo4Ëíð[ƒßЏJ’¢Ê%§5¬¡i~Û½å³^W Û½Cªà>Þ±˜>^Þg¥U†)ÌËíAÛe¸Â2|zêºÏ ƒqÀâ¡kÁY Y1Ê)¿¿j}èYúy^a´¬Zï.çžD¿1 ú€„8O—•[ÕŒrø%/¼µ Ô¶ ¨KSúáòH/Zf/œ’‡¹À‹ˆ×y‚2Ô.¦Ñv1m-SBû$ž¡€Þ– èzWY2=°>ôh:ÄòÝs,Ñ;~Í#*ñ„‚y]oo†¨Ñ.#È®«ž>:='8jÞr¥€uÌ’ô1Ä’½%uÔ“®ö¾n…,~Ó¿3ú‹´1{-ÿbGÆ.Ža”æ"RïÕÏýp1™„z ;œùvé’ ‘úõ‰Ô¯A¤2DéW#J?‡(ýÊDé7E”ø*¬AÈ!G¦­…ÐN‰Èˆ-J+ó«^úU^aN¦ $…ÈH»y@f,tä+¬q–:‹Ì”Ûéɾ6  2æä,¨‡‡lÙÞñÇ. ÎÞGŒÒÇï²Æ²×e1 Dá¥ð®’v™öDH»t1;ã²27ýZ¸é¯7À¬kÇM¾¿|‘ÿ7æ1]1hAþÏ~ÿiÊÿ»·Íÿüü¿ßw”wÿÖ..¹78MÛAMøè¦š“8‘øˆ‹ŽDªgêv åÝ%pèED‡¨ç‰r|Èíé' ÍÚÉ}^ãÒ,%?±Ìr'CÞ_—la-{ß»ò¡ä4ñ/F¿ÑnD0‹u›}Ùè:í Ì7»-ô,]¦–dN­p6¹nã ø´ ¬ex†X âf'Ad"ža\lB?N¦–ªMAþ^\³âbx¬y×ÅŠ3î Œ]lG/·•Ü̃8Ëð”CŸª‹Q·?yî yëÔa^`Ð×MqƒŽžüÒ}ºêÉ_L!;I:K1ÕÔÑËO‹£ ÎÄ­ +É(…?äiˆ¡H¾…0 Ö2ÓìÊ­9V[2‚Úüú!µÞVYqjöqQn‘ç/'PVŸT†$©<3y˜O¾*{ðo1c8…5HaŒZ”r–‘5àAêž=Lü¯¦HÛ¡šÁØacä|3ºhÑàɶnwÁÍëî¼° &gŠ£ƒ£4Oà4¢Ä4_Í…÷Òbú³µM©Yö6@TQ%Û/U.óºÑµj7½_ìèod9¢ª×âtx›Bu’xŒhVk $dy¸¨ñšƒ‹Jp{UŒâ·ºùµÈ¦»·§HÆ”Ùè&ÃVp»B°5â¬Ùˆ“‹å­Uf V™Ê6”*$gGÖŽ*¹wê˜L7 ”CB¿ú"A¶¬ uÍþ›&Ÿ;š"¾•×w!¯Ëb}+¿¾üNÈû•ÝUpGr{›÷ånò¿Ì½øbÕB`ù_ûOõúä,µ­ÿõ ìÿñÅý›ÿã‹Õ¬ÿÔxœž!£‰ýÐfƒ¶RIÈ`¯¦ÃÑ2Î6دZ{’‰­GiUÁN àŒÔeà²K›¢=†l2³#káXûºûÙÌ,Nž3ÓP‘¿We‚êÑ€¬´yêôE>FHªÂÁ€Ø_xc¢2NŒØÔ1§Âú Õç>ô YGÀ† ~ái<úƒtèÓŽšÆÃl ¶¼(Iåɹ<òlÃâë[5—þªÖáröÜ4¡BçzSÞ5¬½x/ ½hœÉz…^k@0H|ìXC"V2Ó÷Òå1Î[r؃p¡M4sÕ3<Ÿÿ$Ë`ÂÉ'ð&™Ž­B²œ…a ‡[íï¾ô¿FjÀÕÿîêõ_{G‡[ýoÓõ?Ió»SJ»@WKt2Ih8&­»ëâ´… DÙíb]PSqä¡è Sî`´IÉá/èŒU¡yr¤EéÙAÛìÑŒ¥ rG7~QC9†öVÆcêëŠ0îÈÖZøç9²-þ“ué__…‹±>oüŽ!°-ß6ŠÉ²Ø½ä Ìû´èÇKîÃŒ#º2˜Ñ Žß;Ê@íråÞX—à–“}>V„¤ðZ·ˆ9Õkb Ó ¬ï.‘ .]eù<›ÜY%à¶œ_q¹óÎLW6tý2Ì‹‹›¢•ô®ëf² É-œÈ†„þ^0ät6?Ë$KË¥Ó3Œ¬ðŸ$ï"ár0îÏ´6|ñü SJ˜PÅè1VVÈÍqˆæ3C…¡Â>ÎГâ#Óx%í;øwV‹QÔÿìÇá¸,ò¦ ™O;jçÎn–¯.‚Ñ…5"  «M³oM±/)Ñ™ƒ+ý@œž2ºÊPXÔýr×)Ï`LÊ"k9cÁVmÝÐZ&Žæ³ÐÿW¿ê«ÿóäð±vÿ×{üäIo«ÿߣþ? ÇË Óþåí9¹ðÓª¯`÷%b:µ§þtZVê‚ þàÓsK\áÙûN0¶‰‚2»Ž/ˆ>”ü”’!ðiwá]¹haæØA¦X“pƒhîü\ˆH˜Ó„]“èWŠ~™–€*òc¢lœG%J~"rÖ±l"Em3X¼cUúƒORs\s\€Rvrî1N]x`6"•ÏÕ'dÈôI 1Ëé Ø°Zs\ÞÊ• îÀ÷+CÍ'»ÁL€[ ªß_e-ØNKA¬`ø&aH:À¢|f€†ì*i]Ü Árì žÃU`l†!¸ltóÚ'‡ÉÉØ.!c ê ˆ–b "æ"ä,nQ&À|“fÌ‘_Nr©I ÖMŒà1ŠH9êL|“2=êÄš±Ý´ä@) .x&æ„÷é%Âh f[ÓØ€4yÈ(äÙ;B»"¤Œyœ/6ýbvM«1:iYZóÐç‰ÂL°@!Ž™³;9úÅÕ´$ ¯ðïÔ€JJºÏ””ö~ K, Œ¾ ¢ò*%ÊÕ)É–ðu1G–Ý,‚‡®A\ª:VgÁã­ÀJŒ§°[%°ã9[øzׂ£»I`³ñðèd‡Ìn<¦hb;f0$þ%kÀ60¾zJÏ-Éš/šç–`2BH ¯¥¬ÄfC”Äù§ã+tÌšUñFQ[èLzg`ÍÑpsõ ¡Êâ[}¯ªÇliH-$E!wÆÀ8ôãz @Íж/&ðbR:8•Õ£4$؉yC~œ™|¼d¨OY8ÙO h`dá]±¹ „”³ÎÈæ¶ {SѰ/ ,s–Š–g*õU#8½.ô¸ÇéÈÒª& ‡UôÒ‘œgM Ë/z"æ*n?P‡æ°¸tˆoàª÷¨Û=û^èÒˆ wõ’Ópʬ…hJßêâ5QiÊn =¨PþAB’ udî&×£ BîÞ ©þq[¶‹ÔI&¡BYîw:þêx„ȈKq}à •!N55ëÂÃо‚Ê`\^ñóYˆ¯‹:ø±kö>•š”WKaL]¸‰Îü›^ÂyZ¼ G/7µ¡»E83?¹ÑaՉϊ”36³O íÍ>‡²¨„ÀÌ]„â¾ãÝfï×ò,¥½›Èzh‰½²{ñ48¿`Ñ"C˜¥EÙ¬esÎGånê%hS´ÏoãEªßÿ/üÈ'|½ˆ’ï"þã°ßKÅôzGÛûÿ͹ÿg¿¾²COQêÓcÒèüýr:½ND ÓV˜ëÖ÷Ç?AVù(ûïÃeì'ÂÀ‹ã…» ×;,”üD ËÅJò ¤šHœäRâ4õ×,­¾eW$úc¹kx™(žn0#C€u; 3XGzEøgtÉ_HR±Ìf+P—üd#^øl*Ûõ…D÷%wŽ.Ûê^ñ–:6‘©dcDÇÌÁKÛn˜$°uEû–<.Ê–ô,ÿ¬ø+C8Ø„¹°¦°‰HÉiÂÀ xÎ’MÝz5zHüÂûçNqLeé%§O†?C7òÄË[,éçŒ*<ÖÛúèº7z’v#$'K‹aò"Å‘øÚ *¦{m$Dvc»§(ʘzW}sW}ÞU?¯«BêeÑ/‡‚½Š$Ìí¬_¹3m†S Cp»BÎÈ¢Tƒœ:@ AŠOzìEÉúéúìEjUòmÕ³ÍÑÿØÛ¼ haüWï@ÿ::ØæßDÿO–8U Ì`aS.õêÆƒæŸ^ð#¦Ò„æV•’¼hïórÊÒîöoG23Ð|­ô_còXe LM#úÏͶmˆåÝ%³Uç/O+™®Š¹Ö¢aAnÅòéHsP ²¥+Í‹m<|R`6€>rŒ>J²xmÒNs#ûËîõ•Ë“!yöñúŸÉ}Ém~ŒAj`± ñ ì ž£É"p\ËÒß`Dƒ&™ ÚYPÎuä´AT|×[hn¶iÙùB&Mwê/Îý–mê€#?0(8Õäfš«ìª‰ï“Žm Ç‚óÉxó=~¢½‘§£ÑH¾Ý¼Í>`UîÏE/"yïæCBU‘ßFô7ªªe’³³rÎHš Æ·8^¬c.âxÎ|ûà²X¥YFï5”´¤Û_Ý?½ñî•ûúØ}ùöíO#×¾wQ…NØw¯¥…€çäˆ:Ádìˆ ÇTpàGùôS˵Aµ6 {¯£½—!E .„4üA*„óV/ÏΚÂa‚ÂWoN^ŸüÍ=yË’È@â›Yxe]Ñ$®¬³8’ØMݯÄþ´þoåhŠ0ô,Éd‹VCb¢è§×ÿöêØ=þÛÏß½ýéõK"¨Xq³1¢ ¬î™òú"oò×–‰{Ñ1ÔËy I² <Ù켇Rþü)¸ô£½c†>ÊÒì¶Öá ú?ÙŒ&û’¡‹ÛÂV>äëÿý£ƒ'uûïÓþVÿ¿Gýßlþ…²=ê–ü:á–c潯GÏ:,ÏœX‰éoº`ÒˆÝóI8ô&¿K K®Šú³X‘BLǰÀ’œê–(½ÝØ›c’;n×ý$Iþ¬KG>uè¿.zEBµ"þà, Ý¡·0}*ìÀ§NbN:Hž•éC63ËýÉ‹ÒÔ·ü¾Ô8Âf-"ÇHÞ–aკ1Rê¥qÄt«œ‘QQ=u¨¾šôF׿3nÉT•äõÖÆkUÆEîŠmÊŒÖó”g,”=~FÒ¾6²S–øã¦U†|ZÕ—2\žšøˆŠ¢”O&@õ,ú–¦2Ñô(> rõRšXzMi6`ÃwÜlø¸ÜhîÌÿ¯4¤ÚCJÅyab¶!f:ÛKæøÊ~ ÈØR0„„÷˜]W¦NT@ž¬=.'3iEù§ܦŽÒø»—“±uAŽ•dãgg>ŒÀµ‰9>W–„,‰wšŸ±èHg5æ­^r2§9²L^úÂoˆŒƒ•ñR ‰ŽJ,d6©ìO’_w²ƒùó R¨às „²¸4»†KÂÞü.gd¯F|’n wŠ—áTž WÚ›«JIó§™XJ-8ô…‡+p*$¨3§‡OôȼbàŠáÚzobRæ.39¡T—™–æ Y­IqÈU¸¸dqeR³R›B uË0­Óè÷‰ W˜µúÕ Èœ»7Gä‡ÈŸœÊ.‚ó`æM œ”8ÉTìxÂIÛ,­ÆÆ¡›ŠsJ\ƒ!¨X\ËZ˜ÍÀUöê)û¦rŽÕTžÒµ·–’Ò·IAuZUZ,”̦q(c&…))í!#¤ÌŽÎ–)ÃU^¿b†Ž$Ê{O±Lý´ÀS-Z«ðO:åù¯ÄŸú”Ãg­LfvŠ™|N¬`Љ-l±pYàË­Š’[måÉàüJ‹ËÑ––u»u–Ýúÿ*þ¿T=Z=°(þ¯ÿäH÷ÿ}|ôdëÿû üÿBýRñcèHy“n©”¬JRÛµx?†üÆ>*}AƒÖxé_›•Æ”5Ûì(Ä%+íÑè²¢KáêW"æ„Bgl>¡Ðw&[üýΑôKëÿ§ƒ Õ_\•¤›:ó:`i jÐßàÅëÐeeèÀ­ð |uẠor– |œ>Ô­Ä8E¶ïšŽO £cȬ‚Ñ…7;ײ® ~C¯5ÙùyîMè1sý37À Õ -‘òÅÓj/®Bw.ür׆²ëÿ£•ôá°ÊiZ¯Žè³¼ù!möà¹u˜Ù[¾7Ã'òU™H7 §ó‰ÿÑj]¿‹Ì;_Ó >ømkìÅž_Ï k·ü]IÄ×ô²Õ:ùÒ‹¦ï[Ãå¹õè«?öÚ¦,lŒe¥¹ÔhGiºC¨–LM¯çw*w~U¿¤ñy`ÞaKò_“Bkãå|Œ¼Ø™8Ô ü©£rv•žmS…lœþŸ>u®~ (ÐÿŸ>yz¨éÿý§·õŸ€þÿžrË1g–‚C€V/:ã`h•{ ú}”½ŸM&VªA%Á´ù“¨ä>C'·I+Õ_7 q±RŠÁÖcœUù(jêlÑéFÊÌvÃWjßoaê"¼ýÿaƒÏþÜx P 99ÎÈ!bá]CÄGžÿÐêz·æ:FÁ'93!…ˆ7Š—"RÍj±_Ï‚E·ïý0yê$~ ùSÛèCee^¿ŸceûÌ—ÑAîÙr¾«¬µ¬Võ¤ƒæñ=,¤†JŠæA?u(—â®TkJŠOIήmœ¾ CÒoø²*0íA@mè§£À3x&Š<â5jÑPÓÊJæSexŽÊŒæÌö!ã@)b´VCˆÁ`ºvŽâ!ÌŠj/{F^“±¹•¥yH[Ëm6ÎûßíTå üª,G$0¤zÅW…ÉüI 9ù’Ò LÝÿö·ùÿ‚ý§¬áGk—aø1´ZÙð³µûlí>[»ÏÖî³µû”·ûl†¡§c9Åý[CÏÖг5ôÜ­¡'ºcêukèÉt]1’¼“wÚÞD#ŽAM7qL*¾ÇôÅo͈SÄ- ¨*ܳ5Ð9 Η ”»+‚ ì?½'ŸjöŸÃÞÖÿÿ!Øìcdئ_ÊÌ"­9nÞ‘áKa£WV¦V’¦ZΠKAj9”G{D.ÒŸú‹þp‚þx4à“‡ô§'Éë§âã¯E.ÓÉ-r|‚d²ô3u§{,ƒW+BǶlo2¿ðìÔ›¾eý˜¼H½9Ô›eŸ{Ó©Ò•^z/y÷ƒ%/¿JwüØÜñ“t9†0ë©ñùWÉ@ŠÂídèQJ²52Ä9s²Š ¯ClÅï!nŽaÚᨶn+öò8éåIòãSÇzÊYó+Çú ÜxÛw»¥HòŸì£ÁWW´%Xƒá2ö#7ˆ}²æÂJÈÿƒ^ï‰.ÿ¶òÿë¿ Ï„ñ_Þpœ‚9^3ÞI±õÌ~àþßòú§õ¼Üˆ¨Øþšë¿<~ÒëõSõ_¶÷›»þß!soPAÓñ„~×b_¿x÷º½#v{¨ÕíÍç;’²”¼gS¶ý[/5e«E'ÃÑrÊmB²iƒÚ£.º,vE¹ÅåÜ‹Æx•c]'Vùx±Œ/äÛŸta‘…ö­èH´Úœ7±œ`wðôìX¯É¨ç>9³Ñë¨o,µ%r™ø±YóÄ.ÊÌ-oH曞‹©ž¢Š2Ъ.¼¾{é_·l®\,ËðÁ)¶¨ßñ¢š¥>=å­ù»uÔogUý+A«3où j†N«¿‹x)oqŽóyí{3‰|8ð¦QfQHBlT“†ôÛ4«ÐqL "-CÏéø–ý&h¦_oÅ(Ä…4cÍjR¦ÁHöYC–ÄàmNKbVٔʧӎN*‚&ÊÕ7!FN.]ÔÖÏó6ºt,¢"Üͦ¤™|3”b'Ŭh”eÇR‚-»¬ìõIzêÎ?%¼½ëM&áUÄ“lYnôÆ·»e"Ó#¢¬Oíë4þ| ¥f¯ÉÒĬ¦ØÔ.Z¤–½X'úm(l1æ]6w¡|Úá`>ÐWÑ\b—LcN¿KTC²ðÓ?8hç·†ãkQ 2¨ä2¹­QJÃ)5¾‹y2#œ¤|vxRQ¢rY/ñ»“ëy²;ÁAžˆUE\;r\ òÁA#¿…oåÌB /ˆe˜?…õü9`O ¶šWYÿT1ëÀ(Á,ˆ¬L›å[Ö;¥LE`jû÷#ŸÖxB~ôc¸›<|˜û»d´0·]FN%lŒw/”5”;N ÏFÉÕ²÷)A=¥CÑ«ö.±¸Ï ¼IÛvˆ ƒJÎ š«1g1kÒÎÛyãk„.ÁQY¦^<ºhí“q`÷gíç‰?z{Ï÷!Jz¤ Œ4 FA<¹¶Îƒ~"•"`ØtèEþØ‚M¤¼åOü©ê?W†+Èé(ÇçŒX‡Ý@9ÖÞׄҿ¿j ´SüE[©~nâÖõ™Äæ¿1Á¡³ˆhܱ Ž:ÜšøE«^Žg^0‰ ¯äîÉyOP Q„èzð¨¶É`ëX€b6ˆ´"LhF‰‘îF>ÍÝ€›†äýžIe‚4¤S r6ô û³åtè/²°Úë€ÃäÈuŸ¬=ÔÆ,ú ÁØá@&&ÌÀ]± 3 ¼â“ˆ  &\EUi8ñßâCêP ð÷âxÍJÂù³—jÛi£ø8èt»½ƒ¦g–„(û@E`sMlvÌ)xŽÈT<Ü&É;X¢sP´Q®^ø£Kµwy„UOY §‹°J '(IrÊFéeI'(O'Y Ì„|¦.P Y ½J;f¯üòÌ˰Hk œ¬ùÔYeÜßПLDØ’¡€ T²4EÚÛýâà)a¶$(²Z ™7ÙEq>ñÏbÖNHï šÙ±õˆiì†gß½N:¡šöƒQÆœ@Ú@Þ á’x9ö³eÜQðÿñ@r¥k@ôç˜Ñ(~ÁùŃAPtgJÛƒ$6@škr¶˜ÑðuBc¸ ¡x…‚¡ AÌ%ƒ;='{³ ¤šÑj@lb$3i§ »Yíèö%'ü*!š£Ú0Rtç{¸èˆñNpyyV èªƒúxÉa³a(ä_†T O¯B[]…ÞÃ}a߆ؕ]Ýä6ñã–E¸LAàGŠíÙÝ®ýÏBÓÙ{hGŠÁ‚>ÈÞ—ô„ÄÚv,úçW{æ´_3š,Ð|˜€@%ÙÏ£`ìøüs%|UÃ'%qšÅS“Gµ#¦‹–³[ ë²ñù"\Ε®­H@¡-†È¢2| tW9)ä‘,ÇÓ¥HBÆa¿Ý{ÑÏAfÙ?Á€`ô{…Ò¢ЉD»7¸³eŒµð¢ò¦N¾N°ƒŒ5Ì®ú¢¡,„Ú/BSxér¡­:–jöЛû$¢¡i˜ G{§ÂmWÈ¡Óå]âõ ›É¤$5¹­BJÚÃ}ÐòT"æ`c©¹~Lä¤Êišž\t±‰hSËY´œÏÃxWµíE§ØáüxýÒè—ú†%é†L£àjOr¯CqìÏI;š¨›l¼b]évÝK–4\‡¤¶™z«8ö£Ø¦ ³¦äèÌ'†#»"'udáܳ8jT£8|E\¥ Q|´ 3ˆNj0DnoÃF{«Ï+•¸v”õ9Ðt¬Q³,ŒBø˜˜ã.从ˆVZÿùøíæ†bâÖèz: Á}Ä•óÄx02.¾Y0‘)X¦´éá½à $‡Í ©u¬ÿÍBUY¯`D* QWã"Ã"ƒ ^ ¨K2•'Qûå犜ÕfJÝ/|¨a¿‚Y„Ê‘fp-©ñ¶Œïå,¼š½ãàæÊB7uw,8¸3ë‘.£Ì*žaÓ«²ÞªÙè^È—=”~5‘I$› Êg× Œ^S?мsŸO“b>A«¯èÍ‚1üY¦ÓΕµ U>Ó·:z0‡ƒ00œ¶a°&„Þl,^uK5Ú[œª(Èg4FJüö°iUv³Ï Ýu®}ÉSmi‘îp5ÝX«ŒöG¸ ‘s«Ÿ"žj¹§øÜdz޲»Ì&|Q,ôÝ1ˆ™MÅ燮0†Ì+šI¨UŒí—#Í{æ‘5\BRØW¬‘ûðÙ"œbršþ,9*STògcÆô¦Ùsáud=·~´«pâ¶Yö$™¹¹íp÷êœùѺ¶þÙæÆÌaº­|’°ð šqÝáÄ›]²`#+Õ²cl5`—”Ò Ÿó9tÉÁj¼$´ðvpÚ©1‚À$»ÁÿG &t¬€‡Ð:¼WYj®_/ï¶€,Ö£›à¶­¤ã€œs"¬]:C¾¢?Ýò1é#øé–èO·»ÙÞ ú ´¹ðØtàPø‡?Ðn•V(Zxõ€;{›ýã?‚ôS|$†Ð ÃÈmÙn®SÝŒ2ºQåI=³]:yÚCãp¶×²ïD—Á\õ¦Â+q *#ïä:žÓ†½zׯ9Ù$J¨ß~ õÛ˜qO×Uå;àÊêŒé]§ßL,˜Í„)\\x´I†HÍ€øcEP4ò媅¼~u†q5 ý¸Úq>êÖƒF©TÿU ÕRõS”ØÞ¥ÂülX;‰õqν¦á0l„³æ1XžÛªçȬY”Òc³o€2·©:CüßÒ‡ÉL-AØ©*4êž"%:­x‚ü,¨TtzÈ£Zê ¹ê‰á£ñøh¢X£GÇM!dî9²Žù`ÍÔ7a‚¼3£‰ƾ?‡à£;4@|o±èez{$ÍÀ§WÆÇ‡ô×ÏñÑûì—µ.@öO–(ßx%UÕæÇ=. ¼2 ѯ:àÝCÿIJÁ‰xÒ‡'b64ÔOBŒ—ìT¾h¬¦ìðí<6‚(X”€©¼éó7\ʯ:Ämƒ%á F@IE?P 4qá=&ÇÀÿgÁL¹P¼­£8œ›ïJËú»†3ßø<¾2·/¾_Âýf²‡3-g³âŒ“|·FXÈ€œ¨ dù\…êï0É´9:½Tr¨Ç(ô*ég0¢á™bŠuŠ z„ì$¤Ô3e? ú¥¨Ãâ’‰N4rLû@ÑZ«is[‡49'p:ÖþéÁÞ_îgã~8îX@å8º6dûÓy|]%ŸC,šW¨×a’YÒ þÀ¤+€k§‚ŽZiе³7Ý`¬¼"OˆR‘ñÊÉ·‘Æú‘Û¸Ýj\@-u9Á8ˆLÌÈ-]:™M‘Q˜M ‡t,˜ŽÊ+YåK<ÙX„GYcO.Ë2LQÆ ÿ°l}L“v‹,e,8–N;ÍÀE!P ãáPXÈ 3.ÈÀ•÷Pš"h،ʒ%ZŽF¤ùÙ."èÌ«S&ß5_á"ˆƒÒ*1<»JÂ!XftºU!_ ûÃ@1…2‚±@nèáý5$Õ ¿÷â65)cx»Ÿ“ÀÕ"$Lœ­t¬dJå÷­‡(,ÊØ¨¯;4¸Ô7OuxèÕŽ¶JæÿÇÃTµ¿KÔÿ8ê÷ôúOG‡Ûüÿ›šÿÿ‹Â¡0aIiñ‰HGK“Ñþ†R†T-׬›0?þÎ[d~œg}¤ùÛ_XÏәܻèÚ¢º8zú0àiËŸñ—¹}ÁJMIN„¾üÎðÁÏ9í_f àO’ö?_¿ø„S2ü—ᛖšËu³¦Á,˜.§îÄŸ“-·Gz凇rå^·ËqD¥¿o’LÒ ³"Ó“Ћ;Ö›åÔ_£Žõ]pþ½? ¦Þ„—?ÊË—ÏU1ŠêVÿ>  r(ýû½7ºtœŸ1ØÇ[ÄŽóËœŒMöÍF)¥µžÆšl¸áù Un0m5µÉ‰)îš2³3\Œ]¤O7Áê…ôbpè»´"D^*â\—ÀC)²–ÔG(#ÕdÞ˜4º˜×¥?ËÏqت3t¤¬™Èb9"zƒàö¹Ã“]³dì5(!†(C‰ž’”0ÎJ€2NO‹I‰_Äü‡—¾øªO´ÌÌ$˜V™zÄy“ô¼àª›‘ë~%LÖÏŠË‹©°‘ÅÆ¥5•ñ;\°éwƒ¼K¡Ã¿ hŠôo”LC\û¥Îð̹ó %™Éè’A:¸™/R6Rö 5†“a¨” ‚8‰¡é9 nÖ¼ÅùRKF]LΊ—ðh„,…H”þHΔnÅÞ%Ädã]tL¨½:l?ÏKÛCÄæèÿâv+Ú÷&7\¸3Â5úÿááãTý¿§½­þ¿±õÿ&“·‹7„ÞžýEÜ‚¢Pê‘3ò§ÖíŠr’¹í7{,&‘b‰½ŸšþZDúÈqä×ìj<î7ÿšãà†ÐȼÍ<. O¯3ôAýu®ðüppyœ-–¸¦ÃÅ¡Žª „ ¥{ïXóżGаm.PÁjd×À¸Ü¿‘ÆÄ¥3å @É n,˜U€i📹ðpÞĵĔÃS±±åäŒm ltå¹ 3'M,µ²ŽÁ„6 >BF~ܳ<¡XaqÒP"ý©KÎ)çd\ü–Ϙ(+ÞLzÒ–}iêM9wÒ hbêòÓê‰F… V“Z¦X"€>屄ðVô ûmõs&Œù`äÔ³,„"æçñ)e§­ò„Všà%"Ma›vj»ß¥Ry…è÷*%pTK[õšô?~ñ½ýïèðéÓôþ÷d«ÿm°þ^} ¡©Ü š46aöÊðiªŠTzf%¥ceÝRz»gábêÅ–ޱ‰|Ê÷á…ëq“oN±¸qIííü‘T‡ÑNa¬~θ¤+WŒaµ@Xa²®ÈOJ}¦WÀr¦4·<†“QˆpâNìÈÕ…Ý'&ß6>zi\7AÞhlÕ49d]t×UÜIT˜•–¬?6»©>ò|ø0çÌ.mj MÓÞÕYÜÕ#ôÓ¦Ç./;+Œ/9Eþ¢\h¡\Ïv22Jyn(¡Rž0K€¢Ÿº´¯kå„IÑ„äÙ €¹ƒ™TØgµÐóÚ”R÷ã:óKÀØ(~Kžmþ$˜.†>¢ðÚð *±ÙªÌT kZ+uÉ ­#ºÃ%V f׆.ÏÉ¡@kN •ËH¢Ð3é²~Œ†j'<$83cT8/„!‹ÀPáP Q9B=ÿ$P]<8Ÿ4ò@È8mT‚ Ä‰#Wdehý Àмl¯kù~ ;e^E#'šu̺¬h+3¹z§›&fոƑwªAçjç¡â•ø`¹;[qø“®zÞjbÆk`ü&˜»:™ïyµ¯BæŒó\ÉD“àäÍçøB»‰2^]±xϤç0á1÷Ál¾Œ5_Ó³%ÖQ†ðP‹N!UÖ@»AJeß( ·SFÿÇ¥5:78ŠÒ©¡ÆÕE“½‘âÏž?=Ò ™ªýîZÖßgÖî:zþûl·)¬Í‚IYD‘¦MšN´l¾Ã¬7\zaP;ŠìÂÄBFRóB*µ”øTTÓ1•Ma¼çÍ.º“ì:»Ï- °ÝÛŒR&ðÐóü¢¹àL§–2]`c¹ó)å¬ð"¬Kk¼ (˪J€;7‘Í’Ä@U~–HæY%#x?{K5Í -Šjë–×0Éá  á°¸C-_zà3‰úLñšÍÝÁ›µ„É3ÅéZ@£òÜ8 ŒÎ²X¼`ëÚÇ1+;›Q÷$[3(4Ïv,0À5…kªÑ~õnxï4cÞªåUl8Eß‹*41Õõ þ Vl]ÓѺ8±ØÄSÏó¹Q^Ô’a•Èÿ»D›%ã@Ãð¬F¨¢üŸOžhùŸŽö·ùŸ66ÿSü0ÄÛÏ!¨ÆÜkHja›t›´N"Ð;O‰¹1AÙ/ý눼›Gd¸HÍÕ†Ébyv:_;™°xº±s¾«´¯Ÿ÷4?þGoO®­&Ð$/ŠÍ”Û|&Óbýoú‹‘¿J-¨|ýï1QTkú_ÿÉÑÓ­þwŽ…cÂ뎵ŒÏö¾Ú©£¾DÑtAVׯ—B%JR{¶Ía›ìKSåÊba±´¢Úø©”¢¿DR}׌êKL¯ä…Œh…X½6¬ôš†Ê*¥]s|¤z_ÉÒÀ;ƒzÚ+¹"zMZu'áÈ#SzN^ÏÌGPèŒ<´ ðΛ@BTßrÃ:ô@á ªÔ³gX¦KDQ†ðYËîv÷ÿy±÷òM÷z:!GM×ýáõO¯\·­v²ð¡›ße€jc6ÔõŽ®§¥Êw*ɲJñf”É$gh°†Lt;˜ÅÖU¸¸Œ2j$*ßv˜™àèЫ{°.ã&ñßþ¯ÿãÿû¿ÿËÿŸÿëû¯ÿÓÿóþÿýû_ÿßÿåÏŠ;§Å¦ y ˆAtG„ÉÐ]2zÓ+dz£n1ôódVd£K_0jtšÇ{ß½ßÒÉD'†B½êgA8œg‡ÂRÒ"£¢[Žœ"<_äòIô±ðЈLY©{{Wd#Í×O6€É8Ïv!\u/ZÊ‚EQ•F˜±îkÀ< ²ŸE…ÕbóØDY³”M"‰ONµ}ƒÓ±˜<ïXdâÓáØÃja¤É'-DpcYω¼¹VÔéŸT&‚œI$}E]˜Rߤ?òSHz3%ùþÞÎÌM¡.[Ç,Å÷©ã ºÔÄ’4'…aª@2éÒ&Ø4º‚ÌsRثʥeøô„Ð5³<·Æ(&.á[—äÁ¢ß:ܽ¬eŸ9 ¢È‚ÜEgNo<˜­ž/½¼Ë®›t9–s¾Jþ~’-&Œ{‰º­'Ãî éAB~Ñ®Pñ.£”è5í»@Å+¯Ê;@)ÚY-¬ÞØ®JÃqÄiH«?2J HéAc•’øÈ*¤'ýJ•“½å÷W­žÕ·¼¶×EÒq”MR(_ýñ ½&ºêÊr´…ÓùÄÿh…ˆðȤ š2‹dZVA”s>ÇŽ£œˆ³õ@èG×9tÅš ~-n/ûëÔ5ô´ú§sC¸Å±ûâ~ø»pXÿþ» |*ÖŠOTEÐÙ†­ëºGÚi•ó[0‹mSšäSè)Ay,ß Yûx7÷žEˆ\ jžâý"%øþ,É ?‘]Së^,®d%r‘æ™–ÌŠúIœèø×( ¼ ™€„¯„„?©´d¬DóU,|ËûàoXK…ÙæícuŽÚ’å$¨6ûµŽ*£s<²žË*MÄ,6ê…%ó­¢woàŸ-Iû¸õ¬/¾`~Åvß.Á§ðµ‡:á_!àT1ƒ®Å×-ʽãT@³ovƒ]§×Ùýu×ÙíïÞÚ›Ù)‚¶ÛÛÀ ìµÞ½* P”0avm¼I«|ÃâéBxI8Æ”Èo´RÙÂy7¾Xøìoˆètðám MYaôÀPz‰ÎbBæÃõóà)@Vm‰ hˆµŠàUdÂÃ’°® #÷O—ä>ô +̉ Àƒ/ô± Üe±0¬¬)Ÿ®’ÔÊÈæU=~ìÅâ|9õgñ+ø­øDˆ›ÂÌBæp¡¢Þ{Õ9åƒ 5K”¯üÝòcj}s%ƒ+$ƒŒ²n©]Út%@&W¶ ÜuÉZnÙ2Dߨϒ[ŠžA7ˆ\ïÅ|ûÂÚàäïkåJý…S]Ñý ‘…Ÿ¢OVÔ½ôÉ/ð±VšŽÞhF¸Øe|w…'(×êGÜZ»!U¿s8èì’Áv›Ýk"Q®Âðl÷v­k†H ÎS´/ÜvðÉ¡xr¤‚ý¥7º$p¯u?– Ð.Æó‘¶?XëÂÆ=ý8°D|ç…÷A„w²ô+ePÞK¡üHz2؈Y÷T‘xœ‘—X‡ †ÒÂ0‘$[a¸†[a¸†Sò#!) ¼Vt.â ¢!®®ÊÝ6&“/¯WT)‘‚Z4Hsôm'dÔ¥–»nè»Sç#ëì¶›<ãÜîVBhQHΗ-™@úbê¶K­õ»%´ÏýKœÁÝCn|º[B íÕÇùý‰$ êÍ•A»ðÉÌŽ­©wINç>éÝJ]oî6u,zcYU+aøUDUyM©à8ßôd$I{os*2QLÑ•hâÓˆ]I3§:"W“̉«´]±˜‹À¼*¢`Ⱥ¬±_%áÃI԰؆ØÍdýmÅDkôÞ»“™!¸ë3D±ÇìD½N„h©šrtævRœ…I{ ¶k–ãîŽÓ”õûà3Ø!ÎÃp¼Ö|O‰é4\XóE0 â€ìY£pÉ´ ïÏŠY ’¶DtÊrÕù!ë?L¾Ó¯¸K}?2š Ò’MýjœŒª}Ñ‘cD7ƒºÉZÚ¦”p³õéSÆ»aλQλ±:Ûv7˜a²‚²¹ X™PL–oa¬Sf@òâ‚àzHßvå]¯;¾~—³kra üþªIä0IäšããìGÏÀÚÀvŽng§»dÔÝŽµ‹£ï¾Îóþ"‡¿¡cõ×!”Ä@2Eïk=ÀYþ:¤H+âQ¡g%¢,¥r)ÓÞãôø¸YÜ0¼³€ÎZ°A–x“^Lß ø/Þó–bi££w¡™ú¹2é´Ý·ï{æ”<¦©›àƒÇ•}1|Yƒé|;Àn6¸â«pý ébÄnz@•«p÷öëÒ¡w•-Ê$j›j›jÓ2@ýò>É>:D¬ÃÑPvÓ‰C0dHgéi~£4V1¤y©+ˆŒР”qŒ§G¶Y‰Œ(³þ"V²Ÿ(©˜‡Ë`2NG¥Jw0õkyôð|ÐF×üB³„L™7k¤FÎXø#Ÿœ·[ΪÝõbwFq«OÞÂ4ºÁÜÝpœ3IèõhrNàBìöN’Ioÿ<¸?Åù¿yýÖú Àóó÷{Gýž–ÿûð ¿Íÿ½±õ_¾§¡¥ûf©¸¥–" 7{¥—JÓýâÝkë™tÉ!uA„mÜ‹-ç×(œI±£¹HÁØøy‡wLvzöÓnœF‘nTi:á=ð-‚?‚ßZôLIÈáÓ^ŒÊYMý¦ŸõM?ob†To78—ž:™›b_}ܯ4I9uá½Ì]›|:esq×d ²±‡Si{_@ÞãÓ.¼T,~ÉwDrSßJŸå~¶œÓIqn,ÚK_'³£É¬gáÌÍh“zU?’Ô®l5U W»åØeX1pˆ]ÂS&;Õ õwä´TÞuÍõ€zfψ‹)9Ø»ø>*‹¬H¿Éh‚Öf—i·1½Òë̘¡Ó‘Vþ^7‹0Œó¼6%·S¢±—A•’¶!Ìö¥?õ¥3#o®‰È ×Ìmm0a”&ã‚Jr¥5N~ƒ>LåêšÖèSº¿³ïá7ñãȺ—ÖÄçQÖ“º»ñJ˜Á, ƾRlQ­z`dËŽ`D;Š—ggtÁW*v]tŽ¿Ñ‡°nÁ6ªJ[(30 ø™(é†(\á4ˆåRElE—üZäÓIV¹:µ4ß*¢c³ä†IhHbàæöþ%Ñõ§óøŸ—$eÄH– Y;V-î̈ãÏ$yy[`lG¸j’'¼š¹nbÊ“)˜Íü…«™¹$ ¦aâ%HtjœP#:M›€‰Gïv3på5[´˜0²§å¿Ä®hBrrÜœñ&MàJa”ub«ìj+ƒ5²l ¼T€¤&ÔÉ'º•:50’ßÞVe¹’¿Sþf}áŠý¿üÞ(ž\»áÌwó:n`ùþ_G½'O4ÿ¯££ÞÿÏÞ×5Ç$‰í3DÝHO«ÕÝ$¥»örw4ÎŽ.f$…Ä߯¯Ý]$±> ›‡â›Ão?ûÍ÷xqçGØŽ¸ð¯ñžíáÊúª U@ 4›ÚfÄŒH P•™•™••••ÙÛÆmjü× åˆ7!zs®¥ß¹y°ø£TÓh±7L¦Ñ\Lyù~/§´X¬¹‰êd òž_ˆaÕøO½Ÿðóßü[ã¹5ƒFan:¤Ó<NÄ5?ú!Âÿ9—~j¡‘ïS9o8ò3z‡›à¤ ƒÆŽCbä;!´…ËJ…y¸[íF(YÄþοù™ž³9~Œ¤üþ¦ ‰[²{H€ ÿ=C‡>ÁæÝ´K…ýNÂTвöiÜvi\yJ•nÊâI®!]cµ>L"²]Ñå+ÿÏWI¢YÁG(C “Lë^¡ø=Ú#ßryáÌ …'û}ÄötÒSJO+NÙ®E³ÂJÒ ³qÐJ]0݃f´B1Š|@7pSð 9^â$$p')" ´qã_ó»}Ò§_ ‰B¸oùˆ뼄MÑÁKÉÍ,½zW½¾,bKƒÓ™D‘³ Yê}#8Ù“nOC­=³Æ™z[#û¡ÛÿWËÅo©0[Ë¿¬¾(±ÿ±Ñ¯ÚÿG½þÁÖþßTûÿGÂ'œ!6e P`æSÆf8ãâkÔ‚©o¤²¹Ï{rÒž¶fÿÖì_“Ùß(ómÍÿ?aó¿YV²0k5 `k·®jÿÑiš¢ú€KîÿöžõŸ«÷ý£­ý·©öß[ÆŠá§Ÿ–„žæN3I“#M³8S5$–G?eŒ›Š¾•ÀŒ1äÑ2ž"H;…ÌN‚ªPR58Žû/õ°-'m] cSÚ[sMCNå ¨TN=±šÙÞ}µ #åÙEdä30é —DV¼Ü°TCª£^’-'rzÃM©»{çî—`B¢Ìx°^1ÝÚ@Šq(sÓ©•F™8±Õkå$š|>yWóu±Á×–´RÖ© ¥éUÊëY9Ñ,C»ýóöÍûS+•_Í]sô‘x“?“¸§{Ö{ò—#,k;ªHÑ;BG·øã…tÛÞµF˜B’‹Ê=£,’¡}9Áüƒ™ŒÉ+a2nˆFÎ1Ó\¯Þõ*»Ív¡³ë=›¤ ™KØÒŸ~èúá|I7~„Ÿ½|óúôäõéøô÷oOÈS׃iüfÈZýpòú·§ß³¯» /—µqSÈžšå”8z¶¹TÀl¸;¬°b'¬a>! ’mKE²HîÊ—L¶RfÂIVA£d*+š¼žÕ_ÃÖ¸v1ø¢€Ÿj×^¶l—«f± °8¬°¢müJ–æhêaã­HÊæ+IHDüº‹Q!Ë»Oiî¼'¹1õRP ÍÓr€8UlA2/’d‚·xgå‡éñbŽOT ÔbvÚɘwB}Jx)ÈsËŽ4xÛvdM _)‡¦Ê[àP¸y-P)Ùb¥ÉB†Xçx£ØœbÎæŸŽÀ¸Õ ãKš™b0¢R­Å®Î~MÚ‡±:H)øïS”,^Fñ|C*K—’1ëJ Ì—¹„:Pvf¬$bÊ^ô¤·ùͱª)"²â{MŸÙq¾‘r ’öù ˆ(É<8ËH6Ê¿L 6*äJ†ýˆ\êH;NõƒàFÈÚ*‚M‚ÜqÒΘÀUA¢’t1޲/lfσÎ\šµa%qófW~h#o¤¡YÞ’å¼Hní%ÜBÊË$Ý6kU±Â#:pØ++­@ÛZ+‡±Òwƒ"ÄnÝ9‚‘Y¤ÇÝ)iýB¿:Ĥ9¹) j„} *‹@r–‰‘¬ƒé[äè È\öÚ¨Í5M+)ÊŒv)É**Îà …켑LQw*Sܳ¡ ¼üa9Ñk%Èf ¬çí– ¾¶XÛ1Z&â‚—•)ÉuOÒ¢p*¤éì= \Œ]÷ I";=JÍDM{iT$©hÓN2¦™§ÍffÚ%{$•ˆ5J„’}˲oɾeß²GËÿÙf_šÁ»|ÿWßï{Óó<÷ÜsÎ=÷ÜsÎ=÷Ü™Œ‰9ƒwn룳·×ŠÙëS·$4>¸ÙóƒÎˆ‘Zž^Gy„êöw¹´®Ö-Z’cëà¤[ÅÃ-Š &tPcë±Óè¥îÀÔ«¦çêeÿ½²®æV|UbÙh—â}®ÛSÀW;¨µø¶E‡×­\vÏfÞºWúTÅN¿z÷Í­ÎÄ’#ýôºú2X”õ…Ã:—ÞÐa_§ño›7‚Co}lîïØ×ñÕ³†ŠÆ£7š7Ý_£é~óGjqò²iŸ)6®¸)Éî.¸ßÈ&6½8©S14ñ¥ß˜o„­Z²›Ùîw?ö^·fÑ•ê3¤ ÇÄäÑC)ÇVÆâœ{oÒá„û—¦~ìq„G¨5\g0`ÈõÑ»Ω§§»]ºØ]¯â‘w]èŒ=¡kKh7VXY}Š,·¬ÈjH½éפ>ËgšõWŸšy¥îm7±»¦æÚm›©ÝHÍj*gÙr¾kŽLÝu†½ÈrÃé’¾q/‡oé|µ¾«Þ§™%¼c.õå6~ÍHÔÎÔß‘9ºñËä.\ÇAf»wúU ~ÖÙpýãÍ3!L³÷ÝÊÓX…Ï´7Ó½ÑóËSÚÆ ƒ/¦¼ì”ì\Wy£ÝùO.å¦F>p~û€˜Jî°ÅvyËSÒ¿×´k¸_vø{]Ÿ9”„ºøg( ‰µ³Ï¯›¾ÔºOþK®¹¦ñ½OÇÓón˜D›’ó—5Úu£¯ÙÖ‰m‹§i]åœp6Ó§ºuâ ç­ÓƒîéœïÛÃí²|n]RYÙò4ì#";ÇËŠûêݽíéW¿ëua¶ók­|—…cÕ:í$S¦Ç_¶ÐØühÝÝCZ½ž«†°µGÐ}²Ý ´'V¾øêÑïÓD‡QW5O^zoÏR‹uQÚkÆÖ¼<d¬Ë5¦Œ;7qé^Ò´;óÏLûLü|Âää,Ýå6û>÷,?V{Ào-memâÎ݉Eég‚Ú¿_¼°«‰ÝZnÜ¥)†^¸¼©ט¥ÔŽvôe×ÞÅeM&Gµ+A÷¸å1è€vyŸ÷ÕŸ_¦o÷Vsº‘¸qÞ½!ÆéÌù`7±g€yòš¯6dÝ’ñûŸkìð}ùP;É),íãV&~ד ^çl&‹VË4÷j|<ˆG rùRªµã O?íG¡ôêϳÃÏ|$8éò0v}ŠÇbVAñôý37©WM™ê^ôÑaÿ”ÏɹÇ?—%”Œ`yq8IŸÓÜš¼Æêͱ¯gŒÆŽ`ó=hçµ7Û4fq-(9ÊøXÚþœçYÍ…j¢&:–O0 [Ï»@æ­±±;P¡õ<¬&cí'¼UßA%m¼ó´Õ b£Æô,¸?øÜ„ÚÄÇ~¤¤jÕm6óš©¿dRá:-›…ÑG²sb†U¾7±|ßûÕÉ1ƒ65X’lÒö‰^·RgóÆI‘Ãw$;¾Ã¤›YJÊ$­Œ×}Âà;ž[¿D½Ó)£{›kÏ/}¨A›eSùžÓ©ùÜÞºs†c¾|ÔºQ>ζ?smÏâ½ÛC—jWÎ[:®¶´lŽkE⥂}cæŸk»¿ëqƒn+Ò“«ûLÌQUã?ÿîûv½Á&uƒÖTõl8œu:ÉEWßtÜ ß³øÊ‡õ_~÷|t^·sa»Á¹#f¶¿Î«ª9Éám辺<óù£GGä=¯î]f¿òÄŽ†û­k=v¬ïë±!òFúÛ y“ά+Y9ÒséÇO'wmk–U㡽·ºýú vÑ@Cö BœÚ }Îìn#ÆÔÒ37\mß¿rvw¯ÉŒ}mIN¬Q×¹Îßf„Ü–rú±zïcƒ>´;øfãÌv?Þ˜˜}nþ©wÑ3u½«Ó¶;9þ8dUu½§÷šèžË›.™åœyw\…ýdaÏïÎ[—{Úº¼]s ~W[ ®)á…1âuQ×vëÕ½ÚÑ{r`@Ú¶+–¾ÇÕ·%=Ûä½ö-uIŽéF·q›Û´}Ÿïê¯y¢&Ù&üÔó~»ƒ×oyËñÜñm‹eç}vs*Ã,iËú_ë³Þé¤ë ²ÈŒK#Ïo<1$xöÜ÷“3 OWŒJvmŨè07$£gÕ;Ü‹§ï¾±¹°!ÒIkÝ¥Ó=Ï9ŸÚP¾òÒE´z.ôÄ›–>`I´–¯ÇÞ¹vÚa¬ÊÕ#ìe¬X>j̨‰—²«’ßÍé5òèË.k^³ÂÒü<ÿæpÖ"KÚöÛ¯âÊæ-åò$Ó¯æ²é0W£T­¤Ÿ†Ö:É][ÕöºÕï™CtìN«·TèíJ_c±Ç½ÒôÄQ@ľšK;ÌÜþùξ‰c¶5™®¶?´v£^ûÉv nó&?ý’íþzn²[ºÎøGÛ—¿Ï _Þ¾Ñ÷¹WúÇ,rûýxÐt½ Ñ›Ïuz‰;•`t¹z×Hæ+\-¸ãüãŽFÀû³a^æGoëÓ=`îâ©ÇveªãÁ“ço^×ÎDóNç“&E…sˆaíÑ|v­Cù:«u=6_žö1Ñ}«ýï´~óùVmÎ4ÖYÍI‡l-Ó5®ÎjwÄhçóNÅkÏ7R󬵂µ#ƒ|—vèYHY¿ØXoQ@䥗×tJ"¯µ[i·Ò!Ÿ:`ã‹Ù5†±Ö錊=óÝ‘8íŸv¬hnþX»xÙöö!.o,Óß5Mj×îâ’ÍÓXÉÍ©ý†QãÒBkêh™±ÁصØïã¥Ä'{+~î¹àfeL«Ño§%V­/}û³ì^á¶¶œ”º¬æÍŸßÕXɽ4—¸µlò·êææ© Ëš?U4W¦6T§~Okþøµ9?<ø±íé)+›šè77é7Óo*|çda=áã}VíÕ ÛsÞ¬oøšÕ©Sf'jý»aúzÌÃXÑM:ûnþØz4,yO@ð)§~Ç‚&w)´ÛlœvPo¼‹Ï¬¼¬ë¾yK³Yyc:zœÔ8õðÃdõø)m3ÀÊ-nuj8×#æ×éïKÂM!:¥i r¸ô¡Ô¬0êɬù‰k¾n>ÔqóòÍ—4LsyßGf˜ä>w[çvËÊÚXšëŽyíL_º7žxà}T§ü¨è> eÅKÍëœÏäÙ\öÏq9ÿ#½n¢ÆÂqyÇîeÏ>Ôã‹Ã ¨{ )æsÈj¬†Îv¾-è»/tÁto3Þ%6”Kö»òKÿåË(þÇ4Ú–—õŒ™Aû}rNª‘Þ¼ñœ-ÌŒZ¯+=²"Éàå $÷äÑÊágÆì­²mUðA÷Š×ˆÕõÔSƒ5ÜËö½òzϙӀ~ɇöxý/kæ”o?=ÖÚL“ˆêÁ¯^ž¸IC#¹U#Ï~Þ»øùÔò²'&ï° ]ž“öL«w­Ñ!íÔ£fú—ê½»ûÓ›ö»æ)›8fùÒ+›ÛV_¯oÕî‚϶:ýc¢‚_ŽY²ŸaÚjEbP•Ã.r8ùôIÿ£às¬ævfÜË'–Ô½`ª9÷íßÇmëËnàä0›~³Ó clû}oxrå¦ÖdÿMñw–…Œñy]í ÿ)íµò£€ìŸ ÃM cߌI3I››2vÖ®­¦¶Ÿº3tžÜontÞVºò¼]¢Åši+FGm½å5³¢Á'aÑý©3œ wß“÷ñ­wù‹?Ô·,Ld5"íymø# üÛ·³º,»{¹WÙËݧ–ÆŒç˜4h[ï8¾Ûñýöa‡¨ñáó'dv[{ò^ö‹ƒ–º!: ÌOßfôz\Ï\¾»wíá_,«Ù“è¡…¸§cÕïxkºsmÒ‹ûÌòHëw}À¹¬½=Gosî6¼øŽçâÀ€Š¼q>I:ÅZž3ÇŸüž~@Ë6üªýý¤§_ÄΘ½rŒºíMÈ®.ý_„ÜJ¯¼ŸÐ>'rMšq¼Ï¦kŽ·f½Ê¢àûÝ#¿>lž¢>¢Ã¸@ߎCßyTô^ÕqÀö—§ë¯—½½kЧ8üh—%î »4õ諸'|ªÛfC•öµÆE~ §º-0á™–¿¡OvkûK”!N•g5¬‰«GÆwÙw +žsÞÓiOíq!ìö«›~¬f»Ö³uZE'§F¿¹[øÔµ´•}’óèt²ó§ÁÅ­LKOm^Q²Ÿfâ"ºï³©ôœÇöPû„6ô½Â(“‡õ[Ñ tlðýñìHËmõŠWÚŒÎ/[649>z…žÏ˜1éõ?®tˆº©Ýþ²ûøµ†¹ÃÄ­mårmÞÛµ£Ô‹³'?'œ}«ùäHdÉmYvâ¼.‹¿™~ë«£¾àôQ›äÞ6jÏæè© ü4[»ŸÛü¬çi/âÌ=66{Þo^`«=ºµõà+7+¬Æ>-Ì^Û­Þºu[ý¡Ûïç¯Ö.ž¢³¤s\æƒXƒ¡ãš>g ;2l~jíã»}n¸O3ø´h¨1çBïñÊž‰t¶ˆf’¥½ô²nÙà9[“÷¸Ù»“R—¨ûÕ8á¸Çç^½š~.£(ç™kô&ü‡Äñµ¼3é•=]çêH ïSOg½>5sz—C¶…ï,=öªˆì[uRwfǺ ]–¦Úu£¯2¶ìJÝh½/çÖe=úÊô]qí8§|º”U[i58"Œ·µhêιË/w9 ·ƒWvpŠû×JgïSZ}¦0šBóµ;,èr8ðtXVÿ }Eµ _2³¹_M«»wÛ }ásäóÊÖ›­æ\«àÖîk¹%›/ï1+uö-ŽZ7†|ú{¦vq¨©ÝÈl—ÍA;Í%ZGÇ7ÏØÝeå9R|r!cñÀ±ÛÎ&zçDwÜ|´ñRù霋Oz¼ô}2<ÌOWíMYþæŸîͪÝí½ëœ†ÙÐÆžG«´ Z‘¾ïÕ˜¾œÑØMkÙ|ú„æç3Öª‡i'¦éŸ˜}6kb|ó–Ò±ƒ,nл/ Üzö OÏ€õí̧̫+ë·öº7aîäÅ[Oç´ãZÓ½‹·ÝdÖãNÆã‰nVˆ,_cº>rœÏ̹V‰cV5Ï{ôÂêp?ƼC/¾GŸ¿]JŒÕÛ±"bÓ=ó° tjÞˆ¸ì#ž¸¾G&çúV+~hwöqɱn×õ®ñ†uøêØ¿tKRÛ=6¶^v§Ì¶î8yÃåná¬$·É[2«^>{í丬¥_SÆ_w½›Þ|nõÏ5g¦etä¹ån¸@ÿðˆ“ l½>Óêjßw“5‹õÖ5ØözÉïlC=àªOÊ•kz¯6 ß›i3Ë`÷çÇCp]"5oõÐÔOi}ÆÜ¼!¦ûRÊ­ÓŸ}ñX;cUD0ѽv½ZÐ'¦Ñ‰ºvwÝ[¥æ=)>‹ò*»ç»N7ž×Ë`›×¾2n롇¼s:vwòÜŽæi¾òãlï0öFÕÄ¥4tV¼›BÚläõªù­òfUÎÅk/Ïü³rx%êžuëüî-+Ùïõ1­§QçV¾_äGÙ.H{b9ѨçÊQ”—b¦ñÇâ+ZÝÕÚ»Â0ðÓÍ{·?5༙ŠÛ©¥1ÂÇòžíhLÖ•ªƒqgôùx~O?ëÙOôñe·¨ãsÖ?~òiôdGªwê6—]û_/š•öúqèª'¶Öéó‰[ÆF¦4P»ìßÔ½ïfüî¤?ú2.8,ߪ֭¯ãv¢Ïè·ã­nFÞÒ°õýºUè·ÃµVÝ>­áÃ\$×TO~ØaüÔŒS…cö[P¿ž0%sàKp†Þá C=ïXüdÛ×{@.°Àwð´Nm®§0“ûú”a¾84Лòéy[§ïMûo½9Ø'þ£ó©Ceeæ+’C÷¾ñEŸÃCõÖ¶v†lÊíݘOÖfo,:¸+3é¨ÿ£³õ–nü~îáÍÞã?Šâ¯Äy¥‘5î›î!®x”¹wÓ®£sæ¾Ô:½<ŽâPݹuFƒ…{Ж‚$ïÞºñGß–¶®§èÍŸS»yp¿-åZÇ.?}|àL»TÂÊŠÚe³¬?»3ûó¡ ó;vк¦ûLòzÞ6m¿¾OÁ¹ ;÷uNÉT´¶lÑ--ÓúzôV¬q&§¯EG»»hµ×êë—]ìéŸÍ™yð³‰G‹…»_PÁ>Û/¥¯NŸ¾Ý}Awï[Ó>'Zì™ç7ñv u¸ÙT{s…¾W!õ­÷¢¤æ`\>øhœûð .çOy¸<>²¿¾î´Þ¦q÷ꃶõ^p[½ñR&Åß·ç;ûæ ·:—­­Ò[·×*蘇և¡…qžûýf)g5wjSº'$…z;NèRØúÜŠö ¢Æ_LÇû¨ïT;a§®ýy[ãǾ7Ë {j¥^Ù;çg}0¼ÿëju£-% ±ÝÝFµÔ lLs~L÷F§8€wïòEÇëÓqcíçƒÉgÆrÞ×¼×ü´öaçç³ÈÁË5f½´±ðXÚ±K›ÝÅßnÞξ¸„¤ß1g“Ƹ ú‡ìM†T³·ï‹JËßë=ZZ;p…Æé5C§è\ »Îž«™olìeíG ²ÕÔirQ`âb‡q‹ÞR²¶dÌÛÉëç<¾ô€Ø³tÚqâá"=ÒφñvmJªs®-hô wÈ; è8´öJïH&Îj¶¿uDÇ a“¿œ¶]w§umËý¼Öšö%¸6ÀxÚñ}ñÓx'ýLJžÝÛ¦Mõ6›5Õíô û¯âÎùôæ‡þÜãïL††]xÄ|×ýÙÍúE¼š9}qƒf¯é9üVÎÛ¾®C}ÚVŦŸ/Ò÷™U›±Â¥ªÍÃÉ=é[›&tH,½Üÿü‡[¼œŽoÜv²÷’%eíû;Þ_›0&Èã¾ñò°ÙÝöŒpKÔÞ¸ßÙ®íÀÅ}ŸYÞ3 þpüñƒÈQ‘[c¿Ë·älÈ˽®è»…ÓÆê>«sý^²5è}÷dž®\•Aqßmµ¢õñ['IÇÊÆ:Ïëé°¦æû‡šÓéhIš\®íü™%ŽÔ\SØ»@wtaD½ÁW5ÙNº‹'Ž:9+g_8åJSÂñG׎.hŸTk–?àΌͧ‚3¼ºjº¦å¤oýi½]=»áÍc‡NzÔÏÛÙíÞí>ï¼™ø}j¿(áñjöö? çÂXŸÝIëædª þÓ¨3*¿¿aéµ`øÛ’ÑwwY÷¼ÏɲaU;&û9 ÜuÔìÝ4·¡¹÷qúØ$FÄ‚¡f®½í4.Tìi?÷(#Û¨ÆÿÅèãÛv—nîZŸ5?¶óàØ½íWÆ¥˜0§oÆë{û®(]1ÈãGnN?Òæ]Áœ©–>÷zLÜ^s蹩íaðI~òÛʼ>³‰œ¯µsž™ÌT£»?×ùEN™îÔ(ƒ†oΣd}kãé[åz1ô:kãnN“ú–šh}VRñ5‹úõ £Û3–‘ÎZ³ÆúMÚïã7cë÷Ë:çOÕë/m LY°èÔ˜~ÅާnÛ]INûr•Lš×Ô}]í;—¼²ÖêÞÝÀ»0'jê’v³/Ûâ†n{?þ±OÙùl`%sâ´° uÃOß=©ÃÒ›[ДŸO1ºX:›Z©¦Na}ãÁKËÆ=o{±d khðbcÆúá[½Î ì;pðùN.›: Ô?8÷æ¬ÓaiigÂìȃr†Ú¾ÜwrPö©­…Óæså5}>›Þï㢵žÍùßJêŽeo íyI6õ:÷YŸvó‚Ï];26¼ß'ûom6i| ÷Ê(gcPç˜Û!×v¼Ü¹Ñ&« †®a‚õ÷<L›qÉFßýñ»ïÞܸsðFj]òGƒ’°[ùƒ]ûÄ?ûZR¬£ij@÷äã?®í{¹]¹Uh·Ñ3r¿Ö÷u«Þ~Ðî-#w“ý‚ˆG˼‚ÃÎÌì¸É8½¸iFYýîÝœ¯½¾Ë¤çô™‡«Ž×lYrß²˜ër’ñ,%àé!æùk3—oë¿c流»ìeàž°ˆpàÙÄìá– ø¼¯Gɉ«h @Bi—‘=¿g8mºÜúL¨g´Í…¨™·8çÆyê˜~åQ܇ë3{ôø£W“NscÄÅÍj¾ÏVlz÷Â6}@©NØ ÊÒpã§_¯|þ9ùPTZZÅóËúµ÷§UÄóÞ/hry÷à}ýч—»0íŸÖÉœöðÓ —éF²¯}àÖ¶mÛ7gïm9í´¤¾È¡OýÔ¬‡éËWZª¨=ÉëYæøÞüÞaNè‚@×Móïõ\Óó ÷Fÿø»i~þ¬>îŽÞgnΘ»¡ëÔÂä¸Ôõú:«*÷˜Z\pì•uõÊ)ñ¼= Ó“3Çç/{×[ {w›Ì•3g¸éÙ#<¸âCÎë}ï´ ^ZÒëÈÅ‹À×pŽÕ›±7Óºk¼î¹ W «+°©ÓYÆŽ ƒBx¾›]LŠßwj0½~p]çs)ÏÎ7÷ÚûAãZ„ñçèûjûßrŒí¿ÚŒ?¢»;æÖ³Í¼gh3´óß#'~uëîã~+vÇš~}ÒžçSK»’Ïî% ¦Œà¡ºÔ*ëDBŸÃÉs|Y<ç@§¹]v…Oëœ<,:òÂÊÛå©Ó2=\z9‡èvúQ»1xjqÀÔÆ)$7Rm¨{xàŽ€î‡"«û>Ïý4nóÕO”¡/:TÆÞ¡¶ñˆïv«ŽÍ{<Ö=Iy|ôËÖé/·wÊtŒN$ŒìY_Æœ{A×2Œ¹½ò ¸t©×ûÆØ²p'ÏCÃn¶ÛV34;Ì%OÍ×qÄÁ¸ÖgξÐoH?jZïg}ÚÌoøüèŠ!·±—¿šÇmßE =4—͉Î5rhîcžÂ=ø=¥iªöšaSvM+P_þ ßÔØü]øNøMøEµ~_«Õb?>_×jCþݾCü~Øù騵~9£U¬ÏH#’9õbSï ¼Òwpõ Ž1’Lò†} ÖÿpͽZûG¡•¯mÍRO4¯½÷bI¯Äà„/I{»™¿ýdÿzûã¦É„,žýáÏk¦]n"5TXš1.Ï;¾'§yOõ;}ÇeÓ¶W|nÞöøÙÅi Ý®»Ý«è~ü22çÅó/‡?¶¾¶ªÞÒd}ÿÔ¯/Ó×%¤¦V^û¤“P9雿à5Ì^~|ïÜ XUï˜ÞëÒÑNW÷fŽñÙ{lV‚þ}óI¶)6ãæ–·:KšêšúâƒýÁ ží¶«Ýœ|¿¦þFÖÅ8ýû/]ö&Ÿ¾³J^gî7Ý}¹~jæm×ù½î™7xój/li"ÍN°ž²Â¤Orõjýé®´ 3'óá~ßæë¿}}09 ܾ`ëEns„§WßgÖ¯¬w®c…÷?’øÌ{˜vZQïGß»ïÜ›éy¸ oˆÞá¢ÎE¶;â6œ}×ã¬©Ž® Ak®XÍËŠÛ1÷ÚÍ[†‹ò$”Qr7MÛó~ÖÃ÷=¶jwð8T4'ù†öø ó™ÑÚf½±7ܺFSÔk§º®©Ä/Koæh³bÀn|I‚vèúæäYÏZ×6lOýöš½¥¹ºîø ¦WnznÙbUëR2ò >Àð}ëcuÓ¨Žå{¼üÎÅŸ©Ä¯‡ò¾övŸ`äwðm yÙ´æ×lWáMµwß×™5aÆ'çWDÖã|²Ù–s£—F޼?º)«ÓšâgÍîaõ÷©õ͵•NïóÎjk7Û£g™®Öû{Éìn›—’s½¢ i»eÊkí²KWIïžéqÖýMŽÎ²²‹[ô\×è´ô[Ì—Ûkº…, 4gx¤>ÌÝ4°èÕçå?>œuuquÑã«÷+œ¦¸_ yrþÙ ß7«‹Þ/ì}qͤŽåîj¯‡¨lÓ»“û8ÝMik· ¬ö¶¹nß×uG·NZÞ0ìɇû©Ó.Ý?ÕLŸÛpuòK\†õáÖ§,;zºï‡6ù ZPlCZ×Vy[t–~Ü4ÓåaZÓ±¯êÍQ;ÓÜÊ÷Õ¯h¯Þ:ØÕtñ‘íu¸½šR¿x<ŸÞ¼Y_÷ΗäÐÒ¯ï?bôˆÌîÌzt g¤Wéè]kéÞØoh[­ËîÏ· »ÐQ7TíA™CØ™}cㆤ4¼ÒÎhÜMàÙDþAôéiy¬0tÖ굜EgS›Ù¥¹Í± Nuk^}þ‡OŸöav5åX=¬~qÿÁ©QÓ’v8‰<Ò¢QMφA—õæ$×Tö«\ˆ{{ø‰û ýo«òº$7öGöšµµùsI³³YÚݵ/X&Í)AMY»›î{ïn&‘c¾ïÁ½;ežšP×Ôøíó}ßÒAÏgÔ½‰Ÿ?j©®O?ÃOÖ9Õ gɺ×/ß6¯ÞyÏífÛªÔ¸Ó77ià5Ï:>‘Ù|è[Í1õ‰¯–hüxw-@#kU|IW‡Cœ9oÔ9êknd=kwËT£ãÛk¢XËØÞ)mX¹~Û½ò•íì«ß§Çyù/JùÔíZ%£Oí¾™U¹pzP~¸(û«»®MŠ'³{§åºÇSw,698ëõ¾¿é‘ùö>âfÞìþuÈ­‹»%‡ Î(xó©k¢õ‹Nã %]5Ya~åæÌÂv.ì6Ƴ?=³ä£Áa`ãjß³Ó_oˆ[ö0Íâ{obÍ¡îíÞù;\rçH¬l]9åhd@`ìôÀc5‘=2÷j}¸cîòAê…óf\›Ã¹³:U sJ:­îCí™Û;ܮĽNgn}žÑã9wáüÎ' à®XŸÝ cEç;³çV¾¾Ô]Ïöka»FÒ¾ˆ®Ó¤O¥žšÒpõ̯Ûï4Þûtºqäܸ; 'mí°ófAX¿L§þS_ØöËûö,4ˆ~6ê\ {Õ½U‹NM7Ÿû¤ùǸêŒêÛšCž§ÚØÅ^‹Ügq!H;À,ujþ²9% ¢h~ÕšOI³]òcŒ.dåä¥ëN £p~”7Ö4ÑS7¬iÖiÕª¹¹u«l¯¨™­6wnõç§ÅJ4H‰áÆ2¸„D2ƒNˆJú ú°€~lllßÐäo KÛV–ÖÖ6öÖ6¶¶Ðw–6v–6­‹¿ƒ±\™¡ ‚tßµô^’¸ÿ‘ýš­böqCÕ[ƒYCý[[hü‘oÐKÓpÜÊÏŸ;ÌpîÙ£ãâô«ÿå××ìÙsû͇¦/é_«>ß§?±éý²¬w?®»uL³}Ÿ>$ùfVföðµ£²s~ÑÐŽ´œ’Ñwìv³N Ñ­¬8qåq“Ë<ß;D`G\^§ÏƒL Ù¯–žjõ­ŒÈ·žYº8fzk½‡/X÷^Pòlóº\Û =O 1·[µ¿zuaŸ®M_³º%·Kn»/psŒqÙtò™‰]Ôæ=ÃÝ—›e„LH*ÙoT0>óÀiÿ.¹'ÁÎ9™ÉYsÏt[—üÀ««ÁIïpÓÁŒë ÷6´ Xx¢Ûzµ?ÊàÏÏŸŸ??ÿ©.¤˜GqÈlМ̦™S åÅ Å‘é4*™Gc1¹$ø 'âWÖK ;¹ë¿¥•­•5´þ[ÚB‹¿•½½]+ +KK‹?ëÿßñçÄÒ8 €ƒ‡™ ÒÙ §¥E¹-ÜaÑ ƒ…PYZ@a1y`ÀÅriÌ(€  ’ÐAf/ÀˆÅÁ¡Ÿ@É‚úÁþ‹KW¤™øì¨:™ËF‚‘äX:Ï í('"q™ šŒäã’Ød™1Oæñ8$&™šÈ®‰HÎbð'ìm‘AN'ðX$@‹ÄbÀÄaxøxcÈ‹å0…ß… : '`,qtâw!Þ’Lã Øì–@ÙEBòøø°á\ ‹ "cétº(“pS€r¹ä(0 ¶B,È<€ B̆þ4LÆúO(Ñ@ äp:‹e ‚ȤjIÿ›ÿ/þonlÄd§+Ž`QùŸŠRƧƧz8`ôµ¥ò(Ú¨€"¢dIœ8~ˆ¨IS+Z$ ¤4&ÒtJ,ÈI¸<¤X”  {rQ5ê~i09‘§áÆf,&=ñ÷*AOæ°íç¡2)`0¿G9ªÏ8ËW^ü·ø¯ 3. Ùþ˜(\¸É¿DOИ$!"ÀãÄ‚ÿ”† Óé¬x.I.]„Eÿ" A‹b²`ž Dæ•, ™4úO¢©²– q Of”`ñ4h!ÅV9´ÿމÁôFAŽu‚ɰ5H²Œ¿dÕ'²1,ÿ%Ó-’Èhý³ó5’L£sÅ$HÁld±"ÈœÝLÀÔ±9Âýß»¾¸PŽPÙ¸–½¢ŠÄð’ŽâYvHÈ&+žÌ˜,¬›0(@†ÃrÎ…YEè4È €ùB¦1áÆ0Xø5-"– @Çr8 “'\{¡/eÙé±L:$ü^ "¶=Ö'!’Æ‘BA&‰Œð*’NŽ‚qãB²¬˜lK÷%ËöË…ì9˜P4¤ê ÆH| q‹Ì„Ä‹Ì`Cc K,ê7„0áeú†*KãáÀTI ¡ŒQ78Wxü` âƒ˜=È‚CÀI29$C&57 jæB¡@oÌaäqဓ´îÀíqÿâB‡†Lˆ$„H$B€Ä5E¹H”faS&‹I’Û\Qgd:TØ%òÅ?©6øhj¦*Jˆ°B£Ž$6`üe)T–aÕÇ…\ØæçüŠEFÞý~KcRè±T°%•¦ÊQ %d¤h %–* ¤5$Ó¸ú „þ‚5¨-°î@þå„ÈÜÏÓ&w¡pc£ÿï![lø`ʱEUEBrQÅHê-S ¥õóÿ¯af")Ã$˜¥Ê3 Vÿ>ýUJý/üÿÿåø?ÙôDF<•„.V¿¸  8þoaeig#ÿ·²±°ýÿÿãÿ˜ã0OL|٢΃à$fËE'BV.- ˆe³Y‘èÊ‚|Rjúò%K¨5 …AæÄÉ\Ì:ó„°^‰§%âÒˆu«LÇ‚®åE$ŠÃW¨ƒÄ…c˜ ²+•‡‹ /^‹ï!pY± cà"¦œ”e‡j15/ß,æ;‘ÚÞdQ·Ž5ƒËä)1B´ˆn“Ú‚¢xò-ñdEPdR`äD­O¡í‰a¯Eñ,N ȆˆQa¬9èZ‚0ÓÄ-.t e~‹xÞL 6Ä-p¦tqˆÌa9ÅÉÃUL |ÿº°MÄÄñmkl Ri‘‘ ì?CÎ5´è h1E/§< 66ÿ« äkÿŸÆŒ94´ò£KÁïØþoiý·±·°—Üÿ·²°þ³þÿ‹öÿ!5O$z "j:ÈÃ#Ë– ¤òqÞ´¨X@¶2ÈÂA{O£š@zoc…Cõ>¶|{òå ƒ)H¢‹´‚ƒ$”#kÁÅC4ªƒ'rᆠ~Øê]—¦I„XPœ„QM,~H‚éY{ù ðãpeb+(¾q ‡C£RAf@lŸ!iZb©d8ªH DQÙ p60LC; }Ó¨ruÏø† N´3¢h_)D@ÐŽFÅ…§(fÇoaÂ_‡žXu úã&½¹Æ *Xx!» ADЕГ5¿ˆDÁ¤(ôÖLl±‡Ì{"‘-G´W®@T‘À4ò 'iãâÌ 3…„“ÀSæè–‚xˆÅÖÒ¨)&rG›O2èdJ ÀŠl04”/ر !Ùu‘A‹òxCã/ºd¢” üŠÈÐJ‘8`X‚ÿ¨<ðÕÞB.ø›C* _ùýQ ÿ{ðK.•”ýlœ’Pðwÿ-Ûÿ–ö6Vö¿…­ÅŸüß“ýïÆ¤²Y4&O2Ö#{»µåx¢öšg´pÙd ¨ :ˆÍS,æ¾0•ò½Ý+î À„œ'´òà`‡€Ó’´Ž‘) }-6¯“ElmX=ñm5ÜT䊿ð5ú·Ð‰HQJ¯C:§!† d|‰¯h"Y¬¿dÓO$b#<â.Ë`ãa²áLHAóÉdÒè&&R©hð€(@˜ :`ÿÖ‚8ˆcêPîØ'ÿ(ú|Ä(PniÐÿ‚ˆ:7 œ·K¢1IV,üÙå %ýoee'¡ÿ­mí¬þèÿÿ°þ'2DÖ‘Çl¨=lgIX8©<&ô?E‰0ÐÚ+C¯‹èñŸRÍè<¦¢™†Ð¬·¦¤4Ç(ùËvø…äËÆ"^&Þ"¸"üqý«T‘ý¯o¡ÿŠÿ3á,ŒßüWBÿÛÙYKÙÿÎÿýËãÿX ßÉ(>ö}ì BŠ*±S/®V 1íá¢O©S…õD_„+Žò¢øÊÚUnÆÓÁ8n)º(ðÃâÉ߬—‰¿H]ª7+ñöRyaþ–ÓdEˆ— ÀÏ@Y#½dHäØJ8º­/ü¾Å­} œ5ŠdˆIƃD á‘ ¢£Ë&:0å+Ê Èþ… ÐY v£ÅÂ*èÇ&?‹œ­NP=©Oô—•4ºñ,ª,ºèÇ&Õâ(¡ÿùÉÉ¿ÓüoQÿÛHék[»?úÿ¿lÿCÂ(a4C9Þœ-&böz˜hàE°"@Ÿ…‡(,G˜ ¡Ž‡|éíÎ΀§ÛßdXËFLVæª~R3!ô_ôMþFþ?uN$ô¿ˆÚ‡l8Z$RýKó-mí$ã?VÖöôÿZÿÃYý"³]*Š/CŸc8\h‰ S‘3”h2SƹԿð(Ÿ[ÿxà N;™Y"¦ß_Ô7øßMë¿y ‘Òÿ< |fvp[¨ýomm!yþÃÒÎÖþþÿ_ˆÿøÁ#;‰yåéVYA;»q¸d­Ìâ`_9Oˆèé2Sè#&•»ÑˆÔŠÍfÑíY€CäÂÉÜfT¹ÄÂE DãTÈò=…÷…)pq”¡ò¢*(Zô•Ê„¢ÍT¢” Å{%yþ'Av¶§ ®¡X)`›2ñ$‘ñ—ñíBzA5$…K2Ò$tàÅ—XlàELèôàarŠ)€ó ô#¹¸ººùâ'gñ ‚8&•€0ÝL ‰ƒUܤ¶±°•ö¿Œýe´ró[ðÂLYxýdé!’ìBæ Άþ-C¤ÂF¼¤:ËÂÁ½™(3Æ?GÕOðO%˜ï è’–Œ®ˆáv ÿûRXQLZœÿÁ‹þ›öÿ,lì¥óÿ,ÿØÿ.û÷‚8‚¸¬ÈH5VÀê €Ð"ùÉ ?º‘ éÄb…Hãà‘´+s8dk)T™D9-}$üû‚LáŒ逓àSqú0°°‰3! Ž>7Ì"œÀâТhLqµ†‚láñ‘‘Eˆ™4:\¯GH= ¨\Á@–b$bË£hp)xë Á@6„dc)A‚mH‚ù£bÿÃúQÔ¿uÿOFþŸÍŸøïŸý?–¢ìß²ñÇeÁ±.Èí&ÉÙýà×6ÿÉ À?[l~~Zÿ#e<ùƒ°Ð°JKA úßÂÎÂVBÿÛÚÙü9ÿÿ_Öÿ vþ~ËùÅ*œÍâŠkG [QÅ×6Ç™ –†_Š‘ýÃêNbþs£Éœ¿=ÿ×ÊZêüŸÝŸû¿þÝû?Y¡˜à`ÓÕ ðFöU`Í 2éä§þŠÏv"› ùÔHDTöž?ôäWòð„&m”HN¬ð+.äèÊþJj?£…²±ü-1*emïÈÕZHí!Y-e'PA î B2å#aÇÑ:´ …·˜† }@cò³@±$D#»*X|JDuÙHé`¤â<<<È?Å£»lÀNÿÿ&…¯Šþ·¶´ªÿdikkñÇÿÿõ¿ð)¢ð̱ýjØ ÆJLpqJÕüYûP$ÌÌæ@z*AÜYEbŸ‡Å‚KÕAEañQ¤Ö¼ø÷Bë}àÈñ lº™sɱ‚ ¢ÑS=Œó€O Àp9 ˜e)jZŠTa?Œ®‚«L—…Šx$eÊ_À"rdâÙ"rFã'¨ œ´ JfùA ~qÑ*¡\À×/ÐÓ×'ào’¬¢® Ê RlŒIt23FÆV.‹Ý^ãçø „k‰yD?M‘ÌÌ€©¢âI—¨C•S™…Ÿj#ž…)J‡ 'ÎRª<‹Ä7‚-èS%êÈ Uóy-`Y@bx)èZdF®Õ'É54­H|GÆ#¡Y§¤0š’è´¨‰PÍ‹ „òc)¿´‰¼:ü&¸/å*\(@2Jÿ>|¡ÎL% þÁ&1|#›'¬^þ³ô 9]AX™ÈA.# Ž3q²Ê”àDsMùù_†Ào‹_K‚É7¼}ˉ¤XÙYÚñoŒàׄ§ >šGóxl¢¹y||l Á&K&†Ð ¥–ŸW†Žá)kc5RDeQ6þ¿¥B5¯¤[ñí<ÎëEVƤ~a1Œ„Z‹Øç­’vŽ”AFä©Zò­SñX%& ‰1Øáh¸d/\¶YRä˜÷æ.æq–|RU3ðñ|ð²DfR@:¤Ëx\)©: ¾ÕŠ‹Ô@ýwlE|]F)Oà5´²˜Ô¿žN±š;Ð8‹#PˆŽ$Y•wZšBR3Hº‰dßR-aù”5è*ÃE“¬¸`Òc\HÍp8|±{ŽhL&ÈQžÙ !QŸYøg޽—L4Ùå”9æ)€‡+]BXŒÁÛÜÊZùÙ }+50bT‡ƒ^„~ÙƒÙ)ˆÚGÖg8.<¾S‚ÃŽåB 6[‘ $CGÊØ=9ig%©åj>„éÃ’I„"-`㋃“¨mg¥ªRD{6Q1Ú!EE‚ÃFñø(ÈBd «XðÿÁåOH¦ÀY‡ÀT2;Uè§L"&CR&!¶$2'id®¸N‘?Q„\ƒï“ÂC€LzÉDõ‰ &ÒŠ$ªe G$ÉMÒñÄÌ3²Ð'¤%ñÓ/ù¼¤­™Bê–‘.áíì‹ÀH&P<ÍÅ éýçf¹äAdß3©Qý‰ÌY2Ï/hÃf⯱ÂT <0³0slþw°ˆA£D“Aºò,¼…‰ê¼‡yz&Š £¬A|:dhˆí-Yh™ ï4"ž8›Œ–$† c˜Ìè—èB/2âûŠŽ rÞZlSUr dl ø;{m*4v¥°747Y…šÉÉzD¸Y ÎD•‰/>å±»½‘;Så%£‹p.Ž;ߊ®oÂßàd’DOÅ¿vå€dØç!p;œ2²'Úv1„°”UaÈBSLWDCn Îðg°y‰È //e]xH‰cEâXà$/6å,²A„EF°˜ rç<ŸDÐ>5ÉGŒ¿·ÏKàI½S© ±$HØ¥ÁÚ˜9ãY˜_N™q°=þ-2eà½2>‰¸ã0mh^öq…ˆx°Q"SvPïJ:ú¬ˆß`iPB¾#¦5fyAÒáâç)®{¤.íÏb¿åØl€2ì+¸&•¬TüîØV JÚæH‹‡™ yÙ¢—Æ`÷ae~ÈÒ…‚ŬPJœ”ᯋ+H}ÈïS–æq©“ÖµòÂááz÷ª\e9™–q–@œ•‰[’•#[leßÌJ~3™‚h4ø¬@• ‹Ä-¡Pµ”y…}(Cv¥},GƒopÀ®ÙVH¥`ÌþE¤-»*¬ÂJ¯üìÈ#Í/õ¢ %uABfÁ*¿*¶Šãè¿…E]HËT‚EÈHØ’› öš`"ÀJBޱƒœÃ L•9\¡%\Ìʼnw´²àfÊ[&"Ðæ¢•‰Th.íH­üBlš  ‡°PÃÈX#qÒDôf+9ª]žñD8 Æ„Í$2¾ r^˜ÄŠÄc]‰’½ „p@ H‹ƒ ñSüIHB÷¾ñp‰œÉoƒ™iâàav›hIIj%!}‹/nr»ÙVQ°Þ`bˆ®ÁÒ5Ê¡%–gUÜB%e¦ 0à~Ì@&…ßµËMdD°èŠqæ%ðä ,¸éó/Â$c9€e[ÉyŽ™æ|Ó ŽßƲyȦDò€ä¸£ŪžÀ—°ÁµD‚ò÷=°°RË·Vˆ“™l@£ °Ö)8eÈ£1EbÈh\T6…ÞhºÏ®Œ_))µJf70Ç)§©¡õ!B–¦F|ÂÃZ?!5Ü1oqÑ´D² -\\ÐÃ+\B$ÃÅàr…ñNäï©’"‹<%À¼÷'`—¸˜ü¦EB{ÌÿYLˆìXÓ„”œžª%nÿÃÏÄÎUâ¸ÈݘÐêHD‡)` ¹©–K´‚I4 pö¹)I¦s¡_L]¤Ôy*nÔ`ãNÆCNƒa2 s¡aÕš‚è*¾ÏKcb“Ð@ÒÅ‘ôÉEÊ)Ɉ3ÃT™H‚€gôàè"d="œÄ…k‰C‡ ¢[³¦¨%$ãRyȜƹúúºù’Çù¹I—w‘tΔҧÈ99¡ƒ ¬,," ¦e•ùˆ+„² »L•¿¹™œb¢%aHn%çZИðR¸`¶Ç‘‡¸¿gtѾþóÃËÂÊ3YI‰ŽeÆÀ¹2“ 9!ˆ !žoò+ìÄ@+7ÔJ¶ôpÿþç×t ôwñ åæOróqõééãŽ~±'ÌËÍÇ=Ðy-ºQö»Eæ· $7•¼|@æºOæðäºhr~È,3GVp‰å}&ý—N‹NÆÉÝôm )s4#A$öPž¥`©Â2/‚f&üdk¬ksq¾)ᎊ~ÏGá× ˆ¡b.Á¬–a‰6'nD8!’ ïàÂÓF®´ÁŸÉ¶.é,ºŒñƒ·Ô!ä6Àê ÒA(HïGêç‰ì©3„¢Ö‚¾Tq•$PQD6FÀ z€]X¡Ü5v¯…Â,Ñð¿DLNá¹h‰†R¦%ïDAöÔ±$áå D)³#†Ò¢‚4¡„IƒPò¤·„h ÛȀȿÕUyx"¤‹Í@•©T è§h•Á@ ŽàϤ˜p¨?Yày#>a„Íd;-¢®´Š³9,6È¡' äµQ7L†[bÙ2LЊ²¢ŽžŒØÁ6ÉüZæ®­ìÆ*Ìfþ*Ž„õqÐ2ŽÃA«¸X†€+2ƒyX~ôo”.À‚O¼h2Ë"•ä4YL €…GGà ƒÿ.¢›P$Q6 è¾’M% ¸™Ä¡@#M‹„Mâ¹pZ‘³KÒ? +Ýå±±[H} ˜…"` à\‘ÌÄ-%N)‰Pª¬ÕÃ?âCFL4>`ŽÊ!J>~çjH×Ö$þBó“)›üÝw‹¶8ó›©t¸ÌRåíœ"¡1@H…ä4–‰¹ƒDcL¬™@¨™k,äM0Ì<$oðí'ówGp’MLÑx9"+¹€Ï 1þI²GübÈŸážPà”àÌpÏÛÛÕ “¢:\Ñn2×!Ei$…åb$oû³˜ÈðDùã¡Ø8àß./½“/ò£üñ[“Ó詇dôl€“~…á,r[Dš(4$•A´…šÔ+å€℉kV"Y¤` < ðÕêÈ®ZЍÕô;§p Bø‹¢$.AzpÒ4$I€('2ÒÔDZ&ÀáÏšxZš¨¨ð1âÀ b< 6táÃPÂnEŠ#Ç2E^¶ ¾ò×þwF¶"Pf¡F¬•øù›ÿHôß Ì,•Ô òÚ[Éh/KÈko-¯= þ62ÚómÚd—ËÆµ4ÕGÂnÁV¡„ŒR’…¬I˜<‰:VE ¡Á —¹®«ßÅú·@±Q<ÉÄ“ªø›x\ A—sú» §(-1A—µ·-ÛÜ‘6x$Üo™Vª K‰¢ŽŽf¡Þ^ZŽÃ ôù™&N– A´ÙÉ (p”ÙƒaÎZŽÈ1Kg¼#¤r¸ä(ÐYÂpr4ç¿Ðr4Ǿ†;Pêx>zé'¼m 2ã~ãÉZ¯H¨vEeËZyä+ry­¬ VHà‰8‡’\ƒ}½In.#Ýüeîçþ‚düÍ‚¡À$–CôÔw"Ú€‹Ë/’…œRA@ðµ6ö=<Ì’£'7Y5—AÔ_ûëÜ ™úá¶b›în¦ˆ_i ÀRS™q®h^³Y œ×-Ïû÷³H”QNÁ“ßœM'Ó˜róÆÑ?L„&yÑb Wò³ÆÍ)‡¢‚_ª)ŽÊÆP9I.UŒ¢$, HyÇè—5—Xˆ_QdY6DȃðˆeRMEƒ$aÊ·ÖÄ«Dc?6¸Sìåù‘È&#¢‰¨@²”ÏÞ«$²¨âl¶²I¨‹¤úEN…ð§S4‹£B¯Êx@R nV€{–ál¨„!L†—1#ù7*ˆ9» 1‘š©¿k¥AÇâ¿6"2¦äK“%¶Ú´Ü©è™Ù‘ä÷à2£$æ½Â>èÈ÷ŠË.)µn §Èøþ2UpÙ WåågVÅŽº SÕükt/‹ˆ¼•LÍà+dsô,³§þ¤ªxÓ?jõWÔ*ôEŽ„‹îþj+ì’ßÔ¹üPÀE¹.ÒOÚ¦?£J»]¶Ql…¡IÊZKâµÖU˜JÈ!ÄoÈÒ碀 à”ç8¼š)ðNÿ†ùŽ”jTÐ¥‚=´ß7ÅeGR°yXÁ›dX7XZžò¢ù¯²ò‘4UL|‹ŸX‹,~ÿZ$r ZΞ4\<)žCCkÅ‚‚[È‘ÁÃÆL†¿òCÖè`LÅALÆê pA8rÀq0-•QQ5 gX”RŠn'e‘˜ü£gÈi¶„0%bé4H7üU"ù¿‘±ÂL#¡Ÿ€ê3tÝBûÅ-ÕEëç­œ™òE"[àD«ñÿ¼Ø*+KJøm‡(H3‰‚d]Hù¿Kd_Ìï‹ º¦É]é~ * š„U,§ä¶ý)«ÌZ 6ý ”ôè0 NQY±t¥?1X”A¨øA2À€—CA"ñÙáÄw2¸7<¶©S„÷‘K³cCü|¸XW&,s o}Eƒ&ÿÏÎI14$ê˜"1U‘ldÇYD á]b…¢É"|Æ´£#¤Þ‹ µØ§É!“û%UÞàþ%3BPPêBOz'Ë Ù‰Ar¿–1ë)Š?†¾ ÊýBú$DlñZ8‹À¿Z)i´—F¬mÄ/´¥üB[ªjmÅÏô¨RüNÅ4&Q¾Ë˜rH¶«˜!#=õ"É4úŸ™÷gæýã3Ïâfž…Ì™×Rñ9¥f g³a—ÁÊ€üIGCϦ`µ•GÜC¤Aâoñgþ‰Í?8l†§ƒK“§ŸœeÎ>Eß"“OοuîÁ}˜à\cxΨ4õDšZ©8óDšZ«¸ä‰4µù7­xÒÁ+‰‚P’avñ8°³†”3É¿ Dj¢#›UhÍYx›u$Ux %^é„Z™iYxѬ,eÑOªàA€Ÿÿ .¢'üaXJ#$Q÷IˆQ‹õsTA ¦4N\Cƒ4ARY®Ë¬` ¢#w}üCHGИdN¢"LÑ/~z, ä™qyÌ…&§.R)U2jOŠáa$²¼1ÈQ Z AØ÷†c È=›¶0'~ ½ý"°Ø /ÞÆê8g áó*’Þ6? íXæ6ª –Ÿ +[Å ²¾Vr ù\‘¥ ¹ha@1á)Â#ô)4FnÌXÈ!óXìêi`j=Fx¬úƒHéTñ±ÇÉú@¦@È(/_íìO¦Ä‰®h©™#Ë—zø‚)[QÌÅÇû-·…¦ú»ùxúú %eà'æ–KœÖß1„- “FW™ šÁ`8,º&L–~¥$Xq"37~q"!(~µ-e¥Ò€23)* ðßTø?b?°€ÿÿß@é¥ Ù—[‹} ºŽÇ¡‰*p4xdŠˆ ØZXH*h´é_“ ¯ØÄ‘K“ŒšNJ“‹•R’GhË&”„ym«Ø¼n‘7²ëz)g•¶È áÁ-¥ù¢?)!g¦¶øe>üã$|L¤B1)m͉юVcJ”àD¿—¼S'‚œDhi—JöåôÊdx +Þü#‹Fý‰™ Ní¯)uñøÝ!‚ƒ½¢9ŽJ%e‰ßr€B‘¸ç}¨ð¦~;3gtXUš> ‰$‘x%5¡eTÄE$‰þõ©$±%Ìd®-âóï@Q¶ÌÁ' àÒ|¨„+%jØ%Ò<d 0DïïÚî˜#%ÐУpôü&\²¢!_n½=½ÝˆD˜2.~5 Ÿ0‹p¸ÖWKFmALg…Cb~`ˆÞíCò…2Ž”C?1Å\Drº@ aÃ@F­>óGÒ aá"7û@¢j äÅPùƒœ£±8œa²«»'äR ŸRHŒX‚Ÿx˜N€ý?Åñ;¸Bº wÄe5‘‚¯±ºÐÀ† 4Ųé,2-.@eÅ3±¿?wÔ¢Š£ÁUš v)U^•p™• æ¦8"f}Bö4‘„tRGñ=5)—y`Ž’×~0Q©ÞʲÅ-™ÞBT%*#ˆŠEEÀDÑîGL±¥±¦ªT… ±Ä…K‰4ä’9"ã‘(éÄ‹©i”§—‰$~™’˜ð"!%E„~1ÇŒ!!%+ªJʯG"Q|P✈ÀÅ¥eAQYLd×Ñ’Žrcf ƒF¥ÒÁx2G(2ï?@o?ð‹f1½MÄnUBîQƒCž b¶)0ˆÌ‰âŠÎ’áðHÐà_bÙlø)›-ú½¡Ö ½©–E‹™Ã€aˆäD±Z¯bÙg0"ðÎ6‰$—!6Œ=îZ†àÌ—°p…Ÿ8:¢8ËþÁ YϤh‘Ò¤¤ÑQPêLä.5##á¿€y‹^ÉF»ÚZö !p”Ep=ƒÄˆš¢×˜–VÖ’Óƒß^Ø­À¶ ƒ¯!4U lx¸lÅ%<9׿’†ßT ß¿ðó„‰R¤+TmƒlߨÂ:ÑËZâ"Ì>SU $¨Ø¦@81•U¢„Œ"Ip2%øg†ëw Éx¥ÜhV<ˆùqiT ˜Ê*÷Ê¿`UDJe_ÔªºD*¾rT‘X™h2¤µ·˜ýݼ–¸\ö§á™*+ìá-£ü%±Ä‰]"¬0ÁRÆ’‚]›üWAÝ_sœ*g”į5–¸“ËEGï{„ë˜Â±Yd=OœÀÖ[3g 9EEž‹¯{¿C‚ˆò†2.´ò7¥ì8cVÆ„í¾ß4ÈxlbˆÝÂ*K}A™Ça%J¹`Í„ nŠë×ýOðÊ M‘y@;Y‚… (+¶£"ÀhäBa§]e« xŸLp©+ÿ/d ‘8‚Ì•¼š¶PÑȘ;È‹æ@kéΔº–à\ɱQÑ<~þ—oa ¾Q$ßLQQÑ!d(3FÒŽUº´ÊF•K«ð24QÂâ€DäðH(#%‹‰×$£Záw ,C)'Cž›ñ #b#/ÞFŽ¡àJÒ_[Ìĸ« =CTR#ÁŸ^'³hL<˜ž¿²(BØR c Ò„dðÉ&4µï,ý‚,¡,üŸ%„0@§–nAæñؤ2—F;Éæ°xP_ph.à§°"«2¬ù¸pŽKa±eÝ+!„ˆÆ‰M[%ŠEª¹#'~qŠÎOÁI˜ÐGÈîü/Søo:•€“ØŸ8Je>[Ê šuáèñì}kwÛF’è|Ö¯@è39KS"%'³ˆ•ŒÇq&ÞMbÛ™;{.DBÆ$À ’EÿývU?ÐO AQ²œ(gwlý¨®ª®®®®Ç«7/ÿï³wÜ÷‚–T¤«šÄëÕY—-¡ %ãUrN6co7PõµD¤‚žã½´)¶»ÙlAN,‰ë)d¥‘É™°±m­iU½â2'wXÊæ$×± ¢=$áibt…’1dx[Œ"|Ž6âîö .0ñ*D£¿‹2æÉ±äCË„›©Ù¢•´±ŽR&ó“['Ùö1n.†gŠ'ï‰þUsÙQþ‚!´×Dë œIQiåJŠ@‘`?'_öÂ*x,ñßbMõw7U%¢Úç¾§Dk%Þ6b––7ƒÃ*§q×ñ€eÎã"iÉù'É aXXµµ&ð7ª«ꄹÙÖd£Þ+âzèm ê4¶y~z*©þ ö ½þÙë—=}ÿ‚ ¤²vú·4Gµý-–}ùÊQû:èüAý€¡¯íyÏ« NVqS~ÐØsµŽfž£SÓx;:г*³(UÎPþÈeè’-Iºi<Æð–ZÄ9ûU!J³“Üv¤-Úá œQ¹û~±ÅÚ1$¡ôŽÁ¼’ÍâbÆ©Bþ0=îàÐ{Gfīx ‚ºðA…<Ë/”zê¢P,Ï£vt,°þ’uÌv/ûÁÑ£+J¢(úŽûÍŠi.æñ7™‘ê«Þõ/]½.r2ƒe:»ÁËŸ¾{<~DÁ£+6þu ªŸ„@Ù«oºo ¸·G˜8øG²ˆ¢ÒóÈŸø‰üDÝ©£èí»7/úG/øúÐl öô..ˆ¹Š*ôûg‘b ªÞÆ$¶^Ïèñ«ÜÍREã“#(S%ªáG±(ÇøY¤PãQÍ$l~¡%,“7/ØüÆâÑóæäXþi’%E:•Ï/âË’¹zù­¿ö¢eNÌÅï´HVjUŒ_‡Rv0Jècì`a8–fk8b‹ë³©¨­!£VTeƒ(cW#SZÍ&«ü›nD§éó¤çcú_&J„ÙŒCË¥¡aÃa-È׬HÀ ¦‹å™l9z*¿ö±V2G-èhnÎ#XF»bx‰*¥ììë$:Ùå—&hû¯¯÷‹ž9²ZH~!GÂø;‹ÓÙ‚8²ãŽÌu/CxÚ¢/½è­ÍF‹3ÁkSÝuÌE?–k;ªóùññY‘È î{ ÖÄÈ}:îØ`v¶εóQðîÕ·¯""Nˆ~1Òp°“áài“´_¥PM=çunˆþ9¾Ï/‚ø˜Ü•À8/=‚×Qñ´È¿©"M`Nêw¯|]Ú|Š„#5&ý]/B÷q¤ š'§ñôRÆïD¿„ÚÑ> ZÅiÃã!W“®ÝF@oŸÇâ@‚.¤í(úEœ"ú,°œ–CŒlùJ%6$ý¦ëdJŸ¢ŠwuÚ€>³ü7Rp=@ç¡dåLà—|˜&ø*£ÐU݃³Ÿ…M›Lâz n²î›uzþ úxÌ´Ø©Ðq‚]Ù„$¡ª>Ü×X½é‘÷®’u!Dž°€ô¡73w¨-áÑfQëxÉ) ÙÝgÌÑ× Æ eÖ :ÎÉÏä†2( X†ð…bïGùqXX$ޝx™Ê¢h¦˜Vj7B\ËíŽëÚ9ÃFâS©>ÉÕT<|!%ñ°çá+ŒÈñŒqÙy.gOA*UEKµ2†í!„ð&o= <®P÷º:ÏÓY,óù|‡Ðéyt• Ä£RŸ\ÂG½†ÜÞw¬tˆ¼é ¬Ìz½Öã* ½Á<ÊØ‰•g™ÏO-ãêQE{|¯âcrÆø¶ž/댿òNÊ&þÊ} =•)NèÖ¥ïÍÆÓBlàšÓÁdŸ)½È¢¡@ÙÎug…‹8iØ®-²¥ñTÛÝÝš¯4ØBs¿(ÑtÔFèŒö@Ž-“CÒlÅn±z`´´Ĺq„mÍ}­»{Fž[ówÃS±Þ9B{ª`‹°§¬°†½$¨>6qĺî Wv×,â`–žœ$﯑ο2hM1ÌÁpºêbѰ]ð! Ó…9`Ï3¨Ã¢\ÏãÅñ,¶j×â@kÜ̴Ɔ$>Apåºóp 0Ë!›Kòe]ט£&¬ƒÛ(e±/ñN;›Ü†ý™^]RÏ~N>$SZ³•ã—õËDBŒÍ^sË·šm¡¹„lÚUüž²NüÇ šÖ·O FDô!ë&ynvN> }¥oãK$…®˜Àäç!"T2„‰e4Ë'l=uCÿ”ÿˆœC{¼uêl°éXœm }ûB¬ ,æji¿¶Ï$ ¢è`öjr~Ò†ßMVèYÑ—q‹à¨ìc‘~ñq^¬ðù]ªR§É‡´\y¼­ #2vb ®#.óp›íï joó ÖX7\gÜQ-ñu  ­Ç­˜ï?gy^b&UvY Πó¤,¢Bü»¬0z?„ŽZºF…šÁIá!nnSÞ(Lä]å"~¸l$_bºêvbE›ñc öÛ„BfÖG8û‰7’2 Žó|žÄ™³@Šã‰Žÿüúå “Yr¹¸ô®1PJ†M(¢ÊÛK½ëÞ÷œoÄTa¡ªð§°çÈÏó:Xq^‡÷—õÅL` Š$ ­¨ÆÌr-îÎ[˜ËîN/K,IksŒ²À]aÞoì%®Ósp ) £ó‹ž{|…‹\.’ 6zɱ-öOBÆMV,Ð8'•ºRé›\ ÁÂÀ[VûäÜûÉ0éV oÏmά/´Ä³ám"è4ôbû‚ǽu¢Xm7I  NýÀõçŽ0ÑbùÞX2@ƒõ‚hõaÕÞ5û`‘Îå¹S+xí­œ|Ç„wV…êºèVEkz„ÝCÌÀ–.VXÛ7d+À ´ ‹ÿ¯àötÛcb´ÖsOwÏ«|WíEÈ÷>«-"U…»kO¾ASE:ÁiNÝ WÅÚž1—zÉ d•»k[lîÓ¨"ú÷]UI6£ÄöPÝX›EQï¯:ˆÀND¸s-6&aݰg81L'‡ˆe´ßÀkOx¼(NÝ"¼Ý‘…v"ä ù;K{EËaÀ¿‹ô4Íây奣fØ ‚Žð «âŸ¡š=³£åÚòKÅ.¿>²ý@ö 1¼½ ­zÈ'Ö!2µou‡3Ûæ-Xåß›¼+œ&€ÃK¸÷IrFÖÉ”n¶¬aLoÖlÜ-x³%wêüÙįr•‰Œº «61+5ù±¬Q¦ÆâD+ÃwŒ„¡Ý—z[j–Vî´¥†i/tç*¦ylìÈC{¢áöÔÍ»@®à0ˆ"æû_äߨŽaÜŠZèzDË,ÉUƒÔù妎ƃ9äºë×Ážõ,PNB»ývÓ¨¤ÜýŒfÂú6ÉÀ~®Ä`økIG¡­¬Q¦“‚hLõäÊÊ•À° KŽ 1¦¿8,õ‚Åõ´¢“8¯‹„¢G $óârqœÏ?2Xù& ˆxKpm†û˜cQ{‘®)=e —Í*©ÎMŽ ÖÂoÂÔÏfX!&žóÂYµògö Ƈy©]JγÙ`Q>3·]8"ü¢Äc¹V\ËRmU—\ó™µv÷É0ZKé(@ö ¡ÃR3Žù9Á8ÔThÀ ®Œ—g“¥elыؿãó¨²\U´Ïã"ø@$ðð+×ÊuÄx¯[Ÿ´g‘± ²Î’>¸‚„ëÌ•÷”Ú•íì}áýþÔywEÛ0œ TÚ†xàð¨ùõr™äë So»3í*Bâ ÷NÑÆçNj)®HM¿îê•;W¿tX4hþK'ú¥óèŠ6=Šïãë_:×KQE]çµM¡z¿:xÇ^®1ˆÊtËWõ+,ÀarÊ39–Úu]Eñ¥l,‘ gRxÆS7Ô—Gd/@ƵD+4ìÔ"à©6™ØFº’ÛêE„a |ÃìÕß Ž“‡i[x¯×ÂK¶}2_.Ò2l,yjŽl囜Œ¯±ëÇ¢/ÝÚ‰x7»G;5tmuWèg!]Zq®}™m·5Û꬚ž¯5È <sý×Û-æú;^{'jø5ìrpEÊÂELp/æû+’¾«Ÿ+r¬âÓñŽëQ‰"ºbŸ’¶hè8ìPÓdçëx8ÚºK~ÿºù”‚u´­Ç·,©?$’V'*QÖ+¢uq˜k¥Ê¼Lt"p·¾%}‚NP†¿CJ´áW€¯sø5‡°t&.‡&ð@®ô8/)ŸùÂ!ã›d&—gôþ`+æŠH67r掠‹QÅËtÀtE\s8nÈr¨øÒkLBéËU?hxÏÓÕþ[)€Û—lÝ®_ƒÊל®úDéNå¹n’M5ÔÒ× ®ã«Î[Î4žv­ý`dÑÖ¥;›à}cÕÛrƒi\Ý]Jîôâæ4ê†@çS.~Zu‹ÚöÞô¶Q¤Ü¸9ŽùNŒµŒËPOM×þQ“ Ê‹Bmmë xRÀ϶D݃VÔe覆€‰[âcqXb%!¨ÏSsÈÒ¥,É ä(NŠ^MœÙ*]]*…p\y —2°ñ#À—NÕ7ö›”_°èÏ€ú:Ù¤%”GŸAðŽßê…[NÙ,ðW"«*TDÁQ•ý`ï¯DŽýœ‰âXàÍ ¡‡ëdãÖ$ï^0'ä§û+}õþkÏ©°!ýÿêëZ!ÃÒgÈ,¤¨M·É‘B½ä’C¸Ûeê÷¥¡“ŒR$ɯIû ÄJ'K‹þ”hîO­Xu%‹åêÒDƒÊzJ4£rUŠ5.ŠøuÅŒr<´…Èò;î9”î ÈN®ó,.×U躨Ðõ"A´ÄƒWÉŽOð|z;Û —мÆAI¶4_¨”&¿BMC¥õÑÞX? X=^7P¾9(í–1sЕeÚ°Œˆ½°gïÃ.,ÂYôþÇ‹wa3]J°Ü ¢~õ¼‹­9©›îJlˆ <‰ˆiã#B;²@»s1k¯Ý›à¦Ä¾XýŠqPƒóQ £&x=†¥iĪ …ÙPOþ6 õkyͺ\k»™9ÍqBq%ÐRj%Š4.—¸†`ªW;ç A…€øóE÷|HÔ빟ñé†Ú”mv%82ÊuQlÍɶÔvVÄ@ÜeÖí2m¬¡>Ö²-îf£š1ëöÁjµƒhC¨½IMÝ*‚Œ¾d9òÑ»fÍ+!Vêæ¢›Ïo|ÚV ¾ÜLÆIxxuM¬þ@5½ðjQD§äТUþ>Éú9Ûãÿ-Û˨«?™=š§‹t%šâ†_Âæ¬Xårž®v#êg:,åøq<À¶]a&pÆý@ü€SBõø`0;I{Íž@0b)ü\m/»_Ü?îOÌ…“eöÛÄuâN¿sLþÚ»ØH…†™"²%`}Úü}´ý‘Óán/ñ•ÿù›â@Lj®1 #*ž¼°À‘ÜÏb0Ž´_á^Ũ‰¦˜¾þ•ò1|¼âÜ>£îô³“ËŠÞ›ÑCëQÈ–  Íf“ü¤û}\žõ¬Ï†ì¨¹8KÑlÈ\Òl:_ÏxX Z¹‹ô›Â,˜ÆKP l|ÀÛFçC«ÏI „fBäTé@<ÃÚ¨¨ºöxA%¶ ¨|ˆè=ÿÜJXÇ›”¬ðö #­’ùåv¸T{óJÈFŸÕõ¥-v|ϖ³–rH Îé§~½cÕ`´1U4õ%Í@ÖôN*‚Ô^;²¡EVƒê¦ˆÎ­Í—"Ÿ–‰TòĬ08ÒÇ ¡OTº‚ÕÂg³î«:5%Jû °K 'R“,ª`ª'-kàHX¶5Jàôšß}ìKôD?“`ÀÚ«8»OiAÖ0â?‰ž¶ç\u7l¡þ ÿ¹ ”6/Ö½¦fBÉZž¦CÆ+«è@ž”p-»g±k³œb)6ìfÑËeUFÁk{ÕdÞ^qFäè1w^¿íÝqs¢Ý Âêh[i?D‘O™C ÝŽÀÕžx³UõS£ Ó*ÂÒ ú¾2"•I¿UwÁÊ‚FÎTŠ6÷«à+‹_  ÍæyÎK9m2˧¦ÒwkìgQŸ„f¶´P´¿Ód… )%­fÝêBÛŽìfÕªR§ÝNϹ;i‘§Ìy¯ŒX~•üRñˆ(a6j¸õU -6SVNð³°\UB?Ö¶(&êÉÈñ«Z ª}ÄŠ¨ð°ÅÆbLÐÎáÊù‰m&~073&§^½%ÓFRcÉÈo0n$¹ùÐßñÝgˆî²Ùäov½†¡u; öCÚ!Üä`á0ê÷@Ý~äðŽBG‡‘Ñc¤B¬n•šãȵmí@·Úº¡3äDzuío ÷NÛú>­HmlOÁ˜MCpnµŒ0òaäaCá/N -–%Œ$pa^‚öšAZ¢Ä^5”Z"6¸¡+ÝC©¬‘"¢^³éÆ×(Qp˜ Â?†\‡~†Æ_ÇiF•Ú“B<¤6ë~¦º†µÛH릀|£ámߨ >GÞuŽü¦ Þý£ÊA€e:K§™<õ~åܤüÌ.[t™@DBMÉù~¯šŒD“‘æ@ŽÝð]Ü-’ÕÓ¼yÊ›‚pààÚaF«;Ñ©Êùlµj£ñ‹É*é מŽÒF_&q¡¹ÙÔ ‹³‰lOÅc•*`ªHJ½Ž¨Çõ›vä0í´»}íí´¹{Í\|°9öÕ êï`M”b5«º Þ,Î]ôÉÿ0““ž!eƒ$Y ÌÕV…`80­PÊvrY ¤ÎÅ7…á öÌ‹9]É™G0LéÍÎ@2&™ošè‚.u‘G¥€ÌŠ5ˆÖeR”¶TcÑY2Ÿç¦îÒß±_Ø:Ó˜ny'+±ßʼnÚX eÈz (§™Ÿ¶qžúM ¾÷'?Ý"ʹEãBླྀßlù–$ݾÈ7°~EWŃnïE±­¤¦ôtârÉ~ ¬cŠÛã¸L§h3ÐáÔ¡ï¼DSž©Ftþ_Cù?ÂàóÏE{ñN ÿpŸ*Ÿ2µõrÞ}êcÀª[ýüîûWo^þßgï^¾ú !’ BPÜO€üÝ ¡} …½Ûb=&eEj,å|+ýxoØò„ƒ&•ÒCÄûäs6ƒZ¿!¤±Üš@–ò¥ø°ˆ¼¬QËeA›»Z̵ɲ Öº?ªn‚+&k³#¨ß’ Í' ×ó»Ö›ç†áœwÚi~š¥¿‚g_¥HÒx^%Ì¥æ˜Ø6ì!q;^2óY—WŠC‹×Ô‚V8Þ:HDRÍg&Hôç ¸“šM”¬¶8¦-p3h—ôõÔGKÒ2úkˆ6ÆÒÖá9VMbÉu;ti5'f3Qu7À|ËÔKfZ$±ú¡¦ í%<žŸbn›Í×]è|±Lç–ç`jK3‚‡L1Öisòf2šªìNà×§Ÿaß@?‹³Óä3ô4Ãê4B9ˆ3¨áˆ³ÏlK±C(~¥£·[v[h•oŒÄb¥oX–{6à®Í(w¥8œC~Öê7üXöþ¦g×džÓ2Bûa ý¾£çY³»K+ÒÒéŽzÕ? ¢ˆ ­ÿ"«Ìóxfì*!ø‚èœ"aÙ‘e¾±««¶Äp|´GâÉŒàF9çÄAqz2Ó ¼<»u°WËj{ákC‹øµÌ¬ODƒw!’Ò7';Ü5»†þj¦´e‘Ÿ§G$žNÁ¡\QÈ¥ÙInq&ms˜ïZÓ{KP· :Ô¤ö6ê¡B åýi¤u<¨ÌdFÕ)©‰Ò÷ZRªKYFïí4Aðeè(õ X‚Æ»Q:s°º´sÏöt6{'¹§láZ°‰ŽVÖDá=`¬ÙX*CT|håIWSMÙþZ¹.ÁuPг ÃñƒtÛVílöd™Ä`ý&§òdžžèïvWö]©”ææ.ܘ´";,Ô1ù@à,í¡ÃÑæ"m…+³öê+õ!˜Ê– ¶,Ì]§~ñ·"Ÿ?cwödð–éEÊŸŠ}ÃQ½{{ *Å.p2Ñ™•y7Ú\v¦ÜPrÏ(pŸkÁÅ««»ÙlÌ 6re‚©ðòŸU°ogßéV¿ƒ?ÚîÂÉ6ØYŠÅyÓRÔw°κÝ"[;]¤m—ÛÞ˜2&o‡û‘GÎVr)âÛA9KãÌ3dK‡H1&ưŚ”ÎÚìg"o•½aÝN^GÚÔy“5‚r›ìN ³€–’¤ ²Hg³yr*ªŸm¦ÊÅ×(ú{\&==ëÎ “NŠ5BÏ.Øäý€…{DF!G*ça--Þ“Öe"ÁlåkªÏ«­vöŒZ½ á‚õuºÙßüeR¤ñ<ý.'ZdŸóÀØ‹à­ÔD¿ø/–óD#–1ÁŽúêCÀ0i© 4…@®áUæ´˜ûÌ:“½¶]k†­¡8«Å ñªCщ:k×%5ÏW­WpÅû [³ëQz£õÀ¬HY—ka1ÍCÑ´2=Üç¨f=ýºÅŽ›×Z¶ª¥¬²¯ükÜlRŠ>,æ›(_¤›½ªˆY¡SB“Ìr‚*Òž´ñh ž>}ü¯Øyú Y¥:ì {úªNVvØùùÝwÿÚùæë§(¿&Ã?eBÿkr¸ƒ6E°Kz¯‚·"ðé.oµót—u…ÙlXÔ„¡çnS_oi›a$p;ÔŠp±ŸGU %wÝõ–I1ºMRÂ|­_ó¿<Ý?IßGüûH|]è8.²xÊ .¾èrÎ{Ÿréž.Q=ì :ˆLúAB5ûÁü6ª¾ñ¿•n[Ï“/¦;e‹ÿüö-½|³>çÌò–ôÝ‘V¾]/—UFv²k.%ŠD_W¢CáR&Z[p%Ý¡`È$AO˜1çê²È§,Ùj9Ûá&á¾F…’‘ð Þc" òé{ÌIÛu4ù¤zUã6&j’ž'ÝH„KOÇM߃Q¿7€Ó¾ÑÁ })@hɜà ꟫߭YaŒµL˜¹þ_³,©ËVW(Û¸X©mÛuÇ'DQiµl½Ç–V­[³h½éFkö\è6W×´¤úulñ {øo+瞤§ëyp[:@Ãù¿w°7RÏÿÑÞþ“‡óÿþŸÿ2³l¢ÈýWˆJ 7¨:\š:ð qœûнMÕßgÿ?êûøÅÁhÿaÿß÷ýÿ-a–†mîŸ3e×C¯¦Ímê÷8Ÿ[ÚÚ¦R¤9IÁ qàŽOÂ=€v‹Ã £‘5vGø»’Þw3 VÁ”H&1xŸ÷w*bI÷¢¹Å»‘ /ÅC÷Xo±«T½³õzîihéîmN¡ÄNKîªP$‡W­•Ôª‡&³‰„YåM]­è¡“¦¯µ…²ÖPL¼ÈµÒ¦ Ã<‘+x¦—‚ˆúÕe¼B|©ß0C ¤Ê Ãì ûÆøú§¤E„™EÃñXè<#þxIÿJc¸4X™‘™Ìò¯gdôwùû$ÓË.éúg<§‘×ùºÒ]ˆ6p °Q>^ëmùÿzÅÊ}p™¸`ú)‡téä²N›$³dö=µfŽv×cÅßȵó ~ÑóPÑÆÂ/]…YÔ\³åš‹¾R33bŠ2ÞšŒìÏ%&“²DõU_‰¼ÔàgiùÌ ƒ5…%Â# Ô:©©’$?%Ÿc[}dMŒÓ ŽècñlÌãèØ¥{îŽÎ$W2¨Y:¯U%l`tVÙ’üÔº<5_þƒ¸[ùÿdoßÿöÿOAþ#³l$ÿ±çÎŽg9?¡e‹˜åù±1&uÜ”ÄPxMŸ•tá3V¤AèÈëü{žÏ“8{ ×ý›]óÙë—ÆšXÚˆ×Gž¬òÓÓy2Y {ùäê;¯4Ëæu–‚DdCDJðT‚d‡x­ÿó³t>#À8_YÜ/زꭱ'Ô¹^HëfEO!Šà/¿iÑ4S9é"í{|ŒýaœáÁõ4ÎHŒ÷iȈ…¯[ߥk^ÉÙüý€§´ìWDÿAFrÑž€#Ö$/ÒÓ4‹ç[ƒ¢~ìê ÆÆüéÞ}¢‹&òNh)ïRN;×EòÕØ5ÖX“œ¦[›1Šè‘²äWr¯ÿ¿aìòý Ì ùOWóËîˆL›’©>©zú?½¸v( G;YtÒƒ6*q”o£šoû÷š¨w@T1Ù>Ÿ¬‰Ì€Rüß}’/ôÍÔo×|Ô²ý¾c«k…Ëin˜‚  8IpWñRÇί iýÏ´€hÉèÙjEÄûz™ô{è¾°9ÎÁ¦="†æ›Å=¹ÏíJ¬>Í‚)ž¹xþ›‰—ç•Õ…½ÇcûÜ–•˜I¹±G%¢r5 Åò3ë[U£©^lÏü…ü’{€¿=FèN’˜'ϼNø‡[ámÞÿ“A?a¶ä-]ëï#rçÛ×ý¿FÃÿ{ÿ{‰Ìòxeƒ; Ô[ªn@d뤠6¶(ÉÎûTêý‘ühü}C»:¦YºÂT)ò#àßHx ’Ÿ~þÆìwúÏòÐø~Tå¬Ö7ÈâÓ~YŽùˆº“ûJ¬q?ayÁ"ö¨ð­nX|Y­ž’ÅSýÄÈ9ÏEËÓ+Ö=íduûœ8Ìd3!DSÇË”÷[‚Ï0àZjŽá o°‡Í€SjëÈ9ýˆˆ+ëÅü %KÀ`¬–àVˆ}éÃówù:ƒÇøƒ½LAE³8LÊËÅq>ïÒ±zŽ8:cVà„Y ø8>0سã€^DãŠí@ãšòÿ@© æX‚ôgLáŽØ²nx„4ÇëJ:&”üœ½Ï­¸ÎnX@ŽžXË"à_Q›mßeþö[À…Æ‘u­,Uû#W6ö—* ˆ4I¿rù9Ï%&ëÉŒÈïiõŠaPÓ‹€|¹ƒZeDÃôþÞȱ¤qÍ <×¼-ÿ¢ãÙᑞ^ˆ‰Ý°™¿ÉáF.´IÖ'ý@ôUœ`š4lƒ¤áÇA’­´­óç‹î?^¼ ^ÿü.xõ¼DÞöª4 Ôæó›¦-6£½=(ÉKº‡ºár òCî ýí‰oȹE?æÓ÷üWrŒ@rIA'ŒØŸ=WñfõvÎ&¤Wpz€uùo~¹Åƒ¹è!,úõ«·òª·±æÇìõv¶²â†õ›Vy«üöÅ/Þ½Øö:Ù¨w´Òƒ¦•îU+>¬i¼$bU ÜÊêEpF7óÔ®ä¨MÂ;ÁÏž[ dâN}IWÇ!'ëpÇë¶pœÈöZ–2vmº¨L’ &ÛÞñ¼û–Õm¢¤9‚ô$X£ÂHK,)¨dï64KÌIžO ÃKuA@âPãŒß}Vœ®„ /¨~¾¥=Á¯¸êNædÕ€aÏ& hFng«ä4á¸Â±JhGÃ=š}U2ÐTÍb°\ 1–ôB¬yÌþŠ©“J:Ï6ØZû<\[^V“¿ÅÉeœÙõ(àf²jžpØ^AJÂ&:Dj‰*ÕA­2š)9êoBÖÄÍ.w·êÓ”hÁ¨@çòpÑV"+VdÞ)oLµ¶iíkÇ[þ>MJkr•8Õ¶‚ü$x®5µÌ x†Œ˜Ÿ¬c- ?µ§=pRJá9}@‡zíŸÿÄÈrR¯G“á kè«Ìl…Ù¤\(L¦¼s¸ˆ+ âFÌšø¢Ÿ&ð .Í4•Î.üƪ^IqUsždD/¾ ß"Bey›çÉwä÷(‚ÿý;ùˆêK5«ÔßÞç Ïh"úÉeÏôš§»êE† ALÜ컆¬\ –X'/¡©÷jƒY8ƒ(«w7I–SÛ]rQ\ÄÅ +ö‘kØq:OW—=!i¯žìTÑŠ„¾$È¥2„!WC[î6ß½b&Ý[®Š$^4î_O¢ºe#w1}Nî×Éãç„· ¢;õ!þƒüºÛÓcïñIvŠ)5‡£}gãwEœ•'IñøKË ÇeòÅ9]¹…üu‡‹é  qÒoÆÔz óy™xœ&"¼'823™cc8eÝ ” BpfçAs}þ˜’ÞÃæ£2MeøcÔͯ0 €æ ìš[e@1yåâk›ÕàÄö›Ìì˜ûn…ZSßèÊþ¼bèT*‰‹ÓßGÄãTc㣈¾ÕBQJýeźҪ¹{±Ø¦Íû‹nkyÂâfù32­Œ?‘­ÈzP“&´ çäyRħ‰ñ&Óû(•lLýuIå9Öˆ±ãÚ[¹4FvhÂ`!’­>°KC `¸ZäÓ÷ÚÑ.}!ô­.ÈR“x>Ï/ºòšõ‡-Z±ÿ°µôìS¹|kù:¬õHš‚'4õÑY§µR4Ó®ýüM4Ê.ˆ˜H—sÆÝê=P§ä$ÏTEMûf§§AMƃ¢¸8(Õ@ÿö\óš;À|u‘;!'ß|!‡a|!qÈGÈÉ`u®¾V–¬ÓiUvÚøQ–»çÈÚ³‚Ö¢$ N>Ρ¯ÄÎe½j Ü|Q€Ç*[C¯n#­Û(l·2"°1<ñ†<{ØîZM±hËöøëÞa ô¶ö€ÝËpÓÁýeo xߨêÑàÑ.É ã°r9È–³Aè刣j0³d: ÉžÏUê˜Ã•ÑŽ>C˜z sßDZrÎàøÒ©`J&p>t÷êºG½Od£÷ŽvÕ×}‚¢èG|;ú)_ýO²zÆçfÝz.¿IÍÿožŸž&Å–3@5Åÿî ¿Ôó?}ùÅCüï½÷ÿû™¥}(Ú¯)ø—¶ª;ª °‡Qv Ì,_£GÿÅ–.Š~s%Œ²|­ÄýÈÚ¸a6;;µÖNKšcnëØ]6E;Ôÿ¹ü¿«ªR[<äÿþÞ#ÿ÷ù¿ï¿ü¯ £màþý£^¿Ì}娚֟*<¾9Àe«}žOª ÇqQÓÐè²þ‡1 Éj»)`êõ?¢ùù_¾xrð ÿÝwýïµ`– ô¿ª³ücÕ¼ j™9•Ì0ö1Ý*8R*¬`F2‰yPvÙý ¼ŒÊÏZ³´ lçÎ!céÄ"†v¹\—gnæ›°l²E?øË_ ¨ ¶­9»l[' ܶf͸¨Cn ”Ö!²¦;ižùz9)§D§é àG†¡Átžg‰–ë'.Ód>sO‘|Xñt5aY,)kˆ«LE5 ðÖÙ2þb“AZNâoºÏ ¸uOÍLŠ”Ã6Pï‹5ü>.ÏzÁ7ìÃ2_‘˜ ¡®à7Dí¢ õ‚Ï?>ƒßøOãã2 ¶ž‘³J¤ö‘GŽ5õÂUíMÛ…KÝöMÙ÷ô«íAßLΩ&D æLòl¢&•£ï+¢ÆÌ2õÖ[1o2cu{µ_¼Ûñ<¼d¥W,%l„Ì_VŽòÅÖÊ Ø…m9äÅÕ2¼gÊî|4™ï|ŽYo@Ü‘ÍC¤f>M!‰.Ußi–g:XhAW+L`È <-)ONvŒÔ_ ª4’)C-GŽ­î0U“Ždä˜ðM ¨b@N`²ãòìqò!-1üE„J•ˆŒ­"ëêÚD‘ôzc,Ï| _³œ`J3x*:˜ßÏBïrO°«¨4î8;džÆè6ml>óšoFÝHŒ' Ç–þ౿Üt|¸íÇÓ˜¸.Ò<­x ”aÇݰÊÝ–ÎxÎ6wÒÇ ‰ÜxÉRªš˞[Õà™›Éå/‘ëÝUã4}‘6…¤ÔѬJaÇpl4®IìS£F˜$´ç,¼íYÀ4â]4¼Ox¿ktjfìP!C‚&¸™éIBÅLµDVQ’+«”ÃñUœ[Vÿ;Eób½ZC1ÈR4_—äÌpò/iŠe DËŠ‘G1 ûæ<Ñàfi ¦šõ,Í=ðkÁª2"˜NħÝÆ_J4!‹¥2‡‘I~âDk~àÔKê·„!u’mâ'^Mæ Tûm@P¼ °¢‡¬³†´)n EÚ,[ÅæÆ›dM(šÏ!¶3ÛCÊ·… e’mâ¥y½^eUpœÊèÔ¬øXþZ®,!Í Sò4s'E¾¨IGƒ“þXÙ;®ÀäAtJa¯ãA;Ô;G«mÕ;»ÉʾCÝCm8änÀ¨ôlò¢Æ+ [hÌœÞà& 6`m¸ˆX³*Ñ6%4ÅŒXx¼ÓþÆLgÁûäÒ™‘·9Ä8ó:?j¶Ô#•}‰<¿âéÌ÷ÅŸ/ºµN~V‹e³±B#0q‹k¯.VIÿµõQPFø¢y¹Éb¹º´5²-Ѻ7\ ­‹…j×߇üŒ¿Ë÷–D\nå¨!ÿãÞýýg4ކï?÷ýý‡e°á¡Ž<i#X’ø—ɪKdxŸÊv¥Ì8ϼF>C¾’òrpØ®¡2@º8^' ÃÖ4ò1¡k+«w\² Òî½4¥9- â?^.ç)Íïµûï2—ä1W¦bcìq¸ú° åQiÆ:ÚÖî÷ºÂªlØ.°´óu"‘²rs¼:{?à [ µÉMyËfÇYžõ9óõŠ»nÓ’c&·¨vàJ  Â:Ÿ•: ÄðîµeÜsœÓ?Ùîém“ª4 "=ƒx¦Søý;þs½ƒRs¶|”áqårâ®øzŽÅSi) snä%f(ûݰ ÁÁá×Aõµç\5G;ö¥öÞH ,^ºÝØé×[[<Þºrú©g¿À•òšé¿½ì๺íD_”ìMïûÿ‹î:§D é½ñ≺f—Ÿ‡ô¹9ƒh³•šBNÑÚØ0¤cFœ"Ú‡šòäT]‘K?¤–Ëœ«tJÆ?‹íl…[^)««]osX…iœ!‹&1np’A°a‡i;œ(éÉ8BhóP:]EÁÎ(£¡Á¨¦ ʯÎP‡\VØÈ/5e¯íÿ‰ˆ)Îñ‰.ý‘E l;(tÚÆ8D6DJ"·¶§Y\\j äÓU²zÌòîô6<,I %çº-=,m·vX³_»D¾H›¹ç½jreŸ®“ ØUµ.#ÂÌ®2+´7²;¤=/ U¶ÀƒŒŒÝÇ‘{Ûlìlè3"ÅçpÎfé¼g5„IØ  g}¢ D -†<±@›É@Ž È{rïŸO–Õø¡ÕÚÕ×´¶ø²½‘ýùfØŽ5"ªòÔ¯OÏ‚H*0o ý£(­ƒÇ_ƒá,™ÏsõuæÓ@~œM„G[~Ò} È÷Å>ÕÀ*lÔc>>΋äÉ•qËž,˜ñŸfªíóÄä@x‚XrÎp6í˜nhZv…mûèŠåë ñn˜¼î³¹gØaëô<yN”•cö\ºá‹Ä̦\_Òªiå*WÚjZÑúÝðø2 {^%«js×­¯JPÁVÙò½(Bû|U'«üâlX}…¶9¬4×;zH?Ç”(óbÆyZbE q¶dè ÆñIZícòå†x/¨d¹]ª’¾ÉEþ3ܲp¿4”Å ï±l¦œÓA}*µSA¦©|8[Sߘ$H1 zϰ®°nÛúÛ®kÒõtÕôƒ×S³€Ó$ƒ „ ÔÍ,°¢6ïÍO¿Ð{GQ¦cÒ ò´-‹C)í$ý•E¦yn ¹SÖ0t†C› Ëý=Ù2µI’‹ΞX\¿Ê9Ïpó›Íb¤7‚ TˆØÅ"r¸ùu1)U?ÉóЯ#‘„c-nÔ¯£¢g¡]E×õƒŠp})1´Î=MJ=ãÞ%}¶Â~ Ç1~Î,ºþ§Ãibj=}éY,j°‘DeLBÅô>êL"SŽMÀ£4j›0s™—·º,Xî±€ã†+YßîB~ö[Çú†Ë€{Çm®ãûϾõY^Ån´š‹ì6×Âê¤{¬†Âr³õØN«-/èÕëw/_ýôÖgEüæx³=¯¦g·ºkž½{þ½×¾Hn¶q|›Ö y`eÞ Ò_)5îÈ¢E'–MáGôð±ë/­L-Ö¬iµr›®íõS5¶®wˆ¥¼/ªf£`êæÏ0âS?І¶0A…mÆê„v+š4©Þ£u#™M(<ÀP`…øÉÊ+ :ÉO2m ^9%<!a·nºž7)2dûŽn Û_éiÎ?’90½Q 'zxÂçëbšlJ>èmZÞ ¤å6A-“Ó…í•÷&€²1·ŠÑÜÈp†ÒŸþ^/öÕ,"l«Íh¢¨p ™]&– ê£ÚQô'7¢xŠú/»ðÈ1·­@[1PÒ]²ä˜DzÖì¬q­–¤]Â\Þ†Œ›ÀÕ—;à@*ˆO!¶¨Ù‘ .xëòŸÔb¼¥g^rñòj¾àÐsʪZXS¾z½\ãŠØ÷º>!«`7ä]\÷`m;%§ÉØM»ÝÁ_z»jRÜÏ´GUöÄ [ÜⱫ’G*M©´ä?¦Ér¼ÂJ7B µ¶à B·´šU*…ÊL¹0uà œl\ƒ]U©u£X±ù-òYzrTº¾=7¦FÒll‚·Ö4(Ò%—ÿ!{ÿu`B¶ì€Úgg핽B9DמÐÍÏ£°ñ¡Zäw:…½ßqª#Íÿ‡g?ÙªP“ÿÏhϨÿ°ðPÿáÞûÿ¼e̲ïª&ç1_t¾òJ¶ÃG³ù É@6æªÏJ‡I—šÀéÕA¾M‚HºÒ†-½Ü†íjÅ@P€ª% ›]:¢½J,#ïÝ´ñÍæËüÞy+ e!°9qzŠÒ<†”VÝ- «Å«A :?χ>8饀¦ Oç°G˜HDï‘ò<A7‡¾êÙµõ„À û:ji1Ïã9ÇG½ñÏA·zÍ«êÄ@tJiÉÖ§ ®®¥mc^|`ýI›õ™{¾~iØÞ¾ªžk/N¬ k‘±^~ó¼rጠÔR rË¹Ñ âWd#ßA7W›Ù:S•ù"™€õó#å“ã¸h¸DW`V{R¶.:†sjÍù§Ý ÇÉÄ]€ÅÅÂ-H~#Víf`­ýù×ÁwÂÃ6AÛó9­oÂËÌ&\¶0ˬD]íø©íXß²²–ì_P¿‡u3ÿA1Kù;AªåÆhm¤Ý'Ë$Ͳ²¥x¹‘¼4„Š[f:Ï ä¦¤ ß­ì”gö–£R/Y*róÍOïX뢀²H¸ÿ·)Lèl{¿çÃÂŽQnMlg¾ÆµOF½­‚3mE4y¯Þw®¶’Å{nGºØ¶¤1wÞFZ2¾cY#æõרx? Zß‘”‘ ÛXÆXÇ<ÄÇoMÉØÖ|u+÷•0žÀÈ·£ùbá¶dçöÛ’¤16—F£í»õ}–)Ë0u—wA1kƒd1 ÛÜÕr¡7¢¦±<7 ]+lWyNv`s¼n£ØA9¸Óà?y¡A¤ ²¶½[ú*4€\‰ôôòø—nkÇ4ðh¿/Ñw<+>-/Ë pO…"U ‡Ë´Ãf¨RÏvòß4g}b©w›I7^hûõÍò)&¸F ½&Ö}¤˜ü#ÀØë%Xø>#($Ò°7GúWúÜߦʖ­Ìqå1ö¼5289j®rÌÄ\HJB-ФÁÜxKÀ°ö$ÌèØ”¾‚U ½¢yÍtúÇ|-Õyð¼ Ït®ähNŠDi7‰W+ò“O6•*'‘Þµ{t²žÏñÖBdÕ‡±ÄX(":i ÂR7ÞNÝ#rû¨Iƽؓ[%>pŒ\ߨ5]ÒÿDž†­&lÒÿ†û{ºþ7üâÉ“‡ú¯Sÿ[XKdB·Š- £”f‹*^àÐ/—;ÒžÞ[STL «¯Ø‰Tk¸Òg—ÛvÁõ•«x,vªEçilÈÀ*!pwÂYÓ:fy¾¬R×Mù9ŽÁ÷œ=Õ‹Üap’%·×v¥ÎB@Ù/’“¤HÔ8½›ÈY~·:‚MZåçä´Hg–q‘¡©ƒ3s7Ü ðéº(@¸¯¡ðãõŽvDÑÄl¡Y»¡ñ oˆuK†¨/Ž­*Ü‹†J%ÖÔ<2XJ`cø÷üXœ0Òù Uñ ¢„öà8Ÿ]Šp":Œ¯I)ó[¡¥ŽFx‚yG:ãõꌦš"§`¥Òóe\í‡Ð§GÊíNo"NBÎÄø)°“Er?J³t…% +I ·Šß£ªÅƒd(ÛIá„ð&hÊ祑Tß,þ£¯P:x~^¥ó(zY™‰ßò8–ä¢\5”#¤© 2šêÒØôÈL¯¥ÿ‡‘´…yüŒ„g¹Â±8]A¡rÈpOŠÏƒ5¡>ÆD ”Y¤jø=ä¹.òb>ðcAæ)•£°êø€Œ~ÆËT¤t Å5í}J86?1Ò™YÙA+žÈd€ŒòMÑôáÁB}u1gù"Qå+ˆ8ÚûBüDº6ŽQ·‘è|+‘‘{ÞÛŽÎì<Ë¡Ò/,IzŒööðý[ͶH9Ù:3^ëQ~Ël†ٗþåÖp³§áFÀÝp‹H"µle>X„.[F#æ*ÛC_<7Ç£moB*/éÌ¿ÑÞL.U,Ò±ƒð_Ÿ]$ð:©V±’V…GþÅÉÉe-éå‘4‰ÈHçòY%œtþDÚÚ²ÌbÞ¥*Üêe›»3£µ›æ3 6Ðg¯VMWWþ_o_ýDK¢Û¨ÎW-ñ(îH,œ|ˆÁÓc§ÒA>Ïó÷iB›ð¹zn¨ãÙ,…“:ž{/ Õ¿÷îõä_“¼yöúÅäù/_üôŽN;lµF 39ŸÏÓDH@ëaX9‡¼RbÕBp8Kƒ7D#‰¢ Ÿ¿©NA¨¢-S¿êqDWöö~üû«&?ïÅ›UªC:ùäóòLáÌÕ´üöF%9Á¶#Zãyïh4ÆÓË–C '´ããïéV®P☻~CL‘'¶sZ“ÿÝåã)[†ýx..ÇtÛ>¦¿ CD̘ËVWwöõ8tãÄ äÈõm–/â^5—¾3¦ùBicÕûÊ„ÜÈÈ WÄÏ׌ýË>®„bݲú—º^22ÑÿÉÇ$º/òPG鎗d$úîc¶Óǃr9OWÝÎ/Y§7(ó‚_äçÁQ%ø‡ ô¾þåà‚ûî ¸R“¤‡iùHͺV#Þê?¹¾b4:T)ô’åp÷+F Ž¥±©* ²|\ä`F`Ãû…xCM‚#+й^çd¸§a’+GüóظîjÝi&*4ž¿zõß/_P1È.Šå|MZXó‡ìó>óiÿ°×š3ô›€½õrY¦5ÄnŠ6¶HذN¨ZhùF¶–Ü kðüi5YyÞ˜ð—Štj¥ zS@6¤Á²]vwppÀÝ› (sÔ®E¹æÙ,¦L)p”.M¹­„€{:uÂ>ËèƒTþMyÍYÑȯp\¦ÒÞŸåe…Þ;6÷[2‚ÖƒÑEg:,8*•:Õáð+`nüépäocÙ$ææ0øJ´Ä‹x‰ˆ‚go:Ôo6¡pþå¿â"Šè_1Kü¤ê„g«Õ2ÚÝ%grê=l¤?àF¢9gYã]å ÜpÏÙn)š“…ÈrÉíBz1ITbÎòõ|ÅÁ³é*=OÞ®—K¢G0Ûÿ!;øe6KOð‘mõl:M´z”rb}Z,@+"†@ pn»ËAÕSG‰§•Íg7y¯­çpJ. 2¼áÛ‚A"¦Ã‹æI¢…¿àÃrDq?X].É}êíª¨ŠþéÂÉçGQŒ×(ð~hÂ|Šù…·LÙí¤‰—¹¯Y£ ŠüJt¹ ’¬LnDWh–m{l‰çADîP¹„éê:ŬÏm¬YøÃcöïÐÒƒ¦áàäŽÓÂ…DË“|]¬ÎìŸÒÇ:üdu‘»§PV–~PF²uV$IÝh*¦ÎÉ®QGÔbFQö…ùÂÑíñBz¼N‰äBE¢NŒ G² ü÷álu¯h`ÅSFà}ˆÍ@=ocQdú1­„A»%mÿ˜3¬}#^Ý>¬’¬¤þh¾Â‡y®ý³–ÌÕ·¾±K˜-‡l{þ©Ë}^™Ýo²HKZ„R/ow%úÐÇ(˜Q±¦»àºN†ðžßà¾:äUŽuáÐdÈT¬v‰ïíñQ!zíìÍÙá{1Š~$>ÜErK·DÖ-ÒóŽuttkU’Jþ¸Àt‘ðp)j`"1ÒFÍ€Ö›¥ ¿í0k¼»Õ£j£§á&´R<„ã£* 6IaȽȋ÷} ŠÓ 9G­~L¦W±†¥žqVïðÓ=‰yß*¬Dv¤Q{5º FÀ¼$Ûm–@ùj èXòS¾úŸdõìÅe;%þ®°Ex˜/¬(…Žc×ày8ߎ"°o[D]û³à`o¯Îp°ÈœÎC˜Àw±£¶zM ûB½ê+<ò*D¡&Ë õ€°*擌¤ ·›¨Çy>OâÌ\¸R®·–ÝŠ²>¦×Ž ŽqðÙ¡´]TÑêQÄ®\ÿUæÙ€¨fË..9¢ìÚØ|FÂ9Ï_ýôîÅOï&ïþç5{—´ð:ÁÍ.˜å7ñù½i‘‰·BXE¼)],FÕu6Oʲý.1¾Ù6QéØÖǸcŠZ¤›|ý,…6Èîê’¢˜”­îwy©ß7r h<9ÛU+b·bÃS”Ë ¯×üß âÆGˆƒñ!þÁQ"8 êÿ›(0©>ØMH´­r}ç=þ|Ñ¥« kei½ºa4ã#ÌÖ·WÆ6á@üÈ+½VQ.”‘HÑZútdËÝÅÆ×Ÿ>Õh“6N(Š¢3/Ôîq\ÿÿ•èÅ‚U¢àIŸìÞU^RgU”£ëü¢,š 1Ïaµ2ªÏ¢Ò_©C"_”§ãÊC€aÄìµîKCZêÉäp¢QßÃjàÊæ¬š#ËàÈNÍÀÕPq9ll„è’¨lŽ|~­4Îf½¦Õkfá¦Å㺉²R\L"¶_¼ßÊ¥FÌOÞIJ å£ifwÊÎ-‘ öMŠ= ”â†1A ½$ç<ûHHé+ ¨ŒÝîBWýÌsår‘¯3øSdpÔ³|}<¿œðö‡öäAÖÆò ¾ÐÞöëÏïK×™(KQ©ö5é¡uš¬ô3I?‘xž.ûY¤åŒ\6pSð7 z?TZpgh¥ôG#Ž1a…¯Z"Tê«4Jûiî~º„b¢bÿu¦3¯å%%QpQ{Jõ—"º¨úÕW»iœ1ÿL.Ž«;t-–µ;íï2Rî<ùb¶Æî—ýOcœ´-î ®óÓçQ‘Ì·¢H’³R—P‘âÝrmГpŽ¢Kqq ‹ñë"1™èLPâ×9‰>¥žRp‘~(Y¯ü»ÁíDpÆ9ª—ly¼I³·‰þò[ü›Æ‰‚g3¬k„‘&Óx ÑáFÚA5jP½ ‚Ïá,e@`@šŠ,ÍäK:ì'óü¢Nrº/!¦Ã¿UðÚ.õÂ×Cü6v™d9Su¢ î [Qì=†Ä*†Ä@¾BiA##ˆN)Qw.(ÚoÈú>ÔÞ²KaývF{±ž¯Òå<±bSßÚ›Ÿ¾óãµz¼îÔ¶p,ÆÅ*-W-äL£BT£Ñh{¾ÉòA½œfu¿$´Âß*+„ "(¢& ø0 …vò2Õò”׈³ZU°^8ØAæäEØé)ôZD¯Î„O~‘ªPeÈÆm»ÃðvÄóÙHg¢€,i¹:»t¶ öä¸H©“{Å¢kµðºïÊüp»Ë—å……vËgûsCÝ%KBšUP¨ÕŸŒBóŦèã\{:Uøªö29¤è”ðJ¿2gï[E"£oãÔ­Œ¨¥›µ”ûá“4·‹4Ì›s߯øóæÙP¹w=(»à• o5 Q„g<õ,¿˜]ŽkRš}ƒ-›’›)!¥8›ÉH0f·ƒØk²ÏN!ƒyYö.ˆ'+èé¬n¢*ú<…Ö4#É’ˆL" Γbåëe‘øFJv3ÿH4¼iºº;|y³oø_ްõá·Úªô_kß«3ÈBÒì”åI# ŒN‰pÉ‚0°,òs"gJ_šáÐhM)-‰àͳ ŽI$¥<d‹—?GÁîà/»ÁuÏO-7×9¯‚γäor"­Ò¶î=mK›Ár~ÃY`‡³0£ †Ðp2§dNoJ`„Ý([/މ4i$ ¶;øK Ýí´+ùv´÷ø?ÇžT ž>èm IÞÓCƒ b®5’ .Š<;õ›M}Ð>Ø;pq ŒV-g˜0l{:ø"ÍæÉ& 0h"„Iu‡pHqûŒXvºú@AÚAÑÈññ´â¾àÚrc1„MϼÃÔ‹ëÓ¯iše6HµÐoÜ<&øœ kö¨Ùeƒ=f»¬y_Þ„ºáÁ‹„GÂZµÏÖÖ;»ËªtX˜«Hý³K/‰¥{Ç 0r§¸Ø`;ûLf“ƒíc2ÚÈNiæaØk•WÕ@Ì*j}’¤²¢‹²¢g§µìes#9®€ép\ü½\ßp(íX*#\T`‘)õ€¶p½mVç`˜šÜ$ÿž_ïa;Ÿ`ÏDülhûª„ó[ÙïËÕ¥Ï×–%†áÖ`ü$xÅRÖ’«É,9I³döMý†Ò-æj•%N¹ýøCý¢\¤ Ÿ¥¾æÈ|Š–ë¯›ûa1o'ä rÙŠFµYÎú®†ýMŽ™øÄÈtÕ™LPèe«É¤søu‡OÙ¹þ}PÎõR…»K†9ø™mØ€ †C8kçA¾HW+ñ¦¢×E« ®âBžàrˆŒ[%öé$ùv„¸3ï¾õ•Z{¹œ³%&Èû5¸8 ÖYIsÿ$2x æúÐëíøQ•Lœqô¥MúAGGBg§Õ™m£XE¯ÛÚ1^j]‹"WdÙNÔyw–H^\2¶ƒ_th~ !ú3GsúT›Ñî±ËUªÙîr§xLOvF¹+¡)IÐzt’ÒLõ ªÀŸD¡D™2©Ë·uzo²5+…;—æ$~䊷L%ž V“•fö™µûØf_Ó3¸-®׫“Ç wì’ܪ~ÏâU\+~íT…np#‡[K—ÕËyÏÂàºe\zp±›#+òJ“³#:¹„,É1VažÚ,‡R-÷ˆ—³ šáC!4ÙÎfŒ¦ÝÏ˽ƒ ]EB4’´éî·„c3½>àfL'¹àìš®l­]åw…zwFÆt·7úúÖw*cÔ ísƒòY|žgé)8[V„ƒøÞLº¿[oµÃÑ>$eÒYžl˜Sj¢PÑ3JŸMQ± Œ¬Ý/ïd²âëç7?ØÐEM;dšoÒÙ!=Ü2~5ncü‡œ¼5'/½Ó(ÄT™ÔÑXƧ‰ÿ»0»!…ïÀß’iXè} UÂâÕ­ b©(zÒ¦îš<‹v[áÊ¿´GÂÏTÀÌ ¨n6ÀÃí¬õ Mm4ŠºeŠ|›àãR6àhk¦Ä;߬zKŽ„+rAXÏXÕ­5&@Â~¯ ƒ–™äád' z€|Ç 6‹üœ\ÔWÉ‚ÜÂã"_–ÈÀƒÐžäSæÇý½}̨»âçÚ)Vý¢Å A Ó/Pï#†¶L:¬FhK<ó: É¥R@åŸ/Þ¼}ùê'ʃðË.ÌÚ†ûwBŠgYƒÏcÕ¾I¦Ðw S+ ˜¹æq†:Ï·dâ~5Vd+²)W?>W‹…Õr5–/¹X¤´X #lßË0 d …½Ö¼ ñ¬,_ͨj-Œ¥àW‘–ÜœC´º<fi”¶f»2K.ä%ñ‹\”´š€l?B‡>dÉBãã©­øµÃ÷{1ÙFš%'¾#AÓžŠH¶±¢!ÅiF˜.¶çDÒ+jt“hEÆðª^^Î’ùR #Ó‰ÃSþoü—à·ßÝ^« u^ÂÒÂæé®vâüBë.¯m^Ía.sßQ.sÝl7‘®ótš‚xB¿j;Bí…¶Y¹ ´¾fQÔ¸U–¿5 Ý‚Àš%‘Γx™Nh=zUÍ€¼ãeðS¼H^€ºD“+&¬t=ºç€ˆç‘}—pÃY+‰XZsI‚håßm ’¾ü…P÷¾È§ä4”Ô.=ºÎ¬æËÀVœ®ÁmH,!摇ì„×’nõ?^¼f>Ãi ø p–%ðìÁk‚ È®7d(Uñ<w°©Œ[‘ç0…nå+Dº (*NRòèõgÖÕû•V@ˆR)co¤Ý¿¢“é¿h‰L4½úïP²©ªOnܳp­”äÏ-ÌC ç“m…šøkÇ ?)zÄãžÎT E9ŸÚ±DG¾¢Í郬"Ю›‰ÀËŽÉóÁ]Ileï²Kxô1«MØk…ヽÇ.B(J ¡,Á-’âKß|‰oQÂËLKÖ™Äò²<{Lq@¶Ã6ÈI“œÜöÒGbéM깡g}³Š/6Ã^Ÿò·¢Ûùà>:ŠÕ˜/jüI²$`W ^¹Ùþ¦+ÄÙó!N¹½)bn¡NÝ,¯¬;8‡Ñ<(B[t#Öƒ^¼R¥ó† TQì~!í€! R95úc¡æßÒnQ p„ÑÀzLÄ…á½Æ\E0óœ´PXÀl*<¬ sU!ðÈžIÕíÏ“âø7%œÐS yt]ëå4.“k†ÕŽ=&å4¯SF4eš; m:¥gÛsÝbÙ¨°Ü÷{ý›¼[dÛù{÷X‚Ñ‚ÃCr—";, ¾!›zDšÐd “†ý Ã1©‹± š7 ö¾®§W)Éæg‰UÀÃAøà;,I+ýÁ» ÈÇÓ$tñϨ²Z-£]N†A^œÒ)³ýQx>øóáXQð¤ñÛŽòÌã­X Ênð·ëŽM¼ófìÏ~°¦E"ØÖƒ¨bTÆätv+X`ŒŽ¿´cÁ”6˜ýªxÓ‹P´"9I?X¨Î‘A1nÁ„xýÅÀe> ·Å9d¬ÝóáH¦W³EøRu_2Ý]ÿQðÓ«w/"Œ;R®t$3|)†“4§ox‘žD¨MɈL6‰–d5ðÂ5§OØ1›„ ó³8,÷µ‘­N[+yÓ[¬'®H88µ°~3,B\¶èãä%–+I34ƒ­pFÙ¿æÙóç/^¿3#Nγـ­ep>üÖþs_ô6€|g€ýcŒ¾,i´eOß?¦þ”[]ÍW\„´ª–«,ÌäÒã4‹‹ËƶZ8ÈIJ4ÛïÈÿ¼]I¼H L€9™|÷ò‡“I}yô5¸ ôdn¦˜JŽ/À@ÚF™JÝVü<ƒkp;v³dõ£eÙˆ23,‡n½£ð&o} ABE>ü TßǯŠô4Íèsé_ªWYÏ~{µ^yKYT}/’°9$}¥Øè3³t Ï÷¦÷lk:øÓ1LgrU]/‡¯Z Ùÿ—ZùÒ¹@O5m™??< ^Ïãir–Ïg"Ùx3±³³¤3ÿ êO‘$YùÿÖr¼³äçgÓUzž¼¥¾{QôS¾JO˜¸)¢ew÷<v{¨ý%.NËê¦Æçxú´v´(zíP(àN‰@_~ÄòjA„¨i¤´2‹ØÎ°8’¼%ƒXøP½/³ /ÀÝ«."?Óž¹8Gÿ©.T‰P/¤." WcˆAÖ‰ÓlBt†éj~YÕ~€§I•ܽËj8ðW‰I±ÎøÛÓ‰n‘4æ2BÇÚŽ¨ “÷i6›ä'º7‰%¡õ†ÿ18`®i>Ÿ“5LØÒÈ>«‹³ ÷h€À!¥·=0¨8cÏßwúi#óh|;˜‘Ÿ\Û"‰uÍïžàj- Ù*¶ªûe!oè—Þ™üe¼è·Â†R ô0ÞV8z ‰ƒ&móÑ’dçd|õ”€úŽ@Z6vÏu ³Ãø"Á bºJé™l={%Ñ&Ç—ÝÏ#8±{7>‹ï%ÆúÚă6ñ M¡q…áŽø9cB9#ÜÙîBÈÁj[c¶J"­å°hÄ)ÆË¥{g¯Ü¡\(™x¢ŽR$µ„·˜,®&ð–ÄÓgËþ9øرœ¶×-þþo‰RèÆÇSZ½Þ+ƒÂއGÍq‡Ý[ªÞü…Þ˜DËP1ŸÃ²‹|}zÆŸÙE¦pJ§` ø”ä¾ ¡rt£/ÀyÈ3ür±Ïè†Ó•!hŒ‰ŒÓŠ„¡£·ÓÒ\ÔÙ*’añAœZe ȯ@6>Õ'096ÖuA[Ï“€Žù–ॊ•Àµ¼#ü+.¢,îI´Õwñûä¹XRÂlE©FTƒJDóJ1grPyUãÞ£Žì£´c7Pʸ#ëÀò¸*Ò4öÝ ÿÚÝÕ.ÓE¹¢aËWæPxä‰(9o[.ñ©ïB2ÅëU¾ t€³ñ2À*·ÿ s õ…Ql¡V–#b ™Ë(ºm"=#ð>ž%+²ÜÏ$b XX²}ð£cSõ9ÚÓ¡u‹”ÐVО"Ç1øÉ{…¤8 èoÒqœ`~H~’ü¡Èw¤Òo|WÁßÅ: €š´-Š:"Ö1¨•{Ã'„ÒÛ— ¸PêtÎ ›q:`]ÒÁÂÐSua‚ôÈ’=O5T ‹0zðˆr3˵AðEÝÞ$Ó¼˜apNO ÈèYà£E%Él•œËÿ7þß:).7Å_ÁG7·ƒc¯liÈ£(¨ƒ)hmlý T¦­qb“CUÏAìm™h[’¶Ú› 'V‡_•-r´Ø\ŽÚPßnåÜj%ò8ë¤î¬& g3Ôèr‚Ÿ÷É%¿TçëD¯¸oÑ7¶&\ÕUòQÁ·h^ ³¨skX9béç£2)ðµ2TMÎâòLò§‰/d×x¶.VìâÑm¡:ÄûŠ3Þr€d Ùê &HhF@Ñ–dÉy åf;®$èôG‚c©È%O†U‡ƒI…8¯ü ®Õsu7õ4›ýßRˆÆO}ËÆU{cŠhö¬çœ=¥Aû ±¶Y—¯:l’NtÕIghx}íH-ãbIéûÄx¦¼¿LÃ!­ªbú·Qola/Þ£5{•wÂ_e':âÖ§]¯ëÓû¨5gÚkX¾Ì¥±¼(î8’@üƦRX 't²”ì‰ËX Âðå{ƒß~Zš*Ò}5Ú©téÄÞQÿŸeÙeŠåµ{N½¼­†äd$¿‚+¹ GרFä›P:xúôñ¿~üaçé7¤—Ëè {²ªi™¤;?¿ûîñ_;ß|½óÎÏ¯ÉØOÙ¿Æyž¦¾–ðôt†»¢åÓ]Úæk`nŒy¹Ü)±Øû±7òF«bJÕ™KîDiÉkku“—Áz•ÎSÍÞÄÓ÷Qyº^‡rüÛK5ˆ_Zcù".ô4¸ØHCìÜ=—?’çgH„û8¬ÍâbF UAbY€"@Õ#<²ÇÑOà–Á´ñy¼8žÅDsÿ-gÚI”AâE[(’nHK ñÕ_ò»qÛѶ¿Kå1¡ë!¹}˳üÞýþŒÏcx_®Wø jÅÝoÉ0ð§Ìdø»ôþÿ9ÚB©uëkŒMúxÖõª»ÑŠ”‹Ëø4éCÛ'\d?`XïZëm=ª¹5xÝI“OXJG¹lW¸Äz<(;”]àQà÷+Bh‚/LË~¾6ÚŽìmGrÊ•k['ÛFä[Ù¶wζ{âS'ûarx¾ß…uM0š™&<.oäVïÿ5ÜöTÿ¯Ñè‹ÑÁƒÿ×Çóÿ2½oDÑ?…ë.¦¿fÈUÂe*ò©M×É߯!ÿkpF4¤¹dynö«‹¥5†«ä$©t"ˆÁ»1Y9¯à".1™6ùg2ÃÂT{EZ'5»¬z´QS%À/Ü.= Ýi–*79ÙQΚZp­TÕ®€¼²™r9Sg…“8…Œ˜¼a)'ŒDá.- OË;„[¯·,áÞç>b§`¯±”ž‰!ÕtwRêƒßcüÀïw† ¹,ðýÄ QYY°©‚§ÛAÑÕõ}@ƒ%³¬U°3aq>|‚R¾v=;¿×#'ð¹“fò°T¾¼‚¸úrŠã:Ä 8æQ&H›ÎcHÇj8n娸 ÄÝÞA±-¼¹å-¥B7Õ–¥Á§°ù ÎC'c¬ÔmÅJ½¶ƒ» Øh…ï<Žý¡•IR¾©f¬¡ð©¨’D¢V£±{¶ZÌ·Œ¬‡0Óûeÿc‰'4ƒá„¾alllˆÿ<øbô¥fÿÛß'<Øÿî§ýï%eŽgÈßÓWzgÍ„¿«NÀU<Œi†À–-O+–_]®„<ÚÛ3‹æù¤|”ÓÑʃcR7&H ¡gÓ¦ Z¢ï\9K¦Z³x8ªORr8ÄôĆ«DAè¤Ýúy m˜ÈŒýàâ7@Þ¿?§}!¿#ËîØ£\oœöfïžÇÉ„;ÌC7ed-V#K…Ð_ø¢ƒ^Sî%&ʳüB»Fq“†zúo5—f½È~ó#77våa¨¡i‰Aé¹åG€*¿ñþg]‚cú|íë3e8⎵)­ö§ÌOý 9b€•ãÚLŸwsOÅ8>"^Øi¹t¦ÀX2šâ )Éë»V`‰Ú\оy+‚<Ò‰×Öt5¡™h'Ç &g™§ïóñX“ì³ éá<É4_ 83åŒÉtÕãu«¥² é|¸ÚÚô-íîóÒ»ºuºŒó²æÔìé[6òÜúž~Øcw·Ç()›7Ùøå—²ó†s‰VõÇÆ7’WÛÛZÍFÛÛync (ˆ0Ãòá·ãp Â$P@3`ÉY$áháßãYÀòÅ…ã~@~’_Îâõ ÊýJ&¦?¿Ë‹ãt6K²Ð–Œ4: Þ$e¾.¦ ½]äëŒðEŸž±2ù?Žx¹¥eÜ'éKˆ‡¾J ¥ïáøA¡yPh>I…¦/ ³àx½úä•›Éó yÔ¼5Ï!ô âá'g˜ ì2ÂdËzŒ&WîX‰¹eñôÉ+yÛxŸ’bgxè«Íü~4™ÛØÔŸ²­êh6Æû ã=èxŸ¸Ž÷Iò,ÇÀƒX~ËšïQó½S7èzÿ_‘„æãÿ÷öžXâÿ‡ñÿwòß#‘«, 0[ÐÎæÁ߉”E¸Ó¤r.z\Ülÿ—7Mûÿ€œùÚþßÿrïaÿ2ûŸ©Ê¯X¨­ €£(îÑñø.ec}¾é£ ü]Å®ßÿ¬J{~Ëö¿=cÿñäáüÿäöÿ?9·lñJpºš ÷Â!ïGâw)ìûÿ\¤x½ýü¿{OFÆþ?=ìÿwÿ¿æåªXOWeÆM.qßvwû»<ÿ{Œi˜©™¾¡é]˜ˆ¸ ^-“ì-‚‚bæ‹‚#sø1«4/Þ«dñªøa7+ û¢EðÑçÅ€Œ–žf¼( •UibSúñu>6Kø`Lez\èµB.+š,“X-Îjñ-Ò õ\nÝHâ/EÎÊå<]uÃ~Ø,âe÷óˆ0uºìUõ0RpaH²jL.“箃’ðO¼1”XDàU:OÖó9´4ñ‹!Š·:j&CXyíîT÷N˜¢W›<"—]Lè?Mzbuö‰Fm'Bï—†©*oœV,2šL2{± ©EÏ8 hÅYŠe¨lHç  ³5™§º“ÈLÌ2ÓÕü²KÐ*§;ëÓ"~дtš-\•|}]ªär˜‰Š÷5¤Äz 4 S¤[Aeæd>S f7×­‘ÝWýŽ Å» ðY7AÖ^‹Äì¢ÚˆœTþù"ÍËÏÿ^§ÓD¢/q’gÉ$?¡cõiß¾ÚÖ姤ޠz,i£_äÅûò³Ð]*J¨~`ä:ZâSt…62(4|Fä7ýÙ¿pÍQ¸ \ °êC]™‹£:ÁçAJ2Q¢RKPSI%Ç:cnrÆÚîéu×丼áUdIwiw#¹Ù”7£Ú‡³}ÕcÆ{< L=EÔ öIž+9¢‹<ŠâñQtLþJù·™[¤Ü±a,ð¬bå #ò?S¢ÅÇ”$ª»]Bñ°Um¡,¬Bñ£™°ÓŽ:džÎxl{ï’hŽ/^ú^p“|cYWÕV‰­ôÝ„D‚4éMt‰%nëD)‡TµÔ_ÿš¤Ù,=9I pP„,Ý¥ÏË`ƒþ÷ä`´¯é_~ùÿÿÞêϦ«ô4Ùÿ÷÷uÿσýáCüÇ}¶ÿ§ä·ÿïö•~„{ä#X£ÿ?{o×ÝÆ‘-нëWôPƒC R’#Ù#ËòXsmIW¤ç̃ƒÛšd[ƒnˆ¢iÞ§¼få/$+ÏÉS’µîʯɽYù©½ë»ºº»ºÑ A>sD²»«jÕ®]»ví-†¾£ó;¶îœ`[9d„ìÎxó †Rˆ™/üq 1+`²E¬Þé t†5j%gÚ’\¸`FÜ9}Ù6ÝØx‹wtÿA=¦59í “‹óþþûî5ƒnT²–ýGØ€ü†ùΧÑÈŸÅlž­æãªñ€E÷ÿàaÿíüÿ·tÿ/L÷Ή¾YÚãhv°\®QÁ`âÇ« >èñ û’à™\Sx4VgcÊ¢„,’š¹ÈtŽÝf Éyn,;×^ôfÔ”çµvs%ÇÕ/`øÊzÉçƒh‡ÝŠöÔ×þÒuŒoC“eÌL2 ÆÙY8 6œÿ£óä8•ÿãðx—ÿg+öï‰ ôz'L¬3ÄdˆoŸ{T\’e@& µEÈ#Ï fõ*6Gržî8°!Ë:c·ù $ü’ß,H.¢ ±RþòêT¤=¦É?ÿ>zLBÈ›j)C¿þðâÝ»×oþBÛ€Á7=˜ÃëàùÁ2XL‰ö˜0À¯†}$pQôˆÆX*ß6y 8÷‰iqšœ¦í±?î“Oši¥¥ÞrÔ¢^¶ŽV£i`¼'†b4„”'½ìq4 àUî]l!'<=š_T|ÎŧßèŠQ½–ȯe§ÉžsM±2Þ”XòÇzÑ*ÅÄP» +6Wÿ¯õÃIÿ?íšùȳÝý­ÑÿòšË=½òÑb5õˆþ|ï4˜-`ªH»h¾X%dzð°x b]ŽB²fΡókw§åº.x¦Øp@\3èàBÌoƒ´áõˆHs@0ÿ@ݾ\†I°í4¢;Ý£†÷¯s8$ ÆË(˜ƒ­©µY—¡è&½ì°Ïzô‡¼û&–£woON•4ü%rîKk·ÌzÂWàù4ˆcïý_ÿcøîû§ß¾}ÿƒ÷ü¹×øÉÿèKïÊÌÿ .ÚÌÂ9ü ëÁø‚EŸ~,n[·ÅmkB¦Pú[h›_~yîz±˜‰÷ì¹×i?nw=yQ…åߢ³´›² Â'8Nk pBÓ#p²tÚOÚî÷˜48J²÷ås¯KFõöÅŸï³Ï¼ý}D0} ÓÉÛ£&ýß’¿Ÿ4›–s¾ôÅImiîwè¶hŸ…Ë8iöŠ46¸ÐÍ`À!^CÞo€œ‰U ^-M²ÆÓ(ÖŸ Ãù‡µV EÿO#ÈZ›ÚwÖÿ©ü'G»û[uþ#vëh\ýâ¡¿›Ž›vÅiÍ5·²ò&¹4ÜÉ껋e˜¾eؘýÙ"ð»TïæwÙ.锽‰4G³Q8&þJób•ÈIäB^v¡÷±# ‰€ù½Hxî!¯+b+2‹Vó„×t°0À)œ*ý/tx­Û/…ÛÃÝåöEð)¯0ñÑ—¢üFé |2 OLw/ gÒº€É ľ Ûóèòt¼ `zÖqÊuH—Ù†ruŸ7ôñÞP1Ùæ=þ-Ýÿž…“É4¸ô—ÁTŽ9€T2µ,EúÿèqÇ´ÿŸvvþß;Ôÿâ)ÈÀ“cË‚ðƒ¢!ˆ´ôz_Cæ¡ ],ÛDÆ Ç0˧3bÏ®†øk³ƒ¬âmÍ8†;Ý2U<§6}¿ã3bÌñg¹5”ÊHZ‚ŽoÞ¾yÕ¨ì4 =óìsbˆgÞyø1`Éä¼1±K¥ó ŠV€æÇÓïÞ¾ýß¿8}ýö Úý˜§/ ”B«ý†?!ö)ÆÅá/ÍeÚŠÚ"MGÈ5u ÉLJ¸t~¹Œˆ5 Á_ˆð&ÄaÜ‘$À5wÇkèÿI<­g/PÿÕ=NéÿÇOvú›ìÿ´ºÿæäûá^h2¦Ñøä{ôå>ùq#SþÅA’³W&㻟؀õ( ÊS:Ý¡~\ÏÃù#¾xÀVåÓ7è$hDœIxNìAá…O…0µa ¹@‚$¦Z·ñA¢{‚-©ÁXÙµýY–šm8JÜÏ]>[ž „y±ÇUAoq„y“~ Z‚hò }B^}&Ÿ ö0W£"k1B+pw|¶š&á‚è$Ì:mÏ‚åy°Ï%(^- â•¸æ-³·>CþNž+à°î èH”Ä]( —ÙO;Â߇!ÙkÍ£dH{ÕQW¾É‹5lKû±ÔtÉ0sÌÏ*óÅÒ‰ªwp¤–ª¿°£¼­ŽmoÃOèWòŒþ¾ ¤¹lªZÛ6ô.Œk›ì¿8$ça°áúLJŸ¦ê¿<Ùå¿Kû¯ŠàDÈ UC"†êkÔ®/TƒJÏT z¬tÄ,\%â 7ö¸£Çí¼8Ü¢ÇZ,ØÏÁE0’^Q‚I,@bŽ8ý³"û SqÿM¥¯åjÐáЇ@ßïBµcØçößÓi);–A»1XcÒ„V×wÖgÞ<ÊØV{ÞŸÑÈ€gþ4–ántÏ}yA¸ñ1X–J Ú±˜y%\©±ëqi”tjdS4ßWQ#ôª¯¢<éÓaˆßÐü‡oëóèý éâÀ“1ä€m“yÎÈ[;_€]>?WÎGð°'Œ?†L©9}Œ J˜ƒ@ÀÏ>SNLŒOûû·{ôB–ÆÀ{þŸ½ƒgÀä6§¥Ál‘\}•5EfÑdE6RÑö¼4l>½Sè™rj%T a®à×/¡jqëU¸áê-¦/™â!½~ÚçŸå^vLÌԞ׿ö.‚+2èU´Âk¬×TQ([ÉÜŽ"üûgò÷ àˆÊ¢[ubõz§|ÛkÞ\ð=f&*óN¥„¥æI¢–±¶ˆ8;G‘’¸–Âs³~F©2.LÊþ–v½¡l. ‹ƒÆ+›Pµ(ŒµngÿÆìÿÚŽþìÿNçØŒÿë<}údWÿy[ý¿éƒ¾ë¬ÏÐ<šúóC²"5¥ÃWy†îà¡n67¾ …ÉìÝP²~'ñ¡÷‚`"@¨«+¸‚ž ççm(MlïK»“p²Z4Ûþ|2¤•ÄGúQ×…OÓíAX¢O+Fà¾hi$µ–n‚Ó¡I½Sp˜ÊŠ-IÄGÈêãÉ®od~+,à8Òˆì˜bÍwDÇH ê訥[ÀØ™–KǾð[£+|Fd@Åùw€´êžOãE¸OKFèµ}¬â…—‘ˆ=D˜î/'¸ä²U*Jzs“qéÄåy†?¥ Ç7ó>uŽ SUQWåw§4vWÉVt1"›"Œ‰=%Õã&DvÅ!ÁÍ6Øòfmæèî$ñl%r´¬çj>ÏJî6õlW­4 ) &ÑŠspªæ^³þ3ÿŠìì•_ûÒðGNýùÕ0œ“¥k>†ê ûúW—è&Â/³_dçÏžy3%ÚQ@”mBœºÄ\ˆ/¢KbѲ1-uªÎ…c‚râDìX1åÎ+|ë²ahÓÔæÎçCHˆEØC½Vïù[k%¨¬ VW1$×d\ú0{“Q3J~¬­ºÇ°ÏôG㔫"¢{…TŽüÈ6ÖüEMrè’Úgˆ 8ÖIbé3Œ2£±•ë GûÀ/üXô€Ì˜Ñ¸0ƒ.üÒÐ*™ˆ^ËCNR>6wÜÛ÷Ò »K¡­> ˆÛ“X\ˆ4² øÎÊ úÚb³üF¾-Íø QÀÍ6£ xôªN¯K“àÌ_MU˜k RœjÜ­öê“?[LƒƒÔzϲԑâØ„××B¯¯ÉxóàúÒîi;§ÔMÍòL6($åhA ‰±9‘T¤°¥ ™,‹e8V g}$o'!j "¡{?@|í$©Æ\aL§…-S¾ÔrL–S{Fa&.Ï‚ÛñÑ×tÇÆSÃî+Eç%Ù½¼@ûœtòõUÐPï „ÓòîQý< ¶y ¯à$IGc•̳Ž~ÌsŸþEáybzÄABL¤”2sH!À.˜ö *¤™æŸD˜PËö@çf¡TI;Û._oÙkb£Ý‚¨)£­+oFWÎR§aQiÖs Â`¸‘×ÔOòA@ÙR¾¦©ÆÆ¤ß`]öDÈøœà ª-o&([K†ûèŠm Ó—®+L •‚ù’ýÛrsÛý¿´Œê-Ýÿ>:NÕÿ;ììòÿoÅý”ŒGpV–\¸…©C ç(ÓûøDèz¦éáÙ+ìOêCú·œÎÑ<=8\7Áþ#?x U7{"!ýÛƒu©‘¹ó‼z>zöŒ¬ÂÓ3é I’åû{=ZÌ:ë%½§¯+¸ý²ü?<ßcµ<½Ï‚{‡ªî&¶ 8†Tã:G™ƒ*§ªXd ~Årj~ë‹_^ä ^çV<èzÁ]ü€Ó2}Q’ß4'öѵØÈ‚/./[dÓ5­–çÁÐàWÜ´ÌÆga @‚e´X†~Lå63Ni WïYëžwÜ9dö˜º‚¸œ†v ¾€ŒŽÂK0–‡M¥DYV´«³3 ƒ¤zÂ~½h¾ïCW—÷øðÐ3¼9€V¢ÛãÃCËŠ/¶Kf‰íõÇ7¨aÈV3+ÃD‡ téçŠì–^f0™¤¥7<ó.}2´º+t’kl߃abI×̉Z/z Í£u<<òÒD| °[è«ïíÄrP R-¶$ôôµÀ†ë.ª!Ûþã¥_oáþoçéã'füoçpwþ¿µçÿŠ¡÷ЀJGe*äF1ù#ÓäÏ‹¬°LKŠžç6Èùïœö¾ ´XF_Šm ©u]@ÂÆ¿ãuª[LÇg[zŠBÄ'=O4‰N{²|õe8!*ãÿ¸éBfû0¬b02µ<ÔåL(¦ü§P‰Ö•ø&˜‡ìaƒ„2Z¬I ¶Gá®D oLtE4K‰ÍK|LgÅ3[isá¼2¶ JÃ5'Ò“$×1¬†ÒVíÁ„9Ò“‡*ûŽ‚L©©“#€ƒËÉaŸ’¿SÑúâŸ{_}ùÏù3›üâyϘyù%2ñÙÿ“|tÀ¿Úûõ1®ÆÕÍ{ýÊL¢sðK}>;`ñú5ã"oªðМٕa±ä£ËýTS²§½rH!úK6@?|$=%í5ón`«ž7õg£‰wl…›gáüdÃ=†ßÙÉ ù-˜„¿—áy8÷§CábüÅèNhh÷áD"Ûòp[”Ähe&‹½ÙäΈ9xë˜=×ç_n·¥‘GX»O±Ø3³ ÎWSÉœ|¸Á\kWŸ [V5ÞÓJN«cÑFMµF1NA:òãu¼3&qKxK{+]]f<·'Ô‰çÏ'^O „¡–pëŽ(·Æ}S»`"[2´±N;Gœiå™ ¼®ÛÿžÎx‘òUïBÔT¡w…›oé3 à4!à©ê¡müzVhbýÚ$eíýDYAyô[”äSòk‚Òí Šç.([qbÿFå-Äuž>9LÅ<ÞÕÿØÖøo¹p8$ßâÕ&‘‚]|¾®’ AM( ³ãJÍ”L2Ó„’ :ˆ‹®ÂœŒƒ¥å‚ž9¤?Ó!'Á™ø7¢1\õC•M %ä¦`JíÊ€†#ö­¯h©a þÇZ=÷þ ]fl¼{qúÝðõ›oß² ƒíy ×Ð"QÙË—¯Þf”Šâ8í¾øã ¸>ú…«Ã·À{=ÆÎ¿’víÉj¶ØGÜ›¢jaƭ´ÞÕ×GVÉ{QJâ¡çÅDùÊk}¬âY­H6¤ ×à²YÐoÑ@àëT[ßX6º‘sëÐ~•tmêC¢9òHÏÀkfß4gó,bÓ‰#8ýk69è,ÁtbJÌ¥…á 0åÌ¯ÈÆ±As N\ï€{½þ5"Ý#ÿþ¼€Ý*w>Î'Ä ?/Å¥lÐ]8GLÙ,®5b,ÔÞÈà Á¬Ñ;uf‹êSF®<#|Y' ÚZ­“„ÁØÌ¯ò,èMC“/È‚2UsPÐb¡|•ê‹ ¡òáMNΦ%ÅB§/bÒ"¿51›_Úkš Vž.˜(rÈÀ‘¾·ìFdw+¾>a…âÖrFYða‹_œÚ„ŽÂKã%SÖPäÊíz>eõ‹/ÔFõ2¯îYò¯YÀ“+² Ì?`2/ÒðYÎ 4íiò÷'ï_ÏÛG-5xÜi®a­PlÀk›?hMÚø0 ?AÆ78•"æÈ…žô¬&ë'¿~ÊÇ¢¾=âBí)¸ùŽVI°ÑòGãçÝöQ.ŸÖÆA–ÉÄÐ3£±8’zq… 'dµzô±óyMZA? e§¹"‹êN1?![dbM‡Øt ïâ:|ÜgQ ÐÊŠÿçjs#»ù±@1t ×ìL_ë±âsm *Á [3/úÑ&fñÕl‘-½Ó¸+, ^VÈ0«=]æìËM‹ŒCl”ÙÎ#z^ãðîs5`Oi 3¥híì«-cý#Iì8ŽÜÁj¸ð†-N“–R骤­.R½¼T g˜Æ‡Pw¡”Ð2™ËÀ'›g€¶ÔàAó’àsS?,  vP$UÕȧGlÔªô`Í×áØ#­ â=Ì"UÎC2ÇàoC£Ýͬª·,á*jÕ ôµud!20M£êWœó`Ž¡ä?`‹9cD´Jrx±½4I‘ÂTÅÆŒØ0ä nFòö&ÒÄûË`/«µŒ՚‰]4ú‰F€¢[üå'§oð¾}ûþ‡§Ò;.̮֙óè*×ÓŽêã tÙ3½²Ï»FSȨ9ó‘Ü¿¡„?%F"Ó²¨ÙM jý=€jo gU5ç–*3™Pæóšåró¯'o߬ÍRÛ„Êf¨:ä oÍ#a7ó‘X?9˜GC.üF®^û@å‰!%³2ú1 §q¯wrúâôǓ´&¾y;|õæôõé?†_¿ýæô ¢¥i_¿HYÚNïY4¡aƯéW7ê½tÒ`" &4¶àÁÀ62ïóúº³\=¨OõŸiS›ÙÕ3[æí„óÅJοß_î¿{{rêAyù÷îÇSï›Wß¿:}Õ”DœD÷‹Jòý´nmÙv¦ã °â“ç«äìÑìNU2*ƒ§¾ÕO߀{lgÀ®¨êá5…ð7¡ãh¡ý)œ …sôû?´™ÿ7$CØBìéÝ“"ÂZz¢óú-Í}½ÆÃQM¾×ÃX®=zܸ×ÛCO…ˆ·î±Ì[Tö…Ðüêý«ÿøã«“Óá¯N¿{û ~J1L}ùòí›S"øÃÓ¼{…ß©äK}t`ì'߆Qfß¿zó—ÓïØWm¨F•\hßê8Û6v¢7ý†$iÖ5¸J—ìX1ÃÑ‹ÔtÊ”l¯ñÅjþ<¹UÅŒ4I‹Ùú"–%^VÑšj²å&Wi™²Lø®REM¼Ó÷/Þœ|ûê=QÒ/ß~#NCåÁy¾;a ‰ªUš4™i,ƒËî¼~Û¨—Ódâ-‰•»ãü–rÞ¾ù4ìzCÊâÂóå3(Ÿø%dê}v€¿>; /ª* z¨^·Ä¤:ͧÅG™gÞ[†"1~’!-æ9ùÊëý@ö áßµ(rb@¹N~â*ÒW7 S-ÿZcôCaSs†´¬\}^ãGéõÀV~óâôaÞ7¯_ sNZžñÕ»ïO^½øúûW©Oí³)ìHæE6L‚ð|û“¼úÍa\YDÐ~þŽH>??M­ØÙ–”‹åjE•±¡Š,(Wû©YQjx¡œâÜýi³?&ðäÚ¡Ë"žN‚åÇà[ò#ò¯^7[ó¨šÂpaŒÖK†Ñ-OÌûqNaÈù„Ž•ª.5ÿˆÙ1× $•q@– ÀÍéêï§Éà)¤hæn­Pa‚qÊr_/0¢ÉÊÌ@25?s0=£PÁ–^J‰š÷–Õ6Urtf¸$Šã¹ÅæÚv´eFêµ¹ëÏë1ZY¨°¦Ì5w n.ò—2ÍNú¼‹š#h ø£â#vâ£+QêÕækÉ”Ÿ (ÐæÆ!<’4w‰:WrÎIç Ä£å,\ÊšnùŒÍ=>¢~&´A–<éž¼ÔVëã7S wƒ9È&R˸d¹ë§úCErÞ¢V¼@# V‰êlמ_ž”ÅBªÙµ.[Én(ݰ=PºÇ=n6ét³4¶hfÀ† Îym³øO¥YÏSþÁÕ¬¶B‹­®ÆmüR&› ºÈ÷{lp“‡Øú©`õ ‡?óºqޗϽŽõû´$ Ú¨„ùXo.žÙïO£‘?kªQPÿ¡óä°kÖ8~²»ÿµ­÷¿þB…ÃáöûÒV¸®`f¡×”M`+%|»Ex Há2šÏˆå ­@ñE´šNèé%'!·‘=[£ÌÂv6‹[ëNÚ dÛ¦ôjX¼¬NÍàñnU0!‡QIà0ÖÚ 6K 3Ì>ïЋ¾Ú¡.€îQXòÚŽ«ÀvýOtâøÃ-Õÿétž>í¤êÿ<~ºÓÿ[ªÿO@8´B?øÄÈïþmÉF’Çæøòk™ór?È×”z;KÉMÔ>ùDÙfŠ’šÁþgøNî4ÿŒUmcu,à‚²XFc¶–Ê=bŒ}¥ç¹ýÞ*&V¹À2|+ø ÈF”ì‰5ž é2—ý­þFG¼Ñ÷c,!X´Ðb'  è·úΗk©U¨£i ²V$^Åzßb_`"t©)Ë¢9[@QqØÒcg¡CÉZs|áÏÏ¥-XÈd/9ºÚïd(bµºxÖ(¶(àLÄ0\Ë_ž¯fX ¥<[4ƒSË›] Iß=ï¸{›¨[›¶ "SSŸÁw­A8(O9:÷ê Ÿ95>ƒ¹±9ªéÃ9Óm÷%ULìSÔ3¶TûböQ ¢Òâ#+¹Y²ØœçpÙl> >åÑ—vå¶67û‡ƒjÙïØjúÊ…tLùS©KNï7˜´-&#)S»Þ{";ÒH8¿šEë¥òœìãæèÔ$mâ±-LŠªóý%¼c·³§biV¤tG-Ì(ATnt®jHw ëuZÎe)Þ’£l×Y?N¶KMôm8í®oçHvõy]b2W™ÈZðHóA]³¸Ì .3{)ÝÓÓ×:ak.J­òüãn e}¤24IiÌÔ`ßùêâÁ7¼Å‚AàÞ MðÖ¢’³ŒÌR÷<ÂÄÿzj´ªŠ¥)f”+ñRônàÌ +àr¡8>”2dgKµŽzTs?¨â2©Ý)àF„n"tk%‚êÙªºý·M?· C|§¯oC_»R}§¿ï¿þ–ìýêî2¸%½½Ëûr;ù_~r±n!°‚ü¯GOŽÍú_ÝÃήþ×½ðÿ'wïþO.ÖóþSçHzþ ³bíÇŽp4µJB½pŽWI¶Ã~ÐÛ#?¾í«~jÇâ¤v«áìŠöa²ÈÌs\Œì‹žwð±}ÚÝÌ èä9s Å{•f¨yð|-4è‹4FHÊÂÁ€8Xúb2N­Ô461}á}…ês;¬£;à¿Ãð4ÝA:GüË=‡Ýìù±L嫹<ò|âõžK]ï°›?7Íè#Éè\‘½ÿ´ ÎC²e[þ'ïCpu-'&ÞØŽ°©ž6 dÙÝ=¹æ}z´qËSû°ÓH…Î…2&ñ}O¨éVîu a9Ù[9áE…×ÚE©XS˜Vxd}·‰VÒY–/³òÌJ‚»ßû §;ïÌvdCç/£¼8¸)šP²wÓ6SMnáD6$Üàÿè‡S¸€œÎæg9µ†=ËÈš q$yRÊÁ¹c<icøbü S*”ÐÕè VVÈÍqˆî»@‘½&>½‘¯ÜLÓ•|ß³®±XUýArM\‰0eè|ÚQ3pv²|yŽ/¼1…LP˜m†k†})‰ÎLLXiô’p~ªärc ð¨ŸBí¬SÅ`N]‰µš³ËVMÓÑêræWaÿ¯ÔWåþÏ“£Ç]Ãþüäiggÿß¡ý?‹&«)³þÕåYøÕ×CpŒ5š‡³`6++uÀÿáÓsOá5z!xdýùUrAì!ù[J‡@ÓöÒ¿D®¼fŽdª5¸n/üq ‘„„M4Š`ý*@Ñ–9` ¨â !ÆÆyì”üèÙž× Z´a‹w, J7°ðÈšÛÂwnp˜e'çãÒÏQ¡ú¹Of‚q‚ÝÉÖ/)g%yx¶}K †TSÒuÆ]Q6*è0%ðvðe»›”T)—ÆQ,¡u±Dº®€šÁŒCW`.5Ë‹`Jð6 `)ÁÓÄ­XµÉ\CÄzW‚£„¸)`·uó m2BCæ7žP2‡‰M3ÿÑC{ˆ è;¡4n2k¾ø<·“By(U#6"yÏ?}¿Â¤¬Ý¯•´UÎ$ Ð 7×^ðªü)ihèïuó˜M å ÅPÈŇ6.àÌ cù²Q&•“«e¡!Ýêã|ÊäÓ%Ã|ʢɄ Y@‘¥ÉpqóΨs_Pc[Ép tÙKÅ«3ûºœú<âtìUEÀ*Fé(Á³¶ݧ?=¸ŠÓ´¡9,C:ÄWpT‡kÔCÂ?…º´bÂãY½4œrk!™$á÷ÛxLä¬@Ù‰¤Æ?hH‚ÐÄ$æž<rï–HHí×.R;ÉW´{tüõé+•–âø†*CšfÖ…Wø r¡¸:ãïå³_•tðkÕTkÞSYu¢˜>q¥Íü›žÂyVü¶^ÃÔ„áÑlÎy¢ÃªŸ+vjfŸ@Ú›2Q…€™«¥´ãÝd¯×*–ÊÚÍd=4‹ÔžëZ< Ï/ØmŸÌ3nÙldqÎ'å.ê¼)Zçw·…ËŸÿ/ƒ8 r½Œå¯·qÿã¨ÛIÝÿètwçÿÛsþÏþ|'$äÝEéOOH\Ab<ð7«ÙìJª@f­°Ð­oN¾‡¬òq8 ÞG«$ÊÀO’åpI1zxy¸Ç®²‘߈rµ"›@ª „ –§©¿®UmõgvDb>V»†—Òð†sb1„X·2ƒµ”WD~Æø E+º,¶‚tRáË…x°i¨-4׆³hü¡©¯oi`A%Û#:f^ÆrÃ4±€­-¾ßWÇeJÙSžåïdܸ&1D@LXkŠ ™4€”œ6 \Cä,Yd0¬×à‡"/¼gÁV–^ údô0´p!—QÞb¢(¿g$Pá7±ñ«Ø›1°ã†9º.ÓnH@r²´X)Ž„Â7Õ)Ýiš !±;œÚÍ(ÐÆ4»êÚ»êò®ºy]r/‹9ì”dangÝÒB1Š ì %#‹SÒïƒ)9é°Ž=tÓ=tÙ‹eòí̳í±ÿØ[hý÷ø¨{dÞÿ:îîâ?·1þ“%NÕ.f°kSCÕÍ¿¼:å[Líš[UIòb¼ÏË)K»ï±Ÿ-ÅÍ@óµÒŸÖä±Ú˜šFôŸ›mÛr—Ct'±ÕñWÑ’èêP¿Q®µTP¿bùt´„‚lê*x±…‡#nè#Çé£%‹7PVškuÛßóî‘vx2"Ï>]ý,ÏKnì‡?ò¾Çƒõ¡JÍüÜLLNëå,ž ÁÈî¼'áÇàdµXDˤ׃«mÿFVâ×óIxv,ÉÊ ÷–YÚ¿†O33 $ú@ß,túÀµ  ãçP[ì_}J‚9M(㳋Û_CV Κ&$ƒ“ÙÜlU¢™·9`ÌÀÛ0pñÆKÉF!„`q(8G’ˆ1\ÚK²-$1ô—F~üÄx=&OÇã±z }“Í%,ÿÀïè‰1ï½ ŸJÍ–4S[êfY'3«×ÈJ¤à`g)·Vx¡¹B™ºH’ Ó„`HH–9ýD¯y̦Õùþ>üËûï^ _Ÿ _¾}û=U!WQ†“Ø”¦5a‚¾ ZŠˆÅÌD½òÞC•ðèuüèe÷Û€åæ$deB8ÿ@õêì¬.J¾zsúúôÃÓ·,aä0šG—Þ%ÍÇ ¹LÁÑŽè8R7uT–\³RôÓÏÈÄôæXe[¼‘ê”Dß¿þ¯N†'ÿøáë·ß¿~I&ç‡|6E´uóG_äMþܲIo4'Zˆ¬Ï ß]ÃËI(•ÏïÃAüè„‘J€‚ÝÎÑ¿éýY㦊£“ûB×ÞæïÿºÇ‡O›þÿ§G»ú_w¸ÿ³»ÿ¡l“¾Ž¿–ÒrÂno˜·§{,Ï ˜¾é6mpi%Ãói4ò§¿KkX¾!戦º˜© `ÁIBª[b´´I¹_ÿE-ñgm:r¿G1*ªUñgQ4ùK[SqÐïÉ#Ù|æÒ‡zÌ ö§NJ[ßê{§qÄ™…:ŠxhC¾ua€uš1Rê¥uÄôW9#£ýÛïQ3XöFÿ6ÛY×qjòú^“µ²3DnKl\F«Cx\ÆÙ¤eï"HFk«8e©?îZgħU©ÀåÙ–©*JÅ”`\ߣoi*Ãøâr%YOÄÒsÊ8°´ãg–Æn£ çÁ§d­!õRv©È Ìè ©PÓÙ~2Ç×ÖAÆ¢‚!"²·ÄìÊ*wâöd­Ap8É+*?npÛ:JÓï"ZM'ÞÙ‹’…_x˜ Öƒ¥¹6%TMü ~ŒEGê8ë0oö’í<Í‘f»¥!âÆÈ8X1õ¡¤‘èÈa"3¤²›È?dO{ó s¨ ¹‚+-íWeHOþWs²V#=I7;ÇϸT ‰«¬Íeµ¤½i&•RïB@U4˜×Ç'æÍÌbà­†‘Úíe s¯ÈÉ—ôÁ¦„¸g\[-œx·Yá¸Ô–FçÐW™\=cjy7»Û]ü¯ÿKÍ£õïƒÕÿë>96ã?~²‹ÿ½Wñ¿£q ©ûƒHyþR+Y&SCX¿ÛçýXòC<œd¨ô} Vã‡àÊn4¦¼Ùö@!®YiÖS —?2UØ(cû…¾³ùâïGæÐw¶ÿûƒ Ó_9òMǼ ˜V Tˆšô/8@ ’*|Y:+¼„XF@8n“œÕ§7uk N‘ï»bà“&èxÏ fÁøÂŸŸ÷c7¿¥×Šâü<÷$ôÖ„¹úž`…K žHùãµ7×aÃp-·cCÕŠ þµ/ûè±ÊyF¯=ѧ»û!íö๕˜Û[=7Ã'êQ™¸ >Žf‹iðÉÛÛA…w± g!\¬mz?ñ½äjAD{?øÔ&$arE[ƒ¸å‘–>x4ƒÀ­Î½‡_ü±Ó´¥à¡`ãXšKvÔ#Ÿ®Àj$Ó3ë9öՀʟzKz©Ü;lJþIÚ›¬Ópì'Ö[”2 VÐO•‹«òl—*fëìÿô®sý]@ýÿôÉS#ÿK·ûôÉ®þ÷=°ÿßSi9áÂR° 0ê…gl,_ånR B´õl:Mg)c$ØÖ±`;®c0´<½]´¼Tí8Z&ÅF)ÞО NÔ䣤©²D§?Ò0{P½Rë~ÓŸàiæ­ÿ÷cãtüê÷}€bPËÎqN6Kÿ n|äÅ­ow[`Þªmd|"‘7òŽøãd%nªyûìϳp'Í;ßLö{2n!µ­ÞT––õ»ÙV‰Ïb_âž­–+°Î\Ëúªš€´°ažÜÁ®ÔPMQ?èý•R\•*á õ Å”ä¬ÚVüóMú¶áÓÊ `Úƒ€ÚÒOKƒgp/\y̫գ¡§VÜ}mxNʌϙïC(ÆVÄj£Ž‹ÃlíÃC¸4Ó^Œ¼§ûWž!íAЏù$¯¾{PV&°•«DHR½â+‹Ádoâb!Ë–”î¥cè–Ú$lMÏØ,œ|Ix”öŠýñèÐê“mpwÉ\aùŽ0Ùè-ÿÚ¤LS(LåÙ]ºÁLÿO~WÿÏã£ÔùowWÿá>ø\?ÆwŽËWk;~v~Ÿßgç÷Ùù}v~w¿Ïv8zZ^¯8¢çèÙ9zvŽžÛuôÈ¡[¶^wŽžÌÐ+Ë[y»ímtâXÌt‹Çfòç;ql-~kNœ"ii@•‘žƒæ>:hn9þò·”É!‘“³ð|µD½»†#¨ÀÿÓyòø©áÿ!ìâÿïÿ§q‚âËôKUX”9ÇÝ;Ê$|)|ôÚÌ4êƒÒTË´)Hû=*£¢éoÝ–G9EH=ð‡ÉCúÛùú©hüÅ hÁe6¹G¶OL–6ÓWJ±Æ2x"„ `¯áO~#õ¦ë5FAB^¤Þ™ŠŒaç5ÎýÙLëÊ,½ýéð£%O¿HwüØÞñ“tAF0ï©õùr EdØQZ²42Âõ8åZ®7]{Œ°%ÛÁ½9Fé'µwS²—Dz—'ò×§=ï)Í/zÞÆÛ¼Ý%EÑÿd '8»â(ÁŽVIÃ$ s.Z£tþ?ìtž˜úÿèøp§ÿï°þŸÐðLÿMÊF¯÷BÇk& )v‘Ù÷<þ[ÿ¼®îp\øáÇhµÜœý×íÙ  ÅðñXuºT‚°À“%àâ,‘/…ošmÿ=Ÿ×§lèEÇ£ñjÆÏ„Ô£ Lj·ñÊB[”Û~.à Wåyjq*OÔ|r¡Fèë¬êßI/MêòΓzÏ{Þk2êy°lñÑzÞq×jˆ\fAb÷¾e ž™ÉW¶€câBž±Ï*r·NóP¤™g«JΑ} œÖÄ&¯²9•ϧ”amrEðD }#¬18CÀÉå‹þõó¼EãAU>q‘@>Ìæ¤|1Tr'¬h–…–§%[h³²ƒÞ/ÊSÜDü"e{ì¢Ë˜'Ùô^›ßì¹NDfGÄY+ŸÞ/wþáÊÃÏ<Ĭæøi£h’’MKL`šÑP°ÄxXwÁÞ…Ö¶x¸ š³'g³Ov0ÍüïGÑäJTµ–9N3P+€Ð£4šÑÃw';„SŒ¯ÂžTœ˜\ÞKlwzµ«:N–´y§ƒMýù}g’OKb…<ÂF@M¡äœTe¨s\†:L`˜Fž Q¼Ü¥¬D1ƒA¦á8L¦WÞyø1˜«jBÆOG~L<0ÁÚó‚i0ÓïѸ0ÌÊ0šÄ\È_`-‰âM$ô÷—ûíŒÑ,”pÖ5îÿ‹æR!>ny ž>܆Ĩ+-È3?œÆ_|ÐÞ‹w¯·DH®{Oꬱ¡¹ÀQVF™Ñ2#3†fÑë%Ê-ˆèL)j‘cØ_+ÔŸ¯f£`™Eý~§§ÎÀ¾ ÈÜÃ]™GÛŠ Tfàé> –K²Q³œÈ½žCH*Ù2¦Á[|Hc])°„{œ°ÃR¨@šc쮕‡íÃv»sX7ÖiMˆº¶ Wå4‰^\FcM²­šËäLQ8ˆ2¢^½ÆHßÙó4‡ b˧MÐþaË#¢Ò¨‰ em‰8=-)‚*:r‚²£AÒLŸ  2A;¥,çŽûôÌË2I+œÌù”Ïb Ú_ÓßlLر¡€ T³ÔÅÚÛÝ1âð9a÷(jºZ™²‡ê|œ%ì;¡½ÃxÞH¼‡„M“atö•°ëO•m}°8gí…d,ì)IV“ [Çýÿ•+55¨þw:¥Ï2<¿¸7j‘n@éó†PÞVp•{‹ù/Ì­Kl(JWbI¡!¢åZ”æ¦þ2žAT;Y-„•N ›µÑgÔ¨fG»«œuÀŸ ¡9©‡FJîüHw“0>À ¡ï÷ BÃ*T[õpP.9b6Š„>ãÓšáéYØÐg¡?Âð;L°îÀ‡ØU£¼ë}$Iò¼p¢4üF»Ýø¹ÐÅNÖڑ渤ê-,ºCbß¶<ú ç§ÆÝê?iîtU¡€€ %YÏãpüèù×Rô<.GO:м<‡»&ŸZGÌu;¿^xãóe´Zh;œ[±H„€¾¢WˆÉð‘ðiRfC¦± Gòz¾©E$G.÷÷֢Žgþ‚óÿj‹J@+qˆww–¡Œw®ýØÝUÃÀç v1£F9ÊÕœ4T„Ðú¥C/.ô«–烙=¢šrÿ]³L…£ù Ä©w Ä¡èò.ñ•^ŸÏä$u¹­ÃJÚÃ]ð²¯0s°µÜ\ƒ>6vRã4ÍO®:aÛD¬©Õ<^-Ñn –õíYU§Xá‚dóÚèG }ÍštKÐ(8âWÂlÑFœ ò-ØC^±Œ®eãË) Ç!©e¦Ú,N‚8iÐDþú¡&XÑ?ÅXK$­Œ‹iÈNêUÜ£ùô ‚ ô|´0ÛGà VÇÑKª‚t¨]Ôhþšø#@aFWÜF.-®á*¨77 Ÿy3²õ S…Âq£¤$µTáÒ³$j\B¢8|ER¥‘Q4ZGD'"··Q­½U—•RR;ΑÚhZÞ¸^F¥rL,£Å2ôU¦Uµ í+žÍVólz5 >§«˜Hv–´gJº¾5´žÑ>F…}0/Æ=<( **Zûú¯'oß°p4›´ÆW³QadC5_¤#/WlòÍé LÁ4¥ŸÝ ÐéHO 9ªOImbþo¯*+z¥#Za„¶WžPdp·³zð‚¢-ÉLiöIãç’ìÕè}Q¸ž…ë¸E¨ÞWG‹wßjñ~˜G—ówÜfNh6¿(È¥}‡&0…Ír…Ã%Ä7ýqé(é£ûýåþ'ïÊû¹ièccÐÈWMzHŠÁ­ŸÈ~4;ªy,;ê.Þ6pö¶C '§#™¡[ٜʅÿªþnuø•ˆ>7øõÆ?ÅCí‡ÏëEÙóÈÌ!ä¢n)…lSˆ¬ûIMÁ™5¸=(Vóe0%PLàË`Qvðã‚Áæƒ1œÉèG®4¬»`™ÀÌè~ð…sï¡)5vOeïTÆl“‹o«0­1Rþ´­ö"wiÌc8µfË>ËÁ‘ð•bà*¹*Š#íQ¶m€²63¥]cÖ9Mq¡þ]ð§‚ÝbLaöI‹ÊÒ5gNi¡uöÃøËþh [”ù‚ÆRJÞî7¯\Õoïèæå*Püøå¦DîÃlºö2fí;qSb.O½nŠyú0¥ç6ósœÝe6ã×[ˆë„1;}c«]Æü¹&ªh¬émz™—À7|ðšÉçIIt½ðY‹Úd‰zOÈÿ(ט¬ ,Úpm×>!{œ$Üz¤¤Ä+¨f4+‹R¤+´Šr1ZU ±ðnZ58Ø£1528\Z'—oßœ¾zs:<ýÇ»WTRÆ1JÀ|¿É[,qÿpЇÄËöe§åž±AÙ‡Þhi´°ÞØÃÙ2ša:oZðA Póç&Š4¦ÎÂëØ{îý>Ü2Ê¥¬É¾a- ­ö52(µáæfà(ý­ºÕ ìµl\R_Z·7l Ãç‡öbMV„kÞ–§™jˆw¦ñ‚Ú0$ôÿ„×§•ˆEÌ/OÓZ”¼WYùÜ ¤ÛÛ¶x¯Ã›¦v­:ñع Ë—·Gê‘Vô·>&}¿Ýðááýíf/;nÓŒµ  úC|+øíVû uÐ~¦Ó¤©EƒŽ F‘×n®RÝŒ3ºÑ—¼j”érgŒL‹½‘o<þ.ô¸q þ®ÒªÊ¬7éœ>¬ —“?× D3ÎK8­5FÌí”íVz“›Ñ!µ"«ô›IûhŠ>ý$C¥f@ü©$¨Çûrf×f#gd:æëbÎ'óœ¤V.Ußå—'C¹½þ's£/,P%iJ~þÿµ:ÿM×N—Åío…³¢Ã_Åm]WGN[­ìX—Ò¾ýQ!GKø;27Jƒ²J£ª£CáÓšNŽ_—Š6¸y\K¹9ÖÝÔ~²z8l«Õ»±-ŒÌuuTñpm˜ûvßF-BçÖ°ÉÃ$pÍ:%50ß_ÊóÍ”»B~!Ç—hfÒ_7ÇýaöÙuu€A½#VÔ|SÖ-–'=C xi¢­ZàHê Ci†"µ„ÓöÏu6"¥.ðo†”>D)gìðPì< Qˆ(S{Óåo¸T^Mˆ›¤„€þ%uÏ“z@à“!¼Çt€XÔô,œkÁZtAœD {T˜ëÍžhXŸ'—öï“‹e8\ôL!¦nnU.8²Ý¯ú@Í7i&ésé’i×Uzªäpqø\2÷`G£33L³[QÕÙ’¤Ì;güKq‡e`!8±È1ÑáÄ.IU[\Í28'pö¼ƒþá£?>?Ȧý&iÜò€ÚvtcÄV“9eðc„E÷ ½_!kéXÔ¸tpåD¨ÐÑ~šcÍìE7œh/”;¶Ä¨ÈxåO&¤mlȆ¹åβѤ€zêr®#1±¡^Wä6EAa>B# AG—•¬‚;–”¶²ÖëÊ%¤,Ë1ECuüô¥uÒ@œ3NN„ÄR´Ó\tÙ[Š0n…‡ :ÅàJ™oÜðtæH6“#W¶Ä«ñ˜|~¶‚ƒŠyyÎä;£Ë0Z†Iø3­‹ÍóIJyˆÀ3cò­ ‹ðš¹ðï1 s(ãÚ9è 3‘QA-èoü$OSŒ—D ý¤Ú,Wn=Ë®´ÔPv9d³ÞÃ@RË=áb‰“Ãõ :G2ô‡ÐY®ÐÛ&ì²Ýw§§ï6£ ÖÓ9zØ´@2‰ì8ã•.X}R¿:Ñ»‡';äÛ2Óå`)Ì\¨­ TaÊÆ ãÉJšiTšÅ2Û wÁϺj’*éjMX,ƒŒ=¹1€’;Iµ6îØ\è:¯L÷NIÀDÎNñ ð¶ævÃM¡DË%žX0ŽTÒÞÀ’ŽÊ’“ˆ€'d—šHÃî¯ÑÅüu‹Ó´g;œõµ¬Ølç›÷Ú›¢å¾pÁ×çûj1±}ân;Ëe„ÑÍY&AË“(¹¯[÷QH*ªÔ¨n;Ô8Õ·Ït¸Õb¼ÛSÿ ·kþr«ÿùøÉQרÿuxÜy¼«ÿµ­õ¿ Õ[šXQ |"ÊQÐbßF‘R!Á¨51lþɲfb»¯ýef»?Ù=p´jÓ ïyº~SÃ"÷©=ŠÑ. dúåø heåçé V`^ñò!pôå×–?ä|ÿ2c€`*¿ÿáêŧ0šð'£r¯G!‡jj¢H8g«ÙpÌÏɲӡýOêãCµÞ¯åÚë-–á,LÈþî+Y?†QZ\@ûvùIË{³šËpÜò¾Ï¿ ÆáÌŸòXÛ¼*Y Åćs¢ *n öGGŸû¿£§Înÿ·­û¿ÓéÛå"oÏþ&΄QIMþg€ù^·+Š+ÎÇ4û°X4\»‰5¿$lþ¨#tŸ¬Cê- ògvµA^á«?å„û!4ªl³ø¨Ïаê]†ÓÃéq¶\…âЋ9BÃXt¥{•Ùâ±4H ø°i/P W÷ÈŠ@4ÏXD{Ò‚é ‰ÄàÚ øÍ @ƒÿ.qá÷ïe -w»æqÌ©°/¨Ñœç!=LiN=½²ªÅ¡8 ?A%&´²âÂUüPaý­Mv¬çd\lË1&+‰?Wž4ÕÈ¢j(ç"­&PWŸ–O0"ÄÍ‚´H„PÂuÀ£<‘±›¿mà~˜P-9PËD(~~[Çm]&,4ðÒ w¸w#•m:Äïn§Jébž29Ш:•~û;°ÿxÀFì¿ã£§OÒöß“ý·Åö_tù5„aþq׺üXœ °W–¦©*ÖP5ò˜ü¡ÚvPÊex-g~âõ LXê§üˆfÈMk–.> cåûFþHzøl‰tjéqIWC1vŒ=Ta d‡"/= _ƒÊ™Aá¼Ø¬+…å(D9qË…òƒÂê“¶µîLëú ÈÍš:‡¬Jîê£ÚÓ#: Ò¦ÕÇfbåG>ƒ†÷gv|Wahšî¸úÈâ$±‚¡MëÛ]w–_ ¥Šƒ¥Û•ØB½ž“áԦ幣„jy"4C¼Pý4ÀSX¸)“"„TlPÁÜ&%ÖYãFìyeNéëqü$[%oòÙö#Ál1Œ˜5€‡K²5cPJÌÖ¦rlØÐ\©Êe&Xù@È­–cŒlÅCÊ!ÏP¢AkO•+H¢À2sé²~{ô´rñŒBÙù«n aÈ¥b-0”ØT"TŽRÏß Vr77x¦q\µó©^h‹FuÛE”zV­7ºƒu@–…] †ÂEöÝŽ£AñN#„ŒÝF)v¹*+Ãꯆúu{IXÝWú ¬”y×IjÙÑlkWÕæ‚\µÝMXÕnqäí„*ð¹Ü~¨x&Þ[éÎ6Üï?Òe÷[u`¼Á¯C¸Ë³ùŽgû:lÎØÏ9¦Ý„ ±ÀÆI”õ芽Às&3£ Ï@ΫĈ:>[A¬^–õ( ©:$Æ R*I¥B-Yö?½ªÐ¹%d˜¢†1—aBûc-È6=HÄ^ †z¿{ž÷Ϲ··‰žÿ9ß«‹jópêJ(òi]£¦ÓNÛÏ0« —žÔ¢Æ0µ‘âÈ>‘œ¦GEwÝXûÞ~½ÞÃp’½ÞÞnWØÞMFB-xx"ä¹âL'Ú²]àc¹u”rfxÕ•9^”n£êàÇ•ú¡^–Xx¢ëÀ¤©_T2RdÏc ÁYqÆE5ŠF¥Ò¹©eXuJr8è„E8<P˧ž­ødÆœÍ]ÁëÕA‰ä¹âL+ Vy&P%§+ïت€Ö¤˜Iª$"œì²­^JÌé–‰U.^ºÇ.ZÅÒ £§²Àª“ó¶ÀÝB »Ê;u‡V‘xÍ‘ºù‰É‘U Õ}˜•Þ—¬j†Ç•AkD””ؾ>ÓòeÂ&54Jí!îÜ¡`1]U:ø|kA»kA’Jšk¨!’—¤ªÊÒ]¹ÙÁN^Û ÌyQ™‚ãˆËEv˜lË Ð=ÛòÀ ÞnAèNûõ³ÚQóÑg¬@$<*Á§0N 7ÄŸõ,U(G·gaè>Œ;Ȳj‹RùqÁ~îÖ'…“‹û6&… ŠóĨ€‰ê[ìþqÃDL ëLÁ»y·‡jë~LšìeG.'k­:ÙZL¶Ü„63Ýë÷B™ePŽy¨l¤oz²¹Ãpš5·J)-B:™¹rs«€¡(kÔÙùkS˜¶~ ³P«º¦¡ýœìîç¡Ã ’>QÈ:hCÜã´1B©‘:”ʹØrµÈb±zŠoC",žn-η•öuëóžfÐ'øä“é•W™ÔI±µ™rëÏdZlÿÑT÷ëÔË·ÿžužö_÷É“]ý¯[ùï!‘¨q4!²ÞóVÉÙ£/T±i¹ÃdUùx)L"™Ú³i¿¶ÉZÚ*„Pi‹¥5ÆO¥ý1VªÝfÔábv%/MAëåš•r•×ôª¬Vè6'Fªó…ª ü3¨.ÞcÅwDï¯ÉWíi4ö§PÅ£Ìí[P茖ôàâ?…„¨íÊ ëЃƒ˜RÏžae 6QEP_ží7Ú탟/½|Ó¾šMÉVs8üöõ÷¯†Ã¦ÞÉ2€n~—j{h@•óøjæTÌTKU˜8£h(ÙCƒ7dj† 4Âyâ]FËqFÅH­m‹¹ Žüªk—0‰ÿúýÿßÿý?ü·ÿù¿ü×ÿò?ý?ÿçÿøßþ·ÿõÿý_þ÷¬[`ç´ô6a/1Œ/`‹0ùãŒßô™ž¨{Œü<™YèÒŒŸÉ£¯ßïødã#¡Yµà:œï_…¥¬EÆE3Ö„~œâz¾Èå#/èc ª1AY«œ{s[l#Ÿožm“Ïf!\UZ\Á¢¤Ê»F„‰®k <ËÕÔ¸ˆk«›'&Úœ¥b+rÒ7J5$¦Åê; Aæ{A|6šøX7Ž|ò‹‘N"<ƒ±¼çDß\éAêô¿T&Bœi¬´¢!L©v‡éFAê#Ò‡ù™–|ÿnfæ¦Ð§Aä,¥w¿çÚÔÅš4'…aª\4éÒJjZCAçõRÔ++¥.rzJx–Y^Xcœ„Ó)×pP«ì*#ú“Áâß&Âý¬iŸ‰1dAïb0§?™„ÌWϧ^F ²›fŽnÁ÷bAÉ_O²Õ„u-Ñ—u9|áÚ^â­ %Ï2œT¯m(XJy•^œxçÑzsͲ<œÄœ‡´^ãä €•>|¬sy…ü¤-¡p;Y[~¹ßñºžÿssS,ÄÙ,µòÅ›â«I ¬@Ëq4[LƒO^„mÖ M ³HvSWQÍùdÙ÷zÚŽ8Û„~L+CWl bkqzyÔݤhÄ §Í? ˜k"-=ï¨+·¿ŽFÕÏ¿]àÓ©V¼» &‚)6l^WÝ2ÐNËìßÂyÒ°¥IîC‡ÌÊh/tíã ZÜ —qâ¦Õ¡¯–GþEHð`T 1iŽZÞñè6ô·HÇ3¬£áSä__½ßGo…™ªÞzÎTª`DÂÍÉlê;–#Iwxå`Zb-¼šÓó:4ÝUÊæÁp¸A¾—š ¦óí.Aѽf›eL¦˜qt–t™yÄäFz~vö–S,-æ&º¤ƒ²rvèçîÄFoñ‹p&þw Ì:ù´êyœ[|pî\%uºGôñ»šyÎ •TÛ˪µÞûã½ÞDÍ„DQ$dô€à‹`ÁVí3ÒŒ+²Ü¾sõÙ"ŠÑ†ßgè3i@`ê »FÓ{jyð9‡ì4ˆ  ÐŽJG¥8 q§ƒp¬‘#är@<ák߀P@ÿؤ Aÿ´–œpën'¿xCˆódq5ï16u+¹˜ëkήóWÂóŒÀ J;¡±:[¸Cz“>ÿ|—´Ýí¿Âk~öø<Ãö—ª¤‚ ½$A]x©sy7æb`ˆ~€h|<úâ–›4ˆ¤/¦a²ðÏøóƒf{æ/ö?ë‘96"‹Qâ ¾R8œŒi悵4Гí¯mÛüõäí›6ÒÖÆOÞRó¯æ{#oìMn ´Ã–Çþ7ÈPy¢Óg±@5ŠP_„íD)Í/~ ã7·L’d‡þ_³Š qh’Äû܉үO+­˜(ÑL;ËÀó?úáÔU²`Û¼u  Î1[²Â›õÏ~ªbʘÒ¼çªI3_³jÁ¢BiÔDV—äûJv¼Ï>c~ÂnÃANá=É![ñ–÷\•×p6¥çnÈ5Ð×{á^¯ÓÚûi¯·×Ý»ild}m¯³'€465¢ @Qª—ù•7ö§uÌ0ð-“§ 㢠^‹ƒfÁÀ(2›­¼Qv“‹e@ÀþЍÎ>¼©c¢i3Œnœ§ÈáÚ¼ ö²rSACª•¯¤9Âr´q(¬Ò?[‘ ø( ¢° &¿6ÞÃèàhɃ­ ¯±ºBÒY’šÙ²jÞ|}±<_Í‚yò þ*Þâ¢ðˆÞcƒìB*—Ü=<±¯²Ëj.¯üÕòSj~s#ƒ$ƒŒ‚”©UÚvŒ®6 ȹ°¼r¬B™­CÌ…úLžSò Úa<ô¿BPìçÆì»>Nþ½Ò£ñ¦CªK¢º¿"ºð—ø/nÈÐØ(ªIc1b\ .·D ;çê'\Z {=ªnëhÐÚ#ƒíõ®÷®ˆF¹Œ¢³½›Îe"­T48ûhW:¸iá“#ñäXû_+üÀ½ÑõXe@³˜ÎÇØî`£+·ÿià‰›éþGq1%Žr!y'EòcåÉ`+°°®h"ñ’D_BJ0®*œï”áNî”áNÞOeÈ·„T¥€òxñE´L.ˆ…¸¾i¨v[›R”-¯ÖUT)•‚V4hû½MúâÑ*_î=¼¦ïú½O¬³›¶|ƸÙ+§„У Î§-A }0uÓ¦Þú=ÇIA í² Aÿâgpû[Ÿî9(¤½ãê4¿;•d@½½:hšÌ‰7ó?Ýy@z÷RÇ›{umËGþD5Õ¿šªr·” ¶óu#£hÚ;éÈE1Ãp¢i@s (ª˜…M½*sþÈ ae¹b·Ý<*\ˆªˆÃë²Âz%È|bb'“Õ—ûõ»¢÷ï6ApÛWïìPÃóªaê†MĸKoGg~8e;Åy$So„±»z%îö$íî¢r‡a…8¢ÉF3õD“èÕÓ¦û2ØL³®Ša·žiWlÜÝ5ƒOÕ¿yòëjõÛ}·†(;[F2ÌÁí‚0×J¼e©1ì)Wá)g>–5 o™]6"Ø¡OÙ•›‚´“ ‚a]nrýØËÄfcnŽw9vfÖa­Íê¼­¼Ç–tÇ»\Æ.æ].ã[Íeü[È`¬ÆlµGjØv€¡ÖK¬O3õ¦´ÎÁªŸ IÉØf œKy¡O;0uÈí9ÿ,-§VT÷ÀéüJÊò΂JÞ¼²‘õªfá1•ÊU6™h¤FÉXã üì÷«fÛO†³(Nö»ä- Ñ†Z$pme-Ãóp®(½Î!ý„ì8¸»¹•²H¿™ÿŠë?±ŒGk€Ê¯ÿÔíw;Fý§£Ã£§»úOÛZÿó*F¹'VŠIùR”ab¯Ìv©2M/Þ½öž)¡"jQO”AXüüÄëýGs%Gnw8±>õ§¤ój°ßárcU„V3Ц×Ì&®Xù#øk`ÜAv„šv²`Ôö?z›nV›nb–Tß׈KGG¦ÃPì껥TS×ß îòé’=9ÌÝA$K²F3G_@ÞãÓ6¼Ôv¥V§m2>AïÙ„‚0g‚ˆ‚åvÊPt”™W¤Í2Š’¼»/ÊåbçºJKeߤ¡¿õe #ÿ\+˜™ô"÷kËÆß™EL 8ÄUæ8ùk`M‘6¼ê†¶èSº¾³ö°û™Iì]E+o@ˆ1/âÍ. x ²KŽÃI%òwôªwV±l AlÄÉêìŒNø2{àÂÝïµ9„w0Uš:¢Ìy+àg÷hH7ÄàŠfa¢–ªe3â9«äË„º—¦þµG˜y%[¬sšæ%ê¾ôž õ˜µÛ»i¥úòx_ÉeÔÈÿÆöá¢(Z(^ù :«<áli⸠f©ýgr *mój‹ˆ–gŒÃÖªàíû°¹ hÁ™‡S®"tkÕüØl €vàF`¶“aÊ ãÉ0×Êb5 c¼\À#æ¬ô¿È‰ǯp˜çØC÷nfc¯É?zçt ¨‚šTga0ZÄdb¢çÈ 3~¿ 'Ï;›ßǼˆ=渇 N&BŒq4!Ý<ø• t¹µ[Sv"ñÜËÏ~TËX´DpáPj¿¼~#e{7¼{ìÕþ…­§T/°ÉÐz²ôbòÉ"ÁçËhµR™*(ÍðáWøoÐÇ´¡ÏáßÏÒºâ™jàžü冦4³ôå2?ˆ«ã+û (©}ÚM‹Àâ²h‘vY*”Oz¤õ‘s¡4JngÝV-?«g%íyj‘n›‹[7nÜhe.¦¬wlh4 9vÅLœ>t»Ï¯[¹–¼lD¬œa8šm5æ5J\VeÉb Lqýµ4ÊõçÙæùõœ.Y-ç1úÚÁÊØ±Û÷pþ‹eô‘˜×ú a;ЛK¼›&@¯ÍŽüó‹ðmä u_„–¬NÈUpÇ2©AY  C]¡Ù¥UûÈItÓ‹G½¬£x{âl«?¨$ÚàÿØ&µ @¦xç;kL¾ÀÜsµÉ³ °l‰¶}m‘iÛgë)ddh%i¶"x+òl'V¦¶¶uÃ]L/øÌirKz­\F£/ˆý‚±ªàR7’-(àÚ8­"Ÿ<ýöÌàU.Goîb㵇ôä,·B§—f_Gul—Þ°) E \ßܽá ƒÙ"¹ÂçšÄEdéSճѮ‡yƒ¹¢/o œíWEöD—óa‰“w6…óy°n.ŃiAÜE}+BµØ45,6½ÝÅ`¨ÎÙ¢…ÀF‘e4ó¨üI¿ ÙÉisÆ?©ƒVš l’Z®³Í…jdÚXd©€Hu¨•ÏtO*Š8Éoª^É_)³dÅñ_Á'œL¯†Ñ<FgUÂÀòã¿;Ožñ_ÇÇÝÃ]ü׶ƽ¢ñv¼=3‚ÀD»ÆCbý;¡i¦A²ß‹ÇÑBM~’,WcZ,ÖÜØôN²yß_ž«ÁÈäO»MøùÇWÊ<·fÐÂMÇ‚¤äýÞ(€hàÞe8Èœ"gËU(,4l/æ ´áÈOh&ÄÉ:@‹,Œ-Z´°å!Aà[¨Tñ }3ןN Bq² ÇpþÍÏ|Ïäq UIB˜$× Ñc7|þ»D‡>!æÝ¶K…ýNÌÓ|!ã=í\-¨ÒB žäf$·}Ù0±*vyi^fá'žõ£Y<‹Á‡”Á&³ ©³`yünÛrùó‰?Wž4%}Ô{ît²SÊN+NÝ®D³¬è ›°qÓJ͵ݽ´B1Š|®àÞ,ðüØ‹1p'Î#MhÓðžÉoÝIúˆ§¿ÍáÞ3‘#z oÊ1Eã./j¦hŠ`âÂ\úu‰[¼:ȤN9’ ïâäNº} µöÌŸêÔÛÙ÷ßþyÒÓûJ·@òíÿÎÓ'Ý®iÿwŸvwöÿöÚÿ Cp¿B¯x¨mˆ&¿ëõÍ«o_üøýéðÕß_¾zwzâ=÷ú æäABÚƒ®ùà¨1hŸ-ƒàç@»Sòì(Ð3¡Èü$Y!;vCq*ݱ¶}0ŸyÞŸÙ#ï—_`êÝÀ¾ øçâcΔŒÌÛ«yø/[ìôÕÉéðå‹“W€ÿõ%Ì.öÄ3; îm†öÒ$nsè•HÎ*Âö¼¾æ塚&á—ãžw|xŲ'W8";§À;>[|É:ƒUo!-PÏ&ôRû8GGŽÂ骃°Jå#µGÑ!çºC2†ù›œ¸# ÊaÓŽQ›bÍ:0dµ±¬å‰Ì-‘Þ7SãÔËÄÒÝoœwóhÈÆräÚ¦xbCLÿ®4nxVãˆX°mÐÓH\Gðñ:›£òó'6 ¨yÜl±’<¾ÏJ’²sM]YÄfg•y2°–j=¾/ª5½C¹'Ï÷e LõL_µÔwöLÆé=7î–g;›èå¸_<±wB°õB h{h6¤Iœ²t¼‘2Ç´G:¢Ng°9;7í–AëNgslìlR²E㨰õ‘[['• HC‘^p“ õRywDäð~sÑI#¥K2ž†¦—f¿™y'åÁæ:'26È”þÑ ¸‡£Ší×5eÅYús}?á®U:‡í¶»mp9èdO×NÖÅŸ7ÜW­&HVU½ù‘¤[¹øc®Î'Á'Ìz¹ÿ¡å}l¶¼aøKªQvjš?éc¿Ç 0W&+×Êf‹Æü‘Ö˜?ÌLl ™>˜ ]$^ÊKNšÊg¡œ+¿ž£ÙÂO ,Ô[„Œš½^áf=,ѧ®d>·ßÅ|`;—ÎŽõ6IhLTêì­Z:§ƒ.Ke:kÇþl1 Ò5ŽÍ=˱yyËñ‚¯pnЫa0¹;x‘[b‹um̤¸UÇ90¨ÿEËû#Y^wMy¹þʯh@»ô­ßs­ø×ES¡ß0£CíàP¤Þ¹š¢)SuQ177ŽEå©qRMÕ9ÓæDÉâ9Àñ‹ä¥HçÃëð¦ç=¼þpã="?’>MF4¸Ñ*sºëÂT2¤â´ÓT»ò\æy&«'œwÞhO¸î  £„u„O´é<5ó¿w»wöß¶Úï˜D†Ÿ‘|¬ õX*ᘜiú–Yæ3S¢ñì7RpÅÔ7³RpïÄø9f Í„ýTBÒ—ÓH×Áô-9虋^gjs˧¥¥¤ YIÅyoD!Wœ·R(ª²Rà.‡"¨âŽŒ¾U‚lÊvÙÞ°aÀ×gû`¬bua!ËÊx5 æ =J‹æc¥Ll#ñ iÎ4H/´$EÿÚðúÁ±-ÔŸ„ˆ,L¥FH8Ó)¬'¤³ŽU°&‹“±ô¶4ujæä2Q ÿ–ƒ$E9ñ.Ç2¸Œ–bOÛèg Mn}·œžV”Š;äò;OIÛHуQVŒ"µCq{ô³€´FÅñ?ôÔ zôOaþ¿ÎñÓÇFüO÷igÿ³µñ?ïQ"Ü3ÿ±WF³ºn7òh²zékôlÑ}Fê µDŒôýG?‚Fro+êÁj¾r7ÈDåq½\Fþ ÛØŸÿ³‘@)éy8Í ƒ©©S xÉVÉÐÜà;Æé¬Àº„ß”F¯è.ÉYbð*”hDÄÆts×T¾ T<³Ö‹1ªZ Þ¢ŒënÂŒ.Ž?Ó-n^;Œ…€éïÙ ‚¨Ã9l-–¡Ÿè>$jè D¼o´©7WÌ´³ƒ™,eå(†æùuf[„†àYZáÎê1ÃŒÌÀG¹\W¦î¯mT»4åSsT͈LGгh.7bÌÀL&o#üÝîAzzSÔüj«kÜðGãÆàÖ„$®,óµ O†‹5 ;‡°¡[ÇW³O²q5¦a Ì…É9(W…ê°8dÄœ¬™þ®N¥×ʲPJýUÂlŸ”}qtYÍcoÛR¸yGˆ-ôéAÑÚg‚~·àjYlK›.w1°ôoãºI±h•Éa¹r_¬¸c«âÚ´Y¦Æå„° rÛŠm±)F'½¶Ü5>ù ŠƒÔõcmë²`å(§º¡›ž½"ˆ¡ô$Î:-·Nw··¾‚Ðaéàô‘’úÑ^êM¶"ÿ•\-öÿ®QøÅÉÿû¸{|ø4åÿíîê¿l­ÿ·Zå—ìš/{ñý¯hÉ—9›ôb/·V?Ü[y†'Q†¥¹Ê.ÃpüœšSF &a‹}ü·é2(A@×Ó$¥zß|¥›2´É>ýÑtY¼!Ñ_]2\HT…uËNX"D3y¾š9оTõ4× ¸gÌcp¹HrWà·?hTKžXˆX*ãµ*@;ýÊ­~YIÆ ð¦ Ï7…}6[yý&kÎ|–¸ÎÄ?Ä “"íVìMÃ8i¨tâÙYŽCé/b?kÀ ?f(¦8¬$†/…©3”©A¦ ÔÏÚ 8ó§Ó‘?þ ®pl¤Ÿž\ÙÇ=¦(š•RÔyˆÿŸ½§knÜHÎÏúXmH1M‘”ä½c|^¯×çuÙk×îÆ¹+ ’# ·ÀHieYo©¼¥òœ·\å1•ä%UIª®òkâKò/2=ÀÌ`€DùȪÕòc0ÓÝÓÝÓÓÓÓMÝ6Å—*½N)QyXØPÐ뀂®—D&Lt*¿6ø­B^(.+Íí£-< Ö¦ÊhšÆÄëÃ÷®öµÀwÙâùKçJH/XšÍÁ./ÇÙƒ4÷ŠÄ•ó±Ó³6Z€é8Èôóš ùG…ÐuÆJ«¸ 蛲̅ q“¶î\E®Ö€”Ny‘Úvð£Ý}E3ä‡iìíSgL¿q…å’•-´a•èñ.ÖŠ$r Blj“¯D4…zå‘Rùœˆ a¢£h!Z&£)´2ãï$Ôl Ø÷¯÷|g¼oõ“ñqØò@_&Mn=UYb)PÒæ ÍØïðúõà ]oذوUƒ¾S¦lÖ‹M+Sb°sœN;ÎQÇ9ÕĤ] «Á†Dév;)j¤’L6$Õ-Õ©[ùZUšEKÊJÓ™ìkÁž/󊒮љG“ø¬ª/çq4±¶å © =µ§p*Á-ûÁ MÉš¼uK:P|$ÕƒO5®`Sð©uDr¦ ¹–Ò ½¬ I¸’Ýÿ’OJ÷4!„¹Z~ý ¨ ‘íáè­n¨¬d‘æÐ:uÅL?LƒmWÃU<~©‚ìQd¥zO®å:d×ÇýsNïyy“Rh+Rg`?*Ù±Ž+VŽo)åèÆWb «µÇ*GkezÃÏÉÙVø?ö)Ó.Ü{\¢eÖ+„Æ3€Ž¾&x‹ä5<4ÊÎ%69I¡1`áÔ§–+eC”ΣÜ'͇Bô­lFPz™ V‚u˜ "ugYÅI£ß+Ì\åyãP_øWHž3ª1‚;è I­Çm³ô$ˆc¡r@Å”|=t³pÁ`V2‘&€¦q„?²½)ƒ““ï”xŒv„Õš j'VJ9ý˜“‹`65 Yìm«aÈ ³]0…ŒimÐ÷uªÔD$»Ü=Ë]nG¨ÚZm¶D°‹ TZSù ³…70kp¹(¡¶âÝÁg?n üö„È7zØ€ÆWøšBnÞ=mЊ™ÖŒXÎá?^¶Ôá¥.¤=æ ;L³ùp´¡+m…½÷Êt)ßh7Ì*Gk3®ôl=šÀÞR°‡<êáòÅÁ„eR¨„\—Ò %è¤ÑîY5J:t1}µÊÐZ+!]Ø%A-|™ÖWf ó~؈ˆóî˲…œB½ù»?Y;UÄëh¤üº$ïù4ë“°ûóT Ù¹7QÙÊ=‹£K~J°QE¶¬2p¹E C”ª\Yyô(—è2Ê5R½fEô4,¦Ðœ’ã´>p\OIÔf-úbo6‰eEw”#…Cˆn öHÖŠnb™`ÉN¬M¢$ ¹¹G³È'®Í‰ƒ{#Z€wJŠë¤•W°¾A¹-BLh©„òQUd øã˜ÚÃ-ä´vªªçͨúÎÛ $÷”3q)QCXE~»¤«è`Ÿ¤1=s‚…ã4\…cÚï5‡g¿gemY Í¢sâêã9v§ýÞ¨9ü w³kÚFäþàÛ…%”Ú˜94% ±ã$²H‘SkQÆK#ý„‘M)úè¾ô#õÖm&±²¨²ŒlmÓ$áÔSWjL©Þ7¥,liaØ*Á×j¼ ¨{&˽Âf^tÙ].I%A5Ö<צ0þ(&íÒ/ÃS1øH¬[+4Qó93Q¡!B£ ®ÐÞ@Ûï‚Å£Å2÷¨_¢ é¢óÎÿ(„bÛ&±—™tOoBÿ2˜JÜÔ'íOhšc”hŠ_J¸¦vÅ£‰ÉE%™_2òŠ ¹Ú{~xŽ4‡lšö†xæöׯ¤¬&)¥Ýç³È_dLÚëöº],¤¥Ñæ¹>jÉcøÈGa¨ɯ—ˆ¡‘ÞQ €=ĉrb‚¹( wòÓâ]<’!L‚)âÚ–Lq²Ã‰wÜ4+•`stÈ퉌'íÑIÄ‹ ?ë~Ôqž€Î?ìà¹úù¨Qü”»=:f!Æé)¹<{ÑrAðµž;×o(„#»ˆœúb•P/§¤QÍÜž‘àtn/ñÏÖøk&»Ö\W¦Gb‰¾!J¢Ôy† m¼,ã+ì >b¼"º?—Èm<Ò2& ¯Ü^¢„¦¥ØÒ+ ›†2gx¾KøÒ_L. š×_6r°VáPAœ[ñ©Ë&ÃJ›• y]J¼½G(ѧ7p$ÊÐ/ö7@j€šŸŠû¿yÑ/ýXåsP>ìâócO‘Ó~AiJĵ+ëêÄØceXfsËDÊõ¸“èl³±WÄj¼1X™Š‡Ò”.yI/Ò+Yé[t#ÇZ–-}{PµŠ éàR`ô:ͶÌ=uë೨1üApI¦](óJ·­ @3¯éˆ ZWr¡ÀT™³¸ˆáJ/oΓ6de|º[€O‡RÏDQ£úD™ÚM‡Œ!Û5ôZ#Å›¨aRèY\ ¯ˆ4s¤09Œ¹á†nÊÓÇ}öÍË7Ï_¾ñÞüæÛç®sò1¦øY'dù;€F+Ïå—¯¿y ôMnZE¦%ˆi=Ê”MBlºÆïÄÃ}˜M©ÆSÁ3Ämn> }ì<“eL®ŸÆˆ*!g†ü·PÄzŒ×óGJŠ Gî%°0h ¤ÀŒó…Ÿ\Ðß­V98óéCëZð0“%†?iî©®¸aîPë[*×¹£Nw1+€Lá½sN{#’ø0›‚â%qÉ¿òcb‚A¥TcÕ•ØØ[Pà§ä`ǰdZMëå ‡ÂÁüa,U8Å”B”,Òdê–˜m"[}„Ï6Ôä3Ï¡½DMÁÑOØTMÁŸØ‰ëC³kÒ¥RÔóeB©ÐÀ“²˜ÖÖ—Sþ*û­­­,5ômäße¥~]a7›mò`>ƒ4ÿ_«ÚL‚¿<K‘»|ጋÉÍj·ŠvóïM³é¥û«ymÁ%O7ì#ûS³øZ÷ÁˆËîè'±ê6Æ–--¹~†YdE[ø7˜\°›õJ æZì ™Îóȸ’‡ØuITt-aÏÂ¤Ë ›µÅ(÷ ±¹†cÃ2=1ànB8Zo‰RLÕ”²"Ië¨a~ĵPrõ™JåNš¤šúÅÌBrȯL š(ÖÇe4]Î+6 YÉS8Ø/Ÿù ȧyŽ„›K='pi)×ô ͧáðS?AÒìÃ!¿sB¥æÑ\ôB,òÆîûÒ# ´Á’D±óŽô‰Ñé’Áœ_œè~[D#µ+8‚ÒemÍÀæP`ñý„"ëž-g3ÒeêþH(ȼë®s ùœÇÈ|1œžceƒO¢»ˆÜ] ‘§MÜ.0d]Á%t&9ò:Nöžf²¶³º5%®¡å"2·³;K#Æ÷ oÿ¸Åš¡p¿ñ°"œú­`e©rÈ2eLuWP46GHï4ƒèÁ9±¢dŽõJv•eXû)|Kê6 X"’ã&W`o|¨ÚL[ç…dj~U+8Î~U8T8-æCkï®k> p£ç£ÎæC¿’ ÀÂ:Î÷¯Éª›&RÛ2F¡¥ ËŒôë€-ýbkLí§C³0y㙾ÒÒ •—#u“F‰ãù¹³w‡&åℳ¶¸&˜¿/üpŠÍ]Ó*  ŸZÍDèj$p:§6^Æ¥ÌÊ@l]@ž3FLâ³à¿øXD¦Ù7ŸFcp^È@BOÈÐQ”ˆ>˜>×ävKCs ¯ºXó®40³"ƒKen :–3Pð±óò›7χԸJ;Gð:‘@¬,ýõWð_\x·†õQ}$Ñ3–?Y,I¢wÐO¤ËaŠÞ)ƒetJìJaëÞmÐMŽÞ¥T<11Ï­“1ŠÀ53ã©ä*ÊbNžZžxŸr-Dm˜¦ÉØ|ÝØlƈ¾>5¦Ü–ÂíÓ°§åâ ÁŠlžøgK+%r"Ž£ùÉJgr%5£9Ø6kídx› \E»„B]ë)µ03:b—C–.–7îèþØg±‚F\›??§ÂxÎb„/òÆ£WƒSäA¥àN6@w÷ÁNºpý怪 ˆ›¡Œµ†#Ð9VUh‘ÔÛXŸ§Ô³Ð¥0d}G†T,"È Õ(Úçñ|=hk:ª¶›Ì_wa¦m’$Ñ|±’h:²Øâ¥Ð³ÈBrò“ÅHêOä@[Pí±œ H/ôÚ‡å¶IµÌ-;ýÁË . f³ú¸€™mý —‰l\탡T#[ x¦‡Ä„Ê^wÿ«°Q*0Öl‘ÄÐÊät"oø›çË8šûçW~xs‰¦¨I¶"c–¥ +6®ØF™lUp3Ž{Éìö ›ÍA²ˆÖËr4”ÉêükO–ñ€ê𨛮ּ «ÞrÀjŠ¡z½lT)’a ÙA'l«Q>­Ø©Ù9Pgž¨æ ¦ûY¸çñ€]Õ+¸¥©a²1ni•-¶ê&Ô+R[u\V÷U¦.Îz´\ÃNÞ«êFügö´®ÏNöcl +ª$uæ:/.W ÒZ-(3½ñ®†Ê!,âÊN¹Ú9Â2í4 MÍ±Ž „m¤±­Ç9Ž0CЮ@øè/üò<¸Ba9¦k¹>Ò 4±tYÌ*­Ä¤\4 ŠÞ­„8~Àkõî h»{L»Z‡´xw˜²6× f|.´›`Û´kíkNÇü`ÃY$lЉ°%÷ºe½ìebð ù!È9ë…ÖºÓޱ—%Ÿ©Õ“]¤%©§HIñ¡R[Ô—¦Dì ægÌ›ðPd‚UsÄ™:%›Fcê!kpa(Âw¿Ý ¸š#TôØÞÛõJX"rìW|'´ BN1Þ9iÁë~Ó˼£f óÍ·S„æ$.(±ÚdZ’¢ãäôJj3½K;î°Òþé´Óa˜Á7ËÈ­Ž¦øž.j-­’¤¡ºr¦ÝXÎ5Äãh ÌQÕê¨^FÆ]°;ì@¾Ž#±°\u¥cuÖ@aT8Ú|Ýj7yÌeó7!vpfòœ›°¾×9±aAá¹LÑ ŒÉ½«àPÂIÇŸ6BQ]Nå46R[ÅúƒÃ à-+™ Í(H!AádjŽ™¤œ ¯=©¦Ñ6¬Lã%º/ÕSðv´HѤíWŸ'Sl åÖ¦"»-SeaPýý`2%s‚Ôû·:á,Ï:ªŠh6F ÖÍGæ@ÍúžÊ¯rÅXÜè‡v›AÙ°x¿¡ýÑf`ÝÐê7t™#W¦J‰FA~ÇÔ,iìF·¥O–aŒf¾VFŸé³fÂ"Z›‰=–ãÚb†z×ÁÙ ìØ ƒX&HÚÄGy–Ý{@É*+^E»£¨˜ ª~Åö抃%E¡]”£û&úaô•°ä(9ølxzÐpôÁ©0­LƒAu$ˆþŒIlo ¸gʯΒ¨YŒlò¨#d-îðoagá;Ä-ËI4™!?†#`Å=HoUÃ"pš˜0Í@¹t… \µ²ô¨RåMædEº¯à°‚².¹«‰ŽCƒëð¯°aý ëøžr|'ñŠÜé°n%©{S!½Ig …e3LŠ a:ˆ;-ºb \£[TjöÈ5ž˜Ü³QÈ6œwñˆˆÖu9ʽlý«¾Â:%9•œÇäoî,CDÃb7ÕU‡ƒKcÄŠIåòb¹x½@³¹zЙ±-ûUåS&~ù„tÅRZXʸ×®4Ÿ×Û#q…ôÙ믆Ã/(8T[Ò*๣sâ|MºìÂÂw mI÷kC;OS TËuŠÍgNfË)5ƒ– dGÔ,ØZýÙ y°ÑMóû«L=Ã¥®…JÊØžoP¼¥*¤ï:™[„·BEy ¥¶(öÊÚWœñóï+ùáq{3#³Ö:ßwN9RLG¥ÐS}˜žÒk ÏJ(u86[GäãNƱ#[›3Íaíâ/áØ(žb-:œØúòƒ‘IÓôæærͲ:§C?™`Œ¦(™ˆå‹X¯§CöGzâoLã¤ýñ†åƒA£ÊôÒ_8C¸U­™$†%‡èEmòá$F°…ñüÅHyˆ´~·5áÙœ™x«Rœ‚ÅËÒYéè0¤v9‚ÚDÿаÕÈRPèH³†á­c˜ÜY•¸}#BÑŠã`šeÕ |JvǺy0ü%ù{òÒ²0X“ØâNËÆMN€óïm‚apdI¶TºÒ°«-¬jEÙŒò‹0 onéͦÝá.WáÆB»wnµ<¬¦ ÒÆœdGÐj­•\Å_Œ“‰×kv/:Ko9çž1¦ažŽÜ}y¡yUIJ Jv†n¥Oºdlß©É/6âØ#>AÒ·å¡g¬ê·R[9Õl´‘?¹ÐÛ˜|Ñ2ž îäð˜Â`˜®cT`«^¡Ù8ÿí2˜¨¿b¤ñRGê{xÛFzïÐ~:ì ÑŸ"Tƒšé4£›”ιðŒò€0ºædÇ~Ö¸Sl3$Ȧ›Ÿß–sürwñÇá¨?'çXÉ3,!Ùq€À˜ ‰ iþ[ìdFé„’ùtjN¢Lms™ èsm¢çAùmlEó¯ *Ù÷òÏ{þËx³V䙕¨´QøÙ,g—K–'½Ã‹V\UV±²וaÏŽbR½pTµ”éí¢SöBÝ]¢½Ëô·ãpÒz)i˵8ÆÁXc+P×¥¹–]Ńãq“MÖÁ¥<[ª[‰@GጘnÁø<"À\'ç–ŸD‹ÉEaÿwKÿ*XhÚè0£vÒÇVG/¿däQ”dJÓ!=°ÁzP íA†÷  Äîê ñ¬™ºcŸèÜÁ¡<%_ö #"ÿ.²‰&÷NµÅŸs_¦ÍF±LKÓÞq¸Ä0p+=5Ȱtª2™)P c›XúKTåN}­W¢ñÊ´¦+˜ª «LY•**;%Uù\å¾ §ÍÓ#÷b¡Ùj {=akóAf'ŸÇNñRp}C*‘àC°ίb]Âr¢N±müÖVÊ }™…^PÝF¹ú¶c5iÒ& ÔÊ”'¤‚¨#YivB]!QЩlGDÞ:ð-óUÈr«­,K5/% äÑG í·²6D4ôt¦Ç¡;ït³>?§0üÀåÎ{¤2ÖƒNQOöÛvyDÏbói ÊšCÕ°œò‹ÜBZ‰é$ži¿YºSKt< xdÚp%÷Ùæjý øËîvQØÔ5Cø^^;Úñ¶gB/Sq91„/œ£ÿɸ ü…Gölã‚EážÃ£(Ít ^η –!І+@nüNÞ†ª–KRy,ˆ³¡›y³ûßÍWâgÍ®6½BˆSO¯Ræ6õv\e?,]+³†që²iYŸÑW ÷°EÏ‹BU;®²lèÉÐòV½lÖ­Ð,;< 8þ¾ðÞnÍÍkýO~o^„uC›seHãîüž5õÃÚŸoŠb_ó>µòFôÁ¬ Ö„’X`å}þFѵl¯{[%êÍ¢˜xi,“ÕV²`ª‰bª`l¾­­¸´UpumŠ  ïòp¶êåwLê\PqÛyß”y¯[3µ`¦«‡,n§ºu· E\‰+Òe÷ÌŸ%P  æ½uX^g?l‘…cjô@2Všó™ ¶Ó ÇœEQZÜN¾Z°ƒdÿÃ_ø÷Þö•'ô*ÖžÇÄ|@Á‘l>ðǃÝx¼Ê½~¯÷ÑÑÑ{=úRÿïõŸ|ô^ÿ°|t|X‰0e\—•1§$,×/€Gb< ß½ÀÉÂmƒ!LDm–ÄÞ×3gr˜Û48;C¤ Ÿ+’9…¸‡!_1~h‚wXzê3ùL“+‡KXfyqw©#àÈâ K(d©UάMú¾Š¾Ê±Žº¨dQzÍ®wÐUÒg©NÓí¤?8®ó (çô*Óð‡;…ªœ¡414lß ¨~›@12ãAËs!³È϶:gÄl¹½·—YZ2Á÷Ûb»z’z°\óé@na<9âµ›HnvwÀé Ñtî³Y"?½¸ðÉ‘“Ò ©¨í§H¼ „ËB´ÊŠœ|‚—¾9^ý~øáÿÐÕžÈïàƒ“¬Eq@aE‰,‡ºßÔë׊åìÞÿµoõ`3 PçDT:ë…ê×q°È¤(‹û "ܤ—‚ß A«üÑ»üF ©Ç~¦åùz:ò"¯ Ã~îÄ‹;ý%ûtÒ_Íå‘îÆ·ÛŸ´ÿ7óý¯Åá[íü§?èÉþßþqµõÿ¶ðú³¯¾yú™÷íÓ7_t—arœ-ö>f¨; bRTÖó>ñÕsÏÛßß15ý-Þ1ÂʧÛ4 Æní.’å|Å è`'=¯"©µ\á‹x9¾9G_=ýj¼ §38Ïú”¾éò_xI³^°Õ¾³óYŸî>¾ÕƒpwÀ 8ø ,»£.»Ûàüp†ÛC‰7Þ/|&ºrçEÿg!Þ à•f‚<ÿÊfàPò°¥çÏ~$ÁJ;;¯^à +¶>Ï‚ó%1mœè§¨UŠßuYy ç•?y;¾Á‡_£ÅE4Mò Ãáð5…8­™µ#U†=Jî~oŠðª>¡eíd ©±µGnrìãÅŽìýå"˜ ‡/hex@ê5-Ü7`ÑÂ;ŸEcö/„„é\L`ÅóØÝyÆßv¯‘?Ú.,÷®ÿ{ý$˜xþ›(œDSÄ…ËÎÿ¹óÿþÑ“­þoåÅ*þ‚ÒØI««3åA¬DöU¦Fà¥Ñ‡d<³·LPÌk£'ÉuO³ºû)´#®(^ûÑQ—>ÿÑÑÖ»üÉ»áã[þìÝî6œ¯eù'NpáA4ëzDßJþÔø¿ÞñVþ7Yþß¿ÞÉÜ_`Cˆd¢Þ{ïg¦Ñ%±O²ú·Ôÿåѯ!zúöŽn_!Žp—<¸ŒƒŽ“ÖǾ½ë`‰¿bïþœ¸ÊÄ¢ºiCú†W¢”œ®W§î³o^¾yþò÷æ7ß>wGÔWäÏç³€Ú=$ÔU¼Ï—` ³Gì8DGYȇ «$ùçîï̻ƭ`™ü?é)òßr8ØÆÿl†üOfP±â9ãŒÏ1øepò ùœm¿àüA¹«šó¨‚A„Á"ðgÁ÷h‹f';Œ:IéòïX ÑL?Áà†øoö•ЫÜö{X°÷óÏâmfoâÐ;4QÇù8c¿)[H’ؾzÉ"FØ[£'¨Üþï©òß?lå¿b<ñ¯Ù¼ï䤑°^ë/(~’~7ŸùéÉæ›{x•dk$ñ«Dsîew7»û’^ðž˜{ýYißîo­ÿvÖrÅk4ý-忯Êÿq¿¿•ÿ͵ÿ_`kúWÏ_yϾzúúµ÷òé×ϱ*èñt‰F·xŽúÉk<å0ÒˆÔüNWÄ|ŸÛíËòŸ2®U”ÈÿáQ/·ÿïoíÿV^ïÒ`ÿzÊà±ó -–qÈBàÁ. 'ðì¬9;Ðf1hÓæ,ûu ijF"3„g»¹^C8­ŸÑŽI*Òë A]A©dl möxܸ 2ë{yÿ”AÓIF!3cø+;™Â;˜Nö,ÅœŽ+~ÏÑ›âGû¹abÿr…q´^ *Ý!_K¯þd‚æ‹4¶`݃ 8ÂùàdÊyŸ/!æð9œP‘Ôî2|Fס“ÝKqð.ÅÇKÉ \gPf5sl6EUH%œmVá˜Û;àÛ0ú0š—̹¹eŽÆ·rÐáoÞ|ë=}öìù·oÈñTIÛµ+ºµ®ÂiW Ï&Bî>”¾£\{·ÛѦ ÃMh¸Œ\­sÔD—s²`Óÿ+&º«ÈGf½ïž¿zýâ›—×ÐÄÌÐŽ»¬uŽ{t«Ã1§Ç#ü“^SE‡_'ªbSc^ƒ«ôîŒ4<1$÷³®¯K]sþ¯Ðû¾lê¨Íra©¦Zþä$/ YùÇÒ ®Ì¿ƒ8×Jœ%9wØ2ü¶Æäöµ}m_Û—ôúÿÿÎ&¨ checksums.yaml.gz0000444000000000000000000000041313154552777014622 0ustar00wheelwheel00000000000000‹þÕ²Ye1R@ó{Å}à,`a33s_À.`db]äëÝÓLkâ¡›¹Ýn—·×|¾\¯uŒ{<½=_Û&%u+`@J˜¬2ÙsŠ­à›Æ¾Nï§sÏßÅSL°QˆvÊ6Ôa*)Þª ýãî1Èö‰åâªN8*–ŽhØ °tI·±avf¯á2hZè¢J†jå"¢¬2ìÍ[Ö(w˜"€) ˜Éµ*{=„ÿþ£‡'梻G´R…\ÃLp–Ÿi:ÀMØÔŠGÄ F«€—ðãQCøØNFC×tÞhTÍétöí΂¬6æsÐÑxíË74ó<¢grape-1.0.2/CONTRIBUTING.md0000644000004100000410000000670513231337007015100 0ustar www-datawww-dataContributing to Grape ===================== Grape is work of [hundreds of contributors](https://github.com/ruby-grape/grape/graphs/contributors). You're encouraged to submit [pull requests](https://github.com/ruby-grape/grape/pulls), [propose features and discuss issues](https://github.com/ruby-grape/grape/issues). When in doubt, ask a question in the [Grape Google Group](http://groups.google.com/group/ruby-grape). #### Fork the Project Fork the [project on Github](https://github.com/ruby-grape/grape) and check out your copy. ``` git clone https://github.com/contributor/grape.git cd grape git remote add upstream https://github.com/ruby-grape/grape.git ``` #### Create a Topic Branch Make sure your fork is up-to-date and create a topic branch for your feature or bug fix. ``` git checkout master git pull upstream master git checkout -b my-feature-branch ``` #### Bundle Install and Test Ensure that you can build the project and run tests. ``` bundle install bundle exec rake ``` Run tests against all supported versions of Rails. ``` appraisal install appraisal rake spec ``` #### Write Tests Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [spec/grape](spec/grape). We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix. #### Write Code Implement your feature or bug fix. Ruby style is enforced with [Rubocop](https://github.com/bbatsov/rubocop), run `bundle exec rubocop` and fix any style issues highlighted. Make sure that `bundle exec rake` completes without errors. #### Write Documentation Document any external behavior in the [README](README.md). #### Update Changelog Add a line to [CHANGELOG](CHANGELOG.md) under *Next Release*. Make it look like every other line, including your name and link to your Github account. #### Commit Changes Make sure git knows your name and email address: ``` git config --global user.name "Your Name" git config --global user.email "contributor@example.com" ``` Writing good commit logs is important. A commit log should describe what changed and why. ``` git add ... git commit ``` #### Push ``` git push origin my-feature-branch ``` #### Make a Pull Request Go to https://github.com/contributor/grape and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days. #### Rebase If you've been working on a change for a while, rebase with upstream/master. ``` git fetch upstream git rebase upstream/master git push origin my-feature-branch -f ``` #### Update CHANGELOG Again Update the [CHANGELOG](CHANGELOG.md) with the pull request number. A typical entry looks as follows. ``` * [#123](https://github.com/ruby-grape/grape/pull/123): Reticulated splines - [@contributor](https://github.com/contributor). ``` Amend your previous commit and force push the changes. ``` git commit --amend git push origin my-feature-branch -f ``` #### Check on Your Pull Request Go back to your pull request after a few minutes and see whether it passed muster with Travis-CI. Everything should look green, otherwise fix issues and amend your commit as described above. #### Be Patient It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang on there! #### Thank You Please do know that we really appreciate and value your time and work. We love you, really. grape-1.0.2/LICENSE0000644000004100000410000000211013231337007013636 0ustar www-datawww-dataCopyright (c) 2010-2018 Michael Bleigh, Intridea Inc. and Contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. grape-1.0.2/RELEASING.md0000644000004100000410000000571013231337007014475 0ustar www-datawww-dataReleasing Grape =============== There're no particular rules about when to release Grape. Release bug fixes frequently, features not so frequently and breaking API changes rarely. ### Release Run tests, check that all tests succeed locally. ``` bundle install rake ``` Check that the last build succeeded in [Travis CI](https://travis-ci.org/ruby-grape/grape) for all supported platforms. Those with r/w permissions to the [master Grape repository](https://github.com/ruby-grape/grape) generally have large Grape-based projects. Point one to Grape HEAD and run all your API tests to catch any obvious regressions. ``` gem grape, github: 'ruby-grape/grape' ``` Increment the version, modify [lib/grape/version.rb](lib/grape/version.rb). * Increment the third number if the release has bug fixes and/or very minor features, only (eg. change `0.5.1` to `0.5.2`). * Increment the second number if the release contains major features or breaking API changes (eg. change `0.5.1` to `0.6.0`). Modify the "Stable Release" section in [README.md](README.md). Change the text to reflect that this is going to be the documentation for a stable release. Remove references to the previous release of Grape. Keep the file open, you'll have to undo this change after the release. ``` ## Stable Release You're reading the documentation for the stable release of Grape, 0.6.0. ``` Change "Next Release" in [CHANGELOG.md](CHANGELOG.md) to the new version. ``` #### 0.6.0 (9/16/2013) ``` Remove the line with "Your contribution here.", since there will be no more contributions to this release. Commit your changes. ``` git add README.md CHANGELOG.md lib/grape/version.rb git commit -m "Preparing for release, 0.6.0." git push origin master ``` Release. ``` $ rake release grape 0.6.0 built to pkg/grape-0.6.0.gem. Tagged v0.6.0. Pushed git commits and tags. Pushed grape 0.6.0 to rubygems.org. ``` ### Prepare for the Next Version Modify the "Stable Release" section in [README.md](README.md). Change the text to reflect that this is going to be the next release. ``` ## Stable Release You're reading the documentation for the next release of Grape, which should be 0.6.1. The current stable release is [0.6.0](https://github.com/ruby-grape/grape/blob/v0.6.0/README.md). ``` Add the next release to [CHANGELOG.md](CHANGELOG.md). ``` #### 0.6.1 (Next) * Your contribution here. ``` Bump the minor version in lib/grape/version.rb. ```ruby module Grape VERSION = '0.6.1' end ``` Commit your changes. ``` git add CHANGELOG.md README.md lib/grape/version.rb git commit -m "Preparing for next development iteration, 0.6.1." git push origin master ``` ### Make an Announcement Make an announcement on the [ruby-grape@googlegroups.com](mailto:ruby-grape@googlegroups.com) mailing list. The general format is as follows. ``` Grape 0.6.0 has been released. There were 8 contributors to this release, not counting documentation. Please note the breaking API change in ... [copy/paste CHANGELOG here] ``` grape-1.0.2/Appraisals0000644000004100000410000000106313231337007014661 0ustar www-datawww-dataappraise 'rails-3' do gem 'rails', '3.2.19' gem 'rack-cache', '<= 1.2' # Pin as next rack-cache version (1.3) removes Ruby1.9 support end appraise 'rails-4' do gem 'rails', '4.1.6' end appraise 'rails-5' do gem 'rails', '5.0.0' end appraise 'rack-1.5.2' do gem 'rack', '1.5.2' end appraise 'rails-edge' do gem 'arel', github: 'rails/arel' end appraise 'rack-edge' do gem 'rack', github: 'rack/rack' end appraise 'multi_json' do gem 'multi_json', require: 'multi_json' end appraise 'multi_xml' do gem 'multi_xml', require: 'multi_xml' end grape-1.0.2/CHANGELOG.md0000644000004100000410000020070513231337007014454 0ustar www-datawww-data### 1.0.2 (1/10/2018) #### Features * [#1686](https://github.com/ruby-grape/grape/pull/1686): Avoid coercion of a value if it is valid - [@timothysu](https://github.com/timothysu). * [#1688](https://github.com/ruby-grape/grape/pull/1688): Removes yard docs - [@ramkumar-kr](https://github.com/ramkumar-kr). * [#1702](https://github.com/ruby-grape/grape/pull/1702): Added danger-toc, verify correct TOC in README - [@dblock](https://github.com/dblock). * [#1711](https://github.com/ruby-grape/grape/pull/1711): Automatically coerce arrays and sets of types that implement a `parse` method - [@dslh](https://github.com/dslh). #### Fixes * [#1710](https://github.com/ruby-grape/grape/pull/1710): Fix wrong transformation of empty Array in declared params - [@pablonahuelgomez](https://github.com/pablonahuelgomez). * [#1722](https://github.com/ruby-grape/grape/pull/1722): Fix catch-all hiding multiple versions of an endpoint after the first definition - [@zherr](https://github.com/zherr). * [#1724](https://github.com/ruby-grape/grape/pull/1724): Optional nested array validation - [@ericproulx](https://github.com/ericproulx). * [#1725](https://github.com/ruby-grape/grape/pull/1725): Fix `rescue_from :all` documentation - [@Jelkster](https://github.com/Jelkster). * [#1726](https://github.com/ruby-grape/grape/pull/1726): Improved startup performance during API method generation - [@jkowens](https://github.com/jkowens). * [#1727](https://github.com/ruby-grape/grape/pull/1727): Fix infinite loop when mounting endpoint with same superclass - [@jkowens](https://github.com/jkowens). ### 1.0.1 (9/8/2017) #### Features * [#1652](https://github.com/ruby-grape/grape/pull/1652): Add the original exception to the error_formatter the original exception - [@dcsg](https://github.com/dcsg). * [#1665](https://github.com/ruby-grape/grape/pull/1665): Make helpers available in subclasses - [@pablonahuelgomez](https://github.com/pablonahuelgomez). * [#1674](https://github.com/ruby-grape/grape/pull/1674): Add parameter alias (`as`) - [@glaucocustodio](https://github.com/glaucocustodio). #### Fixes * [#1652](https://github.com/ruby-grape/grape/pull/1652): Fix missing backtrace that was not being bubbled up to the `error_formatter` - [@dcsg](https://github.com/dcsg). * [#1661](https://github.com/ruby-grape/grape/pull/1661): Handle deeply-nested dependencies correctly - [@rnubel](https://github.com/rnubel), [@jnardone](https://github.com/jnardone). * [#1679](https://github.com/ruby-grape/grape/pull/1679): Treat StandardError from explicit values validator proc as false - [@jlfaber](https://github.com/jlfaber). ### 1.0.0 (7/3/2017) #### Features * [#1594](https://github.com/ruby-grape/grape/pull/1594): Replace `Hashie::Mash` parameters with `ActiveSupport::HashWithIndifferentAccess` - [@james2m](https://github.com/james2m), [@dblock](https://github.com/dblock). * [#1622](https://github.com/ruby-grape/grape/pull/1622): Add `except_values` validator to replace `except` option of `values` validator - [@jlfaber](https://github.com/jlfaber). * [#1635](https://github.com/ruby-grape/grape/pull/1635): Instrument validators with ActiveSupport::Notifications - [@ktimothy](https://github.com/ktimothy). * [#1646](https://github.com/ruby-grape/grape/pull/1646): Add ability to include an array of modules as helpers - [@pablonahuelgomez](https://github.com/pablonahuelgomez). * [#1623](https://github.com/ruby-grape/grape/pull/1623): Removed `multi_json` and `multi_xml` dependencies - [@dblock](https://github.com/dblock). * [#1650](https://github.com/ruby-grape/grape/pull/1650): Add extra specs for Boolean type field - [@tiarly](https://github.com/tiarly). #### Fixes * [#1648](https://github.com/ruby-grape/grape/pull/1631): Declared now returns declared options using the class that params is set to use - [@thogg4](https://github.com/thogg4). * [#1632](https://github.com/ruby-grape/grape/pull/1632): Silence warnings - [@thogg4](https://github.com/thogg4). * [#1615](https://github.com/ruby-grape/grape/pull/1615): Fix default and type validator when values is a Hash with no value attribute - [@jlfaber](https://github.com/jlfaber). * [#1625](https://github.com/ruby-grape/grape/pull/1625): Handle `given` correctly when nested in Array params - [@rnubel](https://github.com/rnubel), [@avellable](https://github.com/avellable). * [#1649](https://github.com/ruby-grape/grape/pull/1649): Don't share validator instances between requests - [@anakinj](https://github.com/anakinj). ### 0.19.2 (4/12/2017) #### Features * [#1555](https://github.com/ruby-grape/grape/pull/1555): Added code coverage w/Coveralls - [@dblock](https://github.com/dblock). * [#1568](https://github.com/ruby-grape/grape/pull/1568): Add `proc` option to `values` validator to allow custom checks - [@jlfaber](https://github.com/jlfaber). * [#1575](https://github.com/ruby-grape/grape/pull/1575): Include nil values for missing nested params in declared - [@thogg4](https://github.com/thogg4). * [#1585](https://github.com/ruby-grape/grape/pull/1585): Bugs in declared method - make sure correct options var is used and respect include missing for non children params - [@thogg4](https://github.com/thogg4). #### Fixes * [#1570](https://github.com/ruby-grape/grape/pull/1570): Make versioner consider the mount destination path - [@namusyaka](https://github.com/namusyaka). * [#1579](https://github.com/ruby-grape/grape/pull/1579): Fix delete status with a return value - [@eproulx-petalmd](https://github.com/eproulx-petalmd). * [#1559](https://github.com/ruby-grape/grape/pull/1559): You can once again pass `nil` to optional attributes with `values` validation set - [@ghiculescu](https://github.com/ghiculescu). * [#1562](https://github.com/ruby-grape/grape/pull/1562): Fix rainbow gem installation failure above ruby 2.3.3 on travis-ci - [@brucehsu](https://github.com/brucehsu). * [#1561](https://github.com/ruby-grape/grape/pull/1561): Fix performance issue introduced by duplicated calls in StackableValue#[] - [@brucehsu](https://github.com/brucehsu). * [#1564](https://github.com/ruby-grape/grape/pull/1564): Fix declared params bug with nested namespaces - [@bmarini](https://github.com/bmarini). * [#1567](https://github.com/ruby-grape/grape/pull/1567): Fix values validator when value is empty array and apply except to input array - [@jlfaber](https://github.com/jlfaber). * [#1569](https://github.com/ruby-grape/grape/pull/1569), [#1511](https://github.com/ruby-grape/grape/issues/1511): Upgrade mustermann-grape to 1.0.0 - [@namusyaka](https://github.com/namusyaka). * [#1589](https://github.com/ruby-grape/grape/pull/1589): [#726](https://github.com/ruby-grape/grape/issues/726): Use default_format when Content-type is missing and respond with 406 when Content-type is invalid - [@inclooder](https://github.com/inclooder). ### 0.19.1 (1/9/2017) #### Features * [#1536](https://github.com/ruby-grape/grape/pull/1536): Updated `invalid_versioner_option` translation - [@Lavode](https://github.com/Lavode). * [#1543](https://github.com/ruby-grape/grape/pull/1543): Added support for ruby 2.4 - [@LeFnord](https://github.com/LeFnord), [@namusyaka](https://github.com/namusyaka). #### Fixes * [#1548](https://github.com/ruby-grape/grape/pull/1548): Fix: avoid failing even if given path does not match with prefix - [@thomas-peyric](https://github.com/thomas-peyric), [@namusyaka](https://github.com/namusyaka). * [#1550](https://github.com/ruby-grape/grape/pull/1550): Fix: return 200 as default status for DELETE - [@jthornec](https://github.com/jthornec). ### 0.19.0 (12/18/2016) #### Features * [#1503](https://github.com/ruby-grape/grape/pull/1503): Allowed use of regexp validator with arrays - [@akoltun](https://github.com/akoltun). * [#1507](https://github.com/ruby-grape/grape/pull/1507): Added group attributes for parameter definitions - [@304](https://github.com/304). * [#1532](https://github.com/ruby-grape/grape/pull/1532): Set 204 as default status for DELETE - [@LeFnord](https://github.com/LeFnord). #### Fixes * [#1505](https://github.com/ruby-grape/grape/pull/1505): Run `before` and `after` callbacks, but skip the rest when handling OPTIONS - [@jlfaber](https://github.com/jlfaber). * [#1517](https://github.com/ruby-grape/grape/pull/1517), [#1089](https://github.com/ruby-grape/grape/pull/1089): Fix: priority of ANY routes - [@namusyaka](https://github.com/namusyaka), [@wagenet](https://github.com/wagenet). * [#1512](https://github.com/ruby-grape/grape/pull/1512): Fix: deeply nested parameters are included within `#declared(params)` - [@krbs](https://github.com/krbs). * [#1510](https://github.com/ruby-grape/grape/pull/1510): Fix: inconsistent validation for multiple parameters - [@dgasper](https://github.com/dgasper). * [#1526](https://github.com/ruby-grape/grape/pull/1526): Reduced warnings caused by instance variables not initialized - [@cpetschnig](https://github.com/cpetschnig). ### 0.18.0 (10/7/2016) #### Features * [#1480](https://github.com/ruby-grape/grape/pull/1480): Used the ruby-grape-danger gem for PR linting - [@dblock](https://github.com/dblock). * [#1486](https://github.com/ruby-grape/grape/pull/1486): Implemented except in values validator - [@jonmchan](https://github.com/jonmchan). * [#1470](https://github.com/ruby-grape/grape/pull/1470): Dropped support for Ruby 2.0 - [@namusyaka](https://github.com/namusyaka). * [#1490](https://github.com/ruby-grape/grape/pull/1490): Switched to Ruby-2.x+ syntax - [@namusyaka](https://github.com/namusyaka). * [#1499](https://github.com/ruby-grape/grape/pull/1499): Support `fail_fast` param validation option - [@dgasper](https://github.com/dgasper). #### Fixes * [#1498](https://github.com/ruby-grape/grape/pull/1498): Fix: skip validations in inactive given blocks - [@jlfaber](https://github.com/jlfaber). * [#1479](https://github.com/ruby-grape/grape/pull/1479): Fix: support inserting middleware before/after anonymous classes in the middleware stack - [@rosa](https://github.com/rosa). * [#1488](https://github.com/ruby-grape/grape/pull/1488): Fix: ensure calling before filters when receiving OPTIONS request - [@namusyaka](https://github.com/namusyaka), [@jlfaber](https://github.com/jlfaber). * [#1493](https://github.com/ruby-grape/grape/pull/1493): Fix: coercion and lambda fails params validation - [@jonmchan](https://github.com/jonmchan). ### 0.17.0 (7/29/2016) #### Features * [#1393](https://github.com/ruby-grape/grape/pull/1393): Middleware can be inserted before or after default Grape middleware - [@ridiculous](https://github.com/ridiculous). * [#1390](https://github.com/ruby-grape/grape/pull/1390): Allowed inserting middleware at arbitrary points in the middleware stack - [@rosa](https://github.com/rosa). * [#1366](https://github.com/ruby-grape/grape/pull/1366): Stored `message_key` on `Grape::Exceptions::Validation` - [@mkou](https://github.com/mkou). * [#1398](https://github.com/ruby-grape/grape/pull/1398): Added `rescue_from :grape_exceptions` - allow Grape to use the built-in `Grape::Exception` handing and use `rescue :all` behavior for everything else - [@mmclead](https://github.com/mmclead). * [#1443](https://github.com/ruby-grape/grape/pull/1443): Extended `given` to receive a `Proc` - [@glaucocustodio](https://github.com/glaucocustodio). * [#1455](https://github.com/ruby-grape/grape/pull/1455): Added an automated PR linter - [@orta](https://github.com/orta). #### Fixes * [#1463](https://github.com/ruby-grape/grape/pull/1463): Fix array indicies in error messages - [@ffloyd](https://github.com/ffloyd). * [#1465](https://github.com/ruby-grape/grape/pull/1465): Fix 'before' being called twice when using not allowed method - [@jsteinberg](https://github.com/jsteinberg). * [#1446](https://github.com/ruby-grape/grape/pull/1446): Fix for `env` inside `before` when using not allowed method - [@leifg](https://github.com/leifg). * [#1438](https://github.com/ruby-grape/grape/pull/1439): Try to dup non-frozen default params with each use - [@jlfaber](https://github.com/jlfaber). * [#1430](https://github.com/ruby-grape/grape/pull/1430): Fix for `declared(params)` inside `route_param` - [@Arkanain](https://github.com/Arkanain). * [#1405](https://github.com/ruby-grape/grape/pull/1405): Fix priority of `rescue_from` clauses applying - [@hedgesky](https://github.com/hedgesky). * [#1365](https://github.com/ruby-grape/grape/pull/1365): Fix finding exception handler in error middleware - [@ktimothy](https://github.com/ktimothy). * [#1380](https://github.com/ruby-grape/grape/pull/1380): Fix `allow_blank: false` for `Time` attributes with valid values causes `NoMethodError` - [@ipkes](https://github.com/ipkes). * [#1384](https://github.com/ruby-grape/grape/pull/1384): Fix parameter validation with an empty optional nested `Array` - [@ipkes](https://github.com/ipkes). * [#1414](https://github.com/ruby-grape/grape/pull/1414): Fix multiple version definitions for path versioning - [@304](https://github.com/304). * [#1415](https://github.com/ruby-grape/grape/pull/1415): Fix `declared(params, include_parent_namespaces: false)` - [@304](https://github.com/304). * [#1421](https://github.com/ruby-grape/grape/pull/1421): Avoid polluting `Grape::Middleware::Error` - [@namusyaka](https://github.com/namusyaka). * [#1422](https://github.com/ruby-grape/grape/pull/1422): Concat parent declared params with current one - [@plukevdh](https://github.com/plukevdh), [@rnubel](https://github.com/rnubel), [@namusyaka](https://github.com/namusyaka). ### 0.16.2 (4/12/2016) #### Features * [#1348](https://github.com/ruby-grape/grape/pull/1348): Fix global functions polluting Grape::API scope - [@dblock](https://github.com/dblock). * [#1357](https://github.com/ruby-grape/grape/pull/1357): Expose Route#options - [@namusyaka](https://github.com/namusyaka). #### Fixes * [#1357](https://github.com/ruby-grape/grape/pull/1357): Don't include fixed named captures as route params - [@namusyaka](https://github.com/namusyaka). * [#1359](https://github.com/ruby-grape/grape/pull/1359): Avoid evaluating the same route twice - [@namusyaka](https://github.com/namusyaka), [@dblock](https://github.com/dblock). * [#1361](https://github.com/ruby-grape/grape/pull/1361): Return 405 correctly even if version is using as header and wrong request method - [@namusyaka](https://github.com/namusyaka), [@dblock](https://github.com/dblock). ### 0.16.1 (4/3/2016) #### Features * [#1276](https://github.com/ruby-grape/grape/pull/1276): Replace rack-mount with new router - [@namusyaka](https://github.com/namusyaka). * [#1321](https://github.com/ruby-grape/grape/pull/1321): Serve files without using FileStreamer-like object - [@lfidnl](https://github.com/lfidnl). * [#1339](https://github.com/ruby-grape/grape/pull/1339): Implement Grape::API.recognize_path - [@namusyaka](https://github.com/namusyaka). #### Fixes * [#1325](https://github.com/ruby-grape/grape/pull/1325): Params: Fix coerce_with helper with Array types - [@ngonzalez](https://github.com/ngonzalez). * [#1326](https://github.com/ruby-grape/grape/pull/1326): Fix wrong behavior for OPTIONS and HEAD requests with catch-all - [@ekampp](https://github.com/ekampp), [@namusyaka](https://github.com/namusyaka). * [#1330](https://github.com/ruby-grape/grape/pull/1330): Add `register` keyword for adding customized parsers and formatters - [@namusyaka](https://github.com/namusyaka). * [#1336](https://github.com/ruby-grape/grape/pull/1336): Do not modify Hash argument to `error!` - [@tjwp](https://github.com/tjwp). ### 0.15.0 (3/8/2016) #### Features * [#1227](https://github.com/ruby-grape/grape/pull/1227): Store `message_key` on `Grape::Exceptions::Validation` - [@stjhimy](https://github.com/sthimy). * [#1232](https://github.com/ruby-grape/grape/pull/1232): Helpers are now available inside `rescue_from` - [@namusyaka](https://github.com/namusyaka). * [#1237](https://github.com/ruby-grape/grape/pull/1237): Allow multiple parameters in `given`, which behaves as if the scopes were nested in the inputted order - [@ochagata](https://github.com/ochagata). * [#1238](https://github.com/ruby-grape/grape/pull/1238): Call `after` of middleware on error - [@namusyaka](https://github.com/namusyaka). * [#1243](https://github.com/ruby-grape/grape/pull/1243): Add `header` support for middleware - [@namusyaka](https://github.com/namusyaka). * [#1252](https://github.com/ruby-grape/grape/pull/1252): Allow default to be a subset or equal to allowed values without raising IncompatibleOptionValues - [@jeradphelps](https://github.com/jeradphelps). * [#1255](https://github.com/ruby-grape/grape/pull/1255): Allow param type definition in `route_param` - [@namusyaka](https://github.com/namusyaka). * [#1257](https://github.com/ruby-grape/grape/pull/1257): Allow Proc, Symbol or String in `rescue_from with: ...` - [@namusyaka](https://github.com/namusyaka). * [#1280](https://github.com/ruby-grape/grape/pull/1280): Support `Rack::Sendfile` middleware - [@lfidnl](https://github.com/lfidnl). * [#1285](https://github.com/ruby-grape/grape/pull/1285): Add a warning for errors appearing in `after` callbacks - [@gregormelhorn](https://github.com/gregormelhorn). * [#1295](https://github.com/ruby-grape/grape/pull/1295): Add custom validation messages for parameter exceptions - [@railsmith](https://github.com/railsmith). #### Fixes * [#1216](https://github.com/ruby-grape/grape/pull/1142): Fix JSON error response when calling `error!` with non-Strings - [@jrforrest](https://github.com/jrforrest). * [#1225](https://github.com/ruby-grape/grape/pull/1225): Fix `given` with nested params not returning correct declared params - [@JanStevens](https://github.com/JanStevens). * [#1249](https://github.com/ruby-grape/grape/pull/1249): Don't fail even if invalid type value is passed to default validator - [@namusyaka](https://github.com/namusyaka). * [#1266](https://github.com/ruby-grape/grape/pull/1266): Fix `Allow` header including `OPTIONS` when `do_not_route_options!` is active - [@arempe93](https://github.com/arempe93). * [#1270](https://github.com/ruby-grape/grape/pull/1270): Fix `param` versioning with a custom parameter - [@wshatch](https://github.com/wshatch). * [#1282](https://github.com/ruby-grape/grape/pull/1282): Fix specs circular dependency - [@304](https://github.com/304). * [#1283](https://github.com/ruby-grape/grape/pull/1283): Fix 500 error for xml format when method is not allowed - [@304](https://github.com/304). * [#1197](https://github.com/ruby-grape/grape/pull/1290): Fix using JSON and Array[JSON] as groups when parameter is optional - [@lukeivers](https://github.com/lukeivers). ### 0.14.0 (12/07/2015) #### Features * [#1218](https://github.com/ruby-grape/grape/pull/1218): Provide array index context in errors - [@towanda](https://github.com/towanda). * [#1196](https://github.com/ruby-grape/grape/pull/1196): Allow multiple `before_each` blocks - [@huynhquancam](https://github.com/huynhquancam). * [#1190](https://github.com/ruby-grape/grape/pull/1190): Bypass formatting for statuses with no entity-body - [@tylerdooling](https://github.com/tylerdooling). * [#1188](https://github.com/ruby-grape/grape/pull/1188): Allow parameters with more than one type - [@dslh](https://github.com/dslh). * [#1179](https://github.com/ruby-grape/grape/pull/1179): Allow all RFC6838 valid characters in header vendor - [@suan](https://github.com/suan). * [#1170](https://github.com/ruby-grape/grape/pull/1170): Allow dashes and periods in header vendor - [@suan](https://github.com/suan). * [#1167](https://github.com/ruby-grape/grape/pull/1167): Convenience wrapper `type: File` for validating multipart file parameters - [@dslh](https://github.com/dslh). * [#1167](https://github.com/ruby-grape/grape/pull/1167): Refactor and extend coercion and type validation system - [@dslh](https://github.com/dslh). * [#1163](https://github.com/ruby-grape/grape/pull/1163): First-class `JSON` parameter type - [@dslh](https://github.com/dslh). * [#1161](https://github.com/ruby-grape/grape/pull/1161): Custom parameter coercion using `coerce_with` - [@dslh](https://github.com/dslh). #### Fixes * [#1194](https://github.com/ruby-grape/grape/pull/1194): Redirect as plain text with message - [@tylerdooling](https://github.com/tylerdooling). * [#1185](https://github.com/ruby-grape/grape/pull/1185): Use formatters for custom vendored content types - [@tylerdooling](https://github.com/tylerdooling). * [#1156](https://github.com/ruby-grape/grape/pull/1156): Fixed `no implicit conversion of Symbol into Integer` with nested `values` validation - [@quickpay](https://github.com/quickpay). * [#1153](https://github.com/ruby-grape/grape/pull/1153): Fixes boolean declaration in an external file - [@towanda](https://github.com/towanda). * [#1142](https://github.com/ruby-grape/grape/pull/1142): Makes #declared unavailable to before filters - [@jrforrest](https://github.com/jrforrest). * [#1114](https://github.com/ruby-grape/grape/pull/1114): Fix regression which broke identical endpoints with different versions - [@suan](https://github.com/suan). * [#1109](https://github.com/ruby-grape/grape/pull/1109): Memoize Virtus attribute and fix memory leak - [@marshall-lee](https://github.com/marshall-lee). * [#1101](https://github.com/ruby-grape/grape/pull/1101): Fix: Incorrect media-type `Accept` header now correctly returns 406 with `strict: true` - [@elliotlarson](https://github.com/elliotlarson). * [#1108](https://github.com/ruby-grape/grape/pull/1039): Raise a warning when `desc` is called with options hash and block - [@rngtng](https://github.com/rngtng). ### 0.13.0 (8/10/2015) #### Features * [#1039](https://github.com/ruby-grape/grape/pull/1039): Added support for custom parameter types - [@rnubel](https://github.com/rnubel). * [#1047](https://github.com/ruby-grape/grape/pull/1047): Adds `given` to DSL::Parameters, allowing for dependent params - [@rnubel](https://github.com/rnubel). * [#1064](https://github.com/ruby-grape/grape/pull/1064): Add public `Grape::Exception::ValidationErrors#full_messages` - [@romanlehnert](https://github.com/romanlehnert). * [#1079](https://github.com/ruby-grape/grape/pull/1079): Added `stream` method to take advantage of `Rack::Chunked` - [@zbelzer](https://github.com/zbelzer). * [#1086](https://github.com/ruby-grape/grape/pull/1086): Added `ActiveSupport::Notifications` instrumentation - [@wagenet](https://github.com/wagenet). #### Fixes * [#1062](https://github.com/ruby-grape/grape/issues/1062): Fix: `Grape::Exceptions::ValidationErrors` will include headers set by `header` - [@yairgo](https://github.com/yairgo). * [#1038](https://github.com/ruby-grape/grape/pull/1038): Avoid dup-ing the `String` class when used in inherited params - [@rnubel](https://github.com/rnubel). * [#1042](https://github.com/ruby-grape/grape/issues/1042): Fix coercion of complex arrays - [@dim](https://github.com/dim). * [#1045](https://github.com/ruby-grape/grape/pull/1045): Do not convert `Rack::Response` to `Rack::Response` in middleware - [@dmitry](https://github.com/dmitry). * [#1048](https://github.com/ruby-grape/grape/pull/1048): Only dup `InheritableValues`, remove support for `deep_dup` - [@toddmazierski](https://github.com/toddmazierski). * [#1052](https://github.com/ruby-grape/grape/pull/1052): Reset `description[:params]` when resetting validations - [@marshall-lee](https://github.com/marshall-lee). * [#1088](https://github.com/ruby-grape/grape/pull/1088): Support ActiveSupport 3.x by explicitly requiring `Hash#except` - [@wagenet](https://github.com/wagenet). * [#1096](https://github.com/ruby-grape/grape/pull/1096): Fix coercion on booleans - [@towanda](https://github.com/towanda). ### 0.12.0 (6/18/2015) #### Features * [#995](https://github.com/ruby-grape/grape/issues/995): Added support for coercion to Set or Set[Other] - [@jordansexton](https://github.com/jordansexton) [@u2](https://github.com/u2). * [#980](https://github.com/ruby-grape/grape/issues/980): Grape is now eager-loaded - [@u2](https://github.com/u2). * [#956](https://github.com/ruby-grape/grape/issues/956): Support `present` with `Grape::Presenters::Presenter` - [@u2](https://github.com/u2). * [#974](https://github.com/ruby-grape/grape/pull/974): Added `error!` to `rescue_from` blocks - [@whatasunnyday](https://github.com/whatasunnyday). * [#950](https://github.com/ruby-grape/grape/pull/950): Status method can now accept one of Rack::Utils status code symbols (:ok, :found, :bad_request, etc.) - [@dabrorius](https://github.com/dabrorius). * [#952](https://github.com/ruby-grape/grape/pull/952): Status method now raises error when called with invalid status code - [@dabrorius](https://github.com/dabrorius). * [#957](https://github.com/ruby-grape/grape/pull/957): Regexp validator now supports `allow_blank`, `nil` value behavior changed - [@calfzhou](https://github.com/calfzhou). * [#962](https://github.com/ruby-grape/grape/pull/962): The `default` attribute with `false` value is documented now - [@ajvondrak](https://github.com/ajvondrak). * [#1026](https://github.com/ruby-grape/grape/pull/1026): Added `file` method, explicitly setting a file-like response object - [@dblock](https://github.com/dblock). #### Fixes * [#994](https://github.com/ruby-grape/grape/pull/994): Fixed optional Array params default to Hash - [@u2](https://github.com/u2). * [#988](https://github.com/ruby-grape/grape/pull/988): Fixed duplicate identical endpoints - [@u2](https://github.com/u2). * [#936](https://github.com/ruby-grape/grape/pull/936): Fixed default params processing for optional groups - [@dm1try](https://github.com/dm1try). * [#942](https://github.com/ruby-grape/grape/pull/942): Fixed forced presence for optional params when based on a reused entity that was also required in another context - [@croeck](https://github.com/croeck). * [#1001](https://github.com/ruby-grape/grape/pull/1001): Fixed calling endpoint with specified format with format in its path - [@hodak](https://github.com/hodak). * [#1005](https://github.com/ruby-grape/grape/pull/1005): Fixed the Grape::Middleware::Globals - [@urkle](https://github.com/urkle). * [#1012](https://github.com/ruby-grape/grape/pull/1012): Fixed `allow_blank: false` with a Boolean value of `false` - [@mfunaro](https://github.com/mfunaro). * [#1023](https://github.com/ruby-grape/grape/issues/1023): Fixes unexpected behavior with `present` and an object that responds to `merge` but isn't a Hash - [@dblock](https://github.com/dblock). * [#1017](https://github.com/ruby-grape/grape/pull/1017): Fixed `undefined method stringify_keys` with nested mutual exclusive params - [@quickpay](https://github.com/quickpay). ### 0.11.0 (2/23/2015) * [#925](https://github.com/ruby-grape/grape/pull/925): Fixed `toplevel constant DateTime referenced by Virtus::Attribute::DateTime` - [@u2](https://github.com/u2). * [#916](https://github.com/ruby-grape/grape/pull/916): Added `DateTime/Date/Numeric/Boolean` type support `allow_blank` - [@u2](https://github.com/u2). * [#871](https://github.com/ruby-grape/grape/pull/871): Fixed `Grape::Middleware::Base#response` - [@galathius](https://github.com/galathius). * [#559](https://github.com/ruby-grape/grape/issues/559): Added support for Rack 1.6.0, which parses requests larger than 128KB - [@myitcv](https://github.com/myitcv). * [#876](https://github.com/ruby-grape/grape/pull/876): Call to `declared(params)` now returns a `Hashie::Mash` - [@rodzyn](https://github.com/rodzyn). * [#879](https://github.com/ruby-grape/grape/pull/879): The `route_info` value is no longer included in `params` Hash - [@rodzyn](https://github.com/rodzyn). * [#881](https://github.com/ruby-grape/grape/issues/881): Fixed `Grape::Validations::ValuesValidator` support for `Range` type - [@ajvondrak](https://github.com/ajvondrak). * [#901](https://github.com/ruby-grape/grape/pull/901): Fix: callbacks defined in a version block are only called for the routes defined in that block - [@kushkella](https://github.com/kushkella). * [#886](https://github.com/ruby-grape/grape/pull/886): Group of parameters made to require an explicit type of Hash or Array - [@jrichter1](https://github.com/jrichter1). * [#912](https://github.com/ruby-grape/grape/pull/912): Extended the `:using` feature for param documentation to `optional` fields - [@croeck](https://github.com/croeck). * [#906](https://github.com/ruby-grape/grape/pull/906): Fix: invalid body parse errors are not rescued by handlers - [@croeck](https://github.com/croeck). * [#913](https://github.com/ruby-grape/grape/pull/913): Fix: Invalid accept headers are not processed by rescue handlers - [@croeck](https://github.com/croeck). * [#913](https://github.com/ruby-grape/grape/pull/913): Fix: Invalid accept headers cause internal processing errors (500) when http_codes are defined - [@croeck](https://github.com/croeck). * [#917](https://github.com/ruby-grape/grape/pull/917): Use HTTPS for rubygems.org - [@O-I](https://github.com/O-I). ### 0.10.1 (12/28/2014) * [#868](https://github.com/ruby-grape/grape/pull/868), [#862](https://github.com/ruby-grape/grape/pull/862), [#861](https://github.com/ruby-grape/grape/pull/861): Fixed `version`, `prefix`, and other settings being overridden or changing scope when mounting API - [@yesmeck](https://github.com/yesmeck). * [#864](https://github.com/ruby-grape/grape/pull/864): Fixed `declared(params, include_missing: false)` now returning attributes with `nil` and `false` values - [@ppadron](https://github.com/ppadron). ### 0.10.0 (12/19/2014) * [#803](https://github.com/ruby-grape/grape/pull/803), [#820](https://github.com/ruby-grape/grape/pull/820): Added `all_or_none_of` parameter validator - [@loveltyoic](https://github.com/loveltyoic), [@natecj](https://github.com/natecj). * [#774](https://github.com/ruby-grape/grape/pull/774): Extended `mutually_exclusive`, `exactly_one_of`, `at_least_one_of` to work inside any kind of group: `requires` or `optional`, `Hash` or `Array` - [@ShPakvel](https://github.com/ShPakvel). * [#743](https://github.com/ruby-grape/grape/pull/743): Added `allow_blank` parameter validator to validate non-empty strings - [@elado](https://github.com/elado). * [#745](https://github.com/ruby-grape/grape/pull/745): Removed `atom+xml`, `rss+xml`, and `jsonapi` content-types - [@akabraham](https://github.com/akabraham). * [#745](https://github.com/ruby-grape/grape/pull/745): Added `:binary, application/octet-stream` content-type - [@akabraham](https://github.com/akabraham). * [#757](https://github.com/ruby-grape/grape/pull/757): Changed `desc` can now be used with a block syntax - [@dspaeth-faber](https://github.com/dspaeth-faber). * [#779](https://github.com/ruby-grape/grape/pull/779): Fixed using `values` with a `default` proc - [@ShPakvel](https://github.com/ShPakvel). * [#799](https://github.com/ruby-grape/grape/pull/799): Fixed custom validators with required `Hash`, `Array` types - [@bwalex](https://github.com/bwalex). * [#784](https://github.com/ruby-grape/grape/pull/784): Fixed `present` to not overwrite the previously added contents of the response body whebn called more than once - [@mfunaro](https://github.com/mfunaro). * [#809](https://github.com/ruby-grape/grape/pull/809): Removed automatic `(.:format)` suffix on paths if you're using only one format (e.g., with `format :json`, `/path` will respond with JSON but `/path.xml` will be a 404) - [@ajvondrak](https://github.com/ajvondrak). * [#816](https://github.com/ruby-grape/grape/pull/816): Added ability to filter out missing params if params is a nested hash with `declared(params, include_missing: false)` - [@georgimitev](https://github.com/georgimitev). * [#819](https://github.com/ruby-grape/grape/pull/819): Allowed both `desc` and `description` in the params DSL - [@mzikherman](https://github.com/mzikherman). * [#821](https://github.com/ruby-grape/grape/pull/821): Fixed passing string value when hash is expected in params - [@rebelact](https://github.com/rebelact). * [#824](https://github.com/ruby-grape/grape/pull/824): Validate array params against list of acceptable values - [@dnd](https://github.com/dnd). * [#813](https://github.com/ruby-grape/grape/pull/813): Routing methods dsl refactored to get rid of explicit `paths` parameter - [@AlexYankee](https://github.com/AlexYankee). * [#826](https://github.com/ruby-grape/grape/pull/826): Find `coerce_type` for `Array` when not specified - [@manovotn](https://github.com/manovotn). * [#645](https://github.com/ruby-grape/grape/issues/645): Invoking `body false` will return `204 No Content` - [@dblock](https://github.com/dblock). * [#801](https://github.com/ruby-grape/grape/issues/801): Only evaluate permitted parameter `values` and `default` lazily on each request when declared as a proc - [@dblock](https://github.com/dblock). * [#679](https://github.com/ruby-grape/grape/issues/679): Fixed `OPTIONS` method returning 404 when combined with `prefix` - [@dblock](https://github.com/dblock). * [#679](https://github.com/ruby-grape/grape/issues/679): Fixed unsupported methods returning 404 instead of 405 when combined with `prefix` - [@dblock](https://github.com/dblock). ### 0.9.0 (8/27/2014) #### Features * [#691](https://github.com/ruby-grape/grape/issues/691): Added `at_least_one_of` parameter validator - [@dblock](https://github.com/dblock). * [#698](https://github.com/ruby-grape/grape/pull/698): `error!` sets `status` for `Endpoint` too - [@dspaeth-faber](https://github.com/dspaeth-faber). * [#703](https://github.com/ruby-grape/grape/pull/703): Added support for Auth-Middleware extension - [@dspaeth-faber](https://github.com/dspaeth-faber). * [#703](https://github.com/ruby-grape/grape/pull/703): Removed `Grape::Middleware::Auth::Basic` - [@dspaeth-faber](https://github.com/dspaeth-faber). * [#703](https://github.com/ruby-grape/grape/pull/703): Removed `Grape::Middleware::Auth::Digest` - [@dspaeth-faber](https://github.com/dspaeth-faber). * [#703](https://github.com/ruby-grape/grape/pull/703): Removed `Grape::Middleware::Auth::OAuth2` - [@dspaeth-faber](https://github.com/dspaeth-faber). * [#719](https://github.com/ruby-grape/grape/pull/719): Allow passing options hash to a custom validator - [@elado](https://github.com/elado). * [#716](https://github.com/ruby-grape/grape/pull/716): Calling `content-type` will now return the current content-type - [@dblock](https://github.com/dblock). * [#705](https://github.com/ruby-grape/grape/pull/705): Errors can now be presented with a `Grape::Entity` class - [@dspaeth-faber](https://github.com/dspaeth-faber). #### Fixes * [#687](https://github.com/ruby-grape/grape/pull/687): Fix: `mutually_exclusive` and `exactly_one_of` validation error messages now label parameters as strings, consistently with `requires` and `optional` - [@dblock](https://github.com/dblock). ### 0.8.0 (7/10/2014) #### Features * [#639](https://github.com/ruby-grape/grape/pull/639): Added support for blocks with reusable params - [@mibon](https://github.com/mibon). * [#637](https://github.com/ruby-grape/grape/pull/637): Added support for `exactly_one_of` parameter validation - [@Morred](https://github.com/Morred). * [#626](https://github.com/ruby-grape/grape/pull/626): Added support for `mutually_exclusive` parameters - [@oliverbarnes](https://github.com/oliverbarnes). * [#617](https://github.com/ruby-grape/grape/pull/617): Running tests on Ruby 2.1.1, Rubinius 2.1 and 2.2, Ruby and JRuby HEAD - [@dblock](https://github.com/dblock). * [#397](https://github.com/ruby-grape/grape/pull/397): Adds `Grape::Endpoint.before_each` to allow easy helper stubbing - [@mbleigh](https://github.com/mbleigh). * [#673](https://github.com/ruby-grape/grape/pull/673): Avoid requiring non-existent fields when using Grape::Entity documentation - [@qqshfox](https://github.com/qqshfox). #### Fixes * [#671](https://github.com/ruby-grape/grape/pull/671): Allow required param with predefined set of values to be nil inside optional group - [@dm1try](https://github.com/dm1try). * [#651](https://github.com/ruby-grape/grape/pull/651): The `rescue_from` keyword now properly defaults to rescuing subclasses of exceptions - [@xevix](https://github.com/xevix). * [#614](https://github.com/ruby-grape/grape/pull/614): Params with `nil` value are now refused by `RegexpValidator` - [@dm1try](https://github.com/dm1try). * [#494](https://github.com/ruby-grape/grape/issues/494): Fixed performance issue with requests carrying a large payload - [@dblock](https://github.com/dblock). * [#619](https://github.com/ruby-grape/grape/pull/619): Convert specs to RSpec 3 syntax with Transpec - [@danielspector](https://github.com/danielspector). * [#632](https://github.com/ruby-grape/grape/pull/632): `Grape::Endpoint#present` causes ActiveRecord to make an extra query during entity's detection - [@fixme](https://github.com/fixme). ### 0.7.0 (4/2/2014) #### Features * [#558](https://github.com/ruby-grape/grape/pull/558): Support lambda-based values for params - [@wpschallenger](https://github.com/wpschallenger). * [#510](https://github.com/ruby-grape/grape/pull/510): Support lambda-based default values for params - [@myitcv](https://github.com/myitcv). * [#511](https://github.com/ruby-grape/grape/pull/511): Added `required` option for OAuth2 middleware - [@bcm](https://github.com/bcm). * [#520](https://github.com/ruby-grape/grape/pull/520): Use `default_error_status` to specify the default status code returned from `error!` - [@salimane](https://github.com/salimane). * [#525](https://github.com/ruby-grape/grape/pull/525): The default status code returned from `error!` has been changed from 403 to 500 - [@dblock](https://github.com/dblock). * [#526](https://github.com/ruby-grape/grape/pull/526): Allowed specifying headers in `error!` - [@dblock](https://github.com/dblock). * [#527](https://github.com/ruby-grape/grape/pull/527): The `before_validation` callback is now a distinct one - [@myitcv](https://github.com/myitcv). * [#530](https://github.com/ruby-grape/grape/pull/530): Added ability to restrict `declared(params)` to the local endpoint with `include_parent_namespaces: false` - [@myitcv](https://github.com/myitcv). * [#531](https://github.com/ruby-grape/grape/pull/531): Helpers are now available to auth middleware, executing in the context of the endpoint - [@joelvh](https://github.com/joelvh). * [#540](https://github.com/ruby-grape/grape/pull/540): Ruby 2.1.0 is now supported - [@salimane](https://github.com/salimane). * [#544](https://github.com/ruby-grape/grape/pull/544): The `rescue_from` keyword now handles subclasses of exceptions by default - [@xevix](https://github.com/xevix). * [#545](https://github.com/ruby-grape/grape/pull/545): Added `type` (`Array` or `Hash`) support to `requires`, `optional` and `group` - [@bwalex](https://github.com/bwalex). * [#550](https://github.com/ruby-grape/grape/pull/550): Added possibility to define reusable params - [@dm1try](https://github.com/dm1try). * [#560](https://github.com/ruby-grape/grape/pull/560): Use `Grape::Entity` documentation to define required and optional parameters with `requires using:` - [@reynardmh](https://github.com/reynardmh). * [#572](https://github.com/ruby-grape/grape/pull/572): Added `documentation` support to `requires`, `optional` and `group` parameters - [@johnallen3d](https://github.com/johnallen3d). #### Fixes * [#600](https://github.com/ruby-grape/grape/pull/600): Don't use an `Entity` constant that is available in the namespace as presenter - [@fuksito](https://github.com/fuksito). * [#590](https://github.com/ruby-grape/grape/pull/590): Fix issue where endpoint param of type `Integer` cannot set values array - [@xevix](https://github.com/xevix). * [#586](https://github.com/ruby-grape/grape/pull/586): Do not repeat the same validation error messages - [@kiela](https://github.com/kiela). * [#508](https://github.com/ruby-grape/grape/pull/508): Allow parameters, such as content encoding, in `content_type` - [@dm1try](https://github.com/dm1try). * [#492](https://github.com/ruby-grape/grape/pull/492): Don't allow to have nil value when a param is required and has a list of allowed values - [@Antti](https://github.com/Antti). * [#495](https://github.com/ruby-grape/grape/pull/495): Fixed `ParamsScope#params` for parameters nested inside arrays - [@asross](https://github.com/asross). * [#498](https://github.com/ruby-grape/grape/pull/498): Dry'ed up options and headers logic, allow headers to be passed to OPTIONS requests - [@karlfreeman](https://github.com/karlfreeman). * [#500](https://github.com/ruby-grape/grape/pull/500): Skip entity auto-detection when explicitely passed - [@yaneq](https://github.com/yaneq). * [#503](https://github.com/ruby-grape/grape/pull/503): Calling declared(params) from child namespace fails to include parent namespace defined params - [@myitcv](https://github.com/myitcv). * [#512](https://github.com/ruby-grape/grape/pull/512): Don't create `Grape::Request` multiple times - [@dblock](https://github.com/dblock). * [#538](https://github.com/ruby-grape/grape/pull/538): Fixed default values for grouped params - [@dm1try](https://github.com/dm1try). * [#549](https://github.com/ruby-grape/grape/pull/549): Fixed handling of invalid version headers to return 406 if a header cannot be parsed - [@bwalex](https://github.com/bwalex). * [#557](https://github.com/ruby-grape/grape/pull/557): Pass `content_types` option to `Grape::Middleware::Error` to fix the content-type header for custom formats - [@bernd](https://github.com/bernd). * [#585](https://github.com/ruby-grape/grape/pull/585): Fix after boot thread-safety issue - [@etehtsea](https://github.com/etehtsea). * [#587](https://github.com/ruby-grape/grape/pull/587): Fix oauth2 middleware compatibility with [draft-ietf-oauth-v2-31](http://tools.ietf.org/html/draft-ietf-oauth-v2-31) spec - [@etehtsea](https://github.com/etehtsea). * [#610](https://github.com/ruby-grape/grape/pull/610): Fixed group keyword was not working with type parameter - [@klausmeyer](https://github.com/klausmeyer). ### 0.6.1 (10/19/2013) #### Features * [#475](https://github.com/ruby-grape/grape/pull/475): Added support for the `:jsonapi`, `application/vnd.api+json` media type registered at http://jsonapi.org - [@bcm](https://github.com/bcm). * [#471](https://github.com/ruby-grape/grape/issues/471): Added parameter validator for a list of allowed values - [@vickychijwani](https://github.com/vickychijwani). * [#488](https://github.com/ruby-grape/grape/issues/488): Upgraded to Virtus 1.0 - [@dblock](https://github.com/dblock). #### Fixes * [#477](https://github.com/ruby-grape/grape/pull/477): Fixed `default_error_formatter` which takes a format symbol - [@vad4msiu](https://github.com/vad4msiu). #### Development * Implemented Rubocop, a Ruby code static code analyzer - [@dblock](https://github.com/dblock). ### 0.6.0 (9/16/2013) #### Features * Grape is no longer tested against Ruby 1.8.7 - [@dblock](https://github.com/dblock). * [#442](https://github.com/ruby-grape/grape/issues/442): Enable incrementally building on top of a previous API version - [@dblock](https://github.com/dblock). * [#442](https://github.com/ruby-grape/grape/issues/442): API `version` can now take an array of multiple versions - [@dblock](https://github.com/dblock). * [#444](https://github.com/ruby-grape/grape/issues/444): Added `:en` as fallback locale for I18n - [@aew](https://github.com/aew). * [#448](https://github.com/ruby-grape/grape/pull/448): Adding POST style parameters for DELETE requests - [@dquimper](https://github.com/dquimper). * [#450](https://github.com/ruby-grape/grape/pull/450): Added option to pass an exception handler lambda as an argument to `rescue_from` - [@robertopedroso](https://github.com/robertopedroso). * [#443](https://github.com/ruby-grape/grape/pull/443): Let `requires` and `optional` take blocks that initialize new scopes - [@asross](https://github.com/asross). * [#452](https://github.com/ruby-grape/grape/pull/452): Added `with` as a hash option to specify handlers for `rescue_from` and `error_formatter` - [@robertopedroso](https://github.com/robertopedroso). * [#433](https://github.com/ruby-grape/grape/issues/433), [#462](https://github.com/ruby-grape/grape/issues/462): Validation errors are now collected and `Grape::Exceptions::ValidationErrors` is raised - [@stevschmid](https://github.com/stevschmid). #### Fixes * [#428](https://github.com/ruby-grape/grape/issues/428): Removes memoization from `Grape::Request` params to prevent middleware from freezing parameter values before `Formatter` can get them - [@mbleigh](https://github.com/mbleigh). ### 0.5.0 (6/14/2013) #### Features * [#344](https://github.com/ruby-grape/grape/pull/344): Added `parser :type, nil` which disables input parsing for a given content-type - [@dblock](https://github.com/dblock). * [#381](https://github.com/ruby-grape/grape/issues/381): Added `cascade false` option at API level to remove the `X-Cascade: true` header from the API response - [@dblock](https://github.com/dblock). * [#392](https://github.com/ruby-grape/grape/pull/392): Extracted headers and params from `Endpoint` to `Grape::Request` - [@niedhui](https://github.com/niedhui). * [#376](https://github.com/ruby-grape/grape/pull/376): Added `route_param`, syntax sugar for quick declaration of route parameters - [@mbleigh](https://github.com/mbleigh). * [#390](https://github.com/ruby-grape/grape/pull/390): Added default value for an `optional` parameter - [@oivoodoo](https://github.com/oivoodoo). * [#403](https://github.com/ruby-grape/grape/pull/403): Added support for versioning using the `Accept-Version` header - [@politician](https://github.com/politician). * [#407](https://github.com/ruby-grape/grape/issues/407): Specifying `default_format` will also set the default POST/PUT data parser to the given format - [@dblock](https://github.com/dblock). * [#241](https://github.com/ruby-grape/grape/issues/241): Present with multiple entities using an optional Symbol - [@niedhui](https://github.com/niedhui). #### Fixes * [#378](https://github.com/ruby-grape/grape/pull/378): Fix: stop rescuing all exceptions during formatting - [@kbarrette](https://github.com/kbarrette). * [#380](https://github.com/ruby-grape/grape/pull/380): Fix: `Formatter#read_body_input` when transfer encoding is chunked - [@paulnicholon](https://github.com/paulnicholson). * [#347](https://github.com/ruby-grape/grape/issues/347): Fix: handling non-hash body params - [@paulnicholon](https://github.com/paulnicholson). * [#394](https://github.com/ruby-grape/grape/pull/394): Fix: path version no longer overwrites a `version` parameter - [@tmornini](https://github.com/tmornini). * [#412](https://github.com/ruby-grape/grape/issues/412): Fix: specifying `content_type` will also override the selection of the data formatter - [@dblock](https://github.com/dblock). * [#383](https://github.com/ruby-grape/grape/issues/383): Fix: Mounted APIs aren't inheriting settings (including `before` and `after` filters) - [@seanmoon](https://github.com/seanmoon). * [#408](https://github.com/ruby-grape/grape/pull/408): Fix: Goliath passes request header keys as symbols not strings - [@bobek](https://github.com/bobek). * [#417](https://github.com/ruby-grape/grape/issues/417): Fix: Rails 4 does not rewind input, causes POSTed data to be empty - [@dblock](https://github.com/dblock). * [#423](https://github.com/ruby-grape/grape/pull/423): Fix: `Grape::Endpoint#declared` now correctly handles nested params (ie. declared with `group`) - [@jbarreneche](https://github.com/jbarreneche). * [#427](https://github.com/ruby-grape/grape/issues/427): Fix: `declared(params)` breaks when `params` contains array - [@timhabermaas](https://github.com/timhabermaas). ### 0.4.1 (4/1/2013) * [#375](https://github.com/ruby-grape/grape/pull/375): Fix: throwing an `:error` inside a middleware doesn't respect the `format` settings - [@dblock](https://github.com/dblock). ### 0.4.0 (3/17/2013) * [#356](https://github.com/ruby-grape/grape/pull/356): Fix: presenting collections other than `Array` (eg. `ActiveRecord::Relation`) - [@zimbatm](https://github.com/zimbatm). * [#352](https://github.com/ruby-grape/grape/pull/352): Fix: using `Rack::JSONP` with `Grape::Entity` responses - [@deckchair](https://github.com/deckchair). * [#347](https://github.com/ruby-grape/grape/issues/347): Grape will accept any valid JSON as PUT or POST, including strings, symbols and arrays - [@qqshfox](https://github.com/qqshfox), [@dblock](https://github.com/dblock). * [#347](https://github.com/ruby-grape/grape/issues/347): JSON format APIs always return valid JSON, eg. strings are now returned as `"string"` and no longer `string` - [@dblock](https://github.com/dblock). * Raw body input from POST and PUT requests (`env['rack.input'].read`) is now available in `api.request.input` - [@dblock](https://github.com/dblock). * Parsed body input from POST and PUT requests is now available in `api.request.body` - [@dblock](https://github.com/dblock). * [#343](https://github.com/ruby-grape/grape/pull/343): Fix: return `Content-Type: text/plain` with error 405 - [@gustavosaume](https://github.com/gustavosaume), [@wyattisimo](https://github.com/wyattisimo). * [#357](https://github.com/ruby-grape/grape/pull/357): Grape now requires Rack 1.3.0 or newer - [@jhecking](https://github.com/jhecking). * [#320](https://github.com/ruby-grape/grape/issues/320): API `namespace` now supports `requirements` - [@niedhui](https://github.com/niedhui). * [#353](https://github.com/ruby-grape/grape/issues/353): Revert to standard Ruby logger formatter, `require active_support/all` if you want old behavior - [@rhunter](https://github.com/rhunter), [@dblock](https://github.com/dblock). * Fix: `undefined method 'call' for nil:NilClass` for an API method implementation without a block, now returns an empty string - [@dblock](https://github.com/dblock). ### 0.3.2 (2/28/2013) * [#355](https://github.com/ruby-grape/grape/issues/355): Relax dependency constraint on Hashie - [@reset](https://github.com/reset). ### 0.3.1 (2/25/2013) * [#351](https://github.com/ruby-grape/grape/issues/351): Compatibility with Ruby 2.0 - [@mbleigh](https://github.com/mbleigh). ### 0.3.0 (02/21/2013) * [#294](https://github.com/ruby-grape/grape/issues/294): Extracted `Grape::Entity` into a [grape-entity](https://github.com/agileanimal/grape-entity) gem - [@agileanimal](https://github.com/agileanimal). * [#340](https://github.com/ruby-grape/grape/pull/339), [#342](https://github.com/ruby-grape/grape/pull/342): Added `:cascade` option to `version` to allow disabling of rack/mount cascade behavior - [@dieb](https://github.com/dieb). * [#333](https://github.com/ruby-grape/grape/pull/333): Added support for validation of arrays in `params` - [@flyerhzm](https://github.com/flyerhzm). * [#306](https://github.com/ruby-grape/grape/issues/306): Added I18n support for all Grape exceptions - [@niedhui](https://github.com/niedhui). * [#309](https://github.com/ruby-grape/grape/pull/309): Added XML support to the entity presenter - [@johnnyiller](https://github.com/johnnyiller), [@dblock](https://github.com/dblock). * [#131](https://github.com/ruby-grape/grape/issues/131): Added instructions for Grape API reloading in Rails - [@jyn](https://github.com/jyn), [@dblock](https://github.com/dblock). * [#317](https://github.com/ruby-grape/grape/issues/317): Added `headers` that returns a hash of parsed HTTP request headers - [@dblock](https://github.com/dblock). * [#332](https://github.com/ruby-grape/grape/pull/332): `Grape::Exceptions::Validation` now contains full nested parameter names - [@alovak](https://github.com/alovak). * [#328](https://github.com/ruby-grape/grape/issues/328): API version can now be specified as both String and Symbol - [@dblock](https://github.com/dblock). * [#190](https://github.com/ruby-grape/grape/issues/190): When you add a `GET` route for a resource, a route for the `HEAD` method will also be added automatically. You can disable this behavior with `do_not_route_head!` - [@dblock](https://github.com/dblock). * Added `do_not_route_options!`, which disables the automatic creation of the `OPTIONS` route - [@dblock](https://github.com/dblock). * [#309](https://github.com/ruby-grape/grape/pull/309): An XML format API will return an error instead of returning a string representation of the response if the latter cannot be converted to XML - [@dblock](https://github.com/dblock). * A formatter that raises an exception will cause the API to return a 500 error - [@dblock](https://github.com/dblock). * [#322](https://github.com/ruby-grape/grape/issues/322): When returning a 406 status, Grape will include the requested format or content-type in the response body - [@dblock](https://github.com/dblock). * [#60](https://github.com/ruby-grape/grape/issues/60): Fix: mounting of a Grape API onto a path - [@dblock](https://github.com/dblock). * [#335](https://github.com/ruby-grape/grape/pull/335): Fix: request body parameters from a `PATCH` request not available in `params` - [@FreakenK](https://github.com/FreakenK). ### 0.2.6 (01/11/2013) * Fix: support content-type with character set when parsing POST and PUT input - [@dblock](https://github.com/dblock). * Fix: CVE-2013-0175, multi_xml parse vulnerability, require multi_xml 0.5.2 - [@dblock](https://github.com/dblock). ### 0.2.5 (01/10/2013) * Added support for custom parsers via `parser`, in addition to built-in multipart, JSON and XML parsers - [@dblock](https://github.com/dblock). * Removed `body_params`, data sent via a POST or PUT with a supported content-type is merged into `params` - [@dblock](https://github.com/dblock). * Setting `format` will automatically remove other content-types by calling `content_type` - [@dblock](https://github.com/dblock). * Setting `content_type` will prevent any input data other than the matching content-type or any Rack-supported form and parseable media types (`application/x-www-form-urlencoded`, `multipart/form-data`, `multipart/related` and `multipart/mixed`) from being parsed - [@dblock](https://github.com/dblock). * [#305](https://github.com/ruby-grape/grape/issues/305): Fix: presenting arrays of objects via `represent` or when auto-detecting an `Entity` constant in the objects being presented - [@brandonweiss](https://github.com/brandonweiss). * [#306](https://github.com/ruby-grape/grape/issues/306): Added i18n support for validation error messages - [@niedhui](https://github.com/niedhui). ### 0.2.4 (01/06/2013) * [#297](https://github.com/ruby-grape/grape/issues/297): Added `default_error_formatter` - [@dblock](https://github.com/dblock). * [#297](https://github.com/ruby-grape/grape/issues/297): Setting `format` will automatically set `default_error_formatter` - [@dblock](https://github.com/dblock). * [#295](https://github.com/ruby-grape/grape/issues/295): Storing original API source block in endpoint's `source` attribute - [@dblock](https://github.com/dblock). * [#293](https://github.com/ruby-grape/grape/pull/293): Added options to `cookies.delete`, enables passing a path - [@inst](https://github.com/inst). * [#174](https://github.com/ruby-grape/grape/issues/174): The value of `env['PATH_INFO']` is no longer altered with `path` versioning - [@dblock](https://github.com/dblock). * [#296](https://github.com/ruby-grape/grape/issues/296): Fix: ArgumentError with default error formatter - [@dblock](https://github.com/dblock). * [#298](https://github.com/ruby-grape/grape/pull/298): Fix: subsequent calls to `body_params` would fail due to IO read - [@justinmcp](https://github.com/justinmcp). * [#301](https://github.com/ruby-grape/grape/issues/301): Fix: symbol memory leak in cookie and formatter middleware - [@dblock](https://github.com/dblock). * [#300](https://github.com/ruby-grape/grape/issues/300): Fix `Grape::API.routes` to include mounted api routes - [@aiwilliams](https://github.com/aiwilliams). * [#302](https://github.com/ruby-grape/grape/pull/302): Fix: removed redundant `autoload` entries - [@ugisozols](https://github.com/ugisozols). * [#172](https://github.com/ruby-grape/grape/issues/172): Fix: MultiJson deprecated methods warnings - [@dblock](https://github.com/dblock). * [#133](https://github.com/ruby-grape/grape/issues/133): Fix: header-based versioning with use of `prefix` - [@seanmoon](https://github.com/seanmoon), [@dblock](https://github.com/dblock). * [#280](https://github.com/ruby-grape/grape/issues/280): Fix: grouped parameters mangled in `route_params` hash - [@marcusg](https://github.com/marcusg), [@dblock](https://github.com/dblock). * [#304](https://github.com/ruby-grape/grape/issues/304): Fix: `present x, :with => Entity` returns class references with `format :json` - [@dblock](https://github.com/dblock). * [#196](https://github.com/ruby-grape/grape/issues/196): Fix: root requests don't work with `prefix` - [@dblock](https://github.com/dblock). ### 0.2.3 (24/12/2012) * [#179](https://github.com/ruby-grape/grape/issues/178): Using `content_type` will remove all default content-types - [@dblock](https://github.com/dblock). * [#265](https://github.com/ruby-grape/grape/issues/264): Fix: Moved `ValidationError` into `Grape::Exceptions` - [@thepumpkin1979](https://github.com/thepumpkin1979). * [#269](https://github.com/ruby-grape/grape/pull/269): Fix: `LocalJumpError` will not be raised when using explict return in API methods - [@simulacre](https://github.com/simulacre). * [#86](https://github.com/ruby-grape/grape/issues/275): Fix Path-based versioning not recognizing `/` route - [@walski](https://github.com/walski). * [#273](https://github.com/ruby-grape/grape/pull/273): Disabled formatting via `serializable_hash` and added support for `format :serializable_hash` - [@dblock](https://github.com/dblock). * [#277](https://github.com/ruby-grape/grape/pull/277): Added a DSL to declare `formatter` in API settings - [@tim-vandecasteele](https://github.com/tim-vandecasteele). * [#284](https://github.com/ruby-grape/grape/pull/284): Added a DSL to declare `error_formatter` in API settings - [@dblock](https://github.com/dblock). * [#285](https://github.com/ruby-grape/grape/pull/285): Removed `error_format` from API settings, now matches request format - [@dblock](https://github.com/dblock). * [#290](https://github.com/ruby-grape/grape/pull/290): The default error format for XML is now `error/message` instead of `hash/error` - [@dpsk](https://github.com/dpsk). * [#44](https://github.com/ruby-grape/grape/issues/44): Pass `env` into formatters to enable templating - [@dblock](https://github.com/dblock). ### 0.2.2 (12/10/2012) #### Features * [#201](https://github.com/ruby-grape/grape/pull/201), [#236](https://github.com/ruby-grape/grape/pull/236), [#221](https://github.com/ruby-grape/grape/pull/221): Added coercion and validations support to `params` DSL - [@schmurfy](https://github.com/schmurfy), [@tim-vandecasteele](https://github.com/tim-vandecasteele), [@adamgotterer](https://github.com/adamgotterer). * [#204](https://github.com/ruby-grape/grape/pull/204): Added ability to declare shared `params` at `namespace` level - [@tim-vandecasteele](https://github.com/tim-vandecasteele). * [#234](https://github.com/ruby-grape/grape/pull/234): Added a DSL for creating entities via mixin - [@mbleigh](https://github.com/mbleigh). * [#240](https://github.com/ruby-grape/grape/pull/240): Define API response format from a query string `format` parameter, if specified - [@neetiraj](https://github.com/neetiraj). * Adds Endpoint#declared to easily filter out unexpected params - [@mbleigh](https://github.com/mbleigh). #### Fixes * [#248](https://github.com/ruby-grape/grape/pull/248): Fix: API `version` returns last version set - [@narkoz](https://github.com/narkoz). * [#242](https://github.com/ruby-grape/grape/issues/242): Fix: permanent redirect status should be `301`, was `304` - [@adamgotterer](https://github.com/adamgotterer). * [#211](https://github.com/ruby-grape/grape/pull/211): Fix: custom validations are no longer triggered when optional and parameter is not present - [@adamgotterer](https://github.com/adamgotterer). * [#210](https://github.com/ruby-grape/grape/pull/210): Fix: `Endpoint#body_params` causing undefined method 'size' - [@adamgotterer](https://github.com/adamgotterer). * [#205](https://github.com/ruby-grape/grape/pull/205): Fix: Corrected parsing of empty JSON body on POST/PUT - [@tim-vandecasteele](https://github.com/tim-vandecasteele). * [#181](https://github.com/ruby-grape/grape/pull/181): Fix: Corrected JSON serialization of nested hashes containing `Grape::Entity` instances - [@benrosenblum](https://github.com/benrosenblum). * [#203](https://github.com/ruby-grape/grape/pull/203): Added a check to `Entity#serializable_hash` that verifies an entity exists on an object - [@adamgotterer](https://github.com/adamgotterer). * [#208](https://github.com/ruby-grape/grape/pull/208): `Entity#serializable_hash` must also check if attribute is generated by a user supplied block - [@ppadron](https://github.com/ppadron). * [#252](https://github.com/ruby-grape/grape/pull/252): Resources that don't respond to a requested HTTP method return 405 (Method Not Allowed) instead of 404 (Not Found) - [@simulacre](https://github.com/simulacre). ### 0.2.1 (7/11/2012) * [#186](https://github.com/ruby-grape/grape/issues/186): Fix: helpers allow multiple calls with modules and blocks - [@ppadron](https://github.com/ppadron). * [#188](https://github.com/ruby-grape/grape/pull/188): Fix: multi-method routes append '(.:format)' only once - [@kainosnoema](https://github.com/kainosnoema). * [#64](https://github.com/ruby-grape/grape/issues/64), [#180](https://github.com/ruby-grape/grape/pull/180): Added support to `GET` request bodies as parameters - [@bobbytables](https://github.com/bobbytables). * [#175](https://github.com/ruby-grape/grape/pull/175): Added support for API versioning based on a request parameter - [@jackcasey](https://github.com/jackcasey). * [#168](https://github.com/ruby-grape/grape/pull/168): Fix: Formatter can parse symbol keys in the headers hash - [@netmask](https://github.com/netmask). * [#169](https://github.com/ruby-grape/grape/pull/169): Silence multi_json deprecation warnings - [@whiteley](https://github.com/whiteley). * [#166](https://github.com/ruby-grape/grape/pull/166): Added support for `redirect`, including permanent and temporary - [@allenwei](https://github.com/allenwei). * [#159](https://github.com/ruby-grape/grape/pull/159): Added `:requirements` to routes, allowing to use reserved characters in paths - [@gaiottino](https://github.com/gaiottino). * [#156](https://github.com/ruby-grape/grape/pull/156): Added support for adding formatters to entities - [@bobbytables](https://github.com/bobbytables). * [#183](https://github.com/ruby-grape/grape/pull/183): Added ability to include documentation in entities - [@flah00](https://github.com/flah00). * [#189](https://github.com/ruby-grape/grape/pull/189): `HEAD` requests no longer return a body - [@stephencelis](https://github.com/stephencelis). * [#97](https://github.com/ruby-grape/grape/issues/97): Allow overriding `Content-Type` - [@dblock](https://github.com/dblock). ### 0.2.0 (3/28/2012) * Added support for inheriting exposures from entities - [@bobbytables](https://github.com/bobbytables). * Extended formatting with `default_format` - [@dblock](https://github.com/dblock). * Added support for cookies - [@lukaszsliwa](https://github.com/lukaszsliwa). * Added support for declaring additional content-types - [@joeyAghion](https://github.com/joeyAghion). * Added support for HTTP PATCH - [@LTe](https://github.com/LTe). * Added support for describing, documenting and reflecting APIs - [@dblock](https://github.com/dblock). * Added support for anchoring and vendoring - [@jwkoelewijn](https://github.com/jwkoelewijn). * Added support for HTTP OPTIONS - [@grimen](https://github.com/grimen). * Added support for silencing logger - [@evansj](https://github.com/evansj). * Added support for helper modules - [@freelancing-god](https://github.com/freelancing-god). * Added support for Accept header-based versioning - [@jch](https://github.com/jch), [@rodzyn](https://github.com/rodzyn). * Added support for mounting APIs and other Rack applications within APIs - [@mbleigh](https://github.com/mbleigh). * Added entities, multiple object representations - [@mbleigh](https://github.com/mbleigh). * Added ability to handle XML in the incoming request body - [@jwillis](https://github.com/jwillis). * Added support for a configurable logger - [@mbleigh](https://github.com/mbleigh). * Added support for before and after filters - [@mbleigh](https://github.com/mbleigh). * Extended `rescue_from`, which can now take a block - [@dblock](https://github.com/dblock). ### 0.1.5 (6/14/2011) * Extended exception handling to all exceptions - [@dblock](https://github.com/dblock). * Added support for returning JSON objects from within error blocks - [@dblock](https://github.com/dblock). * Added support for handling incoming JSON in body - [@tedkulp](https://github.com/tedkulp). * Added support for HTTP digest authentication - [@daddz](https://github.com/daddz). ### 0.1.4 (4/8/2011) * Allow multiple definitions of the same endpoint under multiple versions - [@chrisrhoden](https://github.com/chrisrhoden). * Added support for multipart URL parameters - [@mcastilho](https://github.com/mcastilho). * Added support for custom formatters - [@spraints](https://github.com/spraints). ### 0.1.3 (1/10/2011) * Added support for JSON format in route matching - [@aiwilliams](https://github.com/aiwilliams). * Added suport for custom middleware - [@mbleigh](https://github.com/mbleigh). ### 0.1.1 (11/14/2010) * Endpoints properly reset between each request - [@mbleigh](https://github.com/mbleigh). ### 0.1.0 (11/13/2010) * Initial public release - [@mbleigh](https://github.com/mbleigh). grape-1.0.2/README.md0000644000004100000410000027152213231337007014127 0ustar www-datawww-data![grape logo](grape.png) [![Gem Version](https://badge.fury.io/rb/grape.svg)](http://badge.fury.io/rb/grape) [![Build Status](https://travis-ci.org/ruby-grape/grape.svg?branch=master)](https://travis-ci.org/ruby-grape/grape) [![Dependency Status](https://gemnasium.com/ruby-grape/grape.svg)](https://gemnasium.com/ruby-grape/grape) [![Code Climate](https://codeclimate.com/github/ruby-grape/grape.svg)](https://codeclimate.com/github/ruby-grape/grape) [![Coverage Status](https://coveralls.io/repos/github/ruby-grape/grape/badge.svg?branch=master)](https://coveralls.io/github/ruby-grape/grape?branch=master) [![Inline docs](http://inch-ci.org/github/ruby-grape/grape.svg)](http://inch-ci.org/github/ruby-grape/grape) [![git.legal](https://git.legal/projects/1364/badge.svg "Number of libraries approved")](https://git.legal/projects/1364) [![Join the chat at https://gitter.im/ruby-grape/grape](https://badges.gitter.im/ruby-grape/grape.svg)](https://gitter.im/ruby-grape/grape?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## Table of Contents - [What is Grape?](#what-is-grape) - [Stable Release](#stable-release) - [Project Resources](#project-resources) - [Installation](#installation) - [Basic Usage](#basic-usage) - [Mounting](#mounting) - [Rack](#rack) - [ActiveRecord without Rails](#activerecord-without-rails) - [Alongside Sinatra (or other frameworks)](#alongside-sinatra-or-other-frameworks) - [Rails](#rails) - [Modules](#modules) - [Versioning](#versioning) - [Path](#path) - [Header](#header) - [Accept-Version Header](#accept-version-header) - [Param](#param) - [Describing Methods](#describing-methods) - [Parameters](#parameters) - [Params Class](#params-class) - [Declared](#declared) - [Include Parent Namespaces](#include-parent-namespaces) - [Include Missing](#include-missing) - [Parameter Validation and Coercion](#parameter-validation-and-coercion) - [Supported Parameter Types](#supported-parameter-types) - [Integer/Fixnum and Coercions](#integerfixnum-and-coercions) - [Custom Types and Coercions](#custom-types-and-coercions) - [Multipart File Parameters](#multipart-file-parameters) - [First-Class `JSON` Types](#first-class-json-types) - [Multiple Allowed Types](#multiple-allowed-types) - [Validation of Nested Parameters](#validation-of-nested-parameters) - [Dependent Parameters](#dependent-parameters) - [Group Options](#group-options) - [Alias](#alias) - [Built-in Validators](#built-in-validators) - [`allow_blank`](#allowblank) - [`values`](#values) - [`except_values`](#exceptvalues) - [`regexp`](#regexp) - [`mutually_exclusive`](#mutuallyexclusive) - [`exactly_one_of`](#exactlyoneof) - [`at_least_one_of`](#atleastoneof) - [`all_or_none_of`](#allornoneof) - [Nested `mutually_exclusive`, `exactly_one_of`, `at_least_one_of`, `all_or_none_of`](#nested-mutuallyexclusive-exactlyoneof-atleastoneof-allornoneof) - [Namespace Validation and Coercion](#namespace-validation-and-coercion) - [Custom Validators](#custom-validators) - [Validation Errors](#validation-errors) - [I18n](#i18n) - [Custom Validation messages](#custom-validation-messages) - [`presence`, `allow_blank`, `values`, `regexp`](#presence-allowblank-values-regexp) - [`mutually_exclusive`](#mutuallyexclusive-1) - [Overriding Attribute Names](#overriding-attribute-names) - [With Default](#with-default) - [Routes](#routes) - [Helpers](#helpers) - [Path Helpers](#path-helpers) - [Parameter Documentation](#parameter-documentation) - [Cookies](#cookies) - [HTTP Status Code](#http-status-code) - [Redirecting](#redirecting) - [Recognizing Path](#recognizing-path) - [Allowed Methods](#allowed-methods) - [Raising Exceptions](#raising-exceptions) - [Default Error HTTP Status Code](#default-error-http-status-code) - [Handling 404](#handling-404) - [Exception Handling](#exception-handling) - [Rescuing exceptions inside namespaces](#rescuing-exceptions-inside-namespaces) - [Unrescuable Exceptions](#unrescuable-exceptions) - [Rails 3.x](#rails-3x) - [Logging](#logging) - [API Formats](#api-formats) - [JSONP](#jsonp) - [CORS](#cors) - [Content-type](#content-type) - [API Data Formats](#api-data-formats) - [JSON and XML Processors](#json-and-xml-processors) - [RESTful Model Representations](#restful-model-representations) - [Grape Entities](#grape-entities) - [Hypermedia and Roar](#hypermedia-and-roar) - [Rabl](#rabl) - [Active Model Serializers](#active-model-serializers) - [Sending Raw or No Data](#sending-raw-or-no-data) - [Authentication](#authentication) - [Basic and Digest Auth](#basic-and-digest-auth) - [Register custom middleware for authentication](#register-custom-middleware-for-authentication) - [Describing and Inspecting an API](#describing-and-inspecting-an-api) - [Current Route and Endpoint](#current-route-and-endpoint) - [Before and After](#before-and-after) - [Anchoring](#anchoring) - [Using Custom Middleware](#using-custom-middleware) - [Grape Middleware](#grape-middleware) - [Rails Middleware](#rails-middleware) - [Remote IP](#remote-ip) - [Writing Tests](#writing-tests) - [Writing Tests with Rack](#writing-tests-with-rack) - [RSpec](#rspec) - [Airborne](#airborne) - [MiniTest](#minitest) - [Writing Tests with Rails](#writing-tests-with-rails) - [RSpec](#rspec-1) - [MiniTest](#minitest-1) - [Stubbing Helpers](#stubbing-helpers) - [Reloading API Changes in Development](#reloading-api-changes-in-development) - [Reloading in Rack Applications](#reloading-in-rack-applications) - [Reloading in Rails Applications](#reloading-in-rails-applications) - [Performance Monitoring](#performance-monitoring) - [Active Support Instrumentation](#active-support-instrumentation) - [endpoint_run.grape](#endpointrungrape) - [endpoint_render.grape](#endpointrendergrape) - [endpoint_run_filters.grape](#endpointrunfiltersgrape) - [endpoint_run_validators.grape](#endpointrunvalidatorsgrape) - [Monitoring Products](#monitoring-products) - [Contributing to Grape](#contributing-to-grape) - [License](#license) - [Copyright](#copyright) ## What is Grape? Grape is a REST-like API framework for Ruby. It's designed to run on Rack or complement existing web application frameworks such as Rails and Sinatra by providing a simple DSL to easily develop RESTful APIs. It has built-in support for common conventions, including multiple formats, subdomain/prefix restriction, content negotiation, versioning and much more. ## Stable Release You're reading the documentation for the stable release of Grape, **1.0.2**. Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version. ## Project Resources * [Grape Website](http://www.ruby-grape.org) * [Documentation](http://www.rubydoc.info/gems/grape) * Need help? Try [Grape Google Group](http://groups.google.com/group/ruby-grape) or [Gitter](https://gitter.im/ruby-grape/grape) * [Follow us on Twitter](https://twitter.com/grapeframework) ## Installation Grape is available as a gem, to install it just install the gem: gem install grape If you're using Bundler, add the gem to Gemfile. gem 'grape' Run `bundle install`. ## Basic Usage Grape APIs are Rack applications that are created by subclassing `Grape::API`. Below is a simple example showing some of the more common features of Grape in the context of recreating parts of the Twitter API. ```ruby module Twitter class API < Grape::API version 'v1', using: :header, vendor: 'twitter' format :json prefix :api helpers do def current_user @current_user ||= User.authorize!(env) end def authenticate! error!('401 Unauthorized', 401) unless current_user end end resource :statuses do desc 'Return a public timeline.' get :public_timeline do Status.limit(20) end desc 'Return a personal timeline.' get :home_timeline do authenticate! current_user.statuses.limit(20) end desc 'Return a status.' params do requires :id, type: Integer, desc: 'Status id.' end route_param :id do get do Status.find(params[:id]) end end desc 'Create a status.' params do requires :status, type: String, desc: 'Your status.' end post do authenticate! Status.create!({ user: current_user, text: params[:status] }) end desc 'Update a status.' params do requires :id, type: String, desc: 'Status ID.' requires :status, type: String, desc: 'Your status.' end put ':id' do authenticate! current_user.statuses.find(params[:id]).update({ user: current_user, text: params[:status] }) end desc 'Delete a status.' params do requires :id, type: String, desc: 'Status ID.' end delete ':id' do authenticate! current_user.statuses.find(params[:id]).destroy end end end end ``` ## Mounting ### Rack The above sample creates a Rack application that can be run from a rackup `config.ru` file with `rackup`: ```ruby run Twitter::API ``` And would respond to the following routes: GET /api/statuses/public_timeline GET /api/statuses/home_timeline GET /api/statuses/:id POST /api/statuses PUT /api/statuses/:id DELETE /api/statuses/:id Grape will also automatically respond to HEAD and OPTIONS for all GET, and just OPTIONS for all other routes. ### ActiveRecord without Rails If you want to use ActiveRecord within Grape, you will need to make sure that ActiveRecord's connection pool is handled correctly. The easiest way to achieve that is by using ActiveRecord's `ConnectionManagement` middleware in your `config.ru` before mounting Grape, e.g.: ```ruby use ActiveRecord::ConnectionAdapters::ConnectionManagement run Twitter::API ``` ### Alongside Sinatra (or other frameworks) If you wish to mount Grape alongside another Rack framework such as Sinatra, you can do so easily using `Rack::Cascade`: ```ruby # Example config.ru require 'sinatra' require 'grape' class API < Grape::API get :hello do { hello: 'world' } end end class Web < Sinatra::Base get '/' do 'Hello world.' end end use Rack::Session::Cookie run Rack::Cascade.new [API, Web] ``` ### Rails Place API files into `app/api`. Rails expects a subdirectory that matches the name of the Ruby module and a file name that matches the name of the class. In our example, the file name location and directory for `Twitter::API` should be `app/api/twitter/api.rb`. Modify `application.rb`: ```ruby config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb') config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')] ``` Modify `config/routes`: ```ruby mount Twitter::API => '/' ``` See [below](#reloading-api-changes-in-development) for additional code that enables reloading of API changes in development. ### Modules You can mount multiple API implementations inside another one. These don't have to be different versions, but may be components of the same API. ```ruby class Twitter::API < Grape::API mount Twitter::APIv1 mount Twitter::APIv2 end ``` You can also mount on a path, which is similar to using `prefix` inside the mounted API itself. ```ruby class Twitter::API < Grape::API mount Twitter::APIv1 => '/v1' end ``` Keep in mind such declarations as `before/after/rescue_from` must be placed before `mount` in a case where they should be inherited. ```ruby class Twitter::API < Grape::API before do header 'X-Base-Header', 'will be defined for all APIs that are mounted below' end mount Twitter::Users mount Twitter::Search end ``` ## Versioning There are four strategies in which clients can reach your API's endpoints: `:path`, `:header`, `:accept_version_header` and `:param`. The default strategy is `:path`. ### Path ```ruby version 'v1', using: :path ``` Using this versioning strategy, clients should pass the desired version in the URL. curl http://localhost:9292/v1/statuses/public_timeline ### Header ```ruby version 'v1', using: :header, vendor: 'twitter' ``` Currently, Grape only supports versioned media types in the following format: ``` vnd.vendor-and-or-resource-v1234+format ``` Basically all tokens between the final `-` and the `+` will be interpreted as the version. Using this versioning strategy, clients should pass the desired version in the HTTP `Accept` head. curl -H Accept:application/vnd.twitter-v1+json http://localhost:9292/statuses/public_timeline By default, the first matching version is used when no `Accept` header is supplied. This behavior is similar to routing in Rails. To circumvent this default behavior, one could use the `:strict` option. When this option is set to `true`, a `406 Not Acceptable` error is returned when no correct `Accept` header is supplied. When an invalid `Accept` header is supplied, a `406 Not Acceptable` error is returned if the `:cascade` option is set to `false`. Otherwise a `404 Not Found` error is returned by Rack if no other route matches. ### Accept-Version Header ```ruby version 'v1', using: :accept_version_header ``` Using this versioning strategy, clients should pass the desired version in the HTTP `Accept-Version` header. curl -H "Accept-Version:v1" http://localhost:9292/statuses/public_timeline By default, the first matching version is used when no `Accept-Version` header is supplied. This behavior is similar to routing in Rails. To circumvent this default behavior, one could use the `:strict` option. When this option is set to `true`, a `406 Not Acceptable` error is returned when no correct `Accept` header is supplied and the `:cascade` option is set to `false`. Otherwise a `404 Not Found` error is returned by Rack if no other route matches. ### Param ```ruby version 'v1', using: :param ``` Using this versioning strategy, clients should pass the desired version as a request parameter, either in the URL query string or in the request body. curl http://localhost:9292/statuses/public_timeline?apiver=v1 The default name for the query parameter is 'apiver' but can be specified using the `:parameter` option. ```ruby version 'v1', using: :param, parameter: 'v' ``` curl http://localhost:9292/statuses/public_timeline?v=v1 ## Describing Methods You can add a description to API methods and namespaces. ```ruby desc 'Returns your public timeline.' do detail 'more details' params API::Entities::Status.documentation success API::Entities::Entity failure [[401, 'Unauthorized', 'Entities::Error']] named 'My named route' headers XAuthToken: { description: 'Validates your identity', required: true }, XOptionalHeader: { description: 'Not really needed', required: false } end get :public_timeline do Status.limit(20) end ``` * `detail`: A more enhanced description * `params`: Define parameters directly from an `Entity` * `success`: (former entity) The `Entity` to be used to present by default this route * `failure`: (former http_codes) A definition of the used failure HTTP Codes and Entities * `named`: A helper to give a route a name and find it with this name in the documentation Hash * `headers`: A definition of the used Headers ## Parameters Request parameters are available through the `params` hash object. This includes `GET`, `POST` and `PUT` parameters, along with any named parameters you specify in your route strings. ```ruby get :public_timeline do Status.order(params[:sort_by]) end ``` Parameters are automatically populated from the request body on `POST` and `PUT` for form input, JSON and XML content-types. The request: ``` curl -d '{"text": "140 characters"}' 'http://localhost:9292/statuses' -H Content-Type:application/json -v ``` The Grape endpoint: ```ruby post '/statuses' do Status.create!(text: params[:text]) end ``` Multipart POSTs and PUTs are supported as well. The request: ``` curl --form image_file='@image.jpg;type=image/jpg' http://localhost:9292/upload ``` The Grape endpoint: ```ruby post 'upload' do # file in params[:image_file] end ``` In the case of conflict between either of: * route string parameters * `GET`, `POST` and `PUT` parameters * the contents of the request body on `POST` and `PUT` Route string parameters will have precedence. ### Params Class By default parameters are available as `ActiveSupport::HashWithIndifferentAccess`. This can be changed to, for example, Ruby `Hash` or `Hashie::Mash` for the entire API. ```ruby class API < Grape::API include Grape::Extensions::Hashie::Mash::ParamBuilder params do optional :color, type: String end get do params.color # instead of params[:color] end ``` The class can also be overridden on individual parameter blocks using `build_with` as follows. ```ruby params do build_with Grape::Extensions::Hash::ParamBuilder optional :color, type: String end ``` In the example above, `params["color"]` will return `nil` since `params` is a plain `Hash`. Available parameter builders are `Grape::Extensions::Hash::ParamBuilder`, `Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder` and `Grape::Extensions::Hashie::Mash::ParamBuilder`. ### Declared Grape allows you to access only the parameters that have been declared by your `params` block. It filters out the params that have been passed, but are not allowed. Consider the following API endpoint: ````ruby format :json post 'users/signup' do { 'declared_params' => declared(params) } end ```` If you do not specify any parameters, `declared` will return an empty hash. **Request** ````bash curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{"user": {"first_name":"first name", "last_name": "last name"}}' ```` **Response** ````json { "declared_params": {} } ```` Once we add parameters requirements, grape will start returning only the declared parameters. ````ruby format :json params do requires :user, type: Hash do requires :first_name, type: String requires :last_name, type: String end end post 'users/signup' do { 'declared_params' => declared(params) } end ```` **Request** ````bash curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{"user": {"first_name":"first name", "last_name": "last name", "random": "never shown"}}' ```` **Response** ````json { "declared_params": { "user": { "first_name": "first name", "last_name": "last name" } } } ```` The returned hash is an `ActiveSupport::HashWithIndifferentAccess`. The `#declared` method is not available to `before` filters, as those are evaluated prior to parameter coercion. ### Include Parent Namespaces By default `declared(params)` includes parameters that were defined in all parent namespaces. If you want to return only parameters from your current namespace, you can set `include_parent_namespaces` option to `false`. ````ruby format :json namespace :parent do params do requires :parent_name, type: String end namespace ':parent_name' do params do requires :child_name, type: String end get ':child_name' do { 'without_parent_namespaces' => declared(params, include_parent_namespaces: false), 'with_parent_namespaces' => declared(params, include_parent_namespaces: true), } end end end ```` **Request** ````bash curl -X GET -H "Content-Type: application/json" localhost:9292/parent/foo/bar ```` **Response** ````json { "without_parent_namespaces": { "child_name": "bar" }, "with_parent_namespaces": { "parent_name": "foo", "child_name": "bar" }, } ```` ### Include Missing By default `declared(params)` includes parameters that have `nil` values. If you want to return only the parameters that are not `nil`, you can use the `include_missing` option. By default, `include_missing` is set to `true`. Consider the following API: ````ruby format :json params do requires :first_name, type: String optional :last_name, type: String end post 'users/signup' do { 'declared_params' => declared(params, include_missing: false) } end ```` **Request** ````bash curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{"user": {"first_name":"first name", "random": "never shown"}}' ```` **Response with include_missing:false** ````json { "declared_params": { "user": { "first_name": "first name" } } } ```` **Response with include_missing:true** ````json { "declared_params": { "first_name": "first name", "last_name": null } } ```` It also works on nested hashes: ````ruby format :json params do requires :user, type: Hash do requires :first_name, type: String optional :last_name, type: String requires :address, type: Hash do requires :city, type: String optional :region, type: String end end end post 'users/signup' do { 'declared_params' => declared(params, include_missing: false) } end ```` **Request** ````bash curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{"user": {"first_name":"first name", "random": "never shown", "address": { "city": "SF"}}}' ```` **Response with include_missing:false** ````json { "declared_params": { "user": { "first_name": "first name", "address": { "city": "SF" } } } } ```` **Response with include_missing:true** ````json { "declared_params": { "user": { "first_name": "first name", "last_name": null, "address": { "city": "Zurich", "region": null } } } } ```` Note that an attribute with a `nil` value is not considered *missing* and will also be returned when `include_missing` is set to `false`: **Request** ````bash curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{"user": {"first_name":"first name", "last_name": null, "address": { "city": "SF"}}}' ```` **Response with include_missing:false** ````json { "declared_params": { "user": { "first_name": "first name", "last_name": null, "address": { "city": "SF"} } } } ```` ## Parameter Validation and Coercion You can define validations and coercion options for your parameters using a `params` block. ```ruby params do requires :id, type: Integer optional :text, type: String, regexp: /\A[a-z]+\z/ group :media, type: Hash do requires :url end optional :audio, type: Hash do requires :format, type: Symbol, values: [:mp3, :wav, :aac, :ogg], default: :mp3 end mutually_exclusive :media, :audio end put ':id' do # params[:id] is an Integer end ``` When a type is specified an implicit validation is done after the coercion to ensure the output type is the one declared. Optional parameters can have a default value. ```ruby params do optional :color, type: String, default: 'blue' optional :random_number, type: Integer, default: -> { Random.rand(1..100) } optional :non_random_number, type: Integer, default: Random.rand(1..100) end ``` Note that default values will be passed through to any validation options specified. The following example will always fail if `:color` is not explicitly provided. Default values are eagerly evaluated. Above `:non_random_number` will evaluate to the same number for each call to the endpoint of this `params` block. To have the default evaluate lazily with each request use a lambda, like `:random_number` above. ```ruby params do optional :color, type: String, default: 'blue', values: ['red', 'green'] end ``` The correct implementation is to ensure the default value passes all validations. ```ruby params do optional :color, type: String, default: 'blue', values: ['blue', 'red', 'green'] end ``` ### Supported Parameter Types The following are all valid types, supported out of the box by Grape: * Integer * Float * BigDecimal * Numeric * Date * DateTime * Time * Boolean * String * Symbol * Rack::Multipart::UploadedFile (alias `File`) * JSON ### Integer/Fixnum and Coercions Please be aware that the behavior differs between Ruby 2.4 and earlier versions. In Ruby 2.4, values consisting of numbers are converted to Integer, but in earlier versions it will be treated as Fixnum. ```ruby params do requires :integers, type: Hash do requires :int, coerce: Integer end end get '/int' do params[:integers][:int].class end ... get '/int' integers: { int: '45' } #=> Integer in ruby 2.4 #=> Fixnum in earlier ruby versions ``` ### Custom Types and Coercions Aside from the default set of supported types listed above, any class can be used as a type as long as an explicit coercion method is supplied. If the type implements a class-level `parse` method, Grape will use it automatically. This method must take one string argument and return an instance of the correct type, or raise an exception to indicate the value was invalid. E.g., ```ruby class Color attr_reader :value def initialize(color) @value = color end def self.parse(value) fail 'Invalid color' unless %w(blue red green).include?(value) new(value) end end params do requires :color, type: Color, default: Color.new('blue') requires :more_colors, type: Array[Color] # Collections work optional :unique_colors, type: Set[Color] # Duplicates discarded end get '/stuff' do # params[:color] is already a Color. params[:color].value end ``` Alternatively, a custom coercion method may be supplied for any type of parameter using `coerce_with`. Any class or object may be given that implements a `parse` or `call` method, in that order of precedence. The method must accept a single string parameter, and the return value must match the given `type`. ```ruby params do requires :passwd, type: String, coerce_with: Base64.method(:decode) requires :loud_color, type: Color, coerce_with: ->(c) { Color.parse(c.downcase) } requires :obj, type: Hash, coerce_with: JSON do requires :words, type: Array[String], coerce_with: ->(val) { val.split(/\s+/) } optional :time, type: Time, coerce_with: Chronic end end ``` Example of use of `coerce_with` with a lambda (a class with a `parse` method could also have been used) It will parse a string and return an Array of Integers, matching the `Array[Integer]` `type`. ```ruby params do requires :values, type: Array[Integer], coerce_with: ->(val) { val.split(/\s+/).map(&:to_i) } end ``` Grape will assert that coerced values match the given `type`, and will reject the request if they do not. To override this behaviour, custom types may implement a `parsed?` method that should accept a single argument and return `true` if the value passes type validation. ```ruby class SecureUri def self.parse(value) URI.parse value end def self.parsed?(value) value.is_a? URI::HTTPS end end params do requires :secure_uri, type: SecureUri end ``` ### Multipart File Parameters Grape makes use of `Rack::Request`'s built-in support for multipart file parameters. Such parameters can be declared with `type: File`: ```ruby params do requires :avatar, type: File end post '/' do params[:avatar][:filename] # => 'avatar.png' params[:avatar][:type] # => 'image/png' params[:avatar][:tempfile] # => # end ``` ### First-Class `JSON` Types Grape supports complex parameters given as JSON-formatted strings using the special `type: JSON` declaration. JSON objects and arrays of objects are accepted equally, with nested validation rules applied to all objects in either case: ```ruby params do requires :json, type: JSON do requires :int, type: Integer, values: [1, 2, 3] end end get '/' do params[:json].inspect end client.get('/', json: '{"int":1}') # => "{:int=>1}" client.get('/', json: '[{"int":"1"}]') # => "[{:int=>1}]" client.get('/', json: '{"int":4}') # => HTTP 400 client.get('/', json: '[{"int":4}]') # => HTTP 400 ``` Additionally `type: Array[JSON]` may be used, which explicitly marks the parameter as an array of objects. If a single object is supplied it will be wrapped. ```ruby params do requires :json, type: Array[JSON] do requires :int, type: Integer end end get '/' do params[:json].each { |obj| ... } # always works end ``` For stricter control over the type of JSON structure which may be supplied, use `type: Array, coerce_with: JSON` or `type: Hash, coerce_with: JSON`. ### Multiple Allowed Types Variant-type parameters can be declared using the `types` option rather than `type`: ```ruby params do requires :status_code, types: [Integer, String, Array[Integer, String]] end get '/' do params[:status_code].inspect end client.get('/', status_code: 'OK_GOOD') # => "OK_GOOD" client.get('/', status_code: 300) # => 300 client.get('/', status_code: %w(404 NOT FOUND)) # => [404, "NOT", "FOUND"] ``` As a special case, variant-member-type collections may also be declared, by passing a `Set` or `Array` with more than one member to `type`: ```ruby params do requires :status_codes, type: Array[Integer,String] end get '/' do params[:status_codes].inspect end client.get('/', status_codes: %w(1 two)) # => [1, "two"] ``` ### Validation of Nested Parameters Parameters can be nested using `group` or by calling `requires` or `optional` with a block. In the [above example](#parameter-validation-and-coercion), this means `params[:media][:url]` is required along with `params[:id]`, and `params[:audio][:format]` is required only if `params[:audio]` is present. With a block, `group`, `requires` and `optional` accept an additional option `type` which can be either `Array` or `Hash`, and defaults to `Array`. Depending on the value, the nested parameters will be treated either as values of a hash or as values of hashes in an array. ```ruby params do optional :preferences, type: Array do requires :key requires :value end requires :name, type: Hash do requires :first_name requires :last_name end end ``` ### Dependent Parameters Suppose some of your parameters are only relevant if another parameter is given; Grape allows you to express this relationship through the `given` method in your parameters block, like so: ```ruby params do optional :shelf_id, type: Integer given :shelf_id do requires :bin_id, type: Integer end end ``` In the example above Grape will use `blank?` to check whether the `shelf_id` param is present. `given` also takes a `Proc` with custom code. Below, the param `description` is required only if the value of `category` is equal `foo`: ```ruby params do optional :category given category: ->(val) { val == 'foo' } do requires :description end end ``` ### Group Options Parameters options can be grouped. It can be useful if you want to extract common validation or types for several parameters. The example below presents a typical case when parameters share common options. ```ruby params do requires :first_name, type: String, regexp: /w+/, desc: 'First name' requires :middle_name, type: String, regexp: /w+/, desc: 'Middle name' requires :last_name, type: String, regexp: /w+/, desc: 'Last name' end ``` Grape allows you to present the same logic through the `with` method in your parameters block, like so: ```ruby params do with(type: String, regexp: /w+/) do requires :first_name, desc: 'First name' requires :middle_name, desc: 'Middle name' requires :last_name, desc: 'Last name' end end ``` ### Alias You can set an alias for parameters using `as`, which can be useful when refactoring existing APIs: ```ruby resource :users do params do requires :email_address, as: :email requires :password end post do User.create!(declared(params)) # User takes email and password end end ``` The value passed to `as` will be the key when calling `params` or `declared(params)`. ### Built-in Validators #### `allow_blank` Parameters can be defined as `allow_blank`, ensuring that they contain a value. By default, `requires` only validates that a parameter was sent in the request, regardless its value. With `allow_blank: false`, empty values or whitespace only values are invalid. `allow_blank` can be combined with both `requires` and `optional`. If the parameter is required, it has to contain a value. If it's optional, it's possible to not send it in the request, but if it's being sent, it has to have some value, and not an empty string/only whitespaces. ```ruby params do requires :username, allow_blank: false optional :first_name, allow_blank: false end ``` #### `values` Parameters can be restricted to a specific set of values with the `:values` option. ```ruby params do requires :status, type: Symbol, values: [:not_started, :processing, :done] optional :numbers, type: Array[Integer], default: 1, values: [1, 2, 3, 5, 8] end ``` Supplying a range to the `:values` option ensures that the parameter is (or parameters are) included in that range (using `Range#include?`). ```ruby params do requires :latitude, type: Float, values: -90.0..+90.0 requires :longitude, type: Float, values: -180.0..+180.0 optional :letters, type: Array[String], values: 'a'..'z' end ``` Note that *both* range endpoints have to be a `#kind_of?` your `:type` option (if you don't supply the `:type` option, it will be guessed to be equal to the class of the range's first endpoint). So the following is invalid: ```ruby params do requires :invalid1, type: Float, values: 0..10 # 0.kind_of?(Float) => false optional :invalid2, values: 0..10.0 # 10.0.kind_of?(0.class) => false end ``` The `:values` option can also be supplied with a `Proc`, evaluated lazily with each request. If the Proc has arity zero (i.e. it takes no arguments) it is expected to return either a list or a range which will then be used to validate the parameter. For example, given a status model you may want to restrict by hashtags that you have previously defined in the `HashTag` model. ```ruby params do requires :hashtag, type: String, values: -> { Hashtag.all.map(&:tag) } end ``` Alternatively, a Proc with arity one (i.e. taking one argument) can be used to explicitly validate each parameter value. In that case, the Proc is expected to return a truthy value if the parameter value is valid. The parameter will be considered invalid if the Proc returns a falsy value or if it raises a StandardError. ```ruby params do requires :number, type: Integer, values: ->(v) { v.even? && v < 25 } end ``` While Procs are convenient for single cases, consider using [Custom Validators](#custom-validators) in cases where a validation is used more than once. #### `except_values` Parameters can be restricted from having a specific set of values with the `:except_values` option. The `except_values` validator behaves similarly to the `values` validator in that it accepts either an Array, a Range, or a Proc. Unlike the `values` validator, however, `except_values` only accepts Procs with arity zero. ```ruby params do requires :browser, except_values: [ 'ie6', 'ie7', 'ie8' ] requires :port, except_values: { value: 0..1024, message: 'is not allowed' } requires :hashtag, except_values: -> { Hashtag.FORBIDDEN_LIST } end ``` #### `regexp` Parameters can be restricted to match a specific regular expression with the `:regexp` option. If the value does not match the regular expression an error will be returned. Note that this is true for both `requires` and `optional` parameters. ```ruby params do requires :email, regexp: /.+@.+/ end ``` The validator will pass if the parameter was sent without value. To ensure that the parameter contains a value, use `allow_blank: false`. ```ruby params do requires :email, allow_blank: false, regexp: /.+@.+/ end ``` #### `mutually_exclusive` Parameters can be defined as `mutually_exclusive`, ensuring that they aren't present at the same time in a request. ```ruby params do optional :beer optional :wine mutually_exclusive :beer, :wine end ``` Multiple sets can be defined: ```ruby params do optional :beer optional :wine mutually_exclusive :beer, :wine optional :scotch optional :aquavit mutually_exclusive :scotch, :aquavit end ``` **Warning**: Never define mutually exclusive sets with any required params. Two mutually exclusive required params will mean params are never valid, thus making the endpoint useless. One required param mutually exclusive with an optional param will mean the latter is never valid. #### `exactly_one_of` Parameters can be defined as 'exactly_one_of', ensuring that exactly one parameter gets selected. ```ruby params do optional :beer optional :wine exactly_one_of :beer, :wine end ``` Note that using `:default` with `mutually_exclusive` will cause multiple parameters to always have a default value and raise a `Grape::Exceptions::Validation` mutually exclusive exception. #### `at_least_one_of` Parameters can be defined as 'at_least_one_of', ensuring that at least one parameter gets selected. ```ruby params do optional :beer optional :wine optional :juice at_least_one_of :beer, :wine, :juice end ``` #### `all_or_none_of` Parameters can be defined as 'all_or_none_of', ensuring that all or none of parameters gets selected. ```ruby params do optional :beer optional :wine optional :juice all_or_none_of :beer, :wine, :juice end ``` #### Nested `mutually_exclusive`, `exactly_one_of`, `at_least_one_of`, `all_or_none_of` All of these methods can be used at any nested level. ```ruby params do requires :food, type: Hash do optional :meat optional :fish optional :rice at_least_one_of :meat, :fish, :rice end group :drink, type: Hash do optional :beer optional :wine optional :juice exactly_one_of :beer, :wine, :juice end optional :dessert, type: Hash do optional :cake optional :icecream mutually_exclusive :cake, :icecream end optional :recipe, type: Hash do optional :oil optional :meat all_or_none_of :oil, :meat end end ``` ### Namespace Validation and Coercion Namespaces allow parameter definitions and apply to every method within the namespace. ```ruby namespace :statuses do params do requires :user_id, type: Integer, desc: 'A user ID.' end namespace ':user_id' do desc "Retrieve a user's status." params do requires :status_id, type: Integer, desc: 'A status ID.' end get ':status_id' do User.find(params[:user_id]).statuses.find(params[:status_id]) end end end ``` The `namespace` method has a number of aliases, including: `group`, `resource`, `resources`, and `segment`. Use whichever reads the best for your API. You can conveniently define a route parameter as a namespace using `route_param`. ```ruby namespace :statuses do route_param :id do desc 'Returns all replies for a status.' get 'replies' do Status.find(params[:id]).replies end desc 'Returns a status.' get do Status.find(params[:id]) end end end ``` You can also define a route parameter type by passing to `route_param`'s options. ```ruby namespace :arithmetic do route_param :n, type: Integer do desc 'Returns in power' get 'power' do params[:n] ** params[:n] end end end ``` ### Custom Validators ```ruby class AlphaNumeric < Grape::Validations::Base def validate_param!(attr_name, params) unless params[attr_name] =~ /\A[[:alnum:]]+\z/ fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: 'must consist of alpha-numeric characters' end end end ``` ```ruby params do requires :text, alpha_numeric: true end ``` You can also create custom classes that take parameters. ```ruby class Length < Grape::Validations::Base def validate_param!(attr_name, params) unless params[attr_name].length <= @option fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long" end end end ``` ```ruby params do requires :text, length: 140 end ``` You can also create custom validation that use request to validate the attribute. For example if you want to have parameters that are available to only admins, you can do the following. ```ruby class Admin < Grape::Validations::Base def validate(request) # return if the param we are checking was not in request # @attrs is a list containing the attribute we are currently validating # in our sample case this method once will get called with # @attrs being [:admin_field] and once with @attrs being [:admin_false_field] return unless request.params.key?(@attrs.first) # check if admin flag is set to true return unless @option # check if user is admin or not # as an example get a token from request and check if it's admin or not fail Grape::Exceptions::Validation, params: @attrs, message: 'Can not set admin-only field.' unless request.headers['X-Access-Token'] == 'admin' end end ``` And use it in your endpoint definition as: ```ruby params do optional :admin_field, type: String, admin: true optional :non_admin_field, type: String optional :admin_false_field, type: String, admin: false end ``` Every validation will have it's own instance of the validator, which means that the validator can have a state. ### Validation Errors Validation and coercion errors are collected and an exception of type `Grape::Exceptions::ValidationErrors` is raised. If the exception goes uncaught it will respond with a status of 400 and an error message. The validation errors are grouped by parameter name and can be accessed via `Grape::Exceptions::ValidationErrors#errors`. The default response from a `Grape::Exceptions::ValidationErrors` is a humanly readable string, such as "beer, wine are mutually exclusive", in the following example. ```ruby params do optional :beer optional :wine optional :juice exactly_one_of :beer, :wine, :juice end ``` You can rescue a `Grape::Exceptions::ValidationErrors` and respond with a custom response or turn the response into well-formatted JSON for a JSON API that separates individual parameters and the corresponding error messages. The following `rescue_from` example produces `[{"params":["beer","wine"],"messages":["are mutually exclusive"]}]`. ```ruby format :json subject.rescue_from Grape::Exceptions::ValidationErrors do |e| error! e, 400 end ``` `Grape::Exceptions::ValidationErrors#full_messages` returns the validation messages as an array. `Grape::Exceptions::ValidationErrors#message` joins the messages to one string. For responding with an array of validation messages, you can use `Grape::Exceptions::ValidationErrors#full_messages`. ```ruby format :json subject.rescue_from Grape::Exceptions::ValidationErrors do |e| error!({ messages: e.full_messages }, 400) end ``` Grape returns all validation and coercion errors found by default. To skip all subsequent validation checks when a specific param is found invalid, use `fail_fast: true`. The following example will not check if `:wine` is present unless it finds `:beer`. ```ruby params do required :beer, fail_fast: true required :wine end ``` The result of empty params would be a single `Grape::Exceptions::ValidationErrors` error. Similarly, no regular expression test will be performed if `:blah` is blank in the following example. ```ruby params do required :blah, allow_blank: false, regexp: /blah/, fail_fast: true end ``` ### I18n Grape supports I18n for parameter-related error messages, but will fallback to English if translations for the default locale have not been provided. See [en.yml](lib/grape/locale/en.yml) for message keys. ### Custom Validation messages Grape supports custom validation messages for parameter-related and coerce-related error messages. #### `presence`, `allow_blank`, `values`, `regexp` ```ruby params do requires :name, values: { value: 1..10, message: 'not in range from 1 to 10' }, allow_blank: { value: false, message: 'cannot be blank' }, regexp: { value: /^[a-z]+$/, message: 'format is invalid' }, message: 'is required' end ``` #### `all_or_none_of` ```ruby params do optional :beer optional :wine optional :juice all_or_none_of :beer, :wine, :juice, message: "all params are required or none is required" end ``` #### `mutually_exclusive` ```ruby params do optional :beer optional :wine optional :juice mutually_exclusive :beer, :wine, :juice, message: "are mutually exclusive cannot pass both params" end ``` #### `exactly_one_of` ```ruby params do optional :beer optional :wine optional :juice exactly_one_of :beer, :wine, :juice, message: {exactly_one: "are missing, exactly one parameter is required", mutual_exclusion: "are mutually exclusive, exactly one parameter is required"} end ``` #### `at_least_one_of` ```ruby params do optional :beer optional :wine optional :juice at_least_one_of :beer, :wine, :juice, message: "are missing, please specify at least one param" end ``` #### `Coerce` ```ruby params do requires :int, type: {value: Integer, message: "type cast is invalid" } end ``` #### `With Lambdas` ```ruby params do requires :name, values: { value: -> { (1..10).to_a }, message: 'not in range from 1 to 10' } end ``` #### `Pass symbols for i18n translations` You can pass a symbol if you want i18n translations for your custom validation messages. ```ruby params do requires :name, message: :name_required end ``` ```ruby # en.yml en: grape: errors: format: ! '%{attributes} %{message}' messages: name_required: 'must be present' ``` #### Overriding Attribute Names You can also override attribute names. ```ruby # en.yml en: grape: errors: format: ! '%{attributes} %{message}' messages: name_required: 'must be present' attributes: name: 'Oops! Name' ``` Will produce 'Oops! Name must be present' #### With Default You cannot set a custom message option for Default as it requires interpolation `%{option1}: %{value1} is incompatible with %{option2}: %{value2}`. You can change the default error message for Default by changing the `incompatible_option_values` message key inside [en.yml](lib/grape/locale/en.yml) ```ruby params do requires :name, values: { value: -> { (1..10).to_a }, message: 'not in range from 1 to 10' }, default: 5 end ``` ## Headers Request headers are available through the `headers` helper or from `env` in their original form. ```ruby get do error!('Unauthorized', 401) unless headers['Secret-Password'] == 'swordfish' end ``` ```ruby get do error!('Unauthorized', 401) unless env['HTTP_SECRET_PASSWORD'] == 'swordfish' end ``` You can set a response header with `header` inside an API. ```ruby header 'X-Robots-Tag', 'noindex' ``` When raising `error!`, pass additional headers as arguments. ```ruby error! 'Unauthorized', 401, 'X-Error-Detail' => 'Invalid token.' ``` ## Routes Optionally, you can define requirements for your named route parameters using regular expressions on namespace or endpoint. The route will match only if all requirements are met. ```ruby get ':id', requirements: { id: /[0-9]*/ } do Status.find(params[:id]) end namespace :outer, requirements: { id: /[0-9]*/ } do get :id do end get ':id/edit' do end end ``` ## Helpers You can define helper methods that your endpoints can use with the `helpers` macro by either giving a block or an array of modules. ```ruby module StatusHelpers def user_info(user) "#{user} has statused #{user.statuses} status(s)" end end module HttpCodesHelpers def unauthorized 401 end end class API < Grape::API # define helpers with a block helpers do def current_user User.find(params[:user_id]) end end # or mix in an array of modules helpers StatusHelpers, HttpCodesHelpers before do error!('Access Denied', unauthorized) unless current_user end get 'info' do # helpers available in your endpoint and filters user_info(current_user) end end ``` You can define reusable `params` using `helpers`. ```ruby class API < Grape::API helpers do params :pagination do optional :page, type: Integer optional :per_page, type: Integer end end desc 'Get collection' params do use :pagination # aliases: includes, use_scope end get do Collection.page(params[:page]).per(params[:per_page]) end end ``` You can also define reusable `params` using shared helpers. ```ruby module SharedParams extend Grape::API::Helpers params :period do optional :start_date optional :end_date end params :pagination do optional :page, type: Integer optional :per_page, type: Integer end end class API < Grape::API helpers SharedParams desc 'Get collection.' params do use :period, :pagination end get do Collection .from(params[:start_date]) .to(params[:end_date]) .page(params[:page]) .per(params[:per_page]) end end ``` Helpers support blocks that can help set default values. The following API can return a collection sorted by `id` or `created_at` in `asc` or `desc` order. ```ruby module SharedParams extend Grape::API::Helpers params :order do |options| optional :order_by, type:Symbol, values:options[:order_by], default:options[:default_order_by] optional :order, type:Symbol, values:%i(asc desc), default:options[:default_order] end end class API < Grape::API helpers SharedParams desc 'Get a sorted collection.' params do use :order, order_by:%i(id created_at), default_order_by: :created_at, default_order: :asc end get do Collection.send(params[:order], params[:order_by]) end end ``` ## Path Helpers If you need methods for generating paths inside your endpoints, please see the [grape-route-helpers](https://github.com/reprah/grape-route-helpers) gem. ## Parameter Documentation You can attach additional documentation to `params` using a `documentation` hash. ```ruby params do optional :first_name, type: String, documentation: { example: 'Jim' } requires :last_name, type: String, documentation: { example: 'Smith' } end ``` ## Cookies You can set, get and delete your cookies very simply using `cookies` method. ```ruby class API < Grape::API get 'status_count' do cookies[:status_count] ||= 0 cookies[:status_count] += 1 { status_count: cookies[:status_count] } end delete 'status_count' do { status_count: cookies.delete(:status_count) } end end ``` Use a hash-based syntax to set more than one value. ```ruby cookies[:status_count] = { value: 0, expires: Time.tomorrow, domain: '.twitter.com', path: '/' } cookies[:status_count][:value] +=1 ``` Delete a cookie with `delete`. ```ruby cookies.delete :status_count ``` Specify an optional path. ```ruby cookies.delete :status_count, path: '/' ``` ## HTTP Status Code By default Grape returns a 201 for `POST`-Requests, 204 for `DELETE`-Requests that don't return any content, and 200 status code for all other Requests. You can use `status` to query and set the actual HTTP Status Code ```ruby post do status 202 if status == 200 # do some thing end end ``` You can also use one of status codes symbols that are provided by [Rack utils](http://www.rubydoc.info/github/rack/rack/Rack/Utils#HTTP_STATUS_CODES-constant) ```ruby post do status :no_content end ``` ## Redirecting You can redirect to a new url temporarily (302) or permanently (301). ```ruby redirect '/statuses' ``` ```ruby redirect '/statuses', permanent: true ``` ## Recognizing Path You can recognize the endpoint matched with given path. This API returns an instance of `Grape::Endpoint`. ```ruby class API < Grape::API get '/statuses' do end end API.recognize_path '/statuses' ``` ## Allowed Methods When you add a `GET` route for a resource, a route for the `HEAD` method will also be added automatically. You can disable this behavior with `do_not_route_head!`. ``` ruby class API < Grape::API do_not_route_head! get '/example' do # only responds to GET end end ``` When you add a route for a resource, a route for the `OPTIONS` method will also be added. The response to an OPTIONS request will include an "Allow" header listing the supported methods. If the resource has `before` and `after` callbacks they will be executed, but no other callbacks will run. ```ruby class API < Grape::API get '/rt_count' do { rt_count: current_user.rt_count } end params do requires :value, type: Integer, desc: 'Value to add to the rt count.' end put '/rt_count' do current_user.rt_count += params[:value].to_i { rt_count: current_user.rt_count } end end ``` ``` shell curl -v -X OPTIONS http://localhost:3000/rt_count > OPTIONS /rt_count HTTP/1.1 > < HTTP/1.1 204 No Content < Allow: OPTIONS, GET, PUT ``` You can disable this behavior with `do_not_route_options!`. If a request for a resource is made with an unsupported HTTP method, an HTTP 405 (Method Not Allowed) response will be returned. If the resource has `before` callbacks they will be executed, but no other callbacks will run. ``` shell curl -X DELETE -v http://localhost:3000/rt_count/ > DELETE /rt_count/ HTTP/1.1 > Host: localhost:3000 > < HTTP/1.1 405 Method Not Allowed < Allow: OPTIONS, GET, PUT ``` ## Raising Exceptions You can abort the execution of an API method by raising errors with `error!`. ```ruby error! 'Access Denied', 401 ``` Anything that responds to `#to_s` can be given as a first argument to `error!`. ```ruby error! :not_found, 404 ``` You can also return JSON formatted objects by raising error! and passing a hash instead of a message. ```ruby error!({ error: 'unexpected error', detail: 'missing widget' }, 500) ``` You can present documented errors with a Grape entity using the the [grape-entity](https://github.com/ruby-grape/grape-entity) gem. ```ruby module API class Error < Grape::Entity expose :code expose :message end end ``` The following example specifies the entity to use in the `http_codes` definition. ```ruby desc 'My Route' do failure [[408, 'Unauthorized', API::Error]] end error!({ message: 'Unauthorized' }, 408) ``` The following example specifies the presented entity explicitly in the error message. ```ruby desc 'My Route' do failure [[408, 'Unauthorized']] end error!({ message: 'Unauthorized', with: API::Error }, 408) ``` ### Default Error HTTP Status Code By default Grape returns a 500 status code from `error!`. You can change this with `default_error_status`. ``` ruby class API < Grape::API default_error_status 400 get '/example' do error! 'This should have http status code 400' end end ``` ### Handling 404 For Grape to handle all the 404s for your API, it can be useful to use a catch-all. In its simplest form, it can be like: ```ruby route :any, '*path' do error! # or something else end ``` It is very crucial to __define this endpoint at the very end of your API__, as it literally accepts every request. ## Exception Handling Grape can be told to rescue all `StandardError` exceptions and return them in the API format. ```ruby class Twitter::API < Grape::API rescue_from :all end ``` Grape can also rescue from all exceptions and still use the built-in exception handing. This will give the same behavior as `rescue_from :all` with the addition that Grape will use the exception handling defined by all Exception classes that inherit `Grape::Exceptions::Base`. The intent of this setting is to provide a simple way to cover the most common exceptions and return any unexpected exceptions in the API format. ```ruby class Twitter::API < Grape::API rescue_from :grape_exceptions end ``` You can also rescue specific exceptions. ```ruby class Twitter::API < Grape::API rescue_from ArgumentError, UserDefinedError end ``` In this case ```UserDefinedError``` must be inherited from ```StandardError```. Notice that you could combine these two approaches (rescuing custom errors takes precedence). For example, it's useful for handling all exceptions except Grape validation errors. ```ruby class Twitter::API < Grape::API rescue_from Grape::Exceptions::ValidationErrors do |e| error!(e, 400) end rescue_from :all end ``` The error format will match the request format. See "Content-Types" below. Custom error formatters for existing and additional types can be defined with a proc. ```ruby class Twitter::API < Grape::API error_formatter :txt, ->(message, backtrace, options, env, original_exception) { "error: #{message} from #{backtrace}" } end ``` You can also use a module or class. ```ruby module CustomFormatter def self.call(message, backtrace, options, env, original_exception) { message: message, backtrace: backtrace } end end class Twitter::API < Grape::API error_formatter :custom, CustomFormatter end ``` You can rescue all exceptions with a code block. The `error!` wrapper automatically sets the default error code and content-type. ```ruby class Twitter::API < Grape::API rescue_from :all do |e| error!("rescued from #{e.class.name}") end end ``` Optionally, you can set the format, status code and headers. ```ruby class Twitter::API < Grape::API format :json rescue_from :all do |e| error!({ error: 'Server error.' }, 500, { 'Content-Type' => 'text/error' }) end end ``` You can also rescue all exceptions with a code block and handle the Rack response at the lowest level. ```ruby class Twitter::API < Grape::API rescue_from :all do |e| Rack::Response.new([ e.message ], 500, { 'Content-type' => 'text/error' }).finish end end ``` Or rescue specific exceptions. ```ruby class Twitter::API < Grape::API rescue_from ArgumentError do |e| error!("ArgumentError: #{e.message}") end rescue_from NoMethodError do |e| error!("NoMethodError: #{e.message}") end end ``` By default, `rescue_from` will rescue the exceptions listed and all their subclasses. Assume you have the following exception classes defined. ```ruby module APIErrors class ParentError < StandardError; end class ChildError < ParentError; end end ``` Then the following `rescue_from` clause will rescue exceptions of type `APIErrors::ParentError` and its subclasses (in this case `APIErrors::ChildError`). ```ruby rescue_from APIErrors::ParentError do |e| error!({ error: "#{e.class} error", message: e.message }, e.status) end ``` To only rescue the base exception class, set `rescue_subclasses: false`. The code below will rescue exceptions of type `RuntimeError` but _not_ its subclasses. ```ruby rescue_from RuntimeError, rescue_subclasses: false do |e| error!({ status: e.status, message: e.message, errors: e.errors }, e.status) end ``` Helpers are also available inside `rescue_from`. ```ruby class Twitter::API < Grape::API format :json helpers do def server_error! error!({ error: 'Server error.' }, 500, { 'Content-Type' => 'text/error' }) end end rescue_from :all do |e| server_error! end end ``` The `rescue_from` block must return a `Rack::Response` object, call `error!` or re-raise an exception. The `with` keyword is available as `rescue_from` options, it can be passed method name or Proc object. ```ruby class Twitter::API < Grape::API format :json helpers do def server_error! error!({ error: 'Server error.' }, 500, { 'Content-Type' => 'text/error' }) end end rescue_from :all, with: :server_error! rescue_from ArgumentError, with: -> { Rack::Response.new('rescued with a method', 400) } end ``` #### Rescuing exceptions inside namespaces You could put `rescue_from` clauses inside a namespace and they will take precedence over ones defined in the root scope: ```ruby class Twitter::API < Grape::API rescue_from ArgumentError do |e| error!("outer") end namespace :statuses do rescue_from ArgumentError do |e| error!("inner") end get do raise ArgumentError.new end end end ``` Here `'inner'` will be result of handling occured `ArgumentError`. #### Unrescuable Exceptions `Grape::Exceptions::InvalidVersionHeader`, which is raised when the version in the request header doesn't match the currently evaluated version for the endpoint, will _never_ be rescued from a `rescue_from` block (even a `rescue_from :all`) This is because Grape relies on Rack to catch that error and try the next versioned-route for cases where there exist identical Grape endpoints with different versions. ### Rails 3.x When mounted inside containers, such as Rails 3.x, errors such as "404 Not Found" or "406 Not Acceptable" will likely be handled and rendered by Rails handlers. For instance, accessing a nonexistent route "/api/foo" raises a 404, which inside rails will ultimately be translated to an `ActionController::RoutingError`, which most likely will get rendered to a HTML error page. Most APIs will enjoy preventing downstream handlers from handling errors. You may set the `:cascade` option to `false` for the entire API or separately on specific `version` definitions, which will remove the `X-Cascade: true` header from API responses. ```ruby cascade false ``` ```ruby version 'v1', using: :header, vendor: 'twitter', cascade: false ``` ## Logging `Grape::API` provides a `logger` method which by default will return an instance of the `Logger` class from Ruby's standard library. To log messages from within an endpoint, you need to define a helper to make the logger available in the endpoint context. ```ruby class API < Grape::API helpers do def logger API.logger end end post '/statuses' do logger.info "#{current_user} has statused" end end ``` To change the logger level. ```ruby class API < Grape::API self.logger.level = Logger::INFO end ``` You can also set your own logger. ```ruby class MyLogger def warning(message) puts "this is a warning: #{message}" end end class API < Grape::API logger MyLogger.new helpers do def logger API.logger end end get '/statuses' do logger.warning "#{current_user} has statused" end end ``` For similar to Rails request logging try the [grape_logging](https://github.com/aserafin/grape_logging) or [grape-middleware-logger](https://github.com/ridiculous/grape-middleware-logger) gems. ## API Formats Your API can declare which content-types to support by using `content_type`. If you do not specify any, Grape will support _XML_, _JSON_, _BINARY_, and _TXT_ content-types. The default format is `:txt`; you can change this with `default_format`. Essentially, the two APIs below are equivalent. ```ruby class Twitter::API < Grape::API # no content_type declarations, so Grape uses the defaults end class Twitter::API < Grape::API # the following declarations are equivalent to the defaults content_type :xml, 'application/xml' content_type :json, 'application/json' content_type :binary, 'application/octet-stream' content_type :txt, 'text/plain' default_format :txt end ``` If you declare any `content_type` whatsoever, the Grape defaults will be overridden. For example, the following API will only support the `:xml` and `:rss` content-types, but not `:txt`, `:json`, or `:binary`. Importantly, this means the `:txt` default format is not supported! So, make sure to set a new `default_format`. ```ruby class Twitter::API < Grape::API content_type :xml, 'application/xml' content_type :rss, 'application/xml+rss' default_format :xml end ``` Serialization takes place automatically. For example, you do not have to call `to_json` in each JSON API endpoint implementation. The response format (and thus the automatic serialization) is determined in the following order: * Use the file extension, if specified. If the file is .json, choose the JSON format. * Use the value of the `format` parameter in the query string, if specified. * Use the format set by the `format` option, if specified. * Attempt to find an acceptable format from the `Accept` header. * Use the default format, if specified by the `default_format` option. * Default to `:txt`. For example, consider the following API. ```ruby class MultipleFormatAPI < Grape::API content_type :xml, 'application/xml' content_type :json, 'application/json' default_format :json get :hello do { hello: 'world' } end end ``` * `GET /hello` (with an `Accept: */*` header) does not have an extension or a `format` parameter, so it will respond with JSON (the default format). * `GET /hello.xml` has a recognized extension, so it will respond with XML. * `GET /hello?format=xml` has a recognized `format` parameter, so it will respond with XML. * `GET /hello.xml?format=json` has a recognized extension (which takes precedence over the `format` parameter), so it will respond with XML. * `GET /hello.xls` (with an `Accept: */*` header) has an extension, but that extension is not recognized, so it will respond with JSON (the default format). * `GET /hello.xls` with an `Accept: application/xml` header has an unrecognized extension, but the `Accept` header corresponds to a recognized format, so it will respond with XML. * `GET /hello.xls` with an `Accept: text/plain` header has an unrecognized extension *and* an unrecognized `Accept` header, so it will respond with JSON (the default format). You can override this process explicitly by specifying `env['api.format']` in the API itself. For example, the following API will let you upload arbitrary files and return their contents as an attachment with the correct MIME type. ```ruby class Twitter::API < Grape::API post 'attachment' do filename = params[:file][:filename] content_type MIME::Types.type_for(filename)[0].to_s env['api.format'] = :binary # there's no formatter for :binary, data will be returned "as is" header 'Content-Disposition', "attachment; filename*=UTF-8''#{CGI.escape(filename)}" params[:file][:tempfile].read end end ``` You can have your API only respond to a single format with `format`. If you use this, the API will **not** respond to file extensions other than specified in `format`. For example, consider the following API. ```ruby class SingleFormatAPI < Grape::API format :json get :hello do { hello: 'world' } end end ``` * `GET /hello` will respond with JSON. * `GET /hello.json` will respond with JSON. * `GET /hello.xml`, `GET /hello.foobar`, or *any* other extension will respond with an HTTP 404 error code. * `GET /hello?format=xml` will respond with an HTTP 406 error code, because the XML format specified by the request parameter is not supported. * `GET /hello` with an `Accept: application/xml` header will still respond with JSON, since it could not negotiate a recognized content-type from the headers and JSON is the effective default. The formats apply to parsing, too. The following API will only respond to the JSON content-type and will not parse any other input than `application/json`, `application/x-www-form-urlencoded`, `multipart/form-data`, `multipart/related` and `multipart/mixed`. All other requests will fail with an HTTP 406 error code. ```ruby class Twitter::API < Grape::API format :json end ``` When the content-type is omitted, Grape will return a 406 error code unless `default_format` is specified. The following API will try to parse any data without a content-type using a JSON parser. ```ruby class Twitter::API < Grape::API format :json default_format :json end ``` If you combine `format` with `rescue_from :all`, errors will be rendered using the same format. If you do not want this behavior, set the default error formatter with `default_error_formatter`. ```ruby class Twitter::API < Grape::API format :json content_type :txt, 'text/plain' default_error_formatter :txt end ``` Custom formatters for existing and additional types can be defined with a proc. ```ruby class Twitter::API < Grape::API content_type :xls, 'application/vnd.ms-excel' formatter :xls, ->(object, env) { object.to_xls } end ``` You can also use a module or class. ```ruby module XlsFormatter def self.call(object, env) object.to_xls end end class Twitter::API < Grape::API content_type :xls, 'application/vnd.ms-excel' formatter :xls, XlsFormatter end ``` Built-in formatters are the following. * `:json`: use object's `to_json` when available, otherwise call `MultiJson.dump` * `:xml`: use object's `to_xml` when available, usually via `MultiXml`, otherwise call `to_s` * `:txt`: use object's `to_txt` when available, otherwise `to_s` * `:serializable_hash`: use object's `serializable_hash` when available, otherwise fallback to `:json` * `:binary`: data will be returned "as is" Response statuses that indicate no content as defined by [Rack](https://github.com/rack) [here](https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L567) will bypass serialization and the body entity - though there should be none - will not be modified. ### JSONP Grape supports JSONP via [Rack::JSONP](https://github.com/rack/rack-contrib), part of the [rack-contrib](https://github.com/rack/rack-contrib) gem. Add `rack-contrib` to your `Gemfile`. ```ruby require 'rack/contrib' class API < Grape::API use Rack::JSONP format :json get '/' do 'Hello World' end end ``` ### CORS Grape supports CORS via [Rack::CORS](https://github.com/cyu/rack-cors), part of the [rack-cors](https://github.com/cyu/rack-cors) gem. Add `rack-cors` to your `Gemfile`, then use the middleware in your config.ru file. ```ruby require 'rack/cors' use Rack::Cors do allow do origins '*' resource '*', headers: :any, methods: :get end end run Twitter::API ``` ## Content-type Content-type is set by the formatter. You can override the content-type of the response at runtime by setting the `Content-Type` header. ```ruby class API < Grape::API get '/home_timeline_js' do content_type 'application/javascript' "var statuses = ...;" end end ``` ## API Data Formats Grape accepts and parses input data sent with the POST and PUT methods as described in the Parameters section above. It also supports custom data formats. You must declare additional content-types via `content_type` and optionally supply a parser via `parser` unless a parser is already available within Grape to enable a custom format. Such a parser can be a function or a class. With a parser, parsed data is available "as-is" in `env['api.request.body']`. Without a parser, data is available "as-is" and in `env['api.request.input']`. The following example is a trivial parser that will assign any input with the "text/custom" content-type to `:value`. The parameter will be available via `params[:value]` inside the API call. ```ruby module CustomParser def self.call(object, env) { value: object.to_s } end end ``` ```ruby content_type :txt, 'text/plain' content_type :custom, 'text/custom' parser :custom, CustomParser put 'value' do params[:value] end ``` You can invoke the above API as follows. ``` curl -X PUT -d 'data' 'http://localhost:9292/value' -H Content-Type:text/custom -v ``` You can disable parsing for a content-type with `nil`. For example, `parser :json, nil` will disable JSON parsing altogether. The request data is then available as-is in `env['api.request.body']`. ## JSON and XML Processors Grape uses `JSON` and `ActiveSupport::XmlMini` for JSON and XML parsing by default. It also detects and supports [multi_json](https://github.com/intridea/multi_json) and [multi_xml](https://github.com/sferik/multi_xml). Adding those gems to your Gemfile and requiring them will enable them and allow you to swap the JSON and XML back-ends. ## RESTful Model Representations Grape supports a range of ways to present your data with some help from a generic `present` method, which accepts two arguments: the object to be presented and the options associated with it. The options hash may include `:with`, which defines the entity to expose. ### Grape Entities Add the [grape-entity](https://github.com/ruby-grape/grape-entity) gem to your Gemfile. Please refer to the [grape-entity documentation](https://github.com/ruby-grape/grape-entity/blob/master/README.md) for more details. The following example exposes statuses. ```ruby module API module Entities class Status < Grape::Entity expose :user_name expose :text, documentation: { type: 'string', desc: 'Status update text.' } expose :ip, if: { type: :full } expose :user_type, :user_id, if: ->(status, options) { status.user.public? } expose :digest do |status, options| Digest::MD5.hexdigest(status.txt) end expose :replies, using: API::Status, as: :replies end end class Statuses < Grape::API version 'v1' desc 'Statuses index' do params: API::Entities::Status.documentation end get '/statuses' do statuses = Status.all type = current_user.admin? ? :full : :default present statuses, with: API::Entities::Status, type: type end end end ``` You can use entity documentation directly in the params block with `using: Entity.documentation`. ```ruby module API class Statuses < Grape::API version 'v1' desc 'Create a status' params do requires :all, except: [:ip], using: API::Entities::Status.documentation.except(:id) end post '/status' do Status.create! params end end end ``` You can present with multiple entities using an optional Symbol argument. ```ruby get '/statuses' do statuses = Status.all.page(1).per(20) present :total_page, 10 present :per_page, 20 present :statuses, statuses, with: API::Entities::Status end ``` The response will be ``` { total_page: 10, per_page: 20, statuses: [] } ``` In addition to separately organizing entities, it may be useful to put them as namespaced classes underneath the model they represent. ```ruby class Status def entity Entity.new(self) end class Entity < Grape::Entity expose :text, :user_id end end ``` If you organize your entities this way, Grape will automatically detect the `Entity` class and use it to present your models. In this example, if you added `present Status.new` to your endpoint, Grape will automatically detect that there is a `Status::Entity` class and use that as the representative entity. This can still be overridden by using the `:with` option or an explicit `represents` call. You can present `hash` with `Grape::Presenters::Presenter` to keep things consistent. ```ruby get '/users' do present { id: 10, name: :dgz }, with: Grape::Presenters::Presenter end ```` The response will be ```ruby { id: 10, name: 'dgz' } ``` It has the same result with ```ruby get '/users' do present :id, 10 present :name, :dgz end ``` ### Hypermedia and Roar You can use [Roar](https://github.com/apotonick/roar) to render HAL or Collection+JSON with the help of [grape-roar](https://github.com/ruby-grape/grape-roar), which defines a custom JSON formatter and enables presenting entities with Grape's `present` keyword. ### Rabl You can use [Rabl](https://github.com/nesquena/rabl) templates with the help of the [grape-rabl](https://github.com/ruby-grape/grape-rabl) gem, which defines a custom Grape Rabl formatter. ### Active Model Serializers You can use [Active Model Serializers](https://github.com/rails-api/active_model_serializers) serializers with the help of the [grape-active_model_serializers](https://github.com/jrhe/grape-active_model_serializers) gem, which defines a custom Grape AMS formatter. ## Sending Raw or No Data In general, use the binary format to send raw data. ```ruby class API < Grape::API get '/file' do content_type 'application/octet-stream' File.binread 'file.bin' end end ``` You can set the response body explicitly with `body`. ```ruby class API < Grape::API get '/' do content_type 'text/plain' body 'Hello World' # return value ignored end end ``` Use `body false` to return `204 No Content` without any data or content-type. You can also set the response to a file with `file`. ```ruby class API < Grape::API get '/' do file '/path/to/file' end end ``` If you want a file to be streamed using Rack::Chunked, use `stream`. ```ruby class API < Grape::API get '/' do stream '/path/to/file' end end ``` ## Authentication ### Basic and Digest Auth Grape has built-in Basic and Digest authentication (the given `block` is executed in the context of the current `Endpoint`). Authentication applies to the current namespace and any children, but not parents. ```ruby http_basic do |username, password| # verify user's password here { 'test' => 'password1' }[username] == password end ``` ```ruby http_digest({ realm: 'Test Api', opaque: 'app secret' }) do |username| # lookup the user's password here { 'user1' => 'password1' }[username] end ``` ### Register custom middleware for authentication Grape can use custom Middleware for authentication. How to implement these Middleware have a look at `Rack::Auth::Basic` or similar implementations. For registering a Middleware you need the following options: * `label` - the name for your authenticator to use it later * `MiddlewareClass` - the MiddlewareClass to use for authentication * `option_lookup_proc` - A Proc with one Argument to lookup the options at runtime (return value is an `Array` as Parameter for the Middleware). Example: ```ruby Grape::Middleware::Auth::Strategies.add(:my_auth, AuthMiddleware, ->(options) { [options[:realm]] } ) auth :my_auth, { realm: 'Test Api'} do |credentials| # lookup the user's password here { 'user1' => 'password1' }[username] end ``` Use [warden-oauth2](https://github.com/opperator/warden-oauth2) or [rack-oauth2](https://github.com/nov/rack-oauth2) for OAuth2 support. ## Describing and Inspecting an API Grape routes can be reflected at runtime. This can notably be useful for generating documentation. Grape exposes arrays of API versions and compiled routes. Each route contains a `route_prefix`, `route_version`, `route_namespace`, `route_method`, `route_path` and `route_params`. You can add custom route settings to the route metadata with `route_setting`. ```ruby class TwitterAPI < Grape::API version 'v1' desc 'Includes custom settings.' route_setting :custom, key: 'value' get do end end ``` Examine the routes at runtime. ```ruby TwitterAPI::versions # yields [ 'v1', 'v2' ] TwitterAPI::routes # yields an array of Grape::Route objects TwitterAPI::routes[0].version # => 'v1' TwitterAPI::routes[0].description # => 'Includes custom settings.' TwitterAPI::routes[0].settings[:custom] # => { key: 'value' } ``` Note that `Route#route_xyz` methods have been deprecated since 0.15.0. Please use `Route#xyz` instead. Note that difference of `Route#options` and `Route#settings`. The `options` can be referred from your route, it should be set by specifing key and value on verb methods such as `get`, `post` and `put`. The `settings` can also be referred from your route, but it should be set by specifing key and value on `route_setting`. ## Current Route and Endpoint It's possible to retrieve the information about the current route from within an API call with `route`. ```ruby class MyAPI < Grape::API desc 'Returns a description of a parameter.' params do requires :id, type: Integer, desc: 'Identity.' end get 'params/:id' do route.route_params[params[:id]] # yields the parameter description end end ``` The current endpoint responding to the request is `self` within the API block or `env['api.endpoint']` elsewhere. The endpoint has some interesting properties, such as `source` which gives you access to the original code block of the API implementation. This can be particularly useful for building a logger middleware. ```ruby class ApiLogger < Grape::Middleware::Base def before file = env['api.endpoint'].source.source_location[0] line = env['api.endpoint'].source.source_location[1] logger.debug "[api] #{file}:#{line}" end end ``` ## Before and After Blocks can be executed before or after every API call, using `before`, `after`, `before_validation` and `after_validation`. Before and after callbacks execute in the following order: 1. `before` 2. `before_validation` 3. _validations_ 4. `after_validation` 5. _the API call_ 6. `after` Steps 4, 5 and 6 only happen if validation succeeds. If a request for a resource is made with an unsupported HTTP method (returning HTTP 405) only `before` callbacks will be executed. The remaining callbacks will be bypassed. If a request for a resource is made that triggers the built-in `OPTIONS` handler, only `before` and `after` callbacks will be executed. The remaining callbacks will be bypassed. For example, using a simple `before` block to set a header. ```ruby before do header 'X-Robots-Tag', 'noindex' end ``` **Namespaces** Callbacks apply to each API call within and below the current namespace: ```ruby class MyAPI < Grape::API get '/' do "root - #{@blah}" end namespace :foo do before do @blah = 'blah' end get '/' do "root - foo - #{@blah}" end namespace :bar do get '/' do "root - foo - bar - #{@blah}" end end end end ``` The behavior is then: ```bash GET / # 'root - ' GET /foo # 'root - foo - blah' GET /foo/bar # 'root - foo - bar - blah' ``` Params on a `namespace` (or whichever alias you are using) will also be available when using `before_validation` or `after_validation`: ```ruby class MyAPI < Grape::API params do requires :blah, type: Integer end resource ':blah' do after_validation do # if we reach this point validations will have passed @blah = declared(params, include_missing: false)[:blah] end get '/' do @blah.class end end end ``` The behavior is then: ```bash GET /123 # 'Integer' GET /foo # 400 error - 'blah is invalid' ``` **Versioning** When a callback is defined within a version block, it's only called for the routes defined in that block. ```ruby class Test < Grape::API resource :foo do version 'v1', :using => :path do before do @output ||= 'v1-' end get '/' do @output += 'hello' end end version 'v2', :using => :path do before do @output ||= 'v2-' end get '/' do @output += 'hello' end end end end ``` The behavior is then: ```bash GET /foo/v1 # 'v1-hello' GET /foo/v2 # 'v2-hello' ``` **Altering Responses** Using `present` in any callback allows you to add data to a response: ```ruby class MyAPI < Grape::API format :json after_validation do present :name, params[:name] if params[:name] end get '/greeting' do present :greeting, 'Hello!' end end ``` The behavior is then: ```bash GET /greeting # {"greeting":"Hello!"} GET /greeting?name=Alan # {"name":"Alan","greeting":"Hello!"} ``` Instead of altering a response, you can also terminate and rewrite it from any callback using `error!`, including `after`. This will cause all subsequent steps in the process to not be called. **This includes the actual api call and any callbacks** ## Anchoring Grape by default anchors all request paths, which means that the request URL should match from start to end to match, otherwise a `404 Not Found` is returned. However, this is sometimes not what you want, because it is not always known upfront what can be expected from the call. This is because Rack-mount by default anchors requests to match from the start to the end, or not at all. Rails solves this problem by using a `anchor: false` option in your routes. In Grape this option can be used as well when a method is defined. For instance when your API needs to get part of an URL, for instance: ```ruby class TwitterAPI < Grape::API namespace :statuses do get '/(*:status)', anchor: false do end end end ``` This will match all paths starting with '/statuses/'. There is one caveat though: the `params[:status]` parameter only holds the first part of the request url. Luckily this can be circumvented by using the described above syntax for path specification and using the `PATH_INFO` Rack environment variable, using `env['PATH_INFO']`. This will hold everything that comes after the '/statuses/' part. ## Using Custom Middleware ### Grape Middleware You can make a custom middleware by using `Grape::Middleware::Base`. It's inherited from some grape official middlewares in fact. For example, you can write a middleware to log application exception. ```ruby class LoggingError < Grape::Middleware::Base def after return unless @app_response && @app_response[0] == 500 env['rack.logger'].error("Raised error on #{env['PATH_INFO']}") end end ``` Your middleware can overwrite application response as follows, except error case. ```ruby class Overwriter < Grape::Middleware::Base def after [200, { 'Content-Type' => 'text/plain' }, ['Overwritten.']] end end ``` You can add your custom middleware with `use`, that push the middleware onto the stack, and you can also control where the middleware is inserted using `insert`, `insert_before` and `insert_after`. ```ruby class CustomOverwriter < Grape::Middleware::Base def after [200, { 'Content-Type' => 'text/plain' }, [@options[:message]]] end end class API < Grape::API use Overwriter insert_before Overwriter, CustomOverwriter, message: 'Overwritten again.' insert 0, CustomOverwriter, message: 'Overwrites all other middleware.' get '/' do end end ``` ### Rails Middleware Note that when you're using Grape mounted on Rails you don't have to use Rails middleware because it's already included into your middleware stack. You only have to implement the helpers to access the specific `env` variable. ### Remote IP By default you can access remote IP with `request.ip`. This is the remote IP address implemented by Rack. Sometimes it is desirable to get the remote IP [Rails-style](http://stackoverflow.com/questions/10997005/whats-the-difference-between-request-remote-ip-and-request-ip-in-rails) with `ActionDispatch::RemoteIp`. Add `gem 'actionpack'` to your Gemfile and `require 'action_dispatch/middleware/remote_ip.rb'`. Use the middleware in your API and expose a `client_ip` helper. See [this documentation](http://api.rubyonrails.org/classes/ActionDispatch/RemoteIp.html) for additional options. ```ruby class API < Grape::API use ActionDispatch::RemoteIp helpers do def client_ip env['action_dispatch.remote_ip'].to_s end end get :remote_ip do { ip: client_ip } end end ``` ## Writing Tests ### Writing Tests with Rack Use `rack-test` and define your API as `app`. #### RSpec You can test a Grape API with RSpec by making HTTP requests and examining the response. ```ruby require 'spec_helper' describe Twitter::API do include Rack::Test::Methods def app Twitter::API end context 'GET /api/statuses/public_timeline' do it 'returns an empty array of statuses' do get '/api/statuses/public_timeline' expect(last_response.status).to eq(200) expect(JSON.parse(last_response.body)).to eq [] end end context 'GET /api/statuses/:id' do it 'returns a status by id' do status = Status.create! get "/api/statuses/#{status.id}" expect(last_response.body).to eq status.to_json end end end ``` There's no standard way of sending arrays of objects via an HTTP GET, so POST JSON data and specify the correct content-type. ```ruby describe Twitter::API do context 'POST /api/statuses' do it 'creates many statuses' do statuses = [{ text: '...' }, { text: '...'}] post '/api/statuses', statuses.to_json, 'CONTENT_TYPE' => 'application/json' expect(last_response.body).to eq 201 end end end ``` #### Airborne You can test with other RSpec-based frameworks, including [Airborne](https://github.com/brooklynDev/airborne), which uses `rack-test` to make requests. ```ruby require 'airborne' Airborne.configure do |config| config.rack_app = Twitter::API end describe Twitter::API do context 'GET /api/statuses/:id' do it 'returns a status by id' do status = Status.create! get "/api/statuses/#{status.id}" expect_json(status.as_json) end end end ``` #### MiniTest ```ruby require 'test_helper' class Twitter::APITest < MiniTest::Test include Rack::Test::Methods def app Twitter::API end def test_get_api_statuses_public_timeline_returns_an_empty_array_of_statuses get '/api/statuses/public_timeline' assert last_response.ok? assert_equal [], JSON.parse(last_response.body) end def test_get_api_statuses_id_returns_a_status_by_id status = Status.create! get "/api/statuses/#{status.id}" assert_equal status.to_json, last_response.body end end ``` ### Writing Tests with Rails #### RSpec ```ruby describe Twitter::API do context 'GET /api/statuses/public_timeline' do it 'returns an empty array of statuses' do get '/api/statuses/public_timeline' expect(response.status).to eq(200) expect(JSON.parse(response.body)).to eq [] end end context 'GET /api/statuses/:id' do it 'returns a status by id' do status = Status.create! get "/api/statuses/#{status.id}" expect(response.body).to eq status.to_json end end end ``` In Rails, HTTP request tests would go into the `spec/requests` group. You may want your API code to go into `app/api` - you can match that layout under `spec` by adding the following in `spec/rails_helper.rb`. ```ruby RSpec.configure do |config| config.include RSpec::Rails::RequestExampleGroup, type: :request, file_path: /spec\/api/ end ``` #### MiniTest ```ruby class Twitter::APITest < ActiveSupport::TestCase include Rack::Test::Methods def app Rails.application end test 'GET /api/statuses/public_timeline returns an empty array of statuses' do get '/api/statuses/public_timeline' assert last_response.ok? assert_equal [], JSON.parse(last_response.body) end test 'GET /api/statuses/:id returns a status by id' do status = Status.create! get "/api/statuses/#{status.id}" assert_equal status.to_json, last_response.body end end ``` ### Stubbing Helpers Because helpers are mixed in based on the context when an endpoint is defined, it can be difficult to stub or mock them for testing. The `Grape::Endpoint.before_each` method can help by allowing you to define behavior on the endpoint that will run before every request. ```ruby describe 'an endpoint that needs helpers stubbed' do before do Grape::Endpoint.before_each do |endpoint| allow(endpoint).to receive(:helper_name).and_return('desired_value') end end after do Grape::Endpoint.before_each nil end it 'stubs the helper' do end end ``` ## Reloading API Changes in Development ### Reloading in Rack Applications Use [grape-reload](https://github.com/AlexYankee/grape-reload). ### Reloading in Rails Applications Add API paths to `config/application.rb`. ```ruby # Auto-load API and its subdirectories config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb') config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')] ``` Create `config/initializers/reload_api.rb`. ```ruby if Rails.env.development? ActiveSupport::Dependencies.explicitly_unloadable_constants << 'Twitter::API' api_files = Dir[Rails.root.join('app', 'api', '**', '*.rb')] api_reloader = ActiveSupport::FileUpdateChecker.new(api_files) do Rails.application.reload_routes! end ActionDispatch::Callbacks.to_prepare do api_reloader.execute_if_updated end end ``` For Rails >= 5.1.4, change this: ```ruby ActionDispatch::Callbacks.to_prepare do api_reloader.execute_if_updated end ``` to this: ```ruby ActiveSupport::Reloader.to_prepare do api_reloader.execute_if_updated end ``` See [StackOverflow #3282655](http://stackoverflow.com/questions/3282655/ruby-on-rails-3-reload-lib-directory-for-each-request/4368838#4368838) for more information. ## Performance Monitoring ### Active Support Instrumentation Grape has built-in support for [ActiveSupport::Notifications](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) which provides simple hook points to instrument key parts of your application. The following are currently supported: #### endpoint_run.grape The main execution of an endpoint, includes filters and rendering. * *endpoint* - The endpoint instance #### endpoint_render.grape The execution of the main content block of the endpoint. * *endpoint* - The endpoint instance #### endpoint_run_filters.grape * *endpoint* - The endpoint instance * *filters* - The filters being executed * *type* - The type of filters (before, before_validation, after_validation, after) #### endpoint_run_validators.grape The execution of validators. * *endpoint* - The endpoint instance * *validators* - The validators being executed * *request* - The request being validated See the [ActiveSupport::Notifications documentation](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) for information on how to subscribe to these events. ### Monitoring Products Grape integrates with following third-party tools: * **New Relic** - [built-in support](https://docs.newrelic.com/docs/agents/ruby-agent/frameworks/grape-instrumentation) from v3.10.0 of the official [newrelic_rpm](https://github.com/newrelic/rpm) gem, also [newrelic-grape](https://github.com/xinminlabs/newrelic-grape) gem * **Librato Metrics** - [grape-librato](https://github.com/seanmoon/grape-librato) gem * **[Skylight](https://www.skylight.io/)** - [skylight](https://github.com/skylightio/skylight-ruby) gem, [documentation](https://docs.skylight.io/grape/) * **[AppSignal](https://www.appsignal.com)** - [appsignal-ruby](https://github.com/appsignal/appsignal-ruby) gem, [documentation](http://docs.appsignal.com/getting-started/supported-frameworks.html#grape) ## Contributing to Grape Grape is work of hundreds of contributors. You're encouraged to submit pull requests, propose features and discuss issues. See [CONTRIBUTING](CONTRIBUTING.md). ## License MIT License. See LICENSE for details. ## Copyright Copyright (c) 2010-2018 Michael Bleigh, Intridea Inc. and Contributors. grape-1.0.2/Guardfile0000644000004100000410000000046613231337007014472 0ustar www-datawww-dataguard :rspec, all_on_start: true, cmd: 'bundle exec rspec' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { 'spec' } end guard :rubocop do watch(/.+\.rb$/) watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) } end